private void SerializeRopeData(BitStream stream, bool applyWhenReading, List<MyCubeGrid> gridsGroup = null) { if (MyRopeComponent.Static == null) return; if (stream.Writing) { m_tmpRopes.Clear(); m_tmpRopeGrids.Clear(); m_tmpRopeGrids.Add(Entity); Debug.Assert(gridsGroup != null); if (gridsGroup != null) { foreach (var grid in gridsGroup) m_tmpRopeGrids.Add(grid); } MyRopeComponent.Static.GetRopesForGrids(m_tmpRopeGrids, m_tmpRopes); MyRopeData ropeData; stream.WriteUInt16((ushort)m_tmpRopes.Count); foreach (var rope in m_tmpRopes) { var ropeProxyTarget = MyMultiplayer.Static.ReplicationLayer.GetProxyTarget((IMyEventProxy)rope); NetworkId ropeNetworkId = MyMultiplayer.Static.ReplicationLayer.GetNetworkIdByObject(ropeProxyTarget); stream.WriteNetworkId(ropeNetworkId); //TODO - MyRopeComponent should be rewritten to singleton MyRopeComponent.GetRopeData(rope.EntityId, out ropeData); stream.WriteFloat(ropeData.CurrentRopeLength); } m_tmpRopes.Clear(); m_tmpRopeGrids.Clear(); } else { uint ropesCount = stream.ReadUInt16(); for (uint i = 0; i < ropesCount; ++i) { NetworkId ropeNetworkId = stream.ReadNetworkId(); float ropeLength = stream.ReadFloat(); MyRopeReplicable replicable = MyMultiplayer.Static.ReplicationLayer.GetObjectByNetworkId(ropeNetworkId) as MyRopeReplicable; MyRope rope = replicable != null ? replicable.Instance : null; if (rope != null && applyWhenReading) MyRopeComponent.Static.SetRopeLengthSynced(rope.EntityId, ropeLength); } } }
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 override void SerializePhysics(BitStream stream, MyNetworkClient sender, bool highOrientationCompression = false) { // Serialize base base.SerializePhysics(stream, sender); Vector3D pos = Entity.WorldMatrix.Translation; if (stream.Writing) { var g = MyCubeGridGroups.Static.Physical.GetGroup(Entity); stream.WriteByte((byte)(g.Nodes.Count - 1)); // Ignoring self foreach (var node in g.Nodes) { // Ignore self, already serialized if (node.NodeData != Entity) { var target = MyMultiplayer.Static.ReplicationLayer.GetProxyTarget((IMyEventProxy)node.NodeData); // ~26.5 bytes per grid, not bad NetworkId networkId = MyMultiplayer.Static.ReplicationLayer.GetNetworkIdByObject(target); PositionUpdateMsg msg = CreatePositionMsg(node.NodeData); stream.WriteNetworkId(networkId); // ~2 bytes HalfVector3 posDelta = (HalfVector3)(Vector3)(msg.Position - pos); stream.Serialize(ref posDelta); // 6 bytes stream.SerializeNorm(ref msg.Orientation); // 6.5 bytes stream.Serialize(ref msg.LinearVelocity); // 6 bytes stream.Serialize(ref msg.AngularVelocity); // 6 bytes } } } else { byte numRecords = stream.ReadByte(); for (int i = 0; i < numRecords; i++) { PositionUpdateMsg msg = default(PositionUpdateMsg); NetworkId networkId = stream.ReadNetworkId(); HalfVector3 posDelta = default(HalfVector3); stream.Serialize(ref posDelta); msg.Position = posDelta + pos; stream.SerializeNorm(ref msg.Orientation); stream.Serialize(ref msg.LinearVelocity); stream.Serialize(ref msg.AngularVelocity); MyCubeGrid grid = MyMultiplayer.Static.ReplicationLayer.GetObjectByNetworkId(networkId) as MyCubeGrid; if (grid != null) { grid.SyncObject.OnPositionUpdate(ref msg, sender); } } } }
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; }
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); } }