@ -5,7 +5,7 @@ import { get, Unsubscriber } from "svelte/store";
import { userMessageManager } from "../../Administration/UserMessageManager" ;
import { connectionManager } from "../../Connexion/ConnectionManager" ;
import { CoWebsite, coWebsiteManager } from "../../WebRtc/CoWebsiteManager" ;
import { coWebsiteManager } from "../../WebRtc/CoWebsiteManager" ;
import { urlManager } from "../../Url/UrlManager" ;
import { mediaManager } from "../../WebRtc/MediaManager" ;
import { UserInputManager } from "../UserInput/UserInputManager" ;
@ -20,9 +20,8 @@ import { EmbeddedWebsiteManager } from "./EmbeddedWebsiteManager";
import { lazyLoadPlayerCharacterTextures , loadCustomTexture } from "../Entity/PlayerTexturesLoadingManager" ;
import { lazyLoadCompanionResource } from "../Companion/CompanionTexturesLoadingManager" ;
import { ON_ACTION_TRIGGER_BUTTON } from "../../WebRtc/LayoutManager" ;
import { iframeListener } from "../../Api/IframeListener" ;
import { DEBUG_MODE , JITSI_ PRIVATE_MODE , MAX_PER_GROUP , POSITION_DELAY } from "../../Enum/EnvironmentVariable" ;
import { DEBUG_MODE , JITSI_ URL , MAX_PER_GROUP , POSITION_DELAY } from "../../Enum/EnvironmentVariable" ;
import { ProtobufClientUtils } from "../../Network/ProtobufClientUtils" ;
import { Room } from "../../Connexion/Room" ;
import { jitsiFactory } from "../../WebRtc/JitsiFactory" ;
@ -76,7 +75,7 @@ import { emoteStore, emoteMenuStore } from "../../Stores/EmoteStore";
import { userIsAdminStore } from "../../Stores/GameStore" ;
import { contactPageStore } from "../../Stores/MenuStore" ;
import type { WasCameraUpdatedEvent } from "../../Api/Events/WasCameraUpdatedEvent" ;
import { audioManagerFileStore , audioManagerVisibilityStore } from "../../Stores/AudioManagerStore" ;
import { audioManagerFileStore } from "../../Stores/AudioManagerStore" ;
import EVENT_TYPE = Phaser . Scenes . Events ;
import Texture = Phaser . Textures . Texture ;
@ -94,6 +93,9 @@ import { GameSceneUserInputHandler } from "../UserInput/GameSceneUserInputHandle
import { locale } from "../../i18n/i18n-svelte" ;
import { StringUtils } from "../../Utils/StringUtils" ;
import { startLayerNamesStore } from "../../Stores/StartLayerNamesStore" ;
import { JitsiCoWebsite } from "../../WebRtc/CoWebsite/JitsiCoWebsite" ;
import { SimpleCoWebsite } from "../../WebRtc/CoWebsite/SimpleCoWebsite" ;
import type { CoWebsite } from "../../WebRtc/CoWebsite/CoWesbite" ;
export interface GameSceneInitInterface {
initPosition : PointInterface | null ;
reconnecting : boolean ;
@ -564,7 +566,7 @@ export class GameScene extends DirtyScene {
this . pathfindingManager = new PathfindingManager (
this ,
this . gameMap . getCollision s Grid( ) ,
this . gameMap . getCollision Grid( ) ,
this . gameMap . getTileDimensions ( )
) ;
@ -582,7 +584,7 @@ export class GameScene extends DirtyScene {
this . pathfindingManager = new PathfindingManager (
this ,
this . gameMap . getCollision s Grid( ) ,
this . gameMap . getCollision Grid( ) ,
this . gameMap . getTileDimensions ( )
) ;
@ -633,7 +635,6 @@ export class GameScene extends DirtyScene {
) ;
new GameMapPropertiesListener ( this , this . gameMap ) . register ( ) ;
this . triggerOnMapLayerPropertyChange ( ) ;
if ( ! this . room . isDisconnected ( ) ) {
this . scene . sleep ( ) ;
@ -800,7 +801,19 @@ export class GameScene extends DirtyScene {
* Triggered when we receive the JWT token to connect to Jitsi
* /
this . connection . sendJitsiJwtMessageStream . subscribe ( ( message ) = > {
this . startJitsi ( message . jitsiRoom , message . jwt ) ;
if ( ! JITSI_URL ) {
throw new Error ( "Missing JITSI_URL environment variable." ) ;
}
let domain = JITSI_URL ;
if ( domain . substring ( 0 , 7 ) !== "http://" && domain . substring ( 0 , 8 ) !== "https://" ) {
domain = ` ${ location . protocol } // ${ domain } ` ;
}
const coWebsite = new JitsiCoWebsite ( new URL ( domain ) , false , undefined , undefined , false ) ;
coWebsiteManager . addCoWebsiteToStore ( coWebsite , 0 ) ;
this . initialiseJitsi ( coWebsite , message . jitsiRoom , message . jwt ) ;
} ) ;
this . messageSubscription = this . connection . worldFullMessageStream . subscribe ( ( message ) = > {
@ -937,103 +950,6 @@ export class GameScene extends DirtyScene {
}
}
private triggerOnMapLayerPropertyChange() {
this . gameMap . onPropertyChange ( GameMapProperties . EXIT_SCENE_URL , ( newValue , oldValue ) = > {
if ( newValue ) {
this . onMapExit (
Room . getRoomPathFromExitSceneUrl ( newValue as string , window . location . toString ( ) , this . MapUrlFile )
) . catch ( ( e ) = > console . error ( e ) ) ;
} else {
setTimeout ( ( ) = > {
layoutManagerActionStore . removeAction ( "roomAccessDenied" ) ;
} , 2000 ) ;
}
} ) ;
this . gameMap . onPropertyChange ( GameMapProperties . EXIT_URL , ( newValue , oldValue ) = > {
if ( newValue ) {
this . onMapExit ( Room . getRoomPathFromExitUrl ( newValue as string , window . location . toString ( ) ) ) . catch ( ( e ) = >
console . error ( e )
) ;
} else {
setTimeout ( ( ) = > {
layoutManagerActionStore . removeAction ( "roomAccessDenied" ) ;
} , 2000 ) ;
}
} ) ;
this . gameMap . onPropertyChange ( GameMapProperties . JITSI_ROOM , ( newValue , oldValue , allProps ) = > {
if ( newValue === undefined ) {
layoutManagerActionStore . removeAction ( "jitsi" ) ;
this . stopJitsi ( ) ;
} else {
const openJitsiRoomFunction = ( ) = > {
const roomName = jitsiFactory . getRoomName ( newValue . toString ( ) , this . instance ) ;
const jitsiUrl = allProps . get ( GameMapProperties . JITSI_URL ) as string | undefined ;
if ( JITSI_PRIVATE_MODE && ! jitsiUrl ) {
const adminTag = allProps . get ( GameMapProperties . JITSI_ADMIN_ROOM_TAG ) as string | undefined ;
this . connection ? . emitQueryJitsiJwtMessage ( roomName , adminTag ) ;
} else {
this . startJitsi ( roomName , undefined ) ;
}
layoutManagerActionStore . removeAction ( "jitsi" ) ;
} ;
const jitsiTriggerValue = allProps . get ( GameMapProperties . JITSI_TRIGGER ) ;
const forceTrigger = localUserStore . getForceCowebsiteTrigger ( ) ;
if ( forceTrigger || jitsiTriggerValue === ON_ACTION_TRIGGER_BUTTON ) {
let message = allProps . get ( GameMapProperties . JITSI_TRIGGER_MESSAGE ) ;
if ( message === undefined ) {
message = "Press SPACE or touch here to enter Jitsi Meet room" ;
}
layoutManagerActionStore . addAction ( {
uuid : "jitsi" ,
type : "message" ,
message : message ,
callback : ( ) = > openJitsiRoomFunction ( ) ,
userInputManager : this.userInputManager ,
} ) ;
} else {
openJitsiRoomFunction ( ) ;
}
}
} ) ;
this . gameMap . onPropertyChange ( GameMapProperties . SILENT , ( newValue , oldValue ) = > {
if ( newValue === undefined || newValue === false || newValue === "" ) {
this . connection ? . setSilent ( false ) ;
this . CurrentPlayer . noSilent ( ) ;
} else {
this . connection ? . setSilent ( true ) ;
this . CurrentPlayer . isSilent ( ) ;
}
} ) ;
this . gameMap . onPropertyChange ( GameMapProperties . PLAY_AUDIO , ( newValue , oldValue , allProps ) = > {
const volume = allProps . get ( GameMapProperties . AUDIO_VOLUME ) as number | undefined ;
const loop = allProps . get ( GameMapProperties . AUDIO_LOOP ) as boolean | undefined ;
newValue === undefined
? audioManagerFileStore . unloadAudio ( )
: audioManagerFileStore . playAudio ( newValue , this . getMapDirUrl ( ) , volume , loop ) ;
audioManagerVisibilityStore . set ( ! ( newValue === undefined ) ) ;
} ) ;
// TODO: This legacy property should be removed at some point
this . gameMap . onPropertyChange ( GameMapProperties . PLAY_AUDIO_LOOP , ( newValue , oldValue ) = > {
newValue === undefined
? audioManagerFileStore . unloadAudio ( )
: audioManagerFileStore . playAudio ( newValue , this . getMapDirUrl ( ) , undefined , true ) ;
audioManagerVisibilityStore . set ( ! ( newValue === undefined ) ) ;
} ) ;
// TODO: Legacy functionnality replace by layer change
this . gameMap . onPropertyChange ( GameMapProperties . ZONE , ( newValue , oldValue ) = > {
if ( oldValue ) {
iframeListener . sendLeaveEvent ( oldValue as string ) ;
}
if ( newValue ) {
iframeListener . sendEnterEvent ( newValue as string ) ;
}
} ) ;
}
private listenToIframeEvents ( ) : void {
this . iframeSubscriptionList = [ ] ;
this . iframeSubscriptionList . push (
@ -1266,13 +1182,11 @@ ${escapedMessage}
throw new Error ( "Unknown query source" ) ;
}
const coWebsite = coWebsiteManager . addCoWebsite (
openCoWebsite . url ,
iframeListener . getBaseUrlFromSource ( source ) ,
const coWebsite : SimpleCoWebsite = new SimpleCoWebsite (
new URL ( openCoWebsite . url , iframeListener . getBaseUrlFromSource ( source ) ) ,
openCoWebsite . allowApi ,
openCoWebsite . allowPolicy ,
openCoWebsite . widthPercent ,
openCoWebsite . position ,
openCoWebsite . closable ? ? true
) ;
@ -1281,7 +1195,7 @@ ${escapedMessage}
}
return {
id : coWebsite. iframe.id ,
id : coWebsite. getId( ) ,
} ;
} ) ;
@ -1290,27 +1204,23 @@ ${escapedMessage}
return coWebsites . map ( ( coWebsite : CoWebsite ) = > {
return {
id : coWebsite. iframe.id ,
id : coWebsite. getId( ) ,
} ;
} ) ;
} ) ;
iframeListener . registerAnswerer ( "closeCoWebsite" , async ( coWebsiteId ) = > {
iframeListener . registerAnswerer ( "closeCoWebsite" , ( coWebsiteId ) = > {
const coWebsite = coWebsiteManager . getCoWebsiteById ( coWebsiteId ) ;
if ( ! coWebsite ) {
throw new Error ( "Unknown co-website" ) ;
}
return coWebsiteManager . closeCoWebsite ( coWebsite ) . catch ( ( error ) = > {
throw new Error ( "Error on closing co-website" ) ;
} ) ;
return coWebsiteManager . closeCoWebsite ( coWebsite ) ;
} ) ;
iframeListener . registerAnswerer ( "closeCoWebsites" , async ( ) = > {
return await coWebsiteManager . closeCoWebsites ( ) . catch ( ( error ) = > {
throw new Error ( "Error on closing all co-websites" ) ;
} ) ;
iframeListener . registerAnswerer ( "closeCoWebsites" , ( ) = > {
return coWebsiteManager . closeCoWebsites ( ) ;
} ) ;
iframeListener . registerAnswerer ( "getMapData" , ( ) = > {
@ -1395,7 +1305,7 @@ ${escapedMessage}
//Create new colliders with the new GameMap
this . createCollisionWithPlayer ( ) ;
//Create new trigger with the new GameMap
this. triggerOnMapLayerPropertyChange ( ) ;
new GameMapPropertiesListener ( this , this . gameMap ) . register ( ) ;
resolve ( newFirstgid ) ;
} ) ;
} ) ;
@ -1508,14 +1418,15 @@ ${escapedMessage}
phaserLayers [ i ] . setCollisionByProperty ( { collides : true } , visible ) ;
}
}
this . pathfindingManager . setCollisionGrid ( this . gameMap . getCollisionGrid ( ) ) ;
this . markDirty ( ) ;
}
p rivate getMapDirUrl ( ) : string {
return this . MapUrlFile . substr ( 0 , this . MapUrlFile . lastIndexOf ( "/" ) ) ;
p ublic getMapDirUrl ( ) : string {
return this . MapUrlFile . substr ing ( 0 , this . MapUrlFile . lastIndexOf ( "/" ) ) ;
}
p rivate async onMapExit ( roomUrl : URL ) {
p ublic async onMapExit ( roomUrl : URL ) {
if ( this . mapTransitioning ) return ;
this . mapTransitioning = true ;
@ -1574,14 +1485,13 @@ ${escapedMessage}
public cleanupClosingScene ( ) : void {
// stop playing audio, close any open website, stop any open Jitsi
coWebsiteManager . closeCoWebsites ( ) .catch ( ( e ) = > console . error ( e ) ) ;
coWebsiteManager . closeCoWebsites ( ) ;
// Stop the script, if any
const scripts = this . getScriptUrls ( this . mapFile ) ;
for ( const script of scripts ) {
iframeListener . unregisterScript ( script ) ;
}
this . stopJitsi ( ) ;
audioManagerFileStore . unloadAudio ( ) ;
// We are completely destroying the current scene to avoid using a half-backed instance when coming back to the same map.
this . connection ? . closeConnection ( ) ;
@ -2136,7 +2046,7 @@ ${escapedMessage}
mediaManager . hideMyCamera ( ) ;
}
public startJitsi( roomName : string , jwt? : string ) : void {
public initialiseJitsi( coWebsite : JitsiCoWebsite , roomName : string , jwt? : string ) : void {
const allProps = this . gameMap . getCurrentProperties ( ) ;
const jitsiConfig = this . safeParseJSONstring (
allProps . get ( GameMapProperties . JITSI_CONFIG ) as string | undefined ,
@ -2148,20 +2058,15 @@ ${escapedMessage}
) ;
const jitsiUrl = allProps . get ( GameMapProperties . JITSI_URL ) as string | undefined ;
jitsiFactory. start ( roomName , this . playerName , jwt , jitsiConfig , jitsiInterfaceConfig , jitsiUrl ) . catch ( ( ) = > {
console . error ( "Cannot start a Jitsi co-website" ) ;
coWebsite. setJitsiLoadPromise ( ( ) = > {
return jitsiFactory . start ( roomName , this . playerName , jwt , jitsiConfig , jitsiInterfaceConfig , jitsiUrl ) ;
} ) ;
this . disableMediaBehaviors ( ) ;
analyticsClient . enteredJitsi ( roomName , this . room . id ) ;
}
public stopJitsi ( ) : void {
const coWebsite = coWebsiteManager . searchJitsi ( ) ;
if ( coWebsite ) {
coWebsiteManager . closeCoWebsite ( coWebsite ) . catch ( ( e ) = > {
console . error ( "Error during Jitsi co-website closing" , e ) ;
} ) ;
}
coWebsiteManager . loadCoWebsite ( coWebsite ) . catch ( ( err ) = > {
console . error ( err ) ;
} ) ;
analyticsClient . enteredJitsi ( roomName , this . room . id ) ;
}
//todo: put this into an 'orchestrator' scene (EntryScene?)