public static List <DinosaurEntry> ExtractDinos(UAssetCacheBlock cache, List <ArkAsset> assets, DeltaExportPatch patch, PropertyReader primalDataReader, Dictionary <string, PropertyReader> dinoEntries) { //Loop through assets and import them List <DinosaurEntry> dinos = new List <DinosaurEntry>(); foreach (var a in assets) { //Open file UAssetFileBlueprint f; try { f = UAssetFileBlueprint.OpenFile(a.filename, false, a.name, a.installation.contentFolder); } catch (Exception ex) { continue; } //Convert file try { //Create a dino entry DinosaurEntry entry = ArkDinoEntryConverter.Convert(f, cache, patch, primalDataReader, dinoEntries); dinos.Add(entry); } catch (Exception ex) { continue; } } return(dinos); }
public static UAssetFileBlueprint GetFile(UAssetFileBlueprint f, UAssetCacheBlock cache) { //Search for this by name GameObjectTableHead hr = null; UAssetFileBlueprint workingFile = f; while (hr == null && workingFile != null) { //Search foreach (var h in workingFile.gameObjectReferences) { if (h.name.StartsWith("DinoCharacterStatusComponent_BP_")) { hr = h; } } //Try to get the parent file workingFile = workingFile.GetParentBlueprint(cache); } if (hr == null) { throw new Exception("Could not find dino status component!"); } //Open file string pathname = f.GetReferencedUAssetPathname(hr); return(f.GetReferencedUAssetBlueprintFromPathname(pathname)); }
public static ArkDinoEntry Convert(UAssetFileBlueprint f, UAssetCacheBlock cache, Dictionary <string, PropertyReader> dinoEntries) { //Open reader PropertyReader reader = new PropertyReader(f.GetFullProperties(cache)); //Get the dino settings UAssetFileBlueprint settingsFileAdult = ArkDinoFood.GetAdultFile(f, cache); UAssetFileBlueprint settingsFileBaby = ArkDinoFood.GetBabyFile(f, cache); //Get time int time = (int)Math.Round((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds); //Get status component UAssetFileBlueprint statusComponent = ArkDinoEntryStatus.GetFile(f, cache); PropertyReader statusReader = new PropertyReader(statusComponent.GetFullProperties(cache)); //Use name tag to find entry string tag = reader.GetPropertyStringOrName("DinoNameTag"); if (!dinoEntries.ContainsKey(tag)) { throw new Exception($"Could not find dino entry for '{f.classname}' (tag '{tag}')"); } PropertyReader entry = dinoEntries[tag]; //Now, load the material used for the dino image UAssetFileMaterial entryMaterial = entry.GetProperty <ObjectProperty>("DinoMaterial").GetReferencedFileMaterial(); UAssetFileMaterial.TextureParameterValue entryMaterialTexture = entryMaterial.textureParameters[0]; ClassnamePathnamePair entryTexture = entryMaterialTexture.prop.GetReferencedFile(); //Read ArkDinoEntry e = new ArkDinoEntry { screen_name = reader.GetPropertyString("DescriptiveName", null), colorizationIntensity = reader.GetPropertyFloat("ColorizationIntensity", 1), babyGestationSpeed = reader.GetPropertyFloat("BabyGestationSpeed", -1), extraBabyGestationSpeedMultiplier = reader.GetPropertyFloat("ExtraBabyGestationSpeedMultiplier", -1), babyAgeSpeed = reader.GetPropertyFloat("BabyAgeSpeed", null), extraBabyAgeMultiplier = reader.GetPropertyFloat("ExtraBabyAgeSpeedMultiplier", -1), useBabyGestation = reader.GetPropertyBool("bUseBabyGestation", false), statusComponent = ArkDinoEntryStatus.Convert(statusComponent, statusReader), adultFoods = ArkDinoFood.Convert(settingsFileAdult, cache), childFoods = ArkDinoFood.Convert(settingsFileBaby, cache), classname = f.classname, blueprintPath = "N/A", captureTime = time, icon = ImageTool.QueueImage(entryTexture, ImageTool.ImageModifications.None), icon_white = ImageTool.QueueImage(entryTexture, ImageTool.ImageModifications.White) }; //Finally, read stats ArkStatsRipper.DoRipStats(statusReader, e); return(e); }
public static UAssetFileBlueprint GetBabyFile(UAssetFileBlueprint f, UAssetCacheBlock cache) { //First, try to see if it's a property PropertyReader r = new PropertyReader(f.GetFullProperties(cache)); ObjectProperty p = r.GetProperty <ObjectProperty>("BabyDinoSettings"); if (p != null) { //Get file return(p.GetReferencedFileBlueprint()); } //Fallback to adult settings return(GetAdultFile(f, cache)); }
static void DebugFile(string gameRoot, string package, string classname) { using (FileStream fs = new FileStream(gameRoot + package, FileMode.Open, FileAccess.Read)) { UAssetFileBlueprint f = UAssetFileBlueprint.OpenFile(fs, true, classname, gameRoot); UAssetCacheBlock cache = new UAssetCacheBlock(); List <UProperty> props = f.GetFullProperties(cache); foreach (var p in props) { Console.WriteLine($"{p.name}, {p.type}, {p.WriteString()}"); } } Console.WriteLine("Complete."); Console.ReadLine(); }
/// <summary> /// Extracts data and returns the package /// </summary> public Stream Run(UAssetCacheBlock cache, out string hash) { //Get pathnames that match this List <ArkAsset>[] files = DiscoveryService.DiscoverFiles(installation, this); //Load mod info if this is a mod. TODO //Load Primal Data for mod string primalDataPathname = "/Game/PrimalEarth/CoreBlueprints/PrimalGameData_BP"; ArkAsset primalDataNs = ArkAsset.GetAssetFromGame(primalDataPathname, installation); UAssetFileBlueprint primalData = UAssetFileBlueprint.OpenFile(primalDataNs.filename, false, primalDataNs.name, this.installation.contentFolder); PropertyReader primalDataReader = new PropertyReader(primalData.GetFullProperties(cache)); //Load all dino entries var dinoEntriesArray = primalDataReader.GetProperty <ArrayProperty>("DinoEntries"); Dictionary <string, PropertyReader> dinoEntries = new Dictionary <string, PropertyReader>(); //Dino entries mapped by tag name foreach (var i in dinoEntriesArray.props) { var ii = ((ObjectProperty)i).GetReferencedFileBlueprint(); var iir = new PropertyReader(ii.GetFullProperties(cache)); string tag = iir.GetPropertyStringOrName("DinoNameTag"); if (!dinoEntries.ContainsKey(tag)) { dinoEntries.Add(tag, iir); } else { dinoEntries[tag] = iir; } } //Import dinos var dinos = DinoExtractorService.ExtractDinos(cache, files[(int)ArkAssetType.Dino], patch, primalDataReader, dinoEntries); //Import items var items = ItemExtractorService.ExtractItems(cache, files[(int)ArkAssetType.InventoryItem], patch); Log.WriteSuccess("Export-Package-Run", $"Package {name}: Processed {dinos.Count} dinos, {items.Count} items"); //Return the package return(CompilePackage(new Dictionary <string, object> { { "items.bson", items }, { "dinos.bson", dinos } }, out hash)); }
public static DinosaurEntry Convert(UAssetFileBlueprint f, UAssetCacheBlock cache, DeltaExportPatch patch, PropertyReader primalDataReader, Dictionary <string, PropertyReader> dinoEntries) { //Open reader PropertyReader reader = new PropertyReader(f.GetFullProperties(cache)); //Get the dino settings UAssetFileBlueprint settingsFileAdult = ArkDinoFoodConverter.GetAdultFile(f, cache); UAssetFileBlueprint settingsFileBaby = ArkDinoFoodConverter.GetBabyFile(f, cache); //Get status component UAssetFileBlueprint statusComponent = ArkDinoEntryStatusConverter.GetFile(f, cache); PropertyReader statusReader = new PropertyReader(statusComponent.GetFullProperties(cache)); //Use name tag to find entry string tag = reader.GetPropertyStringOrName("DinoNameTag"); PropertyReader entry = dinoEntries[tag]; //Now, load the material used for the dino image UAssetFileMaterial entryMaterial = entry.GetProperty <ObjectProperty>("DinoMaterial").GetReferencedFileMaterial(); UAssetFileMaterial.TextureParameterValue entryMaterialTexture = entryMaterial.textureParameters[0]; ClassnamePathnamePair entryTexture = entryMaterialTexture.prop.GetReferencedFile(); //Read DinosaurEntry e = new DinosaurEntry { screen_name = reader.GetPropertyString("DescriptiveName", null), colorizationIntensity = reader.GetPropertyFloat("ColorizationIntensity", 1), babyGestationSpeed = reader.GetPropertyFloat("BabyGestationSpeed", -1), extraBabyGestationSpeedMultiplier = reader.GetPropertyFloat("ExtraBabyGestationSpeedMultiplier", -1), babyAgeSpeed = reader.GetPropertyFloat("BabyAgeSpeed", null), extraBabyAgeMultiplier = reader.GetPropertyFloat("ExtraBabyAgeSpeedMultiplier", -1), useBabyGestation = reader.GetPropertyBool("bUseBabyGestation", false), statusComponent = ArkDinoEntryStatusConverter.Convert(statusComponent, statusReader), adultFoods = ArkDinoFoodConverter.Convert(settingsFileAdult, cache), childFoods = ArkDinoFoodConverter.Convert(settingsFileBaby, cache), classname = DeltaDataExtractor.Program.TrimArkClassname(f.classname), icon = ImageTool.QueueImage(entryTexture, ImageTool.ImageModifications.None, patch), }; //Finally, read stats ArkStatsRipper.DoRipStats(statusReader, e); return(e); }
public static void ImportItems(UAssetCacheBlock cache, Dictionary <string, string> map, List <string> readErrors) { //Find items to import List <ArkItemEntry> items = new List <ArkItemEntry>(); foreach (var mapEntry in map) { //Check if this is an item if (!mapEntry.Key.StartsWith("PrimalItem")) { continue; } //Open UAssetFileBlueprint bp; try { bp = UAssetFileBlueprint.OpenFile(mapEntry.Value, false, mapEntry.Key, Program.GAME_ROOT_PATH); } catch (Exception ex) { Console.WriteLine($"FAILED TO READ ITEM {mapEntry.Key} with error {ex.Message}"); readErrors.Add($"FAILED TO READ ITEM {mapEntry.Key} with error {ex.Message} {ex.StackTrace}"); continue; } //Decode try { ArkItemEntry entry = ArkItemEntry.ConvertEntry(bp, cache); items.Add(entry); } catch (Exception ex) { Console.WriteLine("FAILED TO IMPORT ITEM " + bp.classname); readErrors.Add($"FAILED TO IMPORT ITEM {bp.classname} {ex.Message} {ex.StackTrace}"); continue; } } //OK Console.WriteLine($"Imported {items.Count} items."); //Save File.WriteAllText(Program.GetOutputDir() + "items.json", JsonConvert.SerializeObject(items, Formatting.Indented)); Console.WriteLine("Saved."); }
static void SingleFileTestBlueprint(string path, string classname) { Console.WriteLine("Testing"); using (FileStream fs = new FileStream(GAME_ROOT_PATH + path, FileMode.Open, FileAccess.Read)) { UAssetFileBlueprint f = UAssetFileBlueprint.OpenFile(fs, true, classname, GAME_ROOT_PATH); UAssetCacheBlock cache = new UAssetCacheBlock(); List <UProperty> props = f.GetFullProperties(cache); foreach (var p in props) { Console.WriteLine($"{p.name}, {p.type}, {p.WriteString()}"); } //File.WriteAllText("E:\\rockdrake.json", JsonConvert.SerializeObject(props, Formatting.Indented)); //ArkDinoEntry e = ArkDinoEntry.Convert(f, cache); } Console.WriteLine("Done"); Console.ReadLine(); }
public static void DoRun() { //First, map the game dir Dictionary <string, string> map = DirectoryIndexer.MapGameDir(); //Create cache and import UAssetCacheBlock cache = new UAssetCacheBlock(); List <string> readErrors = new List <string>(); //DinoImporter.ImportDinos(cache, map, readErrors); ItemImporter.ImportItems(cache, map, readErrors); //Now, save imges ImageTool.ProcessImages(readErrors); //Finish File.WriteAllLines(Program.GetOutputDir() + "errors.log", readErrors.ToArray()); Console.WriteLine("Done."); Console.ReadLine(); }
public static List <ArkDinoFood> Convert(UAssetFileBlueprint f, UAssetCacheBlock cache) { //Open reader PropertyReader reader = new PropertyReader(f.GetFullProperties(cache)); List <ArkDinoFood> output = new List <ArkDinoFood>(); //Get each ArrayProperty mBase = reader.GetProperty <ArrayProperty>("FoodEffectivenessMultipliers"); ArrayProperty mExtra = reader.GetProperty <ArrayProperty>("ExtraFoodEffectivenessMultipliers"); //Convert if (mBase != null) { output.AddRange(ConvertMultiplier(f, cache, mBase)); } if (mExtra != null) { output.AddRange(ConvertMultiplier(f, cache, mExtra)); } return(output); }
public static List <ItemEntry> ExtractItems(UAssetCacheBlock cache, List <ArkAsset> assets, DeltaExportPatch patch) { //Loop through all assets List <ItemEntry> items = new List <ItemEntry>(); foreach (var a in assets) { //Open DateTime start = DateTime.UtcNow; UAssetFileBlueprint bp; try { bp = UAssetFileBlueprint.OpenFile(a.filename, false, a.name, a.installation.contentFolder); } catch (Exception ex) { Log.WriteError("Item Extractor", "Failed to open file " + a.fullName + ": " + ex.Message + ex.StackTrace); continue; } //Decode try { ItemEntry entry = ArkItemEntryReader.ConvertEntry(bp, cache, patch); items.Add(entry); TimeSpan time = DateTime.UtcNow - start; Log.WriteInfo("Item Extractor", "Successfully opened and converted " + a.fullName + " in " + Math.Round(time.TotalMilliseconds) + "ms"); } catch (Exception ex) { Log.WriteError("Item Extractor", "Failed to import " + a.fullName + ": " + ex.Message + ex.StackTrace); continue; } } Log.WriteSuccess("Item Extractor", "Extracted " + items.Count + "/" + assets.Count + " items."); return(items); }
public static UAssetFileBlueprint GetAdultFile(UAssetFileBlueprint f, UAssetCacheBlock cache) { //First, try to see if it's a property PropertyReader r = new PropertyReader(f.GetFullProperties(cache)); ObjectProperty p = r.GetProperty <ObjectProperty>("AdultDinoSettings"); if (p != null) { //Get file return(p.GetReferencedFileBlueprint()); } //Get the base DinoSettingsClass property p = r.GetProperty <ObjectProperty>("DinoSettingsClass"); if (p != null) { //Get file return(p.GetReferencedFileBlueprint()); } //Throw error throw new Exception("Dino settings class was not found."); }
private static List <ArkDinoFood> ConvertMultiplier(UAssetFileBlueprint f, UAssetCacheBlock cache, ArrayProperty p) { //Convert each entry List <ArkDinoFood> output = new List <ArkDinoFood>(); foreach (var s in p.props) { StructProperty data = (StructProperty)s; PropListStruct sdata = (PropListStruct)data.data; PropertyReader reader = new PropertyReader(sdata.propsList); UAssetFileBlueprint foodClass = reader.GetProperty <ObjectProperty>("FoodItemParent").GetReferencedFileBlueprint(); ArkDinoFood food = new ArkDinoFood { classname = foodClass.classname, foodEffectivenessMultiplier = reader.GetPropertyFloat("FoodEffectivenessMultiplier", null), affinityOverride = reader.GetPropertyFloat("AffinityOverride", null), affinityEffectivenessMultiplier = reader.GetPropertyFloat("AffinityEffectivenessMultiplier", null), foodCategory = reader.GetPropertyInt("FoodItemCategory", null), priority = reader.GetPropertyFloat("UntamedFoodConsumptionPriority", null) }; output.Add(food); } return(output); }
public static ItemEntry ConvertEntry(UAssetFileBlueprint bp, UAssetCacheBlock cache, DeltaExportPatch patch) { //Open reader PropertyReader reader = new PropertyReader(bp.GetFullProperties(cache)); //Get primary icon DeltaAsset icon; if (reader.GetProperty <ObjectProperty>("ItemIcon") != null) { icon = ImageTool.QueueImage(reader.GetProperty <ObjectProperty>("ItemIcon").GetReferencedFile(), ImageTool.ImageModifications.None, patch); } else { icon = DeltaAsset.MISSING_ICON; } //Get broken icon DeltaAsset brokenIcon; if (reader.GetProperty <ObjectProperty>("BrokenImage") != null) { brokenIcon = ImageTool.QueueImage(reader.GetProperty <ObjectProperty>("BrokenImage").GetReferencedFile(), ImageTool.ImageModifications.None, patch); } else { brokenIcon = DeltaAsset.MISSING_ICON; } //Get the array of UseItemAddCharacterStatusValues ArrayProperty statusValuesArray = reader.GetProperty <ArrayProperty>("UseItemAddCharacterStatusValues"); Dictionary <string, ItemEntry_ConsumableAddStatusValue> statusValues = new Dictionary <string, ItemEntry_ConsumableAddStatusValue>(); if (statusValuesArray != null) { foreach (var i in statusValuesArray.props) { StructProperty sv = (StructProperty)i; var svp = ((PropListStruct)sv.data).propsList; var svpr = new PropertyReader(svp); string type = svpr.GetProperty <ByteProperty>("StatusValueType").enumValue; ItemEntry_ConsumableAddStatusValue sve = ArkItemEntry_ConsumableAddStatusValueReader.Convert(svpr, type); statusValues.Add(type, sve); } } //Create ItemEntry e = new ItemEntry { hideFromInventoryDisplay = reader.GetPropertyBool("bHideFromInventoryDisplay", false), useItemDurability = reader.GetPropertyBool("bUseItemDurability", false), isTekItem = reader.GetPropertyBool("bTekItem", false), allowUseWhileRiding = reader.GetPropertyBool("bAllowUseWhileRiding", false), name = reader.GetPropertyString("DescriptiveNameBase", null), description = reader.GetPropertyString("ItemDescription", null), spoilingTime = reader.GetPropertyFloat("SpolingTime", 0), baseItemWeight = reader.GetPropertyFloat("BaseItemWeight", 0), useCooldownTime = reader.GetPropertyFloat("MinimumUseInterval", 0), baseCraftingXP = reader.GetPropertyFloat("BaseCraftingXP", 0), baseRepairingXP = reader.GetPropertyFloat("BaseRepairingXP", 0), maxItemQuantity = reader.GetPropertyInt("MaxItemQuantity", 0), classname = DeltaDataExtractor.Program.TrimArkClassname(bp.classname), icon = icon, broken_icon = brokenIcon, addStatusValues = statusValues }; return(e); }
public static void ImportDinos(UAssetCacheBlock cache, Dictionary <string, string> map, List <string> readErrors) { //Open PrimalGameData Console.WriteLine("Opening PrimalGameData..."); UAssetFileBlueprint primalGameData = UAssetFileBlueprint.OpenFile(Program.GAME_ROOT_PATH + @"PrimalEarth\CoreBlueprints\PrimalGameData_BP.uasset", false, "PrimalGameData_BP", Program.GAME_ROOT_PATH); PropertyReader primalGameDataReader = new PropertyReader(primalGameData.GetFullProperties(cache)); Console.WriteLine("PrimalGameData opened."); //Now, open all dino entries Console.WriteLine("Opening dino entries..."); Dictionary <string, PropertyReader> dinoEntries = new Dictionary <string, PropertyReader>(); ArrayProperty entriesArray = primalGameDataReader.GetProperty <ArrayProperty>("DinoEntries"); int entriesCount = 0; foreach (var en in entriesArray.props) { //Open UAssetFileBlueprint bp = ((ObjectProperty)en).GetReferencedFileBlueprint(); PropertyReader bpReader = new PropertyReader(bp.GetFullProperties(cache)); string name = bpReader.GetPropertyStringOrName("DinoNameTag"); if (dinoEntries.ContainsKey(name)) { dinoEntries.Remove(name); } dinoEntries.Add(name, bpReader); entriesCount++; } Console.WriteLine($"Finished opening dino entries. Found {entriesCount} entries."); //Now, open binder ClassListBinder binder = ClassListBinder.OpenBinder("classes.json"); //Find base dino ClassListEntry dinoBase = binder.ClassData.SearchForClass("Dino_Character_BP"); if (dinoBase == null) { throw new Exception("Failed to find dino base class."); } //Get children List <ClassListEntry> dinoClasses = dinoBase.GetAllChildren(); Console.WriteLine($"Found {dinoClasses.Count} dino classes to import."); //Loop classes and start reading List <ArkDinoEntry> dinos = new List <ArkDinoEntry>(); foreach (ClassListEntry e in dinoClasses) { try { //Find this dino file in the map if (!map.ContainsKey(e.Name)) { throw new Exception($"Failed to find dino {e.Name} in uasset map."); } string pathname = map[e.Name]; //Now, open the UASSET file UAssetFileBlueprint f = UAssetFileBlueprint.OpenFile(pathname, false, e.Name, Program.GAME_ROOT_PATH); //Create a dino entry ArkDinoEntry entry = ArkDinoEntry.Convert(f, cache, dinoEntries); dinos.Add(entry); } catch (Exception ex) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine($"Failed to import dino {e.Name} with error {ex.Message}!"); readErrors.Add($"Failed to import dino {e.Name} with error {ex.Message}{ex.StackTrace}!"); Console.ForegroundColor = ConsoleColor.White; } } //Now, save Console.WriteLine($"Finished reading {dinos.Count}/{dinoClasses.Count} dinos. Saving now..."); File.WriteAllText(Program.GetOutputDir() + "dinos.json", JsonConvert.SerializeObject(dinos, Formatting.Indented)); Console.WriteLine("Done importing dinos."); }