1+ #include < includes.hpp>
2+ #include < tools/fastfile/handlers/bo4/bo4_unlinker_map.hpp>
3+ #include < tools/fastfile/handlers/bo4/bo4_unlinker_scriptbundle.hpp>
4+ #include < core/hashes/raw_file_extractor.hpp>
5+ #include < tools/utils/data_utils.hpp>
6+
7+ namespace fastfile ::handlers::bo4::map {
8+ using namespace games ::bo4::pool;
9+
10+ struct ScriptBundleList ;
11+ struct ObjectiveList ;
12+
13+ struct MapTableEntry {
14+ const char * nameStr;
15+ XHash name;
16+ int size;
17+ XHash mapName;
18+ XHash rootMapName;
19+ const char * missionName;
20+ XHash mapDescription;
21+ XHash unk58;
22+ uint64_t unk68;
23+ XHash location;
24+ XHash unk80;
25+ XHash presence;
26+ XHash unka0;
27+ XHash previewImage;
28+ XHash loadScreen;
29+ XHash unkd0;
30+ GfxImage* unke0;
31+ GfxImage* unke8;
32+ const char * loadingmovie;
33+ uint64_t unkf8;
34+ ObjectiveList* objectiveList;
35+ const char * unk108;
36+ ScriptBundleList* bundleList;
37+ XHash unk118;
38+ uint64_t unk128;
39+ uint64_t unk130;
40+ const char * unk138;
41+ GfxImage* unk140;
42+ uint32_t playerRoleTemplatesCount;
43+ PlayerRoleTemplate** playerRoleTemplates;
44+ uint64_t unk158;
45+ uint32_t unk160;
46+ uint32_t unk164;
47+ XHash unk168;
48+ scriptbundle::SB_ObjectsArray bundle;
49+ uint64_t uniqueID;
50+ };
51+ static_assert (sizeof (MapTableEntry) == 0x1A0 );
52+
53+ struct MapTable {
54+ XHash name;
55+ uint32_t mapCount;
56+ MapTableEntry* maps;
57+ eModes sessionMode;
58+ uint32_t campaignMode;
59+ int32_t dlcIndex;
60+ };
61+ static_assert (sizeof (MapTable) == 0x30 );
62+
63+ struct MapTableListElem {
64+ uint64_t mapsCount;
65+ XHash* maps;
66+ uint64_t devMapsCount;
67+ XHash* devMaps;
68+ };
69+
70+ struct MapTableList {
71+ XHash name;
72+ MapTableListElem cp;
73+ MapTableListElem mp;
74+ MapTableListElem zm;
75+ MapTableListElem wz;
76+ };
77+
78+ struct MapTableLoadingImages {
79+ XHash name;
80+ uint64_t imageCount;
81+ GfxImage** images;
82+ uint64_t mapCount;
83+ };
84+ static_assert (sizeof (MapTableLoadingImages) == 0x28 );
85+
86+ struct MapTablePreviewImages {
87+ XHash name;
88+ uint64_t imageCount;
89+ GfxImage** images;
90+ uint64_t mapCount;
91+ };
92+ static_assert (sizeof (MapTablePreviewImages) == 0x28 );
93+
94+ class MapTableWorker : public Worker {
95+ void Unlink (fastfile::FastFileOption& opt, void * ptr) override {
96+ MapTable& asset{ *(MapTable*)ptr };
97+
98+
99+ BO4JsonWriter json{};
100+
101+ json.BeginObject ();
102+ json.WriteFieldValueXHash (" name" , asset.name );
103+ json.WriteFieldValueString (" sessionMode" , GetEModeName (asset.sessionMode ));
104+ if (asset.dlcIndex ) json.WriteFieldValueNumber (" dlcIndex" , asset.dlcIndex );
105+ if (asset.campaignMode ) json.WriteFieldValueNumber (" campaignMode" , asset.campaignMode );
106+
107+ if (asset.maps ) {
108+ json.WriteFieldNameString (" maps" );
109+ json.BeginArray ();
110+
111+ for (size_t i = 0 ; i < asset.mapCount ; i++) {
112+ MapTableEntry& e{ asset.maps [i] };
113+
114+ json.BeginObject ();
115+ json.WriteFieldValueNumber (" uniqueID" , e.uniqueID );
116+ json.WriteFieldValueXString (" name" , e.nameStr );
117+ json.WriteFieldValueXHash (" hashname" , e.name );
118+ json.WriteFieldValueXString (" missionName" , e.missionName );
119+ json.WriteFieldValueXString (" loadingmovie" , e.loadingmovie );
120+ json.WriteFieldValueXHash (" mapName" , e.mapName );
121+ json.WriteFieldValueXHash (" rootMapName" , e.rootMapName );
122+ json.WriteFieldValueXHash (" mapDescription" , e.mapDescription );
123+ json.WriteFieldValueXHash (" unk58" , e.unk58 );
124+ json.WriteFieldValueXHash (" location" , e.location );
125+ json.WriteFieldValueXHash (" unk80" , e.unk80 );
126+ json.WriteFieldValueXHash (" presence" , e.presence );
127+ json.WriteFieldValueXHash (" unka0" , e.unka0 );
128+ json.WriteFieldValueXHash (" previewImage" , e.previewImage );
129+ json.WriteFieldValueXHash (" loadScreen" , e.loadScreen );
130+ json.WriteFieldValueXHash (" unkd0" , e.unkd0 );
131+ json.WriteFieldValueXHash (" unk118" , e.unk118 );
132+ json.WriteFieldValueXHash (" unk168" , e.unk168 );
133+ json.WriteFieldValueXAsset (" e:unke0" , XAssetType::ASSET_TYPE_IMAGE, e.unke0 );
134+ json.WriteFieldValueXAsset (" e:unke8" , XAssetType::ASSET_TYPE_IMAGE, e.unke8 );
135+ json.WriteFieldValueXAsset (" e:unk140" , XAssetType::ASSET_TYPE_IMAGE, e.unk140 );
136+ if (e.unk164 ) json.WriteFieldValueNumber (" e:unk164" , e.unk164 );
137+ json.WriteFieldValueXAsset (" bundleList" , XAssetType::ASSET_TYPE_SCRIPTBUNDLELIST, e.bundleList );
138+ json.WriteFieldValueXAsset (" objectiveList" , XAssetType::ASSET_TYPE_OBJECTIVE_LIST, e.objectiveList );
139+ json.WriteFieldValueXAssetArray (" playerRoleTemplates" , XAssetType::ASSET_TYPE_PLAYER_ROLE_TEMPLATE, e.playerRoleTemplatesCount , e.playerRoleTemplates );
140+ json.WriteFieldValueNumber (" size" , e.size );
141+
142+ scriptbundle::WriteObject (json, " bundle" , e.bundle );
143+
144+ json.WriteFieldValueUnknown (" e:unk68" , e.unk68 );
145+ json.WriteFieldValueUnknown (" e:unkf8" , e.unkf8 );
146+ json.WriteFieldValueUnknown (" e:unk108" , e.unk108 );
147+ json.WriteFieldValueUnknown (" e:unk128" , e.unk128 );
148+ json.WriteFieldValueUnknown (" e:unk130" , e.unk130 );
149+ json.WriteFieldValueUnknown (" e:unk138" , e.unk138 );
150+ json.WriteFieldValueUnknown (" e:unk158" , e.unk158 );
151+ json.WriteFieldValueUnknown (" e:unk160" , e.unk160 );
152+ json.EndObject ();
153+ }
154+
155+ json.EndArray ();
156+ }
157+
158+ json.EndObject ();
159+
160+
161+ std::filesystem::path outFile{ opt.m_output / " bo4" / " source" / " tables" / " map" / std::format (" {}.json" , hashutils::ExtractTmp (" file" , asset.name )) };
162+
163+ std::filesystem::create_directories (outFile.parent_path ());
164+ LOG_OPT_INFO (" Dump map table {}" , outFile.string ());
165+
166+ if (!json.WriteToFile (outFile)) {
167+ LOG_ERROR (" Error when dumping {}" , outFile.string ());
168+ }
169+ }
170+ };
171+ class MapTablListWorker : public Worker {
172+ void Unlink (fastfile::FastFileOption& opt, void * ptr) override {
173+ MapTableList& asset{ *(MapTableList*)ptr };
174+
175+
176+ BO4JsonWriter json{};
177+
178+ json.BeginObject ();
179+ json.WriteFieldValueXHash (" name" , asset.name );
180+
181+ auto WriteList = [&json](MapTableListElem& elem, const char * id) {
182+ if (!(elem.maps || elem.devMaps )) return ;
183+ json.WriteFieldNameString (id);
184+ json.BeginObject ();
185+ if (elem.maps ) {
186+ json.WriteFieldNameString (" maps" );
187+ json.BeginArray ();
188+ for (size_t i = 0 ; i < elem.mapsCount ; i++) {
189+ json.WriteValueHash (elem.maps [i]);
190+ }
191+ json.EndArray ();
192+ }
193+ if (elem.devMaps ) {
194+ json.WriteFieldNameString (" devMaps" );
195+ json.BeginArray ();
196+ for (size_t i = 0 ; i < elem.devMapsCount ; i++) {
197+ json.WriteValueHash (elem.devMaps [i]);
198+ }
199+ json.EndArray ();
200+ }
201+ json.EndObject ();
202+ };
203+
204+ WriteList (asset.cp , " cp" );
205+ WriteList (asset.mp , " mp" );
206+ WriteList (asset.zm , " zm" );
207+ WriteList (asset.wz , " wz" );
208+
209+ json.EndObject ();
210+
211+
212+ std::filesystem::path outFile{ opt.m_output / " bo4" / " source" / " tables" / " map" / " list" / std::format (" {}.json" , hashutils::ExtractTmp (" file" , asset.name )) };
213+
214+ std::filesystem::create_directories (outFile.parent_path ());
215+ LOG_OPT_INFO (" Dump map table list {}" , outFile.string ());
216+
217+ if (!json.WriteToFile (outFile)) {
218+ LOG_ERROR (" Error when dumping {}" , outFile.string ());
219+ }
220+ }
221+ };
222+
223+ class MapTableImagesWorker : public Worker {
224+ const char * type;
225+ public:
226+ MapTableImagesWorker (const char * type) : type(type) {}
227+
228+ void Unlink (fastfile::FastFileOption& opt, void * ptr) override {
229+ MapTablePreviewImages& asset{ *(MapTablePreviewImages*)ptr };
230+
231+
232+ BO4JsonWriter json{};
233+
234+ json.BeginObject ();
235+ json.WriteFieldValueXHash (" name" , asset.name );
236+ json.WriteFieldValueNumber (" mapCount" , asset.mapCount );
237+ json.WriteFieldValueXAssetArray (" images" , XAssetType::ASSET_TYPE_IMAGE, asset.imageCount , asset.images );
238+ json.EndObject ();
239+
240+
241+ std::filesystem::path outFile{ opt.m_output / " bo4" / " source" / " tables" / " map" / type / std::format (" {}.json" , hashutils::ExtractTmp (" file" , asset.name )) };
242+
243+ std::filesystem::create_directories (outFile.parent_path ());
244+ LOG_OPT_INFO (" Dump map table {} {}" , type, outFile.string ());
245+
246+ if (!json.WriteToFile (outFile)) {
247+ LOG_ERROR (" Error when dumping {}" , outFile.string ());
248+ }
249+ }
250+ };
251+
252+ utils::MapAdder<MapTableWorker, games::bo4::pool::XAssetType, Worker> impltable{ GetWorkers (), games::bo4::pool::XAssetType::ASSET_TYPE_MAPTABLE };
253+ utils::MapAdder<MapTablListWorker, games::bo4::pool::XAssetType, Worker> impltablelist{ GetWorkers (), games::bo4::pool::XAssetType::ASSET_TYPE_MAPTABLE_LIST };
254+ utils::MapAdder<MapTableImagesWorker, games::bo4::pool::XAssetType, Worker> implimgl{ GetWorkers (), games::bo4::pool::XAssetType::ASSET_TYPE_MAPTABLE_LOADING_IMAGES, " loadingimages" };
255+ utils::MapAdder<MapTableImagesWorker, games::bo4::pool::XAssetType, Worker> implimgp{ GetWorkers (), games::bo4::pool::XAssetType::ASSET_TYPE_MAPTABLE_PREVIEW_IMAGES, " previewimages" };
256+ }
0 commit comments