modified: app.py
This commit is contained in:
138
app.py
138
app.py
@@ -464,11 +464,22 @@ async def init_database():
|
|||||||
status VARCHAR(50) DEFAULT 'setup',
|
status VARCHAR(50) DEFAULT 'setup',
|
||||||
players JSON NOT NULL,
|
players JSON NOT NULL,
|
||||||
winner_team VARCHAR(255),
|
winner_team VARCHAR(255),
|
||||||
|
notification_message_id BIGINT NULL,
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
finished_at TIMESTAMP NULL
|
finished_at TIMESTAMP NULL
|
||||||
)
|
)
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
# Add notification_message_id column if it doesn't exist (for existing databases)
|
||||||
|
try:
|
||||||
|
await cursor.execute('''
|
||||||
|
ALTER TABLE games
|
||||||
|
ADD COLUMN notification_message_id BIGINT NULL
|
||||||
|
''')
|
||||||
|
except:
|
||||||
|
# Column already exists, ignore error
|
||||||
|
pass
|
||||||
|
|
||||||
# Create game_results table (MySQL syntax)
|
# Create game_results table (MySQL syntax)
|
||||||
await cursor.execute('''
|
await cursor.execute('''
|
||||||
CREATE TABLE IF NOT EXISTS game_results (
|
CREATE TABLE IF NOT EXISTS game_results (
|
||||||
@@ -622,6 +633,88 @@ async def reload_bot(ctx):
|
|||||||
)
|
)
|
||||||
await ctx.send(embed=embed)
|
await ctx.send(embed=embed)
|
||||||
|
|
||||||
|
# Game notification channel
|
||||||
|
GAME_NOTIFICATION_CHANNEL_ID = 1432368177685332030
|
||||||
|
|
||||||
|
async def create_game_notification_embed(game_data: Dict, players_data: List[Dict]) -> discord.Embed:
|
||||||
|
"""Create an embed for game notifications"""
|
||||||
|
embed = discord.Embed(
|
||||||
|
title=f"🎮 {game_data['game_name']}",
|
||||||
|
description=f"**Type:** {game_data['game_type'].title()}\n**Status:** Setup Phase",
|
||||||
|
color=discord.Color.blue()
|
||||||
|
)
|
||||||
|
|
||||||
|
if not players_data:
|
||||||
|
embed.add_field(name="Players", value="No players yet", inline=False)
|
||||||
|
return embed
|
||||||
|
|
||||||
|
# Group players by team
|
||||||
|
teams = {}
|
||||||
|
for p in players_data:
|
||||||
|
team = p['team_name']
|
||||||
|
if team not in teams:
|
||||||
|
teams[team] = []
|
||||||
|
teams[team].append(p)
|
||||||
|
|
||||||
|
# Add team fields
|
||||||
|
for team_name, members in teams.items():
|
||||||
|
team_emoji = "🎖️" # Simple fallback since we don't have ctx here
|
||||||
|
avg_elo = sum(m['current_elo'] for m in members) / len(members) if members else 0
|
||||||
|
|
||||||
|
field_name = f"{team_emoji} {team_name} (avg {avg_elo:.0f})"
|
||||||
|
|
||||||
|
lines = []
|
||||||
|
for m in sorted(members, key=lambda mm: (-mm.get('t_level', 2), mm['username'])):
|
||||||
|
t_level = m.get('t_level', 2)
|
||||||
|
t_emoji = {1: "🔹", 2: "🔸", 3: "🔺"}.get(t_level, "🔹")
|
||||||
|
|
||||||
|
country = m.get('country')
|
||||||
|
country_text = f" [{country}]" if country else ""
|
||||||
|
|
||||||
|
lines.append(f"{t_emoji} {m['username']}{country_text} ({m['current_elo']})")
|
||||||
|
|
||||||
|
embed.add_field(name=field_name, value="\n".join(lines), inline=True)
|
||||||
|
|
||||||
|
embed.set_footer(text=f"Players: {len(players_data)} | Teams: {len(teams)}")
|
||||||
|
return embed
|
||||||
|
|
||||||
|
async def update_game_notification(game_data: Dict, players_data: List[Dict]):
|
||||||
|
"""Update or create game notification in the notification channel"""
|
||||||
|
try:
|
||||||
|
channel = bot.get_channel(GAME_NOTIFICATION_CHANNEL_ID)
|
||||||
|
if not channel:
|
||||||
|
return
|
||||||
|
|
||||||
|
embed = await create_game_notification_embed(game_data, players_data)
|
||||||
|
|
||||||
|
if game_data.get('notification_message_id'):
|
||||||
|
# Try to edit existing message
|
||||||
|
try:
|
||||||
|
message = await channel.fetch_message(game_data['notification_message_id'])
|
||||||
|
await message.edit(embed=embed)
|
||||||
|
except (discord.NotFound, discord.HTTPException):
|
||||||
|
# Message not found, create new one
|
||||||
|
message = await channel.send(embed=embed)
|
||||||
|
# Update DB with new message ID
|
||||||
|
async with db_pool.acquire() as conn:
|
||||||
|
async with conn.cursor() as cursor:
|
||||||
|
await cursor.execute(
|
||||||
|
"UPDATE games SET notification_message_id = %s WHERE id = %s",
|
||||||
|
(message.id, game_data['id'])
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# Create new message
|
||||||
|
message = await channel.send(embed=embed)
|
||||||
|
# Store message ID in database
|
||||||
|
async with db_pool.acquire() as conn:
|
||||||
|
async with conn.cursor() as cursor:
|
||||||
|
await cursor.execute(
|
||||||
|
"UPDATE games SET notification_message_id = %s WHERE id = %s",
|
||||||
|
(message.id, game_data['id'])
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logging.warning(f"Failed to update game notification: {e}")
|
||||||
|
|
||||||
# HOI4 ELO Commands
|
# HOI4 ELO Commands
|
||||||
@bot.hybrid_command(name='hoi4create', description='Create a new HOI4 game')
|
@bot.hybrid_command(name='hoi4create', description='Create a new HOI4 game')
|
||||||
async def hoi4create(ctx, game_type: str, game_name: str):
|
async def hoi4create(ctx, game_type: str, game_name: str):
|
||||||
@@ -649,6 +742,13 @@ async def hoi4create(ctx, game_type: str, game_name: str):
|
|||||||
"INSERT INTO games (game_name, game_type, status, players) VALUES (%s, %s, 'setup', %s)",
|
"INSERT INTO games (game_name, game_type, status, players) VALUES (%s, %s, 'setup', %s)",
|
||||||
(game_name, game_type.lower(), '[]')
|
(game_name, game_type.lower(), '[]')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Get the created game data for notification
|
||||||
|
await cursor.execute(
|
||||||
|
"SELECT * FROM games WHERE game_name = %s AND game_type = %s ORDER BY id DESC LIMIT 1",
|
||||||
|
(game_name, game_type.lower())
|
||||||
|
)
|
||||||
|
game_data = await cursor.fetchone()
|
||||||
|
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
title="🎮 Game Created",
|
title="🎮 Game Created",
|
||||||
@@ -662,6 +762,10 @@ async def hoi4create(ctx, game_type: str, game_name: str):
|
|||||||
|
|
||||||
await ctx.send(embed=embed)
|
await ctx.send(embed=embed)
|
||||||
|
|
||||||
|
# Create notification in notification channel
|
||||||
|
if game_data:
|
||||||
|
await update_game_notification(dict(game_data), [])
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
await ctx.send(f"❌ Error creating game: {str(e)}")
|
await ctx.send(f"❌ Error creating game: {str(e)}")
|
||||||
|
|
||||||
@@ -754,6 +858,9 @@ async def hoi4remove(ctx, game_name: str, user: discord.Member):
|
|||||||
|
|
||||||
await ctx.send(embed=embed)
|
await ctx.send(embed=embed)
|
||||||
|
|
||||||
|
# Update notification in notification channel
|
||||||
|
await update_game_notification(dict(game), new_players)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
await ctx.send(f"❌ Error removing player: {str(e)}")
|
await ctx.send(f"❌ Error removing player: {str(e)}")
|
||||||
|
|
||||||
@@ -841,6 +948,9 @@ async def hoi4setup(ctx, game_name: str, user: discord.Member, team_name: str, t
|
|||||||
|
|
||||||
await ctx.send(embed=embed)
|
await ctx.send(embed=embed)
|
||||||
|
|
||||||
|
# Update notification in notification channel
|
||||||
|
await update_game_notification(dict(game), players)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
await ctx.send(f"❌ Error adding player: {str(e)}")
|
await ctx.send(f"❌ Error adding player: {str(e)}")
|
||||||
|
|
||||||
@@ -1036,6 +1146,34 @@ async def hoi4end(ctx, game_name: str, winner_team: str):
|
|||||||
|
|
||||||
await ctx.send(embed=embed)
|
await ctx.send(embed=embed)
|
||||||
|
|
||||||
|
# Post final game result to notification channel
|
||||||
|
try:
|
||||||
|
channel = bot.get_channel(GAME_NOTIFICATION_CHANNEL_ID)
|
||||||
|
if channel:
|
||||||
|
final_embed = discord.Embed(
|
||||||
|
title=f"🏁 Game Finished: {game_name}",
|
||||||
|
description=f"**Result:** {'Draw' if is_draw else f'{winner_team} Victory'}",
|
||||||
|
color=discord.Color.gold() if not is_draw else discord.Color.orange()
|
||||||
|
)
|
||||||
|
|
||||||
|
final_embed.add_field(name="Game Type", value=game['game_type'].title(), inline=True)
|
||||||
|
final_embed.add_field(name="Players", value=len(players), inline=True)
|
||||||
|
final_embed.add_field(name="Teams", value=len(teams), inline=True)
|
||||||
|
|
||||||
|
# Add team results
|
||||||
|
for team, team_changes in teams_results.items():
|
||||||
|
avg_change = sum(c['elo_change'] for c in team_changes) / len(team_changes)
|
||||||
|
emoji = "🏆" if team == winner_team and not is_draw else "🤝" if is_draw else "💔"
|
||||||
|
final_embed.add_field(
|
||||||
|
name=f"{emoji} {team}",
|
||||||
|
value=f"{len(team_changes)} players\nAvg ELO change: {avg_change:+.1f}",
|
||||||
|
inline=True
|
||||||
|
)
|
||||||
|
|
||||||
|
await channel.send(embed=final_embed)
|
||||||
|
except Exception as e:
|
||||||
|
logging.warning(f"Failed to post final game notification: {e}")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
await ctx.send(f"❌ Error ending game: {str(e)}")
|
await ctx.send(f"❌ Error ending game: {str(e)}")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user