feat: leveling system
This commit is contained in:
@@ -2,16 +2,26 @@ package commands
|
||||
|
||||
import (
|
||||
"velox-bot/internal/commands/fun"
|
||||
"velox-bot/internal/commands/help"
|
||||
cmdlevel "velox-bot/internal/commands/level"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
)
|
||||
|
||||
var AllCommands = []*discordgo.ApplicationCommand{
|
||||
fun.PingCommand,
|
||||
help.HelpCommand,
|
||||
cmdlevel.LevelConfigCommand,
|
||||
cmdlevel.RankCommand,
|
||||
cmdlevel.LeaderboardCommand,
|
||||
}
|
||||
|
||||
var handlers = map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){
|
||||
"ping": fun.HandlePing,
|
||||
"help": help.HandleHelp,
|
||||
"slvl": cmdlevel.HandleLevelConfig,
|
||||
"rank": cmdlevel.HandleRank,
|
||||
"leaderboard": cmdlevel.HandleLeaderboard,
|
||||
}
|
||||
|
||||
func HandleInteraction(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
package help
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
)
|
||||
|
||||
var HelpCommand = &discordgo.ApplicationCommand{
|
||||
Name: "help",
|
||||
Description: "Get help with the bot",
|
||||
}
|
||||
|
||||
func HandleHelp(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Check your DMs for help.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
|
||||
userID := ""
|
||||
|
||||
// check if command is run in a guild
|
||||
if i.Member != nil {
|
||||
userID = i.Member.User.ID
|
||||
} else {
|
||||
userID = i.Interaction.User.ID
|
||||
}
|
||||
|
||||
dmChannel, err := s.UserChannelCreate(userID)
|
||||
if err != nil {
|
||||
log.Printf("Error creating DM channel: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
author := discordgo.MessageEmbedAuthor{
|
||||
Name: "Velox Bot",
|
||||
URL: "https://gitea.fernandovideira.com/FernandoJVideira/velox-bot",
|
||||
}
|
||||
|
||||
embed := &discordgo.MessageEmbed{
|
||||
Title: "Velox Bot Help",
|
||||
Description: "Here is the help for the bot.",
|
||||
Color: 0xFFA500,
|
||||
Fields: []*discordgo.MessageEmbedField{
|
||||
{
|
||||
Name: "Fun Commands",
|
||||
Value: "Here are the fun commands for the bot.",
|
||||
},
|
||||
{
|
||||
Name: "/ping",
|
||||
Value: "Pong!",
|
||||
},
|
||||
{
|
||||
Name: "/help",
|
||||
Value: "Get help with the bot.",
|
||||
},
|
||||
{
|
||||
Name: "Leveling System",
|
||||
Value: `The leveling system is a system that allows users to gain XP and level up. The system is based on the amount of messages sent in a server. The more messages you send, the more XP you gain. The more XP you gain, the higher your level will be. The leveling system is disabled by default, however you can enable/disable it by using the /slvl toggle command. You can also configure the leveling system by using the /slvl command.`,
|
||||
},
|
||||
{
|
||||
Name: "/slvl toggle",
|
||||
Value: "Toggle the leveling system.",
|
||||
},
|
||||
{
|
||||
Name: "/slvl set",
|
||||
Value: "Set the level of a user.",
|
||||
},
|
||||
},
|
||||
Author: &author,
|
||||
}
|
||||
|
||||
s.ChannelMessageSendEmbed(dmChannel.ID, embed)
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
package level
|
||||
|
||||
import (
|
||||
"context"
|
||||
"bytes"
|
||||
"strconv"
|
||||
"fmt"
|
||||
|
||||
"velox-bot/internal/db/services"
|
||||
"velox-bot/internal/rankcard"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
)
|
||||
|
||||
var RankCommand = &discordgo.ApplicationCommand{
|
||||
Name: "rank",
|
||||
Description: "Get your level card",
|
||||
Options: []*discordgo.ApplicationCommandOption{
|
||||
{
|
||||
Type: discordgo.ApplicationCommandOptionUser,
|
||||
Name: "user",
|
||||
Description: "The user to get the rank card of",
|
||||
Required: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var LeaderboardCommand = &discordgo.ApplicationCommand{
|
||||
Name: "leaderboard",
|
||||
Description: "Top 10 levels in this server",
|
||||
}
|
||||
|
||||
func HandleRank(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
if services.Global == nil || services.Global.Level == nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Leveling service is not available.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Determine target user: option or caller.
|
||||
target := i.User
|
||||
if i.Member != nil && i.Member.User != nil {
|
||||
target = i.Member.User
|
||||
}
|
||||
|
||||
if len(i.ApplicationCommandData().Options) > 0 {
|
||||
if u := i.ApplicationCommandData().Options[0].UserValue(s); u != nil {
|
||||
target = u
|
||||
}
|
||||
}
|
||||
|
||||
if target == nil {
|
||||
return
|
||||
}
|
||||
|
||||
guildID, err := strconv.ParseInt(i.GuildID, 10, 64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
userID, err := strconv.ParseInt(target.ID, 10, 64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
lvl, err := services.Global.Level.GetLevel(ctx, guildID, userID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
percent := float64(lvl.XP) / 100.0
|
||||
avatarURL := target.AvatarURL("256")
|
||||
|
||||
pngBytes, err := rankcard.RenderPNG(ctx, rankcard.Data{
|
||||
Name: target.Username,
|
||||
Level: lvl.Level,
|
||||
XP: lvl.XP,
|
||||
Percent: percent,
|
||||
Avatar: avatarURL,
|
||||
})
|
||||
if err != nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Failed to render rank card.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Files: []*discordgo.File{
|
||||
{
|
||||
Name: "levelcard.png",
|
||||
Reader: bytes.NewReader(pngBytes),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func HandleLeaderboard(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
if i.GuildID == "" {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "This command can only be used in a server.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if services.Global == nil || services.Global.Level == nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Leveling service is not available.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
guildID, err := strconv.ParseInt(i.GuildID, 10, 64)
|
||||
if err != nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Invalid guild ID.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
top, err := services.Global.Level.TopLevels(ctx, guildID, 10)
|
||||
if err != nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Failed to load leaderboard.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if len(top) == 0 {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "No leaderboard data yet.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
fields := make([]*discordgo.MessageEmbedField, 0, len(top))
|
||||
for idx, entry := range top {
|
||||
display := fmt.Sprintf("<@%d>", entry.UserID)
|
||||
if u, err := s.User(strconv.FormatInt(entry.UserID, 10)); err == nil && u != nil && u.Username != "" {
|
||||
display = u.Username
|
||||
}
|
||||
|
||||
fields = append(fields, &discordgo.MessageEmbedField{
|
||||
Name: fmt.Sprintf("%d. %s", idx+1, display),
|
||||
Value: fmt.Sprintf("Level: **%d** | XP: **%d**", entry.Level, entry.XP),
|
||||
Inline: false,
|
||||
})
|
||||
}
|
||||
|
||||
embed := &discordgo.MessageEmbed{
|
||||
Title: "Leaderboard",
|
||||
Description: fmt.Sprintf("These are the top %d users in the server", len(top)),
|
||||
Fields: fields,
|
||||
Color: 0xF59E0B,
|
||||
}
|
||||
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Embeds: []*discordgo.MessageEmbed{embed},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,597 @@
|
||||
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:
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Invalid subcommand.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func HandleLevelToggle(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
// Basic permission check: require Manage Guild permission
|
||||
if i.Member == nil || (i.Member.Permissions&discordgo.PermissionManageGuild) == 0 {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "You don't have permission to manage leveling settings.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if services.Global == nil || services.Global.LevelSettings == nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Leveling service is not available.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
guildID, err := strconv.ParseInt(i.GuildID, 10, 64)
|
||||
if err != nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Invalid guild ID.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
enabled, err := services.Global.LevelSettings.ToggleLevelSystem(ctx, guildID)
|
||||
if err != nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Failed to toggle leveling system.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
status := "disabled"
|
||||
if enabled {
|
||||
status = "enabled"
|
||||
}
|
||||
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Leveling system " + status + " for this server.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func HandleLevelSet(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
// Basic permission check: require Manage Guild permission
|
||||
if i.Member == nil || (i.Member.Permissions&discordgo.PermissionManageGuild) == 0 {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "You don't have permission to manage leveling settings.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// check if the leveling service is available
|
||||
if services.Global == nil || services.Global.Level == nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Leveling service is not available.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
data := i.ApplicationCommandData()
|
||||
optMap := make(map[string]*discordgo.ApplicationCommandInteractionDataOption, len(data.Options[0].Options))
|
||||
for _, opt := range data.Options[0].Options {
|
||||
optMap[opt.Name] = opt
|
||||
}
|
||||
|
||||
userOpt, ok := optMap["user"]
|
||||
if !ok {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Missing user option.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
levelOpt, ok := optMap["level"]
|
||||
if !ok {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Missing level option.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
targetUser := userOpt.UserValue(s)
|
||||
if targetUser == nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Invalid user.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// prevent setting bots (including ourselves)
|
||||
if targetUser.Bot {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "You can't set a bot's level.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
newLevel := int(levelOpt.IntValue())
|
||||
|
||||
ctx := context.Background()
|
||||
guildID, err := strconv.ParseInt(i.GuildID, 10, 64)
|
||||
if err != nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Invalid guild ID.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
userID, err := strconv.ParseInt(targetUser.ID, 10, 64)
|
||||
if err != nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Invalid user ID.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
err = services.Global.Level.SetLevel(ctx, guildID, userID, newLevel)
|
||||
if err != nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Failed to set level.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Level set to " + strconv.Itoa(newLevel) + " for " + targetUser.Mention() + ".",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func HandleLevelSetChannel(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
// Basic permission check: require Manage Guild permission
|
||||
if i.Member == nil || (i.Member.Permissions&discordgo.PermissionManageGuild) == 0 {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "You don't have permission to manage leveling settings.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// check if the leveling service is available
|
||||
if services.Global == nil || services.Global.Level == nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Leveling service is not available.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
guildID, err := strconv.ParseInt(i.GuildID, 10, 64)
|
||||
if err != nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Invalid guild ID.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
data := i.ApplicationCommandData()
|
||||
optMap := make(map[string]*discordgo.ApplicationCommandInteractionDataOption, len(data.Options[0].Options))
|
||||
for _, opt := range data.Options[0].Options {
|
||||
optMap[opt.Name] = opt
|
||||
}
|
||||
|
||||
channelOpt, ok := optMap["channel"]
|
||||
if !ok {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Missing channel option.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
channelID := channelOpt.ChannelValue(s)
|
||||
if channelID == nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Invalid channel.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
channelIDInt, err := strconv.ParseInt(channelID.ID, 10, 64)
|
||||
if err != nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Invalid channel ID.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
err = services.Global.LevelSettings.SetLevelUpChannel(ctx, guildID, channelIDInt)
|
||||
if err != nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Failed to set level up channel.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Level up channel set to " + channelID.Mention() + ".",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func HandleLevelSetMessage(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
// Basic permission check: require Manage Guild permission
|
||||
if i.Member == nil || (i.Member.Permissions&discordgo.PermissionManageGuild) == 0 {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "You don't have permission to manage leveling settings.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// check if the leveling service is available
|
||||
if services.Global == nil || services.Global.Level == nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Leveling service is not available.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
guildID, err := strconv.ParseInt(i.GuildID, 10, 64)
|
||||
if err != nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Invalid guild ID.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
data := i.ApplicationCommandData()
|
||||
optMap := make(map[string]*discordgo.ApplicationCommandInteractionDataOption, len(data.Options[0].Options))
|
||||
for _, opt := range data.Options[0].Options {
|
||||
optMap[opt.Name] = opt
|
||||
}
|
||||
|
||||
messageOpt, ok := optMap["message"]
|
||||
if !ok {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Missing message option.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
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 {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Failed to set level up channel.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Level up message set to " + message + ".",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func HandleLevelSetReward(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
// Basic permission check: require Manage Guild permission
|
||||
if i.Member == nil || (i.Member.Permissions&discordgo.PermissionManageGuild) == 0 {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "You don't have permission to manage leveling settings.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// check if the leveling service is available
|
||||
if services.Global == nil || services.Global.LevelSettings == nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Leveling service is not available.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
guildID, err := strconv.ParseInt(i.GuildID, 10, 64)
|
||||
if err != nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Invalid guild ID.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
data := i.ApplicationCommandData()
|
||||
optMap := make(map[string]*discordgo.ApplicationCommandInteractionDataOption, len(data.Options[0].Options))
|
||||
for _, opt := range data.Options[0].Options {
|
||||
optMap[opt.Name] = opt
|
||||
}
|
||||
|
||||
levelOpt, ok := optMap["level"]
|
||||
if !ok {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Missing level option.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
roleOpt, ok := optMap["role"]
|
||||
if !ok {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Missing role option.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
level := int(levelOpt.IntValue())
|
||||
role := roleOpt.RoleValue(s, i.GuildID)
|
||||
if role == nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Invalid role.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
roleID, err := strconv.ParseInt(role.ID, 10, 64)
|
||||
if err != nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Invalid role ID.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
if err := services.Global.LevelSettings.SetRoleRewardForLevel(ctx, guildID, level, roleID); err != nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Failed to set reward.",
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "Reward set: level " + strconv.Itoa(level) + " -> " + role.Mention(),
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user