Improve ban commands
This commit is contained in:
parent
33bfef4da8
commit
0a63dd8fe4
|
@ -55,4 +55,13 @@ func (s *GenericSyncMap[T]) ChangeKey(oldKey, newKey string) {
|
|||
|
||||
s.Set(newKey, v)
|
||||
s.Delete(oldKey)
|
||||
}
|
||||
|
||||
func (s *GenericSyncMap[T]) Len() int {
|
||||
count := 0
|
||||
s.m.Range(func(_, _ interface{}) bool {
|
||||
count++
|
||||
return true
|
||||
})
|
||||
return count
|
||||
}
|
174
aid/time.go
174
aid/time.go
|
@ -1,6 +1,9 @@
|
|||
package aid
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TimeStartOfDay() string {
|
||||
return time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 0, 0, 0, 0, time.Now().Location()).Format("2006-01-02T15:04:05.999Z")
|
||||
|
@ -12,4 +15,173 @@ func TimeEndOfDay() string {
|
|||
|
||||
func TimeEndOfWeekString() string {
|
||||
return time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 23, 59, 59, 999999999, time.Now().Location()).AddDate(0, 0, 7).Format("2006-01-02T15:04:05.999Z")
|
||||
}
|
||||
|
||||
// everything below is taken from the golang standard library I just added the extra units to the map
|
||||
|
||||
var unitMap = map[string]uint64{
|
||||
"ns": uint64(time.Nanosecond),
|
||||
"us": uint64(time.Microsecond),
|
||||
"µs": uint64(time.Microsecond), // U+00B5 = micro symbol
|
||||
"μs": uint64(time.Microsecond), // U+03BC = Greek letter mu
|
||||
"ms": uint64(time.Millisecond),
|
||||
"s": uint64(time.Second),
|
||||
"m": uint64(time.Minute),
|
||||
"h": uint64(time.Hour),
|
||||
"d": uint64(time.Hour * 24),
|
||||
"w": uint64(time.Hour * 24 * 7),
|
||||
"y": uint64(time.Hour * 24 * 365), // no leap year
|
||||
"c": uint64(time.Hour * 24 * 365 * 100), // no leap year
|
||||
}
|
||||
|
||||
// ParseDuration parses a duration string.
|
||||
// A duration string is a possibly signed sequence of
|
||||
// decimal numbers, each with optional fraction and a unit suffix,
|
||||
// such as "300ms", "-1.5h" or "2h45m".
|
||||
// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
||||
|
||||
func leadingFraction(s string) (x uint64, scale float64, rem string) {
|
||||
i := 0
|
||||
scale = 1
|
||||
overflow := false
|
||||
for ; i < len(s); i++ {
|
||||
c := s[i]
|
||||
if c < '0' || c > '9' {
|
||||
break
|
||||
}
|
||||
if overflow {
|
||||
continue
|
||||
}
|
||||
if x > (1<<63-1)/10 {
|
||||
// It's possible for overflow to give a positive number, so take care.
|
||||
overflow = true
|
||||
continue
|
||||
}
|
||||
y := x*10 + uint64(c) - '0'
|
||||
if y > 1<<63 {
|
||||
overflow = true
|
||||
continue
|
||||
}
|
||||
x = y
|
||||
scale *= 10
|
||||
}
|
||||
return x, scale, s[i:]
|
||||
}
|
||||
|
||||
func leadingInt[bytes []byte | string](s bytes) (x uint64, rem bytes, err error) {
|
||||
i := 0
|
||||
for ; i < len(s); i++ {
|
||||
c := s[i]
|
||||
if c < '0' || c > '9' {
|
||||
break
|
||||
}
|
||||
if x > 1<<63/10 {
|
||||
// overflow
|
||||
return 0, rem, errors.New("time: invalid duration ")
|
||||
}
|
||||
x = x*10 + uint64(c) - '0'
|
||||
if x > 1<<63 {
|
||||
// overflow
|
||||
return 0, rem, errors.New("time: invalid duration ")
|
||||
}
|
||||
}
|
||||
return x, s[i:], nil
|
||||
}
|
||||
|
||||
func ParseDuration(s string) (time.Duration, error) {
|
||||
// [-+]?([0-9]*(\.[0-9]*)?[a-z]+)+
|
||||
var d uint64
|
||||
neg := false
|
||||
|
||||
// Consume [-+]?
|
||||
if s != "" {
|
||||
c := s[0]
|
||||
if c == '-' || c == '+' {
|
||||
neg = c == '-'
|
||||
s = s[1:]
|
||||
}
|
||||
}
|
||||
// Special case: if all that is left is "0", this is zero.
|
||||
if s == "0" {
|
||||
return 0, nil
|
||||
}
|
||||
if s == "" {
|
||||
return 0, errors.New("time: invalid duration")
|
||||
}
|
||||
for s != "" {
|
||||
var (
|
||||
v, f uint64 // integers before, after decimal point
|
||||
scale float64 = 1 // value = v + f/scale
|
||||
)
|
||||
|
||||
var err error
|
||||
|
||||
// The next character must be [0-9.]
|
||||
if !(s[0] == '.' || '0' <= s[0] && s[0] <= '9') {
|
||||
return 0, errors.New("time: invalid duration")
|
||||
}
|
||||
// Consume [0-9]*
|
||||
pl := len(s)
|
||||
v, s, err = leadingInt(s)
|
||||
if err != nil {
|
||||
return 0, errors.New("time: invalid duration")
|
||||
}
|
||||
pre := pl != len(s) // whether we consumed anything before a period
|
||||
|
||||
// Consume (\.[0-9]*)?
|
||||
post := false
|
||||
if s != "" && s[0] == '.' {
|
||||
s = s[1:]
|
||||
pl := len(s)
|
||||
f, scale, s = leadingFraction(s)
|
||||
post = pl != len(s)
|
||||
}
|
||||
if !pre && !post {
|
||||
// no digits (e.g. ".s" or "-.s")
|
||||
return 0, errors.New("time: invalid duration")
|
||||
}
|
||||
|
||||
// Consume unit.
|
||||
i := 0
|
||||
for ; i < len(s); i++ {
|
||||
c := s[i]
|
||||
if c == '.' || '0' <= c && c <= '9' {
|
||||
break
|
||||
}
|
||||
}
|
||||
if i == 0 {
|
||||
return 0, errors.New("time: missing unit in duration")
|
||||
}
|
||||
u := s[:i]
|
||||
s = s[i:]
|
||||
unit, ok := unitMap[u]
|
||||
if !ok {
|
||||
return 0, errors.New("time: unknown unit in duration")
|
||||
}
|
||||
if v > 1<<63/unit {
|
||||
// overflow
|
||||
return 0, errors.New("time: invalid duration ")
|
||||
}
|
||||
v *= unit
|
||||
if f > 0 {
|
||||
// float64 is needed to be nanosecond accurate for fractions of hours.
|
||||
// v >= 0 && (f*unit/scale) <= 3.6e+12 (ns/h, h is the largest unit)
|
||||
v += uint64(float64(f) * (float64(unit) / scale))
|
||||
if v > 1<<63 {
|
||||
// overflow
|
||||
return 0, errors.New("time: invalid duration")
|
||||
}
|
||||
}
|
||||
d += v
|
||||
if d > 1<<63 {
|
||||
return 0, errors.New("time: invalid duration")
|
||||
}
|
||||
}
|
||||
if neg {
|
||||
return -time.Duration(d), nil
|
||||
}
|
||||
if d > 1<<63-1 {
|
||||
return 0, errors.New("time: invalid duration")
|
||||
}
|
||||
return time.Duration(d), nil
|
||||
}
|
185
discord/admin.go
185
discord/admin.go
|
@ -1,6 +1,7 @@
|
|||
package discord
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
|
@ -107,64 +108,117 @@ func whoHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|||
})
|
||||
}
|
||||
|
||||
func banHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
func bansHandler(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) {
|
||||
if !looker.HasPermission(person.PermissionBansControl) {
|
||||
s.InteractionRespond(i.Interaction, &ErrorNoPermission)
|
||||
return
|
||||
}
|
||||
|
||||
player := getPersonFromOptions(i.ApplicationCommandData().Options, s)
|
||||
if len(i.ApplicationCommandData().Options) <= 0 {
|
||||
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
|
||||
return
|
||||
}
|
||||
|
||||
subCommand := i.ApplicationCommandData().Options[0]
|
||||
if len(subCommand.Options) <= 0 {
|
||||
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
|
||||
return
|
||||
}
|
||||
|
||||
player := getPersonFromOptions(subCommand.Options, s)
|
||||
if player == nil {
|
||||
s.InteractionRespond(i.Interaction, &ErrorInvalidDisplayOrDiscord)
|
||||
return
|
||||
}
|
||||
|
||||
player.Ban()
|
||||
lookup := map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate, looker *person.Person, player *person.Person, options []*discordgo.ApplicationCommandInteractionDataOption){
|
||||
"add": addBanHandler,
|
||||
"clear": clearBansHandler,
|
||||
"list": listBansHandler,
|
||||
}
|
||||
|
||||
if handler, ok := lookup[subCommand.Name]; ok {
|
||||
handler(s, i, looker, player, subCommand.Options)
|
||||
return
|
||||
}
|
||||
|
||||
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
|
||||
}
|
||||
|
||||
func addBanHandler(s *discordgo.Session, i *discordgo.InteractionCreate, looker *person.Person, player *person.Person, options []*discordgo.ApplicationCommandInteractionDataOption) {
|
||||
reason := options[0].StringValue()
|
||||
if reason == "" {
|
||||
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
|
||||
return
|
||||
}
|
||||
|
||||
var expiry string
|
||||
for _, option := range options {
|
||||
if option.Name == "expires" {
|
||||
expiry = option.StringValue()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
aid.Print(expiry)
|
||||
|
||||
player.AddBan(reason, looker.ID, expiry)
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: player.DisplayName + " has been banned.",
|
||||
Content: player.DisplayName + " has been banned for `" + reason + "`.",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
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().Options, s)
|
||||
if player == nil {
|
||||
s.InteractionRespond(i.Interaction, &ErrorInvalidDisplayOrDiscord)
|
||||
return
|
||||
}
|
||||
|
||||
player.Unban()
|
||||
func clearBansHandler(s *discordgo.Session, i *discordgo.InteractionCreate, looker *person.Person, player *person.Person, options []*discordgo.ApplicationCommandInteractionDataOption) {
|
||||
player.ClearBans()
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: player.DisplayName + " has been unbanned.",
|
||||
Content: player.DisplayName + " has had all bans cleared.",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func giveItemHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
func listBansHandler(s *discordgo.Session, i *discordgo.InteractionCreate, looker *person.Person, player *person.Person, options []*discordgo.ApplicationCommandInteractionDataOption) {
|
||||
embed := NewEmbedBuilder().
|
||||
SetTitle("Ban History").
|
||||
SetColor(0x2b2d31)
|
||||
|
||||
player.BanHistory.Range(func(key string, ban *storage.DB_BanStatus) bool {
|
||||
banIssuer := person.Find(ban.IssuedBy)
|
||||
if banIssuer == nil {
|
||||
banIssuer = &person.Person{Discord: &storage.DB_DiscordPerson{ID: "0"}}
|
||||
}
|
||||
|
||||
embed.AddField(ban.Reason, "Banned by <@"+banIssuer.Discord.ID+"> on <t:"+fmt.Sprintf("%d", ban.Expiry.Unix())+":D>", false)
|
||||
return true
|
||||
})
|
||||
|
||||
if player.BanHistory.Len() <= 0 {
|
||||
embed.SetDescription("No bans found.")
|
||||
}
|
||||
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Embeds: []*discordgo.MessageEmbed{embed.Build()},
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func itemsHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
looker := person.FindByDiscord(i.Member.User.ID)
|
||||
if looker == nil {
|
||||
s.InteractionRespond(i.Interaction, &ErrorNoAccount)
|
||||
s.InteractionRespond(i.Interaction, &ErrorNoPermission)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -173,25 +227,56 @@ func giveItemHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|||
return
|
||||
}
|
||||
|
||||
player := getPersonFromOptions(i.ApplicationCommandData().Options, s)
|
||||
if len(i.ApplicationCommandData().Options) <= 0 {
|
||||
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
|
||||
return
|
||||
}
|
||||
|
||||
subCommand := i.ApplicationCommandData().Options[0]
|
||||
if len(subCommand.Options) <= 0 {
|
||||
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
|
||||
return
|
||||
}
|
||||
|
||||
player := getPersonFromOptions(subCommand.Options, s)
|
||||
if player == nil {
|
||||
s.InteractionRespond(i.Interaction, &ErrorInvalidDisplayOrDiscord)
|
||||
return
|
||||
}
|
||||
|
||||
item := i.ApplicationCommandData().Options[0].StringValue()
|
||||
lookup := map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate, looker *person.Person, player *person.Person, options []*discordgo.ApplicationCommandInteractionDataOption){
|
||||
"add": addItemHandler,
|
||||
"remove": removeItemHandler,
|
||||
"fill": fillItemsHandler,
|
||||
}
|
||||
|
||||
if handler, ok := lookup[subCommand.Name]; ok {
|
||||
handler(s, i, looker, player, subCommand.Options)
|
||||
return
|
||||
}
|
||||
|
||||
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
|
||||
}
|
||||
|
||||
func addItemHandler(s *discordgo.Session, i *discordgo.InteractionCreate, looker *person.Person, player *person.Person, options []*discordgo.ApplicationCommandInteractionDataOption) {
|
||||
if !looker.HasPermission(person.PermissionItemControl) {
|
||||
s.InteractionRespond(i.Interaction, &ErrorNoPermission)
|
||||
return
|
||||
}
|
||||
|
||||
item := options[0].StringValue()
|
||||
if item == "" {
|
||||
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
|
||||
return
|
||||
}
|
||||
|
||||
qty := i.ApplicationCommandData().Options[1].IntValue()
|
||||
qty := options[1].IntValue()
|
||||
if qty <= 0 {
|
||||
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
|
||||
return
|
||||
}
|
||||
|
||||
profile := i.ApplicationCommandData().Options[2].StringValue()
|
||||
profile := options[2].StringValue()
|
||||
if profile == "" {
|
||||
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
|
||||
return
|
||||
|
@ -222,37 +307,25 @@ func giveItemHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|||
})
|
||||
}
|
||||
|
||||
func takeItemHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
looker := person.FindByDiscord(i.Member.User.ID)
|
||||
if looker == nil {
|
||||
s.InteractionRespond(i.Interaction, &ErrorNoAccount)
|
||||
return
|
||||
}
|
||||
|
||||
func removeItemHandler(s *discordgo.Session, i *discordgo.InteractionCreate, looker *person.Person, player *person.Person, options []*discordgo.ApplicationCommandInteractionDataOption) {
|
||||
if !looker.HasPermission(person.PermissionItemControl) {
|
||||
s.InteractionRespond(i.Interaction, &ErrorNoPermission)
|
||||
return
|
||||
}
|
||||
|
||||
player := getPersonFromOptions(i.ApplicationCommandData().Options, s)
|
||||
if player == nil {
|
||||
s.InteractionRespond(i.Interaction, &ErrorInvalidDisplayOrDiscord)
|
||||
return
|
||||
}
|
||||
|
||||
item := i.ApplicationCommandData().Options[0].StringValue()
|
||||
item := options[0].StringValue()
|
||||
if item == "" {
|
||||
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
|
||||
return
|
||||
}
|
||||
|
||||
qty := i.ApplicationCommandData().Options[1].IntValue()
|
||||
qty := options[1].IntValue()
|
||||
if qty <= 0 {
|
||||
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
|
||||
return
|
||||
}
|
||||
|
||||
profile := i.ApplicationCommandData().Options[2].StringValue()
|
||||
profile := options[2].StringValue()
|
||||
if profile == "" {
|
||||
s.InteractionRespond(i.Interaction, &ErrorInvalidArguments)
|
||||
return
|
||||
|
@ -273,7 +346,6 @@ func takeItemHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|||
default:
|
||||
foundItem.Quantity -= int(qty)
|
||||
foundItem.Save()
|
||||
|
||||
if foundItem.Quantity <= 0 {
|
||||
player.GetProfileFromType(profile).Items.DeleteItem(foundItem.ID)
|
||||
remove = true
|
||||
|
@ -294,31 +366,18 @@ func takeItemHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|||
})
|
||||
}
|
||||
|
||||
func giveEverythingHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
looker := person.FindByDiscord(i.Member.User.ID)
|
||||
if looker == nil {
|
||||
s.InteractionRespond(i.Interaction, &ErrorNoPermission)
|
||||
return
|
||||
}
|
||||
|
||||
func fillItemsHandler(s *discordgo.Session, i *discordgo.InteractionCreate, looker *person.Person, player *person.Person, options []*discordgo.ApplicationCommandInteractionDataOption) {
|
||||
if !looker.HasPermission(person.PermissionItemControl) || !looker.HasPermission(person.PermissionLockerControl) {
|
||||
s.InteractionRespond(i.Interaction, &ErrorNoPermission)
|
||||
return
|
||||
}
|
||||
|
||||
player := getPersonFromOptions(i.ApplicationCommandData().Options, s)
|
||||
if player == nil {
|
||||
s.InteractionRespond(i.Interaction, &ErrorInvalidDisplayOrDiscord)
|
||||
return
|
||||
}
|
||||
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
|
||||
})
|
||||
|
||||
fortnite.GiveEverything(player)
|
||||
|
||||
str := player.DisplayName + "has been granted everything."
|
||||
str := player.DisplayName + "has been granted all items."
|
||||
s.InteractionResponseEdit(i.Interaction, &discordgo.WebhookEdit{
|
||||
Content: &str,
|
||||
})
|
||||
|
|
|
@ -48,7 +48,7 @@ func addCommands() {
|
|||
|
||||
addCommand(&DiscordCommand{
|
||||
Command: &discordgo.ApplicationCommand{
|
||||
Name: "me",
|
||||
Name: "account",
|
||||
Description: "Lookup your own information.",
|
||||
},
|
||||
Handler: meHandler,
|
||||
|
@ -89,23 +89,49 @@ func addCommands() {
|
|||
AdminOnly: true,
|
||||
})
|
||||
|
||||
addCommand(&DiscordCommand{
|
||||
Command: &discordgo.ApplicationCommand{
|
||||
Name: "ban",
|
||||
Description: "Ban a player from using the bot.",
|
||||
bansOptions := append([]*discordgo.ApplicationCommandOption{
|
||||
{
|
||||
Type: discordgo.ApplicationCommandOptionString,
|
||||
Name: "reason",
|
||||
Description: "The reason for the ban.",
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Type: discordgo.ApplicationCommandOptionString,
|
||||
Name: "expires",
|
||||
Description: "The time the ban expires. (e.g. 1y, 1w, 1d, 1h, 1m, 1s) (default: 1w)",
|
||||
Required: false,
|
||||
},
|
||||
}, personOptions...)
|
||||
|
||||
bansSubCommands := []*discordgo.ApplicationCommandOption{
|
||||
{
|
||||
Type: discordgo.ApplicationCommandOptionSubCommand,
|
||||
Name: "add",
|
||||
Description: "Ban a player from using this service.",
|
||||
Options: bansOptions,
|
||||
},
|
||||
{
|
||||
Type: discordgo.ApplicationCommandOptionSubCommand,
|
||||
Name: "clear",
|
||||
Description: "Clear all bans from a player.",
|
||||
Options: personOptions,
|
||||
},
|
||||
Handler: banHandler,
|
||||
AdminOnly: true,
|
||||
})
|
||||
{
|
||||
Type: discordgo.ApplicationCommandOptionSubCommand,
|
||||
Name: "list",
|
||||
Description: "List all previous bans from a player.",
|
||||
Options: personOptions,
|
||||
},
|
||||
}
|
||||
|
||||
addCommand(&DiscordCommand{
|
||||
Command: &discordgo.ApplicationCommand{
|
||||
Name: "unban",
|
||||
Description: "Unban a player from using the bot.",
|
||||
Options: personOptions,
|
||||
Name: "bans",
|
||||
Description: "Perform an action on a player's bans.",
|
||||
Options: bansSubCommands,
|
||||
},
|
||||
Handler: unbanHandler,
|
||||
Handler: bansHandler,
|
||||
AdminOnly: true,
|
||||
})
|
||||
|
||||
|
@ -125,38 +151,71 @@ func addCommands() {
|
|||
{
|
||||
Type: discordgo.ApplicationCommandOptionString,
|
||||
Name: "profile",
|
||||
Description: "common_core, athena, common_public, profile0, collections, creative",
|
||||
Description: "The profile to give/take the item from.",
|
||||
Required: true,
|
||||
Choices: []*discordgo.ApplicationCommandOptionChoice{
|
||||
{
|
||||
Name: "Athena",
|
||||
Value: "athena",
|
||||
},
|
||||
{
|
||||
Name: "Common Core",
|
||||
Value: "common_core",
|
||||
},
|
||||
{
|
||||
Name: "Profile0",
|
||||
Value: "profile0",
|
||||
},
|
||||
{
|
||||
Name: "Creative",
|
||||
Value: "creative",
|
||||
},
|
||||
{
|
||||
Name: "Collections",
|
||||
Value: "collections",
|
||||
},
|
||||
{
|
||||
Name: "Common Public",
|
||||
Value: "common_public",
|
||||
},
|
||||
},
|
||||
},
|
||||
}, personOptions...)
|
||||
|
||||
addCommand(&DiscordCommand{
|
||||
Command: &discordgo.ApplicationCommand{
|
||||
Name: "give",
|
||||
grantSubCommands := []*discordgo.ApplicationCommandOption{
|
||||
{
|
||||
Type: discordgo.ApplicationCommandOptionSubCommand,
|
||||
Name: "add",
|
||||
Description: "Grant a player an item in the game.",
|
||||
Options: grantOptions,
|
||||
},
|
||||
Handler: giveItemHandler,
|
||||
AdminOnly: true,
|
||||
})
|
||||
|
||||
addCommand(&DiscordCommand{
|
||||
Command: &discordgo.ApplicationCommand{
|
||||
Name: "take",
|
||||
{
|
||||
Type: discordgo.ApplicationCommandOptionSubCommand,
|
||||
Name: "remove",
|
||||
Description: "Take an item from a player in the game.",
|
||||
Options: grantOptions,
|
||||
},
|
||||
Handler: takeItemHandler,
|
||||
AdminOnly: true,
|
||||
})
|
||||
{
|
||||
Type: discordgo.ApplicationCommandOptionSubCommand,
|
||||
Name: "fill",
|
||||
Description: "Grant a player all items in the game.",
|
||||
Options: personOptions,
|
||||
},
|
||||
{
|
||||
Type: discordgo.ApplicationCommandOptionSubCommand,
|
||||
Name: "clear",
|
||||
Description: "Reset their locker to default.",
|
||||
Options: personOptions,
|
||||
},
|
||||
}
|
||||
|
||||
addCommand(&DiscordCommand{
|
||||
Command: &discordgo.ApplicationCommand{
|
||||
Name: "everything",
|
||||
Description: "Give a player full locker",
|
||||
Options: personOptions,
|
||||
Name: "items",
|
||||
Description: "Perform an action on a player's items.",
|
||||
Options: grantSubCommands,
|
||||
},
|
||||
Handler: giveEverythingHandler,
|
||||
Handler: itemsHandler,
|
||||
AdminOnly: true,
|
||||
})
|
||||
|
||||
|
@ -215,7 +274,7 @@ func addCommands() {
|
|||
{
|
||||
Type: discordgo.ApplicationCommandOptionSubCommand,
|
||||
Name: "remove",
|
||||
Description: "Rake a permission from a player.",
|
||||
Description: "Remove a permission from a player.",
|
||||
Options: permissionOptions,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -14,14 +14,7 @@ import (
|
|||
func GetLightswitchBulkStatus(c *fiber.Ctx) error {
|
||||
person := c.Locals("person").(*person.Person)
|
||||
|
||||
isBanned := false
|
||||
for _, ban := range person.BanHistory {
|
||||
expres := time.Unix(ban.Expiry, 0)
|
||||
if time.Now().Before(expres) {
|
||||
isBanned = true
|
||||
break
|
||||
}
|
||||
}
|
||||
ban := person.GetLatestActiveBan()
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON([]aid.JSON{{
|
||||
"serviceInstanceId": "fortnite",
|
||||
|
@ -29,7 +22,7 @@ func GetLightswitchBulkStatus(c *fiber.Ctx) error {
|
|||
"message": "fortnite is up.",
|
||||
"maintenanceUri": nil,
|
||||
"allowedActions": []string{"PLAY","DOWNLOAD"},
|
||||
"banned": isBanned,
|
||||
"banned": ban != nil && time.Now().Before(ban.Expiry),
|
||||
"launcherInfoDTO": aid.JSON{
|
||||
"appName":"Fortnite",
|
||||
"namespace":"fn",
|
||||
|
|
|
@ -4,18 +4,22 @@ type Permission int64
|
|||
|
||||
// DO NOT MOVE THE ORDER OF THESE PERMISSIONS AS THEY ARE USED IN THE DATABASE
|
||||
const (
|
||||
// random utility permissions
|
||||
PermissionLookup Permission = 1 << iota
|
||||
PermissionBan
|
||||
PermissionInformation
|
||||
|
||||
// control permissions
|
||||
PermissionBansControl
|
||||
PermissionItemControl
|
||||
PermissionLockerControl
|
||||
PermissionPermissionControl
|
||||
|
||||
// user roles, not really permissions but implemented as such
|
||||
PermissionOwner
|
||||
PermissionDonator
|
||||
|
||||
// special permissions
|
||||
PermissionAll = PermissionLookup | PermissionBan | PermissionInformation | PermissionItemControl | PermissionLockerControl | PermissionPermissionControl
|
||||
PermissionAll = PermissionLookup | PermissionBansControl | PermissionInformation | PermissionItemControl | PermissionLockerControl | PermissionPermissionControl
|
||||
PermissionAllWithRoles = PermissionAll | PermissionOwner | PermissionDonator
|
||||
)
|
||||
|
||||
|
@ -36,7 +40,7 @@ func (p Permission) GetName() string {
|
|||
return "Lookup"
|
||||
}
|
||||
|
||||
if p&PermissionBan != 0 {
|
||||
if p&PermissionBansControl != 0 {
|
||||
return "Ban"
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ type Person struct {
|
|||
CollectionsProfile *Profile
|
||||
CreativeProfile *Profile
|
||||
Discord *storage.DB_DiscordPerson
|
||||
BanHistory []storage.DB_BanStatus
|
||||
BanHistory aid.GenericSyncMap[storage.DB_BanStatus]
|
||||
Relationships aid.GenericSyncMap[Relationship]
|
||||
}
|
||||
|
||||
|
@ -188,7 +188,7 @@ func findHelper(databasePerson *storage.DB_Person, shallow bool, save bool) *Per
|
|||
ID: databasePerson.ID,
|
||||
DisplayName: databasePerson.DisplayName,
|
||||
Permissions: Permission(databasePerson.Permissions),
|
||||
BanHistory: databasePerson.BanHistory,
|
||||
BanHistory: aid.GenericSyncMap[storage.DB_BanStatus]{},
|
||||
AthenaProfile: athenaProfile,
|
||||
CommonCoreProfile: commonCoreProfile,
|
||||
CommonPublicProfile: commonPublicProfile,
|
||||
|
@ -200,6 +200,10 @@ func findHelper(databasePerson *storage.DB_Person, shallow bool, save bool) *Per
|
|||
Relationships: aid.GenericSyncMap[Relationship]{},
|
||||
}
|
||||
|
||||
for _, ban := range databasePerson.BanHistory {
|
||||
person.BanHistory.Set(ban.ID, &ban)
|
||||
}
|
||||
|
||||
if !shallow {
|
||||
person.LoadRelationships()
|
||||
}
|
||||
|
@ -262,24 +266,53 @@ func (p *Person) SaveShallow() {
|
|||
storage.Repo.SavePerson(dbPerson)
|
||||
}
|
||||
|
||||
func (p *Person) Ban() {
|
||||
p.BanHistory = append(p.BanHistory, storage.DB_BanStatus{
|
||||
ID: uuid.New().String(),
|
||||
PersonID: p.ID,
|
||||
IssuedBy: "system",
|
||||
Reason: "Banned by system",
|
||||
Expiry: time.Now().AddDate(0, 0, 7).Unix(),
|
||||
})
|
||||
func (p *Person) AddBan(reason string, issuedBy string, expiry ...string) {
|
||||
t := time.Now().AddDate(0, 0, 7)
|
||||
|
||||
p.SaveShallow()
|
||||
}
|
||||
|
||||
func (p *Person) Unban() {
|
||||
for _, ban := range p.BanHistory {
|
||||
ban.Expiry = time.Now().Unix()
|
||||
if len(expiry) > 0 && expiry[0] != "" {
|
||||
parsed, err := aid.ParseDuration(expiry[0])
|
||||
if err == nil {
|
||||
t = time.Now().Add(parsed)
|
||||
aid.Print("Parsed duration for ban expiry:", t.Format("2006-01-02T15:04:05.999Z"))
|
||||
} else {
|
||||
aid.Print("Failed to parse duration for ban expiry:", err)
|
||||
}
|
||||
}
|
||||
|
||||
p.SaveShallow()
|
||||
ban := &storage.DB_BanStatus{
|
||||
ID: uuid.New().String(),
|
||||
PersonID: p.ID,
|
||||
IssuedBy: issuedBy,
|
||||
Reason: reason,
|
||||
Expiry: t,
|
||||
}
|
||||
|
||||
p.BanHistory.Set(ban.ID, ban)
|
||||
storage.Repo.SaveBanStatus(ban)
|
||||
}
|
||||
|
||||
func (p *Person) ClearBans() {
|
||||
p.BanHistory.Range(func(key string, ban *storage.DB_BanStatus) bool {
|
||||
ban.Expiry = time.Now()
|
||||
storage.Repo.SaveBanStatus(ban)
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func (p *Person) GetLatestActiveBan() *storage.DB_BanStatus {
|
||||
var latestBan *storage.DB_BanStatus
|
||||
p.BanHistory.Range(func(key string, ban *storage.DB_BanStatus) bool {
|
||||
if latestBan == nil || ban.Expiry.After(latestBan.Expiry) {
|
||||
latestBan = ban
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
if latestBan != nil && latestBan.Expiry.Before(time.Now()) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return latestBan
|
||||
}
|
||||
|
||||
func (p *Person) AddPermission(permission Permission) {
|
||||
|
@ -305,7 +338,7 @@ func (p *Person) ToDatabase() *storage.DB_Person {
|
|||
ID: p.ID,
|
||||
DisplayName: p.DisplayName,
|
||||
Permissions: int64(p.Permissions),
|
||||
BanHistory: p.BanHistory,
|
||||
BanHistory: []storage.DB_BanStatus{},
|
||||
RefundTickets: p.RefundTickets,
|
||||
Profiles: []storage.DB_Profile{},
|
||||
Stats: []storage.DB_SeasonStat{},
|
||||
|
@ -325,6 +358,11 @@ func (p *Person) ToDatabase() *storage.DB_Person {
|
|||
"creative": p.CreativeProfile,
|
||||
}
|
||||
|
||||
p.BanHistory.Range(func(key string, ban *storage.DB_BanStatus) bool {
|
||||
dbPerson.BanHistory = append(dbPerson.BanHistory, *ban)
|
||||
return true
|
||||
})
|
||||
|
||||
for profileType, profile := range profilesToConvert {
|
||||
dbProfile := storage.DB_Profile{
|
||||
ID: profile.ID,
|
||||
|
@ -374,7 +412,7 @@ func (p *Person) ToDatabaseShallow() *storage.DB_Person {
|
|||
ID: p.ID,
|
||||
DisplayName: p.DisplayName,
|
||||
Permissions: int64(p.Permissions),
|
||||
BanHistory: p.BanHistory,
|
||||
BanHistory: []storage.DB_BanStatus{},
|
||||
RefundTickets: p.RefundTickets,
|
||||
Profiles: []storage.DB_Profile{},
|
||||
Stats: []storage.DB_SeasonStat{},
|
||||
|
@ -385,11 +423,16 @@ func (p *Person) ToDatabaseShallow() *storage.DB_Person {
|
|||
dbPerson.Discord = *p.Discord
|
||||
}
|
||||
|
||||
p.BanHistory.Range(func(key string, ban *storage.DB_BanStatus) bool {
|
||||
dbPerson.BanHistory = append(dbPerson.BanHistory, *ban)
|
||||
return true
|
||||
})
|
||||
|
||||
return &dbPerson
|
||||
}
|
||||
|
||||
func (p *Person) Snapshot() *PersonSnapshot {
|
||||
return &PersonSnapshot{
|
||||
snapshot := &PersonSnapshot{
|
||||
ID: p.ID,
|
||||
DisplayName: p.DisplayName,
|
||||
Permissions: int64(p.Permissions),
|
||||
|
@ -399,9 +442,16 @@ func (p *Person) Snapshot() *PersonSnapshot {
|
|||
Profile0Profile: *p.Profile0Profile.Snapshot(),
|
||||
CollectionsProfile: *p.CollectionsProfile.Snapshot(),
|
||||
CreativeProfile: *p.CreativeProfile.Snapshot(),
|
||||
BanHistory: p.BanHistory,
|
||||
BanHistory: []storage.DB_BanStatus{},
|
||||
Discord: *p.Discord,
|
||||
}
|
||||
|
||||
p.BanHistory.Range(func(key string, ban *storage.DB_BanStatus) bool {
|
||||
snapshot.BanHistory = append(snapshot.BanHistory, *ban)
|
||||
return true
|
||||
})
|
||||
|
||||
return snapshot
|
||||
}
|
||||
|
||||
func (p *Person) Delete() {
|
||||
|
|
|
@ -250,4 +250,12 @@ func (s *PostgresStorage) SaveDiscordPerson(discordPerson *DB_DiscordPerson) {
|
|||
|
||||
func (s *PostgresStorage) DeleteDiscordPerson(discordPersonId string) {
|
||||
s.Postgres.Delete(&DB_DiscordPerson{}, "id = ?", discordPersonId)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) SaveBanStatus(banStatus *DB_BanStatus) {
|
||||
s.Postgres.Save(banStatus)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) DeleteBanStatus(banStatusId string) {
|
||||
s.Postgres.Delete(&DB_BanStatus{}, "id = ?", banStatusId)
|
||||
}
|
|
@ -54,6 +54,9 @@ type Storage interface {
|
|||
|
||||
SaveDiscordPerson(person *DB_DiscordPerson)
|
||||
DeleteDiscordPerson(personId string)
|
||||
|
||||
SaveBanStatus(ban *DB_BanStatus)
|
||||
DeleteBanStatus(banId string)
|
||||
}
|
||||
|
||||
type Repository struct {
|
||||
|
@ -225,4 +228,12 @@ func (r *Repository) SaveDiscordPerson(person *DB_DiscordPerson) {
|
|||
|
||||
func (r *Repository) DeleteDiscordPerson(personId string) {
|
||||
r.Storage.DeleteDiscordPerson(personId)
|
||||
}
|
||||
|
||||
func (r *Repository) SaveBanStatus(ban *DB_BanStatus) {
|
||||
r.Storage.SaveBanStatus(ban)
|
||||
}
|
||||
|
||||
func (r *Repository) DeleteBanStatus(banId string) {
|
||||
r.Storage.DeleteBanStatus(banId)
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
package storage
|
||||
|
||||
import "github.com/lib/pq"
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/lib/pq"
|
||||
)
|
||||
|
||||
type Tabler interface {
|
||||
TableName() string
|
||||
|
@ -210,7 +214,7 @@ type DB_BanStatus struct {
|
|||
ID string `gorm:"primary_key"`
|
||||
PersonID string `gorm:"index"`
|
||||
IssuedBy string
|
||||
Expiry int64
|
||||
Expiry time.Time
|
||||
Reason string
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user