add loads of discord bot commands

This commit is contained in:
eccentric 2023-12-14 19:47:54 +00:00
parent f35e2ea77c
commit 156f7e8f95
11 changed files with 700 additions and 54 deletions

View File

@ -48,8 +48,9 @@ func IntialiseClient() {
addCommands() addCommands()
for _, command := range StaticClient.Commands { if len(StaticClient.Commands) < len(StaticClient.GetRegisteredCommands()) {
StaticClient.RegisterCommand(command) StaticClient.UnregisterCommands()
StaticClient.RegisterCommands()
} }
err := StaticClient.Client.Open() err := StaticClient.Client.Open()
@ -58,17 +59,66 @@ func IntialiseClient() {
} }
} }
func (c *DiscordClient) RegisterCommand(command *DiscordCommand) { func (c *DiscordClient) UnregisterCommands() {
if command.AdminOnly { commands := c.GetRegisteredCommands()
adminDefaultPermission := int64(discordgo.PermissionAdministrator) if commands == nil {
command.Command.DefaultMemberPermissions = &adminDefaultPermission
}
_, err := c.Client.ApplicationCommandCreate(aid.Config.Discord.ID, aid.Config.Discord.Guild, command.Command)
if err != nil {
aid.Print("Failed to register command: " + command.Command.Name)
return return
} }
for _, command := range commands {
err := c.Client.ApplicationCommandDelete(aid.Config.Discord.ID, aid.Config.Discord.Guild, command.ID)
if err != nil {
aid.Print("Failed to delete command: " + command.Name)
}
}
commands = c.GetGlobalRegisteredCommands()
for _, command := range commands {
err := c.Client.ApplicationCommandDelete(aid.Config.Discord.ID, "", command.ID)
if err != nil {
aid.Print("Failed to delete command: " + command.Name)
}
}
}
func (c *DiscordClient) RegisterCommands() {
adminPermission := int64(discordgo.PermissionAdministrator)
update := []*discordgo.ApplicationCommand{}
for _, command := range c.Commands {
if command.AdminOnly {
command.Command.DefaultMemberPermissions = &adminPermission
}
update = append(update, command.Command)
}
_, err := c.Client.ApplicationCommandBulkOverwrite(aid.Config.Discord.ID, aid.Config.Discord.Guild, update)
if err != nil {
aid.Print("Failed to register commands", err)
return
}
}
func (c *DiscordClient) GetRegisteredCommands() []*discordgo.ApplicationCommand {
commands, err := c.Client.ApplicationCommands(aid.Config.Discord.ID, aid.Config.Discord.Guild)
if err != nil {
aid.Print("Failed to get commands")
return nil
}
return commands
}
func (c *DiscordClient) GetGlobalRegisteredCommands() []*discordgo.ApplicationCommand {
commands, err := c.Client.ApplicationCommands(aid.Config.Discord.ID, "")
if err != nil {
aid.Print("Failed to get commands")
return nil
}
return commands
} }
func (c *DiscordClient) readyHandler(s *discordgo.Session, event *discordgo.Ready) { func (c *DiscordClient) readyHandler(s *discordgo.Session, event *discordgo.Ready) {

51
discord/errors.go Normal file
View File

@ -0,0 +1,51 @@
package discord
import "github.com/bwmarrin/discordgo"
var ErrorNoAccount = discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: "You do not have an account with the bot.",
Flags: discordgo.MessageFlagsEphemeral,
},
}
var ErrorNoPermission = discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: "You do not have permission to use this command.",
Flags: discordgo.MessageFlagsEphemeral,
},
}
var ErrorInvalidArguments = discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: "Please provide valid arguments.",
Flags: discordgo.MessageFlagsEphemeral,
},
}
var ErrorInvalidDisplayOrDiscord = discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: "Please provide a valid display name or discord user.",
Flags: discordgo.MessageFlagsEphemeral,
},
}
var ErrorNoDisplay = discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: "No display name found with that name, please try again with a valid name.",
Flags: discordgo.MessageFlagsEphemeral,
},
}
var ErrorNoDiscordUser = discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: "No discord user found with that ID, please try again with a valid ID.",
Flags: discordgo.MessageFlagsEphemeral,
},
}

View File

@ -1,6 +1,8 @@
package discord package discord
import ( import (
"strings"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
"github.com/ectrc/snow/aid" "github.com/ectrc/snow/aid"
"github.com/ectrc/snow/fortnite" "github.com/ectrc/snow/fortnite"
@ -8,9 +10,6 @@ import (
"github.com/ectrc/snow/storage" "github.com/ectrc/snow/storage"
) )
var (
)
func addCommand(command *DiscordCommand) { func addCommand(command *DiscordCommand) {
StaticClient.Commands[command.Command.Name] = command StaticClient.Commands[command.Command.Name] = command
} }
@ -46,6 +45,37 @@ func addCommands() {
AdminOnly: true, AdminOnly: true,
}) })
addCommand(&DiscordCommand{
Command: &discordgo.ApplicationCommand{
Name: "who",
Description: "Lookup a player's information.",
Options: []*discordgo.ApplicationCommandOption{
{
Type: discordgo.ApplicationCommandOptionString,
Name: "display",
Description: "The display name of the player.",
Required: false,
},
{
Type: discordgo.ApplicationCommandOptionUser,
Name: "discord",
Description: "The discord account of the player.",
Required: false,
},
},
},
Handler: whoHandler,
AdminOnly: true,
})
addCommand(&DiscordCommand{
Command: &discordgo.ApplicationCommand{
Name: "me",
Description: "Lookup your own information.",
},
Handler: meHandler,
})
addCommand(&DiscordCommand{ addCommand(&DiscordCommand{
Command: &discordgo.ApplicationCommand{ Command: &discordgo.ApplicationCommand{
Name: "delete", Name: "delete",
@ -53,6 +83,134 @@ func addCommands() {
}, },
Handler: deleteHandler, Handler: deleteHandler,
}) })
addCommand(&DiscordCommand{
Command: &discordgo.ApplicationCommand{
Name: "ban",
Description: "Ban a player from using the bot.",
Options: []*discordgo.ApplicationCommandOption{
{
Type: discordgo.ApplicationCommandOptionUser,
Name: "discord",
Description: "The discord account of the player.",
Required: false,
},
{
Type: discordgo.ApplicationCommandOptionString,
Name: "display",
Description: "The display name of the player.",
Required: false,
},
},
},
Handler: banHandler,
AdminOnly: true,
})
addCommand(&DiscordCommand{
Command: &discordgo.ApplicationCommand{
Name: "unban",
Description: "Unban a player from using the bot.",
Options: []*discordgo.ApplicationCommandOption{
{
Type: discordgo.ApplicationCommandOptionUser,
Name: "discord",
Description: "The discord account of the player.",
Required: false,
},
{
Type: discordgo.ApplicationCommandOptionString,
Name: "display",
Description: "The display name of the player.",
Required: false,
},
},
},
Handler: unbanHandler,
AdminOnly: true,
})
addCommand(&DiscordCommand{
Command: &discordgo.ApplicationCommand{
Name: "give",
Description: "Grant a player an item in the game.",
Options: []*discordgo.ApplicationCommandOption{
{
Type: discordgo.ApplicationCommandOptionString,
Name: "template_id",
Description: "The item id of the cosmetic to give.",
Required: true,
},
{
Type: discordgo.ApplicationCommandOptionInteger,
Name: "quantity",
Description: "The amount of the item to give.",
Required: true,
},
{
Type: discordgo.ApplicationCommandOptionString,
Name: "profile",
Description: "common_core, athena, common_public, profile0, collections, creative",
Required: true,
},
{
Type: discordgo.ApplicationCommandOptionUser,
Name: "discord",
Description: "The discord account of the player.",
Required: false,
},
{
Type: discordgo.ApplicationCommandOptionString,
Name: "display",
Description: "The display name of the player.",
Required: false,
},
},
},
Handler: giveItemHandler,
AdminOnly: true,
})
addCommand(&DiscordCommand{
Command: &discordgo.ApplicationCommand{
Name: "take",
Description: "Take an item from a player in the game.",
Options: []*discordgo.ApplicationCommandOption{
{
Type: discordgo.ApplicationCommandOptionString,
Name: "template_id",
Description: "The item id of the cosmetic to take.",
Required: true,
},
{
Type: discordgo.ApplicationCommandOptionInteger,
Name: "quantity",
Description: "The amount of the item to take.",
Required: true,
},
{
Type: discordgo.ApplicationCommandOptionString,
Name: "profile",
Description: "common_core, athena, common_public, profile0, collections, creative",
Required: true,
},
{
Type: discordgo.ApplicationCommandOptionUser,
Name: "discord",
Description: "The discord account of the player.",
Required: false,
},
{
Type: discordgo.ApplicationCommandOptionString,
Name: "display",
Description: "The display name of the player.",
Required: false,
},
},
},
Handler: takeItemHandler,
AdminOnly: true,
})
} }
func createHandler(s *discordgo.Session, i *discordgo.InteractionCreate) { func createHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
@ -106,9 +264,7 @@ func createModalHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource, Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{ Data: &discordgo.InteractionResponseData{
Embeds: []*discordgo.MessageEmbed{ Content: "You already have an account with the display name: `"+ found.DisplayName +"`",
NewEmbedBuilder().SetTitle("Account already exists").SetDescription("You already have an account with the display name: `"+ found.DisplayName +"`").SetColor(0xda373c).Build(),
},
}, },
}) })
return return
@ -119,15 +275,13 @@ func createModalHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource, Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{ Data: &discordgo.InteractionResponseData{
Embeds: []*discordgo.MessageEmbed{ Content: "Someone already has an account with the display name: `"+ found.DisplayName +"`, please choose another one.",
NewEmbedBuilder().SetTitle("Account already exists").SetDescription("An account with that display name already exists, please try a different name.").SetColor(0xda373c).Build(),
},
}, },
}) })
return return
} }
account := fortnite.NewFortnitePerson(display.Value, aid.RandomString(10), false) // or aid.Config.Fortnite.Everything account := fortnite.NewFortnitePerson(display.Value, false) // or aid.Config.Fortnite.Everything
discord := &storage.DB_DiscordPerson{ discord := &storage.DB_DiscordPerson{
ID: i.Member.User.ID, ID: i.Member.User.ID,
PersonID: account.ID, PersonID: account.ID,
@ -140,9 +294,7 @@ func createModalHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource, Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{ Data: &discordgo.InteractionResponseData{
Embeds: []*discordgo.MessageEmbed{ Content: "Your account has been created with the display name: `"+ account.DisplayName +"`",
NewEmbedBuilder().SetTitle("Account created").SetDescription("Your account has been created with the display name: `"+ account.DisplayName +"`").SetColor(0x2093dc).Build(),
},
}, },
}) })
} }
@ -153,9 +305,8 @@ func deleteHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource, Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{ Data: &discordgo.InteractionResponseData{
Embeds: []*discordgo.MessageEmbed{ Content: "You do not have an account with the bot.",
NewEmbedBuilder().SetTitle("Account not found").SetDescription("You don't have an account with the bot.").SetColor(0xda373c).Build(), Flags: discordgo.MessageFlagsEphemeral,
},
}, },
}) })
return return
@ -167,14 +318,24 @@ func deleteHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource, Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{ Data: &discordgo.InteractionResponseData{
Embeds: []*discordgo.MessageEmbed{ Content: "Your account has been deleted.",
NewEmbedBuilder().SetTitle("Account deleted").SetDescription("Your account has been deleted.").SetColor(0x2093dc).Build(), Flags: discordgo.MessageFlagsEphemeral,
},
}, },
}) })
} }
func informationHandler(s *discordgo.Session, i *discordgo.InteractionCreate) { func informationHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
looker := person.FindByDiscord(i.Member.User.ID)
if looker == nil {
s.InteractionRespond(i.Interaction, &ErrorNoPermission)
return
}
if !looker.HasPermission(person.PermissionInformation) {
s.InteractionRespond(i.Interaction, &ErrorNoPermission)
return
}
playerCount := storage.Repo.GetPersonsCount() playerCount := storage.Repo.GetPersonsCount()
totalVbucks := storage.Repo.TotalVBucks() totalVbucks := storage.Repo.TotalVBucks()
@ -184,13 +345,344 @@ func informationHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
Embeds: []*discordgo.MessageEmbed{ Embeds: []*discordgo.MessageEmbed{
NewEmbedBuilder(). NewEmbedBuilder().
SetTitle("Information"). SetTitle("Information").
SetDescription("Useful information about this server's activity!"). SetColor(0x2b2d31).
SetColor(0x2093dc).
AddField("Players Registered", aid.FormatNumber(playerCount), true). AddField("Players Registered", aid.FormatNumber(playerCount), true).
AddField("Players Online", aid.FormatNumber(0), true). AddField("Players Online", aid.FormatNumber(0), true).
AddField("VBucks in Circulation", aid.FormatNumber(totalVbucks), false). AddField("VBucks in Circulation", aid.FormatNumber(totalVbucks), false).
Build(), Build(),
}, },
Flags: discordgo.MessageFlagsEphemeral,
}, },
}) })
}
func whoHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
looker := person.FindByDiscord(i.Member.User.ID)
if looker == nil {
s.InteractionRespond(i.Interaction, &ErrorNoPermission)
return
}
if !looker.HasPermission(person.PermissionLookup) {
s.InteractionRespond(i.Interaction, &ErrorNoPermission)
return
}
player := getPersonFromOptions(i.ApplicationCommandData(), s)
if player == nil {
s.InteractionRespond(i.Interaction, &ErrorInvalidDisplayOrDiscord)
return
}
playerVbucks := player.CommonCoreProfile.Items.GetItemByTemplateID("Currency:MtxPurchased")
if playerVbucks == nil {
return
}
activeCharacter := func() string {
if player.AthenaProfile == nil {
return "None"
}
characterId := ""
player.AthenaProfile.Loadouts.RangeLoadouts(func(key string, value *person.Loadout) bool {
characterId = value.CharacterID
return false
})
if characterId == "" {
return "None"
}
character := player.AthenaProfile.Items.GetItem(characterId)
if character == nil {
return "None"
}
return character.TemplateID
}()
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Embeds: []*discordgo.MessageEmbed{
NewEmbedBuilder().
SetTitle("Player Lookup").
SetColor(0x2b2d31).
AddField("Display Name", player.DisplayName, true).
AddField("VBucks", aid.FormatNumber(playerVbucks.Quantity), true).
AddField("Discord Account", "<@"+player.Discord.ID+">", true).
AddField("ID", player.ID, true).
SetThumbnail("https://fortnite-api.com/images/cosmetics/br/"+ strings.Split(activeCharacter, ":")[1] +"/icon.png").
Build(),
},
Flags: discordgo.MessageFlagsEphemeral,
},
})
}
func meHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
player := person.FindByDiscord(i.Member.User.ID)
if player == nil {
s.InteractionRespond(i.Interaction, &ErrorNoAccount)
return
}
playerVbucks := player.CommonCoreProfile.Items.GetItemByTemplateID("Currency:MtxPurchased")
if playerVbucks == nil {
return
}
activeCharacter := func() string {
if player.AthenaProfile == nil {
return "None"
}
characterId := ""
player.AthenaProfile.Loadouts.RangeLoadouts(func(key string, value *person.Loadout) bool {
characterId = value.CharacterID
return false
})
if characterId == "" {
return "None"
}
character := player.AthenaProfile.Items.GetItem(characterId)
if character == nil {
return "None"
}
return character.TemplateID
}()
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Embeds: []*discordgo.MessageEmbed{
NewEmbedBuilder().
SetTitle("Player Lookup").
SetColor(0x2b2d31).
AddField("Display Name", player.DisplayName, true).
AddField("VBucks", aid.FormatNumber(playerVbucks.Quantity), true).
AddField("Discord Account", "<@"+player.Discord.ID+">", true).
AddField("ID", player.ID, true).
SetThumbnail("https://fortnite-api.com/images/cosmetics/br/"+ strings.Split(activeCharacter, ":")[1] +"/icon.png").
Build(),
},
Flags: discordgo.MessageFlagsEphemeral,
},
})
}
func banHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
looker := person.FindByDiscord(i.Member.User.ID)
if looker == nil {
s.InteractionRespond(i.Interaction, &ErrorNoPermission)
return
}
if !looker.HasPermission(person.PermissionBan) {
s.InteractionRespond(i.Interaction, &ErrorNoPermission)
return
}
player := getPersonFromOptions(i.ApplicationCommandData(), s)
if player == nil {
s.InteractionRespond(i.Interaction, &ErrorInvalidDisplayOrDiscord)
return
}
player.Ban()
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: player.DisplayName + " has been banned.",
},
})
}
func unbanHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
looker := person.FindByDiscord(i.Member.User.ID)
if looker == nil {
s.InteractionRespond(i.Interaction, &ErrorNoPermission)
return
}
if !looker.HasPermission(person.PermissionBan) {
s.InteractionRespond(i.Interaction, &ErrorNoPermission)
return
}
player := getPersonFromOptions(i.ApplicationCommandData(), s)
if player == nil {
s.InteractionRespond(i.Interaction, &ErrorInvalidDisplayOrDiscord)
return
}
player.Unban()
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: player.DisplayName + " has been unbanned.",
},
})
}
func giveItemHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
looker := person.FindByDiscord(i.Member.User.ID)
if looker == nil {
s.InteractionRespond(i.Interaction, &ErrorNoAccount)
return
}
if !looker.HasPermission(person.PermissionGiveItem) {
s.InteractionRespond(i.Interaction, &ErrorNoPermission)
return
}
player := getPersonFromOptions(i.ApplicationCommandData(), s)
if player == nil {
s.InteractionRespond(i.Interaction, &ErrorInvalidDisplayOrDiscord)
return
}
item := i.ApplicationCommandData().Options[0].StringValue()
if item == "" {
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
return
}
qty := i.ApplicationCommandData().Options[1].IntValue()
if qty <= 0 {
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
return
}
profile := i.ApplicationCommandData().Options[2].StringValue()
if profile == "" {
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
return
}
if player.GetProfileFromType(profile) == nil {
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
return
}
snapshot := player.GetProfileFromType(profile).Snapshot()
foundItem := player.GetProfileFromType(profile).Items.GetItemByTemplateID(item)
switch (foundItem) {
case nil:
foundItem = person.NewItem(item, int(qty))
player.GetProfileFromType(profile).Items.AddItem(foundItem)
default:
foundItem.Quantity += int(qty)
}
foundItem.Save()
player.GetProfileFromType(profile).Diff(snapshot)
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: player.DisplayName + " has been given or updated `" + item + "` in `" + profile + "`.",
},
})
}
func takeItemHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
looker := person.FindByDiscord(i.Member.User.ID)
if looker == nil {
s.InteractionRespond(i.Interaction, &ErrorNoAccount)
return
}
if !looker.HasPermission(person.PermissionTakeItem) {
s.InteractionRespond(i.Interaction, &ErrorNoPermission)
return
}
player := getPersonFromOptions(i.ApplicationCommandData(), s)
if player == nil {
s.InteractionRespond(i.Interaction, &ErrorInvalidDisplayOrDiscord)
return
}
item := i.ApplicationCommandData().Options[0].StringValue()
if item == "" {
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
return
}
qty := i.ApplicationCommandData().Options[1].IntValue()
if qty <= 0 {
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
return
}
profile := i.ApplicationCommandData().Options[2].StringValue()
if profile == "" {
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
return
}
if player.GetProfileFromType(profile) == nil {
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
return
}
snapshot := player.GetProfileFromType(profile).Snapshot()
foundItem := player.GetProfileFromType(profile).Items.GetItemByTemplateID(item)
remove := false
switch (foundItem) {
case nil:
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
return
default:
foundItem.Quantity -= int(qty)
foundItem.Save()
if foundItem.Quantity <= 0 {
player.GetProfileFromType(profile).Items.DeleteItem(foundItem.ID)
remove = true
}
}
player.GetProfileFromType(profile).Diff(snapshot)
str := player.DisplayName + " has had `" + aid.FormatNumber(int(qty)) + "` of `" + item + "` removed from `" + profile + "`."
if remove {
str = player.DisplayName + " has had `" + item + "` removed from `" + profile + "`."
}
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: str,
},
})
}
func getPersonFromOptions(data discordgo.ApplicationCommandInteractionData, s *discordgo.Session) *person.Person {
options := data.Options
if len(options) <= 0 {
return nil
}
for _, option := range options {
switch option.Type {
case discordgo.ApplicationCommandOptionUser:
if option.Name != "discord" {
continue
}
return person.FindByDiscord(option.UserValue(s).ID)
case discordgo.ApplicationCommandOptionString:
if option.Name != "display" {
continue
}
return person.FindByDisplay(option.StringValue())
}
}
return nil
} }

View File

@ -22,10 +22,9 @@ var (
} }
) )
func NewFortnitePerson(displayName string, key string, everything bool) *p.Person { func NewFortnitePerson(displayName string, everything bool) *p.Person {
person := p.NewPerson() person := p.NewPerson()
person.DisplayName = displayName person.DisplayName = displayName
person.AccessKey = key
for _, item := range defaultAthenaItems { for _, item := range defaultAthenaItems {
item := p.NewItem(item, 1) item := p.NewItem(item, 1)

View File

@ -66,14 +66,6 @@ func PostTokenPassword(c *fiber.Ctx, body *FortniteTokenBody) error {
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("No Account Found")) return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("No Account Found"))
} }
if person.AccessKey == "" {
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("Activation Required"))
}
if person.AccessKey != body.Password {
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("Invalid Access Key"))
}
access, err := aid.JWTSign(aid.JSON{ access, err := aid.JWTSign(aid.JSON{
"snow_id": person.ID, // custom "snow_id": person.ID, // custom
"creation_date": time.Now().Format("2006-01-02T15:04:05.999Z"), "creation_date": time.Now().Format("2006-01-02T15:04:05.999Z"),

View File

@ -7,17 +7,20 @@ import (
"time" "time"
"github.com/ectrc/snow/aid" "github.com/ectrc/snow/aid"
"github.com/ectrc/snow/person"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
) )
func GetLightswitchBulkStatus(c *fiber.Ctx) error { func GetLightswitchBulkStatus(c *fiber.Ctx) error {
person := c.Locals("person").(*person.Person)
return c.Status(fiber.StatusOK).JSON([]aid.JSON{{ return c.Status(fiber.StatusOK).JSON([]aid.JSON{{
"serviceInstanceId": "fortnite", "serviceInstanceId": "fortnite",
"status" :"UP", "status" :"UP",
"message": "fortnite is up.", "message": "fortnite is up.",
"maintenanceUri": nil, "maintenanceUri": nil,
"allowedActions": []string{"PLAY","DOWNLOAD"}, "allowedActions": []string{"PLAY","DOWNLOAD"},
"banned":false, "banned": person.IsBanned,
"launcherInfoDTO": aid.JSON{ "launcherInfoDTO": aid.JSON{
"appName":"Fortnite", "appName":"Fortnite",
"catalogItemId":"4fe75bbc5a674f4f9b356b5c90567da5", "catalogItemId":"4fe75bbc5a674f4f9b356b5c90567da5",

View File

@ -106,6 +106,7 @@ func main() {
profile.Post("/client/:action", handlers.PostProfileAction) profile.Post("/client/:action", handlers.PostProfileAction)
lightswitch := r.Group("/lightswitch/api") lightswitch := r.Group("/lightswitch/api")
lightswitch.Use(handlers.FortniteMiddleware)
lightswitch.Get("/service/bulk/status", handlers.GetLightswitchBulkStatus) lightswitch.Get("/service/bulk/status", handlers.GetLightswitchBulkStatus)
snow := r.Group("/snow") snow := r.Group("/snow")

15
person/permissions.go Normal file
View File

@ -0,0 +1,15 @@
package person
type Permission string
const (
PermissionLookup Permission = "lookup"
PermissionBan Permission = "ban"
PermissionInformation Permission = "information"
PermissionDonator Permission = "donator"
PermissionGiveItem Permission = "give_item"
PermissionTakeItem Permission = "take_item"
PermissionReset Permission = "reset"
PermissionAll Permission = "all"
)

View File

@ -8,14 +8,14 @@ import (
type Person struct { type Person struct {
ID string ID string
DisplayName string DisplayName string
AccessKey string Permissions []string
IsBanned bool
AthenaProfile *Profile AthenaProfile *Profile
CommonCoreProfile *Profile CommonCoreProfile *Profile
CommonPublicProfile *Profile CommonPublicProfile *Profile
Profile0Profile *Profile Profile0Profile *Profile
CollectionsProfile *Profile CollectionsProfile *Profile
CreativeProfile *Profile CreativeProfile *Profile
// DiscordID string
Discord *storage.DB_DiscordPerson Discord *storage.DB_DiscordPerson
} }
@ -28,7 +28,8 @@ func NewPerson() *Person {
return &Person{ return &Person{
ID: uuid.New().String(), ID: uuid.New().String(),
DisplayName: uuid.New().String(), DisplayName: uuid.New().String(),
AccessKey: "", Permissions: []string{},
IsBanned: false,
AthenaProfile: NewProfile("athena"), AthenaProfile: NewProfile("athena"),
CommonCoreProfile: NewProfile("common_core"), CommonCoreProfile: NewProfile("common_core"),
CommonPublicProfile: NewProfile("common_public"), CommonPublicProfile: NewProfile("common_public"),
@ -135,7 +136,8 @@ func findHelper(databasePerson *storage.DB_Person) *Person {
person := &Person{ person := &Person{
ID: databasePerson.ID, ID: databasePerson.ID,
DisplayName: databasePerson.DisplayName, DisplayName: databasePerson.DisplayName,
AccessKey: databasePerson.AccessKey, Permissions: databasePerson.Permissions,
IsBanned: databasePerson.IsBanned,
AthenaProfile: athenaProfile, AthenaProfile: athenaProfile,
CommonCoreProfile: commonCoreProfile, CommonCoreProfile: commonCoreProfile,
CommonPublicProfile: commonPublicProfile, CommonPublicProfile: commonPublicProfile,
@ -143,7 +145,6 @@ func findHelper(databasePerson *storage.DB_Person) *Person {
CollectionsProfile: collectionsProfile, CollectionsProfile: collectionsProfile,
CreativeProfile: creativeProfile, CreativeProfile: creativeProfile,
Discord: &databasePerson.Discord, Discord: &databasePerson.Discord,
// DiscordID: databasePerson.DiscordID,
} }
cache.SavePerson(person) cache.SavePerson(person)
@ -197,14 +198,54 @@ func (p *Person) Save() {
storage.Repo.SavePerson(dbPerson) storage.Repo.SavePerson(dbPerson)
} }
func (p *Person) Ban() {
p.IsBanned = true
p.Save()
}
func (p *Person) Unban() {
p.IsBanned = false
p.Save()
}
func (p *Person) AddPermission(permission string) {
p.Permissions = append(p.Permissions, permission)
p.Save()
}
func (p *Person) RemovePermission(permission string) {
for i, perm := range p.Permissions {
if perm == permission {
p.Permissions = append(p.Permissions[:i], p.Permissions[i+1:]...)
break
}
}
p.Save()
}
func (p *Person) HasPermission(permission Permission) bool {
for _, perm := range p.Permissions {
if perm == string(PermissionAll) {
return true
}
if perm == string(permission) {
return true
}
}
return false
}
func (p *Person) ToDatabase() *storage.DB_Person { func (p *Person) ToDatabase() *storage.DB_Person {
dbPerson := storage.DB_Person{ dbPerson := storage.DB_Person{
ID: p.ID, ID: p.ID,
DisplayName: p.DisplayName, DisplayName: p.DisplayName,
Permissions: p.Permissions,
IsBanned: p.IsBanned,
Profiles: []storage.DB_Profile{}, Profiles: []storage.DB_Profile{},
Stats: []storage.DB_SeasonStat{}, Stats: []storage.DB_SeasonStat{},
AccessKey: p.AccessKey, Discord: storage.DB_DiscordPerson{},
// DiscordID: p.DiscordID,
} }
if p.Discord != nil { if p.Discord != nil {
@ -281,6 +322,8 @@ func (p *Person) Snapshot() *PersonSnapshot {
return &PersonSnapshot{ return &PersonSnapshot{
ID: p.ID, ID: p.ID,
DisplayName: p.DisplayName, DisplayName: p.DisplayName,
Permissions: p.Permissions,
IsBanned: p.IsBanned,
AthenaProfile: *p.AthenaProfile.Snapshot(), AthenaProfile: *p.AthenaProfile.Snapshot(),
CommonCoreProfile: *p.CommonCoreProfile.Snapshot(), CommonCoreProfile: *p.CommonCoreProfile.Snapshot(),
CommonPublicProfile: *p.CommonPublicProfile.Snapshot(), CommonPublicProfile: *p.CommonPublicProfile.Snapshot(),
@ -288,7 +331,6 @@ func (p *Person) Snapshot() *PersonSnapshot {
CollectionsProfile: *p.CollectionsProfile.Snapshot(), CollectionsProfile: *p.CollectionsProfile.Snapshot(),
CreativeProfile: *p.CreativeProfile.Snapshot(), CreativeProfile: *p.CreativeProfile.Snapshot(),
Discord: *p.Discord, Discord: *p.Discord,
DiscordID: p.Discord.ID,
} }
} }

View File

@ -5,6 +5,8 @@ import "github.com/ectrc/snow/storage"
type PersonSnapshot struct { type PersonSnapshot struct {
ID string ID string
DisplayName string DisplayName string
Permissions []string
IsBanned bool
AthenaProfile ProfileSnapshot AthenaProfile ProfileSnapshot
CommonCoreProfile ProfileSnapshot CommonCoreProfile ProfileSnapshot
CommonPublicProfile ProfileSnapshot CommonPublicProfile ProfileSnapshot
@ -12,7 +14,6 @@ type PersonSnapshot struct {
CollectionsProfile ProfileSnapshot CollectionsProfile ProfileSnapshot
CreativeProfile ProfileSnapshot CreativeProfile ProfileSnapshot
Discord storage.DB_DiscordPerson Discord storage.DB_DiscordPerson
DiscordID string
} }
type ProfileSnapshot struct { type ProfileSnapshot struct {

View File

@ -9,10 +9,10 @@ type Tabler interface {
type DB_Person struct { type DB_Person struct {
ID string ID string
DisplayName string DisplayName string
AccessKey string Permissions pq.StringArray `gorm:"type:text[]"`
IsBanned bool
Profiles []DB_Profile `gorm:"foreignkey:PersonID"` Profiles []DB_Profile `gorm:"foreignkey:PersonID"`
Stats []DB_SeasonStat `gorm:"foreignkey:PersonID"` Stats []DB_SeasonStat `gorm:"foreignkey:PersonID"`
// DiscordID string
Discord DB_DiscordPerson `gorm:"foreignkey:PersonID"` Discord DB_DiscordPerson `gorm:"foreignkey:PersonID"`
} }