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,