/// <summary> /// Load the valid XAssets for the RawFile XAsset Pool. /// </summary> /// <param name="instance"></param> /// <returns>List of RawFile XAsset objects.</returns> public override List <GameXAsset> Load(JekyllInstance instance) { List <GameXAsset> results = new List <GameXAsset>(); DBAssetPool pool = instance.Reader.ReadStruct <DBAssetPool>(instance.Game.DBAssetPools + (Index * Marshal.SizeOf <DBAssetPool>())); Entries = pool.Entries; ElementSize = pool.ElementSize; PoolSize = pool.PoolSize; for (int i = 0; i < PoolSize; i++) { RawFileXAsset header = instance.Reader.ReadStruct <RawFileXAsset>(Entries + (i * ElementSize)); if (IsNullXAsset(header.Name)) { continue; } else if (header.Len == 0) { continue; } results.Add(new GameXAsset() { Name = instance.Reader.ReadNullTerminatedString(header.Name), Type = Name, Size = ElementSize, XAssetPool = this, HeaderAddress = Entries + (i * ElementSize), }); } return(results); }
/// <summary> /// Gets the first entry in the XModel XAsset Pool of Black Ops 4. /// </summary> /// <param name="instance"></param> /// <returns>Name of the XModel.</returns> public string GetFirstXModel(JekyllInstance instance) { long address = instance.Game.DBAssetPools + (Marshal.SizeOf <DBAssetPool>() * (int)XAssetType.xmodel); DBAssetPool pool = instance.Reader.ReadStruct <DBAssetPool>(address); return(instance.Reader.ReadBytesToString(pool.Entries).ToLower()); }
/// <summary> /// Gets the first entry in the XModel XAsset Pool of Modern Warfare. /// </summary> /// <param name="instance"></param> /// <returns>Name of the XModel.</returns> public string GetFirstXModel(JekyllInstance instance) { long address = BaseAddress + DBAssetPools + (Marshal.SizeOf <DBAssetPool>() * (int)XAssetType.ASSET_TYPE_XMODEL); DBAssetPool pool = instance.Reader.ReadStruct <DBAssetPool>(address); long name = instance.Reader.ReadInt64(pool.Entries); return(instance.Reader.ReadNullTerminatedString(name)); }
/// <summary> /// Load the valid XAssets for the Key/Value Pairs XAsset Pool. /// </summary> /// <param name="instance"></param> /// <returns>List of Key/Value Pairs XAsset objects.</returns> public override List <GameXAsset> Load(JekyllInstance instance) { List <GameXAsset> results = new List <GameXAsset>(); DBAssetPool pool = instance.Reader.ReadStruct <DBAssetPool>(instance.Game.BaseAddress + instance.Game.DBAssetPools + (Index * Marshal.SizeOf <DBAssetPool>())); Entries = pool.Entries; ElementSize = pool.ElementSize; PoolSize = pool.PoolSize; if (IsValidPool(Name, ElementSize, Marshal.SizeOf <KeyValuePairsXAsset>()) == false) { return(results); } Dictionary <string, string> entries = new Dictionary <string, string>(); for (int i = 0; i < PoolSize; i++) { KeyValuePairsXAsset header = instance.Reader.ReadStruct <KeyValuePairsXAsset>(Entries + (i * ElementSize)); if (IsNullXAsset(header.Name)) { continue; } string key = instance.Reader.ReadNullTerminatedString(header.Name); if (entries.TryGetValue(key, out string _)) { continue; } KeyValuePair data = instance.Reader.ReadStruct <KeyValuePair>(header.KeyValuePairs); string value = instance.Reader.ReadNullTerminatedString(data.Value); entries.Add(key, value); Console.WriteLine($"Exported {Name} {key}"); } string path = Path.Combine(instance.ExportPath, "keyValuePairs.json"); Directory.CreateDirectory(Path.GetDirectoryName(path)); using (StreamWriter file = File.CreateText(path)) { file.Write(JsonConvert.SerializeObject(entries, Formatting.Indented)); } return(results); }
/// <summary> /// Load the valid XAssets for the ScriptFile XAsset Pool. /// </summary> /// <param name="instance"></param> /// <returns>List of ScriptFile XAsset objects.</returns> public override List <GameXAsset> Load(JekyllInstance instance) { List <GameXAsset> results = new List <GameXAsset>(); DBAssetPool poolInfo = instance.Reader.ReadStruct <DBAssetPool>(instance.Game.BaseAddress + instance.Game.DBAssetPools + (Index * Marshal.SizeOf <DBAssetPool>())); Entries = poolInfo.Entries; ElementSize = poolInfo.ElementSize; PoolSize = poolInfo.PoolSize; if (IsValidPool(Name, ElementSize, Marshal.SizeOf <ScriptFileXAsset>()) == false) { return(results); } for (int i = 0; i < PoolSize; i++) { ScriptFileXAsset header = instance.Reader.ReadStruct <ScriptFileXAsset>(Entries + (i * ElementSize)); if (IsNullXAsset(header.Name)) { continue; } else if (header.CompressedLen == 0) { continue; } else if (header.Len == 0) { continue; } else if (header.BytecodeLen == 0) { continue; } results.Add(new GameXAsset() { Name = instance.Reader.ReadNullTerminatedString(header.Name), Type = Name, Size = ElementSize, XAssetPool = this, HeaderAddress = Entries + (i * ElementSize), }); } return(results); }
/// <summary> /// Validates and sets the DBAssetPools address of Modern Warfare. /// </summary> /// <param name="instance"></param> /// <returns>True if address is valid, otherwise false.</returns> public bool InitializeGame(JekyllInstance instance) { BaseAddress = instance.Reader.GetBaseAddress(); var scanDBAssetPools = instance.Reader.FindBytes( new byte?[] { 0x48, 0x8D, 0x04, 0x40, 0x4C, 0x8D, 0x8E, null, null, null, null, 0x4D, 0x8D, 0x0C, 0xC1, 0x8D, 0x42, 0xFF }, BaseAddress, BaseAddress + instance.Reader.GetModuleMemorySize(), true); if (scanDBAssetPools.Length > 0) { DBAssetPools = instance.Reader.ReadInt32(scanDBAssetPools[0] + 0x7); // In Modern Warfare, axis_guide_createfx will always be the first entry in the XModel XAsset Pool. if (GetFirstXModel(instance) == "axis_guide_createfx") { List <Dictionary <string, object> > pools = new List <Dictionary <string, object> >(); foreach (int index in Enum.GetValues(typeof(XAssetType))) { DBAssetPool pool = instance.Reader.ReadStruct <DBAssetPool>(instance.Game.BaseAddress + instance.Game.DBAssetPools + (index * Marshal.SizeOf <DBAssetPool>())); pools.Add(new Dictionary <string, object>() { { "Name", Enum.GetName(typeof(XAssetType), index) }, { "ElementSize", pool.ElementSize }, }); } string path = Path.Combine(instance.ExportPath, "DBAssetPools.json"); Directory.CreateDirectory(Path.GetDirectoryName(path)); using (StreamWriter file = File.CreateText(path)) { file.Write(JsonConvert.SerializeObject(pools, Formatting.Indented)); } return(true); } } return(false); }
/// <summary> /// Load the valid XAssets for the Localize XAsset Pool. /// </summary> /// <param name="instance"></param> /// <returns>List of Localize XAsset objects.</returns> public override List <GameXAsset> Load(JekyllInstance instance) { DBAssetPool pool = instance.Reader.ReadStruct <DBAssetPool>(instance.Game.DBAssetPools + (Index * Marshal.SizeOf <DBAssetPool>())); Entries = pool.Entries; ElementSize = pool.ElementSize; PoolSize = pool.PoolSize; Dictionary <string, string> entries = new Dictionary <string, string>(); for (int i = 0; i < PoolSize; i++) { LocalizeEntry header = instance.Reader.ReadStruct <LocalizeEntry>(Entries + (i * ElementSize)); if (IsNullXAsset(header.Name)) { continue; } string key = instance.Reader.ReadNullTerminatedString(header.Name).ToUpper(); if (entries.TryGetValue(key, out string _)) { continue; } string value = instance.Reader.ReadNullTerminatedString(header.Value); entries.Add(key, value); Console.WriteLine($"Exported {Name} {key}"); } string path = Path.Combine(instance.ExportPath, "localize.json"); Directory.CreateDirectory(Path.GetDirectoryName(path)); using (StreamWriter file = File.CreateText(path)) { file.Write(JsonConvert.SerializeObject(entries, Formatting.Indented)); } return(new List <GameXAsset>()); }
/// <summary> /// Load the valid XAssets for the RawFile XAsset Pool. /// </summary> /// <param name="instance"></param> /// <returns>List of RawFile XAsset objects.</returns> public override List <GameXAsset> Load(JekyllInstance instance) { List <GameXAsset> results = new List <GameXAsset>(); DBAssetPool pool = instance.Reader.ReadStruct <DBAssetPool>(instance.Game.DBAssetPools + (Index * Marshal.SizeOf <DBAssetPool>())); Entries = pool.Entries; ElementSize = pool.ElementSize; PoolSize = pool.PoolSize; if (IsValidPool(Name, ElementSize, Marshal.SizeOf <RawFileXAsset>()) == false) { return(results); } for (int i = 0; i < PoolSize; i++) { RawFileXAsset header = instance.Reader.ReadStruct <RawFileXAsset>(Entries + (i * ElementSize)); if (header.Len == 0) { continue; } results.Add(new GameXAsset() { Name = instance.Reader.ReadBytesToString(Entries + (i * ElementSize)).ToLower(), Type = Name, Size = ElementSize, XAssetPool = this, HeaderAddress = Entries + (i * Marshal.SizeOf <RawFileXAsset>()), }); } return(results); }