From 9e395f775f62c416ccc4cd16cb0a67dbfbe1cc9e Mon Sep 17 00:00:00 2001 From: Christopher Renaud Oelerich Date: Sat, 9 Dec 2023 16:55:07 -0600 Subject: [PATCH] Update Actor Model for 2.4.0 --- module.json | 8 ++++---- src/module.mjs | 7 +++++-- src/sync.mjs | 54 ++++++++++++++++++++++++++++++++------------------ 3 files changed, 44 insertions(+), 25 deletions(-) diff --git a/module.json b/module.json index a804b1e..14c2299 100644 --- a/module.json +++ b/module.json @@ -6,8 +6,8 @@ "library": "false", "manifestPlusVersion": "1.2.0", "compatibility": { - "minimum": 10.303, - "verified": 11, + "minimum": 11.303, + "verified": 11.315, "maximum": 11 }, "authors": [ @@ -27,8 +27,8 @@ "id": "dnd5e", "manifest": "https://raw.githubusercontent.com/foundryvtt/dnd5e/master/system.json", "compatibility": { - "minimum": "2.0.0", - "verified": "2.3.1" + "minimum": "2.4.0", + "verified": "2.4.1" } } ], diff --git a/src/module.mjs b/src/module.mjs index 9284b3b..b3bc1c9 100644 --- a/src/module.mjs +++ b/src/module.mjs @@ -1,7 +1,7 @@ import {Logger} from "./util.mjs"; import {registerSettings} from "./settings.mjs"; import {ID_MAP, MODULE_ID} from "./constants.mjs"; -import {sync_actor} from "./sync.mjs" +import {del_actor, sync_actor} from "./sync.mjs" let socket; @@ -43,11 +43,14 @@ Hooks.on("createActor", async (actor, data, options, userId) => { await sync_actor(actor) }) Hooks.on("updateActor", async (actor, data, options, userId) => { + if ('currency' in data?.system) { + //todo handle currency + } await sync_actor(actor) //todo handle incremental updates }) Hooks.on("deleteActor", async (actor, data, options, userId) => { - //handle actor deletion + await del_actor(actor.id) }) diff --git a/src/sync.mjs b/src/sync.mjs index 29cfb51..57ba344 100644 --- a/src/sync.mjs +++ b/src/sync.mjs @@ -1,5 +1,5 @@ import {ACTORS, AUTH, GUILD_ID, ID_MAP, MODULE_ID, ORONDER_BASE_URL} from "./constants.mjs"; -import {hash} from "./util.mjs"; +import {hash, Logger} from "./util.mjs"; function prune_roll_data( { @@ -78,7 +78,7 @@ function gen_item_deets(item, actor_lvl) { .filter(s => s !== '0') let attack = new Roll( - ["1d20", ...attack_parts].join(" + "), + ["1d20", ...attack_parts].join(" + ").replace(' + -', ' - '), item.getRollData() ) @@ -118,14 +118,16 @@ export function enrich_actor(actor) { let portrait_url = actor.img.indexOf('http://') === 0 || actor.img.indexOf('https://') === 0 ? actor.img : new URL(actor.img, window.location.origin).href - + const pc_roll_data = actor.getRollData() const clone_pc = JSON.parse(JSON.stringify( - actor.getRollData(), + pc_roll_data, (k, v) => v instanceof Set ? [...v] : v) ) - clone_pc.details['dead'] = Boolean(actor.effects.find(e => !e.disabled && e.name === 'Dead')) + clone_pc.details.dead = Boolean(actor.effects.find(e => !e.disabled && e.name === 'Dead')) + clone_pc.details.background = actor.system.details.background ? actor.system.details.background.name : '' + clone_pc.details.race = actor.system.details.race ? actor.system.details.race.name : '' - const out = { + return { ...prune_roll_data(clone_pc), name: actor.name, id: actor.id, @@ -133,21 +135,23 @@ export function enrich_actor(actor) { weapons: weapons, portrait_url: portrait_url } - - return out } -async function upload(pc) { +function headers() { const guild_id = game.settings.get(MODULE_ID, GUILD_ID) const authorization = game.settings.get(MODULE_ID, AUTH) + return new Headers({ + "Accept": "application/json", + "Content-Type": "application/json", + 'Guild-Id': guild_id, + 'Authorization': authorization + }) +} + +async function upload(pc) { const requestOptions = { method: 'PUT', - headers: new Headers({ - "Accept": "application/json", - "Content-Type": "application/json", - 'Guild-Id': guild_id, - 'Authorization': authorization - }), + headers: headers(), body: JSON.stringify(pc), redirect: 'follow' }; @@ -155,10 +159,20 @@ async function upload(pc) { return await fetch(`${ORONDER_BASE_URL}/actor`, requestOptions) } +export async function del_actor(pc_id) { + const requestOptions = { + method: 'DELETE', + headers: headers(), + redirect: 'follow' + }; + + return await fetch(`${ORONDER_BASE_URL}/actor/${pc_id}`, requestOptions) +} + const actor_to_discord_ids = actor => Object.entries(actor.ownership) - .filter(([owner_id, perm_lvl]) => perm_lvl === 3) + .filter(([_, perm_lvl]) => perm_lvl === 3) .map(([owner_id, _]) => game.settings.get(MODULE_ID, ID_MAP)[owner_id]) .filter(discord_id => discord_id) @@ -175,14 +189,16 @@ export async function sync_actor(actor) { if (!discord_ids.length) return - const old_hash = localStorage.getItem(`${ACTORS}.actor.id`) + const old_hash = localStorage.getItem(`${ACTORS}.${actor.id}`) const actor_obj = enrich_actor(actor) + const new_hash = hash(actor_obj) - // const new_hash = hash(actor_obj) + if (!old_hash || old_hash !== new_hash) { const response = await upload(actor_obj) if (response.ok) { - localStorage.setItem(`${ACTORS}.actor.id`, new_hash) + localStorage.setItem(`${ACTORS}.${actor.id}`, new_hash) + Logger.log(`Syncing ${actor_obj.name}`); } } } \ No newline at end of file