diff --git a/loader/include/Geode/loader/Hook.hpp b/loader/include/Geode/loader/Hook.hpp index bc4cd430a..d3e94682b 100644 --- a/loader/include/Geode/loader/Hook.hpp +++ b/loader/include/Geode/loader/Hook.hpp @@ -144,6 +144,20 @@ namespace geode { * @param priority Priority */ void setPriority(int32_t priority); + + /** + * Get the name of the modify class this hook belongs to, or `std::nullopt` if unavailable. + * This is the final, user-specified (or auto generated) name of the modify class, not the name of the modified class. + * This will not work for manual hooks or hooks in mods compiled with an older version of Geode. + * @returns Name of the modify class this hook belongs to + */ + std::optional getModifyClassName() const; + + /** + * Set the name of the modify class this hook belongs to. + * For internal usage only. + */ + void setModifyClassName(std::string name); }; class GEODE_DLL Patch final { diff --git a/loader/include/Geode/modify/Modify.hpp b/loader/include/Geode/modify/Modify.hpp index a700c23f5..f9ab20707 100644 --- a/loader/include/Geode/modify/Modify.hpp +++ b/loader/include/Geode/modify/Modify.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #define GEODE_APPLY_MODIFY_FOR_FUNCTION(AddressInline_, Convention_, ClassName_, FunctionName_, ...) \ do { \ @@ -411,6 +412,7 @@ namespace geode::modifier { ModifyDerived::Derived::onModify(*this); std::vector added; for (auto& [uuid, hook] : m_hooks) { + hook->setModifyClassName(std::string{ModifyDerived::Derived::SELF_NAME}); auto res = Mod::get()->claimHook(hook); if (!res) { log::error("Failed to claim hook {}: {}", hook->getDisplayName(), res.unwrapErr()); @@ -461,6 +463,11 @@ namespace geode { public: using Self = Derived; + static inline constexpr std::string_view SELF_NAME = [] { + auto [ptr, size] = arc::getTypename(); + return std::string_view{ptr, size}; + }(); + // abusing the internal stuff // basically we dont want modify to invoke base ctors and dtors Modify() : Base(CutoffConstructor, sizeof(Base)) {} diff --git a/loader/src/loader/Hook.cpp b/loader/src/loader/Hook.cpp index 462ffc68d..8c22e63e2 100644 --- a/loader/src/loader/Hook.cpp +++ b/loader/src/loader/Hook.cpp @@ -75,3 +75,11 @@ int32_t Hook::getPriority() const { void Hook::setPriority(int32_t priority) { return m_impl->setPriority(priority); } + +std::optional Hook::getModifyClassName() const { + return m_impl->getModifyClassName(); +} + +void Hook::setModifyClassName(std::string name) { + return m_impl->setModifyClassName(std::move(name)); +} diff --git a/loader/src/loader/HookImpl.cpp b/loader/src/loader/HookImpl.cpp index f02c91e6b..9c4e0e7c9 100644 --- a/loader/src/loader/HookImpl.cpp +++ b/loader/src/loader/HookImpl.cpp @@ -151,6 +151,16 @@ void Hook::Impl::setPriority(int32_t priority) { } } +std::optional Hook::Impl::getModifyClassName() const { + return m_modifyClassName.transform([](auto& s) { + return std::string_view{s}; + }); +} + +void Hook::Impl::setModifyClassName(std::string name) { + m_modifyClassName = std::move(name); +} + Result<> Hook::Impl::updateHookMetadata() { if (!m_enabled) return Ok(); GEODE_UNWRAP_INTO(auto handler, LoaderImpl::get()->getHandler(m_address)); diff --git a/loader/src/loader/HookImpl.hpp b/loader/src/loader/HookImpl.hpp index 7c435cd24..ed26e5da9 100644 --- a/loader/src/loader/HookImpl.hpp +++ b/loader/src/loader/HookImpl.hpp @@ -43,6 +43,7 @@ class Hook::Impl final : ModPatch { void* m_address; void* m_detour; std::string m_displayName; + std::optional m_modifyClassName; tulip::hook::HandlerMetadata m_handlerMetadata; tulip::hook::HookMetadata m_hookMetadata; tulip::hook::HookHandle m_handle = 0; @@ -60,6 +61,9 @@ class Hook::Impl final : ModPatch { int32_t getPriority() const; void setPriority(int32_t priority); + std::optional getModifyClassName() const; + void setModifyClassName(std::string name); + Result<> updateHookMetadata(); friend class Hook;