Play audio on voice chat and more (#1053)

* feat(VC): audio through voice chat
* fix(BlackHole): remove unnecessary cleanup
* fix(Formatting): fix formatting for initializer lists
* feat(LSC): reimplement LSC
* feat(Protections): add (untested) protections for vehicle kick and remote teleport
This commit is contained in:
maybegreat48 2023-03-09 12:23:01 +00:00 committed by GitHub
parent 2d44f14a22
commit ad90ee3f6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 845 additions and 323 deletions

View File

@ -3,7 +3,7 @@ include(FetchContent)
FetchContent_Declare(
gtav_classes
GIT_REPOSITORY https://github.com/Yimura/GTAV-Classes.git
GIT_TAG f71748dd1dfac7b1c678e0e8b87d2739bde314b6
GIT_TAG 56aeddea31d677efa0e5c4f84b4f353d420a8502
GIT_PROGRESS TRUE
CONFIGURE_COMMAND ""
BUILD_COMMAND ""

View File

@ -1,55 +0,0 @@
#include "backend/player_command.hpp"
#include "core/scr_globals.hpp"
#include "gta_util.hpp"
#include "natives.hpp"
#include "packet.hpp"
#include "pointers.hpp"
#include <network/Network.hpp>
namespace big
{
class lost_connection_kick : player_command
{
using player_command::player_command;
void gamer_handle_serialize(rage::rlGamerHandle& hnd, rage::datBitBuffer& buf)
{
buf.Write<uint8_t>(*reinterpret_cast<uint8_t*>(&hnd.m_platform), 8);
if (*reinterpret_cast<uint8_t*>(&hnd.m_platform) == 3)
{
buf.WriteInt64(*(int64_t*)&hnd.m_rockstar_id, 64);
buf.Write<uint8_t>(hnd.unk_0009, 8);
}
}
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::TOXIC;
}
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
if (gta_util::get_network()->m_game_session_ptr->is_host())
{
g_notification_service->push_error("Kick", "Cannot use the lost connection kick while host");
return;
}
packet msg{};
msg.write_message(rage::eNetMessage::MsgLostConnectionToHost);
msg.write<uint64_t>(gta_util::get_network()->m_game_session_ptr->m_rline_session.m_session_id, 64);
gamer_handle_serialize(player->get_net_data()->m_gamer_handle, msg);
for (auto& [_, plyr] : g_player_service->players())
{
if (plyr->is_host())
{
msg.send(plyr->get_session_player()->m_msg_id);
break;
}
}
}
};
lost_connection_kick g_lost_connection_kick("lckick", "Lost Connection Kick", "Can only be detected or blocked by the host. Does not work when you are the host, use Host Kick instead", 0);
}

View File

@ -15,5 +15,5 @@ namespace big
}
};
bring g_bring("bring", "Bring", "Teleports the player to you if they are in a vehicle", 0);
bring g_bring("bring", "Bring", "Teleports the player to you", 0, false);
}

View File

@ -1,7 +1,6 @@
#include "backend/command.hpp"
#include "natives.hpp"
#include "util/mobile.hpp"
#include "util/vehicle.hpp"
#include "util/teleport.hpp"
namespace big
{

View File

@ -1,7 +1,7 @@
#include "backend/command.hpp"
#include "natives.hpp"
#include "util/mobile.hpp"
#include "util/vehicle.hpp"
#include "util/teleport.hpp"
namespace big
{

View File

@ -0,0 +1,30 @@
#include "backend/looped_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
namespace big
{
class voice_chat_audio : looped_command
{
using looped_command::looped_command;
virtual void on_enable() override
{
*g_pointers->m_refresh_audio_input = true;
}
virtual void on_tick() override
{
NETWORK::NETWORK_OVERRIDE_SEND_RESTRICTIONS_ALL(true);
}
virtual void on_disable() override
{
*g_pointers->m_refresh_audio_input = true;
NETWORK::NETWORK_OVERRIDE_SEND_RESTRICTIONS_ALL(false);
}
};
voice_chat_audio g_voice_chat_audio("vcaudio", "Play Audio Through Voice Chat", "Plays the audio.wav file in the project folder through voice chat. The wave file must be encoded with a mono 16 bit 16kHz PCM format. You have to reset voice chat settings whenever you load the menu for the sound to play",
g.spoofing.voice_chat_audio);
}

View File

@ -1,70 +1,101 @@
#include "backend/looped/looped.hpp"
#include "gta/enums.hpp"
#include "gta_util.hpp"
#include "script_function.hpp"
#include "script_local.hpp"
#include "services/script_patcher/script_patcher_service.hpp"
#include "util/math.hpp"
#include "util/scripts.hpp"
namespace big
{
static bool state = false;
static bool busy = false;
constexpr auto CARMOD_SHOP_STRUCT = 730; // move_m@generic_idles@std -- one function below -- first local
constexpr auto CARMOD_SHOP_CUTSCENE = 2208;// "carmod_fam1" -- first boolean local below it
static bool bLastLsCustoms = false;
static bool bModshopReady = false;
void looped::vehicle_ls_customs()
{
if (busy)
if (g.vehicle.ls_customs && g.vehicle.ls_customs != bLastLsCustoms)
{
g_fiber_pool->queue_job([] {
scripts::request_script(RAGE_JOAAT("carmod_shop"));
if (scripts::wait_till_loaded(RAGE_JOAAT("carmod_shop")))
{
HUD::REQUEST_ADDITIONAL_TEXT("MOD_MNU", 9);
while (!HUD::HAS_THIS_ADDITIONAL_TEXT_LOADED("MOD_MNU", 9))
script::get_current()->yield();
GRAPHICS::REQUEST_STREAMED_TEXTURE_DICT("CommonMenu", false);
GRAPHICS::REQUEST_STREAMED_TEXTURE_DICT("MPShopSale", false);
GRAPHICS::REQUEST_STREAMED_TEXTURE_DICT("ShopUI_Title_Los_Santos_Car_Meet", false);
// clang-format off
while (!GRAPHICS::HAS_STREAMED_TEXTURE_DICT_LOADED("CommonMenu")
|| !GRAPHICS::HAS_STREAMED_TEXTURE_DICT_LOADED("MPShopSale")
|| !GRAPHICS::HAS_STREAMED_TEXTURE_DICT_LOADED("ShopUI_Title_Los_Santos_Car_Meet"))
script::get_current()->yield();
// clang-format on
auto id = SYSTEM::START_NEW_SCRIPT_WITH_NAME_HASH(RAGE_JOAAT("carmod_shop"), 5050);
if (!id)
return;
busy = true;
constexpr int hash = RAGE_JOAAT("carmod_shop");
if (g.vehicle.ls_customs && g.vehicle.ls_customs == state)
{
if (auto carmod_shop_thread = gta_util::find_script_thread(hash);
carmod_shop_thread && *script_local(carmod_shop_thread, CARMOD_SHOP_STRUCT).at(11).as<int*>() != 4)
{
g.vehicle.ls_customs = false;
g.m_modshop_thread = gta_util::find_script_thread_by_id(id);
if (!g.m_modshop_thread)
return;
*script_local(carmod_shop_thread, CARMOD_SHOP_STRUCT).as<int*>() = 1;// cleanup
g.m_modshop_thread->m_context.m_state = rage::eThreadState::unk_3;
scr_functions::modshop_loop.populate_ip();
scr_functions::setup_modshop.populate_ip();
g_script_patcher_service->update();
scr_functions::setup_modshop.call_latent(g.m_modshop_thread, gta_util::find_script_program(RAGE_JOAAT("carmod_shop")), {45, 0, 18, 0}, bModshopReady);
*script_local(g.m_modshop_thread->m_stack, 730).at(446).as<int*>() = 2;
*script_local(g.m_modshop_thread->m_stack, 2237).as<ControllerInputs*>() = ControllerInputs::INPUT_FRONTEND_LT;
}
});
bLastLsCustoms = true;
}
else if (!g.vehicle.ls_customs && g.vehicle.ls_customs != bLastLsCustoms)
{
if (g.m_modshop_thread)
g.m_modshop_thread->kill();
GRAPHICS::SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("CommonMenu");
GRAPHICS::SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPShopSale");
GRAPHICS::SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("ShopUI_Title_Los_Santos_Car_Meet");
g.m_modshop_thread = nullptr;
bLastLsCustoms = false;
bModshopReady = false;
g_script_patcher_service->update();
}
if (g.vehicle.ls_customs && g.vehicle.ls_customs != state)
if (self::veh == 0 || SCRIPT::GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(RAGE_JOAAT("maintransition")) > 0 || (!g.m_modshop_thread && bModshopReady))
{
Vehicle veh = self::veh;
if (!ENTITY::DOES_ENTITY_EXIST(veh) || ENTITY::IS_ENTITY_DEAD(veh, false))
{
busy = false;
g.vehicle.ls_customs = false;
g_notification_service->push_warning("LS Customs", "You aren't in a vehicle.");
return;
}
scripts::request_script(hash);
if (scripts::wait_till_loaded(hash))
if (g.vehicle.ls_customs && g.m_modshop_thread)
{
int args[] = {45, 0, 9};
scripts::start_script_with_args(hash, args, 3, 3600);
PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_VEH_CIN_CAM, true);
scripts::wait_till_running(hash);
if (*script_local(g.m_modshop_thread->m_stack, 2466).as<bool*>() && PAD::IS_CONTROL_JUST_PRESSED(2, (int)ControllerInputs::INPUT_FRONTEND_ACCEPT))
g.vehicle.ls_customs = false;
}
if (scripts::is_running(hash))
if (g.vehicle.ls_customs && bModshopReady && g.m_modshop_thread && g.m_modshop_thread->m_stack)
{
if (auto carmod_shop_thread = gta_util::find_script_thread(hash); carmod_shop_thread)
{
*script_local(carmod_shop_thread, CARMOD_SHOP_STRUCT).at(409).as<int*>() = veh;// "HIDDEN_RADIO_09_HIPHOP_OLD"
*script_local(carmod_shop_thread, CARMOD_SHOP_CUTSCENE).as<bool*>() = false;// skips cutscene that's invisible
*script_local(g.m_modshop_thread->m_stack, 2418).as<bool*>() = false;
*script_local(g.m_modshop_thread->m_stack, 730).at(638).as<int*>() = -1;
*script_local(g.m_modshop_thread->m_stack, 730).at(409).as<Vehicle*>() = self::veh;
*script_local(carmod_shop_thread, CARMOD_SHOP_STRUCT).at(11).as<int*>() = 4;
}
}
}
if (*script_local(g.m_modshop_thread->m_stack, 730).at(446).as<int*>() == 0)
*script_local(g.m_modshop_thread->m_stack, 730).at(446).as<int*>() = 2;
busy = false;
state = g.vehicle.ls_customs;
scr_functions::modshop_loop.call(g.m_modshop_thread, gta_util::find_script_program(RAGE_JOAAT("carmod_shop")), {});
}
}
}

View File

@ -1,5 +1,6 @@
#include "backend/looped/looped.hpp"
#include "core/enums.hpp"
#include "gta/enums.hpp"
#include "util/entity.hpp"
#include "util/vehicle.hpp"

View File

@ -1,5 +1,6 @@
#include "backend/looped/looped.hpp"
#include "core/enums.hpp"
#include "gta/enums.hpp"
#include "gui.hpp"
#include "util/math.hpp"
#include "util/vehicle.hpp"

View File

@ -44,6 +44,19 @@ namespace big
{0x2B, 0x2B, 0x2B, 0x00, 0x55},
&g.self.invisibility});
g_script_patcher_service->add_patch(
{RAGE_JOAAT("carmod_shop"), "2D 01 0A 00 00 4F ? ? 40 ? 41 ? 39 03", 5, {0x2E, 0x01, 0x00}, &g.vehicle.ls_customs});// disable camera
g_script_patcher_service->add_patch(
{RAGE_JOAAT("carmod_shop"), "2D 02 10 00 00 2C", 5, {0x71, 0x2E, 0x02, 0x01}, &g.vehicle.ls_customs});
g_script_patcher_service->add_patch(
{RAGE_JOAAT("carmod_shop"), "2D 00 B8 00 00", 5, {0x2E, 0x00, 0x00}, &g.vehicle.ls_customs});
g_script_patcher_service->add_patch(
{RAGE_JOAAT("carmod_shop"), "06 1F 56 ? ? 62 ? ? ? 56", 0, {0x2B, 0x2B, 0x55}, &g.vehicle.ls_customs});// buy mods for free in SP
g_script_patcher_service->add_patch(
{RAGE_JOAAT("carmod_shop"), "2D 03 16 00 00 5D", 5, {0x72, 0x2E, 0x03, 0x01}, &g.vehicle.ls_customs});// allow all vehicles
g_script_patcher_service->add_patch(
{RAGE_JOAAT("carmod_shop"), "2D 03 07 00 00 71 38 02", 5, {0x72, 0x2E, 0x03, 0x01}, &g.vehicle.ls_customs});// allow all vehicles 2
for (auto& entry : *g_pointers->m_script_program_table)
{
if (entry.m_program)

View File

@ -53,8 +53,9 @@ namespace big
int m_remote_controller_vehicle = -1;
int m_remote_controlled_vehicle = -1;
int m_mod_net_id = -1;
int m_test_net_id = -1;
std::uint16_t m_tp_veh_net_id;
std::uint16_t m_tp_player_net_id;
rage::fvector3 m_tp_position;
rage::scrThread* m_hunt_the_beast_thread = nullptr;
@ -63,6 +64,10 @@ namespace big
rage::scrThread* m_mission_creator_thread = nullptr;
rage::scrThread* m_modshop_thread = nullptr;
bool in_script_vm = false;
struct debug
{
struct logs
@ -512,7 +517,9 @@ namespace big
bool spoof_session_player_count = false;
int session_player_count = 25;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(spoofing, hide_from_player_list, spoof_cheater, spoof_hide_god, spoof_hide_spectate, spoof_crew_data, crew_tag, rockstar_crew, square_crew_tag, spoof_session_region_type, session_region_type, spoof_session_language, session_language, spoof_session_player_count, session_player_count, spoof_blip, blip_type, spoof_rank, rank, spoof_job_points, job_points, spoof_bad_sport, badsport_type, spoof_kd_ratio, kd_ratio, spoof_player_model, player_model)
bool voice_chat_audio = false;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(spoofing, hide_from_player_list, spoof_cheater, spoof_hide_god, spoof_hide_spectate, spoof_crew_data, crew_tag, rockstar_crew, square_crew_tag, spoof_session_region_type, session_region_type, spoof_session_language, session_language, spoof_session_player_count, session_player_count, voice_chat_audio)
} spoofing{};
struct vehicle
@ -587,13 +594,7 @@ namespace big
bool no_collision = false;
bool unlimited_weapons = false;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(vehicle,
speedo_meter, fly, rainbow_paint, speed_unit, god_mode,
proof_bullet, proof_fire, proof_collision, proof_melee, proof_explosion, proof_steam, proof_water, proof_mask,
auto_drive_destination, auto_drive_style, auto_drive_speed, auto_turn_signals, boost_behavior,
drive_on_water, horn_boost, instant_brake, block_homing, seatbelt, turn_signals, vehicle_jump,
keep_vehicle_repaired, no_water_collision, disable_engine_auto_start, change_engine_state_immediately,
vehinvisibility, localveh_visibility, localped_visibility, keep_on_ground, no_collision, unlimited_weapons)
NLOHMANN_DEFINE_TYPE_INTRUSIVE(vehicle, speedo_meter, fly, rainbow_paint, speed_unit, god_mode, proof_bullet, proof_fire, proof_collision, proof_melee, proof_explosion, proof_steam, proof_water, proof_mask, auto_drive_destination, auto_drive_style, auto_drive_speed, auto_turn_signals, boost_behavior, drive_on_water, horn_boost, instant_brake, block_homing, seatbelt, turn_signals, vehicle_jump, keep_vehicle_repaired, no_water_collision, disable_engine_auto_start, change_engine_state_immediately, vehinvisibility, localveh_visibility, localped_visibility, keep_on_ground, no_collision, unlimited_weapons)
} vehicle{};
struct weapons

View File

@ -6,7 +6,8 @@
namespace big
{
fiber_pool::fiber_pool(std::size_t num_fibers)
fiber_pool::fiber_pool(std::size_t num_fibers) :
m_num_fibers(num_fibers)
{
for (std::size_t i = 0; i < num_fibers; ++i)
{
@ -51,4 +52,22 @@ namespace big
script::get_current()->yield();
}
}
int fiber_pool::get_total_fibers()
{
return m_num_fibers;
}
int fiber_pool::get_used_fibers()
{
return m_jobs.size();
}
void fiber_pool::reset()
{
std::lock_guard lock(m_mutex);
while (!m_jobs.empty())
m_jobs.pop();
}
}

View File

@ -14,9 +14,15 @@ namespace big
void fiber_tick();
static void fiber_func();
int get_total_fibers();
int get_used_fibers();
void reset();
private:
std::recursive_mutex m_mutex;
std::stack<std::function<void()>> m_jobs;
int m_num_fibers;
};
inline fiber_pool* g_fiber_pool{};

View File

@ -21,6 +21,7 @@ namespace rage
class snConnectToPeerTaskResult;
class rlScHandle;
class rlQueryPresenceAttributesContext;
enum class eThreadState : uint32_t;
}
namespace datafile_commands
@ -115,7 +116,7 @@ namespace big::functions
using send_remove_gamer_cmd = void (*)(rage::netConnectionManager* net_connection_mgr, rage::netConnectionPeer* player, int connection_id, rage::snMsgRemoveGamersFromSessionCmd* cmd, int flags);
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 script_vm = rage::eThreadState (*)(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);
@ -133,4 +134,6 @@ namespace big::functions
using get_next_carriage = void* (*)(void* carriage);
using get_entity_attached_to = rage::CDynamicEntity* (*)(rage::CDynamicEntity* entity);
using migrate_object = void (*)(CNetGamePlayer* player, rage::netObject* object, int type);
}

203
src/gta/sound.hpp Normal file
View File

@ -0,0 +1,203 @@
#pragma once
#include "file_manager.hpp"
#include "thread_pool.hpp"
using namespace std::chrono_literals;
// {DCB7EF33-CD8A-4231-8051-66E3F683180B}
static const GUID g_yim_device = {0xdcb7ef33, 0xcd8a, 0x4231, {0x80, 0x51, 0x66, 0xe3, 0xf6, 0x83, 0x18, 0xb}};
class IDirectSoundCaptureBuffer
{
inline int GetActualReadPos()
{
return read_position + (audio_page * 32000);
}
virtual void QueryInterface(){};
virtual int AddRef()
{
return 0;
};
virtual int Release()
{
return 0;
}
virtual HRESULT GetCaps(void* caps)
{
return (HRESULT)0L;// DS_OK
}
virtual HRESULT GetCurrentPosition(int* capture, int* read)
{
if (capture)
*capture = 0;
if (read)
*read = read_position;
return (HRESULT)0L;// DS_OK
}
virtual HRESULT GetFormat(void* out, int length, int* out_length)
{
return (HRESULT)0L;// DS_OK
}
virtual HRESULT GetStatus(int* status)
{
*status = 1; // DSCBSTATUS_CAPTURING
return (HRESULT)0L;// DS_OK
}
virtual HRESULT Initialize(void*, void*)
{
return (HRESULT)0L;// DS_OK
}
virtual HRESULT Lock(DWORD dwOffset, DWORD dwBytes, char** ppvAudioPtr1, LPDWORD pdwAudioBytes1, char** ppvAudioPtr2, LPDWORD pdwAudioBytes2, DWORD dwFlags)
{
if (dwOffset > read_position && audio_page != 0)
{
dwOffset -= 32000;// fix page offset if we have to read back
}
dwOffset += (audio_page * 32000);// add our page offset to get the actual position
// fix artifacts after audio ends
if (dwBytes > 1280)
dwOffset = 0;
if (dwOffset + dwBytes <= audio_size)
{
*ppvAudioPtr1 = &audio_buffer[dwOffset];
*pdwAudioBytes1 = dwBytes;
*ppvAudioPtr2 = NULL;
*pdwAudioBytes2 = 0;
}
else
{
*ppvAudioPtr1 = &audio_buffer[dwOffset];
*pdwAudioBytes1 = audio_size - dwOffset;
*ppvAudioPtr2 = &audio_buffer[0];
*pdwAudioBytes2 = dwBytes - *pdwAudioBytes1;
}
return (HRESULT)0L;// DS_OK
}
virtual HRESULT Start(int flags)
{
if (big::g_file_manager->get_project_file("./audio.wav").exists())
{
std::ifstream wave_stream(big::g_file_manager->get_project_file("./audio.wav").get_path(), std::ios::in | std::ios::binary);
// https://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html
int header_size = 0;
int data_size = 0;
wave_stream.seekg(4, std::ios_base::cur); // RIFF
wave_stream.seekg(4, std::ios_base::cur); // chunk size
wave_stream.seekg(4, std::ios_base::cur); // Wave ID
wave_stream.seekg(4, std::ios_base::cur); // ckID "fmt "
wave_stream.read((char*)&header_size, 4); // cksize "fmt "
wave_stream.seekg(header_size, std::ios_base::cur);// format
wave_stream.seekg(4, std::ios_base::cur); // ckID "data"
wave_stream.read((char*)&data_size, 4); // cksize "data"
audio_buffer = new char[data_size];
memset(audio_buffer, 0, data_size);
audio_size = data_size;
wave_stream.read(audio_buffer, audio_size);
wave_stream.close();
}
else
{
audio_buffer = new char[0xFFFF];
audio_size = 0xFFFF;
}
running = true;
big::g_thread_pool->push([this] {
last_read = std::chrono::high_resolution_clock::now();
while (!big::g_running)
std::this_thread::yield();
while (big::g_running && running)
{
std::this_thread::yield();
// the buffer can only support up to 32000 bytes of data at once, so we have to page it instead
if (std::chrono::high_resolution_clock::now() - last_read >= 1ms)
{
last_read = std::chrono::high_resolution_clock::now();
read_position += ((2 * 16000) / 1000);// F*M*Nc/1000
// reset page idx after audio playback completes
if (GetActualReadPos() > audio_size)
{
read_position = 0;
audio_page = 0;
}
// use next page if we go beyond 32000
if (read_position > 32000)
{
read_position = read_position % 32000;
audio_page++;
}
}
}
});
return (HRESULT)0L;// DS_OK
}
virtual HRESULT Stop()
{
running = false;
delete[] audio_buffer;
return (HRESULT)0L;// DS_OK
}
virtual HRESULT Unlock(LPVOID pvAudioPtr1, DWORD dwAudioBytes1, LPVOID pvAudioPtr2, DWORD dwAudioBytes2)
{
return (HRESULT)0L;// DS_OK
}
char* audio_buffer = nullptr;
int audio_size = 0;
int audio_page = 0;
int read_position = 0;
bool running = false;
std::chrono::high_resolution_clock::time_point last_read = std::chrono::high_resolution_clock::time_point();
};
inline IDirectSoundCaptureBuffer g_direct_sound_capture_buffer{};
class IDirectSoundCapture
{
virtual void QueryInterface(){};
virtual int AddRef()
{
return 0;
};
virtual int Release()
{
return 0;
}
virtual HRESULT CreateSoundBuffer(void* desc, IDirectSoundCaptureBuffer** buffer, void* unknown)
{
*buffer = &g_direct_sound_capture_buffer;
return (HRESULT)0L;// DS_OK
}
// we shouldn't need the rest
};
inline IDirectSoundCapture g_direct_sound_capture{};

View File

@ -11,6 +11,7 @@
#include "script_mgr.hpp"
#include <MinHook.h>
#include <vehicle/CVehicle.hpp>
namespace big
{
@ -113,6 +114,11 @@ namespace big
detour_hook_helper::add<hooks::get_model_info>("GMI", g_pointers->m_get_model_info);
detour_hook_helper::add<hooks::enumerate_audio_devices>("EAD", g_pointers->m_enumerate_audio_devices);
detour_hook_helper::add<hooks::direct_sound_capture_create>("DSCC", g_pointers->m_direct_sound_capture_create);
detour_hook_helper::add<hooks::write_vehicle_proximity_migration_data_node>("WVPMDN", g_pointers->m_write_vehicle_proximity_migration_data_node);
g_hooking = this;
}

View File

@ -27,6 +27,9 @@ class CPlayerCardStats;
class CStatsSerializationContext;
class CPlayerCreationDataNode;
class CPlayerAppearanceDataNode;
class CFoundDevice;
class IDirectSoundCapture;
class CVehicleProximityMigrationDataNode;
namespace rage
{
@ -153,6 +156,11 @@ namespace big
static void write_player_appearance_data_node(rage::netObject* player, CPlayerAppearanceDataNode* node);
static CBaseModelInfo* get_model_info(rage::joaat_t hash, uint32_t* a2);
static int enumerate_audio_devices(CFoundDevice* found_devices, int count, int flags);
static HRESULT direct_sound_capture_create(GUID* guid, IDirectSoundCapture** sound, void* unknown);
static void write_vehicle_proximity_migration_data_node(rage::netObject* veh, CVehicleProximityMigrationDataNode* node);
};
class minhook_keepalive

View File

@ -20,6 +20,7 @@
#include "netsync/nodes/train/CTrainGameStateDataNode.hpp"
#include "netsync/nodes/vehicle/CVehicleCreationDataNode.hpp"
#include "netsync/nodes/vehicle/CVehicleGadgetDataNode.hpp"
#include "netsync/nodes/vehicle/CVehicleProximityMigrationDataNode.hpp"
#include "network/CNetGamePlayer.hpp"
#include "network/netObject.hpp"
#include "util/model_info.hpp"
@ -503,6 +504,21 @@ namespace big
return false;
}
inline bool is_in_vehicle(CPed* ped, CVehicle* vehicle)
{
if (!ped || !vehicle)
return false;
if (ped == vehicle->m_driver)
return true;
for (int i = 0; i < 15; i++)
if (vehicle->m_passengers[i] == ped)
return true;
return false;
}
bool check_node(rage::netSyncNodeBase* node, CNetGamePlayer* sender, rage::netObject* object)
{
if (node->IsParentNode())
@ -604,7 +620,7 @@ namespace big
}
else if (attach_node->m_attached && is_attachment_infinite(get_game_object(object), attach_node->m_attached_to))
{
notify::crash_blocked(sender, "recursive infinite ped attachment");
// notify::crash_blocked(sender, "recursive infinite ped attachment");
return true;
}
@ -650,6 +666,28 @@ namespace big
}
break;
}
case RAGE_JOAAT("CVehicleProximityMigrationDataNode"):
{
if (g_local_player && g_local_player->m_net_object)
{
const auto migration_node = (CVehicleProximityMigrationDataNode*)(node);
if (is_in_vehicle(g_local_player, g_local_player->m_vehicle) && g_local_player->m_vehicle->m_net_object
&& g_local_player->m_vehicle->m_net_object->m_object_id == object->m_object_id)
return false; // vehicle kick?
if (!g_local_player->m_vehicle || !g_local_player->m_vehicle->m_net_object
|| g_local_player->m_vehicle->m_net_object->m_object_id != object->m_object_id
|| !is_in_vehicle(g_local_player, g_local_player->m_vehicle))
{
for (int i = 0; i < 16; i++)
{
if (migration_node->m_has_occupants[i]
&& migration_node->m_occupants[i] == g_local_player->m_net_object->m_object_id)
return true; // remote teleport
}
}
}
}
}
}
return false;

View File

@ -10,7 +10,7 @@ namespace big
g_hooking->get_original<hooks::serialize_take_off_ped_variation_task>()(info, serializer);
if (info->m_prop_hash != 0 && info->m_variation_component == 5 && info->m_prop_hash != RAGE_JOAAT("p_parachute_s"))
{
notify::crash_blocked(g.m_syncing_player, "invalid parachute");
// notify::crash_blocked(g.m_syncing_player, "invalid parachute"); false positives
info->m_prop_hash = 0;
}
}

View File

@ -8,7 +8,8 @@ namespace big
const auto result = g_hooking->get_original<gta_thread_kill>()(thread);
if (g.notifications.gta_thread_kill.log)
LOG(INFO) << "Script Thread '" << thread->m_name << "' terminated.";
LOG(INFO) << "Script Thread '" << thread->m_name << "' terminated (" << thread->m_exit_message << ").";
if (g.notifications.gta_thread_kill.notify)
g_notification_service->push("Script Thread Termination",
std::format("Script Thread '{}' terminated.", thread->m_name));
@ -22,6 +23,9 @@ namespace big
if (thread == g.m_mission_creator_thread)
g.m_mission_creator_thread = nullptr;
if (thread == g.m_modshop_thread)
g.m_modshop_thread = nullptr;
return result;
}
}

View File

@ -30,6 +30,8 @@ namespace big
scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[self::id].CurrentShopIndex = old_shop_index;
scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[self::id].CayoPericoFlags = old_cayo_flags;
}
g.in_script_vm = true;
}
~script_vm_guard()
@ -47,6 +49,8 @@ namespace big
scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[self::id].CayoPericoFlags = 1;
}
}
g.in_script_vm = false;
}
};

View File

@ -0,0 +1,24 @@
#include "gta/net_array.hpp"
#include "hooking.hpp"
#include "script_global.hpp"
#include "script_local.hpp"
#include <netsync/nodes/vehicle/CVehicleProximityMigrationDataNode.hpp>
namespace big
{
void hooks::write_vehicle_proximity_migration_data_node(rage::netObject* veh, CVehicleProximityMigrationDataNode* node)
{
CVehicle* vehicle = *(CVehicle**)(((__int64)veh) - 432);
g_hooking->get_original<hooks::write_vehicle_proximity_migration_data_node>()(veh, node);
if (vehicle->m_net_object->m_object_id = g.m_tp_veh_net_id)
{
node->m_has_occupants[0] = true;
node->m_occupants[0] = g.m_tp_player_net_id;
node->m_override_position = true;
node->m_position = g.m_tp_position;
}
}
}

View File

@ -0,0 +1,18 @@
#include "gta/sound.hpp"
#include "hooking.hpp"
namespace big
{
HRESULT hooks::direct_sound_capture_create(GUID* guid, IDirectSoundCapture** sound, void* unknown)
{
if ((*guid) == g_yim_device && g.spoofing.voice_chat_audio)
{
*sound = &g_direct_sound_capture;
return (HRESULT)0L;// DS_OK
}
else
{
return g_hooking->get_original<hooks::direct_sound_capture_create>()(guid, sound, unknown);
}
}
}

View File

@ -0,0 +1,42 @@
#include "gta/sound.hpp"
#include "hooking.hpp"
class CFoundDevice
{
public:
GUID m_guid;
char16_t m_name[64];
int m_device_type;
int m_default_type;
int m_pad2;
};
static_assert(sizeof(CFoundDevice) == 0x9C);
namespace big
{
int hooks::enumerate_audio_devices(CFoundDevice* found_devices, int count, int flags)
{
auto res = g_hooking->get_original<hooks::enumerate_audio_devices>()(found_devices, count, flags);
if ((flags & 1) && g.spoofing.voice_chat_audio)
{
for (int i = 0; i < count; i++)
{
if (found_devices[i].m_device_type != 2 || found_devices[i].m_default_type != 2)
{
lstrcpyW((LPWSTR)found_devices[i].m_name, L"YimMenu Virtual Input Device");
found_devices[i].m_guid = g_yim_device;
found_devices[i].m_device_type = 1;
found_devices[i].m_default_type = 1;
if (i >= res)
res++;
break;
}
}
}
return res;
}
}

View File

@ -1,5 +1,6 @@
#include "stack_trace.hpp"
#include "gta/script_thread.hpp"
#include "memory/module.hpp"
#include <DbgHelp.h>
@ -26,9 +27,13 @@ namespace big
m_exception_info = exception_info;
m_dump << exception_code_to_string(exception_info->ExceptionRecord->ExceptionCode) << '\n';
if (g.in_script_vm)
dump_script_info();
dump_module_info();
dump_registers();
dump_stacktrace();
m_dump << "\n--------End of exception--------\n";
}
@ -40,12 +45,12 @@ namespace big
// I'd prefer to make some sort of global instance that cache all modules once instead of doing this every time
void stack_trace::dump_module_info()
{
m_dump << "Dumping modules:\n";
// modules cached already
if (m_modules.size())
return;
m_dump << "Dumping modules:\n";
const auto peb = reinterpret_cast<PPEB>(NtCurrentTeb()->ProcessEnvironmentBlock);
if (!peb)
return;
@ -138,6 +143,13 @@ namespace big
}
}
void stack_trace::dump_script_info()
{
m_dump << "Currently executing script: " << rage::scrThread::get()->m_name << '\n';
m_dump << "Thread program counter (could be inaccurate): "
<< m_exception_info->ContextRecord->Rdi - m_exception_info->ContextRecord->Rsi << '\n';
}
void stack_trace::grab_stacktrace()
{
CONTEXT context = *m_exception_info->ContextRecord;

View File

@ -37,6 +37,7 @@ namespace big
void dump_module_info();
void dump_registers();
void dump_stacktrace();
void dump_script_info();
void grab_stacktrace();
const module_info* get_module_by_address(uint64_t addr) const;

View File

@ -125,8 +125,7 @@ namespace big
case ControllerInputs::INPUT_VEH_FLY_BOOST:
case ControllerInputs::INPUT_VEH_PARACHUTE:
case ControllerInputs::INPUT_VEH_BIKE_WINGS:
case ControllerInputs::INPUT_VEH_TRANSFORM:
return;
case ControllerInputs::INPUT_VEH_TRANSFORM: return;
}
}
@ -141,7 +140,7 @@ namespace big
HUD::HUD_FORCE_WEAPON_WHEEL(src->get_arg<BOOL>(0));
}
void NETWORK_CASINO_CAN_BET(rage::scrNativeCallContext* src)
void RETURN_TRUE(rage::scrNativeCallContext* src)
{
src->set_return_value<BOOL>(TRUE);
}

View File

@ -46,6 +46,9 @@ namespace big
case RAGE_JOAAT("MP1_AWD_FMRALLYWONNAV"):
case RAGE_JOAAT("MP1_AWD_FMWINSEARACE"):
case RAGE_JOAAT("MP1_AWD_FMWINAIRRACE"): *out = 1; break;
case RAGE_JOAAT("SP0_TOTAL_CASH"):
case RAGE_JOAAT("SP1_TOTAL_CASH"):
case RAGE_JOAAT("SP2_TOTAL_CASH"): *out = 999999; break;
default: src->set_return_value<BOOL>(STATS::STAT_GET_INT(hash, out, src->get_arg<int>(2))); break;
}
}
@ -73,5 +76,13 @@ namespace big
VEHICLE::SET_VEHICLE_LIGHTS(src->get_arg<Vehicle>(0), src->get_arg<int>(1));
}
}
inline void DISABLE_ALL_CONTROL_ACTIONS(rage::scrNativeCallContext* src)
{
if (!g.vehicle.ls_customs)
{
PAD::DISABLE_ALL_CONTROL_ACTIONS(src->get_arg<int>(0));
}
}
}
}

View File

@ -111,12 +111,14 @@ namespace big
add_native_detour(0xADF692B254977C0C, all_scripts::SET_CURRENT_PED_WEAPON);
add_native_detour(0xFE99B66D079CF6BC, all_scripts::DISABLE_CONTROL_ACTION);
add_native_detour(0xEB354E5376BC81A7, all_scripts::HUD_FORCE_WEAPON_WHEEL);
add_native_detour(0x158C16F5E4CF41F8, all_scripts::NETWORK_CASINO_CAN_BET);//bypass casino country restrictions
add_native_detour(0x158C16F5E4CF41F8, all_scripts::RETURN_TRUE); //bypass casino country restrictions
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);
add_native_detour(RAGE_JOAAT("carmod_shop"), 0x767FBC2AC802EF3D, carmod_shop::STAT_GET_INT);
add_native_detour(RAGE_JOAAT("carmod_shop"), 0x5F4B6931816E599B, carmod_shop::DISABLE_ALL_CONTROL_ACTIONS);
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"), 0xEA1C610A04DB6BBB, freemode::SET_ENTITY_VISIBLE);

View File

@ -711,16 +711,41 @@ namespace big
m_write_player_appearance_data_node = ptr.as<PVOID>();
});
// DC
// Enumerate Audio Devices
main_batch.add("EAD", "48 89 5C 24 08 48 89 7C 24 10 55 48 8B EC 48 83 EC 70 41", [this](memory::handle ptr) {
m_enumerate_audio_devices = ptr.as<PVOID>();
});
// Direct Sound Capture Create
main_batch.add("DSCC", "E8 ? ? ? ? 33 FF 85 C0 78 C1", [this](memory::handle ptr) {
m_direct_sound_capture_create = ptr.add(1).rip().as<PVOID>();
});
// Refresh Audio Input
main_batch.add("RAI", "40 88 3D ? ? ? ? 89 05 ? ? ? ? 40 38 3D", [this](memory::handle ptr) {
m_refresh_audio_input = ptr.add(3).rip().as<bool*>();
});
// Disable Collision
main_batch.add("DC", "48 8B D1 49 8B CA ? ? ? ? ? 48 8B D1 49 8B CA", [this](memory::handle ptr) {
m_disable_collision = memory::byte_patch::make(ptr.sub(2).as<uint8_t*>(), 0xEB).get();
});
// AWIV
// Allow Weapons In Vehicle
main_batch.add("AWIV", "49 3B C9 7C F0 ? ? C3", [this](memory::handle ptr) {
m_allow_weapons_in_vehicle = memory::byte_patch::make(ptr.add(5).as<uint16_t*>(), 0x01B0).get();//In order for the second xref loop not to stop
});
// Write Vehicle Proximity Migration Data Node
main_batch.add("WVPMDN", "48 89 4C 24 08 55 53 56 57 41 54 41 55 41 56 41 57 48 8B EC 48 83 EC 68 4C 8B A9", [this](memory::handle ptr) {
m_write_vehicle_proximity_migration_data_node = ptr.as<PVOID>();
});
// Migrate Object
main_batch.add("MO", "48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 54 41 55 41 56 41 57 48 83 EC 20 41 8B F8 48", [this](memory::handle ptr) {
m_migrate_object = ptr.as<functions::migrate_object>();
});
auto mem_region = memory::module("GTA5.exe");
if (!main_batch.run(mem_region))
{

View File

@ -249,8 +249,15 @@ namespace big
PVOID m_write_player_creation_data_node{};
PVOID m_write_player_appearance_data_node{};
PVOID m_enumerate_audio_devices{};
PVOID m_direct_sound_capture_create{};
bool* m_refresh_audio_input{};
memory::byte_patch* m_disable_collision{};
memory::byte_patch* m_allow_weapons_in_vehicle{};
PVOID m_write_vehicle_proximity_migration_data_node{};
functions::migrate_object m_migrate_object{};
};
inline pointers* g_pointers{};

View File

@ -62,6 +62,45 @@ namespace big
tls_ctx->m_is_script_thread_active = og_thread != nullptr;
}
void script_function::call_latent(rage::scrThread* thread, rage::scrProgram* program, std::initializer_list<std::uint64_t> args, bool& done)
{
g_fiber_pool->queue_job([this, thread, program, args, &done] {
auto stack = (uint64_t*)thread->m_stack;
rage::eThreadState result = rage::eThreadState::idle;
rage::scrThreadContext ctx = thread->m_context;
for (auto& arg : args)
stack[ctx.m_stack_pointer++] = arg;
stack[ctx.m_stack_pointer++] = 0;
ctx.m_instruction_pointer = m_ip;
ctx.m_state = rage::eThreadState::idle;
while (result != rage::eThreadState::killed)
{
auto tls_ctx = rage::tlsContext::get();
auto og_thread = tls_ctx->m_script_thread;
tls_ctx->m_script_thread = thread;
tls_ctx->m_is_script_thread_active = true;
auto old_ctx = thread->m_context;
thread->m_context = ctx;
result = g_pointers->m_script_vm(stack, g_pointers->m_script_globals, program, &thread->m_context);
thread->m_context = old_ctx;
tls_ctx->m_script_thread = og_thread;
tls_ctx->m_is_script_thread_active = og_thread != nullptr;
script::get_current()->yield();
}
done = true;
});
}
void script_function::static_call(std::initializer_list<std::uint64_t> args)
{
populate_ip();

View File

@ -17,6 +17,7 @@ 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);
void call_latent(rage::scrThread* thread, rage::scrProgram* program, std::initializer_list<std::uint64_t> args, bool& done);
// for pure functions that do not need access to thread stack
void static_call(std::initializer_list<std::uint64_t> args);
@ -33,5 +34,8 @@ namespace big
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);
static inline script_function modshop_loop("ML", RAGE_JOAAT("carmod_shop"), "2D 00 07 00 00 71 51", 0);
static inline script_function setup_modshop("SM", RAGE_JOAAT("carmod_shop"), "2D 04 12 00 00 38 00 51", 0);
}
}

View File

@ -141,4 +141,34 @@ namespace big::entity
}
return target_entities;
}
inline bool load_ground_at_3dcoord(Vector3& location)
{
float groundZ;
const uint8_t attempts = 10;
for (uint8_t i = 0; i < attempts; i++)
{
// Only request a collision after the first try failed because the location might already be loaded on first attempt.
for (uint16_t z = 0; i && z < 1000; z += 100)
{
STREAMING::REQUEST_COLLISION_AT_COORD(location.x, location.y, (float)z);
script::get_current()->yield();
}
if (MISC::GET_GROUND_Z_FOR_3D_COORD(location.x, location.y, 1000.f, &groundZ, false, false))
{
location.z = groundZ + 1.f;
return true;
}
script::get_current()->yield();
}
location.z = 1000.f;
return false;
}
}

View File

@ -2,7 +2,9 @@
#include "blip.hpp"
#include "entity.hpp"
#include "gta/enums.hpp"
#include "gta/net_object_mgr.hpp"
#include "services/players/player_service.hpp"
#include "vehicle.hpp"
namespace big::teleport
{
@ -16,12 +18,8 @@ namespace big::teleport
return false;
}
if (!PED::IS_PED_IN_ANY_VEHICLE(ent, true))
if (PED::IS_PED_IN_ANY_VEHICLE(ent, true))
{
g_notification_service->push_warning("TELEPORT"_T.data(), "TELEPORT_PLAYER_IS_NOT_IN_VEHICLE"_T.data());
return false;
}
ent = PED::GET_VEHICLE_PED_IS_IN(ent, false);
if (entity::take_control_of(ent))
@ -31,42 +29,45 @@ namespace big::teleport
return true;
}
else
{
auto hnd = vehicle::spawn(RAGE_JOAAT("ninef"), *player->get_ped()->get_position(), 0.0f, true);
ENTITY::SET_ENTITY_VISIBLE(hnd, false, false);
ENTITY::SET_ENTITY_COLLISION(hnd, false, false);
ENTITY::FREEZE_ENTITY_POSITION(hnd, true);
g.m_tp_position = {coords.x, coords.y, coords.z};
g.m_tp_player_net_id = player->get_ped()->m_net_object->m_object_id;
g.m_tp_veh_net_id = g_pointers->m_handle_to_ptr(hnd)->m_net_object->m_object_id;
if ((player->is_valid() && PED::IS_PED_IN_ANY_VEHICLE(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id()), false))
|| PLAYER::IS_REMOTE_PLAYER_IN_NON_CLONED_VEHICLE(player->id()))
g_pointers->m_clear_ped_tasks_network(player->get_ped(), true);
for (int i = 0; i < 15; i++)
{
script::get_current()->yield(50ms);
if (auto ptr = (rage::CDynamicEntity*)g_pointers->m_handle_to_ptr(hnd))
{
if (auto netobj = ptr->m_net_object)
{
g_pointers->m_migrate_object(player->get_net_game_player(), netobj, 3);
}
}
}
entity::delete_entity(hnd);
return true;
}
}
inline bool bring_player(player_ptr player)
{
return teleport_player_to_coords(player, self::pos);
}
inline bool load_ground_at_3dcoord(Vector3& location)
{
float groundZ;
const uint8_t attempts = 10;
for (uint8_t i = 0; i < attempts; i++)
{
// Only request a collision after the first try failed because the location might already be loaded on first attempt.
for (uint16_t z = 0; i && z < 1000; z += 100)
{
STREAMING::REQUEST_COLLISION_AT_COORD(location.x, location.y, (float)z);
script::get_current()->yield();
}
if (MISC::GET_GROUND_Z_FOR_3D_COORD(location.x, location.y, 1000.f, &groundZ, false, false))
{
location.z = groundZ + 1.f;
return true;
}
script::get_current()->yield();
}
location.z = 1000.f;
return false;
}
inline bool into_vehicle(Vehicle veh)
{
if (!ENTITY::IS_ENTITY_A_VEHICLE(veh))
@ -90,7 +91,7 @@ namespace big::teleport
}
Vector3 location = ENTITY::GET_ENTITY_COORDS(veh, true);
load_ground_at_3dcoord(location);
entity::load_ground_at_3dcoord(location);
Ped ped = self::ped;
@ -116,7 +117,7 @@ namespace big::teleport
return false;
if (sprite == (int)BlipIcons::Waypoint)
load_ground_at_3dcoord(location);
entity::load_ground_at_3dcoord(location);
PED::SET_PED_COORDS_KEEP_VEHICLE(self::ped, location.x, location.y, location.z);

View File

@ -9,7 +9,6 @@
#include "script.hpp"
#include "script_global.hpp"
#include "services/vehicle_helper/vehicle_helper.hpp"
#include "teleport.hpp"
namespace big::vehicle
{
@ -66,7 +65,7 @@ namespace big::vehicle
return g_notification_service->push_error("VEHICLE"_T.data(), "VEHICLE_INVALID"_T.data());
auto vecVehicleLocation = ENTITY::GET_ENTITY_COORDS(veh, true);
teleport::load_ground_at_3dcoord(vecVehicleLocation);
entity::load_ground_at_3dcoord(vecVehicleLocation);
if (!entity::take_control_of(veh))
return g_notification_service->push_warning("VEHICLE"_T.data(), "VEHICLE_FAILED_CONTROL"_T.data());

View File

@ -24,6 +24,7 @@ namespace big
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.69f, 0.29f, 0.29f, 1.00f));
if (components::nav_button("UNLOAD"_T))
{
g_fiber_pool->reset();
g_fiber_pool->queue_job([] {
for (auto& command : g_looped_commands)
if (command->is_enabled())

View File

@ -15,15 +15,13 @@ namespace big
{
if (ImGui::BeginTabItem("DEBUG_TAB_MISC"_T.data()))
{
if (components::button("MOV QWORD"))
{
*static_cast<uint64_t*>(nullptr) = 0;
uint64_t i = *static_cast<uint64_t*>(nullptr);
}
ImGui::Text("Fiber Pool Usage %d/%d", g_fiber_pool->get_used_fibers(), g_fiber_pool->get_total_fibers());
if (components::button("MOV 0xdead"))
ImGui::SameLine();
if (components::button("Reset"))
{
*((unsigned int*)0) = 0xDEAD;
g_fiber_pool->reset();
}
if (components::button("Dump entrypoints"))

View File

@ -11,11 +11,9 @@ namespace big
{
void view::spoofing()
{
// requires translation
ImGui::Checkbox("HIDE_FROM_PLAYER_LIST"_T.data(), &g.spoofing.hide_from_player_list);
ImGui::Checkbox("Hide From Player List", &g.spoofing.hide_from_player_list);
components::script_patch_checkbox("Spoof Blip Type", &g.spoofing.spoof_blip);
components::script_patch_checkbox("SPOOF_BLIP_TYPE"_T, &g.spoofing.spoof_blip);
if (g.spoofing.spoof_blip)
{
ImGui::SameLine();
@ -32,7 +30,7 @@ namespace big
}
}
ImGui::Checkbox("Spoof Rank", &g.spoofing.spoof_rank);
ImGui::Checkbox("SPOOF_RANK"_T.data(), &g.spoofing.spoof_rank);
if (g.spoofing.spoof_rank)
{
ImGui::SameLine();
@ -42,7 +40,7 @@ namespace big
}
}
ImGui::Checkbox("Spoof K/D Ratio", &g.spoofing.spoof_kd_ratio);
ImGui::Checkbox("SPOOF_KD"_T.data(), &g.spoofing.spoof_kd_ratio);
if (g.spoofing.spoof_kd_ratio)
{
ImGui::SameLine();
@ -52,7 +50,7 @@ namespace big
}
}
ImGui::Checkbox("Spoof Badsport State", &g.spoofing.spoof_bad_sport);
ImGui::Checkbox("SPOOF_BADSPORT"_T.data(), &g.spoofing.spoof_bad_sport);
if (g.spoofing.spoof_bad_sport)
{
ImGui::SameLine();
@ -62,14 +60,14 @@ namespace big
}
}
ImGui::Checkbox("Spoof Job Points", &g.spoofing.spoof_job_points);
ImGui::Checkbox("SPOOF_JOB_POINTS"_T.data(), &g.spoofing.spoof_job_points);
if (g.spoofing.spoof_job_points)
{
ImGui::SameLine();
ImGui::InputInt("###jp", &g.spoofing.job_points);
}
ImGui::Checkbox("Spoof Player Model", &g.spoofing.spoof_player_model);
ImGui::Checkbox("SPOOF_PLAYER_MODEL"_T.data(), &g.spoofing.spoof_player_model);
if (g.spoofing.spoof_player_model)
{
static char model[32];
@ -82,6 +80,7 @@ namespace big
g.spoofing.player_model = std::string(model);
}
components::command_checkbox<"vcaudio">();
components::sub_title("SPOOFING_HIDE_FEATURES"_T);
ImGui::Checkbox("SPOOFING_HIDE_GOD_MODE"_T.data(), &g.spoofing.spoof_hide_god);

View File

@ -1,9 +1,9 @@
#include "core/data/command_access_levels.hpp"
#include "core/data/language_codes.hpp"
#include "core/scr_globals.hpp"
#include "natives.hpp"
#include "services/player_database/player_database_service.hpp"
#include "views/view.hpp"
#include "natives.hpp"
#include <script/globals/GPBD_FM.hpp>
#include <script/globals/GPBD_FM_3.hpp>
@ -16,9 +16,9 @@ namespace big
if (ImGui::TreeNode("INFO"_T.data()))
{
components::button("Open SC Overlay", [] {
int gamerHandle;
NETWORK::NETWORK_HANDLE_FROM_PLAYER(g_player_service->get_selected()->id(), &gamerHandle, 13);
NETWORK::NETWORK_SHOW_PROFILE_UI(&gamerHandle);
uint64_t gamerHandle[13];
NETWORK::NETWORK_HANDLE_FROM_PLAYER(g_player_service->get_selected()->id(), (Any*)&gamerHandle, 13);
NETWORK::NETWORK_SHOW_PROFILE_UI((Any*)&gamerHandle);
});
ImGui::Text("PLAYER_INFO_ID"_T.data(), g_player_service->get_selected()->id());

View File

@ -15,9 +15,6 @@ namespace big
components::player_command_button<"breakup">(g_player_service->get_selected());
ImGui::SameLine();
components::command_checkbox<"breakupcheating">();
components::disable_unless(std::not_fn(is_session_host), [] {
components::player_command_button<"lckick">(g_player_service->get_selected());
});
components::player_command_button<"bailkick">(g_player_service->get_selected());
ImGui::SameLine();

View File

@ -1,5 +1,6 @@
#include "script/globals/GPBD_FM_3.hpp"
#include "util/scripts.hpp"
#include "util/vehicle.hpp"
#include "views/view.hpp"
namespace big

View File

@ -3,7 +3,7 @@
#include "script.hpp"
#include "services/vehicle/persist_car_service.hpp"
#include "util/mobile.hpp"
#include "util/vehicle.hpp"
#include "util/teleport.hpp"
#include "views/view.hpp"
namespace big

View File

@ -1,7 +1,7 @@
#include "core/data/speed_units.hpp"
#include "fiber_pool.hpp"
#include "util/mobile.hpp"
#include "util/vehicle.hpp"
#include "util/teleport.hpp"
#include "views/view.hpp"
namespace big