86 lines
No EOL
3.7 KiB
TypeScript
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.`);
|
|
} |