Merge pull request #301 from thecodingmachine/room_refactoring
Refactoring Room.ts to fetch map url automatically from ID
This commit is contained in:
commit
4ca2876b31
8 changed files with 119 additions and 66 deletions
|
@ -25,7 +25,6 @@ import {
|
||||||
RoomJoinedMessage,
|
RoomJoinedMessage,
|
||||||
ItemStateMessage,
|
ItemStateMessage,
|
||||||
ServerToClientMessage,
|
ServerToClientMessage,
|
||||||
SetUserIdMessage,
|
|
||||||
SilentMessage,
|
SilentMessage,
|
||||||
WebRtcSignalToClientMessage,
|
WebRtcSignalToClientMessage,
|
||||||
WebRtcSignalToServerMessage,
|
WebRtcSignalToServerMessage,
|
||||||
|
@ -228,16 +227,6 @@ export class IoSocketController {
|
||||||
|
|
||||||
// Let's join the room
|
// Let's join the room
|
||||||
this.handleJoinRoom(client, client.roomId, client.position, client.viewport, client.name, client.characterLayers);
|
this.handleJoinRoom(client, client.roomId, client.position, client.viewport, client.name, client.characterLayers);
|
||||||
|
|
||||||
const setUserIdMessage = new SetUserIdMessage();
|
|
||||||
setUserIdMessage.setUserid(client.userId);
|
|
||||||
|
|
||||||
const serverToClientMessage = new ServerToClientMessage();
|
|
||||||
serverToClientMessage.setSetuseridmessage(setUserIdMessage);
|
|
||||||
|
|
||||||
if (!client.disconnecting) {
|
|
||||||
client.send(serverToClientMessage.serializeBinary().buffer, true);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
message: (ws, arrayBuffer, isBinary): void => {
|
message: (ws, arrayBuffer, isBinary): void => {
|
||||||
const client = ws as ExSocketInterface;
|
const client = ws as ExSocketInterface;
|
||||||
|
@ -363,6 +352,8 @@ export class IoSocketController {
|
||||||
roomJoinedMessage.addItem(itemStateMessage);
|
roomJoinedMessage.addItem(itemStateMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
roomJoinedMessage.setCurrentuserid(client.userId);
|
||||||
|
|
||||||
const serverToClientMessage = new ServerToClientMessage();
|
const serverToClientMessage = new ServerToClientMessage();
|
||||||
serverToClientMessage.setRoomjoinedmessage(roomJoinedMessage);
|
serverToClientMessage.setRoomjoinedmessage(roomJoinedMessage);
|
||||||
|
|
||||||
|
|
|
@ -29,37 +29,41 @@ class ConnectionManager {
|
||||||
const roomSlug = data.roomSlug;
|
const roomSlug = data.roomSlug;
|
||||||
urlManager.editUrlForRoom(roomSlug, organizationSlug, worldSlug);
|
urlManager.editUrlForRoom(roomSlug, organizationSlug, worldSlug);
|
||||||
|
|
||||||
const room = new Room(window.location.pathname, data.mapUrlStart)
|
const room = new Room(window.location.pathname);
|
||||||
return Promise.resolve(room);
|
return Promise.resolve(room);
|
||||||
} else if (connexionType === GameConnexionTypes.anonymous) {
|
} else if (connexionType === GameConnexionTypes.anonymous || connexionType === GameConnexionTypes.empty) {
|
||||||
const localUser = localUserStore.getLocalUser();
|
const localUser = localUserStore.getLocalUser();
|
||||||
|
|
||||||
if (localUser) {
|
if (localUser && localUser.jwtToken && localUser.uuid) {
|
||||||
this.localUser = localUser
|
this.localUser = localUser
|
||||||
} else {
|
} else {
|
||||||
const data = await Axios.post(`${API_URL}/anonymLogin`).then(res => res.data);
|
const data = await Axios.post(`${API_URL}/anonymLogin`).then(res => res.data);
|
||||||
this.localUser = new LocalUser(data.userUuid, data.authToken);
|
this.localUser = new LocalUser(data.userUuid, data.authToken);
|
||||||
localUserStore.saveUser(this.localUser);
|
localUserStore.saveUser(this.localUser);
|
||||||
}
|
}
|
||||||
const room = new Room(window.location.pathname, urlManager.getAnonymousMapUrlStart())
|
let roomId: string
|
||||||
|
if (connexionType === GameConnexionTypes.empty) {
|
||||||
|
const defaultMapUrl = window.location.host.replace('play.', 'maps.') + URL_ROOM_STARTED;
|
||||||
|
roomId = urlManager.editUrlForRoom(defaultMapUrl, null, null);
|
||||||
|
} else {
|
||||||
|
roomId = window.location.pathname;
|
||||||
|
}
|
||||||
|
const room = new Room(roomId);
|
||||||
return Promise.resolve(room);
|
return Promise.resolve(room);
|
||||||
} else if (connexionType == GameConnexionTypes.organization) {
|
} else if (connexionType == GameConnexionTypes.organization) {
|
||||||
const localUser = localUserStore.getLocalUser();
|
const localUser = localUserStore.getLocalUser();
|
||||||
|
|
||||||
if (localUser) {
|
if (localUser) {
|
||||||
this.localUser = localUser
|
this.localUser = localUser
|
||||||
//todo: ask the node api for the correct starting map Url from its slug
|
const room = new Room(window.location.pathname);
|
||||||
return Promise.reject('Case not handled: need to get the map\'s url from its slug');
|
return Promise.resolve(room);
|
||||||
} else {
|
} else {
|
||||||
//todo: find some kind of fallback?
|
//todo: find some kind of fallback?
|
||||||
return Promise.reject('Could not find a user in localstorage');
|
return Promise.reject('Could not find a user in localstorage');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo: cleaner way to handle the default case
|
return Promise.reject('Invalid URL');
|
||||||
const defaultMapUrl = window.location.host.replace('api.', 'maps.') + URL_ROOM_STARTED;
|
|
||||||
const defaultRoomId = urlManager.editUrlForRoom(URL_ROOM_STARTED, null, null);
|
|
||||||
return Promise.resolve(new Room(defaultRoomId, defaultMapUrl));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public initBenchmark(): void {
|
public initBenchmark(): void {
|
||||||
|
|
|
@ -1,10 +1,67 @@
|
||||||
|
import Axios from "axios";
|
||||||
|
import {API_URL} from "../Enum/EnvironmentVariable";
|
||||||
|
|
||||||
export class Room {
|
export class Room {
|
||||||
public ID: string;
|
public readonly id: string;
|
||||||
public url: string
|
public readonly isPublic: boolean;
|
||||||
|
private mapUrl: string|undefined;
|
||||||
|
|
||||||
constructor(ID: string, url: string) {
|
constructor(id: string) {
|
||||||
this.ID = ID;
|
if (id.startsWith('/')) {
|
||||||
this.url = url;
|
id = id.substr(1);
|
||||||
|
}
|
||||||
|
this.id = id;
|
||||||
|
if (id.startsWith('_/')) {
|
||||||
|
this.isPublic = true;
|
||||||
|
} else if (id.startsWith('@/')) {
|
||||||
|
this.isPublic = false;
|
||||||
|
} else {
|
||||||
|
throw new Error('Invalid room ID');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getMapUrl(): Promise<string> {
|
||||||
|
return new Promise<string>((resolve, reject) => {
|
||||||
|
if (this.mapUrl !== undefined) {
|
||||||
|
resolve(this.mapUrl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isPublic) {
|
||||||
|
const match = /_\/[^/]+\/(.+)/.exec(this.id);
|
||||||
|
if (!match) throw new Error('Could not extract url from "'+this.id+'"');
|
||||||
|
this.mapUrl = window.location.protocol+'//'+match[1];
|
||||||
|
resolve(this.mapUrl);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// We have a private ID, we need to query the map URL from the server.
|
||||||
|
const urlParts = this.parsePrivateUrl(this.id);
|
||||||
|
|
||||||
|
Axios.get(`${API_URL}/map`, {
|
||||||
|
params: urlParts
|
||||||
|
}).then(({data}) => {
|
||||||
|
console.log('Map ', this.id, ' resolves to URL ', data.mapUrl);
|
||||||
|
resolve(data.mapUrl);
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private parsePrivateUrl(url: string): { organizationSlug: string, worldSlug: string, roomSlug?: string } {
|
||||||
|
const regex = /@\/([^/]+)\/([^/]+)(?:\/([^/]*))?/gm;
|
||||||
|
const match = regex.exec(url);
|
||||||
|
if (!match) {
|
||||||
|
throw new Error('Invalid URL '+url);
|
||||||
|
}
|
||||||
|
const results: { organizationSlug: string, worldSlug: string, roomSlug?: string } = {
|
||||||
|
organizationSlug: match[1],
|
||||||
|
worldSlug: match[2],
|
||||||
|
}
|
||||||
|
if (match[3] !== undefined) {
|
||||||
|
results.roomSlug = match[3];
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -11,7 +11,6 @@ import {
|
||||||
RoomJoinedMessage,
|
RoomJoinedMessage,
|
||||||
ServerToClientMessage,
|
ServerToClientMessage,
|
||||||
SetPlayerDetailsMessage,
|
SetPlayerDetailsMessage,
|
||||||
SetUserIdMessage,
|
|
||||||
SilentMessage, StopGlobalMessage,
|
SilentMessage, StopGlobalMessage,
|
||||||
UserJoinedMessage,
|
UserJoinedMessage,
|
||||||
UserLeftMessage,
|
UserLeftMessage,
|
||||||
|
@ -58,7 +57,7 @@ export class RoomConnection implements RoomConnection {
|
||||||
let url = API_URL.replace('http://', 'ws://').replace('https://', 'wss://');
|
let url = API_URL.replace('http://', 'ws://').replace('https://', 'wss://');
|
||||||
url += '/room';
|
url += '/room';
|
||||||
url += '?roomId='+(roomId ?encodeURIComponent(roomId):'');
|
url += '?roomId='+(roomId ?encodeURIComponent(roomId):'');
|
||||||
url += '?token='+(token ?encodeURIComponent(token):'');
|
url += '&token='+(token ?encodeURIComponent(token):'');
|
||||||
url += '&name='+encodeURIComponent(name);
|
url += '&name='+encodeURIComponent(name);
|
||||||
for (const layer of characterLayers) {
|
for (const layer of characterLayers) {
|
||||||
url += '&characterLayers='+encodeURIComponent(layer);
|
url += '&characterLayers='+encodeURIComponent(layer);
|
||||||
|
@ -124,13 +123,13 @@ export class RoomConnection implements RoomConnection {
|
||||||
items[item.getItemid()] = JSON.parse(item.getStatejson());
|
items[item.getItemid()] = JSON.parse(item.getStatejson());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.userId = roomJoinedMessage.getCurrentuserid();
|
||||||
|
|
||||||
this.dispatch(EventMessage.START_ROOM, {
|
this.dispatch(EventMessage.START_ROOM, {
|
||||||
users,
|
users,
|
||||||
groups,
|
groups,
|
||||||
items
|
items
|
||||||
});
|
});
|
||||||
} else if (message.hasSetuseridmessage()) {
|
|
||||||
this.userId = (message.getSetuseridmessage() as SetUserIdMessage).getUserid();
|
|
||||||
} else if (message.hasErrormessage()) {
|
} else if (message.hasErrormessage()) {
|
||||||
console.error(EventMessage.MESSAGE_ERROR, message.getErrormessage()?.getMessage());
|
console.error(EventMessage.MESSAGE_ERROR, message.getErrormessage()?.getMessage());
|
||||||
} else if (message.hasWebrtcsignaltoclientmessage()) {
|
} else if (message.hasWebrtcsignaltoclientmessage()) {
|
||||||
|
|
|
@ -17,7 +17,7 @@ export class GameManager {
|
||||||
|
|
||||||
public async init(scenePlugin: Phaser.Scenes.ScenePlugin) {
|
public async init(scenePlugin: Phaser.Scenes.ScenePlugin) {
|
||||||
this.startRoom = await connectionManager.initGameConnexion();
|
this.startRoom = await connectionManager.initGameConnexion();
|
||||||
this.loadMap(this.startRoom.url, this.startRoom.ID, scenePlugin);
|
await this.loadMap(this.startRoom, scenePlugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
public setPlayerName(name: string): void {
|
public setPlayerName(name: string): void {
|
||||||
|
@ -41,8 +41,11 @@ export class GameManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public loadMap(mapUrl: string, roomID: string, scenePlugin: Phaser.Scenes.ScenePlugin): void {
|
public async loadMap(room: Room, scenePlugin: Phaser.Scenes.ScenePlugin): Promise<void> {
|
||||||
|
const roomID = room.id;
|
||||||
|
const mapUrl = await room.getMapUrl();
|
||||||
console.log('Loading map '+roomID+' at url '+mapUrl);
|
console.log('Loading map '+roomID+' at url '+mapUrl);
|
||||||
|
|
||||||
const gameIndex = scenePlugin.getIndex(mapUrl);
|
const gameIndex = scenePlugin.getIndex(mapUrl);
|
||||||
if(gameIndex === -1){
|
if(gameIndex === -1){
|
||||||
const game : Phaser.Scene = GameScene.createFromUrl(mapUrl, roomID);
|
const game : Phaser.Scene = GameScene.createFromUrl(mapUrl, roomID);
|
||||||
|
@ -58,9 +61,10 @@ export class GameManager {
|
||||||
return mapUrlStart.substring(startPos, endPos);
|
return mapUrlStart.substring(startPos, endPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
public goToStartingMap(scenePlugin: Phaser.Scenes.ScenePlugin) {
|
public async goToStartingMap(scenePlugin: Phaser.Scenes.ScenePlugin) {
|
||||||
console.log('Starting scene '+this.startRoom.url);
|
const url = await this.startRoom.getMapUrl();
|
||||||
scenePlugin.start(this.startRoom.url, {startLayerName: 'global'});
|
console.log('Starting scene '+url);
|
||||||
|
scenePlugin.start(url, {startLayerName: 'global'});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ import {RoomConnection} from "../../Connexion/RoomConnection";
|
||||||
import {GlobalMessageManager} from "../../Administration/GlobalMessageManager";
|
import {GlobalMessageManager} from "../../Administration/GlobalMessageManager";
|
||||||
import {ConsoleGlobalMessageManager} from "../../Administration/ConsoleGlobalMessageManager";
|
import {ConsoleGlobalMessageManager} from "../../Administration/ConsoleGlobalMessageManager";
|
||||||
import {ResizableScene} from "../Login/ResizableScene";
|
import {ResizableScene} from "../Login/ResizableScene";
|
||||||
|
import {Room} from "../../Connexion/Room";
|
||||||
|
|
||||||
|
|
||||||
export enum Textures {
|
export enum Textures {
|
||||||
|
@ -690,8 +691,13 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: eventually compute a relative URL
|
// TODO: eventually compute a relative URL
|
||||||
|
|
||||||
|
// TODO: handle /@/ URL CASES!
|
||||||
|
|
||||||
const absoluteExitSceneUrl = new URL(exitSceneUrl, this.MapUrlFile).href;
|
const absoluteExitSceneUrl = new URL(exitSceneUrl, this.MapUrlFile).href;
|
||||||
gameManager.loadMap(absoluteExitSceneUrl, instance, this.scene);
|
const absoluteExitSceneUrlWithoutProtocol = absoluteExitSceneUrl.toString().substr(absoluteExitSceneUrl.toString().indexOf('://')+3);
|
||||||
|
const roomId = '_/'+instance+'/'+absoluteExitSceneUrlWithoutProtocol;
|
||||||
|
gameManager.loadMap(new Room(roomId), this.scene);
|
||||||
const exitSceneKey = instance;
|
const exitSceneKey = instance;
|
||||||
|
|
||||||
const tiles : number[] = layer.data as number[];
|
const tiles : number[] = layer.data as number[];
|
||||||
|
|
|
@ -3,6 +3,7 @@ export enum GameConnexionTypes {
|
||||||
anonymous=1,
|
anonymous=1,
|
||||||
organization,
|
organization,
|
||||||
register,
|
register,
|
||||||
|
empty,
|
||||||
unknown,
|
unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,19 +18,14 @@ class UrlManager {
|
||||||
} else if (url.includes('@/')) {
|
} else if (url.includes('@/')) {
|
||||||
return GameConnexionTypes.organization;
|
return GameConnexionTypes.organization;
|
||||||
} else if(url.includes('register/')) {
|
} else if(url.includes('register/')) {
|
||||||
return GameConnexionTypes.register
|
return GameConnexionTypes.register;
|
||||||
|
} else if(url === '/') {
|
||||||
|
return GameConnexionTypes.empty;
|
||||||
} else {
|
} else {
|
||||||
return GameConnexionTypes.unknown
|
return GameConnexionTypes.unknown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public getAnonymousMapUrlStart():string {
|
|
||||||
const match = /\/_\/global\/(.+)/.exec(window.location.pathname.toString())
|
|
||||||
if (!match) throw new Error('Could not extract startmap url from'+window.location.pathname);
|
|
||||||
return window.location.protocol+'//'+match[1];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public getOrganizationToken(): string|null {
|
public getOrganizationToken(): string|null {
|
||||||
const match = /\/register\/(.+)/.exec(window.location.pathname.toString());
|
const match = /\/register\/(.+)/.exec(window.location.pathname.toString());
|
||||||
return match ? match [1] : null;
|
return match ? match [1] : null;
|
||||||
|
|
|
@ -129,10 +129,6 @@ message ErrorMessage {
|
||||||
string message = 1;
|
string message = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SetUserIdMessage {
|
|
||||||
int32 userId = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ItemStateMessage {
|
message ItemStateMessage {
|
||||||
int32 itemId = 1;
|
int32 itemId = 1;
|
||||||
string stateJson = 2;
|
string stateJson = 2;
|
||||||
|
@ -142,6 +138,7 @@ message RoomJoinedMessage {
|
||||||
repeated UserJoinedMessage user = 1;
|
repeated UserJoinedMessage user = 1;
|
||||||
repeated GroupUpdateMessage group = 2;
|
repeated GroupUpdateMessage group = 2;
|
||||||
repeated ItemStateMessage item = 3;
|
repeated ItemStateMessage item = 3;
|
||||||
|
int32 currentUserId = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message WebRtcStartMessage {
|
message WebRtcStartMessage {
|
||||||
|
@ -164,12 +161,11 @@ message ServerToClientMessage {
|
||||||
BatchMessage batchMessage = 1;
|
BatchMessage batchMessage = 1;
|
||||||
ErrorMessage errorMessage = 2;
|
ErrorMessage errorMessage = 2;
|
||||||
RoomJoinedMessage roomJoinedMessage = 3;
|
RoomJoinedMessage roomJoinedMessage = 3;
|
||||||
SetUserIdMessage setUserIdMessage = 4; // TODO: merge this with RoomJoinedMessage ?
|
WebRtcStartMessage webRtcStartMessage = 4;
|
||||||
WebRtcStartMessage webRtcStartMessage = 5;
|
WebRtcSignalToClientMessage webRtcSignalToClientMessage = 5;
|
||||||
WebRtcSignalToClientMessage webRtcSignalToClientMessage = 6;
|
WebRtcSignalToClientMessage webRtcScreenSharingSignalToClientMessage = 6;
|
||||||
WebRtcSignalToClientMessage webRtcScreenSharingSignalToClientMessage = 7;
|
WebRtcDisconnectMessage webRtcDisconnectMessage = 7;
|
||||||
WebRtcDisconnectMessage webRtcDisconnectMessage = 8;
|
PlayGlobalMessage playGlobalMessage = 8;
|
||||||
PlayGlobalMessage playGlobalMessage = 9;
|
StopGlobalMessage stopGlobalMessage = 9;
|
||||||
StopGlobalMessage stopGlobalMessage = 10;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue