Closed barrucadu closed 1 year ago
Alright, so I see this might not actually be possible, since I don't see a way to make a scene flag editable by a normal user without also giving them access to everything else.
One technique I have seen in other modules is to send messages, via socket, from player clients to a connected GM client. This allows the player clients to proxy actions through the GM.
I had a go at this using socketlib, and came up with something incomplete but functional enough for my needs (probably):
diff --git a/classes/OverlayLayer.js b/classes/OverlayLayer.js
index f4025ac..5cbff22 100644
--- a/classes/OverlayLayer.js
+++ b/classes/OverlayLayer.js
@@ -156,28 +156,13 @@ export default class OverlayLayer extends CanvasLayer {
* Add buffered history stack to scene flag and clear buffer
*/
async commitHistory () {
- // Do nothing if no history to be committed, otherwise get history
if (this.historyBuffer.length === 0) return;
if (this.lock) return;
this.lock = true;
- let history = canvas.scene.getFlag(this.layername, "history");
- // If history storage doesn't exist, create it
- if (!history) {
- history = {
- events: [],
- pointer: 0,
- };
+ if (await canvas.polmapSocket.executeAsGM("commit", this.historyBuffer)) {
+ polmapLog(`Pushed ${this.historyBuffer.length} updates (via GM socket).`);
+ this.historyBuffer = [];
}
- // If pointer is less than history length (f.x. user undo), truncate history
- history.events = history.events.slice(0, history.pointer);
- // Push the new history buffer to the scene
- history.events.push(this.historyBuffer);
- history.pointer = history.events.length;
- await canvas.scene.unsetFlag(this.layername, "history");
- await this.setSetting("history", history);
- polmapLog(`Pushed ${this.historyBuffer.length} updates.`);
- // Clear the history buffer
- this.historyBuffer = [];
this.lock = false;
}
diff --git a/classes/PaletteControls.js b/classes/PaletteControls.js
index e30e03b..9f4bba2 100644
--- a/classes/PaletteControls.js
+++ b/classes/PaletteControls.js
@@ -15,7 +15,7 @@ export default class PaletteControls extends FormApplication {
submitOnChange: true,
submitOnClose: true,
popOut: false,
- editable: game.user.isGM,
+ editable: true,
template: "modules/polmap/templates/palette-controls.hbs",
id: "filter-config",
title: game.i18n.localize("POLMAP.Political Map Options"),
diff --git a/js/controls.js b/js/controls.js
index eb074d9..1399363 100644
--- a/js/controls.js
+++ b/js/controls.js
@@ -11,14 +11,16 @@ const _doCacheControls = () => {
* Add control buttons
*/
Hooks.on("getSceneControlButtons", (controls) => {
- if (!game.user.isGM) return;
- controls.push({
- name: "polmap",
- title: game.i18n.localize("POLMAP.Political Map Overlay"),
- icon: "fas fa-handshake",
- layer: "polmap",
- activeTool: "grid",
- tools: [
+ let tools = [
+ {
+ name: "grid",
+ title: game.i18n.localize("POLMAP.Marker Tool"),
+ icon: "fas fa-border-none",
+ }
+ ];
+
+ if (game.user.isGM) {
+ tools = [
{
name: "polmaptoggle",
title: game.i18n.localize("POLMAP.Enable/Disable Political Map Overlay"),
@@ -68,7 +70,16 @@ Hooks.on("getSceneControlButtons", (controls) => {
},
button: true,
},
- ],
+ ];
+ }
+
+ controls.push({
+ name: "polmap",
+ title: game.i18n.localize("POLMAP.Political Map Overlay"),
+ icon: "fas fa-handshake",
+ layer: "polmap",
+ activeTool: "grid",
+ tools: tools,
});
});
diff --git a/js/polmap.js b/js/polmap.js
index ad0f333..b65d678 100644
--- a/js/polmap.js
+++ b/js/polmap.js
@@ -24,6 +24,33 @@ Hooks.once("canvasInit", () => {
}});
});
+Hooks.once("socketlib.ready", () => {
+ canvas.polmapSocket = socketlib.registerModule("polmap");
+ canvas.polmapSocket.register("commit", async (historyBuffer) => {
+ if (historyBuffer.length === 0) return true;
+ if (canvas.scene.getFlag("polmap", "history_lock") === true) return false;
+ await canvas.scene.setFlag("polmap", "history_lock", true);
+ let history = canvas.scene.getFlag("polmap", "history");
+ // If history storage doesn't exist, create it
+ if (!history) {
+ history = {
+ events: [],
+ pointer: 0,
+ };
+ }
+ // If pointer is less than history length (f.x. user undo), truncate history
+ history.events = history.events.slice(0, history.pointer);
+ // Push the new history buffer to the scene
+ history.events.push(historyBuffer);
+ history.pointer = history.events.length;
+ await canvas.scene.setFlag("polmap", "history", history);
+ await canvas.scene.setFlag("polmap", "history_lock", false);
+ polmapLog(`Pushed ${historyBuffer.length} updates.`);
+
+ return true;
+ });
+});
+
Hooks.once("ready", () => {
PoliticalMapMigrations.check().then(() => polmapLog("Migrations complete!"));
});
diff --git a/module.json b/module.json
index cdbf334..fc38481 100644
--- a/module.json
+++ b/module.json
@@ -27,5 +27,11 @@
],
"styles": [
"css/main.css"
- ]
+ ],
+ "dependencies": [
+ {
+ "name": "socketlib"
+ }
+ ],
+ "socket": true
}
This is a great little module, and looks like it'll be very handy for a West Marches-style hexcrawl, where the players are mapping out the terrain as they go. I can give them a blank map, and give them GM permissions, and they can colour hexes as they explore them.
But it would be even better if I didn't need to make them GMs, if I could let players or trusted players access the map controls directly.
~I'll probably just fork this module and comment out the GM check, rather than implement the config myself, but I think it would be handy to have the configuration in the module.~