/// <summary> /// 这里比较的是通过客户端的缓存还原出来的和服务器时间对应的过去状态和当前服务器状态的比较 /// 这里只能确认当前演播环境需不需要回滚,但是并不能得到演播环境应该如何回滚,只有演播环境自己才能做自己的回滚 /// </summary> /// <param name="clientState"></param> /// <returns></returns> private bool NeedRollBack(ClientWorldState clientState) { _tmpGameContext.Reset(); clientState.Buffer.Reset(); UnpackEntityUtility.CreateEntities(_tmpGameContext, clientState.Buffer, clientState.EntityCount); #region Movers var moverMatcher = GameMatcher.Mover; string TakeMoverIdMethod(GameEntity e) { return(e.moverID.value); } if (!SameEntices(moverMatcher, TakeMoverIdMethod, _backGameContext, _tmpGameContext)) { return(true); } #endregion #region Ice var iceMatcher = GameMatcher.Ice; string TakeIceOwnerMethod(GameEntity e) { return(e.ice.Owner); } return(!SameEntices(iceMatcher, TakeIceOwnerMethod, _backGameContext, _tmpGameContext)); #endregion }
private unsafe void ExecuteState(IntPtr state) { PackedDataFlags flags; int cursor; if (_firstPacket) { _firstPacket = false; flags = PackedDataFlags.Commands | PackedDataFlags.CreatedEntities; cursor = 0; } else { flags = (PackedDataFlags)Marshal.ReadByte(state); cursor = 1; } #region commands if ((flags & PackedDataFlags.Commands) == PackedDataFlags.Commands) { var commandsHeaderSpan = new ReadOnlySpan <ushort>(IntPtr.Add(state, cursor).ToPointer(), 2); var commandCount = commandsHeaderSpan[0]; var commandLength = commandsHeaderSpan[1]; cursor += 4; if (commandCount > 0) { var dataSpan = new ReadOnlySpan <byte>(IntPtr.Add(state, cursor).ToPointer(), commandLength); _fromServer.Clear(); _fromServer.FromSpan(ref dataSpan, commandLength); ClientCommandExecutor.Execute(_handler, _fromServer, commandCount); cursor += commandLength; } } #endregion #region created entities if ((flags & PackedDataFlags.CreatedEntities) == PackedDataFlags.CreatedEntities) { var createdEntitiesHeaderSpan = new ReadOnlySpan <ushort>(IntPtr.Add(state, cursor).ToPointer(), 2); var createdEntitiesCount = createdEntitiesHeaderSpan[0]; var createdEntitiesLength = createdEntitiesHeaderSpan[1]; cursor += 4; if (createdEntitiesCount > 0) { var dataSpan = new ReadOnlySpan <byte>(IntPtr.Add(state, cursor).ToPointer(), createdEntitiesLength); _fromServer.Clear(); _fromServer.FromSpan(ref dataSpan, createdEntitiesLength); UnpackEntityUtility.CreateEntities(_game, _fromServer, createdEntitiesCount); cursor += createdEntitiesLength; } } #endregion #region removed entities if ((flags & PackedDataFlags.RemovedEntities) == PackedDataFlags.RemovedEntities) { var removedEntitiesHeaderSpan = new ReadOnlySpan <ushort>(IntPtr.Add(state, cursor).ToPointer(), 2); var removedEntitiesCount = removedEntitiesHeaderSpan[0]; var removedEntitiesLength = removedEntitiesHeaderSpan[1]; cursor += 4; if (removedEntitiesCount > 0) { var dataSpan = new ReadOnlySpan <byte>(IntPtr.Add(state, cursor).ToPointer(), removedEntitiesLength); _fromServer.Clear(); _fromServer.FromSpan(ref dataSpan, removedEntitiesLength); UnpackEntityUtility.RemoveEntities(_game, _fromServer, removedEntitiesCount); cursor += removedEntitiesLength; } } #endregion #region removed components if ((flags & PackedDataFlags.RemovedComponents) == PackedDataFlags.RemovedComponents) { var removedComponentsHeaderSpan = new ReadOnlySpan <ushort>(IntPtr.Add(state, cursor).ToPointer(), 2); var removedComponentsCount = removedComponentsHeaderSpan[0]; var removedComponentsLength = removedComponentsHeaderSpan[1]; cursor += 4; if (removedComponentsCount > 0) { var dataSpan = new ReadOnlySpan <byte>(IntPtr.Add(state, cursor).ToPointer(), removedComponentsLength); _fromServer.Clear(); _fromServer.FromSpan(ref dataSpan, removedComponentsLength); UnpackEntityUtility.RemoveComponents(_game, _fromServer, removedComponentsCount); cursor += removedComponentsLength; } } #endregion #region changed components if ((flags & PackedDataFlags.ChangedComponents) == PackedDataFlags.ChangedComponents) { var changedComponentsHeaderSpan = new ReadOnlySpan <ushort>(IntPtr.Add(state, cursor).ToPointer(), 2); var changedComponentsCount = changedComponentsHeaderSpan[0]; var changedComponentsLength = changedComponentsHeaderSpan[1]; cursor += 4; if (changedComponentsCount > 0) { var dataSpan = new ReadOnlySpan <byte>(IntPtr.Add(state, cursor).ToPointer(), changedComponentsLength); _fromServer.Clear(); _fromServer.FromSpan(ref dataSpan, changedComponentsLength); UnpackEntityUtility.ChangeComponents(_game, _fromServer, changedComponentsCount); } } #endregion Marshal.FreeHGlobal(state); }
private static void DoCover(BitBuffer buffer, GameEntity localEntity) { buffer.Reset(); UnpackEntityUtility.MakeEntity(localEntity, buffer); }