Merge pull request #428 from thecodingmachine/master
Hotfixes from master
This commit is contained in:
commit
eed292b707
@ -43,6 +43,7 @@ export class IoSocketController {
|
||||
if (token !== ADMIN_API_TOKEN) {
|
||||
console.log('Admin access refused for token: '+token)
|
||||
res.writeStatus("401 Unauthorized").end('Incorrect token');
|
||||
return;
|
||||
}
|
||||
const roomId = query.roomId as string;
|
||||
|
||||
|
@ -1,11 +1,9 @@
|
||||
import {OK} from "http-status-codes";
|
||||
import {URL_ROOM_STARTED} from "../Enum/EnvironmentVariable";
|
||||
import {HttpRequest, HttpResponse, TemplatedApp} from "uWebSockets.js";
|
||||
import {BaseController} from "./BaseController";
|
||||
import {parse} from "query-string";
|
||||
import {adminApi} from "../Services/AdminApi";
|
||||
|
||||
//todo: delete this
|
||||
|
||||
export class MapController extends BaseController{
|
||||
|
||||
constructor(private App : TemplatedApp) {
|
||||
@ -36,18 +34,21 @@ export class MapController extends BaseController{
|
||||
res.writeStatus("400 Bad request");
|
||||
this.addCorsHeaders(res);
|
||||
res.end("Expected organizationSlug parameter");
|
||||
return;
|
||||
}
|
||||
if (typeof query.worldSlug !== 'string') {
|
||||
console.error('Expected worldSlug parameter');
|
||||
res.writeStatus("400 Bad request");
|
||||
this.addCorsHeaders(res);
|
||||
res.end("Expected worldSlug parameter");
|
||||
return;
|
||||
}
|
||||
if (typeof query.roomSlug !== 'string' && query.roomSlug !== undefined) {
|
||||
console.error('Expected only one roomSlug parameter');
|
||||
res.writeStatus("400 Bad request");
|
||||
this.addCorsHeaders(res);
|
||||
res.end("Expected only one roomSlug parameter");
|
||||
return;
|
||||
}
|
||||
|
||||
(async () => {
|
||||
|
@ -33,6 +33,7 @@
|
||||
"ports": [80],
|
||||
"env": {
|
||||
"API_URL": "api."+url,
|
||||
"ADMIN_URL": "admin."+url,
|
||||
"JITSI_URL": env.JITSI_URL,
|
||||
"SECRET_JITSI_KEY": env.SECRET_JITSI_KEY,
|
||||
"TURN_SERVER": "turn:coturn.workadventu.re:443,turns:coturn.workadventu.re:443",
|
||||
|
@ -27,6 +27,7 @@ services:
|
||||
HOST: "0.0.0.0"
|
||||
NODE_ENV: development
|
||||
API_URL: api.workadventure.localhost
|
||||
ADMIN_URL: admin.workadventure.localhost
|
||||
STARTUP_COMMAND_1: yarn install
|
||||
TURN_SERVER: "turn:coturn.workadventu.re:443,turns:coturn.workadventu.re:443"
|
||||
TURN_USER: workadventure
|
||||
|
@ -1,12 +1,12 @@
|
||||
const DEBUG_MODE: boolean = process.env.DEBUG_MODE == "true";
|
||||
const API_URL = (process.env.API_PROTOCOL || (typeof(window) !== 'undefined' ? window.location.protocol : 'http:')) + '//' + (process.env.API_URL || "api.workadventure.localhost");
|
||||
const ADMIN_URL = API_URL.replace('api', 'admin');
|
||||
const ADMIN_URL = (process.env.API_PROTOCOL || (typeof(window) !== 'undefined' ? window.location.protocol : 'http:')) + '//' + (process.env.ADMIN_URL || "admin.workadventure.localhost");
|
||||
const TURN_SERVER: string = process.env.TURN_SERVER || "turn:numb.viagenie.ca";
|
||||
const TURN_USER: string = process.env.TURN_USER || 'g.parant@thecodingmachine.com';
|
||||
const TURN_PASSWORD: string = process.env.TURN_PASSWORD || 'itcugcOHxle9Acqi$';
|
||||
const JITSI_URL : string|undefined = (process.env.JITSI_URL === '') ? undefined : process.env.JITSI_URL;
|
||||
const JITSI_PRIVATE_MODE : boolean = process.env.JITSI_PRIVATE_MODE == "true";
|
||||
const RESOLUTION = 3;
|
||||
const RESOLUTION = 2;
|
||||
const ZOOM_LEVEL = 1/*3/4*/;
|
||||
const POSITION_DELAY = 200; // Wait 200ms between sending position events
|
||||
const MAX_EXTRAPOLATION_TIME = 100; // Extrapolate a maximum of 250ms if no new movement is sent by the player
|
||||
|
@ -342,46 +342,11 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||
throw new Error('Your map MUST contain a layer of type "objectgroup" whose name is "floorLayer" that represents the layer characters are drawn at.');
|
||||
}
|
||||
|
||||
// If there is an init position passed
|
||||
if (this.initPosition !== null) {
|
||||
this.startX = this.initPosition.x;
|
||||
this.startY = this.initPosition.y;
|
||||
} else {
|
||||
// Now, let's find the start layer
|
||||
if (this.room.hash) {
|
||||
for (const layer of this.mapFile.layers) {
|
||||
if (this.room.hash === layer.name && layer.type === 'tilelayer' && this.isStartLayer(layer)) {
|
||||
const startPosition = this.startUser(layer);
|
||||
this.startX = startPosition.x;
|
||||
this.startY = startPosition.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.startX === undefined) {
|
||||
// If we have no start layer specified or if the hash passed does not exist, let's go with the default start position.
|
||||
for (const layer of this.mapFile.layers) {
|
||||
if (layer.type === 'tilelayer' && layer.name === "start") {
|
||||
const startPosition = this.startUser(layer);
|
||||
this.startX = startPosition.x;
|
||||
this.startY = startPosition.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Still no start position? Something is wrong with the map, we need a "start" layer.
|
||||
if (this.startX === undefined) {
|
||||
console.warn('This map is missing a layer named "start" that contains the available default start positions.');
|
||||
// Let's start in the middle of the map
|
||||
this.startX = this.mapFile.width * 16;
|
||||
this.startY = this.mapFile.height * 16;
|
||||
}
|
||||
this.initStartXAndStartY();
|
||||
|
||||
//add entities
|
||||
this.Objects = new Array<Phaser.Physics.Arcade.Sprite>();
|
||||
|
||||
//init event click
|
||||
this.EventToClickOnTile();
|
||||
|
||||
//initialise list of other player
|
||||
this.MapPlayers = this.physics.add.group({immovable: true});
|
||||
|
||||
@ -651,6 +616,40 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||
this.chatModeSprite.setFrame(3);
|
||||
}
|
||||
}
|
||||
|
||||
private initStartXAndStartY() {
|
||||
// If there is an init position passed
|
||||
if (this.initPosition !== null) {
|
||||
this.startX = this.initPosition.x;
|
||||
this.startY = this.initPosition.y;
|
||||
} else {
|
||||
// Now, let's find the start layer
|
||||
if (this.room.hash) {
|
||||
this.initPositionFromLayerName(this.room.hash);
|
||||
}
|
||||
if (this.startX === undefined) {
|
||||
// If we have no start layer specified or if the hash passed does not exist, let's go with the default start position.
|
||||
this.initPositionFromLayerName("start");
|
||||
}
|
||||
}
|
||||
// Still no start position? Something is wrong with the map, we need a "start" layer.
|
||||
if (this.startX === undefined) {
|
||||
console.warn('This map is missing a layer named "start" that contains the available default start positions.');
|
||||
// Let's start in the middle of the map
|
||||
this.startX = this.mapFile.width * 16;
|
||||
this.startY = this.mapFile.height * 16;
|
||||
}
|
||||
}
|
||||
|
||||
private initPositionFromLayerName(layerName: string) {
|
||||
for (const layer of this.mapFile.layers) {
|
||||
if (layerName === layer.name && layer.type === 'tilelayer' && (layerName === "start" || this.isStartLayer(layer))) {
|
||||
const startPosition = this.startUser(layer);
|
||||
this.startX = startPosition.x;
|
||||
this.startY = startPosition.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private getExitUrl(layer: ITiledMapLayer): string|undefined {
|
||||
return this.getProperty(layer, "exitUrl") as string|undefined;
|
||||
@ -690,9 +689,6 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||
instance = this.instance;
|
||||
}
|
||||
|
||||
//console.log('existSceneUrl', exitSceneUrl);
|
||||
//console.log('existSceneInstance', instance);
|
||||
|
||||
const absoluteExitSceneUrl = new URL(exitSceneUrl, this.MapUrlFile).href;
|
||||
const absoluteExitSceneUrlWithoutProtocol = absoluteExitSceneUrl.toString().substr(absoluteExitSceneUrl.toString().indexOf('://')+3);
|
||||
const roomId = '_/'+instance+'/'+absoluteExitSceneUrlWithoutProtocol;
|
||||
@ -710,11 +706,6 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||
this.loadNextGame(layer, mapWidth, fullPath);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param layer
|
||||
* @param mapWidth
|
||||
*/
|
||||
//todo: push that into the gameManager
|
||||
private loadNextGame(layer: ITiledMapLayer, mapWidth: number, roomId: string){
|
||||
|
||||
@ -750,9 +741,6 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param layer
|
||||
*/
|
||||
private startUser(layer: ITiledMapLayer): PositionInterface {
|
||||
const tiles = layer.data;
|
||||
if (typeof(tiles) === 'string') {
|
||||
@ -908,17 +896,6 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||
});
|
||||
}
|
||||
|
||||
EventToClickOnTile(){
|
||||
// debug code to get a tile properties by clicking on it
|
||||
/*this.input.on("pointerdown", (pointer: Phaser.Input.Pointer)=>{
|
||||
//pixel position toz tile position
|
||||
const tile = this.Map.getTileAt(this.Map.worldToTileX(pointer.worldX), this.Map.worldToTileY(pointer.worldY));
|
||||
if(tile){
|
||||
this.CurrentPlayer.say("Your touch " + tile.layer.name);
|
||||
}
|
||||
});*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @param time
|
||||
* @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
|
||||
@ -963,13 +940,19 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||
});
|
||||
|
||||
const nextSceneKey = this.checkToExit();
|
||||
if (nextSceneKey) {
|
||||
if (!nextSceneKey) return;
|
||||
if (nextSceneKey.key !== this.scene.key) {
|
||||
// We are completely destroying the current scene to avoid using a half-backed instance when coming back to the same map.
|
||||
this.connection.closeConnection();
|
||||
this.simplePeer.unregister();
|
||||
this.scene.stop();
|
||||
this.scene.remove(this.scene.key);
|
||||
this.scene.start(nextSceneKey.key);
|
||||
} else {
|
||||
//if the exit points to the current map, we simply teleport the user back to the startLayer
|
||||
this.initPositionFromLayerName(this.room.hash || 'start');
|
||||
this.CurrentPlayer.x = this.startX;
|
||||
this.CurrentPlayer.y = this.startY;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1071,11 +1054,6 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||
await Promise.all(loadPromises);
|
||||
|
||||
player.addTextures(characterLayerList, 1);
|
||||
//init collision
|
||||
/*this.physics.add.collider(this.CurrentPlayer, player, (CurrentPlayer: CurrentGamerInterface, MapPlayer: GamerInterface) => {
|
||||
CurrentPlayer.say("Hello, how are you ? ");
|
||||
});*/
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1118,7 +1096,6 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||
// We do not update the player position directly (because it is sent only every 200ms).
|
||||
// Instead we use the PlayersPositionInterpolator that will do a smooth animation over the next 200ms.
|
||||
const playerMovement = new PlayerMovement({ x: player.x, y: player.y }, this.currentTick, message.position, this.currentTick + POSITION_DELAY);
|
||||
//console.log('Target position: ', player.x, player.y);
|
||||
this.playersPositionInterpolator.updatePlayerPosition(player.userId, playerMovement);
|
||||
}
|
||||
|
||||
@ -1167,11 +1144,6 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||
|
||||
/**
|
||||
* Sends to the server an event emitted by one of the ActionableItems.
|
||||
*
|
||||
* @param itemId
|
||||
* @param eventName
|
||||
* @param state
|
||||
* @param parameters
|
||||
*/
|
||||
emitActionableEvent(itemId: number, eventName: string, state: unknown, parameters: unknown) {
|
||||
this.connection.emitActionableEvent(itemId, eventName, state, parameters);
|
||||
|
@ -20,32 +20,31 @@ class CoWebsiteManager {
|
||||
* Quickly going in and out of an iframe trigger can create conflicts between the iframe states.
|
||||
* So we use this promise to queue up every cowebsite state transition
|
||||
*/
|
||||
private currentOperationPromise: Promise<void> = Promise.resolve();
|
||||
private currentOperationPromise: Promise<void> = Promise.resolve();
|
||||
private cowebsiteDiv: HTMLDivElement;
|
||||
|
||||
private close(): HTMLDivElement {
|
||||
const cowebsiteDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>(cowebsiteDivId);
|
||||
cowebsiteDiv.classList.remove('loaded'); //edit the css class to trigger the transition
|
||||
cowebsiteDiv.classList.add('hidden');
|
||||
constructor() {
|
||||
this.cowebsiteDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>(cowebsiteDivId);
|
||||
}
|
||||
|
||||
private close(): void {
|
||||
this.cowebsiteDiv.classList.remove('loaded'); //edit the css class to trigger the transition
|
||||
this.cowebsiteDiv.classList.add('hidden');
|
||||
this.opened = iframeStates.closed;
|
||||
return cowebsiteDiv;
|
||||
}
|
||||
private load(): HTMLDivElement {
|
||||
const cowebsiteDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>(cowebsiteDivId);
|
||||
cowebsiteDiv.classList.remove('hidden'); //edit the css class to trigger the transition
|
||||
cowebsiteDiv.classList.add('loading');
|
||||
private load(): void {
|
||||
this.cowebsiteDiv.classList.remove('hidden'); //edit the css class to trigger the transition
|
||||
this.cowebsiteDiv.classList.add('loading');
|
||||
this.opened = iframeStates.loading;
|
||||
return cowebsiteDiv;
|
||||
}
|
||||
private open(): HTMLDivElement {
|
||||
const cowebsiteDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>(cowebsiteDivId);
|
||||
cowebsiteDiv.classList.remove('loading', 'hidden'); //edit the css class to trigger the transition
|
||||
private open(): void {
|
||||
this.cowebsiteDiv.classList.remove('loading', 'hidden'); //edit the css class to trigger the transition
|
||||
this.opened = iframeStates.opened;
|
||||
return cowebsiteDiv;
|
||||
}
|
||||
|
||||
public loadCoWebsite(url: string): void {
|
||||
const cowebsiteDiv = this.load();
|
||||
cowebsiteDiv.innerHTML = '';
|
||||
this.load();
|
||||
this.cowebsiteDiv.innerHTML = '';
|
||||
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.id = 'cowebsite-iframe';
|
||||
@ -53,7 +52,7 @@ class CoWebsiteManager {
|
||||
const onloadPromise = new Promise((resolve) => {
|
||||
iframe.onload = () => resolve();
|
||||
});
|
||||
cowebsiteDiv.appendChild(iframe);
|
||||
this.cowebsiteDiv.appendChild(iframe);
|
||||
const onTimeoutPromise = new Promise((resolve) => {
|
||||
setTimeout(() => resolve(), 2000);
|
||||
});
|
||||
@ -69,23 +68,23 @@ class CoWebsiteManager {
|
||||
* Just like loadCoWebsite but the div can be filled by the user.
|
||||
*/
|
||||
public insertCoWebsite(callback: (cowebsite: HTMLDivElement) => Promise<void>): void {
|
||||
const cowebsiteDiv = this.load();
|
||||
this.currentOperationPromise = this.currentOperationPromise.then(() => callback(cowebsiteDiv)).then(() => {
|
||||
this.load();
|
||||
this.currentOperationPromise = this.currentOperationPromise.then(() => callback(this.cowebsiteDiv)).then(() => {
|
||||
this.open();
|
||||
setTimeout(() => {
|
||||
this.fire();
|
||||
}, animationTime)
|
||||
}, animationTime);
|
||||
}).catch(() => this.closeCoWebsite());
|
||||
}
|
||||
|
||||
public closeCoWebsite(): Promise<void> {
|
||||
this.currentOperationPromise = this.currentOperationPromise.then(() => new Promise((resolve, reject) => {
|
||||
if(this.opened === iframeStates.closed) resolve(); //this method may be called twice, in case of iframe error for example
|
||||
const cowebsiteDiv = this.close();
|
||||
this.close();
|
||||
this.fire();
|
||||
setTimeout(() => {
|
||||
this.cowebsiteDiv.innerHTML = '';
|
||||
resolve();
|
||||
setTimeout(() => cowebsiteDiv.innerHTML = '', 500)
|
||||
}, animationTime)
|
||||
}));
|
||||
return this.currentOperationPromise;
|
||||
@ -111,6 +110,7 @@ class CoWebsiteManager {
|
||||
}
|
||||
}
|
||||
|
||||
//todo: is it still useful to allow any kind of observers?
|
||||
public onStateChange(observer: CoWebsiteStateChangedCallback) {
|
||||
this.observers.push(observer);
|
||||
}
|
||||
|
@ -50,8 +50,9 @@ class JitsiFactory {
|
||||
delete options.jwt;
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
options.onload = () => resolve(); //we want for the iframe to be loaded before triggering animations.
|
||||
setTimeout(() => resolve(), 2000); //failsafe in case the iframe is deleted before loading or too long to load
|
||||
this.jitsiApi = new window.JitsiMeetExternalAPI(domain, options);
|
||||
this.jitsiApi.executeCommand('displayName', playerName);
|
||||
|
||||
|
@ -45,7 +45,7 @@ module.exports = {
|
||||
new webpack.ProvidePlugin({
|
||||
Phaser: 'phaser'
|
||||
}),
|
||||
new webpack.EnvironmentPlugin(['API_URL', 'DEBUG_MODE', 'TURN_SERVER', 'TURN_USER', 'TURN_PASSWORD', 'JITSI_URL', 'JITSI_PRIVATE_MODE'])
|
||||
new webpack.EnvironmentPlugin(['API_URL', 'ADMIN_URL', 'DEBUG_MODE', 'TURN_SERVER', 'TURN_USER', 'TURN_PASSWORD', 'JITSI_URL', 'JITSI_PRIVATE_MODE'])
|
||||
],
|
||||
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user