MC / player_tracker.py
smodusermc's picture
Create player_tracker.py
ac3d971 verified
Raw History Blame Contribute Delete
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 []