had forgot to add new files
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/hilnius@13209 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
c1534075d3
commit
2f08ee8902
366
src/karts/controller/network_player_controller.cpp
Normal file
366
src/karts/controller/network_player_controller.cpp
Normal file
@ -0,0 +1,366 @@
|
||||
#include "karts/controller/network_player_controller.hpp"
|
||||
|
||||
#include "config/player.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/post_processing.hpp"
|
||||
#include "input/input_manager.hpp"
|
||||
#include "items/attachment.hpp"
|
||||
#include "items/item.hpp"
|
||||
#include "items/powerup.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "karts/skidding.hpp"
|
||||
#include "karts/rescue_animation.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "race/history.hpp"
|
||||
#include "states_screens/race_gui_base.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
|
||||
NetworkPlayerController::NetworkPlayerController(AbstractKart *kart,
|
||||
StateManager::ActivePlayer *player)
|
||||
: Controller(kart)
|
||||
{
|
||||
assert(player != NULL);
|
||||
m_player = player;
|
||||
m_player->setKart(kart);
|
||||
m_penalty_time = 0.0f;
|
||||
|
||||
reset();
|
||||
} // NetworkPlayerController
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Destructor for a player kart.
|
||||
*/
|
||||
NetworkPlayerController::~NetworkPlayerController()
|
||||
{
|
||||
} // ~NetworkPlayerController
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Resets the player kart for a new or restarted race.
|
||||
*/
|
||||
void NetworkPlayerController::reset()
|
||||
{
|
||||
m_steer_val_l = 0;
|
||||
m_steer_val_r = 0;
|
||||
m_steer_val = 0;
|
||||
m_prev_brake = 0;
|
||||
m_prev_accel = 0;
|
||||
m_prev_nitro = false;
|
||||
m_penalty_time = 0;
|
||||
} // reset
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Resets the state of control keys. This is used after the in-game menu to
|
||||
* avoid that any keys pressed at the time the menu is opened are still
|
||||
* considered to be pressed.
|
||||
*/
|
||||
void NetworkPlayerController::resetInputState()
|
||||
{
|
||||
m_steer_val_l = 0;
|
||||
m_steer_val_r = 0;
|
||||
m_steer_val = 0;
|
||||
m_prev_brake = 0;
|
||||
m_prev_accel = 0;
|
||||
m_prev_nitro = false;
|
||||
m_controls->reset();
|
||||
} // resetInputState
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** This function interprets a kart action and value, and set the corresponding
|
||||
* entries in the kart control data structure. This function handles esp.
|
||||
* cases like 'press left, press right, release right' - in this case after
|
||||
* releasing right, the steering must switch to left again. Similarly it
|
||||
* handles 'press left, press right, release left' (in which case still
|
||||
* right must be selected). Similarly for braking and acceleration.
|
||||
* \param action The action to be executed.
|
||||
* \param value If 32768, it indicates a digital value of 'fully set'
|
||||
* if between 1 and 32767, it indicates an analog value,
|
||||
* and if it's 0 it indicates that the corresponding button
|
||||
* was released.
|
||||
*/
|
||||
void NetworkPlayerController::action(PlayerAction action, int value)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case PA_STEER_LEFT:
|
||||
m_steer_val_l = value;
|
||||
if (value)
|
||||
{
|
||||
m_steer_val = value;
|
||||
if(m_controls->m_skid==KartControl::SC_NO_DIRECTION)
|
||||
m_controls->m_skid = KartControl::SC_LEFT;
|
||||
}
|
||||
else
|
||||
m_steer_val = m_steer_val_r;
|
||||
|
||||
break;
|
||||
case PA_STEER_RIGHT:
|
||||
m_steer_val_r = -value;
|
||||
if (value)
|
||||
{
|
||||
m_steer_val = -value;
|
||||
if(m_controls->m_skid==KartControl::SC_NO_DIRECTION)
|
||||
m_controls->m_skid = KartControl::SC_RIGHT;
|
||||
}
|
||||
else
|
||||
m_steer_val = m_steer_val_l;
|
||||
|
||||
break;
|
||||
case PA_ACCEL:
|
||||
m_prev_accel = value;
|
||||
if (value && !(m_penalty_time > 0.0f))
|
||||
{
|
||||
m_controls->m_accel = value/32768.0f;
|
||||
m_controls->m_brake = false;
|
||||
m_controls->m_nitro = m_prev_nitro;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_controls->m_accel = 0.0f;
|
||||
m_controls->m_brake = m_prev_brake;
|
||||
m_controls->m_nitro = false;
|
||||
}
|
||||
break;
|
||||
case PA_BRAKE:
|
||||
m_prev_brake = value!=0;
|
||||
// let's consider below that to be a deadzone
|
||||
if(value > 32768/2)
|
||||
{
|
||||
m_controls->m_brake = true;
|
||||
m_controls->m_accel = 0.0f;
|
||||
m_controls->m_nitro = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_controls->m_brake = false;
|
||||
m_controls->m_accel = m_prev_accel/32768.0f;
|
||||
// Nitro still depends on whether we're accelerating
|
||||
m_controls->m_nitro = (m_prev_nitro && m_prev_accel);
|
||||
}
|
||||
break;
|
||||
case PA_NITRO:
|
||||
// This basically keeps track whether the button still is being pressed
|
||||
m_prev_nitro = (value != 0);
|
||||
// Enable nitro only when also accelerating
|
||||
m_controls->m_nitro = ((value!=0) && m_controls->m_accel);
|
||||
break;
|
||||
case PA_RESCUE:
|
||||
m_controls->m_rescue = (value!=0);
|
||||
break;
|
||||
case PA_FIRE:
|
||||
{
|
||||
m_controls->m_fire = (value!=0);
|
||||
break;
|
||||
}
|
||||
case PA_LOOK_BACK:
|
||||
m_controls->m_look_back = (value!=0);
|
||||
break;
|
||||
case PA_DRIFT:
|
||||
if(value==0)
|
||||
m_controls->m_skid = KartControl::SC_NONE;
|
||||
else
|
||||
if(m_steer_val==0)
|
||||
m_controls->m_skid = KartControl::SC_NO_DIRECTION;
|
||||
else
|
||||
m_controls->m_skid = m_steer_val<0
|
||||
? KartControl::SC_RIGHT
|
||||
: KartControl::SC_LEFT;
|
||||
break;
|
||||
case PA_PAUSE_RACE:
|
||||
if (value != 0) StateManager::get()->escapePressed();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
} // action
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Handles steering for a player kart.
|
||||
*/
|
||||
void NetworkPlayerController::steer(float dt, int steer_val)
|
||||
{
|
||||
if(stk_config->m_disable_steer_while_unskid &&
|
||||
m_controls->m_skid==KartControl::SC_NONE &&
|
||||
m_kart->getSkidding()->getVisualSkidRotation()!=0)
|
||||
{
|
||||
m_controls->m_steer = 0;
|
||||
}
|
||||
|
||||
|
||||
// Amount the steering is changed for digital devices.
|
||||
// If the steering is 'back to straight', a different steering
|
||||
// change speed is used.
|
||||
const float STEER_CHANGE = ( (steer_val<=0 && m_controls->m_steer<0) ||
|
||||
(steer_val>=0 && m_controls->m_steer>0) )
|
||||
? dt/m_kart->getKartProperties()->getTimeResetSteer()
|
||||
: dt/m_kart->getTimeFullSteer(fabsf(m_controls->m_steer));
|
||||
if (steer_val < 0)
|
||||
{
|
||||
// If we got analog values do not cumulate.
|
||||
if (steer_val > -32767)
|
||||
m_controls->m_steer = -steer_val/32767.0f;
|
||||
else
|
||||
m_controls->m_steer += STEER_CHANGE;
|
||||
}
|
||||
else if(steer_val > 0)
|
||||
{
|
||||
// If we got analog values do not cumulate.
|
||||
if (steer_val < 32767)
|
||||
m_controls->m_steer = -steer_val/32767.0f;
|
||||
else
|
||||
m_controls->m_steer -= STEER_CHANGE;
|
||||
}
|
||||
else
|
||||
{ // no key is pressed
|
||||
if(m_controls->m_steer>0.0f)
|
||||
{
|
||||
m_controls->m_steer -= STEER_CHANGE;
|
||||
if(m_controls->m_steer<0.0f) m_controls->m_steer=0.0f;
|
||||
}
|
||||
else
|
||||
{ // m_controls->m_steer<=0.0f;
|
||||
m_controls->m_steer += STEER_CHANGE;
|
||||
if(m_controls->m_steer>0.0f) m_controls->m_steer=0.0f;
|
||||
} // if m_controls->m_steer<=0.0f
|
||||
} // no key is pressed
|
||||
if(UserConfigParams::m_gamepad_debug)
|
||||
{
|
||||
Log::debug("PlayerController", " set to: %f\n", m_controls->m_steer);
|
||||
}
|
||||
|
||||
m_controls->m_steer = std::min(1.0f, std::max(-1.0f, m_controls->m_steer));
|
||||
|
||||
} // steer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Callback when the skidding bonus is triggered. The player controller
|
||||
* resets the current steering to 0, which makes the kart easier to control.
|
||||
*/
|
||||
void NetworkPlayerController::skidBonusTriggered()
|
||||
{
|
||||
m_controls->m_steer = 0;
|
||||
} // skidBonusTriggered
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Updates the player kart, called once each timestep.
|
||||
*/
|
||||
void NetworkPlayerController::update(float dt)
|
||||
{
|
||||
if (UserConfigParams::m_gamepad_debug)
|
||||
{
|
||||
// Print a dividing line so that it's easier to see which events
|
||||
// get received in which order in the one frame.
|
||||
Log::debug("PlayerController", "irr_driver", "-------------------------------------\n");
|
||||
}
|
||||
|
||||
// Don't do steering if it's replay. In position only replay it doesn't
|
||||
// matter, but if it's physics replay the gradual steering causes
|
||||
// incorrect results, since the stored values are already adjusted.
|
||||
if (!history->replayHistory())
|
||||
steer(dt, m_steer_val);
|
||||
|
||||
if (World::getWorld()->isStartPhase())
|
||||
{
|
||||
if (m_controls->m_accel || m_controls->m_brake ||
|
||||
m_controls->m_fire || m_controls->m_nitro)
|
||||
{
|
||||
// Only give penalty time in SET_PHASE.
|
||||
// Penalty time check makes sure it doesn't get rendered on every
|
||||
// update.
|
||||
if (m_penalty_time == 0.0 &&
|
||||
World::getWorld()->getPhase() == WorldStatus::SET_PHASE)
|
||||
{
|
||||
RaceGUIBase* m=World::getWorld()->getRaceGUI();
|
||||
if (m)
|
||||
{
|
||||
m->addMessage(_("Penalty time!!"), m_kart, 2.0f,
|
||||
video::SColor(255, 255, 128, 0));
|
||||
m->addMessage(_("Don't accelerate before go"), m_kart, 2.0f,
|
||||
video::SColor(255, 210, 100, 50));
|
||||
}
|
||||
|
||||
m_penalty_time = stk_config->m_penalty_time;
|
||||
} // if penalty_time = 0
|
||||
|
||||
m_controls->m_brake = false;
|
||||
m_controls->m_accel = 0.0f;
|
||||
} // if key pressed
|
||||
|
||||
return;
|
||||
} // if isStartPhase
|
||||
|
||||
if (m_penalty_time>0.0)
|
||||
{
|
||||
m_penalty_time-=dt;
|
||||
return;
|
||||
}
|
||||
|
||||
// We can't restrict rescue to fulfil isOnGround() (which would be more like
|
||||
// MK), since e.g. in the City track it is possible for the kart to end
|
||||
// up sitting on a brick wall, with all wheels in the air :((
|
||||
// Only accept rescue if there is no kart animation is already playing
|
||||
// (e.g. if an explosion happens, wait till the explosion is over before
|
||||
// starting any other animation).
|
||||
if ( m_controls->m_rescue && !m_kart->getKartAnimation() )
|
||||
{
|
||||
new RescueAnimation(m_kart);
|
||||
m_controls->m_rescue=false;
|
||||
}
|
||||
} // update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Checks if the kart was overtaken, and if so plays a sound
|
||||
*/
|
||||
void NetworkPlayerController::setPosition(int p)
|
||||
{
|
||||
if(m_kart->getPosition()<p)
|
||||
{
|
||||
World *world = World::getWorld();
|
||||
//have the kart that did the passing beep.
|
||||
//I'm not sure if this method of finding the passing kart is fail-safe.
|
||||
for(unsigned int i = 0 ; i < world->getNumKarts(); i++ )
|
||||
{
|
||||
AbstractKart *kart = world->getKart(i);
|
||||
if(kart->getPosition() == p + 1)
|
||||
{
|
||||
kart->beep();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // setPosition
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Called when a kart finishes race.
|
||||
* /param time Finishing time for this kart.
|
||||
d*/
|
||||
void NetworkPlayerController::finishedRace(float time)
|
||||
{
|
||||
|
||||
} // finishedRace
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Called when a kart hits or uses a zipper.
|
||||
*/
|
||||
void NetworkPlayerController::handleZipper(bool play_sound)
|
||||
{
|
||||
m_kart->showZipperFire();
|
||||
} // handleZipper
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Called when a kart hits an item.
|
||||
* \param item Item that was collected.
|
||||
* \param add_info Additional info to be used then handling the item. If
|
||||
* this is -1 (default), the item type is selected
|
||||
* randomly. Otherwise it contains the powerup or
|
||||
* attachment for the kart. This is used in network mode to
|
||||
* let the server determine the powerup/attachment for
|
||||
* the clients.
|
||||
*/
|
||||
void NetworkPlayerController::collectedItem(const Item &item, int add_info, float old_energy)
|
||||
{
|
||||
|
||||
} // collectedItem
|
48
src/karts/controller/network_player_controller.hpp
Normal file
48
src/karts/controller/network_player_controller.hpp
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef NETWORK_PLAYER_CONTROLLER_HPP
|
||||
#define NETWORK_PLAYER_CONTROLLER_HPP
|
||||
|
||||
#include "karts/controller/controller.hpp"
|
||||
|
||||
class AbstractKart;
|
||||
class Player;
|
||||
|
||||
class NetworkPlayerController : public Controller
|
||||
{
|
||||
protected:
|
||||
int m_steer_val, m_steer_val_l, m_steer_val_r;
|
||||
int m_prev_accel;
|
||||
bool m_prev_brake;
|
||||
bool m_prev_nitro;
|
||||
|
||||
float m_penalty_time;
|
||||
|
||||
void steer(float, int);
|
||||
public:
|
||||
NetworkPlayerController (AbstractKart *kart,
|
||||
StateManager::ActivePlayer *_player);
|
||||
virtual ~NetworkPlayerController ();
|
||||
void update (float);
|
||||
void action (PlayerAction action, int value);
|
||||
void handleZipper (bool play_sound);
|
||||
void collectedItem (const Item &item, int add_info=-1,
|
||||
float previous_energy=0);
|
||||
virtual void skidBonusTriggered();
|
||||
virtual void setPosition (int p);
|
||||
virtual bool isPlayerController() const { return false; }
|
||||
virtual bool isNetworkController() const { return true; }
|
||||
virtual void reset ();
|
||||
void resetInputState ();
|
||||
virtual void finishedRace (float time);
|
||||
virtual void crashed (const AbstractKart *k) {}
|
||||
virtual void crashed (const Material *m) {}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Callback whenever a new lap is triggered. Used by the AI
|
||||
* to trigger a recomputation of the way to use, not used for players. */
|
||||
virtual void newLap(int lap) {}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Player will always be able to get a slipstream bonus. */
|
||||
virtual bool disableSlipstreamBonus() const { return false; }
|
||||
|
||||
};
|
||||
|
||||
#endif // NETWORK_PLAYER_CONTROLLER_HPP
|
@ -24,6 +24,7 @@
|
||||
#include "network/protocols/get_peer_address.hpp"
|
||||
#include "network/protocols/connect_to_server.hpp"
|
||||
#include "network/protocols/client_lobby_room_protocol.hpp"
|
||||
#include "network/protocols/synchronization_protocol.hpp"
|
||||
|
||||
#include "utils/log.hpp"
|
||||
|
||||
|
17
src/network/network_world.cpp
Normal file
17
src/network/network_world.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
#include "network/network_world.hpp"
|
||||
|
||||
#include "modes/world.hpp"
|
||||
|
||||
NetworkWorld::NetworkWorld()
|
||||
{
|
||||
m_running = false;
|
||||
}
|
||||
|
||||
NetworkWorld::~NetworkWorld()
|
||||
{
|
||||
}
|
||||
|
||||
void NetworkWorld::update(float dt)
|
||||
{
|
||||
World::getWorld()->updateWorld(dt);
|
||||
}
|
28
src/network/network_world.hpp
Normal file
28
src/network/network_world.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef NETWORK_WORLD_HPP
|
||||
#define NETWORK_WORLD_HPP
|
||||
|
||||
#include "network/singleton.hpp"
|
||||
|
||||
/*! \brief Manages the world updates during an online game
|
||||
* This function's update is to be called instead of the normal World update
|
||||
*/
|
||||
class NetworkWorld : public Singleton<NetworkWorld>
|
||||
{
|
||||
friend class Singleton<NetworkWorld>;
|
||||
public:
|
||||
void update(float dt);
|
||||
|
||||
void start() { m_running = true; }
|
||||
void stop() { m_running = false; }
|
||||
bool isRunning() { return m_running; }
|
||||
|
||||
protected:
|
||||
bool m_running;
|
||||
float m_race_time;
|
||||
|
||||
private:
|
||||
NetworkWorld();
|
||||
virtual ~NetworkWorld();
|
||||
};
|
||||
|
||||
#endif // NETWORK_WORLD_HPP
|
37
src/network/protocols/start_game_protocol.cpp
Normal file
37
src/network/protocols/start_game_protocol.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
#include "network/protocols/start_game_protocol.hpp"
|
||||
|
||||
#include "network/game_setup.hpp"
|
||||
|
||||
StartGameProtocol::StartGameProtocol(GameSetup* game_setup) :
|
||||
Protocol(NULL, PROTOCOL_START_GAME)
|
||||
{
|
||||
m_game_setup = game_setup;
|
||||
std::vector<NetworkPlayerProfile*> players = m_game_setup->getPlayers();
|
||||
for (unsigned int i = 0; i < players.size(); i++)
|
||||
{
|
||||
m_player_states.push_back(std::pair<NetworkPlayerProfile*, STATE>(players[i], LOADING));
|
||||
}
|
||||
}
|
||||
|
||||
StartGameProtocol::~StartGameProtocol()
|
||||
{
|
||||
}
|
||||
|
||||
void StartGameProtocol::notifyEvent(Event* event)
|
||||
{
|
||||
}
|
||||
|
||||
void StartGameProtocol::setup()
|
||||
{
|
||||
m_state = LOADING;
|
||||
}
|
||||
|
||||
void StartGameProtocol::update()
|
||||
{
|
||||
if (m_state == LOADING)
|
||||
{
|
||||
}
|
||||
else if (m_state == READY)
|
||||
{
|
||||
}
|
||||
}
|
29
src/network/protocols/start_game_protocol.hpp
Normal file
29
src/network/protocols/start_game_protocol.hpp
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef START_GAME_PROTOCOL_HPP
|
||||
#define START_GAME_PROTOCOL_HPP
|
||||
|
||||
#include "network/protocol.hpp"
|
||||
|
||||
class GameSetup;
|
||||
class NetworkPlayerProfile;
|
||||
|
||||
class StartGameProtocol : public Protocol
|
||||
{
|
||||
protected:
|
||||
enum STATE { LOADING, READY };
|
||||
std::vector<std::pair<NetworkPlayerProfile*, STATE> > m_player_states;
|
||||
|
||||
GameSetup* m_game_setup;
|
||||
|
||||
STATE m_state;
|
||||
|
||||
public:
|
||||
StartGameProtocol(GameSetup* game_setup);
|
||||
virtual ~StartGameProtocol();
|
||||
|
||||
virtual void notifyEvent(Event* event);
|
||||
virtual void setup();
|
||||
virtual void update();
|
||||
|
||||
};
|
||||
|
||||
#endif // START_GAME_PROTOCOL_HPP
|
107
src/network/protocols/synchronization_protocol.cpp
Normal file
107
src/network/protocols/synchronization_protocol.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
#include "network/protocols/synchronization_protocol.hpp"
|
||||
|
||||
#include "network/network_manager.hpp"
|
||||
#include "utils/time.hpp"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SynchronizationProtocol::SynchronizationProtocol(uint32_t* ping, bool* successed) : Protocol(NULL, PROTOCOL_SYNCHRONIZATION)
|
||||
{
|
||||
m_average_ping = ping;
|
||||
m_successed = successed;
|
||||
m_pings.resize(NetworkManager::getInstance()->getPeerCount(), std::vector<std::pair<double,double> >(0));
|
||||
m_pings_count = 0;
|
||||
m_successed_pings = 0;
|
||||
m_total_diff = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SynchronizationProtocol::~SynchronizationProtocol()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SynchronizationProtocol::notifyEvent(Event* event)
|
||||
{
|
||||
if (event->data.size() < 10)
|
||||
{
|
||||
Log::warn("SynchronizationProtocol", "Received a message too short.");
|
||||
return;
|
||||
}
|
||||
uint8_t talk_id = event->data.gui8(0);
|
||||
uint32_t token = event->data.gui32(1);
|
||||
uint32_t request = event->data.gui8(5);
|
||||
uint32_t sequence = event->data.gui32(6);
|
||||
|
||||
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
|
||||
|
||||
if (m_listener->isServer())
|
||||
{
|
||||
if (talk_id > peers.size())
|
||||
{
|
||||
Log::warn("SynchronizationProtocol", "The ID isn't known.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t peer_id = (m_listener->isServer() ? talk_id : 0); // on clients, peer index is 0
|
||||
if (peers[peer_id]->getClientServerToken() != token)
|
||||
{
|
||||
Log::warn("SynchronizationProtocol", "Bad token from peer %d", talk_id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (request)
|
||||
{
|
||||
NetworkString response;
|
||||
response.ai8(event->data.gui8(talk_id)).ai32(token).ai8(0).ai32(sequence);
|
||||
m_listener->sendMessage(this, peers[talk_id], response, false);
|
||||
}
|
||||
else // response
|
||||
{
|
||||
if (sequence < m_pings[peer_id].size())
|
||||
{
|
||||
Log::warn("SynchronizationProtocol", "The sequence isn't known.");
|
||||
return;
|
||||
}
|
||||
m_pings[peer_id][sequence].second = Time::getRealTime();
|
||||
m_total_diff += (m_pings[peer_id][sequence].second - m_pings[peer_id][sequence].first);
|
||||
m_successed_pings++;
|
||||
*m_average_ping = (int)((m_total_diff/m_successed_pings)*1000.0);
|
||||
if ( *m_successed == false && m_successed_pings > 5)
|
||||
{
|
||||
*m_successed = true; // success after 5 pings (we have good idea of ping)
|
||||
}
|
||||
Log::info("SynchronizationProtocol", "Ping is %u", m_average_ping);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SynchronizationProtocol::setup()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SynchronizationProtocol::update()
|
||||
{
|
||||
static double timer = Time::getRealTime();
|
||||
if (Time::getRealTime() > timer+100 && m_pings_count < 100) // max 100 pings (10 seconds)
|
||||
{
|
||||
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
|
||||
for (unsigned int i = 0; i < peers.size(); i++)
|
||||
{
|
||||
NetworkString ns;
|
||||
ns.ai8(i).addUInt32(peers[i]->getClientServerToken()).addUInt8(1).addUInt32(m_pings_count);
|
||||
timer = Time::getRealTime();
|
||||
m_pings[i].push_back(std::pair<double, double>(timer, 0.0));
|
||||
m_listener->sendMessage(this, peers[i], ns, false);
|
||||
}
|
||||
m_pings_count++;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
28
src/network/protocols/synchronization_protocol.hpp
Normal file
28
src/network/protocols/synchronization_protocol.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef SYNCHRONIZATION_PROTOCOL_HPP
|
||||
#define SYNCHRONIZATION_PROTOCOL_HPP
|
||||
|
||||
#include "network/protocol.hpp"
|
||||
#include <list>
|
||||
#include <utility>
|
||||
|
||||
class SynchronizationProtocol : public Protocol
|
||||
{
|
||||
public:
|
||||
SynchronizationProtocol(uint32_t* ping, bool* successed);
|
||||
virtual ~SynchronizationProtocol();
|
||||
|
||||
virtual void notifyEvent(Event* event);
|
||||
virtual void setup();
|
||||
virtual void update();
|
||||
|
||||
protected:
|
||||
//!< stores the start time / arrival time of packets for each peer
|
||||
std::vector<std::vector<std::pair<double, double> > > m_pings;
|
||||
uint32_t* m_average_ping;
|
||||
uint32_t m_pings_count;
|
||||
uint32_t m_successed_pings;
|
||||
double m_total_diff;
|
||||
bool* m_successed;
|
||||
};
|
||||
|
||||
#endif // SYNCHRONIZATION_PROTOCOL_HPP
|
Loading…
x
Reference in New Issue
Block a user