protected bool RaiseEventOperationHandler(HivePeer peer, RaiseEventRequest raiseEventRequest, SendParameters sendParameters, Actor actor) { sendParameters.Flush = raiseEventRequest.Flush; if (raiseEventRequest.IsCacheSliceIndexOperation) { var msg = string.Empty; if (!this.UpdateCacheSlice(actor.Peer, raiseEventRequest.Cache, raiseEventRequest.CacheSliceIndex, ref msg)) { this.SendErrorResponse(peer, raiseEventRequest.OperationCode, ErrorCode.OperationInvalid, msg, sendParameters); if (Log.IsWarnEnabled) { Log.WarnFormat("Game '{0}' userId '{1}' failed to update Cache Slice. msg:{2} -- peer:{3}", this.Name, peer.UserId, msg, peer); } if (Log.IsWarnEnabled) { Log.Warn(msg); } } return false; } if (raiseEventRequest.IsCacheOpRemoveFromCache) { this.EventCache.RemoveEventsFromCache(raiseEventRequest); var response = new OperationResponse(raiseEventRequest.OperationRequest.OperationCode); peer.SendOperationResponse(response, sendParameters); return false; } if (raiseEventRequest.IsCacheOpRemoveFromCacheForActorsLeft) { var currentActorNumbers = this.ActorsManager.ActorsGetActorNumbers(); this.EventCache.RemoveEventsForActorsNotInList(currentActorNumbers); var response = new OperationResponse(raiseEventRequest.OperationRequest.OperationCode); peer.SendOperationResponse(response, sendParameters); return false; } // publish the custom event var customEvent = new CustomEvent(actor.ActorNr, raiseEventRequest.EvCode, raiseEventRequest.Data); var updateEventCache = false; IEnumerable<Actor> recipients; if (raiseEventRequest.Actors != null && raiseEventRequest.Actors.Length > 0) { recipients = this.ActorsManager.ActorsGetActorsByNumbers(raiseEventRequest.Actors); } else if (raiseEventRequest.Group != 0) { var group = this.GroupManager.GetActorGroup(raiseEventRequest.Group); if (group != null) { recipients = group.GetExcludedList(actor); } else { // group does not exists yet because no one joined it yet. // it's not an error to sent events to empty groups so no error response will be sent return false; } } else { switch ((ReceiverGroup)raiseEventRequest.ReceiverGroup) { case ReceiverGroup.All: recipients = this.Actors; updateEventCache = true; break; case ReceiverGroup.Others: recipients = this.ActorsManager.ActorsGetExcludedList(actor); updateEventCache = true; break; case ReceiverGroup.MasterClient: recipients = new[] { this.ActorsManager.ActorsGetActorByNumber(this.MasterClientId) }; break; default: this.SendErrorResponse(peer, raiseEventRequest.OperationCode, ErrorCode.OperationInvalid, HiveErrorMessages.InvalidReceiverGroup + raiseEventRequest.ReceiverGroup, sendParameters); if (Log.IsWarnEnabled) { Log.WarnFormat("Game '{0}' user '{1}' sent wrong receiver group. msg:{2} -- peer:{3}", this.Name, peer.UserId, HiveErrorMessages.InvalidReceiverGroup + raiseEventRequest.ReceiverGroup, peer); } return false; } } if (updateEventCache && raiseEventRequest.Cache != (byte)CacheOperation.DoNotCache) { string msg; if (!this.UpdateEventCache(actor, raiseEventRequest, out msg)) { this.SendErrorResponse(peer, raiseEventRequest.OperationCode, ErrorCode.OperationInvalid, msg, sendParameters); if (Log.IsWarnEnabled) { Log.WarnFormat("Game '{0}' user '{1}' failed to update EventCache. msg:{2} -- peer:{3}", this.Name, peer.UserId, msg, peer); } return false; } } this.PublishEvent(customEvent, recipients, sendParameters); return true; }
protected bool UpdateEventCache(Actor actor, byte eventCode, object data, byte cacheOp, out string msg) { msg = null; CustomEvent customEvent; switch (cacheOp) { case (byte)CacheOperation.DoNotCache: return true; case (byte)CacheOperation.AddToRoomCache: customEvent = new CustomEvent(actor.ActorNr, eventCode, data); this.EventCache.AddEventToCurrentSlice(customEvent); return true; case (byte)CacheOperation.AddToRoomCacheGlobal: customEvent = new CustomEvent(0, eventCode, data); this.EventCache.AddEventToCurrentSlice(customEvent); return true; } return this.UpdateEventCache(actor, eventCode, data, (CacheOperation)cacheOp, ref msg); }
/// <summary> /// Sends all cached events to a peer. /// </summary> /// <param name = "litePeer"> /// The lite peer that receives the events. /// </param> /// <param name="joinRequest"></param> protected void PublishEventCache(HivePeer litePeer, JoinGameRequest joinRequest) { var @event = new CustomEvent(0, 0, null); foreach (KeyValuePair<int, EventCache> entry in this.ActorEventCache) { var actor = entry.Key; var cache = entry.Value; @event.ActorNr = actor; foreach (KeyValuePair<byte, Hashtable> eventEntry in cache) { @event.Code = @eventEntry.Key; @event.Data = @eventEntry.Value; var eventData = new EventData(@event.Code, @event); litePeer.SendEvent(eventData, new SendParameters()); } } int cacheSliceRequested = 0; if (joinRequest.CacheSlice.HasValue) { cacheSliceRequested = joinRequest.CacheSlice.Value; } foreach (var slice in this.EventCache.Slices) { if (slice >= cacheSliceRequested) { if (slice != 0) { var sliceChangedEvent = new CacheSliceChanged(0) { Slice = slice }; this.PublishEvent(sliceChangedEvent, this.GetActorByPeer(litePeer), new SendParameters()); } foreach (var customEvent in this.EventCache[slice]) { var eventData = new EventData(customEvent.Code, customEvent); litePeer.SendEvent(eventData, new SendParameters()); } } } }