/// <summary> /// Handles operation RaiseGenericEvent. Sends event ItemGeneric to an Item owner or the subscribers of an Item />. /// </summary> public OperationResponse OperationRaiseGenericEvent(PeerBase peer, OperationRequest request, SendParameters sendParameters) { var operation = new RaiseGenericEvent(peer.Protocol, request); if (!operation.IsValid) { return new OperationResponse(request.OperationCode) { ReturnCode = (int)ReturnCode.InvalidOperationParameter, DebugMessage = operation.GetErrorMessage() }; } operation.OnStart(); Item item; bool actorItem = true; if (this.TryGetItem(operation.ItemId, out item) == false) { if (this.World.ItemCache.TryGetItem(operation.ItemId, out item) == false) { return operation.GetOperationResponse((int)ReturnCode.ItemNotFound, "ItemNotFound"); } actorItem = false; } if (actorItem) { // we are already in the item thread, invoke directly return ItemOperationRaiseGenericEvent(item, operation, sendParameters); } // second parameter (peer) allows us to send an error event to the client (in case of an error) item.Fiber.Enqueue(() => this.ExecItemOperation(() => ItemOperationRaiseGenericEvent(item, operation, sendParameters), sendParameters)); // operation continued later return null; }
private static OperationResponse ItemOperationRaiseGenericEvent(Item item, RaiseGenericEvent operation, SendParameters sendParameters) { if (item.Disposed) { return operation.GetOperationResponse((int)ReturnCode.ItemNotFound, "ItemNotFound"); } var eventInstance = new ItemGeneric { ItemId = item.Id, CustomEventCode = operation.CustomEventCode, EventData = operation.EventData }; var eventData = new EventData((byte)EventCode.ItemGeneric, eventInstance); sendParameters.Unreliable = (Reliability)operation.EventReliability == Reliability.Unreliable; sendParameters.ChannelId = Settings.ItemEventChannel; switch (operation.EventReceiver) { case (byte)EventReceiver.ItemOwner: { item.Owner.Peer.SendEvent(eventData, sendParameters); break; } case (byte)EventReceiver.ItemSubscriber: { var message = new ItemEventMessage(item, eventData, sendParameters); item.EventChannel.Publish(message); break; } default: { return operation.GetOperationResponse((int)ReturnCode.ParameterOutOfRange, "Invalid EventReceiver " + operation.EventReceiver); } } // no response operation.OnComplete(); return null; }
/// <summary> /// The operation raise generic event. /// </summary> /// <param name = "item"> /// The mmo item. /// </param> /// <param name = "operation"> /// The operation. /// </param> /// <param name = "sendParameters"> /// The send Parameters. /// </param> /// <returns> /// Ok or ItemNotFound /// </returns> private static OperationResponse ItemOperationRaiseGenericEvent(Item item, RaiseGenericEvent operation, SendParameters sendParameters) { if (item.Disposed) { return operation.GetOperationResponse((int)ReturnCode.ItemNotFound, "ItemNotFound"); } var eventInstance = new ItemGeneric { ItemId = item.Id, ItemType = item.Type, CustomEventCode = operation.CustomEventCode, EventData = operation.EventData }; var eventData = new EventData((byte)EventCode.ItemGeneric, eventInstance); sendParameters.Unreliable = (Reliability)operation.EventReliability == Reliability.Unreliable; sendParameters.ChannelId = Settings.ItemEventChannel; switch (operation.EventReceiver) { case (byte)EventReceiver.ItemOwner: { if (((IMmoItem)item).ReceiveEvent(eventData, sendParameters) == false) { string debugMessage = string.Format("Target item {0}/{1} could not receive event", item.Type, item.Id); return operation.GetOperationResponse((int)ReturnCode.InvalidOperation, debugMessage); } break; } case (byte)EventReceiver.ItemSubscriber: { var message = new ItemEventMessage(item, eventData, sendParameters); item.EventChannel.Publish(message); break; } default: { return operation.GetOperationResponse((int)ReturnCode.ParameterOutOfRange, "Invalid EventReceiver " + operation.EventReceiver); } } // no response operation.OnComplete(); return null; }