public int GetBiotaCount() { using (var context = new ShardDbContext()) return(context.Biota.Count()); }
public static void HandleFixSpellBars(Session session, params string[] parameters) { Console.WriteLine(); Console.WriteLine("This command will attempt to fix player spell bars. Unless explictly indicated, command will dry run only"); Console.WriteLine("You must have executed 2020-04-11-00-Update-Character-SpellBars.sql script first before running this command"); Console.WriteLine(); var execute = false; if (parameters.Length < 1) { Console.WriteLine("This will be a dry run and show which characters that would be affected. To perform fix, please use command: fix-spell-bars execute"); } else if (parameters[0].ToLower() == "execute") { execute = true; } else { Console.WriteLine("Please use command fix-spell-bars execute"); } if (!execute) { Console.WriteLine(); Console.WriteLine("Press enter to start."); Console.ReadLine(); } var numberOfRecordsFixed = 0; log.Info($"Starting FixSpellBarsPR2918 process. This could take a while..."); using (var context = new ShardDbContext()) { var characterSpellBarsNotFixed = context.CharacterPropertiesSpellBar.Where(c => c.SpellBarNumber == 0).ToList(); if (characterSpellBarsNotFixed.Count > 0) { log.Warn("2020-04-11-00-Update-Character-SpellBars.sql patch not yet applied. Please apply this patch ASAP! Skipping FixSpellBarsPR2918 for now..."); log.Fatal("2020-04-11-00-Update-Character-SpellBars.sql patch not yet applied. You must apply this patch before proceeding further..."); return; } var characterSpellBars = context.CharacterPropertiesSpellBar.OrderBy(c => c.CharacterId).ThenBy(c => c.SpellBarNumber).ThenBy(c => c.SpellBarIndex).ToList(); uint characterId = 0; uint spellBarNumber = 0; uint spellBarIndex = 0; foreach (var entry in characterSpellBars) { if (entry.CharacterId != characterId) { characterId = entry.CharacterId; spellBarIndex = 0; } if (entry.SpellBarNumber != spellBarNumber) { spellBarNumber = entry.SpellBarNumber; spellBarIndex = 0; } spellBarIndex++; if (entry.SpellBarIndex != spellBarIndex) { Console.WriteLine($"FixSpellBarsPR2918: Character 0x{entry.CharacterId:X8}, SpellBarNumber = {entry.SpellBarNumber} | SpellBarIndex = {entry.SpellBarIndex:000}; Fixed - {spellBarIndex:000}"); entry.SpellBarIndex = spellBarIndex; numberOfRecordsFixed++; } else { Console.WriteLine($"FixSpellBarsPR2918: Character 0x{entry.CharacterId:X8}, SpellBarNumber = {entry.SpellBarNumber} | SpellBarIndex = {entry.SpellBarIndex:000}; OK"); } } // Save if (execute) { Console.WriteLine("Saving changes..."); context.SaveChanges(); log.Info($"Fixed {numberOfRecordsFixed:N0} CharacterPropertiesSpellBar records."); } else { Console.WriteLine($"{numberOfRecordsFixed:N0} CharacterPropertiesSpellBar records need to be fixed!"); Console.WriteLine("dry run completed. Use fix-spell-bars execute to actually run command"); } } }
public static void UpdateDatabaseBiota(ShardDbContext context, ACE.Entity.Models.Biota sourceBiota, ACE.Database.Models.Shard.Biota targetBiota) { targetBiota.WeenieClassId = sourceBiota.WeenieClassId; targetBiota.WeenieType = (int)sourceBiota.WeenieType; throw new NotImplementedException(); /* Uncomment this when new biota model is used * if (sourceBiota.PropertiesBool != null) * { * foreach (var kvp in sourceBiota.PropertiesBool) * targetBiota.SetProperty(kvp.Key, kvp.Value); * } * foreach (var value in targetBiota.BiotaPropertiesBool) * { * if (sourceBiota.PropertiesBool == null || !sourceBiota.PropertiesBool.ContainsKey((PropertyBool)value.Type)) * context.BiotaPropertiesBool.Remove(value); * } * * if (sourceBiota.PropertiesDID != null) * { * foreach (var kvp in sourceBiota.PropertiesDID) * targetBiota.SetProperty(kvp.Key, kvp.Value); * } * foreach (var value in targetBiota.BiotaPropertiesDID) * { * if (sourceBiota.PropertiesDID == null || !sourceBiota.PropertiesDID.ContainsKey((PropertyDataId)value.Type)) * context.BiotaPropertiesDID.Remove(value); * } * * if (sourceBiota.PropertiesFloat != null) * { * foreach (var kvp in sourceBiota.PropertiesFloat) * targetBiota.SetProperty(kvp.Key, kvp.Value); * } * foreach (var value in targetBiota.BiotaPropertiesFloat) * { * if (sourceBiota.PropertiesFloat == null || !sourceBiota.PropertiesFloat.ContainsKey((PropertyFloat)value.Type)) * context.BiotaPropertiesFloat.Remove(value); * } * * if (sourceBiota.PropertiesIID != null) * { * foreach (var kvp in sourceBiota.PropertiesIID) * targetBiota.SetProperty(kvp.Key, kvp.Value); * } * foreach (var value in targetBiota.BiotaPropertiesIID) * { * if (sourceBiota.PropertiesIID == null || !sourceBiota.PropertiesIID.ContainsKey((PropertyInstanceId)value.Type)) * context.BiotaPropertiesIID.Remove(value); * } * * if (sourceBiota.PropertiesInt != null) * { * foreach (var kvp in sourceBiota.PropertiesInt) * targetBiota.SetProperty(kvp.Key, kvp.Value); * } * foreach (var value in targetBiota.BiotaPropertiesInt) * { * if (sourceBiota.PropertiesInt == null || !sourceBiota.PropertiesInt.ContainsKey((PropertyInt)value.Type)) * context.BiotaPropertiesInt.Remove(value); * } * * if (sourceBiota.PropertiesInt64 != null) * { * foreach (var kvp in sourceBiota.PropertiesInt64) * targetBiota.SetProperty(kvp.Key, kvp.Value); * } * foreach (var value in targetBiota.BiotaPropertiesInt64) * { * if (sourceBiota.PropertiesInt64 == null || !sourceBiota.PropertiesInt64.ContainsKey((PropertyInt64)value.Type)) * context.BiotaPropertiesInt64.Remove(value); * } * * if (sourceBiota.PropertiesString != null) * { * foreach (var kvp in sourceBiota.PropertiesString) * targetBiota.SetProperty(kvp.Key, kvp.Value); * } * foreach (var value in targetBiota.BiotaPropertiesString) * { * if (sourceBiota.PropertiesString == null || !sourceBiota.PropertiesString.ContainsKey((PropertyString)value.Type)) * context.BiotaPropertiesString.Remove(value); * }*/ if (sourceBiota.PropertiesPosition != null) { foreach (var kvp in sourceBiota.PropertiesPosition) { BiotaPropertiesPosition existingValue = targetBiota.BiotaPropertiesPosition.FirstOrDefault(r => r.PositionType == (ushort)kvp.Key); if (existingValue == null) { existingValue = new BiotaPropertiesPosition { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesPosition.Add(existingValue); } existingValue.PositionType = (ushort)kvp.Key; existingValue.ObjCellId = kvp.Value.ObjCellId; existingValue.OriginX = kvp.Value.PositionX; existingValue.OriginY = kvp.Value.PositionY; existingValue.OriginZ = kvp.Value.PositionZ; existingValue.AnglesW = kvp.Value.RotationW; existingValue.AnglesX = kvp.Value.RotationX; existingValue.AnglesY = kvp.Value.RotationY; existingValue.AnglesZ = kvp.Value.RotationZ; } } foreach (var value in targetBiota.BiotaPropertiesPosition) { if (sourceBiota.PropertiesPosition == null || !sourceBiota.PropertiesPosition.ContainsKey((PositionType)value.PositionType)) { context.BiotaPropertiesPosition.Remove(value); } } if (sourceBiota.PropertiesSpellBook != null) { foreach (var kvp in sourceBiota.PropertiesSpellBook) { BiotaPropertiesSpellBook existingValue = targetBiota.BiotaPropertiesSpellBook.FirstOrDefault(r => r.Spell == (ushort)kvp.Key); if (existingValue == null) { existingValue = new BiotaPropertiesSpellBook { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesSpellBook.Add(existingValue); } existingValue.Spell = kvp.Key; existingValue.Probability = kvp.Value; } } foreach (var value in targetBiota.BiotaPropertiesSpellBook) { if (sourceBiota.PropertiesSpellBook == null || !sourceBiota.PropertiesSpellBook.ContainsKey(value.Spell)) { context.BiotaPropertiesSpellBook.Remove(value); } } if (sourceBiota.PropertiesAnimPart != null) { for (int i = 0; i < sourceBiota.PropertiesAnimPart.Count; i++) { var value = sourceBiota.PropertiesAnimPart[i]; BiotaPropertiesAnimPart existingValue = targetBiota.BiotaPropertiesAnimPart.FirstOrDefault(r => r.Order == i); if (existingValue == null) { existingValue = new BiotaPropertiesAnimPart { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesAnimPart.Add(existingValue); } existingValue.Index = value.Index; existingValue.AnimationId = value.AnimationId; existingValue.Order = (byte)i; } } foreach (var value in targetBiota.BiotaPropertiesAnimPart) { if (sourceBiota.PropertiesAnimPart == null || value.Order >= sourceBiota.PropertiesAnimPart.Count) { context.BiotaPropertiesAnimPart.Remove(value); } } if (sourceBiota.PropertiesPalette != null) { foreach (var value in sourceBiota.PropertiesPalette) { BiotaPropertiesPalette existingValue = targetBiota.BiotaPropertiesPalette.FirstOrDefault(r => r.SubPaletteId == value.SubPaletteId && r.Offset == value.Offset && r.Length == value.Length); if (existingValue == null) { existingValue = new BiotaPropertiesPalette { ObjectId = sourceBiota.Id, SubPaletteId = value.SubPaletteId, Offset = value.Offset, Length = value.Length }; targetBiota.BiotaPropertiesPalette.Add(existingValue); } } } foreach (var value in targetBiota.BiotaPropertiesPalette) { if (sourceBiota.PropertiesPalette == null || !sourceBiota.PropertiesPalette.Any(p => p.SubPaletteId == value.SubPaletteId && p.Offset == value.Offset && p.Length == value.Length)) { context.BiotaPropertiesPalette.Remove(value); } } if (sourceBiota.PropertiesTextureMap != null) { for (int i = 0; i < sourceBiota.PropertiesTextureMap.Count; i++) { var value = sourceBiota.PropertiesTextureMap[i]; BiotaPropertiesTextureMap existingValue = targetBiota.BiotaPropertiesTextureMap.FirstOrDefault(r => r.Order == i); if (existingValue == null) { existingValue = new BiotaPropertiesTextureMap { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesTextureMap.Add(existingValue); } existingValue.Index = value.PartIndex; existingValue.OldId = value.OldTexture; existingValue.NewId = value.NewTexture; existingValue.Order = (byte)i; } } foreach (var value in targetBiota.BiotaPropertiesTextureMap) { if (sourceBiota.PropertiesTextureMap == null || value.Order >= sourceBiota.PropertiesTextureMap.Count) { context.BiotaPropertiesTextureMap.Remove(value); } } // Properties for all world objects that typically aren't modified over the original Biota /*if (biota.PropertiesCreateList != null) * { * foreach (var value in biota.PropertiesCreateList) * { * BiotaPropertiesCreateList existingValue = existingBiota.BiotaPropertiesCreateList.FirstOrDefault(r => r.Id == value.Id); * * if (existingValue == null) * existingBiota.BiotaPropertiesCreateList.Add(value); * else * { * existingValue.DestinationType = value.DestinationType; * existingValue.WeenieClassId = value.WeenieClassId; * existingValue.StackSize = value.StackSize; * existingValue.Palette = value.Palette; * existingValue.Shade = value.Shade; * existingValue.TryToBond = value.TryToBond; * } * } * } * foreach (var value in existingBiota.BiotaPropertiesCreateList) * { * if (biota.PropertiesCreateList == null || !biota.PropertiesCreateList.Any(p => p.Id == value.Id)) * context.BiotaPropertiesCreateList.Remove(value); * }*/ /*if (biota.PropertiesEmote != null) * { * foreach (var value in biota.PropertiesEmote) * { * BiotaPropertiesEmote existingValue = existingBiota.BiotaPropertiesEmote.FirstOrDefault(r => r.Id == value.Id); * * if (existingValue == null) * existingBiota.BiotaPropertiesEmote.Add(value); * else * { * existingValue.Category = value.Category; * existingValue.Probability = value.Probability; * existingValue.WeenieClassId = value.WeenieClassId; * existingValue.Style = value.Style; * existingValue.Substyle = value.Substyle; * existingValue.Quest = value.Quest; * existingValue.VendorType = value.VendorType; * existingValue.MinHealth = value.MinHealth; * existingValue.MaxHealth = value.MaxHealth; * * foreach (var value2 in value.PropertiesEmoteAction) * { * BiotaPropertiesEmoteAction existingValue2 = existingValue.BiotaPropertiesEmoteAction.FirstOrDefault(r => r.Id == value2.Id); * * if (existingValue2 == null) * existingValue.BiotaPropertiesEmoteAction.Add(value2); * else * { * //existingValue2.EmoteId = value2.EmoteId; * existingValue2.Order = (uint)value.PropertiesEmoteAction.IndexOf(value2); * existingValue2.Type = value2.Type; * existingValue2.Delay = value2.Delay; * existingValue2.Extent = value2.Extent; * existingValue2.Motion = value2.Motion; * existingValue2.Message = value2.Message; * existingValue2.TestString = value2.TestString; * existingValue2.Min = value2.Min; * existingValue2.Max = value2.Max; * existingValue2.Min64 = value2.Min64; * existingValue2.Max64 = value2.Max64; * existingValue2.MinDbl = value2.MinDbl; * existingValue2.MaxDbl = value2.MaxDbl; * existingValue2.Stat = value2.Stat; * existingValue2.Display = value2.Display; * existingValue2.Amount = value2.Amount; * existingValue2.Amount64 = value2.Amount64; * existingValue2.HeroXP64 = value2.HeroXP64; * existingValue2.Percent = value2.Percent; * existingValue2.SpellId = value2.SpellId; * existingValue2.WealthRating = value2.WealthRating; * existingValue2.TreasureClass = value2.TreasureClass; * existingValue2.TreasureType = value2.TreasureType; * existingValue2.PScript = value2.PScript; * existingValue2.Sound = value2.Sound; * existingValue2.DestinationType = value2.DestinationType; * existingValue2.WeenieClassId = value2.WeenieClassId; * existingValue2.StackSize = value2.StackSize; * existingValue2.Palette = value2.Palette; * existingValue2.Shade = value2.Shade; * existingValue2.TryToBond = value2.TryToBond; * existingValue2.ObjCellId = value2.ObjCellId; * existingValue2.OriginX = value2.OriginX; * existingValue2.OriginY = value2.OriginY; * existingValue2.OriginZ = value2.OriginZ; * existingValue2.AnglesW = value2.AnglesW; * existingValue2.AnglesX = value2.AnglesX; * existingValue2.AnglesY = value2.AnglesY; * existingValue2.AnglesZ = value2.AnglesZ; * } * } * foreach (var value2 in value.PropertiesEmoteAction) * { * if (!existingValue.BiotaPropertiesEmoteAction.Any(p => p.Id == value2.Id)) * context.BiotaPropertiesEmoteAction.Remove(value2); * } * } * } * } * foreach (var value in existingBiota.BiotaPropertiesEmote) * { * if (biota.PropertiesEmote == null || !biota.PropertiesEmote.Any(p => p.Id == value.Id)) * context.BiotaPropertiesEmote.Remove(value); * }*/ if (sourceBiota.PropertiesEventFilter != null) { foreach (var value in sourceBiota.PropertiesEventFilter) { BiotaPropertiesEventFilter existingValue = targetBiota.BiotaPropertiesEventFilter.FirstOrDefault(r => r.Event == value); if (existingValue == null) { var entity = new BiotaPropertiesEventFilter { ObjectId = sourceBiota.Id, Event = value }; targetBiota.BiotaPropertiesEventFilter.Add(entity); } } } foreach (var value in targetBiota.BiotaPropertiesEventFilter) { if (sourceBiota.PropertiesEventFilter == null || !sourceBiota.PropertiesEventFilter.Any(p => p == value.Event)) { context.BiotaPropertiesEventFilter.Remove(value); } } /*if (biota.PropertiesGenerator != null) * { * foreach (var value in biota.PropertiesGenerator) * { * BiotaPropertiesGenerator existingValue = existingBiota.BiotaPropertiesGenerator.FirstOrDefault(r => r.Id == value.Id); * * if (existingValue == null) * existingBiota.BiotaPropertiesGenerator.Add(value); * else * { * existingValue.Probability = value.Probability; * existingValue.WeenieClassId = value.WeenieClassId; * existingValue.Delay = value.Delay; * existingValue.InitCreate = value.InitCreate; * existingValue.MaxCreate = value.MaxCreate; * existingValue.WhenCreate = value.WhenCreate; * existingValue.WhereCreate = value.WhereCreate; * existingValue.StackSize = value.StackSize; * existingValue.PaletteId = value.PaletteId; * existingValue.Shade = value.Shade; * existingValue.ObjCellId = value.ObjCellId; * existingValue.OriginX = value.OriginX; * existingValue.OriginY = value.OriginY; * existingValue.OriginZ = value.OriginZ; * existingValue.AnglesW = value.AnglesW; * existingValue.AnglesX = value.AnglesX; * existingValue.AnglesY = value.AnglesY; * existingValue.AnglesZ = value.AnglesZ; * } * } * } * foreach (var value in existingBiota.BiotaPropertiesGenerator) * { * if (biota.PropertiesGenerator == null || !biota.PropertiesGenerator.Any(p => p.Id == value.Id)) * context.BiotaPropertiesGenerator.Remove(value); * }*/ // Properties for creatures if (sourceBiota.PropertiesAttribute != null) { foreach (var kvp in sourceBiota.PropertiesAttribute) { BiotaPropertiesAttribute existingValue = targetBiota.BiotaPropertiesAttribute.FirstOrDefault(r => r.Type == (ushort)kvp.Key); if (existingValue == null) { existingValue = new BiotaPropertiesAttribute { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesAttribute.Add(existingValue); } existingValue.Type = (ushort)kvp.Key; existingValue.InitLevel = kvp.Value.InitLevel; existingValue.LevelFromCP = kvp.Value.LevelFromCP; existingValue.CPSpent = kvp.Value.CPSpent; } } foreach (var value in targetBiota.BiotaPropertiesAttribute) { if (sourceBiota.PropertiesAttribute == null || !sourceBiota.PropertiesAttribute.ContainsKey((PropertyAttribute)value.Type)) { context.BiotaPropertiesAttribute.Remove(value); } } if (sourceBiota.PropertiesAttribute2nd != null) { foreach (var kvp in sourceBiota.PropertiesAttribute2nd) { BiotaPropertiesAttribute2nd existingValue = targetBiota.BiotaPropertiesAttribute2nd.FirstOrDefault(r => r.Type == (ushort)kvp.Key); if (existingValue == null) { existingValue = new BiotaPropertiesAttribute2nd { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesAttribute2nd.Add(existingValue); } existingValue.Type = (ushort)kvp.Key; existingValue.InitLevel = kvp.Value.InitLevel; existingValue.LevelFromCP = kvp.Value.LevelFromCP; existingValue.CPSpent = kvp.Value.CPSpent; existingValue.CurrentLevel = kvp.Value.CurrentLevel; } } foreach (var value in targetBiota.BiotaPropertiesAttribute2nd) { if (sourceBiota.PropertiesAttribute2nd == null || !sourceBiota.PropertiesAttribute2nd.ContainsKey((PropertyAttribute2nd)value.Type)) { context.BiotaPropertiesAttribute2nd.Remove(value); } } if (sourceBiota.PropertiesBodyPart != null) { foreach (var kvp in sourceBiota.PropertiesBodyPart) { BiotaPropertiesBodyPart existingValue = targetBiota.BiotaPropertiesBodyPart.FirstOrDefault(r => r.Key == (uint)kvp.Key); if (existingValue == null) { existingValue = new BiotaPropertiesBodyPart { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesBodyPart.Add(existingValue); } existingValue.Key = (ushort)kvp.Key; existingValue.DType = (int)kvp.Value.DType; existingValue.DVal = kvp.Value.DVal; existingValue.DVar = kvp.Value.DVar; existingValue.BaseArmor = kvp.Value.BaseArmor; existingValue.ArmorVsSlash = kvp.Value.ArmorVsSlash; existingValue.ArmorVsPierce = kvp.Value.ArmorVsPierce; existingValue.ArmorVsBludgeon = kvp.Value.ArmorVsBludgeon; existingValue.ArmorVsCold = kvp.Value.ArmorVsCold; existingValue.ArmorVsFire = kvp.Value.ArmorVsFire; existingValue.ArmorVsAcid = kvp.Value.ArmorVsAcid; existingValue.ArmorVsElectric = kvp.Value.ArmorVsElectric; existingValue.ArmorVsNether = kvp.Value.ArmorVsNether; existingValue.BH = kvp.Value.BH; existingValue.HLF = kvp.Value.HLF; existingValue.MLF = kvp.Value.MLF; existingValue.LLF = kvp.Value.LLF; existingValue.HRF = kvp.Value.HRF; existingValue.MRF = kvp.Value.MRF; existingValue.LRF = kvp.Value.LRF; existingValue.HLB = kvp.Value.HLB; existingValue.MLB = kvp.Value.MLB; existingValue.LLB = kvp.Value.LLB; existingValue.HRB = kvp.Value.HRB; existingValue.MRB = kvp.Value.MRB; existingValue.LRB = kvp.Value.LRB; } } foreach (var value in targetBiota.BiotaPropertiesBodyPart) { if (sourceBiota.PropertiesBodyPart == null || !sourceBiota.PropertiesBodyPart.ContainsKey((CombatBodyPart)value.Key)) { context.BiotaPropertiesBodyPart.Remove(value); } } if (sourceBiota.PropertiesSkill != null) { foreach (var kvp in sourceBiota.PropertiesSkill) { BiotaPropertiesSkill existingValue = targetBiota.BiotaPropertiesSkill.FirstOrDefault(r => r.Type == (ushort)kvp.Key); if (existingValue == null) { existingValue = new BiotaPropertiesSkill { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesSkill.Add(existingValue); } existingValue.Type = (ushort)kvp.Key; existingValue.LevelFromPP = kvp.Value.LevelFromPP; existingValue.SAC = (uint)kvp.Value.SAC; existingValue.PP = kvp.Value.PP; existingValue.InitLevel = kvp.Value.InitLevel; existingValue.ResistanceAtLastCheck = kvp.Value.ResistanceAtLastCheck; existingValue.LastUsedTime = kvp.Value.LastUsedTime; } } foreach (var value in targetBiota.BiotaPropertiesSkill) { if (sourceBiota.PropertiesSkill == null || !sourceBiota.PropertiesSkill.ContainsKey((Skill)value.Type)) { context.BiotaPropertiesSkill.Remove(value); } } // Properties for books if (sourceBiota.PropertiesBook != null) { if (targetBiota.BiotaPropertiesBook == null) { targetBiota.BiotaPropertiesBook = new BiotaPropertiesBook { ObjectId = sourceBiota.Id, } } ; targetBiota.BiotaPropertiesBook.MaxNumPages = sourceBiota.PropertiesBook.MaxNumPages; targetBiota.BiotaPropertiesBook.MaxNumCharsPerPage = sourceBiota.PropertiesBook.MaxNumCharsPerPage; } else { if (targetBiota.BiotaPropertiesBook != null) { context.BiotaPropertiesBook.Remove(targetBiota.BiotaPropertiesBook); } } if (sourceBiota.PropertiesBookPageData != null) { for (int i = 0; i < sourceBiota.PropertiesBookPageData.Count; i++) { var value = sourceBiota.PropertiesBookPageData[i]; BiotaPropertiesBookPageData existingValue = targetBiota.BiotaPropertiesBookPageData.FirstOrDefault(r => r.PageId == i); if (existingValue == null) { existingValue = new BiotaPropertiesBookPageData { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesBookPageData.Add(existingValue); } existingValue.PageId = (uint)i; existingValue.AuthorId = value.AuthorId; existingValue.AuthorName = value.AuthorName; existingValue.AuthorAccount = value.AuthorAccount; existingValue.IgnoreAuthor = value.IgnoreAuthor; existingValue.PageText = value.PageText; } } foreach (var value in targetBiota.BiotaPropertiesBookPageData) { if (sourceBiota.PropertiesBookPageData == null || value.PageId >= sourceBiota.PropertiesBookPageData.Count) { context.BiotaPropertiesBookPageData.Remove(value); } } // Biota additions over Weenie if (sourceBiota.PropertiesAllegiance != null) { foreach (var kvp in sourceBiota.PropertiesAllegiance) { BiotaPropertiesAllegiance existingValue = targetBiota.BiotaPropertiesAllegiance.FirstOrDefault(r => r.CharacterId == kvp.Key); if (existingValue == null) { existingValue = new BiotaPropertiesAllegiance { AllegianceId = sourceBiota.Id }; targetBiota.BiotaPropertiesAllegiance.Add(existingValue); } existingValue.CharacterId = kvp.Key; existingValue.Banned = kvp.Value.Banned; existingValue.ApprovedVassal = kvp.Value.ApprovedVassal; } } foreach (var value in targetBiota.BiotaPropertiesAllegiance) { if (sourceBiota.PropertiesAllegiance == null || !sourceBiota.PropertiesAllegiance.ContainsKey(value.CharacterId)) { context.BiotaPropertiesAllegiance.Remove(value); } } if (sourceBiota.PropertiesEnchantmentRegistry != null) { foreach (var value in sourceBiota.PropertiesEnchantmentRegistry) { BiotaPropertiesEnchantmentRegistry existingValue = targetBiota.BiotaPropertiesEnchantmentRegistry.FirstOrDefault(r => r.SpellId == value.SpellId && r.LayerId == value.LayerId && r.CasterObjectId == value.CasterObjectId); if (existingValue == null) { existingValue = new BiotaPropertiesEnchantmentRegistry { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesEnchantmentRegistry.Add(existingValue); } existingValue.EnchantmentCategory = value.EnchantmentCategory; existingValue.SpellId = value.SpellId; existingValue.LayerId = value.LayerId; existingValue.HasSpellSetId = value.HasSpellSetId; existingValue.SpellCategory = (ushort)value.SpellCategory; existingValue.PowerLevel = value.PowerLevel; existingValue.StartTime = value.StartTime; existingValue.Duration = value.Duration; existingValue.CasterObjectId = value.CasterObjectId; existingValue.DegradeModifier = value.DegradeModifier; existingValue.DegradeLimit = value.DegradeLimit; existingValue.LastTimeDegraded = value.LastTimeDegraded; existingValue.StatModType = (uint)value.StatModType; existingValue.StatModKey = value.StatModKey; existingValue.StatModValue = value.StatModValue; existingValue.SpellSetId = (uint)value.SpellSetId; } } foreach (var value in targetBiota.BiotaPropertiesEnchantmentRegistry) { if (sourceBiota.PropertiesEnchantmentRegistry == null || !sourceBiota.PropertiesEnchantmentRegistry.Any(p => p.SpellId == value.SpellId && p.LayerId == value.LayerId && p.CasterObjectId == value.CasterObjectId)) { context.BiotaPropertiesEnchantmentRegistry.Remove(value); } } if (sourceBiota.HousePermissions != null) { foreach (var kvp in sourceBiota.HousePermissions) { HousePermission existingValue = targetBiota.HousePermission.FirstOrDefault(r => r.PlayerGuid == kvp.Key); if (existingValue == null) { existingValue = new HousePermission { HouseId = sourceBiota.Id }; targetBiota.HousePermission.Add(existingValue); } existingValue.PlayerGuid = kvp.Key; existingValue.Storage = kvp.Value; } } foreach (var value in targetBiota.HousePermission) { if (sourceBiota.HousePermissions == null || !sourceBiota.HousePermissions.ContainsKey(value.PlayerGuid)) { context.HousePermission.Remove(value); } } } }
public List <ConfigPropertiesBoolean> GetAllBools() { using (var context = new ShardDbContext()) return(context.ConfigPropertiesBoolean.AsNoTracking().ToList()); }
public List <ConfigPropertiesString> GetAllStrings() { using (var context = new ShardDbContext()) return(context.ConfigPropertiesString.AsNoTracking().ToList()); }
public static void PurgeCharacter(uint characterId, out int charactersPurged, out int playerBiotasPurged, out int possessionsPurged, string reason = null) { using (var context = new ShardDbContext()) PurgeCharacter(context, characterId, out charactersPurged, out playerBiotasPurged, out possessionsPurged, reason); }
public static void UpdateDatabaseBiota(ShardDbContext context, ACE.Entity.Models.Biota sourceBiota, ACE.Database.Models.Shard.Biota targetBiota) { targetBiota.WeenieClassId = sourceBiota.WeenieClassId; targetBiota.WeenieType = (int)sourceBiota.WeenieType; if (sourceBiota.PropertiesBool != null) { foreach (var kvp in sourceBiota.PropertiesBool) { targetBiota.SetProperty(kvp.Key, kvp.Value); } } foreach (var value in targetBiota.BiotaPropertiesBool) { if (sourceBiota.PropertiesBool == null || !sourceBiota.PropertiesBool.ContainsKey((PropertyBool)value.Type)) { context.BiotaPropertiesBool.Remove(value); } } if (sourceBiota.PropertiesDID != null) { foreach (var kvp in sourceBiota.PropertiesDID) { targetBiota.SetProperty(kvp.Key, kvp.Value); } } foreach (var value in targetBiota.BiotaPropertiesDID) { if (sourceBiota.PropertiesDID == null || !sourceBiota.PropertiesDID.ContainsKey((PropertyDataId)value.Type)) { context.BiotaPropertiesDID.Remove(value); } } if (sourceBiota.PropertiesFloat != null) { foreach (var kvp in sourceBiota.PropertiesFloat) { targetBiota.SetProperty(kvp.Key, kvp.Value); } } foreach (var value in targetBiota.BiotaPropertiesFloat) { if (sourceBiota.PropertiesFloat == null || !sourceBiota.PropertiesFloat.ContainsKey((PropertyFloat)value.Type)) { context.BiotaPropertiesFloat.Remove(value); } } if (sourceBiota.PropertiesIID != null) { foreach (var kvp in sourceBiota.PropertiesIID) { targetBiota.SetProperty(kvp.Key, kvp.Value); } } foreach (var value in targetBiota.BiotaPropertiesIID) { if (sourceBiota.PropertiesIID == null || !sourceBiota.PropertiesIID.ContainsKey((PropertyInstanceId)value.Type)) { context.BiotaPropertiesIID.Remove(value); } } if (sourceBiota.PropertiesInt != null) { foreach (var kvp in sourceBiota.PropertiesInt) { targetBiota.SetProperty(kvp.Key, kvp.Value); } } foreach (var value in targetBiota.BiotaPropertiesInt) { if (sourceBiota.PropertiesInt == null || !sourceBiota.PropertiesInt.ContainsKey((PropertyInt)value.Type)) { context.BiotaPropertiesInt.Remove(value); } } if (sourceBiota.PropertiesInt64 != null) { foreach (var kvp in sourceBiota.PropertiesInt64) { targetBiota.SetProperty(kvp.Key, kvp.Value); } } foreach (var value in targetBiota.BiotaPropertiesInt64) { if (sourceBiota.PropertiesInt64 == null || !sourceBiota.PropertiesInt64.ContainsKey((PropertyInt64)value.Type)) { context.BiotaPropertiesInt64.Remove(value); } } if (sourceBiota.PropertiesString != null) { foreach (var kvp in sourceBiota.PropertiesString) { targetBiota.SetProperty(kvp.Key, kvp.Value); } } foreach (var value in targetBiota.BiotaPropertiesString) { if (sourceBiota.PropertiesString == null || !sourceBiota.PropertiesString.ContainsKey((PropertyString)value.Type)) { context.BiotaPropertiesString.Remove(value); } } if (sourceBiota.PropertiesPosition != null) { foreach (var kvp in sourceBiota.PropertiesPosition) { BiotaPropertiesPosition existingValue = targetBiota.BiotaPropertiesPosition.FirstOrDefault(r => r.PositionType == (ushort)kvp.Key); if (existingValue == null) { existingValue = new BiotaPropertiesPosition { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesPosition.Add(existingValue); } existingValue.PositionType = (ushort)kvp.Key; existingValue.ObjCellId = kvp.Value.ObjCellId; existingValue.OriginX = kvp.Value.PositionX; existingValue.OriginY = kvp.Value.PositionY; existingValue.OriginZ = kvp.Value.PositionZ; existingValue.AnglesW = kvp.Value.RotationW; existingValue.AnglesX = kvp.Value.RotationX; existingValue.AnglesY = kvp.Value.RotationY; existingValue.AnglesZ = kvp.Value.RotationZ; } } foreach (var value in targetBiota.BiotaPropertiesPosition) { if (sourceBiota.PropertiesPosition == null || !sourceBiota.PropertiesPosition.ContainsKey((PositionType)value.PositionType)) { context.BiotaPropertiesPosition.Remove(value); } } if (sourceBiota.PropertiesSpellBook != null) { foreach (var kvp in sourceBiota.PropertiesSpellBook) { BiotaPropertiesSpellBook existingValue = targetBiota.BiotaPropertiesSpellBook.FirstOrDefault(r => r.Spell == (ushort)kvp.Key); if (existingValue == null) { existingValue = new BiotaPropertiesSpellBook { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesSpellBook.Add(existingValue); } existingValue.Spell = kvp.Key; existingValue.Probability = kvp.Value; } } foreach (var value in targetBiota.BiotaPropertiesSpellBook) { if (sourceBiota.PropertiesSpellBook == null || !sourceBiota.PropertiesSpellBook.ContainsKey(value.Spell)) { context.BiotaPropertiesSpellBook.Remove(value); } } if (sourceBiota.PropertiesAnimPart != null) { for (int i = 0; i < sourceBiota.PropertiesAnimPart.Count; i++) { var value = sourceBiota.PropertiesAnimPart[i]; BiotaPropertiesAnimPart existingValue = targetBiota.BiotaPropertiesAnimPart.FirstOrDefault(r => r.Order == i); if (existingValue == null) { existingValue = new BiotaPropertiesAnimPart { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesAnimPart.Add(existingValue); } existingValue.Index = value.Index; existingValue.AnimationId = value.AnimationId; existingValue.Order = (byte)i; } } foreach (var value in targetBiota.BiotaPropertiesAnimPart) { if (sourceBiota.PropertiesAnimPart == null || value.Order == null || value.Order >= sourceBiota.PropertiesAnimPart.Count) { context.BiotaPropertiesAnimPart.Remove(value); } } if (sourceBiota.PropertiesPalette != null) { foreach (var value in sourceBiota.PropertiesPalette) { BiotaPropertiesPalette existingValue = targetBiota.BiotaPropertiesPalette.FirstOrDefault(r => r.SubPaletteId == value.SubPaletteId && r.Offset == value.Offset && r.Length == value.Length); if (existingValue == null) { existingValue = new BiotaPropertiesPalette { ObjectId = sourceBiota.Id, SubPaletteId = value.SubPaletteId, Offset = value.Offset, Length = value.Length }; targetBiota.BiotaPropertiesPalette.Add(existingValue); } } } foreach (var value in targetBiota.BiotaPropertiesPalette) { if (sourceBiota.PropertiesPalette == null || !sourceBiota.PropertiesPalette.Any(p => p.SubPaletteId == value.SubPaletteId && p.Offset == value.Offset && p.Length == value.Length)) { context.BiotaPropertiesPalette.Remove(value); } } if (sourceBiota.PropertiesTextureMap != null) { for (int i = 0; i < sourceBiota.PropertiesTextureMap.Count; i++) { var value = sourceBiota.PropertiesTextureMap[i]; BiotaPropertiesTextureMap existingValue = targetBiota.BiotaPropertiesTextureMap.FirstOrDefault(r => r.Order == i); if (existingValue == null) { existingValue = new BiotaPropertiesTextureMap { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesTextureMap.Add(existingValue); } existingValue.Index = value.PartIndex; existingValue.OldId = value.OldTexture; existingValue.NewId = value.NewTexture; existingValue.Order = (byte)i; } } foreach (var value in targetBiota.BiotaPropertiesTextureMap) { if (sourceBiota.PropertiesTextureMap == null || value.Order == null || value.Order >= sourceBiota.PropertiesTextureMap.Count) { context.BiotaPropertiesTextureMap.Remove(value); } } // Properties for all world objects that typically aren't modified over the original Biota // This is a cluster... because there is no key per record, just the record id. // That poses a problem because when we add a new record to be saved, we don't know what the record id is yet. // It's not until we try to save the record a second time that we will then have the database persisted record (with a valid id), and the entity record (that still has a DatabaseRecordId of 0) // We then need to match up the record that was saved with it's entity counterpart var processedSourceCreateList = new HashSet <ACE.Entity.Models.PropertiesCreateList>(); var usedTargetCreateList = new HashSet <BiotaPropertiesCreateList>(); if (sourceBiota.PropertiesCreateList != null) { // Process matched up records first foreach (var value in sourceBiota.PropertiesCreateList) { if (value.DatabaseRecordId == 0) { continue; } // Source record should already exist in the target BiotaPropertiesCreateList existingValue = targetBiota.BiotaPropertiesCreateList.FirstOrDefault(r => r.Id == value.DatabaseRecordId); // If the existingValue was not found, the database was likely modified outside of ACE after our last save if (existingValue == null) { continue; } CopyValueInto(value, existingValue); processedSourceCreateList.Add(value); usedTargetCreateList.Add(existingValue); } foreach (var value in sourceBiota.PropertiesCreateList) { if (processedSourceCreateList.Contains(value)) { continue; } // For simplicity, just find the first unused target BiotaPropertiesCreateList existingValue = targetBiota.BiotaPropertiesCreateList.FirstOrDefault(r => !usedTargetCreateList.Contains(r)); if (existingValue == null) { existingValue = new BiotaPropertiesCreateList { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesCreateList.Add(existingValue); } value.DatabaseRecordId = existingValue.Id; CopyValueInto(value, existingValue); //processedSourceCreateList.Add(value); usedTargetCreateList.Add(existingValue); } } foreach (var value in targetBiota.BiotaPropertiesCreateList) { if (!usedTargetCreateList.Contains(value)) { context.BiotaPropertiesCreateList.Remove(value); } } // This is a cluster... because there is no key per record, just the record id. // That poses a problem because when we add a new record to be saved, we don't know what the record id is yet. // It's not until we try to save the record a second time that we will then have the database persisted record (with a valid id), and the entity record (that still has a DatabaseRecordId of 0) // We then need to match up the record that was saved with it's entity counterpart var emoteMap = new Dictionary <ACE.Entity.Models.PropertiesEmote, BiotaPropertiesEmote>(); if (sourceBiota.PropertiesEmote != null) { // Process matched up records first foreach (var value in sourceBiota.PropertiesEmote) { if (value.DatabaseRecordId == 0) { continue; } // Source record should already exist in the target BiotaPropertiesEmote existingValue = targetBiota.BiotaPropertiesEmote.FirstOrDefault(r => r.Id == value.DatabaseRecordId); // If the existingValue was not found, the database was likely modified outside of ACE after our last save if (existingValue == null) { continue; } CopyValueInto(value, existingValue); emoteMap[value] = existingValue; } foreach (var value in sourceBiota.PropertiesEmote) { if (emoteMap.Keys.Contains(value)) { continue; } // For simplicity, just find the first unused target BiotaPropertiesEmote existingValue = targetBiota.BiotaPropertiesEmote.FirstOrDefault(r => !emoteMap.Values.Contains(r)); if (existingValue == null) { existingValue = new BiotaPropertiesEmote { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesEmote.Add(existingValue); } value.DatabaseRecordId = existingValue.Id; CopyValueInto(value, existingValue); emoteMap[value] = existingValue; } } foreach (var value in targetBiota.BiotaPropertiesEmote) { if (!emoteMap.Values.Contains(value)) { context.BiotaPropertiesEmote.Remove(value); } } // Now process the emote actions foreach (var kvp in emoteMap) { for (int i = 0; i < kvp.Key.PropertiesEmoteAction.Count; i++) { BiotaPropertiesEmoteAction existingValue = kvp.Value.BiotaPropertiesEmoteAction.FirstOrDefault(r => r.Order == i); if (existingValue == null) { existingValue = new BiotaPropertiesEmoteAction { EmoteId = kvp.Value.Id }; kvp.Value.BiotaPropertiesEmoteAction.Add(existingValue); } CopyValueInto(kvp.Key.PropertiesEmoteAction[i], existingValue, (uint)i); } foreach (var value in kvp.Value.BiotaPropertiesEmoteAction) { if (value.Order >= kvp.Key.PropertiesEmoteAction.Count) { context.BiotaPropertiesEmoteAction.Remove(value); } } } if (sourceBiota.PropertiesEventFilter != null) { foreach (var value in sourceBiota.PropertiesEventFilter) { BiotaPropertiesEventFilter existingValue = targetBiota.BiotaPropertiesEventFilter.FirstOrDefault(r => r.Event == value); if (existingValue == null) { var entity = new BiotaPropertiesEventFilter { ObjectId = sourceBiota.Id, Event = value }; targetBiota.BiotaPropertiesEventFilter.Add(entity); } } } foreach (var value in targetBiota.BiotaPropertiesEventFilter) { if (sourceBiota.PropertiesEventFilter == null || !sourceBiota.PropertiesEventFilter.Any(p => p == value.Event)) { context.BiotaPropertiesEventFilter.Remove(value); } } // This is a cluster... because there is no key per record, just the record id. // That poses a problem because when we add a new record to be saved, we don't know what the record id is yet. // It's not until we try to save the record a second time that we will then have the database persisted record (with a valid id), and the entity record (that still has a DatabaseRecordId of 0) // We then need to match up the record that was saved with it's entity counterpart var processedSourceGenerators = new HashSet <ACE.Entity.Models.PropertiesGenerator>(); var usedTargetGenerators = new HashSet <BiotaPropertiesGenerator>(); if (sourceBiota.PropertiesGenerator != null) { // Process matched up records first foreach (var value in sourceBiota.PropertiesGenerator) { if (value.DatabaseRecordId == 0) { continue; } // Source record should already exist in the target BiotaPropertiesGenerator existingValue = targetBiota.BiotaPropertiesGenerator.FirstOrDefault(r => r.Id == value.DatabaseRecordId); // If the existingValue was not found, the database was likely modified outside of ACE after our last save if (existingValue == null) { continue; } CopyValueInto(value, existingValue); processedSourceGenerators.Add(value); usedTargetGenerators.Add(existingValue); } foreach (var value in sourceBiota.PropertiesGenerator) { if (processedSourceGenerators.Contains(value)) { continue; } // For simplicity, just find the first unused target BiotaPropertiesGenerator existingValue = targetBiota.BiotaPropertiesGenerator.FirstOrDefault(r => !usedTargetGenerators.Contains(r)); if (existingValue == null) { existingValue = new BiotaPropertiesGenerator { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesGenerator.Add(existingValue); } value.DatabaseRecordId = existingValue.Id; CopyValueInto(value, existingValue); //processedSourceGenerators.Add(value); usedTargetGenerators.Add(existingValue); } } foreach (var value in targetBiota.BiotaPropertiesGenerator) { if (!usedTargetGenerators.Contains(value)) { context.BiotaPropertiesGenerator.Remove(value); } } // Properties for creatures if (sourceBiota.PropertiesAttribute != null) { foreach (var kvp in sourceBiota.PropertiesAttribute) { BiotaPropertiesAttribute existingValue = targetBiota.BiotaPropertiesAttribute.FirstOrDefault(r => r.Type == (ushort)kvp.Key); if (existingValue == null) { existingValue = new BiotaPropertiesAttribute { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesAttribute.Add(existingValue); } existingValue.Type = (ushort)kvp.Key; existingValue.InitLevel = kvp.Value.InitLevel; existingValue.LevelFromCP = kvp.Value.LevelFromCP; existingValue.CPSpent = kvp.Value.CPSpent; } } foreach (var value in targetBiota.BiotaPropertiesAttribute) { if (sourceBiota.PropertiesAttribute == null || !sourceBiota.PropertiesAttribute.ContainsKey((PropertyAttribute)value.Type)) { context.BiotaPropertiesAttribute.Remove(value); } } if (sourceBiota.PropertiesAttribute2nd != null) { foreach (var kvp in sourceBiota.PropertiesAttribute2nd) { BiotaPropertiesAttribute2nd existingValue = targetBiota.BiotaPropertiesAttribute2nd.FirstOrDefault(r => r.Type == (ushort)kvp.Key); if (existingValue == null) { existingValue = new BiotaPropertiesAttribute2nd { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesAttribute2nd.Add(existingValue); } existingValue.Type = (ushort)kvp.Key; existingValue.InitLevel = kvp.Value.InitLevel; existingValue.LevelFromCP = kvp.Value.LevelFromCP; existingValue.CPSpent = kvp.Value.CPSpent; existingValue.CurrentLevel = kvp.Value.CurrentLevel; } } foreach (var value in targetBiota.BiotaPropertiesAttribute2nd) { if (sourceBiota.PropertiesAttribute2nd == null || !sourceBiota.PropertiesAttribute2nd.ContainsKey((PropertyAttribute2nd)value.Type)) { context.BiotaPropertiesAttribute2nd.Remove(value); } } if (sourceBiota.PropertiesBodyPart != null) { foreach (var kvp in sourceBiota.PropertiesBodyPart) { BiotaPropertiesBodyPart existingValue = targetBiota.BiotaPropertiesBodyPart.FirstOrDefault(r => r.Key == (uint)kvp.Key); if (existingValue == null) { existingValue = new BiotaPropertiesBodyPart { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesBodyPart.Add(existingValue); } existingValue.Key = (ushort)kvp.Key; existingValue.DType = (int)kvp.Value.DType; existingValue.DVal = kvp.Value.DVal; existingValue.DVar = kvp.Value.DVar; existingValue.BaseArmor = kvp.Value.BaseArmor; existingValue.ArmorVsSlash = kvp.Value.ArmorVsSlash; existingValue.ArmorVsPierce = kvp.Value.ArmorVsPierce; existingValue.ArmorVsBludgeon = kvp.Value.ArmorVsBludgeon; existingValue.ArmorVsCold = kvp.Value.ArmorVsCold; existingValue.ArmorVsFire = kvp.Value.ArmorVsFire; existingValue.ArmorVsAcid = kvp.Value.ArmorVsAcid; existingValue.ArmorVsElectric = kvp.Value.ArmorVsElectric; existingValue.ArmorVsNether = kvp.Value.ArmorVsNether; existingValue.BH = kvp.Value.BH; existingValue.HLF = kvp.Value.HLF; existingValue.MLF = kvp.Value.MLF; existingValue.LLF = kvp.Value.LLF; existingValue.HRF = kvp.Value.HRF; existingValue.MRF = kvp.Value.MRF; existingValue.LRF = kvp.Value.LRF; existingValue.HLB = kvp.Value.HLB; existingValue.MLB = kvp.Value.MLB; existingValue.LLB = kvp.Value.LLB; existingValue.HRB = kvp.Value.HRB; existingValue.MRB = kvp.Value.MRB; existingValue.LRB = kvp.Value.LRB; } } foreach (var value in targetBiota.BiotaPropertiesBodyPart) { if (sourceBiota.PropertiesBodyPart == null || !sourceBiota.PropertiesBodyPart.ContainsKey((CombatBodyPart)value.Key)) { context.BiotaPropertiesBodyPart.Remove(value); } } if (sourceBiota.PropertiesSkill != null) { foreach (var kvp in sourceBiota.PropertiesSkill) { BiotaPropertiesSkill existingValue = targetBiota.BiotaPropertiesSkill.FirstOrDefault(r => r.Type == (ushort)kvp.Key); if (existingValue == null) { existingValue = new BiotaPropertiesSkill { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesSkill.Add(existingValue); } existingValue.Type = (ushort)kvp.Key; existingValue.LevelFromPP = kvp.Value.LevelFromPP; existingValue.SAC = (uint)kvp.Value.SAC; existingValue.PP = kvp.Value.PP; existingValue.InitLevel = kvp.Value.InitLevel; existingValue.ResistanceAtLastCheck = kvp.Value.ResistanceAtLastCheck; existingValue.LastUsedTime = kvp.Value.LastUsedTime; } } foreach (var value in targetBiota.BiotaPropertiesSkill) { if (sourceBiota.PropertiesSkill == null || !sourceBiota.PropertiesSkill.ContainsKey((Skill)value.Type)) { context.BiotaPropertiesSkill.Remove(value); } } // Properties for books if (sourceBiota.PropertiesBook != null) { if (targetBiota.BiotaPropertiesBook == null) { targetBiota.BiotaPropertiesBook = new BiotaPropertiesBook { ObjectId = sourceBiota.Id, } } ; targetBiota.BiotaPropertiesBook.MaxNumPages = sourceBiota.PropertiesBook.MaxNumPages; targetBiota.BiotaPropertiesBook.MaxNumCharsPerPage = sourceBiota.PropertiesBook.MaxNumCharsPerPage; } else { if (targetBiota.BiotaPropertiesBook != null) { context.BiotaPropertiesBook.Remove(targetBiota.BiotaPropertiesBook); } } if (sourceBiota.PropertiesBookPageData != null) { for (int i = 0; i < sourceBiota.PropertiesBookPageData.Count; i++) { var value = sourceBiota.PropertiesBookPageData[i]; BiotaPropertiesBookPageData existingValue = targetBiota.BiotaPropertiesBookPageData.FirstOrDefault(r => r.PageId == i); if (existingValue == null) { existingValue = new BiotaPropertiesBookPageData { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesBookPageData.Add(existingValue); } existingValue.PageId = (uint)i; existingValue.AuthorId = value.AuthorId; existingValue.AuthorName = value.AuthorName; existingValue.AuthorAccount = value.AuthorAccount; existingValue.IgnoreAuthor = value.IgnoreAuthor; existingValue.PageText = value.PageText; } } foreach (var value in targetBiota.BiotaPropertiesBookPageData) { if (sourceBiota.PropertiesBookPageData == null || value.PageId >= sourceBiota.PropertiesBookPageData.Count) { context.BiotaPropertiesBookPageData.Remove(value); } } // Biota additions over Weenie if (sourceBiota.PropertiesAllegiance != null) { foreach (var kvp in sourceBiota.PropertiesAllegiance) { BiotaPropertiesAllegiance existingValue = targetBiota.BiotaPropertiesAllegiance.FirstOrDefault(r => r.CharacterId == kvp.Key); if (existingValue == null) { existingValue = new BiotaPropertiesAllegiance { AllegianceId = sourceBiota.Id }; targetBiota.BiotaPropertiesAllegiance.Add(existingValue); } existingValue.CharacterId = kvp.Key; existingValue.Banned = kvp.Value.Banned; existingValue.ApprovedVassal = kvp.Value.ApprovedVassal; } } foreach (var value in targetBiota.BiotaPropertiesAllegiance) { if (sourceBiota.PropertiesAllegiance == null || !sourceBiota.PropertiesAllegiance.ContainsKey(value.CharacterId)) { context.BiotaPropertiesAllegiance.Remove(value); } } if (sourceBiota.PropertiesEnchantmentRegistry != null) { foreach (var value in sourceBiota.PropertiesEnchantmentRegistry) { BiotaPropertiesEnchantmentRegistry existingValue = targetBiota.BiotaPropertiesEnchantmentRegistry.FirstOrDefault(r => r.SpellId == value.SpellId && r.LayerId == value.LayerId && r.CasterObjectId == value.CasterObjectId); if (existingValue == null) { existingValue = new BiotaPropertiesEnchantmentRegistry { ObjectId = sourceBiota.Id }; targetBiota.BiotaPropertiesEnchantmentRegistry.Add(existingValue); } existingValue.EnchantmentCategory = value.EnchantmentCategory; existingValue.SpellId = value.SpellId; existingValue.LayerId = value.LayerId; existingValue.HasSpellSetId = value.HasSpellSetId; existingValue.SpellCategory = (ushort)value.SpellCategory; existingValue.PowerLevel = value.PowerLevel; existingValue.StartTime = value.StartTime; existingValue.Duration = value.Duration; existingValue.CasterObjectId = value.CasterObjectId; existingValue.DegradeModifier = value.DegradeModifier; existingValue.DegradeLimit = value.DegradeLimit; existingValue.LastTimeDegraded = value.LastTimeDegraded; existingValue.StatModType = (uint)value.StatModType; existingValue.StatModKey = value.StatModKey; existingValue.StatModValue = value.StatModValue; existingValue.SpellSetId = (uint)value.SpellSetId; } } foreach (var value in targetBiota.BiotaPropertiesEnchantmentRegistry) { if (sourceBiota.PropertiesEnchantmentRegistry == null || !sourceBiota.PropertiesEnchantmentRegistry.Any(p => p.SpellId == value.SpellId && p.LayerId == value.LayerId && p.CasterObjectId == value.CasterObjectId)) { context.BiotaPropertiesEnchantmentRegistry.Remove(value); } } if (sourceBiota.HousePermissions != null) { foreach (var kvp in sourceBiota.HousePermissions) { HousePermission existingValue = targetBiota.HousePermission.FirstOrDefault(r => r.PlayerGuid == kvp.Key); if (existingValue == null) { existingValue = new HousePermission { HouseId = sourceBiota.Id }; targetBiota.HousePermission.Add(existingValue); } existingValue.PlayerGuid = kvp.Key; existingValue.Storage = kvp.Value; } } foreach (var value in targetBiota.HousePermission) { if (sourceBiota.HousePermissions == null || !sourceBiota.HousePermissions.ContainsKey(value.PlayerGuid)) { context.HousePermission.Remove(value); } } }
private void UpdateBiota(ShardDbContext context, Biota existingBiota, Biota biota) { // This pattern is described here: https://docs.microsoft.com/en-us/ef/core/saving/disconnected-entities // You'll notice though that we're not using the recommended: context.Entry(existingEntry).CurrentValues.SetValues(newEntry); // It is EXTREMLY slow. 4x or more slower. I suspect because it uses reflection to find the properties that the object contains // Manually setting the properties like we do below is the best case scenario for performance. However, it also has risks. // If we add columns to the schema and forget to add those changes here, changes to the biota may not propegate to the database. // Mag-nus 2018-08-18 context.Entry(existingBiota).CurrentValues.SetValues(biota); foreach (var value in biota.BiotaPropertiesAnimPart) { BiotaPropertiesAnimPart existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesAnimPart.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesAnimPart.Add(value); } else { existingValue.Index = value.Index; existingValue.AnimationId = value.AnimationId; existingValue.Order = value.Order; } } foreach (var value in existingBiota.BiotaPropertiesAnimPart) { if (!biota.BiotaPropertiesAnimPart.Any(p => p.Id == value.Id)) { context.BiotaPropertiesAnimPart.Remove(value); } } foreach (var value in biota.BiotaPropertiesAttribute) { BiotaPropertiesAttribute existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesAttribute.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesAttribute.Add(value); } else { existingValue.Type = value.Type; existingValue.InitLevel = value.InitLevel; existingValue.LevelFromCP = value.LevelFromCP; existingValue.CPSpent = value.CPSpent; } } foreach (var value in existingBiota.BiotaPropertiesAttribute) { if (!biota.BiotaPropertiesAttribute.Any(p => p.Id == value.Id)) { context.BiotaPropertiesAttribute.Remove(value); } } foreach (var value in biota.BiotaPropertiesAttribute2nd) { BiotaPropertiesAttribute2nd existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesAttribute2nd.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesAttribute2nd.Add(value); } else { existingValue.Type = value.Type; existingValue.InitLevel = value.InitLevel; existingValue.LevelFromCP = value.LevelFromCP; existingValue.CPSpent = value.CPSpent; existingValue.CurrentLevel = value.CurrentLevel; } } foreach (var value in existingBiota.BiotaPropertiesAttribute2nd) { if (!biota.BiotaPropertiesAttribute2nd.Any(p => p.Id == value.Id)) { context.BiotaPropertiesAttribute2nd.Remove(value); } } foreach (var value in biota.BiotaPropertiesBodyPart) { BiotaPropertiesBodyPart existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesBodyPart.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesBodyPart.Add(value); } else { existingValue.Key = value.Key; existingValue.DType = value.DType; existingValue.DVal = value.DVal; existingValue.DVar = value.DVar; existingValue.BaseArmor = value.BaseArmor; existingValue.ArmorVsSlash = value.ArmorVsSlash; existingValue.ArmorVsPierce = value.ArmorVsPierce; existingValue.ArmorVsBludgeon = value.ArmorVsBludgeon; existingValue.ArmorVsCold = value.ArmorVsCold; existingValue.ArmorVsFire = value.ArmorVsFire; existingValue.ArmorVsAcid = value.ArmorVsAcid; existingValue.ArmorVsElectric = value.ArmorVsElectric; existingValue.ArmorVsNether = value.ArmorVsNether; existingValue.BH = value.BH; existingValue.HLF = value.HLF; existingValue.MLF = value.MLF; existingValue.LLF = value.LLF; existingValue.HRF = value.HRF; existingValue.MRF = value.MRF; existingValue.LRF = value.LRF; existingValue.HLB = value.HLB; existingValue.MLB = value.MLB; existingValue.LLB = value.LLB; existingValue.HRB = value.HRB; existingValue.MRB = value.MRB; existingValue.LRB = value.LRB; } } foreach (var value in existingBiota.BiotaPropertiesBodyPart) { if (!biota.BiotaPropertiesBodyPart.Any(p => p.Id == value.Id)) { context.BiotaPropertiesBodyPart.Remove(value); } } if (biota.BiotaPropertiesBook != null) { if (existingBiota.BiotaPropertiesBook == null) { existingBiota.BiotaPropertiesBook = biota.BiotaPropertiesBook; } else { existingBiota.BiotaPropertiesBook.MaxNumPages = biota.BiotaPropertiesBook.MaxNumPages; existingBiota.BiotaPropertiesBook.MaxNumCharsPerPage = biota.BiotaPropertiesBook.MaxNumCharsPerPage; } } else { if (existingBiota.BiotaPropertiesBook != null) { context.BiotaPropertiesBook.Remove(existingBiota.BiotaPropertiesBook); } } foreach (var value in biota.BiotaPropertiesBookPageData) { BiotaPropertiesBookPageData existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesBookPageData.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesBookPageData.Add(value); } else { existingValue.PageId = value.PageId; existingValue.AuthorId = value.AuthorId; existingValue.AuthorName = value.AuthorName; existingValue.AuthorAccount = value.AuthorAccount; existingValue.IgnoreAuthor = value.IgnoreAuthor; existingValue.PageText = value.PageText; } } foreach (var value in existingBiota.BiotaPropertiesBookPageData) { if (!biota.BiotaPropertiesBookPageData.Any(p => p.Id == value.Id)) { context.BiotaPropertiesBookPageData.Remove(value); } } foreach (var value in biota.BiotaPropertiesBool) { BiotaPropertiesBool existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesBool.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesBool.Add(value); } else { existingValue.Type = value.Type; existingValue.Value = value.Value; } } foreach (var value in existingBiota.BiotaPropertiesBool) { if (!biota.BiotaPropertiesBool.Any(p => p.Id == value.Id)) { context.BiotaPropertiesBool.Remove(value); } } foreach (var value in biota.BiotaPropertiesCreateList) { BiotaPropertiesCreateList existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesCreateList.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesCreateList.Add(value); } else { existingValue.DestinationType = value.DestinationType; existingValue.WeenieClassId = value.WeenieClassId; existingValue.StackSize = value.StackSize; existingValue.Palette = value.Palette; existingValue.Shade = value.Shade; existingValue.TryToBond = value.TryToBond; } } foreach (var value in existingBiota.BiotaPropertiesCreateList) { if (!biota.BiotaPropertiesCreateList.Any(p => p.Id == value.Id)) { context.BiotaPropertiesCreateList.Remove(value); } } foreach (var value in biota.BiotaPropertiesDID) { BiotaPropertiesDID existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesDID.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesDID.Add(value); } else { existingValue.Type = value.Type; existingValue.Value = value.Value; } } foreach (var value in existingBiota.BiotaPropertiesDID) { if (!biota.BiotaPropertiesDID.Any(p => p.Id == value.Id)) { context.BiotaPropertiesDID.Remove(value); } } foreach (var value in biota.BiotaPropertiesEmote) { BiotaPropertiesEmote existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesEmote.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesEmote.Add(value); } else { existingValue.Category = value.Category; existingValue.Probability = value.Probability; existingValue.WeenieClassId = value.WeenieClassId; existingValue.Style = value.Style; existingValue.Substyle = value.Substyle; existingValue.Quest = value.Quest; existingValue.VendorType = value.VendorType; existingValue.MinHealth = value.MinHealth; existingValue.MaxHealth = value.MaxHealth; foreach (var value2 in value.BiotaPropertiesEmoteAction) { BiotaPropertiesEmoteAction existingValue2 = (value2.Id == 0 ? null : existingValue.BiotaPropertiesEmoteAction.FirstOrDefault(r => r.Id == value2.Id)); if (existingValue2 == null) { existingValue.BiotaPropertiesEmoteAction.Add(value2); } else { existingValue2.EmoteId = value2.EmoteId; existingValue2.Order = value2.Order; existingValue2.Type = value2.Type; existingValue2.Delay = value2.Delay; existingValue2.Extent = value2.Extent; existingValue2.Motion = value2.Motion; existingValue2.Message = value2.Message; existingValue2.TestString = value2.TestString; existingValue2.Min = value2.Min; existingValue2.Max = value2.Max; existingValue2.Min64 = value2.Min64; existingValue2.Max64 = value2.Max64; existingValue2.MinDbl = value2.MinDbl; existingValue2.MaxDbl = value2.MaxDbl; existingValue2.Stat = value2.Stat; existingValue2.Display = value2.Display; existingValue2.Amount = value2.Amount; existingValue2.Amount64 = value2.Amount64; existingValue2.HeroXP64 = value2.HeroXP64; existingValue2.Percent = value2.Percent; existingValue2.SpellId = value2.SpellId; existingValue2.WealthRating = value2.WealthRating; existingValue2.TreasureClass = value2.TreasureClass; existingValue2.TreasureType = value2.TreasureType; existingValue2.PScript = value2.PScript; existingValue2.Sound = value2.Sound; existingValue2.DestinationType = value2.DestinationType; existingValue2.WeenieClassId = value2.WeenieClassId; existingValue2.StackSize = value2.StackSize; existingValue2.Palette = value2.Palette; existingValue2.Shade = value2.Shade; existingValue2.TryToBond = value2.TryToBond; existingValue2.ObjCellId = value2.ObjCellId; existingValue2.OriginX = value2.OriginX; existingValue2.OriginY = value2.OriginY; existingValue2.OriginZ = value2.OriginZ; existingValue2.AnglesW = value2.AnglesW; existingValue2.AnglesX = value2.AnglesX; existingValue2.AnglesY = value2.AnglesY; existingValue2.AnglesZ = value2.AnglesZ; } } foreach (var value2 in value.BiotaPropertiesEmoteAction) { if (!existingValue.BiotaPropertiesEmoteAction.Any(p => p.Id == value2.Id)) { context.BiotaPropertiesEmoteAction.Remove(value2); } } } } foreach (var value in existingBiota.BiotaPropertiesEmote) { if (!biota.BiotaPropertiesEmote.Any(p => p.Id == value.Id)) { context.BiotaPropertiesEmote.Remove(value); } } foreach (var value in biota.BiotaPropertiesEnchantmentRegistry) { BiotaPropertiesEnchantmentRegistry existingValue = (value.ObjectId == 0 ? null : existingBiota.BiotaPropertiesEnchantmentRegistry.FirstOrDefault(r => r.ObjectId == value.ObjectId && r.SpellId == value.SpellId && r.LayerId == value.LayerId && r.CasterObjectId == value.CasterObjectId)); if (existingValue == null) { existingBiota.BiotaPropertiesEnchantmentRegistry.Add(value); } else { existingValue.EnchantmentCategory = value.EnchantmentCategory; existingValue.SpellId = value.SpellId; existingValue.LayerId = value.LayerId; existingValue.HasSpellSetId = value.HasSpellSetId; existingValue.SpellCategory = value.SpellCategory; existingValue.PowerLevel = value.PowerLevel; existingValue.StartTime = value.StartTime; existingValue.Duration = value.Duration; existingValue.CasterObjectId = value.CasterObjectId; existingValue.DegradeModifier = value.DegradeModifier; existingValue.DegradeLimit = value.DegradeLimit; existingValue.LastTimeDegraded = value.LastTimeDegraded; existingValue.StatModType = value.StatModType; existingValue.StatModKey = value.StatModKey; existingValue.StatModValue = value.StatModValue; existingValue.SpellSetId = value.SpellSetId; } } foreach (var value in existingBiota.BiotaPropertiesEnchantmentRegistry) { if (!biota.BiotaPropertiesEnchantmentRegistry.Any(p => p.ObjectId == value.ObjectId && p.SpellId == value.SpellId && p.LayerId == value.LayerId && p.CasterObjectId == value.CasterObjectId)) { context.BiotaPropertiesEnchantmentRegistry.Remove(value); } } foreach (var value in biota.BiotaPropertiesEventFilter) { BiotaPropertiesEventFilter existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesEventFilter.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesEventFilter.Add(value); } else { existingValue.Event = value.Event; } } foreach (var value in existingBiota.BiotaPropertiesEventFilter) { if (!biota.BiotaPropertiesEventFilter.Any(p => p.Id == value.Id)) { context.BiotaPropertiesEventFilter.Remove(value); } } foreach (var value in biota.BiotaPropertiesFloat) { BiotaPropertiesFloat existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesFloat.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesFloat.Add(value); } else { existingValue.Type = value.Type; existingValue.Value = value.Value; } } foreach (var value in existingBiota.BiotaPropertiesFloat) { if (!biota.BiotaPropertiesFloat.Any(p => p.Id == value.Id)) { context.BiotaPropertiesFloat.Remove(value); } } foreach (var value in biota.BiotaPropertiesGenerator) { BiotaPropertiesGenerator existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesGenerator.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesGenerator.Add(value); } else { existingValue.Probability = value.Probability; existingValue.WeenieClassId = value.WeenieClassId; existingValue.Delay = value.Delay; existingValue.InitCreate = value.InitCreate; existingValue.MaxCreate = value.MaxCreate; existingValue.WhenCreate = value.WhenCreate; existingValue.WhereCreate = value.WhereCreate; existingValue.StackSize = value.StackSize; existingValue.PaletteId = value.PaletteId; existingValue.Shade = value.Shade; existingValue.ObjCellId = value.ObjCellId; existingValue.OriginX = value.OriginX; existingValue.OriginY = value.OriginY; existingValue.OriginZ = value.OriginZ; existingValue.AnglesW = value.AnglesW; existingValue.AnglesX = value.AnglesX; existingValue.AnglesY = value.AnglesY; existingValue.AnglesZ = value.AnglesZ; } } foreach (var value in existingBiota.BiotaPropertiesGenerator) { if (!biota.BiotaPropertiesGenerator.Any(p => p.Id == value.Id)) { context.BiotaPropertiesGenerator.Remove(value); } } foreach (var value in biota.BiotaPropertiesIID) { BiotaPropertiesIID existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesIID.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesIID.Add(value); } else { existingValue.Type = value.Type; existingValue.Value = value.Value; } } foreach (var value in existingBiota.BiotaPropertiesIID) { if (!biota.BiotaPropertiesIID.Any(p => p.Id == value.Id)) { context.BiotaPropertiesIID.Remove(value); } } foreach (var value in biota.BiotaPropertiesInt) { BiotaPropertiesInt existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesInt.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesInt.Add(value); } else { existingValue.Type = value.Type; existingValue.Value = value.Value; } } foreach (var value in existingBiota.BiotaPropertiesInt) { if (!biota.BiotaPropertiesInt.Any(p => p.Id == value.Id)) { context.BiotaPropertiesInt.Remove(value); } } foreach (var value in biota.BiotaPropertiesInt64) { BiotaPropertiesInt64 existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesInt64.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesInt64.Add(value); } else { existingValue.Type = value.Type; existingValue.Value = value.Value; } } foreach (var value in existingBiota.BiotaPropertiesInt64) { if (!biota.BiotaPropertiesInt64.Any(p => p.Id == value.Id)) { context.BiotaPropertiesInt64.Remove(value); } } foreach (var value in biota.BiotaPropertiesPalette) { BiotaPropertiesPalette existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesPalette.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesPalette.Add(value); } else { existingValue.SubPaletteId = value.SubPaletteId; existingValue.Offset = value.Offset; existingValue.Length = value.Length; } } foreach (var value in existingBiota.BiotaPropertiesPalette) { if (!biota.BiotaPropertiesPalette.Any(p => p.Id == value.Id)) { context.BiotaPropertiesPalette.Remove(value); } } foreach (var value in biota.BiotaPropertiesPosition) { BiotaPropertiesPosition existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesPosition.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesPosition.Add(value); } else { existingValue.PositionType = value.PositionType; existingValue.ObjCellId = value.ObjCellId; existingValue.OriginX = value.OriginX; existingValue.OriginY = value.OriginY; existingValue.OriginZ = value.OriginZ; existingValue.AnglesW = value.AnglesW; existingValue.AnglesX = value.AnglesX; existingValue.AnglesY = value.AnglesY; existingValue.AnglesZ = value.AnglesZ; } } foreach (var value in existingBiota.BiotaPropertiesPosition) { if (!biota.BiotaPropertiesPosition.Any(p => p.Id == value.Id)) { context.BiotaPropertiesPosition.Remove(value); } } foreach (var value in biota.BiotaPropertiesSkill) { BiotaPropertiesSkill existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesSkill.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesSkill.Add(value); } else { existingValue.Type = value.Type; existingValue.LevelFromPP = value.LevelFromPP; existingValue.SAC = value.SAC; existingValue.PP = value.PP; existingValue.InitLevel = value.InitLevel; existingValue.ResistanceAtLastCheck = value.ResistanceAtLastCheck; existingValue.LastUsedTime = value.LastUsedTime; } } foreach (var value in existingBiota.BiotaPropertiesSkill) { if (!biota.BiotaPropertiesSkill.Any(p => p.Id == value.Id)) { context.BiotaPropertiesSkill.Remove(value); } } foreach (var value in biota.BiotaPropertiesSpellBook) { BiotaPropertiesSpellBook existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesSpellBook.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesSpellBook.Add(value); } else { existingValue.Spell = value.Spell; existingValue.Probability = value.Probability; } } foreach (var value in existingBiota.BiotaPropertiesSpellBook) { if (!biota.BiotaPropertiesSpellBook.Any(p => p.Id == value.Id)) { context.BiotaPropertiesSpellBook.Remove(value); } } foreach (var value in biota.BiotaPropertiesString) { BiotaPropertiesString existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesString.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesString.Add(value); } else { existingValue.Type = value.Type; existingValue.Value = value.Value; } } foreach (var value in existingBiota.BiotaPropertiesString) { if (!biota.BiotaPropertiesString.Any(p => p.Id == value.Id)) { context.BiotaPropertiesString.Remove(value); } } foreach (var value in biota.BiotaPropertiesTextureMap) { BiotaPropertiesTextureMap existingValue = (value.Id == 0 ? null : existingBiota.BiotaPropertiesTextureMap.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.BiotaPropertiesTextureMap.Add(value); } else { existingValue.Index = value.Index; existingValue.OldId = value.OldId; existingValue.NewId = value.NewId; existingValue.Order = value.Order; } } foreach (var value in existingBiota.BiotaPropertiesTextureMap) { if (!biota.BiotaPropertiesTextureMap.Any(p => p.Id == value.Id)) { context.BiotaPropertiesTextureMap.Remove(value); } } foreach (var value in biota.HousePermission) { HousePermission existingValue = (value.Id == 0 ? null : existingBiota.HousePermission.FirstOrDefault(r => r.Id == value.Id)); if (existingValue == null) { existingBiota.HousePermission.Add(value); } else { existingValue.PlayerGuid = value.PlayerGuid; existingValue.Storage = value.Storage; } } foreach (var value in existingBiota.HousePermission) { if (!biota.HousePermission.Any(p => p.Id == value.Id)) { context.HousePermission.Remove(value); } } }
public override bool SaveBiota(Biota biota, ReaderWriterLockSlim rwLock) { if (BiotaContexts.TryGetValue(biota, out var cachedContext)) { rwLock.EnterReadLock(); try { SetBiotaPopulatedCollections(biota); Exception firstException = null; retry: try { cachedContext.SaveChanges(); if (firstException != null) { log.Debug($"[DATABASE] SaveBiota 0x{biota.Id:X8}:{biota.GetProperty(PropertyString.Name)} retry succeeded after initial exception of: {firstException.GetFullMessage()}"); } return(true); } catch (Exception ex) { if (firstException == null) { firstException = ex; goto retry; } // Character name might be in use or some other fault log.Error($"[DATABASE] SaveBiota 0x{biota.Id:X8}:{biota.GetProperty(PropertyString.Name)} failed first attempt with exception: {firstException}"); log.Error($"[DATABASE] SaveBiota 0x{biota.Id:X8}:{biota.GetProperty(PropertyString.Name)} failed second attempt with exception: {ex}"); return(false); } } finally { rwLock.ExitReadLock(); } } if (ObjectGuid.IsPlayer(biota.Id)) { var context = new ShardDbContext(); BiotaContexts.Add(biota, context); rwLock.EnterReadLock(); try { SetBiotaPopulatedCollections(biota); context.Biota.Add(biota); Exception firstException = null; retry: try { context.SaveChanges(); if (firstException != null) { log.Debug($"[DATABASE] SaveBiota 0x{biota.Id:X8}:{biota.GetProperty(PropertyString.Name)} retry succeeded after initial exception of: {firstException.GetFullMessage()}"); } return(true); } catch (Exception ex) { if (firstException == null) { firstException = ex; goto retry; } // Character name might be in use or some other fault log.Error($"[DATABASE] SaveBiota 0x{biota.Id:X8}:{biota.GetProperty(PropertyString.Name)} failed first attempt with exception: {firstException}"); log.Error($"[DATABASE] SaveBiota 0x{biota.Id:X8}:{biota.GetProperty(PropertyString.Name)} failed second attempt with exception: {ex}"); return(false); } } finally { rwLock.ExitReadLock(); } } using (var context = new ShardDbContext()) { var existingBiota = GetBiota(context, biota.Id); rwLock.EnterReadLock(); try { SetBiotaPopulatedCollections(biota); if (existingBiota == null) { context.Biota.Add(biota); } else { UpdateBiota(context, existingBiota, biota); } Exception firstException = null; retry: try { context.SaveChanges(); if (firstException != null) { log.Debug($"[DATABASE] SaveBiota 0x{biota.Id:X8}:{biota.GetProperty(PropertyString.Name)} retry succeeded after initial exception of: {firstException.GetFullMessage()}"); } return(true); } catch (Exception ex) { if (firstException == null) { firstException = ex; goto retry; } // Character name might be in use or some other fault log.Error($"[DATABASE] SaveBiota 0x{biota.Id:X8}:{biota.GetProperty(PropertyString.Name)} failed first attempt with exception: {firstException}"); log.Error($"[DATABASE] SaveBiota 0x{biota.Id:X8}:{biota.GetProperty(PropertyString.Name)} failed second attempt with exception: {ex}"); return(false); } } finally { rwLock.ExitReadLock(); } } }
public static void HandleVerifySkillCredits(Session session, params string[] parameters) { var players = PlayerManager.GetAllOffline(); var fix = parameters.Length > 0 && parameters[0].Equals("fix"); var fixStr = fix ? " -- fixed" : ""; var foundIssues = false; using (var ctx = new ShardDbContext()) { foreach (var player in players) { // skip admins if (player.Account == null || player.Account.AccessLevel == (uint)AccessLevel.Admin) { continue; } // player starts with 52 skill credits var startCredits = 52; // skills that cannot be untrained: arcane lore, jump, loyalty, magic defense, run, salvaging // all of these have '0' cost to train, except for arcane lore, which has 4 (seems to be an outlier?) startCredits += 4; var levelCredits = GetAdditionalCredits(player.Level ?? 1); var totalCredits = startCredits + levelCredits; var used = 0; foreach (var skill in player.Biota.BiotaPropertiesSkill) { var sac = (SkillAdvancementClass)skill.SAC; if (sac < SkillAdvancementClass.Trained) { continue; } if (!DatManager.PortalDat.SkillTable.SkillBaseHash.TryGetValue(skill.Type, out var skillInfo)) { Console.WriteLine($"{player.Name}.HandleVerifySkillCredits({(Skill)skill.Type}): unknown skill"); continue; } //Console.WriteLine($"{(Skill)skill.Type} trained cost: {skillInfo.TrainedCost}, spec cost: {skillInfo.SpecializedCost}"); used += skillInfo.TrainedCost; if (sac == SkillAdvancementClass.Specialized) { switch ((Skill)skill.Type) { // these can only be speced through augs, they have >= 999 in the spec data case Skill.ArmorTinkering: case Skill.ItemTinkering: case Skill.MagicItemTinkering: case Skill.WeaponTinkering: case Skill.Salvaging: continue; } used += skillInfo.UpgradeCostFromTrainedToSpecialized; } } // 2 possible skill credits from quests // - ChasingOswaldDone // - ArantahKill1 (no 'turned in' stamp, only if given figurine?) var questCredits = ctx.CharacterPropertiesQuestRegistry.Count(i => i.CharacterId == player.Guid.Full && (i.QuestName.Equals("ChasingOswaldDone") || i.QuestName.Equals("ArantahKill1"))); totalCredits += questCredits; // TODO: 2 lum augs var targetCredits = totalCredits - used; var targetMsg = $"{player.Name} should have {targetCredits} available skill credits"; if (targetCredits < 0) { // if the player has already spent more skill credits than they should have, // unfortunately this situation requires a partial reset.. Console.WriteLine($"{targetMsg}. To fix this situation, trained skill reset will need to be applied{fixStr}"); foundIssues = true; if (fix) { UntrainSkills(player, targetCredits); } continue; } var availableCredits = player.GetProperty(PropertyInt.AvailableSkillCredits) ?? 0; if (availableCredits != targetCredits) { Console.WriteLine($"{targetMsg}, but they have {availableCredits}{fixStr}"); foundIssues = true; if (fix) { player.SetProperty(PropertyInt.AvailableSkillCredits, targetCredits); player.SaveBiotaToDatabase(); } } } } if (!fix && foundIssues) { Console.WriteLine($"Dry run completed. Type 'verify-skill-credits fix' to fix any issues."); } if (!foundIssues) { Console.WriteLine($"Verified skill credits for {players.Count:N0} players"); } }
public static void HandleFixBiotaEmoteDelay(Session session, params string[] parameters) { if (parameters.Length == 0) { CommandHandlerHelper.WriteOutputInfo(session, "This command is intended to be run while the world is in offline mode, or there are 0 players connected."); CommandHandlerHelper.WriteOutputInfo(session, "To run this fix, type fix-biota-emote-delay fix"); return; } var fix = parameters[0].Equals("fix", StringComparison.OrdinalIgnoreCase); CommandHandlerHelper.WriteOutputInfo(session, "Building weenie emote cache"); var weenieEmoteCache = BuildWeenieEmoteCache(); CommandHandlerHelper.WriteOutputInfo(session, $"Found {weenieEmoteCache.Count:N0} weenie templates w/ emote actions with delay 0"); using (var ctx = new ShardDbContext()) { CommandHandlerHelper.WriteOutputInfo(session, $"Finding biotas for these wcids"); var biotas = ctx.Biota.Where(i => weenieEmoteCache.ContainsKey(i.WeenieClassId)).ToList(); var distinct = biotas.Select(i => i.WeenieClassId).Distinct(); var counts = new Dictionary <uint, uint>(); foreach (var biota in biotas) { if (!counts.ContainsKey(biota.WeenieClassId)) { counts[biota.WeenieClassId] = 1; } else { counts[biota.WeenieClassId]++; } } CommandHandlerHelper.WriteOutputInfo(session, $"Found {biotas.Count} biotas matching {distinct.Count()} distinct wcids"); foreach (var kvp in counts.OrderBy(i => i.Key)) { CommandHandlerHelper.WriteOutputInfo(session, $"{kvp.Key} - {(WeenieClassName)kvp.Key} ({kvp.Value})"); } if (!fix) { CommandHandlerHelper.WriteOutputInfo(session, $"Dry run completed"); return; } var totalUpdated = 0; foreach (var biota in biotas) { bool updated = false; var query = from emote in ctx.BiotaPropertiesEmote join action in ctx.BiotaPropertiesEmoteAction on emote.Id equals action.EmoteId where emote.ObjectId == biota.Id && action.Delay == 1.0f select new { Emote = emote, Action = action }; var emoteActions = query.ToList(); foreach (var emoteAction in emoteActions) { var emote = emoteAction.Emote; var action = emoteAction.Action; // ensure this delay 1 should be delay 0 var hash = CalculateEmoteHash(emote); var weenieEmotes = weenieEmoteCache[biota.WeenieClassId]; if (!weenieEmotes.TryGetValue(hash, out var list)) { //CommandHandlerHelper.WriteOutputInfo(session, $"Skipping emote for {biota.WeenieClassId} not found in hash list"); continue; } if (!list.Contains(action.Order)) { //CommandHandlerHelper.WriteOutputInfo(session, $"Skipping emote for {biota.WeenieClassId} not found in action list"); continue; } // confirmed match, update delay 1 -> 0 action.Delay = 0.0f; updated = true; } if (updated) { CommandHandlerHelper.WriteOutputInfo(session, $"Fixed shard object {biota.Id:X8} of type {biota.WeenieClassId} - {(WeenieClassName)biota.WeenieClassId}"); totalUpdated++; } } ctx.SaveChanges(); CommandHandlerHelper.WriteOutputInfo(session, $"Completed successfully, fixed {totalUpdated} shard items"); } }
public bool SaveBiota(Biota biota, ReaderWriterLockSlim rwLock) { if (BiotaContexts.TryGetValue(biota, out var cachedContext)) { rwLock.EnterReadLock(); try { SetBiotaPopulatedCollections(biota); Exception firstException = null; retry: try { cachedContext.SaveChanges(); if (firstException != null) { log.Debug($"SaveBiota retry succeeded after initial exception of: {firstException.GetFullMessage()}"); } return(true); } catch (Exception ex) { if (firstException == null) { firstException = ex; goto retry; } // Character name might be in use or some other fault log.Error($"SaveBiota failed first attempt with exception: {firstException}"); log.Error($"SaveBiota failed second attempt with exception: {ex}"); return(false); } } finally { rwLock.ExitReadLock(); } } var context = new ShardDbContext(); BiotaContexts.Add(biota, context); rwLock.EnterReadLock(); try { SetBiotaPopulatedCollections(biota); context.Biota.Add(biota); Exception firstException = null; retry: try { context.SaveChanges(); if (firstException != null) { log.Debug($"SaveBiota retry succeeded after initial exception of: {firstException.GetFullMessage()}"); } return(true); } catch (Exception ex) { if (firstException == null) { firstException = ex; goto retry; } // Character name might be in use or some other fault log.Error($"SaveBiota failed first attempt with exception: {firstException}"); log.Error($"SaveBiota failed second attempt with exception: {ex}"); return(false); } } finally { rwLock.ExitReadLock(); } }
public CategoriesController(ServiceFactory serviceFactory, IMapper iMapper) { _context = serviceFactory.Context; _iMapper = iMapper; }
public static void PurgeCharacter(ShardDbContext context, uint characterId, out int charactersPurged, out int playerBiotasPurged, out int possessionsPurged) { charactersPurged = 0; playerBiotasPurged = 0; possessionsPurged = 0; // First purge the inventory var inventoryBiotas = GetInventoryBiotas(context, characterId, true); foreach (var biota in inventoryBiotas) { context.Biota.Remove(biota); possessionsPurged++; } // Then the wielded items var wieldedGuids = GetWieldedGuids(context, characterId); foreach (var guid in wieldedGuids) { var stub = new Biota { Id = guid }; context.Biota.Attach(stub); context.Biota.Remove(stub); possessionsPurged++; } // Second to last, the payer biota if (context.Biota.Any(r => r.Id == characterId)) { var stub = new Biota { Id = characterId }; context.Biota.Attach(stub); context.Biota.Remove(stub); playerBiotasPurged++; } // Lastly, the character record var character = context.Character.FirstOrDefault(r => r.Id == characterId); if (character != null) { context.Character.Remove(character); charactersPurged++; } if (character != null) { log.Debug($"[DATABASE][PURGE] Character 0x{characterId:X8}:{character.Name}, deleted on {Common.Time.GetDateTimeFromTimestamp(character.DeleteTime).ToLocalTime()}, and {possessionsPurged} of their possessions has been purged."); } else { log.Debug($"[DATABASE][PURGE] Character 0x{characterId:X8} and {possessionsPurged} of their possessions has been purged."); } try { context.SaveChanges(); } catch (Exception ex) { // Character name might be in use or some other fault log.Error($"PurgeCharacter 0x{characterId:X8} failed with exception: {ex}"); } }
public virtual Biota GetBiota(ShardDbContext context, uint id, bool doNotAddToCache = false) { var biota = context.Biota .FirstOrDefault(r => r.Id == id); if (biota == null) { return(null); } PopulatedCollectionFlags populatedCollectionFlags = (PopulatedCollectionFlags)biota.PopulatedCollectionFlags; // todo: There are gains to be had here if we can conditionally perform mulitple .Include (.Where) statements in a single query. // todo: Until I figure out how to do that, this is still pretty good. Mag-nus 2018-08-10 if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesAnimPart)) { biota.BiotaPropertiesAnimPart = context.BiotaPropertiesAnimPart.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesAttribute)) { biota.BiotaPropertiesAttribute = context.BiotaPropertiesAttribute.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesAttribute2nd)) { biota.BiotaPropertiesAttribute2nd = context.BiotaPropertiesAttribute2nd.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesBodyPart)) { biota.BiotaPropertiesBodyPart = context.BiotaPropertiesBodyPart.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesBook)) { biota.BiotaPropertiesBook = context.BiotaPropertiesBook.FirstOrDefault(r => r.ObjectId == biota.Id); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesBookPageData)) { biota.BiotaPropertiesBookPageData = context.BiotaPropertiesBookPageData.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesBool)) { biota.BiotaPropertiesBool = context.BiotaPropertiesBool.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesCreateList)) { biota.BiotaPropertiesCreateList = context.BiotaPropertiesCreateList.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesDID)) { biota.BiotaPropertiesDID = context.BiotaPropertiesDID.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesEmote)) { biota.BiotaPropertiesEmote = context.BiotaPropertiesEmote.Include(r => r.BiotaPropertiesEmoteAction).Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesEnchantmentRegistry)) { biota.BiotaPropertiesEnchantmentRegistry = context.BiotaPropertiesEnchantmentRegistry.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesEventFilter)) { biota.BiotaPropertiesEventFilter = context.BiotaPropertiesEventFilter.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesFloat)) { biota.BiotaPropertiesFloat = context.BiotaPropertiesFloat.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesGenerator)) { biota.BiotaPropertiesGenerator = context.BiotaPropertiesGenerator.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesIID)) { biota.BiotaPropertiesIID = context.BiotaPropertiesIID.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesInt)) { biota.BiotaPropertiesInt = context.BiotaPropertiesInt.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesInt64)) { biota.BiotaPropertiesInt64 = context.BiotaPropertiesInt64.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesPalette)) { biota.BiotaPropertiesPalette = context.BiotaPropertiesPalette.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesPosition)) { biota.BiotaPropertiesPosition = context.BiotaPropertiesPosition.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesSkill)) { biota.BiotaPropertiesSkill = context.BiotaPropertiesSkill.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesSpellBook)) { biota.BiotaPropertiesSpellBook = context.BiotaPropertiesSpellBook.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesString)) { biota.BiotaPropertiesString = context.BiotaPropertiesString.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesTextureMap)) { biota.BiotaPropertiesTextureMap = context.BiotaPropertiesTextureMap.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.HousePermission)) { biota.HousePermission = context.HousePermission.Where(r => r.HouseId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesAllegiance)) { biota.BiotaPropertiesAllegiance = context.BiotaPropertiesAllegiance.Where(r => r.AllegianceId == biota.Id).ToList(); } return(biota); }
public override bool RemoveBiota(Biota biota, ReaderWriterLockSlim rwLock) { if (BiotaContexts.TryGetValue(biota, out var cachedContext)) { BiotaContexts.Remove(biota); rwLock.EnterReadLock(); try { cachedContext.Biota.Remove(biota); Exception firstException = null; retry: try { cachedContext.SaveChanges(); if (firstException != null) { log.Debug($"[DATABASE] RemoveBiota 0x{biota.Id:X8}:{biota.GetProperty(PropertyString.Name)} retry succeeded after initial exception of: {firstException.GetFullMessage()}"); } return(true); } catch (Exception ex) { if (firstException == null) { firstException = ex; goto retry; } // Character name might be in use or some other fault log.Error($"[DATABASE] RemoveBiota 0x{biota.Id:X8}:{biota.GetProperty(PropertyString.Name)} failed first attempt with exception: {firstException}"); log.Error($"[DATABASE] RemoveBiota 0x{biota.Id:X8}:{biota.GetProperty(PropertyString.Name)} failed second attempt with exception: {ex}"); return(false); } } finally { rwLock.ExitReadLock(); cachedContext.Dispose(); } } if (!ObjectGuid.IsPlayer(biota.Id)) { using (var context = new ShardDbContext()) { var existingBiota = context.Biota .AsNoTracking() .FirstOrDefault(r => r.Id == biota.Id); if (existingBiota == null) { return(true); } rwLock.EnterWriteLock(); try { context.Biota.Remove(biota); Exception firstException = null; retry: try { context.SaveChanges(); if (firstException != null) { log.Debug($"[DATABASE] RemoveBiota 0x{biota.Id:X8}:{biota.GetProperty(PropertyString.Name)} retry succeeded after initial exception of: {firstException.GetFullMessage()}"); } return(true); } catch (Exception ex) { if (firstException == null) { firstException = ex; goto retry; } // Character name might be in use or some other fault log.Error($"[DATABASE] RemoveBiota 0x{biota.Id:X8}:{biota.GetProperty(PropertyString.Name)} failed first attempt with exception: {firstException}"); log.Error($"[DATABASE] RemoveBiota 0x{biota.Id:X8}:{biota.GetProperty(PropertyString.Name)} failed second attempt with exception: {ex}"); return(false); } } finally { rwLock.ExitWriteLock(); } } } // If we got here, the biota didn't come from the database through this class. // Most likely, it doesn't exist in the database, so, no need to remove. return(true); }
public virtual Biota GetBiota(uint id, bool doNotAddToCache = false) { using (var context = new ShardDbContext()) return(GetBiota(context, id, doNotAddToCache)); }
public static void ConsolidateBiotaGuids(uint startingGuid, bool tryNotToBreakPlugins, bool skipUserInputAfterWarning, out int numberOfBiotasConsolidated, out int numberOfBiotasSkipped, out int numberOfErrors) { log.Info($"Consolidating biotas, starting at guid 0x{startingGuid:X8}, tryNotToBreakPlugins: {tryNotToBreakPlugins}..."); Thread.Sleep(1000); // Give the logger type to flush to the client so that our output lines up in order Console.WriteLine("!!! Do not proceed unless you have backed up your shard database first !!!"); Console.WriteLine("In the event of any failure, you may be asked to rollback your shard database."); if (!skipUserInputAfterWarning) { Console.WriteLine("Press any key to proceed, or abort the process to quit."); Console.ReadLine(); } Console.WriteLine(".... hold on to your butts..."); if (startingGuid < ObjectGuid.DynamicMin) { throw new Exception($"startingGuid cannot be lower than ObjectGuid.DynamicMin (0x{ObjectGuid.DynamicMin:X8})"); } int counter = 0; int numOfBiotasConsolidated = 0; int numOfBiotasSkipped = 0; int numOfErrors = 0; var shardDatabase = new ShardDatabase(); var biotaCount = shardDatabase.GetBiotaCount(); var sequenceGaps = shardDatabase.GetSequenceGaps(ObjectGuid.DynamicMin, (uint)biotaCount); var availableIDs = new LinkedList <(uint start, uint end)>(sequenceGaps); List <Biota> partialBiotas; using (var context = new ShardDbContext()) { context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; partialBiotas = context.Biota.Where(r => r.Id >= startingGuid).OrderByDescending(r => r.Id).ToList(); } var idConversions = new ConcurrentDictionary <uint, uint>(); // Process ConsolidatableBasicWeenieTypes first Parallel.ForEach(partialBiotas, ConfigManager.Config.Server.Threading.DatabaseParallelOptions, partialBiota => { try { if (numOfErrors > 0) { return; } if (!ConsolidatableBasicWeenieTypes.Contains((WeenieType)partialBiota.WeenieType)) { return; } // Get the original biota var fullBiota = shardDatabase.GetBiota(partialBiota.Id, true); if (fullBiota == null) { Interlocked.Increment(ref numOfErrors); log.Warn($"Failed to get biota with id 0x{partialBiota.Id:X8} from the database. This shouldn't happen. It also shouldn't require a rollback."); return; } if (tryNotToBreakPlugins && MightBreakPlugins(fullBiota)) { Interlocked.Increment(ref numOfBiotasSkipped); return; } // Get the next available id uint newId = 0; lock (availableIDs) { if (availableIDs.First != null) { var id = availableIDs.First.Value.start; if (availableIDs.First.Value.start == availableIDs.First.Value.end) { availableIDs.RemoveFirst(); } else { availableIDs.First.Value = (availableIDs.First.Value.start + 1, availableIDs.First.Value.end); }
public static void PurgeCharacter(ShardDbContext context, uint characterId, out int charactersPurged, out int playerBiotasPurged, out int possessionsPurged, string reason = null) { charactersPurged = 0; playerBiotasPurged = 0; possessionsPurged = 0; // First purge the inventory var inventoryBiotas = GetInventoryBiotas(context, characterId, true); foreach (var biota in inventoryBiotas) { context.Biota.Remove(biota); possessionsPurged++; } // Then the wielded items var wieldedGuids = GetWieldedGuids(context, characterId); foreach (var guid in wieldedGuids) { var stub = new Biota { Id = guid }; context.Biota.Attach(stub); context.Biota.Remove(stub); possessionsPurged++; } // Second to last, the payer biota if (context.Biota.Any(r => r.Id == characterId)) { var stub = new Biota { Id = characterId }; context.Biota.Attach(stub); context.Biota.Remove(stub); playerBiotasPurged++; } // Lastly, the character record var character = context.Character.FirstOrDefault(r => r.Id == characterId); if (character != null) { context.Character.Remove(character); charactersPurged++; } var message = $"[DATABASE][PURGE] Character 0x{characterId:X8}"; if (character != null) { message += $":{character.Name}, deleted on {Common.Time.GetDateTimeFromTimestamp(character.DeleteTime).ToLocalTime()}"; } message += $", and {possessionsPurged} of their possessions has been purged."; if (!String.IsNullOrWhiteSpace(reason)) { message += $" Reason: {reason}."; } log.Debug(message); try { context.SaveChanges(); } catch (Exception ex) { log.Error($"[DATABASE][PURGE] PurgeCharacter 0x{characterId:X8} failed with exception: {ex}"); } }
public virtual Biota GetBiota(ShardDbContext context, uint id, bool doNotAddToCache = false) { var biota = context.Biota .FirstOrDefault(r => r.Id == id); if (biota == null) { return(null); } PopulatedCollectionFlags populatedCollectionFlags = (PopulatedCollectionFlags)biota.PopulatedCollectionFlags; if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesAnimPart)) { biota.BiotaPropertiesAnimPart = context.BiotaPropertiesAnimPart.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesAttribute)) { biota.BiotaPropertiesAttribute = context.BiotaPropertiesAttribute.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesAttribute2nd)) { biota.BiotaPropertiesAttribute2nd = context.BiotaPropertiesAttribute2nd.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesBodyPart)) { biota.BiotaPropertiesBodyPart = context.BiotaPropertiesBodyPart.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesBook)) { biota.BiotaPropertiesBook = context.BiotaPropertiesBook.FirstOrDefault(r => r.ObjectId == biota.Id); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesBookPageData)) { biota.BiotaPropertiesBookPageData = context.BiotaPropertiesBookPageData.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesBool)) { biota.BiotaPropertiesBool = context.BiotaPropertiesBool.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesCreateList)) { biota.BiotaPropertiesCreateList = context.BiotaPropertiesCreateList.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesDID)) { biota.BiotaPropertiesDID = context.BiotaPropertiesDID.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesEmote)) { biota.BiotaPropertiesEmote = context.BiotaPropertiesEmote.Include(r => r.BiotaPropertiesEmoteAction).Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesEnchantmentRegistry)) { biota.BiotaPropertiesEnchantmentRegistry = context.BiotaPropertiesEnchantmentRegistry.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesEventFilter)) { biota.BiotaPropertiesEventFilter = context.BiotaPropertiesEventFilter.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesFloat)) { biota.BiotaPropertiesFloat = context.BiotaPropertiesFloat.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesGenerator)) { biota.BiotaPropertiesGenerator = context.BiotaPropertiesGenerator.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesIID)) { biota.BiotaPropertiesIID = context.BiotaPropertiesIID.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesInt)) { biota.BiotaPropertiesInt = context.BiotaPropertiesInt.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesInt64)) { biota.BiotaPropertiesInt64 = context.BiotaPropertiesInt64.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesPalette)) { biota.BiotaPropertiesPalette = context.BiotaPropertiesPalette.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesPosition)) { biota.BiotaPropertiesPosition = context.BiotaPropertiesPosition.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesSkill)) { biota.BiotaPropertiesSkill = context.BiotaPropertiesSkill.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesSpellBook)) { biota.BiotaPropertiesSpellBook = context.BiotaPropertiesSpellBook.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesString)) { biota.BiotaPropertiesString = context.BiotaPropertiesString.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesTextureMap)) { biota.BiotaPropertiesTextureMap = context.BiotaPropertiesTextureMap.Where(r => r.ObjectId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.HousePermission)) { biota.HousePermission = context.HousePermission.Where(r => r.HouseId == biota.Id).ToList(); } if (populatedCollectionFlags.HasFlag(PopulatedCollectionFlags.BiotaPropertiesAllegiance)) { biota.BiotaPropertiesAllegiance = context.BiotaPropertiesAllegiance.Where(r => r.AllegianceId == biota.Id).ToList(); } return(biota); }
public ConfigPropertiesString GetString(string key) { using (var context = new ShardDbContext()) return(context.ConfigPropertiesString.AsNoTracking().FirstOrDefault(r => r.Key == key)); }
public bool AddBiota(Biota biota) { using (var context = new ShardDbContext()) return(AddBiota(context, biota)); }
public List <ConfigPropertiesDouble> GetAllDoubles() { using (var context = new ShardDbContext()) return(context.ConfigPropertiesDouble.AsNoTracking().ToList()); }
public bool AddBiotas(IEnumerable <Biota> biotas) { using (var context = new ShardDbContext()) return(AddBiotas(context, biotas)); }
public bool StringExists(string key) { using (var context = new ShardDbContext()) return(context.ConfigPropertiesString.Any(r => r.Key == key)); }
/// <summary> /// Use this method when you know if the biota is a player or not. /// Player biotas reference additional tables. Knowing if the biota is a player can significantly improve the query perofrmance. /// </summary> private static Biota GetBiota(ShardDbContext context, uint id, bool isPlayer) { if (isPlayer) { return(context.Biota //.Include(r => r.BiotaPropertiesAnimPart) .Include(r => r.BiotaPropertiesAttribute) .Include(r => r.BiotaPropertiesAttribute2nd) .Include(r => r.BiotaPropertiesBodyPart) //.Include(r => r.BiotaPropertiesBook) //.Include(r => r.BiotaPropertiesBookPageData) .Include(r => r.BiotaPropertiesBool) .Include(r => r.BiotaPropertiesContract) //.Include(r => r.BiotaPropertiesCreateList) .Include(r => r.BiotaPropertiesDID) //.Include(r => r.BiotaPropertiesEmote).ThenInclude(emote => emote.BiotaPropertiesEmoteAction) //.Include(r => r.BiotaPropertiesEmoteAction) //.Include(r => r.BiotaPropertiesEventFilter) .Include(r => r.BiotaPropertiesFloat) //.Include(r => r.BiotaPropertiesFriendListFriend) .Include(r => r.BiotaPropertiesFriendListObject) //.Include(r => r.BiotaPropertiesGenerator) .Include(r => r.BiotaPropertiesIID) .Include(r => r.BiotaPropertiesInt) .Include(r => r.BiotaPropertiesInt64) //.Include(r => r.BiotaPropertiesPalette) .Include(r => r.BiotaPropertiesPosition) .Include(r => r.BiotaPropertiesShortcutBarObject) .Include(r => r.BiotaPropertiesSkill) .Include(r => r.BiotaPropertiesSpellBar) .Include(r => r.BiotaPropertiesSpellBook) .Include(r => r.BiotaPropertiesString) //.Include(r => r.BiotaPropertiesTextureMap) .FirstOrDefault(r => r.Id == id)); } // Base properties for every biota (ACBaseQualities) var biota = context.Biota .Include(r => r.BiotaPropertiesBool) .Include(r => r.BiotaPropertiesDID) .Include(r => r.BiotaPropertiesFloat) .Include(r => r.BiotaPropertiesIID) .Include(r => r.BiotaPropertiesInt) .Include(r => r.BiotaPropertiesInt64) .Include(r => r.BiotaPropertiesPosition) .Include(r => r.BiotaPropertiesString) .FirstOrDefault(r => r.Id == id); if (biota == null) { return(null); } var weenieType = (WeenieType)biota.WeenieType; bool isCreature = weenieType == WeenieType.Creature || weenieType == WeenieType.Cow || weenieType == WeenieType.Sentinel || weenieType == WeenieType.Admin || weenieType == WeenieType.Vendor; biota.BiotaPropertiesAnimPart = context.BiotaPropertiesAnimPart.Where(r => r.ObjectId == biota.Id).ToList(); if (isCreature) { biota.BiotaPropertiesAttribute = context.BiotaPropertiesAttribute.Where(r => r.ObjectId == biota.Id).ToList(); biota.BiotaPropertiesAttribute2nd = context.BiotaPropertiesAttribute2nd.Where(r => r.ObjectId == biota.Id).ToList(); biota.BiotaPropertiesBodyPart = context.BiotaPropertiesBodyPart.Where(r => r.ObjectId == biota.Id).ToList(); } if (weenieType == WeenieType.Book) { biota.BiotaPropertiesBook = context.BiotaPropertiesBook.FirstOrDefault(r => r.ObjectId == biota.Id); biota.BiotaPropertiesBookPageData = context.BiotaPropertiesBookPageData.Where(r => r.ObjectId == biota.Id).ToList(); } // Player only //biota.BiotaPropertiesContract = context.BiotaPropertiesContract.Where(r => r.ObjectId == biota.Id).ToList(); biota.BiotaPropertiesCreateList = context.BiotaPropertiesCreateList.Where(r => r.ObjectId == biota.Id).ToList(); biota.BiotaPropertiesEmote = context.BiotaPropertiesEmote.Where(r => r.ObjectId == biota.Id).ToList(); biota.BiotaPropertiesEmoteAction = context.BiotaPropertiesEmoteAction.Where(r => r.ObjectId == biota.Id).ToList(); biota.BiotaPropertiesEventFilter = context.BiotaPropertiesEventFilter.Where(r => r.ObjectId == biota.Id).ToList(); // Player only //biota.BiotaPropertiesFriendListFriend = context.BiotaPropertiesFriendList.Where(r => r.FriendId == biota.Id).ToList(); //biota.BiotaPropertiesFriendListObject = context.BiotaPropertiesFriendList.Where(r => r.ObjectId == biota.Id).ToList(); biota.BiotaPropertiesGenerator = context.BiotaPropertiesGenerator.Where(r => r.ObjectId == biota.Id).ToList(); biota.BiotaPropertiesPalette = context.BiotaPropertiesPalette.Where(r => r.ObjectId == biota.Id).ToList(); // Player only //biota.BiotaPropertiesShortcutBarObject = context.BiotaPropertiesShortcutBar.Where(r => r.ObjectId == biota.Id).ToList(); if (isCreature) { biota.BiotaPropertiesSkill = context.BiotaPropertiesSkill.Where(r => r.ObjectId == biota.Id).ToList(); } // Player only //biota.BiotaPropertiesSpellBar = context.BiotaPropertiesSpellBar.Where(r => r.ObjectId == biota.Id).ToList(); biota.BiotaPropertiesSpellBook = context.BiotaPropertiesSpellBook.Where(r => r.ObjectId == biota.Id).ToList(); biota.BiotaPropertiesTextureMap = context.BiotaPropertiesTextureMap.Where(r => r.ObjectId == biota.Id).ToList(); return(biota); }
public static void HandleFixShortcutBars(Session session, params string[] parameters) { Console.WriteLine(); Console.WriteLine("This command will attempt to fix duplicate shortcuts found in player shortcut bars. Unless explictly indicated, command will dry run only"); Console.WriteLine("If the command outputs nothing or errors, you are ready to proceed with updating your shard db with 2019-04-17-00-Character_Shortcut_Changes.sql script"); Console.WriteLine(); var execute = false; if (parameters.Length < 1) { Console.WriteLine("This will be a dry run and show which characters that would be affected. To perform fix, please use command: fix-shortcut-bars execute"); } else if (parameters[0].ToLower() == "execute") { execute = true; } else { Console.WriteLine("Please use command fix-shortcut-bars execute"); } using (var ctx = new ShardDbContext()) { var results = ctx.CharacterPropertiesShortcutBar .FromSql("SELECT * FROM character_properties_shortcut_bar ORDER BY character_Id, shortcut_Bar_Index, id") .ToList(); var sqlCommands = new List <string>(); uint characterId = 0; string playerName = null; var idxToObj = new Dictionary <uint, uint>(); var objToIdx = new Dictionary <uint, uint>(); var buggedChar = false; var buggedPlayerCount = 0; foreach (var result in results) { if (characterId != result.CharacterId) { if (buggedChar) { buggedPlayerCount++; Console.WriteLine($"Player {playerName} ({characterId}) was found to have errors in their shortcuts."); sqlCommands.AddRange(OutputShortcutSQLCommand(playerName, characterId, idxToObj)); buggedChar = false; } // begin parsing new character characterId = result.CharacterId; var player = PlayerManager.FindByGuid(characterId); playerName = player != null ? player.Name : $"{characterId:X8}"; idxToObj = new Dictionary <uint, uint>(); objToIdx = new Dictionary <uint, uint>(); } var dupeIdx = idxToObj.ContainsKey(result.ShortcutBarIndex); var dupeObj = objToIdx.ContainsKey(result.ShortcutObjectId); if (dupeIdx || dupeObj) { //Console.WriteLine($"Player: {playerName}, Idx: {result.ShortcutBarIndex}, Obj: {result.ShortcutObjectId:X8} ({result.Id})"); buggedChar = true; } objToIdx[result.ShortcutObjectId] = result.ShortcutBarIndex; if (!dupeObj) { idxToObj[result.ShortcutBarIndex] = result.ShortcutObjectId; } } if (buggedChar) { Console.WriteLine($"Player {playerName} ({characterId}) was found to have errors in their shortcuts."); buggedPlayerCount++; sqlCommands.AddRange(OutputShortcutSQLCommand(playerName, characterId, idxToObj)); } Console.WriteLine($"Total players found with bugged shortcuts: {buggedPlayerCount}"); if (execute) { Console.WriteLine("Executing changes..."); foreach (var cmd in sqlCommands) { ctx.Database.ExecuteSqlCommand(cmd); } } else { Console.WriteLine("dry run completed. Use fix-shortcut-bars execute to actually run command"); } } }
public CategoryService(ServiceFactory serviceFactory) { _context = serviceFactory.Context; }