From 286481cbcd6696fc0d2104c2c0db8b520ce7eb9f Mon Sep 17 00:00:00 2001 From: FutureRave Date: Thu, 24 Feb 2022 19:25:58 +0000 Subject: [PATCH] Clean up gsc functions with additional checks --- src/component/command.cpp | 2 +- src/component/gsc.cpp | 28 ++++++++++++++++--------- src/component/notifies.cpp | 8 ++++++- src/component/userinfo.cpp | 43 ++++++++++++++++++++++++++++++-------- src/game/structs.hpp | 31 ++++++++++++++------------- 5 files changed, 77 insertions(+), 35 deletions(-) diff --git a/src/component/command.cpp b/src/component/command.cpp index 007005c..88c88b0 100644 --- a/src/component/command.cpp +++ b/src/component/command.cpp @@ -49,6 +49,7 @@ namespace command if (i > index) result.append(" "); result.append(this->get(i)); } + return result; } @@ -96,7 +97,6 @@ namespace command public: void post_unpack() override { - } }; } diff --git a/src/component/gsc.cpp b/src/component/gsc.cpp index d01147d..1eda243 100644 --- a/src/component/gsc.cpp +++ b/src/component/gsc.cpp @@ -402,8 +402,13 @@ namespace gsc } const auto client = ent.entnum; - const auto message = args[0].as(); + if (game::g_entities[client].client == nullptr) + { + throw std::runtime_error("Not a player entity"); + } + + const auto message = args[0].as(); game::SV_GameSendServerCommand(client, 0, utils::string::va("%c \"%s\"", 84, message.data())); return {}; @@ -416,16 +421,18 @@ namespace gsc throw std::runtime_error("Invalid entity"); } - const auto num = ent.entnum; + const auto client = ent.entnum; + + if (game::g_entities[client].client == nullptr) + { + throw std::runtime_error("Not a player entity"); + } + const auto toggle = args[0].as(); + auto flags = game::g_entities[client].client->ps.perks[0]; - auto g_client = game::g_entities[num].client; - auto playerState = &g_client->ps; - auto flags = playerState->perks[0]; - - playerState->perks[0] = toggle - ? flags | 0x4000u - : flags & ~0x4000u; + game::g_entities[client].client->ps.perks[0] = toggle + ? flags | 0x4000u : flags & ~0x4000u; return {}; }); @@ -438,9 +445,10 @@ namespace gsc } const auto client = ent.entnum; + if (game::g_entities[client].client == nullptr) { - throw std::runtime_error("entity is not a player"); + throw std::runtime_error("Not a player entity"); } return game::svs_clients[client].bIsTestClient; diff --git a/src/component/notifies.cpp b/src/component/notifies.cpp index e47a31d..825c2c9 100644 --- a/src/component/notifies.cpp +++ b/src/component/notifies.cpp @@ -14,7 +14,13 @@ namespace notifies void client_command_stub(int clientNum) { - char cmd[1024] = { 0 }; + char cmd[1024] = {0}; + const auto* entity = &game::g_entities[clientNum]; + + if (entity->client == nullptr) + { + return; // Client is not fully in game yet + } game::SV_Cmd_ArgvBuffer(0, cmd, 1024); diff --git a/src/component/userinfo.cpp b/src/component/userinfo.cpp index b171615..3fe1635 100644 --- a/src/component/userinfo.cpp +++ b/src/component/userinfo.cpp @@ -92,13 +92,18 @@ namespace userinfo gsc::method::add("setname", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value { - const auto name = args[0].as(); - - if (ent.classnum != 0 || ent.entnum > 17) + if (ent.classnum != 0) { throw std::runtime_error("Invalid entity"); } + if (game::g_entities[ent.entnum].client == nullptr) + { + throw std::runtime_error("Not a player entity"); + } + + const auto name = args[0].as(); + userinfo_overrides[ent.entnum]["name"] = name; game::ClientUserinfoChanged(ent.entnum); @@ -107,11 +112,16 @@ namespace userinfo gsc::method::add("resetname", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value { - if (ent.classnum != 0 || ent.entnum > 17) + if (ent.classnum != 0) { throw std::runtime_error("Invalid entity"); } + if (game::g_entities[ent.entnum].client == nullptr) + { + throw std::runtime_error("Not a player entity"); + } + userinfo_overrides[ent.entnum].erase("name"); game::ClientUserinfoChanged(ent.entnum); @@ -120,13 +130,18 @@ namespace userinfo gsc::method::add("setclantag", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value { - const auto name = args[0].as(); - - if (ent.classnum != 0 || ent.entnum > 17) + if (ent.classnum != 0) { throw std::runtime_error("Invalid entity"); } + if (game::g_entities[ent.entnum].client == nullptr) + { + throw std::runtime_error("Not a player entity"); + } + + const auto name = args[0].as(); + userinfo_overrides[ent.entnum]["clantag"] = name; userinfo_overrides[ent.entnum]["ec_TagText"] = name; userinfo_overrides[ent.entnum]["ec_usingTag"] = "1"; @@ -137,11 +152,16 @@ namespace userinfo gsc::method::add("resetclantag", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value { - if (ent.classnum != 0 || ent.entnum > 17) + if (ent.classnum != 0) { throw std::runtime_error("Invalid entity"); } + if (game::g_entities[ent.entnum].client == nullptr) + { + throw std::runtime_error("Not a player entity"); + } + userinfo_overrides[ent.entnum].erase("clantag"); userinfo_overrides[ent.entnum].erase("ec_TagText"); userinfo_overrides[ent.entnum].erase("ec_usingTag"); @@ -152,11 +172,16 @@ namespace userinfo gsc::method::add("removeclantag", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value { - if (ent.classnum != 0 || ent.entnum > 17) + if (ent.classnum != 0) { throw std::runtime_error("Invalid entity"); } + if (game::g_entities[ent.entnum].client == nullptr) + { + throw std::runtime_error("Not a player entity"); + } + userinfo_overrides[ent.entnum]["clantag"] = ""; userinfo_overrides[ent.entnum]["ec_TagText"] = ""; userinfo_overrides[ent.entnum]["ec_usingTag"] = "0"; diff --git a/src/game/structs.hpp b/src/game/structs.hpp index ec63303..6e8c861 100644 --- a/src/game/structs.hpp +++ b/src/game/structs.hpp @@ -26,20 +26,35 @@ namespace game const char** argv[8]; }; + enum netsrc_t + { + NS_CLIENT1 = 0x0, + NS_CLIENT2 = 0x1, + NS_CLIENT3 = 0x2, + NS_CLIENT4 = 0x3, + NS_MAXCLIENTS = 0x4, + NS_SERVER = 0x4, + NS_PACKET = 0x5, + NS_INVALID_NETSRC = 0x6 + }; + struct msg_t { int overflowed; int readOnly; - char* data; - char* splitData; + unsigned char* data; + unsigned char* splitData; int maxsize; int cursize; int splitSize; int readcount; int bit; int lastEntityRef; + netsrc_t targetLocalNetID; }; + static_assert(sizeof(msg_t) == 0x2C); + struct XZoneInfo { const char* name; @@ -328,18 +343,6 @@ namespace game char __pad2[0xEC]; }; - enum netsrc_t - { - NS_CLIENT1 = 0x0, - NS_CLIENT2 = 0x1, - NS_CLIENT3 = 0x2, - NS_CLIENT4 = 0x3, - NS_MAXCLIENTS = 0x4, - NS_SERVER = 0x4, - NS_PACKET = 0x5, - NS_INVALID_NETSRC = 0x6 - }; - enum netadrtype_t { NA_BOT = 0x0,