diff --git a/bindings/GeometryDash.bro b/bindings/GeometryDash.bro index 9c735cae..ea4ee79b 100644 --- a/bindings/GeometryDash.bro +++ b/bindings/GeometryDash.bro @@ -1156,9 +1156,9 @@ class EditorPauseLayer : CCBlockLayer, FLAlertLayerProtocol { void doResetUnused() = win 0x165070; bool m_saved; - PAD = mac 0x8, win 0x4; - CCMenuItemSpriteExtra* m_button0; - CCMenuItemSpriteExtra* m_button1; + PAD = mac 0x4, win 0x4; + CCMenuItemSpriteExtra* m_guidelinesOffButton; + CCMenuItemSpriteExtra* m_guidelinesOnButton; LevelEditorLayer* m_editorLayer; } diff --git a/loader/include/Geode/platform/ItaniumCast.hpp b/loader/include/Geode/platform/ItaniumCast.hpp new file mode 100644 index 00000000..93cd024e --- /dev/null +++ b/loader/include/Geode/platform/ItaniumCast.hpp @@ -0,0 +1,127 @@ +#pragma once + +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(ptr); + + auto typeinfoPtr = + static_cast(static_cast(vftable)); + + return typeinfoPtr->m_typeinfo->m_typeinfoVtable; + } + + inline void* traverseTypeinfoFor( + void* ptr, ClassTypeinfoType const* 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(typeinfo); + return traverseTypeinfoFor(ptr, siTypeinfo->m_baseClassTypeinfo, afterIdent); + } + else if (typeinfo->m_typeinfoVtable == typeinfoVtableOf(&dummyMultipleClass)) { + auto vmiTypeinfo = static_cast(typeinfo); + for (int i = 0; i < vmiTypeinfo->m_numBaseClass; ++i) { + auto& entry = vmiTypeinfo->m_baseClasses[i]; + auto optionPtr = reinterpret_cast(ptr) + entry.m_offset; + auto ret = traverseTypeinfoFor(optionPtr, entry.m_baseClassTypeinfo, afterIdent); + if (ret != nullptr) return ret; + } + } + + return nullptr; + } + + inline void* typeinfoCastInternal(void* ptr, ClassTypeinfoType const* beforeTypeinfo, ClassTypeinfoType const* afterTypeinfo, size_t hint) { + // we're not using either because uhhh idk + // hint is for diamond inheritance iirc which is never + // used in gd, so should be pretty safe to ignore + if (!ptr) { + return nullptr; + } + + (void)beforeTypeinfo; + (void)hint; + + auto vftable = *reinterpret_cast(ptr); + auto dataPointer = static_cast(static_cast(vftable)); + auto typeinfo = dataPointer->m_typeinfo; + auto basePtr = static_cast(ptr) + dataPointer->m_offset; + + auto afterIdent = afterTypeinfo->m_typeinfoName; + + return traverseTypeinfoFor(basePtr, typeinfo, afterIdent); + } + + template + inline After typeinfo_cast(Before ptr) { + static_assert( + std::is_polymorphic_v> && std::is_polymorphic_v>, + "Input is not a polymorphic type" + ); + if (!ptr) { + return static_cast(nullptr); + } + + auto beforeTypeinfo = reinterpret_cast(&typeid(std::remove_pointer_t)); + auto afterTypeinfo = reinterpret_cast(&typeid(std::remove_pointer_t)); + return static_cast(typeinfoCastInternal(ptr, beforeTypeinfo, afterTypeinfo, 0)); + } +} \ No newline at end of file diff --git a/loader/include/Geode/platform/ios.hpp b/loader/include/Geode/platform/ios.hpp index 0367ea25..b93f840c 100644 --- a/loader/include/Geode/platform/ios.hpp +++ b/loader/include/Geode/platform/ios.hpp @@ -4,6 +4,7 @@ #include #include #include +#include "ItaniumCast.hpp" namespace geode { using dylib_t = void*; @@ -23,110 +24,3 @@ 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(ptr); - - auto typeinfoPtr = - static_cast(static_cast(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(typeinfo); - return traverseTypeinfoFor(ptr, siTypeinfo->m_baseClassTypeinfo, afterIdent); - } - else if (typeinfo->m_typeinfoVtable == typeinfoVtableOf(&dummyMultipleClass)) { - auto vmiTypeinfo = static_cast(typeinfo); - for (int i = 0; i < vmiTypeinfo->m_numBaseClass; ++i) { - auto& entry = vmiTypeinfo->m_baseClasses[i]; - auto optionPtr = reinterpret_cast(ptr) + entry.m_offset; - auto ret = traverseTypeinfoFor(optionPtr, entry.m_baseClassTypeinfo, afterIdent); - if (ret != nullptr) return ret; - } - } - - return nullptr; - } - - template - inline After typeinfo_cast(Before ptr) { - static_assert( - std::is_polymorphic_v>, "Input is not a polymorphic type" - ); - auto basePtr = dynamic_cast(ptr); - auto vftable = *reinterpret_cast(basePtr); - auto typeinfo = - static_cast(static_cast(vftable))->m_typeinfo; - - auto afterTypeinfo = - reinterpret_cast(&typeid(std::remove_pointer_t)); - auto afterIdent = afterTypeinfo->m_typeinfoName; - - return static_cast(traverseTypeinfoFor(basePtr, typeinfo, afterIdent)); - } -} diff --git a/loader/include/Geode/platform/macos.hpp b/loader/include/Geode/platform/macos.hpp index 4c351cd7..806a3329 100644 --- a/loader/include/Geode/platform/macos.hpp +++ b/loader/include/Geode/platform/macos.hpp @@ -4,6 +4,7 @@ #include #include #include +#include "ItaniumCast.hpp" namespace geode { using dylib_t = void*; @@ -19,121 +20,3 @@ 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(ptr); - - auto typeinfoPtr = - static_cast(static_cast(vftable)); - - return typeinfoPtr->m_typeinfo->m_typeinfoVtable; - } - - inline void* traverseTypeinfoFor( - void* ptr, ClassTypeinfoType const* 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(typeinfo); - return traverseTypeinfoFor(ptr, siTypeinfo->m_baseClassTypeinfo, afterIdent); - } - else if (typeinfo->m_typeinfoVtable == typeinfoVtableOf(&dummyMultipleClass)) { - auto vmiTypeinfo = static_cast(typeinfo); - for (int i = 0; i < vmiTypeinfo->m_numBaseClass; ++i) { - auto& entry = vmiTypeinfo->m_baseClasses[i]; - auto optionPtr = reinterpret_cast(ptr) + entry.m_offset; - auto ret = traverseTypeinfoFor(optionPtr, entry.m_baseClassTypeinfo, afterIdent); - if (ret != nullptr) return ret; - } - } - - return nullptr; - } - - inline void* typeinfoCastInternal(void* ptr, ClassTypeinfoType const* beforeTypeinfo, ClassTypeinfoType const* afterTypeinfo, size_t hint) { - // we're not using either because uhhh idk - // hint is for diamond inheritance iirc which is never - // used in gd, so should be pretty safe to ignore - (void)beforeTypeinfo; - (void)hint; - - auto vftable = *reinterpret_cast(ptr); - auto dataPointer = static_cast(static_cast(vftable)); - auto typeinfo = dataPointer->m_typeinfo; - auto basePtr = static_cast(ptr) + dataPointer->m_offset; - - auto afterIdent = afterTypeinfo->m_typeinfoName; - - return traverseTypeinfoFor(basePtr, typeinfo, afterIdent); - } - - template - inline After typeinfo_cast(Before ptr) { - static_assert( - std::is_polymorphic_v> && std::is_polymorphic_v>, - "Input is not a polymorphic type" - ); - auto beforeTypeinfo = reinterpret_cast(&typeid(std::remove_pointer_t)); - auto afterTypeinfo = reinterpret_cast(&typeid(std::remove_pointer_t)); - return static_cast(typeinfoCastInternal(ptr, beforeTypeinfo, afterTypeinfo, 0)); - } -} diff --git a/loader/src/loader/Index.cpp b/loader/src/loader/Index.cpp index e9488aca..4d5c0cda 100644 --- a/loader/src/loader/Index.cpp +++ b/loader/src/loader/Index.cpp @@ -135,7 +135,7 @@ static Result<> flattenGithubRepo(ghc::filesystem::path const& dir) { // github zipballs have a folder at root, but we already have our // own folder for that so let's just bring everything from that // folder to ours - GEODE_UNWRAP_INTO(auto files, file::listFiles(dir)); + GEODE_UNWRAP_INTO(auto files, file::readDirectory(dir)); try { // only flatten if there is only one file and it's a directory if (files.size() == 1 && ghc::filesystem::is_directory(files[0])) {