diff --git a/sdk b/sdk index 7a3acd1d..aeaf0cab 160000 --- a/sdk +++ b/sdk @@ -1 +1 @@ -Subproject commit 7a3acd1ddd98f68093c7af45ed508bb90acfcf18 +Subproject commit aeaf0cab87f754f48e251a76a904f4e824bccb7a diff --git a/src/adminsystem.cpp b/src/adminsystem.cpp index 645aa208..771fb3a3 100644 --- a/src/adminsystem.cpp +++ b/src/adminsystem.cpp @@ -426,34 +426,30 @@ CON_COMMAND_CHAT_FLAGS(setteam, " - Set a player's team", ADM PrintMultiAdminAction(nType, pszCommandPlayerName, "moved", szAction); } -CON_COMMAND_CHAT_FLAGS(noclip, "- Toggle noclip on yourself", ADMFLAG_SLAY | ADMFLAG_CHEATS) +CON_COMMAND_CHAT_FLAGS(noclip, "[name] - Toggle noclip on a player", ADMFLAG_CHEATS) { - if (!player) - { - ClientPrint(player, HUD_PRINTCONSOLE, CHAT_PREFIX "You cannot use this command from the server console."); + int iNumClients = 0; + int pSlots[MAXPLAYERS]; + + if (!g_playerManager->CanTargetPlayers(player, args.ArgC() < 2 ? "@me" : args[1], iNumClients, pSlots, NO_MULTIPLE | NO_DEAD | NO_SPECTATOR)) return; - } - CBasePlayerPawn *pPawn = player->m_hPawn(); + CCSPlayerController* pTarget = CCSPlayerController::FromSlot(pSlots[0]); + CBasePlayerPawn *pPawn = pTarget->m_hPawn(); + const char* pszCommandPlayerName = player ? player->GetPlayerName() : CONSOLE_NAME; if (!pPawn) return; - if (pPawn->m_iHealth() <= 0) - { - ClientPrint(player, HUD_PRINTTALK, CHAT_PREFIX "You cannot noclip while dead!"); - return; - } - if (pPawn->m_nActualMoveType() == MOVETYPE_NOCLIP) { pPawn->SetMoveType(MOVETYPE_WALK); - ClientPrintAll(HUD_PRINTTALK, CHAT_PREFIX ADMIN_PREFIX "exited noclip.", player->GetPlayerName()); + PrintSingleAdminAction(pszCommandPlayerName, pTarget->GetPlayerName(), "disabled noclip on"); } else { pPawn->SetMoveType(MOVETYPE_NOCLIP); - ClientPrintAll(HUD_PRINTTALK, CHAT_PREFIX ADMIN_PREFIX "entered noclip.", player->GetPlayerName()); + PrintSingleAdminAction(pszCommandPlayerName, pTarget->GetPlayerName(), "enabled noclip on"); } } @@ -976,6 +972,138 @@ CON_COMMAND_CHAT_FLAGS(listdc, "- List recently disconnected players and their S g_pAdminSystem->ShowDisconnectedPlayers(player); } +CON_COMMAND_CHAT_FLAGS(endround, "- Immediately ends the round, client-side variant of endround", ADMFLAG_RCON) +{ + g_pGameRules->TerminateRound(0.0f, CSRoundEndReason::Draw); +} + +CON_COMMAND_CHAT_FLAGS(money, " - Set a player's amount of money", ADMFLAG_CHEATS) +{ + if (args.ArgC() < 3) + { + ClientPrint(player, HUD_PRINTTALK, CHAT_PREFIX "Usage: !money "); + return; + } + + int iMoney = V_StringToInt32(args[2], -1); + + if (iMoney < 0) + { + ClientPrint(player, HUD_PRINTTALK, CHAT_PREFIX "Invalid amount specified, must be a positive number."); + return; + } + + int iNumClients = 0; + int pSlots[MAXPLAYERS]; + ETargetType nType; + + if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_TARGET_BLOCKS, nType)) + return; + + const char* pszCommandPlayerName = player ? player->GetPlayerName() : CONSOLE_NAME; + + char szAction[64]; + V_snprintf(szAction, sizeof(szAction), "set $%i money on", iMoney); + + for (int i = 0; i < iNumClients; i++) + { + CCSPlayerController* pTarget = CCSPlayerController::FromSlot(pSlots[i]); + + if (!pTarget) + continue; + + pTarget->m_pInGameMoneyServices->m_iAccount = iMoney; + + if (iNumClients == 1) + PrintSingleAdminAction(pszCommandPlayerName, pTarget->GetPlayerName(), szAction, ""); + } + + if (iNumClients > 1) + PrintMultiAdminAction(nType, pszCommandPlayerName, szAction, ""); +} + +CON_COMMAND_CHAT_FLAGS(health, " - Set a player's health", ADMFLAG_CHEATS) +{ + if (args.ArgC() < 3) + { + ClientPrint(player, HUD_PRINTTALK, CHAT_PREFIX "Usage: !health "); + return; + } + + int iHealth = V_StringToInt32(args[2], -1); + + if (iHealth < 1) + { + ClientPrint(player, HUD_PRINTTALK, CHAT_PREFIX "Invalid amount specified, must be a positive number."); + return; + } + + int iNumClients = 0; + int pSlots[MAXPLAYERS]; + ETargetType nType; + + if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_DEAD | NO_SPECTATOR, nType)) + return; + + const char* pszCommandPlayerName = player ? player->GetPlayerName() : CONSOLE_NAME; + + char szAction[64]; + V_snprintf(szAction, sizeof(szAction), "set %i health on", iHealth); + + for (int i = 0; i < iNumClients; i++) + { + CCSPlayerController* pTarget = CCSPlayerController::FromSlot(pSlots[i]); + + if (!pTarget) + continue; + + CCSPlayerPawn* pPawn = pTarget->GetPlayerPawn(); + + if (!pPawn) + continue; + + if (pPawn->m_iMaxHealth < iHealth) + pPawn->m_iMaxHealth = iHealth; + + pPawn->m_iHealth = iHealth; + + if (iNumClients == 1) + PrintSingleAdminAction(pszCommandPlayerName, pTarget->GetPlayerName(), szAction, ""); + } + + if (iNumClients > 1) + PrintMultiAdminAction(nType, pszCommandPlayerName, szAction, ""); +} + +CON_COMMAND_CHAT_FLAGS(setpos, " - Set your origin", ADMFLAG_CHEATS) +{ + if (!player) + { + ClientPrint(player, HUD_PRINTTALK, CHAT_PREFIX "You cannot use this command from the server console."); + return; + } + + CBasePlayerPawn* pPawn = player->GetPawn(); + + if (!pPawn) + return; + + if (pPawn->m_iTeamNum() < CS_TEAM_T || !pPawn->IsAlive()) + { + ClientPrint(player, HUD_PRINTTALK, CHAT_PREFIX "You must be alive to use this command."); + return; + } + + Vector origin; + V_StringToVector(args.ArgS(), origin); + + char szOrigin[64]; + V_snprintf(szOrigin, sizeof(szOrigin), "%f %f %f", origin.x, origin.y, origin.z); + + pPawn->Teleport(&origin, nullptr, nullptr); + PrintSingleAdminAction(player->GetPlayerName(), szOrigin, "teleported to"); +} + #ifdef _DEBUG CON_COMMAND_CHAT_FLAGS(add_dc, " - Adds a fake player to disconnected player list for testing", ADMFLAG_GENERIC) { diff --git a/src/commands.cpp b/src/commands.cpp index a74834b9..6abcb3aa 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -593,6 +593,8 @@ CON_COMMAND_CHAT(help, "- Display list of commands in console") CON_COMMAND_CHAT(spec, "[name] - Spectate another player or join spectators") { + CCSPlayerPawn* pPawn = (CCSPlayerPawn*)player->GetPawn(); + if (!player) { ClientPrint(player, HUD_PRINTCONSOLE, CHAT_PREFIX "You cannot use this command from the server console."); @@ -607,6 +609,9 @@ CON_COMMAND_CHAT(spec, "[name] - Spectate another player or join spectators") } else { + if (pPawn && pPawn->IsAlive()) + pPawn->CommitSuicide(false, true); + player->SwitchTeam(CS_TEAM_SPECTATOR); ClientPrint(player, HUD_PRINTTALK, CHAT_PREFIX "Moved to spectators."); } @@ -617,7 +622,7 @@ CON_COMMAND_CHAT(spec, "[name] - Spectate another player or join spectators") int iNumClients = 0; int pSlot[MAXPLAYERS]; - if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlot, NO_MULTIPLE | NO_SELF | NO_DEAD | NO_SPECTATOR)) + if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlot, NO_MULTIPLE | NO_SELF | NO_DEAD | NO_SPECTATOR | NO_IMMUNITY)) return; CCSPlayerController* pTarget = CCSPlayerController::FromSlot(pSlot[0]); @@ -626,7 +631,12 @@ CON_COMMAND_CHAT(spec, "[name] - Spectate another player or join spectators") return; if (player->m_iTeamNum() != CS_TEAM_SPECTATOR) + { + if (pPawn && pPawn->IsAlive()) + pPawn->CommitSuicide(false, true); + player->SwitchTeam(CS_TEAM_SPECTATOR); + } // 1 frame delay as observer services will be null on same frame as spectator team switch CHandle hPlayer = player->GetHandle(); @@ -794,55 +804,11 @@ CON_COMMAND_CHAT(fl, "- Flashlight") pLight->AcceptInput("SetParentAttachmentMaintainOffset", &val2); } -CON_COMMAND_CHAT(message, " - Message someone") -{ - if (!player) - return; - - // Note that the engine will treat this as a player slot number, not an entity index - int uid = atoi(args[1]); - - CCSPlayerController* pTarget = CCSPlayerController::FromSlot(uid); - - if (!pTarget) - return; - - // skipping the id and space, it's dumb but w/e - const char *pMessage = args.ArgS() + V_strlen(args[1]) + 1; - - ClientPrint(pTarget, HUD_PRINTTALK, CHAT_PREFIX "Private message from %s to %s: \5%s", player->GetPlayerName(), pTarget->GetPlayerName(), pMessage); -} - CON_COMMAND_CHAT(say, " - Say something using console") { ClientPrintAll(HUD_PRINTTALK, "%s", args.ArgS()); } -CON_COMMAND_CHAT(takemoney, " - Take your money") -{ - if (!player) - return; - - int amount = atoi(args[1]); - int money = player->m_pInGameMoneyServices->m_iAccount; - - player->m_pInGameMoneyServices->m_iAccount = money - amount; -} - -CON_COMMAND_CHAT(sethealth, " - Set your health") -{ - if (!player) - return; - - int health = atoi(args[1]); - - CBaseEntity *pEnt = (CBaseEntity *)player->GetPawn(); - - pEnt->m_iHealth = health; - - ClientPrint(player, HUD_PRINTTALK, CHAT_PREFIX "Your health is now %d", health); -} - CON_COMMAND_CHAT(test_target, " [blocked flag] [...] - Test string targetting") { if (!player) @@ -897,20 +863,6 @@ CON_COMMAND_CHAT(test_target, " [blocked flag] [...] - Test string targett } } -CON_COMMAND_CHAT(setorigin, " - Set your origin") -{ - if (!player) - return; - - CBasePlayerPawn *pPawn = player->GetPawn(); - Vector vecNewOrigin; - V_StringToVector(args.ArgS(), vecNewOrigin); - - pPawn->Teleport(&vecNewOrigin, nullptr, nullptr); - - ClientPrint(player, HUD_PRINTTALK, CHAT_PREFIX "Your origin is now %f %f %f", vecNewOrigin.x, vecNewOrigin.y, vecNewOrigin.z); -} - CON_COMMAND_CHAT(particle, "- Spawn a particle") { if (!player) diff --git a/src/cvars.cpp b/src/cvars.cpp index cd1aa43d..f6de75f3 100644 --- a/src/cvars.cpp +++ b/src/cvars.cpp @@ -25,6 +25,7 @@ static uint64 g_iFlagsToRemove = (FCVAR_HIDDEN | FCVAR_DEVELOPMENTONLY | FCVAR_MISSING0 | FCVAR_MISSING1 | FCVAR_MISSING2 | FCVAR_MISSING3); static constexpr const char *pUnCheatCvars[] = { "bot_stop", "bot_freeze", "bot_zombie" }; +static constexpr const char* pUnCheatCmds[] = { "report_entities", "endround" }; void UnlockConVars() { @@ -81,11 +82,20 @@ void UnlockConCommands() hConCommandHandle.Set(hConCommandHandle.Get() + 1); - if (!pConCommand || pConCommand == pInvalidCommand || !(pConCommand->GetFlags() & g_iFlagsToRemove)) + if (!pConCommand || pConCommand == pInvalidCommand) continue; - pConCommand->RemoveFlags(g_iFlagsToRemove); - iUnhiddenConCommands++; + for (int i = 0; i < sizeof(pUnCheatCmds) / sizeof(*pUnCheatCmds); i++) + { + if (!V_strcmp(pConCommand->GetName(), pUnCheatCmds[i])) + pConCommand->RemoveFlags(FCVAR_CHEAT); + } + + if (pConCommand->GetFlags() & g_iFlagsToRemove) + { + pConCommand->RemoveFlags(g_iFlagsToRemove); + iUnhiddenConCommands++; + } } while (pConCommand && pConCommand != pInvalidCommand); Message("Removed hidden flags from %d commands\n", iUnhiddenConCommands); diff --git a/src/playermanager.cpp b/src/playermanager.cpp index 864a9076..9a8c64f7 100644 --- a/src/playermanager.cpp +++ b/src/playermanager.cpp @@ -34,6 +34,7 @@ #include "leader.h" #include "tier0/vprof.h" #include "networksystem/inetworkmessages.h" +#include "engine/igameeventsystem.h" #include "tier0/memdbgon.h" @@ -41,6 +42,7 @@ extern IVEngineServer2 *g_pEngineServer2; extern CGameEntitySystem *g_pEntitySystem; extern CGlobalVars *gpGlobals; +extern IGameEventSystem* g_gameEventSystem; static int g_iAdminImmunityTargetting = 0; static bool g_bEnableMapSteamIds = false; @@ -557,7 +559,9 @@ void ZEPlayer::ReplicateConVar(const char* pszName, const char* pszValue) cvarMsg->set_name(pszName); cvarMsg->set_value(pszValue); - GetClientBySlot(GetPlayerSlot())->GetNetChannel()->SendNetMessage(data, BUF_RELIABLE); + CSingleRecipientFilter filter(GetPlayerSlot()); + g_gameEventSystem->PostEventAbstract(-1, false, &filter, pNetMsg, data, 0); + delete data; } diff --git a/src/zombiereborn.cpp b/src/zombiereborn.cpp index ad79e6cc..d22300c9 100644 --- a/src/zombiereborn.cpp +++ b/src/zombiereborn.cpp @@ -1113,7 +1113,8 @@ void ZR_InfectShake(CCSPlayerController *pController) data->set_amplitude(g_flInfectShakeAmplitude); data->set_command(0); - pController->GetServerSideClient()->GetNetChannel()->SendNetMessage(data, BUF_RELIABLE); + CSingleRecipientFilter filter(pController->GetPlayerSlot()); + g_gameEventSystem->PostEventAbstract(-1, false, &filter, pNetMsg, data, 0); delete data; }