Skip to content

Commit

Permalink
Merge pull request #10 from MythicPalette/player-permissions
Browse files Browse the repository at this point in the history
Player permissions
  • Loading branch information
MythicPalette authored Nov 10, 2024
2 parents 1321f0d + 70e57af commit a101df4
Show file tree
Hide file tree
Showing 15 changed files with 262 additions and 58 deletions.
12 changes: 12 additions & 0 deletions lang/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@
"TrackerMaxHeight": {
"Name": "Quest-Log Max Höhe",
"Hint": "Legt die maximale Höhe (in Pixeln) des Quest-Logs fest, wenn es angedockt ist. Hat keine Auswirkung, wenn schwebend."
},
"PlayerCreate": {
"Name": "Spieler erstellen erlauben",
"Hint": "Erlaube es den Spielern, Quests zu erstellen."
},
"PlayerEdit": {
"Name": "Spielern erlauben, GM-Quests zu bearbeiten",
"Hint": "Erlaube es den Spielern, Quests des GM zu bearbeiten. Achtung, dies ermöglicht es den Spielern, die Eingabedaten der Ziele zu sehen, was möglicherweise geheime Ziele enthüllt."
},
"PlayersMark": {
"Name": "Spielern erlauben, GM-Ziele zu markieren",
"Hint": "Erlaube es den Spielern, die Ziele der Quests des GM als abgeschlossen, fehlgeschlagen oder unvollständig zu markieren."
}
},
"Tracker": {
Expand Down
12 changes: 12 additions & 0 deletions lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@
"TrackerMaxHeight": {
"Name": "Tracker Max Height",
"Hint": "Sets the max height (in pixels) of the tracker while docked. Has no effect if not docked."
},
"PlayerCreate": {
"Name": "Allow Player Create",
"Hint": "Allow players to create quests."
},
"PlayerEdit": {
"Name": "Allow Players to Edit GM Quests",
"Hint": "Allow players to edit quests made by the GM. Warning, this will allow players to see objective entry data, potentially revealing secret objectives."
},
"PlayersMark": {
"Name": "Allow Players to Mark GM Objectives",
"Hint": "Allow players to mark the objectives of quests made by the GM as complete, failed, or incomplete."
}
},
"Tracker": {
Expand Down
5 changes: 3 additions & 2 deletions module.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
}
}
],
"version": "v0.1.7",
"version": "v0.1.8",
"compatibility": {
"minimum": "12",
"verified": "12"
Expand All @@ -33,7 +33,8 @@
"styles": ["styles/style.css", "styles/editor.css", "styles/tracker.css"],
"minimumCoreVersion": "12",
"compatibleCoreVersion": "12",
"socket": true,
"url": "https://github.com/MythicPalette/simpler-quests",
"manifest": "https://github.com/MythicPalette/simpler-quests/releases/latest/download/module.json",
"download": "https://github.com/MythicPalette/simpler-quests/releases/download/v0.1.7/module.zip"
"download": "https://github.com/MythicPalette/simpler-quests/releases/download/v0.1.8/module.zip"
}
18 changes: 17 additions & 1 deletion scripts/data/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ export class QuestDatabase extends Collection {
}
}

q.canEdit =
game.user.isGM ||
Settings.get(Settings.NAMES.PLAYER_EDIT) ||
!q.GMQuest;

// Players can never delete GM quests.
q.canDelete = game.user.isGM || !q.GMQuest;

// Return the quest with modified data.
return {
...q,
Expand Down Expand Up @@ -191,8 +199,16 @@ export class QuestDatabase extends Collection {
static refresh() {
this.#quests = Settings.get(Settings.NAMES.QUEST_DB).quests;

// Verify that all quest objectives have an id
// Validate all quest data.
this.#quests.forEach((q, i) => {
// For backwards compatability, if a quest
// does not have the GMQuest flag, add it.
if (!("GMQuest" in q)) {
q.GMQuest = true;
console.log(q);
}

// Ensure that all quest objectives have an id
if (q.objectives)
this.#quests[i] = {
...q,
Expand Down
1 change: 1 addition & 0 deletions scripts/data/quest.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export class Quest {
this.objectives = [];
this.viewStyle =
data.viewStyle || Settings.get(Settings.NAMES.QUEST_VIEW_STYLE);
this.GMQuest = "GMQuest" in data ? data.GMQuest : true; // Default to GM-made quests.

// Go through the objectives in the data and create them.
if (data.objectives) {
Expand Down
73 changes: 73 additions & 0 deletions scripts/helpers/SocketHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { constants } from "./global.js";
import { Quest } from "../data/quest.js";
import { QuestDatabase } from "../data/database.js";
import { UIManager } from "../ui/ui-manager.js";
import { Settings } from "./settings.js";

export class SocketHandler {
identifier = `module.simpler-quests`;

constructor() {
this.registerSocketListeners();
}

registerSocketListeners() {
game.socket?.on(this.identifier, (ev) => {
if (ev.type === "InsertOrUpdate") this.#OnInsertOrUpdate(ev.data);
if (ev.type === "DeleteQuest") this.#OnDeleteQuest(ev.data);
else if (ev.type == "UpdateObjective")
this.#OnUpdateObjective(ev.data);
});
}

emit(type, payload) {
// Add the user to the data for tracking who sent the data.
payload.user = game.user;

const sock = game.socket;
if (sock)
return sock.emit(this.identifier, { type: type, data: payload });
}

#OnInsertOrUpdate(data) {
// If the user isn't a GM, ignore.
if (!game.user.isGM) return;

// If the quest is a GM quest but players aren't allowed
// to edit GM quests, don't allow the edit.
if (data.GMQuest && !Settings.get(Settings.NAMES.PLAYER_EDIT)) return;

console.log(`User ${data.user.id} has edited quest ${data.questId}`);
let q = new Quest(data);
QuestDatabase.InsertOrUpdate(q);
UIManager.tracker.render();
}

#OnDeleteQuest(data) {
// If the user isn't a GM, ignore.
if (!game.user.isGM) return;

// If the quest is a GM quest, players cannot delete it.
if (data.GMQuest) return;

console.log(`User ${data.user.id} has deleted quest ${data.questId}`);
QuestDatabase.removeQuest(data.questId);
}

#OnUpdateObjective(data) {
// If the user isn't a GM, ignore.
if (!game.user.isGM) return;

// Get the quest
var Q = QuestDatabase.getQuest(data.questId);

// If the quest is a GM quest but players aren't allowed
// to mark GM quests, don't allow the mark.
if (Q.GMQuest && !Settings.get(Settings.NAMES.PLAYER_MARK)) return;

console.log(
`User ${data.user.id} has marked quest ${data.questId} objective ${data.objId}`
);
Quest.updateObjective(data.questId, data.objId, "state");
}
}
8 changes: 8 additions & 0 deletions scripts/helpers/global.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,11 @@ export function gmCheck() {
}
return true;
}

var _sock;
export function getSocket() {
return _sock;
}
export function setSocket(socket) {
_sock = socket;
}
33 changes: 33 additions & 0 deletions scripts/helpers/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ export class Settings {
TRACKER_POS: "trackerWindowPosition",
TRACKER_OPEN: "trackerWindowOpen",
TRACKER_HIDE: "trackerHideFromPlayers",
PLAYER_EDIT: "playersEditQuest",
PLAYER_CREATE: "playersCreateQuest",
PLAYER_MARK: "playersMarkObjectives",
});

static registerSettings() {
Expand All @@ -36,6 +39,36 @@ export class Settings {
requiresReload: true,
});

game.settings.register(constants.moduleName, this.NAMES.PLAYER_CREATE, {
name: "SimplerQuests.Settings.PlayerCreate.Name",
hint: "SimplerQuests.Settings.PlayerCreate.Hint",
scope: "world",
type: Boolean,
default: false,
config: true,
requiresReload: true,
});

game.settings.register(constants.moduleName, this.NAMES.PLAYER_EDIT, {
name: "SimplerQuests.Settings.PlayerEdit.Name",
hint: "SimplerQuests.Settings.PlayerEdit.Hint",
scope: "world",
type: Boolean,
default: false,
config: true,
requiresReload: true,
});

game.settings.register(constants.moduleName, this.NAMES.PLAYER_MARK, {
name: "SimplerQuests.Settings.PlayersMark.Name",
hint: "SimplerQuests.Settings.PlayersMark.Hint",
scope: "world",
type: Boolean,
default: false,
config: true,
requiresReload: true,
});

game.settings.register(
constants.moduleName,
this.NAMES.QUEST_VIEW_STYLE,
Expand Down
4 changes: 4 additions & 0 deletions scripts/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { UIManager } from "./ui/ui-manager.js";
import { Settings } from "./helpers/settings.js";
import { HandlebarHelper } from "./helpers/handlebars.js";
import { SimplerQuestsAPI } from "./api.js";
import { setSocket } from "./helpers/global.js";
import { SocketHandler } from "./helpers/socketHandler.js";

Hooks.once("init", (opts) => {
// Start by registering the module settings.
Expand All @@ -13,6 +15,8 @@ Hooks.once("init", (opts) => {

// Prepare the quest tracker.
UIManager.init();

setSocket(new SocketHandler());
});

Hooks.on("ready", async () => {
Expand Down
33 changes: 25 additions & 8 deletions scripts/ui/questeditor.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { constants, objectiveState } from "../helpers/global.js";
import { constants, getSocket, objectiveState } from "../helpers/global.js";
import { QuestDatabase } from "../data/database.js";
import { Quest } from "../data/quest.js";
import { Objective } from "../data/objective.js";
Expand Down Expand Up @@ -33,6 +33,10 @@ export class QuestEditor extends Application {
}
} else {
this.#quest = new Quest();
if (!game.user.isGM) {
this.#quest.visible = true;
this.#quest.GMQuest = false;
}
}
}

Expand Down Expand Up @@ -94,18 +98,30 @@ export class QuestEditor extends Application {
.find("#objective-display-select > .selection-bar > .body")
.data("value");

let q = new Quest({
// Prepare the quest data
let qData = {
id: this.quest.id,
title: title,
objectives: objs,
viewStyle: selectBody,
visible: this.quest.visible,
});

QuestDatabase.InsertOrUpdate(q);
console.log(q);
UIManager.tracker.render();
this.close();
GMQuest: this.quest.GMQuest,
};

// If the user is the GM then save the quest
// TODO Flip this by removing the !
if (game.user.isGM) {
let q = new Quest(qData);

QuestDatabase.InsertOrUpdate(q);
console.log(q);
UIManager.tracker.render();
this.close();
} else {
getSocket().emit("InsertOrUpdate", qData);
UIManager.tracker.render();
this.close();
}
});

// Quest visibility toggle.
Expand All @@ -124,6 +140,7 @@ export class QuestEditor extends Application {
Settings.get(Settings.NAMES.QUEST_VIEW_STYLE);

return foundry.utils.mergeObject(super.getData(), {
isGM: game.user.isGM,
title: "Quest Editor Test",
questTitle: this.quest.title,
objectives: Quest.stringify(this.quest),
Expand Down
Loading

0 comments on commit a101df4

Please sign in to comment.