2021-05-10 21:48:11 +02:00
import { PUSHER_URL , UPLOADER_URL } from "../Enum/EnvironmentVariable" ;
2020-10-01 14:11:34 +02:00
import Axios from "axios" ;
2020-09-18 13:57:38 +02:00
import {
2020-09-29 16:01:22 +02:00
BatchMessage ,
ClientToServerMessage ,
GroupDeleteMessage ,
GroupUpdateMessage ,
ItemEventMessage ,
2020-10-06 18:09:23 +02:00
PlayGlobalMessage ,
2020-09-29 16:01:22 +02:00
PositionMessage ,
RoomJoinedMessage ,
ServerToClientMessage ,
SetPlayerDetailsMessage ,
2021-06-25 18:14:40 +02:00
SilentMessage ,
StopGlobalMessage ,
2020-09-29 16:01:22 +02:00
UserJoinedMessage ,
UserLeftMessage ,
UserMovedMessage ,
2020-09-18 13:57:38 +02:00
UserMovesMessage ,
2020-09-29 16:01:22 +02:00
ViewportMessage ,
WebRtcDisconnectMessage ,
WebRtcSignalToClientMessage ,
WebRtcSignalToServerMessage ,
2020-10-12 11:22:41 +02:00
WebRtcStartMessage ,
2020-10-13 11:39:07 +02:00
ReportPlayerMessage ,
2020-10-20 16:39:23 +02:00
TeleportMessageMessage ,
QueryJitsiJwtMessage ,
SendJitsiJwtMessage ,
CharacterLayerMessage ,
2020-11-10 18:26:46 +01:00
PingMessage ,
2021-03-31 11:21:06 +02:00
EmoteEventMessage ,
EmotePromptMessage ,
2021-05-12 09:13:25 +02:00
SendUserMessage ,
2021-06-08 16:30:58 +02:00
BanUserMessage ,
2021-07-19 10:16:43 +02:00
VariableMessage , ErrorMessage ,
2021-06-25 18:14:40 +02:00
} from "../Messages/generated/messages_pb" ;
2020-05-15 22:40:06 +02:00
2021-05-18 15:18:35 +02:00
import type { UserSimplePeerInterface } from "../WebRtc/SimplePeer" ;
2020-09-18 13:57:38 +02:00
import Direction = PositionMessage . Direction ;
2021-05-10 21:48:11 +02:00
import { ProtobufClientUtils } from "../Network/ProtobufClientUtils" ;
2020-09-25 18:29:22 +02:00
import {
EventMessage ,
2021-06-25 18:14:40 +02:00
GroupCreatedUpdatedMessageInterface ,
ItemEventMessageInterface ,
MessageUserJoined ,
OnConnectInterface ,
PlayGlobalMessageInterface ,
PositionInterface ,
2020-09-25 18:29:22 +02:00
RoomJoinedMessageInterface ,
2021-06-25 18:14:40 +02:00
ViewportInterface ,
WebRtcDisconnectMessageInterface ,
2020-09-25 18:29:22 +02:00
WebRtcSignalReceivedMessageInterface ,
} from "./ConnexionModels" ;
2021-05-18 15:18:35 +02:00
import type { BodyResourceDescriptionInterface } from "../Phaser/Entity/PlayerTextures" ;
2021-05-10 21:48:11 +02:00
import { adminMessagesService } from "./AdminMessagesService" ;
import { worldFullMessageStream } from "./WorldFullMessageStream" ;
import { worldFullWarningStream } from "./WorldFullWarningStream" ;
import { connectionManager } from "./ConnectionManager" ;
2021-05-26 10:58:25 +02:00
import { emoteEventStream } from "./EmoteEventStream" ;
2020-09-25 18:29:22 +02:00
2020-11-10 18:26:46 +01:00
const manualPingDelay = 20000 ;
2020-09-25 18:29:22 +02:00
export class RoomConnection implements RoomConnection {
2020-09-28 18:52:54 +02:00
private readonly socket : WebSocket ;
2021-05-10 21:48:11 +02:00
private userId : number | null = null ;
2020-09-29 16:01:22 +02:00
private listeners : Map < string , Function [ ] > = new Map < string , Function [ ] > ( ) ;
2021-05-10 21:48:11 +02:00
private static websocketFactory : null | ( ( url : string ) = > any ) = null ; // eslint-disable-line @typescript-eslint/no-explicit-any
2020-10-01 17:16:49 +02:00
private closed : boolean = false ;
2020-10-14 11:07:34 +02:00
private tags : string [ ] = [ ] ;
2020-04-07 20:41:35 +02:00
2021-06-25 18:45:15 +02:00
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2021-06-25 18:14:40 +02:00
public static setWebsocketFactory ( websocketFactory : ( url : string ) = > any ) : void {
2020-09-29 17:12:28 +02:00
RoomConnection . websocketFactory = websocketFactory ;
2020-09-28 18:52:54 +02:00
}
2020-06-22 15:00:23 +02:00
2020-10-06 18:09:23 +02:00
/ * *
*
* @param token A JWT token containing the UUID of the user
2021-07-13 19:09:07 +02:00
* @param roomUrl The URL of the room in the form "https://example.com/_/[instance]/[map_url]" or "https://example.com/@/[org]/[event]/[map]"
2020-10-06 18:09:23 +02:00
* /
2021-06-25 18:14:40 +02:00
public constructor (
token : string | null ,
2021-07-13 19:09:07 +02:00
roomUrl : string ,
2021-06-25 18:14:40 +02:00
name : string ,
characterLayers : string [ ] ,
position : PositionInterface ,
viewport : ViewportInterface ,
companion : string | null
) {
2021-03-31 16:38:51 +02:00
let url = new URL ( PUSHER_URL , window . location . toString ( ) ) . toString ( ) ;
2021-06-25 18:14:40 +02:00
url = url . replace ( "http://" , "ws://" ) . replace ( "https://" , "wss://" ) ;
if ( ! url . endsWith ( "/" ) ) {
url += "/" ;
2021-03-31 17:50:27 +02:00
}
2021-06-25 18:14:40 +02:00
url += "room" ;
2021-07-15 17:12:54 +02:00
url += "?roomId=" + encodeURIComponent ( roomUrl ) ;
2021-06-25 18:14:40 +02:00
url += "&token=" + ( token ? encodeURIComponent ( token ) : "" ) ;
url += "&name=" + encodeURIComponent ( name ) ;
2020-10-09 17:14:03 +02:00
for ( const layer of characterLayers ) {
2021-06-25 18:14:40 +02:00
url += "&characterLayers=" + encodeURIComponent ( layer ) ;
2020-10-06 18:09:23 +02:00
}
2021-06-25 18:14:40 +02:00
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 ) ;
2021-04-02 21:21:11 +02:00
}
2020-09-15 10:06:11 +02:00
2020-09-29 17:12:28 +02:00
if ( RoomConnection . websocketFactory ) {
this . socket = RoomConnection . websocketFactory ( url ) ;
2020-09-28 18:52:54 +02:00
} else {
this . socket = new WebSocket ( url ) ;
}
2020-09-18 15:51:15 +02:00
2021-06-25 18:14:40 +02:00
this . socket . binaryType = "arraybuffer" ;
2020-09-28 18:52:54 +02:00
2021-05-10 21:48:11 +02:00
let interval : ReturnType < typeof setInterval > | undefined = undefined ;
2020-12-03 16:39:44 +01:00
2020-09-28 18:52:54 +02:00
this . socket . onopen = ( ev ) = > {
2020-11-10 18:26:46 +01:00
//we manually ping every 20s to not be logged out by the server, even when the game is in background.
const pingMessage = new PingMessage ( ) ;
2020-12-03 16:39:44 +01:00
interval = setInterval ( ( ) = > this . socket . send ( pingMessage . serializeBinary ( ) . buffer ) , manualPingDelay ) ;
2020-09-28 18:52:54 +02:00
} ;
2021-06-25 18:14:40 +02:00
this . socket . addEventListener ( "close" , ( event ) = > {
2020-12-03 16:39:44 +01:00
if ( interval ) {
clearInterval ( interval ) ;
}
// If we are not connected yet (if a JoinRoomMessage was not sent), we need to retry.
2021-03-05 18:25:27 +01:00
if ( this . userId === null && ! this . closed ) {
2020-12-03 16:39:44 +01:00
this . dispatch ( EventMessage . CONNECTING_ERROR , event ) ;
}
} ) ;
2020-09-28 18:52:54 +02:00
this . socket . onmessage = ( messageEvent ) = > {
const arrayBuffer : ArrayBuffer = messageEvent . data ;
const message = ServerToClientMessage . deserializeBinary ( new Uint8Array ( arrayBuffer ) ) ;
if ( message . hasBatchmessage ( ) ) {
for ( const subMessage of ( message . getBatchmessage ( ) as BatchMessage ) . getPayloadList ( ) ) {
2021-06-25 18:14:40 +02:00
let event : string | null = null ;
2020-09-28 18:52:54 +02:00
let payload ;
if ( subMessage . hasUsermovedmessage ( ) ) {
event = EventMessage . USER_MOVED ;
payload = subMessage . getUsermovedmessage ( ) ;
} else if ( subMessage . hasGroupupdatemessage ( ) ) {
event = EventMessage . GROUP_CREATE_UPDATE ;
payload = subMessage . getGroupupdatemessage ( ) ;
} else if ( subMessage . hasGroupdeletemessage ( ) ) {
event = EventMessage . GROUP_DELETE ;
payload = subMessage . getGroupdeletemessage ( ) ;
} else if ( subMessage . hasUserjoinedmessage ( ) ) {
event = EventMessage . JOIN_ROOM ;
payload = subMessage . getUserjoinedmessage ( ) ;
} else if ( subMessage . hasUserleftmessage ( ) ) {
event = EventMessage . USER_LEFT ;
payload = subMessage . getUserleftmessage ( ) ;
} else if ( subMessage . hasItemeventmessage ( ) ) {
event = EventMessage . ITEM_EVENT ;
payload = subMessage . getItemeventmessage ( ) ;
2021-03-31 11:21:06 +02:00
} else if ( subMessage . hasEmoteeventmessage ( ) ) {
const emoteMessage = subMessage . getEmoteeventmessage ( ) as EmoteEventMessage ;
2021-05-21 16:25:12 +02:00
emoteEventStream . fire ( emoteMessage . getActoruserid ( ) , emoteMessage . getEmote ( ) ) ;
2021-07-19 10:16:43 +02:00
} else if ( subMessage . hasErrormessage ( ) ) {
const errorMessage = subMessage . getErrormessage ( ) as ErrorMessage ;
console . error ( 'An error occurred server side: ' + errorMessage . getMessage ( ) ) ;
2021-07-07 17:17:28 +02:00
} else if ( subMessage . hasVariablemessage ( ) ) {
event = EventMessage . SET_VARIABLE ;
payload = subMessage . getVariablemessage ( ) ;
2020-09-28 18:52:54 +02:00
} else {
2021-06-25 18:14:40 +02:00
throw new Error ( "Unexpected batch message type" ) ;
2020-09-28 18:52:54 +02:00
}
2021-03-31 11:21:06 +02:00
if ( event ) {
this . dispatch ( event , payload ) ;
}
2020-09-18 15:51:15 +02:00
}
2020-09-28 18:52:54 +02:00
} else if ( message . hasRoomjoinedmessage ( ) ) {
const roomJoinedMessage = message . getRoomjoinedmessage ( ) as RoomJoinedMessage ;
2021-05-10 21:48:11 +02:00
const items : { [ itemId : number ] : unknown } = { } ;
2020-09-28 18:52:54 +02:00
for ( const item of roomJoinedMessage . getItemList ( ) ) {
items [ item . getItemid ( ) ] = JSON . parse ( item . getStatejson ( ) ) ;
2020-09-15 10:06:11 +02:00
}
2020-09-28 18:52:54 +02:00
2021-07-07 17:17:28 +02:00
const variables = new Map < string , unknown > ( ) ;
for ( const variable of roomJoinedMessage . getVariableList ( ) ) {
2021-07-19 18:46:33 +02:00
try {
variables . set ( variable . getName ( ) , JSON . parse ( variable . getValue ( ) ) ) ;
} catch ( e ) {
console . error ( 'Unable to unserialize value received from server for variable "' + variable . getName ( ) + '". Value received: "' + variable . getValue ( ) + '". Error: ' , e ) ;
}
2021-07-07 17:17:28 +02:00
}
2020-10-13 16:46:46 +02:00
this . userId = roomJoinedMessage . getCurrentuserid ( ) ;
2020-10-14 11:07:34 +02:00
this . tags = roomJoinedMessage . getTagList ( ) ;
2020-10-13 16:46:46 +02:00
2020-12-03 16:39:44 +01:00
this . dispatch ( EventMessage . CONNECT , {
connection : this ,
room : {
2021-06-25 18:14:40 +02:00
items ,
2021-07-07 17:17:28 +02:00
variables ,
2021-06-25 18:14:40 +02:00
} as RoomJoinedMessageInterface ,
2020-12-03 16:39:44 +01:00
} ) ;
2021-03-11 16:14:34 +01:00
} else if ( message . hasWorldfullmessage ( ) ) {
worldFullMessageStream . onMessage ( ) ;
2021-03-05 18:25:27 +01:00
this . closed = true ;
2021-04-29 23:47:30 +02:00
} else if ( message . hasWorldconnexionmessage ( ) ) {
worldFullMessageStream . onMessage ( message . getWorldconnexionmessage ( ) ? . getMessage ( ) ) ;
this . closed = true ;
2021-05-10 21:48:11 +02:00
} else if ( message . hasWebrtcsignaltoclientmessage ( ) ) {
2020-09-29 16:01:22 +02:00
this . dispatch ( EventMessage . WEBRTC_SIGNAL , message . getWebrtcsignaltoclientmessage ( ) ) ;
} else if ( message . hasWebrtcscreensharingsignaltoclientmessage ( ) ) {
2021-06-25 18:14:40 +02:00
this . dispatch (
EventMessage . WEBRTC_SCREEN_SHARING_SIGNAL ,
message . getWebrtcscreensharingsignaltoclientmessage ( )
) ;
2020-09-29 16:01:22 +02:00
} else if ( message . hasWebrtcstartmessage ( ) ) {
this . dispatch ( EventMessage . WEBRTC_START , message . getWebrtcstartmessage ( ) ) ;
} else if ( message . hasWebrtcdisconnectmessage ( ) ) {
this . dispatch ( EventMessage . WEBRTC_DISCONNECT , message . getWebrtcdisconnectmessage ( ) ) ;
2020-10-01 14:11:34 +02:00
} else if ( message . hasPlayglobalmessage ( ) ) {
this . dispatch ( EventMessage . PLAY_GLOBAL_MESSAGE , message . getPlayglobalmessage ( ) ) ;
} else if ( message . hasStopglobalmessage ( ) ) {
this . dispatch ( EventMessage . STOP_GLOBAL_MESSAGE , message . getStopglobalmessage ( ) ) ;
2020-10-13 11:39:07 +02:00
} else if ( message . hasTeleportmessagemessage ( ) ) {
this . dispatch ( EventMessage . TELEPORT , message . getTeleportmessagemessage ( ) ) ;
2020-10-16 19:13:26 +02:00
} else if ( message . hasSendjitsijwtmessage ( ) ) {
this . dispatch ( EventMessage . START_JITSI_ROOM , message . getSendjitsijwtmessage ( ) ) ;
2020-10-19 19:32:47 +02:00
} else if ( message . hasSendusermessage ( ) ) {
2021-03-01 17:47:00 +01:00
adminMessagesService . onSendusermessage ( message . getSendusermessage ( ) as SendUserMessage ) ;
2021-03-11 01:25:36 +01:00
} else if ( message . hasBanusermessage ( ) ) {
2021-04-19 20:19:40 +02:00
adminMessagesService . onSendusermessage ( message . getBanusermessage ( ) as BanUserMessage ) ;
2021-03-11 16:14:34 +01:00
} else if ( message . hasWorldfullwarningmessage ( ) ) {
worldFullWarningStream . onMessage ( ) ;
2021-04-01 16:43:12 +02:00
} else if ( message . hasRefreshroommessage ( ) ) {
//todo: implement a way to notify the user the room was refreshed.
2020-09-29 16:01:22 +02:00
} else {
2021-06-25 18:14:40 +02:00
throw new Error ( "Unknown message received" ) ;
2020-09-15 10:06:11 +02:00
}
2021-06-25 18:14:40 +02:00
} ;
2020-04-10 12:54:05 +02:00
}
2020-09-29 16:01:22 +02:00
private dispatch ( event : string , payload : unknown ) : void {
const listeners = this . listeners . get ( event ) ;
if ( listeners === undefined ) {
return ;
}
for ( const listener of listeners ) {
listener ( payload ) ;
}
}
2020-10-20 16:39:23 +02:00
public emitPlayerDetailsMessage ( userName : string , characterLayersSelected : BodyResourceDescriptionInterface [ ] ) {
2020-09-25 18:29:22 +02:00
const message = new SetPlayerDetailsMessage ( ) ;
2020-09-29 17:24:16 +02:00
message . setName ( userName ) ;
2020-10-20 16:39:23 +02:00
message . setCharacterlayersList ( characterLayersSelected . map ( ( characterLayer ) = > characterLayer . name ) ) ;
2020-06-22 16:10:18 +02:00
2020-09-29 17:12:28 +02:00
const clientToServerMessage = new ClientToServerMessage ( ) ;
clientToServerMessage . setSetplayerdetailsmessage ( message ) ;
2020-09-28 18:52:54 +02:00
2020-09-29 17:12:28 +02:00
this . socket . send ( clientToServerMessage . serializeBinary ( ) . buffer ) ;
2020-04-05 20:57:14 +02:00
}
2020-05-10 17:31:27 +02:00
2020-06-22 11:58:07 +02:00
public closeConnection ( ) : void {
this . socket ? . close ( ) ;
2020-10-01 17:16:49 +02:00
this . closed = true ;
2020-06-03 11:55:31 +02:00
}
2021-05-10 21:48:11 +02:00
private toPositionMessage ( x : number , y : number , direction : string , moving : boolean ) : PositionMessage {
2020-09-18 13:57:38 +02:00
const positionMessage = new PositionMessage ( ) ;
positionMessage . setX ( Math . floor ( x ) ) ;
positionMessage . setY ( Math . floor ( y ) ) ;
2020-11-13 18:00:22 +01:00
let directionEnum : Direction ;
2020-09-18 13:57:38 +02:00
switch ( direction ) {
2021-06-25 18:14:40 +02:00
case "up" :
2020-09-18 13:57:38 +02:00
directionEnum = Direction . UP ;
break ;
2021-06-25 18:14:40 +02:00
case "down" :
2020-09-18 13:57:38 +02:00
directionEnum = Direction . DOWN ;
break ;
2021-06-25 18:14:40 +02:00
case "left" :
2020-09-18 13:57:38 +02:00
directionEnum = Direction . LEFT ;
break ;
2021-06-25 18:14:40 +02:00
case "right" :
2020-09-18 13:57:38 +02:00
directionEnum = Direction . RIGHT ;
break ;
default :
throw new Error ( "Unexpected direction" ) ;
}
positionMessage . setDirection ( directionEnum ) ;
positionMessage . setMoving ( moving ) ;
2020-09-28 18:52:54 +02:00
return positionMessage ;
}
private toViewportMessage ( viewport : ViewportInterface ) : ViewportMessage {
2020-09-18 13:57:38 +02:00
const viewportMessage = new ViewportMessage ( ) ;
viewportMessage . setLeft ( Math . floor ( viewport . left ) ) ;
viewportMessage . setRight ( Math . floor ( viewport . right ) ) ;
viewportMessage . setTop ( Math . floor ( viewport . top ) ) ;
viewportMessage . setBottom ( Math . floor ( viewport . bottom ) ) ;
2020-09-28 18:52:54 +02:00
return viewportMessage ;
}
2021-05-10 21:48:11 +02:00
public sharePosition ( x : number , y : number , direction : string , moving : boolean , viewport : ViewportInterface ) : void {
if ( ! this . socket ) {
2020-09-28 18:52:54 +02:00
return ;
}
const positionMessage = this . toPositionMessage ( x , y , direction , moving ) ;
const viewportMessage = this . toViewportMessage ( viewport ) ;
2020-09-18 13:57:38 +02:00
const userMovesMessage = new UserMovesMessage ( ) ;
userMovesMessage . setPosition ( positionMessage ) ;
userMovesMessage . setViewport ( viewportMessage ) ;
2020-09-24 10:05:16 +02:00
//console.log('Sending position ', positionMessage.getX(), positionMessage.getY());
2020-09-28 18:52:54 +02:00
const clientToServerMessage = new ClientToServerMessage ( ) ;
clientToServerMessage . setUsermovesmessage ( userMovesMessage ) ;
2020-09-24 10:05:16 +02:00
2020-09-28 18:52:54 +02:00
this . socket . send ( clientToServerMessage . serializeBinary ( ) . buffer ) ;
2020-04-05 20:57:14 +02:00
}
2020-08-31 14:03:40 +02:00
public setSilent ( silent : boolean ) : void {
2020-09-28 18:52:54 +02:00
const silentMessage = new SilentMessage ( ) ;
silentMessage . setSilent ( silent ) ;
const clientToServerMessage = new ClientToServerMessage ( ) ;
clientToServerMessage . setSilentmessage ( silentMessage ) ;
this . socket . send ( clientToServerMessage . serializeBinary ( ) . buffer ) ;
2020-08-31 14:03:40 +02:00
}
2020-09-15 16:21:41 +02:00
public setViewport ( viewport : ViewportInterface ) : void {
2020-09-24 17:36:10 +02:00
const viewportMessage = new ViewportMessage ( ) ;
viewportMessage . setTop ( Math . round ( viewport . top ) ) ;
viewportMessage . setBottom ( Math . round ( viewport . bottom ) ) ;
viewportMessage . setLeft ( Math . round ( viewport . left ) ) ;
viewportMessage . setRight ( Math . round ( viewport . right ) ) ;
2020-09-28 18:52:54 +02:00
const clientToServerMessage = new ClientToServerMessage ( ) ;
clientToServerMessage . setViewportmessage ( viewportMessage ) ;
this . socket . send ( clientToServerMessage . serializeBinary ( ) . buffer ) ;
2020-04-05 20:57:14 +02:00
}
2020-06-22 11:58:07 +02:00
public onUserJoins ( callback : ( message : MessageUserJoined ) = > void ) : void {
2020-09-29 16:01:22 +02:00
this . onMessage ( EventMessage . JOIN_ROOM , ( message : UserJoinedMessage ) = > {
2020-09-28 18:52:54 +02:00
callback ( this . toMessageUserJoined ( message ) ) ;
2020-09-24 14:50:28 +02:00
} ) ;
2020-05-19 19:11:12 +02:00
}
2020-09-28 18:52:54 +02:00
// TODO: move this to protobuf utils
private toMessageUserJoined ( message : UserJoinedMessage ) : MessageUserJoined {
const position = message . getPosition ( ) ;
if ( position === undefined ) {
2021-06-25 18:14:40 +02:00
throw new Error ( "Invalid JOIN_ROOM message" ) ;
2020-09-28 18:52:54 +02:00
}
2020-10-20 16:39:23 +02:00
2021-06-25 18:14:40 +02:00
const characterLayers = message
. getCharacterlayersList ( )
. map ( ( characterLayer : CharacterLayerMessage ) : BodyResourceDescriptionInterface = > {
return {
name : characterLayer.getName ( ) ,
img : characterLayer.getUrl ( ) ,
} ;
} ) ;
2020-10-20 16:39:23 +02:00
2021-04-02 21:21:11 +02:00
const companion = message . getCompanion ( ) ;
2020-09-28 18:52:54 +02:00
return {
userId : message.getUserid ( ) ,
name : message.getName ( ) ,
2020-10-20 16:39:23 +02:00
characterLayers ,
2021-06-08 16:30:58 +02:00
visitCardUrl : message.getVisitcardurl ( ) ,
2021-04-02 21:21:11 +02:00
position : ProtobufClientUtils.toPointInterface ( position ) ,
2021-06-25 18:14:40 +02:00
companion : companion ? companion . getName ( ) : null ,
2021-07-07 11:24:51 +02:00
userUuid : message.getUseruuid ( ) ,
2021-06-25 18:14:40 +02:00
} ;
2020-09-28 18:52:54 +02:00
}
2020-09-18 15:51:15 +02:00
public onUserMoved ( callback : ( message : UserMovedMessage ) = > void ) : void {
2020-09-29 16:01:22 +02:00
this . onMessage ( EventMessage . USER_MOVED , callback ) ;
2020-09-18 15:51:15 +02:00
//this.socket.on(EventMessage.USER_MOVED, callback);
}
/ * *
* Registers a listener on a message that is part of a batch
* /
2020-09-29 16:01:22 +02:00
private onMessage ( eventName : string , callback : Function ) : void {
let callbacks = this . listeners . get ( eventName ) ;
2020-09-18 15:51:15 +02:00
if ( callbacks === undefined ) {
callbacks = new Array < Function > ( ) ;
2020-09-29 16:01:22 +02:00
this . listeners . set ( eventName , callbacks ) ;
2020-09-18 15:51:15 +02:00
}
callbacks . push ( callback ) ;
2020-05-19 19:11:12 +02:00
}
2020-09-18 13:57:38 +02:00
public onUserLeft ( callback : ( userId : number ) = > void ) : void {
2020-09-29 16:01:22 +02:00
this . onMessage ( EventMessage . USER_LEFT , ( message : UserLeftMessage ) = > {
2020-09-24 16:11:47 +02:00
callback ( message . getUserid ( ) ) ;
} ) ;
2020-05-19 19:11:12 +02:00
}
2021-06-25 18:14:40 +02:00
public onGroupUpdatedOrCreated (
callback : ( groupCreateUpdateMessage : GroupCreatedUpdatedMessageInterface ) = > void
) : void {
2020-09-29 16:01:22 +02:00
this . onMessage ( EventMessage . GROUP_CREATE_UPDATE , ( message : GroupUpdateMessage ) = > {
2020-09-28 18:52:54 +02:00
callback ( this . toGroupCreatedUpdatedMessage ( message ) ) ;
} ) ;
}
2020-09-21 11:24:03 +02:00
2020-09-28 18:52:54 +02:00
private toGroupCreatedUpdatedMessage ( message : GroupUpdateMessage ) : GroupCreatedUpdatedMessageInterface {
const position = message . getPosition ( ) ;
if ( position === undefined ) {
2021-06-25 18:14:40 +02:00
throw new Error ( "Missing position in GROUP_CREATE_UPDATE" ) ;
2020-09-28 18:52:54 +02:00
}
2020-09-21 11:24:03 +02:00
2020-09-28 18:52:54 +02:00
return {
groupId : message.getGroupid ( ) ,
2020-10-21 16:07:42 +02:00
position : position.toObject ( ) ,
2021-06-25 18:14:40 +02:00
groupSize : message.getGroupsize ( ) ,
} ;
2020-05-08 00:35:36 +02:00
}
2020-09-21 11:24:03 +02:00
public onGroupDeleted ( callback : ( groupId : number ) = > void ) : void {
2020-09-29 16:01:22 +02:00
this . onMessage ( EventMessage . GROUP_DELETE , ( message : GroupDeleteMessage ) = > {
2020-09-24 10:05:16 +02:00
callback ( message . getGroupid ( ) ) ;
} ) ;
2020-05-08 00:35:36 +02:00
}
2020-12-03 16:39:44 +01:00
public onConnectingError ( callback : ( event : CloseEvent ) = > void ) : void {
this . onMessage ( EventMessage . CONNECTING_ERROR , ( event : CloseEvent ) = > {
callback ( event ) ;
} ) ;
}
2020-09-28 18:52:54 +02:00
public onConnectError ( callback : ( error : Event ) = > void ) : void {
2021-06-25 18:14:40 +02:00
this . socket . addEventListener ( "error" , callback ) ;
2020-09-28 18:52:54 +02:00
}
2021-03-31 16:00:14 +02:00
2020-12-03 16:39:44 +01:00
public onConnect ( callback : ( roomConnection : OnConnectInterface ) = > void ) : void {
2020-11-13 18:00:22 +01:00
//this.socket.addEventListener('open', callback)
this . onMessage ( EventMessage . CONNECT , callback ) ;
2020-06-22 16:10:18 +02:00
}
2020-10-06 18:09:23 +02:00
/ * *
* Triggered when we receive all the details of a room ( users , groups , . . . )
* /
2020-12-03 16:39:44 +01:00
/ * p u b l i c o n S t a r t R o o m ( c a l l b a c k : ( e v e n t : R o o m J o i n e d M e s s a g e I n t e r f a c e ) = > v o i d ) : v o i d {
2020-10-06 18:09:23 +02:00
this . onMessage ( EventMessage . START_ROOM , callback ) ;
2020-12-03 16:39:44 +01:00
} * /
2020-10-06 18:09:23 +02:00
2020-09-18 13:57:38 +02:00
public sendWebrtcSignal ( signal : unknown , receiverId : number ) {
2020-09-29 16:01:22 +02:00
const webRtcSignal = new WebRtcSignalToServerMessage ( ) ;
webRtcSignal . setReceiverid ( receiverId ) ;
webRtcSignal . setSignal ( JSON . stringify ( signal ) ) ;
const clientToServerMessage = new ClientToServerMessage ( ) ;
clientToServerMessage . setWebrtcsignaltoservermessage ( webRtcSignal ) ;
this . socket . send ( clientToServerMessage . serializeBinary ( ) . buffer ) ;
2020-04-25 16:05:33 +02:00
}
2020-09-18 13:57:38 +02:00
public sendWebrtcScreenSharingSignal ( signal : unknown , receiverId : number ) {
2020-09-29 16:01:22 +02:00
const webRtcSignal = new WebRtcSignalToServerMessage ( ) ;
webRtcSignal . setReceiverid ( receiverId ) ;
webRtcSignal . setSignal ( JSON . stringify ( signal ) ) ;
const clientToServerMessage = new ClientToServerMessage ( ) ;
clientToServerMessage . setWebrtcscreensharingsignaltoservermessage ( webRtcSignal ) ;
this . socket . send ( clientToServerMessage . serializeBinary ( ) . buffer ) ;
2020-04-25 16:05:33 +02:00
}
2020-09-29 16:01:22 +02:00
public receiveWebrtcStart ( callback : ( message : UserSimplePeerInterface ) = > void ) {
this . onMessage ( EventMessage . WEBRTC_START , ( message : WebRtcStartMessage ) = > {
callback ( {
userId : message.getUserid ( ) ,
2021-02-16 09:58:08 +01:00
initiator : message.getInitiator ( ) ,
2021-02-16 18:13:30 +01:00
webRtcUser : message.getWebrtcusername ( ) ? ? undefined ,
2021-02-16 09:58:08 +01:00
webRtcPassword : message.getWebrtcpassword ( ) ? ? undefined ,
2020-09-29 16:01:22 +02:00
} ) ;
} ) ;
2020-04-25 16:05:33 +02:00
}
2020-08-20 16:56:10 +02:00
public receiveWebrtcSignal ( callback : ( message : WebRtcSignalReceivedMessageInterface ) = > void ) {
2020-09-29 16:01:22 +02:00
this . onMessage ( EventMessage . WEBRTC_SIGNAL , ( message : WebRtcSignalToClientMessage ) = > {
callback ( {
userId : message.getUserid ( ) ,
2021-02-16 18:13:30 +01:00
signal : JSON.parse ( message . getSignal ( ) ) ,
webRtcUser : message.getWebrtcusername ( ) ? ? undefined ,
webRtcPassword : message.getWebrtcpassword ( ) ? ? undefined ,
2020-09-29 16:01:22 +02:00
} ) ;
} ) ;
2020-04-25 16:05:33 +02:00
}
2020-08-20 16:56:10 +02:00
public receiveWebrtcScreenSharingSignal ( callback : ( message : WebRtcSignalReceivedMessageInterface ) = > void ) {
2020-09-29 16:01:22 +02:00
this . onMessage ( EventMessage . WEBRTC_SCREEN_SHARING_SIGNAL , ( message : WebRtcSignalToClientMessage ) = > {
callback ( {
userId : message.getUserid ( ) ,
2021-02-16 18:13:30 +01:00
signal : JSON.parse ( message . getSignal ( ) ) ,
webRtcUser : message.getWebrtcusername ( ) ? ? undefined ,
webRtcPassword : message.getWebrtcpassword ( ) ? ? undefined ,
2020-09-29 16:01:22 +02:00
} ) ;
} ) ;
2020-04-25 16:05:33 +02:00
}
2021-03-26 14:12:22 +01:00
public onServerDisconnected ( callback : ( ) = > void ) : void {
2021-06-25 18:14:40 +02:00
this . socket . addEventListener ( "close" , ( event ) = > {
2021-03-26 14:12:22 +01:00
if ( this . closed === true || connectionManager . unloading ) {
2020-10-01 17:16:49 +02:00
return ;
}
2021-06-25 18:14:40 +02:00
console . log ( "Socket closed with code " + event . code + ". Reason: " + event . reason ) ;
2020-09-28 18:52:54 +02:00
if ( event . code === 1000 ) {
// Normal closure case
2020-06-22 15:00:23 +02:00
return ;
}
2021-03-26 14:12:22 +01:00
callback ( ) ;
2020-05-13 20:22:42 +02:00
} ) ;
2020-06-22 18:42:54 +02:00
}
2020-06-17 15:37:02 +02:00
2021-02-02 18:19:51 +01:00
public getUserId ( ) : number {
2021-06-25 18:14:40 +02:00
if ( this . userId === null ) throw "UserId cannot be null!" ;
2020-06-22 18:42:54 +02:00
return this . userId ;
2020-05-13 20:22:42 +02:00
}
2020-06-05 13:07:18 +02:00
disconnectMessage ( callback : ( message : WebRtcDisconnectMessageInterface ) = > void ) : void {
2020-09-29 16:01:22 +02:00
this . onMessage ( EventMessage . WEBRTC_DISCONNECT , ( message : WebRtcDisconnectMessage ) = > {
callback ( {
2021-06-25 18:14:40 +02:00
userId : message.getUserid ( ) ,
2020-09-29 16:01:22 +02:00
} ) ;
} ) ;
2020-05-02 20:46:02 +02:00
}
2020-07-27 22:36:07 +02:00
2020-09-24 17:24:37 +02:00
emitActionableEvent ( itemId : number , event : string , state : unknown , parameters : unknown ) : void {
const itemEventMessage = new ItemEventMessage ( ) ;
itemEventMessage . setItemid ( itemId ) ;
itemEventMessage . setEvent ( event ) ;
itemEventMessage . setStatejson ( JSON . stringify ( state ) ) ;
itemEventMessage . setParametersjson ( JSON . stringify ( parameters ) ) ;
2020-09-28 18:52:54 +02:00
const clientToServerMessage = new ClientToServerMessage ( ) ;
clientToServerMessage . setItemeventmessage ( itemEventMessage ) ;
this . socket . send ( clientToServerMessage . serializeBinary ( ) . buffer ) ;
2020-07-27 22:36:07 +02:00
}
2021-07-06 10:58:12 +02:00
emitSetVariableEvent ( name : string , value : unknown ) : void {
const variableMessage = new VariableMessage ( ) ;
variableMessage . setName ( name ) ;
variableMessage . setValue ( JSON . stringify ( value ) ) ;
const clientToServerMessage = new ClientToServerMessage ( ) ;
clientToServerMessage . setVariablemessage ( variableMessage ) ;
this . socket . send ( clientToServerMessage . serializeBinary ( ) . buffer ) ;
}
2020-07-27 22:36:07 +02:00
onActionableEvent ( callback : ( message : ItemEventMessageInterface ) = > void ) : void {
2020-09-29 16:01:22 +02:00
this . onMessage ( EventMessage . ITEM_EVENT , ( message : ItemEventMessage ) = > {
2020-09-24 17:24:37 +02:00
callback ( {
itemId : message.getItemid ( ) ,
event : message.getEvent ( ) ,
parameters : JSON.parse ( message . getParametersjson ( ) ) ,
2021-06-25 18:14:40 +02:00
state : JSON.parse ( message . getStatejson ( ) ) ,
2020-09-24 17:24:37 +02:00
} ) ;
} ) ;
2020-07-27 22:36:07 +02:00
}
2020-10-01 14:11:34 +02:00
2021-05-10 21:48:11 +02:00
public uploadAudio ( file : FormData ) {
2021-06-25 18:14:40 +02:00
return Axios . post ( ` ${ UPLOADER_URL } /upload-audio-message ` , file )
. then ( ( res : { data : { } } ) = > {
return res . data ;
} )
. catch ( ( err ) = > {
console . error ( err ) ;
throw err ;
} ) ;
2020-10-01 14:11:34 +02:00
}
public receivePlayGlobalMessage ( callback : ( message : PlayGlobalMessageInterface ) = > void ) {
return this . onMessage ( EventMessage . PLAY_GLOBAL_MESSAGE , ( message : PlayGlobalMessage ) = > {
callback ( {
id : message.getId ( ) ,
type : message . getType ( ) ,
message : message.getMessage ( ) ,
} ) ;
} ) ;
}
public receiveStopGlobalMessage ( callback : ( messageId : string ) = > void ) {
return this . onMessage ( EventMessage . STOP_GLOBAL_MESSAGE , ( message : StopGlobalMessage ) = > {
callback ( message . getId ( ) ) ;
} ) ;
}
2020-10-13 11:39:07 +02:00
public receiveTeleportMessage ( callback : ( messageId : string ) = > void ) {
return this . onMessage ( EventMessage . TELEPORT , ( message : TeleportMessageMessage ) = > {
callback ( message . getMap ( ) ) ;
} ) ;
}
2021-05-10 21:48:11 +02:00
public emitGlobalMessage ( message : PlayGlobalMessageInterface ) {
2020-10-01 14:11:34 +02:00
const playGlobalMessage = new PlayGlobalMessage ( ) ;
playGlobalMessage . setId ( message . id ) ;
playGlobalMessage . setType ( message . type ) ;
playGlobalMessage . setMessage ( message . message ) ;
const clientToServerMessage = new ClientToServerMessage ( ) ;
clientToServerMessage . setPlayglobalmessage ( playGlobalMessage ) ;
this . socket . send ( clientToServerMessage . serializeBinary ( ) . buffer ) ;
}
2020-10-12 11:22:41 +02:00
2021-07-07 11:24:51 +02:00
public emitReportPlayerMessage ( reportedUserUuid : string , reportComment : string ) : void {
2020-10-12 11:22:41 +02:00
const reportPlayerMessage = new ReportPlayerMessage ( ) ;
2021-07-07 11:24:51 +02:00
reportPlayerMessage . setReporteduseruuid ( reportedUserUuid ) ;
2020-10-12 11:22:41 +02:00
reportPlayerMessage . setReportcomment ( reportComment ) ;
const clientToServerMessage = new ClientToServerMessage ( ) ;
clientToServerMessage . setReportplayermessage ( reportPlayerMessage ) ;
this . socket . send ( clientToServerMessage . serializeBinary ( ) . buffer ) ;
}
2020-10-14 15:06:10 +02:00
2021-05-10 21:48:11 +02:00
public emitQueryJitsiJwtMessage ( jitsiRoom : string , tag : string | undefined ) : void {
2020-10-16 19:13:26 +02:00
const queryJitsiJwtMessage = new QueryJitsiJwtMessage ( ) ;
queryJitsiJwtMessage . setJitsiroom ( jitsiRoom ) ;
if ( tag !== undefined ) {
queryJitsiJwtMessage . setTag ( tag ) ;
}
const clientToServerMessage = new ClientToServerMessage ( ) ;
clientToServerMessage . setQueryjitsijwtmessage ( queryJitsiJwtMessage ) ;
this . socket . send ( clientToServerMessage . serializeBinary ( ) . buffer ) ;
}
public onStartJitsiRoom ( callback : ( jwt : string , room : string ) = > void ) : void {
this . onMessage ( EventMessage . START_JITSI_ROOM , ( message : SendJitsiJwtMessage ) = > {
callback ( message . getJwt ( ) , message . getJitsiroom ( ) ) ;
} ) ;
}
2021-07-07 17:17:28 +02:00
public onSetVariable ( callback : ( name : string , value : unknown ) = > void ) : void {
this . onMessage ( EventMessage . SET_VARIABLE , ( message : VariableMessage ) = > {
const name = message . getName ( ) ;
const serializedValue = message . getValue ( ) ;
let value : unknown = undefined ;
if ( serializedValue ) {
2021-07-19 18:46:33 +02:00
try {
value = JSON . parse ( serializedValue ) ;
} catch ( e ) {
console . error ( 'Unable to unserialize value received from server for variable "' + name + '". Value received: "' + serializedValue + '". Error: ' , e ) ;
}
2021-07-07 17:17:28 +02:00
}
callback ( name , value ) ;
} ) ;
}
2020-10-14 11:07:34 +02:00
public hasTag ( tag : string ) : boolean {
2020-10-14 11:48:34 +02:00
return this . tags . includes ( tag ) ;
2020-10-14 11:07:34 +02:00
}
2021-02-16 09:58:08 +01:00
2020-12-04 11:30:35 +01:00
public isAdmin ( ) : boolean {
2021-06-25 18:14:40 +02:00
return this . hasTag ( "admin" ) ;
2020-12-04 11:30:35 +01:00
}
2021-03-31 11:21:06 +02:00
public emitEmoteEvent ( emoteName : string ) : void {
const emoteMessage = new EmotePromptMessage ( ) ;
2021-06-25 18:14:40 +02:00
emoteMessage . setEmote ( emoteName ) ;
2021-03-31 11:21:06 +02:00
const clientToServerMessage = new ClientToServerMessage ( ) ;
clientToServerMessage . setEmotepromptmessage ( emoteMessage ) ;
this . socket . send ( clientToServerMessage . serializeBinary ( ) . buffer ) ;
}
2021-05-26 10:58:25 +02:00
2021-06-25 18:14:40 +02:00
public getAllTags ( ) : string [ ] {
2021-05-20 10:57:36 +02:00
return this . tags ;
}
2020-05-08 00:35:36 +02:00
}