diff --git a/back/src/Assets/Maps/Floor0/floor0.json b/back/src/Assets/Maps/Floor0/floor0.json
index 631cb84c..be96afaf 100644
--- a/back/src/Assets/Maps/Floor0/floor0.json
+++ b/back/src/Assets/Maps/Floor0/floor0.json
@@ -49,7 +49,7 @@
{
"name":"exitSceneUrl",
"type":"string",
- "value":"\/Floor1\/floor1.json"
+ "value":"..\/Floor1\/floor1.json"
}],
"type":"tilelayer",
"visible":true,
@@ -67,7 +67,7 @@
{
"name":"exitSceneUrl",
"type":"string",
- "value":"\/Lyon\/lyon.json"
+ "value":"..\/Lyon\/lyon.json"
}],
"type":"tilelayer",
"visible":true,
diff --git a/back/src/Assets/Maps/Floor1/floor1.json b/back/src/Assets/Maps/Floor1/floor1.json
index 6791b98a..b443e68f 100644
--- a/back/src/Assets/Maps/Floor1/floor1.json
+++ b/back/src/Assets/Maps/Floor1/floor1.json
@@ -43,7 +43,7 @@
{
"name":"exitSceneUrl",
"type":"string",
- "value":"\/Floor0\/floor0.json"
+ "value":"..\/Floor0\/floor0.json"
}],
"type":"tilelayer",
"visible":true,
diff --git a/back/src/Assets/Maps/Lyon/floortileset.png b/back/src/Assets/Maps/Lyon/floortileset.png
new file mode 100644
index 00000000..c672dcbb
Binary files /dev/null and b/back/src/Assets/Maps/Lyon/floortileset.png differ
diff --git a/back/src/Assets/Maps/Lyon/lyon.json b/back/src/Assets/Maps/Lyon/lyon.json
index 69fdff1d..0ed62a9c 100644
--- a/back/src/Assets/Maps/Lyon/lyon.json
+++ b/back/src/Assets/Maps/Lyon/lyon.json
@@ -37,7 +37,7 @@
{
"name":"exitSceneUrl",
"type":"string",
- "value":"\/Floor0\/floor0.json"
+ "value":"..\/Floor0\/floor0.json"
}],
"type":"tilelayer",
"visible":true,
diff --git a/back/src/Assets/Maps/Lyon/tilesets_deviant_milkian_1.png b/back/src/Assets/Maps/Lyon/tilesets_deviant_milkian_1.png
new file mode 100644
index 00000000..47400131
Binary files /dev/null and b/back/src/Assets/Maps/Lyon/tilesets_deviant_milkian_1.png differ
diff --git a/back/src/Controller/MapController.ts b/back/src/Controller/MapController.ts
index 65ca7956..bc7546cc 100644
--- a/back/src/Controller/MapController.ts
+++ b/back/src/Controller/MapController.ts
@@ -20,7 +20,7 @@ export class MapController {
getMaps() {
this.App.get("/maps", (req: Request, res: Response) => {
return res.status(OK).send({
- mapUrlStart: URL_ROOM_STARTED
+ mapUrlStart: req.headers.host + "/map/files" + URL_ROOM_STARTED
});
});
}
diff --git a/front/dist/.htaccess b/front/dist/.htaccess
new file mode 100644
index 00000000..53979e53
--- /dev/null
+++ b/front/dist/.htaccess
@@ -0,0 +1,23 @@
+DirectoryIndex index.html
+
+# By default, Apache does not evaluate symbolic links if you did not enable this
+# feature in your server configuration. Uncomment the following line if you
+# install assets as symlinks or if you experience problems related to symlinks
+# when compiling LESS/Sass/CoffeScript assets.
+# Options FollowSymlinks
+
+# Disabling MultiViews prevents unwanted negotiation, e.g. "/index" should not resolve
+# to the front controller "/index.php" but be rewritten to "/index.php/index".
+
+ Options -MultiViews
+
+
+RewriteEngine On
+
+RewriteBase /
+
+# If the requested filename exists, simply serve it.
+# We only want to let Apache serve files and not directories.
+# Rewrite all other queries starting with _ to index.ts.
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteRule "^_/" "/index.html" [L]
diff --git a/front/dist/index.html b/front/dist/index.html
index 85aced1e..51d52705 100644
--- a/front/dist/index.html
+++ b/front/dist/index.html
@@ -5,6 +5,7 @@
+
Document
diff --git a/front/src/Connexion.ts b/front/src/Connexion.ts
index 69b6647b..f7d1e7db 100644
--- a/front/src/Connexion.ts
+++ b/front/src/Connexion.ts
@@ -140,7 +140,6 @@ export interface ConnexionInterface {
token: string;
email: string;
userId: string;
- startedRoom: string;
createConnexion(characterSelected: string): Promise;
@@ -167,7 +166,6 @@ export class Connexion implements ConnexionInterface {
token: string;
email: string;
userId: string;
- startedRoom: string;
GameManager: GameManager;
@@ -183,8 +181,6 @@ export class Connexion implements ConnexionInterface {
return Axios.post(`${API_URL}/login`, {email: this.email})
.then((res) => {
this.token = res.data.token;
-
- this.startedRoom = getMapKeyByUrl(res.data.mapUrlStart);
this.userId = res.data.userId;
this.socket = SocketIo(`${API_URL}`, {
@@ -194,10 +190,10 @@ export class Connexion implements ConnexionInterface {
});
//join the room
- this.joinARoom(this.startedRoom, characterSelected);
+ //this.joinARoom(this.startedRoom, characterSelected);
//share your first position
- this.sharePosition(0, 0, characterSelected, this.startedRoom);
+ //this.sharePosition(0, 0, characterSelected, this.startedRoom);
this.positionOfAllUser();
diff --git a/front/src/Enum/EnvironmentVariable.ts b/front/src/Enum/EnvironmentVariable.ts
index 50296fe6..30250d5e 100644
--- a/front/src/Enum/EnvironmentVariable.ts
+++ b/front/src/Enum/EnvironmentVariable.ts
@@ -3,13 +3,11 @@ const API_URL = process.env.API_URL || "http://api.workadventure.localhost";
const ROOM = [process.env.ROOM || "THECODINGMACHINE"];
const RESOLUTION = 3;
const ZOOM_LEVEL = 1/*3/4*/;
-const MAP_FILE_URL = `${API_URL}/map/files`;
export {
DEBUG_MODE,
API_URL,
RESOLUTION,
ZOOM_LEVEL,
- ROOM,
- MAP_FILE_URL
+ ROOM
}
diff --git a/front/src/Phaser/Game/GameManager.ts b/front/src/Phaser/Game/GameManager.ts
index 78019f5d..78436429 100644
--- a/front/src/Phaser/Game/GameManager.ts
+++ b/front/src/Phaser/Game/GameManager.ts
@@ -5,6 +5,9 @@ import {
ListMessageUserPositionInterface
} from "../../Connexion";
import {SimplePeerInterface, SimplePeer} from "../../WebRtc/SimplePeer";
+import {getMapKeyByUrl} from "../Login/LogincScene";
+import SceneManager = Phaser.Scenes.SceneManager;
+import ScenePlugin = Phaser.Scenes.ScenePlugin;
export enum StatusGameManagerEnum {
IN_PROGRESS = 1,
@@ -124,6 +127,18 @@ export class GameManager {
pushPlayerPosition(event: HasMovedEvent) {
this.ConnexionInstance.sharePosition(event.x, event.y, event.character, this.currentGameScene.scene.key, event.direction);
}
+
+ loadMap(mapUrl: string, scene: ScenePlugin): string {
+ let sceneKey = getMapKeyByUrl(mapUrl);
+
+ let gameIndex = scene.getIndex(sceneKey);
+ let game : Phaser.Scene = null;
+ if(gameIndex === -1){
+ game = new GameScene(sceneKey, mapUrl);
+ scene.add(sceneKey, game, false);
+ }
+ return sceneKey;
+ }
}
export const gameManager = new GameManager();
diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts
index 9120378d..701cbe31 100644
--- a/front/src/Phaser/Game/GameScene.ts
+++ b/front/src/Phaser/Game/GameScene.ts
@@ -1,14 +1,13 @@
import {GameManager, gameManager, HasMovedEvent, MapObject, StatusGameManagerEnum} from "./GameManager";
import {GroupCreatedUpdatedMessageInterface, MessageUserPositionInterface} from "../../Connexion";
import {CurrentGamerInterface, GamerInterface, hasMovedEventName, Player} from "../Player/Player";
-import { DEBUG_MODE, MAP_FILE_URL, RESOLUTION, ROOM, ZOOM_LEVEL} from "../../Enum/EnvironmentVariable";
+import { DEBUG_MODE, RESOLUTION, ROOM, ZOOM_LEVEL} from "../../Enum/EnvironmentVariable";
import {ITiledMap, ITiledMapLayer, ITiledTileSet} from "../Map/ITiledMap";
import {PLAYER_RESOURCES} from "../Entity/PlayableCaracter";
import Texture = Phaser.Textures.Texture;
import Sprite = Phaser.GameObjects.Sprite;
import CanvasTexture = Phaser.Textures.CanvasTexture;
import CreateSceneFromObjectConfig = Phaser.Types.Scenes.CreateSceneFromObjectConfig;
-import {getMapKeyByUrl} from "../Login/LogincScene";
export enum Textures {
Player = "male1"
@@ -61,7 +60,7 @@ export class GameScene extends Phaser.Scene implements GameSceneInterface, Creat
// Triggered when the map is loaded
// Load tiles attached to the map recursively
this.map = data.data;
- let url = this.MapUrlFile.substr(0, this.MapUrlFile.indexOf(`${this.MapKey}.json`));
+ let url = this.MapUrlFile.substr(0, this.MapUrlFile.lastIndexOf('/'));
this.map.tilesets.forEach((tileset) => {
if (typeof tileset.name === 'undefined' || typeof tileset.image === 'undefined') {
console.warn("Don't know how to handle tileset ", tileset)
@@ -151,6 +150,15 @@ export class GameScene extends Phaser.Scene implements GameSceneInterface, Creat
context.strokeStyle = '#ffffff';
context.stroke();
this.circleTexture.refresh();
+
+ // Let's alter browser history
+ let url = new URL(this.MapUrlFile);
+ let path = '/_/'+url.host+url.pathname;
+ if (url.hash) {
+ // FIXME: entry should be dictated by a property passed to init()
+ path += '#'+url.hash;
+ }
+ window.history.pushState({}, null, path);
}
private getExitSceneUrl(layer: ITiledMapLayer): string|undefined {
@@ -175,19 +183,11 @@ export class GameScene extends Phaser.Scene implements GameSceneInterface, Creat
private loadNextGame(layer: ITiledMapLayer, mapWidth: number, tileWidth: number, tileHeight: number){
let exitSceneUrl = this.getExitSceneUrl(layer);
- let exitSceneKey = getMapKeyByUrl(exitSceneUrl);
+ // TODO: eventually compute a relative URL
+ let absoluteExitSceneUrl = new URL(exitSceneUrl, this.MapUrlFile).href;
+ console.log('absoluteExitSceneUrl ', absoluteExitSceneUrl);
+ let exitSceneKey = gameManager.loadMap(absoluteExitSceneUrl, this.scene);
- let gameIndex = this.scene.getIndex(exitSceneKey);
- let game : Phaser.Scene = null;
- if(gameIndex === -1){
- game = new GameScene(exitSceneKey, `${MAP_FILE_URL}${exitSceneUrl}`);
- this.scene.add(exitSceneKey, game, false);
- }else{
- game = this.scene.get(exitSceneKey);
- }
- if(!game){
- return;
- }
let tiles : any = layer.data;
tiles.forEach((objectKey : number, key: number) => {
if(objectKey === 0){
diff --git a/front/src/Phaser/Login/LogincScene.ts b/front/src/Phaser/Login/LogincScene.ts
index 49487376..3136060c 100644
--- a/front/src/Phaser/Login/LogincScene.ts
+++ b/front/src/Phaser/Login/LogincScene.ts
@@ -8,9 +8,15 @@ import Rectangle = Phaser.GameObjects.Rectangle;
import {PLAYER_RESOURCES} from "../Entity/PlayableCaracter";
import {cypressAsserter} from "../../Cypress/CypressAsserter";
import {GroupCreatedUpdatedMessageInterface, MessageUserPositionInterface} from "../../Connexion";
-import {MAP_FILE_URL} from "../../Enum/EnvironmentVariable";
export function getMapKeyByUrl(mapUrlStart: string){
+ // FIXME: the key should be computed from the full URL of the map.
+ let startPos = mapUrlStart.indexOf('://')+3;
+ let endPos = mapUrlStart.indexOf(".json");
+ console.log('MAP KEY '+mapUrlStart.substring(startPos, endPos));
+ return mapUrlStart.substring(startPos, endPos);
+
+
let tab = mapUrlStart.split("/");
return tab[tab.length -1].substr(0, tab[tab.length -1].indexOf(".json"));
}
@@ -99,25 +105,40 @@ export class LogincScene extends Phaser.Scene implements GameSceneInterface {
private async login(name: string) {
return gameManager.connect(name, this.selectedPlayer.texture.key).then(() => {
- return gameManager.loadMaps().then((scene : any) => {
- if (!scene) {
- return;
- }
- let key = getMapKeyByUrl(scene.mapUrlStart);
- let game = new GameScene(key,`${MAP_FILE_URL}${scene.mapUrlStart}`);
- this.scene.add(key, game, false);
+ // Do we have a start URL in the address bar? If so, let's redirect to this address
+ let mapUrl = this.findMapUrl();
+ if (mapUrl !== null) {
+ let key = gameManager.loadMap(mapUrl, this.scene);
this.scene.start(key);
- return scene;
- }).catch((err) => {
- console.error(err);
- throw err;
- });
+ return mapUrl;
+ } else {
+ // If we do not have a map address in the URL, let's ask the server for a start map.
+ return gameManager.loadMaps().then((scene : any) => {
+ if (!scene) {
+ return;
+ }
+ let key = gameManager.loadMap(window.location.protocol+"//"+scene.mapUrlStart, this.scene);
+ this.scene.start(key);
+ return scene;
+ }).catch((err) => {
+ console.error(err);
+ throw err;
+ });
+ }
}).catch((err) => {
console.error(err);
throw err;
});
}
+ private findMapUrl(): string|null {
+ let path = window.location.pathname;
+ if (!path.startsWith('/_/')) {
+ return null;
+ }
+ return window.location.protocol+'//'+path.substr(3);
+ }
+
Map: Phaser.Tilemaps.Tilemap;
initAnimation(): void {
diff --git a/front/webpack.config.js b/front/webpack.config.js
index ff164804..d1bccd6f 100644
--- a/front/webpack.config.js
+++ b/front/webpack.config.js
@@ -8,6 +8,12 @@ module.exports = {
contentBase: './dist',
host: '0.0.0.0',
disableHostCheck: true,
+ historyApiFallback: {
+ rewrites: [
+ { from: /^_\/.*$/, to: '/index.html' }
+ ],
+ disableDotRule: true
+ },
},
module: {
rules: [
@@ -24,6 +30,7 @@ module.exports = {
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
+ publicPath: '/'
},
plugins: [
new webpack.ProvidePlugin({