tg-bot-ts/src/subcommands/char/share.ts
2026-06-03 01:51:26 +01:00

86 lines
No EOL
3.7 KiB
TypeScript

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<void> {
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<void> {
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.`);
}