Exemple #1
0
        private void UpdateInternal()
        {
            MyStatToken token;

            MySimpleProfiler.BeginBlock("UpdateFrame", MySimpleProfiler.ProfilingBlockType.INTERNAL);
            using (token = Stats.Generic.Measure("BeforeUpdate"))
            {
                MyRenderProxy.BeforeUpdate();
            }
            this.m_totalTime      = this.m_gameTimer.Elapsed;
            this.m_updateCounter += (ulong)1L;
            if (MySession.Static != null)
            {
                this.m_simulationTimeWithSpeed += MyTimeSpan.FromMilliseconds(16.666666666666668 * MyFakes.SIMULATION_SPEED);
            }
            bool enableNetworkPacketTracking = MyCompilationSymbols.EnableNetworkPacketTracking;

            this.Update();
            if (!IsDedicated)
            {
                this.PrepareForDraw();
            }
            using (token = Stats.Generic.Measure("AfterUpdate"))
            {
                this.AfterDraw();
            }
            MySimpleProfiler.End("UpdateFrame");
            MySimpleProfiler.Commit();
        }
Exemple #2
0
 public override void PrepareForDraw()
 {
     base.PrepareForDraw();
     if (MyDebugDrawSettings.DEBUG_DRAW_GRID_DIRTY_BLOCKS)
     {
         MyTimeSpan span = MyTimeSpan.FromMilliseconds(1500.0);
         using (this.m_tmpRemoveList.GetClearToken <Vector3I>())
         {
             foreach (KeyValuePair <Vector3I, MyTimeSpan> pair in this.m_dirtyBlocks)
             {
                 if ((MySandboxGame.Static.TotalTime - pair.Value) > span)
                 {
                     this.m_tmpRemoveList.Add(pair.Key);
                 }
             }
             foreach (Vector3I vectori in this.m_tmpRemoveList)
             {
                 this.m_dirtyBlocks.Remove(vectori);
             }
         }
         foreach (Vector3I vectori2 in this.m_cubeGrid.DirtyBlocks)
         {
             this.m_dirtyBlocks[vectori2] = MySandboxGame.Static.TotalTime;
         }
     }
 }
Exemple #3
0
        public override void PrepareForDraw()
        {
            base.PrepareForDraw();

            if (MyDebugDrawSettings.DEBUG_DRAW_GRID_DIRTY_BLOCKS)
            {
                MyTimeSpan delay = MyTimeSpan.FromMilliseconds(1500);
                using (m_tmpRemoveList.GetClearToken())
                {
                    foreach (var b in m_dirtyBlocks)
                    {
                        if ((MySandboxGame.Static.UpdateTime - b.Value) > delay)
                        {
                            m_tmpRemoveList.Add(b.Key);
                        }
                    }
                    foreach (var b in m_tmpRemoveList)
                    {
                        m_dirtyBlocks.Remove(b);
                    }
                }

                foreach (var block in m_cubeGrid.DirtyBlocks)
                {
                    m_dirtyBlocks[block] = MySandboxGame.Static.UpdateTime;
                }
            }
        }
Exemple #4
0
        public void Draw([CallerMemberName] string member = "", [CallerLineNumber] int line = 0, [CallerFilePath] string file = "")
        {
            if (!m_enabled)
            {
                return;
            }

            var profiler = ThreadProfiler;

            profiler.Stopwatch.Restart();

            var drawProfiler = m_selectedProfiler;

            if (drawProfiler != null)
            {
                int lastFrameIndex;
                using (drawProfiler.LockHistory(out lastFrameIndex))
                {
                    int frameToDraw = m_useCustomFrame ? m_selectedFrame : lastFrameIndex;
                    Draw(drawProfiler, lastFrameIndex, frameToDraw);
                }

                profiler.ProfileCustomValue("Profiler.Draw", member, line, file, 0, MyTimeSpan.FromMilliseconds(profiler.Stopwatch.Elapsed.TotalMilliseconds), null, null);
            }
        }
Exemple #5
0
        public void ReadAndClear(MyTimeSpan currentTime, out Value sum, out int count, out Value min, out Value max, out Value last, out MyStatTypeEnum type, out int decimals, out MyTimeSpan inactivityMs)
        {
            Lock.Enter();
            try
            {
                inactivityMs = MyTimeSpan.Zero;

                if (Count <= 0) // Nothing was written
                {
                    // Load delta, increment it and save it
                    var delta = IntToDeltaTime(-Count);
                    delta += Count < 0 ? currentTime - LastClear : MyTimeSpan.FromMilliseconds(1);
                    Count  = -DeltaTimeToInt(delta);

                    inactivityMs = delta;
                    LastClear    = currentTime; // Nothing was written, postpone clear
                }
                else
                {
                    if (currentTime >= (LastRefresh + MyTimeSpan.FromMilliseconds(RefreshRate)))
                    {
                        DrawSum     = Sum;
                        DrawCount   = Count;
                        DrawMin     = Min;
                        DrawMax     = Max;
                        DrawLast    = Last;
                        LastRefresh = currentTime;

                        if (ClearRate == -1) // Clear with refresh
                        {
                            Count = 0;
                            ClearUnsafe();
                        }
                    }

                    if (ClearRate != -1 && currentTime >= (LastClear + MyTimeSpan.FromMilliseconds(ClearRate)))
                    {
                        Count = 0;
                        ClearUnsafe();
                        LastClear = currentTime;
                    }
                }

                type     = Type;
                decimals = NumDecimals;
            }
            finally
            {
                Lock.Exit();
            }

            // No need lock, not accessed anywhere else outside read
            sum   = DrawSum;
            count = DrawCount;
            min   = DrawMin;
            max   = DrawMax;
            last  = DrawLast;
        }
        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;
        }
Exemple #7
0
        public void SubmitWork(MyObjectBuilder_EntityBase objectBuilder, bool addToScene, Action <MyEntity> doneHandler, MyEntity entity = null, byte waitGroup = 0, double serializationTimestamp = 0.0, bool fadeIn = false)
        {
            Item item = new Item {
                ObjectBuilder          = objectBuilder,
                AddToScene             = addToScene,
                DoneHandler            = doneHandler,
                Result                 = entity,
                WaitGroup              = waitGroup,
                SerializationTimestamp = MyTimeSpan.FromMilliseconds(serializationTimestamp),
                FadeIn                 = fadeIn
            };

            this.SubmitWork(item);
        }
Exemple #8
0
        public void Commit([CallerMemberName] string member = "", [CallerLineNumber] int line = 0, [CallerFilePath] string file = "")
        {
            var profiler = ThreadProfiler;

            profiler.Stopwatch.Restart();
            if (!Paused)
            {
                profiler.CommitFrame();
                m_useCustomFrame = true;
            }
            else
            {
                profiler.ClearFrame();
            }
            profiler.ProfileCustomValue("Profiler.Commit", member, line, file, 0, MyTimeSpan.FromMilliseconds(profiler.Stopwatch.ElapsedMilliseconds), null, null);
        }
        protected MyBehaviorTreeState TryReserveAreaAroundEntity([BTParam] string areaName, [BTParam] float radius, [BTParam] int timeMs)
        {
            var logic = Bot.HumanoidLogic;
            MyBehaviorTreeState retStatus = MyBehaviorTreeState.FAILURE;

            if (logic != null)
            {
                switch (logic.ReservationStatus)
                {
                case Logic.MyReservationStatus.NONE:
                    logic.ReservationStatus   = Logic.MyReservationStatus.WAITING;
                    logic.ReservationAreaData = new MyAiTargetManager.ReservedAreaData()
                    {
                        WorldPosition    = Bot.HumanoidEntity.WorldMatrix.Translation,
                        Radius           = radius,
                        ReservationTimer = MyTimeSpan.FromMilliseconds(timeMs),
                        ReserverId       = new World.MyPlayer.PlayerId(Bot.Player.Id.SteamId, Bot.Player.Id.SerialId)
                    };
                    MyAiTargetManager.OnAreaReservationResult += AreaReservationHandler;
                    MyAiTargetManager.Static.RequestAreaReservation(areaName, Bot.HumanoidEntity.WorldMatrix.Translation, radius, timeMs, Bot.Player.Id.SerialId);
                    m_reservationTimeOut    = MySandboxGame.Static.UpdateTime + MyTimeSpan.FromSeconds(RESERVATION_WAIT_TIMEOUT_SECONDS);
                    logic.ReservationStatus = Logic.MyReservationStatus.WAITING;
                    retStatus = MyBehaviorTreeState.RUNNING;
                    break;

                case Logic.MyReservationStatus.SUCCESS:
                    retStatus = MyBehaviorTreeState.SUCCESS;
                    break;

                case Logic.MyReservationStatus.FAILURE:
                    retStatus = MyBehaviorTreeState.FAILURE;
                    break;

                case Logic.MyReservationStatus.WAITING:
                    if (m_reservationTimeOut < MySandboxGame.Static.UpdateTime)
                    {
                        retStatus = MyBehaviorTreeState.FAILURE;
                    }
                    else
                    {
                        retStatus = MyBehaviorTreeState.RUNNING;
                    }
                    break;
                }
            }
            return(retStatus);
        }
Exemple #10
0
        protected MyBehaviorTreeState TryReserveAreaAroundEntity([BTParam] string areaName, [BTParam] float radius, [BTParam] int timeMs)
        {
            MyHumanoidBotLogic  humanoidLogic = this.Bot.HumanoidLogic;
            MyBehaviorTreeState fAILURE       = MyBehaviorTreeState.FAILURE;

            if (humanoidLogic != null)
            {
                switch (humanoidLogic.ReservationStatus)
                {
                case MyReservationStatus.NONE:
                {
                    humanoidLogic.ReservationStatus = MyReservationStatus.WAITING;
                    MyAiTargetManager.ReservedAreaData data = new MyAiTargetManager.ReservedAreaData {
                        WorldPosition    = this.Bot.HumanoidEntity.WorldMatrix.Translation,
                        Radius           = radius,
                        ReservationTimer = MyTimeSpan.FromMilliseconds((double)timeMs),
                        ReserverId       = new MyPlayer.PlayerId(this.Bot.Player.Id.SteamId, this.Bot.Player.Id.SerialId)
                    };
                    humanoidLogic.ReservationAreaData          = data;
                    MyAiTargetManager.OnAreaReservationResult += new Sandbox.Game.AI.MyAiTargetManager.AreaReservationHandler(this.AreaReservationHandler);
                    MyAiTargetManager.Static.RequestAreaReservation(areaName, this.Bot.HumanoidEntity.WorldMatrix.Translation, radius, (long)timeMs, this.Bot.Player.Id.SerialId);
                    this.m_reservationTimeOut       = MySandboxGame.Static.TotalTime + MyTimeSpan.FromSeconds(3.0);
                    humanoidLogic.ReservationStatus = MyReservationStatus.WAITING;
                    fAILURE = MyBehaviorTreeState.RUNNING;
                    break;
                }

                case MyReservationStatus.WAITING:
                    fAILURE = (this.m_reservationTimeOut >= MySandboxGame.Static.TotalTime) ? MyBehaviorTreeState.RUNNING : MyBehaviorTreeState.FAILURE;
                    break;

                case MyReservationStatus.SUCCESS:
                    fAILURE = MyBehaviorTreeState.SUCCESS;
                    break;

                case MyReservationStatus.FAILURE:
                    fAILURE = MyBehaviorTreeState.FAILURE;
                    break;

                default:
                    break;
                }
            }
            return(fAILURE);
        }
Exemple #11
0
 public static void OnCharacterParentChangeTimeOut(double delay)
 {
     MyCharacterPhysicsStateGroup.ParentChangeTimeOut = MyTimeSpan.FromMilliseconds(delay);
 }
Exemple #12
0
        private static void OnReserveAreaRequest(string reservationName, Vector3D position, float radius, long reservationTimeMs, int senderSerialId)
        {
            EndpointId sender;
            Vector3D?  nullable;

            if (MyEventContext.Current.IsLocallyInvoked)
            {
                sender = new EndpointId(Sync.MyId);
            }
            else
            {
                sender = MyEventContext.Current.Sender;
            }
            if (!m_reservedAreas.ContainsKey(reservationName))
            {
                m_reservedAreas.Add(reservationName, new Dictionary <long, ReservedAreaData>());
            }
            Dictionary <long, ReservedAreaData> dictionary = m_reservedAreas[reservationName];
            bool flag = false;

            MyPlayer.PlayerId id2 = new MyPlayer.PlayerId(sender.Value, senderSerialId);
            foreach (KeyValuePair <long, ReservedAreaData> pair in dictionary)
            {
                ReservedAreaData data    = pair.Value;
                Vector3D         vectord = data.WorldPosition - position;
                if (vectord.LengthSquared() <= (data.Radius * data.Radius))
                {
                    flag = true;
                    break;
                }
            }
            if (flag)
            {
                if (MyEventContext.Current.IsLocallyInvoked)
                {
                    OnReserveAreaFailure(position, radius, senderSerialId);
                }
                else
                {
                    nullable = null;
                    MyMultiplayer.RaiseStaticEvent <Vector3D, float, int>(s => new Action <Vector3D, float, int>(MyAiTargetManager.OnReserveAreaFailure), position, radius, senderSerialId, sender, nullable);
                }
            }
            else
            {
                AreaReservationCounter += 1L;
                ReservedAreaData data2 = new ReservedAreaData {
                    WorldPosition    = position,
                    Radius           = radius,
                    ReservationTimer = MySandboxGame.Static.TotalTime + MyTimeSpan.FromMilliseconds((double)reservationTimeMs),
                    ReserverId       = id2
                };
                dictionary[AreaReservationCounter] = data2;
                EndpointId targetEndpoint = new EndpointId();
                nullable = null;
                MyMultiplayer.RaiseStaticEvent <long, string, Vector3D, float>(s => new Action <long, string, Vector3D, float>(MyAiTargetManager.OnReserveAreaAllSuccess), AreaReservationCounter, reservationName, position, radius, targetEndpoint, nullable);
                if (MyEventContext.Current.IsLocallyInvoked)
                {
                    OnReserveAreaSuccess(position, radius, senderSerialId);
                }
                else
                {
                    nullable = null;
                    MyMultiplayer.RaiseStaticEvent <Vector3D, float, int>(s => new Action <Vector3D, float, int>(MyAiTargetManager.OnReserveAreaSuccess), position, radius, senderSerialId, sender, nullable);
                }
            }
        }
Exemple #13
0
 static MyTimeSpan?ToTime(this float customTime)
 {
     return(MyTimeSpan.FromMilliseconds(customTime));
 }
        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);
            }
        }
        //List<byte> m_alreadyReceivedPackets = new List<byte>();


        /// <summary>
        /// Processes state sync sent by server.
        /// </summary>
        public void ProcessStateSync(MyPacket packet)
        {
            LastMessageFromServer = DateTime.UtcNow;
            // Simulated packet loss
            // if (MyRandom.Instance.NextFloat() > 0.3f) return;

            ReceiveStream.ResetRead(packet);
            bool isStreaming = ReceiveStream.ReadBool();

            var packetId = ReceiveStream.ReadByte();

            //if (m_alreadyReceivedPackets.Contains(packetId))
            //{
            //}
            //if (m_alreadyReceivedPackets.Count > 128)
            //    m_alreadyReceivedPackets.RemoveAt(0);
            //m_alreadyReceivedPackets.Add(packetId);

            var serverOrder = m_serverTracker.Add(packetId);

            m_serverStats.Update(serverOrder);
            if (serverOrder == MyPacketTracker.OrderType.Duplicate)
            {
                return;
            }
            m_lastStateSyncPacketId = packetId;

            MyPacketStatistics stats = new MyPacketStatistics();

            stats.Read(ReceiveStream);
            m_clientStatsFromServer.Add(stats);

            var serverTimeStamp = MyTimeSpan.FromMilliseconds(ReceiveStream.ReadDouble());

            if (m_lastServerTimeStamp < serverTimeStamp)
            {
                m_lastServerTimeStamp = serverTimeStamp;
            }

            double lastClientRealtime = ReceiveStream.ReadDouble();

            if (lastClientRealtime > 0)
            {
                var ping = packet.ReceivedTime - MyTimeSpan.FromMilliseconds(lastClientRealtime);
                if (ping.Milliseconds < 1000)
                {
                    SetPing(ping);
                }
            }

            MyTimeSpan relevantTimeStamp = serverTimeStamp;

            m_callback.ReadCustomState(ReceiveStream);

            while (ReceiveStream.BytePosition < ReceiveStream.ByteLength)
            {
                NetworkId     networkID = ReceiveStream.ReadNetworkId();
                IMyStateGroup obj       = GetObjectByNetworkId(networkID) as IMyStateGroup;

                if (obj == null)
                {
                    if (isStreaming == false)
                    {
                        Debug.Fail("IMyStateGroup not found by NetworkId");
                        break;
                    }
                    else
                    {
                        return;
                    }
                }

                if (isStreaming && obj.GroupType != StateGroupEnum.Streaming)
                {
                    Debug.Fail("group type mismatch !");
                    MyLog.Default.WriteLine("received streaming flag but group is not streaming !");
                    return;
                }

                if (!isStreaming && obj.GroupType == StateGroupEnum.Streaming)
                {
                    Debug.Fail("group type mismatch !");
                    MyLog.Default.WriteLine("received non streaming flag but group wants to stream !");
                    return;
                }

                if (VRage.MyCompilationSymbols.EnableNetworkPacketTracking)
                {
                    Trace.MyTrace.Send(Trace.TraceWindow.MPackets, " ObjSync: " + obj.GetType().Name);
                }

                var pos = ReceiveStream.BytePosition;
                NetProfiler.Begin(obj.GetType().Name);
                obj.Serialize(ReceiveStream, ClientState.EndpointId, relevantTimeStamp, m_lastStateSyncPacketId, 0);
                NetProfiler.End(ReceiveStream.ByteLength - pos);

                if (!m_acks.Contains(m_lastStateSyncPacketId))
                {
                    m_acks.Add(m_lastStateSyncPacketId);
                }
            }
        }
Exemple #16
0
        private MySnapshotHistory.MyItem UpdateFromServerQueue(MyTimeSpan clientTimestamp, MyPredictedSnapshotSyncSetup setup)
        {
            bool recalc     = false;
            var  serverItem = m_receivedQueue.GetItem(clientTimestamp);

            if (serverItem.Valid)
            {
                if (serverItem.Timestamp != m_lastServerTimestamp)
                {
                    var item = m_clientHistory.Get(serverItem.Timestamp, MyTimeSpan.Zero);
                    if (item.Valid && (item.Type == MySnapshotHistory.SnapshotType.Exact || item.Type == MySnapshotHistory.SnapshotType.Interpolation))
                    {
                        m_lastServerTimestamp = serverItem.Timestamp;
                        m_receivedQueue.Prune(clientTimestamp, MyTimeSpan.Zero, 3);
                        m_clientHistory.Prune(serverItem.Timestamp, MyTimeSpan.Zero, 10);

                        MySnapshot delta;
                        if (!serverItem.Snapshot.Active && !setup.IsControlled)
                        {
                            var currentSnapshot = new MySnapshot(m_entity);
                            delta = serverItem.Snapshot.Diff(currentSnapshot);
                            Reset();
                        }
                        else
                        {
                            delta = serverItem.Snapshot.Diff(item.Snapshot);
                        }
                        if (m_lastServerVelocity.IsValid())
                        {
                            var deltaVelocity = serverItem.Snapshot.LinearVelocity - m_lastServerVelocity;
                            m_lastServerVelocity = serverItem.Snapshot.LinearVelocity;

                            var deltaVelocityLengthSqr = deltaVelocity.LengthSquared();
                            if (m_stopSuspected > 0)
                            {
                                var currentSnapshot     = new MySnapshot(m_entity);
                                var maxVelocityDeltaSqr = (MinVelocityChangeToReset / 2) * (MinVelocityChangeToReset / 2);
                                if ((serverItem.Snapshot.LinearVelocity - currentSnapshot.LinearVelocity).LengthSquared() > maxVelocityDeltaSqr)
                                {
                                    Reset();
                                    delta           = serverItem.Snapshot.Diff(currentSnapshot);
                                    m_stopSuspected = 0;
                                }
                            }
                            if (deltaVelocityLengthSqr > (MinVelocityChangeToReset * MinVelocityChangeToReset))
                            {
                                m_stopSuspected = 10;
                                if (MyCompilationSymbols.EnableNetworkPositionTracking)
                                {
                                    VRage.Trace.MyTrace.Send(VRage.Trace.TraceWindow.MPositions3, "!!!!!!!!!!!!!!!!!!! sudden server velocity change (" + m_entity.DisplayName + "): " + Math.Sqrt(deltaVelocityLengthSqr));
                                }
                            }
                            else if (m_stopSuspected > 0)
                            {
                                m_stopSuspected--;
                            }
                        }
                        else
                        {
                            m_lastServerVelocity = serverItem.Snapshot.LinearVelocity;
                        }
                        if (m_wasReset)
                        {
                            delta.Position     += serverItem.Snapshot.LinearVelocity * (float)(clientTimestamp - serverItem.Timestamp).Seconds;
                            m_wasReset          = false;
                            serverItem.Snapshot = delta;
                            serverItem.Type     = MySnapshotHistory.SnapshotType.Reset;
                            return(serverItem);
                        }

                        /*{
                         *  var lvsqr = delta.LinearVelocity.LengthSquared();
                         *  var maxLinearFactorSqr = setup.MaxLinearFactor * setup.MaxLinearFactor;
                         *  var maxLinVel = MaxLinearVelocityDelta * MaxLinearVelocityDelta * maxLinearFactorSqr;
                         *  if (lvsqr > maxLinVel)
                         *  {
                         *      var similarItem = m_clientHistory.GetSimilar(serverItem.Timestamp, serverItem.Snapshot.LinearVelocity);
                         *      if (similarItem.Valid)
                         *      {
                         *          var newDelta = serverItem.Snapshot.LinearVelocity - similarItem.Snapshot.LinearVelocity;
                         *          if (newDelta.LengthSquared() < maxLinVel)
                         *          {
                         *              if (MyCompilationSymbols.EnableNetworkClientControlledTracking)
                         *                  if (m_entity.DisplayName.Contains(m_trackName))
                         *                      VRage.Trace.MyTrace.Send(VRage.Trace.TraceWindow.MPositions3,
                         *                          m_entity.DisplayName + ": old " + newDelta + " new " + delta.LinearVelocity +
                         *                          " ------------------------------------------" +
                         *                          serverItem.Snapshot + " >> " + item.Snapshot + " >> " + similarItem.Snapshot);
                         *              delta.LinearVelocity = Vector3.Zero;
                         *          }
                         *      }
                         *  }
                         * }*/
                        var  serverAngVelSqr         = serverItem.Snapshot.AngularVelocity.LengthSquared();
                        bool anyAngVel               = serverAngVelSqr > 0.001f;
                        var  minLinearVelocityFactor = Math.Max(Math.Min(serverItem.Snapshot.LinearVelocity.LengthSquared() /
                                                                         (ReferenceLinearVelocity * ReferenceLinearVelocity), 1.0f), 0.01f);
                        var minAngularVelocityFactor = Math.Max(Math.Min(serverAngVelSqr /
                                                                         (ReferenceAngularVelocity * ReferenceAngularVelocity), 1.0f), 0.01f);
                        int iterations   = (int)(SmoothTimesteps * setup.IterationsFactor);
                        var maxFactorSqr = setup.MaxPositionFactor * setup.MaxPositionFactor;

                        var anyDelta = setup.ApplyPhysics && setup.ApplyRotation && delta.AngularVelocity.LengthSquared() > 0.00001f;
                        // position
                        {
                            var psqr = delta.Position.LengthSquared();
                            if (psqr > MaxPositionDelta * MaxPositionDelta * maxFactorSqr)
                            {
                                var dir       = delta.Position;
                                var length    = dir.Normalize();
                                var newLength = length - MaxPositionDelta * (1.0f - DeltaFactor);
                                delta.Position = dir * newLength;
                                anyDelta       = true;
                                m_animDeltaPositionIterations = 0;
                            }
                            else if (!SmoothPositionCorrection)
                            {
                                delta.Position *= DeltaFactor;
                                anyDelta        = true;
                                m_animDeltaPositionIterations = 0;
                            }
                            else
                            {
                                if (psqr > MinPositionDelta * MinPositionDelta * minLinearVelocityFactor)
                                {
                                    m_animDeltaPositionIterations = iterations;
                                }
                                if (m_animDeltaPositionIterations > 0)
                                {
                                    m_animDeltaPosition          = delta.Position / m_animDeltaPositionIterations;
                                    m_animDeltaPositionTimestamp = serverItem.Timestamp;
                                }
                                delta.Position = Vector3D.Zero;
                            }
                        }
                        // rotation
                        if (setup.ApplyRotation)
                        {
                            Vector3 axis;
                            float   angle;
                            delta.Rotation.GetAxisAngle(out axis, out angle);

                            if (angle > MathHelper.Pi)
                            {
                                axis  = -axis;
                                angle = 2 * MathHelper.Pi - angle;
                            }
                            if (angle > MaxRotationAngle * setup.MaxRotationFactor)
                            {
                                delta.Rotation = Quaternion.CreateFromAxisAngle(axis, angle - MaxRotationAngle * (1.0f - DeltaFactor));
                                anyDelta       = true;
                                m_animDeltaRotationIterations = 0;
                            }
                            else if (!SmoothRotationCorrection)
                            {
                                delta.Rotation = Quaternion.CreateFromAxisAngle(axis, angle * DeltaFactor);
                                anyDelta       = true;
                                m_animDeltaRotationIterations = 0;
                            }
                            else
                            {
                                if (angle > MinRotationAngle * minAngularVelocityFactor)
                                {
                                    m_animDeltaRotationIterations = iterations;
                                }
                                if (m_animDeltaRotationIterations > 0)
                                {
                                    m_animDeltaRotation          = Quaternion.CreateFromAxisAngle(axis, angle / m_animDeltaRotationIterations);
                                    m_animDeltaRotationTimestamp = serverItem.Timestamp;
                                }
                                delta.Rotation = Quaternion.Identity;
                            }
                        }
                        if (setup.ApplyPhysics)
                        {
                            // linear velocity
                            {
                                var lvsqr = delta.LinearVelocity.LengthSquared();
                                if (!SmoothLinearVelocityCorrection)
                                {
                                    delta.LinearVelocity *= DeltaFactor;
                                    anyDelta              = true;
                                    m_animDeltaLinearVelocityIterations = 0;
                                }
                                else
                                {
                                    if (lvsqr > MinLinearVelocityDelta * MinLinearVelocityDelta)
                                    {
                                        m_animDeltaLinearVelocityIterations = iterations;
                                    }
                                    if (m_animDeltaLinearVelocityIterations > 0)
                                    {
                                        m_animDeltaLinearVelocity          = delta.LinearVelocity * DeltaFactor / m_animDeltaLinearVelocityIterations;
                                        m_animDeltaLinearVelocityTimestamp = serverItem.Timestamp;
                                    }
                                    delta.LinearVelocity = Vector3.Zero;
                                }
                            }
                            // angular velocity
                            {
                                var lvsqr = delta.AngularVelocity.LengthSquared();
                                if (!SmoothAngularVelocityCorrection)
                                {
                                    delta.AngularVelocity *= DeltaFactor;
                                    anyDelta = true;
                                    m_animDeltaAngularVelocityIterations = 0;
                                }
                                else
                                {
                                    if (lvsqr > MinAngularVelocityDelta * MinAngularVelocityDelta)
                                    {
                                        m_animDeltaAngularVelocityIterations = iterations;
                                    }
                                    if (m_animDeltaAngularVelocityIterations > 0)
                                    {
                                        m_animDeltaAngularVelocity          = delta.AngularVelocity * DeltaFactor / m_animDeltaAngularVelocityIterations;
                                        m_animDeltaAngularVelocityTimestamp = serverItem.Timestamp;
                                    }
                                    delta.AngularVelocity = Vector3.Zero;
                                }
                            }
                        }

                        if (!SetTransformCorrections)
                        {
                            delta.Position = Vector3D.Zero;
                            delta.Rotation = Quaternion.Identity;
                            m_animDeltaPositionIterations = m_animDeltaRotationIterations = 0;
                        }
                        if (!SetPhysicsCorrections)
                        {
                            delta.LinearVelocity  = Vector3.Zero;
                            delta.AngularVelocity = Vector3.Zero;
                            m_animDeltaLinearVelocityIterations = m_animDeltaAngularVelocityIterations = 0;
                        }

                        if (anyDelta)
                        {
                            if (MyCompilationSymbols.EnableNetworkPositionTracking)
                            {
                                if (m_entity.DisplayName.Contains(m_trackName))
                                {
                                    VRage.Trace.MyTrace.Send(VRage.Trace.TraceWindow.MPositions3,
                                                             m_entity.DisplayName + ": " + serverItem.Snapshot + " >> " + item.Snapshot + " >> " + delta);
                                }
                            }
                        }
                        serverItem.Snapshot = delta;
                        serverItem.Valid    = anyDelta;
                    }
                    else
                    {
                        serverItem.Valid = false;
                        recalc           = m_wasReset;
                        if (!m_wasReset && MyCompilationSymbols.EnableNetworkPositionTracking)
                        {
                            MyTrace.Send(TraceWindow.MPositions3,
                                         "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! " + m_entity.DisplayName + ": " + item.Type);
                        }
                    }
                }
                else
                {
                    serverItem.Valid = false;
                    recalc           = m_wasReset;
                }
            }
            else
            {
                if (!m_receivedQueue.Empty())
                {
                    recalc = true;
                }
                m_clientHistory.Prune(clientTimestamp, MyTimeSpan.FromMilliseconds(1500));
            }
            if (recalc)
            {
                serverItem = m_receivedQueue.Get(clientTimestamp, MyTimeSpan.Zero);
                if (serverItem.Valid && serverItem.Type == MySnapshotHistory.SnapshotType.Exact ||
                    serverItem.Type == MySnapshotHistory.SnapshotType.Interpolation ||
                    serverItem.Type == MySnapshotHistory.SnapshotType.Extrapolation)
                {
                    var currentSnapshot = new MySnapshot(m_entity);
                    var delta           = serverItem.Snapshot.Diff(currentSnapshot);
                    serverItem.Valid    = true;
                    serverItem.Snapshot = delta;
                    serverItem.Type     = MySnapshotHistory.SnapshotType.Reset;
                    return(serverItem);
                }
                else
                {
                    serverItem.Valid = false;
                    if (MyCompilationSymbols.EnableNetworkPositionTracking)
                    {
                        MyTrace.Send(TraceWindow.MPositions3,
                                     "------------------------------------------- " + m_entity.DisplayName + ": " +
                                     m_receivedQueue.ToStringTimestamps() + " / " + serverItem.Type);
                    }
                }
            }
            return(serverItem);
        }
Exemple #17
0
 private MyTimeSpan IntToDeltaTime(int v)
 {
     return(MyTimeSpan.FromMilliseconds(v / 1000.0f));
 }
        private static void OnReserveAreaRequest(string reservationName, Vector3D position, float radius, long reservationTimeMs, int senderSerialId)
        {
            EndpointId sender;

            if (MyEventContext.Current.IsLocallyInvoked)
            {
                sender = new EndpointId(Sync.MyId);
            }
            else
            {
                sender = MyEventContext.Current.Sender;
            }

            if (!m_reservedAreas.ContainsKey(reservationName))
            {
                m_reservedAreas.Add(reservationName, new Dictionary <long, ReservedAreaData>());
            }

            var  reservations      = m_reservedAreas[reservationName];
            bool reservedBySomeone = false;

            MyPlayer.PlayerId requestId = new MyPlayer.PlayerId(sender.Value, senderSerialId);

            foreach (var r in reservations)
            {
                var  currentReservation = r.Value;
                var  sqDist             = (currentReservation.WorldPosition - position).LengthSquared();
                bool inRadius           = sqDist <= currentReservation.Radius * currentReservation.Radius;

                if (inRadius)
                {
                    reservedBySomeone = true;
                    break;
                }
            }

            if (!reservedBySomeone)
            {
                reservations[AreaReservationCounter++] = new ReservedAreaData()
                {
                    WorldPosition    = position,
                    Radius           = radius,
                    ReservationTimer = MySandboxGame.Static.UpdateTime + MyTimeSpan.FromMilliseconds(reservationTimeMs),
                    ReserverId       = requestId,
                };

                MyMultiplayer.RaiseStaticEvent(s => MyAiTargetManager.OnReserveAreaAllSuccess, AreaReservationCounter, reservationName, position, radius);

                if (MyEventContext.Current.IsLocallyInvoked)
                {
                    OnReserveAreaSuccess(position, radius, senderSerialId);
                }
                else
                {
                    MyMultiplayer.RaiseStaticEvent(s => MyAiTargetManager.OnReserveAreaSuccess, position, radius, senderSerialId, sender);
                }
            }
            else
            {
                if (MyEventContext.Current.IsLocallyInvoked)
                {
                    OnReserveAreaFailure(position, radius, senderSerialId);
                }
                else
                {
                    MyMultiplayer.RaiseStaticEvent(s => MyAiTargetManager.OnReserveAreaFailure, position, radius, senderSerialId, sender);
                }
            }
        }
Exemple #19
0
 public static void CustomValue(string name, float value, float customTimeMs, string timeFormat = null, string valueFormat = null, [CallerMemberName] string member = "", [CallerLineNumber] int line = 0, [CallerFilePath] string file = "")
 {
     Profiler.ProfileCustomValue(name, value, MyTimeSpan.FromMilliseconds(customTimeMs), timeFormat, valueFormat, member, line, file);
 }