From 1f7f211e3658f5404303547711dd96fb7d3818b8 Mon Sep 17 00:00:00 2001 From: Eaven Kimura Date: Fri, 26 Sep 2025 08:52:41 +0000 Subject: [PATCH] Add server uptime metric to embed --- pterodisbot.py | 48 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/pterodisbot.py b/pterodisbot.py index fa71274..ad407f4 100644 --- a/pterodisbot.py +++ b/pterodisbot.py @@ -551,8 +551,8 @@ class PterodactylBot(commands.Bot): self.update_lock = asyncio.Lock() # Prevents concurrent updates self.embed_storage_path = Path(EMBED_LOCATIONS_FILE) # File to store embed locations # Track previous server states and CPU usage to detect changes - # Format: {server_id: (state, cpu_usage)} - self.previous_states: Dict[str, Tuple[str, float]] = {} + # Format: {server_id: (state, cpu_usage, last_force_update)} + self.previous_states: Dict[str, Tuple[str, float, Optional[float]]] = {} logger.info("Initialized PterodactylBot instance with state tracking") async def setup_hook(self): @@ -765,6 +765,28 @@ class PterodactylBot(commands.Bot): network_rx = round(resource_attributes.get('resources', {}).get('network_rx_bytes', 0) / (1024 ** 2), 2) network_tx = round(resource_attributes.get('resources', {}).get('network_tx_bytes', 0) / (1024 ** 2), 2) + # Get uptime from Pterodactyl API (in milliseconds) + uptime_ms = resource_attributes.get('resources', {}).get('uptime', 0) + + # Format uptime for display + if uptime_ms > 0: + uptime_seconds = uptime_ms // 1000 # Convert ms to seconds + if uptime_seconds < 60: + uptime_text = f"{uptime_seconds}s" + elif uptime_seconds < 3600: + uptime_text = f"{uptime_seconds // 60}m {uptime_seconds % 60}s" + elif uptime_seconds < 86400: + hours = uptime_seconds // 3600 + minutes = (uptime_seconds % 3600) // 60 + uptime_text = f"{hours}h {minutes}m" + else: + days = uptime_seconds // 86400 + hours = (uptime_seconds % 86400) // 3600 + uptime_text = f"{days}d {hours}h" + else: + uptime_text = "Just started" + + embed.add_field(name="Uptime", value=uptime_text, inline=True) embed.add_field(name="CPU Usage", value=f"{cpu_usage}%", inline=True) embed.add_field(name="Memory Usage", value=f"{memory_usage} MB", inline=True) embed.add_field(name="Disk Usage", value=f"{disk_usage} MB", inline=True) @@ -790,6 +812,7 @@ class PterodactylBot(commands.Bot): 1. Server power state changes (started/stopped/restarted) 2. Significant CPU usage change (>50% difference) 3. First time seeing the server + 4. Server has been running for 10 minutes (force update for uptime) This minimizes API calls to Discord and updates while maintaining real-time awareness of important server changes. @@ -812,6 +835,7 @@ class PterodactylBot(commands.Bot): error_count = 0 # Failed updates missing_count = 0 # Missing embeds skipped_count = 0 # Servers that didn't need updates + current_time = datetime.now().timestamp() # Process each server we're tracking embeds for for server_id, location in list(self.embed_locations.items()): @@ -831,8 +855,8 @@ class PterodactylBot(commands.Bot): current_state = resources.get('attributes', {}).get('current_state', 'offline') cpu_usage = round(resources.get('attributes', {}).get('resources', {}).get('cpu_absolute', 0), 2) - # Retrieve previous recorded state and CPU usage - prev_state, prev_cpu = self.previous_states.get(server_id, (None, 0)) + # Retrieve previous recorded state, CPU usage, and last force update time + prev_state, prev_cpu, last_force_update = self.previous_states.get(server_id, (None, 0, None)) # DECISION LOGIC: Should we update the embed? needs_update = False @@ -852,6 +876,15 @@ class PterodactylBot(commands.Bot): logger.debug(f"First check for {server_name}, performing initial update") needs_update = True + # 4. Force update every 10 minutes for running servers (for uptime counter) + elif (current_state == 'running' and + (last_force_update is None or + current_time - last_force_update >= 600)): # 10 minutes = 600 seconds + logger.debug(f"Executing 10-minute force update for running server {server_name}") + needs_update = True + # Update the last force update time + last_force_update = current_time + # PERFORM UPDATE IF NEEDED if needs_update: # Generate fresh embed and view components @@ -870,9 +903,12 @@ class PterodactylBot(commands.Bot): logger.debug(f"Updated status for {server_name}") # Update our state tracking with new values - self.previous_states[server_id] = (current_state, cpu_usage) + # Only update last_force_update if this was a force update + new_last_force_update = last_force_update if needs_update and current_state == 'running' and current_time - (last_force_update or 0) >= 600 else (last_force_update if last_force_update is not None else None) + self.previous_states[server_id] = (current_state, cpu_usage, new_last_force_update) else: - # No significant changes detected + # No significant changes detected, but update tracking with current state + self.previous_states[server_id] = (current_state, cpu_usage, last_force_update) skipped_count += 1 logger.debug(f"No changes detected for {server_name}, skipping update")