You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
547 lines
15 KiB
547 lines
15 KiB
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//
|
|
//=============================================================================//
|
|
#include "cbase.h"
|
|
#include "../EventLog.h"
|
|
#include "team.h"
|
|
#include "KeyValues.h"
|
|
#include "dod_shareddefs.h"
|
|
#include "dod_team.h"
|
|
|
|
#define LOG_DETAIL_ENEMY_ATTACKS 1
|
|
#define LOG_DETAIL_TEAMMATE_ATTACKS 2
|
|
|
|
ConVar mp_logdetail( "mp_logdetail", "0", FCVAR_NONE, "Logs attacks. Values are: 0=off, 1=enemy, 2=teammate, 3=both)", true, 0.0f, true, 3.0f );
|
|
|
|
class CDODEventLog : public CEventLog
|
|
{
|
|
private:
|
|
typedef CEventLog BaseClass;
|
|
|
|
public:
|
|
bool PrintEvent( IGameEvent * event ) // override virtual function
|
|
{
|
|
if ( !PrintDodEvent( event ) ) // allow DOD to override logging
|
|
{
|
|
return BaseClass::PrintEvent( event );
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool Init()
|
|
{
|
|
BaseClass::Init();
|
|
|
|
ListenForGameEvent( "player_death" );
|
|
ListenForGameEvent( "player_hurt" );
|
|
ListenForGameEvent( "player_changeclass" );
|
|
ListenForGameEvent( "dod_warmup_begins" );
|
|
ListenForGameEvent( "dod_warmup_ends" );
|
|
ListenForGameEvent( "dod_round_start" );
|
|
ListenForGameEvent( "dod_restart_round" );
|
|
ListenForGameEvent( "dod_ready_restart" );
|
|
ListenForGameEvent( "dod_allies_ready" );
|
|
ListenForGameEvent( "dod_axis_ready" );
|
|
ListenForGameEvent( "dod_round_restart_seconds" );
|
|
ListenForGameEvent( "dod_team_scores" );
|
|
ListenForGameEvent( "dod_round_win" );
|
|
ListenForGameEvent( "dod_tick_points" );
|
|
ListenForGameEvent( "dod_game_over" );
|
|
ListenForGameEvent( "dod_point_captured" );
|
|
ListenForGameEvent( "dod_capture_blocked" );
|
|
ListenForGameEvent( "dod_bomb_planted" );
|
|
ListenForGameEvent( "dod_bomb_exploded" );
|
|
ListenForGameEvent( "dod_bomb_defused" );
|
|
ListenForGameEvent( "dod_kill_planter" );
|
|
ListenForGameEvent( "dod_kill_defuser" );
|
|
|
|
return true;
|
|
}
|
|
|
|
protected:
|
|
|
|
bool PrintDodEvent( IGameEvent * event ) // print Mod specific logs
|
|
{
|
|
const char *eventName = event->GetName();
|
|
|
|
if ( !Q_strncmp( eventName, "server_", strlen("server_")) )
|
|
{
|
|
return false; // ignore server_ messages
|
|
}
|
|
|
|
if ( FStrEq( eventName, "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" );
|
|
CBasePlayer *pAttacker = UTIL_PlayerByUserId( attackerid );
|
|
|
|
if ( pPlayer == pAttacker )
|
|
{
|
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"%s\"\n",
|
|
pPlayer->GetPlayerName(),
|
|
userid,
|
|
pPlayer->GetNetworkIDString(),
|
|
pPlayer->GetTeam()->GetName(),
|
|
weapon
|
|
);
|
|
}
|
|
else if ( pAttacker )
|
|
{
|
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" killed \"%s<%i><%s><%s>\" with \"%s\"\n",
|
|
pAttacker->GetPlayerName(),
|
|
attackerid,
|
|
pAttacker->GetNetworkIDString(),
|
|
pAttacker->GetTeam()->GetName(),
|
|
pPlayer->GetPlayerName(),
|
|
userid,
|
|
pPlayer->GetNetworkIDString(),
|
|
pPlayer->GetTeam()->GetName(),
|
|
weapon
|
|
);
|
|
}
|
|
else
|
|
{
|
|
// killed by the world
|
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"world\"\n",
|
|
pPlayer->GetPlayerName(),
|
|
userid,
|
|
pPlayer->GetNetworkIDString(),
|
|
pPlayer->GetTeam()->GetName()
|
|
);
|
|
}
|
|
|
|
// Domination and Revenge
|
|
// pAttacker //int attackerid = engine->GetPlayerForUserID( event->GetInt( "attacker" ) );
|
|
// pPlayer //int userid = engine->GetPlayerForUserID( event->GetInt( "userid" ) );
|
|
|
|
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( "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()
|
|
);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
else if ( FStrEq( eventName, "player_hurt" ) )
|
|
{
|
|
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" );
|
|
CBasePlayer *pAttacker = UTIL_PlayerByUserId( attackerid );
|
|
if ( !pAttacker )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool isTeamAttack = ( (pPlayer->GetTeamNumber() == pAttacker->GetTeamNumber() ) && (pPlayer != pAttacker) );
|
|
int detail = mp_logdetail.GetInt();
|
|
if ( ( isTeamAttack && ( detail & LOG_DETAIL_TEAMMATE_ATTACKS ) ) ||
|
|
( !isTeamAttack && ( detail & LOG_DETAIL_ENEMY_ATTACKS ) ) )
|
|
{
|
|
int hitgroup = event->GetInt( "hitgroup" );
|
|
const char *hitgroupStr = "GENERIC";
|
|
switch ( hitgroup )
|
|
{
|
|
case HITGROUP_GENERIC:
|
|
hitgroupStr = "generic";
|
|
break;
|
|
case HITGROUP_HEAD:
|
|
hitgroupStr = "head";
|
|
break;
|
|
case HITGROUP_CHEST:
|
|
hitgroupStr = "chest";
|
|
break;
|
|
case HITGROUP_STOMACH:
|
|
hitgroupStr = "stomach";
|
|
break;
|
|
case HITGROUP_LEFTARM:
|
|
hitgroupStr = "left arm";
|
|
break;
|
|
case HITGROUP_RIGHTARM:
|
|
hitgroupStr = "right arm";
|
|
break;
|
|
case HITGROUP_LEFTLEG:
|
|
hitgroupStr = "left leg";
|
|
break;
|
|
case HITGROUP_RIGHTLEG:
|
|
hitgroupStr = "right leg";
|
|
break;
|
|
}
|
|
|
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" attacked \"%s<%i><%s><%s>\" with \"%s\" (damage \"%d\") (health \"%d\") (hitgroup \"%s\")\n",
|
|
pAttacker->GetPlayerName(),
|
|
attackerid,
|
|
pAttacker->GetNetworkIDString(),
|
|
pAttacker->GetTeam()->GetName(),
|
|
pPlayer->GetPlayerName(),
|
|
userid,
|
|
pPlayer->GetNetworkIDString(),
|
|
pPlayer->GetTeam()->GetName(),
|
|
weapon,
|
|
event->GetInt( "damage" ),
|
|
event->GetInt( "health" ),
|
|
hitgroupStr );
|
|
}
|
|
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");
|
|
int iTeam = pPlayer->GetTeamNumber();
|
|
|
|
if ( iTeam != TEAM_ALLIES && iTeam != TEAM_AXIS )
|
|
return true;
|
|
|
|
CDODTeam *pTeam = GetGlobalDODTeam( iTeam );
|
|
|
|
if ( iClass == PLAYERCLASS_RANDOM )
|
|
{
|
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" changed role to \"Random\"\n",
|
|
pPlayer->GetPlayerName(),
|
|
userid,
|
|
pPlayer->GetNetworkIDString(),
|
|
pTeam->GetName()
|
|
);
|
|
}
|
|
else if ( iClass < GetGlobalDODTeam(iTeam)->GetNumPlayerClasses() )
|
|
{
|
|
const CDODPlayerClassInfo &pInfo = GetGlobalDODTeam(iTeam)->GetPlayerClassInfo( iClass );
|
|
|
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" changed role to \"%s\"\n",
|
|
pPlayer->GetPlayerName(),
|
|
userid,
|
|
pPlayer->GetNetworkIDString(),
|
|
pTeam->GetName(),
|
|
pInfo.m_szPrintName
|
|
);
|
|
}
|
|
return true;
|
|
}
|
|
else if ( FStrEq( eventName, "dod_warmup_begins" ) )
|
|
{
|
|
UTIL_LogPrintf( "World triggered \"Warmup_Begin\"\n" );
|
|
return true;
|
|
}
|
|
else if ( FStrEq( eventName, "dod_warmup_ends" ) )
|
|
{
|
|
UTIL_LogPrintf( "World triggered \"Warmup_Ends\"\n" );
|
|
return true;
|
|
}
|
|
else if ( FStrEq( eventName, "dod_round_start" ) )
|
|
{
|
|
UTIL_LogPrintf("World triggered \"Round_Start\"\n");
|
|
return true;
|
|
}
|
|
else if ( FStrEq( eventName, "dod_restart_round" ) )
|
|
{
|
|
UTIL_LogPrintf("World triggered \"Round_Restart\"\n");
|
|
return true;
|
|
}
|
|
else if ( FStrEq( eventName, "dod_ready_restart" ) )
|
|
{
|
|
UTIL_LogPrintf( "World triggered \"Ready_Restart_Begin\"\n" );
|
|
return true;
|
|
}
|
|
else if ( FStrEq( eventName, "dod_allies_ready" ) )
|
|
{
|
|
UTIL_LogPrintf("World triggered \"Allies Ready\"\n");
|
|
return true;
|
|
}
|
|
else if ( FStrEq( eventName, "dod_axis_ready" ) )
|
|
{
|
|
UTIL_LogPrintf("World triggered \"Axis Ready\"\n");
|
|
return true;
|
|
}
|
|
else if ( FStrEq( eventName, "dod_round_restart_seconds" ) )
|
|
{
|
|
UTIL_LogPrintf( "World triggered \"Round_Restart_In\" (delay \"%d\")\n", event->GetInt("seconds") );
|
|
return true;
|
|
}
|
|
else if ( FStrEq( eventName, "dod_team_scores" ) )
|
|
{
|
|
int iAlliesRoundsWon = event->GetInt( "allies_caps" );
|
|
int iAlliesTickPoints = event->GetInt( "allies_tick" );
|
|
int iNumAllies = event->GetInt( "allies_players" );
|
|
int iAxisRoundsWon = event->GetInt( "axis_caps" );
|
|
int iAxisTickPoints = event->GetInt( "axis_tick" );
|
|
int iNumAxis = event->GetInt( "axis_players" );
|
|
|
|
UTIL_LogPrintf( "Team \"Allies\" triggered \"team_scores\" (roundswon \"%d\") (tickpoints \"%d\") (numplayers \"%d\")\n", iAlliesRoundsWon, iAlliesTickPoints, iNumAllies );
|
|
UTIL_LogPrintf( "Team \"Allies\" triggered \"team_scores\" (roundswon \"%d\") (tickpoints \"%d\") (numplayers \"%d\")\n", iAxisRoundsWon, iAxisTickPoints, iNumAxis );
|
|
return true;
|
|
}
|
|
else if ( FStrEq( eventName, "dod_round_win" ) )
|
|
{
|
|
CDODTeam *pTeam = GetGlobalDODTeam( event->GetInt( "team" ) );
|
|
|
|
UTIL_LogPrintf( "Team \"%s\" triggered \"round_win\" (rounds_won \"%d\") (numplayers \"%d\")\n",
|
|
pTeam->GetName(),
|
|
pTeam->GetRoundsWon(),
|
|
pTeam->GetNumPlayers() );
|
|
|
|
return true;
|
|
}
|
|
else if ( FStrEq( eventName, "dod_tick_points" ) )
|
|
{
|
|
CDODTeam *pTeam = GetGlobalDODTeam( event->GetInt( "team" ) );
|
|
|
|
int iScore = event->GetInt( "score" );
|
|
int iTotalScore = event->GetInt( "totalscore" );
|
|
|
|
UTIL_LogPrintf( "Team \"%s\" triggered \"tick_score\" (score \"%i\") (totalscore \"%d\") (numplayers \"%d\")\n",
|
|
pTeam->GetName(),
|
|
iScore,
|
|
iTotalScore,
|
|
pTeam->GetNumPlayers() );
|
|
|
|
return true;
|
|
}
|
|
else if ( FStrEq( eventName, "dod_game_over" ) )
|
|
{
|
|
UTIL_LogPrintf( "World triggered \"Game_Over\" reason \"%s\"\n", event->GetString( "reason" ) );
|
|
return true;
|
|
}
|
|
else if ( FStrEq( eventName, "dod_point_captured" ) )
|
|
{
|
|
// identifier of the area "cp" "cpname"
|
|
int iPointIndex = event->GetInt( "cp" );
|
|
const char *szPointName = event->GetString( "cpname" );
|
|
|
|
const char *szCappers = event->GetString( "cappers" );
|
|
|
|
int iNumCappers = Q_strlen( szCappers );
|
|
|
|
if ( iNumCappers <= 0 )
|
|
return true;
|
|
|
|
//"Team "Allies" captured location "<3><#map_flag_2nd_axis>" with "2"
|
|
// players (1 "Matt<UID><STEAMID><TEAM>") (2 "Player2<2><STEAMID><TEAM>")
|
|
|
|
char buf[512];
|
|
|
|
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 ( i == 0 )
|
|
{
|
|
Q_snprintf( buf, sizeof(buf), "Team \"%s\" triggered \"captured_loc\" (flagindex \"%d\") (flagname \"%s\") (numplayers \"%d\") ",
|
|
pPlayer->GetTeam()->GetName(),
|
|
iPointIndex,
|
|
szPointName,
|
|
iNumCappers );
|
|
}
|
|
|
|
char playerBuf[256];
|
|
Q_snprintf( playerBuf, sizeof(playerBuf), "(player \"%s<%i><%s><%s>\") ",
|
|
pPlayer->GetPlayerName(),
|
|
pPlayer->GetUserID(),
|
|
pPlayer->GetNetworkIDString(),
|
|
pPlayer->GetTeam()->GetName() );
|
|
|
|
Q_strncat( buf, playerBuf, sizeof(buf), COPY_ALL_CHARACTERS );
|
|
}
|
|
|
|
UTIL_LogPrintf( "%s\n", buf );
|
|
}
|
|
else if ( FStrEq( eventName, "dod_capture_blocked" ) )
|
|
{
|
|
int iPointIndex = event->GetInt( "cp" );
|
|
const char *szPointName = event->GetString( "cpname" );
|
|
|
|
int iBlocker = event->GetInt( "blocker" );
|
|
|
|
CBasePlayer *pPlayer = UTIL_PlayerByIndex( iBlocker );
|
|
|
|
if ( !pPlayer )
|
|
return false;
|
|
|
|
// "Matt<2><UNKNOWN><Allies>" triggered "capblock" (flagindex "2") (flagname "#map_flag_2nd_axis")
|
|
|
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"capblock\" (flagindex \"%d\") (flagname \"%s\")\n",
|
|
pPlayer->GetPlayerName(),
|
|
pPlayer->GetUserID(),
|
|
pPlayer->GetNetworkIDString(),
|
|
pPlayer->GetTeam()->GetName(),
|
|
iPointIndex,
|
|
szPointName );
|
|
}
|
|
else if ( FStrEq( eventName, "dod_bomb_planted" ) )
|
|
{
|
|
int iPointIndex = event->GetInt( "cp" );
|
|
const char *szPointName = event->GetString( "cpname" );
|
|
|
|
int iPlanter = event->GetInt( "userid" );
|
|
|
|
CBasePlayer *pPlayer = UTIL_PlayerByUserId( iPlanter );
|
|
|
|
if ( !pPlayer )
|
|
return false;
|
|
|
|
// "Matt<2><UNKNOWN><Allies>" triggered "bomb_plant" (flagindex "2") (flagname "#map_flag_2nd_axis")
|
|
|
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"bomb_plant\" (flagindex \"%d\") (flagname \"%s\")\n",
|
|
pPlayer->GetPlayerName(),
|
|
pPlayer->GetUserID(),
|
|
pPlayer->GetNetworkIDString(),
|
|
pPlayer->GetTeam()->GetName(),
|
|
iPointIndex,
|
|
szPointName );
|
|
|
|
return true;
|
|
}
|
|
else if ( FStrEq( eventName, "dod_bomb_defused" ) )
|
|
{
|
|
int iPointIndex = event->GetInt( "cp" );
|
|
const char *szPointName = event->GetString( "cpname" );
|
|
|
|
int iDefuser = event->GetInt( "userid" );
|
|
|
|
CBasePlayer *pPlayer = UTIL_PlayerByUserId( iDefuser );
|
|
|
|
if ( !pPlayer )
|
|
return false;
|
|
|
|
// "Matt<2><UNKNOWN><Allies>" triggered "bomb_defuse" (flagindex "2") (flagname "#map_flag_2nd_axis")
|
|
|
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"bomb_defuse\" (flagindex \"%d\") (flagname \"%s\")\n",
|
|
pPlayer->GetPlayerName(),
|
|
pPlayer->GetUserID(),
|
|
pPlayer->GetNetworkIDString(),
|
|
pPlayer->GetTeam()->GetName(),
|
|
iPointIndex,
|
|
szPointName );
|
|
|
|
return true;
|
|
}
|
|
else if ( FStrEq( eventName, "dod_kill_planter" ) )
|
|
{
|
|
int iKiller = event->GetInt( "userid" );
|
|
|
|
CBasePlayer *pPlayer = UTIL_PlayerByUserId( iKiller );
|
|
|
|
if ( !pPlayer )
|
|
return false;
|
|
|
|
int iVictim = event->GetInt( "victimid" );
|
|
|
|
CBasePlayer *pVictim = UTIL_PlayerByUserId( iVictim );
|
|
|
|
if ( !pVictim )
|
|
return false;
|
|
|
|
// "Matt<2><UNKNOWN><Allies>" triggered "kill_planter" against "Fred<3><UNKNOWN><Axis>"
|
|
|
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"kill_planter\" against \"%s<%i><%s><%s>\"\n",
|
|
pPlayer->GetPlayerName(),
|
|
pPlayer->GetUserID(),
|
|
pPlayer->GetNetworkIDString(),
|
|
pPlayer->GetTeam()->GetName(),
|
|
pVictim->GetPlayerName(),
|
|
pVictim->GetUserID(),
|
|
pVictim->GetNetworkIDString(),
|
|
pVictim->GetTeam()->GetName() );
|
|
|
|
return true;
|
|
}
|
|
else if ( FStrEq( eventName, "dod_kill_defuser" ) )
|
|
{
|
|
int iKiller = event->GetInt( "userid" );
|
|
|
|
CBasePlayer *pPlayer = UTIL_PlayerByUserId( iKiller );
|
|
|
|
if ( !pPlayer )
|
|
return false;
|
|
|
|
int iVictim = event->GetInt( "victimid" );
|
|
|
|
CBasePlayer *pVictim = UTIL_PlayerByUserId( iVictim );
|
|
|
|
if ( !pVictim )
|
|
return false;
|
|
|
|
// "Matt<2><UNKNOWN><Allies>" triggered "kill_defuser" against "Fred<3><UNKNOWN><Axis>"
|
|
|
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"kill_defuser\" against \"%s<%i><%s><%s>\"\n",
|
|
pPlayer->GetPlayerName(),
|
|
pPlayer->GetUserID(),
|
|
pPlayer->GetNetworkIDString(),
|
|
pPlayer->GetTeam()->GetName(),
|
|
pVictim->GetPlayerName(),
|
|
pVictim->GetUserID(),
|
|
pVictim->GetNetworkIDString(),
|
|
pVictim->GetTeam()->GetName() );
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
};
|
|
|
|
CDODEventLog g_DODEventLog;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Singleton access
|
|
//-----------------------------------------------------------------------------
|
|
IGameSystem* GameLogSystem()
|
|
{
|
|
return &g_DODEventLog;
|
|
}
|
|
|