Skip to content

Commit

Permalink
Fix #72
Browse files Browse the repository at this point in the history
  • Loading branch information
Erik McClure committed Mar 8, 2018
1 parent f65e85e commit 52218a3
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 14 deletions.
6 changes: 3 additions & 3 deletions rolesmodule/RolesModule.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ func (c *leaveRoleCommand) Process(args []string, msg *discordgo.Message, indice
return bot.ReturnError(err)
}
hasrole := info.UserHasRole(bot.DiscordUser(msg.Author.ID), bot.DiscordRole(r.ID))
err = info.Bot.DG.GuildMemberRoleRemove(info.ID, msg.Author.ID, r.ID) // Try removing it no matter what in case discord screwed up
err = info.ResolveRoleAddError(info.Bot.DG.GuildMemberRoleRemove(info.ID, msg.Author.ID, r.ID)) // Try removing it no matter what in case discord screwed up
if !hasrole {
return "```\nYou don't have that role.```", false, nil
}
Expand Down Expand Up @@ -346,7 +346,7 @@ func (c *removeRoleCommand) Process(args []string, msg *discordgo.Message, indic

r, err := GetRoleByNameOrPing(msg.Content[indices[0]:], info)
if err != nil {
return bot.ReturnError(err)
return bot.ReturnError(info.ResolveRoleAddError(err))
}
delete(info.Config.Users.Roles, bot.DiscordRole(r.ID))
info.SaveConfig()
Expand Down Expand Up @@ -381,7 +381,7 @@ func (c *deleteRoleCommand) Process(args []string, msg *discordgo.Message, indic
}
r, err := GetRoleByNameOrPing(msg.Content[indices[0]:], info)
if err != nil {
return bot.ReturnError(err)
return bot.ReturnError(info.ResolveRoleAddError(err))
}
err = info.Bot.DG.GuildRoleDelete(info.ID, r.ID)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions schedulermodule/SchedulerModule.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func (w *SchedulerModule) OnTick(info *bot.GuildInfo, t time.Time) {
dat := strings.SplitN(v.Data, "|", 2)
info.SendMessage(channel, dat[0]+" "+dat[1])
case typeEventSilence:
err := info.Bot.DG.RemoveRole(info.ID, bot.DiscordUser(v.Data), info.Config.Basic.SilenceRole)
err := info.ResolveRoleAddError(info.Bot.DG.RemoveRole(info.ID, bot.DiscordUser(v.Data), info.Config.Basic.SilenceRole))
if err != nil {
info.SendMessage(info.Config.Basic.ModChannel, "Error unsilencing <@"+v.Data+">: "+err.Error())
} else {
Expand All @@ -149,7 +149,7 @@ func (w *SchedulerModule) OnTick(info *bot.GuildInfo, t time.Time) {
info.SendMessage(info.Config.Basic.ModChannel, "Invalid data in role removal event: "+v.Data)
} else {
role := bot.DiscordRole(dat[1])
err := info.Bot.DG.RemoveRole(info.ID, bot.DiscordUser(dat[0]), role)
err := info.ResolveRoleAddError(info.Bot.DG.RemoveRole(info.ID, bot.DiscordUser(dat[0]), role))
if err != nil {
info.SendMessage(info.Config.Basic.ModChannel, "Error removing "+role.Show(info)+" from <@"+dat[0]+">: "+err.Error())
} else {
Expand Down
46 changes: 46 additions & 0 deletions sql_592141.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
DELIMITER //

ALTER DEFINER=`root`@`localhost` EVENT `CleanChatlog`
ON SCHEDULE
EVERY 1 DAY STARTS '2016-01-29 17:04:34'
ON COMPLETION NOT PRESERVE
ENABLE
COMMENT ''
DO BEGIN
DELETE FROM editlog WHERE Timestamp < DATE_SUB(UTC_TIMESTAMP(), INTERVAL 7 DAY);
DELETE FROM chatlog WHERE Timestamp < DATE_SUB(UTC_TIMESTAMP(), INTERVAL 7 DAY);
END//

DROP TRIGGER IF EXISTS `users_before_delete`//
CREATE DEFINER=`root`@`localhost` TRIGGER `users_before_delete` BEFORE DELETE ON `users` FOR EACH ROW BEGIN

-- Note: You cannot delete a user unless they have no entries in the members table
DELETE FROM aliases WHERE `User` = OLD.ID;
DELETE FROM editlog WHERE `Author` = OLD.ID;
DELETE FROM chatlog WHERE `Author` = OLD.ID;
DELETE FROM debuglog WHERE `User` = OLD.ID;
DELETE FROM votes WHERE `User` = OLD.ID;

END//

DROP PROCEDURE IF EXISTS `RemoveGuild`//
CREATE DEFINER=`root`@`localhost` PROCEDURE `RemoveGuild`(
IN `_guild` BIGINT UNSIGNED

)
LANGUAGE SQL
NOT DETERMINISTIC
MODIFIES SQL DATA
SQL SECURITY DEFINER
COMMENT ''
BEGIN

DELETE FROM `members` WHERE Guild = _guild;
DELETE FROM `polls` WHERE Guild = _guild;
DELETE FROM `schedule` WHERE Guild = _guild;
DELETE FROM `editlog` WHERE Guild = _guild;
DELETE FROM `chatlog` WHERE Guild = _guild;
DELETE FROM `debuglog` WHERE Guild = _guild;
DELETE FROM `tags` WHERE Guild = _guild;

END//
7 changes: 4 additions & 3 deletions sweetiebot/BotConfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ type CommandID string

// BotConfig lists all bot configuration options, grouped into structs
type BotConfig struct {
Version int `json:"version"`
LastVersion int `json:"lastversion"`
SetupDone bool `json:"setupdone"`
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"`
Expand Down
80 changes: 80 additions & 0 deletions sweetiebot/DebugModule.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package sweetiebot

import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sort"
"strings"
"sync/atomic"
Expand All @@ -13,6 +17,7 @@ import (
// DebugModule contains various debugging commands
type DebugModule struct {
lastcheck int64
lastclean int64
}

// Name of the module
Expand Down Expand Up @@ -53,6 +58,81 @@ func (w *DebugModule) OnTick(info *GuildInfo, t time.Time) {
updater := &updateCommand{}
updater.Process([]string{}, m, []int{}, info)
}

go func() { // Getting the user list takes forever because of discord API limits, so we do this on a new thread
if info.Bot.IsMainGuild(info) && t.Unix()-w.lastclean > CleanInterval {
fmt.Println("CLEANING GUILDS")
w.lastclean = t.Unix()

lastid := ""
guilds := make(map[string]*discordgo.UserGuild)
list, err := info.Bot.DG.UserGuilds(100, "", lastid)
for err == nil && len(list) > 0 {
for _, v := range list {
guilds[v.ID] = v
}
lastid = list[len(list)-1].ID
list, err = info.Bot.DG.UserGuilds(100, "", lastid)
}
info.LogError("Error cleaning guilds: ", err)

if err == nil { // ONLY proceed if we have a complete listing of all our guilds with no errors
cur, _ := GetCurrentDir()
timeNow := time.Now().UTC().Unix()
results, err := ioutil.ReadDir(cur)
info.LogError("Error cleaning guilds: ", err)

for _, f := range results {
if !f.IsDir() {
matches := guildfileregex.FindStringSubmatch(f.Name())
if len(matches) > 1 {
id := matches[1]
_, ok := guilds[id]
config := BotConfig{}
cfgfile, err := ioutil.ReadFile(filepath.Join(cur, f.Name()))
if err == nil {
err = json.Unmarshal(cfgfile, &config)
}
if err != nil {
info.LogError("Error loading config: ", err)
continue
}

if ok || config.Expires == 0 {
config.Expires = timeNow + ExpireTime
info.Bot.GuildsLock.RLock()
guild, ok := info.Bot.Guilds[DiscordGuild(id)]
info.Bot.GuildsLock.RUnlock()

if ok {
guild.ConfigLock.Lock()
guild.Config.Expires = config.Expires
guild.ConfigLock.Unlock()
}

if data, err := json.Marshal(&config); err == nil {
if err = ioutil.WriteFile(id+".json", data, 0664); err != nil {
info.Log("Error saving config file: ", err.Error())
}
} else {
info.Log("Error marshalling config file: ", err.Error())
}
} else if config.Expires < timeNow {
fmt.Println("Server ID " + id + " has expired.")
info.Bot.GuildsLock.Lock()
delete(info.Bot.Guilds, DiscordGuild(id))
info.Bot.GuildsLock.Unlock()
if err := os.Remove(id + ".json"); err == nil {
err = info.Bot.DB.RemoveGuild(SBatoi(id))
}
info.LogError("Error deleting guild: ", err)
}
}
}
}
}
}
}()
}

type echoCommand struct {
Expand Down
9 changes: 9 additions & 0 deletions sweetiebot/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ type BotDB struct {
sqlGetItemTags *sql.Stmt
sqlGetTags *sql.Stmt
sqlImportTag *sql.Stmt
sqlRemoveGuild *sql.Stmt
}

func dbLoad(log logger, driver string, conn string) (*BotDB, error) {
Expand Down Expand Up @@ -287,6 +288,7 @@ func (db *BotDB) LoadStatements() error {
db.sqlGetItemTags, err = db.Prepare("SELECT T.Name FROM itemtags M INNER JOIN tags T ON M.Tag = T.ID WHERE M.Item = ? AND T.Guild = ?")
db.sqlGetTags, err = db.Prepare("SELECT T.Name, COUNT(M.Item) FROM tags T LEFT OUTER JOIN itemtags M ON T.ID = M.Tag WHERE T.Guild = ? GROUP BY T.Name")
db.sqlImportTag, err = db.Prepare("INSERT IGNORE INTO itemtags (Item, Tag) SELECT Item, ? FROM itemtags WHERE Tag = ?")
db.sqlRemoveGuild, err = db.Prepare("CALL RemoveGuild(?)")
return err
}

Expand Down Expand Up @@ -1263,3 +1265,10 @@ func (db *BotDB) ImportTag(srcTag uint64, destTag uint64) error {
db.CheckError("ImportTag", err)
return err
}

// RemoveGuild removes the given guild from the database, if it exists
func (db *BotDB) RemoveGuild(guild uint64) error {
_, err := db.sqlRemoveGuild.Exec(guild)
err = db.standardErr(err)
return db.CheckError("RemoveGuild", err)
}
4 changes: 2 additions & 2 deletions sweetiebot/selfhost.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"github.com/blackhole12/discordgo"
)

var fileregex = regexp.MustCompile("^sql_([0-9]+)[.]sql$")
var sqlfileregex = regexp.MustCompile("^sql_([0-9]+)[.]sql$")
var ErrMD5Error = errors.New("MD5 mismatch, file corrupt")

type SelfhostBase struct {
Expand Down Expand Up @@ -175,7 +175,7 @@ func FindUpgradeFiles(scriptdir string, version int) (files []int) {
results, _ := ioutil.ReadDir(scriptdir)
for _, f := range results {
if !f.IsDir() {
matches := fileregex.FindStringSubmatch(f.Name())
matches := sqlfileregex.FindStringSubmatch(f.Name())
if len(matches) > 1 {
v, err := strconv.Atoi(matches[1])
if err == nil && v > version {
Expand Down
6 changes: 5 additions & 1 deletion sweetiebot/sweetiebot.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@ var discriminantregex = regexp.MustCompile(".*#[0-9][0-9][0-9]+")
var colorregex = regexp.MustCompile("0x[0-9A-Fa-f]+")
var locUTC = time.FixedZone("UTC", 0)
var urlregex = regexp.MustCompile("https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-z]{1,6}([-a-zA-Z0-9@:%_\\+.~#?&//=]*)")
var guildfileregex = regexp.MustCompile("^([0-9]+)[.]json$")

// DiscordEpoch is used to figure out snowflake creation times
var DiscordEpoch uint64 = 1420070400000

// BotVersion stores the current version of sweetiebot
var BotVersion = Version{0, 9, 9, 12}
var BotVersion = Version{0, 9, 9, 13}

const (
MaxPublicLines = 12
Expand All @@ -50,6 +51,8 @@ const (
UpdateGrace = 120
MaxUpdateGrace = 600
UpdateInterval = 300
CleanInterval = 3600
ExpireTime = 3600 * 72
MaxScheduleRows = 5000
)

Expand Down Expand Up @@ -1001,6 +1004,7 @@ func New(token string, loader func(*GuildInfo) []Module) *SweetieBot {
WebDomain: "localhost",
WebPort: ":80",
changelog: map[int]string{
AssembleVersion(0, 9, 9, 13): "- Made some error messages more clear\n- Fixed database cleanup functions\n- Sweetiebot now deletes all information about guilds she hasn't been on for 3 days.",
AssembleVersion(0, 9, 9, 12): "- Fix crash on !setfilter",
AssembleVersion(0, 9, 9, 11): "- Merged !showroll command\n- Prevented setting your default server to one that isn't set up.",
AssembleVersion(0, 9, 9, 10): "- Sweetiebot no longer inserts !quote and !drop into the bored commands after restarting, unless the bored commands are empty; if you need to disable bored, disable the module instead.\n- Exorcised demons from three servers with corrupted channel information.\n- Filters now applied to invalid commands.",
Expand Down
6 changes: 3 additions & 3 deletions usersmodule/UsersModule.go
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ func (c *silenceCommand) Process(args []string, msg *discordgo.Message, indices

code, err := assignRoleMember(info, user, info.Config.Basic.SilenceRole)
if code < 0 || err != nil {
return fmt.Sprintf("```\nError occurred trying to silence %s: %s```", info.GetUserName(user), err.Error()), false, nil
return fmt.Sprintf("```\nError occurred trying to silence %s: %s```", info.GetUserName(user), info.ResolveRoleAddError(err).Error()), false, nil
} else if code == 1 {
var t *time.Time
if info.Bot.DB.Status.Get() {
Expand Down Expand Up @@ -669,7 +669,7 @@ func (c *unsilenceCommand) Process(args []string, msg *discordgo.Message, indice
}
user, err := bot.ParseUser(msg.Content[indices[0]:], info)
if err != nil {
return bot.ReturnError(err)
return bot.ReturnError(info.ResolveRoleAddError(err))
}

err = info.Bot.DG.RemoveRole(info.ID, user, info.Config.Basic.SilenceRole)
Expand Down Expand Up @@ -729,7 +729,7 @@ func (c *assignRoleCommand) Process(args []string, msg *discordgo.Message, indic

code, err := assignRoleMember(info, user, role)
if code < 0 || err != nil {
return fmt.Sprintf("```\nError occurred trying to assign %s to %s: %s```", role.Show(info), info.GetUserName(user), err.Error()), false, nil
return fmt.Sprintf("```\nError occurred trying to assign %s to %s: %s```", role.Show(info), info.GetUserName(user), info.ResolveRoleAddError(err).Error()), false, nil
} else if code == 1 {
var t *time.Time
if info.Bot.DB.Status.Get() {
Expand Down

0 comments on commit 52218a3

Please sign in to comment.