MoveSpeedChecker.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. using CommonAI;
  2. using CommonAI.RTS;
  3. using CommonAI.Zone;
  4. using CommonAI.Zone.Helper;
  5. using CommonAI.Zone.Instance;
  6. using CommonLang;
  7. using CommonLang.Log;
  8. using CommonLang.Vector;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Linq;
  12. using System.Text;
  13. using XmdsCommonServer.Message;
  14. using XmdsCommonServer.Plugin.Units;
  15. namespace XmdsServerNode.CheatingDeath
  16. {
  17. public class MoveSpeedChecker
  18. {
  19. private static Logger _log;
  20. private static Logger log
  21. {
  22. get { if (_log == null) _log = LoggerFactory.GetLogger("GapChecker"); return _log; }
  23. }
  24. private readonly XmdsInstancePlayer mActor;
  25. private Vector2 mLastPos = new Vector2();
  26. private long mLastCheckTime = CUtils.CurrentTimeMS;
  27. private bool mCheckFlag = false;
  28. public MoveSpeedChecker(InstancePlayer player)
  29. {
  30. this.mActor = player as XmdsInstancePlayer;
  31. this.mActor.OnUpdate += MActor_OnUpdate;
  32. this.mActor.OnObjectSendingEvent += MActor_OnObjectSendingEvent;
  33. this.mActor.OnHandleAction += MActor_OnHandleAction;
  34. this.mActor.OnRemoved += MActor_OnRemoved;
  35. this.mActor.OnRegionTransport += MActor_OnRegionTransport;
  36. this.mLastPos.SetX(mActor.X);
  37. this.mLastPos.SetY(mActor.Y);
  38. }
  39. private void MActor_OnRemoved(InstanceUnit unit)
  40. {
  41. this.mActor.OnUpdate -= MActor_OnUpdate;
  42. this.mActor.OnObjectSendingEvent -= MActor_OnObjectSendingEvent;
  43. this.mActor.OnHandleAction -= MActor_OnHandleAction;
  44. this.mActor.OnRemoved -= MActor_OnRemoved;
  45. this.mActor.OnRegionTransport -= MActor_OnRegionTransport;
  46. }
  47. private void MActor_OnRegionTransport()
  48. {
  49. this.mLastPos.SetX(mActor.X);
  50. this.mLastPos.SetY(mActor.Y);
  51. }
  52. private void MActor_OnHandleAction(InstanceUnit unit, ObjectAction act)
  53. {
  54. if (act is UnitUpdatePosAction)
  55. {
  56. var sync = act as UnitUpdatePosAction;
  57. mCheckFlag = true;
  58. }
  59. }
  60. public void setFrameNotCheckFlag()
  61. {
  62. mCheckFlag = false;
  63. }
  64. private void MActor_OnObjectSendingEvent(InstanceZoneObject obj, ref CommonAI.Zone.ObjectEvent evt)
  65. {
  66. if (evt is UnitForceSyncPosEvent)
  67. {
  68. this.mLastPos.SetX(mActor.X);
  69. this.mLastPos.SetY(mActor.Y);
  70. //Console.WriteLine("UnitForceSyncPosEvent : " + mActor.X + ", " + mActor.Y);
  71. }
  72. }
  73. private void MActor_OnUpdate(InstanceUnit unit)
  74. {
  75. if (!mActor.IsLock)
  76. {
  77. if (mCheckFlag)
  78. {
  79. mCheckFlag = false;
  80. var curtime = CUtils.CurrentTimeMS;
  81. var intervalMS = (int)(curtime - mLastCheckTime);
  82. this.mLastCheckTime = curtime;
  83. //以每次上传坐标的时间间隔来检测,避免客户端包积压,一次发N个包导致的瞬移//
  84. if (CheckCheating(intervalMS))
  85. {
  86. mActor.Lock(CheatingDeathConfig.CHEATER_LOCK_TIME_MS);
  87. CheatingDeathManager.SendPlayerException(mActor, "speed too faster");
  88. }
  89. }
  90. }
  91. else
  92. {
  93. mActor.transport(mLastPos.X, mLastPos.Y);
  94. }
  95. this.mLastPos.SetX(mActor.X);
  96. this.mLastPos.SetY(mActor.Y);
  97. }
  98. //移动偏差累加//
  99. private float over_move_distance = 0;
  100. //移动错误累加//
  101. private float over_move_tick = 0;
  102. protected virtual bool CheckCheating(int intervalMS)
  103. {
  104. if (mActor.CurrentActionStatus == UnitActionStatus.Move)
  105. {
  106. var expectDistance = MoveHelper.GetDistance(intervalMS, mActor.MoveSpeedSEC);
  107. var moveDistance = MathVector.getDistance(mLastPos.X, mLastPos.Y, mActor.X, mActor.Y);
  108. var delta = moveDistance - expectDistance;
  109. //计算预期移动距离和实际移动距离偏差//
  110. over_move_distance += delta;
  111. if (over_move_distance < 0)
  112. {
  113. over_move_distance = 0;
  114. }
  115. else if (over_move_distance > CheatingDeathConfig.TOTAL_EXCEPTION_MOVE_DISTANCE_LIMIT)
  116. {
  117. //位移偏差累加到阀值,错误增加1//
  118. //PrintSpeed(delta, moveDistance, expectDistance);
  119. over_move_distance = 0;
  120. over_move_tick++;
  121. mActor.transport(mLastPos.X, mLastPos.Y);
  122. if (over_move_tick > CheatingDeathConfig.TOTAL_EXCEPTION_COUNT)
  123. {
  124. //累计N次错误,则判定为作弊//
  125. over_move_tick = 0;
  126. return true;
  127. }
  128. }
  129. return false;
  130. }
  131. else
  132. {
  133. var expectDistance = MoveHelper.GetDistance(intervalMS, mActor.MoveSpeedSEC);
  134. over_move_distance -= expectDistance;
  135. if (over_move_distance < 0)
  136. {
  137. over_move_tick = 0;
  138. over_move_distance = 0;
  139. }
  140. return false;
  141. }
  142. }
  143. protected void PrintSpeed(float delta, float moveDistance, float expectDistance)
  144. {
  145. //Console.WriteLine(string.Format("Check move : total={0} delta={1} move_distance={2} expect_distance={3}",
  146. // over_move_distance,
  147. // delta,
  148. // moveDistance,
  149. // expectDistance
  150. // ));
  151. }
  152. }
  153. }