public void HandlePacket(GameClient client, GSPacketIn packet) { string ipAddress = client.TcpEndpointAddress; packet.Skip(2); //Skip the client_type byte var major = (byte)packet.ReadByte(); var minor = (byte)packet.ReadByte(); var build = (byte)packet.ReadByte(); string 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); } string userName = packet.ReadString(20); /* 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.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) { 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; } bool goodname = true; foreach (char c in userName.ToLower()) { if ((c < '0' || c > '9') && (c < 'a' || c > 'z') && client.Account.PrivLevel == (uint)ePrivLevel.Player) { goodname = false; break; } } // Yes! Stoping! if (!goodname) { if (Log.IsInfoEnabled) Log.Info("Invalid symbols in account name \"" + userName + "\" found!"); client.Out.SendLoginDenied(eLoginError.AccountInvalid); 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.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.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.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.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.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.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.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.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 OnCommand(GameClient client, string[] args) { if (args.Length < 2) { DisplaySyntax(client); return; } switch (args[1].ToLower()) { #region Create case "create": { if (args.Length < 4) { DisplaySyntax(client); return; } string AccountName = args[2].ToLower(); string Password = args[3]; foreach (char c in AccountName.ToCharArray()) { if ((c < '0' || c > '9') && (c < 'a' || c > 'z')) { DisplayMessage(client, LanguageMgr.GetTranslation(client, "AdminCommands.Account.InvalidAccountName")); return; } } if (AccountName.Length < 4 || Password.Length < 4) { DisplayMessage(client, LanguageMgr.GetTranslation(client, "AdminCommands.Account.InvalidAccountNameOrPassword")); return; } Account account = GetAccount(AccountName); if (account != null) { DisplayMessage(client, LanguageMgr.GetTranslation(client, "AdminCommands.Account.AccountNameAlreadyRegistered")); return; } account = new Account(); account.Name = AccountName; account.Password = PacketHandler.Client.v168.LoginRequestHandler.CryptPassword(Password); account.PrivLevel = (uint)ePrivLevel.Player; account.Realm = (int)eRealm.None; account.CreationDate = DateTime.Now; account.Language = ServerProperties.Properties.SERV_LANGUAGE; GameServer.Database.AddObject(account); DisplayMessage(client, LanguageMgr.GetTranslation(client, "AdminCommands.Account.AccountCreated")); } break; #endregion Create #region ChangePassword case "changepassword": { if (args.Length < 4) { DisplaySyntax(client); return; } string accountname = args[2]; string newpass = args[3]; Account acc = GetAccount(accountname); if (acc == null) { DisplayMessage(client, LanguageMgr.GetTranslation(client, "AdminCommands.Account.AccountNotFound", accountname)); return; } acc.Password = LoginRequestHandler.CryptPassword(newpass); GameServer.Database.SaveObject(acc); // Log change AuditMgr.AddAuditEntry(client, AuditType.Account, AuditSubtype.AccountPasswordChange, "", (client.Player != null ? client.Player.Name : "")); } break; #endregion ChangePassword #region Delete case "delete": { if (args.Length < 3) { DisplaySyntax(client); return; } string AccountName = args[2]; Account acc = GetAccount(AccountName); if (acc == null) { DisplayMessage(client, LanguageMgr.GetTranslation(client, "AdminCommands.Account.AccountNotFound", AccountName)); return; } KickAccount(acc); GameServer.Database.DeleteObject(acc); // Log change AuditMgr.AddAuditEntry(client, AuditType.Account, AuditSubtype.AccountDelete, "acct=" + AccountName, (client.Player != null ? client.Player.Name : "")); DisplayMessage(client, LanguageMgr.GetTranslation(client, "AdminCommands.Account.AccountDeleted", acc.Name)); return; } #endregion Delete #region DeleteCharacter case "deletecharacter": { if (args.Length < 3) { DisplaySyntax(client); return; } string charname = args[2]; DOLCharacters cha = GetCharacter(charname); if (cha == null) { DisplayMessage(client, LanguageMgr.GetTranslation(client, "AdminCommands.Account.CharacterNotFound", charname)); return; } KickCharacter(cha); GameServer.Database.DeleteObject(cha); // Log change AuditMgr.AddAuditEntry(client, AuditType.Character, AuditSubtype.CharacterDelete, "char=" + charname, (client.Player != null ? client.Player.Name : "")); DisplayMessage(client, LanguageMgr.GetTranslation(client, "AdminCommands.Account.CharacterDeleted", cha.Name)); return; } #endregion DeleteCharacter #region MoveCharacter case "movecharacter": { if (args.Length < 4) { DisplaySyntax(client); return; } string charname = args[2]; string accountname = args[3]; DOLCharacters cha = GetCharacter(charname); if (cha == null) { DisplayMessage(client, LanguageMgr.GetTranslation(client, "AdminCommands.Account.CharacterNotFound", charname)); return; } Account acc = GetAccount(accountname); if (acc == null) { DisplayMessage(client, LanguageMgr.GetTranslation(client, "AdminCommands.Account.AccountNotFound", accountname)); return; } int firstAccountSlot = 0; switch ((eRealm)cha.Realm) { case eRealm.Albion: firstAccountSlot = 1 * 8; break; case eRealm.Midgard: firstAccountSlot = 2 * 8; break; case eRealm.Hibernia: firstAccountSlot = 3 * 8; break; default: DisplayMessage(client, LanguageMgr.GetTranslation(client, "AdminCommands.Account.CharNotFromValidRealm")); return; } int freeslot = 0; for (freeslot = firstAccountSlot; freeslot < firstAccountSlot + 8; freeslot++) { bool found = false; foreach (DOLCharacters ch in acc.Characters) { if (ch.Realm == cha.Realm && ch.AccountSlot == freeslot) { found = true; break; } } if (!found) break; } if (freeslot == 0) { DisplayMessage(client, LanguageMgr.GetTranslation(client, "AdminCommands.Account.AccountHasNoFreeSlots", accountname)); return; } GameClient playingclient = WorldMgr.GetClientByPlayerName(cha.Name, true, false); if (playingclient != null) { playingclient.Out.SendPlayerQuit(true); playingclient.Disconnect(); } cha.AccountName = acc.Name; cha.AccountSlot = freeslot; GameServer.Database.SaveObject(cha); DisplayMessage(client, LanguageMgr.GetTranslation(client, "AdminCommands.Account.CharacterMovedToAccount", cha.Name, acc.Name)); return; } #endregion MoveCharacter #region Status case "status": { if (args.Length < 4) { DisplaySyntax(client); return; } string accountname = args[2]; Account acc = GetAccount(accountname); if (acc == null) { DisplayMessage(client, LanguageMgr.GetTranslation(client, "AdminCommands.Account.AccountNotFound", accountname)); return; } int status = -1; try { status = Convert.ToInt32(args[3]); } catch (Exception) { DisplaySyntax(client); return; } if (status >= 0 && status < 256) { acc.Status = status; GameServer.Database.SaveObject(acc); DisplayMessage(client, "Account " + acc.Name + " Status is now set to : " + acc.Status); } else DisplaySyntax(client); return; } #endregion Status #region Unban case "unban": { if (args.Length < 3) { DisplaySyntax(client); return; } string accountname = args[2]; Account acc = GetAccount(accountname); if (acc == null) { DisplayMessage(client, LanguageMgr.GetTranslation(client, "AdminCommands.Account.AccountNotFound", accountname)); return; } var banacc = GameServer.Database.SelectObjects<DBBannedAccount>("((Type='A' OR Type='B') AND Account ='" + GameServer.Database.Escape(accountname) + "')"); if (banacc.Count == 0) { DisplayMessage(client, LanguageMgr.GetTranslation(client, "AdminCommands.Account.AccountNotFound", accountname)); return; } try { foreach (DBBannedAccount banned in banacc) GameServer.Database.DeleteObject(banned); } catch (Exception) { DisplaySyntax(client); return; } DisplayMessage(client, "Account " + accountname + " unbanned!"); return; } #endregion Unban #region AccountName case "accountname": { if (args.Length < 3) { DisplaySyntax(client); return; } string CharName = args[2]; DOLCharacters Char = GetCharacter(CharName); if (Char == null) { DisplayMessage(client, LanguageMgr.GetTranslation(client, "AdminCommands.Account.CharacterNotFound", CharName)); return; } string AccName = GetAccountName(Char.Name); DisplayMessage(client, LanguageMgr.GetTranslation(client, "AdminCommands.Account.AccNameForChar", Char.Name, AccName)); return; } #endregion AccountName } }
/// <summary> /// Kicks an active playing account from the server /// </summary> /// <param name="acc">The account</param> private void KickAccount(Account acc) { GameClient playingclient = WorldMgr.GetClientByAccountName(acc.Name, true); if (playingclient != null) { playingclient.Out.SendPlayerQuit(true); playingclient.Disconnect(); } }
/// <summary> /// Constructs a new event argument class for the /// account events /// </summary> /// <param name="account"></param> public AccountEventArgs(Account account) { m_account = account; }