package level import ( "context" "strconv" "velox-bot/internal/db/services" "github.com/bwmarrin/discordgo" ) var LevelConfigCommand = &discordgo.ApplicationCommand{ Name: "slvl", Description: "Leveling System", Options: []*discordgo.ApplicationCommandOption{ { Type: discordgo.ApplicationCommandOptionSubCommand, Name: "toggle", Description: "Toggle the leveling system", }, { Type: discordgo.ApplicationCommandOptionSubCommand, Name: "set", Description: "Set the level of a user", Options: []*discordgo.ApplicationCommandOption{ { Type: discordgo.ApplicationCommandOptionUser, Name: "user", Description: "The user to set the level of", Required: true, }, { Type: discordgo.ApplicationCommandOptionInteger, Name: "level", Description: "The level to set the user to", Required: true, }, }, }, { Type: discordgo.ApplicationCommandOptionSubCommand, Name: "set-channel", Description: "Set the level up channel", Options: []*discordgo.ApplicationCommandOption{ { Type: discordgo.ApplicationCommandOptionChannel, Name: "channel", Description: "The channel to set the level up channel to. If not provided, the current channel will be used.", Required: true, }, }, }, { Type: discordgo.ApplicationCommandOptionSubCommand, Name: "set-message", Description: "Set the level up message", Options: []*discordgo.ApplicationCommandOption{ { Type: discordgo.ApplicationCommandOptionString, Name: "message", Description: "Level-up message. Variables: {user}, {level}", Required: true, }, }, }, { Type: discordgo.ApplicationCommandOptionSubCommand, Name: "set-reward", Description: "Set role reward for a level", Options: []*discordgo.ApplicationCommandOption{ { Type: discordgo.ApplicationCommandOptionInteger, Name: "level", Description: "Level to reward", Required: true, }, { Type: discordgo.ApplicationCommandOptionRole, Name: "role", Description: "Role to grant", Required: true, }, }, }, }, } func HandleLevelConfig(s *discordgo.Session, i *discordgo.InteractionCreate) { data := i.ApplicationCommandData() subCommand := data.Options[0].Name switch subCommand { case "toggle": HandleLevelToggle(s, i) case "set": HandleLevelSet(s, i) case "set-channel": HandleLevelSetChannel(s, i) case "set-message": HandleLevelSetMessage(s, i) case "set-reward": HandleLevelSetReward(s, i) default: respondEphemeral(s, i, "Invalid subcommand.") } } func HandleLevelToggle(s *discordgo.Session, i *discordgo.InteractionCreate) { if !requireManageGuild(s, i) { return } if !requireLevelSettingsService(s, i) { return } ctx := context.Background() guildID, ok := parseGuildID(s, i) if !ok { return } enabled, err := services.Global.LevelSettings.ToggleLevelSystem(ctx, guildID) if err != nil { respondEphemeral(s, i, "Failed to toggle leveling system.") return } status := "disabled" if enabled { status = "enabled" } respondEphemeral(s, i, "Leveling system "+status+" for this server.") } func HandleLevelSet(s *discordgo.Session, i *discordgo.InteractionCreate) { if !requireManageGuild(s, i) || !requireLevelSystemEnabled(s, i) { return } if services.Global == nil || services.Global.Level == nil { respondEphemeral(s, i, "Leveling service is not available.") return } optMap := subcommandOptionMap(i) userOpt, ok := optMap["user"] if !ok { respondEphemeral(s, i, "Missing user option.") return } levelOpt, ok := optMap["level"] if !ok { respondEphemeral(s, i, "Missing level option.") return } targetUser := userOpt.UserValue(s) if targetUser == nil { respondEphemeral(s, i, "Invalid user.") return } // prevent setting bots (including ourselves) if targetUser.Bot { respondEphemeral(s, i, "You can't set a bot's level.") return } newLevel := int(levelOpt.IntValue()) ctx := context.Background() guildID, ok := parseGuildID(s, i) if !ok { return } userID, err := strconv.ParseInt(targetUser.ID, 10, 64) if err != nil { respondEphemeral(s, i, "Invalid user ID.") return } err = services.Global.Level.SetLevel(ctx, guildID, userID, newLevel) if err != nil { respondEphemeral(s, i, "Failed to set level.") return } respondEphemeral(s, i, "Level set to "+strconv.Itoa(newLevel)+" for "+targetUser.Mention()+".") } func HandleLevelSetChannel(s *discordgo.Session, i *discordgo.InteractionCreate) { if !requireManageGuild(s, i) || !requireLevelSystemEnabled(s, i) { return } if !requireLevelSettingsService(s, i) { return } guildID, ok := parseGuildID(s, i) if !ok { return } optMap := subcommandOptionMap(i) channelOpt, ok := optMap["channel"] if !ok { respondEphemeral(s, i, "Missing channel option.") return } channelID := channelOpt.ChannelValue(s) if channelID == nil { respondEphemeral(s, i, "Invalid channel.") return } ctx := context.Background() channelIDInt, err := strconv.ParseInt(channelID.ID, 10, 64) if err != nil { respondEphemeral(s, i, "Invalid channel ID.") return } err = services.Global.LevelSettings.SetLevelUpChannel(ctx, guildID, channelIDInt) if err != nil { respondEphemeral(s, i, "Failed to set level up channel.") return } respondEphemeral(s, i, "Level up channel set to "+channelID.Mention()+".") } func HandleLevelSetMessage(s *discordgo.Session, i *discordgo.InteractionCreate) { if !requireManageGuild(s, i) || !requireLevelSystemEnabled(s, i) { return } if !requireLevelSettingsService(s, i) { return } guildID, ok := parseGuildID(s, i) if !ok { return } optMap := subcommandOptionMap(i) messageOpt, ok := optMap["message"] if !ok { respondEphemeral(s, i, "Missing message option.") return } message := messageOpt.StringValue() if message == "" { message = "GG {user}, you reached level {level}!" } ctx := context.Background() err := services.Global.LevelSettings.SetLevelUpMessage(ctx, guildID, message) if err != nil { respondEphemeral(s, i, "Failed to set level up message.") return } respondEphemeral(s, i, "Level up message set.") } func HandleLevelSetReward(s *discordgo.Session, i *discordgo.InteractionCreate) { if !requireManageGuild(s, i) || !requireLevelSystemEnabled(s, i) { return } if !requireLevelSettingsService(s, i) { return } guildID, ok := parseGuildID(s, i) if !ok { return } optMap := subcommandOptionMap(i) levelOpt, ok := optMap["level"] if !ok { respondEphemeral(s, i, "Missing level option.") return } roleOpt, ok := optMap["role"] if !ok { respondEphemeral(s, i, "Missing role option.") return } level := int(levelOpt.IntValue()) role := roleOpt.RoleValue(s, i.GuildID) if role == nil { respondEphemeral(s, i, "Invalid role.") return } roleID, err := strconv.ParseInt(role.ID, 10, 64) if err != nil { respondEphemeral(s, i, "Invalid role ID.") return } ctx := context.Background() if err := services.Global.LevelSettings.SetRoleRewardForLevel(ctx, guildID, level, roleID); err != nil { respondEphemeral(s, i, "Failed to set reward.") return } respondEphemeral(s, i, "Reward set: level "+strconv.Itoa(level)+" -> "+role.Mention()) }