From cb78ff333bb62f2c896ea5f30ba60f1290c24f58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Tue, 6 Jul 2021 10:58:12 +0200 Subject: [PATCH] Adding client side check of setVariable with writableBy property --- front/src/Connexion/RoomConnection.ts | 13 +++++- .../src/Phaser/Game/SharedVariablesManager.ts | 38 ++++++++++++++++-- maps/tests/Variables/script.js | 13 ++++-- maps/tests/Variables/variables.json | 40 ++++++++++++++++++- messages/protos/messages.proto | 2 +- 5 files changed, 95 insertions(+), 11 deletions(-) diff --git a/front/src/Connexion/RoomConnection.ts b/front/src/Connexion/RoomConnection.ts index 1b080a55..c2d4157b 100644 --- a/front/src/Connexion/RoomConnection.ts +++ b/front/src/Connexion/RoomConnection.ts @@ -31,7 +31,7 @@ import { EmoteEventMessage, EmotePromptMessage, SendUserMessage, - BanUserMessage, + BanUserMessage, VariableMessage, } from "../Messages/generated/messages_pb"; import type { UserSimplePeerInterface } from "../WebRtc/SimplePeer"; @@ -536,6 +536,17 @@ export class RoomConnection implements RoomConnection { this.socket.send(clientToServerMessage.serializeBinary().buffer); } + emitSetVariableEvent(name: string, value: unknown): void { + const variableMessage = new VariableMessage(); + variableMessage.setName(name); + variableMessage.setValue(JSON.stringify(value)); + + const clientToServerMessage = new ClientToServerMessage(); + clientToServerMessage.setVariablemessage(variableMessage); + + this.socket.send(clientToServerMessage.serializeBinary().buffer); + } + onActionableEvent(callback: (message: ItemEventMessageInterface) => void): void { this.onMessage(EventMessage.ITEM_EVENT, (message: ItemEventMessage) => { callback({ diff --git a/front/src/Phaser/Game/SharedVariablesManager.ts b/front/src/Phaser/Game/SharedVariablesManager.ts index 283eb5c3..284dec1d 100644 --- a/front/src/Phaser/Game/SharedVariablesManager.ts +++ b/front/src/Phaser/Game/SharedVariablesManager.ts @@ -9,7 +9,9 @@ import type {ITile, ITiledMapObject} from "../Map/ITiledMap"; import type {Var} from "svelte/types/compiler/interfaces"; interface Variable { - defaultValue: unknown + defaultValue: unknown, + readableBy?: string, + writableBy?: string, } export class SharedVariablesManager { @@ -30,15 +32,24 @@ export class SharedVariablesManager { iframeListener.registerAnswerer('setVariable', (event) => { const key = event.key; - if (!this.variableObjects.has(key)) { + const object = this.variableObjects.get(key); + + if (object === undefined) { const errMsg = 'A script is trying to modify variable "'+key+'" but this variable is not defined in the map.' + 'There should be an object in the map whose name is "'+key+'" and whose type is "variable"'; console.error(errMsg); throw new Error(errMsg); } + if (object.writableBy && !this.roomConnection.hasTag(object.writableBy)) { + const errMsg = 'A script is trying to modify variable "'+key+'" but this variable is only writable for users with tag "'+object.writableBy+'".'; + console.error(errMsg); + throw new Error(errMsg); + } + this._variables.set(key, event.value); // TODO: dispatch to the room connection. + this.roomConnection.emitSetVariableEvent(key, event.value); }); } @@ -68,8 +79,27 @@ export class SharedVariablesManager { if (object.properties) { for (const property of object.properties) { - if (property.name === 'default') { - variable.defaultValue = property.value; + const value = property.value; + switch (property.name) { + case 'default': + variable.defaultValue = value; + break; + case 'writableBy': + if (typeof value !== 'string') { + throw new Error('The writableBy property of variable "'+object.name+'" must be a string'); + } + if (value) { + variable.writableBy = value; + } + break; + case 'readableBy': + if (typeof value !== 'string') { + throw new Error('The readableBy property of variable "'+object.name+'" must be a string'); + } + if (value) { + variable.readableBy = value; + } + break; } } } diff --git a/maps/tests/Variables/script.js b/maps/tests/Variables/script.js index ea381018..120a4425 100644 --- a/maps/tests/Variables/script.js +++ b/maps/tests/Variables/script.js @@ -7,9 +7,14 @@ WA.onInit().then(() => { console.log('Successfully caught error: ', e); }); - console.log('Trying to set variable "config". This should work.'); - WA.room.saveVariable('config', {'foo': 'bar'}); + console.log('Trying to set variable "myvar". This should work.'); + WA.room.saveVariable('myvar', {'foo': 'bar'}); - console.log('Trying to read variable "config". This should display a {"foo": "bar"} object.'); - console.log(WA.room.loadVariable('config')); + console.log('Trying to read variable "myvar". This should display a {"foo": "bar"} object.'); + console.log(WA.room.loadVariable('myvar')); + + console.log('Trying to set variable "config". This should not work because we are not logged as admin.'); + WA.room.saveVariable('config', {'foo': 'bar'}).catch(e => { + console.log('Successfully caught error because variable "config" is not writable: ', e); + }); }); diff --git a/maps/tests/Variables/variables.json b/maps/tests/Variables/variables.json index d74e90cc..79ca591b 100644 --- a/maps/tests/Variables/variables.json +++ b/maps/tests/Variables/variables.json @@ -104,6 +104,44 @@ "width":0, "x":131.38069962269, "y":106.004988169086 + }, + { + "height":0, + "id":9, + "name":"myvar", + "point":true, + "properties":[ + { + "name":"default", + "type":"string", + "value":"{}" + }, + { + "name":"jsonSchema", + "type":"string", + "value":"{}" + }, + { + "name":"persist", + "type":"bool", + "value":true + }, + { + "name":"readableBy", + "type":"string", + "value":"" + }, + { + "name":"writableBy", + "type":"string", + "value":"" + }], + "rotation":0, + "type":"variable", + "visible":true, + "width":0, + "x":88.8149900876127, + "y":147.75212636695 }], "opacity":1, "type":"objectgroup", @@ -112,7 +150,7 @@ "y":0 }], "nextlayerid":8, - "nextobjectid":9, + "nextobjectid":10, "orientation":"orthogonal", "properties":[ { diff --git a/messages/protos/messages.proto b/messages/protos/messages.proto index a9483dd9..30882cd9 100644 --- a/messages/protos/messages.proto +++ b/messages/protos/messages.proto @@ -186,7 +186,7 @@ message RoomJoinedMessage { repeated ItemStateMessage item = 3; int32 currentUserId = 4; repeated string tag = 5; - repeated VariableMessage = 6; + repeated VariableMessage variable = 6; } message WebRtcStartMessage {