コード例 #1
0
        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);
                }
            }

        }
コード例 #2
0
        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;
        }
コード例 #3
0
        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);
            }
        }
コード例 #4
0
ファイル: MySyncGrid.cs プロジェクト: fluxit/SpaceEngineers
        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);
                    }
                }
            }
        }
コード例 #5
0
        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);
            }
        }
コード例 #6
0
        private void ProcessEvent( MyPacket packet )
        {
            if ( _networkHandlers.Count == 0 )
            {
                ((MyReplicationLayer)MyMultiplayer.ReplicationLayer).ProcessEvent(packet);
                return;
            }

            //magic: DO NOT TOUCH
            BitStream stream = new BitStream();
            stream.ResetRead( packet );

            NetworkId networkId = stream.ReadNetworkId();
            //this value is unused, but removing this line corrupts the rest of the stream
            NetworkId blockedNetworkId = stream.ReadNetworkId();
            uint eventId = (uint)stream.ReadByte();

            CallSite site;
            IMyNetObject sendAs;
            object obj;
            if ( networkId.IsInvalid ) // Static event
            {
                site = m_typeTable.StaticEventTable.Get( eventId );
                sendAs = null;
                obj = null;
            }
            else // Instance event
            {
                sendAs = ( (MyReplicationLayer)MyMultiplayer.ReplicationLayer ).GetObjectByNetworkId( networkId );
                if ( sendAs == null )
                {
                    return;
                }
                var typeInfo = m_typeTable.Get( sendAs.GetType() );
                int eventCount = typeInfo.EventTable.Count;
                if ( eventId < eventCount ) // Directly
                {
                    obj = sendAs;
                    site = typeInfo.EventTable.Get( eventId );
                }
                else // Through proxy
                {
                    obj = ( (IMyProxyTarget)sendAs ).Target;
                    typeInfo = m_typeTable.Get( obj.GetType() );
                    site = typeInfo.EventTable.Get( eventId - (uint)eventCount ); // Subtract max id of Proxy
                }
            }

            #if DEBUG
            if ( ExtenderOptions.IsDebugging )
            {
                if ( !site.MethodInfo.Name.Contains( "SyncPropertyChanged" ) && !site.MethodInfo.Name.Contains( "OnSimulationInfo" ) )
                    ApplicationLog.Error( $"Caught event {site.MethodInfo.Name} from user {PlayerMap.Instance.GetFastPlayerNameFromSteamId( packet.Sender.Value )}:{packet.Sender.Value}" );
            }
            #endif
            //we're handling the network live in the game thread, this needs to go as fast as possible
            bool handled = false;
            Parallel.ForEach( _networkHandlers, handler =>
                                                {
                                                    if ( handler.CanHandle( site ) )
                                                        handled |= handler.Handle( packet.Sender.Value, site, stream, obj );
                                                } );

            if ( !handled )
                ( (MyReplicationLayer)MyMultiplayer.ReplicationLayer ).ProcessEvent( packet );
        }