#pragma once #include "../meta/meta.hpp" #include "Addresses.hpp" #include "Field.hpp" #include "IDManager.hpp" #include "Types.hpp" #include "Wrapper.hpp" #include #include #include #include #define GEODE_APPLY_MODIFY_FOR_FUNCTION(addr_index, pure_index, convention, className, functionName) \ { \ using DerivedWrap = wrap::functionName; \ using BaseWrap = wrap::functionName; \ if constexpr (DerivedWrap::uuid != nullptr && (void*)BaseWrap::uuid != (void*)DerivedWrap::uuid) { \ auto hook = Hook::create( \ Mod::get(), \ reinterpret_cast(addresses::address##addr_index()), \ DerivedWrap::value, \ #className "::" #functionName \ ); \ BaseModify::m_hooks[FunctionUUID::value] = hook; \ } \ } namespace geode::modifier { template class ModifyDerive; template class ModifyBase { public: std::map m_hooks; template Result getHook() { auto uuid = FunctionUUID::value; if (m_hooks.find(uuid) == m_hooks.end()) { return Err("Hook not in this modify"); } return m_hooks[uuid]; } // unordered_map idea ModifyBase() { Loader::get()->scheduleOnModLoad(getMod(), [this]() { this->apply(); ModifyDerived::Derived::onModify(*this); for (auto& [uuid, hook] : m_hooks) { auto res = Mod::get()->addHook(hook); if (!res) { log::error("Failed to add hook: {}", res.error()); } } }); } virtual void apply() {} template friend class ModifyDerive; // explicit Modify(Property property) idea }; template class ModifyDerive { public: ModifyDerive() { static_assert(core::meta::always_false, "Custom Modify not implemented."); } }; } namespace geode { template class Modify : public Base { private: static inline modifier::ModifyDerive s_apply; // because for some reason we need it static inline auto s_applyRef = &Modify::s_apply; public: modifier::FieldIntermediate m_fields; static void onModify(auto& self) {} }; }