82 lines
No EOL
3.2 KiB
TypeScript
82 lines
No EOL
3.2 KiB
TypeScript
import { ChatInputCommandInteraction, TextChannel } from "discord.js";
|
|
import { cfg } from "../../systems/config";
|
|
import { polls, updatePollMessage } from "../../systems/poll";
|
|
import { getEffectiveCharacter } from "../../systems/borrow";
|
|
import { nowFormatted, resolveMessage } from "../../systems/messages";
|
|
import { replyAndDelete } from "../../utils";
|
|
import { VoteEntry } from "../../types";
|
|
|
|
export async function handleInject(interaction: ChatInputCommandInteraction): Promise<void> {
|
|
const userKey = interaction.options.getString("name", true);
|
|
const voteType = interaction.options.getString("vote_type", true) as "yes" | "no";
|
|
|
|
console.log("[inject] called");
|
|
const slot = [...polls.keys()][0];
|
|
console.log("[inject] slot:", slot);
|
|
if (slot === undefined) return void replyAndDelete(interaction, "❌ No active poll found.");
|
|
|
|
const state = polls.get(slot)!;
|
|
if (state.locked || state.confirmed !== null) {
|
|
return void replyAndDelete(interaction, "❌ Poll is locked or confirmed.");
|
|
}
|
|
|
|
const { char, borrowedFrom } = getEffectiveCharacter(userKey);
|
|
console.log(`[DEBUG inject] userKey=${userKey} char=${JSON.stringify(char)} borrowedFrom=${JSON.stringify(borrowedFrom)}`);
|
|
if (!char) return void replyAndDelete(interaction, `❌ No active character found for **${userKey}**.`);
|
|
|
|
// Use a synthetic userId based on userKey to avoid collisions
|
|
const syntheticId = `injected:${userKey}`;
|
|
const now = nowFormatted();
|
|
|
|
const publicMsg = resolveMessage("public", voteType, 1, userKey, null, null);
|
|
|
|
const entry: VoteEntry = {
|
|
userKey,
|
|
displayName: char.name,
|
|
characterName: char.name,
|
|
characterClass: char.class,
|
|
characterLevel: char.level,
|
|
characterNation: char.nation,
|
|
borrowedFrom: borrowedFrom ?? undefined,
|
|
votedAt: now,
|
|
publicMessage: publicMsg ?? undefined,
|
|
};
|
|
|
|
if (voteType === "yes") {
|
|
state.no.delete(syntheticId);
|
|
state.yes.set(syntheticId, entry);
|
|
} else {
|
|
state.yes.delete(syntheticId);
|
|
state.no.set(syntheticId, entry);
|
|
}
|
|
|
|
const channel = await interaction.client.channels.fetch(cfg("pollChannelId")) as TextChannel;
|
|
await updatePollMessage(channel, slot);
|
|
return void replyAndDelete(interaction, `✅ Injected **${userKey}** as **${voteType}**.`);
|
|
}
|
|
|
|
export async function handleRemoveVote(interaction: ChatInputCommandInteraction): Promise<void> {
|
|
const userKey = interaction.options.getString("name", true);
|
|
|
|
const slot = [...polls.keys()][0];
|
|
if (slot === undefined) return void replyAndDelete(interaction, "❌ No active poll found.");
|
|
|
|
const state = polls.get(slot)!;
|
|
const syntheticId = `injected:${userKey}`;
|
|
|
|
// Also try removing real votes by scanning for userKey
|
|
let removed = false;
|
|
for (const [id, entry] of [...state.yes.entries(), ...state.no.entries()]) {
|
|
if (entry.userKey === userKey || id === syntheticId) {
|
|
state.yes.delete(id);
|
|
state.no.delete(id);
|
|
removed = true;
|
|
}
|
|
}
|
|
|
|
if (!removed) return void replyAndDelete(interaction, `❌ No vote found for **${userKey}**.`);
|
|
|
|
const channel = await interaction.client.channels.fetch(cfg("pollChannelId")) as TextChannel;
|
|
await updatePollMessage(channel, slot);
|
|
return void replyAndDelete(interaction, `✅ Vote removed for **${userKey}**.`);
|
|
} |