#include "backend/backend.hpp" #include "byte_patch_manager.hpp" #include "common.hpp" #include "fiber_pool.hpp" #include "gui.hpp" #include "hooking/hooking.hpp" #include "http_client/http_client.hpp" #include "logger/exception_handler.hpp" #include "lua/lua_manager.hpp" #include "native_hooks/native_hooks.hpp" #include "pointers.hpp" #include "rage/gameSkeleton.hpp" #include "renderer/renderer.hpp" #include "script_mgr.hpp" #include "services/api/api_service.hpp" #include "services/context_menu/context_menu_service.hpp" #include "services/custom_text/custom_text_service.hpp" #include "services/gta_data/gta_data_service.hpp" #include "services/gui/gui_service.hpp" #include "services/hotkey/hotkey_service.hpp" #include "services/matchmaking/matchmaking_service.hpp" #include "services/mobile/mobile_service.hpp" #include "services/model_preview/model_preview_service.hpp" #include "services/notifications/notification_service.hpp" #include "services/orbital_drone/orbital_drone.hpp" #include "services/pickups/pickup_service.hpp" #include "services/player_database/player_database_service.hpp" #include "services/players/player_service.hpp" #include "services/script_connection/script_connection_service.hpp" #include "services/script_patcher/script_patcher_service.hpp" #include "services/squad_spawner/squad_spawner.hpp" #include "services/tunables/tunables_service.hpp" #include "services/vehicle/handling_service.hpp" #include "services/vehicle/vehicle_control_service.hpp" #include "services/vehicle/xml_vehicles_service.hpp" #include "services/xml_maps/xml_map_service.hpp" #include "thread_pool.hpp" #include "util/is_proton.hpp" #include "version.hpp" namespace big { bool disable_anticheat_skeleton() { bool patched = false; 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(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; patched = true; //LOG(INFO) << "Patching problematic skeleton update"; reinterpret_cast(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; i.m_init_func = reinterpret_cast(g_pointers->m_gta.m_nullsub); i.m_shutdown_func = reinterpret_cast(g_pointers->m_gta.m_nullsub); } return patched; } std::string ReadRegistryKeySZ(HKEY hKeyParent, std::string subkey, std::string valueName) { HKEY hKey; char value[1024]; DWORD value_length = 1024; LONG ret = RegOpenKeyEx(hKeyParent, subkey.c_str(), 0, KEY_READ, &hKey); if (ret != ERROR_SUCCESS) { LOG(INFO) << "Unable to read registry key " << subkey; return ""; } ret = RegQueryValueEx(hKey, valueName.c_str(), NULL, NULL, (LPBYTE)&value, &value_length); RegCloseKey(hKey); if (ret != ERROR_SUCCESS) { LOG(INFO) << "Unable to read registry key " << valueName; return ""; } return std::string(value); } DWORD ReadRegistryKeyDWORD(HKEY hKeyParent, std::string subkey, std::string valueName) { HKEY hKey; DWORD value; DWORD value_length = sizeof(DWORD); LONG ret = RegOpenKeyEx(hKeyParent, subkey.c_str(), 0, KEY_READ, &hKey); if (ret != ERROR_SUCCESS) { LOG(INFO) << "Unable to read registry key " << subkey; return NULL; } ret = RegQueryValueEx(hKey, valueName.c_str(), NULL, NULL, (LPBYTE)&value, &value_length); RegCloseKey(hKey); if (ret != ERROR_SUCCESS) { LOG(INFO) << "Unable to read registry key " << valueName; return NULL; } return value; } std::unique_ptr GetWindowsVersion() { typedef LPWSTR(WINAPI * BFS)(LPCWSTR); LPWSTR UTF16 = BFS(GetProcAddress(LoadLibrary("winbrand.dll"), "BrandingFormatString"))(L"%WINDOWS_LONG%"); int BufferSize = WideCharToMultiByte(CP_UTF8, 0, UTF16, -1, NULL, 0, NULL, NULL); std::unique_ptr UTF8(new char[BufferSize]); WideCharToMultiByte(CP_UTF8, 0, UTF16, -1, UTF8.get(), BufferSize, NULL, NULL); // BrandingFormatString requires a GlobalFree. GlobalFree(UTF16); return UTF8; } } BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID) { using namespace big; if (reason == DLL_PROCESS_ATTACH) { DisableThreadLibraryCalls(hmod); g_hmodule = hmod; g_main_thread = CreateThread( nullptr, 0, [](PVOID) -> DWORD { auto handler = exception_handler(); while (!FindWindow("grcWindow", nullptr)) std::this_thread::sleep_for(100ms); std::filesystem::path base_dir = std::getenv("appdata"); base_dir /= "YimMenu"; g_file_manager.init(base_dir); auto logger_instance = std::make_unique("YimMenu", g_file_manager.get_project_file("./cout.log")); EnableMenuItem(GetSystemMenu(GetConsoleWindow(), 0), SC_CLOSE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); std::srand(std::chrono::system_clock::now().time_since_epoch().count()); LOG(INFO) << "Yim's Menu Initializing"; LOGF(INFO, "Git Info\n\tBranch:\t{}\n\tHash:\t{}\n\tDate:\t{}", version::GIT_BRANCH, version::GIT_SHA1, version::GIT_DATE); // more tech debt, YAY! if (is_proton()) { LOG(INFO) << "Running on proton!"; } else { auto display_version = ReadRegistryKeySZ(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "DisplayVersion"); auto current_build = ReadRegistryKeySZ(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "CurrentBuild"); auto UBR = ReadRegistryKeyDWORD(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "UBR"); LOG(INFO) << GetWindowsVersion() << " Version " << display_version << " (OS Build " << current_build << "." << UBR << ")"; } #ifndef NDEBUG LOG(WARNING) << "Debug Build. Switch to RelWithDebInfo or Release Build for a more stable experience"; #endif auto thread_pool_instance = std::make_unique(); LOG(INFO) << "Thread pool initialized."; g.init(g_file_manager.get_project_file("./settings.json")); LOG(INFO) << "Settings Loaded."; auto pointers_instance = std::make_unique(); LOG(INFO) << "Pointers initialized."; while (!disable_anticheat_skeleton()) { LOG(WARNING) << "Failed patching anticheat gameskeleton (injected too early?). Waiting 100ms and trying again"; std::this_thread::sleep_for(100ms); } LOG(INFO) << "Disabled anticheat gameskeleton."; auto byte_patch_manager_instance = std::make_unique(); LOG(INFO) << "Byte Patch Manager initialized."; g_renderer.init(); LOG(INFO) << "Renderer initialized."; auto gui_instance = std::make_unique(); auto fiber_pool_instance = std::make_unique(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_translation_service.init(); LOG(INFO) << "Translation Service initialized."; auto hooking_instance = std::make_unique(); LOG(INFO) << "Hooking initialized."; auto context_menu_service_instance = std::make_unique(); auto custom_text_service_instance = std::make_unique(); auto mobile_service_instance = std::make_unique(); auto notification_service_instance = std::make_unique(); auto pickup_service_instance = std::make_unique(); auto player_service_instance = std::make_unique(); auto gta_data_service_instance = std::make_unique(); auto model_preview_service_instance = std::make_unique(); auto handling_service_instance = std::make_unique(); auto gui_service_instance = std::make_unique(); auto script_patcher_service_instance = std::make_unique(); auto player_database_service_instance = std::make_unique(); auto hotkey_service_instance = std::make_unique(); auto matchmaking_service_instance = std::make_unique(); auto api_service_instance = std::make_unique(); auto tunables_service_instance = std::make_unique(); auto script_connection_service_instance = std::make_unique(); auto xml_vehicles_service_instance = std::make_unique(); auto xml_maps_service_instance = std::make_unique(); LOG(INFO) << "Registered service instances..."; g_script_mgr.add_script(std::make_unique