tanghai преди 2 години
родител
ревизия
b7a1dac2d5
променени са 40 файла, в които са добавени 383 реда и са изтрити 133 реда
  1. 1 1
      DotNet/Hotfix/DotNet.Hotfix.csproj
  2. 18 0
      Unity/Assets/Config/Proto/LockStepInner_S_21001.proto
  3. 7 0
      Unity/Assets/Config/Proto/LockStepOuter_C_11001.proto
  4. 4 4
      Unity/Assets/Scripts/Core/Serialize/MongoHelper.cs
  5. 12 0
      Unity/Assets/Scripts/Hotfix/Client/LockStep/G2C_ReconnectHandler.cs
  6. 1 1
      Unity/Assets/Scripts/Hotfix/Client/LockStep/G2C_ReconnectHandler.cs.meta
  7. 0 3
      Unity/Assets/Scripts/Hotfix/Client/LockStep/LSClientHelper.cs
  8. 5 6
      Unity/Assets/Scripts/Hotfix/Client/LockStep/LSClientUpdaterSystem.cs
  9. 22 3
      Unity/Assets/Scripts/Hotfix/Client/LockStep/LSSceneChangeHelper.cs
  10. 4 3
      Unity/Assets/Scripts/Hotfix/Client/LockStep/OneFrameInputsHandler.cs
  11. 1 1
      Unity/Assets/Scripts/Hotfix/Client/Module/Message/NetClientComponentSystem.cs
  12. 39 9
      Unity/Assets/Scripts/Hotfix/Server/Demo/Scenes/Gate/C2G_LoginGateHandler.cs
  13. 16 0
      Unity/Assets/Scripts/Hotfix/Server/Demo/Scenes/Gate/PlayerComponentSystem.cs
  14. 0 1
      Unity/Assets/Scripts/Hotfix/Server/Demo/Scenes/Gate/SessionPlayerComponentSystem.cs
  15. 1 1
      Unity/Assets/Scripts/Hotfix/Server/Demo/Scenes/Realm/C2R_LoginHandler.cs
  16. 4 4
      Unity/Assets/Scripts/Hotfix/Server/Demo/Scenes/Realm/RealmGateAddressHelper.cs
  17. 23 0
      Unity/Assets/Scripts/Hotfix/Server/LockStep/Room/G2Room_ReconnectHandler.cs
  18. 11 0
      Unity/Assets/Scripts/Hotfix/Server/LockStep/Room/G2Room_ReconnectHandler.cs.meta
  19. 0 5
      Unity/Assets/Scripts/Hotfix/Server/LockStep/Room/LSServerUpdaterSystem.cs
  20. 1 1
      Unity/Assets/Scripts/Hotfix/Server/Module/Actor/ActorMessageDispatcherComponentSystem.cs
  21. 1 1
      Unity/Assets/Scripts/Hotfix/Server/Module/Message/NetServerComponentSystem.cs
  22. 0 2
      Unity/Assets/Scripts/Hotfix/Share/LockStep/LSUnitFactory.cs
  23. 13 11
      Unity/Assets/Scripts/Hotfix/Share/LockStep/RoomSystem.cs
  24. 0 31
      Unity/Assets/Scripts/HotfixView/Client/LockStep/LSAfterUnitCreate_CreateUnitFView.cs
  25. 0 2
      Unity/Assets/Scripts/HotfixView/Client/LockStep/LSSceneChangeStart_AddComponent.cs
  26. 2 0
      Unity/Assets/Scripts/HotfixView/Client/LockStep/LSSceneInitFinish_Finish.cs
  27. 29 0
      Unity/Assets/Scripts/HotfixView/Client/LockStep/LSUnitViewComponentSystem.cs
  28. 11 0
      Unity/Assets/Scripts/HotfixView/Client/LockStep/LSUnitViewComponentSystem.cs.meta
  29. 3 2
      Unity/Assets/Scripts/HotfixView/Client/LockStep/LSUnitViewSystem.cs
  30. 0 5
      Unity/Assets/Scripts/Model/Client/LockStep/EventType.cs
  31. 16 0
      Unity/Assets/Scripts/Model/Generate/Client/Message/LockStepOuter_C_11001.cs
  32. 39 0
      Unity/Assets/Scripts/Model/Generate/ClientServer/Message/LockStepInner_S_21001.cs
  33. 16 0
      Unity/Assets/Scripts/Model/Generate/ClientServer/Message/LockStepOuter_C_11001.cs
  34. 39 0
      Unity/Assets/Scripts/Model/Generate/Server/Message/LockStepInner_S_21001.cs
  35. 16 0
      Unity/Assets/Scripts/Model/Generate/Server/Message/LockStepOuter_C_11001.cs
  36. 1 0
      Unity/Assets/Scripts/Model/Server/Demo/Gate/PlayerComponent.cs
  37. 23 32
      Unity/Assets/Scripts/Model/Share/LockStep/FrameBuffer.cs
  38. 1 1
      Unity/Assets/Scripts/Model/Share/LockStep/Room.cs
  39. 2 2
      Unity/Assets/Scripts/Model/Share/Module/Message/OpcodeHelper.cs
  40. 1 1
      Unity/Assets/Scripts/Model/Share/Module/Message/Session.cs

+ 1 - 1
DotNet/Hotfix/DotNet.Hotfix.csproj

@@ -37,7 +37,7 @@
     </ItemGroup>
     <ItemGroup>
         <ProjectReference Include="..\..\Share\Analyzer\Share.Analyzer.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
-        <ProjectReference Include="..\..\Share\Share.SourceGenerator\Share.SourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
+        <ProjectReference Include="..\..\Share\Share.SourceGenerator\Share.SourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
         <ProjectReference Include="..\Loader\DotNet.Loader.csproj" />
         <ProjectReference Include="..\Model\DotNet.Model.csproj" />
     </ItemGroup>

+ 18 - 0
Unity/Assets/Config/Proto/LockStepInner_S_21001.proto

@@ -32,4 +32,22 @@ message Map2Match_GetRoom // IActorResponse
 	
 	// 房间的instanceId
 	int64 InstanceId = 4;
+}
+
+//ResponseType Room2G_Reconnect
+message G2Room_Reconnect // IActorRequest
+{
+	int32 RpcId = 1;
+	int64 PlayerId = 2;
+}
+
+message Room2G_Reconnect // IActorResponse
+{
+	int32 RpcId = 1;
+	int32 Error = 2;
+	string Message = 3;
+
+	int64 StartTime = 4;
+	repeated LockStepUnitInfo UnitInfos = 5;
+	int32 Frame = 6;
 }

+ 7 - 0
Unity/Assets/Config/Proto/LockStepOuter_C_11001.proto

@@ -72,3 +72,10 @@ message Room2C_CheckHashFail // IActorMessage
 	bytes LSWorldBytes = 2;
 }
 
+message G2C_Reconnect // IActorMessage
+{
+	int64 StartTime = 1;
+	repeated LockStepUnitInfo UnitInfos = 2;
+	int32 Frame = 3;
+}
+

+ 4 - 4
Unity/Assets/Scripts/Core/Serialize/MongoHelper.cs

@@ -191,7 +191,7 @@ namespace ET
             }
             catch (Exception e)
             {
-                throw new Exception($"from bson error: {type.Name}", e);
+                throw new Exception($"from bson error: {type.FullName} {bytes.Length}", e);
             }
         }
 
@@ -206,7 +206,7 @@ namespace ET
             }
             catch (Exception e)
             {
-                throw new Exception($"from bson error: {type.Name}", e);
+                throw new Exception($"from bson error: {type.FullName} {bytes.Length} {index} {count}", e);
             }
         }
 
@@ -218,7 +218,7 @@ namespace ET
             }
             catch (Exception e)
             {
-                throw new Exception($"from bson error: {type.Name}", e);
+                throw new Exception($"from bson error: {type.FullName} {stream.Position} {stream.Length}", e);
             }
         }
 
@@ -233,7 +233,7 @@ namespace ET
             }
             catch (Exception e)
             {
-                throw new Exception($"from bson error: {typeof (T).Name}", e);
+                throw new Exception($"from bson error: {typeof (T).FullName} {bytes.Length}", e);
             }
         }
 

+ 12 - 0
Unity/Assets/Scripts/Hotfix/Client/LockStep/G2C_ReconnectHandler.cs

@@ -0,0 +1,12 @@
+namespace ET.Client
+{
+    [MessageHandler(SceneType.LockStep)]
+    public class G2C_ReconnectHandler: AMHandler<G2C_Reconnect>
+    {
+        protected override async ETTask Run(Session session, G2C_Reconnect message)
+        {
+            await LSSceneChangeHelper.SceneChangeToReconnect(session.ClientScene(), message);
+            await ETTask.CompletedTask;
+        }
+    }
+}

+ 1 - 1
Unity/Assets/Scripts/HotfixView/Client/LockStep/LSAfterUnitCreate_CreateUnitFView.cs.meta → Unity/Assets/Scripts/Hotfix/Client/LockStep/G2C_ReconnectHandler.cs.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: d331a561092d14702b60ce62cb54ec42
+guid: 41d6bacdbd4ca1843a732fc0144dc8fb
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2

+ 0 - 3
Unity/Assets/Scripts/Hotfix/Client/LockStep/LSClientHelper.cs

@@ -34,7 +34,6 @@ namespace ET
         // 回滚
         public static void Rollback(Room room, int frame)
         {
-            Log.Debug($"roll back start {frame}");
             room.LSWorld.Dispose();
             FrameBuffer frameBuffer = room.FrameBuffer;
             
@@ -55,8 +54,6 @@ namespace ET
             }
             
             RunRollbackSystem(room);
-            
-            Log.Debug($"roll back finish {frame}");
         }
         
         public static void SendHash(this Room self, int frame)

+ 5 - 6
Unity/Assets/Scripts/Hotfix/Client/LockStep/LSClientUpdaterSystem.cs

@@ -76,14 +76,13 @@ namespace ET.Client
             
             // predict
             OneFrameInputs predictionFrame = frameBuffer.FrameInputs(frame);
-            if (predictionFrame == null)
-            {
-                throw new Exception($"get frame is null: {frame}, max frame: {frameBuffer.MaxFrame}");
-            }
             
             frameBuffer.MoveForward(frame);
-            OneFrameInputs authorityFrame = frameBuffer.FrameInputs(room.AuthorityFrame);
-            authorityFrame?.CopyTo(predictionFrame);
+            if (frameBuffer.CheckFrame(room.AuthorityFrame))
+            {
+                OneFrameInputs authorityFrame = frameBuffer.FrameInputs(room.AuthorityFrame);
+                authorityFrame.CopyTo(predictionFrame);
+            }
             predictionFrame.Inputs[self.MyId] = self.Input;
             
             return predictionFrame;

+ 22 - 3
Unity/Assets/Scripts/Hotfix/Client/LockStep/LSSceneChangeHelper.cs

@@ -37,15 +37,34 @@ namespace ET.Client
             room.Name = "Map1";
             room.IsReplay = true;
             room.Replay = replay;
-
+            room.LSWorld = new LSWorld(SceneType.LockStepClient);
+            room.Init(replay.UnitInfos, TimeHelper.ServerFrameTime());
+            
             // 等待表现层订阅的事件完成
             await EventSystem.Instance.PublishAsync(clientScene, new EventType.LSSceneChangeStart() {Room = room});
             
+
+            room.AddComponent<LSReplayUpdater>();
+            // 这个事件中可以订阅取消loading
+            EventSystem.Instance.Publish(clientScene, new EventType.LSSceneInitFinish());
+        }
+        
+        // 场景切换协程
+        public static async ETTask SceneChangeToReconnect(Scene clientScene, G2C_Reconnect message)
+        {
+            clientScene.RemoveComponent<Room>();
+
+            Room room = clientScene.AddComponent<Room>();
+            room.Name = "Map1";
+            
             room.LSWorld = new LSWorld(SceneType.LockStepClient);
-            room.Init(replay.UnitInfos, TimeHelper.ServerFrameTime());
+            room.Init(message.UnitInfos, message.StartTime, message.Frame);
             
-            room.AddComponent<LSReplayUpdater>();
+            // 等待表现层订阅的事件完成
+            await EventSystem.Instance.PublishAsync(clientScene, new EventType.LSSceneChangeStart() {Room = room});
 
+
+            room.AddComponent<LSClientUpdater>();
             // 这个事件中可以订阅取消loading
             EventSystem.Instance.Publish(clientScene, new EventType.LSSceneInitFinish());
         }

+ 4 - 3
Unity/Assets/Scripts/Hotfix/Client/LockStep/OneFrameInputsHandler.cs

@@ -10,7 +10,7 @@ namespace ET.Client
             Room room = session.DomainScene().GetComponent<Room>();
             
             Log.Debug($"OneFrameInputs: {room.AuthorityFrame + 1} {input.ToJson()}");
-            
+                        
             FrameBuffer frameBuffer = room.FrameBuffer;
 
             ++room.AuthorityFrame;
@@ -22,7 +22,6 @@ namespace ET.Client
             }
             else
             {
-
                 // 服务端返回来的消息,跟预测消息对比
                 OneFrameInputs predictionInput = frameBuffer.FrameInputs(room.AuthorityFrame);
                 // 对比失败有两种可能,
@@ -31,16 +30,18 @@ namespace ET.Client
                 // 回滚重新预测的时候,自己的输入不用变化
                 if (input != predictionInput)
                 {
+                    Log.Debug($"frame diff: {predictionInput} {input}");
                     input.CopyTo(predictionInput);
                     // 回滚到frameBuffer.AuthorityFrame
+                    Log.Debug($"roll back start {room.AuthorityFrame}");
                     LSClientHelper.Rollback(room, room.AuthorityFrame);
+                    Log.Debug($"roll back finish {room.AuthorityFrame}");
                 }
                 else
                 {
                     room.SendHash(room.AuthorityFrame);
                 }
             }
-
             // 回收消息,减少GC
             NetServices.Instance.RecycleMessage(input);
             await ETTask.CompletedTask;

+ 1 - 1
Unity/Assets/Scripts/Hotfix/Client/Module/Message/NetClientComponentSystem.cs

@@ -46,7 +46,7 @@ namespace ET.Client
 
             session.LastRecvTime = TimeHelper.ClientNow();
             
-            OpcodeHelper.LogMsg(self.DomainScene(), message);
+            self.LogMsg(message);
             
             EventSystem.Instance.Publish(Root.Instance.Scene, new NetClientComponentOnRead() {Session = session, Message = message});
         }

+ 39 - 9
Unity/Assets/Scripts/Hotfix/Server/Demo/Scenes/Gate/C2G_LoginGateHandler.cs

@@ -16,23 +16,53 @@ namespace ET.Server
                 response.Message = "Gate key验证失败!";
                 return;
             }
-			
+            
             session.RemoveComponent<SessionAcceptTimeoutComponent>();
 
             PlayerComponent playerComponent = scene.GetComponent<PlayerComponent>();
-            Player player = playerComponent.AddChild<Player, string>(account);
-            PlayerSessionComponent playerSessionComponent = player.AddComponent<PlayerSessionComponent>();
-            playerSessionComponent.Session = session;
-            playerSessionComponent.AddComponent<MailBoxComponent, MailboxType>(MailboxType.GateSession);
-            await playerSessionComponent.AddLocation(LocationType.GateSession);
+            Player player = playerComponent.GetByAccount(account);
+            if (player == null)
+            {
+                player = playerComponent.AddChild<Player, string>(account);
+                playerComponent.Add(player);
+                PlayerSessionComponent playerSessionComponent = player.AddComponent<PlayerSessionComponent>();
+                playerSessionComponent.AddComponent<MailBoxComponent, MailboxType>(MailboxType.GateSession);
+                await playerSessionComponent.AddLocation(LocationType.GateSession);
 			
-            player.AddComponent<MailBoxComponent, MailboxType>(MailboxType.UnOrderMessageDispatcher);
-            await player.AddLocation(LocationType.Player);
+                player.AddComponent<MailBoxComponent, MailboxType>(MailboxType.UnOrderMessageDispatcher);
+                await player.AddLocation(LocationType.Player);
 			
-            session.AddComponent<SessionPlayerComponent>().Player = player;
+                session.AddComponent<SessionPlayerComponent>().Player = player;
+                playerSessionComponent.Session = session;
+            }
+            else
+            {
+                // 判断是否在战斗
+                PlayerRoomComponent playerRoomComponent = player.GetComponent<PlayerRoomComponent>();
+                if (playerRoomComponent.RoomInstanceId != 0)
+                {
+                    CheckRoom(player, session).Coroutine();
+                }
+                else
+                {
+                    PlayerSessionComponent playerSessionComponent = player.GetComponent<PlayerSessionComponent>();
+                    playerSessionComponent.Session = session;
+                }
+            }
 
             response.PlayerId = player.Id;
             await ETTask.CompletedTask;
         }
+
+        private static async ETTask CheckRoom(Player player, Session session)
+        {
+            await Game.WaitFrameFinish();
+            
+            Room2G_Reconnect room2GateReconnect = await ActorMessageSenderComponent.Instance.Call(
+                player.GetComponent<PlayerRoomComponent>().RoomInstanceId,
+                new G2Room_Reconnect() { PlayerId = player.Id }) as Room2G_Reconnect;
+            session.Send(new G2C_Reconnect() { StartTime = room2GateReconnect.StartTime, UnitInfos = room2GateReconnect.UnitInfos, Frame = room2GateReconnect.Frame});
+            player.GetComponent<PlayerSessionComponent>().Session = session;
+        }
     }
 }

+ 16 - 0
Unity/Assets/Scripts/Hotfix/Server/Demo/Scenes/Gate/PlayerComponentSystem.cs

@@ -5,5 +5,21 @@ namespace ET.Server
     [FriendOf(typeof(PlayerComponent))]
     public static class PlayerComponentSystem
     {
+        public static void Add(this PlayerComponent self, Player player)
+        {
+            self.dictionary.Add(player.Account, player);
+        }
+        
+        public static void Remove(this PlayerComponent self, Player player)
+        {
+            self.dictionary.Remove(player.Account);
+            player.Dispose();
+        }
+        
+        public static Player GetByAccount(this PlayerComponent self,  string account)
+        {
+            self.dictionary.TryGetValue(account, out Player player);
+            return player;
+        }
     }
 }

+ 0 - 1
Unity/Assets/Scripts/Hotfix/Server/Demo/Scenes/Gate/SessionPlayerComponentSystem.cs

@@ -10,7 +10,6 @@ namespace ET.Server
 			{
 				// 发送断线消息
 				ActorLocationSenderComponent.Instance?.Get(LocationType.Unit)?.Send(self.Player.Id, new G2M_SessionDisconnect());
-				self.DomainScene().GetComponent<PlayerComponent>()?.RemoveChild(self.Player.Id);
 			}
 		}
 	}

+ 1 - 1
Unity/Assets/Scripts/Hotfix/Server/Demo/Scenes/Realm/C2R_LoginHandler.cs

@@ -10,7 +10,7 @@ namespace ET.Server
 		protected override async ETTask Run(Session session, C2R_Login request, R2C_Login response)
 		{
 			// 随机分配一个Gate
-			StartSceneConfig config = RealmGateAddressHelper.GetGate(session.DomainZone());
+			StartSceneConfig config = RealmGateAddressHelper.GetGate(session.DomainZone(), request.Account);
 			Log.Debug($"gate address: {MongoHelper.ToJson(config)}");
 			
 			// 向gate请求一个key,客户端可以拿着这个key连接gate

+ 4 - 4
Unity/Assets/Scripts/Hotfix/Server/Demo/Scenes/Realm/RealmGateAddressHelper.cs

@@ -5,13 +5,13 @@ namespace ET.Server
 {
 	public static class RealmGateAddressHelper
 	{
-		public static StartSceneConfig GetGate(int zone)
+		public static StartSceneConfig GetGate(int zone, string account)
 		{
+			long hash = account.GetLongHashCode();
+			
 			List<StartSceneConfig> zoneGates = StartSceneConfigCategory.Instance.Gates[zone];
 			
-			int n = RandomGenerator.RandomNumber(0, zoneGates.Count);
-
-			return zoneGates[n];
+			return zoneGates[(int)(hash % zoneGates.Count)];
 		}
 	}
 }

+ 23 - 0
Unity/Assets/Scripts/Hotfix/Server/LockStep/Room/G2Room_ReconnectHandler.cs

@@ -0,0 +1,23 @@
+using System.Collections.Generic;
+
+namespace ET.Server
+{
+    [ActorMessageHandler(SceneType.Room)]
+    public class G2Room_ReconnectHandler: AMActorRpcHandler<Room, G2Room_Reconnect, Room2G_Reconnect>
+    {
+        protected override async ETTask Run(Room room, G2Room_Reconnect request, Room2G_Reconnect response)
+        {
+            response.StartTime = room.StartTime;
+            response.UnitInfos = new List<LockStepUnitInfo>();
+            LSUnitComponent lsUnitComponent = room.LSWorld.GetComponent<LSUnitComponent>();
+            foreach (long playerId in room.PlayerIds)
+            {
+                LSUnit lsUnit = lsUnitComponent.GetChild<LSUnit>(playerId);
+                response.UnitInfos.Add(new LockStepUnitInfo() {PlayerId = playerId, Position = lsUnit.Position, Rotation = lsUnit.Rotation});    
+            }
+
+            response.Frame = room.AuthorityFrame;
+            await ETTask.CompletedTask;
+        }
+    }
+}

+ 11 - 0
Unity/Assets/Scripts/Hotfix/Server/LockStep/Room/G2Room_ReconnectHandler.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f78aa3bd3f95d5d4a9b4178c61599dab
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 0 - 5
Unity/Assets/Scripts/Hotfix/Server/LockStep/Room/LSServerUpdaterSystem.cs

@@ -43,11 +43,6 @@ namespace ET.Server
             Room room = self.GetParent<Room>();
             FrameBuffer frameBuffer = room.FrameBuffer;
             OneFrameInputs oneFrameInputs = frameBuffer.FrameInputs(frame);
-            if (oneFrameInputs == null)
-            {
-                throw new Exception($"get frame is null: {frame}, max frame: {frameBuffer.MaxFrame}");
-            }
-            
             frameBuffer.MoveForward(frame);
             
             if (oneFrameInputs.Inputs.Count == LSConstValue.MatchCount)

+ 1 - 1
Unity/Assets/Scripts/Hotfix/Server/Module/Actor/ActorMessageDispatcherComponentSystem.cs

@@ -132,7 +132,7 @@ namespace ET.Server
                 return;
             }
             
-            OpcodeHelper.LogMsg(entity.DomainScene(), iActorRequest);
+            self.LogMsg(iActorRequest);
 
             MailBoxComponent mailBoxComponent = entity.GetComponent<MailBoxComponent>();
             if (mailBoxComponent == null)

+ 1 - 1
Unity/Assets/Scripts/Hotfix/Server/Module/Message/NetServerComponentSystem.cs

@@ -72,7 +72,7 @@ namespace ET.Server
             }
             session.LastRecvTime = TimeHelper.ClientNow();
             
-            OpcodeHelper.LogMsg(self.DomainScene(), message);
+            self.LogMsg(message);
 			
             EventSystem.Instance.Publish(Root.Instance.Scene, new NetServerComponentOnRead() {Session = session, Message = message});
         }

+ 0 - 2
Unity/Assets/Scripts/Hotfix/Share/LockStep/LSUnitFactory.cs

@@ -11,8 +11,6 @@
 	        lsUnit.Rotation = unitInfo.Rotation;
 
 			lsUnit.AddComponent<LSInputComponent>();
-	        
-	        EventSystem.Instance.Publish(lsUnit.LSWorld(), new EventType.LSAfterUnitCreate() {LsUnit = lsUnit});
             return lsUnit;
         }
     }

+ 13 - 11
Unity/Assets/Scripts/Hotfix/Share/LockStep/RoomSystem.cs

@@ -12,13 +12,16 @@ namespace ET
             return entity.Domain as Room;
         }
         
-        public static void Init(this Room self, List<LockStepUnitInfo> unitInfos, long startTime)
+        public static void Init(this Room self, List<LockStepUnitInfo> unitInfos, long startTime, int frame = -1)
         {
             self.StartTime = startTime;
+            self.AuthorityFrame = frame;
+            self.PredictionFrame = frame;
             self.Replay.UnitInfos = unitInfos;
+            self.FrameBuffer = new FrameBuffer(frame);
             self.FixedTimeCounter = new FixedTimeCounter(self.StartTime, 0, LSConstValue.UpdateInterval);
-
             LSWorld lsWorld = self.LSWorld;
+            lsWorld.Frame = frame + 1;
             lsWorld.AddComponent<LSUnitComponent>();
             for (int i = 0; i < unitInfos.Count; ++i)
             {
@@ -28,18 +31,9 @@ namespace ET
             }
         }
 
-
         public static void Update(this Room self, OneFrameInputs oneFrameInputs)
         {
-            if (!self.IsReplay)
-            {
-                // 保存当前帧场景数据
-                self.SaveLSWorld();
-                self.Record(self.LSWorld.Frame);
-            }
-
             LSWorld lsWorld = self.LSWorld;
-
             // 设置输入到每个LSUnit身上
             LSUnitComponent unitComponent = lsWorld.GetComponent<LSUnitComponent>();
             foreach (var kv in oneFrameInputs.Inputs)
@@ -49,6 +43,13 @@ namespace ET
                 lsInputComponent.LSInput = kv.Value;
             }
             
+            if (!self.IsReplay)
+            {
+                // 保存当前帧场景数据
+                self.SaveLSWorld();
+                self.Record(self.LSWorld.Frame);
+            }
+
             lsWorld.Update();
         }
         
@@ -65,6 +66,7 @@ namespace ET
         public static void SaveLSWorld(this Room self)
         {
             int frame = self.LSWorld.Frame;
+            Log.Debug($"11111111111111111 Save world: {frame}");
             MemoryBuffer memoryBuffer = self.FrameBuffer.Snapshot(frame);
             memoryBuffer.Seek(0, SeekOrigin.Begin);
             memoryBuffer.SetLength(0);

+ 0 - 31
Unity/Assets/Scripts/HotfixView/Client/LockStep/LSAfterUnitCreate_CreateUnitFView.cs

@@ -1,31 +0,0 @@
-using ET.EventType;
-using UnityEngine;
-
-namespace ET.Client
-{
-    [Event(SceneType.LockStepClient)]
-    public class LSAfterUnitCreate_CreateUnitFView: AEvent<LSWorld, LSAfterUnitCreate>
-    {
-        protected override async ETTask Run(LSWorld lsWorld, LSAfterUnitCreate args)
-        {
-            Room room = lsWorld.GetParent<Room>();
-            LSUnitViewComponent lsUnitViewComponent = room.GetComponent<LSUnitViewComponent>();
-
-            if (lsUnitViewComponent == null)
-            {
-                return;
-            }
-            
-            GameObject bundleGameObject = (GameObject)ResourcesComponent.Instance.GetAsset("Unit.unity3d", "Unit");
-            GameObject prefab = bundleGameObject.Get<GameObject>("Skeleton");
-            
-            GameObject go = UnityEngine.Object.Instantiate(prefab, GlobalComponent.Instance.Unit, true);
-            go.transform.position = args.LsUnit.Position.ToVector();
-
-            LSUnitView lsUnitView = lsUnitViewComponent.AddChildWithId<LSUnitView, GameObject>(args.LsUnit.Id, go);
-            lsUnitView.AddComponent<LSAnimatorComponent>();
-
-            await ETTask.CompletedTask;
-        }
-    }
-}

+ 0 - 2
Unity/Assets/Scripts/HotfixView/Client/LockStep/LSSceneChangeStart_AddComponent.cs

@@ -22,8 +22,6 @@ namespace ET.Client
             // 切换到map场景
 
             await SceneManager.LoadSceneAsync(room.Name);
-
-            room.AddComponent<LSUnitViewComponent>();
         }
     }
 }

+ 2 - 0
Unity/Assets/Scripts/HotfixView/Client/LockStep/LSSceneInitFinish_Finish.cs

@@ -7,6 +7,8 @@ namespace ET.Client
         {
             Room room = clientScene.GetComponent<Room>();
             
+            room.AddComponent<LSUnitViewComponent>();
+            
             room.AddComponent<LSCameraComponent>();
 
             if (!room.IsReplay)

+ 29 - 0
Unity/Assets/Scripts/HotfixView/Client/LockStep/LSUnitViewComponentSystem.cs

@@ -0,0 +1,29 @@
+using UnityEngine;
+
+namespace ET.Client
+{
+    public static class LSUnitViewComponentSystem
+    {
+        public class AwakeSystem: AwakeSystem<LSUnitViewComponent>
+        {
+            protected override void Awake(LSUnitViewComponent self)
+            {
+                Room room = self.Room();
+                LSUnitComponent lsUnitComponent = room.LSWorld.GetComponent<LSUnitComponent>();
+                foreach (long playerId in room.PlayerIds)
+                {
+                    LSUnit lsUnit = lsUnitComponent.GetChild<LSUnit>(playerId);
+                    GameObject bundleGameObject = (GameObject)ResourcesComponent.Instance.GetAsset("Unit.unity3d", "Unit");
+                    GameObject prefab = bundleGameObject.Get<GameObject>("Skeleton");
+
+                    GameObject unitGo = UnityEngine.Object.Instantiate(prefab, GlobalComponent.Instance.Unit, true);
+                    unitGo.transform.position = lsUnit.Position.ToVector();
+
+                    LSUnitView lsUnitView = self.AddChildWithId<LSUnitView, GameObject>(lsUnit.Id, unitGo);
+                    lsUnitView.AddComponent<LSAnimatorComponent>();
+                }
+            }
+        }
+
+    }
+}

+ 11 - 0
Unity/Assets/Scripts/HotfixView/Client/LockStep/LSUnitViewComponentSystem.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a60af096c378e164994c0c5da1a9761c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 3 - 2
Unity/Assets/Scripts/HotfixView/Client/LockStep/LSUnitViewSystem.cs

@@ -12,6 +12,7 @@ namespace ET.Client
             {
                 self.GameObject = go;
                 self.Transform = go.transform;
+                
             }
         }
         
@@ -38,7 +39,7 @@ namespace ET.Client
         private static void Update(this LSUnitView self)
         {
             LSUnit unit = self.GetUnit();
-
+            
             Vector3 unitPos = unit.Position.ToVector();
             const float speed = 6f;
             float speed2 = speed;// * self.Room().SpeedMultiply;
@@ -52,6 +53,7 @@ namespace ET.Client
                 self.Rotation = unit.Rotation.ToQuaternion();
             }
             
+            
             LSInput input = unit.GetComponent<LSInputComponent>().LSInput;
             if (input.V != TSVector2.zero)
             {
@@ -61,7 +63,6 @@ namespace ET.Client
             {
                 self.GetComponent<LSAnimatorComponent>().SetFloatValue("Speed", 0);
             }
-
             self.t += Time.deltaTime;
             self.Transform.rotation = Quaternion.Lerp(self.Transform.rotation, self.Rotation, self.t / 1f);
             self.Transform.position = Vector3.Lerp(self.Transform.position, self.Position, self.t / self.totalTime);

+ 0 - 5
Unity/Assets/Scripts/Model/Client/LockStep/EventType.cs

@@ -10,10 +10,5 @@
         public struct LSSceneInitFinish
         {
         }
-
-        public struct LSAfterUnitCreate
-        {
-            public LSUnit LsUnit;
-        }
     }
 }

+ 16 - 0
Unity/Assets/Scripts/Model/Generate/Client/Message/LockStepOuter_C_11001.cs

@@ -140,6 +140,21 @@ namespace ET
 
 	}
 
+	[Message(LockStepOuter.G2C_Reconnect)]
+	[MemoryPackable]
+	public partial class G2C_Reconnect: MessageObject, IActorMessage
+	{
+		[MemoryPackOrder(0)]
+		public long StartTime { get; set; }
+
+		[MemoryPackOrder(1)]
+		public List<LockStepUnitInfo> UnitInfos { get; set; }
+
+		[MemoryPackOrder(2)]
+		public int Frame { get; set; }
+
+	}
+
 	public static class LockStepOuter
 	{
 		 public const ushort C2G_Match = 11002;
@@ -153,5 +168,6 @@ namespace ET
 		 public const ushort Room2C_AdjustUpdateTime = 11010;
 		 public const ushort C2Room_CheckHash = 11011;
 		 public const ushort Room2C_CheckHashFail = 11012;
+		 public const ushort G2C_Reconnect = 11013;
 	}
 }

+ 39 - 0
Unity/Assets/Scripts/Model/Generate/ClientServer/Message/LockStepInner_S_21001.cs

@@ -64,11 +64,50 @@ namespace ET
 
 	}
 
+	[ResponseType(nameof(Room2G_Reconnect))]
+	[Message(LockStepInner.G2Room_Reconnect)]
+	[MemoryPackable]
+	public partial class G2Room_Reconnect: MessageObject, IActorRequest
+	{
+		[MemoryPackOrder(0)]
+		public int RpcId { get; set; }
+
+		[MemoryPackOrder(1)]
+		public long PlayerId { get; set; }
+
+	}
+
+	[Message(LockStepInner.Room2G_Reconnect)]
+	[MemoryPackable]
+	public partial class Room2G_Reconnect: MessageObject, IActorResponse
+	{
+		[MemoryPackOrder(0)]
+		public int RpcId { get; set; }
+
+		[MemoryPackOrder(1)]
+		public int Error { get; set; }
+
+		[MemoryPackOrder(2)]
+		public string Message { get; set; }
+
+		[MemoryPackOrder(3)]
+		public long StartTime { get; set; }
+
+		[MemoryPackOrder(4)]
+		public List<LockStepUnitInfo> UnitInfos { get; set; }
+
+		[MemoryPackOrder(5)]
+		public int Frame { get; set; }
+
+	}
+
 	public static class LockStepInner
 	{
 		 public const ushort G2Match_Match = 21002;
 		 public const ushort Match2G_Match = 21003;
 		 public const ushort Match2Map_GetRoom = 21004;
 		 public const ushort Map2Match_GetRoom = 21005;
+		 public const ushort G2Room_Reconnect = 21006;
+		 public const ushort Room2G_Reconnect = 21007;
 	}
 }

+ 16 - 0
Unity/Assets/Scripts/Model/Generate/ClientServer/Message/LockStepOuter_C_11001.cs

@@ -140,6 +140,21 @@ namespace ET
 
 	}
 
+	[Message(LockStepOuter.G2C_Reconnect)]
+	[MemoryPackable]
+	public partial class G2C_Reconnect: MessageObject, IActorMessage
+	{
+		[MemoryPackOrder(0)]
+		public long StartTime { get; set; }
+
+		[MemoryPackOrder(1)]
+		public List<LockStepUnitInfo> UnitInfos { get; set; }
+
+		[MemoryPackOrder(2)]
+		public int Frame { get; set; }
+
+	}
+
 	public static class LockStepOuter
 	{
 		 public const ushort C2G_Match = 11002;
@@ -153,5 +168,6 @@ namespace ET
 		 public const ushort Room2C_AdjustUpdateTime = 11010;
 		 public const ushort C2Room_CheckHash = 11011;
 		 public const ushort Room2C_CheckHashFail = 11012;
+		 public const ushort G2C_Reconnect = 11013;
 	}
 }

+ 39 - 0
Unity/Assets/Scripts/Model/Generate/Server/Message/LockStepInner_S_21001.cs

@@ -64,11 +64,50 @@ namespace ET
 
 	}
 
+	[ResponseType(nameof(Room2G_Reconnect))]
+	[Message(LockStepInner.G2Room_Reconnect)]
+	[MemoryPackable]
+	public partial class G2Room_Reconnect: MessageObject, IActorRequest
+	{
+		[MemoryPackOrder(0)]
+		public int RpcId { get; set; }
+
+		[MemoryPackOrder(1)]
+		public long PlayerId { get; set; }
+
+	}
+
+	[Message(LockStepInner.Room2G_Reconnect)]
+	[MemoryPackable]
+	public partial class Room2G_Reconnect: MessageObject, IActorResponse
+	{
+		[MemoryPackOrder(0)]
+		public int RpcId { get; set; }
+
+		[MemoryPackOrder(1)]
+		public int Error { get; set; }
+
+		[MemoryPackOrder(2)]
+		public string Message { get; set; }
+
+		[MemoryPackOrder(3)]
+		public long StartTime { get; set; }
+
+		[MemoryPackOrder(4)]
+		public List<LockStepUnitInfo> UnitInfos { get; set; }
+
+		[MemoryPackOrder(5)]
+		public int Frame { get; set; }
+
+	}
+
 	public static class LockStepInner
 	{
 		 public const ushort G2Match_Match = 21002;
 		 public const ushort Match2G_Match = 21003;
 		 public const ushort Match2Map_GetRoom = 21004;
 		 public const ushort Map2Match_GetRoom = 21005;
+		 public const ushort G2Room_Reconnect = 21006;
+		 public const ushort Room2G_Reconnect = 21007;
 	}
 }

+ 16 - 0
Unity/Assets/Scripts/Model/Generate/Server/Message/LockStepOuter_C_11001.cs

@@ -140,6 +140,21 @@ namespace ET
 
 	}
 
+	[Message(LockStepOuter.G2C_Reconnect)]
+	[MemoryPackable]
+	public partial class G2C_Reconnect: MessageObject, IActorMessage
+	{
+		[MemoryPackOrder(0)]
+		public long StartTime { get; set; }
+
+		[MemoryPackOrder(1)]
+		public List<LockStepUnitInfo> UnitInfos { get; set; }
+
+		[MemoryPackOrder(2)]
+		public int Frame { get; set; }
+
+	}
+
 	public static class LockStepOuter
 	{
 		 public const ushort C2G_Match = 11002;
@@ -153,5 +168,6 @@ namespace ET
 		 public const ushort Room2C_AdjustUpdateTime = 11010;
 		 public const ushort C2Room_CheckHash = 11011;
 		 public const ushort Room2C_CheckHashFail = 11012;
+		 public const ushort G2C_Reconnect = 11013;
 	}
 }

+ 1 - 0
Unity/Assets/Scripts/Model/Server/Demo/Gate/PlayerComponent.cs

@@ -6,5 +6,6 @@ namespace ET.Server
 	[ComponentOf(typeof(Scene))]
 	public class PlayerComponent : Entity, IAwake, IDestroy
 	{
+		public Dictionary<string, Player> dictionary = new Dictionary<string, Player>();
 	}
 }

+ 23 - 32
Unity/Assets/Scripts/Model/Share/LockStep/FrameBuffer.cs

@@ -11,9 +11,9 @@ namespace ET
         private readonly List<MemoryBuffer> snapshots;
         private readonly List<long> hashs;
 
-        public FrameBuffer(int capacity = LSConstValue.FrameCountPerSecond * 10)
+        public FrameBuffer(int frame = 0, int capacity = LSConstValue.FrameCountPerSecond * 10)
         {
-            this.MaxFrame = capacity - 1;
+            this.MaxFrame = frame + LSConstValue.FrameCountPerSecond;
             this.frameInputs = new List<OneFrameInputs>(capacity);
             this.snapshots = new List<MemoryBuffer>(capacity);
             this.hashs = new List<long>(capacity);
@@ -31,43 +31,42 @@ namespace ET
 
         public void SetHash(int frame, long hash)
         {
-            if (frame < 0)
-            {
-                return;
-            }
-
-            if (frame > this.MaxFrame)
-            {
-                return;
-            }
+            EnsureFrame(frame);
             this.hashs[frame % this.frameInputs.Capacity] = hash;
         }
         
         public long GetHash(int frame)
+        {
+            EnsureFrame(frame);
+            return this.hashs[frame % this.frameInputs.Capacity];
+        }
+
+        public bool CheckFrame(int frame)
         {
             if (frame < 0)
             {
-                return 0;
+                return false;
             }
 
             if (frame > this.MaxFrame)
             {
-                return 0;
+                return false;
             }
-            return this.hashs[frame % this.frameInputs.Capacity];
+
+            return true;
         }
-        
-        public OneFrameInputs FrameInputs(int frame)
-        {
-            if (frame < 0)
-            {
-                return null;
-            }
 
-            if (frame > this.MaxFrame)
+        private void EnsureFrame(int frame)
+        {
+            if (!CheckFrame(frame))
             {
-                return null;
+                throw new Exception($"frame out: {frame}, maxframe: {frame}");
             }
+        }
+        
+        public OneFrameInputs FrameInputs(int frame)
+        {
+            EnsureFrame(frame);
             OneFrameInputs oneFrameInputs = this.frameInputs[frame % this.frameInputs.Capacity];
             return oneFrameInputs;
         }
@@ -87,15 +86,7 @@ namespace ET
 
         public MemoryBuffer Snapshot(int frame)
         {
-            if (frame < 0)
-            {
-                return null;
-            }
-
-            if (frame > this.MaxFrame)
-            {
-                return null;
-            }
+            EnsureFrame(frame);
             MemoryBuffer memoryBuffer = this.snapshots[frame % this.snapshots.Capacity];
             return memoryBuffer;
         }

+ 1 - 1
Unity/Assets/Scripts/Model/Share/LockStep/Room.cs

@@ -12,7 +12,7 @@ namespace ET
         public long StartTime { get; set; }
 
         // 帧缓存
-        public FrameBuffer FrameBuffer { get; } = new();
+        public FrameBuffer FrameBuffer { get; set; }
 
         // 计算fixedTime,fixedTime在客户端是动态调整的,会做时间膨胀缩放
         public FixedTimeCounter FixedTimeCounter { get; set; }

+ 2 - 2
Unity/Assets/Scripts/Model/Share/Module/Message/OpcodeHelper.cs

@@ -39,7 +39,7 @@ namespace ET
         }
 
         [Conditional("DEBUG")]
-        public static void LogMsg(Scene scene, object message)
+        public static void LogMsg(this Entity entity, object message)
         {
             ushort opcode = NetServices.Instance.GetOpcode(message.GetType());
             if (!IsNeedLogMessage(opcode))
@@ -47,7 +47,7 @@ namespace ET
                 return;
             }
             
-            Logger.Instance.Debug($"{scene.Name} {message}");
+            Logger.Instance.Debug($"{entity.Domain.SceneType} {message}");
         }
     }
 }

+ 1 - 1
Unity/Assets/Scripts/Model/Share/Module/Message/Session.cs

@@ -135,7 +135,7 @@ namespace ET
         public static void Send(this Session self, long actorId, IMessage message)
         {
             self.LastSendTime = TimeHelper.ClientNow();
-            OpcodeHelper.LogMsg(self.DomainScene(), message);
+            self.LogMsg(message);
             NetServices.Instance.SendMessage(self.ServiceId, self.Id, actorId, message as MessageObject);
         }
     }