Ejemplo n.º 1
0
        /// <summary>
        ///   Sends all cached events to a peer.
        /// </summary>
        /// <param name = "litePeer">
        ///   The lite peer that receives the events.
        /// </param>
        protected void PublishEventCache(LitePeer litePeer)
        {
            var @event = new CustomEvent(0, 0, null);
            foreach (KeyValuePair<int, EventCache> entry in this.eventCacheOld)
            {
                int actor = entry.Key;
                EventCache 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());
                }
            }

            foreach (CustomEvent customEvent in this.eventCache)
            {
                var eventData = new EventData(customEvent.Code, customEvent);
                litePeer.SendEvent(eventData, new SendParameters());
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        ///   Helper method of <see cref = "HandleRaiseEventOperation" />.
        ///   Stores an event for new actors.
        /// </summary>
        /// <param name = "actor">
        ///   The actor.
        /// </param>
        /// <param name = "raiseEventRequest">
        ///   The raise event request.
        /// </param>
        /// <returns>
        ///   True if <see cref = "RaiseEventRequest.Cache" /> is valid.
        /// </returns>
        protected bool UpdateEventCache(Actor actor, RaiseEventRequest raiseEventRequest)
        {
            CustomEvent customEvent;

            switch (raiseEventRequest.Cache)
            {
                case (byte)CacheOperation.AddToRoomCache:
                    customEvent = new CustomEvent(actor.ActorNr, raiseEventRequest.EvCode, raiseEventRequest.Data) { Cache = raiseEventRequest.Cache };
                    this.eventCache.AddEvent(customEvent);
                    return true;

                case (byte)CacheOperation.AddToRoomCacheGlobal:
                    customEvent = new CustomEvent(0, raiseEventRequest.EvCode, raiseEventRequest.Data) { Cache = raiseEventRequest.Cache };
                    this.eventCache.AddEvent(customEvent);
                    return true;

                case (byte)CacheOperation.MergeCache:
                    {
                        EventCache eventCache;
                        if (!this.eventCacheOld.TryGetValue(actor.ActorNr, out eventCache))
                        {
                            eventCache = new EventCache();
                            this.eventCacheOld.Add(actor.ActorNr, eventCache);
                        }

                        Hashtable @event;
                        if (eventCache.TryGetValue(raiseEventRequest.EvCode, out @event))
                        {
                            // null events are removed
                            if (raiseEventRequest.Data == null)
                            {
                                eventCache.Remove(raiseEventRequest.EvCode);
                            }
                            else
                            {
                                // merge or delete
                                foreach (DictionaryEntry pair in raiseEventRequest.Data)
                                {
                                    // null values are removed
                                    if (pair.Value == null)
                                    {
                                        @event.Remove(pair.Key);
                                    }
                                    else
                                    {
                                        @event[pair.Key] = pair.Value;
                                    }
                                }
                            }
                        }
                        else if (raiseEventRequest.Data != null)
                        {
                            // new
                            @event = raiseEventRequest.Data;
                            eventCache.Add(raiseEventRequest.EvCode, @event);
                        }

                        return true;
                    }

                case (byte)CacheOperation.RemoveCache:
                    {
                        EventCache eventCache;
                        if (!this.eventCacheOld.TryGetValue(actor.ActorNr, out eventCache))
                        {
                            return true;
                        }

                        eventCache.Remove(raiseEventRequest.EvCode);
                        return true;
                    }

                case (byte)CacheOperation.ReplaceCache:
                    {
                        EventCache eventCache;
                        if (!this.eventCacheOld.TryGetValue(actor.ActorNr, out eventCache))
                        {
                            eventCache = new EventCache();
                            this.eventCacheOld.Add(actor.ActorNr, eventCache);
                        }

                        eventCache.Remove(raiseEventRequest.EvCode);
                        if (raiseEventRequest.Data != null)
                        {
                            Hashtable @event = raiseEventRequest.Data;
                            eventCache.Add(raiseEventRequest.EvCode, @event);
                        }

                        return true;
                    }

                default:
                    {
                        return false;
                    }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        ///   Handles the <see cref = "RaiseEventRequest" />: Sends a <see cref = "CustomEvent" /> to actors in the room.
        /// </summary>
        /// <param name = "peer">
        ///   The peer.
        /// </param>
        /// <param name = "raiseEventRequest">
        ///   The operation
        /// </param>
        /// <param name = "sendParameters">
        ///   The send Parameters.
        /// </param>
        protected virtual void HandleRaiseEventOperation(LitePeer peer, RaiseEventRequest raiseEventRequest, SendParameters sendParameters)
        {
            // get the actor who send the operation request
            Actor actor = this.GetActorByPeer(peer);
            if (actor == null)
            {
                return;
            }

            sendParameters.Flush = raiseEventRequest.Flush;

            if (raiseEventRequest.Cache == (byte)CacheOperation.RemoveFromRoomCache)
            {
                this.eventCache.RemoveEvents(raiseEventRequest);
                var response = new OperationResponse(raiseEventRequest.OperationRequest.OperationCode) { ReturnCode = 0 };
                peer.SendOperationResponse(response, sendParameters);
                return;
            }

            if (raiseEventRequest.Cache == (byte)CacheOperation.RemoveFromCacheForActorsLeft)
            {
                var currentActorNumbers = this.Actors.GetActorNumbers();
                this.eventCache.RemoveEventsForActorsNotInList(currentActorNumbers);
                var response = new OperationResponse(raiseEventRequest.OperationRequest.OperationCode) { ReturnCode = 0 };
                peer.SendOperationResponse(response, sendParameters);
                return;
            }

            // publish the custom event
            var customEvent = new CustomEvent(actor.ActorNr, raiseEventRequest.EvCode, raiseEventRequest.Data) { Cache = raiseEventRequest.Cache };

            bool updateEventCache = false;
            IEnumerable<Actor> recipients;
            if (raiseEventRequest.Actors != null && raiseEventRequest.Actors.Length > 0)
            {
                recipients = this.Actors.GetActorsByNumbers(raiseEventRequest.Actors);
            }
            else
            {
                switch ((ReceiverGroup)raiseEventRequest.ReceiverGroup)
                {
                    case ReceiverGroup.All:
                        recipients = this.Actors;
                        updateEventCache = true;
                        break;

                    case ReceiverGroup.Others:
                        recipients = this.Actors.GetExcludedList(actor);
                        updateEventCache = true;
                        break;

                    case ReceiverGroup.MasterClient:
                        recipients = new[] { this.Actors[0] };
                        break;

                    default:
                        peer.SendOperationResponse(
                            new OperationResponse
                            {
                                OperationCode = raiseEventRequest.OperationRequest.OperationCode,
                                ReturnCode = -1,
                                DebugMessage = "Invalid ReceiverGroup " + raiseEventRequest.ReceiverGroup
                            },
                            sendParameters);
                        return;
                }
            }

            if (updateEventCache && raiseEventRequest.Cache != (byte)CacheOperation.DoNotCache)
            {
                if (!this.UpdateEventCache(actor, raiseEventRequest))
                {
                    peer.SendOperationResponse(
                        new OperationResponse
                        {
                            OperationCode = raiseEventRequest.OperationRequest.OperationCode,
                            ReturnCode = -1,
                            DebugMessage = "Invalid cache operation " + raiseEventRequest.Cache
                        },
                        sendParameters);
                    return;
                }
            }

            this.PublishEvent(customEvent, recipients, sendParameters);
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Sends the complete list of games to one actor in the lobby.
 /// </summary>
 /// <param name="actor">
 /// The actor.
 /// </param>
 private void PublishGameList(Actor actor)
 {
     // Room list needs to be cloned because it is serialized in other thread and is changed at the same time
     var customEvent = new CustomEvent(actor.ActorNr, (byte)LiteLobbyEventCode.GameList, (Hashtable)this.roomList.Clone());
     this.PublishEvent(customEvent, actor, new SendParameters { Unreliable = true });
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Sends the change list to all users in the lobby and then clears it.
        /// </summary>
        private void PublishChangeList()
        {
            if (this.changedRoomList.Count > 0 && this.Actors.Count > 0)
            {
                var customEvent = new CustomEvent(0, (byte)LiteLobbyEventCode.GameListUpdate, this.changedRoomList);

                // PublishEvent(hashtable) uses a reference to hashtable, which means you can not clear it (see below)
                this.PublishEvent(customEvent, this.Actors, new SendParameters { Unreliable = true });
            }

            this.changedRoomList = new Hashtable(); // creating a new hashtable, as PublishEvent() uses just a ref to the data to be sent
            this.SchedulePublishChanges();
        }
Ejemplo n.º 6
0
        /// <summary>
        ///   Handles the <see cref = "RaiseEventRequest" />: Sends a <see cref = "CustomEvent" /> to actors in the room.
        /// </summary>
        /// <param name = "peer">
        ///   The peer.
        /// </param>
        /// <param name = "raiseEventRequest">
        ///   The operation
        /// </param>
        /// <param name = "sendParameters">
        ///   The send Parameters.
        /// </param>
        protected virtual void HandleRaiseEventOperation(LitePeer peer, RaiseEventRequest raiseEventRequest,
                                                         SendParameters sendParameters)
        {
            // get the actor who send the operation request
            Actor actor = this.GetActorByPeer(peer);
            if (actor == null)
            {
                return;
            }

            var customEvent = new CustomEvent(actor.ActorNr, raiseEventRequest.EvCode, raiseEventRequest.Data);

            if (raiseEventRequest.Cache == (byte) CacheOperation.RemoveFromRoomCache)
            {
                this.roomEventCache.RemoveEvents(raiseEventRequest);
                var response = new OperationResponse(raiseEventRequest.OperationRequest.OperationCode) {ReturnCode = 0};
                peer.SendOperationResponse(response, sendParameters);
                return;
            }

            // publish the custom event
            IEnumerable<Actor> recipients;
            if (raiseEventRequest.Actors != null && raiseEventRequest.Actors.Length > 0)
            {
                recipients = this.Actors.GetActorsByNumbers(raiseEventRequest.Actors);
                sendParameters.Flush = raiseEventRequest.Flush;
                this.PublishEvent(customEvent, recipients, sendParameters);
                return;
            }

            switch (raiseEventRequest.ReceiverGroup)
            {
                case (byte) ReceiverGroup.All:
                    {
                        recipients = this.Actors;

                        if (raiseEventRequest.Cache == (byte) CacheOperation.AddToRoomCache)
                        {
                            customEvent.Cache = raiseEventRequest.Cache;
                            this.roomEventCache.AddEvent(customEvent);
                        }
                        else if (raiseEventRequest.Cache == (byte) CacheOperation.AddToRoomCacheGlobal)
                        {
                            customEvent.ActorNr = 0;
                            customEvent.Cache = raiseEventRequest.Cache;
                            this.roomEventCache.AddEvent(customEvent);
                        }
                        else if (raiseEventRequest.Cache != (byte) CacheOperation.DoNotCache)
                        {
                            if (!this.UpdateEventCache(actor, raiseEventRequest, raiseEventRequest.EvCode))
                            {
                                peer.SendOperationResponse(
                                    new OperationResponse
                                        {
                                            OperationCode = raiseEventRequest.OperationRequest.OperationCode,
                                            ReturnCode = -1,
                                            DebugMessage = "Invalid cache operation " + raiseEventRequest.Cache
                                        },
                                    sendParameters);
                                return;
                            }

                            customEvent.Cache = raiseEventRequest.Cache;
                        }

                        break;
                    }

                case (byte) ReceiverGroup.Others:
                    {
                        recipients = this.Actors.GetExcludedList(actor);

                        if (raiseEventRequest.Cache == (byte) CacheOperation.AddToRoomCache)
                        {
                            customEvent.Cache = raiseEventRequest.Cache;
                            this.roomEventCache.AddEvent(customEvent);
                        }
                        else if (raiseEventRequest.Cache == (byte) CacheOperation.AddToRoomCacheGlobal)
                        {
                            customEvent.ActorNr = 0;
                            customEvent.Cache = raiseEventRequest.Cache;
                            this.roomEventCache.AddEvent(customEvent);
                        }
                        else if (raiseEventRequest.Cache != (byte) CacheOperation.DoNotCache)
                        {
                            if (!this.UpdateEventCache(actor, raiseEventRequest, raiseEventRequest.EvCode))
                            {
                                peer.SendOperationResponse(
                                    new OperationResponse
                                        {
                                            OperationCode = raiseEventRequest.OperationRequest.OperationCode,
                                            ReturnCode = -1,
                                            DebugMessage = "Invalid cache operation " + raiseEventRequest.Cache
                                        },
                                    sendParameters);
                                return;
                            }

                            customEvent.Cache = raiseEventRequest.Cache;
                        }

                        break;
                    }

                case (byte) ReceiverGroup.MasterClient:
                    {
                        recipients = new[] {this.Actors[0]};
                        break;
                    }

                default:
                    {
                        peer.SendOperationResponse(
                            new OperationResponse
                                {
                                    OperationCode = raiseEventRequest.OperationRequest.OperationCode,
                                    ReturnCode = -1,
                                    DebugMessage = "Invalid ReceiverGroup " + raiseEventRequest.ReceiverGroup
                                },
                            sendParameters);
                        return;
                    }
            }

            this.PublishEvent(customEvent, recipients, sendParameters);
        }
Ejemplo n.º 7
0
        /// <summary>
        ///   Helper method of <see cref = "HandleRaiseEventOperation" />.
        ///   Stores an event for new actors.
        /// </summary>
        /// <param name = "actor">
        ///   The actor.
        /// </param>
        /// <param name = "raiseEventRequest">
        ///   The raise event request.
        /// </param>
        /// <param name="msg">
        ///   Contains an error message if the method returns false.
        /// </param>
        /// <returns>
        ///   True if <see cref = "RaiseEventRequest.Cache" /> is valid.
        /// </returns>
        protected bool UpdateEventCache(Actor actor, RaiseEventRequest raiseEventRequest, out string msg)
        {
            msg = null;
            CustomEvent customEvent;

            switch (raiseEventRequest.Cache)
            {
                case (byte)CacheOperation.DoNotCache:
                    return true;

                case (byte)CacheOperation.AddToRoomCache:
                    customEvent = new CustomEvent(actor.ActorNr, raiseEventRequest.EvCode, raiseEventRequest.Data);
                    this.eventCache.AddEvent(customEvent);
                    return true;

                case (byte)CacheOperation.AddToRoomCacheGlobal:
                    customEvent = new CustomEvent(0, raiseEventRequest.EvCode, raiseEventRequest.Data);
                    this.eventCache.AddEvent(customEvent);
                    return true;
            }

            // cache operations for the actor event cache currently only working with hashtable data
            Hashtable eventData;
            if (raiseEventRequest.Data == null || raiseEventRequest.Data is Hashtable)
            {
                eventData = (Hashtable)raiseEventRequest.Data;
            }
            else
            {
                msg = string.Format("Cache operation '{0}' requires a Hashtable as event data.", raiseEventRequest.Cache);
                return false;
            }


            switch (raiseEventRequest.Cache)
            {
                case (byte)CacheOperation.MergeCache:
                    this.actorEventCache.MergeEvent(actor.ActorNr, raiseEventRequest.EvCode, eventData);
                    return true;

                case (byte)CacheOperation.RemoveCache:
                    this.actorEventCache.RemoveEvent(actor.ActorNr, raiseEventRequest.EvCode);
                    return true;

                case (byte)CacheOperation.ReplaceCache:
                    this.actorEventCache.ReplaceEvent(actor.ActorNr, raiseEventRequest.EvCode, eventData);
                    return true;

                default:
                msg = string.Format("Unknown cache operation '{0}'.", raiseEventRequest.Cache);
                    return false;
            }
        }