Merge branch 'develop' of github.com:thecodingmachine/workadventure into twemojiEmoteMenu

This commit is contained in:
Lurkars 2021-07-20 16:27:49 +02:00
commit 83bd19c8dc
163 changed files with 5252 additions and 3394 deletions

View file

@ -38,11 +38,9 @@ class ConnectionManager {
this.localUser = new LocalUser(data.userUuid, data.authToken, data.textures);
localUserStore.saveUser(this.localUser);
const organizationSlug = data.organizationSlug;
const worldSlug = data.worldSlug;
const roomSlug = data.roomSlug;
const roomUrl = data.roomUrl;
const room = new Room('/@/'+organizationSlug+'/'+worldSlug+'/'+roomSlug + window.location.search + window.location.hash);
const room = await Room.createRoom(new URL(window.location.protocol + '//' + window.location.host + roomUrl + window.location.search + window.location.hash));
urlManager.pushRoomIdToUrl(room);
return Promise.resolve(room);
} else if (connexionType === GameConnexionTypes.organization || connexionType === GameConnexionTypes.anonymous || connexionType === GameConnexionTypes.empty) {
@ -66,22 +64,21 @@ class ConnectionManager {
throw "Error to store local user data";
}
let roomId: string;
let roomPath: string;
if (connexionType === GameConnexionTypes.empty) {
roomId = START_ROOM_URL;
roomPath = window.location.protocol + '//' + window.location.host + START_ROOM_URL;
} else {
roomId = window.location.pathname + window.location.search + window.location.hash;
roomPath = window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search + window.location.hash;
}
//get detail map for anonymous login and set texture in local storage
const room = new Room(roomId);
const mapDetail = await room.getMapDetail();
if(mapDetail.textures != undefined && mapDetail.textures.length > 0) {
const room = await Room.createRoom(new URL(roomPath));
if(room.textures != undefined && room.textures.length > 0) {
//check if texture was changed
if(localUser.textures.length === 0){
localUser.textures = mapDetail.textures;
localUser.textures = room.textures;
}else{
mapDetail.textures.forEach((newTexture) => {
room.textures.forEach((newTexture) => {
const alreadyExistTexture = localUser?.textures.find((c) => newTexture.id === c.id);
if(localUser?.textures.findIndex((c) => newTexture.id === c.id) !== -1){
return;
@ -114,9 +111,9 @@ class ConnectionManager {
this.localUser = new LocalUser('', 'test', []);
}
public connectToRoomSocket(roomId: string, name: string, characterLayers: string[], position: PositionInterface, viewport: ViewportInterface, companion: string|null): Promise<OnConnectInterface> {
public connectToRoomSocket(roomUrl: string, name: string, characterLayers: string[], position: PositionInterface, viewport: ViewportInterface, companion: string|null): Promise<OnConnectInterface> {
return new Promise<OnConnectInterface>((resolve, reject) => {
const connection = new RoomConnection(this.localUser.jwtToken, roomId, name, characterLayers, position, viewport, companion);
const connection = new RoomConnection(this.localUser.jwtToken, roomUrl, name, characterLayers, position, viewport, companion);
connection.onConnectError((error: object) => {
console.log('An error occurred while connecting to socket server. Retrying');
reject(error);
@ -137,7 +134,7 @@ class ConnectionManager {
this.reconnectingTimeout = setTimeout(() => {
//todo: allow a way to break recursion?
//todo: find a way to avoid recursive function. Otherwise, the call stack will grow indefinitely.
this.connectToRoomSocket(roomId, name, characterLayers, position, viewport, companion).then((connection) => resolve(connection));
this.connectToRoomSocket(roomUrl, name, characterLayers, position, viewport, companion).then((connection) => resolve(connection));
}, 4000 + Math.floor(Math.random() * 2000) );
});
});

View file

@ -1,8 +1,8 @@
import type {SignalData} from "simple-peer";
import type {RoomConnection} from "./RoomConnection";
import type {BodyResourceDescriptionInterface} from "../Phaser/Entity/PlayerTextures";
import type { SignalData } from "simple-peer";
import type { RoomConnection } from "./RoomConnection";
import type { BodyResourceDescriptionInterface } from "../Phaser/Entity/PlayerTextures";
export enum EventMessage{
export enum EventMessage {
CONNECT = "connect",
WEBRTC_SIGNAL = "webrtc-signal",
WEBRTC_SCREEN_SHARING_SIGNAL = "webrtc-screen-sharing-signal",
@ -17,7 +17,7 @@ export enum EventMessage{
GROUP_CREATE_UPDATE = "group-create-update",
GROUP_DELETE = "group-delete",
SET_PLAYER_DETAILS = "set-player-details", // Send the name and character to the server (on connect), receive back the id.
ITEM_EVENT = 'item-event',
ITEM_EVENT = "item-event",
CONNECT_ERROR = "connect_error",
CONNECTING_ERROR = "connecting_error",
@ -36,7 +36,7 @@ export enum EventMessage{
export interface PointInterface {
x: number;
y: number;
direction : string;
direction: string;
moving: boolean;
}
@ -45,8 +45,9 @@ export interface MessageUserPositionInterface {
name: string;
characterLayers: BodyResourceDescriptionInterface[];
position: PointInterface;
visitCardUrl: string|null;
companion: string|null;
visitCardUrl: string | null;
companion: string | null;
userUuid: string;
}
export interface MessageUserMovedInterface {
@ -60,58 +61,59 @@ export interface MessageUserJoined {
characterLayers: BodyResourceDescriptionInterface[];
position: PointInterface;
visitCardUrl: string | null;
companion: string|null;
companion: string | null;
userUuid: string;
}
export interface PositionInterface {
x: number,
y: number
x: number;
y: number;
}
export interface GroupCreatedUpdatedMessageInterface {
position: PositionInterface,
groupId: number,
groupSize: number
position: PositionInterface;
groupId: number;
groupSize: number;
}
export interface WebRtcDisconnectMessageInterface {
userId: number
userId: number;
}
export interface WebRtcSignalReceivedMessageInterface {
userId: number,
signal: SignalData,
webRtcUser: string | undefined,
webRtcPassword: string | undefined
userId: number;
signal: SignalData;
webRtcUser: string | undefined;
webRtcPassword: string | undefined;
}
export interface ViewportInterface {
left: number,
top: number,
right: number,
bottom: number,
left: number;
top: number;
right: number;
bottom: number;
}
export interface ItemEventMessageInterface {
itemId: number,
event: string,
state: unknown,
parameters: unknown
itemId: number;
event: string;
state: unknown;
parameters: unknown;
}
export interface RoomJoinedMessageInterface {
//users: MessageUserPositionInterface[],
//groups: GroupCreatedUpdatedMessageInterface[],
items: { [itemId: number] : unknown }
items: { [itemId: number]: unknown };
}
export interface PlayGlobalMessageInterface {
id: string
type: string
message: string
id: string;
type: string;
message: string;
}
export interface OnConnectInterface {
connection: RoomConnection,
room: RoomJoinedMessageInterface
connection: RoomConnection;
room: RoomJoinedMessageInterface;
}

View file

@ -1,90 +1,105 @@
import Axios from "axios";
import {PUSHER_URL} from "../Enum/EnvironmentVariable";
import type {CharacterTexture} from "./LocalUser";
import { PUSHER_URL } from "../Enum/EnvironmentVariable";
import type { CharacterTexture } from "./LocalUser";
export class MapDetail{
constructor(public readonly mapUrl: string, public readonly textures : CharacterTexture[]|undefined) {
}
export class MapDetail {
constructor(public readonly mapUrl: string, public readonly textures: CharacterTexture[] | undefined) {}
}
export interface RoomRedirect {
redirectUrl: string;
}
export class Room {
public readonly id: string;
public readonly isPublic: boolean;
private mapUrl: string|undefined;
private textures: CharacterTexture[]|undefined;
private instance: string|undefined;
private _search: URLSearchParams;
private _mapUrl: string | undefined;
private _textures: CharacterTexture[] | undefined;
private instance: string | undefined;
private readonly _search: URLSearchParams;
constructor(id: string) {
const url = new URL(id, 'https://example.com');
private constructor(private roomUrl: URL) {
this.id = roomUrl.pathname;
this.id = url.pathname;
if (this.id.startsWith('/')) {
if (this.id.startsWith("/")) {
this.id = this.id.substr(1);
}
if (this.id.startsWith('_/')) {
if (this.id.startsWith("_/")) {
this.isPublic = true;
} else if (this.id.startsWith('@/')) {
} else if (this.id.startsWith("@/")) {
this.isPublic = false;
} else {
throw new Error('Invalid room ID');
throw new Error("Invalid room ID");
}
this._search = new URLSearchParams(url.search);
this._search = new URLSearchParams(roomUrl.search);
}
public static getIdFromIdentifier(identifier: string, baseUrl: string, currentInstance: string): {roomId: string, hash: string} {
let roomId = '';
let hash = '';
if (!identifier.startsWith('/_/') && !identifier.startsWith('/@/')) { //relative file link
//Relative identifier can be deep enough to rewrite the base domain, so we cannot use the variable 'baseUrl' as the actual base url for the URL objects.
//We instead use 'workadventure' as a dummy base value.
const baseUrlObject = new URL(baseUrl);
const absoluteExitSceneUrl = new URL(identifier, 'http://workadventure/_/'+currentInstance+'/'+baseUrlObject.hostname+baseUrlObject.pathname);
roomId = absoluteExitSceneUrl.pathname; //in case of a relative url, we need to create a public roomId
roomId = roomId.substring(1); //remove the leading slash
hash = absoluteExitSceneUrl.hash;
hash = hash.substring(1); //remove the leading diese
} else { //absolute room Id
const parts = identifier.split('#');
roomId = parts[0];
roomId = roomId.substring(1); //remove the leading slash
if (parts.length > 1) {
hash = parts[1]
/**
* Creates a "Room" object representing the room.
* This method will follow room redirects if necessary, so the instance returned is a "real" room.
*/
public static async createRoom(roomUrl: URL): Promise<Room> {
let redirectCount = 0;
while (redirectCount < 32) {
const room = new Room(roomUrl);
const result = await room.getMapDetail();
if (result instanceof MapDetail) {
return room;
}
redirectCount++;
roomUrl = new URL(result.redirectUrl);
}
return {roomId, hash}
throw new Error("Room resolving seems stuck in a redirect loop after 32 redirect attempts");
}
public async getMapDetail(): Promise<MapDetail> {
return new Promise<MapDetail>((resolve, reject) => {
if (this.mapUrl !== undefined && this.textures != undefined) {
resolve(new MapDetail(this.mapUrl, this.textures));
return;
}
public static getRoomPathFromExitUrl(exitUrl: string, currentRoomUrl: string): URL {
const url = new URL(exitUrl, currentRoomUrl);
return url;
}
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(new MapDetail(this.mapUrl, this.textures));
return;
} else {
// We have a private ID, we need to query the map URL from the server.
const urlParts = this.parsePrivateUrl(this.id);
/**
* @deprecated USage of exitSceneUrl is deprecated and therefore, this method is deprecated too.
*/
public static getRoomPathFromExitSceneUrl(
exitSceneUrl: string,
currentRoomUrl: string,
currentMapUrl: string
): URL {
const absoluteExitSceneUrl = new URL(exitSceneUrl, currentMapUrl);
const baseUrl = new URL(currentRoomUrl);
Axios.get(`${PUSHER_URL}/map`, {
params: urlParts
}).then(({data}) => {
console.log('Map ', this.id, ' resolves to URL ', data.mapUrl);
resolve(data);
return;
}).catch((reason) => {
reject(reason);
});
}
const currentRoom = new Room(baseUrl);
let instance: string = "global";
if (currentRoom.isPublic) {
instance = currentRoom.instance as string;
}
baseUrl.pathname = "/_/" + instance + "/" + absoluteExitSceneUrl.host + absoluteExitSceneUrl.pathname;
if (absoluteExitSceneUrl.hash) {
baseUrl.hash = absoluteExitSceneUrl.hash;
}
return baseUrl;
}
private async getMapDetail(): Promise<MapDetail | RoomRedirect> {
const result = await Axios.get(`${PUSHER_URL}/map`, {
params: {
playUri: this.roomUrl.toString(),
},
});
const data = result.data;
if (data.redirectUrl) {
return {
redirectUrl: data.redirectUrl as string,
};
}
console.log("Map ", this.id, " resolves to URL ", data.mapUrl);
this._mapUrl = data.mapUrl;
this._textures = data.textures;
return new MapDetail(data.mapUrl, data.textures);
}
/**
@ -99,37 +114,39 @@ export class Room {
if (this.isPublic) {
const match = /_\/([^/]+)\/.+/.exec(this.id);
if (!match) throw new Error('Could not extract instance from "'+this.id+'"');
if (!match) throw new Error('Could not extract instance from "' + this.id + '"');
this.instance = match[1];
return this.instance;
} else {
const match = /@\/([^/]+)\/([^/]+)\/.+/.exec(this.id);
if (!match) throw new Error('Could not extract instance from "'+this.id+'"');
this.instance = match[1]+'/'+match[2];
if (!match) throw new Error('Could not extract instance from "' + this.id + '"');
this.instance = match[1] + "/" + match[2];
return this.instance;
}
}
private parsePrivateUrl(url: string): { organizationSlug: string, worldSlug: string, roomSlug?: string } {
/**
* @deprecated
*/
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);
throw new Error("Invalid URL " + url);
}
const results: { organizationSlug: string, worldSlug: string, roomSlug?: string } = {
const results: { organizationSlug: string; worldSlug: string; roomSlug?: string } = {
organizationSlug: match[1],
worldSlug: match[2],
}
};
if (match[3] !== undefined) {
results.roomSlug = match[3];
}
return results;
}
public isDisconnected(): boolean
{
const alone = this._search.get('alone');
if (alone && alone !== '0' && alone.toLowerCase() !== 'false') {
public isDisconnected(): boolean {
const alone = this._search.get("alone");
if (alone && alone !== "0" && alone.toLowerCase() !== "false") {
return true;
}
return false;
@ -138,4 +155,32 @@ export class Room {
public get search(): URLSearchParams {
return this._search;
}
/**
* 2 rooms are equal if they share the same path (but not necessarily the same hash)
* @param room
*/
public isEqual(room: Room): boolean {
return room.key === this.key;
}
/**
* A key representing this room
*/
public get key(): string {
const newUrl = new URL(this.roomUrl.toString());
newUrl.hash = "";
return newUrl.toString();
}
get textures(): CharacterTexture[] | undefined {
return this._textures;
}
get mapUrl(): string {
if (!this._mapUrl) {
throw new Error("Map URL not fetched yet");
}
return this._mapUrl;
}
}

View file

@ -11,7 +11,8 @@ import {
RoomJoinedMessage,
ServerToClientMessage,
SetPlayerDetailsMessage,
SilentMessage, StopGlobalMessage,
SilentMessage,
StopGlobalMessage,
UserJoinedMessage,
UserLeftMessage,
UserMovedMessage,
@ -31,17 +32,22 @@ import {
EmotePromptMessage,
SendUserMessage,
BanUserMessage,
} from "../Messages/generated/messages_pb"
} from "../Messages/generated/messages_pb";
import type { UserSimplePeerInterface } from "../WebRtc/SimplePeer";
import Direction = PositionMessage.Direction;
import { ProtobufClientUtils } from "../Network/ProtobufClientUtils";
import {
EventMessage,
GroupCreatedUpdatedMessageInterface, ItemEventMessageInterface,
MessageUserJoined, OnConnectInterface, PlayGlobalMessageInterface, PositionInterface,
GroupCreatedUpdatedMessageInterface,
ItemEventMessageInterface,
MessageUserJoined,
OnConnectInterface,
PlayGlobalMessageInterface,
PositionInterface,
RoomJoinedMessageInterface,
ViewportInterface, WebRtcDisconnectMessageInterface,
ViewportInterface,
WebRtcDisconnectMessageInterface,
WebRtcSignalReceivedMessageInterface,
} from "./ConnexionModels";
import type { BodyResourceDescriptionInterface } from "../Phaser/Entity/PlayerTextures";
@ -61,36 +67,45 @@ export class RoomConnection implements RoomConnection {
private closed: boolean = false;
private tags: string[] = [];
public static setWebsocketFactory(websocketFactory: (url: string) => any): void { // eslint-disable-line @typescript-eslint/no-explicit-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public static setWebsocketFactory(websocketFactory: (url: string) => any): void {
RoomConnection.websocketFactory = websocketFactory;
}
/**
*
* @param token A JWT token containing the UUID of the user
* @param roomId The ID of the room in the form "_/[instance]/[map_url]" or "@/[org]/[event]/[map]"
* @param roomUrl The URL of the room in the form "https://example.com/_/[instance]/[map_url]" or "https://example.com/@/[org]/[event]/[map]"
*/
public constructor(token: string | null, roomId: string, name: string, characterLayers: string[], position: PositionInterface, viewport: ViewportInterface, companion: string | null) {
public constructor(
token: string | null,
roomUrl: string,
name: string,
characterLayers: string[],
position: PositionInterface,
viewport: ViewportInterface,
companion: string | null
) {
let url = new URL(PUSHER_URL, window.location.toString()).toString();
url = url.replace('http://', 'ws://').replace('https://', 'wss://');
if (!url.endsWith('/')) {
url += '/';
url = url.replace("http://", "ws://").replace("https://", "wss://");
if (!url.endsWith("/")) {
url += "/";
}
url += 'room';
url += '?roomId=' + (roomId ? encodeURIComponent(roomId) : '');
url += '&token=' + (token ? encodeURIComponent(token) : '');
url += '&name=' + encodeURIComponent(name);
url += "room";
url += "?roomId=" + encodeURIComponent(roomUrl);
url += "&token=" + (token ? encodeURIComponent(token) : "");
url += "&name=" + encodeURIComponent(name);
for (const layer of characterLayers) {
url += '&characterLayers=' + encodeURIComponent(layer);
url += "&characterLayers=" + encodeURIComponent(layer);
}
url += '&x=' + Math.floor(position.x);
url += '&y=' + Math.floor(position.y);
url += '&top=' + Math.floor(viewport.top);
url += '&bottom=' + Math.floor(viewport.bottom);
url += '&left=' + Math.floor(viewport.left);
url += '&right=' + Math.floor(viewport.right);
if (typeof companion === 'string') {
url += '&companion=' + encodeURIComponent(companion);
url += "&x=" + Math.floor(position.x);
url += "&y=" + Math.floor(position.y);
url += "&top=" + Math.floor(viewport.top);
url += "&bottom=" + Math.floor(viewport.bottom);
url += "&left=" + Math.floor(viewport.left);
url += "&right=" + Math.floor(viewport.right);
if (typeof companion === "string") {
url += "&companion=" + encodeURIComponent(companion);
}
if (RoomConnection.websocketFactory) {
@ -99,7 +114,7 @@ export class RoomConnection implements RoomConnection {
this.socket = new WebSocket(url);
}
this.socket.binaryType = 'arraybuffer';
this.socket.binaryType = "arraybuffer";
let interval: ReturnType<typeof setInterval> | undefined = undefined;
@ -109,7 +124,7 @@ export class RoomConnection implements RoomConnection {
interval = setInterval(() => this.socket.send(pingMessage.serializeBinary().buffer), manualPingDelay);
};
this.socket.addEventListener('close', (event) => {
this.socket.addEventListener("close", (event) => {
if (interval) {
clearInterval(interval);
}
@ -126,7 +141,7 @@ export class RoomConnection implements RoomConnection {
if (message.hasBatchmessage()) {
for (const subMessage of (message.getBatchmessage() as BatchMessage).getPayloadList()) {
let event: string|null = null;
let event: string | null = null;
let payload;
if (subMessage.hasUsermovedmessage()) {
event = EventMessage.USER_MOVED;
@ -150,7 +165,7 @@ export class RoomConnection implements RoomConnection {
const emoteMessage = subMessage.getEmoteeventmessage() as EmoteEventMessage;
emoteEventStream.fire(emoteMessage.getActoruserid(), emoteMessage.getEmote());
} else {
throw new Error('Unexpected batch message type');
throw new Error("Unexpected batch message type");
}
if (event) {
@ -171,8 +186,8 @@ export class RoomConnection implements RoomConnection {
this.dispatch(EventMessage.CONNECT, {
connection: this,
room: {
items
} as RoomJoinedMessageInterface
items,
} as RoomJoinedMessageInterface,
});
} else if (message.hasWorldfullmessage()) {
worldFullMessageStream.onMessage();
@ -183,7 +198,10 @@ export class RoomConnection implements RoomConnection {
} else if (message.hasWebrtcsignaltoclientmessage()) {
this.dispatch(EventMessage.WEBRTC_SIGNAL, message.getWebrtcsignaltoclientmessage());
} else if (message.hasWebrtcscreensharingsignaltoclientmessage()) {
this.dispatch(EventMessage.WEBRTC_SCREEN_SHARING_SIGNAL, message.getWebrtcscreensharingsignaltoclientmessage());
this.dispatch(
EventMessage.WEBRTC_SCREEN_SHARING_SIGNAL,
message.getWebrtcscreensharingsignaltoclientmessage()
);
} else if (message.hasWebrtcstartmessage()) {
this.dispatch(EventMessage.WEBRTC_START, message.getWebrtcstartmessage());
} else if (message.hasWebrtcdisconnectmessage()) {
@ -205,10 +223,9 @@ export class RoomConnection implements RoomConnection {
} else if (message.hasRefreshroommessage()) {
//todo: implement a way to notify the user the room was refreshed.
} else {
throw new Error('Unknown message received');
throw new Error("Unknown message received");
}
}
};
}
private dispatch(event: string, payload: unknown): void {
@ -243,16 +260,16 @@ export class RoomConnection implements RoomConnection {
positionMessage.setY(Math.floor(y));
let directionEnum: Direction;
switch (direction) {
case 'up':
case "up":
directionEnum = Direction.UP;
break;
case 'down':
case "down":
directionEnum = Direction.DOWN;
break;
case 'left':
case "left":
directionEnum = Direction.LEFT;
break;
case 'right':
case "right":
directionEnum = Direction.RIGHT;
break;
default:
@ -327,15 +344,17 @@ export class RoomConnection implements RoomConnection {
private toMessageUserJoined(message: UserJoinedMessage): MessageUserJoined {
const position = message.getPosition();
if (position === undefined) {
throw new Error('Invalid JOIN_ROOM message');
throw new Error("Invalid JOIN_ROOM message");
}
const characterLayers = message.getCharacterlayersList().map((characterLayer: CharacterLayerMessage): BodyResourceDescriptionInterface => {
return {
name: characterLayer.getName(),
img: characterLayer.getUrl()
}
})
const characterLayers = message
.getCharacterlayersList()
.map((characterLayer: CharacterLayerMessage): BodyResourceDescriptionInterface => {
return {
name: characterLayer.getName(),
img: characterLayer.getUrl(),
};
});
const companion = message.getCompanion();
@ -345,8 +364,9 @@ export class RoomConnection implements RoomConnection {
characterLayers,
visitCardUrl: message.getVisitcardurl(),
position: ProtobufClientUtils.toPointInterface(position),
companion: companion ? companion.getName() : null
}
companion: companion ? companion.getName() : null,
userUuid: message.getUseruuid(),
};
}
public onUserMoved(callback: (message: UserMovedMessage) => void): void {
@ -372,7 +392,9 @@ export class RoomConnection implements RoomConnection {
});
}
public onGroupUpdatedOrCreated(callback: (groupCreateUpdateMessage: GroupCreatedUpdatedMessageInterface) => void): void {
public onGroupUpdatedOrCreated(
callback: (groupCreateUpdateMessage: GroupCreatedUpdatedMessageInterface) => void
): void {
this.onMessage(EventMessage.GROUP_CREATE_UPDATE, (message: GroupUpdateMessage) => {
callback(this.toGroupCreatedUpdatedMessage(message));
});
@ -381,14 +403,14 @@ export class RoomConnection implements RoomConnection {
private toGroupCreatedUpdatedMessage(message: GroupUpdateMessage): GroupCreatedUpdatedMessageInterface {
const position = message.getPosition();
if (position === undefined) {
throw new Error('Missing position in GROUP_CREATE_UPDATE');
throw new Error("Missing position in GROUP_CREATE_UPDATE");
}
return {
groupId: message.getGroupid(),
position: position.toObject(),
groupSize: message.getGroupsize()
}
groupSize: message.getGroupsize(),
};
}
public onGroupDeleted(callback: (groupId: number) => void): void {
@ -404,7 +426,7 @@ export class RoomConnection implements RoomConnection {
}
public onConnectError(callback: (error: Event) => void): void {
this.socket.addEventListener('error', callback)
this.socket.addEventListener("error", callback);
}
public onConnect(callback: (roomConnection: OnConnectInterface) => void): void {
@ -445,7 +467,6 @@ export class RoomConnection implements RoomConnection {
this.onMessage(EventMessage.WEBRTC_START, (message: WebRtcStartMessage) => {
callback({
userId: message.getUserid(),
name: message.getName(),
initiator: message.getInitiator(),
webRtcUser: message.getWebrtcusername() ?? undefined,
webRtcPassword: message.getWebrtcpassword() ?? undefined,
@ -476,11 +497,11 @@ export class RoomConnection implements RoomConnection {
}
public onServerDisconnected(callback: () => void): void {
this.socket.addEventListener('close', (event) => {
this.socket.addEventListener("close", (event) => {
if (this.closed === true || connectionManager.unloading) {
return;
}
console.log('Socket closed with code ' + event.code + ". Reason: " + event.reason);
console.log("Socket closed with code " + event.code + ". Reason: " + event.reason);
if (event.code === 1000) {
// Normal closure case
return;
@ -490,14 +511,14 @@ export class RoomConnection implements RoomConnection {
}
public getUserId(): number {
if (this.userId === null) throw 'UserId cannot be null!'
if (this.userId === null) throw "UserId cannot be null!";
return this.userId;
}
disconnectMessage(callback: (message: WebRtcDisconnectMessageInterface) => void): void {
this.onMessage(EventMessage.WEBRTC_DISCONNECT, (message: WebRtcDisconnectMessage) => {
callback({
userId: message.getUserid()
userId: message.getUserid(),
});
});
}
@ -521,21 +542,22 @@ export class RoomConnection implements RoomConnection {
itemId: message.getItemid(),
event: message.getEvent(),
parameters: JSON.parse(message.getParametersjson()),
state: JSON.parse(message.getStatejson())
state: JSON.parse(message.getStatejson()),
});
});
}
public uploadAudio(file: FormData) {
return Axios.post(`${UPLOADER_URL}/upload-audio-message`, file).then((res: { data: {} }) => {
return res.data;
}).catch((err) => {
console.error(err);
throw err;
});
return Axios.post(`${UPLOADER_URL}/upload-audio-message`, file)
.then((res: { data: {} }) => {
return res.data;
})
.catch((err) => {
console.error(err);
throw err;
});
}
public receivePlayGlobalMessage(callback: (message: PlayGlobalMessageInterface) => void) {
return this.onMessage(EventMessage.PLAY_GLOBAL_MESSAGE, (message: PlayGlobalMessage) => {
callback({
@ -570,9 +592,9 @@ export class RoomConnection implements RoomConnection {
this.socket.send(clientToServerMessage.serializeBinary().buffer);
}
public emitReportPlayerMessage(reportedUserId: number, reportComment: string): void {
public emitReportPlayerMessage(reportedUserUuid: string, reportComment: string): void {
const reportPlayerMessage = new ReportPlayerMessage();
reportPlayerMessage.setReporteduserid(reportedUserId);
reportPlayerMessage.setReporteduseruuid(reportedUserUuid);
reportPlayerMessage.setReportcomment(reportComment);
const clientToServerMessage = new ClientToServerMessage();
@ -605,12 +627,12 @@ export class RoomConnection implements RoomConnection {
}
public isAdmin(): boolean {
return this.hasTag('admin');
return this.hasTag("admin");
}
public emitEmoteEvent(emoteName: string): void {
const emoteMessage = new EmotePromptMessage();
emoteMessage.setEmote(emoteName)
emoteMessage.setEmote(emoteName);
const clientToServerMessage = new ClientToServerMessage();
clientToServerMessage.setEmotepromptmessage(emoteMessage);
@ -618,7 +640,7 @@ export class RoomConnection implements RoomConnection {
this.socket.send(clientToServerMessage.serializeBinary().buffer);
}
public getAllTags() : string[] {
public getAllTags(): string[] {
return this.tags;
}
}