Save creator jobs and bug fixes (#713)
* feat(Session): Session info serialization * feat(Creator): Save and load jobs to file * fix(Creator): Actually load the job * fix(Creator): Try to fix loading * fix(ScriptFunction): Fix memory corruption due to low stack size * fix(Creator): Fix "No translation." * fix(NativeHooks): Fix softlock when loading Cayo Perico * chore(Toxic): Remove net time test for now
This commit is contained in:
parent
7da9427128
commit
792d765ffa
@ -82,11 +82,10 @@ namespace big
|
||||
"Spawn Into Personal Vehicle"
|
||||
};
|
||||
|
||||
auto transition_state = script_global(1574993);
|
||||
eTransitionState last_state = eTransitionState::TRANSITION_STATE_EMPTY;
|
||||
void looped::hud_transition_state()
|
||||
{
|
||||
const auto state = *transition_state.as<eTransitionState*>();
|
||||
const auto state = *scr_globals::transition_state.as<eTransitionState*>();
|
||||
|
||||
if (SCRIPT::GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(RAGE_JOAAT("maintransition")) == 0)
|
||||
return;
|
||||
|
@ -32,6 +32,7 @@ namespace big::scr_globals
|
||||
static inline script_global mission_creator_exited(1574530);
|
||||
|
||||
static inline script_global in_multiplayer(78558); // g_bInMultiplayer
|
||||
static inline script_global transition_state(1574993);
|
||||
|
||||
static inline script_global vehicle_global = script_global(1586468);
|
||||
static inline script_global mechanic_global = script_global(2793044);
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
class CMsgJoinResponse;
|
||||
class NetworkGameFilterMatchmakingComponent;
|
||||
class sCloudFile;
|
||||
|
||||
namespace rage
|
||||
{
|
||||
@ -15,6 +16,11 @@ namespace rage
|
||||
class CDynamicEntity;
|
||||
}
|
||||
|
||||
namespace datafile_commands
|
||||
{
|
||||
class SveFileObject;
|
||||
}
|
||||
|
||||
namespace big::functions
|
||||
{
|
||||
using run_script_threads = bool(*)(std::uint32_t ops_to_execute);
|
||||
@ -102,4 +108,11 @@ namespace big::functions
|
||||
using handle_remove_gamer_cmd = void* (*)(rage::snSession* session, rage::snPlayer* origin, rage::snMsgRemoveGamersFromSessionCmd* cmd);
|
||||
|
||||
using script_vm = int (*) (uint64_t* stack, int64_t** scr_globals, rage::scrProgram* program, rage::scrThreadContext* ctx);
|
||||
|
||||
using encode_session_info = bool(*)(rage::rlSessionInfo* info, char* buffer, int buffer_size, int* bytes_written);
|
||||
using decode_session_info = bool(*)(rage::rlSessionInfo* out_info, char* buffer, int* bytes_read);
|
||||
|
||||
using load_cloud_file = void(*)(sCloudFile** out_cloud_file, char* buffer, int size, const char* reason);
|
||||
using set_as_active_cloud_file = void(*)(datafile_commands::SveFileObject* object, sCloudFile** file);
|
||||
using save_json_data = char*(*)(datafile_commands::SveFileObject* object, int* out_length, const char* reason);
|
||||
}
|
||||
|
@ -7,9 +7,9 @@ namespace rage
|
||||
class tlsContext
|
||||
{
|
||||
public:
|
||||
char m_padding1[0xC8]; // 0x00
|
||||
sysMemAllocator* m_allocator; // 0xC8
|
||||
char m_padding2[0x778]; // 0xD0
|
||||
char m_padding1[0xB8]; // 0x00
|
||||
sysMemAllocator* m_allocator; // 0xB8
|
||||
char m_padding2[0x788]; // 0xD0
|
||||
scrThread* m_script_thread; // 0x848
|
||||
bool m_is_script_thread_active; // 0x850
|
||||
|
||||
|
@ -21,22 +21,6 @@ namespace big
|
||||
src->set_return_value(return_value);
|
||||
}
|
||||
|
||||
void NETWORK_HAS_RECEIVED_HOST_BROADCAST_DATA(rage::scrNativeCallContext* src)
|
||||
{
|
||||
if (SCRIPT::GET_HASH_OF_THIS_SCRIPT_NAME() == RAGE_JOAAT("freemode") && g->session.force_script_host)
|
||||
{
|
||||
g_fiber_pool->queue_job([]
|
||||
{
|
||||
scripts::force_host(RAGE_JOAAT("freemode"));
|
||||
if (auto script = gta_util::find_script_thread(RAGE_JOAAT("freemode")); script && script->m_net_component)
|
||||
script->m_net_component->block_host_migration(true);
|
||||
});
|
||||
}
|
||||
|
||||
*scr_globals::gsbd.as<int*>() = 4;
|
||||
src->set_return_value<BOOL>(TRUE);
|
||||
}
|
||||
|
||||
void NETWORK_SET_THIS_SCRIPT_IS_NETWORK_SCRIPT(rage::scrNativeCallContext* src)
|
||||
{
|
||||
if (rage::scrThread::get() && rage::scrThread::get()->m_handler)
|
||||
|
@ -41,5 +41,21 @@ namespace big
|
||||
if ((!g->m_mission_creator_thread) || src->get_arg<Blip>(0) != HUD::GET_MAIN_PLAYER_BLIP_ID())
|
||||
HUD::SET_BLIP_DISPLAY(src->get_arg<Blip>(0), src->get_arg<BOOL>(1));
|
||||
};
|
||||
|
||||
void NETWORK_HAS_RECEIVED_HOST_BROADCAST_DATA(rage::scrNativeCallContext* src)
|
||||
{
|
||||
if (SCRIPT::GET_HASH_OF_THIS_SCRIPT_NAME() == RAGE_JOAAT("freemode") && g->session.force_script_host)
|
||||
{
|
||||
g_fiber_pool->queue_job([]
|
||||
{
|
||||
scripts::force_host(RAGE_JOAAT("freemode"));
|
||||
if (auto script = gta_util::find_script_thread(RAGE_JOAAT("freemode")); script && script->m_net_component)
|
||||
script->m_net_component->block_host_migration(true);
|
||||
});
|
||||
}
|
||||
|
||||
*scr_globals::gsbd.as<int*>() = 4;
|
||||
src->set_return_value<BOOL>(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
@ -104,9 +104,9 @@ namespace big
|
||||
native_hooks::native_hooks()
|
||||
{
|
||||
add_native_detour(0x812595A0644CE1DE, all_scripts::IS_DLC_PRESENT);
|
||||
add_native_detour(0x5D10B3795F3FC886, all_scripts::NETWORK_HAS_RECEIVED_HOST_BROADCAST_DATA);
|
||||
add_native_detour(0x1CA59E306ECB80A5, all_scripts::NETWORK_SET_THIS_SCRIPT_IS_NETWORK_SCRIPT);
|
||||
add_native_detour(0xD1110739EEADB592, all_scripts::NETWORK_TRY_TO_SET_THIS_SCRIPT_IS_NETWORK_SCRIPT);
|
||||
|
||||
add_native_detour(RAGE_JOAAT("carmod_shop"), 0x06843DA7060A026B, carmod_shop::SET_ENTITY_COORDS);
|
||||
add_native_detour(RAGE_JOAAT("carmod_shop"), 0x8E2530AA8ADA980E, carmod_shop::SET_ENTITY_HEADING);
|
||||
add_native_detour(RAGE_JOAAT("carmod_shop"), 0x34E710FF01247C5A, carmod_shop::SET_VEHICLE_LIGHTS);
|
||||
@ -116,9 +116,12 @@ namespace big
|
||||
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"), 0x9029B2F3DA924928, freemode::SET_BLIP_DISPLAY);
|
||||
add_native_detour(RAGE_JOAAT("freemode"), 0x5D10B3795F3FC886, freemode::NETWORK_HAS_RECEIVED_HOST_BROADCAST_DATA);
|
||||
add_native_detour(RAGE_JOAAT("fmmc_launcher"), 0x5D10B3795F3FC886, freemode::NETWORK_HAS_RECEIVED_HOST_BROADCAST_DATA);
|
||||
add_native_detour(RAGE_JOAAT("shop_controller"), 0xDC38CC1E35B6A5D7, shop_controller::SET_WARNING_MESSAGE_WITH_HEADER);
|
||||
add_native_detour(RAGE_JOAAT("maintransition"), 0x6F3D4ED9BEE4E61D, network::NETWORK_SESSION_HOST);
|
||||
add_native_detour(RAGE_JOAAT("am_launcher"), 0xB8BA7F44DF1575E1, am_launcher::START_NEW_SCRIPT_WITH_ARGS);
|
||||
add_native_detour(RAGE_JOAAT("am_launcher"), 0x5D10B3795F3FC886, freemode::NETWORK_HAS_RECEIVED_HOST_BROADCAST_DATA);
|
||||
|
||||
add_native_detour(RAGE_JOAAT("fm_race_creator"), 0x2C83A9DA6BFFC4F9, creator::GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH);
|
||||
add_native_detour(RAGE_JOAAT("fm_capture_creator"), 0x2C83A9DA6BFFC4F9, creator::GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH);
|
||||
|
@ -672,12 +672,60 @@ namespace big
|
||||
m_invalid_decal_crash = ptr.add(1).rip().as<PVOID>();
|
||||
});
|
||||
|
||||
// Encode Session Info
|
||||
main_batch.add("ESI", "48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 20 57 48 81", [this](memory::handle ptr)
|
||||
{
|
||||
m_encode_session_info = ptr.as<functions::encode_session_info>();
|
||||
});
|
||||
|
||||
// Decode Session Info
|
||||
main_batch.add("DSI", "48 89 5C 24 08 48 89 6C 24 10 56 57 41 56 48 81 EC C0", [this](memory::handle ptr)
|
||||
{
|
||||
m_decode_session_info = ptr.as<functions::decode_session_info>();
|
||||
});
|
||||
|
||||
// Can Start Session Joining Check
|
||||
main_batch.add("CSSJC", "77 DB ? ? ? ? ? ? ? 74 09", [this](memory::handle ptr)
|
||||
{
|
||||
memory::byte_patch::make(ptr.as<void*>(), std::to_array({ 0x90, 0x90 }))->apply(); // join faster
|
||||
});
|
||||
|
||||
// Can Start Joining Joining Check
|
||||
main_batch.add("CSJJC", "74 16 48 8B 0B E8 ? ? ? ? 84 C0", [this](memory::handle ptr)
|
||||
{
|
||||
memory::byte_patch::make(ptr.as<uint8_t*>(), 0xEB)->apply(); // join faster
|
||||
});
|
||||
|
||||
// NTQVM Caller
|
||||
main_batch.add("NTQVMC", "66 0F 6F 0D ? ? ? ? 66 0F 6F 05 ? ? ? ? 66 0F 66 C4", [this](memory::handle ptr)
|
||||
{
|
||||
memory::byte_patch::make(ptr.add(4).rip().sub(32).as<uint64_t*>(), (uint64_t)&hooks::nt_query_virtual_memory)->apply();
|
||||
});
|
||||
|
||||
// Main File Object
|
||||
main_batch.add("MFO", "48 8D 05 ? ? ? ? 48 8D 1C D0 EB 03", [this](memory::handle ptr)
|
||||
{
|
||||
m_main_file_object = ptr.add(3).rip().as<datafile_commands::SveFileObject*>();
|
||||
});
|
||||
|
||||
// Load Cloud File
|
||||
main_batch.add("LCF", "48 89 5C 24 08 48 89 74 24 10 57 48 83 EC 40 48 8B F2 48 8B D9 41 8B D0", [this](memory::handle ptr)
|
||||
{
|
||||
m_load_cloud_file = ptr.as<functions::load_cloud_file>();
|
||||
});
|
||||
|
||||
// Set As Active Cloud File
|
||||
main_batch.add("SAACF", "48 83 EC 28 45 33 C0 4C 39", [this](memory::handle ptr)
|
||||
{
|
||||
m_set_as_active_cloud_file = ptr.as<functions::set_as_active_cloud_file>();
|
||||
});
|
||||
|
||||
// Save JSON Data
|
||||
main_batch.add("SJD", "48 89 5C 24 08 57 48 83 EC 30 33 DB 48 8B FA 48", [this](memory::handle ptr)
|
||||
{
|
||||
m_save_json_data = ptr.as<functions::save_json_data>();
|
||||
});
|
||||
|
||||
auto mem_region = memory::module("GTA5.exe");
|
||||
main_batch.run(mem_region);
|
||||
|
||||
|
@ -204,6 +204,14 @@ namespace big
|
||||
|
||||
PVOID m_write_bitbuffer_gamer_handle;
|
||||
PVOID m_read_bitbuffer_gamer_handle;
|
||||
|
||||
functions::encode_session_info m_encode_session_info;
|
||||
functions::decode_session_info m_decode_session_info;
|
||||
|
||||
datafile_commands::SveFileObject* m_main_file_object;
|
||||
functions::load_cloud_file m_load_cloud_file;
|
||||
functions::set_as_active_cloud_file m_set_as_active_cloud_file;
|
||||
functions::save_json_data m_save_json_data;
|
||||
};
|
||||
|
||||
inline pointers* g_pointers{};
|
||||
|
@ -60,6 +60,24 @@ namespace big
|
||||
tls_ctx->m_is_script_thread_active = og_thread != nullptr;
|
||||
}
|
||||
|
||||
void script_function::static_call(std::initializer_list<std::uint64_t> args)
|
||||
{
|
||||
populate_ip();
|
||||
|
||||
rage::scrThread* thread = (rage::scrThread*)new uint8_t[sizeof(rage::scrThread)];
|
||||
memcpy(thread, rage::scrThread::get(), sizeof(rage::scrThread));
|
||||
|
||||
void* stack = new uint64_t[25000];
|
||||
thread->m_stack = stack;
|
||||
thread->m_context.m_stack_size = 25000;
|
||||
thread->m_context.m_stack_pointer = 1;
|
||||
|
||||
call(thread, gta_util::find_script_program(m_script), args);
|
||||
|
||||
delete[] stack;
|
||||
delete[] (uint8_t*)thread; // without the cast it ends up calling the destructor which leads to some pretty funny crashes
|
||||
}
|
||||
|
||||
void script_function::operator()(std::initializer_list<std::uint64_t> args)
|
||||
{
|
||||
populate_ip();
|
||||
|
@ -17,6 +17,10 @@ namespace big
|
||||
script_function(const std::string& name, const rage::joaat_t script, const std::string& pattern, int32_t offset);
|
||||
void populate_ip();
|
||||
void call(rage::scrThread* thread, rage::scrProgram* program, std::initializer_list<std::uint64_t> args);
|
||||
|
||||
// for pure functions that do not need access to thread stack
|
||||
void static_call(std::initializer_list<std::uint64_t> args);
|
||||
|
||||
void operator()(std::initializer_list<std::uint64_t> args);
|
||||
};
|
||||
|
||||
@ -25,5 +29,8 @@ namespace big
|
||||
static inline script_function join_ceo("JC", RAGE_JOAAT("freemode"), "2D 04 1D 00 00 5D", 0);
|
||||
static inline script_function dance_loop("DL", RAGE_JOAAT("am_mp_nightclub"), "2D 00 14 00 00 4F ? ? 47 ? ? 5D ? ? ? 56", 0);
|
||||
static inline script_function init_nightclub_script("INS", RAGE_JOAAT("am_mp_nightclub"), "2D 00 11 00 00 4F", 0);
|
||||
|
||||
static inline script_function save_to_datafile("STD", RAGE_JOAAT("fm_race_creator"), "2D 01 03 00 00 71 2C", 0);
|
||||
static inline script_function load_from_datafile("LFD", RAGE_JOAAT("fm_race_creator"), "2D 04 0D 00 00 71 2C", 0);
|
||||
}
|
||||
}
|
91
src/services/creator_storage/creator_storage_service.cpp
Normal file
91
src/services/creator_storage/creator_storage_service.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
#include "gta/joaat.hpp"
|
||||
#include "creator_storage_service.hpp"
|
||||
#include "pointers.hpp"
|
||||
#include "gta/tls_context.hpp"
|
||||
#include "natives.hpp"
|
||||
#include "gta/sysMemAllocator.hpp"
|
||||
#include "script.hpp"
|
||||
#include "script_function.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
std::vector<std::string> creator_storage_service::list_files()
|
||||
{
|
||||
std::vector<std::string> file_paths;
|
||||
|
||||
const auto file_path = check_jobs_folder();
|
||||
for (const auto& directory_entry : std::filesystem::directory_iterator(file_path.get_path()))
|
||||
if (directory_entry.path().extension() == ".json")
|
||||
file_paths.push_back(directory_entry.path().filename().generic_string());
|
||||
|
||||
return file_paths;
|
||||
}
|
||||
|
||||
void creator_storage_service::create_file(std::string file)
|
||||
{
|
||||
std::ofstream(check_jobs_folder().get_file(file).get_path());
|
||||
}
|
||||
|
||||
void creator_storage_service::save_file(std::string_view filename)
|
||||
{
|
||||
std::ofstream file(check_jobs_folder().get_file(filename).get_path());
|
||||
|
||||
while (!SCRIPT::HAS_SCRIPT_WITH_NAME_HASH_LOADED(RAGE_JOAAT("fm_race_creator")))
|
||||
{
|
||||
SCRIPT::REQUEST_SCRIPT_WITH_NAME_HASH(RAGE_JOAAT("fm_race_creator"));
|
||||
script::get_current()->yield();
|
||||
}
|
||||
|
||||
char* storage = new char[0x50000];
|
||||
scr_functions::save_to_datafile.static_call({ (uint64_t)storage });
|
||||
delete[] storage;
|
||||
|
||||
SCRIPT::SET_SCRIPT_WITH_NAME_HASH_AS_NO_LONGER_NEEDED(RAGE_JOAAT("fm_race_creator"));
|
||||
|
||||
auto buffer = g_pointers->m_save_json_data(g_pointers->m_main_file_object, nullptr, "to save it to a file I guess?");
|
||||
|
||||
if (!buffer)
|
||||
{
|
||||
g_notification_service->push_error("Save Job", "Cannot obtain JSON data");
|
||||
return;
|
||||
}
|
||||
|
||||
file << buffer;
|
||||
file.close();
|
||||
|
||||
rage::tlsContext::get()->m_allocator->Free(buffer);
|
||||
}
|
||||
|
||||
void creator_storage_service::load_file(std::string_view file_name)
|
||||
{
|
||||
const auto file = check_jobs_folder().get_file(file_name);
|
||||
|
||||
std::ifstream file_stream(file.get_path());
|
||||
std::string buffer(std::istreambuf_iterator<char>{file_stream}, {});
|
||||
|
||||
if (DATAFILE::DATAFILE_GET_FILE_DICT(0) != nullptr)
|
||||
DATAFILE::DATAFILE_DELETE(0);
|
||||
|
||||
sCloudFile* cloud_file = nullptr;
|
||||
g_pointers->m_load_cloud_file(&cloud_file, buffer.data(), buffer.length(), "to load it from a file I guess?");
|
||||
g_pointers->m_set_as_active_cloud_file(g_pointers->m_main_file_object, &cloud_file);
|
||||
|
||||
while (!SCRIPT::HAS_SCRIPT_WITH_NAME_HASH_LOADED(RAGE_JOAAT("fm_race_creator")))
|
||||
{
|
||||
SCRIPT::REQUEST_SCRIPT_WITH_NAME_HASH(RAGE_JOAAT("fm_race_creator"));
|
||||
script::get_current()->yield();
|
||||
}
|
||||
|
||||
scr_functions::load_from_datafile.static_call({ 1, true, false, 0 });
|
||||
|
||||
SCRIPT::SET_SCRIPT_WITH_NAME_HASH_AS_NO_LONGER_NEEDED(RAGE_JOAAT("fm_race_creator"));
|
||||
file_stream.close();
|
||||
}
|
||||
|
||||
big::folder creator_storage_service::check_jobs_folder()
|
||||
{
|
||||
const auto folder = g_file_manager->get_project_folder("./jobs");
|
||||
|
||||
return folder;
|
||||
}
|
||||
}
|
18
src/services/creator_storage/creator_storage_service.hpp
Normal file
18
src/services/creator_storage/creator_storage_service.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include "natives.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
class creator_storage_service
|
||||
{
|
||||
public:
|
||||
static std::vector<std::string> list_files();
|
||||
|
||||
static void create_file(std::string name);
|
||||
static void load_file(std::string_view file_name);
|
||||
static void save_file(std::string_view file_name);
|
||||
|
||||
private:
|
||||
static big::folder check_jobs_folder();
|
||||
};
|
||||
}
|
@ -26,6 +26,7 @@ namespace big
|
||||
WORLD,
|
||||
SPAWN_PED,
|
||||
TIME_AND_WEATHER,
|
||||
CREATOR,
|
||||
|
||||
NETWORK,
|
||||
SESSION,
|
||||
@ -76,6 +77,7 @@ namespace big
|
||||
{ tabs::WORLD, { "World", nullptr, {
|
||||
{ tabs::SPAWN_PED, { "Spawn Ped", view::spawn_ped }},
|
||||
{ tabs::TIME_AND_WEATHER, { "Time And Weather", view::time_and_weather }},
|
||||
{ tabs::CREATOR, { "Creator", view::creator }}
|
||||
}}},
|
||||
{tabs::NETWORK, { "Network", nullptr, {
|
||||
{ tabs::SPOOFING, { "Spoofing", view::spoofing }},
|
||||
|
@ -210,7 +210,7 @@ incorrect:
|
||||
return;
|
||||
}
|
||||
|
||||
if (MISC::GET_NUMBER_OF_FREE_STACKS_OF_THIS_SIZE(51000) == 0)
|
||||
if (MISC::GET_NUMBER_OF_FREE_STACKS_OF_THIS_SIZE(54000) == 0)
|
||||
{
|
||||
g_notification_service->push_warning("Creator", "No free stacks for MISSION stack size");
|
||||
}
|
||||
@ -226,7 +226,7 @@ incorrect:
|
||||
*scr_globals::mission_creator_exited.as<bool*>() = false;
|
||||
*scr_globals::mission_creator_radar_follows_camera.as<bool*>() = true;
|
||||
|
||||
if (SYSTEM::START_NEW_SCRIPT_WITH_NAME_HASH(hash, 51000))
|
||||
if (SYSTEM::START_NEW_SCRIPT_WITH_NAME_HASH(hash, 54000))
|
||||
{
|
||||
g->m_mission_creator_thread = gta_util::find_script_thread(hash);
|
||||
}
|
||||
|
@ -32,6 +32,30 @@ namespace big::toxic
|
||||
blame_explode_coord(to_blame, coords, explosion_type, damage, is_audible, is_invisible, camera_shake);
|
||||
}
|
||||
|
||||
inline void ceo_kick(player_ptr target)
|
||||
{
|
||||
auto leader = *scr_globals::gpbd_fm_3.at(target->id(), scr_globals::size::gpbd_fm_3).at(10).as<int*>();
|
||||
|
||||
if (leader == -1)
|
||||
g_notification_service->push_warning("CEO Kick", "Player is not in a CEO/MC");
|
||||
else if (leader == target->id())
|
||||
{
|
||||
g_notification_service->push_error("CEO Kick", "Cannot kick leader of CEO/MC anymore");
|
||||
}
|
||||
else
|
||||
{
|
||||
// use a more private method to remove associate
|
||||
const size_t arg_count = 3;
|
||||
int64_t args[arg_count] = {
|
||||
(int64_t)eRemoteEvent::MarkPlayerAsBeast,
|
||||
(int64_t)self::id,
|
||||
leader
|
||||
};
|
||||
|
||||
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << target->id());
|
||||
}
|
||||
}
|
||||
|
||||
inline void send_player_to_island(player_ptr target)
|
||||
{
|
||||
const size_t arg_count = 2;
|
||||
@ -168,14 +192,14 @@ namespace big::toxic
|
||||
|
||||
if (wanted_level > 0)
|
||||
{
|
||||
*scr_globals::globalplayer_bd.at(self::id, scr_globals::size::globalplayer_bd).at(212).as<Player*>() = id;
|
||||
*scr_globals::globalplayer_bd.at(self::id, scr_globals::size::globalplayer_bd).at(213).as<int*>() = wanted_level;
|
||||
*scr_globals::globalplayer_bd.at(self::id, scr_globals::size::globalplayer_bd).at(214).as<Player*>() = id;
|
||||
*scr_globals::globalplayer_bd.at(self::id, scr_globals::size::globalplayer_bd).at(215).as<int*>() = wanted_level;
|
||||
|
||||
for (int i = 0; PLAYER::GET_PLAYER_WANTED_LEVEL(id) < wanted_level && i < 3600; i++)
|
||||
script::get_current()->yield(1ms);
|
||||
|
||||
*scr_globals::globalplayer_bd.at(self::id, scr_globals::size::globalplayer_bd).at(212).as<Player*>() = -1; // reset to prevent wanted from being constantly set
|
||||
*scr_globals::globalplayer_bd.at(self::id, scr_globals::size::globalplayer_bd).at(213).as<int*>() = -1;
|
||||
*scr_globals::globalplayer_bd.at(self::id, scr_globals::size::globalplayer_bd).at(214).as<Player*>() = -1; // reset to prevent wanted from being constantly set
|
||||
*scr_globals::globalplayer_bd.at(self::id, scr_globals::size::globalplayer_bd).at(215).as<int*>() = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "util/toxic.hpp"
|
||||
#include "core/data/apartment_names.hpp"
|
||||
#include "core/data/warehouse_names.hpp"
|
||||
#include <network/Network.hpp>
|
||||
|
||||
namespace big
|
||||
{
|
||||
@ -20,6 +21,22 @@ namespace big
|
||||
session::join_by_rockstar_id(rid);
|
||||
});
|
||||
|
||||
static char base64[500]{};
|
||||
ImGui::InputText("Session Info", base64, sizeof(base64));
|
||||
components::button("Join Session Info", []
|
||||
{
|
||||
rage::rlSessionInfo info;
|
||||
g_pointers->m_decode_session_info(&info, base64, nullptr);
|
||||
session::join_session(info);
|
||||
});
|
||||
ImGui::SameLine();
|
||||
components::button("Copy Current Session Info", []
|
||||
{
|
||||
char buf[0x100];
|
||||
g_pointers->m_encode_session_info(>a_util::get_network()->m_game_session.m_rline_session.m_session_info, buf, 0x7D, nullptr);
|
||||
ImGui::SetClipboardText(buf);
|
||||
});
|
||||
|
||||
components::sub_title("Session Switcher");
|
||||
if (ImGui::ListBoxHeader("###session_switch"))
|
||||
{
|
||||
@ -163,6 +180,14 @@ namespace big
|
||||
ImGui::SameLine();
|
||||
components::button("Remove All Weapons", [] { g_player_service->iterate([](auto& plyr) { toxic::remove_all_weapons(plyr.second); }); });
|
||||
|
||||
components::button("CEO Kick", [] {
|
||||
g_player_service->iterate([](auto& plyr)
|
||||
{
|
||||
if (*scr_globals::gpbd_fm_3.at(plyr.second->id(), scr_globals::size::gpbd_fm_3).at(10).as<int*>() != -1)
|
||||
toxic::ceo_kick(plyr.second);
|
||||
});
|
||||
});
|
||||
|
||||
components::small_text("Teleports");
|
||||
|
||||
if (ImGui::BeginCombo("##apartment", apartment_names[g->session.send_to_apartment_idx]))
|
||||
@ -262,10 +287,10 @@ namespace big
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginGroup();
|
||||
components::button("One-On-One Deathmatch", [] { scripts::start_launcher_script(187); });
|
||||
components::button("One-On-One Deathmatch", [] { scripts::start_launcher_script(197); });
|
||||
components::button("Impromptu Race", [] { scripts::start_launcher_script(16); });
|
||||
components::button("Flight School", [] { scripts::start_launcher_script(186); });
|
||||
components::button("Golf", [] { scripts::start_launcher_script(183); });
|
||||
components::button("Flight School", [] { scripts::start_launcher_script(196); });
|
||||
components::button("Golf", [] { scripts::start_launcher_script(193); });
|
||||
components::button("Tutorial", [] { scripts::start_launcher_script(20); });
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("Only works on joining players");
|
||||
@ -274,11 +299,11 @@ namespace big
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginGroup();
|
||||
components::button("Gunslinger", [] { scripts::start_launcher_script(201); });
|
||||
components::button("Space Monkey", [] { scripts::start_launcher_script(206); });
|
||||
components::button("Wizard", [] { scripts::start_launcher_script(202); });
|
||||
components::button("QUB3D", [] { scripts::start_launcher_script(207); });
|
||||
components::button("Camhedz", [] { scripts::start_launcher_script(208); });
|
||||
components::button("Gunslinger", [] { scripts::start_launcher_script(211); });
|
||||
components::button("Space Monkey", [] { scripts::start_launcher_script(216); });
|
||||
components::button("Wizard", [] { scripts::start_launcher_script(212); });
|
||||
components::button("QUB3D", [] { scripts::start_launcher_script(217); });
|
||||
components::button("Camhedz", [] { scripts::start_launcher_script(218); });
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::Checkbox("Disable Pedestrians", &g->session.disable_peds);
|
||||
|
@ -16,6 +16,7 @@ namespace big
|
||||
{
|
||||
static char name_buf[32];
|
||||
static char search[64];
|
||||
static char session_info[255];
|
||||
|
||||
ImGui::SetNextItemWidth(300.f);
|
||||
|
||||
@ -31,6 +32,7 @@ namespace big
|
||||
if (components::selectable(std::to_string(g_matchmaking_service->get_found_sessions()[i].info.m_session_token), i == selected_session_idx))
|
||||
{
|
||||
selected_session_idx = i;
|
||||
g_pointers->m_encode_session_info(&g_matchmaking_service->get_found_sessions()[i].info, session_info, 0x7D, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -57,12 +59,17 @@ namespace big
|
||||
auto& data = session.info.m_net_player_data;
|
||||
ImGui::Text("Host Rockstar ID: %d", data.m_gamer_handle.m_rockstar_id);
|
||||
|
||||
components::button("Copy Session Info", []
|
||||
{
|
||||
ImGui::SetClipboardText(session_info);
|
||||
});
|
||||
ImGui::SameLine();
|
||||
components::button("Join", [session]
|
||||
{
|
||||
if (SCRIPT::GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(RAGE_JOAAT("maintransition")) != 0 ||
|
||||
STREAMING::IS_PLAYER_SWITCH_IN_PROGRESS())
|
||||
{
|
||||
g_notification_service->push_error("RID Joiner", "Player switch in progress, wait a bit.");
|
||||
g_notification_service->push_error("Join Session", "Player switch in progress, wait a bit.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -15,12 +15,13 @@ namespace big
|
||||
toxic::kill_player(g_player_service->get_selected(), g_player_service->get_self());
|
||||
});
|
||||
|
||||
components::button("CEO Kick", [] { toxic::ceo_kick(g_player_service->get_selected()); });
|
||||
|
||||
components::button("Kick From Vehicle", [] { toxic::kick_player_from_vehicle(g_player_service->get_selected()); });
|
||||
ImGui::SameLine();
|
||||
components::button("Ragdoll Player", [] { toxic::ragdoll_player(g_player_service->get_selected()); });
|
||||
|
||||
components::button("Kick From Interior", [] { toxic::kick_player_from_interior(g_player_service->get_selected()); });
|
||||
ImGui::SameLine();
|
||||
components::button("Turn Into Beast", [] { toxic::turn_player_into_beast(g_player_service->get_selected()); });
|
||||
|
||||
static int wanted_level;
|
||||
|
@ -214,14 +214,6 @@ namespace big
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
||||
components::sub_title("Launch Creator");
|
||||
ImGui::BeginGroup();
|
||||
components::button("Race", [] { scripts::start_creator_script(RAGE_JOAAT("fm_race_creator")); }); ImGui::SameLine();
|
||||
components::button("Capture", [] { scripts::start_creator_script(RAGE_JOAAT("fm_capture_creator")); }); ImGui::SameLine();
|
||||
components::button("Deathmatch", [] { scripts::start_creator_script(RAGE_JOAAT("fm_deathmatch_creator")); }); ImGui::SameLine();
|
||||
components::button("LTS", [] { scripts::start_creator_script(RAGE_JOAAT("fm_lts_creator")); });
|
||||
ImGui::EndGroup();
|
||||
|
||||
g->self.proof_mask = 0;
|
||||
if (g->self.god_mode)
|
||||
{
|
||||
|
@ -46,6 +46,7 @@ namespace big
|
||||
static void weapons();
|
||||
static void context_menu();
|
||||
static void gta_data();
|
||||
static void creator();
|
||||
|
||||
static void player_info();
|
||||
static void player_troll();
|
||||
|
85
src/views/world/view_creator.cpp
Normal file
85
src/views/world/view_creator.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
#include "fiber_pool.hpp"
|
||||
#include "script.hpp"
|
||||
#include "views/view.hpp"
|
||||
#include "services/creator_storage/creator_storage_service.hpp"
|
||||
#include "util/scripts.hpp"
|
||||
|
||||
static bool cached_creator_files = false;
|
||||
static std::vector<std::string> creator_files;
|
||||
|
||||
namespace big
|
||||
{
|
||||
void view::creator()
|
||||
{
|
||||
static std::string selected_creator_file = "";
|
||||
if (!cached_creator_files)
|
||||
{
|
||||
creator_files = creator_storage_service::list_files();
|
||||
cached_creator_files = true;
|
||||
}
|
||||
|
||||
ImGui::PushItemWidth(250);
|
||||
components::sub_title("Saved Jobs");
|
||||
|
||||
if (ImGui::ListBoxHeader("##empty", ImVec2(200, 200)))
|
||||
{
|
||||
for (const auto& pair : creator_files)
|
||||
{
|
||||
if (ImGui::Selectable(pair.c_str(), selected_creator_file == pair))
|
||||
selected_creator_file = pair;
|
||||
}
|
||||
|
||||
ImGui::ListBoxFooter();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginGroup();
|
||||
|
||||
if (!selected_creator_file.empty())
|
||||
{
|
||||
components::button("Save To File", []
|
||||
{
|
||||
creator_storage_service::save_file(selected_creator_file);
|
||||
});
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
components::button("Load From File", []
|
||||
{
|
||||
creator_storage_service::load_file(selected_creator_file);
|
||||
});
|
||||
}
|
||||
|
||||
static char job_file_name_input[50]{};
|
||||
|
||||
ImGui::PushItemWidth(250);
|
||||
components::input_text_with_hint(
|
||||
"Job Name",
|
||||
"Ex: My Cool Job",
|
||||
job_file_name_input, IM_ARRAYSIZE(job_file_name_input));
|
||||
|
||||
components::button("Create Job File", []
|
||||
{
|
||||
cached_creator_files = false;
|
||||
creator_storage_service::create_file(std::string(job_file_name_input) + ".json");
|
||||
});
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
components::button("Refresh", []
|
||||
{
|
||||
cached_creator_files = false;
|
||||
});
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
||||
components::sub_title("Launch Creator");
|
||||
ImGui::BeginGroup();
|
||||
components::button("Race", [] { scripts::start_creator_script(RAGE_JOAAT("fm_race_creator")); }); ImGui::SameLine();
|
||||
components::button("Capture", [] { scripts::start_creator_script(RAGE_JOAAT("fm_capture_creator")); }); ImGui::SameLine();
|
||||
components::button("Deathmatch", [] { scripts::start_creator_script(RAGE_JOAAT("fm_deathmatch_creator")); }); ImGui::SameLine();
|
||||
components::button("LTS", [] { scripts::start_creator_script(RAGE_JOAAT("fm_lts_creator")); });
|
||||
ImGui::EndGroup();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user