private void SendEvents(object state)
        {
            var rnd = new Random();
            while (!Console.KeyAvailable)
            {
                var data = new Hashtable();

                var operation = new RaiseEventRequest { EvCode = 100, Data = data };
                var request = new OperationRequest((byte)Lite.Operations.OperationCode.RaiseEvent, operation);

                //Console.Write('s');
                this.gameServerClient.SendOperationRequest(request, new SendParameters());

                Thread.Sleep(rnd.Next(2000, 5000));
            }
        }
Example #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;
                    }
            }
        }
Example #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);
        }
Example #4
0
        /// <summary>
        ///   Called for each operation in the execution queue.
        ///   Every <see cref = "Room" /> has a queue of incoming operations to execute. 
        ///   Per game <see cref = "ExecuteOperation" /> is never executed multi-threaded, thus all code executed here has thread safe access to all instance members.
        /// </summary>
        /// <param name = "peer">
        ///   The peer.
        /// </param>
        /// <param name = "operationRequest">
        ///   The operation request to execute.
        /// </param>
        /// <param name = "sendParameters">
        ///   The send Parameters.
        /// </param>
        protected override void ExecuteOperation(LitePeer peer, OperationRequest operationRequest, SendParameters sendParameters)
        {
            try
            {
                base.ExecuteOperation(peer, operationRequest, sendParameters);

                if (Log.IsDebugEnabled)
                {
                    Log.DebugFormat("Executing operation {0}", (OperationCode)operationRequest.OperationCode);
                }

                switch ((OperationCode)operationRequest.OperationCode)
                {
                    case OperationCode.Join:
                        {
                            var joinRequest = new JoinRequest(peer.Protocol, operationRequest);
                            if (peer.ValidateOperation(joinRequest, sendParameters) == false)
                            {
                                return;
                            }

                            this.logQueue.Add(new LogEntry("ExecuteOperation: " + (OperationCode)operationRequest.OperationCode, "Peer=" + peer.ConnectionId));

                            joinRequest.OnStart();
                            this.HandleJoinOperation(peer, joinRequest, sendParameters);
                            joinRequest.OnComplete();
                            break;
                        }

                    case OperationCode.Leave:
                        {
                            var leaveOperation = new LeaveRequest(peer.Protocol, operationRequest);
                            if (peer.ValidateOperation(leaveOperation, sendParameters) == false)
                            {
                                return;
                            }

                            this.logQueue.Add(new LogEntry("ExecuteOperation: " + (OperationCode)operationRequest.OperationCode, "Peer=" + peer.ConnectionId));

                            leaveOperation.OnStart();
                            this.HandleLeaveOperation(peer, leaveOperation, sendParameters);
                            leaveOperation.OnComplete();
                            break;
                        }

                    case OperationCode.RaiseEvent:
                        {
                            var raiseEventOperation = new RaiseEventRequest(peer.Protocol, operationRequest);
                            if (peer.ValidateOperation(raiseEventOperation, sendParameters) == false)
                            {
                                return;
                            }

                            raiseEventOperation.OnStart();
                            this.HandleRaiseEventOperation(peer, raiseEventOperation, sendParameters);
                            raiseEventOperation.OnComplete();
                            break;
                        }

                    case OperationCode.GetProperties:
                        {
                            var getPropertiesOperation = new GetPropertiesRequest(peer.Protocol, operationRequest);
                            if (peer.ValidateOperation(getPropertiesOperation, sendParameters) == false)
                            {
                                return;
                            }

                            getPropertiesOperation.OnStart();
                            this.HandleGetPropertiesOperation(peer, getPropertiesOperation, sendParameters);
                            getPropertiesOperation.OnComplete();
                            break;
                        }

                    case OperationCode.SetProperties:
                        {
                            var setPropertiesOperation = new SetPropertiesRequest(peer.Protocol, operationRequest);
                            if (peer.ValidateOperation(setPropertiesOperation, sendParameters) == false)
                            {
                                return;
                            }

                            setPropertiesOperation.OnStart();
                            this.HandleSetPropertiesOperation(peer, setPropertiesOperation, sendParameters);
                            setPropertiesOperation.OnComplete();
                            break;
                        }

                    case OperationCode.Ping:
                        {
                            peer.SendOperationResponse(new OperationResponse { OperationCode = operationRequest.OperationCode }, sendParameters);
                            break;
                        }

                    default:
                        {
                            string message = string.Format("Unknown operation code {0}", (OperationCode)operationRequest.OperationCode);
                            peer.SendOperationResponse(
                                new OperationResponse { OperationCode = operationRequest.OperationCode, ReturnCode = -1, DebugMessage = message }, sendParameters);

                            if (Log.IsWarnEnabled)
                            {
                                Log.Warn(message);
                            }
                        }

                        break;
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }
        }
Example #5
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);
        }
Example #6
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;
            }
        }