/// <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);
            }
        }
Beispiel #2
0
        protected override void HandleSetPropertiesOperation(LitePeer peer, SetPropertiesRequest request, SendParameters sendParameters)
        {
            byte? newMaxPlayer = null;
            bool? newIsOpen = null;
            bool? newIsVisible = null;
            object[] newLobbyProperties = null;

            // try to parse build in propeties if game properties should be set (ActorNumber == 0)
            bool updateGameProperties = request.ActorNumber == 0 && request.Properties != null && request.Properties.Count > 0;

            // special handling for game and actor properties send by AS3/Flash (Amf3 protocol) or JSON clients
            if (peer.Protocol.ProtocolType == ProtocolType.Amf3V152 || peer.Protocol.ProtocolType == ProtocolType.Json)
            {
                if (updateGameProperties)
                {
                    Utilities.ConvertAs3WellKnownPropertyKeys(request.Properties, null);   
                }
                else
                {
                    Utilities.ConvertAs3WellKnownPropertyKeys(null, request.Properties);   
                }
            }

            if (updateGameProperties)
            {
                if (!TryParseDefaultProperties(peer, request, request.Properties, sendParameters, out newMaxPlayer, out newIsOpen, out newIsVisible, out newLobbyProperties))
                {
                    return;
                }
            }

            base.HandleSetPropertiesOperation(peer, request, sendParameters);

            // report to master only if game properties are updated
            if (!updateGameProperties)
            {
                return;
            }

            // set default properties
            if (newMaxPlayer.HasValue && newMaxPlayer.Value != this.maxPlayers)
            {
                this.maxPlayers = newMaxPlayer.Value;
            }

            if (newIsOpen.HasValue && newIsOpen.Value != this.isOpen)
            {
                this.isOpen = newIsOpen.Value;
            }

            if (newIsVisible.HasValue && newIsVisible.Value != this.isVisible)
            {
                this.isVisible = newIsVisible.Value;
            }

            if (newLobbyProperties != null)
            {
                this.lobbyProperties = new HashSet<object>(newLobbyProperties);
            }

            Hashtable gameProperties;
            if (newLobbyProperties != null)
            {
                // if the property filter for the app lobby properties has been changed
                // all game properties are resend to the master server because the application 
                // lobby might not contain all properties specified.
                gameProperties = this.GetLobbyGameProperties(this.Properties.GetProperties());
            }
            else
            {
                // property filter hasn't chjanged; only the changed properties will
                // be updatet in the application lobby
                gameProperties = this.GetLobbyGameProperties(request.Properties);
            }

            this.UpdateGameStateOnMaster(newMaxPlayer, newIsOpen, newIsVisible, newLobbyProperties, gameProperties);
        }
        /// <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);
            }
        }
Beispiel #4
0
        protected override void HandleSetPropertiesOperation(LitePeer peer, SetPropertiesRequest request, SendParameters sendParameters)
        {
            byte? newMaxPlayer = null;
            bool? newIsOpen = null;
            bool? newIsVisible = null;
            object[] newLobbyProperties = null;

            // try to parse build in propeties if game properties should be set (ActorNumber == 0)
            bool updateGameProperties = request.ActorNumber == 0 && request.Properties != null && request.Properties.Count > 0;
            if (updateGameProperties)
            {
                if (!TryParseDefaultProperties(peer, request, request.Properties, sendParameters, out newMaxPlayer, out newIsOpen, out newIsVisible, out newLobbyProperties))
                {
                    return;
                }
            }

            base.HandleSetPropertiesOperation(peer, request, sendParameters);

            // report to master only if game properties are updated
            if (!updateGameProperties)
            {
                return;
            }

            Hashtable gameProperties;
            if (newLobbyProperties != null)
            {
                this.lobbyProperties = new HashSet<object>(newLobbyProperties);

                // app lobby properties have changed.
                // all new properties which are specified are send to the master server
                // because the SetPropertiesRequest might not contain all of the new
                // properties specified.
                gameProperties = new Hashtable();
                foreach (var entry in this.lobbyProperties)
                {
                    object value;
                    if (this.Properties.TryGetValue(entry, out value))
                    {
                        gameProperties.Add(entry, value);
                    }
                }
            }
            else
            {
                if (this.lobbyProperties == null)
                {
                    // if no filter is set for properties which should be listet in the lobby
                    // all changed properties are sent to the master
                    gameProperties = request.Properties;
                }
                else
                {
                    gameProperties = new Hashtable();

                    foreach (var key in this.lobbyProperties)
                    {
                        if (request.Properties.ContainsKey(key))
                        {
                            gameProperties.Add(key, request.Properties[key]);
                        }
                    }
                }
            }

            if (newMaxPlayer.HasValue && newMaxPlayer.Value != this.maxPlayers)
            {
                this.maxPlayers = newMaxPlayer.Value;
                gameProperties[(byte)GameParameter.MaxPlayer] = this.maxPlayers;
            }
            else
            {
                gameProperties.Remove((byte)GameParameter.MaxPlayer);
            }

            if (newIsOpen.HasValue && newIsOpen.Value != this.isOpen)
            {
                this.isOpen = newIsOpen.Value;
                gameProperties[(byte)GameParameter.IsOpen] = this.isOpen;
            }
            else
            {
                gameProperties.Remove((byte)GameParameter.IsOpen);
            }

            if (newIsVisible.HasValue && newIsVisible.Value != this.isVisible)
            {
                this.isVisible = newIsVisible.Value;
                gameProperties[(byte)GameParameter.IsVisible] = this.isVisible;
            }
            else
            {
                gameProperties.Remove((byte)GameParameter.IsVisible);
            }

            if (newLobbyProperties != null)
            {
                gameProperties[(byte)GameParameter.Properties] = newLobbyProperties;
            }

            this.UpdateGameStateOnMaster(gameProperties, null, null, false);
        }