Skip to content

Commit

Permalink
Role menu subcommands (#46)
Browse files Browse the repository at this point in the history
* Renamed /create-role-menu to /role-select-menu and broke it into subcommands

* implemented /role-select-menu update add

* implemented /role-select-menu update delete

* Renamed /role-select-menu subcommands

* Improved error message when unable to add role to select menu

* Reorderd response calls

* Bot will now optionally start a pprof server for code profiling.

Added optional pprof config and helper scripts. Large role
management commands run very slowly, so I figured something like
this would be both fun and insightful for seeing where the
slowdown(s) are occuring. I'm sure it won't be the only time I
need to do it either.

* Added handler trace regions

* Fixed a bug where the reset role button would not work for multiple action bars

* Greatly sped up role reset button handler by batching role removal instead of removing them individually

* Greatly sped up the role selection menu interactions by batching role updates instead of doing them one at a time

* update MaxValues when adding or removing a role from the menu

* menu select responses now return added roles instead of all current roles

* Reduced redundant code

* updated docker-compose for v1.9.1
  • Loading branch information
Kardbord authored Jan 4, 2022
1 parent 54596f6 commit cfc3c63
Show file tree
Hide file tree
Showing 13 changed files with 993 additions and 224 deletions.
8 changes: 7 additions & 1 deletion config/setup.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
{
"enable-dg-logging": false,
"default-log-level": "info",
"unregister-all-cmds-on-startup": false
"unregister-all-cmds-on-startup": false,
"pprof": {
"enabled": false,
"address": "localhost:6060",
"block-profile-rate": 0,
"mutex-profile-fraction": 0
}
}
4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
version: "3.9"
services:
kardbot:
image: tkvarfordt/kardbot:v1.9.0
container_name: kardbot-v1.9.0
image: tkvarfordt/kardbot:v1.9.1
container_name: kardbot-v1.9.1
volumes:
- ./config:/app/config
- ./assets/pasta:/app/assets/pasta
Expand Down
29 changes: 15 additions & 14 deletions kardbot/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const (
maxDiscordOptionChoices = 25
maxDiscordSelectMenuOpts = 25
maxDiscordActionRows = 5
minDiscordSelectMenuOpts = 2 // discord requires at least this many options per SelectMenu
)

func getCommands() []*discordgo.ApplicationCommand {
Expand Down Expand Up @@ -323,7 +324,7 @@ func getCommands() []*discordgo.ApplicationCommand {
},
},
{
Name: createRoleSelectCommand,
Name: roleSelectMenuCommand,
Description: "Allow users to select roles for themselves",
Options: roleSelectCmdOpts(),
},
Expand All @@ -342,19 +343,19 @@ func getCommands() []*discordgo.ApplicationCommand {

func getCommandImpls() map[string]onInteractionHandler {
return map[string]onInteractionHandler{
RollCmd: roll,
"loglevel": updateLogLevel,
"pasta": servePasta,
"reddit-roulette": redditRoulette,
"uwu": uwuify,
"compliments": complimentHandler,
"creepy-dms": creepyDMHandler,
"help": botInfo,
"what-are-the-odds": whatAreTheOdds,
memeCommand: buildAMeme,
delBotDMCmd: deleteBotDMs,
storyTimeCmd: storyTime,
createRoleSelectCommand: createRoleSelect,
RollCmd: roll,
"loglevel": updateLogLevel,
"pasta": servePasta,
"reddit-roulette": redditRoulette,
"uwu": uwuify,
"compliments": complimentHandler,
"creepy-dms": creepyDMHandler,
"help": botInfo,
"what-are-the-odds": whatAreTheOdds,
memeCommand: buildAMeme,
delBotDMCmd: deleteBotDMs,
storyTimeCmd: storyTime,
roleSelectMenuCommand: handleRoleSelectMenuCommand,
}
}

Expand Down
73 changes: 48 additions & 25 deletions kardbot/kardbot.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package kardbot

import (
"context"
"encoding/json"
"errors"
"fmt"
"math/rand"
"os"
"os/signal"
"runtime/debug"
"runtime/trace"
"sync"
"syscall"
"time"
Expand Down Expand Up @@ -35,6 +36,9 @@ type kardbot struct {
EnableDGLogging bool `json:"enable-dg-logging"`
UnregisterAllCmdsOnStartup bool `json:"unregister-all-cmds-on-startup"`

// Enable trace regions for profiling
TraceEnabled bool

// Initialized in kardbot.Run, used to determine when
// kardbot.Stop has been called.
wg *sync.WaitGroup
Expand All @@ -55,18 +59,28 @@ func bot() *kardbot {
}

// Run initializes and starts the bot.
// Returns a WaitGroup
func Run() {
// Setting traceEnabled to true enables
// trace regions for profiling.
func Run(traceEnabled bool) {
if gbot != nil {
log.Warn("Run has already been called")
return
}

if traceEnabled {
log.Info("Bot will run with trace regions enabled")
} else {
log.Info("Bot will run with trace regions disabled (this is normal)")
}

log.RegisterExitHandler(Stop)

wg := sync.WaitGroup{}
wg.Add(1)
gbot = &kardbot{wg: &wg}
gbot = &kardbot{
wg: &wg,
TraceEnabled: traceEnabled,
}
go handleInterrupt()
gbot.initialize()
log.Print("Bot is now running. Press CTRL-C to exit.")
Expand All @@ -76,8 +90,8 @@ func Block() {
bot().wg.Wait()
}

func RunAndBlock() {
Run()
func RunAndBlock(traceEnabled bool) {
Run(traceEnabled)
Block()
}

Expand Down Expand Up @@ -229,33 +243,42 @@ func (kbot *kardbot) prepInteractionHandlers() {
}
}()

var handler func(*discordgo.Session, *discordgo.InteractionCreate) = nil
command := "unknown interaction type"
switch i.Type {
case discordgo.InteractionApplicationCommand:
cmd := i.ApplicationCommandData().Name
if strMatchesMemeCmdPattern(cmd) {
cmd = memeCommand
command = i.ApplicationCommandData().Name
if strMatchesMemeCmdPattern(command) {
command = memeCommand
}
if h, ok := getCommandImpls()[cmd]; ok {
h(s, i)
} else {
errStr := fmt.Sprintf("Unknown command received: %s", i.ApplicationCommandData().Name)
log.Error(errStr)
interactionRespondEphemeralError(s, i, true, errors.New(errStr))
if h, ok := getCommandImpls()[command]; ok {
handler = h
}

case discordgo.InteractionMessageComponent:
buttonID := i.MessageComponentData().CustomID
if strMatchesRoleSelectMenuID(buttonID) {
buttonID = roleSelectMenuComponentIDPrefix
command = i.MessageComponentData().CustomID
if strMatchesRoleSelectMenuID(command) {
command = roleSelectMenuComponentIDPrefix
}
if h, ok := getComponentImpls()[buttonID]; ok {
h(s, i)
} else {
log.Errorf(`unknown message component ID "%s"`, i.MessageComponentData().CustomID)
if h, ok := getComponentImpls()[command]; ok {
handler = h
}
}

if handler == nil {
err := fmt.Errorf("interaction failed: %s", command)
log.Error(err)
interactionRespondEphemeralError(s, i, true, err)
return
}

default:
log.Errorf("Unknown interaction type received: %s", i.Type.String())
if kbot.TraceEnabled {
ctx, task := trace.NewTask(context.Background(), command)
defer task.End()
r := trace.StartRegion(ctx, command)
handler(s, i)
r.End()
} else {
handler(s, i)
}
})
}
Expand Down
Loading

0 comments on commit cfc3c63

Please sign in to comment.