OneFrameInputsHandler.cs 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. using System;
  2. namespace ET.Client
  3. {
  4. public static partial class OneFrameInputsHandler
  5. {
  6. [MessageHandler(SceneType.LockStep)]
  7. private static async ETTask Run(Session session, OneFrameInputs input)
  8. {
  9. Room room = session.DomainScene().GetComponent<Room>();
  10. Log.Debug($"OneFrameInputs: {room.AuthorityFrame + 1} {input.ToJson()}");
  11. FrameBuffer frameBuffer = room.FrameBuffer;
  12. ++room.AuthorityFrame;
  13. // 服务端返回的消息比预测的还早
  14. if (room.AuthorityFrame > room.PredictionFrame)
  15. {
  16. OneFrameInputs authorityFrame = frameBuffer.FrameInputs(room.AuthorityFrame);
  17. input.CopyTo(authorityFrame);
  18. }
  19. else
  20. {
  21. // 服务端返回来的消息,跟预测消息对比
  22. OneFrameInputs predictionInput = frameBuffer.FrameInputs(room.AuthorityFrame);
  23. // 对比失败有两种可能,
  24. // 1是别人的输入预测失败,这种很正常,
  25. // 2 自己的输入对比失败,这种情况是自己发送的消息比服务器晚到了,服务器使用了你的上一次输入
  26. // 回滚重新预测的时候,自己的输入不用变化
  27. if (input != predictionInput)
  28. {
  29. Log.Debug($"frame diff: {predictionInput} {input}");
  30. input.CopyTo(predictionInput);
  31. // 回滚到frameBuffer.AuthorityFrame
  32. Log.Debug($"roll back start {room.AuthorityFrame}");
  33. LSClientHelper.Rollback(room, room.AuthorityFrame);
  34. Log.Debug($"roll back finish {room.AuthorityFrame}");
  35. }
  36. else
  37. {
  38. room.SendHash(room.AuthorityFrame);
  39. }
  40. }
  41. // 回收消息,减少GC
  42. NetServices.Instance.RecycleMessage(input);
  43. await ETTask.CompletedTask;
  44. }
  45. }
  46. }