pluginadminlog.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. class PluginAdminLog extends PluginBase // Class for admin log messages handled by script
  2. {
  3. string m_PlayerName;
  4. string m_Pid;
  5. vector m_Position;
  6. string m_PlayerPrefix;
  7. string m_PlayerPrefix2;
  8. string m_Message;
  9. string m_DisplayName;
  10. string m_HitMessage;
  11. float m_Distance;
  12. PlayerBase m_Player;
  13. PlayerBase m_Source;
  14. string m_ItemInHands;
  15. string m_PosArray[3];
  16. int m_DotIndex;
  17. PlayerStat<float> m_StatWater;
  18. PlayerStat<float> m_StatEnergy;
  19. BleedingSourcesManagerServer m_BleedMgr;
  20. // filters
  21. protected int m_HitFilter;
  22. protected int m_PlacementFilter;
  23. protected int m_ActionsFilter;
  24. protected int m_PlayerListFilter;
  25. ref Timer m_Timer;
  26. autoptr array<Man> m_PlayerArray;
  27. const int TIMER_PLAYERLIST = GetPlayerListTimer();
  28. static int GetPlayerListTimer()
  29. {
  30. return 300; // seconds
  31. }
  32. /*
  33. EXE side ADM log messages (not removable):
  34. Connect / Disconnect
  35. Chat
  36. Player->Admin report (ingame chat: #toadmin <text>)
  37. */
  38. void PluginAdminLog()
  39. {
  40. m_HitFilter = GetGame().ServerConfigGetInt("adminLogPlayerHitsOnly"); // 1 - log player hits only / 0 - log all hits ( animals/infected )
  41. m_PlacementFilter = GetGame().ServerConfigGetInt("adminLogPlacement"); // 1 - log placement ( traps, tents )
  42. m_ActionsFilter = GetGame().ServerConfigGetInt("adminLogBuildActions"); // 1 - log basebuilding actions ( build, dismantle, destroy )
  43. m_PlayerListFilter = GetGame().ServerConfigGetInt("adminLogPlayerList"); // 1 - log periodic player list with position every 5 minutes
  44. m_PlayerArray = new array<Man>;
  45. if ( m_PlayerListFilter == 1 )
  46. {
  47. m_Timer = new Timer();
  48. m_Timer.Run( TIMER_PLAYERLIST , this, "PlayerList", NULL, true );
  49. }
  50. }
  51. void ~PluginAdminLog()
  52. {
  53. }
  54. void LogPrint( string message )
  55. {
  56. GetGame().AdminLog( message );
  57. }
  58. string GetPlayerPrefix( PlayerBase player, PlayerIdentity identity ) // player name + id + position prefix for log prints
  59. {
  60. m_Position = player.GetPosition();
  61. m_PosArray[3] = { m_Position[0].ToString(), m_Position[2].ToString(), m_Position[1].ToString() };
  62. for ( int i = 0; i < 3; i++ ) // trim position precision
  63. {
  64. m_DotIndex = m_PosArray[i].IndexOf(".");
  65. if ( m_DotIndex != -1 )
  66. {
  67. m_PosArray[i] = m_PosArray[i].Substring( 0, m_DotIndex + 2 );
  68. }
  69. }
  70. if ( identity ) // return partial message even if it fails to fetch identity
  71. {
  72. //return "Player \"" + "Unknown/Dead Entity" + "\" (id=" + "Unknown" + " pos=<" + m_PosArray[0] + ", " + m_PosArray[1] + ", " + m_PosArray[2] + ">)";
  73. m_PlayerName = "\"" + identity.GetName() + "\"";
  74. m_Pid = identity.GetId();
  75. }
  76. else
  77. {
  78. m_PlayerName = "\"" + player.GetCachedName() + "\"";
  79. m_Pid = player.GetCachedID();
  80. }
  81. if ( !player.IsAlive() )
  82. {
  83. m_PlayerName = m_PlayerName + " (DEAD)";
  84. }
  85. return "Player " + m_PlayerName + " (id=" + m_Pid + " pos=<" + m_PosArray[0] + ", " + m_PosArray[1] + ", " + m_PosArray[2] + ">)";
  86. }
  87. string GetHitMessage( TotalDamageResult damageResult, int component, string zone, string ammo)
  88. {
  89. if ( damageResult )
  90. {
  91. float dmg = damageResult.GetHighestDamage("Health");
  92. return " into " + zone + "(" + component.ToString() + ") for " + dmg.ToString() + " damage (" + ammo + ")";
  93. }
  94. else // block
  95. {
  96. return " into Block" + "(" + component.ToString() + ") for 0 damage ";
  97. }
  98. }
  99. void PlayerKilled( PlayerBase player, Object source ) // PlayerBase.c
  100. {
  101. if (!player || !source)
  102. {
  103. LogPrint("DEBUG: PlayerKilled() player/source does not exist");
  104. return;
  105. }
  106. PlayerBase playerSource = PlayerBase.Cast( EntityAI.Cast( source ).GetHierarchyParent() );
  107. if (!playerSource)
  108. {
  109. playerSource = PlayerBase.Cast( source );
  110. }
  111. string playerPrefix, playerPrefix2;
  112. if (playerSource)
  113. {
  114. playerPrefix2 = GetPlayerPrefix( playerSource , playerSource.GetIdentity() );
  115. }
  116. playerPrefix = GetPlayerPrefix( player , player.GetIdentity() );
  117. if (player == source) // deaths not caused by another object (starvation, dehydration)
  118. {
  119. m_StatWater = player.GetStatWater();
  120. m_StatEnergy = player.GetStatEnergy();
  121. m_BleedMgr = player.GetBleedingManagerServer();
  122. if ( m_StatWater && m_StatEnergy && m_BleedMgr )
  123. {
  124. LogPrint( playerPrefix + " died. Stats> Water: " + m_StatWater.Get().ToString() + " Energy: " + m_StatEnergy.Get().ToString() + " Bleed sources: " + m_BleedMgr.GetBleedingSourcesCount().ToString() );
  125. }
  126. else if ( m_StatWater && m_StatEnergy && !m_BleedMgr )
  127. {
  128. LogPrint( playerPrefix + " died. Stats> Water: " + m_StatWater.Get().ToString() + " Energy: " + m_StatEnergy.Get().ToString() );
  129. }
  130. else
  131. {
  132. LogPrint( playerPrefix + " died. Stats> could not fetch");
  133. }
  134. }
  135. else if (source.IsWeapon() || source.IsMeleeWeapon()) // player
  136. {
  137. if (ExplosivesBase.Cast(source))
  138. {
  139. LogPrint( playerPrefix + " killed by " + source.GetDisplayName() );
  140. }
  141. else if (source.IsMeleeWeapon())
  142. {
  143. LogPrint( playerPrefix + " killed by " + playerPrefix2 + " with " + source.GetDisplayName() );
  144. }
  145. else
  146. {
  147. m_Distance = vector.Distance( player.GetPosition(), playerSource.GetPosition() );
  148. LogPrint( playerPrefix + " killed by " + playerPrefix2 + " with " + source.GetDisplayName() + " from " + m_Distance + " meters " );
  149. }
  150. }
  151. else
  152. {
  153. if (playerSource)
  154. {
  155. //fists
  156. LogPrint( playerPrefix + " killed by " + playerPrefix2 + " with (MeleeFist)" );
  157. }
  158. else
  159. {
  160. //rest, Animals, Zombies
  161. LogPrint( playerPrefix + " killed by " + source.GetType());
  162. }
  163. }
  164. }
  165. void PlayerHitBy( TotalDamageResult damageResult, int damageType, PlayerBase player, EntityAI source, int component, string dmgZone, string ammo ) // PlayerBase.c
  166. {
  167. if ( player && source )
  168. {
  169. string playerPrefix = GetPlayerPrefix( player , player.GetIdentity() ) + "[HP: " + player.GetHealth().ToString() + "]";
  170. string playerPrefix2;
  171. m_HitMessage = GetHitMessage( damageResult, component, dmgZone, ammo );
  172. PlayerBase playerSource;
  173. if ( source.IsPlayer() )// Fists
  174. playerSource = PlayerBase.Cast( source );
  175. else
  176. playerSource = PlayerBase.Cast( source.GetHierarchyParent() );
  177. if (playerSource)
  178. playerPrefix2 = GetPlayerPrefix( playerSource , playerSource.GetIdentity() );
  179. switch ( damageType )
  180. {
  181. case DamageType.CLOSE_COMBAT: // Player melee, animals, infected
  182. if (source.IsZombie() || source.IsAnimal()) // Infected & Animals
  183. {
  184. if (m_HitFilter == 1)
  185. break;
  186. m_DisplayName = source.GetDisplayName();
  187. LogPrint( playerPrefix + " hit by " + m_DisplayName + m_HitMessage );
  188. }
  189. else if (source.IsPlayer())// Fists
  190. {
  191. LogPrint( playerPrefix + " hit by " + playerPrefix2 + m_HitMessage );
  192. }
  193. else if ( playerSource && (source.IsMeleeWeapon() || source.IsWeapon())) // Melee weapons
  194. {
  195. m_ItemInHands = source.GetDisplayName();
  196. LogPrint( playerPrefix + " hit by " + playerPrefix2 + m_HitMessage + " with " + m_ItemInHands );
  197. }
  198. else
  199. {
  200. m_DisplayName = source.GetType();
  201. LogPrint( playerPrefix + " hit by " + m_DisplayName + m_HitMessage );
  202. }
  203. break;
  204. case DamageType.FIRE_ARM: // Player ranged
  205. if ( source.IsWeapon() && playerSource )
  206. {
  207. m_ItemInHands = source.GetDisplayName();
  208. m_Distance = vector.Distance( player.GetPosition(), playerSource.GetPosition() );
  209. LogPrint( playerPrefix + " hit by " + playerPrefix2 + m_HitMessage + " with " + m_ItemInHands + " from " + m_Distance + " meters ");
  210. }
  211. else
  212. {
  213. m_DisplayName = source.GetType();
  214. LogPrint( playerPrefix + " hit by " + m_DisplayName + m_HitMessage );
  215. }
  216. break;
  217. case DamageType.EXPLOSION: // Explosion
  218. LogPrint( playerPrefix + " hit by explosion (" + ammo + ")" );
  219. break;
  220. case DamageType.STUN: // unused atm
  221. LogPrint( playerPrefix + " stunned by " + ammo );
  222. break;
  223. case DamageType.CUSTOM: // Others (Vehicle hit, fall, fireplace, barbed wire ...)
  224. float globalHealthDamage = damageResult.GetDamage("", "Health");
  225. if (ammo == DayZPlayerImplementFallDamage.FALL_DAMAGE_AMMO_HEALTH || ammo == DayZPlayerImplementFallDamage.FALL_DAMAGE_AMMO_SHOCK || ammo == DayZPlayerImplementFallDamage.FALL_DAMAGE_AMMO_HEALTH_OTHER_ATTACHMENTS)
  226. {
  227. if (globalHealthDamage > 0.0)
  228. LogPrint(playerPrefix + " hit by " + ammo);
  229. }
  230. else if ( source.GetType() == "AreaDamageManager" )
  231. {
  232. EntityAI parent = EntityAI.Cast( source );
  233. if ( parent )
  234. {
  235. LogPrint( playerPrefix + " hit by " + parent.GetType() + " with " + ammo );
  236. }
  237. }
  238. else
  239. {
  240. m_DisplayName = source.GetType();
  241. LogPrint( playerPrefix + " hit by " + m_DisplayName + " with " + ammo );
  242. }
  243. break;
  244. default:
  245. LogPrint("DEBUG: PlayerHitBy() unknown damageType: " + ammo );
  246. break;
  247. }
  248. }
  249. else
  250. {
  251. LogPrint("DEBUG: player/source does not exist");
  252. }
  253. }
  254. void UnconStart( PlayerBase player ) // PlayerBase.c
  255. {
  256. m_PlayerPrefix = GetPlayerPrefix( player , player.GetIdentity() );
  257. LogPrint( m_PlayerPrefix + " is unconscious" );
  258. }
  259. void UnconStop( PlayerBase player ) // PlayerBase.c
  260. {
  261. if ( player.IsAlive() ) // Do not log uncon stop for dead players
  262. {
  263. m_PlayerPrefix = GetPlayerPrefix( player , player.GetIdentity() );
  264. LogPrint( m_PlayerPrefix + " regained consciousness" );
  265. }
  266. }
  267. void OnPlacementComplete( Man player, ItemBase item ) // ItemBase.c
  268. {
  269. if ( m_PlacementFilter == 1 )
  270. {
  271. m_Source = PlayerBase.Cast( player );
  272. m_PlayerPrefix = GetPlayerPrefix( m_Source , m_Source.GetIdentity() );
  273. m_DisplayName = item.GetDisplayName();
  274. if ( m_DisplayName == "" )
  275. {
  276. LogPrint( m_PlayerPrefix + " placed unknown object" );
  277. }
  278. else
  279. {
  280. LogPrint( m_PlayerPrefix + " placed " + m_DisplayName );
  281. }
  282. }
  283. }
  284. void OnContinouousAction( ActionData action_data ) // ActionContinouousBase.c
  285. {
  286. if ( m_ActionsFilter == 1 )
  287. {
  288. m_Message = action_data.m_Action.GetAdminLogMessage(action_data);
  289. if(m_Message == "")
  290. return;
  291. m_PlayerPrefix = GetPlayerPrefix( action_data.m_Player , action_data.m_Player.GetIdentity() );
  292. LogPrint( m_PlayerPrefix + m_Message );
  293. }
  294. }
  295. void Suicide( PlayerBase player ) // EmoteManager.c
  296. {
  297. m_PlayerPrefix = GetPlayerPrefix( player , player.GetIdentity() );
  298. LogPrint( m_PlayerPrefix + " committed suicide" );
  299. }
  300. void BleedingOut( PlayerBase player ) // Bleeding.c
  301. {
  302. m_PlayerPrefix = GetPlayerPrefix( player , player.GetIdentity() );
  303. LogPrint( m_PlayerPrefix + " bled out" );
  304. }
  305. //"top" == 'true' for flag all the way at the top, 'false' for all the way at the bottom
  306. void TotemFlagChange(bool top, notnull PlayerBase player, notnull EntityAI totem)
  307. {
  308. if (m_ActionsFilter !=1)
  309. return;
  310. string prefix = GetPlayerPrefix(player, player.GetIdentity());
  311. string flagType = totem.FindAttachmentBySlotName("Material_FPole_Flag").ClassName();
  312. string action;
  313. if (top)
  314. action = "raised ";
  315. else
  316. action = "lowered ";
  317. LogPrint( prefix + " has " + action + flagType + " on " + totem.ClassName() + " at " + totem.GetPosition());
  318. }
  319. void PlayerList()
  320. {
  321. GetGame().GetPlayers( m_PlayerArray );
  322. if ( m_PlayerArray.Count() != 0 )
  323. {
  324. LogPrint( "##### PlayerList log: " + m_PlayerArray.Count().ToString() + " players" );
  325. foreach ( Man player: m_PlayerArray )
  326. {
  327. m_Player = PlayerBase.Cast(player);
  328. m_PlayerPrefix = GetPlayerPrefix( m_Player , m_Player.GetIdentity() );
  329. LogPrint( m_PlayerPrefix );
  330. }
  331. LogPrint( "#####" );
  332. }
  333. }
  334. void PlayerTeleportedLog(notnull PlayerBase player, vector startPos, vector targetPos, string reason)
  335. {
  336. m_PlayerPrefix = GetPlayerPrefix(player, player.GetIdentity());
  337. LogPrint(m_PlayerPrefix + " was teleported from: " + startPos.ToString() + " to: " + targetPos.ToString() + ". Reason: " + reason);
  338. }
  339. void DirectAdminLogPrint(string str)
  340. {
  341. LogPrint(str);
  342. }
  343. }