@@ -36,7 +36,8 @@ import {
3636 setRoomConnection ,
3737 SET_COMMS_ISLAND ,
3838 SET_ROOM_CONNECTION ,
39- setLiveKitAdapter
39+ setLiveKitAdapter ,
40+ setSceneRoomConnection
4041} from './actions'
4142import { LivekitAdapter } from './adapters/LivekitAdapter'
4243import { OfflineAdapter } from './adapters/OfflineAdapter'
@@ -48,13 +49,16 @@ import { positionReportToCommsPositionRfc4 } from './interface/utils'
4849import { commsLogger } from './logger'
4950import { Rfc4RoomConnection } from './logic/rfc-4-room-connection'
5051import { getConnectedPeerCount , processAvatarVisibility } from './peers'
51- import { getCommsRoom , reconnectionState } from './selectors'
52+ import { getCommsRoom , getSceneRooms , reconnectionState } from './selectors'
5253import { RootState } from 'shared/store/rootTypes'
5354import { now } from 'lib/javascript/now'
5455import { getGlobalAudioStream } from './adapters/voice/loopback'
5556import { store } from 'shared/store/isolatedStore'
5657import { buildSnapshotContent } from 'shared/profiles/sagas/handleDeployProfile'
5758import { isBase64 } from 'lib/encoding/base64ToBlob'
59+ import { SET_PARCEL_POSITION } from 'shared/scene-loader/actions'
60+ import { getSceneLoader } from '../scene-loader/selectors'
61+ import { Vector2 } from '../protocol/decentraland/common/vectors.gen'
5862
5963const TIME_BETWEEN_PROFILE_RESPONSES = 1000
6064// this interval should be fast because this will be the delay other people around
@@ -89,6 +93,8 @@ export function* commsSaga() {
8993 yield fork ( handleCommsReconnectionInterval )
9094 yield fork ( pingerProcess )
9195 yield fork ( reportPositionSaga )
96+
97+ yield fork ( sceneRoomComms )
9298}
9399
94100/**
@@ -219,7 +225,11 @@ function* handleConnectToComms(action: ConnectToCommsAction) {
219225 }
220226}
221227
222- async function connectAdapter ( connStr : string , identity : ExplorerIdentity ) : Promise < RoomConnection > {
228+ async function connectAdapter (
229+ connStr : string ,
230+ identity : ExplorerIdentity ,
231+ id : string = 'island'
232+ ) : Promise < RoomConnection > {
223233 const ix = connStr . indexOf ( ':' )
224234 const protocol = connStr . substring ( 0 , ix )
225235 const url = connStr . substring ( ix + 1 )
@@ -272,12 +282,12 @@ async function connectAdapter(connStr: string, identity: ExplorerIdentity): Prom
272282 throw new Error ( `An unknown error was detected while trying to connect to the selected realm.` )
273283 }
274284 case 'offline' : {
275- return new Rfc4RoomConnection ( new OfflineAdapter ( ) )
285+ return new Rfc4RoomConnection ( new OfflineAdapter ( ) , id )
276286 }
277287 case 'ws-room' : {
278288 const finalUrl = ! url . startsWith ( 'ws:' ) && ! url . startsWith ( 'wss:' ) ? 'wss://' + url : url
279289
280- return new Rfc4RoomConnection ( new WebSocketAdapter ( finalUrl , identity ) )
290+ return new Rfc4RoomConnection ( new WebSocketAdapter ( finalUrl , identity ) , id )
281291 }
282292 case 'simulator' : {
283293 return new SimulationRoom ( url )
@@ -298,7 +308,7 @@ async function connectAdapter(connStr: string, identity: ExplorerIdentity): Prom
298308
299309 store . dispatch ( setLiveKitAdapter ( livekitAdapter ) )
300310
301- return new Rfc4RoomConnection ( livekitAdapter )
311+ return new Rfc4RoomConnection ( livekitAdapter , id )
302312 }
303313 }
304314 throw new Error ( `A communications adapter could not be created for protocol=${ protocol } ` )
@@ -531,3 +541,61 @@ function* handleRoomDisconnectionSaga(action: HandleRoomDisconnection) {
531541 }
532542 }
533543}
544+
545+ function * sceneRoomComms ( ) {
546+ let currentSceneId : string = ''
547+ const commsSceneToRemove = new Map < string , NodeJS . Timeout > ( )
548+
549+ while ( true ) {
550+ const reason : { timeout ?: unknown ; newParcel ?: { payload : { position : Vector2 } } } = yield race ( {
551+ newParcel : take ( SET_PARCEL_POSITION ) ,
552+ timeout : delay ( 5000 )
553+ } )
554+ const sceneLoader : ReturnType < typeof getSceneLoader > = yield select ( getSceneLoader )
555+ if ( ! sceneLoader ) continue
556+ if ( reason . newParcel ) {
557+ const sceneId = yield call ( sceneLoader . getSceneId ! , reason . newParcel . payload . position )
558+ // We are still on the same scene.
559+ if ( sceneId === currentSceneId ) continue
560+ const oldSceneId = currentSceneId
561+ yield call ( checkDisconnectScene , sceneId , oldSceneId , commsSceneToRemove )
562+ yield call ( connectSceneToComms , sceneId )
563+ // Player moved to a new scene. Instanciate new comms
564+ currentSceneId = sceneId
565+ }
566+ }
567+ }
568+
569+ function * checkDisconnectScene (
570+ currentSceneId : string ,
571+ oldSceneId : string ,
572+ commsSceneToRemove : Map < string , NodeJS . Timeout >
573+ ) {
574+ // avoid deleting an already created comms. Use when the user is switching between two scenes
575+ if ( commsSceneToRemove . has ( currentSceneId ) ) {
576+ clearTimeout ( commsSceneToRemove . get ( currentSceneId ) )
577+ commsSceneToRemove . delete ( currentSceneId )
578+ }
579+ if ( ! oldSceneId ) return
580+
581+ console . log ( '[SceneComms]: will disconnect' , oldSceneId )
582+ const sceneRooms : ReturnType < typeof getSceneRooms > = yield select ( getSceneRooms )
583+ const oldRoom = sceneRooms . get ( oldSceneId )
584+ const timeout = setTimeout ( ( ) => {
585+ console . log ( '[SceneComms]: disconnectSceneComms' , oldSceneId )
586+ void oldRoom ?. disconnect ( )
587+ commsSceneToRemove . delete ( oldSceneId )
588+ } , 1000 )
589+ commsSceneToRemove . set ( oldSceneId , timeout )
590+ }
591+
592+ function * connectSceneToComms ( sceneId : string ) {
593+ console . log ( '[SceneComms]: connectSceneToComms' , sceneId )
594+ // Fetch connection string
595+ // const connectionString = `https://boedo.com/${sceneId}`
596+ const connectionString = `offline:offline`
597+ const identity : ExplorerIdentity = yield select ( getCurrentIdentity )
598+ const sceneRoomConnetion = yield call ( connectAdapter , connectionString , identity , sceneId )
599+ yield call ( bindHandlersToCommsContext , sceneRoomConnetion , false )
600+ yield put ( setSceneRoomConnection ( sceneId , sceneRoomConnetion ) )
601+ }
0 commit comments