diff --git a/Documents/Recorder.txt b/Documents/Recorder.txt index f15ec27..1934e7a 100644 --- a/Documents/Recorder.txt +++ b/Documents/Recorder.txt @@ -6,6 +6,8 @@ lost 24 byte, 6 fields or 2 lists Important CK Class size CKObject no change. 0x14(20) CKSceneObject no change 0x1C(28), share Load/Save with CKObject + +CKBehavior no change 0x6C(108) CKBeObject 0x50(80) count 20 CKGroup 0x68(104) count 26 @@ -39,6 +41,14 @@ CKFileManagerData no change (12) CKStateChunk is 0x28u black box CKBufferParser also is 0x10u black box +typedef char* CKSTRING; +typedef char CKCHAR; +typedef int CKBOOL; +typedef unsigned char CKBYTE; +typedef unsigned int CKDWORD; +typedef unsigned short CKWORD; +typedef int CKERROR; + struct CKGUID { DWORD d1,d2; }; @@ -98,6 +108,38 @@ struct XFileObjectsTable { }; +struct CKObject { + DWORD* vtable; + CK_ID m_ID; + CKSTRING m_Name; + CKDWORD m_ObjectFlags; + CKContext *m_Context; +}; + +struct CKSceneObject : CKObject { + XBitArray m_Scenes; +}; + +struct BehaviorBlockData{}; +struct BehaviorGraphData{}; +struct CKBehavior : CKSceneObject { + CK_ID m_Owner; + CK_ID m_BehParent; + XSObjectPointerArray m_InputArray; + XSObjectPointerArray m_OutputArray; + XSObjectPointerArray m_InParameter; + XSObjectPointerArray m_OutParameter; + XSObjectPointerArray m_LocalParameter; + CK_CLASSID m_CompatibleClassID; + int m_Priority; + CKDWORD m_Flags; + CKStateChunk * m_InterfaceChunk; + BehaviorGraphData* m_GraphData; + BehaviorBlockData* m_BlockData; + float m_LastExecutionTime; + CK_ID m_InputTargetParam; +}; + struct CKFileInfo { DWORD ProductVersion; // Virtools Version (Dev/Creation). (CK_VIRTOOLS_VERSION) @@ -180,6 +222,28 @@ struct CKStateChunk { CKFile* m_BindFile; DWORD m_unknow; }; +struct CKStateChunkRemap { // 0x40 count 16 +DWORD m_ChunkVersion; +DWORD* m_pData; +DWORD m_DataDwordSize; +DWORD unknow_3; +DWORD* m_ObjList_pData; +DWORD m_ObjList_Count; +DWORD* m_ChkList_pData; +DWORD m_ChkList_Count; + +DWORD unknow_8; +DWORD unknow_9; +DWORD unknow_10; +DWORD unknow_11; +DWORD unknow_12; +DWORD unknow_13; + +CKDependenciesContext* m_DepCtx; +CKContext* m_Ctx; +}; + + struct CKBufferParser { char* m_MemBegin; diff --git a/LibCmo/CKDefines.hpp b/LibCmo/CKDefines.hpp index 3a3e97d..bbe13ee 100644 --- a/LibCmo/CKDefines.hpp +++ b/LibCmo/CKDefines.hpp @@ -23,7 +23,6 @@ namespace LibCmo { using XClassArray = std::vector; //using CKObjectArray = std::vector; - struct CKGUID { union { struct { diff --git a/LibCmo/CKFileReader.cpp b/LibCmo/CKFileReader.cpp index 6ab1291..a3adb8d 100644 --- a/LibCmo/CKFileReader.cpp +++ b/LibCmo/CKFileReader.cpp @@ -347,6 +347,11 @@ namespace LibCmo { return CKERROR::CKERR_OK; } + CKERROR CKFile::DeepLoad(CKSTRING u8_filename, CKFileData::DeepDocument** out_doc) { + return CKERROR::CKERR_OK; + } + + //CKERROR CKFile::Load(CKSTRING u8_filename, /*CKObjectArray list, */ CK_LOAD_FLAGS flags) { // CKERROR result = this->OpenFile(u8_filename, flags); // if (result == CKERROR::CKERR_OK || result == CKERROR::CKERR_PLUGINSMISSING) { diff --git a/LibCmo/CKMinContext.hpp b/LibCmo/CKMinContext.hpp index baf6781..1175545 100644 --- a/LibCmo/CKMinContext.hpp +++ b/LibCmo/CKMinContext.hpp @@ -3,13 +3,11 @@ #include "CKDefines.hpp" #include "CKEnums.hpp" #include "VTEncoding.hpp" +#include "VTObjects.hpp" #include namespace LibCmo { - // forward decl to rm recursive reference - namespace ObjsImpl { class CKObject; } - class CKMinContext { public: CKMinContext(); @@ -19,7 +17,7 @@ namespace LibCmo { void Printf(CKSTRING fmt, ...); - ObjsImpl::CKObject* CreateObject(CK_ID id, CKSTRING name); + ObjsImpl::CKObject* CreateObject(CK_ID id, CK_CLASSID cls, CKSTRING name); void DestroyObject(ObjsImpl::CKObject* obj); void GetUtf8ObjectName(std::string& native_name, std::string& u8_name); diff --git a/LibCmo/CKStateChunk.cpp b/LibCmo/CKStateChunk.cpp index 7c85516..3241094 100644 --- a/LibCmo/CKStateChunk.cpp +++ b/LibCmo/CKStateChunk.cpp @@ -9,27 +9,96 @@ namespace LibCmo { +#pragma region Ctor Dtor + CKStateChunk::CKStateChunk() : m_ClassId(CK_CLASSID::CKCID_OBJECT), m_DataDwSize(0u), m_pData(nullptr), m_DataVersion(CK_STATECHUNK_DATAVERSION::CHUNKDATA_CURRENTVERSION), m_ChunkVersion(CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION4), - m_Parser{ 0u, 0u, 0u }, + m_Parser{ CKStateChunkStatus::IDLE, 0u, 0u, 0u }, m_ObjectList(), m_ChunkList(), m_ManagerList() { ; } - LibCmo::CKStateChunk::CKStateChunk(CK_CLASSID clsid) : - m_ClassId(clsid), m_DataDwSize(0u), m_pData(nullptr), - m_DataVersion(CK_STATECHUNK_DATAVERSION::CHUNKDATA_CURRENTVERSION), m_ChunkVersion(CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION4), - m_Parser{ 0u, 0u, 0u }, - m_ObjectList(), m_ChunkList(), m_ManagerList() + CKStateChunk::CKStateChunk(const CKStateChunk& rhs) : + m_ClassId(rhs.m_ClassId), m_DataVersion(rhs.m_DataVersion), m_ChunkVersion(rhs.m_ChunkVersion), + m_Parser(rhs.m_Parser), + m_ObjectList(rhs.m_ObjectList), m_ManagerList(rhs.m_ManagerList), m_ChunkList(rhs.m_ChunkList), + m_pData(nullptr), m_DataDwSize(rhs.m_DataDwSize) { - ; + // copy buffer + if (rhs.m_pData != nullptr) { + this->m_pData = new(std::nothrow) CKDWORD[rhs.m_DataDwSize]; + if (this->m_pData != nullptr) { + memcpy(this->m_pData, rhs.m_pData, sizeof(CKDWORD) * rhs.m_DataDwSize); + } + } + } + CKStateChunk& CKStateChunk::operator=(const CKStateChunk& rhs) { + this->Clear(); + + this->m_DataVersion = rhs.m_DataVersion; + this->m_ChunkVersion = rhs.m_ChunkVersion; + this->m_ClassId = rhs.m_ClassId; + + this->m_Parser = rhs.m_Parser; + + this->m_ObjectList = rhs.m_ObjectList; + this->m_ManagerList = rhs.m_ManagerList; + this->m_ChunkList = rhs.m_ChunkList; + + // copy buffer + if (rhs.m_pData != nullptr) { + this->m_pData = new(std::nothrow) CKDWORD[rhs.m_DataDwSize]; + if (this->m_pData != nullptr) { + memcpy(this->m_pData, rhs.m_pData, sizeof(CKDWORD) * rhs.m_DataDwSize); + } + } + this->m_DataDwSize = rhs.m_DataDwSize; + + return *this; } CKStateChunk::~CKStateChunk() { if (this->m_pData != nullptr) delete[] this->m_pData; } +#pragma endregion + +#pragma region Misc Funcs + + void CKStateChunk::Clear(void) { + this->m_ClassId = CK_CLASSID::CKCID_OBJECT; + //this->m_DataVersion = CK_STATECHUNK_DATAVERSION::CHUNK_DEV_2_1; + //this->m_ChunkVersion = CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION4; + + this->m_Parser.m_CurrentPos = 0; + this->m_Parser.m_DataSize = 0; + this->m_Parser.m_PrevIdentifierPos = 0; + + this->m_DataDwSize = 0; + if (this->m_pData != nullptr) { + delete[] this->m_pData; + this->m_pData = nullptr; + } + + this->m_ObjectList.clear(); + this->m_ManagerList.clear(); + this->m_ChunkList.clear(); + } + + CKDWORD CKStateChunk::GetDataSize(void) { + return sizeof(CKDWORD) * this->m_DataDwSize; + } + + void LibCmo::CKStateChunk::_EnsureWriteSpace(CKDWORD size) { + ; + } + + +#pragma endregion + +#pragma region Buffer Related + bool CKStateChunk::ConvertFromBuffer(const void* buf) { if (buf == nullptr) return false; @@ -163,6 +232,9 @@ namespace LibCmo { return 0u; } +#pragma endregion + + //bool CKStateChunk::UnPack(CKDWORD DestSize) { // // NOTE: in UnPack. pData store the compressed buffer, and // // dwSize store the length of compressed buffer as CHAR size, not DWORD size! @@ -192,20 +264,21 @@ namespace LibCmo { // return true; //} - CKDWORD CKStateChunk::GetDataSize(void) { - return sizeof(CKDWORD) * this->m_DataDwSize; - } - bool CKStateChunk::SeekIdentifier(CKDWORD identifier) { return false; } + void CKStateChunk::StartRead(void) { + if (this->m_Parser.m_Status != CKStateChunkStatus::IDLE) return; + + this->m_Parser.m_CurrentPos = 0u; + this->m_Parser.m_DataSize = this->m_DataDwSize; + this->m_Parser.m_PrevIdentifierPos = 0u; + this->m_Parser.m_Status = CKStateChunkStatus::READ; + } + void CKStateChunk::ReadString(std::string& strl) { ; } - void LibCmo::CKStateChunk::_EnsureEnoughSpace(CKDWORD size) { - ; - } - } diff --git a/LibCmo/CKStateChunk.hpp b/LibCmo/CKStateChunk.hpp index 5991ce2..01d017f 100644 --- a/LibCmo/CKStateChunk.hpp +++ b/LibCmo/CKStateChunk.hpp @@ -8,23 +8,30 @@ namespace LibCmo { class CKStateChunk { public: CKStateChunk(); - CKStateChunk(CK_CLASSID clsid); - CKStateChunk(const CKStateChunk&) = delete; - CKStateChunk& operator=(const CKStateChunk&) = delete; + CKStateChunk(const CKStateChunk&); + CKStateChunk& operator=(const CKStateChunk&); ~CKStateChunk(); - bool ConvertFromOldBuffer(const void* buf, CKDWORD buf_size, CKDWORD blk_size, CK_FILE_WRITEMODE mode); + void Clear(void); + bool ConvertFromBuffer(const void* buf); CKDWORD ConvertToBuffer(void* buf); - bool UnPack(CKDWORD DestSize); + //bool UnPack(CKDWORD DestSize); CKDWORD GetDataSize(void); bool SeekIdentifier(CKDWORD identifier); + void StartRead(void); void ReadString(std::string& strl); private: + enum class CKStateChunkStatus : int32_t { + IDLE, + READ, + WRITE + }; + CK_CLASSID m_ClassId; CKDWORD m_DataDwSize; CKDWORD* m_pData; @@ -33,6 +40,7 @@ namespace LibCmo { CK_STATECHUNK_CHUNKVERSION m_ChunkVersion; struct { + CKStateChunkStatus m_Status; CKDWORD m_CurrentPos; CKDWORD m_DataSize; CKDWORD m_PrevIdentifierPos; @@ -43,8 +51,10 @@ namespace LibCmo { std::vector m_ManagerList; private: - void _EnsureEnoughSpace(CKDWORD size); - + void _EnsureWriteSpace(CKDWORD size); + inline bool _EnsureReadSpace(CKDWORD required) { + return (this->m_Parser.m_CurrentPos <= this->m_Parser.m_DataSize) && (required <= (this->m_Parser.m_DataSize - this->m_Parser.m_CurrentPos)); + } }; } diff --git a/LibCmo/LibCmo.vcxproj b/LibCmo/LibCmo.vcxproj index 1258b51..8fa9fb9 100644 --- a/LibCmo/LibCmo.vcxproj +++ b/LibCmo/LibCmo.vcxproj @@ -190,6 +190,7 @@ + diff --git a/LibCmo/LibCmo.vcxproj.filters b/LibCmo/LibCmo.vcxproj.filters index 6ef7c45..4649f45 100644 --- a/LibCmo/LibCmo.vcxproj.filters +++ b/LibCmo/LibCmo.vcxproj.filters @@ -80,5 +80,8 @@ Headers + + Headers + \ No newline at end of file diff --git a/LibCmo/VTManagers.hpp b/LibCmo/VTManagers.hpp new file mode 100644 index 0000000..e6cd65e --- /dev/null +++ b/LibCmo/VTManagers.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include "CKDefines.hpp" +#include "CKEnums.hpp" + +namespace LibCmo { + + // forward decl to rm recursive reference + class CKMinContext; + class CKStateChunk; + + namespace MgrsImpl { + + class CKBaseManager { + public: + CKBaseManager(); + CKBaseManager(const CKBaseManager&) = delete; + CKBaseManager& operator=(const CKBaseManager&) = delete; + virtual ~CKBaseManager(); + + private: + + }; + + } +} diff --git a/LibCmo/VTObjects.hpp b/LibCmo/VTObjects.hpp index de245b5..4d69abd 100644 --- a/LibCmo/VTObjects.hpp +++ b/LibCmo/VTObjects.hpp @@ -2,9 +2,13 @@ #include "CKDefines.hpp" #include "CKEnums.hpp" -#include "CKStateChunk.hpp" namespace LibCmo { + + // forward decl to rm recursive reference + class CKMinContext; + class CKStateChunk; + namespace ObjsImpl { class CKObject { diff --git a/Unvirt/Unvirt.cpp b/Unvirt/Unvirt.cpp index 16f7361..925ad6d 100644 --- a/Unvirt/Unvirt.cpp +++ b/Unvirt/Unvirt.cpp @@ -15,7 +15,7 @@ int main(int argc, char* argv[]) { LibCmo::CKFile vtfile(&vtctx); LibCmo::CKFileData::ShallowDocument* doc; - LibCmo::CKERROR err = vtfile.ShallowLoad("combining behaviors.cmo", &doc); + LibCmo::CKERROR err = vtfile.ShallowLoad("Language.old.nmo", &doc); if (doc) Unvirt::StructFormatter::PrintCKFileInfo(doc->m_FileInfo); diff --git a/VirtoolsProbe/main.cpp b/VirtoolsProbe/main.cpp index 6cc5914..bf3d302 100644 --- a/VirtoolsProbe/main.cpp +++ b/VirtoolsProbe/main.cpp @@ -10,10 +10,10 @@ #define BUFFER_SIZE 1024 void Assert(bool cond, const char* desc) { - if (!cond) { + if (!cond) { std::cout << desc << std::endl; - ExitProcess(0); - } + ExitProcess(0); + } } struct MyModuleInfo { @@ -59,6 +59,31 @@ std::map ConstructModuleList() { return result; } +void PrintVTable(std::map& modules, CKDWORD* pCls, size_t vtable_len, char indent) { + if (pCls == nullptr) { + fputc('\n', stdout); + return; + } + CKDWORD* vtable = *(reinterpret_cast(pCls)); + + for (size_t i = 0; i < vtable_len; ++i) { + intptr_t addr = vtable[i]; + const auto& it = modules.lower_bound(addr); + if (it != modules.end() && it != modules.begin()) { + const auto& itt = std::prev(it); + fprintf(stdout, "%s::", itt->second.ModuleName.c_str()); + addr = addr - itt->second.BaseOfDll; + + if (itt->second.ModuleName == "CK2_3D.dll") + addr += 0x10000000u; + else if (itt->second.ModuleName == "CK2.dll") + addr += 0x24000000u; + } + fprintf(stdout, "%08X%c", addr, indent); + } + fputc('\n', stdout); +} + int main() { Assert(LoadLibrary("CK2.dll"), "Error loading CK2.dll"); @@ -88,141 +113,137 @@ int main() { std::cout << "Press any key to run..." << std::endl; system("pause"); - static std::vector cls{ - CKCID_OBJECT, - CKCID_PARAMETERIN, - CKCID_PARAMETEROPERATION, - CKCID_STATE, - CKCID_BEHAVIORLINK, - CKCID_BEHAVIOR, - CKCID_BEHAVIORIO, - CKCID_RENDERCONTEXT, - CKCID_KINEMATICCHAIN, - CKCID_SCENEOBJECT, - CKCID_OBJECTANIMATION, - CKCID_ANIMATION, - CKCID_KEYEDANIMATION, - CKCID_BEOBJECT, - CKCID_DATAARRAY, - CKCID_SCENE, - CKCID_LEVEL, - CKCID_PLACE, - CKCID_GROUP, - CKCID_SOUND, - CKCID_WAVESOUND, - CKCID_MIDISOUND, - CKCID_MATERIAL, - CKCID_TEXTURE, - CKCID_MESH, - CKCID_PATCHMESH, - CKCID_RENDEROBJECT, - CKCID_2DENTITY, - CKCID_SPRITE, - CKCID_SPRITETEXT, - CKCID_3DENTITY, - CKCID_GRID, - CKCID_CURVEPOINT, - CKCID_SPRITE3D, - CKCID_CURVE, - CKCID_CAMERA, - CKCID_TARGETCAMERA, - CKCID_LIGHT, - CKCID_TARGETLIGHT, - CKCID_CHARACTER, - CKCID_3DOBJECT, - CKCID_BODYPART, - CKCID_PARAMETER, - CKCID_PARAMETERLOCAL, - CKCID_PARAMETERVARIABLE, - CKCID_PARAMETEROUT, - CKCID_INTERFACEOBJECTMANAGER, - CKCID_CRITICALSECTION, - CKCID_LAYER, - CKCID_PROGRESSIVEMESH, - CKCID_SYNCHRO - }; - static std::vector clsname{ - "CKCID_OBJECT", - "CKCID_PARAMETERIN", - "CKCID_PARAMETEROPERATION", - "CKCID_STATE", - "CKCID_BEHAVIORLINK", - "CKCID_BEHAVIOR", - "CKCID_BEHAVIORIO", - "CKCID_RENDERCONTEXT", - "CKCID_KINEMATICCHAIN", - "CKCID_SCENEOBJECT", - "CKCID_OBJECTANIMATION", - "CKCID_ANIMATION", - "CKCID_KEYEDANIMATION", - "CKCID_BEOBJECT", - "CKCID_DATAARRAY", - "CKCID_SCENE", - "CKCID_LEVEL", - "CKCID_PLACE", - "CKCID_GROUP", - "CKCID_SOUND", - "CKCID_WAVESOUND", - "CKCID_MIDISOUND", - "CKCID_MATERIAL", - "CKCID_TEXTURE", - "CKCID_MESH", - "CKCID_PATCHMESH", - "CKCID_RENDEROBJECT", - "CKCID_2DENTITY", - "CKCID_SPRITE", - "CKCID_SPRITETEXT", - "CKCID_3DENTITY", - "CKCID_GRID", - "CKCID_CURVEPOINT", - "CKCID_SPRITE3D", - "CKCID_CURVE", - "CKCID_CAMERA", - "CKCID_TARGETCAMERA", - "CKCID_LIGHT", - "CKCID_TARGETLIGHT", - "CKCID_CHARACTER", - "CKCID_3DOBJECT", - "CKCID_BODYPART", - "CKCID_PARAMETER", - "CKCID_PARAMETERLOCAL", - "CKCID_PARAMETERVARIABLE", - "CKCID_PARAMETEROUT", - "CKCID_INTERFACEOBJECTMANAGER", - "CKCID_CRITICALSECTION", - "CKCID_LAYER", - "CKCID_PROGRESSIVEMESH", - "CKCID_SYNCHRO" - }; - + // print CKObject vtable + //static std::vector cls{ + // CKCID_OBJECT, + // CKCID_PARAMETERIN, + // CKCID_PARAMETEROPERATION, + // CKCID_STATE, + // CKCID_BEHAVIORLINK, + // CKCID_BEHAVIOR, + // CKCID_BEHAVIORIO, + // CKCID_RENDERCONTEXT, + // CKCID_KINEMATICCHAIN, + // CKCID_SCENEOBJECT, + // CKCID_OBJECTANIMATION, + // CKCID_ANIMATION, + // CKCID_KEYEDANIMATION, + // CKCID_BEOBJECT, + // CKCID_DATAARRAY, + // CKCID_SCENE, + // CKCID_LEVEL, + // CKCID_PLACE, + // CKCID_GROUP, + // CKCID_SOUND, + // CKCID_WAVESOUND, + // CKCID_MIDISOUND, + // CKCID_MATERIAL, + // CKCID_TEXTURE, + // CKCID_MESH, + // CKCID_PATCHMESH, + // CKCID_RENDEROBJECT, + // CKCID_2DENTITY, + // CKCID_SPRITE, + // CKCID_SPRITETEXT, + // CKCID_3DENTITY, + // CKCID_GRID, + // CKCID_CURVEPOINT, + // CKCID_SPRITE3D, + // CKCID_CURVE, + // CKCID_CAMERA, + // CKCID_TARGETCAMERA, + // CKCID_LIGHT, + // CKCID_TARGETLIGHT, + // CKCID_CHARACTER, + // CKCID_3DOBJECT, + // CKCID_BODYPART, + // CKCID_PARAMETER, + // CKCID_PARAMETERLOCAL, + // CKCID_PARAMETERVARIABLE, + // CKCID_PARAMETEROUT, + // CKCID_INTERFACEOBJECTMANAGER, + // CKCID_CRITICALSECTION, + // CKCID_LAYER, + // CKCID_PROGRESSIVEMESH, + // CKCID_SYNCHRO + //}; + //static std::vector clsname{ + // "CKCID_OBJECT", + // "CKCID_PARAMETERIN", + // "CKCID_PARAMETEROPERATION", + // "CKCID_STATE", + // "CKCID_BEHAVIORLINK", + // "CKCID_BEHAVIOR", + // "CKCID_BEHAVIORIO", + // "CKCID_RENDERCONTEXT", + // "CKCID_KINEMATICCHAIN", + // "CKCID_SCENEOBJECT", + // "CKCID_OBJECTANIMATION", + // "CKCID_ANIMATION", + // "CKCID_KEYEDANIMATION", + // "CKCID_BEOBJECT", + // "CKCID_DATAARRAY", + // "CKCID_SCENE", + // "CKCID_LEVEL", + // "CKCID_PLACE", + // "CKCID_GROUP", + // "CKCID_SOUND", + // "CKCID_WAVESOUND", + // "CKCID_MIDISOUND", + // "CKCID_MATERIAL", + // "CKCID_TEXTURE", + // "CKCID_MESH", + // "CKCID_PATCHMESH", + // "CKCID_RENDEROBJECT", + // "CKCID_2DENTITY", + // "CKCID_SPRITE", + // "CKCID_SPRITETEXT", + // "CKCID_3DENTITY", + // "CKCID_GRID", + // "CKCID_CURVEPOINT", + // "CKCID_SPRITE3D", + // "CKCID_CURVE", + // "CKCID_CAMERA", + // "CKCID_TARGETCAMERA", + // "CKCID_LIGHT", + // "CKCID_TARGETLIGHT", + // "CKCID_CHARACTER", + // "CKCID_3DOBJECT", + // "CKCID_BODYPART", + // "CKCID_PARAMETER", + // "CKCID_PARAMETERLOCAL", + // "CKCID_PARAMETERVARIABLE", + // "CKCID_PARAMETEROUT", + // "CKCID_INTERFACEOBJECTMANAGER", + // "CKCID_CRITICALSECTION", + // "CKCID_LAYER", + // "CKCID_PROGRESSIVEMESH", + // "CKCID_SYNCHRO" + //}; + // + //auto moduleInfos = ConstructModuleList(); + + //fputs("Class Name,Class Id,Show(),IsHiddenByParent(),CanBeHide(),IsVisible(),~dtor(),GetClassID(),PreSave(),Save(),Load(),PostLoad(),PreDelete(),CheckPreDeletion(),CheckPostDeletion(),GetMemoryOccupation(),IsObjectUsed(),PrepareDependencies(),RemapDependencies(),Copy(),\n", stdout); + //for (size_t j = 0; j < cls.size(); ++j) { + // CK_CLASSID item = cls[j]; + // const char* itemname = clsname[j]; + + // CKObject* obj = ctx->CreateObject(item, NULL, CK_OBJECTCREATION_NONAMECHECK, NULL); + + // fprintf(stdout, "%s,%d,", itemname, item); + // PrintVTable(moduleInfos, reinterpret_cast(obj), 18); + //} + + // print manager vtables auto moduleInfos = ConstructModuleList(); + int count = ctx->GetManagerCount(); + for (int i = 0; i < count; ++i) { + CKBaseManager* mgr = ctx->GetManager(i); - fputs("Class Name,Class Id,Show(),IsHiddenByParent(),CanBeHide(),IsVisible(),~dtor(),GetClassID(),PreSave(),Save(),Load(),PostLoad(),PreDelete(),CheckPreDeletion(),CheckPostDeletion(),GetMemoryOccupation(),IsObjectUsed(),PrepareDependencies(),RemapDependencies(),Copy(),\n", stdout); - for (size_t j = 0; j < cls.size(); ++j) { - CK_CLASSID item = cls[j]; - const char* itemname = clsname[j]; - - CKObject* obj = ctx->CreateObject(item, NULL, CK_OBJECTCREATION_NONAMECHECK, NULL); - if (obj == nullptr) continue; - CKDWORD* vtable = *(reinterpret_cast(obj)); - - fprintf(stdout, "%s,%d,", itemname, item); - for (size_t i = 0; i < 18; ++i) { - intptr_t addr = vtable[i]; - const auto& it = moduleInfos.lower_bound(addr); - if (it != moduleInfos.end() && it != moduleInfos.begin()) { - const auto& itt = std::prev(it); - fprintf(stdout, "%s::", itt->second.ModuleName.c_str()); - addr = addr - itt->second.BaseOfDll; - - if (itt->second.ModuleName == "CK2_3D.dll") - addr += 0x10000000u; - else if (itt->second.ModuleName == "CK2.dll") - addr += 0x24000000u; - } - fprintf(stdout, "%08X,", addr); - } - fputc('\n', stdout); + CKSTRING name = mgr->GetName(); + CKGUID guid = mgr->GetGuid(); + fprintf(stdout, "%s\t0x%08x, 0x%08x\t", name, guid.d1, guid.d2); + PrintVTable(moduleInfos, reinterpret_cast(mgr), 30, '\t'); } // call reader