From 8a770985d61dca9d67cec357f72f44521e7d552f Mon Sep 17 00:00:00 2001 From: Diavolo Date: Fri, 15 Apr 2022 14:50:22 +0200 Subject: [PATCH 01/25] Add branding component --- src/Components/Loader.cpp | 2 +- src/Components/Loader.hpp | 3 +- src/Components/Modules/Branding.cpp | 118 ++++++++++++++++++++++++++ src/Components/Modules/Branding.hpp | 26 ++++++ src/Components/Modules/QuickPatch.cpp | 25 ------ src/Components/Modules/QuickPatch.hpp | 2 - src/Components/Modules/Window.cpp | 2 +- src/Components/Modules/Window.hpp | 2 +- src/Game/Functions.cpp | 20 +++-- src/Game/Functions.hpp | 71 +++++++++------- 10 files changed, 198 insertions(+), 73 deletions(-) create mode 100644 src/Components/Modules/Branding.cpp create mode 100644 src/Components/Modules/Branding.hpp diff --git a/src/Components/Loader.cpp b/src/Components/Loader.cpp index 08ed4485..b1af5759 100644 --- a/src/Components/Loader.cpp +++ b/src/Components/Loader.cpp @@ -69,7 +69,6 @@ namespace Components Loader::Register(new Renderer()); Loader::Register(new UIFeeder()); Loader::Register(new UIScript()); - Loader::Register(new AntiCheat()); Loader::Register(new Changelog()); Loader::Register(new Dedicated()); Loader::Register(new Discovery()); @@ -105,6 +104,7 @@ namespace Components Loader::Register(new Elevators()); Loader::Register(new ClientCommand()); Loader::Register(new ScriptExtension()); + Loader::Register(new Branding()); Loader::Pregame = false; } diff --git a/src/Components/Loader.hpp b/src/Components/Loader.hpp index 9d521bba..52c40528 100644 --- a/src/Components/Loader.hpp +++ b/src/Components/Loader.hpp @@ -99,7 +99,6 @@ namespace Components #include "Modules/RawFiles.hpp" #include "Modules/Renderer.hpp" #include "Modules/UIFeeder.hpp" -#include "Modules/AntiCheat.hpp" #include "Modules/Changelog.hpp" #include "Modules/Dedicated.hpp" #include "Modules/Discovery.hpp" @@ -134,6 +133,6 @@ namespace Components #include "Modules/Movement.hpp" #include "Modules/Elevators.hpp" #include "Modules/ClientCommand.hpp" - #include "Modules/Gamepad.hpp" #include "Modules/ScriptExtension.hpp" +#include "Modules/Branding.hpp" diff --git a/src/Components/Modules/Branding.cpp b/src/Components/Modules/Branding.cpp new file mode 100644 index 00000000..fbc4a9c9 --- /dev/null +++ b/src/Components/Modules/Branding.cpp @@ -0,0 +1,118 @@ +#include + +namespace Components +{ + Dvar::Var Branding::CGDrawVersion; + Dvar::Var Branding::CGDrawVersionX; + Dvar::Var Branding::CGDrawVersionY; + Game::dvar_t** Branding::Version = reinterpret_cast(0x1AD7930); + + void Branding::CG_DrawVersion() + { + // Default values + constexpr auto fontScale = 0.25f; + constexpr auto maxChars = std::numeric_limits::max(); + // Default colours + constexpr Game::vec4_t shadowColor = {0.0f, 0.0f, 0.0f, 0.7f}; + constexpr Game::vec4_t color = {0.4f, 0.7f, 1.0f, 0.7f}; + + auto* const placement = Game::ScrPlace_GetUnsafeFullPlacement(); + auto* const font = Game::UI_GetFontHandle(placement, 0, 0.5f); + + const auto width = Game::UI_TextWidth((*Version)->current.string, 0, font, fontScale); + const auto height = Game::UI_TextHeight(font, fontScale); + + Game::UI_DrawText(placement, (*Version)->current.string, maxChars, font, 1.0f - (CGDrawVersionX.get() + width), + 1.0f - (CGDrawVersionY.get() + height), 3, 3, fontScale, shadowColor, 0); + Game::UI_DrawText(placement, (*Version)->current.string, maxChars, font, (0.0f - width) - CGDrawVersionX.get(), + (0.0f - height) - CGDrawVersionY.get(), 3, 3, fontScale, color, 0); + } + + void Branding::CG_DrawVersion_Hk(int localClientNum) + { + Utils::Hook::Call(0x4EFF80)(localClientNum); + + if (Branding::CGDrawVersion.get()) + { + Branding::CG_DrawVersion(); + } + } + + const char* Branding::GetBuildNumber() + { + static char buf[128]; // Length the game uses + + const auto* data = "latest " __DATE__ " " __TIME__; + sprintf_s(buf, sizeof(buf), "%s %s", SHORTVERSION, data); + + return buf; + } + + // Use IW4x Branding + void Branding::Dvar_SetVersionString(const Game::dvar_t* dvar, const char* /*value*/) + { +#ifdef _DEBUG + const auto* buildType = "IW4x_DEV MP"; +#else + const auto* buildType = "IW4x MP"; +#endif + + // IW4x is technically a beta + const auto* result = Utils::String::VA("%s %s build %s %s", + buildType, "(Beta)", Branding::GetBuildNumber(), reinterpret_cast(0x7170A0)); + + Utils::Hook::Call(0x4A9580)(dvar, result); + } + + Game::dvar_t* Branding::Dvar_RegisterUIBuildLocation(const char* dvarName, + float /*x*/, float /*y*/, float min, float max, int /*flags*/, const char* description) + { +#ifdef _DEBUG + constexpr auto flag = Game::dvar_flag::DVAR_NONE; +#else + constexpr auto flag = Game::dvar_flag::DVAR_READONLY; +#endif + return Game::Dvar_RegisterVec2(dvarName, -60.0f, 474.0f, min, max, flag, description); + } + + void Branding::RegisterBrandingDvars() + { +#ifdef _DEBUG + constexpr auto value = true; +#else + constexpr auto value = false; +#endif + Branding::CGDrawVersion = Dvar::Register("cg_drawVersion", value, + Game::dvar_flag::DVAR_NONE, "Draw the game version"); + Branding::CGDrawVersionX = Dvar::Register("cg_drawVersionX", 50.0f, + 0.0f, 512.0f, Game::dvar_flag::DVAR_NONE, "X offset for the version string"); + Branding::CGDrawVersionY = Dvar::Register("cg_drawVersionY", 18.0f, + 0.0f, 512.0f, Game::dvar_flag::DVAR_NONE, "Y offset for the version string"); + } + + Branding::Branding() + { + Dvar::OnInit(Branding::RegisterBrandingDvars); + + // UI version string + Utils::Hook::Set(0x43F73B, "IW4x: " VERSION); + + // Short version dvar + Utils::Hook::Set(0x60BD91, SHORTVERSION); + + // Console version string + Utils::Hook::Set(0x4B12BB, "IW4x " VERSION " (built " __DATE__ " " __TIME__ ")"); + + // Version string color + static Game::vec4_t buildLocColor = {1.0f, 1.0f, 1.0f, 0.8f}; + Utils::Hook::Set(0x43F710, buildLocColor); + + // Shift ui version string to the left (ui_buildlocation) + Utils::Hook(0x6310A0, Branding::Dvar_RegisterUIBuildLocation, HOOK_CALL).install()->quick(); // Dvar_RegisterVec2 + + Utils::Hook(0x60BD81, Branding::Dvar_SetVersionString, HOOK_CALL).install()->quick(); + + // Hook CG_DrawFullScreenDebugOverlays so we may render the version when it's appropriate + Utils::Hook(0x5AC975, Branding::CG_DrawVersion_Hk, HOOK_CALL).install()->quick(); + } +} diff --git a/src/Components/Modules/Branding.hpp b/src/Components/Modules/Branding.hpp new file mode 100644 index 00000000..a0735a53 --- /dev/null +++ b/src/Components/Modules/Branding.hpp @@ -0,0 +1,26 @@ +#pragma once + +namespace Components +{ + class Branding : public Component + { + public: + Branding(); + + private: + static Dvar::Var CGDrawVersion; + static Dvar::Var CGDrawVersionX; + static Dvar::Var CGDrawVersionY; + static Game::dvar_t** Version; + + static void CG_DrawVersion(); + static void CG_DrawVersion_Hk(int localClientNum); + + static const char* GetBuildNumber(); + static void Dvar_SetVersionString(const Game::dvar_t* dvar, const char* value); + + static Game::dvar_t* Dvar_RegisterUIBuildLocation(const char* dvarName, float x, float y, float min, float max, int flags, const char* description); + + static void RegisterBrandingDvars(); + }; +} diff --git a/src/Components/Modules/QuickPatch.cpp b/src/Components/Modules/QuickPatch.cpp index d8c1d1f6..adcf2415 100644 --- a/src/Components/Modules/QuickPatch.cpp +++ b/src/Components/Modules/QuickPatch.cpp @@ -348,12 +348,6 @@ namespace Components } } - Game::dvar_t* QuickPatch::Dvar_RegisterUIBuildLocation(const char* dvarName, - float /*x*/, float /*y*/, float min, float max, int /*flags*/, const char* description) - { - return Game::Dvar_RegisterVec2(dvarName, -60.0f, 474.0f, min, max, Game::DVAR_READONLY, description); - } - QuickPatch::QuickPatch() { // quitHard @@ -426,22 +420,6 @@ namespace Components // fs_basegame Utils::Hook::Set(0x6431D1, BASEGAME); - // UI version string - Utils::Hook::Set(0x43F73B, "IW4x: " VERSION); - - // console version string - Utils::Hook::Set(0x4B12BB, "IW4x " VERSION " (built " __DATE__ " " __TIME__ ")"); - - // version string - Utils::Hook::Set(0x60BD56, "IW4x (" VERSION ")"); - - // version string color - static Game::vec4_t buildLocColor = { 1.0f, 1.0f, 1.0f, 0.8f }; - Utils::Hook::Set(0x43F710, buildLocColor); - - // Shift ui version string to the left (ui_buildlocation) - Utils::Hook(0x6310A0, QuickPatch::Dvar_RegisterUIBuildLocation, HOOK_CALL).install()->quick(); - // console title if (ZoneBuilder::IsEnabled()) { @@ -462,9 +440,6 @@ namespace Components // sv_hostname Utils::Hook::Set(0x4D378B, "IW4Host"); - // shortversion - Utils::Hook::Set(0x60BD91, SHORTVERSION); - // console logo Utils::Hook::Set(0x428A66, BASEGAME "/images/logo.bmp"); diff --git a/src/Components/Modules/QuickPatch.hpp b/src/Components/Modules/QuickPatch.hpp index 6eac85a2..e3acc495 100644 --- a/src/Components/Modules/QuickPatch.hpp +++ b/src/Components/Modules/QuickPatch.hpp @@ -40,7 +40,5 @@ namespace Components static void CL_KeyEvent_OnEscape(); static void CL_KeyEvent_ConsoleEscape_Stub(); - - static Game::dvar_t* Dvar_RegisterUIBuildLocation(const char* dvarName, float x, float y, float min, float max, int flags, const char* description); }; } diff --git a/src/Components/Modules/Window.cpp b/src/Components/Modules/Window.cpp index a5669656..2a635678 100644 --- a/src/Components/Modules/Window.cpp +++ b/src/Components/Modules/Window.cpp @@ -88,7 +88,7 @@ namespace Components } } - void Window::DrawCursorStub(void *scrPlace, float x, float y, float w, float h, int horzAlign, int vertAlign, const float *color, Game::Material *material) + void Window::DrawCursorStub(Game::ScreenPlacement* scrPlace, float x, float y, float w, float h, int horzAlign, int vertAlign, const float* color, Game::Material* material) { if (Window::NativeCursor.get()) { diff --git a/src/Components/Modules/Window.hpp b/src/Components/Modules/Window.hpp index 37a97547..d170ceab 100644 --- a/src/Components/Modules/Window.hpp +++ b/src/Components/Modules/Window.hpp @@ -32,7 +32,7 @@ namespace Components static BOOL WINAPI MessageHandler(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); static int WINAPI ShowCursorHook(BOOL show); - static void DrawCursorStub(void *scrPlace, float x, float y, float w, float h, int horzAlign, int vertAlign, const float *color, Game::Material *material); + static void DrawCursorStub(Game::ScreenPlacement* scrPlace, float x, float y, float w, float h, int horzAlign, int vertAlign, const float* color, Game::Material* material); static void StyleHookStub(); static HWND WINAPI CreateMainWindow(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam); diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 6e2ff06e..75d37d74 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -192,7 +192,7 @@ namespace Game Load_snd_alias_list_nameArray_t Load_snd_alias_list_nameArray = Load_snd_alias_list_nameArray_t(0x4499F0); Menus_CloseAll_t Menus_CloseAll = Menus_CloseAll_t(0x4BA5B0); - Menus_CloseRequest_t Menus_CloseRequest = Menus_CloseRequest_t(0x430D50); + Menus_CloseRequest_t Menus_CloseRequest = Menus_CloseRequest_t(0x430D50); Menus_OpenByName_t Menus_OpenByName = Menus_OpenByName_t(0x4CCE60); Menus_FindByName_t Menus_FindByName = Menus_FindByName_t(0x487240); Menu_IsVisible_t Menu_IsVisible = Menu_IsVisible_t(0x4D77D0); @@ -378,6 +378,7 @@ namespace Game UI_DrawHandlePic_t UI_DrawHandlePic = UI_DrawHandlePic_t(0x4D0EA0); ScrPlace_GetActivePlacement_t ScrPlace_GetActivePlacement = ScrPlace_GetActivePlacement_t(0x4F8940); UI_TextWidth_t UI_TextWidth = UI_TextWidth_t(0x6315C0); + UI_TextHeight_t UI_TextHeight = UI_TextHeight_t(0x4C8630); UI_DrawText_t UI_DrawText = UI_DrawText_t(0x49C0D0); UI_GetFontHandle_t UI_GetFontHandle = UI_GetFontHandle_t(0x4AEA60); ScrPlace_ApplyRect_t ScrPlace_ApplyRect = ScrPlace_ApplyRect_t(0x454E20); @@ -432,7 +433,7 @@ namespace Game int* svs_clientCount = reinterpret_cast(0x31D938C); client_t* svs_clients = reinterpret_cast(0x31D9390); - UiContext *uiContext = reinterpret_cast(0x62E2858); + UiContext* uiContext = reinterpret_cast(0x62E2858); int* arenaCount = reinterpret_cast(0x62E6930); mapArena_t* arenas = reinterpret_cast(0x62E6934); @@ -460,10 +461,6 @@ namespace Game gentity_t* g_entities = reinterpret_cast(0x18835D8); - int* level_num_entities = reinterpret_cast(0x1A831B0); - int* level_time = reinterpret_cast(0x1A83554); - int* level_scriptPrintChannel = reinterpret_cast(0x1A860FC); - netadr_t* connectedHost = reinterpret_cast(0xA1E888); SOCKET* ip_socket = reinterpret_cast(0x64A3008); @@ -534,9 +531,11 @@ namespace Game XModel** cached_models = reinterpret_cast(0x1AA20C8); + vec3_t* CorrectSolidDeltas = reinterpret_cast(0x739BB8); // Count 26 + FastCriticalSection* db_hashCritSect = reinterpret_cast(0x16B8A54); - vec3_t* CorrectSolidDeltas = reinterpret_cast(0x739BB8); // Count 26 + ScreenPlacement* scrPlaceFullUnsafe = reinterpret_cast(0x1084460); void Sys_LockRead(FastCriticalSection* critSect) { @@ -1102,6 +1101,11 @@ namespace Game return GraphGetValueFromFraction(graph->knotCount, graph->knots, fraction) * graph->scale; } + ScreenPlacement* ScrPlace_GetUnsafeFullPlacement() + { + return scrPlaceFullUnsafe; + } + #pragma optimize("", off) __declspec(naked) float UI_GetScoreboardLeft(void* /*a1*/) { @@ -1576,7 +1580,7 @@ namespace Game __declspec(naked) void AimAssist_UpdateAdsLerp(const AimInput* /*aimInput*/) { - __asm + __asm { mov eax, [esp + 0x4] mov ebx, 0x569AA0 diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 80610630..a8951af3 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -420,7 +420,7 @@ namespace Game typedef void(__cdecl * LargeLocalInit_t)(); extern LargeLocalInit_t LargeLocalInit; - typedef bool(__cdecl * Load_Stream_t)(bool atStreamStart, const void *ptr, unsigned int size); + typedef bool(__cdecl * Load_Stream_t)(bool atStreamStart, const void* ptr, unsigned int size); extern Load_Stream_t Load_Stream; typedef void(__cdecl * Load_XString_t)(bool atStreamStart); @@ -429,64 +429,64 @@ namespace Game typedef void(__cdecl * Load_XModelPtr_t)(bool atStreamStart); extern Load_XModelPtr_t Load_XModelPtr; - typedef void(__cdecl * Load_XModelSurfsFixup_t)(XModelSurfs **, XModelLodInfo *); + typedef void(__cdecl * Load_XModelSurfsFixup_t)(XModelSurfs**, XModelLodInfo*); extern Load_XModelSurfsFixup_t Load_XModelSurfsFixup; typedef void(__cdecl * Load_XStringArray_t)(bool atStreamStart, int count); extern Load_XStringArray_t Load_XStringArray; - typedef void(__cdecl * Load_XStringCustom_t)(const char **str); + typedef void(__cdecl * Load_XStringCustom_t)(const char** str); extern Load_XStringCustom_t Load_XStringCustom; - typedef void(__cdecl *Load_FxEffectDefHandle_t)(bool atStreamStart); + typedef void(__cdecl * Load_FxEffectDefHandle_t)(bool atStreamStart); extern Load_FxEffectDefHandle_t Load_FxEffectDefHandle; - typedef void(__cdecl *Load_FxElemDef_t)(bool atStreamStart); + typedef void(__cdecl * Load_FxElemDef_t)(bool atStreamStart); extern Load_FxElemDef_t Load_FxElemDef; - typedef void(__cdecl *Load_GfxImagePtr_t)(bool atStreamStart); + typedef void(__cdecl * Load_GfxImagePtr_t)(bool atStreamStart); extern Load_GfxImagePtr_t Load_GfxImagePtr; - typedef void(__cdecl *Load_GfxTextureLoad_t)(bool atStreamStart); + typedef void(__cdecl * Load_GfxTextureLoad_t)(bool atStreamStart); extern Load_GfxTextureLoad_t Load_GfxTextureLoad; - typedef int(__cdecl *Load_Texture_t)(GfxImageLoadDef **loadDef, GfxImage *image); + typedef int(__cdecl * Load_Texture_t)(GfxImageLoadDef** loadDef, GfxImage* image); extern Load_Texture_t Load_Texture; typedef void(__cdecl * Load_SndAliasCustom_t)(snd_alias_list_t** var); extern Load_SndAliasCustom_t Load_SndAliasCustom; - typedef void(__cdecl *Load_MaterialHandle_t)(bool atStreamStart); + typedef void(__cdecl * Load_MaterialHandle_t)(bool atStreamStart); extern Load_MaterialHandle_t Load_MaterialHandle; - typedef void(__cdecl *Load_PhysCollmapPtr_t)(bool atStreamStart); + typedef void(__cdecl * Load_PhysCollmapPtr_t)(bool atStreamStart); extern Load_PhysCollmapPtr_t Load_PhysCollmapPtr; - typedef void(__cdecl *Load_PhysPresetPtr_t)(bool atStreamStart); + typedef void(__cdecl * Load_PhysPresetPtr_t)(bool atStreamStart); extern Load_PhysPresetPtr_t Load_PhysPresetPtr; - typedef void(__cdecl *Load_TracerDefPtr_t)(bool atStreamStart); + typedef void(__cdecl * Load_TracerDefPtr_t)(bool atStreamStart); extern Load_TracerDefPtr_t Load_TracerDefPtr; - typedef void(__cdecl *Load_snd_alias_list_nameArray_t)(bool atStreamStart, int count); + typedef void(__cdecl * Load_snd_alias_list_nameArray_t)(bool atStreamStart, int count); extern Load_snd_alias_list_nameArray_t Load_snd_alias_list_nameArray; - typedef void(__cdecl * Menus_CloseAll_t)(UiContext *dc); + typedef void(__cdecl * Menus_CloseAll_t)(UiContext* dc); extern Menus_CloseAll_t Menus_CloseAll; - typedef void(__cdecl * Menus_CloseRequest_t)(UiContext *dc, menuDef_t* menu); - extern Menus_CloseRequest_t Menus_CloseRequest; + typedef void(__cdecl * Menus_CloseRequest_t)(UiContext *dc, menuDef_t* menu); + extern Menus_CloseRequest_t Menus_CloseRequest; - typedef int(__cdecl * Menus_OpenByName_t)(UiContext *dc, const char *p); + typedef int(__cdecl * Menus_OpenByName_t)(UiContext* dc, const char* p); extern Menus_OpenByName_t Menus_OpenByName; - typedef menuDef_t *(__cdecl * Menus_FindByName_t)(UiContext *dc, const char *name); + typedef menuDef_t *(__cdecl * Menus_FindByName_t)(UiContext* dc, const char* name); extern Menus_FindByName_t Menus_FindByName; - typedef bool(__cdecl * Menu_IsVisible_t)(UiContext *dc, menuDef_t *menu); + typedef bool(__cdecl * Menu_IsVisible_t)(UiContext* dc, menuDef_t* menu); extern Menu_IsVisible_t Menu_IsVisible; - typedef bool(__cdecl * Menus_MenuIsInStack_t)(UiContext *dc, menuDef_t *menu); + typedef bool(__cdecl * Menus_MenuIsInStack_t)(UiContext* dc, menuDef_t* menu); extern Menus_MenuIsInStack_t Menus_MenuIsInStack; typedef menuDef_t*(__cdecl * Menu_GetFocused_t)(UiContext* ctx); @@ -498,16 +498,16 @@ namespace Game typedef bool(__cdecl * UI_KeyEvent_t)(int clientNum, int key, int down); extern UI_KeyEvent_t UI_KeyEvent; - typedef const char* (__cdecl * UI_SafeTranslateString_t)(const char* reference); + typedef const char*(__cdecl * UI_SafeTranslateString_t)(const char* reference); extern UI_SafeTranslateString_t UI_SafeTranslateString; typedef void(__cdecl * UI_ReplaceConversions_t)(const char* sourceString, ConversionArguments* arguments, char* outputString, size_t outputStringSize); extern UI_ReplaceConversions_t UI_ReplaceConversions; - typedef void(__cdecl * MSG_Init_t)(msg_t *buf, char *data, int length); + typedef void(__cdecl * MSG_Init_t)(msg_t* buf, char* data, int length); extern MSG_Init_t MSG_Init; - typedef void(__cdecl * MSG_ReadData_t)(msg_t *msg, void *data, int len); + typedef void(__cdecl * MSG_ReadData_t)(msg_t* msg, void* data, int len); extern MSG_ReadData_t MSG_ReadData; typedef int(__cdecl * MSG_ReadLong_t)(msg_t* msg); @@ -894,16 +894,16 @@ namespace Game typedef void(__cdecl * Sys_SuspendOtherThreads_t)(); extern Sys_SuspendOtherThreads_t Sys_SuspendOtherThreads; - typedef void(__cdecl * UI_AddMenuList_t)(UiContext *dc, MenuList *menuList, int close); + typedef void(__cdecl * UI_AddMenuList_t)(UiContext* dc, MenuList* menuList, int close); extern UI_AddMenuList_t UI_AddMenuList; typedef uiMenuCommand_t(__cdecl * UI_GetActiveMenu_t)(int localClientNum); extern UI_GetActiveMenu_t UI_GetActiveMenu; - typedef char* (__cdecl * UI_CheckStringTranslation_t)(char*, char*); + typedef char*(__cdecl * UI_CheckStringTranslation_t)(char*, char*); extern UI_CheckStringTranslation_t UI_CheckStringTranslation; - typedef MenuList *(__cdecl * UI_LoadMenus_t)(const char *menuFile, int imageTrack); + typedef MenuList*(__cdecl * UI_LoadMenus_t)(const char* menuFile, int imageTrack); extern UI_LoadMenus_t UI_LoadMenus; typedef void(__cdecl * UI_UpdateArenas_t)(); @@ -912,15 +912,18 @@ namespace Game typedef void(__cdecl * UI_SortArenas_t)(); extern UI_SortArenas_t UI_SortArenas; - typedef void(__cdecl * UI_DrawHandlePic_t)(/*ScreenPlacement*/void *scrPlace, float x, float y, float w, float h, int horzAlign, int vertAlign, const float *color, Material *material); + typedef void(__cdecl * UI_DrawHandlePic_t)(ScreenPlacement* scrPlace, float x, float y, float w, float h, int horzAlign, int vertAlign, const float* color, Material* material); extern UI_DrawHandlePic_t UI_DrawHandlePic; typedef ScreenPlacement*(__cdecl * ScrPlace_GetActivePlacement_t)(int localClientNum); extern ScrPlace_GetActivePlacement_t ScrPlace_GetActivePlacement; - typedef int(__cdecl * UI_TextWidth_t)(const char *text, int maxChars, Font_s *font, float scale); + typedef int(__cdecl * UI_TextWidth_t)(const char* text, int maxChars, Font_s *font, float scale); extern UI_TextWidth_t UI_TextWidth; + typedef int(__cdecl * UI_TextHeight_t)(Font_s* font, float scale); + extern UI_TextHeight_t UI_TextHeight; + typedef void(__cdecl * UI_DrawText_t)(const ScreenPlacement* scrPlace, const char* text, int maxChars, Font_s* font, float x, float y, int horzAlign, int vertAlign, float scale, const float* color, int style); extern UI_DrawText_t UI_DrawText; @@ -1006,7 +1009,7 @@ namespace Game extern source_t **sourceFiles; extern keywordHash_t **menuParseKeywordHash; - extern UiContext *uiContext; + extern UiContext* uiContext; extern int* arenaCount; extern mapArena_t* arenas; @@ -1036,10 +1039,6 @@ namespace Game constexpr auto ENTITYNUM_NONE = MAX_GENTITIES - 1; extern gentity_t* g_entities; - extern int* level_num_entities; - extern int* level_time; - extern int* level_scriptPrintChannel; - extern netadr_t* connectedHost; extern SOCKET* ip_socket; @@ -1117,11 +1116,17 @@ namespace Game extern FastCriticalSection* db_hashCritSect; + extern ScreenPlacement* scrPlaceFullUnsafe; + + extern level_locals_t* level; + void Sys_LockRead(FastCriticalSection* critSect); void Sys_UnlockRead(FastCriticalSection* critSect); XModel* G_GetModel(int index); + ScreenPlacement* ScrPlace_GetUnsafeFullPlacement(); + XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize); void Menu_FreeItemMemory(Game::itemDef_s* item); void Menu_SetNextCursorItem(Game::UiContext* ctx, Game::menuDef_t* currentMenu, int unk = 1); From 790b75e18693c54c487709848e2d4bf979d2a3bf Mon Sep 17 00:00:00 2001 From: Diavolo Date: Fri, 15 Apr 2022 18:17:20 +0200 Subject: [PATCH 02/25] Clean up Premake5.lua --- premake5.lua | 4 ++-- src/Game/Functions.hpp | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/premake5.lua b/premake5.lua index 47c2b42f..4a5fbe51 100644 --- a/premake5.lua +++ b/premake5.lua @@ -161,7 +161,7 @@ newaction { local versionHeader = assert(io.open(wks.location .. "/src/version.h", "w")) versionHeader:write("/*\n") versionHeader:write(" * Automatically generated by premake5.\n") - versionHeader:write(" * Do not touch, you fucking moron!\n") + versionHeader:write(" * Do not touch!\n") versionHeader:write(" */\n") versionHeader:write("\n") versionHeader:write("#define GIT_DESCRIBE " .. gitDescribeOutputQuoted .. "\n") @@ -181,7 +181,7 @@ newaction { local versionHeader = assert(io.open(wks.location .. "/src/version.hpp", "w")) versionHeader:write("/*\n") versionHeader:write(" * Automatically generated by premake5.\n") - versionHeader:write(" * Do not touch, you fucking moron!\n") + versionHeader:write(" * Do not touch!\n") versionHeader:write(" *\n") versionHeader:write(" * This file exists for reasons of complying with our coding standards.\n") versionHeader:write(" *\n") diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index a8951af3..9994409b 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -867,7 +867,7 @@ namespace Game typedef bool(__cdecl * Sys_IsDatabaseThread_t)(); extern Sys_IsDatabaseThread_t Sys_IsDatabaseThread; - typedef char** (__cdecl * Sys_ListFiles_t)(const char *directory, const char *extension, const char *filter, int *numfiles, int wantsubs); + typedef char**(__cdecl * Sys_ListFiles_t)(const char* directory, const char* extension, const char* filter, int* numfiles, int wantsubs); extern Sys_ListFiles_t Sys_ListFiles; typedef int(__cdecl * Sys_Milliseconds_t)(); @@ -918,7 +918,7 @@ namespace Game typedef ScreenPlacement*(__cdecl * ScrPlace_GetActivePlacement_t)(int localClientNum); extern ScrPlace_GetActivePlacement_t ScrPlace_GetActivePlacement; - typedef int(__cdecl * UI_TextWidth_t)(const char* text, int maxChars, Font_s *font, float scale); + typedef int(__cdecl * UI_TextWidth_t)(const char* text, int maxChars, Font_s* font, float scale); extern UI_TextWidth_t UI_TextWidth; typedef int(__cdecl * UI_TextHeight_t)(Font_s* font, float scale); @@ -930,13 +930,13 @@ namespace Game typedef Font_s* (__cdecl* UI_GetFontHandle_t)(ScreenPlacement* scrPlace, int fontEnum, float scale); extern UI_GetFontHandle_t UI_GetFontHandle; - typedef void(__cdecl* ScrPlace_ApplyRect_t)(ScreenPlacement* a1, float* x, float* y, float* w, float* h, int horzAlign, int vertAlign); + typedef void(__cdecl* ScrPlace_ApplyRect_t)(const ScreenPlacement* scrPlace, float* x, float* y, float* w, float* h, int horzAlign, int vertAlign); extern ScrPlace_ApplyRect_t ScrPlace_ApplyRect; - typedef const char * (__cdecl * Win_GetLanguage_t)(); + typedef const char*(__cdecl * Win_GetLanguage_t)(); extern Win_GetLanguage_t Win_GetLanguage; - typedef void (__cdecl * Vec3UnpackUnitVec_t)(PackedUnitVec, vec3_t *); + typedef void(__cdecl * Vec3UnpackUnitVec_t)(PackedUnitVec, vec3_t*); extern Vec3UnpackUnitVec_t Vec3UnpackUnitVec; typedef float(__cdecl * vectoyaw_t)(vec2_t* vec); From b99ad565bb2bf4cc1ae8cbcc3ff0e1c6f2c92a6b Mon Sep 17 00:00:00 2001 From: Diavolo Date: Sat, 16 Apr 2022 17:11:08 +0200 Subject: [PATCH 03/25] Cleanup code a bit --- src/Components/Modules/Branding.cpp | 25 +++++++++++++++++++------ src/Components/Modules/Branding.hpp | 6 +++++- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/Components/Modules/Branding.cpp b/src/Components/Modules/Branding.cpp index fbc4a9c9..cb713665 100644 --- a/src/Components/Modules/Branding.cpp +++ b/src/Components/Modules/Branding.cpp @@ -43,13 +43,12 @@ namespace Components static char buf[128]; // Length the game uses const auto* data = "latest " __DATE__ " " __TIME__; - sprintf_s(buf, sizeof(buf), "%s %s", SHORTVERSION, data); + sprintf_s(buf, "%s %s", SHORTVERSION, data); return buf; } - // Use IW4x Branding - void Branding::Dvar_SetVersionString(const Game::dvar_t* dvar, const char* /*value*/) + const char* Branding::GetVersionString() { #ifdef _DEBUG const auto* buildType = "IW4x_DEV MP"; @@ -61,9 +60,22 @@ namespace Components const auto* result = Utils::String::VA("%s %s build %s %s", buildType, "(Beta)", Branding::GetBuildNumber(), reinterpret_cast(0x7170A0)); + return result; + } + + void Branding::Dvar_SetVersionString(const Game::dvar_t* dvar, const char* /*value*/) + { + const auto* result = Branding::GetVersionString(); Utils::Hook::Call(0x4A9580)(dvar, result); } + // Branding this might be a good idea in case this LSP logging ever gets turned on for some reason + void Branding::MSG_WriteVersionStringHeader(Game::msg_t* msg, const char* /*string*/) + { + const auto* result = Branding::GetVersionString(); + Utils::Hook::Call(0x463820)(msg, result); + } + Game::dvar_t* Branding::Dvar_RegisterUIBuildLocation(const char* dvarName, float /*x*/, float /*y*/, float min, float max, int /*flags*/, const char* description) { @@ -100,18 +112,19 @@ namespace Components // Short version dvar Utils::Hook::Set(0x60BD91, SHORTVERSION); - // Console version string - Utils::Hook::Set(0x4B12BB, "IW4x " VERSION " (built " __DATE__ " " __TIME__ ")"); + Utils::Hook(0x4B12B0, Branding::GetBuildNumber, HOOK_JUMP).install()->quick(); // Version string color static Game::vec4_t buildLocColor = {1.0f, 1.0f, 1.0f, 0.8f}; Utils::Hook::Set(0x43F710, buildLocColor); - // Shift ui version string to the left (ui_buildlocation) + // Place ui version string to bottom right corner (ui_buildlocation) Utils::Hook(0x6310A0, Branding::Dvar_RegisterUIBuildLocation, HOOK_CALL).install()->quick(); // Dvar_RegisterVec2 Utils::Hook(0x60BD81, Branding::Dvar_SetVersionString, HOOK_CALL).install()->quick(); + Utils::Hook(0x4DA842, Branding::MSG_WriteVersionStringHeader, HOOK_CALL).install()->quick(); + // Hook CG_DrawFullScreenDebugOverlays so we may render the version when it's appropriate Utils::Hook(0x5AC975, Branding::CG_DrawVersion_Hk, HOOK_CALL).install()->quick(); } diff --git a/src/Components/Modules/Branding.hpp b/src/Components/Modules/Branding.hpp index a0735a53..b8424ae4 100644 --- a/src/Components/Modules/Branding.hpp +++ b/src/Components/Modules/Branding.hpp @@ -7,6 +7,9 @@ namespace Components public: Branding(); + static const char* GetBuildNumber(); + static const char* GetVersionString(); + private: static Dvar::Var CGDrawVersion; static Dvar::Var CGDrawVersionX; @@ -16,8 +19,9 @@ namespace Components static void CG_DrawVersion(); static void CG_DrawVersion_Hk(int localClientNum); - static const char* GetBuildNumber(); + // Use IW4x Branding static void Dvar_SetVersionString(const Game::dvar_t* dvar, const char* value); + static void MSG_WriteVersionStringHeader(Game::msg_t* msg, const char* string); static Game::dvar_t* Dvar_RegisterUIBuildLocation(const char* dvarName, float x, float y, float min, float max, int flags, const char* description); From 0955d451cd2073eddce6dbb70ec14ddd238d3dfa Mon Sep 17 00:00:00 2001 From: Diavolo Date: Thu, 21 Apr 2022 20:37:14 +0200 Subject: [PATCH 04/25] Fix color --- src/Components/Modules/Branding.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Modules/Branding.cpp b/src/Components/Modules/Branding.cpp index cb713665..a5a4c954 100644 --- a/src/Components/Modules/Branding.cpp +++ b/src/Components/Modules/Branding.cpp @@ -13,8 +13,8 @@ namespace Components constexpr auto fontScale = 0.25f; constexpr auto maxChars = std::numeric_limits::max(); // Default colours - constexpr Game::vec4_t shadowColor = {0.0f, 0.0f, 0.0f, 0.7f}; - constexpr Game::vec4_t color = {0.4f, 0.7f, 1.0f, 0.7f}; + constexpr Game::vec4_t shadowColor = {0.0f, 0.0f, 0.0f, 0.69f}; + constexpr Game::vec4_t color = {0.4f, 0.69f, 1.0f, 0.69f}; auto* const placement = Game::ScrPlace_GetUnsafeFullPlacement(); auto* const font = Game::UI_GetFontHandle(placement, 0, 0.5f); From d28dc6ecc46a6451ece3764f47a5d3bfb573c0eb Mon Sep 17 00:00:00 2001 From: FutureRave Date: Wed, 4 May 2022 00:03:11 +0100 Subject: [PATCH 05/25] [Dedicated] fix sv_lanOnly --- src/Components/Modules/Dedicated.cpp | 14 +++++++++++++- src/Components/Modules/Dedicated.hpp | 1 + src/Components/Modules/Node.cpp | 4 ++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/Components/Modules/Dedicated.cpp b/src/Components/Modules/Dedicated.cpp index 6043607a..da207d22 100644 --- a/src/Components/Modules/Dedicated.cpp +++ b/src/Components/Modules/Dedicated.cpp @@ -3,7 +3,9 @@ namespace Components { SteamID Dedicated::PlayerGuids[18][2]; + Dvar::Var Dedicated::SVRandomMapRotation; + Dvar::Var Dedicated::SVLanOnly; bool Dedicated::IsEnabled() { @@ -290,7 +292,11 @@ namespace Components // Make sure all callbacks are handled Scheduler::OnFrame(Steam::SteamAPI_RunCallbacks); - Dvar::Register("sv_lanOnly", false, Game::dvar_flag::DVAR_NONE, "Don't act as node"); + Dvar::OnInit([] + { + Dedicated::SVLanOnly = Dvar::Register("sv_lanOnly", false, + Game::dvar_flag::DVAR_NONE, "Don't act as node"); + }); Utils::Hook(0x60BE98, Dedicated::InitDedicatedServer, HOOK_CALL).install()->quick(); @@ -380,6 +386,12 @@ namespace Components { static Utils::Time::Interval interval; + // Do not send an heartbeat if sv_lanOnly is set to true + if (Dedicated::SVLanOnly.get()) + { + return; + } + if (Dvar::Var("sv_maxclients").get() > 0 && interval.elapsed(2min)) { interval.update(); diff --git a/src/Components/Modules/Dedicated.hpp b/src/Components/Modules/Dedicated.hpp index cfcbc539..80b39795 100644 --- a/src/Components/Modules/Dedicated.hpp +++ b/src/Components/Modules/Dedicated.hpp @@ -8,6 +8,7 @@ namespace Components Dedicated(); static SteamID PlayerGuids[18][2]; + static Dvar::Var SVLanOnly; static bool IsEnabled(); diff --git a/src/Components/Modules/Node.cpp b/src/Components/Modules/Node.cpp index 60d1d18b..9ed8e9c9 100644 --- a/src/Components/Modules/Node.cpp +++ b/src/Components/Modules/Node.cpp @@ -114,7 +114,7 @@ namespace Components void Node::StoreNodes(bool force) { - if (Dedicated::IsEnabled() && Dvar::Var("sv_lanOnly").get()) return; + if (Dedicated::IsEnabled() && Dedicated::SVLanOnly.get()) return; static Utils::Time::Interval interval; if (!force && !interval.elapsed(1min)) return; @@ -168,7 +168,7 @@ namespace Components void Node::RunFrame() { if (ServerList::useMasterServer) return; - if (Dedicated::IsEnabled() && Dvar::Var("sv_lanOnly").get()) return; + if (Dedicated::IsEnabled() && Dedicated::SVLanOnly.get()) return; if (!Dedicated::IsEnabled() && *Game::clcState > 0) { From 219a10d6a0cdad0312e5afd6a39b9faecf605200 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Wed, 4 May 2022 00:26:53 +0100 Subject: [PATCH 06/25] [Dedicated] Actually fix sv_lanOnly --- src/Components/Modules/Dedicated.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Components/Modules/Dedicated.cpp b/src/Components/Modules/Dedicated.cpp index da207d22..582bebb0 100644 --- a/src/Components/Modules/Dedicated.cpp +++ b/src/Components/Modules/Dedicated.cpp @@ -252,9 +252,15 @@ namespace Components } void Dedicated::Heartbeat() - { - int masterPort = Dvar::Var("masterPort").get(); - const char* masterServerName = Dvar::Var("masterServerName").get(); + { + // Do not send a heartbeat if sv_lanOnly is set to true + if (Dedicated::SVLanOnly.get()) + { + return; + } + + auto masterPort = Dvar::Var("masterPort").get(); + const auto* masterServerName = Dvar::Var("masterServerName").get(); Network::Address master(Utils::String::VA("%s:%u", masterServerName, masterPort)); @@ -386,12 +392,6 @@ namespace Components { static Utils::Time::Interval interval; - // Do not send an heartbeat if sv_lanOnly is set to true - if (Dedicated::SVLanOnly.get()) - { - return; - } - if (Dvar::Var("sv_maxclients").get() > 0 && interval.elapsed(2min)) { interval.update(); From 8d31466fc5fa7999358841b85e1ce36bbeb26e0d Mon Sep 17 00:00:00 2001 From: FutureRave Date: Wed, 4 May 2022 12:44:45 +0100 Subject: [PATCH 07/25] [Script] GScr_IsArray --- src/Components/Modules/ClientCommand.cpp | 2 +- src/Components/Modules/Download.cpp | 4 +- src/Components/Modules/Script.cpp | 26 +++---- src/Components/Modules/ScriptExtension.cpp | 34 ++++++++-- src/Game/Functions.cpp | 1 + src/Game/Functions.hpp | 5 +- src/Game/Structs.hpp | 79 ++++++++++++++++------ 7 files changed, 108 insertions(+), 43 deletions(-) diff --git a/src/Components/Modules/ClientCommand.cpp b/src/Components/Modules/ClientCommand.cpp index 060fb81f..7d8436da 100644 --- a/src/Components/Modules/ClientCommand.cpp +++ b/src/Components/Modules/ClientCommand.cpp @@ -354,7 +354,7 @@ namespace Components } }); - Script::AddFunction("DropAllBots", []() // gsc: DropAllBots(); + Script::AddFunction("DropAllBots", [] // gsc: DropAllBots(); { Game::SV_DropAllBots(); }); diff --git a/src/Components/Modules/Download.cpp b/src/Components/Modules/Download.cpp index c9d875da..5865d569 100644 --- a/src/Components/Modules/Download.cpp +++ b/src/Components/Modules/Download.cpp @@ -964,7 +964,7 @@ namespace Components Download::ScriptDownloads.clear(); }); - Script::AddFunction("HttpGet", []() + Script::AddFunction("HttpGet", [] { if (!Flags::HasFlag("scriptablehttp")) return; @@ -985,7 +985,7 @@ namespace Components Game::RemoveRefToObject(object); }); - Script::AddFunction("HttpCancel", []() + Script::AddFunction("HttpCancel", [] { if (!Flags::HasFlag("scriptablehttp")) return; diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index 798a2541..cb4dc4e9 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -431,7 +431,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].type = Game::scrParamType_t::VAR_FLOAT; Game::scrVmPub->top[-6].u.floatValue = 0.0f; ++Game::scrVmPub->outparamcount; @@ -450,7 +450,7 @@ namespace Components const auto value = &Game::scrVmPub->top[-index]; - if (value->type != Game::VAR_FUNCTION) + if (value->type != Game::scrParamType_t::VAR_FUNCTION) { Game::Scr_ParamError(static_cast(index), "^1GetCodePosForParam: Expects a function as parameter!\n"); return ""; @@ -549,7 +549,7 @@ namespace Components void Script::AddFunctions() { - Script::AddFunction("ReplaceFunc", []() // gsc: ReplaceFunc(, ) + Script::AddFunction("ReplaceFunc", [] // gsc: ReplaceFunc(, ) { if (Game::Scr_GetNumParam() != 2u) { @@ -564,7 +564,7 @@ namespace Components }); // System time - Script::AddFunction("GetSystemTime", []() // gsc: GetSystemTime() + Script::AddFunction("GetSystemTime", [] // gsc: GetSystemTime() { SYSTEMTIME time; GetSystemTime(&time); @@ -572,7 +572,7 @@ namespace Components Game::Scr_AddInt(time.wSecond); }); - Script::AddFunction("GetSystemMilliseconds", []() // gsc: GetSystemMilliseconds() + Script::AddFunction("GetSystemMilliseconds", [] // gsc: GetSystemMilliseconds() { SYSTEMTIME time; GetSystemTime(&time); @@ -581,7 +581,7 @@ namespace Components }); // Executes command to the console - Script::AddFunction("Exec", []() // gsc: Exec() + Script::AddFunction("Exec", [] // gsc: Exec() { const auto str = Game::Scr_GetString(0); @@ -595,7 +595,7 @@ namespace Components }); // Allow printing to the console even when developer is 0 - Script::AddFunction("PrintConsole", []() // gsc: PrintConsole() + Script::AddFunction("PrintConsole", [] // gsc: PrintConsole() { for (auto i = 0u; i < Game::Scr_GetNumParam(); i++) { @@ -612,7 +612,7 @@ namespace Components }); // Script Storage Functions - Script::AddFunction("StorageSet", []() // gsc: StorageSet(, ); + Script::AddFunction("StorageSet", [] // gsc: StorageSet(, ); { const auto* key = Game::Scr_GetString(0); const auto* value = Game::Scr_GetString(1); @@ -626,7 +626,7 @@ namespace Components Script::ScriptStorage.insert_or_assign(key, value); }); - Script::AddFunction("StorageRemove", []() // gsc: StorageRemove(); + Script::AddFunction("StorageRemove", [] // gsc: StorageRemove(); { const auto* key = Game::Scr_GetString(0); @@ -645,7 +645,7 @@ namespace Components Script::ScriptStorage.erase(key); }); - Script::AddFunction("StorageGet", []() // gsc: StorageGet(); + Script::AddFunction("StorageGet", [] // gsc: StorageGet(); { const auto* key = Game::Scr_GetString(0); @@ -665,7 +665,7 @@ namespace Components Game::Scr_AddString(data.data()); }); - Script::AddFunction("StorageHas", []() // gsc: StorageHas(); + Script::AddFunction("StorageHas", [] // gsc: StorageHas(); { const auto* key = Game::Scr_GetString(0); @@ -678,7 +678,7 @@ namespace Components Game::Scr_AddBool(static_cast(Script::ScriptStorage.count(key))); // Until C++17 }); - Script::AddFunction("StorageClear", []() // gsc: StorageClear(); + Script::AddFunction("StorageClear", [] // gsc: StorageClear(); { Script::ScriptStorage.clear(); }); @@ -746,7 +746,7 @@ namespace Components }); #ifdef _DEBUG - Script::AddFunction("DebugBox", []() + Script::AddFunction("DebugBox", [] { const auto* message = Game::Scr_GetString(0); diff --git a/src/Components/Modules/ScriptExtension.cpp b/src/Components/Modules/ScriptExtension.cpp index 68e80a7a..66e166de 100644 --- a/src/Components/Modules/ScriptExtension.cpp +++ b/src/Components/Modules/ScriptExtension.cpp @@ -116,7 +116,7 @@ namespace Components void ScriptExtension::AddFunctions() { // File functions - Script::AddFunction("FileWrite", []() // gsc: FileWrite(, , ) + Script::AddFunction("FileWrite", [] // gsc: FileWrite(, , ) { const auto* path = Game::Scr_GetString(0); auto* text = Game::Scr_GetString(1); @@ -159,7 +159,7 @@ namespace Components } }); - Script::AddFunction("FileRead", []() // gsc: FileRead() + Script::AddFunction("FileRead", [] // gsc: FileRead() { const auto* path = Game::Scr_GetString(0); @@ -187,7 +187,7 @@ namespace Components Game::Scr_AddString(FileSystem::FileReader(path).getBuffer().data()); }); - Script::AddFunction("FileExists", []() // gsc: FileExists() + Script::AddFunction("FileExists", [] // gsc: FileExists() { const auto* path = Game::Scr_GetString(0); @@ -209,7 +209,7 @@ namespace Components Game::Scr_AddInt(FileSystem::FileReader(path).exists()); }); - Script::AddFunction("FileRemove", []() // gsc: FileRemove() + Script::AddFunction("FileRemove", [] // gsc: FileRemove() { const auto* path = Game::Scr_GetString(0); @@ -235,7 +235,7 @@ namespace Components }); // Misc functions - Script::AddFunction("ToUpper", []() // gsc: ToUpper() + Script::AddFunction("ToUpper", [] // gsc: ToUpper() { const auto scriptValue = Game::Scr_GetConstString(0); const auto* string = Game::SL_ConvertToString(scriptValue); @@ -280,7 +280,7 @@ namespace Components }); // Func present on IW5 - Script::AddFunction("StrICmp", []() // gsc: StrICmp(, ) + Script::AddFunction("StrICmp", [] // gsc: StrICmp(, ) { const auto value1 = Game::Scr_GetConstString(0); const auto value2 = Game::Scr_GetConstString(1); @@ -292,7 +292,7 @@ namespace Components }); // Func present on IW5 - Script::AddFunction("IsEndStr", []() // gsc: IsEndStr(, ) + Script::AddFunction("IsEndStr", [] // gsc: IsEndStr(, ) { const auto* s1 = Game::Scr_GetString(0); const auto* s2 = Game::Scr_GetString(1); @@ -305,6 +305,26 @@ namespace Components Game::Scr_AddBool(Utils::String::EndsWith(s1, s2)); }); + + Script::AddFunction("IsArray", [] + { + const auto type = Game::Scr_GetType(0); + + bool result; + if (type == Game::scrParamType_t::VAR_POINTER) + { + const auto ptr_type = Game::Scr_GetPointerType(0); + assert(ptr_type >= Game::FIRST_OBJECT); + result = (ptr_type == Game::scrParamType_t::VAR_ARRAY); + } + else + { + assert(type < Game::FIRST_OBJECT); + result = false; + } + + Game::Scr_AddBool(result); + }); } void ScriptExtension::AddMethods() diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 5fb7505a..4dab19e6 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -293,6 +293,7 @@ namespace Game Scr_ParamError_t Scr_ParamError = Scr_ParamError_t(0x4FBC70); Scr_GetType_t Scr_GetType = Scr_GetType_t(0x422900); + Scr_GetPointerType_t Scr_GetPointerType = Scr_GetPointerType_t(0x4828E0); Scr_ClearOutParams_t Scr_ClearOutParams = Scr_ClearOutParams_t(0x4386E0); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 4369bbad..a03f0c85 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -735,9 +735,12 @@ namespace Game typedef bool(__cdecl * Scr_IsSystemActive_t)(); extern Scr_IsSystemActive_t Scr_IsSystemActive; - typedef int(__cdecl * Scr_GetType_t)(unsigned int); + typedef int(__cdecl * Scr_GetType_t)(unsigned int index); extern Scr_GetType_t Scr_GetType; + typedef int(__cdecl * Scr_GetPointerType_t)(unsigned int index); + extern Scr_GetPointerType_t Scr_GetPointerType; + typedef void(__cdecl * Scr_Error_t)(const char*); extern Scr_Error_t Scr_Error; diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index e0eb5dcc..f30a607d 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -234,7 +234,7 @@ namespace Game CS_ACTIVE = 0x5, } clientstate_t; - typedef enum + enum errorParm_t { ERR_FATAL = 0x0, ERR_DROP = 0x1, @@ -244,7 +244,39 @@ namespace Game ERR_SCRIPT_DROP = 0x5, ERR_LOCALIZATION = 0x6, ERR_MAPLOADERRORSUMMARY = 0x7 - } errorParm_t; + }; + + enum conChannel_t + { + CON_CHANNEL_DONT_FILTER, + CON_CHANNEL_ERROR, + CON_CHANNEL_GAMENOTIFY, + CON_CHANNEL_BOLDGAME, + CON_CHANNEL_SUBTITLE, + CON_CHANNEL_OBITUARY, + CON_CHANNEL_LOGFILEONLY, + CON_CHANNEL_CONSOLEONLY, + CON_CHANNEL_GFX, + CON_CHANNEL_SOUND, + CON_CHANNEL_FILES, + CON_CHANNEL_DEVGUI, + CON_CHANNEL_PROFILE, + CON_CHANNEL_UI, + CON_CHANNEL_CLIENT, + CON_CHANNEL_SERVER, + CON_CHANNEL_SYSTEM, + CON_CHANNEL_PLAYERWEAP, + CON_CHANNEL_AI, + CON_CHANNEL_ANIM, + CON_CHANNEL_PHYS, + CON_CHANNEL_FX, + CON_CHANNEL_LEADERBOARDS, + CON_CHANNEL_PARSERSCRIPT, + CON_CHANNEL_SCRIPT, + CON_CHANNEL_NETWORK, + + CON_BUILTIN_CHANNEL_COUNT, + }; enum entityFlag { @@ -5096,7 +5128,7 @@ namespace Game char buf[1]; }; - enum VariableType + enum scrParamType_t { VAR_UNDEFINED = 0x0, VAR_BEGIN_REF = 0x1, @@ -5114,21 +5146,30 @@ namespace Game VAR_BUILTIN_METHOD = 0xB, VAR_STACK = 0xC, VAR_ANIMATION = 0xD, - VAR_PRE_ANIMATION = 0xE, - VAR_THREAD = 0xF, - VAR_NOTIFY_THREAD = 0x10, - VAR_TIME_THREAD = 0x11, - VAR_CHILD_THREAD = 0x12, - VAR_OBJECT = 0x13, - VAR_DEAD_ENTITY = 0x14, - VAR_ENTITY = 0x15, - VAR_ARRAY = 0x16, - VAR_DEAD_THREAD = 0x17, - VAR_COUNT = 0x18, - VAR_FREE = 0x18, - VAR_THREAD_LIST = 0x19, - VAR_ENDON_LIST = 0x1A, - VAR_TOTAL_COUNT = 0x1B, + VAR_DEVELOPER_CODEPOS = 0xE, + VAR_PRE_ANIMATION = 0xF, + VAR_THREAD = 0x10, + VAR_NOTIFY_THREAD = 0x11, + VAR_TIME_THREAD = 0x12, + VAR_CHILD_THREAD = 0x13, + VAR_OBJECT = 0x14, + VAR_DEAD_ENTITY = 0x15, + VAR_ENTITY = 0x16, + VAR_ARRAY = 0x17, + VAR_DEAD_THREAD = 0x18, + VAR_COUNT = 0x19, + VAR_THREAD_LIST = 0x1A, + VAR_ENDON_LIST = 0x1B, + }; + + enum $2441F0C7E439C64E6C27842ECB570A7C + { + FIRST_OBJECT = 0x10, + FIRST_CLEARABLE_OBJECT = 0x14, + LAST_NONENTITY_OBJECT = 0x14, + FIRST_ENTITY_OBJECT = 0x16, + FIRST_NONFIELD_OBJECT = 0x17, + FIRST_DEAD_OBJECT = 0x18, }; union VariableUnion @@ -5147,7 +5188,7 @@ namespace Game struct VariableValue { VariableUnion u; - VariableType type; + scrParamType_t type; }; struct function_stack_t From bf0ea14fdee8761894599aab059fe9db73b1c43e Mon Sep 17 00:00:00 2001 From: FutureRave Date: Wed, 4 May 2022 12:49:03 +0100 Subject: [PATCH 08/25] [General] Update changelog --- CHANGELOG.md | 2 ++ src/Components/Modules/ScriptExtension.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 725f82b6..4c277f8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,9 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0. ### Changed - Test clients' native functionality has been restored by default (#162) +- Renamed GSC method `isBot` to `IsTestClient` (#162) - Custom GSC functions can be called correctly from a game script (#216) +- GSC functions `HttpCancel` and `HttpCancel` require the game to be launched with the command line argument `scriptablehttp` (#162) - Master server list will be used instead of the node system (load server list faster) (#234) ### Fixed diff --git a/src/Components/Modules/ScriptExtension.cpp b/src/Components/Modules/ScriptExtension.cpp index 66e166de..31b55ae1 100644 --- a/src/Components/Modules/ScriptExtension.cpp +++ b/src/Components/Modules/ScriptExtension.cpp @@ -306,7 +306,7 @@ namespace Components Game::Scr_AddBool(Utils::String::EndsWith(s1, s2)); }); - Script::AddFunction("IsArray", [] + Script::AddFunction("IsArray", [] // gsc: IsArray() { const auto type = Game::Scr_GetType(0); From 378ef7ec6008af7e09caeb5c225a0107e6a973ae Mon Sep 17 00:00:00 2001 From: Jan Date: Wed, 4 May 2022 17:47:50 +0200 Subject: [PATCH 09/25] Update gamepad patch dvar flags --- src/Components/Modules/Gamepad.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Components/Modules/Gamepad.cpp b/src/Components/Modules/Gamepad.cpp index ca170379..a511feea 100644 --- a/src/Components/Modules/Gamepad.cpp +++ b/src/Components/Modules/Gamepad.cpp @@ -1711,8 +1711,8 @@ namespace Components { gpad_enabled = Dvar::Register("gpad_enabled", false, Game::DVAR_ARCHIVE, "Game pad enabled"); gpad_debug = Dvar::Register("gpad_debug", false, Game::DVAR_NONE, "Game pad debugging"); - gpad_present = Dvar::Register("gpad_present", false, Game::DVAR_NONE, "Game pad present"); - gpad_in_use = Dvar::Register("gpad_in_use", false, Game::DVAR_NONE, "A game pad is in use"); + gpad_present = Dvar::Register("gpad_present", false, Game::DVAR_READONLY, "Game pad present"); + gpad_in_use = Dvar::Register("gpad_in_use", false, Game::DVAR_READONLY, "A game pad is in use"); gpad_style = Dvar::Register("gpad_style", false, Game::DVAR_ARCHIVE, "Switch between Xbox and PS HUD"); gpad_sticksConfig = Dvar::Register("gpad_sticksConfig", "", Game::DVAR_ARCHIVE, "Game pad stick configuration"); gpad_buttonConfig = Dvar::Register("gpad_buttonConfig", "", Game::DVAR_ARCHIVE, "Game pad button configuration"); @@ -1720,15 +1720,15 @@ namespace Components gpad_menu_scroll_delay_rest = Dvar::Register("gpad_menu_scroll_delay_rest", 210, 0, 1000, Game::DVAR_ARCHIVE, "Menu scroll key-repeat delay, for repeats after the first, in milliseconds"); gpad_rumble = Dvar::Register("gpad_rumble", true, Game::DVAR_ARCHIVE, "Enable game pad rumble"); - gpad_stick_pressed_hysteresis = Dvar::Register("gpad_stick_pressed_hysteresis", 0.1f, 0.0f, 1.0f, Game::DVAR_NONE, + gpad_stick_pressed_hysteresis = Dvar::Register("gpad_stick_pressed_hysteresis", 0.1f, 0.0f, 1.0f, Game::DVAR_ARCHIVE, "Game pad stick pressed no-change-zone around gpad_stick_pressed to prevent bouncing"); - gpad_stick_pressed = Dvar::Register("gpad_stick_pressed", 0.4f, 0.0, 1.0, Game::DVAR_NONE, "Game pad stick pressed threshhold"); - gpad_stick_deadzone_max = Dvar::Register("gpad_stick_deadzone_max", 0.01f, 0.0f, 1.0f, Game::DVAR_NONE, "Game pad maximum stick deadzone"); - gpad_stick_deadzone_min = Dvar::Register("gpad_stick_deadzone_min", 0.2f, 0.0f, 1.0f, Game::DVAR_NONE, "Game pad minimum stick deadzone"); - gpad_button_deadzone = Dvar::Register("gpad_button_deadzone", 0.13f, 0.0f, 1.0f, Game::DVAR_NONE, "Game pad button deadzone threshhold"); - gpad_button_lstick_deflect_max = Dvar::Register("gpad_button_lstick_deflect_max", 1.0f, 0.0f, 1.0f, Game::DVAR_NONE, "Game pad maximum pad stick pressed value"); - gpad_button_rstick_deflect_max = Dvar::Register("gpad_button_rstick_deflect_max", 1.0f, 0.0f, 1.0f, Game::DVAR_NONE, "Game pad maximum pad stick pressed value"); - gpad_use_hold_time = Dvar::Register("gpad_use_hold_time", 250, 0, std::numeric_limits::max(), Game::DVAR_NONE, "Time to hold the 'use' button on gamepads to activate use"); + gpad_stick_pressed = Dvar::Register("gpad_stick_pressed", 0.4f, 0.0, 1.0, Game::DVAR_ARCHIVE, "Game pad stick pressed threshhold"); + gpad_stick_deadzone_max = Dvar::Register("gpad_stick_deadzone_max", 0.01f, 0.0f, 1.0f, Game::DVAR_ARCHIVE, "Game pad maximum stick deadzone"); + gpad_stick_deadzone_min = Dvar::Register("gpad_stick_deadzone_min", 0.2f, 0.0f, 1.0f, Game::DVAR_ARCHIVE, "Game pad minimum stick deadzone"); + gpad_button_deadzone = Dvar::Register("gpad_button_deadzone", 0.13f, 0.0f, 1.0f, Game::DVAR_ARCHIVE, "Game pad button deadzone threshhold"); + gpad_button_lstick_deflect_max = Dvar::Register("gpad_button_lstick_deflect_max", 1.0f, 0.0f, 1.0f, Game::DVAR_ARCHIVE, "Game pad maximum pad stick pressed value"); + gpad_button_rstick_deflect_max = Dvar::Register("gpad_button_rstick_deflect_max", 1.0f, 0.0f, 1.0f, Game::DVAR_ARCHIVE, "Game pad maximum pad stick pressed value"); + gpad_use_hold_time = Dvar::Register("gpad_use_hold_time", 250, 0, std::numeric_limits::max(), Game::DVAR_ARCHIVE, "Time to hold the 'use' button on gamepads to activate use"); gpad_lockon_enabled = Dvar::Register("gpad_lockon_enabled", true, Game::DVAR_ARCHIVE, "Game pad lockon aim assist enabled"); gpad_slowdown_enabled = Dvar::Register("gpad_slowdown_enabled", true, Game::DVAR_ARCHIVE, "Game pad slowdown aim assist enabled"); From 4af77130df2bf18d12eda1392f4589ca8233339d Mon Sep 17 00:00:00 2001 From: Jan Date: Wed, 4 May 2022 20:15:17 +0200 Subject: [PATCH 10/25] Fix RawMouse patch making gamepad mouse move hook not getting called --- src/Components/Modules/Gamepad.cpp | 7 ++++++- src/Components/Modules/Gamepad.hpp | 2 ++ src/Components/Modules/RawMouse.cpp | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Components/Modules/Gamepad.cpp b/src/Components/Modules/Gamepad.cpp index a511feea..250a5d85 100644 --- a/src/Components/Modules/Gamepad.cpp +++ b/src/Components/Modules/Gamepad.cpp @@ -1833,13 +1833,18 @@ namespace Components return gamePads[0].inUse; } - int Gamepad::CL_MouseEvent_Hk(const int x, const int y, const int dx, const int dy) + void Gamepad::OnMouseMove(const int x, const int y, const int dx, const int dy) { if (dx != 0 || dy != 0) { gamePads[0].inUse = false; gpad_in_use.setRaw(false); } + } + + int Gamepad::CL_MouseEvent_Hk(const int x, const int y, const int dx, const int dy) + { + OnMouseMove(x, y, dx, dy); // Call original function return Utils::Hook::Call(0x4D7C50)(x, y, dx, dy); diff --git a/src/Components/Modules/Gamepad.hpp b/src/Components/Modules/Gamepad.hpp index 024d0c6a..a09a4ec6 100644 --- a/src/Components/Modules/Gamepad.hpp +++ b/src/Components/Modules/Gamepad.hpp @@ -41,6 +41,8 @@ namespace Components public: Gamepad(); + static void OnMouseMove(int x, int y, int dx, int dy); + private: static Game::ButtonToCodeMap_t buttonList[]; static Game::StickToCodeMap_t analogStickList[4]; diff --git a/src/Components/Modules/RawMouse.cpp b/src/Components/Modules/RawMouse.cpp index 3f95a874..51cba280 100644 --- a/src/Components/Modules/RawMouse.cpp +++ b/src/Components/Modules/RawMouse.cpp @@ -97,6 +97,7 @@ namespace Components Game::s_wmv->oldPos = curPos; ScreenToClient(Window::GetWindow(), &curPos); + Gamepad::OnMouseMove(curPos.x, curPos.y, dx, dy); auto recenterMouse = Game::CL_MouseEvent(curPos.x, curPos.y, dx, dy); if (recenterMouse) From 20d17a3dec95cce2c8ac48a5a22122eb721ad56f Mon Sep 17 00:00:00 2001 From: Jan Date: Wed, 4 May 2022 20:29:02 +0200 Subject: [PATCH 11/25] Mark Gamepad OnMouseMove parameters as maybe unused --- src/Components/Modules/Gamepad.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Modules/Gamepad.cpp b/src/Components/Modules/Gamepad.cpp index 250a5d85..364021c8 100644 --- a/src/Components/Modules/Gamepad.cpp +++ b/src/Components/Modules/Gamepad.cpp @@ -1833,7 +1833,7 @@ namespace Components return gamePads[0].inUse; } - void Gamepad::OnMouseMove(const int x, const int y, const int dx, const int dy) + void Gamepad::OnMouseMove([[maybe_unused]] const int x, [[maybe_unused]] const int y, const int dx, const int dy) { if (dx != 0 || dy != 0) { From 9685dccdcddec1d405ce74052a124e9b30830ada Mon Sep 17 00:00:00 2001 From: FutureRave Date: Thu, 5 May 2022 10:20:10 +0100 Subject: [PATCH 12/25] Clarify some things in the elevators patch --- src/Components/Modules/Elevators.cpp | 21 ++++++++++----------- src/Game/Functions.cpp | 4 ++-- src/Game/Functions.hpp | 8 ++++---- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/Components/Modules/Elevators.cpp b/src/Components/Modules/Elevators.cpp index 08dffeb7..6507f1f2 100644 --- a/src/Components/Modules/Elevators.cpp +++ b/src/Components/Modules/Elevators.cpp @@ -16,9 +16,9 @@ namespace Components const auto elevatorSetting = Elevators::BG_Elevators.get(); while (true) { - point[0] = ps->origin[0] + Game::CorrectSolidDeltas[i][0]; - point[1] = ps->origin[1] + Game::CorrectSolidDeltas[i][1]; - point[2] = ps->origin[2] + Game::CorrectSolidDeltas[i][2]; + point[0] = ps->origin[0] + (*Game::CorrectSolidDeltas)[i][0]; + point[1] = ps->origin[1] + (*Game::CorrectSolidDeltas)[i][1]; + point[2] = ps->origin[2] + (*Game::CorrectSolidDeltas)[i][2]; Game::PM_playerTrace(pm, trace, point, point, &pm->bounds, ps->clientNum, pm->tracemask); @@ -40,8 +40,8 @@ namespace Components } } - i += 1; - if (i >= 26) + ++i; + if (i >= 26) // CorrectSolidDeltas count { ps->groundEntityNum = Game::ENTITYNUM_NONE; pml->groundPlane = 0; @@ -62,15 +62,15 @@ namespace Components return 1; } - void Elevators::PM_Trace_Hk(Game::pmove_s* pm, Game::trace_t* trace, const float* f3, - const float* f4, const Game::Bounds* bounds, int a6, int a7) + void Elevators::PM_Trace_Hk(Game::pmove_s* pm, Game::trace_t* results, const float* start, + const float* end, const Game::Bounds* bounds, int passEntityNum, int contentMask) { - Game::PM_Trace(pm, trace, f3, f4, bounds, a6, a7); + Game::PM_Trace(pm, results, start, end, bounds, passEntityNum, contentMask); // Allow the player to stand even when there is no headroom if (Elevators::BG_Elevators.get() == Elevators::EASY) { - trace->allsolid = false; + results->allsolid = false; } } @@ -111,8 +111,7 @@ namespace Components Elevators::ENABLED, Game::DVAR_CODINFO, "Elevators glitch settings"); }); - //Replace PM_CorrectAllSolid - Utils::Hook(0x57369E, Elevators::PM_CorrectAllSolidStub, HOOK_CALL).install()->quick(); + Utils::Hook(0x57369E, Elevators::PM_CorrectAllSolidStub, HOOK_CALL).install()->quick(); // PM_GroundTrace // Place hooks in PM_CheckDuck. If the elevators dvar is set to easy the // flags for duck/prone will always be removed from the player state diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 4dab19e6..3edcc68a 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -547,11 +547,11 @@ namespace Game FastCriticalSection* db_hashCritSect = reinterpret_cast(0x16B8A54); - vec3_t* CorrectSolidDeltas = reinterpret_cast(0x739BB8); // Count 26 + float (*CorrectSolidDeltas)[26][3] = reinterpret_cast(0x739BB8); // Count 26 level_locals_t* level = reinterpret_cast(0x1A831A8); - float(*penetrationDepthTable)[PENETRATE_TYPE_COUNT][SURF_TYPE_COUNT] = reinterpret_cast(0x7C4878); + float (*penetrationDepthTable)[PENETRATE_TYPE_COUNT][SURF_TYPE_COUNT] = reinterpret_cast(0x7C4878); WinMouseVars_t* s_wmv = reinterpret_cast(0x649D640); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index a03f0c85..e6840329 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -999,10 +999,10 @@ namespace Game typedef void(__cdecl * Jump_ClearState_t)(playerState_s* ps); extern Jump_ClearState_t Jump_ClearState; - typedef void(__cdecl * PM_playerTrace_t)(pmove_s*, trace_t*, const float*, const float*, const Bounds*, int, int); + typedef void(__cdecl * PM_playerTrace_t)(pmove_s* pm, trace_t* results, const float* start, const float* end, const Bounds* bounds, int passEntityNum, int contentMask); extern PM_playerTrace_t PM_playerTrace; - typedef void(__cdecl * PM_Trace_t)(pmove_s*, trace_t*, const float*, const float*, const Bounds*, int, int); + typedef void(__cdecl * PM_Trace_t)(pmove_s* pm, trace_t* results, const float* start, const float* end, const Bounds* bounds, int passEntityNum, int contentMask); extern PM_Trace_t PM_Trace; typedef EffectiveStance(__cdecl * PM_GetEffectiveStance_t)(const playerState_s* ps); @@ -1145,13 +1145,13 @@ namespace Game constexpr auto MAX_MODELS = 512; extern XModel** cached_models; - extern vec3_t* CorrectSolidDeltas; + extern float (*CorrectSolidDeltas)[26][3]; extern FastCriticalSection* db_hashCritSect; extern level_locals_t* level; - extern float(*penetrationDepthTable)[PENETRATE_TYPE_COUNT][SURF_TYPE_COUNT]; + extern float (*penetrationDepthTable)[PENETRATE_TYPE_COUNT][SURF_TYPE_COUNT]; extern WinMouseVars_t* s_wmv; From 41c652ed36a91641c2114a6362d653e1cc32c03c Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 5 May 2022 21:24:25 +0200 Subject: [PATCH 13/25] Fix not being able to assign gamepad keys in bind menu fields --- src/Components/Modules/Gamepad.cpp | 36 ++++++++++++++++++++++++++---- src/Components/Modules/Gamepad.hpp | 5 +++-- src/Game/Functions.cpp | 2 ++ src/Game/Functions.hpp | 2 ++ 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/Components/Modules/Gamepad.cpp b/src/Components/Modules/Gamepad.cpp index 364021c8..3cad580b 100644 --- a/src/Components/Modules/Gamepad.cpp +++ b/src/Components/Modules/Gamepad.cpp @@ -1033,6 +1033,13 @@ namespace Components void Gamepad::UI_GamepadKeyEvent(const int gamePadIndex, const int key, const bool down) { + // If we are currently capturing a key for menu bind inputs then do not map keys and pass to game + if (*Game::g_waitingForKey) + { + Game::UI_KeyEvent(gamePadIndex, key, down); + return; + } + for (const auto& mapping : controllerMenuKeyMappings) { if (mapping.controllerKey == key) @@ -1777,19 +1784,19 @@ namespace Components return command; } - int Gamepad::Key_GetCommandAssignmentInternal_Hk(const char* cmd, int (*keys)[2]) + int Gamepad::Key_GetCommandAssignmentInternal([[maybe_unused]] int localClientNum, const char* cmd, int (*keys)[2]) { auto keyCount = 0; if (gamePads[0].inUse) { - cmd = GetGamePadCommand(cmd); + const auto gamePadCmd = GetGamePadCommand(cmd); for (auto keyNum = 0; keyNum < Game::K_LAST_KEY; keyNum++) { if (!Key_IsValidGamePadChar(keyNum)) continue; - if (Game::playerKeys[0].keys[keyNum].binding && strcmp(Game::playerKeys[0].keys[keyNum].binding, cmd) == 0) + if (Game::playerKeys[0].keys[keyNum].binding && strcmp(Game::playerKeys[0].keys[keyNum].binding, gamePadCmd) == 0) { (*keys)[keyCount++] = keyNum; @@ -1818,6 +1825,27 @@ namespace Components return keyCount; } + void __declspec(naked) Gamepad::Key_GetCommandAssignmentInternal_Stub() + { + __asm + { + push eax + pushad + + push [esp + 0x20 + 0x4 + 0x8] // keyNums + push [esp + 0x20 + 0x4 + 0x8] // command + push eax // localClientNum + call Key_GetCommandAssignmentInternal + add esp, 0xC + + mov[esp + 0x20], eax + + popad + pop eax + ret + } + } + void Gamepad::CL_KeyEvent_Hk(const int localClientNum, const int key, const int down, const unsigned time) { // A keyboard key has been pressed. Mark controller as unused. @@ -1954,7 +1982,7 @@ namespace Components Utils::Hook(0x48E527, UI_RefreshViewport_Hk, HOOK_CALL).install()->quick(); // Only return gamepad keys when gamepad enabled and only non gamepad keys when not - Utils::Hook(0x5A7A23, Key_GetCommandAssignmentInternal_Hk, HOOK_CALL).install()->quick(); + Utils::Hook(0x5A7890, Key_GetCommandAssignmentInternal_Stub, HOOK_JUMP).install()->quick(); // Add gamepad inputs to remote control (eg predator) handling Utils::Hook(0x5A6D4E, CL_RemoteControlMove_Stub, HOOK_CALL).install()->quick(); diff --git a/src/Components/Modules/Gamepad.hpp b/src/Components/Modules/Gamepad.hpp index a09a4ec6..36c969e9 100644 --- a/src/Components/Modules/Gamepad.hpp +++ b/src/Components/Modules/Gamepad.hpp @@ -192,8 +192,9 @@ namespace Components static void CG_RegisterDvars_Hk(); static const char* GetGamePadCommand(const char* command); - static int Key_GetCommandAssignmentInternal_Hk(const char* cmd, int(*keys)[2]); - static bool IsGamePadInUse(); + static int Key_GetCommandAssignmentInternal(int localClientNum, const char* cmd, int (*keys)[2]); + static void Key_GetCommandAssignmentInternal_Stub(); + static bool IsGamePadInUse(); 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(); diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 4dab19e6..f617cb4e 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -558,6 +558,8 @@ namespace Game int* window_center_x = reinterpret_cast(0x649D638); int* window_center_y = reinterpret_cast(0x649D630); + int* g_waitingForKey = reinterpret_cast(0x63A50FC); + void Sys_LockRead(FastCriticalSection* critSect) { InterlockedIncrement(&critSect->readCount); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index a03f0c85..48f02c0a 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -1158,6 +1158,8 @@ namespace Game extern int* window_center_x; extern int* window_center_y; + extern int* g_waitingForKey; + void Sys_LockRead(FastCriticalSection* critSect); void Sys_UnlockRead(FastCriticalSection* critSect); From 13911fcb620754b514427fc72776d2dff508837d Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 5 May 2022 21:36:27 +0200 Subject: [PATCH 14/25] Whenever a gamepad button is rebound with a menu bind field, set the button config to custom so gamepad config shows a changed button layout --- src/Components/Modules/Gamepad.cpp | 13 +++++++++++++ src/Components/Modules/Gamepad.hpp | 1 + src/Game/Functions.cpp | 1 + src/Game/Functions.hpp | 3 +++ 4 files changed, 18 insertions(+) diff --git a/src/Components/Modules/Gamepad.cpp b/src/Components/Modules/Gamepad.cpp index 3cad580b..fa97f155 100644 --- a/src/Components/Modules/Gamepad.cpp +++ b/src/Components/Modules/Gamepad.cpp @@ -1846,6 +1846,14 @@ namespace Components } } + void Gamepad::Key_SetBinding_Hk(const int localClientNum, const int keyNum, const char* binding) + { + if(Key_IsValidGamePadChar(keyNum)) + gpad_buttonConfig.set("custom"); + + Game::Key_SetBinding(localClientNum, keyNum, binding); + } + void Gamepad::CL_KeyEvent_Hk(const int localClientNum, const int key, const int down, const unsigned time) { // A keyboard key has been pressed. Mark controller as unused. @@ -1984,6 +1992,11 @@ namespace Components // Only return gamepad keys when gamepad enabled and only non gamepad keys when not Utils::Hook(0x5A7890, Key_GetCommandAssignmentInternal_Stub, HOOK_JUMP).install()->quick(); + // Whenever a key binding for a gamepad key is replaced update the button config + Utils::Hook(0x47D473, Key_SetBinding_Hk, HOOK_CALL).install()->quick(); + Utils::Hook(0x47D485, Key_SetBinding_Hk, HOOK_CALL).install()->quick(); + Utils::Hook(0x47D49D, Key_SetBinding_Hk, HOOK_CALL).install()->quick(); + // Add gamepad inputs to remote control (eg predator) handling Utils::Hook(0x5A6D4E, CL_RemoteControlMove_Stub, HOOK_CALL).install()->quick(); diff --git a/src/Components/Modules/Gamepad.hpp b/src/Components/Modules/Gamepad.hpp index 36c969e9..f468dacd 100644 --- a/src/Components/Modules/Gamepad.hpp +++ b/src/Components/Modules/Gamepad.hpp @@ -194,6 +194,7 @@ namespace Components static const char* GetGamePadCommand(const char* command); static int Key_GetCommandAssignmentInternal(int localClientNum, const char* cmd, int (*keys)[2]); static void Key_GetCommandAssignmentInternal_Stub(); + static void Key_SetBinding_Hk(int localClientNum, int keyNum, const char* binding); static bool IsGamePadInUse(); 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); diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index f617cb4e..343466db 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -171,6 +171,7 @@ namespace Game Key_SetCatcher_t Key_SetCatcher = Key_SetCatcher_t(0x43BD00); Key_RemoveCatcher_t Key_RemoveCatcher = Key_RemoveCatcher_t(0x408260); Key_IsKeyCatcherActive_t Key_IsKeyCatcherActive = Key_IsKeyCatcherActive_t(0x4DA010); + Key_SetBinding_t Key_SetBinding = Key_SetBinding_t(0x494C90); LargeLocalInit_t LargeLocalInit = LargeLocalInit_t(0x4A62A0); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 48f02c0a..da3ab84e 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -420,6 +420,9 @@ namespace Game typedef bool(__cdecl * Key_IsKeyCatcherActive_t)(int localClientNum, int catcher); extern Key_IsKeyCatcherActive_t Key_IsKeyCatcherActive; + typedef void(__cdecl * Key_SetBinding_t)(int localClientNum, int keyNum, const char* binding); + extern Key_SetBinding_t Key_SetBinding; + typedef void(__cdecl * LargeLocalInit_t)(); extern LargeLocalInit_t LargeLocalInit; From f9bfb0b8831df4aaa481fab9bf57b097eef24392 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 5 May 2022 21:42:15 +0200 Subject: [PATCH 15/25] replace spaces with tabs in gamepad patch --- src/Components/Modules/Gamepad.cpp | 4 ++-- src/Components/Modules/Gamepad.hpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Components/Modules/Gamepad.cpp b/src/Components/Modules/Gamepad.cpp index fa97f155..0a4b8b89 100644 --- a/src/Components/Modules/Gamepad.cpp +++ b/src/Components/Modules/Gamepad.cpp @@ -1849,9 +1849,9 @@ namespace Components void Gamepad::Key_SetBinding_Hk(const int localClientNum, const int keyNum, const char* binding) { if(Key_IsValidGamePadChar(keyNum)) - gpad_buttonConfig.set("custom"); + gpad_buttonConfig.set("custom"); - Game::Key_SetBinding(localClientNum, keyNum, binding); + Game::Key_SetBinding(localClientNum, keyNum, binding); } void Gamepad::CL_KeyEvent_Hk(const int localClientNum, const int key, const int down, const unsigned time) diff --git a/src/Components/Modules/Gamepad.hpp b/src/Components/Modules/Gamepad.hpp index f468dacd..2e55c67d 100644 --- a/src/Components/Modules/Gamepad.hpp +++ b/src/Components/Modules/Gamepad.hpp @@ -193,9 +193,9 @@ namespace Components static const char* GetGamePadCommand(const char* command); static int Key_GetCommandAssignmentInternal(int localClientNum, const char* cmd, int (*keys)[2]); - static void Key_GetCommandAssignmentInternal_Stub(); - static void Key_SetBinding_Hk(int localClientNum, int keyNum, const char* binding); - static bool IsGamePadInUse(); + static void Key_GetCommandAssignmentInternal_Stub(); + static void Key_SetBinding_Hk(int localClientNum, int keyNum, const char* binding); + static bool IsGamePadInUse(); 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(); From d75a5a71e58d8520fe5364ed5e71c0aaf7ba4a60 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Thu, 5 May 2022 23:48:33 +0100 Subject: [PATCH 16/25] [Bots] Add isBot GSC meth back --- src/Components/Modules/Bots.cpp | 21 +++++++++++++-------- src/Components/Modules/Bots.hpp | 1 + 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/Components/Modules/Bots.cpp b/src/Components/Modules/Bots.cpp index edccc68b..8c53ec2d 100644 --- a/src/Components/Modules/Bots.cpp +++ b/src/Components/Modules/Bots.cpp @@ -108,8 +108,19 @@ namespace Components } } + void Bots::GScr_isTestClient(Game::scr_entref_t entref) + { + const auto* ent = Game::GetPlayerEntity(entref); + const auto* client = Script::GetClient(ent); + + Game::Scr_AddBool(client->bIsTestClient == 1); + } + void Bots::AddMethods() { + Script::AddMethod("IsBot", Bots::GScr_isTestClient); // Usage: self IsBot(); + Script::AddMethod("IsTestClient", Bots::GScr_isTestClient); // Usage: self IsTestClient(); + Script::AddMethod("SetPing", [](Game::scr_entref_t entref) // gsc: self SetPing() { auto ping = Game::Scr_GetInt(0); @@ -128,14 +139,6 @@ namespace Components client->ping = static_cast(ping); }); - Script::AddMethod("IsTestClient", [](Game::scr_entref_t entref) // Usage: IsTestClient(); - { - const auto* gentity = Game::GetPlayerEntity(entref); - const auto* client = Script::GetClient(gentity); - - Game::Scr_AddBool(client->bIsTestClient == 1); - }); - Script::AddMethod("BotStop", [](Game::scr_entref_t entref) // Usage: BotStop(); { const auto* ent = Game::GetPlayerEntity(entref); @@ -327,6 +330,8 @@ namespace Components Bots::Bots() { + AssertOffset(Game::client_s, bIsTestClient, 0x41AF0); + // Replace connect string Utils::Hook::Set(0x48ADA6, "connect bot%d \"\\cg_predictItems\\1\\cl_anonymous\\0\\color\\4\\head\\default\\model\\multi\\snaps\\20\\rate\\5000\\name\\%s\\protocol\\%d\\checksum\\%d\\statver\\%d %u\\qport\\%d\""); diff --git a/src/Components/Modules/Bots.hpp b/src/Components/Modules/Bots.hpp index 910bacfa..8bf9045c 100644 --- a/src/Components/Modules/Bots.hpp +++ b/src/Components/Modules/Bots.hpp @@ -14,6 +14,7 @@ namespace Components static void Spawn(unsigned int count); + static void GScr_isTestClient(Game::scr_entref_t entref); static void AddMethods(); static void BotAiAction(Game::client_t* cl); From 849b890a96751dd2ed1f6b692dfe99f3a308b65c Mon Sep 17 00:00:00 2001 From: FutureRave Date: Sat, 7 May 2022 00:49:29 +0100 Subject: [PATCH 17/25] Get rid of direct checks of bistestclient --- src/Components/Modules/Bots.cpp | 43 +++++++++++++-------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/src/Components/Modules/Bots.cpp b/src/Components/Modules/Bots.cpp index 8c53ec2d..e89c73a2 100644 --- a/src/Components/Modules/Bots.cpp +++ b/src/Components/Modules/Bots.cpp @@ -111,9 +111,7 @@ namespace Components void Bots::GScr_isTestClient(Game::scr_entref_t entref) { const auto* ent = Game::GetPlayerEntity(entref); - const auto* client = Script::GetClient(ent); - - Game::Scr_AddBool(client->bIsTestClient == 1); + Game::Scr_AddBool(Game::SV_IsTestClient(ent->s.number) != 0); } void Bots::AddMethods() @@ -130,7 +128,7 @@ namespace Components const auto* ent = Game::GetPlayerEntity(entref); auto* client = Script::GetClient(ent); - if (!client->bIsTestClient) + if (Game::SV_IsTestClient(ent->s.number) == 0) { Game::Scr_Error("^1SetPing: Can only call on a bot!\n"); return; @@ -142,9 +140,8 @@ namespace Components Script::AddMethod("BotStop", [](Game::scr_entref_t entref) // Usage: BotStop(); { const auto* ent = Game::GetPlayerEntity(entref); - const auto* client = Script::GetClient(ent); - if (!client->bIsTestClient) + if (Game::SV_IsTestClient(ent->s.number) == 0) { Game::Scr_Error("^1BotStop: Can only call on a bot!\n"); return; @@ -157,17 +154,16 @@ namespace Components Script::AddMethod("BotWeapon", [](Game::scr_entref_t entref) // Usage: BotWeapon(); { - const auto* weapon = Game::Scr_GetString(0); - const auto* ent = Game::GetPlayerEntity(entref); - const auto* client = Script::GetClient(ent); - if (!client->bIsTestClient) + if (Game::SV_IsTestClient(ent->s.number) == 0) { Game::Scr_Error("^1BotWeapon: Can only call on a bot!\n"); return; } + const auto* weapon = Game::Scr_GetString(0); + if (weapon == nullptr || weapon[0] == '\0') { g_botai[entref.entnum].weapon = 1; @@ -181,6 +177,14 @@ namespace Components Script::AddMethod("BotAction", [](Game::scr_entref_t entref) // Usage: BotAction(); { + const auto* ent = Game::GetPlayerEntity(entref); + + if (Game::SV_IsTestClient(ent->s.number) == 0) + { + Game::Scr_Error("^1BotAction: Can only call on a bot!\n"); + return; + } + const auto* action = Game::Scr_GetString(0); if (action == nullptr) @@ -189,15 +193,6 @@ namespace Components return; } - const auto* ent = Game::GetPlayerEntity(entref); - const auto* client = Script::GetClient(ent); - - if (!client->bIsTestClient) - { - Game::Scr_Error("^1BotAction: Can only call on a bot!\n"); - return; - } - if (action[0] != '+' && action[0] != '-') { Game::Scr_ParamError(0, "^1BotAction: Sign for action must be '+' or '-'.\n"); @@ -223,20 +218,16 @@ namespace Components Script::AddMethod("BotMovement", [](Game::scr_entref_t entref) // Usage: BotMovement(, ); { - auto forwardInt = Game::Scr_GetInt(0); - auto rightInt = Game::Scr_GetInt(1); - const auto* ent = Game::GetPlayerEntity(entref); - const auto* client = Script::GetClient(ent); - if (!client->bIsTestClient) + if (Game::SV_IsTestClient(ent->s.number) == 0) { Game::Scr_Error("^1BotMovement: Can only call on a bot!\n"); return; } - forwardInt = std::clamp(forwardInt, std::numeric_limits::min(), std::numeric_limits::max()); - rightInt = std::clamp(rightInt, std::numeric_limits::min(), std::numeric_limits::max()); + const auto forwardInt = std::clamp(Game::Scr_GetInt(0), std::numeric_limits::min(), std::numeric_limits::max()); + const auto rightInt = std::clamp(Game::Scr_GetInt(1), std::numeric_limits::min(), std::numeric_limits::max()); g_botai[entref.entnum].forward = static_cast(forwardInt); g_botai[entref.entnum].right = static_cast(rightInt); From ae8580079f0874ee78c9ec906d90c01b4f3f002a Mon Sep 17 00:00:00 2001 From: FutureRave Date: Sat, 7 May 2022 01:17:15 +0100 Subject: [PATCH 18/25] Fix issue with get system milliseconds --- src/Components/Modules/Script.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index cb4dc4e9..dbe79ccc 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -564,14 +564,6 @@ namespace Components }); // System time - Script::AddFunction("GetSystemTime", [] // gsc: GetSystemTime() - { - SYSTEMTIME time; - GetSystemTime(&time); - - Game::Scr_AddInt(time.wSecond); - }); - Script::AddFunction("GetSystemMilliseconds", [] // gsc: GetSystemMilliseconds() { SYSTEMTIME time; From c0b2ca0813cdb20ca16f94efdc14235f0857a91d Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 7 May 2022 14:26:32 +0200 Subject: [PATCH 19/25] Fix knife charge not working anymore with gamepad patch enabled --- src/Components/Modules/Gamepad.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Components/Modules/Gamepad.cpp b/src/Components/Modules/Gamepad.cpp index 0a4b8b89..5a7a98b8 100644 --- a/src/Components/Modules/Gamepad.cpp +++ b/src/Components/Modules/Gamepad.cpp @@ -661,7 +661,8 @@ namespace Components Game::AimAssist_UpdateAdsLerp(input); AimAssist_ApplyTurnRates(input, output); - Game::AimAssist_ApplyAutoMelee(input, output); + // Automelee has already been done by keyboard so don't do it again + AimAssist_ApplyLockOn(input, output); } @@ -886,8 +887,6 @@ namespace Components AimAssist_UpdateGamePadInput(&aimInput, &aimOutput); clientActive.clViewangles[0] = aimOutput.pitch; clientActive.clViewangles[1] = aimOutput.yaw; - cmd->meleeChargeDist = aimOutput.meleeChargeDist; - cmd->meleeChargeYaw = aimOutput.meleeChargeYaw; } } From 413e26b2aea07511b1cac68a633c38711b7b2938 Mon Sep 17 00:00:00 2001 From: m Date: Sat, 7 May 2022 08:23:26 -0500 Subject: [PATCH 20/25] fix visible server list refreshing --- src/Components/Modules/ServerList.cpp | 19 +++++++++++++++---- src/Components/Modules/ServerList.hpp | 1 + 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/Components/Modules/ServerList.cpp b/src/Components/Modules/ServerList.cpp index d6af313a..5bffcf9e 100644 --- a/src/Components/Modules/ServerList.cpp +++ b/src/Components/Modules/ServerList.cpp @@ -199,6 +199,11 @@ namespace Components } void ServerList::RefreshVisibleList(UIScript::Token) + { + ServerList::RefreshVisibleListInternal(UIScript::Token()); + } + + void ServerList::RefreshVisibleListInternal(UIScript::Token, bool refresh) { Dvar::Var("ui_serverSelected").set(false); @@ -207,6 +212,12 @@ namespace Components auto list = ServerList::GetList(); if (!list) return; + if (refresh) + { + ServerList::Refresh(UIScript::Token()); + return; + } + bool ui_browserShowFull = Dvar::Var("ui_browserShowFull").get(); bool ui_browserShowEmpty = Dvar::Var("ui_browserShowEmpty").get(); int ui_browserShowHardcore = Dvar::Var("ui_browserKillcam").get(); @@ -368,7 +379,7 @@ namespace Components auto list = ServerList::GetList(); if (list) list->clear(); - ServerList::RefreshVisibleList(UIScript::Token()); + ServerList::RefreshVisibleListInternal(UIScript::Token()); Game::ShowMessageBox("Server removed from favourites.", "Success"); } @@ -530,7 +541,7 @@ namespace Components if (lList) { lList->push_back(server); - ServerList::RefreshVisibleList(UIScript::Token()); + ServerList::RefreshVisibleListInternal(UIScript::Token()); } } @@ -693,7 +704,7 @@ namespace Components netSource.set(source); - ServerList::RefreshVisibleList(UIScript::Token()); + ServerList::RefreshVisibleListInternal(UIScript::Token(), true); } void ServerList::UpdateGameType() @@ -709,7 +720,7 @@ namespace Components joinGametype.set(gametype); - ServerList::RefreshVisibleList(UIScript::Token()); + ServerList::RefreshVisibleListInternal(UIScript::Token()); } void ServerList::UpdateVisibleInfo() diff --git a/src/Components/Modules/ServerList.hpp b/src/Components/Modules/ServerList.hpp index 22754f7b..51f7a062 100644 --- a/src/Components/Modules/ServerList.hpp +++ b/src/Components/Modules/ServerList.hpp @@ -35,6 +35,7 @@ namespace Components static void Refresh(UIScript::Token); static void RefreshVisibleList(UIScript::Token); + static void RefreshVisibleListInternal(UIScript::Token, bool refresh = false); static void UpdateVisibleList(UIScript::Token); static void InsertRequest(Network::Address address); static void Insert(Network::Address address, Utils::InfoString info); From eb11652f2cb1f3dbcba84c14b2312005bcf0ce5c Mon Sep 17 00:00:00 2001 From: FutureRave Date: Sat, 7 May 2022 14:59:15 +0100 Subject: [PATCH 21/25] [Branding] Address review --- src/Components/Modules/Branding.cpp | 35 +++++++++++----------------- src/Components/Modules/Exception.cpp | 18 -------------- 2 files changed, 13 insertions(+), 40 deletions(-) diff --git a/src/Components/Modules/Branding.cpp b/src/Components/Modules/Branding.cpp index a5a4c954..6d560719 100644 --- a/src/Components/Modules/Branding.cpp +++ b/src/Components/Modules/Branding.cpp @@ -22,10 +22,10 @@ namespace Components const auto width = Game::UI_TextWidth((*Version)->current.string, 0, font, fontScale); const auto height = Game::UI_TextHeight(font, fontScale); - Game::UI_DrawText(placement, (*Version)->current.string, maxChars, font, 1.0f - (CGDrawVersionX.get() + width), - 1.0f - (CGDrawVersionY.get() + height), 3, 3, fontScale, shadowColor, 0); - Game::UI_DrawText(placement, (*Version)->current.string, maxChars, font, (0.0f - width) - CGDrawVersionX.get(), - (0.0f - height) - CGDrawVersionY.get(), 3, 3, fontScale, color, 0); + Game::UI_DrawText(placement, (*Version)->current.string, maxChars, font, 1.0f - (CGDrawVersionX.get() + static_cast(width)), + 1.0f - (CGDrawVersionY.get() + static_cast(height)), 3, 3, fontScale, shadowColor, 0); + Game::UI_DrawText(placement, (*Version)->current.string, maxChars, font, (0.0f - static_cast(width)) - CGDrawVersionX.get(), + (0.0f - static_cast(height)) - CGDrawVersionY.get(), 3, 3, fontScale, color, 0); } void Branding::CG_DrawVersion_Hk(int localClientNum) @@ -40,12 +40,7 @@ namespace Components const char* Branding::GetBuildNumber() { - static char buf[128]; // Length the game uses - - const auto* data = "latest " __DATE__ " " __TIME__; - sprintf_s(buf, "%s %s", SHORTVERSION, data); - - return buf; + return SHORTVERSION " latest " __DATE__ " " __TIME__; } const char* Branding::GetVersionString() @@ -63,28 +58,24 @@ namespace Components return result; } - void Branding::Dvar_SetVersionString(const Game::dvar_t* dvar, const char* /*value*/) + void Branding::Dvar_SetVersionString(const Game::dvar_t* dvar, [[maybe_unused]] const char* value) { const auto* result = Branding::GetVersionString(); Utils::Hook::Call(0x4A9580)(dvar, result); } // Branding this might be a good idea in case this LSP logging ever gets turned on for some reason - void Branding::MSG_WriteVersionStringHeader(Game::msg_t* msg, const char* /*string*/) + void Branding::MSG_WriteVersionStringHeader(Game::msg_t* msg, [[maybe_unused]] const char* string) { const auto* result = Branding::GetVersionString(); Utils::Hook::Call(0x463820)(msg, result); } - Game::dvar_t* Branding::Dvar_RegisterUIBuildLocation(const char* dvarName, - float /*x*/, float /*y*/, float min, float max, int /*flags*/, const char* description) + Game::dvar_t* Branding::Dvar_RegisterUIBuildLocation(const char* dvarName, [[maybe_unused]] float x, + [[maybe_unused]] float y, float min, float max, [[maybe_unused]] int flags, const char* description) { -#ifdef _DEBUG - constexpr auto flag = Game::dvar_flag::DVAR_NONE; -#else - constexpr auto flag = Game::dvar_flag::DVAR_READONLY; -#endif - return Game::Dvar_RegisterVec2(dvarName, -60.0f, 474.0f, min, max, flag, description); + return Game::Dvar_RegisterVec2(dvarName, -60.0f, + 474.0f, min, max, Game::dvar_flag::DVAR_READONLY, description); } void Branding::RegisterBrandingDvars() @@ -96,9 +87,9 @@ namespace Components #endif Branding::CGDrawVersion = Dvar::Register("cg_drawVersion", value, Game::dvar_flag::DVAR_NONE, "Draw the game version"); - Branding::CGDrawVersionX = Dvar::Register("cg_drawVersionX", 50.0f, + Branding::CGDrawVersionX = Dvar::Register("cg_drawVersionX", 10.0f, 0.0f, 512.0f, Game::dvar_flag::DVAR_NONE, "X offset for the version string"); - Branding::CGDrawVersionY = Dvar::Register("cg_drawVersionY", 18.0f, + Branding::CGDrawVersionY = Dvar::Register("cg_drawVersionY", 455.0f, 0.0f, 512.0f, Game::dvar_flag::DVAR_NONE, "Y offset for the version string"); } diff --git a/src/Components/Modules/Exception.cpp b/src/Components/Modules/Exception.cpp index 572bfdfd..a58dfefa 100644 --- a/src/Components/Modules/Exception.cpp +++ b/src/Components/Modules/Exception.cpp @@ -193,24 +193,6 @@ namespace Components { Exception::SetMiniDumpType(Flags::HasFlag("bigminidumps"), Flags::HasFlag("reallybigminidumps")); -#ifdef DEBUG - // Display DEBUG branding, so we know we're on a debug build - Scheduler::OnFrame([]() - { - auto* font = Game::R_RegisterFont("fonts/normalFont", 0); - Game::vec4_t color = { 1.0f, 1.0f, 1.0f, 1.0f }; - - // Change the color when attaching a debugger - if (IsDebuggerPresent()) - { - color[0] = 0.6588f; - color[1] = 1.0000f; - color[2] = 0.0000f; - } - - Game::R_AddCmdDrawText("DEBUG-BUILD", 0x7FFFFFFF, font, 15.0f, 10.0f + Game::R_TextHeight(font), 1.0f, 1.0f, 0.0f, color, Game::ITEM_TEXTSTYLE_SHADOWED); - }, true); -#endif #if !defined(DEBUG) || defined(FORCE_EXCEPTION_HANDLER) Exception::SetFilterHook.initialize(SetUnhandledExceptionFilter, Exception::SetUnhandledExceptionFilterStub, HOOK_JUMP); Exception::SetFilterHook.install(); From 4ba8b8b442f5d833b9cbd3429a3a68591b83ca5f Mon Sep 17 00:00:00 2001 From: Edo Date: Sat, 7 May 2022 11:02:28 -0400 Subject: [PATCH 22/25] Address review --- src/Components/Modules/Branding.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Modules/Branding.cpp b/src/Components/Modules/Branding.cpp index 6d560719..3a513af6 100644 --- a/src/Components/Modules/Branding.cpp +++ b/src/Components/Modules/Branding.cpp @@ -17,7 +17,7 @@ namespace Components constexpr Game::vec4_t color = {0.4f, 0.69f, 1.0f, 0.69f}; auto* const placement = Game::ScrPlace_GetUnsafeFullPlacement(); - auto* const font = Game::UI_GetFontHandle(placement, 0, 0.5f); + auto* const font = Game::UI_GetFontHandle(placement, 0, 0.583f); const auto width = Game::UI_TextWidth((*Version)->current.string, 0, font, fontScale); const auto height = Game::UI_TextHeight(font, fontScale); From dbc30dee6ed5e667523be1069700825812b6a716 Mon Sep 17 00:00:00 2001 From: m Date: Mon, 9 May 2022 20:02:53 -0500 Subject: [PATCH 23/25] only return node frames on non-dedi instances --- src/Components/Modules/Node.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Modules/Node.cpp b/src/Components/Modules/Node.cpp index 9ed8e9c9..8955fe0c 100644 --- a/src/Components/Modules/Node.cpp +++ b/src/Components/Modules/Node.cpp @@ -167,7 +167,7 @@ namespace Components void Node::RunFrame() { - if (ServerList::useMasterServer) return; + if (!Dedicated::IsEnabled() && ServerList::useMasterServer) return; if (Dedicated::IsEnabled() && Dedicated::SVLanOnly.get()) return; if (!Dedicated::IsEnabled() && *Game::clcState > 0) From 88a6bd5887f337e635db9bfa703ea93f0378df19 Mon Sep 17 00:00:00 2001 From: m Date: Tue, 10 May 2022 06:22:36 -0500 Subject: [PATCH 24/25] cleanup if statements? --- src/Components/Modules/Node.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Components/Modules/Node.cpp b/src/Components/Modules/Node.cpp index 8955fe0c..6f112469 100644 --- a/src/Components/Modules/Node.cpp +++ b/src/Components/Modules/Node.cpp @@ -167,13 +167,17 @@ namespace Components void Node::RunFrame() { - if (!Dedicated::IsEnabled() && ServerList::useMasterServer) return; if (Dedicated::IsEnabled() && Dedicated::SVLanOnly.get()) return; - if (!Dedicated::IsEnabled() && *Game::clcState > 0) + if (!Dedicated::IsEnabled()) { - wasIngame = true; - return; // don't run while ingame because it can still cause lag spikes on lower end PCs + if (ServerList::useMasterServer) return; // don't run node frame if master server is active + + if (*Game::clcState > 0) + { + wasIngame = true; + return; // don't run while ingame because it can still cause lag spikes on lower end PCs + } } if (wasIngame) // our last frame we were ingame and now we aren't so touch all nodes From c9864eff2e22546379d448cc915019517e81ace3 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Tue, 10 May 2022 20:25:34 +0100 Subject: [PATCH 25/25] Update changelog --- CHANGELOG.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c277f8b..4906ef22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,29 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.3.0/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [0.7.2] - 2022-05-10 + +### Added + +- Add IsArray GSC function (#248) +- Keybind fields in menus work with controller keys (#255) + +### Changed + +- GSC function `GetSystemTime` now returns the Unix time (#258) + +### Fixed + +- Knife charge is fixed for controller players (#259) +- Fixed internet, local and favorites filters (#260) +- `sv_lanOnly` Dvar now prevents the server from sending heatbeats to master if set to true (#246) + +### Known issue + +- HTTPS is not supported for fast downloads at the moment. +- Sound issue fix is experimental as the bug is not fully understood. +- `reloadmenus` command does not free resources used by custom menus. + ## [0.7.1] - 2022-05-03 ### Added