public static async void HandleLoadingScreenNotify(LoadingScreenNotify loadingScreenNotify, CharacterSession session) { Log.Debug("Loading screen for map '{0}' {1}.", loadingScreenNotify.MapID, loadingScreenNotify.Showing ? "enabled" : "disabled"); if (loadingScreenNotify.Showing) { var worldServer = Manager.Redirect.GetWorldServer(loadingScreenNotify.MapID); if (worldServer != null) { NetHandler.SendConnectTo(session, worldServer.Address, worldServer.Port); // Suspend the current connection await session.Send(new SuspendComms { Serial = 0x14 }); } } }
public static async void AuthSessionHandler(AuthSession authSession, CharacterSession session) { var accountParts = authSession.Account.Split(new[] { '#' }); var authResult = AuthResult.Ok; if (accountParts.Length == 2) { var accountId = int.Parse(accountParts[0]); var gameIndex = byte.Parse(accountParts[1]); session.Account = DB.Auth.Single<Account>(a => a.Id == accountId); if (session.Account != null) session.GameAccount = session.Account.GameAccounts.SingleOrDefault(ga => ga.Index == gameIndex); if (session.GameAccount != null) session.Crypt = new WoWCrypt(session.GameAccount.SessionKey.ToByteArray()); else authResult = AuthResult.Failed; } session.Realm = DB.Auth.Single<Realm>(r => r.Id == authSession.RealmID); if (authSession.LoginServerType != (sbyte)LoginServerTypes.Battlenet || session.Realm == null) authResult = AuthResult.Reject; if (authResult == AuthResult.Ok) { var sha1 = new Sha1(); sha1.Process(authSession.Account); sha1.Process(0u); sha1.Process(authSession.LocalChallenge); sha1.Process(session.Challenge); sha1.Finish(session.GameAccount.SessionKey.ToByteArray(), 40); // Check the password digest. if (!sha1.Digest.Compare(authSession.Digest)) authResult = AuthResult.Failed; } var authResponse = new AuthResponse { Result = authResult, HasSuccessInfo = authResult == AuthResult.Ok, }; if (authResponse.HasSuccessInfo) { session.State = SessionState.Authenticated; var addonData = AddonHandler.GetAddonInfoData(session, authSession.AddonInfo, authSession.CompressedAddonInfoSize, authSession.UncompressedAddonInfoSize); if (addonData != null && addonData.Length != authSession.UncompressedAddonInfoSize) { Log.Error("Addon Info data size mismatch."); session.Dispose(); return; } authResponse.SuccessInfo.ActiveExpansionLevel = session.GameAccount.BoxLevel; authResponse.SuccessInfo.AccountExpansionLevel = session.GameAccount.BoxLevel; authResponse.SuccessInfo.AvailableRaces = Manager.GameAccount.GetAvailableRaces(session.GameAccount, session.Realm); authResponse.SuccessInfo.AvailableClasses = Manager.GameAccount.GetAvailableClasses(session.GameAccount, session.Realm); authResponse.SuccessInfo.Templates = Manager.GameAccount.GetAvailableCharacterTemplates(session.GameAccount, session.Realm); await session.Send(authResponse); AddonHandler.HandleAddonInfo(session, addonData); await session.Send(new TutorialFlags()); } else await session.Send(authResponse); }
public static async void HandleCreateCharacter(CreateCharacter createCharacter, CharacterSession session) { var createChar = new CreateChar { Code = CharCreateCode.InProgress }; if (!ClientDB.ChrRaces.Any(c => c.Id == createCharacter.RaceID) || !ClientDB.ChrClasses.Any(c => c.Id == createCharacter.ClassID)) createChar.Code = CharCreateCode.Failed; else if (!ClientDB.CharBaseInfo.Any(c => c.RaceId == createCharacter.RaceID && c.ClassId == createCharacter.ClassID)) createChar.Code = CharCreateCode.Failed; else if (DB.Character.Any<Character>(c => c.Name == createCharacter.Name)) createChar.Code = CharCreateCode.NameInUse; else if (createChar.Code == CharCreateCode.InProgress) { if (createCharacter.TemplateSetID != 0) { var accTemplate = session.GameAccount.GameAccountCharacterTemplates.Any(t => t.SetId == createCharacter.TemplateSetID); var realmTemplate = session.Realm.RealmCharacterTemplates.Any(t => t.SetId == createCharacter.TemplateSetID); if (accTemplate || realmTemplate) { // Not implemented = creation failed createChar.Code = CharCreateCode.Failed; } else createChar.Code = CharCreateCode.Failed; } else { var creationData = DB.Character.Single<CharacterCreationData>(d => d.Race == createCharacter.RaceID && d.Class == createCharacter.ClassID); if (creationData != null) { var newChar = new Character { Name = createCharacter.Name, GameAccountId = session.GameAccount.Id, RealmId = session.Realm.Id, Race = createCharacter.RaceID, Class = createCharacter.ClassID, Sex = createCharacter.SexID, Skin = createCharacter.SkinID, Face = createCharacter.FaceID, HairStyle = createCharacter.HairStyleID, HairColor = createCharacter.HairColorID, FacialHairStyle = createCharacter.FacialHairStyleID, Map = creationData.Map, X = creationData.X, Y = creationData.Y, Z = creationData.Z, O = creationData.O, CharacterFlags = CharacterFlags.Decline, FirstLogin = 1, ExperienceLevel = 1 }; if (DB.Character.Add(newChar)) { Manager.Character.LearnStartAbilities(newChar); Manager.Character.AddStartItems(newChar); createChar.Code = CharCreateCode.Success; } else createChar.Code = CharCreateCode.Success; } else createChar.Code = CharCreateCode.Failed; } } await session.Send(createChar); }
public static async void HandleEnumCharacters(EnumCharacters enumCharacters, CharacterSession session) { var charList = DB.Character.Where<Character>(c => c.GameAccountId == session.GameAccount.Id); var enumCharactersResult = new EnumCharactersResult(); charList.ForEach(c => { var character = new CharacterListEntry { Guid = new CharacterGuid { CreationBits = c.Guid, RealmId = (ushort)c.RealmId }, Name = c.Name, ListPosition = c.ListPosition, RaceID = c.Race, ClassID = c.Class, SexID = c.Sex, SkinID = c.Skin, FaceID = c.Face, HairStyle = c.HairStyle, HairColor = c.HairColor, FacialHairStyle = c.FacialHairStyle, ExperienceLevel = c.ExperienceLevel, ZoneID = (int)c.Zone, MapID = (int)c.Map, PreloadPos = new Vector3 { X = c.X, Y = c.Y, Z = c.Z }, GuildGUID = new GuildGuid { CreationBits = c.GuildGuid }, Flags = c.CharacterFlags, Flags2 = c.CustomizeFlags, Flags3 = c.Flags3, FirstLogin = c.FirstLogin == 1, PetCreatureDisplayID = c.PetCreatureDisplayId, PetExperienceLevel = c.PetLevel, PetCreatureFamilyID = c.PetCreatureFamily, }; if (c.CharacterItems != null) { for (var i = 0; i < character.InventoryItems.Length; i++) { foreach (var ci in c.CharacterItems) { Item item; if ((int)ci.Slot == i && ClientDB.Items.TryGetValue(ci.ItemId, out item) && ci.Equipped) { character.InventoryItems[i].DisplayID = (uint)item.DisplayId; character.InventoryItems[i].InvType = (byte)item.Slot; break; } } } } enumCharactersResult.Characters.Add(character); }); await session.Send(enumCharactersResult); }
public static async void HandlePlayerLogin(PlayerLogin playerLogin, CharacterSession session) { await session.Send(new CharacterLoginFailed { Code = CharLoginCode.NoWorld }); }
public static async void HandleGenerateRandomCharacterName(GenerateRandomCharacterName generateRandomCharacterName, CharacterSession session) { var rand = new Random(Environment.TickCount); var generateRandomCharacterNameResult = new GenerateRandomCharacterNameResult(); var names = ClientDB.NameGens.Where(n => n.RaceId == generateRandomCharacterName.Race && n.Sex == generateRandomCharacterName.Sex).Select(n => n.Name).ToList(); do { generateRandomCharacterNameResult.Name = names[rand.Next(names.Count)]; } while (DB.Character.Any<Character>(c => c.Name == generateRandomCharacterNameResult.Name)); generateRandomCharacterNameResult.Success = generateRandomCharacterNameResult.Name != ""; await session.Send(generateRandomCharacterNameResult); }
public static async void HandleCharDelete(CharDelete charDelete, CharacterSession session) { if (charDelete.Guid.CreationBits > 0 && charDelete.Guid.Type == GuidType.Player) { var deleteChar = new DeleteChar(); var guid = charDelete.Guid; var gameAccount = session.GameAccount; if (DB.Character.Delete<Character>(c => c.Guid == guid.Low && c.GameAccountId == gameAccount.Id)) deleteChar.Code = CharDeleteCode.Success; else deleteChar.Code = CharDeleteCode.Failed; await session.Send(deleteChar); } else session.Dispose(); }
public static async void SendConnectTo(CharacterSession session, string ip, ushort port, byte connection = 0) { var connectTo = new ConnectTo { Key = Manager.Redirect.CreateRedirectKey(session.GameAccount.Id), Serial = 0xE, Con = connection }; // Fail if (connectTo.Key == 0) { session.Dispose(); return; } var payloadData = new byte[0xFF]; var ipBytes = IPAddress.Parse(ip).GetAddressBytes(); // 0 - 15, Address, IPv6 not supported for now payloadData[0] = ipBytes[0]; payloadData[1] = ipBytes[1]; payloadData[2] = ipBytes[2]; payloadData[3] = ipBytes[3]; // 16 payloadData[16] = 0x01; // 17 - 20, adler32, changes with compression seed. // Let's use a static one for now payloadData[17] = 0x43; payloadData[18] = 0xfd; payloadData[19] = 0xb8; payloadData[20] = 0x22; // 21 payloadData[21] = 0x2A; var portBytes = BitConverter.GetBytes(port); // 22 - 23, Port payloadData[22] = portBytes[0]; payloadData[23] = portBytes[1]; var msg = "Blossom opens above\nSpines rising to the air\nArctium grows stronger\n\0\0\0\0"; // 24 - 94, Haiku Array.Copy(Encoding.ASCII.GetBytes(msg), 0, payloadData, 24, 71); // 94 - 125, static for now... Array.Copy(new byte[] { 0xD6, 0xAC, 0x21, 0xE6, 0xB2, 0x7B, 0x06, 0x3D, 0xA9, 0x9C, 0x09, 0x4B, 0xC7, 0x30, 0x48, 0x34, 0xD4, 0xF0, 0x55, 0x3B, 0x1B, 0x1D, 0xC9, 0x5B, 0xFD, 0x3C, 0xB9, 0x30, 0x9D, 0xF5, 0x40, 0xC0 }, 0, payloadData, 94, 32); // 126 - 233, 0 for now Array.Copy(new byte[108], 0, payloadData, 126, 108); // 234 - 253, ranodm for now Array.Copy(new byte[0].GenerateRandomKey(20), 0, payloadData, 234, 20); var dataOrder = new byte[payloadData.Length]; for (var i = 0; i < payloadData.Length; i++) dataOrder[i] = payloadData[ConnectTo.PayloadOrder[i]]; var encrypted = Manager.Redirect.Crypt.Encrypt(dataOrder); Array.Copy(encrypted, connectTo.Where, 0x100); await session.Send(connectTo); }
//! TODO Implement server side addon & banned addon handling public static async void HandleAddonInfo(CharacterSession session, byte[] addonData) { var addonInfo = new AddonInfo(); var addonDataReader = new Packet(addonData, 0); var addons = addonDataReader.Read<uint>(); for (var i = 0; i < addons; i++) { var addonName = addonDataReader.ReadString(); var addonInfoProvided = addonDataReader.Read<bool>(); var addonCRC = addonDataReader.Read<uint>(); var urlCRC = addonDataReader.Read<uint>(); Log.Debug($"AddonData: Name '{addonName}', Info Provided '{addonInfoProvided}', CRC '0x{addonCRC:X}', URL CRC '0x{urlCRC:X}'."); addonInfo.Addons.Add(new AddonInfoData { InfoProvided = addonInfoProvided, KeyProvided = true, KeyData = addonPublicKey }); } await session.Send(addonInfo); }