-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #119 from psiberx/master
Added object package reading
- Loading branch information
Showing
15 changed files
with
615 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
#ifdef RED4EXT_STATIC_LIB | ||
#include <RED4ext/Package.hpp> | ||
#endif | ||
|
||
#include <RED4ext/Detail/AddressHashes.hpp> | ||
#include <RED4ext/Relocation.hpp> | ||
|
||
RED4EXT_INLINE RED4ext::ObjectPackageHeader::ObjectPackageHeader() | ||
: rootIndex(-1) | ||
{ | ||
} | ||
|
||
RED4EXT_INLINE bool RED4ext::ObjectPackageHeader::IsEmpty() const | ||
{ | ||
return cruids.IsEmpty(); | ||
} | ||
|
||
RED4EXT_INLINE RED4ext::ObjectPackageReader::ObjectPackageReader(void* aBuffer, uint32_t aSize) | ||
{ | ||
using func_t = void (*)(ObjectPackageReader*); | ||
static UniversalRelocFunc<func_t> func(Detail::AddressHashes::ObjectPackageReader_ctor); | ||
|
||
func(this); | ||
|
||
buffer = aBuffer; | ||
size = aSize; | ||
} | ||
|
||
RED4EXT_INLINE RED4ext::ObjectPackageReader::ObjectPackageReader(const DeferredDataBuffer& aBuffer) | ||
{ | ||
using func_t = void (*)(ObjectPackageReader*); | ||
static UniversalRelocFunc<func_t> func(Detail::AddressHashes::ObjectPackageReader_ctor); | ||
|
||
func(this); | ||
|
||
buffer = aBuffer.raw->data; | ||
size = aBuffer.raw->size; | ||
} | ||
|
||
RED4EXT_INLINE RED4ext::ObjectPackageReader::ObjectPackageReader(const DataBuffer& aBuffer) | ||
{ | ||
using func_t = void (*)(ObjectPackageReader*); | ||
static UniversalRelocFunc<func_t> func(Detail::AddressHashes::ObjectPackageReader_ctor); | ||
|
||
func(this); | ||
|
||
buffer = aBuffer.buffer.data; | ||
size = aBuffer.buffer.size; | ||
} | ||
|
||
RED4EXT_INLINE RED4ext::ObjectPackageReader::ObjectPackageReader(const RawBuffer& aBuffer) | ||
{ | ||
using func_t = void (*)(ObjectPackageReader*); | ||
static UniversalRelocFunc<func_t> func(Detail::AddressHashes::ObjectPackageReader_ctor); | ||
|
||
func(this); | ||
|
||
buffer = aBuffer.data; | ||
size = aBuffer.size; | ||
} | ||
|
||
RED4EXT_INLINE void RED4ext::ObjectPackageReader::OnReadHeader(uint64_t a1, uint64_t a2) | ||
{ | ||
using func_t = void (*)(ObjectPackageReader*, uint64_t, uint64_t); | ||
static UniversalRelocFunc<func_t> func(Detail::AddressHashes::ObjectPackageReader_OnReadHeader); | ||
|
||
func(this, a1, a2); | ||
} | ||
|
||
RED4EXT_INLINE void RED4ext::ObjectPackageReader::ReadHeader() | ||
{ | ||
using func_t = void (*)(ObjectPackageReader*, ObjectPackageHeader&); | ||
static UniversalRelocFunc<func_t> func(Detail::AddressHashes::ObjectPackageReader_ReadHeader); | ||
|
||
func(this, header); | ||
} | ||
|
||
RED4EXT_INLINE void RED4ext::ObjectPackageReader::ReadHeader(RED4ext::ObjectPackageHeader& aOut) | ||
{ | ||
using func_t = void (*)(ObjectPackageReader*, ObjectPackageHeader&); | ||
static UniversalRelocFunc<func_t> func(Detail::AddressHashes::ObjectPackageReader_ReadHeader); | ||
|
||
func(this, aOut); | ||
} | ||
|
||
RED4EXT_INLINE bool RED4ext::ObjectPackageReader::IsEmpty() const | ||
{ | ||
return !buffer; | ||
} | ||
|
||
RED4EXT_INLINE RED4ext::ObjectPackageExtractorParams::ObjectPackageExtractorParams(const RED4ext::PackageHeader& aHeader) | ||
: header(aHeader) | ||
, loader(ResourceLoader::Get()) | ||
, disablePostLoad(false) | ||
, disableImports(false) | ||
, disablePreInitialization(false) | ||
, unk63(0) | ||
, unk64(0) | ||
, unk78(0) | ||
{ | ||
} | ||
|
||
RED4EXT_INLINE RED4ext::ObjectPackageExtractorParams::ObjectPackageExtractorParams(const RED4ext::ObjectPackageHeader& aHeader) | ||
: ObjectPackageExtractorParams(aHeader.package) | ||
{ | ||
} | ||
|
||
RED4EXT_INLINE RED4ext::ObjectPackageExtractor::ObjectPackageExtractor(const RED4ext::ObjectPackageExtractorParams& aParams) | ||
: unk78(0) | ||
, loader(nullptr) | ||
, disablePostLoad(false) | ||
, disableImports(false) | ||
, disablePreInitialization(false) | ||
, unkBB(0) | ||
, unkBC(0) | ||
, unkF0(nullptr) | ||
, unkF8(nullptr) | ||
, unk100(nullptr) | ||
, unk108(nullptr) | ||
, unk110(nullptr) | ||
, unk118(nullptr) | ||
{ | ||
using func_t = void (*)(ObjectPackageExtractor*, const ObjectPackageExtractorParams&); | ||
static UniversalRelocFunc<func_t> func(Detail::AddressHashes::ObjectPackageExtractor_Initialize); | ||
|
||
func(this, aParams); | ||
} | ||
|
||
RED4EXT_INLINE void RED4ext::ObjectPackageExtractor::ExtractSync() | ||
{ | ||
using func_t = void (*)(ObjectPackageExtractor*); | ||
static UniversalRelocFunc<func_t> func(Detail::AddressHashes::ObjectPackageExtractor_ExtractSync); | ||
|
||
func(this); | ||
} | ||
|
||
RED4EXT_INLINE RED4ext::JobHandle RED4ext::ObjectPackageExtractor::ExtractAsync() | ||
{ | ||
using func_t = void (*)(ObjectPackageExtractor*, JobHandle&); | ||
static UniversalRelocFunc<func_t> func(Detail::AddressHashes::ObjectPackageExtractor_ExtractAsync); | ||
|
||
JobHandle job; | ||
func(this, job); | ||
|
||
return job; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
#pragma once | ||
|
||
#include <cstdint> | ||
|
||
#include <RED4ext/Common.hpp> | ||
#include <RED4ext/NativeTypes.hpp> | ||
#include <RED4ext/Range.hpp> | ||
#include <RED4ext/ResourceLoader.hpp> | ||
|
||
namespace RED4ext | ||
{ | ||
struct PackageHeader | ||
{ | ||
struct Chunk | ||
{ | ||
uint32_t typeID; | ||
uint32_t offset; | ||
}; | ||
RED4EXT_ASSERT_SIZE(Chunk, 0x8); | ||
|
||
struct Name | ||
{ | ||
uint32_t offset : 24; | ||
uint32_t size : 8; | ||
}; | ||
RED4EXT_ASSERT_SIZE(Name, 0x4); | ||
|
||
struct Import | ||
{ | ||
uint32_t offset : 23; | ||
uint32_t size : 8; | ||
uint32_t sync : 1; | ||
}; | ||
RED4EXT_ASSERT_SIZE(Import, 0x4); | ||
|
||
uint8_t version; // 00 | ||
uint8_t unk01; // 01 | ||
uint16_t unk02; // 02 | ||
Range<Chunk> root; // 08 | ||
Range<Chunk> chunks; // 18 | ||
Range<Name> names; // 28 | ||
Range<Import> imports; // 38 | ||
void* buffer; // 48 | ||
uint32_t size; // 50 | ||
}; | ||
RED4EXT_ASSERT_SIZE(PackageHeader, 0x58); | ||
RED4EXT_ASSERT_OFFSET(PackageHeader, unk02, 0x02); | ||
RED4EXT_ASSERT_OFFSET(PackageHeader, root, 0x08); | ||
RED4EXT_ASSERT_OFFSET(PackageHeader, buffer, 0x48); | ||
|
||
struct ObjectPackageHeader | ||
{ | ||
ObjectPackageHeader(); | ||
|
||
[[nodiscard]] bool IsEmpty() const; | ||
|
||
int16_t rootIndex; // 00 - Set to 0 if package contains root Entity, otherwise -1 | ||
Range<CRUID> cruids; // 08 | ||
PackageHeader package; // 18 | ||
}; | ||
RED4EXT_ASSERT_SIZE(ObjectPackageHeader, 0x70); | ||
RED4EXT_ASSERT_OFFSET(ObjectPackageHeader, rootIndex, 0x0); | ||
RED4EXT_ASSERT_OFFSET(ObjectPackageHeader, cruids, 0x08); | ||
RED4EXT_ASSERT_OFFSET(ObjectPackageHeader, package, 0x18); | ||
|
||
struct ObjectPackageReader | ||
{ | ||
ObjectPackageReader(void* aBuffer, uint32_t aSize); | ||
ObjectPackageReader(const DeferredDataBuffer& aBuffer); | ||
ObjectPackageReader(const DataBuffer& aBuffer); | ||
ObjectPackageReader(const RawBuffer& aBuffer); | ||
|
||
virtual ~ObjectPackageReader() = default; // 00 | ||
virtual void OnReadHeader(uint64_t a1, uint64_t a2); // 08 | ||
|
||
void ReadHeader(); | ||
void ReadHeader(ObjectPackageHeader& aOut); | ||
|
||
[[nodiscard]] bool IsEmpty() const; | ||
|
||
void* buffer; // 08 | ||
uint32_t size; // 10 | ||
ObjectPackageHeader header; // 18 | ||
}; | ||
RED4EXT_ASSERT_SIZE(ObjectPackageReader, 0x88); | ||
RED4EXT_ASSERT_OFFSET(ObjectPackageReader, buffer, 0x08); | ||
RED4EXT_ASSERT_OFFSET(ObjectPackageReader, size, 0x10); | ||
RED4EXT_ASSERT_OFFSET(ObjectPackageReader, header, 0x18); | ||
|
||
struct ObjectPackageExtractorParams | ||
{ | ||
ObjectPackageExtractorParams(const ObjectPackageHeader& aHeader); | ||
ObjectPackageExtractorParams(const PackageHeader& aHeader); | ||
|
||
PackageHeader header; // 00 | ||
ResourceLoader* loader; // 58 | ||
bool disablePostLoad; // 60 - See ObjectPackageExtractor | ||
bool disableImports; // 61 - See ObjectPackageExtractor | ||
bool disablePreInitialization; // 62 - See ObjectPackageExtractor | ||
uint8_t unk63; // 63 | ||
uint8_t unk64; // 64 | ||
DynArray<uint32_t> unk68; // 68 | ||
uint32_t unk78; // 78 | ||
RawBuffer unk80; // 80 - Moved to ObjectPackageExtractor in ctor | ||
}; | ||
RED4EXT_ASSERT_SIZE(ObjectPackageExtractorParams, 0xA0); | ||
RED4EXT_ASSERT_OFFSET(ObjectPackageExtractorParams, loader, 0x58); | ||
RED4EXT_ASSERT_OFFSET(ObjectPackageExtractorParams, disablePostLoad, 0x60); | ||
RED4EXT_ASSERT_OFFSET(ObjectPackageExtractorParams, disableImports, 0x61); | ||
RED4EXT_ASSERT_OFFSET(ObjectPackageExtractorParams, disablePreInitialization, 0x62); | ||
RED4EXT_ASSERT_OFFSET(ObjectPackageExtractorParams, unk80, 0x80); | ||
|
||
struct ObjectPackageExtractor | ||
{ | ||
ObjectPackageExtractor(const ObjectPackageExtractorParams& aParams); | ||
|
||
void ExtractSync(); | ||
JobHandle ExtractAsync(); | ||
|
||
WeakPtr<ObjectPackageExtractor> self; // 00 | ||
PackageHeader header; // 10 | ||
DynArray<uint32_t> unk68; // 68 | ||
uint32_t unk78; // 78 | ||
RawBuffer unk80; // 80 | ||
ResourceLoader* loader; // A0 | ||
DynArray<Handle<ISerializable>> results; // A8 | ||
bool disablePostLoad; // B8 - Don't call serializable->PostLoad() | ||
bool disableImports; // B9 - Don't load resource references | ||
bool disablePreInitialization; // BA - Don't call pre-initilization during PostLoad() | ||
uint8_t unkBB; // BB | ||
uint8_t unkBC; // BC | ||
DynArray<Handle<ISerializable>> objects; // C0 | ||
DynArray<SharedPtr<ResourceToken<>>> resources; // D0 | ||
DynArray<uint32_t> unkE0; // E0 | ||
void* unkF0; // F0 | ||
void* unkF8; // F8 | ||
void* unk100; // 100 | ||
void* unk108; // 108 | ||
void* unk110; // 110 | ||
void* unk118; // 118 | ||
}; | ||
RED4EXT_ASSERT_SIZE(ObjectPackageExtractor, 0x120); | ||
RED4EXT_ASSERT_OFFSET(ObjectPackageExtractor, header, 0x10); | ||
RED4EXT_ASSERT_OFFSET(ObjectPackageExtractor, results, 0xA8); | ||
RED4EXT_ASSERT_OFFSET(ObjectPackageExtractor, disablePostLoad, 0xB8); | ||
RED4EXT_ASSERT_OFFSET(ObjectPackageExtractor, disableImports, 0xB9); | ||
RED4EXT_ASSERT_OFFSET(ObjectPackageExtractor, disablePreInitialization, 0xBA); | ||
RED4EXT_ASSERT_OFFSET(ObjectPackageExtractor, objects, 0xC0); | ||
RED4EXT_ASSERT_OFFSET(ObjectPackageExtractor, resources, 0xD0); | ||
} // namespace RED4ext | ||
|
||
#ifdef RED4EXT_HEADER_ONLY | ||
#include <RED4ext/Package-inl.hpp> | ||
#endif |
Oops, something went wrong.