General code and GUI cleanup (#1200)
* feat(native_hooks): removed useless bail kick hook * feat(Translations): add button to force update languages * refactor: reorganize GUI for world * refactor: improve exception handler Modified the exception handler to not catch C++ try/catch blocks before those could gracefully catch the error. * chore: debug removed crash test button * chore: removed script exception handler * feat(OrbitalDrone): add translations * feat(VehicleController): add translation keys * feat: added player admin detected translation keys * feat(Views): add cache sub menu
This commit is contained in:
parent
60d8269d3b
commit
6df7be6f06
@ -1,22 +1,16 @@
|
|||||||
#include "hooking.hpp"
|
#include "hooking.hpp"
|
||||||
#include "renderer.hpp"
|
#include "renderer.hpp"
|
||||||
#include "script.hpp"
|
#include "script.hpp"
|
||||||
|
|
||||||
namespace big
|
namespace big
|
||||||
{
|
{
|
||||||
HRESULT hooks::swapchain_present(IDXGISwapChain* this_, UINT sync_interval, UINT flags)
|
HRESULT hooks::swapchain_present(IDXGISwapChain* this_, UINT sync_interval, UINT flags)
|
||||||
{
|
{
|
||||||
TRY_CLAUSE
|
if (g_running)
|
||||||
{
|
{
|
||||||
if (g_running)
|
g_renderer->on_present();
|
||||||
{
|
}
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +1,25 @@
|
|||||||
#include "hooking.hpp"
|
#include "hooking.hpp"
|
||||||
#include "renderer.hpp"
|
#include "renderer.hpp"
|
||||||
#include "script.hpp"
|
#include "script.hpp"
|
||||||
|
|
||||||
namespace big
|
namespace big
|
||||||
{
|
{
|
||||||
HRESULT hooks::swapchain_resizebuffers(IDXGISwapChain* this_, UINT buffer_count, UINT width, UINT height, DXGI_FORMAT new_format, UINT swapchain_flags)
|
HRESULT hooks::swapchain_resizebuffers(IDXGISwapChain* this_, UINT buffer_count, UINT width, UINT height, DXGI_FORMAT new_format, UINT swapchain_flags)
|
||||||
{
|
{
|
||||||
TRY_CLAUSE
|
if (g_running)
|
||||||
{
|
{
|
||||||
if (g_running)
|
g_renderer->pre_reset();
|
||||||
{
|
|
||||||
g_renderer->pre_reset();
|
const auto result = g_hooking->m_swapchain_hook.get_original<decltype(&swapchain_resizebuffers)>(swapchain_resizebuffers_index)(this_, buffer_count, width, height, new_format, swapchain_flags);
|
||||||
|
|
||||||
const 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 (SUCCEEDED(result))
|
g_renderer->post_reset();
|
||||||
{
|
}
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,22 +1,16 @@
|
|||||||
#include "hooking.hpp"
|
#include "hooking.hpp"
|
||||||
#include "renderer.hpp"
|
#include "renderer.hpp"
|
||||||
#include "script.hpp"
|
#include "script.hpp"
|
||||||
|
|
||||||
namespace big
|
namespace big
|
||||||
{
|
{
|
||||||
LRESULT hooks::wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
LRESULT hooks::wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||||
{
|
{
|
||||||
TRY_CLAUSE
|
if (g_running)
|
||||||
{
|
{
|
||||||
if (g_running)
|
g_renderer->wndproc(hwnd, msg, wparam, lparam);
|
||||||
{
|
}
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -51,8 +51,8 @@ namespace big
|
|||||||
auto found = std::find(admin_rids.begin(), admin_rids.end(), net_player_data->m_gamer_handle.m_rockstar_id);
|
auto found = std::find(admin_rids.begin(), admin_rids.end(), net_player_data->m_gamer_handle.m_rockstar_id);
|
||||||
if (found != admin_rids.end())
|
if (found != admin_rids.end())
|
||||||
{
|
{
|
||||||
g_notification_service->push_warning("Potential Admin Found!",
|
g_notification_service->push_warning("POTENTIAL_ADMIN_FOUND"_T.data(),
|
||||||
std::format("{} has been detected as admin", net_player_data->m_name));
|
std::vformat("PLAYER_DETECTED_AS_ADMIN"_T, std::make_format_args(net_player_data->m_name)));
|
||||||
LOG(WARNING) << net_player_data->m_name << " (" << net_player_data->m_gamer_handle.m_rockstar_id << ") has been detected as admin";
|
LOG(WARNING) << net_player_data->m_name << " (" << net_player_data->m_gamer_handle.m_rockstar_id << ") has been detected as admin";
|
||||||
auto id = player->m_player_id;
|
auto id = player->m_player_id;
|
||||||
if (auto plyr = g_player_service->get_by_id(id))
|
if (auto plyr = g_player_service->get_by_id(id))
|
||||||
|
@ -1,37 +1,39 @@
|
|||||||
#include "exception_handler.hpp"
|
#include "exception_handler.hpp"
|
||||||
|
|
||||||
#include "stack_trace.hpp"
|
#include "stack_trace.hpp"
|
||||||
|
|
||||||
#include <Zydis/Zydis.h>
|
#include <Zydis/Zydis.h>
|
||||||
|
|
||||||
namespace big
|
namespace big
|
||||||
{
|
{
|
||||||
exception_handler::exception_handler()
|
exception_handler::exception_handler()
|
||||||
{
|
{
|
||||||
m_exception_handler = AddVectoredExceptionHandler(1, &vectored_exception_handler);
|
SetErrorMode(0);
|
||||||
}
|
SetUnhandledExceptionFilter(&vectored_exception_handler);
|
||||||
|
}
|
||||||
exception_handler::~exception_handler()
|
|
||||||
{
|
exception_handler::~exception_handler()
|
||||||
RemoveVectoredExceptionHandler(m_exception_handler);
|
{
|
||||||
}
|
// passing NULL / 0 will make it go back to normal exception handling
|
||||||
|
SetUnhandledExceptionFilter(0);
|
||||||
inline static stack_trace trace;
|
}
|
||||||
LONG vectored_exception_handler(EXCEPTION_POINTERS* exception_info)
|
|
||||||
{
|
inline static stack_trace trace;
|
||||||
const auto exception_code = exception_info->ExceptionRecord->ExceptionCode;
|
LONG vectored_exception_handler(EXCEPTION_POINTERS* exception_info)
|
||||||
if (exception_code == EXCEPTION_BREAKPOINT || exception_code == DBG_PRINTEXCEPTION_C || exception_code == DBG_PRINTEXCEPTION_WIDE_C)
|
{
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
const auto exception_code = exception_info->ExceptionRecord->ExceptionCode;
|
||||||
|
if (exception_code == EXCEPTION_BREAKPOINT || exception_code == DBG_PRINTEXCEPTION_C || exception_code == DBG_PRINTEXCEPTION_WIDE_C)
|
||||||
trace.new_stack_trace(exception_info);
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
LOG(FATAL) << trace;
|
|
||||||
|
trace.new_stack_trace(exception_info);
|
||||||
ZyanU64 opcode_address = exception_info->ContextRecord->Rip;
|
LOG(FATAL) << trace;
|
||||||
ZydisDisassembledInstruction instruction;
|
|
||||||
ZydisDisassembleIntel(ZYDIS_MACHINE_MODE_LONG_64, opcode_address, reinterpret_cast<void*>(opcode_address), 32, &instruction);
|
ZyanU64 opcode_address = exception_info->ContextRecord->Rip;
|
||||||
|
ZydisDisassembledInstruction instruction;
|
||||||
exception_info->ContextRecord->Rip += instruction.info.length;
|
ZydisDisassembleIntel(ZYDIS_MACHINE_MODE_LONG_64, opcode_address, reinterpret_cast<void*>(opcode_address), 32, &instruction);
|
||||||
|
|
||||||
return EXCEPTION_CONTINUE_EXECUTION;
|
exception_info->ContextRecord->Rip += instruction.info.length;
|
||||||
}
|
|
||||||
|
return EXCEPTION_CONTINUE_EXECUTION;
|
||||||
|
}
|
||||||
}
|
}
|
@ -18,11 +18,6 @@ namespace big
|
|||||||
src->set_return_value(STATS::STAT_GET_INT(src->get_arg<Hash>(0), src->get_arg<int*>(1), src->get_arg<int>(2)));
|
src->set_return_value(STATS::STAT_GET_INT(src->get_arg<Hash>(0), src->get_arg<int*>(1), src->get_arg<int>(2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void NETWORK_BAIL(rage::scrNativeCallContext* src)
|
|
||||||
{
|
|
||||||
LOG(INFO) << "NETWORK_BAIL prevented";
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void IS_PLAYER_PLAYING(rage::scrNativeCallContext* src)
|
inline void IS_PLAYER_PLAYING(rage::scrNativeCallContext* src)
|
||||||
{
|
{
|
||||||
// block undead OTR
|
// block undead OTR
|
||||||
|
@ -121,7 +121,6 @@ namespace big
|
|||||||
add_native_detour(RAGE_JOAAT("carmod_shop"), 0x5F4B6931816E599B, carmod_shop::DISABLE_ALL_CONTROL_ACTIONS);
|
add_native_detour(RAGE_JOAAT("carmod_shop"), 0x5F4B6931816E599B, carmod_shop::DISABLE_ALL_CONTROL_ACTIONS);
|
||||||
|
|
||||||
add_native_detour(RAGE_JOAAT("freemode"), 0x767FBC2AC802EF3D, freemode::STAT_GET_INT);
|
add_native_detour(RAGE_JOAAT("freemode"), 0x767FBC2AC802EF3D, freemode::STAT_GET_INT);
|
||||||
add_native_detour(RAGE_JOAAT("freemode"), 0x95914459A87EBA28, freemode::NETWORK_BAIL);
|
|
||||||
add_native_detour(RAGE_JOAAT("freemode"), 0x5E9564D8246B909A, freemode::IS_PLAYER_PLAYING);
|
add_native_detour(RAGE_JOAAT("freemode"), 0x5E9564D8246B909A, freemode::IS_PLAYER_PLAYING);
|
||||||
add_native_detour(RAGE_JOAAT("freemode"), 0xEA1C610A04DB6BBB, freemode::SET_ENTITY_VISIBLE);
|
add_native_detour(RAGE_JOAAT("freemode"), 0xEA1C610A04DB6BBB, freemode::SET_ENTITY_VISIBLE);
|
||||||
add_native_detour(RAGE_JOAAT("freemode"), 0x231C8F89D0539D8F, freemode::SET_BIGMAP_ACTIVE);
|
add_native_detour(RAGE_JOAAT("freemode"), 0x231C8F89D0539D8F, freemode::SET_BIGMAP_ACTIVE);
|
||||||
|
218
src/script.cpp
218
src/script.cpp
@ -1,120 +1,100 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "script.hpp"
|
#include "script.hpp"
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
|
||||||
namespace big
|
namespace big
|
||||||
{
|
{
|
||||||
void script::script_exception_handler(PEXCEPTION_POINTERS exp)
|
script::script(const func_t func, const std::string_view name, const bool toggleable, const std::optional<std::size_t> stack_size) :
|
||||||
{
|
script(func, stack_size)
|
||||||
HMODULE mod{};
|
{
|
||||||
DWORD64 offset{};
|
m_name = name;
|
||||||
char buffer[MAX_PATH]{};
|
m_toggleable = toggleable;
|
||||||
if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)exp->ExceptionRecord->ExceptionAddress, &mod) == TRUE && mod != nullptr)
|
}
|
||||||
{
|
|
||||||
offset = ((DWORD64)exp->ExceptionRecord->ExceptionAddress - (DWORD64)mod);
|
script::script(const func_t func, const std::optional<std::size_t> stack_size) :
|
||||||
GetModuleFileNameA(mod, buffer, MAX_PATH - 1);
|
m_enabled(true),
|
||||||
}
|
m_toggleable(false),
|
||||||
LOG(FATAL) << "Exception Code: " << HEX_TO_UPPER(exp->ExceptionRecord->ExceptionCode) << " Exception Offset: " << HEX_TO_UPPER(offset) << " Fault Module Name: " << buffer;
|
m_script_fiber(nullptr),
|
||||||
}
|
m_main_fiber(nullptr),
|
||||||
|
m_func(func)
|
||||||
script::script(const func_t func, const std::string_view name, const bool toggleable, const std::optional<std::size_t> stack_size) :
|
{
|
||||||
script(func, stack_size)
|
m_script_fiber = CreateFiber(
|
||||||
{
|
stack_size.has_value() ? stack_size.value() : 0,
|
||||||
m_name = name;
|
[](void* param) {
|
||||||
m_toggleable = toggleable;
|
auto this_script = static_cast<script*>(param);
|
||||||
}
|
this_script->fiber_func();
|
||||||
|
},
|
||||||
script::script(const func_t func, const std::optional<std::size_t> stack_size) :
|
this);
|
||||||
m_enabled(true),
|
}
|
||||||
m_toggleable(false),
|
|
||||||
m_script_fiber(nullptr),
|
script::~script()
|
||||||
m_main_fiber(nullptr),
|
{
|
||||||
m_func(func)
|
if (m_script_fiber)
|
||||||
{
|
DeleteFiber(m_script_fiber);
|
||||||
m_script_fiber = CreateFiber(
|
}
|
||||||
stack_size.has_value() ? stack_size.value() : 0,
|
|
||||||
[](void* param) {
|
const char* script::name() const
|
||||||
auto this_script = static_cast<script*>(param);
|
{
|
||||||
this_script->fiber_func();
|
return m_name.data();
|
||||||
},
|
}
|
||||||
this);
|
|
||||||
}
|
bool script::is_enabled() const
|
||||||
|
{
|
||||||
script::~script()
|
return m_enabled;
|
||||||
{
|
}
|
||||||
if (m_script_fiber)
|
|
||||||
DeleteFiber(m_script_fiber);
|
void script::set_enabled(const bool toggle)
|
||||||
}
|
{
|
||||||
|
if (m_toggleable)
|
||||||
const char* script::name() const
|
m_enabled = toggle;
|
||||||
{
|
}
|
||||||
return m_name.data();
|
|
||||||
}
|
bool* script::toggle_ptr()
|
||||||
|
{
|
||||||
bool script::is_enabled() const
|
return &m_enabled;
|
||||||
{
|
}
|
||||||
return m_enabled;
|
|
||||||
}
|
bool script::is_toggleable() const
|
||||||
|
{
|
||||||
void script::set_enabled(const bool toggle)
|
return m_toggleable;
|
||||||
{
|
}
|
||||||
if (m_toggleable)
|
|
||||||
m_enabled = toggle;
|
void script::tick()
|
||||||
}
|
{
|
||||||
|
m_main_fiber = GetCurrentFiber();
|
||||||
bool* script::toggle_ptr()
|
if (!m_wake_time.has_value() || m_wake_time.value() <= std::chrono::high_resolution_clock::now())
|
||||||
{
|
{
|
||||||
return &m_enabled;
|
SwitchToFiber(m_script_fiber);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
bool script::is_toggleable() const
|
|
||||||
{
|
void script::yield(std::optional<std::chrono::high_resolution_clock::duration> time)
|
||||||
return m_toggleable;
|
{
|
||||||
}
|
if (time.has_value())
|
||||||
|
{
|
||||||
void script::tick()
|
m_wake_time = std::chrono::high_resolution_clock::now() + time.value();
|
||||||
{
|
}
|
||||||
m_main_fiber = GetCurrentFiber();
|
else
|
||||||
if (!m_wake_time.has_value() || m_wake_time.value() <= std::chrono::high_resolution_clock::now())
|
{
|
||||||
{
|
m_wake_time = std::nullopt;
|
||||||
SwitchToFiber(m_script_fiber);
|
}
|
||||||
}
|
|
||||||
}
|
SwitchToFiber(m_main_fiber);
|
||||||
|
}
|
||||||
void script::yield(std::optional<std::chrono::high_resolution_clock::duration> time)
|
|
||||||
{
|
script* script::get_current()
|
||||||
if (time.has_value())
|
{
|
||||||
{
|
return static_cast<script*>(GetFiberData());
|
||||||
m_wake_time = std::chrono::high_resolution_clock::now() + time.value();
|
}
|
||||||
}
|
|
||||||
else
|
void script::fiber_func()
|
||||||
{
|
{
|
||||||
m_wake_time = std::nullopt;
|
m_func();
|
||||||
}
|
|
||||||
|
while (true)
|
||||||
SwitchToFiber(m_main_fiber);
|
{
|
||||||
}
|
yield();
|
||||||
|
}
|
||||||
script* script::get_current()
|
}
|
||||||
{
|
|
||||||
return static_cast<script*>(GetFiberData());
|
|
||||||
}
|
|
||||||
|
|
||||||
void script::fiber_func()
|
|
||||||
{
|
|
||||||
TRY_CLAUSE
|
|
||||||
{
|
|
||||||
m_func();
|
|
||||||
}
|
|
||||||
EXCEPT_CLAUSE
|
|
||||||
[]() {
|
|
||||||
LOG(INFO) << "Script finished!";
|
|
||||||
}();
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,54 +1,40 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
|
||||||
namespace big
|
namespace big
|
||||||
{
|
{
|
||||||
class script
|
class script
|
||||||
{
|
{
|
||||||
std::string_view m_name;
|
std::string_view m_name;
|
||||||
bool m_enabled;
|
bool m_enabled;
|
||||||
bool m_toggleable;
|
bool m_toggleable;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using func_t = void (*)();
|
using func_t = void (*)();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit script(const func_t func, const std::string_view name, const bool toggleable = true, const std::optional<std::size_t> stack_size = std::nullopt);
|
explicit script(const func_t func, const std::string_view name, const bool toggleable = true, const std::optional<std::size_t> stack_size = std::nullopt);
|
||||||
explicit script(const func_t func, const std::optional<std::size_t> stack_size = std::nullopt);
|
explicit script(const func_t func, const std::optional<std::size_t> stack_size = std::nullopt);
|
||||||
~script();
|
~script();
|
||||||
|
|
||||||
[[nodiscard]] const char* name() const;
|
[[nodiscard]] const char* name() const;
|
||||||
[[nodiscard]] bool is_enabled() const;
|
[[nodiscard]] bool is_enabled() const;
|
||||||
void set_enabled(const bool toggle);
|
void set_enabled(const bool toggle);
|
||||||
[[nodiscard]] bool* toggle_ptr();
|
[[nodiscard]] bool* toggle_ptr();
|
||||||
|
|
||||||
[[nodiscard]] bool is_toggleable() const;
|
[[nodiscard]] bool is_toggleable() const;
|
||||||
|
|
||||||
void tick();
|
void tick();
|
||||||
void yield(std::optional<std::chrono::high_resolution_clock::duration> time = std::nullopt);
|
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:
|
||||||
private:
|
void fiber_func();
|
||||||
void fiber_func();
|
|
||||||
|
private:
|
||||||
private:
|
void* m_script_fiber;
|
||||||
void* m_script_fiber;
|
void* m_main_fiber;
|
||||||
void* m_main_fiber;
|
func_t m_func;
|
||||||
func_t m_func;
|
std::optional<std::chrono::high_resolution_clock::time_point> m_wake_time;
|
||||||
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) \
|
|
||||||
{ \
|
|
||||||
} \
|
|
||||||
});
|
|
||||||
}
|
}
|
@ -11,6 +11,8 @@ namespace big
|
|||||||
WEAPONS,
|
WEAPONS,
|
||||||
TELEPORT,
|
TELEPORT,
|
||||||
MOBILE,
|
MOBILE,
|
||||||
|
OUTFIT_EDITOR,
|
||||||
|
OUTFIT_SLOTS,
|
||||||
|
|
||||||
VEHICLE,
|
VEHICLE,
|
||||||
HANDLING,
|
HANDLING,
|
||||||
@ -26,10 +28,8 @@ namespace big
|
|||||||
|
|
||||||
WORLD,
|
WORLD,
|
||||||
SPAWN_PED,
|
SPAWN_PED,
|
||||||
TIME_AND_WEATHER,
|
|
||||||
CREATOR,
|
CREATOR,
|
||||||
TRAIN,
|
TRAIN,
|
||||||
WATER,
|
|
||||||
BLACKHOLE,
|
BLACKHOLE,
|
||||||
MODEL_SWAPPER,
|
MODEL_SWAPPER,
|
||||||
NEARBY,
|
NEARBY,
|
||||||
@ -41,13 +41,12 @@ namespace big
|
|||||||
SPOOFING,
|
SPOOFING,
|
||||||
PLAYER_DATABASE,
|
PLAYER_DATABASE,
|
||||||
SESSION_BROWSER,
|
SESSION_BROWSER,
|
||||||
|
STAT_EDITOR,
|
||||||
|
|
||||||
SETTINGS,
|
SETTINGS,
|
||||||
OUTFIT_EDITOR,
|
|
||||||
OUTFIT_SLOTS,
|
|
||||||
STAT_EDITOR,
|
|
||||||
CONTEXT_MENU_SETTINGS,
|
CONTEXT_MENU_SETTINGS,
|
||||||
ESP_SETTINGS,
|
ESP_SETTINGS,
|
||||||
|
GTA_CACHE_SETTINGS,
|
||||||
GUI_SETTINGS,
|
GUI_SETTINGS,
|
||||||
HOTKEY_SETTINGS,
|
HOTKEY_SETTINGS,
|
||||||
REACTION_SETTINGS,
|
REACTION_SETTINGS,
|
||||||
@ -80,6 +79,8 @@ namespace big
|
|||||||
{tabs::WEAPONS, {"GUI_TAB_WEAPONS", view::weapons}},
|
{tabs::WEAPONS, {"GUI_TAB_WEAPONS", view::weapons}},
|
||||||
{tabs::MOBILE, {"GUI_TAB_MOBILE", view::mobile}},
|
{tabs::MOBILE, {"GUI_TAB_MOBILE", view::mobile}},
|
||||||
{tabs::TELEPORT, {"GUI_TAB_TELEPORT", view::teleport}},
|
{tabs::TELEPORT, {"GUI_TAB_TELEPORT", view::teleport}},
|
||||||
|
{tabs::OUTFIT_EDITOR, {"GUI_TAB_OUTFIT_EDITOR", view::outfit_editor}},
|
||||||
|
{tabs::OUTFIT_SLOTS, {"GUI_TAB_OUTFIT_SLOTS", view::outfit_slots}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -112,17 +113,15 @@ namespace big
|
|||||||
tabs::WORLD,
|
tabs::WORLD,
|
||||||
{
|
{
|
||||||
"GUI_TAB_WORLD",
|
"GUI_TAB_WORLD",
|
||||||
nullptr,
|
view::world,
|
||||||
{
|
{
|
||||||
{tabs::SPAWN_PED, {"GUI_TAB_SPAWN_PED", view::spawn_ped}},
|
{tabs::SPAWN_PED, {"GUI_TAB_SPAWN_PED", view::spawn_ped}},
|
||||||
{tabs::TIME_AND_WEATHER, {"GUI_TAB_TIME_N_WEATHER", view::time_and_weather}},
|
|
||||||
{tabs::CREATOR, {"GUI_TAB_CREATOR", view::creator}},
|
{tabs::CREATOR, {"GUI_TAB_CREATOR", view::creator}},
|
||||||
{tabs::TRAIN, {"GUI_TAB_TRAIN", view::train}},
|
{tabs::TRAIN, {"GUI_TAB_TRAIN", view::train}},
|
||||||
{tabs::WATER, {"GUI_TAB_WATER", view::water}},
|
|
||||||
{tabs::BLACKHOLE, {"GUI_TAB_BLACKHOLE", view::blackhole}},
|
{tabs::BLACKHOLE, {"GUI_TAB_BLACKHOLE", view::blackhole}},
|
||||||
{tabs::MODEL_SWAPPER, {"GUI_TAB_MODEL_SWAPPER", view::model_swapper}},
|
{tabs::MODEL_SWAPPER, {"GUI_TAB_MODEL_SWAPPER", view::model_swapper}},
|
||||||
{tabs::NEARBY, {"GUI_TAB_NEARBY", view::nearby}},
|
{tabs::NEARBY, {"GUI_TAB_NEARBY", view::nearby}},
|
||||||
{tabs::ORBITAL_DRONE, {"Orbital Drone", view::orbital_drone}},
|
{tabs::ORBITAL_DRONE, {"GUI_TAB_ORBITAL_DRONE", view::orbital_drone}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -137,6 +136,7 @@ namespace big
|
|||||||
{tabs::MISSIONS, {"GUI_TAB_MISSIONS", view::missions}},
|
{tabs::MISSIONS, {"GUI_TAB_MISSIONS", view::missions}},
|
||||||
{tabs::PLAYER_DATABASE, {"GUI_TAB_PLAYER_DB", view::player_database}},
|
{tabs::PLAYER_DATABASE, {"GUI_TAB_PLAYER_DB", view::player_database}},
|
||||||
{tabs::SESSION_BROWSER, {"GUI_TAB_SESSION_BROWSER", view::session_browser}},
|
{tabs::SESSION_BROWSER, {"GUI_TAB_SESSION_BROWSER", view::session_browser}},
|
||||||
|
{tabs::STAT_EDITOR, {"GUI_TAB_STAT_EDITOR", view::stat_editor}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -146,11 +146,9 @@ namespace big
|
|||||||
"GUI_TAB_SETTINGS",
|
"GUI_TAB_SETTINGS",
|
||||||
view::settings,
|
view::settings,
|
||||||
{
|
{
|
||||||
{tabs::OUTFIT_EDITOR, {"GUI_TAB_OUTFIT_EDITOR", view::outfit_editor}},
|
|
||||||
{tabs::OUTFIT_SLOTS, {"GUI_TAB_OUTFIT_SLOTS", view::outfit_slots}},
|
|
||||||
{tabs::STAT_EDITOR, {"GUI_TAB_STAT_EDITOR", view::stat_editor}},
|
|
||||||
{tabs::CONTEXT_MENU_SETTINGS, {"GUI_TAB_CONTEXT_MENU", view::context_menu_settings}},
|
{tabs::CONTEXT_MENU_SETTINGS, {"GUI_TAB_CONTEXT_MENU", view::context_menu_settings}},
|
||||||
{tabs::ESP_SETTINGS, {"GUI_TAB_ESP", view::esp_settings}},
|
{tabs::ESP_SETTINGS, {"GUI_TAB_ESP", view::esp_settings}},
|
||||||
|
{tabs::GTA_CACHE_SETTINGS, {"GTA Cache", view::gta_cache}},
|
||||||
{tabs::GUI_SETTINGS, {"GUI_TAB_GUI", view::gui_settings}},
|
{tabs::GUI_SETTINGS, {"GUI_TAB_GUI", view::gui_settings}},
|
||||||
{tabs::HOTKEY_SETTINGS, {"GUI_TAB_HOTKEYS", view::hotkey_settings}},
|
{tabs::HOTKEY_SETTINGS, {"GUI_TAB_HOTKEYS", view::hotkey_settings}},
|
||||||
{tabs::REACTION_SETTINGS, {"GUI_TAB_REACTIONS", view::reaction_settings}},
|
{tabs::REACTION_SETTINGS, {"GUI_TAB_REACTIONS", view::reaction_settings}},
|
||||||
|
@ -1,213 +1,213 @@
|
|||||||
#include "translation_service.hpp"
|
#include "translation_service.hpp"
|
||||||
|
|
||||||
#include "file_manager.hpp"
|
#include "file_manager.hpp"
|
||||||
#include "thread_pool.hpp"
|
#include "thread_pool.hpp"
|
||||||
|
|
||||||
#include <cpr/cpr.h>
|
#include <cpr/cpr.h>
|
||||||
|
|
||||||
namespace big
|
namespace big
|
||||||
{
|
{
|
||||||
translation_service::translation_service() :
|
translation_service::translation_service() :
|
||||||
m_url("https://cdn.jsdelivr.net/gh/YimMenu/Translations@master")
|
m_url("https://cdn.jsdelivr.net/gh/YimMenu/Translations@master")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void translation_service::init()
|
void translation_service::init()
|
||||||
{
|
{
|
||||||
m_translation_directory = std::make_unique<folder>(g_file_manager->get_project_folder("./translations").get_path());
|
m_translation_directory = std::make_unique<folder>(g_file_manager->get_project_folder("./translations").get_path());
|
||||||
|
|
||||||
bool loaded_remote_index = false;
|
bool loaded_remote_index = false;
|
||||||
for (size_t i = 0; i < 5 && !loaded_remote_index; i++)
|
for (size_t i = 0; i < 5 && !loaded_remote_index; i++)
|
||||||
{
|
{
|
||||||
if (i)
|
if (i)
|
||||||
LOG(WARNING) << "Failed to download remote index, trying again... (" << i << ")";
|
LOG(WARNING) << "Failed to download remote index, trying again... (" << i << ")";
|
||||||
loaded_remote_index = download_index();
|
loaded_remote_index = download_index();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (load_local_index())
|
if (load_local_index())
|
||||||
{
|
{
|
||||||
if (!loaded_remote_index)
|
if (!loaded_remote_index)
|
||||||
{
|
{
|
||||||
LOG(WARNING) << "Failed to load remote index, attempting to use fallback.";
|
LOG(WARNING) << "Failed to load remote index, attempting to use fallback.";
|
||||||
use_fallback_remote();
|
use_fallback_remote();
|
||||||
}
|
}
|
||||||
else if (m_local_index.version < m_remote_index.version)
|
else if (m_local_index.version < m_remote_index.version)
|
||||||
{
|
{
|
||||||
LOG(INFO) << "Languages outdated, downloading new translations.";
|
LOG(INFO) << "Languages outdated, downloading new translations.";
|
||||||
|
|
||||||
update_language_packs();
|
update_language_packs();
|
||||||
m_local_index.version = m_remote_index.version;
|
m_local_index.version = m_remote_index.version;
|
||||||
}
|
}
|
||||||
load_translations();
|
load_translations();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loaded_remote_index)
|
if (!loaded_remote_index)
|
||||||
{
|
{
|
||||||
LOG(WARNING) << "Failed to load remote index, unable to load translations.";
|
LOG(WARNING) << "Failed to load remote index, unable to load translations.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(INFO) << "Downloading translations...";
|
LOG(INFO) << "Downloading translations...";
|
||||||
|
|
||||||
m_local_index.fallback_default_language = m_remote_index.default_lang;
|
m_local_index.fallback_default_language = m_remote_index.default_lang;
|
||||||
m_local_index.selected_language = m_remote_index.default_lang;
|
m_local_index.selected_language = m_remote_index.default_lang;
|
||||||
m_local_index.version = m_remote_index.version;
|
m_local_index.version = m_remote_index.version;
|
||||||
|
|
||||||
load_translations();
|
load_translations();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string_view translation_service::get_translation(const std::string_view translation_key) const
|
std::string_view translation_service::get_translation(const std::string_view translation_key) const
|
||||||
{
|
{
|
||||||
return get_translation(rage::joaat(translation_key));
|
return get_translation(rage::joaat(translation_key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string_view translation_service::get_translation(const rage::joaat_t translation_key) const
|
std::string_view translation_service::get_translation(const rage::joaat_t translation_key) const
|
||||||
{
|
{
|
||||||
if (auto it = m_translations.find(translation_key); it != m_translations.end())
|
if (auto it = m_translations.find(translation_key); it != m_translations.end())
|
||||||
return it->second.c_str();
|
return it->second.c_str();
|
||||||
|
|
||||||
return {0, 0};
|
return {0, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, translation_entry>& translation_service::available_translations()
|
std::map<std::string, translation_entry>& translation_service::available_translations()
|
||||||
{
|
{
|
||||||
return m_remote_index.translations;
|
return m_remote_index.translations;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& translation_service::current_language_pack()
|
const std::string& translation_service::current_language_pack()
|
||||||
{
|
{
|
||||||
return m_local_index.selected_language;
|
return m_local_index.selected_language;
|
||||||
}
|
}
|
||||||
|
|
||||||
void translation_service::select_language_pack(const std::string& pack_id)
|
void translation_service::select_language_pack(const std::string& pack_id)
|
||||||
{
|
{
|
||||||
g_thread_pool->push([this, &pack_id] {
|
g_thread_pool->push([this, &pack_id] {
|
||||||
m_local_index.selected_language = pack_id;
|
m_local_index.selected_language = pack_id;
|
||||||
load_translations();
|
load_translations();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void translation_service::load_translations()
|
void translation_service::update_language_packs()
|
||||||
{
|
{
|
||||||
m_translations.clear();
|
for (auto item : std::filesystem::directory_iterator(m_translation_directory->get_path()))
|
||||||
|
{
|
||||||
// load default lang first to make sure there are fallback keys if another language pack doesn't have a certain key
|
const auto path = item.path();
|
||||||
auto j = load_translation(m_remote_index.default_lang);
|
const auto stem = path.stem().string();
|
||||||
for (auto& [key, value] : j.items())
|
if (stem == "index" || item.path().extension() != ".json")
|
||||||
{
|
continue;
|
||||||
m_translations.insert({rage::joaat(key), value.get<std::string>()});
|
|
||||||
}
|
if (!download_language_pack(stem))
|
||||||
|
{
|
||||||
// Don't load selected language if it's the same as default
|
LOG(WARNING) << "Failed to update '" << stem << "' language pack";
|
||||||
if (m_local_index.selected_language != m_remote_index.default_lang)
|
}
|
||||||
{
|
}
|
||||||
auto j = load_translation(m_local_index.selected_language);
|
}
|
||||||
for (auto& [key, value] : j.items())
|
|
||||||
{
|
void translation_service::load_translations()
|
||||||
m_translations[rage::joaat(key)] = value;
|
{
|
||||||
}
|
m_translations.clear();
|
||||||
}
|
|
||||||
|
// load default lang first to make sure there are fallback keys if another language pack doesn't have a certain key
|
||||||
save_local_index();
|
auto j = load_translation(m_remote_index.default_lang);
|
||||||
}
|
for (auto& [key, value] : j.items())
|
||||||
|
{
|
||||||
nlohmann::json translation_service::load_translation(const std::string_view pack_id)
|
m_translations.insert({rage::joaat(key), value.get<std::string>()});
|
||||||
{
|
}
|
||||||
auto file = m_translation_directory->get_file(std::format("./{}.json", pack_id));
|
|
||||||
if (!file.exists())
|
// Don't load selected language if it's the same as default
|
||||||
{
|
if (m_local_index.selected_language != m_remote_index.default_lang)
|
||||||
LOG(INFO) << "Translations for '" << pack_id << "' does not exist, downloading from " << m_url;
|
{
|
||||||
if (!download_language_pack(pack_id))
|
auto j = load_translation(m_local_index.selected_language);
|
||||||
{
|
for (auto& [key, value] : j.items())
|
||||||
LOG(WARNING) << "Failed to download language pack, can't recover...";
|
{
|
||||||
return {};
|
m_translations[rage::joaat(key)] = value;
|
||||||
}
|
}
|
||||||
// make a copy available
|
}
|
||||||
m_local_index.fallback_languages[pack_id.data()] = m_remote_index.translations[pack_id.data()];
|
|
||||||
}
|
save_local_index();
|
||||||
return nlohmann::json::parse(std::ifstream(file.get_path(), std::ios::binary));
|
}
|
||||||
}
|
|
||||||
|
nlohmann::json translation_service::load_translation(const std::string_view pack_id)
|
||||||
bool translation_service::download_language_pack(const std::string_view pack_id)
|
{
|
||||||
{
|
auto file = m_translation_directory->get_file(std::format("./{}.json", pack_id));
|
||||||
if (auto it = m_remote_index.translations.find(pack_id.data()); it != m_remote_index.translations.end())
|
if (!file.exists())
|
||||||
{
|
{
|
||||||
cpr::Response response = cpr::Get(cpr::Url{m_url + "/" + it->second.file});
|
LOG(INFO) << "Translations for '" << pack_id << "' does not exist, downloading from " << m_url;
|
||||||
|
if (!download_language_pack(pack_id))
|
||||||
if (response.status_code == 200)
|
{
|
||||||
{
|
LOG(WARNING) << "Failed to download language pack, can't recover...";
|
||||||
auto json = nlohmann::json::parse(response.text);
|
return {};
|
||||||
auto lang_file = m_translation_directory->get_file("./" + it->second.file);
|
}
|
||||||
|
// make a copy available
|
||||||
auto out_file = std::ofstream(lang_file.get_path(), std::ios::binary | std::ios::trunc);
|
m_local_index.fallback_languages[pack_id.data()] = m_remote_index.translations[pack_id.data()];
|
||||||
out_file << json.dump(4);
|
}
|
||||||
out_file.close();
|
return nlohmann::json::parse(std::ifstream(file.get_path(), std::ios::binary));
|
||||||
|
}
|
||||||
return true;
|
|
||||||
}
|
bool translation_service::download_language_pack(const std::string_view pack_id)
|
||||||
}
|
{
|
||||||
return false;
|
if (auto it = m_remote_index.translations.find(pack_id.data()); it != m_remote_index.translations.end())
|
||||||
}
|
{
|
||||||
|
cpr::Response response = cpr::Get(cpr::Url{m_url + "/" + it->second.file});
|
||||||
void translation_service::update_language_packs()
|
|
||||||
{
|
if (response.status_code == 200)
|
||||||
for (auto item : std::filesystem::directory_iterator(m_translation_directory->get_path()))
|
{
|
||||||
{
|
auto json = nlohmann::json::parse(response.text);
|
||||||
const auto path = item.path();
|
auto lang_file = m_translation_directory->get_file("./" + it->second.file);
|
||||||
const auto stem = path.stem().string();
|
|
||||||
if (stem == "index" || item.path().extension() != ".json")
|
auto out_file = std::ofstream(lang_file.get_path(), std::ios::binary | std::ios::trunc);
|
||||||
continue;
|
out_file << json.dump(4);
|
||||||
|
out_file.close();
|
||||||
if (!download_language_pack(stem))
|
|
||||||
{
|
return true;
|
||||||
LOG(WARNING) << "Failed to update '" << stem << "' language pack";
|
}
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool translation_service::download_index()
|
bool translation_service::download_index()
|
||||||
{
|
{
|
||||||
cpr::Response response = cpr::Get(cpr::Url{m_url + "/index.json"});
|
cpr::Response response = cpr::Get(cpr::Url{m_url + "/index.json"});
|
||||||
|
|
||||||
if (response.status_code == 200)
|
if (response.status_code == 200)
|
||||||
{
|
{
|
||||||
m_remote_index = nlohmann::json::parse(response.text);
|
m_remote_index = nlohmann::json::parse(response.text);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool translation_service::load_local_index()
|
bool translation_service::load_local_index()
|
||||||
{
|
{
|
||||||
const auto local_index = m_translation_directory->get_file("./index.json");
|
const auto local_index = m_translation_directory->get_file("./index.json");
|
||||||
if (local_index.exists())
|
if (local_index.exists())
|
||||||
{
|
{
|
||||||
const auto path = local_index.get_path();
|
const auto path = local_index.get_path();
|
||||||
m_local_index = nlohmann::json::parse(std::ifstream(path, std::ios::binary));
|
m_local_index = nlohmann::json::parse(std::ifstream(path, std::ios::binary));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void translation_service::save_local_index()
|
void translation_service::save_local_index()
|
||||||
{
|
{
|
||||||
nlohmann::json j = m_local_index;
|
nlohmann::json j = m_local_index;
|
||||||
|
|
||||||
const auto local_index = m_translation_directory->get_file("./index.json");
|
const auto local_index = m_translation_directory->get_file("./index.json");
|
||||||
|
|
||||||
auto os = std::ofstream(local_index.get_path(), std::ios::binary | std::ios::trunc);
|
auto os = std::ofstream(local_index.get_path(), std::ios::binary | std::ios::trunc);
|
||||||
os << j.dump(4);
|
os << j.dump(4);
|
||||||
os.close();
|
os.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void translation_service::use_fallback_remote()
|
void translation_service::use_fallback_remote()
|
||||||
{
|
{
|
||||||
m_remote_index.default_lang = m_local_index.fallback_default_language;
|
m_remote_index.default_lang = m_local_index.fallback_default_language;
|
||||||
m_remote_index.translations = m_local_index.fallback_languages;
|
m_remote_index.translations = m_local_index.fallback_languages;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,87 +1,87 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "file_manager/folder.hpp"
|
#include "file_manager/folder.hpp"
|
||||||
#include "gta/joaat.hpp"
|
#include "gta/joaat.hpp"
|
||||||
#include "local_index.hpp"
|
#include "local_index.hpp"
|
||||||
#include "remote_index.hpp"
|
#include "remote_index.hpp"
|
||||||
|
|
||||||
namespace big
|
namespace big
|
||||||
{
|
{
|
||||||
using translation_map = std::unordered_map<rage::joaat_t, std::string>;
|
using translation_map = std::unordered_map<rage::joaat_t, std::string>;
|
||||||
|
|
||||||
class translation_service
|
class translation_service
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
translation_service();
|
translation_service();
|
||||||
virtual ~translation_service() = default;
|
virtual ~translation_service() = default;
|
||||||
translation_service(const translation_service&) = delete;
|
translation_service(const translation_service&) = delete;
|
||||||
translation_service(translation_service&&) noexcept = delete;
|
translation_service(translation_service&&) noexcept = delete;
|
||||||
translation_service& operator=(const translation_service&) = delete;
|
translation_service& operator=(const translation_service&) = delete;
|
||||||
translation_service& operator=(translation_service&&) noexcept = delete;
|
translation_service& operator=(translation_service&&) noexcept = delete;
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
std::string_view get_translation(const std::string_view translation_key) const;
|
std::string_view get_translation(const std::string_view translation_key) const;
|
||||||
std::string_view get_translation(const rage::joaat_t translation_key) const;
|
std::string_view get_translation(const rage::joaat_t translation_key) const;
|
||||||
|
|
||||||
std::map<std::string, translation_entry>& available_translations();
|
std::map<std::string, translation_entry>& available_translations();
|
||||||
const std::string& current_language_pack();
|
const std::string& current_language_pack();
|
||||||
void select_language_pack(const std::string& pack_id);
|
void select_language_pack(const std::string& pack_id);
|
||||||
|
void update_language_packs();
|
||||||
private:
|
|
||||||
void load_translations();
|
private:
|
||||||
nlohmann::json load_translation(const std::string_view pack_id);
|
void load_translations();
|
||||||
|
nlohmann::json load_translation(const std::string_view pack_id);
|
||||||
bool download_language_pack(const std::string_view pack_id);
|
|
||||||
void update_language_packs();
|
bool download_language_pack(const std::string_view pack_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Downloads the remote index to compare with our local index
|
* @brief Downloads the remote index to compare with our local index
|
||||||
*
|
*
|
||||||
* @return true
|
* @return true
|
||||||
* @return false
|
* @return false
|
||||||
*/
|
*/
|
||||||
bool download_index();
|
bool download_index();
|
||||||
bool load_local_index();
|
bool load_local_index();
|
||||||
void save_local_index();
|
void save_local_index();
|
||||||
/**
|
/**
|
||||||
* @brief Attempts to load the remote from the local index fallback
|
* @brief Attempts to load the remote from the local index fallback
|
||||||
*/
|
*/
|
||||||
void use_fallback_remote();
|
void use_fallback_remote();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::string m_url;
|
const std::string m_url;
|
||||||
std::unique_ptr<folder> m_translation_directory;
|
std::unique_ptr<folder> m_translation_directory;
|
||||||
local_index m_local_index;
|
local_index m_local_index;
|
||||||
remote_index m_remote_index;
|
remote_index m_remote_index;
|
||||||
|
|
||||||
translation_map m_translations;
|
translation_map m_translations;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto g_translation_service = translation_service();
|
inline auto g_translation_service = translation_service();
|
||||||
|
|
||||||
template<std::size_t N>
|
template<std::size_t N>
|
||||||
struct TranslationLiteral
|
struct TranslationLiteral
|
||||||
{
|
{
|
||||||
rage::joaat_t m_hash;
|
rage::joaat_t m_hash;
|
||||||
char m_key[N]{};
|
char m_key[N]{};
|
||||||
|
|
||||||
consteval TranslationLiteral(char const (&pp)[N])
|
consteval TranslationLiteral(char const (&pp)[N])
|
||||||
{
|
{
|
||||||
std::ranges::copy(pp, m_key);
|
std::ranges::copy(pp, m_key);
|
||||||
m_hash = rage::joaat(pp);
|
m_hash = rage::joaat(pp);
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::string_view translation() const
|
const std::string_view translation() const
|
||||||
{
|
{
|
||||||
if (const auto translation = g_translation_service.get_translation(m_hash); translation.length())
|
if (const auto translation = g_translation_service.get_translation(m_hash); translation.length())
|
||||||
return translation;
|
return translation;
|
||||||
return m_key;
|
return m_key;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<TranslationLiteral T>
|
template<TranslationLiteral T>
|
||||||
constexpr auto operator"" _T()
|
constexpr auto operator"" _T()
|
||||||
{
|
{
|
||||||
return T.translation();
|
return T.translation();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -187,7 +187,7 @@ namespace big
|
|||||||
4.f,
|
4.f,
|
||||||
5.f);
|
5.f);
|
||||||
//LOG(INFO) << "Navmesh probably failed, issiuing regular task ";
|
//LOG(INFO) << "Navmesh probably failed, issiuing regular task ";
|
||||||
g_notification_service->push_warning("Vehicle controller", "Your vehicle could not assess an accurate path, it will try something else");
|
g_notification_service->push_warning("VEHICLE_CONTROLLER"_T.data(), "VEHICLE_CONTROLLER_TRY_ALT_PATHFINDING"_T.data());
|
||||||
script::get_current()->yield(500ms);
|
script::get_current()->yield(500ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,12 +331,12 @@ namespace big
|
|||||||
if (vehicle_control::find_suitable_destination_near_player(destination, heading))
|
if (vehicle_control::find_suitable_destination_near_player(destination, heading))
|
||||||
{
|
{
|
||||||
//LOG(INFO) << "Suitable destination found";
|
//LOG(INFO) << "Suitable destination found";
|
||||||
g_notification_service->push_warning("Vehicle controller", "Found a nice spot, your vehicle is on its way");
|
g_notification_service->push_warning("VEHICLE_CONTROLLER"_T.data(), "VEHICLE_CONTROLLER_FOUND_LOCATION"_T.data());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//LOG(INFO) << "Couldn't find suitable destionation, defaulting to offset of player\nThis might go wrong";
|
//LOG(INFO) << "Couldn't find suitable destionation, defaulting to offset of player\nThis might go wrong";
|
||||||
g_notification_service->push_warning("Vehicle controller", "Couldn't locate an accurate spot, your vehicle is on its way regardless");
|
g_notification_service->push_warning("VEHICLE_CONTROLLER"_T.data(), "VEHICLE_CONTROLLER_FORCE_PATHFINDING"_T.data());
|
||||||
destination = behind_pos;
|
destination = behind_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,7 +359,7 @@ namespace big
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
//LOG(INFO) << "Navmesh load failed";
|
//LOG(INFO) << "Navmesh load failed";
|
||||||
g_notification_service->push_error("Nav mesh", "Failed loading the navmesh");
|
g_notification_service->push_error("VEHICLE_CONTROLLER"_T.data(), "VEHICLE_CONTROLLER_NAVMESH_FAILURE"_T.data());
|
||||||
m_driver_performing_task = false;
|
m_driver_performing_task = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,251 +1,251 @@
|
|||||||
#include "natives.hpp"
|
#include "natives.hpp"
|
||||||
#include "pointers.hpp"
|
#include "pointers.hpp"
|
||||||
#include "util/outfit.hpp"
|
#include "util/outfit.hpp"
|
||||||
#include "util/ped.hpp"
|
#include "util/ped.hpp"
|
||||||
#include "views/view.hpp"
|
#include "views/view.hpp"
|
||||||
|
|
||||||
namespace big
|
namespace big
|
||||||
{
|
{
|
||||||
void view::outfit_editor()
|
void view::outfit_editor()
|
||||||
{
|
{
|
||||||
static outfit::components_t components;
|
static outfit::components_t components;
|
||||||
static outfit::props_t props;
|
static outfit::props_t props;
|
||||||
|
|
||||||
g_fiber_pool->queue_job([] {
|
g_fiber_pool->queue_job([] {
|
||||||
for (auto& item : components.items)
|
for (auto& item : components.items)
|
||||||
{
|
{
|
||||||
item.drawable_id = PED::GET_PED_DRAWABLE_VARIATION(self::ped, item.id);
|
item.drawable_id = PED::GET_PED_DRAWABLE_VARIATION(self::ped, item.id);
|
||||||
item.drawable_id_max = PED::GET_NUMBER_OF_PED_DRAWABLE_VARIATIONS(self::ped, item.id) - 1;
|
item.drawable_id_max = PED::GET_NUMBER_OF_PED_DRAWABLE_VARIATIONS(self::ped, item.id) - 1;
|
||||||
|
|
||||||
item.texture_id = PED::GET_PED_TEXTURE_VARIATION(self::ped, item.id);
|
item.texture_id = PED::GET_PED_TEXTURE_VARIATION(self::ped, item.id);
|
||||||
item.texture_id_max = PED::GET_NUMBER_OF_PED_TEXTURE_VARIATIONS(self::ped, item.id, item.drawable_id) - 1;
|
item.texture_id_max = PED::GET_NUMBER_OF_PED_TEXTURE_VARIATIONS(self::ped, item.id, item.drawable_id) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& item : props.items)
|
for (auto& item : props.items)
|
||||||
{
|
{
|
||||||
item.drawable_id = PED::GET_PED_PROP_INDEX(self::ped, item.id, 1);
|
item.drawable_id = PED::GET_PED_PROP_INDEX(self::ped, item.id, 1);
|
||||||
item.drawable_id_max = PED::GET_NUMBER_OF_PED_PROP_DRAWABLE_VARIATIONS(self::ped, item.id) - 1;
|
item.drawable_id_max = PED::GET_NUMBER_OF_PED_PROP_DRAWABLE_VARIATIONS(self::ped, item.id) - 1;
|
||||||
|
|
||||||
item.texture_id = PED::GET_PED_PROP_TEXTURE_INDEX(self::ped, item.id);
|
item.texture_id = PED::GET_PED_PROP_TEXTURE_INDEX(self::ped, item.id);
|
||||||
item.texture_id_max = PED::GET_NUMBER_OF_PED_PROP_TEXTURE_VARIATIONS(self::ped, item.id, item.drawable_id) - 1;
|
item.texture_id_max = PED::GET_NUMBER_OF_PED_PROP_TEXTURE_VARIATIONS(self::ped, item.id, item.drawable_id) - 1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
components::button("OUTFIT_RANDOM_COMPONENT"_T, [] {
|
components::button("OUTFIT_RANDOM_COMPONENT"_T, [] {
|
||||||
ped::set_ped_random_component_variation(self::ped);
|
ped::set_ped_random_component_variation(self::ped);
|
||||||
});
|
});
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
components::button("OUTFIT_DEFAULT_COMPONENT"_T, [] {
|
components::button("OUTFIT_DEFAULT_COMPONENT"_T, [] {
|
||||||
PED::SET_PED_DEFAULT_COMPONENT_VARIATION(self::ped);
|
PED::SET_PED_DEFAULT_COMPONENT_VARIATION(self::ped);
|
||||||
});
|
});
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
components::button("OUTFIT_RANDOM_PROPS"_T, [] {
|
components::button("OUTFIT_RANDOM_PROPS"_T, [] {
|
||||||
PED::SET_PED_RANDOM_PROPS(self::ped);
|
PED::SET_PED_RANDOM_PROPS(self::ped);
|
||||||
});
|
});
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
components::button("OUTFIT_CLEAR_PROPS"_T, [] {
|
components::button("OUTFIT_CLEAR_PROPS"_T, [] {
|
||||||
PED::CLEAR_ALL_PED_PROPS(self::ped, 1);
|
PED::CLEAR_ALL_PED_PROPS(self::ped, 1);
|
||||||
});
|
});
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
components::button("EXPORT_TO_CLIPBOARD"_T, [] {
|
components::button("EXPORT_TO_CLIPBOARD"_T, [] {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
for (auto& item : components.items)
|
for (auto& item : components.items)
|
||||||
ss << item.id << " " << item.drawable_id << " " << item.texture_id << " ";
|
ss << item.id << " " << item.drawable_id << " " << item.texture_id << " ";
|
||||||
for (auto& item : props.items)
|
for (auto& item : props.items)
|
||||||
ss << item.id << " " << item.drawable_id << " " << item.texture_id << " ";
|
ss << item.id << " " << item.drawable_id << " " << item.texture_id << " ";
|
||||||
ImGui::SetClipboardText(ss.str().c_str());
|
ImGui::SetClipboardText(ss.str().c_str());
|
||||||
g_notification_service->push("OUTFIT"_T.data(), "EXPORT_TO_CLIPBOARD"_T.data());
|
g_notification_service->push("OUTFIT"_T.data(), "EXPORT_TO_CLIPBOARD"_T.data());
|
||||||
});
|
});
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
components::button("IMPORT_FROM_CLIPBOARD"_T, [] {
|
components::button("IMPORT_FROM_CLIPBOARD"_T, [] {
|
||||||
std::stringstream ss(ImGui::GetClipboardText());
|
std::stringstream ss(ImGui::GetClipboardText());
|
||||||
for (auto& item : components.items)
|
for (auto& item : components.items)
|
||||||
{
|
{
|
||||||
int id = 0;
|
int id = 0;
|
||||||
int drawable_id = 0;
|
int drawable_id = 0;
|
||||||
int texture_id = 0;
|
int texture_id = 0;
|
||||||
ss >> id;
|
ss >> id;
|
||||||
ss >> drawable_id;
|
ss >> drawable_id;
|
||||||
ss >> texture_id;
|
ss >> texture_id;
|
||||||
PED::SET_PED_COMPONENT_VARIATION(self::ped, id, drawable_id, texture_id, PED::GET_PED_PALETTE_VARIATION(self::ped, id));
|
PED::SET_PED_COMPONENT_VARIATION(self::ped, id, drawable_id, texture_id, PED::GET_PED_PALETTE_VARIATION(self::ped, id));
|
||||||
}
|
}
|
||||||
for (auto& item : props.items)
|
for (auto& item : props.items)
|
||||||
{
|
{
|
||||||
int id = 0;
|
int id = 0;
|
||||||
int drawable_id = 0;
|
int drawable_id = 0;
|
||||||
int texture_id = 0;
|
int texture_id = 0;
|
||||||
ss >> id;
|
ss >> id;
|
||||||
ss >> drawable_id;
|
ss >> drawable_id;
|
||||||
ss >> texture_id;
|
ss >> texture_id;
|
||||||
if (drawable_id == -1)
|
if (drawable_id == -1)
|
||||||
PED::CLEAR_PED_PROP(self::ped, id, 1);
|
PED::CLEAR_PED_PROP(self::ped, id, 1);
|
||||||
else
|
else
|
||||||
PED::SET_PED_PROP_INDEX(self::ped, id, drawable_id, texture_id, TRUE, 1);
|
PED::SET_PED_PROP_INDEX(self::ped, id, drawable_id, texture_id, TRUE, 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
for (auto& item : components.items)
|
for (auto& item : components.items)
|
||||||
{
|
{
|
||||||
ImGui::SetNextItemWidth(60);
|
ImGui::SetNextItemWidth(60);
|
||||||
if (ImGui::InputInt(std::format("{} [0,{}]", item.label, item.drawable_id_max).c_str(), &item.drawable_id, 0))
|
if (ImGui::InputInt(std::format("{} [0,{}]", item.label, item.drawable_id_max).c_str(), &item.drawable_id, 0))
|
||||||
{
|
{
|
||||||
g_fiber_pool->queue_job([item] {
|
g_fiber_pool->queue_job([item] {
|
||||||
PED::SET_PED_COMPONENT_VARIATION(self::ped, item.id, item.drawable_id, 0, PED::GET_PED_PALETTE_VARIATION(self::ped, item.id));
|
PED::SET_PED_COMPONENT_VARIATION(self::ped, item.id, item.drawable_id, 0, PED::GET_PED_PALETTE_VARIATION(self::ped, item.id));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
for (auto& item : components.items)
|
for (auto& item : components.items)
|
||||||
{
|
{
|
||||||
ImGui::SetNextItemWidth(60);
|
ImGui::SetNextItemWidth(60);
|
||||||
if (ImGui::InputInt(std::format("{} {} [0,{}]", item.label, "OUTFIT_TEX"_T, item.texture_id_max).c_str(), &item.texture_id, 0))
|
if (ImGui::InputInt(std::format("{} {} [0,{}]", item.label, "OUTFIT_TEX"_T, item.texture_id_max).c_str(), &item.texture_id, 0))
|
||||||
{
|
{
|
||||||
g_fiber_pool->queue_job([item] {
|
g_fiber_pool->queue_job([item] {
|
||||||
PED::SET_PED_COMPONENT_VARIATION(self::ped, item.id, item.drawable_id, item.texture_id, PED::GET_PED_PALETTE_VARIATION(self::ped, item.id));
|
PED::SET_PED_COMPONENT_VARIATION(self::ped, item.id, item.drawable_id, item.texture_id, PED::GET_PED_PALETTE_VARIATION(self::ped, item.id));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
for (auto& item : props.items)
|
for (auto& item : props.items)
|
||||||
{
|
{
|
||||||
ImGui::SetNextItemWidth(60);
|
ImGui::SetNextItemWidth(60);
|
||||||
if (ImGui::InputInt(std::format("{} [0,{}]", item.label, item.drawable_id_max).c_str(), &item.drawable_id, 0))
|
if (ImGui::InputInt(std::format("{} [0,{}]", item.label, item.drawable_id_max).c_str(), &item.drawable_id, 0))
|
||||||
{
|
{
|
||||||
g_fiber_pool->queue_job([item] {
|
g_fiber_pool->queue_job([item] {
|
||||||
if (item.drawable_id == -1)
|
if (item.drawable_id == -1)
|
||||||
PED::CLEAR_PED_PROP(self::ped, item.id, 1);
|
PED::CLEAR_PED_PROP(self::ped, item.id, 1);
|
||||||
else
|
else
|
||||||
PED::SET_PED_PROP_INDEX(self::ped, item.id, item.drawable_id, 0, TRUE, 1);
|
PED::SET_PED_PROP_INDEX(self::ped, item.id, item.drawable_id, 0, TRUE, 1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
for (auto& item : props.items)
|
for (auto& item : props.items)
|
||||||
{
|
{
|
||||||
ImGui::SetNextItemWidth(60);
|
ImGui::SetNextItemWidth(60);
|
||||||
if (ImGui::InputInt(std::format("{} {} [0,{}]", item.label, "OUTFIT_TEX"_T, item.texture_id_max).c_str(), &item.texture_id, 0))
|
if (ImGui::InputInt(std::format("{} {} [0,{}]", item.label, "OUTFIT_TEX"_T, item.texture_id_max).c_str(), &item.texture_id, 0))
|
||||||
{
|
{
|
||||||
g_fiber_pool->queue_job([item] {
|
g_fiber_pool->queue_job([item] {
|
||||||
PED::SET_PED_PROP_INDEX(self::ped, item.id, item.drawable_id, item.texture_id, TRUE, 1);
|
PED::SET_PED_PROP_INDEX(self::ped, item.id, item.drawable_id, item.texture_id, TRUE, 1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
static char outfit_name[MAX_PATH] = {};
|
static char outfit_name[MAX_PATH] = {};
|
||||||
static folder saved_outfit_path = g_file_manager->get_project_folder("saved_outfits");
|
static folder saved_outfit_path = g_file_manager->get_project_folder("saved_outfits");
|
||||||
std::vector<std::string> saved_outfits;
|
std::vector<std::string> saved_outfits;
|
||||||
for (const auto& directory_entry : std::filesystem::directory_iterator(saved_outfit_path.get_path()))
|
for (const auto& directory_entry : std::filesystem::directory_iterator(saved_outfit_path.get_path()))
|
||||||
saved_outfits.push_back(directory_entry.path().filename().generic_string());
|
saved_outfits.push_back(directory_entry.path().filename().generic_string());
|
||||||
static int selected_index = -1;
|
static int selected_index = -1;
|
||||||
|
|
||||||
ImGui::SetNextItemWidth(300);
|
ImGui::SetNextItemWidth(300);
|
||||||
|
|
||||||
ImGui::InputText("##outfit_name", outfit_name, sizeof(outfit_name));
|
ImGui::InputText("##outfit_name", outfit_name, sizeof(outfit_name));
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
components::button("OUTFIT_SAVE_CURRENT"_T, [] {
|
components::button("OUTFIT_SAVE_CURRENT"_T, [] {
|
||||||
nlohmann::json j;
|
nlohmann::json j;
|
||||||
nlohmann::json j_components;
|
nlohmann::json j_components;
|
||||||
nlohmann::json j_props;
|
nlohmann::json j_props;
|
||||||
|
|
||||||
for (auto& item : components.items)
|
for (auto& item : components.items)
|
||||||
{
|
{
|
||||||
nlohmann::json tmp;
|
nlohmann::json tmp;
|
||||||
tmp["drawable_id"] = item.drawable_id;
|
tmp["drawable_id"] = item.drawable_id;
|
||||||
tmp["texture_id"] = item.texture_id;
|
tmp["texture_id"] = item.texture_id;
|
||||||
j_components[std::to_string(item.id)] = tmp;
|
j_components[std::to_string(item.id)] = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& item : props.items)
|
for (auto& item : props.items)
|
||||||
{
|
{
|
||||||
nlohmann::json tmp;
|
nlohmann::json tmp;
|
||||||
tmp["drawable_id"] = item.drawable_id;
|
tmp["drawable_id"] = item.drawable_id;
|
||||||
tmp["texture_id"] = item.texture_id;
|
tmp["texture_id"] = item.texture_id;
|
||||||
j_props[std::to_string(item.id)] = tmp;
|
j_props[std::to_string(item.id)] = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
j["components"] = j_components;
|
j["components"] = j_components;
|
||||||
j["props"] = j_props;
|
j["props"] = j_props;
|
||||||
|
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
std::string str = outfit_name;
|
std::string str = outfit_name;
|
||||||
while (saved_outfit_path.get_file(str + ".json").exists())
|
while (saved_outfit_path.get_file(str + ".json").exists())
|
||||||
str = std::format("{}({})", outfit_name, ++index);
|
str = std::format("{}({})", outfit_name, ++index);
|
||||||
|
|
||||||
std::ofstream o(saved_outfit_path.get_file(str + ".json").get_path());
|
std::ofstream o(saved_outfit_path.get_file(str + ".json").get_path());
|
||||||
o << std::setw(4) << j << std::endl;
|
o << std::setw(4) << j << std::endl;
|
||||||
});
|
});
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
components::button("OUTFIT_APPLY_SELECTED"_T, [saved_outfits] {
|
components::button("OUTFIT_APPLY_SELECTED"_T, [saved_outfits] {
|
||||||
if (selected_index >= 0 && selected_index < saved_outfits.size())
|
if (selected_index >= 0 && selected_index < saved_outfits.size())
|
||||||
{
|
{
|
||||||
std::ifstream i(saved_outfit_path.get_file(saved_outfits[selected_index]).get_path());
|
std::ifstream i(saved_outfit_path.get_file(saved_outfits[selected_index]).get_path());
|
||||||
nlohmann::json j;
|
nlohmann::json j;
|
||||||
i >> j;
|
i >> j;
|
||||||
|
|
||||||
for (auto& item : j["components"].items())
|
for (auto& item : j["components"].items())
|
||||||
{
|
{
|
||||||
std::stringstream ss(item.key());
|
std::stringstream ss(item.key());
|
||||||
int id = 0;
|
int id = 0;
|
||||||
ss >> id;
|
ss >> id;
|
||||||
int drawable_id = item.value()["drawable_id"];
|
int drawable_id = item.value()["drawable_id"];
|
||||||
int texture_id = item.value()["texture_id"];
|
int texture_id = item.value()["texture_id"];
|
||||||
PED::SET_PED_COMPONENT_VARIATION(self::ped, id, drawable_id, texture_id, PED::GET_PED_PALETTE_VARIATION(self::ped, id));
|
PED::SET_PED_COMPONENT_VARIATION(self::ped, id, drawable_id, texture_id, PED::GET_PED_PALETTE_VARIATION(self::ped, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& item : j["props"].items())
|
for (auto& item : j["props"].items())
|
||||||
{
|
{
|
||||||
std::stringstream ss(item.key());
|
std::stringstream ss(item.key());
|
||||||
int id = 0;
|
int id = 0;
|
||||||
ss >> id;
|
ss >> id;
|
||||||
int drawable_id = item.value()["drawable_id"];
|
int drawable_id = item.value()["drawable_id"];
|
||||||
int texture_id = item.value()["texture_id"];
|
int texture_id = item.value()["texture_id"];
|
||||||
if (drawable_id == -1)
|
if (drawable_id == -1)
|
||||||
PED::CLEAR_PED_PROP(self::ped, id, 1);
|
PED::CLEAR_PED_PROP(self::ped, id, 1);
|
||||||
else
|
else
|
||||||
PED::SET_PED_PROP_INDEX(self::ped, id, drawable_id, texture_id, TRUE, 1);
|
PED::SET_PED_PROP_INDEX(self::ped, id, drawable_id, texture_id, TRUE, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
components::button("OUTFIT_DELETE_SELECTED"_T, [saved_outfits] {
|
components::button("OUTFIT_DELETE_SELECTED"_T, [saved_outfits] {
|
||||||
if (selected_index >= 0 && selected_index < saved_outfits.size())
|
if (selected_index >= 0 && selected_index < saved_outfits.size())
|
||||||
{
|
{
|
||||||
std::filesystem::remove(saved_outfit_path.get_file(saved_outfits[selected_index]).get_path());
|
std::filesystem::remove(saved_outfit_path.get_file(saved_outfits[selected_index]).get_path());
|
||||||
if (selected_index == saved_outfits.size() - 1)
|
if (selected_index == saved_outfits.size() - 1)
|
||||||
--selected_index;
|
--selected_index;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (ImGui::BeginListBox("##outfit_editor_list_box", ImVec2(300, 0)))
|
if (ImGui::BeginListBox("##outfit_editor_list_box", ImVec2(300, 0)))
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < saved_outfits.size(); i++)
|
for (size_t i = 0; i < saved_outfits.size(); i++)
|
||||||
if (ImGui::Selectable(saved_outfits[i].c_str(), selected_index == i))
|
if (ImGui::Selectable(saved_outfits[i].c_str(), selected_index == i))
|
||||||
selected_index = i;
|
selected_index = i;
|
||||||
ImGui::EndListBox();
|
ImGui::EndListBox();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,124 +1,124 @@
|
|||||||
#include "natives.hpp"
|
#include "natives.hpp"
|
||||||
#include "pointers.hpp"
|
#include "pointers.hpp"
|
||||||
#include "util/outfit.hpp"
|
#include "util/outfit.hpp"
|
||||||
#include "views/view.hpp"
|
#include "views/view.hpp"
|
||||||
|
|
||||||
namespace big
|
namespace big
|
||||||
{
|
{
|
||||||
void view::outfit_slots()
|
void view::outfit_slots()
|
||||||
{
|
{
|
||||||
if (*g_pointers->m_script_globals)
|
if (*g_pointers->m_script_globals)
|
||||||
{
|
{
|
||||||
static int slot = 0;
|
static int slot = 0;
|
||||||
ImGui::SetNextItemWidth(160);
|
ImGui::SetNextItemWidth(160);
|
||||||
if (ImGui::InputInt("OUTFIT_SLOT"_T.data(), &slot))
|
if (ImGui::InputInt("OUTFIT_SLOT"_T.data(), &slot))
|
||||||
{
|
{
|
||||||
if (slot < 0)
|
if (slot < 0)
|
||||||
slot = 19;
|
slot = 19;
|
||||||
if (slot > 19)
|
if (slot > 19)
|
||||||
slot = 0;
|
slot = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::SetNextItemWidth(300);
|
ImGui::SetNextItemWidth(300);
|
||||||
ImGui::InputText("OUTFIT_NAME"_T.data(), outfit::get_slot_name_address(slot), 16);
|
ImGui::InputText("OUTFIT_NAME"_T.data(), outfit::get_slot_name_address(slot), 16);
|
||||||
|
|
||||||
static outfit::components_t components;
|
static outfit::components_t components;
|
||||||
static outfit::props_t props;
|
static outfit::props_t props;
|
||||||
|
|
||||||
g_fiber_pool->queue_job([] {
|
g_fiber_pool->queue_job([] {
|
||||||
for (auto& item : components.items)
|
for (auto& item : components.items)
|
||||||
{
|
{
|
||||||
item.drawable_id = *outfit::get_component_drawable_id_address(slot, item.id);
|
item.drawable_id = *outfit::get_component_drawable_id_address(slot, item.id);
|
||||||
item.drawable_id_max = PED::GET_NUMBER_OF_PED_DRAWABLE_VARIATIONS(self::ped, item.id) - 1;
|
item.drawable_id_max = PED::GET_NUMBER_OF_PED_DRAWABLE_VARIATIONS(self::ped, item.id) - 1;
|
||||||
|
|
||||||
item.texture_id = *outfit::get_component_texture_id_address(slot, item.id);
|
item.texture_id = *outfit::get_component_texture_id_address(slot, item.id);
|
||||||
item.texture_id_max = PED::GET_NUMBER_OF_PED_TEXTURE_VARIATIONS(self::ped, item.id, item.drawable_id) - 1;
|
item.texture_id_max = PED::GET_NUMBER_OF_PED_TEXTURE_VARIATIONS(self::ped, item.id, item.drawable_id) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& item : props.items)
|
for (auto& item : props.items)
|
||||||
{
|
{
|
||||||
item.drawable_id = *outfit::get_prop_drawable_id_address(slot, item.id);
|
item.drawable_id = *outfit::get_prop_drawable_id_address(slot, item.id);
|
||||||
item.drawable_id_max = PED::GET_NUMBER_OF_PED_PROP_DRAWABLE_VARIATIONS(self::ped, item.id) - 1;
|
item.drawable_id_max = PED::GET_NUMBER_OF_PED_PROP_DRAWABLE_VARIATIONS(self::ped, item.id) - 1;
|
||||||
|
|
||||||
item.texture_id = *outfit::get_prop_texture_id_address(slot, item.id);
|
item.texture_id = *outfit::get_prop_texture_id_address(slot, item.id);
|
||||||
item.texture_id_max = PED::GET_NUMBER_OF_PED_PROP_TEXTURE_VARIATIONS(self::ped, item.id, item.drawable_id) - 1;
|
item.texture_id_max = PED::GET_NUMBER_OF_PED_PROP_TEXTURE_VARIATIONS(self::ped, item.id, item.drawable_id) - 1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
components::button("EXPORT_TO_CLIPBOARD"_T, [] {
|
components::button("EXPORT_TO_CLIPBOARD"_T, [] {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
for (auto& item : components.items)
|
for (auto& item : components.items)
|
||||||
ss << item.id << " " << item.drawable_id << " " << item.texture_id << " ";
|
ss << item.id << " " << item.drawable_id << " " << item.texture_id << " ";
|
||||||
for (auto& item : props.items)
|
for (auto& item : props.items)
|
||||||
ss << item.id << " " << item.drawable_id << " " << item.texture_id << " ";
|
ss << item.id << " " << item.drawable_id << " " << item.texture_id << " ";
|
||||||
ImGui::SetClipboardText(ss.str().c_str());
|
ImGui::SetClipboardText(ss.str().c_str());
|
||||||
g_notification_service->push("OUTFIT"_T.data(), "EXPORT_TO_CLIPBOARD"_T.data());
|
g_notification_service->push("OUTFIT"_T.data(), "EXPORT_TO_CLIPBOARD"_T.data());
|
||||||
});
|
});
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
components::button("IMPORT_FROM_CLIPBOARD"_T, [] {
|
components::button("IMPORT_FROM_CLIPBOARD"_T, [] {
|
||||||
std::stringstream ss(ImGui::GetClipboardText());
|
std::stringstream ss(ImGui::GetClipboardText());
|
||||||
for (auto& item : components.items)
|
for (auto& item : components.items)
|
||||||
{
|
{
|
||||||
int id = 0;
|
int id = 0;
|
||||||
int drawable_id = 0;
|
int drawable_id = 0;
|
||||||
int texture_id = 0;
|
int texture_id = 0;
|
||||||
ss >> id;
|
ss >> id;
|
||||||
ss >> drawable_id;
|
ss >> drawable_id;
|
||||||
ss >> texture_id;
|
ss >> texture_id;
|
||||||
*outfit::get_component_drawable_id_address(slot, id) = drawable_id;
|
*outfit::get_component_drawable_id_address(slot, id) = drawable_id;
|
||||||
*outfit::get_component_texture_id_address(slot, id) = texture_id;
|
*outfit::get_component_texture_id_address(slot, id) = texture_id;
|
||||||
}
|
}
|
||||||
for (auto& item : props.items)
|
for (auto& item : props.items)
|
||||||
{
|
{
|
||||||
int id = 0;
|
int id = 0;
|
||||||
int drawable_id = 0;
|
int drawable_id = 0;
|
||||||
int texture_id = 0;
|
int texture_id = 0;
|
||||||
ss >> id;
|
ss >> id;
|
||||||
ss >> drawable_id;
|
ss >> drawable_id;
|
||||||
ss >> texture_id;
|
ss >> texture_id;
|
||||||
*outfit::get_prop_drawable_id_address(slot, id) = drawable_id;
|
*outfit::get_prop_drawable_id_address(slot, id) = drawable_id;
|
||||||
*outfit::get_prop_texture_id_address(slot, id) = texture_id;
|
*outfit::get_prop_texture_id_address(slot, id) = texture_id;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
for (auto& item : components.items)
|
for (auto& item : components.items)
|
||||||
{
|
{
|
||||||
ImGui::SetNextItemWidth(60);
|
ImGui::SetNextItemWidth(60);
|
||||||
ImGui::InputInt(std::format("{} [0,{}]", item.label, item.drawable_id_max).c_str(), outfit::get_component_drawable_id_address(slot, item.id), 0);
|
ImGui::InputInt(std::format("{} [0,{}]", item.label, item.drawable_id_max).c_str(), outfit::get_component_drawable_id_address(slot, item.id), 0);
|
||||||
}
|
}
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
for (auto& item : components.items)
|
for (auto& item : components.items)
|
||||||
{
|
{
|
||||||
ImGui::SetNextItemWidth(60);
|
ImGui::SetNextItemWidth(60);
|
||||||
ImGui::InputInt(std::format("{} {} [0,{}]", item.label, "OUTFIT_TEX"_T, item.texture_id_max).c_str(), outfit::get_component_texture_id_address(slot, item.id), 0);
|
ImGui::InputInt(std::format("{} {} [0,{}]", item.label, "OUTFIT_TEX"_T, item.texture_id_max).c_str(), outfit::get_component_texture_id_address(slot, item.id), 0);
|
||||||
}
|
}
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
for (auto& item : props.items)
|
for (auto& item : props.items)
|
||||||
{
|
{
|
||||||
ImGui::SetNextItemWidth(60);
|
ImGui::SetNextItemWidth(60);
|
||||||
ImGui::InputInt(std::format("{} [0,{}]", item.label, item.drawable_id_max).c_str(), outfit::get_prop_drawable_id_address(slot, item.id), 0);
|
ImGui::InputInt(std::format("{} [0,{}]", item.label, item.drawable_id_max).c_str(), outfit::get_prop_drawable_id_address(slot, item.id), 0);
|
||||||
}
|
}
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
for (auto& item : props.items)
|
for (auto& item : props.items)
|
||||||
{
|
{
|
||||||
ImGui::SetNextItemWidth(60);
|
ImGui::SetNextItemWidth(60);
|
||||||
ImGui::InputInt(std::format("{} {} [0,{}]", item.label, "OUTFIT_TEX"_T, item.texture_id_max).c_str(), outfit::get_prop_texture_id_address(slot, item.id), 0);
|
ImGui::InputInt(std::format("{} {} [0,{}]", item.label, "OUTFIT_TEX"_T, item.texture_id_max).c_str(), outfit::get_prop_texture_id_address(slot, item.id), 0);
|
||||||
}
|
}
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
33
src/views/settings/view_gta_cache.cpp
Normal file
33
src/views/settings/view_gta_cache.cpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#include "natives.hpp"
|
||||||
|
#include "pointers.hpp"
|
||||||
|
#include "script.hpp"
|
||||||
|
#include "services/gta_data/gta_data_service.hpp"
|
||||||
|
#include "thread_pool.hpp"
|
||||||
|
#include "views/view.hpp"
|
||||||
|
|
||||||
|
namespace big
|
||||||
|
{
|
||||||
|
void view::gta_cache()
|
||||||
|
{
|
||||||
|
auto ped_count = g_gta_data_service->peds().size();
|
||||||
|
auto veh_count = g_gta_data_service->vehicles().size();
|
||||||
|
auto wep_count = g_gta_data_service->weapons().size();
|
||||||
|
|
||||||
|
components::sub_title("GTA cache stats:");
|
||||||
|
ImGui::Text("Peds Cached: %d\nVehicles Cached: %d\nWeapons Cached: %d", ped_count, veh_count, wep_count);
|
||||||
|
|
||||||
|
if (components::button("Rebuild Cache in Online"))
|
||||||
|
{
|
||||||
|
g_gta_data_service->set_state(eGtaDataUpdateState::NEEDS_UPDATE);
|
||||||
|
|
||||||
|
if (!*g_pointers->m_is_session_started)
|
||||||
|
{
|
||||||
|
g_gta_data_service->update_in_online();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_gta_data_service->update_now();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,26 +1,38 @@
|
|||||||
#include "views/view.hpp"
|
#include "thread_pool.hpp"
|
||||||
|
#include "views/view.hpp"
|
||||||
namespace big
|
|
||||||
{
|
|
||||||
void view::translation_settings()
|
namespace big
|
||||||
{
|
{
|
||||||
const auto& language_entries = g_translation_service.available_translations();
|
void view::translation_settings()
|
||||||
const auto current_pack = g_translation_service.current_language_pack();
|
{
|
||||||
|
const auto& language_entries = g_translation_service.available_translations();
|
||||||
ImGui::Text("SETTINGS_LANGUAGES"_T.data());
|
const auto current_pack = g_translation_service.current_language_pack();
|
||||||
if (ImGui::BeginCombo("##combo-languages", language_entries.at(current_pack).name.c_str()))
|
|
||||||
{
|
ImGui::Text("SETTINGS_LANGUAGES"_T.data());
|
||||||
for (auto& i : language_entries)
|
if (ImGui::BeginCombo("##combo-languages", language_entries.at(current_pack).name.c_str()))
|
||||||
{
|
{
|
||||||
if (ImGui::Selectable(i.second.name.c_str(), i.first == current_pack))
|
for (auto& i : language_entries)
|
||||||
g_translation_service.select_language_pack(i.first);
|
{
|
||||||
|
if (ImGui::Selectable(i.second.name.c_str(), i.first == current_pack))
|
||||||
if (i.first == current_pack)
|
g_translation_service.select_language_pack(i.first);
|
||||||
{
|
|
||||||
ImGui::SetItemDefaultFocus();
|
if (i.first == current_pack)
|
||||||
}
|
{
|
||||||
}
|
ImGui::SetItemDefaultFocus();
|
||||||
ImGui::EndCombo();
|
}
|
||||||
}
|
}
|
||||||
}
|
ImGui::EndCombo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (components::button("Force Update Languages"))
|
||||||
|
{
|
||||||
|
g_thread_pool->push([]
|
||||||
|
{
|
||||||
|
g_translation_service.update_language_packs();
|
||||||
|
|
||||||
|
g_notification_service->push("Translations", "Finished updating translations.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -57,10 +57,11 @@ namespace big
|
|||||||
static void gta_data();
|
static void gta_data();
|
||||||
static void creator();
|
static void creator();
|
||||||
static void train();
|
static void train();
|
||||||
static void water();
|
|
||||||
static void blackhole();
|
static void blackhole();
|
||||||
static void model_swapper();
|
static void model_swapper();
|
||||||
static void nearby();
|
static void nearby();
|
||||||
|
static void world();
|
||||||
|
static void gta_cache();
|
||||||
|
|
||||||
static void player_info();
|
static void player_info();
|
||||||
static void player_troll();
|
static void player_troll();
|
||||||
|
@ -37,7 +37,7 @@ namespace big
|
|||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
|
|
||||||
ImGui::SetNextItemWidth(200);
|
ImGui::SetNextItemWidth(200);
|
||||||
if (ImGui::BeginCombo("##alldoorslock", "All doors"))
|
if (ImGui::BeginCombo("##alldoorslock", "VEHICLE_CONTROLLER_ALL_DOORS"_T.data()))
|
||||||
{
|
{
|
||||||
for (int lockindex = 0; lockindex < MAX_VEHICLE_LOCK_STATES; lockindex++)
|
for (int lockindex = 0; lockindex < MAX_VEHICLE_LOCK_STATES; lockindex++)
|
||||||
{
|
{
|
||||||
@ -52,7 +52,7 @@ namespace big
|
|||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
if (ImGui::Button("Open all"))
|
if (components::button("OPEN_ALL_DOORS"_T))
|
||||||
{
|
{
|
||||||
g_fiber_pool->queue_job([=] {
|
g_fiber_pool->queue_job([=] {
|
||||||
g_vehicle_control_service.operate_door(eDoorId::VEH_EXT_DOOR_INVALID_ID, true);
|
g_vehicle_control_service.operate_door(eDoorId::VEH_EXT_DOOR_INVALID_ID, true);
|
||||||
@ -60,7 +60,7 @@ namespace big
|
|||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
if (ImGui::Button("Close all"))
|
if (components::button("CLOSE_ALL_DOORS"_T))
|
||||||
{
|
{
|
||||||
g_fiber_pool->queue_job([=] {
|
g_fiber_pool->queue_job([=] {
|
||||||
g_vehicle_control_service.operate_door(eDoorId::VEH_EXT_DOOR_INVALID_ID, false);
|
g_vehicle_control_service.operate_door(eDoorId::VEH_EXT_DOOR_INVALID_ID, false);
|
||||||
@ -75,6 +75,7 @@ namespace big
|
|||||||
|
|
||||||
for (int i = 0; i < MAX_VEHICLE_DOORS; i++)
|
for (int i = 0; i < MAX_VEHICLE_DOORS; i++)
|
||||||
{
|
{
|
||||||
|
ImGui::PushID(i);
|
||||||
if (!g_vehicle_control_service.m_controlled_vehicle.doors[i].valid)
|
if (!g_vehicle_control_service.m_controlled_vehicle.doors[i].valid)
|
||||||
continue;
|
continue;
|
||||||
ImGui::SetNextItemWidth(200);
|
ImGui::SetNextItemWidth(200);
|
||||||
@ -94,15 +95,15 @@ namespace big
|
|||||||
|
|
||||||
ImGui::SameLine(300);
|
ImGui::SameLine(300);
|
||||||
|
|
||||||
std::string buttonlabel = g_vehicle_control_service.m_controlled_vehicle.doors[i].open ? "Close" : "Open";
|
const auto button_label = g_vehicle_control_service.m_controlled_vehicle.doors[i].open ? "CLOSE"_T : "OPEN"_T;
|
||||||
buttonlabel.append("##").append(std::to_string(i));
|
if (components::button(button_label))
|
||||||
if (ImGui::Button(buttonlabel.data()))
|
|
||||||
{
|
{
|
||||||
g_fiber_pool->queue_job([=] {
|
g_fiber_pool->queue_job([=] {
|
||||||
g_vehicle_control_service.operate_door((eDoorId)i,
|
g_vehicle_control_service.operate_door((eDoorId)i,
|
||||||
!g_vehicle_control_service.m_controlled_vehicle.doors[i].open);
|
!g_vehicle_control_service.m_controlled_vehicle.doors[i].open);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -118,21 +119,21 @@ namespace big
|
|||||||
"Rear",
|
"Rear",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (ImGui::Button("Toggle lights"))
|
if (components::button("VEHICLE_CONTROLLER_TOGGLE_LIGHTS"_T))
|
||||||
{
|
{
|
||||||
g_fiber_pool->queue_job([=] {
|
g_fiber_pool->queue_job([=] {
|
||||||
g_vehicle_control_service.operate_lights(!g_vehicle_control_service.m_controlled_vehicle.headlights, false);
|
g_vehicle_control_service.operate_lights(!g_vehicle_control_service.m_controlled_vehicle.headlights, false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Button("Toggle High beams"))
|
if (components::button("VEHICLE_CONTROLLER_TOGGLE_HIGH_BEAMS"_T))
|
||||||
{
|
{
|
||||||
g_fiber_pool->queue_job([=] {
|
g_fiber_pool->queue_job([=] {
|
||||||
g_vehicle_control_service.operate_lights(g_vehicle_control_service.m_controlled_vehicle.headlights,
|
g_vehicle_control_service.operate_lights(g_vehicle_control_service.m_controlled_vehicle.headlights,
|
||||||
!g_vehicle_control_service.m_controlled_vehicle.highbeams);
|
!g_vehicle_control_service.m_controlled_vehicle.highbeams);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (ImGui::Button("Interior lights on"))
|
if (components::button("VEHICLE_CONTROLLER_INTERIOR_LIGHTS_ON"_T))
|
||||||
{
|
{
|
||||||
g_fiber_pool->queue_job([=] {
|
g_fiber_pool->queue_job([=] {
|
||||||
if (g.window.vehicle_control.operation_animation)
|
if (g.window.vehicle_control.operation_animation)
|
||||||
@ -141,7 +142,7 @@ namespace big
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Button("Interior lights off"))
|
if (components::button("VEHICLE_CONTROLLER_INTERIOR_LIGHTS_OFF"_T))
|
||||||
{
|
{
|
||||||
g_fiber_pool->queue_job([=] {
|
g_fiber_pool->queue_job([=] {
|
||||||
if (g.window.vehicle_control.operation_animation)
|
if (g.window.vehicle_control.operation_animation)
|
||||||
@ -150,7 +151,7 @@ namespace big
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Text("Neon lights");
|
ImGui::Text("VEHICLE_CONTROLLER_NEON_LIGHTS"_T.data());
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
@ -180,18 +181,18 @@ namespace big
|
|||||||
|
|
||||||
static int movespeed = 1;
|
static int movespeed = 1;
|
||||||
|
|
||||||
if (ImGui::RadioButton("Walk", movespeed == 1))
|
if (ImGui::RadioButton("VEHICLE_CONTROLLER_ENTER_VEHICLE_SPEED_WALKING"_T.data(), movespeed == 1))
|
||||||
movespeed = 1;
|
movespeed = 1;
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::RadioButton("Run", movespeed == 2))
|
if (ImGui::RadioButton("VEHICLE_CONTROLLER_ENTER_VEHICLE_SPEED_RUNNING"_T.data(), movespeed == 2))
|
||||||
movespeed = 2;
|
movespeed = 2;
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::RadioButton("Sprint", movespeed == 3))
|
if (ImGui::RadioButton("VEHICLE_CONTROLLER_ENTER_VEHICLE_SPEED_SPRINTING"_T.data(), movespeed == 3))
|
||||||
movespeed = 3;
|
movespeed = 3;
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
if (ImGui::Button(seatnames[i]))
|
if (components::button(seatnames[i]))
|
||||||
{
|
{
|
||||||
g_fiber_pool->queue_job([=] {
|
g_fiber_pool->queue_job([=] {
|
||||||
if (g.window.vehicle_control.operation_animation)
|
if (g.window.vehicle_control.operation_animation)
|
||||||
@ -214,7 +215,7 @@ namespace big
|
|||||||
|
|
||||||
if (g_vehicle_control_service.m_controlled_vehicle.isconvertible)
|
if (g_vehicle_control_service.m_controlled_vehicle.isconvertible)
|
||||||
{
|
{
|
||||||
if (ImGui::Button(g_vehicle_control_service.m_controlled_vehicle.convertibelstate ? "Raise" : "Lower"))
|
if (components::button(g_vehicle_control_service.m_controlled_vehicle.convertibelstate ? "Raise" : "Lower"))
|
||||||
{
|
{
|
||||||
g_fiber_pool->queue_job([=] {
|
g_fiber_pool->queue_job([=] {
|
||||||
if (g.window.vehicle_control.operation_animation)
|
if (g.window.vehicle_control.operation_animation)
|
||||||
|
@ -10,22 +10,21 @@ namespace big
|
|||||||
{
|
{
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::Text("press 'Look behind' (C/R3 by default) to activate\npress WASD buttons or Left thumbstick to navigate\nUse scroll wheel/Mouse or Right thumbstick to zoom\npress E/Q or L1/R1 to modify speed\npress 'Jump' (Space/X/Square by default) to lock on an entity\npress 'Fire' (Mouse button 1/Right trigger by default) to Obliterate\npress Enter or A/X by default to teleport to target");
|
ImGui::Text("ORBITAL_DRONE_USAGE_DESCR"_T.data());
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::Checkbox("Detect player on lock", &g.world.orbital_drone.detect_player);
|
ImGui::Checkbox("ORBITAL_DRONE_AUTO_LOCK_ON_PLAYER"_T.data(), &g.world.orbital_drone.detect_player);
|
||||||
if (ImGui::IsItemHovered())
|
if (ImGui::IsItemHovered())
|
||||||
{
|
{
|
||||||
ImGui::BeginTooltip();
|
ImGui::BeginTooltip();
|
||||||
ImGui::Text("if enabled, changes the selected player to the one it detects upon locking on an entity");
|
ImGui::TextWrapped("ORBITAL_DRONE_AUTO_LOCK_ON_PLAYER_TOOLTIP"_T.data());
|
||||||
ImGui::Text("All explosions will be blamed on the selected player, defaulting to the local player");
|
|
||||||
ImGui::EndTooltip();
|
ImGui::EndTooltip();
|
||||||
}
|
}
|
||||||
ImGui::Text("Adjust fast modifier");
|
ImGui::Text("ORBITAL_DRONE_HIGH_SPEED_MULTIPLIER"_T.data());
|
||||||
ImGui::SliderFloat("##fastspeed", &g.world.orbital_drone.nav_ovverride_fast, 1.f, 10.f);
|
ImGui::SliderFloat("##fastspeed", &g.world.orbital_drone.nav_ovverride_fast, 1.f, 10.f);
|
||||||
ImGui::Text("Adjust slow modifier");
|
ImGui::Text("ORBITAL_DRONE_LOW_SPEED_MULTIPLIER"_T.data());
|
||||||
ImGui::SliderFloat("##slowspeed", &g.world.orbital_drone.nav_ovverride_slow, 0.f, 1.f);
|
ImGui::SliderFloat("##slowspeed", &g.world.orbital_drone.nav_ovverride_slow, 0.f, 1.f);
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
}
|
}
|
||||||
|
@ -1,41 +1,41 @@
|
|||||||
#include "fiber_pool.hpp"
|
#include "fiber_pool.hpp"
|
||||||
#include "util/session.hpp"
|
#include "util/session.hpp"
|
||||||
#include "views/view.hpp"
|
#include "views/view.hpp"
|
||||||
|
|
||||||
namespace big
|
namespace big
|
||||||
{
|
{
|
||||||
void view::time_and_weather()
|
void view::time_and_weather()
|
||||||
{
|
{
|
||||||
if (ImGui::TreeNode("LOCAL_TIME"_T.data()))
|
if (ImGui::TreeNode("LOCAL_TIME"_T.data()))
|
||||||
{
|
{
|
||||||
ImGui::Checkbox("OVERRIDE_TIME"_T.data(), &g.session.override_time);
|
ImGui::Checkbox("OVERRIDE_TIME"_T.data(), &g.session.override_time);
|
||||||
|
|
||||||
if (g.session.override_time)
|
if (g.session.override_time)
|
||||||
{
|
{
|
||||||
ImGui::SliderInt("HOUR"_T.data(), &g.session.custom_time.hour, 0, 23);
|
ImGui::SliderInt("HOUR"_T.data(), &g.session.custom_time.hour, 0, 23);
|
||||||
ImGui::SliderInt("MINUTE"_T.data(), &g.session.custom_time.minute, 0, 59);
|
ImGui::SliderInt("MINUTE"_T.data(), &g.session.custom_time.minute, 0, 59);
|
||||||
ImGui::SliderInt("SECOND"_T.data(), &g.session.custom_time.second, 0, 59);
|
ImGui::SliderInt("SECOND"_T.data(), &g.session.custom_time.second, 0, 59);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::TreeNode("LOCAL_WEATHER"_T.data()))
|
if (ImGui::TreeNode("LOCAL_WEATHER"_T.data()))
|
||||||
{
|
{
|
||||||
components::button("CLEAR_OVERRIDE"_T, [] {
|
components::button("CLEAR_OVERRIDE"_T, [] {
|
||||||
MISC::CLEAR_OVERRIDE_WEATHER();
|
MISC::CLEAR_OVERRIDE_WEATHER();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (ImGui::ListBox("##weather-listbox", &g.session.local_weather, session::weathers, 15))
|
if (ImGui::ListBox("##weather-listbox", &g.session.local_weather, session::weathers, 15))
|
||||||
{
|
{
|
||||||
g_fiber_pool->queue_job([] {
|
g_fiber_pool->queue_job([] {
|
||||||
session::local_weather();
|
session::local_weather();
|
||||||
});
|
});
|
||||||
|
|
||||||
ImGui::ListBoxFooter();
|
ImGui::ListBoxFooter();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
#include "fiber_pool.hpp"
|
|
||||||
#include "views/view.hpp"
|
|
||||||
|
|
||||||
namespace big
|
|
||||||
{
|
|
||||||
void view::water()
|
|
||||||
{
|
|
||||||
components::command_checkbox<"partwater">();
|
|
||||||
}
|
|
||||||
}
|
|
19
src/views/world/view_world.cpp
Normal file
19
src/views/world/view_world.cpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#include "views/view.hpp"
|
||||||
|
|
||||||
|
namespace big
|
||||||
|
{
|
||||||
|
void view::world()
|
||||||
|
{
|
||||||
|
components::sub_title("GUI_TAB_TIME_N_WEATHER"_T);
|
||||||
|
{
|
||||||
|
view::time_and_weather();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
components::sub_title("GUI_TAB_WATER"_T);
|
||||||
|
{
|
||||||
|
components::command_checkbox<"partwater">();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user