MoveSpeedChecker.cs 5.6 KB

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