From a8b95f8d3a50228e9b635631bdee447d1cc82f64 Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 31 Oct 2024 08:04:59 +0800 Subject: [PATCH] feat: SetModel input & Steam ID filtering (#317) * feat: map perks api * add fake convar * Fix being affected by noblock cvar & rename cvar --------- Co-authored-by: Alex --- cfg/cs2fixes/cs2fixes.cfg | 1 + src/cs2_sdk/entity/cbaseentity.h | 8 ++++++++ src/detours.cpp | 14 +++++++++++++- src/events.cpp | 14 ++++++++------ src/playermanager.cpp | 25 +++++++++++++++++++++++++ src/playermanager.h | 1 + 6 files changed, 56 insertions(+), 7 deletions(-) diff --git a/cfg/cs2fixes/cs2fixes.cfg b/cfg/cs2fixes/cs2fixes.cfg index f8cb059f..4a212053 100644 --- a/cfg/cs2fixes/cs2fixes.cfg +++ b/cfg/cs2fixes/cs2fixes.cfg @@ -22,6 +22,7 @@ cs2f_disable_subtick_shooting 0 // Whether to disable subtick shooting, experim cs2f_full_alltalk 0 // Whether to enforce sv_full_alltalk 1 cs2f_drop_map_weapons 0 // Whether to force drop map-spawned weapons on death cs2f_prevent_using_players 0 // Whether to prevent +use from hitting players (0=can use players, 1=cannot use players) +cs2f_map_steamids_enable 0 // Whether to make Steam ID's available to maps cs2f_beacon_particle "particles/cs2fixes/player_beacon.vpcf" // .vpcf file to be precached and used for player beacon diff --git a/src/cs2_sdk/entity/cbaseentity.h b/src/cs2_sdk/entity/cbaseentity.h index e51b5f92..0bb40b39 100644 --- a/src/cs2_sdk/entity/cbaseentity.h +++ b/src/cs2_sdk/entity/cbaseentity.h @@ -305,6 +305,14 @@ class CBaseEntity : public CEntityInstance return nullptr; } + [[nodiscard]] CBaseModelEntity* AsBaseModelEntity() + { + if (const auto pCollision = this->m_pCollision()) + return reinterpret_cast(this); + + return nullptr; + } + /* End Custom Entities Cast */ }; diff --git a/src/detours.cpp b/src/detours.cpp index 03a3f56a..1b847642 100644 --- a/src/detours.cpp +++ b/src/detours.cpp @@ -393,7 +393,8 @@ bool FASTCALL Detour_CEntityIdentity_AcceptInput(CEntityIdentity* pThis, CUtlSym Message("Invalid value type for input %s\n", pInputName->String()); return false; } - else if (!V_strnicmp(pInputName->String(), "IgniteL", 7)) // Override IgniteLifetime + + if (!V_strnicmp(pInputName->String(), "IgniteL", 7)) // Override IgniteLifetime { float flDuration = 0.f; @@ -435,6 +436,17 @@ bool FASTCALL Detour_CEntityIdentity_AcceptInput(CEntityIdentity* pThis, CUtlSym return true; } } + else if (!V_strcasecmp(pInputName->String(), "SetModel")) + { + if (const auto pModelEntity = reinterpret_cast(pThis->m_pInstance)->AsBaseModelEntity()) + { + if ((value->m_type == FIELD_CSTRING || value->m_type == FIELD_STRING) && value->m_pszString) + { + pModelEntity->SetModel(value->m_pszString); + } + return true; + } + } else if (const auto pGameUI = reinterpret_cast(pThis->m_pInstance)->AsGameUI()) { if (!V_strcasecmp(pInputName->String(), "Activate")) diff --git a/src/events.cpp b/src/events.cpp index b0a04588..b75510aa 100644 --- a/src/events.cpp +++ b/src/events.cpp @@ -147,10 +147,6 @@ GAME_EVENT_F(player_spawn) if (pController->IsConnected()) pController->GetZEPlayer()->OnSpawn(); - // Rest of the code is to set debris collisions - if (!g_bNoblock) - return; - CHandle hController = pController->GetHandle(); // Gotta do this on the next frame... @@ -158,13 +154,19 @@ GAME_EVENT_F(player_spawn) { CCSPlayerController *pController = hController.Get(); - if (!pController || !pController->m_bPawnIsAlive()) + if (!pController) + return -1.0f; + + if (const auto player = pController->GetZEPlayer()) + player->SetSteamIdAttribute(); + + if (!pController->m_bPawnIsAlive()) return -1.0f; CBasePlayerPawn *pPawn = pController->GetPawn(); // Just in case somehow there's health but the player is, say, an observer - if (!pPawn || !pPawn->IsAlive()) + if (!g_bNoblock || !pPawn || !pPawn->IsAlive()) return -1.0f; pPawn->SetCollisionGroup(COLLISION_GROUP_DEBRIS); diff --git a/src/playermanager.cpp b/src/playermanager.cpp index 5e43414c..79c21944 100644 --- a/src/playermanager.cpp +++ b/src/playermanager.cpp @@ -43,8 +43,10 @@ extern CGameEntitySystem *g_pEntitySystem; extern CGlobalVars *gpGlobals; static int g_iAdminImmunityTargetting = 0; +static bool g_bEnableMapSteamIds = false; FAKE_INT_CVAR(cs2f_admin_immunity, "Mode for which admin immunity system targetting allows: 0 - strictly lower, 1 - equal to or lower, 2 - ignore immunity levels", g_iAdminImmunityTargetting, 0, false) +FAKE_BOOL_CVAR(cs2f_map_steamids_enable, "Whether to make Steam ID's available to maps", g_bEnableMapSteamIds, false, 0) ZEPlayerHandle::ZEPlayerHandle() : m_Index(INVALID_ZEPLAYERHANDLE_INDEX) {}; @@ -110,6 +112,8 @@ void ZEPlayer::OnAuthenticated() CheckAdmin(); CheckInfractions(); g_pUserPreferencesSystem->PullPreferences(GetPlayerSlot().Get()); + + SetSteamIdAttribute(); } void ZEPlayer::CheckInfractions() @@ -497,6 +501,27 @@ void ZEPlayer::EndGlow() addresses::UTIL_Remove(pModelParent); } +void ZEPlayer::SetSteamIdAttribute() +{ + if (!g_bEnableMapSteamIds) + return; + + if (!IsAuthenticated()) + return; + + const auto pController = CCSPlayerController::FromSlot(GetPlayerSlot()); + if (!pController || !pController->IsConnected() || pController->IsBot() || pController->m_bIsHLTV()) + return; + + const auto pPawn = pController->GetPlayerPawn(); + if (!pPawn) + return; + + const auto& steamId = std::to_string(GetSteamId64()); + pPawn->AcceptInput("AddAttribute", steamId.c_str()); + pController->AcceptInput("AddAttribute", steamId.c_str()); +} + void ZEPlayer::ReplicateConVar(const char* pszName, const char* pszValue) { INetworkMessageInternal* pNetMsg = g_pNetworkMessages->FindNetworkMessagePartial("SetConVar"); diff --git a/src/playermanager.h b/src/playermanager.h index 21d43c71..f4446eff 100644 --- a/src/playermanager.h +++ b/src/playermanager.h @@ -283,6 +283,7 @@ class ZEPlayer void PurgeLeaderVotes(); void StartGlow(Color color, int duration); void EndGlow(); + void SetSteamIdAttribute(); private: bool m_bAuthenticated;