| """ |
| Enhanced Emoji system for the bot. |
| Loads custom emojis from emojies.txt and provides UI emoji aliases with rich decorations. |
| """ |
|
|
| import os |
| from pathlib import Path |
| import re |
|
|
| import discord |
|
|
|
|
| |
| |
| |
|
|
| FALLBACK_EMOJIS: dict[str, str] = { |
| |
| "ok": "✅", "no": "❌", "warn": "⚠️", "globe": "🌐", "music": "🎛️", |
| "join": "✅", "leave": "👋", "play": "▶️", "pause": "⏸️", "resume": "▶️", |
| "skip": "⏭️", "stop": "⏹️", "queue": "🎵", "video": "🎬", |
| |
| |
| "mario": "🍄", "choose": "🤖", "coin": "🪙", "ping": "🏓", "roll": "🎲", |
| "menu": "📘", "stats": "📊", "members": "👥", "channels": "🧵", "roles": "🛡️", |
| "boost": "🚀", "user": "👤", "refresh": "🔄", "trivia": "🧠", "bot": "🤖", |
| |
| |
| "settings": "⚙️", "volume": "🔊", "shuffle": "🔀", "loop": "🔁", |
| "previous": "⏮️", "search": "🔎", "preview": "🎬", "stay_247": "♾️", "joystick": "🕹️", |
| |
| |
| "suggest": "💡", "economy": "💰", "gamehub": "🎮", "diamond": "💎", "star": "✅", |
| "catjam": "😺", "djpeepo": "🎧", "spotify": "🎵", "partytime": "🎉", "letsgo": "🚀", |
| |
| |
| "arrow_green": "<:animatedarrowgreen:1477261279428087979>", "arrow_pink": "✅", "arrow_blue": "🔵", "arrow_purple": "<:animatedarrowgreen:1477261279428087979>", |
| "arrow_orange": "🟠", "arrow_yellow": "<:animatedarrowyellow:1477261257592668271>", "shield": "🛡️", "gift": "🎁", "hype": "🔥", |
| |
| |
| "notebook": "📓", "ticket": "🎫", "verified": "✅", "error": "❌", "loading": "⏳", |
| |
| |
| "num_1": "1️⃣", "num_2": "2️⃣", "num_3": "3️⃣", "num_4": "4️⃣", "num_5": "5️⃣", |
| "num_6": "6️⃣", "num_7": "7️⃣", "num_8": "8️⃣", "num_9": "9️⃣", "num_10": "🔟", |
| |
| |
| "sparkle": "✨", "fire": "🔥", "heart": "✅", "purple_heart": "<:animatedarrowgreen:1477261279428087979>", "blue_heart": "🔵", |
| "green_heart": "<:animatedarrowgreen:1477261279428087979>", "yellow_heart": "<:animatedarrowyellow:1477261257592668271>", "orange_heart": "🟠", "pink_heart": "✅", |
| "crown": "👑", "trophy": "🏆", "medal": "🎖️", "ribbon": "🎀", "gem": "💎", |
| "crystal_ball": "🔮", "comet": "☄️", "star2": "✅", "star3": "✅", "dizzy": "💫", |
| "boom": "💥", "zap": "⚡", "warning": "⚠️", "information": "ℹ️", "question": "❓", |
| "exclamation": "❗", "white_check_mark": "✅", "x": "❌", "lock": "🔒", "unlock": "🔓", |
| "key": "🔑", "door": "🚪", "bell": "🔔", "megaphone": "📢", "speech": "💬", |
| "envelope": "✉️", "pencil": "📝", "book": "📖", "scroll": "📜", "page": "📄", |
| "folder": "📁", "file": "🗃️", "card_index": "📇", "clipboard": "📋", |
| |
| |
| "controller": "🎮", "dice": "🎲", "slots": "🎰", "8ball": "🎱", "bowling": "🎳", |
| "dart": "🎯", "video_game": "🕹️", "chess": "♟️", "jigsaw": "🧩", |
| |
| |
| "notes": "🎶", "musical_score": "🎼", "studio_microphone": "🎙️", "microphone": "🎤", |
| "headphones": "🎧", "radio": "📻", "saxophone": "🎷", "guitar": "🎸", "drum": "🥁", |
| |
| |
| "money_bag": "💰", "dollar": "💵", "yen": "💴", "euro": "💶", "pound": "💷", |
| "credit_card": "💳", "chart": "📈", "bank": "🏦", "atm": "🏧", "receipt": "🧾", |
| |
| |
| "line": "▬", "dash": "—", "dot": "•", "bullet": "•", "circle": "<:animatedarrowgreen:1477261279428087979>", |
| "square": "■", "diamond_shape": "◆", "triangle": "▲", "star_border": "✅", |
| } |
|
|
|
|
| |
| |
| |
|
|
| _EMOJI_FILES = ( |
| Path("emojies.txt"), |
| Path("bot/emojies.txt"), |
| Path(os.getenv("EMOJI_FILE_PATH", "/opt/bot/emojies.txt")) if os.getenv("EMOJI_FILE_PATH") else None, |
| ) |
| _EMOJI_FILES = tuple(p for p in _EMOJI_FILES if p is not None) |
| _EMOJI_ID_RE = re.compile(r"\d{6,}") |
| _EMOJI_TAG_RE = re.compile(r"^<(a?):([\w~]+):(\d{6,})>$") |
| _EMOJI_BOT: discord.Client | None = None |
| _DYNAMIC_EMOJI_MAP: dict[str, tuple[str, ...]] = { |
| "economy": ("coin", "money", "bank", "work", "daily", "rob", "gamble"), |
| "admin": ("shield", "hammer", "warn", "trash", "mute", "lock"), |
| "ai": ("robot", "brain", "sparkles", "setup", "speak"), |
| "music": ("musicbeat", "play", "pause", "skip", "stop", "queue", "loop"), |
| } |
|
|
|
|
| def _normalize_key(value: str) -> str: |
| return (value or "").strip().lower().replace(" ", "_") |
|
|
|
|
| def _sanitize_emoji_name(name: str) -> str: |
| cleaned = re.sub(r"[^A-Za-z0-9_]", "_", (name or "").strip()) |
| cleaned = re.sub(r"_+", "_", cleaned).strip("_") |
| if not cleaned: |
| return "emoji" |
| if len(cleaned) < 2: |
| return f"{cleaned}_x" |
| return cleaned[:32] |
|
|
|
|
| def set_emoji_bot(bot: discord.Client) -> None: |
| """Register bot/client instance for dynamic custom emoji lookup.""" |
| global _EMOJI_BOT |
| _EMOJI_BOT = bot |
|
|
|
|
| def _extract_emoji_id(value: str) -> int | None: |
| cleaned = (value or "").strip() |
| if not cleaned: |
| return None |
| if cleaned.isdigit(): |
| return int(cleaned) |
| match = _EMOJI_ID_RE.search(cleaned) |
| return int(match.group(0)) if match else None |
|
|
|
|
| def _format_custom_emoji(emoji_obj: discord.Emoji | discord.PartialEmoji) -> str: |
| prefix = "a" if emoji_obj.animated else "" |
| return f"<{prefix}:{emoji_obj.name}:{emoji_obj.id}>" |
|
|
|
|
| def _build_custom_emoji_code(name: str, emoji_id: int, animated: bool) -> str: |
| """Build a Discord custom emoji tag without relying on cache objects.""" |
| prefix = "a" if animated else "" |
| return f"<{prefix}:{name}:{emoji_id}>" |
|
|
|
|
| def _ensure_unescaped_emoji(value: str) -> str: |
| """Keep emoji tags raw so Discord can render them.""" |
| return value.replace("\\<", "<") |
|
|
|
|
| def resolve_emoji_value(value: str, fallback: str = "✨", *, bot: discord.Client | None = None) -> str: |
| """Resolve emoji config for display in embeds/messages. |
| |
| Returns the full custom emoji tag <:name:id> so Discord can render it. |
| Only falls back to unicode if the value is invalid or empty. |
| Custom emoji tags work in embed descriptions if the bot has access to the emoji. |
| """ |
| parsed = _parse_custom_emoji_config(value) |
| if parsed is not None: |
| config_name, emoji_id, animated = parsed |
| |
| return _ensure_unescaped_emoji(_build_custom_emoji_code(config_name, emoji_id, animated)) |
|
|
| emoji_id = _extract_emoji_id(value) |
| active_bot = bot or _EMOJI_BOT |
| if emoji_id is not None and active_bot is not None: |
| resolved = active_bot.get_emoji(emoji_id) |
| if resolved is not None: |
| return _ensure_unescaped_emoji(_format_custom_emoji(resolved)) |
| |
| return _ensure_unescaped_emoji(value or fallback) |
|
|
|
|
| def _parse_custom_emoji_config(value: str) -> tuple[str, int, bool] | None: |
| """Parse a custom emoji value and return (name, id, animated).""" |
| cleaned = (value or "").strip() |
| if not cleaned: |
| return None |
|
|
| match = _EMOJI_TAG_RE.fullmatch(cleaned) |
| if match: |
| return match.group(2), int(match.group(3)), bool(match.group(1)) |
|
|
| if cleaned.isdigit(): |
| return "emoji", int(cleaned), False |
|
|
| return None |
|
|
|
|
| def _parse_emoji_file() -> dict[str, str]: |
| """Parse emoji file and return name -> emoji mapping. |
| |
| Supports two formats: |
| - name=<:name:id> (full format) |
| - name=id (just the ID) |
| """ |
| parsed: dict[str, str] = {} |
|
|
| for file in _EMOJI_FILES: |
| if not file.is_file(): |
| continue |
|
|
| try: |
| raw = file.read_text(encoding="utf-8", errors="ignore") |
| except Exception: |
| continue |
|
|
| for line in raw.splitlines(): |
| line = line.strip() |
| |
| if not line or line.startswith("#"): |
| continue |
| |
| |
| if "=" in line: |
| name, value = line.split("=", 1) |
| key = _normalize_key(name) |
| value = value.strip() |
| |
| if key and value: |
| |
| if (value.startswith("<:") or value.startswith("<a:")) and value.endswith(">"): |
| cfg = _parse_custom_emoji_config(value) |
| if cfg is not None: |
| cfg_name, emoji_id, animated = cfg |
| parsed[key] = _build_custom_emoji_code( |
| _sanitize_emoji_name(cfg_name), emoji_id, animated |
| ) |
| else: |
| parsed[key] = value |
| elif value.isdigit(): |
| |
| parsed[key] = f"<:{_sanitize_emoji_name(name)}:{value}>" |
| else: |
| |
| parsed[key] = value |
|
|
| return parsed |
|
|
|
|
| |
| CUSTOM_EMOJIS: dict[str, str] = _parse_emoji_file() |
|
|
|
|
| |
| |
| |
|
|
| |
| _UI_ALIASES: dict[str, tuple[str, ...]] = { |
| |
| "ok": ("accountisconnected", "white_check_mark"), |
| "no": ("accountisnotconnected", "x"), |
| "warn": ("warning",), |
| "connected": ("accountisconnected", "accountisconnectedwhite"), |
| "disconnected": ("accountisnotconnected",), |
| |
| |
| "play": ("djpeepo", "letsgo", "partytime"), |
| "pause": ("spotifypause", "pause"), |
| "resume": ("djpeepo", "play"), |
| "skip": ("letsgo", "skip"), |
| "stop": ("stop", "soundmute"), |
| "queue": ("spotifyqueueadd", "queue"), |
| "shuffle": ("shuffle",), |
| "loop": ("loop",), |
| "previous": ("previous",), |
| "volume": ("soundwhite", "sounddark", "volume"), |
| "volume_mute": ("soundmutewhite", "soundmutedark"), |
| |
| |
| "music": ("spotify", "spotifymusicdisc", "listeningtomusic"), |
| "spotify": ("spotify", "spotify2", "spotify3"), |
| "spotify_download": ("spotifydownload",), |
| "spotify_added": ("spotifyadded",), |
| "spotify_remove": ("spotifyremove",), |
| "spotify_favorite": ("spotifyfavourite",), |
| "spotify_listening": ("spotifylistening",), |
| "music_note": ("excitedmusicnote", "wingedmusicnote"), |
| "music_beat": ("musicbeat",), |
| "boombox": ("_Boombox",), |
| |
| |
| "microphone": ("microphonewhite", "microphonedark"), |
| "microphone_mute": ("microphonemutewhite", "microphonemutedark"), |
| |
| |
| "settings": ("settingswhite", "settingsdark", "settings"), |
| "edit_profile": ("editprofilewhite", "editprofiledark"), |
| |
| |
| "arrow_green": ("animatedarrowgreen",), |
| "arrow_purple": ("animatedarrowpurple",), |
| "arrow_red": ("animatedarrowred",), |
| "arrow_white": ("animatedarrowwhite",), |
| "arrow_pink": ("animatedarrowpink", "animatedarrowpink2"), |
| "arrow_orange": ("animatedarroworange",), |
| "arrow_yellow": ("animatedarrowyellow",), |
| "arrow_blue": ("animatedarrowblue", "animatedarrowbluelite"), |
| |
| |
| "gamehub": ("xbox", "controller"), |
| "youtube": ("youtube",), |
| "cinema": ("cinema1", "cinema2", "cinema3"), |
| "chess": ("whiteking", "blackking"), |
| |
| |
| "catjam": ("catjam",), |
| "djpeepo": ("djpeepo",), |
| "partytime": ("partytime",), |
| "letsgo": ("letsgo", "letsgo2"), |
| "hype": ("hype",), |
| "cooked": ("cooked", "cooked2", "cookedsoldier"), |
| "gigachad": ("gigachad",), |
| "pepejam": ("pepejam",), |
| "pepe_guitar": ("pepeguitar",), |
| "therock": ("therock",), |
| "skull": ("skull",), |
| "lol": ("lol",), |
| "sus": ("sus",), |
| "uwu": ("uwu",), |
| "rip": ("rip",), |
| "crying": ("crying",), |
| "sad": ("sad",), |
| "bye": ("bye",), |
| "hi": ("hi",), |
| "slay": ("slay",), |
| "ahhhhh": ("ahhhhh",), |
| |
| |
| "bongo_cat": ("bongocatbmo", "whalebongocat", "rubberhosebongocat"), |
| "cat_happy": ("cathappy",), |
| "cat_sad": ("catsobbing", "catsob1", "catsob2"), |
| "cat_burning": ("catburning",), |
| "cat_pleading": ("catpleading",), |
| |
| |
| "diamond": ("diamond",), |
| "star": ("yellowstar",), |
| "crown": ("clovercrown",), |
| "shield": ("shield",), |
| "staff": ("staff",), |
| "owner": ("owner",), |
| "partner": ("partner",), |
| "boost": ("discordboost", "naboosticon"), |
| "developer": ("discorddeveloper",), |
| "bug_hunter": ("purplebughunter",), |
| "premium": ("whitepremium",), |
| "mod": ("modswordsids",), |
| "security": ("securityfilter",), |
| |
| |
| "notebook": ("notebook",), |
| "gift": ("redgift",), |
| "trash": ("trashcan",), |
| "info": ("info",), |
| "gg": ("gg",), |
| |
| |
| "economy": ("diamond", "nacashicon"), |
| "coin": ("naemeraldicon",), |
| |
| |
| "globe": ("globe",), |
| "join": ("accountisconnected",), |
| "leave": ("bye",), |
| "refresh": ("refresh",), |
| "search": ("search",), |
| "menu": ("notebook",), |
| "suggest": ("suggest",), |
| } |
|
|
|
|
| def _resolve_emoji(*candidates: str) -> str | None: |
| """Resolve emoji from custom emojis or return None.""" |
| for candidate in candidates: |
| key = _normalize_key(candidate) |
| if key in CUSTOM_EMOJIS: |
| return CUSTOM_EMOJIS[key] |
| return None |
|
|
|
|
| |
| |
| |
|
|
| |
| USE_UNICODE_EMOJIS = False |
|
|
|
|
| def _build_ui_emojis() -> dict[str, str]: |
| """Build the UI emojis dictionary.""" |
| emojis = {} |
| for name, aliases in _UI_ALIASES.items(): |
| if USE_UNICODE_EMOJIS: |
| emojis[name] = FALLBACK_EMOJIS.get(name, "✨") |
| else: |
| |
| custom = _resolve_emoji(*aliases) |
| emojis[name] = custom or FALLBACK_EMOJIS.get(name, "✨") |
| return emojis |
|
|
|
|
| UI_EMOJIS: dict[str, str] = _build_ui_emojis() |
|
|
|
|
| def ui(name: str) -> str: |
| """Get a UI emoji by name. |
| |
| Resolution order: |
| 1) Hardcoded custom key from `emojies.txt`. |
| 2) Alias definitions (custom match via _UI_ALIASES / UI_EMOJIS). |
| 3) Windows/Unicode fallback from FALLBACK_EMOJIS. |
| """ |
| key = _normalize_key(name) |
| |
| fallback = FALLBACK_EMOJIS.get(key, "✨") |
|
|
| |
| if not USE_UNICODE_EMOJIS: |
| if key in CUSTOM_EMOJIS: |
| return resolve_emoji_value(CUSTOM_EMOJIS[key], fallback) |
|
|
| |
| aliases = _UI_ALIASES.get(key, ()) |
| custom_alias = _resolve_emoji(*aliases) if aliases else None |
| if custom_alias: |
| return resolve_emoji_value(custom_alias, fallback) |
| |
| |
| if key in UI_EMOJIS: |
| return resolve_emoji_value(UI_EMOJIS[key], fallback) |
| |
| |
| return fallback |
|
|
|
|
| def custom_emoji(name: str) -> str | None: |
| """Get a custom emoji by name, returns None if not found.""" |
| key = _normalize_key(name) |
| return CUSTOM_EMOJIS.get(key) |
|
|
|
|
| def get_emoji(name: str, fallback: str = "✨") -> str: |
| """Get emoji by name with custom fallback.""" |
| result = ui(name) |
| return result if result != "✨" else fallback |
|
|
|
|
| def get_custom_emoji(category: str, fallback: str = "✨") -> str: |
| """Return a best-match custom emoji for a semantic category. |
| |
| Uses the loaded custom emoji map first, then live bot emoji cache, and finally |
| falls back to unicode defaults. |
| """ |
| category_key = _normalize_key(category) |
| category_keywords: dict[str, tuple[str, ...]] = { |
| "economy": ("coin", "money", "bank", "gem", "cash", "wallet"), |
| "admin": ("shield", "hammer", "ban", "mute", "mod", "security"), |
| "games": ("dice", "board", "crown", "chess", "controller", "game"), |
| } |
| keywords = category_keywords.get(category_key, (category_key,)) |
|
|
| for key, value in CUSTOM_EMOJIS.items(): |
| if any(word in key for word in keywords): |
| return resolve_emoji_value(value, fallback) |
|
|
| active_bot = _EMOJI_BOT |
| if active_bot is not None: |
| for emoji_obj in getattr(active_bot, "emojis", []): |
| name = _normalize_key(getattr(emoji_obj, "name", "")) |
| if any(word in name for word in keywords): |
| return resolve_emoji_value(_format_custom_emoji(emoji_obj), fallback, bot=active_bot) |
|
|
| fallback_map = { |
| "economy": "💰", |
| "admin": "🛡️", |
| "games": "🎲", |
| } |
| return fallback_map.get(category_key, fallback) |
|
|
|
|
| |
| |
| |
|
|
| COMMAND_EMOJIS: dict[str, str] = { |
| |
| "play": ui("play"), |
| "pause": ui("pause"), |
| "resume": ui("resume"), |
| "skip": ui("skip"), |
| "stop": ui("stop"), |
| "queue": ui("queue"), |
| "nowplaying": ui("music"), |
| "volume": ui("volume"), |
| "shuffle": ui("shuffle"), |
| "loop": ui("loop"), |
| "previous": ui("previous"), |
| "seek": "⏩", |
| "rewind": "⏪", |
| "forward": "⏩", |
| "filter": "🎛️", |
| "clear": ui("trash"), |
| "remove": ui("spotify_remove"), |
| "move": "↔️", |
| "autoplay": "🔄", |
| "disconnect": ui("disconnected"), |
| "join": ui("connected"), |
| "247": "♾️", |
| |
| |
| "ban": "🔨", |
| "kick": "👢", |
| "mute": "🔇", |
| "unmute": "🔊", |
| "warn": "⚠️", |
| "unwarn": "✅", |
| "clearwarns": "🧹", |
| "slowmode": "🐌", |
| "lock": "🔒", |
| "unlock": "🔓", |
| "purge": "🧹", |
| |
| |
| "setup": ui("settings"), |
| "config": ui("settings"), |
| "prefix": "📝", |
| "language": "🌐", |
| "dj": ui("djpeepo"), |
| "log": "📋", |
| |
| |
| "balance": ui("economy"), |
| "daily": "📅", |
| "work": "💼", |
| "rob": "🦹", |
| "give": "🎁", |
| "leaderboard": "🏆", |
| "shop": "🛒", |
| "buy": "🛒", |
| |
| |
| "8ball": "🎱", |
| "roll": "🎲", |
| "flip": "🪙", |
| "meme": "😂", |
| "joke": "😂", |
| "quote": "💬", |
| "fact": "📚", |
| |
| |
| "avatar": "👤", |
| "userinfo": "👤", |
| "serverinfo": "📊", |
| "ping": "🏓", |
| "help": "❓", |
| "invite": "📨", |
| "stats": "📈", |
| "uptime": "⏱️", |
| |
| |
| "ticket": "🎫", |
| "close": "❌", |
| "open": "✅", |
| |
| |
| "giveaway": "🎁", |
| "reroll": "🔄", |
| "end": "🛑", |
| } |
|
|
|
|
| def get_command_emoji(command_name: str) -> str: |
| """Get emoji for a specific command.""" |
| key = _normalize_key(command_name) |
| return COMMAND_EMOJIS.get(key, "✨") |
|
|
|
|
| |
| |
| |
|
|
| def decorative_emoji(index: int) -> str: |
| """Get a decorative emoji by index (cycles through available emojis).""" |
| values = list(CUSTOM_EMOJIS.values()) if CUSTOM_EMOJIS else list(FALLBACK_EMOJIS.values()) |
| if not values: |
| return "✨" |
| return values[index % len(values)] |
|
|
|
|
| def random_decorative_emoji() -> str: |
| """Get a random decorative emoji.""" |
| import random |
| values = list(CUSTOM_EMOJIS.values()) if CUSTOM_EMOJIS else list(FALLBACK_EMOJIS.values()) |
| return random.choice(values) if values else "✨" |
|
|
|
|
| def decorated_title(emoji: str, text: str) -> str: |
| """Create a beautifully decorated title with emoji and sparkle effects.""" |
| return f"✨ {emoji} **{text}** ✨" |
|
|
|
|
| def panel_header(emoji: str, title: str, subtitle: str = "") -> str: |
| """Create a rich panel header with decorations.""" |
| header = f"╔══════════════════════════════╗\n║ {emoji} **{title}**" |
| if subtitle: |
| header += f"\n║ {subtitle}" |
| header += "\n╚══════════════════════════════╝" |
| return header |
|
|
|
|
| def status_emoji(success: bool) -> str: |
| """Get appropriate status emoji.""" |
| return ui("ok") if success else ui("no") |
|
|
|
|
| def rank_badge(rank: int) -> str: |
| """Get rank badge emoji for leaderboards.""" |
| badges = { |
| 1: "🥇", |
| 2: "🥈", |
| 3: "🥉", |
| } |
| return badges.get(rank, f"#{rank}") |
|
|
|
|
| |
| |
| |
|
|
| |
| E_CATJAM = ui("catjam") |
| E_DIAMOND = ui("diamond") |
| E_STAR = ui("star") |
| E_SPOTIFY = ui("spotify") |
| E_PARTYTIME = ui("partytime") |
| E_LETSGO = ui("letsgo") |
| E_DJPEEPO = ui("djpeepo") |
| E_SHIELD = ui("shield") |
| E_GIFT = ui("gift") |
| E_HYPE = ui("hype") |
| E_NOTEBOOK = ui("notebook") |
| E_OK = ui("ok") |
| E_NO = ui("no") |
| E_WARN = ui("warn") |
| E_MUSIC = ui("music") |
| E_PLAY = ui("play") |
| E_PAUSE = ui("pause") |
| E_SKIP = ui("skip") |
| E_STOP = ui("stop") |
| E_QUEUE = ui("queue") |
| E_JOIN = ui("join") |
| E_LEAVE = ui("leave") |
| E_VOLUME = ui("volume") |
| E_SHUFFLE = ui("shuffle") |
| E_LOOP = ui("loop") |
| E_PREVIOUS = ui("previous") |
| E_SEARCH = ui("search") |
| E_PREVIEW = ui("preview") |
| E_STAY_247 = ui("stay_247") |
| E_ECONOMY = ui("economy") |
| E_GAMEHUB = ui("gamehub") |
|
|
| |
| E_ARROW_GREEN = ui("arrow_green") |
| E_ARROW_PINK = ui("arrow_pink") |
| E_ARROW_BLUE = ui("arrow_blue") |
| E_ARROW_PURPLE = ui("arrow_purple") |
| E_ARROW_ORANGE = ui("arrow_orange") |
| E_ARROW_YELLOW = ui("arrow_yellow") |
|
|
| |
| E_CROWN = "👑" |
| E_TROPHY = "🏆" |
| E_FIRE = "🔥" |
| E_SPARKLE = "✨" |
| E_GEM = "💎" |
| E_ROCKET = "🚀" |
| E_MONEY = "💰" |
| E_CHART = "📈" |
| E_TARGET = "🎯" |
| E_DICE = "🎲" |
| E_GIFT_BOX = "🎁" |
| E_LOCK = "🔒" |
| E_KEY = "🔑" |
| E_BELL = "🔔" |
| E_STAR2 = "✅" |
| E_DIZZY = "💫" |
| E_BOOM = "💥" |
| E_ZAP = "⚡" |
| E_HEART = "✅" |
| E_PURPLE_HEART = "<:animatedarrowgreen:1477261279428087979>" |
| E_BLUE_HEART = "💙" |
| E_GREEN_HEART = "<:animatedarrowgreen:1477261279428087979>" |
| E_YELLOW_HEART = "💛" |
|
|