async def clan_members(interaction: discord.Interaction, tag: str): try: clan = await Clash_of_clans.get_clan(tag) except coc.errors.NotFound: await interaction.response.send_message(f"Clan not found\nThere is no clan with the tag `{tag}` (do not forget the # in front of the tag).", ephemeral=True) return text = "" x = 0 rank = 0 embeds = [] async for member in clan.get_detailed_members(): rank += 1 text += f"- {rank} `{escape_markdown(member.name)}`: {trophies_to_league(member.trophies)} (best: {trophies_to_league(member.best_trophies)}) {Emojis['Th_emojis'][member.town_hall]} {member.tag}\n" x += 1 if x == 25: embed = create_embed(f"Clan members {escape_markdown(clan.name)} ({clan.tag})", f"Members list: \n{text}", interaction.guild.me.color, "", interaction.guild.me.avatar.url) embeds += [embed] text = "" x = 0 if x != 0: embed = create_embed(f"Clan members {escape_markdown(clan.name)} ({clan.tag})", f"Members list: \n{text}", interaction.guild.me.color, "", interaction.guild.me.avatar.url) embeds += [embed] if (lambda l: sum([len(l[i]) for i in range(len(l))]))(embeds) <= 6000: await interaction.response.send_message(embeds=embeds) else: await interaction.response.send_message(embed=embeds[0]) if len(embeds) > 1: await interaction.channel.send(embed=embeds[1]) return
async def unlink_coc_account(interaction: discord.Interaction, player_tag: str): player_tag = coc.utils.correct_tag(player_tag) if player_tag in Linked_accounts[interaction.user.id]["Clash Of Clans"]: Linked_accounts[interaction.user.id]["Clash Of Clans"].pop( Linked_accounts[interaction.user.id]["Clash Of Clans"].index( player_tag)) if not Linked_accounts[interaction.user.id]["Clash Of Clans"]: Linked_accounts.pop(interaction.user.id) json_text = json.dumps(Linked_accounts, sort_keys=True, indent=4) linked_account_file = open( f"{Config['secure_folder_path']}linked_accounts.json", "w") linked_account_file.write(json_text) linked_account_file.close() embed = create_embed( "Accounts unlinked", f"Your Discord account is no longer linked with the Clash Of Clans account `{player_tag}`", interaction.guild.me.color, "", interaction.guild.me.avatar.url) await interaction.response.send_message(embed=embed, ephemeral=True) else: embed = create_embed( "Account not linked", f"Your Discord account is not linked with the Clash Of Clans account `{player_tag}`", interaction.guild.me.color, "", interaction.guild.me.avatar.url) await interaction.response.send_message(embed=embed, ephemeral=True) return
async def clan_super_troops_activated(interaction: discord.Interaction, clan_tag: str, super_troop: str): try: clan = await Clash_of_clans.get_clan(clan_tag) except coc.errors.NotFound: await interaction.response.send_message( f"Clan not found\nThere is no clan with the tag `{clan_tag}` (do not forget the # in front of the tag).", ephemeral=True) return members_with_super_troop = [] max_level = "Max level unknown" async for member in clan.get_detailed_members(): s_troop = member.get_troop(super_troop) if s_troop is not None and s_troop.is_active: max_level = s_troop.max_level s_troop.level = "*Unknown*" # TODO : s_troop.level is always 1 members_with_super_troop.append({ "name": member.name, "tag": member.tag, "super_troop_level": s_troop.level }) text = "" for player in members_with_super_troop: text += f"- `{escape_markdown(player['name'])}`: {super_troop} level {player['super_troop_level']}/{max_level} {player['tag']}\n" if text == "": text = f"No player has the {super_troop} active in this clan" embed = create_embed( f"Members with the {super_troop} active in the clan {escape_markdown(clan.name)} ({clan.tag})", text, interaction.guild.me.color, "", icon_url=interaction.guild.me.avatar.url) await interaction.response.send_message(embed=embed) return
async def member_remove(self: discord.Client, member: discord.Member): if member.guild.id == Ids["Support_server"]: users = 0 for m in member.guild.members: if not m.bot: users += 1 for channel in member.guild.channels: if channel.name.startswith("👤 "): await channel.edit(name=f"👤 Users: {users: ,}") break else: overwrite = {member.guild.default_role: discord.PermissionOverwrite(connect=False, view_channel=True)} await member.guild.create_voice_channel(f"👤 Users: {users: ,}", overwrites=overwrite) welcome = self.get_channel(Ids["Welcome_channel"]) days_spent_in_the_server = (datetime.datetime.now().date() - member.joined_at.date()).days if days_spent_in_the_server > 1: embed = create_embed(f"Unfortunately, {escape_markdown(member.name)} left us", f"{escape_markdown(member.name)}#{member.discriminator} (`{member.id}`) left us. He/She joined the server the {member.joined_at.date().isoformat()} ({days_spent_in_the_server} days ago)", member.color, "", member.guild.me.avatar.url) embed.set_thumbnail(url=member.avatar.url) await welcome.send(embed=embed) else: async for message in welcome.history(limit=None): old_embed = message.embeds[0] if int(old_embed.description.split("`")[-2]) == member.id: if message.author == message.guild.me: new_embed = old_embed.copy() new_embed.description = old_embed.description + f"\n*Unfortunately, {escape_markdown(member.name)} left us after less than a day in the server*" new_embed.set_image(url="attachment://Welcome.png") await message.edit(embed=new_embed) break return
async def link_coc_account(interaction: discord.Interaction, player_tag: str, api_token: str): api_token = api_token.upper() player_tag = coc.utils.correct_tag(player_tag) is_correct_token = await Clash_of_clans.verify_player_token( player_tag, api_token) if is_correct_token: if interaction.user.id not in list(Linked_accounts.keys()): Linked_accounts[interaction.user.id] = {"Clash Of Clans": []} if player_tag not in Linked_accounts[ interaction.user.id]["Clash Of Clans"]: Linked_accounts[ interaction.user.id]["Clash Of Clans"] = Linked_accounts[ interaction.user.id]["Clash Of Clans"] + [player_tag] json_text = json.dumps(Linked_accounts, sort_keys=True, indent=4) linked_account_file = open( f"{Config['secure_folder_path']}linked_accounts.json", "w") linked_account_file.write(json_text) linked_account_file.close() embed = create_embed( "Accounts linked", f"Your Discord account is now linked with the Clash Of Clans account `{player_tag}`", interaction.guild.me.color, "", interaction.guild.me.avatar.url) await interaction.response.send_message(embed=embed, ephemeral=True) else: await interaction.response.send_message( f"Your Discord account is already linked with the Clash Of Clans account `{player_tag}`" ) else: await interaction.response.send_message( f"The token {api_token} does not match with the tag {player_tag}", ephemeral=True) return
async def on_ready(self): from data.secure_folder import Votes user = clash_info.get_user(voter_id) votes_channel = self.get_channel(Ids["Votes_channel"]) if user.id not in list(Votes.keys()): Votes[user.id] = 1 else: Votes[user.id] += 1 json_text = json.dumps(Votes, sort_keys=True, indent=4) def_votes = open(f"{Config['secure_folder_path']}votes.json", "w") def_votes.write(json_text) def_votes.close() vote_copy = dict(Votes) vote = {} for member_id, member_votes in vote_copy.items(): member = clash_info.get_user(int(member_id)) vote[member.mention] = member_votes vote = sorted(vote.items(), key=lambda t: t[1]) text = "" for user_vote_tuple in vote: text += f"{user_vote_tuple[0]} has voted {user_vote_tuple[1]} times\n" embed = create_embed(f"{user} has voted for Clash INFO", text, votes_channel.guild.me.color, "", votes_channel.guild.me.avatar.url) await votes_channel.send(embed=embed) await self.close()
async def add_a_bot_id(interaction: discord.Interaction, bot_id: int): link = discord.utils.oauth_url( bot_id, permissions=discord.Permissions(administrator=True)) embed = create_embed(f"Add the bot with the ID {bot_id}:", link, interaction.guild.me.color, "", interaction.guild.me.avatar.url) await interaction.response.send_message(embed=embed) return
async def buildings_th_embed(interaction: discord.Interaction, lvl: int) -> discord.Embed: level_th = Main_base_buildings[lvl] text_th = "" for category, buildings in level_th.items(): text_th += f"\n__{category}:__\n" for building_name, building_max_level in buildings.items(): text_th += f"{building_name} level max: {building_max_level}\n" embed = create_embed(f"__**TH {lvl}:\n**__", text_th, interaction.guild.me.color, f"buildings_th|{interaction.user.id}", interaction.guild.me.avatar.url) return embed
async def buildings_th(interaction: discord.Interaction, lvl: int): if lvl > Useful["max_th_lvl"] or lvl < 0: await interaction.response.send_message(f"Town Hall not found\nPlease give a valid TH level: there is no level `{lvl}` TH.", ephemeral=True) return elif lvl == 0: embed = create_embed("What is your TH level ?", "", interaction.guild.me.color, f"buildings_th|{interaction.user.id}", interaction.guild.me.avatar.url) await interaction.response.send_message(embed=embed, view=ComponentView("buildings_th")) elif 0 < lvl <= Useful["max_th_lvl"]: embed = await buildings_th_embed(interaction, lvl) await interaction.response.send_message(embed=embed, view=ComponentView("buildings_th")) return
async def member_info(interaction: discord.Interaction, member: discord.Member): accounts_linked = "" if member.id in list(Linked_accounts.keys()): for k, v in Linked_accounts[member.id].items(): accounts_linked += f"{k}: {escape_markdown(v)}" else: accounts_linked = "None" member_permissions = "" if member.guild_permissions.administrator: member_permissions += "Administrator\n" if member.guild_permissions.manage_guild: member_permissions += "Manage server\n" if member.guild_permissions.manage_roles: member_permissions += "Manage roles\n" if member.guild_permissions.manage_permissions: member_permissions += "Manage permissions\n" if member.guild_permissions.manage_events: member_permissions += "Manage events\n" if member.guild_permissions.manage_emojis_and_stickers: member_permissions += "Manage emojis and stickers\n" if member.guild_permissions.manage_channels: member_permissions += "Manage channels\n" if member.guild_permissions.manage_threads: member_permissions += "Manage threads\n" if member.guild_permissions.manage_messages: member_permissions += "Manage messages\n" if member.guild_permissions.manage_webhooks: member_permissions += "Manage webhooks\n" if member.guild_permissions.ban_members: member_permissions += "Ban members\n" if member.guild_permissions.kick_members: member_permissions += "Kick members\n" if member.guild_permissions.moderate_members: member_permissions += "Moderate members\n" if member.guild_permissions.manage_nicknames: member_permissions += "Manage nicknames\n" if member.guild_permissions.mention_everyone: member_permissions += "Mention everyone\n" if member.guild_permissions.view_audit_log: member_permissions += "View logs\n" if member_permissions == "": member_permissions = "Any" embed = create_embed( escape_markdown(member.name), f"{Emojis['Invite']} Server join: **{member.joined_at.date().isoformat()}**.\n{Emojis['Discord']} Discord account creation: **{member.created_at.date().isoformat()}**\n\n{Emojis['Member']} **Accounts linked:**\n{accounts_linked}\n\n{Emojis['Settings']} **Member permissions:**\n{member_permissions}", member.color, "", interaction.guild.me.avatar.url) embed.set_thumbnail(url=member.avatar.url) await interaction.response.send_message(embed=embed) return
async def guild_join(self: discord.Client, guild: discord.Guild): if Config["top_gg"]: from bot.apis_clients.top_gg import Dbl_client await Dbl_client.post_guild_count(guild_count=len(self.guilds)) users = 0 bots = 0 for member in guild.members: if member.bot: bots += 1 else: users += 1 if users >= 100: log = self.get_channel(Ids["Guilds_bot_log_channel"]) await log.send( f"The bot has JOINED the server {escape_markdown(guild.name)},\n owned by {escape_markdown(guild.owner.name)},\n with {len(guild.members)} members ({users} users and {bots} bots)" ) if guild.me.guild_permissions.manage_channels and guild.me.guild_permissions.manage_roles: for channel in guild.text_channels: if "clash-info-news" in channel.name: break else: overwrite = { guild.default_role: discord.PermissionOverwrite(view_channel=True, send_messages=False), guild.me: discord.PermissionOverwrite(add_reactions=True, embed_links=True, external_emojis=True, read_message_history=True, send_messages=True, view_channel=True) } channel = await guild.create_text_channel("clash-info-news", overwrites=overwrite) embed = create_embed( "Thank you for using this bot on your server !", f"Hello\nIf you want to receive the list of the features for the bot, please check the reaction {Emojis['News']} bellow. If you want to delete this channel, please check the reaction {Emojis['Delete']} bellow. You can join the Clash INFO support server here: https://discord.gg/KQmstPw\n\nPlease grant the permissions `Use External Emoji` to `@everyone`, or the bot slash commands won't show emojis !", 0x00ffff, "joined_guild_message", guild.me.avatar.url) await channel.send(embed=embed, view=ComponentView("joined_guild_message")) await channel.send("https://discord.gg/KQmstPw") nb_guilds = len(self.guilds) act = discord.Activity(type=discord.ActivityType.watching, name=f"{nb_guilds: ,} servers") await self.change_presence(status=discord.Status.online, activity=act) return
async def bot_info(interaction: discord.Interaction): required_permissions = Useful["required_permissions"] text_permissions = ":warning: The bot needs the permissions: " for perm in required_permissions: if not getattr(interaction.app_permissions, perm): text_permissions += "\n" + perm text_permissions += "\nSo please grant them to the bot." if text_permissions == ":warning: The bot needs the permissions: " + "\nSo please grant them to the bot.": text_permissions = f"{Emojis['Yes']} The bot has all required permissions !" text_servers_number = f"{Emojis['Discord']} The bot is on {len(Clash_info.guilds)} servers !" text_created = f"{Emojis['Calendar']} The bot was created the 2020-04-28, and certified the 2020-09-23." embed = create_embed( "Clash INFO", f"{text_permissions}\n{text_servers_number}\n{text_created}", interaction.guild.me.color, "", interaction.guild.me.avatar.url) await interaction.response.send_message(embed=embed) return
async def help(interaction: discord.Interaction): embed = create_embed("Help: Slash commands list", "", interaction.guild.me.color, "", interaction.guild.me.avatar.url) embed.add_field( name="Slash Commands list", value= "**You can get the bot commands list with detailed description [here](https://rreemmii-dev.github.io/commands)**\n\nHowever, here is the list of slash commands:\n" + escape_markdown( "/auto_roles_[th|bh|leagues]\n/buildings_[bh|th]\n/player_info\n/clan_info\n/search_clan\n/clan_members\n/clan_super_troops_activated\n/army_link_analyze\n/link_coc_account\n/unlink_coc_account\n/member_info\n/bot_info" ), inline=True) embed.add_field( name="Links:", value= f"[{Emojis['Clash_info']} Add the bot](https://rreemmii-dev.github.io/invite) | [{Emojis['Discord']} Support server](https://discord.gg/KQmstPw) | [{Emojis['Github']} GitHub](https://github.com/rreemmii-dev/Clash-Of-Clans-Discord-Bot)", inline=False) await interaction.response.send_message(embed=embed) return
async def auto_roles_leagues(interaction: discord.Interaction, channel: discord.TextChannel): text = "" for league, emoji in Emojis["League_emojis"].items(): role = discord.utils.get(interaction.guild.roles, name=league) if role is None: role = await interaction.guild.create_role(name=league) text += f"{emoji} to be {role.mention}\n" embed = create_embed("Select your league to get the matching role", text, interaction.guild.me.color, "auto_roles_leagues", interaction.guild.me.avatar.url) if interaction.channel == channel: await interaction.response.send_message( embed=embed, view=ComponentView("auto_roles_leagues")) else: await channel.send(embed=embed, view=ComponentView("auto_roles_leagues")) await interaction.response.send_message("Done", ephemeral=True) return
async def clan_info_embed(interaction: discord.Interaction, tag: str) -> discord.Embed: clan = await Clash_of_clans.get_clan(tag) if clan.location is not None: location = clan.location.name else: location = "International" leader = "None" for member in clan.members: if member.role == coc.Role.leader: leader = member break ties = clan.war_ties if ties is None: ties = "unknown" losses = clan.war_losses if losses is None: losses = "unknown" embed = create_embed(f"Clan: {escape_markdown(clan.name)} ({clan.tag})", f"{Emojis['Trophy']} Clan points: {clan.points: ,}\n{Emojis['Versus_trophy']} Builder base clan points: {clan.versus_points: ,}\n{Emojis['War_leagues'][clan.war_league.name]} League: {clan.war_league}\n{Emojis['Trophy']} Required trophies: {clan.required_trophies: ,}\n{Emojis['Owner']} Leader: {escape_markdown(leader.name)} ({leader.tag})\n{Emojis['Members']} Number of members: {clan.member_count}\n:crossed_swords: Wars: {clan.war_wins} wins, {ties} ties and {losses} losses\n{Emojis['Pin']} Location: {location}\n{Emojis['Language']} Language: {clan.chat_language}\n{Emojis['Invite']} Invitations type: {clan.type}\n{Emojis['Description']} Description: {escape_markdown(clan.description)}\n[Open in Clash Of Clans]({clan.share_link})", interaction.guild.me.color, "For more information on clan members, send /members [tag]", interaction.guild.me.avatar.url) embed.set_thumbnail(url=clan.badge.url) return embed
async def army_link_analyze(interaction: discord.interactions, army_link: str): try: troops, spells = Clash_of_clans.parse_army_link(army_link) except: await interaction.response.send_message( "There is an error, make sure your link is really an army link!") return text = f"[This army]({army_link}) contains:\n\n" if [troops, spells] != [[], []]: for troop, quantity in troops: text += f"{quantity} {Emojis['Troops_emojis'][troop.name]} ({troop.name})\n" for spell, quantity in spells: text += f"{quantity} {Emojis['Troops_emojis'][spell.name]} ({spell.name})\n" else: text += "Nothing! Make sure your link is really an army link" embed = create_embed(f"Analyze of the in-game army link", text, interaction.guild.me.color, "", interaction.guild.me.avatar.url) await interaction.response.send_message(embed=embed) return
async def stats(interaction: discord.Interaction): connection = sqlite3.connect(Config["secure_folder_path"] + "secure.sqlite") cursor = connection.cursor() cursor.execute("SELECT COUNT(*) FROM bot_usage") nb_monthly_users = cursor.fetchone()[0] text = f"Monthly users: {nb_monthly_users}\n" cursor.execute("PRAGMA table_info(bot_usage)") commands_names = [] for command_name in cursor.fetchall(): if command_name[1] != "user_id": commands_names += [command_name[1]] for command in commands_names: cursor.execute( f"SELECT COUNT(*) FROM bot_usage WHERE NOT {command} = 0") text += f"{command}: {cursor.fetchone()[0]}\n" embed = create_embed("Stats:", text, interaction.guild.me.color, "", interaction.guild.me.avatar.url) await interaction.response.send_message(embed=embed) return
async def on_message(self: discord.Client, message: discord.Message): if message.author.bot: return if message.channel.type == discord.ChannelType.private: channel = self.get_channel(Ids["Dm_bot_log_channel"]) if message.author.id != self.id: await message.author.send("Hello !\nI am a bot, so I cannot answer you !\nSupport server:\nhttps://discord.gg/KQmstPw") if len(message.attachments) == 0: await channel.send(f"```{message.content}``` from:\n{message.author} (`{message.author.id}`)\nMessage_id: `{message.id}`") else: files = [] for attachment in message.attachments: response = requests.get(attachment.url) img = BytesIO(response.content) files += [discord.File(img, filename=f"file.{response.headers['Content-Type'].split('/')[1]}")] if message.content == "": message.content = " " await channel.send(f"```{message.content}``` from:\n{message.author} (`{message.author.id}`)\nMessage_id: `{message.id}`", files=files) return if not Config["message_content_intent"]: return # ----- Auto Moderation ----- if message.guild.id == Ids["Support_server"]: if message.author.top_role < discord.utils.get(message.guild.roles, name="Staff"): text = message.content if Config["perspective_api"]: import googleapiclient from googleapiclient import discovery, errors client = googleapiclient.discovery.build( "commentanalyzer", "v1alpha1", developerKey=Login["perspective_api"]["token"], discoveryServiceUrl="https://commentanalyzer.googleapis.com/$discovery/rest?version=v1alpha1", static_discovery=False, ) analyze_request = { "comment": {"text": text}, "requestedAttributes": { "TOXICITY": {} }, "doNotStore": True } try: response = client.comments().analyze(body=analyze_request).execute() d = {} txt = f"Text: `{text}`\n" for attribute, data in response["attributeScores"].items(): d[attribute] = data['spanScores'][0]['score']['value'] txt += f"{attribute}: {data['spanScores'][0]['score']['value']} ({data['spanScores'][0]['score']['type']})\n" max_value = (max(d, key=d.get), d[max(d, key=d.get)]) if max_value[1] > 0.5: channel = message.guild.get_channel(Ids["Perspective_api_channel"]) await channel.send(embed=create_embed(f"{max_value[0]}: {max_value[1]}", f"[This message]({message.jump_url}) with the content: ```{text}``` has been flagged for {max_value[0]} with a probability of {max_value[1]}", message.guild.me.color, "", message.guild.me.avatar.url)) await message.author.timeout(datetime.timedelta(minutes=5), reason=f"Toxic message:\n{text}") await message.reply(f"{message.author.mention} has been timed out for {max_value[0]}\n\n*This message will be deleted in 5 minutes*", delete_after=300) except googleapiclient.errors.HttpError as e: print("Error (PerspectiveApi):", e) pass # Test Link import re pattern = re.compile("""(https?|ftp)://[^\s/$.?#].[^\s]*""", re.IGNORECASE + re.DOTALL) if pattern.search(text) is not None: await message.author.timeout(datetime.timedelta(minutes=5), reason=f"Link in:\n{text}") await message.delete() await message.channel.send(f"{message.author.mention} has been timed out for link\n\n*This message will be deleted in 5 minutes*", delete_after=300) # Test Discord Invite import re pattern = re.compile("""discord(?:\.com|app\.com|\.gg)[\/invite\/]?(?:[a-zA-Z0-9\-]{2,32})""", re.IGNORECASE + re.DOTALL) if pattern.search(text) is not None: await message.author.timeout(datetime.timedelta(minutes=5), reason=f"Link in:\n{text}") await message.delete() await message.channel.send(f"{message.author.mention} has been timed out for discord invite\n\n*This message will be deleted in 5 minutes*", delete_after=300) if message.author.id in Ids["Creators"]: if message.content.startswith("dltmsg") and message.channel.permissions_for(message.author).manage_messages: number = int(message.content.split(" ")[1]) message_numbers = 0 async for msg in message.channel.history(limit=number + 1): if not msg.pinned: message_numbers += 1 await msg.delete() message_numbers -= 1 embed = create_embed("Messages deleted", f"{message_numbers: ,} messages deleted", message.guild.me.color, "", message.guild.me.avatar.url) msg = await message.channel.send(embed=embed) import asyncio await asyncio.sleep(10) await msg.delete() return return
async def raw_message_edit(self: discord.Client, payload: discord.RawMessageUpdateEvent): if not Config["message_content_intent"]: return # ----- Auto Moderation ----- if payload.guild_id == Ids["Support_server"]: async for message in self.get_guild(Ids["Support_server"]).get_channel(payload.channel_id).history(limit=None): if message.id == payload.message_id: break else: message = None if message is None: return author = message.author if author is None: return if author.top_role < discord.utils.get(message.guild.roles, name="Staff"): text = message.content if Config["perspective_api"]: import googleapiclient from googleapiclient import discovery, errors client = googleapiclient.discovery.build( "commentanalyzer", "v1alpha1", developerKey=Login["perspective_api"]["token"], discoveryServiceUrl="https://commentanalyzer.googleapis.com/$discovery/rest?version=v1alpha1", static_discovery=False, ) analyze_request = { "comment": {"text": text}, "requestedAttributes": { "TOXICITY": {} }, "doNotStore": True } try: response = client.comments().analyze(body=analyze_request).execute() d = {} txt = f"Text: `{text}`\n" for attribute, data in response["attributeScores"].items(): d[attribute] = data['spanScores'][0]['score']['value'] txt += f"{attribute}: {data['spanScores'][0]['score']['value']} ({data['spanScores'][0]['score']['type']})\n" max_value = (max(d, key=d.get), d[max(d, key=d.get)]) if max_value[1] > 0.5: channel = message.guild.get_channel(Ids["Perspective_api_channel"]) await channel.send(embed=create_embed(f"{max_value[0]}: {max_value[1]}", f"[This message]({message.jump_url}) with the content: ```{text}``` has been flagged for {max_value[0]} with a probability of {max_value[1]}", message.guild.me.color, "", message.guild.me.avatar.url)) await message.author.timeout(datetime.timedelta(minutes=5), reason=f"Toxic message:\n{text}") await message.reply(f"{message.author.mention} has been timed out for {max_value[0]}\n\n*This message will be deleted in 5 minutes*", delete_after=300) except googleapiclient.errors.HttpError as e: print("Error (PerspectiveApi):", e) pass # Test Link import re pattern = re.compile("""(https?|ftp)://[^\s/$.?#].[^\s]*""", re.IGNORECASE + re.DOTALL) if pattern.search(text) is not None: await message.author.timeout(datetime.timedelta(minutes=5), reason=f"Link in:\n{text}") await message.delete() await message.channel.send(f"{message.author.mention} has been timed out for link\n\n*This message will be deleted in 5 minutes*", delete_after=300) # Test Discord Invite import re pattern = re.compile("""discord(?:\.com|app\.com|\.gg)[\/invite\/]?(?:[a-zA-Z0-9\-]{2,32})""", re.IGNORECASE + re.DOTALL) if pattern.search(text) is not None: await message.author.timeout(datetime.timedelta(minutes=5), reason=f"Link in:\n{text}") await message.delete() await message.channel.send(f"{message.author.mention} has been timed out for discord invite\n\n*This message will be deleted in 5 minutes*", delete_after=300) return
async def member_join(self: discord.Client, member: discord.Member): if member.guild.id == Ids["Support_server"]: member_role = discord.utils.get(member.guild.roles, name="Member") await member.add_roles(member_role) users = 0 for m in member.guild.members: if not m.bot: users += 1 for channel in member.guild.channels: if channel.name.startswith("👤 "): await channel.edit(name=f"👤 Users: {users: ,}") break else: overwrite = { member.guild.default_role: discord.PermissionOverwrite(connect=False, view_channel=True) } await member.guild.create_voice_channel(f"👤 Users: {users: ,}", overwrites=overwrite) buffer_avatar = io.BytesIO() await member.display_avatar.save(buffer_avatar) buffer_avatar.seek(0) avatar = Image.open(buffer_avatar).convert("RGBA") avatar = avatar.resize((512, 512)) bigsize = (avatar.size[0] * 3, avatar.size[1] * 3) mask = Image.new("L", bigsize, 0) draw = ImageDraw.Draw(mask) draw.ellipse((0, 0) + bigsize, fill=255) mask = mask.resize(avatar.size, Image.ANTIALIAS) avatar.putalpha(mask) output = ImageOps.fit(avatar, mask.size, centering=(0.5, 0.5)) output.putalpha(mask) avatar_image = output avatar_size = 768 avatar_image = avatar_image.resize((avatar_size, avatar_size)) image = Image.open("ressources/welcome.png") image = image.resize((1920, 1080)) image_width, image_height = image.size foreground = avatar_image x = (1024 - avatar_size) // 2 y = (image_height - avatar_size) // 2 image.paste(foreground, (x, y), foreground) draw = ImageDraw.Draw(image) font = ImageFont.truetype("ressources/supercell_magic_webfont.ttf", 100) text_width, text_height = draw.textsize(f"Welcome {member.name}", font=font) x = (image_width - text_width) // 2 y = (image_height - text_height) // 2 - 400 text_color = (55, 115, 235) draw.text((x, y), f"Welcome {member.name}", fill=text_color, font=font) text_width, text_height = draw.textsize("Clash INFO support server", font=font) x = (image_width - text_width) // 2 y = (image_height - text_height) // 2 + 400 draw.text((x, y), "Clash INFO support server", fill=text_color, font=font) buffer_output = io.BytesIO() image.save(buffer_output, format="PNG") buffer_output.seek(0) file = discord.File(buffer_output, "Welcome.png") url = "attachment://Welcome.png" rules_channel = self.get_channel(Ids["Rules_channel"]) embed = create_embed( f"Welcome {escape_markdown(member.name)} !", f"Welcome ! Please check the {rules_channel.mention}, you will find everything you need here !\n{Emojis['Id']} ID: `{member.id}`\n{Emojis['Discord']} Discord account creation: {member.created_at.date().isoformat()}", member.color, "", member.guild.me.avatar.url, img=url) welcome = self.get_channel(Ids["Welcome_channel"]) await welcome.send(embed=embed, file=file) return
async def player_info_embed(interaction: discord.Interaction, tag: str, information: str) -> discord.Embed: player = await Clash_of_clans.get_player(tag) if information == "main": lvl_barbarian_king = 0 lvl_archer_queen = 0 lvl_grand_warden = 0 lvl_royal_champion = 0 lvl_battle_machine = 0 for hero in player.heroes: if hero.name == "Battle Machine": lvl_battle_machine = hero.level if hero.name == "Barbarian King": lvl_barbarian_king = hero.level if hero.name == "Archer Queen": lvl_archer_queen = hero.level if hero.name == "Grand Warden": lvl_grand_warden = hero.level if hero.name == "Royal Champion": lvl_royal_champion = hero.level if player.town_hall_weapon: weapon = f"({player.town_hall_weapon} {Emojis['Star']})" else: weapon = "" if player.clan: clan = f"{escape_markdown(player.clan.name)} ({player.clan.tag})" else: clan = "None" if player.builder_hall: player__versus_trophies = player.versus_trophies player__best_versus_trophies = player.best_versus_trophies else: player__versus_trophies = 0 player__best_versus_trophies = 0 embed = create_embed( f"Player: {escape_markdown(player.name)} ({player.tag}) (Main information)", f"===== Main Base =====\n{Emojis['Th_emojis'][player.town_hall]} {weapon} | {trophies_to_league(player.trophies)} {player.trophies} | {trophies_to_league(player.best_trophies)} Best: {player.best_trophies} | {Emojis['Exp']} {player.exp_level}\n{Emojis['Barbarian_king']} {lvl_barbarian_king} | {Emojis['Archer_queen']} {lvl_archer_queen} | {Emojis['Grand_warden']} {lvl_grand_warden} | {Emojis['Royal_champion']} {lvl_royal_champion}\n{Emojis['Members']} Clan: {clan}\n{Emojis['Star']} War stars earned: {player.war_stars}\n{Emojis['Donations']} Troops donated: {player.donations}\n{Emojis['Received']} Troops received: {player.received}\n:crossed_swords: Attacks won: {player.attack_wins}\n:shield: Defenses won: {player.defense_wins}\n\n===== Builder Base =====\n{Emojis['Bh_emojis'][player.builder_hall] if player.builder_hall else Emojis['Bh_emojis'][1]} | {Emojis['Versus_trophy']} {player__versus_trophies} | {Emojis['Versus_trophy']} Best: {player__best_versus_trophies} | {Emojis['Battle_machine']} {lvl_battle_machine}\n:crossed_swords: Versus battle won: {player.versus_attack_wins}\n\n[Open in Clash Of Clans]({player.share_link})", interaction.guild.me.color, f"player_info|{interaction.user.id}", interaction.guild.me.avatar.url) elif information == "troops": troops = {} for troop in player.home_troops: if not troop.is_super_troop: troops[troop.name] = { "name": troop.name, "player": troop.level, "max for the th": troop.get_max_level_for_townhall(player.town_hall), "max for the game": troop.max_level } for troop in player.spells: troops[troop.name] = { "name": troop.name, "player": troop.level, "max for the th": troop.get_max_level_for_townhall(player.town_hall), "max for the game": troop.max_level } for troop in player.siege_machines: troops[troop.name] = { "name": troop.name, "player": troop.level, "max for the th": troop.get_max_level_for_townhall(player.town_hall), "max for the game": troop.max_level } for troop in player.hero_pets: troops[troop.name] = { "name": troop.name, "player": troop.level, "max for the th": 10, "max for the game": troop.max_level } # TODO : Edit "max for the th" when it will be available text = "*level | max level (TH) | max level (all the game)*" for troop in troops.values(): emoji = Emojis["Troops_emojis"][troop["name"]] if troop["name"] == "Barbarian": text += "\n\n__Troops:__\n" a = 0 if troop["name"] == "Minion": text += "\n\n__Dark troops:__\n" a = 0 if troop["name"] == "Lightning Spell": text += "\n\n__Spells:__\n" a = 0 if troop["name"] == "Poison Spell": text += "\n\n__Dark spells__:\n" a = 0 if troop["name"] == "Wall Wrecker": text += "\n\n__Siege machines__:\n" a = 0 if troop["name"] == "L.A.S.S.I": text += "\n\n__Pets__:\n" a = 0 if a == 4: a = 0 text += "\n" a += 1 emoji = f"<:{emoji.name}:{emoji.id}>" text += f"{emoji}: {troop['player']} | {troop['max for the th']} | {troop['max for the game']} " embed = create_embed( f"Player: {escape_markdown(player.name)} ({player.tag}) (Troops)", text, interaction.guild.me.color, f"player_info|{interaction.user.id}", interaction.guild.me.avatar.url) elif information == "success": achievements = "*name: stars | % for next star*" total_stars = 0 for achievement in player.achievements: total_stars += achievement.stars achievements += f"\n{achievement.name}: {achievement.stars} {Emojis['Star_success']} | {int(achievement.value / achievement.target * 100)}%" achievements += f"\n\nTotal stars: {total_stars} {Emojis['Star_success']}" embed = create_embed( f"Player: {escape_markdown(player.name)} ({player.tag}) (Achievements)", f"{achievements}\n[Open in Clash Of Clans]({player.share_link})", interaction.guild.me.color, f"player_info|{interaction.user.id}", interaction.guild.me.avatar.url) return embed