예제 #1
0
		public void HandlePacket(GameClient client, GSPacketIn packet)
		{
			if (client == null)
				return;

			string ipAddress = client.TcpEndpointAddress;

			byte major;
			byte minor;
			byte build;
			string password;
			string userName;
			
			/// <summary>
			/// Packet Format Change above 1.115
			/// </summary>
			
			if (client.Version < GameClient.eClientVersion.Version1115)
			{
				packet.Skip(2); //Skip the client_type byte
				
				major = (byte)packet.ReadByte();
				minor = (byte)packet.ReadByte();
				build = (byte)packet.ReadByte();
				password = packet.ReadString(20);
				
				
				bool v174;
				//the logger detection we had is no longer working
				//bool loggerUsing = false;
				switch (client.Version)
				{
					case GameClient.eClientVersion.Version168:
					case GameClient.eClientVersion.Version169:
					case GameClient.eClientVersion.Version170:
					case GameClient.eClientVersion.Version171:
					case GameClient.eClientVersion.Version172:
					case GameClient.eClientVersion.Version173:
						v174 = false;
						break;
					default:
						v174 = true;
						break;
				}
	
				if (v174)
				{
					packet.Skip(11);
				}
				else
				{
					packet.Skip(7);
				}
	
				uint c2 = packet.ReadInt();
				uint c3 = packet.ReadInt();
				uint c4 = packet.ReadInt();
	
				if (v174)
				{
					packet.Skip(27);
				}
				else
				{
					packet.Skip(31);
				}
	
				userName = packet.ReadString(20);
			}
			else
			{
				// 1.115c+
				
				// client type
				packet.Skip(1);
				
				//version
				major = (byte)packet.ReadByte();
				minor = (byte)packet.ReadByte();
				build = (byte)packet.ReadByte();
				
				// revision
				packet.Skip(1);
				// build
				packet.Skip(2);
				
				// Read Login
				userName = packet.ReadLowEndianShortPascalString();

				// Read Password
				password = packet.ReadLowEndianShortPascalString();
			}


			
			/*
			if (c2 == 0 && c3 == 0x05000000 && c4 == 0xF4000000)
			{
				loggerUsing = true;
				Log.Warn("logger detected (" + username + ")");
			}*/

			// check server status
			if (GameServer.Instance.ServerStatus == eGameServerStatus.GSS_Closed)
            {
                client.IsConnected = false;
				client.Out.SendLoginDenied(eLoginError.GameCurrentlyClosed);
				Log.Info(ipAddress + " disconnected because game is closed!");
				GameServer.Instance.Disconnect(client);

				return;
			}

			// check connection allowed with serverrules
			try
			{
				if (!GameServer.ServerRules.IsAllowedToConnect(client, userName))
				{
					if (Log.IsInfoEnabled)
						Log.Info(ipAddress + " disconnected because IsAllowedToConnect returned false!");

					GameServer.Instance.Disconnect(client);

					return;
				}
			}
			catch (Exception e)
			{
				if (Log.IsErrorEnabled)
					Log.Error("Error shutting down Client after IsAllowedToConnect failed!", e);
			}

			// Handle connection
			EnterLock(userName);

			try
			{
				Account playerAccount;
				// Make sure that client won't quit
				lock (client)
				{
					GameClient.eClientState state = client.ClientState;
					if (state != GameClient.eClientState.NotConnected)
					{
						Log.DebugFormat("wrong client state on connect {0} {1}", userName, state.ToString());
						return;
					}

					if (Log.IsInfoEnabled)
						Log.Info(string.Format("({0})User {1} logging on! ({2} type:{3} add:{4})", ipAddress, userName, client.Version,
											   (client.ClientType), client.ClientAddons.ToString("G")));
					// check client already connected
					GameClient findclient = WorldMgr.GetClientByAccountName(userName, true);
					if (findclient != null)
					{
						client.IsConnected = false;
						                            
						if (findclient.ClientState == GameClient.eClientState.Connecting)
						{
							if (Log.IsInfoEnabled) Log.Info("User is already connecting, ignored.");

							client.Out.SendLoginDenied(eLoginError.AccountAlreadyLoggedIn);

							return;
						} // in login

						if (findclient.ClientState == GameClient.eClientState.Linkdead)
						{
							if (Log.IsInfoEnabled) Log.Info("User is still being logged out from linkdeath!");

							client.Out.SendLoginDenied(eLoginError.AccountIsInLogoutProcedure);
						}
						else
						{
							if (Log.IsInfoEnabled) Log.Info("User already logged in!");

							client.Out.SendLoginDenied(eLoginError.AccountAlreadyLoggedIn);
						}

						GameServer.Instance.Disconnect(client);

						return;
					}
					
					Regex goodName = new Regex("^[a-zA-Z0-9]*$");
					if (!goodName.IsMatch(userName) || string.IsNullOrWhiteSpace(userName))
					{
						if (Log.IsInfoEnabled)
							Log.Info("Invalid symbols in account name \"" + userName + "\" found!");

						client.IsConnected = false;
						if (client != null && client.Out != null)
						{
							client.Out.SendLoginDenied(eLoginError.AccountInvalid);
						}
						else
						{
							Log.Warn("Client or Client.Out null on invalid name failure.  Disconnecting.");
						}

						GameServer.Instance.Disconnect(client);

						return;
					}
					else
					{
						playerAccount = GameServer.Database.FindObjectByKey<Account>(userName);

						client.PingTime = DateTime.Now.Ticks;

						if (playerAccount == null)
						{
							//check autocreate ...

							if (GameServer.Instance.Configuration.AutoAccountCreation && Properties.ALLOW_AUTO_ACCOUNT_CREATION)
							{
								// autocreate account
								if (string.IsNullOrEmpty(password))
                                {
                                    client.IsConnected = false;
									client.Out.SendLoginDenied(eLoginError.AccountInvalid);
									GameServer.Instance.Disconnect(client);

									if (Log.IsInfoEnabled)
										Log.Info("Account creation failed, no password set for Account: " + userName);

									return;
								}

								// check for account bombing
								TimeSpan ts;
								IList<Account> allAccByIp = GameServer.Database.SelectObjects<Account>("`LastLoginIP` = @LastLoginIP", new QueryParameter("@LastLoginIP", ipAddress));
								int totalacc = 0;
								foreach (Account ac in allAccByIp)
								{
									ts = DateTime.Now - ac.CreationDate;
									if (ts.TotalMinutes < Properties.TIME_BETWEEN_ACCOUNT_CREATION_SAMEIP && totalacc > 1)
									{
										Log.Warn("Account creation: too many from same IP within set minutes - " + userName + " : " + ipAddress);

                                        client.IsConnected = false;
										client.Out.SendLoginDenied(eLoginError.PersonalAccountIsOutOfTime);
										GameServer.Instance.Disconnect(client);

										return;
									}

									totalacc++;
								}
								if (totalacc >= Properties.TOTAL_ACCOUNTS_ALLOWED_SAMEIP)
								{
									Log.Warn("Account creation: too many accounts created from same ip - " + userName + " : " + ipAddress);

                                    client.IsConnected = false;
									client.Out.SendLoginDenied(eLoginError.AccountNoAccessThisGame);
									GameServer.Instance.Disconnect(client);

									return;
								}

								// per timeslice - for preventing account bombing via different ip
								if (Properties.TIME_BETWEEN_ACCOUNT_CREATION > 0)
								{
									ts = DateTime.Now - m_lastAccountCreateTime;
									if (ts.TotalMinutes < Properties.TIME_BETWEEN_ACCOUNT_CREATION)
									{
										Log.Warn("Account creation: time between account creation too small - " + userName + " : " + ipAddress);

                                        client.IsConnected = false;
										client.Out.SendLoginDenied(eLoginError.PersonalAccountIsOutOfTime);
										GameServer.Instance.Disconnect(client);

										return;
									}
								}

								m_lastAccountCreateTime = DateTime.Now;

								playerAccount = new Account();
								playerAccount.Name = userName;
								playerAccount.Password = CryptPassword(password);
								playerAccount.Realm = 0;
								playerAccount.CreationDate = DateTime.Now;
								playerAccount.LastLogin = DateTime.Now;
								playerAccount.LastLoginIP = ipAddress;
								playerAccount.LastClientVersion = ((int)client.Version).ToString();
								playerAccount.Language = Properties.SERV_LANGUAGE;
								playerAccount.PrivLevel = 1;

								if (Log.IsInfoEnabled)
									Log.Info("New account created: " + userName);

								GameServer.Database.AddObject(playerAccount);

								// Log account creation
								AuditMgr.AddAuditEntry(client, AuditType.Account, AuditSubtype.AccountCreate, "", userName);
							}
							else
							{
								if (Log.IsInfoEnabled)
									Log.Info("No such account found and autocreation deactivated!");

                                client.IsConnected = false;
								client.Out.SendLoginDenied(eLoginError.AccountNotFound);
								GameServer.Instance.Disconnect(client);

								return;
							}
						}
						else
						{
							// check password
							if (!playerAccount.Password.StartsWith("##"))
							{
								playerAccount.Password = CryptPassword(playerAccount.Password);
							}

							if (!CryptPassword(password).Equals(playerAccount.Password))
							{
								if (Log.IsInfoEnabled)
									Log.Info("(" + client.TcpEndpoint + ") Wrong password!");

                                client.IsConnected = false;
								client.Out.SendLoginDenied(eLoginError.WrongPassword);

								// Log failure
								AuditMgr.AddAuditEntry(client, AuditType.Account, AuditSubtype.AccountFailedLogin, "", userName);

								GameServer.Instance.Disconnect(client);

								return;
							}

							// save player infos
							playerAccount.LastLogin = DateTime.Now;
							playerAccount.LastLoginIP = ipAddress;
							playerAccount.LastClientVersion = ((int)client.Version).ToString();
							if (string.IsNullOrEmpty(playerAccount.Language))
							{
								playerAccount.Language = Properties.SERV_LANGUAGE;
							}

							GameServer.Database.SaveObject(playerAccount);
						}
					}

					//Save the account table
					client.Account = playerAccount;

					// create session ID here to disable double login bug
					if (WorldMgr.CreateSessionID(client) < 0)
					{
						if (Log.IsInfoEnabled) Log.InfoFormat("Too many clients connected, denied login to " + playerAccount.Name);

                        client.IsConnected = false;
						client.Out.SendLoginDenied(eLoginError.TooManyPlayersLoggedIn);
						client.Disconnect();

						return;
					}

					client.Out.SendLoginGranted();
					client.ClientState = GameClient.eClientState.Connecting;

					// Log entry
					AuditMgr.AddAuditEntry(client, AuditType.Account, AuditSubtype.AccountSuccessfulLogin, "", userName);
				}
			}
			catch (DatabaseException e)
			{
				if (Log.IsErrorEnabled) Log.Error("LoginRequestHandler", e);

                client.IsConnected = false;
				client.Out.SendLoginDenied(eLoginError.CannotAccessUserAccount);
				GameServer.Instance.Disconnect(client);
			}
			catch (Exception e)
			{
				if (Log.IsErrorEnabled)
					Log.Error("LoginRequestHandler", e);

				client.Out.SendLoginDenied(eLoginError.CannotAccessUserAccount);
				GameServer.Instance.Disconnect(client);
			}
			finally
			{
				ExitLock(userName);
			}
		}
예제 #2
0
        public void HandlePacket(GameClient client, GSPacketIn packet)
        {
            if (client == null)
            {
                return;
            }

            string ipAddress = client.TcpEndpointAddress;

            byte   major;
            byte   minor;
            byte   build;
            string password;
            string userName;

            /// <summary>
            /// Packet Format Change above 1.115
            /// </summary>

            if (client.Version < GameClient.eClientVersion.Version1115)
            {
                packet.Skip(2);                 //Skip the client_type byte

                major    = (byte)packet.ReadByte();
                minor    = (byte)packet.ReadByte();
                build    = (byte)packet.ReadByte();
                password = packet.ReadString(20);


                bool v174;
                //the logger detection we had is no longer working
                //bool loggerUsing = false;
                switch (client.Version)
                {
                case GameClient.eClientVersion.Version168:
                case GameClient.eClientVersion.Version169:
                case GameClient.eClientVersion.Version170:
                case GameClient.eClientVersion.Version171:
                case GameClient.eClientVersion.Version172:
                case GameClient.eClientVersion.Version173:
                    v174 = false;
                    break;

                default:
                    v174 = true;
                    break;
                }

                if (v174)
                {
                    packet.Skip(11);
                }
                else
                {
                    packet.Skip(7);
                }

                uint c2 = packet.ReadInt();
                uint c3 = packet.ReadInt();
                uint c4 = packet.ReadInt();

                if (v174)
                {
                    packet.Skip(27);
                }
                else
                {
                    packet.Skip(31);
                }

                userName = packet.ReadString(20);
            }
            else
            {
                // 1.115c+

                // client type
                packet.Skip(1);

                //version
                major = (byte)packet.ReadByte();
                minor = (byte)packet.ReadByte();
                build = (byte)packet.ReadByte();

                // revision
                packet.Skip(1);
                // build
                packet.Skip(2);

                // Read Login
                userName = packet.ReadLowEndianShortPascalString();

                // Read Password
                password = packet.ReadLowEndianShortPascalString();
            }



            /*
             * if (c2 == 0 && c3 == 0x05000000 && c4 == 0xF4000000)
             * {
             *      loggerUsing = true;
             *      Log.Warn("logger detected (" + username + ")");
             * }*/

            // check server status
            if (GameServer.Instance.ServerStatus == eGameServerStatus.GSS_Closed)
            {
                client.IsConnected = false;
                client.Out.SendLoginDenied(eLoginError.GameCurrentlyClosed);
                Log.Info(ipAddress + " disconnected because game is closed!");
                GameServer.Instance.Disconnect(client);

                return;
            }

            // check connection allowed with serverrules
            try
            {
                if (!GameServer.ServerRules.IsAllowedToConnect(client, userName))
                {
                    if (Log.IsInfoEnabled)
                    {
                        Log.Info(ipAddress + " disconnected because IsAllowedToConnect returned false!");
                    }

                    GameServer.Instance.Disconnect(client);

                    return;
                }
            }
            catch (Exception e)
            {
                if (Log.IsErrorEnabled)
                {
                    Log.Error("Error shutting down Client after IsAllowedToConnect failed!", e);
                }
            }

            // Handle connection
            EnterLock(userName);

            try
            {
                Account playerAccount;
                // Make sure that client won't quit
                lock (client)
                {
                    GameClient.eClientState state = client.ClientState;
                    if (state != GameClient.eClientState.NotConnected)
                    {
                        Log.DebugFormat("wrong client state on connect {0} {1}", userName, state.ToString());
                        return;
                    }

                    if (Log.IsInfoEnabled)
                    {
                        Log.Info(string.Format("({0})User {1} logging on! ({2} type:{3} add:{4})", ipAddress, userName, client.Version,
                                               (client.ClientType), client.ClientAddons.ToString("G")));
                    }
                    // check client already connected
                    GameClient findclient = WorldMgr.GetClientByAccountName(userName, true);
                    if (findclient != null)
                    {
                        client.IsConnected = false;

                        if (findclient.ClientState == GameClient.eClientState.Connecting)
                        {
                            if (Log.IsInfoEnabled)
                            {
                                Log.Info("User is already connecting, ignored.");
                            }

                            client.Out.SendLoginDenied(eLoginError.AccountAlreadyLoggedIn);

                            return;
                        }                         // in login

                        if (findclient.ClientState == GameClient.eClientState.Linkdead)
                        {
                            if (Log.IsInfoEnabled)
                            {
                                Log.Info("User is still being logged out from linkdeath!");
                            }

                            client.Out.SendLoginDenied(eLoginError.AccountIsInLogoutProcedure);
                        }
                        else
                        {
                            if (Log.IsInfoEnabled)
                            {
                                Log.Info("User already logged in!");
                            }

                            client.Out.SendLoginDenied(eLoginError.AccountAlreadyLoggedIn);
                        }

                        GameServer.Instance.Disconnect(client);

                        return;
                    }

                    Regex goodName = new Regex("^[a-zA-Z0-9]*$");
                    if (!goodName.IsMatch(userName) || string.IsNullOrWhiteSpace(userName))
                    {
                        if (Log.IsInfoEnabled)
                        {
                            Log.Info("Invalid symbols in account name \"" + userName + "\" found!");
                        }

                        client.IsConnected = false;
                        if (client != null && client.Out != null)
                        {
                            client.Out.SendLoginDenied(eLoginError.AccountInvalid);
                        }
                        else
                        {
                            Log.Warn("Client or Client.Out null on invalid name failure.  Disconnecting.");
                        }

                        GameServer.Instance.Disconnect(client);

                        return;
                    }
                    else
                    {
                        playerAccount = GameServer.Database.FindObjectByKey <Account>(userName);

                        client.PingTime = DateTime.Now.Ticks;

                        if (playerAccount == null)
                        {
                            //check autocreate ...

                            if (GameServer.Instance.Configuration.AutoAccountCreation && Properties.ALLOW_AUTO_ACCOUNT_CREATION)
                            {
                                // autocreate account
                                if (string.IsNullOrEmpty(password))
                                {
                                    client.IsConnected = false;
                                    client.Out.SendLoginDenied(eLoginError.AccountInvalid);
                                    GameServer.Instance.Disconnect(client);

                                    if (Log.IsInfoEnabled)
                                    {
                                        Log.Info("Account creation failed, no password set for Account: " + userName);
                                    }

                                    return;
                                }

                                // check for account bombing
                                TimeSpan        ts;
                                IList <Account> allAccByIp = GameServer.Database.SelectObjects <Account>("LastLoginIP = '" + ipAddress + "'");
                                int             totalacc   = 0;
                                foreach (Account ac in allAccByIp)
                                {
                                    ts = DateTime.Now - ac.CreationDate;
                                    if (ts.TotalMinutes < Properties.TIME_BETWEEN_ACCOUNT_CREATION_SAMEIP && totalacc > 1)
                                    {
                                        Log.Warn("Account creation: too many from same IP within set minutes - " + userName + " : " + ipAddress);

                                        client.IsConnected = false;
                                        client.Out.SendLoginDenied(eLoginError.PersonalAccountIsOutOfTime);
                                        GameServer.Instance.Disconnect(client);

                                        return;
                                    }

                                    totalacc++;
                                }
                                if (totalacc >= Properties.TOTAL_ACCOUNTS_ALLOWED_SAMEIP)
                                {
                                    Log.Warn("Account creation: too many accounts created from same ip - " + userName + " : " + ipAddress);

                                    client.IsConnected = false;
                                    client.Out.SendLoginDenied(eLoginError.AccountNoAccessThisGame);
                                    GameServer.Instance.Disconnect(client);

                                    return;
                                }

                                // per timeslice - for preventing account bombing via different ip
                                if (Properties.TIME_BETWEEN_ACCOUNT_CREATION > 0)
                                {
                                    ts = DateTime.Now - m_lastAccountCreateTime;
                                    if (ts.TotalMinutes < Properties.TIME_BETWEEN_ACCOUNT_CREATION)
                                    {
                                        Log.Warn("Account creation: time between account creation too small - " + userName + " : " + ipAddress);

                                        client.IsConnected = false;
                                        client.Out.SendLoginDenied(eLoginError.PersonalAccountIsOutOfTime);
                                        GameServer.Instance.Disconnect(client);

                                        return;
                                    }
                                }

                                m_lastAccountCreateTime = DateTime.Now;

                                playerAccount                   = new Account();
                                playerAccount.Name              = userName;
                                playerAccount.Password          = CryptPassword(password);
                                playerAccount.Realm             = 0;
                                playerAccount.CreationDate      = DateTime.Now;
                                playerAccount.LastLogin         = DateTime.Now;
                                playerAccount.LastLoginIP       = ipAddress;
                                playerAccount.LastClientVersion = ((int)client.Version).ToString();
                                playerAccount.Language          = Properties.SERV_LANGUAGE;
                                playerAccount.PrivLevel         = 1;

                                if (Log.IsInfoEnabled)
                                {
                                    Log.Info("New account created: " + userName);
                                }

                                GameServer.Database.AddObject(playerAccount);

                                // Log account creation
                                AuditMgr.AddAuditEntry(client, AuditType.Account, AuditSubtype.AccountCreate, "", userName);
                            }
                            else
                            {
                                if (Log.IsInfoEnabled)
                                {
                                    Log.Info("No such account found and autocreation deactivated!");
                                }

                                client.IsConnected = false;
                                client.Out.SendLoginDenied(eLoginError.AccountNotFound);
                                GameServer.Instance.Disconnect(client);

                                return;
                            }
                        }
                        else
                        {
                            // check password
                            if (!playerAccount.Password.StartsWith("##"))
                            {
                                playerAccount.Password = CryptPassword(playerAccount.Password);
                            }

                            if (!CryptPassword(password).Equals(playerAccount.Password))
                            {
                                if (Log.IsInfoEnabled)
                                {
                                    Log.Info("(" + client.TcpEndpoint + ") Wrong password!");
                                }

                                client.IsConnected = false;
                                client.Out.SendLoginDenied(eLoginError.WrongPassword);

                                // Log failure
                                AuditMgr.AddAuditEntry(client, AuditType.Account, AuditSubtype.AccountFailedLogin, "", userName);

                                GameServer.Instance.Disconnect(client);

                                return;
                            }

                            // save player infos
                            playerAccount.LastLogin         = DateTime.Now;
                            playerAccount.LastLoginIP       = ipAddress;
                            playerAccount.LastClientVersion = ((int)client.Version).ToString();
                            if (string.IsNullOrEmpty(playerAccount.Language))
                            {
                                playerAccount.Language = Properties.SERV_LANGUAGE;
                            }

                            GameServer.Database.SaveObject(playerAccount);
                        }
                    }

                    //Save the account table
                    client.Account = playerAccount;

                    // create session ID here to disable double login bug
                    if (WorldMgr.CreateSessionID(client) < 0)
                    {
                        if (Log.IsInfoEnabled)
                        {
                            Log.InfoFormat("Too many clients connected, denied login to " + playerAccount.Name);
                        }

                        client.IsConnected = false;
                        client.Out.SendLoginDenied(eLoginError.TooManyPlayersLoggedIn);
                        client.Disconnect();

                        return;
                    }

                    client.Out.SendLoginGranted();
                    client.ClientState = GameClient.eClientState.Connecting;

                    // Log entry
                    AuditMgr.AddAuditEntry(client, AuditType.Account, AuditSubtype.AccountSuccessfulLogin, "", userName);
                }
            }
            catch (DatabaseException e)
            {
                if (Log.IsErrorEnabled)
                {
                    Log.Error("LoginRequestHandler", e);
                }

                client.IsConnected = false;
                client.Out.SendLoginDenied(eLoginError.CannotAccessUserAccount);
                GameServer.Instance.Disconnect(client);
            }
            catch (Exception e)
            {
                if (Log.IsErrorEnabled)
                {
                    Log.Error("LoginRequestHandler", e);
                }

                client.Out.SendLoginDenied(eLoginError.CannotAccessUserAccount);
                GameServer.Instance.Disconnect(client);
            }
            finally
            {
                ExitLock(userName);
            }
        }
예제 #3
0
        public void HandlePacket(GameClient client, GSPacketIn packet)
        {
            if (client == null)
            {
                return;
            }

            string ipAddress = client.TcpEndpointAddress;

            string password;
            string userName;

            /// <summary>
            /// Packet Format Change above 1.115
            /// </summary>

            // 1.115c+

            // client type
            packet.Skip(1);

            // version
            packet.ReadByte(); // major
            packet.ReadByte(); // minor
            packet.ReadByte(); // build

            // revision
            packet.Skip(1);

            // build
            packet.Skip(2);

            // Read Login
            userName = packet.ReadLowEndianShortPascalString();

            // Read Password
            password = packet.ReadLowEndianShortPascalString();


            // check server status
            if (GameServer.Instance.ServerStatus == eGameServerStatus.GSS_Closed)
            {
                client.IsConnected = false;
                client.Out.SendLoginDenied(eLoginError.GameCurrentlyClosed);
                Log.Info(ipAddress + " disconnected because game is closed!");
                GameServer.Instance.Disconnect(client);

                return;
            }

            // check connection allowed with serverrules
            try
            {
                if (!GameServer.ServerRules.IsAllowedToConnect(client, userName))
                {
                    if (Log.IsInfoEnabled)
                    {
                        Log.Info($"{ipAddress} disconnected because IsAllowedToConnect returned false!");
                    }

                    GameServer.Instance.Disconnect(client);

                    return;
                }
            }
            catch (Exception e)
            {
                if (Log.IsErrorEnabled)
                {
                    Log.Error("Error shutting down Client after IsAllowedToConnect failed!", e);
                }
            }

            // Handle connection
            EnterLock(userName);

            try
            {
                // Make sure that client won't quit
                lock (client)
                {
                    GameClient.eClientState state = client.ClientState;
                    if (state != GameClient.eClientState.NotConnected)
                    {
                        Log.Debug($"wrong client state on connect {userName} {state}");
                        return;
                    }

                    if (Log.IsInfoEnabled)
                    {
                        Log.Info($"({ipAddress})User {userName} logging on! ({client.Version} type:{client.ClientType} add:{client.ClientAddons:G})");
                    }

                    // check client already connected
                    GameClient findclient = WorldMgr.GetClientByAccountName(userName, true);
                    if (findclient != null)
                    {
                        client.IsConnected = false;

                        if (findclient.ClientState == GameClient.eClientState.Connecting)
                        {
                            if (Log.IsInfoEnabled)
                            {
                                Log.Info("User is already connecting, ignored.");
                            }

                            client.Out.SendLoginDenied(eLoginError.AccountAlreadyLoggedIn);

                            return;
                        } // in login

                        if (findclient.ClientState == GameClient.eClientState.Linkdead)
                        {
                            if (Log.IsInfoEnabled)
                            {
                                Log.Info("User is still being logged out from linkdeath!");
                            }

                            client.Out.SendLoginDenied(eLoginError.AccountIsInLogoutProcedure);
                        }
                        else
                        {
                            if (Log.IsInfoEnabled)
                            {
                                Log.Info("User already logged in!");
                            }

                            client.Out.SendLoginDenied(eLoginError.AccountAlreadyLoggedIn);
                        }

                        GameServer.Instance.Disconnect(client);

                        return;
                    }

                    Regex   goodName = new Regex("^[a-zA-Z0-9]*$");
                    Account playerAccount;
                    if (!goodName.IsMatch(userName) || string.IsNullOrWhiteSpace(userName))
                    {
                        if (Log.IsInfoEnabled)
                        {
                            Log.Info($"Invalid symbols in account name \"{userName}\" found!");
                        }

                        client.IsConnected = false;
                        if (client.Out != null)
                        {
                            client.Out.SendLoginDenied(eLoginError.AccountInvalid);
                        }
                        else
                        {
                            Log.Warn("Client or Client.Out null on invalid name failure.  Disconnecting.");
                        }

                        GameServer.Instance.Disconnect(client);

                        return;
                    }
                    else
                    {
                        playerAccount = GameServer.Database.FindObjectByKey <Account>(userName);

                        client.PingTime = DateTime.Now.Ticks;

                        if (playerAccount == null)
                        {
                            // check autocreate ...
                            if (GameServer.Instance.Configuration.AutoAccountCreation && Properties.ALLOW_AUTO_ACCOUNT_CREATION)
                            {
                                // autocreate account
                                if (string.IsNullOrEmpty(password))
                                {
                                    client.IsConnected = false;
                                    client.Out.SendLoginDenied(eLoginError.AccountInvalid);
                                    GameServer.Instance.Disconnect(client);

                                    if (Log.IsInfoEnabled)
                                    {
                                        Log.Info($"Account creation failed, no password set for Account: {userName}");
                                    }

                                    return;
                                }

                                // check for account bombing
                                TimeSpan        ts;
                                IList <Account> allAccByIp = GameServer.Database.SelectObjects <Account>("`LastLoginIP` = @LastLoginIP", new QueryParameter("@LastLoginIP", ipAddress));
                                int             totalacc   = 0;
                                foreach (Account ac in allAccByIp)
                                {
                                    ts = DateTime.Now - ac.CreationDate;
                                    if (ts.TotalMinutes < Properties.TIME_BETWEEN_ACCOUNT_CREATION_SAMEIP && totalacc > 1)
                                    {
                                        Log.Warn($"Account creation: too many from same IP within set minutes - {userName} : {ipAddress}");

                                        client.IsConnected = false;
                                        client.Out.SendLoginDenied(eLoginError.PersonalAccountIsOutOfTime);
                                        GameServer.Instance.Disconnect(client);

                                        return;
                                    }

                                    totalacc++;
                                }

                                if (totalacc >= Properties.TOTAL_ACCOUNTS_ALLOWED_SAMEIP)
                                {
                                    Log.Warn($"Account creation: too many accounts created from same ip - {userName} : {ipAddress}");

                                    client.IsConnected = false;
                                    client.Out.SendLoginDenied(eLoginError.AccountNoAccessThisGame);
                                    GameServer.Instance.Disconnect(client);

                                    return;
                                }

                                // per timeslice - for preventing account bombing via different ip
                                if (Properties.TIME_BETWEEN_ACCOUNT_CREATION > 0)
                                {
                                    ts = DateTime.Now - _lastAccountCreateTime;
                                    if (ts.TotalMinutes < Properties.TIME_BETWEEN_ACCOUNT_CREATION)
                                    {
                                        Log.Warn($"Account creation: time between account creation too small - {userName} : {ipAddress}");

                                        client.IsConnected = false;
                                        client.Out.SendLoginDenied(eLoginError.PersonalAccountIsOutOfTime);
                                        GameServer.Instance.Disconnect(client);

                                        return;
                                    }
                                }

                                _lastAccountCreateTime = DateTime.Now;

                                playerAccount = new Account
                                {
                                    Name              = userName,
                                    Password          = CryptPassword(password),
                                    Realm             = 0,
                                    CreationDate      = DateTime.Now,
                                    LastLogin         = DateTime.Now,
                                    LastLoginIP       = ipAddress,
                                    LastClientVersion = ((int)client.Version).ToString(),
                                    Language          = Properties.SERV_LANGUAGE,
                                    PrivLevel         = 1
                                };

                                if (Log.IsInfoEnabled)
                                {
                                    Log.Info($"New account created: {userName}");
                                }

                                GameServer.Database.AddObject(playerAccount);

                                // Log account creation
                                AuditMgr.AddAuditEntry(client, AuditType.Account, AuditSubtype.AccountCreate, string.Empty, userName);
                            }
                            else
                            {
                                if (Log.IsInfoEnabled)
                                {
                                    Log.Info("No such account found and autocreation deactivated!");
                                }

                                client.IsConnected = false;
                                client.Out.SendLoginDenied(eLoginError.AccountNotFound);
                                GameServer.Instance.Disconnect(client);

                                return;
                            }
                        }
                        else
                        {
                            // check password
                            if (!playerAccount.Password.StartsWith("##"))
                            {
                                playerAccount.Password = CryptPassword(playerAccount.Password);
                            }

                            if (!CryptPassword(password).Equals(playerAccount.Password))
                            {
                                if (Log.IsInfoEnabled)
                                {
                                    Log.Info($"({client.TcpEndpoint}) Wrong password!");
                                }

                                client.IsConnected = false;
                                client.Out.SendLoginDenied(eLoginError.WrongPassword);

                                // Log failure
                                AuditMgr.AddAuditEntry(client, AuditType.Account, AuditSubtype.AccountFailedLogin, string.Empty, userName);

                                GameServer.Instance.Disconnect(client);

                                return;
                            }

                            // save player infos
                            playerAccount.LastLogin         = DateTime.Now;
                            playerAccount.LastLoginIP       = ipAddress;
                            playerAccount.LastClientVersion = ((int)client.Version).ToString();
                            if (string.IsNullOrEmpty(playerAccount.Language))
                            {
                                playerAccount.Language = Properties.SERV_LANGUAGE;
                            }

                            GameServer.Database.SaveObject(playerAccount);
                        }
                    }

                    // Save the account table
                    client.Account = playerAccount;

                    // create session ID here to disable double login bug
                    if (WorldMgr.CreateSessionID(client) < 0)
                    {
                        if (Log.IsInfoEnabled)
                        {
                            Log.InfoFormat("Too many clients connected, denied login to {0}", playerAccount.Name);
                        }

                        client.IsConnected = false;
                        client.Out.SendLoginDenied(eLoginError.TooManyPlayersLoggedIn);
                        client.Disconnect();

                        return;
                    }

                    client.Out.SendLoginGranted();
                    client.ClientState = GameClient.eClientState.Connecting;

                    // Log entry
                    AuditMgr.AddAuditEntry(client, AuditType.Account, AuditSubtype.AccountSuccessfulLogin, string.Empty, userName);
                }
            }
            catch (DatabaseException e)
            {
                if (Log.IsErrorEnabled)
                {
                    Log.Error("LoginRequestHandler", e);
                }

                client.IsConnected = false;
                client.Out.SendLoginDenied(eLoginError.CannotAccessUserAccount);
                GameServer.Instance.Disconnect(client);
            }
            catch (Exception e)
            {
                if (Log.IsErrorEnabled)
                {
                    Log.Error("LoginRequestHandler", e);
                }

                client.Out.SendLoginDenied(eLoginError.CannotAccessUserAccount);
                GameServer.Instance.Disconnect(client);
            }
            finally
            {
                ExitLock(userName);
            }
        }