OneFrameInputsHandler.cs 2.1 KB

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