protected void SerializeActive(BitStream stream, MyEntity entity) { if (stream.Writing) { if (entity.Physics.RigidBody != null && entity.Physics.RigidBody.IsActive) stream.WriteBool(true); else stream.WriteBool(false); } else { // reading bool isActive = stream.ReadBool(); if (entity != null && entity.Physics != null) { HkRigidBody rb = entity.Physics.RigidBody; if (rb != null) { if (isActive) rb.Activate(); else rb.Deactivate(); } } } }
public override bool Serialize(BitStream stream, EndpointId forClient, uint timestamp, byte packetId, int maxBitPosition) { bool lowPrecisionOrientation = true; bool applyWhenReading = true; SetSupport(FindSupportDelegate()); if (stream.Writing) { bool moving = IsMoving(Entity); stream.WriteBool(moving); SerializeVelocities(stream, Entity, MyEntityPhysicsStateGroup.EffectiveSimulationRatio, applyWhenReading, moving); SerializeTransform(stream, Entity, null, lowPrecisionOrientation, applyWhenReading, moving, timestamp); } else { bool moving = stream.ReadBool(); // reading SerializeServerVelocities(stream, Entity, MyEntityPhysicsStateGroup.EffectiveSimulationRatio, moving, ref Entity.m_serverLinearVelocity, ref Entity.m_serverAngularVelocity); applyWhenReading = SerializeServerTransform(stream, Entity, null, moving, timestamp, lowPrecisionOrientation, ref Entity.m_serverPosition, ref Entity.m_serverOrientation, ref Entity.m_serverWorldMatrix, m_positionValidation); if (applyWhenReading && moving) { Entity.PositionComp.SetWorldMatrix(Entity.m_serverWorldMatrix, null, true); Entity.SetSpeedsAccordingToServerValues(); } } SerializeFriction(stream, Entity); SerializeActive(stream, Entity); return true; }
void Write(BitStream stream) { // TODO: Make sure sleeping, server controlled entities are not moving locally (or they can be but eventually their position should be corrected) stream.WriteBool(MySession.ControlledEntity != null); if (MySession.ControlledEntity == null) { Vector3D pos = MySpectatorCameraController.Static.Position; stream.WriteDouble(pos.X); stream.WriteDouble(pos.Y); stream.WriteDouble(pos.Z); } else { var controlledEntity = MySession.ControlledEntity.Entity.GetTopMostParent(); // Send controlled entity every other frame to server if (MyMultiplayer.Static.FrameCounter % 2 == 0) { // TODO: Write additional client data, context if (controlledEntity != null && controlledEntity.SyncFlag && ((MySyncEntity)controlledEntity.SyncObject).ResponsibleForUpdate(Sync.Clients.LocalClient)) { stream.WriteInt64(controlledEntity.EntityId); switch (MyGuiScreenTerminal.GetCurrentScreen()) { case MyTerminalPageEnum.Inventory: stream.WriteInt32((int)MyContextKind.Inventory, 2); break; case MyTerminalPageEnum.ControlPanel: stream.WriteInt32((int)MyContextKind.Terminal, 2); break; case MyTerminalPageEnum.Production: stream.WriteInt32((int)MyContextKind.Production, 2); break; default: stream.WriteInt32((int)MyContextKind.None, 2); break; } if (MyGuiScreenTerminal.InteractedEntity != null) { stream.WriteInt64(MyGuiScreenTerminal.InteractedEntity.EntityId); } else { stream.WriteInt64(0); } ((MySyncEntity)controlledEntity.SyncObject).SerializePhysics(stream, null); } } } }
public override bool Serialize(BitStream stream, EndpointId forClient, uint timestamp, byte packetId, int maxBitPosition) { bool lowPrecisionOrientation = true; bool applyWhenReading = true; if (stream.Writing) { bool moving = IsMoving(Entity); stream.WriteBool(moving); SerializeVelocities(stream, Entity, MyEntityPhysicsStateGroup.EffectiveSimulationRatio, applyWhenReading, moving); SerializeTransform(stream, Entity, null, lowPrecisionOrientation, applyWhenReading, moving, timestamp); } else { bool moving = stream.ReadBool(); // reading SerializeServerVelocities(stream, Entity, MyEntityPhysicsStateGroup.EffectiveSimulationRatio, moving, ref Entity.m_serverLinearVelocity, ref Entity.m_serverAngularVelocity); float positionTolerancy = Math.Max(Entity.PositionComp.MaximalSize * 0.1f, 0.1f); float smallSpeed = 0.1f; if (Entity.m_serverLinearVelocity == Vector3.Zero || Entity.m_serverLinearVelocity.Length() < smallSpeed) { positionTolerancy = Math.Max(Entity.PositionComp.MaximalSize * 0.5f, 1.0f); } applyWhenReading = SerializeServerTransform(stream, Entity, null, moving, timestamp, lowPrecisionOrientation, positionTolerancy, ref Entity.m_serverPosition, ref Entity.m_serverOrientation, ref Entity.m_serverWorldMatrix, m_positionValidation); if (applyWhenReading && moving) { Entity.PositionComp.SetWorldMatrix(Entity.m_serverWorldMatrix, null, true); Entity.SetSpeedsAccordingToServerValues(); } } SerializeFriction(stream, Entity); SerializeActive(stream, Entity); return true; }
private void WritePhysics(BitStream stream, MyEntity controlledEntity) { IMyReplicable player = MyExternalReplicable.FindByObject(controlledEntity); if (player == null) { stream.WriteBool(false); return; } var stateGroup = player.FindStateGroup<MyEntityPhysicsStateGroup>(); if (stateGroup == null) { stream.WriteBool(false); return; } bool isResponsible = stateGroup.ResponsibleForUpdate(new EndpointId(Sync.MyId)); stream.WriteBool(isResponsible); if (isResponsible) { stateGroup.Serialize(stream, null, 0, 65535); } }
private void WritePhysics(BitStream stream, MyEntity controlledEntity) { IMyReplicable controlledReplicable = MyExternalReplicable.FindByObject(controlledEntity); stream.WriteBool(controlledReplicable != null); if (controlledReplicable == null) { return; } IMyStateGroup stateGroup = null; bool useCharacterOnServer = controlledEntity is MyCharacter && MyFakes.ENABLE_CHARACTER_CONTROL_ON_SERVER; bool useGridOnServer = controlledEntity is MyCubeGrid && MyFakes.ENABLE_SHIP_CONTROL_ON_SERVER; MyShipController controller = MySession.Static.ControlledEntity as MyShipController; bool hasWheels = controller != null && controller.HasWheels; if (useCharacterOnServer || (useGridOnServer && hasWheels == false)) { stateGroup = controlledReplicable.FindStateGroup<MyEntityPositionVerificationStateGroup>(); } else { stateGroup = controlledReplicable.FindStateGroup<MyEntityPhysicsStateGroup>(); } stream.WriteBool(useCharacterOnServer || (useGridOnServer && hasWheels == false)); stream.WriteBool(stateGroup != null ); if (stateGroup == null) { return; } bool isResponsible = MyEntityPhysicsStateGroup.ResponsibleForUpdate(controlledEntity,new EndpointId(Sync.MyId)); stream.WriteBool(isResponsible); if (isResponsible) { stateGroup.Serialize(stream, EndpointId, ClientTimeStamp, 0, 1024*1024); } }
private InventoryDeltaInformation PrepareSendData(ref InventoryDeltaInformation packetInfo, BitStream stream, int maxBitPosition,out bool needsSplit) { needsSplit = false; int startStreamPosition = stream.BitPosition; InventoryDeltaInformation sentData = new InventoryDeltaInformation(); sentData.HasChanges = false; stream.WriteBool(false); stream.WriteUInt32(packetInfo.MessageId); stream.WriteBool(packetInfo.ChangedItems != null); if (packetInfo.ChangedItems != null) { stream.WriteInt32(packetInfo.ChangedItems.Count); if (stream.BitPosition > maxBitPosition) { needsSplit = true; } else { sentData.ChangedItems = new Dictionary<uint, MyFixedPoint>(); foreach (var item in packetInfo.ChangedItems) { stream.WriteUInt32(item.Key); stream.WriteInt64(item.Value.RawValue); if (stream.BitPosition <= maxBitPosition) { sentData.ChangedItems[item.Key] = item.Value; sentData.HasChanges = true; } else { needsSplit = true; } } } } stream.WriteBool(packetInfo.RemovedItems != null); if (packetInfo.RemovedItems != null) { stream.WriteInt32(packetInfo.RemovedItems.Count); if (stream.BitPosition > maxBitPosition) { needsSplit = true; } else { sentData.RemovedItems = new List<uint>(); foreach (var item in packetInfo.RemovedItems) { stream.WriteUInt32(item); if (stream.BitPosition <= maxBitPosition) { sentData.RemovedItems.Add(item); sentData.HasChanges = true; } else { needsSplit = true; } } } } stream.WriteBool(packetInfo.NewItems != null); if (packetInfo.NewItems != null) { stream.WriteInt32(packetInfo.NewItems.Count); if (stream.BitPosition > maxBitPosition) { needsSplit = true; } else { sentData.NewItems = new SortedDictionary<int, MyPhysicalInventoryItem>(); foreach (var item in packetInfo.NewItems) { MyPhysicalInventoryItem inventoryItem = item.Value; VRage.Serialization.MySerializer.Write(stream, ref inventoryItem, MyObjectBuilderSerializer.Dynamic); if (stream.BitPosition <= maxBitPosition) { sentData.NewItems[item.Key] = inventoryItem; sentData.HasChanges = true; } else { needsSplit = true; } } } } stream.WriteBool(packetInfo.SwappedItems != null); if (packetInfo.SwappedItems != null) { stream.WriteInt32(packetInfo.SwappedItems.Count); if (stream.BitPosition > maxBitPosition) { needsSplit = true; } else { sentData.SwappedItems = new Dictionary<int, int>(); foreach (var item in packetInfo.SwappedItems) { stream.WriteInt32(item.Key); stream.WriteInt32(item.Value); if (stream.BitPosition <= maxBitPosition) { sentData.SwappedItems[item.Key] = item.Value; sentData.HasChanges = true; } else { needsSplit = true; } } } } stream.SetBitPositionWrite(startStreamPosition); return sentData; }
private InventoryDeltaInformation WriteInventory(ref InventoryDeltaInformation packetInfo, BitStream stream, byte packetId, int maxBitPosition, out bool needsSplit) { InventoryDeltaInformation sendPacketInfo = PrepareSendData(ref packetInfo, stream, maxBitPosition, out needsSplit); if (sendPacketInfo.HasChanges == false) { stream.WriteBool(false); return sendPacketInfo; } sendPacketInfo.MessageId = packetInfo.MessageId; stream.WriteBool(true); stream.WriteUInt32(sendPacketInfo.MessageId); stream.WriteBool(sendPacketInfo.ChangedItems != null); if (sendPacketInfo.ChangedItems != null) { stream.WriteInt32(sendPacketInfo.ChangedItems.Count); foreach (var item in sendPacketInfo.ChangedItems) { stream.WriteUInt32(item.Key); stream.WriteInt64(item.Value.RawValue); } } stream.WriteBool(sendPacketInfo.RemovedItems != null); if (sendPacketInfo.RemovedItems != null) { stream.WriteInt32(sendPacketInfo.RemovedItems.Count); foreach (var item in sendPacketInfo.RemovedItems) { stream.WriteUInt32(item); } } stream.WriteBool(sendPacketInfo.NewItems != null); if (sendPacketInfo.NewItems != null) { stream.WriteInt32(sendPacketInfo.NewItems.Count); foreach (var item in sendPacketInfo.NewItems) { stream.WriteInt32(item.Key); MyPhysicalInventoryItem itemTosend = item.Value; VRage.Serialization.MySerializer.Write(stream, ref itemTosend, MyObjectBuilderSerializer.Dynamic); } } stream.WriteBool(sendPacketInfo.SwappedItems != null); if (sendPacketInfo.SwappedItems != null) { stream.WriteInt32(sendPacketInfo.SwappedItems.Count); foreach (var item in sendPacketInfo.SwappedItems) { stream.WriteInt32(item.Key); stream.WriteInt32(item.Value); } } return sendPacketInfo; }
public void Serialize(BitStream bs, int clientIndex) { var dirty = m_dirty[clientIndex] != MySyncedDataStateEnum.UpToDate; bs.WriteBool(dirty); if (dirty) { foreach (var mySyncedObject in m_syncedClass) { mySyncedObject.Serialize(bs, clientIndex); } foreach (var mySynced in m_syncedVariables) { mySynced.Serialize(bs, clientIndex); } m_dirty[clientIndex] = MySyncedDataStateEnum.Pending; } }
public static bool WriteSubgrids(MyCubeGrid masterGrid, BitStream stream, ref EndpointId forClient, uint timestamp, int maxBitPosition, bool lowPrecisionOrientation,ref Vector3D basePos, ref int currentSentPosition) { bool fullyWritten = true; var g = MyCubeGridGroups.Static.PhysicalDynamic.GetGroup(masterGrid); if (g == null) { stream.WriteBool(false); } else { m_groups.Clear(); int i = 0; foreach (var node in g.Nodes) { i++; if (i < currentSentPosition) { continue; } var target = MyMultiplayer.Static.ReplicationLayer.GetProxyTarget((IMyEventProxy)node.NodeData); int pos = stream.BitPosition; if (node.NodeData != masterGrid && node.NodeData.Physics != null && !node.NodeData.Physics.IsStatic && target != null) { stream.WriteBool(true); // ~26.5 bytes per grid, not bad NetworkId networkId = MyMultiplayer.Static.ReplicationLayer.GetNetworkIdByObject(target); stream.WriteNetworkId(networkId); // ~2 bytes bool moving = IsMovingSubGrid(node.NodeData); stream.WriteBool(moving); SerializeTransform(stream, node.NodeData, basePos, lowPrecisionOrientation, false, moving, timestamp, null, null); // 12.5 bytes SerializeVelocities(stream, node.NodeData, EffectiveSimulationRatio, false, moving); // 12 byte UpdateGridMaxSpeed(node.NodeData, Sync.IsServer); m_groups.Add(node.NodeData); currentSentPosition++; } if (stream.BitPosition > maxBitPosition) { stream.SetBitPositionWrite(pos); fullyWritten = false; currentSentPosition--; break; } if (i == g.Nodes.Count) { currentSentPosition = 0; } } stream.WriteBool(false); } return fullyWritten; }
/// <summary> /// Serializes physics and takes into account support (what's entity standing on) /// </summary> private void SerializePhysicsWithSupport(BitStream stream, EndpointId forClient,uint timestamp, byte packetId, int maxBitPosition) { if (stream.Writing) { // TODO: only prototype implementation SetSupport(FindSupportDelegate()); stream.WriteBool(m_supportPhysics != null); if (m_supportPhysics != null) { stream.WriteInt64(m_supportPhysics.Entity.EntityId); var localToParent = Entity.WorldMatrix * MatrixD.Invert(m_supportPhysics.Entity.PositionComp.WorldMatrix); stream.Write(localToParent.Translation); stream.Write(Quaternion.CreateFromForwardUp(localToParent.Forward, localToParent.Up).ToVector4()); bool moving = IsMoving(Entity); stream.WriteBool(moving); SerializeVelocities(stream, Entity, EffectiveSimulationRatio, !IsControlledLocally, moving); } else { base.Serialize(stream, forClient,timestamp, packetId, maxBitPosition); } } else { if (stream.ReadBool()) { MyEntity support; bool apply = MyEntities.TryGetEntityById(stream.ReadInt64(), out support) && !IsControlledLocally; var pos = stream.ReadVector3D(); var orient = Quaternion.FromVector4(stream.ReadVector4()); if (apply) { var old = Entity.PositionComp.WorldMatrix; MatrixD localToParent = MatrixD.CreateFromQuaternion(orient); localToParent.Translation = pos; MatrixD matrix = localToParent * support.WorldMatrix; Entity.PositionComp.SetWorldMatrix(matrix, null, true); SetSupport(MySupportHelper.FindPhysics(support)); var handler = MoveHandler; if (handler != null) { handler(ref old, ref matrix); } } else { SetSupport(null); } bool moving = stream.ReadBool(); SerializeVelocities(stream, Entity, EffectiveSimulationRatio, apply, moving); } else { SetSupport(null); base.Serialize(stream, forClient, timestamp, packetId, maxBitPosition); } } }
public override void Serialize(BitStream stream, MyClientStateBase forClient, byte packetId, int maxBitPosition) { base.Serialize(stream, forClient, packetId, maxBitPosition); if (stream.Writing) { stream.WriteHalf(Entity.Physics.LinearVelocity.Length()); // Head and spine stuff, 36 - 152b (4.5B - 19 B) stream.WriteHalf(Entity.HeadLocalXAngle); // 2B stream.WriteHalf(Entity.HeadLocalYAngle); // 2B // TODO: Spine has only one angle (bending forward backward) // Getting EULER angles from Matrix seems good way to get it (z-component) stream.WriteQuaternionNormCompressedIdentity(Entity.GetAdditionalRotation(Entity.Definition.SpineBone)); // 1b / 30b stream.WriteQuaternionNormCompressedIdentity(Entity.GetAdditionalRotation(Entity.Definition.HeadBone)); // 1b / 30b // Movement state, 2B stream.WriteUInt16((ushort)Entity.GetCurrentMovementState()); // Movement flag. stream.WriteUInt16((ushort)Entity.MovementFlags); // Flags, 6 bits bool hasJetpack = Entity.JetpackComp != null; stream.WriteBool(hasJetpack ? Entity.JetpackComp.TurnedOn : false); stream.WriteBool(hasJetpack ? Entity.JetpackComp.DampenersTurnedOn : false); stream.WriteBool(Entity.LightEnabled); // TODO: Remove stream.WriteBool(Entity.ZoomMode == MyZoomModeEnum.IronSight); stream.WriteBool(Entity.RadioBroadcaster.WantsToBeEnabled); // TODO: Remove stream.WriteBool(Entity.TargetFromCamera); stream.WriteNormalizedSignedVector3(Entity.MoveIndicator, 8); if (MyFakes.CHARACTER_SERVER_SYNC) { Vector2 rotation = Entity.RotationIndicator; stream.WriteHalf(rotation.X); stream.WriteHalf(rotation.Y); stream.WriteHalf(Entity.RollIndicator); } } else { Vector3 move; MyCharacterNetState charNetState = ReadCharacterState(stream, out move); if (MyFakes.CHARACTER_SERVER_SYNC) { charNetState.Rotation.X = stream.ReadHalf(); charNetState.Rotation.Y = stream.ReadHalf(); charNetState.Roll = stream.ReadHalf(); } if (!IsControlledLocally && !Entity.Closed) { Entity.SetStateFromNetwork(ref charNetState); Entity.MoveIndicator = move; } } }
public override bool Serialize(BitStream stream, EndpointId forClient,uint timeStamp, byte packetId, int maxBitPosition) { base.Serialize(stream, forClient,timeStamp, packetId, maxBitPosition); if (stream.Writing) { // Head and spine stuff, 36 - 152b (4.5B - 19 B) stream.WriteHalf(Entity.HeadLocalXAngle); // 2B stream.WriteHalf(Entity.HeadLocalYAngle); // 2B // TODO: Spine has only one angle (bending forward backward) // Getting EULER angles from Matrix seems good way to get it (z-component) stream.WriteQuaternionNormCompressedIdentity(Entity.GetAdditionalRotation(Entity.Definition.SpineBone)); // 1b / 30b stream.WriteQuaternionNormCompressedIdentity(Entity.GetAdditionalRotation(Entity.Definition.HeadBone)); // 1b / 30b // Movement state, 2B stream.WriteUInt16((ushort)Entity.GetCurrentMovementState()); // Movement flag. stream.WriteUInt16((ushort)Entity.MovementFlags); // Flags, 6 bits bool hasJetpack = Entity.JetpackComp != null; stream.WriteBool(hasJetpack ? Entity.JetpackComp.TurnedOn : false); stream.WriteBool(hasJetpack ? Entity.JetpackComp.DampenersTurnedOn : false); stream.WriteBool(Entity.LightEnabled); // TODO: Remove stream.WriteBool(Entity.ZoomMode == MyZoomModeEnum.IronSight); stream.WriteBool(Entity.RadioBroadcaster.WantsToBeEnabled); // TODO: Remove stream.WriteBool(Entity.TargetFromCamera); stream.WriteNormalizedSignedVector3(Entity.MoveIndicator, 8); float speed = Entity.Physics.CharacterProxy != null ? Entity.Physics.CharacterProxy.Speed : 0.0f; stream.WriteFloat(speed); stream.WriteFloat(Entity.RotationIndicator.X); stream.WriteFloat(Entity.RotationIndicator.Y); stream.WriteFloat(Entity.RollIndicator); } else { Vector3 move; MyCharacterNetState charNetState = ReadCharacterState(stream); if (!IsControlledLocally && !Entity.Closed) { Entity.SetStateFromNetwork(ref charNetState); } } return true; }
/// <summary> /// Shared area for SE and ME. So far it writes whether you have a controlled entity or not. In the latter case you get the spectator position /// </summary> /// <param name="stream"></param> /// <param name="validControlledEntity"></param> private void WriteShared(BitStream stream, MyEntity controlledEntity) { stream.WriteBool(controlledEntity != null); if (controlledEntity == null) { Vector3D pos = MySpectatorCameraController.Static.Position; stream.Serialize(ref pos); } else { stream.WriteInt64(controlledEntity.EntityId); } }
public virtual bool Serialize(BitStream stream, EndpointId forClient,uint timestamp, byte packetId, int maxBitPosition) { bool moving = false; if (stream.Writing) { moving = IsMoving(Entity); stream.WriteBool(moving); } else { moving = stream.ReadBool(); } // When controlled by local player, don't apply what came from server SerializeTransform(stream, Entity, null, m_lowPrecisionOrientation, !IsControlledLocally, moving, timestamp, null, MoveHandler); SerializeVelocities(stream, Entity, EffectiveSimulationRatio, !IsControlledLocally, moving,VelocityHandler); return true; }
public override void SerializePhysics(BitStream stream, MyNetworkClient sender, bool highOrientationCompression = false) { // Usually 59 B // Base stuff (position, orientation, velocities) base.SerializePhysics(stream, sender, true); // 50.5 B if (MyFakes.CHARACTER_SERVER_SYNC) { // TODO: Serialize move and rotate when necesary } if (stream.Writing) { // Head and spine stuff, 36 - 152b (4.5B - 19 B) stream.WriteHalf(Entity.HeadLocalXAngle); // 2B stream.WriteHalf(Entity.HeadLocalYAngle); // 2B // TODO: Spine has only one angle (bending forward backward) stream.WriteQuaternionNormCompressedIdentity(Entity.GetAdditionalRotation(Entity.Definition.SpineBone)); // 1b / 30b stream.WriteQuaternionNormCompressedIdentity(Entity.GetAdditionalRotation(Entity.Definition.HeadBone)); // 1b / 30b stream.WriteQuaternionNormCompressedIdentity(Entity.GetAdditionalRotation(Entity.Definition.LeftForearmBone)); // 1b / 30b stream.WriteQuaternionNormCompressedIdentity(Entity.GetAdditionalRotation(Entity.Definition.LeftUpperarmBone)); // 1b / 30b // Movement state, 2B stream.WriteUInt16((ushort)Entity.GetCurrentMovementState()); // Flags, 6 bits stream.WriteBool(Entity.JetpackComp != null); if (Entity.JetpackComp != null) { stream.WriteBool(Entity.JetpackComp.TurnedOn); stream.WriteBool(Entity.JetpackComp.DampenersTurnedOn); } stream.WriteBool(Entity.LightEnabled); // TODO: Remove stream.WriteBool(Entity.ZoomMode == MyZoomModeEnum.IronSight); stream.WriteBool(Entity.RadioBroadcaster.WantsToBeEnabled); // TODO: Remove stream.WriteBool(Entity.TargetFromCamera); if (MyFakes.CHARACTER_SERVER_SYNC) { Vector3 temp = Entity.MoveIndicator; stream.WriteHalf(temp.X); stream.WriteHalf(temp.Y); stream.WriteHalf(temp.Z); Vector2 rotation = Entity.RotationIndicator; stream.WriteHalf(rotation.X); stream.WriteHalf(rotation.Y); stream.WriteHalf(Entity.Roll); } } else { // Head and spine stuff float headX = stream.ReadHalf(); float headY = stream.ReadHalf(); Quaternion spine = stream.ReadQuaternionNormCompressedIdentity(); Quaternion head = stream.ReadQuaternionNormCompressedIdentity(); Quaternion hand = stream.ReadQuaternionNormCompressedIdentity(); Quaternion upperArm = stream.ReadQuaternionNormCompressedIdentity(); var handler0 = HeadOrSpineChanged; if (handler0 != null) handler0(headX, headY, spine, head, hand, upperArm); // Movement state MyCharacterMovementEnum movementState = (MyCharacterMovementEnum)stream.ReadUInt16(); var handler = MovementStateChanged; if (handler != null && Entity.GetCurrentMovementState() != movementState) handler(movementState); // Flags bool hasJetpack = stream.ReadBool(); bool jetpack = false; bool dampeners = false; if (hasJetpack) { jetpack = stream.ReadBool(); dampeners = stream.ReadBool(); } bool lights = stream.ReadBool(); // TODO: Remove bool ironsight = stream.ReadBool(); bool broadcast = stream.ReadBool(); // TODO: Remove bool targetFromCamera = stream.ReadBool(); if (MyFakes.CHARACTER_SERVER_SYNC) { Vector3 temp = Vector3.Zero; temp.X = stream.ReadHalf(); temp.Y = stream.ReadHalf(); temp.Z = stream.ReadHalf(); Entity.MoveIndicator = temp; Vector2 rotation = Vector2.Zero; rotation.X = stream.ReadHalf(); rotation.Y = stream.ReadHalf(); Entity.RotationIndicator = rotation; Entity.Roll = stream.ReadHalf(); } var handler2 = FlagsChanged; if (handler2 != null) handler2(jetpack, dampeners, lights, ironsight, broadcast, targetFromCamera); } }
void WriteTransform(BitStream stream, MyEntity entity, Vector3D? deltaPosBase, bool lowPrecisionOrientation) { var matrix = entity.WorldMatrix; stream.WriteBool(deltaPosBase == null); if (deltaPosBase == null) { stream.Write(matrix.Translation); // 24 B } else { stream.Write((Vector3)(matrix.Translation - deltaPosBase.Value)); // 6 B } var orientation = Quaternion.CreateFromForwardUp(matrix.Forward, matrix.Up); stream.WriteBool(lowPrecisionOrientation); if (lowPrecisionOrientation) { stream.WriteQuaternionNormCompressed(orientation); // 29b } else { stream.WriteQuaternionNorm(orientation); // 52b } }
public override bool Serialize(BitStream stream, EndpointId forClient,uint timestamp, byte packetId, int maxBitPosition) { // Client does not care about slave grids, he always synced group through controlled object Debug.Assert(stream.Reading || !Sync.IsServer || Entity == GetMasterGrid(Entity), "Writing data from SlaveGrid!"); bool apply = !IsControlledLocally; bool moving = false; if (stream.Writing) { moving = IsMoving(Entity); stream.WriteBool(moving); } else { moving = stream.ReadBool(); } // Serialize this grid apply = SerializeTransform(stream, Entity, null, m_lowPrecisionOrientation, apply,moving, timestamp, m_positionValidation, MoveHandler); SerializeVelocities(stream, Entity, EffectiveSimulationRatio, apply, moving,VelocityHandler); // Serialize other grids in group Vector3D basePos = Entity.WorldMatrix.Translation; if (stream.Writing) { UpdateGridMaxSpeed(Entity, Sync.IsServer); bool fullyWritten = WriteSubgrids(Entity,stream, ref forClient, timestamp, maxBitPosition,m_lowPrecisionOrientation, ref basePos, ref m_currentSentPosition); stream.WriteBool(fullyWritten); if (fullyWritten) { SerializeRopeData(stream, apply, gridsGroup: m_groups); } return fullyWritten; } else { UpdateGridMaxSpeed(Entity, !Sync.IsServer); ReadSubGrids(stream, timestamp, apply,m_lowPrecisionOrientation, ref basePos); if (stream.ReadBool()) { SerializeRopeData(stream, apply); } } return true; }
public override void Serialize(BitStream stream, MyClientStateBase forClient, byte packetId, int maxBitPosition) { // Client does not care about slave grids, he always synced group through controlled object Debug.Assert(stream.Reading || !Sync.IsServer || Entity == GetMasterGrid(Entity), "Writing data from SlaveGrid!"); bool apply = !IsControlledLocally; bool moving = false; if (stream.Writing) { moving = IsMoving(Entity); stream.WriteBool(moving); } else { moving = stream.ReadBool(); } // Serialize this grid apply = SerializeTransform(stream, Entity, null, m_lowPrecisionOrientation, apply,moving, m_positionValidation, MoveHandler); SerializeVelocities(stream, Entity, EffectiveSimulationRatio, apply, moving,VelocityHandler); // Serialize other grids in group Vector3D basePos = Entity.WorldMatrix.Translation; if (stream.Writing) { UpdateGridMaxSpeed(Entity, Sync.IsServer); var g = MyCubeGridGroups.Static.PhysicalDynamic.GetGroup(Entity); if (g == null) { stream.WriteByte(0); } else { m_groups.Clear(); int i= -1; foreach (var node in g.Nodes) { i++; if(i < m_currentSentPosition) { continue; } if (i == m_currentSentPosition + NUM_NODES_TO_SEND_ALL) { break; } var target = MyMultiplayer.Static.ReplicationLayer.GetProxyTarget((IMyEventProxy)node.NodeData); if (node.NodeData != Entity && !node.NodeData.IsStatic && target != null) { m_groups.Add(node.NodeData); } } m_currentSentPosition = i; if (m_currentSentPosition >= g.Nodes.Count-1) { m_currentSentPosition = 0; } stream.WriteByte((byte)m_groups.Count); // Ignoring self foreach (var node in m_groups) { var target = MyMultiplayer.Static.ReplicationLayer.GetProxyTarget((IMyEventProxy)node); // ~26.5 bytes per grid, not bad NetworkId networkId = MyMultiplayer.Static.ReplicationLayer.GetNetworkIdByObject(target); stream.WriteNetworkId(networkId); // ~2 bytes moving = IsMoving(node); stream.WriteBool(moving); SerializeTransform(stream, node, basePos, true, apply, moving,null, null); // 12.5 bytes SerializeVelocities(stream, node, EffectiveSimulationRatio, apply, moving); // 12 byte UpdateGridMaxSpeed(node, Sync.IsServer); } } SerializeRopeData(stream, apply, gridsGroup: m_groups); } else { UpdateGridMaxSpeed(Entity, !Sync.IsServer); byte numRecords = stream.ReadByte(); for (int i = 0; i < numRecords; i++) { NetworkId networkId = stream.ReadNetworkId(); // ~2 bytes MyCubeGridReplicable replicable = MyMultiplayer.Static.ReplicationLayer.GetObjectByNetworkId(networkId) as MyCubeGridReplicable; MyCubeGrid grid = replicable != null ? replicable.Grid : null; moving = stream.ReadBool(); SerializeTransform(stream, grid, basePos, true, apply && grid != null,moving, null, null); // 12.5 bytes SerializeVelocities(stream, grid, EffectiveSimulationRatio, apply && grid != null, moving); // 12 bytes UpdateGridMaxSpeed(grid,!Sync.IsServer); } SerializeRopeData(stream, apply); } }
public override bool Serialize(BitStream stream, EndpointId forClient,uint timestamp, byte packetId, int maxBitPosition) { // Client does not care about slave grids, he always synced group through controlled object Debug.Assert(stream.Reading || !Sync.IsServer || Entity == GetMasterGrid(Entity), "Writing data from SlaveGrid!"); bool apply = !IsControlledLocally; bool moving = false; if (stream.Writing) { moving = IsMoving(Entity); stream.WriteBool(moving); } else { moving = stream.ReadBool(); } // Serialize this grid apply = SerializeTransform(stream, Entity, null, m_lowPrecisionOrientation, apply,moving, timestamp, m_positionValidation, MoveHandler); SerializeVelocities(stream, Entity, EffectiveSimulationRatio, apply, moving,VelocityHandler); // Serialize other grids in group Vector3D basePos = Entity.WorldMatrix.Translation; if (stream.Writing) { bool fullyWritten = true; UpdateGridMaxSpeed(Entity, Sync.IsServer); var g = MyCubeGridGroups.Static.PhysicalDynamic.GetGroup(Entity); if (g == null) { stream.WriteBool(false); } else { m_groups.Clear(); int i = 0; foreach (var node in g.Nodes) { i++; if (ResponsibleForUpdate(node.NodeData, forClient)) { continue; } if(i < m_currentSentPosition) { continue; } var target = MyMultiplayer.Static.ReplicationLayer.GetProxyTarget((IMyEventProxy)node.NodeData); int pos = stream.BitPosition; if (node.NodeData != Entity && !node.NodeData.IsStatic && target != null) { stream.WriteBool(true); // ~26.5 bytes per grid, not bad NetworkId networkId = MyMultiplayer.Static.ReplicationLayer.GetNetworkIdByObject(target); stream.WriteNetworkId(networkId); // ~2 bytes moving = IsMoving(node.NodeData); stream.WriteBool(moving); SerializeTransform(stream, node.NodeData, basePos, m_lowPrecisionOrientation, apply, moving, timestamp, null, null); // 12.5 bytes SerializeVelocities(stream, node.NodeData, EffectiveSimulationRatio, apply, moving); // 12 byte UpdateGridMaxSpeed(node.NodeData, Sync.IsServer); m_groups.Add(node.NodeData); m_currentSentPosition++; } if (stream.BitPosition > maxBitPosition) { stream.SetBitPositionWrite(pos); fullyWritten = false; m_currentSentPosition--; break; } if (i == g.Nodes.Count) { m_currentSentPosition = 0; } } stream.WriteBool(false); } stream.WriteBool(fullyWritten); if (fullyWritten) { SerializeRopeData(stream, apply, gridsGroup: m_groups); } return fullyWritten; } else { UpdateGridMaxSpeed(Entity, !Sync.IsServer); while (stream.ReadBool()) { NetworkId networkId = stream.ReadNetworkId(); // ~2 bytes MyCubeGridReplicable replicable = MyMultiplayer.Static.ReplicationLayer.GetObjectByNetworkId(networkId) as MyCubeGridReplicable; MyCubeGrid grid = replicable != null ? replicable.Grid : null; moving = stream.ReadBool(); SerializeTransform(stream, grid, basePos, m_lowPrecisionOrientation, apply && grid != null, moving, timestamp, null, null); // 12.5 bytes SerializeVelocities(stream, grid, EffectiveSimulationRatio, apply && grid != null, moving); // 12 bytes UpdateGridMaxSpeed(grid,!Sync.IsServer); } if (stream.ReadBool()) { SerializeRopeData(stream, apply); } } return true; }
public void SerializeDefault(BitStream bs, int clientIndex = -1) { bool isDefault = IsDefault(); bs.WriteBool(!isDefault); if (!isDefault) { foreach (var syncObj in m_syncedClass) { syncObj.SerializeDefault(bs, clientIndex); } foreach (var syncVar in m_syncedVariables) { syncVar.SerializeDefault(bs, clientIndex); } } if (clientIndex == -1) { for (int i = 0; i < m_dirty.Length; i++) { m_dirty[i] = MySyncedDataStateEnum.Pending; } } else { Debug.Assert(clientIndex < m_dirty.Length); m_dirty[clientIndex] = MySyncedDataStateEnum.Pending; } }