private void PasswordCheckCallback(GamePlayer player, byte response) { if (response != 0x01) { return; } var newPassword = player.TempProperties.getProperty <string>(this, null); if (newPassword == null) { return; } player.TempProperties.removeProperty(this); player.Out.SendMessage("Your password has been changed.", eChatType.CT_Important, eChatLoc.CL_SystemWindow); player.Client.Account.Password = LoginRequestHandler.CryptPassword(newPassword); GameServer.Database.SaveObject(player.Client.Account); // Log change AuditMgr.AddAuditEntry(player, AuditType.Account, AuditSubtype.AccountPasswordChange, "", player.Name); if (log.IsInfoEnabled) { log.Info(player.Name + " (" + player.Client.Account.Name + ") changed password."); } }
/// <summary> /// 1126 support. Packet changed again from version 1125d /// Alot of test code i slapped together to get it to work, likely can be changed /// </summary> private void _HandlePacket1126(GameClient client, GSPacketIn packet) { byte charIndex = (byte)packet.ReadByte(); // character account location // some funkyness going on below here. Could use some safeguards to ensure a character is loaded correctly if (client.Player == null && client.Account.Characters != null && client.ClientState == GameClient.eClientState.CharScreen) { bool charFound = false; int realmOffset = charIndex - (client.Account.Realm * 10 - 10); int charSlot = (client.Account.Realm * 100) + realmOffset; for (int i = 0; i < client.Account.Characters.Length; i++) { if (client.Account.Characters[i] != null && client.Account.Characters[i].AccountSlot == charSlot) { charFound = true; client.LoadPlayer(i); break; } } if (!charFound) { client.Player = null; client.ActiveCharIndex = -1; } else { // Log character play AuditMgr.AddAuditEntry(client, AuditType.Character, AuditSubtype.CharacterLogin, "", client.Player.Name); } } client.Out.SendSessionID(); }
public void OnCommand(GameClient client, string[] args) { if (IsSpammingCommand(client.Player, "email")) { return; } if (args.Length == 1) { client.Out.SendMessage( "Usage: /email <address>", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } EmailSyntaxValidator emailsyntaxvalidator; // validate mail string EmailAddy = args[1]; emailsyntaxvalidator = new EmailSyntaxValidator(EmailAddy, true); if (!emailsyntaxvalidator.IsValid) { client.Out.SendMessage( "Please enter a valid e-mail address.", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } try { var obj = (GamePlayer)client.Player; if (obj != null) { string oldEmail = obj.Client.Account.Mail; obj.Client.Account.Mail = EmailAddy; // Set email GameServer.Database.SaveObject(obj.Client.Account); // Save account. // Log change AuditMgr.AddAuditEntry(client, AuditType.Account, AuditSubtype.AccountEmailChange, oldEmail, EmailAddy); client.Out.SendMessage( "Contact e-mail address set to " + obj.Client.Account.Mail + ". Thanks!", eChatType.CT_System, eChatLoc.CL_SystemWindow); } } catch (Exception) { client.Out.SendMessage( "Error - Usage: /email <address>", eChatType.CT_System, eChatLoc.CL_SystemWindow); } }
private void _HandlePacket1125d(GameClient client, GSPacketIn packet) { byte type = (byte)packet.ReadByte(); // changed from ushort low end packet.Skip(1); // unknown string charName = packet.ReadString(24); // down from 28, both need checking //TODO Character handling if (charName.Equals("noname")) { client.Out.SendLoginGranted(); client.Out.SendSessionID(); } else { // SH: Also load the player if client player is NOT null but their charnames differ!!! // only load player when on charscreen and player is not loaded yet // packet is sent on every region change (and twice after "play" was pressed) if (((client.Player == null && client.Account.Characters != null) || (client.Player != null && client.Player.Name.ToLower() != charName.ToLower())) && client.ClientState == GameClient.eClientState.CharScreen) { bool charFound = false; for (int i = 0; i < client.Account.Characters.Length; i++) { if (client.Account.Characters[i] != null && client.Account.Characters[i].Name == charName) { charFound = true; client.LoadPlayer(i); break; } } if (!charFound) { client.Player = null; client.ActiveCharIndex = -1; } else { // Log character play AuditMgr.AddAuditEntry(client, AuditType.Character, AuditSubtype.CharacterLogin, "", charName); } } // live actually sends the login granted packet, which sets the button activity states client.Out.SendLoginGranted(); client.Out.SendSessionID(); } }
public void HandlePacket(GameClient client, GSPacketIn packet) { packet.Skip(4); // Skip the first 4 bytes packet.Skip(1); string charName = packet.ReadString(28); // TODO Character handling if (charName.Equals("noname")) { client.Out.SendSessionID(); } else { // SH: Also load the player if client player is NOT null but their charnames differ!!! // only load player when on charscreen and player is not loaded yet // packet is sent on every region change (and twice after "play" was pressed) if (((client.Player == null && client.Account.Characters != null) || (client.Player != null && client.Player.Name.ToLower() != charName.ToLower())) && client.ClientState == GameClient.eClientState.CharScreen) { bool charFound = false; for (int i = 0; i < client.Account.Characters.Length; i++) { if (client.Account.Characters[i] != null && client.Account.Characters[i].Name == charName) { charFound = true; // Notify Character Selection Event, last hope to fix any bad data before Loading. GameEventMgr.Notify(DatabaseEvent.CharacterSelected, new CharacterEventArgs(client.Account.Characters[i], client)); client.LoadPlayer(i); break; } } if (charFound == false) { client.Player = null; client.ActiveCharIndex = -1; } else { // Log character play AuditMgr.AddAuditEntry(client, AuditType.Character, AuditSubtype.CharacterLogin, string.Empty, charName); } } client.Out.SendSessionID(); } }
public void HandlePacket(GameClient client, GSPacketIn packet) { byte charIndex = (byte)packet.ReadByte(); if (client.Player == null && client.Account.Characters != null && client.ClientState == GameClient.eClientState.CharScreen) { var charSlot = CalculateCharSlot(client, charIndex); var character = FindCharacter(client, charSlot); if (character != null) { AuditMgr.AddAuditEntry(client, AuditType.Character, AuditSubtype.CharacterLogin, "", character.Name); } else { client.Player = null; client.ActiveCharIndex = -1; } } client.Out.SendRegions(); }
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.Account.Language, "AdminCommands.Account.InvalidAccountName")); return; } } if (AccountName.Length < 4 || Password.Length < 4) { DisplayMessage(client, LanguageMgr.GetTranslation(client.Account.Language, "AdminCommands.Account.InvalidAccountNameOrPassword")); return; } Account account = GetAccount(AccountName); if (account != null) { DisplayMessage(client, LanguageMgr.GetTranslation(client.Account.Language, "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.Account.Language, "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.Account.Language, "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.Account.Language, "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.Account.Language, "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.Account.Language, "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.Account.Language, "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.Account.Language, "AdminCommands.Account.CharacterNotFound", charname)); return; } Account acc = GetAccount(accountname); if (acc == null) { DisplayMessage(client, LanguageMgr.GetTranslation(client.Account.Language, "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.Account.Language, "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.Account.Language, "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.Account.Language, "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.Account.Language, "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.Account.Language, "AdminCommands.Account.AccountNotFound", accountname)); return; } var banacc = GameServer.Database.SelectObjects <DBBannedAccount>("(`Type` = @TypeA OR `Type` = @TypeB) AND `Account` = @Account", new[] { new QueryParameter("@TypeA", "A"), new QueryParameter("@TypeB", "B"), new QueryParameter("@Account", accountname) }); if (banacc.Count == 0) { DisplayMessage(client, LanguageMgr.GetTranslation(client.Account.Language, "AdminCommands.Account.AccountNotFound", accountname)); return; } try { GameServer.Database.DeleteObject(banacc); } 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.Account.Language, "AdminCommands.Account.CharacterNotFound", CharName)); return; } string AccName = GetAccountName(Char.Name); DisplayMessage(client, LanguageMgr.GetTranslation(client.Account.Language, "AdminCommands.Account.AccNameForChar", Char.Name, AccName)); return; } #endregion AccountName } }
public static bool CheckForDeletedCharacter(string accountName, GameClient client, int slot) { int charSlot = slot; if (accountName.EndsWith("-S")) { charSlot = 100 + slot; } else if (accountName.EndsWith("-N")) { charSlot = 200 + slot; } else if (accountName.EndsWith("-H")) { charSlot = 300 + slot; } DOLCharacters[] allChars = client.Account.Characters; if (allChars != null) { foreach (DOLCharacters character in allChars.ToArray()) { if (character.AccountSlot == charSlot && client.ClientState == GameClient.eClientState.CharScreen) { if (log.IsWarnEnabled) { log.WarnFormat("DB Character Delete: Account {0}, Character: {1}, slot position: {2}, client slot {3}", accountName, character.Name, character.AccountSlot, slot); } var characterRealm = (eRealm)character.Realm; if (allChars.Length < client.ActiveCharIndex && client.ActiveCharIndex > -1 && allChars[client.ActiveCharIndex] == character) { client.ActiveCharIndex = -1; } GameEventMgr.Notify(DatabaseEvent.CharacterDeleted, null, new CharacterEventArgs(character, client)); if (Properties.BACKUP_DELETED_CHARACTERS) { var backupCharacter = new DOLCharactersBackup(character); backupCharacter.CustomParams.ForEach(param => GameServer.Database.AddObject(param)); GameServer.Database.AddObject(backupCharacter); if (log.IsWarnEnabled) { log.WarnFormat("DB Character {0} backed up to DOLCharactersBackup and no associated content deleted.", character.ObjectId); } } else { // delete associated data try { var objs = GameServer.Database.SelectObjects <InventoryItem>("`OwnerID` = @OwnerID", new QueryParameter("@OwnerID", character.ObjectId)); GameServer.Database.DeleteObject(objs); } catch (Exception e) { if (log.IsErrorEnabled) { log.ErrorFormat("Error deleting char items, char OID={0}, Exception:{1}", character.ObjectId, e); } } // delete quests try { var objs = GameServer.Database.SelectObjects <DBQuest>("`Character_ID` = @Character_ID", new QueryParameter("@Character_ID", character.ObjectId)); GameServer.Database.DeleteObject(objs); } catch (Exception e) { if (log.IsErrorEnabled) { log.ErrorFormat("Error deleting char quests, char OID={0}, Exception:{1}", character.ObjectId, e); } } // delete ML steps try { var objs = GameServer.Database.SelectObjects <DBCharacterXMasterLevel>("`Character_ID` = @Character_ID", new QueryParameter("@Character_ID", character.ObjectId)); GameServer.Database.DeleteObject(objs); } catch (Exception e) { if (log.IsErrorEnabled) { log.ErrorFormat("Error deleting char ml steps, char OID={0}, Exception:{1}", character.ObjectId, e); } } } string deletedChar = character.Name; GameServer.Database.DeleteObject(character); client.Account.Characters = null; client.Player = null; GameServer.Database.FillObjectRelations(client.Account); if (client.Account.Characters == null || client.Account.Characters.Length == 0) { if (log.IsInfoEnabled) { log.InfoFormat("Account {0} has no more chars. Realm reset!", client.Account.Name); } //Client has no more characters, so the client can choose the realm again! client.Account.Realm = 0; } GameServer.Database.SaveObject(client.Account); // Log deletion AuditMgr.AddAuditEntry(client, AuditType.Character, AuditSubtype.CharacterDelete, "", deletedChar); return(true); } } } return(false); }
private bool CreateCharacter(CreationCharacterData pdata, GameClient client, int accountSlot) { Account account = client.Account; var ch = new DOLCharacters(); ch.AccountName = account.Name; ch.Name = pdata.CharName; if (pdata.CustomMode == 0x01) { ch.EyeSize = (byte)pdata.EyeSize; ch.LipSize = (byte)pdata.LipSize; ch.EyeColor = (byte)pdata.EyeColor; ch.HairColor = (byte)pdata.HairColor; ch.FaceType = (byte)pdata.FaceType; ch.HairStyle = (byte)pdata.HairStyle; ch.MoodType = (byte)pdata.MoodType; ch.CustomisationStep = 2; // disable config button if (log.IsDebugEnabled) { log.Debug("Disable Config Button"); } } ch.Level = 1; // Set Realm and Class ch.Realm = pdata.Realm; ch.Class = pdata.Class; // Set Account Slot, Gender ch.AccountSlot = accountSlot + ch.Realm * 100; ch.Gender = pdata.Gender; // Set Race ch.Race = pdata.Race; ch.CreationModel = pdata.CreationModel; ch.CurrentModel = ch.CreationModel; ch.Region = pdata.Region; ch.Strength = pdata.Strength; ch.Dexterity = pdata.Dexterity; ch.Constitution = pdata.Constitution; ch.Quickness = pdata.Quickness; ch.Intelligence = pdata.Intelligence; ch.Piety = pdata.Piety; ch.Empathy = pdata.Empathy; ch.Charisma = pdata.Charisma; // defaults ch.CreationDate = DateTime.Now; ch.Endurance = 100; ch.MaxEndurance = 100; ch.Concentration = 100; ch.MaxSpeed = GamePlayer.PLAYER_BASE_SPEED; if (log.IsDebugEnabled) { log.DebugFormat("Creation {0} character, class:{1}, realm:{2}", client.Version, ch.Class, ch.Realm); } // Is class disabled ? int occurences = 0; List <string> disabled_classes = Properties.DISABLED_CLASSES.SplitCSV(true); occurences = (from j in disabled_classes where j == ch.Class.ToString() select j).Count(); if (occurences > 0 && (ePrivLevel)client.Account.PrivLevel == ePrivLevel.Player) { if (log.IsDebugEnabled) { log.DebugFormat("Client {0} tried to create a disabled classe: {1}", client.Account.Name, (eCharacterClass)ch.Class); } return(true); } // check if race disabled List <string> disabled_races = Properties.DISABLED_RACES.SplitCSV(true); occurences = (from j in disabled_races where j == ch.Race.ToString() select j).Count(); if (occurences > 0 && (ePrivLevel)client.Account.PrivLevel == ePrivLevel.Player) { if (log.IsDebugEnabled) { log.DebugFormat("Client {0} tried to create a disabled race: {1}", client.Account.Name, (eRace)ch.Race); } return(true); } // If sending invalid Class ID if (!Enum.IsDefined(typeof(eCharacterClass), (eCharacterClass)ch.Class)) { if (log.IsErrorEnabled) { log.ErrorFormat("{0} tried to create a character with wrong class ID: {1}, realm:{2}", client.Account.Name, ch.Class, ch.Realm); } if (ServerProperties.Properties.BAN_HACKERS) { client.BanAccount(string.Format("Autoban character create class: id:{0} realm:{1} name:{2} account:{3}", ch.Class, ch.Realm, ch.Name, account.Name)); client.Disconnect(); return(false); } return(true); } // check if client tried to create invalid char if (!IsCharacterValid(ch)) { if (log.IsWarnEnabled) { log.WarnFormat("{0} tried to create invalid character:\nchar name={1}, gender={2}, race={3}, realm={4}, class={5}, region={6}" + "\nstr={7}, con={8}, dex={9}, qui={10}, int={11}, pie={12}, emp={13}, chr={14}", ch.AccountName, ch.Name, ch.Gender, ch.Race, ch.Realm, ch.Class, ch.Region, ch.Strength, ch.Constitution, ch.Dexterity, ch.Quickness, ch.Intelligence, ch.Piety, ch.Empathy, ch.Charisma); } return(true); } //Save the character in the database GameServer.Database.AddObject(ch); // Fire the character creation event // This is Where Most Creation Script should take over to update any data they would like ! GameEventMgr.Notify(DatabaseEvent.CharacterCreated, null, new CharacterEventArgs(ch, client)); //write changes GameServer.Database.SaveObject(ch); // Log creation AuditMgr.AddAuditEntry(client, AuditType.Account, AuditSubtype.CharacterCreate, "", pdata.CharName); client.Account.Characters = null; if (log.IsInfoEnabled) { log.InfoFormat("Character {0} created on Account {1}!", pdata.CharName, account); } // Reload Account Relations GameServer.Database.FillObjectRelations(client.Account); return(true); }
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) { int packetVersion; 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: packetVersion = 168; break; default: packetVersion = 174; break; } packet.Skip(4); //Skip the first 4 bytes if (packetVersion == 174) { packet.Skip(1); } string charName = packet.ReadString(28); //TODO Character handling if (charName.Equals("noname")) { client.Out.SendSessionID(); } else { // SH: Also load the player if client player is NOT null but their charnames differ!!! // only load player when on charscreen and player is not loaded yet // packet is sent on every region change (and twice after "play" was pressed) if ( ( (client.Player == null && client.Account.Characters != null) || (client.Player != null && client.Player.Name.ToLower() != charName.ToLower()) ) && client.ClientState == GameClient.eClientState.CharScreen) { bool charFound = false; for (int i = 0; i < client.Account.Characters.Length; i++) { if (client.Account.Characters[i] != null && client.Account.Characters[i].Name == charName) { charFound = true; client.LoadPlayer(i); break; } } if (charFound == false) { client.Player = null; client.ActiveCharIndex = -1; } else { // Log character play AuditMgr.AddAuditEntry(client, AuditType.Character, AuditSubtype.CharacterLogin, "", charName); } } if (client.Player == null) { // client keeps sending the name of the deleted char even if new one was created, correct name only after "play" button pressed //client.Server.Error(new Exception("ERROR, active character not found!!! name="+charName)); } client.Out.SendSessionID(); } }
public void HandlePacket(GameClient client, GSPacketIn packet) { if (client.Version >= GameClient.eClientVersion.Version1126) { _HandlePacket1126(client, packet); return; } // 1125d support TODO this needs to be changed when a version greater than 1125d comes out if (client.Version >= GameClient.eClientVersion.Version1125) { _HandlePacket1125d(client, packet); return; } int packetVersion; 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: packetVersion = 168; break; default: packetVersion = 174; break; } packet.Skip(4); //Skip the first 4 bytes if (packetVersion == 174) { packet.Skip(1); } string charName = packet.ReadString(28); //TODO Character handling if (charName.Equals("noname")) { client.Out.SendSessionID(); } else { // SH: Also load the player if client player is NOT null but their charnames differ!!! // only load player when on charscreen and player is not loaded yet // packet is sent on every region change (and twice after "play" was pressed) if ( ( (client.Player == null && client.Account.Characters != null) || (client.Player != null && client.Player.Name.ToLower() != charName.ToLower()) ) && client.ClientState == GameClient.eClientState.CharScreen) { bool charFound = false; for (int i = 0; i < client.Account.Characters.Length; i++) { if (client.Account.Characters[i] != null && client.Account.Characters[i].Name == charName) { charFound = true; // Notify Character Selection Event, last hope to fix any bad data before Loading. GameEventMgr.Notify(DatabaseEvent.CharacterSelected, new CharacterEventArgs(client.Account.Characters[i], client)); client.LoadPlayer(i); break; } } if (charFound == false) { client.Player = null; client.ActiveCharIndex = -1; } else { // Log character play AuditMgr.AddAuditEntry(client, AuditType.Character, AuditSubtype.CharacterLogin, "", charName); } } client.Out.SendSessionID(); } }
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; if (client.Version >= GameClient.eClientVersion.Version1126) { // Read Login userName = packet.ReadIntPascalStringLowEndian(); // Read Password password = packet.ReadIntPascalStringLowEndian(); } else if (client.Version == GameClient.eClientVersion.Version1125) { // 1.125 // 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.ReadIntPascalStringLowEndian(); // Read Password password = packet.ReadIntPascalStringLowEndian(); } else { // 1.115c - 1.124 // 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.ReadShortPascalStringLowEndian(); // Read Password password = packet.ReadShortPascalStringLowEndian(); } // 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); } }
public void HandlePacket(GameClient client, GSPacketIn packet) { string charName = packet.ReadString(30); DOLCharacters[] chars = client.Account.Characters; if (chars == null) { return; } for (int i = 0; i < chars.Length; i++) { if (chars[i].Name.ToLower().Equals(charName.ToLower())) { if (client.ActiveCharIndex == i) { client.ActiveCharIndex = -1; } if (Log.IsInfoEnabled) { Log.Info(String.Format("IP {1} is Deleting character {0} from account {2}!", charName, client.TcpEndpoint, client.Account.Name)); } //Fire the deletion event before removing the char GameEventMgr.Notify(DatabaseEvent.CharacterDeleted, null, new CharacterEventArgs(chars[i], client)); //EventMgr.FireCharacterDeletion(chars[i]); // delete items try { var objs = GameServer.Database.SelectObjects <InventoryItem>("OwnerID = '" + GameServer.Database.Escape(chars[i].ObjectId) + "'"); foreach (InventoryItem item in objs) { GameServer.Database.DeleteObject(item); } // 2008-01-29 Kakuri - Obsolete //GameServer.Database.WriteDatabaseTable( typeof( InventoryItem ) ); } catch (Exception e) { if (Log.IsErrorEnabled) { Log.Error("Error deleting char items, char OID=" + chars[i].ObjectId, e); } } // delete quests try { var objs = GameServer.Database.SelectObjects <DBQuest>("Character_ID = '" + GameServer.Database.Escape(chars[i].ObjectId) + "'"); foreach (DBQuest quest in objs) { GameServer.Database.DeleteObject(quest); } // 2008-01-29 Kakuri - Obsolete //GameServer.Database.WriteDatabaseTable( typeof( DBQuest ) ); } catch (Exception e) { if (Log.IsErrorEnabled) { Log.Error("Error deleting char quests, char OID=" + chars[i].ObjectId, e); } } // delete ML steps try { var objs = GameServer.Database.SelectObjects <DBCharacterXMasterLevel>("Character_ID = '" + GameServer.Database.Escape(chars[i].ObjectId) + "'"); foreach (DBCharacterXMasterLevel mlstep in objs) { GameServer.Database.DeleteObject(mlstep); } // 2008-01-29 Kakuri - Obsolete //GameServer.Database.WriteDatabaseTable( typeof( DBCharacterXMasterLevel ) ); } catch (Exception e) { if (Log.IsErrorEnabled) { Log.Error("Error deleting char ml steps, char OID=" + chars[i].ObjectId, e); } } GameServer.Database.DeleteObject(chars[i]); // 2008-01-29 Kakuri - Obsolete //GameServer.Database.WriteDatabaseTable( typeof( Character ) ); client.Account.Characters = null; GameServer.Database.FillObjectRelations(client.Account); client.Player = null; if (client.Account.Characters == null || client.Account.Characters.Length == 0) { if (Log.IsInfoEnabled) { Log.Info(string.Format("Account {0} has no more chars. Realm reset!", client.Account.Name)); } //Client has no more characters, so the client can choose //the realm again! client.Account.Realm = 0; GameServer.Database.SaveObject(client.Account); // 2008-01-29 Kakuri - Obsolete //GameServer.Database.WriteDatabaseTable( typeof( Account ) ); } // Log deletion AuditMgr.AddAuditEntry(client, AuditType.Character, AuditSubtype.CharacterDelete, "", charName); break; } } }