示例#1
0
 public override (IToken token, int length) ReadToken(string text, int offset, ReadingOptions options)
 {
     CheckArguments(text, offset);
     return(offset == text.Length ? (null, 0) : (new TextToken(text[offset].ToString()), 1));
 }
示例#2
0
        protected override void RunCommand(IEnumerable <string> args)
        {
            List <string> argsList = args.ToList();

            if (showCommandHelp(argsList))
            {
                return;
            }

            string savePath = argsList[0];

            Stopwatch stopwatch = new Stopwatch(GlobalOptions.UseStopWatch);

            ArkSavegame savegame = new ArkSavegame().ReadBinary <ArkSavegame>(savePath, ReadingOptions.Create());

            stopwatch.Stop("Loading");

            List <GameObject> hibernationObjects = new List <GameObject>();

            foreach (HibernationEntry entry in savegame.HibernationEntries)
            {
                hibernationObjects.AddRange(entry.Objects);
            }

            List <SizeObjectPair> pairList = savegame.Objects.Select(gameObject => new SizeObjectPair(gameObject, savegame.SaveVersion < 6, false))
                                             .Concat(hibernationObjects.Select(gameObject => new SizeObjectPair(gameObject, false, true)))
                                             .OrderByDescending(sizeObjectPair => sizeObjectPair.Size)
                                             .ToList();

            stopwatch.Stop("Collecting");

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

                foreach (SizeObjectPair pair in pairList)
                {
                    generator.WriteStartObject();
                    generator.WriteArrayFieldStart("names");
                    foreach (ArkName name in pair.GameObject.Names)
                    {
                        generator.WriteValue(name.ToString());
                    }
                    generator.WriteEndArray();
                    if (pair.GameObject.FromDataFile)
                    {
                        generator.WriteField("dataFileIndex", pair.GameObject.DataFileIndex);
                    }
                    generator.WriteField("class", pair.GameObject.ClassString);
                    generator.WriteField("size", pair.Size);
                    generator.WriteEndObject();
                }

                generator.WriteEndArray();
            };

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

            stopwatch.Stop("Writing");
            stopwatch.Print();
        }
示例#3
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();
        }
示例#4
0
        public Tribe(string path, ReadingOptions ro)
        {
            ArkTribe tribe = new ArkTribe().ReadBinary <ArkTribe>(path, ro);

            StructPropertyList tribeData = tribe.GetPropertyValue <IStruct, StructPropertyList>("TribeData");

            tribeName         = tribeData.GetPropertyValue <string>("TribeName", defaultValue: string.Empty);
            ownerPlayerDataId = tribeData.GetPropertyValue <int>("OwnerPlayerDataID");
            tribeId           = tribeData.GetPropertyValue <int>("TribeID");

            ArkArrayString membersNames = tribeData.GetPropertyValue <IArkArray, ArkArrayString>("MembersPlayerName");

            if (membersNames != null)
            {
                membersPlayerName.AddRange(membersNames);
                foreach (string memberName in membersNames)
                {
                    membersPlayerName.Add(memberName);
                }
            }

            ArkArrayUInt32 membersData = tribeData.GetPropertyValue <IArkArray, ArkArrayUInt32>("MembersPlayerDataID");

            if (membersData != null)
            {
                foreach (int memberDataId in membersData)
                {
                    membersPlayerDataId.Add(memberDataId);
                }
            }

            ArkArrayUInt32 tribeAdminIds = tribeData.GetPropertyValue <IArkArray, ArkArrayUInt32>("TribeAdmins");

            if (tribeAdminIds != null)
            {
                foreach (int tribeAdmin in tribeAdminIds)
                {
                    tribeAdmins.Add(tribeAdmin);
                }
            }

            ArkArrayInt8 memberRankGroups = tribeData.GetPropertyValue <IArkArray, ArkArrayInt8>("MembersRankGroups");

            if (memberRankGroups != null)
            {
                foreach (byte memberRankGroup in memberRankGroups)
                {
                    membersRankGroups.Add(memberRankGroup);
                }
            }

            setGovernment = tribeData.GetPropertyValue <bool>("SetGovernment");

            IPropertyContainer tribeGovernment = tribeData.GetPropertyValue <IStruct, IPropertyContainer>("TribeGovernment");

            if (tribeGovernment != null)
            {
                tribeGovernPINCode              = tribeGovernment.GetPropertyValue <int>("TribeGovern_PINCode");
                tribeGovernDinoOwnership        = tribeGovernment.GetPropertyValue <int>("TribeGovern_DinoOwnership");
                tribeGovernStructureOwnership   = tribeGovernment.GetPropertyValue <int>("TribeGovern_StructureOwnership");
                tribeGovernDinoTaming           = tribeGovernment.GetPropertyValue <int>("TribeGovern_DinoTaming");
                tribeGovernDinoUnclaimAdminOnly = tribeGovernment.GetPropertyValue <int>("TribeGovern_DinoUnclaimAdminOnly");
            }
            else
            {
                tribeGovernDinoOwnership      = 1;
                tribeGovernStructureOwnership = 1;
            }

            ArkArrayString logEntrys = tribeData.GetPropertyValue <IArkArray, ArkArrayString>("TribeLog");

            if (logEntrys != null)
            {
                foreach (string log in logEntrys)
                {
                    tribeLog.Add(log);
                }
            }

            logIndex = tribeData.GetPropertyValue <int>("LogIndex");

            ArkArrayStruct tribeRankStructs = tribeData.GetPropertyValue <IStruct, ArkArrayStruct>("TribeRankGroups");

            if (tribeRankStructs != null)
            {
                foreach (IStruct tribeRankStruct in tribeRankStructs)
                {
                    tribeRankGroups.Add(new TribeRankGroup((IPropertyContainer)tribeRankStruct));
                }
            }
        }
示例#5
0
        protected override void RunCommand(IEnumerable <string> args)
        {
            List <string> argsList = args.ToList();

            if (showCommandHelp(argsList))
            {
                return;
            }

            string savePath  = argsList[0];
            string className = argsList[1];

            Stopwatch stopwatch = new Stopwatch(GlobalOptions.UseStopWatch);

            Predicate <GameObject> filter = gameObject => gameObject.ClassString == className;

            ArkSavegame savegame = new ArkSavegame().ReadBinary <ArkSavegame>(savePath, ReadingOptions.Create().WithObjectFilter(filter));

            stopwatch.Stop("Loading");

            WriteJsonCallback dumpObjects = (generator, writingOptions) => {
                generator.WriteStartArray();

                foreach (GameObject gameObject in savegame)
                {
                    if (filter.Invoke(gameObject))
                    {
                        gameObject.WriteJson(generator, writingOptions);
                    }
                }

                foreach (HibernationEntry entry in savegame.HibernationEntries)
                {
                    foreach (GameObject gameObject in entry)
                    {
                        if (filter.Invoke(gameObject))
                        {
                            gameObject.WriteJson(generator, writingOptions);
                        }
                    }
                }

                generator.WriteEndArray();
            };

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

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

            if (showCommandHelp(argsList))
            {
                return;
            }

            string clusterDirectory = argsList[0];
            string outputDirectory  = argsList[1];

            ArkDataManager.LoadData(GlobalOptions.Language);

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

            Stopwatch stopwatch = new Stopwatch(GlobalOptions.UseStopWatch);

            foreach (string path in Directory.EnumerateFiles(clusterDirectory))
            {
                Action task = () => {
                    try {
                        ArkCloudInventory cloudInventory = new ArkCloudInventory().ReadBinary <ArkCloudInventory>(path, ReadingOptions.Create());

                        CustomDataContext context = new CustomDataContext {
                            ObjectContainer = cloudInventory
                        };

                        IPropertyContainer arkData = cloudInventory.InventoryData.GetPropertyValue <IPropertyContainer>("MyArkData");

                        CommonFunctions.WriteJson(Path.Combine(outputDirectory, path + ".json"), (generator, writingOptions) => {
                            generator.WriteStartObject();

                            ArkArrayStruct tamedDinosData = arkData.GetPropertyValue <ArkArrayStruct>("ArkTamedDinosData");
                            if (tamedDinosData != null && tamedDinosData.Any())
                            {
                                generator.WriteArrayFieldStart("creatures");
                                foreach (IStruct dinoStruct in tamedDinosData)
                                {
                                    IPropertyContainer dino = (IPropertyContainer)dinoStruct;
                                    ArkContainer container  = null;
                                    if (cloudInventory.InventoryVersion == 1)
                                    {
                                        ArkArrayUInt8 byteData = dino.GetPropertyValue <ArkArrayUInt8>("DinoData");

                                        container = new ArkContainer(byteData);
                                    }
                                    else if (cloudInventory.InventoryVersion == 3)
                                    {
                                        ArkArrayInt8 byteData = dino.GetPropertyValue <ArkArrayInt8>("DinoData");

                                        container = new ArkContainer(byteData);
                                    }

                                    ObjectReference dinoClass = dino.GetPropertyValue <ObjectReference>("DinoClass");
                                    // Skip "BlueprintGeneratedClass " = 24 chars
                                    string dinoClassName = dinoClass.ObjectString.ToString().Substring(24);
                                    generator.WriteStartObject();

                                    generator.WriteField("type",
                                                         ArkDataManager.HasCreatureByPath(dinoClassName) ? ArkDataManager.GetCreatureByPath(dinoClassName).Name : dinoClassName);

                                    // NPE for unknown versions
                                    Creature creature = new Creature(container.Objects[0], container);
                                    generator.WriteObjectFieldStart("data");
                                    creature.writeAllProperties(generator, context, writeAllFields);
                                    generator.WriteEndObject();

                                    generator.WriteEndObject();
                                }

                                generator.WriteEndArray();
                            }

                            ArkArrayStruct arkItems = arkData.GetPropertyValue <ArkArrayStruct>("ArkItems");
                            if (arkItems != null)
                            {
                                List <Item> items = new List <Item>();
                                foreach (IStruct itemStruct in arkItems)
                                {
                                    IPropertyContainer item    = (IPropertyContainer)itemStruct;
                                    IPropertyContainer netItem = item.GetPropertyValue <IPropertyContainer>("ArkTributeItem");

                                    items.Add(new Item(netItem));
                                }

                                if (items.Any())
                                {
                                    generator.WritePropertyName("items");
                                    Inventory.writeInventoryLong(generator, context, items, writeAllFields);
                                }
                            }

                            generator.WriteEndObject();
                        }, writingOptions);
                    } catch (Exception ex) {
                        Console.Error.WriteLine("Found potentially corrupt cluster data: " + 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());
            }

            stopwatch.Stop("Loading cluster data and writing info");
            stopwatch.Print();
        }
示例#7
0
        public override (IToken token, int length) ReadToken(string text, int offset, ReadingOptions options)
        {
            CheckArguments(text, offset);
            var innerTokens = new List <IToken>();
            var currentIdx  = offset;

            if (!text.StartsWith(StartSymbols, currentIdx))
            {
                return(null, 0);
            }
            currentIdx += StartSymbols.Length;
            var allowedInnerReaders = options.GetAvailableInnerReadersFor(this);

            do
            {
                var(innerToken, innerTokenLength) = allowedInnerReaders
                                                    .Select(reader => reader.ReadToken(text, currentIdx, options.WithAllowedReaders(allowedInnerReaders)))
                                                    .FirstOrDefault(readingResult => readingResult.token != null);
                if (innerTokenLength == 0)
                {
                    return(null, 0);
                }
                innerTokens.Add(innerToken);
                currentIdx += innerTokenLength;
            } while (!text.StartsWith(MiddleSymbols, currentIdx));

            currentIdx        += MiddleSymbols.Length;
            var(token, length) = pureLinkReader.ReadToken(text, currentIdx, options);
            currentIdx        += length;
            return(text.StartsWith(EndSymbols, currentIdx)
                ? (new LinkToken(innerTokens, (token as TextToken)?.Value ?? ""), currentIdx + EndSymbols.Length)
                : (null, 0));
        }
示例#8
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();
        }
示例#9
0
        protected override void RunCommand(IEnumerable <string> args)
        {
            List <string> argsList = args.ToList();

            if (showCommandHelp(argsList))
            {
                return;
            }

            ArkDataManager.LoadData(GlobalOptions.Language);

            Stopwatch stopwatch = new Stopwatch(GlobalOptions.UseStopWatch);

            bool mapNeeded = !string.IsNullOrEmpty(inventory) || positions;

            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.PlayersPath);
            string saveDir         = Path.GetDirectoryName(saveGame);

            CustomDataContext context = new CustomDataContext();

            if (mapNeeded)
            {
                ArkSavegame mapSave = new ArkSavegame().ReadBinary <ArkSavegame>(saveGame, ReadingOptions.Create().WithBuildComponentTree(true));
                context.ObjectContainer = mapSave;
                context.Savegame        = mapSave;
                context.MapData         = LatLonCalculator.ForSave(mapSave);
                stopwatch.Stop("Loading map data");
            }

            Dictionary <int, Tribe> tribes = new Dictionary <int, Tribe>();
            List <Action>           tasks  = GlobalOptions.Parallel ? new List <Action>() : null;

            foreach (string path in Directory.EnumerateFiles(saveDir).Where(path => profilePattern.IsMatch(Path.GetFileName(path))))
            {
                if (maxAge.HasValue)
                {
                    DateTimeOffset fileTime = File.GetLastWriteTimeUtc(path);

                    if (fileTime < DateTimeOffset.UtcNow.AddSeconds(-maxAge.Value))
                    {
                        continue;
                    }
                }

                Action task = () => {
                    try {
                        Player player = new Player(path, context, ReadingOptions.Create());

                        long playerId = player.playerDataId;

                        string playerFileName;
                        if (naming == "steamid" || string.IsNullOrWhiteSpace(naming))
                        {
                            playerFileName = player.uniqueId.NetId + ".json";
                        }
                        else if (naming == "playerid")
                        {
                            playerFileName = playerId + ".json";
                        }
                        else
                        {
                            throw new Exception("Invalid value for parameter naming.");
                        }

                        if (player.tribeId != 0)
                        {
                            if (!tribes.ContainsKey(player.tribeId))
                            {
                                string tribePath = Path.Combine(saveDir, player.tribeId + ".arktribe");
                                if (File.Exists(tribePath))
                                {
                                    try {
                                        tribes[player.tribeId] = new Tribe(tribePath, ReadingOptions.Create());
                                    } catch (Exception ex) {
                                        // Either the header didn't match or one of the properties is missing
                                        Console.Error.WriteLine("Found potentially corrupt ArkTribe: " + tribePath);
                                        if (GlobalOptions.Verbose)
                                        {
                                            Console.Error.WriteLine(ex.Message);
                                            Console.Error.WriteLine(ex.StackTrace);
                                        }
                                    }
                                }
                            }
                        }

                        string playerPath = Path.Combine(outputDirectory, playerFileName);

                        void writePlayer(JsonTextWriter writer, WritingOptions options)
                        {
                            writer.WriteStartObject();

                            // Player data

                            player.WriteAllProperties(writer, context, writeAllFields, noPrivacy);

                            // Inventory
                            if (!string.IsNullOrEmpty(inventory))
                            {
                                player.WriteInventory(writer, context, writeAllFields, inventory.ToLowerInvariant() != "long");
                            }

                            // Tribe

                            if (player.tribeId != 0 && tribes.TryGetValue(player.tribeId, out Tribe tribe))
                            {
                                writer.WriteField("tribeName", tribe.tribeName);

                                if (writeAllFields || tribe.ownerPlayerDataId == playerId)
                                {
                                    writer.WriteField("tribeOwner", tribe.ownerPlayerDataId == playerId);
                                }

                                if (writeAllFields || tribe.tribeAdmins.Contains((int)playerId))
                                {
                                    writer.WriteField("tribeAdmin", tribe.tribeAdmins.Contains((int)playerId));
                                }
                            }

                            writer.WriteEndObject();
                        }

                        CommonFunctions.WriteJson(playerPath, writePlayer, writingOptions);
                    } catch (Exception ex) when(!Debugger.IsAttached)
                    {
                        Console.Error.WriteLine("Found potentially corrupt ArkProfile: " + 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());
            }

            stopwatch.Stop("Loading profiles and writing info");
            stopwatch.Print();
        }
示例#10
0
        public override (IToken token, int length) ReadToken(string text, int offset, ReadingOptions options)
        {
            CheckArguments(text, offset);
            var nextSymbolIdx = offset + 1;

            if (nextSymbolIdx < text.Length + 1 && text[offset] == '\\')
            {
                return(new TextToken(text[nextSymbolIdx].ToString()), 2);
            }
            return(null, 0);
        }
示例#11
0
        public Player(string path, IDataContext context, ReadingOptions ro)
        {
            ArkProfile profile = new ArkProfile().ReadBinary <ArkProfile>(path, ro);

            savedPlayerDataVersion = profile.GetPropertyValue <int>("SavedPlayerDataVersion");

            StructPropertyList myData = profile.GetPropertyValue <IStruct, StructPropertyList>("MyData");

            playerDataId        = myData.GetPropertyValue <long>("PlayerDataID");
            uniqueId            = myData.GetPropertyValue <IStruct, StructUniqueNetIdRepl>("UniqueID");
            savedNetworkAddress = myData.GetPropertyValue <string>("SavedNetworkAddress");
            playerName          = myData.GetPropertyValue <string>("PlayerName");
            tribeId             = myData.GetPropertyValue <int>("TribeID");
            playerDataVersion   = myData.GetPropertyValue <int>("PlayerDataVersion");
            spawnDayNumber      = myData.GetPropertyValue <int>("SpawnDayNumber");
            spawnDayTime        = myData.GetPropertyValue <float>("SpawnDayTime");

            IPropertyContainer characterConfig = myData.GetPropertyValue <IStruct, IPropertyContainer>("MyPlayerCharacterConfig");

            // Character data

            isFemale   = characterConfig.GetPropertyValue <bool>("bIsFemale");
            bodyColors = Enumerable.Range(0, PlayerBodyColorRegions.Instance.Count).Select(i => characterConfig.GetPropertyValue <IStruct, StructLinearColor>("BodyColors", i)).ToArray();
            //for (int i = 0; i < PlayerBodyColorRegions.Instance.Count; i++) {
            //    bodyColors[i] = characterConfig.getPropertyValue<IStruct, StructLinearColor>("BodyColors", i);
            //}

            overrideHeadHairColor   = characterConfig.GetPropertyValue <IStruct, StructLinearColor>("OverrideHeadHairColor");
            overrideFacialHairColor = characterConfig.GetPropertyValue <IStruct, StructLinearColor>("OverrideFacialHairColor");
            facialHairIndex         = characterConfig.GetPropertyValue <ArkByteValue>("FacialHairIndex")?.ByteValue ?? 0;
            headHairIndex           = characterConfig.GetPropertyValue <ArkByteValue>("HeadHairIndex")?.ByteValue ?? 0;
            playerCharacterName     = characterConfig.GetPropertyValue <string>("PlayerCharacterName", defaultValue: string.Empty);

            rawBoneModifiers = Enumerable.Range(0, PlayerBoneModifierNames.Instance.Count).Select(i => characterConfig.GetPropertyValue <float>("RawBoneModifiers", i)).ToArray();
            //for (int i = 0; i < PlayerBoneModifierNames.Instance.Count; i++) {
            //    rawBoneModifiers[i] = characterConfig.findPropertyValue<float>("RawBoneModifiers", i);
            //}

            IPropertyContainer characterStats = myData.GetPropertyValue <IStruct, IPropertyContainer>("MyPersistentCharacterStats");

            characterLevel    = characterStats.GetPropertyValue <short>("CharacterStatusComponent_ExtraCharacterLevel") + 1;
            experiencePoints  = characterStats.GetPropertyValue <float>("CharacterStatusComponent_ExperiencePoints");
            totalEngramPoints = characterStats.GetPropertyValue <int>("PlayerState_TotalEngramPoints");

            List <ObjectReference> learnedEngrams = characterStats.GetPropertyValue <IArkArray, ArkArrayObjectReference>("PlayerState_EngramBlueprints");

            if (learnedEngrams != null)
            {
                foreach (ObjectReference reference in learnedEngrams)
                {
                    engramBlueprints.Add(reference.ObjectString.ToString());
                }
            }

            numberOfLevelUpPointsApplied = Enumerable.Range(0, AttributeNames.Instance.Count)
                                           .Select(i => characterStats.GetPropertyValue <ArkByteValue>("CharacterStatusComponent_NumberOfLevelUpPointsApplied", i)?.ByteValue ?? 0)
                                           .ToArray();
            //for (int i = 0; i < AttributeNames.Instance.Count; i++) {
            //    numberOfLevelUpPointsApplied[i] = characterStats.findPropertyValue<ArkByteValue>("CharacterStatusComponent_NumberOfLevelUpPointsApplied", i)
            //            ?.ByteValue ?? 0;
            //}

            percentageOfHeadHairGrowth   = characterStats.GetPropertyValue <float>("PercentageOfHeadHairGrowth");
            percentageOfFacialHairGrowth = characterStats.GetPropertyValue <float>("PercentageOfFacialHairGrowth");

            if (context.ObjectContainer == null)
            {
                return;
            }

            GameObject player = null;

            foreach (GameObject gameObject in context.ObjectContainer)
            {
                long?linkedPlayerDataId = gameObject.GetPropertyValue <long?>("LinkedPlayerDataID");
                if (linkedPlayerDataId == null || linkedPlayerDataId != playerDataId)
                {
                    continue;
                }
                player = gameObject;
                break;
            }

            if (player == null)
            {
                return;
            }

            GameObject playerCharacterStatus = null;

            foreach (GameObject gameObject in context.ObjectContainer)
            {
                if (gameObject.Names.Count != 2 || gameObject.Names[0].ToString() != "PlayerCharacterStatus" || gameObject.Names[1] != player.Names[0])
                {
                    continue;
                }
                playerCharacterStatus = gameObject;
                break;
            }

            inventory = player.GetPropertyValue <ObjectReference, GameObject>("MyInventoryComponent", map: reference => context.ObjectContainer[reference]);
            location  = player.Location;

            if (playerCharacterStatus == null)
            {
                return;
            }
            lastHypothermalCharacterInsulationValue  = playerCharacterStatus.GetPropertyValue <float>("LastHypothermalCharacterInsulationValue");
            lastHyperthermalCharacterInsulationValue = playerCharacterStatus.GetPropertyValue <float>("LastHyperthermalCharacterInsulationValue");

            for (int index = 0; index < AttributeNames.Instance.Count; index++)
            {
                currentStatusValues[index] = playerCharacterStatus.GetPropertyValue <float>("CurrentStatusValues", index);
            }
        }
示例#12
0
 public abstract (IToken token, int length) ReadToken(string text, int offset, ReadingOptions options);
示例#13
0
        public override (IToken token, int length) ReadToken(string text, int offset, ReadingOptions options)
        {
            CheckArguments(text, offset);
            var innerTokens = new List <IToken>();
            var currentIdx  = offset;

            if (!CanReadTagSymbols(text, offset, inStart: true))
            {
                return(null, 0);
            }
            currentIdx += TagSymbols.Length;
            var allowedInnerReaders = options.GetAvailableInnerReadersFor(this);

            do
            {
                var(innerToken, innerTokenLength) = allowedInnerReaders
                                                    .Select(reader => reader.ReadToken(text, currentIdx, options.WithAllowedReaders(allowedInnerReaders)))
                                                    .FirstOrDefault(readingResult => readingResult.token != null);
                if (innerTokenLength == 0)
                {
                    return(null, 0);
                }
                innerTokens.Add(innerToken);
                currentIdx += innerTokenLength;
            } while (!CanReadTagSymbols(text, currentIdx, inStart: false));

            currentIdx += TagSymbols.Length;
            return(new PairedTagToken(TagName, innerTokens), currentIdx - offset);
        }
示例#14
0
        /// <summary>
        /// A more flexible filtering method than Filter(). Filter() will always return materialized items.
        /// </summary>
        public IEnumerable <TEntityInterface> FilterOrQuery(IEnumerable <TEntityInterface> items, object parameter, Type parameterType)
        {
            bool preferQuery = items is IQueryable;

            // If exists use Filter(IQueryable, TParameter) or Filter(IEnumerable, TParameter)
            {
                ReadingOption enumerableFilter = () =>
                {
                    var reader = Reflection.RepositoryEnumerableFilterMethod(parameterType);
                    if (reader == null)
                    {
                        return(null);
                    }
                    return(() =>
                    {
                        _logger.Trace(() => "Filtering using enumerable Filter(items, " + reader.GetParameters()[1].ParameterType.FullName + ")");
                        Reflection.MaterializeEntityList(ref items);
                        return (IEnumerable <TEntityInterface>)reader.InvokeEx(_repository.Value, items, parameter);
                    });
                };

                ReadingOption queryableFilter = () =>
                {
                    var reader = Reflection.RepositoryQueryableFilterMethod(parameterType);
                    if (reader == null)
                    {
                        return(null);
                    }
                    return(() =>
                    {
                        _logger.Trace(() => "Filtering using queryable Filter(items, " + reader.GetParameters()[1].ParameterType.FullName + ")");
                        var query = Reflection.AsQueryable(items);
                        return (IEnumerable <TEntityInterface>)reader.InvokeEx(_repository.Value, query, parameter);
                    });
                };

                ReadingOptions options;
                if (!preferQuery)
                {
                    options = new ReadingOptions {
                        enumerableFilter, queryableFilter
                    }
                }
                ;
                else
                {
                    options = new ReadingOptions {
                        queryableFilter, enumerableFilter
                    }
                };

                var readingMethod = options.FirstOptionOrNull();
                if (readingMethod != null)
                {
                    return(readingMethod());
                }
            }

            // If the parameter is FilterAll, unless explicitly implemented above, return all
            if (typeof(FilterAll).IsAssignableFrom(parameterType))
            {
                _logger.Trace(() => "Filtering all items returned.");
                return(items);
            }

            // If the parameter is a generic filter, unless explicitly implemented above, execute it
            if (parameterType == typeof(FilterCriteria))
            {
                _logger.Trace(() => "Filtering using generic filter");
                return(ExecuteGenericFilter(new[] { (FilterCriteria)parameter }, preferQuery, items));
            }
            if (typeof(IEnumerable <FilterCriteria>).IsAssignableFrom(parameterType))
            {
                _logger.Trace(() => "Filtering using generic filters");
                return(ExecuteGenericFilter((IEnumerable <FilterCriteria>)parameter, preferQuery, items));
            }

            // If the parameter is a generic property filter, unless explicitly implemented above, use queryable items.Where(property filter)
            if (typeof(IEnumerable <PropertyFilter>).IsAssignableFrom(parameterType))
            {
                _logger.Trace(() => "Reading using items.AsQueryable().Where(property filter");

                // The filterExpression must use EntityType or EntityNavigationType, depending on the provided query.
                var itemType = items.GetType().GetInterface("IEnumerable`1").GetGenericArguments()[0];

                var filterExpression = _genericFilterHelper.ToExpression((IEnumerable <PropertyFilter>)parameter, itemType);
                if (Reflection.IsQueryable(items))
                {
                    var query = Reflection.AsQueryable(items);
                    return(Reflection.Where(query, filterExpression));
                }
                else
                {
                    return(Reflection.Where(items, filterExpression.Compile()));
                }
            }

            // If the parameter is a filter expression, unless explicitly implemented above, use queryable items.Where(parameter)
            if (Reflection.IsPredicateExpression(parameterType))
            {
                _logger.Trace(() => "Filtering using items.AsQueryable().Where(" + parameterType.Name + ")");
                var query = Reflection.AsQueryable(items);
                return(Reflection.Where(query, (Expression)parameter));
            }

            // If the parameter is a filter function, unless explicitly implemented above, use materialized items.Where(parameter)
            if (typeof(Func <TEntityInterface, bool>).IsAssignableFrom(parameterType))
            {
                _logger.Trace(() => "Filtering using items.Where(" + parameterType.Name + ")");
                var filterFunction = parameter as Func <TEntityInterface, bool>;
                Reflection.MaterializeEntityList(ref items);
                if (filterFunction != null)
                {
                    return(items.Where(filterFunction));
                }
            }

            // If the parameter is a IEnumarable<Guid>, it will be interpreted as filter by IDs.
            if (typeof(IEnumerable <Guid>).IsAssignableFrom(parameterType))
            {
                _logger.Trace(() => "Filtering using items.Where(item => guids.Contains(item.ID))");
                if (!(parameter is List <Guid>))
                {
                    parameter = ((IEnumerable <Guid>)parameter).ToList();
                }

                if (items is IQueryable <TEntityInterface> ) // Use queryable Where function with bool expression instead of bool function.
                {
                    // The query is built by reflection to avoid an obscure problem with complex query in NHibernate:
                    // using generic parameter TEntityInterface or IEntity for a query parameter fails with exception on some complex scenarios.
                    var filterPredicateParameter = Expression.Parameter(Reflection.EntityType, "item");
                    var filterPredicate          = Expression.Lambda(
                        Expression.Call(
                            Expression.Constant(parameter),
                            typeof(List <Guid>).GetMethod("Contains"),
                            new[] { Expression.Property(filterPredicateParameter, "ID") }),
                        filterPredicateParameter);

                    return(Reflection.Where((IQueryable <TEntityInterface>)items, EFExpression.OptimizeContains(filterPredicate)));
                }

                return(items.Where(item => ((List <Guid>)parameter).Contains(item.ID)));
            }

            string errorMessage = $"{EntityName} does not implement a filter with parameter {parameterType.FullName}.";

            if (Reflection.RepositoryLoadWithParameterMethod(parameterType) != null)
            {
                errorMessage += " There is a loader method with this parameter implemented: Try reordering filters to use the " + parameterType.Name + " first.";
                throw new ClientException(errorMessage);
            }
            else
            {
                throw new FrameworkException(errorMessage);
            }
        }
示例#15
0
        public IEnumerable <TEntityInterface> Read(object parameter, Type parameterType, bool preferQuery)
        {
            // Use Load(parameter), Query(parameter) or Filter(Query(), parameter), if any of the options exist.
            ReadingOption loaderWithParameter = () =>
            {
                var reader = Reflection.RepositoryLoadWithParameterMethod(parameterType);
                if (reader == null)
                {
                    return(null);
                }
                return(() =>
                {
                    _logger.Trace(() => "Reading using Load(" + reader.GetParameters()[0].ParameterType.FullName + ")");
                    return (IEnumerable <TEntityInterface>)reader.InvokeEx(_repository.Value, parameter);
                });
            };

            ReadingOption queryWithParameter = () =>
            {
                var reader = Reflection.RepositoryQueryWithParameterMethod(parameterType);
                if (reader == null)
                {
                    return(null);
                }
                return(() =>
                {
                    _logger.Trace(() => "Reading using Query(" + reader.GetParameters()[0].ParameterType.FullName + ")");
                    return (IEnumerable <TEntityInterface>)reader.InvokeEx(_repository.Value, parameter);
                });
            };

            ReadingOption queryThenQueryableFilter = () =>
            {
                if (Reflection.RepositoryQueryMethod == null)
                {
                    return(null);
                }
                var reader = Reflection.RepositoryQueryableFilterMethod(parameterType);
                if (reader == null)
                {
                    return(null);
                }
                return(() =>
                {
                    _logger.Trace(() => "Reading using queryable Filter(Query(), " + reader.GetParameters()[1].ParameterType.FullName + ")");
                    var query = Reflection.RepositoryQueryMethod.InvokeEx(_repository.Value);
                    return (IEnumerable <TEntityInterface>)reader.InvokeEx(_repository.Value, query, parameter);
                });
            };

            ReadingOption queryAll = () =>
            {
                if (!typeof(FilterAll).IsAssignableFrom(parameterType))
                {
                    return(null);
                }
                var reader = Reflection.RepositoryQueryMethod;
                if (reader == null)
                {
                    return(null);
                }
                return(() =>
                {
                    _logger.Trace(() => "Reading using Query()");
                    return (IEnumerable <TEntityInterface>)reader.InvokeEx(_repository.Value);
                });
            };

            {
                ReadingOptions options;
                if (!preferQuery)
                {
                    options = new ReadingOptions {
                        loaderWithParameter, queryWithParameter, queryThenQueryableFilter
                    }
                }
                ;
                else
                {
                    options = new ReadingOptions {
                        queryWithParameter, queryThenQueryableFilter, queryAll, loaderWithParameter
                    }
                };

                var readingMethod = options.FirstOptionOrNull();
                if (readingMethod != null)
                {
                    return(readingMethod());
                }
            }

            // If the parameter is FilterAll, unless explicitly implemented above, use Load() or Query() if any option exists
            if (typeof(FilterAll).IsAssignableFrom(parameterType))
            {
                var options = new ReadingOptions {
                    () => {
                        var reader = Reflection.RepositoryLoadMethod;
                        if (reader == null)
                        {
                            return(null);
                        }
                        return(() => {
                            _logger.Trace(() => "Reading using Load()");
                            return (IEnumerable <TEntityInterface>)reader.InvokeEx(_repository.Value);
                        });
                    },
                    () => {
                        var reader = Reflection.RepositoryQueryMethod;
                        if (reader == null)
                        {
                            return(null);
                        }
                        return(() => {
                            _logger.Trace(() => "Reading using Query()");
                            return (IEnumerable <TEntityInterface>)reader.InvokeEx(_repository.Value);
                        });
                    }
                };

                if (preferQuery)
                {
                    options.Reverse();
                }

                var readingMethod = options.FirstOptionOrNull();
                if (readingMethod != null)
                {
                    return(readingMethod());
                }
            }

            // If the parameter is a generic filter, unless explicitly implemented above, execute it
            if (parameterType == typeof(FilterCriteria))
            {
                _logger.Trace(() => "Reading using generic filter");
                return(ExecuteGenericFilter(new[] { (FilterCriteria)parameter }, preferQuery));
            }
            if (typeof(IEnumerable <FilterCriteria>).IsAssignableFrom(parameterType))
            {
                _logger.Trace(() => "Reading using generic filters");
                return(ExecuteGenericFilter((IEnumerable <FilterCriteria>)parameter, preferQuery));
            }

            // If the parameter is a generic property filter, unless explicitly implemented above, use Query().Where(property filter)
            if (Reflection.RepositoryQueryMethod != null && typeof(IEnumerable <PropertyFilter>).IsAssignableFrom(parameterType))
            {
                _logger.Trace(() => "Reading using Query().Where(property filter");
                var query            = (IQueryable <TEntityInterface>)Reflection.RepositoryQueryMethod.InvokeEx(_repository.Value);
                var filterExpression = _genericFilterHelper.ToExpression((IEnumerable <PropertyFilter>)parameter, Reflection.EntityNavigationType);
                return(Reflection.Where(query, filterExpression));
            }

            // If the parameter is a filter expression, unless explicitly implemented above, use Query().Where(parameter)
            if (Reflection.RepositoryQueryMethod != null && Reflection.IsPredicateExpression(parameterType))
            {
                _logger.Trace(() => "Reading using Query().Where(" + parameterType.Name + ")");
                var query = (IQueryable <TEntityInterface>)Reflection.RepositoryQueryMethod.InvokeEx(_repository.Value);
                return(Reflection.Where(query, (Expression)parameter));
            }

            // If the parameter is a IEnumarable<Guid>, it will be interpreted as filter by IDs.
            if (Reflection.RepositoryQueryMethod != null && typeof(IEnumerable <Guid>).IsAssignableFrom(parameterType))
            {
                _logger.Trace(() => "Reading using Query().Where(item => guids.Contains(item.ID))");
                if (!(parameter is List <Guid>))
                {
                    parameter = ((IEnumerable <Guid>)parameter).ToList();
                }
                var query = (IQueryable <TEntityInterface>)Reflection.RepositoryQueryMethod.InvokeEx(_repository.Value);

                // The query is built by reflection to avoid an obscure problem with complex query in NHibernate:
                // using generic parameter TEntityInterface or IEntity for a query parameter fails with exception on some complex scenarios.
                var filterPredicateParameter = Expression.Parameter(Reflection.EntityType, "item");
                var filterPredicate          = Expression.Lambda(
                    Expression.Call(
                        Expression.Constant(parameter),
                        typeof(List <Guid>).GetMethod("Contains"),
                        new[] { Expression.Property(filterPredicateParameter, "ID") }),
                    filterPredicateParameter);

                return(Reflection.Where(query, EFExpression.OptimizeContains(filterPredicate)));
            }

            // It there is only enumerable filter available, use inefficient loader with in-memory filtering: Filter(Load(), parameter)
            {
                var reader = Reflection.RepositoryEnumerableFilterMethod(parameterType);
                if (reader != null)
                {
                    IEnumerable <TEntityInterface> items;
                    try
                    {
                        items = Read(null, typeof(FilterAll), preferQuery: false);
                    }
                    catch (FrameworkException)
                    {
                        items = null;
                    }

                    if (items != null)
                    {
                        _logger.Trace(() => "Reading using enumerable Filter(all, " + reader.GetParameters()[1].ParameterType.FullName + ")");
                        Reflection.MaterializeEntityList(ref items);
                        return((IEnumerable <TEntityInterface>)reader.InvokeEx(_repository.Value, items, parameter));
                    }
                }
            }

            throw new FrameworkException($"{EntityName} does not implement a loader, a query or a filter with parameter {parameterType.FullName}.");
        }
示例#16
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);
                        }
                    }
                }
            }
        }