fix(chat): relance des dés accessible aux joueurs sur Foundry v14

- Correction du check d'autorisation : message.user -> message.author
  (champ renommé en v12+, message.user est undefined sur v14)
- Les joueurs ne peuvent plus mettre à jour les ChatMessages (permission
  OWNER, option Modifier retirée du menu contextuel en v12+) : la relance
  (dé et effort) est relayée via le socket system.vermine2047 et appliquée
  par le client MJ (registerRerollSocket), avec vérification de l'auteur
- Ajout de la déclaration "socket": true au system.json (requise par le
  serveur pour écouter le namespace system.<id>)
This commit is contained in:
2026-08-09 08:31:09 +02:00
parent 9ab2c6b01a
commit edd1819c86
3 changed files with 65 additions and 14 deletions
+3 -3
View File
@@ -67,9 +67,9 @@ export const registerHooks = function () {
}
})
Hooks.once("ready", async () => {
// System initialized
//await registerTours();
// Relays player rerolls to the GM client (Foundry v14 ChatMessage
// updates are GM-only).
VermineUtils.registerRerollSocket();
});
// changement de la pause
+61 -11
View File
@@ -204,9 +204,10 @@ export class VermineUtils {
* @returns {Promise<boolean>} Whether the reroll was successful
*/
static async onReroll(message, target) {
// Verify user permissions
const msgUserId = message.user?.id ?? message.user;
if (msgUserId !== game.user?.id && !game.user?.isGM) {
// Verify user permissions. Foundry v14 renamed the ChatMessage field
// `user` to `author`, so `message.user` is undefined on this core.
const msgAuthorId = message.author?.id ?? message.user?.id ?? message.user;
if (msgAuthorId !== game.user?.id && !game.user?.isGM) {
ui.notifications.warn(game.i18n.localize('VERMINE.error_cannot_reroll'));
return false;
}
@@ -231,9 +232,6 @@ export class VermineUtils {
target.classList.add('rerolled');
// Set reroll flag
await message.setFlag("world", "reroll", true);
// Get difficulty and dice type
const ulElement = target.closest('ul');
const difficulty = ulElement?.dataset.difficulty ?? 7;
@@ -331,14 +329,55 @@ export class VermineUtils {
+ mk('adapted', stats.adapted.count, stats.adapted.success);
}
await message.update({
content: messageContent.outerHTML
});
// Persist the reroll. The GM writes the message directly ; players
// cannot update ChatMessages on Foundry v14 (permission "OWNER"), so
// their reroll is relayed through the system socket and applied by the
// GM client (see registerRerollSocket).
if (game.user?.isGM) {
await message.setFlag("world", "reroll", true);
await message.update({
content: messageContent.outerHTML
});
} else {
game.socket?.emit(`system.${game.system.id}`, {
type: "reroll",
messageId: message.id,
requestId: foundry.utils.randomID(8),
content: messageContent.outerHTML
});
}
}
return true;
}
/**
* Registers the system socket listener which applies rerolls requested by
* players. Foundry v14 only allows GMs to update ChatMessages, so player
* rerolls are relayed to the GM client through `system.<id>` (see onReroll).
* Call once after the world is ready; re-registration replaces the handler.
*/
static registerRerollSocket() {
const eventName = `system.${game.system.id}`;
const handler = async (payload, userId) => {
if (!game.user?.isGM) return;
if (payload?.type !== "reroll") return;
const message = game.messages.get(payload.messageId);
if (!message) return;
// Security: only the message author may request the reroll update.
if (message.author?.id !== userId) return;
await message.setFlag("world", "reroll", true);
await message.update({ content: payload.content });
};
if (VermineUtils.#rerollSocketHandler) {
game.socket?.off(eventName, VermineUtils.#rerollSocketHandler);
}
VermineUtils.#rerollSocketHandler = handler;
game.socket?.on(eventName, handler);
}
static #rerollSocketHandler;
/**
* Sets up event listeners for chat messages.
* @param {HTMLElement} html - The HTML element containing chat events.
@@ -396,8 +435,19 @@ export class VermineUtils {
const rollMessage = btn.closest(".vermine-roll-message");
if (rollMessage) {
const content = rollMessage.outerHTML;
const message = await game.messages.get(messageId);
await message.update({ content: content });
// GM applies the update directly ; players relay through the
// system socket (Foundry v14 ChatMessage updates are GM-only).
if (game.user?.isGM) {
const message = await game.messages.get(messageId);
await message.update({ content: content });
} else {
game.socket?.emit(`system.${game.system.id}`, {
type: "reroll",
messageId: messageId,
requestId: foundry.utils.randomID(8),
content: content
});
}
}
}
});
+1
View File
@@ -168,6 +168,7 @@
"distance": 1,
"units": "m"
},
"socket": true,
"primaryTokenAttribute": "health",
"secondaryTokenAttribute": "power",
"url": "https://www.uberwald.me/gitea/uberwald/vermine2047",