From 68e9cdae4ea521d2ed01cd46a6b9f0015558dc0e Mon Sep 17 00:00:00 2001 From: salmonik Date: Thu, 19 Mar 2026 18:01:11 +0100 Subject: vclogs afk/active time --- cogs/vclogs.py | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 116 insertions(+), 10 deletions(-) (limited to 'cogs/vclogs.py') diff --git a/cogs/vclogs.py b/cogs/vclogs.py index 9ed7134..0589364 100644 --- a/cogs/vclogs.py +++ b/cogs/vclogs.py @@ -16,6 +16,30 @@ from cogs.voice import get_voice_manager logger = logging.getLogger(__name__) +ACTIVITY_FILE = 'temp/voice_activity.json' + + +def load_activity_data(): + if os.path.exists(ACTIVITY_FILE): + with open(ACTIVITY_FILE, 'r') as f: + return json.load(f) + return {} + + +def save_activity_data(data): + with open(ACTIVITY_FILE, 'w') as f: + json.dump(data, f, indent=4) + + +def format_duration(seconds): + hours, remainder = divmod(int(seconds), 3600) + minutes, seconds = divmod(remainder, 60) + if hours > 0: + return f"{hours}h {minutes}m {seconds}s" + elif minutes > 0: + return f"{minutes}m {seconds}s" + return f"{seconds}s" + class VcLogs(commands.Cog): def __init__(self, bot): @@ -30,7 +54,7 @@ class VcLogs(commands.Cog): settings_file = 'settings.json' @staticmethod - async def handle_state_change(member, channel, state_type, is_enabled, current_time, log_channel): + async def handle_state_change(member, channel, state_type, is_enabled, current_time, log_channel, activity_suffix=None): """Helper method to handle voice state changes""" state_messages = { 'deaf': { @@ -56,6 +80,8 @@ class VcLogs(commands.Cog): } message, tts_text = state_messages[state_type][is_enabled] + if activity_suffix: + message = f"{message}\n{activity_suffix}" await log_channel.send(message) logger.info(f"Voice state change: {message}") return tts_text, channel @@ -109,37 +135,117 @@ class VcLogs(commands.Cog): async def on_voice_state_update(self, member, before, after): log_channel = self.bot.get_channel(1213843195457183885) current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + current_ts = datetime.datetime.now().timestamp() tts_text = None tts_channel = None - # Ignore if the user is a bot if member.bot: return + user_id = str(member.id) + activity_data = load_activity_data() + if before.channel is None and after.channel is not None: + is_afk = after.self_mute or after.self_deaf + activity_data[user_id] = { + 'join_time': current_ts, + 'total_active': 0, + 'total_afk': 0, + 'is_afk': is_afk, + 'afk_start': current_ts if is_afk else None, + 'active_start': current_ts if not is_afk else None, + 'channel_name': after.channel.name + } + save_activity_data(activity_data) + message = f"[{current_time}] {member.name} dołączył na {after.channel.name}" tts_text = f"{member.display_name} sie zespawnił" tts_channel = after.channel await log_channel.send(message) logger.info(f"User joined voice channel: {message}") + elif before.channel is not None and after.channel is None: - message = f"[{current_time}] {member.name} rozłączył się z {before.channel.name}" - tts_text = f"{member.display_name} jest chujem" - tts_channel = before.channel - await log_channel.send(message) - logger.info(f"User left voice channel: {message}") + if user_id in activity_data: + data = activity_data[user_id] + + if data.get('is_afk') and data.get('afk_start'): + afk_duration = current_ts - data['afk_start'] + data['total_afk'] += afk_duration + elif data.get('active_start'): + active_since_start = current_ts - data['active_start'] + data['total_active'] += active_since_start + + active_str = format_duration(data['total_active']) + afk_str = format_duration(data['total_afk']) + + message = ( + f"[{current_time}] {member.name} rozłączył się z {before.channel.name}\n" + f" Aktywny: {active_str} | AFK: {afk_str}" + ) + tts_text = f"{member.display_name} jest chujem" + tts_channel = before.channel + await log_channel.send(message) + logger.info(f"User left voice channel: {message}") + + del activity_data[user_id] + save_activity_data(activity_data) + else: + message = f"[{current_time}] {member.name} rozłączył się z {before.channel.name}" + tts_text = f"{member.display_name} jest chujem" + tts_channel = before.channel + await log_channel.send(message) + logger.info(f"User left voice channel: {message}") + + elif user_id in activity_data: + data = activity_data[user_id] + + if data.get('is_afk') and not (after.self_mute or after.self_deaf): + afk_duration = current_ts - data['afk_start'] + data['total_afk'] += afk_duration + data['afk_start'] = None + data['is_afk'] = False + data['active_start'] = current_ts + save_activity_data(activity_data) + elif not data.get('is_afk') and (after.self_mute or after.self_deaf): + if data.get('active_start'): + active_since_start = current_ts - data['active_start'] + data['total_active'] += active_since_start + data['afk_start'] = current_ts + data['is_afk'] = True + data['active_start'] = None + save_activity_data(activity_data) if before.self_deaf != after.self_deaf: + activity_suffix = None + if user_id in activity_data: + data = activity_data[user_id] + if after.self_deaf: + active_str = format_duration(data['total_active']) + activity_suffix = f" Aktywny przed AFK: {active_str}" + else: + active_str = format_duration(data['total_active']) + afk_str = format_duration(data['total_afk']) + activity_suffix = f" Był AFK: {afk_str} | Łączny aktywny: {active_str}" tts_text, tts_channel = await self.handle_state_change( - member, after.channel, 'deaf', after.self_deaf, current_time, log_channel + member, after.channel, 'deaf', after.self_deaf, current_time, log_channel, activity_suffix ) if tts_text and tts_channel: await self.play_tts(tts_channel, tts_text) return if before.self_mute != after.self_mute: + activity_suffix = None + if user_id in activity_data: + data = activity_data[user_id] + if after.self_mute: + active_str = format_duration(data['total_active']) + activity_suffix = f" Aktywny przed AFK: {active_str}" + else: + active_str = format_duration(data['total_active']) + afk_str = format_duration(data['total_afk']) + activity_suffix = f" Był AFK: {afk_str} | Łączny aktywny: {active_str}" tts_text, tts_channel = await self.handle_state_change( - member, after.channel, 'mute', after.self_mute, current_time, log_channel + member, after.channel, 'mute', after.self_mute, current_time, log_channel, activity_suffix ) if tts_text and tts_channel: @@ -147,4 +253,4 @@ class VcLogs(commands.Cog): def setup(bot): - bot.add_cog(VcLogs(bot)) \ No newline at end of file + bot.add_cog(VcLogs(bot)) -- cgit v1.2.3