diff --git a/pkg/channeld/event.go b/pkg/channeld/event.go index 4d6ec37..c7a916c 100644 --- a/pkg/channeld/event.go +++ b/pkg/channeld/event.go @@ -23,6 +23,13 @@ var Event_AuthComplete = &Event[AuthEventData]{} var Event_FsmDisallowed = &Event[*Connection]{} +type EntityChannelSpatiallyOwnedEventData struct { + EntityChannel *Channel + SpatialChanel *Channel +} + +var Event_EntityChannelSpatiallyOwned = &Event[EntityChannelSpatiallyOwnedEventData]{} + type EventData interface { } diff --git a/pkg/channeld/message_spatial.go b/pkg/channeld/message_spatial.go index b55f915..9298a09 100644 --- a/pkg/channeld/message_spatial.go +++ b/pkg/channeld/message_spatial.go @@ -248,13 +248,9 @@ func handleCreateEntityChannel(ctx MessageContext) { newChannel.Logger().Info("set the entity channel owner to the spatial channel's", zap.Uint32("spatialChId", uint32(spatialChId))) - /* Sub-and-send happens at the end of this function - // Subscribe the owner to the entity channel - sub, shouldSend := ownerConn.SubscribeToChannel(newChannel, msg.SubOptions) - if shouldSend { - ownerConn.sendSubscribed(MessageContext{}, newChannel, ownerConn, 0, &sub.options) - } - */ + Event_EntityChannelSpatiallyOwned.Broadcast(EntityChannelSpatiallyOwnedEventData{newChannel, spatialCh}) + + // Sub-and-send happens at the end of this function // Set the messge context so that the CreateChannelResultMessage will be sent to the owner // instead of the message sender (the master server). diff --git a/pkg/unreal/message.go b/pkg/unreal/message.go index 1362fb2..da4a709 100644 --- a/pkg/unreal/message.go +++ b/pkg/unreal/message.go @@ -12,6 +12,8 @@ import ( func InitMessageHandlers() { channeld.RegisterMessageHandler(uint32(unrealpb.MessageType_SPAWN), &channeldpb.ServerForwardMessage{}, handleUnrealSpawnObject) channeld.RegisterMessageHandler(uint32(unrealpb.MessageType_DESTROY), &channeldpb.ServerForwardMessage{}, handleUnrealDestroyObject) + + channeld.Event_EntityChannelSpatiallyOwned.Listen(handleEntityChannelSpatiallyOwned) } // Executed in the spatial channels or the GLOBAL channel (no-spatial scenario) @@ -116,6 +118,8 @@ type UnrealObjectEntityData interface { SetObjRef(objRef *unrealpb.UnrealObjectRef) } +// Add the SpatialEntityState to the spatial channel data. If an entity doesn't exist in the spatial channel data, +// handover will not work properly. func addSpatialEntity(ch *channeld.Channel, objRef *unrealpb.UnrealObjectRef) { if ch.Type() != channeldpb.ChannelType_SPATIAL { return @@ -183,3 +187,15 @@ func handleUnrealDestroyObject(ctx channeld.MessageContext) { channeld.RemoveChannel(entityCh) } } + +func handleEntityChannelSpatiallyOwned(data channeld.EntityChannelSpatiallyOwnedEventData) { + dataMsgWithObjRef, ok := data.EntityChannel.GetDataMessage().(unrealpb.EntityChannelDataWithObjRef) + if !ok { + data.EntityChannel.Logger().Error("spatial-owned entity channel data doesn't implement EntityChannelDataWithObjRef") + return + } + + data.SpatialChanel.Execute(func(ch *channeld.Channel) { + addSpatialEntity(ch, dataMsgWithObjRef.GetObjRef()) + }) +}