Commands (#725)
* 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:
parent
f44859a973
commit
79e5e7a30b
@ -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();
|
||||
|
@ -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();
|
||||
|
62
src/backend/bool_command.cpp
Normal file
62
src/backend/bool_command.cpp
Normal 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;
|
||||
}
|
||||
}
|
20
src/backend/bool_command.hpp
Normal file
20
src/backend/bool_command.hpp
Normal 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
112
src/backend/command.cpp
Normal 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
39
src/backend/command.hpp
Normal 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;
|
||||
}
|
25
src/backend/commands/misc/recovery.cpp
Normal file
25
src/backend/commands/misc/recovery.cpp
Normal 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);
|
||||
}
|
32
src/backend/commands/player/kick/bail_kick.cpp
Normal file
32
src/backend/commands/player/kick/bail_kick.cpp
Normal 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);
|
||||
}
|
39
src/backend/commands/player/kick/breakup_kick.cpp
Normal file
39
src/backend/commands/player/kick/breakup_kick.cpp
Normal 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);
|
||||
}
|
33
src/backend/commands/player/kick/complaint_kick.cpp
Normal file
33
src/backend/commands/player/kick/complaint_kick.cpp
Normal 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
|
||||
}
|
32
src/backend/commands/player/kick/end_session_kick.cpp
Normal file
32
src/backend/commands/player/kick/end_session_kick.cpp
Normal 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);
|
||||
}
|
38
src/backend/commands/player/kick/host_kick.cpp
Normal file
38
src/backend/commands/player/kick/host_kick.cpp
Normal 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);
|
||||
}
|
55
src/backend/commands/player/kick/lost_connection_kick.cpp
Normal file
55
src/backend/commands/player/kick/lost_connection_kick.cpp
Normal 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);
|
||||
}
|
32
src/backend/commands/player/kick/null_function_kick.cpp
Normal file
32
src/backend/commands/player/kick/null_function_kick.cpp
Normal 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);
|
||||
}
|
48
src/backend/commands/player/kick/oom_kick.cpp
Normal file
48
src/backend/commands/player/kick/oom_kick.cpp
Normal 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);
|
||||
}
|
31
src/backend/commands/player/kick/script_host_kick.cpp
Normal file
31
src/backend/commands/player/kick/script_host_kick.cpp
Normal 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);
|
||||
}
|
24
src/backend/commands/player/misc/clear_wanted_level.cpp
Normal file
24
src/backend/commands/player/misc/clear_wanted_level.cpp
Normal 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);
|
||||
}
|
42
src/backend/commands/player/misc/enter_interior.cpp
Normal file
42
src/backend/commands/player/misc/enter_interior.cpp
Normal 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);
|
||||
}
|
25
src/backend/commands/player/misc/give_ammo.cpp
Normal file
25
src/backend/commands/player/misc/give_ammo.cpp
Normal 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);
|
||||
}
|
25
src/backend/commands/player/misc/give_armor.cpp
Normal file
25
src/backend/commands/player/misc/give_armor.cpp
Normal 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);
|
||||
}
|
25
src/backend/commands/player/misc/give_health.cpp
Normal file
25
src/backend/commands/player/misc/give_health.cpp
Normal 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);
|
||||
}
|
20
src/backend/commands/player/misc/join_ceo.cpp
Normal file
20
src/backend/commands/player/misc/join_ceo.cpp
Normal 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);
|
||||
}
|
21
src/backend/commands/player/misc/steal_identity.cpp
Normal file
21
src/backend/commands/player/misc/steal_identity.cpp
Normal 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?
|
||||
}
|
21
src/backend/commands/player/misc/steal_outfit.cpp
Normal file
21
src/backend/commands/player/misc/steal_outfit.cpp
Normal 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);
|
||||
}
|
43
src/backend/commands/player/toxic/ceo_kick.cpp
Normal file
43
src/backend/commands/player/toxic/ceo_kick.cpp
Normal 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);
|
||||
}
|
46
src/backend/commands/player/toxic/give_all_weapons.cpp
Normal file
46
src/backend/commands/player/toxic/give_all_weapons.cpp
Normal 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);
|
||||
}
|
33
src/backend/commands/player/toxic/kick_from_interior.cpp
Normal file
33
src/backend/commands/player/toxic/kick_from_interior.cpp
Normal 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);
|
||||
}
|
41
src/backend/commands/player/toxic/kick_from_vehicle.cpp
Normal file
41
src/backend/commands/player/toxic/kick_from_vehicle.cpp
Normal 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);
|
||||
}
|
27
src/backend/commands/player/toxic/kill_player.cpp
Normal file
27
src/backend/commands/player/toxic/kill_player.cpp
Normal 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);
|
||||
}
|
25
src/backend/commands/player/toxic/ragdoll_player.cpp
Normal file
25
src/backend/commands/player/toxic/ragdoll_player.cpp
Normal 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);
|
||||
}
|
24
src/backend/commands/player/toxic/remove_all_weapons.cpp
Normal file
24
src/backend/commands/player/toxic/remove_all_weapons.cpp
Normal 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);
|
||||
}
|
37
src/backend/commands/player/toxic/send_to_apartment.cpp
Normal file
37
src/backend/commands/player/toxic/send_to_apartment.cpp
Normal 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);
|
||||
}
|
50
src/backend/commands/player/toxic/send_to_interior.cpp
Normal file
50
src/backend/commands/player/toxic/send_to_interior.cpp
Normal 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);
|
||||
}
|
30
src/backend/commands/player/toxic/send_to_island.cpp
Normal file
30
src/backend/commands/player/toxic/send_to_island.cpp
Normal 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);
|
||||
}
|
38
src/backend/commands/player/toxic/send_to_warehouse.cpp
Normal file
38
src/backend/commands/player/toxic/send_to_warehouse.cpp
Normal 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);
|
||||
}
|
67
src/backend/commands/player/toxic/set_wanted_level.cpp
Normal file
67
src/backend/commands/player/toxic/set_wanted_level.cpp
Normal 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);
|
||||
}
|
152
src/backend/commands/player/toxic/turn_into_beast.cpp
Normal file
152
src/backend/commands/player/toxic/turn_into_beast.cpp
Normal 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);
|
||||
}
|
19
src/backend/commands/player/troll/bring.cpp
Normal file
19
src/backend/commands/player/troll/bring.cpp
Normal 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);
|
||||
}
|
30
src/backend/commands/player/troll/remote_control_vehicle.cpp
Normal file
30
src/backend/commands/player/troll/remote_control_vehicle.cpp
Normal 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);
|
||||
}
|
19
src/backend/commands/player/troll/teleport.cpp
Normal file
19
src/backend/commands/player/troll/teleport.cpp
Normal 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);
|
||||
}
|
21
src/backend/commands/player/troll/teleport_into_vehicle.cpp
Normal file
21
src/backend/commands/player/troll/teleport_into_vehicle.cpp
Normal 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);
|
||||
}
|
18
src/backend/commands/self/clean_player.cpp
Normal file
18
src/backend/commands/self/clean_player.cpp
Normal 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);
|
||||
}
|
26
src/backend/commands/self/fill_inventory.cpp
Normal file
26
src/backend/commands/self/fill_inventory.cpp
Normal 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);
|
||||
}
|
18
src/backend/commands/self/heal.cpp
Normal file
18
src/backend/commands/self/heal.cpp
Normal 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);
|
||||
}
|
17
src/backend/commands/self/skip_cutscene.cpp
Normal file
17
src/backend/commands/self/skip_cutscene.cpp
Normal 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);
|
||||
}
|
17
src/backend/commands/self/suicide.cpp
Normal file
17
src/backend/commands/self/suicide.cpp
Normal 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);
|
||||
}
|
59
src/backend/commands/spawn/spawn_vehicle.cpp
Normal file
59
src/backend/commands/spawn/spawn_vehicle.cpp
Normal 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);
|
||||
}
|
20
src/backend/commands/teleport/bring_personal_vehicle.cpp
Normal file
20
src/backend/commands/teleport/bring_personal_vehicle.cpp
Normal 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);
|
||||
}
|
23
src/backend/commands/teleport/teleport_to_last_vehicle.cpp
Normal file
23
src/backend/commands/teleport/teleport_to_last_vehicle.cpp
Normal 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);
|
||||
}
|
18
src/backend/commands/teleport/teleport_to_objective.cpp
Normal file
18
src/backend/commands/teleport/teleport_to_objective.cpp
Normal 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);
|
||||
}
|
@ -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);
|
||||
}
|
18
src/backend/commands/teleport/teleport_to_waypoint.cpp
Normal file
18
src/backend/commands/teleport/teleport_to_waypoint.cpp
Normal 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);
|
||||
}
|
43
src/backend/context/chat_command_context.cpp
Normal file
43
src/backend/context/chat_command_context.cpp
Normal 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);
|
||||
}
|
||||
}
|
17
src/backend/context/chat_command_context.hpp
Normal file
17
src/backend/context/chat_command_context.hpp
Normal 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);
|
||||
};
|
||||
}
|
15
src/backend/context/command_context.hpp
Normal file
15
src/backend/context/command_context.hpp
Normal 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;
|
||||
};
|
||||
}
|
24
src/backend/context/default_command_context.cpp
Normal file
24
src/backend/context/default_command_context.cpp
Normal 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);
|
||||
}
|
||||
}
|
15
src/backend/context/default_command_context.hpp
Normal file
15
src/backend/context/default_command_context.hpp
Normal 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() {};
|
||||
};
|
||||
}
|
32
src/backend/int_command.cpp
Normal file
32
src/backend/int_command.cpp
Normal 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;
|
||||
}
|
||||
}
|
19
src/backend/int_command.hpp
Normal file
19
src/backend/int_command.hpp
Normal 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; }
|
||||
};
|
||||
}
|
@ -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
|
||||
|
@ -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();
|
||||
};
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
using looped_command::looped_command;
|
||||
|
||||
virtual void on_tick() override
|
||||
{
|
||||
if (g.self.clean_player) {
|
||||
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);
|
||||
}
|
@ -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()
|
||||
class fast_respawn : looped_command
|
||||
{
|
||||
if (g.self.fast_respawn)
|
||||
using looped_command::looped_command;
|
||||
|
||||
virtual void on_tick() override
|
||||
{
|
||||
if(PED::IS_PED_DEAD_OR_DYING(self::ped, true))
|
||||
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);
|
||||
}
|
@ -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,56 +21,38 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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::RENDER_SCRIPT_CAMS(false, true, 500, true, true, 0);
|
||||
CAM::DESTROY_CAM(cCam, false);
|
||||
STREAMING::SET_FOCUS_ENTITY(ped);
|
||||
|
||||
ENTITY::FREEZE_ENTITY_POSITION(vehicle, false);
|
||||
|
||||
bLastFreeCam = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 vecChange = { 0.f, 0.f, 0.f };
|
||||
|
||||
@ -106,19 +80,32 @@ namespace big
|
||||
else if (mult < 10)
|
||||
mult += 0.15f;
|
||||
|
||||
Vector3 rot = CAM::GET_CAM_ROT(cCam, 2);
|
||||
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
|
||||
|
||||
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;
|
||||
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(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);
|
||||
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);
|
||||
|
||||
vecRot = CAM::GET_GAMEPLAY_CAM_ROT(2);
|
||||
CAM::SET_CAM_ROT(cCam, vecRot.x, vecRot.y, vecRot.z, 2);
|
||||
rotation = CAM::GET_GAMEPLAY_CAM_ROT(2);
|
||||
CAM::SET_CAM_ROT(camera, rotation.x, rotation.y, rotation.z, 2);
|
||||
}
|
||||
|
||||
virtual void on_disable() override
|
||||
{
|
||||
CAM::SET_CAM_ACTIVE(camera, false);
|
||||
CAM::RENDER_SCRIPT_CAMS(false, true, 500, true, true, 0);
|
||||
CAM::DESTROY_CAM(camera, false);
|
||||
STREAMING::CLEAR_FOCUS();
|
||||
|
||||
ENTITY::FREEZE_ENTITY_POSITION(camera, false);
|
||||
}
|
||||
};
|
||||
|
||||
free_cam g_free_cam("freecam", "Freecam", "Allows you to move your camera freely?", g.self.free_cam);
|
||||
}
|
@ -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)
|
||||
NETWORK::SET_ENTITY_LOCALLY_VISIBLE(self::ped);
|
||||
}
|
||||
|
||||
virtual void on_disable() override
|
||||
{
|
||||
ENTITY::SET_ENTITY_VISIBLE(ped, true, 0);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
if (bNoCollsion)
|
||||
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;
|
||||
bLastNoCollsion = bNoCollsion;
|
||||
}
|
||||
else if (bNoCollsion != bLastNoCollsion)
|
||||
|
||||
virtual void on_disable() 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 = 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);
|
||||
}
|
||||
|
@ -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);
|
||||
PED::SET_PED_CAN_RAGDOLL(self::ped, false);
|
||||
}
|
||||
|
||||
bLastNoRagdoll = g.self.no_ragdoll;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
if (bNoWaterCollsion)
|
||||
virtual void on_tick() override
|
||||
{
|
||||
if (g_local_player)
|
||||
g_local_player->m_navigation->m_damp->m_water_collision = 0;
|
||||
bLastSelfNoWaterCollsion = bNoWaterCollsion;
|
||||
}
|
||||
else if (bNoWaterCollsion != bLastSelfNoWaterCollsion)
|
||||
|
||||
virtual void on_disable() override
|
||||
{
|
||||
if (g_local_player)
|
||||
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);
|
||||
}
|
@ -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;
|
||||
|
||||
// cleanup when changing entities
|
||||
if (prev != ent)
|
||||
if (m_entity != ent)
|
||||
{
|
||||
ENTITY::FREEZE_ENTITY_POSITION(prev, false);
|
||||
ENTITY::SET_ENTITY_COLLISION(prev, true, true);
|
||||
ENTITY::FREEZE_ENTITY_POSITION(m_entity, false);
|
||||
ENTITY::SET_ENTITY_COLLISION(m_entity, true, true);
|
||||
|
||||
prev = ent;
|
||||
m_entity = 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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
@ -1,24 +1,29 @@
|
||||
#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;
|
||||
class super_run : looped_command
|
||||
{
|
||||
using looped_command::looped_command;
|
||||
|
||||
void looped::self_super_run()
|
||||
const float run_cap = 100.f;
|
||||
float run_speed = 10.f;
|
||||
|
||||
virtual void on_tick() override
|
||||
{
|
||||
if (g.self.super_run && PAD::IS_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_SPRINT))
|
||||
if (g_local_player)
|
||||
{
|
||||
if (run_speed < run_cap) run_speed += .5f;
|
||||
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 rot = CAM::GET_GAMEPLAY_CAM_ROT(2);
|
||||
Vector3 rot = ENTITY::GET_ENTITY_ROTATION(ped, 2);
|
||||
float yaw = math::deg_to_rad(rot.z + 90);
|
||||
|
||||
@ -38,16 +43,23 @@ namespace big
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
@ -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)
|
||||
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);
|
||||
}
|
@ -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;
|
||||
|
@ -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(>a_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;
|
||||
|
@ -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);
|
||||
}
|
25
src/backend/looped/vehicle/block_homing.cpp
Normal file
25
src/backend/looped/vehicle/block_homing.cpp
Normal 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);
|
||||
}
|
@ -1,12 +1,17 @@
|
||||
#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;
|
||||
class drive_on_water : looped_command
|
||||
{
|
||||
using looped_command::looped_command;
|
||||
|
||||
const rage::joaat_t drive_on_water_surface_hash = RAGE_JOAAT("stt_prop_stunt_bblock_xl3");
|
||||
Vector3 drive_on_water_last_loc;
|
||||
|
||||
void drive_on_water_hide_surface()
|
||||
{
|
||||
@ -19,26 +24,19 @@ namespace big
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void looped::vehicle_drive_on_water()
|
||||
virtual void on_tick() override
|
||||
{
|
||||
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))
|
||||
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,
|
||||
@ -90,4 +88,12 @@ namespace big
|
||||
drive_on_water_hide_surface();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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;
|
||||
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;
|
||||
|
||||
float horn_boost_speed = horn_boost_speed_default;
|
||||
|
||||
virtual void on_tick() override
|
||||
{
|
||||
Vehicle vehicle = self::veh;
|
||||
|
||||
if (vehicle == 0)
|
||||
{
|
||||
hornBoostSpeed = hornBoostSpeedDefault;
|
||||
|
||||
horn_boost_speed = horn_boost_speed_default;
|
||||
return;
|
||||
}
|
||||
|
||||
if (PAD::IS_CONTROL_JUST_PRESSED(0, (int)ControllerInputs::INPUT_VEH_HORN))
|
||||
hornBoostSpeed = ENTITY::GET_ENTITY_SPEED(vehicle);
|
||||
horn_boost_speed = ENTITY::GET_ENTITY_SPEED(vehicle);
|
||||
|
||||
if (PAD::IS_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_VEH_HORN))
|
||||
{
|
||||
if (hornBoostSpeed < hostBoostSpeedMax) hornBoostSpeed++;
|
||||
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, hornBoostSpeed, 0.f) - ENTITY::GET_ENTITY_COORDS(vehicle, true);
|
||||
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))
|
||||
hornBoostSpeed = hornBoostSpeedDefault;
|
||||
horn_boost_speed = horn_boost_speed_default;
|
||||
}
|
||||
};
|
||||
|
||||
horn_boost g_horn_boost("hornboost", "Horn Boost", "Boosts your vehicle forward when you sound the horn", g.vehicle.horn_boost);
|
||||
}
|
@ -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
|
||||
{
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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)) {
|
||||
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);
|
||||
}
|
@ -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;
|
||||
|
||||
if (bNoWaterCollsion)
|
||||
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;
|
||||
bLastVehicleNoWaterCollsion = bNoWaterCollsion;
|
||||
}
|
||||
else if (bNoWaterCollsion != bLastVehicleNoWaterCollsion)
|
||||
|
||||
virtual void on_disable() override
|
||||
{
|
||||
if (g_local_player && g_local_player->m_vehicle)
|
||||
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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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 (PAD::IS_CONTROL_JUST_PRESSED(0, (int)ControllerInputs::INPUT_VEH_HANDBRAKE))
|
||||
if (self::veh && 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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
vehicle_jump g_vehicle_jump("vehjump", "Vehicle Jump", "Makes the vehicle jump when you press the handbrake", g.vehicle.vehicle_jump);
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
using looped_command::looped_command;
|
||||
|
||||
virtual void on_tick() override
|
||||
{
|
||||
if (g.weapons.force_crosshairs) {
|
||||
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?
|
||||
}
|
@ -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);
|
||||
WEAPON::SET_PED_INFINITE_AMMO(self::ped, TRUE, NULL);
|
||||
}
|
||||
|
||||
bLastInfiniteAmmo = g.weapons.infinite_ammo;
|
||||
}
|
||||
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);
|
||||
}
|
@ -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);
|
||||
WEAPON::SET_PED_INFINITE_AMMO_CLIP(self::ped, TRUE);
|
||||
}
|
||||
|
||||
bLastInfiniteMag = g.weapons.infinite_mag;
|
||||
}
|
||||
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);
|
||||
}
|
@ -1,35 +1,17 @@
|
||||
#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{};
|
||||
class no_recoil : looped_command
|
||||
{
|
||||
using looped_command::looped_command;
|
||||
|
||||
bool is_recoil_value_cached(uint32_t hash)
|
||||
{
|
||||
return std::find_if(og_recoil_values.begin(), og_recoil_values.end(), [hash](auto const entry)
|
||||
{
|
||||
return hash == entry.first;
|
||||
}) != og_recoil_values.end();
|
||||
}
|
||||
CWeaponInfo* p_modified_weapon = nullptr;
|
||||
float og_recoil_value = 0.0f;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
float get_recoil_value(uint32_t hash)
|
||||
{
|
||||
return g.weapons.no_recoil
|
||||
? 0.f
|
||||
: get_og_recoil_value(hash);
|
||||
}
|
||||
|
||||
void looped::weapons_no_recoil()
|
||||
virtual void on_tick() override
|
||||
{
|
||||
if (!g_local_player)
|
||||
{
|
||||
@ -39,16 +21,27 @@ namespace big
|
||||
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 (p_modified_weapon != weapon_mgr->m_weapon_info && weapon_mgr->m_weapon_info)
|
||||
{
|
||||
if (!is_recoil_value_cached(cur_weapon_hash))
|
||||
{
|
||||
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);
|
||||
}
|
@ -1,35 +1,17 @@
|
||||
#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)
|
||||
{
|
||||
return hash == entry.first;
|
||||
}) != og_spread_values.end();
|
||||
}
|
||||
CWeaponInfo* p_modified_weapon = nullptr;
|
||||
float og_spread_value = 0.0f;
|
||||
|
||||
float get_og_spread_value(uint32_t hash)
|
||||
{
|
||||
return std::find_if(og_spread_values.begin(), og_spread_values.end(), [hash](auto const entry)
|
||||
{
|
||||
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()
|
||||
virtual void on_tick() override
|
||||
{
|
||||
if (!g_local_player)
|
||||
{
|
||||
@ -39,16 +21,27 @@ namespace big
|
||||
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 (p_modified_weapon != weapon_mgr->m_weapon_info && weapon_mgr->m_weapon_info)
|
||||
{
|
||||
if (!is_spread_value_cached(cur_weapon_hash))
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
weapon_mgr->m_weapon_info->m_accuracy_spread = get_spread_value(cur_weapon_hash);
|
||||
}
|
||||
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);
|
||||
}
|
@ -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()
|
||||
class rapid_fire : looped_command
|
||||
{
|
||||
if (g.weapons.rapid_fire)
|
||||
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))
|
||||
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))
|
||||
{
|
||||
@ -23,5 +25,7 @@ namespace big
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
rapid_fire g_rapid_fire("rapidfire", "Rapid Fire", "Makes your weapon fire insanely fast", g.weapons.rapid_fire);
|
||||
}
|
45
src/backend/looped_command.cpp
Normal file
45
src/backend/looped_command.cpp
Normal 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(); });
|
||||
}
|
||||
}
|
||||
}
|
23
src/backend/looped_command.hpp
Normal file
23
src/backend/looped_command.hpp
Normal 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;
|
||||
}
|
133
src/backend/player_command.cpp
Normal file
133
src/backend/player_command.cpp
Normal 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);
|
||||
});
|
||||
}
|
||||
}
|
33
src/backend/player_command.hpp
Normal file
33
src/backend/player_command.hpp
Normal 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);
|
||||
};
|
||||
}
|
@ -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
|
||||
|
||||
|
@ -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" },
|
||||
|
14
src/core/data/command_access_levels.hpp
Normal file
14
src/core/data/command_access_levels.hpp
Normal 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 (!)" }
|
||||
};
|
||||
}
|
@ -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" }
|
||||
})
|
||||
}
|
||||
|
@ -305,6 +305,12 @@ namespace big
|
||||
std::string spoofed_name = "";
|
||||
bool join_in_sctv_slots = false;
|
||||
|
||||
const char chat_command_prefix = '/';
|
||||
const char chat_output_prefix = '>';
|
||||
|
||||
bool chat_commands = false;
|
||||
CommandAccessLevel chat_command_default_access_level = CommandAccessLevel::FRIENDLY;
|
||||
|
||||
bool kick_chat_spammers = false;
|
||||
bool kick_host_when_forcing_host = false;
|
||||
|
||||
@ -334,7 +340,8 @@ namespace big
|
||||
log_text_messages, decloak_players, force_session_host, force_script_host, player_magnet_enabled,
|
||||
player_magnet_count, is_team, name_spoof_enabled, advertise_menu, spoofed_name, join_in_sctv_slots,
|
||||
kick_chat_spammers, kick_host_when_forcing_host, explosion_karma, damage_karma, disable_traffic,
|
||||
disable_peds, force_thunder, block_ceo_money, randomize_ceo_colors, send_to_apartment_idx, send_to_warehouse_idx)
|
||||
disable_peds, force_thunder, block_ceo_money, randomize_ceo_colors, send_to_apartment_idx, send_to_warehouse_idx,
|
||||
chat_commands, chat_command_default_access_level)
|
||||
} session{};
|
||||
|
||||
struct settings
|
||||
@ -482,7 +489,7 @@ namespace big
|
||||
bool drive_on_water = false;
|
||||
bool horn_boost = false;
|
||||
bool instant_brake = false;
|
||||
bool is_targetable = true;
|
||||
bool block_homing = true;
|
||||
bool ls_customs = false; // don't save this to disk
|
||||
bool seatbelt = false;
|
||||
bool turn_signals = false;
|
||||
@ -496,7 +503,7 @@ namespace big
|
||||
speedo_meter, fly, rainbow_paint, speed_unit, god_mode,
|
||||
proof_bullet, proof_fire, proof_collision, proof_melee, proof_explosion, proof_steam, proof_water, proof_mask,
|
||||
auto_drive_destination, auto_drive_style, auto_drive_speed, auto_turn_signals, boost_behavior,
|
||||
drive_on_water, horn_boost, instant_brake, is_targetable, seatbelt, turn_signals, vehicle_jump,
|
||||
drive_on_water, horn_boost, instant_brake, block_homing, seatbelt, turn_signals, vehicle_jump,
|
||||
keep_vehicle_repaired, no_water_collision, disable_engine_auto_start, change_engine_state_immediately)
|
||||
} vehicle{};
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user