From 82fd5449ae37155df23383c970c2d0d9bd38dc94 Mon Sep 17 00:00:00 2001 From: SimolZimol <70102430+SimolZimol@users.noreply.github.com> Date: Mon, 27 Oct 2025 16:23:40 +0100 Subject: [PATCH] modified: app.py new file: emotes.markdown new file: tags.txt --- app.py | 156 +++++++++++++++++++++++++++++++++++++++++++++++- emotes.markdown | 30 ++++++++++ tags.txt | 105 ++++++++++++++++++++++++++++++++ 3 files changed, 288 insertions(+), 3 deletions(-) create mode 100644 emotes.markdown create mode 100644 tags.txt diff --git a/app.py b/app.py index 5da088f..788ff56 100644 --- a/app.py +++ b/app.py @@ -151,6 +151,21 @@ def find_custom_emoji(ctx: commands.Context, keyword_variants: List[str]) -> Opt return str(e) except Exception: 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 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 "πŸ”΄" # Generic HOI4 emoji or fallback 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 "πŸŽ–οΈ" +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 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)}") @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""" if t_level not in [1, 2, 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, 'team_name': team_name, '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) @@ -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="T-Level", value=f"T{t_level}", 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) await ctx.send(embed=embed) @@ -851,7 +992,16 @@ async def hoi4games(ctx): lines = [] 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))) - 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" # Discord field value max ~1024 chars; trim if necessary if len(value) > 1000: diff --git a/emotes.markdown b/emotes.markdown new file mode 100644 index 0000000..5a139ce --- /dev/null +++ b/emotes.markdown @@ -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> \ No newline at end of file diff --git a/tags.txt b/tags.txt new file mode 100644 index 0000000..9e124bf --- /dev/null +++ b/tags.txt @@ -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