public void RequestSyncClientKeyframes(int frameIdx, PtKeyFrameCollection keyframes) { keyframes.FrameIdx = frameIdx; GameClientNetwork.Instance.SendRequest(PtMessagePackage.Build((int)C2SMessageId.RequestSyncClientKeyframes, new ByteBuffer().WriteBytes(PtKeyFrameCollection.Write(keyframes)) .Getbuffer())); }
void StartRollingSyncMsgThread() { QueueKeyFrameCollection = new ConcurrentQueue <PtKeyFrameCollection>(); ThreadPool.QueueUserWorkItem((state) => { while (true) { DictKeyFrames.Clear(); PtKeyFrameCollection collection = null; while (QueueKeyFrameCollection.TryDequeue(out collection)) { if (!DictKeyFrames.ContainsKey(collection.FrameIdx)) { DictKeyFrames[collection.FrameIdx] = collection; } else { DictKeyFrames[collection.FrameIdx].AddKeyFramesRange(collection); } } foreach (var value in DictKeyFrames.Values) { GameServerNetwork.Instance.Broadcast(PtMessagePackage.Build((int)S2CMessageId.ResponseSyncKeyframes, false, PtKeyFrameCollection.Write(value))); } Thread.Sleep(40); } }); }
/// <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 override void Update() { lock (Entitas.EntityWorld.SyncRoot) { logicBehaviour = Sim.GetBehaviour <LogicFrameBehaviour>(); backupBehaviour = Sim.GetBehaviour <ComponentsBackupBehaviour>(); while (Service.Get <LoginService>().QueueKeyFrameCollection.Count > 0) { PtKeyFrameCollection pt = null; if (Service.Get <LoginService>().QueueKeyFrameCollection.TryPeek(out pt) && pt.FrameIdx < logicBehaviour.CurrentFrameIdx) { PtKeyFrameCollection keyframeCollection = null; if (Service.Get <LoginService>().QueueKeyFrameCollection.TryDequeue(out keyframeCollection)) { RollImpl(keyframeCollection); } else { break; } //DebugFrameIdx = string.Format("{0} CollectionFrameIdx:{1}", logicBehaviour.CurrentFrameIdx, keyframeCollection.FrameIdx); } else { break; } } } }
void SendKeyFrame(int idx) { PtKeyFrameCollection collection = KeyFrameSender.GetFrameCommand(); if (collection.KeyFrames.Count > 0) { Service.Get <LoginService>().RequestSyncClientKeyframes(idx, collection); KeyFrameSender.ClearFrameCommand(); } }
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); } } } } }
void OnResponseSyncKeyframes(Notification note) { ByteBuffer buff = new ByteBuffer(note.GetBytes()); PtKeyFrameCollection collection = PtKeyFrameCollection.Read(buff.ReadBytes()); QueueKeyFrameCollection.Enqueue(collection); KeyframesCount++; AllFramesCount += collection.KeyFrames.Count; //Debug.Log(string.Format("[client receive] frameIdx:{0}", collection.FrameIdx)); }
public override void Update() { lock (Entitas.EntityWorld.SyncRoot) { logicBehaviour = Sim.GetBehaviour <LogicFrameBehaviour>(); backupBehaviour = Sim.GetBehaviour <ComponentsBackupBehaviour>(); int count = 0; while (MgobeHelper.QueueKeyFrameCollection.Count > 0) { count++; if (count > MaxCount) { break; } PtKeyFrameCollection pt = null; if (MgobeHelper.QueueKeyFrameCollection.TryPeek(out pt)) { PtKeyFrameCollection keyframeCollection = null; if (pt.FrameIdx < logicBehaviour.CurrentFrameIdx) { if (MgobeHelper.QueueKeyFrameCollection.TryDequeue(out keyframeCollection)) { RollImpl(keyframeCollection); } else { break; } } else if (pt.FrameIdx > logicBehaviour.CurrentFrameIdx) { if (MgobeHelper.QueueKeyFrameCollection.TryDequeue(out keyframeCollection)) { QuickImpl(keyframeCollection); } else { break; } } } else { break; } } } }
internal void FlushKeyFrame(int currentFrameIdx) { //StartRollingSyncMsgThread(); PtKeyFrameCollection collection = null; while (QueueKeyFrameCollection.TryDequeue(out collection)) { collection.FrameIdx = currentFrameIdx; collection.KeyFrames.ForEach((e) => { e.Idx = currentFrameIdx; }); GameServerNetwork.Instance.Broadcast(PtMessagePackage.Build((int)S2CMessageId.ResponseSyncKeyframes, true, PtKeyFrameCollection.Write(collection))); } }
void OnRequestSyncClientKeyframes(Notification note) { int serverFrameIdx = SimulationManager.Instance.GetSimulation(Const.SERVER_SIMULATION_ID).GetBehaviour <ServerLogicFrameBehaviour>().CurrentFrameIdx; Message msg = note.GetMessage(); ByteBuffer buffer = new ByteBuffer(note.GetBytes()); PtKeyFrameCollection collection = PtKeyFrameCollection.Read(buffer.ReadBytes()); foreach (var item in collection.KeyFrames) { item.Idx = serverFrameIdx; } collection.FrameIdx = serverFrameIdx; QueueKeyFrameCollection.Enqueue(collection); //GameServerNetwork.Instance.Broadcast(PtMessagePackage.Build((int)S2CMessageId.ResponseSyncKeyframes, // new ByteBuffer().WriteBytes(PtKeyFrameCollection.Write(collection)).Getbuffer(),false)); }
/// <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); } }
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); }