package main
import (
"fmt"
"math/rand"
"os"
"path/filepath"
"sort"
"strconv"
"strings"
"time"
"github.com/rudi9719/loggy"
)
func setupCommands ( ) {
reboot := Command {
Name : "Reboot" ,
RequiresAdmin : true ,
Help : "Reboot me, requires token from logs." ,
Keywords : [ ] string { "reboot" , "re" , "restart" } ,
Exec : Reboot ,
}
commands = append ( commands , reboot )
bumpset := Command {
Name : "BumpSet" ,
RequiresAdmin : true ,
Help : "Set the bump timer (requires time in minutes until next bump)." ,
Keywords : [ ] string { "bs" , "bumpset" , "bumps" } ,
Exec : BumpSet ,
}
commands = append ( commands , bumpset )
retrieveVerification := Command {
Name : "Retrieve Verification" ,
RequiresAdmin : true ,
Help : "Retrieve verification either by discord ID or by nickname" ,
Keywords : [ ] string { "veri" , "verification" , "retrieve" } ,
Exec : RetrieveVerification ,
}
commands = append ( commands , retrieveVerification )
addQuote := Command {
Name : "Add Quote" ,
RequiresAdmin : true ,
Keywords : [ ] string { "quote" , "addq" , "q" } ,
Exec : AddQuote ,
}
commands = append ( commands , addQuote )
snap := Command {
Name : "Snap" ,
Help : "Trigger a purge!" ,
RequiresAdmin : false ,
Keywords : [ ] string { "snap" , "purge" , "sn" } ,
Exec : Snap ,
}
commands = append ( commands , snap )
status := Command {
Name : "Status" ,
RequiresAdmin : true ,
Help : "Show the current status of Thanos/Verifications and probations" ,
Keywords : [ ] string { "st" , "status" , "stats" } ,
Exec : Status ,
}
commands = append ( commands , status )
listCommands := Command {
Name : "List Commands" ,
RequiresAdmin : false ,
Keywords : [ ] string { "help" , "commands" , "cmd" , "cmds" } ,
Exec : Commands ,
}
commands = append ( commands , listCommands )
debugLevel := Command {
Name : "Debug Level" ,
RequiresAdmin : true ,
Keywords : [ ] string { "debug" } ,
Exec : Debug ,
Help : "Set the log level for loggy" ,
}
commands = append ( commands , debugLevel )
activityReport := Command {
Name : "Activity Report" ,
RequiresAdmin : false ,
Keywords : [ ] string { "activity" , "active" , "list" } ,
Exec : ActivityReport ,
Help : "List activity for the discord. Supply a number to get the top N users (5 would be top 5 users) or all for all users!" ,
}
commands = append ( commands , activityReport )
urlWhitelist := Command {
Name : "Whitelist URL" ,
RequiresAdmin : true ,
Keywords : [ ] string { "whitelist" } ,
Exec : WhitelistURL ,
Help : "Add a domain to the HTTP whitelist domains are in the format `thisvid.com` without the subdomain." ,
}
commands = append ( commands , urlWhitelist )
}
func Commands ( b BotCommand ) bool {
defer log . PanicSafe ( )
print := "Available commands:\n"
for _ , cmd := range commands {
if cmd . RequiresAdmin {
if isAdmin ( b . Message . Member ) {
print += fmt . Sprintf ( "```%+v\n%+v\n%+v```\n" , cmd . Name , cmd . Keywords , cmd . Help )
}
} else {
print += fmt . Sprintf ( "```%+v\n%+v\n%+v```\n" , cmd . Name , cmd . Keywords , cmd . Help )
}
}
b . Session . ChannelMessageSend ( b . Message . ChannelID , print )
return true
}
func Debug ( b BotCommand ) bool {
defer log . PanicSafe ( )
level , err := strconv . Atoi ( b . Parts [ 0 ] )
if err != nil {
return false
}
config . LogOpts . Level = loggy . LogLevel ( level )
log = loggy . NewLogger ( config . LogOpts )
return true
}
func Reboot ( b BotCommand ) bool {
defer log . PanicSafe ( )
if strings . Contains ( b . Message . Content , rebootToken ) {
exit ( b . Session )
return true
}
return false
}
func ActivityReport ( b BotCommand ) bool {
useCounter := true
counterStop := 4
if len ( b . Parts ) > 0 {
test , err := strconv . Atoi ( b . Parts [ 0 ] )
if err == nil {
counterStop = test
} else {
useCounter = false
}
}
statistics := "```"
n := map [ int ] [ ] string { }
counter := 0
var a [ ] int
for k , v := range config . Activity {
n [ v ] = append ( n [ v ] , k )
}
for k := range n {
a = append ( a , k )
}
sort . Sort ( sort . Reverse ( sort . IntSlice ( a ) ) )
for _ , k := range a {
for _ , s := range n [ k ] {
if useCounter && counter == counterStop - 1 {
return true
}
user , err := b . Session . GuildMember ( config . GuildID , s )
if err == nil {
statistics += fmt . Sprintf ( "\n%+v: %+v" , user . User . Username , k )
counter ++
} else {
log . LogErrorType ( err )
}
}
}
statistics += "\n```"
return true
}
func BumpSet ( b BotCommand ) bool {
defer log . PanicSafe ( )
bump = false
timer , err := strconv . Atoi ( b . Parts [ 0 ] )
if err != nil {
b . Session . ChannelMessageSend ( b . Message . ChannelID , fmt . Sprintf ( "Unable to decode timer: %+v" , b . Parts [ 0 ] ) )
return false
}
config . BumpTime = time . Now ( ) . Add ( time . Duration ( timer ) * time . Minute ) . Add ( - 2 * time . Hour )
b . Session . ChannelMessageSend ( b . Message . ChannelID , fmt . Sprintf ( "New last bump time: <t:%+v:t>, expecting next bump at <t:%+v:t>" , config . BumpTime . Unix ( ) , config . BumpTime . Add ( 2 * time . Hour ) . Unix ( ) ) )
return true
}
func RetrieveVerification ( b BotCommand ) bool {
defer log . PanicSafe ( )
discordId := b . Parts [ 0 ]
_ , err := strconv . Atoi ( discordId )
if err != nil {
discordId = idFromUsername ( discordId )
}
user , err := b . Session . GuildMember ( config . GuildID , discordId )
if err != nil {
log . LogErrorType ( err )
return false
}
matches , err := filepath . Glob ( fmt . Sprintf ( "./verifications/*%+v*" , discordId ) )
if err != nil {
log . LogErrorType ( err )
return false
}
if len ( matches ) != 1 {
b . Session . ChannelMessageSend ( b . Message . ChannelID , fmt . Sprintf ( "Error finding verification for ID %+v" , discordId ) )
return false
}
verificationImage , err := os . Open ( matches [ 0 ] )
if err != nil {
log . LogErrorType ( err )
return false
}
msg := fmt . Sprintf ( "``` %+v\nJoined: %+v\n```" , user . User . Username , user . JoinedAt )
b . Session . ChannelFileSendWithMessage ( b . Message . ChannelID , msg , matches [ 0 ] , verificationImage )
return true
}
func AddQuote ( b BotCommand ) bool {
defer log . PanicSafe ( )
quotes = append ( quotes , strings . ReplaceAll ( b . Message . Content , b . Command , "" ) )
return true
}
func Snap ( b BotCommand ) bool {
defer log . PanicSafe ( )
go runPurge ( b . Session )
b . Session . ChannelMessageSend ( config . AdminChannel , quotes [ rand . Intn ( len ( quotes ) ) ] )
return true
}
func Status ( b BotCommand ) bool {
defer log . PanicSafe ( )
status := fmt . Sprintf ( "Uptime: %+v\n" , time . Since ( startupTime ) )
status += fmt . Sprintf ( "Last active time: %+v\n" , time . Since ( lastActiveTime ) )
status += fmt . Sprintf ( "Last bump: <t:%+v:t>\n" , config . BumpTime . Unix ( ) )
status += fmt . Sprintf ( "Last bumper: %+v\n" , userFromID ( config . LastBumper ) . Username )
status += fmt . Sprintf ( "Bump needed: %+v\n" , bump )
if len ( config . Unverified ) > 0 {
status += "Unverified users:\n"
for k , v := range config . Unverified {
uvUser := userFromID ( k )
status += fmt . Sprintf ( "\n%+v will be removed at <t:%+v:t>" , uvUser . Username , v . Add ( 1 * time . Hour ) . Unix ( ) )
}
status += "\n"
} else {
status += "There are no unverified users.\n"
}
if len ( config . Verifications ) > 0 {
status += "Pending verifications:\n"
for _ , v := range config . Verifications {
status += fmt . Sprintf ( "%+v has submitted a verification." , v . Username )
}
status += "\n"
} else {
status += "There are no pending verifications.\n"
}
if len ( config . Probations ) > 0 {
status += "\nThe following users are on probation: \n"
for uid , join := range config . Probations {
probationUser := userFromID ( uid )
status += fmt . Sprintf ( "%+v for until <t:%+v:t>\n" , probationUser . Username , join . Add ( 2 * time . Hour ) . Unix ( ) )
}
status += "\n"
} else {
status += "There are no users on probation.\n"
}
b . Session . ChannelMessageSend ( config . AdminChannel , status )
statistics := "```"
for k , v := range config . Stats {
adminUser , err := b . Session . GuildMember ( config . GuildID , k )
if err == nil {
statistics += fmt . Sprintf ( "\n%+v: %+v" , adminUser . User . Username , v + 1 )
} else {
log . LogErrorType ( err )
}
}
statistics += "\n```"
log . LogInfo ( "Private statistics: %+v" , statistics )
go runPurge ( b . Session )
return true
}
func WhitelistURL ( b BotCommand ) bool {
defer log . PanicSafe ( )
config . WhitelistURLs = append ( config . WhitelistURLs , strings . ReplaceAll ( b . Message . Content , b . Command , "" ) )
return true ;
}