* feat(Commands): Prototype command system
* feat(Commands): Chat commands
* refactor(Toxic): convert most options into commands
* feat(Protections): block breakup kicks on other players as host
* refactor(Kicks): convert most options into commands
* refactor(Commands): add labels and descriptions to all commands
* feat(Commands): cleanup on unload
* refactor(Troll): convert most options into commands
* refactor(Misc): convert most options into commands
* refactor(Teleport): convert most options into commands
* feat(Commands): Variadic commands and toggleable bools
* feat(Hotkeys): hotkeys now use commands
* fix(Chat): fix the chat window locking up when a message is sent
* fix(Commands): properly handle spoofed username
* fix(Spam): update filter

Co-authored-by: Yimura <24669514+Yimura@users.noreply.github.com>
This commit is contained in:
maybegreat48 2022-12-22 21:23:32 +00:00 committed by GitHub
parent 9d9d438b5d
commit ce5c317d87
143 changed files with 3194 additions and 1458 deletions

View File

@ -54,4 +54,4 @@ add_compile_definitions(YimMenu
"_CRT_SECURE_NO_WARNINGS"
"NOMINMAX"
"WIN32_LEAN_AND_MEAN"
)
)

View File

@ -4,11 +4,15 @@
#include "looped/looped.hpp"
#include "services/context_menu/context_menu_service.hpp"
#include "script_patches.hpp"
#include "looped_command.hpp"
namespace big
{
void backend::loop()
{
for (auto& command : g_looped_commands)
command->refresh();
register_script_patches();
while (g_running)
@ -20,6 +24,10 @@ namespace big
looped::system_mission_creator();
looped::system_auto_tp();
for (auto command : g_looped_commands)
if (command->is_enabled())
command->on_tick();
script::get_current()->yield();
}
}
@ -30,20 +38,9 @@ namespace big
while (g_running)
{
looped::self_clean_player();
looped::self_free_cam();
looped::self_godmode();
looped::self_invisibility();
looped::self_no_ragdoll();
looped::self_off_radar();
looped::self_police();
looped::self_super_run();
looped::self_no_collision();
looped::self_hud();
looped::self_unlimited_oxygen();
looped::self_no_water_collision();
looped::self_mobile_radio();
looped::self_fast_respawn();
looped::self_dance_mode();
script::get_current()->yield();
@ -59,17 +56,11 @@ namespace big
looped::weapons_ammo_special_type();
looped::weapons_cage_gun();
looped::weapons_delete_gun();
looped::weapons_force_crosshairs();
looped::weapons_gravity_gun();
looped::weapons_increased_damage();
looped::weapons_infinite_ammo();
looped::weapons_infinite_mag();
looped::weapons_no_recoil();
looped::weapons_no_spread();
looped::weapons_repair_gun();
looped::weapons_steal_vehicle_gun();
looped::weapons_vehicle_gun();
looped::weapons_rapid_fire();
script::get_current()->yield();
}
@ -83,16 +74,8 @@ namespace big
{
looped::vehicle_auto_drive();
looped::vehicle_boost_behavior();
looped::vehicle_drive_on_water();
looped::vehicle_god_mode();
looped::vehicle_horn_boost();
looped::vehicle_jump();
looped::vehicle_instant_brake();
looped::vehicle_is_targetable();
looped::vehicle_seatbelt();
looped::vehicle_speedo_meter();
looped::vehicle_keep_vehicle_repaired();
looped::vehicle_no_water_collision();
script::get_current()->yield();
}
@ -117,7 +100,6 @@ namespace big
while (g_running)
{
looped::hud_transition_state();
looped::tunables_disable_phone();
looped::session_local_time();
looped::session_pop_multiplier_areas();
looped::session_force_thunder();
@ -142,18 +124,6 @@ namespace big
}
}
void backend::noclip_loop()
{
LOG(INFO) << "Starting script: No clip";
while (g_running)
{
looped::self_noclip();
script::get_current()->yield();
}
}
void backend::lscustoms_loop()
{
LOG(INFO) << "Starting script: Ls customs";
@ -196,11 +166,8 @@ namespace big
while (g_running)
{
looped::self_free_cam_disable_control_action();
looped::self_noclip_disable_control_action();
looped::custom_gun_disable_control_action();
context_menu_service::disable_control_action_loop();
script::get_current()->yield();

View File

@ -13,7 +13,6 @@ namespace big
static void turnsignal_loop();
static void misc_loop();
static void remote_loop();
static void noclip_loop();
static void lscustoms_loop();
static void rainbowpaint_loop();
static void vehiclefly_loop();

View File

@ -0,0 +1,62 @@
#include "bool_command.hpp"
namespace big
{
bool_command::bool_command(const std::string& name, const std::string& label, const std::string& description, bool& toggle) :
command(name, label, description, std::nullopt),
m_toggle(toggle)
{
}
void bool_command::execute(const std::vector<std::uint64_t>& args, const std::shared_ptr<command_context> ctx)
{
if (args.size() == 0)
{
if (is_enabled())
{
m_toggle = false;
ctx->report_output(std::format("{} has been disabled", m_label));
}
else
{
m_toggle = true;
ctx->report_output(std::format("{} has been enabled", m_label));
}
}
else
{
m_toggle = args[0];
}
this->refresh();
}
std::optional<std::vector<std::uint64_t>> bool_command::parse_args(const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx)
{
std::vector<std::uint64_t> result;
if (args.size() == 0)
return result;
if (args.size() > 1)
{
ctx->report_error(std::format("Too many arguments passed to command {}, Expected 1 or less, got {}", m_name, args.size()));
return std::nullopt;
}
if (args[0] == "yes" || args[0] == "on" || args[0] == "enable" || args[0] == "true")
{
result.push_back(1);
return result;
}
if (args[0] == "no" || args[0] == "off" || args[0] == "disable" || args[0] == "false")
{
result.push_back(0);
return result;
}
ctx->report_error(std::format("Cannot convert\"{}\" into a boolean in command {}", args[0], m_name));
return std::nullopt;
}
}

View File

@ -0,0 +1,20 @@
#pragma once
#include "command.hpp"
namespace big
{
class bool_command : public command
{
protected:
bool& m_toggle;
virtual void execute(const std::vector<std::uint64_t>& args, const std::shared_ptr<command_context> ctx = std::make_shared<default_command_context>()) override;
virtual std::optional<std::vector<std::uint64_t>> parse_args(const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx = std::make_shared<default_command_context>()) override;
public:
bool_command(const std::string& name, const std::string& label, const std::string& description, bool& toggle);
inline bool& is_enabled() { return m_toggle; }
virtual void refresh() {};
virtual void enable() { m_toggle = true; };
virtual void disable() { m_toggle = false; };
};
}

112
src/backend/command.cpp Normal file
View File

@ -0,0 +1,112 @@
#include "command.hpp"
#include "fiber_pool.hpp"
namespace
{
// https://stackoverflow.com/a/7408245
static std::vector<std::string> split(const std::string& text, char sep)
{
std::vector<std::string> tokens;
std::size_t start = 0, end = 0;
while ((end = text.find(sep, start)) != std::string::npos)
{
if (end != start)
{
tokens.push_back(text.substr(start, end - start));
}
start = end + 1;
}
if (end != start)
{
tokens.push_back(text.substr(start));
}
return tokens;
}
}
namespace big
{
command::command(const std::string& name, const std::string& label, const std::string& description, std::optional<std::uint8_t> num_args, bool fiber_pool) :
m_name(name),
m_label(label),
m_description(description),
m_num_args(num_args),
m_fiber_pool(fiber_pool)
{
g_commands[rage::joaat(name)] = this;
}
void command::call(const std::vector<std::uint64_t>& args, const std::shared_ptr<command_context> ctx)
{
if (m_num_args.has_value() && args.size() != m_num_args.value())
{
ctx->report_error(std::format("Command {} called with the wrong number of arguments. Expected {}, got {}", m_name, m_num_args.value(), args.size()));
return;
}
if (ctx->get_access_level() < get_access_level())
{
ctx->report_error(std::format("You do not have sufficient permissions to call command {}", m_name));
return;
}
if (m_fiber_pool)
g_fiber_pool->queue_job([this, args, ctx] { execute(args, ctx); });
else
execute(args, ctx);
}
void command::call(const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx)
{
if (m_num_args.has_value() && args.size() != m_num_args.value())
{
ctx->report_error(std::format("Command {} called with the wrong number of arguments. Expected {}, got {}", m_name, m_num_args.value(), args.size()));
return;
}
if (ctx->get_access_level() < get_access_level())
{
ctx->report_error(std::format("You do not have sufficient permissions to call command {}", m_name));
return;
}
auto parsed = parse_args(args, ctx);
if (parsed.has_value())
call(parsed.value(), ctx);
}
command* command::get(rage::joaat_t command)
{
return g_commands[command];
}
void command::call(rage::joaat_t command, const std::vector<std::uint64_t>& args, const std::shared_ptr<command_context> ctx)
{
g_commands[command]->call(args, ctx);
}
void command::call(rage::joaat_t command, const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx)
{
g_commands[command]->call(args, ctx);
}
void command::process(const std::string& text, const std::shared_ptr<command_context> ctx)
{
auto args = split(text, ' ');
if (args.size() == 0 || args[0].empty())
{
ctx->report_error("No command to call");
return;
}
std::uint32_t hash = rage::joaat(args[0]);
if (!g_commands.contains(hash))
{
ctx->report_error(std::format("Command {} does not exist", args[0]));
return;
}
args.erase(args.begin());
call(hash, args, ctx);
}
}

39
src/backend/command.hpp Normal file
View File

@ -0,0 +1,39 @@
#pragma once
#include "gta/joaat.hpp"
#include "core/enums.hpp"
#include "context/command_context.hpp"
#include "context/default_command_context.hpp"
namespace big
{
class command
{
protected:
std::string m_name;
std::string m_label;
std::string m_description;
std::optional<std::uint8_t> m_num_args;
bool m_fiber_pool;
virtual void execute(const std::vector<std::uint64_t>& args, const std::shared_ptr<command_context> ctx = std::make_shared<default_command_context>()) = 0;
virtual std::optional<std::vector<std::uint64_t>> parse_args(const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx = std::make_shared<default_command_context>()) { return std::vector<std::uint64_t>(); };
virtual CommandAccessLevel get_access_level() { return CommandAccessLevel::ADMIN; }
public:
command(const std::string& name, const std::string& label, const std::string& description, std::optional<std::uint8_t> num_args, bool fiber_pool = true);
inline const std::string& get_label() { return m_label; }
inline const std::string& get_description() { return m_description; }
void call(const std::vector<std::uint64_t>& args, const std::shared_ptr<command_context> ctx = std::make_shared<default_command_context>());
void call(const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx = std::make_shared<default_command_context>());
static command* get(rage::joaat_t command);
static void call(rage::joaat_t command, const std::vector<std::uint64_t>& args, const std::shared_ptr<command_context> ctx = std::make_shared<default_command_context>());
static void call(rage::joaat_t command, const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx = std::make_shared<default_command_context>());
static void process(const std::string& text, const std::shared_ptr<command_context> ctx = std::make_shared<default_command_context>());
};
inline std::unordered_map<rage::joaat_t, command*> g_commands;
}

View File

@ -0,0 +1,25 @@
#include "backend/command.hpp"
#include "natives.hpp"
namespace big
{
class recovery : command
{
using command::command;
virtual CommandAccessLevel get_access_level() override
{
return CommandAccessLevel::NONE;
}
virtual void execute(const std::vector<std::uint64_t>&, const std::shared_ptr<command_context> ctx)
{
ctx->report_error("Money and recovery options are not supported in YimMenu to keep Rockstar/Take Two happy. You can try Kiddion's Modest Menu (free) instead, but make sure to only get it from UnknownCheats.me, the rest are scams and contain malware");
}
};
recovery g_money("money", "", "", 0);
recovery g_cash("cash", "", "", 0);
recovery g_drop("drop", "", "", 0);
recovery g_stats("stats", "", "", 0);
}

View File

@ -0,0 +1,32 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
namespace big
{
class bail_kick : player_command
{
using player_command::player_command;
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)
{
const size_t arg_count = 3;
int64_t args[arg_count] =
{
(int64_t)eRemoteEvent::NetworkBail,
(int64_t)self::id,
*scr_globals::gpbd_fm_3.at(player->id(), scr_globals::size::gpbd_fm_3).at(510).as<int64_t*>()
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << player->id());
}
};
bail_kick g_bail_kick("bailkick", "Bail Kick", "Blocked by most menus", 0);
}

View File

@ -0,0 +1,39 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
#include "gta_util.hpp"
#include <network/Network.hpp>
namespace big
{
class breakup_kick : player_command
{
using player_command::player_command;
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)
{
rage::snMsgRemoveGamersFromSessionCmd cmd{};
cmd.m_session_id = gta_util::get_network()->m_game_session_ptr->m_rline_session.m_session_id;
cmd.m_num_peers = 1;
cmd.m_peer_ids[0] = player->get_session_peer()->m_peer_data.m_peer_id_2;
g_pointers->m_handle_remove_gamer_cmd(gta_util::get_network()->m_game_session_ptr, player->get_session_player(), &cmd);
for (auto& [_, plyr] : g_player_service->players())
{
if (plyr->id() != player->id())
g_pointers->m_send_remove_gamer_cmd(gta_util::get_network()->m_game_session_ptr->m_net_connection_mgr,
g_pointers->m_get_connection_peer(gta_util::get_network()->m_game_session_ptr->m_net_connection_mgr, (int)plyr->get_session_player()->m_player_data.m_peer_id_2),
gta_util::get_network()->m_game_session_ptr->m_connection_identifier, &cmd, 0x1000000);
}
}
};
breakup_kick g_breakup_kick("breakup", "Breakup Kick", "Nearly unblockable but could be detected by others", 0, false);
}

View File

@ -0,0 +1,33 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
#include "gta_util.hpp"
#include <network/Network.hpp>
namespace big
{
class complaint_kick : player_command
{
using player_command::player_command;
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())
{
gta_util::get_network()->m_game_complaint_mgr.raise_complaint(player->get_net_data()->m_host_token);
return;
}
g_player_service->m_player_to_use_complaint_kick = player;
}
};
complaint_kick g_complaint_kick("desync", "Desync Kick", "This may take around 10 seconds to kick the player. Does not work against the host", 0); // this is pretty much desync except we don't actually remove the player from CNetworkPlayerMgr
}

View File

@ -0,0 +1,32 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
#include "util/scripts.hpp"
namespace big
{
class end_session_kick : player_command
{
using player_command::player_command;
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 (!scripts::force_host(RAGE_JOAAT("freemode")))
{
g_notification_service->push_error("Kick", "Force script host failed!");
return;
}
g_player_service->m_player_to_use_end_session_kick = player;
*scr_globals::gsbd.as<int*>() = (int)(__rdtsc() % 50000) + 6; // making the game trigger the broadcast is a bit difficult and requires a little bit of tampering with the value and luck
}
};
end_session_kick g_end_session_kick("endkick", "End Session Kick", "This may take around 10 seconds to kick the player", 0, false);
}

View File

@ -0,0 +1,38 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
#include "gta_util.hpp"
#include <network/Network.hpp>
namespace big
{
class host_kick : player_command
{
using player_command::player_command;
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 (!g_player_service->get_self()->is_host())
{
g_notification_service->push_error("Kick", "You have to be the session host");
return;
}
rage::snMsgRemoveGamersFromSessionCmd cmd{};
cmd.m_session_id = gta_util::get_network()->m_game_session_ptr->m_rline_session.m_session_id;
cmd.m_num_peers = 1;
cmd.m_peer_ids[0] = player->get_session_peer()->m_peer_data.m_peer_id_2;
g_pointers->m_handle_remove_gamer_cmd(gta_util::get_network()->m_game_session_ptr, player->get_session_player(), &cmd);
}
};
host_kick g_host_kick("hostkick", "Host Kick", "Unblockable and undetectable, but requires session host", 0, false);
}

View File

@ -0,0 +1,55 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
#include "packet.hpp"
#include "gta_util.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>(*reinterpret_cast<uint8_t*>(reinterpret_cast<__int64>(&hnd) + 9), 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((*(rage::rlGamerHandle*)(&player->get_net_data()->m_gamer_handle_2.m_rockstar_id)), 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

@ -0,0 +1,32 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
namespace big
{
class null_function_kick : player_command
{
using player_command::player_command;
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)
{
const size_t arg_count = 15;
int64_t args[arg_count] =
{
(int64_t)eRemoteEvent::InteriorControl,
(int64_t)self::id,
(int64_t)(int)-1
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << player->id());
}
};
null_function_kick g_null_function_kick("nfkick", "Null Function Kick", "It may take around 15 seconds for the player to actually leave the session", 0);
}

View File

@ -0,0 +1,48 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
#include "util/scripts.hpp"
#include "packet.hpp"
namespace big
{
class oom_kick : player_command
{
using player_command::player_command;
std::chrono::system_clock::time_point last_oom_kick_time{};
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 (std::chrono::system_clock::now() - last_oom_kick_time < 7s)
{
g_notification_service->push_error("Kick", "Don't spam this or it will backfire");
return;
}
last_oom_kick_time = std::chrono::system_clock::now();
if (auto freemode = gta_util::find_script_thread(RAGE_JOAAT("freemode")))
{
packet msg{};
msg.write_message(rage::eNetMessage::MsgScriptMigrateHost);
freemode->m_handler->get_id()->serialize(&msg.m_buffer);
msg.write<int>(0, 16);
msg.write<int>(0, 32);
auto msg_id = player->get_net_game_player()->m_msg_id;
for (int j = 0; j < 2100; j++)
{
msg.send(msg_id);
}
}
}
};
oom_kick g_oom_kick("oomkick", "OOM Kick", "Causes the player to be kicked with an alert. This kick has a high chance of backfiring in its current state", 0, false);
}

View File

@ -0,0 +1,31 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
#include "util/scripts.hpp"
namespace big
{
class script_host_kick : player_command
{
using player_command::player_command;
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 (!scripts::force_host(RAGE_JOAAT("freemode")))
{
g_notification_service->push_error("Kick", "Force script host failed!");
return;
}
*scr_globals::gsbd_kicking.at(player->id(), 1).as<bool*>() = true;
}
};
script_host_kick g_script_host_kick("shkick", "Script Host Kick", "Blocked by most menus", 0, false);
}

View File

@ -0,0 +1,24 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "util/globals.hpp"
namespace big
{
class clear_wanted_level : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::FRIENDLY;
}
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
globals::clear_wanted_player(player->id());
}
};
clear_wanted_level g_clear_wanted_level("clearwanted", "Clear Wanted Level", "Clears the player's wanted level", 0);
}

View File

@ -0,0 +1,42 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
#include "util/misc.hpp"
namespace big
{
class enter_interior : player_command
{
using player_command::player_command;
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
if (*scr_globals::globalplayer_bd.at(player->id(), scr_globals::size::globalplayer_bd).at(318).at(6).as<int*>() == -1)
{
g_notification_service->push_error("Enter Interior", "Player does not seem to be in an interior");
return;
}
int owner = *scr_globals::globalplayer_bd.at(player->id(), scr_globals::size::globalplayer_bd).at(318).at(9).as<int*>();
if (owner == -1)
owner = player->id();
*script_global(1950108).at(3684).as<int*>() = 0;
*script_global(1950108).at(3682).as<int*>() = 1;
*script_global(1950108).at(4780).as<int*>() = 1;
*script_global(1950108).at(3218).as<int*>() = 1; // this doesnt exists at all?
*script_global(1950108).at(3214).as<int*>() = 1; // ^
*script_global(1950108).at(3689).as<int*>() = 1;
// misc::set_bit(script_global(1950108).at(1).as<int*>(), 22);
misc::set_bit(script_global(1950108).as<int*>(), 6);
misc::clear_bit(script_global(1950108).at(1).as<int*>(), 9);
*script_global(1950108).at(3346).as<int*>() = owner;
*script_global(1950108).at(3683).as<int*>() = *scr_globals::globalplayer_bd.at(player->id(), scr_globals::size::globalplayer_bd).at(318).at(6).as<int*>();
}
};
enter_interior g_enter_interior("enterint", "Enter Interior", "Enters the player's interior", 0, false);
}

View File

@ -0,0 +1,25 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "util/globals.hpp"
#include "services/pickups/pickup_service.hpp"
namespace big
{
class give_ammo : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::FRIENDLY;
}
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
g_pickup_service->give_player_health(player->id());
}
};
give_ammo g_give_ammo("giveammo", "Give Ammo", "Gives the player some ammo", 0);
}

View File

@ -0,0 +1,25 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "util/globals.hpp"
#include "services/pickups/pickup_service.hpp"
namespace big
{
class give_armor : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::FRIENDLY;
}
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
g_pickup_service->give_player_health(player->id());
}
};
give_armor g_give_armor("givearmor", "Give Armor", "Gives the player some armor", 0);
}

View File

@ -0,0 +1,25 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "util/globals.hpp"
#include "services/pickups/pickup_service.hpp"
namespace big
{
class give_health : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::FRIENDLY;
}
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
g_pickup_service->give_player_health(player->id());
}
};
give_health g_give_health("givehealth", "Give Health", "Gives the player some health", 0);
}

View File

@ -0,0 +1,20 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
#include "script_function.hpp"
namespace big
{
class join_ceo : player_command
{
using player_command::player_command;
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
scr_functions::join_ceo({ player->id(), 0, false, false });
}
};
join_ceo g_join_ceo("joinceo", "Join CEO/MC", "Joins the player's CEO/MC", 0, false);
}

View File

@ -0,0 +1,21 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "util/ped.hpp"
namespace big
{
class steal_identity : player_command
{
using player_command::player_command;
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
ped::steal_identity(
PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id())
);
}
};
steal_identity g_steal_identity("copymodel", "Steal Identity", "Copies the player's model to your ped", 0, false); // do we really need this?
}

View File

@ -0,0 +1,21 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "util/ped.hpp"
namespace big
{
class steal_outfit : player_command
{
using player_command::player_command;
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
ped::steal_outfit(
PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id())
);
}
};
steal_outfit g_steal_outfit("copyoutfit", "Steal Outfit", "Copies the player's outfit to your ped", 0, false);
}

View File

@ -0,0 +1,43 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
namespace big
{
class ceo_kick : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
auto leader = *scr_globals::gpbd_fm_3.at(player->id(), scr_globals::size::gpbd_fm_3).at(10).as<int*>();
if (leader == -1)
return;
else if (leader == player->id())
{
return;
}
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 << player->id());
}
}
};
ceo_kick g_ceo_kick("ceokick", "CEO Kick", "Kicks an associate from the CEO/MC. You cannot kick leaders of CEOs/MCs anymore", 0);
}

View File

@ -0,0 +1,46 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "services/gta_data/gta_data_service.hpp"
#include "script.hpp"
namespace big
{
class give_all_weapons : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::FRIENDLY;
}
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
for (auto& weapon : g_gta_data_service->weapons())
WEAPON::GIVE_WEAPON_TO_PED(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id()), weapon.second.m_hash, 9999, FALSE, FALSE);
}
};
class give_all_weapons_all : command
{
using command::command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::FRIENDLY;
}
virtual void execute(const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
g_player_service->iterate([](auto& plyr) {
for (auto& weapon : g_gta_data_service->weapons())
WEAPON::GIVE_WEAPON_TO_PED(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(plyr.second->id()), weapon.second.m_hash, 9999, FALSE, FALSE);
script::get_current()->yield(500ms);
});
}
};
give_all_weapons g_give_all_weapons("giveweaps", "Give Weapons", "Gives all weapons to the player", 0, false);
give_all_weapons_all g_give_all_weapons_all("giveweapsall", "Give Weapons", "Gives weapons to everyone. Don't spam this or you will crash", 0);
}

View File

@ -0,0 +1,33 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "gta/net_object_mgr.hpp"
#include "core/scr_globals.hpp"
namespace big
{
class kick_from_interior : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
const size_t arg_count = 8;
int64_t args[arg_count]{
(int64_t)eRemoteEvent::KickFromInterior,
(int64_t)self::id,
*scr_globals::globalplayer_bd.at(player->id(), scr_globals::size::globalplayer_bd).at(321).at(6).as<int64_t*>(),
*scr_globals::globalplayer_bd.at(player->id(), scr_globals::size::globalplayer_bd).at(321).at(7).as<int64_t*>(),
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << player->id());
}
};
kick_from_interior g_kick_from_interior("intkick", "Kick From Interior", "Kicks the player from the interior they are in", 0);
}

View File

@ -0,0 +1,41 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "gta/net_object_mgr.hpp"
namespace big
{
class kick_from_vehicle : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
auto vehicle = player->get_current_vehicle();
if (!vehicle || !vehicle->m_net_object)
{
// vehicle hasn't synced yet, use TSE
const size_t arg_count = 9;
int64_t args[arg_count] = {
(int64_t)eRemoteEvent::VehicleKick,
self::id, 0, 0, 0, 0, 0, 0, 0
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << player->id());
}
else
{
// use a private method to kick player from vehicle
(*g_pointers->m_network_object_mgr)->ChangeOwner(vehicle->m_net_object, g_player_service->get_self()->get_net_game_player(), 0);
}
}
};
kick_from_vehicle g_kick_from_vehicle("vehkick", "Vehicle Kick", "Kicks the player from their current vehicle", 0);
}

View File

@ -0,0 +1,27 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
namespace big
{
class kill_player : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
if (!player->get_ped())
return;
g_pointers->m_send_network_damage((CEntity*)g_player_service->get_self()->get_ped(), (CEntity*)player->get_ped(), player->get_ped()->m_navigation->get_position(),
0, true, RAGE_JOAAT("weapon_explosion"), 10000.0f, 2, 0, (1 << 4), 0, 0, 0, false, false, true, true, nullptr);
}
};
kill_player g_kill_player("kill", "Kill Player", "Kills the player, bypassing most forms of interior godmode", 0);
}

View File

@ -0,0 +1,25 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
namespace big
{
class ragdoll_player : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
if (auto ped = player->get_ped())
if (auto net_object = ped->m_net_object)
g_pointers->m_request_ragdoll(net_object->m_object_id);
}
};
ragdoll_player g_ragdoll_player("ragdoll", "Ragdoll Player", "Ragdolls the player", 0);
}

View File

@ -0,0 +1,24 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
namespace big
{
class remove_all_weapons : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
// TODO: Doesn't actually do anything
WEAPON::REMOVE_ALL_PED_WEAPONS(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id()), FALSE);
}
};
remove_all_weapons g_remove_all_weapons("remweaps", "Remove All Weapons", "Remove all weapons from the player", 0);
}

View File

@ -0,0 +1,37 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
namespace big
{
class send_to_apartment : player_command
{
using player_command::player_command;
virtual std::optional<std::vector<std::uint64_t>> parse_args_p(const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx)
{
return std::vector<std::uint64_t>{ (uint64_t)std::atoi(args[0].c_str()) };
}
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
const size_t arg_count = 9;
int64_t args[arg_count] = {
(int64_t)eRemoteEvent::Teleport,
self::id,
(int64_t)player->id(),
(int64_t)(int)-1, 1, (int64_t)_args[0], 1, 1, 1
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << player->id());
}
};
send_to_apartment g_send_to_apartment("apartmenttp", "TP To Apartment", "Teleports the player to the specified apartment index", 1);
}

View File

@ -0,0 +1,50 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
namespace big
{
class send_to_interior : player_command
{
using player_command::player_command;
virtual std::optional<std::vector<std::uint64_t>> parse_args_p(const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx)
{
return std::vector<std::uint64_t>{ (uint64_t)std::atoi(args[0].c_str()) };
}
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
float max = 1e+38f;
auto coords = ENTITY::GET_ENTITY_COORDS(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id()), FALSE);
const size_t arg_count = 15;
int64_t args[arg_count] =
{
(int64_t)eRemoteEvent::InteriorControl,
(int64_t)self::id,
(int64_t)(int)_args[0],
(int64_t)self::id,
(int64_t)false,
(int64_t)true, // true means enter sender interior
(int64_t) * (uint32_t*)&coords.x,
(int64_t) * (uint32_t*)&coords.y,
(int64_t) * (uint32_t*)&coords.z,
0,
0,
1,
(int64_t) * (uint32_t*)&max,
(int64_t)true,
-1
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << player->id());
}
};
send_to_interior g_send_to_interior("interiortp", "TP To Interior", "Teleports the player to the specified interior index", 1);
}

View File

@ -0,0 +1,30 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
namespace big
{
class send_to_island : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
const size_t arg_count = 2;
int64_t args[arg_count] = {
(int64_t)eRemoteEvent::SendToCayoPerico,
(int64_t)self::id,
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << player->id());
}
};
send_to_island g_send_to_island("cayotp", "TP To Cayo Perico", "Teleports the player to Cayo Perico", 0);
}

View File

@ -0,0 +1,38 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
namespace big
{
class send_to_warehouse : player_command
{
using player_command::player_command;
virtual std::optional<std::vector<std::uint64_t>> parse_args_p(const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx)
{
return std::vector<std::uint64_t>{ (uint64_t)std::atoi(args[0].c_str()) };
}
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
const size_t arg_count = 6;
int64_t args[arg_count] = {
(int64_t)eRemoteEvent::TeleportToWarehouse,
self::id,
(int64_t)player->id(),
1,
(int64_t)_args[0]
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << player->id());
}
};
send_to_warehouse g_send_to_warehouse("warehousetp", "TP To Warehouse", "Teleports the player to the specified warehouse index", 1);
}

View File

@ -0,0 +1,67 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
#include "util/globals.hpp"
#include "script.hpp"
namespace big
{
class set_wanted_level : player_command
{
using player_command::player_command;
virtual std::optional<std::vector<std::uint64_t>> parse_args_p(const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx)
{
uint64_t level = std::atoi(args[0].c_str());
if (level < 0 || level > 5)
{
ctx->report_error(std::format("Wanted level {} is invalid", level));
return std::nullopt;
}
return std::vector<std::uint64_t>{ level };
}
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
if (player->id() == self::id)
{
PLAYER::SET_PLAYER_WANTED_LEVEL(self::id, _args[0], FALSE);
}
else
{
int id = player->id();
if (PLAYER::GET_PLAYER_WANTED_LEVEL(id) > _args[0])
{
// clear existing wanted
globals::clear_wanted_player(id);
for (int i = 0; PLAYER::GET_PLAYER_WANTED_LEVEL(id) > _args[0] && i < 3600; i++)
script::get_current()->yield(1ms);
}
if (_args[0] > 0)
{
*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*>() = _args[0];
for (int i = 0; PLAYER::GET_PLAYER_WANTED_LEVEL(id) < _args[0] && i < 3600; i++)
script::get_current()->yield(1ms);
*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;
}
}
}
};
set_wanted_level g_set_wanted_level("wanted", "Set Wanted Level", "Sets the specified wanted level to the player", 1, false);
}

View File

@ -0,0 +1,152 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
#include "util/scripts.hpp"
namespace big
{
class turn_into_beast : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
auto id = player->id();
if (!NETWORK::NETWORK_IS_PLAYER_A_PARTICIPANT_ON_SCRIPT(id, "am_hunt_the_beast", -1))
{
if (!NETWORK::NETWORK_IS_PLAYER_A_PARTICIPANT_ON_SCRIPT(id, "am_launcher", -1))
{
g_notification_service->push_error("Turn to Beast", "Cannot start the Hunt the Beast event, player not a participant of am_launcher");
return;
}
g_notification_service->push("Turn to Beast", "Starting Hunt The Beast event. Please wait...");
scripts::start_launcher_script(47);
for (int i = 0; !NETWORK::NETWORK_IS_PLAYER_A_PARTICIPANT_ON_SCRIPT(id, "am_hunt_the_beast", -1); i++)
{
if (i >= 1000)
{
g_notification_service->push_error("Turn to Beast", "Failed to start the Hunt The Beast event");
return;
}
script::get_current()->yield(1ms);
}
}
if (!NETWORK::NETWORK_IS_PLAYER_CONNECTED(id))
return;
if (!scripts::force_host(RAGE_JOAAT("am_hunt_the_beast")))
{
g_notification_service->push_error("Turn to Beast", "Failed to take control of am_hunt_the_beast");
return;
}
auto thread = gta_util::find_script_thread(RAGE_JOAAT("am_hunt_the_beast"));
auto stack = thread->m_stack;
auto net_component = thread->m_net_component;
auto idx = scr_locals::am_hunt_the_beast::broadcast_idx;
if (!stack || !net_component || !player->is_valid())
return;
*script_local(stack, idx).as<int*>() = 1;
*script_local(stack, idx).at(1).as<int*>() = 2; // stage
*script_local(stack, idx).at(1).at(6).as<int*>() = net_component->get_participant_index(player->get_net_game_player()); // beast participant idx
*script_local(stack, idx).at(1).at(7).as<Player*>() = id; // beast player idx
*script_local(stack, idx).at(1).at(2).as<int*>() = INT_MAX; // stopwatch time
*script_local(stack, idx).at(1).at(2).at(1).as<bool*>() = true; // stopwatch initialized
*script_local(stack, idx).at(1).at(4).at(1).as<bool*>() = false; // destroy old stage 1 stopwatch
*script_local(stack, idx).at(1).at(9).as<int*>() = 2; // some distance check
*script_local(stack, idx).at(83).as<int*>() = 0; // transformed bitset
}
};
class turn_into_beast_all : command
{
using command::command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
virtual void execute(const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
scripts::start_launcher_script(47);
for (int i = 0; !scripts::is_running(RAGE_JOAAT("am_launcher")); i++)
{
if (i >= 7000)
{
g_notification_service->push_error("Turn to Beast", "Failed to start the Hunt The Beast event");
return;
}
script::get_current()->yield(1ms);
}
script::get_current()->yield(500ms);
if (!scripts::force_host(RAGE_JOAAT("am_hunt_the_beast")))
{
g_notification_service->push_error("Turn to Beast", "Failed to take control of am_hunt_the_beast");
return;
}
script::get_current()->yield(3s);
auto thread = gta_util::find_script_thread(RAGE_JOAAT("am_hunt_the_beast"));
if (!thread)
return;
auto stack = thread->m_stack;
auto net_component = thread->m_net_component;
auto idx = scr_locals::am_hunt_the_beast::broadcast_idx;
if (!stack || !net_component)
return;
thread->m_net_component->block_host_migration(true);
thread->m_context.m_state = rage::eThreadState::unk_3;
g.m_hunt_the_beast_thread = thread;
for (int i = 0; i < 15; i++)
{
*script_local(stack, idx).as<int*>() = 1;
*script_local(stack, idx).at(1).as<int*>() = 2; // stage
*script_local(stack, idx).at(1).at(6).as<int*>() = __rdtsc(); // participant idx
*script_local(stack, idx).at(1).at(7).as<Player*>() = __rdtsc(); // beast player idx
*script_local(stack, idx).at(1).at(2).as<int*>() = INT_MAX; // stopwatch time
*script_local(stack, idx).at(1).at(2).at(1).as<bool*>() = true; // stopwatch initialized
*script_local(stack, idx).at(1).at(4).at(1).as<bool*>() = false; // destroy old stage 1 stopwatch
*script_local(stack, idx).at(1).at(9).as<int*>() = 2; // some distance check
*script_local(stack, idx).at(83).as<int*>() = 0; // transformed bitset
script::get_current()->yield(350ms);
}
// unfortunately we must also turn ourselves into the beast to prevent the script from exiting due to a "missing player"
*script_local(stack, idx).at(1).at(6).as<int*>() = net_component->m_local_participant_index; // participant idx
*script_local(stack, idx).at(1).at(7).as<Player*>() = self::id; // beast player idx
*script_local(stack, idx).at(1).at(2).as<int*>() = INT_MAX; // stopwatch time
*script_local(stack, idx).at(83).as<int*>() = 0; // transformed bitset
thread->m_context.m_state = rage::eThreadState::running;
}
};
turn_into_beast g_turn_into_beast("beast", "Turn Into Beast", "Turns the player into the beast", 0, false);
turn_into_beast_all g_turn_into_beast_all("beastall", "Turn Everyone Into Beast", "Turns everyone into the beast, including you", 0);
}

View File

@ -0,0 +1,19 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "util/teleport.hpp"
namespace big
{
class bring : player_command
{
using player_command::player_command;
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
teleport::bring_player(player);
}
};
bring g_bring("bring", "Bring", "Teleports the player to you if they are in a vehicle", 0);
}

View File

@ -0,0 +1,30 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "util/vehicle.hpp"
namespace big
{
class remote_control_vehicle : player_command
{
using player_command::player_command;
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
Vehicle veh = PED::GET_VEHICLE_PED_IS_IN(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id()), FALSE);
if (veh == 0)
{
if (g.player.spectating)
g_notification_service->push_warning("Remote Control", "Player not in a vehicle");
else
g_notification_service->push_warning("Remote Control", "Player not in a vehicle, try spectating the player");
return;
}
vehicle::remote_control_vehicle(veh);
g.player.spectating = false;
}
};
remote_control_vehicle g_remote_control_vehicle("rcplayer", "Remote Control Vehicle", "Take control of the player's vehicle. Spectate the player beforehand for best results", 0, false);
}

View File

@ -0,0 +1,19 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "util/teleport.hpp"
namespace big
{
class teleport_to_player : player_command
{
using player_command::player_command;
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
teleport::to_player(player->id());
}
};
teleport_to_player g_teleport_to_player("playertp", "Teleport", "Teleports you to the player", 0, false);
}

View File

@ -0,0 +1,21 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "util/teleport.hpp"
namespace big
{
class teleport_into_vehicle : player_command
{
using player_command::player_command;
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
Vehicle veh = PED::GET_VEHICLE_PED_IS_IN(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(g_player_service->get_selected()->id()), false);
teleport::into_vehicle(veh);
}
};
teleport_into_vehicle g_teleport_into_vehicle("playervehtp", "Teleport Into Vehicle", "Take control of the player's vehicle. Spectate the player beforehand for best results", 0, false);
}

View File

@ -0,0 +1,18 @@
#include "backend/command.hpp"
#include "natives.hpp"
#include "util/entity.hpp"
namespace big
{
class clean_player : command
{
using command::command;
virtual void execute(const std::vector<std::uint64_t>&, const std::shared_ptr<command_context> ctx)
{
entity::clean_ped(self::ped);
}
};
clean_player g_clean_player("clean", "Clean Player", "Cleans the player of wetness and decals", 0);
}

View File

@ -0,0 +1,26 @@
#include "backend/command.hpp"
#include "natives.hpp"
#include "util/local_player.hpp"
namespace big
{
class fill_inventory : command
{
using command::command;
virtual void execute(const std::vector<std::uint64_t>&, const std::shared_ptr<command_context> ctx)
{
std::string mpPrefix = local_player::get_mp_prefix();
STATS::STAT_SET_INT(rage::joaat(mpPrefix + "NO_BOUGHT_YUM_SNACKS"), 30, true);
STATS::STAT_SET_INT(rage::joaat(mpPrefix + "NO_BOUGHT_HEALTH_SNACKS"), 15, true);
STATS::STAT_SET_INT(rage::joaat(mpPrefix + "NO_BOUGHT_EPIC_SNACKS"), 5, true);
STATS::STAT_SET_INT(rage::joaat(mpPrefix + "MP_CHAR_ARMOUR_1_COUNT"), 10, true);
STATS::STAT_SET_INT(rage::joaat(mpPrefix + "MP_CHAR_ARMOUR_2_COUNT"), 10, true);
STATS::STAT_SET_INT(rage::joaat(mpPrefix + "MP_CHAR_ARMOUR_3_COUNT"), 10, true);
STATS::STAT_SET_INT(rage::joaat(mpPrefix + "MP_CHAR_ARMOUR_4_COUNT"), 10, true);
STATS::STAT_SET_INT(rage::joaat(mpPrefix + "MP_CHAR_ARMOUR_5_COUNT"), 10, true);
}
};
fill_inventory g_fill_inventory("fillsnacks", "Fill Inventory", "Refills snacks and armor", 0);
}

View File

@ -0,0 +1,18 @@
#include "backend/command.hpp"
#include "natives.hpp"
namespace big
{
class heal : command
{
using command::command;
virtual void execute(const std::vector<std::uint64_t>&, const std::shared_ptr<command_context> ctx)
{
ENTITY::SET_ENTITY_HEALTH(self::ped, PED::GET_PED_MAX_HEALTH(self::ped), 0);
PED::SET_PED_ARMOUR(self::ped, PLAYER::GET_PLAYER_MAX_ARMOUR(self::id));
}
};
heal g_heal("heal", "Heal", "Restores full health and armor", 0);
}

View File

@ -0,0 +1,17 @@
#include "backend/command.hpp"
#include "natives.hpp"
namespace big
{
class skip_cutscene : command
{
using command::command;
virtual void execute(const std::vector<std::uint64_t>&, const std::shared_ptr<command_context> ctx)
{
CUTSCENE::STOP_CUTSCENE_IMMEDIATELY();
}
};
skip_cutscene g_skip_cutscene("skipcutscene", "Skip Cutscene", "Skips the currently playing cutscene", 0);
}

View File

@ -0,0 +1,17 @@
#include "backend/command.hpp"
#include "natives.hpp"
namespace big
{
class suicide : command
{
using command::command;
virtual void execute(const std::vector<std::uint64_t>&, const std::shared_ptr<command_context> ctx)
{
ENTITY::SET_ENTITY_HEALTH(self::ped, 0, 0);
}
};
suicide g_suicide("suicide", "Suicide", "Kills you", 0);
}

View File

@ -0,0 +1,59 @@
#include "backend/command.hpp"
#include "backend/bool_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "util/vehicle.hpp"
namespace big
{
class spawn_vehicle : command
{
using command::command;
virtual std::optional<std::vector<std::uint64_t>> parse_args(const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx)
{
auto hash = rage::joaat(args[0]);
return std::vector<std::uint64_t>{ hash };
}
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::FRIENDLY;
}
virtual void execute(const std::vector<std::uint64_t>& args, const std::shared_ptr<command_context> ctx)
{
if (!STREAMING::IS_MODEL_IN_CDIMAGE(args[0]) || !STREAMING::IS_MODEL_A_VEHICLE(args[0]))
{
ctx->report_error("Specified model is invalid");
return;
}
const auto spawn_location = vehicle::get_spawn_location(ctx->get_sender()->id() == self::id ? g.spawn_vehicle.spawn_inside : false, PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(ctx->get_sender()->id()));
const auto spawn_heading = ENTITY::GET_ENTITY_HEADING(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(ctx->get_sender()->id()));
const auto veh = vehicle::spawn(args[0], spawn_location, spawn_heading);
if (veh == 0)
{
g_notification_service->push_error("Vehicle", "Unable to spawn vehicle");
}
else
{
if (g.spawn_vehicle.spawn_maxed)
{
vehicle::max_vehicle(veh);
}
if (g.spawn_vehicle.spawn_inside && ctx->get_sender()->id() == self::id)
{
vehicle::teleport_into_vehicle(veh);
}
}
}
};
spawn_vehicle g_spawn_vehicle("spawn", "Spawn Vehicle", "Spawn a vehicle with the specified model", 1);
bool_command g_spawn_maxed("spawnmaxed", "Spawn Maxed", "Controls whether the vehicle spawned will have its mods maxed out", g.spawn_vehicle.spawn_maxed);
bool_command g_spawn_inside("spawnin", "Spawn Inside", "Controls whether the player should be set inside the vehicle after it spawns", g.spawn_vehicle.spawn_inside);
}

View File

@ -0,0 +1,20 @@
#include "backend/command.hpp"
#include "natives.hpp"
#include "util/vehicle.hpp"
#include "util/mobile.hpp"
namespace big
{
class bring_personal_vehicle : command
{
using command::command;
virtual void execute(const std::vector<std::uint64_t>&, const std::shared_ptr<command_context> ctx)
{
Vehicle veh = mobile::mechanic::get_personal_vehicle();
vehicle::bring(veh, self::pos);
}
};
bring_personal_vehicle g_bring_personal_vehicle("bringpv", "Bring Personal Vehicle", "Teleports your PV near you", 0);
}

View File

@ -0,0 +1,23 @@
#include "backend/command.hpp"
#include "natives.hpp"
#include "util/vehicle.hpp"
#include "util/mobile.hpp"
namespace big
{
class teleport_to_last_vehicle : command
{
using command::command;
virtual void execute(const std::vector<std::uint64_t>&, const std::shared_ptr<command_context> ctx)
{
if (g_local_player && g_local_player->m_vehicle)
{
const Vehicle veh = g_pointers->m_ptr_to_handle(g_local_player->m_vehicle);
teleport::into_vehicle(veh);
}
}
};
teleport_to_last_vehicle g_teleport_to_last_vehicle("lastvehtp", "Teleport To Last Vehicle", "Teleports you into your last driven vehicle", 0);
}

View File

@ -0,0 +1,18 @@
#include "backend/command.hpp"
#include "natives.hpp"
#include "util/teleport.hpp"
namespace big
{
class teleport_to_objective : command
{
using command::command;
virtual void execute(const std::vector<std::uint64_t>&, const std::shared_ptr<command_context> ctx)
{
teleport::to_objective();
}
};
teleport_to_objective g_teleport_to_objective("objectivetp", "Teleport To Objective", "Teleports you to your mission objective", 0);
}

View File

@ -0,0 +1,23 @@
#include "backend/command.hpp"
#include "natives.hpp"
#include "util/vehicle.hpp"
#include "util/mobile.hpp"
namespace big
{
class teleport_to_personal_vehicle : command
{
using command::command;
virtual void execute(const std::vector<std::uint64_t>&, const std::shared_ptr<command_context> ctx)
{
if (g_local_player && g_local_player->m_vehicle)
{
Vehicle veh = mobile::mechanic::get_personal_vehicle();
teleport::into_vehicle(veh);
}
}
};
teleport_to_personal_vehicle g_teleport_to_personal_vehicle("pvtp", "Teleport To Personal Vehicle", "Teleports you into your PV", 0);
}

View File

@ -0,0 +1,18 @@
#include "backend/command.hpp"
#include "natives.hpp"
#include "util/teleport.hpp"
namespace big
{
class teleport_to_waypoint : command
{
using command::command;
virtual void execute(const std::vector<std::uint64_t>&, const std::shared_ptr<command_context> ctx)
{
teleport::to_waypoint();
}
};
teleport_to_waypoint g_teleport_to_waypoint("waypointtp", "Teleport To Waypoint", "Teleports you to your waypoint", 0);
}

View File

@ -0,0 +1,43 @@
#include "chat_command_context.hpp"
#include "util/notify.hpp"
#include "hooking.hpp"
namespace big
{
chat_command_context::chat_command_context(player_ptr player) :
m_player(player)
{
}
player_ptr chat_command_context::get_sender() const
{
return m_player;
}
CommandAccessLevel chat_command_context::get_access_level() const
{
if (!m_player->is_valid())
return CommandAccessLevel::NONE;
return m_player->command_access_level.value_or(g.session.chat_command_default_access_level);
}
void chat_command_context::report_output(const std::string& output) const
{
g_fiber_pool->queue_job([this, output]
{
char msg[265]{};
msg[0] = g.session.chat_output_prefix;
msg[1] = ' ';
strncpy(msg + 2, output.c_str(), sizeof(msg) - 2);
if (g_hooking->get_original<hooks::send_chat_message>()(*g_pointers->m_send_chat_ptr, g_player_service->get_self()->get_net_data(), msg, false))
notify::draw_chat(msg, g_player_service->get_self()->get_name(), false);
});
}
void chat_command_context::report_error(const std::string& error) const
{
report_output(error);
}
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "command_context.hpp"
namespace big
{
class chat_command_context : public command_context
{
player_ptr m_player;
public:
virtual player_ptr get_sender() const override;
virtual CommandAccessLevel get_access_level() const override;
virtual void report_output(const std::string& output) const override;
virtual void report_error(const std::string& error) const override;
chat_command_context(player_ptr player);
};
}

View File

@ -0,0 +1,15 @@
#pragma once
#include "services/players/player_service.hpp"
#include "core/enums.hpp"
namespace big
{
class command_context
{
public:
virtual player_ptr get_sender() const = 0;
virtual CommandAccessLevel get_access_level() const = 0;
virtual void report_output(const std::string& output) const = 0;
virtual void report_error(const std::string& error) const = 0;
};
}

View File

@ -0,0 +1,24 @@
#include "default_command_context.hpp"
namespace big
{
player_ptr default_command_context::get_sender() const
{
return g_player_service->get_self();
}
CommandAccessLevel default_command_context::get_access_level() const
{
return CommandAccessLevel::ADMIN;
}
void default_command_context::report_output(const std::string& output) const
{
g_notification_service->push("Command", output);
}
void default_command_context::report_error(const std::string& error) const
{
g_notification_service->push_error("Command", error);
}
}

View File

@ -0,0 +1,15 @@
#pragma once
#include "command_context.hpp"
namespace big
{
class default_command_context : public command_context
{
public:
virtual player_ptr get_sender() const override;
virtual CommandAccessLevel get_access_level() const override;
virtual void report_output(const std::string& output) const override;
virtual void report_error(const std::string& error) const override;
default_command_context() {};
};
}

View File

@ -0,0 +1,32 @@
#include "int_command.hpp"
namespace big
{
int_command::int_command(const std::string& name, const std::string& label, const std::string& description, int& value, int lower_bound, int upper_bound) :
command(name, label, description, 1),
m_value(value),
m_lower_bound(lower_bound),
m_upper_bound(upper_bound)
{
}
void int_command::execute(const std::vector<std::uint64_t>& args, const std::shared_ptr<command_context> ctx)
{
m_value = args[0];
}
std::optional<std::vector<std::uint64_t>> int_command::parse_args(const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx)
{
std::vector<std::uint64_t> result;
int value = std::atoi(args[0].c_str());
if (value < m_lower_bound || value > m_upper_bound)
{
ctx->report_error(std::format("Value {} is not between {} and {} in command {}", value, m_lower_bound, m_upper_bound, m_name));
return std::nullopt;
}
result.push_back(value);
return result;
}
}

View File

@ -0,0 +1,19 @@
#pragma once
#include "command.hpp"
namespace big
{
class int_command : command
{
protected:
int& m_value;
int m_lower_bound;
int m_upper_bound;
virtual void execute(const std::vector<std::uint64_t>& args, const std::shared_ptr<command_context> ctx = std::make_shared<default_command_context>()) override;
virtual std::optional<std::vector<std::uint64_t>> parse_args(const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx = std::make_shared<default_command_context>()) override;
public:
int_command(const std::string& name, const std::string& label, const std::string& description, int& value, int lower_bound, int upper_bound);
inline int& get_value() { return m_value; }
};
}

View File

@ -2,8 +2,8 @@
#include "natives.hpp"
#include "script_global.hpp"
#include "gta/joaat.hpp"
#include "util/kick.hpp"
#include "services/players/player_service.hpp"
#include "core/scr_globals.hpp"
// Credits: QuickNET
namespace big

View File

@ -10,30 +10,14 @@ namespace big
public:
static void hud_transition_state();
static void tunables_disable_phone();
static void player_good_options();
static void player_spectate();
static void player_remote_control_vehicle();
static void self_clean_player();
static void self_free_cam_disable_control_action();
static void self_free_cam();
static void self_godmode();
static void self_invisibility();
static void self_noclip_disable_control_action();
static void self_noclip();
static void self_no_ragdoll();
static void self_off_radar();
static void self_police();
static void self_super_run();
static void self_no_collision();
static void self_hud();
static void self_unlimited_oxygen();
static void self_no_water_collision();
static void self_mobile_radio();
static void self_dance_mode();
static void self_fast_respawn();
static void session_local_time();
static void session_pop_multiplier_areas();
@ -50,35 +34,21 @@ namespace big
static void vehicle_auto_drive();
static void vehicle_boost_behavior();
static void vehicle_drive_on_water();
static void vehicle_fly();
static void vehicle_god_mode();
static void vehicle_horn_boost();
static void vehicle_jump();
static void vehicle_instant_brake();
static void vehicle_is_targetable();
static void vehicle_ls_customs();
static void vehicle_rainbow_paint();
static void vehicle_seatbelt();
static void vehicle_speedo_meter();
static void vehicle_turn_signals();
static void vehicle_keep_vehicle_repaired();
static void vehicle_no_water_collision();
static void weapons_ammo_special_type();
static void weapons_cage_gun();
static void custom_gun_disable_control_action();
static void weapons_delete_gun();
static void weapons_force_crosshairs();
static void weapons_gravity_gun();
static void weapons_increased_damage();
static void weapons_infinite_ammo();
static void weapons_infinite_mag();
static void weapons_no_recoil();
static void weapons_no_spread();
static void weapons_repair_gun();
static void weapons_steal_vehicle_gun();
static void weapons_vehicle_gun();
static void weapons_rapid_fire();
};
}

View File

@ -1,13 +1,18 @@
#include "backend/looped/looped.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
#include "util/entity.hpp"
namespace big
{
void looped::self_clean_player()
class clean_player_looped : looped_command
{
if (g.self.clean_player) {
using looped_command::looped_command;
virtual void on_tick() override
{
entity::clean_ped(self::ped);
}
}
}
};
clean_player_looped g_clean_player_looped("cleanloop", "Keep Player Clean", "Prevents wetness and decals from being applied on you", g.self.clean_player);
}

View File

@ -1,17 +1,26 @@
#include "backend/looped/looped.hpp"
#include "fiber_pool.hpp"
#include "gta/enums.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
namespace big
{
void looped::self_fast_respawn()
{
if (g.self.fast_respawn)
{
if(PED::IS_PED_DEAD_OR_DYING(self::ped, true))
{
PED::RESURRECT_PED(self::ped);
ENTITY::SET_ENTITY_COORDS_NO_OFFSET(self::ped, self::pos.x, self::pos.y, self::pos.z, 0, 0, 0);
}
}
}
}
class fast_respawn : looped_command
{
using looped_command::looped_command;
virtual void on_tick() override
{
if (PED::IS_PED_DEAD_OR_DYING(self::ped, true))
{
PED::RESURRECT_PED(self::ped);
ENTITY::SET_ENTITY_COORDS_NO_OFFSET(self::ped, self::pos.x, self::pos.y, self::pos.z, 0, 0, 0);
TASK::CLEAR_PED_TASKS_IMMEDIATELY(self::ped);
MISC::FORCE_GAME_STATE_PLAYING();
}
}
};
fast_respawn g_fast_respawn("fastrespawn", "Instant Respawn", "Makes you respawn instantly when you die", g.self.fast_respawn);
}

View File

@ -1,20 +1,12 @@
#include "backend/looped/looped.hpp"
#include "fiber_pool.hpp"
#include "gta/enums.hpp"
#include "natives.hpp"
#include "util/globals.hpp"
#include "backend/looped_command.hpp"
#include "util/math.hpp"
namespace big
{
static bool bLastFreeCam = false;
static float speed = 0.5f;
static float mult = 0.f;
static Cam cCam = -1;
static Vector3 vecPosition;
static Vector3 vecRot;
static const ControllerInputs controls[] =
{
ControllerInputs::INPUT_LOOK_LR,
@ -29,96 +21,91 @@ namespace big
ControllerInputs::INPUT_LOOK_DOWN
};
void looped::self_free_cam_disable_control_action()
class free_cam : looped_command
{
if (g_local_player == nullptr) return;
using looped_command::looped_command;
if (g.self.free_cam)
float speed = 0.5f;
float mult = 0.f;
Cam camera = -1;
Vector3 position;
Vector3 rotation;
virtual void on_enable() override
{
camera = CAM::CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", 0);
position = CAM::GET_GAMEPLAY_CAM_COORD();
rotation = CAM::GET_GAMEPLAY_CAM_ROT(2);
ENTITY::FREEZE_ENTITY_POSITION(self::veh, true);
CAM::SET_CAM_COORD(camera, position.x, position.y, position.z);
CAM::SET_CAM_ROT(camera, rotation.x, rotation.y, rotation.z, 2);
CAM::SET_CAM_ACTIVE(camera, true);
CAM::RENDER_SCRIPT_CAMS(true, true, 500, true, true, 0);
}
virtual void on_tick() override
{
PAD::DISABLE_ALL_CONTROL_ACTIONS(0);
for (const auto& control : controls)
PAD::ENABLE_CONTROL_ACTION(0, static_cast<int>(control), true);
Vector3 vecChange = { 0.f, 0.f, 0.f };
// Left Shift
if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_SPRINT))
vecChange.z += speed / 2;
// Left Control
if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_DUCK))
vecChange.z -= speed / 2;
// Forward
if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_MOVE_UP_ONLY))
vecChange.y += speed;
// Backward
if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_MOVE_DOWN_ONLY))
vecChange.y -= speed;
// Left
if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_MOVE_LEFT_ONLY))
vecChange.x -= speed;
// Right
if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_MOVE_RIGHT_ONLY))
vecChange.x += speed;
if (vecChange.x == 0.f && vecChange.y == 0.f && vecChange.z == 0.f)
mult = 0.f;
else if (mult < 10)
mult += 0.15f;
Vector3 rot = CAM::GET_CAM_ROT(camera, 2);
//float pitch = math::deg_to_rad(rot.x); // vertical
//float roll = rot.y;
float yaw = math::deg_to_rad(rot.z); // horizontal
position.x += (vecChange.x * cos(yaw) - vecChange.y * sin(yaw)) * mult;
position.y += (vecChange.x * sin(yaw) + vecChange.y * cos(yaw)) * mult;
position.z += vecChange.z * mult;
CAM::SET_CAM_COORD(camera, position.x, position.y, position.z);
STREAMING::SET_FOCUS_POS_AND_VEL(position.x, position.y, position.z, 0.f, 0.f, 0.f);
rotation = CAM::GET_GAMEPLAY_CAM_ROT(2);
CAM::SET_CAM_ROT(camera, rotation.x, rotation.y, rotation.z, 2);
}
}
void looped::self_free_cam()
{
if (g_local_player == nullptr) return;
const auto vehicle = self::veh;
const auto ped = self::ped;
if (!g.self.free_cam && !bLastFreeCam) return;
if (g.self.free_cam && !bLastFreeCam)
virtual void on_disable() override
{
cCam = CAM::CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", 0);
vecPosition = CAM::GET_GAMEPLAY_CAM_COORD();
vecRot = CAM::GET_GAMEPLAY_CAM_ROT(2);
ENTITY::FREEZE_ENTITY_POSITION(vehicle, true);
CAM::SET_CAM_COORD(cCam, vecPosition.x, vecPosition.y, vecPosition.z);
CAM::SET_CAM_ROT(cCam, vecRot.x, vecRot.y, vecRot.z, 2);
CAM::SET_CAM_ACTIVE(cCam, true);
CAM::RENDER_SCRIPT_CAMS(true, true, 500, true, true, 0);
bLastFreeCam = true;
}
else if (!g.self.free_cam && bLastFreeCam)
{
CAM::SET_CAM_ACTIVE(cCam, false);
CAM::SET_CAM_ACTIVE(camera, false);
CAM::RENDER_SCRIPT_CAMS(false, true, 500, true, true, 0);
CAM::DESTROY_CAM(cCam, false);
STREAMING::SET_FOCUS_ENTITY(ped);
CAM::DESTROY_CAM(camera, false);
STREAMING::CLEAR_FOCUS();
ENTITY::FREEZE_ENTITY_POSITION(vehicle, false);
bLastFreeCam = false;
return;
ENTITY::FREEZE_ENTITY_POSITION(camera, false);
}
};
Vector3 vecChange = { 0.f, 0.f, 0.f };
// Left Shift
if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_SPRINT))
vecChange.z += speed / 2;
// Left Control
if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_DUCK))
vecChange.z -= speed / 2;
// Forward
if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_MOVE_UP_ONLY))
vecChange.y += speed;
// Backward
if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_MOVE_DOWN_ONLY))
vecChange.y -= speed;
// Left
if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_MOVE_LEFT_ONLY))
vecChange.x -= speed;
// Right
if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_MOVE_RIGHT_ONLY))
vecChange.x += speed;
if (vecChange.x == 0.f && vecChange.y == 0.f && vecChange.z == 0.f)
mult = 0.f;
else if (mult < 10)
mult += 0.15f;
Vector3 rot = CAM::GET_CAM_ROT(cCam, 2);
//float pitch = math::deg_to_rad(rot.x); // vertical
//float roll = rot.y;
float yaw = math::deg_to_rad(rot.z); // horizontal
vecPosition.x += (vecChange.x * cos(yaw) - vecChange.y * sin(yaw)) * mult;
vecPosition.y += (vecChange.x * sin(yaw) + vecChange.y * cos(yaw)) * mult;
vecPosition.z += vecChange.z * mult;
CAM::SET_CAM_COORD(cCam, vecPosition.x, vecPosition.y, vecPosition.z);
STREAMING::SET_FOCUS_POS_AND_VEL(vecPosition.x, vecPosition.y, vecPosition.z, 0.f, 0.f, 0.f);
vecRot = CAM::GET_GAMEPLAY_CAM_ROT(2);
CAM::SET_CAM_ROT(cCam, vecRot.x, vecRot.y, vecRot.z, 2);
}
}
free_cam g_free_cam("freecam", "Freecam", "Allows you to move your camera freely?", g.self.free_cam);
}

View File

@ -1,36 +1,27 @@
#include "backend/looped/looped.hpp"
#include "fiber_pool.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
namespace big
{
static bool bLastInvisibility = false;
void looped::self_invisibility()
class invisibility : looped_command
{
Ped ped = self::ped;
using looped_command::looped_command;
bool bInvisibility = g.self.invisibility;
if (bInvisibility || (!bInvisibility && bInvisibility != bLastInvisibility))
{
ENTITY::SET_ENTITY_VISIBLE(ped, !g.self.invisibility, 0);
bLastInvisibility = g.self.invisibility;
}
if (NETWORK::NETWORK_IS_SESSION_STARTED())
{
if (g.self.invisibility && g.self.local_visibility)
{
NETWORK::SET_ENTITY_LOCALLY_VISIBLE(ped);
}
}
else
virtual void on_tick() override
{
ENTITY::SET_ENTITY_VISIBLE(self::ped, false, 0);
if (g.self.local_visibility)
{
ENTITY::SET_ENTITY_VISIBLE(ped, true, 0);
}
NETWORK::SET_ENTITY_LOCALLY_VISIBLE(self::ped);
}
}
virtual void on_disable() override
{
ENTITY::SET_ENTITY_VISIBLE(self::ped, true, 0);
}
};
invisibility g_invisibility("invis", "Invisiblity", "Makes you invisible", g.self.invisibility);
bool_command g_local_visibility("localvis", "Visible Locally", "Makes you visible to yourself, other players will still not be able to see you", g.self.local_visibility);
}

View File

@ -1,25 +1,24 @@
#include "backend/looped/looped.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
namespace big
{
static bool bLastMobileRadio = false;
void looped::self_mobile_radio()
class mobile_radio : looped_command
{
const bool bMobileRadio = g.self.mobile_radio;
using looped_command::looped_command;
if (bMobileRadio)
virtual void on_tick() override
{
AUDIO::SET_MOBILE_PHONE_RADIO_STATE(true);
AUDIO::SET_MOBILE_RADIO_ENABLED_DURING_GAMEPLAY(true);
}
else if (bMobileRadio != bLastMobileRadio)
virtual void on_disable() override
{
AUDIO::SET_MOBILE_PHONE_RADIO_STATE(false);
AUDIO::SET_MOBILE_RADIO_ENABLED_DURING_GAMEPLAY(false);
}
};
bLastMobileRadio = bMobileRadio;
}
mobile_radio g_mobile_radio("mobileradio", "Mobile Radio", "Allows you to listen to the radio on foot", g.self.mobile_radio);
}

View File

@ -1,26 +1,28 @@
#include "backend/looped/looped.hpp"
#include "base/phArchetype.hpp"
#include "base/phBoundComposite.hpp"
#include "fiber_pool.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
#include <base/phArchetype.hpp>
#include <base/phBoundComposite.hpp>
namespace big
{
static bool bLastNoCollsion = false;
void looped::self_no_collision()
class no_collision : looped_command
{
if (g_local_player == nullptr) return;
using looped_command::looped_command;
bool bNoCollsion = g.self.no_collision;
virtual void on_tick() override
{
if (g_local_player)
((rage::phBoundComposite*)g_local_player->m_navigation->m_damp->m_bound)->m_bounds[0]->m_bounding_box_max_xyz_margin_w.w = -1;
}
if (bNoCollsion)
virtual void on_disable() override
{
((rage::phBoundComposite*)g_local_player->m_navigation->m_damp->m_bound)->m_bounds[0]->m_bounding_box_max_xyz_margin_w.w = -1;
bLastNoCollsion = bNoCollsion;
if (g_local_player)
((rage::phBoundComposite*)g_local_player->m_navigation->m_damp->m_bound)->m_bounds[0]->m_bounding_box_max_xyz_margin_w.w = 0.25;
}
else if (bNoCollsion != bLastNoCollsion)
{
((rage::phBoundComposite*)g_local_player->m_navigation->m_damp->m_bound)->m_bounds[0]->m_bounding_box_max_xyz_margin_w.w = 0.25;
bLastNoCollsion = bNoCollsion;
}
}
};
no_collision g_no_collision("nocollision", "No Collision", "Allows you to walk through vehicles and most obstacles", g.self.no_collision);
}

View File

@ -1,19 +1,24 @@
#include "backend/looped/looped.hpp"
#include "fiber_pool.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
namespace big
{
static bool bLastNoRagdoll = false;
void looped::self_no_ragdoll()
class no_ragdoll : looped_command
{
bool bNoRagdoll = g.self.no_ragdoll;
using looped_command::looped_command;
if (bNoRagdoll || (!bNoRagdoll && bNoRagdoll != bLastNoRagdoll))
virtual void on_tick() override
{
PED::SET_PED_CAN_RAGDOLL(self::ped, !g.self.no_ragdoll);
bLastNoRagdoll = g.self.no_ragdoll;
PED::SET_PED_CAN_RAGDOLL(self::ped, false);
}
}
virtual void on_disable() override
{
PED::SET_PED_CAN_RAGDOLL(self::ped, true);
}
};
no_ragdoll g_no_ragdoll("noragdoll", "No Ragdoll", "Prevents you from ragdolling", g.self.no_ragdoll);
}

View File

@ -1,24 +1,26 @@
#include "backend/looped/looped.hpp"
#include "fiber_pool.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
namespace big
{
static bool bLastSelfNoWaterCollsion = false;
void looped::self_no_water_collision()
class no_water_collision : looped_command
{
if (g_local_player == nullptr) return;
using looped_command::looped_command;
bool bNoWaterCollsion = g.self.no_water_collision;
virtual void on_tick() override
{
if (g_local_player)
g_local_player->m_navigation->m_damp->m_water_collision = 0;
}
if (bNoWaterCollsion)
virtual void on_disable() override
{
g_local_player->m_navigation->m_damp->m_water_collision = 0;
bLastSelfNoWaterCollsion = bNoWaterCollsion;
if (g_local_player)
g_local_player->m_navigation->m_damp->m_water_collision = 1;
}
else if (bNoWaterCollsion != bLastSelfNoWaterCollsion)
{
g_local_player->m_navigation->m_damp->m_water_collision = 1;
bLastSelfNoWaterCollsion = bNoWaterCollsion;
}
}
}
};
no_water_collision g_no_water_collision("walkunder", "Walk Underwater", "Allows you to walk and shoot underwater", g.self.no_water_collision);
}

View File

@ -3,10 +3,11 @@
#include "gta/enums.hpp"
#include "natives.hpp"
#include "util/entity.hpp"
#include "backend/looped_command.hpp"
namespace big
{
static const ControllerInputs controls[] =
static constexpr ControllerInputs controls[] =
{
ControllerInputs::INPUT_SPRINT,
ControllerInputs::INPUT_MOVE_UP_ONLY,
@ -16,41 +17,32 @@ namespace big
ControllerInputs::INPUT_DUCK
};
static float speed = 20.f;
static float mult = 0.f;
static constexpr float speed = 20.f;
static bool bLastNoclip = false;
static Entity prev = -1;
static Vector3 rot{};
void looped::self_noclip_disable_control_action()
class noclip : looped_command
{
if (g.self.noclip)
using looped_command::looped_command;
Entity m_entity;
float m_speed_multiplier;
virtual void on_tick() override
{
for (const auto& control : controls)
PAD::DISABLE_CONTROL_ACTION(0, static_cast<int>(control), true);
}
}
void looped::self_noclip()
{
const auto bNoclip = g.self.noclip;
const auto location = self::pos;
const Entity ent = (self::veh != 0 && g_local_player->m_ped_task_flag & (int)ePedTask::TASK_DRIVING) ? self::veh : self::ped;
const auto location = self::pos;
const Entity ent = (self::veh != 0 && g_local_player->m_ped_task_flag & (int)ePedTask::TASK_DRIVING) ? self::veh : self::ped;
// cleanup when changing entities
if (m_entity != ent)
{
ENTITY::FREEZE_ENTITY_POSITION(m_entity, false);
ENTITY::SET_ENTITY_COLLISION(m_entity, true, true);
// cleanup when changing entities
if (prev != ent)
{
ENTITY::FREEZE_ENTITY_POSITION(prev, false);
ENTITY::SET_ENTITY_COLLISION(prev, true, true);
m_entity = ent;
}
prev = ent;
}
if (bNoclip)
{
Vector3 vel = { 0.f, 0.f, 0.f };
// Left Shift
@ -72,20 +64,19 @@ namespace big
if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_MOVE_RIGHT_ONLY))
vel.x += speed;
rot = CAM::GET_GAMEPLAY_CAM_ROT(2);
auto rot = CAM::GET_GAMEPLAY_CAM_ROT(2);
ENTITY::SET_ENTITY_ROTATION(ent, 0.f, rot.y, rot.z, 2, 0);
ENTITY::SET_ENTITY_COLLISION(ent, false, false);
if (vel.x == 0.f && vel.y == 0.f && vel.z == 0.f)
{
// freeze entity to prevent drifting when standing still
ENTITY::FREEZE_ENTITY_POSITION(ent, true);
mult = 0.f;
m_speed_multiplier = 0.f;
}
else
{
if (mult < 20.f)
mult += 0.15f;
if (m_speed_multiplier < 20.f)
m_speed_multiplier += 0.15f;
ENTITY::FREEZE_ENTITY_POSITION(ent, false);
@ -93,18 +84,19 @@ namespace big
vel.x = offset.x - location.x;
vel.y = offset.y - location.y;
ENTITY::SET_ENTITY_VELOCITY(ent, vel.x * mult, vel.y * mult, vel.z * mult);
}
}
else if (bNoclip != bLastNoclip)
{
if (entity::take_control_of(ent))
{
ENTITY::FREEZE_ENTITY_POSITION(ent, false);
ENTITY::SET_ENTITY_COLLISION(ent, true, false);
ENTITY::SET_ENTITY_VELOCITY(ent, vel.x * m_speed_multiplier, vel.y * m_speed_multiplier, vel.z * m_speed_multiplier);
}
}
bLastNoclip = bNoclip;
}
virtual void on_disable() override
{
if (entity::take_control_of(m_entity))
{
ENTITY::FREEZE_ENTITY_POSITION(m_entity, false);
ENTITY::SET_ENTITY_COLLISION(m_entity, true, false);
}
}
};
noclip g_noclip("noclip", "No Clip", "Allows you to fly through the map", g.self.noclip);
}

View File

@ -1,11 +1,24 @@
#include "backend/looped/looped.hpp"
#include "util/mobile.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
#include "core/scr_globals.hpp"
namespace big
{
void looped::self_off_radar()
class off_radar : looped_command
{
if (g.self.off_radar)
mobile::lester::off_radar(g.self.off_radar);
}
}
using looped_command::looped_command;
virtual void on_tick() override
{
*scr_globals::globalplayer_bd.at(PLAYER::GET_PLAYER_INDEX(), scr_globals::size::globalplayer_bd).at(210).as<int*>() = true;
*script_global(2672505).at(56).as<int*>() = NETWORK::GET_NETWORK_TIME() + 1;
}
virtual void on_disable() override
{
*scr_globals::globalplayer_bd.at(PLAYER::GET_PLAYER_INDEX(), scr_globals::size::globalplayer_bd).at(210).as<int*>() = false;
}
};
off_radar g_off_radar("otr", "Off Radar", "Hides your blip from other players", g.self.off_radar);
}

View File

@ -1,53 +1,65 @@
#include "backend/looped/looped.hpp"
#include "gta/enums.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
#include "util/math.hpp"
namespace big
{
static float run_speed = 10.f;
static float run_cap = 100.f;
static bool super_run_state = false;
void looped::self_super_run()
class super_run : looped_command
{
if (g.self.super_run && PAD::IS_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_SPRINT))
using looped_command::looped_command;
const float run_cap = 100.f;
float run_speed = 10.f;
virtual void on_tick() override
{
if (run_speed < run_cap) run_speed += .5f;
if (g_local_player)
{
if (PAD::IS_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_SPRINT))
{
if (run_speed < run_cap)
run_speed += .5f;
Vector3 location = self::pos;
Ped ped = self::ped;
Vector3 location = self::pos;
Ped ped = self::ped;
//Vector3 rot = CAM::GET_GAMEPLAY_CAM_ROT(2);
Vector3 rot = ENTITY::GET_ENTITY_ROTATION(ped, 2);
float yaw = math::deg_to_rad(rot.z + 90);
Vector3 rot = ENTITY::GET_ENTITY_ROTATION(ped, 2);
float yaw = math::deg_to_rad(rot.z + 90);
Vector3 offset;
offset.x = location.x + (run_speed * cos(yaw));
offset.y = location.y + (run_speed * sin(yaw));
offset.z = location.z + .2f;
Vector3 offset;
offset.x = location.x + (run_speed * cos(yaw));
offset.y = location.y + (run_speed * sin(yaw));
offset.z = location.z + .2f;
float groundZ;
MISC::GET_GROUND_Z_FOR_3D_COORD(offset.x, offset.y, 1000.f, &groundZ, false, false);
if (groundZ < location.z)
offset.z = groundZ;
float groundZ;
MISC::GET_GROUND_Z_FOR_3D_COORD(offset.x, offset.y, 1000.f, &groundZ, false, false);
if (groundZ < location.z)
offset.z = groundZ;
Vector3 vel = offset - location;
Vector3 vel = offset - location;
ENTITY::SET_ENTITY_VELOCITY(ped, vel.x, vel.y, vel.z);
ENTITY::SET_ENTITY_VELOCITY(ped, vel.x, vel.y, vel.z);
g_local_player->m_player_info->m_run_speed = .7f;
}
else if (!g.self.super_run && g.self.super_run != super_run_state)
{
g_local_player->m_player_info->m_run_speed = 1.f;
}
else if (PAD::IS_CONTROL_JUST_RELEASED(0, (int)ControllerInputs::INPUT_SPRINT))
{
run_speed = 10.f;
g_local_player->m_player_info->m_run_speed = 1.f;
g_local_player->m_player_info->m_run_speed = .7f;
}
else if (PAD::IS_CONTROL_JUST_RELEASED(0, (int)ControllerInputs::INPUT_SPRINT))
{
run_speed = 10.f;
g_local_player->m_player_info->m_run_speed = 1.f;
}
}
}
super_run_state = g.self.super_run;
}
}
virtual void on_disable() override
{
if (g_local_player)
{
run_speed = 10.f;
g_local_player->m_player_info->m_run_speed = 1.f;
}
}
};
super_run g_super_run("fastrun", "Super Run", "Makes you run much faster", g.self.super_run);
}

View File

@ -1,12 +1,18 @@
#include "backend/looped/looped.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
namespace big
{
void looped::self_unlimited_oxygen()
class unlimited_oxygen : looped_command
{
if (g_local_player == nullptr) return;
using looped_command::looped_command;
if (g.self.unlimited_oxygen)
g_local_player->m_oxygen_info->m_oxygen_time = 0;
}
}
virtual void on_tick() override
{
if (g_local_player)
g_local_player->m_oxygen_info->m_oxygen_time = 0;
}
};
unlimited_oxygen g_unlimited_oxygen("infoxy", "Unlimited Oxygen", "Allows you to stay underwater without losing oxygen", g.self.unlimited_oxygen);
}

View File

@ -1,7 +1,7 @@
#include "backend/looped/looped.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "util/kick.hpp"
#include "backend/player_command.hpp"
namespace big
{
@ -14,7 +14,9 @@ namespace big
g_player_service->iterate([](auto& plyr)
{
if (plyr.second->is_host())
kick::lost_connection_kick(plyr.second);
{
((player_command*)(command::get(RAGE_JOAAT("lckick"))))->call(plyr.second, {});
}
});
}
bLastKickHost = kick_host;

View File

@ -10,6 +10,9 @@ namespace big
{
void looped::system_desync_kick_protection()
{
if (g_player_service->get_self()->is_valid() && g_player_service->get_self()->is_host())
return;
memset(&gta_util::get_network()->m_game_complaint_mgr.m_host_tokens_complained, 0, 64 * sizeof(std::uint64_t));
if (!g_player_service->m_player_to_use_complaint_kick || !g_player_service->m_player_to_use_complaint_kick->get()->get_net_data())
gta_util::get_network()->m_game_complaint_mgr.m_num_tokens_complained = 0;

View File

@ -1,10 +1,23 @@
#include "backend/looped/looped.hpp"
#include "script_global.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
#include "core/scr_globals.hpp"
namespace big
{
void looped::tunables_disable_phone()
class disable_phone : looped_command
{
*script_global(20366).as<bool*>() = g.tunables.disable_phone; // Who even uses that...
}
}
using looped_command::looped_command;
virtual void on_tick() override
{
*script_global(20366).as<bool*>() = true;
}
virtual void on_disable() override
{
*script_global(20366).as<bool*>() = false;
}
};
disable_phone g_disable_phone("nophone", "Disable Phone", "Blocks phone and stops all phone calls", g.tunables.disable_phone);
}

View File

@ -0,0 +1,25 @@
#include "natives.hpp"
#include "backend/looped_command.hpp"
#include "gta/enums.hpp"
namespace big
{
class block_homing : looped_command
{
using looped_command::looped_command;
virtual void on_tick() override
{
if (g_local_player && g_local_player->m_vehicle)
g_local_player->m_vehicle->m_is_targetable = false;
}
virtual void on_disable() override
{
if (g_local_player && g_local_player->m_vehicle)
g_local_player->m_vehicle->m_is_targetable = true;
}
};
block_homing g_block_homing("blockhoming", "Block Homing Missiles", "Prevents homing missiles from locking on to your vehicle", g.vehicle.block_homing);
}

View File

@ -1,93 +1,99 @@
#include "backend/looped/looped.hpp"
#include "fiber_pool.hpp"
#include "natives.hpp"
#include "script.hpp"
#include "backend/looped_command.hpp"
#include "util/entity.hpp"
namespace big
{
constexpr auto drive_on_water_surface_hash = RAGE_JOAAT("stt_prop_stunt_bblock_xl3");
static Vector3 drive_on_water_last_loc;
void drive_on_water_hide_surface()
class drive_on_water : looped_command
{
Object surface = OBJECT::GET_CLOSEST_OBJECT_OF_TYPE(
drive_on_water_last_loc.x, drive_on_water_last_loc.y, drive_on_water_last_loc.z,
4.0, drive_on_water_surface_hash, 0, 0, 1
);
using looped_command::looped_command;
if (surface)
{
entity::take_control_of(surface);
ENTITY::SET_ENTITY_COORDS(surface, 0, 0, -1000.0f, 0, 0, 0, 1);
script::get_current()->yield(10ms);
ENTITY::SET_ENTITY_AS_NO_LONGER_NEEDED(&surface);
ENTITY::DELETE_ENTITY(&surface);
WATER::RESET_DEEP_OCEAN_SCALER();
}
}
const rage::joaat_t drive_on_water_surface_hash = RAGE_JOAAT("stt_prop_stunt_bblock_xl3");
Vector3 drive_on_water_last_loc;
void looped::vehicle_drive_on_water()
{
if (!g.vehicle.drive_on_water || self::veh == 0) {
drive_on_water_hide_surface();
return;
}
Vector3 location = ENTITY::GET_ENTITY_COORDS(self::veh, 1);
float height = 0;
WATER::SET_DEEP_OCEAN_SCALER(0);
if (location.z - height < 10 && WATER::GET_WATER_HEIGHT_NO_WAVES(location.x, location.y, location.z, &height))
void drive_on_water_hide_surface()
{
Object surface = OBJECT::GET_CLOSEST_OBJECT_OF_TYPE(
drive_on_water_last_loc.x, drive_on_water_last_loc.y, drive_on_water_last_loc.z,
4.0, drive_on_water_surface_hash, 0, 0, 1
);
if (ENTITY::DOES_ENTITY_EXIST(surface) && height > -50.0f)
if (surface)
{
entity::take_control_of(surface);
ENTITY::SET_ENTITY_COORDS(surface, 0, 0, -1000.0f, 0, 0, 0, 1);
ENTITY::SET_ENTITY_AS_NO_LONGER_NEEDED(&surface);
ENTITY::DELETE_ENTITY(&surface);
WATER::RESET_DEEP_OCEAN_SCALER();
}
}
drive_on_water_last_loc = location;
drive_on_water_last_loc.z = height - 0.5f;
ENTITY::SET_ENTITY_COORDS(
surface,
drive_on_water_last_loc.x, drive_on_water_last_loc.y, drive_on_water_last_loc.z,
0, 0, 0, 0
virtual void on_tick() override
{
Vector3 location = ENTITY::GET_ENTITY_COORDS(self::veh, 1);
float height = 0;
WATER::SET_DEEP_OCEAN_SCALER(0);
if (location.z - height < 10 && WATER::GET_WATER_HEIGHT_NO_WAVES(location.x, location.y, location.z, &height) && self::veh)
{
Object surface = OBJECT::GET_CLOSEST_OBJECT_OF_TYPE(
drive_on_water_last_loc.x, drive_on_water_last_loc.y, drive_on_water_last_loc.z,
4.0, drive_on_water_surface_hash, 0, 0, 1
);
if (location.z < height - 2.f)
if (ENTITY::DOES_ENTITY_EXIST(surface) && height > -50.0f)
{
entity::take_control_of(self::veh);
ENTITY::SET_ENTITY_COORDS(self::veh, location.x, location.y, height, 0, 0, 0, 0);
entity::take_control_of(surface);
drive_on_water_last_loc = location;
drive_on_water_last_loc.z = height - 0.5f;
ENTITY::SET_ENTITY_COORDS(
surface,
drive_on_water_last_loc.x, drive_on_water_last_loc.y, drive_on_water_last_loc.z,
0, 0, 0, 0
);
if (location.z < height - 2.f)
{
entity::take_control_of(self::veh);
ENTITY::SET_ENTITY_COORDS(self::veh, location.x, location.y, height, 0, 0, 0, 0);
}
}
else
{
STREAMING::REQUEST_MODEL(drive_on_water_surface_hash);
while (!STREAMING::HAS_MODEL_LOADED(drive_on_water_surface_hash))
{
script::get_current()->yield();
}
drive_on_water_last_loc = location;
drive_on_water_last_loc.z = height - 0.5f;
surface = OBJECT::CREATE_OBJECT(
drive_on_water_surface_hash,
drive_on_water_last_loc.x, drive_on_water_last_loc.y, drive_on_water_last_loc.z,
1, 1, 0
);
entity::take_control_of(surface);
ENTITY::FREEZE_ENTITY_POSITION(surface, 1);
ENTITY::SET_ENTITY_ALPHA(surface, 0, 1);
ENTITY::SET_ENTITY_VISIBLE(surface, false, 0);
}
}
else
{
STREAMING::REQUEST_MODEL(drive_on_water_surface_hash);
while (!STREAMING::HAS_MODEL_LOADED(drive_on_water_surface_hash))
{
script::get_current()->yield();
}
drive_on_water_last_loc = location;
drive_on_water_last_loc.z = height - 0.5f;
surface = OBJECT::CREATE_OBJECT(
drive_on_water_surface_hash,
drive_on_water_last_loc.x, drive_on_water_last_loc.y, drive_on_water_last_loc.z,
1, 1, 0
);
entity::take_control_of(surface);
ENTITY::FREEZE_ENTITY_POSITION(surface, 1);
ENTITY::SET_ENTITY_ALPHA(surface, 0, 1);
ENTITY::SET_ENTITY_VISIBLE(surface, false, 0);
drive_on_water_hide_surface();
}
}
else
virtual void on_disable() override
{
drive_on_water_hide_surface();
}
}
};
drive_on_water g_drive_on_water("driveonwater", "Drive On Water", "Allows you to drive on water", g.vehicle.drive_on_water);
}

View File

@ -1,38 +1,44 @@
#include "backend/looped/looped.hpp"
#include "gta/enums.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
#include "gta/enums.hpp"
namespace big
{
static constexpr float hornBoostSpeedDefault = 10.f;
static float hornBoostSpeed = hornBoostSpeedDefault;
static constexpr float hostBoostSpeedMax = 200.f;
void looped::vehicle_horn_boost()
class horn_boost : looped_command
{
if (!g.vehicle.horn_boost) return;
Vehicle vehicle = self::veh;
using looped_command::looped_command;
static constexpr float horn_boost_speed_default = 10.f;
static constexpr float horn_boost_speed_max = 200.f;
static constexpr float horn_boost_speed_increment = 0.3f;
if (vehicle == 0)
float horn_boost_speed = horn_boost_speed_default;
virtual void on_tick() override
{
hornBoostSpeed = hornBoostSpeedDefault;
Vehicle vehicle = self::veh;
return;
if (vehicle == 0)
{
horn_boost_speed = horn_boost_speed_default;
return;
}
if (PAD::IS_CONTROL_JUST_PRESSED(0, (int)ControllerInputs::INPUT_VEH_HORN))
horn_boost_speed = ENTITY::GET_ENTITY_SPEED(vehicle);
if (PAD::IS_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_VEH_HORN))
{
if (horn_boost_speed < horn_boost_speed_max)
horn_boost_speed += horn_boost_speed_increment;
const auto velocity =
ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vehicle, 0.f, horn_boost_speed, 0.f) - ENTITY::GET_ENTITY_COORDS(vehicle, true);
ENTITY::SET_ENTITY_VELOCITY(vehicle, velocity.x, velocity.y, velocity.z);
}
else if (PAD::IS_CONTROL_JUST_RELEASED(0, (int)ControllerInputs::INPUT_VEH_HORN))
horn_boost_speed = horn_boost_speed_default;
}
};
if (PAD::IS_CONTROL_JUST_PRESSED(0, (int)ControllerInputs::INPUT_VEH_HORN))
hornBoostSpeed = ENTITY::GET_ENTITY_SPEED(vehicle);
if (PAD::IS_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_VEH_HORN))
{
if (hornBoostSpeed < hostBoostSpeedMax) hornBoostSpeed++;
const auto velocity =
ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vehicle, 0.f, hornBoostSpeed, 0.f) - ENTITY::GET_ENTITY_COORDS(vehicle, true);
ENTITY::SET_ENTITY_VELOCITY(vehicle, velocity.x, velocity.y, velocity.z);
}
else if (PAD::IS_CONTROL_JUST_RELEASED(0, (int)ControllerInputs::INPUT_VEH_HORN))
hornBoostSpeed = hornBoostSpeedDefault;
}
}
horn_boost g_horn_boost("hornboost", "Horn Boost", "Boosts your vehicle forward when you sound the horn", g.vehicle.horn_boost);
}

View File

@ -1,22 +1,22 @@
#include "backend/looped/looped.hpp"
#include "gta/enums.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
#include "gta/enums.hpp"
namespace big
{
void looped::vehicle_instant_brake()
class instant_brake : looped_command
{
if (!g.vehicle.instant_brake) return;
using looped_command::looped_command;
Vehicle vehicle = self::veh;
if (vehicle == 0 || ENTITY::GET_ENTITY_SPEED_VECTOR(vehicle, true).y < 1.f || !VEHICLE::IS_VEHICLE_ON_ALL_WHEELS(vehicle))
virtual void on_tick() override
{
return;
}
if (self::veh == 0 || ENTITY::GET_ENTITY_SPEED_VECTOR(self::veh, true).y < 1.f || !VEHICLE::IS_VEHICLE_ON_ALL_WHEELS(self::veh))
return;
if (PAD::IS_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_VEH_BRAKE) || PAD::IS_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_VEH_HANDBRAKE))
VEHICLE::SET_VEHICLE_FORWARD_SPEED(vehicle, 0);
}
if (PAD::IS_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_VEH_BRAKE) || PAD::IS_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_VEH_HANDBRAKE))
VEHICLE::SET_VEHICLE_FORWARD_SPEED(self::veh, 0);
}
};
instant_brake g_instant_brake("instantbrake", "Instant Brake", "Makes your vehicle stop instantly when you press the brake", g.vehicle.instant_brake);
}

View File

@ -1,10 +0,0 @@
#include "backend/looped/looped.hpp"
namespace big
{
void looped::vehicle_is_targetable()
{
if (g_local_player && g_local_player->m_vehicle)
g_local_player->m_vehicle->m_is_targetable = g.vehicle.is_targetable;
}
}

View File

@ -1,12 +1,19 @@
#include "backend/looped/looped.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
#include "util/vehicle.hpp"
namespace big
{
void looped::vehicle_keep_vehicle_repaired()
class keep_vehicle_repaired : looped_command
{
if (g.vehicle.keep_vehicle_repaired && VEHICLE::GET_DOES_VEHICLE_HAVE_DAMAGE_DECALS(self::veh)) {
vehicle::repair(self::veh);
using looped_command::looped_command;
virtual void on_tick() override
{
if (VEHICLE::GET_DOES_VEHICLE_HAVE_DAMAGE_DECALS(self::veh))
vehicle::repair(self::veh);
}
}
}
};
keep_vehicle_repaired g_keep_vehicle_repaired("keepfixed", "Keep Vehicle Repaired", "Keeps your vehicle free of wear and tear", g.vehicle.keep_vehicle_repaired);
}

View File

@ -1,24 +1,24 @@
#include "backend/looped/looped.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
namespace big
{
static bool bLastVehicleNoWaterCollsion = false;
void looped::vehicle_no_water_collision()
class no_vehicle_water_collision : looped_command
{
if (g_local_player == nullptr || g_local_player->m_vehicle == nullptr) return;
using looped_command::looped_command;
bool bNoWaterCollsion = g.vehicle.no_water_collision;
virtual void on_tick() override
{
if (g_local_player && g_local_player->m_vehicle)
g_local_player->m_vehicle->m_navigation->m_damp->m_water_collision = 0;
}
if (bNoWaterCollsion)
virtual void on_disable() override
{
g_local_player->m_vehicle->m_navigation->m_damp->m_water_collision = 0;
bLastVehicleNoWaterCollsion = bNoWaterCollsion;
if (g_local_player && g_local_player->m_vehicle)
g_local_player->m_vehicle->m_navigation->m_damp->m_water_collision = 1;
}
else if (bNoWaterCollsion != bLastVehicleNoWaterCollsion)
{
g_local_player->m_vehicle->m_navigation->m_damp->m_water_collision = 1;
bLastVehicleNoWaterCollsion = bNoWaterCollsion;
}
}
}
};
no_vehicle_water_collision g_no_vehicle_water_collision("driveunder", "Drive Underwater", "Allows you to drive underwater", g.vehicle.no_water_collision);
}

View File

@ -1,21 +1,24 @@
#include "backend/looped/looped.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
namespace big
{
static bool b_last_seatbelt = false;
void looped::vehicle_seatbelt()
class seatbelt : looped_command
{
bool b_seatbelt = g.vehicle.seatbelt;
using looped_command::looped_command;
if (b_seatbelt || (!b_seatbelt && b_seatbelt != b_last_seatbelt))
virtual void on_tick() override
{
PED::SET_PED_CONFIG_FLAG(self::ped, 32, g.vehicle.seatbelt);
PED::SET_PED_CAN_BE_KNOCKED_OFF_VEHICLE(self::ped, g.vehicle.seatbelt);
b_last_seatbelt = g.vehicle.seatbelt;
PED::SET_PED_CONFIG_FLAG(self::ped, 32, true);
PED::SET_PED_CAN_BE_KNOCKED_OFF_VEHICLE(self::ped, true);
}
}
virtual void on_disable() override
{
PED::SET_PED_CONFIG_FLAG(self::ped, 32, false);
PED::SET_PED_CAN_BE_KNOCKED_OFF_VEHICLE(self::ped, false);
}
};
seatbelt g_seatbelt("seatbelt", "Seatbelt", "Prevent you from falling off bikes or flying through the windshield", g.vehicle.no_water_collision);
}

View File

@ -1,23 +1,21 @@
#include "backend/looped/looped.hpp"
#include "gta/enums.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
#include "gta/enums.hpp"
namespace big
{
void looped::vehicle_jump()
class vehicle_jump : looped_command
{
if (!g.vehicle.vehicle_jump) return;
using looped_command::looped_command;
const auto vehicle = self::veh;
if (!vehicle || !ENTITY::IS_ENTITY_A_VEHICLE(vehicle))
virtual void on_tick() override
{
return;
if (self::veh && PAD::IS_CONTROL_JUST_PRESSED(0, (int)ControllerInputs::INPUT_VEH_HANDBRAKE))
{
ENTITY::APPLY_FORCE_TO_ENTITY(self::veh, 1, 0.0, 0.0, 20, 0.0, 0.0, 0.0, 0, 0, 1, 1, 0, 1);
}
}
};
if (PAD::IS_CONTROL_JUST_PRESSED(0, (int)ControllerInputs::INPUT_VEH_HANDBRAKE))
{
ENTITY::APPLY_FORCE_TO_ENTITY(vehicle, 1, 0.0, 0.0, 20, 0.0, 0.0, 0.0, 0, 0, 1, 1, 0, 1);
}
}
vehicle_jump g_vehicle_jump("vehjump", "Vehicle Jump", "Makes the vehicle jump when you press the handbrake", g.vehicle.vehicle_jump);
}

View File

@ -1,13 +1,17 @@
#include "backend/looped/looped.hpp"
#include "natives.hpp"
#include "core/enums.hpp"
#include "backend/looped_command.hpp"
namespace big
{
void looped::weapons_force_crosshairs()
class force_crosshairs : looped_command
{
if (g.weapons.force_crosshairs) {
using looped_command::looped_command;
virtual void on_tick() override
{
HUD::SHOW_HUD_COMPONENT_THIS_FRAME(static_cast<int>(HudComponents::RETICLE));
}
}
}
};
force_crosshairs g_force_crosshairs("crosshairs", "Force Crosshairs", "Shows the crosshair even when you are not aiming", g.weapons.force_crosshairs); // do we need this?
}

View File

@ -1,19 +1,25 @@
#include "backend/looped/looped.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
namespace big
{
static bool bLastInfiniteAmmo = false;
void looped::weapons_infinite_ammo()
class infinite_ammo : looped_command
{
bool bInfiniteAmmo = g.weapons.infinite_ammo;
using looped_command::looped_command;
if (bInfiniteAmmo || (!bInfiniteAmmo && bInfiniteAmmo != bLastInfiniteAmmo))
CWeaponInfo* p_modified_weapon = nullptr;
float og_recoil_value = 0.0f;
virtual void on_tick() override
{
WEAPON::SET_PED_INFINITE_AMMO(self::ped, g.weapons.infinite_ammo, NULL);
bLastInfiniteAmmo = g.weapons.infinite_ammo;
WEAPON::SET_PED_INFINITE_AMMO(self::ped, TRUE, NULL);
}
}
}
virtual void on_disable() override
{
WEAPON::SET_PED_INFINITE_AMMO(self::ped, FALSE, NULL);
}
};
infinite_ammo g_infinite_ammo("infammo", "Infinite Ammo", "Never run out of ammo again", g.weapons.no_recoil);
}

View File

@ -1,19 +1,25 @@
#include "backend/looped/looped.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
namespace big
{
static bool bLastInfiniteMag = false;
void looped::weapons_infinite_mag()
class infinite_mag : looped_command
{
bool bInfiniteMag = g.weapons.infinite_mag;
using looped_command::looped_command;
if (bInfiniteMag || (!bInfiniteMag && bInfiniteMag != bLastInfiniteMag))
CWeaponInfo* p_modified_weapon = nullptr;
float og_recoil_value = 0.0f;
virtual void on_tick() override
{
WEAPON::SET_PED_INFINITE_AMMO_CLIP(self::ped, g.weapons.infinite_mag);
bLastInfiniteMag = g.weapons.infinite_mag;
WEAPON::SET_PED_INFINITE_AMMO_CLIP(self::ped, TRUE);
}
}
}
virtual void on_disable() override
{
WEAPON::SET_PED_INFINITE_AMMO_CLIP(self::ped, FALSE);
}
};
infinite_mag g_infinite_mag("infclip", "Infinite Clip", "Shoot forever without needing to reload", g.weapons.no_recoil);
}

View File

@ -1,54 +1,47 @@
#include "backend/looped/looped.hpp"
#include "pointers.hpp"
#include "gta/enums.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
namespace big
{
static std::vector<std::pair<uint32_t, float>> og_recoil_values{};
static uint32_t prev_weapon_hash{};
bool is_recoil_value_cached(uint32_t hash)
class no_recoil : looped_command
{
return std::find_if(og_recoil_values.begin(), og_recoil_values.end(), [hash](auto const entry)
{
return hash == entry.first;
}) != og_recoil_values.end();
}
using looped_command::looped_command;
float get_og_recoil_value(uint32_t hash)
{
return std::find_if(og_recoil_values.begin(), og_recoil_values.end(), [hash](auto const entry)
{
return hash == entry.first;
})->second;
}
CWeaponInfo* p_modified_weapon = nullptr;
float og_recoil_value = 0.0f;
float get_recoil_value(uint32_t hash)
{
return g.weapons.no_recoil
? 0.f
: get_og_recoil_value(hash);
}
void looped::weapons_no_recoil()
{
if (!g_local_player)
virtual void on_tick() override
{
return;
}
auto* const weapon_mgr = g_local_player->m_weapon_manager;
if (weapon_mgr)
{
auto const cur_weapon_hash = weapon_mgr->m_selected_weapon_hash;
if (prev_weapon_hash != cur_weapon_hash)
if (!g_local_player)
{
if (!is_recoil_value_cached(cur_weapon_hash))
return;
}
auto* const weapon_mgr = g_local_player->m_weapon_manager;
if (weapon_mgr)
{
if (p_modified_weapon != weapon_mgr->m_weapon_info && weapon_mgr->m_weapon_info)
{
og_recoil_values.push_back({ cur_weapon_hash, weapon_mgr->m_weapon_info->m_explosion_shake_amplitude });
if (p_modified_weapon)
p_modified_weapon->m_explosion_shake_amplitude = og_recoil_value;
og_recoil_value = weapon_mgr->m_weapon_info->m_explosion_shake_amplitude;
p_modified_weapon = weapon_mgr->m_weapon_info;
weapon_mgr->m_weapon_info->m_explosion_shake_amplitude = 0.0f;
}
weapon_mgr->m_weapon_info->m_explosion_shake_amplitude = get_recoil_value(cur_weapon_hash); // m_explosion_shake_amplitude is the right offset in https://github.com/Yimura/GTAV-Classes
}
}
}
}
virtual void on_disable() override
{
if (g_local_player && p_modified_weapon)
{
p_modified_weapon->m_explosion_shake_amplitude = og_recoil_value;
p_modified_weapon = nullptr;
}
}
};
no_recoil g_no_recoil("norecoil", "No Recoil", "Removes weapon recoil when shooting", g.weapons.no_recoil);
}

View File

@ -1,54 +1,47 @@
#include "backend/looped/looped.hpp"
#include "pointers.hpp"
#include "gta/enums.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
namespace big
{
static std::vector<std::pair<uint32_t, float>> og_spread_values{};
static uint32_t prev_weapon_hash{};
class no_spread : looped_command
{
using looped_command::looped_command;
bool is_spread_value_cached(uint32_t hash)
{
return std::find_if(og_spread_values.begin(), og_spread_values.end(), [hash](auto const entry)
CWeaponInfo* p_modified_weapon = nullptr;
float og_spread_value = 0.0f;
virtual void on_tick() override
{
if (!g_local_player)
{
return hash == entry.first;
}) != og_spread_values.end();
}
return;
}
float get_og_spread_value(uint32_t hash)
{
return std::find_if(og_spread_values.begin(), og_spread_values.end(), [hash](auto const entry)
auto* const weapon_mgr = g_local_player->m_weapon_manager;
if (weapon_mgr)
{
return hash == entry.first;
})->second;
}
float get_spread_value(uint32_t hash)
{
return g.weapons.no_spread
? 0.f
: get_og_spread_value(hash);
}
void looped::weapons_no_spread()
{
if (!g_local_player)
{
return;
}
auto* const weapon_mgr = g_local_player->m_weapon_manager;
if (weapon_mgr)
{
auto const cur_weapon_hash = weapon_mgr->m_selected_weapon_hash;
if (prev_weapon_hash != cur_weapon_hash)
{
if (!is_spread_value_cached(cur_weapon_hash))
if (p_modified_weapon != weapon_mgr->m_weapon_info && weapon_mgr->m_weapon_info)
{
og_spread_values.push_back({ cur_weapon_hash, weapon_mgr->m_weapon_info->m_accuracy_spread });
}
if (p_modified_weapon)
p_modified_weapon->m_accuracy_spread = og_spread_value;
weapon_mgr->m_weapon_info->m_accuracy_spread = get_spread_value(cur_weapon_hash);
og_spread_value = weapon_mgr->m_weapon_info->m_accuracy_spread;
p_modified_weapon = weapon_mgr->m_weapon_info;
weapon_mgr->m_weapon_info->m_accuracy_spread = 0.0f;
}
}
}
virtual void on_disable() override
{
if (g_local_player && p_modified_weapon)
{
p_modified_weapon->m_accuracy_spread = og_spread_value;
p_modified_weapon = nullptr;
}
}
}
}
};
no_spread g_no_spread("nospread", "No Spread", "Removes weapon spread when shooting", g.weapons.no_spread);
}

View File

@ -1,16 +1,18 @@
#include "backend/looped/looped.hpp"
#include "natives.hpp"
#include "gta/enums.hpp"
#include "natives.hpp"
#include "backend/looped_command.hpp"
#include "util/math.hpp"
#include "gui.hpp"
namespace big
{
void looped::weapons_rapid_fire()
{
if (g.weapons.rapid_fire)
{
if(!HUD::IS_PAUSE_MENU_ACTIVE() && !g_gui->is_open() && !PED::IS_PED_DEAD_OR_DYING(self::ped, true))
class rapid_fire : looped_command
{
using looped_command::looped_command;
virtual void on_tick() override
{
if (!HUD::IS_PAUSE_MENU_ACTIVE() && !g_gui->is_open() && !PED::IS_PED_DEAD_OR_DYING(self::ped, true) && !PED::IS_PED_IN_ANY_VEHICLE(self::ped, TRUE))
{
if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_ATTACK))
{
@ -22,6 +24,8 @@ namespace big
MISC::SHOOT_SINGLE_BULLET_BETWEEN_COORDS(start.x, start.y, start.z, end.x, end.y, end.z, WEAPON::GET_WEAPON_DAMAGE(weapon_hash, 0), true, weapon_hash, self::ped, true, false, -1.0);
}
}
}
}
}
}
};
rapid_fire g_rapid_fire("rapidfire", "Rapid Fire", "Makes your weapon fire insanely fast", g.weapons.rapid_fire);
}

View File

@ -0,0 +1,45 @@
#include "looped_command.hpp"
#include "fiber_pool.hpp"
namespace big
{
looped_command::looped_command(const std::string& name, const std::string& label, const std::string& description, bool& toggle) :
bool_command(name, label, description, toggle)
{
g_looped_commands.push_back(this);
}
void looped_command::enable()
{
if (!m_toggle)
{
m_toggle = true;
m_last_enabled = true;
g_fiber_pool->queue_job([this] { on_enable(); });
}
}
void looped_command::disable()
{
if (m_toggle)
{
m_toggle = false;
m_last_enabled = false;
g_fiber_pool->queue_job([this] { disable(); });
}
}
void looped_command::refresh()
{
if (m_toggle && !m_last_enabled)
{
m_last_enabled = true;
g_fiber_pool->queue_job([this] { on_enable(); });
}
else if (!m_toggle && m_last_enabled)
{
m_last_enabled = false;
g_fiber_pool->queue_job([this] { on_disable(); });
}
}
}

View File

@ -0,0 +1,23 @@
#pragma once
#include "bool_command.hpp"
namespace big
{
class looped_command : public bool_command
{
bool m_last_enabled = false;
public:
looped_command(const std::string& name, const std::string& label, const std::string& description, bool& toggle);
virtual void on_enable() {};
virtual void on_disable() {};
virtual void on_tick() = 0;
virtual void refresh() override;
virtual void enable() override;
virtual void disable() override;
};
inline std::vector<looped_command*> g_looped_commands;
}

View File

@ -0,0 +1,133 @@
#include "player_command.hpp"
#include "fiber_pool.hpp"
namespace big
{
player_all_component::player_all_component(player_command* parent, const std::string& name, const std::string& label, const std::string& description, std::optional<std::uint8_t> num_args) :
command(name + "all", label, description, num_args),
m_parent(parent)
{
}
void player_all_component::execute(const std::vector<std::uint64_t>& args, const std::shared_ptr<command_context> ctx)
{
g_fiber_pool->queue_job([this, args, &ctx]
{
g_player_service->iterate([this, args, &ctx](const player_entry& player)
{
m_parent->execute(player.second, args, ctx);
});
});
}
std::optional<std::vector<std::uint64_t>> player_all_component::parse_args(const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx)
{
return m_parent->parse_args_p(args, ctx);
}
player_command::player_command(const std::string& name, const std::string& label, const std::string& description, std::optional<std::uint8_t> num_args, bool make_all_version) :
command(name, label, description, num_args.has_value() ? std::optional{num_args.value() + 1} : std::nullopt)
{
if (make_all_version)
m_all_component = std::make_unique<player_all_component>(this, name, label, description, num_args);
}
void player_command::execute(const std::vector<std::uint64_t>& args, const std::shared_ptr<command_context> ctx)
{
g_fiber_pool->queue_job([this, args, ctx]
{
std::vector<std::uint64_t> new_args;
// TODO: This looks ugly and inefficient
for (int i = 1; i < m_num_args; i++)
new_args.push_back(args[i]);
if (g_player_service->get_self()->id() == args[0])
{
execute(g_player_service->get_self(), new_args, ctx);
return;
}
for (auto& plyr : g_player_service->players())
{
if (plyr.second->id() == args[0])
{
execute(plyr.second, new_args, ctx);
return;
}
}
ctx->report_error(std::format("Tried to execute command {}, but a player with index {} was not found", m_name, args[0]));
});
}
std::optional<std::vector<std::uint64_t>> player_command::parse_args(const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx)
{
std::vector<std::string> new_args;
std::vector<std::uint64_t> result;
if (args[0] == "me" || args[0] == "self")
{
result.push_back(ctx->get_sender()->id());
}
else
{
int plyr_id = -1;
for (auto& plyr : g_player_service->players())
{
if (stricmp(plyr.second->get_name(), args[0].c_str()) == 0)
{
plyr_id = plyr.second->id();
break;
}
}
if (stricmp(g_player_service->get_self()->get_name(), args[0].c_str()) == 0 || (g.spoofing.spoof_username && stricmp(g.spoofing.username.c_str(), args[0].c_str()) == 0))
{
plyr_id = g_player_service->get_self()->id();
}
if (ctx->get_access_level() != CommandAccessLevel::ADMIN && (get_access_level() == CommandAccessLevel::TOXIC || get_access_level() == CommandAccessLevel::AGGRESSIVE) && plyr_id == self::id)
{
ctx->report_error("Permission denied, cannot call toxic commands on me");
return std::nullopt;
}
if (plyr_id == -1)
{
ctx->report_error(std::format("Cannot find player with name {} in command {}", args[0], m_name));
return std::nullopt;
}
result.push_back(plyr_id);
}
for (int i = 1; i < args.size(); i++)
new_args.push_back(args[i]);
auto res = parse_args_p(new_args, ctx);
if (!res.has_value())
return std::nullopt;
for (auto& p : res.value())
result.push_back(p);
return result;
}
void player_command::call(player_ptr player, const std::vector<std::uint64_t>& args, const std::shared_ptr<command_context> ctx)
{
// TODO: Code duplication
if (m_num_args.has_value() && args.size() != (m_num_args.value() - 1))
{
ctx->report_error(std::format("Command {} called with the wrong number of arguments. Expected {}, got {}", m_name, m_num_args.value(), args.size()));
return;
}
g_fiber_pool->queue_job([this, player, args, ctx] {
if (player->is_valid())
execute(player, args, ctx);
});
}
}

View File

@ -0,0 +1,33 @@
#pragma once
#include "command.hpp"
#include "services/players/player_service.hpp"
namespace big
{
class player_command;
class player_all_component : public command
{
player_command* m_parent;
protected:
virtual void execute(const std::vector<std::uint64_t>& args, const std::shared_ptr<command_context> ctx = std::make_shared<default_command_context>()) override;
virtual std::optional<std::vector<std::uint64_t>> parse_args(const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx = std::make_shared<default_command_context>()) override;
public:
player_all_component(player_command* parent, const std::string& name, const std::string& label, const std::string& description, std::optional<std::uint8_t> num_args);
};
class player_command : public command
{
friend player_all_component;
std::unique_ptr<player_all_component> m_all_component;
protected:
virtual void execute(const std::vector<std::uint64_t>& args, const std::shared_ptr<command_context> ctx = std::make_shared<default_command_context>()) override;
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& args, const std::shared_ptr<command_context> ctx = std::make_shared<default_command_context>()) = 0;
virtual std::optional<std::vector<std::uint64_t>> parse_args(const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx = std::make_shared<default_command_context>()) override;
virtual std::optional<std::vector<std::uint64_t>> parse_args_p(const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx = std::make_shared<default_command_context>()) { return std::vector<std::uint64_t>(); };
public:
void call(player_ptr player, const std::vector<std::uint64_t>& args, const std::shared_ptr<command_context> ctx = std::make_shared<default_command_context>());
player_command(const std::string& name, const std::string& label, const std::string& description, std::optional<std::uint8_t> num_args, bool make_all_version = true);
};
}

View File

@ -12,6 +12,7 @@ namespace big
g_script_patcher_service->add_patch({ RAGE_JOAAT("freemode"), "5D ? ? ? 76 57 ? ? 5D ? ? ? 76", 0, { 0x2E, 0x00, 0x00 }, nullptr }); // end session kick protection
g_script_patcher_service->add_patch({ RAGE_JOAAT("freemode"), "2D 01 09 00 00 5D ? ? ? 56 ? ? 2E", 5, { 0x2E, 0x01, 0x00 }, nullptr }); // disable death when undermap/spectating
g_script_patcher_service->add_patch({ RAGE_JOAAT("freemode"), "71 2E ? ? 55 ? ? 61 ? ? ? 47 ? ? 63", 0, { 0x72 }, nullptr }); // load island even if stranded animal IPL choice is not set
g_script_patcher_service->add_patch({ RAGE_JOAAT("freemode"), "2D 00 07 00 00 7B", 5, { 0x2E, 0x00, 0x00 }, nullptr }); // disable population load balancing
g_script_patcher_service->add_patch({ RAGE_JOAAT("shop_controller"), "2D 01 04 00 00 2C ? ? ? 56 ? ? 71", 5, { 0x71, 0x2E, 0x01, 0x01 }, nullptr }); // despawn bypass
g_script_patcher_service->add_patch({ RAGE_JOAAT("shop_controller"), "38 00 5D ? ? ? 38 00 5D ? ? ? 38 00 41", 0, std::vector<uint8_t>(12, 0x0), nullptr}); // godmode/invisibility detection bypass

View File

@ -1,6 +1,7 @@
#pragma once
std::map<eExplosionTag, const char*> BULLET_IMPACTS = {
inline std::unordered_map<eExplosionTag, const char*> BULLET_IMPACTS =
{
{ eExplosionTag::DONTCARE, "DEFAULT_BULLETS" },
{ eExplosionTag::GRENADE, "GRENADE" },
{ eExplosionTag::GRENADELAUNCHER, "GRENADELAUNCHER" },

View File

@ -0,0 +1,14 @@
#pragma once
#include "core/enums.hpp"
namespace big
{
inline std::unordered_map<CommandAccessLevel, const char*> COMMAND_ACCESS_LEVELS =
{
{ CommandAccessLevel::NONE, "None" },
{ CommandAccessLevel::FRIENDLY, "Friendly" },
{ CommandAccessLevel::AGGRESSIVE, "Aggressive" },
{ CommandAccessLevel::TOXIC, "Toxic" },
{ CommandAccessLevel::ADMIN, "Admin (!)" }
};
}

View File

@ -399,4 +399,20 @@ namespace big
HUD_COMPONENTS,
HUD_WEAPONS
};
enum class CommandAccessLevel
{
NONE,
FRIENDLY, // heal, semi godmode...
AGGRESSIVE, // kick from vehicle, send to apartment...
TOXIC, // kicks
ADMIN // full access
};
NLOHMANN_JSON_SERIALIZE_ENUM(CommandAccessLevel, {
{ CommandAccessLevel::NONE, "none" },
{ CommandAccessLevel::FRIENDLY, "friendly" },
{ CommandAccessLevel::AGGRESSIVE, "aggressive" },
{ CommandAccessLevel::TOXIC, "toxic" },
{ CommandAccessLevel::ADMIN, "admin" }
})
}

Some files were not shown because too many files have changed in this diff Show More