Send the player's online or local (if not online) name to the server
and all clients.
This commit is contained in:
parent
801b390860
commit
b092b47a58
@ -20,13 +20,18 @@
|
||||
|
||||
#include "online/online_player_profile.hpp"
|
||||
|
||||
NetworkPlayerProfile::NetworkPlayerProfile(int race_player_id)
|
||||
/** Constructor. The player id is a unique number assigned from the server
|
||||
* to this player (though it might not be the index in the peer list).
|
||||
*/
|
||||
NetworkPlayerProfile::NetworkPlayerProfile(int race_player_id,
|
||||
const irr::core::stringw &name)
|
||||
{
|
||||
m_race_player_id = race_player_id;
|
||||
m_online_profile = NULL;
|
||||
m_kart_name = "";
|
||||
m_world_kart_id = 0;
|
||||
m_per_player_difficulty = PLAYER_DIFFICULTY_NORMAL;
|
||||
m_player_name = name;
|
||||
} // BetworkPlayerProfile
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -36,12 +36,17 @@ namespace Online { class OnlineProfile; }
|
||||
class NetworkPlayerProfile
|
||||
{
|
||||
private:
|
||||
/** The id of the player for the race. */
|
||||
/** The unique id of the player for this race. The number is assigned
|
||||
* by the server (and it might not be the index of this player in the
|
||||
* peer list. */
|
||||
uint8_t m_race_player_id;
|
||||
|
||||
/** The selected kart. */
|
||||
/** The selected kart id. */
|
||||
std::string m_kart_name;
|
||||
|
||||
/** The name of the player. */
|
||||
irr::core::stringw m_player_name;
|
||||
|
||||
/** Pointer to the online profile of this player. */
|
||||
Online::OnlineProfile* m_online_profile;
|
||||
|
||||
@ -51,8 +56,9 @@ private:
|
||||
/** Per player difficulty. */
|
||||
PerPlayerDifficulty m_per_player_difficulty;
|
||||
public:
|
||||
NetworkPlayerProfile(int race_player_id);
|
||||
~NetworkPlayerProfile();
|
||||
NetworkPlayerProfile(int race_player_id,
|
||||
const irr::core::stringw &name);
|
||||
~NetworkPlayerProfile();
|
||||
int getGlobalID() const;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@ -85,8 +91,13 @@ public:
|
||||
Online::OnlineProfile *getOnlineProfile() { return m_online_profile; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the per-player difficulty. */
|
||||
PerPlayerDifficulty getPerPlayerDifficulty() const { return m_per_player_difficulty; }
|
||||
PerPlayerDifficulty getPerPlayerDifficulty() const
|
||||
{
|
||||
return m_per_player_difficulty;
|
||||
} // getPerPlayerDifficulty
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the name of this player. */
|
||||
const irr::core::stringw& getName() const { return m_player_name; }
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
}; // class NetworkPlayerProfile
|
||||
|
@ -16,9 +16,64 @@
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#include "network/network_string.hpp"
|
||||
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
NetworkString operator+(NetworkString const& a, NetworkString const& b)
|
||||
{
|
||||
NetworkString ns(a);
|
||||
ns += b;
|
||||
return ns;
|
||||
}
|
||||
} // operator+
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Adds one byte for the length of the string, and then (up to 255 of)
|
||||
* the characters of the given string. */
|
||||
NetworkString& NetworkString::encodeString(const std::string &value)
|
||||
{
|
||||
int len = value.size();
|
||||
if(len<=255)
|
||||
return addUInt8(len).addString(value);
|
||||
else
|
||||
return addUInt8(255).addString(value.substr(0, 255));
|
||||
} // encodeString
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Adds one byte for the length of the string, and then (up to 255 of)
|
||||
* the characters of the given string. */
|
||||
NetworkString& NetworkString::encodeString(const irr::core::stringw &value)
|
||||
{
|
||||
std::string v = StringUtils::wideToUtf8(value);
|
||||
return encodeString(v);
|
||||
} // encodeString
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns a string at the given position. The first byte indicates the
|
||||
* length, followed by the actual string (not 0 terminated).
|
||||
* \param[in] pos Buffer position where the encoded string starts.
|
||||
* \param[out] out The decoded string.
|
||||
* \return number of bytes read = 1+length of string
|
||||
*/
|
||||
int NetworkString::decodeString(int pos, std::string *out) const
|
||||
{
|
||||
uint8_t len = getUInt8(pos);
|
||||
*out = getString(pos+1, len);
|
||||
return len;
|
||||
} // decodeString
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns an irrlicht wide string from the utf8 encoded string at the
|
||||
* given position.
|
||||
* \param[in] pos Buffer position where the encoded string starts.
|
||||
* \param[out] out The decoded string.
|
||||
* \return number of bytes read. If there are no special characters in the
|
||||
* string that will be 1+length of string, but multi-byte encoded
|
||||
* characters can mean that the length of the returned string is
|
||||
* less than the number of bytes read.
|
||||
*/
|
||||
int NetworkString::decodeStringW(int pos, irr::core::stringw *out) const
|
||||
{
|
||||
std::string s;
|
||||
int len = decodeString(pos, &s);
|
||||
*out = StringUtils::utf8ToWide(s);
|
||||
return len;
|
||||
} // decodeString
|
||||
|
@ -25,6 +25,8 @@
|
||||
|
||||
#include "utils/types.hpp"
|
||||
|
||||
#include "irrString.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
@ -85,6 +87,11 @@ public:
|
||||
memcpy(m_string.data(), p, len);
|
||||
} // NetworkString(char*, int)
|
||||
// ------------------------------------------------------------------------
|
||||
NetworkString& encodeString(const std::string &value);
|
||||
NetworkString& encodeString(const irr::core::stringw &value);
|
||||
int decodeString(int n, std::string *out) const;
|
||||
int decodeStringW(int n, irr::core::stringw *out) const;
|
||||
// ------------------------------------------------------------------------
|
||||
NetworkString& add(const std::string &s)
|
||||
{
|
||||
return addUInt8(uint8_t(s.size())).as(s);
|
||||
@ -218,7 +225,6 @@ public:
|
||||
/** Adds a single character. */
|
||||
inline NetworkString& ac(const char& value) { return addChar(value); }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds a string. */
|
||||
NetworkString& addString(const std::string& value)
|
||||
{
|
||||
|
@ -234,10 +234,18 @@ void ClientLobbyRoomProtocol::update()
|
||||
break;
|
||||
case LINKED:
|
||||
{
|
||||
NetworkString ns(6);
|
||||
core::stringw name;
|
||||
if(PlayerManager::getCurrentOnlineState()==PlayerProfile::OS_SIGNED_IN)
|
||||
name = PlayerManager::getCurrentOnlineUserName();
|
||||
else
|
||||
name = PlayerManager::getCurrentPlayer()->getName();
|
||||
|
||||
std::string name_u8 = StringUtils::wideToUtf8(name);
|
||||
NetworkString ns(6+1+name_u8.size());
|
||||
// 4 (size of id), global id
|
||||
ns.ai8(LE_CONNECTION_REQUESTED).ai8(4)
|
||||
.ai32(PlayerManager::getCurrentOnlineId());
|
||||
.addUInt32(PlayerManager::getCurrentOnlineId())
|
||||
.encodeString(name);
|
||||
sendMessage(ns);
|
||||
m_state = REQUESTING_CONNECTION;
|
||||
}
|
||||
@ -283,11 +291,11 @@ void ClientLobbyRoomProtocol::update()
|
||||
* \param event : Event providing the information.
|
||||
*
|
||||
* Format of the data :
|
||||
* Byte 0 1 5 6 7
|
||||
* ------------------------------------------------
|
||||
* Size | 1 | 4 | 1 | 1 |
|
||||
* Data | 4 | player global id | 1 | 0 <= race id < 16 |
|
||||
* ------------------------------------------------
|
||||
* Byte 0 1 5 6 7 8
|
||||
* -------------------------------------------------------------------
|
||||
* Size | 1 | 4 | 1 | 1 | 1 | |
|
||||
* Data | 4 | player global id | 1 | 0 <= race id < 16 | len | player name|
|
||||
* -------------------------------------------------------------------
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::newPlayer(Event* event)
|
||||
{
|
||||
@ -302,7 +310,9 @@ void ClientLobbyRoomProtocol::newPlayer(Event* event)
|
||||
|
||||
uint32_t global_id = data.gui32(1);
|
||||
uint8_t player_id = data.gui8(6);
|
||||
|
||||
int name_len = data.getUInt8(7);
|
||||
std::string name_utf8 = data.getString(8, name_len);
|
||||
core::stringw name = StringUtils::utf8ToWide(name_utf8);
|
||||
if (global_id == PlayerManager::getCurrentOnlineId())
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol",
|
||||
@ -313,8 +323,7 @@ void ClientLobbyRoomProtocol::newPlayer(Event* event)
|
||||
m_setup->getProfile(global_id) == NULL)
|
||||
{
|
||||
Log::verbose("ClientLobbyRoomProtocol", "New player connected.");
|
||||
// FIXME: what player id to use?
|
||||
NetworkPlayerProfile* profile = new NetworkPlayerProfile(-1);
|
||||
NetworkPlayerProfile* profile = new NetworkPlayerProfile(player_id, name);
|
||||
profile->setPlayerID(player_id);
|
||||
// FIXME: memory leak??
|
||||
profile->setOnlineProfile(new Online::OnlineProfile(global_id, ""));
|
||||
@ -369,13 +378,13 @@ void ClientLobbyRoomProtocol::disconnectedPlayer(Event* event)
|
||||
* Byte 0 1 2 3 7 8 12
|
||||
* ----------------------------------------------------------
|
||||
* Size | 1 | 1 | 1 | 4 | 1 | 4 |
|
||||
* Data | 1 | 0 <= race id < 16 | 4 | priv token | 4 | global id |
|
||||
* Data | 1 | 0 <= race id < 16 | 4 | priv token | 4 | global id | playernames*
|
||||
* ----------------------------------------------------------
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::connectionAccepted(Event* event)
|
||||
{
|
||||
NetworkString &data = event->data();
|
||||
// 12 bytes should remain now
|
||||
// At least 12 bytes should remain now
|
||||
if (data.size() < 12 || data[0] != 1 || data[2] != 4 || data[7] != 4)
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol",
|
||||
@ -386,55 +395,60 @@ void ClientLobbyRoomProtocol::connectionAccepted(Event* event)
|
||||
STKPeer* peer = event->getPeer();
|
||||
|
||||
uint32_t global_id = data.gui32(8);
|
||||
if (global_id == PlayerManager::getCurrentOnlineId())
|
||||
if (global_id != PlayerManager::getCurrentOnlineId())
|
||||
{
|
||||
Log::info("ClientLobbyRoomProtocol",
|
||||
"The server accepted the connection.");
|
||||
|
||||
// self profile
|
||||
//FIXME
|
||||
NetworkPlayerProfile* profile = new NetworkPlayerProfile(-1);
|
||||
profile->setPlayerID(data.gui8(1));
|
||||
profile->setOnlineProfile(PlayerManager::getCurrentOnlineProfile());
|
||||
m_setup->addPlayer(profile);
|
||||
// connection token
|
||||
uint32_t token = data.gui32(3);
|
||||
peer->setClientServerToken(token);
|
||||
// add all players
|
||||
data.removeFront(12); // remove the 12 first bytes
|
||||
int remaining = data.size();
|
||||
if (remaining%7 != 0)
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol",
|
||||
"ConnectionAccepted : Error in the server list");
|
||||
}
|
||||
remaining /= 7;
|
||||
for (int i = 0; i < remaining; i++)
|
||||
{
|
||||
if (data[0] != 1 || data[2] != 4)
|
||||
Log::error("ClientLobbyRoomProtocol",
|
||||
"Bad format in players list.");
|
||||
|
||||
uint8_t race_id = data[1];
|
||||
uint32_t global_id = data.gui32(3);
|
||||
Online::OnlineProfile* new_user =
|
||||
new Online::OnlineProfile(global_id, "");
|
||||
|
||||
// FIXME
|
||||
NetworkPlayerProfile* profile2 = new NetworkPlayerProfile(-1);
|
||||
profile2->setPlayerID(race_id);
|
||||
profile2->setOnlineProfile(new_user);
|
||||
m_setup->addPlayer(profile2);
|
||||
data.removeFront(7);
|
||||
}
|
||||
|
||||
// add self
|
||||
m_server = event->getPeer();
|
||||
m_state = CONNECTED;
|
||||
}
|
||||
else
|
||||
Log::info("ClientLobbyRoomProtocol",
|
||||
"Failure during the connection acceptation process.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Accepted
|
||||
// ========
|
||||
Log::info("ClientLobbyRoomProtocol",
|
||||
"The server accepted the connection.");
|
||||
|
||||
// self profile
|
||||
irr::core::stringw name;
|
||||
if (PlayerManager::getCurrentOnlineState() == PlayerProfile::OS_SIGNED_IN)
|
||||
name = PlayerManager::getCurrentOnlineUserName();
|
||||
else
|
||||
name = PlayerManager::getCurrentPlayer()->getName();
|
||||
NetworkPlayerProfile* profile = new NetworkPlayerProfile(-1, name);
|
||||
profile->setPlayerID(data.gui8(1));
|
||||
profile->setOnlineProfile(PlayerManager::getCurrentOnlineProfile());
|
||||
m_setup->addPlayer(profile);
|
||||
// connection token
|
||||
uint32_t token = data.gui32(3);
|
||||
peer->setClientServerToken(token);
|
||||
|
||||
// Add all players
|
||||
// ===============
|
||||
int n = 12;
|
||||
while (n < data.size())
|
||||
{
|
||||
if (data[n] != 1 || data[n + 2] != 4)
|
||||
Log::error("ClientLobbyRoomProtocol",
|
||||
"Bad format in players list.");
|
||||
|
||||
uint8_t race_player_id = data[n + 1];
|
||||
uint32_t global_id = data.gui32(n + 3);
|
||||
irr::core::stringw name;
|
||||
int bytes_read = data.decodeStringW(n + 7, &name);
|
||||
// FIXME - leak?
|
||||
Online::OnlineProfile* new_user =
|
||||
new Online::OnlineProfile(global_id, name);
|
||||
|
||||
NetworkPlayerProfile* profile2 =
|
||||
new NetworkPlayerProfile(race_player_id, name);
|
||||
profile2->setPlayerID(race_player_id);
|
||||
profile2->setOnlineProfile(new_user);
|
||||
m_setup->addPlayer(profile2);
|
||||
n += bytes_read+7;
|
||||
}
|
||||
|
||||
// add self
|
||||
m_server = event->getPeer();
|
||||
m_state = CONNECTED;
|
||||
} // connectionAccepted
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -412,16 +412,16 @@ void ServerLobbyRoomProtocol::kartDisconnected(Event* event)
|
||||
*
|
||||
* Format of the data :
|
||||
* Byte 0 1 5
|
||||
* ------------------------
|
||||
* Size | 1 | 4 |
|
||||
* Data | 4 | global player id |
|
||||
* ------------------------
|
||||
* ----------------------------------------
|
||||
* Size | 1 | 4 |1| |
|
||||
* Data | 4 | global player id |n| player name |
|
||||
* ----------------------------------------
|
||||
*/
|
||||
void ServerLobbyRoomProtocol::connectionRequested(Event* event)
|
||||
{
|
||||
STKPeer* peer = event->getPeer();
|
||||
const NetworkString &data = event->data();
|
||||
if (data.size() != 5 || data[0] != 4)
|
||||
if (data[0] != 4)
|
||||
{
|
||||
Log::warn("ServerLobbyRoomProtocol",
|
||||
"Receiving badly formated message. Size is %d and first byte %d",
|
||||
@ -431,68 +431,75 @@ void ServerLobbyRoomProtocol::connectionRequested(Event* event)
|
||||
uint32_t player_id = 0;
|
||||
player_id = data.getUInt32(1);
|
||||
// can we add the player ?
|
||||
if (m_setup->getPlayerCount() < NetworkConfig::get()->getMaxPlayers() &&
|
||||
m_state==ACCEPTING_CLIENTS )
|
||||
{
|
||||
// add the player to the game setup
|
||||
m_next_id = m_setup->getPlayerCount();
|
||||
// notify everybody that there is a new player
|
||||
NetworkString message(8);
|
||||
// size of id -- id -- size of local id -- local id;
|
||||
message.ai8(LE_NEW_PLAYER_CONNECTED).ai8(4).ai32(player_id)
|
||||
.ai8(1).ai8(m_next_id);
|
||||
ProtocolManager::getInstance()->sendMessageExcept(this, peer, message);
|
||||
|
||||
/// now answer to the peer that just connected
|
||||
RandomGenerator token_generator;
|
||||
// use 4 random numbers because rand_max is probably 2^15-1.
|
||||
uint32_t token = (uint32_t)(((token_generator.get(RAND_MAX)<<24) & 0xff) +
|
||||
((token_generator.get(RAND_MAX)<<16) & 0xff) +
|
||||
((token_generator.get(RAND_MAX)<<8) & 0xff) +
|
||||
((token_generator.get(RAND_MAX) & 0xff)));
|
||||
|
||||
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(13+players.size()*7);
|
||||
// connection success (129) -- size of token -- token
|
||||
message_ack.ai8(LE_CONNECTION_ACCEPTED).ai8(1).ai8(m_next_id).ai8(4)
|
||||
.ai32(token).ai8(4).ai32(player_id);
|
||||
// add all players so that this user knows
|
||||
for (unsigned int i = 0; i < players.size(); i++)
|
||||
{
|
||||
// do not duplicate the player into the message
|
||||
if (players[i]->getPlayerID() != m_next_id &&
|
||||
players[i]->getGlobalID() != player_id)
|
||||
{
|
||||
message_ack.ai8(1).ai8(players[i]->getPlayerID()).ai8(4)
|
||||
.ai32(players[i]->getGlobalID());
|
||||
}
|
||||
}
|
||||
sendMessage(peer, message_ack);
|
||||
|
||||
peer->setClientServerToken(token);
|
||||
|
||||
NetworkPlayerProfile* profile = new NetworkPlayerProfile(m_next_id);
|
||||
// FIXME: memory leak OnlineProfile
|
||||
profile->setOnlineProfile(new Online::OnlineProfile(player_id, ""));
|
||||
m_setup->addPlayer(profile);
|
||||
peer->setPlayerProfile(profile);
|
||||
Log::verbose("ServerLobbyRoomProtocol", "New player.");
|
||||
} // accept player
|
||||
else // refuse the connection with code 0 (too much players)
|
||||
if (m_setup->getPlayerCount() >= NetworkConfig::get()->getMaxPlayers() ||
|
||||
m_state!=ACCEPTING_CLIENTS )
|
||||
{
|
||||
NetworkString message(3);
|
||||
message.ai8(LE_CONNECTION_REFUSED);
|
||||
message.ai8(1); // 1 bytes for the error code
|
||||
if(m_state!=ACCEPTING_CLIENTS)
|
||||
message.ai8(2); // 2 = Busy
|
||||
else
|
||||
message.ai8(0); // 0 = too many players
|
||||
// Len, error code: 2 = busy, 0 = too many players
|
||||
message.ai8(LE_CONNECTION_REFUSED).ai8(1)
|
||||
.ai8(m_state!=ACCEPTING_CLIENTS ? 2 : 0);
|
||||
|
||||
// send only to the peer that made the request
|
||||
sendMessage(peer, message);
|
||||
Log::verbose("ServerLobbyRoomProtocol", "Player refused");
|
||||
return;
|
||||
}
|
||||
|
||||
// Connection accepted.
|
||||
// ====================
|
||||
std::string name_u8;
|
||||
int name_len = data.decodeString(5, &name_u8);
|
||||
core::stringw name = StringUtils::utf8ToWide(name_u8);
|
||||
|
||||
// add the player to the game setup
|
||||
m_next_id = m_setup->getPlayerCount();
|
||||
|
||||
NetworkPlayerProfile* profile = new NetworkPlayerProfile(m_next_id, name);
|
||||
// FIXME: memory leak OnlineProfile
|
||||
profile->setOnlineProfile(new Online::OnlineProfile(player_id, ""));
|
||||
m_setup->addPlayer(profile);
|
||||
peer->setPlayerProfile(profile);
|
||||
|
||||
// notify everybody that there is a new player
|
||||
NetworkString message(8);
|
||||
// size of id -- id -- size of local id -- local id;
|
||||
message.ai8(LE_NEW_PLAYER_CONNECTED).ai8(4).ai32(player_id)
|
||||
.ai8(1).ai8(m_next_id).encodeString(name_u8);
|
||||
ProtocolManager::getInstance()->sendMessageExcept(this, peer, message);
|
||||
|
||||
// Now answer to the peer that just connected
|
||||
RandomGenerator token_generator;
|
||||
// use 4 random numbers because rand_max is probably 2^15-1.
|
||||
uint32_t token = (uint32_t)(((token_generator.get(RAND_MAX) << 24) & 0xff) +
|
||||
((token_generator.get(RAND_MAX) << 16) & 0xff) +
|
||||
((token_generator.get(RAND_MAX) << 8) & 0xff) +
|
||||
((token_generator.get(RAND_MAX) & 0xff)));
|
||||
|
||||
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(13 + players.size() * 7);
|
||||
// connection success (129) -- size of token -- token
|
||||
message_ack.ai8(LE_CONNECTION_ACCEPTED).ai8(1).ai8(m_next_id).ai8(4)
|
||||
.ai32(token).ai8(4).ai32(player_id);
|
||||
// add all players so that this user knows
|
||||
for (unsigned int i = 0; i < players.size(); i++)
|
||||
{
|
||||
// do not duplicate the player into the message
|
||||
if (players[i]->getPlayerID() != m_next_id &&
|
||||
players[i]->getGlobalID() != player_id)
|
||||
{
|
||||
message_ack.ai8(1).ai8(players[i]->getPlayerID()).ai8(4)
|
||||
.ai32(players[i]->getGlobalID())
|
||||
.encodeString(players[i]->getName());
|
||||
}
|
||||
}
|
||||
sendMessage(peer, message_ack);
|
||||
|
||||
peer->setClientServerToken(token);
|
||||
|
||||
Log::verbose("ServerLobbyRoomProtocol", "New player.");
|
||||
|
||||
} // connectionRequested
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user