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; }
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; 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; }
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); } }
private void ReadPhysics(BitStream stream, MyNetworkClient sender, MyEntity controlledEntity) { var stateGroup = MyExternalReplicable.FindByObject(controlledEntity).FindStateGroup<MyEntityPhysicsStateGroup>(); bool hasPhysics = stream.ReadBool(); if (hasPhysics && stateGroup.ResponsibleForUpdate(new EndpointId(sender.SteamUserId))) { stateGroup.Serialize(stream, null, 0, 65535); } }
private void ReadShared(BitStream stream, MyNetworkClient sender, out MyEntity controlledEntity) { controlledEntity = null; var hasControlledEntity = stream.ReadBool(); if (!hasControlledEntity) { Vector3D pos = Vector3D.Zero; stream.Serialize(ref pos); // 24B Position = pos; } else { var entityId = stream.ReadInt64(); MyEntity entity; if (!MyEntities.TryGetEntityById(entityId, out entity)) return; Position = entity.WorldMatrix.Translation; // TODO: Obsolete check? MySyncEntity syncEntity = entity.SyncObject as MySyncEntity; if (syncEntity == null) return; controlledEntity = entity; } }
private void ReadPhysics(BitStream stream, MyNetworkClient sender, MyEntity controlledEntity,uint serverTimeStamp) { bool hasPhysics = stream.ReadBool(); //if (m_currentServerTimeStamp == serverTimeStamp) //{ // return; //} m_currentServerTimeStamp = serverTimeStamp; if (hasPhysics && MyEntityPhysicsStateGroup.ResponsibleForUpdate(controlledEntity, new EndpointId(sender.SteamUserId))) { IMyStateGroup stateGroup = null; bool enableControlOnServer = stream.ReadBool(); bool stateGroupFound = stream.ReadBool(); if (stateGroupFound == false) { return; } if (enableControlOnServer) { stateGroup = MyExternalReplicable.FindByObject(controlledEntity).FindStateGroup<MyEntityPositionVerificationStateGroup>(); } else { stateGroup = MyExternalReplicable.FindByObject(controlledEntity).FindStateGroup<MyEntityPhysicsStateGroup>(); } if (stream.ReadBool()) { stateGroup.Serialize(stream, new EndpointId(sender.SteamUserId), ClientTimeStamp, 0, 65535); } } }
private void ReadInventory(BitStream stream) { if(stream.ReadBool() == false) { return; } if(m_recievedPacketIds == null) { m_recievedPacketIds = new MyQueue<uint>(RECIEVED_PACKET_HISTORY); } uint packetId = stream.ReadUInt32(); bool apply = true; if (m_recievedPacketIds.Count == RECIEVED_PACKET_HISTORY) { m_recievedPacketIds.Dequeue(); } if (m_recievedPacketIds.InternalArray.Contains(packetId) == false) { m_recievedPacketIds.Enqueue(packetId); } else { apply = false; } bool hasItems = stream.ReadBool(); if(hasItems) { int numItems = stream.ReadInt32(); for (int i = 0; i < numItems; ++i) { uint itemId = stream.ReadUInt32(); MyFixedPoint amout = new MyFixedPoint(); amout.RawValue = stream.ReadInt64(); if (apply) { Inventory.UpdateItemAmoutClient(itemId, amout); } } } hasItems = stream.ReadBool(); if (hasItems) { int numItems = stream.ReadInt32(); for (int i = 0; i < numItems; ++i) { uint itemId = stream.ReadUInt32(); if (apply) { Inventory.RemoveItemClient(itemId); } } } hasItems = stream.ReadBool(); if (hasItems) { int numItems = stream.ReadInt32(); for (int i = 0; i < numItems; ++i) { int position = stream.ReadInt32(); MyPhysicalInventoryItem item; VRage.Serialization.MySerializer.CreateAndRead(stream, out item, MyObjectBuilderSerializer.Dynamic); if (apply) { Inventory.AddItemClient(position, item); } } } hasItems = stream.ReadBool(); if (hasItems) { int numItems = stream.ReadInt32(); for (int i = 0; i < numItems; ++i) { int position = stream.ReadInt32(); int newPosition = stream.ReadInt32(); if (apply) { Inventory.SwapItemClient(position, newPosition); } } } Inventory.Refresh(); }
public void DeserializeDefault(BitStream bs) { bool isDefault = bs.ReadBool(); if (!isDefault) { foreach (var mySyncedObject in m_syncedClass) { mySyncedObject.DeserializeDefault(bs); } foreach (var mySynced in m_syncedVariables) { mySynced.DeserializeDefault(bs); } } }
public static void ReadSubGrids(BitStream stream, uint timestamp, bool apply,bool lowPrecisionOrientation, ref Vector3D basePos) { 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; bool moving = stream.ReadBool(); SerializeTransform(stream, grid, basePos, 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); } }
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; }
/// <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); } } }
static MyCharacterNetState ReadCharacterState(BitStream stream, out Vector3 move) { MyCharacterNetState charNetState = new MyCharacterNetState(); charNetState.WorldRealSpeed = stream.ReadHalf(); // Head and spine stuff charNetState.HeadX = stream.ReadHalf(); if (charNetState.HeadX.IsValid() == false) { charNetState.HeadX = 0.0f; } charNetState.HeadY = stream.ReadHalf(); charNetState.Spine = stream.ReadQuaternionNormCompressedIdentity(); charNetState.Head = stream.ReadQuaternionNormCompressedIdentity(); // Movement state charNetState.MovementState = (MyCharacterMovementEnum)stream.ReadUInt16(); // Movement flag charNetState.MovementFlag = (MyCharacterMovementFlags)stream.ReadUInt16(); //Flags charNetState.Jetpack = stream.ReadBool(); charNetState.Dampeners = stream.ReadBool(); charNetState.Lights = stream.ReadBool(); // TODO: Remove charNetState.Ironsight = stream.ReadBool(); charNetState.Broadcast = stream.ReadBool(); // TODO: Remove charNetState.TargetFromCamera = stream.ReadBool(); move = stream.ReadNormalizedSignedVector3(8); return charNetState; }
void Read(BitStream stream) { // TODO: Read additional client data, context MyNetworkClient sender; if (!Sync.Clients.TryGetClient(EndpointId.Value, out sender)) { Debug.Fail("Unknown sender"); return; } var hasControlledEntity = stream.ReadBool(); if (hasControlledEntity == false) { Vector3D pos = Vector3D.Zero; stream.Serialize(ref pos); // 24B Position = pos; } else { int numEntity = 0; if (stream.BytePosition < stream.ByteLength) { var entityId = stream.ReadInt64(); MyEntity entity; if (!MyEntities.TryGetEntityById(entityId, out entity)) return; MySyncEntity syncEntity = entity.SyncObject as MySyncEntity; if (syncEntity == null) return; Context = (MyContextKind)stream.ReadInt32(2); switch (Context) { case MyContextKind.Inventory: entityId = stream.ReadInt64(); break; case MyContextKind.Terminal: entityId = stream.ReadInt64(); break; case MyContextKind.Production: entityId = stream.ReadInt64(); break; default: entityId = stream.ReadInt64(); break; } MyEntities.TryGetEntityById(entityId, out entity); ContextEntity = entity; if (!syncEntity.ResponsibleForUpdate(sender)) { // Also happens when entering cockpit due to order of operations and responsibility update change //Debug.Fail("Server sending entity update for entity controlled by client, should happen only very rarely (packets out-of-order)"); return; } syncEntity.SerializePhysics(stream, sender); if (numEntity == 0) { Position = syncEntity.Entity.WorldMatrix.Translation; } numEntity++; } } }
bool ReadTransform(BitStream stream, MyEntity entity, Vector3D? deltaPosBase, bool applyWhenReading, bool movingOnServer, ref Vector3D outPosition, ref Quaternion outOrientation, ref MatrixD outWorldMartix, Func<MyEntity, Vector3D, bool> posValidation = null, MovedDelegate moveHandler = null) { Vector3D position; if (stream.ReadBool()) { position = stream.ReadVector3D(); // 24 B } else { Vector3 pos = stream.ReadVector3(); // 6 B if (deltaPosBase != null) { position = pos + deltaPosBase.Value; } else { position = pos; } } Quaternion orientation; bool lowPrecisionOrientation = stream.ReadBool(); if (lowPrecisionOrientation) { orientation = stream.ReadQuaternionNormCompressed(); // 29b } else { orientation = stream.ReadQuaternionNorm(); // 52b } if (entity != null) { movingOnServer |= (entity.PositionComp.GetPosition() - position).LengthSquared() > epsilonSq; if (movingOnServer && applyWhenReading && (posValidation == null || posValidation(entity, position))) { MatrixD matrix = MatrixD.CreateFromQuaternion(orientation); if (matrix.IsValid()) { matrix.Translation = position; outPosition = matrix.Translation; outOrientation = orientation; outWorldMartix = matrix; return true; } return false; } } return false; }
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 Deserialize(BitStream bs) { bool fieldExists = bs.ReadBool(); if (fieldExists) { foreach (var mySyncedObject in m_syncedClass) { mySyncedObject.Deserialize(bs); } foreach (var mySynced in m_syncedVariables) { mySynced.Deserialize(bs); } } }