import { ChatInputCommandInteraction } from "discord.js"; import { cfg } from "../../systems/config"; import { resolveUser, hasOfficerRole } from "../../systems/users"; import { getCharacterByName } from "../../systems/characters"; import { replyAndDelete } from "../../utils"; import fs from "fs"; import path from "path"; import { clearPersistentPreference } from "../../systems/borrow"; const CHARS_PATH = path.join(__dirname, "../../../data/characters.json"); function saveCharacters(chars: any): void { fs.writeFileSync(CHARS_PATH, JSON.stringify(chars, null, 2)); } function loadRawChars(): any { return JSON.parse(fs.readFileSync(CHARS_PATH, "utf8")); } export async function handleCharShare(interaction: ChatInputCommandInteraction): Promise { const member = await interaction.guild!.members.fetch(interaction.user.id); const isOfficer = hasOfficerRole(member, cfg("officerRoles")); const user = await resolveUser(member); const ownerArg = interaction.options.getString("owner"); const charName = interaction.options.getString("char_name", true); const targetKey = interaction.options.getString("name", true); if (ownerArg && !isOfficer) { return void replyAndDelete(interaction, "❌ Only officers can share other players' characters."); } const ownerKey = ownerArg ?? user.userKey; if (!ownerKey) return void replyAndDelete(interaction, "❌ You are not registered in the system."); const char = getCharacterByName(ownerKey, charName); if (!char) return void replyAndDelete(interaction, `❌ Character **«${charName}»** not found.`); if (char.sharedWith?.includes(targetKey)) { return void replyAndDelete(interaction, `❌ **${targetKey}** already has access to **«${charName}»**.`); } // Write directly to characters.json const raw = loadRawChars(); const charEntry = raw[ownerKey]?.characters?.find((c: any) => c.name.toLowerCase() === charName.toLowerCase()); if (!charEntry) return void replyAndDelete(interaction, `❌ Character not found in data.`); if (!charEntry.sharedWith) charEntry.sharedWith = []; charEntry.sharedWith.push(targetKey); saveCharacters(raw); return void replyAndDelete(interaction, `✅ **${charName}** is now permanently shared with **${targetKey}**.`); } export async function handleCharUnshare(interaction: ChatInputCommandInteraction): Promise { const member = await interaction.guild!.members.fetch(interaction.user.id); const isOfficer = hasOfficerRole(member, cfg("officerRoles")); const user = await resolveUser(member); const ownerArg = interaction.options.getString("owner"); const charName = interaction.options.getString("char_name", true); const targetKey = interaction.options.getString("name", true); if (ownerArg && !isOfficer) { return void replyAndDelete(interaction, "❌ Only officers can modify other players' character shares."); } const ownerKey = ownerArg ?? user.userKey; if (!ownerKey) return void replyAndDelete(interaction, "❌ You are not registered in the system."); const raw = loadRawChars(); const charEntry = raw[ownerKey]?.characters?.find((c: any) => c.name.toLowerCase() === charName.toLowerCase()); if (!charEntry) return void replyAndDelete(interaction, `❌ Character **«${charName}»** not found.`); if (!charEntry.sharedWith?.includes(targetKey)) { return void replyAndDelete(interaction, `❌ **${targetKey}** does not have access to **«${charName}»**.`); } charEntry.sharedWith = charEntry.sharedWith.filter((k: string) => k !== targetKey); saveCharacters(raw); // Clear persistent preference if the borrower was using this char clearPersistentPreference(targetKey); return void replyAndDelete(interaction, `✅ **${targetKey}**'s access to **«${charName}»** has been revoked.`); }