示例#1
0
        protected virtual int RemovePeerFromGame(PlayerPeer peer, LeaveRequest leaveRequest)
        {
            var actor = Actors.RemoveActorByPeer(peer);

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

                return(-1);
            }

            ActorEventCache.RemoveEventCache(actor.ActorNr);

            if (DeleteCacheOnLeave)
            {
                EventCache.RemoveEventsByActor(actor.ActorNr);
            }

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

            return(actor.ActorNr);
        }
示例#2
0
        protected void PublishEventCache(PlayerPeer playerPeer)
        {
            var @event = new CustomEvent(0, 0, null);

            foreach (var entry in ActorEventCache)
            {
                var actor = entry.Key;
                var cache = entry.Value;
                @event.ActorNr = actor;
                foreach (var eventEntry in cache)
                {
                    @event.Code = @eventEntry.Key;
                    @event.Data = @eventEntry.Value;

                    var eventData = new EventData(@event.Code, @event);
                    playerPeer.SendEvent(eventData, new SendParameters());
                }
            }

            foreach (var customEvent in EventCache)
            {
                var eventData = new EventData(customEvent.Code, customEvent);
                playerPeer.SendEvent(eventData, new SendParameters());
            }
        }
        public Actor RemoveActorByPeer(PlayerPeer peer)
        {
            var index = FindIndex(actor => actor.Peer == peer);

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

            var result = this[index];

            RemoveAt(index);
            return(result);
        }
示例#4
0
        protected virtual void HandleLeaveOperation(
            PlayerPeer peer,
            LeaveRequest leaveRequest,
            SendParameters sendParameters)
        {
            RemovePeerFromGame(peer, leaveRequest);

            // is always reliable, so it gets a response
            peer.SendOperationResponse(
                new OperationResponse {
                OperationCode = leaveRequest.OperationRequest.OperationCode
            },
                sendParameters);
        }
示例#5
0
        protected Actor GetActorByPeer(PlayerPeer peer)
        {
            var actor = Actors.GetActorByPeer(peer);

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

            return(actor);
        }
示例#6
0
        protected virtual void HandleGetPropertiesOperation(
            PlayerPeer 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 = 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 (var actor in Actors)
                    {
                        var actorProperties = actor.Properties.GetProperties(getPropertiesRequest.ActorPropertyKeys);
                        response.ActorProperties.Add(actor.ActorNr, actorProperties);
                    }
                }
                else
                {
                    foreach (var actorNumber in getPropertiesRequest.ActorNumbers)
                    {
                        var actor = Actors.GetActorByNumber(actorNumber);
                        if (actor != null)
                        {
                            var actorProperties =
                                actor.Properties.GetProperties(getPropertiesRequest.ActorPropertyKeys);
                            response.ActorProperties.Add(actorNumber, actorProperties);
                        }
                    }
                }
            }

            peer.SendOperationResponse(
                new OperationResponse(getPropertiesRequest.OperationRequest.OperationCode, response),
                sendParameters);
        }
示例#7
0
        protected virtual void HandleChangeGroupsOperation(
            PlayerPeer peer,
            ChangeGroups changeGroupsRequest,
            SendParameters sendParameters)
        {
            // get the actor who send the operation request
            var actor = 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 (!ActorGroups.TryGetValue(groupId, out group))
                        {
                            group = new ActorGroup(groupId);
                            ActorGroups.Add(groupId, group);
                        }

                        actor.AddGroup(group);
                    }
                }
                else
                {
                    foreach (var group in ActorGroups.Values)
                    {
                        actor.AddGroup(group);
                    }
                }
            }
        }
示例#8
0
        protected virtual bool TryAddPeerToGame(PlayerPeer peer, int actorNr, out Actor actor)
        {
            // check if the peer already exists in this game
            actor = Actors.GetActorByPeer(peer);
            if (actor != null)
            {
                return(false);
            }

            if (actorNr != 0)
            {
                actor = Actors.GetActorByNumber(actorNr);
                if (actor != null)
                {
                    return(false);
                }
            }

            // create new actor instance
            actor = new Actor(peer);
            if (actorNr != 0)
            {
                actor.ActorNr = actorNr;
            }
            else
            {
                _actorNumberCounter++;
                actor.ActorNr = _actorNumberCounter;
            }

            Actors.Add(actor);

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

            return(true);
        }
示例#9
0
        protected virtual void PublishJoinEvent(PlayerPeer peer, JoinRequest joinRequest)
        {
            if (SuppressRoomEvents)
            {
                return;
            }

            var actor = GetActorByPeer(peer);

            if (actor == null)
            {
                return;
            }

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

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

            PublishEvent(joinEvent, Actors, new SendParameters());
        }
示例#10
0
        protected virtual void HandleSetPropertiesOperation(
            PlayerPeer peer,
            SetPropertiesRequest setPropertiesRequest,
            SendParameters sendParameters)
        {
            // check if peer has joined this room instance
            var sender = 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)
            {
                var actor = 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
            {
                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)
            {
                var actor                  = Actors.GetActorByPeer(peer);
                var recipients             = Actors.GetExcludedList(actor);
                var propertiesChangedEvent =
                    new PropertiesChangedEvent(actor.ActorNr)
                {
                    TargetActorNumber = setPropertiesRequest.ActorNumber,
                    Properties        = setPropertiesRequest.Properties
                };

                PublishEvent(propertiesChangedEvent, recipients, sendParameters);
            }
        }
示例#11
0
        protected virtual void HandleRaiseEventOperation(
            PlayerPeer peer,
            RaiseEventRequest raiseEventRequest,
            SendParameters sendParameters)
        {
            // get the actor who send the operation request
            var actor = GetActorByPeer(peer);

            if (actor == null)
            {
                return;
            }

            sendParameters.Flush = raiseEventRequest.Flush;

            if (raiseEventRequest.Cache == (byte)CacheOperation.RemoveFromRoomCache)
            {
                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 = Actors.GetActorNumbers();
                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);

            var updateEventCache = false;
            IEnumerable <Actor> recipients;

            if (raiseEventRequest.Actors != null && raiseEventRequest.Actors.Length > 0)
            {
                recipients = Actors.GetActorsByNumbers(raiseEventRequest.Actors);
            }
            else if (raiseEventRequest.Group != 0)
            {
                ActorGroup group;
                if (ActorGroups.TryGetValue(raiseEventRequest.Group, out group))
                {
                    recipients = group.GetExcludedList(actor);
                }
                else
                {
                    return;
                }
            }
            else
            {
                switch ((ReceiverGroup)raiseEventRequest.ReceiverGroup)
                {
                case ReceiverGroup.All:
                    recipients       = Actors;
                    updateEventCache = true;
                    break;

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

                case ReceiverGroup.MasterClient:
                    recipients = new[] { 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 (!UpdateEventCache(actor, raiseEventRequest, out msg))
                {
                    peer.SendOperationResponse(
                        new OperationResponse
                    {
                        OperationCode = raiseEventRequest.OperationRequest.OperationCode,
                        ReturnCode    = -1,
                        DebugMessage  = msg
                    },
                        sendParameters);
                    return;
                }
            }

            PublishEvent(customEvent, recipients, sendParameters);
        }
示例#12
0
        protected override void ExecuteOperation(
            PlayerPeer 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 (LogQueue.Log.IsDebugEnabled)
                    {
                        LogQueue.Add(
                            new LogEntry(
                                "ExecuteOperation: " + (OperationCode)operationRequest.OperationCode,
                                "Peer=" + peer.ConnectionId));
                    }

                    joinRequest.OnStart();
                    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 (LogQueue.Log.IsDebugEnabled)
                    {
                        LogQueue.Add(
                            new LogEntry(
                                "ExecuteOperation: " + (OperationCode)operationRequest.OperationCode,
                                "Peer=" + peer.ConnectionId));
                    }

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

                case OperationCode.CustomOp:
                    // todo: here implemented custom logic
                    // get handler for opp
                    break;

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

                    raiseEventOperation.OnStart();
                    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();
                    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();
                    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();
                    HandleChangeGroupsOperation(peer, changeGroupsOperation, sendParameters);
                    changeGroupsOperation.OnComplete();
                    break;
                }

                default:
                {
                    var message = $"Unknown operation code {(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);
            }
        }
示例#13
0
        protected virtual Actor HandleJoinOperation(
            PlayerPeer peer,
            JoinRequest joinRequest,
            SendParameters sendParameters)
        {
            if (IsDisposed)
            {
                // join arrived after being disposed - repeat join operation
                if (Log.IsWarnEnabled)
                {
                    Log.WarnFormat("Join operation on disposed game. GameName={0}", 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 (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 (RemoveTimer != null)
            {
                RemoveTimer.Dispose();
                RemoveTimer = null;
            }

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

                if (joinRequest.GameProperties != null)
                {
                    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 (Properties.Count > 0)
            {
                joinResponse.CurrentGameProperties = Properties.GetProperties();
            }

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

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

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

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

            PublishEventCache(peer);

            return(actor);
        }
示例#14
0
 protected virtual void ExecuteOperation(
     PlayerPeer peer,
     OperationRequest operation,
     SendParameters sendParameters)
 {
 }
示例#15
0
 public void EnqueueOperation(PlayerPeer peer, OperationRequest operationRequest, SendParameters sendParameters)
 {
     ExecutionFiber.Enqueue(() => ExecuteOperation(peer, operationRequest, sendParameters));
 }