Skip to content

Commit

Permalink
Merge pull request #75 from bl4ckswordsman/add-duration
Browse files Browse the repository at this point in the history
feat: Add duration for game and server session
  • Loading branch information
bl4ckswordsman authored Nov 11, 2024
2 parents 5c41e7c + 2721bb9 commit b093177
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 7 deletions.
16 changes: 11 additions & 5 deletions monitor-app/src/core/notification_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ def handle_game_state_change(state, old_status, new_status):
if new_status == 'online' and old_status == 'offline':
notify_game_online(game_name, current_time, icon_url)
elif new_status == 'offline' and old_status == 'online':
notify_game_offline(game_name, current_time, icon_url)
duration = state.get_duration()
notify_game_offline(game_name, current_time, icon_url, duration)
else:
logger.info(f"Game state change detected: {old_status} -> {new_status}")

Expand All @@ -46,7 +47,8 @@ def handle_game_server_state_change(state, old_status, new_status):
if new_status == 'online' and old_status == 'offline':
notify_server_online(game_name, state.server_owner, state.lobby_id or "Unknown", current_time, icon_url)
elif new_status == 'offline' and old_status == 'online':
notify_server_offline(game_name, state.server_owner, current_time, icon_url)
duration = state.get_duration()
notify_server_offline(game_name, state.server_owner, current_time, icon_url, duration)

def notify_game_online(game_name: str, current_time: str, icon_url: Optional[str]):
logger.info(f"{game_name} is now running")
Expand All @@ -62,21 +64,24 @@ def notify_game_online(game_name: str, current_time: str, icon_url: Optional[str
}]
})

def notify_game_offline(game_name: str, current_time: str, icon_url: Optional[str]):
def notify_game_offline(game_name: str, current_time: str, icon_url: Optional[str], duration: Optional[float]):
logger.info(f"{game_name} is now offline")
send_webhook_notification(settings_loader.get_setting('webhook_url'), {
"content": f"{game_name} is no longer running",
"embeds": [{
"title": f"{RED_CIRCLE} Game Offline",
"description": f"No active {game_name} instance",
"color": 15548997, # Red color
"fields": [
{"name": "Uptime", "value": duration if duration else "N/A", "inline": True}
],
"timestamp": current_time,
"footer": {"text": "Last updated"},
"thumbnail": {"url": icon_url} if icon_url else {}
}]
})

def notify_server_offline(game_name: str, server_owner: str, current_time: str, icon_url: Optional[str]):
def notify_server_offline(game_name: str, server_owner: str, current_time: str, icon_url: Optional[str], duration: Optional[float]):
logger.info(f"{game_name} server owned by {server_owner} is now offline")
send_webhook_notification(settings_loader.get_setting('webhook_url'), {
"content": f"The {game_name} server is down! @everyone",
Expand All @@ -85,7 +90,8 @@ def notify_server_offline(game_name: str, server_owner: str, current_time: str,
"description": f"No active {game_name} server",
"color": 15548997, # Red color
"fields": [
{"name": "Steam Host", "value": server_owner, "inline": True}
{"name": "Steam Host", "value": server_owner, "inline": True},
{"name": "Uptime", "value": duration if duration else "N/A", "inline": True}
],
"timestamp": current_time,
"footer": {"text": "Last updated"},
Expand Down
45 changes: 43 additions & 2 deletions monitor-app/src/core/state.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
from typing import Optional, Dict
from dataclasses import dataclass
from .events import event_emitter
import time

def format_duration(seconds: float) -> str:
"""Convert seconds into a human readable duration string."""
if seconds < 60:
return f"{seconds:.0f} seconds"

minutes = int(seconds / 60)
if minutes < 60:
return f"{minutes} minutes"

hours = minutes // 60
remaining_minutes = minutes % 60
if remaining_minutes == 0:
return f"{hours} hours"
return f"{hours} hours {remaining_minutes} minutes"

@dataclass
class GameState:
status: str = 'offline'
last_notified_status: str = 'offline'
start_time: Optional[float] = None
end_time: Optional[float] = None

def retrieve_state(self):
return self.status
Expand All @@ -19,16 +37,28 @@ def update_state(self, **kwargs):
changed = True
new_state = self.retrieve_state()
if changed and new_state != self.last_notified_status:
if new_state == 'online':
self.start_time = time.time()
elif new_state == 'offline':
self.end_time = time.time()
event_emitter.emit('game_state_changed', self, old_state, new_state)
self.last_notified_status = new_state

def get_duration(self) -> Optional[str]:
if self.start_time and self.end_time:
duration_seconds = self.end_time - self.start_time
return format_duration(duration_seconds)
return None

@dataclass
class GameServerState:
status: str = 'offline'
lobby_id: Optional[str] = None
server_owner: Optional[str] = None
server_data: Optional[Dict] = None
last_notified_status: str = 'offline'
start_time: Optional[float] = None
end_time: Optional[float] = None

def retrieve_state(self):
if self.status == 'offline' or self.lobby_id is None:
Expand All @@ -38,14 +68,25 @@ def retrieve_state(self):

def update_state(self, **kwargs):
old_state = self.retrieve_state()
changed = False
for key, value in kwargs.items():
if hasattr(self, key):
if hasattr(self, key) and getattr(self, key) != value:
setattr(self, key, value)
changed = True
new_state = self.retrieve_state()
if new_state != self.last_notified_status:
if changed and new_state != self.last_notified_status:
if new_state == 'online':
self.start_time = time.time()
elif new_state == 'offline':
self.end_time = time.time()
event_emitter.emit('game_server_state_changed', self, old_state, new_state)
self.last_notified_status = new_state

def get_duration(self):
if self.start_time and self.end_time:
return self.end_time - self.start_time
return None


game_state = GameState()
game_server_state = GameServerState()

0 comments on commit b093177

Please sign in to comment.