feat(anticheat): Anticheat bypass improvements (#2463)
- Add more metrics to bad_metrics set - Add MM Filtering (This metric shouldnt be normally called anyway) - Improve QD Hook to increase AC verifier delay when detected - Removed gameskeleton hook in favor of patching ac at init - Added tamperactions check to gameskeleton patcher
This commit is contained in:
parent
f0302ab135
commit
062c95b374
@ -3,7 +3,7 @@ include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
gtav_classes
|
||||
GIT_REPOSITORY https://github.com/Yimura/GTAV-Classes.git
|
||||
GIT_TAG 3c7763fcf996f53f891e40f12bbfa8115fd612a7
|
||||
GIT_TAG 9e76175d28b3de21c24a69e71bee779d704d8304
|
||||
GIT_PROGRESS TRUE
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
|
@ -64,7 +64,7 @@ namespace big::functions
|
||||
using ptr_to_handle = Entity (*)(void*);
|
||||
using handle_to_ptr = rage::CDynamicEntity* (*)(Entity);
|
||||
|
||||
using set_gravity_level = void(*)(int level);
|
||||
using set_gravity_level = void (*)(int level);
|
||||
|
||||
using check_chat_profanity = int(__int64 chat_type, const char* input, const char** output);
|
||||
using write_player_game_state_data_node = bool (*)(rage::netObject* plr, CPlayerGameStateDataNode* node);
|
||||
@ -120,9 +120,9 @@ namespace big::functions
|
||||
using start_get_presence_attributes = bool (*)(int profile_index, rage::rlScHandle* handle, int num_handles, rage::rlQueryPresenceAttributesContext** contexts, int count, rage::rlScTaskStatus* state);
|
||||
using join_session_by_info = bool (*)(Network* network, rage::rlSessionInfo* info, int unk, int flags, rage::rlGamerHandle* handles, int handlecount);
|
||||
|
||||
using invite_player_by_gamer_handle = bool(*)(uint64_t config, rage::rlGamerHandle* handle, int unk1, int unk2, int unk3, int unk4);
|
||||
using add_friend_by_gamer_handle = void(*)(rage::rlGamerHandle* handle, const char* unk);
|
||||
using show_profile_by_gamer_handle = void(*)(rage::rlGamerHandle* handle);
|
||||
using invite_player_by_gamer_handle = bool (*)(uint64_t config, rage::rlGamerHandle* handle, int unk1, int unk2, int unk3, int unk4);
|
||||
using add_friend_by_gamer_handle = void (*)(rage::rlGamerHandle* handle, const char* unk);
|
||||
using show_profile_by_gamer_handle = void (*)(rage::rlGamerHandle* handle);
|
||||
|
||||
using generate_uuid = bool (*)(uint64_t* uuid);
|
||||
|
||||
@ -194,9 +194,9 @@ namespace big::functions
|
||||
using delete_vehicle = bool (*)(CVehicle* veh);
|
||||
using delete_object = bool (*)(CObject* object, bool unk);
|
||||
|
||||
using decal_manager_remove = void(*)(PVOID manager, rage::fwEntity*, DWORD a3, DWORD64 a4, DWORD ignore_bitset);
|
||||
using decal_manager_remove = void (*)(PVOID manager, rage::fwEntity*, DWORD a3, DWORD64 a4, DWORD ignore_bitset);
|
||||
|
||||
using remove_player_from_sender_list = bool(*)(void* list, uint64_t* rockstar_id);
|
||||
using remove_player_from_sender_list = bool (*)(void* list, uint64_t* rockstar_id);
|
||||
|
||||
using get_ped_bone = bool(*)(CPed* ped_ptr, rage::fvector4& output, PedBones bone);
|
||||
using get_ped_bone = bool (*)(CPed* ped_ptr, rage::fvector4& output, PedBones bone);
|
||||
}
|
||||
|
@ -18,12 +18,11 @@ namespace rage
|
||||
buffer(_buffer),
|
||||
maxlen(_length)
|
||||
{
|
||||
unk0
|
||||
= 0;
|
||||
unk1 = 0;
|
||||
curlen = 0;
|
||||
unk4 = 1;
|
||||
flags = 0;
|
||||
unk0 = 0;
|
||||
unk1 = 0;
|
||||
curlen = 0;
|
||||
unk4 = 1;
|
||||
flags = 0;
|
||||
}
|
||||
|
||||
inline char* get_string() const
|
||||
|
@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
#include <memory/handle.hpp>
|
||||
#include "function_types.hpp"
|
||||
|
||||
#include <memory/handle.hpp>
|
||||
|
||||
class CCommunications;
|
||||
class FriendRegistry;
|
||||
class CNetworkPlayerMgr;
|
||||
@ -27,6 +28,7 @@ namespace rage
|
||||
class RageSecurity;
|
||||
class netTime;
|
||||
class rlGamerInfo;
|
||||
struct game_skeleton;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -71,6 +73,8 @@ namespace big
|
||||
CPedFactory** m_ped_factory;
|
||||
CNetworkPlayerMgr** m_network_player_mgr;
|
||||
CNetworkObjectMgr** m_network_object_mgr;
|
||||
rage::game_skeleton* m_game_skeleton;
|
||||
void (*m_nullsub)();
|
||||
|
||||
functions::ptr_to_handle m_ptr_to_handle;
|
||||
functions::handle_to_ptr m_handle_to_ptr;
|
||||
@ -353,8 +357,6 @@ namespace big
|
||||
|
||||
bool* m_is_social_club_overlay_active;
|
||||
|
||||
PVOID m_game_skeleton_update;
|
||||
|
||||
functions::get_ped_bone m_get_ped_bone;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include "gta/script_thread.hpp"
|
||||
#include "script/tlsContext.hpp"
|
||||
#include "pointers.hpp"
|
||||
#include "script/tlsContext.hpp"
|
||||
|
||||
#include <network/CNetworkPlayerMgr.hpp>
|
||||
#include <ped/CPedFactory.hpp>
|
||||
|
@ -147,8 +147,6 @@ namespace big
|
||||
|
||||
detour_hook_helper::add<hooks::read_bits_single>("RBS", g_pointers->m_gta.m_read_bits_single);
|
||||
|
||||
detour_hook_helper::add<hooks::game_skeleton_update>("GSU", g_pointers->m_gta.m_game_skeleton_update);
|
||||
|
||||
g_hooking = this;
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
#pragma once
|
||||
#include "MinHook.h"
|
||||
#include "call_hook.hpp"
|
||||
#include "common.hpp"
|
||||
#include "detour_hook.hpp"
|
||||
#include "gta/enums.hpp"
|
||||
#include "gta/fwddec.hpp"
|
||||
#include "gta/script_thread.hpp"
|
||||
#include "gta/json_serializer.hpp"
|
||||
#include "gta/script_thread.hpp"
|
||||
#include "vmt_hook.hpp"
|
||||
#include "vtable_hook.hpp"
|
||||
#include "call_hook.hpp"
|
||||
|
||||
#include <network/netConnection.hpp>
|
||||
|
||||
@ -128,7 +128,7 @@ namespace big
|
||||
static void serialize_parachute_task(__int64 info, rage::CSyncDataBase* serializer);
|
||||
|
||||
static int nt_query_virtual_memory(void* _this, HANDLE handle, PVOID base_addr, int info_class, MEMORY_BASIC_INFORMATION* info, int size, size_t* return_len);
|
||||
static int queue_dependency(void* a1, int a2, void* dependency);
|
||||
static int queue_dependency(void* a1, int a2, int64_t dependency);
|
||||
|
||||
static bool prepare_metric_for_sending(rage::json_serializer* bit_buffer, int unk, int time, rage::rlMetric* metric);
|
||||
static bool http_start_request(void* request, const char* uri);
|
||||
@ -185,7 +185,6 @@ namespace big
|
||||
static bool sync_reader_serialize_array(void* _this, void* array, int size);
|
||||
|
||||
static bool remove_player_from_sender_list(void* list, uint64_t rockstar_id);
|
||||
static void game_skeleton_update(__int64 skeleton, int type);
|
||||
};
|
||||
|
||||
class minhook_keepalive
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
namespace big
|
||||
{
|
||||
const auto bad_metrics = std::unordered_set<std::string>({
|
||||
const auto bad_metrics = std::unordered_set<std::string_view>({
|
||||
"REPORTER",
|
||||
"REPORT_INVALIDMODEL",
|
||||
"MEM_NEW",
|
||||
@ -36,6 +36,7 @@ namespace big
|
||||
"GSINT",
|
||||
"EARN",
|
||||
"GARAGE_TAMPER",
|
||||
"DUPE_DETECT",
|
||||
"LAST_VEH",
|
||||
"FAIL_SERV",
|
||||
"CCF_UPDATE",
|
||||
@ -43,25 +44,72 @@ namespace big
|
||||
"COLLECTIBLE",
|
||||
"FIRST_VEH",
|
||||
"MM",
|
||||
"RDEV",
|
||||
"RQA",
|
||||
"RANK_UP",
|
||||
});
|
||||
|
||||
std::string hex_encode(std::string_view input) {
|
||||
const char* hex_chars = "0123456789ABCDEF";
|
||||
std::string output;
|
||||
output.reserve(input.length() * 2); // Pre-allocate memory for efficiency
|
||||
for (unsigned char c : input) {
|
||||
output.push_back(hex_chars[c >> 4]); // Extract the high nibble (4 bits)
|
||||
output.push_back(hex_chars[c & 0x0F]); // Extract the low nibble
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
std::string remove_module_from_mmlist(std::string_view input, std::string_view element_to_remove) {
|
||||
std::string result(input);
|
||||
std::string delimiter = "|";
|
||||
size_t start_pos = 0;
|
||||
|
||||
while (true) {
|
||||
size_t delimiter_pos = result.find(delimiter, start_pos);
|
||||
if (delimiter_pos == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
std::string current_element = result.substr(start_pos, delimiter_pos - start_pos);
|
||||
if (current_element == element_to_remove) {
|
||||
result.erase(start_pos, delimiter_pos - start_pos + delimiter.length());
|
||||
break;
|
||||
}
|
||||
start_pos = delimiter_pos + delimiter.length();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool hooks::prepare_metric_for_sending(rage::json_serializer* serializer, int unk, int time, rage::rlMetric* metric)
|
||||
{
|
||||
const auto ret = g_hooking->get_original<prepare_metric_for_sending>()(serializer, unk, time, metric);
|
||||
|
||||
const auto is_bad_metric = bad_metrics.contains(metric->get_name());
|
||||
char metric_json_buffer [256] {};
|
||||
rage::json_serializer yim_serializer(metric_json_buffer, sizeof(metric_json_buffer));
|
||||
metric->serialize(&yim_serializer);
|
||||
const bool is_bad_metric = bad_metrics.contains(metric->get_name());
|
||||
if (is_bad_metric)
|
||||
{
|
||||
LOG(WARNING) << "BAD METRIC: " << metric->get_name() << "; DATA: " << serializer->get_string();
|
||||
|
||||
LOG(WARNING) << "BAD METRIC: " << metric->get_name() << "; DATA: " << yim_serializer.get_string();
|
||||
if(strcmp(metric->get_name(), "MM") == 0)
|
||||
{
|
||||
std::string data = std::string(reinterpret_cast<char*>(metric) + 0x18);
|
||||
char module_name[MAX_PATH];
|
||||
GetModuleFileNameA(g_hmodule, module_name, sizeof(module_name));
|
||||
std::string encoded_module_name = hex_encode(std::filesystem::path(module_name).filename().string());
|
||||
std::string result = remove_module_from_mmlist(data, encoded_module_name + "00");
|
||||
if(result.size() != data.size())
|
||||
LOG(INFO) << "Removed YimMenu DLL from MM metric";
|
||||
strncpy(reinterpret_cast<char*>(metric) + 0x18, result.c_str(), 0x900);
|
||||
return g_hooking->get_original<prepare_metric_for_sending>()(serializer, unk, time, metric);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_bad_metric && g.debug.logs.metric_logs)
|
||||
{
|
||||
LOG(INFO) << "METRIC: " << metric->get_name() << "; DATA: " << serializer->get_string();
|
||||
LOG(INFO) << "METRIC: " << metric->get_name() << "; DATA: " << yim_serializer.get_string();
|
||||
}
|
||||
|
||||
return ret;
|
||||
return g_hooking->get_original<prepare_metric_for_sending>()(serializer, unk, time, metric);
|
||||
}
|
||||
}
|
||||
|
@ -1,63 +0,0 @@
|
||||
#include "hooking.hpp"
|
||||
|
||||
// rage::gameSkeleton -> modes (does not derive from updateBase?) -> groups -> items
|
||||
|
||||
namespace big
|
||||
{
|
||||
class game_skeleton_update_group;
|
||||
class game_skeleton_item;
|
||||
|
||||
#pragma pack(push, 8)
|
||||
struct game_skeleton_update_mode
|
||||
{
|
||||
int m_type; // 0x00
|
||||
game_skeleton_update_group* m_groups; // 0x08
|
||||
game_skeleton_update_mode* m_next; // 0x10
|
||||
};
|
||||
static_assert(sizeof(game_skeleton_update_mode) == 0x18);
|
||||
|
||||
struct game_skeleton_update_group
|
||||
{
|
||||
virtual ~game_skeleton_update_group() = default;
|
||||
virtual void run() = 0; // 0x08
|
||||
|
||||
char pad[0x10]; // 0x08
|
||||
game_skeleton_update_group* m_next; // 0x18
|
||||
game_skeleton_item* m_items; // 0x20
|
||||
};
|
||||
static_assert(sizeof(game_skeleton_update_group) == 0x28);
|
||||
|
||||
struct game_skeleton_item
|
||||
{
|
||||
virtual ~game_skeleton_item() = default;
|
||||
virtual void run() = 0; // 0x08
|
||||
|
||||
char m_pad[0x8]; // 0x08
|
||||
uint32_t m_hash; // 0x10
|
||||
game_skeleton_item* m_next; // 0x18
|
||||
};
|
||||
static_assert(sizeof(game_skeleton_item) == 0x20);
|
||||
#pragma pack(pop)
|
||||
|
||||
void hooks::game_skeleton_update(__int64 skeleton, int type)
|
||||
{
|
||||
for (auto mode = *(game_skeleton_update_mode**)(skeleton + 0x140); mode; mode = mode->m_next)
|
||||
{
|
||||
if (mode && mode->m_type == type)
|
||||
{
|
||||
for (auto group = mode->m_groups; group; group = group->m_next)
|
||||
{
|
||||
for (auto item = group->m_items; item; item = item->m_next)
|
||||
{
|
||||
if (item->m_hash != 0xA0F39FB6)
|
||||
{
|
||||
item->run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,15 +1,17 @@
|
||||
#include "hooking.hpp"
|
||||
#include "pointers.hpp"
|
||||
|
||||
#include "security/ObfVar.hpp"
|
||||
#include <Psapi.h>
|
||||
|
||||
namespace big
|
||||
{
|
||||
bool inline is_address_in_game_region(uint64_t address)
|
||||
bool inline is_address_in_game_region(int64_t address)
|
||||
{
|
||||
static uint64_t moduleBase = NULL;
|
||||
static uint64_t moduleSize = NULL;
|
||||
if ((!moduleBase) || (!moduleSize))
|
||||
if(!address)
|
||||
return false;
|
||||
static int64_t moduleBase = NULL;
|
||||
static int64_t moduleSize = NULL;
|
||||
if (!moduleBase || !moduleSize)
|
||||
{
|
||||
MODULEINFO info;
|
||||
if (!GetModuleInformation(GetCurrentProcess(), GetModuleHandle(0), &info, sizeof(info)))
|
||||
@ -19,31 +21,34 @@ namespace big
|
||||
}
|
||||
else
|
||||
{
|
||||
moduleBase = (uint64_t)GetModuleHandle(0);
|
||||
moduleSize = (uint64_t)info.SizeOfImage;
|
||||
moduleBase = (int64_t)GetModuleHandle(0);
|
||||
moduleSize = (int64_t)info.SizeOfImage;
|
||||
}
|
||||
}
|
||||
return address > moduleBase && address < (moduleBase + moduleSize);
|
||||
}
|
||||
|
||||
bool is_jump(__int64 fptr)
|
||||
struct ac_verifier
|
||||
{
|
||||
if (!is_address_in_game_region(fptr))
|
||||
virtual ~ac_verifier() = 0;
|
||||
virtual bool run() = 0;
|
||||
rage::Obf32 m_last_time; // 0x8
|
||||
rage::Obf32 m_delay; // 0x18
|
||||
};
|
||||
|
||||
bool is_unwanted_dependency(int64_t cb)
|
||||
{
|
||||
int64_t f1 = *reinterpret_cast<int64_t*>(cb + 0x60);
|
||||
int64_t f2 = *reinterpret_cast<int64_t*>(cb + 0x100);
|
||||
int64_t f3 = *reinterpret_cast<int64_t*>(cb + 0x1A0);
|
||||
|
||||
if (!is_address_in_game_region(f1) || !is_address_in_game_region(f2) || !is_address_in_game_region(f3))
|
||||
return false;
|
||||
|
||||
auto value = *(uint8_t*)(fptr);
|
||||
return value == 0xE9;
|
||||
}
|
||||
|
||||
bool is_unwanted_dependency(__int64 cb)
|
||||
{
|
||||
auto f1 = *(__int64*)(cb + 0x60);
|
||||
auto f2 = *(__int64*)(cb + 0x100);
|
||||
|
||||
if (!is_address_in_game_region(f1) || (f2 && !is_address_in_game_region(f2)))
|
||||
if(*reinterpret_cast<uint8_t*>(f1) != 0xE9)
|
||||
return false;
|
||||
|
||||
return is_jump(f1) || is_jump(f2);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool nullsub()
|
||||
@ -51,12 +56,16 @@ namespace big
|
||||
return true; // returning false would cause the dependency to requeue
|
||||
}
|
||||
|
||||
int hooks::queue_dependency(void* a1, int a2, void* dependency)
|
||||
int hooks::queue_dependency(void* a1, int a2, int64_t dependency)
|
||||
{
|
||||
if (is_unwanted_dependency((__int64)dependency))
|
||||
if (is_unwanted_dependency(dependency))
|
||||
{
|
||||
*(void**)((__int64)dependency + 0x60) = nullsub;
|
||||
*(void**)((__int64)dependency + 0x100) = nullsub;
|
||||
LOG(INFO) << "Blocking AC Verifier " << std::hex << *reinterpret_cast<int64_t*>(dependency + 0x60) - reinterpret_cast<int64_t>(GetModuleHandleA(0));
|
||||
ac_verifier* verifier = reinterpret_cast<ac_verifier*>(dependency - 0x30);
|
||||
verifier->m_delay = INT_MAX; // makes it so these won't queue in the future
|
||||
*reinterpret_cast<void**>(dependency + 0x60) = nullsub;
|
||||
*reinterpret_cast<void**>(dependency + 0x100) = nullsub;
|
||||
*reinterpret_cast<void**>(dependency + 0x1A0) = nullsub;
|
||||
}
|
||||
|
||||
return g_hooking->get_original<hooks::queue_dependency>()(a1, a2, dependency);
|
||||
|
43
src/main.cpp
43
src/main.cpp
@ -9,6 +9,7 @@
|
||||
#include "lua/lua_manager.hpp"
|
||||
#include "native_hooks/native_hooks.hpp"
|
||||
#include "pointers.hpp"
|
||||
#include "rage/gameSkeleton.hpp"
|
||||
#include "renderer.hpp"
|
||||
#include "script_mgr.hpp"
|
||||
#include "services/api/api_service.hpp"
|
||||
@ -36,6 +37,41 @@
|
||||
#include "thread_pool.hpp"
|
||||
#include "version.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
void disable_anticheat_skeleton()
|
||||
{
|
||||
for (rage::game_skeleton_update_mode* mode = g_pointers->m_gta.m_game_skeleton->m_update_modes; mode; mode = mode->m_next)
|
||||
{
|
||||
for (rage::game_skeleton_update_base* update_node = mode->m_head; update_node; update_node = update_node->m_next)
|
||||
{
|
||||
if (update_node->m_hash != RAGE_JOAAT("Common Main"))
|
||||
continue;
|
||||
rage::game_skeleton_update_group* group = reinterpret_cast<rage::game_skeleton_update_group*>(update_node);
|
||||
for (rage::game_skeleton_update_base* group_child_node = group->m_head; group_child_node;
|
||||
group_child_node = group_child_node->m_next)
|
||||
{
|
||||
// TamperActions is a leftover from the old AC, but still useful to block anyway
|
||||
if (group_child_node->m_hash != 0xA0F39FB6 && group_child_node->m_hash != RAGE_JOAAT("TamperActions"))
|
||||
continue;
|
||||
//LOG(INFO) << "Patching problematic skeleton update";
|
||||
reinterpret_cast<rage::game_skeleton_update_element*>(group_child_node)->m_function =
|
||||
g_pointers->m_gta.m_nullsub;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (rage::skeleton_data& i : g_pointers->m_gta.m_game_skeleton->m_sys_data)
|
||||
{
|
||||
if (i.m_hash != 0xA0F39FB6 && i.m_hash != RAGE_JOAAT("TamperActions"))
|
||||
continue;
|
||||
//LOG(INFO) << "Patching problematic skeleton init/shutdown";
|
||||
i.m_init_func = reinterpret_cast<uint64_t>(g_pointers->m_gta.m_nullsub);
|
||||
i.m_shutdown_func = reinterpret_cast<uint64_t>(g_pointers->m_gta.m_nullsub);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
|
||||
{
|
||||
@ -75,6 +111,9 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
|
||||
auto pointers_instance = std::make_unique<pointers>();
|
||||
LOG(INFO) << "Pointers initialized.";
|
||||
|
||||
disable_anticheat_skeleton();
|
||||
LOG(INFO) << "Disabled anticheat gameskeleton.";
|
||||
|
||||
auto byte_patch_manager_instance = std::make_unique<byte_patch_manager>();
|
||||
LOG(INFO) << "Byte Patch Manager initialized.";
|
||||
|
||||
@ -85,8 +124,8 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
|
||||
auto fiber_pool_instance = std::make_unique<fiber_pool>(11);
|
||||
LOG(INFO) << "Fiber pool initialized.";
|
||||
|
||||
g_http_client.init(g_file_manager.get_project_file("./proxy_settings.json"));
|
||||
LOG(INFO) << "HTTP Client initialized.";
|
||||
g_http_client.init(g_file_manager.get_project_file("./proxy_settings.json"));
|
||||
LOG(INFO) << "HTTP Client initialized.";
|
||||
|
||||
g_translation_service.init();
|
||||
LOG(INFO) << "Translation Service initialized.";
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "hooking.hpp"
|
||||
#include "memory/all.hpp"
|
||||
#include "rage/atSingleton.hpp"
|
||||
#include "rage/gameSkeleton.hpp"
|
||||
#include "sc_pointers_layout_info.hpp"
|
||||
#include "security/RageSecurity.hpp"
|
||||
|
||||
@ -1722,13 +1723,22 @@ namespace big
|
||||
g_pointers->m_gta.m_is_social_club_overlay_active = ptr.add(2).rip().as<bool*>();
|
||||
}
|
||||
},
|
||||
// Game Skeleton Update
|
||||
// Game Skeleton
|
||||
{
|
||||
"GSU",
|
||||
"40 53 48 83 EC 20 48 8B 81 40 01",
|
||||
"GS",
|
||||
"48 8D 0D ? ? ? ? BA ? ? ? ? 74 05 BA ? ? ? ? E8 ? ? ? ? E8 ? ? ? ? C6 05 ? ? ? ? ? 48 8D 0D ? ? ? ? BA ? ? ? ? 84 DB 75 05 BA ? ? ? ? E8 ? ? ? ? 48 8B CD C6 05 ? ? ? ? ? E8 ? ? ? ? 84",
|
||||
[](memory::handle ptr)
|
||||
{
|
||||
g_pointers->m_gta.m_game_skeleton_update = ptr.as<PVOID>();
|
||||
g_pointers->m_gta.m_game_skeleton = ptr.add(3).rip().as<rage::game_skeleton*>();
|
||||
}
|
||||
},
|
||||
// Nullsub
|
||||
{
|
||||
"NS",
|
||||
"C3",
|
||||
[](memory::handle ptr)
|
||||
{
|
||||
g_pointers->m_gta.m_nullsub = ptr.as<void(*)()>();
|
||||
}
|
||||
},
|
||||
// Get Ped Bone
|
||||
|
@ -7,7 +7,7 @@ namespace big
|
||||
{
|
||||
public:
|
||||
constexpr script_global(std::size_t index) :
|
||||
m_index(index)
|
||||
m_index(index)
|
||||
{
|
||||
}
|
||||
|
||||
@ -35,6 +35,5 @@ namespace big
|
||||
private:
|
||||
void* get() const;
|
||||
std::size_t m_index;
|
||||
|
||||
};
|
||||
}
|
||||
|
@ -18,8 +18,8 @@ namespace big
|
||||
}
|
||||
|
||||
script_local::script_local(std::size_t index) :
|
||||
m_index(index),
|
||||
m_stack(nullptr)
|
||||
m_index(index),
|
||||
m_stack(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
#include "common.hpp"
|
||||
#include "gta/script_thread.hpp"
|
||||
#include "script/tlsContext.hpp"
|
||||
#include "gta_util.hpp"
|
||||
#include "invoker.hpp"
|
||||
#include "pointers.hpp"
|
||||
#include "script/tlsContext.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include "common.hpp"
|
||||
#include "script.hpp"
|
||||
#include "lua/lua_manager.hpp"
|
||||
#include "script.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
|
@ -4,8 +4,8 @@ namespace big
|
||||
{
|
||||
thread_pool::thread_pool(const std::size_t preallocated_thread_count) :
|
||||
m_accept_jobs(true),
|
||||
m_allocated_thread_count(preallocated_thread_count),
|
||||
m_busy_threads(0)
|
||||
m_allocated_thread_count(preallocated_thread_count),
|
||||
m_busy_threads(0)
|
||||
{
|
||||
rescale_thread_pool();
|
||||
|
||||
|
Reference in New Issue
Block a user