@@ -9,6 +9,7 @@ import JOLT from "@/util/loading/JoltSyncLoader"
9
9
import PhysicsSystem from "../physics/PhysicsSystem"
10
10
import World from "../World"
11
11
import type {
12
+ AssemblyRequestData ,
12
13
ClientInfo ,
13
14
CollisionData ,
14
15
EncodedAssembly ,
@@ -18,6 +19,7 @@ import type {
18
19
MetadataUpdateData ,
19
20
UpdateObjectData ,
20
21
} from "./types"
22
+ import MirabufCachingService , { MiraType } from "@/mirabuf/MirabufLoader"
21
23
22
24
const COLLISION_TIMEOUT = 500
23
25
@@ -210,6 +212,10 @@ class MultiplayerSystem {
210
212
case "newObject" :
211
213
await this . handleNewObject ( message . data , peerId )
212
214
break
215
+ case "needAssembly" :
216
+ await this . handleAssemblyRequest ( message . data , peerId )
217
+ break
218
+
213
219
case "metadataUpdate" :
214
220
await this . handleMetadataUpdate ( message . data )
215
221
}
@@ -320,7 +326,30 @@ class MultiplayerSystem {
320
326
}
321
327
322
328
async handleNewObject ( data : InitObjectData , peerId : string ) {
323
- const assembly = mirabuf . Assembly . decode ( data . assembly )
329
+ const assemblyName = data . assemblyName
330
+ let assembly : mirabuf . Assembly
331
+ if ( data . assembly ) {
332
+ assembly = mirabuf . Assembly . decode ( data . assembly )
333
+ } else {
334
+ const cachedFields = Object . values ( MirabufCachingService . getCacheMap ( MiraType . FIELD ) )
335
+ const fieldInfo = cachedFields . find ( f => f . name === assemblyName )
336
+ if ( fieldInfo ) {
337
+ const fieldAssembly = await MirabufCachingService . get ( fieldInfo . id , MiraType . FIELD )
338
+ if ( fieldAssembly ) {
339
+ assembly = fieldAssembly
340
+ } else {
341
+ this . send ( peerId , {
342
+ type : "needAssembly" ,
343
+ data : { assemblyName, sceneObjectKey : data . sceneObjectKey } ,
344
+ } )
345
+ return
346
+ }
347
+ } else {
348
+ this . send ( peerId , { type : "needAssembly" , data : { assemblyName, sceneObjectKey : data . sceneObjectKey } } )
349
+ return
350
+ }
351
+ }
352
+
324
353
const object = await createMirabuf ( assembly )
325
354
if ( object == null ) return
326
355
@@ -334,6 +363,36 @@ class MultiplayerSystem {
334
363
this . _clientToObjectMap . get ( peerId ) ?. push ( object . id ) || this . _clientToObjectMap . set ( peerId , [ object . id ] )
335
364
}
336
365
366
+ async handleAssemblyRequest ( data : AssemblyRequestData , peerId : string ) {
367
+ const assemblyName = data . assemblyName
368
+ const sceneObjectKey = data . sceneObjectKey
369
+
370
+ const cachedFields = Object . values ( MirabufCachingService . getCacheMap ( MiraType . FIELD ) )
371
+ const assemblyInfo = cachedFields . find ( n => n . name === assemblyName )
372
+ if ( ! assemblyInfo ) {
373
+ console . error ( `Cannot find requested assembly in cache: ${ assemblyName } ` )
374
+ return
375
+ }
376
+ const assembly = await MirabufCachingService . get ( assemblyInfo . id , MiraType . FIELD )
377
+ if ( ! assembly ) {
378
+ console . error ( `Failed to get assembly: ${ assemblyName } from cache` )
379
+ return
380
+ }
381
+
382
+ const encodedAssembly = mirabuf . Assembly . encode ( assembly ) . finish ( ) as EncodedAssembly
383
+
384
+ const message : Message = {
385
+ type : "newObject" ,
386
+ data : {
387
+ sceneObjectKey,
388
+ assembly : encodedAssembly ,
389
+ assemblyName,
390
+ } ,
391
+ }
392
+
393
+ this . send ( peerId , message )
394
+ }
395
+
337
396
async handleMetadataUpdate ( data : MetadataUpdateData ) {
338
397
const sceneObject = World . sceneRenderer . sceneObjects . get ( data . sceneObjectKey )
339
398
if ( ! sceneObject || ! ( sceneObject instanceof MirabufSceneObject ) ) return
0 commit comments