Finally: User supplied avatars are transfered! They are stored on the server and clients request them if needed. Make sure the server has write access to the cache dir to make it work.
This commit is contained in:
@@ -76,6 +76,7 @@ protected:
|
||||
typedef std::map<unsigned, GameInfo> GameInfoMap;
|
||||
typedef std::list<boost::shared_ptr<NetPacket> > NetPacketList;
|
||||
typedef std::map<unsigned, PlayerInfo> PlayerInfoMap;
|
||||
typedef std::map<unsigned, boost::shared_ptr<AvatarData> > AvatarDataMap;
|
||||
|
||||
// Main function of the thread.
|
||||
virtual void Main();
|
||||
@@ -88,6 +89,10 @@ protected:
|
||||
void SetPlayerInfo(unsigned id, const PlayerInfo &info);
|
||||
void SetNewGameAdmin(unsigned id);
|
||||
|
||||
void AddTempAvatarData(unsigned playerId, unsigned avatarSize, AvatarFileType type);
|
||||
void StoreInTempAvatarData(unsigned playerId, const std::vector<unsigned char> &data);
|
||||
void CompleteTempAvatarData(unsigned playerId);
|
||||
|
||||
const ClientContext &GetContext() const;
|
||||
ClientContext &GetContext();
|
||||
|
||||
@@ -156,6 +161,8 @@ private:
|
||||
mutable boost::mutex m_playerInfoMapMutex;
|
||||
PlayerIdList m_playerInfoRequestList;
|
||||
|
||||
AvatarDataMap m_tempAvatarMap;
|
||||
|
||||
unsigned m_curGameId;
|
||||
unsigned m_guiPlayerId;
|
||||
bool m_sessionEstablished;
|
||||
|
||||
@@ -352,6 +352,7 @@ ClientStateStartSession::Process(ClientThread &client)
|
||||
initData.password = context.GetPassword();
|
||||
initData.playerName = context.GetPlayerName();
|
||||
string avatarFile = context.GetAvatarFile();
|
||||
initData.showAvatar = false;
|
||||
if (!avatarFile.empty())
|
||||
{
|
||||
if (client.GetAvatarManager().GetHashForAvatar(avatarFile, initData.avatar))
|
||||
@@ -394,6 +395,16 @@ AbstractClientStateReceiving::Process(ClientThread &client)
|
||||
NetPacketPlayerInfo::Data infoData;
|
||||
tmpPacket->ToNetPacketPlayerInfo()->GetData(infoData);
|
||||
client.SetPlayerInfo(infoData.playerId, infoData.playerInfo);
|
||||
// Retrieve avatar if needed.
|
||||
if (infoData.playerInfo.hasAvatar && !client.GetAvatarManager().HasAvatar(infoData.playerInfo.avatar))
|
||||
{
|
||||
boost::shared_ptr<NetPacket> retrieveAvatar(new NetPacketRetrieveAvatar);
|
||||
NetPacketRetrieveAvatar::Data retrieveAvatarData;
|
||||
retrieveAvatarData.requestId = infoData.playerId;
|
||||
retrieveAvatarData.avatar = infoData.playerInfo.avatar;
|
||||
static_cast<NetPacketRetrieveAvatar *>(retrieveAvatar.get())->SetData(retrieveAvatarData);
|
||||
client.GetSender().Send(client.GetContext().GetSocket(), retrieveAvatar);
|
||||
}
|
||||
}
|
||||
else if (tmpPacket->ToNetPacketRemovedFromGame())
|
||||
{
|
||||
@@ -481,6 +492,24 @@ AbstractClientStateReceiving::Process(ClientThread &client)
|
||||
tmpPacket->ToNetPacketGameListPlayerLeft()->GetData(playerLeftData);
|
||||
client.ModifyGameInfoRemovePlayer(playerLeftData.gameId, playerLeftData.playerId);
|
||||
}
|
||||
else if (tmpPacket->ToNetPacketAvatarHeader())
|
||||
{
|
||||
NetPacketAvatarHeader::Data headerData;
|
||||
tmpPacket->ToNetPacketAvatarHeader()->GetData(headerData);
|
||||
client.AddTempAvatarData(headerData.requestId, headerData.avatarFileSize, headerData.avatarFileType);
|
||||
}
|
||||
else if (tmpPacket->ToNetPacketAvatarFile())
|
||||
{
|
||||
NetPacketAvatarFile::Data fileData;
|
||||
tmpPacket->ToNetPacketAvatarFile()->GetData(fileData);
|
||||
client.StoreInTempAvatarData(fileData.requestId, fileData.fileData);
|
||||
}
|
||||
else if (tmpPacket->ToNetPacketAvatarEnd())
|
||||
{
|
||||
NetPacketAvatarEnd::Data endData;
|
||||
tmpPacket->ToNetPacketAvatarEnd()->GetData(endData);
|
||||
client.CompleteTempAvatarData(endData.requestId);
|
||||
}
|
||||
else if (tmpPacket->ToNetPacketError())
|
||||
{
|
||||
// Server reported an error.
|
||||
@@ -543,6 +572,7 @@ ClientStateWaitSession::InternalProcess(ClientThread &client, boost::shared_ptr<
|
||||
{
|
||||
client.GetSender().SendLowPrio(client.GetContext().GetSocket(), tmpList);
|
||||
}
|
||||
// TODO handle error
|
||||
}
|
||||
|
||||
return retVal;
|
||||
|
||||
@@ -387,6 +387,7 @@ ClientThread::SetPlayerInfo(unsigned id, const PlayerInfo &info)
|
||||
boost::mutex::scoped_lock lock(m_playerInfoMapMutex);
|
||||
m_playerInfoMap[id] = info;
|
||||
}
|
||||
|
||||
// Update player data for current game.
|
||||
boost::shared_ptr<PlayerData> playerData = GetPlayerDataByUniqueId(id);
|
||||
if (playerData.get())
|
||||
@@ -397,11 +398,15 @@ ClientThread::SetPlayerInfo(unsigned id, const PlayerInfo &info)
|
||||
{
|
||||
string avatarFile;
|
||||
if (GetAvatarManager().GetAvatarFileName(info.avatar, avatarFile))
|
||||
{
|
||||
playerData->SetAvatarFile(avatarFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Notify GUI
|
||||
GetCallback().SignalNetClientPlayerChanged(id, info.playerName);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@@ -416,6 +421,52 @@ ClientThread::SetNewGameAdmin(unsigned id)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClientThread::AddTempAvatarData(unsigned playerId, unsigned avatarSize, AvatarFileType type)
|
||||
{
|
||||
boost::shared_ptr<AvatarData> tmpAvatar(new AvatarData);
|
||||
tmpAvatar->fileData.reserve(avatarSize);
|
||||
tmpAvatar->fileType = type;
|
||||
tmpAvatar->reportedSize = avatarSize;
|
||||
|
||||
m_tempAvatarMap[playerId] = tmpAvatar;
|
||||
}
|
||||
|
||||
void
|
||||
ClientThread::StoreInTempAvatarData(unsigned playerId, const vector<unsigned char> &data)
|
||||
{
|
||||
AvatarDataMap::iterator pos = m_tempAvatarMap.find(playerId);
|
||||
if (pos == m_tempAvatarMap.end())
|
||||
throw NetException(ERR_NET_INVALID_REQUEST_ID, 0);
|
||||
// We trust the server (concerning size of the data).
|
||||
std::copy(data.begin(), data.end(), back_inserter(pos->second->fileData));
|
||||
}
|
||||
|
||||
void
|
||||
ClientThread::CompleteTempAvatarData(unsigned playerId)
|
||||
{
|
||||
AvatarDataMap::iterator pos = m_tempAvatarMap.find(playerId);
|
||||
if (pos == m_tempAvatarMap.end())
|
||||
throw NetException(ERR_NET_INVALID_REQUEST_ID, 0);
|
||||
|
||||
boost::shared_ptr<AvatarData> tmpAvatar = pos->second;
|
||||
unsigned avatarSize = (unsigned)tmpAvatar->fileData.size();
|
||||
if (avatarSize != tmpAvatar->reportedSize)
|
||||
throw NetException(ERR_NET_WRONG_AVATAR_SIZE, 0);
|
||||
|
||||
PlayerInfo tmpPlayerInfo;
|
||||
if (!GetCachedPlayerInfo(playerId, tmpPlayerInfo))
|
||||
throw NetException(ERR_NET_UNKNOWN_PLAYER_ID, 0);
|
||||
|
||||
GetAvatarManager().StoreAvatarInCache(tmpPlayerInfo.avatar, tmpAvatar->fileType, &tmpAvatar->fileData[0], avatarSize);
|
||||
// TODO log error
|
||||
// Free memory.
|
||||
m_tempAvatarMap.erase(pos);
|
||||
|
||||
// Update player info, but never re-request avatar.
|
||||
SetPlayerInfo(playerId, tmpPlayerInfo);
|
||||
}
|
||||
|
||||
const ClientContext &
|
||||
ClientThread::GetContext() const
|
||||
{
|
||||
|
||||
@@ -156,6 +156,11 @@ AbstractServerGameStateReceiving::Process(ServerGameThread &server)
|
||||
// Delegate to Lobby.
|
||||
server.GetLobbyThread().HandleGameRetrievePlayerInfo(session, *packet->ToNetPacketRetrievePlayerInfo());
|
||||
}
|
||||
else if (packet->ToNetPacketRetrieveAvatar())
|
||||
{
|
||||
// Delegate to Lobby.
|
||||
server.GetLobbyThread().HandleGameRetrieveAvatar(session, *packet->ToNetPacketRetrieveAvatar());
|
||||
}
|
||||
else if (packet->ToNetPacketLeaveCurrentGame())
|
||||
{
|
||||
server.MoveSessionToLobby(session, NTF_NET_REMOVED_ON_REQUEST);
|
||||
|
||||
@@ -169,6 +169,13 @@ ServerLobbyThread::HandleGameRetrievePlayerInfo(SessionWrapper session, const Ne
|
||||
HandleNetPacketRetrievePlayerInfo(session, tmpPacket);
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::HandleGameRetrieveAvatar(SessionWrapper session, const NetPacketRetrieveAvatar &tmpPacket)
|
||||
{
|
||||
// Someone within a game requested an avatar.
|
||||
HandleNetPacketRetrieveAvatar(session, tmpPacket);
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::RemoveGame(unsigned id)
|
||||
{
|
||||
@@ -295,6 +302,8 @@ ServerLobbyThread::ProcessLoop()
|
||||
{
|
||||
if (packet->ToNetPacketRetrievePlayerInfo())
|
||||
HandleNetPacketRetrievePlayerInfo(session, *packet->ToNetPacketRetrievePlayerInfo());
|
||||
else if (packet->ToNetPacketRetrieveAvatar())
|
||||
HandleNetPacketRetrieveAvatar(session, *packet->ToNetPacketRetrieveAvatar());
|
||||
else if (packet->ToNetPacketCreateGame())
|
||||
HandleNetPacketCreateGame(session, *packet->ToNetPacketCreateGame());
|
||||
else if (packet->ToNetPacketJoinGame())
|
||||
@@ -356,7 +365,7 @@ ServerLobbyThread::HandleNetPacketInit(SessionWrapper session, const NetPacketIn
|
||||
m_sessionManager.SetSessionPlayerData(session.sessionData->GetSocket(), tmpPlayerData);
|
||||
session.playerData = tmpPlayerData;
|
||||
|
||||
if (!GetAvatarManager().HasAvatar(initData.avatar))
|
||||
if (initData.showAvatar && !GetAvatarManager().HasAvatar(initData.avatar))
|
||||
RequestPlayerAvatar(session);
|
||||
else
|
||||
EstablishSession(session);
|
||||
@@ -416,6 +425,7 @@ ServerLobbyThread::HandleNetPacketAvatarEnd(SessionWrapper session, const NetPac
|
||||
if (avatarSize == tmpAvatar->reportedSize)
|
||||
{
|
||||
GetAvatarManager().StoreAvatarInCache(avatarMD5, tmpAvatar->fileType, &tmpAvatar->fileData[0], avatarSize);
|
||||
// TODO log error
|
||||
// Free memory.
|
||||
session.playerData->SetNetAvatarData(boost::shared_ptr<AvatarData>());
|
||||
// Init finished - start session.
|
||||
@@ -454,6 +464,21 @@ ServerLobbyThread::HandleNetPacketRetrievePlayerInfo(SessionWrapper session, con
|
||||
// TODO: handle error
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::HandleNetPacketRetrieveAvatar(SessionWrapper session, const NetPacketRetrieveAvatar &tmpPacket)
|
||||
{
|
||||
NetPacketRetrieveAvatar::Data request;
|
||||
tmpPacket.GetData(request);
|
||||
|
||||
string tmpFile;
|
||||
if (GetAvatarManager().GetAvatarFileName(request.avatar, tmpFile))
|
||||
{
|
||||
NetPacketList tmpPackets;
|
||||
if (GetAvatarManager().AvatarFileToNetPackets(tmpFile, request.requestId, tmpPackets))
|
||||
GetSender().SendLowPrio(session.sessionData->GetSocket(), tmpPackets);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::HandleNetPacketCreateGame(SessionWrapper session, const NetPacketCreateGame &tmpPacket)
|
||||
{
|
||||
|
||||
@@ -61,6 +61,7 @@ public:
|
||||
void NotifyStartingGame(unsigned gameId);
|
||||
|
||||
void HandleGameRetrievePlayerInfo(SessionWrapper session, const NetPacketRetrievePlayerInfo &tmpPacket);
|
||||
void HandleGameRetrieveAvatar(SessionWrapper session, const NetPacketRetrieveAvatar &tmpPacket);
|
||||
|
||||
void RemoveGame(unsigned id);
|
||||
|
||||
@@ -88,6 +89,7 @@ protected:
|
||||
void HandleNetPacketAvatarFile(SessionWrapper session, const NetPacketAvatarFile &tmpPacket);
|
||||
void HandleNetPacketAvatarEnd(SessionWrapper session, const NetPacketAvatarEnd &tmpPacket);
|
||||
void HandleNetPacketRetrievePlayerInfo(SessionWrapper session, const NetPacketRetrievePlayerInfo &tmpPacket);
|
||||
void HandleNetPacketRetrieveAvatar(SessionWrapper session, const NetPacketRetrieveAvatar &tmpPacket);
|
||||
void HandleNetPacketCreateGame(SessionWrapper session, const NetPacketCreateGame &tmpPacket);
|
||||
void HandleNetPacketJoinGame(SessionWrapper session, const NetPacketJoinGame &tmpPacket);
|
||||
void EstablishSession(SessionWrapper session);
|
||||
|
||||
@@ -59,6 +59,8 @@
|
||||
#define ERR_NET_INVALID_PLAYER_COUNT 115
|
||||
#define ERR_NET_TOO_MANY_MANUAL_BLINDS 116
|
||||
#define ERR_NET_BUF_INVALID_SIZE 117
|
||||
#define ERR_NET_INVALID_REQUEST_ID 118
|
||||
#define ERR_NET_WRONG_AVATAR_SIZE 119
|
||||
|
||||
#define ERR_IRC_INTERNAL 151
|
||||
#define ERR_IRC_CONNECT_FAILED 152
|
||||
|
||||
Reference in New Issue
Block a user