/// <summary> /// Subscribes the player on the item's event channel and notifies the client /// </summary> protected override void OnMmoObjectSubscribed(MmoObjectSnapshot snapshot) { var mmoObject = snapshot.Source; // publish event messages var eventSubscription = mmoObject.EventChannel.Subscribe(this.fiber, this.SubscribedItem_OnGameObjectEvent); this.eventChannelSubscriptions.Add(mmoObject, eventSubscription); var eventSubscribed = new ObjectSubscribed { ObjectId = mmoObject.Guid, Position = snapshot.Coordinate, Orientation = snapshot.Rotation.Y, }; var objectFlags = mmoObject.Flags; if ((objectFlags & MmoObjectFlags.HasProperties) == MmoObjectFlags.HasProperties) { eventSubscribed.Revision = snapshot.Revision; if ((objectFlags & MmoObjectFlags.SendPropertiesOnSubscribe) == MmoObjectFlags.SendPropertiesOnSubscribe) { lock (mmoObject) // locking is important eventSubscribed.Properties = mmoObject.GetProperties(); } } switch ((ObjectType)mmoObject.Guid.Type) { case ObjectType.Gameobject: case ObjectType.Npc: case ObjectType.Dynamic: { var interestFlags = this.Owner.GetFlags(mmoObject); if (interestFlags != InterestFlags.None) { eventSubscribed.Flags = (int)interestFlags; } } break; } this.receiver.SendEvent(eventSubscribed, new MessageParameters { ChannelId = PeerSettings.MmoObjectEventChannel }); this.Owner.OnSubscribe(mmoObject); }
/// <summary> /// Receives the <see cref="MmoObjectSnapshot"/> auto subscribes item if necessary. /// </summary> internal void ReceiveMmoObjectSnapshot(MmoObjectSnapshot message) { lock (SyncRoot) { // auto subscribe item? if (CanAutoSubscribeMmoObject(message.Source) == false) { return; } MmoObjectAutoSubscription existingSubscription; if (autoManagedItemSubscriptions.TryGetValue(message.Source, out existingSubscription)) { // dropped out of world, unsubscribe if (message.WorldRegion == null) { this.AutoUnsubscribeMmoObject(existingSubscription); return; } // update position existingSubscription.Position = message.Position; existingSubscription.WorldRegion = message.WorldRegion; return; } // item not in view if (message.WorldRegion == null || this.subscribedWorldRegions.ContainsKey(message.WorldRegion) == false) { return; } // unsubscribe if item is disposed var disposalSubscription = message.Source.DisposeChannel.Subscribe(this.subscriptionManagementFiber, this.AutoSubscribedMmoObject_OnMmoObjectDisposed); // unsubscribe if item moves out of range var positionSubscription = message.Source.PositionUpdateChannel.SubscribeToLast(this.subscriptionManagementFiber, this.AutoSubscribedMmoObject_OnMmoObjectPosition, GameObjectAutoUnsubcribeDelayMilliseconds); var itemSubscription = new MmoObjectAutoSubscription(message.Source, message.Position, message.WorldRegion, new UnsubscriberCollection(disposalSubscription, positionSubscription)); this.autoManagedItemSubscriptions.Add(message.Source, itemSubscription); this.OnMmoObjectSubscribed(message); } }
/// <summary> /// Does nothing. /// Called after subscribing an <see cref = "MmoObject" />. /// </summary> protected virtual void OnMmoObjectSubscribed(MmoObjectSnapshot itemSnapshot) { }