using System; using System.Collections.Generic; using System.IO; namespace ET { [FriendOf(typeof(Room))] public static partial class RoomSystem { public static Room Room(this Entity entity) { return entity.IScene as Room; } public static void Init(this Room self, List 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(); for (int i = 0; i < unitInfos.Count; ++i) { LockStepUnitInfo unitInfo = unitInfos[i]; LSUnitFactory.Init(lsWorld, unitInfo); self.PlayerIds.Add(unitInfo.PlayerId); } } public static void Update(this Room self, OneFrameInputs oneFrameInputs) { LSWorld lsWorld = self.LSWorld; // 设置输入到每个LSUnit身上 LSUnitComponent unitComponent = lsWorld.GetComponent(); foreach (var kv in oneFrameInputs.Inputs) { LSUnit lsUnit = unitComponent.GetChild(kv.Key); LSInputComponent lsInputComponent = lsUnit.GetComponent(); lsInputComponent.LSInput = kv.Value; } if (!self.IsReplay) { // 保存当前帧场景数据 self.SaveLSWorld(); self.Record(self.LSWorld.Frame); } lsWorld.Update(); } public static LSWorld GetLSWorld(this Room self, SceneType sceneType, int frame) { MemoryBuffer memoryBuffer = self.FrameBuffer.Snapshot(frame); memoryBuffer.Seek(0, SeekOrigin.Begin); LSWorld lsWorld = MongoHelper.Deserialize(typeof (LSWorld), memoryBuffer) as LSWorld; lsWorld.SceneType = sceneType; memoryBuffer.Seek(0, SeekOrigin.Begin); return lsWorld; } private static void SaveLSWorld(this Room self) { int frame = self.LSWorld.Frame; MemoryBuffer memoryBuffer = self.FrameBuffer.Snapshot(frame); memoryBuffer.Seek(0, SeekOrigin.Begin); memoryBuffer.SetLength(0); MongoHelper.Serialize(self.LSWorld, memoryBuffer); memoryBuffer.Seek(0, SeekOrigin.Begin); long hash = memoryBuffer.GetBuffer().Hash(0, (int) memoryBuffer.Length); self.FrameBuffer.SetHash(frame, hash); } // 记录需要存档的数据 public static void Record(this Room self, int frame) { if (frame > self.AuthorityFrame) { return; } OneFrameInputs oneFrameInputs = self.FrameBuffer.FrameInputs(frame); OneFrameInputs saveInput = new(); oneFrameInputs.CopyTo(saveInput); self.Replay.FrameInputs.Add(saveInput); if (frame % LSConstValue.SaveLSWorldFrameCount == 0) { MemoryBuffer memoryBuffer = self.FrameBuffer.Snapshot(frame); byte[] bytes = memoryBuffer.ToArray(); self.Replay.Snapshots.Add(bytes); } } } }