Merge branch 'refactor-network-string' of github.com:supertuxkart/stk-code into refactor-network-string

This commit is contained in:
hiker 2016-03-01 11:56:49 +11:00
commit d9f607fc24
10 changed files with 271 additions and 424 deletions

View File

@ -66,6 +66,7 @@ Event::Event(ENetEvent* event)
Log::error("Event", "HostID %d Token %d message token %d",
m_peer->getHostId(), m_peer->getClientServerToken(),
m_data->getToken());
Log::error("Event", m_data->getLogMessage().c_str());
}
} // Event(ENetEvent)
@ -80,12 +81,3 @@ Event::~Event()
delete m_data;
} // ~Event
// ----------------------------------------------------------------------------
/** \brief Remove bytes at the beginning of data.
* \param size : The number of bytes to remove.
*/
void Event::removeFront(int size)
{
m_data->removeFront(size);
} // removeFront

View File

@ -70,7 +70,6 @@ private:
public:
Event(ENetEvent* event);
~Event();
void removeFront(int size);
// ------------------------------------------------------------------------
/** Returns the type of this event. */

View File

@ -24,6 +24,7 @@
#define NETWORK_STRING_HPP
#include "network/protocol.hpp"
#include "utils/leak_check.hpp"
#include "utils/types.hpp"
#include "utils/vec3.hpp"
@ -50,6 +51,9 @@ typedef unsigned char uchar;
class BareNetworkString
{
private:
LEAK_CHECK();
protected:
/** The actual buffer. */
std::vector<uint8_t> m_buffer;
@ -193,11 +197,13 @@ public:
} // addFloat
// ------------------------------------------------------------------------
/** Adds the content of another network string. */
/** Adds the content of another network string. It only copies data which
* has not been 'removed' (i.e. skipped). */
BareNetworkString& operator+=(BareNetworkString const& value)
{
m_buffer.insert(m_buffer.end(), value.m_buffer.begin(),
value.m_buffer.end() );
m_buffer.insert(m_buffer.end(),
value.m_buffer.begin()+value.m_current_offset,
value.m_buffer.end() );
return *this;
} // operator+=
@ -251,7 +257,21 @@ public:
float getFloat(int pos=0) const
{
uint32_t u = getUInt32(pos);
return *(float*)&u;
float f;
// Doig a "return *(float*)&u;" appears to be more efficient,
// but it can create incorrect code on higher optimisation: c++
// makes the assumption that pointer of different types never
// overlap. So the compiler can assume that the int pointer (&u)
// and float pointer do point to different aras, so there read
// (*(float*) can be done before the write to u (and then the
// write to u is basically a no-op and can be removed, too).
// Using a union of int and float is not valid either, there
// is no guarantee that writing to the int part of the union
// will affect the float part. So, an explicit memcpy is the
// more or less only portable guaranteed to be correct way of
// converting the int to a float.
memcpy(&f, &u, sizeof(float));
return f;
} // getFloat
// ------------------------------------------------------------------------
@ -296,9 +316,10 @@ public:
static void unitTesting();
/** Constructor for a message to be sent. It sets the
* protocol type of this message. */
* protocol type of this message. It adds 5 bytes to the capacity:
* 1 byte for the protocol type, and 4 bytes for the token. */
NetworkString(ProtocolType type, int capacity=16)
: BareNetworkString(capacity)
: BareNetworkString(capacity+5)
{
m_buffer.push_back(type);
addUInt32(0); // add dummy token for now

View File

@ -57,39 +57,21 @@ NetworkString* Protocol::getNetworkString(int capacity)
} // getNetworkString
// ----------------------------------------------------------------------------
bool Protocol::checkDataSizeAndToken(Event* event, unsigned int minimum_size)
/** Checks if the message has at least the specified size, and if not prints
* a warning message including the message content.
* \return True if the message is long enough, false otherwise.
*/
bool Protocol::checkDataSize(Event* event, unsigned int minimum_size)
{
const NetworkString &data = event->data();
if (data.size() < minimum_size || data[0] != 4)
if (data.size() < minimum_size)
{
Log::warn("Protocol", "Receiving a badly "
"formated message. Size is %d and first byte %d",
data.size(), data[0]);
return false;
}
STKPeer* peer = event->getPeer();
uint32_t token = data.getUInt32(1);
if (token != peer->getClientServerToken())
{
Log::warn("Protocol", "Peer sending bad token. Request "
"aborted.");
Log::warn("Protocol", "Receiving a badly formated message:");
Log::warn("Protocol", data.getLogMessage().c_str());
return false;
}
return true;
} // checkDataSizeAndToken
// ----------------------------------------------------------------------------
bool Protocol::isByteCorrect(Event* event, int byte_nb, int value)
{
const 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;
} // isByteCorrect
} // checkDataSize
// ----------------------------------------------------------------------------
/** Starts a request in the protocol manager to start this protocol.

View File

@ -124,8 +124,7 @@ public:
/// functions to check incoming data easily
NetworkString* getNetworkString(int capacity=16);
bool checkDataSizeAndToken(Event* event, unsigned int minimum_size);
bool isByteCorrect(Event* event, int byte_nb, int value);
bool checkDataSize(Event* event, unsigned int minimum_size);
void sendMessageToPeersChangingToken(NetworkString *message,
bool reliable = true);
void broadcastToClients(NetworkString *message, bool reliable=true);

View File

@ -62,6 +62,7 @@ void ClientLobbyRoomProtocol::requestKartSelection(const std::string &kart_name)
{
NetworkString *request = getNetworkString(2+kart_name.size());
request->addUInt8(LE_KART_SELECTION).encodeString(kart_name);
sendToServer(request, /*reliable*/ true);
delete request;
} // requestKartSelection
@ -101,8 +102,8 @@ void ClientLobbyRoomProtocol::voteMinor(uint32_t minor)
void ClientLobbyRoomProtocol::voteTrack(const std::string &track,
uint8_t track_nb)
{
NetworkString *request = getNetworkString(8+1+track.size());
request->addUInt8(LE_VOTE_TRACK).encodeString(track).addUInt8(track_nb);
NetworkString *request = getNetworkString(2+1+track.size());
request->addUInt8(LE_VOTE_TRACK).addUInt8(track_nb).encodeString(track);
sendToServer(request, true);
delete request;
} // voteTrack
@ -143,14 +144,14 @@ bool ClientLobbyRoomProtocol::notifyEvent(Event* event)
assert(m_setup); // assert that the setup exists
if (event->getType() == EVENT_TYPE_MESSAGE)
{
const NetworkString &data = event->data();
NetworkString &data = event->data();
assert(data.size()); // assert that data isn't empty
uint8_t message_type = data[0];
if (message_type != LE_KART_SELECTION_UPDATE &&
message_type != LE_RACE_FINISHED )
return false; // don't treat the event
event->removeFront(1);
data.removeFront(1);
Log::info("ClientLobbyRoomProtocol", "Synchronous message of type %d",
message_type);
if (message_type == LE_KART_SELECTION_UPDATE) // kart selection update
@ -170,11 +171,11 @@ bool ClientLobbyRoomProtocol::notifyEventAsynchronous(Event* event)
assert(m_setup); // assert that the setup exists
if (event->getType() == EVENT_TYPE_MESSAGE)
{
const NetworkString &data = event->data();
NetworkString &data = event->data();
assert(data.size()); // assert that data isn't empty
uint8_t message_type = data[0];
event->removeFront(1);
data.removeFront(1);
Log::info("ClientLobbyRoomProtocol", "Asynchronous message of type %d",
message_type);
switch(message_type)
@ -287,25 +288,19 @@ void ClientLobbyRoomProtocol::update()
* \param event : Event providing the information.
*
* Format of the data :
* Byte 0 1 2s
* ---------------------------------------
* Size | 1 | 1 | |
* Data | 1 | 0 <= race id < 16 | player name|
* ---------------------------------------
* Byte 0 1 2
* -------------------------------------
* Size | 1 | 1 | |
* Data | player_id | hostid | player name |
* -------------------------------------
*/
void ClientLobbyRoomProtocol::newPlayer(Event* event)
{
if (!checkDataSize(event, 2)) return;
const NetworkString &data = event->data();
if (data[0] != 1)
{
Log::error("ClientLobbyRoomProtocol",
"A message notifying a new player wasn't formated "
"as expected.");
return;
}
uint8_t player_id = data.getUInt8(1);
uint8_t player_id = data[0];
uint8_t hostid = data[1];
core::stringw name;
data.decodeStringW(2, &name);
// FIXME need adjusting when splitscreen is used/
@ -335,22 +330,17 @@ void ClientLobbyRoomProtocol::newPlayer(Event* event)
* \param event : Event providing the information.
*
* Format of the data :
* Byte 0 1 2
* -------------------------
* Size | 1 | 1 |
* Data | 1 | 0 <= race id < 16 |
* -------------------------
* Byte 0
* -------------
* Size | 1 |
* Data | player id |
* -------------
*/
void ClientLobbyRoomProtocol::disconnectedPlayer(Event* event)
{
if (!checkDataSize(event, 1)) return;
const NetworkString &data = event->data();
if (data.size() != 2 || data[0] != 1)
{
Log::error("ClientLobbyRoomProtocol",
"A message notifying a new player wasn't formated "
"as expected.");
return;
}
if (m_setup->removePlayer(event->getPeer()->getPlayerProfile()))
{
Log::info("ClientLobbyRoomProtocol", "Peer removed successfully.");
@ -371,21 +361,16 @@ void ClientLobbyRoomProtocol::disconnectedPlayer(Event* event)
* Format of the data :
* Byte 0 1 2 3
* ---------------------------------------------------------
* Size | 1 | 1 | 1 | |
* Data | 0 <= race id < 16 | hostid | authorised |playernames* |
* Size | 1 | 1 | 1 | |
* Data | player_id| hostid | authorised |playernames* |
* ---------------------------------------------------------
*/
void ClientLobbyRoomProtocol::connectionAccepted(Event* event)
{
// At least 3 bytes should remain now
if(!checkDataSize(event, 3)) return;
NetworkString &data = event->data();
// At least 12 bytes should remain now
if (data.size() < 3)
{
Log::error("ClientLobbyRoomProtocol",
"A message notifying an accepted connection wasn't "
"formated as expected.");
return;
}
STKPeer* peer = event->getPeer();
// Accepted
@ -399,9 +384,9 @@ void ClientLobbyRoomProtocol::connectionAccepted(Event* event)
name = PlayerManager::getCurrentOnlineUserName();
else
name = PlayerManager::getCurrentPlayer()->getName();
uint8_t my_player_id = data.getUInt8(0);
uint8_t my_host_id = data.getUInt8(1);
uint8_t authorised = data.getUInt8(2);
uint8_t my_player_id = data[0];
uint8_t my_host_id = data[1];
uint8_t authorised = data[2];
data.removeFront(3);
// Store this client's authorisation status in the peer information
// for the server.
@ -449,24 +434,18 @@ void ClientLobbyRoomProtocol::connectionAccepted(Event* event)
* \param event : Event providing the information.
*
* Format of the data :
* Byte 0 1 2
* --------------------
* Size | 1 | 1 |
* Data | 1 | refusal code |
* --------------------
* Byte 0
* ----------------
* Size | 1 |
* Data | refusal code |
* ----------------
*/
void ClientLobbyRoomProtocol::connectionRefused(Event* event)
{
if (!checkDataSize(event, 1)) return;
const NetworkString &data = event->data();
if (data.size() != 2 || data[0] != 1) // 2 bytes remains now
{
Log::error("ClientLobbyRoomProtocol",
"A message notifying a refused connection wasn't formated "
"as expected.");
return;
}
switch (data[1]) // the second byte
switch (data[0]) // the second byte
{
case 0:
Log::info("ClientLobbyRoomProtocol",
@ -490,24 +469,19 @@ void ClientLobbyRoomProtocol::connectionRefused(Event* event)
* \param event : Event providing the information.
*
* Format of the data :
* Byte 0 1 2
* --------------------
* Size | 1 | 1 |
* Data | 1 | refusal code |
* --------------------
* Byte 0
* ----------------
* Size | 1 |
* Data | refusal code |
* ----------------
*/
void ClientLobbyRoomProtocol::kartSelectionRefused(Event* event)
{
const NetworkString &data = event->data();
if (data.size() != 2 || data[0] != 1)
{
Log::error("ClientLobbyRoomProtocol",
"A message notifying a refused kart selection wasn't "
"formated as expected.");
return;
}
if(!checkDataSize(event, 1)) return;
switch (data[1]) // the error code
const NetworkString &data = event->data();
switch (data[0]) // the error code
{
case 0:
Log::info("ClientLobbyRoomProtocol",
@ -529,25 +503,19 @@ void ClientLobbyRoomProtocol::kartSelectionRefused(Event* event)
* \param event : Event providing the information.
*
* Format of the data :
* Byte 0 1 2 3 N+3
* Byte 0 1 2 3 N+3
* --------------------------------------------------
* Size | 1 | 1 | 1 | N |
* Data | 1 | player id | N (kart name size) | kart name |
* Size | 1 | 1 | N |
* Data | player id | N (kart name size) | kart name |
* --------------------------------------------------
*/
void ClientLobbyRoomProtocol::kartSelectionUpdate(Event* event)
{
if(!checkDataSize(event, 3)) return;
const NetworkString &data = event->data();
if (data.size() < 3 || data[0] != 1)
{
Log::error("ClientLobbyRoomProtocol",
"A message notifying a kart selection update wasn't "
"formated as expected.");
return;
}
uint8_t player_id = data[1];
uint8_t player_id = data[0];
std::string kart_name;
data.decodeString(2, &kart_name);
data.decodeString(1, &kart_name);
if (!m_setup->isKartAvailable(kart_name))
{
Log::error("ClientLobbyRoomProtocol",
@ -561,24 +529,12 @@ void ClientLobbyRoomProtocol::kartSelectionUpdate(Event* event)
//-----------------------------------------------------------------------------
/*! \brief Called when the race needs to be started.
* \param event : Event providing the information.
*
* Format of the data :
* Byte 0 1 5
* -------------
* Size | 1 | 4 |
* Data | 4 | token |
* -------------
* \param event : Event providing the information (no additional information
* in this case).
*/
void ClientLobbyRoomProtocol::startGame(Event* event)
{
const NetworkString &data = event->data();
if (data.size() < 5 || data[0] != 4)
{
Log::error("ClientLobbyRoomProtocol", "A message notifying a kart "
"selection update wasn't formated as expected.");
return;
}
m_state = PLAYING;
ProtocolManager::getInstance()
->requestStart(new StartGameProtocol(m_setup));
@ -588,24 +544,11 @@ void ClientLobbyRoomProtocol::startGame(Event* event)
//-----------------------------------------------------------------------------
/*! \brief Called when the kart selection starts.
* \param event : Event providing the information.
*
* Format of the data :
* Byte 0 1 5
* -------------
* Size | 1 | 4 |
* Data | 4 | token |
* -------------
* \param event : Event providing the information (no additional information
* in this case).
*/
void ClientLobbyRoomProtocol::startSelection(Event* event)
{
const NetworkString &data = event->data();
if (data.size() < 5 || data[0] != 4)
{
Log::error("ClientLobbyRoomProtocol", "A message notifying a kart "
"selection start wasn't formated as expected.");
return;
}
m_state = KART_SELECTION;
Log::info("ClientLobbyRoomProtocol", "Kart selection starts now");
} // startSelection
@ -616,21 +559,17 @@ void ClientLobbyRoomProtocol::startSelection(Event* event)
* \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 | token | 1 | Kart 1 ID | 1 | kart id 2 | ... |
* ---------------------------------------------------
* Byte 0 1
* -------------------------------
* Size | 1 | 1 | |
* Data | Kart 1 ID | kart id 2 | ... |
* -------------------------------
*/
void ClientLobbyRoomProtocol::raceFinished(Event* event)
{
if(!checkDataSize(event, 1)) return;
NetworkString &data = event->data();
if (data.size() < 5)
{
Log::error("ClientLobbyRoomProtocol", "Not enough data provided.");
return;
}
data.removeFront(5);
Log::error("ClientLobbyRoomProtocol",
"Server notified that the race is finished.");
@ -666,21 +605,11 @@ void ClientLobbyRoomProtocol::raceFinished(Event* event)
int position = 1;
while(data.size()>0)
{
if (data.size() < 2)
{
Log::error("ClientLobbyRoomProtocol", "Incomplete field.");
return;
}
if (data[0] != 1)
{
Log::error("ClientLobbyRoomProtocol", "Badly formatted field.");
return;
}
uint8_t kart_id = data[1];
uint8_t kart_id = data[0];
ranked_world->setKartPosition(kart_id,position);
Log::info("ClientLobbyRoomProtocol", "Kart %d has finished #%d",
kart_id, position);
data.removeFront(2);
data.removeFront(1);
position++;
}
ranked_world->endSetKartPositions();
@ -694,22 +623,18 @@ void ClientLobbyRoomProtocol::raceFinished(Event* event)
* \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 |
* --------------------------------------------------------
* Byte 0 1 2
* ------------------------------
* Size | 1 | 1 |
* Data |player id | major mode vote |
* ------------------------------
*/
void ClientLobbyRoomProtocol::playerMajorVote(Event* event)
{
const NetworkString &data = event->data();
if (!checkDataSizeAndToken(event, 9))
if (!checkDataSize(event, 2))
return;
if (!isByteCorrect(event, 5, 1))
return;
if (!isByteCorrect(event, 7, 4))
return;
m_setup->getRaceConfig()->setPlayerMajorVote(data[6], data[8]);
m_setup->getRaceConfig()->setPlayerMajorVote(data[0], data[1]);
} // playerMajorVote
//-----------------------------------------------------------------------------
@ -717,22 +642,17 @@ void ClientLobbyRoomProtocol::playerMajorVote(Event* event)
* \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 |
* ----------------------------------------------------
* Byte 0 1
* ---------------------------
* Size | 1 | 1 |
* Data | player id | races count |
* ---------------------------
*/
void ClientLobbyRoomProtocol::playerRaceCountVote(Event* event)
{
if (!checkDataSize(event, 2)) return;
const 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]);
m_setup->getRaceConfig()->setPlayerRaceCountVote(data[0], data[1]);
} // playerRaceCountVote
//-----------------------------------------------------------------------------
@ -740,22 +660,17 @@ void ClientLobbyRoomProtocol::playerRaceCountVote(Event* event)
* \param event : Event providing the information.
*
* Format of the data :
* Byte 0 1 5 6 7 8 9
* --------------------------------------------------------
* Size | 1 | 4 | 1 | 1 | 1 | 4 |
* Data | 4 | priv token | 1 | player id | 4 | minor mode vote |
* --------------------------------------------------------
* Byte 0 1
* -------------------------------
* Size | 1 | 4 |
* Data | player id | minor mode vote |
* -------------------------------
*/
void ClientLobbyRoomProtocol::playerMinorVote(Event* event)
{
if (!checkDataSize(event, 2)) return;
const NetworkString &data = event->data();
if (!checkDataSizeAndToken(event, 9))
return;
if (!isByteCorrect(event, 5, 1))
return;
if (!isByteCorrect(event, 7, 4))
return;
m_setup->getRaceConfig()->setPlayerMinorVote(data[6], data[8]);
m_setup->getRaceConfig()->setPlayerMinorVote(data[0], data[1]);
} // playerMinorVote
//-----------------------------------------------------------------------------
@ -764,25 +679,20 @@ void ClientLobbyRoomProtocol::playerMinorVote(Event* event)
* \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) |
* ---------------------------------------------------------------------------
* Byte 0 1 2 3
* --------------------------------------------------
* Size | 1 | 1 | 1 | N |
* Data | player id | track number (gp) | N | track name |
* --------------------------------------------------
*/
void ClientLobbyRoomProtocol::playerTrackVote(Event* event)
{
if (!checkDataSize(event, 3)) return;
const NetworkString &data = event->data();
if (!checkDataSizeAndToken(event, 10))
return;
if (!isByteCorrect(event, 5, 1))
return;
std::string track_name;
int N = data.decodeString(7, &track_name);
if (!isByteCorrect(event, N+7, 1))
return;
m_setup->getRaceConfig()->setPlayerTrackVote(data[6], track_name,
data[N+8]);
int N = data.decodeString(2, &track_name);
m_setup->getRaceConfig()->setPlayerTrackVote(data[0], track_name,
data[1]);
} // playerTrackVote
//-----------------------------------------------------------------------------
@ -791,24 +701,18 @@ void ClientLobbyRoomProtocol::playerTrackVote(Event* event)
* \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) |
* -------------------------------------------------------------------------
* Byte 0 1 2
* -------------------------------------------
* Size | 1 | 1 | 1 |
* Data | player id |reversed | track number (gp) |
* -------------------------------------------
*/
void ClientLobbyRoomProtocol::playerReversedVote(Event* event)
{
if (!checkDataSize(event, 3)) return;
const 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]!=0, data[10]);
m_setup->getRaceConfig()->setPlayerReversedVote(data[0], data[1]!=0,
data[2]);
} // playerReversedVote
//-----------------------------------------------------------------------------
@ -817,22 +721,17 @@ void ClientLobbyRoomProtocol::playerReversedVote(Event* event)
* \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) |
* ---------------------------------------------------------------------
* Byte 0 1 2
* ----------------------------------------
* Size | 1 | 1 | 1 |
* Data | player id | laps | track number (gp) |
* ----------------------------------------
*/
void ClientLobbyRoomProtocol::playerLapsVote(Event* event)
{
if (!checkDataSize(event, 3)) return;
const 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]);
m_setup->getRaceConfig()->setPlayerLapsVote(data[0], data[1], data[2]);
} // playerLapsVote
//-----------------------------------------------------------------------------

View File

@ -78,11 +78,11 @@ bool ServerLobbyRoomProtocol::notifyEventAsynchronous(Event* event)
assert(m_setup); // assert that the setup exists
if (event->getType() == EVENT_TYPE_MESSAGE)
{
const NetworkString &data = event->data();
NetworkString &data = event->data();
assert(data.size()); // message not empty
uint8_t message_type;
message_type = data[0];
event->removeFront(1);
data.removeFront(1);
Log::info("ServerLobbyRoomProtocol", "Message received with type %d.",
message_type);
switch(message_type)
@ -224,7 +224,7 @@ void ServerLobbyRoomProtocol::registerServer()
void ServerLobbyRoomProtocol::startGame()
{
const std::vector<STKPeer*> &peers = STKHost::get()->getPeers();
NetworkString *ns = getNetworkString(6);
NetworkString *ns = getNetworkString(1);
ns->addUInt8(LE_START_RACE);
sendMessageToPeersChangingToken(ns, /*reliable*/true);
delete ns;
@ -247,13 +247,10 @@ void ServerLobbyRoomProtocol::startSelection(const Event *event)
return;
}
const std::vector<STKPeer*> &peers = STKHost::get()->getPeers();
NetworkString *ns = getNetworkString(6);
NetworkString *ns = getNetworkString(1);
// start selection
ns->addUInt8(LE_START_SELECTION);
for (unsigned int i = 0; i < peers.size(); i++)
{
peers[i]->sendPacket(ns, /*reliable*/true);
}
sendMessageToPeersChangingToken(ns, /*reliable*/true);
delete ns;
m_selection_enabled = true;
@ -338,17 +335,15 @@ void ServerLobbyRoomProtocol::checkRaceFinished()
const std::vector<STKPeer*> &peers = STKHost::get()->getPeers();
NetworkString *queue = getNetworkString(karts_results.size()*2);
NetworkString *total = getNetworkString(1+karts_results.size());
total->setSynchronous(true);
total->addUInt8(LE_RACE_FINISHED);
for (unsigned int i = 0; i < karts_results.size(); i++)
{
queue->addUInt8(1).addUInt8(karts_results[i]); // kart pos = i+1
total->addUInt8(karts_results[i]); // kart pos = i+1
Log::info("ServerLobbyRoomProtocol", "Kart %d finished #%d",
karts_results[i], i + 1);
}
NetworkString *total = getNetworkString();
total->setSynchronous(true);
total->addUInt8(LE_RACE_FINISHED).addUInt8(4);
*total += *queue;
sendMessageToPeersChangingToken(total, /*reliable*/ true);
delete total;
Log::info("ServerLobbyRoomProtocol", "End of game message sent");
@ -394,8 +389,8 @@ void ServerLobbyRoomProtocol::kartDisconnected(Event* event)
STKPeer* peer = event->getPeer();
if (peer->getPlayerProfile() != NULL) // others knew him
{
NetworkString *msg = getNetworkString(3);
msg->addUInt8(LE_PLAYER_DISCONNECTED).addUInt8(1)
NetworkString *msg = getNetworkString(2);
msg->addUInt8(LE_PLAYER_DISCONNECTED)
.addUInt8(peer->getPlayerProfile()->getGlobalPlayerId());
broadcastToClients(msg);
delete msg;
@ -431,9 +426,9 @@ void ServerLobbyRoomProtocol::connectionRequested(Event* event)
if (m_setup->getPlayerCount() >= NetworkConfig::get()->getMaxPlayers() ||
m_state!=ACCEPTING_CLIENTS )
{
NetworkString *message = getNetworkString(3);
NetworkString *message = getNetworkString(2);
// Len, error code: 2 = busy, 0 = too many players
message->addUInt8(LE_CONNECTION_REFUSED).addUInt8(1)
message->addUInt8(LE_CONNECTION_REFUSED)
.addUInt8(m_state!=ACCEPTING_CLIENTS ? 2 : 0);
// send only to the peer that made the request
@ -466,10 +461,10 @@ void ServerLobbyRoomProtocol::connectionRequested(Event* event)
// Notify everybody that there is a new player
// -------------------------------------------
NetworkString *message = getNetworkString(8);
NetworkString *message = getNetworkString(3+1+name_u8.size());
// size of id -- id -- size of local id -- local id;
message->addUInt8(LE_NEW_PLAYER_CONNECTED).addUInt8(1).addUInt8(new_player_id)
.encodeString(name_u8).addUInt8(new_host_id);
message->addUInt8(LE_NEW_PLAYER_CONNECTED).addUInt8(new_player_id)
.addUInt8(new_host_id).encodeString(name_u8);
ProtocolManager::getInstance()->sendMessageExcept(peer, message);
delete message;
@ -486,9 +481,8 @@ void ServerLobbyRoomProtocol::connectionRequested(Event* event)
const std::vector<NetworkPlayerProfile*> &players = m_setup->getPlayers();
// send a message to the one that asked to connect
// Size is overestimated, probably one player's data will not be sent
NetworkString *message_ack = getNetworkString(14 + players.size() * 7);
message_ack->setToken(token);
// Estimate 10 as average name length
NetworkString *message_ack = getNetworkString(4 + players.size() * (2+10));
// connection success -- size of token -- token
message_ack->addUInt8(LE_CONNECTION_ACCEPTED).addUInt8(new_player_id)
.addUInt8(new_host_id).addUInt8(is_authorised);
@ -520,11 +514,11 @@ void ServerLobbyRoomProtocol::connectionRequested(Event* event)
* \param event : Event providing the information.
*
* Format of the data :
* Byte 0 1 5 6 N+6
* -----------------------------------------------
* Size | 4 | 1 | N |
* Data | priv token | N (kart name size) | kart name |
* -----------------------------------------------
* Byte 0 1
* ----------------------------------
* Size | 1 | N |
* Data | N (kart name size) | kart name |
* ----------------------------------
*/
void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
{
@ -535,19 +529,19 @@ void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
return;
}
if (!checkDataSize(event, 1)) return;
const NetworkString &data = event->data();
STKPeer* peer = event->getPeer();
if (!checkDataSizeAndToken(event, 6))
return;
std::string kart_name;
data.decodeString(5, &kart_name);
data.decodeString(0, &kart_name);
// check if selection is possible
if (!m_selection_enabled)
{
NetworkString *answer = getNetworkString(3);
NetworkString *answer = getNetworkString(2);
// selection still not started
answer->addUInt8(LE_KART_SELECTION_REFUSED).addUInt8(1).addUInt8(2);
answer->addUInt8(LE_KART_SELECTION_REFUSED).addUInt8(2);
peer->sendPacket(answer);
delete answer;
return;
@ -555,9 +549,9 @@ void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
// check if somebody picked that kart
if (!m_setup->isKartAvailable(kart_name))
{
NetworkString *answer = getNetworkString(3);
NetworkString *answer = getNetworkString(2);
// kart is already taken
answer->addUInt8(LE_KART_SELECTION_REFUSED).addUInt8(1).addUInt8(0);
answer->addUInt8(LE_KART_SELECTION_REFUSED).addUInt8(0);
peer->sendPacket(answer);
delete answer;
return;
@ -565,23 +559,23 @@ void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
// check if this kart is authorized
if (!m_setup->isKartAllowed(kart_name))
{
NetworkString *answer = getNetworkString(3);
NetworkString *answer = getNetworkString(2);
// kart is not authorized
answer->addUInt8(LE_KART_SELECTION_REFUSED).addUInt8(1).addUInt8(1);
answer->addUInt8(LE_KART_SELECTION_REFUSED).addUInt8(1);
peer->sendPacket(answer);
delete answer;
return;
}
// send a kart update to everyone
NetworkString *answer = getNetworkString(3+1+kart_name.size());
NetworkString *answer = getNetworkString(3+kart_name.size());
// This message must be handled synchronously on the client.
answer->setSynchronous(true);
// kart update (3), 1, race id
uint8_t player_id = peer->getPlayerProfile()->getGlobalPlayerId();
answer->addUInt8(LE_KART_SELECTION_UPDATE).addUInt8(1).addUInt8(player_id)
answer->addUInt8(LE_KART_SELECTION_UPDATE).addUInt8(player_id)
.encodeString(kart_name);
broadcastToClients(answer);
sendMessageToPeersChangingToken(answer);
delete answer;
m_setup->setPlayerKart(player_id, kart_name);
} // kartSelectionRequested
@ -592,28 +586,24 @@ void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
* \param event : Event providing the information.
*
* Format of the data :
* Byte 0 1 5 6 10
* ----------------------------------------
* Size | 1 | 4 | 1 | 4 |
* Data | 4 | priv token | 4 | major mode vote |
* ----------------------------------------
* Byte 0 1
* -------------------
* Size | 4 |
* Data | major mode vote |
* -------------------
*/
void ServerLobbyRoomProtocol::playerMajorVote(Event* event)
{
if (!checkDataSize(event, 1)) return;
NetworkString &data = event->data();
STKPeer* peer = event->getPeer();
if (!checkDataSizeAndToken(event, 7))
return;
if (!isByteCorrect(event, 5, 4))
return;
uint8_t player_id = peer->getPlayerProfile()->getGlobalPlayerId();
uint32_t major = data.getUInt32(6);
uint32_t major = data.getUInt32(0);
m_setup->getRaceConfig()->setPlayerMajorVote(player_id, major);
// Send the vote to everybody (including the sender)
data.removeFront(5); // remove the token
NetworkString *other = getNetworkString(6+data.size());
other->addUInt8(LE_VOTE_MAJOR).addUInt8(1).addUInt8(player_id); // add the player id
*other += data; // add the data
NetworkString *other = getNetworkString(6);
other->addUInt8(LE_VOTE_MAJOR).addUInt8(player_id).addUInt32(major);
sendMessageToPeersChangingToken(other);
delete other;
} // playerMajorVote
@ -624,28 +614,24 @@ void ServerLobbyRoomProtocol::playerMajorVote(Event* event)
* \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 |
* ------------------------------------
* Byte 0 1
* ---------------
* Size | 1 |
* Data | races count |
* ---------------
*/
void ServerLobbyRoomProtocol::playerRaceCountVote(Event* event)
{
if (!checkDataSize(event, 1)) return;
NetworkString &data = event->data();
STKPeer* peer = event->getPeer();
if (!checkDataSizeAndToken(event, 7))
return;
if (!isByteCorrect(event, 5, 1))
return;
uint8_t player_id = peer->getPlayerProfile()->getGlobalPlayerId();
m_setup->getRaceConfig()->setPlayerRaceCountVote(player_id, data[6]);
uint8_t race_count = data[0];
m_setup->getRaceConfig()->setPlayerRaceCountVote(player_id, race_count);
// Send the vote to everybody (including the sender)
data.removeFront(5); // remove the token
NetworkString *other = getNetworkString(3+data.size());
other->addUInt8(LE_VOTE_RACE_COUNT).addUInt8(1)
.addUInt8(player_id); // add the player id
*other += data; // add the data
NetworkString *other = getNetworkString(3);
other->addUInt8(LE_VOTE_RACE_COUNT).addUInt8(player_id)
.addUInt8(race_count);
sendMessageToPeersChangingToken(other);
delete other;
} // playerRaceCountVote
@ -656,28 +642,24 @@ void ServerLobbyRoomProtocol::playerRaceCountVote(Event* event)
* \param event : Event providing the information.
*
* Format of the data :
* Byte 0 1 5 6 10
* ----------------------------------------
* Size | 1 | 4 | 1 | 4 |
* Data | 4 | priv token | 4 | minor mode vote |
* ----------------------------------------
* Byte 0 1
* -------------------
* Size | 4 |
* Data | minor mode vote |
* -------------------
*/
void ServerLobbyRoomProtocol::playerMinorVote(Event* event)
{
if (!checkDataSize(event, 1)) return;
NetworkString &data = event->data();
STKPeer* peer = event->getPeer();
if (!checkDataSizeAndToken(event, 7))
return;
if (!isByteCorrect(event, 5, 4))
return;
uint8_t player_id = peer->getPlayerProfile()->getGlobalPlayerId();
uint32_t minor = data.getUInt32(6);
uint32_t minor = data.getUInt32(0);
m_setup->getRaceConfig()->setPlayerMinorVote(player_id, minor);
// Send the vote to everybody (including the sender)
data.removeFront(5); // remove the token
NetworkString *other = getNetworkString(3+data.size());
other->addUInt8(LE_VOTE_MINOR).addUInt8(1).addUInt8(player_id);
*other += data; // add the data
NetworkString *other = getNetworkString(3);
other->addUInt8(LE_VOTE_MINOR).addUInt8(player_id).addUInt8(minor);
sendMessageToPeersChangingToken(other);
delete other;
} // playerMinorVote
@ -688,29 +670,29 @@ void ServerLobbyRoomProtocol::playerMinorVote(Event* event)
* \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) |
* -----------------------------------------------------------
* Byte 0 1 2
* --------------------------------------
* Size | 1 | 1 | N |
* Data | track number (gp) | N | track name |
* --------------------------------------
*/
void ServerLobbyRoomProtocol::playerTrackVote(Event* event)
{
if (!checkDataSize(event, 2)) return;
NetworkString &data = event->data();
STKPeer* peer = event->getPeer();
if (!checkDataSizeAndToken(event, 8))
return;
// As which track this track should be used, e.g. 1st track: Santrack
// 2nd track Mathclass, ...
uint8_t track_number = data[0];
std::string track_name;
int N = data.decodeString(5, &track_name);
if (!isByteCorrect(event, N+5, 1))
return;
int N = data.decodeString(1, &track_name);
uint8_t player_id = peer->getPlayerProfile()->getGlobalPlayerId();
m_setup->getRaceConfig()->setPlayerTrackVote(player_id, track_name, data[N+6]);
m_setup->getRaceConfig()->setPlayerTrackVote(player_id, track_name,
track_number);
// Send the vote to everybody (including the sender)
data.removeFront(5); // remove the token
NetworkString *other = getNetworkString(3+data.size());
other->addUInt8(LE_VOTE_TRACK).addUInt8(1).addUInt8(player_id);
*other += data; // add the data
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;
if(m_setup->getRaceConfig()->getNumTrackVotes()==m_setup->getPlayerCount())
@ -723,30 +705,27 @@ void ServerLobbyRoomProtocol::playerTrackVote(Event* event)
* \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) |
* ---------------------------------------------------------
* Byte 0 1
* --------------------------------
* Size | 1 | 1 |
* Data | reversed | track number (gp) |
* --------------------------------
*/
void ServerLobbyRoomProtocol::playerReversedVote(Event* event)
{
if (!checkDataSize(event, 2)) return;
NetworkString &data = event->data();
STKPeer* peer = event->getPeer();
if (!checkDataSizeAndToken(event, 9))
return;
if (!isByteCorrect(event, 5, 1))
return;
if (!isByteCorrect(event, 7, 1))
return;
uint8_t player_id = peer->getPlayerProfile()->getGlobalPlayerId();
uint8_t reverse = data[0];
uint8_t nb_track = data[1];
m_setup->getRaceConfig()->setPlayerReversedVote(player_id,
data[6]!=0, data[8]);
reverse!=0, nb_track);
// Send the vote to everybody (including the sender)
data.removeFront(5); // remove the token
NetworkString *other = getNetworkString(3+data.size());
other->addUInt8(LE_VOTE_REVERSE).addUInt8(1).addUInt8(player_id);
*other += data; // add the data
NetworkString *other = getNetworkString(4);
other->addUInt8(LE_VOTE_REVERSE).addUInt8(player_id).addUInt8(reverse)
.addUInt8(nb_track);
sendMessageToPeersChangingToken(other);
delete other;
} // playerReversedVote
@ -757,29 +736,25 @@ void ServerLobbyRoomProtocol::playerReversedVote(Event* event)
* \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) |
* -----------------------------------------------------
* Byte 0 1
* ----------------------------
* Size | 1 | 1 |
* Data | laps | track number (gp) |
* ----------------------------
*/
void ServerLobbyRoomProtocol::playerLapsVote(Event* event)
{
if (!checkDataSize(event, 2)) return;
NetworkString &data = event->data();
STKPeer* peer = event->getPeer();
if (!checkDataSizeAndToken(event, 9))
return;
if (!isByteCorrect(event, 5, 1))
return;
if (!isByteCorrect(event, 7, 1))
return;
uint8_t player_id = peer->getPlayerProfile()->getGlobalPlayerId();
m_setup->getRaceConfig()->setPlayerLapsVote(player_id, data[6], data[8]);
// Send the vote to everybody (including the sender)
data.removeFront(5); // remove the token
NetworkString *other = getNetworkString(3+data.size());
other->addUInt8(LE_VOTE_LAPS).addUInt8(1).addUInt8(player_id);
*other += data; // add the data
uint8_t lap_count = data[0];
uint8_t track_nb = data[1];
m_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

View File

@ -123,20 +123,11 @@ void StartGameProtocol::setup()
// ----------------------------------------------------------------------------
bool StartGameProtocol::notifyEventAsynchronous(Event* event)
{
if(!checkDataSize(event, 1)) return true;
const NetworkString &data = event->data();
if (data.size() < 5)
{
Log::error("StartGameProtocol", "Too short message.");
return true;
}
uint32_t token = data.getUInt32();
uint8_t ready = data.getUInt8(4);
uint8_t ready = data.getUInt8(0);
STKPeer* peer = event->getPeer();
if (peer->getClientServerToken() != token)
{
Log::error("StartGameProtocol", "Bad token received.");
return true;
}
if (NetworkConfig::get()->isServer() && ready) // on server, player is ready
{
Log::info("StartGameProtocol", "One of the players is ready.");
@ -219,8 +210,8 @@ void StartGameProtocol::ready()
if (NetworkConfig::get()->isClient())
{
assert(STKHost::get()->getPeerCount() == 1);
NetworkString *ns = getNetworkString(5);
ns->setToken(STKHost::get()->getPeers()[0]->getClientServerToken());
NetworkString *ns = getNetworkString(1);
// 1 indicates: client is ready
ns->addUInt8(1);
Log::info("StartGameProtocol", "Player ready, notifying server.");
sendToServer(ns, /*reliable*/true);

View File

@ -42,16 +42,11 @@ bool SynchronizationProtocol::notifyEventAsynchronous(Event* event)
{
if (event->getType() != EVENT_TYPE_MESSAGE)
return true;
if(!checkDataSize(event, 5)) return true;
const NetworkString &data = event->data();
if (data.size() < 9)
{
Log::warn("SynchronizationProtocol", "Received a too short message.");
return true;
}
uint32_t token = data.getUInt32(0);
uint32_t request = data.getUInt8(4);
uint32_t sequence = data.getUInt32(5);
uint32_t request = data.getUInt8(0);
uint32_t sequence = data.getUInt32(1);
const std::vector<STKPeer*> &peers = STKHost::get()->getPeers();
assert(peers.size() > 0);
@ -68,19 +63,12 @@ bool SynchronizationProtocol::notifyEventAsynchronous(Event* event)
break;
}
}
if (event->getPeer()->getClientServerToken() != token)
{
Log::warn("SynchronizationProtocol", "Bad token from peer %d",
peer_id);
return true;
}
if (request)
{
// Only a client should receive a request for a ping response
assert(NetworkConfig::get()->isClient());
NetworkString *response = getNetworkString(10);
response->setToken(token);
NetworkString *response = getNetworkString(5);
// The '0' indicates a response to a ping request
response->addUInt8(0).addUInt32(sequence);
event->getPeer()->sendPacket(response, false);
@ -89,9 +77,9 @@ bool SynchronizationProtocol::notifyEventAsynchronous(Event* event)
sequence, StkTime::getRealTime());
// countdown time in the message
if (data.size() == 13)
if (data.size() == 9)
{
uint32_t time_to_start = data.getUInt32(9);
uint32_t time_to_start = data.getUInt32(5);
Log::debug("SynchronizationProtocol",
"Request to start game in %d.", time_to_start);
if (!m_countdown_activated)
@ -171,12 +159,13 @@ void SynchronizationProtocol::asynchronousUpdate()
const std::vector<STKPeer*> &peers = STKHost::get()->getPeers();
for (unsigned int i = 0; i < peers.size(); i++)
{
NetworkString *ping_request = getNetworkString(13);
NetworkString *ping_request =
getNetworkString(m_countdown_activated ? 9 : 5);
ping_request->addUInt8(1).addUInt32(m_pings[i].size());
// Server adds the countdown if it has started. This will indicate
// to the client to start the countdown as well (first time the
// message is received), or to update the countdown time.
if (m_countdown_activated )
if (m_countdown_activated)
{
ping_request->addUInt32((int)(m_countdown*1000.0));
Log::debug("SynchronizationProtocol",

View File

@ -37,7 +37,7 @@ void RaceEventManager::update(float dt)
ProtocolManager::getInstance()->getProtocol(PROTOCOL_SYNCHRONIZATION));
if (protocol) // The existance of this protocol indicates that we play online
{
Log::debug("RaceEventManager", "Coutdown value is %f",
Log::debug("RaceEventManager", "Countdown value is %f",
protocol->getCountdown());
if (protocol->getCountdown() > 0.0)
{