This commit is contained in:
NotSoToothless
2026-06-17 01:21:00 -07:00
committed by GitHub
parent 7bd8a1b72c
commit c5b74de367
3 changed files with 133 additions and 26 deletions
+86 -10
View File
@@ -58,8 +58,11 @@ async def team_autocomplete(interaction: discord.Interaction, current: str) -> L
return []
choices = []
for r in rows:
label = (r.get("long_name") or str(r["team_id"]))[:100]
choices.append(app_commands.Choice(name=label, value=str(r["team_id"])))
# Teams are tracked by name (ids are per-tournament and meaningless), so the
# autocomplete value is the name itself.
name = str(r.get("name") or "")
if name:
choices.append(app_commands.Choice(name=name[:100], value=name[:100]))
return choices
@@ -83,6 +86,54 @@ def _too_many_msg(candidates: List[dict]) -> str:
)
# ---------------------------------------------------------------------------
# Language picker (mirrors SREBOT's /language dropdown)
# ---------------------------------------------------------------------------
# Displayed language name -> canonical stored value (the LangTableReader column,
# shared with SREBOT's lang/units.csv). Kept identical to SREBOT's mapping.
LANGUAGE_MAPPING = {
"English": "<English>",
"Français": "<French>",
"Italiano": "<Italian>",
"Deutsch": "<German>",
"Español": "<Spanish>",
"Русский": "<Russian>",
"Polski": "<Polish>",
"Čeština": "<Czech>",
"简体中文": "<Chinese>",
"Português": "<Portuguese>",
"Українська": "<Ukrainian>",
}
class LanguageSelect(discord.ui.Select):
"""Dropdown for choosing the server's vehicle-name language."""
def __init__(self):
options = [discord.SelectOption(label=label, value=label) for label in LANGUAGE_MAPPING]
super().__init__(placeholder="Select a language", min_values=1, max_values=1, options=options)
async def callback(self, interaction: discord.Interaction):
if interaction.guild is None:
return await interaction.response.send_message("This command must be used in a server.", ephemeral=True)
selected = self.values[0]
canonical = LANGUAGE_MAPPING.get(selected, f"<{selected}>")
features = preferences.load_features(interaction.guild.id)
features["Language"] = canonical
preferences.save_features(interaction.guild.id, features)
log.info("Guild %s (%s) set language to %s", interaction.guild.name, interaction.guild.id, canonical)
await interaction.response.send_message(f"✅ Language set to **{selected}**.", ephemeral=True)
class LanguageView(discord.ui.View):
"""View wrapper holding the language dropdown."""
def __init__(self):
super().__init__()
self.add_item(LanguageSelect())
# ---------------------------------------------------------------------------
# Cog
# ---------------------------------------------------------------------------
@@ -123,15 +174,15 @@ class TssCommands(commands.Cog):
resolved = await storage.resolve_team(team)
if not resolved:
return await interaction.followup.send(f"Could not find a team matching **{team}**.", ephemeral=True)
name = resolved.get("long_name") or str(resolved["team_id"])
name = resolved.get("name") or str(resolved["team_id"])
preferences.set_guild_team(interaction.guild_id, int(resolved["team_id"]), name)
await interaction.followup.send(
f"✅ This server's team is now **{name}** (id `{resolved['team_id']}`).", ephemeral=True
f"✅ This server's team is now **{name}**.", ephemeral=True
)
# ── /log-team ──────────────────────────────────────────────────────────
@app_commands.command(name="log-team", description="Send a team's matches to this channel")
@app_commands.describe(team="TSS team name or ID")
@app_commands.command(name="log-team", description="Send a team's matches to this channel (or * for all)")
@app_commands.describe(team="TSS team name, or */all/everything to log every match")
@app_commands.autocomplete(team=team_autocomplete)
@app_commands.checks.has_permissions(manage_guild=True)
@not_blacklisted()
@@ -139,12 +190,22 @@ class TssCommands(commands.Cog):
await interaction.response.defer(ephemeral=True)
if interaction.guild_id is None or interaction.channel_id is None:
return await interaction.followup.send("This command must be used in a server channel.", ephemeral=True)
# Wildcard: log every TSS match to this channel.
if team.strip().lower() in preferences.WILDCARD_TOKENS:
preferences.upsert_log_entry(
interaction.guild_id, preferences.WILDCARD_KEY, "tss-wildcard",
"All matches", interaction.channel_id,
)
return await interaction.followup.send(
f"✅ Logging **all TSS matches** to <#{interaction.channel_id}>.", ephemeral=True
)
resolved = await storage.resolve_team(team)
if not resolved:
return await interaction.followup.send(f"Could not find a team matching **{team}**.", ephemeral=True)
name = resolved.get("long_name") or str(resolved["team_id"])
# Tracked by name — team ids are per-tournament and not stable.
name = resolved.get("name") or str(resolved["team_id"])
preferences.upsert_log_entry(
interaction.guild_id, int(resolved["team_id"]), "tss-team", name, interaction.channel_id
interaction.guild_id, preferences.team_pref_key(name), "tss-team", name, interaction.channel_id
)
await interaction.followup.send(
f"✅ Logging **{name}**'s matches to <#{interaction.channel_id}>.", ephemeral=True
@@ -167,7 +228,8 @@ class TssCommands(commands.Cog):
return await interaction.followup.send(_too_many_msg(candidates), ephemeral=True)
uid, nick = str(candidates[0]["uid"]), candidates[0]["nick"]
preferences.upsert_log_entry(
interaction.guild_id, uid, "tss-player", nick, interaction.channel_id
interaction.guild_id, preferences.player_pref_key(uid), "tss-player", nick,
interaction.channel_id, extra={"UID": uid},
)
await interaction.followup.send(
f"✅ Logging **{nick}**'s matches to <#{interaction.channel_id}>.", ephemeral=True
@@ -291,6 +353,17 @@ class TssCommands(commands.Cog):
embeds[-1].set_footer(text=FOOTER)
await interaction.followup.send(embeds=embeds)
# ── /languages ─────────────────────────────────────────────────────────
@app_commands.command(name="language", description="Set the language used for vehicle names")
@app_commands.checks.has_permissions(manage_guild=True)
@not_blacklisted()
async def language(self, interaction: discord.Interaction):
if interaction.guild_id is None:
return await interaction.response.send_message("This command must be used in a server.", ephemeral=True)
await interaction.response.send_message(
"Choose this server's language for vehicle names:", view=LanguageView(), ephemeral=True
)
# ── /help ──────────────────────────────────────────────────────────────
@app_commands.command(name="help", description="List TSSBOT commands and what they do")
@not_blacklisted()
@@ -320,7 +393,10 @@ class TssCommands(commands.Cog):
)
embed.add_field(
name="Info",
value="`/news` — latest announcements\n`/help` — this message",
value=(
"`/language` — set the language for vehicle names\n"
"`/news` — latest announcements\n`/help` — this message"
),
inline=False,
)
embed.set_footer(text=FOOTER)