Beispiel #1
0
    async def convert(self, ctx, argument):
        if isinstance(argument, coc.BasicPlayer):
            return argument

        tag = coc.utils.correct_tag(argument)
        name = argument.strip()

        if tag_validator.match(tag):
            try:
                return await ctx.coc.get_player(tag)
            except coc.NotFound:
                raise commands.BadArgument(
                    'I detected a player tag; and couldn\'t '
                    'find an account with that tag! '
                    'If you didn\'t pass in a tag, '
                    'please drop the owner a message.')
        for rcs_tag in rcs_tags():
            clan = await ctx.coc.get_clan(rcs_tag)
            if clan.name == name or clan.tag == tag:
                raise commands.BadArgument(
                    f'You appear to be passing '
                    f'the clan tag/name for `{str(clan)}`')

            member = clan.get_member(name=name)
            if member:
                return member

        raise commands.BadArgument(f"Invalid tag or IGN. Please try again.")
Beispiel #2
0
class TestWarUpdates(commands.Cog, command_attrs=dict(hidden=True)):
    def __init__(self, bot):
        self.bot = bot

    @coc.WarEvents.state(rcs_tags(prefix=True))
    async def on_war_state_change(self, current_state, war):
        channel = self.bot.get_channel(settings['log_channels']['test'])
        if current_state == "preparation":
            await channel.send(
                f"Preparation has just begun for a war between **{war.clan.name}** and "
                f"**{war.opponent.name}**.")
        elif current_state == "inWar":
            await channel.send(
                f"War has just begun between **{war.clan.name}** and **{war.opponent.name}**."
            )
        elif current_state == "warEnded":
            content = f"War has just ended between **{war.clan.name}** and **{war.opponent.name}**.\n"
            if war.status == "won":
                content += f"{war.clan.name} won!"
            elif war.status == "lost":
                content += f"{war.clan.name} lost! :("
            else:
                content += "Looks like a tie!"
            await channel.send(content)
        else:
            await channel.send(
                f"War state is {current_state} for {war.clan.name}")
Beispiel #3
0
 async def update_warlog(self):
     conn = self.bot.pool
     for tag in helper.rcs_tags():
         try:
             war_log = await self.bot.coc.get_warlog(f"#{tag}")
         except coc.PrivateWarLog:
             print(f"{tag} has a private war log.")
             continue
         for war in war_log:
             if war.is_league_entry:
                 # skip all CWL wars
                 continue
             sql = (
                 "SELECT war_id, team_size, end_time::timestamp::date, war_state FROM rcs_wars "
                 "WHERE clan_tag = $1 AND opponent_tag = $2 AND end_time < $3"
             )
             fetch = await conn.fetch(sql, tag, war.opponent.tag[1:],
                                      datetime.utcnow())
             if fetch:
                 # Update existing data in the database
                 for row in fetch:
                     if row['end_time'] == war.end_time.time.date(
                     ) and row['war_state'] != "warEnded":
                         # update database to reflect end of war
                         sql = (
                             "UPDATE rcs_wars SET war_state = 'warEnded', clan_attacks = $1, "
                             "clan_destruction = $2, clan_stars = $3, "
                             "opponent_destruction = $4, opponent_stars = $5 WHERE war_id = $6"
                         )
                         await conn.execute(sql, war.clan.attacks_used,
                                            war.clan.destruction,
                                            war.clan.stars,
                                            war.opponent.destruction,
                                            war.opponent.stars,
                                            row['war_id'])
             else:
                 # War is not in database, add it (happens if bot is down)
                 if war.end_time.time < datetime.utcnow() - timedelta(
                         days=2):
                     reported = True
                 else:
                     reported = False
                 sql = (
                     "INSERT INTO rcs_wars (clan_name, clan_tag, clan_attacks, clan_destruction, clan_stars,"
                     "opponent_tag, opponent_name, opponent_destruction, opponent_stars,"
                     "end_time, war_state, team_size, reported)"
                     "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)"
                 )
                 await conn.execute(sql, war.clan.name, war.clan.tag[1:],
                                    war.clan.attacks_used,
                                    war.clan.destruction, war.clan.stars,
                                    war.opponent.tag[1:], war.opponent.name,
                                    war.opponent.destruction,
                                    war.opponent.stars, war.end_time.time,
                                    "warEnded", war.team_size, reported)
                 self.bot.logger.info(
                     f"Added war for {war.clan.name} vs {war.opponent.name} ending "
                     f"{war.end_time.time}.")
Beispiel #4
0
 def __init__(self, bot):
     self.bot = bot
     self.guild = None
     self.media_stats = None
     self.bot.coc.add_events(
         self.on_clan_war_win_streak_change,
         self.on_clan_level_change,
         self.on_clan_war_win_change,
     )
     self.bot.coc.add_clan_update(rcs_tags(prefix=True))
     self.bot.coc.start_updates("clan")
     self.clan_checks.start()
     self.rcs_list.start()
     bot.loop.create_task(self.cog_init_ready())
Beispiel #5
0
 async def plot_trophy_attack(self, ctx):
     """Correlation plot for all RCS clans. Determines connections between trophy count and attack wins."""
     await ctx.send("Sit tight! This one takes about 70 seconds.",
                    delete_after=60.0)
     trophies = []
     attack_wins = []
     async with ctx.typing():
         for tag in rcs_tags(prefix=True):
             clan = await self.bot.coc.get_clan(tag)
             async for member in clan.get_detailed_members():
                 if member.trophies > 500 and member.attack_wins > 0:
                     trophies.append(member.trophies)
                     attack_wins.append(member.attack_wins)
     df = pd.DataFrame({
         "Trophy Count": trophies,
         "Attack Wins": attack_wins
     })
     df.plot(kind="scatter", y="Attack Wins", x="Trophy Count")
     plt.savefig(fname='plot')
     await ctx.send(file=discord.File('plot.png'))
Beispiel #6
0
    async def cwl(self, ctx, *args):
        """List CWL leagues of all RCS clans

        **Example:**
        ++cwl - Shows list of RCS clans in their leagues
        """
        sort_leagues = cwl_league_order[::-1]
        cwl_clans = {}
        for league in sort_leagues:
            cwl_clans[league] = []
        for tag in rcs_tags():
            clan = await self.bot.coc.get_clan(tag)
            league = clan.war_league.name.replace("League ", "")
            cwl_clans[league].append(f"{clan.name} ({clan.tag})")
        for league in sort_leagues:
            content = header_only = f"**{league}:**\n"
            for clan in cwl_clans[league]:
                content += f"  {clan}\n"
            if content != header_only:
                await ctx.send(content)
Beispiel #7
0
 async def games_start(self, ctx):
     """For starting games manually"""
     conn = self.bot.pool
     games = await self.get_current_games()
     games_id = games['games_id']
     to_insert = []
     async for clan in self.bot.coc.get_clans(rcs_tags(prefix=True)):
         counter = 1
         async for member in clan.get_detailed_members():
             to_insert.append(
                 (counter, games_id, member.tag[1:], clan.tag[1:],
                  member.get_achievement("Games Champion").value,
                  member.get_achievement("Games Champion").value))
             counter += 1
     sql = (
         "INSERT INTO rcs_clan_games (event_id, player_tag, clan_tag, starting_points, current_points) "
         "SELECT x.event_id, x.player_tag, x.clan_tag, x.starting_points, x.current_points "
         "FROM unnest($1::rcs_clan_games[]) as x")
     await conn.execute(sql, to_insert)
     await ctx.send(f"Added {counter} games records for the current games.")
Beispiel #8
0
 async def start_games(self):
     """Task to pull initial Games data for the new clan games"""
     now = datetime.utcnow()
     conn = self.bot.pool
     games_id, start_time = await self.get_next_games()
     if games_id:
         print(f"start_games:\n  Start Time: {start_time}")
         if start_time - now < timedelta(minutes=10):
             to_insert = []
             async for clan in self.bot.coc.get_clans(
                     rcs_tags(prefix=True)):
                 counter = 1
                 async for member in clan.get_detailed_members():
                     to_insert.append(
                         (counter, games_id, member.tag[1:], clan.tag[1:],
                          member.get_achievement("Games Champion").value,
                          member.get_achievement("Games Champion").value))
                     counter += 1
             sql = (
                 "INSERT INTO rcs_clan_games (event_id, player_tag, clan_tag, starting_points, current_points) "
                 "SELECT x.event_id, x.player_tag, x.clan_tag, x.starting_points, x.current_points "
                 "FROM unnest($1::rcs_clan_games[]) as x")
             await conn.execute(sql, to_insert)
Beispiel #9
0
 async def on_ready(self):
     activity = discord.Game("Clash of Clans")
     await self.change_presence(status=discord.Status.online, activity=activity)
     self.coc.add_clan_updates(*rcs_tags(prefix=True))
Beispiel #10
0
    async def leader_notes(self):
        """Check the leader-notes channel and see if any of those players are in an RCS clan"""
        if datetime.utcnow().hour != 16:
            return
        danger_channel = self.bot.get_channel(
            settings['rcs_channels']['danger_bot'])
        notes_channel = self.bot.get_channel(
            settings['rcs_channels']['leader_notes'])

        messages = ""
        async for message in notes_channel.history(limit=None,
                                                   oldest_first=True):
            if message.content:
                messages += message.content + " - "
        regex = r"[tT]ag:\s[PYLQGRJCUV0289]+|#[PYLQGRJCUV0289]{6,}"
        ban_list = []
        for match in re.finditer(regex, messages):
            if not match.group().startswith("#"):
                new_match = match.group().upper().replace("TAG: ", "#")
            else:
                new_match = match.group().upper()
            if new_match not in ban_list:
                ban_list.append(new_match)
        self.bot.logger.debug(f"ban_list has {len(ban_list)} items")
        for tag in ban_list:
            if len(tag) < 6:
                self.bot.logger.debug(f"Short tag: {tag}")
            try:
                player = await self.bot.coc.get_player(tag)
                if player.clan and player.clan.tag[1:] in rcs_tags():
                    with Sql() as cursor:
                        sql = ("SELECT COUNT(timestamp) AS reported "
                               "FROM rcs_notify "
                               "WHERE memberTag = %s AND clanTag = %s")
                        cursor.execute(sql,
                                       (player.tag[1:], player.clan.tag[1:]))
                        row = cursor.fetchone()
                        reported = row[0]
                        if reported < 3:
                            clan = get_clan(player.clan.tag[1:])
                            await danger_channel.send(f"<@{clan['leaderTag']}>"
                                                      )
                            embed = discord.Embed(
                                color=discord.Color.dark_red())
                            embed.add_field(
                                name="Leader Note found:",
                                value=
                                f"{player.name} ({player.tag}) is in {player.clan.name}. Please "
                                f"search for `in:leader-notes {player.tag}` for details."
                            )
                            embed.set_footer(
                                text=
                                "Reminder: This is not a ban list, simply information that this "
                                "member has caused problems in the past.")
                            await danger_channel.send(embed=embed)
                            sql = ("INSERT INTO rcs_notify "
                                   "VALUES (%s, %s, %s)")
                            cursor.execute(
                                sql,
                                (datetime.now().strftime('%m-%d-%Y %H:%M:%S'),
                                 player.clan.tag[1:], player.tag[1:]))
            except coc.NotFound:
                self.bot.logger.warning(f"Exception on tag: {tag}")
            except:
                self.bot.logger.exception("Other failure")
            # Add to task log
            sql = (
                "INSERT INTO rcs_task_log (log_type_id, log_date, argument) "
                "VALUES ($1, $2, $3)")
        try:
            await self.bot.pool.execute(sql, log_types['danger'], date.today(),
                                        f"{len(ban_list)} tags processed")
        except:
            self.bot.logger.exception("RCS Task Log insert error")
Beispiel #11
0
 async def push_start(self, ctx):
     msg = await ctx.send("Starting process...")
     # start push
     start = time.perf_counter()
     player_list = []
     async for clan in self.bot.coc.get_clans(rcs_tags()):
         if clan.tag == "#9L2PRL0U":  # Change to in list if more than one clan bails
             continue
         for member in clan.itermembers:
             player_list.append(member.tag)
     team_boom = [
         '#20PCPRJ8', '#2QG2C9LG8', '#288UUGPGG', '#YQCVUGJU', '#2G0YV209J',
         '#9P0PPJV8', '#9PYP8VY90', '#982V9288G', '#2Q8GQLU9R', '#22LPCGV8',
         '#RU9LYLG9', '#28VYCQGRU', '#P2P9QU8C2', '#GVJP200U', '#20CCV90UQ',
         '#Y9C2909R', '#2UL9UVCC2', '#89QQ9QRJ0', '#8JQGGU2Q0', '#GPUQYRJC',
         '#R8JVUGVU', '#V8UQ0G0L', '#G82J00P', '#8VQY0GP2', '#88Y0YL98P',
         '#80LPL9PRP', '#Y0RPYJPC', '#9L9VCYQQ2', '#9P8PCUY8L', '#YY82YY2Y',
         '#2LQPJVR0', '#2PYQR02GV', '#URLVC082', '#PJ8V0QUU', '#2LJJY8JGQ',
         '#CYUVGPPQ', '#PY90C2CY', '#L0GYY8V2', '#8L8PLY2Q2', '#LQY0UUV8V',
         '#2VVQJ9GG2', '#9Y9GCYRJJ', '#8R2QVYYG', '#2VCG8PPVU',
         '#2UPPC0GUC', '#8LVCUQGRG', '#2LQVURL9L', '#PCR8QGY9',
         '#2YCV2JRRJ', '#JLPC2GCU'
     ]
     player_list.extend(team_boom)
     print(len(player_list))
     players_many = []
     to_insert = []
     async for player in self.bot.coc.get_players(player_list):
         players_many.append(
             (player.tag[1:], player.clan.tag[1:],
              player.trophies if player.trophies <= 5000 else 5000,
              player.trophies if player.trophies <= 5000 else 5000,
              player.best_trophies, player.town_hall,
              player.name.replace("'", "''"), player.clan.name))
         to_insert.append({
             "player_tag":
             player.tag[1:],
             "clan_tag":
             player.clan.tag[1:],
             "starting_trophies":
             player.trophies if player.trophies <= 5000 else 5000,
             "current_trophies":
             player.trophies if player.trophies <= 5000 else 5000,
             "best_trophies":
             player.best_trophies,
             "starting_th_level":
             player.town_hall,
             "player_name":
             player.name.replace("'", "''"),
             "clan_name":
             player.clan.name
         })
     print("Player list assembled.")
     with Sql() as cursor:
         sql = (f"INSERT INTO rcspush_2020_1 "
                f"(playerTag, clanTag, startingTrophies, currentTrophies, "
                f"bestTrophies, startingThLevel, playerName, clanName) "
                f"VALUES (%s, %s, %d, %d, %d, %d, %s, %s)")
         cursor.executemany(sql, players_many)
         sql = (
             "UPDATE rcspush_2020_1 SET clanTag = '9L2PRL0U' "
             "WHERE playerTag IN ('#20PCPRJ8', '#2QG2C9LG8', '#288UUGPGG', '#YQCVUGJU', '#2G0YV209J', "
             "'#9P0PPJV8', "
             "'#9PYP8VY90', '#982V9288G', '#2Q8GQLU9R', '#22LPCGV8', '#RU9LYLG9', '#28VYCQGRU', '#P2P9QU8C2', "
             "'#GVJP200U', '#20CCV90UQ', '#Y9C2909R', '#2UL9UVCC2', '#89QQ9QRJ0', '#8JQGGU2Q0', '#GPUQYRJC', "
             "'#R8JVUGVU', '#V8UQ0G0L', '#G82J00P', '#8VQY0GP2', '#88Y0YL98P', '#80LPL9PRP', '#Y0RPYJPC', "
             "'#9L9VCYQQ2', '#9P8PCUY8L', '#YY82YY2Y', '#2LQPJVR0', '#2PYQR02GV', '#URLVC082', '#PJ8V0QUU', "
             "'#2LJJY8JGQ', '#CYUVGPPQ', '#PY90C2CY', '#L0GYY8V2', '#8L8PLY2Q2', '#LQY0UUV8V', '#2VVQJ9GG2', "
             "'#9Y9GCYRJJ', '#8R2QVYYG', '#2VCG8PPVU', '#2UPPC0GUC', '#8LVCUQGRG', '#2LQVURL9L', '#PCR8QGY9', "
             "'#2YCV2JRRJ', '#JLPC2GCU')")
         cursor.execute(sql)
     conn = self.bot.pool
     sql = (
         "INSERT INTO rcspush_2020_1 (player_tag, clan_tag, starting_trophies, current_trophies, best_trophies, "
         "starting_th_level, player_name, clan_name) "
         "SELECT x.player_tag, x.clan_tag, x.starting_trophies, x.current_trophies, x.best_trophies, "
         "x.starting_th_level, x.player_name, x.clan_name "
         "FROM jsonb_to_recordset($1::jsonb) as x (player_tag TEXT, clan_tag TEXT, starting_trophies INTEGER, "
         "current_trophies INTEGER, best_trophies INTEGER, starting_th_level INTEGER, player_name TEXT, "
         "clan_name TEXT)")
     await conn.execute(sql, to_insert)
     await msg.delete()
     await ctx.send(f"{len(player_list)} members added. Elapsed time: "
                    f"{(time.perf_counter() - start) / 60:.2f} minutes")
Beispiel #12
0
 def __init__(self, bot):
     self.bot = bot
     self.bot.coc.add_events(self.on_war_state_change)
     self.bot.coc.add_war_update(rcs_tags(prefix="#"))
     self.bot.coc.start_updates("war")