From c0a9731b02981360932102bc508555e7c6590c1a Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Mon, 6 Oct 2025 23:25:27 -0600 Subject: [PATCH] Add socket event handling foundations and an updateSands event in anticipation of hasty rolls --- langs/en-ca.json | 6 +++++- module/hooks/init.mjs | 2 ++ module/sockets/_index.mjs | 27 +++++++++++++++++++++++++ module/sockets/updateSands.mjs | 36 ++++++++++++++++++++++++++++++++++ module/utils/clamp.mjs | 3 +++ 5 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 module/sockets/_index.mjs create mode 100644 module/sockets/updateSands.mjs create mode 100644 module/utils/clamp.mjs diff --git a/langs/en-ca.json b/langs/en-ca.json index cad8c6a..963b2c2 100644 --- a/langs/en-ca.json +++ b/langs/en-ca.json @@ -193,7 +193,11 @@ "error": { "cannot-equip": "Cannot equip the {itemType}, see console for more details.", "invalid-delta": "The delta for \"{name}\" is not a number, cannot finish processing the action.", - "at-favourite-limit": "Cannot favourite more than three items, unfavourite one to make space." + "at-favourite-limit": "Cannot favourite more than three items, unfavourite one to make space.", + "invalid-socket": "Invalid socket data received, this means a module or system bug is present.", + "unknown-socket-event": "An unknown socket event was received: {event}", + "no-active-gm": "No active @USER.GM is logged in, you must wait for a @USER.GM to be active before you can do that.", + "malformed-socket-payload": "Socket event \"{event}\" received with malformed payload. Details: {details}" }, "warn": { "cannot-go-negative": "\"{name}\" is unable to be a negative number." diff --git a/module/hooks/init.mjs b/module/hooks/init.mjs index 548e8e2..28c4fd9 100644 --- a/module/hooks/init.mjs +++ b/module/hooks/init.mjs @@ -34,6 +34,7 @@ import { Logger } from "../utils/Logger.mjs"; import { registerCustomComponents } from "../Apps/components/_index.mjs"; import { registerDevSettings } from "../settings/devSettings.mjs"; import { registerMetaSettings } from "../settings/metaSettings.mjs"; +import { registerSockets } from "../sockets/_index.mjs"; import { registerUserSettings } from "../settings/userSettings.mjs"; import { registerWorldSettings } from "../settings/worldSettings.mjs"; @@ -127,6 +128,7 @@ Hooks.once(`init`, () => { CONFIG.Actor.trackableAttributes.hero = HeroData.trackableAttributes; // #endregion + registerSockets(); registerCustomComponents(); Handlebars.registerHelper(helpers); }); diff --git a/module/sockets/_index.mjs b/module/sockets/_index.mjs new file mode 100644 index 0000000..d0b632d --- /dev/null +++ b/module/sockets/_index.mjs @@ -0,0 +1,27 @@ +import { localizer } from "../utils/Localizer.mjs"; +import { Logger } from "../utils/Logger.mjs"; +import { updateSands } from "./updateSands.mjs"; + +const events = { + updateSands, +}; + +export function registerSockets() { + Logger.info(`Setting up socket listener`); + + game.socket.on(`system.${game.system.id}`, (data, userID) => { + const { event, payload } = data ?? {}; + if (event == null || payload === undefined) { + ui.notifications.error(localizer(`RipCrypt.notifs.error.invalid-socket`)); + return; + }; + + if (events[event] == null) { + ui.notifications.error(localizer(`RipCrypt.notifs.error.unknown-socket-event`, { event })); + return; + }; + + const user = game.users.get(userID); + events[event](payload, user); + }); +}; diff --git a/module/sockets/updateSands.mjs b/module/sockets/updateSands.mjs new file mode 100644 index 0000000..f851ce1 --- /dev/null +++ b/module/sockets/updateSands.mjs @@ -0,0 +1,36 @@ +import { clamp } from "../utils/clamp.mjs"; +import { localizer } from "../utils/Localizer.mjs"; + +export function updateSands(payload) { + if (!game.user.isActiveGM) { return }; + + // Assert payload validity + const { value, delta } = payload; + if (value == null && delta == null) { + ui.notifications.error(localizer( + `RipCrypt.notifs.error.malformed-socket-payload`, + { + event: `updateSands`, + details: `Either value or delta must be provided`, + }, + )); + return; + }; + + // Take action + if (value != null) { + const initial = game.settings.get(game.system.id, `sandsOfFateInitial`); + let sands = clamp(0, value, initial); + if (sands === 0) { + ui.delveDice.alertCrypticEvent(); + sands = initial; + }; + game.settings.set( + game.system.id, + `sandsOfFate`, + sands, + ); + } else if (delta != null) { + ui.delveDice.sandsOfFateDelta(delta); + }; +}; diff --git a/module/utils/clamp.mjs b/module/utils/clamp.mjs new file mode 100644 index 0000000..94cac4e --- /dev/null +++ b/module/utils/clamp.mjs @@ -0,0 +1,3 @@ +export function clamp(min, ideal, max) { + return Math.max(min, Math.min(ideal, max)); +};