mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-14 19:15:05 -05:00
Merge branch 'main' of https://github.com/geode-sdk/sdk into main
This commit is contained in:
commit
be9d861596
5 changed files with 291 additions and 1 deletions
|
@ -633,6 +633,7 @@ class cocos2d::CCScheduler {
|
|||
auto scheduleSelector(cocos2d::SEL_SCHEDULE, cocos2d::CCObject*, float, unsigned int, float, bool) = mac 0x242b20;
|
||||
auto scheduleUpdateForTarget(cocos2d::CCObject*, int, bool) = mac 0x2438d0;
|
||||
auto unscheduleAllForTarget(cocos2d::CCObject*) = mac 0x243e40;
|
||||
auto unscheduleUpdateForTarget(cocos2d::CCObject const*) = mac 0x243c60;
|
||||
virtual auto update(float delta) = mac 0x2446d0;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,3 +8,11 @@ namespace geode::base {
|
|||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
namespace geode::cast {
|
||||
template <class After, class Before>
|
||||
After typeinfo_cast(Before ptr) {
|
||||
// yall have symbols smh
|
||||
return dynamic_cast<After>(ptr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
#include <mach-o/dyld.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
#include <cstring>
|
||||
|
||||
namespace geode {
|
||||
using dylib_t = void*;
|
||||
|
@ -21,4 +24,102 @@ namespace geode::base {
|
|||
|
||||
extern "C" inline uintptr_t _geode_ios_base() {
|
||||
return geode::base::get();
|
||||
}
|
||||
}
|
||||
|
||||
namespace geode::cast {
|
||||
using uinthalf_t = uint32_t;
|
||||
using inthalf_t = int32_t;
|
||||
|
||||
struct DummyClass {
|
||||
virtual ~DummyClass() {}
|
||||
};
|
||||
struct DummySingleClass : DummyClass {};
|
||||
struct DummyClass2 {};
|
||||
struct DummyMultipleClass : DummySingleClass, DummyClass2 {};
|
||||
|
||||
struct ClassTypeinfoType {
|
||||
void** m_typeinfoVtable;
|
||||
char const* m_typeinfoName;
|
||||
};
|
||||
|
||||
struct SingleClassTypeinfoType : ClassTypeinfoType {
|
||||
ClassTypeinfoType* m_baseClassTypeinfo;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct MultipleClassSingleEntryType {
|
||||
ClassTypeinfoType* m_baseClassTypeinfo;
|
||||
uint8_t m_visibilityFlag;
|
||||
inthalf_t m_offset;
|
||||
uint8_t m_padding[sizeof(inthalf_t) - 1];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
struct MultipleClassTypeinfoType : ClassTypeinfoType {
|
||||
uint32_t m_flags;
|
||||
uint32_t m_numBaseClass;
|
||||
MultipleClassSingleEntryType m_baseClasses[0x100];
|
||||
};
|
||||
|
||||
struct VtableTypeinfoType {
|
||||
inthalf_t m_offset;
|
||||
ClassTypeinfoType* m_typeinfo;
|
||||
};
|
||||
|
||||
struct VtableType {
|
||||
void* m_vtable[0x100];
|
||||
};
|
||||
|
||||
struct CompleteVtableType : VtableTypeinfoType, VtableType {};
|
||||
|
||||
inline void** typeinfoVtableOf(void* ptr) {
|
||||
auto vftable = *reinterpret_cast<VtableType**>(ptr);
|
||||
|
||||
auto typeinfoPtr = static_cast<VtableTypeinfoType*>(static_cast<CompleteVtableType*>(vftable));
|
||||
|
||||
return typeinfoPtr->m_typeinfo->m_typeinfoVtable;
|
||||
}
|
||||
|
||||
inline void* traverseTypeinfoFor(void* ptr, ClassTypeinfoType* typeinfo, char const* afterIdent) {
|
||||
DummySingleClass dummySingleClass;
|
||||
DummyMultipleClass dummyMultipleClass;
|
||||
|
||||
{
|
||||
auto optionIdent = typeinfo->m_typeinfoName;
|
||||
if (std::strcmp(optionIdent, afterIdent) == 0) {
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
if (typeinfo->m_typeinfoVtable == typeinfoVtableOf(&dummySingleClass)) {
|
||||
auto siTypeinfo = static_cast<SingleClassTypeinfoType*>(typeinfo);
|
||||
return traverseTypeinfoFor(ptr, siTypeinfo->m_baseClassTypeinfo, afterIdent);
|
||||
}
|
||||
else if (typeinfo->m_typeinfoVtable == typeinfoVtableOf(&dummyMultipleClass)) {
|
||||
auto vmiTypeinfo = static_cast<MultipleClassTypeinfoType*>(typeinfo);
|
||||
for (int i = 0; i < vmiTypeinfo->m_numBaseClass; ++i) {
|
||||
auto& entry = vmiTypeinfo->m_baseClasses[i];
|
||||
auto optionPtr = reinterpret_cast<std::byte*>(ptr) + entry.m_offset;
|
||||
auto ret = traverseTypeinfoFor(optionPtr, entry.m_baseClassTypeinfo, afterIdent);
|
||||
if (ret != nullptr) return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <class After, class Before>
|
||||
inline After typeinfo_cast(Before ptr) {
|
||||
static_assert(
|
||||
std::is_polymorphic_v<std::remove_pointer_t<Before>>,
|
||||
"Input is not a polymorphic type"
|
||||
);
|
||||
auto basePtr = dynamic_cast<void*>(ptr);
|
||||
auto vftable = *reinterpret_cast<VtableType**>(basePtr);
|
||||
auto typeinfo = static_cast<VtableTypeinfoType*>(static_cast<CompleteVtableType*>(vftable))->m_typeinfo;
|
||||
|
||||
auto afterTypeinfo = reinterpret_cast<ClassTypeinfoType const*>(&typeid(std::remove_pointer_t<After>));
|
||||
auto afterIdent = afterTypeinfo->m_typeinfoName;
|
||||
|
||||
return static_cast<After>(traverseTypeinfoFor(basePtr, typeinfo, afterIdent));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
#include <mach-o/dyld.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
#include <cstring>
|
||||
|
||||
namespace geode {
|
||||
using dylib_t = void*;
|
||||
struct PlatformInfo {
|
||||
|
@ -15,3 +19,101 @@ namespace geode::base {
|
|||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
namespace geode::cast {
|
||||
using uinthalf_t = uint32_t;
|
||||
using inthalf_t = int32_t;
|
||||
|
||||
struct DummyClass {
|
||||
virtual ~DummyClass() {}
|
||||
};
|
||||
struct DummySingleClass : DummyClass {};
|
||||
struct DummyClass2 {};
|
||||
struct DummyMultipleClass : DummySingleClass, DummyClass2 {};
|
||||
|
||||
struct ClassTypeinfoType {
|
||||
void** m_typeinfoVtable;
|
||||
char const* m_typeinfoName;
|
||||
};
|
||||
|
||||
struct SingleClassTypeinfoType : ClassTypeinfoType {
|
||||
ClassTypeinfoType* m_baseClassTypeinfo;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct MultipleClassSingleEntryType {
|
||||
ClassTypeinfoType* m_baseClassTypeinfo;
|
||||
uint8_t m_visibilityFlag;
|
||||
inthalf_t m_offset;
|
||||
uint8_t m_padding[sizeof(inthalf_t) - 1];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
struct MultipleClassTypeinfoType : ClassTypeinfoType {
|
||||
uint32_t m_flags;
|
||||
uint32_t m_numBaseClass;
|
||||
MultipleClassSingleEntryType m_baseClasses[0x100];
|
||||
};
|
||||
|
||||
struct VtableTypeinfoType {
|
||||
inthalf_t m_offset;
|
||||
ClassTypeinfoType* m_typeinfo;
|
||||
};
|
||||
|
||||
struct VtableType {
|
||||
void* m_vtable[0x100];
|
||||
};
|
||||
|
||||
struct CompleteVtableType : VtableTypeinfoType, VtableType {};
|
||||
|
||||
inline void** typeinfoVtableOf(void* ptr) {
|
||||
auto vftable = *reinterpret_cast<VtableType**>(ptr);
|
||||
|
||||
auto typeinfoPtr = static_cast<VtableTypeinfoType*>(static_cast<CompleteVtableType*>(vftable));
|
||||
|
||||
return typeinfoPtr->m_typeinfo->m_typeinfoVtable;
|
||||
}
|
||||
|
||||
inline void* traverseTypeinfoFor(void* ptr, ClassTypeinfoType* typeinfo, char const* afterIdent) {
|
||||
DummySingleClass dummySingleClass;
|
||||
DummyMultipleClass dummyMultipleClass;
|
||||
|
||||
{
|
||||
auto optionIdent = typeinfo->m_typeinfoName;
|
||||
if (std::strcmp(optionIdent, afterIdent) == 0) {
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
if (typeinfo->m_typeinfoVtable == typeinfoVtableOf(&dummySingleClass)) {
|
||||
auto siTypeinfo = static_cast<SingleClassTypeinfoType*>(typeinfo);
|
||||
return traverseTypeinfoFor(ptr, siTypeinfo->m_baseClassTypeinfo, afterIdent);
|
||||
}
|
||||
else if (typeinfo->m_typeinfoVtable == typeinfoVtableOf(&dummyMultipleClass)) {
|
||||
auto vmiTypeinfo = static_cast<MultipleClassTypeinfoType*>(typeinfo);
|
||||
for (int i = 0; i < vmiTypeinfo->m_numBaseClass; ++i) {
|
||||
auto& entry = vmiTypeinfo->m_baseClasses[i];
|
||||
auto optionPtr = reinterpret_cast<std::byte*>(ptr) + entry.m_offset;
|
||||
auto ret = traverseTypeinfoFor(optionPtr, entry.m_baseClassTypeinfo, afterIdent);
|
||||
if (ret != nullptr) return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <class After, class Before>
|
||||
inline After typeinfo_cast(Before ptr) {
|
||||
static_assert(
|
||||
std::is_polymorphic_v<std::remove_pointer_t<Before>>,
|
||||
"Input is not a polymorphic type"
|
||||
);
|
||||
auto basePtr = dynamic_cast<void*>(ptr);
|
||||
auto vftable = *reinterpret_cast<VtableType**>(basePtr);
|
||||
auto typeinfo = static_cast<VtableTypeinfoType*>(static_cast<CompleteVtableType*>(vftable))->m_typeinfo;
|
||||
|
||||
auto afterTypeinfo = reinterpret_cast<ClassTypeinfoType const*>(&typeid(std::remove_pointer_t<After>));
|
||||
auto afterIdent = afterTypeinfo->m_typeinfoName;
|
||||
|
||||
return static_cast<After>(traverseTypeinfoFor(basePtr, typeinfo, afterIdent));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
#include <meta/membercall.hpp>
|
||||
#include <meta/thiscall.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
#include <cstring>
|
||||
|
||||
namespace geode {
|
||||
struct PlatformInfo {
|
||||
HMODULE m_hmod;
|
||||
|
@ -23,3 +27,77 @@ namespace geode::base {
|
|||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace geode::cast {
|
||||
struct TypeDescriptorType {
|
||||
void* m_typeinfoTable;
|
||||
int32_t m_spare;
|
||||
char m_typeDescriptorName[0x100];
|
||||
};
|
||||
|
||||
struct ClassDescriptorType;
|
||||
|
||||
struct BaseClassDescriptorType {
|
||||
TypeDescriptorType* m_typeDescriptor;
|
||||
int32_t m_numContainedBases;
|
||||
int32_t m_memberDisplacement[3];
|
||||
int32_t m_attributes;
|
||||
ClassDescriptorType* m_classDescriptor;
|
||||
};
|
||||
|
||||
struct ClassDescriptorType {
|
||||
int32_t m_signature;
|
||||
int32_t m_attributes;
|
||||
int32_t m_numBaseClasses;
|
||||
BaseClassDescriptorType** m_baseClassArray;
|
||||
};
|
||||
|
||||
struct CompleteLocatorType {
|
||||
int32_t m_signature;
|
||||
int32_t m_offset;
|
||||
int32_t m_cdOffset;
|
||||
TypeDescriptorType* m_typeDescriptor;
|
||||
ClassDescriptorType* m_classDescriptor;
|
||||
};
|
||||
|
||||
struct MetaPointerType {
|
||||
CompleteLocatorType* m_completeLocator;
|
||||
};
|
||||
|
||||
struct VftableType {
|
||||
void* m_vftable[0x100];
|
||||
};
|
||||
|
||||
struct CompleteVftableType : MetaPointerType, VftableType {};
|
||||
|
||||
template <class After, class Before>
|
||||
inline After typeinfo_cast(Before ptr) {
|
||||
static_assert(
|
||||
std::is_polymorphic_v<std::remove_pointer_t<Before>>,
|
||||
"Input is not a polymorphic type"
|
||||
);
|
||||
|
||||
auto basePtr = dynamic_cast<void*>(ptr);
|
||||
auto vftable = *reinterpret_cast<VftableType**>(basePtr);
|
||||
|
||||
auto metaPtr = static_cast<MetaPointerType*>(static_cast<CompleteVftableType*>(vftable));
|
||||
|
||||
auto afterDesc = reinterpret_cast<TypeDescriptorType const*>(&typeid(std::remove_pointer_t<After>));
|
||||
|
||||
auto afterIdent = static_cast<char const*>(afterDesc->m_typeDescriptorName);
|
||||
|
||||
auto classDesc = metaPtr->m_completeLocator->m_classDescriptor;
|
||||
for (int32_t i = 0; i < classDesc->m_numBaseClasses; ++i) {
|
||||
auto optionIdent = static_cast<char const*>(classDesc->m_baseClassArray[i]->m_typeDescriptor->m_typeDescriptorName);
|
||||
auto optionOffset = classDesc->m_baseClassArray[i]->m_memberDisplacement[0];
|
||||
|
||||
if (std::strcmp(afterIdent, optionIdent) == 0) {
|
||||
auto afterPtr = reinterpret_cast<std::byte*>(basePtr) + optionOffset;
|
||||
return reinterpret_cast<After>(afterPtr);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue