write some shit
This commit is contained in:
parent
bdea4c5bcd
commit
b74d8a4e58
|
@ -16,6 +16,7 @@ in VT25 +32, 128
|
|||
VxMemoryMappedFile and CKFileInfo seems no change
|
||||
CKFileObject still no change
|
||||
CKFilePluginDependencies still no change
|
||||
CKFileManagerData no change (12)
|
||||
|
||||
CKStateChunk is 0x28u black box
|
||||
CKBufferParser also is 0x10u black box
|
||||
|
@ -55,6 +56,25 @@ struct XBitArray {
|
|||
DWORD m_Size;
|
||||
};
|
||||
|
||||
// <T, K> = <int, CK_ID>
|
||||
typedef struct XFileObjectsTable::Entry {
|
||||
CK_ID key;
|
||||
int data;
|
||||
struct Entry* next;
|
||||
} *XFileObjectsTable::pEntry;
|
||||
struct XFileObjectsTable {
|
||||
struct XFileObjectsTable::XSArray_pEntry_ {
|
||||
XFileObjectsTable::pEntry* m_Begin;
|
||||
XFileObjectsTable::pEntry* m_End;
|
||||
}m_Table;
|
||||
struct XFileObjectsTable::XClassArray_pEntry_ {
|
||||
XFileObjectsTable::pEntry* m_Begin;
|
||||
XFileObjectsTable::pEntry* m_End;
|
||||
XFileObjectsTable::pEntry* m_AllocatedEnd;
|
||||
}m_Pool;
|
||||
};
|
||||
|
||||
|
||||
struct CKFileInfo
|
||||
{
|
||||
DWORD ProductVersion; // Virtools Version (Dev/Creation). (CK_VIRTOOLS_VERSION)
|
||||
|
@ -87,6 +107,11 @@ struct CKFileObject {
|
|||
CKDWORD SaveFlags; // Flags used when this object was saved.
|
||||
};
|
||||
|
||||
struct CKFileManagerData {
|
||||
CKStateChunk *data;
|
||||
CKGUID Manager;
|
||||
}
|
||||
|
||||
struct CKFilePluginDependencies{
|
||||
int m_PluginCategory;
|
||||
XArray/*<CKGUID>*/ m_Guids;
|
||||
|
@ -130,7 +155,7 @@ struct CKFile {
|
|||
VxMemoryMappedFile* m_MappedFile;
|
||||
// 33 + 5 = 38
|
||||
// guess
|
||||
float m_Chrono[5];
|
||||
XFileObjectsTable m_ObjectsHashTable;
|
||||
// 38 + 5 = 43
|
||||
//[guess]
|
||||
CKBOOL m_SceneSaved;
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace LibCmo {
|
|||
CKDWORD fhdr1[8];
|
||||
CKDWORD fhdr2[8];
|
||||
if (parser->GetSize() < sizeof(fhdr1)) return CKERROR::CKERR_INVALIDFILE;
|
||||
parser->ReadAndMove(fhdr1, sizeof(fhdr1));
|
||||
parser->Read(fhdr1, sizeof(fhdr1));
|
||||
|
||||
if (fhdr1[5]) { // it seems that there is a ZERO checker?
|
||||
memset(fhdr1, 0, sizeof(fhdr1));
|
||||
|
@ -68,7 +68,7 @@ namespace LibCmo {
|
|||
memset(fhdr2, 0, sizeof(fhdr2));
|
||||
} else {
|
||||
if (parser->GetSize() < sizeof(fhdr1) + sizeof(fhdr2)) return CKERROR::CKERR_INVALIDFILE;
|
||||
parser->ReadAndMove(fhdr2, sizeof(fhdr2));
|
||||
parser->Read(fhdr2, sizeof(fhdr2));
|
||||
}
|
||||
|
||||
// forcely reset too big product ver
|
||||
|
@ -100,23 +100,23 @@ namespace LibCmo {
|
|||
fhdr1[2] = 0;
|
||||
|
||||
// compute crc
|
||||
uLong gotten_crc = adler32(0u, reinterpret_cast<const Bytef*>(&fhdr1), sizeof(fhdr1));
|
||||
CKDWORD gotten_crc = CKComputeDataCRC(&fhdr1, sizeof(fhdr1), 0u);
|
||||
parser->SetCursor(sizeof(fhdr1));
|
||||
gotten_crc = adler32(gotten_crc, reinterpret_cast<const Bytef*>(parser->GetPtr()), sizeof(fhdr2));
|
||||
gotten_crc = CKComputeDataCRC(parser->GetPtr(), sizeof(fhdr2), gotten_crc);
|
||||
parser->MoveCursor(sizeof(fhdr2));
|
||||
gotten_crc = adler32(gotten_crc, reinterpret_cast<const Bytef*>(parser->GetPtr()), this->m_FileInfo.Hdr1PackSize);
|
||||
gotten_crc = CKComputeDataCRC(parser->GetPtr(), this->m_FileInfo.Hdr1PackSize, gotten_crc);
|
||||
parser->MoveCursor(this->m_FileInfo.Hdr1PackSize);
|
||||
gotten_crc = adler32(gotten_crc, reinterpret_cast<const Bytef*>(parser->GetPtr()), this->m_FileInfo.DataPackSize);
|
||||
gotten_crc = CKComputeDataCRC(parser->GetPtr(), this->m_FileInfo.DataPackSize, gotten_crc);
|
||||
parser->SetCursor(sizeof(fhdr1) + sizeof(fhdr2));
|
||||
|
||||
if (gotten_crc != static_cast<uLong>(this->m_FileInfo.Crc)) return CKERROR::CKERR_FILECRCERROR;
|
||||
if (gotten_crc != this->m_FileInfo.Crc) return CKERROR::CKERR_FILECRCERROR;
|
||||
|
||||
// compare size to decide wheher use compress feature
|
||||
void* decomp_buffer = CKUnPackData(this->m_FileInfo.Hdr1UnPackSize, parser->GetPtr(), this->m_FileInfo.Hdr1PackSize);
|
||||
if (decomp_buffer != nullptr) {
|
||||
parser = new(std::nothrow) CKBufferParser(decomp_buffer, this->m_FileInfo.Hdr1UnPackSize, true);
|
||||
if (parser == nullptr) {
|
||||
free(decomp_buffer);
|
||||
delete[] decomp_buffer;
|
||||
return CKERROR::CKERR_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
|
@ -137,15 +137,15 @@ namespace LibCmo {
|
|||
fileobj.Data = nullptr;
|
||||
|
||||
// read basic fields
|
||||
parser->ReadAndMove(&(fileobj.Object), sizeof(CK_ID));
|
||||
parser->ReadAndMove(&(fileobj.ObjectCid), sizeof(CK_CLASSID));
|
||||
parser->ReadAndMove(&(fileobj.FileIndex), sizeof(CKDWORD));
|
||||
parser->Read(&(fileobj.Object), sizeof(CK_ID));
|
||||
parser->Read(&(fileobj.ObjectCid), sizeof(CK_CLASSID));
|
||||
parser->Read(&(fileobj.FileIndex), sizeof(CKDWORD));
|
||||
|
||||
CKDWORD namelen;
|
||||
parser->ReadAndMove(&namelen, sizeof(CKDWORD));
|
||||
parser->Read(&namelen, sizeof(CKDWORD));
|
||||
if (namelen != 0) {
|
||||
fileobj.Name.resize(namelen);
|
||||
parser->ReadAndMove(fileobj.Name.data(), namelen);
|
||||
parser->Read(fileobj.Name.data(), namelen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -156,20 +156,20 @@ namespace LibCmo {
|
|||
if (this->m_FileInfo.FileVersion >= 8) {
|
||||
// get size and resize
|
||||
CKDWORD depSize;
|
||||
parser->ReadAndMove(&depSize, sizeof(CKDWORD));
|
||||
parser->Read(&depSize, sizeof(CKDWORD));
|
||||
this->m_PluginDep.resize(depSize);
|
||||
|
||||
CKDWORD guid_size;
|
||||
for (auto& dep : this->m_PluginDep) {
|
||||
// read category
|
||||
parser->ReadAndMove(&(dep.m_PluginCategory), sizeof(CK_PLUGIN_TYPE));
|
||||
parser->Read(&(dep.m_PluginCategory), sizeof(CK_PLUGIN_TYPE));
|
||||
// get size and resize
|
||||
parser->ReadAndMove(&guid_size, sizeof(CKDWORD));
|
||||
parser->Read(&guid_size, sizeof(CKDWORD));
|
||||
dep.m_Guids.resize(guid_size);
|
||||
dep.ValidGuids.resize(guid_size);
|
||||
// read data
|
||||
if (guid_size != 0) {
|
||||
parser->ReadAndMove(dep.m_Guids.data(), sizeof(CKGUID)* guid_size);
|
||||
parser->Read(dep.m_Guids.data(), sizeof(CKGUID)* guid_size);
|
||||
}
|
||||
|
||||
// extra load flag
|
||||
|
@ -193,20 +193,20 @@ namespace LibCmo {
|
|||
// file ver >= 8 have this feature
|
||||
if (this->m_FileInfo.FileVersion >= 8) {
|
||||
// MARK: i don't knwo what is this!
|
||||
int32_t unknowIncludedFileFlag;
|
||||
parser->ReadAndMove(&unknowIncludedFileFlag, sizeof(int32_t));
|
||||
int32_t hasIncludedFile;
|
||||
parser->Read(&hasIncludedFile, sizeof(int32_t));
|
||||
|
||||
if (unknowIncludedFileFlag > 0) {
|
||||
if (hasIncludedFile > 0) {
|
||||
// read included file size and resize
|
||||
CKDWORD includedFileCount;
|
||||
parser->ReadAndMove(&includedFileCount, sizeof(CKDWORD));
|
||||
parser->Read(&includedFileCount, sizeof(CKDWORD));
|
||||
this->m_IncludedFiles.resize(includedFileCount);
|
||||
|
||||
unknowIncludedFileFlag -= 4;
|
||||
hasIncludedFile -= 4;
|
||||
}
|
||||
|
||||
// backward pos
|
||||
parser->SetCursor(unknowIncludedFileFlag);
|
||||
parser->SetCursor(hasIncludedFile);
|
||||
}
|
||||
|
||||
// ========== read data ==========
|
||||
|
@ -229,10 +229,101 @@ namespace LibCmo {
|
|||
}
|
||||
|
||||
CKERROR CKFile::ReadFileData(CKBufferParser** ParserPtr) {
|
||||
CKBufferParser* parser = *ParserPtr;
|
||||
|
||||
// ========== compress feature process ==========
|
||||
if (EnumHelper::FlagEnumHas(this->m_FileInfo.FileWriteMode, CK_FILE_WRITEMODE::CKFILE_CHUNKCOMPRESSED_OLD) ||
|
||||
EnumHelper::FlagEnumHas(this->m_FileInfo.FileWriteMode, CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED)) {
|
||||
void* decomp_buffer = CKUnPackData(this->m_FileInfo.DataUnPackSize, parser->GetPtr(), this->m_FileInfo.DataPackSize);
|
||||
parser->MoveCursor(this->m_FileInfo.DataPackSize);
|
||||
|
||||
if (decomp_buffer != nullptr) {
|
||||
parser = new(std::nothrow) CKBufferParser(decomp_buffer, this->m_FileInfo.Hdr1UnPackSize, true);
|
||||
if (parser == nullptr) {
|
||||
delete[] decomp_buffer;
|
||||
return CKERROR::CKERR_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========== old file crc and obj list read ==========
|
||||
// only file ver < 8 run this
|
||||
if (this->m_FileInfo.FileVersion < 8) {
|
||||
// very very old flag
|
||||
if (this->m_FileInfo.FileVersion < 2) {
|
||||
;
|
||||
// MARK: dword_2405F6C0 setter
|
||||
}
|
||||
|
||||
// check crc
|
||||
CKDWORD gotten_crc = CKComputeDataCRC(
|
||||
parser->GetPtr(),
|
||||
parser->GetSize() - parser->GetCursor(),
|
||||
0u
|
||||
);
|
||||
if (gotten_crc != this->m_FileInfo.Crc) {
|
||||
// MARK: report crc error
|
||||
return CKERROR::CKERR_FILECRCERROR;
|
||||
}
|
||||
|
||||
// get save id max
|
||||
parser->Read(&this->m_SaveIDMax, sizeof(int32_t));
|
||||
// get object count and resize
|
||||
parser->Read(&this->m_FileInfo.ObjectCount, sizeof(CKDWORD));
|
||||
if (this->m_FileObject.empty()) {
|
||||
this->m_FileObject.resize(this->m_FileInfo.ObjectCount);
|
||||
// MARK: ZeroMemory removed. i think it is not necessary.
|
||||
}
|
||||
}
|
||||
|
||||
// ========== manager read ==========
|
||||
|
||||
|
||||
return CKERROR::CKERR_OK;
|
||||
}
|
||||
|
||||
CKERROR CKFile::LoadFileData(void/*CKObjectArray list*/) {
|
||||
if (!this->m_Parser && !this->m_ReadFileDataDone) {
|
||||
return CKERROR::CKERR_INVALIDFILE;
|
||||
}
|
||||
|
||||
// MARK: sub_240372EA, ctx + 193 = 1
|
||||
|
||||
// if file data has not been read. read it
|
||||
CKERROR err = CKERROR::CKERR_OK;
|
||||
CKBufferParser** ParserPtr = &this->m_Parser;
|
||||
if (!this->m_ReadFileDataDone) {
|
||||
err = this->ReadFileData(ParserPtr);
|
||||
}
|
||||
|
||||
// MARK: i assume FinishLoading do not calling mapped file anymore
|
||||
// free file data
|
||||
if (this->m_Parser != nullptr) {
|
||||
delete this->m_Parser;
|
||||
this->m_Parser = nullptr;
|
||||
}
|
||||
if (this->m_MappedFile != nullptr) {
|
||||
delete this->m_MappedFile;
|
||||
this->m_MappedFile = nullptr;
|
||||
}
|
||||
|
||||
// if no error, do finish loading
|
||||
if (err == CKERROR::CKERR_OK) {
|
||||
this->FinishLoading(this->m_Flags);
|
||||
|
||||
// MARK: dword_2405F6C0 old vt ver output
|
||||
}
|
||||
// MARK: CKContext::SetAutomaticLoadMode
|
||||
// MARK:CKContext::SetUserLoadCallback
|
||||
|
||||
// MARK: sub_24037360
|
||||
// MARK: ctx + 193 = 0
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
CKERROR CKFile::FinishLoading(/*CKObjectArray list, */CK_LOAD_FLAGS flags) {
|
||||
return CKERROR::CKERR_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,21 +10,33 @@
|
|||
|
||||
namespace LibCmo {
|
||||
|
||||
#pragma region CKZLib Func
|
||||
|
||||
void* CKUnPackData(CKINT DestSize, const void* SrcBuffer, CKINT SrcSize) {
|
||||
char* DestBuffer = (char*)malloc(DestSize);
|
||||
char* DestBuffer = new(std::nothrow) char[DestSize];
|
||||
if (DestBuffer == nullptr) return nullptr;
|
||||
|
||||
uLongf cache = DestSize;
|
||||
if (uncompress(
|
||||
reinterpret_cast<Bytef*>(DestBuffer), &cache,
|
||||
reinterpret_cast<const Bytef*>(SrcBuffer), SrcSize) != Z_OK) {
|
||||
free(DestBuffer);
|
||||
delete[] DestBuffer;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return DestBuffer;
|
||||
}
|
||||
|
||||
CKDWORD LibCmo::CKComputeDataCRC(const void* data, size_t size, CKDWORD PreviousCRC) {
|
||||
return static_cast<CKDWORD>(adler32(
|
||||
static_cast<uLong>(PreviousCRC),
|
||||
reinterpret_cast<const Bytef*>(data),
|
||||
static_cast<uInt>(size)
|
||||
));
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region VxMemoryMappedFile
|
||||
|
||||
VxMemoryMappedFile::VxMemoryMappedFile(const char* u8_filepath) :
|
||||
|
@ -129,13 +141,13 @@ namespace LibCmo {
|
|||
#pragma region CKBufferParser
|
||||
|
||||
CKBufferParser::CKBufferParser(void* ptr, size_t rsize, bool need_manual_free) :
|
||||
m_ReaderBegin(static_cast<char*>(ptr)),
|
||||
m_ReaderPos(0u), m_ReaderSize(rsize),
|
||||
m_MemBegin(static_cast<char*>(ptr)),
|
||||
m_MemPos(0u), m_MemSize(rsize),
|
||||
m_NeedManualFree(need_manual_free) {
|
||||
;
|
||||
}
|
||||
CKBufferParser::~CKBufferParser() {
|
||||
if (this->m_NeedManualFree) free(this->m_ReaderBegin);
|
||||
if (this->m_NeedManualFree) delete[](this->m_MemBegin);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
namespace LibCmo {
|
||||
|
||||
void* CKUnPackData(CKINT DestSize, const void* SrcBuffer, CKINT SrcSize);
|
||||
CKDWORD CKComputeDataCRC(const void* data, size_t size, CKDWORD PreviousCRC = 0);
|
||||
|
||||
struct CKGUID {
|
||||
union {
|
||||
|
@ -55,10 +56,10 @@ namespace LibCmo {
|
|||
|
||||
class CKBufferParser {
|
||||
private:
|
||||
char* m_ReaderBegin;
|
||||
size_t m_ReaderPos;
|
||||
char* m_MemBegin;
|
||||
size_t m_MemPos;
|
||||
bool m_NeedManualFree;
|
||||
size_t m_ReaderSize;
|
||||
size_t m_MemSize;
|
||||
|
||||
public:
|
||||
CKBufferParser(void* ptr, size_t rsize, bool need_manual_free);
|
||||
|
@ -66,14 +67,19 @@ namespace LibCmo {
|
|||
CKBufferParser& operator=(const CKBufferParser&) = delete;
|
||||
~CKBufferParser();
|
||||
|
||||
inline const void* GetPtr(void) { return (this->m_ReaderBegin + m_ReaderPos); }
|
||||
inline void ReadAndMove(void* data, size_t data_size) {
|
||||
memcpy(data, (this->m_ReaderBegin + m_ReaderPos), data_size);
|
||||
this->m_ReaderPos += data_size;
|
||||
inline const void* GetPtr(void) { return (this->m_MemBegin + m_MemPos); }
|
||||
inline void Read(void* data, size_t data_size) {
|
||||
memcpy(data, (this->m_MemBegin + m_MemPos), data_size);
|
||||
this->m_MemPos += data_size;
|
||||
}
|
||||
inline size_t GetSize(void) { return this->m_ReaderSize; }
|
||||
inline void MoveCursor(size_t off) { this->m_ReaderPos += off; }
|
||||
inline void SetCursor(size_t off) { this->m_ReaderPos = off; }
|
||||
inline void Write(const void* data, size_t data_size) {
|
||||
memcpy((this->m_MemBegin + m_MemPos), data, data_size);
|
||||
this->m_MemPos += data_size;
|
||||
}
|
||||
inline size_t GetSize(void) { return this->m_MemSize; }
|
||||
inline size_t GetCursor(void) { return this->m_MemPos; }
|
||||
inline void MoveCursor(size_t off) { this->m_MemPos += off; }
|
||||
inline void SetCursor(size_t off) { this->m_MemPos = off; }
|
||||
};
|
||||
|
||||
struct CKFileInfo {
|
||||
|
@ -127,6 +133,7 @@ namespace LibCmo {
|
|||
CKERROR ReadFileHeaders(CKBufferParser** ParserPtr);
|
||||
CKERROR ReadFileData(CKBufferParser** ParserPtr);
|
||||
CKERROR LoadFileData(void/*CKObjectArray list*/);
|
||||
CKERROR FinishLoading(/*CKObjectArray list, */CK_LOAD_FLAGS flags);
|
||||
|
||||
int32_t m_SaveIDMax;
|
||||
XArray<CKFileObject> m_FileObject;
|
||||
|
|
Loading…
Reference in New Issue
Block a user