Última actividad 4 weeks ago

nuno revisó este gist 4 weeks ago. Ir a la revisión

1 file changed, 123 insertions

gistfile1.txt(archivo creado)

@@ -0,0 +1,123 @@
1 + async function handleSwitchAfterReclaim(btn: ButtonInteraction): Promise<void> {
2 + const prefix = btn.customId.startsWith("companion_switch:") ? "companion_switch:" : "switch_after_reclaim:";
3 + const withoutPrefix = btn.customId.slice(prefix.length);
4 + const firstColon = withoutPrefix.indexOf(":");
5 + const userKey = withoutPrefix.slice(0, firstColon);
6 + const rest = withoutPrefix.slice(firstColon + 1);
7 + const lastColon = rest.lastIndexOf(":");
8 + const charName = rest.slice(0, lastColon);
9 + const prevVoteType = (rest.slice(lastColon + 1) || "yes") as "yes" | "no";
10 +
11 + const chars = JSON.parse(
12 + fs.readFileSync(path.join(__dirname, "../../data/characters.json"), "utf8")
13 + );
14 +
15 + let resolvedChar: any = null;
16 + let borrowedFrom: string | null = null;
17 +
18 + // Try own char first
19 + const ownEntry = chars[userKey]?.characters?.find((c: any) => c.name === charName);
20 + if (ownEntry) {
21 + setActiveCharacter(userKey, charName);
22 + clearSessionBorrowForUser(userKey);
23 + clearPersistentPreference(userKey);
24 + resolvedChar = ownEntry;
25 + } else {
26 + // Try shared char
27 + for (const [ownerKey, data] of Object.entries(chars) as [string, any][]) {
28 + const char = data.characters?.find(
29 + (c: any) => c.name === charName && c.sharedWith?.includes(userKey)
30 + );
31 + if (char) {
32 + setPersistentPreference(userKey, ownerKey, charName);
33 + clearSessionBorrowForUser(userKey);
34 + resolvedChar = char;
35 + borrowedFrom = ownerKey;
36 + break;
37 + }
38 + }
39 + }
40 +
41 + if (!resolvedChar) {
42 + await btn.reply({ content: `❌ Could not switch to **${charName}**.`, ephemeral: true });
43 + return;
44 + }
45 +
46 + // Re-add to poll with previous vote type
47 + const slot = [...polls.keys()][0];
48 + const state = slot !== undefined ? polls.get(slot) : null;
49 +
50 + let existingVoteId: string | null = null;
51 + if (state) {
52 + for (const [id, entry] of [...state.yes.entries(), ...state.no.entries()]) {
53 + if (entry.userKey === userKey) {
54 + existingVoteId = id;
55 + break;
56 + }
57 + }
58 + }
59 +
60 + // Conflict check
61 + if (state && resolvedChar) {
62 + for (const [id, entry] of state.yes.entries()) {
63 + if (id !== existingVoteId && id !== btn.user.id &&
64 + entry.characterName === resolvedChar.name &&
65 + entry.userKey !== userKey) {
66 + await btn.reply({
67 + content: `❌ ${format.char(resolvedChar)} is already in the poll by another player.`,
68 + ephemeral: true,
69 + });
70 + return;
71 + }
72 + }
73 + }
74 +
75 + if (state && !state.locked && state.confirmed === null) {
76 + const { char } = getEffectiveCharacter(userKey);
77 + const now = nowFormatted();
78 + const publicMsg = resolveMessage("public", prevVoteType, 1, userKey, null, null);
79 + const voteEntry = {
80 + userKey,
81 + displayName: charName,
82 + characterName: char?.name ?? charName,
83 + characterClass: char?.class ?? resolvedChar.class,
84 + characterLevel: char?.level ?? resolvedChar.level,
85 + characterNation: char?.nation ?? resolvedChar.nation,
86 + borrowedFrom: borrowedFrom ?? undefined,
87 + discordId: btn.user.id,
88 + votedAt: now,
89 + publicMessage: publicMsg ?? undefined,
90 + };
91 +
92 + // Find and reuse existing vote ID — avoids duplicate entries
93 + let existingVoteId: string | null = null;
94 + for (const [id, entry] of [...state.yes.entries(), ...state.no.entries()]) {
95 + if (entry.userKey === userKey) {
96 + if (!existingVoteId) existingVoteId = id;
97 + state.yes.delete(id);
98 + state.no.delete(id);
99 + }
100 + }
101 + const voteId = existingVoteId ?? btn.user.id;
102 +
103 + if (prevVoteType === "yes") {
104 + state.yes.set(voteId, voteEntry);
105 + } else {
106 + state.no.set(voteId, voteEntry);
107 + }
108 +
109 + console.log(`[switch_reclaim] cleaning up for userKey=${userKey}`);
110 + console.log(`[switch_reclaim] yes keys:`, [...state.yes.entries()].map(([id, e]) => `${id}:${e.userKey}`));
111 + console.log(`[switch_reclaim] no keys:`, [...state.no.entries()].map(([id, e]) => `${id}:${e.userKey}`));
112 +
113 + const channel = await btn.client.channels.fetch(cfg("pollChannelId")) as TextChannel;
114 + await updatePollMessage(channel, slot!);
115 + }
116 +
117 + const charDisplay = resolvedChar ? format.char(resolvedChar) : charName;
118 + const borrowNote = borrowedFrom ? ` *(shared by ${borrowedFrom})*` : "";
119 + await btn.reply({
120 + content: `🔄 ${charDisplay}${borrowNote}${state ? ` — re-added to poll as **${prevVoteType}**.` : ""}`,
121 + ephemeral: true,
122 + });
123 + }
Siguiente Anterior