Exemplo n.º 1
0
        private bool ReceiveOne()
        {
            uint length;

            if ((MySteam.IsActive || MySteam.Server != null) && Peer2Peer.IsPacketAvailable(out length, Channel))
            {
                ulong sender;
                var   msg = GetMessage((int)length);
                if (Peer2Peer.ReadPacket(msg.Data, out length, out sender, Channel))
                {
                    if (m_timestampProvider != null)
                    {
                        msg.Timestamp = m_timestampProvider();
                    }

                    msg.ReceivedTime = MyTimeSpan.FromTicks(Stopwatch.GetTimestamp());
                    msg.Length       = (int)length;
                    msg.UserId       = sender;

                    m_receiveQueue.Enqueue(msg);
                    return(true);
                }
                else
                {
                    m_messagePool.Return(msg);
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }
Exemplo n.º 2
0
        private void ProcessMessages(NetworkMessageDelegate handler, MyTimeSpan delay)
        {
            long delayTicks  = (long)Math.Round(delay.Seconds * Stopwatch.Frequency);
            var  processTime = MyTimeSpan.FromTicks(Stopwatch.GetTimestamp() - delayTicks);

            Message msg;
            int     count = m_receiveQueue.Count;

            while (m_receiveQueue.TryPeek(out msg) && (processTime > msg.ReceivedTime) && count != 0)
            {
                count--;
                if (m_receiveQueue.TryDequeue(out msg)) // Can fail when queue was cleared
                {
                    if (msg.Timestamp != MyTimeSpan.Zero)
                    {
                        msg.Timestamp += delay;
                    }

                    try
                    {
                        handler(msg.Data, msg.Length, msg.UserId, msg.Timestamp, msg.ReceivedTime);
                    }
                    catch (Exception ex)
                    {
                        MyLog.Default.WriteLine(ex);
                        if (!Sandbox.Game.Multiplayer.Sync.IsServer)
                        {
                            throw;
                        }
                        m_disconnectPeerOnError(msg.UserId);
                    }
                    m_messagePool.Return(msg);
                }
            }
        }
Exemplo n.º 3
0
        public override void Run(VoidAction tickCallback)
        {
            // 59.75 is sort of compensation
            long ticksPerFrame = (int)Math.Round(MyGameTimer.Frequency / 59.75f);
            long targetTicks   = 0;

            MyLog.Default.WriteLine("Timer Frequency: " + MyGameTimer.Frequency);
            MyLog.Default.WriteLine("Ticks per frame: " + ticksPerFrame);

            ManualResetEventSlim waiter = new ManualResetEventSlim(false, 0);

            MyTimer.TimerEventHandler handler = new MyTimer.TimerEventHandler((a, b, c, d, e) =>
            {
                waiter.Set();
            });


            base.Run(delegate
            {
                using (Stats.Generic.Measure("WaitForUpdate"))
                {
                    var currentTicks = m_gameTimer.ElapsedTicks;

                    // Wait for correct frame start
                    targetTicks += ticksPerFrame;
                    if (currentTicks > targetTicks + ticksPerFrame * 5)
                    {
                        // We're more behind than 5 frames, don't try to catch up
                        targetTicks = currentTicks;
                    }
                    else
                    {
                        // For until correct tick comes
                        if (MyFakes.ENABLE_UPDATE_WAIT)
                        {
                            var remaining = MyTimeSpan.FromTicks(targetTicks - currentTicks);
                            int waitMs    = (int)(remaining.Miliseconds - 0.1); // To handle up to 0.1ms inaccuracy of timer
                            if (waitMs > 0)
                            {
                                waiter.Reset();
                                MyTimer.StartOneShot(waitMs, handler);
                                waiter.Wait(17); // Never wait more than 17ms
                                //Debug.Assert(MyPerformanceCounter.ElapsedTicks < targetTicks);
                                //VRageRender.MyRenderStats.Write("WaitRemaining", (float)MyPerformanceCounter.TicksToMs(targetTicks - MyPerformanceCounter.ElapsedTicks), VRageRender.MyStatTypeEnum.MinMaxAvg, 300, 3);
                            }
                        }
                        while (m_gameTimer.ElapsedTicks < targetTicks)
                        {
                            ;
                        }
                    }
                }

                //UpdateInternal();
                tickCallback();

                ProfilerShort.Commit();
            });
        }
Exemplo n.º 4
0
        private void UpdatePingSmoothing()
        {
            var currentTime = MyTimeSpan.FromTicks(Stopwatch.GetTimestamp());
            var deltaTime   = currentTime - m_lastPingTime;
            var factor      = Math.Min(deltaTime.Seconds / PingSmoothFactor, 1.0);

            m_smoothPing   = MyTimeSpan.FromMilliseconds(m_ping.Milliseconds * factor + m_smoothPing.Milliseconds * (1 - factor));
            m_lastPingTime = currentTime;
        }
Exemplo n.º 5
0
        public override void Run(VoidAction tickCallback)
        {
            long targetTicks = 0;

            ManualResetEventSlim waiter = new ManualResetEventSlim(false, 0);

            MyTimer.TimerEventHandler handler = new MyTimer.TimerEventHandler((a, b, c, d, e) =>
            {
                waiter.Set();
            });

            base.Run(delegate
            {
                using (StatGroup.Measure(StatName))
                {
                    var currentTicks = m_gameTimer.ElapsedTicks;

                    // Wait for correct frame start
                    targetTicks += TickPerFrame;
                    if (currentTicks > targetTicks + TickPerFrame * 5)
                    {
                        // We're more behind than 5 frames, don't try to catch up
                        targetTicks = currentTicks;
                    }
                    else
                    {
                        // For until correct tick comes
                        if (EnableUpdateWait)
                        {
                            var remaining = MyTimeSpan.FromTicks(targetTicks - currentTicks);
                            int waitMs    = (int)(remaining.Miliseconds - 0.1); // To handle up to 0.1ms inaccuracy of timer
                            if (waitMs > 0)
                            {
                                waiter.Reset();
                                MyTimer.StartOneShot(waitMs, handler);
                                waiter.Wait(17); // Never wait more than 17ms
                                //Debug.Assert(MyPerformanceCounter.ElapsedTicks < targetTicks);
                                //VRageRender.MyRenderStats.Write("WaitRemaining", (float)MyPerformanceCounter.TicksToMs(targetTicks - MyPerformanceCounter.ElapsedTicks), VRageRender.MyStatTypeEnum.MinMaxAvg, 300, 3);
                            }
                        }
                        while (m_gameTimer.ElapsedTicks < targetTicks)
                        {
                            ;
                        }
                    }
                }

                //UpdateInternal();
                tickCallback();
            });
        }
Exemplo n.º 6
0
        private void Lock(long beforeUpdate)
        {
            //maximum sim speed can be 1.0 minimum 0.01, during loading there can be peaks more than 100 ms and we dont want to lock sim speed to such values
            long currentTicks = Math.Min(Math.Max(m_renderLoop.TickPerFrame, UpdateCurrentFrame()), 10 * m_renderLoop.TickPerFrame);

            m_currentMin = Math.Max(currentTicks, m_currentMin);
            m_currentFrameIncreaseTime += m_targetMs;

            if (currentTicks > m_targetTicks)
            {
                m_targetTicks = currentTicks;
                m_currentFrameIncreaseTime = 0;
                m_currentMin = 0;
                m_targetMs   = (float)MyPerformanceCounter.TicksToMs(m_targetTicks);
            }
            else
            {
                //if there was spike that was longer than 5 frames that caused drop and after that sim speed increased more than 0.2 we want to get back to those values
                //no need to lock to lower values
                long difference        = m_targetTicks - m_currentMin;
                bool increaseInstantly = difference > RATIO_TO_INCREASE_INSTANTLY * m_renderLoop.TickPerFrame;

                if (m_currentFrameIncreaseTime > NUM_MS_TO_INCREASE || increaseInstantly)
                {
                    m_targetTicks = m_currentMin;
                    m_currentFrameIncreaseTime = 0;
                    m_currentMin = 0;
                    m_targetMs   = (float)MyPerformanceCounter.TicksToMs(m_targetTicks);
                }
            }

            long remainingTicksTowait = MyPerformanceCounter.ElapsedTicks - beforeUpdate;
            var  remainingTimeToWait  = MyTimeSpan.FromTicks(m_targetTicks - remainingTicksTowait);

            int waitMs = (int)(remainingTimeToWait.Miliseconds - 0.1);

            if (waitMs > 0 && !EnableMaxSpeed)
            {
                m_waiter.Reset();
                MyTimer.StartOneShot(waitMs, m_handler);
                m_waiter.Wait(waitMs + 1);
            }

            remainingTicksTowait = MyPerformanceCounter.ElapsedTicks - beforeUpdate;

            while (m_targetTicks > remainingTicksTowait)
            {
                remainingTicksTowait = MyPerformanceCounter.ElapsedTicks - beforeUpdate;
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Enqueues message for processing, useful for loopback
        /// </summary>
        public void AddMessage(byte[] data, int length, ulong sender)
        {
            var msg = GetMessage(length);

            Array.Copy(data, msg.Data, length);
            msg.Length       = length;
            msg.ReceivedTime = MyTimeSpan.FromTicks(Stopwatch.GetTimestamp());
            if (m_timestampProvider != null)
            {
                msg.Timestamp = m_timestampProvider();
            }
            msg.UserId = sender;
            m_receiveQueue.Enqueue(msg);
        }
Exemplo n.º 8
0
        public void ProcessRpc(BitReaderWriter reader)
        {
            reader.ReadData(m_sender, false);
            MyPacket packet;

            packet.Data   = m_sender.ReceiveStream.Data;
            packet.Sender = MyEventContext.Current.Sender;
            if (packet.Sender.IsNull)
            {
                packet.Sender = new EndpointId(Sync.MyId);
            }
            packet.Timestamp     = MyTimeSpan.Zero;
            packet.PayloadOffset = 0;
            packet.PayloadLength = (int)m_sender.ReceiveStream.Position;
            packet.ReceivedTime  = MyTimeSpan.FromTicks(Stopwatch.GetTimestamp());
            TransportLayer.HandleOldGameEvent(packet);
        }
Exemplo n.º 9
0
        private void HandleMessage(byte[] data, int dataSize, ulong sender, MyTimeSpan timestamp, MyTimeSpan receivedTime)
        {
            if (dataSize < sizeof(byte)) // This would cause crash, message has to contain at least MyMessageId
            {
                return;
            }

            ProfilerShort.Begin("Handle message");

            if (sender != Sync.MyId)
            {
                ByteCountReceived += dataSize;
            }

            MyMessageId id = (MyMessageId)data[0];

            LogStats(ReceiveStats, "", dataSize, 1, P2PMessageEnum.Reliable);


            m_thisFrameTraffic[(int)id] += dataSize;

            if (id == MyMessageId.OLD_GAME_EVENT_FLUSH) // Flush buffer
            {
                if (m_buffer != null)
                {
                    m_buffer.Clear();
                }
            }
            else if (IsBuffering && id != MyMessageId.JOIN_RESULT && id != MyMessageId.WORLD_DATA && id != MyMessageId.WORLD_BATTLE_DATA)  // Buffer event
            {
                var buff = new Buffer();
                buff.Sender = sender;
                buff.Data   = new byte[dataSize];
                Array.Copy(data, buff.Data, dataSize);
                buff.ReceivedTime = MyTimeSpan.FromTicks(Stopwatch.GetTimestamp());
                m_buffer.Add(buff);
            }
            else // Process event
            {
                NetProfiler.Begin("Live data", 0);
                ProcessMessage(data, dataSize, sender, timestamp, receivedTime);
                NetProfiler.End();
            }

            ProfilerShort.End();
        }
Exemplo n.º 10
0
        public override void SendUpdate()
        {
            ProfilerShort.Begin("ClientState.WriteAcks");

            // Client ACK Packet - reliable
            SendStream.ResetWrite();

            // ACK Header
            // Write last state sync packet id
            SendStream.WriteByte(m_lastStateSyncPacketId);

            // Write ACKs
            byte num = (byte)m_acks.Count;

            SendStream.WriteByte(num);
            for (int i = 0; i < num; i++)
            {
                SendStream.WriteByte(m_acks[i]);
            }
            SendStream.Terminate();
            m_acks.Clear();
            ProfilerShort.End();
            m_callback.SendClientAcks(SendStream);

            // Client Update Packet
            SendStream.ResetWrite();

            m_clientPacketId++;
            SendStream.WriteByte(m_clientPacketId);
            SendStream.WriteDouble(MyTimeSpan.FromTicks(Stopwatch.GetTimestamp()).Milliseconds);
            ProfilerShort.Begin("ClientState.Serialize");
            if (VRage.MyCompilationSymbols.EnableNetworkPacketTracking)
            {
                Trace.MyTrace.Send(Trace.TraceWindow.MPackets, "Send client update: ");
            }
            // Write Client state
            ClientState.Serialize(SendStream, false);
            ProfilerShort.End();
            SendStream.Terminate();

            ProfilerShort.Begin("SendClientUpdate");
            m_callback.SendClientUpdate(SendStream);
            ProfilerShort.End();

            //Client.SendMessageToServer(m_sendStream, PacketReliabilityEnum.UNRELIABLE, PacketPriorityEnum.IMMEDIATE_PRIORITY, MyChannelEnum.StateDataSync);
        }
Exemplo n.º 11
0
        private void Lock(long beforeUpdate)
        {
            long num = Math.Min(Math.Max(this.m_renderLoop.TickPerFrame, this.UpdateCurrentFrame()), 10 * this.m_renderLoop.TickPerFrame);

            this.m_currentMin = Math.Max(num, this.m_currentMin);
            this.m_currentFrameIncreaseTime += m_targetMs;
            if (num > this.m_targetTicks)
            {
                this.m_targetTicks = num;
                this.m_currentFrameIncreaseTime = 0f;
                this.m_currentMin = 0L;
                m_targetMs        = (float)Sandbox.Game.Debugging.MyPerformanceCounter.TicksToMs(this.m_targetTicks);
            }
            else
            {
                bool flag = (this.m_targetTicks - this.m_currentMin) > (0.25f * this.m_renderLoop.TickPerFrame);
                if ((this.m_currentFrameIncreaseTime > 2000f) | flag)
                {
                    this.m_targetTicks = this.m_currentMin;
                    this.m_currentFrameIncreaseTime = 0f;
                    this.m_currentMin = 0L;
                    m_targetMs        = (float)Sandbox.Game.Debugging.MyPerformanceCounter.TicksToMs(this.m_targetTicks);
                }
            }
            long num2       = Sandbox.Game.Debugging.MyPerformanceCounter.ElapsedTicks - beforeUpdate;
            int  intervalMS = (int)(MyTimeSpan.FromTicks(this.m_targetTicks - num2).Milliseconds - 0.1);

            if ((intervalMS > 0) && !this.EnableMaxSpeed)
            {
                this.m_waiter.Reset();
                MyTimer.StartOneShot(intervalMS, this.m_handler);
                this.m_waiter.Wait((int)(intervalMS + 1));
            }
            for (num2 = Sandbox.Game.Debugging.MyPerformanceCounter.ElapsedTicks - beforeUpdate; this.m_targetTicks > num2; num2 = Sandbox.Game.Debugging.MyPerformanceCounter.ElapsedTicks - beforeUpdate)
            {
            }
        }
Exemplo n.º 12
0
        private void SendUpdate()
        {
            MyPacketDataBitStreamBase bitStreamPacketData = MyNetworkWriter.GetBitStreamPacketData();
            BitStream stream = bitStreamPacketData.Stream;

            stream.WriteByte(this.m_lastStateSyncPacketId, 8);
            stream.WriteByte((byte)this.m_acks.Count, 8);
            foreach (byte num2 in this.m_acks)
            {
                stream.WriteByte(num2, 8);
            }
            stream.Terminate();
            this.m_acks.Clear();
            this.SendClientAcks(bitStreamPacketData);
            bitStreamPacketData = MyNetworkWriter.GetBitStreamPacketData();
            stream = bitStreamPacketData.Stream;
            this.m_clientPacketId = (byte)(this.m_clientPacketId + 1);
            stream.WriteByte(this.m_clientPacketId, 8);
            stream.WriteDouble(MyTimeSpan.FromTicks(Stopwatch.GetTimestamp()).Milliseconds);
            stream.WriteDouble(0.0);
            this.m_clientState.Serialize(stream, false);
            stream.Terminate();
            this.SendClientUpdate(bitStreamPacketData);
        }
Exemplo n.º 13
0
        public ReceiveStatus ReceiveOne(out uint length)
        {
            ulong num;

            length = 0;
            if ((!MyGameService.IsActive && ((MyGameService.GameServer == null) || !MyGameService.GameServer.Running)) || !MyGameService.Peer2Peer.IsPacketAvailable(out length, this.m_channel))
            {
                return(ReceiveStatus.None);
            }
            MyPacketDataPooled message = this.GetMessage((int)length);

            if (!MyGameService.Peer2Peer.ReadPacket(message.Data, ref length, out num, this.m_channel))
            {
                return(ReceiveStatus.None);
            }
            MyPacketData item = message;
            bool         flag = message.Data[1] > 0;

            if ((message.Data[0] != 0xce) || (flag && !this.CheckCrc(message.Data, 2, 6, ((int)length) - 6)))
            {
                string str = null;
                for (int i = 0; i < Math.Min(10, length); i++)
                {
                    str = str + message.Data[i].ToString("X ");
                }
                MyLog.Default.WriteLine($"ERROR! Invalid packet from channel #{this.m_channel} length {(uint) length} from {num} initial bytes: {str}");
                message.Return();
                return(ReceiveStatus.TamperredPacket);
            }
            byte num2       = message.Data[6];
            byte num3       = message.Data[7];
            int  byteOffset = 8;

            if (num3 > 1)
            {
                if (num2 == 0)
                {
                    int num6 = num3 * 0xf4240;
                    this.m_largePacket = new byte[num6];
                }
                Array.Copy(message.Data, 8L, this.m_largePacket, (long)(num2 * 0xf4240), (long)(length - 8));
                this.m_largePacketCounter++;
                message.Return();
                if (num2 != (num3 - 1))
                {
                    return(this.ReceiveOne(out length));
                }
                MyPacketData data1 = new MyPacketData();
                data1.Data                = this.m_largePacket;
                data1.BitStream           = new BitStream(0);
                data1.ByteStream          = new ByteStream();
                item                      = data1;
                byteOffset                = 0;
                length                   -= 8;
                length                    = (uint)(length + ((num3 - 1) * 0xf4240));
                this.m_largePacketCounter = 0;
                this.m_largePacket        = null;
            }
            item.BitStream.ResetRead(item.Data, byteOffset, (((int)((ulong)length)) - byteOffset) * 8, false);
            item.ByteStream.Reset(item.Data, (int)length);
            item.ByteStream.Position = byteOffset;
            item.ReceivedTime        = MyTimeSpan.FromTicks(Stopwatch.GetTimestamp());
            item.Sender = new Endpoint(num, 0);
            this.m_receiveQueue.Enqueue(item);
            return(ReceiveStatus.Success);
        }
Exemplo n.º 14
0
        public override void UpdateAfter()
        {
            if (!m_clientReady || !m_hasTypeTable || ClientState == null)
            {
                return;
            }

            NetProfiler.Begin("Replication client update", 0);

            var simulationTime = m_callback.GetUpdateTime();

            if (m_clientStartTimeStamp == MyTimeSpan.Zero)
            {
                m_clientStartTimeStamp = simulationTime; // (uint)DateTime.Now.TimeOfDay.TotalMilliseconds;
            }
            var timeStamp = simulationTime - m_clientStartTimeStamp;

            UpdatePingSmoothing();
            NetProfiler.CustomTime("Ping", (float)m_ping.Milliseconds, "{0} ms");
            NetProfiler.CustomTime("SmoothPing", (float)m_smoothPing.Milliseconds, "{0} ms");

            NetProfiler.Begin("Packet stats");
            NetProfiler.CustomTime("Server Drops", (float)m_serverStats.Drops, "{0}");
            NetProfiler.CustomTime("Server OutOfOrder", (float)m_serverStats.OutOfOrder, "{0}");
            NetProfiler.CustomTime("Server Duplicates", (float)m_serverStats.Duplicates, "{0}");
            NetProfiler.CustomTime("Client Drops", (float)m_clientStatsFromServer.Drops, "{0}");
            NetProfiler.CustomTime("Client OutOfOrder", (float)m_clientStatsFromServer.OutOfOrder, "{0}");
            NetProfiler.CustomTime("Client Duplicates", (float)m_clientStatsFromServer.Duplicates, "{0}");
            m_serverStats.Reset();
            m_clientStatsFromServer.Reset();
            NetProfiler.End();

            MyTimeSpan ping = UseSmoothPing ? m_smoothPing : m_ping;
            var        diffCorrection = -ping.Milliseconds * m_callback.GetServerSimulationRatio();
            var        diffMS = timeStamp.Milliseconds - m_lastServerTimeStamp.Milliseconds;
            var        correctionCurrent = diffMS + diffCorrection;
            int        correction = 0, nextFrameDelta = 0;
            MyTimeSpan currentTime   = MyTimeSpan.FromTicks(Stopwatch.GetTimestamp());
            MyTimeSpan realtimeDelta = currentTime - m_lastTime;

            // try to be always one simulation step ahead
            correctionCurrent -= m_simulationTimeStep;
            //if (Math.Abs(correctionCurrent) > 200)
            //  m_correctionSmooth = MyTimeSpan.FromMilliseconds(correctionCurrent);
            correctionCurrent = Math.Min(correctionCurrent, (int)(m_simulationTimeStep * 2 / m_callback.GetServerSimulationRatio()));

            if (diffMS < -MAX_TIMESTAMP_DIFF_LOW || diffMS > MAX_TIMESTAMP_DIFF_HIGH)
            {
                m_clientStartTimeStamp = MyTimeSpan.FromMilliseconds(m_clientStartTimeStamp.Milliseconds + diffMS);

                timeStamp          = simulationTime - m_clientStartTimeStamp;
                m_correctionSmooth = MyTimeSpan.Zero;
                TimestampReset();
                if (VRage.MyCompilationSymbols.EnableNetworkPositionTracking)
                {
                    Trace.MyTrace.Send(Trace.TraceWindow.MTiming, "---------------------------------------------------------------- DESYNC");
                }
            }
            else
            {
                var factor = Math.Min(realtimeDelta.Seconds / SmoothCorrectionAmplitude, 1.0);
                m_correctionSmooth = MyTimeSpan.FromMilliseconds(correctionCurrent * factor + m_correctionSmooth.Milliseconds * (1 - factor));
                // special case: we really dont want the client timestamp to fall behind
                if (diffMS < 0)
                {
                    correction = (int)correctionCurrent;
                }
                else
                {
                    correction = UseSmoothCorrection ? (int)m_correctionSmooth.Milliseconds : (int)correctionCurrent;
                }

                NetProfiler.CustomTime("Correction", (float)correctionCurrent, "{0} ms");
                NetProfiler.CustomTime("SmoothCorrection", (float)m_correctionSmooth.Milliseconds, "{0} ms");

                if (ApplyCorrectionsDebug && (LastMessageFromServer - DateTime.UtcNow).Seconds < 1.0f)
                {
                    if (diffMS < 0)
                    {
                        nextFrameDelta = correction;
                        m_callback.SetNextFrameDelayDelta(nextFrameDelta);
                    }
                    else if (Math.Abs(correction) > TimestampCorrectionMinimum)
                    {
                        nextFrameDelta = (Math.Abs(correction) - TimestampCorrectionMinimum) * Math.Sign(correction);
                        m_callback.SetNextFrameDelayDelta(nextFrameDelta);
                    }
                }
            }
            NetProfiler.CustomTime("GameTimeDelta", (float)(timeStamp - Timestamp).Milliseconds, "{0} ms");
            NetProfiler.CustomTime("RealTimeDelta", (float)realtimeDelta.Milliseconds, "{0} ms");
            Timestamp = timeStamp;

            //if (VRage.MyCompilationSymbols.EnableNetworkPositionTracking)
            {
                string trace = "realtime delta: " + realtimeDelta +
                               ", client: " + Timestamp +
                               ", server: " + m_lastServerTimeStamp +
                               ", diff: " + diffMS.ToString("##.#") + " => " + (Timestamp.Milliseconds - m_lastServerTimeStamp.Milliseconds).ToString("##.#") +
                               ", Ping: " + m_ping.Milliseconds.ToString("##.#") + " / " + m_smoothPing.Milliseconds.ToString("##.#") +
                               "ms, Correction " + correctionCurrent + " / " + m_correctionSmooth.Milliseconds + " / " + nextFrameDelta +
                               ", ratio " + m_callback.GetServerSimulationRatio();
                Trace.MyTrace.Send(Trace.TraceWindow.MTiming, trace);
                //Trace.MyTrace.Send(Trace.TraceWindow.MPositions2, trace);
            }
            m_lastTime = currentTime;

            NetProfiler.End();

            if (StressSleep.X > 0)
            {
                int sleep;
                if (StressSleep.Z == 0)
                {
                    sleep = MyRandom.Instance.Next(StressSleep.X, StressSleep.Y);
                }
                else
                {
                    sleep = (int)(Math.Sin(simulationTime.Milliseconds * Math.PI / StressSleep.Z) * StressSleep.Y + StressSleep.X);
                }
                System.Threading.Thread.Sleep(sleep);
            }
        }