1+ #include " GameTypes/UE/Core/IO/IoStore.h"
2+
3+ #include " IO/Archive/IStreamArchive.h"
4+ #include " Utils/VectorUtils.h"
5+
6+ void SatisfactorySave::FIoStoreTocHeader::serialize (Archive& ar) {
7+ ar << TocMagic;
8+ ar << Version;
9+ ar << Reserved0;
10+ ar << Reserved1;
11+ ar << TocHeaderSize;
12+ ar << TocEntryCount;
13+ ar << TocCompressedBlockEntryCount;
14+ ar << TocCompressedBlockEntrySize;
15+ ar << CompressionMethodNameCount;
16+ ar << CompressionMethodNameLength;
17+ ar << CompressionBlockSize;
18+ ar << DirectoryIndexSize;
19+ ar << PartitionCount;
20+ ar << ContainerId;
21+ ar << EncryptionKeyGuid;
22+ ar << ContainerFlags;
23+ ar << Reserved3;
24+ ar << Reserved4;
25+ ar << TocChunkPerfectHashSeedsCount;
26+ ar << PartitionSize;
27+ ar << TocChunksWithoutPerfectHashCount;
28+ ar << Reserved7;
29+ ar << Reserved8;
30+ }
31+
32+ void SatisfactorySave::FIoStoreTocResource::serialize (Archive& ar) {
33+ if (!ar.isIArchive ()) {
34+ throw std::runtime_error (" Only IStreamArchive support implemented!" );
35+ }
36+ auto & inAr = dynamic_cast <IStreamArchive&>(ar);
37+
38+ // https://github.com/EpicGames/UnrealEngine/blob/5.3.2-release/Engine/Source/Runtime/Core/Private/IO/IoStore.cpp#L2917
39+
40+ inAr << Header;
41+ if (!Header.CheckMagic ()) {
42+ throw std::runtime_error (" Bad IoStore magic!" );
43+ }
44+ if (Header.Version != 5 ) {
45+ throw std::runtime_error (" Bad IoStore header version!" );
46+ }
47+ if (Header.TocHeaderSize != sizeof (FIoStoreTocHeader)) {
48+ throw std::runtime_error (" Bad IoStore header size!" );
49+ }
50+
51+ ChunkIds.resize (Header.TocEntryCount );
52+ inAr.serializeRaw (ChunkIds.data (), vector_bin_size (ChunkIds));
53+
54+ ChunkOffsetLengths.resize (Header.TocEntryCount );
55+ inAr.serializeRaw (ChunkOffsetLengths.data (), vector_bin_size (ChunkOffsetLengths));
56+
57+ ChunkPerfectHashSeeds.resize (Header.TocChunkPerfectHashSeedsCount );
58+ inAr.serializeRaw (ChunkPerfectHashSeeds.data (), vector_bin_size (ChunkPerfectHashSeeds));
59+
60+ ChunkIndicesWithoutPerfectHash.resize (Header.TocChunksWithoutPerfectHashCount );
61+ inAr.serializeRaw (ChunkIndicesWithoutPerfectHash.data (), vector_bin_size (ChunkIndicesWithoutPerfectHash));
62+
63+ CompressionBlocks.resize (Header.TocCompressedBlockEntryCount );
64+ inAr.serializeRaw (CompressionBlocks.data (), vector_bin_size (CompressionBlocks));
65+
66+ CompressionMethods.emplace_back (" None" );
67+ for (uint32_t i = 0 ; i < Header.CompressionMethodNameCount ; i++) {
68+ const auto name = inAr.read_buffer (Header.CompressionMethodNameLength );
69+ CompressionMethods.emplace_back (std::string (name.data ()));
70+ }
71+
72+ if (Header.ContainerFlags & static_cast <std::underlying_type_t <EIoContainerFlags>>(EIoContainerFlags::Signed)) {
73+ const auto HashSize = inAr.read <int32_t >();
74+ std::vector<uint8_t > TocSignature (HashSize);
75+ inAr.serializeRaw (TocSignature.data (), vector_bin_size (TocSignature));
76+ std::vector<uint8_t > BlockSignature (HashSize);
77+ inAr.serializeRaw (BlockSignature.data (), vector_bin_size (BlockSignature));
78+ ChunkBlockSignatures.resize (Header.TocCompressedBlockEntryCount );
79+ inAr.serializeRaw (ChunkBlockSignatures.data (), vector_bin_size (ChunkBlockSignatures));
80+ }
81+
82+ DirectoryIndexBuffer.resize (Header.DirectoryIndexSize );
83+ inAr.serializeRaw (DirectoryIndexBuffer.data (), vector_bin_size (DirectoryIndexBuffer));
84+
85+ ChunkMetas.resize (Header.TocEntryCount );
86+ inAr.serializeRaw (ChunkMetas.data (), vector_bin_size (ChunkMetas));
87+ }
0 commit comments