diff --git a/archived/commands/CommandsOlder/Commands/WarCommands.py b/archived/commands/CommandsOlder/Commands/WarCommands.py index 3b885c41..824cfd6e 100644 --- a/archived/commands/CommandsOlder/Commands/WarCommands.py +++ b/archived/commands/CommandsOlder/Commands/WarCommands.py @@ -76,33 +76,33 @@ async def war_search(self, ctx: disnake.ApplicationCommandInteraction, clan:str, disc = "<:map:944913638500761600>" emoji = ''.join(filter(str.isdigit, disc)) - emoji = self.bot.get_emoji(int(emoji)) + emoji = self.bot.emoji_holder.all_emojis.get(int(emoji)) emoji = disnake.PartialEmoji(name=emoji.name, id=emoji.id) troop = "<:troop:861797310224400434>" troop = ''.join(filter(str.isdigit, troop)) - troop = self.bot.get_emoji(int(troop)) + troop = self.bot.emoji_holder.all_emojis.get(int(troop)) troop = disnake.PartialEmoji(name=troop.name, id=troop.id) swords = "" swords = ''.join(filter(str.isdigit, swords)) - swords = self.bot.get_emoji(int(swords)) + swords = self.bot.emoji_holder.all_emojis.get(int(swords)) swords = disnake.PartialEmoji(name=swords.name, id=swords.id, animated=True) shield = "<:clash:877681427129458739>" shield = ''.join(filter(str.isdigit, shield)) - shield = self.bot.get_emoji(int(shield)) + shield = self.bot.emoji_holder.all_emojis.get(int(shield)) shield = disnake.PartialEmoji(name=shield.name, id=shield.id) magnify = "<:magnify:944914253171810384>" magnify = ''.join(filter(str.isdigit, magnify)) - magnify = self.bot.get_emoji(int(magnify)) + magnify = self.bot.emoji_holder.all_emojis.get(int(magnify)) magnify = disnake.PartialEmoji(name=magnify.name, id=magnify.id) surr = "<:surrender:947978096034869249>" surr = ''.join(filter(str.isdigit, surr)) - surr = self.bot.get_emoji(int(surr)) + surr = self.bot.emoji_holder.all_emojis.get(int(surr)) surr = disnake.PartialEmoji(name=surr.name, id=surr.id) embed = await main_war_page(bot=self.bot, war=war, war_league=str(clan.war_league)) diff --git a/archived/commands/CommandsOlder/Utils/Player.py b/archived/commands/CommandsOlder/Utils/Player.py index 7f1d77b0..52471f91 100644 --- a/archived/commands/CommandsOlder/Utils/Player.py +++ b/archived/commands/CommandsOlder/Utils/Player.py @@ -9,7 +9,6 @@ from utility.clash.other import * from utility.general import acronym, create_superscript from utility.discord_utils import interaction_handler -from typing import TYPE_CHECKING from classes.bot import CustomClient from classes.player import MyCustomPlayer from numerize import numerize @@ -55,7 +54,7 @@ async def create_profile_stats(bot: CustomClient, ctx, player: MyCustomPlayer): f"[Clash Of Stats Profile](https://www.clashofstats.com/players/{player.tag.strip('#')})\n\n" \ f"**Season Stats:**\n" \ f"__Attacks__\n" \ - f"- {league_emoji(player)}Trophies: {player.trophies}\n" \ + f"- {fetch_emoji(player.league.name)}Trophies: {player.trophies}\n" \ f"- {bot.emoji.thick_sword}Attack Wins: {player.attack_wins}\n" \ f"- {bot.emoji.brown_shield}Defense Wins: {player.defense_wins}\n" \ f"{loot_text}" \ @@ -64,9 +63,9 @@ async def create_profile_stats(bot: CustomClient, ctx, player: MyCustomPlayer): f"- {bot.emoji.avg_stars}Avg Stars: `{round(hitrate.average_stars, 2)}`\n" \ f"- {bot.emoji.war_stars}Total Stars: `{hitrate.total_stars}, {hitrate.num_attacks} atks`\n" \ f"__Donations__\n" \ - f"- <:warwon:932212939899949176>Donated: {player.donos().donated}\n" \ - f"- <:warlost:932212154164183081>Received: {player.donos().received}\n" \ - f"- <:winrate:932212939908337705>Donation Ratio: {player.donation_ratio()}\n" \ + f"- {bot.emoji.up_green_arrow}Donated: {player.donos().donated}\n" \ + f"- {bot.emoji.down_red_arrow}Received: {player.donos().received}\n" \ + f"- {bot.emoji.ratio}Donation Ratio: {player.donation_ratio()}\n" \ f"__Event Stats__\n" \ f"- {bot.emoji.capital_gold}CG Donated: {'{:,}'.format(sum([sum(cap.donated) for cap in capital_stats]))}\n" \ f"- {bot.emoji.thick_sword}CG Raided: {'{:,}'.format(sum([sum(cap.raided) for cap in capital_stats]))}\n" \ diff --git a/assets/emojiDictionary.py b/assets/emojis.py similarity index 72% rename from assets/emojiDictionary.py rename to assets/emojis.py index f9b3c8e3..278b8de5 100644 --- a/assets/emojiDictionary.py +++ b/assets/emojis.py @@ -1,34 +1,23 @@ -switcher = { - "Barbarian King": "<:BarbarianKing:1125780508190720041>", - "Archer Queen": "<:ArcherQueen:1125780510485004399>", - "Grand Warden": "<:GrandWarden:1125780512699592725>", - "Royal Champion": "<:RoyalChampion:1125780514486353983>", - "Battle Copter": "<:battle_copter:1109716293696888852>", - "Electrofire Wizard": "<:electro_wiz:1109716130735587358>", - "Archer": "<:Archer:1125780518433206302>", - "Baby Dragon": "<:BabyDragon:1125780520991731723>", - "Barbarian": "<:Barbarian:1125780523495731271>", - "Bowler": "<:Bowler:1125780525102149723>", - "Electro Dragon": "<:ElectroDragon:1125780527052505128>", - "Dragon": "<:Dragon:1125780530445693059>", - "Dragon Rider": "<:dragon_rider:1125780532840644669>", - "Balloon": "<:Balloon:1125780535801806858>", - "Ice Golem": "<:IceGolem:1125780538955939920>", - "Miner": "<:Miner:1125780541090840586>", - "Hog Rider": "<:HogRider:1125780543473205318>", - "Yeti": "<:Yeti:1125780545981403226>", - "Wizard": "<:Wizard:1125780548154040361>", - "Healer": "<:Healer:1125780550569951453>", - "Giant": "<:Giant:1125780552419659806>", - "Goblin": "<:Goblin:1125780554537762897>", - "Witch": "<:Witch:1125780557029187594>", - "Minion": "<:Minion:1125780559830986752>", - "P.E.K.K.A": "<:PEKKA:1125780562586640464>", - "Wall Breaker": "<:WallBreaker:1125780564667011144>", - "Golem": "<:Golem:1125780566508314624>", - "Lava Hound": "<:LavaHound:1125780568559333376>", - "Valkyrie": "<:Valkyrie:1125780570601947178>", - "Headhunter": "<:Headhunter:1125780573588299896>", +townhall_emojis = { + 1: "<:02:1125807195456536677>", + 2: "<:02:1125807195456536677>", + 3: "<:03:1125807197415288923>", + 4: "<:04:1125807199495667743>", + 5: "<:05:1125807201752195153>", + 6: "<:06:1125807203803213954>", + 7: "<:07:1125807205757751397>", + 8: "<:08:1125810709406679081>", + 9: "<:09:1125810712078454854>", + 10: "<:10:1125810714179817604>", + 11: "<:11:1125810716608303244>", + 12: "<:12:1125810719259115631>", + 13: "<:132:1125810721490473091>", + 14: "<:14:1125810723822506015>", + 15: "<:th15_big:1029215029486157855>", + 16: "<:16:1183533663367987252>" +} + +super_troop_emojis = { "Super Wall Breaker": "<:SuperWallBreaker:1125780575945494579>", "Super Barbarian": "<:SuperBarbarian:1125780578139111516>", "Super Archer": "<:SuperArcher:1125780580462759987>", @@ -44,57 +33,23 @@ "Ice Hound": "<:IceHound:1125780609290227722>", "Super Dragon": "<:SuperDragon:1125780611240579105>", "Super Bowler": "<:SuperBowler:1125780613174136852>", + "Super Hog Rider": "<:SHogRider:1120604618100060180>", +} + +pet_emojis = { "Unicorn": "<:Unicorn:1125780616395378808>", "Mighty Yak": "<:MightyYak:1125780619079729282>", "Electro Owl": "<:ElectroOwl:1125780621474660383>", "L.A.S.S.I": "<:LASSI:1125780623605387344>", - "trophy": "<:trophyy:1125780625778016277>", - "Wall Wrecker": "<:WallWrecker:1125780628328153129>", - "Battle Blimp": "<:BattleBlimp:1125780630463057991>", - "Stone Slammer": "<:StoneSlammer:1125780633055133706>", - "Siege Barracks": "<:SiegeBarracks:1125795608788226109>", - "Log Launcher": "<:LogLauncher:1125795611925549097>", - "Flame Flinger": "<:FlameFlinger:1125795614261776484>", - "Skeleton Spell": "<:skel:1125795616698667051>", - "Rage Spell": "<:rs:1125795619831812096>", - "Poison Spell": "<:ps:1125795621895405598>", - "Healing Spell": "<:hs:1125795624319717426>", - "Invisibility Spell": "<:invi:1125795629516476518>", - "Jump Spell": "<:js:1125795631936573450>", - "Lightning Spell": "<:ls:1125795633907904512>", - "Haste Spell": "<:haste:1125795636181213325>", - "Freeze Spell": "<:fs:1125795638907502602>", - "Earthquake Spell": "<:es:1125795641654788256>", - "Bat Spell": "<:bat:1125795643689025606>", - "Clone Spell": "<:cs:1125795645958144162>", - "clan castle": "<:clan_castle:1125795648462147594>", - "shield": "<:clash:1125795651280699392>", - "Electro Titan": "<:ElectroTitan:1029213693021519963>", - "Battle Drill": "<:BattleDrill:1029199490038628442>", - "Recall Spell": "<:recall:1029199491385012304>", "Frosty": "<:Frosty:1029199487849201785>", "Poison Lizard": "<:PoisonLizard:1029199485450068029>", "Phoenix": "<:Phoenix:1029199486347661343>", "Diggy": "<:Diggy:1029199488906170428>", "Root Rider": "<:RootRider:1183561929864794222>", "Spirit Fox": "<:PhaseFennec:1183561928438718494>", - 1: "<:02:1125807195456536677>", - 2: "<:02:1125807195456536677>", - 3: "<:03:1125807197415288923>", - 4: "<:04:1125807199495667743>", - 5: "<:05:1125807201752195153>", - 6: "<:06:1125807203803213954>", - 7: "<:07:1125807205757751397>", - 8: "<:08:1125810709406679081>", - 9: "<:09:1125810712078454854>", - 10: "<:10:1125810714179817604>", - 11: "<:11:1125810716608303244>", - 12: "<:12:1125810719259115631>", - 13: "<:132:1125810721490473091>", - 14: "<:14:1125810723822506015>", - 15: "<:th15_big:1029215029486157855>", - 16: "<:16:1183533663367987252>", +} +hero_equipment_emojis = { "Barbarian Puppet": "<:BarbDoll:1183561776642662420>", "Rage Vial": "<:RageVial:1183561869282258984>", "Archer Puppet": "<:ArcherDoll:1183561721445625937>", @@ -111,8 +66,9 @@ "Rage Gem": "<:RageGem:1183561924064051343>", "Healing Tome": "<:HeartTome:1183561922319229009>", "Freeze Arrow": "<:FreezeArrow:1183561723500834846>", +} - "Capital Gold": "<:capitalgold:1125795653696626860>", +capital_hall_emojis = { "Capital_Hall7": "<:CH7:1125795655646986291>", "District_Hall4": "<:DH4:1125795658629128213>", "District_Hall5": "<:DH5:1125795660650786906>", @@ -128,6 +84,9 @@ "Capital_Hall3": "<:CH3:1125795684176633878>", "Capital_Hall2": "<:CH2:1125795686139576340>", "Capital_Hall1": "<:CH1:1125795688802951270>", +} + +builder_base_emojis = { "Bomber": "<:Bomber:1125800091161202750>", "Hog Glider": "<:HogGlider:1125799777020424223>", "Cannon Cart": "<:CannonCart:1125800093753298985>", @@ -139,21 +98,78 @@ "Night Witch": "<:NightWitch:1125800110111076454>", "Sneaky Archer": "<:SneakyArcher:1125800112480854156>", "Battle Machine": "<:bm:1041499330240053352>", - "Super Hog Rider": "<:SHogRider:1120604618100060180>", - "Apprentice Warden": "<:Apprentice:1120604620713107507>" + "Battle Copter": "<:battle_copter:1109716293696888852>", + "Electrofire Wizard": "<:electro_wiz:1109716130735587358>", } -def emojiDictionary(emojiName): - return switcher.get(emojiName) +siege_machine_emojis = { + "Wall Wrecker": "<:WallWrecker:1125780628328153129>", + "Battle Blimp": "<:BattleBlimp:1125780630463057991>", + "Stone Slammer": "<:StoneSlammer:1125780633055133706>", + "Siege Barracks": "<:SiegeBarracks:1125795608788226109>", + "Log Launcher": "<:LogLauncher:1125795611925549097>", + "Flame Flinger": "<:FlameFlinger:1125795614261776484>", + "Battle Drill": "<:BattleDrill:1029199490038628442>", +} +spell_emojis = { + "Skeleton Spell": "<:skel:1125795616698667051>", + "Rage Spell": "<:rs:1125795619831812096>", + "Poison Spell": "<:ps:1125795621895405598>", + "Healing Spell": "<:hs:1125795624319717426>", + "Invisibility Spell": "<:invi:1125795629516476518>", + "Jump Spell": "<:js:1125795631936573450>", + "Lightning Spell": "<:ls:1125795633907904512>", + "Haste Spell": "<:haste:1125795636181213325>", + "Freeze Spell": "<:fs:1125795638907502602>", + "Earthquake Spell": "<:es:1125795641654788256>", + "Bat Spell": "<:bat:1125795643689025606>", + "Clone Spell": "<:cs:1125795645958144162>", + "Recall Spell": "<:recall:1029199491385012304>", +} +troop_emojis = { + "Archer": "<:Archer:1125780518433206302>", + "Baby Dragon": "<:BabyDragon:1125780520991731723>", + "Barbarian": "<:Barbarian:1125780523495731271>", + "Bowler": "<:Bowler:1125780525102149723>", + "Electro Dragon": "<:ElectroDragon:1125780527052505128>", + "Dragon": "<:Dragon:1125780530445693059>", + "Dragon Rider": "<:dragon_rider:1125780532840644669>", + "Balloon": "<:Balloon:1125780535801806858>", + "Ice Golem": "<:IceGolem:1125780538955939920>", + "Miner": "<:Miner:1125780541090840586>", + "Hog Rider": "<:HogRider:1125780543473205318>", + "Yeti": "<:Yeti:1125780545981403226>", + "Wizard": "<:Wizard:1125780548154040361>", + "Healer": "<:Healer:1125780550569951453>", + "Giant": "<:Giant:1125780552419659806>", + "Goblin": "<:Goblin:1125780554537762897>", + "Witch": "<:Witch:1125780557029187594>", + "Minion": "<:Minion:1125780559830986752>", + "P.E.K.K.A": "<:PEKKA:1125780562586640464>", + "Wall Breaker": "<:WallBreaker:1125780564667011144>", + "Golem": "<:Golem:1125780566508314624>", + "Lava Hound": "<:LavaHound:1125780568559333376>", + "Valkyrie": "<:Valkyrie:1125780570601947178>", + "Headhunter": "<:Headhunter:1125780573588299896>", + "Electro Titan": "<:ElectroTitan:1029213693021519963>", + "Apprentice Warden": "<:Apprentice:1120604620713107507>" +} + +hero_emojis = { + "Barbarian King": "<:BarbarianKing:1125780508190720041>", + "Archer Queen": "<:ArcherQueen:1125780510485004399>", + "Grand Warden": "<:GrandWarden:1125780512699592725>", + "Royal Champion": "<:RoyalChampion:1125780514486353983>", +} -emoji_class_dict = { +icon_emojis = { + "trophy": "<:trophyy:1125780625778016277>", "discord": "<:discord:840749695466864650>", "clan_castle": "<:clan_castle:855688168816377857>", "shield": "<:sh:948845842809360424>", - "trophy": "<:trophyy:849144172698402817>", "capital_gold": "<:capitalgold:987861320286216223>", "legends_shield": "<:legends:881450752109850635>", "sword": "<:cw:948845649229647952>", @@ -224,9 +240,77 @@ def emojiDictionary(emojiName): "globe": "<:globe:1113285560715444274>", "wood_swords": "<:wood_swords:1109716092647112787>", "red_pin": "<:redpin:1130343263698690128>", - "wbb_red": "", "spells": "<:spells:1184426093353127966>", "heart": "<:heart:1184426691704135701>", "pet_paw": "<:pet:1184426579149987852>" } +league_emojis = { + "Bronze League I": "<:BronzeLeagueI:601611950228635648>", + "Bronze League II": "<:BronzeLeagueII:601611942850986014>", + "Bronze League III": "<:BronzeLeagueIII:601611929311510528>", + "Champion League I": "<:ChampionLeagueI:601612124447440912>", + "Champion League II": "<:ChampionLeagueII:601612113345249290>", + "Champion League III": "<:ChampionLeagueIII:601612099226959892>", + "Crystal League I": "<:CrystalLeagueI:601612045359775746>", + "Crystal League II": "<:CrystalLeagueII:601612033976434698>", + "Crystal League III": "<:CrystalLeagueIII:601612021472952330>", + "Gold League I": "<:GoldLeagueI:601612010492526592>", + "Gold League II": "<:GoldLeagueII:601611996290613249>", + "Gold League III": "<:GoldLeagueIII:601611988992262144>", + "Legend League": "<:LegendLeague:601612163169255436>", + "Master League I": "<:MasterLeagueI:601612085327036436>", + "Master League II": "<:MasterLeagueII:601612075474616399>", + "Master League III": "<:MasterLeagueIII:601612064913621002>", + "Silver League I": "<:SilverLeagueI:601611974849331222>", + "Silver League II": "<:SilverLeagueII:601611965550428160>", + "Silver League III": "<:SilverLeagueIII:601611958067920906>", + "Titan League I": "<:TitanLeagueI:601612159327141888>", + "Titan League II": "<:TitanLeagueII:601612148325744640>", + "Titan League III": "<:TitanLeagueIII:601612137491726374>", +} + +builder_league_emojis = { + "Wood": "<:wood_league:1109716152709566524>", + "Clay": "<:clay_league:1109716160561291274>", + "Stone": "<:stone_league:1109716159126843403>", + "Copper": "<:copper_league:1109716157440720966>", + "Brass": "<:brass_league:1109716155876249620>", + "Iron": "<:iron_league:1109716154257264670>", + "Steel": "<:steel_league:1109716168375279616>", + "Titanium": "<:titanium_league:1109716170208198686>", + "Platinum": "<:platinum_league:1109716172330512384>", + "Emerald": "<:emerald_league:1109716179121094707>", + "Ruby": "<:ruby_league:1109716183269265501>", + "Diamond": "<:diamond_league:1109716180983369768>" +} + +cwl_league_emojis = { + "CWL Bronze League I": "<:WarBronzeI:1116151829617705000>", + "CWL Bronze League II": "<:WarBronzeII:1116151836035006464>", + "CWL Bronze League III": "<:WarBronzeIII:1116151838136356895>", + "CWL Silver League I": "<:WarSilverI:1116151826870456420>", + "CWL Silver League II": "<:WarSilverII:1116151831542907011>", + "CWL Silver League III": "<:WarSilverIII:1116151833891704953>", + "CWL Gold League I": "<:WarGoldI:1116151792904966154>", + "CWL Gold League II": "<:WarGoldII:1116151794721103912>", + "CWL Gold League III": "<:WarGoldIII:1116151824471293954>", + "CWL Crystal League I": "<:WarCrystalI:1116151785476866109>", + "CWL Crystal League II": "<:WarCrystalII:1116151788895211682>", + "CWL Crystal League III": "<:WarCrystalIII:1116151790946230312>", + "CWL Master League I": "<:WarMasterI:1116151777813868596>", + "CWL Master League II": "<:WarMasterII:1116151780074598421>", + "CWL Master League III": "<:WarMasterIII:1116151784059191347>", + "CWL Champion League I": "<:WarChampionI:1116151613795598407>", + "CWL Champion League II": "<:WarChampionII:1116151615506894858>", + "CWL Champion League III": "<:WarChampionIII:1116151617922809947>" +} + + + +class SharedEmojis: + all_emojis = (townhall_emojis | super_troop_emojis | pet_emojis | hero_equipment_emojis | capital_hall_emojis | + league_emojis | cwl_league_emojis | builder_league_emojis | + builder_base_emojis | siege_machine_emojis | spell_emojis | troop_emojis | hero_emojis | icon_emojis) + + diff --git a/background/logs/auto_eval.py b/background/logs/auto_eval.py index 669c8e3c..adebe08d 100644 --- a/background/logs/auto_eval.py +++ b/background/logs/auto_eval.py @@ -7,7 +7,7 @@ from typing import TYPE_CHECKING from classes.bot import CustomClient from background.logs.events import clan_ee -from Link_and_Eval.eval_logic import eval_logic +from commands.eval.utils import logic class AutoEval(commands.Cog): diff --git a/background/logs/ban_events.py b/background/logs/ban_events.py index 5cec47ee..5562b440 100644 --- a/background/logs/ban_events.py +++ b/background/logs/ban_events.py @@ -40,9 +40,8 @@ async def ban_alerts(self, event): date = results.get("DateCreated")[:10] role = f"<@&{db_clan.member_role}>" - embed = disnake.Embed( - description=f"[WARNING! BANNED PLAYER {member.name} JOINED]({member.share_link})", + description=f"{role}\n[WARNING! BANNED PLAYER {member.name} JOINED]({member.share_link})", color=disnake.Color.green()) embed.add_field(name="Banned Player.", value=f"Player {member.name} [{member.tag}] has joined {clan.name} and is on the {server.name} BAN list!\n\n" diff --git a/background/logs/clan_capital_events.py b/background/logs/clan_capital_events.py index 3bf6db96..7cc55c6b 100644 --- a/background/logs/clan_capital_events.py +++ b/background/logs/clan_capital_events.py @@ -1,17 +1,16 @@ -from disnake.ext import commands import disnake import coc +from disnake.ext import commands from classes.server import DatabaseClan -from typing import TYPE_CHECKING from classes.bot import CustomClient from background.logs.events import player_ee, raid_ee from datetime import datetime from pytz import utc from coc.raid import RaidLogEntry, RaidAttack, RaidMember from numerize import numerize -from ImageGen.ClanCapitalResult import calc_raid_medals -from BoardCommands.Utils import Clan as clan_embeds +#from ImageGen.ClanCapitalResult import calc_raid_medals +#from BoardCommands.Utils import Clan as clan_embeds from exceptions.CustomExceptions import MissingWebhookPerms class clan_capital_events(commands.Cog, name="Clan Capital Events"): diff --git a/background/logs/donations.py b/background/logs/donations.py index 82d598d7..2647d56e 100644 --- a/background/logs/donations.py +++ b/background/logs/donations.py @@ -2,16 +2,14 @@ import disnake from disnake.ext import commands -from utility.clash import heros -from typing import TYPE_CHECKING from classes.bot import CustomClient from classes.server import DatabaseClan from background.logs.events import clan_ee -from utility.clash import leagueAndTrophies from pymongo import UpdateOne from utility.discord_utils import get_webhook_for_channel from exceptions.CustomExceptions import MissingWebhookPerms + class Donations(commands.Cog, name="Donations"): def __init__(self, bot: CustomClient): @@ -20,14 +18,13 @@ def __init__(self, bot: CustomClient): self.clan_ee.on("all_member_donations", self.donations) async def donations(self, event): - clan = coc.Clan(data=event["new_clan"], client=self.bot.coc_client) old_clan = coc.Clan(data=event["old_clan"], client=self.bot.coc_client) tag_to_member = {member.tag : member for member in clan.members} donated = [] received = [] - changes = [] + for old_member in old_clan.members: new_member: coc.ClanMember = tag_to_member.get(old_member.tag) if new_member is None: @@ -35,14 +32,10 @@ async def donations(self, event): change_dono = new_member.donations - old_member.donations change_rec = new_member.received - old_member.received if change_dono > 0: - change_amount = 0.05 if new_member.donations > 100000 else 0.25 donated.append((new_member, change_dono)) - changes.append(UpdateOne({"tag": new_member.tag}, {"$inc": {f"points": change_amount * change_dono}}, upsert=True)) if change_rec > 0: received.append((new_member, change_rec)) - if changes: - await self.bot.player_stats.bulk_write(changes) embed = disnake.Embed(description=f"[**{clan.name}**]({clan.share_link})") embed.set_thumbnail(url=clan.badge.url) diff --git a/background/logs/events.py b/background/logs/events.py index a5729ac3..c737cdf2 100644 --- a/background/logs/events.py +++ b/background/logs/events.py @@ -1,3 +1,6 @@ +import asyncio + +import disnake import orjson from classes.config import Config from pymitter import EventEmitter @@ -7,30 +10,59 @@ clan_ee = EventEmitter() war_ee = EventEmitter() raid_ee = EventEmitter() +reminder_ee = EventEmitter() +from aiokafka import AIOKafkaConsumer, TopicPartition -from aiokafka import AIOKafkaConsumer - - -async def kafka_events(): - consumer: AIOKafkaConsumer = AIOKafkaConsumer("clan", "capital", bootstrap_servers='85.10.200.219:9092') +async def kafka_events(bot: disnake.Client): + topic = "player" + consumer: AIOKafkaConsumer = AIOKafkaConsumer(topic, bootstrap_servers='85.10.200.219:9092') await consumer.start() + await bot.wait_until_ready() try: async for msg in consumer: + json_message = orjson.loads(msg.value) + + if (f := json_message.get("type")) is not None: + fields = [f] + else: + fields = json_message.get("types", []) + + if "heroes" not in fields: + continue + + for field in fields: + if field != "heroes": + continue + awaitable = None + if msg.topic == "player": + awaitable = player_ee.emit_async(field, json_message) + elif msg.topic == "war": + awaitable = war_ee.emit_async(field, json_message) + if msg.topic == "clan": + awaitable = clan_ee.emit_async(field, json_message) + elif msg.topic == "capital": + awaitable = raid_ee.emit_async(field, json_message) + if awaitable is not None: + await awaitable + + '''async for msg in consumer: print(msg) + continue json_message = orjson.loads(msg.value) + field = json_message["type"] awaitable = None - '''if msg.topic == "player": + if msg.topic == "player": awaitable = player_ee.emit_async(field, json_message) elif msg.topic == "war": - awaitable = war_ee.emit_async(field, json_message)''' + awaitable = war_ee.emit_async(field, json_message) if msg.topic == "clan": awaitable = clan_ee.emit_async(field, json_message) - '''elif msg.topic == "capital": - awaitable = raid_ee.emit_async(field, json_message)''' + elif msg.topic == "capital": + awaitable = raid_ee.emit_async(field, json_message) if awaitable is not None: - await awaitable + await awaitable''' finally: await consumer.stop() \ No newline at end of file diff --git a/background/logs/join_leave_events.py b/background/logs/join_leave_events.py index eaf24f92..787ce3cf 100644 --- a/background/logs/join_leave_events.py +++ b/background/logs/join_leave_events.py @@ -2,15 +2,14 @@ import disnake from disnake.ext import commands -from utility.clash import heros -from typing import TYPE_CHECKING +from utility.clash.other import heros, leagueAndTrophies, basic_heros from classes.bot import CustomClient from classes.server import DatabaseClan from background.logs.events import clan_ee -from utility.clash import leagueAndTrophies from utility.discord_utils import get_webhook_for_channel from exceptions.CustomExceptions import MissingWebhookPerms + class join_leave_events(commands.Cog, name="Clan Join & Leave Events"): def __init__(self, bot: CustomClient): @@ -62,8 +61,7 @@ async def player_join(self, event): log = db_clan.join_log player = await self.bot.getPlayer(player_tag=member.tag) - hero = heros(bot=self.bot, player=player) - hero = "" if hero is None else hero + hero = basic_heros(bot=self.bot, player=player) th_emoji = self.bot.fetch_emoji(player.town_hall) embed = disnake.Embed(description=f"[**{player.name}** ({player.tag})]({player.share_link})\n" + @@ -100,7 +98,8 @@ async def player_leave(self, event): clan = coc.Clan(data=event["clan"], client=self.bot.coc_client) member = coc.ClanMember(data=event["member"], client=self.bot.coc_client, clan=clan) - for cc in await self.bot.clan_db.find({"$and": [{"tag": clan.tag}, {"logs.leave_log.webhook": {"$ne" : None}}]}).to_list(length=None): + tracked = self.bot.clan_db.find({"$and": [{"tag": clan.tag}, {"logs.join_log.webhook": {"$ne" : None}}]}) + for cc in await tracked.to_list(length=None): db_clan = DatabaseClan(bot=self.bot, data=cc) if db_clan.server_id not in self.bot.OUR_GUILDS: continue @@ -124,8 +123,7 @@ async def player_leave(self, event): log = db_clan.leave_log player = await self.bot.getPlayer(player_tag=member.tag) - hero = heros(bot=self.bot, player=player) - hero = "" if hero is None else hero + hero = basic_heros(bot=self.bot, player=player) th_emoji = self.bot.fetch_emoji(player.town_hall) embed = disnake.Embed(description=f"[**{player.name}** ({player.tag})]({player.share_link})\n" + diff --git a/background/logs/legend_events.py b/background/logs/legend_events.py index a862d5ee..42fc1e47 100644 --- a/background/logs/legend_events.py +++ b/background/logs/legend_events.py @@ -1,30 +1,104 @@ -import coc import disnake +import pendulum as pend +import msgspec + from disnake.ext import commands -from typing import TYPE_CHECKING from classes.bot import CustomClient from classes.server import DatabaseClan from background.logs.events import player_ee -from datetime import datetime -from pytz import utc from utility.discord_utils import get_webhook_for_channel from exceptions.CustomExceptions import MissingWebhookPerms +from msgspec import Struct +from typing import Optional, List + +class Badges(Struct): + large: str + def to_dict(self): + return {f: getattr(self, f) for f in self.__struct_fields__} + +class Clan(Struct): + name: str + tag: str + badgeUrls: Badges + + def to_dict(self): + result = {f: getattr(self, f) for f in self.__struct_fields__} + for field, value in result.items(): + if isinstance(value, Struct): + result[field] = value.to_dict() # Recursively convert nested structs + elif isinstance(value, list) and all(isinstance(item, Struct) for item in value): + result[field] = [item.to_dict() for item in value] # Convert lists of structs + + return result + +class Equipment(Struct): + name: str + level: int + + def to_dict(self): + return {f: getattr(self, f) for f in self.__struct_fields__} + +class Heroes(Struct): + name: str + equipment: Optional[List[Equipment]] = list() + + def to_dict(self): + result = {f: getattr(self, f) for f in self.__struct_fields__} + for field, value in result.items(): + if isinstance(value, Struct): + result[field] = value.to_dict() # Recursively convert nested structs + elif isinstance(value, list) and all(isinstance(item, Struct) for item in value): + result[field] = [item.to_dict() for item in value] # Convert lists of structs + + return result + +class League(Struct): + name: str + + def to_dict(self): + return {f: getattr(self, f) for f in self.__struct_fields__} + +class Player(Struct): + name: str + tag: str + trophies: int + attackWins: int + defenseWins: int + heroes: List[Heroes] + equipment: Optional[List[Equipment]] = list() + clan: Optional[Clan] = None + league: Optional[League] = None + + def to_dict(self): + result = {f: getattr(self, f) for f in self.__struct_fields__} + for field, value in result.items(): + if isinstance(value, Struct): + result[field] = value.to_dict() # Recursively convert nested structs + elif isinstance(value, list) and all(isinstance(item, Struct) for item in value): + result[field] = [item.to_dict() for item in value] # Convert lists of structs + + return result + + def share_link(self): + return f"https://link.clashofclans.com/en?action=OpenPlayerProfile&tag=%23{self.tag.strip('#')}" + + class LegendEvents(commands.Cog): def __init__(self, bot: CustomClient): self.bot = bot self.player_ee = player_ee - self.player_ee.on("trophies", self.legend_event) + self.player_ee.on("legends", self.legend_event) async def legend_event(self, event): - player = coc.Player(data=event["new_player"], client=self.bot.coc_client) + player = msgspec.convert(event["new_data"], Player) if player.clan is None: return - old_player = coc.Player(data=event["old_player"], client=self.bot.coc_client) + old_player = msgspec.convert(event["old_data"], Player) trophy_change = player.trophies - old_player.trophies - utc_time = datetime.now(utc).replace(tzinfo=utc) + utc_time = pend.now(tz=pend.UTC) if trophy_change >= 1: color = disnake.Color.green() @@ -35,8 +109,8 @@ async def legend_event(self, event): change = f"{self.bot.emoji.shield} {trophy_change} trophies" type = "logs.legend_log_defenses.webhook" - embed = disnake.Embed(description=f"{change} | [profile]({player.share_link})", color=color) - embed.set_author(name=f"{player.name} | {player.clan.name}", icon_url=player.clan.badge.url) + embed = disnake.Embed(description=f"{change} | [profile]({player.share_link()})", color=color) + embed.set_author(name=f"{player.name} | {player.clan.name}", icon_url=player.clan.badgeUrls.large) embed.set_footer(text=f"{player.trophies}", icon_url=self.bot.emoji.legends_shield.partial_emoji.url) embed.timestamp = utc_time diff --git a/background/logs/player_upgrade_events.py b/background/logs/player_upgrade_events.py index d6b59b2f..3cabb62e 100644 --- a/background/logs/player_upgrade_events.py +++ b/background/logs/player_upgrade_events.py @@ -1,17 +1,15 @@ -from disnake.ext import commands import disnake import coc import re +from disnake.ext import commands from classes.server import DatabaseClan -from typing import TYPE_CHECKING from classes.bot import CustomClient from background.logs.events import player_ee -from utility.clash import league_emoji -from pytz import utc +from utility.clash.other import league_emoji from utility.discord_utils import get_webhook_for_channel from exceptions.CustomExceptions import MissingWebhookPerms -from BoardCommands.Utils.Player import upgrade_embed +#from BoardCommands.Utils.Player import upgrade_embed class UpgradeEvent(commands.Cog): @@ -24,6 +22,9 @@ def __init__(self, bot: CustomClient): self.player_ee.on("townHallLevel", self.th_upgrade) self.player_ee.on("name", self.name_change) self.player_ee.on("league", self.league_change) + self.player_ee.on("role", self.role_change) + self.player_ee.on("heroEquipment", self.gear_upgrade) + async def league_change(self, event): new_player = coc.Player(data=event["new_player"], client=self.bot.coc_client) @@ -90,6 +91,39 @@ async def name_change(self, event): continue + async def role_change(self, event): + new_player = coc.Player(data=event["new_player"], client=self.bot.coc_client) + if new_player.clan is None or new_player.role is None: + return + + new_name = re.sub('[*_`~/]', '', new_player.name) + old_player = coc.Player(data=event["old_player"], client=self.bot.coc_client) + for cc in await self.bot.clan_db.find({"$and": [{"tag": new_player.clan.tag}, {f"logs.role_change.webhook": {"$ne": None}}]}).to_list(length=None): + clan = DatabaseClan(bot=self.bot, data=cc) + if clan.server_id not in self.bot.OUR_GUILDS: + continue + + content = f"{self.bot.fetch_emoji(name=new_player.town_hall)}[{new_name}](<{new_player.share_link}>) {old_player.role.in_game_name} -> {new_player.role.in_game_name}" + + log = clan.role_change + try: + webhook = await self.bot.getch_webhook(log.webhook) + if webhook.user.id != self.bot.user.id: + webhook = await get_webhook_for_channel(bot=self.bot, channel=webhook.channel) + await log.set_webhook(id=webhook.id) + if log.thread is not None: + thread = await self.bot.getch_channel(log.thread) + if thread.locked: + continue + await webhook.send(content=content, thread=thread) + else: + await webhook.send(content=content) + except (disnake.NotFound, disnake.Forbidden, MissingWebhookPerms): + await log.set_thread(id=None) + await log.set_webhook(id=None) + continue + + async def th_upgrade(self, event): new_player = coc.Player(data=event["new_player"], client=self.bot.coc_client) if new_player.clan is None: @@ -202,9 +236,7 @@ async def hero_upgrade(self, event): clan = DatabaseClan(bot=self.bot, data=cc) if clan.server_id not in self.bot.OUR_GUILDS: continue - log = clan.hero_upgrade - if text is None: old_player = coc.Player(data=event["old_player"], client=self.bot.coc_client) unlocked = [] @@ -241,6 +273,54 @@ async def hero_upgrade(self, event): continue + async def gear_upgrade(self, event): + new_player = coc.Player(data=event["new_player"], client=self.bot.coc_client) + if new_player.clan is None: + return + + name = re.sub('[*_`~/]', '', new_player.name) + text = None + for cc in await self.bot.clan_db.find({"$and": [{"tag": new_player.clan.tag}, {f"logs.hero_equipment_upgrade.webhook": {"$ne": None}}]}).to_list(length=None): + clan = DatabaseClan(bot=self.bot, data=cc) + if clan.server_id not in self.bot.OUR_GUILDS: + continue + log = clan.hero_equipment_upgrade + if text is None: + old_player = coc.Player(data=event["old_player"], client=self.bot.coc_client) + unlocked = [] + leveled_up = [] + for gear in new_player.equipment: + old_gear = old_player.get_equipment(name=gear.name) + if old_gear is None: + unlocked.append(gear) + elif gear.level > old_gear.level: + leveled_up.append(gear) + if not unlocked and not leveled_up: + return + text = "" + for gear in unlocked: + text += f"{self.bot.fetch_emoji(name=new_player.town_hall)}[{name}](<{new_player.share_link}>) unlocked {self.bot.fetch_emoji(name=gear.name)}{gear.name}\n" + for gear in leveled_up: + text += f"{self.bot.fetch_emoji(name=new_player.town_hall)}[{name}](<{new_player.share_link}>) leveled up {self.bot.fetch_emoji(name=gear.name)}{gear.name} to lv{gear.level}\n" + + try: + webhook = await self.bot.getch_webhook(log.webhook) + if webhook.user.id != self.bot.user.id: + webhook = await get_webhook_for_channel(bot=self.bot, channel=webhook.channel) + await log.set_webhook(id=webhook.id) + if log.thread is not None: + thread = await self.bot.getch_channel(log.thread) + if thread.locked: + continue + await webhook.send(content=text, thread=thread) + else: + await webhook.send(content=text) + except (disnake.NotFound, disnake.Forbidden, MissingWebhookPerms): + await log.set_thread(id=None) + await log.set_webhook(id=None) + continue + + async def spells_upgrade(self, event): new_player = coc.Player(data=event["new_player"], client=self.bot.coc_client) if new_player.clan is None: @@ -299,8 +379,8 @@ async def on_button_click(self, ctx: disnake.MessageInteraction): player = await self.bot.getPlayer(player_tag=tag, custom=True) if player is None: return await ctx.edit_original_response(content="No player found.") - embeds = await upgrade_embed(self.bot, player) - await ctx.edit_original_response(embeds=embeds) + #embeds = await upgrade_embed(self.bot, player) + #await ctx.edit_original_response(embeds=embeds) def setup(bot: CustomClient): bot.add_cog(UpgradeEvent(bot)) \ No newline at end of file diff --git a/background/logs/reddit_recruit_feed.py b/background/logs/reddit_recruit_feed.py index 25d8f3f9..5347c88e 100644 --- a/background/logs/reddit_recruit_feed.py +++ b/background/logs/reddit_recruit_feed.py @@ -1,15 +1,15 @@ -from disnake.ext import commands -from typing import TYPE_CHECKING -from classes.bot import CustomClient -from utility.player_pagination import button_pagination -from datetime import datetime - import asyncpraw import os import disnake import re import coc +from disnake.ext import commands +from classes.bot import CustomClient +from utility.player_pagination import button_pagination +from datetime import datetime + + subreddit = "ClashOfClansRecruit" secret = os.getenv("SECRET") RPW = os.getenv("RPW") diff --git a/background/logs/reminders.py b/background/logs/reminders.py new file mode 100644 index 00000000..1b20f09d --- /dev/null +++ b/background/logs/reminders.py @@ -0,0 +1,20 @@ +from disnake.ext import commands +from classes.bot import CustomClient +from background.logs.events import reminder_ee +from commands.reminders.send_reminders import war_reminder + + +class Reminders(commands.Cog): + + def __init__(self, bot: CustomClient): + self.bot = bot + self.reminder_ee = reminder_ee + self.reminder_ee.on("war", self.war_reminder_event) + + + async def war_reminder_event(self, event): + await war_reminder(bot=self.bot, event=event) + + +def setup(bot: CustomClient): + bot.add_cog(Reminders(bot)) \ No newline at end of file diff --git a/background/logs/war_track.py b/background/logs/war_track.py index 5762dcf1..5aed6168 100644 --- a/background/logs/war_track.py +++ b/background/logs/war_track.py @@ -3,10 +3,9 @@ import coc import disnake import pytz -from ImageGen import WarEndResult as war_gen +from utility.imagegen import WarEndResult as war_gen from disnake.ext import commands -from assets.emojiDictionary import emojiDictionary -from typing import TYPE_CHECKING +from assets.emojis import emoji_holder from classes.bot import CustomClient from datetime import datetime diff --git a/background/tasks/background_cache.py b/background/tasks/background_cache.py index f4205d82..edf61a54 100644 --- a/background/tasks/background_cache.py +++ b/background/tasks/background_cache.py @@ -1,36 +1,28 @@ -import pytz -import os -import time -from typing import TYPE_CHECKING + from classes.bot import CustomClient from disnake.ext import commands, tasks -utc = pytz.utc -EMAIL = os.getenv("LEGEND_EMAIL") -PASSWORD = os.getenv("LEGEND_PW") class BackgroundCache(commands.Cog): def __init__(self, bot: CustomClient): self.bot = bot - self.guilds.start() + self.guilds_store.start() @tasks.loop(seconds=60) - async def guilds(self): - guild_fetch = await self.bot.server_db.distinct("server") + async def guilds_store(self): if not self.bot.user.public_flags.verified_bot: - guild_fetch = [guild.id for guild in self.bot.guilds if guild.id != 923764211845312533] - x = guild_fetch - if self.bot.user.public_flags.verified_bot: - active_custom_bots = await self.bot.credentials.distinct("server") - for bot in active_custom_bots: - try: - x.remove(bot) - except: - pass - self.bot.OUR_GUILDS = set(x) + guild_id_list = [guild.id for guild in self.bot.guilds] + await self.bot.custom_bots.update_one({"token" : self.bot._config.bot_token}, {"$set" : {"server_ids" : guild_id_list}}) + else: + guild_id_list = [guild.id for guild in self.bot.guilds] + self.bot.OUR_GUILDS = set(guild_id_list) + + @guilds_store.before_loop + async def before_guilds_store(self): + await self.bot.wait_until_ready() def setup(bot: CustomClient): diff --git a/background/tasks/emoji_refresh.py b/background/tasks/emoji_refresh.py index 41ea2b47..2aa4f4ef 100644 --- a/background/tasks/emoji_refresh.py +++ b/background/tasks/emoji_refresh.py @@ -1,5 +1,4 @@ -import random - +from collections import deque from classes.bot import CustomClient from disnake.ext import commands, tasks from utility.constants import BADGE_GUILDS @@ -28,6 +27,27 @@ async def refresh(self): for emoji in guild.emojis: emoji_map[emoji.name] = f"<:{emoji.name}:{emoji.id}>" self.bot.clan_badge_emoji_map = emoji_map + else: + our_badge_guild = [server.id for server in self.bot.guilds if server.owner_id == self.bot.user.id and server.name == "ckcustombotbadges"] + if our_badge_guild: + emoji_map = {} + self.bot.BADGE_GUILDS = deque(our_badge_guild) + for guild_id in self.bot.BADGE_GUILDS: + guild = await self.bot.getch_guild(guild_id) + #only shard one needs to worry about deleting + if self.bot.shard_id == 1 and len(guild.emojis) >= 46 : + num_to_delete = len(guild.emojis) - 45 + #sort from newest to oldest to remove the old ones + guild_emojis = sorted(guild.emojis, key=lambda x : x.id, reverse=True) + for emoji in guild_emojis[(-1 * num_to_delete):]: + await emoji.delete() + for emoji in guild.emojis: + emoji_map[emoji.name] = f"<:{emoji.name}:{emoji.id}>" + self.bot.clan_badge_emoji_map = emoji_map + + @refresh.before_loop + async def before_refresh(self): + await self.bot.wait_until_ready() def setup(bot: CustomClient): diff --git a/classes/DatabaseClient/Classes/abc.py b/classes/DatabaseClient/Classes/abc.py index febf02e6..87c29e3e 100644 --- a/classes/DatabaseClient/Classes/abc.py +++ b/classes/DatabaseClient/Classes/abc.py @@ -1,7 +1,7 @@ import coc from utility.constants import SUPER_SCRIPTS, SHORT_CLAN_LINK, SHORT_PLAYER_LINK from classes.emoji import EmojiType -from assets.emojiDictionary import emojiDictionary +from assets.emojis import SharedEmojis from assets.thPicDictionary import thDictionary import emoji import re @@ -73,7 +73,7 @@ def __int__(self): @property def emoji(self): - return EmojiType(emojiDictionary(self.level)) + return EmojiType(SharedEmojis.all_emojis.get(self.level)) @property def image_url(self): diff --git a/classes/bot.py b/classes/bot.py index fec611ff..2aa29f00 100644 --- a/classes/bot.py +++ b/classes/bot.py @@ -6,12 +6,9 @@ import disnake import re import asyncio -import collections -import random import calendar import aiohttp import emoji -import expiring_dict import pendulum as pend from math import ceil @@ -19,7 +16,7 @@ from coc.ext import discordlinks from disnake.ext import commands from typing import Dict, List -from assets.emojiDictionary import emojiDictionary +from assets.emojis import SharedEmojis from classes.player import MyCustomPlayer, CustomClanClass from classes.emoji import Emojis, EmojiType from urllib.request import urlopen @@ -76,6 +73,7 @@ def __init__(self, config: Config, command_prefix: str, help_command, intents: d self.link_client: coc.ext.discordlinks.DiscordLinkClient = asyncio.get_event_loop().run_until_complete(discordlinks.login(self._config.link_api_username, self._config.link_api_password)) self.bot_stats: collection_class = self.looper_db.clashking.bot_stats self.clan_stats: collection_class = self.new_looper.clan_stats + self.war_elo: collection_class = self.looper_db.looper.war_elo self.raid_weekend_db: collection_class = self.looper_db.looper.raid_weekends self.clan_join_leave: collection_class = self.new_looper.clan_join_leave @@ -139,7 +137,6 @@ def __init__(self, config: Config, command_prefix: str, help_command, intents: d self.redis = redis.Redis(host=self._config.redis_ip, port=6379, db=0, password=self._config.redis_pw, retry_on_timeout=True, max_connections=250, retry_on_error=[redis.ConnectionError]) - self.emoji = Emojis() self.locations = locations self.MAX_FEED_LEN = 5 @@ -155,6 +152,11 @@ def __init__(self, config: Config, command_prefix: str, help_command, intents: d self.number_emoji_map = {} self.clan_badge_emoji_map = {} + self.BADGE_GUILDS = BADGE_GUILDS + + @property + def emoji(self): + return Emojis() def clean_string(self, text: str): @@ -183,16 +185,17 @@ async def create_new_badge_emoji(self, url:str): return self.clan_badge_emoji_map.get(new_url[-15:].replace("-", "")) img = urlopen(url).read() - BADGE_GUILDS.rotate(1) - guild = await self.getch_guild(BADGE_GUILDS[0]) + self.BADGE_GUILDS.rotate(1) + guild = await self.getch_guild(self.BADGE_GUILDS[0]) emoji = await guild.create_custom_emoji(name=new_url[-15:].replace("-", ""), image=img) return f"<:{emoji.name}:{emoji.id}>" def get_number_emoji(self, color: str, number: int) -> EmojiType: if not self.user.id == 808566437199216691 and not self.user.public_flags.verified_bot: - color = "gold" - emoji = self.number_emoji_map.get(color).get(number) + emoji = SharedEmojis.all_emojis.get(f"{number}_") + else: + emoji = self.number_emoji_map.get(color).get(number) return EmojiType(emoji_string=emoji) @@ -365,7 +368,7 @@ def partial_emoji_gen(self, emoji_string: str): def fetch_emoji(self, name: str | int): - emoji = emojiDictionary(name) + emoji = SharedEmojis.all_emojis.get(name) if emoji is None: return None return EmojiType(emoji_string=emoji) diff --git a/classes/config.py b/classes/config.py index a8b18024..78c010aa 100644 --- a/classes/config.py +++ b/classes/config.py @@ -8,8 +8,8 @@ class Config: coc_email = getenv("COC_EMAIL") coc_password = getenv("COC_PASSWORD") - min_coc_email = 1 - max_coc_email = 2 + min_coc_email = 51 + max_coc_email = 51 static_mongodb = getenv("STATIC_MONGODB") stats_mongodb = getenv("STATS_MONGODB") diff --git a/classes/emoji.py b/classes/emoji.py index 20758d9c..9682ae26 100644 --- a/classes/emoji.py +++ b/classes/emoji.py @@ -1,5 +1,5 @@ import disnake -from assets.emojiDictionary import emoji_class_dict +from assets.emojis import SharedEmojis class EmojiType(): def __init__(self, emoji_string): @@ -18,169 +18,88 @@ def partial_emoji(self): class Emojis(): def __init__(self): - self.discord = EmojiType(emoji_class_dict.get("discord")) - self.clan_castle = EmojiType(emoji_class_dict.get("clan_castle")) - self.shield = EmojiType(emoji_class_dict.get("shield")) - self.trophy = EmojiType(emoji_class_dict.get("trophy")) - self.capital_gold = EmojiType(emoji_class_dict.get("capital_gold")) - self.legends_shield = EmojiType(emoji_class_dict.get("legends_shield")) - self.sword = EmojiType(emoji_class_dict.get("sword")) - self.previous_days = EmojiType(emoji_class_dict.get("previous_days")) - self.legends_overview = EmojiType(emoji_class_dict.get("legends_overview")) - self.graph_and_stats = EmojiType(emoji_class_dict.get("graph_and_stats")) - self.history = EmojiType(emoji_class_dict.get("history")) - self.quick_check = EmojiType(emoji_class_dict.get("quick_check")) - self.gear = EmojiType(emoji_class_dict.get("gear")) - self.pin = EmojiType(emoji_class_dict.get("pin")) - self.back = EmojiType(emoji_class_dict.get("back")) - self.forward = EmojiType(emoji_class_dict.get("forward")) - self.print = EmojiType(emoji_class_dict.get("print")) - self.refresh = EmojiType(emoji_class_dict.get("refresh")) - self.trashcan = EmojiType(emoji_class_dict.get("trashcan")) - self.alphabet = EmojiType(emoji_class_dict.get("alphabet")) - self.start = EmojiType(emoji_class_dict.get("start")) - self.blue_shield = EmojiType(emoji_class_dict.get("blue_shield")) - self.blue_sword = EmojiType(emoji_class_dict.get("blue_sword")) - self.blue_trophy = EmojiType(emoji_class_dict.get("blue_trophy")) - self.grey_circle = EmojiType(emoji_class_dict.get("grey_circle")) - self.earth = EmojiType(emoji_class_dict.get("earth")) - self.sword_clash = EmojiType(emoji_class_dict.get("sword_clash")) - self.war_star = EmojiType(emoji_class_dict.get("war_star")) - self.blank = EmojiType(emoji_class_dict.get("blank")) - self.clock = EmojiType(emoji_class_dict.get("clock")) - self.troop = EmojiType(emoji_class_dict.get("troop")) - self.reddit_icon = EmojiType(emoji_class_dict.get("reddit_icon")) - self.xp = EmojiType(emoji_class_dict.get("xp")) - self.deny_mark = EmojiType(emoji_class_dict.get("deny_mark")) - self.raid_medal = EmojiType(emoji_class_dict.get("raid_medal")) - self.clan_games = EmojiType(emoji_class_dict.get("clan_games")) - self.time = EmojiType(emoji_class_dict.get("time")) - self.no_star = EmojiType(emoji_class_dict.get("no_star")) - self.yes = EmojiType(emoji_class_dict.get("yes")) - self.no = EmojiType(emoji_class_dict.get("no")) - self.gear = EmojiType(emoji_class_dict.get("gear")) - self.ratio = EmojiType(emoji_class_dict.get("ratio")) - self.switch = EmojiType(emoji_class_dict.get("switch")) - self.menu = EmojiType(emoji_class_dict.get("menu")) - self.elixir = EmojiType(emoji_class_dict.get("elixir")) - self.dark_elixir = EmojiType(emoji_class_dict.get("dark_elixir")) - self.gold = EmojiType(emoji_class_dict.get("gold")) - self.brown_shield = EmojiType(emoji_class_dict.get("brown_shield")) - self.thick_sword = EmojiType(emoji_class_dict.get("thick_sword")) - self.hitrate = EmojiType(emoji_class_dict.get("hitrate")) - self.avg_stars = EmojiType(emoji_class_dict.get("avg_stars")) - self.war_stars = EmojiType(emoji_class_dict.get("war_stars")) - self.versus_trophy = EmojiType(emoji_class_dict.get("versus_trophy")) - self.up_green_arrow = EmojiType(emoji_class_dict.get("up_green_arrow")) - self.down_red_arrow = EmojiType(emoji_class_dict.get("down_red_arrow")) - self.capital_trophy = EmojiType(emoji_class_dict.get("capital_trophy")) - self.cwl_medal = EmojiType(emoji_class_dict.get("cwl_medal")) - self.person = EmojiType(emoji_class_dict.get("person")) - self.excel = EmojiType(emoji_class_dict.get("excel")) - self.magnify_glass = EmojiType(emoji_class_dict.get("magnify_glass")) - self.right_green_arrow = EmojiType(emoji_class_dict.get("right_green_arrow")) - self.calendar = EmojiType(emoji_class_dict.get("calendar")) - self.red_status = EmojiType(emoji_class_dict.get("red_status")) - self.green_status = EmojiType(emoji_class_dict.get("green_status")) - self.toggle_on = EmojiType(emoji_class_dict.get("toggle_on")) - self.toggle_off = EmojiType(emoji_class_dict.get("toggle_off")) - self.unranked = EmojiType(emoji_class_dict.get("unranked")) - self.hashmark = EmojiType(emoji_class_dict.get("hashmark")) - self.red_tick = EmojiType(emoji_class_dict.get("red_tick")) - self.green_tick = EmojiType(emoji_class_dict.get("green_tick")) - self.opt_in = EmojiType(emoji_class_dict.get("opt_in")) - self.opt_out = EmojiType(emoji_class_dict.get("opt_out")) - self.globe = EmojiType(emoji_class_dict.get("globe")) - self.wood_swords = EmojiType(emoji_class_dict.get("wood_swords")) - self.red_pin = EmojiType(emoji_class_dict.get("red_pin")) - self.wbb_red = EmojiType(emoji_class_dict.get("wbb_red")) - self.spells = EmojiType(emoji_class_dict.get("spells")) - self.heart = EmojiType(emoji_class_dict.get("heart")) - self.pet_paw = EmojiType(emoji_class_dict.get("pet_paw")) + self.discord = EmojiType(SharedEmojis.all_emojis.get("discord")) + self.clan_castle = EmojiType(SharedEmojis.all_emojis.get("clan_castle")) + self.shield = EmojiType(SharedEmojis.all_emojis.get("shield")) + self.trophy = EmojiType(SharedEmojis.all_emojis.get("trophy")) + self.capital_gold = EmojiType(SharedEmojis.all_emojis.get("capital_gold")) + self.legends_shield = EmojiType(SharedEmojis.all_emojis.get("legends_shield")) + self.sword = EmojiType(SharedEmojis.all_emojis.get("sword")) + self.previous_days = EmojiType(SharedEmojis.all_emojis.get("previous_days")) + self.legends_overview = EmojiType(SharedEmojis.all_emojis.get("legends_overview")) + self.graph_and_stats = EmojiType(SharedEmojis.all_emojis.get("graph_and_stats")) + self.history = EmojiType(SharedEmojis.all_emojis.get("history")) + self.quick_check = EmojiType(SharedEmojis.all_emojis.get("quick_check")) + self.gear = EmojiType(SharedEmojis.all_emojis.get("gear")) + self.pin = EmojiType(SharedEmojis.all_emojis.get("pin")) + self.back = EmojiType(SharedEmojis.all_emojis.get("back")) + self.forward = EmojiType(SharedEmojis.all_emojis.get("forward")) + self.print = EmojiType(SharedEmojis.all_emojis.get("print")) + self.refresh = EmojiType(SharedEmojis.all_emojis.get("refresh")) + self.trashcan = EmojiType(SharedEmojis.all_emojis.get("trashcan")) + self.alphabet = EmojiType(SharedEmojis.all_emojis.get("alphabet")) + self.start = EmojiType(SharedEmojis.all_emojis.get("start")) + self.blue_shield = EmojiType(SharedEmojis.all_emojis.get("blue_shield")) + self.blue_sword = EmojiType(SharedEmojis.all_emojis.get("blue_sword")) + self.blue_trophy = EmojiType(SharedEmojis.all_emojis.get("blue_trophy")) + self.grey_circle = EmojiType(SharedEmojis.all_emojis.get("grey_circle")) + self.earth = EmojiType(SharedEmojis.all_emojis.get("earth")) + self.sword_clash = EmojiType(SharedEmojis.all_emojis.get("sword_clash")) + self.war_star = EmojiType(SharedEmojis.all_emojis.get("war_star")) + self.blank = EmojiType(SharedEmojis.all_emojis.get("blank")) + self.clock = EmojiType(SharedEmojis.all_emojis.get("clock")) + self.troop = EmojiType(SharedEmojis.all_emojis.get("troop")) + self.reddit_icon = EmojiType(SharedEmojis.all_emojis.get("reddit_icon")) + self.xp = EmojiType(SharedEmojis.all_emojis.get("xp")) + self.deny_mark = EmojiType(SharedEmojis.all_emojis.get("deny_mark")) + self.raid_medal = EmojiType(SharedEmojis.all_emojis.get("raid_medal")) + self.clan_games = EmojiType(SharedEmojis.all_emojis.get("clan_games")) + self.time = EmojiType(SharedEmojis.all_emojis.get("time")) + self.no_star = EmojiType(SharedEmojis.all_emojis.get("no_star")) + self.yes = EmojiType(SharedEmojis.all_emojis.get("yes")) + self.no = EmojiType(SharedEmojis.all_emojis.get("no")) + self.gear = EmojiType(SharedEmojis.all_emojis.get("gear")) + self.ratio = EmojiType(SharedEmojis.all_emojis.get("ratio")) + self.switch = EmojiType(SharedEmojis.all_emojis.get("switch")) + self.menu = EmojiType(SharedEmojis.all_emojis.get("menu")) + self.elixir = EmojiType(SharedEmojis.all_emojis.get("elixir")) + self.dark_elixir = EmojiType(SharedEmojis.all_emojis.get("dark_elixir")) + self.gold = EmojiType(SharedEmojis.all_emojis.get("gold")) + self.brown_shield = EmojiType(SharedEmojis.all_emojis.get("brown_shield")) + self.thick_sword = EmojiType(SharedEmojis.all_emojis.get("thick_sword")) + self.hitrate = EmojiType(SharedEmojis.all_emojis.get("hitrate")) + self.avg_stars = EmojiType(SharedEmojis.all_emojis.get("avg_stars")) + self.war_stars = EmojiType(SharedEmojis.all_emojis.get("war_stars")) + self.versus_trophy = EmojiType(SharedEmojis.all_emojis.get("versus_trophy")) + self.up_green_arrow = EmojiType(SharedEmojis.all_emojis.get("up_green_arrow")) + self.down_red_arrow = EmojiType(SharedEmojis.all_emojis.get("down_red_arrow")) + self.capital_trophy = EmojiType(SharedEmojis.all_emojis.get("capital_trophy")) + self.cwl_medal = EmojiType(SharedEmojis.all_emojis.get("cwl_medal")) + self.person = EmojiType(SharedEmojis.all_emojis.get("person")) + self.excel = EmojiType(SharedEmojis.all_emojis.get("excel")) + self.magnify_glass = EmojiType(SharedEmojis.all_emojis.get("magnify_glass")) + self.right_green_arrow = EmojiType(SharedEmojis.all_emojis.get("right_green_arrow")) + self.calendar = EmojiType(SharedEmojis.all_emojis.get("calendar")) + self.red_status = EmojiType(SharedEmojis.all_emojis.get("red_status")) + self.green_status = EmojiType(SharedEmojis.all_emojis.get("green_status")) + self.toggle_on = EmojiType(SharedEmojis.all_emojis.get("toggle_on")) + self.toggle_off = EmojiType(SharedEmojis.all_emojis.get("toggle_off")) + self.unranked = EmojiType(SharedEmojis.all_emojis.get("unranked")) + self.hashmark = EmojiType(SharedEmojis.all_emojis.get("hashmark")) + self.red_tick = EmojiType(SharedEmojis.all_emojis.get("red_tick")) + self.green_tick = EmojiType(SharedEmojis.all_emojis.get("green_tick")) + self.opt_in = EmojiType(SharedEmojis.all_emojis.get("opt_in")) + self.opt_out = EmojiType(SharedEmojis.all_emojis.get("opt_out")) + self.globe = EmojiType(SharedEmojis.all_emojis.get("globe")) + self.wood_swords = EmojiType(SharedEmojis.all_emojis.get("wood_swords")) + self.red_pin = EmojiType(SharedEmojis.all_emojis.get("red_pin")) + self.wbb_red = EmojiType(SharedEmojis.all_emojis.get("wbb_red")) + self.spells = EmojiType(SharedEmojis.all_emojis.get("spells")) + self.heart = EmojiType(SharedEmojis.all_emojis.get("heart")) + self.pet_paw = EmojiType(SharedEmojis.all_emojis.get("pet_paw")) -class OldEmojis(): - def __init__(self): - self.discord = EmojiType("<:discord:840749695466864650>") - self.clan_castle = EmojiType("<:clan_castle:855688168816377857>") - self.shield = EmojiType("<:sh:948845842809360424>") - self.trophy = EmojiType("<:trophyy:849144172698402817>") - self.capital_gold = EmojiType("<:capitalgold:987861320286216223>") - self.legends_shield = EmojiType("<:legends:881450752109850635>") - self.sword = EmojiType("<:cw:948845649229647952>") - self.previous_days = EmojiType("<:cal:989351376146530304>") - self.legends_overview = EmojiType("<:list:989351376796680213>") - self.graph_and_stats = EmojiType("<:graph:989351375349624832>") - self.history = EmojiType("<:history:989351374087151617>") - self.quick_check = EmojiType("<:plusminus:989351373608980490>") - self.gear = EmojiType("<:gear:989351372711399504>") - self.pin = EmojiType("<:pin:989362628361072650>") - self.back = EmojiType("<:back_arrow:989399022156525650>") - self.forward = EmojiType("<:forward_arrow:989399021602877470>") - self.print = EmojiType("<:print:989400875766251581>") - self.refresh = EmojiType("<:refresh:1183532546575843410>") - self.trashcan = EmojiType("<:trashcan:989534332425232464>") - self.alphabet = EmojiType("<:alphabet:989649421564280872>") - self.start = EmojiType("<:start:989649420742176818>") - self.blue_shield = EmojiType("<:blueshield:989649418665996321>") - self.blue_sword = EmojiType("<:bluesword:989649419878166558>") - self.blue_trophy = EmojiType("<:bluetrophy:989649417760018483>") - self.grey_circle = EmojiType("<:status_offline:910938138984206347>") - self.earth = EmojiType("") - self.sword_clash = EmojiType("") - self.war_star = EmojiType("<:war_star:1013159341395816618>") - self.blank = EmojiType("<:blanke:838574915095101470>") - self.clock = EmojiType("<:clock:1013161445833326653>") - self.troop = EmojiType("<:troop:861797310224400434>") - self.reddit_icon = EmojiType("<:reddit:1015107963536539688>") - self.xp = EmojiType("<:xp:991965062703095938>") - self.deny_mark = EmojiType("<:not_clan:1045915201037422683>") - self.raid_medal = EmojiType("<:raidmedal:1032108724552224798>") - self.clan_games = EmojiType("<:cg:1033805598518677604>") - self.time = EmojiType("<:time:1033909938281529386>") - self.no_star = EmojiType("<:no_star:1033914094824198174>") - self.yes = EmojiType("<:yes:1033915430198333500>") - self.no = EmojiType("<:no:1033915481335275621>") - self.gear = EmojiType("<:gear:1035416941646594118>") - self.ratio = EmojiType("<:winrate:932212939908337705>") - self.switch = EmojiType("<:switch:1037530447665704980>") - self.menu = EmojiType("<:menu:1037531977324167219>") - self.elixir = EmojiType("<:elixir:1043616874446999602>") - self.dark_elixir = EmojiType("<:delixir:1043616963815022612>") - self.gold = EmojiType("<:gold:1043616714874687578>") - self.brown_shield = EmojiType("<:shield:1045920451165159525>") - self.thick_sword = EmojiType("<:thick_sword:1045921321990754305>") - self.hitrate = EmojiType("<:hitrate:1046114606151630918>") - self.avg_stars = EmojiType("<:avg_stars:1046114668139270234>") - self.war_stars = EmojiType("<:war_stars:1046114735059378236>") - self.versus_trophy = EmojiType("<:builder_trophies:1109716019573964820>") - self.up_green_arrow = EmojiType("<:warwon:932212939899949176>") - self.down_red_arrow = EmojiType("<:warlost:932212154164183081>") - self.capital_trophy = EmojiType("<:capital_trophy:1054056202864177232>") - self.cwl_medal = EmojiType("<:cwlmedal:1037126610962362370>") - self.person = EmojiType("<:people:932212939891552256>") - self.excel = EmojiType("<:excel:1059583349762572298>") - self.magnify_glass = EmojiType("<:magnify:944914253171810384>") - self.right_green_arrow = EmojiType("<:arrow_right_green:1059585270833487943>") - self.calendar = EmojiType("<:calendar:1063642295162916924>") - self.red_status = EmojiType("<:status_red:948032012160204840>") - self.green_status = EmojiType("<:status_green:948031949140799568>") - self.toggle_on = EmojiType("<:toggle_on:1067254915438739456>") - self.toggle_off = EmojiType("<:toggle_off:1067254958698803230>") - self.unranked = EmojiType("<:Unranked:601618883853680653>") - self.hashmark = EmojiType("<:hash:1097685290132459602>") - self.red_tick = EmojiType("<:redtick:601900691312607242>") - self.green_tick = EmojiType("<:greentick:601900670823694357>") - self.opt_in = EmojiType("<:opt_in:944905885367537685>") - self.opt_out = EmojiType("<:opt_out:944905931265810432>") - self.globe = EmojiType("<:globe:1113285560715444274>") - self.wood_swords = EmojiType("<:wood_swords:1109716092647112787>") - self.red_pin = EmojiType("<:redpin:1130343263698690128>") - self.wbb_red = EmojiType("") - self.spells = EmojiType("<:spells:1184426093353127966>") - self.heart = EmojiType("<:heart:1184426691704135701>") - self.pet_paw = EmojiType("<:pet:1184426579149987852>") diff --git a/classes/player.py b/classes/player.py index b826aae7..d003fbcd 100644 --- a/classes/player.py +++ b/classes/player.py @@ -2,7 +2,7 @@ import coc import pytz from coc import utils -from assets.emojiDictionary import emojiDictionary +from assets.emojis import SharedEmojis from assets.thPicDictionary import thDictionary from datetime import datetime, timedelta from classes.emoji import EmojiType @@ -1039,22 +1039,22 @@ def superscript(self): class MyCustomTroops(coc.Troop): @property def emoji(self): - return EmojiType(emojiDictionary(self.name)) + return EmojiType(SharedEmojis.all_emojis.get(self.name)) class MyCustomHeros(coc.Hero): @property def emoji(self): - return EmojiType(emojiDictionary(self.name)) + return EmojiType(SharedEmojis.all_emojis.get(self.name)) class MyCustomSpells(coc.Spell): @property def emoji(self): - return EmojiType(emojiDictionary(self.name)) + return EmojiType(SharedEmojis.all_emojis.get(self.name)) class MyCustomPets(coc.Pet): @property def emoji(self): - return EmojiType(emojiDictionary(self.name)) + return EmojiType(SharedEmojis.all_emojis.get(self.name)) class CustomTownHall(): def __init__(self, th_level): @@ -1062,7 +1062,7 @@ def __init__(self, th_level): self.str_level = str(th_level) @property def emoji(self): - return EmojiType(emojiDictionary(self.level)) + return EmojiType(SharedEmojis.all_emojis.get(self.level)) @property def image_url(self): diff --git a/classes/server.py b/classes/server.py index 2716c265..e75562cd 100644 --- a/classes/server.py +++ b/classes/server.py @@ -143,6 +143,11 @@ def __init__(self, bot: CustomClient, data): self.capital_weekly_summary = ClanLog(parent=self, type="capital_weekly_summary") self.raid_panel = CapitalPanel(parent=self, type="new_raid_panel") self.donation_log = ClanLog(parent=self, type="donation_log") + self.clan_achievement_log = ClanLog(parent=self, type="clan_achievement_log") + self.clan_requirements_log = ClanLog(parent=self, type="clan_requirements_log") + self.clan_description_log = ClanLog(parent=self, type="clan_description_log") + self.cwl_lineup_change_log = ClanLog(parent=self, type="cwl_lineup_change") + self.super_troop_boost_log = ClanLog(parent=self, type="super_troop_boost") self.role_change = ClanLog(parent=self, type="role_change") self.troop_upgrade = ClanLog(parent=self, type="troop_upgrade") @@ -150,6 +155,8 @@ def __init__(self, bot: CustomClient, data): self.league_change = ClanLog(parent=self, type="league_change") self.spell_upgrade = ClanLog(parent=self, type="spell_upgrade") self.hero_upgrade = ClanLog(parent=self, type="hero_upgrade") + self.hero_equipment_upgrade = ClanLog(parent=self, type="hero_equipment_upgrade") + self.name_change = ClanLog(parent=self, type="name_change") self.ban_alert_channel = data.get("ban_alert_channel") self.war_log = ClanLog(parent=self, type="war_log") diff --git a/commands/other/commands.py b/commands/other/commands.py index db9882d7..80f2b856 100644 --- a/commands/other/commands.py +++ b/commands/other/commands.py @@ -149,11 +149,11 @@ async def create_pepe(self, ctx, sign_text: str, hidden: str = commands.Param(ch if len(sign_text) > 19: size = 16 - back = Image.open("Other/pepesign.png") + back = Image.open("other/pepesign.png") width = 250 height = 250 - font = ImageFont.truetype("Other/pepefont.ttf", size) + font = ImageFont.truetype("other/pepefont.ttf", size) draw = ImageDraw.Draw(back) draw.text(((width / 2) - 5, 55), sign_text, anchor="mm", fill=(0, 0, 0), font=font) diff --git a/commands/owner/commands.py b/commands/owner/commands.py index a7dfb191..bba5355f 100644 --- a/commands/owner/commands.py +++ b/commands/owner/commands.py @@ -21,18 +21,15 @@ from contextlib import redirect_stdout import io import re -from assets.emojiDictionary import switcher, emoji_class_dict import asyncio import aiohttp - +from pymongo import InsertOne class OwnerCommands(commands.Cog): def __init__(self, bot: CustomClient): self.bot = bot self.count = 0 - coc_client: coc.EventsClient = self.bot.coc_client - @@ -206,21 +203,7 @@ async def create_keys(self, emails: list, passwords: list, ip: str): @commands.slash_command(name="test", guild_ids=[923764211845312533]) @commands.is_owner() async def test(self, ctx: disnake.ApplicationCommandInteraction): - config = self.bot._config - emails = [config.coc_email.format(x=x) for x in range(1, 2 + 1)] - passwords = [config.coc_password] * (2 + 1 - 1) - keys = await self.create_keys(emails=emails, passwords=passwords, ip="85.10.200.219") - print(len(keys)) - to_insert = [] - for k in keys: - to_insert.append({ - "token" : k - }) - await self.bot.new_looper.get_collection("api_tokens").insert_many(documents=to_insert) - - - - + switcher, emoji_class_dict @commands.slash_command(name="anniversary", guild_ids=[923764211845312533]) diff --git a/commands/reminders/Reminders.py b/commands/reminders/commands.py similarity index 94% rename from commands/reminders/Reminders.py rename to commands/reminders/commands.py index 564233b7..019520c6 100644 --- a/commands/reminders/Reminders.py +++ b/commands/reminders/commands.py @@ -4,8 +4,7 @@ from utility.discord_utils import check_commands from disnake.ext import commands from typing import Union, List -from FamilyManagement.Reminders import ReminderUtils -from typing import TYPE_CHECKING +from .utils import create_war_reminder, create_games_reminder, create_roster_reminder, create_capital_reminder, create_inactivity_reminder from classes.bot import CustomClient from exceptions.CustomExceptions import NotValidReminderTime @@ -98,6 +97,15 @@ async def edit_reminders(self, ctx: disnake.ApplicationCommandInteraction, await ReminderUtils.edit_reminder(bot=self.bot, clan=clan, ctx=ctx, type=r_type) + @reminders.sub_command(name="manual", description="send a manual reminder") + @commands.check_any(commands.has_permissions(manage_guild=True), check_commands()) + async def manual_reminders(self, ctx: disnake.ApplicationCommandInteraction, + clan: coc.Clan = commands.Param(converter=clan_converter), + type=commands.Param(choices=["War & CWL"])): + await ctx.response.defer() + pass + + @reminders.sub_command(name="list", description="Get the list of reminders set up on the server") async def reminder_list(self, ctx: disnake.ApplicationCommandInteraction): await ctx.response.defer() diff --git a/commands/reminders/SendReminders.py b/commands/reminders/send_reminders.py similarity index 93% rename from commands/reminders/SendReminders.py rename to commands/reminders/send_reminders.py index cbfa2ef4..f5a2878d 100644 --- a/commands/reminders/SendReminders.py +++ b/commands/reminders/send_reminders.py @@ -1,26 +1,28 @@ import datetime import coc import disnake +import sentry_sdk from pytz import utc from utility.clash.capital import gen_raid_weekend_datestrings, get_raidlog_entry -from typing import TYPE_CHECKING from classes.bot import CustomClient from classes.reminders import Reminder -import sentry_sdk -async def war_reminder(bot: CustomClient, clan_tag, reminder_time): - war: coc.ClanWar = await bot.get_clanwar(clanTag=clan_tag) - if war is None: - return - missing = {}; names = {}; ths = {} + +async def war_reminder(bot: CustomClient, event: dict): + reminder_time = event.get("time") + clan_tag = event.get("clan_tag") + war: coc.ClanWar = coc.ClanWar(data=event.get("data"), client=None, clan_tag=clan_tag) + missing = {} + names = {} + ths = {} for player in war.clan.members: if len(player.attacks) < war.attacks_per_member: missing[player.tag] = war.attacks_per_member - len(player.attacks) names[player.tag] = player.name ths[player.tag] = player.town_hall - tags= list(missing.keys()) + tags = list(missing.keys()) if not missing: return links = await bot.link_client.get_links(*tags) @@ -88,8 +90,7 @@ async def war_reminder(bot: CustomClient, clan_tag, reminder_time): pass -async def clan_capital_reminder(bot:CustomClient, reminder_time): - +async def clan_capital_reminder(bot: CustomClient, reminder_time): for reminder in await bot.reminders.find({"$and": [{"type": "Clan Capital"}, {"time": reminder_time}]}).to_list(length=None): try: reminder = Reminder(bot=bot, data=reminder) @@ -115,8 +116,8 @@ async def clan_capital_reminder(bot:CustomClient, reminder_time): continue missing = {} - clan_members = {member.tag : member for member in clan.members} - for member in raid_log_entry.members: #type: coc.RaidMember + clan_members = {member.tag: member for member in clan.members} + for member in raid_log_entry.members: # type: coc.RaidMember try: del clan_members[member.tag] except: @@ -167,6 +168,7 @@ async def clan_capital_reminder(bot:CustomClient, reminder_time): sentry_sdk.capture_exception(e) + async def clan_games_reminder(bot: CustomClient, reminder_time): for reminder in await bot.reminders.find({"$and": [{"type": "Clan Games"}, {"time": reminder_time}]}).to_list(length=None): reminder = Reminder(bot=bot, data=reminder) @@ -195,7 +197,6 @@ async def clan_games_reminder(bot: CustomClient, reminder_time): missing[stat.get("tag")] = coc.utils.get(clan.members, tag=stat.get("tag")) member_points[stat.get("tag")] = points - if not missing: continue links = await bot.link_client.get_links(*list(missing.keys())) @@ -221,7 +222,6 @@ async def clan_games_reminder(bot: CustomClient, reminder_time): async def inactivity_reminder(bot: CustomClient): - for reminder in await bot.reminders.find({"type": "inactivity"}).to_list(length=None): reminder = Reminder(bot=bot, data=reminder) if reminder.server_id not in bot.OUR_GUILDS: @@ -241,10 +241,10 @@ async def inactivity_reminder(bot: CustomClient): continue seconds_inactive = int(str(reminder.time).replace("hr", "")) * 60 * 60 - max_diff = 30 * 60 #time in seconds between runs + max_diff = 30 * 60 # time in seconds between runs now = datetime.datetime.now(tz=utc) clan_members = [member.tag for member in clan.members] - clan_members_stats = await bot.player_stats.find({f"tag": {"$in" : clan_members}}).to_list(length=None) + clan_members_stats = await bot.player_stats.find({f"tag": {"$in": clan_members}}).to_list(length=None) inactive_tags = [] names = {} for stat in clan_members_stats: @@ -312,12 +312,12 @@ async def roster_reminder(bot: CustomClient): now = datetime.datetime.now(tz=utc) roster_time = datetime.datetime.fromtimestamp(float(reminder.roster.time), tz=utc) time_until_time = (roster_time - now).total_seconds() - #goes negative if now >= time - #gets smaller as we get closer + # goes negative if now >= time + # gets smaller as we get closer - #we want to ping when we are closer to the time than further, so when seconds_before - #larger - smaller >= 0 - #smaller - larger <= 0 + # we want to ping when we are closer to the time than further, so when seconds_before + # larger - smaller >= 0 + # smaller - larger <= 0 if seconds_before_to_ping - time_until_time >= 0 and seconds_before_to_ping - time_until_time <= max_diff: members = [] if reminder.ping_type == "All Roster Members": @@ -354,10 +354,9 @@ async def roster_reminder(bot: CustomClient): if text == missing_text_list[-1]: reminder_text += f"\n{reminder.custom_text}" button = disnake.ui.Button(label="Clan Link", emoji="🔗", style=disnake.ButtonStyle.url, - url=f"https://link.clashofclans.com/en?action=OpenClanProfile&tag=%23{reminder.roster.roster_result.get('clan_tag').strip('#')}") + url=f"https://link.clashofclans.com/en?action=OpenClanProfile&tag=%23{reminder.roster.roster_result.get('clan_tag').strip('#')}") buttons = [disnake.ui.ActionRow(button)] try: await channel.send(content=reminder_text, components=buttons) except: pass - diff --git a/commands/reminders/ReminderUtils.py b/commands/reminders/utils.py similarity index 100% rename from commands/reminders/ReminderUtils.py rename to commands/reminders/utils.py diff --git a/commands/rosters/commands.py b/commands/rosters/commands.py index 44d716fb..1be16d80 100644 --- a/commands/rosters/commands.py +++ b/commands/rosters/commands.py @@ -6,7 +6,7 @@ from disnake.ext import commands from classes.bot import CustomClient -from assets.emojiDictionary import emojiDictionary +from assets.emojis import SharedEmojis from classes.roster import Roster from utility.discord_utils import check_commands from exceptions.CustomExceptions import * @@ -116,9 +116,9 @@ async def roster_add(self, ctx: disnake.ApplicationCommandInteraction, for player in players: try: await _roster.add_member(player=player, sub=(sub=="Yes")) - added_text += f"{emojiDictionary(player.town_hall)}{player.name}\n" + added_text += f"{SharedEmojis.all_emojis.get(player.town_hall)}{player.name}\n" except Exception as e: - messed_text += f"{emojiDictionary(player.town_hall)}{player.name} - {e}\n" + messed_text += f"{SharedEmojis.all_emojis.get(player.town_hall)}{player.name} - {e}\n" if added_text == "": added_text = f"No Players" embed = disnake.Embed(title=f"Added to **{_roster.roster_result.get('alias')}** roster", description=added_text,color=disnake.Color.green()) diff --git a/commands/setup/commands.py b/commands/setup/commands.py index fb778160..3e983f57 100644 --- a/commands/setup/commands.py +++ b/commands/setup/commands.py @@ -413,7 +413,8 @@ async def autoeval(self, ctx: disnake.ApplicationCommandInteraction, option=comm @setup.sub_command(name="logs", description="Set a variety of different clan logs for your server!") @commands.check_any(commands.has_permissions(manage_guild=True), check_commands()) async def set_log_add(self, ctx: disnake.ApplicationCommandInteraction, - clan: coc.Clan = commands.Param(converter=clan_converter), mode:str = commands.Param(choices=["Add/Edit", "Remove"]), + clan: coc.Clan = commands.Param(converter=convert.clan, autocomplete=autocomplete.clan), + mode:str = commands.Param(choices=["Add/Edit", "Remove"]), channel: Union[disnake.TextChannel, disnake.Thread] = commands.Param(default=None)): await ctx.response.defer() @@ -427,29 +428,63 @@ async def set_log_add(self, ctx: disnake.ApplicationCommandInteraction, db_clan = DatabaseClan(bot=self.bot, data=results) channel = ctx.channel if channel is None else channel - log_types = {"Member Join" : db_clan.join_log, "Member Leave" : db_clan.leave_log, "War Log" : db_clan.war_log, "War Panel" : db_clan.war_panel, - "Capital Donations" : db_clan.capital_donations, "Capital Attacks" : db_clan.capital_attacks, "Capital Panel" : db_clan.raid_panel, - "Capital Weekly Summary" : db_clan.capital_weekly_summary, "Donation Log" : db_clan.donation_log, "Super Troop Boosts" : db_clan.super_troop_boost_log, - "Role Change" : db_clan.role_change, "Troop Upgrade" : db_clan.troop_upgrade, "Townhall Upgrade" : db_clan.th_upgrade, "League Change" : db_clan.league_change, - "Spell Upgrade" : db_clan.spell_upgrade, "Hero Upgrade" : db_clan.hero_upgrade, "Name Change" : db_clan.name_change, - "Legend Attacks" : db_clan.legend_log_attacks, "Legend Defenses" : db_clan.legend_log_defenses} - + clan_log_types = { + "Member Join": db_clan.join_log, + "Member Leave": db_clan.leave_log, + "Member Donation": db_clan.donation_log, + "Clan Achievements" : db_clan.clan_achievement_log, + "Clan Requirements" : db_clan.clan_requirements_log, + "Clan Description": db_clan.clan_description_log, + } + war_log_types = { + "War Log": db_clan.war_log, + "War Panel": db_clan.war_panel, + "CWL Lineup Change": db_clan.cwl_lineup_change_log + } + capital_log_types = { + "Capital Donations": db_clan.capital_donations, + "Capital Attacks": db_clan.capital_attacks, + "Capital Panel": db_clan.raid_panel, + "Capital Weekly Summary": db_clan.capital_weekly_summary + } + player_log_types = { + "Role Change": db_clan.role_change, + "Troop Upgrade": db_clan.troop_upgrade, + "Super Troop Boosts": db_clan.super_troop_boost_log, + "Townhall Upgrade": db_clan.th_upgrade, + "League Change": db_clan.league_change, + "Spell Upgrade": db_clan.spell_upgrade, + "Hero Upgrade": db_clan.hero_upgrade, + "Hero Equipment Upgrade": db_clan.hero_equipment_upgrade, + "Name Change": db_clan.name_change, + "Legend Attacks": db_clan.legend_log_attacks, + "Legend Defenses": db_clan.legend_log_defenses + } + master_log_types = clan_log_types | war_log_types | capital_log_types | player_log_types if mode == "Remove": - for log_type, log in log_types.copy().items(): - if log.webhook is None: - del log_types[log_type] - - options = [] - for log_type in log_types.keys(): - options.append(disnake.SelectOption(label=log_type, emoji=self.bot.emoji.clock.partial_emoji, value=log_type)) - - select = disnake.ui.Select( - options=options, - placeholder="Select logs!", # the placeholder text to show when no options have been chosen - min_values=1, # the minimum number of options a user must select - max_values=len(options), # the maximum number of options a user can select - ) - dropdown = [disnake.ui.ActionRow(select)] + for log_types in [clan_log_types, war_log_types, capital_log_types, player_log_types]: + for log_type, log in log_types.copy().items(): + if log.webhook is None: + del log_types[log_type] + + dropdown = [] + for name, log_types in zip(["Clan Logs", "War Logs", "Capital Logs", "Player Logs"], [clan_log_types, war_log_types, capital_log_types, player_log_types]): + options = [] + for log_type in log_types.keys(): + options.append(disnake.SelectOption(label=log_type, emoji=self.bot.emoji.clock.partial_emoji, value=log_type)) + if options: + select = disnake.ui.Select( + options=options, + placeholder=name, # the placeholder text to show when no options have been chosen + min_values=1, # the minimum number of options a user must select + max_values=len(options), # the maximum number of options a user can select + ) + dropdown.append(disnake.ui.ActionRow(select)) + + if dropdown: + dropdown.append(disnake.ui.ActionRow(disnake.ui.Button(label="Save", emoji=self.bot.emoji.yes.partial_emoji, style=disnake.ButtonStyle.green, custom_id="Save"))) + else: + raise MessageException("No Logs Set Up to Remove") channel_text = "" if mode == "Remove" else f"in {channel.mention}" embed = disnake.Embed( @@ -457,7 +492,6 @@ async def set_log_add(self, ctx: disnake.ApplicationCommandInteraction, f"Visit https://docs.clashking.xyz/clan-setups/log-setup for more info", color=disnake.Color.green()) await ctx.edit_original_message(embed=embed, components=dropdown) - res: disnake.MessageInteraction = await interaction_handler(bot=self.bot, ctx=ctx) if mode == "Add/Edit": webhook = await get_webhook_for_channel(channel=channel, bot=self.bot) thread = None @@ -465,10 +499,18 @@ async def set_log_add(self, ctx: disnake.ApplicationCommandInteraction, await channel.add_user(self.bot.user) thread = channel.id + clicked_save = False + values = [] + while not clicked_save: + res: disnake.MessageInteraction = await interaction_handler(bot=self.bot, ctx=ctx) + if res.component.type == disnake.ComponentType.button: + break + for value in res.values: + values.append(value) text = "" - for value in res.values: - log = log_types[value] + for value in values: + log = master_log_types[value] if mode == "Add/Edit": await log.set_webhook(id=webhook.id) await log.set_thread(id=thread) @@ -479,9 +521,8 @@ async def set_log_add(self, ctx: disnake.ApplicationCommandInteraction, await log.set_thread(id=None) text += f'{self.bot.emoji.yes}{value} Removed\n' - embed = disnake.Embed(title=f"Logs for {clan.name}", description=text, color=disnake.Color.green()) - await res.edit_original_message(embed=embed, components=[]) + await ctx.edit_original_message(embed=embed, components=[]) @setup.sub_command(name="reddit-recruit-feed", description="Feed of searching for a clan posts on the recruiting subreddit") diff --git a/commands/strikes/commands.py b/commands/strikes/commands.py index 96b08ffc..c7d961d4 100644 --- a/commands/strikes/commands.py +++ b/commands/strikes/commands.py @@ -14,7 +14,6 @@ from typing import List - class Strikes(commands.Cog, name="Strikes"): def __init__(self, bot: CustomClient): @@ -51,8 +50,8 @@ async def strike_add(self, ctx: disnake.ApplicationCommandInteraction, @commands.check_any(commands.has_permissions(manage_guild=True), check_commands()) async def strike_list(self, ctx: disnake.ApplicationCommandInteraction, view=commands.Param(choices=["Strike View", "Player View"]), - clan=commands.Param(default=None, converter=clan_converter), - player=commands.Param(default=None, converter=player_converter), + clan=commands.Param(default=None, converter=convert.clan), + player=commands.Param(default=None, converter=convert.player), strike_amount: int = commands.Param(default=1)): """ Parameters diff --git a/commands/utility/utils.py b/commands/utility/utils.py index 9da29f82..66108851 100644 --- a/commands/utility/utils.py +++ b/commands/utility/utils.py @@ -6,12 +6,11 @@ from utility.constants import MAX_ARMY_CAMP, MAX_NUM_SPELLS, EMBED_COLOR_CLASS from assets.army_ids import troop_ids, spell_ids, size from utility.discord_utils import iter_embed_creation, register_button -from assets.emojiDictionary import emojiDictionary from typing import TYPE_CHECKING from classes.bot import CustomClient from collections import defaultdict from exceptions.CustomExceptions import MessageException -from assets.emojiDictionary import emojiDictionary +from assets.emojis import SharedEmojis from typing import List, Dict diff --git a/discord/events.py b/discord/events.py index c7c8d326..6ae3a62c 100644 --- a/discord/events.py +++ b/discord/events.py @@ -1,6 +1,8 @@ import asyncio import datetime import random +import io +import aiohttp import disnake from disnake.ext import commands @@ -10,8 +12,9 @@ has_started = False from classes.tickets import OpenTicket, TicketPanel, LOG_TYPE from classes.DatabaseClient.familyclient import FamilyClient -from assets.emojiDictionary import switcher, emoji_class_dict -from pymongo import UpdateOne +from assets.emojis import SharedEmojis +from collections import deque +from commands.reminders.send_reminders import clan_games_reminder, clan_capital_reminder, inactivity_reminder, roster_reminder class DiscordEvents(commands.Cog): @@ -21,8 +24,15 @@ def __init__(self, bot: CustomClient): @commands.Cog.listener() async def on_connect(self): self.bot.ck_client = FamilyClient(bot=self.bot) + number_emojis = await self.bot.number_emojis.find().to_list(length=None) + number_emojis_map = {"blue": {}, "gold": {}, "white": {}} + for emoji in number_emojis: + number_emojis_map[emoji.get("color")][emoji.get("count")] = emoji.get("emoji_id") + self.bot.number_emoji_map = number_emojis_map + if self.bot.user.id == 808566437199216691: return + global has_started if not has_started: await asyncio.sleep(5) @@ -45,15 +55,41 @@ async def on_connect(self): "lbhour": None, }) - number_emojis = await self.bot.number_emojis.find().to_list(length=None) - number_emojis_map = {"blue" : {}, "gold" : {}, "white" : {}} - for emoji in number_emojis: - number_emojis_map[emoji.get("color")][emoji.get("count")] = emoji.get("emoji_id") - self.bot.number_emoji_map = number_emojis_map + self.bot.scheduler.add_job(clan_capital_reminder, trigger="cron", args=[self.bot, "1 hr"], day_of_week="mon", hour=6, misfire_grace_time=None) + self.bot.scheduler.add_job(clan_capital_reminder, trigger="cron", args=[self.bot, "2 hr"], day_of_week="mon", hour=5, misfire_grace_time=None) + self.bot.scheduler.add_job(clan_capital_reminder, trigger="cron", args=[self.bot, "4 hr"], day_of_week="mon", hour=3, misfire_grace_time=None) + self.bot.scheduler.add_job(clan_capital_reminder, trigger="cron", args=[self.bot, "6 hr"], day_of_week="mon", hour=1, misfire_grace_time=None) + self.bot.scheduler.add_job(clan_capital_reminder, trigger="cron", args=[self.bot, "8 hr"], day_of_week="sun", hour=23, misfire_grace_time=None) + self.bot.scheduler.add_job(clan_capital_reminder, trigger="cron", args=[self.bot, "12 hr"], day_of_week="sun", hour=19, misfire_grace_time=None) + self.bot.scheduler.add_job(clan_capital_reminder, trigger="cron", args=[self.bot, "16 hr"], day_of_week="sun", hour=15, misfire_grace_time=None) + self.bot.scheduler.add_job(clan_capital_reminder, trigger="cron", args=[self.bot, "24 hr"], day_of_week="sun", hour=7, misfire_grace_time=None) + + self.bot.scheduler.add_job(clan_games_reminder, trigger="cron", args=[self.bot, "144 hr"], day=22, hour=8, misfire_grace_time=None) + self.bot.scheduler.add_job(clan_games_reminder, trigger="cron", args=[self.bot, "120 hr"], day=23, hour=8, misfire_grace_time=None) + self.bot.scheduler.add_job(clan_games_reminder, trigger="cron", args=[self.bot, "96 hr"], day=24, hour=8, misfire_grace_time=None) + self.bot.scheduler.add_job(clan_games_reminder, trigger="cron", args=[self.bot, "72 hr"], day=25, hour=8, misfire_grace_time=None) + self.bot.scheduler.add_job(clan_games_reminder, trigger="cron", args=[self.bot, "48 hr"], day=26, hour=8, misfire_grace_time=None) + self.bot.scheduler.add_job(clan_games_reminder, trigger="cron", args=[self.bot, "36 hr"], day=26, hour=20, misfire_grace_time=None) + self.bot.scheduler.add_job(clan_games_reminder, trigger="cron", args=[self.bot, "24 hr"], day=27, hour=8, misfire_grace_time=None) + self.bot.scheduler.add_job(clan_games_reminder, trigger="cron", args=[self.bot, "12 hr"], day=27, hour=20, misfire_grace_time=None) + self.bot.scheduler.add_job(clan_games_reminder, trigger="cron", args=[self.bot, "6 hr"], day=28, hour=2, misfire_grace_time=None) + self.bot.scheduler.add_job(clan_games_reminder, trigger="cron", args=[self.bot, "4 hr"], day=28, hour=4, misfire_grace_time=None) + self.bot.scheduler.add_job(clan_games_reminder, trigger="cron", args=[self.bot, "2 hr"], day=28, hour=6, misfire_grace_time=None) + self.bot.scheduler.add_job(clan_games_reminder, trigger="cron", args=[self.bot, "1 hr"], day=28, hour=7, misfire_grace_time=None) + self.bot.scheduler.add_job(inactivity_reminder, trigger='interval', args=[self.bot], minutes=30, misfire_grace_time=None) + self.bot.scheduler.add_job(roster_reminder, trigger='interval', args=[self.bot], minutes=2, misfire_grace_time=None) + print('We have connected') - '''if not self.bot.user.public_flags.verified_bot and self.bot.user.id != 808566437199216691: + + @commands.Cog.listener() + async def on_ready(self): + await asyncio.sleep(5) + print("ready") + #will remove later, if is a custom bot, remove ourselves from every server but one + if not self.bot.user.public_flags.verified_bot and self.bot.user.id != 808566437199216691: + if self.bot.guilds: largest_server = sorted(self.bot.guilds, key=lambda x: x.member_count, reverse=True)[0] for server in self.bot.guilds: if server.id != largest_server.id: @@ -61,15 +97,82 @@ async def on_connect(self): await server.leave() else: await server.delete() - #create_emojis - bot_settings = await self.bot.custom_bots.find_one({"token" : self.bot._config.bot_token}) - our_emoji = bot_settings.get("emojis") - emojis_we_should_have = switcher | emoji_class_dict - for emoji_name, emoji_text in emojis_we_should_have.items(): - if our_emoji.get(emoji_name): - pass #download emoji''' - print('We have logged in') + for number, emoji_id in self.bot.number_emoji_map.get("gold").items(): + if number <= 50: + SharedEmojis.all_emojis[f"{number}_"] = emoji_id + + print(len(SharedEmojis.all_emojis), "emojis that we have") + if not self.bot.user.public_flags.verified_bot: + our_emoji_servers = [server for server in self.bot.guilds if server.owner_id == self.bot.user.id and server.name != "ckcustombotbadges"] + if len(our_emoji_servers) < 8: + for x in range(0, (8 - len(our_emoji_servers))): + if x != 8: + guild = await self.bot.create_guild(name=f"ckemojiserver{x}") + our_emoji_servers.append(guild) + else: + guild = await self.bot.create_guild(name="ckcustombotbadges") + + print(", ".join([g.name for g in self.bot.guilds])) + print(", ".join([str(len(g.emojis)) for g in self.bot.guilds])) + print(sum([(len(g.emojis)) for g in self.bot.guilds]) - 254, "emojis installed") + + print(len(our_emoji_servers), "servers") + our_emoji_servers = deque(our_emoji_servers) + + id_to_lookup_name_map = {} + for emoji_name, emoji_string in SharedEmojis.all_emojis.items(): + emoji_split = emoji_string.split(":") + animated = "" + + print(deleted, "emojis deleted") + + to_create = 0 + for emoji_name, emoji_string in SharedEmojis.all_emojis.items(): + if emoji_name not in all_our_emojis: + to_create += 1 + + print(f"{to_create} emojis to create") + for emoji_name, emoji_string in SharedEmojis.all_emojis.items(): + if emoji_name not in all_our_emojis: + server = our_emoji_servers[0] + while len(server.emojis) == server.emoji_limit: + our_emoji_servers.rotate(1) + server = our_emoji_servers[0] + emoji_split = emoji_string.split(":") + animated = "" + our_emoji_servers.rotate(1) + + for emoji_name, emoji_string in all_our_emojis.items(): + SharedEmojis.all_emojis[emoji_name] = emoji_string + + print("done with emoji creation") @commands.Cog.listener() @@ -125,6 +228,8 @@ async def on_guild_join(self, guild:disnake.Guild): await firstChannel.send(components=buttons, embed=embed) if results is None else None + + @commands.Cog.listener() async def on_guild_remove(self, guild): if not self.bot.user.public_flags.verified_bot: diff --git a/main.py b/main.py index 94a7c1b8..62e9339d 100644 --- a/main.py +++ b/main.py @@ -56,7 +56,10 @@ "discord.converters", #"background.features.refresh_boards", "exceptions.handler", - "background.tasks.emoji_refresh" + "background.tasks.emoji_refresh", + #"background.logs.join_leave_events" + #"background.logs.legend_events" + #"background.logs.player_upgrade_events" ] @@ -136,6 +139,6 @@ def before_send(event, hint): traceback.print_exc() bot.EXTENSION_LIST.extend(initial_extensions) if not config.is_beta: - bot.loop.create_task(kafka_events()) + bot.loop.create_task(kafka_events(bot)) bot.run(config.bot_token) diff --git a/requirements.txt b/requirements.txt index 89a8864b..fb5061cf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,7 +17,7 @@ kaleido==0.2.1 loguru==0.7.2 matplotlib==3.7.1 motor==3.3.2 -msgspec==0.15.1 +msgspec==0.18.6 numerize==0.12 openai==0.27.8 openpyxl==3.1.2 diff --git a/utility/clash/other.py b/utility/clash/other.py index 8d25f33e..57cbaefa 100644 --- a/utility/clash/other.py +++ b/utility/clash/other.py @@ -1,12 +1,11 @@ import coc import re import emoji -from assets.emojiDictionary import emojiDictionary +from assets.emojis import SharedEmojis from collections import defaultdict from utility.discord_utils import fetch_emoji -from utility.constants import DARK_ELIXIR, SUPER_TROOPS +from utility.constants import SUPER_TROOPS from pytz import utc -from classes.player import MyCustomPlayer from datetime import datetime, timedelta @@ -46,15 +45,15 @@ async def superTroops(player, asArray=False): return str(boostedTroops) -def heros(bot, player: MyCustomPlayer): - def get_emoji(hero: coc.Hero): +def heros(bot, player: coc.Player): + def get_level_emoji(hero: coc.Hero): color = "blue" if hero.level == hero.get_max_level_for_townhall(townhall=player.town_hall): color = "gold" return bot.get_number_emoji(color=color, number=hero.level) gear_to_hero = defaultdict(list) - for gear in player.hero_equipment: + for gear in player.equipment: if gear.hero is not None: gear_to_hero[gear.hero].append(gear) @@ -68,16 +67,34 @@ def get_emoji(hero: coc.Hero): if gear.level == gear.max_level: color = "gold" emoji = bot.get_number_emoji(color=color, number=gear.level) - gear_text += f"{emojiDictionary(gear.name)}{emoji}" + gear_text += f"{SharedEmojis.all_emojis.get(gear.name)}{emoji}" if gear_text == " | ": gear_text = "" - hero_string += f"{emojiDictionary(hero.name)}{get_emoji(hero)}{gear_text}\n" + hero_string += f"{SharedEmojis.all_emojis.get(hero.name)}{get_level_emoji(hero)}{gear_text}\n" if not hero_string: return None return "".join(hero_string) +def basic_heros(bot, player: coc.Player): + def get_level_emoji(hero: coc.Hero): + color = "blue" + if hero.level == hero.get_max_level_for_townhall(townhall=player.town_hall): + color = "gold" + return bot.get_number_emoji(color=color, number=hero.level) + + hero_string = "" + for hero in player.heroes: + if not hero.is_home_base: + continue + hero_string += f"{SharedEmojis.all_emojis.get(hero.name)}{get_level_emoji(hero)}" + + if not hero_string: + return "" + + return hero_string + def spells(player, bot=None): spells = player.spells @@ -86,7 +103,7 @@ def spells(player, bot=None): spellList = "" levelList = "" - def get_emoji(spell: coc.Spell): + def get_level_emoji(spell: coc.Spell): color = "blue" if spell.level == spell.get_max_level_for_townhall(townhall=player.town_hall): color = "gold" @@ -100,8 +117,8 @@ def get_emoji(spell: coc.Spell): if (spell.name == "Poison Spell"): spellList += "\n" + levelList + "\n" levelList = "" - spellList += f"{emojiDictionary(spell.name)} " - levelList += str(get_emoji(spell)) + spellList += f"{SharedEmojis.all_emojis.get(spell.name)} " + levelList += str(get_level_emoji(spell)) if spell.level <= 10: levelList += " " @@ -118,7 +135,7 @@ def troops(player, bot=None): troopList = "" levelList = "" - def get_emoji(troop: coc.Troop): + def get_level_emoji(troop: coc.Troop): color = "blue" if troop.level == troop.get_max_level_for_townhall(townhall=player.town_hall): color = "gold" @@ -129,8 +146,8 @@ def get_emoji(troop: coc.Troop): troop = troops[x] if (troop.is_home_base) and (troop.name not in coc.SIEGE_MACHINE_ORDER) and (troop.name not in SUPER_TROOPS): z += 1 - troopList += emojiDictionary(troop.name) + " " - levelList += str(get_emoji(troop)) + troopList += SharedEmojis.all_emojis.get(troop.name) + " " + levelList += str(get_level_emoji(troop)) if troop.level <= 11: levelList += " " @@ -143,11 +160,13 @@ def get_emoji(troop: coc.Troop): return troopList + def clean_name(name: str): name = emoji.replace_emoji(name) name = re.sub('[*_`~/]', '', name) return f"\u200e{name}" + def siegeMachines(player, bot=None): sieges = player.siege_machines if not sieges: @@ -155,7 +174,7 @@ def siegeMachines(player, bot=None): siegeList = "" levelList = "" - def get_emoji(troop: coc.Troop): + def get_level_emoji(troop: coc.Troop): color = "blue" if troop.level == troop.get_max_level_for_townhall(townhall=player.town_hall): color = "gold" @@ -168,8 +187,8 @@ def get_emoji(troop: coc.Troop): siege = sieges[x] if siege.name in siegeL: z += 1 - siegeList += emojiDictionary(siege.name) + " " - levelList += str(get_emoji(siege)) + siegeList += SharedEmojis.all_emojis.get(siege.name) + " " + levelList += str(get_level_emoji(siege)) if siege.level <= 10: levelList += " " @@ -185,7 +204,7 @@ def heroPets(bot, player: coc.Player): if not player.pets: return None - def get_emoji(pet: coc.Pet): + def get_level_emoji(pet: coc.Pet): color = "blue" if pet.level == pet.max_level: color = "gold" @@ -193,23 +212,24 @@ def get_emoji(pet: coc.Pet): pet_string = "" for count, pet in enumerate(player.pets, 1): - pet_string += f"{emojiDictionary(pet.name)}{get_emoji(pet)}" + pet_string += f"{SharedEmojis.all_emojis.get(pet.name)}{get_level_emoji(pet)}" if count % 4 == 0: pet_string += "\n" return pet_string -def hero_gear(bot, player: MyCustomPlayer): - if not player.hero_equipment: + +def hero_gear(bot, player: coc.Player): + if not player.equipment: return None gear_string = "" - for count, gear in enumerate([g for g in player.hero_equipment if g.hero is None], 1): + for count, gear in enumerate([g for g in player.equipment if g.hero is None], 1): color = "blue" if gear.level == gear.max_level: color = "gold" emoji = bot.get_number_emoji(color=color, number=gear.level) - gear_string += f"{emojiDictionary(gear.name)}{emoji}" + gear_string += f"{SharedEmojis.all_emojis.get(gear.name)}{emoji}" if count % 4 == 0: gear_string += "\n" return gear_string @@ -222,7 +242,7 @@ def profileSuperTroops(player): for x in range(len(troops)): troop = troops[x] if troop.is_active: - emoji = emojiDictionary(troop.name) + emoji = SharedEmojis.all_emojis.get(troop.name) boostedTroops += f"{emoji} {troop.name}" + "\n" if (len(boostedTroops) > 0): @@ -265,208 +285,30 @@ def clan_super_troop_comp(clan_members): def leagueAndTrophies(player): - emoji = "" league = str(player.league) - # print(league) - - if (league == "Bronze League III"): - emoji = "<:BronzeLeagueIII:601611929311510528>" - elif (league == "Bronze League II"): - emoji = "<:BronzeLeagueII:601611942850986014>" - elif (league == "Bronze League I"): - emoji = "<:BronzeLeagueI:601611950228635648>" - elif (league == "Silver League III"): - emoji = "<:SilverLeagueIII:601611958067920906>" - elif (league == "Silver League II"): - emoji = "<:SilverLeagueII:601611965550428160>" - elif (league == "Silver League I"): - emoji = "<:SilverLeagueI:601611974849331222>" - elif (league == "Gold League III"): - emoji = "<:GoldLeagueIII:601611988992262144>" - elif (league == "Gold League II"): - emoji = "<:GoldLeagueII:601611996290613249>" - elif (league == "Gold League I"): - emoji = "<:GoldLeagueI:601612010492526592>" - elif (league == "Crystal League III"): - emoji = "<:CrystalLeagueIII:601612021472952330>" - elif (league == "Crystal League II"): - emoji = "<:CrystalLeagueII:601612033976434698>" - elif (league == "Crystal League I"): - emoji = "<:CrystalLeagueI:601612045359775746>" - elif (league == "Master League III"): - emoji = "<:MasterLeagueIII:601612064913621002>" - elif (league == "Master League II"): - emoji = "<:MasterLeagueII:601612075474616399>" - elif (league == "Master League I"): - emoji = "<:MasterLeagueI:601612085327036436>" - elif (league == "Champion League III"): - emoji = "<:ChampionLeagueIII:601612099226959892>" - elif (league == "Champion League II"): - emoji = "<:ChampionLeagueII:601612113345249290>" - elif (league == "Champion League I"): - emoji = "<:ChampionLeagueI:601612124447440912>" - elif (league == "Titan League III"): - emoji = "<:TitanLeagueIII:601612137491726374>" - elif (league == "Titan League II"): - emoji = "<:TitanLeagueII:601612148325744640>" - elif (league == "Titan League I"): - emoji = "<:TitanLeagueI:601612159327141888>" - elif (league == "Legend League"): - emoji = "<:LegendLeague:601612163169255436>" - else: - emoji = "<:Unranked:601618883853680653>" - + emoji = SharedEmojis.all_emojis.get(league, SharedEmojis.all_emojis.get("unranked")) return emoji + str(player.trophies) def league_emoji(player): league = str(player.league) + return SharedEmojis.all_emojis.get(league, SharedEmojis.all_emojis.get("unranked")) - if league == "Bronze League I": - return "<:BronzeLeagueI:601611950228635648>" - elif league == "Bronze League II": - return "<:BronzeLeagueII:601611942850986014>" - elif league == "Bronze League III": - return "<:BronzeLeagueIII:601611929311510528>" - elif league == "Champion League I": - return "<:ChampionLeagueI:601612124447440912>" - elif league == "Champion League II": - return "<:ChampionLeagueII:601612113345249290>" - elif league == "Champion League III": - return "<:ChampionLeagueIII:601612099226959892>" - elif league == "Crystal League I": - return "<:CrystalLeagueI:601612045359775746>" - elif league == "Crystal League II": - return "<:CrystalLeagueII:601612033976434698>" - elif league == "Crystal League III": - return "<:CrystalLeagueIII:601612021472952330>" - elif league == "Gold League I": - return "<:GoldLeagueI:601612010492526592>" - elif league == "Gold League II": - return "<:GoldLeagueII:601611996290613249>" - elif league == "Gold League III": - return "<:GoldLeagueIII:601611988992262144>" - elif league == "Legend League": - return "<:LegendLeague:601612163169255436>" - elif league == "Master League I": - return "<:MasterLeagueI:601612085327036436>" - elif league == "Master League II": - return "<:MasterLeagueII:601612075474616399>" - elif league == "Master League III": - return "<:MasterLeagueIII:601612064913621002>" - elif league == "Silver League I": - return "<:SilverLeagueI:601611974849331222>" - elif league == "Silver League II": - return "<:SilverLeagueII:601611965550428160>" - elif league == "Silver League III": - return "<:SilverLeagueIII:601611958067920906>" - elif league == "Titan League I": - return "<:TitanLeagueI:601612159327141888>" - elif league == "Titan League II": - return "<:TitanLeagueII:601612148325744640>" - elif league == "Titan League III": - return "<:TitanLeagueIII:601612137491726374>" - else: - return "<:Unranked:601618883853680653>" def league_to_emoji(league: str): - if league == "Bronze League I": - return "<:BronzeLeagueI:601611950228635648>" - elif league == "Bronze League II": - return "<:BronzeLeagueII:601611942850986014>" - elif league == "Bronze League III": - return "<:BronzeLeagueIII:601611929311510528>" - elif league == "Champion League I": - return "<:ChampionLeagueI:601612124447440912>" - elif league == "Champion League II": - return "<:ChampionLeagueII:601612113345249290>" - elif league == "Champion League III": - return "<:ChampionLeagueIII:601612099226959892>" - elif league == "Crystal League I": - return "<:CrystalLeagueI:601612045359775746>" - elif league == "Crystal League II": - return "<:CrystalLeagueII:601612033976434698>" - elif league == "Crystal League III": - return "<:CrystalLeagueIII:601612021472952330>" - elif league == "Gold League I": - return "<:GoldLeagueI:601612010492526592>" - elif league == "Gold League II": - return "<:GoldLeagueII:601611996290613249>" - elif league == "Gold League III": - return "<:GoldLeagueIII:601611988992262144>" - elif league == "Legend League": - return "<:LegendLeague:601612163169255436>" - elif league == "Master League I": - return "<:MasterLeagueI:601612085327036436>" - elif league == "Master League II": - return "<:MasterLeagueII:601612075474616399>" - elif league == "Master League III": - return "<:MasterLeagueIII:601612064913621002>" - elif league == "Silver League I": - return "<:SilverLeagueI:601611974849331222>" - elif league == "Silver League II": - return "<:SilverLeagueII:601611965550428160>" - elif league == "Silver League III": - return "<:SilverLeagueIII:601611958067920906>" - elif league == "Titan League I": - return "<:TitanLeagueI:601612159327141888>" - elif league == "Titan League II": - return "<:TitanLeagueII:601612148325744640>" - elif league == "Titan League III": - return "<:TitanLeagueIII:601612137491726374>" - elif "Wood" in league: - return "<:wood_league:1109716152709566524>" - elif "Clay" in league: - return "<:clay_league:1109716160561291274>" - elif "Stone" in league: - return "<:stone_league:1109716159126843403>" - elif "Copper" in league: - return "<:copper_league:1109716157440720966>" - elif "Brass" in league: - return "<:brass_league:1109716155876249620>" - elif "Iron" in league: - return "<:iron_league:1109716154257264670>" - elif "Steel" in league: - return "<:steel_league:1109716168375279616>" - elif "Titanium" in league: - return "<:titanium_league:1109716170208198686>" - elif "Platinum" in league: - return "<:platinum_league:1109716172330512384>" - elif "Emerald" in league: - return "<:emerald_league:1109716179121094707>" - elif "Ruby" in league: - return "<:ruby_league:1109716183269265501>" - elif "Diamond" in league: - return "<:diamond_league:1109716180983369768>" - else: - return "<:Unranked:601618883853680653>" + emoji = SharedEmojis.all_emojis.get(league) + if emoji is None: + league = league.split(" ")[0] + emoji = SharedEmojis.all_emojis.get(league) + if emoji is None: + emoji = SharedEmojis.all_emojis.get("unranked") + return emoji def cwl_league_emojis(league: str): - cwl_emojis = { - "Bronze League I" : "<:WarBronzeI:1116151829617705000>", - "Bronze League II" : "<:WarBronzeII:1116151836035006464>", - "Bronze League III" : "<:WarBronzeIII:1116151838136356895>", - "Silver League I" : "<:WarSilverI:1116151826870456420>", - "Silver League II" : "<:WarSilverII:1116151831542907011>", - "Silver League III" : "<:WarSilverIII:1116151833891704953>", - "Gold League I" : "<:WarGoldI:1116151792904966154>", - "Gold League II" : "<:WarGoldII:1116151794721103912>", - "Gold League III" : "<:WarGoldIII:1116151824471293954>", - "Crystal League I" : "<:WarCrystalI:1116151785476866109>", - "Crystal League II" : "<:WarCrystalII:1116151788895211682>", - "Crystal League III" : "<:WarCrystalIII:1116151790946230312>", - "Master League I" : "<:WarMasterI:1116151777813868596>", - "Master League II" : "<:WarMasterII:1116151780074598421>", - "Master League III" : "<:WarMasterIII:1116151784059191347>", - "Champion League I" : "<:WarChampionI:1116151613795598407>", - "Champion League II" : "<:WarChampionII:1116151615506894858>", - "Champion League III" : "<:WarChampionIII:1116151617922809947>" - } - return cwl_emojis.get(league, "<:Unranked:601618883853680653>") - + return SharedEmojis.all_emojis.get(f"CWL {league}", SharedEmojis.all_emojis.get("unranked")) def is_cwl(): diff --git a/utility/constants.py b/utility/constants.py index 07d7e94c..314eda71 100644 --- a/utility/constants.py +++ b/utility/constants.py @@ -122,6 +122,7 @@ 1029629953907634286, 1029629992830783549, 1029630376911581255, 1029630455202455563, 1029630702125318144, 1029630796966932520, 1029630873588469760, 1029630918106824754, 1029630974025277470, 1029631012084396102]) + SUPER_SCRIPTS=["⁰","¹","²","³","⁴","⁵","⁶", "⁷","⁸", "⁹"] DARK_ELIXIR = ["Minion", "Hog Rider", "Valkyrie", "Golem", "Witch", "Lava Hound", "Bowler", "Ice Golem", "Headhunter"] diff --git a/utility/discord_utils.py b/utility/discord_utils.py index 774f7926..72c5ee8b 100644 --- a/utility/discord_utils.py +++ b/utility/discord_utils.py @@ -2,7 +2,7 @@ import disnake from disnake.ext import commands -from assets.emojiDictionary import emojiDictionary +from assets.emojis import SharedEmojis from typing import Callable, Union from exceptions.CustomExceptions import * from typing import List @@ -52,7 +52,7 @@ async def predicate(ctx: disnake.ApplicationCommandInteraction): def partial_emoji_gen(bot, emoji_string, animated=False): emoji = ''.join(filter(str.isdigit, emoji_string)) - emoji = bot.get_emoji(int(emoji)) + emoji = bot.emoji_holder.all_emojis.get(int(emoji)) emoji = disnake.PartialEmoji( name=emoji.name, id=emoji.id, animated=animated) return emoji @@ -63,9 +63,7 @@ def embed_parse(string): def fetch_emoji(emoji_name): - emoji = emojiDictionary(emoji_name) - if emoji is None: - emoji = legend_emojis(emoji_name) + emoji = SharedEmojis.all_emojis.get(emoji_name) return emoji