diff --git a/.env.template b/.env.template
index d0db42e3..330f3865 100644
--- a/.env.template
+++ b/.env.template
@@ -5,3 +5,4 @@ JITSI_PRIVATE_MODE=false
JITSI_ISS=
SECRET_JITSI_KEY=
ADMIN_API_TOKEN=123
+START_ROOM_URL=/_/global/maps.workadventure.localhost/Floor0/floor0.json
diff --git a/back/src/Enum/EnvironmentVariable.ts b/back/src/Enum/EnvironmentVariable.ts
index 00750969..2cbfbf2e 100644
--- a/back/src/Enum/EnvironmentVariable.ts
+++ b/back/src/Enum/EnvironmentVariable.ts
@@ -1,5 +1,4 @@
const SECRET_KEY = process.env.SECRET_KEY || "THECODINGMACHINE_SECRET_KEY";
-const URL_ROOM_STARTED = "/Floor0/floor0.json";
const MINIMUM_DISTANCE = process.env.MINIMUM_DISTANCE ? Number(process.env.MINIMUM_DISTANCE) : 64;
const GROUP_RADIUS = process.env.GROUP_RADIUS ? Number(process.env.GROUP_RADIUS) : 48;
const ALLOW_ARTILLERY = process.env.ALLOW_ARTILLERY ? process.env.ALLOW_ARTILLERY == 'true' : false;
@@ -16,7 +15,6 @@ export const SOCKET_IDLE_TIMER = parseInt(process.env.SOCKET_IDLE_TIMER as strin
export {
SECRET_KEY,
- URL_ROOM_STARTED,
MINIMUM_DISTANCE,
ADMIN_API_URL,
ADMIN_API_TOKEN,
diff --git a/docker-compose.yaml b/docker-compose.yaml
index 23fa58a4..286c12ba 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -29,10 +29,12 @@ services:
API_URL: pusher.workadventure.localhost
UPLOADER_URL: uploader.workadventure.localhost
ADMIN_URL: workadventure.localhost
- STARTUP_COMMAND_1: yarn install
+ STARTUP_COMMAND_1: ./templater.sh
+ STARTUP_COMMAND_2: yarn install
TURN_SERVER: "turn:coturn.workadventu.re:443,turns:coturn.workadventu.re:443"
TURN_USER: workadventure
TURN_PASSWORD: WorkAdventure123
+ START_ROOM_URL: "$START_ROOM_URL"
command: yarn run start
volumes:
- ./front:/usr/src/app
diff --git a/front/src/Connexion/ConnectionManager.ts b/front/src/Connexion/ConnectionManager.ts
index 552819bb..de8cd234 100644
--- a/front/src/Connexion/ConnectionManager.ts
+++ b/front/src/Connexion/ConnectionManager.ts
@@ -1,5 +1,5 @@
import Axios from "axios";
-import {API_URL, URL_ROOM_STARTED} from "../Enum/EnvironmentVariable";
+import {API_URL, START_ROOM_URL} from "../Enum/EnvironmentVariable";
import {RoomConnection} from "./RoomConnection";
import {OnConnectInterface, PositionInterface, ViewportInterface} from "./ConnexionModels";
import {GameConnexionTypes, urlManager} from "../Url/UrlManager";
@@ -27,9 +27,9 @@ class ConnectionManager {
const organizationSlug = data.organizationSlug;
const worldSlug = data.worldSlug;
const roomSlug = data.roomSlug;
- urlManager.editUrlForRoom(roomSlug, organizationSlug, worldSlug);
- const room = new Room(window.location.pathname + window.location.hash);
+ const room = new Room('/@/'+organizationSlug+'/'+worldSlug+'/'+roomSlug + window.location.hash);
+ urlManager.pushRoomIdToUrl(room);
return Promise.resolve(room);
} else if (connexionType === GameConnexionTypes.organization || connexionType === GameConnexionTypes.anonymous || connexionType === GameConnexionTypes.empty) {
const localUser = localUserStore.getLocalUser();
@@ -48,10 +48,7 @@ class ConnectionManager {
}
let roomId: string
if (connexionType === GameConnexionTypes.empty) {
- roomId = urlManager.editUrlForRoom(URL_ROOM_STARTED, null, null);
- if (URL_ROOM_STARTED.startsWith('http://') || URL_ROOM_STARTED.startsWith('https://')) {
- roomId = '/_/global/' + URL_ROOM_STARTED.replace('http://', '').replace('https://', '');
- }
+ roomId = START_ROOM_URL;
} else {
roomId = window.location.pathname + window.location.hash;
}
diff --git a/front/src/Enum/EnvironmentVariable.ts b/front/src/Enum/EnvironmentVariable.ts
index c456da2f..a71506eb 100644
--- a/front/src/Enum/EnvironmentVariable.ts
+++ b/front/src/Enum/EnvironmentVariable.ts
@@ -1,5 +1,5 @@
const DEBUG_MODE: boolean = process.env.DEBUG_MODE == "true";
-const URL_ROOM_STARTED : string = process.env.URL_ROOM_STARTED || 'tcm/workadventure/floor0';
+const START_ROOM_URL : string = process.env.START_ROOM_URL || '/_/global/maps.workadventure.localhost/Floor0/floor0.json';
const API_URL = (process.env.API_PROTOCOL || (typeof(window) !== 'undefined' ? window.location.protocol : 'http:')) + '//' + (process.env.API_URL || "pusher.workadventure.localhost");
const UPLOADER_URL = (process.env.API_PROTOCOL || (typeof(window) !== 'undefined' ? window.location.protocol : 'http:')) + '//' + (process.env.UPLOADER_URL || 'uploader.workadventure.localhost');
const ADMIN_URL = (process.env.API_PROTOCOL || (typeof(window) !== 'undefined' ? window.location.protocol : 'http:')) + '//' + (process.env.ADMIN_URL || "workadventure.localhost");
@@ -15,7 +15,7 @@ const MAX_EXTRAPOLATION_TIME = 100; // Extrapolate a maximum of 250ms if no new
export {
DEBUG_MODE,
- URL_ROOM_STARTED,
+ START_ROOM_URL,
API_URL,
UPLOADER_URL,
ADMIN_URL,
diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts
index e0081bfa..96fd082b 100644
--- a/front/src/Phaser/Game/GameScene.ts
+++ b/front/src/Phaser/Game/GameScene.ts
@@ -606,8 +606,18 @@ export class GameScene extends ResizableScene implements CenterListener {
if (url === undefined) {
audioManager.unloadAudio();
} else {
- const mapDirUrl = this.MapUrlFile.substr(0, this.MapUrlFile.lastIndexOf('/'));
- const realAudioPath = mapDirUrl + '/' + url;
+ const audioPath = url as string;
+ let realAudioPath = '';
+
+ if (audioPath.indexOf('://') > 0) {
+ // remote file or stream
+ realAudioPath = audioPath;
+ } else {
+ // local file, include it relative to map directory
+ const mapDirUrl = this.MapUrlFile.substr(0, this.MapUrlFile.lastIndexOf('/'));
+ realAudioPath = mapDirUrl + '/' + url;
+ }
+
audioManager.loadAudio(realAudioPath);
if (loop) {
@@ -704,6 +714,10 @@ export class GameScene extends ResizableScene implements CenterListener {
}
public cleanupClosingScene(): void {
+ // stop playing audio, close any open website, stop any open Jitsi
+ coWebsiteManager.closeCoWebsite();
+ this.stopJitsi();
+ this.playAudio(undefined);
// We are completely destroying the current scene to avoid using a half-backed instance when coming back to the same map.
if(this.connection) {
this.connection.closeConnection();
diff --git a/front/src/Url/UrlManager.ts b/front/src/Url/UrlManager.ts
index 443dcee5..31862899 100644
--- a/front/src/Url/UrlManager.ts
+++ b/front/src/Url/UrlManager.ts
@@ -32,26 +32,12 @@ class UrlManager {
return match ? match [1] : null;
}
-
- //todo: simply use the roomId
- //todo: test this with cypress
- public editUrlForRoom(roomSlug: string, organizationSlug: string|null, worldSlug: string |null): string {
- let newUrl:string;
- if (organizationSlug) {
- newUrl = '/@/'+organizationSlug+'/'+worldSlug+'/'+roomSlug;
- } else {
- newUrl = '/@/'+roomSlug;
- }
- history.pushState({}, 'WorkAdventure', newUrl);
- return newUrl;
- }
-
public pushRoomIdToUrl(room:Room): void {
- if (window.location.pathname === room.id) return;
+ if (window.location.pathname === room.id) return;
const hash = window.location.hash;
history.pushState({}, 'WorkAdventure', room.id+hash);
}
-
+
public getStartLayerNameFromUrl(): string|null {
const hash = window.location.hash;
return hash.length > 1 ? hash.substring(1) : null;
diff --git a/front/src/WebRtc/DiscussionManager.ts b/front/src/WebRtc/DiscussionManager.ts
index 4282603b..7653bc7a 100644
--- a/front/src/WebRtc/DiscussionManager.ts
+++ b/front/src/WebRtc/DiscussionManager.ts
@@ -151,15 +151,6 @@ export class DiscussionManager {
this.nbpParticipants.innerText = `PARTICIPANTS (${nb})`;
}
- private urlify(text: string) {
- const urlRegex = /(https?:\/\/[^\s]+)/g;
- return text.replace(urlRegex, (url: string) => {
- return '' + url + '';
- })
- // or alternatively
- // return text.replace(urlRegex, '$1')
- }
-
public addMessage(name: string, message: string, isMe: boolean = false) {
const divMessage: HTMLDivElement = document.createElement('div');
divMessage.classList.add('message');
@@ -170,7 +161,7 @@ export class DiscussionManager {
const pMessage: HTMLParagraphElement = document.createElement('p');
const date = new Date();
if(isMe){
- name = 'Moi';
+ name = 'Me';
}
pMessage.innerHTML = `${name}
@@ -179,7 +170,7 @@ export class DiscussionManager {
divMessage.appendChild(pMessage);
const userMessage: HTMLParagraphElement = document.createElement('p');
- userMessage.innerHTML = this.urlify(message);
+ userMessage.innerHTML = HtmlUtils.urlify(message);
userMessage.classList.add('body');
divMessage.appendChild(userMessage);
this.divMessages?.appendChild(divMessage);
@@ -221,7 +212,7 @@ export class DiscussionManager {
this.activeDiscussion = false;
this.divDiscuss?.classList.remove('active');
}
-
+
public setUserInputManager(userInputManager : UserInputManager){
this.userInputManager = userInputManager;
}
@@ -231,4 +222,4 @@ export class DiscussionManager {
}
}
-export const discussionManager = new DiscussionManager();
\ No newline at end of file
+export const discussionManager = new DiscussionManager();
diff --git a/front/src/WebRtc/HtmlUtils.ts b/front/src/WebRtc/HtmlUtils.ts
index b7cb2124..81f069b3 100644
--- a/front/src/WebRtc/HtmlUtils.ts
+++ b/front/src/WebRtc/HtmlUtils.ts
@@ -17,4 +17,11 @@ export class HtmlUtils {
elem.remove();
return elem as T;
}
+
+ public static urlify(text: string): string {
+ const urlRegex = /(https?:\/\/[^\s]+)/g;
+ return text.replace(urlRegex, (url: string) => {
+ return '' + url + '';
+ })
+ }
}
diff --git a/front/src/index.ts b/front/src/index.ts
index acf66cf8..b9a00731 100644
--- a/front/src/index.ts
+++ b/front/src/index.ts
@@ -53,8 +53,28 @@ const fps : Phaser.Types.Core.FPSConfig = {
smoothStep: false
}
+// the ?phaserMode=canvas parameter can be used to force Canvas usage
+const params = new URLSearchParams(document.location.search.substring(1));
+const phaserMode = params.get("phaserMode");
+let mode: number;
+switch (phaserMode) {
+ case 'auto':
+ case null:
+ mode = Phaser.AUTO;
+ break;
+ case 'canvas':
+ mode = Phaser.CANVAS;
+ break;
+ case 'webgl':
+ mode = Phaser.WEBGL;
+ break;
+ default:
+ throw new Error('phaserMode parameter must be one of "auto", "canvas" or "webgl"');
+}
+
+
const config: GameConfig = {
- type: Phaser.AUTO,
+ type: mode,
title: "WorkAdventure",
width: width / RESOLUTION,
height: height / RESOLUTION,
diff --git a/front/tests/Phaser/Game/HtmlUtilsTest.ts b/front/tests/Phaser/Game/HtmlUtilsTest.ts
new file mode 100644
index 00000000..8ef1d476
--- /dev/null
+++ b/front/tests/Phaser/Game/HtmlUtilsTest.ts
@@ -0,0 +1,14 @@
+import "jasmine";
+import {HtmlUtils} from "../../../src/WebRtc/HtmlUtils";
+
+describe("urlify()", () => {
+ it("should transform an url into a link", () => {
+ const text = HtmlUtils.urlify('https://google.com');
+ expect(text).toEqual('https://google.com');
+ });
+
+ it("should not transform a normal text into a link", () => {
+ const text = HtmlUtils.urlify('hello');
+ expect(text).toEqual('hello');
+ });
+});
\ No newline at end of file
diff --git a/front/webpack.config.js b/front/webpack.config.js
index e5e34e8f..4a108848 100644
--- a/front/webpack.config.js
+++ b/front/webpack.config.js
@@ -45,7 +45,7 @@ module.exports = {
new webpack.ProvidePlugin({
Phaser: 'phaser'
}),
- new webpack.EnvironmentPlugin(['API_URL', 'UPLOADER_URL', 'ADMIN_URL', 'DEBUG_MODE', 'TURN_SERVER', 'TURN_USER', 'TURN_PASSWORD', 'JITSI_URL', 'JITSI_PRIVATE_MODE', 'URL_ROOM_STARTED'])
+ new webpack.EnvironmentPlugin(['API_URL', 'UPLOADER_URL', 'ADMIN_URL', 'DEBUG_MODE', 'TURN_SERVER', 'TURN_USER', 'TURN_PASSWORD', 'JITSI_URL', 'JITSI_PRIVATE_MODE', 'START_ROOM_URL'])
],
};
diff --git a/pusher/src/Enum/EnvironmentVariable.ts b/pusher/src/Enum/EnvironmentVariable.ts
index 17f80f9c..5b3ec9c4 100644
--- a/pusher/src/Enum/EnvironmentVariable.ts
+++ b/pusher/src/Enum/EnvironmentVariable.ts
@@ -1,5 +1,4 @@
const SECRET_KEY = process.env.SECRET_KEY || "THECODINGMACHINE_SECRET_KEY";
-const URL_ROOM_STARTED = "/Floor0/floor0.json";
const MINIMUM_DISTANCE = process.env.MINIMUM_DISTANCE ? Number(process.env.MINIMUM_DISTANCE) : 64;
const GROUP_RADIUS = process.env.GROUP_RADIUS ? Number(process.env.GROUP_RADIUS) : 48;
const ALLOW_ARTILLERY = process.env.ALLOW_ARTILLERY ? process.env.ALLOW_ARTILLERY == 'true' : false;
@@ -16,7 +15,6 @@ export const SOCKET_IDLE_TIMER = parseInt(process.env.SOCKET_IDLE_TIMER as strin
export {
SECRET_KEY,
- URL_ROOM_STARTED,
MINIMUM_DISTANCE,
API_URL,
ADMIN_API_URL,