public static void HandleSelectRealm(WorldSession session, ClientSelectRealm selectRealm) { ServerInfo server = ServerManager.Servers.SingleOrDefault(s => s.Model.Id == selectRealm.RealmId); if (server == null) { throw new InvalidPacketValueException(); } // clicking back or selecting the current realm also triggers this packet, client crashes if we don't ignore it if (server.Model.Id == WorldServer.RealmId) { return; } byte[] sessionKey = RandomProvider.GetBytes(16u); session.EnqueueEvent(new TaskEvent(AuthDatabase.UpdateAccountSessionKey(session.Account, sessionKey), () => { session.EnqueueMessageEncrypted(new ServerNewRealm { SessionKey = sessionKey, GatewayData = new ServerNewRealm.Gateway { Address = server.Address, Port = server.Model.Port }, RealmName = server.Model.Name, Type = (RealmType)server.Model.Type }); })); }
public static void HandlePlayerInfoRequest(WorldSession session, ClientPlayerInfoRequest request) { session.EnqueueEvent(new TaskGenericEvent <Character>(CharacterDatabase.GetCharacterById(request.Identity.CharacterId), character => { if (character == null) { throw new InvalidPacketValueException(); } session.EnqueueMessageEncrypted(new ServerPlayerInfoFullResponse { BaseData = new ServerPlayerInfoFullResponse.Base { ResultCode = 0, Identity = new TargetPlayerIdentity { RealmId = WorldServer.RealmId, CharacterId = character.Id }, Name = character.Name, Faction = (Faction)character.FactionId }, IsClassPathSet = true, Path = (Path)character.ActivePath, Class = (Class)character.Class, Level = character.Level, IsLastLoggedOnInDaysSet = false, LastLoggedInDays = -1f }); })); }
public static void HandleItemUseDecor(WorldSession session, ClientItemUseDecor itemUseDecor) { Item item = session.Player.Inventory.GetItem(itemUseDecor.ItemGuid); if (item == null) { throw new InvalidPacketValueException(); } HousingDecorInfoEntry entry = GameTableManager.HousingDecorInfo.GetEntry(item.Entry.HousingDecorInfoId); if (entry == null) { throw new InvalidPacketValueException(); } Task <Residence> task = ResidenceManager.GetResidence(session.Player.Name); session.EnqueueEvent(new TaskGenericEvent <Residence>(task, residence => { if (residence == null) { residence = ResidenceManager.CreateResidence(session.Player); } if (session.Player.Inventory.ItemUse(item)) { residence.DecorCreate(entry); } })); }
public static void HandleHousingVisit(WorldSession session, ClientHousingVisit housingVisit) { if (!(session.Player.Map is ResidenceMap)) { throw new InvalidPacketValueException(); } if (!session.Player.CanTeleport()) { return; } Task <Residence> residenceTask; if (housingVisit.TargetResidenceName != "") { residenceTask = ResidenceManager.Instance.GetResidence(housingVisit.TargetResidenceName); } else if (housingVisit.TargetResidence.ResidenceId != 0ul) { residenceTask = ResidenceManager.Instance.GetResidence(housingVisit.TargetResidence.ResidenceId); } else { throw new NotImplementedException(); } session.EnqueueEvent(new TaskGenericEvent <Residence>(residenceTask, residence => { if (residence == null) { // TODO: show error return; } switch (residence.PrivacyLevel) { case ResidencePrivacyLevel.Private: { // TODO: show error return; } // TODO: check if player is either a neighbour or roommate case ResidencePrivacyLevel.NeighborsOnly: break; case ResidencePrivacyLevel.RoommatesOnly: break; } // teleport player to correct residence instance ResidenceEntrance entrance = ResidenceManager.Instance.GetResidenceEntrance(residence); session.Player.TeleportTo(entrance.Entry, entrance.Position, 0u, residence.Id); })); }
public static void HandleCharacterSelect(WorldSession session, ClientCharacterSelect characterSelect) { Character character = session.Characters.SingleOrDefault(c => c.Id == characterSelect.CharacterId); if (character == null) { session.EnqueueMessageEncrypted(new ServerCharacterSelectFail { Result = CharacterSelectResult.Failed }); return; } session.Player = new Player(session, character); WorldEntry entry = GameTableManager.World.GetEntry(character.WorldId); if (entry == null) { throw new ArgumentOutOfRangeException(); } switch (entry.Type) { // housing map case 5: { // characters logging in to a housing map are returned to their own residence session.EnqueueEvent(new TaskGenericEvent <Residence>(ResidenceManager.GetResidence(session.Player.Name), residence => { if (residence == null) { residence = ResidenceManager.CreateResidence(session.Player); } ResidenceEntrance entrance = ResidenceManager.GetResidenceEntrance(residence); var mapInfo = new MapInfo(entrance.Entry, 0u, residence.Id); MapManager.AddToMap(session.Player, mapInfo, entrance.Position); })); break; } default: { var mapInfo = new MapInfo(entry); var vector3 = new Vector3(character.LocationX, character.LocationY, character.LocationZ); MapManager.AddToMap(session.Player, mapInfo, vector3); break; } } }
public static void HandleHelloRealm(WorldSession session, ClientHelloRealm helloRealm) { // prevent packets from being processed until asynchronous account select task is complete session.CanProcessPackets = false; session.EnqueueEvent(new TaskGenericEvent <Account>(AuthDatabase.GetAccountAsync(helloRealm.Email, helloRealm.SessionKey), account => { if (account == null) { throw new InvalidPacketValueException($"Failed to find account, Id:{helloRealm.AccountId}, Email:{helloRealm.Email}, SessionKey:{helloRealm.SessionKey}!"); } session.Initialise(account); session.SetEncryptionKey(helloRealm.SessionKey); session.CanProcessPackets = true; })); }
public static void HandleSelectRealm(WorldSession session, ClientSelectRealm selectRealm) { ServerInfo server = ServerManager.Instance.Servers.SingleOrDefault(s => s.Model.Id == selectRealm.RealmId); if (server == null) { throw new InvalidPacketValueException(); } // clicking back or selecting the current realm also triggers this packet, client crashes if we don't ignore it if (server.Model.Id == WorldServer.RealmId) { return; } // TODO: Return proper error packet if server is not online if (!server.IsOnline) { session.EnqueueMessageEncrypted(new ServerForceKick()); return; } byte[] sessionKeyBytes = RandomProvider.GetBytes(16u); string sessionKeyString = BitConverter.ToString(sessionKeyBytes).Replace("-", ""); session.EnqueueEvent(new TaskEvent(DatabaseManager.Instance.AuthDatabase.UpdateAccountSessionKey(session.Account, sessionKeyString), () => { session.EnqueueMessageEncrypted(new ServerNewRealm { SessionKey = sessionKeyBytes, GatewayData = new ServerNewRealm.Gateway { Address = server.Address, Port = server.Model.Port }, RealmName = server.Model.Name, Type = (RealmType)server.Model.Type }); })); }
public static void HandleCharacterList(WorldSession session, ClientCharacterList characterList) { session.EnqueueEvent(new TaskGenericEvent <List <Character> >(CharacterDatabase.GetCharacters(session.Account.Id), characters => { session.Characters.Clear(); session.Characters.AddRange(characters); session.EnqueueMessageEncrypted(new ServerAccountEntitlements { Entitlements = { new ServerAccountEntitlements.AccountEntitlementInfo { Entitlement = Entitlement.BaseCharacterSlots, Count = 12 }, new ServerAccountEntitlements.AccountEntitlementInfo { Entitlement = Entitlement.ChuaWarriorUnlock, Count = 1 }, new ServerAccountEntitlements.AccountEntitlementInfo { Entitlement = Entitlement.AurinEngineerUnlock, Count = 1 } } }); session.EnqueueMessageEncrypted(new ServerMaxCharacterLevelAchieved { Level = 50 }); var serverCharacterList = new ServerCharacterList { RealmId = WorldServer.RealmId }; foreach (Character character in characters) { var listCharacter = new ServerCharacterList.Character { Id = character.Id, Name = character.Name, Sex = (Sex)character.Sex, Race = (Race)character.Race, Class = (Class)character.Class, Faction = character.FactionId, Level = character.Level, WorldId = 3460, WorldZoneId = 5967, RealmId = WorldServer.RealmId }; // create a temporary inventory to show equipped gear var inventory = new Inventory(null, character); foreach (ItemVisual itemVisual in inventory.GetItemVisuals()) { listCharacter.Gear.Add(itemVisual); } foreach (CharacterAppearance appearance in character.CharacterAppearance) { listCharacter.Appearance.Add(new ItemVisual { Slot = (ItemSlot)appearance.Slot, DisplayId = appearance.DisplayId }); } foreach (CharacterCustomisation customisation in character.CharacterCustomisation) { listCharacter.Labels.Add(customisation.Label); listCharacter.Values.Add(customisation.Value); } foreach (CharacterBone bone in character.CharacterBone.OrderBy(bone => bone.BoneIndex)) { listCharacter.Bones.Add(bone.Bone); } serverCharacterList.Characters.Add(listCharacter); } session.EnqueueMessageEncrypted(serverCharacterList); })); }
public static void HandleCharacterCreate(WorldSession session, ClientCharacterCreate characterCreate) { try { // TODO: validate name and path CharacterCreationEntry creationEntry = GameTableManager.CharacterCreation.GetEntry(characterCreate.CharacterCreationId); if (creationEntry == null) { throw new InvalidPacketValueException(); } if (creationEntry.EntitlementIdRequired != 0u) { // TODO: Aurin engineer has this } var character = new Character { AccountId = session.Account.Id, Id = AssetManager.NextCharacterId, Name = characterCreate.Name, Race = (byte)creationEntry.RaceId, Sex = (byte)creationEntry.Sex, Class = (byte)creationEntry.ClassId, Level = 1, FactionId = (ushort)creationEntry.FactionId, ActivePath = characterCreate.Path }; for (Path path = Path.Soldier; path <= Path.Explorer; path++) { character.CharacterPath.Add(new CharacterPath { Path = (byte)path, Unlocked = Convert.ToByte(characterCreate.Path == (byte)path) }); } // merge seperate label and value lists into a single dictonary Dictionary <uint, uint> customisations = characterCreate.Labels .Zip(characterCreate.Values, (l, v) => new { l, v }) .ToDictionary(p => p.l, p => p.v); foreach ((uint label, uint value) in customisations) { character.CharacterCustomisation.Add(new CharacterCustomisation { Label = label, Value = value }); CharacterCustomizationEntry entry = GetCharacterCustomisation(customisations, creationEntry.RaceId, creationEntry.Sex, label, value); if (entry == null) { continue; } character.CharacterAppearance.Add(new CharacterAppearance { Slot = (byte)entry.ItemSlotId, DisplayId = (ushort)entry.ItemDisplayId }); } for (int i = 0; i < characterCreate.Bones.Count; ++i) { character.CharacterBone.Add(new CharacterBone { BoneIndex = (byte)(i), Bone = characterCreate.Bones[i] }); } //TODO: handle starting locations per race character.LocationX = -7683.809f; character.LocationY = -942.5914f; character.LocationZ = -666.6343f; character.WorldId = 870; // create a temporary inventory to create starting gear var inventory = new Inventory(character.Id, creationEntry); var items = inventory .SelectMany(b => b) .Select(i => i); // TODO: actually error check this session.EnqueueEvent(new TaskEvent(CharacterDatabase.CreateCharacter(character, items), () => { session.Characters.Add(character); session.EnqueueMessageEncrypted(new ServerCharacterCreate { CharacterId = character.Id, WorldId = character.WorldId, Result = 3 }); })); } catch { session.EnqueueMessageEncrypted(new ServerCharacterCreate { Result = 0 }); throw; } CharacterCustomizationEntry GetCharacterCustomisation(Dictionary <uint, uint> customisations, uint race, uint sex, uint primaryLabel, uint primaryValue) { ImmutableList <CharacterCustomizationEntry> entries = AssetManager.GetPrimaryCharacterCustomisation(race, sex, primaryLabel, primaryValue); if (entries == null) { return(null); } if (entries.Count == 1) { return(entries[0]); } // customisation has multiple results, filter with secondary label and value uint secondaryLabel = entries.First(e => e.CharacterCustomizationLabelId01 != 0).CharacterCustomizationLabelId01; uint secondaryValue = customisations[secondaryLabel]; CharacterCustomizationEntry entry = entries.SingleOrDefault(e => e.CharacterCustomizationLabelId01 == secondaryLabel && e.Value01 == secondaryValue); return(entry ?? entries.Single(e => e.CharacterCustomizationLabelId01 == 0 && e.Value01 == 0)); } }
public static void HandleCharacterDelete(WorldSession session, ClientCharacterDelete characterDelete) { CharacterModel characterToDelete = session.Characters.FirstOrDefault(c => c.Id == characterDelete.CharacterId); (CharacterModifyResult, uint) GetResult() { if (characterToDelete == null) { return(CharacterModifyResult.DeleteFailed, 0); } // TODO: Not sure if this is definitely the case, but put it in for good measure if (characterToDelete.Mail.Count > 0) { foreach (CharacterMailModel characterMail in characterToDelete.Mail) { if (characterMail.Attachment.Count > 0) { return(CharacterModifyResult.DeleteFailed, 0); } } } uint leaderCount = (uint)GlobalGuildManager.Instance.GetCharacterGuilds(characterToDelete.Id) .Count(g => g.LeaderId == characterDelete.CharacterId); if (leaderCount > 0) { return(CharacterModifyResult.DeleteFailed, leaderCount); } return(CharacterModifyResult.DeleteOk, 0); } (CharacterModifyResult result, uint data)deleteCheck = GetResult(); if (deleteCheck.result != CharacterModifyResult.DeleteOk) { session.EnqueueMessageEncrypted(new ServerCharacterDeleteResult { Result = deleteCheck.result, Data = deleteCheck.data }); return; } session.CanProcessPackets = false; void Save(CharacterContext context) { var model = new CharacterModel { Id = characterToDelete.Id }; EntityEntry <CharacterModel> entity = context.Attach(model); model.DeleteTime = DateTime.UtcNow; entity.Property(e => e.DeleteTime).IsModified = true; model.OriginalName = characterToDelete.Name; entity.Property(e => e.OriginalName).IsModified = true; model.Name = null; entity.Property(e => e.Name).IsModified = true; } session.EnqueueEvent(new TaskEvent(DatabaseManager.Instance.CharacterDatabase.Save(Save), () => { session.CanProcessPackets = true; ResidenceManager.Instance.RemoveResidence(characterToDelete.Name); CharacterManager.Instance.DeleteCharacter(characterToDelete.Id, characterToDelete.Name); session.EnqueueMessageEncrypted(new ServerCharacterDeleteResult { Result = deleteCheck.result }); })); }
public static void HandleCharacterCreate(WorldSession session, ClientCharacterCreate characterCreate) { try { // TODO: validate name and path if (DatabaseManager.Instance.CharacterDatabase.CharacterNameExists(characterCreate.Name)) { session.EnqueueMessageEncrypted(new ServerCharacterCreate { Result = CharacterModifyResult.CreateFailed_UniqueName }); return; } CharacterCreationEntry creationEntry = GameTableManager.Instance.CharacterCreation.GetEntry(characterCreate.CharacterCreationId); if (creationEntry == null) { throw new InvalidPacketValueException(); } if (creationEntry.EntitlementIdRequired != 0u) { // TODO: Aurin engineer has this } var character = new CharacterModel { AccountId = session.Account.Id, Id = AssetManager.Instance.NextCharacterId, Name = characterCreate.Name, Race = (byte)creationEntry.RaceId, Sex = (byte)creationEntry.Sex, Class = (byte)creationEntry.ClassId, FactionId = (ushort)creationEntry.FactionId, ActivePath = characterCreate.Path }; for (Path path = Path.Soldier; path <= Path.Explorer; path++) { character.Path.Add(new CharacterPathModel { Path = (byte)path, Unlocked = Convert.ToByte(characterCreate.Path == (byte)path) }); } // merge seperate label and value lists into a single dictonary Dictionary <uint, uint> customisations = characterCreate.Labels .Zip(characterCreate.Values, (l, v) => new { l, v }) .ToDictionary(p => p.l, p => p.v); foreach ((uint label, uint value) in customisations) { character.Customisation.Add(new CharacterCustomisationModel { Label = label, Value = value }); CharacterCustomizationEntry entry = GetCharacterCustomisation(customisations, creationEntry.RaceId, creationEntry.Sex, label, value); if (entry == null) { continue; } character.Appearance.Add(new CharacterAppearanceModel { Slot = (byte)entry.ItemSlotId, DisplayId = (ushort)entry.ItemDisplayId }); } for (int i = 0; i < characterCreate.Bones.Count; ++i) { character.Bone.Add(new CharacterBoneModel { BoneIndex = (byte)(i), Bone = characterCreate.Bones[i] }); } //TODO: handle starting locations per race character.LocationX = -7683.809f; character.LocationY = -942.5914f; character.LocationZ = -666.6343f; character.WorldId = 870; character.ActiveSpec = 0; // create initial LAS abilities UILocation location = 0; foreach (SpellLevelEntry spellLevelEntry in GameTableManager.Instance.SpellLevel.Entries .Where(s => s.ClassId == character.Class && s.CharacterLevel == 1)) { Spell4Entry spell4Entry = GameTableManager.Instance.Spell4.GetEntry(spellLevelEntry.Spell4Id); if (spell4Entry == null) { continue; } character.Spell.Add(new CharacterSpellModel { Id = character.Id, Spell4BaseId = spell4Entry.Spell4BaseIdBaseSpell, Tier = 1 }); character.ActionSetShortcut.Add(new CharacterActionSetShortcutModel { Id = character.Id, SpecIndex = 0, Location = (ushort)location, ShortcutType = (byte)ShortcutType.Spell, ObjectId = spell4Entry.Spell4BaseIdBaseSpell, Tier = 1 }); location++; } // create a temporary inventory to create starting gear var inventory = new Inventory(character.Id, creationEntry); IEnumerable <Item> items = inventory .SelectMany(b => b) .Select(i => i); //TODO: handle starting stats per class/race character.Stat.Add(new CharacterStatModel { Id = character.Id, Stat = (byte)Stat.Health, Value = 800 }); character.Stat.Add(new CharacterStatModel { Id = character.Id, Stat = (byte)Stat.Shield, Value = 450 }); character.Stat.Add(new CharacterStatModel { Id = character.Id, Stat = (byte)Stat.Dash, Value = 200 }); character.Stat.Add(new CharacterStatModel { Id = character.Id, Stat = (byte)Stat.Level, Value = 1 }); character.Stat.Add(new CharacterStatModel { Id = character.Id, Stat = (byte)Stat.StandState, Value = 3 }); // TODO: actually error check this session.EnqueueEvent(new TaskEvent(DatabaseManager.Instance.CharacterDatabase.Save(c => { c.Character.Add(character); foreach (Item item in items) { item.Save(c); } }), () => { session.Characters.Add(character); session.EnqueueMessageEncrypted(new ServerCharacterCreate { CharacterId = character.Id, WorldId = character.WorldId, Result = CharacterModifyResult.CreateOk }); })); } catch { session.EnqueueMessageEncrypted(new ServerCharacterCreate { Result = CharacterModifyResult.CreateFailed }); throw; } CharacterCustomizationEntry GetCharacterCustomisation(Dictionary <uint, uint> customisations, uint race, uint sex, uint primaryLabel, uint primaryValue) { ImmutableList <CharacterCustomizationEntry> entries = AssetManager.Instance.GetPrimaryCharacterCustomisation(race, sex, primaryLabel, primaryValue); if (entries == null) { return(null); } if (entries.Count == 1) { return(entries[0]); } // customisation has multiple results, filter with secondary label and value uint secondaryLabel = entries.First(e => e.CharacterCustomizationLabelId01 != 0).CharacterCustomizationLabelId01; uint secondaryValue = customisations[secondaryLabel]; CharacterCustomizationEntry entry = entries.SingleOrDefault(e => e.CharacterCustomizationLabelId01 == secondaryLabel && e.Value01 == secondaryValue); return(entry ?? entries.Single(e => e.CharacterCustomizationLabelId01 == 0 && e.Value01 == 0)); } }
public static void HandleCharacterList(WorldSession session, ClientCharacterList characterList) { session.EnqueueEvent(new TaskGenericEvent <List <CharacterModel> >(DatabaseManager.Instance.CharacterDatabase.GetCharacters(session.Account.Id), characters => { byte maxCharacterLevelAchieved = 1; session.Characters.Clear(); session.Characters.AddRange(characters); session.AccountCurrencyManager.SendCharacterListPacket(); session.GenericUnlockManager.SendUnlockList(); session.EnqueueMessageEncrypted(new ServerAccountEntitlements { Entitlements = session.EntitlementManager.GetAccountEntitlements() .Select(e => new ServerAccountEntitlements.AccountEntitlementInfo { Entitlement = e.Type, Count = e.Amount }) .ToList() }); session.EnqueueMessageEncrypted(new ServerAccountTier { Tier = session.AccountTier }); // 2 is just a fail safe for the minimum amount of character slots // this is set in the tbl files so a value should always exist uint characterSlots = (uint)(session.EntitlementManager.GetRewardProperty(RewardPropertyType.CharacterSlots).GetValue(0u) ?? 2u); uint characterCount = (uint)characters.Count(c => c.DeleteTime == null); var serverCharacterList = new ServerCharacterList { RealmId = WorldServer.RealmId, // no longer used as replaced by entitlements but retail server still used to send this AdditionalCount = characterCount, AdditionalAllowedCharCreations = (uint)Math.Max(0, (int)(characterSlots - characterCount)) }; foreach (CharacterModel character in characters.Where(c => c.DeleteTime == null)) { var listCharacter = new ServerCharacterList.Character { Id = character.Id, Name = character.Name, Sex = (Sex)character.Sex, Race = (Race)character.Race, Class = (Class)character.Class, Faction = character.FactionId, Level = character.Level, WorldId = character.WorldId, WorldZoneId = character.WorldZoneId, RealmId = WorldServer.RealmId, Path = (byte)character.ActivePath, LastLoggedOutDays = (float)DateTime.UtcNow.Subtract(character.LastOnline ?? DateTime.UtcNow).TotalDays * -1f }; maxCharacterLevelAchieved = Math.Max(maxCharacterLevelAchieved, character.Level); try { // create a temporary Inventory and CostumeManager to show equipped gear var inventory = new Inventory(null, character); var costumeManager = new CostumeManager(null, session.Account, character); CostumeEntity costume = null; if (character.ActiveCostumeIndex >= 0) { costume = costumeManager.GetCostume((byte)character.ActiveCostumeIndex); } listCharacter.GearMask = costume?.Mask ?? 0xFFFFFFFF; foreach (ItemVisual itemVisual in inventory.GetItemVisuals(costume)) { listCharacter.Gear.Add(itemVisual); } foreach (CharacterAppearanceModel appearance in character.Appearance) { listCharacter.Appearance.Add(new ItemVisual { Slot = (ItemSlot)appearance.Slot, DisplayId = appearance.DisplayId }); } /*foreach (CharacterCustomisation customisation in character.CharacterCustomisation) * { * listCharacter.Labels.Add(customisation.Label); * listCharacter.Values.Add(customisation.Value); * }*/ foreach (CharacterBoneModel bone in character.Bone.OrderBy(bone => bone.BoneIndex)) { listCharacter.Bones.Add(bone.Bone); } foreach (CharacterStatModel stat in character.Stat) { if ((Stat)stat.Stat == Stat.Level) { listCharacter.Level = (uint)stat.Value; break; } } serverCharacterList.Characters.Add(listCharacter); } catch (Exception ex) { log.Fatal(ex, $"An error has occured while loading character '{character.Name}'"); continue; } } session.EnqueueMessageEncrypted(new ServerMaxCharacterLevelAchieved { Level = maxCharacterLevelAchieved }); session.EnqueueMessageEncrypted(serverCharacterList); })); }
public static void HandleCharacterList(WorldSession session, ClientCharacterList characterList) { session.EnqueueEvent(new TaskGenericEvent <List <Character> >(CharacterDatabase.GetCharacters(session.Account.Id), characters => { byte MaxCharacterLevelAchieved = 1; session.Characters.Clear(); session.Characters.AddRange(characters); session.GenericUnlockManager.SendUnlockList(); session.EnqueueMessageEncrypted(new ServerAccountEntitlements { Entitlements = { new ServerAccountEntitlements.AccountEntitlementInfo { Entitlement = Entitlement.BaseCharacterSlots, Count = 12 }, new ServerAccountEntitlements.AccountEntitlementInfo { Entitlement = Entitlement.ExtraDecorSlots, Count = 2000 }, new ServerAccountEntitlements.AccountEntitlementInfo { Entitlement = Entitlement.ChuaWarriorUnlock, Count = 1 }, new ServerAccountEntitlements.AccountEntitlementInfo { Entitlement = Entitlement.AurinEngineerUnlock, Count = 1 } } }); var serverCharacterList = new ServerCharacterList { RealmId = WorldServer.RealmId }; foreach (Character character in characters) { var listCharacter = new ServerCharacterList.Character { Id = character.Id, Name = character.Name, Sex = (Sex)character.Sex, Race = (Race)character.Race, Class = (Class)character.Class, Faction = character.FactionId, Level = character.Level, WorldId = character.WorldId, WorldZoneId = character.WorldZoneId, RealmId = WorldServer.RealmId, Path = (byte)character.ActivePath }; MaxCharacterLevelAchieved = (byte)Math.Max(MaxCharacterLevelAchieved, character.Level); // create a temporary Inventory and CostumeManager to show equipped gear var inventory = new Inventory(null, character); var costumeManager = new CostumeManager(null, session.Account, character); CostumeEntity costume = null; if (character.ActiveCostumeIndex >= 0) { costume = costumeManager.GetCostume((byte)character.ActiveCostumeIndex); } listCharacter.GearMask = costume?.Mask ?? 0xFFFFFFFF; foreach (ItemVisual itemVisual in inventory.GetItemVisuals(costume)) { listCharacter.Gear.Add(itemVisual); } foreach (CharacterAppearance appearance in character.CharacterAppearance) { listCharacter.Appearance.Add(new ItemVisual { Slot = (ItemSlot)appearance.Slot, DisplayId = appearance.DisplayId }); } /*foreach (CharacterCustomisation customisation in character.CharacterCustomisation) * { * listCharacter.Labels.Add(customisation.Label); * listCharacter.Values.Add(customisation.Value); * }*/ foreach (CharacterBone bone in character.CharacterBone.OrderBy(bone => bone.BoneIndex)) { listCharacter.Bones.Add(bone.Bone); } foreach (CharacterStat stat in character.CharacterStat) { if ((Stat)stat.Stat == Stat.Level) { listCharacter.Level = (uint)stat.Value; break; } } serverCharacterList.Characters.Add(listCharacter); } session.EnqueueMessageEncrypted(new ServerMaxCharacterLevelAchieved { Level = MaxCharacterLevelAchieved }); session.EnqueueMessageEncrypted(serverCharacterList); })); }
public static void HandleCharacterDelete(WorldSession session, ClientCharacterDelete characterDelete) { Character characterToDelete = session.Characters.FirstOrDefault(c => c.Id == characterDelete.CharacterId); CharacterModifyResult GetResult() { if (characterToDelete == null) { return(CharacterModifyResult.DeleteFailed); } // TODO: Not sure if this is definitely the case, but put it in for good measure if (characterToDelete.CharacterMail.Count > 0) { foreach (CharacterMail characterMail in characterToDelete.CharacterMail) { if (characterMail.CharacterMailAttachment.Count > 0) { return(CharacterModifyResult.DeleteFailed); } } } // TODO: Ensure character is not a guild master return(CharacterModifyResult.DeleteOk); } CharacterModifyResult result = GetResult(); if (result != CharacterModifyResult.DeleteOk) { session.EnqueueMessageEncrypted(new ServerCharacterDeleteResult { Result = result }); return; } session.CanProcessPackets = false; void Save(CharacterContextExtended context) { var model = new Character { Id = characterToDelete.Id }; EntityEntry <Character> entity = context.Attach(model); model.DeleteTime = DateTime.UtcNow; entity.Property(e => e.DeleteTime).IsModified = true; model.OriginalName = characterToDelete.Name; entity.Property(e => e.OriginalName).IsModified = true; model.Name = null; entity.Property(e => e.Name).IsModified = true; } session.EnqueueEvent(new TaskEvent(CharacterDatabase.Save(Save), () => { session.CanProcessPackets = true; CharacterManager.Instance.DeleteCharacter(characterToDelete.Id); session.EnqueueMessageEncrypted(new ServerCharacterDeleteResult { Result = result }); })); }
public static void HandleCharacterList(WorldSession session, ClientCharacterList characterList) { session.EnqueueEvent(new TaskGenericEvent <List <CharacterModel> >(DatabaseManager.Instance.CharacterDatabase.GetCharacters(session.Account.Id), characters => { byte maxCharacterLevelAchieved = 1; session.Characters.Clear(); session.Characters.AddRange(characters); session.AccountCurrencyManager.SendCharacterListPacket(); session.GenericUnlockManager.SendUnlockList(); session.EnqueueMessageEncrypted(new ServerAccountEntitlements { Entitlements = session.EntitlementManager.GetAccountEntitlements() .Select(e => new ServerAccountEntitlements.AccountEntitlementInfo { Entitlement = e.Type, Count = e.Amount }) .ToList() }); var serverCharacterList = new ServerCharacterList { RealmId = WorldServer.RealmId }; foreach (CharacterModel character in characters) { if (character.DeleteTime != null) { continue; } var listCharacter = new ServerCharacterList.Character { Id = character.Id, Name = character.Name, Sex = (Sex)character.Sex, Race = (Race)character.Race, Class = (Class)character.Class, Faction = character.FactionId, Level = character.Level, WorldId = character.WorldId, WorldZoneId = character.WorldZoneId, RealmId = WorldServer.RealmId, Path = (byte)character.ActivePath }; maxCharacterLevelAchieved = (byte)Math.Max(maxCharacterLevelAchieved, character.Level); // create a temporary Inventory and CostumeManager to show equipped gear var inventory = new Inventory(null, character); var costumeManager = new CostumeManager(null, session.Account, character); CostumeEntity costume = null; if (character.ActiveCostumeIndex >= 0) { costume = costumeManager.GetCostume((byte)character.ActiveCostumeIndex); } listCharacter.GearMask = costume?.Mask ?? 0xFFFFFFFF; foreach (ItemVisual itemVisual in inventory.GetItemVisuals(costume)) { listCharacter.Gear.Add(itemVisual); } foreach (CharacterAppearanceModel appearance in character.Appearance) { listCharacter.Appearance.Add(new ItemVisual { Slot = (ItemSlot)appearance.Slot, DisplayId = appearance.DisplayId }); } /*foreach (CharacterCustomisation customisation in character.CharacterCustomisation) * { * listCharacter.Labels.Add(customisation.Label); * listCharacter.Values.Add(customisation.Value); * }*/ foreach (CharacterBoneModel bone in character.Bone.OrderBy(bone => bone.BoneIndex)) { listCharacter.Bones.Add(bone.Bone); } foreach (CharacterStatModel stat in character.Stat) { if ((Stat)stat.Stat == Stat.Level) { listCharacter.Level = (uint)stat.Value; break; } } serverCharacterList.Characters.Add(listCharacter); } session.EnqueueMessageEncrypted(new ServerMaxCharacterLevelAchieved { Level = maxCharacterLevelAchieved }); session.EnqueueMessageEncrypted(serverCharacterList); })); }