├── .github
└── FUNDING.yml
├── .gitignore
├── Jekyll.Library
├── Enums
│ └── JekyllStatus.cs
├── Game
│ ├── AdvancedWarfare
│ │ ├── AdvancedWarfare.cs
│ │ └── XAssets
│ │ │ ├── Localize.cs
│ │ │ ├── LuaFile.cs
│ │ │ ├── MapEnts.cs
│ │ │ ├── RawFile.cs
│ │ │ ├── ScriptFile.cs
│ │ │ └── StringTable.cs
│ ├── BlackOps
│ │ ├── BlackOps.cs
│ │ └── XAssets
│ │ │ ├── Localize.cs
│ │ │ ├── MapEnts.cs
│ │ │ ├── RawFile.cs
│ │ │ └── StringTable.cs
│ ├── BlackOps2
│ │ ├── BlackOps2.cs
│ │ └── XAssets
│ │ │ ├── Localize.cs
│ │ │ ├── MapEnts.cs
│ │ │ ├── RawFile.cs
│ │ │ ├── ScriptFile.cs
│ │ │ └── StringTable.cs
│ ├── BlackOps3
│ │ ├── BlackOps3.cs
│ │ └── XAssets
│ │ │ ├── BinaryHTML.cs
│ │ │ ├── Localize.cs
│ │ │ ├── MapEnts.cs
│ │ │ ├── RawFile.cs
│ │ │ ├── ScriptFile.cs
│ │ │ ├── StringTable.cs
│ │ │ └── TTF.cs
│ ├── BlackOps4
│ │ ├── BlackOps4.cs
│ │ └── XAssets
│ │ │ └── RawFile.cs
│ ├── Ghosts
│ │ ├── Ghosts.cs
│ │ └── XAssets
│ │ │ ├── Localize.cs
│ │ │ ├── LuaFile.cs
│ │ │ ├── MapEnts.cs
│ │ │ ├── RawFile.cs
│ │ │ ├── ScriptFile.cs
│ │ │ └── StringTable.cs
│ ├── InfiniteWarfare
│ │ ├── InfiniteWarfare.cs
│ │ └── XAssets
│ │ │ ├── Localize.cs
│ │ │ ├── LuaFile.cs
│ │ │ ├── MapEnts.cs
│ │ │ ├── RawFile.cs
│ │ │ ├── ScriptFile.cs
│ │ │ ├── StringTable.cs
│ │ │ └── TTF.cs
│ ├── ModernWarfare2
│ │ ├── ModernWarfare2.cs
│ │ └── XAssets
│ │ │ ├── Localize.cs
│ │ │ ├── MapEnts.cs
│ │ │ ├── RawFile.cs
│ │ │ └── StringTable.cs
│ ├── ModernWarfare2CR
│ │ ├── ModernWarfare2CR.cs
│ │ └── XAssets
│ │ │ ├── Localize.cs
│ │ │ ├── LuaFile.cs
│ │ │ ├── MapEnts.cs
│ │ │ ├── RawFile.cs
│ │ │ ├── ScriptFile.cs
│ │ │ ├── StringTable.cs
│ │ │ └── TTF.cs
│ ├── ModernWarfare3
│ │ ├── ModernWarfare3.cs
│ │ └── XAssets
│ │ │ ├── Localize.cs
│ │ │ ├── MapEnts.cs
│ │ │ ├── RawFile.cs
│ │ │ ├── ScriptFile.cs
│ │ │ └── StringTable.cs
│ ├── ModernWarfareRemastered
│ │ ├── ModernWarfareRemastered.cs
│ │ └── XAssets
│ │ │ ├── Localize.cs
│ │ │ ├── LuaFile.cs
│ │ │ ├── MapEnts.cs
│ │ │ ├── RawFile.cs
│ │ │ ├── ScriptFile.cs
│ │ │ ├── StringTable.cs
│ │ │ └── TTF.cs
│ ├── WWII
│ │ ├── WWII.cs
│ │ └── XAssets
│ │ │ ├── Localize.cs
│ │ │ ├── LuaFile.cs
│ │ │ ├── MapEnts.cs
│ │ │ ├── RawFile.cs
│ │ │ ├── ScriptFile.cs
│ │ │ ├── StringTable.cs
│ │ │ └── TTF.cs
│ └── WorldatWar
│ │ ├── WorldatWar.cs
│ │ └── XAssets
│ │ ├── Localize.cs
│ │ ├── MapEnts.cs
│ │ ├── RawFile.cs
│ │ └── StringTable.cs
├── Interfaces
│ ├── IGame.cs
│ └── IXAssetPool.cs
├── Jekyll.Library.csproj
├── JekyllInstance.cs
└── Utility
│ └── GameXAsset.cs
├── Jekyll.UI
├── Jekyll.UI.csproj
└── Program.cs
├── Jekyll.sln
├── LICENSE
├── PhilLibX
├── IO
│ ├── MemoryUtility.cs
│ └── ProcessReader.cs
├── NativeMethods.cs
└── PhilLibX.csproj
└── README.md
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | ko_fi: mxtive
2 |
--------------------------------------------------------------------------------
/Jekyll.Library/Enums/JekyllStatus.cs:
--------------------------------------------------------------------------------
1 | namespace JekyllLibrary.Library
2 | {
3 | public enum JekyllStatus
4 | {
5 | Success,
6 | UnsupportedBinary,
7 | FailedToFindGame,
8 | Exception,
9 | MemoryChanged,
10 | GameClosed,
11 | }
12 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/AdvancedWarfare/XAssets/Localize.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Runtime.InteropServices;
6 |
7 | namespace JekyllLibrary.Library
8 | {
9 | public partial class AdvancedWarfare
10 | {
11 | public class Localize : IXAssetPool
12 | {
13 | public override string Name => "Localize Entry";
14 |
15 | public override int Index => (int)XAssetType.localize;
16 |
17 | ///
18 | /// Structure of an Advanced Warfare LocalizeEntry XAsset.
19 | ///
20 | private struct LocalizeEntry
21 | {
22 | public long Value { get; set; }
23 | public long Name { get; set; }
24 | }
25 |
26 | ///
27 | /// Load the valid XAssets for the Localize XAsset Pool.
28 | ///
29 | ///
30 | /// List of Localize XAsset objects.
31 | public override List Load(JekyllInstance instance)
32 | {
33 | Entries = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Marshal.SizeOf() * Index));
34 | PoolSize = instance.Reader.ReadStruct(instance.Game.DBAssetPoolSizes + (Marshal.SizeOf() * Index));
35 |
36 | Dictionary entries = new Dictionary();
37 |
38 | for (int i = 0; i < PoolSize; i++)
39 | {
40 | LocalizeEntry header = instance.Reader.ReadStruct(Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()));
41 |
42 | if (IsNullXAsset(header.Name))
43 | {
44 | continue;
45 | }
46 |
47 | string key = instance.Reader.ReadNullTerminatedString(header.Name).ToUpper();
48 |
49 | if (entries.TryGetValue(key, out string _))
50 | {
51 | continue;
52 | }
53 |
54 | entries.Add(key, instance.Reader.ReadNullTerminatedString(header.Value));
55 |
56 | Console.WriteLine($"Exported Localize {key}");
57 | }
58 |
59 | string path = Path.Combine(instance.ExportPath, "localize.json");
60 | Directory.CreateDirectory(Path.GetDirectoryName(path));
61 |
62 | using (StreamWriter file = File.CreateText(path))
63 | {
64 | file.Write(JsonConvert.SerializeObject(entries, Formatting.Indented));
65 | }
66 |
67 | return new List();
68 | }
69 |
70 | ///
71 | /// Exports the specified Localize XAsset.
72 | ///
73 | ///
74 | ///
75 | /// Status of the export operation.
76 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
77 | {
78 | return JekyllStatus.Success;
79 | }
80 | }
81 | }
82 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/AdvancedWarfare/XAssets/LuaFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace JekyllLibrary.Library
7 | {
8 | public partial class AdvancedWarfare
9 | {
10 | public class LuaFile : IXAssetPool
11 | {
12 | public override string Name => "Lua File";
13 |
14 | public override int Index => (int)XAssetType.luafile;
15 |
16 | ///
17 | /// Structure of an Advanced Warfare LuaFile XAsset.
18 | ///
19 | private struct LuaFileXAsset
20 | {
21 | public long Name { get; set; }
22 | public int Len { get; set; }
23 | public int StrippingType { get; set; }
24 | public long Buffer { get; set; }
25 | }
26 |
27 | ///
28 | /// Load the valid XAssets for the LuaFile XAsset Pool.
29 | ///
30 | ///
31 | /// List of LuaFile XAsset objects.
32 | public override List Load(JekyllInstance instance)
33 | {
34 | List results = new List();
35 |
36 | Entries = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Marshal.SizeOf() * Index));
37 | PoolSize = instance.Reader.ReadStruct(instance.Game.DBAssetPoolSizes + (Marshal.SizeOf() * Index));
38 |
39 | for (int i = 0; i < PoolSize; i++)
40 | {
41 | LuaFileXAsset header = instance.Reader.ReadStruct(Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()));
42 |
43 | if (IsNullXAsset(header.Name))
44 | {
45 | continue;
46 | }
47 | else if (header.Len == 0)
48 | {
49 | continue;
50 | }
51 |
52 | results.Add(new GameXAsset()
53 | {
54 | Name = instance.Reader.ReadNullTerminatedString(header.Name),
55 | Type = Name,
56 | Size = ElementSize,
57 | XAssetPool = this,
58 | HeaderAddress = Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()),
59 | });
60 | }
61 |
62 | return results;
63 | }
64 |
65 | ///
66 | /// Exports the specified LuaFile XAsset.
67 | ///
68 | ///
69 | ///
70 | /// Status of the export operation.
71 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
72 | {
73 | LuaFileXAsset header = instance.Reader.ReadStruct(xasset.HeaderAddress);
74 |
75 | if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
76 | {
77 | return JekyllStatus.MemoryChanged;
78 | }
79 |
80 | string path = Path.Combine(instance.ExportPath, xasset.Name);
81 | Directory.CreateDirectory(Path.GetDirectoryName(path));
82 |
83 | byte[] buffer = instance.Reader.ReadBytes(header.Buffer, header.Len);
84 | File.WriteAllBytes(path, buffer);
85 |
86 | Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");
87 |
88 | return JekyllStatus.Success;
89 | }
90 | }
91 | }
92 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/AdvancedWarfare/XAssets/MapEnts.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace JekyllLibrary.Library
7 | {
8 | public partial class AdvancedWarfare
9 | {
10 | public class MapEnts : IXAssetPool
11 | {
12 | public override string Name => "Map Entities";
13 |
14 | public override int Index => (int)XAssetType.map_ents;
15 |
16 | ///
17 | /// Structure of an Advanced Warfare MapEnts XAsset.
18 | ///
19 | private struct MapEntsXAsset
20 | {
21 | public long Name { get; set; }
22 | public long EntityString { get; set; }
23 | // TODO: Fill remaining unknown.
24 | }
25 |
26 | ///
27 | /// Load the valid XAssets for the MapEnts XAsset Pool.
28 | ///
29 | ///
30 | /// List of MapEnts XAsset objects.
31 | public override List Load(JekyllInstance instance)
32 | {
33 | List results = new List();
34 |
35 | Entries = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Marshal.SizeOf() * Index));
36 | PoolSize = instance.Reader.ReadStruct(instance.Game.DBAssetPoolSizes + (Marshal.SizeOf() * Index));
37 |
38 | for (int i = 0; i < PoolSize; i++)
39 | {
40 | MapEntsXAsset header = instance.Reader.ReadStruct(Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()));
41 |
42 | if (IsNullXAsset(header.Name))
43 | {
44 | continue;
45 | }
46 | else if (instance.Reader.ReadNullTerminatedString(header.Name).EndsWith(".d3dbsp") is false)
47 | {
48 | continue;
49 | }
50 |
51 | results.Add(new GameXAsset()
52 | {
53 | Name = instance.Reader.ReadNullTerminatedString(header.Name),
54 | Type = Name,
55 | Size = ElementSize,
56 | XAssetPool = this,
57 | HeaderAddress = Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()),
58 | });
59 | }
60 |
61 | return results;
62 | }
63 |
64 | ///
65 | /// Exports the specified MapEnts XAsset.
66 | ///
67 | ///
68 | ///
69 | /// Status of the export operation.
70 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
71 | {
72 | MapEntsXAsset header = instance.Reader.ReadStruct(xasset.HeaderAddress);
73 |
74 | if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
75 | {
76 | return JekyllStatus.MemoryChanged;
77 | }
78 |
79 | string path = Path.Combine(instance.ExportPath, xasset.Name);
80 | Directory.CreateDirectory(Path.GetDirectoryName(path));
81 |
82 | File.WriteAllText(path, instance.Reader.ReadNullTerminatedString(header.EntityString));
83 |
84 | Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");
85 |
86 | return JekyllStatus.Success;
87 | }
88 | }
89 | }
90 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/AdvancedWarfare/XAssets/RawFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.IO.Compression;
5 | using System.Runtime.InteropServices;
6 |
7 | namespace JekyllLibrary.Library
8 | {
9 | public partial class AdvancedWarfare
10 | {
11 | public class RawFile : IXAssetPool
12 | {
13 | public override string Name => "Raw File";
14 |
15 | public override int Index => (int)XAssetType.rawfile;
16 |
17 | ///
18 | /// Structure of an Advanced Warfare RawFile XAsset.
19 | ///
20 | private struct RawFileXAsset
21 | {
22 | public long Name { get; set; }
23 | public int CompressedLen { get; set; }
24 | public int Len { get; set; }
25 | public long Buffer { get; set; }
26 | }
27 |
28 | ///
29 | /// Load the valid XAssets for the RawFile XAsset Pool.
30 | ///
31 | ///
32 | /// List of RawFile XAsset objects.
33 | public override List Load(JekyllInstance instance)
34 | {
35 | List results = new List();
36 |
37 | Entries = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Marshal.SizeOf() * Index));
38 | PoolSize = instance.Reader.ReadStruct(instance.Game.DBAssetPoolSizes + (Marshal.SizeOf() * Index));
39 |
40 | for (int i = 0; i < PoolSize; i++)
41 | {
42 | RawFileXAsset header = instance.Reader.ReadStruct(Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()));
43 |
44 | if (IsNullXAsset(header.Name))
45 | {
46 | continue;
47 | }
48 | else if (header.Len == 0)
49 | {
50 | continue;
51 | }
52 |
53 | results.Add(new GameXAsset()
54 | {
55 | Name = instance.Reader.ReadNullTerminatedString(header.Name),
56 | Type = Name,
57 | Size = ElementSize,
58 | XAssetPool = this,
59 | HeaderAddress = Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()),
60 | });
61 | }
62 |
63 | return results;
64 | }
65 |
66 | ///
67 | /// Exports the specified RawFile XAsset.
68 | ///
69 | ///
70 | ///
71 | /// Status of the export operation.
72 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
73 | {
74 | RawFileXAsset header = instance.Reader.ReadStruct(xasset.HeaderAddress);
75 |
76 | if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
77 | {
78 | return JekyllStatus.MemoryChanged;
79 | }
80 |
81 | try
82 | {
83 | string path = Path.Combine(instance.ExportPath, xasset.Name);
84 | Directory.CreateDirectory(Path.GetDirectoryName(path));
85 |
86 | MemoryStream DecodedCodeStream = Decode(instance.Reader.ReadBytes(header.Buffer + 2, header.CompressedLen - 2));
87 |
88 | using FileStream outputStream = new FileStream(path, FileMode.Create);
89 | DecodedCodeStream.CopyTo(outputStream);
90 | }
91 | catch
92 | {
93 | return JekyllStatus.Exception;
94 | }
95 |
96 | Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");
97 |
98 | return JekyllStatus.Success;
99 | }
100 |
101 | ///
102 | /// Decompress the specified array of bytes.
103 | ///
104 | ///
105 | ///
106 | public static MemoryStream Decode(byte[] data)
107 | {
108 | MemoryStream output = new MemoryStream();
109 | MemoryStream input = new MemoryStream(data);
110 |
111 | using (DeflateStream deflateStream = new DeflateStream(input, CompressionMode.Decompress))
112 | {
113 | deflateStream.CopyTo(output);
114 | }
115 |
116 | output.Flush();
117 | output.Position = 0;
118 |
119 | return output;
120 | }
121 | }
122 | }
123 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/BlackOps/XAssets/Localize.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Runtime.InteropServices;
6 |
7 | namespace JekyllLibrary.Library
8 | {
9 | public partial class BlackOps
10 | {
11 | public class Localize : IXAssetPool
12 | {
13 | public override string Name => "Localize Entry";
14 |
15 | public override int Index => (int)XAssetType.ASSET_TYPE_LOCALIZE_ENTRY;
16 |
17 | ///
18 | /// Structure of a Black Ops Localize XAsset.
19 | ///
20 | private struct LocalizeEntry
21 | {
22 | public uint Value { get; set; }
23 | public uint Name { get; set; }
24 | }
25 |
26 | ///
27 | /// Load the valid XAssets for the Localize XAsset Pool.
28 | ///
29 | ///
30 | /// List of Localize XAsset objects.
31 | public override List Load(JekyllInstance instance)
32 | {
33 | Entries = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Marshal.SizeOf() * Index));
34 | PoolSize = instance.Reader.ReadStruct(instance.Game.DBAssetPoolSizes + (Marshal.SizeOf() * Index));
35 |
36 | Dictionary entries = new Dictionary();
37 |
38 | for (int i = 0; i < PoolSize; i++)
39 | {
40 | LocalizeEntry header = instance.Reader.ReadStruct(Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()));
41 |
42 | if (IsNullXAsset(header.Name))
43 | {
44 | continue;
45 | }
46 |
47 | string key = instance.Reader.ReadNullTerminatedString(header.Name).ToUpper();
48 |
49 | if (entries.TryGetValue(key, out string _))
50 | {
51 | continue;
52 | }
53 |
54 | entries.Add(key, instance.Reader.ReadNullTerminatedString(header.Value, nullCheck: true));
55 |
56 | Console.WriteLine($"Exported {Name} {key}");
57 | }
58 |
59 | string path = Path.Combine(instance.ExportPath, "localize.json");
60 | Directory.CreateDirectory(Path.GetDirectoryName(path));
61 |
62 | using (StreamWriter file = File.CreateText(path))
63 | {
64 | file.Write(JsonConvert.SerializeObject(entries, Formatting.Indented));
65 | }
66 |
67 | return new List();
68 | }
69 |
70 | ///
71 | /// Exports the specified Localize XAsset.
72 | ///
73 | ///
74 | ///
75 | /// Status of the export operation.
76 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
77 | {
78 | return JekyllStatus.Success;
79 | }
80 | }
81 | }
82 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/BlackOps/XAssets/MapEnts.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace JekyllLibrary.Library
7 | {
8 | public partial class BlackOps
9 | {
10 | public class MapEnts : IXAssetPool
11 | {
12 | public override string Name => "Map Entities";
13 |
14 | public override int Index => (int)XAssetType.ASSET_TYPE_MAP_ENTS;
15 |
16 | ///
17 | /// Structure of a Black Ops MapEnts XAsset.
18 | ///
19 | private struct MapEntsXAsset
20 | {
21 | public uint Name { get; set; }
22 | public uint EntityString { get; set; }
23 | public int NumEntityChars { get; set; }
24 | }
25 |
26 | ///
27 | /// Load the valid XAssets for the MapEnts XAsset Pool.
28 | ///
29 | ///
30 | /// List of MapEnts XAsset objects.
31 | public override List Load(JekyllInstance instance)
32 | {
33 | List results = new List();
34 |
35 | Entries = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Marshal.SizeOf() * Index));
36 | PoolSize = instance.Reader.ReadStruct(instance.Game.DBAssetPoolSizes + (Marshal.SizeOf() * Index));
37 |
38 | for (int i = 0; i < PoolSize; i++)
39 | {
40 | MapEntsXAsset header = instance.Reader.ReadStruct(Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()));
41 |
42 | if (IsNullXAsset(header.Name))
43 | {
44 | continue;
45 | }
46 | else if (instance.Reader.ReadNullTerminatedString(header.Name).EndsWith(".d3dbsp") is false)
47 | {
48 | continue;
49 | }
50 |
51 | results.Add(new GameXAsset()
52 | {
53 | Name = instance.Reader.ReadNullTerminatedString(header.Name),
54 | Type = Name,
55 | Size = ElementSize,
56 | XAssetPool = this,
57 | HeaderAddress = Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()),
58 | });
59 | }
60 |
61 | return results;
62 | }
63 |
64 | ///
65 | /// Exports the specified MapEnts XAsset.
66 | ///
67 | ///
68 | ///
69 | /// Status of the export operation.
70 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
71 | {
72 | MapEntsXAsset header = instance.Reader.ReadStruct(xasset.HeaderAddress);
73 |
74 | if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
75 | {
76 | return JekyllStatus.MemoryChanged;
77 | }
78 |
79 | string path = Path.Combine(instance.ExportPath, xasset.Name);
80 | Directory.CreateDirectory(Path.GetDirectoryName(path));
81 |
82 | File.WriteAllText(path, instance.Reader.ReadNullTerminatedString(header.EntityString));
83 |
84 | Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");
85 |
86 | return JekyllStatus.Success;
87 | }
88 | }
89 | }
90 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/BlackOps/XAssets/RawFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace JekyllLibrary.Library
7 | {
8 | public partial class BlackOps
9 | {
10 | public class RawFile : IXAssetPool
11 | {
12 | public override string Name => "Raw File";
13 |
14 | public override int Index => (int)XAssetType.ASSET_TYPE_RAWFILE;
15 |
16 | ///
17 | /// Structure of a Black Ops RawFile XAsset.
18 | ///
19 | private struct RawFileXAsset
20 | {
21 | public uint Name { get; set; }
22 | public int Len { get; set; }
23 | public uint Buffer { get; set; }
24 | }
25 |
26 | ///
27 | /// Load the valid XAssets for the RawFile XAsset Pool.
28 | ///
29 | ///
30 | /// List of RawFile XAsset objects.
31 | public override List Load(JekyllInstance instance)
32 | {
33 | List results = new List();
34 |
35 | Entries = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Marshal.SizeOf() * Index));
36 | PoolSize = instance.Reader.ReadStruct(instance.Game.DBAssetPoolSizes + (Marshal.SizeOf() * Index));
37 |
38 | for (int i = 0; i < PoolSize; i++)
39 | {
40 | RawFileXAsset header = instance.Reader.ReadStruct(Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()));
41 |
42 | if (IsNullXAsset(header.Name))
43 | {
44 | continue;
45 | }
46 | else if (header.Len == 0)
47 | {
48 | continue;
49 | }
50 |
51 | results.Add(new GameXAsset()
52 | {
53 | Name = instance.Reader.ReadNullTerminatedString(header.Name),
54 | Type = Name,
55 | Size = ElementSize,
56 | XAssetPool = this,
57 | HeaderAddress = Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()),
58 | });
59 | }
60 |
61 | return results;
62 | }
63 |
64 | ///
65 | /// Exports the specified RawFile XAsset.
66 | ///
67 | ///
68 | ///
69 | /// Status of the export operation.
70 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
71 | {
72 | RawFileXAsset header = instance.Reader.ReadStruct(xasset.HeaderAddress);
73 |
74 | if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
75 | {
76 | return JekyllStatus.MemoryChanged;
77 | }
78 |
79 | try
80 | {
81 | string path = Path.Combine(instance.ExportPath, xasset.Name);
82 | Directory.CreateDirectory(Path.GetDirectoryName(path));
83 |
84 | byte[] buffer = instance.Reader.ReadBytes(header.Buffer, header.Len);
85 | File.WriteAllBytes(path, buffer);
86 | }
87 | catch
88 | {
89 | return JekyllStatus.Exception;
90 | }
91 |
92 | Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");
93 |
94 | return JekyllStatus.Success;
95 | }
96 | }
97 | }
98 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/BlackOps2/XAssets/Localize.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Runtime.InteropServices;
6 |
7 | namespace JekyllLibrary.Library
8 | {
9 | public partial class BlackOps2
10 | {
11 | public class Localize : IXAssetPool
12 | {
13 | public override string Name => "Localize Entry";
14 |
15 | public override int Index => (int)XAssetType.ASSET_TYPE_LOCALIZE_ENTRY;
16 |
17 | ///
18 | /// Structure of a Black Ops II LocalizeEntry.
19 | ///
20 | private struct LocalizeEntry
21 | {
22 | public uint Value { get; set; }
23 | public uint Name { get; set; }
24 | }
25 |
26 | ///
27 | /// Load the valid XAssets for the Localize XAsset Pool.
28 | ///
29 | ///
30 | /// List of Localize XAsset objects.
31 | public override List Load(JekyllInstance instance)
32 | {
33 | Entries = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Marshal.SizeOf() * Index));
34 | PoolSize = instance.Reader.ReadStruct(instance.Game.DBAssetPoolSizes + (Marshal.SizeOf() * Index));
35 |
36 | Dictionary entries = new Dictionary();
37 |
38 | for (int i = 0; i < PoolSize; i++)
39 | {
40 | LocalizeEntry header = instance.Reader.ReadStruct(Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()));
41 |
42 | if (IsNullXAsset(header.Name))
43 | {
44 | continue;
45 | }
46 |
47 | string key = instance.Reader.ReadNullTerminatedString(header.Name).ToUpper();
48 |
49 | if (entries.TryGetValue(key, out string _))
50 | {
51 | continue;
52 | }
53 |
54 | entries.Add(key, instance.Reader.ReadNullTerminatedString(header.Value, nullCheck: true));
55 |
56 | Console.WriteLine($"Exported {Name} {key}");
57 | }
58 |
59 | string path = Path.Combine(instance.ExportPath, "localize.json");
60 | Directory.CreateDirectory(Path.GetDirectoryName(path));
61 |
62 | using (StreamWriter file = File.CreateText(path))
63 | {
64 | file.Write(JsonConvert.SerializeObject(entries, Formatting.Indented));
65 | }
66 |
67 | return new List();
68 | }
69 |
70 | ///
71 | /// Exports the specified Localize XAsset.
72 | ///
73 | ///
74 | ///
75 | /// Status of the export operation.
76 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
77 | {
78 | return JekyllStatus.Success;
79 | }
80 | }
81 | }
82 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/BlackOps2/XAssets/MapEnts.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace JekyllLibrary.Library
7 | {
8 | public partial class BlackOps2
9 | {
10 | public class MapEnts : IXAssetPool
11 | {
12 | public override string Name => "Map Entities";
13 |
14 | public override int Index => (int)XAssetType.ASSET_TYPE_MAP_ENTS;
15 |
16 | ///
17 | /// Structure of a Black Ops II MapEnts XAsset.
18 | ///
19 | private struct MapEntsXAsset
20 | {
21 | public uint Name { get; set; }
22 | public uint EntityString { get; set; }
23 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 28)]
24 | public byte[] Unused;
25 | }
26 |
27 | ///
28 | /// Load the valid XAssets for the MapEnts XAsset Pool.
29 | ///
30 | ///
31 | /// List of MapEnts XAsset objects.
32 | public override List Load(JekyllInstance instance)
33 | {
34 | List results = new List();
35 |
36 | Entries = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Marshal.SizeOf() * Index));
37 | PoolSize = instance.Reader.ReadStruct(instance.Game.DBAssetPoolSizes + (Marshal.SizeOf() * Index));
38 |
39 | for (int i = 0; i < PoolSize; i++)
40 | {
41 | MapEntsXAsset header = instance.Reader.ReadStruct(Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()));
42 |
43 | if (IsNullXAsset(header.Name))
44 | {
45 | continue;
46 | }
47 | else if (instance.Reader.ReadNullTerminatedString(header.Name).EndsWith(".d3dbsp") is false)
48 | {
49 | continue;
50 | }
51 |
52 | results.Add(new GameXAsset()
53 | {
54 | Name = instance.Reader.ReadNullTerminatedString(header.Name),
55 | Type = Name,
56 | Size = ElementSize,
57 | XAssetPool = this,
58 | HeaderAddress = Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()),
59 | });
60 | }
61 |
62 | return results;
63 | }
64 |
65 | ///
66 | /// Exports the specified MapEnts XAsset.
67 | ///
68 | ///
69 | ///
70 | /// Status of the export operation.
71 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
72 | {
73 | MapEntsXAsset header = instance.Reader.ReadStruct(xasset.HeaderAddress);
74 |
75 | if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
76 | {
77 | return JekyllStatus.MemoryChanged;
78 | }
79 |
80 | string path = Path.Combine(instance.ExportPath, xasset.Name);
81 | Directory.CreateDirectory(Path.GetDirectoryName(path));
82 |
83 | File.WriteAllText(path, instance.Reader.ReadNullTerminatedString(header.EntityString));
84 |
85 | Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");
86 |
87 | return JekyllStatus.Success;
88 | }
89 | }
90 | }
91 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/BlackOps2/XAssets/RawFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace JekyllLibrary.Library
7 | {
8 | public partial class BlackOps2
9 | {
10 | public class RawFile : IXAssetPool
11 | {
12 | public override string Name => "Raw File";
13 |
14 | public override int Index => (int)XAssetType.ASSET_TYPE_RAWFILE;
15 |
16 | ///
17 | /// Structure of a Black Ops II RawFile XAsset.
18 | ///
19 | private struct RawFileXAsset
20 | {
21 | public uint Name { get; set; }
22 | public int Len { get; set; }
23 | public uint Buffer { get; set; }
24 | }
25 |
26 | ///
27 | /// Load the valid XAssets for the RawFile XAsset Pool.
28 | ///
29 | ///
30 | /// List of RawFile XAsset objects.
31 | public override List Load(JekyllInstance instance)
32 | {
33 | List results = new List();
34 |
35 | Entries = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Marshal.SizeOf() * Index));
36 | PoolSize = instance.Reader.ReadStruct(instance.Game.DBAssetPoolSizes + (Marshal.SizeOf() * Index));
37 |
38 | for (int i = 0; i < PoolSize; i++)
39 | {
40 | RawFileXAsset header = instance.Reader.ReadStruct(Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()));
41 |
42 | if (IsNullXAsset(header.Name))
43 | {
44 | continue;
45 | }
46 | else if (header.Len == 0)
47 | {
48 | continue;
49 | }
50 |
51 | results.Add(new GameXAsset()
52 | {
53 | Name = instance.Reader.ReadNullTerminatedString(header.Name),
54 | Type = Name,
55 | Size = ElementSize,
56 | XAssetPool = this,
57 | HeaderAddress = Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()),
58 | });
59 | }
60 |
61 | return results;
62 | }
63 |
64 | ///
65 | /// Exports the specified RawFile XAsset.
66 | ///
67 | ///
68 | ///
69 | /// Status of the export operation.
70 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
71 | {
72 | RawFileXAsset header = instance.Reader.ReadStruct(xasset.HeaderAddress);
73 |
74 | if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
75 | {
76 | return JekyllStatus.MemoryChanged;
77 | }
78 |
79 | string path = Path.Combine(instance.ExportPath, xasset.Name);
80 | Directory.CreateDirectory(Path.GetDirectoryName(path));
81 |
82 | byte[] buffer = instance.Reader.ReadBytes(header.Buffer, header.Len);
83 | File.WriteAllBytes(path, buffer);
84 |
85 | Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");
86 |
87 | return JekyllStatus.Success;
88 | }
89 | }
90 | }
91 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/BlackOps2/XAssets/ScriptFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace JekyllLibrary.Library
7 | {
8 | public partial class BlackOps2
9 | {
10 | public class ScriptFile : IXAssetPool
11 | {
12 | public override string Name => "Script File";
13 |
14 | public override int Index => (int)XAssetType.ASSET_TYPE_SCRIPTPARSETREE;
15 |
16 | ///
17 | /// Structure of a Black Ops II ScriptParseTree.
18 | ///
19 | private struct ScriptParseTree
20 | {
21 | public uint Name { get; set; }
22 | public int Len { get; set; }
23 | public uint Buffer { get; set; }
24 | }
25 |
26 | ///
27 | /// Load the valid XAssets for the ScriptFile XAsset Pool.
28 | ///
29 | ///
30 | /// List of ScriptFile XAsset objects.
31 | public override List Load(JekyllInstance instance)
32 | {
33 | List results = new List();
34 |
35 | Entries = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Marshal.SizeOf() * Index));
36 | PoolSize = instance.Reader.ReadStruct(instance.Game.DBAssetPoolSizes + (Marshal.SizeOf() * Index));
37 |
38 | for (int i = 0; i < PoolSize; i++)
39 | {
40 | ScriptParseTree header = instance.Reader.ReadStruct(Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()));
41 |
42 | if (IsNullXAsset(header.Name))
43 | {
44 | continue;
45 | }
46 | else if (header.Len == 0)
47 | {
48 | continue;
49 | }
50 |
51 | results.Add(new GameXAsset()
52 | {
53 | Name = instance.Reader.ReadNullTerminatedString(header.Name),
54 | Type = Name,
55 | Size = ElementSize,
56 | XAssetPool = this,
57 | HeaderAddress = Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()),
58 | });
59 | }
60 |
61 | return results;
62 | }
63 |
64 | ///
65 | /// Exports the specified ScriptFile XAsset.
66 | ///
67 | ///
68 | ///
69 | /// Status of the export operation.
70 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
71 | {
72 | ScriptParseTree header = instance.Reader.ReadStruct(xasset.HeaderAddress);
73 |
74 | if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
75 | {
76 | return JekyllStatus.MemoryChanged;
77 | }
78 |
79 | try
80 | {
81 | string path = Path.Combine(instance.ExportPath, xasset.Name);
82 | Directory.CreateDirectory(Path.GetDirectoryName(path));
83 |
84 | byte[] buffer = instance.Reader.ReadBytes(header.Buffer, header.Len);
85 | File.WriteAllBytes(path, buffer);
86 | }
87 | catch
88 | {
89 | return JekyllStatus.Exception;
90 | }
91 |
92 | Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");
93 |
94 | return JekyllStatus.Success;
95 | }
96 | }
97 | }
98 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/BlackOps3/XAssets/BinaryHTML.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace JekyllLibrary.Library
7 | {
8 | public partial class BlackOps3
9 | {
10 | public class BinaryHTML : IXAssetPool
11 | {
12 | public override string Name => "Binary HTML";
13 |
14 | public override int Index => (int)XAssetType.ASSET_TYPE_BINARYHTML;
15 |
16 | ///
17 | /// Structure of a Black Ops III BinaryHTML.
18 | ///
19 | private struct BinaryHTMLXAsset
20 | {
21 | public long Name { get; set; }
22 | public int Len { get; set; }
23 | public long Buffer { get; set; }
24 | }
25 |
26 | ///
27 | /// Load the valid XAssets for the BinaryHTML XAsset Pool.
28 | ///
29 | ///
30 | /// List of BinaryHTML XAsset objects.
31 | public override List Load(JekyllInstance instance)
32 | {
33 | List results = new List();
34 |
35 | XAssetPool pool = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Index * Marshal.SizeOf()));
36 |
37 | Entries = pool.Pool;
38 | ElementSize = pool.ItemSize;
39 | PoolSize = (uint)pool.ItemCount;
40 |
41 | if (IsValidPool(Name, ElementSize, Marshal.SizeOf()) == false)
42 | {
43 | return results;
44 | }
45 |
46 | for (int i = 0; i < PoolSize; i++)
47 | {
48 | BinaryHTMLXAsset header = instance.Reader.ReadStruct(Entries + (i * ElementSize));
49 |
50 | if (IsNullXAsset(header.Name))
51 | {
52 | continue;
53 | }
54 | else if (header.Len == 0)
55 | {
56 | continue;
57 | }
58 |
59 | results.Add(new GameXAsset()
60 | {
61 | Name = instance.Reader.ReadNullTerminatedString(header.Name),
62 | Type = Name,
63 | Size = ElementSize,
64 | XAssetPool = this,
65 | HeaderAddress = Entries + (i * ElementSize),
66 | });
67 | }
68 |
69 | return results;
70 | }
71 |
72 | ///
73 | /// Exports the specified BinaryHTML XAsset.
74 | ///
75 | ///
76 | ///
77 | /// Status of the export operation.
78 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
79 | {
80 | BinaryHTMLXAsset header = instance.Reader.ReadStruct(xasset.HeaderAddress);
81 |
82 | if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
83 | {
84 | return JekyllStatus.MemoryChanged;
85 | }
86 |
87 | string path = Path.Combine(instance.ExportPath, xasset.Name);
88 | Directory.CreateDirectory(Path.GetDirectoryName(path));
89 |
90 | byte[] buffer = instance.Reader.ReadBytes(header.Buffer, header.Len);
91 |
92 | File.WriteAllBytes(path, buffer);
93 |
94 | Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");
95 |
96 | return JekyllStatus.Success;
97 | }
98 | }
99 | }
100 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/BlackOps3/XAssets/Localize.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Runtime.InteropServices;
6 |
7 | namespace JekyllLibrary.Library
8 | {
9 | public partial class BlackOps3
10 | {
11 | public class Localize : IXAssetPool
12 | {
13 | public override string Name => "Localize Entry";
14 |
15 | public override int Index => (int)XAssetType.ASSET_TYPE_LOCALIZE_ENTRY;
16 |
17 | ///
18 | /// Structure of a Black Ops III LocalizeEntry.
19 | ///
20 | private struct LocalizeEntry
21 | {
22 | public long Value { get; set; }
23 | public long Name { get; set; }
24 | }
25 |
26 | ///
27 | /// Load the valid XAssets for the Localize XAsset Pool.
28 | ///
29 | ///
30 | /// List of Localize XAsset objects.
31 | public override List Load(JekyllInstance instance)
32 | {
33 | List results = new List();
34 |
35 | XAssetPool pool = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Index * Marshal.SizeOf()));
36 |
37 | Entries = pool.Pool;
38 | ElementSize = pool.ItemSize;
39 | PoolSize = (uint)pool.ItemCount;
40 |
41 | if (IsValidPool(Name, ElementSize, Marshal.SizeOf()) == false)
42 | {
43 | return results;
44 | }
45 |
46 | Dictionary entries = new Dictionary();
47 |
48 | for (int i = 0; i < PoolSize; i++)
49 | {
50 | LocalizeEntry header = instance.Reader.ReadStruct(Entries + (i * ElementSize));
51 |
52 | if (IsNullXAsset(header.Name))
53 | {
54 | continue;
55 | }
56 |
57 | string key = instance.Reader.ReadNullTerminatedString(header.Name).ToUpper();
58 |
59 | if (entries.TryGetValue(key, out string _))
60 | {
61 | continue;
62 | }
63 |
64 | string value = instance.Reader.ReadNullTerminatedString(header.Value, nullCheck:true);
65 | entries.Add(key, value);
66 |
67 | Console.WriteLine($"Exported {Name} {key}");
68 | }
69 |
70 | string path = Path.Combine(instance.ExportPath, "localize.json");
71 | Directory.CreateDirectory(Path.GetDirectoryName(path));
72 |
73 | using (StreamWriter file = File.CreateText(path))
74 | {
75 | file.Write(JsonConvert.SerializeObject(entries, Formatting.Indented));
76 | }
77 |
78 | return results;
79 | }
80 |
81 | ///
82 | /// Exports the specified Localize XAsset.
83 | ///
84 | ///
85 | ///
86 | /// Status of the export operation.
87 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
88 | {
89 | return JekyllStatus.Success;
90 | }
91 | }
92 | }
93 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/BlackOps3/XAssets/MapEnts.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace JekyllLibrary.Library
7 | {
8 | public partial class BlackOps3
9 | {
10 | public class MapEnts : IXAssetPool
11 | {
12 | public override string Name => "Map Entities";
13 |
14 | public override int Index => (int)XAssetType.ASSET_TYPE_MAP_ENTS;
15 |
16 | ///
17 | /// Structure of a Black Ops III MapEnts XAsset.
18 | ///
19 | private struct MapEntsXAsset
20 | {
21 | public long Name { get; set; }
22 | public long EntityString { get; set; }
23 | public int NumEntityChars { get; set; }
24 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
25 | public byte[] Trigger;
26 | }
27 |
28 | ///
29 | /// Load the valid XAssets for the MapEnts XAsset Pool.
30 | ///
31 | ///
32 | /// List of MapEnts XAsset objects.
33 | public override List Load(JekyllInstance instance)
34 | {
35 | List results = new List();
36 |
37 | XAssetPool pool = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Index * Marshal.SizeOf()));
38 |
39 | Entries = pool.Pool;
40 | ElementSize = pool.ItemSize;
41 | PoolSize = (uint)pool.ItemCount;
42 |
43 | if (IsValidPool(Name, ElementSize, Marshal.SizeOf()) == false)
44 | {
45 | return results;
46 | }
47 |
48 | for (int i = 0; i < PoolSize; i++)
49 | {
50 | MapEntsXAsset header = instance.Reader.ReadStruct(Entries + (i * ElementSize));
51 |
52 | if (IsNullXAsset(header.Name))
53 | {
54 | continue;
55 | }
56 |
57 | results.Add(new GameXAsset()
58 | {
59 | Name = instance.Reader.ReadNullTerminatedString(header.Name),
60 | Type = Name,
61 | Size = ElementSize,
62 | XAssetPool = this,
63 | HeaderAddress = Entries + (i * ElementSize),
64 | });
65 | }
66 |
67 | return results;
68 | }
69 |
70 | ///
71 | /// Exports the specified MapEnts XAsset.
72 | ///
73 | ///
74 | ///
75 | /// Status of the export operation.
76 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
77 | {
78 | MapEntsXAsset header = instance.Reader.ReadStruct(xasset.HeaderAddress);
79 |
80 | if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
81 | {
82 | return JekyllStatus.MemoryChanged;
83 | }
84 |
85 | string path = Path.Combine(instance.ExportPath, xasset.Name);
86 | Directory.CreateDirectory(Path.GetDirectoryName(path));
87 |
88 | File.WriteAllText(path, instance.Reader.ReadNullTerminatedString(header.EntityString));
89 |
90 | Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");
91 |
92 | return JekyllStatus.Success;
93 | }
94 | }
95 | }
96 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/BlackOps3/XAssets/RawFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace JekyllLibrary.Library
7 | {
8 | public partial class BlackOps3
9 | {
10 | public class RawFile : IXAssetPool
11 | {
12 | public override string Name => "Raw File";
13 |
14 | public override int Index => (int)XAssetType.ASSET_TYPE_RAWFILE;
15 |
16 | ///
17 | /// Structure of a Black Ops III RawFile XAsset.
18 | ///
19 | private struct RawFileXAsset
20 | {
21 | public long Name { get; set; }
22 | public int Len { get; set; }
23 | public long Buffer { get; set; }
24 | }
25 |
26 | ///
27 | /// Load the valid XAssets for the RawFile XAsset Pool.
28 | ///
29 | ///
30 | /// List of RawFile XAsset objects.
31 | public override List Load(JekyllInstance instance)
32 | {
33 | List results = new List();
34 |
35 | XAssetPool pool = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Index * Marshal.SizeOf()));
36 |
37 | Entries = pool.Pool;
38 | ElementSize = pool.ItemSize;
39 | PoolSize = (uint)pool.ItemCount;
40 |
41 | if (IsValidPool(Name, ElementSize, Marshal.SizeOf()) == false)
42 | {
43 | return results;
44 | }
45 |
46 | for (int i = 0; i < PoolSize; i++)
47 | {
48 | RawFileXAsset header = instance.Reader.ReadStruct(Entries + (i * ElementSize));
49 |
50 | if (IsNullXAsset(header.Name))
51 | {
52 | continue;
53 | }
54 | else if (header.Len == 0)
55 | {
56 | continue;
57 | }
58 |
59 | results.Add(new GameXAsset()
60 | {
61 | Name = instance.Reader.ReadNullTerminatedString(header.Name),
62 | Type = Name,
63 | Size = ElementSize,
64 | XAssetPool = this,
65 | HeaderAddress = Entries + (i * ElementSize),
66 | });
67 | }
68 |
69 | return results;
70 | }
71 |
72 | ///
73 | /// Exports the specified RawFile XAsset.
74 | ///
75 | ///
76 | ///
77 | /// Status of the export operation.
78 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
79 | {
80 | RawFileXAsset header = instance.Reader.ReadStruct(xasset.HeaderAddress);
81 |
82 | if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
83 | {
84 | return JekyllStatus.MemoryChanged;
85 | }
86 |
87 | string path = Path.Combine(instance.ExportPath, xasset.Name);
88 | Directory.CreateDirectory(Path.GetDirectoryName(path));
89 |
90 | byte[] buffer = instance.Reader.ReadBytes(header.Buffer, header.Len);
91 |
92 | File.WriteAllBytes(path, buffer);
93 |
94 | Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");
95 |
96 | return JekyllStatus.Success;
97 | }
98 | }
99 | }
100 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/BlackOps3/XAssets/ScriptFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace JekyllLibrary.Library
7 | {
8 | public partial class BlackOps3
9 | {
10 | public class ScriptFile : IXAssetPool
11 | {
12 | public override string Name => "Script File";
13 |
14 | public override int Index => (int)XAssetType.ASSET_TYPE_SCRIPTPARSETREE;
15 |
16 | ///
17 | /// Structure of a Black Ops III ScriptParseTree.
18 | ///
19 | private struct ScriptParseTree
20 | {
21 | public long Name { get; set; }
22 | public int Len { get; set; }
23 | public long Buffer { get; set; }
24 | }
25 |
26 | ///
27 | /// Load the valid XAssets for the ScriptParseTree XAsset Pool.
28 | ///
29 | ///
30 | /// List of ScriptParseTree XAsset objects.
31 | public override List Load(JekyllInstance instance)
32 | {
33 | List results = new List();
34 |
35 | XAssetPool pool = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Index * Marshal.SizeOf()));
36 |
37 | Entries = pool.Pool;
38 | ElementSize = pool.ItemSize;
39 | PoolSize = (uint)pool.ItemCount;
40 |
41 | if (IsValidPool(Name, ElementSize, Marshal.SizeOf()) == false)
42 | {
43 | return results;
44 | }
45 |
46 | for (int i = 0; i < PoolSize; i++)
47 | {
48 | ScriptParseTree header = instance.Reader.ReadStruct(Entries + (i * ElementSize));
49 |
50 | if (IsNullXAsset(header.Name))
51 | {
52 | continue;
53 | }
54 | else if (header.Len == 0)
55 | {
56 | continue;
57 | }
58 |
59 | results.Add(new GameXAsset()
60 | {
61 | Name = instance.Reader.ReadNullTerminatedString(header.Name),
62 | Type = Name,
63 | Size = ElementSize,
64 | XAssetPool = this,
65 | HeaderAddress = Entries + (i * ElementSize),
66 | });
67 | }
68 |
69 | return results;
70 | }
71 |
72 | ///
73 | /// Exports the specified ScriptParseTree XAsset.
74 | ///
75 | ///
76 | ///
77 | /// Status of the export operation.
78 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
79 | {
80 | ScriptParseTree header = instance.Reader.ReadStruct(xasset.HeaderAddress);
81 |
82 | if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
83 | {
84 | return JekyllStatus.MemoryChanged;
85 | }
86 |
87 | string path = Path.Combine(instance.ExportPath, xasset.Name);
88 | Directory.CreateDirectory(Path.GetDirectoryName(path));
89 |
90 | byte[] buffer = instance.Reader.ReadBytes(header.Buffer, header.Len);
91 |
92 | File.WriteAllBytes(path, buffer);
93 |
94 | Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");
95 |
96 | return JekyllStatus.Success;
97 | }
98 | }
99 | }
100 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/BlackOps3/XAssets/TTF.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace JekyllLibrary.Library
7 | {
8 | public partial class BlackOps3
9 | {
10 | public class TTF : IXAssetPool
11 | {
12 | public override string Name => "TrueType Font";
13 |
14 | public override int Index => (int)XAssetType.ASSET_TYPE_TTF;
15 |
16 | ///
17 | /// Structure of a Black Ops III TTFDef.
18 | ///
19 | private struct TTFDef
20 | {
21 | public long Name { get; set; }
22 | public int FileLen { get; set; }
23 | public long File { get; set; }
24 | public long FtFace { get; set; }
25 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 131072)]
26 | public byte[] KerningCache;
27 | }
28 |
29 | ///
30 | /// Load the valid XAssets for the TTF XAsset Pool.
31 | ///
32 | ///
33 | /// List of TTF XAsset objects.
34 | public override List Load(JekyllInstance instance)
35 | {
36 | List results = new List();
37 |
38 | XAssetPool pool = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Index * Marshal.SizeOf()));
39 |
40 | Entries = pool.Pool;
41 | ElementSize = pool.ItemSize;
42 | PoolSize = (uint)pool.ItemCount;
43 |
44 | if (IsValidPool(Name, ElementSize, Marshal.SizeOf()) == false)
45 | {
46 | return results;
47 | }
48 |
49 | for (int i = 0; i < PoolSize; i++)
50 | {
51 | TTFDef header = instance.Reader.ReadStruct(Entries + (i * ElementSize));
52 |
53 | if (IsNullXAsset(header.Name))
54 | {
55 | continue;
56 | }
57 | else if (header.FileLen == 0)
58 | {
59 | continue;
60 | }
61 |
62 | results.Add(new GameXAsset()
63 | {
64 | Name = instance.Reader.ReadNullTerminatedString(header.Name),
65 | Type = Name,
66 | Size = ElementSize,
67 | XAssetPool = this,
68 | HeaderAddress = Entries + (i * ElementSize),
69 | });
70 | }
71 |
72 | return results;
73 | }
74 |
75 | ///
76 | /// Exports the specified TTF XAsset.
77 | ///
78 | ///
79 | ///
80 | /// Status of the export operation.
81 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
82 | {
83 | TTFDef header = instance.Reader.ReadStruct(xasset.HeaderAddress);
84 |
85 | if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
86 | {
87 | return JekyllStatus.MemoryChanged;
88 | }
89 |
90 | string path = Path.Combine(instance.ExportPath, xasset.Name);
91 | Directory.CreateDirectory(Path.GetDirectoryName(path));
92 |
93 | byte[] buffer = instance.Reader.ReadBytes(header.File, header.FileLen);
94 |
95 | File.WriteAllBytes(path, buffer);
96 |
97 | Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");
98 |
99 | return JekyllStatus.Success;
100 | }
101 | }
102 | }
103 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/BlackOps4/XAssets/RawFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace JekyllLibrary.Library
7 | {
8 | public partial class BlackOps4
9 | {
10 | public class RawFile : IXAssetPool
11 | {
12 | public override string Name => "Raw File";
13 |
14 | public override int Index => (int)XAssetType.rawfile;
15 |
16 | ///
17 | /// Structure of a Black Ops 4 RawFile XAsset.
18 | ///
19 | private struct RawFileXAsset
20 | {
21 | public long Name { get; set; }
22 | public long NullPadding1 { get; set; }
23 | public int Len { get; set; }
24 | public int CompressedLen { get; set; }
25 | public long Buffer { get; set; }
26 | }
27 |
28 | ///
29 | /// Load the valid XAssets for the RawFile XAsset Pool.
30 | ///
31 | ///
32 | /// List of RawFile XAsset objects.
33 | public override List Load(JekyllInstance instance)
34 | {
35 | List results = new List();
36 |
37 | DBAssetPool pool = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Index * Marshal.SizeOf()));
38 |
39 | Entries = pool.Entries;
40 | ElementSize = pool.ElementSize;
41 | PoolSize = pool.PoolSize;
42 |
43 | if (IsValidPool(Name, ElementSize, Marshal.SizeOf()) == false)
44 | {
45 | return results;
46 | }
47 |
48 | for (int i = 0; i < PoolSize; i++)
49 | {
50 | RawFileXAsset header = instance.Reader.ReadStruct(Entries + (i * ElementSize));
51 |
52 | if (header.Len == 0)
53 | {
54 | continue;
55 | }
56 |
57 | results.Add(new GameXAsset()
58 | {
59 | Name = instance.Reader.ReadBytesToString(Entries + (i * ElementSize)).ToLower(),
60 | Type = Name,
61 | Size = ElementSize,
62 | XAssetPool = this,
63 | HeaderAddress = Entries + (i * Marshal.SizeOf()),
64 | });
65 | }
66 |
67 | return results;
68 | }
69 |
70 | ///
71 | /// Exports the specified RawFile XAsset.
72 | ///
73 | ///
74 | ///
75 | /// Status of the export operation.
76 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
77 | {
78 | RawFileXAsset header = instance.Reader.ReadStruct(xasset.HeaderAddress);
79 |
80 | string path = Path.Combine(instance.ExportPath, "rawfile/" + xasset.Name);
81 | Directory.CreateDirectory(Path.GetDirectoryName(path));
82 |
83 | byte[] buffer = instance.Reader.ReadBytes(header.Buffer, header.Len);
84 |
85 | File.WriteAllBytes(path, buffer);
86 |
87 | Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");
88 |
89 | return JekyllStatus.Success;
90 | }
91 | }
92 | }
93 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/Ghosts/XAssets/Localize.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Runtime.InteropServices;
6 |
7 | namespace JekyllLibrary.Library
8 | {
9 | public partial class Ghosts
10 | {
11 | public class Localize : IXAssetPool
12 | {
13 | public override string Name => "Localize Entry";
14 |
15 | public override int Index => (int)XAssetType.ASSET_TYPE_LOCALIZE_ENTRY;
16 |
17 | ///
18 | /// Structure of a Ghosts LocalizeEntry.
19 | ///
20 | private struct LocalizeEntry
21 | {
22 | public long Value { get; set; }
23 | public long Name { get; set; }
24 | }
25 |
26 | ///
27 | /// Load the valid XAssets for the Localize XAsset Pool.
28 | ///
29 | ///
30 | /// List of Localize XAsset objects.
31 | public override List Load(JekyllInstance instance)
32 | {
33 | List results = new List();
34 |
35 | Entries = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Marshal.SizeOf() * Index));
36 | PoolSize = instance.Reader.ReadStruct(instance.Game.DBAssetPoolSizes + (Marshal.SizeOf() * Index));
37 |
38 | Dictionary entries = new Dictionary();
39 |
40 | for (int i = 0; i < PoolSize; i++)
41 | {
42 | LocalizeEntry header = instance.Reader.ReadStruct(Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()));
43 |
44 | if (IsNullXAsset(header.Name))
45 | {
46 | continue;
47 | }
48 |
49 | string key = instance.Reader.ReadNullTerminatedString(header.Name).ToUpper();
50 |
51 | if (entries.TryGetValue(key, out string _))
52 | {
53 | continue;
54 | }
55 |
56 | entries.Add(key, instance.Reader.ReadNullTerminatedString(header.Value, nullCheck: true));
57 |
58 | Console.WriteLine($"Exported {Name} {key}");
59 | }
60 |
61 | string path = Path.Combine(instance.ExportPath, "localize.json");
62 | Directory.CreateDirectory(Path.GetDirectoryName(path));
63 |
64 | using (StreamWriter file = File.CreateText(path))
65 | {
66 | file.Write(JsonConvert.SerializeObject(entries, Formatting.Indented));
67 | }
68 |
69 | return results;
70 | }
71 |
72 | ///
73 | /// Exports the specified Localize XAsset.
74 | ///
75 | ///
76 | ///
77 | /// Status of the export operation.
78 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
79 | {
80 | return JekyllStatus.Success;
81 | }
82 | }
83 | }
84 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/Ghosts/XAssets/LuaFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace JekyllLibrary.Library
7 | {
8 | public partial class Ghosts
9 | {
10 | public class LuaFile : IXAssetPool
11 | {
12 | public override string Name => "Lua File";
13 |
14 | public override int Index => (int)XAssetType.ASSET_TYPE_LUA_FILE;
15 |
16 | ///
17 | /// Structure of a Ghosts LuaFile XAsset.
18 | ///
19 | private struct LuaFileXAsset
20 | {
21 | public long Name { get; set; }
22 | public int Len { get; set; }
23 | public byte StrippingType { get; set; }
24 | public long Buffer { get; set; }
25 | }
26 |
27 | ///
28 | /// Load the valid XAssets for the LuaFile XAsset Pool.
29 | ///
30 | ///
31 | /// List of LuaFile XAsset objects.
32 | public override List Load(JekyllInstance instance)
33 | {
34 | List results = new List();
35 |
36 | Entries = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Marshal.SizeOf() * Index));
37 | PoolSize = instance.Reader.ReadStruct(instance.Game.DBAssetPoolSizes + (Marshal.SizeOf() * Index));
38 |
39 | for (int i = 0; i < PoolSize; i++)
40 | {
41 | LuaFileXAsset header = instance.Reader.ReadStruct(Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()));
42 |
43 | if (IsNullXAsset(header.Name))
44 | {
45 | continue;
46 | }
47 | else if (header.Len == 0)
48 | {
49 | continue;
50 | }
51 |
52 | results.Add(new GameXAsset()
53 | {
54 | Name = instance.Reader.ReadNullTerminatedString(header.Name),
55 | Type = Name,
56 | Size = ElementSize,
57 | XAssetPool = this,
58 | HeaderAddress = Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()),
59 | });
60 | }
61 |
62 | return results;
63 | }
64 |
65 | ///
66 | /// Exports the specified LuaFile XAsset.
67 | ///
68 | ///
69 | ///
70 | /// Status of the export operation.
71 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
72 | {
73 | LuaFileXAsset header = instance.Reader.ReadStruct(xasset.HeaderAddress);
74 |
75 | if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
76 | {
77 | return JekyllStatus.MemoryChanged;
78 | }
79 |
80 | string path = Path.Combine(instance.ExportPath, xasset.Name);
81 | Directory.CreateDirectory(Path.GetDirectoryName(path));
82 |
83 | byte[] buffer = instance.Reader.ReadBytes(header.Buffer, header.Len);
84 | File.WriteAllBytes(path, buffer);
85 |
86 | Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");
87 |
88 | return JekyllStatus.Success;
89 | }
90 | }
91 | }
92 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/Ghosts/XAssets/MapEnts.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace JekyllLibrary.Library
7 | {
8 | public partial class Ghosts
9 | {
10 | public class MapEnts : IXAssetPool
11 | {
12 | public override string Name => "Map Entities";
13 |
14 | public override int Index => (int)XAssetType.ASSET_TYPE_MAP_ENTS;
15 |
16 | ///
17 | /// Structure of a Ghosts MapEnts XAsset.
18 | ///
19 | private struct MapEntsXAsset
20 | {
21 | public long Name { get; set; }
22 | public long EntityString { get; set; }
23 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 236)]
24 | public byte[] Unused;
25 | }
26 |
27 | ///
28 | /// Load the valid XAssets for the MapEnts XAsset Pool.
29 | ///
30 | ///
31 | /// List of MapEnts XAsset objects.
32 | public override List Load(JekyllInstance instance)
33 | {
34 | List results = new List();
35 |
36 | Entries = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Marshal.SizeOf() * Index));
37 | PoolSize = instance.Reader.ReadStruct(instance.Game.DBAssetPoolSizes + (Marshal.SizeOf() * Index));
38 |
39 | for (int i = 0; i < PoolSize; i++)
40 | {
41 | MapEntsXAsset header = instance.Reader.ReadStruct(Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()));
42 |
43 | if (IsNullXAsset(header.Name))
44 | {
45 | continue;
46 | }
47 | else if (instance.Reader.ReadNullTerminatedString(header.Name).EndsWith(".d3dbsp") is false)
48 | {
49 | continue;
50 | }
51 |
52 | results.Add(new GameXAsset()
53 | {
54 | Name = instance.Reader.ReadNullTerminatedString(header.Name),
55 | Type = Name,
56 | Size = ElementSize,
57 | XAssetPool = this,
58 | HeaderAddress = Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()),
59 | });
60 | }
61 |
62 | return results;
63 | }
64 |
65 | ///
66 | /// Exports the specified MapEnts XAsset.
67 | ///
68 | ///
69 | ///
70 | /// Status of the export operation.
71 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
72 | {
73 | MapEntsXAsset header = instance.Reader.ReadStruct(xasset.HeaderAddress);
74 |
75 | if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
76 | {
77 | return JekyllStatus.MemoryChanged;
78 | }
79 |
80 | string path = Path.Combine(instance.ExportPath, xasset.Name);
81 | Directory.CreateDirectory(Path.GetDirectoryName(path));
82 |
83 | File.WriteAllText(path, instance.Reader.ReadNullTerminatedString(header.EntityString));
84 |
85 | Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");
86 |
87 | return JekyllStatus.Success;
88 | }
89 | }
90 | }
91 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/Ghosts/XAssets/RawFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.IO.Compression;
5 | using System.Runtime.InteropServices;
6 |
7 | namespace JekyllLibrary.Library
8 | {
9 | public partial class Ghosts
10 | {
11 | public class RawFile : IXAssetPool
12 | {
13 | public override string Name => "Raw File";
14 |
15 | public override int Index => (int)XAssetType.ASSET_TYPE_RAWFILE;
16 |
17 | ///
18 | /// Structure of a Ghosts RawFile XAsset.
19 | ///
20 | private struct RawFileXAsset
21 | {
22 | public long Name { get; set; }
23 | public int CompressedLen { get; set; }
24 | public int Len { get; set; }
25 | public long Buffer { get; set; }
26 | }
27 |
28 | ///
29 | /// Load the valid XAssets for the RawFile XAsset Pool.
30 | ///
31 | ///
32 | /// List of RawFile XAsset objects.
33 | public override List Load(JekyllInstance instance)
34 | {
35 | List results = new List();
36 |
37 | Entries = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Marshal.SizeOf() * Index));
38 | PoolSize = instance.Reader.ReadStruct(instance.Game.DBAssetPoolSizes + (Marshal.SizeOf() * Index));
39 |
40 | for (int i = 0; i < PoolSize; i++)
41 | {
42 | RawFileXAsset header = instance.Reader.ReadStruct(Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()));
43 |
44 | if (IsNullXAsset(header.Name))
45 | {
46 | continue;
47 | }
48 | else if (header.Len == 0)
49 | {
50 | continue;
51 | }
52 |
53 | results.Add(new GameXAsset()
54 | {
55 | Name = instance.Reader.ReadNullTerminatedString(header.Name),
56 | Type = Name,
57 | Size = ElementSize,
58 | XAssetPool = this,
59 | HeaderAddress = Entries + Marshal.SizeOf() + (i * Marshal.SizeOf()),
60 | });
61 | }
62 |
63 | return results;
64 | }
65 |
66 | ///
67 | /// Exports the specified RawFile XAsset.
68 | ///
69 | ///
70 | ///
71 | /// Status of the export operation.
72 | public override JekyllStatus Export(GameXAsset xasset, JekyllInstance instance)
73 | {
74 | RawFileXAsset header = instance.Reader.ReadStruct(xasset.HeaderAddress);
75 |
76 | if (xasset.Name != instance.Reader.ReadNullTerminatedString(header.Name))
77 | {
78 | return JekyllStatus.MemoryChanged;
79 | }
80 |
81 | try
82 | {
83 | string path = Path.Combine(instance.ExportPath, xasset.Name);
84 | Directory.CreateDirectory(Path.GetDirectoryName(path));
85 |
86 | MemoryStream DecodedCodeStream = Decode(instance.Reader.ReadBytes(header.Buffer + 2, header.CompressedLen - 2));
87 |
88 | using FileStream outputStream = new FileStream(path, FileMode.Create);
89 | DecodedCodeStream.CopyTo(outputStream);
90 | }
91 | catch
92 | {
93 | return JekyllStatus.Exception;
94 | }
95 |
96 | Console.WriteLine($"Exported {xasset.Type} {xasset.Name}");
97 |
98 | return JekyllStatus.Success;
99 | }
100 |
101 | ///
102 | /// Decompress the specified array of bytes.
103 | ///
104 | ///
105 | ///
106 | public static MemoryStream Decode(byte[] data)
107 | {
108 | MemoryStream output = new MemoryStream();
109 | MemoryStream input = new MemoryStream(data);
110 |
111 | using (DeflateStream deflateStream = new DeflateStream(input, CompressionMode.Decompress))
112 | {
113 | deflateStream.CopyTo(output);
114 | }
115 |
116 | output.Flush();
117 | output.Position = 0;
118 |
119 | return output;
120 | }
121 | }
122 | }
123 | }
--------------------------------------------------------------------------------
/Jekyll.Library/Game/InfiniteWarfare/XAssets/Localize.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Runtime.InteropServices;
6 |
7 | namespace JekyllLibrary.Library
8 | {
9 | public partial class InfiniteWarfare
10 | {
11 | public class Localize : IXAssetPool
12 | {
13 | public override string Name => "Localize Entry";
14 |
15 | public override int Index => (int)XAssetType.localize;
16 |
17 | ///
18 | /// Structure of an Infinite Warfare LocalizeEntry.
19 | ///
20 | private struct LocalizeEntry
21 | {
22 | public long Value { get; set; }
23 | public long Name { get; set; }
24 | }
25 |
26 | ///
27 | /// Load the valid XAssets for the Localize XAsset Pool.
28 | ///
29 | ///
30 | /// List of Localize XAsset objects.
31 | public override List Load(JekyllInstance instance)
32 | {
33 | Entries = instance.Reader.ReadStruct(instance.Game.DBAssetPools + (Marshal.SizeOf() * Index));
34 | PoolSize = instance.Reader.ReadStruct(instance.Game.DBAssetPoolSizes + (Marshal.SizeOf() * Index));
35 |
36 | Dictionary entries = new Dictionary();
37 |
38 | for (int i = 0; i < PoolSize; i++)
39 | {
40 | LocalizeEntry header = instance.Reader.ReadStruct(Entries + Marshal.SizeOf