The server now uses the RewindManager to receive network events

and takes the kart input from this queue of events.
This commit is contained in:
hiker 2016-12-15 08:12:04 +11:00
parent 95ca3fcac1
commit 77c14152c2
10 changed files with 131 additions and 53 deletions

View File

@ -191,7 +191,7 @@ void Attachment::set(AttachmentType type, float time,
{ {
BareNetworkString *buffer = new BareNetworkString(2); BareNetworkString *buffer = new BareNetworkString(2);
saveState(buffer); saveState(buffer);
rwm->addEvent(this, buffer); rwm->addEvent(this, buffer, /*confirmed*/true);
} }
#endif #endif
} // set } // set

View File

@ -75,7 +75,7 @@ void KartControl::setSteer(float f)
// Save full status // Save full status
BareNetworkString *buffer = new BareNetworkString(getLength()); BareNetworkString *buffer = new BareNetworkString(getLength());
copyToBuffer(buffer); copyToBuffer(buffer);
RewindManager::get()->addEvent(this, buffer); RewindManager::get()->addEvent(this, buffer, true);
} }
} // setSteer } // setSteer
@ -90,7 +90,7 @@ void KartControl::setAccel(float f)
{ {
BareNetworkString *buffer = new BareNetworkString(getLength()); BareNetworkString *buffer = new BareNetworkString(getLength());
copyToBuffer(buffer); copyToBuffer(buffer);
RewindManager::get()->addEvent(this, buffer); RewindManager::get()->addEvent(this, buffer, true);
} }
} // setAccel } // setAccel
@ -106,7 +106,7 @@ void KartControl::setBrake(bool b)
// Only store the buttons in this case // Only store the buttons in this case
BareNetworkString *buffer = new BareNetworkString(1); BareNetworkString *buffer = new BareNetworkString(1);
buffer->addUInt8(getButtonsCompressed()); buffer->addUInt8(getButtonsCompressed());
RewindManager::get()->addEvent(this, buffer); RewindManager::get()->addEvent(this, buffer, true);
} }
} // setBrake } // setBrake
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -120,7 +120,7 @@ void KartControl::setNitro(bool b)
{ {
BareNetworkString *buffer = new BareNetworkString(1); BareNetworkString *buffer = new BareNetworkString(1);
buffer->addUInt8(getButtonsCompressed()); buffer->addUInt8(getButtonsCompressed());
RewindManager::get()->addEvent(this, buffer); RewindManager::get()->addEvent(this, buffer, true);
} }
} // setNitro } // setNitro
@ -135,7 +135,7 @@ void KartControl::setSkidControl(SkidControl sc)
{ {
BareNetworkString *buffer = new BareNetworkString(1); BareNetworkString *buffer = new BareNetworkString(1);
buffer->addUInt8(getButtonsCompressed()); buffer->addUInt8(getButtonsCompressed());
RewindManager::get()->addEvent(this, buffer); RewindManager::get()->addEvent(this, buffer, true);
} }
} // seSkidControl } // seSkidControl
@ -150,7 +150,7 @@ void KartControl::setRescue(bool b)
{ {
BareNetworkString *buffer = new BareNetworkString(1); BareNetworkString *buffer = new BareNetworkString(1);
buffer->addUInt8(getButtonsCompressed()); buffer->addUInt8(getButtonsCompressed());
RewindManager::get()->addEvent(this, buffer); RewindManager::get()->addEvent(this, buffer, true);
} }
} // setRescue } // setRescue
@ -165,7 +165,7 @@ void KartControl::setFire(bool b)
{ {
BareNetworkString *buffer = new BareNetworkString(1); BareNetworkString *buffer = new BareNetworkString(1);
buffer->addUInt8(getButtonsCompressed()); buffer->addUInt8(getButtonsCompressed());
RewindManager::get()->addEvent(this, buffer); RewindManager::get()->addEvent(this, buffer, true);
} }
} // setFire } // setFire
@ -180,6 +180,6 @@ void KartControl::setLookBack(bool b)
{ {
BareNetworkString *buffer = new BareNetworkString(1); BareNetworkString *buffer = new BareNetworkString(1);
buffer->addUInt8(getButtonsCompressed()); buffer->addUInt8(getButtonsCompressed());
RewindManager::get()->addEvent(this, buffer); RewindManager::get()->addEvent(this, buffer, true);
} }
} // setLookBack } // setLookBack

View File

@ -39,6 +39,7 @@
#include "modes/world.hpp" #include "modes/world.hpp"
#include "network/network_config.hpp" #include "network/network_config.hpp"
#include "network/protocols/game_protocol.hpp" #include "network/protocols/game_protocol.hpp"
#include "network/rewind_manager.hpp"
#include "race/history.hpp" #include "race/history.hpp"
#include "states_screens/race_gui_base.hpp" #include "states_screens/race_gui_base.hpp"
#include "tracks/track.hpp" #include "tracks/track.hpp"
@ -143,9 +144,10 @@ void LocalPlayerController::action(PlayerAction action, int value)
{ {
PlayerController::action(action, value); PlayerController::action(action, value);
// If this is a client, send the action to the server // If this is a client, send the action to networking layer
if (World::getWorld()->isNetworkWorld() && if (World::getWorld()->isNetworkWorld() &&
NetworkConfig::get()->isClient() ) NetworkConfig::get()->isClient() &&
!RewindManager::get()->isRewinding() )
{ {
GameProtocol::getInstance()->controllerAction(m_kart->getWorldKartId(), GameProtocol::getInstance()->controllerAction(m_kart->getWorldKartId(),
action, value); action, value);

View File

@ -1022,7 +1022,7 @@ void World::update(float dt)
void World::updateTime(const float dt) void World::updateTime(const float dt)
{ {
WorldStatus::updateTime(dt); WorldStatus::updateTime(dt);
RewindManager::get()->setCurrentTime(getTime(), dt); RewindManager::get()->setCurrentTime(getTime());
} // updateTime } // updateTime
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -19,7 +19,7 @@
#include "modes/world.hpp" #include "modes/world.hpp"
#include "karts/abstract_kart.hpp" #include "karts/abstract_kart.hpp"
#include "karts/controller/controller.hpp" #include "karts/controller/player_controller.hpp"
#include "network/event.hpp" #include "network/event.hpp"
#include "network/network_config.hpp" #include "network/network_config.hpp"
#include "network/network_player_profile.hpp" #include "network/network_player_profile.hpp"
@ -27,6 +27,7 @@
#include "network/network_config.hpp" #include "network/network_config.hpp"
#include "network/network_string.hpp" #include "network/network_string.hpp"
#include "network/protocol_manager.hpp" #include "network/protocol_manager.hpp"
#include "network/rewind_manager.hpp"
#include "network/stk_host.hpp" #include "network/stk_host.hpp"
#include "network/stk_peer.hpp" #include "network/stk_peer.hpp"
#include "utils/log.hpp" #include "utils/log.hpp"
@ -56,14 +57,14 @@ bool GameProtocol::notifyEventAsynchronous(Event* event)
{ {
float time = data.getFloat(); float time = data.getFloat();
uint8_t kart_id = data.getUInt8(); uint8_t kart_id = data.getUInt8();
assert(kart_id < World::getWorld()->getNumKarts());
PlayerAction action = (PlayerAction)(data.getUInt8()); PlayerAction action = (PlayerAction)(data.getUInt8());
int value = data.getUInt32(); int value = data.getUInt32();
Log::info("GameProtocol", "Action at %f: %d %d %d", Log::info("GameProtocol", "Action at %f: %d %d %d",
time, kart_id, action, value); time, kart_id, action, value);
assert(kart_id < World::getWorld()->getNumKarts()); BareNetworkString *s = new BareNetworkString(3);
Controller *controller = World::getWorld()->getKart(kart_id) s->addUInt8(kart_id).addUInt8(action).addUInt16(value);
->getController(); RewindManager::get()->addEvent(this, s, /*confirmed*/ true, time);
controller->action(action, value);
} }
if (data.size() > 0 ) if (data.size() > 0 )
@ -107,8 +108,8 @@ void GameProtocol::update(float dt)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Called from the local kart controller when an action (like steering, /** Called from the local kart controller when an action (like steering,
* acceleration, ...) was triggered. It compresses the current kart control * acceleration, ...) was triggered. It sends a message with the new info
* state and sends a message with the new info to the server. * to the server and informs the rewind manager to store the event.
* \param Kart id that triggered the action. * \param Kart id that triggered the action.
* \param action Which action was triggered. * \param action Which action was triggered.
* \param value New value for the given action. * \param value New value for the given action.
@ -116,6 +117,8 @@ void GameProtocol::update(float dt)
void GameProtocol::controllerAction(int kart_id, PlayerAction action, void GameProtocol::controllerAction(int kart_id, PlayerAction action,
int value) int value)
{ {
// Store the action in the list of actions that will be sent to the
// server next.
assert(NetworkConfig::get()->isClient()); assert(NetworkConfig::get()->isClient());
Action a; Action a;
a.m_kart_id = kart_id; a.m_kart_id = kart_id;
@ -125,6 +128,36 @@ void GameProtocol::controllerAction(int kart_id, PlayerAction action,
m_all_actions.push_back(a); m_all_actions.push_back(a);
// Store the event in the rewind manager, which is responsible
// for freeing the allocated memory
BareNetworkString *s = new BareNetworkString(4);
s->addUInt8(kart_id).addUInt8(action).addUInt16(uint16_t(value));
RewindManager::get()->addEvent(this, s, /*confirmed*/true,
World::getWorld()->getTime() );
Log::info("GameProtocol", "Action %d value %d", action, value); Log::info("GameProtocol", "Action at %f: %d value %d",
World::getWorld()->getTime(), action, value);
} // controllerAction } // controllerAction
// ----------------------------------------------------------------------------
/** Called from the RewindManager when rolling back.
* \param buffer Pointer to the saved state information.
*/
void GameProtocol::undo(BareNetworkString *buffer)
{
} // undo
// ----------------------------------------------------------------------------
/** Called from the RewindManager after a rollback to replay the stored
* events.
* \param buffer Pointer to the saved state information.
*/
void GameProtocol::rewind(BareNetworkString *buffer)
{
int kart_id = buffer->getUInt8();
PlayerAction action = PlayerAction(buffer->getUInt8());
int value = buffer->getUInt16();
Controller *c = World::getWorld()->getKart(kart_id)->getController();
c->action(action, value);
} // rewind

View File

@ -19,6 +19,7 @@
#ifndef GAME_PROTOCOL_HPP #ifndef GAME_PROTOCOL_HPP
#define GAME_PROTOCOL_HPP #define GAME_PROTOCOL_HPP
#include "network/event_rewinder.hpp"
#include "network/protocol.hpp" #include "network/protocol.hpp"
#include "input/input.hpp" // for PlayerAction #include "input/input.hpp" // for PlayerAction
@ -27,10 +28,11 @@
#include <vector> #include <vector>
class BareNetworkString;
class NetworkString; class NetworkString;
class GameProtocol : public Protocol class GameProtocol : public Protocol
, public EventRewinder
, public Singleton<GameProtocol> , public Singleton<GameProtocol>
{ {
private: private:
@ -59,8 +61,11 @@ public:
virtual bool notifyEventAsynchronous(Event* event) OVERRIDE; virtual bool notifyEventAsynchronous(Event* event) OVERRIDE;
virtual void update(float dt) OVERRIDE; virtual void update(float dt) OVERRIDE;
void controllerAction(int kart_id, PlayerAction action, void controllerAction(int kart_id, PlayerAction action,
int value); int value);
virtual void undo(BareNetworkString *buffer) OVERRIDE;
virtual void rewind(BareNetworkString *buffer) OVERRIDE;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual void setup() OVERRIDE {}; virtual void setup() OVERRIDE {};
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@ -28,6 +28,7 @@
#include "network/protocols/game_events_protocol.hpp" #include "network/protocols/game_events_protocol.hpp"
#include "network/protocols/latency_protocol.hpp" #include "network/protocols/latency_protocol.hpp"
#include "network/race_event_manager.hpp" #include "network/race_event_manager.hpp"
#include "network/rewind_manager.hpp"
#include "network/stk_host.hpp" #include "network/stk_host.hpp"
#include "race/race_manager.hpp" #include "race/race_manager.hpp"
#include "states_screens/state_manager.hpp" #include "states_screens/state_manager.hpp"
@ -56,6 +57,7 @@ LobbyProtocol::~LobbyProtocol()
void LobbyProtocol::loadWorld() void LobbyProtocol::loadWorld()
{ {
Log::info("LobbyProtocol", "Ready !"); Log::info("LobbyProtocol", "Ready !");
RewindManager::setEnable(true);
// Race startup sequence // Race startup sequence
// --------------------- // ---------------------

View File

@ -6,6 +6,7 @@
#include "network/network_config.hpp" #include "network/network_config.hpp"
#include "network/protocol_manager.hpp" #include "network/protocol_manager.hpp"
#include "network/protocols/game_events_protocol.hpp" #include "network/protocols/game_events_protocol.hpp"
#include "network/rewind_manager.hpp"
RaceEventManager::RaceEventManager() RaceEventManager::RaceEventManager()
@ -29,6 +30,9 @@ void RaceEventManager::update(float dt)
if(!ProtocolManager::getInstance()) if(!ProtocolManager::getInstance())
return; return;
// Replay all recorded events up to the current time:
RewindManager::get()->playEventsTill(World::getWorld()->getTime());
World::getWorld()->updateWorld(dt); World::getWorld()->updateWorld(dt);
// if the race is over // if the race is over

View File

@ -83,6 +83,7 @@ void RewindManager::reset()
m_overall_state_size = 0; m_overall_state_size = 0;
m_state_frequency = 0.1f; // save 10 states a second m_state_frequency = 0.1f; // save 10 states a second
m_last_saved_state = -9999.9f; // forces initial state save m_last_saved_state = -9999.9f; // forces initial state save
m_next_event = 0;
if(!m_enable_rewind_manager) return; if(!m_enable_rewind_manager) return;
@ -108,6 +109,12 @@ void RewindManager::reset()
} // reset } // reset
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Inserts a RewindInfo object in the list of all events at the correct time.
* If there are several RewindInfo at the exact same time, state RewindInfo
* will be insert at the front, and event and time info at the end of the
* RewindInfo with the same time.
* \param ri The RewindInfo object to insert.
*/
void RewindManager::insertRewindInfo(RewindInfo *ri) void RewindManager::insertRewindInfo(RewindInfo *ri)
{ {
#ifdef REWIND_SEARCH_STATS #ifdef REWIND_SEARCH_STATS
@ -211,7 +218,8 @@ unsigned int RewindManager::findFirstIndex(float target_time) const
* \param buffer Pointer to the event data. * \param buffer Pointer to the event data.
*/ */
void RewindManager::addEvent(EventRewinder *event_rewinder, void RewindManager::addEvent(EventRewinder *event_rewinder,
BareNetworkString *buffer) BareNetworkString *buffer, bool confirmed,
float time )
{ {
if(m_is_rewinding) if(m_is_rewinding)
{ {
@ -219,8 +227,11 @@ void RewindManager::addEvent(EventRewinder *event_rewinder,
Log::error("RewindManager", "Adding event when rewinding"); Log::error("RewindManager", "Adding event when rewinding");
return; return;
} }
RewindInfo *ri = new RewindInfoEvent(getCurrentTime(), event_rewinder, Log::verbose("time", "wolrd %f rewind %f", World::getWorld()->getTime(), getCurrentTime());
buffer, /*is confirmed*/true); if (time < 0)
time = getCurrentTime();
RewindInfo *ri = new RewindInfoEvent(time, event_rewinder,
buffer, confirmed);
insertRewindInfo(ri); insertRewindInfo(ri);
} // addEvent } // addEvent
@ -270,6 +281,29 @@ void RewindManager::saveStates()
m_last_saved_state = time; m_last_saved_state = time;
} // saveStates } // saveStates
// ----------------------------------------------------------------------------
/** Replays all events from the last event played till the specified time.
* \param time Up to (and inclusive) which time events will be replayed.
*/
void RewindManager::playEventsTill(float time)
{
assert(!m_is_rewinding);
m_is_rewinding = true;
while (m_next_event < m_rewind_info.size())
{
RewindInfo *ri = m_rewind_info[m_next_event];
if (ri->getTime() > time)
{
m_is_rewinding = false;
return;
}
m_next_event++;
if(ri->isEvent())
ri->rewind();
}
m_is_rewinding = false;
} // playEventsTill
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Rewinds to the specified time. /** Rewinds to the specified time.
* \param t Time to rewind to. * \param t Time to rewind to.

View File

@ -93,6 +93,9 @@ private:
AllRewindInfo m_rewind_info; AllRewindInfo m_rewind_info;
/** Index of the next event to be used when playing events. */
unsigned int m_next_event;
/** Overall amount of memory allocated by states. */ /** Overall amount of memory allocated by states. */
unsigned int m_overall_state_size; unsigned int m_overall_state_size;
@ -111,9 +114,6 @@ private:
* events later. */ * events later. */
float m_current_time; float m_current_time;
/** The current time step size. */
float m_time_step;
#define REWIND_SEARCH_STATS #define REWIND_SEARCH_STATS
#ifdef REWIND_SEARCH_STATS #ifdef REWIND_SEARCH_STATS
@ -134,31 +134,11 @@ public:
static RewindManager *create(); static RewindManager *create();
static void destroy(); static void destroy();
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Sets the time that is to be used for all further states or events,
* and the time step size. This is necessary so that states/events before
* and after World::m_time is increased have the same time stamp.
* \param t Time.
* \param dt Time step size.
*/
void setCurrentTime(float t, float dt)
{
m_current_time = t;
m_time_step = dt;
} // setCurrentTime
// ------------------------------------------------------------------------
/** Returns the current time. */
float getCurrentTime() const { return m_current_time; }
// ------------------------------------------------------------------------
float getCurrentTimeStep() const { return m_time_step; }
// ------------------------------------------------------------------------
/** En- or disables rewinding. */ /** En- or disables rewinding. */
static void setEnable(bool m) { m_enable_rewind_manager = m; } static void setEnable(bool m) { m_enable_rewind_manager = m; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns if rewinding is enabled or not. */ /** Returns if rewinding is enabled or not. */
static bool isEnabled() { return m_enable_rewind_manager; } static bool isEnabled() { return m_enable_rewind_manager; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the singleton. This function will not automatically create /** Returns the singleton. This function will not automatically create
* the singleton. */ * the singleton. */
@ -168,12 +148,30 @@ public:
return m_rewind_manager; return m_rewind_manager;
} // get } // get
// ------------------------------------------------------------------------ // Non-static functtion declarations:
void reset(); void reset();
void saveStates(); void saveStates();
void rewindTo(float target_time); void rewindTo(float target_time);
void addEvent(EventRewinder *event_rewinder, BareNetworkString *buffer); void playEventsTill(float time);
void addEvent(EventRewinder *event_rewinder, BareNetworkString *buffer,
bool confirmed, float time = -1.0f);
// ------------------------------------------------------------------------
/** Sets the time that is to be used for all further states or events,
* and the time step size. This is necessary so that states/events before
* and after World::m_time is increased have the same time stamp.
* \param t Time.
* \param dt Time step size.
*/
void setCurrentTime(float t)
{
m_current_time = t;
} // setCurrentTime
// ------------------------------------------------------------------------
/** Returns the current time. */
float getCurrentTime() const { return m_current_time; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Adds a Rewinder to the list of all rewinders. /** Adds a Rewinder to the list of all rewinders.
* \return true If rewinding is enabled, false otherwise. * \return true If rewinding is enabled, false otherwise.