async def adduser(self, ctx, player_tag, member: discord.Member): try: player_tag = utils.correct_tag(player_tag) player = await self.bot.coc.get_player(player_tag) except coc.NotFound: await ctx.send('This player does not exist') try: self.bot.dbconn.register_user((member.id, player.tag, player.name, player.town_hall, )) await ctx.send(f"Added {member.display_name}'s account to the database") #! Add the townhall role player_th = int(player.town_hall) th_role_id = await getTownhall(int(player_th)) th_role = ctx.author.guild.get_role(int(th_role_id)) if th_role_id is None: await ctx.send("Couldn't add Townhall role") await member.add_roles(th_role) await ctx.send(f"Added the player's townhall role ({player.town_hall})") #! Change their nickname to format we want old_name = str(member.display_name) bar = "|" if bar in old_name: return nick_format = f"{player.name} | {player.clan.name}" await member.edit(nick=nick_format) #! Add clan roles for first time so we don't have to manually do it try: role_to_give_id = self.bot.dbconn.get_role_from_clan_tag((player.clan.tag, ctx.author.guild.id,)) role_to_give = ctx.author.guild.get_role(role_to_give_id) if role_to_give in member.roles: return else: await member.add_roles(role_to_give) except: traceback.print_exc() except: traceback.print_exc()
async def add_user(self, ctx, player_tag): """Command is used to register a user to the database""" player_tag = utils.correct_tag(player_tag) player = await self.bot.coc.get_player(player_tag) self.bot.dbconn.register_user(( player.tag, player.name, player.town_hall, )) await ctx.send(f"User added: {player.name}")
async def delete_link(self, player_tag: str): """Deletes a link between a player tag and a discord ID for the shared junkies database. Player tags can be found either in game or by from clan member lists. Parameters ---------- player_tag : str The player tag to remove the link from. """ return await self._request( "DELETE", "/links/{}".format(correct_tag(player_tag, prefix="")))
async def add_user(self, ctx, player_tag): "Command is used to register a user to the database" player_tag = utils.correct_tag(player_tag) player = await self.bot.coc.get_player(player_tag) commit = self.bot.dbconn.register_user(( player.tag, player.name, player.town_hall, )) if commit: await ctx.send(f'Error: {commit}') else: await ctx.send(f'Adding user {player.name}')
async def linkrole(self, ctx, clan_tag, role: discord.Role): try: corrected_clan_tag = utils.correct_tag(clan_tag) clan = await self.bot.coc.get_clan(corrected_clan_tag) except coc.NotFound: await ctx.send('This clan does not exist') try: self.bot.dbconn.link_role_to_tag((ctx.guild.id, role.id, corrected_clan_tag,)) await ctx.send(f"Linked clan {clan.name} (`{corrected_clan_tag}`) to role `{role.name}`") except: traceback.print_exc()
async def removeuser(self, ctx, player_tag): try: player_tag = utils.correct_tag(player_tag) player = await self.bot.coc.get_player(player_tag) except coc.NotFound: await ctx.send('This player does not exist') try: self.bot.dbconn.remove_user_from_server_players_with_coc_tag((player_tag,)) await ctx.send(f"Removed tag {player_tag} from the database") except: traceback.print_exc()
async def add_link(self, player_tag: str, discord_id: int): """Creates a link between a player tag and a discord ID for the shared junkies database. Player tags can be found either in game or by from clan member lists. Parameters ---------- player_tag : str The player tag to add the link to. discord_id: int The discord ID to add the link to. """ data = { "playerTag": correct_tag(player_tag, prefix=""), "discordId": str(discord_id) } return await self._request("POST", "/links", json=data)
async def get_link(self, player_tag: str) -> typing.Optional[int]: """Get a linked discord ID of a player tag. Player tags can be found either in game or by from clan member lists. Parameters ---------- player_tag: str The player tag to search for. Returns -------- Optional[:class:`int`] The discord ID linked to the player, or ``None`` if no link found. """ data = await self._request( "GET", "/links/{}".format(correct_tag(player_tag, prefix=""))) try: return int(data[0]["discordId"]) except (IndexError, KeyError, TypeError, ValueError): return None
async def get_links( self, *player_tag: str ) -> typing.List[typing.Tuple[str, typing.Optional[int]]]: r"""Get linked discord IDs for an iterable of player tags. Player tags can be found either in game or by from clan member lists. This is the recommended method to use when fetching links for multiple tags as it uses a different endpoint. Parameters ---------- \*player_tag: :class:`str` The player tags to search for. Returns -------- List[:class:`str`:, Optional[:class:`int`]] A list of player_tag, discord_id tuple matches. Discord ID will be ``None`` if not found. Example -------- .. code-block:: python3 links = await client.get_links("#tag1", "#tag2", "#tag3") for player_tag, discord_id in links: print(player_tag, discord_id) """ tags = [correct_tag(tag, prefix="") for tag in player_tag] data = await self._request("POST", "/batch", json=tags) data = data or [] unclaimed_tags = set("#" + tag for tag in tags) - set(p["playerTag"] for p in data) return [(p["playerTag"], int(p["discordId"])) for p in data] + [(tag, None) for tag in unclaimed_tags]
async def add_user(self, ctx, *, args=None): flag_template = { 'clash_tag': { 'flags': ['-t', '--tag'], 'switch': False, 'required': True }, 'guild_member': { 'flags': ['-d', '--discord_id'], 'switch': False, 'required': True } } # Get parserd args parsed_args = await arg_parser(flag_template, args) # Attempt to find user disc_member, in_guild = await self.bot.utils.get_discord_member( ctx, parsed_args['guild_member']) if disc_member is None: await self.bot.embed_print( ctx, title='COMMAND ERROR', color='red', description=f"User `{parsed_args['guild_member']}` not found") return elif in_guild == False: await self.bot.embed_print( ctx, title='COMMAND ERROR', color='red', description= f"User `{disc_member.display_name}` is not in this guild") return # validate clash tag clash_tag = coc_utils.correct_tag(parsed_args['clash_tag']) try: player = await self.bot.coc.get_player(clash_tag) except: await self.bot.embed_print( ctx, title='CLASH ERROR', color='red', description=f'Player `{clash_tag}` not found') return # Change users nickname and add roles await self.bot.utils.update_user( ctx, disc_member, { 'nick': player.name, 'roles': await self.bot.utils.new_user_roles(ctx, player) }) # Get zbp status zbp_server = self.bot.get_guild(self.bot.keys.zbp_server) if disc_member in zbp_server.members: in_zbp = True else: in_zbp = False in_zulu_server = True is_active = True # Validate the user does not exist in the database async with self.bot.pool.acquire() as con: # Attempt to get user from db db_obj = await con.fetchrow( ''' SELECT * FROM discord_user WHERE discord_id=$1''', disc_member.id) # If user exists then we need to check if they are inactive or not if db_obj: if db_obj['is_active']: # TODO: Check to see if there is an alt account to add await ctx.send("User exists: Check to add new tag doe") else: # TODO: Check to see if there is an alt account to add await con.execute( ''' UPDATE discord_user SET is_active = $1 WHERE discord_id = $2''', True, disc_member.id) print(db_obj) return # commit to discord_user user_data = [ (disc_member.id, disc_member.name, disc_member.display_name, f"{disc_member.name}#{disc_member.discriminator}", disc_member.joined_at, disc_member.created_at, datetime.utcnow(), in_zbp, in_zulu_server, is_active), ] async with self.bot.pool.acquire() as con: await con.copy_records_to_table('discord_user', records=user_data) await con.execute( ''' INSERT INTO clash_account VALUES ($1, $2, $3) ''', player.tag, disc_member.id, True)
async def convert(self, ctx, argument): season_id = await ctx.bot.seasonconfig.get_season_id() argument = argument.replace("--byuser", "").strip() if not argument: return player, clan = False, False if "player" in argument: player = True argument = argument.replace("player", "").strip() if "clan" in argument: clan = True argument = argument.replace("clan", "").strip() fake_clan_in_server = ctx.guild.id in ctx.bot.fake_clan_guilds join = "(clans.clan_tag = players.clan_tag OR " \ "(players.fake_clan_tag IS NOT NULL AND clans.clan_tag = players.fake_clan_tag))" \ if fake_clan_in_server else "clans.clan_tag = players.clan_tag" if not (player or clan): if argument in ("all", "server", "guild"): query = f"""SELECT DISTINCT player_tag, player_name, clans.clan_name, players.clan_tag, donations, received, trophies, trophies - start_trophies AS "gain", last_updated - now() AS "since", user_id FROM players INNER JOIN clans ON {join} WHERE clans.guild_id = $1 AND players.season_id = $2 """ return await ctx.db.fetch(query, ctx.guild.id, season_id) try: channel = await commands.TextChannelConverter().convert( ctx, argument) query = f"""SELECT DISTINCT player_tag, player_name, clans.clan_name, players.clan_tag, donations, received, trophies, trophies - start_trophies AS "gain", last_updated - now() AS "since", user_id FROM players INNER JOIN clans ON {join} WHERE clans.channel_id = $1 AND players.season_id = $2 """ return await ctx.db.fetch(query, channel.id, season_id) except commands.BadArgument: pass try: user = await CustomActivityMemberConverter().convert( ctx, argument) links = await ctx.bot.links.get_linked_players(user.id) query = """SELECT DISTINCT player_tag, player_name, players.clan_tag, donations, received, trophies, trophies - start_trophies AS "gain", last_updated - now() AS "since", user_id FROM players WHERE player_tag = ANY($1::TEXT[]) AND players.season_id = $2 """ return await ctx.db.fetch(query, links, season_id) except commands.BadArgument: pass if argument.strip().isdigit(): corrected = argument.strip() else: corrected = correct_tag(argument) if not player: query = f"""SELECT DISTINCT player_tag, player_name, clans.clan_name, players.clan_tag, donations, received, trophies, trophies - start_trophies AS "gain", last_updated - now() AS "since", user_id FROM players INNER JOIN clans ON {join} WHERE clans.clan_tag = $1 AND players.season_id = $3 OR clans.clan_name LIKE $2 AND players.season_id = $3 """ fetch = await ctx.db.fetch(query, corrected, argument, season_id) if fetch: return fetch if not clan: query = """SELECT DISTINCT player_tag, player_name, players.clan_tag, donations, received, trophies, trophies - start_trophies AS "gain", last_updated - now() AS "since", user_id FROM players WHERE player_tag = $1 AND players.season_id = $3 OR player_name LIKE $2 AND players.season_id = $3 """ fetch = await ctx.db.fetch(query, corrected, argument, season_id) if fetch: return fetch await ctx.send( "I'm sorry, but I couldn't parse your argument as one of the following:\n\n" "1. A player tag or player name\n" "2. A clan tag or clan name\n" "3. A user @mention or name\n" "4. A channel #mention or name\n" "5. `server` or `all` to get all clans for the server.\n\n" f"Please try again with a valid argument, or use `{ctx.prefix}help {ctx.command}` for more help." ) raise commands.BadArgument
async def convert(self, ctx, argument): guild = None # discord.Guild channel = None # discord.TextChannel user = None # discord.Member clan = None # (tag, name) player = None # (tag, name) time_ = None match = activity_days_re.search(argument) if match: argument = argument.replace(match.group(0), "").strip() time_ = int(match.group(0)[:-1]) while not (guild or channel or user or player or clan): if argument == "all": guild = ctx.guild break try: channel = await commands.TextChannelConverter().convert( ctx, argument) break except commands.BadArgument: pass try: user = await CustomActivityMemberConverter().convert( ctx, argument) break except commands.BadArgument: pass if not await ctx.bot.is_owner(ctx.author): query = "SELECT DISTINCT(clan_tag), clan_name FROM clans WHERE clan_tag = $1 OR clan_name LIKE $2 AND guild_id = $3" fetch = await ctx.db.fetchrow(query, correct_tag(argument), argument, ctx.guild.id) else: query = "SELECT DISTINCT(clan_tag), clan_name FROM clans WHERE clan_tag = $1 OR clan_name LIKE $2" fetch = await ctx.db.fetchrow(query, correct_tag(argument), argument) if fetch: clan = fetch break fake_clan_in_server = ctx.guild.id in ctx.bot.fake_clan_guilds join = "(clans.clan_tag = players.clan_tag OR " \ "(players.fake_clan_tag IS NOT NULL AND clans.clan_tag = players.fake_clan_tag))" \ if fake_clan_in_server else "clans.clan_tag = players.clan_tag" query = f""" WITH cte AS ( SELECT player_tag, player_name FROM players WHERE ($2 = True OR user_id = $1) AND player_name is not null AND season_id = $6 ), cte2 AS ( SELECT DISTINCT player_tag, player_name FROM players INNER JOIN clans ON {join} WHERE clans.guild_id = $3 AND players.season_id = $6 ) SELECT player_tag, player_name FROM cte WHERE player_tag = $4 OR player_name LIKE $5 UNION SELECT player_tag, player_name FROM cte2 WHERE player_tag = $4 OR player_name LIKE $5 """ fetch = await ctx.db.fetchrow( query, ctx.author.id, await ctx.bot.is_owner(ctx.author), ctx.guild.id, correct_tag(argument), argument, await ctx.bot.seasonconfig.get_season_id(), ) if fetch: player = fetch break raise commands.BadArgument( "I tried to parse your argument as a channel, server, clan name, clan tag, player name " "or tag and couldn't find a match! \n\n" "A couple of security features to note: \n" "1. Clan stats can only be found when the clan has been claimed to this server.\n" "2. Player stats can only be found when the player's current clan is claimed to this server, " "or you have claimed the player.\n\nPlease try again.") fetch = await ctx.db.fetchrow( "SELECT activity_sync FROM guilds WHERE guild_id = $1", ctx.guild.id) if not (fetch and fetch['activity_sync']): await ctx.db.execute( "INSERT INTO guilds (guild_id, activity_sync) VALUES ($1, TRUE) " "ON CONFLICT (guild_id) DO UPDATE SET activity_sync = TRUE", ctx.guild.id) await ctx.send( "This is the first time this command has been run in this server. " "I will only start recording your activity from now. " "Please wait a few days for me to gather reliable data.") return None return guild, channel, user, clan, player, time_