Show avatars in network games. User defined avatars are not transfered yet, but this is already prepared for integration.

This commit is contained in:
lotodore
2007-09-09 00:00:19 +00:00
parent b71ae4ac17
commit e8eddd3b1b
10 changed files with 129 additions and 22 deletions
+5
View File
@@ -63,6 +63,10 @@ public:
{return m_playerName;}
void SetPlayerName(const std::string &playerName)
{m_playerName = playerName;}
const std::string &GetAvatarFile() const
{return m_avatarFile;}
void SetAvatarFile(const std::string &avatarFile)
{m_avatarFile = avatarFile;}
int GetClientSockaddrSize() const
{return m_addrFamily == AF_INET6 ? sizeof(sockaddr_in6) : sizeof(sockaddr_in);}
@@ -79,6 +83,7 @@ private:
std::string m_password;
sockaddr_storage m_clientSockaddr;
std::string m_playerName;
std::string m_avatarFile;
ReceiveBuffer m_receiveBuffer;
};
+6 -2
View File
@@ -36,11 +36,12 @@ class ReceiverHelper;
class ClientSenderCallback;
class Game;
class NetPacket;
class AvatarManager;
class ClientThread : public Thread
{
public:
ClientThread(GuiInterface &gui);
ClientThread(GuiInterface &gui, AvatarManager &avatarManager);
virtual ~ClientThread();
// Set the parameters. Does not do any error checking.
@@ -52,7 +53,8 @@ public:
bool ipv6,
bool sctp,
const std::string &pwd,
const std::string &playerName);
const std::string &playerName,
const std::string &avatarFile);
void SendKickPlayer(unsigned playerId);
void SendLeaveCurrentGame();
@@ -68,6 +70,7 @@ public:
ClientCallback &GetCallback();
GuiInterface &GetGui();
AvatarManager &GetAvatarManager();
protected:
typedef std::map<unsigned, GameInfo> GameInfoMap;
@@ -133,6 +136,7 @@ private:
std::auto_ptr<ClientSenderCallback> m_senderCallback;
ClientState *m_curState;
GuiInterface &m_gui;
AvatarManager &m_avatarManager;
std::auto_ptr<SenderThread> m_sender;
std::auto_ptr<ReceiverHelper> m_receiver;
+14
View File
@@ -27,6 +27,7 @@
#include <net/clientexception.h>
#include <net/socket_helper.h>
#include <net/socket_msg.h>
#include <core/avatarmanager.h>
#include <game.h>
#include <playerinterface.h>
@@ -349,6 +350,12 @@ ClientStateStartSession::Process(ClientThread &client)
NetPacketInit::Data initData;
initData.password = context.GetPassword();
initData.playerName = context.GetPlayerName();
string avatarFile = context.GetAvatarFile();
if (!avatarFile.empty())
{
if (client.GetAvatarManager().GetHashForAvatar(avatarFile, initData.avatar))
initData.showAvatar = true;
}
boost::shared_ptr<NetPacket> packet(new NetPacketInit);
((NetPacketInit *)packet.get())->SetData(initData);
@@ -549,6 +556,7 @@ ClientStateWaitJoin::InternalProcess(ClientThread &client, boost::shared_ptr<Net
boost::shared_ptr<PlayerData> playerData(
new PlayerData(client.GetGuiPlayerId(), 0, PLAYER_TYPE_HUMAN, joinGameAckData.prights));
playerData->SetName(context.GetPlayerName());
playerData->SetAvatarFile(context.GetAvatarFile());
client.AddPlayerData(playerData);
client.SetState(ClientStateWaitGame::Instance());
@@ -628,6 +636,12 @@ ClientStateWaitGame::InternalProcess(ClientThread &client, boost::shared_ptr<Net
playerData.reset(
new PlayerData(netPlayerData.playerId, 0, info.ptype, netPlayerData.prights));
playerData->SetName(info.playerName);
if (info.hasAvatar)
{
string avatarFile;
if (client.GetAvatarManager().GetAvatarFileName(info.avatar, avatarFile))
playerData->SetAvatarFile(avatarFile);
}
}
else
{
+19 -3
View File
@@ -24,6 +24,7 @@
#include <net/receiverhelper.h>
#include <net/clientexception.h>
#include <net/socket_msg.h>
#include <core/avatarmanager.h>
#include <clientenginefactory.h>
#include <game.h>
@@ -53,8 +54,9 @@ private:
};
ClientThread::ClientThread(GuiInterface &gui)
: m_curState(NULL), m_gui(gui), m_curGameId(1), m_guiPlayerId(0), m_sessionEstablished(false)
ClientThread::ClientThread(GuiInterface &gui, AvatarManager &avatarManager)
: m_curState(NULL), m_gui(gui), m_avatarManager(avatarManager),
m_curGameId(1), m_guiPlayerId(0), m_sessionEstablished(false)
{
m_context.reset(new ClientContext);
m_senderCallback.reset(new ClientSenderCallback(*this));
@@ -68,7 +70,8 @@ ClientThread::~ClientThread()
void
ClientThread::Init(
const string &serverAddress, unsigned serverPort, bool ipv6, bool sctp, const string &pwd, const string &playerName)
const string &serverAddress, unsigned serverPort, bool ipv6, bool sctp,
const string &pwd, const string &playerName, const string &avatarFile)
{
if (IsRunning())
{
@@ -84,6 +87,7 @@ ClientThread::Init(
context.SetServerPort(serverPort);
context.SetPassword(pwd);
context.SetPlayerName(playerName);
context.SetAvatarFile(avatarFile);
}
void
@@ -267,6 +271,12 @@ ClientThread::GetGui()
return m_gui;
}
AvatarManager &
ClientThread::GetAvatarManager()
{
return m_avatarManager;
}
void
ClientThread::Main()
{
@@ -382,6 +392,12 @@ ClientThread::SetPlayerInfo(unsigned id, const PlayerInfo &info)
{
playerData->SetName(info.playerName);
playerData->SetType(info.ptype);
if (info.hasAvatar)
{
string avatarFile;
if (GetAvatarManager().GetAvatarFileName(info.avatar, avatarFile))
playerData->SetAvatarFile(avatarFile);
}
}
GetCallback().SignalNetClientPlayerChanged(id, info.playerName);
+61 -11
View File
@@ -68,10 +68,12 @@ using namespace std;
#define NET_GAME_FLAG_PASSWORD_PROTECTED 0x01
#define NET_PLAYER_FLAG_HUMAN 0x01
#define NET_PLAYER_FLAG_ADMIN 0x02
#define NET_PLAYER_FLAG_HAS_AVATAR 0x02
#define NET_START_FLAG_FILL_WITH_CPU_PLAYERS 0x01
#define NET_PRIVACY_FLAG_SHOW_AVATAR 0x01
// Reasons why join game failed.
#define NET_JOIN_FAILED_GAME_FULL 0x0001
#define NET_JOIN_FAILED_GAME_ALREADY_RUNNING 0x0002
@@ -118,7 +120,8 @@ struct GCC_PACKED NetPacketInitData
u_int16_t requestedVersionMinor;
u_int16_t passwordLength;
u_int16_t playerNameLength;
u_int32_t reserved;
u_int16_t privacyFlags;
u_int16_t reserved;
};
struct GCC_PACKED NetPacketInitAckData
@@ -926,16 +929,29 @@ NetPacketInit::SetData(const NetPacketInit::Data &inData)
if (passwordLen > MAX_PASSWORD_SIZE)
throw NetException(ERR_NET_INVALID_PASSWORD_STR, 0);
int avatarSize = inData.showAvatar ? MD5_DATA_SIZE : 0;
// Resize the packet so that the data fits in.
Resize((u_int16_t)
(sizeof(NetPacketInitData) + ADD_PADDING(playerNameLen) + ADD_PADDING(passwordLen)));
(sizeof(NetPacketInitData)
+ avatarSize
+ ADD_PADDING(playerNameLen)
+ ADD_PADDING(passwordLen)));
NetPacketInitData *tmpData = (NetPacketInitData *)GetRawData();
// Set the data.
tmpData->passwordLength = htons(passwordLen);
tmpData->playerNameLength = htons(playerNameLen);
char *passwordPtr = (char *)tmpData + sizeof(NetPacketInitData);
if (inData.showAvatar)
{
// Store MD5 sum of avatar.
tmpData->privacyFlags = htons(NET_PRIVACY_FLAG_SHOW_AVATAR);
char *avatarPtr = (char *)tmpData + sizeof(NetPacketInitData);
memcpy(avatarPtr, inData.avatar.data, MD5_DATA_SIZE);
}
char *passwordPtr = (char *)tmpData + sizeof(NetPacketInitData) + avatarSize;
memcpy(passwordPtr, inData.password.c_str(), passwordLen);
memcpy(passwordPtr + ADD_PADDING(passwordLen), inData.playerName.c_str(), playerNameLen);
@@ -952,8 +968,17 @@ NetPacketInit::GetData(NetPacketInit::Data &outData) const
outData.versionMajor = ntohs(tmpData->requestedVersionMajor);
outData.versionMinor = ntohs(tmpData->requestedVersionMinor);
outData.showAvatar = ntohs(tmpData->privacyFlags) & NET_PRIVACY_FLAG_SHOW_AVATAR;
if (outData.showAvatar)
{
char *avatarPtr = (char *)tmpData + sizeof(NetPacketInitData);
memcpy(outData.avatar.data, avatarPtr, MD5_DATA_SIZE);
}
int avatarSize = outData.showAvatar ? MD5_DATA_SIZE : 0;
u_int16_t passwordLen = ntohs(tmpData->passwordLength);
char *passwordPtr = (char *)tmpData + sizeof(NetPacketInitData);
char *passwordPtr = (char *)tmpData + sizeof(NetPacketInitData) + avatarSize;
outData.password = string(passwordPtr, passwordLen);
outData.playerName = string(passwordPtr + ADD_PADDING(passwordLen), ntohs(tmpData->playerNameLength));
}
@@ -971,12 +996,14 @@ NetPacketInit::InternalCheck(const NetPacketHeader* data) const
NetPacketInitData *tmpData = (NetPacketInitData *)data;
int passwordLength = ntohs(tmpData->passwordLength);
int playerNameLength = ntohs(tmpData->playerNameLength);
int avatarSize = ntohs(tmpData->privacyFlags) & NET_PRIVACY_FLAG_SHOW_AVATAR ? MD5_DATA_SIZE : 0;
// Generous checking of dynamic packet size -
// larger packets are allowed.
// This is because the version number is in this packet,
// and later versions might provide larger packets.
if (dataLen <
sizeof(NetPacketInitData)
+ avatarSize
+ ADD_PADDING(passwordLength)
+ ADD_PADDING(playerNameLength))
{
@@ -990,7 +1017,7 @@ NetPacketInit::InternalCheck(const NetPacketHeader* data) const
throw NetException(ERR_SOCK_INVALID_PACKET, 0);
}
// Check name string.
char *namePtr = (char *)tmpData + sizeof(NetPacketInitData) + ADD_PADDING(passwordLength);
char *namePtr = (char *)tmpData + sizeof(NetPacketInitData) + avatarSize + ADD_PADDING(passwordLength);
if (namePtr[0] == 0)
{
throw NetException(ERR_SOCK_INVALID_PACKET, 0);
@@ -1470,17 +1497,27 @@ NetPacketPlayerInfo::SetData(const NetPacketPlayerInfo::Data &inData)
if (!playerNameLen || playerNameLen > MAX_NAME_SIZE)
throw NetException(ERR_NET_INVALID_PLAYER_NAME, 0);
int avatarSize = inData.playerInfo.hasAvatar ? MD5_DATA_SIZE : 0;
// Resize the packet so that the data fits in.
Resize((u_int16_t)
(sizeof(NetPacketPlayerInfoData) + ADD_PADDING(playerNameLen)));
(sizeof(NetPacketPlayerInfoData) + avatarSize + ADD_PADDING(playerNameLen)));
NetPacketPlayerInfoData *tmpData = (NetPacketPlayerInfoData *)GetRawData();
// Set the data.
tmpData->playerId = htonl(inData.playerId);
tmpData->playerFlags = htons(inData.playerInfo.ptype);
tmpData->playerNameLength = htons(playerNameLen);
char *namePtr = (char *)tmpData + sizeof(NetPacketPlayerInfoData);
u_int16_t tmpPlayerFlags = inData.playerInfo.ptype == PLAYER_TYPE_HUMAN ? NET_PLAYER_FLAG_HUMAN : 0;
if (inData.playerInfo.hasAvatar)
{
tmpPlayerFlags |= NET_PLAYER_FLAG_HAS_AVATAR;
char *avatarPtr = (char *)tmpData + sizeof(NetPacketPlayerInfoData);
memcpy(avatarPtr, inData.playerInfo.avatar.data, MD5_DATA_SIZE);
}
tmpData->playerFlags = htons(tmpPlayerFlags);
char *namePtr = (char *)tmpData + sizeof(NetPacketPlayerInfoData) + avatarSize;
memcpy(namePtr, inData.playerInfo.playerName.c_str(), playerNameLen);
// Check the packet - just in case.
@@ -1494,8 +1531,19 @@ NetPacketPlayerInfo::GetData(NetPacketPlayerInfo::Data &outData) const
NetPacketPlayerInfoData *tmpData = (NetPacketPlayerInfoData *)GetRawData();
outData.playerId = ntohl(tmpData->playerId);
outData.playerInfo.ptype = static_cast<PlayerType>(ntohs(tmpData->playerFlags));
char *namePtr = (char *)tmpData + sizeof(NetPacketPlayerInfoData);
u_int16_t tmpPlayerFlags = ntohs(tmpData->playerFlags);
outData.playerInfo.ptype = (tmpPlayerFlags & NET_PLAYER_FLAG_HUMAN) ? PLAYER_TYPE_HUMAN : PLAYER_TYPE_COMPUTER;
outData.playerInfo.hasAvatar = (tmpPlayerFlags & NET_PLAYER_FLAG_HAS_AVATAR) ? true : false;
if (outData.playerInfo.hasAvatar)
{
char *avatarPtr = (char *)tmpData + sizeof(NetPacketPlayerInfoData);
memcpy(outData.playerInfo.avatar.data, avatarPtr, MD5_DATA_SIZE);
}
int avatarSize = outData.playerInfo.hasAvatar ? MD5_DATA_SIZE : 0;
char *namePtr = (char *)tmpData + avatarSize + sizeof(NetPacketPlayerInfoData);
outData.playerInfo.playerName = string(namePtr, ntohs(tmpData->playerNameLength));
}
@@ -1511,9 +1559,11 @@ NetPacketPlayerInfo::InternalCheck(const NetPacketHeader* data) const
u_int16_t dataLen = ntohs(data->length);
NetPacketPlayerInfoData *tmpData = (NetPacketPlayerInfoData *)data;
int playerNameLength = ntohs(tmpData->playerNameLength);
int avatarSize = (ntohs(tmpData->playerFlags) & NET_PLAYER_FLAG_HAS_AVATAR) ? MD5_DATA_SIZE : 0;
// Exact checking this time.
if (dataLen !=
sizeof(NetPacketPlayerInfoData)
+ avatarSize
+ ADD_PADDING(playerNameLength))
{
throw NetException(ERR_SOCK_INVALID_PACKET, 0);
+4
View File
@@ -157,11 +157,15 @@ AbstractServerGameStateReceiving::Process(ServerGameThread &server)
if (tmpSession.sessionData.get() && tmpSession.playerData.get())
{
// Send player info to client.
// TODO this is a copy and paste
boost::shared_ptr<NetPacket> info(new NetPacketPlayerInfo);
NetPacketPlayerInfo::Data infoData;
infoData.playerId = tmpSession.playerData->GetUniqueId();
infoData.playerInfo.ptype = tmpSession.playerData->GetType();
infoData.playerInfo.playerName = tmpSession.playerData->GetName();
infoData.playerInfo.hasAvatar = !tmpSession.playerData->GetAvatarFile().empty();
if (infoData.playerInfo.hasAvatar)
infoData.playerInfo.avatar.FromString(tmpSession.playerData->GetAvatarFile());
static_cast<NetPacketPlayerInfo *>(info.get())->SetData(infoData);
server.GetSender().Send(session.sessionData->GetSocket(), info);
}
+5
View File
@@ -296,6 +296,8 @@ ServerLobbyThread::HandleNetPacketInit(SessionWrapper session, const NetPacketIn
new PlayerData(GetNextUniquePlayerId(), 0, PLAYER_TYPE_HUMAN, PLAYER_RIGHTS_NORMAL));
tmpPlayerData->SetName(initData.playerName);
tmpPlayerData->SetNetSessionData(session.sessionData);
if (initData.showAvatar)
tmpPlayerData->SetAvatarFile(initData.avatar.ToString());
// Send ACK to client.
boost::shared_ptr<NetPacket> initAck(new NetPacketInitAck);
@@ -344,6 +346,9 @@ ServerLobbyThread::HandleNetPacketRetrievePlayerInfo(SessionWrapper session, con
infoData.playerId = tmpPlayer->GetUniqueId();
infoData.playerInfo.ptype = tmpPlayer->GetType();
infoData.playerInfo.playerName = tmpPlayer->GetName();
infoData.playerInfo.hasAvatar = !tmpPlayer->GetAvatarFile().empty();
if (infoData.playerInfo.hasAvatar)
infoData.playerInfo.avatar.FromString(tmpPlayer->GetAvatarFile());
static_cast<NetPacketPlayerInfo *>(info.get())->SetData(infoData);
GetSender().Send(session.sessionData->GetSocket(), info);
}
+3
View File
@@ -25,6 +25,7 @@
#include <game_defs.h>
#include <gamedata.h>
#include <net/socket_helper.h>
#include <core/crypthelper.h>
#define NET_VERSION_MAJOR 2
#define NET_VERSION_MINOR 0
@@ -152,6 +153,8 @@ public:
int versionMinor;
std::string playerName;
std::string password;
bool showAvatar;
MD5Buf avatar;
};
NetPacketInit();