示例#1
0
async def connectfour(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if not Ongoing.is_ongoing(cmd.name, pld.msg.channel.id):
        color = pld.args[0][0].lower() if pld.args else None
        competitor = pld.msg.guild.me
        if pld.msg.mentions:
            is_author = pld.msg.mentions[0].id == pld.msg.author.id
            is_me = pld.msg.mentions[0].id == cmd.bot.user.id
            is_bot = pld.msg.mentions[0].bot
            if not is_author and not is_bot or is_me:
                competitor = pld.msg.mentions[0]
            else:
                ender = 'another bot' if pld.msg.mentions[0].bot else 'yourself'
                self_embed = GenericResponse(
                    f'You can\'t play against {ender}.').error()
                await pld.msg.channel.send(embed=self_embed)
                return

        Ongoing.set_ongoing(cmd.name, pld.msg.channel.id)
        board = ConnectFourBoard()
        user_av = user_avatar(pld.msg.author)
        board_resp = generate_response(user_av, pld.msg.author, board.make)
        board_msg = await pld.msg.channel.send(embed=board_resp)
        [await board_msg.add_reaction(num) for num in nums]
        await make_game(board_msg, board, pld.msg.author, competitor, color)
    else:
        ongoing_error = GenericResponse(
            'There is already one ongoing.').error()
        await pld.msg.channel.send(embed=ongoing_error)
    async def int_dialogue(self, start, end):
        """
        Creates an interactive int dialogue message for a user to react to.
        :type start: int
        :type end: int
        :rtype: DialogueResponse
        """
        response = DialogueResponse(self)
        ongoing = Ongoing.is_ongoing('dialogue', self.user.id)
        if not ongoing:
            Ongoing.set_ongoing('dialogue', self.user.id)
            start = 0 if start < 0 else start
            end = 9 if end > 9 else end
            self.question.set_author(name=self.user.display_name, icon_url=user_avatar(self.user))
            # noinspection PyBroadException
            try:
                confirmation = await self.channel.send(embed=self.question)
                [await confirmation.add_reaction(INT_REACTIONS[preac]) for preac in range(start, end + 1)]
                await confirmation.add_reaction(CANCEL_REACT)
            except Exception:
                response.error = True
                Ongoing.del_ongoing('dialogue', self.user.id)
                return response

            def check_emote(reac):
                """
                Checks for a valid message reaction.
                :type reac: discord.RawReactionActionEvent
                :rtype: bool
                """
                same_author = reac.user_id == self.msg.author.id
                same_message = reac.message_id == confirmation.id
                valid_reaction = (str(reac.emoji) in INT_REACTIONS) or str(reac.emoji) == CANCEL_REACT
                return same_author and same_message and valid_reaction

            try:
                ae = await self.bot.wait_for('raw_reaction_add', timeout=TIMEOUT, check=check_emote)
                if str(ae.emoji) == CANCEL_REACT:
                    response.cancelled = True
                else:
                    response.ok = True
                    for react_index, int_react in enumerate(INT_REACTIONS):
                        if int_react == str(ae.emoji):
                            response.value = react_index
                            break
            except asyncio.TimeoutError:
                response.timed_out = True
            try:
                await confirmation.delete()
            except discord.NotFound:
                pass
            Ongoing.del_ongoing('dialogue', self.user.id)
        else:
            response.ongoing = True
        return response
    async def bool_dialogue(self):
        """
        Creates an interactive bool dialogue message for a user to react to.
        :rtype: DialogueResponse
        """
        response = DialogueResponse(self)
        ongoing = Ongoing.is_ongoing('dialogue', self.msg.author.id)
        if not ongoing:
            Ongoing.set_ongoing('dialogue', self.user.id)
            self.question.set_author(name=self.user.display_name, icon_url=user_avatar(self.user))
            # noinspection PyBroadException
            try:
                confirmation = await self.channel.send(embed=self.question)
                [await confirmation.add_reaction(preac) for preac in BOOL_REACTIONS]
            except Exception:
                Ongoing.del_ongoing('dialogue', self.user.id)
                response.error = True
                return response

            def check_emote(reac):
                """
                Checks for a valid message reaction.
                :type reac: discord.RawReactionActionEvent
                :rtype: bool
                """
                same_author = reac.user_id == self.msg.author.id
                same_message = reac.message_id == confirmation.id
                valid_reaction = str(reac.emoji) in BOOL_REACTIONS
                return same_author and same_message and valid_reaction

            try:
                ae = await self.bot.wait_for('raw_reaction_add', timeout=TIMEOUT, check=check_emote)
                if str(ae.emoji) == CONFIRM_REACT:
                    response.ok = True
                else:
                    response.cancelled = True
            except asyncio.TimeoutError:
                response.timed_out = True
            try:
                await confirmation.delete()
            except discord.NotFound:
                pass
            Ongoing.del_ongoing('dialogue', self.user.id)
        else:
            response.ongoing = True
        return response
示例#4
0
async def slow_buy(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    currency = cmd.bot.cfg.pref.currency
    if not Ongoing.is_ongoing(cmd.name, pld.msg.author.id):
        Ongoing.set_ongoing(cmd.name, pld.msg.author.id)
        upgrade_file = await cmd.bot.db.get_profile(pld.msg.author.id, 'upgrades') or {}
        upgrade_text = ''
        upgrade_index = 0
        for upgrade in upgrade_list:
            upgrade_index += 1
            upgrade_id = upgrade.get('id')
            upgrade_level = upgrade_file.get(upgrade_id, 0)
            base_price = upgrade.get('cost')
            upgrade_price = get_price(base_price, upgrade_level)
            next_upgrade = upgrade_level + 1
            upgrade_text += f'\n**{upgrade_index}**: Level {next_upgrade} {upgrade["name"]}'
            upgrade_text += f' - {upgrade_price} {currency}'
            upgrade_text += f'\n > {upgrade["desc"]}'
        upgrade_list_embed = discord.Embed(color=0xF9F9F9, title='🛍 Profession Upgrade Shop')
        upgrade_list_embed.description = upgrade_text
        upgrade_list_embed.set_footer(text='Please input the number of the upgrade you want.')
        dialogue = DialogueCore(cmd.bot, pld.msg, upgrade_list_embed)
        dresp = await dialogue.int_dialogue(1, len(upgrade_list))
        if dresp.ok and dresp.value is not None:
            upgrade = upgrade_list[dresp.value - 1]
            current_kud = await cmd.db.get_resource(pld.msg.author.id, 'currency')
            current_kud = current_kud.current
            upgrade_id = upgrade['id']
            upgrade_level = upgrade_file.get(upgrade_id, 0)
            base_price = upgrade['cost']
            upgrade_price = get_price(base_price, upgrade_level)
            if current_kud >= upgrade_price:
                new_upgrade_level = upgrade_level + 1
                upgrade_file.update({upgrade_id: new_upgrade_level})
                await cmd.db.set_profile(pld.msg.author.id, 'upgrades', upgrade_file)
                await cmd.db.del_resource(pld.msg.author.id, 'currency', upgrade_price, cmd.name, pld.msg)
                response = GenericResponse(f'Upgraded your {upgrade["name"]} to Level {new_upgrade_level}.').ok()
            else:
                response = discord.Embed(color=0xa7d28b, title=f'💸 You don\'t have enough {currency}.')
        else:
            response = discord.Embed(color=0x696969, title='🕙 Sorry, you timed out.')
        if Ongoing.is_ongoing(cmd.name, pld.msg.author.id):
            Ongoing.del_ongoing(cmd.name, pld.msg.author.id)
    else:
        response = GenericResponse('You already have a shop open.').error()
    await pld.msg.channel.send(embed=response)
async def wolframalpha(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    init_message = None
    if cmd.cfg.app_id:
        if not Ongoing.is_ongoing('mathgame', pld.msg.channel.id):
            if pld.args:
                query = make_safe_query(pld.args)
                url = f'{api_url}{query}&appid={cmd.cfg.app_id}'
                init_response = discord.Embed(color=0xff7e00)
                init_response.set_author(name='Processing request...',
                                         icon_url=wolfram_icon)
                init_message = await pld.msg.channel.send(embed=init_response)
                results = await get_results(url)
                if results:
                    if len(results) <= 2000:
                        response = discord.Embed(
                            color=0xff7e00, description=f'```\n{results}\n```')
                        response.set_author(name='Wolfram Alpha',
                                            icon_url=wolfram_icon,
                                            url=wolfram_url + query)
                        response.set_footer(
                            text=
                            'View the full results by clicking the embed title.'
                        )
                    else:
                        response = GenericResponse(
                            'Results too long to display.').error()
                        response.description = f'You can view them directly [here]({wolfram_url + query}).'
                else:
                    response = GenericResponse('No results.').not_found()
            else:
                response = GenericResponse('Nothing inputted.').error()
        else:
            response = GenericResponse(
                'Wolfram can\'t be used during an ongoing math game.').error()
    else:
        response = GenericResponse('The API Key is missing.').error()
    await send_response(pld.msg, init_message, response)
示例#6
0
async def connect_four_cycler(ev):
    """
    :param ev: The event object referenced in the event.
    :type ev: sigma.core.mechanics.event.SigmaEvent
    """
    while True:
        if ev.bot.is_ready():
            # noinspection PyBroadException
            try:
                games = cf_cache.cache.items()
                for mid, game in games:
                    expiry = game.expiry
                    now = arrow.utcnow().int_timestamp
                    if now > expiry:
                        channel = await ev.bot.get_channel(game.channel_id)
                        if channel:
                            wait_cycles = 0
                            while Ongoing.is_ongoing(
                                    'cf_ongoing_turn',
                                    channel.id) and wait_cycles < 5:
                                wait_cycles += 1
                                await asyncio.sleep(1)
                            timeout_title = '🕙 Time\'s up'
                            try:
                                timeout_title += ' ' + game.current_turn.display_name + '!'
                            except AttributeError:
                                timeout_title += '!'
                            timeout_embed = discord.Embed(color=0x696969,
                                                          title=timeout_title)
                            try:
                                await channel.send(embed=timeout_embed)
                            except (discord.NotFound, discord.Forbidden):
                                pass
                            if Ongoing.is_ongoing('connectfour', channel.id):
                                Ongoing.del_ongoing('connectfour', channel.id)
                            if Ongoing.is_ongoing('cf_ongoing_turn',
                                                  channel.id):
                                Ongoing.del_ongoing('cf_ongoing_turn',
                                                    channel.id)
                            await cf_cache.del_cache(mid)
            except Exception:
                pass
        await asyncio.sleep(5)
示例#7
0
async def sequencegame(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if Ongoing.is_ongoing(cmd.name, pld.msg.author.id):
        ongoing_error = GenericResponse(
            'There is already one ongoing.').error()
        await pld.msg.channel.send(embed=ongoing_error)
        return
    try:
        Ongoing.set_ongoing(cmd.name, pld.msg.author.id)
        chosen = [secrets.choice(first_symbols) for _ in range(4)]
        title = f'🎯 {pld.msg.author.display_name}, you have 90 seconds for each attempt.'
        desc = f'Symbols you can use: {"".join(first_symbols)}'
        start_embed = discord.Embed(color=0xf9f9f9)
        start_embed.add_field(name=title, value=desc)
        await pld.msg.channel.send(embed=start_embed)

        def answer_check(msg):
            """
            :type msg: discord.Message
            :rtype: bool
            """
            if pld.msg.author.id != msg.author.id:
                return
            if pld.msg.channel.id != msg.channel.id:
                return

            message_args = [
                char for char in msg.content if char in all_symbols
            ]
            if len(message_args) != 4:
                return

            for arg in message_args:
                if arg in all_symbols:
                    return True

        finished = False
        victory = False
        timeout = False
        tries = 0
        while not finished and tries < 6:
            try:
                answer = await cmd.bot.wait_for('message',
                                                check=answer_check,
                                                timeout=90)
                correct, results = check_answer(answer.content, chosen)
                tries += 1
                if correct:
                    finished = True
                    victory = True
                    currency = cmd.bot.cfg.pref.currency
                    await cmd.db.add_resource(answer.author.id, 'currency', 50,
                                              cmd.name, pld.msg)
                    win_title = f'🎉 Correct, {answer.author.display_name}. You won 50 {currency}!'
                    win_embed = discord.Embed(color=0x77B255, title=win_title)
                    await pld.msg.channel.send(embed=win_embed)
                else:
                    attempt_title = f'💣 {answer.author.display_name} {tries}/6: {"".join(results)}'
                    attempt_embed = discord.Embed(color=0x262626,
                                                  title=attempt_title)
                    await pld.msg.channel.send(embed=attempt_embed)
            except asyncio.TimeoutError:
                finished = True
                victory = False
                timeout = True
                timeout_title = f'🕙 Time\'s up {pld.msg.author.display_name}! It was {"".join(chosen)}'
                timeout_embed = discord.Embed(color=0x696969,
                                              title=timeout_title)
                await pld.msg.channel.send(embed=timeout_embed)

        if not victory and not timeout:
            lose_title = f'💥 Ooh, sorry {pld.msg.author.display_name}, it was {"".join(chosen)}'
            final_embed = discord.Embed(color=0xff3300, title=lose_title)
            await pld.msg.channel.send(embed=final_embed)
        Ongoing.del_ongoing(cmd.name, pld.msg.author.id)
    except Exception:
        if Ongoing.is_ongoing(cmd.name, pld.msg.author.id):
            Ongoing.del_ongoing(cmd.name, pld.msg.author.id)
        raise
示例#8
0
async def exportincidents(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    file = None
    if pld.msg.author.permissions_in(pld.msg.channel).manage_messages:
        if not Ongoing.is_ongoing(cmd.name, pld.msg.guild.id):
            Ongoing.set_ongoing(cmd.name, pld.msg.guild.id)
            icore = get_incident_core(cmd.db)
            response, target = None, None
            identifier, incidents = None, None
            title = '🗃️ Gathering all '
            if pld.args:
                if len(pld.args) == 2:
                    identifier = pld.args[0].lower()
                    if (pld.msg.mentions or identifier == 'variant') and identifier in identifiers:
                        if identifier == 'moderator':
                            target = pld.msg.mentions[0]
                            incidents = await icore.get_all_by_mod(pld.msg.guild.id, target.id)
                            title += f'incidents issued by {target.name}.'
                        elif identifier == 'target':
                            target = pld.msg.mentions[0]
                            incidents = await icore.get_all_by_target(pld.msg.guild.id, target.id)
                            title += f'incidents for {target.name}.'
                        else:
                            target = pld.args[1].lower()
                            if target in variants:
                                incidents = await icore.get_all_by_variant(pld.msg.guild.id, target)
                                title += f'{target} incidents.'
                            else:
                                response = GenericResponse('Invalid variant.').error()
                    else:
                        response = GenericResponse('Invalid identifier.').error()
            else:
                incidents = await icore.get_all(pld.msg.guild.id)
                title += 'incidents.'
            if not response:
                if incidents:
                    response = discord.Embed(color=0x226699, title=title)
                    response.set_footer(text='A text file will be sent to you shortly.')
                    if identifier:
                        modifier = f'{identifier.title()}: {target.title() if identifier == "variant" else target.name}'
                    else:
                        modifier = 'All'
                    file_name = make_export_file(pld.msg.guild.name, incidents, modifier)
                    file = discord.File(f'cache/{file_name}', file_name)
                else:
                    if identifier:
                        response = GenericResponse(f'No incidents found for that {identifier}.').error()
                    else:
                        response = GenericResponse('This server has no incidents.').error()
        else:
            response = GenericResponse('There is already one ongoing.').error()
    else:
        response = GenericResponse('Access Denied. Manage Messages needed.').denied()
    if Ongoing.is_ongoing(cmd.name, pld.msg.guild.id):
        Ongoing.del_ongoing(cmd.name, pld.msg.guild.id)
    await pld.msg.channel.send(embed=response)
    if file:
        try:
            await pld.msg.author.send(file=file)
        except (discord.NotFound, discord.Forbidden):
            denied_response = GenericResponse('I was unable to DM you, please adjust your settings.').error()
            await pld.msg.channel.send(pld.msg.author.mention, embed=denied_response)
示例#9
0
async def forage(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    ongoing = Ongoing.is_ongoing('profession', pld.msg.author.id)
    if not ongoing:
        Ongoing.set_ongoing('profession', pld.msg.author.id)
        item_core = await get_item_core(cmd.db)
        if not await cmd.bot.cool_down.on_cooldown('profession',
                                                   pld.msg.author):
            upgrade_file = await cmd.bot.db.get_profile(
                pld.msg.author.id, 'upgrades') or {}
            inv = await cmd.db.get_inventory(pld.msg.author.id)
            storage = upgrade_file.get('storage', 0)
            inv_limit = 64 + (8 * storage)
            if len(inv) < inv_limit:
                base_cooldown = 20
                stamina = upgrade_file.get('stamina', 0)
                cooldown = int(base_cooldown - ((base_cooldown / 100) *
                                                ((stamina * 0.5) /
                                                 (1.25 + (0.01 * stamina)))))
                cooldown = 2 if cooldown < 2 else cooldown
                await cmd.bot.cool_down.set_cooldown('profession',
                                                     pld.msg.author, cooldown)
                rarity = await item_core.roll_rarity(
                    await cmd.bot.db.get_profile(pld.msg.author.id))
                if pld.args:
                    if pld.msg.author.id in cmd.bot.cfg.dsc.owners:
                        try:
                            if int(pld.args[0]) <= 9:
                                rarity = int(pld.args[0])
                        except ValueError:
                            pass
                item = item_core.pick_item_in_rarity('plant', rarity)
                connector = 'a'
                if item.rarity_name[0].lower() in ['a', 'e', 'i', 'o', 'u']:
                    connector = 'an'
                if rarity == 0:
                    if item.name[0].lower() in ['a', 'e', 'i', 'o', 'u']:
                        connector = 'an'
                    response_title = f'{item.icon} You found {connector} {item.name} and threw it away!'
                    response = discord.Embed(color=item.color,
                                             title=response_title)
                else:
                    dialogue = DialogueCore(cmd.bot, pld.msg, None)
                    dresp = await dialogue.item_dialogue(
                        item_icons.get(item.type.lower()), item)
                    if dresp.ok:
                        response_title = f'{item.icon} You found {connector} {item.rarity_name} {item.name}!'
                        data_for_inv = item.generate_inventory_item()
                        await cmd.db.add_to_inventory(pld.msg.author.id,
                                                      data_for_inv)
                        await item_core.add_item_statistic(
                            cmd.db, item, pld.msg.author)
                        await cmd.db.add_resource(pld.msg.author.id, 'items',
                                                  1, cmd.name, pld.msg, True)
                        await cmd.db.add_resource(pld.msg.author.id, 'plant',
                                                  1, cmd.name, pld.msg, True)
                        response = discord.Embed(color=item.color,
                                                 title=response_title)
                    else:
                        if dresp.timed_out:
                            response_title = f'🕙 You forgot where the {item.rarity_name} {item.type.lower()} is...'
                            response = discord.Embed(color=0x696969,
                                                     title=response_title)
                        elif dresp.cancelled:
                            response_title = '❌ Oh no... You dug too hard and hurt the plant...'
                            response = discord.Embed(color=0xBE1931,
                                                     title=response_title)
                        else:
                            response = dresp.generic('foraging')
            else:
                response = GenericResponse('Your inventory is full.').error()
        else:
            timeout = await cmd.bot.cool_down.get_cooldown(
                'profession', pld.msg.author)
            response = discord.Embed(
                color=0x696969,
                title=f'🕙 You are resting for another {timeout} seconds.')
        Ongoing.del_ongoing('profession', pld.msg.author.id)
    else:
        response = GenericResponse(
            "Can't do multiple professions at once.").warn()
    response.set_author(name=pld.msg.author.display_name,
                        icon_url=user_avatar(pld.msg.author))
    await pld.msg.channel.send(embed=response)
示例#10
0
async def sell(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if Ongoing.is_ongoing(cmd.name, pld.msg.author.id):
        return
    Ongoing.set_ongoing(cmd.name, pld.msg.author.id)
    item_core = await get_item_core(cmd.db)
    currency = cmd.bot.cfg.pref.currency
    if pld.args:
        inv = await cmd.db.get_inventory(pld.msg.author.id)
        if inv:
            lookup = ' '.join(pld.args)
            if lookup.lower() == 'all':
                ender = 's' if len(inv) > 1 else ''
                worth = sum([item_core.get_item_by_file_id(ient['item_file_id']).value for ient in inv])
                question = f'❔ Are you sure you want to sell {len(inv)} item{ender} worth {worth} {currency}?'
                quesbed = discord.Embed(color=0xF9F9F9, title=question)
                dialogue = DialogueCore(cmd.bot, pld.msg, quesbed)
                dresp = await dialogue.bool_dialogue()
                if dresp.ok:
                    value = 0
                    count = 0
                    for invitem in inv.copy():
                        item_ob_id = item_core.get_item_by_file_id(invitem['item_file_id'])
                        value += item_ob_id.value
                        count += 1
                        await cmd.db.del_from_inventory(pld.msg.author.id, invitem['item_id'])
                    await cmd.db.add_resource(pld.msg.author.id, 'currency', value, cmd.name, pld.msg)
                    response = discord.Embed(color=0xc6e4b5)
                    response.title = f'💶 You sold {count} item{ender} for {value} {currency}.'
                else:
                    response = dresp.generic('item sale')
            elif lookup.lower() == 'duplicates':
                value = 0
                count = 0
                existing_ids = []
                for invitem in inv.copy():
                    file_id = invitem['item_file_id']
                    if file_id in existing_ids:
                        item_ob_id = item_core.get_item_by_file_id(file_id)
                        value += item_ob_id.value
                        count += 1
                        await cmd.db.del_from_inventory(pld.msg.author.id, invitem['item_id'])
                    else:
                        existing_ids.append(file_id)
                await cmd.db.add_resource(pld.msg.author.id, 'currency', value, cmd.name, pld.msg)
                ender = 's' if count > 1 else ''
                response = discord.Embed(color=0xc6e4b5)
                response.title = f'💶 You sold {count} duplicate{ender} for {value} {currency}.'
            else:
                request_count = 1
                if len(pld.args) > 1:
                    if pld.args[0].isdigit():
                        request_count = int(pld.args[0])
                        lookup = ' '.join(pld.args[1:])
                item_o = item_core.get_item_by_name(lookup)
                count = 0
                value = 0
                if item_o:
                    for _ in range(request_count):
                        item = await cmd.db.get_inventory_item(pld.msg.author.id, item_o.file_id)
                        if item:
                            value += item_o.value
                            count += 1
                            await cmd.db.del_from_inventory(pld.msg.author.id, item['item_id'])
                        else:
                            break
                if count > 0:
                    await cmd.db.add_resource(pld.msg.author.id, 'currency', value, cmd.name, pld.msg)
                    ender = 's' if count > 1 else ''
                    response = discord.Embed(color=0xc6e4b5)
                    response.title = f'💶 You sold {count} {item_o.name}{ender} for {value} {currency}.'
                else:
                    if not lookup.isdigit():
                        response = GenericResponse(f'I didn\'t find any {lookup} in your inventory.').not_found()
                    else:
                        response = GenericResponse(f'Sell {lookup} of what?').not_found()
        else:
            response = discord.Embed(color=0xc6e4b5, title='💸 Your inventory is empty...')
    else:
        response = GenericResponse('Nothing inputted.').error()
    if Ongoing.is_ongoing(cmd.name, pld.msg.author.id):
        Ongoing.del_ongoing(cmd.name, pld.msg.author.id)
    response.set_author(name=pld.msg.author.display_name, icon_url=user_avatar(pld.msg.author))
    await pld.msg.channel.send(embed=response)
示例#11
0
async def unscramblegame(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    cache_key = 'unscramble_word_cache'
    word_cache = await cmd.db.cache.get_cache(cache_key) or {}
    if not word_cache:
        dict_docs = await cmd.db[cmd.db.db_nam
                                 ].DictionaryData.find({}).to_list(None)
        for ddoc in dict_docs:
            word = ddoc.get('word')
            if len(word) > 3 and len(word.split(' ')) == 1:
                word_cache.update({word: ddoc.get('description')})
        await cmd.db.cache.set_cache(cache_key, word_cache)
    if not Ongoing.is_ongoing(cmd.name, pld.msg.channel.id):
        Ongoing.set_ongoing(cmd.name, pld.msg.channel.id)
        words = list(word_cache.keys())
        word_choice = secrets.choice(words)
        word_description = word_cache.get(word_choice)
        kud_reward = len(word_choice)
        scrambled = scramble(word_choice.title())
        question_embed = discord.Embed(color=0x3B88C3,
                                       title=f'🔣 {scrambled}')
        await pld.msg.channel.send(embed=question_embed)

        def check_answer(msg):
            """
            Checks if the answer message is correct.
            :type msg: discord.Message
            :rtype: bool
            """
            if pld.msg.channel.id == msg.channel.id:
                if msg.content.lower() == word_choice.lower():
                    correct = True
                else:
                    correct = False
            else:
                correct = False
            return correct

        try:
            answer_message = await cmd.bot.wait_for('message',
                                                    check=check_answer,
                                                    timeout=30)
            await cmd.db.add_resource(answer_message.author.id, 'currency',
                                      kud_reward, cmd.name, pld.msg)
            author = answer_message.author.display_name
            currency = cmd.bot.cfg.pref.currency
            win_title = f'🎉 Correct, {author}, it was {word_choice}. You won {kud_reward} {currency}!'
            win_embed = discord.Embed(color=0x77B255, title=win_title)
            await pld.msg.channel.send(embed=win_embed)
        except asyncio.TimeoutError:
            timeout_title = '🕙 Time\'s up!'
            timeout_embed = discord.Embed(color=0x696969, title=timeout_title)
            timeout_embed.add_field(name=f'It was {word_choice.lower()}.',
                                    value=word_description)
            await pld.msg.channel.send(embed=timeout_embed)
        if Ongoing.is_ongoing(cmd.name, pld.msg.channel.id):
            Ongoing.del_ongoing(cmd.name, pld.msg.channel.id)
    else:
        ongoing_error = GenericResponse(
            'There is one already ongoing.').error()
        await pld.msg.channel.send(embed=ongoing_error)
示例#12
0
async def vnchargame(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if not Ongoing.is_ongoing(cmd.name, pld.msg.channel.id):
        try:
            Ongoing.set_ongoing(cmd.name, pld.msg.channel.id)
            vndb_icon = 'https://i.imgur.com/YrK5tQF.png'
            wait_embed = discord.Embed(color=0x1d439b)
            wait_embed.set_author(name='Hunting for a good specimen...',
                                  icon_url=vndb_icon)
            working_response = await pld.msg.channel.send(embed=wait_embed)
            if pld.args:
                if pld.args[0].lower() == 'hint':
                    hint = True
                else:
                    hint = False
            else:
                hint = False
            vn_url_list = []
            vn_top_list_url = 'https://vndb.org/v/all?q=;fil=tagspoil-0;rfil=;o=d;s=pop;p=1'
            async with aiohttp.ClientSession() as session:
                async with session.get(vn_top_list_url) as vn_top_list_session:
                    vn_top_list_html = await vn_top_list_session.text()
            vn_top_list_data = html.fromstring(vn_top_list_html)
            list_items = vn_top_list_data.cssselect('.tc1')
            for list_item in list_items:
                if 'href' in list_item[0].attrib:
                    vn_url = list_item[0].attrib['href']
                    if vn_url.startswith(
                            '/v') and not vn_url.startswith('/v/'):
                        vn_url = f'https://vndb.org{vn_url}'
                        vn_url_list.append(vn_url)
            vn_url_choice = secrets.choice(vn_url_list)
            async with aiohttp.ClientSession() as session:
                async with session.get(
                        f'{vn_url_choice}/chars') as vn_details_page_session:
                    vn_details_page_html = await vn_details_page_session.text()
            vn_details_page = html.fromstring(vn_details_page_html)
            vn_title = vn_details_page.cssselect(
                '.stripe')[0][0][1].text_content().strip()
            vn_image = vn_details_page.cssselect(
                '.vnimg')[0][0][0][0].attrib['src']
            character_objects = vn_details_page.cssselect('.chardetails')[:8]
            character = secrets.choice(character_objects)
            char_img = character[0][0][0][0].attrib['src']
            char_name = character[1][0][0][0][0].text.strip()

            kud_reward = None
            description = None
            name_split = char_name.split()
            for name_piece in name_split:
                if kud_reward is None:
                    kud_reward = len(name_piece)
                else:
                    if kud_reward >= len(name_piece):
                        kud_reward = len(name_piece)
            if hint:
                kud_reward = kud_reward // 2
                scrambled_name = scramble(char_name)
                description = f'Name: {scrambled_name}'
            reward_mult = streaks.get(pld.msg.channel.id) or 0
            kud_reward = int(kud_reward * (1 + (reward_mult * 2.25) /
                                           (1.75 + (0.03 * reward_mult))))

            try:
                await working_response.delete()
            except discord.NotFound:
                pass
            question_embed = discord.Embed(color=0x225588)
            if description:
                question_embed.description = description
            question_embed.set_image(url=char_img)
            question_embed.set_author(name=vn_title,
                                      icon_url=vn_image,
                                      url=char_img)
            footer_text = 'You have 30 seconds to guess it.'
            if reward_mult:
                footer_text += f' | Streak: {int(reward_mult)}'
            question_embed.set_footer(text=footer_text)
            await pld.msg.channel.send(embed=question_embed)

            def check_answer(msg):
                """
                :type msg: discord.Message
                :rtype: bool
                """
                if pld.msg.channel.id == msg.channel.id:
                    if msg.content.lower() in char_name.lower().split():
                        correct = True
                    elif msg.content.lower() == char_name.lower():
                        correct = True
                    else:
                        correct = False
                else:
                    correct = False
                return correct

            try:
                answer_message = await cmd.bot.wait_for('message',
                                                        check=check_answer,
                                                        timeout=30)
                await cmd.db.add_resource(answer_message.author.id, 'currency',
                                          kud_reward, cmd.name, pld.msg)
                author = answer_message.author.display_name
                currency = cmd.bot.cfg.pref.currency
                streaks.update({pld.msg.channel.id: reward_mult + 1})
                win_title = f'🎉 Correct, {author}, it was {char_name}. You won {kud_reward} {currency}!'
                win_embed = discord.Embed(color=0x77B255, title=win_title)
                await pld.msg.channel.send(embed=win_embed)
            except asyncio.TimeoutError:
                if pld.msg.channel.id in streaks:
                    streaks.pop(pld.msg.channel.id)
                timeout_title = f'🕙 Time\'s up! It was {char_name} from {vn_title}...'
                timeout_embed = discord.Embed(color=0x696969,
                                              title=timeout_title)
                await pld.msg.channel.send(embed=timeout_embed)
        except (IndexError, KeyError):
            grab_error = GenericResponse(
                'I failed to grab a character, try again.').error()
            await pld.msg.channel.send(embed=grab_error)
        if Ongoing.is_ongoing(cmd.name, pld.msg.channel.id):
            Ongoing.del_ongoing(cmd.name, pld.msg.channel.id)
    else:
        ongoing_error = GenericResponse(
            'There is already one ongoing.').error()
        await pld.msg.channel.send(embed=ongoing_error)
示例#13
0
async def mangachargame(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if not Ongoing.is_ongoing(cmd.name, pld.msg.channel.id):
        try:
            Ongoing.set_ongoing(cmd.name, pld.msg.channel.id)
            mal_icon = 'https://myanimelist.cdn-dena.com/img/sp/icon/apple-touch-icon-256.png'
            wait_embed = discord.Embed(color=0x1d439b)
            wait_embed.set_author(name='Hunting for a good specimen...',
                                  icon_url=mal_icon)
            working_response = await pld.msg.channel.send(embed=wait_embed)
            if pld.args:
                if pld.args[0].lower() == 'hint':
                    hint = True
                else:
                    hint = False
            else:
                hint = False
            ani_order = secrets.randbelow(3) * 50
            if ani_order:
                ani_top_list_url = f'https://myanimelist.net/topmanga.php?limit={ani_order}'
            else:
                ani_top_list_url = 'https://myanimelist.net/topmanga.php'
            async with aiohttp.ClientSession() as session:
                async with session.get(
                        ani_top_list_url) as ani_top_list_session:
                    ani_top_list_html = await ani_top_list_session.text()
            ani_top_list_data = html.fromstring(ani_top_list_html)
            ani_list_objects = ani_top_list_data.cssselect('.ranking-list')
            ani_choice = secrets.choice(ani_list_objects)
            ani_url = ani_choice[1][0].attrib['href']
            async with aiohttp.ClientSession() as session:
                async with session.get(
                        f'{ani_url}/characters') as ani_page_session:
                    ani_page_html = await ani_page_session.text()
            ani_page_data = html.fromstring(ani_page_html)
            cover_object = ani_page_data.cssselect('.borderClass a')[0][0]
            manga_cover = cover_object.attrib['data-src']
            manga_title = cover_object.attrib['alt'].strip()
            character_object_list = ani_page_data.cssselect(
                '.js-scrollfix-bottom-rel')[0]
            character_list = []
            for char_obj_full in character_object_list[5:]:
                char_obj_full = char_obj_full.cssselect(
                    'td.borderClass.bgColor2')
                if len(char_obj_full) != 2:
                    continue
                char_obj = char_obj_full[0].cssselect('.fw-n')[0]
                cover_obj = char_obj_full[1].cssselect('.spaceit_pad small')[0]
                if 'href' in char_obj.attrib:
                    if cover_obj.text_content().strip() == 'Main':
                        character_list.append(char_obj)
            char_choice = secrets.choice(character_list)
            char_url = char_choice.attrib['href']
            async with aiohttp.ClientSession() as session:
                async with session.get(char_url) as char_page_session:
                    char_page_html = await char_page_session.text()
            char_page_data = html.fromstring(char_page_html)
            char_img_obj = char_page_data.cssselect('.borderClass')[0][0][0][0]
            char_img = char_img_obj.attrib['data-src']
            char_name = ' '.join(
                char_img_obj.attrib['alt'].strip().split(', '))

            kud_reward = None
            description = None
            name_split = char_name.split()
            for name_piece in name_split:
                if kud_reward is None:
                    kud_reward = len(name_piece)
                else:
                    if kud_reward >= len(name_piece):
                        kud_reward = len(name_piece)
            if hint:
                kud_reward = kud_reward // 2
                scrambled_name = scramble(char_name)
                description = f'Name: {scrambled_name}'
            reward_mult = streaks.get(pld.msg.channel.id) or 0
            kud_reward = int(kud_reward * (1 + (reward_mult * 2.25) /
                                           (1.75 + (0.03 * reward_mult))))

            try:
                await working_response.delete()
            except discord.NotFound:
                pass
            question_embed = discord.Embed(color=0x1d439b)
            if description:
                question_embed.description = description
            question_embed.set_image(url=char_img)
            question_embed.set_author(name=manga_title,
                                      icon_url=manga_cover,
                                      url=char_img)
            footer_text = 'You have 30 seconds to guess it.'
            if reward_mult:
                footer_text += f' | Streak: {int(reward_mult)}'
            question_embed.set_footer(text=footer_text)
            await pld.msg.channel.send(embed=question_embed)

            def check_answer(msg):
                """
                :type msg: discord.Message
                :rtype: bool
                """
                if pld.msg.channel.id == msg.channel.id:
                    if msg.content.lower() in char_name.lower().split():
                        correct = True
                    elif msg.content.lower() == char_name.lower():
                        correct = True
                    else:
                        correct = False
                else:
                    correct = False
                return correct

            try:
                answer_message = await cmd.bot.wait_for('message',
                                                        check=check_answer,
                                                        timeout=30)
                await cmd.db.add_resource(answer_message.author.id, 'currency',
                                          kud_reward, cmd.name, pld.msg)
                author = answer_message.author.display_name
                currency = cmd.bot.cfg.pref.currency
                streaks.update({pld.msg.channel.id: reward_mult + 1})
                win_title = f'🎉 Correct, {author}, it was {char_name}. You won {kud_reward} {currency}!'
                win_embed = discord.Embed(color=0x77B255, title=win_title)
                await pld.msg.channel.send(embed=win_embed)
            except asyncio.TimeoutError:
                if pld.msg.channel.id in streaks:
                    streaks.pop(pld.msg.channel.id)
                timeout_title = f'🕙 Time\'s up! It was {char_name} from {manga_title}...'
                timeout_embed = discord.Embed(color=0x696969,
                                              title=timeout_title)
                await pld.msg.channel.send(embed=timeout_embed)
        except (IndexError, KeyError):
            grab_error = GenericResponse(
                'I failed to grab a character, try again.').error()
            await pld.msg.channel.send(embed=grab_error)
        if Ongoing.is_ongoing(cmd.name, pld.msg.channel.id):
            Ongoing.del_ongoing(cmd.name, pld.msg.channel.id)
    else:
        ongoing_error = GenericResponse(
            'There is already one ongoing.').error()
        await pld.msg.channel.send(embed=ongoing_error)
示例#14
0
async def bazaar(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    author_stamp = arrow.get(pld.msg.author.created_at).float_timestamp
    current_stamp = arrow.utcnow().float_timestamp
    time_diff = current_stamp - author_stamp
    if time_diff > 2592000:
        if not Ongoing.is_ongoing(cmd.name, pld.msg.author.id):
            Ongoing.set_ongoing(cmd.name, pld.msg.author.id)
            item_core = await get_item_core(cmd.db)
            doc = await get_active_shop(cmd.db, pld.msg.author.id)
            if not doc:
                doc = await generate_shop(cmd.db, pld.msg.author.id)
            currency = cmd.bot.cfg.pref.currency
            lines = []
            keys = ['fish', 'plant', 'animal']
            for (kx, key) in enumerate(keys):
                available = not await has_purchased(cmd.db, pld.msg.author.id,
                                                    key)
                item = item_core.get_item_by_file_id(doc.get(key))
                if available:
                    multi = price_multi(item.file_id)
                    price = int(item.value * multi)
                    item_name = f"{item.icon} {item.rarity_name.title()} {item.name}: **{price} {currency}**"
                else:
                    item_name = f"{item.icon} ~~{item.rarity_name.title()} {item.name}~~"
                line = f"**{kx + 1}**: {item_name}"
                lines.append(line)
            question = discord.Embed(color=0xffac33,
                                     title='🪙 The Item Bazaar')
            question.description = '\n'.join(lines)
            dialogue = DialogueCore(cmd.bot, pld.msg, question)
            dresp = await dialogue.int_dialogue(1, len(keys))
            if dresp.ok and dresp.value is not None:
                key = keys[dresp.value - 1]
                item = item_core.get_item_by_file_id(doc.get(key))
                available = not await has_purchased(cmd.db, pld.msg.author.id,
                                                    key)
                if available:
                    curr = (await cmd.db.get_resource(pld.msg.author.id,
                                                      'currency')).current
                    multi = price_multi(item.file_id)
                    price = int(item.value * multi)
                    if curr >= price:
                        await cmd.db.del_resource(pld.msg.author.id,
                                                  'currency', price, cmd.name,
                                                  pld.msg)
                        data_for_inv = item.generate_inventory_item()
                        await cmd.db.add_to_inventory(pld.msg.author.id,
                                                      data_for_inv)
                        await track_purchase(cmd.db, pld.msg.author.id, key,
                                             item.file_id, price)
                        await item_core.add_item_statistic(
                            cmd.db, item, pld.msg.author)
                        await cmd.db.add_resource(pld.msg.author.id, 'items',
                                                  1, cmd.name, pld.msg, True)
                        response = GenericResponse(
                            f"You have purchased a {item.name} for {price} {currency}."
                        ).ok()
                    else:
                        response = discord.Embed(
                            color=0xa7d28b,
                            title=f'💸 You don\'t have enough {currency}.')
                else:
                    response = GenericResponse(
                        'One per customer please.').error()
            else:
                response = dresp.generic('bazaar')
            if Ongoing.is_ongoing(cmd.name, pld.msg.author.id):
                Ongoing.del_ongoing(cmd.name, pld.msg.author.id)
        else:
            response = GenericResponse(
                'You already have a bazaar open.').error()
    else:
        response = GenericResponse(
            'Sorry, your account is too young to visit the bazaar.').error()
    response.set_author(name=pld.msg.author.display_name,
                        icon_url=user_avatar(pld.msg.author))
    await pld.msg.channel.send(embed=response)
示例#15
0
async def marketsell(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if await cmd.db.is_sabotaged(pld.msg.author.id):
        response = GenericResponse(
            'Quarantined users can\'t use the market.').denied()
        await pld.msg.channel.send(embed=response)
        return
    author_stamp = arrow.get(pld.msg.author.created_at).float_timestamp
    current_stamp = arrow.utcnow().float_timestamp
    time_diff = current_stamp - author_stamp
    if time_diff > 2592000:
        if len(pld.args) >= 2:
            valid = True
            try:
                price = int(pld.args[0])
            except ValueError:
                price = 0
                valid = False
            if valid:
                ic = await get_item_core(cmd.db)
                item_lookup = ' '.join(pld.args[1:])
                item = ic.get_item_by_name(item_lookup)
                if item:
                    if not Ongoing.is_ongoing(cmd.name, pld.msg.author.id):
                        Ongoing.set_ongoing(cmd.name, pld.msg.author.id)
                        inv_item = await cmd.db.get_inventory_item(
                            pld.msg.author.id, item.file_id)
                        if inv_item:
                            expiration = arrow.get(
                                arrow.utcnow().int_timestamp +
                                MARKET_LIFETIME).format(
                                    'DD. MMM. YYYY HH:mm UTC')
                            cost = int(price * 0.005)
                            cost = cost if cost else 10
                            curr = cmd.bot.cfg.pref.currency
                            profit = int(price * (1 -
                                                  (MARKET_TAX_PERCENT / 100)))
                            questitle = f'❔ Sell the {item.rarity_name} {item.name} for {price} {curr}?'
                            quesbed = discord.Embed(color=0xf9f9f9,
                                                    title=questitle)
                            desc = f'Listing the item costs **{cost}** {curr}.'
                            desc += f' The market has a {MARKET_TAX_PERCENT}% tax so if your item gets sold,'
                            desc += f' you will get {profit} instead of {price} {curr}.'
                            desc += ' Retracting the item is not taxed.'
                            desc += f' The item will be available until {expiration}.'
                            quesbed.description = desc
                            dialogue = DialogueCore(cmd.bot, pld.msg, quesbed)
                            dresp = await dialogue.bool_dialogue()
                            if dresp.ok:
                                wallet = (await cmd.db.get_resource(
                                    pld.msg.author.id, 'currency')).current
                                if wallet >= cost:
                                    me = MarketEntry.new(
                                        pld.msg.author, item.file_id, price)
                                    try:
                                        await me.save(cmd.db)
                                        await cmd.db.del_resource(
                                            pld.msg.author.id, 'currency',
                                            cost, cmd.name, pld.msg)
                                        await cmd.db.del_from_inventory(
                                            pld.msg.author.id,
                                            inv_item['item_id'])
                                        pfx = cmd.db.get_prefix(pld.settings)
                                        desc = f'Placed the {item.rarity_name} {item.name}'
                                        desc += f' on the market for {price} {curr}.'
                                        desc += f' The listing expiry is {expiration}.'
                                        desc += f' Your market entry token is `{me.token}`,'
                                        desc += ' it can be bought directly using the'
                                        desc += f' `{pfx}marketbuy {me.token}` command.'
                                        response = GenericResponse(
                                            'Market entry created.').ok()
                                        response.description = desc
                                    except OverflowError:
                                        response = GenericResponse(
                                            "Whoa, that number is way too big!"
                                        ).error()
                                else:
                                    response = GenericResponse(
                                        'You\'re not able to pay the listing fee.'
                                    ).error()
                            else:
                                response = dresp.generic('market sale')
                        else:
                            response = GenericResponse(
                                'You don\'t have this item in your inventory.'
                            ).not_found()
                        if Ongoing.is_ongoing(cmd.name, pld.msg.author.id):
                            Ongoing.del_ongoing(cmd.name, pld.msg.author.id)
                    else:
                        response = GenericResponse(
                            'You already have a market sale open.').error()
                else:
                    response = GenericResponse(
                        'Couldn\'t find that item, did you spell the name correctly?'
                    ).not_found()
            else:
                response = GenericResponse('Invalid arguments.').error()
                response.description = 'Place the price first, and the item name after that.'
        else:
            response = GenericResponse(
                'Not enough arguments, I need a price and item name.').error()
    else:
        response = GenericResponse(
            'Sorry, your account is too young to use the market.').error()
    await pld.msg.channel.send(embed=response)
示例#16
0
async def marketbuy(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if await cmd.db.is_sabotaged(pld.msg.author.id):
        response = GenericResponse('Quarantined users can\'t use the market.').denied()
        await pld.msg.channel.send(embed=response)
        return
    author_stamp = arrow.get(pld.msg.author.created_at).float_timestamp
    current_stamp = arrow.utcnow().float_timestamp
    time_diff = current_stamp - author_stamp
    if time_diff > 2592000:
        if pld.args:
            if not Ongoing.is_ongoing(cmd.name, pld.msg.author.id):
                Ongoing.set_ongoing(cmd.name, pld.msg.author.id)
                ic = await get_item_core(cmd.db)
                lookup = ' '.join(pld.args)
                check_token = len(pld.args) == 1
                item = ic.get_item_by_name(lookup)
                if check_token and item is None:
                    me = await MarketEntry.find(cmd.db, token=lookup)
                    if me:
                        item = ic.get_item_by_file_id(me.item)
                else:
                    if item is not None:
                        me = await MarketEntry.find(cmd.db, item=item.file_id)
                    else:
                        me = None
                if me:
                    await me.delete(cmd.db)
                    self_buy = me.uid == pld.msg.author.id
                    curr = cmd.bot.cfg.pref.currency
                    action = 'Retract' if self_buy else 'Buy'
                    questitle = f'❔ {action} the {item.rarity_name} {item.name} for {me.price} {curr}?'
                    stamp = arrow.get(me.stamp).format('DD. MMM. YYYY HH:mm:ss')
                    quesbed = discord.Embed(color=0xf9f9f9, title=questitle)
                    quesbed.description = f'Market entry {me.token} submitted by {me.uname} on {stamp}.'
                    if self_buy:
                        quesbed.set_footer(text="Retracting the item does not pay its price or tax.")
                    dialogue = DialogueCore(cmd.bot, pld.msg, quesbed)
                    dresp = await dialogue.bool_dialogue()
                    if dresp.ok:
                        kud = (await cmd.db.get_resource(pld.msg.author.id, 'currency')).current
                        if self_buy:
                            data_for_inv = item.generate_inventory_item()
                            await cmd.db.add_to_inventory(pld.msg.author.id, data_for_inv)
                            response = GenericResponse(f'Retracted the {item.rarity_name} {item.name}.').ok()
                        else:
                            if kud >= me.price:
                                await cmd.db.del_resource(pld.msg.author.id, 'currency', me.price, cmd.name, pld.msg)
                                profit = int(me.price * (1 - (MARKET_TAX_PERCENT / 100)))
                                await cmd.db.add_resource(me.uid, 'currency', profit, cmd.name, pld.msg, ranked=False)
                                await cmd.db.add_resource(
                                    cmd.bot.user.id, 'currency', me.price - profit, cmd.name, pld.msg, ranked=False
                                )
                                data_for_inv = item.generate_inventory_item()
                                await cmd.db.add_to_inventory(pld.msg.author.id, data_for_inv)
                                response = GenericResponse(
                                    f'Purchased the {item.rarity_name} {item.name} for {me.price} {curr}.'
                                ).ok()
                            else:
                                await me.save(cmd.db)
                                response = discord.Embed(color=0xa7d28b, title=f'💸 You don\'t have enough {curr}.')
                    else:
                        await me.save(cmd.db)
                        response = dresp.generic('market purchase')
                else:
                    response = GenericResponse('Couldn\'t find any entries for that.').not_found()
                if Ongoing.is_ongoing(cmd.name, pld.msg.author.id):
                    Ongoing.del_ongoing(cmd.name, pld.msg.author.id)
            else:
                response = GenericResponse('You already have a market purchase open.').error()
        else:
            response = GenericResponse('Not enough arguments, I need a price and item name.').error()
    else:
        response = GenericResponse('Sorry, your account is too young to use the market.').error()
    await pld.msg.channel.send(embed=response)
示例#17
0
    async def item_dialogue(self, icons, item):
        """
        Creates an interactive item dialogue message for a user to react to.
        :type icons: dict
        :type item: sigma.modules.minigames.professions.nodes.item_object.SigmaRawItem
        :rtype: DialogueResponse
        """
        response = DialogueResponse(self)
        ongoing = Ongoing.is_ongoing('dialogue', self.user.id)
        if not ongoing:
            Ongoing.set_ongoing('dialogue', self.user.id)
            icon_list = [icons.get(ic) for ic in icons if icons.get(ic) != item.icon]
            icon_list.pop(0)
            possible_proto = [item.icon]
            while len(possible_proto) < secrets.randbelow(2) + 3:
                possible_proto.append(icon_list.pop(secrets.randbelow(len(icon_list))))
            possible = []
            while possible_proto:
                possible.append(possible_proto.pop(secrets.randbelow(len(possible_proto))))
            possible.append(CANCEL_REACT)
            title = f'{item.icon} Quick! Get the correct {item.type.lower()}!'
            self.question = discord.Embed(color=item.color, title=title)
            self.question.set_author(name=self.user.display_name, icon_url=user_avatar(self.user))
            # noinspection PyBroadException
            try:
                confirmation = await self.channel.send(embed=self.question)
                [await confirmation.add_reaction(preac) for preac in possible]
            except Exception:
                response.error = True
                Ongoing.del_ongoing('dialogue', self.user.id)
                return response

            def check_emote(reac):
                """
                Checks for a valid message reaction.
                :type reac: discord.RawReactionActionEvent
                :rtype: bool
                """
                same_author = reac.user_id == self.msg.author.id
                same_message = reac.message_id == confirmation.id
                valid_reaction = str(reac.emoji) in possible
                return same_author and same_message and valid_reaction

            try:
                ae = await self.bot.wait_for('raw_reaction_add', timeout=TIMEOUT, check=check_emote)
                if str(ae.emoji) == item.icon:
                    response.ok = True
                elif str(ae.emoji) == CANCEL_REACT:
                    response.cancelled = True
                else:
                    response.cancelled = True
            except asyncio.TimeoutError:
                response.timed_out = True
            try:
                await confirmation.delete()
            except discord.NotFound:
                pass
            Ongoing.del_ongoing('dialogue', self.user.id)
        else:
            response.ongoing = True
        return response
示例#18
0
async def connect_four_mechanics(ev, pld):
    """
    :param ev: The event object referenced in the event.
    :type ev: sigma.core.mechanics.event.SigmaEvent
    :param pld: The event payload data to process.
    :type pld: sigma.core.mechanics.payload.RawReactionPayload
    """
    payload = pld.raw
    uid = payload.user_id
    cid = payload.channel_id
    mid = payload.message_id
    emoji = payload.emoji
    channel = await ev.bot.get_channel(cid)
    try:
        guild = channel.guild
    except AttributeError:
        guild = None
    if guild:
        # noinspection PyTypeChecker
        game: ConnectFourGame = await cf_cache.get_cache(mid)
        if game:
            if Ongoing.is_ongoing('cf_ongoing_turn', cid):
                return
            Ongoing.set_ongoing('cf_ongoing_turn', cid)
            try:
                message = await channel.fetch_message(mid)
            except (discord.NotFound, discord.Forbidden):
                message = None
            if message:
                if ev.event_type == 'raw_reaction_add':
                    if str(emoji.name) in nums and uid == game.current_turn.id:
                        user_av = user_avatar(game.p_one)
                        await check_emotes(ev.bot, message)
                        piece = game.po_piece if game.current_turn.id == game.p_one.id else game.pt_piece
                        opponent = message.guild.me if game.is_bot else game.p_two
                        next_player = game.p_one if game.current_turn != game.p_one else opponent
                        rows = game.board.edit(nums.index(str(emoji.name)),
                                               piece)
                        board_resp = generate_response(user_av, next_player,
                                                       rows)
                        board_msg = await send_board_msg(
                            channel, message, board_resp)
                        full, winner, win = game.board.winner
                        finished = win or full
                        if not finished:
                            if game.is_bot:
                                # Bot takes turn
                                await asyncio.sleep(2)
                                game.last_bot_move = bot_choice = game.board.bot_move(
                                    game.last_bot_move)
                                rows = game.board.edit(bot_choice,
                                                       game.pt_piece)
                                board_resp = generate_response(
                                    user_av, game.p_one, rows)
                                await send_board_msg(channel, board_msg,
                                                     board_resp)
                                full, winner, win = game.board.winner
                                finished = win or full
                            else:
                                if game.current_turn == game.p_one:
                                    game.current_turn = game.p_two
                                else:
                                    game.current_turn = game.p_one
                        if finished:
                            if winner:
                                if game.is_bot:
                                    if winner == getattr(game.board, piece):
                                        color, icon, resp = 0x3B88C3, '💎', 'You win'
                                    else:
                                        color, icon, resp = 0x292929, '💣', 'You lose'
                                else:
                                    color, icon, resp = 0x3B88C3, '💎', f'{game.current_turn.display_name} wins'
                            else:
                                color, icon, resp = 0xFFCC4D, '🔥', 'It\'s a draw'
                            response = discord.Embed(color=color,
                                                     title=f'{icon} {resp}!')
                            await channel.send(embed=response)
                            await cf_cache.del_cache(mid)
                            if Ongoing.is_ongoing('connectfour', channel.id):
                                Ongoing.del_ongoing('connectfour', channel.id)
            game.expiry = arrow.utcnow().int_timestamp + 120
            if Ongoing.is_ongoing('cf_ongoing_turn', cid):
                Ongoing.del_ongoing('cf_ongoing_turn', cid)
示例#19
0
async def hangman(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    cache_key = 'hangman_word_cache'
    word_cache = await cmd.db.cache.get_cache(cache_key) or {}
    if not word_cache:
        dict_docs = await cmd.db[cmd.db.db_nam
                                 ].DictionaryData.find({}).to_list(None)
        for ddoc in dict_docs:
            word = ddoc.get('word')
            if len(word) > 3 and len(word.split(' ')) == 1 and '-' not in word:
                word_cache.update({word: ddoc.get('description')})
        await cmd.db.cache.set_cache(cache_key, word_cache)
    if not Ongoing.is_ongoing(cmd.name, pld.msg.channel.id):
        Ongoing.set_ongoing(cmd.name, pld.msg.channel.id)
        words = list(word_cache.keys())
        gallows = Gallows(secrets.choice(words))
        word_description = word_cache.get(gallows.word)
        kud_reward = gallows.count
        author = pld.msg.author.display_name
        hangman_resp = generate_response(gallows)
        hangman_msg = await pld.msg.channel.send(embed=hangman_resp)

        def check_answer(msg):
            """
            Checks if the answer message is correct.
            :type msg: discord.Message
            :rtype: bool
            """
            if pld.msg.channel.id != msg.channel.id:
                return
            if pld.msg.author.id != msg.author.id:
                return
            if len(msg.content) == 1:
                if msg.content.isalpha():
                    correct = True
                else:
                    correct = False
            else:
                correct = False
            return correct

        finished = False
        timeout = False
        while not timeout and not finished:
            try:
                answer_message = await cmd.bot.wait_for('message',
                                                        check=check_answer,
                                                        timeout=30)
                letter = answer_message.content.lower()
                if letter in gallows.word:
                    if letter not in gallows.right_letters:
                        gallows.right_letters.append(letter)
                else:
                    if letter.upper() not in gallows.wrong_letters:
                        gallows.wrong_letters.append(letter.upper())
                        gallows.use_part()
                hangman_msg = await send_hangman_msg(
                    pld.msg, hangman_msg, generate_response(gallows))
                finished = gallows.victory or gallows.dead
            except asyncio.TimeoutError:
                timeout = True
                timeout_title = '🕙 Time\'s up!'
                timeout_embed = discord.Embed(color=0x696969,
                                              title=timeout_title)
                timeout_embed.add_field(name=f'It was {gallows.word}.',
                                        value=word_description)
                await pld.msg.channel.send(embed=timeout_embed)

        if gallows.dead:
            lose_title = f'💥 Ooh, sorry {author}, it was {gallows.word}.'
            final_embed = discord.Embed(color=0xff3300, title=lose_title)
            await pld.msg.channel.send(embed=final_embed)
        elif gallows.victory:
            await cmd.db.add_resource(pld.msg.author.id, 'currency',
                                      kud_reward, cmd.name, pld.msg)
            currency = cmd.bot.cfg.pref.currency
            win_title = f'🎉 Correct, {author}, it was {gallows.word}. You won {kud_reward} {currency}!'
            win_embed = discord.Embed(color=0x77B255, title=win_title)
            await pld.msg.channel.send(embed=win_embed)

        if Ongoing.is_ongoing(cmd.name, pld.msg.channel.id):
            Ongoing.del_ongoing(cmd.name, pld.msg.channel.id)
    else:
        ongoing_error = GenericResponse(
            'There is one already ongoing.').error()
        await pld.msg.channel.send(embed=ongoing_error)
示例#20
0
async def trivia(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    global streaks
    if await cmd.bot.cool_down.on_cooldown(cmd.name, pld.msg.author):
        timeout = await cmd.bot.cool_down.get_cooldown(cmd.name,
                                                       pld.msg.author)
        on_cooldown = discord.Embed(
            color=0xccffff,
            title=f'❄ On cooldown for another {timeout} seconds.')
        await pld.msg.channel.send(embed=on_cooldown)
        return
    try:
        if not Ongoing.is_ongoing(cmd.name, pld.msg.author.id):
            Ongoing.set_ongoing(cmd.name, pld.msg.author.id)
            allotted_time = 20
            trivia_api_url = 'https://opentdb.com/api.php?amount=1'
            cat_chosen = False
            if pld.args:
                catlook = pld.args[-1].lower()
                for cat in categories:
                    cat_alts = categories.get(cat)
                    if catlook in cat_alts:
                        trivia_api_url += f'&category={cat}'
                        cat_chosen = True
                        break
                diflook = pld.args[0].lower()
                if diflook in ['easy', 'medium', 'hard']:
                    trivia_api_url += f'&difficulty={diflook}'
                    cat_chosen = True
            async with aiohttp.ClientSession() as session:
                async with session.get(trivia_api_url) as number_get:
                    number_response = await number_get.read()
                    try:
                        data = json.loads(number_response).get('results')[0]
                    except json.JSONDecodeError:
                        if Ongoing.is_ongoing(cmd.name, pld.msg.author.id):
                            Ongoing.del_ongoing(cmd.name, pld.msg.author.id)
                        decode_error = GenericResponse(
                            'Could not retrieve a question.').error()
                        await pld.msg.channel.send(embed=decode_error)
                        return
            await cmd.bot.cool_down.set_cooldown(cmd.name, pld.msg.author, 30)
            question = data['question']
            question = ftfy.fix_text(question)
            question = re.sub(r'([*_~`])', r'\\\1',
                              question)  # escape markdown formatting
            category = data['category']
            correct_answer = data['correct_answer']
            correct_answer = ftfy.fix_text(correct_answer)
            incorrect_answers = data['incorrect_answers']
            difficulty = data['difficulty']
            reward_mult = streaks.get(
                pld.msg.author.id) or 0 if not cat_chosen else 0
            kud_reward = int(
                (awards.get(difficulty) or '10') *
                (1 + (reward_mult * 2.25) / (1.75 + (0.03 * reward_mult))))
            choice_list = [correct_answer] + incorrect_answers
            choice_list = shuffle_questions(choice_list)
            choice_number = 0
            choice_lines = []
            for choice in choice_list:
                choice_number += 1
                choice_line = f'[{choice_number}] {choice}'
                choice_lines.append(choice_line)
            choice_text = '\n'.join(choice_lines)
            choice_text = ftfy.fix_text(choice_text)
            starter = 'An' if difficulty == 'easy' else 'A'
            question_embed = discord.Embed(color=0xF9F9F9,
                                           title='❔ Here\'s a question!')
            question_embed.description = f'{starter} {difficulty} one from the {category} category.'
            question_embed.add_field(name='Question',
                                     value=question,
                                     inline=False)
            question_embed.add_field(name='Choices',
                                     value=f'```py\n{choice_text}\n```',
                                     inline=False)
            question_embed.set_author(name=pld.msg.author.display_name,
                                      icon_url=user_avatar(pld.msg.author))
            footer_text = 'Input the number of your chosen answer.'
            if reward_mult:
                footer_text += f' | Streak: {int(reward_mult)}'
            question_embed.set_footer(text=footer_text)
            await pld.msg.channel.send(embed=question_embed)

            def check_answer(msg):
                """
                :type msg: discord.Message
                :rtype: bool
                """
                if pld.msg.channel.id != msg.channel.id:
                    return
                if pld.msg.author.id != msg.author.id:
                    return
                if msg.content.isdigit():
                    try:
                        int_content = int(msg.content)
                    except ValueError:
                        return
                    if abs(int_content) <= len(choice_lines):
                        return True
                    else:
                        return
                elif msg.content.title() in choice_list:
                    return True

            try:
                answer_message = await cmd.bot.wait_for('message',
                                                        check=check_answer,
                                                        timeout=allotted_time)
                try:
                    answer_index = int(answer_message.content) - 1
                except ValueError:
                    answer_index = None
                correct_index = get_correct_index(choice_list, correct_answer)
                if answer_index == correct_index or answer_message.content.lower(
                ) == correct_answer.lower():
                    if cat_chosen:
                        streaks.update(
                            {pld.msg.author.id: reward_mult + 0.005})
                    else:
                        streaks.update({pld.msg.author.id: reward_mult + 1})
                    await cmd.db.add_resource(answer_message.author.id,
                                              'currency', kud_reward, cmd.name,
                                              pld.msg)
                    author = answer_message.author.display_name
                    currency = cmd.bot.cfg.pref.currency
                    win_title = f'🎉 Correct, {author}, it was {correct_answer}. You won {kud_reward} {currency}!'
                    final_embed = discord.Embed(color=0x77B255,
                                                title=win_title)
                else:
                    if pld.msg.author.id in streaks:
                        streaks.pop(pld.msg.author.id)
                    lose_title = f'💣 Ooh, sorry, it was {correct_answer}...'
                    final_embed = discord.Embed(color=0x262626,
                                                title=lose_title)
                await pld.msg.channel.send(embed=final_embed)
            except asyncio.TimeoutError:
                if pld.msg.author.id in streaks:
                    streaks.pop(pld.msg.author.id)
                timeout_title = f'🕙 Time\'s up! It was {correct_answer}...'
                timeout_embed = discord.Embed(color=0x696969,
                                              title=timeout_title)
                await pld.msg.channel.send(embed=timeout_embed)
            if Ongoing.is_ongoing(cmd.name, pld.msg.author.id):
                Ongoing.del_ongoing(cmd.name, pld.msg.author.id)
        else:
            ongoing_error = GenericResponse(
                'There is already one ongoing.').error()
            await pld.msg.channel.send(embed=ongoing_error)
    except Exception:
        if Ongoing.is_ongoing(cmd.name, pld.msg.author.id):
            Ongoing.del_ongoing(cmd.name, pld.msg.author.id)
        raise
示例#21
0
async def purge(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if pld.msg.author.permissions_in(pld.msg.channel).manage_messages:
        if not Ongoing.is_ongoing(cmd.name, pld.msg.channel.id):
            Ongoing.set_ongoing(cmd.name, pld.msg.channel.id)
            pld.args = [a.lower() for a in pld.args]
            purge_images = 'attachments' in pld.args
            purge_emotes = 'emotes' in pld.args
            until_pin = 'untilpin' in pld.args
            purge_filter = None
            for i, arg in enumerate(pld.args):
                if arg.startswith('content:'):
                    purge_filter = ' '.join([arg.split(':')[1]] +
                                            pld.args[i + 1:])
                    break

            async def get_limit_and_target():
                """
                :rtype: int, discord.Member
                """
                user = cmd.bot.user
                limit = 100
                if pld.msg.mentions:
                    user = pld.msg.mentions[0]
                    if len(pld.args) == 2:
                        try:
                            limit = int(pld.args[0])
                        except ValueError:
                            limit = 100
                else:
                    if pld.args:
                        user = None
                        try:
                            limit = int(pld.args[0])
                        except ValueError:
                            limit = 100
                if until_pin:
                    channel_hist = await pld.msg.channel.history(limit=limit
                                                                 ).flatten()
                    for n, log in enumerate(channel_hist):
                        if log.pinned:
                            limit = n - 1
                if limit > 100:
                    limit = 100
                return limit, user

            count, target = await get_limit_and_target()

            def is_emotes(msg):
                """
                :type msg: discord.Message
                :rtype: bool
                """
                clean = False
                if msg.content:
                    for piece in msg.content.split():
                        piece = piece.strip()
                        # matches custom emote
                        if re.search(r'<a?:\w+:\d+>', piece):
                            clean = True
                        # matches global emote
                        elif re.search(r':\w+:', piece):
                            clean = True
                        # matches Unicode emote
                        elif len(piece) == 1 and category(piece) == 'So':
                            clean = True
                        else:
                            clean = False
                            break
                return clean

            def purge_target_check(msg):
                """
                :type msg: discord.Message
                :rtype: bool
                """
                clean = False
                if not msg.pinned:
                    if msg.author.id == target.id:
                        if purge_images:
                            if msg.attachments:
                                clean = True
                        elif purge_emotes:
                            clean = is_emotes(msg)
                        elif purge_filter:
                            if purge_filter.lower() in msg.content.lower():
                                clean = True
                        else:
                            clean = True
                return clean

            def purge_wide_check(msg):
                """
                :type msg: discord.Message
                :rtype: bool
                """
                clean = False
                if not msg.pinned:
                    if purge_images:
                        if msg.attachments:
                            clean = True
                    elif purge_emotes:
                        clean = is_emotes(msg)
                    elif purge_filter:
                        if purge_filter.lower() in msg.content.lower():
                            clean = True
                    else:
                        clean = True
                return clean

            try:
                await pld.msg.delete()
            except discord.NotFound:
                pass
            deleted = []
            # noinspection PyBroadException
            try:
                if target:
                    deleted = await pld.msg.channel.purge(
                        limit=count, check=purge_target_check)
                else:
                    deleted = await pld.msg.channel.purge(
                        limit=count, check=purge_wide_check)
            except Exception:
                pass
            response = GenericResponse(f'Deleted {len(deleted)} Messages').ok()
            log_embed = generate_log_embed(pld.msg, target, pld.msg.channel,
                                           deleted)
            await log_event(cmd.bot, pld.settings, log_embed, 'log_purges')
            if Ongoing.is_ongoing(cmd.name, pld.msg.channel.id):
                Ongoing.del_ongoing(cmd.name, pld.msg.channel.id)
            try:
                del_response = await pld.msg.channel.send(embed=response)
                await asyncio.sleep(5)
                await del_response.delete()
            except discord.NotFound:
                pass
            return
        else:
            response = GenericResponse('There is already one ongoing.').error()
    else:
        response = GenericResponse(
            'Access Denied. Manage Messages needed.').denied()
    await pld.msg.channel.send(embed=response)
示例#22
0
async def addemote(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    react_msg = None
    if pld.msg.author.guild_permissions.manage_emojis:
        if not Ongoing.is_ongoing(cmd.name, pld.msg.channel.id):
            Ongoing.set_ongoing(cmd.name, pld.msg.guild.id)
            react_embed = discord.Embed(
                color=0xF9F9F9, title='💬 React with the desired emote.')
            react_msg = await pld.msg.channel.send(embed=react_embed)

            def check_emote(reac, usr):
                same_author = usr.id == pld.msg.author.id
                same_message = reac.message.id == react_msg.id
                return same_author and same_message

            try:
                ae, _au = await cmd.bot.wait_for('reaction_add',
                                                 timeout=30,
                                                 check=check_emote)
                working_embed = discord.Embed(title='⬇️ Downloading file...',
                                              color=0x3B88C3)
                try:
                    await react_msg.edit(embed=working_embed)
                except discord.NotFound:
                    await pld.msg.channel.send(embed=working_embed)

                react_msg = await pld.msg.channel.fetch_message(react_msg.id)
                emote_to_add = None
                for reaction in react_msg.reactions:
                    if str(reaction.emoji) == str(ae):
                        emote_to_add = reaction.emoji
                        break
                if not isinstance(emote_to_add, str):
                    if pld.args and len(pld.args[0]) > 1:
                        name = pld.args[0]
                    else:
                        # noinspection PyUnresolvedReferences
                        name = emote_to_add.name

                    # noinspection PyUnresolvedReferences
                    image = await get_emote_image(str(emote_to_add.url))
                    try:
                        emote = await pld.msg.guild.create_custom_emoji(
                            name=name, image=image)
                        response = GenericResponse(
                            f'Added emote {emote.name}.').ok()
                    except discord.errors.HTTPException:
                        response = GenericResponse(
                            'File size cannot exceed 256kb.').error()
                else:
                    response = GenericResponse(
                        'Must be a custom emote.').error()
            except asyncio.TimeoutError:
                response = discord.Embed(color=0x696969,
                                         title='🕙 The message timed out.')

            if Ongoing.is_ongoing(cmd.name, pld.msg.channel.id):
                Ongoing.del_ongoing(cmd.name, pld.msg.channel.id)
        else:
            response = GenericResponse('There is already one ongoing.').error()
    else:
        response = GenericResponse(
            'Access Denied. Manage Emotes needed.').denied()
    if react_msg:
        try:
            await react_msg.edit(embed=response)
        except discord.NotFound:
            await pld.msg.channel.send(embed=response)
    else:
        await pld.msg.channel.send(embed=response)
示例#23
0
async def mathgame(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if not Ongoing.is_ongoing(cmd.name, pld.msg.channel.id):
        Ongoing.set_ongoing(cmd.name, pld.msg.channel.id)
        if pld.args:
            try:
                diff = int(pld.args[0])
                if diff < 1:
                    diff = 1
                elif diff > 9:
                    diff = 9
            except ValueError:
                diff = 3
        else:
            diff = 3
        max_num = diff * 8
        easy_operators = ['+', '-']
        hard_operators = ['*', '/']
        math_operators = easy_operators + hard_operators
        problem_string = str(secrets.randbelow(max_num))
        allotted_time = 7
        kud_reward = 2
        for x in range(0, diff):
            num = secrets.randbelow(max_num) + 1
            oper = secrets.choice(math_operators)
            if oper in easy_operators:
                kud_reward += 1
                allotted_time += 3
            else:
                kud_reward += 4
                allotted_time += 9
            problem_string += f' {oper} {num}'
        result = round(eval(problem_string), 2)
        problem_string = problem_string.replace('*', 'x').replace('/', '÷')
        question_embed = discord.Embed(
            color=0x3B88C3, title=f'#⃣  You have {allotted_time} seconds.')
        question_embed.description = f'{problem_string} = ?'
        await pld.msg.channel.send(embed=question_embed)

        def check_answer(msg):
            """
            :type msg: discord.Message
            :rtype: bool
            """
            if pld.msg.channel.id == msg.channel.id:
                try:
                    an_num = float(msg.content)
                    if an_num == result:
                        correct = True
                    else:
                        correct = False
                except ValueError:
                    correct = False
            else:
                correct = False
            return correct

        try:
            answer_message = await cmd.bot.wait_for('message',
                                                    check=check_answer,
                                                    timeout=allotted_time)
            await cmd.db.add_resource(answer_message.author.id, 'currency',
                                      kud_reward, cmd.name, pld.msg)
            author = answer_message.author.display_name
            currency = cmd.bot.cfg.pref.currency
            win_title = f'🎉 Correct, {author}, it was {result}. You won {kud_reward} {currency}!'
            win_embed = discord.Embed(color=0x77B255, title=win_title)
            await pld.msg.channel.send(embed=win_embed)
        except asyncio.TimeoutError:
            timeout_title = f'🕙 Time\'s up! It was {result}...'
            timeout_embed = discord.Embed(color=0x696969, title=timeout_title)
            await pld.msg.channel.send(embed=timeout_embed)
        if Ongoing.is_ongoing(cmd.name, pld.msg.channel.id):
            Ongoing.del_ongoing(cmd.name, pld.msg.channel.id)
    else:
        ongoing_error = GenericResponse(
            'There is already one ongoing.').error()
        await pld.msg.channel.send(embed=ongoing_error)
示例#24
0
async def cook(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    ongoing = Ongoing.is_ongoing('profession', pld.msg.author.id)
    if not ongoing:
        Ongoing.set_ongoing('profession', pld.msg.author.id)
        recipe_core = await get_recipe_core(cmd.db)
        item_core = await get_item_core(cmd.db)
        if pld.args:
            lookup = ' '.join(pld.args)
            recipe = recipe_core.find_recipe(lookup)
            used_items = []
            if recipe:
                req_satisfied = True
                for ingredient in recipe.ingredients:
                    user_inv = await cmd.db.get_inventory(pld.msg.author.id)
                    in_inventory = False
                    for item in user_inv:
                        if item['item_file_id'] == ingredient.file_id:
                            used_items.append(item)
                            in_inventory = True
                            break
                    if not in_inventory:
                        req_satisfied = False
                if req_satisfied:
                    cooked_item_data = item_core.get_item_by_name(
                        recipe.name).generate_inventory_item()
                    await cmd.db.add_to_inventory(pld.msg.author.id,
                                                  cooked_item_data)
                    await item_core.add_item_statistic(cmd.db, recipe,
                                                       pld.msg.author)
                    for req_item in used_items:
                        if req_item.get('transferred'):
                            cooked_item_data.update({'transferred': True})
                        await cmd.db.del_from_inventory(
                            pld.msg.author.id, req_item['item_id'])
                    quality = cook_quality[cooked_item_data['quality']]
                    connector = 'a'
                    if quality[0].lower() in ['a', 'e', 'i', 'o', 'u']:
                        connector = 'an'
                    await cmd.db.add_resource(pld.msg.author.id, 'items', 1,
                                              cmd.name, pld.msg, True)
                    await cmd.db.add_resource(pld.msg.author.id,
                                              recipe.type.lower(), 1, cmd.name,
                                              pld.msg, True)
                    head_title = f'{recipe.icon} You made {connector} {quality.lower()} {recipe.name}'
                    response = discord.Embed(color=recipe.color,
                                             title=head_title)
                else:
                    response = GenericResponse(
                        'You\'re missing ingredients.').error()
            else:
                response = GenericResponse('Recipe not found.').not_found()
        else:
            response = GenericResponse('Nothing inputted.').error()
        Ongoing.del_ongoing('profession', pld.msg.author.id)
    else:
        response = GenericResponse(
            "Please wait while your previous item is done being prepared."
        ).warn()
    response.set_author(name=pld.msg.author.display_name,
                        icon_url=user_avatar(pld.msg.author))
    await pld.msg.channel.send(embed=response)
示例#25
0
async def blackjack(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if not await cmd.bot.cool_down.on_cooldown(cmd.name, pld.msg.author):
        if not Ongoing.is_ongoing(cmd.name, pld.msg.channel.id):
            bet = 10
            if pld.args:
                if pld.args[0].isdigit():
                    bet = abs(int(pld.args[0]))
            currency_icon = cmd.bot.cfg.pref.currency_icon
            currency = cmd.bot.cfg.pref.currency
            author = pld.msg.author.id
            current_kud = await cmd.db.get_resource(author, 'currency')
            current_kud = current_kud.current
            if current_kud >= bet:
                Ongoing.set_ongoing(cmd.name, pld.msg.channel.id)
                await set_blackjack_cd(cmd, pld)

                bljk = BlackJack(pld.msg)
                if bljk.check_blackjack():
                    if Ongoing.is_ongoing(cmd.name, pld.msg.channel.id):
                        Ongoing.del_ongoing(cmd.name, pld.msg.channel.id)
                    await cmd.db.add_resource(author, 'currency', bet * BJ_RATIO, cmd.name, pld.msg, False)
                    title = f'🎉 You got a BlackJack and won {int(bet * BJ_RATIO)} {currency}!'
                    bj_embed = discord.Embed(color=0xDE2A42, title=title)
                    bj_embed.set_footer(text=f'You won {int(100 * BJ_RATIO)}% of your original bet.')
                    await pld.msg.channel.send(embed=bj_embed)
                    return

                game_embed = bljk.generate_embed()
                game_msg = await pld.msg.channel.send(embed=game_embed)
                [await game_msg.add_reaction(e) for e in GAME_EMOTES]

                def check_emote(reac):
                    """
                    Checks for a valid message reaction.
                    :type reac: discord.RawReactionActionEvent
                    :rtype: bool
                    """
                    same_author = reac.user_id == pld.msg.author.id
                    same_message = reac.message_id == game_msg.id
                    valid_reaction = str(reac.emoji) in GAME_EMOTES
                    return same_author and same_message and valid_reaction

                finished, bust, win = False, False, False
                while not finished and not bust and not win:
                    try:
                        ae = await cmd.bot.wait_for('raw_reaction_add', timeout=60, check=check_emote)
                        # noinspection PyBroadException
                        try:
                            await game_msg.remove_reaction(ae.emoji, pld.msg.author)
                        except Exception:
                            pass
                        if str(ae.emoji) == '🔵':
                            game_msg = await bljk.add_card(game_msg)
                            finished = bljk.check_bust()
                        elif str(ae.emoji) == '🔴':
                            finished = True
                        elif str(ae.emoji) == '⏫':
                            if len(bljk.player_hand) == 2:
                                if current_kud >= bet * 2:
                                    bet += bet
                                    game_msg = await bljk.add_card(game_msg)
                                    finished = True
                                else:
                                    embed = bljk.generate_embed()
                                    embed.set_footer(text=f'Insufficient {currency} to double down.')
                                    game_msg = await send_game_msg(pld.msg.channel, game_msg, embed)
                            else:
                                embed = bljk.generate_embed()
                                embed.set_footer(text='You can only double down on your first turn.')
                                game_msg = await send_game_msg(pld.msg.channel, game_msg, embed)
                    except asyncio.TimeoutError:
                        if Ongoing.is_ongoing(cmd.name, pld.msg.channel.id):
                            Ongoing.del_ongoing(cmd.name, pld.msg.channel.id)
                        await cmd.db.del_resource(pld.msg.author.id, 'currency', bet, cmd.name, pld.msg)
                        timeout_title = f'🕙 Time\'s up {pld.msg.author.display_name}!'
                        timeout_embed = discord.Embed(color=0x696969, title=timeout_title)
                        timeout_embed.set_footer(text=f'You lost {bet} {currency}.')
                        await pld.msg.channel.send(embed=timeout_embed)
                        return
                await bljk.dealer_hit(game_msg)
                if bljk.check_bust():
                    await cmd.db.del_resource(pld.msg.author.id, 'currency', bet, cmd.name, pld.msg)
                    title = f'💣 Your hand bust and you lost {bet} {currency}.'
                    response = discord.Embed(color=0x232323, title=title)
                elif bljk.check_dealer_bust():
                    await cmd.db.add_resource(pld.msg.author.id, 'currency', bet, cmd.name, pld.msg, False)
                    title = f'{currency_icon} The dealer bust and you won {bet} {currency}!'
                    response = discord.Embed(color=0x66cc66, title=title)
                elif bljk.check_push():
                    title = '🔵 You pushed and broke even.'
                    response = discord.Embed(color=0x3B88C3, title=title)
                elif bljk.check_win():
                    await cmd.db.add_resource(pld.msg.author.id, 'currency', bet, cmd.name, pld.msg, False)
                    title = f'{currency_icon} You beat the dealer and won {bet} {currency}!'
                    response = discord.Embed(color=0x66cc66, title=title)
                else:
                    await cmd.db.del_resource(pld.msg.author.id, 'currency', bet, cmd.name, pld.msg)
                    title = f'💣 The dealer won and you lost {bet} {currency}.'
                    response = discord.Embed(color=0x232323, title=title)
                if Ongoing.is_ongoing(cmd.name, pld.msg.channel.id):
                    Ongoing.del_ongoing(cmd.name, pld.msg.channel.id)
            else:
                response = discord.Embed(color=0xa7d28b, title=f'💸 You don\'t have {bet} {currency}.')
        else:
            response = GenericResponse('There is already one ongoing.').error()
    else:
        timeout = await cmd.bot.cool_down.get_cooldown(cmd.name, pld.msg.author)
        response = discord.Embed(color=0x696969, title=f'🕙 You can play again in {timeout} seconds.')
    await pld.msg.channel.send(embed=response)