diff --git a/main.go b/main.go index 2182e05..bce1ad8 100644 --- a/main.go +++ b/main.go @@ -35,8 +35,9 @@ func main() { h := handler.New() h.Command("/ping", commands.PingHandler) + h.Command("/sync", commands.SyncHandler) - if err = b.SetupBot(h, bot.NewListenerFunc(b.OnReady) /*handlers.MessageHandler(b)*/); err != nil { + if err = b.SetupBot(h, bot.NewListenerFunc(b.OnReady)); err != nil { slog.Error("Failed to setup bot", slog.Any("err", err)) os.Exit(-1) } diff --git a/relay/bot.go b/relay/bot.go index b050884..ec22657 100644 --- a/relay/bot.go +++ b/relay/bot.go @@ -2,6 +2,8 @@ package relay import ( "context" + "homestead/homestead_to_go/relay/commands" + "log" "log/slog" "time" @@ -21,12 +23,40 @@ func New(cfg Config) *Bot { } } +func onMessageCreate(event *events.MessageCreate) { + // Ignore bot messages + if event.Message.Author.Bot { + return + } + + // Check if channel is registered + if !commands.ChannelStore.IsRegistered(event.Message.ChannelID) { + return + } + + // Log the message + log.Printf("[%s] %s#%s: %s", + event.Message.ChannelID, + event.Message.Author.Username, + event.Message.Author.Discriminator, + event.Message.Content, + ) + + // You can also log attachments, embeds, etc. + if len(event.Message.Attachments) > 0 { + log.Printf(" └─ Attachments: %d", len(event.Message.Attachments)) + } +} + func (b *Bot) SetupBot(listeners ...bot.EventListener) error { client, err := disgo.New(b.Cfg.Bot.Token, bot.WithGatewayConfigOpts(gateway.WithIntents(gateway.IntentGuilds, gateway.IntentGuildMessages, gateway.IntentMessageContent)), bot.WithCacheConfigOpts(cache.WithCaches(cache.FlagGuilds)), bot.WithEventListeners(b.Paginator), bot.WithEventListeners(listeners...), + bot.WithEventListeners(&events.ListenerAdapter{ + OnMessageCreate: onMessageCreate, + }), ) if err != nil { return err diff --git a/relay/commands/commands.go b/relay/commands/commands.go index 9db3d43..1cad6a1 100644 --- a/relay/commands/commands.go +++ b/relay/commands/commands.go @@ -1,6 +1,9 @@ package commands -import "github.com/disgoorg/disgo/discord" +import ( + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/json" +) func getPingCommand() discord.SlashCommandCreate { return discord.SlashCommandCreate{ @@ -9,6 +12,41 @@ func getPingCommand() discord.SlashCommandCreate { } } +func getSyncCommand() discord.SlashCommandCreate { + perms := json.NewNullable(discord.PermissionManageChannels) + + return discord.SlashCommandCreate{ + Name: "sync", + Description: "Register/remove a channel to sync.", + DefaultMemberPermissions: &perms, + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionSubCommand{ + Name: "register", + Description: "Register a channel for logging", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionChannel{ + Name: "channel", + Description: "Channel to register", + Required: true, + }, + }, + }, + discord.ApplicationCommandOptionSubCommand{ + Name: "remove", + Description: "Remove a channel from logging", + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionChannel{ + Name: "channel", + Description: "Channel to remove", + Required: true, + }, + }, + }, + }, + } +} + var Commands = []discord.ApplicationCommandCreate{ getPingCommand(), + getSyncCommand(), } diff --git a/relay/commands/ping.go b/relay/commands/ping.go index 9f954f8..1ce529a 100644 --- a/relay/commands/ping.go +++ b/relay/commands/ping.go @@ -26,10 +26,10 @@ func PingHandler(e *handler.CommandEvent) error { } lat := float64(msLatency) - if lat > 5000 { - lat = 5000 + if lat > 1500 { + lat = 1500 } - red := int((lat / 5000) * 255) + red := int((lat / 1500) * 255) green := 255 - red color := (red << 16) | (green << 8) @@ -40,8 +40,9 @@ func PingHandler(e *handler.CommandEvent) error { SetColor(color). Build() - return e.CreateMessage(discord.NewMessageCreateBuilder(). - SetEmbeds(embed). - Build(), + return e.CreateMessage( + discord.NewMessageCreateBuilder(). + SetEmbeds(embed). + Build(), ) } diff --git a/relay/commands/sync.go b/relay/commands/sync.go new file mode 100644 index 0000000..881d2d3 --- /dev/null +++ b/relay/commands/sync.go @@ -0,0 +1,74 @@ +package commands + +import ( + "fmt" + "homestead/homestead_to_go/relay/storage" + "log" + + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/handler" +) + +var ChannelStore *storage.ChannelStorage + +func InitStorage() error { + var err error + ChannelStore, err = storage.NewChannelStorage("registered_channels.json") + return err +} + +func SyncHandler(e *handler.CommandEvent) error { + data := e.SlashCommandInteractionData() + + subcommand := data.SubCommandName + if subcommand == nil { + return e.CreateMessage(discord.MessageCreate{ + Content: "Invalid subcommand!", + Flags: discord.MessageFlagEphemeral, + }) + } + + channelID, ok := data.OptSnowflake("channel") + if !ok { + return e.CreateMessage(discord.MessageCreate{ + Content: "Channel not provided!", + Flags: discord.MessageFlagEphemeral, + }) + } + + switch *subcommand { + case "register": + if err := ChannelStore.AddChannel(channelID); err != nil { + log.Printf("Error registering channel: %v", err) + return e.CreateMessage(discord.MessageCreate{ + Content: "❌ Failed to register channel!", + Flags: discord.MessageFlagEphemeral, + }) + } + + return e.CreateMessage(discord.MessageCreate{ + Content: fmt.Sprintf("✅ Registered <#%s> for message logging!", channelID), + Flags: discord.MessageFlagEphemeral, + }) + + case "remove": + if err := ChannelStore.RemoveChannel(channelID); err != nil { + log.Printf("Error removing channel: %v", err) + return e.CreateMessage(discord.MessageCreate{ + Content: "❌ Failed to remove channel!", + Flags: discord.MessageFlagEphemeral, + }) + } + + return e.CreateMessage(discord.MessageCreate{ + Content: fmt.Sprintf("✅ Removed <#%s> from message logging!", channelID), + Flags: discord.MessageFlagEphemeral, + }) + + default: + return e.CreateMessage(discord.MessageCreate{ + Content: "Unknown subcommand!", + Flags: discord.MessageFlagEphemeral, + }) + } +} diff --git a/relay/storage/storage.go b/relay/storage/storage.go new file mode 100644 index 0000000..6f0f6fc --- /dev/null +++ b/relay/storage/storage.go @@ -0,0 +1,80 @@ +package storage + +import ( + "encoding/json" + "os" + + "github.com/disgoorg/snowflake/v2" +) + +func NewChannelStorage(filename string) (*ChannelStorage, error) { + storage := &ChannelStorage{ + filename: filename, + Channels: make(map[snowflake.ID]bool), + } + + if err := storage.Load(); err != nil && !os.IsNotExist(err) { + return nil, err + } + + return storage, nil +} + +func (s *ChannelStorage) Load() error { + s.mutex.Lock() + defer s.mutex.Unlock() + + data, err := os.ReadFile(s.filename) + if err != nil { + return err + } + + return json.Unmarshal(data, s) +} + +func (s *ChannelStorage) Save() error { + s.mutex.Lock() + defer s.mutex.Unlock() + + data, err := json.MarshalIndent(s, "", " ") + if err != nil { + return err + } + + return os.WriteFile(s.filename, data, 0644) +} + +func (s *ChannelStorage) AddChannel(channelID snowflake.ID) error { + s.mutex.Lock() + s.Channels[channelID] = true + s.mutex.Unlock() + + return s.Save() +} + +func (s *ChannelStorage) RemoveChannel(channelID snowflake.ID) error { + s.mutex.Lock() + delete(s.Channels, channelID) + s.mutex.Unlock() + + return s.Save() +} + +func (s *ChannelStorage) IsRegistered(channelID snowflake.ID) bool { + s.mutex.RLock() + defer s.mutex.RUnlock() + + return s.Channels[channelID] +} + +func (s *ChannelStorage) GetAll() []snowflake.ID { + s.mutex.RLock() + defer s.mutex.RUnlock() + + channels := make([]snowflake.ID, 0, len(s.Channels)) + for channelID := range s.Channels { + channels = append(channels, channelID) + } + + return channels +} diff --git a/relay/storage/structs.go b/relay/storage/structs.go new file mode 100644 index 0000000..6d5fc7f --- /dev/null +++ b/relay/storage/structs.go @@ -0,0 +1,13 @@ +package storage + +import ( + "sync" + + "github.com/disgoorg/snowflake/v2" +) + +type ChannelStorage struct { + mutex sync.RWMutex + filename string + Channels map[snowflake.ID]bool `json:"channels"` +}