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); } }
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); } }
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); } }