source-engine/game/server/tf2base/tf_eventlog.cpp
2022-08-10 19:52:28 +03:00

619 lines
18 KiB
C++

//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "cbase.h"
#include "../EventLog.h"
#include "team.h"
#include "teamplayroundbased_gamerules.h"
#include "tf_gamerules.h"
#include "team_control_point_master.h"
#include "team_control_point_round.h"
#include "tf_team.h"
#include "KeyValues.h"
extern ConVar tf_flag_caps_per_round;
class CTFEventLog : public CEventLog
{
private:
typedef CEventLog BaseClass;
public:
bool PrintEvent( IGameEvent *event ) // override virtual function
{
if ( !PrintTFEvent( event ) ) // allow TF to override logging
{
return BaseClass::PrintEvent( event );
}
else
{
return true;
}
}
bool Init()
{
BaseClass::Init();
ListenForGameEvent( "player_death" );
ListenForGameEvent( "player_hurt" );
ListenForGameEvent( "player_changeclass" );
ListenForGameEvent( "tf_game_over" );
ListenForGameEvent( "player_chargedeployed" );
ListenForGameEvent( "player_builtobject" );
ListenForGameEvent( "teamplay_flag_event" );
ListenForGameEvent( "object_destroyed" );
ListenForGameEvent( "teamplay_capture_blocked" );
ListenForGameEvent( "teamplay_point_captured" );
ListenForGameEvent( "teamplay_round_stalemate" );
ListenForGameEvent( "teamplay_round_win" );
ListenForGameEvent( "teamplay_game_over" );
return true;
}
protected:
bool PrintTFEvent( IGameEvent *event ) // print Mod specific logs
{
const char *eventName = event->GetName();
if ( !Q_strncmp( eventName, "server_", strlen("server_")) )
{
return false; // ignore server_ messages
}
if ( !Q_strncmp( eventName, "player_death", Q_strlen( "player_death" ) ) )
{
const int userid = event->GetInt( "userid" );
CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid );
if ( !pPlayer )
{
return false;
}
const int attackerid = event->GetInt( "attacker" );
const char *weapon = event->GetString( "weapon" );
int iCustomDamage = event->GetInt( "customkill" );
CBasePlayer *pAttacker = UTIL_PlayerByUserId( attackerid );
if ( pPlayer == pAttacker )
{
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"%s\" (attacker_position \"%d %d %d\")\n",
pPlayer->GetPlayerName(),
userid,
pPlayer->GetNetworkIDString(),
pPlayer->GetTeam()->GetName(),
weapon,
(int)pPlayer->GetAbsOrigin().x,
(int)pPlayer->GetAbsOrigin().y,
(int)pPlayer->GetAbsOrigin().z );
}
else if ( pAttacker )
{
const char *pszCustom = NULL;
switch( iCustomDamage )
{
case TF_DMG_CUSTOM_HEADSHOT:
pszCustom = "headshot";
break;
case TF_DMG_CUSTOM_BACKSTAB:
pszCustom = "backstab";
break;
default:
break;
}
if ( pszCustom )
{
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" killed \"%s<%i><%s><%s>\" with \"%s\" (customkill \"%s\") (attacker_position \"%d %d %d\") (victim_position \"%d %d %d\")\n",
pAttacker->GetPlayerName(),
attackerid,
pAttacker->GetNetworkIDString(),
pAttacker->GetTeam()->GetName(),
pPlayer->GetPlayerName(),
userid,
pPlayer->GetNetworkIDString(),
pPlayer->GetTeam()->GetName(),
weapon,
pszCustom,
(int)pAttacker->GetAbsOrigin().x,
(int)pAttacker->GetAbsOrigin().y,
(int)pAttacker->GetAbsOrigin().z,
(int)pPlayer->GetAbsOrigin().x,
(int)pPlayer->GetAbsOrigin().y,
(int)pPlayer->GetAbsOrigin().z );
}
else
{
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" killed \"%s<%i><%s><%s>\" with \"%s\" (attacker_position \"%d %d %d\") (victim_position \"%d %d %d\")\n",
pAttacker->GetPlayerName(),
attackerid,
pAttacker->GetNetworkIDString(),
pAttacker->GetTeam()->GetName(),
pPlayer->GetPlayerName(),
userid,
pPlayer->GetNetworkIDString(),
pPlayer->GetTeam()->GetName(),
weapon,
(int)pAttacker->GetAbsOrigin().x,
(int)pAttacker->GetAbsOrigin().y,
(int)pAttacker->GetAbsOrigin().z,
(int)pPlayer->GetAbsOrigin().x,
(int)pPlayer->GetAbsOrigin().y,
(int)pPlayer->GetAbsOrigin().z );
}
}
else
{
// killed by the world
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"world\" (attacker_position \"%d %d %d\")\n",
pPlayer->GetPlayerName(),
userid,
pPlayer->GetNetworkIDString(),
pPlayer->GetTeam()->GetName(),
(int)pPlayer->GetAbsOrigin().x,
(int)pPlayer->GetAbsOrigin().y,
(int)pPlayer->GetAbsOrigin().z );
}
// Assist kill
int assistid = event->GetInt( "assister" );
CBasePlayer *pAssister = UTIL_PlayerByUserId( assistid );
if ( pAssister )
{
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"kill assist\" against \"%s<%i><%s><%s>\" (assister_position \"%d %d %d\") (attacker_position \"%d %d %d\") (victim_position \"%d %d %d\")\n",
pAssister->GetPlayerName(),
assistid,
pAssister->GetNetworkIDString(),
pAssister->GetTeam()->GetName(),
pPlayer->GetPlayerName(),
userid,
pPlayer->GetNetworkIDString(),
pPlayer->GetTeam()->GetName(),
(int)pAssister->GetAbsOrigin().x,
(int)pAssister->GetAbsOrigin().y,
(int)pAssister->GetAbsOrigin().z,
(int)pAttacker->GetAbsOrigin().x,
(int)pAttacker->GetAbsOrigin().y,
(int)pAttacker->GetAbsOrigin().z,
(int)pPlayer->GetAbsOrigin().x,
(int)pPlayer->GetAbsOrigin().y,
(int)pPlayer->GetAbsOrigin().z );
}
// Domination and Revenge
// pAttacker //int attackerid = engine->GetPlayerForUserID( event->GetInt( "attacker" ) );
// pPlayer //int userid = engine->GetPlayerForUserID( event->GetInt( "userid" ) );
// pAssister // assistid
if ( event->GetInt( "dominated" ) > 0 && pAttacker )
{
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"domination\" against \"%s<%i><%s><%s>\"\n",
pAttacker->GetPlayerName(),
attackerid,
pAttacker->GetNetworkIDString(),
pAttacker->GetTeam()->GetName(),
pPlayer->GetPlayerName(),
userid,
pPlayer->GetNetworkIDString(),
pPlayer->GetTeam()->GetName()
);
}
if ( event->GetInt( "assister_dominated" ) > 0 && pAssister )
{
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"domination\" against \"%s<%i><%s><%s>\" (assist \"1\")\n",
pAssister->GetPlayerName(),
assistid,
pAssister->GetNetworkIDString(),
pAssister->GetTeam()->GetName(),
pPlayer->GetPlayerName(),
userid,
pPlayer->GetNetworkIDString(),
pPlayer->GetTeam()->GetName()
);
}
if ( event->GetInt( "revenge" ) > 0 && pAttacker )
{
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"revenge\" against \"%s<%i><%s><%s>\"\n",
pAttacker->GetPlayerName(),
attackerid,
pAttacker->GetNetworkIDString(),
pAttacker->GetTeam()->GetName(),
pPlayer->GetPlayerName(),
userid,
pPlayer->GetNetworkIDString(),
pPlayer->GetTeam()->GetName()
);
}
if ( event->GetInt( "assister_revenge" ) > 0 && pAssister )
{
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"revenge\" against \"%s<%i><%s><%s>\" (assist \"1\")\n",
pAssister->GetPlayerName(),
assistid,
pAssister->GetNetworkIDString(),
pAssister->GetTeam()->GetName(),
pPlayer->GetPlayerName(),
userid,
pPlayer->GetNetworkIDString(),
pPlayer->GetTeam()->GetName()
);
}
return true;
}
else if ( FStrEq( eventName, "player_changeclass" ) )
{
const int userid = event->GetInt( "userid" );
CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid );
if ( !pPlayer )
{
return false;
}
int iClass = event->GetInt("class");
if ( pPlayer->GetTeamNumber() < FIRST_GAME_TEAM )
return true;
if ( iClass >= TF_FIRST_NORMAL_CLASS && iClass <= TF_LAST_NORMAL_CLASS )
{
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" changed role to \"%s\"\n",
pPlayer->GetPlayerName(),
userid,
pPlayer->GetNetworkIDString(),
pPlayer->GetTeam()->GetName(),
GetPlayerClassData( iClass )->m_szClassName
);
}
return true;
}
else if ( FStrEq( eventName, "tf_game_over" ) || FStrEq( eventName, "teamplay_game_over" ) )
{
UTIL_LogPrintf( "World triggered \"Game_Over\" reason \"%s\"\n", event->GetString( "reason" ) );
UTIL_LogPrintf( "Team \"Red\" final score \"%d\" with \"%d\" players\n", GetGlobalTeam( TF_TEAM_RED )->GetScore(), GetGlobalTeam( TF_TEAM_RED )->GetNumPlayers() );
UTIL_LogPrintf( "Team \"Blue\" final score \"%d\" with \"%d\" players\n", GetGlobalTeam( TF_TEAM_BLUE )->GetScore(), GetGlobalTeam( TF_TEAM_BLUE )->GetNumPlayers() );
return true;
}
else if ( FStrEq( eventName, "player_chargedeployed" ) )
{
const int userid = event->GetInt( "userid" );
CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid );
if ( !pPlayer )
{
return false;
}
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"chargedeployed\"\n",
pPlayer->GetPlayerName(),
userid,
pPlayer->GetNetworkIDString(),
pPlayer->GetTeam()->GetName()
);
return true;
}
else if ( FStrEq( eventName, "player_builtobject" ) )
{
const int userid = event->GetInt( "userid" );
CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid );
if ( !pPlayer )
{
return false;
}
// object name
const int objectid = event->GetInt( "object" );
const CObjectInfo *pInfo = GetObjectInfo( objectid );
if ( pInfo )
{
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"builtobject\" (object \"%s\") (position \"%d %d %d\")\n",
pPlayer->GetPlayerName(),
userid,
pPlayer->GetNetworkIDString(),
pPlayer->GetTeam()->GetName(),
pInfo->m_pObjectName,
(int)pPlayer->GetAbsOrigin().x,
(int)pPlayer->GetAbsOrigin().y,
(int)pPlayer->GetAbsOrigin().z );
}
return true;
}
else if ( FStrEq( eventName, "teamplay_flag_event" ) )
{
int playerindex = event->GetInt( "player" );
CBasePlayer *pPlayer = UTIL_PlayerByIndex( playerindex );
if ( !pPlayer )
{
return false;
}
char *pszEvent = "unknown"; // picked up, dropped, defended, captured
int iEventType = event->GetInt( "eventtype" );
bool bPlainLogEntry = true;
switch ( iEventType )
{
case TF_FLAGEVENT_PICKUP:
pszEvent = "picked up";
break;
case TF_FLAGEVENT_CAPTURE:
pszEvent = "captured";
if ( tf_flag_caps_per_round.GetInt() > 0 )
{
bPlainLogEntry = false;
}
break;
case TF_FLAGEVENT_DEFEND:
pszEvent = "defended";
break;
case TF_FLAGEVENT_DROPPED:
pszEvent = "dropped";
break;
}
if ( bPlainLogEntry )
{
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"flagevent\" (event \"%s\") (position \"%d %d %d\")\n",
pPlayer->GetPlayerName(),
pPlayer->GetUserID(),
pPlayer->GetNetworkIDString(),
pPlayer->GetTeam()->GetName(),
pszEvent,
(int)pPlayer->GetAbsOrigin().x,
(int)pPlayer->GetAbsOrigin().y,
(int)pPlayer->GetAbsOrigin().z );
}
else
{
CTFTeam *pTeam = GetGlobalTFTeam( pPlayer->GetTeamNumber() );
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"flagevent\" (event \"%s\") (team_caps \"%d\") (caps_per_round \"%d\") (position \"%d %d %d\")\n",
pPlayer->GetPlayerName(),
pPlayer->GetUserID(),
pPlayer->GetNetworkIDString(),
pPlayer->GetTeam()->GetName(),
pszEvent,
pTeam->GetFlagCaptures(),
tf_flag_caps_per_round.GetInt(),
(int)pPlayer->GetAbsOrigin().x,
(int)pPlayer->GetAbsOrigin().y,
(int)pPlayer->GetAbsOrigin().z );
}
return true;
}
else if ( FStrEq( eventName, "object_destroyed" ) )
{
int objectid = event->GetInt( "objecttype" );
const CObjectInfo *pInfo = NULL;
if ( objectid >= 0 && objectid < OBJ_LAST )
{
pInfo = GetObjectInfo( objectid );
}
if ( !pInfo )
return false;
const int userid = event->GetInt( "userid" );
CBasePlayer *pObjectOwner = UTIL_PlayerByUserId( userid );
if ( !pObjectOwner )
{
return false;
}
const int attackerid = event->GetInt( "attacker" );
CBasePlayer *pAttacker = UTIL_PlayerByUserId( attackerid );
if ( !pAttacker )
{
return false;
}
const char *weapon = event->GetString( "weapon" );
// log that the person killed an object
// attacker
//with "weapon"
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"killedobject\" (object \"%s\") (weapon \"%s\") (objectowner \"%s<%i><%s><%s>\") (attacker_position \"%d %d %d\")\n",
pAttacker->GetPlayerName(),
attackerid,
pAttacker->GetNetworkIDString(),
pAttacker->GetTeam()->GetName(),
pInfo->m_pObjectName,
weapon,
pObjectOwner->GetPlayerName(),
userid,
pObjectOwner->GetNetworkIDString(),
pObjectOwner->GetTeam()->GetName(),
(int)pAttacker->GetAbsOrigin().x,
(int)pAttacker->GetAbsOrigin().y,
(int)pAttacker->GetAbsOrigin().z );
const int assisterid = event->GetInt( "assister" );
CBasePlayer *pAssister = UTIL_PlayerByUserId( assisterid );
if ( pAssister )
{
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"killedobject\" (object \"%s\") (objectowner \"%s<%i><%s><%s>\") (assist \"1\") (assister_position \"%d %d %d\") (attacker_position \"%d %d %d\")\n",
pAssister->GetPlayerName(),
assisterid,
pAssister->GetNetworkIDString(),
pAssister->GetTeam()->GetName(),
pInfo->m_pObjectName,
pObjectOwner->GetPlayerName(),
userid,
pObjectOwner->GetNetworkIDString(),
pObjectOwner->GetTeam()->GetName(),
(int)pAssister->GetAbsOrigin().x,
(int)pAssister->GetAbsOrigin().y,
(int)pAssister->GetAbsOrigin().z,
(int)pAttacker->GetAbsOrigin().x,
(int)pAttacker->GetAbsOrigin().y,
(int)pAttacker->GetAbsOrigin().z );
}
}
else if ( FStrEq( eventName, "teamplay_capture_blocked" ) )
{
int blockerindex = event->GetInt( "blocker" );
CBasePlayer *pBlocker = UTIL_PlayerByIndex( blockerindex );
if ( !pBlocker )
{
return true;
}
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"captureblocked\" (cp \"%d\") (cpname \"%s\") (position \"%d %d %d\")\n",
pBlocker->GetPlayerName(),
pBlocker->GetUserID(),
pBlocker->GetNetworkIDString(),
pBlocker->GetTeam()->GetName(),
event->GetInt( "cp" ),
event->GetString( "cpname" ),
(int)pBlocker->GetAbsOrigin().x,
(int)pBlocker->GetAbsOrigin().y,
(int)pBlocker->GetAbsOrigin().z );
}
else if ( FStrEq( eventName, "teamplay_point_captured" ) )
{
CTeam *pTeam = GetGlobalTeam( event->GetInt( "team" ) );
if ( !pTeam )
return true;
const char *szCappers = event->GetString( "cappers" );
int iNumCappers = Q_strlen( szCappers );
if ( iNumCappers <= 0 )
return true;
char buf[1024];
Q_snprintf( buf, sizeof(buf), "Team \"%s\" triggered \"pointcaptured\" (cp \"%d\") (cpname \"%s\") (numcappers \"%d\") ",
pTeam->GetName(),
event->GetInt( "cp" ),
event->GetString( "cpname" ),
iNumCappers );
for ( int i=0;i<iNumCappers;i++ )
{
int iPlayerIndex = szCappers[i];
Assert( iPlayerIndex != '\0' && iPlayerIndex > 0 && iPlayerIndex <= MAX_PLAYERS );
CBasePlayer *pPlayer = UTIL_PlayerByIndex( iPlayerIndex );
if ( !pPlayer )
continue;
char playerBuf[256];
Q_snprintf( playerBuf, sizeof(playerBuf), "(player%d \"%s<%i><%s><%s>\") (position%d \"%d %d %d\") ",
i + 1,
pPlayer->GetPlayerName(),
pPlayer->GetUserID(),
pPlayer->GetNetworkIDString(),
pPlayer->GetTeam()->GetName(),
i + 1,
(int)pPlayer->GetAbsOrigin().x,
(int)pPlayer->GetAbsOrigin().y,
(int)pPlayer->GetAbsOrigin().z );
Q_strncat( buf, playerBuf, sizeof(buf), COPY_ALL_CHARACTERS );
}
UTIL_LogPrintf( "%s\n", buf );
}
else if ( FStrEq( eventName, "teamplay_round_stalemate" ) )
{
int iReason = event->GetInt( "reason" );
if ( iReason == STALEMATE_TIMER )
{
UTIL_LogPrintf( "World triggered \"Round_SuddenDeath\" reason \"round timelimit reached\"\n" );
}
else if ( iReason == STALEMATE_SERVER_TIMELIMIT )
{
UTIL_LogPrintf( "World triggered \"Round_SuddenDeath\" reason \"server timelimit reached\"\n" );
}
else
{
UTIL_LogPrintf( "World triggered \"Round_SuddenDeath\"\n" );
}
return true;
}
else if ( FStrEq( eventName, "teamplay_round_win" ) )
{
bool bShowScores = true;
int iTeam = event->GetInt( "team" );
bool bFullRound = event->GetBool( "full_round" );
if ( iTeam == TEAM_UNASSIGNED )
{
UTIL_LogPrintf( "World triggered \"Round_Stalemate\"\n" );
}
else
{
const char *pszWinner = "Red";
if ( iTeam == TF_TEAM_BLUE )
{
pszWinner = "Blue";
}
CTeamControlPointMaster *pMaster = g_hControlPointMasters.Count() ? g_hControlPointMasters[0] : NULL;
if ( pMaster && pMaster->PlayingMiniRounds() )
{
UTIL_LogPrintf( "World triggered \"Mini_Round_Win\" (winner \"%s\") (round \"%s\")\n", pszWinner, pMaster->GetCurrentRound()->GetEntityName().ToCStr() );
UTIL_LogPrintf( "World triggered \"Mini_Round_Length\" (seconds \"%0.2f\")\n", event->GetFloat( "round_time" ) );
bShowScores = false;
}
if ( bFullRound )
{
UTIL_LogPrintf( "World triggered \"Round_Win\" (winner \"%s\")\n", pszWinner );
if ( !pMaster || !pMaster->PlayingMiniRounds() )
{
UTIL_LogPrintf( "World triggered \"Round_Length\" (seconds \"%0.2f\")\n", event->GetFloat( "round_time" ) );
}
bShowScores = true;
}
}
if ( bShowScores )
{
UTIL_LogPrintf( "Team \"Red\" current score \"%d\" with \"%d\" players\n", GetGlobalTeam( TF_TEAM_RED )->GetScore(), GetGlobalTeam( TF_TEAM_RED )->GetNumPlayers() );
UTIL_LogPrintf( "Team \"Blue\" current score \"%d\" with \"%d\" players\n", GetGlobalTeam( TF_TEAM_BLUE )->GetScore(), GetGlobalTeam( TF_TEAM_BLUE )->GetNumPlayers() );
}
}
return false;
}
};
CTFEventLog g_TFEventLog;
//-----------------------------------------------------------------------------
// Singleton access
//-----------------------------------------------------------------------------
IGameSystem* GameLogSystem()
{
return &g_TFEventLog;
}