From f9526ba5d4ef506bd82cb44f79ef0b57601453ac Mon Sep 17 00:00:00 2001 From: Fluffy-Bean Date: Fri, 28 Feb 2025 00:27:01 +0000 Subject: [PATCH] Add Ping, Debug and Animal commands --- app/app.go | 92 +++++++++++++++++++++++++++++++++++++++++++++ commands/meta.go | 81 +++++++++++++++++++++++++++++++++++++++ commands/tinyfox.go | 46 +++++++++++++++++++++++ go.mod | 8 ++++ go.sum | 12 ++++++ main.go | 15 +++++++- 6 files changed, 252 insertions(+), 2 deletions(-) create mode 100644 app/app.go create mode 100644 commands/meta.go create mode 100644 commands/tinyfox.go create mode 100644 go.sum diff --git a/app/app.go b/app/app.go new file mode 100644 index 0000000..cd05e6e --- /dev/null +++ b/app/app.go @@ -0,0 +1,92 @@ +package app + +import ( + "fmt" + "os" + "os/signal" + "strings" + "syscall" + + "github.com/bwmarrin/discordgo" +) + +type Config struct { + Token string + Prefix string +} + +type App struct { + Config Config + Commands map[string]func(h *Handler, args []string) +} + +type Handler struct { + Session *discordgo.Session + Message *discordgo.MessageCreate +} + +func NewApp(config Config) *App { + return &App{ + Config: config, + Commands: make(map[string]func(h *Handler, args []string)), + } +} + +func (a *App) RegisterCommand(cmd string, f func(h *Handler, args []string)) { + a.Commands[cmd] = f +} + +func (a *App) Run() { + dg, err := discordgo.New("Bot " + a.Config.Token) + if err != nil { + fmt.Println("error creating Discord session,", err) + + return + } + + dg.AddHandler(func(session *discordgo.Session, message *discordgo.MessageCreate) { + h := &Handler{ + Session: session, + Message: message, + } + + if h.Message.Author.ID == h.Session.State.User.ID { + return + } + + if h.Message.Author.Bot { + return + } + + var command string + var args string + + command = h.Message.Content + command = strings.TrimSpace(command) + command = strings.TrimPrefix(command, a.Config.Prefix) + command, args, _ = strings.Cut(command, " ") + + callback, ok := a.Commands[command] + if !ok { + return + } + + callback(h, strings.Split(args, " ")) + }) + + dg.Identify.Intents = discordgo.IntentsGuildMessages + + err = dg.Open() + if err != nil { + fmt.Println("error opening connection,", err) + + return + } + + fmt.Println("Bot is now running. Press CTRL-C to exit.") + sc := make(chan os.Signal, 1) + signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt) + <-sc + + dg.Close() +} diff --git a/commands/meta.go b/commands/meta.go new file mode 100644 index 0000000..8ca0df6 --- /dev/null +++ b/commands/meta.go @@ -0,0 +1,81 @@ +package commands + +import ( + "flag" + "fmt" + "runtime" + "runtime/debug" + "strings" + "time" + + "github.com/Fluffy-Bean/lynxie/app" +) + +func RegisterMetaCommands(a *app.App) { + a.RegisterCommand("ping", registerPong(a)) + a.RegisterCommand("debug", registerDebug(a)) +} + +func registerPong(a *app.App) func(h *app.Handler, args []string) { + return func(h *app.Handler, args []string) { + var options struct { + latency bool + } + + cmd := flag.NewFlagSet("pong", flag.ContinueOnError) + cmd.BoolVar(&options.latency, "latency", false, "Display the latency of ping") + cmd.Parse(args) + + if options.latency { + h.Session.ChannelMessageSend( + h.Message.ChannelID, + fmt.Sprintf("Pong! %dms", h.Session.HeartbeatLatency().Milliseconds()), + ) + } else { + h.Session.ChannelMessageSend( + h.Message.ChannelID, + "Pong!", + ) + } + } +} + +func registerDebug(a *app.App) func(h *app.Handler, args []string) { + return func(h *app.Handler, args []string) { + modified := false + revision := "-" + tags := "-" + _go := strings.TrimPrefix(runtime.Version(), "go") + gcCount := runtime.MemStats{}.NumGC + localTime := time.Now().Local().Format("2006-01-02 15:04:05") + + info, _ := debug.ReadBuildInfo() + for _, setting := range info.Settings { + switch setting.Key { + case "vcs.revision": + revision = setting.Value + case "vcs.modified": + modified = setting.Value == "true" + case "-tags": + tags = strings.ReplaceAll(setting.Value, ",", " ") + } + } + + if modified { + revision += " (uncommitted changes)" + } + + h.Session.ChannelMessageSend( + h.Message.ChannelID, + fmt.Sprintf( + "``` Revision :: %s\nBuild Tags :: %s\nGo version :: %s\n OS/Arch :: %s\n GC Count :: %d\nLocal Time :: %s```", + revision, + tags, + _go, + runtime.GOOS+"/"+runtime.GOARCH, + gcCount, + localTime, + ), + ) + } +} diff --git a/commands/tinyfox.go b/commands/tinyfox.go new file mode 100644 index 0000000..78dc1af --- /dev/null +++ b/commands/tinyfox.go @@ -0,0 +1,46 @@ +package commands + +import ( + "flag" + "net/http" + "time" + + "github.com/Fluffy-Bean/lynxie/app" +) + +func RegisterTinyfoxCommands(a *app.App) { + a.RegisterCommand("animal", registerAnimal(a)) +} + +func registerAnimal(a *app.App) func(h *app.Handler, args []string) { + client := http.Client{ + Timeout: 10 * time.Second, + } + + return func(h *app.Handler, args []string) { + var options struct { + animal string + } + + cmd := flag.NewFlagSet("pong", flag.ContinueOnError) + cmd.StringVar(&options.animal, "animal", "serval", "Get an image of an animal!") + cmd.Parse(args) + + req, err := http.NewRequest(http.MethodGet, "https://api.tinyfox.dev/img?animal="+options.animal, nil) + if err != nil { + return + } + + res, err := client.Do(req) + if err != nil { + return + } + defer res.Body.Close() + + h.Session.ChannelFileSend( + h.Message.ChannelID, + "animal__"+options.animal+".png", + res.Body, + ) + } +} diff --git a/go.mod b/go.mod index 88fccfe..d6a7bc3 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,11 @@ module github.com/Fluffy-Bean/lynxie go 1.24.0 + +require github.com/bwmarrin/discordgo v0.28.1 + +require ( + github.com/gorilla/websocket v1.4.2 // indirect + golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect + golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e5a04a3 --- /dev/null +++ b/go.sum @@ -0,0 +1,12 @@ +github.com/bwmarrin/discordgo v0.28.1 h1:gXsuo2GBO7NbR6uqmrrBDplPUx2T3nzu775q/Rd1aG4= +github.com/bwmarrin/discordgo v0.28.1/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/main.go b/main.go index 14d62cf..dae9d2e 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,20 @@ package main import ( - "fmt" + "os" + + "github.com/Fluffy-Bean/lynxie/app" + "github.com/Fluffy-Bean/lynxie/commands" ) func main() { - fmt.Println("Lynxie time") + a := app.NewApp(app.Config{ + Token: os.Getenv("TOKEN"), + Prefix: "?", + }) + + commands.RegisterMetaCommands(a) + commands.RegisterTinyfoxCommands(a) + + a.Run() }