async def delete_location(ctx, location_type, name):
     channel = ctx.channel
     guild = ctx.guild
     deleted = 0
     with KyogreDB._db.atomic() as txn:
         try:
             locationresult = (
                 LocationTable.get((LocationTable.guild == guild.id)
                                   & (LocationTable.name == name)))
             location = LocationTable.get_by_id(locationresult)
             TrainerReportRelation.update(location=None)\
                 .where(TrainerReportRelation.location == location.id).execute()
             loc_reg = (LocationRegionRelation.get(
                 LocationRegionRelation.location_id == locationresult))
             if location_type == "stop":
                 deleted = PokestopTable.delete().where(
                     PokestopTable.location_id == locationresult).execute()
             elif location_type == "gym":
                 deleted = GymTable.delete().where(
                     GymTable.location_id == locationresult).execute()
             deleted += LocationRegionRelation.delete().where(
                 LocationRegionRelation.id == loc_reg).execute()
             deleted += location.delete_instance()
             txn.commit()
         except Exception as e:
             await channel.send(e)
             txn.rollback()
     return deleted
Beispiel #2
0
 async def _update_db_research_report(self, guild, message, updated):
     report, report_relation = None, None
     try:
         report_relation = TrainerReportRelation.get(
             TrainerReportRelation.message == message.id)
         report = ResearchTable.get(
             ResearchTable.trainer_report_id == report_relation.id)
     except Exception as e:
         self.bot.logger.info(
             f"Failed to update research table entry with error: {e}")
     if report is None or report_relation is None:
         return self.bot.logger.info(
             f"No Research report found in db to update. Message id: {message.id}"
         )
     quest_dict = self.bot.guild_dict[guild.id]['questreport_dict'].get(
         message.id, None)
     if quest_dict is None:
         return self.bot.logger.info(
             f"No quest_dict found in guild_dict. "
             f"Cannot update research report. Message id: {message.id}")
     report.quest_id = quest_dict['quest_id']
     report.reward = quest_dict['reward']
     report.save()
     report_relation.location_id = quest_dict['location_id']
     report_relation.updated = updated
     report_relation.save()
Beispiel #3
0
 async def _cancel_db_research_report(self, message):
     try:
         report_relation = TrainerReportRelation.get(
             TrainerReportRelation.message == message.id)
     except Exception as e:
         return self.bot.logger.info(
             f"Failed to cancel research table entry with error: {e}")
     report_relation.cancelled = 'True'
     report_relation.save()
Beispiel #4
0
 async def cancel_and_delete(ctx, i):
     report = TrainerReportRelation.get_by_id(i)
     report.cancelled = True
     report.save()
     message_id = report.message
     message = await ctx.channel.fetch_message(message_id)
     try:
         await message.delete()
     except (discord.errors.Forbidden, discord.errors.HTTPException):
         pass
Beispiel #5
0
 async def _add_db_sighting_report(self, ctx, message):
     channel = ctx.channel
     guild = channel.guild
     author = ctx.author
     wild_dict = self.bot.guild_dict[guild.id]['wildreport_dict'][message.id]
     created = round(message.created_at.timestamp())
     __, __ = GuildTable.get_or_create(snowflake=guild.id)
     __, __ = TrainerTable.get_or_create(snowflake=author.id, guild=guild.id)
     report = TrainerReportRelation.create(created=created, trainer=author.id,
                                           location=wild_dict['location_id'], message=message.id)
     try:
         SightingTable.create(trainer_report=report, pokemon=wild_dict['pokemon_id'])
     except Exception as e:
         self.bot.logger.info(f"Failed to create sighting table entry with error: {e}")
Beispiel #6
0
 async def _check_existing(stop):
     epoch = datetime.datetime(1970, 1, 1)
     day_start = datetime.datetime.utcnow().replace(hour=6,
                                                    minute=0,
                                                    second=0,
                                                    microsecond=0)
     day_end = datetime.datetime.utcnow().replace(hour=22,
                                                  minute=0,
                                                  second=0,
                                                  microsecond=0)
     day_start = (day_start - epoch).total_seconds()
     day_end = (day_end - epoch).total_seconds()
     result = (TrainerReportRelation.select(
         TrainerReportRelation.id, TrainerReportRelation.created,
         LocationTable.id.alias('location_id'),
         LocationTable.name.alias('location_name'),
         HideoutTable.rocket_leader.alias('leader'),
         HideoutTable.first_pokemon, HideoutTable.second_pokemon,
         HideoutTable.third_pokemon, LocationTable.latitude,
         LocationTable.longitude, TrainerReportRelation.message,
         TrainerReportRelation.trainer).join(
             LocationTable,
             on=(TrainerReportRelation.location_id == LocationTable.id)
         ).join(
             LocationRegionRelation,
             on=(LocationTable.id == LocationRegionRelation.location_id)
         ).join(
             RegionTable,
             on=(RegionTable.id == LocationRegionRelation.region_id)).join(
                 HideoutTable,
                 on=(TrainerReportRelation.id ==
                     HideoutTable.trainer_report_id)).
               where((LocationTable.name == stop.name)
                     & (TrainerReportRelation.created > day_start)
                     & (TrainerReportRelation.created < day_end)
                     & (TrainerReportRelation.cancelled == False)).order_by(
                         TrainerReportRelation.created))
     results = result.objects(HideoutInstance)
     if len(results) > 0:
         return result.objects(HideoutInstance)[0]
     return None
Beispiel #7
0
 async def _add_db_research_report(self, ctx, message):
     channel = ctx.channel
     guild = channel.guild
     author = ctx.author
     quest_dict = self.bot.guild_dict[guild.id]['questreport_dict'][
         message.id]
     created = round(message.created_at.timestamp())
     __, __ = GuildTable.get_or_create(snowflake=guild.id)
     __, __ = TrainerTable.get_or_create(snowflake=author.id,
                                         guild=guild.id)
     report = TrainerReportRelation.create(
         created=created,
         trainer=author.id,
         location=quest_dict['location_id'],
         message=message.id)
     try:
         ResearchTable.create(trainer_report=report,
                              quest=quest_dict['quest_id'],
                              reward=quest_dict['reward'])
     except Exception as e:
         self.bot.logger.info(
             f"Failed to create research table entry with error: {e}")
Beispiel #8
0
 def get_single_hideout(report_id):
     result = (TrainerReportRelation.select(
         TrainerReportRelation.id, TrainerReportRelation.created,
         LocationTable.id.alias('location_id'),
         LocationTable.name.alias('location_name'),
         HideoutTable.rocket_leader.alias('leader'),
         HideoutTable.first_pokemon, HideoutTable.second_pokemon,
         HideoutTable.third_pokemon, LocationTable.latitude,
         LocationTable.longitude, TrainerReportRelation.message,
         TrainerReportRelation.trainer).join(
             LocationTable,
             on=(TrainerReportRelation.location_id == LocationTable.id)
         ).join(
             LocationRegionRelation,
             on=(LocationTable.id == LocationRegionRelation.location_id)
         ).join(
             RegionTable,
             on=(RegionTable.id == LocationRegionRelation.region_id)).join(
                 HideoutTable,
                 on=(TrainerReportRelation.id ==
                     HideoutTable.trainer_report_id)).where(
                         TrainerReportRelation.id == report_id))
     return result.objects(HideoutInstance)[0]
Beispiel #9
0
 async def _lure(self, ctx, type, *, location):
     """**Usage**: `!lure <type> <location>`
     Location should be the name of a Pokestop.
     Valid lure types are: normal, glacial, mossy, magnetic"""
     content = f"{type} {location}"
     message = ctx.message
     guild = message.guild
     channel = message.channel
     author = message.author
     location_matching_cog = self.bot.cogs.get('LocationMatching')
     subscriptions_cog = self.bot.cogs.get('Subscriptions')
     if len(content.split()) <= 1:
         self.bot.help_logger.info(
             f"User: {ctx.author.name}, channel: {ctx.channel}, error: Insufficient info."
         )
         return await channel.send(embed=discord.Embed(
             colour=discord.Colour.red(),
             description=
             'Give more details when reporting! Usage: **!lure <type> <location>**'
         ))
     report_time = message.created_at + datetime.timedelta(
         hours=self.bot.guild_dict[
             guild.id]['configure_dict']['settings']['offset'])
     report_time_int = round(report_time.timestamp())
     timestamp = report_time.strftime('%Y-%m-%d %H:%M:%S')
     luretype = content.split()[0].strip(',')
     pokestop = ' '.join(content.split()[1:])
     query = LureTypeTable.select()
     if id is not None:
         query = query.where(LureTypeTable.name == luretype)
     query = query.execute()
     result = [d for d in query]
     if len(result) != 1:
         self.bot.help_logger.info(
             f"User: {ctx.author.name}, channel: {ctx.channel}, error: Lure type: {luretype} not found."
         )
         return await channel.send(embed=discord.Embed(
             colour=discord.Colour.red(),
             description=
             'Unable to find the lure type provided, please try again.'))
     luretype = result[0]
     utils_cog = self.bot.cogs.get('Utilities')
     lure_regions = utils_cog.get_channel_regions(channel, 'lure')
     stops = location_matching_cog.get_stops(guild.id, lure_regions)
     if stops:
         stop = await location_matching_cog.match_prompt(
             channel, author.id, pokestop, stops)
         if not stop:
             self.bot.help_logger.info(
                 f"User: {ctx.author.name}, channel: {ctx.channel}, error: Pokestop not found with name: {pokestop}."
             )
             return await channel.send(embed=discord.Embed(
                 colour=discord.Colour.red(),
                 description="Unable to find that Pokestop. "
                 "Please check the name and try again!"))
     report = TrainerReportRelation.create(guild=ctx.guild.id,
                                           created=report_time_int,
                                           trainer=author.id,
                                           location=stop.id)
     lure = LureTable.create(trainer_report=report)
     LureTypeRelation.create(lure=lure, type=luretype)
     lure_embed = discord.Embed(
         title=
         f'Click here for my directions to the {luretype.name.capitalize()} lure!',
         description=
         f"Ask {author.display_name} if my directions aren't perfect!",
         url=stop.maps_url,
         colour=discord.Colour.purple())
     lure_embed.set_footer(text='Reported by {author} - {timestamp}'.format(
         author=author.display_name, timestamp=timestamp),
                           icon_url=author.avatar_url_as(
                               format=None, static_format='jpg', size=32))
     lurereportmsg = await channel.send(
         f'**{luretype.name.capitalize()}** lure reported by '
         f'{author.display_name} at {stop.name}',
         embed=lure_embed)
     listmgmt_cog = self.bot.cogs.get('ListManagement')
     await listmgmt_cog.update_listing_channels(guild,
                                                'lure',
                                                edit=False,
                                                regions=lure_regions)
     details = {
         'regions': lure_regions,
         'type': 'lure',
         'lure_type': luretype.name,
         'location': stop
     }
     send_channel = subscriptions_cog.get_region_list_channel(
         guild, stop.region, 'lure')
     if send_channel is None:
         send_channel = message.channel
     await subscriptions_cog.send_notifications_async(
         'lure', details, send_channel, [message.author.id])
     self.bot.event_loop.create_task(
         self.lure_expiry_check(lurereportmsg, report.id))
     clean_list = self.bot.guild_dict[
         ctx.guild.id]['configure_dict'].setdefault('channel_auto_clean',
                                                    [])
     if ctx.channel.id in clean_list:
         await ctx.message.delete()
Beispiel #10
0
    async def _invasion(self, ctx, *, info=None):
        """**Usage**: `!rocket <pokestop name> [,rocket leader, pokemon names]`

        Report a Team Rocket Leader invasion at a pokestop!.
        Rocket Leader and their Pokemon Lineup are optional and can be updated later."""
        message = ctx.message
        channel = message.channel
        author = message.author
        guild = message.guild
        info = re.split(r',+\s+', info)
        stopname = info[0]
        report_time = message.created_at + \
                      datetime.timedelta(hours=self.bot.guild_dict[guild.id]['configure_dict']['settings']['offset'])
        epoch = datetime.datetime(1970, 1, 1)
        report_time_int = (report_time - epoch).total_seconds()
        utilities_cog = self.bot.cogs.get('Utilities')
        subscriptions_cog = self.bot.cogs.get('Subscriptions')
        location_matching_cog = self.bot.cogs.get('LocationMatching')
        utils_cog = self.bot.cogs.get('Utilities')
        regions = utils_cog.get_channel_regions(channel, 'hideout')
        stops = location_matching_cog.get_stops(guild.id, regions)
        stop = await location_matching_cog.match_prompt(
            channel, author.id, stopname, stops)
        if not stop:
            self.bot.help_logger.info(
                f"User: {ctx.author.name}, channel: {ctx.channel}, error: No Pokestop found {stopname}."
            )
            return await channel.send(embed=discord.Embed(
                colour=discord.Colour.red(),
                description=f"No pokestop found with name '**{stopname}**' "
                f"either. Try reporting again using the exact pokestop name!"),
                                      delete_after=15)
        existing = await self._check_existing(stop)
        if existing:
            if existing.leader and existing.second_pokemon and existing.third_pokemon:
                return await channel.send(embed=discord.Embed(
                    colour=discord.Colour.red(),
                    description=
                    f"Hideout for **{stop.name}** has been completely reported already."
                ),
                                          delete_after=15)
        if not existing:
            existing = HideoutInstance(None, report_time_int, stop.id,
                                       stop.name, None, None, None, None,
                                       stop.latitude, stop.longitude,
                                       message.id, message.author.id)
        regions = [stop.region]
        leader = None
        pokemon_names = [None]
        pokemon_ids = [None]
        # Check through all the info sent in, pull out any leader names and pokemon names we find
        if len(info) > 1:
            for i in info[1:]:
                # if we find a leader name then we can also set the first pokemon
                # this assumption may change in the future
                if i.lower() in self.leader_strings:
                    leader = i
                    p_id = self.leader_map[leader.lower()]
                    pkmn = Pokemon.get_pokemon(self.bot, p_id)
                    pokemon_names[0] = pkmn.name
                    pokemon_ids[0] = pkmn.id
                else:
                    pkmn = Pokemon.get_pokemon(self.bot, i)
                    if pkmn is not None:
                        # if the name found is the one already known to be in the first slot then ignore
                        if pkmn.id not in self.leader_map.values():
                            pokemon_names.append(pkmn.name)
                            pokemon_ids.append(pkmn.id)
        # pad the id and names lists
        if len(pokemon_names) < 3:
            pokemon_names = (pokemon_names + 3 * [None])[:3]
        if len(pokemon_ids) < 3:
            pokemon_ids = (pokemon_ids + 3 * [None])[:3]
        # if there was a pre-existing report, make sure not to override leader set before
        if existing.leader:
            if leader and leader != existing.leader:
                await channel.send(
                    f"**{existing.leader.capitalize()}** has already been reported for **{stop.name}**.",
                    delete_after=30)
            leader = existing.leader
            pkmn = Pokemon.get_pokemon(self.bot,
                                       self.leader_map[leader.lower()])
            pokemon_names[0] = pkmn.name
            pokemon_ids[0] = pkmn.id
        # don't override 2nd slot if already set
        if existing.second_pokemon:
            if pokemon_ids[1]:
                if pokemon_ids[1] != existing.second_pokemon:
                    if pokemon_ids[2]:
                        await channel.send(
                            f"The second lineup slot has already been reported for **{stop.name}**.",
                            delete_after=30)
                    else:
                        # but if the third slot was previously not set, we can fill that in now
                        if not existing.third_pokemon:
                            existing.third_pokemon = pokemon_ids[1]
            pkmn = Pokemon.get_pokemon(self.bot, existing.second_pokemon)
            pokemon_names[1] = pkmn.name
            pokemon_ids[1] = pkmn.id
        # don't override 3rd slot if already set. this may be unreachable
        if existing.third_pokemon:
            if pokemon_ids[2]:
                if pokemon_ids[2] != existing.second_pokemon:
                    await channel.send(
                        f"The third lineup slot has already been reported for **{stop.name}**",
                        delete_after=30)
            pkmn = Pokemon.get_pokemon(self.bot, existing.third_pokemon)
            pokemon_names[2] = pkmn.name
            pokemon_ids[2] = pkmn.id
        if leader:
            leader = leader.lower()
        if existing.id:
            report = TrainerReportRelation.get_by_id(existing.id)
            HideoutTable.update(rocket_leader=leader, first_pokemon=pokemon_ids[0],
                                second_pokemon=pokemon_ids[1], third_pokemon=pokemon_ids[2])\
                .where(HideoutTable.trainer_report == report.id).execute()
            updated = True
        else:
            report = TrainerReportRelation.create(guild=ctx.guild.id,
                                                  created=report_time_int,
                                                  trainer=author.id,
                                                  location=stop.id,
                                                  cancelled=False)
            HideoutTable.create(trainer_report=report,
                                rocket_leader=leader,
                                first_pokemon=pokemon_ids[0],
                                second_pokemon=pokemon_ids[1],
                                third_pokemon=pokemon_ids[2])
            updated = False
        hideout = self.get_single_hideout(report.id)
        inv_embed = await self._build_hideout_embed(ctx, hideout)
        listmgmt_cog = self.bot.cogs.get('ListManagement')
        if updated:
            hideout = self.get_single_hideout(report.id)
            message = await channel.fetch_message(hideout.message)
            try:
                await message.delete()
            except:
                pass
            invasionreportmsg = await channel.send(
                f'**Team Rocket Hideout** report at *{hideout.location_name}* updated!',
                embed=inv_embed)
            await utilities_cog.reaction_delay(invasionreportmsg,
                                               ['\u270f', '🚫'])
            TrainerReportRelation.update(message=invasionreportmsg.id) \
                .where(TrainerReportRelation.id == report.id).execute()
            await listmgmt_cog.update_listing_channels(guild,
                                                       'hideout',
                                                       edit=True,
                                                       regions=regions)
        else:
            invasionreportmsg = await channel.send(
                f'**Team Rocket Hideout** reported at *{stop.name}*',
                embed=inv_embed)
            await utilities_cog.reaction_delay(invasionreportmsg,
                                               ['\u270f', '🚫'])
            details = {'regions': regions, 'type': 'hideout', 'location': stop}
            TrainerReportRelation.update(message=invasionreportmsg.id).where(
                TrainerReportRelation.id == report.id).execute()
            send_channel = subscriptions_cog.get_region_list_channel(
                guild, stop.region, 'invasion')
            if send_channel is None:
                send_channel = message.channel
            await subscriptions_cog.send_notifications_async(
                'hideout', details, send_channel, [message.author.id])
            await asyncio.sleep(1)
            await listmgmt_cog.update_listing_channels(guild,
                                                       'hideout',
                                                       edit=False,
                                                       regions=regions)
        clean_list = self.bot.guild_dict[
            ctx.guild.id]['configure_dict'].setdefault('channel_auto_clean',
                                                       [])
        if ctx.channel.id in clean_list:
            await ctx.message.delete()
Beispiel #11
0
 async def modify_report(self, ctx, payload, report_id):
     channel = self.bot.get_channel(ctx.channel.id)
     try:
         message = await channel.fetch_message(payload.message_id)
     except (discord.errors.NotFound, AttributeError):
         return
     guild = message.guild
     try:
         user = guild.get_member(payload.user_id)
     except AttributeError:
         return
     utils_cog = self.bot.cogs.get('Utilities')
     regions = utils_cog.get_channel_regions(channel, 'hideout')
     prompt = f'Modifying details for **Team Rocket Hideout** at '  #**{stop}**\n' \
     #f'Which item would you like to modify ***{user.display_name}***?'
     choices_list = ['Pokestop', 'Leader', 'Lineup']
     match = await utils.ask_list(self.bot,
                                  prompt,
                                  channel,
                                  choices_list,
                                  user_list=user.id)
     if match in choices_list:
         updated = False
         report = TrainerReportRelation.get_by_id(report_id)
         # Changing pokestop
         if match == choices_list[0]:
             location_matching_cog = self.bot.cogs.get('LocationMatching')
             utils_cog = self.bot.cogs.get('Utilities')
             regions = utils_cog.get_channel_regions(channel, 'hideout')
             stops = location_matching_cog.get_stops(guild.id, regions)
             query_msg = await channel.send(embed=discord.Embed(
                 colour=discord.Colour.gold(),
                 description="What is the correct Location?"))
             try:
                 stopmsg = await self.bot.wait_for(
                     'message',
                     timeout=30,
                     check=(lambda reply: reply.author == user))
             except asyncio.TimeoutError:
                 await query_msg.delete()
                 stopmsg = None
             stop = None
             if not stopmsg:
                 error = "took too long to respond"
             elif stopmsg.clean_content.lower() == "cancel":
                 error = "cancelled the report"
                 await stopmsg.delete()
             elif stopmsg:
                 stop = await location_matching_cog.match_prompt(
                     channel, user.id, stopmsg.clean_content, stops)
                 if not stop:
                     return await channel.send(embed=discord.Embed(
                         colour=discord.Colour.red(),
                         description=
                         f"No pokestop found with name '**{stopmsg.clean_content}**' "
                         f"either. Try reporting again using the exact pokestop name!"
                     ),
                                               delete_after=15)
                 if await self._check_existing(stop):
                     return await channel.send(embed=discord.Embed(
                         colour=discord.Colour.red(),
                         description=
                         f"A Team Rocket Hideout has already been reported for '**{stop.name}**'!"
                     ))
             if stop:
                 updated = True
                 report.location_id = stop.id
                 report.save()
         # Changing leader
         elif match == choices_list[1]:
             query_msg = await channel.send(embed=discord.Embed(
                 colour=discord.Colour.gold(),
                 description="What is the correct Leader?"))
             try:
                 leadmsg = await self.bot.wait_for(
                     'message',
                     timeout=30,
                     check=(lambda reply: reply.author == user))
             except asyncio.TimeoutError:
                 await query_msg.delete()
                 leadmsg = None
             if not leadmsg:
                 error = "took too long to respond"
             elif leadmsg.clean_content.lower() == "cancel":
                 error = "cancelled the report"
                 await leadmsg.delete()
             else:
                 if leadmsg.clean_content.lower() in self.leader_strings:
                     updated = True
                     report = TrainerReportRelation.get_by_id(report_id)
                     HideoutTable.update(rocket_leader=leadmsg.clean_content.lower())\
                         .where(HideoutTable.trainer_report == report.id).execute()
                 else:
                     return await channel.send(embed=discord.Embed(
                         colour=discord.Colour.red(),
                         description=f"No Team Rocket Leader found with name "
                         f"{leadmsg.clean_content}. Please start again."),
                                               delete_after=15)
         # Changing lineup
         elif match == choices_list[2]:
             query_msg = await channel.send(embed=discord.Embed(
                 colour=discord.Colour.gold(),
                 description="What is the correct Lineup?"))
             try:
                 lineupmsg = await self.bot.wait_for(
                     'message',
                     timeout=30,
                     check=(lambda reply: reply.author == user))
             except asyncio.TimeoutError:
                 await query_msg.delete()
                 lineupmsg = None
             if not lineupmsg:
                 error = "took too long to respond"
             elif lineupmsg.clean_content.lower() == "cancel":
                 error = "cancelled the report"
                 await lineupmsg.delete()
             else:
                 info = re.split(r',+\s+', lineupmsg.clean_content)
                 pokemon_ids = [None]
                 for i in info:
                     pkmn = Pokemon.get_pokemon(self.bot, i)
                     if pkmn is not None:
                         if pkmn.id not in self.leader_map.values():
                             pokemon_ids.append(pkmn.id)
                 if not pokemon_ids[0]:
                     hideout = self.get_single_hideout(report.id)
                     if hideout.leader and hideout.leader in self.leader_map:
                         pokemon_ids[0] = self.leader_map[hideout.leader]
                 if len(pokemon_ids) < 3:
                     pokemon_ids = (pokemon_ids + 3 * [None])[:3]
                 updated = True
                 report = TrainerReportRelation.get_by_id(report_id)
                 HideoutTable.update(first_pokemon=pokemon_ids[0], second_pokemon=pokemon_ids[1],
                                     third_pokemon=pokemon_ids[2]) \
                     .where(HideoutTable.trainer_report == report.id).execute()
         if updated:
             hideout = self.get_single_hideout(report.id)
             message = await channel.fetch_message(hideout.message)
             try:
                 await message.delete()
             except:
                 pass
             inv_embed = await self._build_hideout_embed(ctx, hideout)
             invasionreportmsg = await channel.send(
                 f'**Team Rocket Hideout** report at *{hideout.location_name}* updated!',
                 embed=inv_embed)
             utilities_cog = self.bot.cogs.get('Utilities')
             await utilities_cog.reaction_delay(invasionreportmsg,
                                                ['\u270f', '🚫'])
             TrainerReportRelation.update(message=invasionreportmsg.id) \
                 .where(TrainerReportRelation.id == report.id).execute()
             listmgmt_cog = self.bot.cogs.get('ListManagement')
             await listmgmt_cog.update_listing_channels(guild,
                                                        'hideout',
                                                        edit=True,
                                                        regions=regions)
     try:
         await message.remove_reaction(payload.emoji, user)
     except (discord.errors.NotFound):
         pass