Exemple #1
0
 async def from_data(cls, bot, data):
     if data['location'].startswith('gym/'):
         loc_id = data['location'].split('/', maxsplit=1)[1]
         location = Gym(bot, int(loc_id))
     elif data['location'].startswith('pokestop/'):
         loc_id = data['location'].split('/', maxsplit=1)[1]
         location = Pokestop(bot, int(loc_id))
     else:
         city, arg = data['location'].split('/', maxsplit=1)
         location = PartialPOI(bot, city, arg)
     guild_id = data['guild']
     pkmn_id = data['pkmn']
     pkmn = Pokemon(bot, pkmn_id)
     wild_id = data['id']
     caught_by = data.get('caught_by', [])
     reporter_id = data.get('reporter_id')
     wild = cls(wild_id,
                bot,
                guild_id,
                reporter_id,
                location,
                pkmn,
                caught_by=caught_by)
     wild.message_ids = data['messages']
     for idstring in wild.message_ids:
         Wild.by_message[idstring] = wild
     wild.created = data['created']
     wild.monitor_task = bot.loop.create_task(wild.monitor_status())
     return wild
Exemple #2
0
 async def from_mod(cls, mod: Rocket):
     name = mod.name
     if isinstance(mod.location, Pokestop):
         directions_url = await mod.location.url()
         directions_text = await mod.location._name()
     else:
         directions_url = mod.location.url
         directions_text = mod.location._name + " (Unknown Location)"
     fields = {}
     if hasattr(mod, 'pokemon'):
         pkmn = [Pokemon(mod.bot, x) for x in mod.pokemon]
         pkmn_names = [await x.name() for x in pkmn]
         fields['Pokemon'] = "\n".join(pkmn_names)
     fields['Location'] = f'[{directions_text}]({directions_url})'
     img_url = mod.img_url()
     reporter = mod.guild.get_member(mod.reporter_id)
     if not reporter:
         reporter = await mod.guild.fetch_member(mod.reporter_id)
     reporter = reporter.display_name
     footer = f"Reported by {reporter}"
     reportdt = datetime.fromtimestamp(mod.created)
     color = mod.guild.me.color
     embed = formatters.make_embed(title=f"{name} Report",
                                   msg_colour=color,
                                   thumbnail=img_url,
                                   fields=fields,
                                   footer=footer)
     embed.timestamp = reportdt
     return cls(embed)
Exemple #3
0
 def from_data(cls, bot, data):
     guild_id = data['guild_id']
     lister_id = data['lister_id']
     listing_id = data['listing_id']
     offered_pokemon = [
         Pokemon.from_dict(bot, eval(x)) for x in data['offers']
     ]
     wanted_pokemon = []
     for want in data['wants']:
         want = eval(want)
         if want in ['obo', 'any']:
             continue
         want = Pokemon.from_dict(bot, want)
         wanted_pokemon.append(want)
     if 'any' in data['wants']:
         wanted_pokemon.append('any')
     if 'obo' in data['wants']:
         wanted_pokemon.append('obo')
     offer_list = []
     if data['offer_list']:
         offer_list_data = [eval(x) for x in data['offer_list']]
         for x in offer_list_data:
             listed = Pokemon.from_dict(bot, x['listed'])
             if isinstance(x['offered'], dict):
                 offered = Pokemon.from_dict(bot, x['offered'])
             else:
                 offered = x['offered']
             trader_id = x['trader']
             msg = x['msg']
             d = {
                 'trader': trader_id,
                 'listed': listed,
                 'offered': offered,
                 'msg': msg
             }
             offer_list.append(d)
     trade_id = data['id']
     new_trade = cls(trade_id, bot, guild_id, lister_id, listing_id,
                     offered_pokemon, wanted_pokemon)
     new_trade.offer_list = offer_list
     cls.by_listing[listing_id] = new_trade
     for offer in offer_list:
         cls.by_offer[offer['msg']] = new_trade
     return new_trade
Exemple #4
0
 async def get_wants(self):
     wants = []
     if hasattr(self, 'pokemon'):
         pkmn = [Pokemon(self.bot, x) for x in self.pokemon]
         families = [await x._familyId() for x in pkmn]
         families = list(set(families))
         for f in families:
             wants.append(Want(self.bot, f, self.guild_id))
     wants.append(Want(self.bot, self.kind, self.guild_id))
     return wants
Exemple #5
0
    async def from_research(cls, research):
        bot = research.bot
        task = research.task
        location = research.location
        reward = research.reward

        if isinstance(task, Task):
            task = task.id
        else:
            task = task.id.split('/', 1)[1]

        if '/' in reward:
            reward = ItemReward(research.bot, reward)
            desc = await reward.description()
            thumbnail = reward.img_url
        elif reward == 'unknown_encounter':
            desc = "Unknown Encounter"
            thumbnail = ("https://raw.githubusercontent.com/"
                "FoglyOgly/Meowth/new-core/meowth/images/misc/unknown_encounter.png")
        else:
            pkmn = Pokemon(bot, reward)
            desc = await pkmn.name()
            if await pkmn._shiny_available():
                desc += " :sparkles:"
            type_emoji = await pkmn.type_emoji()
            desc += f" {type_emoji}"
            thumbnail = await pkmn.sprite_url()

        if isinstance(location, POI):
            directions_url = await location.url()
            directions_text = await location._name()
        else:
            directions_url = location.url
            directions_text = location._name + " (Unknown Pokestop)"
        
        title = "Field Research Report"
        fields = {
            'Pokestop': f"[{directions_text}]({directions_url})",
            'Task': task,
            'Reward': desc + "\n<:silph:548259248442703895>Research tasks and rewards provided by [The Silph Road](https://thesilphroad.com/research-tasks)"
        }
        reporter = research.guild.get_member(research.reporter_id)
        if not reporter:
            reporter = await research.guild.fetch_member(research.reporter_id)
        color = research.guild.me.color
        reporter_name = reporter.display_name
        reporter_avy = reporter.avatar_url
        footer = f"Reported by {reporter_name} • Expires"
        icon_url = ("https://raw.githubusercontent.com/"
                "FoglyOgly/Meowth/new-core/meowth/images/misc/field-research.png")
        embed = formatters.make_embed(title=title, thumbnail=thumbnail,
            fields=fields, footer=footer, footer_icon=reporter_avy, icon=icon_url, msg_colour=color)
        embed.timestamp = datetime.utcfromtimestamp(research.expires_at)
        return cls(embed)
Exemple #6
0
 async def get_wants(self):
     wants = []
     reward = self.reward
     if reward.startswith('partial'):
         return wants
     elif '/' in reward:
         reward = ItemReward(self.bot, reward)
         item = reward.item
         wants.append(item.id)
     elif reward == 'unknown_encounter':
         return wants
     else:
         pkmn = Pokemon(self.bot, reward)
         family = await pkmn._familyId()
         wants.append(family)
     wants = [Want(self.bot, x, self.guild_id) for x in wants]
     want_dict = {x: await x.mention() for x in wants}
     return want_dict
Exemple #7
0
    async def summary_str(self):
        task = self.task
        reward = self.reward
        location = self.location
        if '/' in reward:
            reward = ItemReward(self.bot, reward)
            desc = await reward.description()
        elif reward == 'unknown_encounter':
            desc = "Unknown Encounter"
        else:
            pkmn = Pokemon(self.bot, reward)
            desc = await pkmn.name()
            if await pkmn._shiny_available():
                desc += " :sparkles:"
            type_emoji = await pkmn.type_emoji()
            desc += f" {type_emoji}"
        
        if isinstance(task, Task):
            task = task.id
        else:
            task = task.id.split('/', 1)[1]
        
        if isinstance(location, POI):
            directions_url = await location.url()
            directions_text = await location._name()
            if len(directions_text) > 25:
                directions_text = directions_text[:25] + "..."
        else:
            directions_url = location.url
            name = location._name
            if len(name) > 25:
                name = name[:25] + "..."
            directions_text = name + " (Unknown Pokestop)"

        summary_str = f"• Reward: {desc} • Task: {task} • Location: [{directions_text}]({directions_url})"
        return summary_str
Exemple #8
0
 async def research(self, ctx, reward: Optional[Union[Pokemon, ItemReward]], task: Optional[Task], *, location: Pokestop):
     """Report a Field Research task.
     
     **Arguments**
     *reward (optional):* Description of the reward for the research. Either
         a Pokemon or an item.
     *task (optional):* Either the text of the research task itself or
         the research category (e.g. `raid`). If a conversion to a Task cannot
         be made, Meowth asks you to select a category, then to select the
         specific task.
     *location:* Name of the Pokestop where the Field Research can be found.
     
     Meowth will automatically expire the research at midnight local time.
     The reporter will be awarded points for the number of users that obtain
     the task."""
     tz = await ctx.tz()
     if reward and not task:
         task_matches = await self.possible_tasks(reward.id)
         if len(task_matches) == 1:
             task = Task(ctx.bot, task_matches[0])
         elif len(task_matches) > 1:
             react_list = formatters.mc_emoji(len(task_matches))
             display_dict = dict(zip(react_list, task_matches))
             display_dict["\u2754"] = "Other"
             react_list.append("\u2754")
             embed = formatters.mc_embed(display_dict)
             multi = await ctx.send('Multiple possible Tasks found! Please select from the following list.',
                 embed=embed)
             payload = await formatters.ask(ctx.bot, [multi], user_list=[ctx.author.id],
                 react_list=react_list)
             if not payload:
                 try:
                     return await multi.delete()
                 except:
                     return
             task = display_dict[str(payload.emoji)]
             if task == 'Other':
                 otherask = await ctx.send('What is the Task for this Research? Please type your answer below.')
                 def check(m):
                     return m.author == ctx.author and m.channel == ctx.channel
                 reply = await ctx.bot.wait_for('message', check=check)
                 arg = reply.content
                 try:
                     await reply.delete()
                     await otherask.delete()
                 except:
                     pass
                 task = PartialTask(ctx.bot, arg)
             else:
                 task = Task(ctx.bot, task)
             try:
                 await multi.delete()
             except:
                 pass
     if not task:
         cats = await self.task_categories()
         content = "What category of Research Task is this? Select from the options below."
         react_list = formatters.mc_emoji(len(cats))
         cat_dict = dict(zip(react_list, cats))
         embed = formatters.mc_embed(cat_dict)
         multi = await ctx.send(content, embed=embed)
         payload = await formatters.ask(ctx.bot, [multi], user_list=[ctx.author.id], react_list=react_list)
         if not payload:
             try:
                 return await multi.delete()
             except:
                 return
         cat = cat_dict[str(payload.emoji)]
         try:
             await multi.delete()
         except:
             pass
         task = await Task.convert(ctx, cat, require_task=True)
     if isinstance(task, Task) and not reward:
         possible_rewards = await task.possible_rewards()
         if len(possible_rewards) == 1:
             reward = possible_rewards[0]
         else:
             react_list = formatters.mc_emoji(len(possible_rewards))
             item_dict = {}
             pkmn_dict = {}
             for reward in possible_rewards:
                 if '/' in reward:
                     obj = ItemReward(ctx.bot, reward)
                     desc = await obj.description()
                     item_dict[desc] = reward
                 else:
                     pkmn = Pokemon(ctx.bot, reward)
                     name = await pkmn.name()
                     pkmn_dict[name] = reward
             reward_dict = dict(pkmn_dict, **item_dict)
             if len(pkmn_dict) > 1:
                 react_list = formatters.mc_emoji(len(possible_rewards)+1)
                 reward_dict['Unknown Encounter'] = 'unknown_encounter'
             choice_dict = dict(zip(react_list, reward_dict.values()))
             display_dict = dict(zip(react_list, reward_dict.keys()))
             embed = formatters.mc_embed(display_dict)
             embed.fields[0].value = embed.fields[0].value + "\n<:silph:548259248442703895>Research tasks and rewards provided by [The Silph Road](https://thesilphroad.com/research-tasks)"
             multi = await ctx.send('What is the reward for this task? Please select from the options below.',
                 embed=embed)
             payload = await formatters.ask(ctx.bot, [multi], user_list=[ctx.author.id],
                 react_list=react_list)
             if not payload:
                 try:
                     return await multi.delete()
                 except:
                     return
             reward = choice_dict[str(payload.emoji)]
             try:
                 await multi.delete()
             except:
                 pass
     elif not reward:
         msg = await ctx.send('What is the reward for this Research? Please type your response below.')
         def check(m):
             return m.author == ctx.author and m.channel == ctx.channel
         reply = await ctx.bot.wait_for('message', check=check)
         try:
             reward = await Pokemon.convert(ctx, reply.content)
         except:
             reward = None
         if not reward:
             try:
                 reward = await ItemReward.convert(ctx, reply.content)
             except:
                 reward = ItemReward(ctx.bot, f'partial/{reply.content}/1')
         try:
             await reply.delete()
             await msg.delete()
         except:
             pass
     if not isinstance(reward, str):
         reward = reward.id
     research_id = next(snowflake.create())
     research = Research(research_id, ctx.bot, ctx.guild.id, ctx.author.id, task, location, reward, tz, time.time())
     embed = await ResearchEmbed.from_research(research)
     embed = embed.embed
     wants = await research.get_wants()
     mentions = [wants.get(x) for x in wants if wants.get(x)]
     mention_str = "\u200b".join(mentions)
     if mention_str:
         reportcontent = mention_str + " - "
     else:
         reportcontent = ""
     stamp = ctx.bot.get_emoji(583375171847585823)
     map_icon = ctx.bot.get_emoji(597185467217346602)
     reportcontent += f"Field Research reported! Use {str(stamp)} to indicate that you picked up this task!"
     report_channels = []
     report_channel = ReportChannel(ctx.bot, ctx.channel)
     msgs = []
     if isinstance(location, Pokestop):
         research_table = ctx.bot.dbi.table('research')
         query = research_table.query()
         query.where(location=str(location.id), guild_id=ctx.guild.id)
         old_research = await query.get()
         if old_research:
             return await ctx.send("There is already a research task reported at this pokéstop!", delete_after=20)
         channel_list = await location.get_all_channels('research')
         report_channels.extend(channel_list)
     if report_channel not in report_channels:
         report_channels.append(report_channel)
     stamp = ctx.bot.get_emoji(583375171847585823)
     for channel in report_channels:
         try:
             msg = await channel.channel.send(reportcontent, embed=embed)
             await msg.add_reaction("\U0001F4DD")  # Task emoji
             await msg.add_reaction(map_icon)
             await msg.add_reaction(stamp)
         except:
             continue
         idstring = f'{msg.channel.id}/{msg.id}'
         msgs.append(idstring)
         Research.by_message[idstring] = research
     research.message_ids = msgs
     await research.upsert()
     ctx.bot.loop.create_task(research.monitor_status())
Exemple #9
0
    async def on_raw_reaction_add(self, payload):
        idstring = f"{payload.channel_id}/{payload.message_id}"
        chn, msg = await ChannelMessage.from_id_string(self.bot, idstring)
        research = Research.by_message.get(idstring)
        if not research or payload.user_id == self.bot.user.id:
            return
        user = payload.member
        if payload.emoji.is_custom_emoji():
            emoji = payload.emoji.id
            if isinstance(emoji, int):
                emoji = self.bot.get_emoji(emoji)
            await msg.remove_reaction(emoji, user)
            if emoji.id == 583375171847585823:
                if payload.user_id not in research.completed_by:
                    research.completed_by.append(payload.user_id)
                if research.reward == 'unknown_encounter':
                    if isinstance(research.task, Task):
                        possible_rewards = await research.task.possible_rewards()
                        pkmn_rewards = [x for x in possible_rewards if '/' not in x]
                        pkmn = [Pokemon(self.bot, x) for x in pkmn_rewards]
                        pkmn_dict = {await x.name(): x.id for x in pkmn}
                        react_list = formatters.mc_emoji(len(pkmn))
                        choice_dict = dict(zip(react_list, pkmn_dict.values()))
                        display_dict = dict(zip(react_list, pkmn_dict.keys()))
                        embed = formatters.mc_embed(display_dict)
                        embed.fields[0].value = embed.fields[0].value + "\n<:silph:548259248442703895>Research tasks and rewards provided by [The Silph Road](https://thesilphroad.com/research-tasks)"
                        multi = await chn.send(f"{user.mention}: What is the reward for this task? Please select from the options below. If you don't know, just ignore this!",
                            embed=embed)
                        payload = await formatters.ask(self.bot, [multi], user_list=[user.id],
                            react_list=react_list)
                        if not payload:
                            return await multi.delete()
                        reward = choice_dict[str(payload.emoji)]
                        try:
                            await multi.delete()
                        except:
                            pass
                        research.reward = reward
            elif emoji.id == 597185467217346602:
                askmsg = await chn.send(f"{user.mention}: Where is this Research located? Please type your response below. If you send a plain text response, I will check it against the Pokestops I know about. You can also send a Google Maps link!")

                def check(m):
                    return m.author == user and m.channel == chn
                reply = await self.bot.wait_for('message', check=check)
                try:
                    await askmsg.delete()
                    await reply.delete()
                except discord.HTTPException:
                    pass
                url_re = '(http(s?)://)?((maps\.google\./)|((www\.)?google\.com/maps/)|(goo.gl/maps/))\S*'
                match = re.search(url_re, reply.content)
                if match:
                    url = match.group()
                    return await research.update_url(url)
                else:
                    ctx = await self.bot.get_context(reply, cls=Context)
                    stop = await Pokestop.convert(ctx, reply.content)
                    research.location = stop
        else:
            emoji = str(payload.emoji)
            await msg.remove_reaction(emoji, user)
            if emoji == '\U0001F4DD':
                askmsg = await chn.send(f"{user.mention}: What Research task is located here? Please type your response below.")

                def check(m):
                    return m.author == user and m.channel == chn
                try:
                    reply = await self.bot.wait_for('message', check=check, timeout=300)
                except asyncio.TimeoutError:
                    return
                try:
                    await askmsg.delete()
                    await reply.delete()
                except discord.HTTPException:
                    pass
                ctx = await self.bot.get_context(reply, cls=Context)
                task = await Task.convert(ctx, reply.content, require_task=True)
                research.task = task

        embed = await ResearchEmbed.from_research(research)
        for msgid in research.message_ids:
            try:
                chn, msg = await ChannelMessage.from_id_string(self.bot, msgid)
                await msg.edit(embed=embed.embed)
            except discord.HTTPException:
                pass
        return await research.upsert()