Ejemplo n.º 1
0
        /// <summary>
        /// Validates and sets the DBAssetPools and DBAssetPoolSizes addresses of Black Ops II.
        /// </summary>
        /// <param name="instance"></param>
        /// <returns>True if addresses are valid, otherwise false.</returns>
        public bool InitializeGame(JekyllInstance instance)
        {
            BaseAddress = instance.Reader.GetBaseAddress();
            long moduleSize = instance.Reader.GetModuleMemorySize();

            long[] scanDBAssetPools = instance.Reader.FindBytes(
                new byte?[] { 0x56, 0x51, 0xFF, 0xD2, 0x8B, 0xF0, 0x83, 0xC4, 0x04, 0x85, 0xF6 },
                BaseAddress,
                BaseAddress + moduleSize,
                true);

            if (scanDBAssetPools.Length > 0)
            {
                DBAssetPools     = instance.Reader.ReadInt32(scanDBAssetPools[0] - 0xB);
                DBAssetPoolSizes = instance.Reader.ReadInt32(scanDBAssetPools[0] + 0x3B);

                // In Black Ops II, defaultvehicle will always be the first entry in the XModel XAsset Pool.
                if (GetFirstXModel(instance) == "defaultvehicle")
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Validates and sets the DBAssetPools and DBAssetPoolSizes addresses of Modern Warfare 2.
        /// </summary>
        /// <param name="instance"></param>
        /// <returns>True if addresses are valid, otherwise false.</returns>
        public bool InitializeGame(JekyllInstance instance)
        {
            BaseAddress = instance.Reader.GetBaseAddress();
            long moduleSize = instance.Reader.GetModuleMemorySize();

            long[] scanDBAssetPools = instance.Reader.FindBytes(
                new byte?[] { 0x56, 0x51, 0xFF, 0xD2, 0x8B, 0xF0, 0x83, 0xC4, 0x04, 0x85, 0xF6 },
                BaseAddress,
                BaseAddress + moduleSize,
                true);

            if (scanDBAssetPools.Length > 0)
            {
                DBAssetPools = instance.Reader.ReadUInt32(scanDBAssetPools[0] - 0xB);

                if (instance.Reader.ActiveProcess.ProcessName == "iw4sp")
                {
                    DBAssetPoolSizes = instance.Reader.ReadUInt32(scanDBAssetPools[0] + 0x30);
                }
                else if (instance.Reader.ActiveProcess.ProcessName == "iw4mp")
                {
                    DBAssetPoolSizes = instance.Reader.ReadUInt32(scanDBAssetPools[0] + 0x46);
                }

                // In Modern Warfare 2, void will always be the first entry in the XModel XAsset Pool.
                if (GetFirstXModel(instance) == "void")
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 3
0
            /// <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);
            }
Ejemplo n.º 4
0
        /// <summary>
        /// Validates and sets the DBAssetPools and DBAssetPoolSizes addresses of WWII.
        /// </summary>
        /// <param name="instance"></param>
        /// <returns>True if addresses are valid, otherwise false.</returns>
        public bool InitializeGame(JekyllInstance instance)
        {
            BaseAddress = instance.Reader.GetBaseAddress();
            long moduleSize = instance.Reader.GetModuleMemorySize();

            var scanDBAssetPools = instance.Reader.FindBytes(
                new byte?[] { 0x4A, 0x8B, 0xAC, null, null, null, null, null, 0x48, 0x85, 0xED },
                BaseAddress,
                BaseAddress + moduleSize,
                true);
            var scanDBAssetPoolSizes = instance.Reader.FindBytes(
                new byte?[] { 0x83, 0xBC, null, null, null, null, null, 0x01, 0x7F, 0x48 },
                BaseAddress,
                BaseAddress + moduleSize,
                true);

            if (scanDBAssetPools.Length > 0 && scanDBAssetPoolSizes.Length > 0)
            {
                DBAssetPools     = instance.Reader.ReadInt32(scanDBAssetPools[0] + 0x4) + BaseAddress;
                DBAssetPoolSizes = instance.Reader.ReadInt32(scanDBAssetPoolSizes[0] + 0x3) + BaseAddress;

                // In WWII, empty_model will always be the first entry in the XModel XAsset Pool.
                if (GetFirstXModel(instance) == "empty_model")
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 5
0
            /// <summary>
            /// Exports the specified ScriptFile XAsset.
            /// </summary>
            /// <param name="xasset"></param>
            /// <param name="instance"></param>
            /// <returns>Status of the export operation.</returns>
            public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
            {
                ScriptFileXAsset header = instance.Reader.ReadStruct <ScriptFileXAsset>(xasset.HeaderAddress);

                if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
                {
                    return(JekyllStatus.MemoryChanged);
                }

                string addedScriptsFolder = Path.Combine(xasset.Name.Contains("scripts") ? "" : "scripts", xasset.Name);
                string path = Path.Combine(instance.ExportPath, addedScriptsFolder.Contains(".gsc") ? "" : addedScriptsFolder + ".gsc");

                Directory.CreateDirectory(Path.GetDirectoryName(path));

                MemoryStream DecodedCodeStream = Decode(instance.Reader.ReadBytes(header.Buffer + 2, header.CompressedLen - 2));

                using (var outputStream = new FileStream(path, FileMode.Create))
                {
                    DecodedCodeStream.CopyTo(outputStream);
                }

                Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");

                return(JekyllStatus.Success);
            }
Ejemplo n.º 6
0
        /// <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());
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Validates and sets the DBAssetPools and DBAssetPoolSizes addresses of Modern Warfare 3.
        /// </summary>
        /// <param name="instance"></param>
        /// <returns>True if addresses are valid, otherwise false.</returns>
        public bool InitializeGame(JekyllInstance instance)
        {
            BaseAddress = instance.Reader.GetBaseAddress();
            long moduleSize = instance.Reader.GetModuleMemorySize();

            long[] scanDBAssetPools = instance.Reader.FindBytes(
                new byte?[] { 0xFF, 0xD1, 0x8B, 0xF8, 0x83, 0xC4, 0x04, 0x85, 0xFF, 0x75 },
                BaseAddress,
                BaseAddress + moduleSize,
                true);

            if (scanDBAssetPools.Length > 0)
            {
                DBAssetPools     = instance.Reader.ReadUInt32(scanDBAssetPools[0] - 0xD);
                DBAssetPoolSizes = instance.Reader.ReadUInt32(scanDBAssetPools[0] + 0x2A);

                // In Modern Warfare 3, void will always be the first entry in the XModel XAsset Pool.
                if (GetFirstXModel(instance) == "void")
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 8
0
            /// <summary>
            /// Load the valid XAssets for the StringTable XAsset Pool.
            /// </summary>
            /// <param name="instance"></param>
            /// <returns>List of StringTable XAsset objects.</returns>
            public override List <GameXAsset> Load(JekyllInstance instance)
            {
                List <GameXAsset> results = new List <GameXAsset>();

                Entries  = instance.Reader.ReadStruct <long>(instance.Game.DBAssetPools + (Marshal.SizeOf <DBAssetPool>() * Index));
                PoolSize = instance.Reader.ReadStruct <int>(instance.Game.DBAssetPoolSizes + (Marshal.SizeOf <DBAssetPoolSize>() * Index));

                for (int i = 0; i < PoolSize; i++)
                {
                    StringTableXAsset header = instance.Reader.ReadStruct <StringTableXAsset>(Entries + Marshal.SizeOf <DBAssetPool>() + (i * Marshal.SizeOf <StringTableXAsset>()));

                    if (IsNullXAsset(header.Name))
                    {
                        continue;
                    }
                    else if (instance.Reader.ReadNullTerminatedString(header.Name).EndsWith(".csv") is false)
                    {
                        continue;
                    }

                    results.Add(new GameXAsset()
                    {
                        Name          = instance.Reader.ReadNullTerminatedString(header.Name),
                        Type          = Name,
                        Size          = ElementSize,
                        XAssetPool    = this,
                        HeaderAddress = Entries + Marshal.SizeOf <DBAssetPool>() + (i * Marshal.SizeOf <StringTableXAsset>()),
                    });
                }

                return(results);
            }
Ejemplo n.º 9
0
        /// <summary>
        /// Validates and sets the DBAssetPools and DBAssetPoolSizes addresses of Ghosts.
        /// </summary>
        /// <param name="instance"></param>
        /// <returns>True if addresses are valid, otherwise false.</returns>
        public bool InitializeGame(JekyllInstance instance)
        {
            BaseAddress = instance.Reader.GetBaseAddress();
            long moduleSize = instance.Reader.GetModuleMemorySize();

            long[] scanDBAssetPools = instance.Reader.FindBytes(
                new byte?[] { 0x48, 0x8B, 0xD8, 0x48, 0x85, 0xC0, 0x75, null, 0xF0, 0xFF, 0x0D },
                BaseAddress,
                BaseAddress + moduleSize,
                true);

            if (scanDBAssetPools.Length > 0)
            {
                DBAssetPools = instance.Reader.ReadUInt32(scanDBAssetPools[0] - 0xB) + BaseAddress;

                if (instance.Reader.ActiveProcess.ProcessName == "iw6sp64_ship")
                {
                    DBAssetPoolSizes = instance.Reader.ReadUInt32(scanDBAssetPools[0] + 0x26) + BaseAddress;
                }
                else if (instance.Reader.ActiveProcess.ProcessName == "iw6mp64_ship")
                {
                    DBAssetPoolSizes = instance.Reader.ReadUInt32(scanDBAssetPools[0] + 0x1E) + BaseAddress;
                }

                // In Ghosts, void or empty_model will always be the first entry in the XModel XAsset Pool.
                if (GetFirstXModel(instance) == "void" || GetFirstXModel(instance) == "empty_model")
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 10
0
            /// <summary>
            /// Exports the specified RawFile XAsset.
            /// </summary>
            /// <param name="xasset"></param>
            /// <param name="instance"></param>
            /// <returns>Status of the export operation.</returns>
            public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
            {
                RawFileXAsset header = instance.Reader.ReadStruct <RawFileXAsset>(xasset.HeaderAddress);

                if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
                {
                    return(JekyllStatus.MemoryChanged);
                }

                string path = Path.Combine(instance.ExportPath, xasset.Name);

                Directory.CreateDirectory(Path.GetDirectoryName(path));

                try
                {
                    MemoryStream DecodedCodeStream = Decode(instance.Reader.ReadBytes(header.Buffer + 2, header.CompressedLen - 2));
                    using FileStream outputStream = new FileStream(path, FileMode.Create);
                    DecodedCodeStream.CopyTo(outputStream);
                }
                catch
                {
                    return(JekyllStatus.Exception);
                }

                Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");

                return(JekyllStatus.Success);
            }
Ejemplo n.º 11
0
        /// <summary>
        /// Validates and sets the DBAssetPools and DBAssetPoolSizes addresses of Infinite Warfare.
        /// </summary>
        /// <param name="instance"></param>
        /// <returns>True if addresses are valid, otherwise false.</returns>
        public bool InitializeGame(JekyllInstance instance)
        {
            BaseAddress = instance.Reader.GetBaseAddress();
            long moduleSize = instance.Reader.GetModuleMemorySize();

            long[] scanDBAssetPools = instance.Reader.FindBytes(
                new byte?[] { 0x48, 0x63, 0xC1, 0x48, 0x8D, 0x15, null, null, null, null, 0x48, 0x8B, 0x8C, 0xC2 },
                BaseAddress,
                BaseAddress + moduleSize,
                true);
            long[] scanDBAssetPoolSizes = instance.Reader.FindBytes(
                new byte?[] { 0x72, null, 0x48, 0x63, 0xC1, 0x48, 0x8D, 0x0D, null, null, null, null, 0x83, 0x3C, 0x81 },
                BaseAddress,
                BaseAddress + moduleSize,
                true);

            if (scanDBAssetPools.Length > 0 && scanDBAssetPoolSizes.Length > 0)
            {
                DBAssetPools     = instance.Reader.ReadInt32(scanDBAssetPools[0] + 0xE) + BaseAddress;
                DBAssetPoolSizes = instance.Reader.ReadInt32(scanDBAssetPoolSizes[0] + 0x8) + (scanDBAssetPoolSizes[0] + 0xC);

                // In Infinite Warfare, viewmodel_default will always be the first entry in the XModel XAsset Pool.
                if (GetFirstXModel(instance) == "viewmodel_default")
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Validates and sets the DBAssetPools and DBAssetPoolSizes addresses of World at War.
        /// </summary>
        /// <param name="instance"></param>
        /// <returns>True if addresses are valid, otherwise false.</returns>
        public bool InitializeGame(JekyllInstance instance)
        {
            BaseAddress = instance.Reader.GetBaseAddress();
            long moduleSize = instance.Reader.GetModuleMemorySize();

            long[] scanDBAssetPools = instance.Reader.FindBytes(
                new byte?[] { 0xFF, 0xD2, 0x8B, 0xF0, 0x83, 0xC4, 0x04, 0x85, 0xF6, 0x75 },
                BaseAddress,
                BaseAddress + moduleSize,
                true);

            if (scanDBAssetPools.Length > 0)
            {
                DBAssetPools     = instance.Reader.ReadInt32(scanDBAssetPools[0] - 0xD);
                DBAssetPoolSizes = instance.Reader.ReadInt32(scanDBAssetPools[0] + 0x25);

                // In World at War, void, defaultactor, or defaultweapon will always be the first entry in the XModel XAsset Pool.
                if (GetFirstXModel(instance) == "void" || GetFirstXModel(instance) == "defaultactor" || GetFirstXModel(instance) == "defaultweapon")
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 13
0
            /// <summary>
            /// Exports the specified ScriptFile XAsset.
            /// </summary>
            /// <param name="xasset"></param>
            /// <param name="instance"></param>
            /// <returns>Status of the export operation.</returns>
            public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
            {
                ScriptParseTree header = instance.Reader.ReadStruct <ScriptParseTree>(xasset.HeaderAddress);

                if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
                {
                    return(JekyllStatus.MemoryChanged);
                }

                try
                {
                    string path = Path.Combine(instance.ExportPath, xasset.Name);
                    Directory.CreateDirectory(Path.GetDirectoryName(path));

                    byte[] buffer = instance.Reader.ReadBytes(header.Buffer, header.Len);
                    File.WriteAllBytes(path, buffer);
                }
                catch
                {
                    return(JekyllStatus.Exception);
                }

                Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");

                return(JekyllStatus.Success);
            }
Ejemplo n.º 14
0
        /// <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));
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Gets the first entry in the XModel XAsset Pool of Infinite Warfare.
        /// </summary>
        /// <param name="instance"></param>
        /// <returns>Name of the XModel.</returns>
        public string GetFirstXModel(JekyllInstance instance)
        {
            long address = DBAssetPools + (Marshal.SizeOf <DBAssetPool>() * (int)XAssetType.xmodel);
            long pool    = instance.Reader.ReadInt64(address) + Marshal.SizeOf <DBAssetPool>();
            long name    = instance.Reader.ReadInt64(pool);

            return(instance.Reader.ReadNullTerminatedString(name));
        }
Ejemplo n.º 16
0
            /// <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);
            }
Ejemplo n.º 17
0
            /// <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)
            {
                List <GameXAsset> results = new List <GameXAsset>();

                XAssetPool pool = instance.Reader.ReadStruct <XAssetPool>(instance.Game.DBAssetPools + (Index * Marshal.SizeOf <XAssetPool>()));

                Entries     = pool.Pool;
                ElementSize = pool.ItemSize;
                PoolSize    = (uint)pool.ItemCount;

                if (IsValidPool(Name, ElementSize, Marshal.SizeOf <LocalizeEntry>()) == false)
                {
                    return(results);
                }

                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, nullCheck: true);
                    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(results);
            }
Ejemplo n.º 18
0
            /// <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);
            }
Ejemplo n.º 19
0
            /// <summary>
            /// Exports the specified RawFile XAsset.
            /// </summary>
            /// <param name="xasset"></param>
            /// <param name="instance"></param>
            /// <returns>Status of the export operation.</returns>
            public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
            {
                RawFileXAsset header = instance.Reader.ReadStruct <RawFileXAsset>(xasset.HeaderAddress);

                string path = Path.Combine(instance.ExportPath, "rawfile/" + xasset.Name);

                Directory.CreateDirectory(Path.GetDirectoryName(path));

                byte[] buffer = instance.Reader.ReadBytes(header.Buffer, header.Len);

                File.WriteAllBytes(path, buffer);

                Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");

                return(JekyllStatus.Success);
            }
Ejemplo n.º 20
0
        /// <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);
        }
Ejemplo n.º 21
0
            /// <summary>
            /// Exports the specified StringTable XAsset.
            /// </summary>
            /// <param name="xasset"></param>
            /// <param name="instance"></param>
            /// <returns>Status of the export operation.</returns>
            public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
            {
                StringTableXAsset header = instance.Reader.ReadStruct <StringTableXAsset>(xasset.HeaderAddress);

                if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
                {
                    return(JekyllStatus.MemoryChanged);
                }

                string path = Path.Combine(instance.ExportPath, xasset.Name);

                Directory.CreateDirectory(Path.GetDirectoryName(path));

                StringBuilder stringTable = new StringBuilder();

                int index = 0;

                for (int x = 0; x < header.RowCount; x++)
                {
                    for (int y = 0; y < header.ColumnCount; y++)
                    {
                        int    cell  = instance.Reader.ReadInt16(header.CellIndices + (2 * index));
                        string value = instance.Reader.ReadNullTerminatedString(instance.Reader.ReadInt64(header.Strings + (8 * cell)));

                        stringTable.Append(value);

                        if (y != (header.ColumnCount - 1))
                        {
                            stringTable.Append(",");
                        }

                        index++;
                    }

                    stringTable.AppendLine();
                }

                File.WriteAllText(path, stringTable.ToString());

                Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");

                return(JekyllStatus.Success);
            }
Ejemplo n.º 22
0
            /// <summary>
            /// Exports the specified ScriptFile XAsset.
            /// </summary>
            /// <param name="xasset"></param>
            /// <param name="instance"></param>
            /// <returns>Status of the export operation.</returns>
            public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
            {
                ScriptFileXAsset header = instance.Reader.ReadStruct <ScriptFileXAsset>(xasset.HeaderAddress);

                if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
                {
                    return(JekyllStatus.MemoryChanged);
                }

                string addedScriptsFolder = Path.Combine(xasset.Name.Contains("scripts") ? "" : "scripts", xasset.Name);
                string path = Path.Combine(instance.ExportPath, addedScriptsFolder.Contains(".gsc") ? addedScriptsFolder + "bin" : addedScriptsFolder + ".gscbin");

                Directory.CreateDirectory(Path.GetDirectoryName(path));

                byte[] filename      = Encoding.UTF8.GetBytes(xasset.Name + char.MinValue);
                byte[] compressedLen = BitConverter.GetBytes(header.CompressedLen);
                byte[] len           = BitConverter.GetBytes(header.Len);
                byte[] bytecodeLen   = BitConverter.GetBytes(header.BytecodeLen);
                byte[] buffer        = instance.Reader.ReadBytes(header.Buffer, header.CompressedLen);
                byte[] bytecode      = instance.Reader.ReadBytes(header.Bytecode, header.BytecodeLen);

                byte[] file = new byte[filename.Length + compressedLen.Length + len.Length + bytecodeLen.Length + buffer.Length + bytecode.Length];

                Buffer.BlockCopy(filename, 0, file, 0, filename.Length);
                Buffer.BlockCopy(compressedLen, 0, file, filename.Length, compressedLen.Length);
                Buffer.BlockCopy(len, 0, file, filename.Length + compressedLen.Length, len.Length);
                Buffer.BlockCopy(bytecodeLen, 0, file, filename.Length + compressedLen.Length + len.Length, bytecodeLen.Length);
                Buffer.BlockCopy(buffer, 0, file, filename.Length + compressedLen.Length + len.Length + bytecodeLen.Length, buffer.Length);
                Buffer.BlockCopy(bytecode, 0, file, filename.Length + compressedLen.Length + len.Length + bytecodeLen.Length + buffer.Length, bytecode.Length);

                try
                {
                    File.WriteAllBytes(path, file);
                }
                catch
                {
                    return(JekyllStatus.Exception);
                }

                Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");

                return(JekyllStatus.Success);
            }
Ejemplo n.º 23
0
            /// <summary>
            /// Exports the specified MapEnts XAsset.
            /// </summary>
            /// <param name="xasset"></param>
            /// <param name="instance"></param>
            /// <returns>Status of the export operation.</returns>
            public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
            {
                MapEntsXAsset header = instance.Reader.ReadStruct <MapEntsXAsset>(xasset.HeaderAddress);

                if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
                {
                    return(JekyllStatus.MemoryChanged);
                }

                string path = Path.Combine(instance.ExportPath, xasset.Name);

                Directory.CreateDirectory(Path.GetDirectoryName(path));

                File.WriteAllText(path, instance.Reader.ReadNullTerminatedString(header.EntityString));

                Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");

                return(JekyllStatus.Success);
            }
Ejemplo n.º 24
0
            /// <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)
            {
                Entries  = instance.Reader.ReadStruct <long>(instance.Game.DBAssetPools + (Marshal.SizeOf <DBAssetPool>() * Index));
                PoolSize = instance.Reader.ReadStruct <int>(instance.Game.DBAssetPoolSizes + (Marshal.SizeOf <DBAssetPoolSize>() * Index));

                Dictionary <string, string> entries = new Dictionary <string, string>();

                Console.WriteLine(PoolSize);

                for (int i = 0; i < PoolSize; i++)
                {
                    LocalizeEntry header = instance.Reader.ReadStruct <LocalizeEntry>(Entries + Marshal.SizeOf <DBAssetPool>() + (i * Marshal.SizeOf <LocalizeEntry>()));

                    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>());
            }
Ejemplo n.º 25
0
            /// <summary>
            /// Exports the specified StringTable XAsset.
            /// </summary>
            /// <param name="xasset"></param>
            /// <param name="instance"></param>
            /// <returns>Status of the export operation.</returns>
            public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
            {
                StringTableXAsset header = instance.Reader.ReadStruct <StringTableXAsset>(xasset.HeaderAddress);

                if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
                {
                    return(JekyllStatus.MemoryChanged);
                }

                string path = Path.Combine(instance.ExportPath, xasset.Name);

                Directory.CreateDirectory(Path.GetDirectoryName(path));

                StringBuilder stringTable = new StringBuilder();

                for (int x = 0; x < header.RowCount; x++)
                {
                    for (int y = 0; y < header.ColumnCount; y++)
                    {
                        uint   data  = instance.Reader.ReadStruct <uint>(header.Values);
                        string value = instance.Reader.ReadNullTerminatedString(data);

                        stringTable.Append(value);

                        if (y != (header.ColumnCount - 1))
                        {
                            stringTable.Append(",");
                        }

                        header.Values += (uint)Marshal.SizeOf <uint>();
                    }

                    stringTable.AppendLine();
                }

                File.WriteAllText(path, stringTable.ToString());

                Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");

                return(JekyllStatus.Success);
            }
Ejemplo n.º 26
0
            /// <summary>
            /// Exports the specified TTF XAsset.
            /// </summary>
            /// <param name="xasset"></param>
            /// <param name="instance"></param>
            /// <returns>Status of the export operation.</returns>
            public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
            {
                TTFDef header = instance.Reader.ReadStruct <TTFDef>(xasset.HeaderAddress);

                if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
                {
                    return(JekyllStatus.MemoryChanged);
                }

                string path = Path.Combine(instance.ExportPath, xasset.Name);

                Directory.CreateDirectory(Path.GetDirectoryName(path));

                byte[] buffer = instance.Reader.ReadBytes(header.File, (int)header.FileLen);

                File.WriteAllBytes(path, buffer);

                Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");

                return(JekyllStatus.Success);
            }
Ejemplo n.º 27
0
            /// <summary>
            /// Load the valid XAssets for the ScriptParseTree XAsset Pool.
            /// </summary>
            /// <param name="instance"></param>
            /// <returns>List of ScriptParseTree XAsset objects.</returns>
            public override List <GameXAsset> Load(JekyllInstance instance)
            {
                List <GameXAsset> results = new List <GameXAsset>();

                XAssetPool pool = instance.Reader.ReadStruct <XAssetPool>(instance.Game.DBAssetPools + (Index * Marshal.SizeOf <XAssetPool>()));

                Entries     = pool.Pool;
                ElementSize = pool.ItemSize;
                PoolSize    = (uint)pool.ItemCount;

                if (IsValidPool(Name, ElementSize, Marshal.SizeOf <ScriptParseTree>()) == false)
                {
                    return(results);
                }

                for (int i = 0; i < PoolSize; i++)
                {
                    ScriptParseTree header = instance.Reader.ReadStruct <ScriptParseTree>(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);
            }
Ejemplo n.º 28
0
        /// <summary>
        /// Validates and sets the XAsset Pools address of Black Ops III.
        /// </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?[] { 0x63, 0xC1, 0x48, 0x8D, 0x05, null, null, null, null, 0x49, 0xC1, 0xE0, null, 0x4C, 0x03, 0xC0 },
                BaseAddress,
                BaseAddress + instance.Reader.GetModuleMemorySize(),
                true);

            if (scanDBAssetPools.Length > 0)
            {
                DBAssetPools = instance.Reader.ReadInt32(scanDBAssetPools[0] + 0x5) + (scanDBAssetPools[0] + 0x9);

                // In Black Ops III, void will always be the first entry in the XModel XAsset Pool.
                if (GetFirstXModel(instance) == "void")
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 29
0
        /// <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")
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 30
0
            /// <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);
            }