From 49d5e8437226408d44e53364514ac4b3051fb0ed Mon Sep 17 00:00:00 2001 From: Edo Date: Sun, 27 Nov 2022 19:20:07 +0000 Subject: [PATCH] [Script]: Add method to clear text in HudElems (#604) --- .../Modules/AssetInterfaces/IXAnimParts.cpp | 4 +-- .../Modules/AssetInterfaces/IXModel.cpp | 2 +- src/Components/Modules/Bots.cpp | 4 +-- src/Components/Modules/Chat.cpp | 2 +- src/Components/Modules/FileSystem.cpp | 6 ++-- src/Components/Modules/GSC/GSC.cpp | 2 ++ src/Components/Modules/GSC/IO.cpp | 2 +- src/Components/Modules/GSC/ScriptPatches.cpp | 36 +++++++++++++++++++ src/Components/Modules/GSC/ScriptPatches.hpp | 13 +++++++ src/Components/Modules/ZoneBuilder.cpp | 2 +- src/Game/Functions.cpp | 5 --- src/Game/Functions.hpp | 12 ------- src/Game/Game.cpp | 4 +++ src/Game/Game.hpp | 5 +++ src/Game/Script.cpp | 14 ++++++++ src/Game/Script.hpp | 33 +++++++++++++++-- src/Game/Server.cpp | 4 +++ src/Game/Server.hpp | 6 ++++ src/Game/Structs.hpp | 9 +++++ 19 files changed, 135 insertions(+), 30 deletions(-) create mode 100644 src/Components/Modules/GSC/ScriptPatches.cpp create mode 100644 src/Components/Modules/GSC/ScriptPatches.hpp diff --git a/src/Components/Modules/AssetInterfaces/IXAnimParts.cpp b/src/Components/Modules/AssetInterfaces/IXAnimParts.cpp index 736b0a40..e3e67e6b 100644 --- a/src/Components/Modules/AssetInterfaces/IXAnimParts.cpp +++ b/src/Components/Modules/AssetInterfaces/IXAnimParts.cpp @@ -39,7 +39,7 @@ namespace Assets xanim->names = builder->getAllocator()->allocateArray(xanim->boneCount[Game::PART_TYPE_ALL]); for (int i = 0; i < xanim->boneCount[Game::PART_TYPE_ALL]; ++i) { - xanim->names[i] = Game::SL_GetString(reader.readCString(), 0); + xanim->names[i] = static_cast(Game::SL_GetString(reader.readCString(), 0)); } } @@ -49,7 +49,7 @@ namespace Assets for (int i = 0; i < xanim->notifyCount; ++i) { - xanim->notify[i].name = Game::SL_GetString(reader.readCString(), 0); + xanim->notify[i].name = static_cast(Game::SL_GetString(reader.readCString(), 0)); } } diff --git a/src/Components/Modules/AssetInterfaces/IXModel.cpp b/src/Components/Modules/AssetInterfaces/IXModel.cpp index c10751fd..60dea742 100644 --- a/src/Components/Modules/AssetInterfaces/IXModel.cpp +++ b/src/Components/Modules/AssetInterfaces/IXModel.cpp @@ -128,7 +128,7 @@ namespace Assets for (char i = 0; i < asset->numBones; ++i) { - asset->boneNames[i] = Game::SL_GetString(reader.readCString(), 0); + asset->boneNames[i] = static_cast(Game::SL_GetString(reader.readCString(), 0)); } } diff --git a/src/Components/Modules/Bots.cpp b/src/Components/Modules/Bots.cpp index 2dfe290e..9f9c08bb 100644 --- a/src/Components/Modules/Bots.cpp +++ b/src/Components/Modules/Bots.cpp @@ -96,13 +96,13 @@ namespace Components { Game::Scr_AddString("autoassign"); Game::Scr_AddString("team_marinesopfor"); - Game::Scr_Notify(ent, Game::SL_GetString("menuresponse", 0), 2); + Game::Scr_Notify(ent, static_cast(Game::SL_GetString("menuresponse", 0)), 2); Scheduler::Once([ent] { Game::Scr_AddString(Utils::String::VA("class%u", Utils::Cryptography::Rand::GenerateInt() % 5u)); Game::Scr_AddString("changeclass"); - Game::Scr_Notify(ent, Game::SL_GetString("menuresponse", 0), 2); + Game::Scr_Notify(ent, static_cast(Game::SL_GetString("menuresponse", 0)), 2); }, Scheduler::Pipeline::SERVER, 1s); }, Scheduler::Pipeline::SERVER, 1s); diff --git a/src/Components/Modules/Chat.cpp b/src/Components/Modules/Chat.cpp index 924cb498..a3ada816 100644 --- a/src/Components/Modules/Chat.cpp +++ b/src/Components/Modules/Chat.cpp @@ -73,7 +73,7 @@ namespace Components Game::Scr_AddEntity(player); Game::Scr_AddString(text + msgIndex); - Game::Scr_NotifyLevel(Game::SL_GetString("say", 0), 2); + Game::Scr_NotifyLevel(static_cast(Game::SL_GetString("say", 0)), 2); return text; } diff --git a/src/Components/Modules/FileSystem.cpp b/src/Components/Modules/FileSystem.cpp index 473a38ac..46ae0ca3 100644 --- a/src/Components/Modules/FileSystem.cpp +++ b/src/Components/Modules/FileSystem.cpp @@ -78,19 +78,19 @@ namespace Components Utils::Memory::Allocator allocator; if (!this->exists()) return std::string(); - int position = Game::FS_FTell(this->handle); + const auto position = Game::FS_FTell(this->handle); this->seek(0, Game::FS_SEEK_SET); char* buffer = allocator.allocateArray(this->size); if (!this->read(buffer, this->size)) { this->seek(position, Game::FS_SEEK_SET); - return std::string(); + return {}; } this->seek(position, Game::FS_SEEK_SET); - return std::string(buffer, this->size); + return {buffer, static_cast(this->size)}; } bool FileSystem::FileReader::read(void* buffer, size_t _size) diff --git a/src/Components/Modules/GSC/GSC.cpp b/src/Components/Modules/GSC/GSC.cpp index 3970b014..0cf74f21 100644 --- a/src/Components/Modules/GSC/GSC.cpp +++ b/src/Components/Modules/GSC/GSC.cpp @@ -4,6 +4,7 @@ #include "IO.hpp" #include "Script.hpp" #include "ScriptExtension.hpp" +#include "ScriptPatches.hpp" #include "ScriptStorage.hpp" namespace Components @@ -14,6 +15,7 @@ namespace Components Loader::Register(new IO()); Loader::Register(new Script()); Loader::Register(new ScriptExtension()); + Loader::Register(new ScriptPatches()); Loader::Register(new ScriptStorage()); } } diff --git a/src/Components/Modules/GSC/IO.cpp b/src/Components/Modules/GSC/IO.cpp index e3a420db..5116d32c 100644 --- a/src/Components/Modules/GSC/IO.cpp +++ b/src/Components/Modules/GSC/IO.cpp @@ -126,7 +126,7 @@ namespace Components } } - const auto p = "scriptdata" / std::filesystem::path(path); + const auto p = "scriptdata"s / std::filesystem::path(path); const auto folder = p.parent_path().string(); const auto file = p.filename().string(); Game::Scr_AddInt(FileSystem::_DeleteFile(folder, file)); diff --git a/src/Components/Modules/GSC/ScriptPatches.cpp b/src/Components/Modules/GSC/ScriptPatches.cpp new file mode 100644 index 00000000..4e7843d8 --- /dev/null +++ b/src/Components/Modules/GSC/ScriptPatches.cpp @@ -0,0 +1,36 @@ +#include +#include "ScriptPatches.hpp" +#include "Script.hpp" + +using namespace Utils::String; + +namespace Components +{ + constexpr auto offset = 511; + + Game::game_hudelem_s* ScriptPatches::HECmd_GetHudElem(Game::scr_entref_t entref) + { + if (entref.classnum != 1) + { + Game::Scr_ObjectError("not a hud element"); + return nullptr; + } + + assert(entref.entnum < 1024); + return &Game::g_hudelems[entref.entnum]; + } + + ScriptPatches::ScriptPatches() + { + Script::AddMethod("ClearHudText", [](Game::scr_entref_t entref) -> void + { + auto* hud = HECmd_GetHudElem(entref); + + // Frees config string up + if ((hud->elem).text) + { + Game::SV_SetConfigstring((hud->elem).text + offset, nullptr); + } + }); + } +} diff --git a/src/Components/Modules/GSC/ScriptPatches.hpp b/src/Components/Modules/GSC/ScriptPatches.hpp new file mode 100644 index 00000000..cf4787d0 --- /dev/null +++ b/src/Components/Modules/GSC/ScriptPatches.hpp @@ -0,0 +1,13 @@ +#pragma once + +namespace Components +{ + class ScriptPatches : public Component + { + public: + ScriptPatches(); + + private: + static Game::game_hudelem_s* HECmd_GetHudElem(Game::scr_entref_t entref); + }; +} diff --git a/src/Components/Modules/ZoneBuilder.cpp b/src/Components/Modules/ZoneBuilder.cpp index 2b64618d..0a35ee71 100644 --- a/src/Components/Modules/ZoneBuilder.cpp +++ b/src/Components/Modules/ZoneBuilder.cpp @@ -576,7 +576,7 @@ namespace Components int ZoneBuilder::Zone::addScriptString(const std::string& str) { - return this->addScriptString(Game::SL_GetString(str.data(), 0)); + return this->addScriptString(static_cast(Game::SL_GetString(str.data(), 0))); } // Mark a scriptString for writing and map it. diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 6f9c2c1d..236719c8 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -168,11 +168,6 @@ namespace Game Dvar_SetFloat_t Dvar_SetFloat = Dvar_SetFloat_t(0x40BB20); Dvar_SetInt_t Dvar_SetInt = Dvar_SetInt_t(0x421DA0); - SL_ConvertToString_t SL_ConvertToString = SL_ConvertToString_t(0x4EC1D0); - SL_GetString_t SL_GetString = SL_GetString_t(0x4CDC10); - SL_AddRefToString_t SL_AddRefToString = SL_AddRefToString_t(0x4D9B00); - SL_RemoveRefToString_t SL_RemoveRefToString = SL_RemoveRefToString_t(0x47CD70); - SND_Init_t SND_Init = SND_Init_t(0x46A630); SND_InitDriver_t SND_InitDriver = SND_InitDriver_t(0x4F5090); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 1c12835c..e642bd77 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -389,18 +389,6 @@ namespace Game typedef int(*SEH_GetCurrentLanguage_t)(); extern SEH_GetCurrentLanguage_t SEH_GetCurrentLanguage; - typedef const char*(*SL_ConvertToString_t)(scr_string_t stringValue); - extern SL_ConvertToString_t SL_ConvertToString; - - typedef short(*SL_GetString_t)(const char *str, unsigned int user); - extern SL_GetString_t SL_GetString; - - typedef void(*SL_AddRefToString_t)(unsigned int stringValue); - extern SL_AddRefToString_t SL_AddRefToString; - - typedef void(*SL_RemoveRefToString_t)(unsigned int stringValue); - extern SL_RemoveRefToString_t SL_RemoveRefToString; - typedef void(*SND_Init_t)(int a1, int a2, int a3); extern SND_Init_t SND_Init; diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 876da5fa..a4fd994d 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -12,8 +12,12 @@ namespace Game G_PrintEntities_t G_PrintEntities = G_PrintEntities_t(0x4E6A50); G_GetEntityTypeName_t G_GetEntityTypeName = G_GetEntityTypeName_t(0x4EB810); + G_LocalizedStringIndex_t G_LocalizedStringIndex = G_LocalizedStringIndex_t(0x4582F0); + gentity_t* g_entities = reinterpret_cast(0x18835D8); + const char* origErrorMsg = reinterpret_cast(0x79B124); + XModel* G_GetModel(const int index) { assert(index > 0); diff --git a/src/Game/Game.hpp b/src/Game/Game.hpp index b4d7d3b7..d094afb9 100644 --- a/src/Game/Game.hpp +++ b/src/Game/Game.hpp @@ -40,9 +40,14 @@ namespace Game typedef const char*(*G_GetEntityTypeName_t)(const gentity_s* ent); extern G_GetEntityTypeName_t G_GetEntityTypeName; + typedef int(*G_LocalizedStringIndex_t)(const char* string); + extern G_LocalizedStringIndex_t G_LocalizedStringIndex; + constexpr std::size_t MAX_GENTITIES = 2048; constexpr std::size_t ENTITYNUM_NONE = MAX_GENTITIES - 1; extern gentity_t* g_entities; + extern const char* origErrorMsg; + extern XModel* G_GetModel(int index); } diff --git a/src/Game/Script.cpp b/src/Game/Script.cpp index 7b68bb61..4766e89b 100644 --- a/src/Game/Script.cpp +++ b/src/Game/Script.cpp @@ -56,6 +56,10 @@ namespace Game Scr_SetClientField_t Scr_SetClientField = Scr_SetClientField_t(0x4A6DF0); Scr_AddClassField_t Scr_AddClassField = Scr_AddClassField_t(0x4C0E70); + Scr_ConstructMessageString_t Scr_ConstructMessageString = Scr_ConstructMessageString_t(0x45F940); + + Scr_FreeHudElemConstStrings_t Scr_FreeHudElemConstStrings = Scr_FreeHudElemConstStrings_t(0x5E1120); + GetEntity_t GetEntity = GetEntity_t(0x4BC270); GetPlayerEntity_t GetPlayerEntity = GetPlayerEntity_t(0x49C4A0); @@ -63,11 +67,21 @@ namespace Game Scr_ShutdownAllocNode_t Scr_ShutdownAllocNode = Scr_ShutdownAllocNode_t(0x441650); Scr_IsSystemActive_t Scr_IsSystemActive = Scr_IsSystemActive_t(0x4B24E0); + SL_ConvertToString_t SL_ConvertToString = SL_ConvertToString_t(0x4EC1D0); + SL_GetString_t SL_GetString = SL_GetString_t(0x4CDC10); + SL_GetString__t SL_GetString_ = SL_GetString__t(0x47E310); + SL_FindString_t SL_FindString = SL_FindString_t(0x434EE0); + SL_FindLowercaseString_t SL_FindLowercaseString = SL_FindLowercaseString_t(0x4C63E0); + SL_AddRefToString_t SL_AddRefToString = SL_AddRefToString_t(0x4D9B00); + SL_RemoveRefToString_t SL_RemoveRefToString = SL_RemoveRefToString_t(0x47CD70); + scr_const_t* scr_const = reinterpret_cast(0x1AA2E00); scrVmPub_t* scrVmPub = reinterpret_cast(0x2040CF0); scrVarPub_t* scrVarPub = reinterpret_cast(0x201A408); + game_hudelem_s* g_hudelems = reinterpret_cast(0x18565A8); + void IncInParam() { Scr_ClearOutParams(); diff --git a/src/Game/Script.hpp b/src/Game/Script.hpp index 145dccf6..7c998c50 100644 --- a/src/Game/Script.hpp +++ b/src/Game/Script.hpp @@ -119,10 +119,10 @@ namespace Game typedef int(*Scr_GetPointerType_t)(unsigned int index); extern Scr_GetPointerType_t Scr_GetPointerType; - typedef void(*Scr_Error_t)(const char*); + typedef void(*Scr_Error_t)(const char* error); extern Scr_Error_t Scr_Error; - typedef void(*Scr_ObjectError_t)(const char*); + typedef void(*Scr_ObjectError_t)(const char* error); extern Scr_ObjectError_t Scr_ObjectError; typedef void(*Scr_ParamError_t)(unsigned int paramIndex, const char*); @@ -143,12 +143,39 @@ namespace Game typedef void(*Scr_AddClassField_t)(unsigned int classnum, const char* name, unsigned int offset); extern Scr_AddClassField_t Scr_AddClassField; + typedef void(*Scr_ConstructMessageString_t)(int firstParmIndex, int lastParmIndex, const char* errorContext, char* string, unsigned int stringLimit); + extern Scr_ConstructMessageString_t Scr_ConstructMessageString; + + typedef void(*Scr_FreeHudElemConstStrings_t)(game_hudelem_s* hud); + extern Scr_FreeHudElemConstStrings_t Scr_FreeHudElemConstStrings; + typedef gentity_s*(*GetPlayerEntity_t)(scr_entref_t entref); extern GetPlayerEntity_t GetPlayerEntity; typedef gentity_s*(*GetEntity_t)(scr_entref_t entref); extern GetEntity_t GetEntity; + typedef const char*(*SL_ConvertToString_t)(scr_string_t stringValue); + extern SL_ConvertToString_t SL_ConvertToString; + + typedef unsigned int(*SL_GetString_t)(const char* str, unsigned int user); + extern SL_GetString_t SL_GetString; + + typedef unsigned int(*SL_GetString__t)(const char* str, unsigned int user, int type); + extern SL_GetString__t SL_GetString_; + + typedef unsigned int(*SL_FindString_t)(const char* name); + extern SL_FindString_t SL_FindString; + + typedef unsigned int(*SL_FindLowercaseString_t)(const char* str); + extern SL_FindLowercaseString_t SL_FindLowercaseString; + + typedef void(*SL_AddRefToString_t)(unsigned int stringValue); + extern SL_AddRefToString_t SL_AddRefToString; + + typedef void(*SL_RemoveRefToString_t)(unsigned int stringValue); + extern SL_RemoveRefToString_t SL_RemoveRefToString; + extern void IncInParam(); extern void Scr_AddBool(int value); @@ -161,4 +188,6 @@ namespace Game extern scrVmPub_t* scrVmPub; extern scrVarPub_t* scrVarPub; + + extern game_hudelem_s* g_hudelems; } diff --git a/src/Game/Server.cpp b/src/Game/Server.cpp index 46bb18d8..1f9370d8 100644 --- a/src/Game/Server.cpp +++ b/src/Game/Server.cpp @@ -12,6 +12,7 @@ namespace Game 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_GetConfigstringConst_t SV_GetConfigstringConst = SV_GetConfigstringConst_t(0x468500); SV_Loaded_t SV_Loaded = SV_Loaded_t(0x4EE3E0); SV_ClientThink_t SV_ClientThink = SV_ClientThink_t(0x44ADD0); SV_DropClient_t SV_DropClient = SV_DropClient_t(0x4D1600); @@ -25,6 +26,9 @@ namespace Game int* svs_clientCount = reinterpret_cast(0x31D938C); client_t* svs_clients = reinterpret_cast(0x31D9390); + unsigned short* sv_sconfigstrings = reinterpret_cast(0x208A632); + unsigned short* sv_emptyConfigString = reinterpret_cast(0x208A630); + volatile long* sv_thread_owns_game = reinterpret_cast(0x2089DB8); int SV_GetServerThreadOwnsGame() diff --git a/src/Game/Server.hpp b/src/Game/Server.hpp index 52ecd6df..c1ce9cd0 100644 --- a/src/Game/Server.hpp +++ b/src/Game/Server.hpp @@ -29,6 +29,9 @@ namespace Game typedef void(*SV_SetConfigstring_t)(int index, const char* string); extern SV_SetConfigstring_t SV_SetConfigstring; + typedef unsigned int(*SV_GetConfigstringConst_t)(int index); + extern SV_GetConfigstringConst_t SV_GetConfigstringConst; + typedef void(*SV_DirectConnect_t)(netadr_t adr); extern SV_DirectConnect_t SV_DirectConnect; @@ -58,6 +61,9 @@ namespace Game extern int* svs_clientCount; extern client_t* svs_clients; + extern unsigned short* sv_sconfigstrings; + extern unsigned short* sv_emptyConfigString; + extern volatile long* sv_thread_owns_game; extern int SV_GetServerThreadOwnsGame(); diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index c87612a2..79b398fd 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -272,6 +272,7 @@ namespace Game CS_VOTE_NO = 0x14, CS_VOTE_MAPNAME = 0x15, CS_VOTE_GAMETYPE = 0x16, + CS_SHELLSHOCKS = 0x985, CS_ITEMS = 0x102A, }; // Incomplete @@ -1290,6 +1291,14 @@ namespace Game int flags; }; + struct game_hudelem_s + { + hudelem_s elem; + int clientNum; + int team; + int archived; + }; + enum { PMF_PRONE = 1 << 0,