pluginadminlog.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  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. string reason = " died.";
  123. if (player.GetDrowningWaterLevelCheck())
  124. reason = " drowned.";
  125. string additionalStats;
  126. if (m_StatWater && m_StatEnergy)
  127. additionalStats = " Stats> Water: " + m_StatWater.Get().ToString() + " Energy: " + m_StatEnergy.Get().ToString();
  128. if (m_BleedMgr)
  129. additionalStats = additionalStats + " Bleed sources: " + m_BleedMgr.GetBleedingSourcesCount().ToString();
  130. LogPrint(playerPrefix + reason + additionalStats);
  131. }
  132. else if (source.IsWeapon() || source.IsMeleeWeapon()) // player
  133. {
  134. if (ExplosivesBase.Cast(source))
  135. {
  136. LogPrint( playerPrefix + " killed by " + source.GetDisplayName() );
  137. }
  138. else if (source.IsMeleeWeapon())
  139. {
  140. LogPrint( playerPrefix + " killed by " + playerPrefix2 + " with " + source.GetDisplayName() );
  141. }
  142. else
  143. {
  144. m_Distance = vector.Distance( player.GetPosition(), playerSource.GetPosition() );
  145. LogPrint( playerPrefix + " killed by " + playerPrefix2 + " with " + source.GetDisplayName() + " from " + m_Distance + " meters " );
  146. }
  147. }
  148. else
  149. {
  150. if (playerSource)
  151. {
  152. //fists
  153. LogPrint( playerPrefix + " killed by " + playerPrefix2 + " with (MeleeFist)" );
  154. }
  155. else
  156. {
  157. //rest, Animals, Zombies
  158. LogPrint( playerPrefix + " killed by " + source.GetType());
  159. }
  160. }
  161. }
  162. void PlayerKilledByDrowningUncon(PlayerBase player)
  163. {
  164. string playerPrefix = GetPlayerPrefix( player , player.GetIdentity() );
  165. LogPrint( playerPrefix + " has drowned while unconscious" );
  166. }
  167. void PlayerKilledByRespawn(PlayerBase player)
  168. {
  169. string playerPrefix = GetPlayerPrefix( player , player.GetIdentity() );
  170. LogPrint( playerPrefix + " is choosing to respawn" );
  171. }
  172. void PlayerKilledByDisconnect(PlayerBase player)
  173. {
  174. string playerPrefix = GetPlayerPrefix( player , player.GetIdentity() );
  175. if (player.IsUnconscious())
  176. LogPrint( playerPrefix + " is disconnecting while being unconscious" );
  177. else if (player.IsRestrained())
  178. LogPrint( playerPrefix + " is disconnecting while being restrained" );
  179. }
  180. void PlayerHitBy( TotalDamageResult damageResult, int damageType, PlayerBase player, EntityAI source, int component, string dmgZone, string ammo ) // PlayerBase.c
  181. {
  182. if ( player && source )
  183. {
  184. string playerPrefix = GetPlayerPrefix( player , player.GetIdentity() ) + "[HP: " + player.GetHealth().ToString() + "]";
  185. string playerPrefix2;
  186. m_HitMessage = GetHitMessage( damageResult, component, dmgZone, ammo );
  187. PlayerBase playerSource;
  188. if ( source.IsPlayer() )// Fists
  189. playerSource = PlayerBase.Cast( source );
  190. else
  191. playerSource = PlayerBase.Cast( source.GetHierarchyParent() );
  192. if (playerSource)
  193. playerPrefix2 = GetPlayerPrefix( playerSource , playerSource.GetIdentity() );
  194. switch ( damageType )
  195. {
  196. case DamageType.CLOSE_COMBAT: // Player melee, animals, infected
  197. if (source.IsZombie() || source.IsAnimal()) // Infected & Animals
  198. {
  199. if (m_HitFilter == 1)
  200. break;
  201. m_DisplayName = source.GetDisplayName();
  202. LogPrint( playerPrefix + " hit by " + m_DisplayName + m_HitMessage );
  203. }
  204. else if (source.IsPlayer())// Fists
  205. {
  206. LogPrint( playerPrefix + " hit by " + playerPrefix2 + m_HitMessage );
  207. }
  208. else if ( playerSource && (source.IsMeleeWeapon() || source.IsWeapon())) // Melee weapons
  209. {
  210. m_ItemInHands = source.GetDisplayName();
  211. LogPrint( playerPrefix + " hit by " + playerPrefix2 + m_HitMessage + " with " + m_ItemInHands );
  212. }
  213. else
  214. {
  215. m_DisplayName = source.GetType();
  216. LogPrint( playerPrefix + " hit by " + m_DisplayName + m_HitMessage );
  217. }
  218. break;
  219. case DamageType.FIRE_ARM: // Player ranged
  220. if ( source.IsWeapon() && playerSource )
  221. {
  222. m_ItemInHands = source.GetDisplayName();
  223. m_Distance = vector.Distance( player.GetPosition(), playerSource.GetPosition() );
  224. LogPrint( playerPrefix + " hit by " + playerPrefix2 + m_HitMessage + " with " + m_ItemInHands + " from " + m_Distance + " meters ");
  225. }
  226. else
  227. {
  228. m_DisplayName = source.GetType();
  229. LogPrint( playerPrefix + " hit by " + m_DisplayName + m_HitMessage );
  230. }
  231. break;
  232. case DamageType.EXPLOSION: // Explosion
  233. LogPrint( playerPrefix + " hit by explosion (" + ammo + ")" );
  234. break;
  235. case DamageType.STUN: // unused atm
  236. LogPrint( playerPrefix + " stunned by " + ammo );
  237. break;
  238. case DamageType.CUSTOM: // Others (Vehicle hit, fall, fireplace, barbed wire ...)
  239. float globalHealthDamage = damageResult.GetDamage("", "Health");
  240. if (ammo == DayZPlayerImplementFallDamage.FALL_DAMAGE_AMMO_HEALTH || ammo == DayZPlayerImplementFallDamage.FALL_DAMAGE_AMMO_SHOCK || ammo == DayZPlayerImplementFallDamage.FALL_DAMAGE_AMMO_HEALTH_OTHER_ATTACHMENTS)
  241. {
  242. if (globalHealthDamage > 0.0)
  243. LogPrint(playerPrefix + " hit by " + ammo);
  244. }
  245. else if ( source.GetType() == "AreaDamageManager" )
  246. {
  247. EntityAI parent = EntityAI.Cast( source );
  248. if ( parent )
  249. {
  250. LogPrint( playerPrefix + " hit by " + parent.GetType() + " with " + ammo );
  251. }
  252. }
  253. else
  254. {
  255. m_DisplayName = source.GetType();
  256. LogPrint( playerPrefix + " hit by " + m_DisplayName + " with " + ammo );
  257. }
  258. break;
  259. default:
  260. LogPrint("DEBUG: PlayerHitBy() unknown damageType: " + ammo );
  261. break;
  262. }
  263. }
  264. else
  265. {
  266. LogPrint("DEBUG: player/source does not exist");
  267. }
  268. }
  269. void UnconStart( PlayerBase player ) // PlayerBase.c
  270. {
  271. m_PlayerPrefix = GetPlayerPrefix( player , player.GetIdentity() );
  272. LogPrint( m_PlayerPrefix + " is unconscious" );
  273. }
  274. void UnconStop( PlayerBase player ) // PlayerBase.c
  275. {
  276. if ( player.IsAlive() ) // Do not log uncon stop for dead players
  277. {
  278. m_PlayerPrefix = GetPlayerPrefix( player , player.GetIdentity() );
  279. LogPrint( m_PlayerPrefix + " regained consciousness" );
  280. }
  281. }
  282. void OnPlacementComplete( Man player, ItemBase item ) // ItemBase.c
  283. {
  284. if ( m_PlacementFilter == 1 )
  285. {
  286. m_Source = PlayerBase.Cast( player );
  287. m_PlayerPrefix = GetPlayerPrefix( m_Source , m_Source.GetIdentity() );
  288. m_DisplayName = item.GetDisplayName();
  289. if ( m_DisplayName == "" )
  290. {
  291. LogPrint( m_PlayerPrefix + " placed Nameless Object" + "<" + item.GetType() + ">" );
  292. }
  293. else
  294. {
  295. LogPrint( m_PlayerPrefix + " placed " + m_DisplayName + "<" + item.GetType() + ">");
  296. }
  297. }
  298. }
  299. void OnContinouousAction( ActionData action_data ) // ActionContinouousBase.c
  300. {
  301. if ( m_ActionsFilter == 1 )
  302. {
  303. m_Message = action_data.m_Action.GetAdminLogMessage(action_data);
  304. if(m_Message == "")
  305. return;
  306. m_PlayerPrefix = GetPlayerPrefix( action_data.m_Player , action_data.m_Player.GetIdentity() );
  307. LogPrint( m_PlayerPrefix + m_Message );
  308. }
  309. }
  310. void OnEmote(PlayerBase player, EmoteBase emote)
  311. {
  312. m_PlayerPrefix = GetPlayerPrefix( player , player.GetIdentity() );
  313. ItemBase item = player.GetItemInHands();
  314. if (item)
  315. LogPrint(m_PlayerPrefix + " performed " + emote.GetInputActionName() + " with " + item.GetType());
  316. else
  317. LogPrint(m_PlayerPrefix + " performed " + emote.GetInputActionName());
  318. }
  319. void Suicide( PlayerBase player ) // EmoteManager.c
  320. {
  321. m_PlayerPrefix = GetPlayerPrefix( player , player.GetIdentity() );
  322. LogPrint( m_PlayerPrefix + " committed suicide" );
  323. }
  324. void BleedingOut( PlayerBase player ) // Bleeding.c
  325. {
  326. m_PlayerPrefix = GetPlayerPrefix( player , player.GetIdentity() );
  327. LogPrint( m_PlayerPrefix + " bled out" );
  328. }
  329. //"top" == 'true' for flag all the way at the top, 'false' for all the way at the bottom
  330. void TotemFlagChange(bool top, notnull PlayerBase player, notnull EntityAI totem)
  331. {
  332. if (m_ActionsFilter !=1)
  333. return;
  334. string prefix = GetPlayerPrefix(player, player.GetIdentity());
  335. string flagType = totem.FindAttachmentBySlotName("Material_FPole_Flag").ClassName();
  336. string action;
  337. if (top)
  338. action = "raised ";
  339. else
  340. action = "lowered ";
  341. LogPrint( prefix + " has " + action + flagType + " on " + totem.ClassName() + " at " + totem.GetPosition());
  342. }
  343. void PlayerList()
  344. {
  345. GetGame().GetPlayers( m_PlayerArray );
  346. if ( m_PlayerArray.Count() != 0 )
  347. {
  348. LogPrint( "##### PlayerList log: " + m_PlayerArray.Count().ToString() + " players" );
  349. foreach ( Man player: m_PlayerArray )
  350. {
  351. m_Player = PlayerBase.Cast(player);
  352. m_PlayerPrefix = GetPlayerPrefix( m_Player , m_Player.GetIdentity() );
  353. LogPrint( m_PlayerPrefix );
  354. }
  355. LogPrint( "#####" );
  356. }
  357. }
  358. void PlayerTeleportedLog(notnull PlayerBase player, vector startPos, vector targetPos, string reason)
  359. {
  360. m_PlayerPrefix = GetPlayerPrefix(player, player.GetIdentity());
  361. LogPrint(m_PlayerPrefix + " was teleported from: " + startPos.ToString() + " to: " + targetPos.ToString() + ". Reason: " + reason);
  362. }
  363. void DirectAdminLogPrint(string str)
  364. {
  365. LogPrint(str);
  366. }
  367. }