forked from sass/tipibot
Feature: Clean up the codebase
This commit is contained in:
310
commands/economy_admin_commands.py
Normal file
310
commands/economy_admin_commands.py
Normal file
@@ -0,0 +1,310 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
import logging
|
||||
from collections.abc import Awaitable, Callable
|
||||
|
||||
import discord
|
||||
from discord import app_commands
|
||||
|
||||
from core import economy
|
||||
import strings as S
|
||||
|
||||
|
||||
async def _dm_user(bot: discord.Client, user_id: int, msg: str) -> None:
|
||||
"""Best-effort DM to a user."""
|
||||
try:
|
||||
user = bot.get_user(user_id) or await bot.fetch_user(user_id)
|
||||
await user.send(msg)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def register_economy_admin_commands(
|
||||
tree: app_commands.CommandTree,
|
||||
bot: discord.Client,
|
||||
log: logging.Logger,
|
||||
cd_ts: Callable[[datetime.timedelta], str],
|
||||
apply_level_role: Callable[[discord.Member, int, int], Awaitable[None]],
|
||||
) -> None:
|
||||
@tree.command(name="adminseason", description=S.CMD["adminseason"])
|
||||
@app_commands.guild_only()
|
||||
@app_commands.default_permissions(manage_guild=True)
|
||||
@app_commands.describe(top_n=S.OPT["adminseason_top_n"])
|
||||
async def cmd_adminseason(interaction: discord.Interaction, top_n: int = 10):
|
||||
await interaction.response.defer(ephemeral=True)
|
||||
top = await economy.do_season_reset(top_n)
|
||||
guild = interaction.guild
|
||||
|
||||
if guild:
|
||||
all_role_names = {name for _, name in economy.LEVEL_ROLES}
|
||||
for role_name in all_role_names:
|
||||
role = discord.utils.find(lambda r: r.name == role_name, guild.roles)
|
||||
if not role:
|
||||
continue
|
||||
for member in list(role.members):
|
||||
try:
|
||||
await member.remove_roles(role, reason="Season reset")
|
||||
except discord.Forbidden:
|
||||
pass
|
||||
|
||||
medals = ["🥇", "🥈", "🥉"]
|
||||
lines = []
|
||||
for i, (uid, exp, lvl) in enumerate(top):
|
||||
member = guild.get_member(int(uid)) if guild else None
|
||||
name = member.display_name if member else S.LEADERBOARD_UI["unknown_user"].format(uid=uid)
|
||||
prefix = medals[i] if i < 3 else f"**{i + 1}.**"
|
||||
lines.append(S.SEASON["entry"].format(prefix=prefix, name=name, exp=exp, level=lvl))
|
||||
|
||||
embed = discord.Embed(
|
||||
title=S.TITLE["adminseason"],
|
||||
description=(S.SEASON["top_header"] + "\n" + "\n".join(lines)) if lines else S.SEASON["no_players"],
|
||||
color=0xF4C430,
|
||||
)
|
||||
embed.set_footer(text=S.SEASON["footer"])
|
||||
await interaction.followup.send(embed=embed, ephemeral=False)
|
||||
await interaction.followup.send(S.SEASON["done"], ephemeral=True)
|
||||
log.info("/adminseason triggered by %s (top_n=%d)", interaction.user, top_n)
|
||||
|
||||
@tree.command(name="admincoins", description=S.CMD["admincoins"])
|
||||
@app_commands.guild_only()
|
||||
@app_commands.describe(
|
||||
kasutaja=S.OPT["admin_kasutaja"],
|
||||
kogus=S.OPT["admincoins_kogus"],
|
||||
põhjus=S.OPT["admin_põhjus"],
|
||||
)
|
||||
@app_commands.default_permissions(manage_guild=True)
|
||||
async def cmd_admincoins(interaction: discord.Interaction, kasutaja: discord.Member, kogus: int, põhjus: str):
|
||||
if kogus == 0:
|
||||
await interaction.response.send_message(S.ERR["admincoins_zero"], ephemeral=True)
|
||||
return
|
||||
res = await economy.do_admin_coins(kasutaja.id, kogus, interaction.user.id, põhjus)
|
||||
verb = f"+{kogus}" if kogus > 0 else str(kogus)
|
||||
emoji = "💰" if kogus > 0 else "💸"
|
||||
await interaction.response.send_message(
|
||||
S.ADMIN["coins_done"].format(
|
||||
emoji=emoji,
|
||||
name=kasutaja.display_name,
|
||||
verb=verb,
|
||||
coin=economy.COIN,
|
||||
balance=f"{res['balance']:,}",
|
||||
reason=põhjus,
|
||||
),
|
||||
ephemeral=True,
|
||||
)
|
||||
await _dm_user(
|
||||
bot,
|
||||
kasutaja.id,
|
||||
S.ADMIN["coins_dm"].format(
|
||||
emoji=emoji,
|
||||
verb=verb,
|
||||
coin=economy.COIN,
|
||||
reason=põhjus,
|
||||
balance=f"{res['balance']:,}",
|
||||
),
|
||||
)
|
||||
log.info("ADMINCOINS %s → %s (%s) by %s", verb, kasutaja, põhjus, interaction.user)
|
||||
|
||||
@tree.command(name="adminjail", description=S.CMD["adminjail"])
|
||||
@app_commands.guild_only()
|
||||
@app_commands.describe(
|
||||
kasutaja=S.OPT["admin_kasutaja"],
|
||||
minutid=S.OPT["adminjail_minutid"],
|
||||
põhjus=S.OPT["admin_põhjus"],
|
||||
)
|
||||
@app_commands.default_permissions(manage_guild=True)
|
||||
async def cmd_adminjail(interaction: discord.Interaction, kasutaja: discord.Member, minutid: int, põhjus: str):
|
||||
if minutid <= 0:
|
||||
await interaction.response.send_message(S.ERR["positive_duration"], ephemeral=True)
|
||||
return
|
||||
await economy.do_admin_jail(kasutaja.id, minutid, interaction.user.id, põhjus)
|
||||
until_ts = cd_ts(datetime.timedelta(minutes=minutid))
|
||||
await interaction.response.send_message(
|
||||
S.ADMIN["jail_done"].format(name=kasutaja.display_name, minutes=minutid, ts=until_ts, reason=põhjus),
|
||||
ephemeral=True,
|
||||
)
|
||||
await _dm_user(
|
||||
bot,
|
||||
kasutaja.id,
|
||||
S.ADMIN["jail_dm"].format(minutes=minutid, reason=põhjus, ts=until_ts),
|
||||
)
|
||||
log.info("ADMINJAIL %s %dmin (%s) by %s", kasutaja, minutid, põhjus, interaction.user)
|
||||
|
||||
@tree.command(name="adminunjail", description=S.CMD["adminunjail"])
|
||||
@app_commands.guild_only()
|
||||
@app_commands.describe(kasutaja=S.OPT["admin_kasutaja"])
|
||||
@app_commands.default_permissions(manage_guild=True)
|
||||
async def cmd_adminunjail(interaction: discord.Interaction, kasutaja: discord.Member):
|
||||
await economy.do_admin_unjail(kasutaja.id, interaction.user.id)
|
||||
await interaction.response.send_message(
|
||||
S.ADMIN["unjail_done"].format(name=kasutaja.display_name), ephemeral=True
|
||||
)
|
||||
await _dm_user(bot, kasutaja.id, S.ADMIN["unjail_dm"])
|
||||
log.info("ADMINUNJAIL %s by %s", kasutaja, interaction.user)
|
||||
|
||||
@tree.command(name="adminban", description=S.CMD["adminban"])
|
||||
@app_commands.guild_only()
|
||||
@app_commands.describe(
|
||||
kasutaja=S.OPT["admin_kasutaja"],
|
||||
põhjus=S.OPT["admin_põhjus"],
|
||||
)
|
||||
@app_commands.default_permissions(manage_guild=True)
|
||||
async def cmd_adminban(interaction: discord.Interaction, kasutaja: discord.Member, põhjus: str):
|
||||
if bot.user and kasutaja.id == bot.user.id:
|
||||
await interaction.response.send_message(S.ERR["admin_ban_bot"], ephemeral=True)
|
||||
return
|
||||
await economy.do_admin_ban(kasutaja.id, interaction.user.id, põhjus)
|
||||
await interaction.response.send_message(
|
||||
S.ADMIN["ban_done"].format(name=kasutaja.display_name, reason=põhjus),
|
||||
ephemeral=True,
|
||||
)
|
||||
await _dm_user(bot, kasutaja.id, S.ADMIN["ban_dm"].format(reason=põhjus))
|
||||
log.info("ADMINBAN %s (%s) by %s", kasutaja, põhjus, interaction.user)
|
||||
|
||||
@tree.command(name="adminunban", description=S.CMD["adminunban"])
|
||||
@app_commands.guild_only()
|
||||
@app_commands.describe(kasutaja=S.OPT["admin_kasutaja"])
|
||||
@app_commands.default_permissions(manage_guild=True)
|
||||
async def cmd_adminunban(interaction: discord.Interaction, kasutaja: discord.Member):
|
||||
await economy.do_admin_unban(kasutaja.id, interaction.user.id)
|
||||
await interaction.response.send_message(
|
||||
S.ADMIN["unban_done"].format(name=kasutaja.display_name), ephemeral=True
|
||||
)
|
||||
await _dm_user(bot, kasutaja.id, S.ADMIN["unban_dm"])
|
||||
log.info("ADMINUNBAN %s by %s", kasutaja, interaction.user)
|
||||
|
||||
@tree.command(name="adminreset", description=S.CMD["adminreset"])
|
||||
@app_commands.guild_only()
|
||||
@app_commands.describe(
|
||||
kasutaja=S.OPT["admin_kasutaja"],
|
||||
põhjus=S.OPT["admin_põhjus"],
|
||||
)
|
||||
@app_commands.default_permissions(manage_guild=True)
|
||||
async def cmd_adminreset(interaction: discord.Interaction, kasutaja: discord.Member, põhjus: str):
|
||||
if bot.user and kasutaja.id == bot.user.id:
|
||||
await interaction.response.send_message(S.ERR["admin_reset_bot"], ephemeral=True)
|
||||
return
|
||||
await economy.do_admin_reset(kasutaja.id, interaction.user.id)
|
||||
await interaction.response.send_message(
|
||||
S.ADMIN["reset_done"].format(name=kasutaja.display_name, reason=põhjus),
|
||||
ephemeral=True,
|
||||
)
|
||||
await _dm_user(bot, kasutaja.id, S.ADMIN["reset_dm"].format(reason=põhjus))
|
||||
log.info("ADMINRESET %s (%s) by %s", kasutaja, põhjus, interaction.user)
|
||||
|
||||
@tree.command(name="adminview", description=S.CMD["adminview"])
|
||||
@app_commands.guild_only()
|
||||
@app_commands.describe(kasutaja=S.OPT["admin_kasutaja"])
|
||||
@app_commands.default_permissions(manage_guild=True)
|
||||
async def cmd_adminview(interaction: discord.Interaction, kasutaja: discord.Member):
|
||||
res = await economy.do_admin_inspect(kasutaja.id)
|
||||
data = res["data"]
|
||||
items_str = ", ".join(data.get("items", [])) or "-"
|
||||
uses = data.get("item_uses", {})
|
||||
uses_str = ", ".join(f"{k}:{v}" for k, v in uses.items()) if uses else "-"
|
||||
jailed = data.get("jailed_until") or "-"
|
||||
banned = S.ADMINVIEW_UI["banned_yes"] if data.get("eco_banned") else S.ADMINVIEW_UI["banned_no"]
|
||||
exp = data.get("exp", 0)
|
||||
level = economy.get_level(exp)
|
||||
prestige_lvl = data.get("prestige_level", 0)
|
||||
prestige_pp = data.get("prestige_points", 0)
|
||||
total_fish = data.get("total_fish_caught", 0)
|
||||
inv_fish = len(data.get("fish_inventory") or [])
|
||||
embed = discord.Embed(
|
||||
title=S.ADMINVIEW_UI["title"].format(name=kasutaja.display_name),
|
||||
color=0x5865F2,
|
||||
)
|
||||
embed.add_field(name=S.ADMINVIEW_UI["f_balance"], value=f"{data.get('balance', 0):,} {economy.COIN}", inline=True)
|
||||
embed.add_field(name=S.ADMINVIEW_UI["f_exp"], value=S.ADMINVIEW_UI["exp_val"].format(exp=f"{exp:,}", level=level), inline=True)
|
||||
embed.add_field(name=S.ADMINVIEW_UI["f_streak"], value=str(data.get("daily_streak", 0)), inline=True)
|
||||
embed.add_field(name=S.ADMINVIEW_UI["f_banned"], value=banned, inline=True)
|
||||
embed.add_field(name=S.ADMINVIEW_UI["f_jailed"], value=jailed, inline=True)
|
||||
embed.add_field(name=S.ADMINVIEW_UI["f_prestige"], value=S.ADMINVIEW_UI["prestige_val"].format(level=prestige_lvl, pp=prestige_pp), inline=True)
|
||||
embed.add_field(name=S.ADMINVIEW_UI["f_fish"], value=S.ADMINVIEW_UI["fish_val"].format(caught=total_fish, inv=inv_fish), inline=True)
|
||||
embed.add_field(name=S.ADMINVIEW_UI["f_items"], value=items_str, inline=False)
|
||||
embed.add_field(name=S.ADMINVIEW_UI["f_uses"], value=uses_str, inline=False)
|
||||
embed.add_field(name=S.ADMINVIEW_UI["f_last_daily"], value=data.get("last_daily") or "-", inline=True)
|
||||
embed.add_field(name=S.ADMINVIEW_UI["f_last_work"], value=data.get("last_work") or "-", inline=True)
|
||||
embed.add_field(name=S.ADMINVIEW_UI["f_last_crime"], value=data.get("last_crime") or "-", inline=True)
|
||||
embed.add_field(name=S.ADMINVIEW_UI["f_last_fish"], value=data.get("last_fish") or "-", inline=True)
|
||||
embed.set_footer(text=S.ADMINVIEW_UI["footer"].format(uid=kasutaja.id))
|
||||
await interaction.response.send_message(embed=embed, ephemeral=True)
|
||||
log.info("ADMINVIEW %s by %s", kasutaja, interaction.user)
|
||||
|
||||
@tree.command(name="adminexp", description=S.CMD["adminexp"])
|
||||
@app_commands.guild_only()
|
||||
@app_commands.describe(
|
||||
kasutaja=S.OPT["admin_kasutaja"],
|
||||
kogus=S.OPT["adminexp_kogus"],
|
||||
põhjus=S.OPT["admin_põhjus"],
|
||||
)
|
||||
@app_commands.default_permissions(manage_guild=True)
|
||||
async def cmd_adminexp(interaction: discord.Interaction, kasutaja: discord.Member, kogus: int, põhjus: str):
|
||||
if kogus == 0:
|
||||
await interaction.response.send_message(S.ERR["admincoins_zero"], ephemeral=True)
|
||||
return
|
||||
res = await economy.do_admin_exp(kasutaja.id, kogus, interaction.user.id, põhjus)
|
||||
verb = f"+{kogus}" if kogus > 0 else str(kogus)
|
||||
emoji = "📈" if kogus > 0 else "📉"
|
||||
await interaction.response.send_message(
|
||||
S.ADMIN["exp_done"].format(
|
||||
emoji=emoji,
|
||||
name=kasutaja.display_name,
|
||||
verb=verb,
|
||||
exp=f"{res['exp']:,}",
|
||||
level=res["new_level"],
|
||||
reason=põhjus,
|
||||
),
|
||||
ephemeral=True,
|
||||
)
|
||||
await _dm_user(
|
||||
bot,
|
||||
kasutaja.id,
|
||||
S.ADMIN["exp_dm"].format(
|
||||
emoji=emoji,
|
||||
verb=verb,
|
||||
reason=põhjus,
|
||||
exp=f"{res['exp']:,}",
|
||||
level=res["new_level"],
|
||||
),
|
||||
)
|
||||
if res["level_changed"]:
|
||||
member = interaction.guild.get_member(kasutaja.id) if interaction.guild else None
|
||||
if member:
|
||||
await apply_level_role(member, res["new_level"], res["old_level"])
|
||||
log.info("ADMINEXP %s → %s (%s) by %s", verb, kasutaja, põhjus, interaction.user)
|
||||
|
||||
@tree.command(name="adminitem", description=S.CMD["adminitem"])
|
||||
@app_commands.guild_only()
|
||||
@app_commands.describe(
|
||||
kasutaja=S.OPT["admin_kasutaja"],
|
||||
ese=S.OPT["adminitem_ese"],
|
||||
tegevus=S.OPT["adminitem_tegevus"],
|
||||
)
|
||||
@app_commands.default_permissions(manage_guild=True)
|
||||
async def cmd_adminitem(interaction: discord.Interaction, kasutaja: discord.Member, ese: str, tegevus: str):
|
||||
action = tegevus.strip().lower()
|
||||
if action not in ("anna", "eemalda"):
|
||||
await interaction.response.send_message(S.ADMIN["item_invalid"].format(item_id=tegevus), ephemeral=True)
|
||||
return
|
||||
action_key = "give" if action == "anna" else "remove"
|
||||
res = await economy.do_admin_item(kasutaja.id, ese, action_key, interaction.user.id)
|
||||
if not res["ok"]:
|
||||
if res["reason"] == "invalid_item":
|
||||
await interaction.response.send_message(S.ADMIN["item_invalid"].format(item_id=ese), ephemeral=True)
|
||||
elif res["reason"] == "not_owned":
|
||||
await interaction.response.send_message(
|
||||
S.ADMIN["item_not_owned"].format(name=kasutaja.display_name, item_id=ese),
|
||||
ephemeral=True,
|
||||
)
|
||||
else:
|
||||
await interaction.response.send_message(S.ERR["generic_error"].format(error=res["reason"]), ephemeral=True)
|
||||
return
|
||||
item_name = economy.SHOP[ese]["name"]
|
||||
if action_key == "give":
|
||||
await interaction.response.send_message(S.ADMIN["item_given"].format(item=item_name, name=kasutaja.display_name), ephemeral=True)
|
||||
await _dm_user(bot, kasutaja.id, S.ADMIN["item_dm_given"].format(item=item_name))
|
||||
else:
|
||||
await interaction.response.send_message(S.ADMIN["item_removed"].format(item=item_name, name=kasutaja.display_name), ephemeral=True)
|
||||
await _dm_user(bot, kasutaja.id, S.ADMIN["item_dm_removed"].format(item=item_name))
|
||||
log.info("ADMINITEM %s %s %s by %s", action_key, ese, kasutaja, interaction.user)
|
||||
Reference in New Issue
Block a user