modified: app.py

This commit is contained in:
SimolZimol
2025-10-26 02:19:25 +02:00
parent 1030701033
commit 9746a9f3bf

163
app.py
View File

@@ -612,6 +612,169 @@ async def hoi4games(ctx):
except Exception as e:
await ctx.send(f"❌ Error getting games: {str(e)}")
@bot.hybrid_command(name='hoi4history', description='Show past games with optional filters')
async def hoi4history(ctx, limit: Optional[int] = 10, player: Optional[discord.Member] = None, game_name: Optional[str] = None, game_type: Optional[str] = None):
"""Show past games with optional filters"""
if limit > 50:
limit = 50 # Prevent too many results
try:
async with db_pool.acquire() as conn:
async with conn.cursor(aiomysql.DictCursor) as cursor:
# Build dynamic query based on filters
query = "SELECT * FROM games WHERE status = 'finished'"
params = []
if game_name:
query += " AND game_name LIKE %s"
params.append(f"%{game_name}%")
if game_type and game_type.lower() in ['standard', 'competitive']:
query += " AND game_type = %s"
params.append(game_type.lower())
if player:
query += " AND JSON_CONTAINS(players, JSON_OBJECT('discord_id', %s))"
params.append(player.id)
query += " ORDER BY finished_at DESC LIMIT %s"
params.append(limit)
await cursor.execute(query, params)
games = await cursor.fetchall()
if not games:
await ctx.send("📝 No finished games found with the specified filters!")
return
embed = discord.Embed(
title="📚 HOI4 Game History",
color=discord.Color.blue()
)
if player:
embed.description = f"Filtered by player: {player.display_name}"
if game_name:
embed.description = f"Filtered by game name: {game_name}"
if game_type:
embed.description = f"Filtered by type: {game_type.title()}"
for game in games:
players = json.loads(game['players']) if game['players'] else []
# Count teams and players
teams = {}
for p in players:
team = p['team_name']
if team not in teams:
teams[team] = 0
teams[team] += 1
# Format date
finished_date = game['finished_at'].strftime("%m/%d/%Y %H:%M") if game['finished_at'] else "Unknown"
# Winner indicator
winner = game['winner_team'] if game['winner_team'] else "Unknown"
game_info = f"**Winner:** {winner}\n"
game_info += f"**Type:** {game['game_type'].title()}\n"
game_info += f"**Players:** {len(players)} | **Teams:** {len(teams)}\n"
game_info += f"**Finished:** {finished_date}"
embed.add_field(
name=f"🏆 {game['game_name']}",
value=game_info,
inline=False
)
embed.set_footer(text=f"Showing {len(games)} of last {limit} games")
await ctx.send(embed=embed)
except Exception as e:
await ctx.send(f"❌ Error getting game history: {str(e)}")
@bot.hybrid_command(name='hoi4leaderboard', description='Show ELO leaderboard')
async def hoi4leaderboard(ctx, game_type: Optional[str] = "standard", limit: Optional[int] = 10):
"""Show ELO leaderboard for standard or competitive"""
if game_type.lower() not in ['standard', 'competitive']:
await ctx.send("❌ Game type must be either 'standard' or 'competitive'")
return
if limit > 25:
limit = 25 # Prevent too many results
try:
async with db_pool.acquire() as conn:
async with conn.cursor(aiomysql.DictCursor) as cursor:
# Get top players by ELO
elo_field = f"{game_type.lower()}_elo"
await cursor.execute(
f"SELECT discord_id, username, {elo_field}, created_at FROM players ORDER BY {elo_field} DESC LIMIT %s",
(limit,)
)
players = await cursor.fetchall()
# Also get some statistics
await cursor.execute(
f"SELECT COUNT(*) as total_players, AVG({elo_field}) as avg_elo, MAX({elo_field}) as max_elo, MIN({elo_field}) as min_elo FROM players"
)
stats = await cursor.fetchone()
if not players:
await ctx.send("📝 No players found in the database!")
return
# Create leaderboard embed
embed = discord.Embed(
title=f"🏆 HOI4 {game_type.title()} Leaderboard",
color=discord.Color.gold()
)
# Add statistics
embed.description = f"**Total Players:** {stats['total_players']} | **Average ELO:** {stats['avg_elo']:.0f}"
leaderboard_text = ""
medals = ["🥇", "🥈", "🥉"]
for i, player in enumerate(players, 1):
# Get medal or rank number
if i <= 3:
rank_indicator = medals[i-1]
else:
rank_indicator = f"**{i}.**"
elo_value = player[elo_field]
username = player['username']
# Get additional player stats
async with db_pool.acquire() as conn:
async with conn.cursor(aiomysql.DictCursor) as cursor:
# Count games played
await cursor.execute(
"SELECT COUNT(*) as games_played, SUM(won) as games_won FROM game_results WHERE discord_id = %s",
(player['discord_id'],)
)
player_stats = await cursor.fetchone()
games_played = player_stats['games_played'] or 0
games_won = player_stats['games_won'] or 0
win_rate = (games_won / games_played * 100) if games_played > 0 else 0
leaderboard_text += f"{rank_indicator} **{username}** - {elo_value} ELO\n"
leaderboard_text += f" 📊 {games_played} games | {win_rate:.1f}% win rate\n\n"
embed.add_field(
name="Rankings",
value=leaderboard_text,
inline=False
)
embed.set_footer(text=f"ELO Range: {stats['min_elo']:.0f} - {stats['max_elo']:.0f}")
await ctx.send(embed=embed)
except Exception as e:
await ctx.send(f"❌ Error getting leaderboard: {str(e)}")
@bot.event
async def on_command_error(ctx, error):
"""Handles command errors"""