95 lines
No EOL
4 KiB
TypeScript
95 lines
No EOL
4 KiB
TypeScript
import { ChatInputCommandInteraction, TextChannel } from "discord.js";
|
|
import { Config } from "../../systems/config";
|
|
import { resolveUser, hasOfficerRole } from "../../systems/users";
|
|
import { getCharacterByName, getActiveCharacter } from "../../systems/characters";
|
|
import { addPendingRequest, setSessionBorrow, sendBorrowRequestDM, canUseCharacter } from "../../systems/borrow";
|
|
import { polls, updatePollMessage } from "../../systems/poll";
|
|
import { replyAndDelete } from "../../utils";
|
|
import { getUsermapEntry, getUsermapEntryById } from "@src/systems/messages";
|
|
|
|
export async function handleCharBorrow(interaction: ChatInputCommandInteraction): Promise<void> {
|
|
const member = await interaction.guild!.members.fetch(interaction.user.id);
|
|
const isOfficer = hasOfficerRole(member, Config.get({ section: "roles", key: "officer" }));
|
|
const requester = await resolveUser(member);
|
|
|
|
// Args: owner, charname, [username] (officer only — grants directly)
|
|
const ownerArg = interaction.options.getString("owner", true);
|
|
const charName = interaction.options.getString("char_name", true);
|
|
const targetArg = interaction.options.getString("name"); // officer: grant to this user
|
|
|
|
if (targetArg && !isOfficer) {
|
|
return void replyAndDelete(interaction, "❌ Only officers can grant borrows directly.");
|
|
}
|
|
|
|
const requesterKey = targetArg ?? requester.userKey;
|
|
if (!requesterKey) return void replyAndDelete(interaction, "❌ You are not registered in the system.");
|
|
|
|
const char = getCharacterByName(ownerArg, charName);
|
|
if (!char) return void replyAndDelete(interaction, `❌ Character **«${charName}»** not found for **${ownerArg}**.`);
|
|
|
|
// Already has access?
|
|
if (canUseCharacter(requesterKey, ownerArg, charName)) {
|
|
return void replyAndDelete(interaction, `❌ **${requesterKey}** already has access to **«${charName}»**.`);
|
|
}
|
|
|
|
// Officer bypasses request — grant directly
|
|
if (isOfficer && targetArg) {
|
|
setSessionBorrow(requesterKey, ownerArg, charName);
|
|
|
|
// Update poll if the user has already voted
|
|
const slot = [...polls.keys()][0];
|
|
if (slot !== undefined) {
|
|
const state = polls.get(slot)!;
|
|
const channel = await interaction.client.channels.fetch(Config.get({ section: "channels", key: "poll" })) as TextChannel;
|
|
// Find the voter entry and update their character
|
|
for (const [id, entry] of [...state.yes.entries(), ...state.no.entries()]) {
|
|
if (entry.userKey === requesterKey) {
|
|
entry.characterName = char.name;
|
|
entry.characterClass = char.class.key;
|
|
entry.characterLevel = char.level;
|
|
entry.characterNation = char.nation;
|
|
entry.publicMessage = undefined;
|
|
}
|
|
}
|
|
await updatePollMessage(channel, slot);
|
|
}
|
|
|
|
return void replyAndDelete(interaction, `✅ **${requesterKey}** can now borrow **«${charName}»** for this session.`);
|
|
}
|
|
|
|
// Regular player — send request to owner
|
|
addPendingRequest({
|
|
requesterKey,
|
|
ownerKey: ownerArg,
|
|
charName,
|
|
requestedAt: Date.now(),
|
|
});
|
|
|
|
// Find owner's Discord ID from guild members
|
|
// We need to reverse-lookup: find the guild member whose discord username maps to ownerArg
|
|
const guild = interaction.guild!;
|
|
await guild.members.fetch();
|
|
const ownerMember = guild.members.cache.find((m) => {
|
|
const entry = getUsermapEntryById(m.user.id, m.user.username);
|
|
return entry?.file === ownerArg;
|
|
});
|
|
|
|
if (!ownerMember) {
|
|
return void replyAndDelete(interaction, `✅ Borrow request sent — but **${ownerArg}** is not currently in the server to be notified.`);
|
|
}
|
|
|
|
const fallbackChannel = await interaction.client.channels.fetch(Config.get({ section: "channels", key: "poll" })) as TextChannel;
|
|
await sendBorrowRequestDM(
|
|
interaction.client,
|
|
ownerMember.user.id,
|
|
requester.displayName,
|
|
ownerArg,
|
|
requesterKey,
|
|
char.name,
|
|
char.class.key,
|
|
char.level,
|
|
fallbackChannel
|
|
);
|
|
|
|
return void replyAndDelete(interaction, `✅ Borrow request sent to **${ownerArg}** for **«${charName}»**.`);
|
|
} |