/// <summary> /// 回滚关键帧数据 /// </summary> /// <param name="collection"></param> void RollImpl(PtKeyFrameCollection collection) { int frameIdx = collection.FrameIdx; if (frameIdx < 1) { return; } collection.KeyFrames.Sort((a, b) => new System.Guid(a.EntityId).CompareTo(new System.Guid(b.EntityId))); //回放命令存储; foreach (var frame in collection.KeyFrames) { logicBehaviour.UpdateKeyFrameIdxInfoAtFrameIdx(collection.FrameIdx, frame); } //从frameIdx-1数据中深度拷贝一份作为frameIdx的数据 EntityWorldFrameData framePrevData = backupBehaviour.GetEntityWorldFrameByFrameIdx(frameIdx - 1); if (framePrevData != null) { //回滚整个entityworld数据 Sim.GetEntityWorld().RollBack(framePrevData.Clone(), collection); //迅速从frameIdx开始模拟至当前客户端frameIdx while (frameIdx < logicBehaviour.CurrentFrameIdx) { base.Update(); backupBehaviour.SetEntityWorldFrameByFrameIdx(frameIdx, new EntityWorldFrameData(Sim.GetEntityWorld().FindAllEntitiesIds(), Sim.GetEntityWorld().FindAllCloneComponents())); ++frameIdx; } } }
public void RollBack(EntityWorldFrameData data, PtKeyFrameCollection collection) { Reset(); foreach (Guid entityId in data.EntityIds) { Entity entity = AddEntity(entityId); foreach (IComponent com in data.Components) { if (com.EntityId == entityId) { if (collection != null) { foreach (FrameIdxInfo info in collection.KeyFrames) { if (info.EqualsInfo(com)) { IParamsUpdatable updatableCom = com as IParamsUpdatable; if (updatableCom != null) { updatableCom.UpdateParams(info.Params); } else { throw new Exception("Component " + com.ToString() + " must be IParamsUpdatable"); } break; } } } entity.AddComponent(com); } } } ; if (collection != null) { foreach (FrameIdxInfo info in collection.KeyFrames) { if (!ContainEntity(info.EntityId)) { if (info.Cmd == FrameCommand.SYNC_CREATE_ENTITY) { NotifyCreateEntity(info); } } else { if (info.Cmd == FrameCommand.SYNC_REMOVE_ENTITY) { NotifyRemoveEntity(info.EntityId); } } } } }
public void SetEntityWorldFrameByFrameIdx(int frameIdx, EntityWorldFrameData data) { QueueFrameCache.Enqueue(frameIdx); if (m_DictEntityWorldFrameData.ContainsKey(frameIdx)) { m_DictEntityWorldFrameData[frameIdx].Clear(); } m_DictEntityWorldFrameData[frameIdx] = data; //while(QueueFrameCache.Count>100) //{ // int fid = QueueFrameCache.Dequeue(); // if (m_DictEntityWorldFrameData.ContainsKey(fid)) // m_DictEntityWorldFrameData.Remove(fid); //} }
/// <summary> /// 追赶帧 /// </summary> /// <param name="collection"></param> void QuickImpl(PtKeyFrameCollection collection) { int frameIdx = collection.FrameIdx; while (frameIdx > logicBehaviour.CurrentFrameIdx) { this.IsActive = false; Sim.Run(); } this.IsActive = true; EntityWorldFrameData framePrevData = backupBehaviour.GetEntityWorldFrameByFrameIdx(frameIdx); if (framePrevData != null) { Sim.GetEntityWorld().RollBack(framePrevData.Clone(), collection); } }
public static string Write(Dictionary <int, EntityWorldFrameData> dict, long roleId) { string log = "[GameEntityInfoLog--RoleId]" + roleId + "\n"; var keys = dict.Keys; List <int> keysList = new List <int>(); foreach (int k in keys) { keysList.Add(k); } keysList.Sort((a, b) => a - b); foreach (int key in keysList) { EntityWorldFrameData data = dict[key]; log += string.Format("FrameIdx:{0} Data:{1}", key, data.ToString()) + "\n\n"; } return(log); }
private void OnClientMsg(object[] args) { string playerId = args[0] as string; string msg = args[1] as string; var msgList = ListCache <string> .Acquire(); msgList.AddRange(msg.Split('|')); var msgType = msgList[0]; switch (msgType) { case (ClientMsgType.ReConnect): StringBuilder sb = new StringBuilder(); sb.Append(ClientMsgType.ReConnectRsp); sb.Append("|"); sb.Append(GetTimeStamp()); sb.Append("|"); var sim = SimulationManager.Instance.GetSimulation(Const.CLIENT_SIMULATION_ID); var frameDatas = sim.GetBehaviour <ComponentsBackupBehaviour>().GetEntityWorldFrameData(); var frameIdx = sim.GetBehaviour <LogicFrameBehaviour>().CurrentFrameIdx; sb.Append(frameIdx); sb.Append("|"); var frameData = frameDatas[frameIdx]; sb.Append(EntityWorldFrameData.Serilize(frameData)); sb.Append("|"); var arrKF = MgobeHelper.QueueKeyFrameCollection.ToArray(); if (arrKF.Length > 0) { for (int i = 0; i < arrKF.Length; i++) { if (i > 0) { sb.Append("&"); } sb.Append(Encoding.UTF8.GetString(PtKeyFrameCollection.Write(arrKF[i]))); } } var list = new List <string>() { playerId }; MgobeHelper.SendToClient(list, RecvType.RoomSome, sb.ToString()); break; case (ClientMsgType.ReConnectRsp): var idx = msgList[1]; var timestamp = ulong.Parse(msgList[2]); var frameStr = msgList[3]; var kfStr = msgList[4]; var entData = EntityWorldFrameData.DeSerilize(frameStr); var queueKeyFrameCollection = new ConcurrentQueue <PtKeyFrameCollection>(); if (!string.IsNullOrEmpty(kfStr)) { var kfStrs = kfStr.Split('&'); for (int i = 0; i < kfStrs.Length; i++) { queueKeyFrameCollection.Enqueue(PtKeyFrameCollection.Read(Encoding.UTF8.GetBytes(kfStrs[i]))); } } MgobeHelper.QueueKeyFrameCollection = queueKeyFrameCollection; OnAddClient(); var sim2 = SimulationManager.Instance.GetSimulation(Const.CLIENT_SIMULATION_ID); sim2.GetBehaviour <LogicFrameBehaviour>().CurrentFrameIdx = int.Parse(idx); sim2.GetEntityWorld().RollBack(entData, null); OnAllReady(null); SimulationManager.Instance.Start(timestamp); break; default: break; } ListCache <string> .Release(msgList); }