2222#include < Utilities/Macro.h>
2323#include < Spawner/Spawner.h>
2424
25+ #include < HouseClass.h>
26+ #include < AnimClass.h>
27+
2528#include < filesystem>
29+ #include < optional>
2630
2731namespace SavedGames
2832{
@@ -162,8 +166,6 @@ DEFINE_HOOK(0x67FD26, LoadOptionsClass_ReadSaveInfo_SGInSubdir, 0x5)
162166 return 0 ;
163167}
164168
165- #include < HouseClass.h>
166- #include < AnimClass.h>
167169
168170namespace SavedGames
169171{
@@ -177,6 +179,11 @@ namespace SavedGames
177179 {
178180 }
179181
182+ operator uint64_t () const
183+ {
184+ return Number;
185+ }
186+
180187 CampaignID (noinit_t ()) { }
181188 };
182189
@@ -224,12 +231,12 @@ namespace SavedGames
224231 return ret;
225232 }
226233
227- /*
234+
228235 template <typename T>
229- bool ReadFromStorage(IStorage* pStorage, const OLECHAR* name)
236+ std::optional<T> ReadFromStorage (IStorage* pStorage, const OLECHAR* name)
230237 {
231238 IStream* pStream = nullptr ;
232- bool ret = false;
239+ bool hasValue = false ;
233240 HRESULT hr = pStorage->OpenStream (
234241 name,
235242 NULL ,
@@ -238,18 +245,20 @@ namespace SavedGames
238245 &pStream
239246 );
240247
248+ T info;
249+
241250 if (SUCCEEDED (hr) && pStream != nullptr )
242251 {
243- T info;
244252 ULONG read = 0 ;
245253 hr = pStream->Read (&info, sizeof (info), &read);
246- ret = SUCCEEDED(hr) && read == sizeof(info);
254+ hasValue = SUCCEEDED (hr) && read == sizeof (info);
255+
247256 pStream->Release ();
248257 }
249258
250- return ret ;
259+ return hasValue ? std::make_optional (info) : std:: nullopt ;
251260 }
252- */
261+
253262}
254263
255264// Write : A la fin
@@ -268,5 +277,38 @@ DEFINE_HOOK(0x67D2E3, GameSave_AdditionalInfoForClient, 0x6)
268277
269278 return 0 ;
270279}
271- // Read : TODO
280+
281+ // Read : Au debut
282+ DEFINE_HOOK (0x67E4DC , LoadGame_AdditionalInfoForClient, 0x7 )
283+ {
284+ LEA_STACK (const wchar_t *, filename, STACK_OFFSET (0x518 , -0x4F4 ));
285+ IStorage* pStorage = nullptr ;
286+ using namespace SavedGames ;
287+
288+ if (SUCCEEDED (StgOpenStorage (filename,NULL ,
289+ STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
290+ 0 ,0 ,&pStorage)
291+ ))
292+ {
293+ if (auto id = ReadFromStorage<CampaignID>(pStorage, L" Campaign ID" ))
294+ {
295+ uint64_t num = id.value ().Number ;
296+ Debug::Log (" [Spawner] sav file CampaignID = %d\n " , num);
297+ Spawner::GetConfig ()->CampaignID = num;
298+ }
299+ if (auto info = ReadFromStorage<ExtraMetaInfo>(pStorage, L" Spawner extra info" ))
300+ {
301+ Debug::Log (" [Spawner] CurrentFrame = %d, TechnoCount = %d, AnimCount = %d \n "
302+ , info.value ().CurrentFrame
303+ , info.value ().TechnoCount
304+ , info.value ().AnimCount
305+ );
306+ }
307+ }
308+ if (pStorage)
309+ pStorage->Release ();
310+
311+ return 0 ;
312+ }
313+ // TODO : Refresh on starting next mission
272314// TODO : the requirement and solution on the client side needs better formulation
0 commit comments