From f78276a930132f8442e1b436f25e885852385a36 Mon Sep 17 00:00:00 2001 From: Benau Date: Fri, 16 Mar 2018 00:54:02 +0800 Subject: [PATCH] Show player vote in message queue for immediate effect --- data/gui/tracks.stkgui | 20 ++ src/network/protocols/client_lobby.cpp | 339 ++---------------- src/network/protocols/client_lobby.hpp | 21 +- src/network/protocols/connect_to_peer.hpp | 2 - src/network/protocols/lobby_protocol.hpp | 14 +- src/network/protocols/server_lobby.cpp | 202 ++--------- src/network/protocols/server_lobby.hpp | 13 +- src/states_screens/network_kart_selection.cpp | 2 + src/states_screens/track_info_screen.cpp | 3 +- src/states_screens/tracks_screen.cpp | 106 ++++-- src/states_screens/tracks_screen.hpp | 20 +- 11 files changed, 182 insertions(+), 560 deletions(-) diff --git a/data/gui/tracks.stkgui b/data/gui/tracks.stkgui index 70b90016d..1b02d6c30 100644 --- a/data/gui/tracks.stkgui +++ b/data/gui/tracks.stkgui @@ -17,5 +17,25 @@ + +
+
+ +
+
+
diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index aaee48d29..65b12d817 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -38,8 +38,10 @@ #include "online/online_profile.hpp" #include "states_screens/networking_lobby.hpp" #include "states_screens/network_kart_selection.hpp" +#include "states_screens/tracks_screen.hpp" #include "states_screens/race_result_gui.hpp" #include "states_screens/state_manager.hpp" +#include "tracks/track.hpp" #include "tracks/track_manager.hpp" #include "utils/log.hpp" @@ -91,122 +93,6 @@ void ClientLobby::setup() m_state = NONE; } // setup -//----------------------------------------------------------------------------- -/** Sends the selection of a kart from this client to the server. - * \param player_id The global player id of the voting player. - * \param kart_name Name of the selected kart. - */ -void ClientLobby::requestKartSelection(uint8_t player_id, - const std::string &kart_name) -{ - NetworkString *request = getNetworkString(3+kart_name.size()); - request->addUInt8(LE_KART_SELECTION).addUInt8(player_id) - .encodeString(kart_name); - sendToServer(request, /*reliable*/ true); - delete request; -} // requestKartSelection - -//----------------------------------------------------------------------------- -/** Sends a vote for a major vote from a client to the server. Note that even - * this client will only store the vote when it is received back from the - * server. - * \param player_id The global player id of the voting player. - * \param major Major mode voted for. - */ -void ClientLobby::voteMajor(uint8_t player_id, uint32_t major) -{ - NetworkString *request = getNetworkString(6); - request->addUInt8(LE_VOTE_MAJOR).addUInt8(player_id) - .addUInt32(major); - sendToServer(request, true); - delete request; -} // voteMajor - -//----------------------------------------------------------------------------- -/** Sends a vote for the number of tracks from a client to the server. Note - * that even this client will only store the vote when it is received back - * from the server. - * \param player_id The global player id of the voting player. - * \param count NUmber of tracks to play. - */ -void ClientLobby::voteRaceCount(uint8_t player_id, uint8_t count) -{ - NetworkString *request = getNetworkString(3); - request->addUInt8(LE_VOTE_RACE_COUNT).addUInt8(player_id).addUInt8(count); - sendToServer(request, true); - delete request; -} // voteRaceCount - -//----------------------------------------------------------------------------- -/** Sends a vote for the minor game mode from a client to the server. Note that - * even this client will only store the vote when it is received back from the - * server. - * \param player_id The global player id of the voting player. - * \param minor Voted minor mode. - */ -void ClientLobby::voteMinor(uint8_t player_id, uint32_t minor) -{ - NetworkString *request = getNetworkString(6); - request->addUInt8(LE_VOTE_MINOR).addUInt8(player_id).addUInt32(minor); - sendToServer(request, true); - delete request; -} // voteMinor - -//----------------------------------------------------------------------------- -/** Sends the vote about which track to play at which place in the list of - * tracks (like a custom GP definition). Note that even this client will only - * store the vote when it is received back from the server. - * \param player_id The global player id of the voting player. - * \param track Name of the track. - * \param At which place in the list of tracks this track should be played. - */ -void ClientLobby::voteTrack(uint8_t player_id, - const std::string &track, - uint8_t track_nb) -{ - NetworkString *request = getNetworkString(2+1+track.size()); - request->addUInt8(LE_VOTE_TRACK).addUInt8(player_id).addUInt8(track_nb) - .encodeString(track); - sendToServer(request, true); - delete request; -} // voteTrack - -//----------------------------------------------------------------------------- -/** Sends a vote if a track at a specified place in the list of all tracks - * should be played in reverse or not. Note that even this client will only - * store the vote when it is received back from the server. - * \param player_id Global player id of the voting player. - * \param reversed True if the track should be played in reverse. - * \param track_nb Index for the track to be voted on in the list of all - * tracks. - */ -void ClientLobby::voteReversed(uint8_t player_id, bool reversed, - uint8_t track_nb) -{ - NetworkString *request = getNetworkString(9); - request->addUInt8(LE_VOTE_REVERSE).addUInt8(player_id).addUInt8(reversed) - .addUInt8(track_nb); - sendToServer(request, true); - delete request; -} // voteReversed - -//----------------------------------------------------------------------------- -/** Vote for the number of laps of the specified track. Note that even this - * client will only store the vote when it is received back from the server. - * \param player_id Global player id of the voting player. - * \param laps Number of laps for the specified track. - * \param track_nb Index of the track in the list of all tracks. - */ -void ClientLobby::voteLaps(uint8_t player_id, uint8_t laps, - uint8_t track_nb) -{ - NetworkString *request = getNetworkString(10); - request->addUInt8(LE_VOTE_LAPS).addUInt8(player_id).addUInt8(laps) - .addUInt8(track_nb); - sendToServer(request, true); - delete request; -} // voteLaps - //----------------------------------------------------------------------------- /** Called from the gui when a client clicked on 'continue' on the race result * screen. It notifies the server that this client has exited the screen and @@ -234,7 +120,6 @@ bool ClientLobby::notifyEvent(Event* event) switch(message_type) { case LE_START_SELECTION: startSelection(event); break; - case LE_KART_SELECTION_UPDATE: kartSelectionUpdate(event); break; case LE_LOAD_WORLD: loadWorld(); break; case LE_RACE_FINISHED: raceFinished(event); break; case LE_EXIT_RESULT: exitResultScreen(event); break; @@ -266,13 +151,7 @@ bool ClientLobby::notifyEventAsynchronous(Event* event) case LE_START_RACE: startGame(event); break; case LE_CONNECTION_REFUSED: connectionRefused(event); break; case LE_CONNECTION_ACCEPTED: connectionAccepted(event); break; - case LE_KART_SELECTION_REFUSED: kartSelectionRefused(event); break; - case LE_VOTE_MAJOR : playerMajorVote(event); break; - case LE_VOTE_RACE_COUNT: playerRaceCountVote(event); break; - case LE_VOTE_MINOR: playerMinorVote(event); break; - case LE_VOTE_TRACK: playerTrackVote(event); break; - case LE_VOTE_REVERSE: playerReversedVote(event); break; - case LE_VOTE_LAPS: playerLapsVote(event); break; + case LE_VOTE: displayPlayerVote(event); break; case LE_SERVER_OWNERSHIP: becomingServerOwner(); break; default: break; } // switch @@ -310,7 +189,6 @@ bool ClientLobby::notifyEventAsynchronous(Event* event) } // notifyEventAsynchronous //----------------------------------------------------------------------------- - void ClientLobby::update(float dt) { switch (m_state) @@ -382,7 +260,9 @@ void ClientLobby::update(float dt) screen->setAvailableKartsFromServer(m_available_karts); screen->push(); m_state = SELECTING_KARTS; - + // Todo: add max lap + TracksScreen::getInstance()->setNetworkTracks(); + TracksScreen::getInstance()->setMaxLap(3); std::make_shared()->requestStart(); Log::info("LobbyProtocol", "LatencyProtocol started."); } @@ -403,7 +283,32 @@ void ClientLobby::update(float dt) } // update //----------------------------------------------------------------------------- +void ClientLobby::displayPlayerVote(Event* event) +{ + if (!checkDataSize(event, 4)) return; + // Get the player name who voted + core::stringw player_name; + NetworkString& data = event->data(); + data.decodeStringW(&player_name); + player_name += ": "; + std::string track_name; + data.decodeString(&track_name); + Track* track = track_manager->getTrack(track_name); + if (!track) + Log::fatal("ClientLobby", "Missing track %s", track_name.c_str()); + core::stringw track_readable = track->getName(); + int lap = data.getUInt8(); + bool reversed = (bool)data.getUInt8(); + core::stringw yes = _("Yes"); + core::stringw no = _("No"); + //I18N: Vote message in network game from a player + core::stringw vote_msg = _("Track: %s, Laps: %d, Reversed: %s", + track_readable, lap, reversed ? yes : no); + vote_msg = player_name + vote_msg; + MessageQueue::add(MessageQueue::MT_GENERIC, vote_msg); +} // displayPlayerVote +//----------------------------------------------------------------------------- /*! \brief Called when a new player is disconnected * \param event : Event providing the information. * @@ -552,58 +457,6 @@ void ClientLobby::connectionRefused(Event* event) //----------------------------------------------------------------------------- -/*! \brief Called when the server refuses the kart selection request. - * \param event : Event providing the information. - * - * Format of the data : - * Byte 0 - * ---------------- - * Size | 1 | - * Data | refusal code | - * ---------------- - */ -void ClientLobby::kartSelectionRefused(Event* event) -{ - if(!checkDataSize(event, 1)) return; - - const NetworkString &data = event->data(); - - switch (data.getUInt8()) // the error code - { - case 0: - Log::info("ClientLobby", - "Kart selection refused : already taken."); - break; - case 1: - Log::info("ClientLobby", - "Kart selection refused : not available."); - break; - default: - Log::info("ClientLobby", "Kart selection refused."); - break; - } -} // kartSelectionRefused - -//----------------------------------------------------------------------------- - -/*! \brief Called when the server tells to update a player's kart. - * \param event : Event providing the information. - * - * Format of the data : - * Byte 0 1 2 3 N+3 - * -------------------------------------------------- - * Size | 1 | 1 | N | - * Data | player id | N (kart name size) | kart name | - * -------------------------------------------------- - */ -void ClientLobby::kartSelectionUpdate(Event* event) -{ - if(!checkDataSize(event, 3)) return; - -} // kartSelectionUpdate - -//----------------------------------------------------------------------------- - /*! \brief Called when the server broadcasts to start the race to all clients. * \param event : Event providing the information (no additional information * in this case). @@ -728,136 +581,6 @@ void ClientLobby::exitResultScreen(Event *event) m_state = NONE; } // exitResultScreen -//----------------------------------------------------------------------------- -/*! \brief Called when a player votes for a major race mode. - * \param event : Event providing the information. - * - * Format of the data : - * Byte 0 1 2 - * ------------------------------ - * Size | 1 | 1 | - * Data |player id | major mode vote | - * ------------------------------ - */ -void ClientLobby::playerMajorVote(Event* event) -{ - const NetworkString &data = event->data(); - if (!checkDataSize(event, 2)) - return; - uint8_t player_id = data.getUInt8(); - uint8_t mode = data.getUInt8(); - m_game_setup->getRaceConfig()->setPlayerMajorVote(player_id, mode); -} // playerMajorVote - -//----------------------------------------------------------------------------- -/*! \brief Called when a player votes for the number of races in a GP. - * \param event : Event providing the information. - * - * Format of the data : - * Byte 0 1 - * --------------------------- - * Size | 1 | 1 | - * Data | player id | races count | - * --------------------------- - */ -void ClientLobby::playerRaceCountVote(Event* event) -{ - if (!checkDataSize(event, 2)) return; - const NetworkString &data = event->data(); - uint8_t player_id = data.getUInt8(); - uint8_t count = data.getUInt8(); - m_game_setup->getRaceConfig()->setPlayerRaceCountVote(player_id, count); -} // playerRaceCountVote - -//----------------------------------------------------------------------------- -/*! \brief Called when a player votes for a minor race mode. - * \param event : Event providing the information. - * - * Format of the data : - * Byte 0 1 - * ------------------------------- - * Size | 1 | 4 | - * Data | player id | minor mode vote | - * ------------------------------- - */ -void ClientLobby::playerMinorVote(Event* event) -{ - if (!checkDataSize(event, 2)) return; - const NetworkString &data = event->data(); - uint8_t player_id = data.getUInt8(); - uint8_t minor = data.getUInt8(); - m_game_setup->getRaceConfig()->setPlayerMinorVote(player_id, minor); -} // playerMinorVote - -//----------------------------------------------------------------------------- - -/*! \brief Called when a player votes for a track. - * \param event : Event providing the information. - * - * Format of the data : - * Byte 0 1 2 3 - * -------------------------------------------------- - * Size | 1 | 1 | 1 | N | - * Data | player id | track number (gp) | N | track name | - * -------------------------------------------------- - */ -void ClientLobby::playerTrackVote(Event* event) -{ - if (!checkDataSize(event, 3)) return; - const NetworkString &data = event->data(); - std::string track_name; - uint8_t player_id = data.getUInt8(); - uint8_t number = data.getUInt8(); - data.decodeString(&track_name); - m_game_setup->getRaceConfig()->setPlayerTrackVote(player_id, track_name, - number); -} // playerTrackVote - -//----------------------------------------------------------------------------- - -/*! \brief Called when a player votes for the reverse mode of a race - * \param event : Event providing the information. - * - * Format of the data : - * Byte 0 1 2 - * ------------------------------------------- - * Size | 1 | 1 | 1 | - * Data | player id |reversed | track number (gp) | - * ------------------------------------------- - */ -void ClientLobby::playerReversedVote(Event* event) -{ - if (!checkDataSize(event, 3)) return; - const NetworkString &data = event->data(); - uint8_t player_id = data.getUInt8(); - uint8_t reversed = data.getUInt8(); - uint8_t number = data.getUInt8(); - m_game_setup->getRaceConfig()->setPlayerReversedVote(player_id, reversed!=0, - number); -} // playerReversedVote - -//----------------------------------------------------------------------------- - -/*! \brief Called when a player votes for a major race mode. - * \param event : Event providing the information. - * - * Format of the data : - * Byte 0 1 2 - * ---------------------------------------- - * Size | 1 | 1 | 1 | - * Data | player id | laps | track number (gp) | - * ---------------------------------------- - */ -void ClientLobby::playerLapsVote(Event* event) -{ - if (!checkDataSize(event, 3)) return; - const NetworkString &data = event->data(); - uint8_t player_id = data.getUInt8(); - uint8_t laps = data.getUInt8(); - uint8_t number = data.getUInt8(); - m_game_setup->getRaceConfig()->setPlayerLapsVote(player_id, laps, number); -} // playerLapsVote - //----------------------------------------------------------------------------- /** Callback when the world is loaded. The client will inform the server * that the players on this host are ready to start the race. It is called by diff --git a/src/network/protocols/client_lobby.hpp b/src/network/protocols/client_lobby.hpp index 1273d3c44..c09686e94 100644 --- a/src/network/protocols/client_lobby.hpp +++ b/src/network/protocols/client_lobby.hpp @@ -12,19 +12,12 @@ private: void disconnectedPlayer(Event* event); void connectionAccepted(Event* event); //!< Callback function on connection acceptation void connectionRefused(Event* event); //!< Callback function on connection refusal - void kartSelectionRefused(Event* event); - void kartSelectionUpdate(Event* event); void startGame(Event* event); void startSelection(Event* event); void raceFinished(Event* event); void exitResultScreen(Event *event); // race votes - void playerMajorVote(Event* event); - void playerRaceCountVote(Event* event); - void playerMinorVote(Event* event); - void playerTrackVote(Event* event); - void playerReversedVote(Event* event); - void playerLapsVote(Event* event); + void displayPlayerVote(Event* event); void updatePlayerList(Event* event); void handleChat(Event* event); void becomingServerOwner(); @@ -54,25 +47,13 @@ private: public: ClientLobby(); virtual ~ClientLobby(); - - virtual void requestKartSelection(uint8_t player_id, - const std::string &kart_name) OVERRIDE; void setAddress(const TransportAddress &address); - void voteMajor(uint8_t player_id, uint32_t major); - void voteRaceCount(uint8_t player_id, uint8_t count); - void voteMinor(uint8_t player_id, uint32_t minor); - void voteTrack(uint8_t player_id, const std::string &track, - uint8_t track_nb = 0); - void voteReversed(uint8_t player_id, bool reversed, uint8_t track_nb = 0); - void voteLaps(uint8_t player_id, uint8_t laps, uint8_t track_nb = 0); void doneWithResults(); void startingRaceNow(); - const std::set& getAvailableKarts() const { return m_available_karts; } const std::set& getAvailableTracks() const { return m_available_tracks; } - virtual bool notifyEvent(Event* event) OVERRIDE; virtual bool notifyEventAsynchronous(Event* event) OVERRIDE; virtual void finishedLoadingWorld() OVERRIDE; diff --git a/src/network/protocols/connect_to_peer.hpp b/src/network/protocols/connect_to_peer.hpp index ac075a0fd..c2b865153 100644 --- a/src/network/protocols/connect_to_peer.hpp +++ b/src/network/protocols/connect_to_peer.hpp @@ -23,8 +23,6 @@ #include "network/transport_address.hpp" #include "utils/cpp2011.hpp" -#include - /** One instance of this is started for every peer who tries to * connect to this server. */ diff --git a/src/network/protocols/lobby_protocol.hpp b/src/network/protocols/lobby_protocol.hpp index 8782a5e14..92c1cad69 100644 --- a/src/network/protocols/lobby_protocol.hpp +++ b/src/network/protocols/lobby_protocol.hpp @@ -53,15 +53,8 @@ public: LE_RACE_FINISHED, // race has finished, display result LE_RACE_FINISHED_ACK, // client went back to lobby LE_EXIT_RESULT, // Force clients to exit race result screen - LE_VOTE, // Any vote (race mode, track, ...) - LE_VOTE_MAJOR, // vote of major race mode - LE_VOTE_MINOR, // vote for minor race mode - LE_VOTE_RACE_COUNT, // vote for number of tracks - LE_VOTE_TRACK, // vote for a track - LE_VOTE_REVERSE, // vote if race in reverse - LE_VOTE_LAPS, // vote number of laps + LE_VOTE, // Track vote LE_CHAT, - LE_FINAL_PLAYER_LIST, LE_SERVER_OWNERSHIP, LE_KICK_HOST }; @@ -115,11 +108,6 @@ public: virtual void loadWorld(); virtual bool waitingForPlayers() const = 0; void terminateLatencyProtocol(); - virtual void requestKartSelection(uint8_t player_id, - const std::string &kart_name) - { - assert(false); // Only defined in client - }; GameSetup* getGameSetup() const { return m_game_setup; } }; // class LobbyProtocol diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index dbb061de9..818779a0a 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -205,12 +205,7 @@ bool ServerLobby::notifyEventAsynchronous(Event* event) case LE_KART_SELECTION: kartSelectionRequested(event); break; case LE_CLIENT_LOADED_WORLD: finishedLoadingWorldClient(event); break; case LE_STARTED_RACE: startedRaceOnClient(event); break; - case LE_VOTE_MAJOR: playerMajorVote(event); break; - case LE_VOTE_RACE_COUNT: playerRaceCountVote(event); break; - case LE_VOTE_MINOR: playerMinorVote(event); break; - case LE_VOTE_TRACK: playerTrackVote(event); break; - case LE_VOTE_REVERSE: playerReversedVote(event); break; - case LE_VOTE_LAPS: playerLapsVote(event); break; + case LE_VOTE: playerVote(event); break; case LE_RACE_FINISHED_ACK: playerFinishedResult(event); break; case LE_KICK_HOST: kickHost(event); break; case LE_CHAT: handleChat(event); break; @@ -572,6 +567,9 @@ void ServerLobby::startSelection(const Event *event) delete ns; m_state = SELECTING; + // 30 seconds for clients to choose kart and track + // will be increased later if there is grand prix + m_timeout = StkTime::getRealTime() + 30.0f; WaitingForOthersScreen::getInstance()->push(); std::make_shared()->requestStart(); @@ -954,7 +952,10 @@ void ServerLobby::kartSelectionRequested(Event* event) return; } - if (!checkDataSize(event, 1)) return; + if (!checkDataSize(event, 1) || + event->getPeer()->getPlayerProfiles().empty()) + return; + const NetworkString& data = event->data(); STKPeer* peer = event->getPeer(); unsigned player_count = data.getUInt8(); @@ -979,185 +980,24 @@ void ServerLobby::kartSelectionRequested(Event* event) } // kartSelectionRequested //----------------------------------------------------------------------------- - -/*! \brief Called when a player votes for a major race mode. +/*! \brief Called when a player votes for track(s). * \param event : Event providing the information. - * - * Format of the data : - * Byte 0 1 - * ------------------------------- - * Size | 1 | 4 | - * Data | player-id | major mode vote | - * ------------------------------- */ -void ServerLobby::playerMajorVote(Event* event) +void ServerLobby::playerVote(Event* event) { - if (!checkDataSize(event, 5)) return; + if (!checkDataSize(event, 4) || + event->getPeer()->getPlayerProfiles().empty()) + return; - NetworkString &data = event->data(); - uint8_t player_id = data.getUInt8(); - uint32_t major = data.getUInt32(); - m_game_setup->getRaceConfig()->setPlayerMajorVote(player_id, major); - // Send the vote to everybody (including the sender) - NetworkString *other = getNetworkString(6); - other->addUInt8(LE_VOTE_MAJOR).addUInt8(player_id).addUInt32(major); - sendMessageToPeersChangingToken(other); - delete other; -} // playerMajorVote + NetworkString& data = event->data(); + NetworkString other = NetworkString(PROTOCOL_LOBBY_ROOM); + other.addUInt8(LE_VOTE).encodeString(event->getPeer() + ->getPlayerProfiles()[0]->getName()); + other += data; + sendMessageToPeersChangingToken(&other); -//----------------------------------------------------------------------------- -/** \brief Called when a player votes for the number of races in a GP. - * \param event : Event providing the information. - * - * Format of the data : - * Byte 0 1 - * --------------------------- - * Size | 1 | 4 | - * Data | player-id | races count | - * --------------------------- - */ -void ServerLobby::playerRaceCountVote(Event* event) -{ - if (!checkDataSize(event, 1)) return; - NetworkString &data = event->data(); - uint8_t player_id = data.getUInt8(); - uint8_t race_count = data.getUInt8(); - m_game_setup->getRaceConfig()->setPlayerRaceCountVote(player_id, race_count); - // Send the vote to everybody (including the sender) - NetworkString *other = getNetworkString(3); - other->addUInt8(LE_VOTE_RACE_COUNT).addUInt8(player_id) - .addUInt8(race_count); - sendMessageToPeersChangingToken(other); - delete other; -} // playerRaceCountVote - -//----------------------------------------------------------------------------- - -/*! \brief Called when a player votes for a minor race mode. - * \param event : Event providing the information. - * - * Format of the data : - * Byte 0 1 - * ------------------------------- - * Size | 1 | 4 | - * Data | player-id | minor mode vote | - * ------------------------------- - */ -void ServerLobby::playerMinorVote(Event* event) -{ - if (!checkDataSize(event, 1)) return; - NetworkString &data = event->data(); - uint8_t player_id = data.getUInt8(); - uint32_t minor = data.getUInt32(); - m_game_setup->getRaceConfig()->setPlayerMinorVote(player_id, minor); - - // Send the vote to everybody (including the sender) - NetworkString *other = getNetworkString(3); - other->addUInt8(LE_VOTE_MINOR).addUInt8(player_id).addUInt8(minor); - sendMessageToPeersChangingToken(other); - delete other; -} // playerMinorVote - -//----------------------------------------------------------------------------- - -/*! \brief Called when a player votes for a track. - * \param event : Event providing the information. - * - * Format of the data : - * Byte 0 1 2 3 - * -------------------------------------------------- - * Size | 1 | 1 | 1 | N | - * Data | player id | track number (gp) | N | track name | - * -------------------------------------------------- - */ -void ServerLobby::playerTrackVote(Event* event) -{ - if (!checkDataSize(event, 3)) return; - NetworkString &data = event->data(); - uint8_t player_id = data.getUInt8(); - // As which track this track should be used, e.g. 1st track: Sandtrack - // 2nd track Mathclass, ... - uint8_t track_number = data.getUInt8(); - std::string track_name; - int N = data.decodeString(&track_name); - m_game_setup->getRaceConfig()->setPlayerTrackVote(player_id, track_name, - track_number); - // Send the vote to everybody (including the sender) - NetworkString *other = getNetworkString(3+1+data.size()); - other->addUInt8(LE_VOTE_TRACK).addUInt8(player_id).addUInt8(track_number) - .encodeString(track_name); - sendMessageToPeersChangingToken(other); - delete other; - - // Check if we received all information - if (m_game_setup->getRaceConfig()->getNumTrackVotes() == - m_game_setup->getPlayerCount()) - { - // Inform clients to start loading the world - NetworkString *ns = getNetworkString(1); - ns->setSynchronous(true); - ns->addUInt8(LE_LOAD_WORLD); - sendMessageToPeersChangingToken(ns, /*reliable*/true); - delete ns; - m_state = LOAD_WORLD; // Server can now load world - } -} // playerTrackVote - -//----------------------------------------------------------------------------- -/*! \brief Called when a player votes for the reverse mode of a race - * \param event : Event providing the information. - * - * Format of the data : - * Byte 0 1 2 - * -------------------------------------------- - * Size | 1 | 1 | 1 | - * Data | player id | reversed | track number (gp) | - * -------------------------------------------- - */ -void ServerLobby::playerReversedVote(Event* event) -{ - if (!checkDataSize(event, 3)) return; - - NetworkString &data = event->data(); - uint8_t player_id = data.getUInt8(); - uint8_t reverse = data.getUInt8(); - uint8_t nb_track = data.getUInt8(); - m_game_setup->getRaceConfig()->setPlayerReversedVote(player_id, - reverse!=0, nb_track); - // Send the vote to everybody (including the sender) - NetworkString *other = getNetworkString(4); - other->addUInt8(LE_VOTE_REVERSE).addUInt8(player_id).addUInt8(reverse) - .addUInt8(nb_track); - sendMessageToPeersChangingToken(other); - delete other; -} // playerReversedVote - -//----------------------------------------------------------------------------- -/*! \brief Called when a player votes for a major race mode. - * \param event : Event providing the information. - * - * Format of the data : - * Byte 0 1 2 - * ---------------------------------------- - * Size | 1 | 1 | 1 | - * Data | player id | laps | track number (gp) | - * ---------------------------------------- - */ -void ServerLobby::playerLapsVote(Event* event) -{ - if (!checkDataSize(event, 2)) return; - NetworkString &data = event->data(); - uint8_t player_id = data.getUInt8(); - uint8_t lap_count = data.getUInt8(); - uint8_t track_nb = data.getUInt8(); - m_game_setup->getRaceConfig()->setPlayerLapsVote(player_id, lap_count, - track_nb); - NetworkString *other = getNetworkString(4); - other->addUInt8(LE_VOTE_LAPS).addUInt8(player_id).addUInt8(lap_count) - .addUInt8(track_nb); - sendMessageToPeersChangingToken(other); - delete other; -} // playerLapsVote + // Save the vote +} // playerVote // ---------------------------------------------------------------------------- /** Called from the RaceManager of the server when the world is loaded. Marks diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index 2d5f6e192..2dd10b3b9 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -63,7 +63,7 @@ private: /** Counts how many players are ready to go on. */ int m_player_ready_counter; - /** Timeout counter for showing the result screen. */ + /** Timeout counter for various state. */ float m_timeout; /** Lock this mutex whenever a client is connect / disconnect or @@ -75,13 +75,8 @@ private: void connectionRequested(Event* event); // kart selection void kartSelectionRequested(Event* event); - // race votes - void playerMajorVote(Event* event); - void playerRaceCountVote(Event* event); - void playerMinorVote(Event* event); - void playerTrackVote(Event* event); - void playerReversedVote(Event* event); - void playerLapsVote(Event* event); + // Track(s) votes + void playerVote(Event *event); void playerFinishedResult(Event *event); void registerServer(); void finishedLoadingWorldClient(Event *event); @@ -108,7 +103,7 @@ public: void startSelection(const Event *event=NULL); void checkIncomingConnectionRequests(); void checkRaceFinished(); - void finishedLoadingWorld(); + void finishedLoadingWorld() OVERRIDE; ServerState getCurrentState() const { return m_state.load(); } virtual bool waitingForPlayers() const OVERRIDE { return m_state.load() == ACCEPTING_CLIENTS; } diff --git a/src/states_screens/network_kart_selection.cpp b/src/states_screens/network_kart_selection.cpp index 39f5fcd79..d87551e68 100644 --- a/src/states_screens/network_kart_selection.cpp +++ b/src/states_screens/network_kart_selection.cpp @@ -149,6 +149,8 @@ void NetworkKartSelectionScreen::playerConfirm(const int playerID) .encodeString(selection); STKHost::get()->sendToServer(&kart, true); input_manager->getDeviceManager()->setAssignMode(ASSIGN); + // Remove kart screen + StateManager::get()->popMenu(); TracksScreen::getInstance()->push(); } } // playerConfirm diff --git a/src/states_screens/track_info_screen.cpp b/src/states_screens/track_info_screen.cpp index c86d47ac9..d09c742e3 100644 --- a/src/states_screens/track_info_screen.cpp +++ b/src/states_screens/track_info_screen.cpp @@ -374,7 +374,8 @@ void TrackInfoScreen::onEnterPressedInternal() num_ai = m_ai_kart_spinner->getValue(); - if (UserConfigParams::m_num_karts_per_gamemode[race_manager->getMinorMode()] != (local_players + num_ai)) + if (UserConfigParams::m_num_karts_per_gamemode + [race_manager->getMinorMode()] != unsigned(local_players + num_ai)) { race_manager->setNumKarts(local_players + num_ai); UserConfigParams::m_num_karts_per_gamemode[race_manager->getMinorMode()] = local_players + num_ai; diff --git a/src/states_screens/tracks_screen.cpp b/src/states_screens/tracks_screen.cpp index 1dbfac7bc..edaeb5fd0 100644 --- a/src/states_screens/tracks_screen.cpp +++ b/src/states_screens/tracks_screen.cpp @@ -22,10 +22,12 @@ #include "config/user_config.hpp" #include "graphics/stk_tex_manager.hpp" #include "guiengine/widget.hpp" +#include "guiengine/widgets/check_box_widget.hpp" #include "guiengine/widgets/dynamic_ribbon_widget.hpp" #include "guiengine/widgets/icon_button_widget.hpp" +#include "guiengine/widgets/label_widget.hpp" +#include "guiengine/widgets/spinner_widget.hpp" #include "io/file_manager.hpp" -#include "network/network_player_profile.hpp" #include "network/protocols/client_lobby.hpp" #include "network/network_config.hpp" #include "network/stk_host.hpp" @@ -88,21 +90,16 @@ void TracksScreen::eventCallback(Widget* widget, const std::string& name, if (track) { - if(STKHost::existHost()) + if (STKHost::existHost()) { - auto clrp = LobbyProtocol::get(); - // server never shows the track screen. - assert(clrp); - // FIXME SPLITSCREEN: we need to supply the global player id of the - // player selecting the track here. For now ... just vote the same - // track for each local player. - /*std::vector players = - STKHost::get()->getMyPlayerProfiles(); - for(unsigned int i=0; ivoteTrack(players[i]->getGlobalPlayerId(),selection); - } - WaitingForOthersScreen::getInstance()->push();*/ + NetworkString vote(PROTOCOL_LOBBY_ROOM); + vote.addUInt8(LobbyProtocol::LE_VOTE); + vote.encodeString(track->getIdent()).addUInt8 + (getWidget("lap-spinner")->getValue()) + .addUInt8( + getWidget("reverse")->getState()); + STKHost::get()->sendToServer(&vote, true); + WaitingForOthersScreen::getInstance()->push(); } else { @@ -125,10 +122,28 @@ void TracksScreen::eventCallback(Widget* widget, const std::string& name, } // eventCallback // ----------------------------------------------------------------------------- +bool TracksScreen::onEscapePressed() +{ + if (m_network_tracks) + { + // Remove this screen + StateManager::get()->popMenu(); + STKHost::get()->shutdown(); + } + return true; // remove the screen +} // onEscapePressed +// ----------------------------------------------------------------------------- +void TracksScreen::tearDown() +{ + m_network_tracks = false; +} // tearDown + +// ----------------------------------------------------------------------------- void TracksScreen::beforeAddingWidget() { Screen::init(); + RibbonWidget* tabs = getWidget("trackgroups"); tabs->clearAllChildren(); @@ -147,12 +162,24 @@ void TracksScreen::beforeAddingWidget() DynamicRibbonWidget* tracks_widget = getWidget("tracks"); tracks_widget->setItemCountHint( (int)track_manager->getNumberOfTracks()+1 ); + } // beforeAddingWidget // ----------------------------------------------------------------------------- - void TracksScreen::init() { + // change the back button image (because it makes the game quit) + if (m_network_tracks) + { + IconButtonWidget* back_button = getWidget("back"); + back_button->setImage("gui/main_quit.png"); + } + else + { + IconButtonWidget* back_button = getWidget("back"); + back_button->setImage("gui/back.png"); + } + DynamicRibbonWidget* tracks_widget = getWidget("tracks"); assert(tracks_widget != NULL); @@ -171,16 +198,48 @@ void TracksScreen::init() tracks_widget->setSelection(0, PLAYER_ID_GAME_MASTER, true); } STKTexManager::getInstance()->unsetTextureErrorMessage(); - if (NetworkConfig::get()->isAutoConnect()) + if (!m_network_tracks) { - DynamicRibbonWidget* tw = getWidget("tracks"); - tw->setSelection(UserConfigParams::m_last_track, 0, - /*focus*/true); - eventCallback(tw, "tracks", - /*player id*/0); + getWidget("lap-text")->setActive(false); + getWidget("lap-text")->setVisible(false); + getWidget("lap-spinner")->setActive(false); + getWidget("lap-spinner")->setVisible(false); + getWidget("reverse-text")->setActive(false); + getWidget("reverse-text")->setVisible(false); + getWidget("reverse")->setActive(false); + getWidget("reverse")->setVisible(false); + } + else + { + getWidget("lap-text")->setActive(true); + getWidget("lap-text")->setVisible(true); + getWidget("lap-spinner")->setActive(true); + getWidget("lap-spinner")->setVisible(true); + getWidget("lap-spinner")->setMin(1); + getWidget("lap-spinner")->setMax(m_max_lap); + getWidget("lap-spinner")->setValue(1); + getWidget("reverse-text")->setActive(true); + getWidget("reverse-text")->setVisible(true); + getWidget("reverse")->setActive(true); + getWidget("reverse")->setVisible(true); + getWidget("reverse")->setState(false); } } // init +// ----------------------------------------------------------------------------- +void TracksScreen::onUpdate(float dt) +{ + if (NetworkConfig::get()->isAutoConnect() && m_network_tracks) + { + assert(!m_random_track_list.empty()); + NetworkString vote(PROTOCOL_LOBBY_ROOM); + vote.addUInt8(LobbyProtocol::LE_VOTE); + vote.encodeString(m_random_track_list[0]).addUInt8(1).addUInt8(0); + STKHost::get()->sendToServer(&vote, true); + WaitingForOthersScreen::getInstance()->push(); + } +} // onUpdate + // ----------------------------------------------------------------------------- /** Rebuild the list of tracks. This need to be recomputed e.g. to * take unlocked tracks into account. @@ -257,7 +316,6 @@ void TracksScreen::buildTrackList() } // buildTrackList // ----------------------------------------------------------------------------- - void TracksScreen::setFocusOnTrack(const std::string& trackName) { DynamicRibbonWidget* tracks_widget = this->getWidget("tracks"); @@ -266,5 +324,3 @@ void TracksScreen::setFocusOnTrack(const std::string& trackName) // so it's safe to use 'PLAYER_ID_GAME_MASTER' tracks_widget->setSelection(trackName, PLAYER_ID_GAME_MASTER, true); } // setFocusOnTrack - -// ----------------------------------------------------------------------------- diff --git a/src/states_screens/tracks_screen.hpp b/src/states_screens/tracks_screen.hpp index 5ca99313e..df35b0f8d 100644 --- a/src/states_screens/tracks_screen.hpp +++ b/src/states_screens/tracks_screen.hpp @@ -33,7 +33,14 @@ class TracksScreen : public GUIEngine::Screen, friend class GUIEngine::ScreenSingleton; private: - TracksScreen() : Screen("tracks.stkgui") {} + TracksScreen() : Screen("tracks.stkgui") + { + m_network_tracks = false; + m_max_lap = 0; + } + + bool m_network_tracks; + unsigned m_max_lap; /** adds the tracks from the current track group into the tracks ribbon */ void buildTrackList(); @@ -56,8 +63,19 @@ public: /** \brief implement callback from parent class GUIEngine::Screen */ virtual void beforeAddingWidget() OVERRIDE; + /** \brief implement callback from parent class GUIEngine::Screen */ + virtual void tearDown() OVERRIDE; + + /** \brief implement callback from parent class GUIEngine::Screen */ + virtual void onUpdate(float dt) OVERRIDE; + + /** \brief implement callback from parent class GUIEngine::Screen */ + virtual bool onEscapePressed() OVERRIDE; + void setFocusOnTrack(const std::string& trackName); + void setNetworkTracks() { m_network_tracks = true; } + void setMaxLap(unsigned lap) { m_max_lap = lap; } }; #endif