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
|
// set phase is over, go to the next one
|
||||||
m_phase = GO_PHASE;
|
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)
|
if (m_play_ready_set_go_sounds)
|
||||||
{
|
{
|
||||||
m_start_sound->play();
|
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
|
/** Called by the server before assembling a new message containing the full
|
||||||
* state of the race to be sent to a client.
|
* 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
|
* 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.
|
* 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->clear();
|
||||||
m_data_to_send->addUInt8(GP_STATE).addUInt32(World::getWorld()->getTimeTicks());
|
// Local saves don't neet this info, they pass time directly to the
|
||||||
Log::info("GameProtocol", "Starting new state at %d.",
|
// RewindInfo in RewindManager::saveLocalState.
|
||||||
World::getWorld()->getTimeTicks());
|
if (!local_save)
|
||||||
|
{
|
||||||
|
m_data_to_send->addUInt8(GP_STATE)
|
||||||
|
.addUInt32(World::getWorld()->getTimeTicks());
|
||||||
|
}
|
||||||
} // startNewState
|
} // startNewState
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -264,9 +268,8 @@ void GameProtocol::startNewState(bool allow_local_save)
|
|||||||
* is copied, so the data can be freed after this call/.
|
* is copied, so the data can be freed after this call/.
|
||||||
* \param buffer Adds the data in the buffer to the current state.
|
* \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->addUInt16(buffer->size());
|
||||||
(*m_data_to_send) += *buffer;
|
(*m_data_to_send) += *buffer;
|
||||||
} // addState
|
} // addState
|
||||||
|
@ -78,8 +78,8 @@ public:
|
|||||||
|
|
||||||
void controllerAction(int kart_id, PlayerAction action,
|
void controllerAction(int kart_id, PlayerAction action,
|
||||||
int value, int val_l, int val_r);
|
int value, int val_l, int val_r);
|
||||||
void startNewState(bool allow_local_save);
|
void startNewState(bool local_save);
|
||||||
void addState(bool allow_local_save, BareNetworkString *buffer);
|
void addState(BareNetworkString *buffer);
|
||||||
void sendState();
|
void sendState();
|
||||||
void adjustTimeForClient(STKPeer *peer, int ticks);
|
void adjustTimeForClient(STKPeer *peer, int ticks);
|
||||||
|
|
||||||
@ -101,6 +101,9 @@ public:
|
|||||||
{
|
{
|
||||||
return m_game_protocol.lock();
|
return m_game_protocol.lock();
|
||||||
} // lock
|
} // lock
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
/** Returns the NetworkString in which a state was saved. */
|
||||||
|
NetworkString* getState() const { return m_data_to_send; }
|
||||||
|
|
||||||
}; // class GameProtocol
|
}; // class GameProtocol
|
||||||
|
|
||||||
|
@ -172,10 +172,10 @@ void RewindManager::addNetworkState(BareNetworkString *buffer, int ticks)
|
|||||||
* a client before a state from the serer).
|
* a client before a state from the serer).
|
||||||
* \param allow_local_save Do a local save.
|
* \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);
|
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;
|
AllRewinder::const_iterator rewinder;
|
||||||
for (rewinder = m_all_rewinder.begin(); rewinder != m_all_rewinder.end(); ++rewinder)
|
for (rewinder = m_all_rewinder.begin(); rewinder != m_all_rewinder.end(); ++rewinder)
|
||||||
{
|
{
|
||||||
@ -185,15 +185,34 @@ void RewindManager::saveState(bool allow_local_save)
|
|||||||
if (buffer && buffer->size() >= 0)
|
if (buffer && buffer->size() >= 0)
|
||||||
{
|
{
|
||||||
m_overall_state_size += buffer->size();
|
m_overall_state_size += buffer->size();
|
||||||
GameProtocol::lock()->addState(allow_local_save, buffer);
|
GameProtocol::lock()->addState(buffer);
|
||||||
} // size >= 0
|
} // size >= 0
|
||||||
delete buffer; // buffer can be freed
|
delete buffer; // buffer can be freed
|
||||||
}
|
}
|
||||||
PROFILER_POP_CPU_MARKER();
|
PROFILER_POP_CPU_MARKER();
|
||||||
|
|
||||||
} // saveState
|
} // 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
|
/** Restores a given state by calling rewindToState for each available rewinder
|
||||||
* with its correct data.
|
* with its correct data.
|
||||||
* \param data The data string used to store the whole game state.
|
* \param data The data string used to store the whole game state.
|
||||||
|
@ -146,7 +146,8 @@ public:
|
|||||||
BareNetworkString *buffer, int ticks);
|
BareNetworkString *buffer, int ticks);
|
||||||
void addNetworkState(BareNetworkString *buffer, int ticks);
|
void addNetworkState(BareNetworkString *buffer, int ticks);
|
||||||
void addNextTimeStep(int ticks, float dt);
|
void addNextTimeStep(int ticks, float dt);
|
||||||
void saveState(bool allow_local_save);
|
void saveState(bool local_save);
|
||||||
|
void saveLocalState();
|
||||||
void restoreState(BareNetworkString *buffer);
|
void restoreState(BareNetworkString *buffer);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Adds a Rewinder to the list of all rewinders.
|
/** Adds a Rewinder to the list of all rewinders.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user