1
0
forked from sass/tipibot

Compare commits

..

2 Commits

Author SHA1 Message Date
Rene Arumetsa
3939c879c9 Refacor emoijs to use application emoijs 2026-06-03 18:34:29 +03:00
Rene Arumetsa
b0e23c1a17 Change admin command permissions 2026-06-01 22:11:44 +03:00
9 changed files with 209 additions and 104 deletions

4
bot.py
View File

@@ -594,8 +594,12 @@ class HelpSelect(discord.ui.Select):
@tree.command(name="help", description=S.CMD["help"]) @tree.command(name="help", description=S.CMD["help"])
async def cmd_help(interaction: discord.Interaction): async def cmd_help(interaction: discord.Interaction):
<<<<<<< HEAD
is_admin = is_bot_admin(interaction.user)
=======
member = interaction.user member = interaction.user
is_admin = isinstance(member, discord.Member) and is_bot_admin(member) is_admin = isinstance(member, discord.Member) and is_bot_admin(member)
>>>>>>> 42f7bae68124fa6a9824780ba17b46d00f3f2b36
await interaction.response.send_message( await interaction.response.send_message(
embed=_help_embed("üldine"), view=HelpView(is_admin), ephemeral=True embed=_help_embed("üldine"), view=HelpView(is_admin), ephemeral=True
) )

View File

@@ -10,6 +10,7 @@ import discord
from discord import app_commands from discord import app_commands
from core import economy from core import economy
from core.emoji import EMOJI as E
import strings as S import strings as S
@@ -288,12 +289,12 @@ def register_economy_extra_commands(
# /jailbreak - Monopoly-style dice escape # /jailbreak - Monopoly-style dice escape
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
_DICE_EMOJI = [ _DICE_EMOJI = [
"<:TipiYKS:1483103190491856916>", E["TipiYKS"],
"<:TipiKAKS:1483103215841972404>", E["TipiKAKS"],
"<:TipiKOLM:1483103217846980781>", E["TipiKOLM"],
"<:TipiNELI:1483103237585240114>", E["TipiNELI"],
"<:TipiVIIS:1483103239036469289>", E["TipiVIIS"],
"<:TipiKUUS:1483103253163020348>", E["TipiKUUS"],
] ]
class JailbreakView(discord.ui.View): class JailbreakView(discord.ui.View):

View File

@@ -9,6 +9,7 @@ import discord
from discord import app_commands from discord import app_commands
from core import economy from core import economy
from core.emoji import EMOJI as E
import strings as S import strings as S
@@ -611,7 +612,7 @@ def register_economy_games_commands(
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
# /slots # /slots
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
_SLOTS_SPIN = "<a:TipiSLOTS:1483444233863037101>" _SLOTS_SPIN = E["TipiSLOTS"]
_SLOTS_DELAY = 0.7 _SLOTS_DELAY = 0.7
def _slots_embed( def _slots_embed(

View File

@@ -13,6 +13,7 @@ from pathlib import Path
import discord import discord
from discord import app_commands from discord import app_commands
from core.admin import bot_admin_check
import strings as S import strings as S
from core.admin import bot_admin_check from core.admin import bot_admin_check

View File

@@ -42,6 +42,23 @@ BIRTHDAY_CHANNEL_ID = (
BIRTHDAY_WINDOW_DAYS = int(os.getenv("BIRTHDAY_WINDOW_DAYS", "7")) BIRTHDAY_WINDOW_DAYS = int(os.getenv("BIRTHDAY_WINDOW_DAYS", "7"))
BASE_ROLE_IDS: list[int] = [1478304631930228779, 1478302278862766190] BASE_ROLE_IDS: list[int] = [1478304631930228779, 1478302278862766190]
def _parse_admin_roles(raw: str) -> dict[int, int]:
"""Parse BOT_ADMIN_ROLES env var as "guild_id:role_id,guild_id:role_id"."""
result: dict[int, int] = {}
for pair in raw.split(","):
pair = pair.strip()
if not pair:
continue
guild_str, _, role_str = pair.partition(":")
if not role_str:
raise SystemExit(f"BOT_ADMIN_ROLES: expected 'guild_id:role_id', got {pair!r}")
result[int(guild_str)] = int(role_str)
return result
BOT_ADMIN_ROLES: dict[int, int] = _parse_admin_roles(os.getenv("BOT_ADMIN_ROLES", ""))
PB_URL = os.getenv("PB_URL", "http://127.0.0.1:8090") PB_URL = os.getenv("PB_URL", "http://127.0.0.1:8090")
PB_ADMIN_EMAIL = os.getenv("PB_ADMIN_EMAIL", "") PB_ADMIN_EMAIL = os.getenv("PB_ADMIN_EMAIL", "")
PB_ADMIN_PASSWORD = os.getenv("PB_ADMIN_PASSWORD", "") PB_ADMIN_PASSWORD = os.getenv("PB_ADMIN_PASSWORD", "")

View File

@@ -6,8 +6,15 @@ from discord import app_commands
import config import config
<<<<<<< HEAD
def is_bot_admin(member: discord.abc.User | None) -> bool:
"""True when the member has the configured admin role for their guild."""
if not isinstance(member, discord.Member) or member.guild is None:
return False
=======
def is_bot_admin(member: discord.Member) -> bool: def is_bot_admin(member: discord.Member) -> bool:
"""Return True if the member has the configured bot-admin role for their guild.""" """Return True if the member has the configured bot-admin role for their guild."""
>>>>>>> 42f7bae68124fa6a9824780ba17b46d00f3f2b36
role_id = config.BOT_ADMIN_ROLES.get(member.guild.id) role_id = config.BOT_ADMIN_ROLES.get(member.guild.id)
if role_id is None: if role_id is None:
return False return False
@@ -15,6 +22,14 @@ def is_bot_admin(member: discord.Member) -> bool:
def bot_admin_check(): def bot_admin_check():
<<<<<<< HEAD
"""Slash-command decorator that gates execution behind ``is_bot_admin``."""
async def predicate(interaction: discord.Interaction) -> bool:
if is_bot_admin(interaction.user):
return True
raise app_commands.MissingPermissions(["bot_admin_role"])
=======
"""Slash-command check decorator: raises MissingPermissions if not a bot admin.""" """Slash-command check decorator: raises MissingPermissions if not a bot admin."""
def predicate(interaction: discord.Interaction) -> bool: def predicate(interaction: discord.Interaction) -> bool:
member = interaction.user member = interaction.user
@@ -23,5 +38,6 @@ def bot_admin_check():
if not is_bot_admin(member): if not is_bot_admin(member):
raise app_commands.MissingPermissions(["bot_admin"]) raise app_commands.MissingPermissions(["bot_admin"])
return True return True
>>>>>>> 42f7bae68124fa6a9824780ba17b46d00f3f2b36
return app_commands.check(predicate) return app_commands.check(predicate)

View File

@@ -17,6 +17,7 @@ import aiohttp
from . import pb_client from . import pb_client
from .pb_client import DatabaseError from .pb_client import DatabaseError
from .emoji import EMOJI as E
import strings import strings
@@ -29,13 +30,9 @@ def _txn(event: str, **fields) -> None:
_txn_log.info("%-16s %s", event, body) _txn_log.info("%-16s %s", event, body)
# --------------------------------------------------------------------------- # Per-profile emoji values live in core/emoji.py; add new IDs there.
# Emoji config COIN = E["TipiCOIN"]
# To use your custom Discord emoji replace COIN with the full tag, e.g.: PP_EMOJI = E["TipiFIRE"]
# COIN = "<:tipicoin:1234567890123456789>"
# ---------------------------------------------------------------------------
COIN = "<:TipiCOIN:1483000209188589628>"
PP_EMOJI = "<:TipiFIRE:1483431381668335687>"
PRESTIGE_ROLE = "TipiPRESTIGE" PRESTIGE_ROLE = "TipiPRESTIGE"
PRESTIGE_MIN_LEVEL = 30 # minimum level required to prestige PRESTIGE_MIN_LEVEL = 30 # minimum level required to prestige
@@ -52,99 +49,99 @@ class ShopItem(TypedDict):
SHOP: dict[str, ShopItem] = { SHOP: dict[str, ShopItem] = {
"gaming_hiir": { "gaming_hiir": {
"name": "Mängurihiir", "name": "Mängurihiir",
"emoji": "<:TipiHIIR:1483004306012504128>", "emoji": E["TipiHIIR"],
"cost": 500, "cost": 500,
"description": strings.ITEM_DESCRIPTIONS["gaming_hiir"], "description": strings.ITEM_DESCRIPTIONS["gaming_hiir"],
}, },
"hiirematt": { "hiirematt": {
"name": "Hiirematt", "name": "Hiirematt",
"emoji": "<:TipiMATT:1483387697132208128>", "emoji": E["TipiMATT"],
"cost": 600, "cost": 600,
"description": strings.ITEM_DESCRIPTIONS["hiirematt"], "description": strings.ITEM_DESCRIPTIONS["hiirematt"],
}, },
"korvaklapid": { "korvaklapid": {
"name": "K\u00f5rvaklapid", "name": "K\u00f5rvaklapid",
"emoji": "<:TipiKLAPID:1483387694083084349>", "emoji": E["TipiKLAPID"],
"cost": 1200, "cost": 1200,
"description": strings.ITEM_DESCRIPTIONS["korvaklapid"], "description": strings.ITEM_DESCRIPTIONS["korvaklapid"],
}, },
"lan_pass": { "lan_pass": {
"name": "LAN pilet", "name": "LAN pilet",
"emoji": "<:TipiPILET:1483004308353060904>", "emoji": E["TipiPILET"],
"cost": 1200, "cost": 1200,
"description": strings.ITEM_DESCRIPTIONS["lan_pass"], "description": strings.ITEM_DESCRIPTIONS["lan_pass"],
}, },
"energiajook": { "energiajook": {
"name": "Red Bull", "name": "Red Bull",
"emoji": "<:TipiBULL:1483004310924300409>", "emoji": E["TipiBULL"],
"cost": 800, "cost": 800,
"description": strings.ITEM_DESCRIPTIONS["energiajook"], "description": strings.ITEM_DESCRIPTIONS["energiajook"],
}, },
"gaming_laptop": { "gaming_laptop": {
"name": "Bot Farm", "name": "Bot Farm",
"emoji": "<:TipiLAP:1483004307161874566>", "emoji": E["TipiLAP"],
"cost": 1500, "cost": 1500,
"description": strings.ITEM_DESCRIPTIONS["gaming_laptop"], "description": strings.ITEM_DESCRIPTIONS["gaming_laptop"],
}, },
"anticheat": { "anticheat": {
"name": "Anticheat", "name": "Anticheat",
"emoji": "<:TipiVAC:1483004309510819860>", "emoji": E["TipiVAC"],
"cost": 1000, "cost": 1000,
"description": strings.ITEM_DESCRIPTIONS["anticheat"], "description": strings.ITEM_DESCRIPTIONS["anticheat"],
}, },
# ----- Tier 2 ----- # ----- Tier 2 -----
"reguleeritav_laud": { "reguleeritav_laud": {
"name": "Reguleeritav laud", "name": "Reguleeritav laud",
"emoji": "<:TipiLAUD:1483387695576125440>", "emoji": E["TipiLAUD"],
"cost": 3500, "cost": 3500,
"description": strings.ITEM_DESCRIPTIONS["reguleeritav_laud"], "description": strings.ITEM_DESCRIPTIONS["reguleeritav_laud"],
}, },
"jellyfin": { "jellyfin": {
"name": "Jellyfin server", "name": "Jellyfin server",
"emoji": "<:TipiSERVER:1483387701032910969>", "emoji": E["TipiSERVER"],
"cost": 4000, "cost": 4000,
"description": strings.ITEM_DESCRIPTIONS["jellyfin"], "description": strings.ITEM_DESCRIPTIONS["jellyfin"],
}, },
"mikrofon": { "mikrofon": {
"name": "Eraldiseisev mikrofon", "name": "Eraldiseisev mikrofon",
"emoji": "<:TipiMIC:1483387698499551313>", "emoji": E["TipiMIC"],
"cost": 2800, "cost": 2800,
"description": strings.ITEM_DESCRIPTIONS["mikrofon"], "description": strings.ITEM_DESCRIPTIONS["mikrofon"],
}, },
"klaviatuur": { "klaviatuur": {
"name": "Mehaaniline klaviatuur", "name": "Mehaaniline klaviatuur",
"emoji": "<:TipiKLAVA:1483014339228078140>", "emoji": E["TipiKLAVA"],
"cost": 1800, "cost": 1800,
"description": strings.ITEM_DESCRIPTIONS["klaviatuur"], "description": strings.ITEM_DESCRIPTIONS["klaviatuur"],
}, },
"monitor": { "monitor": {
"name": "Ultralai monitor", "name": "Ultralai monitor",
"emoji": "<:TipiMONITOR:1483014340327243908>", "emoji": E["TipiMONITOR"],
"cost": 2500, "cost": 2500,
"description": strings.ITEM_DESCRIPTIONS["monitor"], "description": strings.ITEM_DESCRIPTIONS["monitor"],
}, },
"cat6": { "cat6": {
"name": "Cat6 kaabel", "name": "Cat6 kaabel",
"emoji": "<:TipiCAT:1483014337663602718>", "emoji": E["TipiCAT"],
"cost": 3500, "cost": 3500,
"description": strings.ITEM_DESCRIPTIONS["cat6"], "description": strings.ITEM_DESCRIPTIONS["cat6"],
}, },
# ----- Tier 3 ----- # ----- Tier 3 -----
"monitor_360": { "monitor_360": {
"name": "360Hz monitor", "name": "360Hz monitor",
"emoji": "<:TipiMONITOR2:1483387699514839162>", "emoji": E["TipiMONITOR2"],
"cost": 7500, "cost": 7500,
"description": strings.ITEM_DESCRIPTIONS["monitor_360"], "description": strings.ITEM_DESCRIPTIONS["monitor_360"],
}, },
"karikas": { "karikas": {
"name": "TipiLAN karikas", "name": "TipiLAN karikas",
"emoji": "<:TipiKARIKAS:1483014841148112977>", "emoji": E["TipiKARIKAS"],
"cost": 6000, "cost": 6000,
"description": strings.ITEM_DESCRIPTIONS["karikas"], "description": strings.ITEM_DESCRIPTIONS["karikas"],
}, },
"gaming_tool": { "gaming_tool": {
"name": "Gaming tool", "name": "Gaming tool",
"emoji": "<:TipiTOOL:1483014341648187613>", "emoji": E["TipiTOOL"],
"cost": 9000, "cost": 9000,
"description": strings.ITEM_DESCRIPTIONS["gaming_tool"], "description": strings.ITEM_DESCRIPTIONS["gaming_tool"],
}, },
@@ -204,7 +201,7 @@ class PrestigeItem(TypedDict):
PRESTIGE_SHOP: dict[str, PrestigeItem] = { PRESTIGE_SHOP: dict[str, PrestigeItem] = {
"coin_mult": { "coin_mult": {
"emoji": "<:TipiCOIN:1483000209188589628>", "emoji": E["TipiCOIN"],
"max_level": 5, "max_level": 5,
"pp_cost": 5, "pp_cost": 5,
"effect": 0.08, "effect": 0.08,
@@ -1482,21 +1479,21 @@ async def do_rps_pvp_refund(user_id: int, bet: int) -> dict:
# /slots # /slots
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
_SLOTS_SYMBOLS: list[tuple[str, int]] = [ _SLOTS_SYMBOLS: list[tuple[str, int]] = [
("<:TipiHEART:1483431377561976853>", 27), (E["TipiHEART"], 27),
("<:TipiFIRE:1483431381668335687>", 22), (E["TipiFIRE"], 22),
("<:TipiTROLL:1483431380166774895>", 18), (E["TipiTROLL"], 18),
("<:TipICRY:1483431288852709387>", 15), (E["TipICRY"], 15),
("<:TipiSKULL:1483431378929451028>", 10), (E["TipiSKULL"], 10),
("<:TipiKARIKAS:1483014841148112977>", 8), (E["TipiKARIKAS"], 8),
] ]
_SLOTS_JACKPOT = "<:TipiKARIKAS:1483014841148112977>" _SLOTS_JACKPOT = E["TipiKARIKAS"]
_SLOTS_TRIPLE_MULT: dict[str, int] = { _SLOTS_TRIPLE_MULT: dict[str, int] = {
"<:TipiHEART:1483431377561976853>": 4, E["TipiHEART"]: 4,
"<:TipiFIRE:1483431381668335687>": 5, E["TipiFIRE"]: 5,
"<:TipiTROLL:1483431380166774895>": 7, E["TipiTROLL"]: 7,
"<:TipICRY:1483431288852709387>": 10, E["TipICRY"]: 10,
"<:TipiSKULL:1483431378929451028>": 15, E["TipiSKULL"]: 15,
"<:TipiKARIKAS:1483014841148112977>": 25, # jackpot E["TipiKARIKAS"]: 25, # jackpot
} }

66
core/emoji.py Normal file
View File

@@ -0,0 +1,66 @@
"""Custom Discord emoji registry, keyed by symbolic name and resolved per BOT_PROFILE.
Emojis are uploaded as application emojis via the Discord Developer Portal
and are scoped to a single bot application. Dev and production are separate
applications, so the same logical emoji has a different ID in each — hence
two dicts below, selected by BOT_PROFILE.
To add a new emoji: upload it to both applications in the dev portal, grab
the two IDs, and add one line to each dict.
"""
from __future__ import annotations
from config import BOT_PROFILE
_DEV: dict[str, str] = {
"TipiCOIN": "<:TipiCOIN:1483000209188589628>",
"TipiFIRE": "<:TipiFIRE:1483431381668335687>",
"TipiHIIR": "<:TipiHIIR:1483004306012504128>",
"TipiMATT": "<:TipiMATT:1483387697132208128>",
"TipiKLAPID": "<:TipiKLAPID:1483387694083084349>",
"TipiPILET": "<:TipiPILET:1483004308353060904>",
"TipiBULL": "<:TipiBULL:1483004310924300409>",
"TipiLAP": "<:TipiLAP:1483004307161874566>",
"TipiVAC": "<:TipiVAC:1483004309510819860>",
"TipiLAUD": "<:TipiLAUD:1483387695576125440>",
"TipiSERVER": "<:TipiSERVER:1483387701032910969>",
"TipiMIC": "<:TipiMIC:1483387698499551313>",
"TipiKLAVA": "<:TipiKLAVA:1483014339228078140>",
"TipiMONITOR": "<:TipiMONITOR:1483014340327243908>",
"TipiCAT": "<:TipiCAT:1483014337663602718>",
"TipiMONITOR2": "<:TipiMONITOR2:1483387699514839162>",
"TipiKARIKAS": "<:TipiKARIKAS:1483014841148112977>",
"TipiTOOL": "<:TipiTOOL:1483014341648187613>",
"TipiHEART": "<:TipiHEART:1483431377561976853>",
"TipiTROLL": "<:TipiTROLL:1483431380166774895>",
"TipICRY": "<:TipICRY:1483431288852709387>",
"TipiSKULL": "<:TipiSKULL:1483431378929451028>",
"TipiDICE": "<:TipiDICE:1485923107108556950>",
"TipiYKS": "<:TipiYKS:1483103190491856916>",
"TipiKAKS": "<:TipiKAKS:1483103215841972404>",
"TipiKOLM": "<:TipiKOLM:1483103217846980781>",
"TipiNELI": "<:TipiNELI:1483103237585240114>",
"TipiVIIS": "<:TipiVIIS:1483103239036469289>",
"TipiKUUS": "<:TipiKUUS:1483103253163020348>",
"TipiSLOTS": "<a:TipiSLOTS:1483444233863037101>",
}
# Production application emoji IDs. Replace each ID with the one from the
# prod application in the dev portal. The dev IDs below are placeholders so
# this dict is structurally complete — they will NOT render in prod because
# they belong to a different application.
_ECONOMY: dict[str, str] = dict(_DEV)
_EMOJI_SETS = {
"dev": _DEV,
"economy": _ECONOMY,
}
EMOJI: dict[str, str] = _EMOJI_SETS[BOT_PROFILE]
_missing = set(_DEV) - set(EMOJI)
if _missing:
raise RuntimeError(f"Emoji set {BOT_PROFILE!r} missing keys: {sorted(_missing)}")

View File

@@ -4,6 +4,8 @@ Edit this file to change any message, description, or flavour text
without touching any logic code. without touching any logic code.
""" """
from core.emoji import EMOJI as E
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Flavour text # Flavour text
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@@ -256,22 +258,22 @@ HELP_CATEGORIES: dict[str, dict] = {
"description": "TipiBOTi poe esemed ja nende efektid", "description": "TipiBOTi poe esemed ja nende efektid",
"color": 0xF4C430, "color": 0xF4C430,
"fields": [ "fields": [
("<:TipiHIIR:1483004306012504128> Mängurihiir - 500 ⬡", "Teeni töötades 50% rohkem TipiCOINe."), (f"{E['TipiHIIR']} Mängurihiir - 500 ⬡", "Teeni töötades 50% rohkem TipiCOINe."),
("<:TipiMATT:1483387697132208128> XL hiirematt - 600 ⬡", "Kerjamise ooteaeg 5min → 3min."), (f"{E['TipiMATT']} XL hiirematt - 600 ⬡", "Kerjamise ooteaeg 5min → 3min."),
("<:TipiKLAPID:1483387694083084349> Kõrvaklapid - 1200 ⬡", "Päevase boonuse ooteaeg 20h → 18h."), (f"{E['TipiKLAPID']} Kõrvaklapid - 1200 ⬡", "Päevase boonuse ooteaeg 20h → 18h."),
("<:TipiPILET:1483004308353060904> LAN pilet (2025) - 1200 ⬡", "Päevane boonus on duubeldatud."), (f"{E['TipiPILET']} LAN pilet (2025) - 1200 ⬡", "Päevane boonus on duubeldatud."),
("<:TipiVAC:1483004309510819860> Anticheat - 750 ⬡", "Röövimine sinu vastu ebaõnnestub. Pärast 2 kasutust pead ostma uue."), (f"{E['TipiVAC']} Anticheat - 750 ⬡", "Röövimine sinu vastu ebaõnnestub. Pärast 2 kasutust pead ostma uue."),
("<:TipiBULL:1483004310924300409> Red Bull - 800 ⬡", "30% tõenäosus, et teenid töötades 3x rohkem."), (f"{E['TipiBULL']} Red Bull - 800 ⬡", "30% tõenäosus, et teenid töötades 3x rohkem."),
("<:TipiLAP:1483004307161874566> Botikoobas - 1500 ⬡", "RTX 5090 jooksutab botte 24/7. Päevane boonus genereerib 5% intressi sinu saldo pealt."), (f"{E['TipiLAP']} Botikoobas - 1500 ⬡", "RTX 5090 jooksutab botte 24/7. Päevane boonus genereerib 5% intressi sinu saldo pealt."),
("<:TipiLAUD:1483387695576125440> Reguleeritav laud - 3500 ⬡ *(T2)*", "/work teenib 25% rohkem (stackib mängurihiirega)."), (f"{E['TipiLAUD']} Reguleeritav laud - 3500 ⬡ *(T2)*", "/work teenib 25% rohkem (stackib mängurihiirega)."),
("<:TipiSERVER:1483387701032910969> Jellyfin server - 4000 ⬡ *(T2)*", "Röövimise edu tõenäosus 45% → 60%."), (f"{E['TipiSERVER']} Jellyfin server - 4000 ⬡ *(T2)*", "Röövimise edu tõenäosus 45% → 60%."),
("<:TipiMIC:1483387698499551313> Mikrofon - 2800 ⬡ *(T2)*", "Teeni 30% rohkem eduka /crime puhul."), (f"{E['TipiMIC']} Mikrofon - 2800 ⬡ *(T2)*", "Teeni 30% rohkem eduka /crime puhul."),
("<:TipiKLAVA:1483014339228078140> Mehhaaniline klaviatuur - 1800 ⬡ *(T2)*", "/beg teenib 2x rohkem."), (f"{E['TipiKLAVA']} Mehhaaniline klaviatuur - 1800 ⬡ *(T2)*", "/beg teenib 2x rohkem."),
("<:TipiMONITOR:1483014340327243908> Ultralai monitor - 2500 ⬡ *(T2)*", "/work ooteaeg: 1h → 40min."), (f"{E['TipiMONITOR']} Ultralai monitor - 2500 ⬡ *(T2)*", "/work ooteaeg: 1h → 40min."),
("<:TipiCAT:1483014337663602718> CAT6 netikaabel - 3500 ⬡ *(T2)*", "/crime edu tõenäosus tõuseb 60% → 75%."), (f"{E['TipiCAT']} CAT6 netikaabel - 3500 ⬡ *(T2)*", "/crime edu tõenäosus tõuseb 60% → 75%."),
("<:TipiMONITOR2:1483387699514839162> 360hz monitor - 7500 ⬡ *(T3)*", "Mänguautomaadi jackpot 10x → 15x, kolmik 4x → 6x."), (f"{E['TipiMONITOR2']} 360hz monitor - 7500 ⬡ *(T3)*", "Mänguautomaadi jackpot 10x → 15x, kolmik 4x → 6x."),
("<:TipiKARIKAS:1483014841148112977> TipiLANi trofee - 6000 ⬡ *(T3)*", "Streak ei nulli, kui sa mõne päeva vahele jätad."), (f"{E['TipiKARIKAS']} TipiLANi trofee - 6000 ⬡ *(T3)*", "Streak ei nulli, kui sa mõne päeva vahele jätad."),
("<:TipiTOOL:1483014341648187613> Mänguritool - 9000 ⬡ *(T3)*", "/crime ebaõnnestumine ei saada sind vanglasse."), (f"{E['TipiTOOL']} Mänguritool - 9000 ⬡ *(T3)*", "/crime ebaõnnestumine ei saada sind vanglasse."),
], ],
}, },
"games": { "games": {
@@ -347,10 +349,10 @@ REMINDER_OPTS: list[tuple[str, str, str]] = [
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
SLOTS_TIERS: dict[str, tuple[str, int]] = { SLOTS_TIERS: dict[str, tuple[str, int]] = {
"jackpot": ("<:TipiFIRE:1483431381668335687> JACKPOT!!!", 0xF4C430), "jackpot": (f"{E['TipiFIRE']} JACKPOT!!!", 0xF4C430),
"triple": ("🎰 Kolmik!", 0x57F287), "triple": ("🎰 Kolmik!", 0x57F287),
"pair": ("🎰 Paar", 0x99AAB5), "pair": ("🎰 Paar", 0x99AAB5),
"miss": ("<:TipICRY:1483431288852709387> Ei õnnestunud", 0xED4245), "miss": (f"{E['TipICRY']} Ei õnnestunud", 0xED4245),
} }
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@@ -534,22 +536,22 @@ TITLE: dict[str, str] = {
"daily": "📅 Päevane boonus", "daily": "📅 Päevane boonus",
"work": "💼 Töö", "work": "💼 Töö",
"beg": "🙏 Kerjamine", "beg": "🙏 Kerjamine",
"crime_win": "<:TipiFIRE:1483431381668335687> Kuritegu õnnestus!", "crime_win": f"{E['TipiFIRE']} Kuritegu õnnestus!",
"crime_fail": "<:TipiTROLL:1483431380166774895> Vahele jäid!", "crime_fail": f"{E['TipiTROLL']} Vahele jäid!",
"rob_win": "<:TipiFIRE:1483431381668335687> Rööv õnnestus!", "rob_win": f"{E['TipiFIRE']} Rööv õnnestus!",
"rob_fail": "<:TipiTROLL:1483431380166774895> Rööv ebaõnnestus!", "rob_fail": f"{E['TipiTROLL']} Rööv ebaõnnestus!",
"rob_anticheat": "<:TipiVAC:1483004309510819860> Anticheat peatas sind!", "rob_anticheat": f"{E['TipiVAC']} Anticheat peatas sind!",
"jailbreak": "🎲 Vanglast põgenemine", "jailbreak": "🎲 Vanglast põgenemine",
"jailbreak_free": "🎲 <:TipiFIRE:1483431381668335687> DUUBEL! Oled vaba!", "jailbreak_free": f"🎲 {E['TipiFIRE']} DUUBEL! Oled vaba!",
"jailbreak_fail": "<:TipICRY:1483431288852709387> Kolm katset läbi!", "jailbreak_fail": f"{E['TipICRY']} Kolm katset läbi!",
"jailbreak_miss": "🎲 <:TipICRY:1483431288852709387> Ei saanud duublit ({tries}/{max})", "jailbreak_miss": "🎲 " + E["TipICRY"] + " Ei saanud duublit ({tries}/{max})",
"jailbreak_bail": "💸 Kautsjon", "jailbreak_bail": "💸 Kautsjon",
"give": "<:TipiHEART:1483431377561976853> TipiCOINi ülekanne", "give": f"{E['TipiHEART']} TipiCOINi ülekanne",
"stats": "📊 Mängustatistika", "stats": "📊 Mängustatistika",
"leaderboard_coins": "🪙 TipiBOTi edetabel - Mündid", "leaderboard_coins": "🪙 TipiBOTi edetabel - Mündid",
"leaderboard_exp": "📊 TipiBOTi edetabel - EXP / Tase", "leaderboard_exp": "📊 TipiBOTi edetabel - EXP / Tase",
"leaderboard_season": "🏆 TipiBOTi edetabel - Hooaja EXP", "leaderboard_season": "🏆 TipiBOTi edetabel - Hooaja EXP",
"leaderboard_prestige": "<:TipiFIRE:1483431381668335687> TipiBOTi edetabel - Prestiiž", "leaderboard_prestige": f"{E['TipiFIRE']} TipiBOTi edetabel - Prestiiž",
"leaderboard_wagered": "🎲 TipiBOTi edetabel - Hasartmängud", "leaderboard_wagered": "🎲 TipiBOTi edetabel - Hasartmängud",
"leaderboard_fish": "🎣 TipiBOTi edetabel - Kalapüük", "leaderboard_fish": "🎣 TipiBOTi edetabel - Kalapüük",
"rps": "⚔️ Kivi, Paber, Käärid", "rps": "⚔️ Kivi, Paber, Käärid",
@@ -560,26 +562,26 @@ TITLE: dict[str, str] = {
"rps_duel_expire": "⚔️ KPK duell - aegus", "rps_duel_expire": "⚔️ KPK duell - aegus",
"rps_duel_decline": "⚔️ KPK duell - keelduti", "rps_duel_decline": "⚔️ KPK duell - keelduti",
"heist_lobby": "🔫 Grupirööv - kogunemine", "heist_lobby": "🔫 Grupirööv - kogunemine",
"heist_win": "<:TipiFIRE:1483431381668335687> Grupirööv õnnestus!", "heist_win": f"{E['TipiFIRE']} Grupirööv õnnestus!",
"heist_fail": "<:TipiSKULL:1483431378929451028> Grupirööv ebaõnnestus!", "heist_fail": f"{E['TipiSKULL']} Grupirööv ebaõnnestus!",
"heist_cancel": "🔫 Grupirööv tühistatud", "heist_cancel": "🔫 Grupirööv tühistatud",
"request": "<:TipiHEART:1483431377561976853> Rahataotlus", "request": f"{E['TipiHEART']} Rahataotlus",
"reminders": "⏰ Meeldetuletused", "reminders": "⏰ Meeldetuletused",
"cooldowns": "⏱️ Sinu ooteajad", "cooldowns": "⏱️ Sinu ooteajad",
"adminseason": "🏆 Hooaeg lõppes!", "adminseason": "🏆 Hooaeg lõppes!",
"economysetup": "⚙️ Majanduse seadistamine", "economysetup": "⚙️ Majanduse seadistamine",
"blackjack": "🃏 Blackjack", "blackjack": "🃏 Blackjack",
"blackjack_bj": "🃏 <:TipiFIRE:1483431381668335687> BLACKJACK!", "blackjack_bj": f"🃏 {E['TipiFIRE']} BLACKJACK!",
"blackjack_win": "<:TipiFIRE:1483431381668335687> Võitsid!", "blackjack_win": f"{E['TipiFIRE']} Võitsid!",
"blackjack_lose": "<:TipiSKULL:1483431378929451028> Kaotasid!", "blackjack_lose": f"{E['TipiSKULL']} Kaotasid!",
"blackjack_bust": "<:TipiSKULL:1483431378929451028> Üle 21 - kaotasid!", "blackjack_bust": f"{E['TipiSKULL']} Üle 21 - kaotasid!",
"blackjack_push": "🤝 Viik!", "blackjack_push": "🤝 Viik!",
"blackjack_dbust": "<:TipiSKULL:1483431378929451028> Üle 21 - mõlemad kaotasid!", "blackjack_dbust": f"{E['TipiSKULL']} Üle 21 - mõlemad kaotasid!",
"blackjack_dwin": "<:TipiFIRE:1483431381668335687> Topeltpanus võitis!", "blackjack_dwin": f"{E['TipiFIRE']} Topeltpanus võitis!",
"prestige_confirm": "🔥 Prestiiž - kinnita", "prestige_confirm": "🔥 Prestiiž - kinnita",
"prestige_success": "<:TipiFIRE:1483431381668335687> Prestiiž {level} saavutatud!", "prestige_success": E["TipiFIRE"] + " Prestiiž {level} saavutatud!",
"prestige_too_low": "❌ Prestiiž pole saadaval", "prestige_too_low": "❌ Prestiiž pole saadaval",
"prestige_shop": "<:TipiFIRE:1483431381668335687> Prestiižipood", "prestige_shop": f"{E['TipiFIRE']} Prestiižipood",
"prestige_buy_ok": "✅ Uuendus ostetud!", "prestige_buy_ok": "✅ Uuendus ostetud!",
"fish_cast": "🎣 Otsid kala...", "fish_cast": "🎣 Otsid kala...",
"fish_bite": "🐟 KALA NÄKKAB!", "fish_bite": "🐟 KALA NÄKKAB!",
@@ -609,8 +611,8 @@ ERR: dict[str, str] = {
"heist_active": "❌ Serveris on juba aktiivne grupirööv käimas! Oota, kuni see lõpeb.", "heist_active": "❌ Serveris on juba aktiivne grupirööv käimas! Oota, kuni see lõpeb.",
"heist_full": "❌ Grupirööv on täis!", "heist_full": "❌ Grupirööv on täis!",
"heist_min_players": "❌ Grupiröövi alustamiseks on vaja vähemalt **{min}** osalejat.", "heist_min_players": "❌ Grupiröövi alustamiseks on vaja vähemalt **{min}** osalejat.",
"broke": "<:TipICRY:1483431288852709387> Sul pole piisavalt TipiCOINe. Saldo: {bal}", "broke": E["TipICRY"] + " Sul pole piisavalt TipiCOINe. Saldo: {bal}",
"broke_need": "<:TipICRY:1483431288852709387> Sul pole piisavalt TipiCOINe. Vajad veel {need}.", "broke_need": E["TipICRY"] + " Sul pole piisavalt TipiCOINe. Vajad veel {need}.",
"item_owned": "❌ Sul on see ese juba olemas.", "item_owned": "❌ Sul on see ese juba olemas.",
"item_not_found": "❌ Eset ei leitud.", "item_not_found": "❌ Eset ei leitud.",
"item_level_req": "🔒 Selle eseme ostmiseks vajad **taset {min_level}** (sul on tase {user_level}). Teeni EXP-id kõiki käske kasutades.", "item_level_req": "🔒 Selle eseme ostmiseks vajad **taset {min_level}** (sul on tase {user_level}). Teeni EXP-id kõiki käske kasutades.",
@@ -653,7 +655,7 @@ CD_MSG: dict[str, str] = {
"rob": "⏳ Saad uuesti röövida {ts}.", "rob": "⏳ Saad uuesti röövida {ts}.",
"heist": "⏳ Saad uuesti heisti teha {ts}.", "heist": "⏳ Saad uuesti heisti teha {ts}.",
"heist_global": "⏳ Pangahoidla alles kosub eelmisest röövist. Järgmine heist võimalik {ts}.", "heist_global": "⏳ Pangahoidla alles kosub eelmisest röövist. Järgmine heist võimalik {ts}.",
"jailed": "<:TipiTROLL:1483431380166774895> Oled vangis! Pääsed välja {ts}. Kasuta `/jailbreak`, et varem välja pääseda.", "jailed": E["TipiTROLL"] + " Oled vangis! Pääsed välja {ts}. Kasuta `/jailbreak`, et varem välja pääseda.",
"fish": "🎣 Saad uuesti kalastada {ts}.", "fish": "🎣 Saad uuesti kalastada {ts}.",
} }
@@ -837,8 +839,8 @@ CHANNEL_UI: dict[str, str] = {
DAILY_UI: dict[str, str] = { DAILY_UI: dict[str, str] = {
"earned": "✅ Said {earned}!", "earned": "✅ Said {earned}!",
"interest": "<:TipiLAP:1483004307161874566> Bot Farm tootis: +{interest}", "interest": E["TipiLAP"] + " Bot Farm tootis: +{interest}",
"vip": "<:TipiPILET:1483004308353060904> LAN pileti boonus rakendus!", "vip": f"{E['TipiPILET']} LAN pileti boonus rakendus!",
"footer": "Streak: {streak_str} · Saldo: {balance}", "footer": "Streak: {streak_str} · Saldo: {balance}",
} }
@@ -1050,9 +1052,9 @@ RANK_UI: dict[str, str] = {
WORK_UI: dict[str, str] = { WORK_UI: dict[str, str] = {
"desc": "Sa {job} ja teenisid {earned}!", "desc": "Sa {job} ja teenisid {earned}!",
"redbull": "\n<:TipiBULL:1483004310924300409> Red Bull aktiveerus - 3x boonus!", "redbull": f"\n{E['TipiBULL']} Red Bull aktiveerus - 3x boonus!",
"hiir": "\n<:TipiHIIR:1483004306012504128> Mängurihiir: +50% palk", "hiir": f"\n{E['TipiHIIR']} Mängurihiir: +50% palk",
"laud": "\n<:TipiLAUD:1483387695576125440> Reguleeritav laud: +25% palk", "laud": f"\n{E['TipiLAUD']} Reguleeritav laud: +25% palk",
"balance": "\nSaldo: {balance}", "balance": "\nSaldo: {balance}",
} }
@@ -1062,7 +1064,7 @@ WORK_UI: dict[str, str] = {
BEG_UI: dict[str, str] = { BEG_UI: dict[str, str] = {
"desc": "Sa {text} ja said {earned}.", "desc": "Sa {text} ja said {earned}.",
"klaviatuur": "<:TipiKLAVA:1483014339228078140> Mehhaaniline klaviatuur: 2x tulu", "klaviatuur": f"{E['TipiKLAVA']} Mehhaaniline klaviatuur: 2x tulu",
"balance": "Saldo: {balance}", "balance": "Saldo: {balance}",
} }
@@ -1075,8 +1077,8 @@ CRIME_UI: dict[str, str] = {
"fail_base": "Sa {text} ja said trahvi {fine}.", "fail_base": "Sa {text} ja said trahvi {fine}.",
"fail_jailed": "\n\ud83d\udd12 Oled vangis! P\u00e4\u00e4sed {ts}.", "fail_jailed": "\n\ud83d\udd12 Oled vangis! P\u00e4\u00e4sed {ts}.",
"fail_shield": "\n\ud83d\udee1\ufe0f Gaming Tool hoidis sind vanglast!", "fail_shield": "\n\ud83d\udee1\ufe0f Gaming Tool hoidis sind vanglast!",
"mikrofon": "\n<:TipiMIC:1483387698499551313> Mikrofon: +30% saak", "mikrofon": f"\n{E['TipiMIC']} Mikrofon: +30% saak",
"cat6": "\n<:TipiCAT:1483014337663602718> CAT6: 75% edu t\u00f5en\u00e4osus", "cat6": f"\n{E['TipiCAT']} CAT6: 75% edu t\u00f5en\u00e4osus",
"balance": "\nSaldo: {balance}", "balance": "\nSaldo: {balance}",
} }
@@ -1116,7 +1118,7 @@ BUY_UI: dict[str, str] = {
JAILBREAK_UI: dict[str, str] = { JAILBREAK_UI: dict[str, str] = {
"btn_roll": "🎲 Viska täringud ({try_}/{max})", "btn_roll": "🎲 Viska täringud ({try_}/{max})",
"rolling_desc": "<:TipiDICE:1485923107108556950> *Täringud lendavad...*", "rolling_desc": f"{E['TipiDICE']} *Täringud lendavad...*",
"free_desc": "{d1} {d2}\n\n✅ Viskasid duubli - pääsesid vanglast!", "free_desc": "{d1} {d2}\n\n✅ Viskasid duubli - pääsesid vanglast!",
"miss_desc": "{d1} {d2}\n\n{left} katset jäänud. Proovi uuesti!", "miss_desc": "{d1} {d2}\n\n{left} katset jäänud. Proovi uuesti!",
"intro_desc": "Oled vangis kuni {ts}.\n\nViska täringuid ja proovi **duublit** saada - siis pääsed tasuta vabaks!\nSul on **{tries} katset**. Ebaõnnestumisel saad valida: maksa kautsjon **(2030% saldost, min 350 ⬡)** või jää vanglasse kuni aja lõpuni.", "intro_desc": "Oled vangis kuni {ts}.\n\nViska täringuid ja proovi **duublit** saada - siis pääsed tasuta vabaks!\nSul on **{tries} katset**. Ebaõnnestumisel saad valida: maksa kautsjon **(2030% saldost, min 350 ⬡)** või jää vanglasse kuni aja lõpuni.",
@@ -1160,7 +1162,7 @@ LEADERBOARD_UI: dict[str, str] = {
SLOTS_UI: dict[str, str] = { SLOTS_UI: dict[str, str] = {
"playing": "🎰 Mängimas...", "playing": "🎰 Mängimas...",
"jackpot_footer": "<:TipiKARIKAS:1483014841148112977> Kolm karikat! +{change}", "jackpot_footer": E["TipiKARIKAS"] + " Kolm karikat! +{change}",
"triple_footer": "✅ Kolm ühesugust! +{change}", "triple_footer": "✅ Kolm ühesugust! +{change}",
"pair_footer": "Kaks ühesugust! +{change}", "pair_footer": "Kaks ühesugust! +{change}",
"miss_footer": "-{amount}", "miss_footer": "-{amount}",
@@ -1264,7 +1266,7 @@ PRESTIGE_SHOP_DESCRIPTIONS: dict[str, str] = {
PRESTIGE_UI: dict[str, str] = { PRESTIGE_UI: dict[str, str] = {
"confirm_desc": ( "confirm_desc": (
"Oled tasemel **{level}** ({exp} EXP).\n\n" "Oled tasemel **{level}** ({exp} EXP).\n\n"
"Prestiiži korral saad **{pp}** <:TipiFIRE:1483431381668335687> ja kõik lähtestub:\n" "Prestiiži korral saad **{pp}** " + E["TipiFIRE"] + " ja kõik lähtestub:\n"
"• Saldo, EXP, esemed, ooteajad\n\n" "• Saldo, EXP, esemed, ooteajad\n\n"
"**Kalakogu jääb alles!**\n\nKas oled kindel?" "**Kalakogu jääb alles!**\n\nKas oled kindel?"
), ),
@@ -1273,21 +1275,21 @@ PRESTIGE_UI: dict[str, str] = {
"btn_tab_status": "⭐ Prestiiz", "btn_tab_status": "⭐ Prestiiz",
"btn_tab_shop": "🛍️ Uuendused", "btn_tab_shop": "🛍️ Uuendused",
"success_desc": ( "success_desc": (
"Said **{pp}** <:TipiFIRE:1483431381668335687>\n" "Said **{pp}** " + E["TipiFIRE"] + "\n"
"Prestiiži tase: **{level}**\n" "Prestiiži tase: **{level}**\n"
"Kogutud PP: **{total_pp}** <:TipiFIRE:1483431381668335687>\n\n" "Kogutud PP: **{total_pp}** " + E["TipiFIRE"] + "\n\n"
"*Kõik lähtestati. Alusta otsast!*" "*Kõik lähtestati. Alusta otsast!*"
), ),
"too_low_desc": "Prestiiži jaoks vajad taset **{required}** (sul on tase {level}).", "too_low_desc": "Prestiiži jaoks vajad taset **{required}** (sul on tase {level}).",
"shop_desc": "Sul on **{pp}** <:TipiFIRE:1483431381668335687> · Vajuta nuppu uuenduse ostmiseks", "shop_desc": "Sul on **{pp}** " + E["TipiFIRE"] + " · Vajuta nuppu uuenduse ostmiseks",
"shop_maxed": "✅ Max", "shop_maxed": "✅ Max",
"shop_level_fmt": "Tase {cur}/{max}", "shop_level_fmt": "Tase {cur}/{max}",
"shop_cost_fmt": "{cost} <:TipiFIRE:1483431381668335687>", "shop_cost_fmt": "{cost} " + E["TipiFIRE"],
"buy_success_desc":"**{name}** uuendatud tasemele **{new_level}/{max_level}**!\nPP alles: **{pp}** <:TipiFIRE:1483431381668335687>", "buy_success_desc":"**{name}** uuendatud tasemele **{new_level}/{max_level}**!\nPP alles: **{pp}** " + E["TipiFIRE"],
"buy_no_pp": "<:TipICRY:1483431288852709387> Sul pole piisavalt PP. Sul on **{have}**, vajad **{need}** <:TipiFIRE:1483431381668335687>.", "buy_no_pp": E["TipICRY"] + " Sul pole piisavalt PP. Sul on **{have}**, vajad **{need}** " + E["TipiFIRE"] + ".",
"buy_maxed": "❌ See uuendus on juba maksimumtasemel.", "buy_maxed": "❌ See uuendus on juba maksimumtasemel.",
"buy_not_found": "❌ Sellist uuendust ei leitud. Vaata `/prestigeshop`.", "buy_not_found": "❌ Sellist uuendust ei leitud. Vaata `/prestigeshop`.",
"rank_line": "<:TipiFIRE:1483431381668335687> Prestiiž **{level}** · {pp} PP", "rank_line": E["TipiFIRE"] + " Prestiiž **{level}** · {pp} PP",
"rank_season": "🏆 Hooaja EXP: **{exp}**", "rank_season": "🏆 Hooaja EXP: **{exp}**",
"btn_buy_upgrade": "{emoji} {name} +1 ({cost} PP)", "btn_buy_upgrade": "{emoji} {name} +1 ({cost} PP)",
"status_footer": "⭐ Prestiiž {level} · {pp} PP", "status_footer": "⭐ Prestiiž {level} · {pp} PP",