mirror of
https://github.com/ValveSoftware/source-sdk-2013.git
synced 2025-04-11 04:22:55 +00:00
Refactor: Prevent deleting vital entites
► Based on feedback, it is a bad idea to check against classnames. Instead, we will check the class the entity is based on directly, i.e. we should not be able to delete entities falling under CBasePlayer, the world index --which should be 0, and spawn point classes.
This commit is contained in:
parent
7702383398
commit
560c66709b
5 changed files with 134 additions and 29 deletions
|
@ -63,6 +63,7 @@
|
|||
#include "tier1/utlstring.h"
|
||||
#include "utlhashtable.h"
|
||||
#include "vscript_server.h"
|
||||
#include "subs.h"
|
||||
|
||||
#if defined( TF_DLL )
|
||||
#include "tf_gamerules.h"
|
||||
|
@ -5708,14 +5709,59 @@ void CC_Ent_Remove( const CCommand& args )
|
|||
CBasePlayer *pPlayer = UTIL_GetCommandClient();
|
||||
if ( pPlayer )
|
||||
{
|
||||
if ( !Q_stricmp( args[ 1 ], "player" ) ||
|
||||
!Q_stricmp( args[ 1 ], "worldspawn" ) ||
|
||||
!Q_stricmp( args[ 1 ], "info_player_deathmatch" ) ||
|
||||
!Q_stricmp( args[ 1 ], "info_player_rebel" )
|
||||
|| !Q_stricmp( args[ 1 ], "info_player_combine" ) )
|
||||
CBaseEntity *targetEntity = NULL;
|
||||
if ( FStrEq( args[ 1 ], "" ) )
|
||||
{
|
||||
ClientPrint( pPlayer, HUD_PRINTCONSOLE, "This entity cannot be removed\n" );
|
||||
return;
|
||||
targetEntity = FindPickerEntity( pPlayer );
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = atoi( args[ 1 ] );
|
||||
if ( index )
|
||||
{
|
||||
targetEntity = CBaseEntity::Instance( index );
|
||||
}
|
||||
else
|
||||
{
|
||||
targetEntity = gEntList.FindEntityByName( NULL, args[ 1 ] );
|
||||
|
||||
if ( !targetEntity )
|
||||
{
|
||||
targetEntity = gEntList.FindEntityByClassname( NULL, args[ 1 ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Don't check against a classname. They can be changed maliciously
|
||||
// e.g. ent_fire player addoutput "classname abc";ent_remove abc
|
||||
if ( targetEntity )
|
||||
{
|
||||
// Check if it's a player
|
||||
if ( dynamic_cast< CBasePlayer * >( targetEntity ) )
|
||||
{
|
||||
ClientPrint( pPlayer, HUD_PRINTCONSOLE, "You cannot remove players\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if it's the world entity
|
||||
if ( targetEntity->edict() == INDEXENT( 0 ) )
|
||||
{
|
||||
ClientPrint( pPlayer, HUD_PRINTCONSOLE, "You cannot remove the world entity\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if it's a DM spawn point
|
||||
if ( dynamic_cast< CBaseDMStart * >( targetEntity ) )
|
||||
{
|
||||
ClientPrint( pPlayer, HUD_PRINTCONSOLE, "You cannot remove spawn points\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( dynamic_cast< CBaseTeamSpawn * >( targetEntity ) )
|
||||
{
|
||||
ClientPrint( pPlayer, HUD_PRINTCONSOLE, "You cannot remove spawn points\n" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5770,14 +5816,59 @@ void CC_Ent_RemoveAll( const CCommand& args )
|
|||
CBasePlayer *pPlayer = UTIL_GetCommandClient();
|
||||
if ( pPlayer )
|
||||
{
|
||||
if ( !Q_stricmp( args[ 1 ], "player" ) ||
|
||||
!Q_stricmp( args[ 1 ], "worldspawn" ) ||
|
||||
!Q_stricmp( args[ 1 ], "info_player_deathmatch" ) ||
|
||||
!Q_stricmp( args[ 1 ], "info_player_rebel" )
|
||||
|| !Q_stricmp( args[ 1 ], "info_player_combine" ) )
|
||||
CBaseEntity *targetEntity = NULL;
|
||||
if ( FStrEq( args[ 1 ], "" ) )
|
||||
{
|
||||
ClientPrint( pPlayer, HUD_PRINTCONSOLE, "This entity cannot be removed\n" );
|
||||
return;
|
||||
targetEntity = FindPickerEntity( pPlayer );
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = atoi( args[ 1 ] );
|
||||
if ( index )
|
||||
{
|
||||
targetEntity = CBaseEntity::Instance( index );
|
||||
}
|
||||
else
|
||||
{
|
||||
targetEntity = gEntList.FindEntityByName( NULL, args[ 1 ] );
|
||||
|
||||
if ( !targetEntity )
|
||||
{
|
||||
targetEntity = gEntList.FindEntityByClassname( NULL, args[ 1 ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we found an entity, check if it's a protected one
|
||||
if ( targetEntity )
|
||||
{
|
||||
// Check if it's a player
|
||||
if ( dynamic_cast< CBasePlayer * >( targetEntity ) )
|
||||
{
|
||||
ClientPrint( pPlayer, HUD_PRINTCONSOLE, "You cannot remove players\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if it's the world entity
|
||||
if ( targetEntity->edict() == INDEXENT( 0 ) )
|
||||
{
|
||||
ClientPrint( pPlayer, HUD_PRINTCONSOLE, "You cannot remove the world entity\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if it's a DM spawn point
|
||||
if ( dynamic_cast< CBaseDMStart * >( targetEntity ) )
|
||||
{
|
||||
ClientPrint( pPlayer, HUD_PRINTCONSOLE, "You cannot remove spawn points\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if it's a TDM spawn point
|
||||
if ( dynamic_cast< CBaseTeamSpawn * >( targetEntity ) )
|
||||
{
|
||||
ClientPrint( pPlayer, HUD_PRINTCONSOLE, "You cannot remove spawn points\n" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "gamestats.h"
|
||||
#include "ammodef.h"
|
||||
#include "NextBot.h"
|
||||
#include "subs.h"
|
||||
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
||||
|
@ -43,8 +44,8 @@ void DropPrimedFragGrenade( CHL2MP_Player *pPlayer, CBaseCombatWeapon *pGrenade
|
|||
|
||||
LINK_ENTITY_TO_CLASS( player, CHL2MP_Player );
|
||||
|
||||
LINK_ENTITY_TO_CLASS( info_player_combine, CPointEntity );
|
||||
LINK_ENTITY_TO_CLASS( info_player_rebel, CPointEntity );
|
||||
LINK_ENTITY_TO_CLASS( info_player_combine, CBaseTeamSpawn );
|
||||
LINK_ENTITY_TO_CLASS( info_player_rebel, CBaseTeamSpawn );
|
||||
|
||||
// specific to the local player
|
||||
BEGIN_SEND_TABLE_NOBASE( CHL2MP_Player, DT_HL2MPLocalPlayerExclusive )
|
||||
|
|
|
@ -621,6 +621,7 @@ $Project
|
|||
$File "$SRCDIR\public\stringregistry.h"
|
||||
$File "$SRCDIR\game\shared\studio_shared.cpp"
|
||||
$File "subs.cpp"
|
||||
$File "subs.h"
|
||||
$File "sun.cpp"
|
||||
$File "tactical_mission.cpp"
|
||||
$File "tactical_mission.h"
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "doors.h"
|
||||
#include "entitylist.h"
|
||||
#include "globals.h"
|
||||
#include "subs.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
@ -38,19 +39,6 @@ void CNullEntity::Spawn( void )
|
|||
}
|
||||
LINK_ENTITY_TO_CLASS(info_null,CNullEntity);
|
||||
|
||||
class CBaseDMStart : public CPointEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CBaseDMStart, CPointEntity );
|
||||
|
||||
bool IsTriggered( CBaseEntity *pEntity );
|
||||
|
||||
DECLARE_DATADESC();
|
||||
|
||||
string_t m_Master;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
BEGIN_DATADESC( CBaseDMStart )
|
||||
|
||||
|
|
24
src/game/server/subs.h
Normal file
24
src/game/server/subs.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include "cbase.h"
|
||||
|
||||
class CBaseDMStart : public CPointEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CBaseDMStart, CPointEntity );
|
||||
|
||||
bool IsTriggered( CBaseEntity *pEntity );
|
||||
|
||||
DECLARE_DATADESC();
|
||||
|
||||
string_t m_Master;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
// Peter: I don't see a reason why this could not use CBaseDMStart,
|
||||
// but as a precaution because team spawn points were set to use CPointEntity,
|
||||
// I will create a class for this.
|
||||
class CBaseTeamSpawn : public CPointEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CBaseTeamSpawn, CPointEntity );
|
||||
};
|
Loading…
Reference in a new issue