//========= 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") (2 "Player2<2>") char buf[512]; for ( int i=0;i 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>" 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>" 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>" 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>" triggered "kill_planter" against "Fred<3>" 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>" triggered "kill_defuser" against "Fred<3>" 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; }