modified: app.py

This commit is contained in:
SimolZimol
2025-10-27 18:50:57 +01:00
parent fc9d58a03c
commit 16a2ba3b1f

106
app.py
View File

@@ -136,6 +136,81 @@ TEAM_EMOTE_OVERRIDES: Dict[str, str] = {
"default": "<:neutrality:1432391681059197102>",
}
# Role mapping for ELO tiers (IDs provided by user)
# Assumption: Top tier is >= 900 ELO rather than strictly >900,
# to avoid leaving 900 unassigned. Adjust if you want 900 handled differently.
STANDARD_ELO_ROLE_IDS = {
"gte_900": 1432368177014374497,
"851_899": 1432368177014374496,
"801_850": 1432368177014374495,
"eq_800": 1432368177014374494,
"751_799": 1432368177014374493,
"701_750": 1432368177014374492,
"lt_700": 1432368177014374491,
}
COMPETITIVE_ELO_ROLE_IDS = {
"gte_900": 1432368177030893672,
"851_899": 1432368177030893671,
"801_850": 1432368177030893670,
"eq_800": 1432368177030893669,
"751_799": 1432368177030893668,
"701_750": 1432368177014374499,
"lt_700": 1432368177014374498,
}
def _role_id_for_elo(elo: int, category: str) -> Optional[int]:
"""Return the role ID for the given ELO and category ('standard'|'competitive')."""
ids = STANDARD_ELO_ROLE_IDS if category == "standard" else COMPETITIVE_ELO_ROLE_IDS
if elo >= 900:
return ids["gte_900"]
if 851 <= elo <= 899:
return ids["851_899"]
if 801 <= elo <= 850:
return ids["801_850"]
if elo == 800:
return ids["eq_800"]
if 751 <= elo <= 799:
return ids["751_799"]
if 701 <= elo <= 750:
return ids["701_750"]
# < 700
return ids["lt_700"]
def _category_role_ids(category: str) -> List[int]:
ids = STANDARD_ELO_ROLE_IDS if category == "standard" else COMPETITIVE_ELO_ROLE_IDS
return list(ids.values())
async def update_member_elo_role(member: discord.Member, elo: int, category: str, reason: Optional[str] = None):
"""Ensure the member has exactly one rank role for the given category matching their ELO.
- category: 'standard' or 'competitive'
"""
if member is None or member.guild is None:
return
try:
guild = member.guild
target_role_id = _role_id_for_elo(elo, category)
if not target_role_id:
return
target_role = guild.get_role(int(target_role_id))
if not target_role:
return # Role not found in this guild
# Remove any other roles from the same category
category_ids = set(_category_role_ids(category))
roles_to_remove = [r for r in member.roles if r.id in category_ids and r.id != target_role.id]
if roles_to_remove:
await member.remove_roles(*roles_to_remove, reason=reason)
# Add the target role if missing
if target_role not in member.roles:
await member.add_roles(target_role, reason=reason)
except discord.Forbidden:
# Missing permissions or role hierarchy issue
logging.warning(f"Insufficient permissions to modify roles for {member} in category {category}")
except discord.HTTPException as e:
logging.warning(f"Failed to update roles for {member}: {e}")
# Emoji and formatting helpers
def _all_accessible_emojis(ctx: commands.Context) -> List[discord.Emoji]:
"""Return emojis from current guild plus all guilds the bot is in."""
@@ -777,6 +852,27 @@ async def hoi4end(ctx, game_name: str, winner_team: str):
"UPDATE games SET status = 'finished', winner_team = %s, finished_at = CURRENT_TIMESTAMP WHERE id = %s",
(final_result, game['id'])
)
# After DB updates, try to sync Discord roles for affected players (only for this game's category)
try:
guild = ctx.guild
if guild:
for change in elo_changes:
member = guild.get_member(change['discord_id'])
if member is None:
try:
member = await guild.fetch_member(change['discord_id'])
except Exception:
member = None
if member:
await update_member_elo_role(
member,
change['new_elo'],
game['game_type'],
reason=f"HOI4 {game['game_type']} ELO updated in '{game_name}'"
)
except Exception as e:
logging.warning(f"Role sync after game end failed: {e}")
# Create result embed
if is_draw:
@@ -963,6 +1059,16 @@ async def hoi4stats(ctx, user: Optional[discord.Member] = None):
)
await ctx.send(embed=embed)
# Try to keep user's roles in sync for both categories when stats are viewed
try:
if ctx.guild and isinstance(target_user, discord.Member):
await update_member_elo_role(
target_user, player['standard_elo'], 'standard', reason='HOI4 stats viewed: role sync')
await update_member_elo_role(
target_user, player['competitive_elo'], 'competitive', reason='HOI4 stats viewed: role sync')
except Exception as e:
logging.warning(f"Role sync on stats failed: {e}")
except Exception as e:
await ctx.send(f"❌ Error getting stats: {str(e)}")