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.

321 lines
9.1 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 "cs_gamerules.h"
  12. #include "KeyValues.h"
  13. #define LOG_DETAIL_ENEMY_ATTACKS 0x01
  14. #define LOG_DETAIL_TEAMMATE_ATTACKS 0x02
  15. 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 );
  16. class CCSEventLog : public CEventLog
  17. {
  18. private:
  19. typedef CEventLog BaseClass;
  20. public:
  21. bool PrintEvent( IGameEvent *event ) // override virtual function
  22. {
  23. if ( !PrintCStrikeEvent( event ) ) // allow CS to override logging
  24. {
  25. return BaseClass::PrintEvent( event );
  26. }
  27. else
  28. {
  29. return true;
  30. }
  31. }
  32. bool Init()
  33. {
  34. BaseClass::Init();
  35. // listen to CS events
  36. ListenForGameEvent( "round_end" );
  37. ListenForGameEvent( "round_start" );
  38. ListenForGameEvent( "bomb_pickup" );
  39. ListenForGameEvent( "bomb_begindefuse" );
  40. ListenForGameEvent( "bomb_dropped" );
  41. ListenForGameEvent( "bomb_defused" );
  42. ListenForGameEvent( "bomb_planted" );
  43. ListenForGameEvent( "hostage_rescued" );
  44. ListenForGameEvent( "hostage_killed" );
  45. ListenForGameEvent( "hostage_follows" );
  46. ListenForGameEvent( "player_hurt" );
  47. return true;
  48. }
  49. protected:
  50. bool PrintCStrikeEvent( IGameEvent *event ) // print Mod specific logs
  51. {
  52. const char *eventName = event->GetName();
  53. // messages that don't have a user associated to them
  54. if ( !Q_strncmp( eventName, "round_end", Q_strlen("round_end") ) )
  55. {
  56. const int winner = event->GetInt( "winner" );
  57. const int reason = event->GetInt( "reason" );
  58. const char *msg = event->GetString( "message" );
  59. msg++; // remove the '#' char
  60. switch( reason )
  61. {
  62. case Game_Commencing:
  63. UTIL_LogPrintf( "World triggered \"Game_Commencing\"\n" );
  64. return true;
  65. break;
  66. }
  67. CTeam *ct = GetGlobalTeam( TEAM_CT );
  68. CTeam *ter = GetGlobalTeam( TEAM_TERRORIST );
  69. Assert( ct && ter );
  70. switch ( winner )
  71. {
  72. case WINNER_CT:
  73. UTIL_LogPrintf( "Team \"%s\" triggered \"%s\" (CT \"%i\") (T \"%i\")\n", ct->GetName(), msg, ct->GetScore(), ter->GetScore() );
  74. break;
  75. case WINNER_TER:
  76. UTIL_LogPrintf( "Team \"%s\" triggered \"%s\" (CT \"%i\") (T \"%i\")\n", ter->GetName(), msg, ct->GetScore(), ter->GetScore() );
  77. break;
  78. case WINNER_DRAW:
  79. default:
  80. UTIL_LogPrintf( "World triggered \"%s\" (CT \"%i\") (T \"%i\")\n", msg, ct->GetScore(), ter->GetScore() );
  81. break;
  82. }
  83. UTIL_LogPrintf( "Team \"CT\" scored \"%i\" with \"%i\" players\n", ct->GetScore(), ct->GetNumPlayers() );
  84. UTIL_LogPrintf( "Team \"TERRORIST\" scored \"%i\" with \"%i\" players\n", ter->GetScore(), ter->GetNumPlayers() );
  85. UTIL_LogPrintf("World triggered \"Round_End\"\n");
  86. return true;
  87. }
  88. else if ( !Q_strncmp( eventName, "server_", strlen("server_")) )
  89. {
  90. return false; // ignore server_ messages
  91. }
  92. const int userid = event->GetInt( "userid" );
  93. CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid );
  94. if ( !pPlayer )
  95. {
  96. return false;
  97. }
  98. if ( FStrEq( eventName, "player_hurt" ) )
  99. {
  100. const int attackerid = event->GetInt("attacker" );
  101. const char *weapon = event->GetString( "weapon" );
  102. CBasePlayer *pAttacker = UTIL_PlayerByUserId( attackerid );
  103. if ( !pAttacker )
  104. {
  105. return false;
  106. }
  107. bool isTeamAttack = ( (pPlayer->GetTeamNumber() == pAttacker->GetTeamNumber() ) && (pPlayer != pAttacker) );
  108. int detail = mp_logdetail.GetInt();
  109. if ( ( isTeamAttack && ( detail & LOG_DETAIL_TEAMMATE_ATTACKS ) ) ||
  110. ( !isTeamAttack && ( detail & LOG_DETAIL_ENEMY_ATTACKS ) ) )
  111. {
  112. int hitgroup = event->GetInt( "hitgroup" );
  113. const char *hitgroupStr = "GENERIC";
  114. switch ( hitgroup )
  115. {
  116. case HITGROUP_GENERIC:
  117. hitgroupStr = "generic";
  118. break;
  119. case HITGROUP_HEAD:
  120. hitgroupStr = "head";
  121. break;
  122. case HITGROUP_CHEST:
  123. hitgroupStr = "chest";
  124. break;
  125. case HITGROUP_STOMACH:
  126. hitgroupStr = "stomach";
  127. break;
  128. case HITGROUP_LEFTARM:
  129. hitgroupStr = "left arm";
  130. break;
  131. case HITGROUP_RIGHTARM:
  132. hitgroupStr = "right arm";
  133. break;
  134. case HITGROUP_LEFTLEG:
  135. hitgroupStr = "left leg";
  136. break;
  137. case HITGROUP_RIGHTLEG:
  138. hitgroupStr = "right leg";
  139. break;
  140. }
  141. UTIL_LogPrintf( "\"%s<%i><%s><%s>\" attacked \"%s<%i><%s><%s>\" with \"%s\" (damage \"%d\") (damage_armor \"%d\") (health \"%d\") (armor \"%d\") (hitgroup \"%s\")\n",
  142. pAttacker->GetPlayerName(),
  143. attackerid,
  144. pAttacker->GetNetworkIDString(),
  145. pAttacker->GetTeam()->GetName(),
  146. pPlayer->GetPlayerName(),
  147. userid,
  148. pPlayer->GetNetworkIDString(),
  149. pPlayer->GetTeam()->GetName(),
  150. weapon,
  151. event->GetInt( "dmg_health" ),
  152. event->GetInt( "dmg_armor" ),
  153. event->GetInt( "health" ),
  154. event->GetInt( "armor" ),
  155. hitgroupStr );
  156. }
  157. return true;
  158. }
  159. else if ( !Q_strncmp( eventName, "player_death", Q_strlen("player_death") ) )
  160. {
  161. const int attackerid = event->GetInt("attacker" );
  162. const char *weapon = event->GetString( "weapon" );
  163. const bool headShot = (event->GetInt( "headshot" ) == 1);
  164. CBasePlayer *pAttacker = UTIL_PlayerByUserId( attackerid );
  165. if ( pPlayer == pAttacker )
  166. {
  167. UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"%s\"\n",
  168. pPlayer->GetPlayerName(),
  169. userid,
  170. pPlayer->GetNetworkIDString(),
  171. pPlayer->GetTeam()->GetName(),
  172. weapon
  173. );
  174. }
  175. else if ( pAttacker )
  176. {
  177. UTIL_LogPrintf( "\"%s<%i><%s><%s>\" killed \"%s<%i><%s><%s>\" with \"%s\"%s\n",
  178. pAttacker->GetPlayerName(),
  179. attackerid,
  180. pAttacker->GetNetworkIDString(),
  181. pAttacker->GetTeam()->GetName(),
  182. pPlayer->GetPlayerName(),
  183. userid,
  184. pPlayer->GetNetworkIDString(),
  185. pPlayer->GetTeam()->GetName(),
  186. weapon,
  187. headShot ? " (headshot)":""
  188. );
  189. }
  190. else
  191. {
  192. // killed by the world
  193. UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"world\"\n",
  194. pPlayer->GetPlayerName(),
  195. userid,
  196. pPlayer->GetNetworkIDString(),
  197. pPlayer->GetTeam()->GetName()
  198. );
  199. }
  200. return true;
  201. }
  202. else if ( !Q_strncmp( eventName, "round_start", Q_strlen("round_start") ) )
  203. {
  204. UTIL_LogPrintf("World triggered \"Round_Start\"\n");
  205. return true;
  206. }
  207. else if ( !Q_strncmp( eventName, "hostage_follows", Q_strlen("hostage_follows") ) )
  208. {
  209. UTIL_LogPrintf( "\"%s<%i><%s><CT>\" triggered \"Touched_A_Hostage\"\n",
  210. pPlayer->GetPlayerName(),
  211. userid,
  212. pPlayer->GetNetworkIDString()
  213. );
  214. return true;
  215. }
  216. else if ( !Q_strncmp( eventName, "hostage_killed", Q_strlen("hostage_killed") ) )
  217. {
  218. UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Killed_A_Hostage\"\n",
  219. pPlayer->GetPlayerName(),
  220. userid,
  221. pPlayer->GetNetworkIDString(),
  222. pPlayer->GetTeam()->GetName()
  223. );
  224. return true;
  225. }
  226. else if ( !Q_strncmp( eventName, "hostage_rescued", Q_strlen("hostage_rescued") ) )
  227. {
  228. UTIL_LogPrintf("\"%s<%i><%s><CT>\" triggered \"Rescued_A_Hostage\"\n",
  229. pPlayer->GetPlayerName(),
  230. userid,
  231. pPlayer->GetNetworkIDString()
  232. );
  233. return true;
  234. }
  235. else if ( !Q_strncmp( eventName, "bomb_planted", Q_strlen("bomb_planted") ) )
  236. {
  237. UTIL_LogPrintf("\"%s<%i><%s><TERRORIST>\" triggered \"Planted_The_Bomb\"\n",
  238. pPlayer->GetPlayerName(),
  239. userid,
  240. pPlayer->GetNetworkIDString()
  241. );
  242. return true;
  243. }
  244. else if ( !Q_strncmp( eventName, "bomb_defused", Q_strlen("bomb_defused") ) )
  245. {
  246. UTIL_LogPrintf("\"%s<%i><%s><CT>\" triggered \"Defused_The_Bomb\"\n",
  247. pPlayer->GetPlayerName(),
  248. userid,
  249. pPlayer->GetNetworkIDString()
  250. );
  251. return true;
  252. }
  253. else if ( !Q_strncmp( eventName, "bomb_dropped", Q_strlen("bomb_dropped") ) )
  254. {
  255. UTIL_LogPrintf("\"%s<%i><%s><TERRORIST>\" triggered \"Dropped_The_Bomb\"\n",
  256. pPlayer->GetPlayerName(),
  257. userid,
  258. pPlayer->GetNetworkIDString()
  259. );
  260. return true;
  261. }
  262. else if ( !Q_strncmp( eventName, "bomb_begindefuse", Q_strlen("bomb_begindefuse") ) )
  263. {
  264. const bool haskit = (event->GetInt( "haskit" ) == 1);
  265. UTIL_LogPrintf("\"%s<%i><%s><CT>\" triggered \"%s\"\n",
  266. pPlayer->GetPlayerName(),
  267. userid,
  268. pPlayer->GetNetworkIDString(),
  269. haskit ? "Begin_Bomb_Defuse_With_Kit" : "Begin_Bomb_Defuse_Without_Kit"
  270. );
  271. return true;
  272. }
  273. else if ( !Q_strncmp( eventName, "bomb_pickup", Q_strlen("bomb_pickup") ) )
  274. {
  275. UTIL_LogPrintf("\"%s<%i><%s><TERRORIST>\" triggered \"Got_The_Bomb\"\n",
  276. pPlayer->GetPlayerName(),
  277. userid,
  278. pPlayer->GetNetworkIDString()
  279. );
  280. return true;
  281. }
  282. // unused events:
  283. //hostage_hurt
  284. //bomb_exploded
  285. return false;
  286. }
  287. };
  288. CCSEventLog g_CSEventLog;
  289. //-----------------------------------------------------------------------------
  290. // Singleton access
  291. //-----------------------------------------------------------------------------
  292. IGameSystem* GameLogSystem()
  293. {
  294. return &g_CSEventLog;
  295. }