public static (GameObjectContainer, float) ReadSavegameFile(string fileName, string jsonFileName)
        {
            if (new FileInfo(fileName).Length > int.MaxValue)
            {
                throw new Exception("Input file is too large.");
            }

            Stream stream = new MemoryStream(File.ReadAllBytes(fileName));

            ArkSavegame arkSavegame = new ArkSavegame();

            // We're actually converting to json so we don't want to eliminate everything besides dinos.
            //bool PredicateCreatures(GameObject o) => !o.IsItem && (o.Parent != null || o.Components.Any());
            //bool PredicateCreaturesAndCryopods(GameObject o) => (!o.IsItem && (o.Parent != null || o.Components.Any())) || o.ClassString.Contains("Cryopod") || o.ClassString.Contains("SoulTrap_");

            using (ArkArchive archive = new ArkArchive(stream))
            {
                arkSavegame.ReadBinary(archive, ReadingOptions.Create()
                                       .WithDataFiles(false)
                                       .WithEmbeddedData(false)
                                       .WithDataFilesObjectMap(false)
                                       //.WithObjectFilter(new Predicate<GameObject>(PredicateCreaturesAndCryopods))
                                       .WithBuildComponentTree(true));
            }

            // Jenny's addition - immediately write the json format for any binary file we read in.
            using (StreamWriter file = File.CreateText(jsonFileName))
                using (JsonTextWriter writer = new JsonTextWriter(file))
                {
                    writer.Formatting = Formatting.Indented;
                    arkSavegame.WriteJson(writer, WritingOptions.Create());
                }
            // End of Jenny's addition.

            if (!arkSavegame.HibernationEntries.Any())
            {
                return(arkSavegame, arkSavegame.GameTime);
            }

            List <GameObject> combinedObjects = arkSavegame.Objects;

            foreach (HibernationEntry entry in arkSavegame.HibernationEntries)
            {
                ObjectCollector collector = new ObjectCollector(entry, 1);
                combinedObjects.AddRange(collector.Remap(combinedObjects.Count));
            }

            return(new GameObjectContainer(combinedObjects), arkSavegame.GameTime);
        }
        private static async Task <(GameObjectContainer, float)> ReadSavegameFile(string fileName)
        {
            return(await Task.Run(() =>
            {
                if (new FileInfo(fileName).Length > int.MaxValue)
                {
                    throw new Exception("Input file is too large.");
                }

                Stream stream = new MemoryStream(File.ReadAllBytes(fileName));

                ArkSavegame arkSavegame = new ArkSavegame();

                bool PredicateCreatures(GameObject o) => !o.IsItem && (o.Parent != null || o.Components.Any());
                bool PredicateCreaturesAndCryopods(GameObject o) => (!o.IsItem && (o.Parent != null || o.Components.Any())) || o.ClassString.Contains("Cryopod") || o.ClassString.Contains("SoulTrap_");

                using (ArkArchive archive = new ArkArchive(stream))
                {
                    arkSavegame.ReadBinary(archive, ReadingOptions.Create()
                                           .WithDataFiles(false)
                                           .WithEmbeddedData(false)
                                           .WithDataFilesObjectMap(false)
                                           .WithObjectFilter(Properties.Settings.Default.SaveImportCryo ? new Predicate <GameObject>(PredicateCreaturesAndCryopods) : new Predicate <GameObject>(PredicateCreatures))
                                           .WithBuildComponentTree(true));
                }

                if (!arkSavegame.HibernationEntries.Any())
                {
                    return (arkSavegame, arkSavegame.GameTime);
                }

                List <GameObject> combinedObjects = arkSavegame.Objects;

                foreach (HibernationEntry entry in arkSavegame.HibernationEntries)
                {
                    ObjectCollector collector = new ObjectCollector(entry, 1);
                    combinedObjects.AddRange(collector.Remap(combinedObjects.Count));
                }

                return (new GameObjectContainer(combinedObjects), arkSavegame.GameTime);
            }));
        }
Esempio n. 3
0
    private static Task <GameObjectContainer> ReadSavegameFile(string fileName)
    {
        return(Task.Run(() =>
        {
            if (new FileInfo(fileName).Length > int.MaxValue)
            {
                throw new Exception("Input file is too large.");
            }

            var arkSavegame = new ArkSavegame();

            using (var stream = new MemoryStream(File.ReadAllBytes(fileName)))
                using (var archive = new ArkArchive(stream))
                {
                    arkSavegame.ReadBinary(archive, ReadingOptions.Create()
                                           .WithDataFiles(false)
                                           .WithEmbeddedData(false)
                                           .WithDataFilesObjectMap(false)
                                           .WithObjectFilter(o => !o.IsItem && (o.Parent != null || o.Components.Any()))
                                           .WithBuildComponentTree(true));
                }

            if (!arkSavegame.HibernationEntries.Any())
            {
                return (arkSavegame);
            }

            var combinedObjects = arkSavegame.Objects;

            foreach (var entry in arkSavegame.HibernationEntries)
            {
                var collector = new ObjectCollector(entry, 1);
                combinedObjects.AddRange(collector.Remap(combinedObjects.Count));
            }

            return new GameObjectContainer(combinedObjects);
        }));
    }
        private void writeAnimalLists(Func <GameObject, bool> filter)
        {
            if (arkSavegame.HibernationEntries.Any())
            {
                List <GameObject> combinedObjects = arkSavegame.Objects;

                foreach (HibernationEntry entry in arkSavegame.HibernationEntries)
                {
                    ObjectCollector collector = new ObjectCollector(entry, 1);
                    combinedObjects.AddRange(collector.Remap(combinedObjects.Count));
                }

                container = new GameObjectContainer(combinedObjects);
            }
            else
            {
                container = arkSavegame;
            }

            IEnumerable <GameObject> objectStream = container.Where(o => o.IsCreature());

            if (filter != null)
            {
                objectStream = objectStream.Where(filter);
            }

            if (!untameable)
            {
                IEnumerable <string> untameableClasses = GlobalOptions.ArkToolsConfiguration.UntameableClasses?.Split(",").Select(s => s.Trim()) ?? Enumerable.Empty <string>();
                objectStream = objectStream.Where(gameObject => !gameObject.GetPropertyValue <bool>("bForceDisablingTaming"));
                objectStream = objectStream.Where(gameObject => !untameableClasses.Contains(gameObject.ClassString));
            }

            if (cleanFolder)
            {
                foreach (string path in Directory.EnumerateFiles(outputDirectory, "*.json"))
                {
                    File.Delete(path);
                }
            }

            Dictionary <string, List <GameObject> > dinoLists = objectStream.GroupBy(o => o.ClassString)
                                                                .ToDictionary(grouping => grouping.Key, grouping => grouping.ToList());

            if (!withoutIndex)
            {
                Dictionary <string, string> classNames = readClassNames();

                //Func<string, string> fetchName = key => ArkDataManager.GetCreature(key)?.Name ?? key;

                //foreach (string dinoClass in dinoLists.Keys.Where(dinoClass => !classNames.ContainsKey(dinoClass) || classNames[dinoClass] == null)) {
                foreach (string dinoClass in dinoLists.Keys.Where(dinoClass => !classNames.TryGetValue(dinoClass, out string value) || value == null))
                {
                    //string name = fetchName(dinoClass);
                    string name = ArkDataManager.GetCreature(dinoClass)?.Name ?? dinoClass;
                    if (name != null)
                    {
                        classNames.Add(dinoClass, name);
                    }
                }

                writeClassNames(classNames);

                foreach (string s in classNames.Keys.Where(s => !dinoLists.ContainsKey(s)))
                {
                    writeEmpty(s);
                }
            }

            foreach (KeyValuePair <string, List <GameObject> > dinoList in dinoLists)
            {
                writeList(dinoList);
            }
        }
Esempio n. 5
0
        protected override void RunCommand(IEnumerable <string> args)
        {
            List <string> argsList = args.ToList();

            if (showCommandHelp(argsList))
            {
                return;
            }

            if (withNames)
            {
                DataManager.ArkDataManager.LoadData(GlobalOptions.Language);
            }

            string savePath = argsList[0];

            Stopwatch stopwatch = new Stopwatch(GlobalOptions.UseStopWatch);

            // Don't load any properties, we don't need them
            ArkSavegame savegame = new ArkSavegame().ReadBinary <ArkSavegame>(savePath, ReadingOptions.Create()
                                                                              .WithObjectFilter(o => false)
                                                                              .WithBuildComponentTree(withoutDuplicates));

            stopwatch.Stop("Loading");

            List <GameObject> objects;
            //Dictionary<int, Dictionary<List<ArkName>, GameObject>> objectMap;
            Dictionary <int, Dictionary <int, GameObject> > objectMap;

            if (savegame.HibernationEntries.Any())
            {
                objects = new List <GameObject>(savegame.Objects);
                if (withoutDuplicates)
                {
                    objectMap = new Dictionary <int, Dictionary <int, GameObject> >();
                    foreach (KeyValuePair <int, Dictionary <int, GameObject> > pair in savegame.ObjectMap)
                    {
                        objectMap[pair.Key] = new Dictionary <int, GameObject>(pair.Value);
                    }
                }
                else
                {
                    objectMap = null;
                }

                foreach (HibernationEntry entry in savegame.HibernationEntries)
                {
                    ObjectCollector collector = new ObjectCollector(entry, 1);
                    objects.AddRange(collector.Remap(objects.Count));
                    if (withoutDuplicates)
                    {
                        foreach (GameObject gameObject in collector)
                        {
                            int key = gameObject.FromDataFile ? gameObject.DataFileIndex : -1;

                            if (!objectMap.ContainsKey(key))
                            {
                                objectMap[key] = new Dictionary <int, GameObject>();
                            }
                            if (!objectMap[key].ContainsKey(gameObject.Names.HashCode()))
                            {
                                objectMap[key][gameObject.Names.HashCode()] = gameObject;
                            }
                        }
                    }
                }
            }
            else
            {
                objects   = savegame.Objects;
                objectMap = savegame.ObjectMap;
            }

            if (withoutDuplicates)
            {
                //objects.removeIf((GameObject gameObject) => {
                //    int key = gameObject.IsFromDataFile ? gameObject.DataFileIndex : -1;
                //    return objectMap[key]?[gameObject.Names.HashCode()] != gameObject;
                //});
                objects = objects.Where(gameObject => {
                    int key = gameObject.FromDataFile ? gameObject.DataFileIndex : -1;
                    return(objectMap[key]?[gameObject.Names.HashCode()] == gameObject);
                }).ToList();
            }

            Dictionary <string, List <GameObject> > map = objects.GroupBy(o => o.ClassString)
                                                          .ToDictionary(grouping => grouping.Key, grouping => grouping.ToList());

            stopwatch.Stop("Grouping");

            WriteJsonCallback writer = (generator, writingOptions) => {
                generator.WriteStartObject();

                generator.WriteField("_count", objects.Count);

                foreach (KeyValuePair <string, List <GameObject> > entry in map.OrderByDescending(e => e.Value.Count))
                {
                    string name = entry.Key;

                    if (withNames)
                    {
                        if (entry.Value[0].IsItem)
                        {
                            if (DataManager.ArkDataManager.HasItem(name))
                            {
                                name = DataManager.ArkDataManager.GetItem(name).Name;
                            }
                        }
                        else
                        {
                            if (DataManager.ArkDataManager.HasCreature(name))
                            {
                                name = DataManager.ArkDataManager.GetCreature(name).Name;
                            }
                            else if (DataManager.ArkDataManager.HasStructure(name))
                            {
                                name = DataManager.ArkDataManager.GetStructure(name).Name;
                            }
                        }
                    }

                    generator.WriteField(name, entry.Value.Count);
                }

                generator.WriteEndObject();
            };

            if (argsList.Count > 1)
            {
                CommonFunctions.WriteJson(argsList[1], writer, writingOptions);
            }
            else
            {
                CommonFunctions.WriteJson(Console.OpenStandardOutput(), writer, writingOptions);
            }

            stopwatch.Stop("Writing");
            stopwatch.Print();
        }
Esempio n. 6
0
        protected override void RunCommand(IEnumerable <string> args)
        {
            List <string> argsList = args.ToList();

            if (showCommandHelp(argsList))
            {
                return;
            }

            bool itemsLong      = withItems == "long";
            bool inventoryLong  = withInventory == "long";
            bool tamedLong      = tamed == "long";
            bool structuresLong = withStructures == "long";

            Stopwatch stopwatch = new Stopwatch(GlobalOptions.UseStopWatch);

            bool mapNeeded = withItems != null || tamed != null || withStructures != null || withInventory != null;

            if (!GlobalOptions.Quiet && mapNeeded)
            {
                Console.WriteLine("Need to load map, this may take some time...");
            }

            string saveGame        = argsList.Count > 0 ? argsList[0] : Path.Combine(GlobalOptions.ArkToolsConfiguration.BasePath, GlobalOptions.ArkToolsConfiguration.ArkSavegameFilename);
            string outputDirectory = argsList.Count > 1 ? argsList[1] : Path.Combine(GlobalOptions.ArkToolsConfiguration.BasePath, GlobalOptions.ArkToolsConfiguration.TribesPath);
            string saveDir         = Path.GetDirectoryName(saveGame);

            Dictionary <int, HashSet <TribeBase> > baseMap;
            CustomDataContext context = new CustomDataContext();

            if (mapNeeded)
            {
                ArkDataManager.LoadData(GlobalOptions.Language);

                ArkSavegame mapSave = new ArkSavegame().ReadBinary <ArkSavegame>(saveGame, ReadingOptions.Create().WithBuildComponentTree(true));
                context.Savegame = mapSave;
                context.MapData  = LatLonCalculator.ForSave(context.Savegame);
                stopwatch.Stop("Loading map data");
                if (withBases)
                {
                    baseMap = new Dictionary <int, HashSet <TribeBase> >();
                    foreach (GameObject gameObject in mapSave)
                    {
                        // Skip items and stuff without a location
                        if (gameObject.IsItem || gameObject.Location == null)
                        {
                            continue;
                        }

                        string signText      = gameObject.GetPropertyValue <string>("SignText");
                        long?  targetingTeam = gameObject.GetPropertyValue <long?>("TargetingTeam");

                        if (signText != null && targetingTeam != null)
                        {
                            // Might be a 'Base' sign
                            MatchCollection matcher = basePattern.Matches(signText);
                            if (matcher.Any())
                            {
                                // Found a base sign, add it to the set, automatically replacing duplicates
                                int          tribeId  = (int)targetingTeam;
                                LocationData location = gameObject.Location;
                                string       baseName = matcher[1].Value;
                                float        size     = float.Parse(matcher[2].Value);

                                TribeBase tribeBase = new TribeBase(baseName, location.X, location.Y, location.Z, size);

                                if (!baseMap.ContainsKey(tribeId))
                                {
                                    baseMap[tribeId] = new HashSet <TribeBase>();
                                }

                                baseMap[tribeId].Add(tribeBase);
                            }
                        }
                    }

                    stopwatch.Stop("Collecting bases");
                }
                else
                {
                    baseMap = null;
                }

                if (mapSave.HibernationEntries.Any() && tamed != null)
                {
                    List <GameObject> combinedObjects = context.Savegame.Objects.ToList();

                    foreach (HibernationEntry entry in context.Savegame.HibernationEntries)
                    {
                        ObjectCollector collector = new ObjectCollector(entry, 1);
                        combinedObjects.AddRange(collector.Remap(combinedObjects.Count));
                    }

                    context.ObjectContainer = new GameObjectContainer(combinedObjects);
                }
                else
                {
                    context.ObjectContainer = mapSave;
                }
            }
            else
            {
                baseMap = null;
            }

            List <Action> tasks = GlobalOptions.Parallel ? new List <Action>() : null;

            void mapWriter(JsonTextWriter generator, int tribeId)
            {
                if (!mapNeeded)
                {
                    return;
                }
                List <GameObject>  structures   = new List <GameObject>();
                List <GameObject>  creatures    = new List <GameObject>();
                List <Item>        items        = new List <Item>();
                List <Item>        blueprints   = new List <Item>();
                List <DroppedItem> droppedItems = new List <DroppedItem>();
                // Apparently there is a behavior in ARK causing certain structures to exist twice within a save
                HashSet <ArkName> processedList = new HashSet <ArkName>();
                // Bases
                HashSet <TribeBase> bases = withBases ? baseMap[tribeId] : null;

                foreach (GameObject gameObject in context.ObjectContainer)
                {
                    if (gameObject.IsItem)
                    {
                        continue;
                    }

                    int targetingTeam = gameObject.GetPropertyValue <int>("TargetingTeam", defaultValue: -1);
                    if (targetingTeam == -1)
                    {
                        continue;
                    }

                    TeamType teamType = TeamTypes.ForTeam(targetingTeam);
                    if (tribeId == -1 && teamType != TeamType.Player)
                    {
                        continue;
                    }

                    if (tribeId == 0 && teamType != TeamType.NonPlayer)
                    {
                        continue;
                    }

                    if (tribeId > 0 && tribeId != targetingTeam)
                    {
                        continue;
                    }

                    // Determine base if we have bases
                    TribeBase tribeBase;
                    if (bases != null && gameObject.Location != null)
                    {
                        TribeBase matchedBase = null;
                        foreach (TribeBase potentialBase in bases)
                        {
                            if (potentialBase.InsideBounds(gameObject.Location))
                            {
                                matchedBase = potentialBase;
                                break;
                            }
                        }

                        tribeBase = matchedBase;
                    }
                    else
                    {
                        tribeBase = null;
                    }

                    if (gameObject.IsCreature())
                    {
                        if (!processedList.Contains(gameObject.Names[0]))
                        {
                            if (tribeBase != null)
                            {
                                tribeBase.Creatures.Add(gameObject);
                            }
                            else
                            {
                                creatures.Add(gameObject);
                            }

                            processedList.Add(gameObject.Names[0]);
                        }
                        else
                        {
                            // Duped Creature
                            continue;
                        }
                    }
                    else if (!gameObject.IsPlayer() && !gameObject.IsWeapon() && !gameObject.IsDroppedItem())
                    {
                        // LinkedPlayerDataID: Players ain't structures
                        // AssociatedPrimalItem: Items equipped by sleeping players
                        // MyItem: dropped item
                        if (!processedList.Contains(gameObject.Names[0]))
                        {
                            if (tribeBase != null)
                            {
                                tribeBase.Structures.Add(gameObject);
                            }
                            else
                            {
                                structures.Add(gameObject);
                            }

                            processedList.Add(gameObject.Names[0]);
                        }
                        else
                        {
                            // Duped Structure
                            continue;
                        }
                    }
                    else
                    {
                        if (!processedList.Contains(gameObject.Names[0]))
                        {
                            processedList.Add(gameObject.Names[0]);
                        }
                        else
                        {
                            // Duped Player or dropped Item or weapon
                            continue;
                        }
                    }

                    void itemHandler(ObjectReference itemReference)
                    {
                        GameObject item = itemReference.GetObject(context.Savegame);

                        if (item != null && !Item.isDefaultItem(item))
                        {
                            if (processedList.Contains(item.Names[0]))
                            {
                                // happens for players having items in their quick bar
                                return;
                            }

                            processedList.Add(item.Names[0]);

                            if (item.HasAnyProperty("bIsBlueprint"))
                            {
                                if (tribeBase != null)
                                {
                                    tribeBase.Blueprints.Add(new Item(item));
                                }
                                else
                                {
                                    blueprints.Add(new Item(item));
                                }
                            }
                            else
                            {
                                if (tribeBase != null)
                                {
                                    tribeBase.Items.Add(new Item(item));
                                }
                                else
                                {
                                    items.Add(new Item(item));
                                }
                            }
                        }
                    }

                    void droppedItemHandler(GameObject droppedItemObject)
                    {
                        DroppedItem droppedItem = new DroppedItem(droppedItemObject, context.Savegame);

                        if (tribeBase != null)
                        {
                            tribeBase.DroppedItems.Add(droppedItem);
                        }
                        else
                        {
                            droppedItems.Add(droppedItem);
                        }
                    }

                    if (withItems != null && withInventory == null)
                    {
                        foreach (GameObject inventory in gameObject.Components.Values)
                        {
                            if (!inventory.IsInventory())
                            {
                                continue;
                            }

                            List <ObjectReference> inventoryItems = inventory.GetPropertyValue <IArkArray, ArkArrayObjectReference>("InventoryItems");
                            foreach (ObjectReference itemReference in inventoryItems ?? Enumerable.Empty <ObjectReference>())
                            {
                                itemHandler(itemReference);
                            }

                            List <ObjectReference> equippedItems = inventory.GetPropertyValue <IArkArray, ArkArrayObjectReference>("EquippedItems");
                            foreach (ObjectReference itemReference in equippedItems ?? Enumerable.Empty <ObjectReference>())
                            {
                                itemHandler(itemReference);
                            }
                        }
                    }

                    ObjectReference myItem = gameObject.GetPropertyValue <ObjectReference>("MyItem");

                    if (myItem != null)
                    {
                        if (withItems != null && withInventory == null)
                        {
                            itemHandler(myItem);
                        }
                        else if (withInventory != null)
                        {
                            droppedItemHandler(gameObject);
                        }
                    }
                }

                void writeStructures(IEnumerable <GameObject> structList)
                {
                    if (withStructures == null)
                    {
                        return;
                    }
                    generator.WriteArrayFieldStart("structures");

                    if (structuresLong)
                    {
                        foreach (GameObject structureObject in structList)
                        {
                            Structure structure = new Structure(structureObject, context.Savegame);

                            generator.WriteStartObject();

                            structure.writeAllProperties(generator, context, writeAllFields);

                            if (withInventory != null)
                            {
                                structure.writeInventory(generator, context, writeAllFields, !inventoryLong);
                            }

                            generator.WriteEndObject();
                        }
                    }
                    else
                    {
                        Dictionary <ArkName, long> structMap = structList.GroupBy(o => o.ClassName).ToDictionary(objects => objects.Key, objects => objects.LongCount());
                        foreach (KeyValuePair <ArkName, long> entry in structMap.OrderByDescending(pair => pair.Value))
                        {
                            generator.WriteStartObject();

                            string name = entry.Key.ToString();
                            if (ArkDataManager.HasStructure(name))
                            {
                                name = ArkDataManager.GetStructure(name).Name;
                            }

                            generator.WriteField("name", name);
                            generator.WriteField("count", entry.Value);

                            generator.WriteEndObject();
                        }
                    }

                    generator.WriteEndArray();
                }

                void writeCreatures(List <GameObject> creaList)
                {
                    if (tamed == null)
                    {
                        return;
                    }
                    generator.WriteArrayFieldStart("tamed");

                    if (tamedLong)
                    {
                        foreach (GameObject creatureObject in creaList)
                        {
                            Creature creature = new Creature(creatureObject, context.Savegame);

                            generator.WriteStartObject();

                            creature.writeAllProperties(generator, context, writeAllFields);

                            if (withInventory != null)
                            {
                                creature.writeInventory(generator, context, writeAllFields, !inventoryLong);
                            }

                            generator.WriteEndObject();
                        }
                    }
                    else
                    {
                        Dictionary <ArkName, long> creaMap = creaList.GroupBy(o => o.ClassName).ToDictionary(objects => objects.Key, objects => objects.LongCount());
                        foreach (KeyValuePair <ArkName, long> entry in creaMap.OrderByDescending(pair => pair.Value))
                        {
                            generator.WriteStartObject();

                            string name = entry.Key.ToString();
                            if (ArkDataManager.HasCreature(name))
                            {
                                name = ArkDataManager.GetCreature(name).Name;
                            }

                            generator.WriteField("name", name);
                            generator.WriteField("count", entry.Value);

                            generator.WriteEndObject();
                        }
                    }

                    generator.WriteEndArray();
                }

                void writeDroppedItems(List <DroppedItem> droppedList)
                {
                    if (withInventory == null)
                    {
                        return;
                    }
                    generator.WriteArrayFieldStart("droppedItems");

                    foreach (DroppedItem droppedItem in droppedList)
                    {
                        generator.WriteStartObject();

                        droppedItem.writeAllProperties(generator, context, writeAllFields);
                        droppedItem.writeInventory(generator, context, writeAllFields, !inventoryLong);

                        generator.WriteEndObject();
                    }

                    generator.WriteEndArray();
                }

                if (withBases && bases != null)
                {
                    generator.WriteArrayFieldStart("bases");

                    foreach (TribeBase tribeBase in bases)
                    {
                        generator.WriteStartObject();

                        generator.WriteField("name", tribeBase.Name);
                        generator.WriteField("x", tribeBase.X);
                        generator.WriteField("y", tribeBase.Y);
                        generator.WriteField("z", tribeBase.Z);
                        generator.WriteField("lat", context.MapData.CalculateLat(tribeBase.Y));
                        generator.WriteField("lon", context.MapData.CalculateLon(tribeBase.X));
                        generator.WriteField("radius", tribeBase.Size);
                        writeCreatures(tribeBase.Creatures);
                        writeStructures(tribeBase.Structures);
                        writeDroppedItems(tribeBase.DroppedItems);
                        if (itemsLong)
                        {
                            generator.WritePropertyName("items");
                            Inventory.writeInventoryLong(generator, context, tribeBase.Items, writeAllFields);
                            generator.WritePropertyName("blueprints");
                            Inventory.writeInventoryLong(generator, context, tribeBase.Blueprints, writeAllFields);
                        }
                        else
                        {
                            generator.WritePropertyName("items");
                            Inventory.writeInventorySummary(generator, tribeBase.Items);
                            generator.WritePropertyName("blueprints");
                            Inventory.writeInventorySummary(generator, tribeBase.Blueprints);
                        }

                        generator.WriteEndObject();
                    }

                    generator.WriteStartObject();
                }

                writeCreatures(creatures);
                writeStructures(structures);
                writeDroppedItems(droppedItems);
                if (itemsLong)
                {
                    generator.WritePropertyName("items");
                    Inventory.writeInventoryLong(generator, context, items, writeAllFields);
                    generator.WritePropertyName("blueprints");
                    Inventory.writeInventoryLong(generator, context, blueprints, writeAllFields);
                }
                else
                {
                    generator.WritePropertyName("items");
                    Inventory.writeInventorySummary(generator, items);
                    generator.WritePropertyName("blueprints");
                    Inventory.writeInventorySummary(generator, blueprints);
                }

                if (withBases && bases != null)
                {
                    generator.WriteEndObject();

                    generator.WriteEndArray();
                }
            }

            foreach (string path in Directory.EnumerateFiles(saveDir).Where(path => tribePattern.IsMatch(path)))
            {
                Action task = () => {
                    try {
                        Tribe tribe = new Tribe(path, ReadingOptions.Create());

                        string tribeFileName = tribe.tribeId + ".json";

                        string tribePath = Path.Combine(outputDirectory, tribeFileName);

                        CommonFunctions.WriteJson(tribePath, (generator, writingOptions) => {
                            generator.WriteStartObject();

                            tribe.writeAllProperties(generator, context, writeAllFields);

                            mapWriter(generator, tribe.tribeId);

                            generator.WriteEndObject();
                        }, writingOptions);
                    } catch (Exception ex) {
                        Console.Error.WriteLine("Found potentially corrupt ArkTribe: " + path);
                        if (GlobalOptions.Verbose)
                        {
                            Console.Error.WriteLine(ex.Message);
                            Console.Error.WriteLine(ex.StackTrace);
                        }
                    }
                };

                if (tasks != null)
                {
                    tasks.Add(task);
                }
                else
                {
                    task();
                }
            }

            if (tasks != null)
            {
                Parallel.ForEach(tasks, task => task());
            }

            if (tribeless)
            {
                string tribePath = Path.Combine(outputDirectory, "tribeless.json");

                CommonFunctions.WriteJson(tribePath, (generator, writingOptions) => {
                    generator.WriteStartObject();

                    mapWriter(generator, -1);

                    generator.WriteEndObject();
                }, writingOptions);
            }

            if (nonPlayers)
            {
                string tribePath = Path.Combine(outputDirectory, "non-players.json");

                CommonFunctions.WriteJson(tribePath, (generator, writingOptions) => {
                    generator.WriteStartObject();

                    mapWriter(generator, 0);

                    generator.WriteEndObject();
                }, writingOptions);
            }

            stopwatch.Stop("Loading tribes and writing info");
            stopwatch.Print();
        }
Esempio n. 7
0
        public void LoadSavegame(string path)
        {
            Savegame = new ArkSavegame().ReadBinary <ArkSavegame>(path, ReadingOptions.Create()
                                                                  // Skip things like NPCZoneVolume and non-instanced objects
                                                                  .WithObjectFilter(obj => !obj.FromDataFile && (obj.Names.Count > 1 || obj.Names[0].Instance > 0))
                                                                  .WithBuildComponentTree(true));
            MapData = LatLonCalculator.ForSave(Savegame);

            if (Savegame.HibernationEntries.Any())
            {
                List <GameObject> combinedObjects = new List <GameObject>(Savegame.Objects);

                foreach (HibernationEntry entry in Savegame.HibernationEntries)
                {
                    ObjectCollector collector = new ObjectCollector(entry, 1);
                    combinedObjects.AddRange(collector.Remap(combinedObjects.Count));
                }

                ObjectContainer = new GameObjectContainer(combinedObjects);
            }
            else
            {
                ObjectContainer = Savegame;
            }

            foreach (GameObject gameObject in ObjectContainer)
            {
                if (gameObject.FromDataFile || (gameObject.Names.Count == 1 && gameObject.Names[0].Instance == 0))
                {
                    // Skip things like NPCZoneVolume and non-instanced objects
                }
                else if (gameObject.IsInventory())
                {
                    InventoryMap[gameObject.Id] = new Inventory(gameObject);
                }
                else
                {
                    if (!nameObjectMap.ContainsKey(gameObject.Names[0]))
                    {
                        nameObjectMap[gameObject.Names[0]] = gameObject.Id;
                        if (gameObject.IsItem)
                        {
                            ItemMap[gameObject.Id] = new Item(gameObject);
                        }
                        else if (gameObject.IsCreature())
                        {
                            CreatureMap[gameObject.Id] = new Creature(gameObject, Savegame);
                        }
                        else if (gameObject.Location != null &&
                                 !gameObject.IsPlayer() &&
                                 !gameObject.IsDroppedItem() &&
                                 !gameObject.IsWeapon())
                        {
                            // Skip players, weapons and items on the ground
                            // is (probably) a structure
                            StructureMap[gameObject.Id] = new Structure(gameObject, Savegame);
                        }
                        else if (gameObject.IsDroppedItem())
                        {
                            // dropped Item
                            DroppedItemMap[gameObject.Id] = new DroppedItem(gameObject, Savegame);
                        }
                    }
                }
            }
        }