From 8bbe63dafb1a52ca00fe746ed781c7f500711651 Mon Sep 17 00:00:00 2001 From: AK Date: Sat, 1 Aug 2026 15:27:47 -0700 Subject: [PATCH] fix: separate magic 8-ball from pool --- docs/games.md | 12 +++++++++--- docs/plugins.md | 3 +++ plugins/pool.go | 16 ++++++++-------- plugins/pool_test.go | 8 +++++++- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/docs/games.md b/docs/games.md index 9538635..65267a7 100644 --- a/docs/games.md +++ b/docs/games.md @@ -50,12 +50,17 @@ or real-money mechanics. Challenge another nickname and have them accept: ~~~text -!8ball Alex -!9ball Alex +!pool 8 Alex +!pool 9 Alex !pool accept !pool decline ~~~ +Pool commands are intentionally separate from the magic 8-ball plugin. Use +`!pool 8 `, `!pool8 `, or `!8pool ` for 8-ball pool. Use +`!pool 9 `, `!pool9 `, or `!9ball ` for 9-ball. Use +`!8ball `, `!8`, or `!eightball` for a magic 8-ball answer. + During a game, the player whose turn it is shoots one numbered ball: ~~~text @@ -70,7 +75,8 @@ legal only after the player's assigned group is cleared. In 9-ball, the lowest remaining ball must be selected first; pocketing the 9-ball wins. A successful shot keeps the turn, while a miss passes it to the other player. -Aliases include `!8`, `!9ball`, `!9`, `!pool break`, and `!shoot `. +Aliases include `!pool8`, `!8pool`, `!pool9`, `!9ball`, `!9`, `!pool break`, +and `!shoot `. The invited player can use `!pool decline` if they do not want to play. Use `!poolstats [nick]` for persistent wins and losses or `!poolleaderboard` for the top five players. Active games are held in memory diff --git a/docs/plugins.md b/docs/plugins.md index 0f2d8e9..5ade627 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -555,6 +555,9 @@ Responses come from quotes/eightball.txt, one per line. Prefix a response with green|, yellow|, or red| to control its IRC color. Unprefixed responses remain readable without color. Each request produces one bounded message. +Pool's separate 8-ball mode uses `!pool 8 `, `!pool8 `, or +`!8pool `; `!8ball` is reserved for questions to the magic 8-ball. + ## Fun text catalogs The `fun` plugin provides local text without making an external request. Each diff --git a/plugins/pool.go b/plugins/pool.go index 839818a..7d593d4 100644 --- a/plugins/pool.go +++ b/plugins/pool.go @@ -72,11 +72,11 @@ type Pool struct { func (p *Pool) Name() string { return "pool" } func (p *Pool) Commands() []string { - return []string{"pool", "8ball", "8", "nineball", "9ball", "9", "shoot", "forfeit", "poolstats", "poolleaderboard"} + return []string{"pool", "pool8", "8pool", "pool9", "nineball", "9ball", "9", "shoot", "forfeit", "poolstats", "poolleaderboard"} } func (p *Pool) Help() string { - return "!8ball or !9ball — challenge someone; !pool accept|status|shoot [ball]|forfeit; !poolstats" + return "!pool 8 or !pool 9 — challenge someone; !pool accept|status|shoot [ball]|forfeit; !poolstats" } func (p *Pool) Init(c bot.PluginConfig, db *storage.DB) error { @@ -141,7 +141,7 @@ func (p *Pool) Handle(b *bot.Bot, m bot.Message) bool { func poolCommand(command string) bool { switch strings.ToLower(command) { - case "pool", "8ball", "8", "nineball", "9ball", "9", "shoot", "forfeit", "poolstats", "poolleaderboard": + case "pool", "pool8", "8pool", "pool9", "nineball", "9ball", "9", "shoot", "forfeit", "poolstats", "poolleaderboard": return true default: return false @@ -150,9 +150,9 @@ func poolCommand(command string) bool { func (p *Pool) handleLocked(b *bot.Bot, m bot.Message, key string, game *poolGame, command, arg string) string { switch command { - case "8ball", "8": + case "pool8", "8pool": return p.challengeLocked(key, m, poolEightBall, arg) - case "nineball", "9ball", "9": + case "pool9", "nineball", "9ball", "9": return p.challengeLocked(key, m, poolNineBall, arg) case "shoot": return p.shootLocked(m, key, game, arg) @@ -197,7 +197,7 @@ func (p *Pool) poolCommandLocked(key string, m bot.Message, game *poolGame, arg func (p *Pool) challengeLocked(key string, m bot.Message, mode poolMode, rawNick string) string { if strings.TrimSpace(rawNick) == "" { - return fmt.Sprintf("usage: !%s ", map[poolMode]string{poolEightBall: "8ball", poolNineBall: "9ball"}[mode]) + return fmt.Sprintf("usage: !%s ", map[poolMode]string{poolEightBall: "pool 8", poolNineBall: "pool 9"}[mode]) } nick := strings.TrimSpace(strings.TrimPrefix(rawNick, "@")) if !validPoolNick(nick) { @@ -254,7 +254,7 @@ func (p *Pool) declineLocked(m bot.Message, key string, game *poolGame) string { func (p *Pool) shootLocked(m bot.Message, key string, game *poolGame, rawBall string) string { if game == nil || game.Pending { - return "no pool game is active; use !8ball or !9ball " + return "no pool game is active; use !pool 8 or !pool 9 " } player := p.currentPlayer(game) if !samePoolIdentity(m, player) { @@ -319,7 +319,7 @@ func (p *Pool) forfeitLocked(m bot.Message, key string, game *poolGame) string { func (p *Pool) statusLocked(m bot.Message, game *poolGame) string { if game == nil { - return "no pool game is active; use !8ball or !9ball " + return "no pool game is active; use !pool 8 or !pool 9 " } if game.Pending { return fmt.Sprintf("pending %s challenge: %s invited %s; waiting for !pool accept.", game.Mode, game.Players[0].Name, game.Players[1].Name) diff --git a/plugins/pool_test.go b/plugins/pool_test.go index a84b4a6..3fc8501 100644 --- a/plugins/pool_test.go +++ b/plugins/pool_test.go @@ -19,11 +19,17 @@ func TestPoolDefaultsAndCommands(t *testing.T) { t.Fatalf("unexpected pool defaults: %+v", plugin.cfg) } commands := strings.Join(plugin.Commands(), " ") - for _, command := range []string{"pool", "8ball", "8", "9ball", "9", "shoot", "forfeit", "poolstats"} { + for _, command := range []string{"pool", "pool8", "8pool", "pool9", "9ball", "9", "shoot", "forfeit", "poolstats"} { if !strings.Contains(commands, command) { t.Fatalf("command %q missing from %q", command, commands) } } + if poolCommand("8ball") || poolCommand("8") { + t.Fatal("pool must not claim the magic 8-ball commands") + } + if !poolCommand("pool8") || !poolCommand("8pool") { + t.Fatal("pool 8 aliases are not registered correctly") + } } func TestPoolBallSets(t *testing.T) {