From 5573bb2bedc5cd6949fe3706f325334662722b57 Mon Sep 17 00:00:00 2001 From: Hipstercat Date: Fri, 30 Oct 2020 18:36:51 +0100 Subject: [PATCH] add force command --- cogs/wynncraft/wynncraftcog.py | 381 +++++++++++++++++---------------- 1 file changed, 195 insertions(+), 186 deletions(-) diff --git a/cogs/wynncraft/wynncraftcog.py b/cogs/wynncraft/wynncraftcog.py index 4a3e3a2..b8a4893 100644 --- a/cogs/wynncraft/wynncraftcog.py +++ b/cogs/wynncraft/wynncraftcog.py @@ -20,6 +20,7 @@ class WynncraftCog(commands.Cog): def __init__(self, bot): self.bot = bot self.config = Config.get_conf(self, identifier=48775419874) + self.last_status = {} default_guild = { "role_guild_member": 758458266195198003, "role_guild": { @@ -464,204 +465,212 @@ class WynncraftCog(commands.Cog): if await self.config.log(): print(s) - async def loop(self): - await self.bot.wait_until_ready() - last_status = {} - while self is self.bot.get_cog("WynncraftCog"): - await self._log("Looping guilds") - for guild in self.bot.guilds: - roles_combat_level = await self.config.guild(guild).role_levels() - roles_classes = await self.config.guild(guild).role_class() - roles_guild = await self.config.guild(guild).role_guild() - roles_professions = await self.config.guild(guild).role_professions() - role_guild_member = await self.config.guild(guild).role_guild_member() - guild_id = guild.id - online_players = [] - almost_online_players = [] - await self._log("Loop id %s" % guild_id) - try: - guild_name = await self.config.guild(guild).guild_name() - if not guild_name: - members = [a.display_name for a in guild.members if not a.bot] + @commands.command() + @checks.admin_or_permissions(manage_guild=True) + async def force(self, ctx): + await self.do_loop() + await ctx.send("OK!") + + async def do_loop(self): + await self._log("Looping guilds") + for guild in self.bot.guilds: + roles_combat_level = await self.config.guild(guild).role_levels() + roles_classes = await self.config.guild(guild).role_class() + roles_guild = await self.config.guild(guild).role_guild() + roles_professions = await self.config.guild(guild).role_professions() + role_guild_member = await self.config.guild(guild).role_guild_member() + guild_id = guild.id + online_players = [] + almost_online_players = [] + await self._log("Loop id %s" % guild_id) + try: + guild_name = await self.config.guild(guild).guild_name() + if not guild_name: + members = [a.display_name for a in guild.members if not a.bot] + else: + r = requests.get("https://api.wynncraft.com/public_api.php?action=guildStats&command=%s" % guild_name).json() + members = [a["name"] for a in r["members"]] + + for member_name in members: + await self._log("calling API for player %s" % member_name) + r = requests.get("https://api.wynncraft.com/v2/player/%s/stats" % member_name).json() + + max_combat_lvl_class = None + best_professions = dict.fromkeys(list(roles_professions.keys()), 0) + + if "data" not in r or not r["data"]: + await self._log("%s had empty data %s" % (member_name, r["data"])) + continue + for cl in r["data"][0]["classes"]: + if guild_id not in self.last_status: + self.last_status[guild_id] = {} + + if member_name not in self.last_status[guild_id]: + self.last_status[guild_id][member_name] = {} + + if cl["name"] not in self.last_status[guild_id][member_name]: + self.last_status[guild_id][member_name][cl["name"]] = cl + + # ping level up + ping_channel_id = await self.config.guild(guild).ping_channel() + if await self.config.guild(guild).ping_levels() and ping_channel_id: + await self._log("Checking for level up") + if cl["professions"]["combat"]["level"] > self.last_status[guild_id][member_name][cl["name"]]["professions"]["combat"]["level"]: + ping_channel = self.bot.get_channel(ping_channel_id) + await ping_channel.send(":high_brightness: %s a level up au niveau %s! GG!" % (member_name, cl["professions"]["combat"]["level"])) + else: + await self._log("Player %s had last level %s and current %s" % (member_name, self.last_status[guild_id][member_name][cl["name"]]["professions"]["combat"]["level"], cl["professions"]["combat"]["level"])) + self.last_status[guild_id][member_name][cl["name"]] = cl + + # get max_combat_lvl_class + if not max_combat_lvl_class or cl["professions"]["combat"]["level"] > max_combat_lvl_class["professions"]["combat"]["level"]: + max_combat_lvl_class = cl + + # set max_lvl_professions + for prof_name in list(roles_professions.keys()): + if cl["professions"][prof_name]["level"] > best_professions[prof_name]: + best_professions[prof_name] = cl["professions"][prof_name]["level"] + + if r["data"][0]["meta"]["location"]["online"]: + await self._log("%s is online" % member_name) + online_players.append(r) else: - r = requests.get("https://api.wynncraft.com/public_api.php?action=guildStats&command=%s" % guild_name).json() - members = [a["name"] for a in r["members"]] + last_join_dt_utc = datetime.strptime(r["data"][0]["meta"]["lastJoin"], "%Y-%m-%dT%H:%M:%S.%fZ") + last_join_dt_local = utc_to_local(last_join_dt_utc) - for member_name in members: - await self._log("calling API for player %s" % member_name) - r = requests.get("https://api.wynncraft.com/v2/player/%s/stats" % member_name).json() - - max_combat_lvl_class = None - best_professions = dict.fromkeys(list(roles_professions.keys()), 0) - - if "data" not in r or not r["data"]: - await self._log("%s had empty data %s" % (member_name, r["data"])) - continue - for cl in r["data"][0]["classes"]: - if guild_id not in last_status: - last_status[guild_id] = {} - - if member_name not in last_status[guild_id]: - last_status[guild_id][member_name] = {} - - if cl["name"] not in last_status[guild_id][member_name]: - last_status[guild_id][member_name][cl["name"]] = cl - - # ping level up - ping_channel_id = await self.config.guild(guild).ping_channel() - if await self.config.guild(guild).ping_levels() and ping_channel_id: - await self._log("Checking for level up") - if cl["professions"]["combat"]["level"] > last_status[guild_id][member_name][cl["name"]]["professions"]["combat"]["level"]: - ping_channel = self.bot.get_channel(ping_channel_id) - await ping_channel.send(":high_brightness: %s a level up au niveau %s! GG!" % (member_name, cl["professions"]["combat"]["level"])) - else: - await self._log("Player %s had last level %s and current %s" % (member_name, last_status[guild_id][member_name][cl["name"]]["professions"]["combat"]["level"], cl["professions"]["combat"]["level"])) - last_status[guild_id][member_name][cl["name"]] = cl - - # get max_combat_lvl_class - if not max_combat_lvl_class or cl["professions"]["combat"]["level"] > max_combat_lvl_class["professions"]["combat"]["level"]: - max_combat_lvl_class = cl - - # set max_lvl_professions - for prof_name in list(roles_professions.keys()): - if cl["professions"][prof_name]["level"] > best_professions[prof_name]: - best_professions[prof_name] = cl["professions"][prof_name]["level"] - - if r["data"][0]["meta"]["location"]["online"]: - await self._log("%s is online" % member_name) - online_players.append(r) + if last_join_dt_local + timedelta(minutes=30) > datetime.now(last_join_dt_local.tzinfo): + await self._log("%s is ALMOST online" % member_name) + almost_online_players.append(r) else: - last_join_dt_utc = datetime.strptime(r["data"][0]["meta"]["lastJoin"], "%Y-%m-%dT%H:%M:%S.%fZ") - last_join_dt_local = utc_to_local(last_join_dt_utc) + await self._log("%s was offline: %s" % (member_name, r["data"][0]["meta"]["location"])) - if last_join_dt_local + timedelta(minutes=30) > datetime.now(last_join_dt_local.tzinfo): - await self._log("%s is ALMOST online" % member_name) - almost_online_players.append(r) - else: - await self._log("%s was offline: %s" % (member_name, r["data"][0]["meta"]["location"])) + await self._log("Setting roles") + # set max_combat_lvl_class role + discord_member = discord.utils.find(lambda m: m.display_name.lower() == member_name.lower(), guild.members) + if max_combat_lvl_class and discord_member: + await self._log("max_combat_lvl_class and discord_member True") - await self._log("Setting roles") - # set max_combat_lvl_class role - discord_member = discord.utils.find(lambda m: m.display_name.lower() == member_name.lower(), guild.members) - if max_combat_lvl_class and discord_member: - await self._log("max_combat_lvl_class and discord_member True") + # update guild rank + if r["data"][0]["guild"]["name"] == "WynncraftFrance": + # user is guild member + # add guild member role + guild_member_role = guild.get_role(role_guild_member) + if guild_member_role not in discord_member.roles: + await self._log("Add role: %s" % guild_member_role) + await discord_member.add_roles(guild_member_role) - # update guild rank - if r["data"][0]["guild"]["name"] == "WynncraftFrance": - # user is guild member - # add guild member role - guild_member_role = guild.get_role(role_guild_member) - if guild_member_role not in discord_member.roles: - await self._log("Add role: %s" % guild_member_role) - await discord_member.add_roles(guild_member_role) + # add guild rank role + guild_rank = r["data"][0]["guild"]["rank"] + if guild_rank in roles_guild: + guild_role_id = roles_guild[guild_rank] + rank_role = guild.get_role(guild_role_id) + if rank_role not in discord_member.roles: + await self._log("Add role: %s" % rank_role) + await discord_member.add_roles(rank_role) - # add guild rank role - guild_rank = r["data"][0]["guild"]["rank"] - if guild_rank in roles_guild: - guild_role_id = roles_guild[guild_rank] - rank_role = guild.get_role(guild_role_id) - if rank_role not in discord_member.roles: - await self._log("Add role: %s" % rank_role) - await discord_member.add_roles(rank_role) - - roles_to_remove = list(filter(lambda role: role.id in list(roles_guild.values()) and role.id != guild_role_id, discord_member.roles)) - if roles_to_remove: - await self._log("remove roles: %s" % roles_to_remove) - await discord_member.remove_roles(*roles_to_remove) - - else: - # remove ranks - roles_to_remove = list(filter(lambda role: role.id in list(roles_guild.values()) or role.id == role_guild_member, discord_member.roles)) + roles_to_remove = list(filter(lambda role: role.id in list(roles_guild.values()) and role.id != guild_role_id, discord_member.roles)) if roles_to_remove: await self._log("remove roles: %s" % roles_to_remove) await discord_member.remove_roles(*roles_to_remove) - # update level - await discord_member.add_roles(guild.get_role(743544189861626017)) # classe - max_combat_lvl = max_combat_lvl_class["professions"]["combat"]["level"] - combat_role_index = max_combat_lvl // 10 - if combat_role_index > 10: combat_role_index = 10 - combat_role_id = roles_combat_level[combat_role_index] - combat_role = guild.get_role(combat_role_id) - if combat_role not in discord_member.roles: - await self._log("Add role: %s" % combat_role) - await discord_member.add_roles(combat_role) - - roles_to_remove = list(filter(lambda role: role.id in roles_combat_level and role.id != combat_role_id, discord_member.roles)) - if roles_to_remove: - await self._log("remove roles: %s" % roles_to_remove) - await discord_member.remove_roles(*roles_to_remove) - - # update class - class_name = max_combat_lvl_class["name"] - - class_role_id = None - if class_name.startswith("archer") or class_name.startswith("hunter"): - class_role_id = roles_classes["archer"] - if class_name.startswith("mage") or class_name.startswith("darkwizard"): - class_role_id = roles_classes["mage"] - if class_name.startswith("assassin") or class_name.startswith("ninja"): - class_role_id = roles_classes["assassin"] - if class_name.startswith("warrior") or class_name.startswith("knight"): - class_role_id = roles_classes["warrior"] - if class_name.startswith("shaman") or class_name.startswith("skyseer"): - class_role_id = roles_classes["shaman"] - - class_role = guild.get_role(class_role_id) - if class_role not in discord_member.roles: - await self._log("Add role: %s" % class_role) - await discord_member.add_roles(class_role) - - roles_to_remove = list(filter(lambda role: role.id in list(roles_classes.values()) and role.id != class_role_id, discord_member.roles)) - if roles_to_remove: - await self._log("remove roles: %s" % roles_to_remove) - await discord_member.remove_roles(*roles_to_remove) - - # update professions - await discord_member.add_roles(guild.get_role(750108451287466095)) # métiers - role_ids_to_add = [] - for prof_name in best_professions: - prof_level = best_professions[prof_name] - if prof_level < 5: continue # do not add roles for professions < lvl 5 - prof_role_index = prof_level // 10 - if prof_role_index > 10: prof_role_index = 10 - role_ids_to_add.append(roles_professions[prof_name][prof_role_index]) - - roles_to_add = [] - for role_id_to_add in role_ids_to_add: - roles_to_add.append(guild.get_role(role_id_to_add)) - await self._log("Add role: %s" % roles_to_add) - await discord_member.add_roles(*roles_to_add) - - all_prof_ids = list(itertools.chain.from_iterable([roles_professions[b] for b in roles_professions])) - roles_to_remove = list(filter(lambda role: role.id in all_prof_ids and role.id not in role_ids_to_add, discord_member.roles)) - if roles_to_remove: - await self._log("remove roles: %s" % roles_to_remove) - await discord_member.remove_roles(*roles_to_remove) - else: - await self._log("max_combat_lvl_class: %s, discord_member: %s (name: %s)" % (max_combat_lvl_class, discord_member, member_name)) + # remove ranks + roles_to_remove = list(filter(lambda role: role.id in list(roles_guild.values()) or role.id == role_guild_member, discord_member.roles)) + if roles_to_remove: + await self._log("remove roles: %s" % roles_to_remove) + await discord_member.remove_roles(*roles_to_remove) - # update online players - await self._log("Updating online list") - full_text = "" - for online_player in online_players: - s = ":green_circle: **%s** connecté sur %s" % (online_player["data"][0]["username"], online_player["data"][0]["meta"]["location"]["server"]) - full_text += s + "\n" - for almost_online_player in almost_online_players: - last_join_dt_utc = datetime.strptime(almost_online_player["data"][0]["meta"]["lastJoin"], "%Y-%m-%dT%H:%M:%S.%fZ") - last_join_dt_local = utc_to_local(last_join_dt_utc) - mins = math.ceil((datetime.now(last_join_dt_local.tzinfo) - last_join_dt_local).total_seconds() // 60) - s = ":grey_question: **%s** était connecté il y a %s minutes" % (almost_online_player["data"][0]["username"], mins) - full_text += s + "\n" - if not online_players and not almost_online_players: - full_text = "Personne n'est connecté :disappointed_relieved:\n" - full_text += "\n*Dernière mise à jour: %s*\n*Les vraies informations peuvent prendre jusqu'à 5 minutes de plus*" % datetime.now().strftime("%d/%m/%Y %H:%M:%S") - online_channel = self.bot.get_channel(750100968766701708) - update_msg = await online_channel.fetch_message(await self.config.guild(guild).update_msg()) - await update_msg.edit(content=full_text) + # update level + await discord_member.add_roles(guild.get_role(743544189861626017)) # classe + max_combat_lvl = max_combat_lvl_class["professions"]["combat"]["level"] + combat_role_index = max_combat_lvl // 10 + if combat_role_index > 10: combat_role_index = 10 + combat_role_id = roles_combat_level[combat_role_index] + combat_role = guild.get_role(combat_role_id) + if combat_role not in discord_member.roles: + await self._log("Add role: %s" % combat_role) + await discord_member.add_roles(combat_role) - except: - if await self.config.log(): - traceback.print_exc() + roles_to_remove = list(filter(lambda role: role.id in roles_combat_level and role.id != combat_role_id, discord_member.roles)) + if roles_to_remove: + await self._log("remove roles: %s" % roles_to_remove) + await discord_member.remove_roles(*roles_to_remove) + + # update class + class_name = max_combat_lvl_class["name"] + + class_role_id = None + if class_name.startswith("archer") or class_name.startswith("hunter"): + class_role_id = roles_classes["archer"] + if class_name.startswith("mage") or class_name.startswith("darkwizard"): + class_role_id = roles_classes["mage"] + if class_name.startswith("assassin") or class_name.startswith("ninja"): + class_role_id = roles_classes["assassin"] + if class_name.startswith("warrior") or class_name.startswith("knight"): + class_role_id = roles_classes["warrior"] + if class_name.startswith("shaman") or class_name.startswith("skyseer"): + class_role_id = roles_classes["shaman"] + + class_role = guild.get_role(class_role_id) + if class_role not in discord_member.roles: + await self._log("Add role: %s" % class_role) + await discord_member.add_roles(class_role) + + roles_to_remove = list(filter(lambda role: role.id in list(roles_classes.values()) and role.id != class_role_id, discord_member.roles)) + if roles_to_remove: + await self._log("remove roles: %s" % roles_to_remove) + await discord_member.remove_roles(*roles_to_remove) + + # update professions + await discord_member.add_roles(guild.get_role(750108451287466095)) # métiers + role_ids_to_add = [] + for prof_name in best_professions: + prof_level = best_professions[prof_name] + if prof_level < 5: continue # do not add roles for professions < lvl 5 + prof_role_index = prof_level // 10 + if prof_role_index > 10: prof_role_index = 10 + role_ids_to_add.append(roles_professions[prof_name][prof_role_index]) + + roles_to_add = [] + for role_id_to_add in role_ids_to_add: + roles_to_add.append(guild.get_role(role_id_to_add)) + await self._log("Add role: %s" % roles_to_add) + await discord_member.add_roles(*roles_to_add) + + all_prof_ids = list(itertools.chain.from_iterable([roles_professions[b] for b in roles_professions])) + roles_to_remove = list(filter(lambda role: role.id in all_prof_ids and role.id not in role_ids_to_add, discord_member.roles)) + if roles_to_remove: + await self._log("remove roles: %s" % roles_to_remove) + await discord_member.remove_roles(*roles_to_remove) + + else: + await self._log("max_combat_lvl_class: %s, discord_member: %s (name: %s)" % (max_combat_lvl_class, discord_member, member_name)) + + # update online players + await self._log("Updating online list") + full_text = "" + for online_player in online_players: + s = ":green_circle: **%s** connecté sur %s" % (online_player["data"][0]["username"], online_player["data"][0]["meta"]["location"]["server"]) + full_text += s + "\n" + for almost_online_player in almost_online_players: + last_join_dt_utc = datetime.strptime(almost_online_player["data"][0]["meta"]["lastJoin"], "%Y-%m-%dT%H:%M:%S.%fZ") + last_join_dt_local = utc_to_local(last_join_dt_utc) + mins = math.ceil((datetime.now(last_join_dt_local.tzinfo) - last_join_dt_local).total_seconds() // 60) + s = ":grey_question: **%s** était connecté il y a %s minutes" % (almost_online_player["data"][0]["username"], mins) + full_text += s + "\n" + if not online_players and not almost_online_players: + full_text = "Personne n'est connecté :disappointed_relieved:\n" + full_text += "\n*Dernière mise à jour: %s*\n*Les vraies informations peuvent prendre jusqu'à 5 minutes de plus*" % datetime.now().strftime("%d/%m/%Y %H:%M:%S") + online_channel = self.bot.get_channel(750100968766701708) + update_msg = await online_channel.fetch_message(await self.config.guild(guild).update_msg()) + await update_msg.edit(content=full_text) + + except: + if await self.config.log(): + traceback.print_exc() + + async def loop(self): + await self.bot.wait_until_ready() + while self is self.bot.get_cog("WynncraftCog"): + await self.do_loop() await asyncio.sleep(3600)