protected virtual OperationResponse HandleRegisterGameServerRequest(OperationRequest request)
        {
            var registerRequest = new RegisterGameServer(this.Protocol, request);
            if (registerRequest.IsValid == false)
            {
                string msg = registerRequest.GetErrorMessage();
                log.ErrorFormat("RegisterGameServer contract error: {0}", msg);

                return new OperationResponse(request.OperationCode) { DebugMessage = msg, ReturnCode = (short)ErrorCode.OperationInvalid };
            }

            IPAddress masterAddress = this.application.GetInternalMasterNodeIpAddress();
            var contract = new RegisterGameServerResponse { InternalAddress = masterAddress.GetAddressBytes() };

            // is master
            if (this.application.IsMaster)
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat(
                        "Received register request: Address={0}, UdpPort={1}, TcpPort={2}, WebSocketPort={3}, State={4}",
                        registerRequest.GameServerAddress,
                        registerRequest.UdpPort,
                        registerRequest.TcpPort,
                        registerRequest.WebSocketPort,
                        (ServerState)registerRequest.ServerState);
                }

                if (registerRequest.UdpPort.HasValue)
                {
                    this.UdpAddress = registerRequest.GameServerAddress + ":" + registerRequest.UdpPort;
                }

                if (registerRequest.TcpPort.HasValue)
                {
                    this.TcpAddress = registerRequest.GameServerAddress + ":" + registerRequest.TcpPort;
                }

                if (registerRequest.WebSocketPort.HasValue && registerRequest.WebSocketPort != 0)
                {
                    this.WebSocketAddress = registerRequest.GameServerAddress + ":" + registerRequest.WebSocketPort;
                }

                this.ServerId = registerRequest.ServerId;
                this.State = (ServerState)registerRequest.ServerState;

                this.Key = string.Format("{0}-{1}-{2}", registerRequest.GameServerAddress, registerRequest.UdpPort, registerRequest.TcpPort);

                this.application.GameServers.OnConnect(this);

                if (this.State == ServerState.Normal)
                {
                    this.application.LoadBalancer.TryAddServer(this, 0);
                }

                contract.AuthList = this.GetAuthlist();

                return new OperationResponse(request.OperationCode, contract);
            }

            return new OperationResponse(request.OperationCode, contract) { ReturnCode = (short)ErrorCode.RedirectRepeat, DebugMessage = "RedirectRepeat" };
        }
        protected virtual OperationResponse HandleRegisterGameServerRequest(OperationRequest request)
        {
            try
            {
                var registerRequest = new RegisterGameServer(this.Protocol, request);

                if (registerRequest.IsValid == false)
                {
                    string msg = registerRequest.GetErrorMessage();
                    log.ErrorFormat("RegisterGameServer contract error: {0}", msg);

                    return new OperationResponse(request.OperationCode) { DebugMessage = msg, ReturnCode = (short)ErrorCode.OperationInvalid };
                }

                IPAddress masterAddress = this.application.GetInternalMasterNodeIpAddress();
                var contract = new RegisterGameServerResponse { InternalAddress = masterAddress.GetAddressBytes() };

                // is master
                if (!this.application.IsMaster)
                {
                    return new OperationResponse(request.OperationCode, contract)
                               {
                                   ReturnCode = (short)ErrorCode.RedirectRepeat,
                                   DebugMessage = "RedirectRepeat"
                               };
                }

                if (log.IsDebugEnabled)
                {
                    log.DebugFormat(
                        "Received register request: Address={0}, UdpPort={1}, TcpPort={2}, WebSocketPort={3}, SecureWebSocketPort={4}, HttpPort={5}, State={6}, Hostname={7}, IPv6Address={8}",
                        registerRequest.GameServerAddress,
                        registerRequest.UdpPort,
                        registerRequest.TcpPort,
                        registerRequest.WebSocketPort,
                        registerRequest.SecureWebSocketPort,
                        registerRequest.HttpPort,
                        (ServerState)registerRequest.ServerState,
                        registerRequest.GameServerHostName,
                        registerRequest.GameServerAddressIPv6);
                }

                this.Address = registerRequest.GameServerAddress;
                if (registerRequest.GameServerAddressIPv6 != null
                    && IPAddress.Parse(registerRequest.GameServerAddressIPv6).AddressFamily == AddressFamily.InterNetworkV6)
                {
                    this.AddressIPv6 = string.Format("[{0}]", IPAddress.Parse(registerRequest.GameServerAddressIPv6));
                }
                this.Hostname = registerRequest.GameServerHostName;

                if (registerRequest.UdpPort.HasValue)
                {
                    this.UdpAddress = string.IsNullOrEmpty(this.Address) ? null : string.Format("{0}:{1}", this.Address, registerRequest.UdpPort);
                    this.UdpAddressIPv6 = string.IsNullOrEmpty(this.AddressIPv6) ? null : string.Format("{0}:{1}", this.AddressIPv6, registerRequest.UdpPort);
                    this.UdpHostname = string.IsNullOrEmpty(this.Hostname) ? null : string.Format("{0}:{1}", this.Hostname, registerRequest.UdpPort);
                }

                if (registerRequest.TcpPort.HasValue)
                {
                    this.TcpAddress = string.IsNullOrEmpty(this.Address) ? null : string.Format("{0}:{1}", this.Address, registerRequest.TcpPort);
                    this.TcpAddressIPv6 = string.IsNullOrEmpty(this.AddressIPv6) ? null : string.Format("{0}:{1}", this.AddressIPv6, registerRequest.TcpPort);
                    this.TcpHostname = string.IsNullOrEmpty(this.Hostname) ? null : string.Format("{0}:{1}", this.Hostname, registerRequest.TcpPort);
                }

                if (registerRequest.WebSocketPort.HasValue && registerRequest.WebSocketPort != 0)
                {
                    this.WebSocketAddress = string.IsNullOrEmpty(this.Address)
                                                ? null
                                                : string.Format("ws://{0}:{1}", this.Address, registerRequest.WebSocketPort);

                    this.WebSocketAddressIPv6 = string.IsNullOrEmpty(this.AddressIPv6)
                                                    ? null
                                                    : string.Format("ws://{0}:{1}", this.AddressIPv6, registerRequest.WebSocketPort);

                    this.WebSocketHostname = string.IsNullOrEmpty(this.Hostname)
                                                 ? null
                                                 : string.Format("ws://{0}:{1}", this.Hostname, registerRequest.WebSocketPort);
                }

                if (registerRequest.HttpPort.HasValue && registerRequest.HttpPort != 0)
                {
                    this.HttpAddress = string.IsNullOrEmpty(this.Address)
                                           ? null
                                           : string.Format("http://{0}:{1}{2}", this.Address, registerRequest.HttpPort, registerRequest.HttpPath);

                    this.HttpAddressIPv6 = string.IsNullOrEmpty(this.AddressIPv6)
                                               ? null
                                               : string.Format("http://{0}:{1}{2}", this.AddressIPv6, registerRequest.HttpPort, registerRequest.HttpPath);

                    this.HttpHostname = string.IsNullOrEmpty(this.Hostname)
                                            ? null
                                            : string.Format("http://{0}:{1}{2}", this.Hostname, registerRequest.HttpPort, registerRequest.HttpPath);
                }

                // HTTP & WebSockets require a proper domain name (especially for certificate validation on secure Websocket & HTTPS connections):
                if (string.IsNullOrEmpty(this.Hostname))
                {
                    log.WarnFormat("HTTPs & Secure WebSockets not supported. GameServer {0} does not have a public hostname.", this.Address);
                }
                else
                {
                    if (registerRequest.SecureWebSocketPort.HasValue && registerRequest.SecureWebSocketPort != 0)
                    {
                        this.SecureWebSocketHostname = string.Format("wss://{0}:{1}", this.Hostname, registerRequest.SecureWebSocketPort);
                    }

                    if (registerRequest.SecureHttpPort.HasValue && registerRequest.SecureHttpPort != 0)
                    {
                        this.SecureHttpHostname = string.Format("https://{0}:{1}{2}", this.Hostname, registerRequest.SecureHttpPort, registerRequest.HttpPath);
                    }
                }

                this.ServerId = new Guid(registerRequest.ServerId);
                this.State = (ServerState)registerRequest.ServerState;

                this.Key = string.Format("{0}-{1}-{2}", registerRequest.GameServerAddress, registerRequest.UdpPort, registerRequest.TcpPort);

                log.Debug(
                    string.Format(
                        "Registered GameServerAddress={0} GameServerAddressIPv6={1}" + " TcpAddress={2} TcpAddressIPv6={3} UdpAddress={4} UdpAddressIPv6={5}"
                        + " WebSocketAddress={6} WebSocketAddressIPv6={7} HttpAddress={8} HttpAddressIPv6={9}"
                        + " SecureWebSocketAddress={10} SecureHttpAddress={11}",
                        this.Address,
                        this.AddressIPv6,
                        this.TcpAddress,
                        this.TcpAddressIPv6,
                        this.UdpAddress,
                        this.UdpAddressIPv6,
                        this.WebSocketAddress,
                        this.WebSocketAddressIPv6,
                        this.HttpAddress,
                        this.HttpAddressIPv6,
                        this.SecureWebSocketHostname,
                        this.SecureHttpHostname));

                this.application.GameServers.OnConnect(this);

                if (this.State == ServerState.Normal)
                {
                    this.application.LoadBalancer.TryAddServer(this, 0);
                }

                contract.AuthList = this.GetAuthlist();

                return new OperationResponse(request.OperationCode, contract);
            }
            catch (Exception e)
            {
                log.Error(e);
                return new OperationResponse(request.OperationCode) { DebugMessage = e.Message, ReturnCode = (short)ErrorCode.InternalServerError };
            }
        }