最后活跃于 1 month ago

nuno 修订了这个 Gist 1 month ago. 转到此修订

1 file changed, 82 insertions

inject.ts(文件已创建)

@@ -0,0 +1,82 @@
1 + import { ChatInputCommandInteraction, TextChannel } from "discord.js";
2 + import { cfg } from "../../systems/config";
3 + import { polls, updatePollMessage } from "../../systems/poll";
4 + import { getEffectiveCharacter } from "../../systems/borrow";
5 + import { nowFormatted, resolveMessage } from "../../systems/messages";
6 + import { replyAndDelete } from "../../utils";
7 + import { VoteEntry } from "../../types";
8 +
9 + export async function handleInject(interaction: ChatInputCommandInteraction): Promise<void> {
10 + const userKey = interaction.options.getString("name", true);
11 + const voteType = interaction.options.getString("vote_type", true) as "yes" | "no";
12 +
13 + console.log("[inject] called");
14 + const slot = [...polls.keys()][0];
15 + console.log("[inject] slot:", slot);
16 + if (slot === undefined) return void replyAndDelete(interaction, "❌ No active poll found.");
17 +
18 + const state = polls.get(slot)!;
19 + if (state.locked || state.confirmed !== null) {
20 + return void replyAndDelete(interaction, "❌ Poll is locked or confirmed.");
21 + }
22 +
23 + const { char, borrowedFrom } = getEffectiveCharacter(userKey);
24 + console.log(`[DEBUG inject] userKey=${userKey} char=${JSON.stringify(char)} borrowedFrom=${JSON.stringify(borrowedFrom)}`);
25 + if (!char) return void replyAndDelete(interaction, `❌ No active character found for **${userKey}**.`);
26 +
27 + // Use a synthetic userId based on userKey to avoid collisions
28 + const syntheticId = `injected:${userKey}`;
29 + const now = nowFormatted();
30 +
31 + const publicMsg = resolveMessage("public", voteType, 1, userKey, null, null);
32 +
33 + const entry: VoteEntry = {
34 + userKey,
35 + displayName: char.name,
36 + characterName: char.name,
37 + characterClass: char.class,
38 + characterLevel: char.level,
39 + characterNation: char.nation,
40 + borrowedFrom: borrowedFrom ?? undefined,
41 + votedAt: now,
42 + publicMessage: publicMsg ?? undefined,
43 + };
44 +
45 + if (voteType === "yes") {
46 + state.no.delete(syntheticId);
47 + state.yes.set(syntheticId, entry);
48 + } else {
49 + state.yes.delete(syntheticId);
50 + state.no.set(syntheticId, entry);
51 + }
52 +
53 + const channel = await interaction.client.channels.fetch(cfg("pollChannelId")) as TextChannel;
54 + await updatePollMessage(channel, slot);
55 + return void replyAndDelete(interaction, `✅ Injected **${userKey}** as **${voteType}**.`);
56 + }
57 +
58 + export async function handleRemoveVote(interaction: ChatInputCommandInteraction): Promise<void> {
59 + const userKey = interaction.options.getString("name", true);
60 +
61 + const slot = [...polls.keys()][0];
62 + if (slot === undefined) return void replyAndDelete(interaction, "❌ No active poll found.");
63 +
64 + const state = polls.get(slot)!;
65 + const syntheticId = `injected:${userKey}`;
66 +
67 + // Also try removing real votes by scanning for userKey
68 + let removed = false;
69 + for (const [id, entry] of [...state.yes.entries(), ...state.no.entries()]) {
70 + if (entry.userKey === userKey || id === syntheticId) {
71 + state.yes.delete(id);
72 + state.no.delete(id);
73 + removed = true;
74 + }
75 + }
76 +
77 + if (!removed) return void replyAndDelete(interaction, `❌ No vote found for **${userKey}**.`);
78 +
79 + const channel = await interaction.client.channels.fetch(cfg("pollChannelId")) as TextChannel;
80 + await updatePollMessage(channel, slot);
81 + return void replyAndDelete(interaction, `✅ Vote removed for **${userKey}**.`);
82 + }
上一页 下一页