From 0842941f96362c4796352ea67d684f0938cdc494 Mon Sep 17 00:00:00 2001 From: maybegreat48 <96936658+maybegreat48@users.noreply.github.com> Date: Tue, 3 Jun 2025 21:43:38 -0400 Subject: [PATCH] fix(battleye): ensure we don't trigger the BE shadow ban by being in invite-only sessions --- src/core/hooking/Hooking.cpp | 1 + src/game/backend/Tunables.cpp | 2 ++ src/game/backend/Tunables.hpp | 3 +- .../BattlEyeServerProcessPlayerJoin.cpp | 28 +++++++++++++++++++ src/game/hooks/Hooks.hpp | 4 +++ src/game/pointers/Pointers.cpp | 4 +++ src/game/pointers/Pointers.hpp | 1 + .../battleye/CBattlEyePlayerModifyContext.hpp | 20 +++++++++++++ .../CBattlEyePlayerModifyInterface.hpp | 16 +++++++++++ 9 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 src/game/hooks/Anticheat/BattlEyeServerProcessPlayerJoin.cpp create mode 100644 src/types/battleye/CBattlEyePlayerModifyContext.hpp create mode 100644 src/types/battleye/CBattlEyePlayerModifyInterface.hpp diff --git a/src/core/hooking/Hooking.cpp b/src/core/hooking/Hooking.cpp index 8df3391..47b83b2 100644 --- a/src/core/hooking/Hooking.cpp +++ b/src/core/hooking/Hooking.cpp @@ -20,6 +20,7 @@ namespace YimMenu BaseHook::Add(new DetourHook("PrepareMetricForSending", Pointers.PrepareMetricForSending, Hooks::Anticheat::PrepareMetricForSending)); BaseHook::Add(new DetourHook("GetThreadContext", reinterpret_cast(GetProcAddress(LoadLibraryA("kernel32.dll"), "GetThreadContext")), Hooks::Anticheat::GetThreadContext)); BaseHook::Add(new DetourHook("HttpStartRequest", Pointers.HttpStartRequest, Hooks::Anticheat::HttpStartRequest)); + BaseHook::Add(new DetourHook("BattlEyeServerProcessPlayerJoin", Pointers.BattlEyeServerProcessPlayerJoin, Hooks::Anticheat::BattlEyeServerProcessPlayerJoin)); BaseHook::Add(new DetourHook("RunScriptThreads", Pointers.RunScriptThreads, Hooks::Script::RunScriptThreads)); BaseHook::Add(new DetourHook("InitNativeTables", Pointers.InitNativeTables, Hooks::Script::InitNativeTables)); diff --git a/src/game/backend/Tunables.cpp b/src/game/backend/Tunables.cpp index 8bbf4a1..36476ed 100644 --- a/src/game/backend/Tunables.cpp +++ b/src/game/backend/Tunables.cpp @@ -205,5 +205,7 @@ namespace YimMenu if (m_Global) return true; + + return false; } } \ No newline at end of file diff --git a/src/game/backend/Tunables.hpp b/src/game/backend/Tunables.hpp index c7db094..43b37f7 100644 --- a/src/game/backend/Tunables.hpp +++ b/src/game/backend/Tunables.hpp @@ -74,7 +74,8 @@ namespace YimMenu { if (auto it = GetInstance().m_Tunables.find(hash); it != GetInstance().m_Tunables.end()) { - return ScriptGlobal(it->second); + if (ScriptGlobal(it->second).CanAccess()) + return ScriptGlobal(it->second); } return std::nullopt; diff --git a/src/game/hooks/Anticheat/BattlEyeServerProcessPlayerJoin.cpp b/src/game/hooks/Anticheat/BattlEyeServerProcessPlayerJoin.cpp new file mode 100644 index 0000000..d97d9ae --- /dev/null +++ b/src/game/hooks/Anticheat/BattlEyeServerProcessPlayerJoin.cpp @@ -0,0 +1,28 @@ +#include "core/hooking/DetourHook.hpp" +#include "core/commands/BoolCommand.hpp" +#include "core/commands/Commands.hpp" +#include "game/hooks/Hooks.hpp" +#include "game/gta/Natives.hpp" +#include "types/battleye/CBattlEyePlayerModifyContext.hpp" + +namespace YimMenu::Hooks +{ + bool Anticheat::BattlEyeServerProcessPlayerJoin(CBattlEyePlayerModifyInterface* server_iface, CBattlEyePlayerModifyContext* context) + { + if (context->m_IsLocal) + { + if (NETWORK::NETWORK_SESSION_IS_CLOSED_FRIENDS() || NETWORK::NETWORK_SESSION_IS_CLOSED_CREW() || NETWORK::NETWORK_SESSION_IS_SOLO() || NETWORK::NETWORK_SESSION_IS_PRIVATE()) + { + return true; + } + } + + static auto cheater_pool = Commands::GetCommand("cheaterpool"_J); + if (cheater_pool->GetState()) + { + return true; + } + + return BaseHook::Get>()->Original()(server_iface, context); + } +} \ No newline at end of file diff --git a/src/game/hooks/Hooks.hpp b/src/game/hooks/Hooks.hpp index 6c3649a..fcd349a 100644 --- a/src/game/hooks/Hooks.hpp +++ b/src/game/hooks/Hooks.hpp @@ -5,6 +5,9 @@ class CNetworkPlayerMgr; class CNetGamePlayer; class CProjectBaseSyncDataNode; class CScriptedGameEvent; +class CBattlEyePlayerModifyInterface; +class CBattlEyePlayerModifyContext; + namespace rage { class netConnectionManager; @@ -38,6 +41,7 @@ namespace YimMenu::Hooks extern bool PrepareMetricForSending(rage::JsonSerializer* ser, void* a2, void* a3, rage::rlMetric* metric); extern BOOL GetThreadContext(HANDLE hThread, LPCONTEXT lpContext); extern void HttpStartRequest(void* request); + extern bool BattlEyeServerProcessPlayerJoin(CBattlEyePlayerModifyInterface* server_iface, CBattlEyePlayerModifyContext* context); } namespace Info diff --git a/src/game/pointers/Pointers.cpp b/src/game/pointers/Pointers.cpp index d51a490..6cbe89b 100644 --- a/src/game/pointers/Pointers.cpp +++ b/src/game/pointers/Pointers.cpp @@ -374,6 +374,10 @@ namespace YimMenu HasGTAPlus = addr.Add(3).Rip().As(); }); + constexpr auto battlEyeServerProcessPlayerJoinPtrn = Pattern<"BA 2D AD 45 3F">("BattlEyeServerProcessPlayerJoin"); + scanner.Add(battlEyeServerProcessPlayerJoinPtrn, [this](PointerCalculator ptr) { + BattlEyeServerProcessPlayerJoin = ptr.Sub(0x72).As(); + }); if (!scanner.Scan()) { diff --git a/src/game/pointers/Pointers.hpp b/src/game/pointers/Pointers.hpp index b788174..1de8f7e 100644 --- a/src/game/pointers/Pointers.hpp +++ b/src/game/pointers/Pointers.hpp @@ -149,6 +149,7 @@ namespace YimMenu BytePatch HandleJoinRequestIgnorePoolPatch; CStatsMpCharacterMappingData* StatsMpCharacterMappingData; int* HasGTAPlus; + PVOID BattlEyeServerProcessPlayerJoin; }; struct Pointers : PointerData diff --git a/src/types/battleye/CBattlEyePlayerModifyContext.hpp b/src/types/battleye/CBattlEyePlayerModifyContext.hpp new file mode 100644 index 0000000..44e9e91 --- /dev/null +++ b/src/types/battleye/CBattlEyePlayerModifyContext.hpp @@ -0,0 +1,20 @@ +#pragma once +#include "types/rage/atArray.hpp" +#include "types/network/netSocketAddress.hpp" + +namespace rage +{ + using atDynString = rage::atArray; // this is technically true +} + +class CBattlEyePlayerModifyContext +{ +public: + rage::atDynString m_Ticket; + rage::atDynString m_GamerHandleHash; + netSocketAddress m_Address; + uint64_t m_HostToken; + char m_Name[17]; + bool m_IsLocal; +}; +static_assert(sizeof(CBattlEyePlayerModifyContext) == 0x48); \ No newline at end of file diff --git a/src/types/battleye/CBattlEyePlayerModifyInterface.hpp b/src/types/battleye/CBattlEyePlayerModifyInterface.hpp new file mode 100644 index 0000000..759bbac --- /dev/null +++ b/src/types/battleye/CBattlEyePlayerModifyInterface.hpp @@ -0,0 +1,16 @@ +#pragma once + +class CBattlEyeClient; +class CBattlEyeServer; +class CBattlEyePlayerModifyContext; + +class CBattlEyePlayerModifyInterface +{ +public: + virtual ~CBattlEyePlayerModifyInterface() = default; + virtual bool ProcessPlayerJoin(const CBattlEyePlayerModifyContext* context) = 0; + virtual bool ProcessPlayerLeave(const CBattlEyePlayerModifyContext* context) = 0; + + CBattlEyeClient* m_Client; + CBattlEyeServer* m_Server; +};