最後活躍 1 week ago

nuno 已修改 1 week ago. 還原成這個修訂版本

1 file changed, 80 insertions

gistfile1.txt(檔案已創建)

@@ -0,0 +1,80 @@
1 + import { ChatInputCommandInteraction } from "discord.js";
2 + import { Config } from "@systems/config";
3 + import { resolveUser, hasOfficerRole } from "@systems/users";
4 + import { submitScore, detectSlot, normalizeSlot } from "@systems/scores";
5 + import { getEffectiveCharacter } from "@systems/borrow";
6 + import { replyAndDelete } from "@utils";
7 + import { Emoji } from "@systems/emojis";
8 + import { Discord } from "@discord";
9 + import { User } from "@systems/users";
10 +
11 + export async function handleScoreSet(interaction: ChatInputCommandInteraction): Promise<void> {
12 + const options = Discord.Interaction.options<ChatInputCommandInteraction>(interaction);
13 +
14 + const member = await interaction.guild!.members.fetch(interaction.user.id);
15 + const isOfficer = User.hasOfficerRole({
16 + member: member,
17 + officerRoles: Config.get({ section: "roles", key: "officer"
18 + })});
19 + const nameArg = options.string({ key: "name" });
20 + const ptsArg = options.integer({ key: "pts", required: true });
21 + const slotArg = options.string({ key: "slot" });
22 + const k = options.integer({ key: "k" }) ?? undefined;
23 + const d = options.integer({ key: "d" }) ?? undefined;
24 + const atk = options.integer({ key: "atk" }) ?? undefined;
25 + const def = options.integer({ key: "def" }) ?? undefined;
26 + const heal = options.integer({ key: "heal" }) ?? undefined;
27 +
28 + let userKey: string | null;
29 + if (nameArg) {
30 + if (!isOfficer) return void replyAndDelete(interaction, "❌ Only officers can submit scores for other players.");
31 + userKey = nameArg;
32 + } else {
33 + const user = await resolveUser(member);
34 + userKey = user.userKey;
35 + }
36 +
37 + if (!userKey) return void replyAndDelete(interaction, "❌ You are not registered in the system.");
38 +
39 + const { char, borrowedFrom } = getEffectiveCharacter(userKey);
40 + if (!char) return void replyAndDelete(interaction, "❌ No active character found. Use `/tg char set-active` first.");
41 +
42 + let slot: number | null = null;
43 + if (slotArg) {
44 + slot = normalizeSlot(slotArg);
45 + if (slot === null) return void replyAndDelete(interaction, `❌ Could not parse slot "${slotArg}".`);
46 + } else {
47 + slot = detectSlot() ?? Config.get({ section: "poll", key: "slots" }).find((s) => s.active)?.tgHour ?? 20;
48 + }
49 +
50 + await submitScore({
51 + userKey: borrowedFrom ?? userKey,
52 + playedBy: borrowedFrom ? userKey : undefined,
53 + characterName: char.name,
54 + cls: char.class.key,
55 + nation: char.nation,
56 + pts: ptsArg!,
57 + k,
58 + d,
59 + slot,
60 + atk,
61 + def,
62 + heal,
63 + submittedByOfficer: isOfficer && !!nameArg,
64 + });
65 +
66 + const scoreEmoji = Emoji.get("score") || "📊";
67 + const kdEmoji = Emoji.get("kd") || "⚔️";
68 + const borrowNote = borrowedFrom ? ` *(borrowed from ${borrowedFrom})*` : "";
69 + const kdNote = k !== undefined && d !== undefined ? `\n${kdEmoji} ${k}/${d}` : "";
70 + const statsNote = [
71 + atk !== undefined ? `ATK: ${atk}` : null,
72 + def !== undefined ? `DEF: ${def}` : null,
73 + heal !== undefined ? `HEAL: ${heal}` : null,
74 + ].filter(Boolean).join(" · ");
75 +
76 + return void replyAndDelete(interaction,
77 + `✅ ${scoreEmoji} **${ptsArg}** submitted for **${char.name}**${borrowNote} (${slot}:00 TG)${kdNote}${statsNote ? `\n${statsNote}` : ""}`,
78 + true
79 + );
80 + }
上一頁 下一頁