Ejemplo n.º 1
0
        /// <summary>
        ///   Removes a peer from the game.
        ///   This method is called if a client sends a <see cref = "LeaveRequest" /> or disconnects.
        /// </summary>
        /// <param name = "peer">
        ///   The <see cref = "LitePeer" /> to remove.
        /// </param>
        /// <param name="leaveRequest">
        /// The <see cref="LeaveRequest"/> sent by the peer or null if the peer have been disconnected without sending a leave request.
        /// </param>
        /// <returns>
        ///   The actor number of the removed actor.
        ///   If the specified peer does not exists -1 will be returned.
        /// </returns>
        protected virtual int RemovePeerFromGame(LitePeer peer, LeaveRequest leaveRequest)
        {
            Actor actor = this.Actors.RemoveActorByPeer(peer);

            if (actor == null)
            {
                if (Log.IsWarnEnabled)
                {
                    Log.WarnFormat("RemovePeerFromGame - Actor to remove not found for peer: {0}", peer.ConnectionId);
                }

                return(-1);
            }

            this.actorEventCache.RemoveEventCache(actor.ActorNr);

            if (this.DeleteCacheOnLeave)
            {
                this.eventCache.RemoveEventsByActor(actor.ActorNr);
            }

            // raise leave event
            this.PublishLeaveEvent(actor, leaveRequest);

            return(actor.ActorNr);
        }
Ejemplo n.º 2
0
        /// <summary>
        ///   Removes a peer from the game.
        ///   This method is called if a client sends a <see cref = "LeaveRequest" /> or disconnects.
        /// </summary>
        /// <param name = "peer">
        ///   The <see cref = "LitePeer" /> to remove.
        /// </param>
        /// <returns>
        ///   The actor number of the removed actor.
        ///   If the specified peer does not exists -1 will be returned.
        /// </returns>
        protected virtual int RemovePeerFromGame(LitePeer peer)
        {
            Actor actor = this.Actors.RemoveActorByPeer(peer);

            if (actor == null)
            {
                if (Log.IsWarnEnabled)
                {
                    Log.WarnFormat("RemovePeerFromGame - Actor to remove not found for peer: {0}", peer.ConnectionId);
                }

                return(-1);
            }

            this.cachedEvents.Remove(actor.ActorNr);

            // raise leave event
            if (this.Actors.Count > 0)
            {
                IEnumerable <int> actorNumbers = this.Actors.GetActorNumbers();
                var leaveEvent = new LeaveEvent(actor.ActorNr, actorNumbers.ToArray());
                this.PublishEvent(leaveEvent, this.Actors, new SendParameters());
            }

            return(actor.ActorNr);
        }
Ejemplo n.º 3
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.actorEventCache)
            {
                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.º 4
0
        /// <summary>
        ///   Handles the <see cref = "SetPropertiesRequest" /> and sends event <see cref = "PropertiesChangedEvent" /> to all <see cref = "Actor" />s in the room.
        /// </summary>
        /// <param name = "peer">
        ///   The peer.
        /// </param>
        /// <param name = "setPropertiesRequest">
        ///   The <see cref = "SetPropertiesRequest" /> operation to handle.
        /// </param>
        /// <param name = "sendParameters">
        ///   The send Parameters.
        /// </param>
        protected virtual void HandleSetPropertiesOperation(LitePeer peer, SetPropertiesRequest setPropertiesRequest, SendParameters sendParameters)
        {
            // check if peer has joined this room instance
            var sender = this.GetActorByPeer(peer);

            if (sender == null)
            {
                var response = new OperationResponse
                {
                    OperationCode = setPropertiesRequest.OperationRequest.OperationCode,
                    ReturnCode    = -1,
                    DebugMessage  = "Room not joined"
                };

                peer.SendOperationResponse(response, sendParameters);
                return;
            }

            if (setPropertiesRequest.ActorNumber > 0)
            {
                Actor actor = this.Actors.GetActorByNumber(setPropertiesRequest.ActorNumber);
                if (actor == null)
                {
                    peer.SendOperationResponse(
                        new OperationResponse
                    {
                        OperationCode = setPropertiesRequest.OperationRequest.OperationCode,
                        ReturnCode    = -1,
                        DebugMessage  = string.Format("Actor with number {0} not found.", setPropertiesRequest.ActorNumber)
                    },
                        sendParameters);
                    return;
                }

                actor.Properties.SetProperties(setPropertiesRequest.Properties);
            }
            else
            {
                this.Properties.SetProperties(setPropertiesRequest.Properties);
            }

            peer.SendOperationResponse(new OperationResponse {
                OperationCode = setPropertiesRequest.OperationRequest.OperationCode
            }, sendParameters);

            // if the optional paramter Broadcast is set a EvPropertiesChanged
            // event will be send to room actors
            if (setPropertiesRequest.Broadcast)
            {
                Actor actor = this.Actors.GetActorByPeer(peer);
                IEnumerable <Actor> recipients = this.Actors.GetExcludedList(actor);
                var propertiesChangedEvent     = new PropertiesChangedEvent(actor.ActorNr)
                {
                    TargetActorNumber = setPropertiesRequest.ActorNumber, Properties = setPropertiesRequest.Properties
                };

                this.PublishEvent(propertiesChangedEvent, recipients, sendParameters);
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        ///   Handles the <see cref = "LeaveRequest" /> and calls <see cref = "RemovePeerFromGame" />.
        /// </summary>
        /// <param name = "peer">
        ///   The peer.
        /// </param>
        /// <param name = "leaveRequest">
        ///   The operation.
        /// </param>
        /// <param name = "sendParameters">
        ///   The send Parameters.
        /// </param>
        protected virtual void HandleLeaveOperation(LitePeer peer, LeaveRequest leaveRequest, SendParameters sendParameters)
        {
            this.RemovePeerFromGame(peer, leaveRequest);

            // is always reliable, so it gets a response
            peer.SendOperationResponse(new OperationResponse {
                OperationCode = leaveRequest.OperationRequest.OperationCode
            }, sendParameters);
        }
Ejemplo n.º 6
0
 private void DebugLog(LitePeer peer, OperationRequest operationRequest)
 {
     if (this.LogQueue.Log.IsDebugEnabled)
     {
         this.LogQueue.Add(
             new LogEntry(
                 "ExecuteOperation: " + (Lite.Operations.OperationCode)operationRequest.OperationCode,
                 "Peer=" + peer.ConnectionId));
     }
 }
Ejemplo n.º 7
0
        private void HandleMyGameOperation(LitePeer peer, OperationRequest operationRequest, SendParameters sendParameters)
        {
            var requestContract = new MyGameRequest(peer.Protocol, operationRequest);
            requestContract.OnStart();

            var responseContract = new MyGameResponse();
            responseContract.Response = "You are in game " + this.Name;

            var operationResponse = new OperationResponse(operationRequest.OperationCode, responseContract);
            peer.SendOperationResponse(operationResponse, sendParameters);

            requestContract.OnComplete();
        }
Ejemplo n.º 8
0
 /// <summary>
 ///   Sends a <see cref = "LeaveEvent" /> to all <see cref = "Actor" />s.
 /// </summary>
 /// <param name = "peer">
 ///   The peer.
 /// </param>
 /// <param name = "leaveRequest">
 ///   The leave operation.
 /// </param>
 protected virtual void PublishLeaveEvent(LitePeer peer, LeaveRequest leaveRequest)
 {
     if (this.Actors.Count > 0)
     {
         Actor actor = this.GetActorByPeer(peer);
         if (actor != null)
         {
             IEnumerable <int> actorNumbers = this.Actors.GetActorNumbers();
             var leaveEvent = new LeaveEvent(actor.ActorNr, actorNumbers.ToArray());
             this.PublishEvent(leaveEvent, this.Actors, new SendParameters());
         }
     }
 }
Ejemplo n.º 9
0
        private void HandleLeaveOperation(LitePeer peer, OperationRequest operationRequest, SendParameters sendParameters)
        {
            var leaveOperation = new LeaveRequest(peer.Protocol, operationRequest);
            if (peer.ValidateOperation(leaveOperation, sendParameters) == false)
            {
                return;
            }

            DebugLog(peer, operationRequest);

            leaveOperation.OnStart();
            this.HandleLeaveOperation(peer, leaveOperation, sendParameters);
            leaveOperation.OnComplete();
        }
Ejemplo n.º 10
0
        /// <summary>
        ///   Gets the actor for a <see cref = "LitePeer" />.
        /// </summary>
        /// <param name = "peer">
        ///   The peer.
        /// </param>
        /// <returns>
        ///   The actor for the peer or null if no actor for the peer exists (this should not happen).
        /// </returns>
        protected Actor GetActorByPeer(LitePeer peer)
        {
            Actor actor = this.Actors.GetActorByPeer(peer);

            if (actor == null)
            {
                if (Log.IsDebugEnabled)
                {
                    Log.DebugFormat("Actor not found for peer: {0}", peer.ConnectionId);
                }
            }

            return(actor);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Called for each operation in the execution queue.
        /// </summary>
        /// <param name="peer">The peer.</param>
        /// <param name="operationRequest">The operation request to execute.</param>
        /// <param name="sendParameters"></param>
        /// <remarks>
        /// ExecuteOperation is overriden to handle our custom operations.
        /// </remarks>
        protected override void ExecuteOperation(LitePeer peer, OperationRequest operationRequest, SendParameters sendParameters)
        {
            switch ((MyOperationCodes)operationRequest.OperationCode)
            {
                case MyOperationCodes.GameOperation:
                    this.HandleMyGameOperation(peer, operationRequest, sendParameters);
                    break;

                default:
                    // all other operations will be handled by the LiteGame implementation
                    base.ExecuteOperation(peer, operationRequest, sendParameters);
                    break;
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Removes the actor for a a specified peer.
        /// </summary>
        /// <param name="peer">
        /// The peer.
        /// </param>
        /// <returns>
        /// The <see cref="Actor"/> removed or <c>null</c> if no actor for the specified peer exists.
        /// </returns>
        public Actor RemoveActorByPeer(LitePeer peer)
        {
            int index = this.FindIndex(actor => actor.Peer == peer);

            if (index == -1)
            {
                return(null);
            }

            Actor result = this[index];

            this.RemoveAt(index);
            return(result);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Dispatches the <see cref="JoinRequest"/> different from the base <see cref="LiteGame.ExecuteOperation">LiteGame.ExecuteOperation</see>.
        /// </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)
        {
            switch ((OperationCode)operationRequest.OperationCode)
            {
                case OperationCode.Join:
                    var joinOperation = new JoinRequest(peer.Protocol, operationRequest);
                    if (peer.ValidateOperation(joinOperation, sendParameters) == false)
                    {
                        return;
                    }

                    this.HandleJoinOperation(peer, joinOperation, sendParameters);
                    return;
            }

            base.ExecuteOperation(peer, operationRequest, sendParameters);
        }
Ejemplo n.º 14
0
        protected override void ExecuteOperation(LitePeer peer, OperationRequest operationRequest,
                                                 SendParameters sendParameters)
        {
            switch (operationRequest.OperationCode)
            {
                case (byte) DiscussionOpCode.NotifyLeaveUser:
                    {
                        broadcastNewInLobby();
                        break;
                    }
                default:
                    base.ExecuteOperation(peer, operationRequest, sendParameters);
                    break;
            }

            base.ExecuteOperation(peer, operationRequest, sendParameters);
        }
Ejemplo n.º 15
0
        /// <summary>
        ///   Sends a <see cref = "JoinEvent" /> to all <see cref = "Actor" />s.
        /// </summary>
        /// <param name = "peer">
        ///   The peer.
        /// </param>
        /// <param name = "joinRequest">
        ///   The join request.
        /// </param>
        protected virtual void PublishJoinEvent(LitePeer peer, JoinRequest joinRequest)
        {
            Actor actor = this.GetActorByPeer(peer);

            if (actor == null)
            {
                return;
            }

            // generate a join event and publish to all actors in the room
            var joinEvent = new JoinEvent(actor.ActorNr, this.Actors.GetActorNumbers().ToArray());

            if (joinRequest.BroadcastActorProperties)
            {
                joinEvent.ActorProperties = joinRequest.ActorProperties;
            }

            this.PublishEvent(joinEvent, this.Actors, new SendParameters());
        }
Ejemplo n.º 16
0
        /// <summary>
        ///   Handles the <see cref = "GetPropertiesRequest" /> operation: Sends the properties with the <see cref = "OperationResponse" />.
        /// </summary>
        /// <param name = "peer">
        ///   The peer.
        /// </param>
        /// <param name = "getPropertiesRequest">
        ///   The operation to handle.
        /// </param>
        /// <param name = "sendParameters">
        ///   The send Parameters.
        /// </param>
        protected virtual void HandleGetPropertiesOperation(LitePeer peer, GetPropertiesRequest getPropertiesRequest,
                                                            SendParameters sendParameters)
        {
            var response = new GetPropertiesResponse();

            // check if game properties should be returned
            if ((getPropertiesRequest.PropertyType & (byte)PropertyType.Game) == (byte)PropertyType.Game)
            {
                response.GameProperties = this.Properties.GetProperties(getPropertiesRequest.GamePropertyKeys);
            }

            // check if actor properties should be returned
            if ((getPropertiesRequest.PropertyType & (byte)PropertyType.Actor) == (byte)PropertyType.Actor)
            {
                response.ActorProperties = new Hashtable();

                if (getPropertiesRequest.ActorNumbers == null)
                {
                    foreach (Actor actor in this.Actors)
                    {
                        Hashtable actorProperties =
                            actor.Properties.GetProperties(getPropertiesRequest.ActorPropertyKeys);
                        response.ActorProperties.Add(actor.ActorNr, actorProperties);
                    }
                }
                else
                {
                    foreach (int actorNumber in getPropertiesRequest.ActorNumbers)
                    {
                        Actor actor = this.Actors.GetActorByNumber(actorNumber);
                        if (actor != null)
                        {
                            Hashtable actorProperties =
                                actor.Properties.GetProperties(getPropertiesRequest.ActorPropertyKeys);
                            response.ActorProperties.Add(actorNumber, actorProperties);
                        }
                    }
                }
            }

            peer.SendOperationResponse(
                new OperationResponse(getPropertiesRequest.OperationRequest.OperationCode, response), sendParameters);
        }
Ejemplo n.º 17
0
 public void AllRoomsBroadcast(LitePeer peer,
                               OperationRequest operationRequest,
                               SendParameters sendParameters,
                               byte EventCode)
 {
     foreach (string roomName in roomList)
     {
         RoomReference rr = DiscussionGameCache.Instance.GetRoomReference(roomName);
         DiscussionRoom discussionRoom = rr.Room as DiscussionRoom;
         if (discussionRoom != null)
         {
             discussionRoom.Broadcast(peer,
                                      operationRequest,
                                      sendParameters,
                                      EventCode,
                                      BroadcastTo.RoomAll);
         }
     }
     BroadcastLobby(operationRequest, sendParameters, EventCode);
 }
Ejemplo n.º 18
0
        /// <summary>
        ///   Tries to add a <see cref = "LitePeer" /> to this game instance.
        /// </summary>
        /// <param name = "peer">
        ///   The peer to add.
        /// </param>
        /// <param name = "actor">
        ///   When this method returns this out param contains the <see cref = "Actor" /> associated with the <paramref name = "peer" />.
        /// </param>
        /// <returns>
        ///   Returns true if no actor exists for the specified peer and a new actor for the peer has been successfully added.
        ///   The actor parameter is set to the newly created <see cref = "Actor" /> instance.
        ///   Returns false if an actor for the specified peer already exists.
        ///   The actor paramter is set to the existing <see cref = "Actor" /> for the specified peer.
        /// </returns>
        protected virtual bool TryAddPeerToGame(LitePeer peer, out Actor actor)
        {
            // check if the peer already exists in this game
            actor = this.Actors.GetActorByPeer(peer);
            if (actor != null)
            {
                return(false);
            }

            // create new actor instance
            actor = new Actor(peer);
            this.actorNumberCounter++;
            actor.ActorNr = this.actorNumberCounter;
            this.Actors.Add(actor);

            if (Log.IsDebugEnabled)
            {
                Log.DebugFormat("Actor added: {0} to game: {1}", actor.ActorNr, this.Name);
            }

            return(true);
        }
Ejemplo n.º 19
0
        protected override void ExecuteOperation(LitePeer peer, OperationRequest operationRequest, SendParameters sendParameters)
        {
            try
            {
                if (Log.IsDebugEnabled)
                {
                    Log.DebugFormat("Executing operation {0}", operationRequest.OperationCode);
                }

                switch ((byte)operationRequest.OperationCode)
                {
                    case (byte)SPOperationCode.Leave:
                        HandleLeaveOperation(peer, operationRequest, sendParameters);
                        break;

                    //case (byte)SPServer.Operations.SPOperationCode.UpdateFlightControls:
                        //HandleUpdateFlightControls(peer, operationRequest, sendParameters);
                        //break;

                    // Block non-authoritative Lite op codes.
                    case (byte)Lite.Operations.OperationCode.RaiseEvent:
                    case (byte)Lite.Operations.OperationCode.GetProperties:
                    case (byte)Lite.Operations.OperationCode.SetProperties:
                    case (byte)Lite.Operations.OperationCode.ChangeGroups:
                        HandleLiteOperations(peer, operationRequest, sendParameters);
                        break;
                    // all other operation codes will be handled by the LoadBalancing Game implementation
                    default:
                        base.ExecuteOperation(peer, operationRequest, sendParameters);
                        break;
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }
        }
Ejemplo n.º 20
0
        protected virtual void HandleChangeGroupsOperation(LitePeer peer, ChangeGroups changeGroupsRequest, SendParameters sendParameters)
        {
            // get the actor who send the operation request
            Actor actor = this.GetActorByPeer(peer);

            if (actor == null)
            {
                return;
            }

            actor.RemoveGroups(changeGroupsRequest.Remove);

            if (changeGroupsRequest.Add != null)
            {
                if (changeGroupsRequest.Add.Length > 0)
                {
                    foreach (var groupId in changeGroupsRequest.Add)
                    {
                        ActorGroup group;
                        if (!this.actorGroups.TryGetValue(groupId, out group))
                        {
                            group = new ActorGroup(groupId);
                            this.actorGroups.Add(groupId, group);
                        }
                        actor.AddGroup(group);
                    }
                }
                else
                {
                    foreach (var group in this.actorGroups.Values)
                    {
                        actor.AddGroup(group);
                    }
                }
            }
        }
Ejemplo n.º 21
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.º 22
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);

            bool updateEventCache = false;
            IEnumerable <Actor> recipients;

            if (raiseEventRequest.Actors != null && raiseEventRequest.Actors.Length > 0)
            {
                recipients = this.Actors.GetActorsByNumbers(raiseEventRequest.Actors);
            }
            else if (raiseEventRequest.Group != 0)
            {
                ActorGroup group;
                if (this.actorGroups.TryGetValue(raiseEventRequest.Group, out group))
                {
                    recipients = group.GetExcludedList(actor);
                }
                else
                {
                    return;
                }
            }
            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)
            {
                string msg;
                if (!this.UpdateEventCache(actor, raiseEventRequest, out msg))
                {
                    peer.SendOperationResponse(
                        new OperationResponse
                    {
                        OperationCode = raiseEventRequest.OperationRequest.OperationCode,
                        ReturnCode    = -1,
                        DebugMessage  = msg
                    },
                        sendParameters);
                    return;
                }
            }

            this.PublishEvent(customEvent, recipients, sendParameters);
        }
Ejemplo n.º 23
0
 /// <summary>
 ///   Sends a <see cref = "LeaveEvent" /> to all <see cref = "Actor" />s.
 /// </summary>
 /// <param name = "peer">
 ///   The peer.
 /// </param>
 /// <param name = "leaveRequest">
 ///   The leave operation.
 /// </param>
 protected virtual void PublishLeaveEvent(LitePeer peer, LeaveRequest leaveRequest)
 {
     if (this.Actors.Count > 0)
     {
         Actor actor = this.GetActorByPeer(peer);
         if (actor != null)
         {
             IEnumerable<int> actorNumbers = this.Actors.GetActorNumbers();
             var leaveEvent = new LeaveEvent(actor.ActorNr, actorNumbers.ToArray());
             this.PublishEvent(leaveEvent, this.Actors, new SendParameters());
         }
     }
 }
Ejemplo n.º 24
0
        private void HandleUpdateFlightControls(LitePeer peer, OperationRequest operationRequest, SendParameters sendParameters)
        {
            var op = new UpdateControlsRequest(peer.Protocol, operationRequest);
            if (peer.ValidateOperation(op, sendParameters) == false)
            {
                return;
            }
            DebugLog(peer, operationRequest);

            op.OnStart();
            peer.SendOperationResponse(new OperationResponse { OperationCode = op.OperationRequest.OperationCode }, sendParameters);
            op.OnComplete();
        }
Ejemplo n.º 25
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.º 26
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.º 27
0
 /// <summary>
 ///   This method is invoked sequentially for each operation request
 ///   enqueued in the <see cref = "ExecutionFiber" /> using the
 ///   <see cref = "EnqueueOperation" /> method.
 /// </summary>
 /// <param name = "peer">
 ///   The peer.
 /// </param>
 /// <param name = "operation">
 ///   The operation request.
 /// </param>
 /// <param name = "sendParameters">
 ///   The send Parameters.
 /// </param>
 protected virtual void ExecuteOperation(LitePeer peer, OperationRequest operation, SendParameters sendParameters)
 {
 }
Ejemplo n.º 28
0
        /// <summary>
        ///   Gets the actor for a <see cref = "LitePeer" />.
        /// </summary>
        /// <param name = "peer">
        ///   The peer.
        /// </param>
        /// <returns>
        ///   The actor for the peer or null if no actor for the peer exists (this should not happen).
        /// </returns>
        protected Actor GetActorByPeer(LitePeer peer)
        {
            Actor actor = this.Actors.GetActorByPeer(peer);
            if (actor == null)
            {
                if (Log.IsWarnEnabled)
                {
                    Log.WarnFormat("Actor not found for peer: {0}", peer.ConnectionId);
                }
            }

            return actor;
        }
Ejemplo n.º 29
0
        /// <summary>
        /// This override disables the event publishing.
        /// </summary>
        /// <param name="peer">
        /// The peer.
        /// </param>
        /// <param name="leaveRequest">
        /// The <see cref="LeaveRequest"/> sent by the peer or null if the peer have been disconnected without sending a leave request.
        /// </param>
        /// <returns>
        /// the actor number.
        /// </returns>
        protected override int RemovePeerFromGame(LitePeer peer, LeaveRequest leaveRequest)
        {
            Actor actor = this.Actors.GetActorByPeer(peer);

            if (this.Actors.Remove(actor) == false)
            {
                if (Log.IsWarnEnabled)
                {
                    Log.WarnFormat("RemovePeerFromGame - Actor to remove not found for peer: {0}", peer.ConnectionId);
                }

                return 0;
            }

            return actor.ActorNr;
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Executes the base <see cref="LiteGame.HandleJoinOperation">HandleJoinOperation</see> and then sends an updated game list to all <see cref="Actor"/>s in the lobby.
        /// </summary>
        /// <param name="peer">
        /// The peer.
        /// </param>
        /// <param name="joinRequest">
        /// The join request.
        /// </param>
        /// <param name="sendParameters">
        /// The send Parameters.
        /// </param>
        /// <returns>
        /// The new actor
        /// </returns>
        protected virtual Actor HandleJoinOperation(LitePeer peer, JoinRequest joinRequest, SendParameters sendParameters)
        {
            Actor actor = base.HandleJoinOperation(peer, joinRequest, sendParameters);
            if (actor != null)
            {
                this.PublishGameList(actor);
            }

            return actor;
        }
Ejemplo n.º 31
0
 /// <summary>
 /// This override disables the event publishing.
 /// </summary>
 /// <param name="peer">
 /// The peer.
 /// </param>
 /// <param name="joinRequest">
 /// The join request.
 /// </param>
 protected override void PublishJoinEvent(LitePeer peer, Lite.Operations.JoinRequest joinRequest)
 {
     // lobbies don't publish a join event to the clients
 }
Ejemplo n.º 32
0
        /// <summary>
        ///   Removes a peer from the game. 
        ///   This method is called if a client sends a <see cref = "LeaveRequest" /> or disconnects.
        /// </summary>
        /// <param name = "peer">
        ///   The <see cref = "LitePeer" /> to remove.
        /// </param>
        /// <param name="leaveRequest">
        /// The <see cref="LeaveRequest"/> sent by the peer or null if the peer have been disconnected without sending a leave request.
        /// </param>
        /// <returns>
        ///   The actor number of the removed actor. 
        ///   If the specified peer does not exists -1 will be returned.
        /// </returns>
        protected virtual int RemovePeerFromGame(LitePeer peer, LeaveRequest leaveRequest)
        {
            Actor actor = this.Actors.RemoveActorByPeer(peer);
            if (actor == null)
            {
                if (Log.IsWarnEnabled)
                {
                    Log.WarnFormat("RemovePeerFromGame - Actor to remove not found for peer: {0}", peer.ConnectionId);
                }

                return -1;
            }

            this.eventCacheOld.Remove(actor.ActorNr);

            if (this.DeleteCacheOnLeave)
            {
                this.eventCache.RemoveEventsByActor(actor.ActorNr);
            }

            // raise leave event
            this.PublishLeaveEvent(actor, leaveRequest);

            return actor.ActorNr;
        }
Ejemplo n.º 33
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.º 34
0
        private void HandleLiteOperations(LitePeer peer, OperationRequest operationRequest, SendParameters sendParameters)
        {
            string message = string.Format("Unknown operation code {0}", (Lite.Operations.OperationCode)operationRequest.OperationCode);
            peer.SendOperationResponse(
                new OperationResponse { OperationCode = operationRequest.OperationCode, ReturnCode = -1, DebugMessage = message }, sendParameters);

            if (Log.IsWarnEnabled)
            {
                Log.Warn(message);
            }
        }
Ejemplo n.º 35
0
        /// <summary>
        ///   Handles the <see cref = "JoinRequest" />: Joins a peer to a room and calls <see cref = "PublishJoinEvent" />.
        ///   Before a JoinOperation reaches this point (inside a room), the <see cref = "LitePeer" /> made 
        ///   sure that it is removed from the previous Room (if there was any).
        /// </summary>
        /// <param name = "peer">
        ///   The peer.
        /// </param>
        /// <param name = "joinRequest">
        ///   The join operation.
        /// </param>
        /// <param name = "sendParameters">
        ///   The send Parameters.
        /// </param>
        /// <returns>
        ///   The newly created (joined) actor or null if the peer already joined.
        /// </returns>
        protected virtual Actor HandleJoinOperation(LitePeer peer, JoinRequest joinRequest, SendParameters sendParameters)
        {
            if (this.IsDisposed)
            {
                // join arrived after being disposed - repeat join operation
                if (Log.IsWarnEnabled)
                {
                    Log.WarnFormat("Join operation on disposed game. GameName={0}", this.Name);
                }

                return null;
            }

            if (Log.IsDebugEnabled)
            {
                Log.DebugFormat("Join operation from IP: {0} to port: {1}", peer.RemoteIP, peer.LocalPort);
            }

            // create an new actor
            Actor actor;
            if (this.TryAddPeerToGame(peer, out actor) == false)
            {
                peer.SendOperationResponse(
                    new OperationResponse
                        {
                            OperationCode = joinRequest.OperationRequest.OperationCode,
                            ReturnCode = -1,
                            DebugMessage = "Peer already joined the specified game."
                        },
                    sendParameters);
                return null;
            }

            // set game properties for join from the first actor
            if (this.Actors.Count == 1)
            {
                this.DeleteCacheOnLeave = joinRequest.DeleteCacheOnLeave;

                if (joinRequest.GameProperties != null)
                {
                    this.Properties.SetProperties(joinRequest.GameProperties);
                }
            }

            // set custom actor properties if defined
            if (joinRequest.ActorProperties != null)
            {
                actor.Properties.SetProperties(joinRequest.ActorProperties);
            }

            // set operation return values and publish the response
            var joinResponse = new JoinResponse { ActorNr = actor.ActorNr };

            if (this.Properties.Count > 0)
            {
                joinResponse.CurrentGameProperties = this.Properties.GetProperties();
            }

            foreach (Actor t in this.Actors)
            {
                if (t.ActorNr != actor.ActorNr && t.Properties.Count > 0)
                {
                    if (joinResponse.CurrentActorProperties == null)
                    {
                        joinResponse.CurrentActorProperties = new Hashtable();
                    }

                    Hashtable actorProperties = t.Properties.GetProperties();
                    joinResponse.CurrentActorProperties.Add(t.ActorNr, actorProperties);
                }
            }

            peer.SendOperationResponse(new OperationResponse(joinRequest.OperationRequest.OperationCode, joinResponse), sendParameters);

            // publish join event
            this.PublishJoinEvent(peer, joinRequest);

            this.PublishEventCache(peer);

            return actor;
        }
Ejemplo n.º 36
0
        protected bool ValidateGame(LitePeer peer, OperationRequest operationRequest, SendParameters sendParameters)
        {
            var gamePeer = (GameClientPeer)peer;

            // check if the game is open
            if (this.isOpen == false)
            {
                var errorResponse = new OperationResponse { OperationCode = operationRequest.OperationCode, ReturnCode = (int)ErrorCode.GameClosed, DebugMessage = "Game closed" };
                peer.SendOperationResponse(errorResponse, sendParameters);
                gamePeer.OnJoinFailed(ErrorCode.GameClosed);
                return false;
            }

            // check if the maximum number of players has already been reached
            if (this.maxPlayers > 0 && this.Actors.Count >= this.maxPlayers)
            {
                var errorResponse = new OperationResponse { OperationCode = operationRequest.OperationCode, ReturnCode = (int)ErrorCode.GameFull, DebugMessage = "Game full" };
                peer.SendOperationResponse(errorResponse, sendParameters);
                gamePeer.OnJoinFailed(ErrorCode.GameFull);
                return false;
            }

            return true;
        }
Ejemplo n.º 37
0
 /// <summary>
 ///   Enqueues an <see cref = "OperationRequest" /> to the end of the execution queue.
 /// </summary>
 /// <param name = "peer">
 ///   The peer.
 /// </param>
 /// <param name = "operationRequest">
 ///   The operation request to enqueue.
 /// </param>
 /// <param name = "sendParameters">
 ///   The send Parameters.
 /// </param>
 /// <remarks>
 ///   <see cref = "ExecuteOperation" /> is called sequentially for each operation request
 ///   stored in the execution queue.
 ///   Using an execution queue ensures that operation request are processed in order
 ///   and sequentially to prevent object synchronization (multi threading).
 /// </remarks>
 public void EnqueueOperation(LitePeer peer, OperationRequest operationRequest, SendParameters sendParameters)
 {
     this.ExecutionFiber.Enqueue(() => this.ExecuteOperation(peer, operationRequest, sendParameters));
 }
Ejemplo n.º 38
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);
            }
        }
Ejemplo n.º 39
0
        /// <summary>
        ///   Updates the lobby when an <see cref = "Actor" /> joins.
        /// </summary>
        /// <param name = "peer">
        ///   The peer.
        /// </param>
        /// <param name = "joinRequest">
        ///   The join operation.
        /// </param>
        /// <param name = "sendParamters">
        ///   The send Paramters.
        /// </param>
        /// <returns>
        ///   The newly created (joined) <see cref = "Actor" />.
        /// </returns>
        protected override Actor HandleJoinOperation(LitePeer peer, JoinRequest joinRequest, SendParameters sendParamters)
        {
            Actor actor = base.HandleJoinOperation(peer, joinRequest, sendParamters);
            if (actor != null)
            {
                this.UpdateLobby();
            }

            return actor;
        }
Ejemplo n.º 40
0
        /// <summary>
        ///   Handles the <see cref = "GetPropertiesRequest" /> operation: Sends the properties with the <see cref = "OperationResponse" />.
        /// </summary>
        /// <param name = "peer">
        ///   The peer.
        /// </param>
        /// <param name = "getPropertiesRequest">
        ///   The operation to handle.
        /// </param>
        /// <param name = "sendParameters">
        ///   The send Parameters.
        /// </param>
        protected virtual void HandleGetPropertiesOperation(LitePeer peer, GetPropertiesRequest getPropertiesRequest, SendParameters sendParameters)
        {
            var response = new GetPropertiesResponse();

            // check if game properties should be returned
            if ((getPropertiesRequest.PropertyType & (byte)PropertyType.Game) == (byte)PropertyType.Game)
            {
                response.GameProperties = this.Properties.GetProperties(getPropertiesRequest.GamePropertyKeys);
            }

            // check if actor properties should be returned
            if ((getPropertiesRequest.PropertyType & (byte)PropertyType.Actor) == (byte)PropertyType.Actor)
            {
                response.ActorProperties = new Hashtable();

                if (getPropertiesRequest.ActorNumbers == null)
                {
                    foreach (Actor actor in this.Actors)
                    {
                        Hashtable actorProperties = actor.Properties.GetProperties(getPropertiesRequest.ActorPropertyKeys);
                        response.ActorProperties.Add(actor.ActorNr, actorProperties);
                    }
                }
                else
                {
                    foreach (int actorNumber in getPropertiesRequest.ActorNumbers)
                    {
                        Actor actor = this.Actors.GetActorByNumber(actorNumber);
                        if (actor != null)
                        {
                            Hashtable actorProperties = actor.Properties.GetProperties(getPropertiesRequest.ActorPropertyKeys);
                            response.ActorProperties.Add(actorNumber, actorProperties);
                        }
                    }
                }
            }

            peer.SendOperationResponse(new OperationResponse(getPropertiesRequest.OperationRequest.OperationCode, response), sendParameters);
        }
Ejemplo n.º 41
0
 /// <summary>
 ///   Updates the lobby when an <see cref = "Actor" /> leaves (disconnect, <see cref = "LeaveRequest" />, <see cref = "JoinRequest" /> for another game).
 /// </summary>
 /// <param name = "peer">
 ///   The <see cref = "LitePeer" /> to remove.
 /// </param>
 /// <param name="leaveRequest">
 ///   The <see cref="LeaveRequest"/> sent by the peer or null if the peer have been disconnected without sending a leave request.
 /// </param>
 /// <returns>
 ///   The actore number of the removed actor.
 ///   If the specified peer does not exists -1 will be returned.
 /// </returns>
 protected override int RemovePeerFromGame(LitePeer peer, LeaveRequest leaveRequest)
 {
     int actorNr = base.RemovePeerFromGame(peer, leaveRequest);
     this.UpdateLobby();
     return actorNr;
 }
Ejemplo n.º 42
0
        /// <summary>
        ///   Handles the <see cref = "LeaveRequest" /> and calls <see cref = "RemovePeerFromGame" />.
        /// </summary>
        /// <param name = "peer">
        ///   The peer.
        /// </param>
        /// <param name = "leaveRequest">
        ///   The operation.
        /// </param>
        /// <param name = "sendParameters">
        ///   The send Parameters.
        /// </param>
        protected virtual void HandleLeaveOperation(LitePeer peer, LeaveRequest leaveRequest, SendParameters sendParameters)
        {
            this.RemovePeerFromGame(peer, leaveRequest);

            // is always reliable, so it gets a response
            peer.SendOperationResponse(new OperationResponse { OperationCode = leaveRequest.OperationRequest.OperationCode }, sendParameters);
        }
Ejemplo n.º 43
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;
                    }

                    if (this.LogQueue.Log.IsDebugEnabled)
                    {
                        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;
                    }

                    if (this.LogQueue.Log.IsDebugEnabled)
                    {
                        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;
                }

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

                    changeGroupsOperation.OnStart();
                    this.HandleChangeGroupsOperation(peer, changeGroupsOperation, sendParameters);
                    changeGroupsOperation.OnComplete();
                    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);
            }
        }
Ejemplo n.º 44
0
        /// <summary>
        ///   Handles the <see cref = "SetPropertiesRequest" /> and sends event <see cref = "PropertiesChangedEvent" /> to all <see cref = "Actor" />s in the room.
        /// </summary>
        /// <param name = "peer">
        ///   The peer.
        /// </param>
        /// <param name = "setPropertiesRequest">
        ///   The <see cref = "SetPropertiesRequest" /> operation to handle.
        /// </param>
        /// <param name = "sendParameters">
        ///   The send Parameters.
        /// </param>
        protected virtual void HandleSetPropertiesOperation(LitePeer peer, SetPropertiesRequest setPropertiesRequest, SendParameters sendParameters)
        {
            if (setPropertiesRequest.ActorNumber > 0)
            {
                Actor actor = this.Actors.GetActorByNumber(setPropertiesRequest.ActorNumber);
                if (actor == null)
                {
                    peer.SendOperationResponse(
                        new OperationResponse
                            {
                                OperationCode = setPropertiesRequest.OperationRequest.OperationCode,
                                ReturnCode = -1,
                                DebugMessage = string.Format("Actor with number {0} not found.", setPropertiesRequest.ActorNumber)
                            },
                        sendParameters);
                    return;
                }

                actor.Properties.SetProperties(setPropertiesRequest.Properties);
            }
            else
            {
                this.Properties.SetProperties(setPropertiesRequest.Properties);
            }

            peer.SendOperationResponse(new OperationResponse { OperationCode = setPropertiesRequest.OperationRequest.OperationCode }, sendParameters);

            // if the optional paramter Broadcast is set a EvPropertiesChanged
            // event will be send to room actors
            if (setPropertiesRequest.Broadcast)
            {
                Actor actor = this.Actors.GetActorByPeer(peer);
                IEnumerable<Actor> recipients = this.Actors.GetExcludedList(actor);
                var propertiesChangedEvent = new PropertiesChangedEvent(actor.ActorNr)
                    {
                       TargetActorNumber = setPropertiesRequest.ActorNumber, Properties = setPropertiesRequest.Properties
                    };

                this.PublishEvent(propertiesChangedEvent, recipients, sendParameters);
            }
        }
Ejemplo n.º 45
0
        /// <summary>
        ///   Removes a peer from the game. 
        ///   This method is called if a client sends a <see cref = "LeaveRequest" /> or disconnects.
        /// </summary>
        /// <param name = "peer">
        ///   The <see cref = "LitePeer" /> to remove.
        /// </param>
        /// <returns>
        ///   The actor number of the removed actor. 
        ///   If the specified peer does not exists -1 will be returned.
        /// </returns>
        protected virtual int RemovePeerFromGame(LitePeer peer)
        {
            Actor actor = this.Actors.RemoveActorByPeer(peer);
            if (actor == null)
            {
                if (Log.IsWarnEnabled)
                {
                    Log.WarnFormat("RemovePeerFromGame - Actor to remove not found for peer: {0}", peer.ConnectionId);
                }

                return -1;
            }

            this.cachedEvents.Remove(actor.ActorNr);

            // raise leave event
            if (this.Actors.Count > 0)
            {
                IEnumerable<int> actorNumbers = this.Actors.GetActorNumbers();
                var leaveEvent = new LeaveEvent(actor.ActorNr, actorNumbers.ToArray());
                this.PublishEvent(leaveEvent, this.Actors, new SendParameters());
            }

            return actor.ActorNr;
        }
Ejemplo n.º 46
0
        /// <summary>
        ///   Sends a <see cref = "JoinEvent" /> to all <see cref = "Actor" />s.
        /// </summary>
        /// <param name = "peer">
        ///   The peer.
        /// </param>
        /// <param name = "joinRequest">
        ///   The join request.
        /// </param>
        protected virtual void PublishJoinEvent(LitePeer peer, JoinRequest joinRequest)
        {
            Actor actor = this.GetActorByPeer(peer);
            if (actor == null)
            {
                return;
            }

            // generate a join event and publish to all actors in the room
            var joinEvent = new JoinEvent(actor.ActorNr, this.Actors.GetActorNumbers().ToArray());

            if (joinRequest.BroadcastActorProperties)
            {
                joinEvent.ActorProperties = joinRequest.ActorProperties;
            }

            this.PublishEvent(joinEvent, this.Actors, new SendParameters());
        }
Ejemplo n.º 47
0
        /// <summary>
        ///   Handles the <see cref = "JoinRequest" />: Joins a peer to a room and calls <see cref = "PublishJoinEvent" />.
        ///   Before a JoinOperation reaches this point (inside a room), the <see cref = "LitePeer" /> made
        ///   sure that it is removed from the previous Room (if there was any).
        /// </summary>
        /// <param name = "peer">
        ///   The peer.
        /// </param>
        /// <param name = "joinRequest">
        ///   The join operation.
        /// </param>
        /// <param name = "sendParameters">
        ///   The send Parameters.
        /// </param>
        /// <returns>
        ///   The newly created (joined) actor or null if the peer already joined.
        /// </returns>
        protected virtual Actor HandleJoinOperation(LitePeer peer, JoinRequest joinRequest, SendParameters sendParameters)
        {
            if (this.IsDisposed)
            {
                // join arrived after being disposed - repeat join operation
                if (Log.IsWarnEnabled)
                {
                    Log.WarnFormat("Join operation on disposed game. GameName={0}", this.Name);
                }

                return(null);
            }

            if (Log.IsDebugEnabled)
            {
                Log.DebugFormat("Join operation from IP: {0} to port: {1}", peer.RemoteIP, peer.LocalPort);
            }

            // create an new actor
            Actor actor;

            if (this.TryAddPeerToGame(peer, joinRequest.ActorNr, out actor) == false)
            {
                peer.SendOperationResponse(
                    new OperationResponse
                {
                    OperationCode = joinRequest.OperationRequest.OperationCode,
                    ReturnCode    = -1,
                    DebugMessage  = "Peer already joined the specified game."
                },
                    sendParameters);
                return(null);
            }

            // check if a room removal is in progress and cancel it if so
            if (this.RemoveTimer != null)
            {
                this.RemoveTimer.Dispose();
                this.RemoveTimer = null;
            }

            // set game properties for join from the first actor (game creator)
            if (this.Actors.Count == 1)
            {
                this.DeleteCacheOnLeave = joinRequest.DeleteCacheOnLeave;
                this.SuppressRoomEvents = joinRequest.SuppressRoomEvents;

                if (joinRequest.GameProperties != null)
                {
                    this.Properties.SetProperties(joinRequest.GameProperties);
                }
            }

            // set custom actor properties if defined
            if (joinRequest.ActorProperties != null)
            {
                actor.Properties.SetProperties(joinRequest.ActorProperties);
            }

            // set operation return values and publish the response
            var joinResponse = new JoinResponse {
                ActorNr = actor.ActorNr
            };

            if (this.Properties.Count > 0)
            {
                joinResponse.CurrentGameProperties = this.Properties.GetProperties();
            }

            foreach (Actor t in this.Actors)
            {
                if (t.ActorNr != actor.ActorNr && t.Properties.Count > 0)
                {
                    if (joinResponse.CurrentActorProperties == null)
                    {
                        joinResponse.CurrentActorProperties = new Hashtable();
                    }

                    Hashtable actorProperties = t.Properties.GetProperties();
                    joinResponse.CurrentActorProperties.Add(t.ActorNr, actorProperties);
                }
            }

            peer.SendOperationResponse(new OperationResponse(joinRequest.OperationRequest.OperationCode, joinResponse), sendParameters);

            // publish join event
            this.PublishJoinEvent(peer, joinRequest);

            this.PublishEventCache(peer);

            return(actor);
        }
Ejemplo n.º 48
0
        /// <summary>
        ///   Tries to add a <see cref = "LitePeer" /> to this game instance.
        /// </summary>
        /// <param name = "peer">
        ///   The peer to add.
        /// </param>
        /// <param name = "actor">
        ///   When this method returns this out param contains the <see cref = "Actor" /> associated with the <paramref name = "peer" />.
        /// </param>
        /// <returns>
        ///   Returns true if no actor exists for the specified peer and a new actor for the peer has been successfully added. 
        ///   The actor parameter is set to the newly created <see cref = "Actor" /> instance.
        ///   Returns false if an actor for the specified peer already exists. 
        ///   The actor paramter is set to the existing <see cref = "Actor" /> for the specified peer.
        /// </returns>
        protected virtual bool TryAddPeerToGame(LitePeer peer, out Actor actor)
        {
            // check if the peer already exists in this game
            actor = this.Actors.GetActorByPeer(peer);
            if (actor != null)
            {
                return false;
            }

            // create new actor instance
            actor = new Actor(peer);
            this.actorNumberCounter++;
            actor.ActorNr = this.actorNumberCounter;
            this.Actors.Add(actor);

            if (Log.IsDebugEnabled)
            {
                Log.DebugFormat("Actor added: {0} to game: {1}", actor.ActorNr, this.Name);
            }

            return true;
        }
Ejemplo n.º 49
0
 /// <summary>
 /// Gets an actor by a specified peer.
 /// </summary>
 /// <param name="peer">
 /// The peer.
 /// </param>
 /// <returns>
 /// Returns the actor for the specified peer or null
 /// if no actor for the specified peer was found.
 /// </returns>
 public Actor GetActorByPeer(LitePeer peer)
 {
     return(this.FirstOrDefault(actor => actor.Peer == peer));
 }