slight modification in the synchronization protocol to handle correctly multiple clients on the server (token management was not working).

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/hilnius@13257 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hilnius 2013-07-15 23:28:20 +00:00
parent e139380a59
commit 0625379706
15 changed files with 90 additions and 39 deletions

View File

@ -37,7 +37,7 @@ class Item;
class KartControl;
class Material;
/** This is the base class for kart controller - that can be a player
/** This is the base class for kart controller - that can be a player
* or a a robot.
* \ingroup controller
*/
@ -58,7 +58,7 @@ protected:
/** The name of the controller, mainly used for debugging purposes. */
std::string m_controller_name;
public:
Controller (AbstractKart *kart,
Controller (AbstractKart *kart,
StateManager::ActivePlayer *player=NULL);
virtual ~Controller () {};
virtual void reset () = 0;
@ -74,20 +74,20 @@ public:
virtual bool disableSlipstreamBonus() const = 0;
// ---------------------------------------------------------------------------
/** Sets the controller name for this controller. */
virtual void setControllerName(const std::string &name)
virtual void setControllerName(const std::string &name)
{ m_controller_name = name; }
// ---------------------------------------------------------------------------
/** Returns the name of this controller. */
const std::string &getControllerName() const { return m_controller_name; }
// ---------------------------------------------------------------------------
/** Returns the active player for this controller (NULL
/** Returns the active player for this controller (NULL
* if this controller does not belong to a player. */
StateManager::ActivePlayer *getPlayer () {return m_player;}
// ---------------------------------------------------------------------------
/** Returns the player object (or NULL if it's a computer controller). */
const StateManager::ActivePlayer *getPlayer () const { return m_player; }
// ------------------------------------------------------------------------
/** Default: ignore actions. Only PlayerController get them. */
virtual void action(PlayerAction action, int value) = 0;

View File

@ -28,6 +28,8 @@ NetworkPlayerController::NetworkPlayerController(AbstractKart *kart,
m_penalty_time = 0.0f;
reset();
Log::info("NetworkPlayerController", "New network player controller.");
} // NetworkPlayerController
//-----------------------------------------------------------------------------

View File

@ -1466,7 +1466,7 @@ int main(int argc, char *argv[] )
// Create player and associate player with keyboard
StateManager::get()->createActivePlayer(
UserConfigParams::m_all_players.get(0), device );
UserConfigParams::m_all_players.get(0), device, NULL);
if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL)
{

View File

@ -140,7 +140,7 @@ bool DemoWorld::updateIdleTimeAndStartDemo(float dt)
// Use keyboard 0 by default in --no-start-screen
device = input_manager->getDeviceList()->getKeyboard(0);
StateManager::get()->createActivePlayer(
UserConfigParams::m_all_players.get(0), device );
UserConfigParams::m_all_players.get(0), device , NULL);
// ASSIGN should make sure that only input from assigned devices
// is read.
input_manager->getDeviceList()->setAssignMode(ASSIGN);

View File

@ -63,7 +63,7 @@ void OverWorld::enterOverWorld()
// Create player and associate player with keyboard
StateManager::get()->createActivePlayer(unlock_manager->getCurrentPlayer(),
device);
device, NULL);
if (!kart_properties_manager->getKart(UserConfigParams::m_default_kart))
{

View File

@ -38,6 +38,7 @@
#include "karts/controller/player_controller.hpp"
#include "karts/controller/end_controller.hpp"
#include "karts/controller/skidding_ai.hpp"
#include "karts/controller/network_player_controller.hpp"
#include "karts/kart.hpp"
#include "karts/kart_properties_manager.hpp"
#include "modes/overworld.hpp"
@ -280,11 +281,10 @@ AbstractKart *World::createKart(const std::string &kart_ident, int index,
m_num_players ++;
break;
case RaceManager::KT_NETWORK_PLAYER:
break; // Avoid compiler warning about enum not handled.
//controller = new NetworkController(kart_ident, position, init_pos,
// global_player_id);
//m_num_players++;
//break;
controller = new NetworkPlayerController(new_kart,
StateManager::get()->getActivePlayer(local_player_id));
m_num_players++;
break;
case RaceManager::KT_AI:
controller = loadAIController(new_kart);
break;
@ -725,7 +725,7 @@ void World::updateWorld(float dt)
// Create player and associate player with keyboard
StateManager::get()->createActivePlayer(unlock_manager->getCurrentPlayer(),
device);
device, NULL);
if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL)
{

View File

@ -94,21 +94,32 @@ void StartGameProtocol::update()
race_manager->setNumPlayers(m_game_setup->getPlayerCount());
race_manager->setNumLocalPlayers(1);
std::vector<NetworkPlayerProfile*> players = m_game_setup->getPlayers();
// have to add self first
for (unsigned int i = 0; i < players.size(); i++)
{
bool is_me = (players[i]->user_profile == CurrentOnlineUser::get());
NetworkPlayerProfile* profile = players[i];
RemoteKartInfo rki(profile->race_id, profile->kart_name, profile->user_profile->getUserName(), profile->race_id);
RemoteKartInfo rki(profile->race_id, profile->kart_name,
profile->user_profile->getUserName(), profile->race_id, !is_me);
rki.setGlobalPlayerId(profile->race_id);
rki.setLocalPlayerId(profile->race_id);
rki.setHostId(profile->race_id);
rki.setLocalPlayerId(i);
rki.setHostId(i);
race_manager->setPlayerKart(i, rki);
Log::info("StartGameProtocol", "Creating kart %s for Player#%d with race_id %d", profile->kart_name.c_str(), i, profile->race_id);
PlayerProfile* profileToUse = unlock_manager->getCurrentPlayer();
InputDevice* device = NULL;
if (players[i]->user_profile == CurrentOnlineUser::get())
device = input_manager->getDeviceList()->getKeyboard(0);
int new_player_id = StateManager::get()->createActivePlayer( profileToUse, device );
// self config
if (is_me)
{
PlayerProfile* profileToUse = unlock_manager->getCurrentPlayer();
InputDevice* device = input_manager->getDeviceList()->getLatestUsedDevice();
int new_player_id = StateManager::get()->createActivePlayer( profileToUse, device , players[i]->user_profile);
device->setPlayer(StateManager::get()->getActivePlayer(new_player_id));
input_manager->getDeviceList()->setSinglePlayer(StateManager::get()->getActivePlayer(new_player_id));
Log::info("StartGameProtocol", "Self player device added."); // self config
}
else
{
StateManager::get()->createActivePlayer( NULL, NULL , players[i]->user_profile);
}
}
Log::info("StartGameProtocol", "Player configuration ready.");
m_state = SYNCHRONIZATION_WAIT;

View File

@ -53,7 +53,14 @@ void SynchronizationProtocol::notifyEvent(Event* event)
}
}
uint8_t peer_id = (m_listener->isServer() ? talk_id : 0); // on clients, peer index is 0
uint8_t peer_id;
for (unsigned int i = 0; i < peers.size(); i++)
{
if (peers[i]->isSamePeer(*event->peer))
{
peer_id = i;
}
}
if (peers[peer_id]->getClientServerToken() != token)
{
Log::warn("SynchronizationProtocol", "Bad token from peer %d", talk_id);
@ -64,12 +71,12 @@ void SynchronizationProtocol::notifyEvent(Event* event)
{
NetworkString response;
response.ai8(event->data.gui8(talk_id)).ai32(token).ai8(0).ai32(sequence);
m_listener->sendMessage(this, peers[talk_id], response, false);
m_listener->sendMessage(this, peers[peer_id], response, false);
Log::verbose("SynchronizationProtocol", "Answering sequence %u", sequence);
if (event->data.size() == 14 && !m_listener->isServer()) // countdown time in the message
{
uint32_t time_to_start = event->data.gui32(10);
Log::info("SynchronizationProtocol", "Request to start game in %d.", time_to_start);
Log::debug("SynchronizationProtocol", "Request to start game in %d.", time_to_start);
if (!m_countdown_activated)
startCountdown(time_to_start);
else
@ -121,6 +128,16 @@ void SynchronizationProtocol::asynchronousUpdate()
m_listener->requestTerminate(this);
return;
}
static int seconds = -1;
if (seconds == -1)
{
seconds = (int)(ceil(m_countdown));
}
else if (seconds != (int)(ceil(m_countdown)))
{
seconds = (int)(ceil(m_countdown));
Log::info("SynchronizationProtocol", "Starting in %d seconds.", seconds);
}
}
if (current_time > timer+0.1)
{

View File

@ -38,12 +38,15 @@ class RemoteKartInfo
int m_global_player_id;
int m_host_id;
SoccerTeam m_soccer_team;
bool m_network_player;
public:
RemoteKartInfo(int player_id, const std::string& kart_name,
const irr::core::stringw& user_name, int host_id)
const irr::core::stringw& user_name, int host_id, bool network)
: m_kart_name(kart_name), m_user_name(user_name),
m_local_player_id(player_id), m_host_id(host_id), m_soccer_team(SOCCER_TEAM_NONE)
m_local_player_id(player_id), m_host_id(host_id),
m_soccer_team(SOCCER_TEAM_NONE), m_network_player(network)
{};
RemoteKartInfo(const std::string& kart_name)
{m_kart_name=kart_name; m_user_name="";
@ -56,10 +59,12 @@ public:
void setLocalPlayerId(int id) { m_local_player_id = id; }
void setGlobalPlayerId(int id) { m_global_player_id = id; }
void setSoccerTeam(SoccerTeam team) { m_soccer_team = team; }
void setNetworkPlayer(bool value) { m_network_player = value; }
int getHostId() const { return m_host_id; }
int getLocalPlayerId() const { return m_local_player_id; }
int getGlobalPlayerId() const { return m_global_player_id; }
bool isNetworkPlayer() const { return m_network_player; }
const std::string& getKartName() const { return m_kart_name; }
const irr::core::stringw& getPlayerName() const { return m_user_name; }
const SoccerTeam getSoccerTeam() const {return m_soccer_team; }

View File

@ -146,7 +146,7 @@ void RaceManager::setLocalKartInfo(unsigned int player_id,
m_local_player_karts[player_id] = RemoteKartInfo(player_id, kart,
StateManager::get()->getActivePlayerProfile(player_id)->getName(),
0);
0, false);
} // setLocalKartInfo
//-----------------------------------------------------------------------------
@ -322,7 +322,7 @@ void RaceManager::startNew(bool from_overworld)
// -------------------------------------------------
for(int i=m_player_karts.size()-1; i>=0; i--)
{
KartType kt= KT_PLAYER;
KartType kt= m_player_karts[i].isNetworkPlayer() ? KT_NETWORK_PLAYER : KT_PLAYER;
m_kart_status.push_back(KartStatus(m_player_karts[i].getKartName(), i,
m_player_karts[i].getLocalPlayerId(),
m_player_karts[i].getGlobalPlayerId(),

View File

@ -64,7 +64,7 @@ void HelpScreen1::eventCallback(Widget* widget, const std::string& name, const i
// Create player and associate player with keyboard
StateManager::get()->createActivePlayer(unlock_manager->getCurrentPlayer(),
device);
device, NULL);
if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL)
{

View File

@ -1240,7 +1240,7 @@ bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer)
}
const int new_player_id =
StateManager::get()->createActivePlayer( profileToUse, device );
StateManager::get()->createActivePlayer( profileToUse, device, NULL );
StateManager::ActivePlayer* aplayer =
StateManager::get()->getActivePlayer(new_player_id);

View File

@ -314,7 +314,7 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
// Create player and associate player with keyboard
StateManager::get()->createActivePlayer(unlock_manager->getCurrentPlayer(),
device);
device, NULL);
if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL)
{

View File

@ -30,6 +30,7 @@
#include "main_loop.hpp"
#include "modes/profile_world.hpp"
#include "modes/world.hpp"
#include "online/online_user.hpp"
#include "utils/translation.hpp"
using namespace GUIEngine;
@ -100,11 +101,12 @@ void StateManager::updateActivePlayerIDs()
// ----------------------------------------------------------------------------
int StateManager::createActivePlayer(PlayerProfile *profile, InputDevice *device)
int StateManager::createActivePlayer(PlayerProfile *profile, InputDevice *device,
OnlineUser* user)
{
ActivePlayer *p;
int i;
p = new ActivePlayer(profile, device);
p = new ActivePlayer(profile, device, user);
i = m_active_players.size();
m_active_players.push_back(p);
@ -250,7 +252,8 @@ void StateManager::onStackEmptied()
#endif
StateManager::ActivePlayer::ActivePlayer(PlayerProfile* player,
InputDevice *device)
InputDevice *device,
OnlineUser* user)
{
#ifdef DEBUG
m_magic_number = 0xAC1EF1AE;
@ -259,6 +262,7 @@ StateManager::ActivePlayer::ActivePlayer(PlayerProfile* player,
m_player = player;
m_device = NULL;
m_kart = NULL;
m_online_user = user;
setDevice(device);
} // ActivePlayer

View File

@ -34,6 +34,7 @@
class AbstractKart;
class InputDevice;
struct Input;
class OnlineUser;
namespace GUIEngine
{
@ -72,6 +73,7 @@ public:
{
friend class StateManager;
OnlineUser *m_online_user;
PlayerProfile *m_player;
InputDevice *m_device;
@ -81,7 +83,7 @@ public:
/** ID of this player within the list of active players */
int m_id;
ActivePlayer(PlayerProfile* player, InputDevice* device);
ActivePlayer(PlayerProfile* player, InputDevice* device, OnlineUser* user);
#ifdef DEBUG
unsigned int m_magic_number;
@ -122,6 +124,16 @@ public:
* selecting his identity) */
void setPlayerProfile(PlayerProfile* player);
// --------------------------------------------------------------------
OnlineUser* getOnlineUser()
{
return m_online_user;
}
// --------------------------------------------------------------------
/** Call to change the identity of this player (useful when player is
* selecting his identity) */
void setOnlineUser(OnlineUser* user) { m_online_user = user; }
// --------------------------------------------------------------------
/** ID of this player within the list of active players */
int getID() const
@ -178,7 +190,7 @@ public:
*/
const PlayerProfile* getActivePlayerProfile(const int id);
int createActivePlayer(PlayerProfile *profile, InputDevice *device);
int createActivePlayer(PlayerProfile *profile, InputDevice *device, OnlineUser* use);
void removeActivePlayer(int id);
int activePlayerCount();