diff --git a/loader/include/Geode/Enums.hpp b/loader/include/Geode/Enums.hpp index 69040663..5a60b501 100644 --- a/loader/include/Geode/Enums.hpp +++ b/loader/include/Geode/Enums.hpp @@ -1,6 +1,8 @@ #pragma once -using TodoReturn = void; +struct TodoReturnPlaceholder {}; + +using TodoReturn = TodoReturnPlaceholder; // thanks pie enum class SearchType { diff --git a/loader/include/Geode/modify/Modify.hpp b/loader/include/Geode/modify/Modify.hpp index 0f38b239..fb11aa15 100644 --- a/loader/include/Geode/modify/Modify.hpp +++ b/loader/include/Geode/modify/Modify.hpp @@ -1,6 +1,7 @@ #pragma once #include "AsStaticFunction.hpp" #include "Field.hpp" +#include #include "IDManager.hpp" #include @@ -8,28 +9,36 @@ #include #include -#define GEODE_APPLY_MODIFY_FOR_FUNCTION(AddressInline_, Convention_, ClassName_, FunctionName_, ...) \ - do { \ - if constexpr (Unique::different< \ - Resolve<__VA_ARGS__>::func(&Base::FunctionName_), \ - Resolve<__VA_ARGS__>::func(&Derived::FunctionName_)>()) { \ - static auto address = AddressInline_; \ - if (address == 0) { \ - log::error( \ - "Address of {} returned nullptr, can't hook", #ClassName_ "::" #FunctionName_ \ - ); \ - break; \ - } \ - auto hook = Hook::create( \ - reinterpret_cast(address), \ - AsStaticFunction_##FunctionName_< \ - Derived, \ - decltype(Resolve<__VA_ARGS__>::func(&Derived::FunctionName_))>::value, \ - #ClassName_ "::" #FunctionName_, \ - tulip::hook::TulipConvention::Convention_ \ - ); \ - this->m_hooks[#ClassName_ "::" #FunctionName_] = hook; \ - } \ +#define GEODE_APPLY_MODIFY_FOR_FUNCTION(AddressInline_, Convention_, ClassName_, FunctionName_, ...) \ + do { \ + static auto constexpr different = Unique::different< \ + Resolve<__VA_ARGS__>::func(&Base::FunctionName_), \ + Resolve<__VA_ARGS__>::func(&Derived::FunctionName_) \ + >(); \ + using BaseFuncType = decltype(Resolve<__VA_ARGS__>::func(&Base::FunctionName_)); \ + using DerivedFuncType = decltype(Resolve<__VA_ARGS__>::func(&Derived::FunctionName_)); \ + if constexpr (different) { \ + static auto address = AddressInline_; \ + static_assert(!different || !std::is_same_v::type, TodoReturn>, \ + "Function" #ClassName_ "::" #FunctionName_ " has a TodoReturn type, " \ + "please fix it by editing the bindings." \ + ); \ + if (address == 0) { \ + log::error( \ + "Address of {} returned nullptr, can't hook", #ClassName_ "::" #FunctionName_ \ + ); \ + break; \ + } \ + auto hook = Hook::create( \ + reinterpret_cast(address), \ + AsStaticFunction_##FunctionName_< \ + Derived, \ + DerivedFuncType>::value, \ + #ClassName_ "::" #FunctionName_, \ + tulip::hook::TulipConvention::Convention_ \ + ); \ + this->m_hooks[#ClassName_ "::" #FunctionName_] = hook; \ + } \ } while (0); #define GEODE_APPLY_MODIFY_FOR_CONSTRUCTOR(AddressInline_, Convention_, ClassName_, ...) \ diff --git a/loader/include/Geode/modify/Traits.hpp b/loader/include/Geode/modify/Traits.hpp index 9ef75e3c..30afafb4 100644 --- a/loader/include/Geode/modify/Traits.hpp +++ b/loader/include/Geode/modify/Traits.hpp @@ -166,6 +166,29 @@ namespace geode::modifier { } }; + /** + * Gets the return type of a given resolved function pointer. + */ + template + struct ReturnType { + using type = void; + }; + + template + struct ReturnType { + using type = Return; + }; + + template + struct ReturnType { + using type = Return; + }; + + template + struct ReturnType { + using type = Return; + }; + /** * A specialization for giving the variadic types as a single type with the * function type. The return type is ignored.