Lua Scripting (#1334)
Closes #83 Fixes #1309 Fixes #1287 Fixes #1129 (actually fixed now)
This commit is contained in:
@ -44,6 +44,7 @@ namespace big
|
||||
STAT_EDITOR,
|
||||
|
||||
SETTINGS,
|
||||
LUA_SCRIPTS,
|
||||
CONTEXT_MENU_SETTINGS,
|
||||
ESP_SETTINGS,
|
||||
GTA_CACHE_SETTINGS,
|
||||
@ -62,6 +63,7 @@ namespace big
|
||||
const char name[48] = "";
|
||||
std::function<void()> func = nullptr;
|
||||
std::map<tabs, navigation_struct> sub_nav{};
|
||||
rage::joaat_t hash = rage::joaat(name);
|
||||
};
|
||||
|
||||
class gui_service final
|
||||
@ -146,6 +148,7 @@ namespace big
|
||||
"GUI_TAB_SETTINGS",
|
||||
view::settings,
|
||||
{
|
||||
{tabs::LUA_SCRIPTS, {"GUI_TAB_LUA_SCRIPTS", view::lua_scripts}},
|
||||
{tabs::CONTEXT_MENU_SETTINGS, {"GUI_TAB_CONTEXT_MENU", view::context_menu_settings}},
|
||||
{tabs::ESP_SETTINGS, {"GUI_TAB_ESP", view::esp_settings}},
|
||||
{tabs::GTA_CACHE_SETTINGS, {"GTA Cache", view::gta_cache}},
|
||||
|
@ -22,22 +22,22 @@ namespace big
|
||||
this->notifications.emplace(std::hash<std::string>{}(n.message + n.title), n);
|
||||
}
|
||||
|
||||
void notification_service::push(std::string title, std::string message)
|
||||
void notification_service::push(const std::string& title, const std::string& message)
|
||||
{
|
||||
this->push({NotificationType::INFO, title, message, std::chrono::system_clock::now(), 5000.f, 1.f});
|
||||
}
|
||||
|
||||
void notification_service::push_warning(std::string title, std::string message)
|
||||
void notification_service::push_warning(const std::string& title, const std::string& message)
|
||||
{
|
||||
this->push({NotificationType::WARNING, title, message, std::chrono::system_clock::now(), 7000.f, 1.f});
|
||||
}
|
||||
|
||||
void notification_service::push_error(std::string title, std::string message)
|
||||
void notification_service::push_error(const std::string& title, const std::string& message)
|
||||
{
|
||||
this->push({NotificationType::DANGER, title, message, std::chrono::system_clock::now(), 7000.f, 1.f});
|
||||
}
|
||||
|
||||
void notification_service::push_success(std::string title, std::string message)
|
||||
void notification_service::push_success(const std::string& title, const std::string& message)
|
||||
{
|
||||
this->push({NotificationType::SUCCESS, title, message, std::chrono::system_clock::now(), 7000.f, 1.f});
|
||||
}
|
||||
|
@ -28,10 +28,10 @@ namespace big
|
||||
virtual ~notification_service();
|
||||
|
||||
void push(notification);
|
||||
void push(std::string, std::string);
|
||||
void push_warning(std::string, std::string);
|
||||
void push_error(std::string, std::string);
|
||||
void push_success(std::string, std::string);
|
||||
void push(const std::string&, const std::string&);
|
||||
void push_warning(const std::string&, const std::string&);
|
||||
void push_error(const std::string&, const std::string&);
|
||||
void push_success(const std::string&, const std::string&);
|
||||
std::vector<notification> get();
|
||||
|
||||
std::map<NotificationType, ImVec4> notification_colors = {
|
||||
|
@ -83,6 +83,8 @@ namespace big
|
||||
std::optional<std::uint32_t> time_difference;
|
||||
std::uint32_t num_time_syncs_sent = 9999;
|
||||
|
||||
bool block_explosions = false;
|
||||
|
||||
protected:
|
||||
bool equals(const CNetGamePlayer* net_game_player) const;
|
||||
|
||||
|
@ -8,7 +8,8 @@
|
||||
namespace big
|
||||
{
|
||||
translation_service::translation_service() :
|
||||
m_url("https://cdn.jsdelivr.net/gh/YimMenu/Translations@master")
|
||||
m_url("https://raw.githubusercontent.com/YimMenu/Translations/master"),
|
||||
m_fallback_url("https://cdn.jsdelivr.net/gh/YimMenu/Translations@master")
|
||||
{
|
||||
}
|
||||
|
||||
@ -39,7 +40,6 @@ namespace big
|
||||
m_local_index.version = m_remote_index.version;
|
||||
}
|
||||
load_translations();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -151,7 +151,7 @@ namespace big
|
||||
{
|
||||
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});
|
||||
cpr::Response response = download_file("/" + it->second.file);
|
||||
|
||||
if (response.status_code == 200)
|
||||
{
|
||||
@ -170,7 +170,7 @@ namespace big
|
||||
|
||||
bool translation_service::download_index()
|
||||
{
|
||||
cpr::Response response = cpr::Get(cpr::Url{m_url + "/index.json"});
|
||||
cpr::Response response = download_file("/index.json");
|
||||
|
||||
if (response.status_code == 200)
|
||||
{
|
||||
@ -210,4 +210,14 @@ namespace big
|
||||
m_remote_index.default_lang = m_local_index.fallback_default_language;
|
||||
m_remote_index.translations = m_local_index.fallback_languages;
|
||||
}
|
||||
|
||||
cpr::Response translation_service::download_file(const std::string& filename)
|
||||
{
|
||||
cpr::Response response = cpr::Get(cpr::Url{m_url + filename});
|
||||
|
||||
if (response.status_code != 200)
|
||||
response = cpr::Get(cpr::Url{m_fallback_url + filename});
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include "local_index.hpp"
|
||||
#include "remote_index.hpp"
|
||||
|
||||
#include <cpr/response.h>
|
||||
|
||||
namespace big
|
||||
{
|
||||
using translation_map = std::unordered_map<rage::joaat_t, std::string>;
|
||||
@ -47,9 +49,12 @@ namespace big
|
||||
* @brief Attempts to load the remote from the local index fallback
|
||||
*/
|
||||
void use_fallback_remote();
|
||||
cpr::Response download_file(const std::string& filename);
|
||||
|
||||
private:
|
||||
const std::string m_url;
|
||||
const std::string m_fallback_url;
|
||||
|
||||
std::unique_ptr<folder> m_translation_directory;
|
||||
local_index m_local_index;
|
||||
remote_index m_remote_index;
|
||||
|
134
src/services/tunables/tunables_service.cpp
Normal file
134
src/services/tunables/tunables_service.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
#include "tunables_service.hpp"
|
||||
|
||||
#include "memory/module.hpp"
|
||||
#include "natives.hpp"
|
||||
#include "pointers.hpp"
|
||||
#include "script.hpp"
|
||||
#include "services/script_patcher/script_patcher_service.hpp"
|
||||
#include "thread_pool.hpp"
|
||||
#include "util/scripts.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
tunables_service::tunables_service() :
|
||||
m_cache_file(g_file_manager->get_project_file("./cache/tunables.bin"), 1)
|
||||
{
|
||||
m_cache_file.load();
|
||||
|
||||
if (m_cache_file.up_to_date(memory::module("GTA5.exe").size()))
|
||||
{
|
||||
LOG(INFO) << "Loading tunables from cache";
|
||||
m_loading = true;
|
||||
|
||||
g_thread_pool->push([this] {
|
||||
while (!g_pointers->m_gta.m_script_globals[1])
|
||||
{
|
||||
if (!m_loading)
|
||||
return;
|
||||
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
load();
|
||||
});
|
||||
}
|
||||
|
||||
g_tunables_service = this;
|
||||
}
|
||||
|
||||
tunables_service::~tunables_service()
|
||||
{
|
||||
m_loading = false;
|
||||
g_tunables_service = nullptr;
|
||||
}
|
||||
|
||||
void tunables_service::run_script()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
script::get_current()->yield();
|
||||
|
||||
if (m_initialized || m_loading)
|
||||
return;
|
||||
|
||||
if (!m_script_started && SCRIPT::GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(RAGE_JOAAT("tuneables_processing")) > 0)
|
||||
continue;
|
||||
|
||||
if (!m_script_started)
|
||||
{
|
||||
SCRIPT::REQUEST_SCRIPT_WITH_NAME_HASH(RAGE_JOAAT("tuneables_processing"));
|
||||
|
||||
if (SCRIPT::HAS_SCRIPT_WITH_NAME_HASH_LOADED(RAGE_JOAAT("tuneables_processing")))
|
||||
{
|
||||
std::uint64_t args[] = {6, 27, 1}; // TODO: check args
|
||||
|
||||
int id = SYSTEM::START_NEW_SCRIPT_WITH_NAME_HASH_AND_ARGS(RAGE_JOAAT("tuneables_processing"), (Any*)args, sizeof(args) / 8, 1424);
|
||||
|
||||
if (!id)
|
||||
{
|
||||
LOG(FATAL) << "Failed to start tuneables_processing. Cannot cache tunables";
|
||||
return;
|
||||
}
|
||||
|
||||
SCRIPT::SET_SCRIPT_WITH_NAME_HASH_AS_NO_LONGER_NEEDED(RAGE_JOAAT("tuneables_processing"));
|
||||
m_script_started = true;
|
||||
|
||||
g_script_patcher_service->add_patch({RAGE_JOAAT("tuneables_processing"), "2E ? ? 55 ? ? 38 06", 0, std::vector<uint8_t>(17, 0x0), &m_script_started}); // bool tunables registration hack
|
||||
if (auto program = gta_util::find_script_program(RAGE_JOAAT("tuneables_processing")))
|
||||
g_script_patcher_service->on_script_load(program);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SCRIPT::GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(RAGE_JOAAT("tuneables_processing")) == 0)
|
||||
{
|
||||
m_script_started = false;
|
||||
m_initialized = true;
|
||||
LOG(INFO) << "Saving " << m_tunables.size() << " tunables to cache";
|
||||
g_script_patcher_service->update();
|
||||
save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tunables_service::save()
|
||||
{
|
||||
auto data_size = sizeof(std::uint32_t) + sizeof(tunable_save_struct) * m_tunables.size();
|
||||
auto data = std::make_unique<std::uint8_t[]>(data_size);
|
||||
auto data_ptr = data.get();
|
||||
|
||||
*(std::uint32_t*)data_ptr = m_tunables.size();
|
||||
data_ptr += sizeof(std::uint32_t);
|
||||
|
||||
for (auto& [hash, ptr] : m_tunables)
|
||||
{
|
||||
auto save_struct = (tunable_save_struct*)data_ptr;
|
||||
save_struct->hash = hash;
|
||||
save_struct->offset = ((std::int64_t*)ptr) - g_pointers->m_gta.m_script_globals[1];
|
||||
data_ptr += sizeof(tunable_save_struct);
|
||||
}
|
||||
|
||||
m_cache_file.set_header_version(memory::module("GTA5.exe").size());
|
||||
m_cache_file.set_data(std::move(data), data_size);
|
||||
m_cache_file.write();
|
||||
}
|
||||
|
||||
void tunables_service::load()
|
||||
{
|
||||
auto data = m_cache_file.data();
|
||||
|
||||
auto num_tunables = *(std::uint32_t*)data;
|
||||
data += sizeof(std::uint32_t);
|
||||
|
||||
for (int i = 0; i < num_tunables; i++)
|
||||
{
|
||||
auto save_struct = (tunable_save_struct*)data;
|
||||
m_tunables.emplace(save_struct->hash, (void*)(g_pointers->m_gta.m_script_globals[1] + save_struct->offset));
|
||||
data += sizeof(tunable_save_struct);
|
||||
}
|
||||
|
||||
m_initialized = true;
|
||||
m_loading = false;
|
||||
}
|
||||
}
|
93
src/services/tunables/tunables_service.hpp
Normal file
93
src/services/tunables/tunables_service.hpp
Normal file
@ -0,0 +1,93 @@
|
||||
#pragma once
|
||||
#include "fiber_pool.hpp"
|
||||
#include "script.hpp"
|
||||
#include "services/gta_data/cache_file.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
#pragma pack(push, 1)
|
||||
struct tunable_save_struct
|
||||
{
|
||||
rage::joaat_t hash;
|
||||
std::uint32_t offset;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
class tunables_service
|
||||
{
|
||||
public:
|
||||
tunables_service();
|
||||
~tunables_service();
|
||||
void run_script();
|
||||
|
||||
inline bool caching_tunables()
|
||||
{
|
||||
return m_script_started;
|
||||
}
|
||||
|
||||
inline bool initialized()
|
||||
{
|
||||
return m_initialized;
|
||||
}
|
||||
|
||||
inline void register_tunable(rage::joaat_t hash, void* pointer)
|
||||
{
|
||||
m_tunables.emplace(hash, pointer);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::enable_if_t<std::is_pointer_v<T>, T> get_tunable(rage::joaat_t hash)
|
||||
{
|
||||
if (auto it = m_tunables.find(hash); it != m_tunables.end())
|
||||
return reinterpret_cast<T>(it->second);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// wrapper around get_tunable(), may not set the tunable immediately if the service isn't initialized yet
|
||||
template<typename T>
|
||||
inline void set_tunable(rage::joaat_t hash, T value)
|
||||
{
|
||||
if (initialized())
|
||||
{
|
||||
if (auto tunable = get_tunable<T*>(hash))
|
||||
{
|
||||
*tunable = value;
|
||||
LOG(INFO) << "Imm set";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(INFO) << "Not found";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_fiber_pool->queue_job([this, hash, value] {
|
||||
while (!initialized())
|
||||
script::get_current()->yield();
|
||||
|
||||
if (auto tunable = get_tunable<T*>(hash))
|
||||
{
|
||||
*tunable = value;
|
||||
|
||||
LOG(INFO) << "Delay set";
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_initialized = false;
|
||||
bool m_loading = false;
|
||||
bool m_script_started = false;
|
||||
|
||||
cache_file m_cache_file;
|
||||
|
||||
std::unordered_map<rage::joaat_t, void*> m_tunables{};
|
||||
|
||||
void save();
|
||||
void load();
|
||||
};
|
||||
|
||||
inline tunables_service* g_tunables_service;
|
||||
}
|
Reference in New Issue
Block a user