2020-09-25 18:29:22 +02:00
|
|
|
import Axios from "axios";
|
|
|
|
import {API_URL} from "../Enum/EnvironmentVariable";
|
|
|
|
import {RoomConnection} from "./RoomConnection";
|
2020-10-06 18:09:23 +02:00
|
|
|
import {PositionInterface, ViewportInterface} from "./ConnexionModels";
|
2020-10-12 16:23:07 +02:00
|
|
|
import {GameConnexionTypes, urlManager} from "../Url/UrlManager";
|
|
|
|
import {localUserStore} from "./LocalUserStore";
|
|
|
|
import {LocalUser} from "./LocalUser";
|
|
|
|
import {Room} from "./Room";
|
2020-09-28 15:02:37 +02:00
|
|
|
|
2020-10-13 16:42:05 +02:00
|
|
|
const URL_ROOM_STARTED = '/Floor0/floor0.json';
|
|
|
|
|
2020-09-25 18:29:22 +02:00
|
|
|
class ConnectionManager {
|
2020-10-12 16:23:07 +02:00
|
|
|
private localUser!:LocalUser;
|
2020-09-29 17:12:28 +02:00
|
|
|
|
2020-10-12 16:23:07 +02:00
|
|
|
/**
|
|
|
|
* Tries to login to the node server and return the starting map url to be loaded
|
|
|
|
*/
|
|
|
|
public async initGameConnexion(): Promise<Room> {
|
2020-09-29 17:12:28 +02:00
|
|
|
|
2020-10-12 16:23:07 +02:00
|
|
|
const connexionType = urlManager.getGameConnexionType();
|
|
|
|
if(connexionType === GameConnexionTypes.register) {
|
|
|
|
const organizationMemberToken = urlManager.getOrganizationToken();
|
2020-10-13 15:55:30 +02:00
|
|
|
const data = await Axios.post(`${API_URL}/register`, {organizationMemberToken}).then(res => res.data);
|
2020-10-20 16:39:23 +02:00
|
|
|
this.localUser = new LocalUser(data.userUuid, data.authToken, data.textures);
|
2020-10-12 16:23:07 +02:00
|
|
|
localUserStore.saveUser(this.localUser);
|
2020-10-13 16:46:46 +02:00
|
|
|
|
2020-10-12 16:23:07 +02:00
|
|
|
const organizationSlug = data.organizationSlug;
|
|
|
|
const worldSlug = data.worldSlug;
|
|
|
|
const roomSlug = data.roomSlug;
|
|
|
|
urlManager.editUrlForRoom(roomSlug, organizationSlug, worldSlug);
|
2020-10-13 16:46:46 +02:00
|
|
|
|
2020-10-15 15:50:51 +02:00
|
|
|
const room = new Room(window.location.pathname + window.location.hash);
|
2020-10-12 16:23:07 +02:00
|
|
|
return Promise.resolve(room);
|
2020-10-13 17:20:20 +02:00
|
|
|
} else if (connexionType === GameConnexionTypes.anonymous || connexionType === GameConnexionTypes.empty) {
|
2020-10-12 16:23:07 +02:00
|
|
|
const localUser = localUserStore.getLocalUser();
|
2020-10-13 16:46:46 +02:00
|
|
|
|
2020-10-20 16:39:23 +02:00
|
|
|
if (localUser && localUser.jwtToken && localUser.uuid && localUser.textures) {
|
2020-10-15 16:48:42 +02:00
|
|
|
this.localUser = localUser;
|
|
|
|
try {
|
|
|
|
await this.verifyToken(localUser.jwtToken);
|
|
|
|
} catch(e) {
|
|
|
|
// If the token is invalid, let's generate an anonymous one.
|
|
|
|
console.error('JWT token invalid. Did it expire? Login anonymously instead.');
|
|
|
|
await this.anonymousLogin();
|
|
|
|
}
|
2020-10-12 16:23:07 +02:00
|
|
|
} else {
|
2020-10-15 16:48:42 +02:00
|
|
|
await this.anonymousLogin();
|
2020-10-12 16:23:07 +02:00
|
|
|
}
|
2020-10-13 17:20:20 +02:00
|
|
|
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 {
|
2020-10-15 15:50:51 +02:00
|
|
|
roomId = window.location.pathname + window.location.hash;
|
2020-10-13 17:20:20 +02:00
|
|
|
}
|
|
|
|
const room = new Room(roomId);
|
2020-10-12 16:23:07 +02:00
|
|
|
return Promise.resolve(room);
|
|
|
|
} else if (connexionType == GameConnexionTypes.organization) {
|
|
|
|
const localUser = localUserStore.getLocalUser();
|
2020-09-25 18:29:22 +02:00
|
|
|
|
2020-10-12 16:23:07 +02:00
|
|
|
if (localUser) {
|
2020-10-15 16:48:42 +02:00
|
|
|
this.localUser = localUser;
|
|
|
|
await this.verifyToken(localUser.jwtToken);
|
2020-10-15 15:50:51 +02:00
|
|
|
const room = new Room(window.location.pathname + window.location.hash);
|
2020-10-13 16:46:46 +02:00
|
|
|
return Promise.resolve(room);
|
2020-10-12 16:23:07 +02:00
|
|
|
} else {
|
|
|
|
//todo: find some kind of fallback?
|
|
|
|
return Promise.reject('Could not find a user in localstorage');
|
|
|
|
}
|
2020-09-25 18:29:22 +02:00
|
|
|
}
|
2020-10-13 17:20:20 +02:00
|
|
|
|
|
|
|
return Promise.reject('Invalid URL');
|
2020-09-25 18:29:22 +02:00
|
|
|
}
|
2020-09-29 17:12:28 +02:00
|
|
|
|
2020-10-15 16:48:42 +02:00
|
|
|
private async verifyToken(token: string): Promise<void> {
|
|
|
|
await Axios.get(`${API_URL}/verify`, {params: {token}});
|
|
|
|
}
|
|
|
|
|
2020-10-21 14:55:18 +02:00
|
|
|
public async anonymousLogin(isBenchmark: boolean = false): Promise<void> {
|
2020-10-15 16:48:42 +02:00
|
|
|
const data = await Axios.post(`${API_URL}/anonymLogin`).then(res => res.data);
|
2020-10-20 16:39:23 +02:00
|
|
|
this.localUser = new LocalUser(data.userUuid, data.authToken, []);
|
2020-10-21 14:55:18 +02:00
|
|
|
if (!isBenchmark) { // In benchmark, we don't have a local storage.
|
|
|
|
localUserStore.saveUser(this.localUser);
|
|
|
|
}
|
2020-10-15 16:48:42 +02:00
|
|
|
}
|
|
|
|
|
2020-09-30 12:12:24 +02:00
|
|
|
public initBenchmark(): void {
|
2020-10-20 16:39:23 +02:00
|
|
|
this.localUser = new LocalUser('', 'test', []);
|
2020-09-30 12:12:24 +02:00
|
|
|
}
|
|
|
|
|
2020-10-06 18:09:23 +02:00
|
|
|
public connectToRoomSocket(roomId: string, name: string, characterLayers: string[], position: PositionInterface, viewport: ViewportInterface): Promise<RoomConnection> {
|
2020-09-28 15:02:37 +02:00
|
|
|
return new Promise<RoomConnection>((resolve, reject) => {
|
2020-10-12 16:23:07 +02:00
|
|
|
const connection = new RoomConnection(this.localUser.jwtToken, roomId, name, characterLayers, position, viewport);
|
2020-09-28 15:02:37 +02:00
|
|
|
connection.onConnectError((error: object) => {
|
|
|
|
console.log('An error occurred while connecting to socket server. Retrying');
|
|
|
|
reject(error);
|
2020-09-25 18:29:22 +02:00
|
|
|
});
|
2020-09-29 17:12:28 +02:00
|
|
|
connection.onConnect(() => {
|
|
|
|
resolve(connection);
|
|
|
|
})
|
2020-09-28 15:02:37 +02:00
|
|
|
}).catch((err) => {
|
|
|
|
// Let's retry in 4-6 seconds
|
|
|
|
return new Promise<RoomConnection>((resolve, reject) => {
|
|
|
|
setTimeout(() => {
|
|
|
|
//todo: allow a way to break recurrsion?
|
2020-10-06 18:09:23 +02:00
|
|
|
this.connectToRoomSocket(roomId, name, characterLayers, position, viewport).then((connection) => resolve(connection));
|
2020-09-28 15:02:37 +02:00
|
|
|
}, 4000 + Math.floor(Math.random() * 2000) );
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
2020-09-25 18:29:22 +02:00
|
|
|
}
|
|
|
|
|
2020-09-29 17:12:28 +02:00
|
|
|
export const connectionManager = new ConnectionManager();
|