From 9897f399a598e0fff1fbac339ec25602eea7e730 Mon Sep 17 00:00:00 2001 From: Chase Date: Sat, 16 Oct 2021 12:39:25 -0500 Subject: [PATCH 01/38] Update Gamepad.hpp --- src/Components/Modules/Gamepad.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Components/Modules/Gamepad.hpp b/src/Components/Modules/Gamepad.hpp index 9808909f..b2621b3b 100644 --- a/src/Components/Modules/Gamepad.hpp +++ b/src/Components/Modules/Gamepad.hpp @@ -65,6 +65,7 @@ namespace Components static Dvar::Var gpad_debug; static Dvar::Var gpad_present; static Dvar::Var gpad_in_use; + static Dvar::Var gpad_style; static Dvar::Var gpad_sticksConfig; static Dvar::Var gpad_buttonConfig; static Dvar::Var gpad_menu_scroll_delay_first; From 3b00c823d51c4d6d1c761c1c75a7b8c666596a8b Mon Sep 17 00:00:00 2001 From: Chase Date: Sat, 16 Oct 2021 12:40:07 -0500 Subject: [PATCH 02/38] Update Gamepad.cpp --- src/Components/Modules/Gamepad.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Components/Modules/Gamepad.cpp b/src/Components/Modules/Gamepad.cpp index 5068f5b6..2b62f102 100644 --- a/src/Components/Modules/Gamepad.cpp +++ b/src/Components/Modules/Gamepad.cpp @@ -155,6 +155,7 @@ namespace Components Dvar::Var Gamepad::gpad_debug; Dvar::Var Gamepad::gpad_present; Dvar::Var Gamepad::gpad_in_use; + Dvar::Var Gamepad::gpad_style; Dvar::Var Gamepad::gpad_sticksConfig; Dvar::Var Gamepad::gpad_buttonConfig; Dvar::Var Gamepad::gpad_menu_scroll_delay_first; @@ -1694,6 +1695,7 @@ namespace Components gpad_debug = Dvar::Register("gpad_debug", false, Game::DVAR_FLAG_NONE, "Game pad debugging"); gpad_present = Dvar::Register("gpad_present", false, Game::DVAR_FLAG_NONE, "Game pad present"); gpad_in_use = Dvar::Register("gpad_in_use", false, Game::DVAR_FLAG_NONE, "A game pad is in use"); + gpad_style = Dvar::Register("gpad_style", false, Game::DVAR_FLAG_SAVED, "Switch between Xbox and PS HUD"); gpad_sticksConfig = Dvar::Register("gpad_sticksConfig", "", Game::DVAR_FLAG_SAVED, "Game pad stick configuration"); gpad_buttonConfig = Dvar::Register("gpad_buttonConfig", "", Game::DVAR_FLAG_SAVED, "Game pad button configuration"); gpad_menu_scroll_delay_first = Dvar::Register("gpad_menu_scroll_delay_first", 420, 0, 1000, Game::DVAR_FLAG_SAVED, "Menu scroll key-repeat delay, for the first repeat, in milliseconds"); From c22abf2791236892e9d9225bf2c90c1284cb4432 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 16 Oct 2021 22:20:12 +0200 Subject: [PATCH 03/38] Swap between playstation and xbox buttons depending on the style dvar --- src/Components/Modules/Gamepad.cpp | 68 +++++++++++++++++++++++++++--- src/Components/Modules/Gamepad.hpp | 9 +++- 2 files changed, 68 insertions(+), 9 deletions(-) diff --git a/src/Components/Modules/Gamepad.cpp b/src/Components/Modules/Gamepad.cpp index 2b62f102..c3555fc7 100644 --- a/src/Components/Modules/Gamepad.cpp +++ b/src/Components/Modules/Gamepad.cpp @@ -108,7 +108,7 @@ namespace Components {"DPAD_RIGHT", Game::K_DPAD_RIGHT}, }; - Game::keyname_t Gamepad::extendedLocalizedKeyNames[] + Game::keyname_t Gamepad::extendedLocalizedKeyNamesXenon[] { // Material text icons pattern: 0x01 width height material_name_len {"^\x01\x32\x32\x08""button_a", Game::K_BUTTON_A}, @@ -128,8 +128,30 @@ namespace Components {"^\x01\x32\x32\x09""dpad_left", Game::K_DPAD_LEFT}, {"^\x01\x32\x32\x0A""dpad_right", Game::K_DPAD_RIGHT}, }; + + Game::keyname_t Gamepad::extendedLocalizedKeyNamesPs3[] + { + // Material text icons pattern: 0x01 width height material_name_len + {"^\x01\x32\x32\x10""button_ps3_cross", Game::K_BUTTON_A}, + {"^\x01\x32\x32\x11""button_ps3_circle", Game::K_BUTTON_B}, + {"^\x01\x32\x32\x11""button_ps3_square", Game::K_BUTTON_X}, + {"^\x01\x32\x32\x13""button_ps3_triangle", Game::K_BUTTON_Y}, + {"^\x01\x32\x32\x0D""button_ps3_l1", Game::K_BUTTON_LSHLDR}, + {"^\x01\x32\x32\x0D""button_ps3_r1", Game::K_BUTTON_RSHLDR}, + {"^\x01\x32\x32\x10""button_ps3_start", Game::K_BUTTON_START}, + {"^\x01\x32\x32\x0F""button_ps3_back", Game::K_BUTTON_BACK}, + {"^\x01\x48\x32\x0D""button_ps3_l3", Game::K_BUTTON_LSTICK}, + {"^\x01\x48\x32\x0D""button_ps3_r3", Game::K_BUTTON_RSTICK}, + {"^\x01\x32\x32\x0D""button_ps3_l2", Game::K_BUTTON_LTRIG}, + {"^\x01\x32\x32\x0D""button_ps3_r2", Game::K_BUTTON_RTRIG}, + {"^\x01\x32\x32\x0B""dpad_ps3_up", Game::K_DPAD_UP}, + {"^\x01\x32\x32\x0D""dpad_ps3_down", Game::K_DPAD_DOWN}, + {"^\x01\x32\x32\x0D""dpad_ps3_left", Game::K_DPAD_LEFT}, + {"^\x01\x32\x32\x0E""dpad_ps3_right", Game::K_DPAD_RIGHT}, + }; Game::keyname_t Gamepad::combinedKeyNames[Game::KEY_NAME_COUNT + std::extent_v + 1]; - Game::keyname_t Gamepad::combinedLocalizedKeyNames[Game::KEY_NAME_COUNT + std::extent_v + 1]; + Game::keyname_t Gamepad::combinedLocalizedKeyNamesXenon[Game::KEY_NAME_COUNT + std::extent_v + 1]; + Game::keyname_t Gamepad::combinedLocalizedKeyNamesPs3[Game::KEY_NAME_COUNT + std::extent_v + 1]; Gamepad::ControllerMenuKeyMapping Gamepad::controllerMenuKeyMappings[] { @@ -1832,21 +1854,53 @@ namespace Components return cl_bypassMouseInput.get() || IsGamePadInUse(); } + Game::keyname_t* Gamepad::GetLocalizedKeyNameMap() + { + if(gpad_style.get()) + return combinedLocalizedKeyNamesPs3; + + return combinedLocalizedKeyNamesXenon; + } + + void __declspec(naked) Gamepad::GetLocalizedKeyName_Stub() + { + __asm + { + push eax + pushad + + call GetLocalizedKeyNameMap + mov [esp + 0x20], eax + + popad + pop eax + + // Re-execute last instruction from game to set flags again for upcoming jump + test edi, edi + ret + } + } + void Gamepad::CreateKeyNameMap() { memcpy(combinedKeyNames, Game::keyNames, sizeof(Game::keyname_t) * Game::KEY_NAME_COUNT); memcpy(&combinedKeyNames[Game::KEY_NAME_COUNT], extendedKeyNames, sizeof(Game::keyname_t) * std::extent_v); combinedKeyNames[std::extent_v - 1] = {nullptr, 0}; - memcpy(combinedLocalizedKeyNames, Game::localizedKeyNames, sizeof(Game::keyname_t) * Game::LOCALIZED_KEY_NAME_COUNT); - memcpy(&combinedLocalizedKeyNames[Game::LOCALIZED_KEY_NAME_COUNT], extendedLocalizedKeyNames, - sizeof(Game::keyname_t) * std::extent_v); - combinedLocalizedKeyNames[std::extent_v - 1] = {nullptr, 0}; + memcpy(combinedLocalizedKeyNamesXenon, Game::localizedKeyNames, sizeof(Game::keyname_t) * Game::LOCALIZED_KEY_NAME_COUNT); + memcpy(&combinedLocalizedKeyNamesXenon[Game::LOCALIZED_KEY_NAME_COUNT], extendedLocalizedKeyNamesXenon, + sizeof(Game::keyname_t) * std::extent_v); + combinedLocalizedKeyNamesXenon[std::extent_v - 1] = {nullptr, 0}; + + memcpy(combinedLocalizedKeyNamesPs3, Game::localizedKeyNames, sizeof(Game::keyname_t) * Game::LOCALIZED_KEY_NAME_COUNT); + memcpy(&combinedLocalizedKeyNamesPs3[Game::LOCALIZED_KEY_NAME_COUNT], extendedLocalizedKeyNamesPs3, + sizeof(Game::keyname_t) * std::extent_v); + combinedLocalizedKeyNamesPs3[std::extent_v - 1] = {nullptr, 0}; Utils::Hook::Set(0x4A780A, combinedKeyNames); Utils::Hook::Set(0x4A7810, combinedKeyNames); Utils::Hook::Set(0x435C9F, combinedKeyNames); - Utils::Hook::Set(0x435C98, combinedLocalizedKeyNames); + Utils::Hook(0x435C97, GetLocalizedKeyName_Stub, HOOK_CALL).install()->quick(); } Gamepad::Gamepad() diff --git a/src/Components/Modules/Gamepad.hpp b/src/Components/Modules/Gamepad.hpp index b2621b3b..5c55325c 100644 --- a/src/Components/Modules/Gamepad.hpp +++ b/src/Components/Modules/Gamepad.hpp @@ -51,9 +51,11 @@ namespace Components static const char* gamePadMappingTypeNames[]; static Game::keyNum_t menuScrollButtonList[]; static Game::keyname_t extendedKeyNames[]; - static Game::keyname_t extendedLocalizedKeyNames[]; + static Game::keyname_t extendedLocalizedKeyNamesXenon[]; + static Game::keyname_t extendedLocalizedKeyNamesPs3[]; static Game::keyname_t combinedKeyNames[]; - static Game::keyname_t combinedLocalizedKeyNames[]; + static Game::keyname_t combinedLocalizedKeyNamesXenon[]; + static Game::keyname_t combinedLocalizedKeyNamesPs3[]; static ControllerMenuKeyMapping controllerMenuKeyMappings[]; static GamePad gamePads[Game::MAX_GAMEPADS]; @@ -193,6 +195,9 @@ namespace Components static void CL_KeyEvent_Hk(int localClientNum, int key, int down, unsigned int time); static int CL_MouseEvent_Hk(int x, int y, int dx, int dy); static bool UI_RefreshViewport_Hk(); + + static Game::keyname_t* GetLocalizedKeyNameMap(); + static void GetLocalizedKeyName_Stub(); static void CreateKeyNameMap(); }; } From bc36a2999154a393bc0f641f47e19862a74d69db Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 16 Oct 2021 22:21:32 +0200 Subject: [PATCH 04/38] Add "Chase" to list of contributors --- src/Components/Modules/Localization.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Components/Modules/Localization.cpp b/src/Components/Modules/Localization.cpp index 3c5b82a7..1bdb421c 100644 --- a/src/Components/Modules/Localization.cpp +++ b/src/Components/Modules/Localization.cpp @@ -181,6 +181,7 @@ namespace Components "a231", "AmateurHailbut", "Aoki", + "Chase", "civil", "Dasfonia", "Deity", From 1112eba7fa2a25007a97cbda6757cf634fb24179 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Sun, 7 Nov 2021 11:09:00 +0000 Subject: [PATCH 05/38] Add customizable speed scale for stance --- src/Components/Loader.cpp | 1 + src/Components/Loader.hpp | 1 + src/Components/Modules/Dvar.cpp | 3 +++ src/Game/Structs.hpp | 31 +++++++++++++++++++++++++++++++ 4 files changed, 36 insertions(+) diff --git a/src/Components/Loader.cpp b/src/Components/Loader.cpp index 7b76cb02..fea7625e 100644 --- a/src/Components/Loader.cpp +++ b/src/Components/Loader.cpp @@ -104,6 +104,7 @@ namespace Components Loader::Register(new Gamepad()); Loader::Register(new Chat()); Loader::Register(new TextRenderer()); + Loader::Register(new Movement()); Loader::Register(new Client()); diff --git a/src/Components/Loader.hpp b/src/Components/Loader.hpp index 2265b729..dd948b09 100644 --- a/src/Components/Loader.hpp +++ b/src/Components/Loader.hpp @@ -132,6 +132,7 @@ namespace Components #include "Modules/SoundMutexFix.hpp" #include "Modules/Chat.hpp" #include "Modules/TextRenderer.hpp" +#include "Modules/Movement.hpp" #include "Modules/Gamepad.hpp" #include "Modules/Client.hpp" diff --git a/src/Components/Modules/Dvar.cpp b/src/Components/Modules/Dvar.cpp index d0892d2e..24149280 100644 --- a/src/Components/Modules/Dvar.cpp +++ b/src/Components/Modules/Dvar.cpp @@ -299,6 +299,9 @@ namespace Components // Uncheat ui_debugMode Utils::Hook::Xor(0x6312DE, Game::dvar_flag::DVAR_FLAG_CHEAT); + // Remove unknown flag (to prevent unknown behaviour) + Utils::Hook::Xor(0x448B42, Game::dvar_flag::DVAR_FLAG_UNKNOWN80); + // Hook dvar 'name' registration Utils::Hook(0x40531C, Dvar::RegisterName, HOOK_CALL).install()->quick(); diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 7be1e8d7..1a9c019c 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -6876,6 +6876,37 @@ namespace Game const char* args[9]; }; + struct pmove_s + { + playerState_s* ps; + usercmd_s cmd; + usercmd_s oldcmd; + int tracemask; + int numtouch; + int touchents[32]; + char __pad0[24]; + float xyspeed; + int proneChange; + float maxSprintTimeMultiplier; + bool mantleStarted; + float mantleEndPos[3]; + int mantleDuration; + int viewChangeTime; + float viewChange; + float fTorsoPitch; + float fWaistPitch; + unsigned char handler; + }; + + enum EffectiveStance + { + PM_EFF_STANCE_DEFAULT = 0, + PM_EFF_STANCE_PRONE = 1, + PM_EFF_STANCE_DUCKED = 2, + PM_EFF_STANCE_LASTSTANDCRAWL = 3, + PM_EFF_STANCE_COUNT = 4 + }; + #pragma endregion #ifndef IDA From 1b1a53cef623dfcfc99870a46261bfe2b0bea5e3 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Sun, 7 Nov 2021 11:16:56 +0000 Subject: [PATCH 06/38] Add Module --- src/Components/Modules/Dvar.cpp | 2 +- src/Components/Modules/Movement.cpp | 151 ++++++++++++++++++++++++++++ src/Components/Modules/Movement.hpp | 20 ++++ 3 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 src/Components/Modules/Movement.cpp create mode 100644 src/Components/Modules/Movement.hpp diff --git a/src/Components/Modules/Dvar.cpp b/src/Components/Modules/Dvar.cpp index 24149280..5b7122d2 100644 --- a/src/Components/Modules/Dvar.cpp +++ b/src/Components/Modules/Dvar.cpp @@ -299,7 +299,7 @@ namespace Components // Uncheat ui_debugMode Utils::Hook::Xor(0x6312DE, Game::dvar_flag::DVAR_FLAG_CHEAT); - // Remove unknown flag (to prevent unknown behaviour) + // Remove unknown flag (prevent unknown behaviour) Utils::Hook::Xor(0x448B42, Game::dvar_flag::DVAR_FLAG_UNKNOWN80); // Hook dvar 'name' registration diff --git a/src/Components/Modules/Movement.cpp b/src/Components/Modules/Movement.cpp new file mode 100644 index 00000000..10a1377a --- /dev/null +++ b/src/Components/Modules/Movement.cpp @@ -0,0 +1,151 @@ +#include "STDInclude.hpp" + +namespace Components +{ + Dvar::Var Movement::PlayerDuckedSpeedScale; + Dvar::Var Movement::PlayerLastStandCrawlSpeedScale; + Dvar::Var Movement::PlayerProneSpeedScale; + + int Movement::PMGetEffectiveStance(Game::playerState_s* ps) + { + auto heightTarget = ps->viewHeightTarget; + + if (heightTarget == 0x16) + return Game::PM_EFF_STANCE_LASTSTANDCRAWL; + + if (heightTarget == 0x28) + return Game::PM_EFF_STANCE_DUCKED; + + if (heightTarget == 0xB) + return Game::PM_EFF_STANCE_PRONE; + + return Game::PM_EFF_STANCE_DEFAULT; + } + + float Movement::PMCmdScaleForStance(Game::pmove_s* move) + { + auto* playerState = move->ps; + float scale; + + if (playerState->viewHeightLerpTime != 0 && playerState->viewHeightLerpTarget == 0xB) + { + scale = move->cmd.serverTime - playerState->viewHeightLerpTime / 400.0f; + + if (0.0f <= scale) + { + auto flags = 0; + + if (scale < 1.0f) + { + flags |= 1 << 8; + } + + if (scale == 1.0f) + { + flags |= 1 << 14; + } + + if (flags == 0) + { + scale = 1.0f; + return scale * 0.15f + (1.0f - scale) * 0.65f; + } + + if (scale != 0.0f) + { + return scale * 0.15f + (1.0f - scale) * 0.65f; + } + } + } + + if ((playerState->viewHeightLerpTime != 0 && playerState->viewHeightLerpTarget == 0x28) && + playerState->viewHeightLerpDown == 0) + { + scale = 400.0f / move->cmd.serverTime - playerState->viewHeightLerpTime; + + if (0.0f <= scale) + { + auto flags = 0; + + if (scale < 1.0f) + { + flags |= 1 << 8; + } + + if (scale == 1.0f) + { + flags |= 1 << 14; + } + + if (flags == 0) + { + scale = 1.0f; + } + else if (scale != 0.0f) + { + return scale * 0.65f + (1.0f - scale) * 0.15f; + } + } + } + + scale = 1.0f; + auto stance = Movement::PMGetEffectiveStance(playerState); + + if (stance == Game::PM_EFF_STANCE_PRONE) + { + scale = Movement::PlayerProneSpeedScale.get(); + } + + else if (stance == Game::PM_EFF_STANCE_DUCKED) + { + scale = Movement::PlayerDuckedSpeedScale.get(); + } + + else if (stance == Game::PM_EFF_STANCE_LASTSTANDCRAWL) + { + scale = Movement::PlayerLastStandCrawlSpeedScale.get(); + } + + return scale; + } + + __declspec(naked) void Movement::PMCmdScaleForStanceStub() + { + __asm + { + pushad + + push edx + call Movement::PMCmdScaleForStance + add esp, 4 + + popad + ret + } + } + + Movement::Movement() + { + Dvar::OnInit([] + { + Movement::PlayerDuckedSpeedScale = Dvar::Register("player_duckedSpeedScale", + 0.65f, 0.0f, 5.0f, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED, + "The scale applied to the player speed when ducking"); + + Movement::PlayerLastStandCrawlSpeedScale = Dvar::Register("player_lastStandCrawlSpeedScale", + 0.2f, 0.0f, 5.0f, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED, + "The scale applied to the player speed when crawling in last stand"); + + Movement::PlayerProneSpeedScale = Dvar::Register("player_proneSpeedScale", + 0.15f, 0.0f, 5.0f, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED, + "The scale applied to the player speed when crawling"); + }); + + Utils::Hook(0x572F34, Movement::PMCmdScaleForStanceStub, HOOK_CALL).install()->quick(); + Utils::Hook(0x57395F, Movement::PMCmdScaleForStanceStub, HOOK_CALL).install()->quick(); + } + + Movement::~Movement() + { + } +} diff --git a/src/Components/Modules/Movement.hpp b/src/Components/Modules/Movement.hpp new file mode 100644 index 00000000..4c8104a2 --- /dev/null +++ b/src/Components/Modules/Movement.hpp @@ -0,0 +1,20 @@ +#pragma once + +namespace Components +{ + class Movement : public Component + { + public: + Movement(); + ~Movement(); + + private: + static Dvar::Var PlayerDuckedSpeedScale; + static Dvar::Var PlayerLastStandCrawlSpeedScale; + static Dvar::Var PlayerProneSpeedScale; + + static int PMGetEffectiveStance(Game::playerState_s* ps); + static float PMCmdScaleForStance(Game::pmove_s* move); + static void PMCmdScaleForStanceStub(); + }; +} From 7664a773e729d47f4b1876dfe64c1d832e04df0b Mon Sep 17 00:00:00 2001 From: FutureRave Date: Sun, 7 Nov 2021 17:58:33 +0000 Subject: [PATCH 07/38] Have comment explain what dvar flag is being modified --- src/Components/Modules/Dvar.cpp | 2 +- src/Game/Structs.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Modules/Dvar.cpp b/src/Components/Modules/Dvar.cpp index 5b7122d2..0d7f8f9f 100644 --- a/src/Components/Modules/Dvar.cpp +++ b/src/Components/Modules/Dvar.cpp @@ -299,7 +299,7 @@ namespace Components // Uncheat ui_debugMode Utils::Hook::Xor(0x6312DE, Game::dvar_flag::DVAR_FLAG_CHEAT); - // Remove unknown flag (prevent unknown behaviour) + // Remove unknown flag from player_lastStandCrawlSpeedScale (prevent unknown behaviour) Utils::Hook::Xor(0x448B42, Game::dvar_flag::DVAR_FLAG_UNKNOWN80); // Hook dvar 'name' registration diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 1a9c019c..2d8b443c 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -109,7 +109,7 @@ namespace Game IMG_CATEGORY_WATER = 0x5, IMG_CATEGORY_RENDERTARGET = 0x6, IMG_CATEGORY_TEMP = 0x7, - } ; + }; enum buttons_t { From b77e95a846b67bfa77678073f329a3ec8ac62bf4 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Wed, 10 Nov 2021 19:48:00 +0000 Subject: [PATCH 08/38] Refactor quick patch a bit --- src/Components/Modules/QuickPatch.cpp | 38 +++++++++++++-------------- src/Components/Modules/QuickPatch.hpp | 4 +-- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/Components/Modules/QuickPatch.cpp b/src/Components/Modules/QuickPatch.cpp index 1ab8479b..33c8f84f 100644 --- a/src/Components/Modules/QuickPatch.cpp +++ b/src/Components/Modules/QuickPatch.cpp @@ -3,6 +3,7 @@ namespace Components { int QuickPatch::FrameTime = 0; + Dvar::Var QuickPatch::r_customAspectRatio; void QuickPatch::UnlockStats() { @@ -139,16 +140,15 @@ namespace Components } } - bool QuickPatch::InvalidNameCheck(char *dest, char *source, int size) + bool QuickPatch::InvalidNameCheck(char* dest, const char* source, int size) { - strncpy(dest, source, size - 1); - dest[size - 1] = 0; + Utils::Hook::Call(0x4D6F80)(dest, source, size); // I_strncpyz for (int i = 0; i < size - 1; i++) { if (!dest[i]) break; - if (dest[i] > 125 || dest[i] < 32 || dest[i] == '%') + if (dest[i] > 125 || dest[i] < 32 || dest[i] == '%') { return false; } @@ -172,7 +172,7 @@ namespace Components push 1; push kick_reason; push edi; - mov eax, 0x004D1600; + mov eax, 0x004D1600; // SV_DropClientInternal call eax; add esp, 12; popad; @@ -184,7 +184,6 @@ namespace Components } Game::dvar_t* QuickPatch::g_antilag; - __declspec(naked) void QuickPatch::ClientEventsFireWeaponStub() { __asm @@ -268,30 +267,31 @@ namespace Components } } - Game::dvar_t* QuickPatch::r_customAspectRatio; Game::dvar_t* QuickPatch::Dvar_RegisterAspectRatioDvar(const char* name, char**, int defaultVal, int flags, const char* description) { - static std::vector < char * > values = + static char* r_aspectRatioEnum[] = { - const_cast("auto"), - const_cast("standard"), - const_cast("wide 16:10"), - const_cast("wide 16:9"), - const_cast("custom"), - nullptr, + "auto", + "standard", + "wide 16:10", + "wide 16:9", + "custom", + nullptr }; // register custom aspect ratio dvar - r_customAspectRatio = Game::Dvar_RegisterFloat("r_customAspectRatio", 16.0f / 9.0f, 4.0f / 3.0f, 63.0f / 9.0f, flags, "Screen aspect ratio. Divide the width by the height in order to get the aspect ratio value. For example: 16 / 9 = 1,77"); + QuickPatch::r_customAspectRatio = Dvar::Register("r_customAspectRatio", + 16.0f / 9.0f, 4.0f / 3.0f, 63.0f / 9.0f, flags, + "Screen aspect ratio. Divide the width by the height in order to get the aspect ratio value. For example: 16 / 9 = 1,77"); // register enumeration dvar - return Game::Dvar_RegisterEnum(name, values.data(), defaultVal, flags, description); + return Game::Dvar_RegisterEnum(name, r_aspectRatioEnum, defaultVal, flags, description); } void QuickPatch::SetAspectRatio() { // set the aspect ratio - Utils::Hook::Set(0x66E1C78, r_customAspectRatio->current.value); + Utils::Hook::Set(0x66E1C78, r_customAspectRatio.get()); } __declspec(naked) void QuickPatch::SetAspectRatioStub() @@ -483,8 +483,8 @@ namespace Components Utils::Hook(0x578F52, QuickPatch::JavelinResetHookStub, HOOK_JUMP).install()->quick(); // Add ultrawide support - Utils::Hook(0x0051B13B, QuickPatch::Dvar_RegisterAspectRatioDvar, HOOK_CALL).install()->quick(); - Utils::Hook(0x005063F3, QuickPatch::SetAspectRatioStub, HOOK_JUMP).install()->quick(); + Utils::Hook(0x51B13B, QuickPatch::Dvar_RegisterAspectRatioDvar, HOOK_CALL).install()->quick(); + Utils::Hook(0x5063F3, QuickPatch::SetAspectRatioStub, HOOK_JUMP).install()->quick(); // Make sure preDestroy is called when the game shuts down Scheduler::OnShutdown(Loader::PreDestroy); diff --git a/src/Components/Modules/QuickPatch.hpp b/src/Components/Modules/QuickPatch.hpp index 008f4a05..6b13a5a1 100644 --- a/src/Components/Modules/QuickPatch.hpp +++ b/src/Components/Modules/QuickPatch.hpp @@ -28,13 +28,13 @@ namespace Components static void JavelinResetHookStub(); - static bool InvalidNameCheck(char *dest, char *source, int size); + static bool InvalidNameCheck(char* dest, const char* source, int size); static void InvalidNameStub(); static Game::dvar_t* sv_enableBounces; static void BounceStub(); - static Game::dvar_t* r_customAspectRatio; + static Dvar::Var r_customAspectRatio; static Game::dvar_t* Dvar_RegisterAspectRatioDvar(const char* name, char** enumValues, int defaultVal, int flags, const char* description); static void SetAspectRatioStub(); static void SetAspectRatio(); From 37e79f7c3acce22bc4f8e5caca4ef4a9f1f36dd0 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Thu, 11 Nov 2021 13:38:51 +0000 Subject: [PATCH 09/38] Hook dvar register func --- src/Components/Modules/Dvar.cpp | 3 --- src/Components/Modules/Movement.cpp | 18 ++++++++++++++---- src/Components/Modules/Movement.hpp | 2 ++ 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/Components/Modules/Dvar.cpp b/src/Components/Modules/Dvar.cpp index 0d7f8f9f..d0892d2e 100644 --- a/src/Components/Modules/Dvar.cpp +++ b/src/Components/Modules/Dvar.cpp @@ -299,9 +299,6 @@ namespace Components // Uncheat ui_debugMode Utils::Hook::Xor(0x6312DE, Game::dvar_flag::DVAR_FLAG_CHEAT); - // Remove unknown flag from player_lastStandCrawlSpeedScale (prevent unknown behaviour) - Utils::Hook::Xor(0x448B42, Game::dvar_flag::DVAR_FLAG_UNKNOWN80); - // Hook dvar 'name' registration Utils::Hook(0x40531C, Dvar::RegisterName, HOOK_CALL).install()->quick(); diff --git a/src/Components/Modules/Movement.cpp b/src/Components/Modules/Movement.cpp index 10a1377a..3c04b232 100644 --- a/src/Components/Modules/Movement.cpp +++ b/src/Components/Modules/Movement.cpp @@ -124,6 +124,14 @@ namespace Components } } + Game::dvar_t* Movement::Dvar_RegisterLastStandSpeedScale(const char* name, float defaultVal, float min, float max, int, const char*) + { + Movement::PlayerLastStandCrawlSpeedScale = Dvar::Register(name, defaultVal, + min, max, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED, "TEST DESC"); + + return Movement::PlayerLastStandCrawlSpeedScale.get(); + } + Movement::Movement() { Dvar::OnInit([] @@ -132,17 +140,19 @@ namespace Components 0.65f, 0.0f, 5.0f, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED, "The scale applied to the player speed when ducking"); - Movement::PlayerLastStandCrawlSpeedScale = Dvar::Register("player_lastStandCrawlSpeedScale", - 0.2f, 0.0f, 5.0f, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED, - "The scale applied to the player speed when crawling in last stand"); - Movement::PlayerProneSpeedScale = Dvar::Register("player_proneSpeedScale", 0.15f, 0.0f, 5.0f, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED, "The scale applied to the player speed when crawling"); }); + // Hook PM_CmdScaleForStance in PM_CmdScale_Walk Utils::Hook(0x572F34, Movement::PMCmdScaleForStanceStub, HOOK_CALL).install()->quick(); + + //Hook PM_CmdScaleForStance in PM_GetMaxSpeed Utils::Hook(0x57395F, Movement::PMCmdScaleForStanceStub, HOOK_CALL).install()->quick(); + + // Hook Dvar_RegisterFloat. Only thing that's changed is that the 0x80 flag is not used. + Utils::Hook(0x448B66, Movement::Dvar_RegisterLastStandSpeedScale, HOOK_CALL).install()->quick(); } Movement::~Movement() diff --git a/src/Components/Modules/Movement.hpp b/src/Components/Modules/Movement.hpp index 4c8104a2..07ad6894 100644 --- a/src/Components/Modules/Movement.hpp +++ b/src/Components/Modules/Movement.hpp @@ -16,5 +16,7 @@ namespace Components static int PMGetEffectiveStance(Game::playerState_s* ps); static float PMCmdScaleForStance(Game::pmove_s* move); static void PMCmdScaleForStanceStub(); + + static Game::dvar_t* Dvar_RegisterLastStandSpeedScale(const char* name, float defaultVal, float min, float max, int flags, const char* desc); }; } From b02d7f41aee85ef2a063f077469737d4376f88b2 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Thu, 11 Nov 2021 13:40:52 +0000 Subject: [PATCH 10/38] Overlooked this detail --- src/Components/Modules/Movement.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Modules/Movement.cpp b/src/Components/Modules/Movement.cpp index 3c04b232..f71c9699 100644 --- a/src/Components/Modules/Movement.cpp +++ b/src/Components/Modules/Movement.cpp @@ -124,10 +124,10 @@ namespace Components } } - Game::dvar_t* Movement::Dvar_RegisterLastStandSpeedScale(const char* name, float defaultVal, float min, float max, int, const char*) + Game::dvar_t* Movement::Dvar_RegisterLastStandSpeedScale(const char* name, float defaultVal, float min, float max, int, const char* desc) { Movement::PlayerLastStandCrawlSpeedScale = Dvar::Register(name, defaultVal, - min, max, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED, "TEST DESC"); + min, max, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED, desc); return Movement::PlayerLastStandCrawlSpeedScale.get(); } From f6c973bc76de9a33ef56b2d1559b75dc57b21eec Mon Sep 17 00:00:00 2001 From: FutureRave Date: Thu, 11 Nov 2021 16:47:42 +0000 Subject: [PATCH 11/38] Make DvarRegisterEnum accept const char** --- src/Components/Modules/QuickPatch.cpp | 2 +- src/Game/Functions.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Modules/QuickPatch.cpp b/src/Components/Modules/QuickPatch.cpp index 33c8f84f..59691749 100644 --- a/src/Components/Modules/QuickPatch.cpp +++ b/src/Components/Modules/QuickPatch.cpp @@ -269,7 +269,7 @@ namespace Components Game::dvar_t* QuickPatch::Dvar_RegisterAspectRatioDvar(const char* name, char**, int defaultVal, int flags, const char* description) { - static char* r_aspectRatioEnum[] = + static const char* r_aspectRatioEnum[] = { "auto", "standard", diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 2569dbcf..ae4198b9 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -247,7 +247,7 @@ namespace Game typedef dvar_t* (__cdecl * Dvar_RegisterInt_t)(const char* name, int defaultVal, int min, int max, int flags, const char* description); extern Dvar_RegisterInt_t Dvar_RegisterInt; - typedef dvar_t* (__cdecl * Dvar_RegisterEnum_t)(const char* name, char** enumValues, int defaultVal, int flags, const char* description); + typedef dvar_t* (__cdecl * Dvar_RegisterEnum_t)(const char* name, const char** enumValues, int defaultVal, int flags, const char* description); extern Dvar_RegisterEnum_t Dvar_RegisterEnum; typedef dvar_t* (__cdecl * Dvar_RegisterString_t)(const char* name, const char* defaultVal, int, const char*); From 8cd3f2cad44216a35b6ab169fe1ad62572e7085f Mon Sep 17 00:00:00 2001 From: FutureRave Date: Sat, 13 Nov 2021 13:15:27 +0000 Subject: [PATCH 12/38] [Script] Add replaceFun --- src/Components/Modules/Script.cpp | 95 +++++++++++++++++++++++++++++++ src/Components/Modules/Script.hpp | 7 +++ src/Game/Functions.hpp | 4 +- src/Game/Structs.hpp | 2 +- 4 files changed, 105 insertions(+), 3 deletions(-) diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index 72995ce6..4d7435f2 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -9,6 +9,8 @@ namespace Components unsigned short Script::FunctionName; std::unordered_map Script::ScriptStorage; std::unordered_map Script::ScriptBaseProgramNum; + std::unordered_map Script::ReplacedFunctions; + const char* Script::ReplacedPos = 0; int Script::LastFrameTime = -1; Utils::Signal Script::VMShutdownSignal; @@ -397,6 +399,75 @@ namespace Components return Game::Scr_GetNumParam(); } + const char* Script::GetCodePosForParam(int index) + { + return Game::scriptContainer->stack[index].u.codePosValue; + } + + void Script::GetReplacedPos(const char* pos) + { + if (Script::ReplacedFunctions.find(pos) != Script::ReplacedFunctions.end()) + { + Script::ReplacedPos = Script::ReplacedFunctions[pos];; + } + } + + void Script::SetReplacedPos(const char* what, const char* with) + { + // Warn if the function was already detoured + if (Script::ReplacedFunctions.find(what) != Script::ReplacedFunctions.end()) + { + Logger::Print("Warning: a function was already detoured by a script\n"); + } + + Script::ReplacedFunctions[what] = with; + } + + __declspec(naked) void Script::VMExecuteInternalStub() + { + __asm + { + pushad + + push edx + call Script::GetReplacedPos + + pop edx + popad + + cmp Script::ReplacedPos, 0 + jne SetPos + + movzx eax, byte ptr [edx] + inc edx + + Loc1: + cmp eax, 0x8B + + push ecx + + mov ecx, 0x2045094 + mov [ecx], eax + + mov ecx, 0x2040CD4 + mov [ecx], edx + + pop ecx + + push 0x061E944 + retn + + SetPos: + mov edx, Script::ReplacedPos + mov Script::ReplacedPos, 0 + + movzx eax, byte ptr [edx] + inc edx + + jmp Loc1 + } + } + Game::gentity_t* Script::getEntFromEntRef(Game::scr_entref_t entref) { Game::gentity_t* gentity = &Game::g_entities[entref]; @@ -414,6 +485,26 @@ namespace Components void Script::AddFunctions() { + Script::AddFunction("ReplaceFunc", [](Game::scr_entref_t) // gsc: ReplaceFunc(,) + { + if (Game::Scr_GetNumParam() != 2) + { + Game::Scr_Error("^1ReplaceFunc: Needs two parameters!\n"); + return; + } + + if (Game::Scr_GetType(0) != Game::VAR_FUNCTION || Game::Scr_GetType(1) != Game::VAR_FUNCTION) + { + Game::Scr_Error("^1ReplaceFunc: Needs function pointers as parameters!\n"); + return; + } + + const auto what = Script::GetCodePosForParam(0); + const auto with = Script::GetCodePosForParam(-1); + + Script::SetReplacedPos(what, with); + }); + // System time Script::AddFunction("GetSystemTime", [](Game::scr_entref_t) // gsc: GetSystemTime() { @@ -562,6 +653,9 @@ namespace Components Utils::Hook(0x5F41A3, Script::SetExpFogStub, HOOK_CALL).install()->quick(); + Utils::Hook(0x61E92E, Script::VMExecuteInternalStub, HOOK_JUMP).install()->quick(); + Utils::Hook::Nop(0x61E933, 1); + Utils::Hook(0x47548B, Script::ScrShutdownSystemStub, HOOK_CALL).install()->quick(); Utils::Hook(0x4D06BA, Script::ScrShutdownSystemStub, HOOK_CALL).install()->quick(); @@ -623,6 +717,7 @@ namespace Components Script::ScriptHandles.clear(); Script::ScriptNameStack.clear(); Script::ScriptFunctions.clear(); + Script::ReplacedFunctions.clear(); Script::VMShutdownSignal.clear(); Script::ScriptStorage.clear(); diff --git a/src/Components/Modules/Script.hpp b/src/Components/Modules/Script.hpp index dd429cde..8d6e2c8b 100644 --- a/src/Components/Modules/Script.hpp +++ b/src/Components/Modules/Script.hpp @@ -40,6 +40,8 @@ namespace Components static unsigned short FunctionName; static std::unordered_map ScriptStorage; static std::unordered_map ScriptBaseProgramNum; + static std::unordered_map ReplacedFunctions; + static const char* ReplacedPos; static int LastFrameTime; static Utils::Signal VMShutdownSignal; @@ -70,6 +72,11 @@ namespace Components static int SetExpFogStub(); + static const char* GetCodePosForParam(int index); + static void GetReplacedPos(const char* pos); + static void SetReplacedPos(const char* what, const char* with); + static void VMExecuteInternalStub(); + static void AddFunctions(); }; } diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 2569dbcf..47487a29 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -660,7 +660,7 @@ namespace Game typedef unsigned int(__cdecl * Scr_GetObject_t)(int); extern Scr_GetObject_t Scr_GetObject; - typedef int(__cdecl * Scr_GetNumParam_t)(); + typedef unsigned int(__cdecl * Scr_GetNumParam_t)(); extern Scr_GetNumParam_t Scr_GetNumParam; typedef int(__cdecl * Scr_GetFunctionHandle_t)(const char*, const char*); @@ -687,7 +687,7 @@ namespace Game typedef bool(__cdecl * Scr_IsSystemActive_t)(); extern Scr_IsSystemActive_t Scr_IsSystemActive; - typedef int(__cdecl* Scr_GetType_t)(int); + typedef int(__cdecl* Scr_GetType_t)(unsigned int); extern Scr_GetType_t Scr_GetType; typedef void(__cdecl* Scr_Error_t)(const char*); diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 7be1e8d7..6e112ee4 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -4886,7 +4886,7 @@ namespace Game struct VariableValue { VariableUnion u; - int type; + VariableType type; }; struct ScriptContainer From 446c55b0b0c0c7cacdedcbc89259f4cc7fef531c Mon Sep 17 00:00:00 2001 From: FutureRave Date: Sat, 13 Nov 2021 13:22:06 +0000 Subject: [PATCH 13/38] [Script] Fix unsigned/signed mismatch --- src/Components/Modules/Bots.cpp | 8 ++++---- src/Components/Modules/Download.cpp | 4 ++-- src/Components/Modules/Script.cpp | 20 ++++++++++---------- src/Components/Modules/Script.hpp | 2 +- src/Components/Modules/Slowmotion.cpp | 4 ++-- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/Components/Modules/Bots.cpp b/src/Components/Modules/Bots.cpp index 7e0f16ba..15e36cfb 100644 --- a/src/Components/Modules/Bots.cpp +++ b/src/Components/Modules/Bots.cpp @@ -160,7 +160,7 @@ namespace Components { Script::AddFunction("SetPing", [](Game::scr_entref_t id) // gsc: self SetPing() { - if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_INTEGER) + if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_INTEGER) { Game::Scr_Error("^1SetPing: Needs one integer parameter!\n"); return; @@ -250,7 +250,7 @@ namespace Components Script::AddFunction("botWeapon", [](Game::scr_entref_t id) // Usage: botWeapon(); { - if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING) + if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_STRING) { Game::Scr_Error("^1botWeapon: Needs one string parameter!\n"); return; @@ -293,7 +293,7 @@ namespace Components Script::AddFunction("botAction", [](Game::scr_entref_t id) // Usage: botAction(); { - if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING) + if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_STRING) { Game::Scr_Error("^1botAction: Needs one string parameter!\n"); return; @@ -346,7 +346,7 @@ namespace Components Script::AddFunction("botMovement", [](Game::scr_entref_t id) // Usage: botMovement(, ); { - if (Game::Scr_GetNumParam() != 2 || Game::Scr_GetType(0) != Game::VAR_INTEGER || Game::Scr_GetType(1) != Game::VAR_INTEGER) + if (Game::Scr_GetNumParam() != 2u || Game::Scr_GetType(0) != Game::VAR_INTEGER || Game::Scr_GetType(1) != Game::VAR_INTEGER) { Game::Scr_Error("^1botMovement: Needs two integer parameters!\n"); return; diff --git a/src/Components/Modules/Download.cpp b/src/Components/Modules/Download.cpp index d2bb9649..7d1d6f27 100644 --- a/src/Components/Modules/Download.cpp +++ b/src/Components/Modules/Download.cpp @@ -967,7 +967,7 @@ namespace Components Script::AddFunction("httpGet", [](Game::scr_entref_t) { if (!Dedicated::IsEnabled() && !Flags::HasFlag("scriptablehttp")) return; - if (Game::Scr_GetNumParam() < 1) return; + if (Game::Scr_GetNumParam() < 1u) return; std::string url = Game::Scr_GetString(0); unsigned int object = Game::AllocObject(); @@ -981,7 +981,7 @@ namespace Components Script::AddFunction("httpCancel", [](Game::scr_entref_t) { if (!Dedicated::IsEnabled() && !Flags::HasFlag("scriptablehttp")) return; - if (Game::Scr_GetNumParam() < 1) return; + if (Game::Scr_GetNumParam() < 1u) return; unsigned int object = Game::Scr_GetObject(0); for (auto& download : Download::ScriptDownloads) diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index 4d7435f2..4758784c 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -384,9 +384,9 @@ namespace Components Utils::Hook::Call(0x421EE0)(num); } - int Script::SetExpFogStub() + unsigned int Script::SetExpFogStub() { - if (Game::Scr_GetNumParam() == 6) + if (Game::Scr_GetNumParam() == 6u) { std::memmove(&Game::scriptContainer->stack[-4], &Game::scriptContainer->stack[-5], sizeof(Game::VariableValue) * 6); Game::scriptContainer->stack += 1; @@ -408,7 +408,7 @@ namespace Components { if (Script::ReplacedFunctions.find(pos) != Script::ReplacedFunctions.end()) { - Script::ReplacedPos = Script::ReplacedFunctions[pos];; + Script::ReplacedPos = Script::ReplacedFunctions[pos]; } } @@ -487,7 +487,7 @@ namespace Components { Script::AddFunction("ReplaceFunc", [](Game::scr_entref_t) // gsc: ReplaceFunc(,) { - if (Game::Scr_GetNumParam() != 2) + if (Game::Scr_GetNumParam() != 2u) { Game::Scr_Error("^1ReplaceFunc: Needs two parameters!\n"); return; @@ -525,7 +525,7 @@ namespace Components // Print to console, even without being in 'developer 1'. Script::AddFunction("PrintConsole", [](Game::scr_entref_t) // gsc: PrintConsole() { - if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING) + if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_STRING) { Game::Scr_Error("^1PrintConsole: Needs one string parameter!\n"); return; @@ -539,7 +539,7 @@ namespace Components // Executes command to the console Script::AddFunction("Exec", [](Game::scr_entref_t) // gsc: Exec() { - if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING) + if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_STRING) { Game::Scr_Error("^1Exec: Needs one string parameter!\n"); return; @@ -554,7 +554,7 @@ namespace Components // Script Storage Funcs Script::AddFunction("StorageSet", [](Game::scr_entref_t) // gsc: StorageSet(, ); { - if (Game::Scr_GetNumParam() != 2 || Game::Scr_GetType(0) != Game::VAR_STRING || Game::Scr_GetType(1) != Game::VAR_STRING) + if (Game::Scr_GetNumParam() != 2u || Game::Scr_GetType(0) != Game::VAR_STRING || Game::Scr_GetType(1) != Game::VAR_STRING) { Game::Scr_Error("^1StorageSet: Needs two string parameters!\n"); return; @@ -568,7 +568,7 @@ namespace Components Script::AddFunction("StorageRemove", [](Game::scr_entref_t) // gsc: StorageRemove(); { - if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING) + if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_STRING) { Game::Scr_Error("^1StorageRemove: Needs one string parameter!\n"); return; @@ -587,7 +587,7 @@ namespace Components Script::AddFunction("StorageGet", [](Game::scr_entref_t) // gsc: StorageGet(); { - if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING) + if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_STRING) { Game::Scr_Error("^1StorageGet: Needs one string parameter!\n"); return; @@ -607,7 +607,7 @@ namespace Components Script::AddFunction("StorageHas", [](Game::scr_entref_t) // gsc: StorageHas(); { - if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING) + if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_STRING) { Game::Scr_Error("^1StorageHas: Needs one string parameter!\n"); return; diff --git a/src/Components/Modules/Script.hpp b/src/Components/Modules/Script.hpp index 8d6e2c8b..c9125831 100644 --- a/src/Components/Modules/Script.hpp +++ b/src/Components/Modules/Script.hpp @@ -70,7 +70,7 @@ namespace Components static void Scr_PrintPrevCodePosStub(); static void Scr_PrintPrevCodePos(int); - static int SetExpFogStub(); + static unsigned int SetExpFogStub(); static const char* GetCodePosForParam(int index); static void GetReplacedPos(const char* pos); diff --git a/src/Components/Modules/Slowmotion.cpp b/src/Components/Modules/Slowmotion.cpp index 0a15b94d..4879e142 100644 --- a/src/Components/Modules/Slowmotion.cpp +++ b/src/Components/Modules/Slowmotion.cpp @@ -38,12 +38,12 @@ namespace Components float start = Game::Scr_GetFloat(0); float end = 1.0f; - if (Game::Scr_GetNumParam() >= 2) + if (Game::Scr_GetNumParam() >= 2u) { end = Game::Scr_GetFloat(1); } - if (Game::Scr_GetNumParam() >= 3) + if (Game::Scr_GetNumParam() >= 3u) { duration = static_cast(Game::Scr_GetFloat(2) * 1000.0); } From c73794f6ea6d8aa79df7f665d1faa8945f7f50c7 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Sat, 13 Nov 2021 13:32:20 +0000 Subject: [PATCH 14/38] [Script] Better comments --- src/Components/Modules/Script.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index 4758784c..c88b219c 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -414,7 +414,6 @@ namespace Components void Script::SetReplacedPos(const char* what, const char* with) { - // Warn if the function was already detoured if (Script::ReplacedFunctions.find(what) != Script::ReplacedFunctions.end()) { Logger::Print("Warning: a function was already detoured by a script\n"); @@ -485,7 +484,7 @@ namespace Components void Script::AddFunctions() { - Script::AddFunction("ReplaceFunc", [](Game::scr_entref_t) // gsc: ReplaceFunc(,) + Script::AddFunction("ReplaceFunc", [](Game::scr_entref_t) // gsc: ReplaceFunc(, ) { if (Game::Scr_GetNumParam() != 2u) { From f101dbadec8bf0dbde36ec3845aa60cd9c87f16e Mon Sep 17 00:00:00 2001 From: FutureRave Date: Sat, 13 Nov 2021 18:51:37 +0000 Subject: [PATCH 15/38] [Script] Improve structs, add extra checks --- src/Components/Modules/Script.cpp | 69 +++++++++++++++---------------- src/Components/Modules/Script.hpp | 2 +- src/Game/Functions.cpp | 2 +- src/Game/Functions.hpp | 2 +- src/Game/Structs.hpp | 36 ++++++++++++---- 5 files changed, 65 insertions(+), 46 deletions(-) diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index c88b219c..5d10ca9c 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -388,20 +388,34 @@ namespace Components { if (Game::Scr_GetNumParam() == 6u) { - std::memmove(&Game::scriptContainer->stack[-4], &Game::scriptContainer->stack[-5], sizeof(Game::VariableValue) * 6); - Game::scriptContainer->stack += 1; - Game::scriptContainer->stack[-6].type = Game::VAR_FLOAT; - Game::scriptContainer->stack[-6].u.floatValue = 0; + std::memmove(&Game::scrVmPub->top[-4], &Game::scrVmPub->top[-5], sizeof(Game::VariableValue) * 6); + Game::scrVmPub->top += 1; + Game::scrVmPub->top[-6].type = Game::VAR_FLOAT; + Game::scrVmPub->top[-6].u.floatValue = 0; - ++Game::scriptContainer->numParam; + ++Game::scrVmPub->outparamcount; } return Game::Scr_GetNumParam(); } - const char* Script::GetCodePosForParam(int index) + const char* Script::GetCodePosForParam(unsigned int index) { - return Game::scriptContainer->stack[index].u.codePosValue; + if (index >= Game::scrVmPub->outparamcount) + { + Game::Scr_Error("^1GetCodePosForParam: Index is out of range!\n"); + return ""; + } + + const auto value = &Game::scrVmPub->top[0 - index]; + + if (value->type != Game::VAR_FUNCTION) + { + Game::Scr_Error("^1GetCodePosForParam: Expects a function as parameter!\n"); + return ""; + } + + return value->u.codePosValue; } void Script::GetReplacedPos(const char* pos) @@ -414,9 +428,15 @@ namespace Components void Script::SetReplacedPos(const char* what, const char* with) { + if (what[0] == '\0' || with[0] == '\0') + { + Logger::Print("Warning: Invalid paramters passed to ReplacedFunctions\n"); + return; + } + if (Script::ReplacedFunctions.find(what) != Script::ReplacedFunctions.end()) { - Logger::Print("Warning: a function was already detoured by a script\n"); + Logger::Print("Warning: ReplacedFunctions already contains codePosValue for a function\n"); } Script::ReplacedFunctions[what] = with; @@ -453,7 +473,7 @@ namespace Components pop ecx - push 0x061E944 + push 0x61E944 retn SetPos: @@ -499,7 +519,7 @@ namespace Components } const auto what = Script::GetCodePosForParam(0); - const auto with = Script::GetCodePosForParam(-1); + const auto with = Script::GetCodePosForParam(1); Script::SetReplacedPos(what, with); }); @@ -683,31 +703,10 @@ namespace Components Script::AddFunctions(); - // Script::AddFunction("playviewmodelfx", [](Game::scr_entref_t /*index*/) - // { - // /*auto Scr_Error = Utils::Hook::Call(0x42EF40); - // if (index >> 16) - // { - // Scr_Error("not an entity"); - // return; - // }*/ - - // // obtain FX name - // auto fxName = Game::Scr_GetString(0); - // auto fx = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_FX, fxName).fx; - - // auto tagName = Game::Scr_GetString(1); - // auto tagIndex = Game::SL_GetString(tagName, 0); - - // /*char boneIndex = -2; - // if (!Game::CG_GetBoneIndex(2048, tagIndex, &boneIndex)) - // { - // Scr_Error(Utils::String::VA("Unknown bone %s.\n", tagName)); - // return; - // }*/ - - // Game::CG_PlayBoltedEffect(0, fx, 2048, tagIndex); - // }); + Script::OnVMShutdown([] + { + Script::ReplacedFunctions.clear(); + }); } Script::~Script() diff --git a/src/Components/Modules/Script.hpp b/src/Components/Modules/Script.hpp index c9125831..5fb13727 100644 --- a/src/Components/Modules/Script.hpp +++ b/src/Components/Modules/Script.hpp @@ -72,7 +72,7 @@ namespace Components static unsigned int SetExpFogStub(); - static const char* GetCodePosForParam(int index); + static const char* GetCodePosForParam(unsigned int index); static void GetReplacedPos(const char* pos); static void SetReplacedPos(const char* what, const char* with); static void VMExecuteInternalStub(); diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 462c6d9c..d61e41fa 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -460,7 +460,7 @@ namespace Game XZone* g_zones = reinterpret_cast(0x14C0F80); unsigned short* db_hashTable = reinterpret_cast(0x12412B0); - ScriptContainer* scriptContainer = reinterpret_cast(0x2040D00); + scrVmPub_t* scrVmPub = reinterpret_cast(0x2040CF0); clientstate_t* clcState = reinterpret_cast(0xB2C540); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 47487a29..f5e89711 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -968,7 +968,7 @@ namespace Game extern XZone* g_zones; extern unsigned short* db_hashTable; - extern ScriptContainer* scriptContainer; + extern scrVmPub_t* scrVmPub; extern clientstate_t* clcState; diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 6e112ee4..1f090ec0 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -4889,15 +4889,35 @@ namespace Game VariableType type; }; - struct ScriptContainer + struct function_stack_t { - VariableValue* stack; - char unk1; - char unk2; - char unk3; - char pad; - DWORD unk4; - int numParam; + const char* pos; + unsigned int localId; + unsigned int localVarCount; + VariableValue* top; + VariableValue* startTop; + }; + + struct function_frame_t + { + function_stack_t fs; + int topType; + }; + + struct scrVmPub_t + { + unsigned int* localVars; + VariableValue* maxStack; + int function_count; + function_frame_t* function_frame; + VariableValue* top; + bool debugCode; + bool abort_on_error; + bool terminal_error; + unsigned int inparamcount; + unsigned int outparamcount; + function_frame_t function_frame_start[32]; + VariableValue stack[2048]; }; enum UILocalVarType From 4cb8cdfca3570619babae558a510499086e0cbd9 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Sat, 13 Nov 2021 19:12:16 +0000 Subject: [PATCH 16/38] [Script] Removed double check' --- src/Components/Modules/Script.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index 5d10ca9c..b4a0bf86 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -512,12 +512,6 @@ namespace Components return; } - if (Game::Scr_GetType(0) != Game::VAR_FUNCTION || Game::Scr_GetType(1) != Game::VAR_FUNCTION) - { - Game::Scr_Error("^1ReplaceFunc: Needs function pointers as parameters!\n"); - return; - } - const auto what = Script::GetCodePosForParam(0); const auto with = Script::GetCodePosForParam(1); From 5c69267ba3b057d6dbf98a3b149dc65b06d675f1 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Sat, 13 Nov 2021 20:46:58 +0000 Subject: [PATCH 17/38] [Script] Make index signed to keep consistency --- src/Components/Modules/Script.cpp | 4 ++-- src/Components/Modules/Script.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index b4a0bf86..fa97048f 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -399,7 +399,7 @@ namespace Components return Game::Scr_GetNumParam(); } - const char* Script::GetCodePosForParam(unsigned int index) + const char* Script::GetCodePosForParam(int index) { if (index >= Game::scrVmPub->outparamcount) { @@ -407,7 +407,7 @@ namespace Components return ""; } - const auto value = &Game::scrVmPub->top[0 - index]; + const auto value = &Game::scrVmPub->top[-index]; if (value->type != Game::VAR_FUNCTION) { diff --git a/src/Components/Modules/Script.hpp b/src/Components/Modules/Script.hpp index 5fb13727..c9125831 100644 --- a/src/Components/Modules/Script.hpp +++ b/src/Components/Modules/Script.hpp @@ -72,7 +72,7 @@ namespace Components static unsigned int SetExpFogStub(); - static const char* GetCodePosForParam(unsigned int index); + static const char* GetCodePosForParam(int index); static void GetReplacedPos(const char* pos); static void SetReplacedPos(const char* what, const char* with); static void VMExecuteInternalStub(); From c3dd5015e141b93626302363140994c817f01526 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Sat, 13 Nov 2021 20:55:22 +0000 Subject: [PATCH 18/38] [Script] Fix compilation --- src/Components/Modules/Script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index fa97048f..d8c7b955 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -401,7 +401,7 @@ namespace Components const char* Script::GetCodePosForParam(int index) { - if (index >= Game::scrVmPub->outparamcount) + if (static_cast(index) >= Game::scrVmPub->outparamcount) { Game::Scr_Error("^1GetCodePosForParam: Index is out of range!\n"); return ""; From 6eaf72e86f7517d059d3dd8e8001e1469011f88c Mon Sep 17 00:00:00 2001 From: FutureRave Date: Mon, 15 Nov 2021 17:44:23 +0000 Subject: [PATCH 19/38] [Script] Small adjustment to variable type --- src/Components/Modules/Script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index d8c7b955..0f1384d4 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -391,7 +391,7 @@ namespace Components std::memmove(&Game::scrVmPub->top[-4], &Game::scrVmPub->top[-5], sizeof(Game::VariableValue) * 6); Game::scrVmPub->top += 1; Game::scrVmPub->top[-6].type = Game::VAR_FLOAT; - Game::scrVmPub->top[-6].u.floatValue = 0; + Game::scrVmPub->top[-6].u.floatValue = 0.0f; ++Game::scrVmPub->outparamcount; } From f0687f8203d71eaff715b3e1212c7027d2cee259 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Tue, 16 Nov 2021 16:56:13 +0000 Subject: [PATCH 20/38] Use correct enum over numbers for com_error --- src/Components/Modules/Dedicated.cpp | 2 +- src/Components/Modules/Dedicated.hpp | 2 +- src/Components/Modules/Logger.cpp | 8 ++++---- src/Components/Modules/Logger.hpp | 4 ++-- src/Components/Modules/Renderer.cpp | 2 +- src/Components/Modules/Script.cpp | 8 ++++---- src/Components/Modules/ZoneBuilder.cpp | 4 ++-- src/Game/Functions.hpp | 2 +- src/Game/Structs.hpp | 12 ++++++++++++ 9 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/Components/Modules/Dedicated.cpp b/src/Components/Modules/Dedicated.cpp index 7ff6330c..f99ce32f 100644 --- a/src/Components/Modules/Dedicated.cpp +++ b/src/Components/Modules/Dedicated.cpp @@ -96,7 +96,7 @@ namespace Components Game::SV_GameSendServerCommand(-1, 0, list.data()); } - void Dedicated::TimeWrapStub(int code, const char* message) + void Dedicated::TimeWrapStub(Game::errorParm_t code, const char* message) { static bool partyEnable; static std::string mapname; diff --git a/src/Components/Modules/Dedicated.hpp b/src/Components/Modules/Dedicated.hpp index 162e1a8f..f7210be2 100644 --- a/src/Components/Modules/Dedicated.hpp +++ b/src/Components/Modules/Dedicated.hpp @@ -25,6 +25,6 @@ namespace Components static void TransmitGuids(); - static void TimeWrapStub(int code, const char* message); + static void TimeWrapStub(Game::errorParm_t code, const char* message); }; } diff --git a/src/Components/Modules/Logger.cpp b/src/Components/Modules/Logger.cpp index 22ad6e09..10a38fc9 100644 --- a/src/Components/Modules/Logger.cpp +++ b/src/Components/Modules/Logger.cpp @@ -51,7 +51,7 @@ namespace Components } } - void Logger::ErrorPrint(int error, const std::string& message) + void Logger::ErrorPrint(Game::errorParm_t error, const std::string& message) { #ifdef DEBUG if (IsDebuggerPresent()) __debugbreak(); @@ -60,19 +60,19 @@ namespace Components return Game::Com_Error(error, "%s", message.data()); } - void Logger::Error(int error, const char* message, ...) + void Logger::Error(Game::errorParm_t error, const char* message, ...) { return Logger::ErrorPrint(error, Logger::Format(&message)); } void Logger::Error(const char* message, ...) { - return Logger::ErrorPrint(0, Logger::Format(&message)); + return Logger::ErrorPrint(Game::ERR_FATAL, Logger::Format(&message)); } void Logger::SoftError(const char* message, ...) { - return Logger::ErrorPrint(2, Logger::Format(&message)); + return Logger::ErrorPrint(Game::ERR_SERVERDISCONNECT, Logger::Format(&message)); } std::string Logger::Format(const char** message) diff --git a/src/Components/Modules/Logger.hpp b/src/Components/Modules/Logger.hpp index 26625324..a6799b96 100644 --- a/src/Components/Modules/Logger.hpp +++ b/src/Components/Modules/Logger.hpp @@ -11,9 +11,9 @@ namespace Components static void MessagePrint(int channel, const std::string& message); static void Print(int channel, const char* message, ...); static void Print(const char* message, ...); - static void ErrorPrint(int error, const std::string& message); + static void ErrorPrint(Game::errorParm_t error, const std::string& message); static void Error(const char* message, ...); - static void Error(int error, const char* message, ...); + static void Error(Game::errorParm_t error, const char* message, ...); static void SoftError(const char* message, ...); static bool IsConsoleReady(); diff --git a/src/Components/Modules/Renderer.cpp b/src/Components/Modules/Renderer.cpp index 2422fde2..984474b0 100644 --- a/src/Components/Modules/Renderer.cpp +++ b/src/Components/Modules/Renderer.cpp @@ -108,7 +108,7 @@ namespace Components void Renderer::R_TextureFromCodeError(const char* sampler, Game::GfxCmdBufState* state) { - Game::Com_Error(0, "Tried to use sampler '%s' when it isn't valid for material '%s' and technique '%s'", + Game::Com_Error(Game::ERR_FATAL, "Tried to use sampler '%s' when it isn't valid for material '%s' and technique '%s'", sampler, state->material->info.name, state->technique->name); } diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index 72995ce6..354b9465 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -24,7 +24,7 @@ namespace Components Logger::Print(23, "Error: unknown function %s in %s\n", funcName.data(), Script::ScriptName.data()); Logger::Print(23, "************************************\n"); - Logger::Error(5, "script compile error\nunknown function %s\n%s\n\n", funcName.data(), Script::ScriptName.data()); + Logger::Error(Game::ERR_SCRIPT_DROP, "script compile error\nunknown function %s\n%s\n\n", funcName.data(), Script::ScriptName.data()); } __declspec(naked) void Script::StoreFunctionNameStub() @@ -168,7 +168,7 @@ namespace Components Script::PrintSourcePos(Script::ScriptName.data(), offset); Logger::Print(23, "************************************\n\n"); - Logger::Error(5, "script compile error\n%s\n%s\n(see console for actual details)\n", msgbuf, Script::ScriptName.data()); + Logger::Error(Game::ERR_SCRIPT_DROP, "script compile error\n%s\n%s\n(see console for actual details)\n", msgbuf, Script::ScriptName.data()); } int Script::LoadScriptAndLabel(const std::string& script, const std::string& label) @@ -178,7 +178,7 @@ namespace Components if (!Game::Scr_LoadScript(script.data())) { Logger::Print("Script %s encountered an error while loading. (doesn't exist?)", script.data()); - Logger::Error(1, reinterpret_cast(0x70B810), script.data()); + Logger::Error(Game::ERR_DROP, reinterpret_cast(0x70B810), script.data()); } else { @@ -407,7 +407,7 @@ namespace Components { if (!gentity->client) { - Logger::Error(5, "Entity: %i is not a client", gentity); + Logger::Error(Game::ERR_SCRIPT_DROP, "Entity: %i is not a client", gentity); } return &Game::svs_clients[gentity->s.number]; } diff --git a/src/Components/Modules/ZoneBuilder.cpp b/src/Components/Modules/ZoneBuilder.cpp index efff6316..f8f45fc4 100644 --- a/src/Components/Modules/ZoneBuilder.cpp +++ b/src/Components/Modules/ZoneBuilder.cpp @@ -851,7 +851,7 @@ namespace Components Command::Add("error", [](Command::Params*) { - Game::Com_Error(0, "This is a test %s\n", "error"); + Game::Com_Error(Game::ERR_FATAL, "This is a test %s\n", "error"); }); // now load default assets and shaders @@ -1412,7 +1412,7 @@ namespace Components // build final techsets fastfile if (subCount > 24) { - Logger::ErrorPrint(1, "How did you have 576 fastfiles?\n"); + Logger::ErrorPrint(Game::ERR_DROP, "How did you have 576 fastfiles?\n"); } curTechsets_list.clear(); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 2569dbcf..e98103c4 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -121,7 +121,7 @@ namespace Game typedef void(__cdecl * Com_ClientPacketEvent_t)(); extern Com_ClientPacketEvent_t Com_ClientPacketEvent; - typedef void(__cdecl * Com_Error_t)(int type, const char* message, ...); + typedef void(__cdecl * Com_Error_t)(errorParm_t type, const char* message, ...); extern Com_Error_t Com_Error; typedef void(__cdecl * Com_Printf_t)(int channel, const char *fmt, ...); diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 2d8b443c..63d4ce72 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -177,6 +177,18 @@ namespace Game CS_ACTIVE = 0x5, } clientstate_t; + typedef enum + { + ERR_FATAL = 0x0, + ERR_DROP = 0x1, + ERR_SERVERDISCONNECT = 0x2, + ERR_DISCONNECT = 0x3, + ERR_SCRIPT = 0x4, + ERR_SCRIPT_DROP = 0x5, + ERR_LOCALIZATION = 0x6, + ERR_MAPLOADERRORSUMMARY = 0x7 + } errorParm_t; + struct FxEffectDef; struct pathnode_t; struct pathnode_tree_t; From fb8ecf637fd6c7d7419b207de19c8d84ff5a058a Mon Sep 17 00:00:00 2001 From: FutureRave Date: Tue, 16 Nov 2021 18:21:06 +0000 Subject: [PATCH 21/38] Added random map rotation --- src/Components/Modules/Dedicated.cpp | 55 ++++++++++++++++++++++++++-- src/Components/Modules/Dedicated.hpp | 3 ++ src/STDInclude.hpp | 3 +- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/Components/Modules/Dedicated.cpp b/src/Components/Modules/Dedicated.cpp index 7ff6330c..68223880 100644 --- a/src/Components/Modules/Dedicated.cpp +++ b/src/Components/Modules/Dedicated.cpp @@ -3,6 +3,7 @@ namespace Components { SteamID Dedicated::PlayerGuids[18][2]; + Dvar::Var Dedicated::SVRandomMapRotation; bool Dedicated::IsEnabled() { @@ -119,6 +120,41 @@ namespace Components Game::Com_Error(code, message); } + void Dedicated::RandomizeMapRotation() + { + auto rotation = Dvar::Var("sv_mapRotation").get(); + + const auto tokens = Utils::String::Explode(rotation, ' '); + std::vector> mapRotationPair; + + for (auto i = 0u; i < (tokens.size() - 1); i += 2) + { + if (i + 1 >= tokens.size()) break; + + const std::string key = tokens[i]; + const std::string value = tokens[i + 1]; + mapRotationPair.push_back(std::make_pair(key, value)); + } + + const auto seed = Utils::Cryptography::Rand::GenerateInt(); + std::shuffle(std::begin(mapRotationPair), std::end(mapRotationPair), std::default_random_engine(seed)); + + // Rebuild map rotation using the randomized key/values + rotation.clear(); + for (auto j = 0u; j < mapRotationPair.size(); j++) + { + std::pair pair = mapRotationPair[j]; + rotation.append(pair.first); + rotation.append(" "); + rotation.append(pair.second); + + if (j != mapRotationPair.size() - 1) + rotation.append(" "); + } + + Dvar::Var("sv_mapRotationCurrent").set(rotation); + } + void Dedicated::MapRotate() { if (!Dedicated::IsEnabled() && Dvar::Var("sv_dontrotate").get()) @@ -134,9 +170,10 @@ namespace Components } Logger::Print("Rotating map...\n"); + const auto mapRotation = Dvar::Var("sv_mapRotation").get(); // if nothing, just restart - if (Dvar::Var("sv_mapRotation").get().empty()) + if (mapRotation.empty()) { Logger::Print("No rotation defined, restarting map.\n"); @@ -152,14 +189,23 @@ namespace Components return; } - // first, check if the string contains nothing + // First, check if the string contains nothing if (Dvar::Var("sv_mapRotationCurrent").get().empty()) { Logger::Print("Current map rotation has finished, reloading...\n"); - Dvar::Var("sv_mapRotationCurrent").set(Dvar::Var("sv_mapRotation").get()); + + if (Dedicated::SVRandomMapRotation.get()) + { + Logger::Print("Randomizing map rotaion\n"); + Dedicated::RandomizeMapRotation(); + } + else + { + Dvar::Var("sv_mapRotationCurrent").set(mapRotation); + } } - std::string rotation = Dvar::Var("sv_mapRotationCurrent").get(); + auto rotation = Dvar::Var("sv_mapRotationCurrent").get(); auto tokens = Utils::String::Explode(rotation, ' '); @@ -346,6 +392,7 @@ namespace Components Dvar::OnInit([]() { + Dedicated::SVRandomMapRotation = Dvar::Register("sv_randomMapRotation", false, Game::dvar_flag::DVAR_FLAG_SAVED, "Randomize map rotation when true"); Dvar::Register("sv_sayName", "^7Console", Game::dvar_flag::DVAR_FLAG_NONE, "The name to pose as for 'say' commands"); Dvar::Register("sv_motd", "", Game::dvar_flag::DVAR_FLAG_NONE, "A custom message of the day for servers"); diff --git a/src/Components/Modules/Dedicated.hpp b/src/Components/Modules/Dedicated.hpp index 162e1a8f..aaf51f0d 100644 --- a/src/Components/Modules/Dedicated.hpp +++ b/src/Components/Modules/Dedicated.hpp @@ -15,6 +15,9 @@ namespace Components static void Heartbeat(); private: + static Dvar::Var SVRandomMapRotation; + + static void RandomizeMapRotation(); static void MapRotate(); static void InitDedicatedServer(); diff --git a/src/STDInclude.hpp b/src/STDInclude.hpp index 208e0cab..4ae48092 100644 --- a/src/STDInclude.hpp +++ b/src/STDInclude.hpp @@ -42,10 +42,9 @@ #include #include #include - -// Experimental C++17 features #include #include +#include #pragma warning(pop) From daced4427b364ab820f9ed80e1ea541454235e8c Mon Sep 17 00:00:00 2001 From: FutureRave Date: Tue, 16 Nov 2021 18:33:32 +0000 Subject: [PATCH 22/38] Use auto --- src/Components/Modules/Dedicated.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Components/Modules/Dedicated.cpp b/src/Components/Modules/Dedicated.cpp index 68223880..92728421 100644 --- a/src/Components/Modules/Dedicated.cpp +++ b/src/Components/Modules/Dedicated.cpp @@ -131,8 +131,8 @@ namespace Components { if (i + 1 >= tokens.size()) break; - const std::string key = tokens[i]; - const std::string value = tokens[i + 1]; + const auto& key = tokens[i]; + const auto& value = tokens[i + 1]; mapRotationPair.push_back(std::make_pair(key, value)); } @@ -143,7 +143,7 @@ namespace Components rotation.clear(); for (auto j = 0u; j < mapRotationPair.size(); j++) { - std::pair pair = mapRotationPair[j]; + const auto& pair = mapRotationPair[j]; rotation.append(pair.first); rotation.append(" "); rotation.append(pair.second); @@ -196,7 +196,7 @@ namespace Components if (Dedicated::SVRandomMapRotation.get()) { - Logger::Print("Randomizing map rotaion\n"); + Logger::Print("Randomizing map rotation\n"); Dedicated::RandomizeMapRotation(); } else From 447ab3ea615e324df937743a3ed67d93d1be9932 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Nov 2021 17:24:37 +0000 Subject: [PATCH 23/38] Bump deps/pdcurses from `2e15c90` to `6c31f22` Bumps [deps/pdcurses](https://github.com/wmcbrine/PDCurses) from `2e15c90` to `6c31f22`. - [Release notes](https://github.com/wmcbrine/PDCurses/releases) - [Commits](https://github.com/wmcbrine/PDCurses/compare/2e15c90f122fef329b83a4c3c011f192d97ec516...6c31f226922bd8653e7ed40cd4b11cee9845ea97) --- updated-dependencies: - dependency-name: deps/pdcurses dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/pdcurses | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/pdcurses b/deps/pdcurses index 2e15c90f..6c31f226 160000 --- a/deps/pdcurses +++ b/deps/pdcurses @@ -1 +1 @@ -Subproject commit 2e15c90f122fef329b83a4c3c011f192d97ec516 +Subproject commit 6c31f226922bd8653e7ed40cd4b11cee9845ea97 From ae627d5f8f230aeb5f12cd093199ceabcd423f02 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Mon, 29 Nov 2021 12:26:53 +0000 Subject: [PATCH 24/38] Elevators for trickshotting --- src/Components/Loader.cpp | 1 + src/Components/Loader.hpp | 1 + src/Components/Modules/Elevators.cpp | 81 ++++++++++++++++++++++++++++ src/Components/Modules/Elevators.hpp | 17 ++++++ 4 files changed, 100 insertions(+) create mode 100644 src/Components/Modules/Elevators.cpp create mode 100644 src/Components/Modules/Elevators.hpp diff --git a/src/Components/Loader.cpp b/src/Components/Loader.cpp index fea7625e..3217dcd4 100644 --- a/src/Components/Loader.cpp +++ b/src/Components/Loader.cpp @@ -105,6 +105,7 @@ namespace Components Loader::Register(new Chat()); Loader::Register(new TextRenderer()); Loader::Register(new Movement()); + Loader::Register(new Elevators()); Loader::Register(new Client()); diff --git a/src/Components/Loader.hpp b/src/Components/Loader.hpp index dd948b09..f9d1e6ed 100644 --- a/src/Components/Loader.hpp +++ b/src/Components/Loader.hpp @@ -133,6 +133,7 @@ namespace Components #include "Modules/Chat.hpp" #include "Modules/TextRenderer.hpp" #include "Modules/Movement.hpp" +#include "Modules/Elevators.hpp" #include "Modules/Gamepad.hpp" #include "Modules/Client.hpp" diff --git a/src/Components/Modules/Elevators.cpp b/src/Components/Modules/Elevators.cpp new file mode 100644 index 00000000..c8f5a14a --- /dev/null +++ b/src/Components/Modules/Elevators.cpp @@ -0,0 +1,81 @@ +#include "STDInclude.hpp" + +namespace Components +{ + Game::dvar_t* Elevators::SV_EnableEasyElevators; + + __declspec(naked) void Elevators::PM_CorrectAllSolidStub() + { + __asm + { + push ecx + mov ecx, Elevators::SV_EnableEasyElevators + cmp byte ptr [ecx + 16], 1 + pop ecx + + // Always elevate if SV_EnableEasyElevators is set to 1 + je elevate + + // Original code + cmp byte ptr [eax + 0x29], 0 + + // Original code flow + jz elevate + + push 0x5734FF + retn + + elevate: + push 0x57353D + retn + } + } + + __declspec(naked) void Elevators::PM_CheckDuckStub() + { + __asm + { + push eax + mov eax, Elevators::SV_EnableEasyElevators + cmp byte ptr [eax + 16], 1 + pop eax + + // Always stand if SV_EnableEasyElevators is set to 1 + je stand + + // Original code + cmp byte ptr [esp + 0x38], 0 + + // Original code flow + jnz noStand + + stand: + + push 0x570ED4 + retn + + noStand: + push 0x570EF4 + retn + } + } + + Elevators::Elevators() + { + Dvar::OnInit([] + { + Elevators::SV_EnableEasyElevators = Game::Dvar_RegisterBool("sv_enableEasyElevators", + false, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED, + "Enable easy elevators for trickshotting"); + }); + + Utils::Hook(0x5734F9, Elevators::PM_CorrectAllSolidStub, HOOK_JUMP).install()->quick(); + Utils::Hook::Nop(0x5734FE, 1); + + Utils::Hook(0x570ECD, Elevators::PM_CheckDuckStub, HOOK_JUMP).install()->quick(); + } + + Elevators::~Elevators() + { + } +} diff --git a/src/Components/Modules/Elevators.hpp b/src/Components/Modules/Elevators.hpp new file mode 100644 index 00000000..f5af25fd --- /dev/null +++ b/src/Components/Modules/Elevators.hpp @@ -0,0 +1,17 @@ +#pragma once + +namespace Components +{ + class Elevators : public Component + { + public: + Elevators(); + ~Elevators(); + + private: + static Game::dvar_t* SV_EnableEasyElevators; + + static void PM_CorrectAllSolidStub(); + static void PM_CheckDuckStub(); + }; +} From ed53211400d847ccdc88f04c142de3303ec848b5 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Mon, 29 Nov 2021 14:08:44 +0000 Subject: [PATCH 25/38] Comments as requested --- src/Components/Modules/Elevators.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Components/Modules/Elevators.cpp b/src/Components/Modules/Elevators.cpp index c8f5a14a..cd71382a 100644 --- a/src/Components/Modules/Elevators.cpp +++ b/src/Components/Modules/Elevators.cpp @@ -22,10 +22,12 @@ namespace Components // Original code flow jz elevate + // Go to conditional check for the loop push 0x5734FF retn elevate: + // Continue with loop execution push 0x57353D retn } @@ -50,11 +52,12 @@ namespace Components jnz noStand stand: - + // Player is allowed to stand push 0x570ED4 retn noStand: + // Player will remain ducked push 0x570EF4 retn } @@ -69,9 +72,11 @@ namespace Components "Enable easy elevators for trickshotting"); }); + // Place hook PM_CorrectAllSolid so we may skip PM_Trace check Utils::Hook(0x5734F9, Elevators::PM_CorrectAllSolidStub, HOOK_JUMP).install()->quick(); Utils::Hook::Nop(0x5734FE, 1); + // Place hook PM_CheckDuck so we may skip PM_Trace check Utils::Hook(0x570ECD, Elevators::PM_CheckDuckStub, HOOK_JUMP).install()->quick(); } From 79be9e12d5971308d8571b29428af6dd53ed94a0 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Mon, 29 Nov 2021 17:16:18 +0000 Subject: [PATCH 26/38] Add dvar to disable elevators entirely --- src/Components/Modules/Elevators.cpp | 44 ++++++++++++++++++++++++++-- src/Components/Modules/Elevators.hpp | 2 ++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/Components/Modules/Elevators.cpp b/src/Components/Modules/Elevators.cpp index cd71382a..a932782c 100644 --- a/src/Components/Modules/Elevators.cpp +++ b/src/Components/Modules/Elevators.cpp @@ -3,6 +3,7 @@ namespace Components { Game::dvar_t* Elevators::SV_EnableEasyElevators; + Game::dvar_t* Elevators::SV_DisableElevators; __declspec(naked) void Elevators::PM_CorrectAllSolidStub() { @@ -63,6 +64,39 @@ namespace Components } } + __declspec(naked) void Elevators::PM_GroundTraceStub() + { + __asm + { + push eax + mov eax, Elevators::SV_DisableElevators + cmp byte ptr [eax + 16], 1 + pop eax + + // Always skip PM_CorrectAllSolid if SV_DisableElevators is set to 1 + je noElevators + + // Original code + cmp byte ptr [esp + 0x50], 0 + rep movsd + mov esi, [esp + 0x58] + + // Original code flow + push 0x573694 + retn + + noElevators: + + // Original code + rep movsd + mov esi, [esp + 0x58] + + // Jump over call to PM_CorrectAllSolid + push 0x5736AE + retn + } + } + Elevators::Elevators() { Dvar::OnInit([] @@ -70,14 +104,20 @@ namespace Components Elevators::SV_EnableEasyElevators = Game::Dvar_RegisterBool("sv_enableEasyElevators", false, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED, "Enable easy elevators for trickshotting"); + Elevators::SV_DisableElevators = Game::Dvar_RegisterBool("sv_disableElevators", + false, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED, + "Disable elevators"); }); - // Place hook PM_CorrectAllSolid so we may skip PM_Trace check + // Hook PM_CorrectAllSolid so we may skip PM_Trace check Utils::Hook(0x5734F9, Elevators::PM_CorrectAllSolidStub, HOOK_JUMP).install()->quick(); Utils::Hook::Nop(0x5734FE, 1); - // Place hook PM_CheckDuck so we may skip PM_Trace check + // Hook PM_CheckDuck so we may skip PM_Trace check Utils::Hook(0x570ECD, Elevators::PM_CheckDuckStub, HOOK_JUMP).install()->quick(); + + // Hook PM_GroundTrace so me way skip PM_CorrectAllSolid (disable elevators) + Utils::Hook(0x573689, Elevators::PM_GroundTraceStub, HOOK_JUMP).install()->quick(); } Elevators::~Elevators() diff --git a/src/Components/Modules/Elevators.hpp b/src/Components/Modules/Elevators.hpp index f5af25fd..c01b2c98 100644 --- a/src/Components/Modules/Elevators.hpp +++ b/src/Components/Modules/Elevators.hpp @@ -10,8 +10,10 @@ namespace Components private: static Game::dvar_t* SV_EnableEasyElevators; + static Game::dvar_t* SV_DisableElevators; static void PM_CorrectAllSolidStub(); static void PM_CheckDuckStub(); + static void PM_GroundTraceStub(); }; } From bf9ea143333b9829925328e738f5b5778a18cf46 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Mon, 29 Nov 2021 18:22:21 +0000 Subject: [PATCH 27/38] One feature at the time --- src/Components/Modules/Elevators.cpp | 70 ---------------------------- src/Components/Modules/Elevators.hpp | 3 -- 2 files changed, 73 deletions(-) diff --git a/src/Components/Modules/Elevators.cpp b/src/Components/Modules/Elevators.cpp index a932782c..38c69282 100644 --- a/src/Components/Modules/Elevators.cpp +++ b/src/Components/Modules/Elevators.cpp @@ -2,68 +2,8 @@ namespace Components { - Game::dvar_t* Elevators::SV_EnableEasyElevators; Game::dvar_t* Elevators::SV_DisableElevators; - __declspec(naked) void Elevators::PM_CorrectAllSolidStub() - { - __asm - { - push ecx - mov ecx, Elevators::SV_EnableEasyElevators - cmp byte ptr [ecx + 16], 1 - pop ecx - - // Always elevate if SV_EnableEasyElevators is set to 1 - je elevate - - // Original code - cmp byte ptr [eax + 0x29], 0 - - // Original code flow - jz elevate - - // Go to conditional check for the loop - push 0x5734FF - retn - - elevate: - // Continue with loop execution - push 0x57353D - retn - } - } - - __declspec(naked) void Elevators::PM_CheckDuckStub() - { - __asm - { - push eax - mov eax, Elevators::SV_EnableEasyElevators - cmp byte ptr [eax + 16], 1 - pop eax - - // Always stand if SV_EnableEasyElevators is set to 1 - je stand - - // Original code - cmp byte ptr [esp + 0x38], 0 - - // Original code flow - jnz noStand - - stand: - // Player is allowed to stand - push 0x570ED4 - retn - - noStand: - // Player will remain ducked - push 0x570EF4 - retn - } - } - __declspec(naked) void Elevators::PM_GroundTraceStub() { __asm @@ -101,21 +41,11 @@ namespace Components { Dvar::OnInit([] { - Elevators::SV_EnableEasyElevators = Game::Dvar_RegisterBool("sv_enableEasyElevators", - false, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED, - "Enable easy elevators for trickshotting"); Elevators::SV_DisableElevators = Game::Dvar_RegisterBool("sv_disableElevators", false, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED, "Disable elevators"); }); - // Hook PM_CorrectAllSolid so we may skip PM_Trace check - Utils::Hook(0x5734F9, Elevators::PM_CorrectAllSolidStub, HOOK_JUMP).install()->quick(); - Utils::Hook::Nop(0x5734FE, 1); - - // Hook PM_CheckDuck so we may skip PM_Trace check - Utils::Hook(0x570ECD, Elevators::PM_CheckDuckStub, HOOK_JUMP).install()->quick(); - // Hook PM_GroundTrace so me way skip PM_CorrectAllSolid (disable elevators) Utils::Hook(0x573689, Elevators::PM_GroundTraceStub, HOOK_JUMP).install()->quick(); } diff --git a/src/Components/Modules/Elevators.hpp b/src/Components/Modules/Elevators.hpp index c01b2c98..73af502a 100644 --- a/src/Components/Modules/Elevators.hpp +++ b/src/Components/Modules/Elevators.hpp @@ -9,11 +9,8 @@ namespace Components ~Elevators(); private: - static Game::dvar_t* SV_EnableEasyElevators; static Game::dvar_t* SV_DisableElevators; - static void PM_CorrectAllSolidStub(); - static void PM_CheckDuckStub(); static void PM_GroundTraceStub(); }; } From a54d83945d3ee27eb6527fad4518e340b7c3488d Mon Sep 17 00:00:00 2001 From: FutureRave Date: Mon, 29 Nov 2021 18:36:23 +0000 Subject: [PATCH 28/38] Match sv_enableBounces dvar flags --- src/Components/Modules/Elevators.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Components/Modules/Elevators.cpp b/src/Components/Modules/Elevators.cpp index 38c69282..f297f48a 100644 --- a/src/Components/Modules/Elevators.cpp +++ b/src/Components/Modules/Elevators.cpp @@ -42,8 +42,7 @@ namespace Components Dvar::OnInit([] { Elevators::SV_DisableElevators = Game::Dvar_RegisterBool("sv_disableElevators", - false, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED, - "Disable elevators"); + false, Game::DVAR_FLAG_REPLICATED, "Disable elevators"); }); // Hook PM_GroundTrace so me way skip PM_CorrectAllSolid (disable elevators) From 759634833bf1ff3d44d02c4ba2f148953bb7c2e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Dec 2021 17:19:13 +0000 Subject: [PATCH 29/38] Bump deps/libtommath from `8355b88` to `2cec6ad` Bumps [deps/libtommath](https://github.com/libtom/libtommath) from `8355b88` to `2cec6ad`. - [Release notes](https://github.com/libtom/libtommath/releases) - [Commits](https://github.com/libtom/libtommath/compare/8355b88db088e41d6f7e19a8d58d46c9ed0333d3...2cec6addaf4acbd8250611ec4cecadf1f4d655ee) --- 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 8355b88d..2cec6add 160000 --- a/deps/libtommath +++ b/deps/libtommath @@ -1 +1 @@ -Subproject commit 8355b88db088e41d6f7e19a8d58d46c9ed0333d3 +Subproject commit 2cec6addaf4acbd8250611ec4cecadf1f4d655ee From e4b76a3d1fb283bc92d59e9a6450014e2f0e3456 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Thu, 2 Dec 2021 18:35:20 +0000 Subject: [PATCH 30/38] Remove random function call --- src/Components/Modules/Party.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Modules/Party.cpp b/src/Components/Modules/Party.cpp index 527f5b8b..4d7bc515 100644 --- a/src/Components/Modules/Party.cpp +++ b/src/Components/Modules/Party.cpp @@ -151,7 +151,7 @@ namespace Components Party::Party() { static Game::dvar_t* partyEnable = Dvar::Register("party_enable", Dedicated::IsEnabled(), Game::dvar_flag::DVAR_FLAG_NONE, "Enable party system").get(); - Dvar::Register("xblive_privatematch", true, Game::dvar_flag::DVAR_FLAG_WRITEPROTECTED, "").get(); + Dvar::Register("xblive_privatematch", true, Game::dvar_flag::DVAR_FLAG_WRITEPROTECTED, ""); // various changes to SV_DirectConnect-y stuff to allow non-party joinees Utils::Hook::Set(0x460D96, 0x90E9); 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 31/38] 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 32/38] 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 33/38] 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 34/38] 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 35/38] 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 36/38] 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 0ac4cd1ba39f9d0dfb365c1797164420431fff52 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Dec 2021 17:21:21 +0000 Subject: [PATCH 37/38] Bump deps/pdcurses from `6c31f22` to `f1cd4f4` Bumps [deps/pdcurses](https://github.com/wmcbrine/PDCurses) from `6c31f22` to `f1cd4f4`. - [Release notes](https://github.com/wmcbrine/PDCurses/releases) - [Commits](https://github.com/wmcbrine/PDCurses/compare/6c31f226922bd8653e7ed40cd4b11cee9845ea97...f1cd4f4569451a5028ddf3d3c202f0ad6b1ae446) --- updated-dependencies: - dependency-name: deps/pdcurses dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/pdcurses | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/pdcurses b/deps/pdcurses index 6c31f226..f1cd4f45 160000 --- a/deps/pdcurses +++ b/deps/pdcurses @@ -1 +1 @@ -Subproject commit 6c31f226922bd8653e7ed40cd4b11cee9845ea97 +Subproject commit f1cd4f4569451a5028ddf3d3c202f0ad6b1ae446 From 62bca7f3b2449841c2f1d4ae90a25b772f6530cc Mon Sep 17 00:00:00 2001 From: FutureRave Date: Thu, 9 Dec 2021 17:49:47 +0000 Subject: [PATCH 38/38] 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: