diff --git a/bot/commands/coin.go b/bot/commands/coin.go new file mode 100644 index 0000000..a9bcb2f --- /dev/null +++ b/bot/commands/coin.go @@ -0,0 +1,29 @@ +package commands + +import ( + "git.kill0.net/chill9/beepboop/bot" + "git.kill0.net/chill9/beepboop/lib" +) + +type Coin bool + +func (c *Coin) Flip() bool { + *c = Coin(lib.Itob(lib.RandInt(0, 1))) + return bool(*c) +} + +func CoinCommand(cmd *bot.Command, args []string) error { + var ( + c Coin + msg string + ) + + if c.Flip() { + msg = "heads" + } else { + msg = "tails" + } + + cmd.Session.ChannelMessageSend(cmd.Message.ChannelID, msg) + return nil +} diff --git a/bot/handler/deal.go b/bot/commands/deal.go similarity index 66% rename from bot/handler/deal.go rename to bot/commands/deal.go index 4bef4eb..503534b 100644 --- a/bot/handler/deal.go +++ b/bot/commands/deal.go @@ -1,4 +1,4 @@ -package handler +package commands import ( "errors" @@ -8,8 +8,6 @@ import ( "strings" "git.kill0.net/chill9/beepboop/bot" - "git.kill0.net/chill9/beepboop/lib" - "github.com/bwmarrin/discordgo" log "github.com/sirupsen/logrus" ) @@ -52,36 +50,16 @@ func (d *Deck) Deal(n int) ([]Card, error) { return hand, err } -func NewDealHandler(s string) *DealHandler { - h := new(DealHandler) - h.Name = s - return h -} - -func (h *DealHandler) SetConfig(config bot.Config) { - h.config = config -} - -func (h *DealHandler) Handle(s *discordgo.Session, m *discordgo.MessageCreate) { - if m.Author.ID == s.State.User.ID { - return - } - - if !lib.ContainsCommand(m.Content, h.config.Prefix, h.Name) { - return - } - +func DealCommand(cmd *bot.Command, args []string) error { rand.Shuffle(len(deck), func(i, j int) { deck[i], deck[j] = deck[j], deck[i] }) log.Debugf("%+v", deck) - _, args := lib.SplitCommandAndArgs(m.Content, h.config.Prefix) - if len(args) != 1 { - s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("help: `!%s `", h.Name)) - return + cmd.Session.ChannelMessageSend(cmd.Message.ChannelID, fmt.Sprintf("help: `!%s `", cmd.Name)) + return nil } n, err := strconv.Atoi(args[0]) @@ -91,11 +69,12 @@ func (h *DealHandler) Handle(s *discordgo.Session, m *discordgo.MessageCreate) { hand, err := deck.Deal(n) if err != nil { - s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("error: %s\n", err)) - return + cmd.Session.ChannelMessageSend(cmd.Message.ChannelID, fmt.Sprintf("error: %s\n", err)) + return nil } - s.ChannelMessageSend(m.ChannelID, JoinCards(hand, " ")) + cmd.Session.ChannelMessageSend(cmd.Message.ChannelID, JoinCards(hand, " ")) + return nil } func JoinCards(h []Card, sep string) string { diff --git a/bot/handler/dice.go b/bot/commands/dice.go similarity index 66% rename from bot/handler/dice.go rename to bot/commands/dice.go index a10aaf2..79af4e7 100644 --- a/bot/handler/dice.go +++ b/bot/commands/dice.go @@ -1,4 +1,4 @@ -package handler +package commands import ( "errors" @@ -9,7 +9,6 @@ import ( "git.kill0.net/chill9/beepboop/bot" "git.kill0.net/chill9/beepboop/lib" - "github.com/bwmarrin/discordgo" log "github.com/sirupsen/logrus" ) @@ -25,11 +24,6 @@ type ( Rolls []int S string } - - RollHandler struct { - config bot.Config - Name string - } ) func NewRoll(n, d int) *Roll { @@ -84,42 +78,19 @@ func (r *Roll) RollDice() { } } -func NewRollHandler(s string) *RollHandler { - return &RollHandler{Name: s} -} - -func (h *RollHandler) SetConfig(config bot.Config) { - h.config = config -} - -func (h *RollHandler) Handle(s *discordgo.Session, m *discordgo.MessageCreate) { +func RollCommand(cmd *bot.Command, args []string) error { var ( err error msg, roll string r *Roll ) - if m.Author.ID == s.State.User.ID { - return - } - - if !lib.ContainsCommand(m.Content, h.config.Prefix, h.Name) { - return - } - - x := strings.Split(m.Content, " ") - - if len(x) != 2 { - s.ChannelMessageSend(m.ChannelID, "help: `!roll d`") - return - } - - roll = x[1] + roll = args[0] r, err = ParseRoll(roll) if err != nil { - s.ChannelMessageSend(m.ChannelID, err.Error()) - return + cmd.Session.ChannelMessageSend(cmd.Message.ChannelID, err.Error()) + return nil } r.RollDice() @@ -127,5 +98,6 @@ func (h *RollHandler) Handle(s *discordgo.Session, m *discordgo.MessageCreate) { msg = fmt.Sprintf("🎲 %s = %d", lib.JoinInt(r.Rolls, " + "), r.Sum) - s.ChannelMessageSend(m.ChannelID, msg) + cmd.Session.ChannelMessageSend(cmd.Message.ChannelID, msg) + return nil } diff --git a/bot/commands/ping.go b/bot/commands/ping.go new file mode 100644 index 0000000..c0aaf8c --- /dev/null +++ b/bot/commands/ping.go @@ -0,0 +1,10 @@ +package commands + +import ( + "git.kill0.net/chill9/beepboop/bot" +) + +func PingCommand(cmd *bot.Command, args []string) error { + cmd.Session.ChannelMessageSend(cmd.Message.ChannelID, "pong") + return nil +} diff --git a/bot/handler/roulette.go b/bot/commands/roulette.go similarity index 60% rename from bot/handler/roulette.go rename to bot/commands/roulette.go index cdfafde..c4ab9cc 100644 --- a/bot/handler/roulette.go +++ b/bot/commands/roulette.go @@ -1,11 +1,8 @@ -package handler +package commands import ( - "strings" - "git.kill0.net/chill9/beepboop/bot" "git.kill0.net/chill9/beepboop/lib" - "github.com/bwmarrin/discordgo" log "github.com/sirupsen/logrus" ) @@ -21,11 +18,6 @@ type ( C [6]bool N int } - - RouletteHandler struct { - config bot.Config - Name string - } ) var ( @@ -74,23 +66,7 @@ func (g *Gun) IsEmpty() bool { return true } -func NewRouletteHandler(s string) *RouletteHandler { - return &RouletteHandler{Name: s} -} - -func (h *RouletteHandler) SetConfig(config bot.Config) { - h.config = config -} - -func (h *RouletteHandler) Handle(s *discordgo.Session, m *discordgo.MessageCreate) { - if m.Author.ID == s.State.User.ID { - return - } - - if !strings.HasPrefix(m.Content, "!roulette") { - return - } - +func RouletteCommand(cmd *bot.Command, args []string) error { if gun.IsEmpty() { gun.Load(Bullets) log.Debugf("reloading gun: %+v\n", gun) @@ -98,8 +74,9 @@ func (h *RouletteHandler) Handle(s *discordgo.Session, m *discordgo.MessageCreat log.Debugf("firing gun: %+v\n", gun) if gun.Fire() { - s.ChannelMessageSend(m.ChannelID, GunFireMessage) + cmd.Session.ChannelMessageSend(cmd.Message.ChannelID, GunFireMessage) } else { - s.ChannelMessageSend(m.ChannelID, GunClickMessage) + cmd.Session.ChannelMessageSend(cmd.Message.ChannelID, GunClickMessage) } + return nil } diff --git a/bot/commands/time.go b/bot/commands/time.go new file mode 100644 index 0000000..e51d8be --- /dev/null +++ b/bot/commands/time.go @@ -0,0 +1,34 @@ +package commands + +import ( + "fmt" + "time" + + "git.kill0.net/chill9/beepboop/bot" + log "github.com/sirupsen/logrus" +) + +func TimeCommand(cmd *bot.Command, args []string) error { + var ( + t time.Time + tz string + ) + + now := time.Now() + + if len(args) == 1 { + tz = args[0] + loc, err := time.LoadLocation(tz) + if err != nil { + log.Warnf("failed to load location: %s", err) + cmd.Session.ChannelMessageSend(cmd.Message.ChannelID, err.Error()) + return nil + } + t = now.In(loc) + } else { + t = now + } + + cmd.Session.ChannelMessageSend(cmd.Message.ChannelID, fmt.Sprint(t)) + return nil +} diff --git a/bot/commands/version.go b/bot/commands/version.go new file mode 100644 index 0000000..70c81fb --- /dev/null +++ b/bot/commands/version.go @@ -0,0 +1,23 @@ +package commands + +import ( + "fmt" + "runtime" + + "git.kill0.net/chill9/beepboop/bot" +) + +const ( + SourceURI = "https://git.kill0.net/chill9/bb" +) + +func VersionCommand(cmd *bot.Command, args []string) error { + cmd.Session.ChannelMessageSend(cmd.Message.ChannelID, fmt.Sprintf( + "go version: %s\nplatform: %s\nos: %s\nsource: %s\n", + runtime.Version(), + runtime.GOARCH, + runtime.GOOS, + SourceURI, + )) + return nil +} diff --git a/bot/handler/weather.go b/bot/commands/weather.go similarity index 59% rename from bot/handler/weather.go rename to bot/commands/weather.go index 2b5b510..72ce022 100644 --- a/bot/handler/weather.go +++ b/bot/commands/weather.go @@ -1,12 +1,10 @@ -package handler +package commands import ( "fmt" - "strings" "git.kill0.net/chill9/beepboop/bot" "git.kill0.net/chill9/beepboop/lib/weather" - "github.com/bwmarrin/discordgo" log "github.com/sirupsen/logrus" ) @@ -24,48 +22,38 @@ func (h *WeatherHandler) SetConfig(config bot.Config) { h.Config = config } -func (h *WeatherHandler) Handle(s *discordgo.Session, m *discordgo.MessageCreate) { +func WeatherCommand(cmd *bot.Command, args []string) error { var ( err error loc string w weather.Weather ) - if m.Author.ID == s.State.User.ID { - return + if len(args) != 1 { + cmd.Session.ChannelMessageSend(cmd.Message.ChannelID, "help: `!weather ,,`") + return nil } - if !strings.HasPrefix(m.Content, "!weather") { - return - } + loc = args[0] - x := strings.SplitN(m.Content, " ", 2) - - if len(x) != 2 { - s.ChannelMessageSend(m.ChannelID, "help: `!weather ,,`") - return - } - - loc = x[1] - - if h.Config.OpenWeatherMapToken == "" { + if cmd.Config.OpenWeatherMapToken == "" { log.Error("OpenWeather token is not set") - return + return nil } - wc := weather.NewClient(h.Config.OpenWeatherMapToken) + wc := weather.NewClient(cmd.Config.OpenWeatherMapToken) log.Debugf("weather requested for '%s'", loc) w, err = wc.Get(loc) if err != nil { log.Errorf("weather client error: %v", err) - return + return nil } log.Debugf("weather returned for '%s': %+v", loc, w) - s.ChannelMessageSend(m.ChannelID, fmt.Sprintf( + cmd.Session.ChannelMessageSend(cmd.Message.ChannelID, fmt.Sprintf( "%s (%.1f, %.1f) — C:%.1f F:%.1f K:%.1f", loc, w.Coord.Lat, @@ -74,4 +62,6 @@ func (h *WeatherHandler) Handle(s *discordgo.Session, m *discordgo.MessageCreate w.Main.Temp.Fahrenheit(), w.Main.Temp.Kelvin(), )) + + return nil } diff --git a/bot/handler/coin.go b/bot/handler/coin.go deleted file mode 100644 index d5557b3..0000000 --- a/bot/handler/coin.go +++ /dev/null @@ -1,52 +0,0 @@ -package handler - -import ( - "git.kill0.net/chill9/beepboop/bot" - "git.kill0.net/chill9/beepboop/lib" - "github.com/bwmarrin/discordgo" -) - -type ( - Coin bool - - CoinHandler struct { - config bot.Config - Name string - } -) - -func (c *Coin) Flip() bool { - *c = Coin(lib.Itob(lib.RandInt(0, 1))) - return bool(*c) -} - -func NewCoinHandler(s string) *CoinHandler { - return &CoinHandler{Name: s} -} - -func (h *CoinHandler) SetConfig(config bot.Config) { - h.config = config -} - -func (h *CoinHandler) Handle(s *discordgo.Session, m *discordgo.MessageCreate) { - var ( - c Coin - msg string - ) - - if m.Author.ID == s.State.User.ID { - return - } - - if !lib.ContainsCommand(m.Content, h.config.Prefix, h.Name) { - return - } - - if c.Flip() { - msg = "heads" - } else { - msg = "tails" - } - - s.ChannelMessageSend(m.ChannelID, msg) -} diff --git a/bot/handler/ping.go b/bot/handler/ping.go deleted file mode 100644 index 84ff829..0000000 --- a/bot/handler/ping.go +++ /dev/null @@ -1,37 +0,0 @@ -package handler - -import ( - "git.kill0.net/chill9/beepboop/bot" - "git.kill0.net/chill9/beepboop/lib" - "github.com/bwmarrin/discordgo" - log "github.com/sirupsen/logrus" -) - -type ( - PingHandler struct { - config bot.Config - Name string - } -) - -func NewPingHandler(s string) *PingHandler { - return &PingHandler{Name: s} -} - -func (h *PingHandler) SetConfig(config bot.Config) { - h.config = config -} - -func (h *PingHandler) Handle(s *discordgo.Session, m *discordgo.MessageCreate) { - if m.Author.ID == s.State.User.ID { - return - } - - if !lib.ContainsCommand(m.Content, h.config.Prefix, h.Name) { - return - } - - log.Debug("received ping") - - s.ChannelMessageSend(m.ChannelID, "pong") -} diff --git a/bot/handler/time.go b/bot/handler/time.go deleted file mode 100644 index 3b3fe85..0000000 --- a/bot/handler/time.go +++ /dev/null @@ -1,65 +0,0 @@ -package handler - -import ( - "fmt" - "strings" - "time" - - "git.kill0.net/chill9/beepboop/bot" - "github.com/bwmarrin/discordgo" - log "github.com/sirupsen/logrus" -) - -type ( - TimeHandler struct { - config bot.Config - Name string - } -) - -func NewTimeHandler(s string) *TimeHandler { - return &TimeHandler{Name: s} -} - -func (h *TimeHandler) SetConfig(config bot.Config) { - h.config = config -} - -func (h *TimeHandler) Handle(s *discordgo.Session, m *discordgo.MessageCreate) { - var ( - t time.Time - tz string - ) - - if m.Author.ID == s.State.User.ID { - return - } - - if !strings.HasPrefix(m.Content, "!time") { - return - } - - x := strings.SplitN(m.Content, " ", 2) - - if len(x) > 2 { - s.ChannelMessageSend(m.ChannelID, "help: `!time TIMEZONE`") - return - } - - now := time.Now() - - if len(x) == 2 { - tz = x[1] - loc, err := time.LoadLocation(tz) - if err != nil { - log.Warnf("failed to load location: %s", err) - s.ChannelMessageSend(m.ChannelID, err.Error()) - return - } - t = now.In(loc) - } else { - t = now - } - - s.ChannelMessageSend(m.ChannelID, fmt.Sprint(t)) -} diff --git a/bot/handler/version.go b/bot/handler/version.go deleted file mode 100644 index 4f07727..0000000 --- a/bot/handler/version.go +++ /dev/null @@ -1,47 +0,0 @@ -package handler - -import ( - "fmt" - "runtime" - - "git.kill0.net/chill9/beepboop/bot" - "git.kill0.net/chill9/beepboop/lib" - "github.com/bwmarrin/discordgo" -) - -const ( - SourceURI = "https://git.kill0.net/chill9/bb" -) - -type ( - VersionHandler struct { - config bot.Config - Name string - } -) - -func NewVersionHandler(s string) *VersionHandler { - return &VersionHandler{Name: s} -} - -func (h *VersionHandler) SetConfig(config bot.Config) { - h.config = config -} - -func (h *VersionHandler) Handle(s *discordgo.Session, m *discordgo.MessageCreate) { - if m.Author.ID == s.State.User.ID { - return - } - - if !lib.ContainsCommand(m.Content, h.config.Prefix, h.Name) { - return - } - - s.ChannelMessageSend(m.ChannelID, fmt.Sprintf( - "go version: %s\nplatform: %s\nos: %s\nsource: %s\n", - runtime.Version(), - runtime.GOARCH, - runtime.GOOS, - SourceURI, - )) -} diff --git a/cmd/bb/main.go b/cmd/bb/main.go index 8fbf3ba..d645bf3 100644 --- a/cmd/bb/main.go +++ b/cmd/bb/main.go @@ -11,6 +11,7 @@ import ( "syscall" "git.kill0.net/chill9/beepboop/bot" + "git.kill0.net/chill9/beepboop/bot/commands" "git.kill0.net/chill9/beepboop/bot/handler" "git.kill0.net/chill9/beepboop/lib" @@ -24,18 +25,41 @@ var ( C bot.Config handlers []bot.MessageCreateHandler = []bot.MessageCreateHandler{ - handler.NewCoinHandler("coin"), - handler.NewPingHandler("ping"), - handler.NewRollHandler("roll"), - handler.NewRouletteHandler("roulette"), - handler.NewTimeHandler("time"), - handler.NewVersionHandler("version"), - handler.NewWeatherHandler("weather"), handler.NewReactionHandler(), - handler.NewDealHandler("deal"), } ) +func init() { + bot.AddCommand(&bot.Command{ + Name: "coin", + Func: commands.CoinCommand, + }) + bot.AddCommand(&bot.Command{ + Name: "deal", + Func: commands.DealCommand, + }) + bot.AddCommand(&bot.Command{ + Name: "ping", + Func: commands.PingCommand, + }) + bot.AddCommand(&bot.Command{ + Name: "roll", + Func: commands.RollCommand, + }) + bot.AddCommand(&bot.Command{ + Name: "time", + Func: commands.TimeCommand, + }) + bot.AddCommand(&bot.Command{ + Name: "version", + Func: commands.VersionCommand, + }) + bot.AddCommand(&bot.Command{ + Name: "weather", + Func: commands.WeatherCommand, + }) +} + func main() { setupConfig()