Removed StackWalker and replaced it with g3log exception handling.
Updated natives for 1.50. Added settings JSON implementation. Refactored spawn vehicle bypass to not crash. (removed VMT hook)
This commit is contained in:
parent
87599327c5
commit
01d48cd314
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -14,7 +14,7 @@
|
||||
path = vendor/ImGui
|
||||
url = https://github.com/ocornut/imgui
|
||||
ignore = dirty
|
||||
[submodule "vendor/StackWalker"]
|
||||
path = vendor/StackWalker
|
||||
url = https://github.com/JochenKalmbach/StackWalker
|
||||
[submodule "vendor/g3log"]
|
||||
path = vendor/g3log
|
||||
url = https://github.com/KjellKod/g3log.git
|
||||
ignore = dirty
|
||||
|
BIN
BigBaseV2.lnk
Normal file
BIN
BigBaseV2.lnk
Normal file
Binary file not shown.
@ -47,10 +47,11 @@
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <StackWalker.h>
|
||||
|
||||
#include "logger.hpp"
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
namespace big
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
@ -62,16 +63,4 @@ namespace big
|
||||
inline HANDLE g_main_thread{};
|
||||
inline DWORD g_main_thread_id{};
|
||||
inline std::atomic_bool g_running{ true };
|
||||
|
||||
struct stackwalker : public StackWalker
|
||||
{
|
||||
using StackWalker::StackWalker;
|
||||
|
||||
void OnOutput(LPCSTR szText) override
|
||||
{
|
||||
g_logger->raw(log_color::red, szText);
|
||||
}
|
||||
};
|
||||
|
||||
inline stackwalker g_stackwalker;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,11 +2,11 @@
|
||||
#include "detour_hook.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "memory/handle.hpp"
|
||||
#include <MinHook.h>
|
||||
#include <..\MinHook\include\MinHook.h>
|
||||
|
||||
namespace big
|
||||
{
|
||||
detour_hook::detour_hook(std::string name, void *target, void *detour) :
|
||||
detour_hook::detour_hook(std::string name, void* target, void* detour) :
|
||||
m_name(std::move(name)),
|
||||
m_target(target),
|
||||
m_detour(detour)
|
||||
@ -15,12 +15,11 @@ namespace big
|
||||
|
||||
if (auto status = MH_CreateHook(m_target, m_detour, &m_original); status == MH_OK)
|
||||
{
|
||||
LOG_INFO("Created hook '{}'.", m_name);
|
||||
LOG(INFO_TO_FILE) << "Created hook '" << m_name << "'.";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error(fmt::format("Failed to create hook '{}' at 0x{:X} (error: {})", m_name, reinterpret_cast<std::uintptr_t>(m_target), MH_StatusToString(status)));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,14 +30,14 @@ namespace big
|
||||
MH_RemoveHook(m_target);
|
||||
}
|
||||
|
||||
LOG_INFO("Removed hook '{}',", m_name);
|
||||
LOG(INFO) << "Removed hook '" << m_name << "'.";
|
||||
}
|
||||
|
||||
void detour_hook::enable()
|
||||
{
|
||||
if (auto status = MH_EnableHook(m_target); status == MH_OK)
|
||||
{
|
||||
LOG_INFO("Enabled hook '{}'.", m_name);
|
||||
LOG(INFO_TO_FILE) << "Enabled hook '" << m_name << "'.";
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -50,15 +49,15 @@ namespace big
|
||||
{
|
||||
if (auto status = MH_DisableHook(m_target); status == MH_OK)
|
||||
{
|
||||
LOG_INFO("Disabled hook '{}'", m_name);
|
||||
LOG(INFO_TO_FILE) << "Disabled hook '" << m_name << "'.";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Failed to disable hook '{}'.", m_name);
|
||||
LOG(WARNING) << "Failed to disable hook '" << m_name << "'.";
|
||||
}
|
||||
}
|
||||
|
||||
DWORD exp_handler(PEXCEPTION_POINTERS exp, std::string const &name)
|
||||
DWORD exp_handler(PEXCEPTION_POINTERS exp, std::string const& name)
|
||||
{
|
||||
return exp->ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION
|
||||
? EXCEPTION_EXECUTE_HANDLER
|
||||
|
@ -14,7 +14,11 @@ namespace big
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
run_tick();
|
||||
TRY_CLAUSE
|
||||
{
|
||||
run_tick();
|
||||
}
|
||||
EXCEPT_CLAUSE
|
||||
script::get_current()->yield();
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +78,8 @@ using Any = std::uint32_t;
|
||||
using Hash = std::uint32_t;
|
||||
using Entity = std::int32_t;
|
||||
using Player = std::int32_t;
|
||||
using FireId = std::int32_t;
|
||||
using Interior = std::int32_t;
|
||||
using Ped = Entity;
|
||||
using Vehicle = Entity;
|
||||
using Cam = std::int32_t;
|
||||
|
@ -12,7 +12,8 @@
|
||||
#include "script.hpp"
|
||||
|
||||
#include <imgui.h>
|
||||
#include <StackWalker.h>
|
||||
|
||||
#include "gui/base_tab.h"
|
||||
|
||||
namespace big
|
||||
{
|
||||
@ -96,56 +97,17 @@ namespace big
|
||||
|
||||
void gui::dx_on_tick()
|
||||
{
|
||||
if (ImGui::Begin("BigBaseV2"))
|
||||
TRY_CLAUSE
|
||||
{
|
||||
static bool demo_bool = true;
|
||||
static int demo_int = 1;
|
||||
static float demo_float = 1.f;
|
||||
|
||||
static const char *demo_combo[]
|
||||
if (ImGui::Begin("BigBaseV2"))
|
||||
{
|
||||
"One",
|
||||
"Two",
|
||||
"Three"
|
||||
};
|
||||
static int demo_combo_pos = 0;
|
||||
|
||||
ImGui::Checkbox("Bool", &demo_bool);
|
||||
ImGui::SliderInt("Int", &demo_int, 0, 10);
|
||||
ImGui::SliderFloat("Float", &demo_float, 0.f, 10.f);
|
||||
ImGui::Combo("Combo", &demo_combo_pos, demo_combo, sizeof(demo_combo) / sizeof(*demo_combo));
|
||||
|
||||
if (ImGui::Button("Spawn a vehicle"))
|
||||
{
|
||||
g_fiber_pool->queue_job([]
|
||||
{
|
||||
constexpr auto hash = RAGE_JOAAT("adder");
|
||||
while (!STREAMING::HAS_MODEL_LOADED(hash))
|
||||
{
|
||||
STREAMING::REQUEST_MODEL(hash);
|
||||
script::get_current()->yield();
|
||||
}
|
||||
|
||||
auto pos = ENTITY::GET_ENTITY_COORDS(PLAYER::PLAYER_PED_ID(), true);
|
||||
auto vehicle = VEHICLE::CREATE_VEHICLE(hash, pos.x, pos.y, pos.z, 0.f, true, true);
|
||||
|
||||
if (*g_pointers->m_is_session_started)
|
||||
{
|
||||
DECORATOR::DECOR_SET_INT(vehicle, "MPBitset", 0);
|
||||
}
|
||||
|
||||
STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(hash);
|
||||
});
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::Button("Unload"))
|
||||
{
|
||||
g_running = false;
|
||||
ImGui::BeginTabBar("tabbar");
|
||||
base_tab::render_base_tab();
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
ImGui::End();
|
||||
EXCEPT_CLAUSE
|
||||
}
|
||||
|
||||
void gui::script_init()
|
||||
@ -154,10 +116,14 @@ namespace big
|
||||
|
||||
void gui::script_on_tick()
|
||||
{
|
||||
if (g_gui.m_opened)
|
||||
TRY_CLAUSE
|
||||
{
|
||||
CONTROLS::DISABLE_ALL_CONTROL_ACTIONS(0);
|
||||
if (g_gui.m_opened)
|
||||
{
|
||||
PAD::DISABLE_ALL_CONTROL_ACTIONS(0);
|
||||
}
|
||||
}
|
||||
EXCEPT_CLAUSE
|
||||
}
|
||||
|
||||
void gui::script_func()
|
||||
|
99
BigBaseV2/src/gui/base_tab.cpp
Normal file
99
BigBaseV2/src/gui/base_tab.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
#include "common.hpp"
|
||||
#include "base_tab.h"
|
||||
#include "imgui.h"
|
||||
#include "script.hpp"
|
||||
#include "fiber_pool.hpp"
|
||||
#include "natives.hpp"
|
||||
#include "gta_util.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
void base_tab::render_base_tab()
|
||||
{
|
||||
if (ImGui::BeginTabItem("Test"))
|
||||
{
|
||||
static const char* demo_combo[]
|
||||
{
|
||||
"One",
|
||||
"Two",
|
||||
"Three"
|
||||
};
|
||||
static double min = 0., max = 10.;
|
||||
|
||||
//If you want to add a new option, you have to first declare it in settings.h's default_options, otherwise, this code will crash when trying to access an option that does not exist in memory.
|
||||
if (ImGui::Checkbox("Bool", g_settings.options["demo bool"].get<bool*>()))
|
||||
g_settings.save();
|
||||
if (ImGui::SliderInt("Int", (PINT)g_settings.options["demo int"].get<int64_t*>(), 0, 10))
|
||||
g_settings.save();
|
||||
if (ImGui::SliderScalar("Double", ImGuiDataType_Double, g_settings.options["demo double"].get<double*>(), &min, &max)) //JSON does not describe rational numbers as integer/float/double/etc types, it is just "number". See: https://nlohmann.github.io/json/
|
||||
g_settings.save();
|
||||
ImGui::Combo("Combo", (PINT)g_settings.options["demo combo"].get<int64_t*>(), demo_combo, sizeof(demo_combo) / sizeof(*demo_combo));
|
||||
|
||||
if (ImGui::Button("Spawn an Adder"))
|
||||
{
|
||||
QUEUE_JOB_BEGIN_CLAUSE()
|
||||
{
|
||||
constexpr auto hash = RAGE_JOAAT("adder");
|
||||
while (!STREAMING::HAS_MODEL_LOADED(hash))
|
||||
{
|
||||
STREAMING::REQUEST_MODEL(hash);
|
||||
script::get_current()->yield();
|
||||
}
|
||||
|
||||
auto pos = ENTITY::GET_ENTITY_COORDS(PLAYER::PLAYER_PED_ID(), true);
|
||||
|
||||
while (!STREAMING::HAS_MODEL_LOADED(hash))
|
||||
{
|
||||
STREAMING::REQUEST_MODEL(hash);
|
||||
script::get_current()->yield();
|
||||
}
|
||||
*(unsigned short*)g_pointers->m_model_spawn_bypass = 0x9090;
|
||||
Vehicle vehicle = VEHICLE::CREATE_VEHICLE(hash, pos.x, pos.y, pos.z, 0.f, TRUE, FALSE, FALSE);
|
||||
*(unsigned short*)g_pointers->m_model_spawn_bypass = 0x0574; //By writing the "old" bypass to the function, running CREATE_VEHICLE, then restoring it, the anti-cheat does not have enough time to catch the function in a dirty state.
|
||||
script::get_current()->yield();
|
||||
STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(hash);
|
||||
if (*g_pointers->m_is_session_started)
|
||||
{
|
||||
DECORATOR::DECOR_SET_INT(vehicle, "MPBitset", 0);
|
||||
ENTITY::_SET_ENTITY_SOMETHING(vehicle, TRUE); //True means it can be deleted by the engine when switching lobbies/missions/etc, false means the script is expected to clean it up.
|
||||
auto networkId = NETWORK::VEH_TO_NET(vehicle);
|
||||
if (NETWORK::NETWORK_GET_ENTITY_IS_NETWORKED(vehicle))
|
||||
NETWORK::SET_NETWORK_ID_EXISTS_ON_ALL_MACHINES(networkId, true);
|
||||
VEHICLE::SET_VEHICLE_IS_STOLEN(vehicle, FALSE);
|
||||
}
|
||||
|
||||
if (*g_pointers->m_is_session_started)
|
||||
{
|
||||
DECORATOR::DECOR_SET_INT(vehicle, "MPBitset", 0);
|
||||
}
|
||||
|
||||
STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(hash);
|
||||
}
|
||||
QUEUE_JOB_END_CLAUSE
|
||||
}
|
||||
|
||||
if (ImGui::Button("Test g3log crash within ImGui"))
|
||||
{
|
||||
*((PINT)nullptr) = 0xDEADBEEF;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Test g3log crash within GTA V Script"))
|
||||
{
|
||||
QUEUE_JOB_BEGIN_CLAUSE()
|
||||
{
|
||||
//PED::_0xB782F8238512BAD5(PLAYER::PLAYER_PED_ID(), nullptr); //This causes a crash at GTA5.exe+5845356 and nothing of value was in the log in the stack dump because of the context switch to GTA 5's memory. If you encounter something similar, you will have to figure out where the crash occured in the GTA 5 exe, and trace back that native, and figure out which function is calling the native that is crashing.
|
||||
*((PINT)nullptr) = 0xDEADBEEF;
|
||||
}
|
||||
QUEUE_JOB_END_CLAUSE
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::Button("Unload"))
|
||||
{
|
||||
g_running = false;
|
||||
}
|
||||
}
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
13
BigBaseV2/src/gui/base_tab.h
Normal file
13
BigBaseV2/src/gui/base_tab.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "common.hpp"
|
||||
#include "natives.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
class base_tab
|
||||
{
|
||||
public:
|
||||
static void render_base_tab();
|
||||
};
|
||||
}
|
@ -63,7 +63,6 @@ namespace big
|
||||
m_run_script_threads_hook.enable();
|
||||
m_convert_thread_to_fiber_hook.enable();
|
||||
|
||||
ensure_dynamic_hooks();
|
||||
m_enabled = true;
|
||||
}
|
||||
|
||||
@ -71,11 +70,6 @@ namespace big
|
||||
{
|
||||
m_enabled = false;
|
||||
|
||||
if (m_main_persistent_hook)
|
||||
{
|
||||
m_main_persistent_hook->disable();
|
||||
}
|
||||
|
||||
m_convert_thread_to_fiber_hook.disable();
|
||||
m_run_script_threads_hook.disable();
|
||||
|
||||
@ -84,20 +78,6 @@ namespace big
|
||||
m_swapchain_hook.disable();
|
||||
}
|
||||
|
||||
void hooking::ensure_dynamic_hooks()
|
||||
{
|
||||
if (!m_main_persistent_hook)
|
||||
{
|
||||
if (auto main_persistent = find_script_thread(RAGE_JOAAT("main_persistent")))
|
||||
{
|
||||
m_main_persistent_hook = std::make_unique<vmt_hook>(main_persistent->m_handler, hooks::main_persistent_num_funcs);
|
||||
m_main_persistent_hook->hook(hooks::main_persistent_dtor_index, &hooks::main_persistent_dtor);
|
||||
m_main_persistent_hook->hook(hooks::main_persistent_is_networked_index, &hooks::main_persistent_is_networked);
|
||||
m_main_persistent_hook->enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
minhook_keepalive::minhook_keepalive()
|
||||
{
|
||||
MH_Initialize();
|
||||
@ -110,85 +90,94 @@ namespace big
|
||||
|
||||
bool hooks::run_script_threads(std::uint32_t ops_to_execute)
|
||||
{
|
||||
if (g_running)
|
||||
TRY_CLAUSE
|
||||
{
|
||||
g_script_mgr.tick();
|
||||
}
|
||||
if (g_running)
|
||||
{
|
||||
g_script_mgr.tick();
|
||||
}
|
||||
|
||||
return g_hooking->m_run_script_threads_hook.get_original<functions::run_script_threads_t>()(ops_to_execute);
|
||||
return g_hooking->m_run_script_threads_hook.get_original<functions::run_script_threads_t>()(ops_to_execute);
|
||||
} EXCEPT_CLAUSE
|
||||
return false;
|
||||
}
|
||||
|
||||
void *hooks::convert_thread_to_fiber(void *param)
|
||||
{
|
||||
if (IsThreadAFiber())
|
||||
TRY_CLAUSE
|
||||
{
|
||||
return GetCurrentFiber();
|
||||
}
|
||||
if (IsThreadAFiber())
|
||||
{
|
||||
return GetCurrentFiber();
|
||||
}
|
||||
|
||||
return g_hooking->m_convert_thread_to_fiber_hook.get_original<decltype(&convert_thread_to_fiber)>()(param);
|
||||
return g_hooking->m_convert_thread_to_fiber_hook.get_original<decltype(&convert_thread_to_fiber)>()(param);
|
||||
} EXCEPT_CLAUSE
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HRESULT hooks::swapchain_present(IDXGISwapChain *this_, UINT sync_interval, UINT flags)
|
||||
{
|
||||
if (g_running)
|
||||
TRY_CLAUSE
|
||||
{
|
||||
g_renderer->on_present();
|
||||
}
|
||||
if (g_running)
|
||||
{
|
||||
g_renderer->on_present();
|
||||
}
|
||||
|
||||
return g_hooking->m_swapchain_hook.get_original<decltype(&swapchain_present)>(swapchain_present_index)(this_, sync_interval, flags);
|
||||
return g_hooking->m_swapchain_hook.get_original<decltype(&swapchain_present)>(swapchain_present_index)(this_, sync_interval, flags);
|
||||
} EXCEPT_CLAUSE
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HRESULT hooks::swapchain_resizebuffers(IDXGISwapChain * this_, UINT buffer_count, UINT width, UINT height, DXGI_FORMAT new_format, UINT swapchain_flags)
|
||||
{
|
||||
if (g_running)
|
||||
TRY_CLAUSE
|
||||
{
|
||||
g_renderer->pre_reset();
|
||||
|
||||
auto result = g_hooking->m_swapchain_hook.get_original<decltype(&swapchain_resizebuffers)>(swapchain_resizebuffers_index)
|
||||
(this_, buffer_count, width, height, new_format, swapchain_flags);
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
if (g_running)
|
||||
{
|
||||
g_renderer->post_reset();
|
||||
g_renderer->pre_reset();
|
||||
|
||||
auto result = g_hooking->m_swapchain_hook.get_original<decltype(&swapchain_resizebuffers)>(swapchain_resizebuffers_index)
|
||||
(this_, buffer_count, width, height, new_format, swapchain_flags);
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
g_renderer->post_reset();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return g_hooking->m_swapchain_hook.get_original<decltype(&swapchain_resizebuffers)>(swapchain_resizebuffers_index)
|
||||
(this_, buffer_count, width, height, new_format, swapchain_flags);
|
||||
return g_hooking->m_swapchain_hook.get_original<decltype(&swapchain_resizebuffers)>(swapchain_resizebuffers_index)
|
||||
(this_, buffer_count, width, height, new_format, swapchain_flags);
|
||||
} EXCEPT_CLAUSE
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LRESULT hooks::wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
if (g_running)
|
||||
TRY_CLAUSE
|
||||
{
|
||||
g_renderer->wndproc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
if (g_running)
|
||||
{
|
||||
g_renderer->wndproc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
return CallWindowProcW(g_hooking->m_og_wndproc, hwnd, msg, wparam, lparam);
|
||||
return CallWindowProcW(g_hooking->m_og_wndproc, hwnd, msg, wparam, lparam);
|
||||
} EXCEPT_CLAUSE
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL hooks::set_cursor_pos(int x, int y)
|
||||
{
|
||||
if (g_gui.m_opened)
|
||||
TRY_CLAUSE
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (g_gui.m_opened)
|
||||
return true;
|
||||
|
||||
return g_hooking->m_set_cursor_pos_hook.get_original<decltype(&set_cursor_pos)>()(x, y);
|
||||
}
|
||||
|
||||
void hooks::main_persistent_dtor(CGameScriptHandler *this_, bool free_memory)
|
||||
{
|
||||
auto og_func = g_hooking->m_main_persistent_hook->get_original<decltype(&main_persistent_dtor)>(main_persistent_dtor_index);
|
||||
g_hooking->m_main_persistent_hook->disable();
|
||||
g_hooking->m_main_persistent_hook.reset();
|
||||
return og_func(this_, free_memory);
|
||||
}
|
||||
|
||||
bool hooks::main_persistent_is_networked(CGameScriptHandler *this_)
|
||||
{
|
||||
return *g_pointers->m_is_session_started;
|
||||
return g_hooking->m_set_cursor_pos_hook.get_original<decltype(&set_cursor_pos)>()(x, y);
|
||||
} EXCEPT_CLAUSE
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -20,12 +20,6 @@ namespace big
|
||||
|
||||
static LRESULT wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
static BOOL set_cursor_pos(int x, int y);
|
||||
|
||||
static constexpr auto main_persistent_num_funcs = 16;
|
||||
static constexpr auto main_persistent_dtor_index = 0;
|
||||
static constexpr auto main_persistent_is_networked_index = 6;
|
||||
static void main_persistent_dtor(CGameScriptHandler *this_, bool free_memory);
|
||||
static bool main_persistent_is_networked(CGameScriptHandler *this_);
|
||||
};
|
||||
|
||||
struct minhook_keepalive
|
||||
@ -44,7 +38,6 @@ namespace big
|
||||
void enable();
|
||||
void disable();
|
||||
|
||||
void ensure_dynamic_hooks();
|
||||
private:
|
||||
bool m_enabled{};
|
||||
minhook_keepalive m_minhook_keepalive;
|
||||
@ -55,7 +48,6 @@ namespace big
|
||||
|
||||
detour_hook m_run_script_threads_hook;
|
||||
detour_hook m_convert_thread_to_fiber_hook;
|
||||
std::unique_ptr<vmt_hook> m_main_persistent_hook;
|
||||
};
|
||||
|
||||
inline hooking *g_hooking{};
|
||||
|
@ -14,7 +14,7 @@ namespace big
|
||||
|
||||
void native_invoker::cache_handlers()
|
||||
{
|
||||
for (const rage::scrNativeMapping &mapping : g_crossmap)
|
||||
for (const rage::scrNativeMapping& mapping : g_crossmap)
|
||||
{
|
||||
rage::scrNativeHandler handler = g_pointers->m_get_native_handler(
|
||||
g_pointers->m_native_registration_table, mapping.second);
|
||||
@ -34,19 +34,12 @@ namespace big
|
||||
{
|
||||
rage::scrNativeHandler handler = it->second;
|
||||
|
||||
__try
|
||||
{
|
||||
handler(&m_call_context);
|
||||
g_pointers->m_fix_vectors(&m_call_context);
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
LOG_ERROR("Exception caught while trying to call 0x{:X} native.", hash);
|
||||
}
|
||||
handler(&m_call_context);
|
||||
g_pointers->m_fix_vectors(&m_call_context);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Failed to find 0x{:X} native's handler.", hash);
|
||||
[hash]() { LOG(WARNING) << "Failed to find " << HEX_TO_UPPER(hash) << " native's handler."; }();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,188 +1,211 @@
|
||||
#pragma once
|
||||
#include "common.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
enum class log_color : std::uint16_t
|
||||
{
|
||||
red = FOREGROUND_RED,
|
||||
green = FOREGROUND_GREEN,
|
||||
blue = FOREGROUND_BLUE,
|
||||
intensify = FOREGROUND_INTENSITY
|
||||
};
|
||||
|
||||
inline log_color operator|(log_color a, log_color b)
|
||||
{
|
||||
return static_cast<log_color>(static_cast<std::underlying_type_t<log_color>>(a) | static_cast<std::underlying_type_t<log_color>>(b));
|
||||
}
|
||||
|
||||
class logger;
|
||||
inline logger *g_logger{};
|
||||
|
||||
class logger
|
||||
{
|
||||
public:
|
||||
explicit logger() :
|
||||
m_file_path(std::getenv("appdata"))
|
||||
{
|
||||
m_file_path /= "BigBaseV2";
|
||||
try
|
||||
{
|
||||
if (!std::filesystem::exists(m_file_path))
|
||||
{
|
||||
std::filesystem::create_directory(m_file_path);
|
||||
}
|
||||
else if (!std::filesystem::is_directory(m_file_path))
|
||||
{
|
||||
std::filesystem::remove(m_file_path);
|
||||
std::filesystem::create_directory(m_file_path);
|
||||
}
|
||||
|
||||
m_file_path /= "BigBaseV2.log";
|
||||
m_file_out.open(m_file_path, std::ios_base::out | std::ios_base::app);
|
||||
}
|
||||
catch (std::filesystem::filesystem_error const&)
|
||||
{
|
||||
}
|
||||
|
||||
if ((m_did_console_exist = AttachConsole(GetCurrentProcessId())) == false)
|
||||
AllocConsole();
|
||||
|
||||
if ((m_console_handle = GetStdHandle(STD_OUTPUT_HANDLE)) != nullptr)
|
||||
{
|
||||
SetConsoleTitleA("BigBaseV2");
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
|
||||
m_console_out.open("CONOUT$", std::ios_base::out | std::ios_base::app);
|
||||
}
|
||||
|
||||
g_logger = this;
|
||||
}
|
||||
|
||||
~logger()
|
||||
{
|
||||
if (!m_did_console_exist)
|
||||
FreeConsole();
|
||||
|
||||
g_logger = nullptr;
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
void raw(log_color color, Args const &...args)
|
||||
{
|
||||
raw_to_console(color, args...);
|
||||
raw_to_file(args...);
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
void log(log_color color, std::string_view prefix, std::string_view format, Args const &...args)
|
||||
{
|
||||
auto message = fmt::format(format, args...);
|
||||
|
||||
auto time_since_epoch = std::time(nullptr);
|
||||
auto local_time = std::localtime(&time_since_epoch);
|
||||
|
||||
auto console_timestamp = fmt::format("[{:0>2}:{:0>2}:{:0>2}]", local_time->tm_hour, local_time->tm_min, local_time->tm_sec);
|
||||
auto file_timestamp = fmt::format("[{}-{}-{} {:0>2}:{:0>2}:{:0>2}]", local_time->tm_year + 1900, local_time->tm_mon + 1, local_time->tm_mday, local_time->tm_hour, local_time->tm_min, local_time->tm_sec);
|
||||
|
||||
raw_to_console(color, console_timestamp, " [", prefix, "] ", message, "\n");
|
||||
raw_to_file(file_timestamp, " [", prefix, "] ", message, "\n");
|
||||
}
|
||||
private:
|
||||
template <typename ...Args>
|
||||
void raw_to_console(log_color color, Args const &...args)
|
||||
{
|
||||
if (m_console_handle)
|
||||
{
|
||||
SetConsoleTextAttribute(m_console_handle, static_cast<std::uint16_t>(color));
|
||||
}
|
||||
|
||||
if (m_console_out)
|
||||
{
|
||||
((m_console_out << args), ...);
|
||||
m_console_out << std::flush;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
void raw_to_file(Args const &...args)
|
||||
{
|
||||
if (m_file_out)
|
||||
{
|
||||
((m_file_out << args), ...);
|
||||
m_file_out << std::flush;
|
||||
}
|
||||
}
|
||||
private:
|
||||
bool m_did_console_exist{};
|
||||
HANDLE m_console_handle{};
|
||||
std::ofstream m_console_out;
|
||||
|
||||
std::filesystem::path m_file_path;
|
||||
std::ofstream m_file_out;
|
||||
};
|
||||
|
||||
template <typename ...Args>
|
||||
inline void log_info(std::string_view format, Args const &...args)
|
||||
{
|
||||
if (g_logger)
|
||||
{
|
||||
g_logger->log(log_color::blue | log_color::intensify, "Info", format, args...);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugBreak();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
inline void log_error(std::string_view format, Args const &...args)
|
||||
{
|
||||
if (g_logger)
|
||||
{
|
||||
g_logger->log(log_color::green | log_color::intensify, "Error", format, args...);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugBreak();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
inline void log_trace(std::string_view format, Args const &...args)
|
||||
{
|
||||
if (g_logger)
|
||||
{
|
||||
g_logger->log(log_color::green | log_color::intensify, "Trace", format, args...);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugBreak();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
inline void log_raw(log_color color, Args const &...args)
|
||||
{
|
||||
if (g_logger)
|
||||
{
|
||||
g_logger->raw(color, args...);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugBreak();
|
||||
}
|
||||
}
|
||||
|
||||
#define LOG_INFO_IMPL(format, ...) (::big::log_info(format, __VA_ARGS__))
|
||||
#define LOG_INFO(format, ...) LOG_INFO_IMPL(format, __VA_ARGS__)
|
||||
|
||||
#define LOG_ERROR_IMPL(format, ...) (::big::log_error(format, __VA_ARGS__))
|
||||
#define LOG_ERROR(format, ...) LOG_ERROR_IMPL(format, __VA_ARGS__)
|
||||
|
||||
#define LOG_TRACE_IMPL(format, ...) (::big::log_trace(format, __VA_ARGS__))
|
||||
#define LOG_TRACE(format, ...) LOG_TRACE_IMPL(format, __VA_ARGS__)
|
||||
|
||||
#define LOG_RAW_IMPL(color, ...) (::big::log_raw(color, __VA_ARGS__))
|
||||
#define LOG_RAW(color, ...) LOG_RAW_IMPL(color, __VA_ARGS__)
|
||||
}
|
||||
#pragma once
|
||||
#include "common.hpp"
|
||||
#include <g3log/g3log.hpp>
|
||||
#include <g3log/logworker.hpp>
|
||||
|
||||
namespace big
|
||||
{
|
||||
template <typename TP>
|
||||
std::time_t to_time_t(TP tp)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
auto sctp = time_point_cast<system_clock::duration>(tp - TP::clock::now()
|
||||
+ system_clock::now());
|
||||
return system_clock::to_time_t(sctp);
|
||||
}
|
||||
|
||||
enum class log_color : std::uint16_t
|
||||
{
|
||||
red = FOREGROUND_RED,
|
||||
green = FOREGROUND_GREEN,
|
||||
blue = FOREGROUND_BLUE,
|
||||
intensify = FOREGROUND_INTENSITY
|
||||
};
|
||||
|
||||
enum LOG_FLAGS
|
||||
{
|
||||
FLAG_NO_DISK = (1 << 0),
|
||||
FLAG_NO_CONSOLE = (1 << 1)
|
||||
};
|
||||
|
||||
static const int kEventValue = 400;
|
||||
static const int kRawValue = 600;
|
||||
inline constexpr auto max_padding_length = 26;
|
||||
inline constexpr auto level_padding_length = 8;
|
||||
|
||||
const LEVELS INFO_TO_FILE{ INFO.value | FLAG_NO_CONSOLE, {"INFO"} },
|
||||
HACKER{ INFO.value, {"HACKER"} },
|
||||
EVENT{ kEventValue | FLAG_NO_CONSOLE, {"EVENT"} },
|
||||
RAW_GREEN_TO_CONSOLE{ kRawValue | FLAG_NO_DISK, {"RAW_GREEN_TO_CONSOLE"} },
|
||||
RAW_RED{ kRawValue, {"RAW_RED"} };
|
||||
|
||||
inline log_color operator|(log_color a, log_color b)
|
||||
{
|
||||
return static_cast<log_color>(static_cast<std::underlying_type_t<log_color>>(a) | static_cast<std::underlying_type_t<log_color>>(b));
|
||||
}
|
||||
|
||||
class logger;
|
||||
inline logger* g_logger{};
|
||||
|
||||
class logger
|
||||
{
|
||||
public:
|
||||
explicit logger() :
|
||||
m_file_path(std::getenv("appdata")),
|
||||
m_worker(g3::LogWorker::createLogWorker())
|
||||
{
|
||||
if ((m_did_console_exist = AttachConsole(GetCurrentProcessId())) == false)
|
||||
AllocConsole();
|
||||
|
||||
if ((m_console_handle = GetStdHandle(STD_OUTPUT_HANDLE)) != nullptr)
|
||||
{
|
||||
SetConsoleTitleA("BigBaseV2");
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
|
||||
m_console_out.open("CONOUT$", std::ios_base::out | std::ios_base::app);
|
||||
}
|
||||
|
||||
m_file_path /= "BigBaseV2";
|
||||
std::filesystem::path m_backup_path = m_file_path;
|
||||
m_backup_path /= "Backup";
|
||||
try
|
||||
{
|
||||
if (!std::filesystem::exists(m_file_path))
|
||||
{
|
||||
std::filesystem::create_directory(m_file_path);
|
||||
}
|
||||
else if (!std::filesystem::is_directory(m_file_path))
|
||||
{
|
||||
std::filesystem::remove(m_file_path);
|
||||
std::filesystem::create_directory(m_file_path);
|
||||
}
|
||||
if (!std::filesystem::exists(m_backup_path))
|
||||
{
|
||||
std::filesystem::create_directory(m_backup_path);
|
||||
}
|
||||
else if (!std::filesystem::is_directory(m_backup_path))
|
||||
{
|
||||
std::filesystem::remove(m_backup_path);
|
||||
std::filesystem::create_directory(m_backup_path);
|
||||
}
|
||||
|
||||
m_event_file_path = m_file_path;
|
||||
m_file_path /= "BigBaseV2.log";
|
||||
m_event_file_path /= "GTAEvents.log";
|
||||
|
||||
if (std::filesystem::exists(m_file_path))
|
||||
{
|
||||
auto file_time = std::filesystem::last_write_time(m_file_path);
|
||||
auto timet = to_time_t(file_time);
|
||||
auto local_time = std::localtime(&timet);
|
||||
|
||||
auto bigbase_timestamp = fmt::format("{:0>2}-{:0>2}-{}-{:0>2}-{:0>2}-{:0>2} BigBaseV2.log", local_time->tm_mon + 1, local_time->tm_mday, local_time->tm_year + 1900, local_time->tm_hour, local_time->tm_min, local_time->tm_sec);
|
||||
auto gta_events_timestamp = fmt::format("{:0>2}-{:0>2}-{}-{:0>2}-{:0>2}-{:0>2} GTAEvents.log", local_time->tm_mon + 1, local_time->tm_mday, local_time->tm_year + 1900, local_time->tm_hour, local_time->tm_min, local_time->tm_sec);
|
||||
|
||||
std::filesystem::copy_file(m_file_path, m_backup_path / bigbase_timestamp);
|
||||
if (std::filesystem::exists(m_event_file_path) && !std::filesystem::is_empty(m_event_file_path))
|
||||
std::filesystem::copy_file(m_event_file_path, m_backup_path / gta_events_timestamp);
|
||||
}
|
||||
|
||||
m_file_out.open(m_file_path, std::ios_base::out | std::ios_base::trunc);
|
||||
m_gta_event_file_out.open(m_event_file_path, std::ios_base::out | std::ios_base::trunc);
|
||||
|
||||
m_worker->addSink(std::make_unique<log_sink>(), &log_sink::callback);
|
||||
g3::initializeLogging(m_worker.get());
|
||||
g3::installCrashHandler();
|
||||
}
|
||||
catch (std::filesystem::filesystem_error const& error)
|
||||
{
|
||||
m_console_out << error.what();
|
||||
}
|
||||
|
||||
g_logger = this;
|
||||
}
|
||||
|
||||
~logger()
|
||||
{
|
||||
m_worker.reset();
|
||||
if (!m_did_console_exist)
|
||||
FreeConsole();
|
||||
|
||||
g_logger = nullptr;
|
||||
}
|
||||
|
||||
struct log_sink
|
||||
{
|
||||
std::map<std::string, log_color> log_colors = {
|
||||
{INFO.text, log_color::blue | log_color::intensify},
|
||||
{WARNING.text, log_color::red},
|
||||
{HACKER.text, log_color::green | log_color::intensify},
|
||||
{FATAL.text, log_color::red | log_color::intensify},
|
||||
{G3LOG_DEBUG.text, log_color::blue},
|
||||
{RAW_RED.text, log_color::red},
|
||||
{RAW_GREEN_TO_CONSOLE.text, log_color::green | log_color::intensify}
|
||||
};
|
||||
|
||||
void callback(g3::LogMessageMover log)
|
||||
{
|
||||
g3::LogMessage log_message = log.get();
|
||||
int level_value = log_message._level.value;
|
||||
|
||||
bool is_raw = level_value == RAW_RED.value || level_value == RAW_GREEN_TO_CONSOLE.value;
|
||||
|
||||
if (!(level_value & FLAG_NO_CONSOLE))
|
||||
{
|
||||
SetConsoleTextAttribute(g_logger->m_console_handle, static_cast<std::uint16_t>(log_colors[log_message._level.text]));
|
||||
g_logger->m_console_out << log_message.toString(is_raw ? format_raw : format_console) << std::flush;
|
||||
}
|
||||
|
||||
if (!(level_value & FLAG_NO_DISK))
|
||||
{
|
||||
if (level_value == EVENT.value)
|
||||
g_logger->m_gta_event_file_out << log_message.toString(format_file) << std::flush;
|
||||
else
|
||||
g_logger->m_file_out << log_message.toString(is_raw ? format_raw : format_file) << std::flush;
|
||||
}
|
||||
}
|
||||
|
||||
static std::string format_file(const g3::LogMessage& msg)
|
||||
{
|
||||
std::string file_name_with_line = "[" + msg.file() + ":" + msg.line() + "]";
|
||||
std::stringstream out;
|
||||
out << "[" << msg.timestamp("%H:%M:%S") << "] [" << std::left << std::setw(level_padding_length) << msg.level().append("]") << std::setw(max_padding_length) << file_name_with_line;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
static std::string format_console(const g3::LogMessage& msg)
|
||||
{
|
||||
std::stringstream out;
|
||||
out << "[" << msg.timestamp("%H:%M:%S") << "] ";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
static std::string format_raw(const g3::LogMessage& msg)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ...Args>
|
||||
inline void log_now(std::string_view format, Args const& ...args)
|
||||
{
|
||||
auto message = fmt::format(format, args...);
|
||||
if (m_file_out)
|
||||
m_file_out << message << std::endl << std::flush;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_did_console_exist{};
|
||||
HANDLE m_console_handle{};
|
||||
std::ofstream m_console_out;
|
||||
std::filesystem::path m_file_path;
|
||||
std::filesystem::path m_event_file_path;
|
||||
std::ofstream m_file_out;
|
||||
std::ofstream m_gta_event_file_out;
|
||||
std::unique_ptr<g3::LogWorker> m_worker;
|
||||
};
|
||||
|
||||
|
||||
#define LOG_NOW(format, ...) g_logger->log_now(format, __VA_ARGS__)
|
||||
#define HEX_TO_UPPER(value) "0x" << std::hex << std::uppercase << (DWORD64)value << std::dec << std::nouppercase
|
||||
}
|
||||
|
@ -21,102 +21,83 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
|
||||
auto logger_instance = std::make_unique<logger>();
|
||||
try
|
||||
{
|
||||
|
||||
LOG_RAW(log_color::green | log_color::intensify,
|
||||
u8R"kek( ...
|
||||
;::::;
|
||||
;::::; :;
|
||||
;:::::' :;
|
||||
;:::::; ;.
|
||||
,:::::' ; OOO\
|
||||
::::::; ; OOOOO\
|
||||
;:::::; ; OOOOOOOO
|
||||
,;::::::; ;' / OOOOOOO
|
||||
;:::::::::`. ,,,;. / / DOOOOOO
|
||||
.';:::::::::::::::::;, / / DOOOO
|
||||
,::::::;::::::;;;;::::;, / / DOOO
|
||||
;`::::::`'::::::;;;::::: ,#/ / DOOO
|
||||
:`:::::::`;::::::;;::: ;::# / DOOO
|
||||
::`:::::::`;:::::::: ;::::# / DOO
|
||||
`:`:::::::`;:::::: ;::::::#/ DOO
|
||||
:::`:::::::`;; ;:::::::::## OO
|
||||
::::`:::::::`;::::::::;:::# OO
|
||||
`:::::`::::::::::::;'`:;::# O
|
||||
`:::::`::::::::;' / / `:#
|
||||
::::::`:::::;' / / `#
|
||||
|
||||
)kek");
|
||||
|
||||
LOG(RAW_GREEN_TO_CONSOLE) << u8R"kek(
|
||||
______ _ ______ ______
|
||||
(____ \(_) (____ \ (_____ \
|
||||
____) )_ ____ ____) ) ____ ___ ____ _ _ ____) )
|
||||
| __ (| |/ _ | __ ( / _ |/___)/ _ ) | | /_____/
|
||||
| |__) ) ( ( | | |__) | ( | |___ ( (/ / \ V /_______
|
||||
|______/|_|\_|| |______/ \_||_(___/ \____) \_/(_______)
|
||||
(_____|)kek";
|
||||
auto pointers_instance = std::make_unique<pointers>();
|
||||
LOG_INFO("Pointers initialized.");
|
||||
LOG(INFO) << "Pointers initialized.";
|
||||
|
||||
if (*g_pointers->m_game_state != eGameState::Playing)
|
||||
{
|
||||
LOG_INFO("Waiting for the game to load.");
|
||||
do
|
||||
{
|
||||
std::this_thread::sleep_for(100ms);
|
||||
} while (*g_pointers->m_game_state != eGameState::Playing);
|
||||
|
||||
LOG_INFO("The game has loaded.");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_INFO("The game is already loaded.");
|
||||
}
|
||||
//if (*g_pointers->m_game_state != eGameState::Playing)
|
||||
//{
|
||||
// LOG_INFO("Waiting for the game to load.");
|
||||
// do
|
||||
// {
|
||||
// std::this_thread::sleep_for(100ms);
|
||||
// } while (*g_pointers->m_game_state != eGameState::Playing);
|
||||
//
|
||||
// LOG_INFO("The game has loaded.");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// LOG_INFO("The game is already loaded.");
|
||||
//}
|
||||
|
||||
auto renderer_instance = std::make_unique<renderer>();
|
||||
LOG_INFO("Renderer initialized.");
|
||||
LOG(INFO) << "Renderer initialized.";
|
||||
|
||||
auto fiber_pool_instance = std::make_unique<fiber_pool>(10);
|
||||
LOG_INFO("Fiber pool initialized.");
|
||||
LOG(INFO) << "Fiber pool initialized.";
|
||||
|
||||
auto hooking_instance = std::make_unique<hooking>();
|
||||
LOG_INFO("Hooking initialized.");
|
||||
LOG(INFO) << "Hooking initialized.";
|
||||
|
||||
g_settings.load();
|
||||
LOG(INFO) << "Settings Loaded.";
|
||||
|
||||
g_script_mgr.add_script(std::make_unique<script>(&features::script_func));
|
||||
g_script_mgr.add_script(std::make_unique<script>(&gui::script_func));
|
||||
LOG_INFO("Scripts registered.");
|
||||
LOG(INFO) << "Scripts registered.";
|
||||
|
||||
g_hooking->enable();
|
||||
LOG_INFO("Hooking enabled.");
|
||||
LOG(INFO) << "Hooking enabled.";
|
||||
|
||||
while (g_running)
|
||||
{
|
||||
if (GetAsyncKeyState(VK_END) & 0x8000)
|
||||
g_running = false;
|
||||
|
||||
g_hooking->ensure_dynamic_hooks();
|
||||
std::this_thread::sleep_for(10ms);
|
||||
std::this_thread::sleep_for(500ms);
|
||||
}
|
||||
|
||||
g_hooking->disable();
|
||||
LOG_INFO("Hooking disabled.");
|
||||
LOG(INFO) << "Hooking disabled.";
|
||||
|
||||
std::this_thread::sleep_for(1000ms);
|
||||
|
||||
g_script_mgr.remove_all_scripts();
|
||||
LOG_INFO("Scripts unregistered.");
|
||||
LOG(INFO) << "Scripts unregistered.";
|
||||
|
||||
hooking_instance.reset();
|
||||
LOG_INFO("Hooking uninitialized.");
|
||||
LOG(INFO) << "Hooking uninitialized.";
|
||||
|
||||
fiber_pool_instance.reset();
|
||||
LOG_INFO("Fiber pool uninitialized.");
|
||||
LOG(INFO) << "Fiber pool uninitialized.";
|
||||
|
||||
renderer_instance.reset();
|
||||
LOG_INFO("Renderer uninitialized.");
|
||||
LOG(INFO) << "Renderer uninitialized.";
|
||||
|
||||
pointers_instance.reset();
|
||||
LOG_INFO("Pointers uninitialized.");
|
||||
LOG(INFO) << "Pointers uninitialized.";
|
||||
}
|
||||
catch (std::exception const &ex)
|
||||
{
|
||||
LOG_ERROR("{}", ex.what());
|
||||
LOG(WARNING) << ex.what();
|
||||
MessageBoxA(nullptr, ex.what(), nullptr, MB_OK | MB_ICONEXCLAMATION);
|
||||
}
|
||||
|
||||
LOG_INFO("Farewell!");
|
||||
LOG(INFO) << "Farewell!";
|
||||
logger_instance.reset();
|
||||
|
||||
CloseHandle(g_main_thread);
|
||||
|
@ -13,21 +13,26 @@ namespace memory
|
||||
void pattern_batch::run(range region)
|
||||
{
|
||||
bool all_found = true;
|
||||
for (auto &entry : m_entries)
|
||||
for (auto& entry : m_entries)
|
||||
{
|
||||
if (auto result = region.scan(entry.m_pattern))
|
||||
{
|
||||
if (entry.m_callback)
|
||||
{
|
||||
std::invoke(std::move(entry.m_callback), result);
|
||||
LOG_INFO("Found '{}'.", entry.m_name);
|
||||
LOG(big::INFO_TO_FILE) << "Found '" << entry.m_name << "' GTA5.exe+" << HEX_TO_UPPER(result.as<DWORD64>() - region.begin().as<DWORD64>());
|
||||
}
|
||||
else
|
||||
{
|
||||
all_found = false;
|
||||
LOG_ERROR("Failed to find '{}'.", entry.m_name);
|
||||
LOG(WARNING) << "Failed to find '" << entry.m_name << "'.";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
all_found = false;
|
||||
LOG(WARNING) << "Failed to find '" << entry.m_name << "'.";
|
||||
}
|
||||
}
|
||||
|
||||
m_entries.clear();
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -66,6 +66,11 @@ namespace big
|
||||
m_swapchain = ptr.add(3).rip().as<IDXGISwapChain**>();
|
||||
});
|
||||
|
||||
main_batch.add("Model Spawn Bypass", "48 8B C8 FF 52 30 84 C0 74 05 48", [this](memory::handle ptr)
|
||||
{
|
||||
m_model_spawn_bypass = ptr.add(8).as<PVOID>();
|
||||
});
|
||||
|
||||
main_batch.run(memory::module(nullptr));
|
||||
|
||||
m_hwnd = FindWindowW(L"grcWindow", nullptr);
|
||||
|
@ -32,6 +32,8 @@ namespace big
|
||||
CGameScriptHandlerMgr **m_script_handler_mgr{};
|
||||
|
||||
IDXGISwapChain **m_swapchain{};
|
||||
|
||||
PVOID m_model_spawn_bypass;
|
||||
};
|
||||
|
||||
inline pointers *g_pointers{};
|
||||
|
@ -1,100 +1,132 @@
|
||||
#include "common.hpp"
|
||||
#include "fonts.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "gui.hpp"
|
||||
#include "pointers.hpp"
|
||||
#include "renderer.hpp"
|
||||
#include <imgui.h>
|
||||
#include <imgui_impl_dx11.h>
|
||||
#include <imgui_impl_win32.h>
|
||||
|
||||
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
namespace big
|
||||
{
|
||||
renderer::renderer() :
|
||||
m_dxgi_swapchain(*g_pointers->m_swapchain)
|
||||
{
|
||||
void *d3d_device{};
|
||||
if (SUCCEEDED(m_dxgi_swapchain->GetDevice(__uuidof(ID3D11Device), &d3d_device)))
|
||||
{
|
||||
m_d3d_device.Attach(static_cast<ID3D11Device*>(d3d_device));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("Failed to get D3D device.");
|
||||
}
|
||||
|
||||
m_d3d_device->GetImmediateContext(m_d3d_device_context.GetAddressOf());
|
||||
|
||||
ImGui::CreateContext();
|
||||
ImGui_ImplDX11_Init(m_d3d_device.Get(), m_d3d_device_context.Get());
|
||||
ImGui_ImplWin32_Init(g_pointers->m_hwnd);
|
||||
|
||||
ImFontConfig font_cfg{};
|
||||
font_cfg.FontDataOwnedByAtlas = false;
|
||||
std::strcpy(font_cfg.Name, "Rubik");
|
||||
|
||||
m_font = ImGui::GetIO().Fonts->AddFontFromMemoryTTF(const_cast<std::uint8_t*>(font_rubik), sizeof(font_rubik), 20.f, &font_cfg);
|
||||
m_monospace_font = ImGui::GetIO().Fonts->AddFontDefault();
|
||||
|
||||
g_gui.dx_init();
|
||||
g_renderer = this;
|
||||
}
|
||||
|
||||
renderer::~renderer()
|
||||
{
|
||||
ImGui_ImplWin32_Shutdown();
|
||||
ImGui_ImplDX11_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
g_renderer = nullptr;
|
||||
}
|
||||
|
||||
void renderer::on_present()
|
||||
{
|
||||
if (g_gui.m_opened)
|
||||
{
|
||||
ImGui::GetIO().MouseDrawCursor = true;
|
||||
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NoMouse;
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::GetIO().MouseDrawCursor = false;
|
||||
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NoMouse;
|
||||
}
|
||||
|
||||
ImGui_ImplDX11_NewFrame();
|
||||
ImGui_ImplWin32_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
if (g_gui.m_opened)
|
||||
{
|
||||
g_gui.dx_on_tick();
|
||||
}
|
||||
|
||||
ImGui::Render();
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
void renderer::pre_reset()
|
||||
{
|
||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
}
|
||||
|
||||
void renderer::post_reset()
|
||||
{
|
||||
ImGui_ImplDX11_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
void renderer::wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
if (msg == WM_KEYUP && wparam == VK_INSERT)
|
||||
g_gui.m_opened ^= true;
|
||||
|
||||
if (g_gui.m_opened)
|
||||
{
|
||||
ImGui_ImplWin32_WndProcHandler(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
}
|
||||
}
|
||||
#include "common.hpp"
|
||||
#include "fonts.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "gui.hpp"
|
||||
#include "pointers.hpp"
|
||||
#include "renderer.hpp"
|
||||
#include <imgui.h>
|
||||
#include <imgui_impl_dx11.h>
|
||||
#include <imgui_impl_win32.h>
|
||||
#include <imgui_internal.h>
|
||||
|
||||
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
namespace big
|
||||
{
|
||||
renderer::renderer() :
|
||||
m_dxgi_swapchain(*g_pointers->m_swapchain)
|
||||
{
|
||||
void *d3d_device{};
|
||||
if (SUCCEEDED(m_dxgi_swapchain->GetDevice(__uuidof(ID3D11Device), &d3d_device)))
|
||||
{
|
||||
m_d3d_device.Attach(static_cast<ID3D11Device*>(d3d_device));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("Failed to get D3D device.");
|
||||
}
|
||||
|
||||
m_d3d_device->GetImmediateContext(m_d3d_device_context.GetAddressOf());
|
||||
|
||||
auto file_path = std::filesystem::path(std::getenv("appdata"));
|
||||
file_path /= "BigBaseV2";
|
||||
if (!std::filesystem::exists(file_path))
|
||||
{
|
||||
std::filesystem::create_directory(file_path);
|
||||
}
|
||||
else if (!std::filesystem::is_directory(file_path))
|
||||
{
|
||||
std::filesystem::remove(file_path);
|
||||
std::filesystem::create_directory(file_path);
|
||||
}
|
||||
file_path /= "imgui.ini";
|
||||
|
||||
ImGuiContext* ctx = ImGui::CreateContext();
|
||||
|
||||
static std::string path = file_path.make_preferred().string();
|
||||
ctx->IO.IniFilename = path.c_str();
|
||||
|
||||
ImGui_ImplDX11_Init(m_d3d_device.Get(), m_d3d_device_context.Get());
|
||||
ImGui_ImplWin32_Init(g_pointers->m_hwnd);
|
||||
|
||||
ImFontConfig font_cfg{};
|
||||
font_cfg.FontDataOwnedByAtlas = false;
|
||||
std::strcpy(font_cfg.Name, "Rubik");
|
||||
|
||||
m_font = ImGui::GetIO().Fonts->AddFontFromMemoryTTF(const_cast<std::uint8_t*>(font_rubik), sizeof(font_rubik), 20.f, &font_cfg);
|
||||
m_monospace_font = ImGui::GetIO().Fonts->AddFontDefault();
|
||||
|
||||
g_gui.dx_init();
|
||||
g_renderer = this;
|
||||
}
|
||||
|
||||
renderer::~renderer()
|
||||
{
|
||||
ImGui_ImplWin32_Shutdown();
|
||||
ImGui_ImplDX11_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
g_renderer = nullptr;
|
||||
}
|
||||
|
||||
void renderer::on_present()
|
||||
{
|
||||
if (g_gui.m_opened)
|
||||
{
|
||||
ImGui::GetIO().MouseDrawCursor = true;
|
||||
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NoMouse;
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::GetIO().MouseDrawCursor = false;
|
||||
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NoMouse;
|
||||
}
|
||||
|
||||
ImGui_ImplDX11_NewFrame();
|
||||
ImGui_ImplWin32_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
if (g_gui.m_opened)
|
||||
{
|
||||
g_gui.dx_on_tick();
|
||||
}
|
||||
|
||||
ImGui::Render();
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
void renderer::pre_reset()
|
||||
{
|
||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
}
|
||||
|
||||
void renderer::post_reset()
|
||||
{
|
||||
ImGui_ImplDX11_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
void renderer::wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
if (msg == WM_KEYUP && wparam == VK_INSERT)
|
||||
{
|
||||
//Persist and restore the cursor position between menu instances.
|
||||
static POINT cursor_coords{};
|
||||
if (g_gui.m_opened)
|
||||
{
|
||||
GetCursorPos(&cursor_coords);
|
||||
}
|
||||
else if (cursor_coords.x + cursor_coords.y != 0)
|
||||
{
|
||||
SetCursorPos(cursor_coords.x, cursor_coords.y);
|
||||
}
|
||||
|
||||
g_gui.m_opened ^= true;
|
||||
}
|
||||
|
||||
|
||||
if (g_gui.m_opened)
|
||||
{
|
||||
ImGui_ImplWin32_WndProcHandler(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,10 +5,17 @@
|
||||
|
||||
namespace big
|
||||
{
|
||||
static void script_exception_handler(PEXCEPTION_POINTERS exp)
|
||||
void script::script_exception_handler(PEXCEPTION_POINTERS exp)
|
||||
{
|
||||
LOG_ERROR("Script threw an exception!");
|
||||
g_stackwalker.ShowCallstack(GetCurrentThread(), exp->ContextRecord);
|
||||
HMODULE mod{};
|
||||
DWORD64 offset{};
|
||||
char buffer[MAX_PATH]{};
|
||||
if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)exp->ExceptionRecord->ExceptionAddress, &mod) == TRUE && mod != nullptr)
|
||||
{
|
||||
offset = ((DWORD64)exp->ExceptionRecord->ExceptionAddress - (DWORD64)mod);
|
||||
GetModuleFileNameA(mod, buffer, MAX_PATH - 1);
|
||||
}
|
||||
LOG(FATAL) << "Exception Code: " << HEX_TO_UPPER(exp->ExceptionRecord->ExceptionCode) << " Exception Offset: " << HEX_TO_UPPER(offset) << " Fault Module Name: " << buffer;
|
||||
}
|
||||
|
||||
script::script(func_t func, std::optional<std::size_t> stack_size) :
|
||||
@ -52,38 +59,23 @@ namespace big
|
||||
SwitchToFiber(m_main_fiber);
|
||||
}
|
||||
|
||||
script *script::get_current()
|
||||
script* script::get_current()
|
||||
{
|
||||
return static_cast<script*>(GetFiberData());
|
||||
}
|
||||
|
||||
void script::fiber_func()
|
||||
{
|
||||
__try
|
||||
TRY_CLAUSE
|
||||
{
|
||||
[this]()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_func();
|
||||
}
|
||||
catch (std::exception const &ex)
|
||||
{
|
||||
auto ex_class = typeid(ex).name() + 6;
|
||||
LOG_INFO("Script threw an C++ expection! {}: {}", ex_class, ex.what());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_INFO("Script threw a C++ exception!");
|
||||
}
|
||||
}();
|
||||
}
|
||||
__except (script_exception_handler(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
LOG_INFO("Script threw an exception!");
|
||||
m_func();
|
||||
}
|
||||
EXCEPT_CLAUSE
|
||||
|
||||
[]() {
|
||||
LOG(INFO) << "Script finished!";
|
||||
}();
|
||||
|
||||
LOG_INFO("Script finished!");
|
||||
while (true)
|
||||
{
|
||||
yield();
|
||||
|
@ -13,13 +13,20 @@ namespace big
|
||||
|
||||
void tick();
|
||||
void yield(std::optional<std::chrono::high_resolution_clock::duration> time = std::nullopt);
|
||||
static script *get_current();
|
||||
static script* get_current();
|
||||
static void script_exception_handler(PEXCEPTION_POINTERS exp);
|
||||
private:
|
||||
void fiber_func();
|
||||
private:
|
||||
void *m_script_fiber;
|
||||
void *m_main_fiber;
|
||||
void* m_script_fiber;
|
||||
void* m_main_fiber;
|
||||
func_t m_func;
|
||||
std::optional<std::chrono::high_resolution_clock::time_point> m_wake_time;
|
||||
};
|
||||
|
||||
|
||||
#define TRY_CLAUSE __try
|
||||
#define EXCEPT_CLAUSE __except (script::script_exception_handler(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER) { }
|
||||
#define QUEUE_JOB_BEGIN_CLAUSE(...) g_fiber_pool->queue_job([__VA_ARGS__] { __try
|
||||
#define QUEUE_JOB_END_CLAUSE __except (script::script_exception_handler(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER) {} });
|
||||
}
|
||||
|
@ -9,9 +9,9 @@ namespace big
|
||||
{
|
||||
inline std::unordered_map<rage::scrProgram*, script_hook*> script_hook::s_map;
|
||||
|
||||
static bool map_native(rage::scrNativeHash *hash)
|
||||
static bool map_native(rage::scrNativeHash* hash)
|
||||
{
|
||||
for (auto const &mapping : g_crossmap)
|
||||
for (auto const& mapping : g_crossmap)
|
||||
{
|
||||
if (mapping.first == *hash)
|
||||
{
|
||||
@ -34,7 +34,7 @@ namespace big
|
||||
{
|
||||
if (m_program)
|
||||
{
|
||||
for (auto[hash, handler_ptr] : m_native_handler_ptrs)
|
||||
for (auto [hash, handler_ptr] : m_native_handler_ptrs)
|
||||
{
|
||||
auto og_handler = g_pointers->m_get_native_handler(g_pointers->m_native_registration_table, hash);
|
||||
*handler_ptr = og_handler;
|
||||
@ -58,12 +58,12 @@ namespace big
|
||||
if (program->is_valid())
|
||||
{
|
||||
hook_instance(program);
|
||||
LOG_INFO("Hooked {} script ({})", program->m_name, static_cast<void*>(program));
|
||||
LOG(INFO) << "Hooked " << program->m_name << " script (" << HEX_TO_UPPER(static_cast<void*>(program)) << ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void script_hook::hook_instance(rage::scrProgram *program)
|
||||
void script_hook::hook_instance(rage::scrProgram* program)
|
||||
{
|
||||
m_program = program;
|
||||
s_map.emplace(m_program, this);
|
||||
@ -88,7 +88,7 @@ namespace big
|
||||
}
|
||||
}
|
||||
|
||||
void script_hook::scrprogram_dtor(rage::scrProgram *this_, bool free_memory)
|
||||
void script_hook::scrprogram_dtor(rage::scrProgram* this_, bool free_memory)
|
||||
{
|
||||
if (auto it = s_map.find(this_); it != s_map.end())
|
||||
{
|
||||
|
86
BigBaseV2/src/settings.h
Normal file
86
BigBaseV2/src/settings.h
Normal file
@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
#include "common.hpp"
|
||||
#include "gta/player.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
class settings
|
||||
{
|
||||
public:
|
||||
explicit settings() = default;
|
||||
~settings() = default;
|
||||
|
||||
nlohmann::json options;
|
||||
nlohmann::json default_options =
|
||||
R"({
|
||||
"demo bool": false,
|
||||
"demo int": 1,
|
||||
"demo double": 1.0,
|
||||
"demo combo": 0
|
||||
})"_json;
|
||||
|
||||
bool save()
|
||||
{
|
||||
std::string settings_file = std::getenv("appdata");
|
||||
settings_file += "\\BigBaseV2\\settings.json";
|
||||
|
||||
std::ofstream file(settings_file, std::ios::out | std::ios::trunc);
|
||||
file << options.dump(4);
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool load()
|
||||
{
|
||||
std::string settings_file = std::getenv("appdata");
|
||||
settings_file += "\\BigBaseV2\\settings.json";
|
||||
|
||||
std::ifstream file(settings_file);
|
||||
|
||||
if (!file.is_open())
|
||||
{
|
||||
write_default_config();
|
||||
file.open(settings_file);
|
||||
}
|
||||
|
||||
file >> options;
|
||||
|
||||
bool should_save = false;
|
||||
for (auto& e : default_options.items())
|
||||
{
|
||||
if (options.count(e.key()) == 0)
|
||||
{
|
||||
should_save = true;
|
||||
options[e.key()] = e.value();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (should_save)
|
||||
{
|
||||
LOG(INFO) << "Updating settings.";
|
||||
save();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool write_default_config()
|
||||
{
|
||||
std::string settings_file = std::getenv("appdata");
|
||||
settings_file += "\\BigBaseV2\\settings.json";
|
||||
|
||||
std::ofstream file(settings_file, std::ios::out);
|
||||
file << default_options.dump(4);
|
||||
file.close();
|
||||
|
||||
options.clear();
|
||||
options = default_options;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
inline settings g_settings;
|
||||
}
|
5
GenerateProjects.bat
Normal file
5
GenerateProjects.bat
Normal file
@ -0,0 +1,5 @@
|
||||
@echo off
|
||||
premake5 vs2019
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
PAUSE
|
||||
)
|
11
README.md
11
README.md
@ -20,6 +20,15 @@ To set up the build environment, run the following commands in a terminal:
|
||||
```dos
|
||||
git clone https://github.com/Pocakking/BigBaseV2.git --recurse-submodules
|
||||
cd BigBaseV2
|
||||
premake5 vs2019
|
||||
GenerateProjects.bat
|
||||
```
|
||||
Now, you will be able to open the solution, and simply build it in Visual Studio.
|
||||
|
||||
It is reccomended you generate the project each time you add a file instead of adding it directly to Visual Studio.
|
||||
|
||||
## Credits
|
||||
Pocakking - Original creator.
|
||||
|
||||
gir489 - Implementer and wrote the g3log crash handler and added test cases.
|
||||
|
||||
datlimabean04 - Wrote the g3log and settings implementation.
|
71
premake5.lua
71
premake5.lua
@ -17,7 +17,7 @@ workspace "BigBaseV2"
|
||||
IncludeDir["MinHook"] = "vendor/MinHook/include"
|
||||
IncludeDir["ImGui"] = "vendor/ImGui"
|
||||
IncludeDir["ImGuiImpl"] = "vendor/ImGui/examples"
|
||||
IncludeDir["StackWalker"] = "vendor/StackWalker/Main/StackWalker/"
|
||||
IncludeDir["g3log"] = "vendor/g3log/src"
|
||||
|
||||
CppVersion = "C++17"
|
||||
MsvcToolset = "v142"
|
||||
@ -26,6 +26,8 @@ workspace "BigBaseV2"
|
||||
function DeclareMSVCOptions()
|
||||
filter "system:windows"
|
||||
staticruntime "Off"
|
||||
floatingpoint "Fast"
|
||||
vectorextensions "AVX2"
|
||||
systemversion (WindowsSdkVersion)
|
||||
toolset (MsvcToolset)
|
||||
cppdialect (CppVersion)
|
||||
@ -45,6 +47,11 @@ workspace "BigBaseV2"
|
||||
"4307" -- C4307: integral constant overflow
|
||||
}
|
||||
end
|
||||
|
||||
function file_exists(name)
|
||||
local f=io.open(name,"r")
|
||||
if f~=nil then io.close(f) return true else return false end
|
||||
end
|
||||
|
||||
function DeclareDebugOptions()
|
||||
filter "configurations:Debug"
|
||||
@ -102,27 +109,6 @@ workspace "BigBaseV2"
|
||||
DeclareMSVCOptions()
|
||||
DeclareDebugOptions()
|
||||
|
||||
project "StackWalker"
|
||||
location "vendor/%{prj.name}"
|
||||
kind "StaticLib"
|
||||
language "C++"
|
||||
|
||||
targetdir ("bin/lib/" .. outputdir)
|
||||
objdir ("bin/lib/int/" .. outputdir .. "/%{prj.name}")
|
||||
|
||||
files
|
||||
{
|
||||
"vendor/%{prj.name}/Main/StackWalker/StackWalker.cpp"
|
||||
}
|
||||
|
||||
includedirs
|
||||
{
|
||||
"vendor/%{prj.name}/include"
|
||||
}
|
||||
|
||||
DeclareMSVCOptions()
|
||||
DeclareDebugOptions()
|
||||
|
||||
project "MinHook"
|
||||
location "vendor/%{prj.name}"
|
||||
kind "StaticLib"
|
||||
@ -140,6 +126,38 @@ workspace "BigBaseV2"
|
||||
|
||||
DeclareMSVCOptions()
|
||||
DeclareDebugOptions()
|
||||
|
||||
project "g3log"
|
||||
location "vendor/%{prj.name}"
|
||||
kind "StaticLib"
|
||||
language "C++"
|
||||
|
||||
targetdir ("bin/lib/" .. outputdir)
|
||||
objdir ("bin/lib/int/" .. outputdir .. "/%{prj.name}")
|
||||
|
||||
includedirs
|
||||
{
|
||||
"vendor/%{prj.name}/src"
|
||||
}
|
||||
|
||||
if(file_exists("vendor\\g3log\\src\\g3log\\generated_definitions.hpp") == false) then
|
||||
file = io.open("vendor\\g3log\\src\\g3log\\generated_definitions.hpp", "w")
|
||||
file:write("// AUTO GENERATED MACRO DEFINITIONS FOR G3LOG\n\n\n/* ==========================================================================\n*2015 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes\n* with no warranties. This code is yours to share, use and modify with no\n\n*strings attached and no restrictions or obligations.\n* \n* For more information see g3log/LICENSE or refer refer to http://unlicense.org\n\n*============================================================================*/\n#pragma once\n\n\n// CMake induced definitions below. See g3log/Options.cmake for details.");
|
||||
end
|
||||
|
||||
files
|
||||
{
|
||||
"vendor/%{prj.name}/src/**.hpp",
|
||||
"vendor/%{prj.name}/src/**.cpp"
|
||||
}
|
||||
|
||||
removefiles
|
||||
{
|
||||
"vendor/%{prj.name}/src/crashhandler_unix.cpp"
|
||||
}
|
||||
|
||||
DeclareMSVCOptions()
|
||||
DeclareDebugOptions()
|
||||
|
||||
project "BigBaseV2"
|
||||
location "BigBaseV2"
|
||||
@ -155,6 +173,7 @@ workspace "BigBaseV2"
|
||||
files
|
||||
{
|
||||
"%{prj.name}/src/**.hpp",
|
||||
"%{prj.name}/src/**.h",
|
||||
"%{prj.name}/src/**.cpp",
|
||||
"%{prj.name}/src/**.asm"
|
||||
}
|
||||
@ -166,7 +185,7 @@ workspace "BigBaseV2"
|
||||
"%{IncludeDir.MinHook}",
|
||||
"%{IncludeDir.ImGui}",
|
||||
"%{IncludeDir.ImGuiImpl}",
|
||||
"%{IncludeDir.StackWalker}",
|
||||
"%{IncludeDir.g3log}",
|
||||
"%{prj.name}/src"
|
||||
}
|
||||
|
||||
@ -180,7 +199,7 @@ workspace "BigBaseV2"
|
||||
"fmtlib",
|
||||
"MinHook",
|
||||
"ImGui",
|
||||
"StackWalker"
|
||||
"g3log"
|
||||
}
|
||||
|
||||
pchheader "%{PrecompiledHeaderInclude}"
|
||||
@ -197,12 +216,14 @@ workspace "BigBaseV2"
|
||||
flags { "NoImportLib", "Maps" }
|
||||
|
||||
filter "configurations:Debug"
|
||||
flags { "LinkTimeOptimization", "MultiProcessorCompile" }
|
||||
defines { "BIGBASEV2_DEBUG" }
|
||||
|
||||
filter "configurations:Release"
|
||||
flags { "LinkTimeOptimization", "NoManifest", "MultiProcessorCompile" }
|
||||
defines { "BIGBASEV2_RELEASE" }
|
||||
optimize "speed"
|
||||
filter "configurations:Dist"
|
||||
flags { "LinkTimeOptimization", "FatalCompileWarnings" }
|
||||
flags { "LinkTimeOptimization", "FatalWarnings", "NoManifest", "MultiProcessorCompile" }
|
||||
defines { "BIGBASEV2_DIST" }
|
||||
optimize "speed"
|
||||
|
2
vendor/ImGui
vendored
2
vendor/ImGui
vendored
@ -1 +1 @@
|
||||
Subproject commit 6a0d0dab5a9f0b9518a2bc9bb456a69895ae0962
|
||||
Subproject commit 03453246464cdd414c2f76d4a2569d2d5511870b
|
2
vendor/MinHook
vendored
2
vendor/MinHook
vendored
@ -1 +1 @@
|
||||
Subproject commit 9fbd087432700d73fc571118d6a9697a36443d88
|
||||
Subproject commit 8fda4f5481fed5797dc2651cd91e238e9b3928c6
|
1
vendor/StackWalker
vendored
1
vendor/StackWalker
vendored
@ -1 +0,0 @@
|
||||
Subproject commit 42e7a6e056a9e7aca911a7e9e54e2e4f90bc2652
|
2
vendor/fmtlib
vendored
2
vendor/fmtlib
vendored
@ -1 +1 @@
|
||||
Subproject commit 9e554999ce02cf86fcdfe74fe740c4fe3f5a56d5
|
||||
Subproject commit e00997b004713a8de4ea480d7dfb3abb11d07852
|
1
vendor/g3log
vendored
Submodule
1
vendor/g3log
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 3ffc36a3a2d07e2c1e51acfe5e04856f87639488
|
2
vendor/json
vendored
2
vendor/json
vendored
@ -1 +1 @@
|
||||
Subproject commit 53c3eefa2cf790a7130fed3e13a3be35c2f2ace2
|
||||
Subproject commit 456478b3c50d60100dbb1fb9bc931f370a2c1c28
|
Reference in New Issue
Block a user