From 639df29bdcf4751df11ed515b3ef6bca8cce7808 Mon Sep 17 00:00:00 2001 From: lotodore Date: Sun, 7 Oct 2007 15:52:12 +0000 Subject: [PATCH] Server now requests unknown avatar files from client and stores them in the cache dir. Error handling is still missing. Clients not yet request avatar files from the server, this is the next step. AvatarManager is now thread safe. Default and cached avatars are handled in different lists to prevent deleting the default avatars when clearing the cache. --- src/core/avatarmanager.h | 15 ++- src/core/common/avatarmanager.cpp | 144 +++++++++++++++-------- src/core/common/crypthelper.cpp | 6 + src/core/crypthelper.h | 1 + src/net/common/netpacket.cpp | 5 +- src/net/common/serveracceptthread.cpp | 4 +- src/net/common/serverlobbythread.cpp | 159 +++++++++++++++++++++----- src/net/serveracceptthread.h | 3 +- src/net/serverlobbythread.h | 13 ++- src/net/sessiondata.h | 2 +- src/playerdata.cpp | 31 ++++- src/playerdata.h | 19 ++- src/pokerth_server.cpp | 6 +- src/session.cpp | 2 +- 14 files changed, 319 insertions(+), 91 deletions(-) diff --git a/src/core/avatarmanager.h b/src/core/avatarmanager.h index 1acd9e94..c8546d1e 100644 --- a/src/core/avatarmanager.h +++ b/src/core/avatarmanager.h @@ -26,6 +26,7 @@ #include #include +#include #include #define MAX_AVATAR_FILE_SIZE 30720 @@ -46,19 +47,25 @@ public: bool AvatarFileToNetPackets(const std::string &fileName, unsigned requestId, NetPacketList &packets); - bool GetHashForAvatar(const std::string &fileName, MD5Buf &md5buf); + bool GetHashForAvatar(const std::string &fileName, MD5Buf &md5buf) const; bool GetAvatarFileName(const MD5Buf &md5buf, std::string &fileName) const; + bool HasAvatar(const MD5Buf &md5buf) const; bool StoreAvatarInCache(const MD5Buf &md5buf, AvatarFileType avatarFileType, const unsigned char *data, unsigned size); protected: typedef std::map AvatarMap; - void InternalReadDirectory(const std::string &dir); + bool InternalReadDirectory(const std::string &dir, AvatarMap &avatars); private: - AvatarMap m_avatars; + mutable boost::mutex m_avatarsMutex; + AvatarMap m_avatars; - std::string m_cacheDir; + mutable boost::mutex m_cachedAvatarsMutex; + AvatarMap m_cachedAvatars; + + mutable boost::mutex m_cacheDirMutex; + std::string m_cacheDir; }; #endif diff --git a/src/core/common/avatarmanager.cpp b/src/core/common/avatarmanager.cpp index 02cd3648..de0fc816 100644 --- a/src/core/common/avatarmanager.cpp +++ b/src/core/common/avatarmanager.cpp @@ -20,6 +20,7 @@ #include "avatarmanager.h" #include +#include #include #include @@ -51,18 +52,20 @@ AvatarManager::~AvatarManager() bool AvatarManager::Init(const std::string &dataDir, const std::string &cacheDir) { - bool retVal = false; - try { - InternalReadDirectory(dataDir + "gfx/avatars/default/people/"); - InternalReadDirectory(dataDir + "gfx/avatars/default/misc/"); - InternalReadDirectory(cacheDir); + boost::mutex::scoped_lock lock(m_cacheDirMutex); m_cacheDir = cacheDir; - retVal = true; - } catch (...) - { } - return retVal; + { + boost::mutex::scoped_lock lock(m_avatarsMutex); + InternalReadDirectory(dataDir + "gfx/avatars/default/people/", m_avatars); + InternalReadDirectory(dataDir + "gfx/avatars/default/misc/", m_avatars); + } + { + boost::mutex::scoped_lock lock(m_cachedAvatarsMutex); + InternalReadDirectory(cacheDir, m_cachedAvatars); + } + return true; // TODO handle errors } boost::shared_ptr @@ -170,31 +173,50 @@ AvatarManager::AvatarFileToNetPackets(const string &fileName, unsigned requestId } bool -AvatarManager::GetHashForAvatar(const std::string &fileName, MD5Buf &md5buf) +AvatarManager::GetHashForAvatar(const std::string &fileName, MD5Buf &md5buf) const { bool found = false; - if (exists(fileName)) { - AvatarMap::const_iterator i = m_avatars.begin(); - AvatarMap::const_iterator end = m_avatars.end(); - while (i != end) + // Scan default avatars first. { - if (i->second == fileName) + boost::mutex::scoped_lock lock(m_avatarsMutex); + AvatarMap::const_iterator i = m_avatars.begin(); + AvatarMap::const_iterator end = m_avatars.end(); + while (i != end) { - md5buf = i->first; - found = true; - break; + if (i->second == fileName) + { + md5buf = i->first; + found = true; + break; + } + ++i; } - ++i; } + // Check cached avatars next. + if (!found) + { + boost::mutex::scoped_lock lock(m_cachedAvatarsMutex); + AvatarMap::const_iterator i = m_cachedAvatars.begin(); + AvatarMap::const_iterator end = m_cachedAvatars.end(); + while (i != end) + { + if (i->second == fileName) + { + md5buf = i->first; + found = true; + break; + } + ++i; + } + } + + // Calculate md5 sum if not found. if (!found) { if (CryptHelper::MD5Sum(fileName, md5buf)) - { - m_avatars.insert(AvatarMap::value_type(md5buf, fileName)); found = true; - } } } return found; @@ -204,15 +226,35 @@ bool AvatarManager::GetAvatarFileName(const MD5Buf &md5buf, std::string &fileName) const { bool retVal = false; - AvatarMap::const_iterator pos = m_avatars.find(md5buf); - if (pos != m_avatars.end()) { - fileName = pos->second; - retVal = true; + boost::mutex::scoped_lock lock(m_avatarsMutex); + AvatarMap::const_iterator pos = m_avatars.find(md5buf); + if (pos != m_avatars.end()) + { + fileName = pos->second; + retVal = true; + } + } + if (!retVal) + { + boost::mutex::scoped_lock lock(m_cachedAvatarsMutex); + AvatarMap::const_iterator pos = m_cachedAvatars.find(md5buf); + if (pos != m_cachedAvatars.end()) + { + fileName = pos->second; + retVal = true; + } } return retVal; } +bool +AvatarManager::HasAvatar(const MD5Buf &md5buf) const +{ + string tmpFile; + return GetAvatarFileName(md5buf, tmpFile); +} + bool AvatarManager::StoreAvatarInCache(const MD5Buf &md5buf, AvatarFileType avatarFileType, const unsigned char *data, unsigned size) { @@ -237,7 +279,10 @@ AvatarManager::StoreAvatarInCache(const MD5Buf &md5buf, AvatarFileType avatarFil string fileName(tmpPath.file_string()); ofstream o(fileName.c_str(), ios_base::out | ios_base::binary); o.write((const char *)data, size); - m_avatars.insert(AvatarMap::value_type(md5buf, fileName)); + { + boost::mutex::scoped_lock lock(m_cachedAvatarsMutex); + m_cachedAvatars.insert(AvatarMap::value_type(md5buf, fileName)); + } retVal = true; } catch (...) { @@ -245,30 +290,39 @@ AvatarManager::StoreAvatarInCache(const MD5Buf &md5buf, AvatarFileType avatarFil return retVal; } -void -AvatarManager::InternalReadDirectory(const std::string &dir) +bool +AvatarManager::InternalReadDirectory(const std::string &dir, AvatarMap &avatars) { - directory_iterator i(dir); - directory_iterator end; - - while (i != end) + bool retVal = true; + try { - if (is_regular(i->status())) + // This method is not thread safe. Only call after locking the map. + directory_iterator i(dir); + directory_iterator end; + + while (i != end) { - string md5sum(basename(i->path())); - MD5Buf md5buf; - string fileName(i->path().file_string()); - bool success = true; - if (!md5buf.FromString(md5sum)) + if (is_regular(i->status())) { - // sigh. File name is not an md5 sum. Calculate on our own... - if (!CryptHelper::MD5Sum(fileName, md5buf)) - success = false; + string md5sum(basename(i->path())); + MD5Buf md5buf; + string fileName(i->path().file_string()); + bool success = true; + if (!md5buf.FromString(md5sum)) + { + // sigh. File name is not an md5 sum. Calculate on our own... + if (!CryptHelper::MD5Sum(fileName, md5buf)) + success = false; + } + if (success) + avatars.insert(AvatarMap::value_type(md5buf, fileName)); } - if (success) - m_avatars.insert(AvatarMap::value_type(md5buf, fileName)); + ++i; } - ++i; + } catch (...) + { + retVal = false; } + return retVal; } diff --git a/src/core/common/crypthelper.cpp b/src/core/common/crypthelper.cpp index 90808a7e..ebc2a980 100644 --- a/src/core/common/crypthelper.cpp +++ b/src/core/common/crypthelper.cpp @@ -88,6 +88,12 @@ MD5Buf::FromString(const std::string &text) return retVal; } +bool +MD5Buf::IsZero() const +{ + return *this == MD5Buf(); +} + bool MD5Buf::operator==(const MD5Buf &other) const { diff --git a/src/core/crypthelper.h b/src/core/crypthelper.h index 86d9a894..5d1846d8 100644 --- a/src/core/crypthelper.h +++ b/src/core/crypthelper.h @@ -31,6 +31,7 @@ struct MD5Buf std::string ToString() const; bool FromString(const std::string &text); + bool IsZero() const; bool operator==(const MD5Buf &other) const; bool operator<(const MD5Buf &other) const; diff --git a/src/net/common/netpacket.cpp b/src/net/common/netpacket.cpp index 58801488..f04a9a07 100644 --- a/src/net/common/netpacket.cpp +++ b/src/net/common/netpacket.cpp @@ -1359,7 +1359,7 @@ NetPacketAvatarHeader::GetData(NetPacketAvatarHeader::Data &outData) const outData.requestId = ntohl(tmpData->requestId); outData.avatarFileSize = ntohl(tmpData->avatarFileSize); - outData.avatarFileType = static_cast(ntohl(tmpData->avatarFileType)); + outData.avatarFileType = static_cast(ntohs(tmpData->avatarFileType)); } const NetPacketAvatarHeader * @@ -1402,7 +1402,6 @@ NetPacketAvatarFile::Clone() const void NetPacketAvatarFile::SetData(const NetPacketAvatarFile::Data &inData) { - NetPacketAvatarFileData *tmpData = (NetPacketAvatarFileData *)GetRawData(); int fileDataSize = static_cast(inData.fileData.size()); if (fileDataSize > MAX_FILE_DATA_SIZE) @@ -1412,6 +1411,8 @@ NetPacketAvatarFile::SetData(const NetPacketAvatarFile::Data &inData) (sizeof(NetPacketAvatarFileData) + fileDataSize)); + NetPacketAvatarFileData *tmpData = (NetPacketAvatarFileData *)GetRawData(); + tmpData->requestId = htonl(inData.requestId); char *avatarDataPtr = (char *)tmpData + sizeof(NetPacketAvatarFileData); diff --git a/src/net/common/serveracceptthread.cpp b/src/net/common/serveracceptthread.cpp index 23aee13f..4dbc4c47 100644 --- a/src/net/common/serveracceptthread.cpp +++ b/src/net/common/serveracceptthread.cpp @@ -30,11 +30,11 @@ using namespace std; -ServerAcceptThread::ServerAcceptThread(GuiInterface &gui, ConfigFile *config) +ServerAcceptThread::ServerAcceptThread(GuiInterface &gui, ConfigFile *config, AvatarManager &avatarManager) : m_gui(gui) { m_context.reset(new ServerContext); - m_lobbyThread.reset(new ServerLobbyThread(gui, config)); + m_lobbyThread.reset(new ServerLobbyThread(gui, config, avatarManager)); } ServerAcceptThread::~ServerAcceptThread() diff --git a/src/net/common/serverlobbythread.cpp b/src/net/common/serverlobbythread.cpp index 1d7108ad..113f33f1 100644 --- a/src/net/common/serverlobbythread.cpp +++ b/src/net/common/serverlobbythread.cpp @@ -24,11 +24,12 @@ #include #include #include +#include #include #include -#define SERVER_CLOSE_SESSION_DELAY_SEC 10 +#define SERVER_CLOSE_SESSION_DELAY_SEC 1 #define SERVER_MAX_NUM_SESSIONS 512 // Maximum number of idle users in lobby. #define SERVER_COMPUTER_PLAYER_NAME "Computer" @@ -54,8 +55,9 @@ private: }; -ServerLobbyThread::ServerLobbyThread(GuiInterface &gui, ConfigFile *playerConfig) -: m_gui(gui), m_playerConfig(playerConfig), m_curGameId(0), m_curUniquePlayerId(0) +ServerLobbyThread::ServerLobbyThread(GuiInterface &gui, ConfigFile *playerConfig, AvatarManager &avatarManager) +: m_gui(gui), m_avatarManager(avatarManager), m_playerConfig(playerConfig), + m_curGameId(0), m_curUniquePlayerId(0), m_curRequestId(0) { m_senderCallback.reset(new ServerSenderCallback(*this)); m_sender.reset(new SenderThread(GetSenderCallback())); @@ -174,6 +176,12 @@ ServerLobbyThread::RemoveGame(unsigned id) m_removeGameList.push_back(id); } +AvatarManager & +ServerLobbyThread::GetAvatarManager() +{ + return m_avatarManager; +} + u_int32_t ServerLobbyThread::GetNextUniquePlayerId() { @@ -265,17 +273,24 @@ ServerLobbyThread::ProcessLoop() } if (packet.get()) { - if (packet->ToNetPacketInit()) + if (session.sessionData->GetState() == SessionData::Init) { - // Session should be in initial state. - if (session.sessionData->GetState() != SessionData::Init) - SessionError(session, ERR_SOCK_INVALID_STATE); - else + if (packet->ToNetPacketInit()) HandleNetPacketInit(session, *packet->ToNetPacketInit()); + else if (packet->ToNetPacketAvatarHeader()) + HandleNetPacketAvatarHeader(session, *packet->ToNetPacketAvatarHeader()); + else + SessionError(session, ERR_SOCK_INVALID_STATE); + } + else if (session.sessionData->GetState() == SessionData::ReceivingAvatar) + { + if (packet->ToNetPacketAvatarFile()) + HandleNetPacketAvatarFile(session, *packet->ToNetPacketAvatarFile()); + else if (packet->ToNetPacketAvatarEnd()) + HandleNetPacketAvatarEnd(session, *packet->ToNetPacketAvatarEnd()); + else + SessionError(session, ERR_SOCK_INVALID_STATE); } - // Session should be established. - else if (session.sessionData->GetState() != SessionData::Established) - SessionError(session, ERR_SOCK_INVALID_STATE); else { if (packet->ToNetPacketRetrievePlayerInfo()) @@ -284,6 +299,8 @@ ServerLobbyThread::ProcessLoop() HandleNetPacketCreateGame(session, *packet->ToNetPacketCreateGame()); else if (packet->ToNetPacketJoinGame()) HandleNetPacketJoinGame(session, *packet->ToNetPacketJoinGame()); + else + SessionError(session, ERR_SOCK_INVALID_STATE); } } } @@ -333,24 +350,80 @@ ServerLobbyThread::HandleNetPacketInit(SessionWrapper session, const NetPacketIn tmpPlayerData->SetName(initData.playerName); tmpPlayerData->SetNetSessionData(session.sessionData); if (initData.showAvatar) - tmpPlayerData->SetAvatarFile(initData.avatar.ToString()); - - // Send ACK to client. - boost::shared_ptr initAck(new NetPacketInitAck); - NetPacketInitAck::Data initAckData; - initAckData.sessionId = session.sessionData->GetId(); // TODO: currently unused. - initAckData.playerId = tmpPlayerData->GetUniqueId(); - static_cast(initAck.get())->SetData(initAckData); - GetSender().Send(session.sessionData->GetSocket(), initAck); - - // Send the game list to the client. - SendGameList(session.sessionData->GetSocket()); + tmpPlayerData->SetAvatarMD5(initData.avatar); // Set player data for session. m_sessionManager.SetSessionPlayerData(session.sessionData->GetSocket(), tmpPlayerData); + session.playerData = tmpPlayerData; - // Session is now established. - session.sessionData->SetState(SessionData::Established); + if (!GetAvatarManager().HasAvatar(initData.avatar)) + RequestPlayerAvatar(session); + else + EstablishSession(session); +} + +void +ServerLobbyThread::HandleNetPacketAvatarHeader(SessionWrapper session, const NetPacketAvatarHeader &tmpPacket) +{ + if (session.playerData.get()) + { + NetPacketAvatarHeader::Data headerData; + tmpPacket.GetData(headerData); + + if (headerData.avatarFileSize && headerData.avatarFileSize <= MAX_AVATAR_FILE_SIZE) + { + boost::shared_ptr tmpAvatarData(new AvatarData); + tmpAvatarData->fileData.reserve(headerData.avatarFileSize); + tmpAvatarData->fileType = headerData.avatarFileType; + tmpAvatarData->reportedSize = headerData.avatarFileSize; + // Ignore request id for now. + + session.playerData->SetNetAvatarData(tmpAvatarData); + + // Session is now receiving an avatar. + session.sessionData->SetState(SessionData::ReceivingAvatar); + } + // TODO error handling + } +} + +void +ServerLobbyThread::HandleNetPacketAvatarFile(SessionWrapper session, const NetPacketAvatarFile &tmpPacket) +{ + if (session.playerData.get()) + { + NetPacketAvatarFile::Data data; + tmpPacket.GetData(data); + + boost::shared_ptr tmpAvatar = session.playerData->GetNetAvatarData(); + if (tmpAvatar.get() && tmpAvatar->fileData.size() + data.fileData.size() <= tmpAvatar->reportedSize) + { + std::copy(data.fileData.begin(), data.fileData.end(), back_inserter(tmpAvatar->fileData)); + } + } +} + +void +ServerLobbyThread::HandleNetPacketAvatarEnd(SessionWrapper session, const NetPacketAvatarEnd &tmpPacket) +{ + if (session.playerData.get()) + { + boost::shared_ptr tmpAvatar = session.playerData->GetNetAvatarData(); + MD5Buf avatarMD5 = session.playerData->GetAvatarMD5(); + if (!avatarMD5.IsZero() && tmpAvatar.get()) + { + unsigned avatarSize = (unsigned)tmpAvatar->fileData.size(); + if (avatarSize == tmpAvatar->reportedSize) + { + GetAvatarManager().StoreAvatarInCache(avatarMD5, tmpAvatar->fileType, &tmpAvatar->fileData[0], avatarSize); + // Free memory. + session.playerData->SetNetAvatarData(boost::shared_ptr()); + // Init finished - start session. + EstablishSession(session); + } + // TODO error handling + } + } } void @@ -372,9 +445,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(); + infoData.playerInfo.hasAvatar = !tmpPlayer->GetAvatarMD5().IsZero(); if (infoData.playerInfo.hasAvatar) - infoData.playerInfo.avatar.FromString(tmpPlayer->GetAvatarFile()); + infoData.playerInfo.avatar = tmpPlayer->GetAvatarMD5(); static_cast(info.get())->SetData(infoData); GetSender().Send(session.sessionData->GetSocket(), info); } @@ -433,6 +506,38 @@ ServerLobbyThread::HandleNetPacketJoinGame(SessionWrapper session, const NetPack } } +void +ServerLobbyThread::EstablishSession(SessionWrapper session) +{ + assert(session.playerData.get()); + // Send ACK to client. + boost::shared_ptr initAck(new NetPacketInitAck); + NetPacketInitAck::Data initAckData; + initAckData.sessionId = session.sessionData->GetId(); // TODO: currently unused. + initAckData.playerId = session.playerData->GetUniqueId(); + static_cast(initAck.get())->SetData(initAckData); + GetSender().Send(session.sessionData->GetSocket(), initAck); + + // Send the game list to the client. + SendGameList(session.sessionData->GetSocket()); + + // Session is now established. + session.sessionData->SetState(SessionData::Established); +} + +void +ServerLobbyThread::RequestPlayerAvatar(SessionWrapper session) +{ + assert(session.playerData.get()); + // Ask the client to send its avatar. + boost::shared_ptr retrieveAvatar(new NetPacketRetrieveAvatar); + NetPacketRetrieveAvatar::Data retrieveAvatarData; + retrieveAvatarData.requestId = m_curRequestId++; + retrieveAvatarData.avatar = session.playerData->GetAvatarMD5(); + static_cast(retrieveAvatar.get())->SetData(retrieveAvatarData); + GetSender().Send(session.sessionData->GetSocket(), retrieveAvatar); +} + void ServerLobbyThread::CloseSessionLoop() { diff --git a/src/net/serveracceptthread.h b/src/net/serveracceptthread.h index cc051b1a..84b2bf20 100644 --- a/src/net/serveracceptthread.h +++ b/src/net/serveracceptthread.h @@ -32,12 +32,13 @@ class ServerLobbyThread; class ServerSenderCallback; class SenderThread; class ConfigFile; +class AvatarManager; struct GameData; class ServerAcceptThread : public Thread { public: - ServerAcceptThread(GuiInterface &gui, ConfigFile *config); + ServerAcceptThread(GuiInterface &gui, ConfigFile *config, AvatarManager &avatarManager); virtual ~ServerAcceptThread(); // Set the parameters. diff --git a/src/net/serverlobbythread.h b/src/net/serverlobbythread.h index a67ee501..27015509 100644 --- a/src/net/serverlobbythread.h +++ b/src/net/serverlobbythread.h @@ -39,13 +39,14 @@ class ReceiverHelper; class ServerSenderCallback; class ServerGameThread; class ConfigFile; +class AvatarManager; struct GameData; class Game; class ServerLobbyThread : public Thread { public: - ServerLobbyThread(GuiInterface &gui, ConfigFile *playerConfig); + ServerLobbyThread(GuiInterface &gui, ConfigFile *playerConfig, AvatarManager &avatarManager); virtual ~ServerLobbyThread(); void Init(const std::string &pwd); @@ -67,6 +68,8 @@ public: u_int32_t GetNextGameId(); ServerCallback &GetCallback(); + AvatarManager &GetAvatarManager(); + protected: typedef std::deque > ConnectQueue; @@ -81,9 +84,14 @@ protected: void ProcessLoop(); void HandleNetPacketInit(SessionWrapper session, const NetPacketInit &tmpPacket); + void HandleNetPacketAvatarHeader(SessionWrapper session, const NetPacketAvatarHeader &tmpPacket); + void HandleNetPacketAvatarFile(SessionWrapper session, const NetPacketAvatarFile &tmpPacket); + void HandleNetPacketAvatarEnd(SessionWrapper session, const NetPacketAvatarEnd &tmpPacket); void HandleNetPacketRetrievePlayerInfo(SessionWrapper session, const NetPacketRetrievePlayerInfo &tmpPacket); void HandleNetPacketCreateGame(SessionWrapper session, const NetPacketCreateGame &tmpPacket); void HandleNetPacketJoinGame(SessionWrapper session, const NetPacketJoinGame &tmpPacket); + void EstablishSession(SessionWrapper session); + void RequestPlayerAvatar(SessionWrapper session); void CloseSessionLoop(); void RemoveGameLoop(); @@ -141,6 +149,7 @@ private: std::auto_ptr m_sender; std::auto_ptr m_senderCallback; GuiInterface &m_gui; + AvatarManager &m_avatarManager; std::string m_password; ConfigFile *m_playerConfig; @@ -148,6 +157,8 @@ private: u_int32_t m_curUniquePlayerId; mutable boost::mutex m_curUniquePlayerIdMutex; + + u_int32_t m_curRequestId; }; #endif diff --git a/src/net/sessiondata.h b/src/net/sessiondata.h index 109ca893..72ce06f5 100644 --- a/src/net/sessiondata.h +++ b/src/net/sessiondata.h @@ -31,7 +31,7 @@ class SessionData { public: - enum State { Init, Established, Game }; + enum State { Init, ReceivingAvatar, Established, Game }; SessionData(SOCKET sockfd, unsigned id); ~SessionData(); diff --git a/src/playerdata.cpp b/src/playerdata.cpp index 0840d237..f67b145f 100644 --- a/src/playerdata.cpp +++ b/src/playerdata.cpp @@ -19,6 +19,8 @@ #include +using namespace std; + PlayerData::PlayerData(unsigned uniqueId, int number, PlayerType type, PlayerRights rights) : m_uniqueId(uniqueId), m_number(number), m_type(type), m_rights(rights) { @@ -35,7 +37,7 @@ PlayerData::~PlayerData() { } -const std::string & +string PlayerData::GetName() const { boost::mutex::scoped_lock lock(m_dataMutex); @@ -49,7 +51,7 @@ PlayerData::SetName(const std::string &name) m_name = name; } -const std::string & +string PlayerData::GetAvatarFile() const { boost::mutex::scoped_lock lock(m_dataMutex); @@ -63,6 +65,19 @@ PlayerData::SetAvatarFile(const std::string &avatarFile) m_avatarFile = avatarFile; } +MD5Buf +PlayerData::GetAvatarMD5() const +{ + boost::mutex::scoped_lock lock(m_dataMutex); + return m_avatarMD5; +} +void +PlayerData::SetAvatarMD5(const MD5Buf &avatarMD5) +{ + boost::mutex::scoped_lock lock(m_dataMutex); + m_avatarMD5 = avatarMD5; +} + boost::shared_ptr PlayerData::GetNetSessionData() const { @@ -77,6 +92,18 @@ PlayerData::SetNetSessionData(boost::shared_ptr session) m_netSessionData = session; } +boost::shared_ptr +PlayerData::GetNetAvatarData() const +{ + return m_netAvatarData; +} + +void +PlayerData::SetNetAvatarData(boost::shared_ptr avatarData) +{ + m_netAvatarData = avatarData; +} + PlayerType PlayerData::GetType() const { diff --git a/src/playerdata.h b/src/playerdata.h index 939b9359..ebdbb30a 100644 --- a/src/playerdata.h +++ b/src/playerdata.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,14 @@ enum AvatarFileType AVATAR_FILE_TYPE_GIF }; +struct AvatarData +{ + AvatarData() : fileType(AVATAR_FILE_TYPE_UNKNOWN), reportedSize(0) {} + std::vector fileData; + AvatarFileType fileType; + unsigned reportedSize; +}; + struct PlayerInfo { PlayerInfo() : ptype(PLAYER_TYPE_HUMAN) {} @@ -66,12 +75,16 @@ public: PlayerData(const PlayerData &other); ~PlayerData(); - const std::string &GetName() const; + std::string GetName() const; void SetName(const std::string &name); - const std::string &GetAvatarFile() const; + std::string GetAvatarFile() const; void SetAvatarFile(const std::string &avatarFile); + MD5Buf GetAvatarMD5() const; + void SetAvatarMD5(const MD5Buf &avatarMD5); boost::shared_ptr GetNetSessionData() const; void SetNetSessionData(boost::shared_ptr session); + boost::shared_ptr GetNetAvatarData() const; + void SetNetAvatarData(boost::shared_ptr avatarData); PlayerType GetType() const; void SetType(PlayerType type); PlayerRights GetRights() const; @@ -87,9 +100,11 @@ private: int m_number; std::string m_name; std::string m_avatarFile; + MD5Buf m_avatarMD5; PlayerType m_type; PlayerRights m_rights; boost::shared_ptr m_netSessionData; + boost::shared_ptr m_netAvatarData; mutable boost::mutex m_dataMutex; }; diff --git a/src/pokerth_server.cpp b/src/pokerth_server.cpp index b96d1020..cc2bb131 100644 --- a/src/pokerth_server.cpp +++ b/src/pokerth_server.cpp @@ -69,6 +69,9 @@ main(int argc, char *argv[]) //_CrtSetBreakAlloc(164); + //create defaultconfig + ConfigFile *myConfig = new ConfigFile(argc, argv); + // TODO: Hack #ifndef _WIN32 daemon(0, 0); @@ -77,9 +80,6 @@ main(int argc, char *argv[]) signal(SIGTERM, TerminateHandler); signal(SIGINT, TerminateHandler); - //create defaultconfig - ConfigFile *myConfig = new ConfigFile(argc, argv); - socket_startup(); // Create pseudo Gui Wrapper for the server. diff --git a/src/session.cpp b/src/session.cpp index 0b7b2b30..040138fc 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -212,7 +212,7 @@ void Session::startNetworkServer() assert(false); return; } - myNetServer = new ServerAcceptThread(*myGui, myConfig); + myNetServer = new ServerAcceptThread(*myGui, myConfig, *myAvatarManager); myNetServer->Init( myConfig->readConfigInt("ServerPort"), myConfig->readConfigInt("ServerUseIpv6") == 1,