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 };
            }
        }
        protected virtual void Register()
        {
            var contract = new RegisterGameServer
                {
                    GameServerAddress = GameApplication.Instance.PublicIpAddress.ToString(),

                    UdpPort = GameServerSettings.Default.RelayPortUdp == 0 ? this.application.GamingUdpPort : GameServerSettings.Default.RelayPortUdp + this.application.GetCurrentNodeId() - 1,
                    TcpPort = GameServerSettings.Default.RelayPortTcp == 0 ? this.application.GamingTcpPort : GameServerSettings.Default.RelayPortTcp + this.application.GetCurrentNodeId() - 1,
                    WebSocketPort = GameServerSettings.Default.RelayPortWebSocket == 0 ? this.application.GamingWebSocketPort : GameServerSettings.Default.RelayPortWebSocket + this.application.GetCurrentNodeId() - 1,
                    ServerId = GameApplication.ServerId,
                    ServerState = (int)this.application.WorkloadController.ServerState
                };

            if (log.IsInfoEnabled)
            {
                log.InfoFormat(
                    "Registering game server with address {0}, TCP {1}, UDP {2}, WebSocket {3}, ServerID {4}",
                    contract.GameServerAddress,
                    contract.TcpPort,
                    contract.UdpPort,
                    contract.WebSocketPort,
                    contract.ServerId);
            }

            var request = new OperationRequest((byte)OperationCode.RegisterGameServer, contract);
            this.SendOperationRequest(request, new SendParameters());
        }
        protected virtual void Register()
        {
            var contract = new RegisterGameServer
                {
                    GameServerAddress = this.application.PublicIpAddress.ToString(),
                    GameServerHostName = GameServerSettings.Default.PublicHostName,

                    UdpPort = GameServerSettings.Default.RelayPortUdp == 0 ? this.application.GamingUdpPort : GameServerSettings.Default.RelayPortUdp + this.application.GetCurrentNodeId() - 1,
                    TcpPort = GameServerSettings.Default.RelayPortTcp == 0 ? this.application.GamingTcpPort : GameServerSettings.Default.RelayPortTcp + this.application.GetCurrentNodeId() - 1,
                    WebSocketPort = GameServerSettings.Default.RelayPortWebSocket == 0 ? this.application.GamingWebSocketPort : GameServerSettings.Default.RelayPortWebSocket + this.application.GetCurrentNodeId() - 1,
                    SecureWebSocketPort = GameServerSettings.Default.RelayPortSecureWebSocket == 0 ? this.application.GamingSecureWebSocketPort : GameServerSettings.Default.RelayPortSecureWebSocket  + this.application.GetCurrentNodeId() - 1,
                    HttpPort = GameServerSettings.Default.RelayPortHttp == 0 ? this.application.GamingHttpPort : GameServerSettings.Default.RelayPortHttp + this.application.GetCurrentNodeId() - 1,
                    SecureHttpPort = this.application.GamingHttpsPort,
                    HttpPath = this.application.GamingHttpPath,
                    ServerId = this.application.ServerId.ToString(),
                    ServerState = (int)this.application.WorkloadController.ServerState
                };

            if (this.application.PublicIpAddressIPv6 != null)
            {
                contract.GameServerAddressIPv6 = this.application.PublicIpAddressIPv6.ToString();
            }

            if (log.IsInfoEnabled)
            {
                log.InfoFormat(
                    "Registering game server with address {0}, TCP {1}, UDP {2}, WebSocket {3}, Secure WebSocket {4}, HTTP {5}, ServerID {6}, Hostname {7}, IPv6Address {8}",
                    contract.GameServerAddress,
                    contract.TcpPort,
                    contract.UdpPort,
                    contract.WebSocketPort,
                    contract.SecureWebSocketPort,
                    contract.HttpPort,
                    contract.ServerId,
                    contract.GameServerHostName,
                    contract.GameServerAddressIPv6);
            }

            var request = new OperationRequest((byte)OperationCode.RegisterGameServer, contract);
            this.SendOperationRequest(request, new SendParameters());
        }