Spaces:
Build error
Build error
Download player_tracker.py from smodusermc/MC: direct link, hf CLI and curl.
- Browser
- Download file 7.33 kB
-
https://huggingface.co/spaces/smodusermc/MC/resolve/main/player_tracker.py
- Command line
-
hf download hf://spaces/smodusermc/MC/player_tracker.py
-
curl -L -o player_tracker.py https://huggingface.co/spaces/smodusermc/MC/resolve/main/player_tracker.py
7.33 kB
| import json | |
| import os | |
| from pathlib import Path | |
| from datetime import datetime | |
| from typing import List, Dict, Optional | |
| from config import config | |
| class PlayerTracker: | |
| def __init__(self, server_manager): | |
| self.server_manager = server_manager | |
| self.players_data_file = config.SERVER_DIR / "players_data.json" | |
| self.players_data = self._load_data() | |
| def _load_data(self) -> Dict: | |
| """Load player data from file""" | |
| if self.players_data_file.exists(): | |
| try: | |
| with open(self.players_data_file, 'r') as f: | |
| return json.load(f) | |
| except: | |
| pass | |
| return {'players': {}} | |
| def _save_data(self): | |
| """Save player data to file""" | |
| with open(self.players_data_file, 'w') as f: | |
| json.dump(self.players_data, f, indent=2) | |
| def record_join(self, player_name: str): | |
| """Record player joining""" | |
| if player_name not in self.players_data['players']: | |
| self.players_data['players'][player_name] = { | |
| 'first_seen': datetime.now().isoformat(), | |
| 'last_seen': datetime.now().isoformat(), | |
| 'join_count': 0, | |
| 'play_time': 0, | |
| 'is_banned': False, | |
| 'is_op': False, | |
| 'notes': '' | |
| } | |
| self.players_data['players'][player_name]['last_seen'] = datetime.now().isoformat() | |
| self.players_data['players'][player_name]['join_count'] += 1 | |
| self.players_data['players'][player_name]['_join_time'] = datetime.now().isoformat() | |
| self._save_data() | |
| def record_leave(self, player_name: str): | |
| """Record player leaving""" | |
| if player_name in self.players_data['players']: | |
| player = self.players_data['players'][player_name] | |
| player['last_seen'] = datetime.now().isoformat() | |
| if '_join_time' in player: | |
| join_time = datetime.fromisoformat(player['_join_time']) | |
| session_time = (datetime.now() - join_time).total_seconds() | |
| player['play_time'] = player.get('play_time', 0) + session_time | |
| del player['_join_time'] | |
| self._save_data() | |
| def get_online_players(self) -> List[Dict]: | |
| """Get list of online players with details""" | |
| online = [] | |
| for name in self.server_manager.players_online: | |
| player_data = self.players_data['players'].get(name, {}) | |
| online.append({ | |
| 'name': name, | |
| 'join_count': player_data.get('join_count', 1), | |
| 'is_op': player_data.get('is_op', False), | |
| 'first_seen': player_data.get('first_seen', 'Now'), | |
| 'play_time': self._format_time(player_data.get('play_time', 0)) | |
| }) | |
| return online | |
| def get_all_players(self) -> List[Dict]: | |
| """Get all known players""" | |
| players = [] | |
| for name, data in self.players_data['players'].items(): | |
| players.append({ | |
| 'name': name, | |
| 'online': name in self.server_manager.players_online, | |
| 'first_seen': data.get('first_seen', 'Unknown'), | |
| 'last_seen': data.get('last_seen', 'Unknown'), | |
| 'join_count': data.get('join_count', 0), | |
| 'play_time': self._format_time(data.get('play_time', 0)), | |
| 'is_banned': data.get('is_banned', False), | |
| 'is_op': data.get('is_op', False), | |
| 'notes': data.get('notes', '') | |
| }) | |
| return players | |
| def _format_time(self, seconds: float) -> str: | |
| """Format seconds to readable time""" | |
| hours = int(seconds // 3600) | |
| minutes = int((seconds % 3600) // 60) | |
| if hours > 0: | |
| return f"{hours}h {minutes}m" | |
| return f"{minutes}m" | |
| def kick_player(self, player_name: str, reason: str = "Kicked by admin") -> Dict: | |
| """Kick a player""" | |
| if player_name not in self.server_manager.players_online: | |
| return {'success': False, 'message': 'Player not online'} | |
| return self.server_manager.send_command(f'kick {player_name} {reason}') | |
| def ban_player(self, player_name: str, reason: str = "Banned by admin") -> Dict: | |
| """Ban a player""" | |
| result = self.server_manager.send_command(f'ban {player_name} {reason}') | |
| if result['success']: | |
| if player_name in self.players_data['players']: | |
| self.players_data['players'][player_name]['is_banned'] = True | |
| self._save_data() | |
| return result | |
| def pardon_player(self, player_name: str) -> Dict: | |
| """Unban a player""" | |
| result = self.server_manager.send_command(f'pardon {player_name}') | |
| if result['success']: | |
| if player_name in self.players_data['players']: | |
| self.players_data['players'][player_name]['is_banned'] = False | |
| self._save_data() | |
| return result | |
| def op_player(self, player_name: str) -> Dict: | |
| """Give operator status""" | |
| result = self.server_manager.send_command(f'op {player_name}') | |
| if result['success']: | |
| if player_name in self.players_data['players']: | |
| self.players_data['players'][player_name]['is_op'] = True | |
| self._save_data() | |
| return result | |
| def deop_player(self, player_name: str) -> Dict: | |
| """Remove operator status""" | |
| result = self.server_manager.send_command(f'deop {player_name}') | |
| if result['success']: | |
| if player_name in self.players_data['players']: | |
| self.players_data['players'][player_name]['is_op'] = False | |
| self._save_data() | |
| return result | |
| def update_notes(self, player_name: str, notes: str) -> Dict: | |
| """Update player notes""" | |
| if player_name not in self.players_data['players']: | |
| self.players_data['players'][player_name] = {} | |
| self.players_data['players'][player_name]['notes'] = notes | |
| self._save_data() | |
| return {'success': True, 'message': 'Notes updated'} | |
| def get_whitelist(self) -> List[str]: | |
| """Get whitelist""" | |
| whitelist_file = config.SERVER_DIR / "whitelist.json" | |
| if whitelist_file.exists(): | |
| try: | |
| with open(whitelist_file, 'r') as f: | |
| data = json.load(f) | |
| return [p.get('name', '') for p in data] | |
| except: | |
| pass | |
| return [] | |
| def get_ops(self) -> List[str]: | |
| """Get ops list""" | |
| ops_file = config.SERVER_DIR / "ops.json" | |
| if ops_file.exists(): | |
| try: | |
| with open(ops_file, 'r') as f: | |
| data = json.load(f) | |
| return [p.get('name', '') for p in data] | |
| except: | |
| pass | |
| return [] | |
| def get_banned(self) -> List[Dict]: | |
| """Get banned players""" | |
| banned_file = config.SERVER_DIR / "banned-players.json" | |
| if banned_file.exists(): | |
| try: | |
| with open(banned_file, 'r') as f: | |
| return json.load(f) | |
| except: | |
| pass | |
| return [] |