modified: app.py
new file: emotes.markdown new file: tags.txt
This commit is contained in:
156
app.py
156
app.py
@@ -151,6 +151,21 @@ def find_custom_emoji(ctx: commands.Context, keyword_variants: List[str]) -> Opt
|
|||||||
return str(e)
|
return str(e)
|
||||||
except Exception:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
|
# Fallback to markdown-defined emojis if available
|
||||||
|
try:
|
||||||
|
if EMOTE_MAP:
|
||||||
|
for kw in keyword_variants:
|
||||||
|
key = kw.lower()
|
||||||
|
# Exact name match
|
||||||
|
if key in EMOTE_MAP:
|
||||||
|
return EMOTE_MAP[key]
|
||||||
|
# Substring match
|
||||||
|
for name_lower, mention in EMOTE_MAP.items():
|
||||||
|
if key in name_lower:
|
||||||
|
return mention
|
||||||
|
except NameError:
|
||||||
|
# EMOTE_MAP not defined yet
|
||||||
|
pass
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_t_emoji(ctx: commands.Context, t_level: int) -> str:
|
def get_t_emoji(ctx: commands.Context, t_level: int) -> str:
|
||||||
@@ -180,8 +195,128 @@ def get_team_emoji(ctx: commands.Context, team_name: str) -> str:
|
|||||||
return custom or "🔴"
|
return custom or "🔴"
|
||||||
# Generic HOI4 emoji or fallback
|
# Generic HOI4 emoji or fallback
|
||||||
custom = find_custom_emoji(ctx, ["hoi4", "hearts_of_iron", "iron"])
|
custom = find_custom_emoji(ctx, ["hoi4", "hearts_of_iron", "iron"])
|
||||||
|
if not custom:
|
||||||
|
custom = find_custom_emoji(ctx, ["eagle_hoi", "peace_hoi", "navy_hoi", "secretweapon_hoi"])
|
||||||
return custom or "🎖️"
|
return custom or "🎖️"
|
||||||
|
|
||||||
|
def _flag_from_iso2(code: str) -> Optional[str]:
|
||||||
|
"""Return unicode flag from 2-letter ISO code (e.g., 'DE' -> 🇩🇪)."""
|
||||||
|
if not code or len(code) != 2:
|
||||||
|
return None
|
||||||
|
code = code.upper()
|
||||||
|
base = 0x1F1E6
|
||||||
|
try:
|
||||||
|
return chr(base + ord(code[0]) - ord('A')) + chr(base + ord(code[1]) - ord('A'))
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Emotes markdown loader and map
|
||||||
|
def load_emote_markdown(path: Optional[str] = None) -> Dict[str, str]:
|
||||||
|
"""Parse emotes.markdown and return a mapping of lowercased emoji names to their mention strings.
|
||||||
|
Expected line format: <:Name:123456789012345678>
|
||||||
|
Lines that don't match are ignored."""
|
||||||
|
if path is None:
|
||||||
|
base_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
path = os.path.join(base_dir, 'emotes.markdown')
|
||||||
|
mapping: Dict[str, str] = {}
|
||||||
|
try:
|
||||||
|
with open(path, 'r', encoding='utf-8') as f:
|
||||||
|
for raw in f:
|
||||||
|
line = raw.strip()
|
||||||
|
if not line or not line.startswith('<:') or ':' not in line[2:]:
|
||||||
|
continue
|
||||||
|
# Format is <:NAME:ID>
|
||||||
|
try:
|
||||||
|
inner = line[2:-1] if line.endswith('>') else line[2:]
|
||||||
|
name, emoji_id = inner.split(':', 1)
|
||||||
|
name = name.strip()
|
||||||
|
mention = f"<:{name}:{emoji_id.strip('>')}>"
|
||||||
|
mapping[name.lower()] = mention
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
except FileNotFoundError:
|
||||||
|
# Silent if not present
|
||||||
|
pass
|
||||||
|
except Exception as e:
|
||||||
|
print(f"⚠️ Failed to load emotes.markdown: {e}")
|
||||||
|
return mapping
|
||||||
|
|
||||||
|
# Load emotes mapping at import
|
||||||
|
EMOTE_MAP: Dict[str, str] = load_emote_markdown()
|
||||||
|
if EMOTE_MAP:
|
||||||
|
print(f"😀 Loaded {len(EMOTE_MAP)} custom emojis from emotes.markdown")
|
||||||
|
|
||||||
|
def load_country_tags(path: Optional[str] = None) -> Dict[str, str]:
|
||||||
|
"""Load HOI4 country tags mapping from tags.txt.
|
||||||
|
Supported formats per line:
|
||||||
|
TAG=Country Name | TAG:Country Name | TAG,Country Name | TAG Country Name
|
||||||
|
Lines starting with # are ignored.
|
||||||
|
Returns dict like { 'GER': 'Germany', ... }"""
|
||||||
|
if path is None:
|
||||||
|
base_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
path = os.path.join(base_dir, 'tags.txt')
|
||||||
|
mapping: Dict[str, str] = {}
|
||||||
|
try:
|
||||||
|
with open(path, 'r', encoding='utf-8') as f:
|
||||||
|
for raw in f:
|
||||||
|
line = raw.strip()
|
||||||
|
if not line or line.startswith('#'):
|
||||||
|
continue
|
||||||
|
tag = None
|
||||||
|
name = None
|
||||||
|
for sep in ['=', ';', ',', ':']:
|
||||||
|
if sep in line:
|
||||||
|
left, right = line.split(sep, 1)
|
||||||
|
tag = left.strip().upper()
|
||||||
|
name = right.strip()
|
||||||
|
break
|
||||||
|
if tag is None:
|
||||||
|
parts = line.split(None, 1)
|
||||||
|
if len(parts) == 2:
|
||||||
|
tag = parts[0].strip().upper()
|
||||||
|
name = parts[1].strip()
|
||||||
|
else:
|
||||||
|
tag = line.strip().upper()
|
||||||
|
name = line.strip()
|
||||||
|
if tag and name:
|
||||||
|
mapping[tag] = name
|
||||||
|
except FileNotFoundError:
|
||||||
|
print("ℹ️ tags.txt not found; proceeding without country tag labels")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"⚠️ Failed to load tags.txt: {e}")
|
||||||
|
return mapping
|
||||||
|
|
||||||
|
# Loaded at import
|
||||||
|
COUNTRY_TAGS: Dict[str, str] = load_country_tags()
|
||||||
|
if COUNTRY_TAGS:
|
||||||
|
print(f"🗺️ Loaded {len(COUNTRY_TAGS)} HOI4 country tags")
|
||||||
|
|
||||||
|
def get_country_label(country_tag: Optional[str]) -> Optional[str]:
|
||||||
|
"""Return a display label like "[GER] Germany" if known, or "[GER]" if unknown."""
|
||||||
|
if not country_tag:
|
||||||
|
return None
|
||||||
|
tag = country_tag.strip().upper()
|
||||||
|
name = COUNTRY_TAGS.get(tag)
|
||||||
|
return f"[{tag}] {name}" if name else f"[{tag}]"
|
||||||
|
|
||||||
|
def get_country_emoji(ctx: commands.Context, country: Optional[str]) -> str:
|
||||||
|
"""Prefer custom emoji matching the HOI4 tag (e.g., ger, hoi4_ger). If parameter is ISO2, show unicode flag. Else empty."""
|
||||||
|
if not country:
|
||||||
|
return ""
|
||||||
|
c = country.strip()
|
||||||
|
# Try custom emoji lookups using tag variants
|
||||||
|
variants = [c, c.lower(), f"hoi4_{c.lower()}", f"country_{c.lower()}"]
|
||||||
|
custom = find_custom_emoji(ctx, variants)
|
||||||
|
if custom:
|
||||||
|
return custom
|
||||||
|
# If user passed ISO2, render unicode flag
|
||||||
|
if len(c) == 2:
|
||||||
|
flag = _flag_from_iso2(c)
|
||||||
|
if flag:
|
||||||
|
return flag
|
||||||
|
# Otherwise, no emoji fallback to avoid noisy globes
|
||||||
|
return ""
|
||||||
|
|
||||||
# Database Functions
|
# Database Functions
|
||||||
# Database Functions
|
# Database Functions
|
||||||
async def init_database():
|
async def init_database():
|
||||||
@@ -433,7 +568,7 @@ async def hoi4create(ctx, game_type: str, game_name: str):
|
|||||||
await ctx.send(f"❌ Error creating game: {str(e)}")
|
await ctx.send(f"❌ Error creating game: {str(e)}")
|
||||||
|
|
||||||
@bot.hybrid_command(name='hoi4setup', description='Add a player to an existing game')
|
@bot.hybrid_command(name='hoi4setup', description='Add a player to an existing game')
|
||||||
async def hoi4setup(ctx, game_name: str, user: discord.Member, team_name: str, t_level: int):
|
async def hoi4setup(ctx, game_name: str, user: discord.Member, team_name: str, t_level: int, country: Optional[str] = None):
|
||||||
"""Add a player to an existing game"""
|
"""Add a player to an existing game"""
|
||||||
if t_level not in [1, 2, 3]:
|
if t_level not in [1, 2, 3]:
|
||||||
await ctx.send("❌ T-Level must be 1, 2, or 3")
|
await ctx.send("❌ T-Level must be 1, 2, or 3")
|
||||||
@@ -471,7 +606,8 @@ async def hoi4setup(ctx, game_name: str, user: discord.Member, team_name: str, t
|
|||||||
'username': user.display_name,
|
'username': user.display_name,
|
||||||
'team_name': team_name,
|
'team_name': team_name,
|
||||||
't_level': t_level,
|
't_level': t_level,
|
||||||
'current_elo': player[f"{game['game_type']}_elo"]
|
'current_elo': player[f"{game['game_type']}_elo"],
|
||||||
|
'country': country.strip() if country else None
|
||||||
}
|
}
|
||||||
players.append(player_data)
|
players.append(player_data)
|
||||||
|
|
||||||
@@ -490,6 +626,11 @@ async def hoi4setup(ctx, game_name: str, user: discord.Member, team_name: str, t
|
|||||||
embed.add_field(name="Team", value=team_name, inline=True)
|
embed.add_field(name="Team", value=team_name, inline=True)
|
||||||
embed.add_field(name="T-Level", value=f"T{t_level}", inline=True)
|
embed.add_field(name="T-Level", value=f"T{t_level}", inline=True)
|
||||||
embed.add_field(name="Current ELO", value=player[f"{game['game_type']}_elo"], inline=True)
|
embed.add_field(name="Current ELO", value=player[f"{game['game_type']}_elo"], inline=True)
|
||||||
|
if country:
|
||||||
|
flag = get_country_emoji(ctx, country)
|
||||||
|
label = get_country_label(country)
|
||||||
|
value = f"{flag} {label}".strip()
|
||||||
|
embed.add_field(name="Country", value=value, inline=True)
|
||||||
embed.add_field(name="Players in Game", value=len(players), inline=True)
|
embed.add_field(name="Players in Game", value=len(players), inline=True)
|
||||||
|
|
||||||
await ctx.send(embed=embed)
|
await ctx.send(embed=embed)
|
||||||
@@ -851,7 +992,16 @@ async def hoi4games(ctx):
|
|||||||
lines = []
|
lines = []
|
||||||
for m in sorted(members, key=lambda mm: (-mm.get('t_level', 2), mm['username'].lower())):
|
for m in sorted(members, key=lambda mm: (-mm.get('t_level', 2), mm['username'].lower())):
|
||||||
te = get_t_emoji(ctx, int(m.get('t_level', 2)))
|
te = get_t_emoji(ctx, int(m.get('t_level', 2)))
|
||||||
lines.append(f"{te} {m['username']} ({m['current_elo']})")
|
ctry = m.get('country')
|
||||||
|
flag = get_country_emoji(ctx, ctry) if ctry else ""
|
||||||
|
label = get_country_label(ctry) if ctry else None
|
||||||
|
parts = [te]
|
||||||
|
if flag:
|
||||||
|
parts.append(flag)
|
||||||
|
if label:
|
||||||
|
parts.append(label)
|
||||||
|
parts.append(m['username'])
|
||||||
|
lines.append(f"{' '.join(parts)} ({m['current_elo']})")
|
||||||
value = "\n".join(lines) if lines else "No players yet"
|
value = "\n".join(lines) if lines else "No players yet"
|
||||||
# Discord field value max ~1024 chars; trim if necessary
|
# Discord field value max ~1024 chars; trim if necessary
|
||||||
if len(value) > 1000:
|
if len(value) > 1000:
|
||||||
|
|||||||
30
emotes.markdown
Normal file
30
emotes.markdown
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<:Civilian_Economy:1432372408941154325>
|
||||||
|
<:Disarmed_Nation:1432372405669724362>
|
||||||
|
<:Anarchism:1432372205647298672>
|
||||||
|
<:Communism:1432372203860525149>
|
||||||
|
<:Communism:1432372203860525149>
|
||||||
|
<:Democracy:1432372201943994368>
|
||||||
|
<:Fascism:1432372200756740281>
|
||||||
|
<:Neutrality:1432372199469355039>
|
||||||
|
<:Unknown_Ideology:1432372192879972353>
|
||||||
|
<:Nuclear_Strike:1432371908615213148>
|
||||||
|
<:Construction:1432371608806490132>
|
||||||
|
<:Decision:1432371606537109576>
|
||||||
|
<:Deployment:1432371605065044029>
|
||||||
|
<:Diplomacy:1432371603911606315>
|
||||||
|
<:Intelligence:1432371602531680337>
|
||||||
|
<:Logistics:1432371601168535582>
|
||||||
|
<:Production:1432371599524495540>
|
||||||
|
<:Research:1432371597989380258>
|
||||||
|
<:Trade:1432371596558991412>
|
||||||
|
<:navy_hoi:1432370988426985642>
|
||||||
|
<:peace_hoi:1432370987076423780>
|
||||||
|
<:secretweapon_hoi:1432370981607051397>
|
||||||
|
<:Eagle_hoi:1432370708771770509>
|
||||||
|
<:Cadet_hoi:1432370649053270140>
|
||||||
|
<:FreshRecruit:1432370967652335736>
|
||||||
|
<:ExperiencedRegular:1432370968818352191>
|
||||||
|
<:HardenedVeteran:1432370970135625748>
|
||||||
|
<:SkilledCaptain:1432370971792117810>
|
||||||
|
<:CommanderinChief:1432370973176238161>
|
||||||
|
<:WarHero:1432370974212489226>
|
||||||
105
tags.txt
Normal file
105
tags.txt
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
Kingdom of Afghanistan AFG
|
||||||
|
Albanian Kingdom ALB
|
||||||
|
Argentina ARG
|
||||||
|
Sultanate of Aussa AFA
|
||||||
|
Australia AST
|
||||||
|
Austria AUS
|
||||||
|
Belgian Congo COG
|
||||||
|
Belgium BEL
|
||||||
|
Bhutan BHU
|
||||||
|
Bolivian Republic BOL
|
||||||
|
Second Brazilian Republic BRA
|
||||||
|
British Burma BRM
|
||||||
|
British Malaya MAL
|
||||||
|
British Raj RAJ
|
||||||
|
Bulgaria BUL
|
||||||
|
BUZ
|
||||||
|
BUF
|
||||||
|
Dominion of Canada CAN
|
||||||
|
Chile CHL
|
||||||
|
China CHI
|
||||||
|
Colombia COL
|
||||||
|
Communist China PRC
|
||||||
|
Costa Rica COS
|
||||||
|
Cuba CUB
|
||||||
|
Czechoslovakia CZE
|
||||||
|
Denmark DEN
|
||||||
|
Dominican Republic DOM
|
||||||
|
Dutch East Indies INS
|
||||||
|
Ecuador ECU
|
||||||
|
El Salvador ELS
|
||||||
|
Estonia EST
|
||||||
|
Ethiopia ETH
|
||||||
|
Finland FIN
|
||||||
|
France FRA
|
||||||
|
VIC
|
||||||
|
German Reich GER
|
||||||
|
Kingdom of Greece GRE
|
||||||
|
Guangxi Clique GXC
|
||||||
|
Guatemala GUA
|
||||||
|
Haiti HAI
|
||||||
|
Honduras HON
|
||||||
|
Kingdom of Hungary HUN
|
||||||
|
Iceland ICE
|
||||||
|
Iran PER
|
||||||
|
Iraq IRQ
|
||||||
|
Ireland IRE
|
||||||
|
Italy ITA
|
||||||
|
RSI
|
||||||
|
RDS
|
||||||
|
Japan JAP
|
||||||
|
Sheikhdom of Kuwait KUW
|
||||||
|
Latvia LAT
|
||||||
|
Lebanese Republic LEB
|
||||||
|
Liberia LIB
|
||||||
|
Lithuania LIT
|
||||||
|
Luxembourg LUX
|
||||||
|
Manchukuo MAN
|
||||||
|
Mengkukuo MEN
|
||||||
|
Mexico MEX
|
||||||
|
Mongolian People's Republic MON
|
||||||
|
Sultanate of Muscat and Oman OMA
|
||||||
|
Nepal NEP
|
||||||
|
Netherlands HOL
|
||||||
|
New Zealand NZL
|
||||||
|
Nicaragua NIC
|
||||||
|
Norway NOR
|
||||||
|
Mandatory Palestine PAL
|
||||||
|
Panama PAN
|
||||||
|
Republic of Paraguay PAR
|
||||||
|
Peru PRU
|
||||||
|
Philippines PHI
|
||||||
|
Poland POL
|
||||||
|
Portugal POR
|
||||||
|
Romania ROM
|
||||||
|
Saudi Arabia SAU
|
||||||
|
Shanxi SHX
|
||||||
|
Kingdom of Siam SIA
|
||||||
|
Sinkiang SIK
|
||||||
|
South Africa SAF
|
||||||
|
Soviet Union SOV
|
||||||
|
SOS
|
||||||
|
SOT
|
||||||
|
SOB
|
||||||
|
SOP
|
||||||
|
SOU
|
||||||
|
Spain SPR
|
||||||
|
SPA
|
||||||
|
SPB
|
||||||
|
SPC
|
||||||
|
SPD
|
||||||
|
Sweden SWE
|
||||||
|
Switzerland SWI
|
||||||
|
Republic of Syria SYR
|
||||||
|
Tannu Tuva TAN
|
||||||
|
Tibet TIB
|
||||||
|
Emirate of Transjordan JOR
|
||||||
|
Turkey TUR
|
||||||
|
United Kingdom ENG
|
||||||
|
United States USA
|
||||||
|
Uruguay URG
|
||||||
|
Venezuela VEN
|
||||||
|
Xibei San Ma XSM
|
||||||
|
Yemen YEM
|
||||||
|
Yugoslavia YUG
|
||||||
|
Yunnan YUN
|
||||||
Reference in New Issue
Block a user