private static void Postfix()
        {
            if (MPClientExtrapolation.bodies_to_resolve.Count == 0 /* && MPClientExtrapolation.players_to_resolve.Count == 0 */)
            {
                return;
            }

            var amount = MPClientExtrapolation.GetWeaponExtrapolationTime();

            if (amount <= 0f)
            {
                return;
            }

            //foreach (var kvp in MPClientExtrapolation.players_to_resolve) {
            //    var player = kvp.Key;
            //    var velocities = kvp.Value;
            //    player.c_player_ship.c_transform.localPosition = velocities.LocalPosition;
            //    player.c_player_ship.c_transform.rotation = velocities.Rotation;
            //    player.c_player_ship.c_mesh_collider_trans.localPosition = player.c_player_ship.c_transform.localPosition;
            //}

            NetworkSim.PauseAllRigidBodiesExcept(null);

            foreach (var body in MPClientExtrapolation.bodies_to_resolve)
            {
                if (NetworkSim.m_paused_rigid_bodies.ContainsKey(body))
                {
                    var state = NetworkSim.m_paused_rigid_bodies[body];
                    body.isKinematic     = false;
                    body.velocity        = state.m_velocity;
                    body.angularVelocity = state.m_angular_velocity;
                }
            }

            //foreach (var kvp in MPClientExtrapolation.players_to_resolve) {
            //    var player = kvp.Key;
            //    var velocities = kvp.Value;
            //    player.c_player_ship.c_rigidbody.isKinematic = false;
            //    player.c_player_ship.c_rigidbody.velocity = velocities.Velocity;
            //    player.c_player_ship.c_rigidbody.angularVelocity = velocities.AngularVelocity;
            //    player.c_player_ship.c_rigidbody.drag = 0f;
            //}

            Physics.Simulate(amount);

            //foreach (var kvp in MPClientExtrapolation.players_to_resolve) {
            //    var player = kvp.Key;
            //    var velocities = kvp.Value;
            //    player.c_player_ship.c_rigidbody.isKinematic = false;
            //    player.c_player_ship.c_rigidbody.velocity = Vector3.zero;
            //    player.c_player_ship.c_rigidbody.angularVelocity = Vector3.zero;
            //    player.c_player_ship.c_rigidbody.drag = velocities.Drag;
            //}

            NetworkSim.ResumeAllPausedRigidBodies();

            MPClientExtrapolation.bodies_to_resolve.Clear();
            //MPClientExtrapolation.players_to_resolve.Clear();
        }
 private static void Postfix()
 {
     MPClientExtrapolation.InitForMatch();
 }
        // Called per frame, moves ships along their interpolation/extrapolation motions
        public static void updatePlayerPositions()
        {
            float now = Time.time;                        // needs to be the same time source we use for m_last_update_time
            NewPlayerSnapshotToClientMessage msgA = null; // interpolation: start
            NewPlayerSnapshotToClientMessage msgB = null; // interpolation: end, extrapolation start
            float interpolate_factor = 0.0f;              // interpolation: factor in [0,1]
            float delta_t            = 0.0f;
            int   interpolate_ticks  = 0;
            bool  do_interpolation   = false;

            // find out which case we have, and get the relevant snapshot message(s)
            lock (m_last_messages_lock) {
                /*
                 * for (int xxx=0; xxx<m_last_messages_ring_count; xxx++) {
                 *  Debug.LogFormat("having snapshot from {0} represents {1}", m_last_messages_ring[(m_last_messages_ring_pos_last + 4 - xxx)&3].m_timestamp, m_last_update_time - xxx* Time.fixedDeltaTime);
                 * }
                 */
                if (m_last_messages_ring_count < 1)
                {
                    // we do not have any snapshot messages...
                    return;
                }

                // make sure m_last_update_time is up-to-date
                ResyncTime();

                // NOTE: now and m_last_update_time indirectly have timeScale already applied, as they are based on Time.time
                //       we need to adjust just the ping and the mms_ship_max_interpolate_frames offset...
                //       Also note that the server still sends the unscaled velocities.
                delta_t = now + Time.timeScale * MPClientExtrapolation.GetShipExtrapolationTime() - m_last_update_time;
                // if we want interpolation, add this as a _negative_ offset
                // we use delta_t=0  as the base for from which we extrapolate into the future
                delta_t -= (Menus.mms_lag_compensation_ship_added_lag / 1000f) * Time.timeScale;
                // it might sound absurd, but after this point, the Time.fixedDeltaTime is correct
                // and MUST NOT be scaled by timeScale. The data packets do contain 16.67ms of
                // movement each, we already have taken the time dilation into account above...
                // time difference in physics ticks
                float delta_ticks = delta_t / Time.fixedDeltaTime;
                // the number of frames we need to interpolate into
                // <= 0 means no interpolation at all,
                // 1 would mean we use the second most recent and the most recent snapshot, and so on...
                interpolate_ticks = -(int)Mathf.Floor(delta_ticks);
                // do we need to do interpolation?
                do_interpolation = (interpolate_ticks > 0);

                if (do_interpolation)
                {
                    // we need interpolate_ticks + 1 elements in the ring buffer
                    // NOTE: in the code below, the index [(m_last_messages_ring_pos_last + 4 - i) &3]
                    //       effectively acceses the i-ith most recent element (i starting by 0)
                    //       since 4-(i-1) == 4-i+ 1 = 5-i, 5-i references the next older one
                    if (interpolate_ticks < m_last_messages_ring_count)
                    {
                        msgA = m_last_messages_ring[(m_last_messages_ring_pos_last + 4 - interpolate_ticks) & 3];
                        msgB = m_last_messages_ring[(m_last_messages_ring_pos_last + 5 - interpolate_ticks) & 3];
                        interpolate_factor = delta_ticks - Mathf.Floor(delta_ticks);
                    }
                    else
                    {
                        // not enough packets received so far
                        // "extrapolate" into the past
                        do_interpolation = false;
                        // get the oldest snapshot we have
                        msgB = m_last_messages_ring[(m_last_messages_ring_pos_last + 5 - m_last_messages_ring_count) & 3];
                        // offset the time for the extrapolation
                        // delta_t is currently relative to the most recent element we have,
                        // but we need it relative to msgA
                        delta_t += Time.fixedDeltaTime * (m_last_messages_ring_count - 1);
                    }
                }
                else
                {
                    // extrapolation case
                    // use the most recently received snapshot
                    msgB = m_last_messages_ring[m_last_messages_ring_pos_last];
                }
            } // lock
            m_last_frame_time = now;

            /*
             * Debug.LogFormat("At: {0} Setting: {1} IntFrames: {2}, dt: {3}, IntFact {4}",now,Menus.mms_ship_max_interpolate_frames, interpolate_ticks, delta_t, interpolate_factor);
             * if (interpolate_ticks > 0) {
             *  Debug.LogFormat("Using A from {0}", msgA.m_timestamp);
             *  Debug.LogFormat("Using B from {0}", msgB.m_timestamp);
             * } else {
             *  Debug.LogFormat("Using B from {0}", msgB.m_timestamp);
             * }
             */

            // keep statistics
            m_compensation_sum += delta_t;
            m_compensation_count++;
            // NOTE: one can't replace(interpolate_ticks > 0) by do_interpolation here,
            //       because even in the (interpolate_ticks > 0) case the code above could
            //       have reset do_interpolation to false because we technically want
            //       the "extrapolation" into the past thing, but we don't want to count that
            //       as extrapolation...
            m_compensation_interpol_count += (interpolate_ticks > 0)?1:0;
            if (Time.time >= m_compensation_last + 5.0 && m_compensation_count > 0)
            {
                // Debug.LogFormat("ship lag compensation over last {0} frames: {1}ms / {2} physics ticks, {3} interpolation ({4}%) packets: {5} received / {6} missing / {7} old ignored",
                //                 m_compensation_count, 1000.0f* (m_compensation_sum/ m_compensation_count),
                //                 (m_compensation_sum/m_compensation_count)/Time.fixedDeltaTime,
                //                 m_compensation_interpol_count,
                //                 100.0f*((float)m_compensation_interpol_count/(float)m_compensation_count),
                //                 m_received_packets_count, m_missing_packets_count, m_ignored_packets_count);
                m_compensation_sum            = 0.0f;
                m_compensation_count          = 0;
                m_compensation_interpol_count = 0;
                m_received_packets_count      = 0;
                m_missing_packets_count       = 0;
                m_ignored_packets_count       = 0;
                m_compensation_last           = Time.time;
            }

            // actually apply the operation to each player
            foreach (Player player in Overload.NetworkManager.m_Players)
            {
                if (player != null && !player.isLocalPlayer && !player.m_spectator)
                {
                    // do the actual interpolation or extrapolation, as calculated above
                    if (do_interpolation)
                    {
                        NewPlayerSnapshot A = GetPlayerSnapshot(msgA, player);
                        NewPlayerSnapshot B = GetPlayerSnapshot(msgB, player);
                        if (A != null && B != null)
                        {
                            interpolatePlayer(player, A, B, interpolate_factor);
                        }
                    }
                    else
                    {
                        NewPlayerSnapshot snapshot = GetPlayerSnapshot(msgB, player);
                        if (snapshot != null)
                        {
                            extrapolatePlayer(player, snapshot, delta_t);
                        }
                    }
                }
            }
        }