Team Fortress 2 Source Code as on 22/4/2020
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

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #include "cbase.h"
  9. #include "../EventLog.h"
  10. #include "team.h"
  11. #include "KeyValues.h"
  12. #include "dod_shareddefs.h"
  13. #include "dod_team.h"
  14. #define LOG_DETAIL_ENEMY_ATTACKS 1
  15. #define LOG_DETAIL_TEAMMATE_ATTACKS 2
  16. 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 );
  17. class CDODEventLog : public CEventLog
  18. {
  19. private:
  20. typedef CEventLog BaseClass;
  21. public:
  22. bool PrintEvent( IGameEvent * event ) // override virtual function
  23. {
  24. if ( !PrintDodEvent( event ) ) // allow DOD to override logging
  25. {
  26. return BaseClass::PrintEvent( event );
  27. }
  28. else
  29. {
  30. return true;
  31. }
  32. }
  33. bool Init()
  34. {
  35. BaseClass::Init();
  36. ListenForGameEvent( "player_death" );
  37. ListenForGameEvent( "player_hurt" );
  38. ListenForGameEvent( "player_changeclass" );
  39. ListenForGameEvent( "dod_warmup_begins" );
  40. ListenForGameEvent( "dod_warmup_ends" );
  41. ListenForGameEvent( "dod_round_start" );
  42. ListenForGameEvent( "dod_restart_round" );
  43. ListenForGameEvent( "dod_ready_restart" );
  44. ListenForGameEvent( "dod_allies_ready" );
  45. ListenForGameEvent( "dod_axis_ready" );
  46. ListenForGameEvent( "dod_round_restart_seconds" );
  47. ListenForGameEvent( "dod_team_scores" );
  48. ListenForGameEvent( "dod_round_win" );
  49. ListenForGameEvent( "dod_tick_points" );
  50. ListenForGameEvent( "dod_game_over" );
  51. ListenForGameEvent( "dod_point_captured" );
  52. ListenForGameEvent( "dod_capture_blocked" );
  53. ListenForGameEvent( "dod_bomb_planted" );
  54. ListenForGameEvent( "dod_bomb_exploded" );
  55. ListenForGameEvent( "dod_bomb_defused" );
  56. ListenForGameEvent( "dod_kill_planter" );
  57. ListenForGameEvent( "dod_kill_defuser" );
  58. return true;
  59. }
  60. protected:
  61. bool PrintDodEvent( IGameEvent * event ) // print Mod specific logs
  62. {
  63. const char *eventName = event->GetName();
  64. if ( !Q_strncmp( eventName, "server_", strlen("server_")) )
  65. {
  66. return false; // ignore server_ messages
  67. }
  68. if ( FStrEq( eventName, "player_death" ) )
  69. {
  70. const int userid = event->GetInt( "userid" );
  71. CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid );
  72. if ( !pPlayer )
  73. {
  74. return false;
  75. }
  76. const int attackerid = event->GetInt("attacker" );
  77. const char *weapon = event->GetString( "weapon" );
  78. CBasePlayer *pAttacker = UTIL_PlayerByUserId( attackerid );
  79. if ( pPlayer == pAttacker )
  80. {
  81. UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"%s\"\n",
  82. pPlayer->GetPlayerName(),
  83. userid,
  84. pPlayer->GetNetworkIDString(),
  85. pPlayer->GetTeam()->GetName(),
  86. weapon
  87. );
  88. }
  89. else if ( pAttacker )
  90. {
  91. UTIL_LogPrintf( "\"%s<%i><%s><%s>\" killed \"%s<%i><%s><%s>\" with \"%s\"\n",
  92. pAttacker->GetPlayerName(),
  93. attackerid,
  94. pAttacker->GetNetworkIDString(),
  95. pAttacker->GetTeam()->GetName(),
  96. pPlayer->GetPlayerName(),
  97. userid,
  98. pPlayer->GetNetworkIDString(),
  99. pPlayer->GetTeam()->GetName(),
  100. weapon
  101. );
  102. }
  103. else
  104. {
  105. // killed by the world
  106. UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"world\"\n",
  107. pPlayer->GetPlayerName(),
  108. userid,
  109. pPlayer->GetNetworkIDString(),
  110. pPlayer->GetTeam()->GetName()
  111. );
  112. }
  113. // Domination and Revenge
  114. // pAttacker //int attackerid = engine->GetPlayerForUserID( event->GetInt( "attacker" ) );
  115. // pPlayer //int userid = engine->GetPlayerForUserID( event->GetInt( "userid" ) );
  116. if ( event->GetInt( "dominated" ) > 0 && pAttacker )
  117. {
  118. UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"domination\" against \"%s<%i><%s><%s>\"\n",
  119. pAttacker->GetPlayerName(),
  120. attackerid,
  121. pAttacker->GetNetworkIDString(),
  122. pAttacker->GetTeam()->GetName(),
  123. pPlayer->GetPlayerName(),
  124. userid,
  125. pPlayer->GetNetworkIDString(),
  126. pPlayer->GetTeam()->GetName()
  127. );
  128. }
  129. if ( event->GetInt( "revenge" ) > 0 && pAttacker )
  130. {
  131. UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"revenge\" against \"%s<%i><%s><%s>\"\n",
  132. pAttacker->GetPlayerName(),
  133. attackerid,
  134. pAttacker->GetNetworkIDString(),
  135. pAttacker->GetTeam()->GetName(),
  136. pPlayer->GetPlayerName(),
  137. userid,
  138. pPlayer->GetNetworkIDString(),
  139. pPlayer->GetTeam()->GetName()
  140. );
  141. }
  142. return true;
  143. }
  144. else if ( FStrEq( eventName, "player_hurt" ) )
  145. {
  146. const int userid = event->GetInt( "userid" );
  147. CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid );
  148. if ( !pPlayer )
  149. {
  150. return false;
  151. }
  152. const int attackerid = event->GetInt("attacker" );
  153. const char *weapon = event->GetString( "weapon" );
  154. CBasePlayer *pAttacker = UTIL_PlayerByUserId( attackerid );
  155. if ( !pAttacker )
  156. {
  157. return false;
  158. }
  159. bool isTeamAttack = ( (pPlayer->GetTeamNumber() == pAttacker->GetTeamNumber() ) && (pPlayer != pAttacker) );
  160. int detail = mp_logdetail.GetInt();
  161. if ( ( isTeamAttack && ( detail & LOG_DETAIL_TEAMMATE_ATTACKS ) ) ||
  162. ( !isTeamAttack && ( detail & LOG_DETAIL_ENEMY_ATTACKS ) ) )
  163. {
  164. int hitgroup = event->GetInt( "hitgroup" );
  165. const char *hitgroupStr = "GENERIC";
  166. switch ( hitgroup )
  167. {
  168. case HITGROUP_GENERIC:
  169. hitgroupStr = "generic";
  170. break;
  171. case HITGROUP_HEAD:
  172. hitgroupStr = "head";
  173. break;
  174. case HITGROUP_CHEST:
  175. hitgroupStr = "chest";
  176. break;
  177. case HITGROUP_STOMACH:
  178. hitgroupStr = "stomach";
  179. break;
  180. case HITGROUP_LEFTARM:
  181. hitgroupStr = "left arm";
  182. break;
  183. case HITGROUP_RIGHTARM:
  184. hitgroupStr = "right arm";
  185. break;
  186. case HITGROUP_LEFTLEG:
  187. hitgroupStr = "left leg";
  188. break;
  189. case HITGROUP_RIGHTLEG:
  190. hitgroupStr = "right leg";
  191. break;
  192. }
  193. UTIL_LogPrintf( "\"%s<%i><%s><%s>\" attacked \"%s<%i><%s><%s>\" with \"%s\" (damage \"%d\") (health \"%d\") (hitgroup \"%s\")\n",
  194. pAttacker->GetPlayerName(),
  195. attackerid,
  196. pAttacker->GetNetworkIDString(),
  197. pAttacker->GetTeam()->GetName(),
  198. pPlayer->GetPlayerName(),
  199. userid,
  200. pPlayer->GetNetworkIDString(),
  201. pPlayer->GetTeam()->GetName(),
  202. weapon,
  203. event->GetInt( "damage" ),
  204. event->GetInt( "health" ),
  205. hitgroupStr );
  206. }
  207. return true;
  208. }
  209. else if ( FStrEq( eventName, "player_changeclass" ) )
  210. {
  211. const int userid = event->GetInt( "userid" );
  212. CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid );
  213. if ( !pPlayer )
  214. {
  215. return false;
  216. }
  217. int iClass = event->GetInt("class");
  218. int iTeam = pPlayer->GetTeamNumber();
  219. if ( iTeam != TEAM_ALLIES && iTeam != TEAM_AXIS )
  220. return true;
  221. CDODTeam *pTeam = GetGlobalDODTeam( iTeam );
  222. if ( iClass == PLAYERCLASS_RANDOM )
  223. {
  224. UTIL_LogPrintf( "\"%s<%i><%s><%s>\" changed role to \"Random\"\n",
  225. pPlayer->GetPlayerName(),
  226. userid,
  227. pPlayer->GetNetworkIDString(),
  228. pTeam->GetName()
  229. );
  230. }
  231. else if ( iClass < GetGlobalDODTeam(iTeam)->GetNumPlayerClasses() )
  232. {
  233. const CDODPlayerClassInfo &pInfo = GetGlobalDODTeam(iTeam)->GetPlayerClassInfo( iClass );
  234. UTIL_LogPrintf( "\"%s<%i><%s><%s>\" changed role to \"%s\"\n",
  235. pPlayer->GetPlayerName(),
  236. userid,
  237. pPlayer->GetNetworkIDString(),
  238. pTeam->GetName(),
  239. pInfo.m_szPrintName
  240. );
  241. }
  242. return true;
  243. }
  244. else if ( FStrEq( eventName, "dod_warmup_begins" ) )
  245. {
  246. UTIL_LogPrintf( "World triggered \"Warmup_Begin\"\n" );
  247. return true;
  248. }
  249. else if ( FStrEq( eventName, "dod_warmup_ends" ) )
  250. {
  251. UTIL_LogPrintf( "World triggered \"Warmup_Ends\"\n" );
  252. return true;
  253. }
  254. else if ( FStrEq( eventName, "dod_round_start" ) )
  255. {
  256. UTIL_LogPrintf("World triggered \"Round_Start\"\n");
  257. return true;
  258. }
  259. else if ( FStrEq( eventName, "dod_restart_round" ) )
  260. {
  261. UTIL_LogPrintf("World triggered \"Round_Restart\"\n");
  262. return true;
  263. }
  264. else if ( FStrEq( eventName, "dod_ready_restart" ) )
  265. {
  266. UTIL_LogPrintf( "World triggered \"Ready_Restart_Begin\"\n" );
  267. return true;
  268. }
  269. else if ( FStrEq( eventName, "dod_allies_ready" ) )
  270. {
  271. UTIL_LogPrintf("World triggered \"Allies Ready\"\n");
  272. return true;
  273. }
  274. else if ( FStrEq( eventName, "dod_axis_ready" ) )
  275. {
  276. UTIL_LogPrintf("World triggered \"Axis Ready\"\n");
  277. return true;
  278. }
  279. else if ( FStrEq( eventName, "dod_round_restart_seconds" ) )
  280. {
  281. UTIL_LogPrintf( "World triggered \"Round_Restart_In\" (delay \"%d\")\n", event->GetInt("seconds") );
  282. return true;
  283. }
  284. else if ( FStrEq( eventName, "dod_team_scores" ) )
  285. {
  286. int iAlliesRoundsWon = event->GetInt( "allies_caps" );
  287. int iAlliesTickPoints = event->GetInt( "allies_tick" );
  288. int iNumAllies = event->GetInt( "allies_players" );
  289. int iAxisRoundsWon = event->GetInt( "axis_caps" );
  290. int iAxisTickPoints = event->GetInt( "axis_tick" );
  291. int iNumAxis = event->GetInt( "axis_players" );
  292. UTIL_LogPrintf( "Team \"Allies\" triggered \"team_scores\" (roundswon \"%d\") (tickpoints \"%d\") (numplayers \"%d\")\n", iAlliesRoundsWon, iAlliesTickPoints, iNumAllies );
  293. UTIL_LogPrintf( "Team \"Allies\" triggered \"team_scores\" (roundswon \"%d\") (tickpoints \"%d\") (numplayers \"%d\")\n", iAxisRoundsWon, iAxisTickPoints, iNumAxis );
  294. return true;
  295. }
  296. else if ( FStrEq( eventName, "dod_round_win" ) )
  297. {
  298. CDODTeam *pTeam = GetGlobalDODTeam( event->GetInt( "team" ) );
  299. UTIL_LogPrintf( "Team \"%s\" triggered \"round_win\" (rounds_won \"%d\") (numplayers \"%d\")\n",
  300. pTeam->GetName(),
  301. pTeam->GetRoundsWon(),
  302. pTeam->GetNumPlayers() );
  303. return true;
  304. }
  305. else if ( FStrEq( eventName, "dod_tick_points" ) )
  306. {
  307. CDODTeam *pTeam = GetGlobalDODTeam( event->GetInt( "team" ) );
  308. int iScore = event->GetInt( "score" );
  309. int iTotalScore = event->GetInt( "totalscore" );
  310. UTIL_LogPrintf( "Team \"%s\" triggered \"tick_score\" (score \"%i\") (totalscore \"%d\") (numplayers \"%d\")\n",
  311. pTeam->GetName(),
  312. iScore,
  313. iTotalScore,
  314. pTeam->GetNumPlayers() );
  315. return true;
  316. }
  317. else if ( FStrEq( eventName, "dod_game_over" ) )
  318. {
  319. UTIL_LogPrintf( "World triggered \"Game_Over\" reason \"%s\"\n", event->GetString( "reason" ) );
  320. return true;
  321. }
  322. else if ( FStrEq( eventName, "dod_point_captured" ) )
  323. {
  324. // identifier of the area "cp" "cpname"
  325. int iPointIndex = event->GetInt( "cp" );
  326. const char *szPointName = event->GetString( "cpname" );
  327. const char *szCappers = event->GetString( "cappers" );
  328. int iNumCappers = Q_strlen( szCappers );
  329. if ( iNumCappers <= 0 )
  330. return true;
  331. //"Team "Allies" captured location "<3><#map_flag_2nd_axis>" with "2"
  332. // players (1 "Matt<UID><STEAMID><TEAM>") (2 "Player2<2><STEAMID><TEAM>")
  333. char buf[512];
  334. for ( int i=0;i<iNumCappers;i++ )
  335. {
  336. int iPlayerIndex = szCappers[i];
  337. Assert( iPlayerIndex != '\0' && iPlayerIndex > 0 && iPlayerIndex < MAX_PLAYERS );
  338. CBasePlayer *pPlayer = UTIL_PlayerByIndex( iPlayerIndex );
  339. if ( i == 0 )
  340. {
  341. Q_snprintf( buf, sizeof(buf), "Team \"%s\" triggered \"captured_loc\" (flagindex \"%d\") (flagname \"%s\") (numplayers \"%d\") ",
  342. pPlayer->GetTeam()->GetName(),
  343. iPointIndex,
  344. szPointName,
  345. iNumCappers );
  346. }
  347. char playerBuf[256];
  348. Q_snprintf( playerBuf, sizeof(playerBuf), "(player \"%s<%i><%s><%s>\") ",
  349. pPlayer->GetPlayerName(),
  350. pPlayer->GetUserID(),
  351. pPlayer->GetNetworkIDString(),
  352. pPlayer->GetTeam()->GetName() );
  353. Q_strncat( buf, playerBuf, sizeof(buf), COPY_ALL_CHARACTERS );
  354. }
  355. UTIL_LogPrintf( "%s\n", buf );
  356. }
  357. else if ( FStrEq( eventName, "dod_capture_blocked" ) )
  358. {
  359. int iPointIndex = event->GetInt( "cp" );
  360. const char *szPointName = event->GetString( "cpname" );
  361. int iBlocker = event->GetInt( "blocker" );
  362. CBasePlayer *pPlayer = UTIL_PlayerByIndex( iBlocker );
  363. if ( !pPlayer )
  364. return false;
  365. // "Matt<2><UNKNOWN><Allies>" triggered "capblock" (flagindex "2") (flagname "#map_flag_2nd_axis")
  366. UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"capblock\" (flagindex \"%d\") (flagname \"%s\")\n",
  367. pPlayer->GetPlayerName(),
  368. pPlayer->GetUserID(),
  369. pPlayer->GetNetworkIDString(),
  370. pPlayer->GetTeam()->GetName(),
  371. iPointIndex,
  372. szPointName );
  373. }
  374. else if ( FStrEq( eventName, "dod_bomb_planted" ) )
  375. {
  376. int iPointIndex = event->GetInt( "cp" );
  377. const char *szPointName = event->GetString( "cpname" );
  378. int iPlanter = event->GetInt( "userid" );
  379. CBasePlayer *pPlayer = UTIL_PlayerByUserId( iPlanter );
  380. if ( !pPlayer )
  381. return false;
  382. // "Matt<2><UNKNOWN><Allies>" triggered "bomb_plant" (flagindex "2") (flagname "#map_flag_2nd_axis")
  383. UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"bomb_plant\" (flagindex \"%d\") (flagname \"%s\")\n",
  384. pPlayer->GetPlayerName(),
  385. pPlayer->GetUserID(),
  386. pPlayer->GetNetworkIDString(),
  387. pPlayer->GetTeam()->GetName(),
  388. iPointIndex,
  389. szPointName );
  390. return true;
  391. }
  392. else if ( FStrEq( eventName, "dod_bomb_defused" ) )
  393. {
  394. int iPointIndex = event->GetInt( "cp" );
  395. const char *szPointName = event->GetString( "cpname" );
  396. int iDefuser = event->GetInt( "userid" );
  397. CBasePlayer *pPlayer = UTIL_PlayerByUserId( iDefuser );
  398. if ( !pPlayer )
  399. return false;
  400. // "Matt<2><UNKNOWN><Allies>" triggered "bomb_defuse" (flagindex "2") (flagname "#map_flag_2nd_axis")
  401. UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"bomb_defuse\" (flagindex \"%d\") (flagname \"%s\")\n",
  402. pPlayer->GetPlayerName(),
  403. pPlayer->GetUserID(),
  404. pPlayer->GetNetworkIDString(),
  405. pPlayer->GetTeam()->GetName(),
  406. iPointIndex,
  407. szPointName );
  408. return true;
  409. }
  410. else if ( FStrEq( eventName, "dod_kill_planter" ) )
  411. {
  412. int iKiller = event->GetInt( "userid" );
  413. CBasePlayer *pPlayer = UTIL_PlayerByUserId( iKiller );
  414. if ( !pPlayer )
  415. return false;
  416. int iVictim = event->GetInt( "victimid" );
  417. CBasePlayer *pVictim = UTIL_PlayerByUserId( iVictim );
  418. if ( !pVictim )
  419. return false;
  420. // "Matt<2><UNKNOWN><Allies>" triggered "kill_planter" against "Fred<3><UNKNOWN><Axis>"
  421. UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"kill_planter\" against \"%s<%i><%s><%s>\"\n",
  422. pPlayer->GetPlayerName(),
  423. pPlayer->GetUserID(),
  424. pPlayer->GetNetworkIDString(),
  425. pPlayer->GetTeam()->GetName(),
  426. pVictim->GetPlayerName(),
  427. pVictim->GetUserID(),
  428. pVictim->GetNetworkIDString(),
  429. pVictim->GetTeam()->GetName() );
  430. return true;
  431. }
  432. else if ( FStrEq( eventName, "dod_kill_defuser" ) )
  433. {
  434. int iKiller = event->GetInt( "userid" );
  435. CBasePlayer *pPlayer = UTIL_PlayerByUserId( iKiller );
  436. if ( !pPlayer )
  437. return false;
  438. int iVictim = event->GetInt( "victimid" );
  439. CBasePlayer *pVictim = UTIL_PlayerByUserId( iVictim );
  440. if ( !pVictim )
  441. return false;
  442. // "Matt<2><UNKNOWN><Allies>" triggered "kill_defuser" against "Fred<3><UNKNOWN><Axis>"
  443. UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"kill_defuser\" against \"%s<%i><%s><%s>\"\n",
  444. pPlayer->GetPlayerName(),
  445. pPlayer->GetUserID(),
  446. pPlayer->GetNetworkIDString(),
  447. pPlayer->GetTeam()->GetName(),
  448. pVictim->GetPlayerName(),
  449. pVictim->GetUserID(),
  450. pVictim->GetNetworkIDString(),
  451. pVictim->GetTeam()->GetName() );
  452. return true;
  453. }
  454. return false;
  455. }
  456. };
  457. CDODEventLog g_DODEventLog;
  458. //-----------------------------------------------------------------------------
  459. // Singleton access
  460. //-----------------------------------------------------------------------------
  461. IGameSystem* GameLogSystem()
  462. {
  463. return &g_DODEventLog;
  464. }