From 2f8fb69dbfcf24d7df47f8434b1936a06bb7f7ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20M=C3=BCller?= Date: Mon, 26 Aug 2019 20:09:10 +0200 Subject: [PATCH] Extend the usage function and add descriptions for commands User-facing help text is now kept in a dictionary where command tuples map to help entries. This greatly simplifies maintenance should more commands be added in the future. Additionally, every command now has a short description that serves to give players a quick overview of its functionality. --- botcmd.py | 86 +++++++++++++++++++++++++------------------------------ 1 file changed, 39 insertions(+), 47 deletions(-) diff --git a/botcmd.py b/botcmd.py index 703aa84..575c193 100644 --- a/botcmd.py +++ b/botcmd.py @@ -1,5 +1,6 @@ import threading import time +from collections import namedtuple import channel @@ -13,6 +14,8 @@ irc_chan = None game_channel = None +HelpEntry = namedtuple('HelpEntry', ['synopsis', 'desc', 'is_sub']) + def chunk(l, n): assert 0 < n chunked = [] @@ -122,6 +125,33 @@ def send_event(event): game_channel.send(event) def usage(command): + entries = { + ('status',) : HelpEntry('!status', 'Show the game status.', False), + ('ready',) : HelpEntry('!ready', 'Mark yourself as ready.', False), + ('unready',) : HelpEntry('!unready', 'Mark yourself as not ready.', False), + ('kill',) : HelpEntry('!kill', 'Stop the game.', False), + ('leave',) : HelpEntry('!leave', 'Leave the game.', False), + ('players',) : HelpEntry('!players', 'Show a list of players.', False), + ('cards',) : HelpEntry('!cards', 'Show the cards in your hand.', False), + ('origins',) : HelpEntry('!origins', 'Show the cardcast codes of the decks containing the cards that can be picked currently.', False), + ('redeal',) : HelpEntry('!redeal', 'Remove all cards from your hand and redeal.', False), + ('start',) : HelpEntry('!start []', 'Start a game with the specified preset. If no preset is given, use "default". Available presets are: default, empty, offtopia, offtopia-random', False), + ('join',) : HelpEntry('!join []', 'Join the game with the specified message.', False), + ('kick',) : HelpEntry('!kick ', 'Kick the specified player from the game.', False), + ('card',) : HelpEntry('[!card] ...', 'Pick the specified cards. If multiple numbers are specified for a single pick, play one of them at random.', False), + ('jape',) : HelpEntry('[!jape] ...', 'See !card.', False), + ('deck',) : HelpEntry('!deck add | remove | list', 'Manage decks.', True), + ('bot',) : HelpEntry('!bot add | remove', 'Manage bots.', True), + ('limit',) : HelpEntry('!limit [ []]', 'Show or adjust the win limit. Type can be "r" for rounds and "p" for points.', False), + ('help',) : HelpEntry('!help [command [subcommand]]', 'Show a synopsis and description for the specified command.', False), + + ('deck', 'add') : HelpEntry('!deck add | random', 'Add the deck with the specified cardcast code (or pick one randomly).', False), + ('deck', 'remove') : HelpEntry('!deck remove ', 'Remove the deck with the specified cardcast code.', False), + ('deck', 'list') : HelpEntry('!deck list', 'List selected decks.', False), + ('bot', 'add') : HelpEntry('!bot add []', 'Add a bot of the specified type and name. If the name is omitted, name the bot after its type.', False), + ('bot', 'remove') : HelpEntry('!bot remove ', 'Remove the specified bot.', False), + } + if type(command) == str: command = [command] @@ -130,55 +160,17 @@ def usage(command): command[0] = command[0][1:] if len(command) == 0: - return '!status !start !ready !unready !kill !join !leave !players !kick !deck !limit !card !cards !origins !redeal !help' - - elif len(command) == 1: - if command[0] in ('status', 'ready', 'unready', 'kill', 'join', 'leave', 'players', 'cards', 'origins', 'redeal'): - return 'Usage: !%s' % (command[0]) - elif command[0] == 'start': - return 'Usage: !start []' - elif command[0] == 'join': - return 'Usage: !join []' - elif command[0] == 'kick': - return 'Usage: !kick ' - elif command[0] == 'card': - return 'Usage: [!card] ...' - elif command[0] == 'jape': - return 'Usage: [!jape] ...' - elif command[0] == 'deck': - return 'Subcommands: !deck add | remove | list' - elif command[0] == 'bot': - return 'Subcommands: !bot add | remove' - elif command[0] == 'limit': - return 'Usage: !limit [ []]' - elif command[0] == 'help': - return 'Usage: !help [command [subcommmand]]' - else: - return 'No such command !%s' % (command[0]) - - elif len(command) == 2: - if command[0] == 'deck': - if command[1] == 'add': - return 'Usage: !deck add | random' - elif command[1] == 'remove': - return 'Usage: !deck remove ' - elif command[1] == 'list': - return 'Usage: !deck list' - else: - return 'No such subcommand !%s %s' % (command[0], command[1]) - elif command[0] == 'bot': - if command[1] == 'add': - return 'Usage: !bot add []' - elif command[1] == 'remove': - return 'Usage: !bot remove ' - else: - return 'No such subcommand !%s %s' % (command[0], command[1]) - else: - return 'No such subcommand !%s %s' % (command[0], command[1]) - - else: + return ' '.join(sorted(set('!' + cmd[0] for cmd in entries.keys()))) + elif len(command) > 2: return 'Uh, how did we get %i args?' % len(command) + key = tuple(command) + if key in entries: + e = entries[key] + return '%s: %s %s' % ('Subcommands' if e.is_sub else 'Usage', e.synopsis, e.desc) + else: + return 'No such command !%s' % ' '.join(command) + def parse_command(message, nick, irc): def send(m): global irc_chan