Save an initial state at t=0 on the client, to make sure they
can always rewind (e.g. in case that an event from another client arrives before a state from the server).
This commit is contained in:
parent
70e7625282
commit
a9a73e643b
@ -302,6 +302,14 @@ void WorldStatus::updateTime(int ticks)
|
||||
{
|
||||
// set phase is over, go to the next one
|
||||
m_phase = GO_PHASE;
|
||||
// Save one initial state on a client, in case that an event
|
||||
// is received from a client (trieggering a rollback) before
|
||||
// a state from the server has been received.
|
||||
if (NetworkConfig::get()->isClient())
|
||||
{
|
||||
RewindManager::get()->saveLocalState();
|
||||
// FIXME TODO: save state in rewind queue!
|
||||
}
|
||||
if (m_play_ready_set_go_sounds)
|
||||
{
|
||||
m_start_sound->play();
|
||||
|
@ -245,18 +245,22 @@ void GameProtocol::handleAdjustTime(Event *event)
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Called by the server before assembling a new message containing the full
|
||||
* state of the race to be sent to a client.
|
||||
* \param allow_local_save If set it allows a state to be saved on a client.
|
||||
* \param local_save If set it allows a state to be saved on a client.
|
||||
* This only happens at the very first time step to ensure each client
|
||||
* has a state in case it receives an event before a server state.
|
||||
*/
|
||||
void GameProtocol::startNewState(bool allow_local_save)
|
||||
void GameProtocol::startNewState(bool local_save)
|
||||
{
|
||||
assert(allow_local_save || NetworkConfig::get()->isServer());
|
||||
assert(local_save || NetworkConfig::get()->isServer());
|
||||
|
||||
m_data_to_send->clear();
|
||||
m_data_to_send->addUInt8(GP_STATE).addUInt32(World::getWorld()->getTimeTicks());
|
||||
Log::info("GameProtocol", "Starting new state at %d.",
|
||||
World::getWorld()->getTimeTicks());
|
||||
// Local saves don't neet this info, they pass time directly to the
|
||||
// RewindInfo in RewindManager::saveLocalState.
|
||||
if (!local_save)
|
||||
{
|
||||
m_data_to_send->addUInt8(GP_STATE)
|
||||
.addUInt32(World::getWorld()->getTimeTicks());
|
||||
}
|
||||
} // startNewState
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -264,9 +268,8 @@ void GameProtocol::startNewState(bool allow_local_save)
|
||||
* is copied, so the data can be freed after this call/.
|
||||
* \param buffer Adds the data in the buffer to the current state.
|
||||
*/
|
||||
void GameProtocol::addState(bool allow_local_save, BareNetworkString *buffer)
|
||||
void GameProtocol::addState(BareNetworkString *buffer)
|
||||
{
|
||||
assert(allow_local_save || NetworkConfig::get()->isServer());
|
||||
m_data_to_send->addUInt16(buffer->size());
|
||||
(*m_data_to_send) += *buffer;
|
||||
} // addState
|
||||
|
@ -78,8 +78,8 @@ public:
|
||||
|
||||
void controllerAction(int kart_id, PlayerAction action,
|
||||
int value, int val_l, int val_r);
|
||||
void startNewState(bool allow_local_save);
|
||||
void addState(bool allow_local_save, BareNetworkString *buffer);
|
||||
void startNewState(bool local_save);
|
||||
void addState(BareNetworkString *buffer);
|
||||
void sendState();
|
||||
void adjustTimeForClient(STKPeer *peer, int ticks);
|
||||
|
||||
@ -101,6 +101,9 @@ public:
|
||||
{
|
||||
return m_game_protocol.lock();
|
||||
} // lock
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the NetworkString in which a state was saved. */
|
||||
NetworkString* getState() const { return m_data_to_send; }
|
||||
|
||||
}; // class GameProtocol
|
||||
|
||||
|
@ -172,10 +172,10 @@ void RewindManager::addNetworkState(BareNetworkString *buffer, int ticks)
|
||||
* a client before a state from the serer).
|
||||
* \param allow_local_save Do a local save.
|
||||
*/
|
||||
void RewindManager::saveState(bool allow_local_save)
|
||||
void RewindManager::saveState(bool local_save)
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("RewindManager - save state", 0x20, 0x7F, 0x20);
|
||||
GameProtocol::lock()->startNewState(allow_local_save);
|
||||
GameProtocol::lock()->startNewState(local_save);
|
||||
AllRewinder::const_iterator rewinder;
|
||||
for (rewinder = m_all_rewinder.begin(); rewinder != m_all_rewinder.end(); ++rewinder)
|
||||
{
|
||||
@ -185,14 +185,33 @@ void RewindManager::saveState(bool allow_local_save)
|
||||
if (buffer && buffer->size() >= 0)
|
||||
{
|
||||
m_overall_state_size += buffer->size();
|
||||
GameProtocol::lock()->addState(allow_local_save, buffer);
|
||||
GameProtocol::lock()->addState(buffer);
|
||||
} // size >= 0
|
||||
delete buffer; // buffer can be freed
|
||||
}
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
} // saveState
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Saves a state on the client. Used to save an initial state at t=0 for each
|
||||
* client in case that we receive an event from another client (which will
|
||||
* trigger a rewind) before a state from the server.
|
||||
*/
|
||||
void RewindManager::saveLocalState()
|
||||
{
|
||||
int ticks = World::getWorld()->getTimeTicks();
|
||||
|
||||
saveState(/*local_state*/true);
|
||||
NetworkString *state = GameProtocol::lock()->getState();
|
||||
|
||||
// Copy the data to a new string, making the buffer in
|
||||
// GameProtocol availble for again.
|
||||
BareNetworkString *bns =
|
||||
new BareNetworkString(state->getCurrentData(),
|
||||
state->size() );
|
||||
m_rewind_queue.addLocalState(bns, /*confirmed*/true, ticks);
|
||||
} // saveLocalState
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Restores a given state by calling rewindToState for each available rewinder
|
||||
* with its correct data.
|
||||
|
@ -146,7 +146,8 @@ public:
|
||||
BareNetworkString *buffer, int ticks);
|
||||
void addNetworkState(BareNetworkString *buffer, int ticks);
|
||||
void addNextTimeStep(int ticks, float dt);
|
||||
void saveState(bool allow_local_save);
|
||||
void saveState(bool local_save);
|
||||
void saveLocalState();
|
||||
void restoreState(BareNetworkString *buffer);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds a Rewinder to the list of all rewinders.
|
||||
|
Loading…
Reference in New Issue
Block a user