diff --git a/commands/config.go b/commands/config.go index b6e6854..b29cfdd 100644 --- a/commands/config.go +++ b/commands/config.go @@ -2,17 +2,37 @@ package commands import ( "fmt" + "github.com/anhgelus/gokord" "github.com/anhgelus/gokord/cmd" "github.com/anhgelus/gokord/component" "github.com/anhgelus/gokord/logger" "github.com/anhgelus/les-copaings-bot/config" "github.com/anhgelus/les-copaings-bot/exp" "github.com/bwmarrin/discordgo" + "strconv" "strings" + "time" ) const ( - ConfigModify = "config_modify" + ConfigModify = "config_modify" + ConfigModifyXpRole = "xp_role" + ConfigModifyDisChannel = "disabled_channel" + ConfigModifyFallbackChannel = "fallback_channel" + ConfigModifyTimeReduce = "time_reduce" + // xp role related + XpRoleAdd = "xp_role_add" + XpRoleAddLevel = "xp_role_add_level" + XpRoleAddRole = "xp_role_add_role" + XpRoleDel = "xp_role_del" + XpRoleDelRole = "xp_role_del_role" + XpRoleEdit = "xp_role_edit" + XpRoleEditLevel = "xp_role_edit_level" + XpRoleEditRole = "xp_role_edit_role" +) + +var ( + configModifyMap = map[string]uint{} ) func Config(_ *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { @@ -48,41 +68,388 @@ func Config(_ *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMa } else { defaultChan = fmt.Sprintf("<#%s>", cfg.FallbackChannel) } - comp := component.New(). - Add(component.NewTextDisplay("# Config")). - Add(component.NewTextDisplay("**Salon par défaut**\n" + defaultChan)). - Add(component.NewSeparator()). - Add(component.NewTextDisplay("**Rôles liés aux niveaux**\n" + roles)). - Add(component.NewSeparator()). - Add(component.NewTextDisplay("**Salons désactivés**\n" + chans)). - Add(component.NewSeparator()). - Add(component.NewTextDisplay(fmt.Sprintf("**%s**\n%d", "Jours avant la réduction", cfg.DaysXPRemains))). - Add(component.NewActionRow().Add(component.NewStringSelect(ConfigModify). - SetPlaceholder("Modifier..."). + err := resp.AddEmbed(&discordgo.MessageEmbed{ + Type: discordgo.EmbedTypeRich, + Title: "Config", + Color: 0x10E6AD, + Fields: []*discordgo.MessageEmbedField{ + { + Name: "Salon par défaut", + Value: defaultChan, + Inline: false, + }, + { + Name: "Rôles liés aux niveaux", + Value: roles, + Inline: false, + }, + { + Name: "Salons désactivés", + Value: chans, + Inline: false, + }, + { + Name: "Jours avant la réduction", + Value: fmt.Sprintf("%d", cfg.DaysXPRemains), + Inline: false, + }, + }, + }).SetComponents(component.New().Add(component.NewActionRow().Add( + component.NewStringSelect(ConfigModify).SetPlaceholder("Modifier..."). AddOption( - component.NewSelectOption("Rôles liés à l'XP", config.ModifyXpRole). + component.NewSelectOption("Rôles liés à l'XP", ConfigModifyXpRole). SetDescription("Gère les rôles liés à l'XP"). SetEmoji(&discordgo.ComponentEmoji{Name: "🏅"}), ). AddOption( - component.NewSelectOption("Salons désactivés", config.ModifyDisChannel). + component.NewSelectOption("Salons désactivés", ConfigModifyDisChannel). SetDescription("Gère les salons désactivés"). SetEmoji(&discordgo.ComponentEmoji{Name: "❌"}), ). AddOption( // I don't have a better idea for this... - component.NewSelectOption("Salons par défaut", config.ModifyFallbackChannel). - SetDescription("Spécifie le salon par défaut"). + component.NewSelectOption("Salons de repli", ConfigModifyFallbackChannel). + SetDescription("Spécifie le salon de repli"). SetEmoji(&discordgo.ComponentEmoji{Name: "💾"}), ). AddOption( - component.NewSelectOption("Temps avec la réduction", config.ModifyTimeReduce). + component.NewSelectOption("Temps avec la réduction", ConfigModifyTimeReduce). SetDescription("Gère le temps avant la réduction d'XP"). SetEmoji(&discordgo.ComponentEmoji{Name: "⌛"}), ), - )) - err := resp.SetComponents(comp).IsEphemeral().Send() + ))).IsEphemeral().Send() if err != nil { logger.Alert("config/guild.go - Sending config", err.Error()) } } + +func ConfigModifyXPRole(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { + err := resp.IsEphemeral(). + SetMessage("Action à réaliser"). + SetComponents(component.New().Add(component.NewActionRow().Add( + component.NewStringSelect(ConfigModify).SetPlaceholder("Action"). + AddOption( + component.NewSelectOption("Ajouter", XpRoleAdd). + SetDescription("Ajouter un rôle à XP"). + SetEmoji(&discordgo.ComponentEmoji{Name: "⬆️"}), + ). + AddOption( + component.NewSelectOption("Modifier", XpRoleEdit). + SetDescription("Modifier un rôle à XP"). + SetEmoji(&discordgo.ComponentEmoji{Name: "📝"}), + ). + AddOption( + component.NewSelectOption("Supprimer", XpRoleDel). + SetDescription("Supprimer un rôle à XP"). + SetEmoji(&discordgo.ComponentEmoji{Name: "❌"}), + ), + ))).Send() + if err != nil { + logger.Alert("config/guild.go - Sending config", err.Error()) + } +} + +func ConfigXPRoleAddEdit(_ *discordgo.Session, _ *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { + cID := XpRoleAddLevel + if data.CustomID == XpRoleEdit { + cID = XpRoleEditLevel + } + err := resp.IsModal(). + SetTitle("Role"). + SetComponents(component.New().ForModal().Add(component.NewActionRow().Add( + component.NewTextInput(cID, "Niveau", discordgo.TextInputShort). + SetPlaceholder("5"). + IsRequired(). + SetMinLength(0). + SetMaxLength(5), + ))). + Send() + if err != nil { + logger.Alert("config/guild.go - Sending modal to add/edit", err.Error()) + } +} + +func ConfigXPRoleAddRole(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { + cfg := config.GetGuildConfig(i.GuildID) + roleId := data.Values[0] + for _, r := range cfg.XpRoles { + if r.RoleID == roleId { + err := resp.SetMessage("Le rôle est déjà présent dans la config").Send() + if err != nil { + logger.Alert("commands/config.go - Role already in config", err.Error()) + } + return + } + } + cfg.XpRoles = append(cfg.XpRoles, config.XpRole{ + XP: configModifyMap[getKeyConfigRole(i)], + RoleID: roleId, + }) + err := cfg.Save() + if err != nil { + logger.Alert( + "commands/config.go - Saving config", + err.Error(), + "guild_id", i.GuildID, + "role_id", roleId, + "type", "add", + ) + } + if err = resp.IsEphemeral().SetMessage("Rôle ajouté.").Send(); err != nil { + logger.Alert("commands/config.go - Sending success", err.Error()) + } +} + +func ConfigXPRoleEditRole(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { + cfg := config.GetGuildConfig(i.GuildID) + roleId := data.Values[0] + _, r := cfg.FindXpRole(roleId) + if r == nil { + err := resp.SetMessage("Le rôle n'a pas été trouvé dans la config.").Send() + if err != nil { + logger.Alert("commands/config.go - Role not found (edit)", err.Error()) + } + return + } + r.XP = configModifyMap[getKeyConfigRole(i)] + err := gokord.DB.Save(r).Error + if err != nil { + logger.Alert( + "commands/config.go - Saving config", + err.Error(), + "guild_id", i.GuildID, + "role_id", roleId, + "type", "edit", + ) + } + if err = resp.IsEphemeral().SetMessage("Rôle modifié.").Send(); err != nil { + logger.Alert("commands/config.go - Sending success", err.Error()) + } +} + +func ConfigXPRoleDel(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { + err := resp.IsEphemeral(). + SetMessage("Rôle à supprimer"). + SetComponents(component.New().Add(component.NewActionRow().Add(component.NewRoleSelect(XpRoleDelRole)))). + Send() + if err != nil { + logger.Alert("config/guild.go - Sending response to del", err.Error()) + } +} + +func ConfigXPRoleDelRole(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { + cfg := config.GetGuildConfig(i.GuildID) + roleId := data.Values[0] + _, r := cfg.FindXpRole(roleId) + if r == nil { + err := resp.SetMessage("Le rôle n'a pas été trouvé dans la config.").Send() + if err != nil { + logger.Alert("commands/config.go - Sending role not found (del)", err.Error()) + } + return + } + err := gokord.DB.Delete(r).Error + if err != nil { + logger.Alert( + "commands/config.go - Deleting entry", + err.Error(), + "guild_id", i.GuildID, + "role_id", roleId, + "type", "del", + ) + } + if err = resp.IsEphemeral().SetMessage("Rôle supprimé.").Send(); err != nil { + logger.Alert("commands/config.go - Sending success", err.Error()) + } +} + +func ConfigXPRoleLevel(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.ModalSubmitInteractionData, resp *cmd.ResponseBuilder) { + input := data.Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput) + + k := getKeyConfigRole(i) + in, err := strconv.Atoi(input.Value) + if err != nil || in < 0 { + if err = resp.IsEphemeral(). + SetMessage("Impossible de lire le nombre. Il doit s'agit d'un nombre entier positif."). + Send(); err != nil { + logger.Alert("command/config.go - Sending bad number", err.Error()) + } + return + } + configModifyMap[k] = uint(in) + go func(i *discordgo.InteractionCreate, k string) { + time.Sleep(5 * time.Minute) + delete(configModifyMap, k) + }(i, k) + + cID := XpRoleAddRole + resp.SetMessage("Rôle à ajouter") + if data.CustomID == XpRoleEditLevel { + cID = XpRoleEditLevel + resp.SetMessage("Rôle à modifier") + } + + err = resp.IsEphemeral(). + SetMessage("Rôle à supprimer"). + SetComponents(component.New().Add(component.NewActionRow().Add(component.NewRoleSelect(cID)))). + Send() + if err != nil { + logger.Alert("config/guild.go - Sending response to add/edit", err.Error()) + } +} + +func getKeyConfigRole(i *discordgo.InteractionCreate) string { + return fmt.Sprintf("r:%s:%s", i.GuildID, i.User.ID) +} + +func ConfigChannel(s *discordgo.Session, i *discordgo.InteractionCreate, optMap cmd.OptionMap, resp *cmd.ResponseBuilder) { + resp.IsEphemeral() + // verify every args + t, ok := optMap["type"] + if !ok { + err := resp.SetMessage("Le type d'action n'a pas été renseigné.").Send() + if err != nil { + logger.Alert("commands/config.go - Action type not set", err.Error()) + } + return + } + ts := t.StringValue() + salon, ok := optMap["channel"] + if !ok { + err := resp.SetMessage("Le salon n'a pas été renseigné.").Send() + if err != nil { + logger.Alert("commands/config.go - Channel not set (disabled)", err.Error()) + } + return + } + channel := salon.ChannelValue(s) + cfg := config.GetGuildConfig(i.GuildID) + switch ts { + case "add": + if strings.Contains(cfg.DisabledChannels, channel.ID) { + err := resp.SetMessage("Le salon est déjà dans la liste des salons désactivés").Send() + if err != nil { + logger.Alert("commands/config.go - Channel already disabled", err.Error()) + } + return + } + cfg.DisabledChannels += channel.ID + ";" + case "del": + if !strings.Contains(cfg.DisabledChannels, channel.ID) { + err := resp.SetMessage("Le salon n'est pas désactivé").Send() + if err != nil { + logger.Alert("commands/config.go - Channel not disabled", err.Error()) + } + return + } + cfg.DisabledChannels = strings.ReplaceAll(cfg.DisabledChannels, channel.ID+";", "") + default: + err := resp.SetMessage("Le type d'action n'est pas valide.").Send() + if err != nil { + logger.Alert("commands/config.go - Invalid action type", err.Error()) + } + return + } + // save + err := cfg.Save() + if err != nil { + logger.Alert( + "commands/config.go - Saving config", + err.Error(), + "guild_id", + i.GuildID, + "type", + ts, + "channel_id", + channel.ID, + ) + err = resp.SetMessage("Il y a eu une erreur lors de la modification de de la base de données.").Send() + } else { + err = resp.SetMessage("Modification sauvegardé.").Send() + } + if err != nil { + logger.Alert("commands/config.go - Modification saved message", err.Error()) + } +} + +func ConfigFallbackChannel(s *discordgo.Session, i *discordgo.InteractionCreate, optMap cmd.OptionMap, resp *cmd.ResponseBuilder) { + resp.IsEphemeral() + // verify every args + salon, ok := optMap["channel"] + if !ok { + err := resp.SetMessage("Le salon n'a pas été renseigné.").Send() + if err != nil { + logger.Alert("commands/config.go - Channel not set (fallback)", err.Error()) + } + return + } + channel := salon.ChannelValue(s) + if channel.Type != discordgo.ChannelTypeGuildText { + err := resp.SetMessage("Le salon n'est pas un salon textuel.").Send() + if err != nil { + logger.Alert("commands/config.go - Invalid channel type", err.Error()) + } + return + } + cfg := config.GetGuildConfig(i.GuildID) + cfg.FallbackChannel = channel.ID + // save + err := cfg.Save() + if err != nil { + logger.Alert( + "commands/config.go - Saving config", + err.Error(), + "guild_id", + i.GuildID, + "channel_id", + channel.ID, + ) + err = resp.SetMessage("Il y a eu une erreur lors de la modification de de la base de données.").Send() + } else { + err = resp.SetMessage("Salon enregistré.").Send() + } + if err != nil { + logger.Alert("commands/config.go - Channel saved message", err.Error()) + } +} + +func ConfigPeriodBeforeReduce(s *discordgo.Session, i *discordgo.InteractionCreate, optMap cmd.OptionMap, resp *cmd.ResponseBuilder) { + resp.IsEphemeral() + // verify every args + days, ok := optMap["days"] + if !ok { + err := resp.SetMessage("Le nombre de jours n'a pas été renseigné.").Send() + if err != nil { + logger.Alert("commands/config.go - Days not set (fallback)", err.Error()) + } + return + } + d := days.IntValue() + if d < 30 { + err := resp.SetMessage("Le nombre de jours est inférieur à 30.").Send() + if err != nil { + logger.Alert("commands/config.go - Days < 30 (fallback)", err.Error()) + } + return + } + // save + cfg := config.GetGuildConfig(i.GuildID) + cfg.DaysXPRemains = uint(d) + err := cfg.Save() + if err != nil { + logger.Alert( + "commands/config.go - Saving config", + err.Error(), + "guild_id", + i.GuildID, + "days", + d, + ) + err = resp.SetMessage("Il y a eu une erreur lors de la modification de de la base de données.").Send() + } else { + err = resp.SetMessage("Nombre de jours enregistré.").Send() + } + if err != nil { + logger.Alert("commands/config.go - Days saved message", err.Error()) + } +} diff --git a/config/channel.go b/config/channel.go deleted file mode 100644 index 355b0e1..0000000 --- a/config/channel.go +++ /dev/null @@ -1,126 +0,0 @@ -package config - -import ( - "github.com/anhgelus/gokord/cmd" - "github.com/anhgelus/gokord/component" - "github.com/anhgelus/gokord/logger" - "github.com/bwmarrin/discordgo" - "strings" -) - -const ( - ModifyFallbackChannel = "fallback_channel" - FallbackChannelSet = "fallback_channel_set" - - ModifyDisChannel = "disabled_channel" - DisChannelAdd = "disabled_channel_add" - DisChannelAddSet = "disabled_channel_add_set" - DisChannelDel = "disabled_channel_del" - DisChannelDelSet = "disabled_channel_del_set" -) - -func HandleModifyFallbackChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - err := resp.IsEphemeral().SetComponents(component.New().Add(component.NewActionRow().Add( - component.NewChannelSelect(FallbackChannelSet).AddChannelType(discordgo.ChannelTypeGuildText), - ))).Send() - if err != nil { - logger.Alert("config/channel.go - Sending channel list for fallback", err.Error()) - } -} - -func HandleFallbackChannelSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - resp.IsEphemeral() - - cfg := GetGuildConfig(i.GuildID) - channelID := data.Values[0] - - cfg.FallbackChannel = channelID - err := cfg.Save() - if err != nil { - logger.Alert("config/channel.go - Saving fallback channel", err.Error()) - if err = resp.SetMessage("Erreur lors de la sauvegarde du salon").Send(); err != nil { - logger.Alert("config/channel.go - Sending error while saving channel", err.Error()) - } - return - } - if err = resp.SetMessage("Salon sauvegardé.").Send(); err != nil { - logger.Alert("config/channel.go - Sending channel saved", err.Error()) - } -} - -func HandleModifyDisChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - err := resp.IsEphemeral().SetComponents(component.New().Add(component.NewActionRow(). - Add( - component.NewButton(DisChannelAdd, discordgo.PrimaryButton). - SetLabel("Désactiver un salon"). - SetEmoji(&discordgo.ComponentEmoji{Name: "⬇️"}), - ). - Add( - component.NewButton(DisChannelDel, discordgo.DangerButton). - SetLabel("Réactiver un salon"). - SetEmoji(&discordgo.ComponentEmoji{Name: "⬆️"}), - ), - )).Send() - if err != nil { - logger.Alert("config/channel.go - Sending action type", err.Error()) - } -} - -func HandleDisChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - resp.IsEphemeral().SetMessage("Salon à désactiver...") - cID := DisChannelAddSet - if data.CustomID == DisChannelDel { - resp.SetMessage("Salon à réactiver...") - cID = DisChannelDelSet - } - err := resp.SetComponents(component.New().Add(component.NewActionRow().Add(component.NewChannelSelect(cID)))).Send() - if err != nil { - logger.Alert("config/channel.go - Sending channel list for disable", err.Error()) - } -} - -func HandleDisChannelAddSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - resp.IsEphemeral() - cfg := GetGuildConfig(i.GuildID) - id := data.Values[0] - if strings.Contains(cfg.DisabledChannels, id) { - err := resp.SetMessage("Le salon est déjà dans la liste des salons désactivés").Send() - if err != nil { - logger.Alert("commands/config.go - Channel already disabled", err.Error()) - } - return - } - cfg.DisabledChannels += id + ";" - if err := cfg.Save(); err != nil { - logger.Alert("commands/config.go - Saving config disable add", err.Error()) - if err = resp.SetMessage("Il y a eu une erreur lors de la modification de de la base de données.").Send(); err != nil { - logger.Alert("config/channel.go - Sending error while saving config", err.Error()) - } - } - if err := resp.SetMessage("Modification sauvegardé.").Send(); err != nil { - logger.Alert("commands/config.go - Modification saved message disable add", err.Error()) - } -} - -func HandleDisChannelDelSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - resp.IsEphemeral() - cfg := GetGuildConfig(i.GuildID) - id := data.Values[0] - if !strings.Contains(cfg.DisabledChannels, id) { - err := resp.SetMessage("Le salon n'est pas désactivé").Send() - if err != nil { - logger.Alert("commands/config.go - Channel not disabled", err.Error()) - } - return - } - cfg.DisabledChannels = strings.ReplaceAll(cfg.DisabledChannels, id+";", "") - if err := cfg.Save(); err != nil { - logger.Alert("commands/config.go - Saving config disable del", err.Error()) - if err = resp.SetMessage("Il y a eu une erreur lors de la modification de de la base de données.").Send(); err != nil { - logger.Alert("config/channel.go - Sending error while saving config", err.Error()) - } - } - if err := resp.SetMessage("Modification sauvegardé.").Send(); err != nil { - logger.Alert("commands/config.go - Modification saved message disable del", err.Error()) - } -} diff --git a/config/guild.go b/config/guild.go index 3071d95..0606ed0 100644 --- a/config/guild.go +++ b/config/guild.go @@ -15,6 +15,13 @@ type GuildConfig struct { DaysXPRemains uint `gorm:"default:90"` // 30 * 3 = 90 (three months) } +type XpRole struct { + ID uint `gorm:"primarykey"` + XP uint + RoleID string + GuildConfigID uint +} + func GetGuildConfig(guildID string) *GuildConfig { cfg := GuildConfig{GuildID: guildID} if err := cfg.Load(); err != nil { diff --git a/config/xp_reduce.go b/config/xp_reduce.go deleted file mode 100644 index 8e97c26..0000000 --- a/config/xp_reduce.go +++ /dev/null @@ -1,57 +0,0 @@ -package config - -import ( - "github.com/anhgelus/gokord/cmd" - "github.com/anhgelus/gokord/component" - "github.com/anhgelus/gokord/logger" - "github.com/bwmarrin/discordgo" - "strconv" -) - -const ( - ModifyTimeReduce = "time_reduce" - TimeReduceSet = "time_reduce_set" -) - -func HandleModifyPeriodicReduce(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - err := resp.IsModal().SetComponents(component.New().ForModal().Add(component.NewActionRow().Add( - component.NewTextInput(TimeReduceSet, "Jours avant la réduction", discordgo.TextInputShort). - SetMinLength(1). - SetMaxLength(3), - ))).Send() - if err != nil { - logger.Alert("config/xp_reduce.go - Sending modal for periodic reduce", err.Error()) - } -} - -func HandleTimeReduceSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.ModalSubmitInteractionData, resp *cmd.ResponseBuilder) { - resp.IsEphemeral() - v := data.Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value - days, err := strconv.Atoi(v) - if err != nil { - logger.Debug(err.Error()) - if err = resp.SetMessage("Nombres de jours invalides. Merci de mettre un entier.").Send(); err != nil { - logger.Alert("config/channel.go - Sending bad input", err.Error()) - } - return - } - if days < 30 { - err = resp.SetMessage("Le nombre de jours est inférieur à 30.").Send() - if err != nil { - logger.Alert("commands/config.go - Days < 30 (fallback)", err.Error()) - } - return - } - cfg := GetGuildConfig(i.GuildID) - cfg.DaysXPRemains = uint(days) - if err = cfg.Save(); err != nil { - logger.Alert("config/channel.go - Saving days xp remains", err.Error()) - if err = resp.SetMessage("Erreur lors de la sauvegarde du salon").Send(); err != nil { - logger.Alert("config/channel.go - Sending error while saving days xp remains", err.Error()) - } - return - } - if err = resp.SetMessage("Modification sauvegardée.").Send(); err != nil { - logger.Alert("config/channel.go - Sending days saved", err.Error()) - } -} diff --git a/config/xp_role.go b/config/xp_role.go deleted file mode 100644 index 27981c0..0000000 --- a/config/xp_role.go +++ /dev/null @@ -1,213 +0,0 @@ -package config - -import ( - "fmt" - "github.com/anhgelus/gokord" - "github.com/anhgelus/gokord/cmd" - "github.com/anhgelus/gokord/component" - "github.com/anhgelus/gokord/logger" - "github.com/bwmarrin/discordgo" - "strconv" - "time" -) - -type XpRole struct { - ID uint `gorm:"primarykey"` - XP uint - RoleID string - GuildConfigID uint -} - -const ( - ModifyXpRole = "xp_role" - XpRoleAdd = "xp_role_add" - XpRoleAddLevel = "xp_role_add_level" - XpRoleAddRole = "xp_role_add_role" - XpRoleDel = "xp_role_del" - XpRoleDelRole = "xp_role_del_role" - XpRoleEdit = "xp_role_edit" - XpRoleEditLevel = "xp_role_edit_level" - XpRoleEditRole = "xp_role_edit_role" -) - -var ( - configModifyMap = map[string]uint{} -) - -func HandleModifyXpRole(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - err := resp.IsEphemeral(). - SetMessage("Action à réaliser"). - SetComponents(component.New().Add(component.NewActionRow(). - Add(component.NewButton(XpRoleAdd, discordgo.PrimaryButton). - SetLabel("Ajouter"). - SetEmoji(&discordgo.ComponentEmoji{Name: "⬆️"}), - ). - Add(component.NewButton(XpRoleEdit, discordgo.SecondaryButton). - SetLabel("Modifier"). - SetEmoji(&discordgo.ComponentEmoji{Name: "📝"}), - ). - Add(component.NewButton(XpRoleDel, discordgo.DangerButton). - SetLabel("Supprimer"). - SetEmoji(&discordgo.ComponentEmoji{Name: "❌"}), - ), - )).Send() - if err != nil { - logger.Alert("config/guild.go - Sending config", err.Error()) - } -} - -func HandleXpRoleAddEdit(_ *discordgo.Session, _ *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - cID := XpRoleAddLevel - if data.CustomID == XpRoleEdit { - cID = XpRoleEditLevel - } - err := resp.IsModal(). - SetTitle("Role"). - SetComponents(component.New().ForModal().Add(component.NewActionRow().Add( - component.NewTextInput(cID, "Niveau", discordgo.TextInputShort). - SetPlaceholder("5"). - IsRequired(). - SetMinLength(0). - SetMaxLength(5), - ))). - Send() - if err != nil { - logger.Alert("config/guild.go - Sending modal to add/edit", err.Error()) - } -} - -func HandleXpRoleAddRole(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - resp.IsEphemeral() - cfg := GetGuildConfig(i.GuildID) - roleId := data.Values[0] - for _, r := range cfg.XpRoles { - if r.RoleID == roleId { - err := resp.SetMessage("Le rôle est déjà présent dans la config").Send() - if err != nil { - logger.Alert("config/xp_role.go - Role already in config", err.Error()) - } - return - } - } - cfg.XpRoles = append(cfg.XpRoles, XpRole{ - XP: configModifyMap[getKeyConfigRole(i)], - RoleID: roleId, - }) - err := cfg.Save() - if err != nil { - logger.Alert( - "config/xp_role.go - Saving config", - err.Error(), - "guild_id", i.GuildID, - "role_id", roleId, - "type", "add", - ) - } - if err = resp.SetMessage("Rôle ajouté.").Send(); err != nil { - logger.Alert("config/xp_role.go - Sending success", err.Error()) - } -} - -func HandleXpRoleEditRole(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - resp.IsEphemeral() - cfg := GetGuildConfig(i.GuildID) - roleId := data.Values[0] - _, r := cfg.FindXpRole(roleId) - if r == nil { - err := resp.SetMessage("Le rôle n'a pas été trouvé dans la config.").Send() - if err != nil { - logger.Alert("config/xp_role.go - Role not found (edit)", err.Error()) - } - return - } - r.XP = configModifyMap[getKeyConfigRole(i)] - err := gokord.DB.Save(r).Error - if err != nil { - logger.Alert( - "config/xp_role.go - Saving config", - err.Error(), - "guild_id", i.GuildID, - "role_id", roleId, - "type", "edit", - ) - } - if err = resp.SetMessage("Rôle modifié.").Send(); err != nil { - logger.Alert("config/xp_role.go - Sending success", err.Error()) - } -} - -func HandleXpRoleDel(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - err := resp.IsEphemeral(). - SetMessage("Rôle à supprimer"). - SetComponents(component.New().Add(component.NewActionRow().Add(component.NewRoleSelect(XpRoleDelRole)))). - Send() - if err != nil { - logger.Alert("config/guild.go - Sending response to del", err.Error()) - } -} - -func HandleXpRoleDelRole(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - resp.IsEphemeral() - cfg := GetGuildConfig(i.GuildID) - roleId := data.Values[0] - _, r := cfg.FindXpRole(roleId) - if r == nil { - err := resp.SetMessage("Le rôle n'a pas été trouvé dans la config.").Send() - if err != nil { - logger.Alert("config/xp_role.go - Sending role not found (del)", err.Error()) - } - return - } - err := gokord.DB.Delete(r).Error - if err != nil { - logger.Alert( - "config/xp_role.go - Deleting entry", - err.Error(), - "guild_id", i.GuildID, - "role_id", roleId, - "type", "del", - ) - } - if err = resp.SetMessage("Rôle supprimé.").Send(); err != nil { - logger.Alert("config/xp_role.go - Sending success", err.Error()) - } -} - -func HandleXpRoleLevel(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.ModalSubmitInteractionData, resp *cmd.ResponseBuilder) { - resp.IsEphemeral() - input := data.Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput) - - k := getKeyConfigRole(i) - in, err := strconv.Atoi(input.Value) - if err != nil || in < 0 { - if err = resp. - SetMessage("Impossible de lire le nombre. Il doit s'agit d'un nombre entier positif."). - Send(); err != nil { - logger.Alert("command/config.go - Sending bad number", err.Error()) - } - return - } - configModifyMap[k] = uint(in) - go func(i *discordgo.InteractionCreate, k string) { - time.Sleep(5 * time.Minute) - delete(configModifyMap, k) - }(i, k) - - cID := XpRoleAddRole - resp.SetMessage("Rôle à ajouter") - if data.CustomID == XpRoleEditLevel { - cID = XpRoleEditRole - resp.SetMessage("Rôle à modifier") - } - - err = resp. - SetComponents(component.New().Add(component.NewActionRow().Add(component.NewRoleSelect(cID)))). - Send() - if err != nil { - logger.Alert("config/guild.go - Sending response to add/edit", err.Error()) - } -} - -func getKeyConfigRole(i *discordgo.InteractionCreate) string { - return fmt.Sprintf("r:%s:%s", i.GuildID, i.User.ID) -} diff --git a/go.mod b/go.mod index 76e2ee0..854bc8a 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/anhgelus/les-copaings-bot go 1.24 require ( - github.com/anhgelus/gokord v0.11.1-0.20250806143823-567c33f63688 + github.com/anhgelus/gokord v0.11.1-0.20250806122118-84c56722e29d github.com/bwmarrin/discordgo v0.29.0 github.com/joho/godotenv v1.5.1 github.com/pelletier/go-toml/v2 v2.2.4 diff --git a/go.sum b/go.sum index cdae0a5..3a682b4 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,6 @@ github.com/anhgelus/gokord v0.11.1-0.20250806004311-9988b375047f h1:OSTlmWDVRGw3 github.com/anhgelus/gokord v0.11.1-0.20250806004311-9988b375047f/go.mod h1:4xpwLzIG34/XG9QZiPsnYScQhckiCpQMAI0CjP0Nc2k= github.com/anhgelus/gokord v0.11.1-0.20250806122118-84c56722e29d h1:cbhaSdjjipiF5yFijgewtkjE0HyHZ6tJR7zHBpCkkBI= github.com/anhgelus/gokord v0.11.1-0.20250806122118-84c56722e29d/go.mod h1:4xpwLzIG34/XG9QZiPsnYScQhckiCpQMAI0CjP0Nc2k= -github.com/anhgelus/gokord v0.11.1-0.20250806143823-567c33f63688 h1:0ngeLQxHr80Xup9UnPSjpdRH3ZpIH1mpf0ig3sEFVJk= -github.com/anhgelus/gokord v0.11.1-0.20250806143823-567c33f63688/go.mod h1:4xpwLzIG34/XG9QZiPsnYScQhckiCpQMAI0CjP0Nc2k= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= diff --git a/main.go b/main.go index b785259..79ec452 100644 --- a/main.go +++ b/main.go @@ -22,8 +22,8 @@ var ( updatesData []byte Version = gokord.Version{ Major: 3, - Minor: 2, - Patch: 0, + Minor: 1, + Patch: 3, } stopPeriodicReducer chan<- interface{} @@ -129,27 +129,15 @@ func main() { } // interaction: /config - // xp role related - bot.HandleMessageComponent(config.HandleModifyXpRole, config.ModifyXpRole) - bot.HandleMessageComponent(config.HandleXpRoleAddEdit, config.XpRoleAdd) - bot.HandleMessageComponent(config.HandleXpRoleAddEdit, config.XpRoleEdit) - bot.HandleMessageComponent(config.HandleXpRoleAddRole, config.XpRoleAddRole) - bot.HandleMessageComponent(config.HandleXpRoleEditRole, config.XpRoleEditRole) - bot.HandleMessageComponent(config.HandleXpRoleDel, config.XpRoleDel) - bot.HandleMessageComponent(config.HandleXpRoleDelRole, config.XpRoleDelRole) - bot.HandleModal(config.HandleXpRoleLevel, config.XpRoleAddLevel) - bot.HandleModal(config.HandleXpRoleLevel, config.XpRoleEditLevel) - // channel related - bot.HandleMessageComponent(config.HandleModifyFallbackChannel, config.ModifyFallbackChannel) - bot.HandleMessageComponent(config.HandleFallbackChannelSet, config.FallbackChannelSet) - bot.HandleMessageComponent(config.HandleModifyDisChannel, config.ModifyDisChannel) - bot.HandleMessageComponent(config.HandleDisChannel, config.DisChannelAdd) - bot.HandleMessageComponent(config.HandleDisChannel, config.DisChannelDel) - bot.HandleMessageComponent(config.HandleDisChannelAddSet, config.DisChannelAddSet) - bot.HandleMessageComponent(config.HandleDisChannelDelSet, config.DisChannelDelSet) - // reduce related - bot.HandleMessageComponent(config.HandleModifyPeriodicReduce, config.ModifyTimeReduce) - bot.HandleModal(config.HandleTimeReduceSet, config.TimeReduceSet) + bot.HandleMessageComponent(commands.ConfigModifyXPRole, commands.ConfigModifyXpRole) + bot.HandleMessageComponent(commands.ConfigXPRoleAddEdit, commands.XpRoleAdd) + bot.HandleMessageComponent(commands.ConfigXPRoleAddEdit, commands.XpRoleEdit) + bot.HandleMessageComponent(commands.ConfigXPRoleAddRole, commands.XpRoleAddRole) + bot.HandleMessageComponent(commands.ConfigXPRoleEditRole, commands.XpRoleEditRole) + bot.HandleMessageComponent(commands.ConfigXPRoleDel, commands.XpRoleDel) + bot.HandleMessageComponent(commands.ConfigXPRoleDelRole, commands.XpRoleDelRole) + bot.HandleModal(commands.ConfigXPRoleLevel, commands.XpRoleAddLevel) + bot.HandleModal(commands.ConfigXPRoleLevel, commands.XpRoleEditLevel) // xp handlers bot.AddHandler(OnMessage)