/// <summary>
        /// Returns a friendly string for the position of a biota
        /// </summary>
        private static string GetCoords(Biota biota)
        {
            var p = biota.BiotaPropertiesPosition.FirstOrDefault(i => i.PositionType == (ushort)PositionType.Location);

            return(GetCoords(new Position(p.ObjCellId, p.OriginX, p.OriginY, p.OriginZ, p.AnglesX, p.AnglesY, p.AnglesZ, p.AnglesW, 0)));
        }
Example #2
0
 public Hotspot(Biota biota) : base(biota)
 {
     SetEphemeralValues();
 }
        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();
                }
            }
        }
Example #4
0
 /// <summary>
 /// Restore a WorldObject from the database.
 /// </summary>
 public Portal(Biota biota) : base(biota)
 {
     SetEphemeralValues();
 }
Example #5
0
        private static void DoPlayerEnterWorld(Session session, Character character, Biota playerBiota, PossessedBiotas possessedBiotas)
        {
            Player player;

            Player.HandleNoLogLandblock(playerBiota, out var playerLoggedInOnNoLogLandblock);

            var stripAdminProperties  = false;
            var addAdminProperties    = false;
            var addSentinelProperties = false;

            if (ConfigManager.Config.Server.Accounts.OverrideCharacterPermissions)
            {
                if (session.AccessLevel <= AccessLevel.Advocate)                                                     // check for elevated characters
                {
                    if (playerBiota.WeenieType == WeenieType.Admin || playerBiota.WeenieType == WeenieType.Sentinel) // Downgrade weenie
                    {
                        character.IsPlussed    = false;
                        playerBiota.WeenieType = WeenieType.Creature;
                        stripAdminProperties   = true;
                    }
                }
                else if (session.AccessLevel >= AccessLevel.Sentinel && session.AccessLevel <= AccessLevel.Envoy)
                {
                    if (playerBiota.WeenieType == WeenieType.Creature || playerBiota.WeenieType == WeenieType.Admin) // Up/downgrade weenie
                    {
                        character.IsPlussed    = true;
                        playerBiota.WeenieType = WeenieType.Sentinel;
                        addSentinelProperties  = true;
                    }
                }
                else // Developers and Admins
                {
                    if (playerBiota.WeenieType == WeenieType.Creature || playerBiota.WeenieType == WeenieType.Sentinel) // Up/downgrade weenie
                    {
                        character.IsPlussed    = true;
                        playerBiota.WeenieType = WeenieType.Admin;
                        addAdminProperties     = true;
                    }
                }
            }

            if (playerBiota.WeenieType == WeenieType.Admin)
            {
                player = new Admin(playerBiota, possessedBiotas.Inventory, possessedBiotas.WieldedItems, character, session);
            }
            else if (playerBiota.WeenieType == WeenieType.Sentinel)
            {
                player = new Sentinel(playerBiota, possessedBiotas.Inventory, possessedBiotas.WieldedItems, character, session);
            }
            else
            {
                player = new Player(playerBiota, possessedBiotas.Inventory, possessedBiotas.WieldedItems, character, session);
            }

            session.SetPlayer(player);

            if (stripAdminProperties) // continue stripping properties
            {
                player.CloakStatus = CloakStatus.Undef;
                player.Attackable  = true;
                player.SetProperty(ACE.Entity.Enum.Properties.PropertyBool.DamagedByCollisions, true);
                player.AdvocateLevel            = null;
                player.ChannelsActive           = null;
                player.ChannelsAllowed          = null;
                player.Invincible               = false;
                player.Cloaked                  = null;
                player.IgnoreHouseBarriers      = false;
                player.IgnorePortalRestrictions = false;
                player.SafeSpellComponents      = false;
                player.ReportCollisions         = true;


                player.ChangesDetected          = true;
                player.CharacterChangesDetected = true;
            }

            if (addSentinelProperties || addAdminProperties) // continue restoring properties to default
            {
                WorldObject weenie;

                if (addAdminProperties)
                {
                    weenie = Factories.WorldObjectFactory.CreateWorldObject(DatabaseManager.World.GetCachedWeenie("admin"), new ACE.Entity.ObjectGuid(ACE.Entity.ObjectGuid.Invalid.Full));
                }
                else
                {
                    weenie = Factories.WorldObjectFactory.CreateWorldObject(DatabaseManager.World.GetCachedWeenie("sentinel"), new ACE.Entity.ObjectGuid(ACE.Entity.ObjectGuid.Invalid.Full));
                }

                if (weenie != null)
                {
                    player.CloakStatus = CloakStatus.Off;
                    player.Attackable  = weenie.Attackable;
                    player.SetProperty(ACE.Entity.Enum.Properties.PropertyBool.DamagedByCollisions, false);
                    player.AdvocateLevel   = weenie.GetProperty(ACE.Entity.Enum.Properties.PropertyInt.AdvocateLevel);
                    player.ChannelsActive  = (Channel?)weenie.GetProperty(ACE.Entity.Enum.Properties.PropertyInt.ChannelsActive);
                    player.ChannelsAllowed = (Channel?)weenie.GetProperty(ACE.Entity.Enum.Properties.PropertyInt.ChannelsAllowed);
                    player.Invincible      = false;
                    player.Cloaked         = false;


                    player.ChangesDetected          = true;
                    player.CharacterChangesDetected = true;
                }
            }

            // If the client is missing a location, we start them off in the starter town they chose
            if (session.Player.Location == null)
            {
                if (session.Player.Instantiation != null)
                {
                    session.Player.Location = new Position(session.Player.Instantiation);
                }
                else
                {
                    session.Player.Location = new Position(0xA9B40019, 84, 7.1f, 94, 0, 0, -0.0784591f, 0.996917f);  // ultimate fallback
                }
            }

            session.Player.PlayerEnterWorld();

            var success = LandblockManager.AddObject(session.Player, true);

            if (!success)
            {
                // send to lifestone, or fallback location
                var fixLoc = session.Player.Sanctuary ?? new Position(0xA9B40019, 84, 7.1f, 94, 0, 0, -0.0784591f, 0.996917f);

                log.Error($"WorldManager.DoPlayerEnterWorld: failed to spawn {session.Player.Name}, relocating to {fixLoc.ToLOCString()}");

                session.Player.Location = new Position(fixLoc);
                LandblockManager.AddObject(session.Player, true);

                var actionChain = new ActionChain();
                actionChain.AddDelaySeconds(5.0f);
                actionChain.AddAction(session.Player, () =>
                {
                    if (session != null && session.Player != null)
                    {
                        session.Player.Teleport(fixLoc);
                    }
                });
                actionChain.EnqueueChain();
            }

            // These warnings are set by DDD_InterrogationResponse
            if ((session.DatWarnCell || session.DatWarnLanguage || session.DatWarnPortal) && PropertyManager.GetBool("show_dat_warning").Item)
            {
                var msg     = PropertyManager.GetString("dat_warning_msg").Item;
                var chatMsg = new GameMessageSystemChat(msg, ChatMessageType.System);
                session.Network.EnqueueSend(chatMsg);
            }

            var popup_header  = PropertyManager.GetString("popup_header").Item;
            var popup_motd    = PropertyManager.GetString("popup_motd").Item;
            var popup_welcome = PropertyManager.GetString("popup_welcome").Item;

            if (character.TotalLogins <= 1)
            {
                session.Network.EnqueueSend(new GameEventPopupString(session, AppendLines(popup_header, popup_motd, popup_welcome)));
            }
            else if (!string.IsNullOrEmpty(popup_motd))
            {
                session.Network.EnqueueSend(new GameEventPopupString(session, AppendLines(popup_header, popup_motd)));
            }

            var info = "Welcome to Asheron's Call\n  powered by ACEmulator\n\nFor more information on commands supported by this server, type @acehelp\n";

            session.Network.EnqueueSend(new GameMessageSystemChat(info, ChatMessageType.Broadcast));

            var server_motd = PropertyManager.GetString("server_motd").Item;

            if (!string.IsNullOrEmpty(server_motd))
            {
                session.Network.EnqueueSend(new GameMessageSystemChat($"{server_motd}\n", ChatMessageType.Broadcast));
            }

            if (playerLoggedInOnNoLogLandblock) // see http://acpedia.org/wiki/Mount_Elyrii_Hive
            {
                session.Network.EnqueueSend(new GameMessageSystemChat("The currents of portal space cannot return you from whence you came. Your previous location forbids login.", ChatMessageType.Broadcast));
            }
        }
Example #6
0
        private static void SetBiotaPopulatedCollections(Biota biota)
        {
            PopulatedCollectionFlags populatedCollectionFlags = 0;

            if (biota.BiotaPropertiesAnimPart != null && biota.BiotaPropertiesAnimPart.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesAnimPart;
            }
            if (biota.BiotaPropertiesAttribute != null && biota.BiotaPropertiesAttribute.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesAttribute;
            }
            if (biota.BiotaPropertiesAttribute2nd != null && biota.BiotaPropertiesAttribute2nd.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesAttribute2nd;
            }
            if (biota.BiotaPropertiesBodyPart != null && biota.BiotaPropertiesBodyPart.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesBodyPart;
            }
            if (biota.BiotaPropertiesBook != null)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesBook;
            }
            if (biota.BiotaPropertiesBookPageData != null && biota.BiotaPropertiesBookPageData.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesBookPageData;
            }
            if (biota.BiotaPropertiesBool != null && biota.BiotaPropertiesBool.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesBool;
            }
            if (biota.BiotaPropertiesCreateList != null && biota.BiotaPropertiesCreateList.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesCreateList;
            }
            if (biota.BiotaPropertiesDID != null && biota.BiotaPropertiesDID.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesDID;
            }
            if (biota.BiotaPropertiesEmote != null && biota.BiotaPropertiesEmote.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesEmote;
            }
            if (biota.BiotaPropertiesEnchantmentRegistry != null && biota.BiotaPropertiesEnchantmentRegistry.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesEnchantmentRegistry;
            }
            if (biota.BiotaPropertiesEventFilter != null && biota.BiotaPropertiesEventFilter.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesEventFilter;
            }
            if (biota.BiotaPropertiesFloat != null && biota.BiotaPropertiesFloat.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesFloat;
            }
            if (biota.BiotaPropertiesGenerator != null && biota.BiotaPropertiesGenerator.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesGenerator;
            }
            if (biota.BiotaPropertiesIID != null && biota.BiotaPropertiesIID.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesIID;
            }
            if (biota.BiotaPropertiesInt != null && biota.BiotaPropertiesInt.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesInt;
            }
            if (biota.BiotaPropertiesInt64 != null && biota.BiotaPropertiesInt64.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesInt64;
            }
            if (biota.BiotaPropertiesPalette != null && biota.BiotaPropertiesPalette.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesPalette;
            }
            if (biota.BiotaPropertiesPosition != null && biota.BiotaPropertiesPosition.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesPosition;
            }
            if (biota.BiotaPropertiesSkill != null && biota.BiotaPropertiesSkill.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesSkill;
            }
            if (biota.BiotaPropertiesSpellBook != null && biota.BiotaPropertiesSpellBook.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesSpellBook;
            }
            if (biota.BiotaPropertiesString != null && biota.BiotaPropertiesString.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesString;
            }
            if (biota.BiotaPropertiesTextureMap != null && biota.BiotaPropertiesTextureMap.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesTextureMap;
            }
            if (biota.HousePermission != null && biota.HousePermission.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.HousePermission;
            }
            if (biota.BiotaPropertiesAllegiance != null && biota.BiotaPropertiesAllegiance.Count > 0)
            {
                populatedCollectionFlags |= PopulatedCollectionFlags.BiotaPropertiesAllegiance;
            }

            biota.PopulatedCollectionFlags = (uint)populatedCollectionFlags;
        }
Example #7
0
 /// <summary>
 /// Restore a WorldObject from the database.
 /// </summary>
 public Caster(Biota biota) : base(biota)
 {
     SetEphemeralValues();
 }
Example #8
0
        /// <summary>
        /// Restore a WorldObject from the database.
        /// </summary>
        public Container(Biota biota) : base(biota)
        {
            if (Biota.TryRemoveProperty(PropertyBool.Open, BiotaDatabaseLock))
            {
                ChangesDetected = true;
            }

            // This is a temporary fix for objects that were loaded with this PR when EncumbranceVal was not treated as ephemeral. 2020-03-28
            // This can be removed later.
            if (Biota.PropertiesInt.ContainsKey(PropertyInt.EncumbranceVal))
            {
                var weenie = DatabaseManager.World.GetCachedWeenie(biota.WeenieClassId);

                if (weenie != null && weenie.PropertiesInt.TryGetValue(PropertyInt.EncumbranceVal, out var value))
                {
                    if (biota.PropertiesInt[PropertyInt.EncumbranceVal] != value)
                    {
                        biota.PropertiesInt[PropertyInt.EncumbranceVal] = value;
                        ChangesDetected = true;
                    }
                }
                else
                {
                    biota.PropertiesInt.Remove(PropertyInt.EncumbranceVal);
                    ChangesDetected = true;
                }
            }

            // This is a temporary fix for objects that were loaded with this PR when Value was not treated as ephemeral. 2020-03-28
            // This can be removed later.
            if (!(this is Creature) && Biota.PropertiesInt.ContainsKey(PropertyInt.Value))
            {
                var weenie = DatabaseManager.World.GetCachedWeenie(biota.WeenieClassId);

                if (weenie != null && weenie.PropertiesInt.TryGetValue(PropertyInt.Value, out var value))
                {
                    if (biota.PropertiesInt[PropertyInt.Value] != value)
                    {
                        biota.PropertiesInt[PropertyInt.Value] = value;
                        ChangesDetected = true;
                    }
                }
                else
                {
                    biota.PropertiesInt.Remove(PropertyInt.Value);
                    ChangesDetected = true;
                }
            }

            InitializePropertyDictionaries();
            SetEphemeralValues(true);

            // A player has their possessions passed via the ctor. All other world objects must load their own inventory
            if (!(this is Player) && !ObjectGuid.IsPlayer(ContainerId ?? 0))
            {
                DatabaseManager.Shard.GetInventoryInParallel(biota.Id, false, biotas =>
                {
                    EnqueueAction(new ActionEventDelegate(() => SortBiotasIntoInventory(biotas)));
                });
            }
        }
Example #9
0
 /// <summary>
 /// Restore a WorldObject from the database.
 /// </summary>
 public Key(Biota biota) : base(biota)
 {
     SetEphemeralValues();
 }
Example #10
0
 /// <summary>
 /// Restore a WorldObject from the database.
 /// </summary>
 public Ammunition(Biota biota) : base(biota)
 {
     SetEphemeralValues();
 }
Example #11
0
 /// <summary>
 /// Restore a WorldObject from the database.
 /// </summary>
 public Switch(Biota biota) : base(biota)
 {
     SetEphemeralValues();
 }
Example #12
0
 /// <summary>
 /// Restore a WorldObject from the database.
 /// </summary>
 public Hooker(Biota biota) : base(biota)
 {
     SetEphemeralValues();
 }
Example #13
0
        public static Biota CreateCopyAsBiota(this Weenie weenie, uint id)
        {
            var biota = new Biota();

            biota.Id            = id;
            biota.WeenieClassId = weenie.ClassId;
            biota.WeenieType    = weenie.Type;

            if (weenie.WeeniePropertiesBook != null)
            {
                biota.BiotaPropertiesBook                    = new BiotaPropertiesBook();
                biota.BiotaPropertiesBook.ObjectId           = biota.Id;
                biota.BiotaPropertiesBook.MaxNumPages        = weenie.WeeniePropertiesBook.MaxNumPages;
                biota.BiotaPropertiesBook.MaxNumCharsPerPage = weenie.WeeniePropertiesBook.MaxNumCharsPerPage;
            }

            foreach (var value in weenie.WeeniePropertiesAnimPart)
            {
                biota.BiotaPropertiesAnimPart.Add(new BiotaPropertiesAnimPart
                {
                    ObjectId    = biota.Id,
                    Index       = value.Index,
                    AnimationId = value.AnimationId
                });
            }

            foreach (var value in weenie.WeeniePropertiesAttribute)
            {
                biota.BiotaPropertiesAttribute.Add(new BiotaPropertiesAttribute
                {
                    ObjectId    = biota.Id,
                    Type        = value.Type,
                    InitLevel   = value.InitLevel,
                    LevelFromCP = value.LevelFromCP,
                    CPSpent     = value.CPSpent,
                });
            }

            foreach (var value in weenie.WeeniePropertiesAttribute2nd)
            {
                biota.BiotaPropertiesAttribute2nd.Add(new BiotaPropertiesAttribute2nd
                {
                    ObjectId     = biota.Id,
                    Type         = value.Type,
                    InitLevel    = value.InitLevel,
                    LevelFromCP  = value.LevelFromCP,
                    CPSpent      = value.CPSpent,
                    CurrentLevel = value.CurrentLevel,
                });
            }

            foreach (var value in weenie.WeeniePropertiesBodyPart)
            {
                biota.BiotaPropertiesBodyPart.Add(new BiotaPropertiesBodyPart
                {
                    ObjectId        = biota.Id,
                    Key             = value.Key,
                    DType           = value.DType,
                    DVal            = value.DVal,
                    DVar            = value.DVar,
                    BaseArmor       = value.BaseArmor,
                    ArmorVsSlash    = value.ArmorVsSlash,
                    ArmorVsPierce   = value.ArmorVsPierce,
                    ArmorVsBludgeon = value.ArmorVsBludgeon,
                    ArmorVsCold     = value.ArmorVsCold,
                    ArmorVsFire     = value.ArmorVsFire,
                    ArmorVsAcid     = value.ArmorVsAcid,
                    ArmorVsElectric = value.ArmorVsElectric,
                    ArmorVsNether   = value.ArmorVsNether,
                    BH  = value.BH,
                    HLF = value.HLF,
                    MLF = value.MLF,
                    LLF = value.LLF,
                    HRF = value.HRF,
                    MRF = value.MRF,
                    LRF = value.LRF,
                    HLB = value.HLB,
                    MLB = value.MLB,
                    LLB = value.LLB,
                    HRB = value.HRB,
                    MRB = value.MRB,
                    LRB = value.LRB,
                });
            }

            foreach (var value in weenie.WeeniePropertiesBookPageData)
            {
                biota.BiotaPropertiesBookPageData.Add(new BiotaPropertiesBookPageData
                {
                    ObjectId      = biota.Id,
                    PageId        = value.PageId,
                    AuthorId      = value.AuthorId,
                    AuthorName    = value.AuthorName,
                    AuthorAccount = value.AuthorAccount,
                    IgnoreAuthor  = value.IgnoreAuthor,
                    PageText      = value.PageText,
                });
            }

            foreach (var value in weenie.WeeniePropertiesBool)
            {
                biota.BiotaPropertiesBool.Add(new BiotaPropertiesBool
                {
                    ObjectId = biota.Id,
                    Type     = value.Type,
                    Value    = value.Value,
                });
            }

            foreach (var value in weenie.WeeniePropertiesCreateList)
            {
                biota.BiotaPropertiesCreateList.Add(new BiotaPropertiesCreateList
                {
                    ObjectId        = biota.Id,
                    DestinationType = value.DestinationType,
                    WeenieClassId   = value.WeenieClassId,
                    StackSize       = value.StackSize,
                    Palette         = value.Palette,
                    Shade           = value.Shade,
                    TryToBond       = value.TryToBond,
                });
            }

            foreach (var value in weenie.WeeniePropertiesDID)
            {
                biota.BiotaPropertiesDID.Add(new BiotaPropertiesDID
                {
                    ObjectId = biota.Id,
                    Type     = value.Type,
                    Value    = value.Value,
                });
            }


            foreach (var value in weenie.WeeniePropertiesEmote)
            {
                var emote = new BiotaPropertiesEmote
                {
                    ObjectId      = biota.Id,
                    Category      = value.Category,
                    Probability   = value.Probability,
                    WeenieClassId = value.WeenieClassId,
                    Style         = value.Style,
                    Substyle      = value.Substyle,
                    Quest         = value.Quest,
                    VendorType    = value.VendorType,
                    MinHealth     = value.MinHealth,
                    MaxHealth     = value.MaxHealth,
                };

                foreach (var value2 in value.WeeniePropertiesEmoteAction)
                {
                    var action = new BiotaPropertiesEmoteAction
                    {
                        // EmoteId is a foreign key to Emote.Id.
                        // If we don't set this to a non-zero number, EF will not auto-set this for us when we add this biota to the database.
                        // We set it to uint.MaxValue instead of 1 because 1 is more likely to be a valid foreign key. We don't want to enter a valid foreign key.
                        // We just want to enter a value that forces EF to update the record with the correft foreign key. If this behavior changes in the future and we set it to 1,
                        // we're more likely to run into an unnoticed issue (because 1 would not throw an exception and uint.MaxValue probably would).
                        // We put this here instead of in ShardDatabase for efficiency.
                        // It's possible this might be fixable with a attribute in the Emote or EmoteAction classes.
                        // It's also possible we don't have the schema defined in a way that helps scaffolding identify the relationship.
                        // Mag-nus 2018-08-04
                        EmoteId = uint.MaxValue,

                        Order           = value2.Order,
                        Type            = value2.Type,
                        Delay           = value2.Delay,
                        Extent          = value2.Extent,
                        Motion          = value2.Motion,
                        Message         = value2.Message,
                        TestString      = value2.TestString,
                        Min             = value2.Min,
                        Max             = value2.Max,
                        Min64           = value2.Min64,
                        Max64           = value2.Max64,
                        MinDbl          = value2.MinDbl,
                        MaxDbl          = value2.MaxDbl,
                        Stat            = value2.Stat,
                        Display         = value2.Display,
                        Amount          = value2.Amount,
                        Amount64        = value2.Amount64,
                        HeroXP64        = value2.HeroXP64,
                        Percent         = value2.Percent,
                        SpellId         = value2.SpellId,
                        WealthRating    = value2.WealthRating,
                        TreasureClass   = value2.TreasureClass,
                        TreasureType    = value2.TreasureType,
                        PScript         = value2.PScript,
                        Sound           = value2.Sound,
                        DestinationType = value2.DestinationType,
                        WeenieClassId   = value2.WeenieClassId,
                        StackSize       = value2.StackSize,
                        Palette         = value2.Palette,
                        Shade           = value2.Shade,
                        TryToBond       = value2.TryToBond,
                        ObjCellId       = value2.ObjCellId,
                        OriginX         = value2.OriginX,
                        OriginY         = value2.OriginY,
                        OriginZ         = value2.OriginZ,
                        AnglesW         = value2.AnglesW,
                        AnglesX         = value2.AnglesX,
                        AnglesY         = value2.AnglesY,
                        AnglesZ         = value2.AnglesZ,
                    };

                    emote.BiotaPropertiesEmoteAction.Add(action);
                }

                biota.BiotaPropertiesEmote.Add(emote);
            }


            foreach (var value in weenie.WeeniePropertiesEventFilter)
            {
                biota.BiotaPropertiesEventFilter.Add(new BiotaPropertiesEventFilter
                {
                    ObjectId = biota.Id,
                    Event    = value.Event,
                });
            }

            foreach (var value in weenie.WeeniePropertiesFloat)
            {
                biota.BiotaPropertiesFloat.Add(new BiotaPropertiesFloat
                {
                    ObjectId = biota.Id,
                    Type     = value.Type,
                    Value    = value.Value,
                });
            }

            foreach (var value in weenie.WeeniePropertiesGenerator)
            {
                biota.BiotaPropertiesGenerator.Add(new BiotaPropertiesGenerator
                {
                    ObjectId      = biota.Id,
                    Probability   = value.Probability,
                    WeenieClassId = value.WeenieClassId,
                    Delay         = value.Delay,
                    InitCreate    = value.InitCreate,
                    MaxCreate     = value.MaxCreate,
                    WhenCreate    = value.WhenCreate,
                    WhereCreate   = value.WhereCreate,
                    StackSize     = value.StackSize,
                    PaletteId     = value.PaletteId,
                    Shade         = value.Shade,
                    ObjCellId     = value.ObjCellId,
                    OriginX       = value.OriginX,
                    OriginY       = value.OriginY,
                    OriginZ       = value.OriginZ,
                    AnglesW       = value.AnglesW,
                    AnglesX       = value.AnglesX,
                    AnglesY       = value.AnglesY,
                    AnglesZ       = value.AnglesZ,
                });
            }

            foreach (var value in weenie.WeeniePropertiesIID)
            {
                biota.BiotaPropertiesIID.Add(new BiotaPropertiesIID
                {
                    ObjectId = biota.Id,
                    Type     = value.Type,
                    Value    = value.Value,
                });
            }

            foreach (var value in weenie.WeeniePropertiesInt)
            {
                biota.BiotaPropertiesInt.Add(new BiotaPropertiesInt
                {
                    ObjectId = biota.Id,
                    Type     = value.Type,
                    Value    = value.Value,
                });
            }

            foreach (var value in weenie.WeeniePropertiesInt64)
            {
                biota.BiotaPropertiesInt64.Add(new BiotaPropertiesInt64
                {
                    ObjectId = biota.Id,
                    Type     = value.Type,
                    Value    = value.Value,
                });
            }

            foreach (var value in weenie.WeeniePropertiesPalette)
            {
                biota.BiotaPropertiesPalette.Add(new BiotaPropertiesPalette
                {
                    ObjectId     = biota.Id,
                    SubPaletteId = value.SubPaletteId,
                    Offset       = value.Offset,
                    Length       = value.Length,
                });
            }

            foreach (var value in weenie.WeeniePropertiesPosition)
            {
                biota.BiotaPropertiesPosition.Add(new BiotaPropertiesPosition
                {
                    ObjectId     = biota.Id,
                    PositionType = value.PositionType,
                    ObjCellId    = value.ObjCellId,
                    OriginX      = value.OriginX,
                    OriginY      = value.OriginY,
                    OriginZ      = value.OriginZ,
                    AnglesW      = value.AnglesW,
                    AnglesX      = value.AnglesX,
                    AnglesY      = value.AnglesY,
                    AnglesZ      = value.AnglesZ,
                });
            }

            foreach (var value in weenie.WeeniePropertiesSkill)
            {
                biota.BiotaPropertiesSkill.Add(new BiotaPropertiesSkill
                {
                    ObjectId              = biota.Id,
                    Type                  = value.Type,
                    LevelFromPP           = value.LevelFromPP,
                    SAC                   = value.SAC,
                    PP                    = value.PP,
                    InitLevel             = value.InitLevel,
                    ResistanceAtLastCheck = value.ResistanceAtLastCheck,
                    LastUsedTime          = value.LastUsedTime,
                });
            }

            foreach (var value in weenie.WeeniePropertiesSpellBook)
            {
                biota.BiotaPropertiesSpellBook.Add(new BiotaPropertiesSpellBook
                {
                    ObjectId    = biota.Id,
                    Spell       = value.Spell,
                    Probability = value.Probability,
                });
            }

            foreach (var value in weenie.WeeniePropertiesString)
            {
                biota.BiotaPropertiesString.Add(new BiotaPropertiesString
                {
                    ObjectId = biota.Id,
                    Type     = value.Type,
                    Value    = value.Value,
                });
            }

            foreach (var value in weenie.WeeniePropertiesTextureMap)
            {
                biota.BiotaPropertiesTextureMap.Add(new BiotaPropertiesTextureMap
                {
                    ObjectId = biota.Id,
                    Index    = value.Index,
                    OldId    = value.OldId,
                    NewId    = value.NewId,
                });
            }

            return(biota);
        }
Example #14
0
 /// <summary>
 /// Restore a WorldObject from the database.
 /// </summary>
 public Admin(Biota biota, IEnumerable <ACE.Database.Models.Shard.Biota> inventory, IEnumerable <ACE.Database.Models.Shard.Biota> wieldedItems, Character character, Session session) : base(biota, inventory, wieldedItems, character, session)
 {
     SetEphemeralValues();
 }
Example #15
0
 /// <summary>
 /// Restore a WorldObject from the database.
 /// </summary>
 public PKModifier(Biota biota) : base(biota)
 {
     SetEphemeralValues();
 }
Example #16
0
        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();
            }
        }
Example #17
0
 /// <summary>
 /// Restore a WorldObject from the database.
 /// </summary>
 public Door(Biota biota) : base(biota)
 {
     SetEphemeralValues();
 }
Example #18
0
 /// <summary>
 /// Restore a WorldObject from the database.
 /// </summary>
 public ManaStone(Biota biota) : base(biota)
 {
     SetEphemeralValues();
 }
Example #19
0
 /// <summary>
 /// Restore a WorldObject from the database.
 /// </summary>
 public SpellProjectile(Biota biota) : base(biota)
 {
     SetEphemeralValues();
 }
        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}");
            }
        }
Example #21
0
 /// <summary>
 /// Restore a WorldObject from the database.
 /// </summary>
 public Bindstone(Biota biota) : base(biota)
 {
     SetEphemeralValues();
 }
Example #22
0
 /// <summary>
 /// Restore a WorldObject from the database.
 /// </summary>
 public PetDevice(Biota biota) : base(biota)
 {
     SetEphemeralValues();
 }
Example #23
0
 /// <summary>
 /// Restore a WorldObject from the database.
 /// </summary>
 public CombatPet(Biota biota) : base(biota)
 {
     SetEphemeralValues();
 }
        /// <summary>
        /// Restore a WorldObject from the database.
        /// Any properties tagged as Ephemeral will be removed from the biota.
        /// </summary>
        public static WorldObject CreateWorldObject(Biota biota)
        {
            var objWeenieType = (WeenieType)biota.WeenieType;

            switch (objWeenieType)
            {
            case WeenieType.Undef:
                return(null);

            case WeenieType.LifeStone:
                return(new Lifestone(biota));

            case WeenieType.Door:
                return(new Door(biota));

            case WeenieType.Portal:
                return(new Portal(biota));

            case WeenieType.Book:
                return(new Book(biota));

            case WeenieType.PKModifier:
                return(new PKModifier(biota));

            case WeenieType.Cow:
                return(new Cow(biota));

            case WeenieType.Creature:
                return(new Creature(biota));

            case WeenieType.Container:
                return(new Container(biota));

            case WeenieType.Scroll:
                return(new Scroll(biota));

            case WeenieType.Vendor:
                return(new Vendor(biota));

            case WeenieType.Coin:
                return(new Coin(biota));

            case WeenieType.Key:
                return(new Key(biota));

            case WeenieType.Food:
                return(new Food(biota));

            case WeenieType.Gem:
                return(new Gem(biota));

            case WeenieType.Game:
                return(new Game(biota));

            case WeenieType.GamePiece:
                return(new GamePiece(biota));

            case WeenieType.AllegianceBindstone:
                return(new Bindstone(biota));

            case WeenieType.Clothing:
                return(new Clothing(biota));

            case WeenieType.MeleeWeapon:
                return(new MeleeWeapon(biota));

            case WeenieType.MissileLauncher:
                return(new MissileLauncher(biota));

            case WeenieType.Ammunition:
                return(new Ammunition(biota));

            case WeenieType.Missile:
                return(new Missile(biota));

            case WeenieType.Corpse:
                return(new Corpse(biota));

            case WeenieType.Chest:
                return(new Chest(biota));

            case WeenieType.Stackable:
                return(new Stackable(biota));

            case WeenieType.SpellComponent:
                return(new SpellComponent(biota));

            case WeenieType.Switch:
                return(new Switch(biota));

            case WeenieType.AdvocateFane:
                return(new AdvocateFane(biota));

            case WeenieType.AdvocateItem:
                return(new AdvocateItem(biota));

            case WeenieType.Healer:
                return(new Healer(biota));

            case WeenieType.Lockpick:
                return(new Lockpick(biota));

            case WeenieType.Caster:
                return(new Caster(biota));

            case WeenieType.HotSpot:
                return(new Hotspot(biota));

            case WeenieType.ManaStone:
                return(new ManaStone(biota));

            case WeenieType.House:
                return(new House(biota));

            case WeenieType.SlumLord:
                return(new SlumLord(biota));

            case WeenieType.Storage:
                return(new Storage(biota));

            case WeenieType.Hook:
                return(new Hook(biota));

            case WeenieType.Hooker:
                return(new Hooker(biota));

            case WeenieType.HousePortal:
                return(new WorldObjects.HousePortal(biota));

            case WeenieType.SkillAlterationDevice:
                return(new SkillAlterationDevice(biota));

            case WeenieType.PressurePlate:
                return(new PressurePlate(biota));

            case WeenieType.PetDevice:
                return(new PetDevice(biota));

            case WeenieType.Pet:
                return(new Pet(biota));

            case WeenieType.CombatPet:
                return(new CombatPet(biota));

            case WeenieType.Allegiance:
                return(new Allegiance(biota));

            default:
                return(new GenericObject(biota));
            }
        }
Example #25
0
 /// <summary>
 /// Restore a WorldObject from the database.
 /// </summary>
 public Food(Biota biota) : base(biota)
 {
     SetEphemeralValues();
 }
Example #26
0
 /// <summary>
 /// Restore a WorldObject from the database.
 /// </summary>
 public Sentinel(Biota biota, IEnumerable <Biota> inventory, IEnumerable <Biota> wieldedItems, Session session) : base(biota, inventory, wieldedItems, session)
 {
     SetEphemeralValues();
 }
        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 propagate 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 = existingBiota.BiotaPropertiesAttribute.FirstOrDefault(r => r.Type == value.Type);

                if (existingValue == null)
                {
                    existingBiota.BiotaPropertiesAttribute.Add(value);
                }
                else
                {
                    existingValue.InitLevel   = value.InitLevel;
                    existingValue.LevelFromCP = value.LevelFromCP;
                    existingValue.CPSpent     = value.CPSpent;
                }
            }
            foreach (var value in existingBiota.BiotaPropertiesAttribute)
            {
                if (!biota.BiotaPropertiesAttribute.Any(p => p.Type == value.Type))
                {
                    context.BiotaPropertiesAttribute.Remove(value);
                }
            }

            foreach (var value in biota.BiotaPropertiesAttribute2nd)
            {
                BiotaPropertiesAttribute2nd existingValue = existingBiota.BiotaPropertiesAttribute2nd.FirstOrDefault(r => r.Type == value.Type);

                if (existingValue == null)
                {
                    existingBiota.BiotaPropertiesAttribute2nd.Add(value);
                }
                else
                {
                    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.Type == value.Type))
                {
                    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 = existingBiota.BiotaPropertiesBool.FirstOrDefault(r => r.Type == value.Type);

                if (existingValue == null)
                {
                    existingBiota.BiotaPropertiesBool.Add(value);
                }
                else
                {
                    existingValue.Value = value.Value;
                }
            }
            foreach (var value in existingBiota.BiotaPropertiesBool)
            {
                if (!biota.BiotaPropertiesBool.Any(p => p.Type == value.Type))
                {
                    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 = existingBiota.BiotaPropertiesDID.FirstOrDefault(r => r.Type == value.Type);

                if (existingValue == null)
                {
                    existingBiota.BiotaPropertiesDID.Add(value);
                }
                else
                {
                    existingValue.Value = value.Value;
                }
            }
            foreach (var value in existingBiota.BiotaPropertiesDID)
            {
                if (!biota.BiotaPropertiesDID.Any(p => p.Type == value.Type))
                {
                    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.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.SpellId == value.SpellId && p.LayerId == value.LayerId && p.CasterObjectId == value.CasterObjectId))
                {
                    context.BiotaPropertiesEnchantmentRegistry.Remove(value);
                }
            }

            foreach (var value in biota.BiotaPropertiesEventFilter)
            {
                BiotaPropertiesEventFilter existingValue = existingBiota.BiotaPropertiesEventFilter.FirstOrDefault(r => r.Event == value.Event);

                if (existingValue == null)
                {
                    existingBiota.BiotaPropertiesEventFilter.Add(value);
                }
            }
            foreach (var value in existingBiota.BiotaPropertiesEventFilter)
            {
                if (!biota.BiotaPropertiesEventFilter.Any(p => p.Event == value.Event))
                {
                    context.BiotaPropertiesEventFilter.Remove(value);
                }
            }

            foreach (var value in biota.BiotaPropertiesFloat)
            {
                BiotaPropertiesFloat existingValue = existingBiota.BiotaPropertiesFloat.FirstOrDefault(r => r.Type == value.Type);

                if (existingValue == null)
                {
                    existingBiota.BiotaPropertiesFloat.Add(value);
                }
                else
                {
                    existingValue.Value = value.Value;
                }
            }
            foreach (var value in existingBiota.BiotaPropertiesFloat)
            {
                if (!biota.BiotaPropertiesFloat.Any(p => p.Type == value.Type))
                {
                    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 = existingBiota.BiotaPropertiesIID.FirstOrDefault(r => r.Type == value.Type);

                if (existingValue == null)
                {
                    existingBiota.BiotaPropertiesIID.Add(value);
                }
                else
                {
                    existingValue.Value = value.Value;
                }
            }
            foreach (var value in existingBiota.BiotaPropertiesIID)
            {
                if (!biota.BiotaPropertiesIID.Any(p => p.Type == value.Type))
                {
                    context.BiotaPropertiesIID.Remove(value);
                }
            }

            foreach (var value in biota.BiotaPropertiesInt)
            {
                BiotaPropertiesInt existingValue = existingBiota.BiotaPropertiesInt.FirstOrDefault(r => r.Type == value.Type);

                if (existingValue == null)
                {
                    existingBiota.BiotaPropertiesInt.Add(value);
                }
                else
                {
                    existingValue.Value = value.Value;
                }
            }
            foreach (var value in existingBiota.BiotaPropertiesInt)
            {
                if (!biota.BiotaPropertiesInt.Any(p => p.Type == value.Type))
                {
                    context.BiotaPropertiesInt.Remove(value);
                }
            }

            foreach (var value in biota.BiotaPropertiesInt64)
            {
                BiotaPropertiesInt64 existingValue = existingBiota.BiotaPropertiesInt64.FirstOrDefault(r => r.Type == value.Type);

                if (existingValue == null)
                {
                    existingBiota.BiotaPropertiesInt64.Add(value);
                }
                else
                {
                    existingValue.Value = value.Value;
                }
            }
            foreach (var value in existingBiota.BiotaPropertiesInt64)
            {
                if (!biota.BiotaPropertiesInt64.Any(p => p.Type == value.Type))
                {
                    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 = existingBiota.BiotaPropertiesPosition.FirstOrDefault(r => r.PositionType == value.PositionType);

                if (existingValue == null)
                {
                    existingBiota.BiotaPropertiesPosition.Add(value);
                }
                else
                {
                    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.PositionType == value.PositionType))
                {
                    context.BiotaPropertiesPosition.Remove(value);
                }
            }

            foreach (var value in biota.BiotaPropertiesSkill)
            {
                BiotaPropertiesSkill existingValue = existingBiota.BiotaPropertiesSkill.FirstOrDefault(r => r.Type == value.Type);

                if (existingValue == null)
                {
                    existingBiota.BiotaPropertiesSkill.Add(value);
                }
                else
                {
                    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.Type == value.Type))
                {
                    context.BiotaPropertiesSkill.Remove(value);
                }
            }

            foreach (var value in biota.BiotaPropertiesSpellBook)
            {
                BiotaPropertiesSpellBook existingValue = existingBiota.BiotaPropertiesSpellBook.FirstOrDefault(r => r.Spell == value.Spell);

                if (existingValue == null)
                {
                    existingBiota.BiotaPropertiesSpellBook.Add(value);
                }
                else
                {
                    existingValue.Probability = value.Probability;
                }
            }
            foreach (var value in existingBiota.BiotaPropertiesSpellBook)
            {
                if (!biota.BiotaPropertiesSpellBook.Any(p => p.Spell == value.Spell))
                {
                    context.BiotaPropertiesSpellBook.Remove(value);
                }
            }

            foreach (var value in biota.BiotaPropertiesString)
            {
                BiotaPropertiesString existingValue = existingBiota.BiotaPropertiesString.FirstOrDefault(r => r.Type == value.Type);

                if (existingValue == null)
                {
                    existingBiota.BiotaPropertiesString.Add(value);
                }
                else
                {
                    existingValue.Value = value.Value;
                }
            }
            foreach (var value in existingBiota.BiotaPropertiesString)
            {
                if (!biota.BiotaPropertiesString.Any(p => p.Type == value.Type))
                {
                    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 = existingBiota.HousePermission.FirstOrDefault(r => r.HouseId == value.HouseId && r.PlayerGuid == value.PlayerGuid);

                if (existingValue == null)
                {
                    existingBiota.HousePermission.Add(value);
                }
                else
                {
                    existingValue.Storage = value.Storage;
                }
            }
            foreach (var value in existingBiota.HousePermission)
            {
                if (!biota.HousePermission.Any(p => p.HouseId == value.HouseId && p.PlayerGuid == value.PlayerGuid))
                {
                    context.HousePermission.Remove(value);
                }
            }
        }
Example #28
0
File: Chest.cs Project: klp2/ACE
 /// <summary>
 /// Restore a WorldObject from the database.
 /// </summary>
 public Chest(Biota biota) : base(biota)
 {
     SetEphemeralValues();
 }
        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(existingBiota);

                        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);
        }
Example #30
0
 /// <summary>
 /// Restore a WorldObject from the database.
 /// </summary>
 public GamePiece(Biota biota) : base(biota)
 {
     SetEphemeralValues();
 }