2020 app_commands ,
2121 utils ,
2222)
23+ from discord .ext import tasks
2324from discord .ext .commands import Cog
2425
2526from bot .main import ActBot
3536class FarmCog (Cog , description = "Allow players to gain stats and roles" ):
3637 def __init__ (self , bot : ActBot ):
3738 self .bot = bot
39+ self .xp_gain_log : dict [int , dict [int , int ]] = {}
40+ self .log_xp_gains .start ()
41+
42+ def cog_unload (self ):
43+ self .log_xp_gains .cancel ()
44+
45+ # ----------------------------------------------------------------------------------------------------
46+ # * Log XP Gains
47+ # ----------------------------------------------------------------------------------------------------
48+ @tasks .loop (seconds = 60.0 )
49+ async def log_xp_gains (self ):
50+ log_copy = self .xp_gain_log .copy ()
51+ self .xp_gain_log .clear ()
52+
53+ for guild_id , user_gains in log_copy .items ():
54+ if not user_gains :
55+ continue
56+
57+ guild = self .bot .get_guild (guild_id )
58+ if not guild :
59+ continue
60+
61+ log_room = self .load_room (id = FarmCog .__name__ , guild = guild )
62+ if not log_room :
63+ continue
64+
65+ log_channel = guild .get_channel (log_room .channel_id )
66+ if not (log_channel and isinstance (log_channel , TextChannel )):
67+ continue
68+
69+ description_lines = []
70+ for user_id , total_xp in sorted (
71+ user_gains .items (), key = lambda item : item [1 ], reverse = True
72+ ):
73+ description_lines .append (f"⏫ <@{ user_id } > earned **{ total_xp } ** xp." )
74+
75+ if not description_lines :
76+ continue
77+
78+ try :
79+ await log_channel .send ("\n " .join (description_lines ))
80+ except HTTPException as e :
81+ print (
82+ f"Failed to send XP log to #{ log_channel .name } in { guild .name } : { e } "
83+ )
84+
85+ @log_xp_gains .before_loop
86+ async def before_log_xp_gains (self ):
87+ await self .bot .wait_until_ready ()
3888
3989 # ----------------------------------------------------------------------------------------------------
4090 # * Set Farm Log
@@ -212,6 +262,10 @@ async def on_message(self, message: Message):
212262 if not message .guild or not isinstance (member , Member ):
213263 return
214264
265+ # Ignore bots
266+ if member .bot :
267+ return
268+
215269 # Get or create actor
216270 db = self .bot .get_db (message .guild )
217271 actor = db .find_one (Actor , Actor .id == member .id ) or self .bot .create_actor (
@@ -230,27 +284,14 @@ async def on_message(self, message: Message):
230284 print (f"👤 @{ member .name } earned { xp_reward } xp." )
231285
232286 # Log xp gain to a "log" named channel
233- log_room = self .load_room (id = FarmCog .__name__ , guild = message .guild )
234- log_channel = (
235- message .guild .get_channel (log_room .channel_id ) if log_room else None
236- )
237- if not member .bot and log_channel and isinstance (log_channel , TextChannel ):
238- # embed = EmbedX.info(
239- # emoji="",
240- # title="",
241- # description=f"⏫ {member.mention} earned experience.",
242- # )
243- # embed.add_field(name="Experience 🔼", value=f"**⏫ +{xp_reward} **")
244- # embed.set_author(
245- # name=member.display_name, icon_url=member.display_avatar.url
246- # )
247- # embed = EmbedX.info(
248- # emoji="",
249- # title="",
250- # description=f"**⏫ +{xp_reward}** XP for {member.mention}.",
251- # )
252- # await log_channel.send(embed=embed)
253- await log_channel .send (f"{ member .display_name } earned **{ xp_reward } ** xp." )
287+ if xp_reward > 0 :
288+ guild_id = message .guild .id
289+ user_id = member .id
290+ if guild_id not in self .xp_gain_log :
291+ self .xp_gain_log [guild_id ] = {}
292+ self .xp_gain_log [guild_id ][user_id ] = (
293+ self .xp_gain_log [guild_id ].get (user_id , 0 ) + xp_reward
294+ )
254295
255296 # Try level-up
256297 if actor .try_level_up ():
0 commit comments