added class dependency generator for IDA scripts, so you can simply copy paste the generated header file and it should compile fine (more to test when I have time)

This commit is contained in:
EricPlayZ
2025-04-04 01:55:30 +03:00
parent ef14ed13c5
commit 5564beddb8
2 changed files with 115 additions and 56 deletions

View File

@ -1,4 +1,5 @@
import os import os
from typing import Optional
from ExportClassH import JSONGen, Utils, Config from ExportClassH import JSONGen, Utils, Config
from ExportClassH.ClassDefs import ParsedClass, ParsedFunction, ParsedClassVar from ExportClassH.ClassDefs import ParsedClass, ParsedFunction, ParsedClassVar
@ -123,16 +124,18 @@ def GenerateClassContent(targetClass: ParsedClass, indentLevel: str) -> list[str
hasAnyContent = bool(contentLines) hasAnyContent = bool(contentLines)
# Insert access specifier if needed # Insert access specifier if needed
if not firstVarOrFuncAccess and targetClass.type == "class": if not firstVarOrFuncAccess and targetClass.type == "class" and hasAnyContent:
contentLines.insert(1, f"{indentLevel}public:") contentLines.insert(1, f"{indentLevel}public:")
childClassDefinitions: list[str] = [] childClassDefinitions: list[str] = []
for parsedClass in targetClass.childClasses.values(): childClassesLen = len(targetClass.childClasses.values())
classDefinition = GenerateClassDefinition(parsedClass, indentLevel + "\t") for i, parsedClass in enumerate(targetClass.childClasses.values()):
classContent = GenerateClassContent(parsedClass, indentLevel + "\t") childClassDefinition = GenerateClassDefinition(parsedClass, indentLevel + "\t")
childClasSContent = GenerateClassContent(parsedClass, indentLevel + "\t")
if i != 0 and (i != childClassesLen or hasAnyContent):
childClassDefinitions.append("")
childClassDefinitions.extend(classDefinition[:len(classDefinition) - 1] + classContent + classDefinition[len(classDefinition) - 1:]) childClassDefinitions.extend(childClassDefinition[:len(childClassDefinition) - 1] + childClasSContent + childClassDefinition[len(childClassDefinition) - 1:])
childClassDefinitions.append("")
if (hasAnyContent): if (hasAnyContent):
contentLines.insert(0, "#pragma region GENERATED by ExportClassToCPPH.py") contentLines.insert(0, "#pragma region GENERATED by ExportClassToCPPH.py")
@ -154,11 +157,49 @@ def GenerateClassDefinition(targetClass: ParsedClass, indentLevel: str, forwardD
classDefLines.append(f"{indentLevel}}};") classDefLines.append(f"{indentLevel}}};")
return classDefLines return classDefLines
def GenerateClassDependencyDefinition(classDependency: str, indentLevel: str, parsedClassesDict: dict[str, ParsedClass]) -> list[str]:
"""Generate a class definition from a list of methods."""
classDependencyList = Utils.SplitByClassSeparatorOutsideTemplates(classDependency)
classDependencyListLen = len(classDependencyList)
alreadyCheckedDependenciesList: list[str] = []
currentClassDependency: Optional[ParsedClass] = None
classDefLines: list[str] = []
classDefBracketClosingLines: list[str] = []
for i, dependency in enumerate(classDependencyList, 1):
alreadyCheckedDependenciesList.append(dependency)
if not currentClassDependency:
currentClassDependency = parsedClassesDict.get(dependency)
if not currentClassDependency:
continue
else:
currentClassDependency = currentClassDependency.childClasses.get("::".join(alreadyCheckedDependenciesList))
if not currentClassDependency:
continue
canCurrentClassHaveEnclosure = currentClassDependency.type != "enum" and classDependencyListLen > 1 and i != classDependencyListLen
classDefLines.append(f"{indentLevel}{currentClassDependency.type} {currentClassDependency.name}{' {' if canCurrentClassHaveEnclosure else ';'}")
if canCurrentClassHaveEnclosure:
if currentClassDependency.type == "class":
classDefLines.append(f"{indentLevel}public:")
classDefBracketClosingLines.append(f"{indentLevel}}};")
indentLevel += "\t"
classDefLines.extend(classDefBracketClosingLines)
return classDefLines
def GenerateHeaderCode(targetClass: ParsedClass, parsedClassesDict: dict[str, ParsedClass]) -> list[str]: def GenerateHeaderCode(targetClass: ParsedClass, parsedClassesDict: dict[str, ParsedClass]) -> list[str]:
"""Generate header code for a standard class (not nested).""" """Generate header code for a standard class (not nested)."""
global indentLevel global indentLevel
fullClassDefinition: list[str] = [] fullClassDefinition: list[str] = []
for classDependency in targetClass.classDependencies:
classDependencyDefinition = GenerateClassDependencyDefinition(classDependency, indentLevel, parsedClassesDict)
fullClassDefinition.extend(classDependencyDefinition)
fullClassDefinition.append("")
for namespace in targetClass.parentNamespaces: for namespace in targetClass.parentNamespaces:
fullClassDefinition.append(f"{indentLevel}namespace {namespace} {{") fullClassDefinition.append(f"{indentLevel}namespace {namespace} {{")
indentLevel += "\t" indentLevel += "\t"
@ -241,10 +282,10 @@ def ExportClassHeaders():
parsedClassesDict = JSONGen.GetAllParsedClasses() parsedClassesDict = JSONGen.GetAllParsedClasses()
JSONGen.MoveChildClasses(parsedClassesDict) JSONGen.MoveChildClasses(parsedClassesDict)
for (parsedClassName, parsedClass) in parsedClassesDict.items(): for parsedClass in parsedClassesDict.values():
headerCodeLines = GenerateHeaderCode(parsedClass, parsedClassesDict) headerCodeLines = GenerateHeaderCode(parsedClass, parsedClassesDict)
headerCode: str = "\n".join(headerCodeLines) headerCode: str = "\n".join(headerCodeLines)
WriteHeaderToFile(parsedClass, headerCode, f"{parsedClass.name}.h" if parsedClass.type != "namespace" else "") WriteHeaderToFile(parsedClass, headerCode, f"{parsedClass.name}.h" if parsedClass.type != "namespace" else "")
# classDefinition = GenerateClassDefinition(parsedClass, indentLevel) # classDefinition = GenerateClassDefinition(parsedClass, indentLevel)
# classContent = GenerateClassContent(parsedClass, indentLevel) # classContent = GenerateClassContent(parsedClass, indentLevel)

View File

@ -1,6 +1,72 @@
#pragma once #pragma once
#include <EGSDK\Imports.h> #include <EGSDK\Imports.h>
namespace cbs {
class CPcidPath;
};
namespace cbs {
class CEntity;
};
namespace cbs {
class CEntityPointer;
};
namespace cbs {
class CPointer;
};
namespace cbs {
class CPcidPathView;
};
namespace cbs {
enum pcid_t;
};
namespace ttl {
class string_const;
};
class SpawnContext;
class ILevel;
class mtx34;
namespace Replication {
class CreateObjectOptions;
};
struct PresetId;
namespace ttl {
class set;
};
class CRTTIField;
namespace cbs {
struct WorldIndex;
};
namespace ttl {
class string_base;
};
namespace cbs {
class PrefabEntityComponent;
};
namespace ttl {
class span;
};
namespace ttl {
class vector;
};
namespace cbs { namespace cbs {
#pragma region GENERATED by ExportClassToCPPH.py #pragma region GENERATED by ExportClassToCPPH.py
enum pcid_t; enum pcid_t;
@ -95,10 +161,8 @@ namespace cbs {
#pragma endregion #pragma endregion
}; };
public:
class CPointer; class CPointer;
public:
class CSystemWorldData; class CSystemWorldData;
class CBaseObject { class CBaseObject {
@ -675,7 +739,6 @@ namespace cbs {
public: public:
#pragma region GENERATED by ExportClassToCPPH.py #pragma region GENERATED by ExportClassToCPPH.py
struct ResultType; struct ResultType;
GAME_IMPORT CEntityGenerator(cbs::CEntityGenerator&&); GAME_IMPORT CEntityGenerator(cbs::CEntityGenerator&&);
GAME_IMPORT CEntityGenerator(cbs::Prefab const*, SpawnContext&); GAME_IMPORT CEntityGenerator(cbs::Prefab const*, SpawnContext&);
GAME_IMPORT CEntityGenerator(); GAME_IMPORT CEntityGenerator();
@ -1723,7 +1786,6 @@ namespace cbs {
struct SVirtualField; struct SVirtualField;
enum ESavePrefabHierarchy; enum ESavePrefabHierarchy;
GAME_IMPORT static char const* const EXTDTL_FLT_POSTFIX; GAME_IMPORT static char const* const EXTDTL_FLT_POSTFIX;
GAME_IMPORT static char const* const EXT_FLT_POSTFIX; GAME_IMPORT static char const* const EXT_FLT_POSTFIX;
GAME_IMPORT static char const* const FLT_POSTFIX; GAME_IMPORT static char const* const FLT_POSTFIX;
@ -2658,7 +2720,6 @@ namespace cbs {
GAME_IMPORT bool IsEmpty(); GAME_IMPORT bool IsEmpty();
#pragma endregion #pragma endregion
}; };
GAME_IMPORT static uint32_t const UNAVAILABLE_IDX; GAME_IMPORT static uint32_t const UNAVAILABLE_IDX;
GAME_IMPORT static bool __INTERNAL_crtti_fields_initialized_field; GAME_IMPORT static bool __INTERNAL_crtti_fields_initialized_field;
GAME_IMPORT static class rtti::Type& m_RTTI; GAME_IMPORT static class rtti::Type& m_RTTI;
@ -2885,7 +2946,6 @@ namespace cbs {
#pragma endregion #pragma endregion
}; };
public:
class ICallable; class ICallable;
struct WorldIndex; struct WorldIndex;
@ -3230,7 +3290,6 @@ namespace cbs {
struct SAudioHook; struct SAudioHook;
struct SPlayingEventParams; struct SPlayingEventParams;
GAME_IMPORT static bool __INTERNAL_crtti_fields_initialized_field; GAME_IMPORT static bool __INTERNAL_crtti_fields_initialized_field;
GAME_IMPORT static class rtti::Type& m_RTTI; GAME_IMPORT static class rtti::Type& m_RTTI;
GAME_IMPORT static class cbs::CComponentSystem<class cbs::CoAudioEventControl, class cbs::CSystemWorldData<class cbs::CoAudioEventControl>>& s_System; GAME_IMPORT static class cbs::CComponentSystem<class cbs::CoAudioEventControl, class cbs::CSystemWorldData<class cbs::CoAudioEventControl>>& s_System;
@ -3726,7 +3785,6 @@ namespace cbs {
public: public:
#pragma region GENERATED by ExportClassToCPPH.py #pragma region GENERATED by ExportClassToCPPH.py
struct PinnedPointer; struct PinnedPointer;
GAME_IMPORT class cbs::CBaseObject* AllocateComponent(cbs::WorldIndex, cbs::SystemIndex); GAME_IMPORT class cbs::CBaseObject* AllocateComponent(cbs::WorldIndex, cbs::SystemIndex);
GAME_IMPORT void DeallocateComponent(cbs::detail::Handle); GAME_IMPORT void DeallocateComponent(cbs::detail::Handle);
GAME_IMPORT class cbs::CBaseObject* GetComponentImpl(cbs::detail::Handle); GAME_IMPORT class cbs::CBaseObject* GetComponentImpl(cbs::detail::Handle);
@ -4006,7 +4064,6 @@ namespace cbs {
#pragma endregion #pragma endregion
}; };
public:
class ComponentPoolEnumerator; class ComponentPoolEnumerator;
enum ComponentPoolEnumeratorMode; enum ComponentPoolEnumeratorMode;
@ -4638,7 +4695,6 @@ namespace cbs {
#pragma endregion #pragma endregion
}; };
public:
class CAbstractSystem; class CAbstractSystem;
class CEntityMgr { class CEntityMgr {
@ -4665,17 +4721,14 @@ namespace cbs {
#pragma endregion #pragma endregion
}; };
public:
class CComponentSystem; class CComponentSystem;
public:
class CComponentBaseSystem; class CComponentBaseSystem;
struct SPrefabConfigurationOverrideInfo; struct SPrefabConfigurationOverrideInfo;
enum VisitResult; enum VisitResult;
public:
class CSystem; class CSystem;
class PrefabAreaComponent { class PrefabAreaComponent {
@ -6009,7 +6062,6 @@ namespace cbs {
GAME_IMPORT virtual enum cbs::VisitResult Visit(cbs::PrefabEntityComponentHierarchy const&); GAME_IMPORT virtual enum cbs::VisitResult Visit(cbs::PrefabEntityComponentHierarchy const&);
#pragma endregion #pragma endregion
}; };
GAME_IMPORT PrefabDataRetrieval(cbs::Prefab const*, cbs::CPcidPath const&); GAME_IMPORT PrefabDataRetrieval(cbs::Prefab const*, cbs::CPcidPath const&);
GAME_IMPORT void DumpResults(fs::ifile&) const; GAME_IMPORT void DumpResults(fs::ifile&) const;
GAME_IMPORT bool Execute(); GAME_IMPORT bool Execute();
@ -9504,11 +9556,9 @@ namespace cbs {
GAME_IMPORT void Send() const; GAME_IMPORT void Send() const;
#pragma endregion #pragma endregion
}; };
}; };
namespace msg { namespace msg {
public:
class SingleMessagePipeOut; class SingleMessagePipeOut;
class IMessageData { class IMessageData {
@ -10331,7 +10381,6 @@ namespace cbs {
#pragma endregion #pragma endregion
}; };
public:
class MessagePipeId; class MessagePipeId;
class MessageTransmitterPipe { class MessageTransmitterPipe {
@ -10427,14 +10476,11 @@ namespace cbs {
GAME_IMPORT virtual void OnReceive(CRTTIObject*, cbs::msg::Message const&); GAME_IMPORT virtual void OnReceive(CRTTIObject*, cbs::msg::Message const&);
#pragma endregion #pragma endregion
}; };
}; };
namespace detail { namespace detail {
struct MessagePipeReceiver; struct MessagePipeReceiver;
}; };
}; };
namespace ps { namespace ps {
@ -10524,7 +10570,6 @@ namespace cbs {
public: public:
#pragma region GENERATED by ExportClassToCPPH.py #pragma region GENERATED by ExportClassToCPPH.py
enum GUARD_STATE; enum GUARD_STATE;
GAME_IMPORT static bool s_ForceBakeData; GAME_IMPORT static bool s_ForceBakeData;
GAME_IMPORT static enum cbs::ps::CStorage::GUARD_STATE s_Guard; GAME_IMPORT static enum cbs::ps::CStorage::GUARD_STATE s_Guard;
GAME_IMPORT static int s_StaticEntitiesRestoreDefaultsCounter; GAME_IMPORT static int s_StaticEntitiesRestoreDefaultsCounter;
@ -10872,16 +10917,13 @@ namespace cbs {
struct FromStringOptions; struct FromStringOptions;
enum EStringPathFormat; enum EStringPathFormat;
GAME_IMPORT static class cbs::ps::IStorage* GetInstance(); GAME_IMPORT static class cbs::ps::IStorage* GetInstance();
#pragma endregion #pragma endregion
}; };
enum ReplicationRule; enum ReplicationRule;
public:
class CStorageReplicator; class CStorageReplicator;
}; };
namespace prefabs { namespace prefabs {
@ -10890,7 +10932,6 @@ namespace cbs {
public: public:
#pragma region GENERATED by ExportClassToCPPH.py #pragma region GENERATED by ExportClassToCPPH.py
struct ValueView; struct ValueView;
private: private:
GAME_IMPORT GamePrefabValuesContainer(void*); GAME_IMPORT GamePrefabValuesContainer(void*);
public: public:
@ -10936,11 +10977,9 @@ namespace cbs {
namespace impl { namespace impl {
#pragma region GENERATED by ExportClassToCPPH.py #pragma region GENERATED by ExportClassToCPPH.py
struct MemoryDesc; struct MemoryDesc;
GAME_IMPORT void DumpPrefabElementPaths(CLevel const*); GAME_IMPORT void DumpPrefabElementPaths(CLevel const*);
#pragma endregion #pragma endregion
}; };
GAME_IMPORT uint64_t GTotalApplyValuesTime; GAME_IMPORT uint64_t GTotalApplyValuesTime;
GAME_IMPORT uint64_t GTotalCreatePVCTime; GAME_IMPORT uint64_t GTotalCreatePVCTime;
@ -10973,7 +11012,6 @@ namespace cbs {
#pragma endregion #pragma endregion
}; };
public:
class IPropertySet; class IPropertySet;
class IProperty { class IProperty {
@ -10994,13 +11032,11 @@ namespace cbs {
}; };
struct PropertyId; struct PropertyId;
}; };
namespace Call { namespace Call {
#pragma region GENERATED by ExportClassToCPPH.py #pragma region GENERATED by ExportClassToCPPH.py
enum TYPE; enum TYPE;
GAME_IMPORT static class IRTTIEnumerationTyped<enum cbs::Call::TYPE> const* GetRTTI(); GAME_IMPORT static class IRTTIEnumerationTyped<enum cbs::Call::TYPE> const* GetRTTI();
#pragma endregion #pragma endregion
}; };
@ -11031,62 +11067,47 @@ namespace cbs {
namespace EAreaType { namespace EAreaType {
#pragma region GENERATED by ExportClassToCPPH.py #pragma region GENERATED by ExportClassToCPPH.py
enum TYPE; enum TYPE;
GAME_IMPORT static class IRTTIEnumerationTyped<enum cbs::simple::EAreaType::TYPE> const* GetRTTI(); GAME_IMPORT static class IRTTIEnumerationTyped<enum cbs::simple::EAreaType::TYPE> const* GetRTTI();
#pragma endregion #pragma endregion
}; };
namespace FRendering { namespace FRendering {
enum TYPE; enum TYPE;
}; };
}; };
namespace contracts { namespace contracts {
public:
class ApiFindComponent; class ApiFindComponent;
public:
class ApiFindComponentExact; class ApiFindComponentExact;
public:
class ApiGatherComponents; class ApiGatherComponents;
public:
class ApiGetInterface; class ApiGetInterface;
public:
class ApiInvalidatePointer; class ApiInvalidatePointer;
public:
class ApiComponentOnEntityChanged; class ApiComponentOnEntityChanged;
public:
class ApiModifyMessagePipeReceivers; class ApiModifyMessagePipeReceivers;
public:
class ApiEntityInterfaceChainAccess; class ApiEntityInterfaceChainAccess;
}; };
namespace EActivityState { namespace EActivityState {
#pragma region GENERATED by ExportClassToCPPH.py #pragma region GENERATED by ExportClassToCPPH.py
enum TYPE; enum TYPE;
GAME_IMPORT static class IRTTIEnumerationTyped<enum cbs::EActivityState::TYPE> const* GetRTTI(); GAME_IMPORT static class IRTTIEnumerationTyped<enum cbs::EActivityState::TYPE> const* GetRTTI();
#pragma endregion #pragma endregion
}; };
namespace detail { namespace detail {
enum Handle; enum Handle;
}; };
namespace FComponent { namespace FComponent {
#pragma region GENERATED by ExportClassToCPPH.py #pragma region GENERATED by ExportClassToCPPH.py
enum TYPE; enum TYPE;
GAME_IMPORT static class IRTTIEnumerationTyped<enum cbs::FComponent::TYPE> const* GetRTTI(); GAME_IMPORT static class IRTTIEnumerationTyped<enum cbs::FComponent::TYPE> const* GetRTTI();
#pragma endregion #pragma endregion
}; };
@ -11094,7 +11115,6 @@ namespace cbs {
namespace FEntity { namespace FEntity {
#pragma region GENERATED by ExportClassToCPPH.py #pragma region GENERATED by ExportClassToCPPH.py
enum TYPE; enum TYPE;
GAME_IMPORT static class IRTTIEnumerationTyped<enum cbs::FEntity::TYPE> const* GetRTTI(); GAME_IMPORT static class IRTTIEnumerationTyped<enum cbs::FEntity::TYPE> const* GetRTTI();
#pragma endregion #pragma endregion
}; };
@ -11109,9 +11129,7 @@ namespace cbs {
GAME_IMPORT void* Reallocate(cbs::memory::Category, void*, uint64_t); GAME_IMPORT void* Reallocate(cbs::memory::Category, void*, uint64_t);
#pragma endregion #pragma endregion
}; };
}; };
GAME_IMPORT class cbs::PrefabManager* g_PrefabManager; GAME_IMPORT class cbs::PrefabManager* g_PrefabManager;
GAME_IMPORT bool operator==(cbs::CPcidPath const&, cbs::CPcidPath const&); GAME_IMPORT bool operator==(cbs::CPcidPath const&, cbs::CPcidPath const&);