예제 #1
0
        /// <summary>
        /// Handles a <see cref="AcquireServerResponse"/>.
        /// </summary>
        private void HandleOperationResponseAcquireServerResponse(IRpcProtocol protocol, OperationResponse operationResponse)
        {
            var response = new AcquireServerResponse(protocol, operationResponse);

            if (!response.IsValid || operationResponse.ReturnCode != (short)ResultCode.Ok)
            {
#if MMO_DEBUG
                _logger.DebugFormat("Re-acquiring chat server connection info. ResponseValid?={0}. ReturnCode={1}.", response.IsValid, operationResponse.ReturnCode);
#endif
                this.AcquireChatServerConnection(ServerSettings.SERVER_RECONNECT_INTERVAL);
                return;
            }

            Interlocked.CompareExchange(ref listenerState, (int)ListenerState.Connecting, (int)ListenerState.Disconnected);

            var newListenerState = ListenerState;
            if (newListenerState != ListenerState.Connecting)
            {
                _logger.ErrorFormat("[HandleOperationResponseAcquireServerResponse]: Invalid listener state (State={0})", newListenerState);
                return;
            }

            var ipAddress = IPAddress.Parse(response.Address);
            var port      = response.TcpPort;
            WorldApplication.Instance.ConnectToExternalServer(new IPEndPoint(ipAddress, port), "Chat", this);
        }
        private OperationResponse HandleOperationRemoveChatChannel(OperationRequest operationRequest)
        {
            var operation = new RemoveChannel(this.Protocol, operationRequest);

            if (!operation.IsValid)
            {
                return new OperationResponse(operationRequest.OperationCode)
                       {
                           ReturnCode = (short)ResultCode.InvalidOperationParameter, DebugMessage = operation.GetErrorMessage()
                       }
            }
            ;

            Channel channel;

            if (chat.Channels.TryGetValue(operation.ChannelId, out channel))
            {
                if (!chat.RemoveChannel(channel))
                {
                    // this wont happen
                    _logger.ErrorFormat("[HandleOperationRemoveChatChannel]: Cannot remove chat channel");
                    channel.Dispose();
                }
                this.channels.Remove(channel.Id);
            }
            return(null);
        }
예제 #3
0
        protected override void OnEvent(IEventData eventData, SendParameters sendParameters)
        {
            // Events from a Sub-Servers are always sent to a client

            object clientId;

            if (eventData.Parameters.TryGetValue(0, out clientId))
            {
                MasterClientPeer client;
                if (Application.MasterLobby.Clients.TryGetClient((int)clientId, out client))
                {
                    eventData.Parameters.Remove(0);
                    client.RequestFiber.Enqueue(() => client.SendEvent(eventData, sendParameters));
                }
            }
            else
            {
                Logger.ErrorFormat("[OnEvent]: Server (Id={0}) did not send a clientId with Event (EvCode={1})", this.ServerId, eventData.Code);
            }
        }
예제 #4
0
        protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
        {
            IncomingSubServerPeer receiver = null;
            OperationResponse     response = null;

            switch (CurrentState)
            {
            case ClientPeerState.Connect:
            {
                if (operationRequest.OperationCode == (byte)ClientOperationCode.Login)
                {
                    receiver = Application.MasterLobby.SubServers.LoginServer;
                }
            }
            break;

            case ClientPeerState.Login:
            {
                if (operationRequest.OperationCode != (byte)ClientOperationCode.Character)
                {
                    break;
                }

                operationRequest.Parameters.Remove((byte)ParameterCode.Username);
                operationRequest.Parameters.Add((byte)ParameterCode.Username, this.LoginData.Username);

                receiver = Application.MasterLobby.SubServers.LoginServer;
            }
            break;

            case ClientPeerState.WorldEnter:
            {
                switch ((ClientOperationCode)operationRequest.OperationCode)
                {
                case ClientOperationCode.Chat:
                    receiver = Application.MasterLobby.SubServers.ChatServer;
                    break;

                case ClientOperationCode.Group:
                case ClientOperationCode.Social:
                    receiver = Application.MasterLobby.SubServers.SocialServer;
                    break;

                case ClientOperationCode.World:
                    receiver = WorldServer;
                    break;
                }
            }
            break;
            }

            if (receiver != null)
            {
                operationRequest.Parameters.Remove(0);
                operationRequest.Parameters.Add(0, ClientId);

                receiver.SendOperationRequest(operationRequest, sendParameters);
            }
            else
            {
                response = new OperationResponse(operationRequest.OperationCode)
                {
                    ReturnCode = (short)ResultCode.OperationNotAvailable
                };
                _logger.ErrorFormat("State={0} SessionId={1} OpCode={2}", CurrentState, ClientId, (ClientOperationCode)operationRequest.OperationCode);
            }

            if (response != null)
            {
                this.SendOperationResponse(response, new SendParameters());
            }
        }