From 062537970640e835f6f572acad97211f5e6c6e61 Mon Sep 17 00:00:00 2001 From: hilnius Date: Mon, 15 Jul 2013 23:28:20 +0000 Subject: [PATCH] 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 --- src/karts/controller/controller.hpp | 12 ++++---- .../controller/network_player_controller.cpp | 2 ++ src/main.cpp | 2 +- src/modes/demo_world.cpp | 2 +- src/modes/overworld.cpp | 2 +- src/modes/world.cpp | 12 ++++---- src/network/protocols/start_game_protocol.cpp | 29 +++++++++++++------ .../protocols/synchronization_protocol.cpp | 23 +++++++++++++-- src/network/remote_kart_info.hpp | 9 ++++-- src/race/race_manager.cpp | 4 +-- src/states_screens/help_screen_1.cpp | 2 +- src/states_screens/kart_selection.cpp | 2 +- src/states_screens/main_menu_screen.cpp | 2 +- src/states_screens/state_manager.cpp | 10 +++++-- src/states_screens/state_manager.hpp | 16 ++++++++-- 15 files changed, 90 insertions(+), 39 deletions(-) diff --git a/src/karts/controller/controller.hpp b/src/karts/controller/controller.hpp index a981176d2..be343ca73 100644 --- a/src/karts/controller/controller.hpp +++ b/src/karts/controller/controller.hpp @@ -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; diff --git a/src/karts/controller/network_player_controller.cpp b/src/karts/controller/network_player_controller.cpp index a66e9d318..b408727ec 100644 --- a/src/karts/controller/network_player_controller.cpp +++ b/src/karts/controller/network_player_controller.cpp @@ -28,6 +28,8 @@ NetworkPlayerController::NetworkPlayerController(AbstractKart *kart, m_penalty_time = 0.0f; reset(); + + Log::info("NetworkPlayerController", "New network player controller."); } // NetworkPlayerController //----------------------------------------------------------------------------- diff --git a/src/main.cpp b/src/main.cpp index 8393a46af..6f71c1e5d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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) { diff --git a/src/modes/demo_world.cpp b/src/modes/demo_world.cpp index db0616866..35a91def1 100644 --- a/src/modes/demo_world.cpp +++ b/src/modes/demo_world.cpp @@ -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); diff --git a/src/modes/overworld.cpp b/src/modes/overworld.cpp index f301429d6..55f645d65 100644 --- a/src/modes/overworld.cpp +++ b/src/modes/overworld.cpp @@ -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)) { diff --git a/src/modes/world.cpp b/src/modes/world.cpp index c9014c11e..49b814284 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -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) { diff --git a/src/network/protocols/start_game_protocol.cpp b/src/network/protocols/start_game_protocol.cpp index cc370ae7a..f48d48941 100644 --- a/src/network/protocols/start_game_protocol.cpp +++ b/src/network/protocols/start_game_protocol.cpp @@ -94,21 +94,32 @@ void StartGameProtocol::update() race_manager->setNumPlayers(m_game_setup->getPlayerCount()); race_manager->setNumLocalPlayers(1); std::vector 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; diff --git a/src/network/protocols/synchronization_protocol.cpp b/src/network/protocols/synchronization_protocol.cpp index 6bdb68453..ffe47c125 100644 --- a/src/network/protocols/synchronization_protocol.cpp +++ b/src/network/protocols/synchronization_protocol.cpp @@ -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) { diff --git a/src/network/remote_kart_info.hpp b/src/network/remote_kart_info.hpp index 507458d08..2a3da9b7e 100644 --- a/src/network/remote_kart_info.hpp +++ b/src/network/remote_kart_info.hpp @@ -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; } diff --git a/src/race/race_manager.cpp b/src/race/race_manager.cpp index 7ba5886d1..d60a7bf9d 100644 --- a/src/race/race_manager.cpp +++ b/src/race/race_manager.cpp @@ -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(), diff --git a/src/states_screens/help_screen_1.cpp b/src/states_screens/help_screen_1.cpp index edd38a1f6..e54da3e39 100644 --- a/src/states_screens/help_screen_1.cpp +++ b/src/states_screens/help_screen_1.cpp @@ -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) { diff --git a/src/states_screens/kart_selection.cpp b/src/states_screens/kart_selection.cpp index 334fd4046..8123eff9f 100644 --- a/src/states_screens/kart_selection.cpp +++ b/src/states_screens/kart_selection.cpp @@ -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); diff --git a/src/states_screens/main_menu_screen.cpp b/src/states_screens/main_menu_screen.cpp index 677d2c554..58f5c3649 100644 --- a/src/states_screens/main_menu_screen.cpp +++ b/src/states_screens/main_menu_screen.cpp @@ -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) { diff --git a/src/states_screens/state_manager.cpp b/src/states_screens/state_manager.cpp index e787d1b2c..adb49733e 100644 --- a/src/states_screens/state_manager.cpp +++ b/src/states_screens/state_manager.cpp @@ -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 diff --git a/src/states_screens/state_manager.hpp b/src/states_screens/state_manager.hpp index 7db8c6798..8c29cee7a 100644 --- a/src/states_screens/state_manager.hpp +++ b/src/states_screens/state_manager.hpp @@ -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();