Esempio n. 1
0
        /// <summary>
        /// Restores live entity backup from Current
        /// </summary>
        /// <returns>Success state</returns>
        public bool RestoreLiveBackup()
        {
            LiveData liveDataAccessor = new LiveData();

            string currentBackupDirectory = liveDataAccessor.BaseDirectory + liveDataAccessor.CurrentDirectoryName;

            //No backup directory? No live data.
            if (!Directory.Exists(currentBackupDirectory))
            {
                return(false);
            }

            LoggingUtility.Log("World restored from current live INITIATED.", LogChannels.Backup, false);

            try
            {
                //dont load players here
                List <IEntity>     entitiesToLoad   = new List <IEntity>();
                IEnumerable <Type> implimentedTypes = typeof(EntityPartial).Assembly.GetTypes().Where(ty => ty.GetInterfaces().Contains(typeof(IEntity)) &&
                                                                                                      ty.IsClass &&
                                                                                                      !ty.IsAbstract &&
                                                                                                      !ty.GetCustomAttributes <IgnoreAutomatedBackupAttribute>().Any());

                foreach (Type type in implimentedTypes.OrderByDescending(type => type == typeof(Gaia) ? 6 :
                                                                         type == typeof(Zone) ? 5 :
                                                                         type == typeof(Locale) ? 3 :
                                                                         type == typeof(Room) ? 3 :
                                                                         type == typeof(Pathway) ? 2 : 0))
                {
                    if (!Directory.Exists(currentBackupDirectory + type.Name))
                    {
                        continue;
                    }

                    DirectoryInfo entityFilesDirectory = new DirectoryInfo(currentBackupDirectory + type.Name);

                    foreach (FileInfo file in entityFilesDirectory.EnumerateFiles())
                    {
                        entitiesToLoad.Add(liveDataAccessor.ReadEntity(file, type));
                    }
                }

                //Check we found actual data
                if (!entitiesToLoad.Any(ent => ent.GetType() == typeof(Gaia)))
                {
                    throw new Exception("No Worlds found, failover.");
                }

                if (!entitiesToLoad.Any(ent => ent.GetType() == typeof(Zone)))
                {
                    throw new Exception("No zones found, failover.");
                }

                //Shove them all into the live system first
                foreach (IEntity entity in entitiesToLoad.OrderBy(ent => ent.Birthdate))
                {
                    entity.UpsertToLiveWorldCache();
                    entity.KickoffProcesses();
                }

                //We need to pick up any places that aren't already live from the file system incase someone added them during the last session\
                foreach (IGaiaTemplate thing in TemplateCache.GetAll <IGaiaTemplate>().Where(dt => !entitiesToLoad.Any(ent => ent.TemplateId.Equals(dt.Id) && ent.Birthdate >= dt.LastRevised)))
                {
                    IGaia entityThing = Activator.CreateInstance(thing.EntityClass, new object[] { thing }) as IGaia;

                    entityThing.SpawnNewInWorld();
                }

                foreach (IZoneTemplate thing in TemplateCache.GetAll <IZoneTemplate>().Where(dt => !entitiesToLoad.Any(ent => ent.TemplateId.Equals(dt.Id) && ent.Birthdate >= dt.LastRevised)))
                {
                    IZone entityThing = Activator.CreateInstance(thing.EntityClass, new object[] { thing }) as IZone;

                    entityThing.SpawnNewInWorld();
                }

                foreach (ILocaleTemplate thing in TemplateCache.GetAll <ILocaleTemplate>().Where(dt => !entitiesToLoad.Any(ent => ent.TemplateId.Equals(dt.Id) && ent.Birthdate >= dt.LastRevised)))
                {
                    ILocale entityThing = Activator.CreateInstance(thing.EntityClass, new object[] { thing }) as ILocale;

                    entityThing.ParentLocation = entityThing.ParentLocation.GetLiveInstance();
                    entityThing.SpawnNewInWorld();
                }

                foreach (IRoomTemplate thing in TemplateCache.GetAll <IRoomTemplate>().Where(dt => !entitiesToLoad.Any(ent => ent.TemplateId.Equals(dt.Id) && ent.Birthdate >= dt.LastRevised)))
                {
                    IRoom entityThing = Activator.CreateInstance(thing.EntityClass, new object[] { thing }) as IRoom;

                    entityThing.ParentLocation = entityThing.Template <IRoomTemplate>().ParentLocation.GetLiveInstance();
                    entityThing.SpawnNewInWorld();
                }

                foreach (IPathwayTemplate thing in TemplateCache.GetAll <IPathwayTemplate>().Where(dt => !entitiesToLoad.Any(ent => ent.TemplateId.Equals(dt.Id) && ent.Birthdate >= dt.LastRevised)))
                {
                    IPathway entityThing = Activator.CreateInstance(thing.EntityClass, new object[] { thing }) as IPathway;

                    entityThing.SpawnNewInWorld();
                }

                //We have the containers contents and the birthmarks from the deserial
                //I don't know how we can even begin to do this type agnostically since the collections are held on type specific objects without some super ugly reflection
                foreach (Room entity in entitiesToLoad.Where(ent => ent.GetType() == typeof(Room)))
                {
                    foreach (IInanimate obj in entity.Contents.EntitiesContained())
                    {
                        IInanimate fullObj = LiveCache.Get <IInanimate>(new LiveCacheKey(obj));
                        entity.MoveFrom(obj);
                        entity.MoveInto(fullObj);
                    }

                    foreach (INonPlayerCharacter obj in entity.MobilesInside.EntitiesContained())
                    {
                        INonPlayerCharacter fullObj = LiveCache.Get <INonPlayerCharacter>(new LiveCacheKey(obj));
                        entity.MoveFrom(obj);
                        entity.MoveInto(fullObj);
                    }
                }

                foreach (NonPlayerCharacter entity in entitiesToLoad.Where(ent => ent.GetType() == typeof(NonPlayerCharacter)))
                {
                    foreach (IInanimate obj in entity.Inventory.EntitiesContained())
                    {
                        IInanimate fullObj = LiveCache.Get <IInanimate>(new LiveCacheKey(obj));
                        entity.MoveFrom(obj);
                        entity.MoveInto(fullObj);
                    }
                }

                foreach (Inanimate entity in entitiesToLoad.Where(ent => ent.GetType() == typeof(Inanimate)))
                {
                    foreach (Tuple <string, IInanimate> obj in entity.Contents.EntitiesContainedByName())
                    {
                        IInanimate fullObj = LiveCache.Get <IInanimate>(new LiveCacheKey(obj.Item2));
                        entity.MoveFrom(obj.Item2);
                        entity.MoveInto(fullObj, obj.Item1);
                    }

                    foreach (Tuple <string, IInanimate> obj in entity.Contents.EntitiesContainedByName())
                    {
                        INonPlayerCharacter fullObj = LiveCache.Get <INonPlayerCharacter>(new LiveCacheKey(obj.Item2));
                        entity.MoveFrom((INonPlayerCharacter)obj.Item2);
                        entity.MoveInto(fullObj, obj.Item1);
                    }
                }

                //We need to poll the WorldMaps here and give all the rooms their coordinates as well as the zones their sub-maps
                ParseDimension();

                LoggingUtility.Log("World restored from current live.", LogChannels.Backup, false);
                return(true);
            }
            catch (Exception ex)
            {
                LoggingUtility.LogError(ex);
            }

            return(false);
        }