Avoid rewinds on the server (which would create a big chaos since state
updated would be duplicated etc). Instead it will move 'past' events to the current time, causing only a 'jump' in the one client causing the event (instead of all).
This commit is contained in:
parent
40bdb4d777
commit
9b4f773703
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "network/rewind_info.hpp"
|
#include "network/rewind_info.hpp"
|
||||||
|
|
||||||
|
#include "network/network_config.hpp"
|
||||||
#include "physics/physics.hpp"
|
#include "physics/physics.hpp"
|
||||||
|
|
||||||
/** Constructor for a state: it only takes the size, and allocates a buffer
|
/** Constructor for a state: it only takes the size, and allocates a buffer
|
||||||
@ -30,6 +31,18 @@ RewindInfo::RewindInfo(float time, bool is_confirmed)
|
|||||||
m_is_confirmed = is_confirmed;
|
m_is_confirmed = is_confirmed;
|
||||||
} // RewindInfo
|
} // RewindInfo
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Adjusts the time of this RewindInfo. This is only called on the server
|
||||||
|
* in case that an event is received in the past - in this case the server
|
||||||
|
* needs to avoid a Rewind by moving this event forward to the current time.
|
||||||
|
*/
|
||||||
|
void RewindInfo::setTime(float time)
|
||||||
|
{
|
||||||
|
assert(NetworkConfig::get()->isServer());
|
||||||
|
assert(m_time < time);
|
||||||
|
m_time = time;
|
||||||
|
} // setTime
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
RewindInfoState::RewindInfoState(float time, Rewinder *rewinder,
|
RewindInfoState::RewindInfoState(float time, Rewinder *rewinder,
|
||||||
BareNetworkString *buffer, bool is_confirmed)
|
BareNetworkString *buffer, bool is_confirmed)
|
||||||
|
@ -62,7 +62,7 @@ public:
|
|||||||
/** This is called while going forwards in time again to reach current
|
/** This is called while going forwards in time again to reach current
|
||||||
* time. */
|
* time. */
|
||||||
virtual void rewind() = 0;
|
virtual void rewind() = 0;
|
||||||
|
void setTime(float time);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual ~RewindInfo() { }
|
virtual ~RewindInfo() { }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "config/stk_config.hpp"
|
#include "config/stk_config.hpp"
|
||||||
#include "modes/world.hpp"
|
#include "modes/world.hpp"
|
||||||
|
#include "network/network_config.hpp"
|
||||||
#include "network/rewind_info.hpp"
|
#include "network/rewind_info.hpp"
|
||||||
#include "network/rewind_manager.hpp"
|
#include "network/rewind_manager.hpp"
|
||||||
#include "network/time_step_info.hpp"
|
#include "network/time_step_info.hpp"
|
||||||
@ -231,13 +232,16 @@ void RewindQueue::addNetworkState(Rewinder *rewinder, BareNetworkString *buffer,
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Merges thread-safe all data received from the network with the current
|
/** Merges thread-safe all data received from the network with the current
|
||||||
* local rewind information.
|
* local rewind information.
|
||||||
* \param world_time Current world time up to which network events will be
|
* \param world_time[in] Current world time up to which network events will be
|
||||||
* merged in.
|
* merged in.
|
||||||
* \param needs_rewind True if network rewind information was received which
|
* \param dt[in] Time step size. The current frame will cover events between
|
||||||
* was in the past (of this simulation), so a rewind must be performed.
|
* world_time and world_time+dt.
|
||||||
* \param rewind_time If needs_rewind is true, the time to which a rewind must
|
* \param needs_rewind[out] True if network rewind information was received
|
||||||
* be performed (at least). Otherwise undefined, but the value might
|
* which was in the past (of this simulation), so a rewind must be
|
||||||
* be modified in this function.
|
* performed.
|
||||||
|
* \param rewind_time[out] If needs_rewind is true, the time to which a rewind
|
||||||
|
* must be performed (at least). Otherwise undefined, but the value
|
||||||
|
* might be modified in this function.
|
||||||
*/
|
*/
|
||||||
void RewindQueue::mergeNetworkData(float world_time, float dt,
|
void RewindQueue::mergeNetworkData(float world_time, float dt,
|
||||||
bool *needs_rewind, float *rewind_time)
|
bool *needs_rewind, float *rewind_time)
|
||||||
@ -266,6 +270,19 @@ void RewindQueue::mergeNetworkData(float world_time, float dt,
|
|||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// A server never rewinds (otherwise we would have to handle
|
||||||
|
// duplicated states, which in the best case would then have
|
||||||
|
// a negative effect for every player, when in fact only one
|
||||||
|
// player might have a network hickup).
|
||||||
|
if (NetworkConfig::get()->isServer() && (*i)->getTime() < world_time)
|
||||||
|
{
|
||||||
|
Log::warn("RewindQueue", "At %f received message from %f",
|
||||||
|
world_time, (*i)->getTime());
|
||||||
|
// Server received an event in the past. Adjust this event
|
||||||
|
// to be done now - at least we get a bit closer to the
|
||||||
|
// client state.
|
||||||
|
(*i)->setTime(world_time);
|
||||||
|
}
|
||||||
|
|
||||||
// Find closest previous time step.
|
// Find closest previous time step.
|
||||||
AllTimeStepInfo::iterator prev =
|
AllTimeStepInfo::iterator prev =
|
||||||
@ -279,7 +296,7 @@ void RewindQueue::mergeNetworkData(float world_time, float dt,
|
|||||||
|
|
||||||
// Assign this event to the closest of the two existing timesteps
|
// Assign this event to the closest of the two existing timesteps
|
||||||
// prev and next (inserting an additional event in the past would
|
// prev and next (inserting an additional event in the past would
|
||||||
// mean more CPU work in the rewind this will very likely trigger.
|
// mean more CPU work in the rewind this will very likely trigger).
|
||||||
if (next == m_time_step_info.end())
|
if (next == m_time_step_info.end())
|
||||||
tsi = *prev;
|
tsi = *prev;
|
||||||
else if ( (*next)->getTime()-event_time < event_time-(*prev)->getTime() )
|
else if ( (*next)->getTime()-event_time < event_time-(*prev)->getTime() )
|
||||||
|
Loading…
Reference in New Issue
Block a user