implementing the race vote network communications
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/hilnius@14135 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
a637ce6e36
commit
26321be49d
Binary file not shown.
@ -44,14 +44,6 @@ void* waitInput(void* data)
|
|||||||
{
|
{
|
||||||
stop = true;
|
stop = true;
|
||||||
}
|
}
|
||||||
else if (str == "disconnect")
|
|
||||||
{
|
|
||||||
NetworkManager::getInstance()->getPeers()[0]->disconnect();
|
|
||||||
}
|
|
||||||
else if (str == "connect")
|
|
||||||
{
|
|
||||||
ProtocolManager::getInstance()->requestStart(new ConnectToServer());
|
|
||||||
}
|
|
||||||
else if (str == "select")
|
else if (str == "select")
|
||||||
{
|
{
|
||||||
std::string str2;
|
std::string str2;
|
||||||
@ -60,9 +52,48 @@ void* waitInput(void* data)
|
|||||||
ClientLobbyRoomProtocol* clrp = static_cast<ClientLobbyRoomProtocol*>(protocol);
|
ClientLobbyRoomProtocol* clrp = static_cast<ClientLobbyRoomProtocol*>(protocol);
|
||||||
clrp->requestKartSelection(str2);
|
clrp->requestKartSelection(str2);
|
||||||
}
|
}
|
||||||
else if (str == "synchronize")
|
else if (str == "vote")
|
||||||
{
|
{
|
||||||
ProtocolManager::getInstance()->requestStart(new SynchronizationProtocol());
|
std::cout << "Vote for ? (track/laps/reversed/major/minor/race#) :";
|
||||||
|
std::string str2;
|
||||||
|
getline(std::cin, str2);
|
||||||
|
Protocol* protocol = ProtocolManager::getInstance()->getProtocol(PROTOCOL_LOBBY_ROOM);
|
||||||
|
ClientLobbyRoomProtocol* clrp = static_cast<ClientLobbyRoomProtocol*>(protocol);
|
||||||
|
if (str2 == "track")
|
||||||
|
{
|
||||||
|
std::cin >> str2;
|
||||||
|
clrp->voteTrack(str2);
|
||||||
|
}
|
||||||
|
else if (str2 == "laps")
|
||||||
|
{
|
||||||
|
int cnt;
|
||||||
|
std::cin >> cnt;
|
||||||
|
clrp->voteLaps(cnt);
|
||||||
|
}
|
||||||
|
else if (str2 == "reversed")
|
||||||
|
{
|
||||||
|
bool cnt;
|
||||||
|
std::cin >> cnt;
|
||||||
|
clrp->voteReversed(cnt);
|
||||||
|
}
|
||||||
|
else if (str2 == "major")
|
||||||
|
{
|
||||||
|
int cnt;
|
||||||
|
std::cin >> cnt;
|
||||||
|
clrp->voteMajor(cnt);
|
||||||
|
}
|
||||||
|
else if (str2 == "minor")
|
||||||
|
{
|
||||||
|
int cnt;
|
||||||
|
std::cin >> cnt;
|
||||||
|
clrp->voteMinor(cnt);
|
||||||
|
}
|
||||||
|
else if (str2 == "race#")
|
||||||
|
{
|
||||||
|
int cnt;
|
||||||
|
std::cin >> cnt;
|
||||||
|
clrp->voteRaceCount(cnt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (NetworkManager::getInstance()->getPeers().size() > 0)
|
else if (NetworkManager::getInstance()->getPeers().size() > 0)
|
||||||
{
|
{
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "network/protocol.hpp"
|
#include "network/protocol.hpp"
|
||||||
|
|
||||||
#include "network/protocol_manager.hpp"
|
#include "network/protocol_manager.hpp"
|
||||||
|
#include "network/network_manager.hpp"
|
||||||
|
|
||||||
Protocol::Protocol(CallbackObject* callback_object, PROTOCOL_TYPE type)
|
Protocol::Protocol(CallbackObject* callback_object, PROTOCOL_TYPE type)
|
||||||
{
|
{
|
||||||
@ -52,3 +53,47 @@ PROTOCOL_TYPE Protocol::getProtocolType()
|
|||||||
{
|
{
|
||||||
return m_type;
|
return m_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Protocol::checkDataSizeAndToken(Event* event, int minimum_size)
|
||||||
|
{
|
||||||
|
NetworkString data = event->data();
|
||||||
|
if (data.size() < minimum_size || data[0] != 4)
|
||||||
|
{
|
||||||
|
Log::warn("Protocol", "Receiving a badly "
|
||||||
|
"formated message. Size is %d and first byte %d",
|
||||||
|
data.size(), data[0]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
STKPeer* peer = *(event->peer);
|
||||||
|
uint32_t token = data.gui32(1);
|
||||||
|
if (token != peer->getClientServerToken())
|
||||||
|
{
|
||||||
|
Log::warn("Protocol", "Peer sending bad token. Request "
|
||||||
|
"aborted.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Protocol::isByteCorrect(Event* event, int byte_nb, int value)
|
||||||
|
{
|
||||||
|
NetworkString data = event->data();
|
||||||
|
if (data[byte_nb] != value)
|
||||||
|
{
|
||||||
|
Log::info("Protocol", "Bad byte at pos %d. %d "
|
||||||
|
"should be %d", byte_nb, data[byte_nb], value);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Protocol::sendMessageToPeersChangingToken(NetworkString prefix, NetworkString message)
|
||||||
|
{
|
||||||
|
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
|
||||||
|
for (unsigned int i = 0; i < peers.size(); i++)
|
||||||
|
{
|
||||||
|
prefix.ai8(4).ai32(peers[i]->getClientServerToken());
|
||||||
|
prefix += message;
|
||||||
|
m_listener->sendMessage(this, peers[i], prefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -112,6 +112,13 @@ class Protocol
|
|||||||
* \return The protocol type.
|
* \return The protocol type.
|
||||||
*/
|
*/
|
||||||
PROTOCOL_TYPE getProtocolType();
|
PROTOCOL_TYPE getProtocolType();
|
||||||
|
|
||||||
|
/// functions to check incoming data easily
|
||||||
|
bool checkDataSizeAndToken(Event* event, int minimum_size);
|
||||||
|
bool isByteCorrect(Event* event, int byte_nb, int value);
|
||||||
|
void sendMessageToPeersChangingToken(NetworkString prefix, NetworkString message);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ProtocolManager* m_listener; //!< The protocol listener
|
ProtocolManager* m_listener; //!< The protocol listener
|
||||||
PROTOCOL_TYPE m_type; //!< The type of the protocol
|
PROTOCOL_TYPE m_type; //!< The type of the protocol
|
||||||
|
@ -46,6 +46,7 @@ ClientLobbyRoomProtocol::~ClientLobbyRoomProtocol()
|
|||||||
void ClientLobbyRoomProtocol::setup()
|
void ClientLobbyRoomProtocol::setup()
|
||||||
{
|
{
|
||||||
m_setup = NetworkManager::getInstance()->setupNewGame(); // create a new setup
|
m_setup = NetworkManager::getInstance()->setupNewGame(); // create a new setup
|
||||||
|
m_setup->getRaceConfig()->setPlayerCount(16); //FIXME : this has to be changed when logging into the server
|
||||||
m_state = NONE;
|
m_state = NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +57,67 @@ void ClientLobbyRoomProtocol::requestKartSelection(std::string kart_name)
|
|||||||
NetworkString request;
|
NetworkString request;
|
||||||
// 0x02 : kart selection request, size_token (4), token, size kart name, kart name
|
// 0x02 : kart selection request, size_token (4), token, size kart name, kart name
|
||||||
request.ai8(0x02).ai8(4).ai32(m_server->getClientServerToken()).ai8(kart_name.size()).as(kart_name);
|
request.ai8(0x02).ai8(4).ai32(m_server->getClientServerToken()).ai8(kart_name.size()).as(kart_name);
|
||||||
m_listener->sendMessage(this, request);
|
m_listener->sendMessage(this, request, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ClientLobbyRoomProtocol::voteMajor(uint8_t major)
|
||||||
|
{
|
||||||
|
NetworkString request;
|
||||||
|
// 0xc0 : major vote, size_token (4), token, size major(1),major
|
||||||
|
request.ai8(0xc0).ai8(4).ai32(m_server->getClientServerToken()).ai8(1).ai8(major);
|
||||||
|
m_listener->sendMessage(this, request, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ClientLobbyRoomProtocol::voteRaceCount(uint8_t count)
|
||||||
|
{
|
||||||
|
NetworkString request;
|
||||||
|
// 0xc0 : race count vote, size_token (4), token, size race count(1), count
|
||||||
|
request.ai8(0xc1).ai8(4).ai32(m_server->getClientServerToken()).ai8(1).ai8(count);
|
||||||
|
m_listener->sendMessage(this, request, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ClientLobbyRoomProtocol::voteMinor(uint8_t minor)
|
||||||
|
{
|
||||||
|
NetworkString request;
|
||||||
|
// 0xc0 : minor vote, size_token (4), token, size minor(1),minor
|
||||||
|
request.ai8(0xc2).ai8(4).ai32(m_server->getClientServerToken()).ai8(1).ai8(minor);
|
||||||
|
m_listener->sendMessage(this, request, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ClientLobbyRoomProtocol::voteTrack(std::string track, uint8_t track_nb)
|
||||||
|
{
|
||||||
|
NetworkString request;
|
||||||
|
// 0xc0 : major vote, size_token (4), token, size track, track, size #track, #track
|
||||||
|
request.ai8(0xc3).ai8(4).ai32(m_server->getClientServerToken()).ai8(track.size()).as(track).ai8(1).ai8(track_nb);
|
||||||
|
m_listener->sendMessage(this, request, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ClientLobbyRoomProtocol::voteReversed(bool reversed, uint8_t track_nb)
|
||||||
|
{
|
||||||
|
NetworkString request;
|
||||||
|
// 0xc0 : major vote, size_token (4), token, size reversed(1),reversed, size #track, #track
|
||||||
|
request.ai8(0xc4).ai8(4).ai32(m_server->getClientServerToken()).ai8(1).ai8(reversed).ai8(1).ai8(track_nb);
|
||||||
|
m_listener->sendMessage(this, request, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ClientLobbyRoomProtocol::voteLaps(uint8_t laps, uint8_t track_nb)
|
||||||
|
{
|
||||||
|
NetworkString request;
|
||||||
|
// 0xc0 : major vote, size_token (4), token, size laps(1),laps, size #track, #track
|
||||||
|
request.ai8(0xc5).ai8(4).ai32(m_server->getClientServerToken()).ai8(1).ai8(laps).ai8(1).ai8(track_nb);
|
||||||
|
m_listener->sendMessage(this, request, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -124,6 +185,18 @@ bool ClientLobbyRoomProtocol::notifyEventAsynchronous(Event* event)
|
|||||||
connectionAccepted(event);
|
connectionAccepted(event);
|
||||||
else if (message_type == 0x82) // kart selection refused
|
else if (message_type == 0x82) // kart selection refused
|
||||||
kartSelectionRefused(event);
|
kartSelectionRefused(event);
|
||||||
|
else if (message_type == 0xc0) // vote for major mode
|
||||||
|
playerMajorVote(event);
|
||||||
|
else if (message_type == 0xc1) // vote for race count
|
||||||
|
playerRaceCountVote(event);
|
||||||
|
else if (message_type == 0xc2) // vote for minor mode
|
||||||
|
playerMinorVote(event);
|
||||||
|
else if (message_type == 0xc3) // vote for track
|
||||||
|
playerTrackVote(event);
|
||||||
|
else if (message_type == 0xc4) // vote for reversed mode
|
||||||
|
playerReversedVote(event);
|
||||||
|
else if (message_type == 0xc5) // vote for laps
|
||||||
|
playerLapsVote(event);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} // message
|
} // message
|
||||||
@ -589,3 +662,145 @@ void ClientLobbyRoomProtocol::raceFinished(Event* event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*! \brief Called when a player votes for a major race mode.
|
||||||
|
* \param event : Event providing the information.
|
||||||
|
*
|
||||||
|
* Format of the data :
|
||||||
|
* Byte 0 1 5 6 7 8 9
|
||||||
|
* --------------------------------------------------------
|
||||||
|
* Size | 1 | 4 | 1 | 1 | 1 | 1 |
|
||||||
|
* Data | 4 | priv token | 1 | player id | 1 | major mode vote |
|
||||||
|
* --------------------------------------------------------
|
||||||
|
*/
|
||||||
|
void ClientLobbyRoomProtocol::playerMajorVote(Event* event)
|
||||||
|
{
|
||||||
|
NetworkString data = event->data();
|
||||||
|
if (!checkDataSizeAndToken(event, 9))
|
||||||
|
return;
|
||||||
|
if (!isByteCorrect(event, 5, 1))
|
||||||
|
return;
|
||||||
|
if (!isByteCorrect(event, 7, 1))
|
||||||
|
return;
|
||||||
|
m_setup->getRaceConfig()->setPlayerMajorVote(data[6], data[8]);
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*! \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 5 6 7 8 9
|
||||||
|
* ----------------------------------------------------
|
||||||
|
* Size | 1 | 4 | 1 | 1 | 1 | 1 |
|
||||||
|
* Data | 4 | priv token | 1 | player id | 1 | races count |
|
||||||
|
* ----------------------------------------------------
|
||||||
|
*/
|
||||||
|
void ClientLobbyRoomProtocol::playerRaceCountVote(Event* event)
|
||||||
|
{
|
||||||
|
NetworkString data = event->data();
|
||||||
|
if (!checkDataSizeAndToken(event, 9))
|
||||||
|
return;
|
||||||
|
if (!isByteCorrect(event, 5, 1))
|
||||||
|
return;
|
||||||
|
if (!isByteCorrect(event, 7, 1))
|
||||||
|
return;
|
||||||
|
m_setup->getRaceConfig()->setPlayerRaceCountVote(data[6], data[8]);
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*! \brief Called when a player votes for a minor race mode.
|
||||||
|
* \param event : Event providing the information.
|
||||||
|
*
|
||||||
|
* Format of the data :
|
||||||
|
* Byte 0 1 5 6 7 8 9
|
||||||
|
* --------------------------------------------------------
|
||||||
|
* Size | 1 | 4 | 1 | 1 | 1 | 1 |
|
||||||
|
* Data | 4 | priv token | 1 | player id | 1 | minor mode vote |
|
||||||
|
* --------------------------------------------------------
|
||||||
|
*/
|
||||||
|
void ClientLobbyRoomProtocol::playerMinorVote(Event* event)
|
||||||
|
{
|
||||||
|
NetworkString data = event->data();
|
||||||
|
if (!checkDataSizeAndToken(event, 9))
|
||||||
|
return;
|
||||||
|
if (!isByteCorrect(event, 5, 1))
|
||||||
|
return;
|
||||||
|
if (!isByteCorrect(event, 7, 1))
|
||||||
|
return;
|
||||||
|
m_setup->getRaceConfig()->setPlayerMinorVote(data[6], data[8]);
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*! \brief Called when a player votes for a track.
|
||||||
|
* \param event : Event providing the information.
|
||||||
|
*
|
||||||
|
* Format of the data :
|
||||||
|
* Byte 0 1 5 6 7 8 N+8 N+9 N+10
|
||||||
|
* ---------------------------------------------------------------------------
|
||||||
|
* Size | 1 | 4 | 1 | 1 | 1 | N | 1 | 1 |
|
||||||
|
* Data | 4 | priv token | 1 | player id | N | track name | 1 | track number (gp) |
|
||||||
|
* ---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
void ClientLobbyRoomProtocol::playerTrackVote(Event* event)
|
||||||
|
{
|
||||||
|
NetworkString data = event->data();
|
||||||
|
if (!checkDataSizeAndToken(event, 10))
|
||||||
|
return;
|
||||||
|
if (!isByteCorrect(event, 5, 1))
|
||||||
|
return;
|
||||||
|
int N = data[7];
|
||||||
|
std::string track_name = data.gs(8, N);
|
||||||
|
if (!isByteCorrect(event, N+8, 1))
|
||||||
|
return;
|
||||||
|
m_setup->getRaceConfig()->setPlayerTrackVote(data[6], track_name, data[N+9]);
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*! \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 5 6 7 8 9 10 11
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Size | 1 | 4 | 1 | 1 | 1 | 1 | 1 | 1 |
|
||||||
|
* Data | 4 | priv token | 1 | player id | 1 | reversed | 1 | track number (gp) |
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
void ClientLobbyRoomProtocol::playerReversedVote(Event* event)
|
||||||
|
{
|
||||||
|
NetworkString data = event->data();
|
||||||
|
if (!checkDataSizeAndToken(event, 11))
|
||||||
|
return;
|
||||||
|
if (!isByteCorrect(event, 5, 1))
|
||||||
|
return;
|
||||||
|
if (!isByteCorrect(event, 7, 1))
|
||||||
|
return;
|
||||||
|
if (!isByteCorrect(event, 9, 1))
|
||||||
|
return;
|
||||||
|
m_setup->getRaceConfig()->setPlayerReversedVote(data[6], data[8], data[10]);
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*! \brief Called when a player votes for a major race mode.
|
||||||
|
* \param event : Event providing the information.
|
||||||
|
*
|
||||||
|
* Format of the data :
|
||||||
|
* Byte 0 1 5 6 7 8 9 10 11
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
* Size | 1 | 4 | 1 | 1 | 1 | 1 | 1 | 1 |
|
||||||
|
* Data | 4 | priv token | 1 | player id | 1 | laps | 1 | track number (gp) |
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
void ClientLobbyRoomProtocol::playerLapsVote(Event* event)
|
||||||
|
{
|
||||||
|
NetworkString data = event->data();
|
||||||
|
if (!checkDataSizeAndToken(event, 9))
|
||||||
|
return;
|
||||||
|
if (!isByteCorrect(event, 5, 1))
|
||||||
|
return;
|
||||||
|
if (!isByteCorrect(event, 7, 1))
|
||||||
|
return;
|
||||||
|
m_setup->getRaceConfig()->setPlayerLapsVote(data[6], data[8], data[10]);
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -10,6 +10,12 @@ class ClientLobbyRoomProtocol : public LobbyRoomProtocol
|
|||||||
virtual ~ClientLobbyRoomProtocol();
|
virtual ~ClientLobbyRoomProtocol();
|
||||||
|
|
||||||
void requestKartSelection(std::string kart_name);
|
void requestKartSelection(std::string kart_name);
|
||||||
|
void voteMajor(uint8_t major);
|
||||||
|
void voteRaceCount(uint8_t count);
|
||||||
|
void voteMinor(uint8_t minor);
|
||||||
|
void voteTrack(std::string track, uint8_t track_nb = 0);
|
||||||
|
void voteReversed(bool reversed, uint8_t track_nb = 0);
|
||||||
|
void voteLaps(uint8_t laps, uint8_t track_nb = 0);
|
||||||
void sendMessage(std::string message);
|
void sendMessage(std::string message);
|
||||||
void leave();
|
void leave();
|
||||||
|
|
||||||
@ -29,6 +35,13 @@ class ClientLobbyRoomProtocol : public LobbyRoomProtocol
|
|||||||
void startGame(Event* event);
|
void startGame(Event* event);
|
||||||
void startSelection(Event* event);
|
void startSelection(Event* event);
|
||||||
void raceFinished(Event* event);
|
void raceFinished(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);
|
||||||
|
|
||||||
TransportAddress m_server_address;
|
TransportAddress m_server_address;
|
||||||
STKPeer* m_server;
|
STKPeer* m_server;
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "utils/time.hpp"
|
#include "utils/time.hpp"
|
||||||
#include "utils/random_generator.hpp"
|
#include "utils/random_generator.hpp"
|
||||||
|
|
||||||
|
|
||||||
ServerLobbyRoomProtocol::ServerLobbyRoomProtocol() : LobbyRoomProtocol(NULL)
|
ServerLobbyRoomProtocol::ServerLobbyRoomProtocol() : LobbyRoomProtocol(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -49,6 +50,7 @@ ServerLobbyRoomProtocol::~ServerLobbyRoomProtocol()
|
|||||||
void ServerLobbyRoomProtocol::setup()
|
void ServerLobbyRoomProtocol::setup()
|
||||||
{
|
{
|
||||||
m_setup = NetworkManager::getInstance()->setupNewGame(); // create a new setup
|
m_setup = NetworkManager::getInstance()->setupNewGame(); // create a new setup
|
||||||
|
m_setup->getRaceConfig()->setPlayerCount(16); //FIXME : this has to be moved to when logging into the server
|
||||||
m_next_id = 0;
|
m_next_id = 0;
|
||||||
m_state = NONE;
|
m_state = NONE;
|
||||||
m_public_address.ip = 0;
|
m_public_address.ip = 0;
|
||||||
@ -73,8 +75,20 @@ bool ServerLobbyRoomProtocol::notifyEventAsynchronous(Event* event)
|
|||||||
Log::info("ServerLobbyRoomProtocol", "Message received with type %d.", message_type);
|
Log::info("ServerLobbyRoomProtocol", "Message received with type %d.", message_type);
|
||||||
if (message_type == 0x01) // player requesting connection
|
if (message_type == 0x01) // player requesting connection
|
||||||
connectionRequested(event);
|
connectionRequested(event);
|
||||||
if (message_type == 0x02) // player requesting kart selection
|
else if (message_type == 0x02) // player requesting kart selection
|
||||||
kartSelectionRequested(event);
|
kartSelectionRequested(event);
|
||||||
|
else if (message_type == 0xc0) // vote for major mode
|
||||||
|
playerMajorVote(event);
|
||||||
|
else if (message_type == 0xc1) // vote for race count
|
||||||
|
playerRaceCountVote(event);
|
||||||
|
else if (message_type == 0xc2) // vote for minor mode
|
||||||
|
playerMinorVote(event);
|
||||||
|
else if (message_type == 0xc3) // vote for track
|
||||||
|
playerTrackVote(event);
|
||||||
|
else if (message_type == 0xc4) // vote for reversed mode
|
||||||
|
playerReversedVote(event);
|
||||||
|
else if (message_type == 0xc5) // vote for laps
|
||||||
|
playerLapsVote(event);
|
||||||
} // if (event->type == EVENT_TYPE_MESSAGE)
|
} // if (event->type == EVENT_TYPE_MESSAGE)
|
||||||
else if (event->type == EVENT_TYPE_CONNECTED)
|
else if (event->type == EVENT_TYPE_CONNECTED)
|
||||||
{
|
{
|
||||||
@ -404,21 +418,10 @@ void ServerLobbyRoomProtocol::connectionRequested(Event* event)
|
|||||||
void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
|
void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
|
||||||
{
|
{
|
||||||
NetworkString data = event->data();
|
NetworkString data = event->data();
|
||||||
if (data.size() < 6 || data[0] != 4)
|
|
||||||
{
|
|
||||||
Log::warn("ServerLobbyRoomProtocol", "Receiving a badly "
|
|
||||||
"formated message. Size is %d and first byte %d",
|
|
||||||
data.size(), data[0]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
STKPeer* peer = *(event->peer);
|
STKPeer* peer = *(event->peer);
|
||||||
uint32_t token = data.gui32(1);
|
if (!checkDataSizeAndToken(event, 6))
|
||||||
if (token != peer->getClientServerToken())
|
|
||||||
{
|
|
||||||
Log::warn("ServerLobbyRoomProtocol", "Peer sending bad token. Request "
|
|
||||||
"aborted.");
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
uint8_t kart_name_size = data.gui8(5);
|
uint8_t kart_name_size = data.gui8(5);
|
||||||
std::string kart_name = data.gs(6, kart_name_size);
|
std::string kart_name = data.gs(6, kart_name_size);
|
||||||
if (kart_name.size() != kart_name_size)
|
if (kart_name.size() != kart_name_size)
|
||||||
@ -462,3 +465,195 @@ void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*! \brief Called when a player votes for a major race mode.
|
||||||
|
* \param event : Event providing the information.
|
||||||
|
*
|
||||||
|
* Format of the data :
|
||||||
|
* Byte 0 1 5 6 7
|
||||||
|
* ----------------------------------------
|
||||||
|
* Size | 1 | 4 | 1 | 1 |
|
||||||
|
* Data | 4 | priv token | 1 | major mode vote |
|
||||||
|
* ----------------------------------------
|
||||||
|
*/
|
||||||
|
void ServerLobbyRoomProtocol::playerMajorVote(Event* event)
|
||||||
|
{
|
||||||
|
NetworkString data = event->data();
|
||||||
|
STKPeer* peer = *(event->peer);
|
||||||
|
if (!checkDataSizeAndToken(event, 7))
|
||||||
|
return;
|
||||||
|
if (!isByteCorrect(event, 5, 1))
|
||||||
|
return;
|
||||||
|
uint8_t player_id = peer->getPlayerProfile()->race_id;
|
||||||
|
m_setup->getRaceConfig()->setPlayerMajorVote(player_id, data[6]);
|
||||||
|
// Send the vote to everybody (including the sender)
|
||||||
|
NetworkString other;
|
||||||
|
other.ai8(1).ai8(player_id); // add the player id
|
||||||
|
data.removeFront(5); // remove the token
|
||||||
|
other += data; // add the data
|
||||||
|
NetworkString prefix;
|
||||||
|
prefix.ai8(0xc0); // prefix the token with the ype
|
||||||
|
sendMessageToPeersChangingToken(prefix, 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 5 6 7
|
||||||
|
* ------------------------------------
|
||||||
|
* Size | 1 | 4 | 1 | 1 |
|
||||||
|
* Data | 4 | priv token | 1 | races count |
|
||||||
|
* ------------------------------------
|
||||||
|
*/
|
||||||
|
void ServerLobbyRoomProtocol::playerRaceCountVote(Event* event)
|
||||||
|
{
|
||||||
|
NetworkString data = event->data();
|
||||||
|
STKPeer* peer = *(event->peer);
|
||||||
|
if (!checkDataSizeAndToken(event, 7))
|
||||||
|
return;
|
||||||
|
if (!isByteCorrect(event, 5, 1))
|
||||||
|
return;
|
||||||
|
uint8_t player_id = peer->getPlayerProfile()->race_id;
|
||||||
|
m_setup->getRaceConfig()->setPlayerRaceCountVote(player_id, data[6]);
|
||||||
|
// Send the vote to everybody (including the sender)
|
||||||
|
NetworkString other;
|
||||||
|
other.ai8(1).ai8(player_id); // add the player id
|
||||||
|
data.removeFront(5); // remove the token
|
||||||
|
other += data; // add the data
|
||||||
|
NetworkString prefix;
|
||||||
|
prefix.ai8(0xc1); // prefix the token with the ype
|
||||||
|
sendMessageToPeersChangingToken(prefix, other);
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*! \brief Called when a player votes for a minor race mode.
|
||||||
|
* \param event : Event providing the information.
|
||||||
|
*
|
||||||
|
* Format of the data :
|
||||||
|
* Byte 0 1 5 6 7
|
||||||
|
* ----------------------------------------
|
||||||
|
* Size | 1 | 4 | 1 | 1 |
|
||||||
|
* Data | 4 | priv token | 1 | minor mode vote |
|
||||||
|
* ----------------------------------------
|
||||||
|
*/
|
||||||
|
void ServerLobbyRoomProtocol::playerMinorVote(Event* event)
|
||||||
|
{
|
||||||
|
NetworkString data = event->data();
|
||||||
|
STKPeer* peer = *(event->peer);
|
||||||
|
if (!checkDataSizeAndToken(event, 7))
|
||||||
|
return;
|
||||||
|
if (!isByteCorrect(event, 5, 1))
|
||||||
|
return;
|
||||||
|
uint8_t player_id = peer->getPlayerProfile()->race_id;
|
||||||
|
m_setup->getRaceConfig()->setPlayerMinorVote(player_id, data[6]);
|
||||||
|
// Send the vote to everybody (including the sender)
|
||||||
|
NetworkString other;
|
||||||
|
other.ai8(1).ai8(player_id); // add the player id
|
||||||
|
data.removeFront(5); // remove the token
|
||||||
|
other += data; // add the data
|
||||||
|
NetworkString prefix;
|
||||||
|
prefix.ai8(0xc2); // prefix the token with the ype
|
||||||
|
sendMessageToPeersChangingToken(prefix, other);
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*! \brief Called when a player votes for a track.
|
||||||
|
* \param event : Event providing the information.
|
||||||
|
*
|
||||||
|
* Format of the data :
|
||||||
|
* Byte 0 1 5 6 N+6 N+7 N+8
|
||||||
|
* -----------------------------------------------------------
|
||||||
|
* Size | 1 | 4 | 1 | N | 1 | 1 |
|
||||||
|
* Data | 4 | priv token | N | track name | 1 | track number (gp) |
|
||||||
|
* -----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
void ServerLobbyRoomProtocol::playerTrackVote(Event* event)
|
||||||
|
{
|
||||||
|
NetworkString data = event->data();
|
||||||
|
STKPeer* peer = *(event->peer);
|
||||||
|
if (!checkDataSizeAndToken(event, 8))
|
||||||
|
return;
|
||||||
|
int N = data[5];
|
||||||
|
std::string track_name = data.gs(5, N);
|
||||||
|
if (!isByteCorrect(event, N+6, 1))
|
||||||
|
return;
|
||||||
|
uint8_t player_id = peer->getPlayerProfile()->race_id;
|
||||||
|
m_setup->getRaceConfig()->setPlayerTrackVote(player_id, track_name, data[N+7]);
|
||||||
|
// Send the vote to everybody (including the sender)
|
||||||
|
NetworkString other;
|
||||||
|
other.ai8(1).ai8(player_id); // add the player id
|
||||||
|
data.removeFront(5); // remove the token
|
||||||
|
other += data; // add the data
|
||||||
|
NetworkString prefix;
|
||||||
|
prefix.ai8(0xc3); // prefix the token with the ype
|
||||||
|
sendMessageToPeersChangingToken(prefix, other);
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*! \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 5 6 7 8 9
|
||||||
|
* ---------------------------------------------------------
|
||||||
|
* Size | 1 | 4 | 1 | 1 | 1 | 1 |
|
||||||
|
* Data | 4 | priv token | 1 | reversed | 1 | track number (gp) |
|
||||||
|
* ---------------------------------------------------------
|
||||||
|
*/
|
||||||
|
void ServerLobbyRoomProtocol::playerReversedVote(Event* event)
|
||||||
|
{
|
||||||
|
NetworkString data = event->data();
|
||||||
|
STKPeer* peer = *(event->peer);
|
||||||
|
if (!checkDataSizeAndToken(event, 9))
|
||||||
|
return;
|
||||||
|
if (!isByteCorrect(event, 5, 1))
|
||||||
|
return;
|
||||||
|
if (!isByteCorrect(event, 7, 1))
|
||||||
|
return;
|
||||||
|
uint8_t player_id = peer->getPlayerProfile()->race_id;
|
||||||
|
m_setup->getRaceConfig()->setPlayerReversedVote(player_id, data[6], data[8]);
|
||||||
|
// Send the vote to everybody (including the sender)
|
||||||
|
NetworkString other;
|
||||||
|
other.ai8(1).ai8(player_id); // add the player id
|
||||||
|
data.removeFront(5); // remove the token
|
||||||
|
other += data; // add the data
|
||||||
|
NetworkString prefix;
|
||||||
|
prefix.ai8(0xc4); // prefix the token with the ype
|
||||||
|
sendMessageToPeersChangingToken(prefix, other);
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*! \brief Called when a player votes for a major race mode.
|
||||||
|
* \param event : Event providing the information.
|
||||||
|
*
|
||||||
|
* Format of the data :
|
||||||
|
* Byte 0 1 5 6 7 8 9
|
||||||
|
* -----------------------------------------------------
|
||||||
|
* Size | 1 | 4 | 1 | 1 | 1 | 1 |
|
||||||
|
* Data | 4 | priv token | 1 | laps | 1 | track number (gp) |
|
||||||
|
* -----------------------------------------------------
|
||||||
|
*/
|
||||||
|
void ServerLobbyRoomProtocol::playerLapsVote(Event* event)
|
||||||
|
{
|
||||||
|
NetworkString data = event->data();
|
||||||
|
STKPeer* peer = *(event->peer);
|
||||||
|
if (!checkDataSizeAndToken(event, 9))
|
||||||
|
return;
|
||||||
|
if (!isByteCorrect(event, 5, 1))
|
||||||
|
return;
|
||||||
|
if (!isByteCorrect(event, 7, 1))
|
||||||
|
return;
|
||||||
|
uint8_t player_id = peer->getPlayerProfile()->race_id;
|
||||||
|
m_setup->getRaceConfig()->setPlayerLapsVote(player_id, data[6], data[8]);
|
||||||
|
// Send the vote to everybody (including the sender)
|
||||||
|
NetworkString other;
|
||||||
|
other.ai8(1).ai8(player_id); // add the player id
|
||||||
|
data.removeFront(5); // remove the token
|
||||||
|
other += data; // add the data
|
||||||
|
NetworkString prefix;
|
||||||
|
prefix.ai8(0xc5); // prefix the token with the ype
|
||||||
|
sendMessageToPeersChangingToken(prefix, other);
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -20,9 +20,18 @@ class ServerLobbyRoomProtocol : public LobbyRoomProtocol
|
|||||||
void checkRaceFinished();
|
void checkRaceFinished();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// connection management
|
||||||
void kartDisconnected(Event* event);
|
void kartDisconnected(Event* event);
|
||||||
void connectionRequested(Event* event);
|
void connectionRequested(Event* event);
|
||||||
|
// kart selection
|
||||||
void kartSelectionRequested(Event* event);
|
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);
|
||||||
|
|
||||||
uint8_t m_next_id; //!< Next id to assign to a peer.
|
uint8_t m_next_id; //!< Next id to assign to a peer.
|
||||||
std::vector<TransportAddress> m_peers;
|
std::vector<TransportAddress> m_peers;
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
#include "network/race_config.hpp"
|
#include "network/race_config.hpp"
|
||||||
|
|
||||||
#include "race/race_manager.hpp"
|
#include "race/race_manager.hpp"
|
||||||
|
#include "utils/log.hpp"
|
||||||
|
|
||||||
|
/** \brief Gets the element with the highest count in a std::map<S,int>.
|
||||||
|
* \param histogram : A pointer to the histogram.
|
||||||
|
* \return The key of type S that has the highest second value.
|
||||||
|
*/
|
||||||
template<typename S>
|
template<typename S>
|
||||||
S getHighestInHistogram(std::map<S,int>* histogram)
|
S getHighestInHistogram(std::map<S,int>* histogram)
|
||||||
{
|
{
|
||||||
S best_item;
|
S best_item;
|
||||||
int highest_count;
|
uint8_t highest_count;
|
||||||
for (typename std::map<S, int>::iterator it = histogram->begin();
|
for (typename std::map<S, int>::iterator it = histogram->begin();
|
||||||
it != histogram->end(); it++)
|
it != histogram->end(); it++)
|
||||||
{
|
{
|
||||||
@ -20,6 +25,9 @@ S getHighestInHistogram(std::map<S,int>* histogram)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
//--------------------------------- TrackVote --------------------------------
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
TrackVote::TrackVote()
|
TrackVote::TrackVote()
|
||||||
{
|
{
|
||||||
has_voted_laps = false;
|
has_voted_laps = false;
|
||||||
@ -39,12 +47,136 @@ void TrackVote::voteReversed(bool reversed)
|
|||||||
has_voted_reversed = true;
|
has_voted_reversed = true;
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void TrackVote::voteLaps(int laps)
|
void TrackVote::voteLaps(uint8_t laps)
|
||||||
{
|
{
|
||||||
track_info.laps = laps;
|
track_info.laps = laps;
|
||||||
has_voted_laps = true;
|
has_voted_laps = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//--------------------------------- RaceVote ---------------------------------
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
RaceVote::RaceVote()
|
||||||
|
{
|
||||||
|
m_has_voted_major = false;
|
||||||
|
m_has_voted_minor = false;
|
||||||
|
m_has_voted_races_count = false;
|
||||||
|
m_major_mode = 0;
|
||||||
|
m_minor_mode = 0;
|
||||||
|
m_races_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void RaceVote::voteMajor(uint8_t major)
|
||||||
|
{
|
||||||
|
m_has_voted_major = true;
|
||||||
|
m_major_mode = major;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void RaceVote::voteRaceCount(uint8_t count)
|
||||||
|
{
|
||||||
|
m_has_voted_races_count = true;
|
||||||
|
m_races_count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void RaceVote::voteMinor(uint8_t minor)
|
||||||
|
{
|
||||||
|
m_has_voted_minor = true;
|
||||||
|
m_minor_mode = minor;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void RaceVote::voteTrack(std::string track, uint8_t track_number)
|
||||||
|
{
|
||||||
|
m_tracks_vote[track_number].voteTrack(track);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void RaceVote::voteReversed(bool reversed, uint8_t track_number)
|
||||||
|
{
|
||||||
|
m_tracks_vote[track_number].voteReversed(reversed);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void RaceVote::voteLaps(uint8_t laps, uint8_t track_number)
|
||||||
|
{
|
||||||
|
m_tracks_vote[track_number].voteLaps(laps);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool RaceVote::hasVotedMajor() const
|
||||||
|
{
|
||||||
|
return m_has_voted_major;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool RaceVote::hasVotedRacesCount() const
|
||||||
|
{
|
||||||
|
return m_has_voted_races_count;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool RaceVote::hasVotedMinor() const
|
||||||
|
{
|
||||||
|
return m_has_voted_minor;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool RaceVote::hasVotedTrack(uint8_t track_number) const
|
||||||
|
{
|
||||||
|
return m_tracks_vote[track_number].has_voted_track;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool RaceVote::hasVotedReversed(uint8_t track_number) const
|
||||||
|
{
|
||||||
|
return m_tracks_vote[track_number].has_voted_reversed;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool RaceVote::hasVotedLaps(uint8_t track_number) const
|
||||||
|
{
|
||||||
|
return m_tracks_vote[track_number].has_voted_laps;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
uint8_t RaceVote::getMajorVote() const
|
||||||
|
{
|
||||||
|
return m_major_mode;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
uint8_t RaceVote::getRacesCountVote() const
|
||||||
|
{
|
||||||
|
return m_races_count;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
uint8_t RaceVote::getMinorVote() const
|
||||||
|
{
|
||||||
|
return m_minor_mode;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
std::string RaceVote::getTrackVote(uint8_t track_number) const
|
||||||
|
{
|
||||||
|
return m_tracks_vote[track_number].track_info.track;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool RaceVote::getReversedVote(uint8_t track_number) const
|
||||||
|
{
|
||||||
|
return m_tracks_vote[track_number].track_info.reversed;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
uint8_t RaceVote::getLapsVote(uint8_t track_number) const
|
||||||
|
{
|
||||||
|
return m_tracks_vote[track_number].track_info.laps;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//--------------------------------- RaceConfig -------------------------------
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
RaceConfig::RaceConfig()
|
RaceConfig::RaceConfig()
|
||||||
@ -54,7 +186,7 @@ RaceConfig::RaceConfig()
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void RaceConfig::setPlayerCount(int count)
|
void RaceConfig::setPlayerCount(uint8_t count)
|
||||||
{
|
{
|
||||||
m_max_players = count;
|
m_max_players = count;
|
||||||
m_votes.resize(m_max_players);
|
m_votes.resize(m_max_players);
|
||||||
@ -62,81 +194,176 @@ void RaceConfig::setPlayerCount(int count)
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void RaceConfig::setPlayerTrackVote(int player_id, std::string track_name)
|
void RaceConfig::setPlayerMajorVote(uint8_t player_id, uint8_t major)
|
||||||
{
|
{
|
||||||
m_votes[player_id].voteTrack(track_name);
|
Log::info("RaceConfig", "Player %d voted for major %d", player_id, major);
|
||||||
|
m_votes[player_id].voteMajor(major);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void RaceConfig::setPlayerReverseVote(int player_id, bool reversed)
|
void RaceConfig::setPlayerRaceCountVote(uint8_t player_id, uint8_t count)
|
||||||
{
|
{
|
||||||
m_votes[player_id].voteReversed(reversed);
|
Log::info("RaceConfig", "Player %d voted for %d races in GP", player_id, count);
|
||||||
|
m_votes[player_id].voteRaceCount(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void RaceConfig::setPlayerLapVote(int player_id, int lap_count)
|
void RaceConfig::setPlayerMinorVote(uint8_t player_id, uint8_t minor)
|
||||||
{
|
{
|
||||||
m_votes[player_id].voteLaps(lap_count);
|
Log::info("RaceConfig", "Player %d voted for minor %d", player_id, minor);
|
||||||
|
m_votes[player_id].voteMinor(minor);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void RaceConfig::computeNextTrack()
|
void RaceConfig::setPlayerTrackVote(uint8_t player_id, std::string track, uint8_t track_nb)
|
||||||
{
|
{
|
||||||
// first create histograms of the votes
|
Log::info("RaceConfig", "Player %d voted for track %s", player_id, track.c_str());
|
||||||
std::map<std::string,int> tracks_histogram;
|
m_votes[player_id].voteTrack(track, track_nb);
|
||||||
std::map<bool,int> reversed_histogram;
|
}
|
||||||
std::map<int,int> laps_histogram;
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void RaceConfig::setPlayerReversedVote(uint8_t player_id, bool reversed, uint8_t track_nb)
|
||||||
|
{
|
||||||
|
if (reversed)
|
||||||
|
Log::info("RaceConfig", "Player %d voted map %d to be reversed", player_id, track_nb);
|
||||||
|
else
|
||||||
|
Log::info("RaceConfig", "Player %d voted map %d NOT to be reversed", player_id, track_nb);
|
||||||
|
m_votes[player_id].voteReversed(reversed, track_nb);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void RaceConfig::setPlayerLapsVote(uint8_t player_id, uint8_t lap_count, uint8_t track_nb)
|
||||||
|
{
|
||||||
|
Log::info("RaceConfig", "Player %d voted map %d to have %d laps", player_id, track_nb, lap_count);
|
||||||
|
m_votes[player_id].voteLaps(lap_count, track_nb);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void RaceConfig::computeRaceMode()
|
||||||
|
{
|
||||||
|
// calculate the race type and number of tracks (in GP mode).
|
||||||
|
std::map<int,int> major_histogram;
|
||||||
|
std::map<int,int> races_count_histogram;
|
||||||
|
std::map<int,int> minor_histogram;
|
||||||
for (unsigned int i = 0; i < m_max_players; i++)
|
for (unsigned int i = 0; i < m_max_players; i++)
|
||||||
{
|
{
|
||||||
// increase the count of votes
|
// increase the count of votes
|
||||||
if (m_votes[i].has_voted_track)
|
if (m_votes[i].hasVotedMajor())
|
||||||
{
|
{
|
||||||
try // maps
|
try
|
||||||
{
|
{
|
||||||
tracks_histogram.at(m_votes[i].track_info.track) ++;
|
major_histogram.at(m_votes[i].getMajorVote()) ++;
|
||||||
}
|
}
|
||||||
catch (const std::out_of_range& oor) // doesn't exist in the map : add it
|
catch (const std::out_of_range& oor) // doesn't exist in the map
|
||||||
{
|
{
|
||||||
tracks_histogram[m_votes[i].track_info.track] = 1;
|
major_histogram[m_votes[i].getMajorVote()] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_votes[i].has_voted_reversed)
|
else if (m_votes[i].hasVotedRacesCount())
|
||||||
{
|
{
|
||||||
try // reversed
|
try
|
||||||
{
|
{
|
||||||
reversed_histogram.at(m_votes[i].track_info.reversed) ++;
|
races_count_histogram.at(m_votes[i].getRacesCountVote()) ++;
|
||||||
}
|
}
|
||||||
catch (const std::out_of_range& oor) // doesn't exist in the map : add it
|
catch (const std::out_of_range& oor) // doesn't exist in the map
|
||||||
{
|
{
|
||||||
reversed_histogram[m_votes[i].track_info.reversed] = 1;
|
races_count_histogram[m_votes[i].getRacesCountVote()] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_votes[i].has_voted_laps)
|
else if (m_votes[i].hasVotedMinor())
|
||||||
{
|
{
|
||||||
try // laps
|
try
|
||||||
{
|
{
|
||||||
laps_histogram.at(m_votes[i].track_info.laps) ++;
|
minor_histogram.at(m_votes[i].getMinorVote()) ++;
|
||||||
}
|
}
|
||||||
catch (const std::out_of_range& oor) // doesn't exist in the map : add it
|
catch (const std::out_of_range& oor) // doesn't exist in the map
|
||||||
{
|
{
|
||||||
laps_histogram[m_votes[i].track_info.laps] = 1;
|
minor_histogram[m_votes[i].getMinorVote()] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// now find the highest votes
|
// now we know :
|
||||||
m_track.track = getHighestInHistogram<std::string>(&tracks_histogram);
|
m_major_mode = ((major_histogram.size() > 0) ? getHighestInHistogram<int>(&major_histogram) : 1);
|
||||||
m_track.reversed = getHighestInHistogram<bool>(&reversed_histogram);
|
m_races_count = ((minor_histogram.size() > 0) ? getHighestInHistogram<int>(&races_count_histogram) : 1);
|
||||||
m_track.laps = getHighestInHistogram<int>(&laps_histogram);
|
m_minor_mode = ((minor_histogram.size() > 0) ? getHighestInHistogram<int>(&minor_histogram) : 0);
|
||||||
|
|
||||||
|
if (m_major_mode == RaceManager::MAJOR_MODE_GRAND_PRIX)
|
||||||
|
m_tracks.resize(m_races_count);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_tracks.resize(1);
|
||||||
|
m_races_count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info("RaceConfig", "Major mode will be %d with %d races. Minor is %d", m_major_mode, m_races_count, m_minor_mode);
|
||||||
|
}
|
||||||
|
void RaceConfig::computeNextTrack()
|
||||||
|
{
|
||||||
|
for (unsigned int j = 0; j < m_races_count; j++)
|
||||||
|
{
|
||||||
|
// first create histograms of the votes
|
||||||
|
std::map<std::string,int> tracks_histogram;
|
||||||
|
std::map<bool,int> reversed_histogram;
|
||||||
|
std::map<int,int> laps_histogram;
|
||||||
|
for (unsigned int i = 0; i < m_max_players; i++)
|
||||||
|
{
|
||||||
|
// increase the count of votes
|
||||||
|
if (m_votes[i].hasVotedTrack())
|
||||||
|
{
|
||||||
|
try // maps
|
||||||
|
{
|
||||||
|
tracks_histogram.at(m_votes[i].getTrackVote()) ++;
|
||||||
|
}
|
||||||
|
catch (const std::out_of_range& oor) // doesn't exist in the map
|
||||||
|
{
|
||||||
|
tracks_histogram[m_votes[i].getTrackVote()] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_votes[i].hasVotedReversed())
|
||||||
|
{
|
||||||
|
try // reversed
|
||||||
|
{
|
||||||
|
reversed_histogram.at(m_votes[i].getReversedVote()) ++;
|
||||||
|
}
|
||||||
|
catch (const std::out_of_range& oor) // doesn't exist in the map
|
||||||
|
{
|
||||||
|
reversed_histogram[m_votes[i].getReversedVote()] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_votes[i].hasVotedLaps())
|
||||||
|
{
|
||||||
|
try // laps
|
||||||
|
{
|
||||||
|
laps_histogram.at(m_votes[i].getLapsVote()) ++;
|
||||||
|
}
|
||||||
|
catch (const std::out_of_range& oor) // doesn't exist in the mapt
|
||||||
|
{
|
||||||
|
laps_histogram[m_votes[i].getLapsVote()] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// now find the highest votes
|
||||||
|
m_tracks[j].track = getHighestInHistogram<std::string>(&tracks_histogram);
|
||||||
|
m_tracks[j].reversed = getHighestInHistogram<bool>(&reversed_histogram);
|
||||||
|
m_tracks[j].laps = getHighestInHistogram<int>(&laps_histogram);
|
||||||
|
if (m_tracks[j].reversed)
|
||||||
|
Log::info("RaceConfig", "Race %d will be on %s with %d laps and reversed", j, m_tracks[j].track.c_str(), m_tracks[j].laps);
|
||||||
|
else
|
||||||
|
Log::info("RaceConfig", "Race %d will be on %s with %d laps", j, m_tracks[j].track.c_str(), m_tracks[j].laps);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
const TrackInfo* RaceConfig::getNextTrackInfo() const
|
const TrackInfo* RaceConfig::getNextTrackInfo() const
|
||||||
{
|
{
|
||||||
return &m_track;
|
return &m_tracks[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -3,13 +3,15 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "utils/types.hpp"
|
||||||
|
|
||||||
class TrackInfo
|
class TrackInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
TrackInfo() { laps = 0; reversed = false; }
|
||||||
std::string track;
|
std::string track;
|
||||||
bool reversed;
|
bool reversed;
|
||||||
int laps;
|
uint8_t laps;
|
||||||
};
|
};
|
||||||
class TrackVote
|
class TrackVote
|
||||||
{
|
{
|
||||||
@ -18,15 +20,48 @@ class TrackVote
|
|||||||
|
|
||||||
void voteTrack(std::string track);
|
void voteTrack(std::string track);
|
||||||
void voteReversed(bool reversed);
|
void voteReversed(bool reversed);
|
||||||
void voteLaps(int laps);
|
void voteLaps(uint8_t laps);
|
||||||
|
|
||||||
TrackInfo track_info;
|
TrackInfo track_info;
|
||||||
|
|
||||||
bool has_voted_track;
|
bool has_voted_track;
|
||||||
bool has_voted_reversed;
|
bool has_voted_reversed;
|
||||||
bool has_voted_laps;
|
bool has_voted_laps;
|
||||||
|
};
|
||||||
|
class RaceVote
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RaceVote();
|
||||||
|
|
||||||
int minor_race_type; // corresponds to the enum in race_manager.hpp
|
void voteMajor(uint8_t major);
|
||||||
|
void voteRaceCount(uint8_t count);
|
||||||
|
void voteMinor(uint8_t minor);
|
||||||
|
void voteTrack(std::string track, uint8_t track_number = 0);
|
||||||
|
void voteReversed(bool reversed, uint8_t track_number = 0);
|
||||||
|
void voteLaps(uint8_t laps, uint8_t track_number = 0);
|
||||||
|
|
||||||
|
bool hasVotedMajor() const;
|
||||||
|
bool hasVotedRacesCount() const;
|
||||||
|
bool hasVotedMinor() const;
|
||||||
|
bool hasVotedTrack(uint8_t track_number = 0) const;
|
||||||
|
bool hasVotedReversed(uint8_t track_number = 0) const;
|
||||||
|
bool hasVotedLaps(uint8_t track_number = 0) const;
|
||||||
|
|
||||||
|
uint8_t getMajorVote() const;
|
||||||
|
uint8_t getRacesCountVote() const;
|
||||||
|
uint8_t getMinorVote() const;
|
||||||
|
std::string getTrackVote(uint8_t track_number = 0) const;
|
||||||
|
bool getReversedVote(uint8_t track_number = 0) const;
|
||||||
|
uint8_t getLapsVote(uint8_t track_number = 0) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t m_major_mode;
|
||||||
|
uint8_t m_minor_mode;
|
||||||
|
uint8_t m_races_count; //!< Stores the number of races that will be in a GP
|
||||||
|
bool m_has_voted_major;
|
||||||
|
bool m_has_voted_minor;
|
||||||
|
bool m_has_voted_races_count;
|
||||||
|
std::vector<TrackVote> m_tracks_vote;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RaceConfig
|
class RaceConfig
|
||||||
@ -34,11 +69,15 @@ class RaceConfig
|
|||||||
public:
|
public:
|
||||||
RaceConfig();
|
RaceConfig();
|
||||||
|
|
||||||
void setPlayerCount(int count);
|
void setPlayerCount(uint8_t count);
|
||||||
void setPlayerTrackVote(int player_id, std::string track_name);
|
void setPlayerMajorVote(uint8_t player_id, uint8_t major);
|
||||||
void setPlayerReverseVote(int player_id, bool reversed);
|
void setPlayerRaceCountVote(uint8_t player_id, uint8_t count);
|
||||||
void setPlayerLapVote(int player_id, int lap_count);
|
void setPlayerMinorVote(uint8_t player_id, uint8_t minor);
|
||||||
|
void setPlayerTrackVote(uint8_t player_id, std::string track, uint8_t track_nb = 0);
|
||||||
|
void setPlayerReversedVote(uint8_t player_id, bool reversed, uint8_t track_nb = 0);
|
||||||
|
void setPlayerLapsVote(uint8_t player_id, uint8_t lap_count, uint8_t track_nb = 0);
|
||||||
|
|
||||||
|
void computeRaceMode();
|
||||||
void computeNextTrack();
|
void computeNextTrack();
|
||||||
|
|
||||||
const TrackInfo* getNextTrackInfo() const;
|
const TrackInfo* getNextTrackInfo() const;
|
||||||
@ -46,12 +85,13 @@ class RaceConfig
|
|||||||
bool getLapCount() const;
|
bool getLapCount() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TrackInfo m_track;
|
std::vector<TrackInfo> m_tracks;
|
||||||
bool m_reverse;
|
int m_minor_mode;
|
||||||
int m_laps;
|
int m_major_mode;
|
||||||
|
int m_races_count;
|
||||||
|
|
||||||
std::vector<TrackVote> m_votes;
|
std::vector<RaceVote> m_votes;
|
||||||
int m_max_players;
|
uint8_t m_max_players;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,6 +62,16 @@ void* waitInput2(void* data)
|
|||||||
assert(protocol);
|
assert(protocol);
|
||||||
protocol->startSelection();
|
protocol->startSelection();
|
||||||
}
|
}
|
||||||
|
else if (str == "compute_race")
|
||||||
|
{
|
||||||
|
GameSetup* setup = NetworkManager::getInstance()->getGameSetup();
|
||||||
|
setup->getRaceConfig()->computeRaceMode();
|
||||||
|
}
|
||||||
|
else if (str == "compute_track")
|
||||||
|
{
|
||||||
|
GameSetup* setup = NetworkManager::getInstance()->getGameSetup();
|
||||||
|
setup->getRaceConfig()->computeNextTrack();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t id = ProtocolManager::getInstance()->requestStart(new StopServer());
|
uint32_t id = ProtocolManager::getInstance()->requestStart(new StopServer());
|
||||||
|
Loading…
Reference in New Issue
Block a user