Documentation
¶
Index ¶
- Constants
- Variables
- func AbsInt(x int64) int64
- func AssembleVersion(major byte, minor byte, revision byte, build byte) int
- func CheckMapNilBool(m *map[CommandID]bool)
- func CheckMapNilString(m *map[string]string)
- func CheckRateLimit(prevtime *int64, interval int64, curtime int64) bool
- func DownloadFile(url string, file string, checkMD5 bool) error
- func DumpCommandsModules(info *GuildInfo, footer string, description string, msg *discordgo.Message) *discordgo.MessageEmbed
- func DumpScript(dir string)
- func ExecCommand(c *exec.Cmd, dir string, env ...string) (string, error)
- func ExecuteSQLFile(db *sql.DB, file string) error
- func FindRole(name string, guild *discordgo.Guild) (s []*discordgo.Role)
- func FindUpgradeFiles(scriptdir string, version int) (files []int)
- func FixRequest(arg string, t reflect.Value) (string, error)
- func GetCurrentDir() (string, error)
- func GetJoinedAt(m *discordgo.Member) time.Time
- func GetRoleByName(role string, info *GuildInfo) (*discordgo.Role, error)
- func GetTimestamp(m *discordgo.Message) time.Time
- func GuildMemberPermissions(member *discordgo.Member, guild *discordgo.Guild) (apermissions int64)
- func HTTPRequestData(url string) (body []byte, err error)
- func Install(path string, selfhoster *Selfhost)
- func IsSpace(b byte) bool
- func MapGetRandomItem(m map[string]bool) string
- func MapIntToSlice(m map[int]string) []int
- func MapStringToSlice(m map[string]string) []string
- func MapToSlice(m map[string]bool) []string
- func MemberHasRole(m *discordgo.Member, role DiscordRole) bool
- func ParseArguments(s string) ([]string, []int)
- func ParseRepeatInterval(s string) uint8
- func PingAtoi(s string) uint64
- func Pluralize(i int64, str string) string
- func RateLimit(prevtime *int64, interval int64, curtime int64) bool
- func RemoveSliceString(s *[]string, item string) bool
- func ReplaceAllRolePings(s string, info *GuildInfo) string
- func ReturnError(err error) (string, bool, *discordgo.MessageEmbed)
- func RunCommand(path string, dir string, args ...string) (string, error)
- func SBatoi(s string) uint64
- func SBitoa(i uint64) string
- func SnowflakeTime(id uint64) time.Time
- func StartCommand(path string, dir string, args ...string) error
- func StripPing(s string) string
- func TimeDiff(d time.Duration) string
- func UpdateEndpoint(request string, userID DiscordUser, oldversion int) string
- func WaitForPID(arg string)
- type AtomicBool
- type AtomicFlag
- type BotConfig
- func (config *BotConfig) FillConfig()
- func (config *BotConfig) GetConfig(f reflect.Value, state *discordgo.State, guild string) (s []string)
- func (config *BotConfig) IsCommandDisabled(command Command) (str string)
- func (config *BotConfig) IsModuleDisabled(module Module) string
- func (config *BotConfig) SetConfig(info *GuildInfo, args []string, indices []int, message string) (string, bool)
- type BotDB
- func (db *BotDB) AddItem(item string) (uint64, error)
- func (db *BotDB) AddMember(id uint64, guild uint64, firstseen time.Time, nickname string)
- func (db *BotDB) AddMessage(id uint64, author *discordgo.User, message string, channel uint64, ...)
- func (db *BotDB) AddSchedule(guild uint64, date time.Time, ty uint8, data string) error
- func (db *BotDB) AddScheduleRepeat(guild uint64, date time.Time, repeatinterval uint8, repeat int, ty uint8, ...) error
- func (db *BotDB) AddTag(item uint64, tag uint64) error
- func (db *BotDB) AddTranscript(season int, episode int, line int, speaker string, text string) error
- func (db *BotDB) AddUser(id uint64, username string, discriminator int, isonline bool)
- func (db *BotDB) Audit(ty uint8, user *discordgo.User, message string, guild uint64)
- func (db *BotDB) CheckError(name string, err error) error
- func (db *BotDB) CheckStatus() bool
- func (db *BotDB) Close()
- func (db *BotDB) CountItems(guild uint64) (uint64, error)
- func (db *BotDB) CountNewUsers(seconds int64, guild uint64) int
- func (db *BotDB) CountTag(tag uint64) (uint64, error)
- func (db *BotDB) CreateTag(tag string, guild uint64) error
- func (db *BotDB) DeleteSchedule(id uint64) error
- func (db *BotDB) DeleteTag(tag string, guild uint64) error
- func (db *BotDB) FindEvent(user string, guild uint64, ty uint8) *uint64
- func (db *BotDB) FindGuildUsers(name string, maxresults uint64, offset uint64, guild uint64) []uint64
- func (db *BotDB) FindTimeZone(s string) []string
- func (db *BotDB) FindTimeZoneOffset(s string, minutes int) []string
- func (db *BotDB) FindUser(name string, discriminator int, maxresults uint64, offset uint64) []uint64
- func (db *BotDB) GetAliases(user uint64) []string
- func (db *BotDB) GetAuditRows(start uint64, end uint64, user *uint64, search string, guild uint64) []PingContext
- func (db *BotDB) GetCharacterQuote(character string) Transcript
- func (db *BotDB) GetEvent(guild uint64, id uint64) *ScheduleEvent
- func (db *BotDB) GetEvents(guild uint64, maxnum int) []ScheduleEvent
- func (db *BotDB) GetEventsByType(guild uint64, ty uint8, maxnum int) []ScheduleEvent
- func (db *BotDB) GetItem(item string) (uint64, error)
- func (db *BotDB) GetItemTags(item uint64, guild uint64) []string
- func (db *BotDB) GetMember(id uint64, guild uint64) (*discordgo.Member, time.Time, *time.Time)
- func (db *BotDB) GetNewcomers(lookback int, guild uint64) []uint64
- func (db *BotDB) GetNewestUsers(maxresults int, guild uint64) []struct{ ... }
- func (db *BotDB) GetNextEvent(guild uint64, ty uint8) ScheduleEvent
- func (db *BotDB) GetRandomQuote() Transcript
- func (db *BotDB) GetRecentUsers(since time.Time, guild uint64) []*discordgo.User
- func (db *BotDB) GetReminders(guild uint64, id string, maxnum int) []ScheduleEvent
- func (db *BotDB) GetSchedule(guild uint64) []ScheduleEvent
- func (db *BotDB) GetScheduleDate(guild uint64, ty uint8, data string) *time.Time
- func (db *BotDB) GetSpeechQuote() Transcript
- func (db *BotDB) GetTableCounts() string
- func (db *BotDB) GetTag(tag string, guild uint64) (uint64, error)
- func (db *BotDB) GetTags(guild uint64) []struct{ ... }
- func (db *BotDB) GetTimeZone(user uint64) *time.Location
- func (db *BotDB) GetTranscript(season int, episode int, start int, end int) []Transcript
- func (db *BotDB) GetUser(id uint64) (*discordgo.User, time.Time, *time.Location, *uint64)
- func (db *BotDB) GetUserGuilds(user uint64) []uint64
- func (db *BotDB) ImportTag(srcTag uint64, destTag uint64) error
- func (db *BotDB) LoadStatements() error
- func (db *BotDB) Prepare(s string) (*sql.Stmt, error)
- func (db *BotDB) RemoveAlias(user uint64, alias string) error
- func (db *BotDB) RemoveGuild(guild uint64) error
- func (db *BotDB) RemoveItem(item uint64, guild uint64) error
- func (db *BotDB) RemoveMember(id uint64, guild uint64) error
- func (db *BotDB) RemoveSchedule(id uint64) error
- func (db *BotDB) RemoveTag(item uint64, tag uint64) error
- func (db *BotDB) RemoveTranscript(season int, episode int, line int)
- func (db *BotDB) SawUser(user uint64, username string) error
- func (db *BotDB) SentMessage(user uint64, guild uint64) error
- func (db *BotDB) SetDefaultServer(userID uint64, guild uint64) error
- func (db *BotDB) SetTimeZone(user uint64, tz *time.Location) error
- type BotInstance
- type Command
- type CommandID
- type CommandInfo
- type CommandUsage
- type CommandUsageParam
- type ConfigModule
- type DebugModule
- type DiscordChannel
- type DiscordGoSession
- func (s *DiscordGoSession) BulkDeleteBypass(channelID string, messages []string) (err error)
- func (s *DiscordGoSession) ChangeBotName(name string, avatarfile string) error
- func (s *DiscordGoSession) GetMember(userID DiscordUser, guildID string) (*discordgo.Member, error)
- func (s *DiscordGoSession) GetMemberCreate(u *discordgo.User, guildID string) *discordgo.Member
- func (s *DiscordGoSession) RemoveRole(guildID string, userID DiscordUser, role DiscordRole) error
- func (s *DiscordGoSession) ReplaceAllMentions(str string, db *BotDB, guildID string) string
- func (s *DiscordGoSession) UserHasAnyRole(user DiscordUser, guildID string, roles map[DiscordRole]bool) bool
- func (s *DiscordGoSession) UserPermissions(userID DiscordUser, guildID string) (int64, error)
- type DiscordGuild
- type DiscordRole
- type DiscordUser
- type GuildInfo
- func (info *GuildInfo) AddCommand(c Command, m Module)
- func (info *GuildInfo) ApplyTimezone(t time.Time, user DiscordUser) time.Time
- func (info *GuildInfo) BulkDelete(channel *discordgo.Channel, messages []string) (err error)
- func (info *GuildInfo) ChannelMessageDelete(channel *discordgo.Channel, messageID string) (err error)
- func (info *GuildInfo) ChannelPermissionSet(channel *discordgo.Channel, targetID string, ...) (err error)
- func (info *GuildInfo) Clean()
- func (info *GuildInfo) FindChannelID(name string) string
- func (info *GuildInfo) FindUsername(arg string) []uint64
- func (info *GuildInfo) FormatUsage(c Command, usage *CommandUsage) *discordgo.MessageEmbed
- func (info *GuildInfo) GetBotName() string
- func (info *GuildInfo) GetChannels(command CommandID) string
- func (info *GuildInfo) GetGuild() (*discordgo.Guild, error)
- func (info *GuildInfo) GetMemberName(m *discordgo.Member) string
- func (info *GuildInfo) GetRoles(command CommandID) string
- func (info *GuildInfo) GetTimezone(user DiscordUser) *time.Location
- func (info *GuildInfo) GetUserName(user DiscordUser) string
- func (info *GuildInfo) IDsToUsernames(IDs []uint64, discriminator bool) []string
- func (info *GuildInfo) IsDebug(channelID DiscordChannel) bool
- func (info *GuildInfo) Log(args ...interface{})
- func (info *GuildInfo) LogError(msg string, err error)
- func (guild *GuildInfo) MigrateSettings(config []byte) error
- func (info *GuildInfo) ParseCommonTime(s string, user DiscordUser, timestamp time.Time) (time.Time, error)
- func (info *GuildInfo) ProcessMember(u *discordgo.Member)
- func (info *GuildInfo) ProcessMembers(m []*discordgo.Member)
- func (info *GuildInfo) ProcessModule(channelID DiscordChannel, m Module) bool
- func (info *GuildInfo) RegisterModule(m Module)
- func (info *GuildInfo) RequestPostWithBuffer(urlStr string, data *discordgo.MessageSend, minRemaining int) (response []byte, err error)
- func (info *GuildInfo) ResolveRoleAddError(err error) error
- func (info *GuildInfo) Sanitize(s string, flags int) string
- func (info *GuildInfo) SaveConfig() (err error)
- func (info *GuildInfo) SendEmbed(channelID DiscordChannel, embed *discordgo.MessageEmbed) error
- func (info *GuildInfo) SendError(channelID DiscordChannel, message string, t int64)
- func (info *GuildInfo) SendMessage(channelID DiscordChannel, message string) error
- func (info *GuildInfo) UserCanUseCommand(userID DiscordUser, command Command, ignore bool) (bypass bool, err error)
- func (info *GuildInfo) UserHasRole(userID DiscordUser, role DiscordRole) bool
- func (info *GuildInfo) UserIsAdmin(userID DiscordUser) bool
- func (info *GuildInfo) UserIsMod(userID DiscordUser) bool
- type InfoModule
- type Module
- type ModuleID
- type ModuleOnCommand
- type ModuleOnEvent
- type ModuleOnGuildBanAdd
- type ModuleOnGuildBanRemove
- type ModuleOnGuildMemberAdd
- type ModuleOnGuildMemberRemove
- type ModuleOnGuildMemberUpdate
- type ModuleOnGuildRoleDelete
- type ModuleOnGuildUpdate
- type ModuleOnMessageCreate
- type ModuleOnMessageDelete
- type ModuleOnMessageUpdate
- type ModuleOnTick
- type ModuleOnVoiceStateUpdate
- type PingContext
- type SaturationLimit
- type ScheduleEvent
- type Selfhost
- type SelfhostBase
- func (b *SelfhostBase) CheckDonor(m *discordgo.Member) bool
- func (b *SelfhostBase) CheckForUpdate(userID DiscordUser, oldversion int) (int8, *UpdateStatus)
- func (b *SelfhostBase) CheckGuilds(guilds map[DiscordGuild]*GuildInfo)
- func (b *SelfhostBase) ConfigureMux(mux *http.ServeMux)
- func (b *SelfhostBase) DoUpdate(dbauth string, token string) error
- func (b *SelfhostBase) GetWebDir() string
- func (b *SelfhostBase) SelfUpdate(ownerid DiscordUser) error
- func (b *SelfhostBase) UpgradeDatabase(scriptdir string, dbauth string) error
- type SweetieBot
- func (sb *SweetieBot) AttachToGuild(g *discordgo.Guild)
- func (sb *SweetieBot) ChannelCreate(s *discordgo.Session, c *discordgo.ChannelCreate)
- func (sb *SweetieBot) ChannelIsPrivate(channelID DiscordChannel) (*discordgo.Channel, bool)
- func (sb *SweetieBot) Connect() int
- func (sb *SweetieBot) FindServers(name string, guilds []uint64) []*GuildInfo
- func (sb *SweetieBot) GetDefaultServer(user uint64) *GuildInfo
- func (sb *SweetieBot) GetLastMessage(id DiscordChannel) (int64, bool)
- func (sb *SweetieBot) GuildBanAdd(s *discordgo.Session, m *discordgo.GuildBanAdd)
- func (sb *SweetieBot) GuildBanRemove(s *discordgo.Session, m *discordgo.GuildBanRemove)
- func (sb *SweetieBot) GuildCreate(s *discordgo.Session, m *discordgo.GuildCreate)
- func (sb *SweetieBot) GuildDelete(s *discordgo.Session, m *discordgo.GuildDelete)
- func (sb *SweetieBot) GuildMemberAdd(s *discordgo.Session, m *discordgo.GuildMemberAdd)
- func (sb *SweetieBot) GuildMemberRemove(s *discordgo.Session, m *discordgo.GuildMemberRemove)
- func (sb *SweetieBot) GuildMemberUpdate(s *discordgo.Session, m *discordgo.GuildMemberUpdate)
- func (sb *SweetieBot) GuildMembersChunk(s *discordgo.Session, chunk *discordgo.GuildMembersChunk)
- func (sb *SweetieBot) GuildRoleDelete(s *discordgo.Session, m *discordgo.GuildRoleDelete)
- func (sb *SweetieBot) GuildUpdate(s *discordgo.Session, m *discordgo.GuildUpdate)
- func (sb *SweetieBot) IsMainGuild(info *GuildInfo) bool
- func (sb *SweetieBot) MessageCreate(s *discordgo.Session, m *discordgo.MessageCreate)
- func (sb *SweetieBot) MessageDelete(s *discordgo.Session, m *discordgo.MessageDelete)
- func (sb *SweetieBot) MessageUpdate(s *discordgo.Session, m *discordgo.MessageUpdate)
- func (sb *SweetieBot) OnReady(s *discordgo.Session, r *discordgo.Ready)
- func (sb *SweetieBot) ProcessCommand(m *discordgo.Message, info *GuildInfo, t int64, isdebug bool, private bool)
- func (sb *SweetieBot) ProcessUser(u *discordgo.User) uint64
- func (sb *SweetieBot) ServeWeb() error
- func (sb *SweetieBot) UserUpdate(s *discordgo.Session, u *discordgo.UserUpdate)
- type TimeLocation
- type Transcript
- type UpdateStatus
- type Version
Constants ¶
const ( ChannelEmpty = DiscordChannel("") ChannelExclusion = DiscordChannel("!") RoleEmpty = DiscordRole("") RoleExclusion = DiscordRole("!") UserEmpty = DiscordUser("") GuildEmpty = DiscordGuild("") )
const ( CleanMentions = 1 << iota CleanPings = 1 << iota CleanURL = 1 << iota CleanEmotes = 1 << iota CleanCode = 1 << iota CleanCodeBlock = CleanCode | CleanEmotes CleanAll = CleanMentions | CleanURL | CleanEmotes | CleanCode | CleanPings CleanMost = CleanMentions | CleanURL | CleanEmotes | CleanPings )
const ( AuditTypeLog = iota AuditTypeAction = iota AuditTypeCommand = iota )
Audit types
const ( STRING_INVALID_COMMAND = iota STRING_PM_FAILURE = iota STRING_CHECK_PM = iota STRING_DATABASE_ERROR = iota STRING_NO_SERVER = iota STRING_COMMANDS_LIMIT = iota STRING_COMMAND_LIMIT = iota STRING_SETUP_MESSAGE = iota STRING_SPAM_DESCRIPTION = iota STRING_SPAM_ERROR_UNSILENCING = iota STRING_SPAM_UNSILENCING = iota STRING_SPAM_EMBEDDED_URLS = iota STRING_SPAM_TRUNCATED = iota STRING_SPAM_KILLING_SPAMMER_DETAIL = iota STRING_SPAM_AUTOBANNED_REASON = iota STRING_SPAM_BAN_ALERT = iota STRING_SPAM_ERROR_RETRIEVE_MESSAGES = iota STRING_SPAM_WILL_BE_UNSILENCED = iota STRING_SPAM_SILENCE_ALERT = iota STRING_SPAM_KILLING_SPAMMER = iota STRING_SPAM_REASON_MESSAGES = iota STRING_SPAM_REASON_FILES = iota STRING_SPAM_REASON_IMAGES = iota STRING_SPAM_REASON_PINGS = iota STRING_SPAM_REASON_LENGTH = iota STRING_SPAM_REASON_NEWLINES = iota STRING_SPAM_REASON_COPY = iota STRING_SPAM_GUILD_NOT_FOUND = iota STRING_SPAM_VERIFICATION_LEVEL_ERROR = iota STRING_SPAM_LOCKDOWN_DISENGAGE_FAILURE = iota STRING_SPAM_LOCKDOWN_DISENGAGE = iota STRING_SPAM_USER_JOINED = iota STRING_SPAM_JOINED_APPEND = iota STRING_SPAM_RAIDSILENCE_ALL_POSTFIX = iota STRING_SPAM_RAIDSILENCE_ENGAGED = iota STRING_SPAM_RAID_DETECTED = iota STRING_SPAM_LOCKDOWN_ENGAGE_FAILURE = iota STRING_SPAM_LOCKDOWN_ENGAGE = iota STRING_SPAM_RAIDSILENCE_USAGE = iota STRING_SPAM_RAIDSILENCE_ARGS_ERROR = iota STRING_SPAM_RAIDSILENCE_ARGS = iota STRING_SPAM_RAIDSILENCE_DATABASE_ERROR = iota STRING_SPAM_RAIDSILENCE_SET_RAID = iota STRING_SPAM_RAIDSILENCE_DETECTION = iota STRING_SPAM_RAIDSILENCE_SET = iota STRING_SPAM_RAIDSILENCE_DESCRIPTION = iota STRING_SPAM_RAIDSILENCE_DESCRIPTION_NAME = iota STRING_SPAM_WIPE_USAGE = iota STRING_SPAM_WIPE_ARG_ERROR = iota STRING_SPAM_WIPE_PM_ERROR = iota STRING_SPAM_WIPE_CHANNEL_ERROR = iota STRING_SPAM_WIPE_NO_MESSAGES = iota STRING_SPAM_WIPE_RETRIEVAL_ERROR = iota STRING_SPAM_WIPE_DELETED = iota STRING_SPAM_WIPE_DESCRIPTION = iota STRING_SPAM_WIPE_CHANNEL = iota STRING_SPAM_WIPE_MESSAGES = iota STRING_SPAM_PRESSURE_USAGE = iota STRING_SPAM_PRESSURE_ARG_ERROR = iota STRING_SPAM_PRESSURE_DESCRIPTION = iota STRING_SPAM_PRESSURE_USER = iota STRING_SPAM_RAID_USAGE = iota STRING_SPAM_RAID_NONE = iota STRING_SPAM_RAID_USERS = iota STRING_SPAM_RAID_DESCRIPTION = iota STRING_SPAM_BANRAID_USAGE = iota STRING_SPAM_BANRAID_REASON = iota STRING_SPAM_BANRAID_RESULT = iota STRING_SPAM_BANRAID_DESCRIPTION = iota STRING_USERS_BAN_MOD_ERROR = iota STRING_USERS_SILENCE_USAGE = iota STRING_USERS_SILENCE_ARG_ERROR = iota STRING_USERS_SILENCE_ERROR = iota STRING_USERS_SILENCE_MOD_ERROR = iota STRING_USERS_SILENCE_ALREADY_SILENCED = iota STRING_USERS_SILENCE_WILL_BE_UNSILENCED = iota STRING_USERS_SILENCE_REASON = iota STRING_USERS_SILENCE = iota STRING_USERS_SILENCE_DESCRIPTION = iota STRING_USERS_SILENCE_USER = iota STRING_USERS_SILENCE_DURATION = iota STRING_USERS_UNSILENCE_USAGE = iota STRING_USERS_UNSILENCE_ARG_ERROR = iota STRING_USERS_UNSILENCE_ERROR = iota STRING_USERS_UNSILENCE_MOD_ERROR = iota STRING_USERS_UNSILENCE = iota STRING_USERS_UNSILENCE_DESCRIPTION = iota STRING_USERS_UNSILENCE_USER = iota )
const ( MaxPublicLines = 12 SilverServerID = "105443346608095232" PatreonURL = "https://www.patreon.com/erikmcclure" QuitNone = 0 QuitNow = 1 QuitRaid = 2 UpdateGrace = 120 MaxUpdateGrace = 600 UpdateInterval = 300 CleanInterval = 3600 ExpireTime = 3600 * 72 MaxScheduleRows = 5000 DelayTime = time.Duration(200 * time.Millisecond) )
const ( FormatPartialYear = 0 FormatFullYear = 1 FormatNoYear = 2 FormatYearNum = 3 FormatStandard = 0 FormatMilitary = 1 FormatNoTime = 2 FormatTimeNum = 3 FormatZoneOffset = 0 FormatZoneHours = 1 FormatNoZone = 2 FormatZoneNum = 3 )
Time format options
const DBReconnectTimeout = time.Duration(30) * time.Second
DBReconnectTimeout is the reconnect time interval in seconds
const DiscordEpoch uint64 = 1420070400000
DiscordEpoch is used to figure out snowflake creation times
Variables ¶
var BotVersion = Version{1, 0, 2, 1}
BotVersion stores the current version of sweetiebot
var ChannelRegex = regexp.MustCompile("<#([0-9]+)>")
ChannelRegex matches any valid discord channel ping
var ConfigHelp = map[string]map[string]string{
"basic": {
"ignoreinvalidcommands": "If true, the bot won't display an error if a nonsensical command is used. This helps reduce confusion with other bots that use the same prefix.",
"importable": "If true, the collections on this server will be importable into another server.",
"modrole": "This is intended to point at a moderator role shared by all admins and moderators of the server for notification purposes.",
"modchannel": "This should point at the hidden moderator channel, or whatever channel moderates want to be notified on.",
"freechannels": "This is a list of all channels that are exempt from bot command rate limiting. Usually set to the dedicated `#botabuse` channel in a server. Does NOT affect anti-spam! To exclude anti-spam from a channel, use `!setconfig modules.channels spam ! #yourchannel`.",
"botchannel": "This allows you to designate a particular channel to point users if they are trying to run too many commands at once. Usually this channel will also be included in `basic.freechannels`. Again, this is for bot commands, not general spamming!",
"aliases": "Can be used to redirect commands, such as making `!listgroup` call the `!listgroups` command. Useful for making shortcuts.\n\nExample: `!setconfig basic.aliases kawaii pick cute` sets an alias mapping `!kawaii arg1...` to `!pick cute arg1...`, preserving all arguments that are passed to the alias.",
"listentobots": "If true, processes messages from other bots and allows them to run commands. Bots can never trigger anti-spam. Defaults to false.",
"commandprefix": "Determines the SINGLE ASCII CHARACTER prefix used to denote bot commands. You can't set it to an emoji or any weird foreign character. The default is `!`. If this is set to an invalid value, it defaults to `!`.",
"silencerole": "This should be a role with no permissions, so the bot can quarantine potential spammers without banning them. The bot usually manages this role for you, so you should almost never touch this value.",
"memberrole": "This should be a role with all permissions that the everyone role would normally have. You shouldn't touch this value, use the !SetMemberRole command to manage it instead.",
},
"modules": {
"commandroles": "A map of which roles are allowed to run which command. If no mapping exists, everyone can run the command.",
"commandchannels": "A map of which channels commands are allowed to run on. No entry means a command can be run anywhere. If `!` is included as a channel, it switches from a whitelist to a blacklist, enabling you to exclude certain channels instead of allow certain channels.",
"commandlimits": "A map of timeouts for commands. A value of 30 means the command can't be used more than once every 30 seconds.",
"commanddisabled": "A list of disabled commands. Disabled commands can still be run by administrators, but can't be run by the bot and will not function as a bored command.",
"commandperduration": "Maximum number of commands that can be run within `commandmaxduration` seconds. Default: 3",
"commandmaxduration": "Default: 20. This means that by default, at most 3 commands can be run every 20 seconds.",
"disabled": "A list of disabled modules. This disables any hooks the modules normally process, and also disables all commands inside that module (although commands can be selectively re-enabled without enabling the module).",
"channels": "A mapping of what channels a given module can operate on. If no mapping is given, a module operates on all channels. If `!` is included as a channel, it switches from a whitelist to a blacklist, enabling you to exclude certain channels instead of allow certain channels. Restricting a module to a channel DOES NOT restrict its commands to that channel.",
},
"spam": {
"imagepressure": "Additional pressure generated by each image, link or attachment in a message. Defaults to (MaxPressure - BasePressure) / 6 = 8.3, instantly silencing anyone posting 6 or more links at once.",
"repeatpressure": "Additional pressure generated by a message that is identical to the previous message sent (ignores case). Defaults to BasePressure, effectively doubling the pressure penalty for repeated messages.",
"pingpressure": "Additional pressure generated by each unique ping in a message. Defaults to (MaxPressure - BasePressure) / 20 = 2.5, instantly silencing anyone pinging 20 or more people at once.",
"lengthpressure": "Additional pressure generated by each individual character in the message. Discord allows messages up to 2000 characters in length. Defaults to (MaxPressure - BasePressure) / 8000 = 0.00625, silencing anyone posting 3 huge messages at the same time.",
"linepressure": "Additional pressure generated by each newline in the message. Defaults to (MaxPressure - BasePressure) / 70 = 0.714, silencing anyone posting more than 70 newlines in a single message",
"basepressure": "The base pressure generated by sending a message, regardless of length or content. Defaults to 10",
"maxpressure": "The maximum pressure allowed. If a user's pressure exceeds this amount, they will be silenced. Defaults to 60, which is intended to ban after a maximum of 6 short messages sent in rapid succession.",
"maxchannelpressure": "Per-channel pressure override. If a channel's pressure is specified in this map, it will override the global maxpressure setting.",
"pressuredecay": "The number of seconds it takes for a user to lose Spam.BasePressure from their pressure amount. Defaults to 2.5, so after sending 3 messages, it will take 7.5 seconds for their pressure to return to 0.",
"maxremovelookback": "Number of seconds back the bot should delete messages of a silenced user on the channel they spammed on. If set to 0, the bot will only delete the message that caused the user to be silenced. If less than 0, the bot won't delete any messages.",
"ignorerole": "If set, the bot will exclude anyone with this role from spam detection. Use with caution. Does NOT prevent people from sending the bot commands.",
"raidtime": "In order to trigger a raid alarm, at least `spam.raidsize` people must join the chat within this many seconds of each other.",
"raidsize": "Specifies how many people must have joined the server within the `spam.raidtime` period to qualify as a raid.",
"raidsilence": "Gets the current raidsilence state. Use the `!RaidSilence` command to set this.",
"lockdownduration": "Determines how long the server's verification mode will temporarily be increased to tableflip levels after a raid is detected. If set to 0, disables lockdown entirely.",
"silencetimeout": "If greater than 0, any members silenced by the bot (not by the `!silence` command) will be automatically unsilenced after this many seconds. This includes anyone silenced during a raid.",
},
"bucket": {
"maxitems": "Determines the maximum number of items that can be carried in the bucket. If set to 0, the bucket is disabled.",
"maxitemlength": "Determines the maximum length of a string that can be added to the bucket.",
"maxfighthp": "Maximum HP of the randomly generated enemy for the `!fight` command.",
"maxfightdamage": "Maximum amount of damage a randomly generated weapon can deal for the `!fight` command.",
"items": "List of items in the bucket.",
},
"markov": {
"maxpmlines": "This is the maximum number of lines a response can be before its automatically sent as a PM to avoid cluttering the chat. Default: 5",
"maxlines": "Maximum number of lines the `!episodequote` command can be given.",
"defaultlines": "Number of lines for the markov chain to spawn when not given a line count.",
"usemembernames": "Use member names instead of random pony names.",
},
"users": {
"timezonelocation": "Sets the timezone location of the server itself. When no user timezone is available, the bot will use this.",
"welcomechannel": "If set to a channel ID, the bot will treat this channel as a \"quarantine zone\" for new members that haven't had their Member role set. If RaidSilence is enabled, new users will be sent to this channel.",
"jailchannel": "If set to a channel ID, the bot will treat this channel as a \"quarantine zone\" for silenced members. This can be the same as the welcome channel, or it can be a different one.",
"welcomemessage": "If RaidSilence is enabled, this message will be sent to a new user upon joining.",
"silencemessage": "This message will be sent to users that have been silenced by the `!silence` command.",
"roles": "A list of all user-assignable roles. Manage it via !addrole and !removerole",
"notifychannel": "If set to a channel ID other than zero, sends a message to that channel whenever a new user joins the server.",
"trackuserleft": "If true, tracks users that leave the server if notifychannel is set.",
"newuserrole": "If this is set and `newuserduration` is nonzero, this role is given to any new user that joins, regardless of raid settings. It is automatically removed after `newuserduration` seconds.",
"newuserduration": "The number of seconds a new user will have the `newuserrole` role. If zero, `newuserrole` won't be given to any new user.",
},
"filter": {
"filters": "A collection of word lists for each filter. These are combined into a single regex of the form `(word1|word2|etc...)`, depending on the filter template.",
"channels": "A collection of channel exclusions for each filter.",
"responses": "The response message sent by each filter when triggered. If this is set to `!`, the bot won't respond AND she won't delete the message, only the pressure will be added.",
"templates": "The template used to construct the regex. `%%` is replaced with `(word1|word2|etc...)` using the filter's word list. Example: `\\[\\]\\(\\/r?%%[-) \"]` is transformed into `\\[\\]\\(\\/r?(word1|word2)[-) \"]`",
"pressure": "The amount of pressure added to the user when the filter is triggered (defaults to 0).",
},
"bored": {
"cooldown": "The bored cooldown timer, in seconds. This is the length of time a channel must be inactive before a bored message is posted.",
"exponent": "The exponential increase in time between bored posts if no one other than the bot is posting. A value of about 1.41 doubles the amount of time between bored posts until someone else says something. Defaults to 1, which means no increase. The actual formula is (2^n + n).",
"commands": "This determines what commands will be run when nothing has been said in a channel for a while. One command will be chosen from this list at random.\n\nExample: `!setconfig bored.commands !drop \"!pick bored\"`",
},
"information": {
"rules": "Contains a list of numbered rules. The numbers do not need to be contiguous, and can be negative.",
"hidenegativerules": "If true, `!rules -1` will display a rule at index -1, but `!rules` will not. This is useful for joke rules or additional rules that newcomers don't need to know about.",
},
"log": {
"channel": "This is the channel where log output is sent.",
"cooldown": "The cooldown time to display an error message, in seconds, intended to prevent the bot from spamming itself. Default: 4",
},
"witty": {
"responses": "Stores the replies used by the Witty module and must be configured using `!addwit` or `!removewit`",
"cooldown": "The cooldown time for the witty module. At least this many seconds must have passed before the bot will make another witty reply.",
},
"scheduler": {
"birthdayrole": " This is the role given to members on their birthday.",
},
"miscellaneous": {
"maxsearchresults": "Maximum number of search results that can be requested at once.",
},
"spoiler": {
"channels": "A list of channels that are exempt from the spoiler rules.",
},
"status": {
"cooldown": "Number of seconds the bot waits before changing its status to a string picked randomly from the `status` collection.",
"lines": "List of possible status messages that the bot can have.",
},
"quote": {
"quotes": "This is a map of quotes, which should be managed via `!addquote` and `!removequote`.",
},
"counters": {
"map": "This is a map of counters, which should be managed via `!addcounter` and `!removecounter`.",
"descriptions": "These are descriptions for each counter in map, which should be managed via `!addcounter` and `!removecounter`.",
},
}
ConfigHelp is a map of help strings for the configuration options above
var ConfigVersion = 30
ConfigVersion is the latest version of the config file
var ErrDuplicateEntry = errors.New("Error 1062: Duplicate entry for unique key")
ErrDuplicateEntry - Error 1062: Duplicate entry for unique key
var ErrLockWaitTimeout = errors.New("Error 1205: Lock wait timeout exceeded")
ErrLockWaitTimeout - Error 1205: Lock wait timeout exceeded
var ErrMD5Error = errors.New("MD5 mismatch, file corrupt")
var ErrRoleNoMatch = errors.New("role doesn't exist on this server")
ErrRoleNoMatch is thrown when a role name doesn't exist on the server
var RoleRegex = regexp.MustCompile("<\\\\?@&([0-9]+)>")
RoleRegex matches any valid role ping
var StringMap = map[int]string{ STRING_INVALID_COMMAND: "Sorry, %s is not a valid command.\nFor a list of valid commands, type %shelp.", STRING_PM_FAILURE: "I tried to send you a Private Message, but it failed! Try PMing me the command directly.", STRING_CHECK_PM: "```\nCheck your Private Messages for my reply!```", STRING_DATABASE_ERROR: "```\nA temporary database error means I can't process any private message commands right now.```", STRING_NO_SERVER: "```\nCannot determine what server you belong to! Use !defaultserver to set which server I should use when you PM me.```", STRING_COMMANDS_LIMIT: "You can't input more than %v commands every %s!%s", STRING_COMMAND_LIMIT: "You can only run that command once every %s!%s", STRING_SETUP_MESSAGE: "You haven't set up the bot yet! Run the %ssetup command first and follow the instructions.", STRING_SPAM_DESCRIPTION: "Tracks all channels it is active on for spammers. Each message someone sends generates \"pressure\", which decays rapidly. Long messages, messages with links, or messages with pings will generate more pressure. If a user generates too much pressure, they will be silenced and the moderators notified. Also detects groups of people joining at the same time and alerts the moderators of a potential raid.\n\nTo force this module to ignore a specific channel, use this command: `%ssetconfig modules.channels spam ! #channelname`. If the bot is silencing everyone, you should re-run `%ssetup OVERRIDE` to reset the spam configuration. If you want to have a containment channel where silenced members can talk, use `%ssetconfig welcomechannel #channelname`.\n\n**IF THE BOT IS OVERWHELMED BY A RAID, FOLLOW THESE INSTRUCTIONS CAREFULLY:** Due to rate limits, the bot can be overwhelmed by spammers using hundreds of different accounts. As a last resort, you can tell the bot to **ban everyone who has sent their first message in the past 3 minutes** by running this command: `%sbannewcomers`. Only use this as a **last resort**, as it can easily ban people who joined and were caught up in the raid.", STRING_SPAM_ERROR_UNSILENCING: "```\nError unsilencing member: %v```", STRING_SPAM_UNSILENCING: "```\nUnsilenced %v.```", STRING_SPAM_EMBEDDED_URLS: "\nEmbedded URLs: ", STRING_SPAM_TRUNCATED: "... [truncated]", STRING_SPAM_KILLING_SPAMMER_DETAIL: "Killing spammer %s (pressure: %v -> %v). Last message sent on #%s in %s: \n%s%s", STRING_SPAM_AUTOBANNED_REASON: "Autobanned for %v in the welcome channel.", STRING_SPAM_BAN_ALERT: "Alert: <@%v> was banned for %v in the welcome channel.", STRING_SPAM_ERROR_RETRIEVE_MESSAGES: "Error encountered while attempting to retrieve messages: ", STRING_SPAM_WILL_BE_UNSILENCED: ", or they will be unsilenced automatically in %v", STRING_SPAM_SILENCE_ALERT: "Alert: <@%v> was silenced for %v. Please investigate%v", STRING_SPAM_KILLING_SPAMMER: "Killing spammer %v", STRING_SPAM_REASON_MESSAGES: "spamming too many messages", STRING_SPAM_REASON_FILES: "attaching too many files", STRING_SPAM_REASON_IMAGES: "spamming too many images", STRING_SPAM_REASON_PINGS: "pinging too many people", STRING_SPAM_REASON_LENGTH: "sending a really long message", STRING_SPAM_REASON_NEWLINES: "using too many newlines", STRING_SPAM_REASON_COPY: "copy+pasting the same message", STRING_SPAM_GUILD_NOT_FOUND: "Guild cannot be found in state?!", STRING_SPAM_VERIFICATION_LEVEL_ERROR: "The verification level is at %v instead of %v, which means it was manually changed by someone other than %v, so it has not been restored.", STRING_SPAM_LOCKDOWN_DISENGAGE_FAILURE: "Could not disengage lockdown! Make sure you've given the %v role the Manage Server permission, you'll have to manually restore it yourself this time.", STRING_SPAM_LOCKDOWN_DISENGAGE: "Lockdown disengaged, server verification levels restored.", STRING_SPAM_USER_JOINED: "%v (joined: %v)", STRING_SPAM_RAIDSILENCE_ALL_POSTFIX: "Use `%vraidsilenceall to silence them!", STRING_SPAM_RAIDSILENCE_ENGAGED: "RaidSilence has been engaged and the following users silenced:", STRING_SPAM_RAID_DETECTED: " Possible Raid Detected! ", STRING_SPAM_LOCKDOWN_ENGAGE_FAILURE: "Could not engage lockdown! Make sure you've given %v the Manage Server permission, or disable the lockdown entirely via `%vsetconfig spam.lockdownduration 0`.", STRING_SPAM_LOCKDOWN_ENGAGE: "Lockdown engaged! Server verification level will be reset in %v seconds. This lockdown can be manually ended via `%vraidsilence off/alert/log`.", STRING_SPAM_RAIDSILENCE_USAGE: "Toggle raid silencing.", STRING_SPAM_RAIDSILENCE_ARGS_ERROR: "```\nYou must provide a raid silence level (either all, raid, or off).```", STRING_SPAM_RAIDSILENCE_ARGS: "```\nOnly all, raid, and off are valid raid silence levels.```", STRING_SPAM_RAIDSILENCE_DATABASE_ERROR: "```\nRaidSilence was engaged, but a database error prevents me from retroactively applying it!```", STRING_SPAM_RAIDSILENCE_SET_RAID: "```\nRaid silence level set to %v.```", STRING_SPAM_RAIDSILENCE_DETECTION: "```\nDetected a recent raid. All users from the raid have been silenced:", STRING_SPAM_RAIDSILENCE_SET: "```\nRaid silence level set to %v.```", STRING_SPAM_RAIDSILENCE_DESCRIPTION: "Toggles silencing new members during raids. This does not affect spam detection, only new members joining the server.", STRING_SPAM_RAIDSILENCE_DESCRIPTION_NAME: "`all` will always silence all new members. `raid` will only silence new members if a raid is detected, up to `spam.raidtime*2` seconds after the raid is detected. `off` disables raid silencing.", STRING_SPAM_WIPE_USAGE: "Wipes a given channel", STRING_SPAM_WIPE_ARG_ERROR: "```\nYou must specify the duration.```", STRING_SPAM_WIPE_PM_ERROR: "```\nCan't delete messages in a PM!```", STRING_SPAM_WIPE_CHANNEL_ERROR: "```\nThat channel isn't on this server!```", STRING_SPAM_WIPE_NO_MESSAGES: "```\nThere's no point deleting 0 messages!.```", STRING_SPAM_WIPE_RETRIEVAL_ERROR: "```\nError retrieving messages. Are you sure you gave %v a channel that exists? This won't work in PMs! %v```", STRING_SPAM_WIPE_DELETED: "Deleted %v messages in <#%s>.", STRING_SPAM_WIPE_DESCRIPTION: "Removes all messages in a channel sent within the last N seconds, or remove the last N messages if 'm' is appended to the number. Examples: ```\n%swipe 23m``` ```\n%swipe #channel 10```", STRING_SPAM_WIPE_CHANNEL: "The channel to delete from. You must use the #channel format so discord actually highlights the channel, otherwise it won't work. If omitted, uses the current channel", STRING_SPAM_WIPE_MESSAGES: "Specifies the number of seconds to look back. The command deletes all messages sent up to this many seconds ago. If you append 'm' to this number, it will instead delete exactly that many messages.", STRING_SPAM_PRESSURE_USAGE: "Gets a user's pressure.", STRING_SPAM_PRESSURE_ARG_ERROR: "```\nYou must provide a user to search for.```", STRING_SPAM_PRESSURE_DESCRIPTION: "Gets the current spam pressure of a user.", STRING_SPAM_PRESSURE_USER: "User to retrieve pressure from.", STRING_SPAM_RAID_USAGE: "Lists users in most recent raid.", STRING_SPAM_RAID_NONE: "```\nNo raid has occurred within the past %s.```", STRING_SPAM_RAID_USERS: "Users in latest raid: ", STRING_SPAM_RAID_DESCRIPTION: "Lists all users that are considered part of the most recent raid, if there was one.", STRING_SPAM_BANRAID_USAGE: "Bans all users in most recent raid.", STRING_SPAM_BANRAID_REASON: "Banned by %s#%s via the %sbanraid command.", STRING_SPAM_BANRAID_RESULT: "```\nBanned %v users. The ban log will reflect who ran this command.```", STRING_SPAM_BANRAID_DESCRIPTION: "Bans all users that are considered part of the most recent raid, if there was one. Use %vgetraid to check who will be banned before using this command.", STRING_USERS_BAN_MOD_ERROR: "```\nCan't ban %s because they're a moderator or an admin!```", STRING_USERS_SILENCE_USAGE: "Silences a user.", STRING_USERS_SILENCE_ARG_ERROR: "```\nYou must provide a user to silence.```", STRING_USERS_SILENCE_ERROR: "```\nError occurred trying to silence %s: %s```", STRING_USERS_SILENCE_MOD_ERROR: "```\nCannot silence %s because they're a moderator or admin!```", STRING_USERS_SILENCE_ALREADY_SILENCED: "```\n%v is already silenced!```", STRING_USERS_SILENCE_WILL_BE_UNSILENCED: "```\n%s is already silenced, and will be unsilenced in %s```", STRING_USERS_SILENCE_REASON: " because %v", STRING_USERS_SILENCE: "```\nSilenced %s%s.```", STRING_USERS_SILENCE_DESCRIPTION: "Silences the given user.", STRING_USERS_SILENCE_USER: "A ping of the user, or simply their name.", STRING_USERS_SILENCE_DURATION: "If the keyword `for:` is used after the username, looks for a duration of the form `for: 50 MINUTES` and creates an unsilence event that will be fired after that much time has passed from now.", STRING_USERS_UNSILENCE_USAGE: "Unsilences a user.", STRING_USERS_UNSILENCE_ARG_ERROR: "```\nYou must provide a user to unsilence.```", STRING_USERS_UNSILENCE_ERROR: "```\nError unsilencing member: %v```", STRING_USERS_UNSILENCE_MOD_ERROR: "```\nCannot unsilence %s because they are a mod or admin. Remove the status yourself!```", STRING_USERS_UNSILENCE: "```\nUnsilenced %v.```", STRING_USERS_UNSILENCE_DESCRIPTION: "Unsilences the given user.", STRING_USERS_UNSILENCE_USER: "A ping of the user, or simply their name.", }
System-wide string map that can be substituted at runtime
var UserRegex = regexp.MustCompile("<\\\\?@!?([0-9]+)>")
UserRegex matches any valid user or nickname ping
Functions ¶
func AbsInt ¶
I'm going to find whoever is responsible for not including this in Go's standard library and dump them in the middle of Death Valley with an entire cactus shoved up their ass.
func AssembleVersion ¶
AssembleVersion creates a version integer out of four bytes
func CheckMapNilBool ¶
CheckMapNilBool creates a new map if its nil
func CheckMapNilString ¶
CheckMapNilString creates a new map if its nil
func CheckRateLimit ¶
CheckRateLimit performs a check on the rate limit without updating it
func DownloadFile ¶
DownloadFile downloads a file from the url and attempts to get a *.md5 to check it against if checkMD5 is true
func DumpCommandsModules ¶
func DumpCommandsModules(info *GuildInfo, footer string, description string, msg *discordgo.Message) *discordgo.MessageEmbed
DumpCommandsModules dumps information about all commands and modules
func DumpScript ¶
func DumpScript(dir string)
func ExecCommand ¶
ExecCommand adds a directory and environment to a command created by exec.Command()
func ExecuteSQLFile ¶
ExecuteSQLFile splits a file into statements and executes it
func FindUpgradeFiles ¶
FindUpgradeFiles finds the .sql upgrade files that should be run
func FixRequest ¶
FixRequest takes a request that is not fully qualified and attempts to find a fully qualified version
func GetJoinedAt ¶
GetJoinedAt returns either the time the member joined or time.Now() if there is an error
func GetRoleByName ¶
GetRoleByName gets a role by its name
func GetTimestamp ¶
GetTimestamp returns the timestamp of the last edit of the message or time.Now() if there is no valid timestamp
func GuildMemberPermissions ¶
GuildMemberPermissions gets all permissions for a user, ignoring channel specific overrides
func HTTPRequestData ¶
HTTPRequestData returns the result of an HTTP request as a byte array
func MapGetRandomItem ¶
MapGetRandomItem returns a random item from a map without removing it
func MapStringToSlice ¶
MapStringToSlice for map[string]string
func MemberHasRole ¶
func MemberHasRole(m *discordgo.Member, role DiscordRole) bool
MemberHasRole returns true if the already resolved member object has the given role ID
func ParseArguments ¶
ParseArguments transforms a command line into an array of distinct arguments, while respecting quotes
func ParseRepeatInterval ¶
ParseRepeatInterval returns what interval a string refers to
func Pluralize ¶
Pluralize converts i to a string, then appends str to the end, then appends s if it's plural
func RateLimit ¶
RateLimit checks the rate limit, returns false if it was violated, and updates the rate limit
func RemoveSliceString ¶
RemoveSliceString finds and removes an item from the slice
func ReplaceAllRolePings ¶
ReplaceAllRolePings finds any role pings and replaces them with the role name
func ReturnError ¶
func ReturnError(err error) (string, bool, *discordgo.MessageEmbed)
ReturnError formats an error message and returns it as a message
func RunCommand ¶
RunCommand runs the given command and prints any output
func SnowflakeTime ¶
SnowflakeTime returns the time a snowflake ID was created
func StartCommand ¶
StartCommand starts the given command but doesn't wait for it to complete
func UpdateEndpoint ¶
func UpdateEndpoint(request string, userID DiscordUser, oldversion int) string
UpdateEndpoint returns the update endpoint for the given id and current architecture
func WaitForPID ¶
func WaitForPID(arg string)
WaitForPID loops until there is no longer any running process with the given PID, or returns immediately if no valid ID is given
Types ¶
type AtomicBool ¶
type AtomicBool struct {
// contains filtered or unexported fields
}
AtomicBool represents an atomic boolean that can be set to true or false
type AtomicFlag ¶
type AtomicFlag struct {
// contains filtered or unexported fields
}
AtomicFlag represents an atomic bit that can be set or cleared
func (*AtomicFlag) TestAndSet ¶
func (f *AtomicFlag) TestAndSet() bool
TestAndSet returns the old value and sets the flag to 1
type BotConfig ¶
type BotConfig struct { Version int `json:"version"` LastVersion int `json:"lastversion"` SetupDone bool `json:"setupdone"` Expires int64 `json:"expires"` Basic struct { IgnoreInvalidCommands bool `json:"ignoreinvalidcommands"` Importable bool `json:"importable"` ModRole DiscordRole `json:"modrole"` ModChannel DiscordChannel `json:"modchannel"` FreeChannels map[DiscordChannel]bool `json:"freechannels"` BotChannel DiscordChannel `json:"botchannel"` Aliases map[string]string `json:"aliases"` ListenToBots bool `json:"listentobots"` CommandPrefix string `json:"commandprefix"` SilenceRole DiscordRole `json:"silencerole"` MemberRole DiscordRole `json:"memberrole"` } `json:"basic"` Modules struct { Channels map[ModuleID]map[DiscordChannel]bool `json:"modulechannels"` Disabled map[ModuleID]bool `json:"moduledisabled"` CommandRoles map[CommandID]map[DiscordRole]bool `json:"commandroles"` CommandChannels map[CommandID]map[DiscordChannel]bool `json:"commandchannels"` CommandLimits map[CommandID]int64 `json:"Commandlimits"` CommandDisabled map[CommandID]bool `json:"commanddisabled"` CommandPerDuration int `json:"commandperduration"` CommandMaxDuration int64 `json:"commandmaxduration"` } `json:"modules"` Spam struct { ImagePressure float32 `json:"imagepressure"` PingPressure float32 `json:"pingpressure"` LengthPressure float32 `json:"lengthpressure"` RepeatPressure float32 `json:"repeatpressure"` LinePressure float32 `json:"linepressure"` BasePressure float32 `json:"basepressure"` PressureDecay float32 `json:"pressuredecay"` MaxPressure float32 `json:"maxpressure"` MaxChannelPressure map[DiscordChannel]float32 `json:"maxchannelpressure"` MaxRemoveLookback int `json:"MaxSpamRemoveLookback"` IgnoreRole DiscordRole `json:"ignorerole"` RaidTime int64 `json:"maxraidtime"` RaidSize int `json:"raidsize"` RaidSilence int `json:"raidsilence"` LockdownDuration int `json:"lockdownduration"` SilenceTimeout int64 `json:"silencetimeout"` } `json:"spam"` Users struct { TimezoneLocation TimeLocation `json:"timezonelocation"` WelcomeChannel DiscordChannel `json:"welcomechannel"` JailChannel DiscordChannel `json:"jailchannel"` WelcomeMessage string `json:"welcomemessage"` SilenceMessage string `json:"silencemessage"` Roles map[DiscordRole]bool `json:"userroles"` NotifyChannel DiscordChannel `json:"joinchannel"` TrackUserLeft bool `json:"trackuserleft"` NewUserRole DiscordRole `json:"newuserrole"` NewUserDuration int64 `json:"newuserduration"` } `json:"users"` Bucket struct { MaxItems int `json:"maxbucket"` MaxItemLength int `json:"maxbucketlength"` MaxFightHP int `json:"maxfighthp"` MaxFightDamage int `json:"maxfightdamage"` Items map[string]bool `json:"items"` } `json:"bucket"` Markov struct { MaxPMlines int `json:"maxpmlines"` MaxLines int `json:"maxquotelines"` DefaultLines int `json:"defaultmarkovlines"` UseMemberNames bool `json:"usemembernames"` } `json:"markov"` Filter struct { Filters map[string]map[string]bool `json:"filters"` Channels map[string]map[DiscordChannel]bool `json:"channels"` Responses map[string]string `json:"responses"` Templates map[string]string `json:"templates"` Pressure map[string]float32 `json:"pressure"` } `json:"filter"` Bored struct { Cooldown int64 `json:"maxbored"` Exponent float64 `json:"exponent"` Commands map[string]bool `json:"boredcommands"` } Information struct { Rules map[int]string `json:"rules"` HideNegativeRules bool `json:"hidenegativerules"` } `json:"help"` Log struct { Cooldown int64 `json:"maxerror"` Channel DiscordChannel `json:"logchannel"` } `json:"log"` Witty struct { Responses map[string]string `json:"witty"` Cooldown int64 `json:"maxwit"` } `json:"Wit"` Scheduler struct { BirthdayRole DiscordRole `json:"birthdayrole"` } `json:"scheduler"` Miscellaneous struct { MaxSearchResults int `json:"maxsearchresults"` } `json:"misc"` Status struct { Cooldown int `json:"statusdelaytime"` Lines map[string]bool `json:"lines"` } `json:"status"` Quote struct { Quotes map[DiscordUser][]string `json:"quotes"` } `json:"quote"` Counters struct { Map map[string]int64 `json:"map"` Descriptions map[string]string `json:"counterdescriptions"` } `json:"counters"` }
BotConfig lists all bot configuration options, grouped into structs
func DefaultConfig ¶
func DefaultConfig() *BotConfig
DefaultConfig returns a default BotConfig struct. We can't define this as a variable because you can't initialize nested structs in a sane way in Go
func (*BotConfig) FillConfig ¶
func (config *BotConfig) FillConfig()
FillConfig ensures root maps are not nil
func (*BotConfig) IsCommandDisabled ¶
IsCommandDisabled returns a string if a command is disabled
func (*BotConfig) IsModuleDisabled ¶
IsModuleDisabled returns a string if a module is disabled
type BotDB ¶
type BotDB struct { Status AtomicBool // contains filtered or unexported fields }
BotDB contains the database connection and all database Prepared statements exposed as functions
func (*BotDB) AddMessage ¶
func (db *BotDB) AddMessage(id uint64, author *discordgo.User, message string, channel uint64, guild uint64)
AddMessage logs a message to the chatlog
func (*BotDB) AddSchedule ¶
AddSchedule adds an event to the schedule
func (*BotDB) AddScheduleRepeat ¶
func (db *BotDB) AddScheduleRepeat(guild uint64, date time.Time, repeatinterval uint8, repeat int, ty uint8, data string) error
AddScheduleRepeat adds a repeating event to the schedule
func (*BotDB) AddTranscript ¶
func (db *BotDB) AddTranscript(season int, episode int, line int, speaker string, text string) error
AddTranscript is used to construct the markov chain
func (*BotDB) CheckError ¶
CheckError logs any unknown errors and pings the database to check if it's still there
func (*BotDB) CheckStatus ¶
CheckStatus checks if the database connection has been lost
func (*BotDB) CountItems ¶
CountItems returns the number of unique items for a given server
func (*BotDB) CountNewUsers ¶
CountNewUsers returns a count of users joined in the given duration
func (*BotDB) DeleteSchedule ¶
DeleteSchedule deletes the event with the given ID regardless of it's repeat interval or activation time.
func (*BotDB) FindGuildUsers ¶
func (db *BotDB) FindGuildUsers(name string, maxresults uint64, offset uint64, guild uint64) []uint64
FindGuildUsers returns all users in a guild that could satisfy the given name.
func (*BotDB) FindTimeZone ¶
FindTimeZone returns all matching timezone locations
func (*BotDB) FindTimeZoneOffset ¶
FindTimeZoneOffset finds all timezones with the given offset
func (*BotDB) FindUser ¶
func (db *BotDB) FindUser(name string, discriminator int, maxresults uint64, offset uint64) []uint64
FindUser returns all users with the given name and discriminator (which should be only one but cache errors can happen)
func (*BotDB) GetAliases ¶
GetAliases returns all aliases for the given user
func (*BotDB) GetAuditRows ¶
func (db *BotDB) GetAuditRows(start uint64, end uint64, user *uint64, search string, guild uint64) []PingContext
GetAuditRows returns rows from the audit log
func (*BotDB) GetCharacterQuote ¶
func (db *BotDB) GetCharacterQuote(character string) Transcript
GetCharacterQuote gets a random character quote from the transcript
func (*BotDB) GetEvent ¶
func (db *BotDB) GetEvent(guild uint64, id uint64) *ScheduleEvent
GetEvent gets the event data for the given ID
func (*BotDB) GetEvents ¶
func (db *BotDB) GetEvents(guild uint64, maxnum int) []ScheduleEvent
GetEvents gets all events for a guild up to maxnum
func (*BotDB) GetEventsByType ¶
func (db *BotDB) GetEventsByType(guild uint64, ty uint8, maxnum int) []ScheduleEvent
GetEventsByType gets all events for a given type
func (*BotDB) GetItemTags ¶
GetItemTags returns all tags an item has on the given server
func (*BotDB) GetNewcomers ¶
GetNewcomers returns any users that posted recently
func (*BotDB) GetNewestUsers ¶
func (db *BotDB) GetNewestUsers(maxresults int, guild uint64) []struct { User *discordgo.User FirstSeen time.Time }
GetNewestUsers gets the last maxresults users to join the guild
func (*BotDB) GetNextEvent ¶
func (db *BotDB) GetNextEvent(guild uint64, ty uint8) ScheduleEvent
GetNextEvent gets the next event of the given type
func (*BotDB) GetRandomQuote ¶
func (db *BotDB) GetRandomQuote() Transcript
GetRandomQuote gets a random quote from the transcript
func (*BotDB) GetRecentUsers ¶
GetRecentUsers returns any users whose first message was sent after the given timestamp
func (*BotDB) GetReminders ¶
func (db *BotDB) GetReminders(guild uint64, id string, maxnum int) []ScheduleEvent
GetReminders gets reminders for the given user
func (*BotDB) GetSchedule ¶
func (db *BotDB) GetSchedule(guild uint64) []ScheduleEvent
GetSchedule gets all events for a guild
func (*BotDB) GetScheduleDate ¶
GetScheduleDate returns the date for the given event if it exists
func (*BotDB) GetSpeechQuote ¶
func (db *BotDB) GetSpeechQuote() Transcript
GetSpeechQuote gets a random speech quote from the transcript
func (*BotDB) GetTableCounts ¶
GetTableCounts returns a debug dump count of the tables
func (*BotDB) GetTimeZone ¶
GetTimeZone returns the evaluated timezone for the user
func (*BotDB) GetTranscript ¶
GetTranscript gets all lines that satisfy the query from the transcripts
func (*BotDB) GetUserGuilds ¶
GetUserGuilds returns all guilds a user is on
func (*BotDB) LoadStatements ¶
LoadStatements loads all Prepared statements
func (*BotDB) RemoveAlias ¶
RemoveAlias removes an alias from a user, if it exists.
func (*BotDB) RemoveGuild ¶
RemoveGuild removes the given guild from the database, if it exists
func (*BotDB) RemoveItem ¶
RemoveItem removes an item from all tags on the given server
func (*BotDB) RemoveMember ¶
RemoveMember removes a user from a guild
func (*BotDB) RemoveSchedule ¶
RemoveSchedule removes the event with the given ID and creates a new one after the repeat interval
func (*BotDB) RemoveTranscript ¶
RemoveTranscript removes a line from the transcripts
func (*BotDB) SentMessage ¶
SentMessage doesn't log a message, but sets a user's "firstseen" and "lastseen" values if necessary
func (*BotDB) SetDefaultServer ¶
SetDefaultServer sets a users default guild
type BotInstance ¶
type BotInstance struct { DG *DiscordGoSession SelfID string SelfAvatar string SelfName string AppID uint64 AppName string Token string `json:"token"` MainGuildID uint64 `json:"mainguildid"` IsUserMode bool `json:"runasuser"` // True if running as a user for some godawful reason }
BotInstance represents an instance of the bot using a given token that still runs off the same database as all the other instances
type Command ¶
type Command interface { Info() *CommandInfo Process([]string, *discordgo.Message, []int, *GuildInfo) (string, bool, *discordgo.MessageEmbed) Usage(*GuildInfo) *CommandUsage }
Command is any command that is addressed to the bot, optionally restricted by role.
type CommandInfo ¶
type CommandInfo struct { Name string Usage string ServerIndependent bool Sensitive bool Restricted bool Silver bool MainInstance bool }
CommandInfo defines the properties of a command
type CommandUsage ¶
type CommandUsage struct { Desc string Params []CommandUsageParam }
CommandUsage defines the help parameters for a command
type CommandUsageParam ¶
CommandUsageParam describes a single parameter to a command
type ConfigModule ¶
type ConfigModule struct { }
ConfigModule manages the configuration file
func (*ConfigModule) Description ¶
func (w *ConfigModule) Description(info *GuildInfo) string
Description of the module
type DebugModule ¶
type DebugModule struct {
// contains filtered or unexported fields
}
DebugModule contains various debugging commands
func (*DebugModule) Description ¶
func (w *DebugModule) Description(info *GuildInfo) string
Description of the module
type DiscordChannel ¶
type DiscordChannel string
DiscordChannel stores a channel ID
func NewDiscordChannel ¶
func NewDiscordChannel(i uint64) DiscordChannel
NewDiscordChannel constructs a new DiscordChannel from an integer
func ParseChannel ¶
func ParseChannel(s string, guild *discordgo.Guild) (DiscordChannel, error)
ParseChannel resolves multiple different channel tagging formats
func (DiscordChannel) Convert ¶
func (ch DiscordChannel) Convert() (i uint64)
Convert channel to integer
func (DiscordChannel) Show ¶
func (ch DiscordChannel) Show(info *GuildInfo) string
Show channel name if available, or display ping
func (DiscordChannel) String ¶
func (ch DiscordChannel) String() string
func (*DiscordChannel) UnmarshalJSON ¶
func (ch *DiscordChannel) UnmarshalJSON(d []byte) error
UnmarshalJSON is a custom unmarshal function for JSON
type DiscordGoSession ¶
DiscordGoSession overrides the discordgo session, allowing us to extend it and also lets us mock the base class methods for testing
func (*DiscordGoSession) BulkDeleteBypass ¶
func (s *DiscordGoSession) BulkDeleteBypass(channelID string, messages []string) (err error)
BulkDeleteBypass deletes in batches of 99
func (*DiscordGoSession) ChangeBotName ¶
func (s *DiscordGoSession) ChangeBotName(name string, avatarfile string) error
ChangeBotName changes the username and avatar of the bot
func (*DiscordGoSession) GetMember ¶
func (s *DiscordGoSession) GetMember(userID DiscordUser, guildID string) (*discordgo.Member, error)
GetMember attempts to get a member from the guild by checking the state first before making the REST API call.
func (*DiscordGoSession) GetMemberCreate ¶
GetMemberCreate creates a member if they don't exist, so it is guaranteed to return a Member
func (*DiscordGoSession) RemoveRole ¶
func (s *DiscordGoSession) RemoveRole(guildID string, userID DiscordUser, role DiscordRole) error
RemoveRole removes a role from the state and then sends a request to discord to remove it
func (*DiscordGoSession) ReplaceAllMentions ¶
func (s *DiscordGoSession) ReplaceAllMentions(str string, db *BotDB, guildID string) string
ReplaceAllMentions replaces mentions with usernames
func (*DiscordGoSession) UserHasAnyRole ¶
func (s *DiscordGoSession) UserHasAnyRole(user DiscordUser, guildID string, roles map[DiscordRole]bool) bool
UserHasAnyRole returns true if the user ID (as a string) has any of the role IDs given (as a map of strings)
func (*DiscordGoSession) UserPermissions ¶
func (s *DiscordGoSession) UserPermissions(userID DiscordUser, guildID string) (int64, error)
UserPermissions gets all permissions for a user, ignoring channel specific overrides
type DiscordGuild ¶
type DiscordGuild string
DiscordGuild stores a guild ID
func NewDiscordGuild ¶
func NewDiscordGuild(i uint64) DiscordGuild
NewDiscordGuild constructs a new DiscordGuild from an integer
func (DiscordGuild) String ¶
func (g DiscordGuild) String() string
type DiscordRole ¶
type DiscordRole string
DiscordRole stores a role ID
func NewDiscordRole ¶
func NewDiscordRole(i uint64) DiscordRole
NewDiscordRole constructs a new DiscordRole from an integer
func ParseRole ¶
func ParseRole(s string, guild *discordgo.Guild) (DiscordRole, error)
ParseRole resolves multiple different role tagging formats
func (DiscordRole) Show ¶
func (r DiscordRole) Show(info *GuildInfo) string
Show role name if available, or display ping
func (DiscordRole) String ¶
func (r DiscordRole) String() string
func (*DiscordRole) UnmarshalJSON ¶
func (r *DiscordRole) UnmarshalJSON(d []byte) error
UnmarshalJSON is a custom unmarshal function for JSON
type DiscordUser ¶
type DiscordUser string
DiscordUser stores a user ID
func NewDiscordUser ¶
func NewDiscordUser(i uint64) DiscordUser
NewDiscordUser constructs a new DiscordUser from an integer
func ParseUser ¶
func ParseUser(s string, info *GuildInfo) (DiscordUser, error)
ParseUser resolves multiple different user tagging formats
func (DiscordUser) String ¶
func (u DiscordUser) String() string
type GuildInfo ¶
type GuildInfo struct { ID string // Cache the ID because it doesn't change Name string // Cache the name to reduce locking OwnerID DiscordUser BotNick string // If not empty, the nickname assigned to the bot in this server Silver AtomicBool // Has paid features (always true if selfhosting) LastRaid int64 // Last time a raid was recorded by the spam module (or any other module that records raids) ConfigLock sync.RWMutex Config BotConfig Modules []Module Bot *SweetieBot // contains filtered or unexported fields }
GuildInfo Stores state information about a guild
func NewGuildInfo ¶
func NewGuildInfo(sb *SweetieBot, g *discordgo.Guild) *GuildInfo
NewGuildInfo spawns a new GuildInfo object with a default configuration
func (*GuildInfo) AddCommand ¶
AddCommand adds a command to the guild
func (*GuildInfo) ApplyTimezone ¶
ApplyTimezone transforms the given UTC time into local time for the given user
func (*GuildInfo) BulkDelete ¶
BulkDelete Performs a bulk deletion in groups of 100
func (*GuildInfo) ChannelMessageDelete ¶
func (info *GuildInfo) ChannelMessageDelete(channel *discordgo.Channel, messageID string) (err error)
ChannelMessageDelete checks the channel guildID before calling the real ChannelMessageDelete
func (*GuildInfo) ChannelPermissionSet ¶
func (info *GuildInfo) ChannelPermissionSet(channel *discordgo.Channel, targetID string, targetType discordgo.PermissionOverwriteType, allow, deny int64) (err error)
ChannelPermissionSet check the channel guildID before calling the real ChannelPermissionSet
func (*GuildInfo) Clean ¶
func (info *GuildInfo) Clean()
Clean out all commands or modules that no longer exist
func (*GuildInfo) FindChannelID ¶
FindChannelID returns the ID of the first channel in this guild with a matching name
func (*GuildInfo) FindUsername ¶
FindUsername returns all possible matching IDs for the given username
func (*GuildInfo) FormatUsage ¶
func (info *GuildInfo) FormatUsage(c Command, usage *CommandUsage) *discordgo.MessageEmbed
FormatUsage constructs a help string for the given command based on it's usage
func (*GuildInfo) GetBotName ¶
func (*GuildInfo) GetChannels ¶
GetChannels constructs a string describing the allowed channels a command can run on
func (*GuildInfo) GetMemberName ¶
GetMemberName gets either the nickname or username of a member
func (*GuildInfo) GetRoles ¶
GetRoles constructs a string describing the allowed roles for a command
func (*GuildInfo) GetTimezone ¶
func (info *GuildInfo) GetTimezone(user DiscordUser) *time.Location
GetTimezone gets the time.Location of the given user, if it exists, otherwise returns time.UTC
func (*GuildInfo) GetUserName ¶
func (info *GuildInfo) GetUserName(user DiscordUser) string
GetUserName returns a string representation of the user's name if possible, otherwise pings them.
func (*GuildInfo) IDsToUsernames ¶
IDsToUsernames converts an array of integer IDs to an array of username strings
func (*GuildInfo) IsDebug ¶
func (info *GuildInfo) IsDebug(channelID DiscordChannel) bool
IsDebug returns true if the channel is a debug channel
func (*GuildInfo) Log ¶
func (info *GuildInfo) Log(args ...interface{})
Log the given arguments to the server and the command line
func (*GuildInfo) MigrateSettings ¶
MigrateSettings from earlier config version
func (*GuildInfo) ParseCommonTime ¶
func (info *GuildInfo) ParseCommonTime(s string, user DiscordUser, timestamp time.Time) (time.Time, error)
ParseCommonTime iterates through every single imaginable time format that we could possibly parse
func (*GuildInfo) ProcessMember ¶
ProcessMember called ProcessUser and adds additional member information to the database
func (*GuildInfo) ProcessMembers ¶
ProcessMembers adds a member list to the database
func (*GuildInfo) ProcessModule ¶
func (info *GuildInfo) ProcessModule(channelID DiscordChannel, m Module) bool
ProcessModule returns true if a module should process events on this channel
func (*GuildInfo) RegisterModule ¶
RegisterModule registers a module with this guild
func (*GuildInfo) RequestPostWithBuffer ¶
func (info *GuildInfo) RequestPostWithBuffer(urlStr string, data *discordgo.MessageSend, minRemaining int) (response []byte, err error)
RequestPostWithBuffer uses a buffer and a buffer combination function to combine multiple messages if there are fewer than minRequests requests left in the current bucket
func (*GuildInfo) ResolveRoleAddError ¶
func (*GuildInfo) SaveConfig ¶
SaveConfig saves the config file to disk
func (*GuildInfo) SendEmbed ¶
func (info *GuildInfo) SendEmbed(channelID DiscordChannel, embed *discordgo.MessageEmbed) error
SendEmbed sends an embed message to the channel, splitting it into multiple messages if necessary
func (*GuildInfo) SendError ¶
func (info *GuildInfo) SendError(channelID DiscordChannel, message string, t int64)
SendError prints an error message with a saturation limit
func (*GuildInfo) SendMessage ¶
func (info *GuildInfo) SendMessage(channelID DiscordChannel, message string) error
SendMessage sends a message to the given channel, splitting it into multiple messages if necessary, and combining smaller messages if a rate limit is about to be hit
func (*GuildInfo) UserCanUseCommand ¶
func (info *GuildInfo) UserCanUseCommand(userID DiscordUser, command Command, ignore bool) (bypass bool, err error)
UserCanUseCommand returns nil if the user can use the command, or an error explaining why they can't. The boolean marks whether or not they bypass restrictions. Note that even moderators cannot use exclusive commands, only the owner of the bot can.
func (*GuildInfo) UserHasRole ¶
func (info *GuildInfo) UserHasRole(userID DiscordUser, role DiscordRole) bool
UserHasRole returns true if the specified user ID has the given role ID (both in strings)
func (*GuildInfo) UserIsAdmin ¶
func (info *GuildInfo) UserIsAdmin(userID DiscordUser) bool
UserIsAdmin returns true if the user is an admin or the owner of the bot. Always prefers returning false if any kind of error happens.
func (*GuildInfo) UserIsMod ¶
func (info *GuildInfo) UserIsMod(userID DiscordUser) bool
UserIsMod returns true if the user is a mod
type InfoModule ¶
type InfoModule struct { }
InfoModule contains help and about commands
func (*InfoModule) Description ¶
func (w *InfoModule) Description(info *GuildInfo) string
Description of the module
type Module ¶
Module monitors all incoming requests depending on what module interfaces they implement
type ModuleOnCommand ¶
ModuleOnCommand hook interface
type ModuleOnEvent ¶
ModuleOnEvent hook interface
type ModuleOnGuildBanAdd ¶
type ModuleOnGuildBanAdd interface { Module OnGuildBanAdd(*GuildInfo, *discordgo.GuildBanAdd) }
ModuleOnGuildBanAdd hook interface
type ModuleOnGuildBanRemove ¶
type ModuleOnGuildBanRemove interface { Module OnGuildBanRemove(*GuildInfo, *discordgo.GuildBanRemove) }
ModuleOnGuildBanRemove hook interface
type ModuleOnGuildMemberAdd ¶
type ModuleOnGuildMemberAdd interface { Module OnGuildMemberAdd(*GuildInfo, *discordgo.Member, time.Time) }
ModuleOnGuildMemberAdd hook interface
type ModuleOnGuildMemberRemove ¶
type ModuleOnGuildMemberRemove interface { Module OnGuildMemberRemove(*GuildInfo, *discordgo.Member, time.Time) }
ModuleOnGuildMemberRemove hook interface
type ModuleOnGuildMemberUpdate ¶
type ModuleOnGuildMemberUpdate interface { Module OnGuildMemberUpdate(*GuildInfo, *discordgo.Member, time.Time) }
ModuleOnGuildMemberUpdate hook interface
type ModuleOnGuildRoleDelete ¶
type ModuleOnGuildRoleDelete interface { Module OnGuildRoleDelete(*GuildInfo, *discordgo.GuildRoleDelete) }
ModuleOnGuildRoleDelete hook interface
type ModuleOnGuildUpdate ¶
ModuleOnGuildUpdate hook interface
type ModuleOnMessageCreate ¶
ModuleOnMessageCreate hook interface
type ModuleOnMessageDelete ¶
ModuleOnMessageDelete hook interface
type ModuleOnMessageUpdate ¶
ModuleOnMessageUpdate hook interface
type ModuleOnTick ¶
ModuleOnTick hook interface
type ModuleOnVoiceStateUpdate ¶
type ModuleOnVoiceStateUpdate interface { Module OnVoiceStateUpdate(*GuildInfo, *discordgo.VoiceState) }
ModuleOnVoiceStateUpdate hook interface
type PingContext ¶
PingContext contains a simplified context for a message
type SaturationLimit ¶
type SaturationLimit struct {
// contains filtered or unexported fields
}
SaturationLimit tracks when events occurred and implements a saturation limit on them
type ScheduleEvent ¶
ScheduleEvent describes an event in the schedule
type Selfhost ¶
type Selfhost struct { SelfhostBase Donors sync.Map //map[DiscordUser]bool // contains filtered or unexported fields }
Selfhost stores selfhost update state
type SelfhostBase ¶
type SelfhostBase struct {
Version int
}
func (*SelfhostBase) CheckDonor ¶
func (b *SelfhostBase) CheckDonor(m *discordgo.Member) bool
CheckDonor always returns false because donor status never changes when selfhosting
func (*SelfhostBase) CheckForUpdate ¶
func (b *SelfhostBase) CheckForUpdate(userID DiscordUser, oldversion int) (int8, *UpdateStatus)
CheckForUpdate returns 0 if no update is needed, -1 if you haven't bought selfhosting, and 1 plus a list of files that are needed if oldversion is nonzero.
func (*SelfhostBase) CheckGuilds ¶
func (b *SelfhostBase) CheckGuilds(guilds map[DiscordGuild]*GuildInfo)
CheckGuilds sets all guilds as silver unless there's more than 30
func (*SelfhostBase) ConfigureMux ¶
func (b *SelfhostBase) ConfigureMux(mux *http.ServeMux)
ConfigureMux has nothing to configure for selfhosters
func (*SelfhostBase) DoUpdate ¶
func (b *SelfhostBase) DoUpdate(dbauth string, token string) error
DoUpdate is the function run by updater.exe to perform the actual update
func (*SelfhostBase) GetWebDir ¶
func (b *SelfhostBase) GetWebDir() string
GetWebDir returns the directory where the website is
func (*SelfhostBase) SelfUpdate ¶
func (b *SelfhostBase) SelfUpdate(ownerid DiscordUser) error
SelfUpdate is run by sweetie.exe to to get a new version of updater.exe
func (*SelfhostBase) UpgradeDatabase ¶
func (b *SelfhostBase) UpgradeDatabase(scriptdir string, dbauth string) error
UpgradeDatabase does the database migration portion of the upgrade
type SweetieBot ¶
type SweetieBot struct { DB *BotDB DG *DiscordGoSession Debug bool `json:"debug"` SelfID DiscordUser SelfAvatar string SelfName string AppID uint64 AppName string Owner DiscordUser Token string `json:"token"` DBAuth string `json:"dbauth"` MainGuildID DiscordGuild `json:"mainguildid"` DebugChannels map[DiscordGuild]DiscordChannel `json:"debugchannels"` Guilds map[DiscordGuild]*GuildInfo GuildsLock sync.RWMutex LastMessages map[DiscordChannel]int64 LastMessageLock sync.RWMutex MaxConfigSize int `json:"maxconfigsize"` MaxUniqueItems uint64 `json:"maxuniqueitems"` StartTime int64 MessageCount uint32 // 32-bit so we can do atomic ops on a 32-bit platform Selfhoster *Selfhost IsUserMode bool `json:"runasuser"` // True if running as a user for some godawful reason WebSecure bool `json:"websecure"` WebDomain string `json:"webdomain"` WebPort string `json:"webport"` EmptyGuild *GuildInfo // Holds an empty GuildInfo for running server independent commands UpdateLock AtomicFlag Markov *markovChain // contains filtered or unexported fields }
SweetieBot is the primary bot object containing the bot state
func New ¶
func New(token string, loader func(*GuildInfo) []Module) *SweetieBot
New creates and initializes a new instance of Sweetiebot that's ready to connect. Returns nil on error.
func (*SweetieBot) AttachToGuild ¶
func (sb *SweetieBot) AttachToGuild(g *discordgo.Guild)
AttachToGuild adds a guild to sweetiebot's state tracking
func (*SweetieBot) ChannelCreate ¶
func (sb *SweetieBot) ChannelCreate(s *discordgo.Session, c *discordgo.ChannelCreate)
ChannelCreate discord hook
func (*SweetieBot) ChannelIsPrivate ¶
func (sb *SweetieBot) ChannelIsPrivate(channelID DiscordChannel) (*discordgo.Channel, bool)
ChannelIsPrivate returns true if channel should be considered private, false otherwise.
func (*SweetieBot) Connect ¶
func (sb *SweetieBot) Connect() int
Connect opens a websocket connection to discord. Only returns after disconnecting.
func (*SweetieBot) FindServers ¶
func (sb *SweetieBot) FindServers(name string, guilds []uint64) []*GuildInfo
FindServers matches server names against a string
func (*SweetieBot) GetDefaultServer ¶
func (sb *SweetieBot) GetDefaultServer(user uint64) *GuildInfo
GetDefaultServer attempts to find the default server for a user
func (*SweetieBot) GetLastMessage ¶
func (sb *SweetieBot) GetLastMessage(id DiscordChannel) (int64, bool)
func (*SweetieBot) GuildBanAdd ¶
func (sb *SweetieBot) GuildBanAdd(s *discordgo.Session, m *discordgo.GuildBanAdd)
GuildBanAdd discord hook
func (*SweetieBot) GuildBanRemove ¶
func (sb *SweetieBot) GuildBanRemove(s *discordgo.Session, m *discordgo.GuildBanRemove)
GuildBanRemove discord hook
func (*SweetieBot) GuildCreate ¶
func (sb *SweetieBot) GuildCreate(s *discordgo.Session, m *discordgo.GuildCreate)
GuildCreate discord hook
func (*SweetieBot) GuildDelete ¶
func (sb *SweetieBot) GuildDelete(s *discordgo.Session, m *discordgo.GuildDelete)
GuildDelete discord hook
func (*SweetieBot) GuildMemberAdd ¶
func (sb *SweetieBot) GuildMemberAdd(s *discordgo.Session, m *discordgo.GuildMemberAdd)
GuildMemberAdd discord hook
func (*SweetieBot) GuildMemberRemove ¶
func (sb *SweetieBot) GuildMemberRemove(s *discordgo.Session, m *discordgo.GuildMemberRemove)
GuildMemberRemove discord hook
func (*SweetieBot) GuildMemberUpdate ¶
func (sb *SweetieBot) GuildMemberUpdate(s *discordgo.Session, m *discordgo.GuildMemberUpdate)
GuildMemberUpdate discord hook
func (*SweetieBot) GuildMembersChunk ¶
func (sb *SweetieBot) GuildMembersChunk(s *discordgo.Session, chunk *discordgo.GuildMembersChunk)
func (*SweetieBot) GuildRoleDelete ¶
func (sb *SweetieBot) GuildRoleDelete(s *discordgo.Session, m *discordgo.GuildRoleDelete)
GuildRoleDelete discord hook
func (*SweetieBot) GuildUpdate ¶
func (sb *SweetieBot) GuildUpdate(s *discordgo.Session, m *discordgo.GuildUpdate)
GuildUpdate discord hook
func (*SweetieBot) IsMainGuild ¶
func (sb *SweetieBot) IsMainGuild(info *GuildInfo) bool
IsMainGuild returns true if that guild is considered the main (default) guild
func (*SweetieBot) MessageCreate ¶
func (sb *SweetieBot) MessageCreate(s *discordgo.Session, m *discordgo.MessageCreate)
MessageCreate discord hook
func (*SweetieBot) MessageDelete ¶
func (sb *SweetieBot) MessageDelete(s *discordgo.Session, m *discordgo.MessageDelete)
MessageDelete discord hook
func (*SweetieBot) MessageUpdate ¶
func (sb *SweetieBot) MessageUpdate(s *discordgo.Session, m *discordgo.MessageUpdate)
MessageUpdate discord hook
func (*SweetieBot) OnReady ¶
func (sb *SweetieBot) OnReady(s *discordgo.Session, r *discordgo.Ready)
OnReady discord hook
func (*SweetieBot) ProcessCommand ¶
func (sb *SweetieBot) ProcessCommand(m *discordgo.Message, info *GuildInfo, t int64, isdebug bool, private bool)
ProcessCommand processes a command given to sweetiebot in the form "!command"
func (*SweetieBot) ProcessUser ¶
func (sb *SweetieBot) ProcessUser(u *discordgo.User) uint64
ProcessUser adds a user to the database
func (*SweetieBot) ServeWeb ¶
func (sb *SweetieBot) ServeWeb() error
ServeWeb starts a webserver on :80 and optionally on :443. If you're doing a reverse-proxy via nginx, SSL terminates at nginx, so use insecure mode.
func (*SweetieBot) UserUpdate ¶
func (sb *SweetieBot) UserUpdate(s *discordgo.Session, u *discordgo.UserUpdate)
UserUpdate discord hook
type TimeLocation ¶
type TimeLocation string
type Transcript ¶
Transcript describes a single line from the transcript
type UpdateStatus ¶
UpdateStatus stores the version and additional files to download