From 80415e7c8e8048d5729a1d3a65ff03e31343324d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Sep 2021 17:27:23 +0000 Subject: [PATCH 1/7] Bump deps/libtommath from `eda0bd6` to `8355b88` Bumps [deps/libtommath](https://github.com/libtom/libtommath) from `eda0bd6` to `8355b88`. - [Release notes](https://github.com/libtom/libtommath/releases) - [Commits](https://github.com/libtom/libtommath/compare/eda0bd6ae5705ab90b866dfb52c5f15c23687f81...8355b88db088e41d6f7e19a8d58d46c9ed0333d3) --- updated-dependencies: - dependency-name: deps/libtommath dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/libtommath | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/libtommath b/deps/libtommath index eda0bd6a..8355b88d 160000 --- a/deps/libtommath +++ b/deps/libtommath @@ -1 +1 @@ -Subproject commit eda0bd6ae5705ab90b866dfb52c5f15c23687f81 +Subproject commit 8355b88db088e41d6f7e19a8d58d46c9ed0333d3 From 6d916ebd47ad53c965a7b9be7da849013fed093d Mon Sep 17 00:00:00 2001 From: FutureRave Date: Tue, 7 Dec 2021 16:10:46 +0000 Subject: [PATCH 2/7] Added god/demigod and fixed ufo --- src/Components/Modules/Command.cpp | 53 +++++++++++++++++++++++++-- src/Components/Modules/Script.cpp | 58 +++++++++++++++++++++++++++--- src/Game/Structs.hpp | 22 ++++++++++++ 3 files changed, 127 insertions(+), 6 deletions(-) diff --git a/src/Components/Modules/Command.cpp b/src/Components/Modules/Command.cpp index 5f23f9a2..30f6be8a 100644 --- a/src/Components/Modules/Command.cpp +++ b/src/Components/Modules/Command.cpp @@ -164,8 +164,11 @@ namespace Components static int toastDurationMedium = 2500; static int toastDurationLong = 5000; - // Disable native noclip command - Utils::Hook::Nop(0x474846, 5); + // Disable native cheat commands + Utils::Hook::Nop(0x474846, 5); // Cmd_Noclip_f + Utils::Hook::Nop(0x474859, 5); // Cmd_UFO_f + Utils::Hook::Nop(0x47480A, 5); // Cmd_God_f + Utils::Hook::Nop(0x47481D, 5); // Cmd_DemiGod_f Command::Add("noclip", [](Command::Params*) { @@ -213,6 +216,52 @@ namespace Components Toast::Show("cardicon_abduction", "Success", "UFO toggled", toastDurationShort); }); + Command::Add("god", [](Command::Params*) + { + int clientNum = Game::CG_GetClientNum(); + if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0) + { + Logger::Print("You are not hosting a match!\n"); + Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); + return; + } + + if (!Dvar::Var("sv_cheats").get()) + { + Logger::Print("Cheats disabled!\n"); + Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); + return; + } + + Game::g_entities[clientNum].flags ^= Game::FL_GODMODE; + + Logger::Print("Godmode toggled\n"); + Toast::Show("cardicon_abduction", "Success", "Godmode toggled", toastDurationShort); + }); + + Command::Add("demigod", [](Command::Params*) + { + int clientNum = Game::CG_GetClientNum(); + if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0) + { + Logger::Print("You are not hosting a match!\n"); + Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); + return; + } + + if (!Dvar::Var("sv_cheats").get()) + { + Logger::Print("Cheats disabled!\n"); + Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); + return; + } + + Game::g_entities[clientNum].flags ^= Game::FL_DEMI_GODMODE; + + Logger::Print("Demigod toggled\n"); + Toast::Show("cardicon_abduction", "Success", "Demigod toggled", toastDurationShort); + }); + Command::Add("setviewpos", [](Command::Params* params) { int clientNum = Game::CG_GetClientNum(); diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index d97c1486..dfd614af 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -636,7 +636,7 @@ namespace Components Script::ScriptStorage.clear(); }); - Script::AddFunction("Noclip", [](Game::scr_entref_t entref) + Script::AddFunction("Noclip", [](Game::scr_entref_t entref) // gsc: Noclip(); { if (entref >= Game::MAX_GENTITIES || Game::g_entities[entref].client == nullptr) { @@ -644,7 +644,7 @@ namespace Components return; } - if (Game::Scr_GetNumParam() == 1 && Game::Scr_GetType(0) == Game::VAR_INTEGER) + if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) { if (Game::Scr_GetInt(0)) { @@ -661,7 +661,7 @@ namespace Components } }); - Script::AddFunction("Ufo", [](Game::scr_entref_t entref) + Script::AddFunction("Ufo", [](Game::scr_entref_t entref) // gsc: Ufo(); { if (entref >= Game::MAX_GENTITIES || Game::g_entities[entref].client == nullptr) { @@ -669,7 +669,7 @@ namespace Components return; } - if (Game::Scr_GetNumParam() == 1 && Game::Scr_GetType(0) == Game::VAR_INTEGER) + if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) { if (Game::Scr_GetInt(0)) { @@ -685,6 +685,56 @@ namespace Components Game::g_entities[entref].client->flags ^= Game::PLAYER_FLAG_UFO; } }); + + Script::AddFunction("God", [](Game::scr_entref_t entref) // gsc: God(); + { + if (entref >= Game::MAX_GENTITIES) + { + Game::Scr_Error(Utils::String::VA("^1God: entity %u is out of bounds\n", entref)); + return; + } + + if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) + { + if (Game::Scr_GetInt(0)) + { + Game::g_entities[entref].flags |= Game::FL_GODMODE; + } + else + { + Game::g_entities[entref].flags &= ~Game::FL_GODMODE; + } + } + else + { + Game::g_entities[entref].flags ^= Game::FL_GODMODE; + } + }); + + Script::AddFunction("Demigod", [](Game::scr_entref_t entref) // gsc: Demigod(); + { + if (entref >= Game::MAX_GENTITIES) + { + Game::Scr_Error(Utils::String::VA("^1Demigod: entity %u is out of bounds\n", entref)); + return; + } + + if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) + { + if (Game::Scr_GetInt(0)) + { + Game::g_entities[entref].flags |= Game::FL_DEMI_GODMODE; + } + else + { + Game::g_entities[entref].flags &= ~Game::FL_DEMI_GODMODE; + } + } + else + { + Game::g_entities[entref].flags ^= Game::FL_DEMI_GODMODE; + } + }); } Script::Script() diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index bb2bd6f3..8a74e54d 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -189,6 +189,28 @@ namespace Game ERR_MAPLOADERRORSUMMARY = 0x7 } errorParm_t; + enum entityFlag + { + FL_GODMODE = 0x1, + FL_DEMI_GODMODE = 0x2, + FL_NOTARGET = 0x4, + FL_NO_KNOCKBACK = 0x8, + FL_NO_RADIUS_DAMAGE = 0x10, + FL_SUPPORTS_LINKTO = 0x1000, + FL_NO_AUTO_ANIM_UPDATE = 0x2000, + FL_GRENADE_TOUCH_DAMAGE = 0x4000, + FL_STABLE_MISSILES = 0x20000, + FL_REPEAT_ANIM_UPDATE = 0x40000, + FL_VEHICLE_TARGET = 0x80000, + FL_GROUND_ENT = 0x100000, + FL_CURSOR_HINT = 0x200000, + FL_MISSILE_ATTRACTOR = 0x800000, + FL_WEAPON_BEING_GRABBED = 0x1000000, + FL_DELETE = 0x2000000, + FL_BOUNCE = 0x4000000, + FL_MOVER_SLIDE = 0x8000000 + }; + struct FxEffectDef; struct pathnode_t; struct pathnode_tree_t; From ed953165087d4b231dfcbf5257467626ba46b503 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Tue, 7 Dec 2021 16:19:40 +0000 Subject: [PATCH 3/7] Fix wording --- src/Components/Modules/Command.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Modules/Command.cpp b/src/Components/Modules/Command.cpp index 30f6be8a..72e21b41 100644 --- a/src/Components/Modules/Command.cpp +++ b/src/Components/Modules/Command.cpp @@ -235,8 +235,8 @@ namespace Components Game::g_entities[clientNum].flags ^= Game::FL_GODMODE; - Logger::Print("Godmode toggled\n"); - Toast::Show("cardicon_abduction", "Success", "Godmode toggled", toastDurationShort); + Logger::Print("God toggled\n"); + Toast::Show("cardicon_abduction", "Success", "God toggled", toastDurationShort); }); Command::Add("demigod", [](Command::Params*) From 86158bddf2643a97b98ba5e792129ef313f43969 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Tue, 7 Dec 2021 16:53:41 +0000 Subject: [PATCH 4/7] Organize cheat commands/gsc in one module --- src/Components/Loader.cpp | 1 + src/Components/Loader.hpp | 1 + src/Components/Modules/Cheats.cpp | 313 +++++++++++++++++++++++++++++ src/Components/Modules/Cheats.hpp | 15 ++ src/Components/Modules/Command.cpp | 146 -------------- src/Components/Modules/Script.cpp | 100 --------- 6 files changed, 330 insertions(+), 246 deletions(-) create mode 100644 src/Components/Modules/Cheats.cpp create mode 100644 src/Components/Modules/Cheats.hpp diff --git a/src/Components/Loader.cpp b/src/Components/Loader.cpp index 3217dcd4..ebb7d99e 100644 --- a/src/Components/Loader.cpp +++ b/src/Components/Loader.cpp @@ -106,6 +106,7 @@ namespace Components Loader::Register(new TextRenderer()); Loader::Register(new Movement()); Loader::Register(new Elevators()); + Loader::Register(new Cheats()); Loader::Register(new Client()); diff --git a/src/Components/Loader.hpp b/src/Components/Loader.hpp index f9d1e6ed..80b6fa6c 100644 --- a/src/Components/Loader.hpp +++ b/src/Components/Loader.hpp @@ -134,6 +134,7 @@ namespace Components #include "Modules/TextRenderer.hpp" #include "Modules/Movement.hpp" #include "Modules/Elevators.hpp" +#include "Modules/Cheats.hpp" #include "Modules/Gamepad.hpp" #include "Modules/Client.hpp" diff --git a/src/Components/Modules/Cheats.cpp b/src/Components/Modules/Cheats.cpp new file mode 100644 index 00000000..b026a7cf --- /dev/null +++ b/src/Components/Modules/Cheats.cpp @@ -0,0 +1,313 @@ +#include "STDInclude.hpp" + +namespace Components +{ + void Cheats::AddCheatCommands() + { + static int toastDurationShort = 1000; + static int toastDurationMedium = 2500; + static int toastDurationLong = 5000; + + Command::Add("noclip", [](Command::Params*) + { + int clientNum = Game::CG_GetClientNum(); + if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0 || !Game::g_entities[clientNum].client) + { + Logger::Print("You are not hosting a match!\n"); + Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); + return; + } + + if (!Dvar::Var("sv_cheats").get()) + { + Logger::Print("Cheats disabled!\n"); + Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); + return; + } + + Game::g_entities[clientNum].client->flags ^= Game::PLAYER_FLAG_NOCLIP; + + Logger::Print("Noclip toggled\n"); + Toast::Show("cardicon_abduction", "Success", "Noclip toggled", toastDurationShort); + }); + + Command::Add("ufo", [](Command::Params*) + { + int clientNum = Game::CG_GetClientNum(); + if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0 || !Game::g_entities[clientNum].client) + { + Logger::Print("You are not hosting a match!\n"); + Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); + return; + } + + if (!Dvar::Var("sv_cheats").get()) + { + Logger::Print("Cheats disabled!\n"); + Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); + return; + } + + Game::g_entities[clientNum].client->flags ^= Game::PLAYER_FLAG_UFO; + + Logger::Print("UFO toggled\n"); + Toast::Show("cardicon_abduction", "Success", "UFO toggled", toastDurationShort); + }); + + Command::Add("god", [](Command::Params*) + { + int clientNum = Game::CG_GetClientNum(); + if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0) + { + Logger::Print("You are not hosting a match!\n"); + Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); + return; + } + + if (!Dvar::Var("sv_cheats").get()) + { + Logger::Print("Cheats disabled!\n"); + Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); + return; + } + + Game::g_entities[clientNum].flags ^= Game::FL_GODMODE; + + Logger::Print("God toggled\n"); + Toast::Show("cardicon_abduction", "Success", "God toggled", toastDurationShort); + }); + + Command::Add("demigod", [](Command::Params*) + { + int clientNum = Game::CG_GetClientNum(); + if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0) + { + Logger::Print("You are not hosting a match!\n"); + Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); + return; + } + + if (!Dvar::Var("sv_cheats").get()) + { + Logger::Print("Cheats disabled!\n"); + Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); + return; + } + + Game::g_entities[clientNum].flags ^= Game::FL_DEMI_GODMODE; + + Logger::Print("Demigod toggled\n"); + Toast::Show("cardicon_abduction", "Success", "Demigod toggled", toastDurationShort); + }); + + Command::Add("notarget", [](Command::Params*) + { + int clientNum = Game::CG_GetClientNum(); + if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0) + { + Logger::Print("You are not hosting a match!\n"); + Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); + return; + } + + if (!Dvar::Var("sv_cheats").get()) + { + Logger::Print("Cheats disabled!\n"); + Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); + return; + } + + Game::g_entities[clientNum].flags ^= Game::FL_NOTARGET; + + Logger::Print("Notarget toggled\n"); + Toast::Show("cardicon_abduction", "Success", "Notarget toggled", toastDurationShort); + }); + + Command::Add("setviewpos", [](Command::Params* params) + { + int clientNum = Game::CG_GetClientNum(); + if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0 || !Game::g_entities[clientNum].client) + { + Logger::Print("You are not hosting a match!\n"); + Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); + return; + } + + if (!Dvar::Var("sv_cheats").get()) + { + Logger::Print("Cheats disabled!\n"); + Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); + return; + } + + if (params->length() != 4 && params->length() != 6) + { + Logger::Print("Invalid coordinate specified!\n"); + Toast::Show("cardicon_stop", "Error", "Invalid coordinate specified!", toastDurationMedium); + return; + } + + float pos[3] = { 0.0f, 0.0f, 0.0f }; + float orientation[3] = { 0.0f, 0.0f, 0.0f }; + + pos[0] = strtof(params->get(1), nullptr); + pos[1] = strtof(params->get(2), nullptr); + pos[2] = strtof(params->get(3), nullptr); + + if (params->length() == 6) + { + orientation[0] = strtof(params->get(4), nullptr); + orientation[1] = strtof(params->get(5), nullptr); + } + + Game::TeleportPlayer(&Game::g_entities[clientNum], pos, orientation); + + // Logging will spam the console and screen if people use cinematics + }); + } + + void Cheats::AddScriptFunctions() + { + Script::AddFunction("Noclip", [](Game::scr_entref_t entref) // gsc: Noclip(); + { + if (entref >= Game::MAX_GENTITIES || Game::g_entities[entref].client == nullptr) + { + Game::Scr_Error(Utils::String::VA("^1NoClip: entity %u is not a client\n", entref)); + return; + } + + if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) + { + if (Game::Scr_GetInt(0)) + { + Game::g_entities[entref].client->flags |= Game::PLAYER_FLAG_NOCLIP; + } + else + { + Game::g_entities[entref].client->flags &= ~Game::PLAYER_FLAG_NOCLIP; + } + } + else + { + Game::g_entities[entref].client->flags ^= Game::PLAYER_FLAG_NOCLIP; + } + }); + + Script::AddFunction("Ufo", [](Game::scr_entref_t entref) // gsc: Ufo(); + { + if (entref >= Game::MAX_GENTITIES || Game::g_entities[entref].client == nullptr) + { + Game::Scr_Error(Utils::String::VA("^1Ufo: entity %u is not a client\n", entref)); + return; + } + + if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) + { + if (Game::Scr_GetInt(0)) + { + Game::g_entities[entref].client->flags |= Game::PLAYER_FLAG_UFO; + } + else + { + Game::g_entities[entref].client->flags &= ~Game::PLAYER_FLAG_UFO; + } + } + else + { + Game::g_entities[entref].client->flags ^= Game::PLAYER_FLAG_UFO; + } + }); + + Script::AddFunction("God", [](Game::scr_entref_t entref) // gsc: God(); + { + if (entref >= Game::MAX_GENTITIES) + { + Game::Scr_Error(Utils::String::VA("^1God: entity %u is out of bounds\n", entref)); + return; + } + + if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) + { + if (Game::Scr_GetInt(0)) + { + Game::g_entities[entref].flags |= Game::FL_GODMODE; + } + else + { + Game::g_entities[entref].flags &= ~Game::FL_GODMODE; + } + } + else + { + Game::g_entities[entref].flags ^= Game::FL_GODMODE; + } + }); + + Script::AddFunction("Demigod", [](Game::scr_entref_t entref) // gsc: Demigod(); + { + if (entref >= Game::MAX_GENTITIES) + { + Game::Scr_Error(Utils::String::VA("^1Demigod: entity %u is out of bounds\n", entref)); + return; + } + + if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) + { + if (Game::Scr_GetInt(0)) + { + Game::g_entities[entref].flags |= Game::FL_DEMI_GODMODE; + } + else + { + Game::g_entities[entref].flags &= ~Game::FL_DEMI_GODMODE; + } + } + else + { + Game::g_entities[entref].flags ^= Game::FL_DEMI_GODMODE; + } + }); + + Script::AddFunction("Notarget", [](Game::scr_entref_t entref) // gsc: Demigod(); + { + if (entref >= Game::MAX_GENTITIES) + { + Game::Scr_Error(Utils::String::VA("^1Notarget: entity %u is out of bounds\n", entref)); + return; + } + + if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) + { + if (Game::Scr_GetInt(0)) + { + Game::g_entities[entref].flags |= Game::FL_NOTARGET; + } + else + { + Game::g_entities[entref].flags &= ~Game::FL_NOTARGET; + } + } + else + { + Game::g_entities[entref].flags ^= Game::FL_NOTARGET; + } + }); + } + + Cheats::Cheats() + { + // Disable native cheat commands + Utils::Hook::Nop(0x474846, 5); // Cmd_Noclip_f + Utils::Hook::Nop(0x474859, 5); // Cmd_UFO_f + Utils::Hook::Nop(0x47480A, 5); // Cmd_God_f + Utils::Hook::Nop(0x47481D, 5); // Cmd_DemiGod_f + Utils::Hook::Nop(0x474833, 5); // Cmd_Notarget_f + + Cheats::AddCheatCommands(); + Cheats::AddScriptFunctions(); + } + + Cheats::~Cheats() + { + } +} diff --git a/src/Components/Modules/Cheats.hpp b/src/Components/Modules/Cheats.hpp new file mode 100644 index 00000000..c86762e9 --- /dev/null +++ b/src/Components/Modules/Cheats.hpp @@ -0,0 +1,15 @@ +#pragma once + +namespace Components +{ + class Cheats : public Component + { + public: + Cheats(); + ~Cheats(); + + private: + static void AddCheatCommands(); + static void AddScriptFunctions(); + }; +} diff --git a/src/Components/Modules/Command.cpp b/src/Components/Modules/Command.cpp index 72e21b41..49aa6745 100644 --- a/src/Components/Modules/Command.cpp +++ b/src/Components/Modules/Command.cpp @@ -160,152 +160,6 @@ namespace Components { AssertSize(Game::cmd_function_t, 24); - static int toastDurationShort = 1000; - static int toastDurationMedium = 2500; - static int toastDurationLong = 5000; - - // Disable native cheat commands - Utils::Hook::Nop(0x474846, 5); // Cmd_Noclip_f - Utils::Hook::Nop(0x474859, 5); // Cmd_UFO_f - Utils::Hook::Nop(0x47480A, 5); // Cmd_God_f - Utils::Hook::Nop(0x47481D, 5); // Cmd_DemiGod_f - - Command::Add("noclip", [](Command::Params*) - { - int clientNum = Game::CG_GetClientNum(); - if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0 || !Game::g_entities[clientNum].client) - { - Logger::Print("You are not hosting a match!\n"); - Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); - return; - } - - if (!Dvar::Var("sv_cheats").get()) - { - Logger::Print("Cheats disabled!\n"); - Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); - return; - } - - Game::g_entities[clientNum].client->flags ^= Game::PLAYER_FLAG_NOCLIP; - - Logger::Print("Noclip toggled\n"); - Toast::Show("cardicon_abduction", "Success", "Noclip toggled", toastDurationShort); - }); - - Command::Add("ufo", [](Command::Params*) - { - int clientNum = Game::CG_GetClientNum(); - if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0 || !Game::g_entities[clientNum].client) - { - Logger::Print("You are not hosting a match!\n"); - Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); - return; - } - - if (!Dvar::Var("sv_cheats").get()) - { - Logger::Print("Cheats disabled!\n"); - Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); - return; - } - - Game::g_entities[clientNum].client->flags ^= Game::PLAYER_FLAG_UFO; - - Logger::Print("UFO toggled\n"); - Toast::Show("cardicon_abduction", "Success", "UFO toggled", toastDurationShort); - }); - - Command::Add("god", [](Command::Params*) - { - int clientNum = Game::CG_GetClientNum(); - if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0) - { - Logger::Print("You are not hosting a match!\n"); - Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); - return; - } - - if (!Dvar::Var("sv_cheats").get()) - { - Logger::Print("Cheats disabled!\n"); - Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); - return; - } - - Game::g_entities[clientNum].flags ^= Game::FL_GODMODE; - - Logger::Print("God toggled\n"); - Toast::Show("cardicon_abduction", "Success", "God toggled", toastDurationShort); - }); - - Command::Add("demigod", [](Command::Params*) - { - int clientNum = Game::CG_GetClientNum(); - if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0) - { - Logger::Print("You are not hosting a match!\n"); - Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); - return; - } - - if (!Dvar::Var("sv_cheats").get()) - { - Logger::Print("Cheats disabled!\n"); - Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); - return; - } - - Game::g_entities[clientNum].flags ^= Game::FL_DEMI_GODMODE; - - Logger::Print("Demigod toggled\n"); - Toast::Show("cardicon_abduction", "Success", "Demigod toggled", toastDurationShort); - }); - - Command::Add("setviewpos", [](Command::Params* params) - { - int clientNum = Game::CG_GetClientNum(); - if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0 || !Game::g_entities[clientNum].client) - { - Logger::Print("You are not hosting a match!\n"); - Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); - return; - } - - if (!Dvar::Var("sv_cheats").get()) - { - Logger::Print("Cheats disabled!\n"); - Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); - return; - } - - if (params->length() != 4 && params->length() != 6) - { - Logger::Print("Invalid coordinate specified!\n"); - Toast::Show("cardicon_stop", "Error", "Invalid coordinate specified!", toastDurationMedium); - return; - } - - float pos[3] = { 0.0f, 0.0f, 0.0f }; - float orientation[3] = { 0.0f, 0.0f, 0.0f }; - - pos[0] = strtof(params->get(1), nullptr); - pos[1] = strtof(params->get(2), nullptr); - pos[2] = strtof(params->get(3), nullptr); - - if (params->length() == 6) - { - orientation[0] = strtof(params->get(4), nullptr); - orientation[1] = strtof(params->get(5), nullptr); - } - - Game::TeleportPlayer(&Game::g_entities[clientNum], pos, orientation); - - //Logging that will spam the console and screen if people use cinematics - //Logger::Print("Successfully teleported player!\n"); - //Toast::Show("cardicon_abduction", "Success", "You have been teleported!", toastDurationShort); - }); - Command::Add("openLink", [](Command::Params* params) { if (params->length() > 1) diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index dfd614af..343ae06a 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -635,106 +635,6 @@ namespace Components { Script::ScriptStorage.clear(); }); - - Script::AddFunction("Noclip", [](Game::scr_entref_t entref) // gsc: Noclip(); - { - if (entref >= Game::MAX_GENTITIES || Game::g_entities[entref].client == nullptr) - { - Game::Scr_Error(Utils::String::VA("^1NoClip: entity %u is not a client\n", entref)); - return; - } - - if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) - { - if (Game::Scr_GetInt(0)) - { - Game::g_entities[entref].client->flags |= Game::PLAYER_FLAG_NOCLIP; - } - else - { - Game::g_entities[entref].client->flags &= ~Game::PLAYER_FLAG_NOCLIP; - } - } - else - { - Game::g_entities[entref].client->flags ^= Game::PLAYER_FLAG_NOCLIP; - } - }); - - Script::AddFunction("Ufo", [](Game::scr_entref_t entref) // gsc: Ufo(); - { - if (entref >= Game::MAX_GENTITIES || Game::g_entities[entref].client == nullptr) - { - Game::Scr_Error(Utils::String::VA("^1Ufo: entity %u is not a client\n", entref)); - return; - } - - if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) - { - if (Game::Scr_GetInt(0)) - { - Game::g_entities[entref].client->flags |= Game::PLAYER_FLAG_UFO; - } - else - { - Game::g_entities[entref].client->flags &= ~Game::PLAYER_FLAG_UFO; - } - } - else - { - Game::g_entities[entref].client->flags ^= Game::PLAYER_FLAG_UFO; - } - }); - - Script::AddFunction("God", [](Game::scr_entref_t entref) // gsc: God(); - { - if (entref >= Game::MAX_GENTITIES) - { - Game::Scr_Error(Utils::String::VA("^1God: entity %u is out of bounds\n", entref)); - return; - } - - if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) - { - if (Game::Scr_GetInt(0)) - { - Game::g_entities[entref].flags |= Game::FL_GODMODE; - } - else - { - Game::g_entities[entref].flags &= ~Game::FL_GODMODE; - } - } - else - { - Game::g_entities[entref].flags ^= Game::FL_GODMODE; - } - }); - - Script::AddFunction("Demigod", [](Game::scr_entref_t entref) // gsc: Demigod(); - { - if (entref >= Game::MAX_GENTITIES) - { - Game::Scr_Error(Utils::String::VA("^1Demigod: entity %u is out of bounds\n", entref)); - return; - } - - if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) - { - if (Game::Scr_GetInt(0)) - { - Game::g_entities[entref].flags |= Game::FL_DEMI_GODMODE; - } - else - { - Game::g_entities[entref].flags &= ~Game::FL_DEMI_GODMODE; - } - } - else - { - Game::g_entities[entref].flags ^= Game::FL_DEMI_GODMODE; - } - }); } Script::Script() From ff1584cff0a5a0d924e57071bd014bd96a315372 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Tue, 7 Dec 2021 17:47:31 +0000 Subject: [PATCH 5/7] Fix comment --- src/Components/Modules/Cheats.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Modules/Cheats.cpp b/src/Components/Modules/Cheats.cpp index b026a7cf..1e9bab62 100644 --- a/src/Components/Modules/Cheats.cpp +++ b/src/Components/Modules/Cheats.cpp @@ -268,7 +268,7 @@ namespace Components } }); - Script::AddFunction("Notarget", [](Game::scr_entref_t entref) // gsc: Demigod(); + Script::AddFunction("Notarget", [](Game::scr_entref_t entref) // gsc: Notarget(); { if (entref >= Game::MAX_GENTITIES) { From 86f0242a3d47af94a4cd701b96a4770dc1ee403f Mon Sep 17 00:00:00 2001 From: FutureRave Date: Thu, 9 Dec 2021 12:01:37 +0000 Subject: [PATCH 6/7] Reimplement clientcommand like in debug builds --- src/Components/Loader.cpp | 2 +- src/Components/Loader.hpp | 2 +- src/Components/Modules/Cheats.cpp | 313 ----------------------- src/Components/Modules/Cheats.hpp | 15 -- src/Components/Modules/ClientCommand.cpp | 291 +++++++++++++++++++++ src/Components/Modules/ClientCommand.hpp | 24 ++ src/Components/Modules/Command.cpp | 46 ++++ src/Game/Functions.cpp | 1 + src/Game/Functions.hpp | 3 + 9 files changed, 367 insertions(+), 330 deletions(-) delete mode 100644 src/Components/Modules/Cheats.cpp delete mode 100644 src/Components/Modules/Cheats.hpp create mode 100644 src/Components/Modules/ClientCommand.cpp create mode 100644 src/Components/Modules/ClientCommand.hpp diff --git a/src/Components/Loader.cpp b/src/Components/Loader.cpp index ebb7d99e..ec1f5dea 100644 --- a/src/Components/Loader.cpp +++ b/src/Components/Loader.cpp @@ -106,7 +106,7 @@ namespace Components Loader::Register(new TextRenderer()); Loader::Register(new Movement()); Loader::Register(new Elevators()); - Loader::Register(new Cheats()); + Loader::Register(new ClientCommand()); Loader::Register(new Client()); diff --git a/src/Components/Loader.hpp b/src/Components/Loader.hpp index 80b6fa6c..ba7eef63 100644 --- a/src/Components/Loader.hpp +++ b/src/Components/Loader.hpp @@ -134,7 +134,7 @@ namespace Components #include "Modules/TextRenderer.hpp" #include "Modules/Movement.hpp" #include "Modules/Elevators.hpp" -#include "Modules/Cheats.hpp" +#include "Modules/ClientCommand.hpp" #include "Modules/Gamepad.hpp" #include "Modules/Client.hpp" diff --git a/src/Components/Modules/Cheats.cpp b/src/Components/Modules/Cheats.cpp deleted file mode 100644 index 1e9bab62..00000000 --- a/src/Components/Modules/Cheats.cpp +++ /dev/null @@ -1,313 +0,0 @@ -#include "STDInclude.hpp" - -namespace Components -{ - void Cheats::AddCheatCommands() - { - static int toastDurationShort = 1000; - static int toastDurationMedium = 2500; - static int toastDurationLong = 5000; - - Command::Add("noclip", [](Command::Params*) - { - int clientNum = Game::CG_GetClientNum(); - if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0 || !Game::g_entities[clientNum].client) - { - Logger::Print("You are not hosting a match!\n"); - Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); - return; - } - - if (!Dvar::Var("sv_cheats").get()) - { - Logger::Print("Cheats disabled!\n"); - Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); - return; - } - - Game::g_entities[clientNum].client->flags ^= Game::PLAYER_FLAG_NOCLIP; - - Logger::Print("Noclip toggled\n"); - Toast::Show("cardicon_abduction", "Success", "Noclip toggled", toastDurationShort); - }); - - Command::Add("ufo", [](Command::Params*) - { - int clientNum = Game::CG_GetClientNum(); - if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0 || !Game::g_entities[clientNum].client) - { - Logger::Print("You are not hosting a match!\n"); - Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); - return; - } - - if (!Dvar::Var("sv_cheats").get()) - { - Logger::Print("Cheats disabled!\n"); - Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); - return; - } - - Game::g_entities[clientNum].client->flags ^= Game::PLAYER_FLAG_UFO; - - Logger::Print("UFO toggled\n"); - Toast::Show("cardicon_abduction", "Success", "UFO toggled", toastDurationShort); - }); - - Command::Add("god", [](Command::Params*) - { - int clientNum = Game::CG_GetClientNum(); - if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0) - { - Logger::Print("You are not hosting a match!\n"); - Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); - return; - } - - if (!Dvar::Var("sv_cheats").get()) - { - Logger::Print("Cheats disabled!\n"); - Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); - return; - } - - Game::g_entities[clientNum].flags ^= Game::FL_GODMODE; - - Logger::Print("God toggled\n"); - Toast::Show("cardicon_abduction", "Success", "God toggled", toastDurationShort); - }); - - Command::Add("demigod", [](Command::Params*) - { - int clientNum = Game::CG_GetClientNum(); - if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0) - { - Logger::Print("You are not hosting a match!\n"); - Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); - return; - } - - if (!Dvar::Var("sv_cheats").get()) - { - Logger::Print("Cheats disabled!\n"); - Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); - return; - } - - Game::g_entities[clientNum].flags ^= Game::FL_DEMI_GODMODE; - - Logger::Print("Demigod toggled\n"); - Toast::Show("cardicon_abduction", "Success", "Demigod toggled", toastDurationShort); - }); - - Command::Add("notarget", [](Command::Params*) - { - int clientNum = Game::CG_GetClientNum(); - if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0) - { - Logger::Print("You are not hosting a match!\n"); - Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); - return; - } - - if (!Dvar::Var("sv_cheats").get()) - { - Logger::Print("Cheats disabled!\n"); - Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); - return; - } - - Game::g_entities[clientNum].flags ^= Game::FL_NOTARGET; - - Logger::Print("Notarget toggled\n"); - Toast::Show("cardicon_abduction", "Success", "Notarget toggled", toastDurationShort); - }); - - Command::Add("setviewpos", [](Command::Params* params) - { - int clientNum = Game::CG_GetClientNum(); - if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0 || !Game::g_entities[clientNum].client) - { - Logger::Print("You are not hosting a match!\n"); - Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); - return; - } - - if (!Dvar::Var("sv_cheats").get()) - { - Logger::Print("Cheats disabled!\n"); - Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); - return; - } - - if (params->length() != 4 && params->length() != 6) - { - Logger::Print("Invalid coordinate specified!\n"); - Toast::Show("cardicon_stop", "Error", "Invalid coordinate specified!", toastDurationMedium); - return; - } - - float pos[3] = { 0.0f, 0.0f, 0.0f }; - float orientation[3] = { 0.0f, 0.0f, 0.0f }; - - pos[0] = strtof(params->get(1), nullptr); - pos[1] = strtof(params->get(2), nullptr); - pos[2] = strtof(params->get(3), nullptr); - - if (params->length() == 6) - { - orientation[0] = strtof(params->get(4), nullptr); - orientation[1] = strtof(params->get(5), nullptr); - } - - Game::TeleportPlayer(&Game::g_entities[clientNum], pos, orientation); - - // Logging will spam the console and screen if people use cinematics - }); - } - - void Cheats::AddScriptFunctions() - { - Script::AddFunction("Noclip", [](Game::scr_entref_t entref) // gsc: Noclip(); - { - if (entref >= Game::MAX_GENTITIES || Game::g_entities[entref].client == nullptr) - { - Game::Scr_Error(Utils::String::VA("^1NoClip: entity %u is not a client\n", entref)); - return; - } - - if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) - { - if (Game::Scr_GetInt(0)) - { - Game::g_entities[entref].client->flags |= Game::PLAYER_FLAG_NOCLIP; - } - else - { - Game::g_entities[entref].client->flags &= ~Game::PLAYER_FLAG_NOCLIP; - } - } - else - { - Game::g_entities[entref].client->flags ^= Game::PLAYER_FLAG_NOCLIP; - } - }); - - Script::AddFunction("Ufo", [](Game::scr_entref_t entref) // gsc: Ufo(); - { - if (entref >= Game::MAX_GENTITIES || Game::g_entities[entref].client == nullptr) - { - Game::Scr_Error(Utils::String::VA("^1Ufo: entity %u is not a client\n", entref)); - return; - } - - if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) - { - if (Game::Scr_GetInt(0)) - { - Game::g_entities[entref].client->flags |= Game::PLAYER_FLAG_UFO; - } - else - { - Game::g_entities[entref].client->flags &= ~Game::PLAYER_FLAG_UFO; - } - } - else - { - Game::g_entities[entref].client->flags ^= Game::PLAYER_FLAG_UFO; - } - }); - - Script::AddFunction("God", [](Game::scr_entref_t entref) // gsc: God(); - { - if (entref >= Game::MAX_GENTITIES) - { - Game::Scr_Error(Utils::String::VA("^1God: entity %u is out of bounds\n", entref)); - return; - } - - if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) - { - if (Game::Scr_GetInt(0)) - { - Game::g_entities[entref].flags |= Game::FL_GODMODE; - } - else - { - Game::g_entities[entref].flags &= ~Game::FL_GODMODE; - } - } - else - { - Game::g_entities[entref].flags ^= Game::FL_GODMODE; - } - }); - - Script::AddFunction("Demigod", [](Game::scr_entref_t entref) // gsc: Demigod(); - { - if (entref >= Game::MAX_GENTITIES) - { - Game::Scr_Error(Utils::String::VA("^1Demigod: entity %u is out of bounds\n", entref)); - return; - } - - if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) - { - if (Game::Scr_GetInt(0)) - { - Game::g_entities[entref].flags |= Game::FL_DEMI_GODMODE; - } - else - { - Game::g_entities[entref].flags &= ~Game::FL_DEMI_GODMODE; - } - } - else - { - Game::g_entities[entref].flags ^= Game::FL_DEMI_GODMODE; - } - }); - - Script::AddFunction("Notarget", [](Game::scr_entref_t entref) // gsc: Notarget(); - { - if (entref >= Game::MAX_GENTITIES) - { - Game::Scr_Error(Utils::String::VA("^1Notarget: entity %u is out of bounds\n", entref)); - return; - } - - if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) - { - if (Game::Scr_GetInt(0)) - { - Game::g_entities[entref].flags |= Game::FL_NOTARGET; - } - else - { - Game::g_entities[entref].flags &= ~Game::FL_NOTARGET; - } - } - else - { - Game::g_entities[entref].flags ^= Game::FL_NOTARGET; - } - }); - } - - Cheats::Cheats() - { - // Disable native cheat commands - Utils::Hook::Nop(0x474846, 5); // Cmd_Noclip_f - Utils::Hook::Nop(0x474859, 5); // Cmd_UFO_f - Utils::Hook::Nop(0x47480A, 5); // Cmd_God_f - Utils::Hook::Nop(0x47481D, 5); // Cmd_DemiGod_f - Utils::Hook::Nop(0x474833, 5); // Cmd_Notarget_f - - Cheats::AddCheatCommands(); - Cheats::AddScriptFunctions(); - } - - Cheats::~Cheats() - { - } -} diff --git a/src/Components/Modules/Cheats.hpp b/src/Components/Modules/Cheats.hpp deleted file mode 100644 index c86762e9..00000000 --- a/src/Components/Modules/Cheats.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -namespace Components -{ - class Cheats : public Component - { - public: - Cheats(); - ~Cheats(); - - private: - static void AddCheatCommands(); - static void AddScriptFunctions(); - }; -} diff --git a/src/Components/Modules/ClientCommand.cpp b/src/Components/Modules/ClientCommand.cpp new file mode 100644 index 00000000..39e14071 --- /dev/null +++ b/src/Components/Modules/ClientCommand.cpp @@ -0,0 +1,291 @@ +#include "STDInclude.hpp" + +namespace Components +{ + std::unordered_map> ClientCommand::FunctionMap; + + unsigned int ClientCommand::GetEntityNum(const Game::gentity_s* ent) + { + unsigned int num; + + num = ent - Game::g_entities; + + return num; + } + + bool ClientCommand::CheatsOk(const Game::gentity_s* ent) + { + const auto entNum = ClientCommand::GetEntityNum(ent); + + if (!Dvar::Var("sv_cheats").get()) + { + Logger::Print("Cheats disabled!\n"); + Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"GAME_CHEATSNOTENABLED\"", 0x65)); + return false; + } + + if (ent->health < 1) + { + Logger::Print("Entity %u must be alive to use this command!\n", entNum); + Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"GAME_MUSTBEALIVECOMMAND\"", 0x65)); + return false; + } + + return true; + } + + bool ClientCommand::CallbackHandler(Game::gentity_s* ent, const char* cmd) + { + const auto command = Utils::String::ToLower(cmd); + + if (ClientCommand::FunctionMap.find(command) != ClientCommand::FunctionMap.end()) + { + ClientCommand::FunctionMap[command](ent); + return true; + } + + return false; + } + + void ClientCommand::Add(const char* name, Utils::Slot callback) + { + const auto command = Utils::String::ToLower(name); + + ClientCommand::FunctionMap[command] = callback; + } + + void ClientCommand::ClientCommandStub(const int clientNum) + { + char cmd[1024]{}; + const auto entity = &Game::g_entities[clientNum]; + + if (entity->client == nullptr) + { + Logger::Print("Client %d is not fully in game yet\n", clientNum); + return; + } + + Game::SV_Cmd_ArgvBuffer(0, cmd, sizeof(cmd)); + + if (!ClientCommand::CallbackHandler(entity, cmd)) + { + // If no callback was found call original game function + Utils::Hook::Call(0x416790)(clientNum); + } + } + + void ClientCommand::AddCheatCommands() + { + ClientCommand::Add("noclip", [](Game::gentity_s* ent) + { + if (!ClientCommand::CheatsOk(ent)) + return; + + ent->client->flags ^= Game::PLAYER_FLAG_NOCLIP; + + const auto entNum = ClientCommand::GetEntityNum(ent); + Logger::Print("Noclip toggled for entity %u\n", entNum); + + Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65, + (ent->client->flags & Game::PLAYER_FLAG_NOCLIP) ? "GAME_NOCLIPON" : "GAME_NOCLIPOFF")); + }); + + ClientCommand::Add("ufo", [](Game::gentity_s* ent) + { + if (!ClientCommand::CheatsOk(ent)) + return; + + ent->client->flags ^= Game::PLAYER_FLAG_UFO; + + const auto entNum = ClientCommand::GetEntityNum(ent); + Logger::Print("UFO toggled for entity %u\n", entNum); + + Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65, + (ent->client->flags & Game::PLAYER_FLAG_UFO) ? "GAME_UFOON" : "GAME_UFOOFF")); + }); + + ClientCommand::Add("god", [](Game::gentity_s* ent) + { + if (!ClientCommand::CheatsOk(ent)) + return; + + ent->flags ^= Game::FL_GODMODE; + + const auto entNum = ClientCommand::GetEntityNum(ent); + Logger::Print("God toggled for entity %u\n", entNum); + + Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65, + (ent->flags & Game::FL_GODMODE) ? "GAME_GODMODE_ON" : "GAME_GODMODE_OFF")); + }); + + ClientCommand::Add("demigod", [](Game::gentity_s* ent) + { + if (!ClientCommand::CheatsOk(ent)) + return; + + ent->flags ^= Game::FL_DEMI_GODMODE; + + const auto entNum = ClientCommand::GetEntityNum(ent); + Logger::Print("Demigod toggled for entity %u\n", entNum); + + Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65, + (ent->flags & Game::FL_DEMI_GODMODE) ? "GAME_DEMI_GODMODE_ON" : "GAME_DEMI_GODMODE_OFF")); + }); + + ClientCommand::Add("notarget", [](Game::gentity_s* ent) + { + if (!ClientCommand::CheatsOk(ent)) + return; + + ent->flags ^= Game::FL_NOTARGET; + + const auto entNum = ClientCommand::GetEntityNum(ent); + Logger::Print("Notarget toggled for entity %u\n", entNum); + + Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65, + (ent->flags & Game::FL_NOTARGET) ? "GAME_NOTARGETON" : "GAME_NOTARGETOFF")); + }); + } + + void ClientCommand::AddScriptFunctions() + { + Script::AddFunction("Noclip", [](Game::scr_entref_t entref) // gsc: Noclip(); + { + if (entref >= Game::MAX_GENTITIES || Game::g_entities[entref].client == nullptr) + { + Game::Scr_Error(Utils::String::VA("^1NoClip: entity %u is not a client\n", entref)); + return; + } + + if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) + { + if (Game::Scr_GetInt(0)) + { + Game::g_entities[entref].client->flags |= Game::PLAYER_FLAG_NOCLIP; + } + else + { + Game::g_entities[entref].client->flags &= ~Game::PLAYER_FLAG_NOCLIP; + } + } + else + { + Game::g_entities[entref].client->flags ^= Game::PLAYER_FLAG_NOCLIP; + } + }); + + Script::AddFunction("Ufo", [](Game::scr_entref_t entref) // gsc: Ufo(); + { + if (entref >= Game::MAX_GENTITIES || Game::g_entities[entref].client == nullptr) + { + Game::Scr_Error(Utils::String::VA("^1Ufo: entity %u is not a client\n", entref)); + return; + } + + if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) + { + if (Game::Scr_GetInt(0)) + { + Game::g_entities[entref].client->flags |= Game::PLAYER_FLAG_UFO; + } + else + { + Game::g_entities[entref].client->flags &= ~Game::PLAYER_FLAG_UFO; + } + } + else + { + Game::g_entities[entref].client->flags ^= Game::PLAYER_FLAG_UFO; + } + }); + + Script::AddFunction("God", [](Game::scr_entref_t entref) // gsc: God(); + { + if (entref >= Game::MAX_GENTITIES) + { + Game::Scr_Error(Utils::String::VA("^1God: entity %u is out of bounds\n", entref)); + return; + } + + if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) + { + if (Game::Scr_GetInt(0)) + { + Game::g_entities[entref].flags |= Game::FL_GODMODE; + } + else + { + Game::g_entities[entref].flags &= ~Game::FL_GODMODE; + } + } + else + { + Game::g_entities[entref].flags ^= Game::FL_GODMODE; + } + }); + + Script::AddFunction("Demigod", [](Game::scr_entref_t entref) // gsc: Demigod(); + { + if (entref >= Game::MAX_GENTITIES) + { + Game::Scr_Error(Utils::String::VA("^1Demigod: entity %u is out of bounds\n", entref)); + return; + } + + if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) + { + if (Game::Scr_GetInt(0)) + { + Game::g_entities[entref].flags |= Game::FL_DEMI_GODMODE; + } + else + { + Game::g_entities[entref].flags &= ~Game::FL_DEMI_GODMODE; + } + } + else + { + Game::g_entities[entref].flags ^= Game::FL_DEMI_GODMODE; + } + }); + + Script::AddFunction("Notarget", [](Game::scr_entref_t entref) // gsc: Notarget(); + { + if (entref >= Game::MAX_GENTITIES) + { + Game::Scr_Error(Utils::String::VA("^1Notarget: entity %u is out of bounds\n", entref)); + return; + } + + if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER) + { + if (Game::Scr_GetInt(0)) + { + Game::g_entities[entref].flags |= Game::FL_NOTARGET; + } + else + { + Game::g_entities[entref].flags &= ~Game::FL_NOTARGET; + } + } + else + { + Game::g_entities[entref].flags ^= Game::FL_NOTARGET; + } + }); + } + + ClientCommand::ClientCommand() + { + //SV_ExecuteClientCommand + Utils::Hook(0x6259FA, ClientCommand::ClientCommandStub, HOOK_CALL).install()->quick(); + + ClientCommand::AddCheatCommands(); + ClientCommand::AddScriptFunctions(); + } + + ClientCommand::~ClientCommand() + { + ClientCommand::FunctionMap.clear(); + } +} diff --git a/src/Components/Modules/ClientCommand.hpp b/src/Components/Modules/ClientCommand.hpp new file mode 100644 index 00000000..643aa847 --- /dev/null +++ b/src/Components/Modules/ClientCommand.hpp @@ -0,0 +1,24 @@ +#pragma once + +namespace Components +{ + class ClientCommand : public Component + { + public: + typedef void(Callback)(Game::gentity_s* entity); + + ClientCommand(); + ~ClientCommand(); + static void Add(const char* name, Utils::Slot callback); + static unsigned int GetEntityNum(const Game::gentity_s* ent); + static bool CheatsOk(const Game::gentity_s* ent); + + private: + static std::unordered_map> FunctionMap; + + static bool CallbackHandler(Game::gentity_s* ent, const char* cmd); + static void ClientCommandStub(const int clientNum); + static void AddCheatCommands(); + static void AddScriptFunctions(); + }; +} diff --git a/src/Components/Modules/Command.cpp b/src/Components/Modules/Command.cpp index 49aa6745..52a1b3fc 100644 --- a/src/Components/Modules/Command.cpp +++ b/src/Components/Modules/Command.cpp @@ -160,6 +160,52 @@ namespace Components { AssertSize(Game::cmd_function_t, 24); + static int toastDurationShort = 1000; + static int toastDurationMedium = 2500; + static int toastDurationLong = 5000; + + Command::Add("setviewpos", [](Command::Params* params) + { + int clientNum = Game::CG_GetClientNum(); + if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0 || !Game::g_entities[clientNum].client) + { + Logger::Print("You are not hosting a match!\n"); + Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium); + return; + } + + if (!Dvar::Var("sv_cheats").get()) + { + Logger::Print("Cheats disabled!\n"); + Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium); + return; + } + + if (params->length() != 4 && params->length() != 6) + { + Logger::Print("Invalid coordinate specified!\n"); + Toast::Show("cardicon_stop", "Error", "Invalid coordinate specified!", toastDurationMedium); + return; + } + + float pos[3] = { 0.0f, 0.0f, 0.0f }; + float orientation[3] = { 0.0f, 0.0f, 0.0f }; + + pos[0] = strtof(params->get(1), nullptr); + pos[1] = strtof(params->get(2), nullptr); + pos[2] = strtof(params->get(3), nullptr); + + if (params->length() == 6) + { + orientation[0] = strtof(params->get(4), nullptr); + orientation[1] = strtof(params->get(5), nullptr); + } + + Game::TeleportPlayer(&Game::g_entities[clientNum], pos, orientation); + + // Logging will spam the console and screen if people use cinematics + }); + Command::Add("openLink", [](Command::Params* params) { if (params->length() > 1) diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index d61e41fa..d66a4154 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -314,6 +314,7 @@ namespace Game SV_GameSendServerCommand_t SV_GameSendServerCommand = SV_GameSendServerCommand_t(0x4BC3A0); SV_Cmd_TokenizeString_t SV_Cmd_TokenizeString = SV_Cmd_TokenizeString_t(0x4B5780); SV_Cmd_EndTokenizedString_t SV_Cmd_EndTokenizedString = SV_Cmd_EndTokenizedString_t(0x464750); + SV_Cmd_ArgvBuffer_t SV_Cmd_ArgvBuffer = SV_Cmd_ArgvBuffer_t(0x40BB60); SV_DirectConnect_t SV_DirectConnect = SV_DirectConnect_t(0x460480); SV_SetConfigstring_t SV_SetConfigstring = SV_SetConfigstring_t(0x4982E0); SV_Loaded_t SV_Loaded = SV_Loaded_t(0x4EE3E0); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 2f2ef11b..71d05275 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -750,6 +750,9 @@ namespace Game typedef void(__cdecl * SV_Cmd_EndTokenizedString_t)(); extern SV_Cmd_EndTokenizedString_t SV_Cmd_EndTokenizedString; + typedef void(__cdecl* SV_Cmd_ArgvBuffer_t)(int arg, char* buf, int size); + extern SV_Cmd_ArgvBuffer_t SV_Cmd_ArgvBuffer; + typedef void(__cdecl * SV_SetConfigstring_t)(int index, const char* string); extern SV_SetConfigstring_t SV_SetConfigstring; From 62bca7f3b2449841c2f1d4ae90a25b772f6530cc Mon Sep 17 00:00:00 2001 From: FutureRave Date: Thu, 9 Dec 2021 17:49:47 +0000 Subject: [PATCH 7/7] read ent num from struct as Matrix suggested --- src/Components/Modules/ClientCommand.cpp | 29 ++++++++---------------- src/Components/Modules/ClientCommand.hpp | 1 - 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/Components/Modules/ClientCommand.cpp b/src/Components/Modules/ClientCommand.cpp index 39e14071..1325c54e 100644 --- a/src/Components/Modules/ClientCommand.cpp +++ b/src/Components/Modules/ClientCommand.cpp @@ -4,29 +4,20 @@ namespace Components { std::unordered_map> ClientCommand::FunctionMap; - unsigned int ClientCommand::GetEntityNum(const Game::gentity_s* ent) - { - unsigned int num; - - num = ent - Game::g_entities; - - return num; - } - bool ClientCommand::CheatsOk(const Game::gentity_s* ent) { - const auto entNum = ClientCommand::GetEntityNum(ent); + const auto entNum = ent->s.number; if (!Dvar::Var("sv_cheats").get()) { - Logger::Print("Cheats disabled!\n"); + Logger::Print("CheatsOk: cheats are disabled!\n"); Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"GAME_CHEATSNOTENABLED\"", 0x65)); return false; } if (ent->health < 1) { - Logger::Print("Entity %u must be alive to use this command!\n", entNum); + Logger::Print("CheatsOk: entity %u must be alive to use this command!\n", entNum); Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"GAME_MUSTBEALIVECOMMAND\"", 0x65)); return false; } @@ -61,7 +52,7 @@ namespace Components if (entity->client == nullptr) { - Logger::Print("Client %d is not fully in game yet\n", clientNum); + Logger::Print("ClientCommand: client %d is not fully in game yet\n", clientNum); return; } @@ -83,7 +74,7 @@ namespace Components ent->client->flags ^= Game::PLAYER_FLAG_NOCLIP; - const auto entNum = ClientCommand::GetEntityNum(ent); + const auto entNum = ent->s.number; Logger::Print("Noclip toggled for entity %u\n", entNum); Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65, @@ -97,7 +88,7 @@ namespace Components ent->client->flags ^= Game::PLAYER_FLAG_UFO; - const auto entNum = ClientCommand::GetEntityNum(ent); + const auto entNum = ent->s.number; Logger::Print("UFO toggled for entity %u\n", entNum); Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65, @@ -111,7 +102,7 @@ namespace Components ent->flags ^= Game::FL_GODMODE; - const auto entNum = ClientCommand::GetEntityNum(ent); + const auto entNum = ent->s.number; Logger::Print("God toggled for entity %u\n", entNum); Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65, @@ -125,7 +116,7 @@ namespace Components ent->flags ^= Game::FL_DEMI_GODMODE; - const auto entNum = ClientCommand::GetEntityNum(ent); + const auto entNum = ent->s.number; Logger::Print("Demigod toggled for entity %u\n", entNum); Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65, @@ -139,7 +130,7 @@ namespace Components ent->flags ^= Game::FL_NOTARGET; - const auto entNum = ClientCommand::GetEntityNum(ent); + const auto entNum = ent->s.number; Logger::Print("Notarget toggled for entity %u\n", entNum); Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65, @@ -277,7 +268,7 @@ namespace Components ClientCommand::ClientCommand() { - //SV_ExecuteClientCommand + // Hook call to ClientCommand in SV_ExecuteClientCommand so we may add custom commands Utils::Hook(0x6259FA, ClientCommand::ClientCommandStub, HOOK_CALL).install()->quick(); ClientCommand::AddCheatCommands(); diff --git a/src/Components/Modules/ClientCommand.hpp b/src/Components/Modules/ClientCommand.hpp index 643aa847..3c1d1da6 100644 --- a/src/Components/Modules/ClientCommand.hpp +++ b/src/Components/Modules/ClientCommand.hpp @@ -10,7 +10,6 @@ namespace Components ClientCommand(); ~ClientCommand(); static void Add(const char* name, Utils::Slot callback); - static unsigned int GetEntityNum(const Game::gentity_s* ent); static bool CheatsOk(const Game::gentity_s* ent); private: