diff --git a/src/core/hooking/Hooking.cpp b/src/core/hooking/Hooking.cpp index f1967fd5..639019f2 100644 --- a/src/core/hooking/Hooking.cpp +++ b/src/core/hooking/Hooking.cpp @@ -49,6 +49,8 @@ namespace YimMenu BaseHook::Add(new DetourHook("MatchmakingUpdate", Pointers.MatchmakingUpdate, Hooks::Matchmaking::MatchmakingUpdate)); BaseHook::Add(new DetourHook("AssistedAimShouldReleaseEntity", Pointers.AssistedAimShouldReleaseEntity, Hooks::Misc::AssistedAimShouldReleaseEntity)); + BaseHook::Add(new DetourHook("GetLabelText", Pointers.GetLabelText, Hooks::Misc::GetLabelText)); + BaseHook::Add(new DetourHook("GetLabelTextInternal", Pointers.GetLabelTextInternal, Hooks::Misc::GetLabelTextInternal)); } Hooking::~Hooking() diff --git a/src/core/memory/Module.hpp b/src/core/memory/Module.hpp index a856094f..15352872 100644 --- a/src/core/memory/Module.hpp +++ b/src/core/memory/Module.hpp @@ -70,7 +70,7 @@ namespace YimMenu IMAGE_NT_HEADERS* GetNtHeader() const; private: - template + template R GetExportImpl(const T symbol) const; private: @@ -127,7 +127,7 @@ namespace YimMenu return GetExportImpl(ordinal) != nullptr; } - template + template inline R Module::GetExportImpl(const T symbol) const { const auto ntHeader = GetNtHeader(); @@ -142,11 +142,10 @@ namespace YimMenu for (std::size_t i = 0; i < exportDirectory->NumberOfNames; i++) { - if constexpr (std::is_convertible_v) + if constexpr (std::is_integral_v) { if (exportDirectory->Base + ordinalOffsets[i] != symbol) continue; - return m_Base.Add(funcOffsets[ordinalOffsets[i]]).As(); } else if constexpr (std::is_convertible_v) @@ -154,12 +153,12 @@ namespace YimMenu const auto functionName = m_Base.Add(namesOffsets[i]).As(); if (strcmp(functionName, symbol.data())) continue; - return m_Base.Add(funcOffsets[ordinalOffsets[i]]).As(); } else { - static_assert(false, "Unsupported symbol type"); + static_assert(std::is_integral_v || std::is_convertible_v, + "Unsupported symbol type"); } } diff --git a/src/game/backend/CustomLabelText.cpp b/src/game/backend/CustomLabelText.cpp new file mode 100644 index 00000000..54eed017 --- /dev/null +++ b/src/game/backend/CustomLabelText.cpp @@ -0,0 +1,39 @@ +#include "CustomLabelText.hpp" + +namespace YimMenu +{ + void CustomLabelText::InitImpl() + { + AddLabelImpl(0x1B2EA75B, "YimMenu Story"); // Title Story Mode + AddLabelImpl(0xABB00DEB, "YimMenu"); // Title Pause Menu + AddLabelImpl(Joaat("PM_ENTER_MP"), "Play GTA Online with YimMenu"); + AddLabelImpl(Joaat("PM_EXIT_GAME"), "Quit GTA V with YimMenu"); + AddLabelImpl(Joaat("PM_GO"), "Play with YimMenu"); + AddLabelImpl(Joaat("HUD_MPREENTER"), "Joining a new session with YimMenu"); + AddLabelImpl(Joaat("PM_FRIEND_FM"), "Closed Friend Session with YimMenu"); + AddLabelImpl(Joaat("PM_INF_EXIT"), "Quit to desktop with YimMenu"); + AddLabelImpl(Joaat("PM_CREWS"), "Join a Crew Only Session with YimMenu"); + AddLabelImpl(Joaat("PM_INF_PGOT"), "Online with YimMenu"); + AddLabelImpl(Joaat("PM_INVO_FM"), "Join an Invite Only Session with YimMenu"); + AddLabelImpl(Joaat("LOADING_SPLAYER_L"), "Loading Story Mode with YimMenu"); + AddLabelImpl(Joaat("PM_NCREW_FM"), "Join a Crew Session with YimMenu"); + AddLabelImpl(Joaat("PM_CREW_FM"), "Join a Closed Crew Session with YimMenu"); + AddLabelImpl(Joaat("PM_SOLO_FM"), "Join a Solo Session with YimMenu"); + AddLabelImpl(Joaat("PM_FRESES"), "Join a Friends Only Session with YimMenu"); + AddLabelImpl(Joaat("PM_CHOOSE_CHAR"), "Choose your personnage with YimMenu"); + AddLabelImpl(Joaat("PM_INF_PGOT"), "Online with YimMenu"); + } + + bool CustomLabelText::AddLabelImpl(joaat_t hash, const std::string_view text) + { + const auto size = text.size() + 1; + auto buffer = std::make_unique(size); + memcpy(buffer.get(), text.data(), size); + return m_LabelOverwrites.insert({hash, std::move(buffer)}).second; + } + + bool CustomLabelText::AddLabelImpl(joaat_t hash, CustomLabelText_t&& cb) + { + return m_Labels.insert({hash, std::move(cb)}).second; + } +} \ No newline at end of file diff --git a/src/game/backend/CustomLabelText.hpp b/src/game/backend/CustomLabelText.hpp new file mode 100644 index 00000000..59c8a82e --- /dev/null +++ b/src/game/backend/CustomLabelText.hpp @@ -0,0 +1,79 @@ +#pragma once +#include "core/util/Joaat.hpp" + +namespace YimMenu +{ + using CustomLabelText_t = std::function; + class CustomLabelText + { + static CustomLabelText& GetInstance() + { + static CustomLabelText instance; + return instance; + } + public: + static uint64_t ComputeHash(const char* str) + { + return Joaat(str); + } + static uint64_t ComputeHash(uint64_t value) + { + return value; + } + + static void Init() + { + return GetInstance().InitImpl(); + } + + static bool AddLabel(joaat_t hash, const std::string_view text) + { + return GetInstance().AddLabelImpl(hash, text); + } + + static bool AddLabel(joaat_t hash, CustomLabelText_t&& cb) + { + return GetInstance().AddLabelImpl(hash, std::move(cb)); + } + + template + static const char* GetText(const T& label) + { + return GetInstance().GetTextImpl(label); + } + private: + bool AddLabelImpl(joaat_t hash, const std::string_view text); + bool AddLabelImpl(joaat_t hash, CustomLabelText_t&& cb); + + void InitImpl(); + + template + const char* GetTextImpl(const T& label) const + { + uint64_t hash; + + if constexpr (std::is_same_v) + hash = ComputeHash(label); + else if constexpr (std::is_same_v) + hash = ComputeHash(label); + else + static_assert(sizeof(T) == 0, "Label type Unsupported"); + + if (const auto& it = m_Labels.find(hash); it != m_Labels.end()) + { + if constexpr (std::is_same_v) + return it->second(label); + else + return it->second(nullptr); + } + + if (const auto& it = m_LabelOverwrites.find(hash); it != m_LabelOverwrites.end()) + return it->second.get(); + + return nullptr; + } + + std::unordered_map> m_Labels; + std::unordered_map> m_LabelOverwrites; + }; +} \ No newline at end of file diff --git a/src/game/hooks/Hooks.hpp b/src/game/hooks/Hooks.hpp index 00a31305..a83209e0 100644 --- a/src/game/hooks/Hooks.hpp +++ b/src/game/hooks/Hooks.hpp @@ -101,5 +101,7 @@ namespace YimMenu::Hooks namespace Misc { extern bool AssistedAimShouldReleaseEntity(__int64 a1); + extern const char* GetLabelText(void* unk, const char* label); + extern const char* GetLabelTextInternal(void* this_, uint32_t label_hash); } } \ No newline at end of file diff --git a/src/game/hooks/Misc/GetLabelText.cpp b/src/game/hooks/Misc/GetLabelText.cpp new file mode 100644 index 00000000..73eb9752 --- /dev/null +++ b/src/game/hooks/Misc/GetLabelText.cpp @@ -0,0 +1,14 @@ +#include "core/hooking/DetourHook.hpp" +#include "game/hooks/Hooks.hpp" +#include "game/backend/CustomLabelText.hpp" + +namespace YimMenu::Hooks +{ + const char* Misc::GetLabelText(void* unk, const char* label) + { + if (const auto text = CustomLabelText::GetText(label); text) + return text; + + return BaseHook::Get>()->Original()(unk, label); + } +} \ No newline at end of file diff --git a/src/game/hooks/Misc/GetLabelTextInternal.cpp b/src/game/hooks/Misc/GetLabelTextInternal.cpp new file mode 100644 index 00000000..bdd7f68b --- /dev/null +++ b/src/game/hooks/Misc/GetLabelTextInternal.cpp @@ -0,0 +1,14 @@ +#include "core/hooking/DetourHook.hpp" +#include "game/hooks/Hooks.hpp" +#include "game/backend/CustomLabelText.hpp" + +namespace YimMenu::Hooks +{ + const char* Misc::GetLabelTextInternal(void* this_, uint32_t label_hash) + { + if (const auto text = CustomLabelText::GetText(label_hash); text) + return text; + + return BaseHook::Get>()->Original()(this_, label_hash); + } +} \ No newline at end of file diff --git a/src/game/pointers/Pointers.cpp b/src/game/pointers/Pointers.cpp index d97ab9fe..f7420ed1 100644 --- a/src/game/pointers/Pointers.cpp +++ b/src/game/pointers/Pointers.cpp @@ -451,12 +451,17 @@ namespace YimMenu scanner.Add(matchmakingSessionDetailSendResponsePtrn, [this](PointerCalculator addr) { MatchmakingSessionDetailSendResponse = addr.Add(0x2F).Rip().As(); }); - static constexpr auto gameSkeletonUpdatePtrn = Pattern<"56 48 83 EC 20 48 8B 81 40 01 00 00 48 85 C0">("GameSkeletonUpdate"); scanner.Add(gameSkeletonUpdatePtrn, [this](PointerCalculator addr) { GameSkeletonUpdate = addr.As(); }); + static constexpr auto getLabelTextPtrn = Pattern<"56 48 83 EC 20 48 85 D2 74 25 0F B6 02 A8 DF 74 23 48 89 CE 48 89 D1 31 D2 E8 ? ? ? ? 48 89 F1 89 C2 E8 ? ? ? ?">("GetLabelText&GetLabelTextInternal"); + scanner.Add(getLabelTextPtrn, [this](PointerCalculator addr) { + GetLabelText = addr.As(); + GetLabelTextInternal = addr.Add(36).Rip().As(); + }); + if (!scanner.Scan()) { LOG(FATAL) << "Some patterns could not be found, unloading."; diff --git a/src/game/pointers/Pointers.hpp b/src/game/pointers/Pointers.hpp index ac5553c6..e3604b06 100644 --- a/src/game/pointers/Pointers.hpp +++ b/src/game/pointers/Pointers.hpp @@ -171,6 +171,8 @@ namespace YimMenu PVOID MatchmakingUnadvertise; PVOID MatchmakingSessionDetailSendResponse; PVOID GameSkeletonUpdate; + PVOID GetLabelText; + PVOID GetLabelTextInternal; }; struct Pointers : PointerData diff --git a/src/main.cpp b/src/main.cpp index b4b62659..df943a8f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,6 +25,7 @@ #include "game/features/vehicle/SavePersonalVehicle.hpp" #include "game/features/self/OpenGunLocker.hpp" #include "game/features/recovery/DailyActivities.hpp" +#include "game/backend/CustomLabelText.hpp" namespace YimMenu { @@ -83,6 +84,8 @@ namespace YimMenu if (!Pointers.LateInit()) LOG(WARNING) << "Socialclub patterns failed to load"; + CustomLabelText::Init(); + Notifications::Show("YimMenuV2", "Loaded succesfully", NotificationType::Success); if (InWine().value_or(false))