set.ts
· 2.2 KiB · TypeScript
Raw
import { ChatInputCommandInteraction } from "discord.js";
import { cfg } from "../../systems/config";
import { resolveUser, hasOfficerRole } from "../../systems/users";
import { submitScore, detectSlot, normalizeSlot } from "../../systems/scores";
import { getActiveCharacter } from "../../systems/characters";
import { resolveNation } from "../../systems/nations";
import { replyAndDelete } from "../../utils";
export async function handleScoreSet(interaction: ChatInputCommandInteraction): Promise<void> {
const member = await interaction.guild!.members.fetch(interaction.user.id);
const isOfficer = hasOfficerRole(member, cfg("officerRoles"));
const nameArg = interaction.options.getString("name");
const ptsArg = interaction.options.getInteger("pts", true);
const slotArg = interaction.options.getString("slot");
// Officers can specify a name, players cannot
let usermapKey: string | null;
let targetMember = member;
if (nameArg) {
if (!isOfficer) return void replyAndDelete(interaction, "❌ Only officers can submit scores for other players.");
usermapKey = nameArg;
} else {
const user = await resolveUser(member);
usermapKey = user.usermapKey;
}
if (!usermapKey) return void replyAndDelete(interaction, "❌ You are not registered in the system.");
const char = getActiveCharacter(usermapKey);
if (!char) return void replyAndDelete(interaction, "❌ No active character found. Use `/tg char set-active` first.");
// Resolve slot
let slot: number | null = null;
if (slotArg) {
slot = normalizeSlot(slotArg);
if (slot === null) return void replyAndDelete(interaction, `❌ Could not parse slot "${slotArg}".`);
} else {
slot = detectSlot();
if (slot === null) {
return void replyAndDelete(interaction, "❌ No active score window detected. Specify a slot explicitly.");
}
}
await submitScore({
usermapKey,
characterName: char.name,
cls: char.class,
nation: char.nation,
pts: ptsArg,
slot,
submittedByOfficer: isOfficer && !!nameArg,
});
return void replyAndDelete(interaction, `✅ Score of **${ptsArg}** submitted for **${char.name}** (${slot}:00 TG).`);
}
| 1 | import { ChatInputCommandInteraction } from "discord.js"; |
| 2 | import { cfg } from "../../systems/config"; |
| 3 | import { resolveUser, hasOfficerRole } from "../../systems/users"; |
| 4 | import { submitScore, detectSlot, normalizeSlot } from "../../systems/scores"; |
| 5 | import { getActiveCharacter } from "../../systems/characters"; |
| 6 | import { resolveNation } from "../../systems/nations"; |
| 7 | import { replyAndDelete } from "../../utils"; |
| 8 | |
| 9 | export async function handleScoreSet(interaction: ChatInputCommandInteraction): Promise<void> { |
| 10 | const member = await interaction.guild!.members.fetch(interaction.user.id); |
| 11 | const isOfficer = hasOfficerRole(member, cfg("officerRoles")); |
| 12 | |
| 13 | const nameArg = interaction.options.getString("name"); |
| 14 | const ptsArg = interaction.options.getInteger("pts", true); |
| 15 | const slotArg = interaction.options.getString("slot"); |
| 16 | |
| 17 | // Officers can specify a name, players cannot |
| 18 | let usermapKey: string | null; |
| 19 | let targetMember = member; |
| 20 | |
| 21 | if (nameArg) { |
| 22 | if (!isOfficer) return void replyAndDelete(interaction, "❌ Only officers can submit scores for other players."); |
| 23 | usermapKey = nameArg; |
| 24 | } else { |
| 25 | const user = await resolveUser(member); |
| 26 | usermapKey = user.usermapKey; |
| 27 | } |
| 28 | |
| 29 | if (!usermapKey) return void replyAndDelete(interaction, "❌ You are not registered in the system."); |
| 30 | |
| 31 | const char = getActiveCharacter(usermapKey); |
| 32 | if (!char) return void replyAndDelete(interaction, "❌ No active character found. Use `/tg char set-active` first."); |
| 33 | |
| 34 | // Resolve slot |
| 35 | let slot: number | null = null; |
| 36 | if (slotArg) { |
| 37 | slot = normalizeSlot(slotArg); |
| 38 | if (slot === null) return void replyAndDelete(interaction, `❌ Could not parse slot "${slotArg}".`); |
| 39 | } else { |
| 40 | slot = detectSlot(); |
| 41 | if (slot === null) { |
| 42 | return void replyAndDelete(interaction, "❌ No active score window detected. Specify a slot explicitly."); |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | await submitScore({ |
| 47 | usermapKey, |
| 48 | characterName: char.name, |
| 49 | cls: char.class, |
| 50 | nation: char.nation, |
| 51 | pts: ptsArg, |
| 52 | slot, |
| 53 | submittedByOfficer: isOfficer && !!nameArg, |
| 54 | }); |
| 55 | |
| 56 | return void replyAndDelete(interaction, `✅ Score of **${ptsArg}** submitted for **${char.name}** (${slot}:00 TG).`); |
| 57 | } |
| 58 |