Beispiel #1
0
def character_id_from(name):
    try:
        character_id = CACHE['characters'][name]
    except KeyError as e:
        out(e)
        character_id = None
    return character_id
Beispiel #2
0
def process_messages(messages):
    for message in messages:
        try:
            out('\n-> ' + message['text'])
        except KeyError:
            pass
        COMMAND_ROUTER.route(message)
Beispiel #3
0
 def route(self, message):
     command_name = command_name_from(message)
     try:
         response = self.commands[command_name](message)
         reply(message, response)
     except KeyError as e:
         out(e)
         pass
Beispiel #4
0
def command_name_from(message):
    try:
        text = message['text']
        command = text.split(',')[0]
        if command.startswith('/'):
            command = command[1:].split(' ')[0]
    except (KeyError, IndexError) as e:
        out(e)
        command = None
    return command
Beispiel #5
0
def post(endpoint, params):
    headers = {"Content-type": "application/x-www-form-urlencoded",            "Accept": "text/plain"} 
    encoded_params = urlencode(params)
    CONNECTION.request(
        'POST', '/{}/{}'.format(TOKEN, endpoint), 
        encoded_params,
        headers
    )
    response = CONNECTION.getresponse().read()
    out(response)
Beispiel #6
0
def set_character_command(message):
    args = args_from(message)
    try:
        name = args[1]
        character_id = args[2]
        CACHE['characters'][name] = character_id
        update_cache(CACHE)
        return '{} added with ID {}'.format(name, character_id)
    except IndexError as e:
        out(e)
        return (
            'Incorrect number of arguments. \n' +
            'Expected usage: "/setcharacter <character_name> <character_id>"')
Beispiel #7
0
def _dc_values_from(message):
    args = args_from(message)
    args = ''.join(args[1:]).split('c')
    out('ARGS:' + str(args))
    try:
        dice_and_mod = args[0]
        n_dice = dice_and_mod
        dc = args[1]
    except KeyError:
        return None

    # Determine if modifier argument is present
    mod = ''
    try:
        dice_and_mod = dice_and_mod.split('|')
        if len(dice_and_mod) > 1:
            mod = dice_and_mod[1]
            n_dice = dice_and_mod[0]
    except KeyError:
        pass

    out('DICE N: ' + str(n_dice))
    out('MODIFIER:' + mod)
    out('DC: ' + str(dc))

    # Cast to integer values
    n_dice = int(n_dice)
    dc = int(dc)
    if mod != '': mod = int(mod)
    else: mod = 0

    return (n_dice, mod, dc)
Beispiel #8
0
def stats_command(message):
    args = args_from(message)
    try:
        name = args[1]
        character_id = character_id_from(name)
        if character_id != None:
            character_json = dndbeyond_json_from(character_id)
            stats = character_json['stats']
            stats = pretty_stats(stats)
            return stats
        else:
            return 'Could not find character with name: {}'.format(name)
    except Exception as e:
        out(e)
        return 'Error: problem with fetching or constructing character stats'
Beispiel #9
0
def roll_dice_command(message):
    args = args_from(message)
    try:
        result = roll(args[1])
        if isinstance(result, list):
            if len(result) > 1:
                rolls_as_str = [str(roll) for roll in result]
                output = '{} | {}'.format(', '.join(rolls_as_str), sum(result))
            else:
                output = str(result[0])
        else:
            output = str(result)
        return output
    except Exception as e:
        out(e)
        return 'Nope.'
Beispiel #10
0
def reply(message, response):
    try:
        chat_id = message['chat']['id']
        user = message['from']
        if 'username' in user: name = user['username']
        else                 : name = user['first_name']
        to = '@' + name
        full_response = '{} {}'.format(to, response)
        endpoint = 'sendMessage'
        params = {
            'chat_id':chat_id, 
            'text':full_response,
            'parse_mode':'Markdown'
        }
        post(endpoint, params)
        out('<- ' + full_response)
    except Exception:
        out(e)
Beispiel #11
0
def dc_dice_command(message):
    try:
        n_dice, mod, dc = _dc_values_from(message)
        command = '(({}d20).+{})'.format(n_dice, mod)
        result = roll(command)
        saves = 0
        fails = 0
        if isinstance(result, list):
            for dice_roll in result:
                dice_roll = int(dice_roll)
                if dice_roll + mod >= dc:
                    saves += 1
                    out('SAVE: d{}+{} vs {}'.format(dice_roll, mod, dc))
                else:
                    out('FAIL: d{}+{} vs {}'.format(dice_roll, mod, dc))
                    fails += 1
        output = '*DC {}* Saving Throw \n'
        if mod > 0:
            output += '+{} modifier added to each roll\n'.format(mod)
        output += 'Saves: {}\n'
        output += 'Fails: {}\n'
        output = output.format(dc, saves, fails)
        return output
    except Exception as e:
        out(e)
        return 'Nope.'
Beispiel #12
0
COMMAND_ROUTER.add_route('help', help_command)
COMMAND_ROUTER.add_route('roll', routes.roll_dice_command)
COMMAND_ROUTER.add_route('dc', routes.dc_dice_command)
COMMAND_ROUTER.add_route('setcharacter', dndbeyond.set_character_command)
COMMAND_ROUTER.add_route('stats', dndbeyond.stats_command)


def process_messages(messages):
    for message in messages:
        try:
            out('\n-> ' + message['text'])
        except KeyError:
            pass
        COMMAND_ROUTER.route(message)


def event_loop():
    latest_update_id = 0
    while True:
        update_id, messages = messages_after(latest_update_id + 1)
        process_messages(messages)
        message_count = len(messages)
        if message_count == 0:
            latest_update_id = 0
        else:
            latest_update_id = update_id


out("beholder-bot startup complete. Listening for incoming messages...")
event_loop()