First version with variables that actually work
This commit is contained in:
parent
5116b82e77
commit
e65e8b2097
11 changed files with 250 additions and 50 deletions
|
@ -34,6 +34,8 @@ import { handleMenuItemRegistrationEvent, isMenuItemRegisterIframeEvent } from "
|
|||
import { SetTilesEvent, isSetTilesEvent } from "./Events/SetTilesEvent";
|
||||
import { isSetVariableIframeEvent, SetVariableEvent } from "./Events/SetVariableEvent";
|
||||
|
||||
type AnswererCallback<T extends keyof IframeQueryMap> = (query: IframeQueryMap[T]['query']) => IframeQueryMap[T]['answer']|PromiseLike<IframeQueryMap[T]['answer']>;
|
||||
|
||||
/**
|
||||
* Listens to messages from iframes and turn those messages into easy to use observables.
|
||||
* Also allows to send messages to those iframes.
|
||||
|
@ -111,12 +113,10 @@ class IframeListener {
|
|||
private sendPlayerMove: boolean = false;
|
||||
|
||||
|
||||
// Note: we are forced to type this in "any" because of https://github.com/microsoft/TypeScript/issues/31904
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
private answerers: any = {};
|
||||
/*private answerers: {
|
||||
[key in keyof IframeQueryMap]?: (query: IframeQueryMap[key]['query']) => IframeQueryMap[key]['answer']|PromiseLike<IframeQueryMap[key]['answer']>
|
||||
} = {};*/
|
||||
// Note: we are forced to type this in unknown and later cast with "as" because of https://github.com/microsoft/TypeScript/issues/31904
|
||||
private answerers: {
|
||||
[str in keyof IframeQueryMap]?: unknown
|
||||
} = {};
|
||||
|
||||
|
||||
init() {
|
||||
|
@ -156,7 +156,7 @@ class IframeListener {
|
|||
const queryId = payload.id;
|
||||
const query = payload.query;
|
||||
|
||||
const answerer = this.answerers[query.type];
|
||||
const answerer = this.answerers[query.type] as AnswererCallback<keyof IframeQueryMap> | undefined;
|
||||
if (answerer === undefined) {
|
||||
const errorMsg = 'The iFrame sent a message of type "'+query.type+'" but there is no service configured to answer these messages.';
|
||||
console.error(errorMsg);
|
||||
|
@ -432,7 +432,7 @@ class IframeListener {
|
|||
* @param key The "type" of the query we are answering
|
||||
* @param callback
|
||||
*/
|
||||
public registerAnswerer<T extends keyof IframeQueryMap>(key: T, callback: (query: IframeQueryMap[T]['query']) => IframeQueryMap[T]['answer']|PromiseLike<IframeQueryMap[T]['answer']> ): void {
|
||||
public registerAnswerer<T extends keyof IframeQueryMap>(key: T, callback: AnswererCallback<T> ): void {
|
||||
this.answerers[key] = callback;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ export enum EventMessage {
|
|||
TELEPORT = "teleport",
|
||||
USER_MESSAGE = "user-message",
|
||||
START_JITSI_ROOM = "start-jitsi-room",
|
||||
SET_VARIABLE = "set-variable",
|
||||
}
|
||||
|
||||
export interface PointInterface {
|
||||
|
@ -105,6 +106,7 @@ export interface RoomJoinedMessageInterface {
|
|||
//users: MessageUserPositionInterface[],
|
||||
//groups: GroupCreatedUpdatedMessageInterface[],
|
||||
items: { [itemId: number]: unknown };
|
||||
variables: Map<string, unknown>;
|
||||
}
|
||||
|
||||
export interface PlayGlobalMessageInterface {
|
||||
|
|
|
@ -165,6 +165,9 @@ export class RoomConnection implements RoomConnection {
|
|||
} else if (subMessage.hasEmoteeventmessage()) {
|
||||
const emoteMessage = subMessage.getEmoteeventmessage() as EmoteEventMessage;
|
||||
emoteEventStream.fire(emoteMessage.getActoruserid(), emoteMessage.getEmote());
|
||||
} else if (subMessage.hasVariablemessage()) {
|
||||
event = EventMessage.SET_VARIABLE;
|
||||
payload = subMessage.getVariablemessage();
|
||||
} else {
|
||||
throw new Error("Unexpected batch message type");
|
||||
}
|
||||
|
@ -174,6 +177,7 @@ export class RoomConnection implements RoomConnection {
|
|||
}
|
||||
}
|
||||
} else if (message.hasRoomjoinedmessage()) {
|
||||
console.error('COUCOU')
|
||||
const roomJoinedMessage = message.getRoomjoinedmessage() as RoomJoinedMessage;
|
||||
|
||||
const items: { [itemId: number]: unknown } = {};
|
||||
|
@ -181,6 +185,11 @@ export class RoomConnection implements RoomConnection {
|
|||
items[item.getItemid()] = JSON.parse(item.getStatejson());
|
||||
}
|
||||
|
||||
const variables = new Map<string, unknown>();
|
||||
for (const variable of roomJoinedMessage.getVariableList()) {
|
||||
variables.set(variable.getName(), JSON.parse(variable.getValue()));
|
||||
}
|
||||
|
||||
this.userId = roomJoinedMessage.getCurrentuserid();
|
||||
this.tags = roomJoinedMessage.getTagList();
|
||||
|
||||
|
@ -188,6 +197,7 @@ export class RoomConnection implements RoomConnection {
|
|||
connection: this,
|
||||
room: {
|
||||
items,
|
||||
variables,
|
||||
} as RoomJoinedMessageInterface,
|
||||
});
|
||||
} else if (message.hasWorldfullmessage()) {
|
||||
|
@ -634,6 +644,18 @@ export class RoomConnection implements RoomConnection {
|
|||
});
|
||||
}
|
||||
|
||||
public onSetVariable(callback: (name: string, value: unknown) => void): void {
|
||||
this.onMessage(EventMessage.SET_VARIABLE, (message: VariableMessage) => {
|
||||
const name = message.getName();
|
||||
const serializedValue = message.getValue();
|
||||
let value: unknown = undefined;
|
||||
if (serializedValue) {
|
||||
value = JSON.parse(serializedValue);
|
||||
}
|
||||
callback(name, value);
|
||||
});
|
||||
}
|
||||
|
||||
public hasTag(tag: string): boolean {
|
||||
return this.tags.includes(tag);
|
||||
}
|
||||
|
|
|
@ -707,7 +707,7 @@ export class GameScene extends DirtyScene {
|
|||
});
|
||||
|
||||
// Set up variables manager
|
||||
this.sharedVariablesManager = new SharedVariablesManager(this.connection, this.gameMap);
|
||||
this.sharedVariablesManager = new SharedVariablesManager(this.connection, this.gameMap, onConnect.room.variables);
|
||||
|
||||
//this.initUsersPosition(roomJoinedMessage.users);
|
||||
this.connectionAnswerPromiseResolve(onConnect.room);
|
||||
|
|
|
@ -7,6 +7,7 @@ import type {Subscription} from "rxjs";
|
|||
import type {GameMap} from "./GameMap";
|
||||
import type {ITile, ITiledMapObject} from "../Map/ITiledMap";
|
||||
import type {Var} from "svelte/types/compiler/interfaces";
|
||||
import {init} from "svelte/internal";
|
||||
|
||||
interface Variable {
|
||||
defaultValue: unknown,
|
||||
|
@ -18,7 +19,7 @@ export class SharedVariablesManager {
|
|||
private _variables = new Map<string, unknown>();
|
||||
private variableObjects: Map<string, Variable>;
|
||||
|
||||
constructor(private roomConnection: RoomConnection, private gameMap: GameMap) {
|
||||
constructor(private roomConnection: RoomConnection, private gameMap: GameMap, serverVariables: Map<string, unknown>) {
|
||||
// We initialize the list of variable object at room start. The objects cannot be edited later
|
||||
// (otherwise, this would cause a security issue if the scripting API can edit this list of objects)
|
||||
this.variableObjects = SharedVariablesManager.findVariablesInMap(gameMap);
|
||||
|
@ -28,6 +29,22 @@ export class SharedVariablesManager {
|
|||
this._variables.set(name, variableObject.defaultValue);
|
||||
}
|
||||
|
||||
// Override default values with the variables from the server:
|
||||
for (const [name, value] of serverVariables) {
|
||||
this._variables.set(name, value);
|
||||
}
|
||||
|
||||
roomConnection.onSetVariable((name, value) => {
|
||||
console.log('Set Variable received from server');
|
||||
this._variables.set(name, value);
|
||||
|
||||
// On server change, let's notify the iframes
|
||||
iframeListener.setVariable({
|
||||
key: name,
|
||||
value: value,
|
||||
})
|
||||
});
|
||||
|
||||
// When a variable is modified from an iFrame
|
||||
iframeListener.registerAnswerer('setVariable', (event) => {
|
||||
const key = event.key;
|
||||
|
@ -48,7 +65,8 @@ export class SharedVariablesManager {
|
|||
}
|
||||
|
||||
this._variables.set(key, event.value);
|
||||
// TODO: dispatch to the room connection.
|
||||
|
||||
// Dispatch to the room connection.
|
||||
this.roomConnection.emitSetVariableEvent(key, event.value);
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue