Show player vote in message queue for immediate effect

This commit is contained in:
Benau 2018-03-16 00:54:02 +08:00
parent bc56c07c51
commit f78276a930
11 changed files with 182 additions and 560 deletions

View File

@ -17,5 +17,25 @@
<tabs width="100%" height="25" id="trackgroups"> </tabs>
<spacer width="100%" height="2%" />
<box width="100%" height="20%" padding="15" layout="vertical-row">
<div width="100%" height="fit" layout="horizontal-row" >
<label id="lap-text" proportion="1" I18N="In the track screen" text="Number of laps" text_align="right"/>
<spacer width="40"/>
<div proportion="1" height="fit" layout="horizontal-row">
<spinner id="lap-spinner" width="50%" min_value="1" max_value="20" align="center"
wrap_around="true" />
</div>
</div>
<spacer height="10"/>
<div width="100%" height="fit" layout="horizontal-row" >
<label id="reverse-text" proportion="1" I18N="In the track screen" text="Drive in reverse" text_align="right"/>
<spacer width="40"/>
<div proportion="1" height="fit" layout="horizontal-row">
<div width="50%" height="fit" text-align="center" layout="vertical-row" >
<checkbox id="reverse" align="center"/>
</div>
</div>
</div>
</box>
</div>
</stkgui>

View File

@ -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<LatencyProtocol>()->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

View File

@ -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<std::string>& getAvailableKarts() const
{ return m_available_karts; }
const std::set<std::string>& getAvailableTracks() const
{ return m_available_tracks; }
virtual bool notifyEvent(Event* event) OVERRIDE;
virtual bool notifyEventAsynchronous(Event* event) OVERRIDE;
virtual void finishedLoadingWorld() OVERRIDE;

View File

@ -23,8 +23,6 @@
#include "network/transport_address.hpp"
#include "utils/cpp2011.hpp"
#include <chrono>
/** One instance of this is started for every peer who tries to
* connect to this server.
*/

View File

@ -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

View File

@ -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<LatencyProtocol>()->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

View File

@ -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; }

View File

@ -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

View File

@ -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;

View File

@ -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<ClientLobby>();
// 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<NetworkPlayerProfile*> players =
STKHost::get()->getMyPlayerProfiles();
for(unsigned int i=0; i<players.size(); i++)
{
clrp->voteTrack(players[i]->getGlobalPlayerId(),selection);
}
WaitingForOthersScreen::getInstance()->push();*/
NetworkString vote(PROTOCOL_LOBBY_ROOM);
vote.addUInt8(LobbyProtocol::LE_VOTE);
vote.encodeString(track->getIdent()).addUInt8
(getWidget<SpinnerWidget>("lap-spinner")->getValue())
.addUInt8(
getWidget<CheckBoxWidget>("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<RibbonWidget>("trackgroups");
tabs->clearAllChildren();
@ -147,12 +162,24 @@ void TracksScreen::beforeAddingWidget()
DynamicRibbonWidget* tracks_widget = getWidget<DynamicRibbonWidget>("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<IconButtonWidget>("back");
back_button->setImage("gui/main_quit.png");
}
else
{
IconButtonWidget* back_button = getWidget<IconButtonWidget>("back");
back_button->setImage("gui/back.png");
}
DynamicRibbonWidget* tracks_widget = getWidget<DynamicRibbonWidget>("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<DynamicRibbonWidget>("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<SpinnerWidget>("lap-spinner")->setMin(1);
getWidget<SpinnerWidget>("lap-spinner")->setMax(m_max_lap);
getWidget<SpinnerWidget>("lap-spinner")->setValue(1);
getWidget("reverse-text")->setActive(true);
getWidget("reverse-text")->setVisible(true);
getWidget("reverse")->setActive(true);
getWidget("reverse")->setVisible(true);
getWidget<CheckBoxWidget>("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<DynamicRibbonWidget>("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
// -----------------------------------------------------------------------------

View File

@ -33,7 +33,14 @@ class TracksScreen : public GUIEngine::Screen,
friend class GUIEngine::ScreenSingleton<TracksScreen>;
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