From f2ec0b1ef43201c56bd771ed64a511499b69ca61 Mon Sep 17 00:00:00 2001 From: lotodore Date: Sun, 22 Mar 2009 00:39:25 +0000 Subject: [PATCH] Detect avatar file type for download. Not fully working yet. --- docs/net_protocol.txt | 1 + src/core/avatarmanager.h | 2 + src/core/common/avatarmanager.cpp | 66 ++++++++++++++++++---------- src/net/common/clientthread.cpp | 4 +- src/net/common/netpacket.cpp | 17 +++++++ src/net/common/serverlobbythread.cpp | 12 ++++- src/playerdata.h | 3 +- 7 files changed, 77 insertions(+), 28 deletions(-) diff --git a/docs/net_protocol.txt b/docs/net_protocol.txt index 8484ea37..fd838b19 100644 --- a/docs/net_protocol.txt +++ b/docs/net_protocol.txt @@ -332,6 +332,7 @@ Server Reply: Player Info Player Flags: 0x01 set: Player is human 0x02 set: Player has avatar + 0x04/0x08 set: Avatar type Server Reply: Unknown Player Id diff --git a/src/core/avatarmanager.h b/src/core/avatarmanager.h index 3a03cc37..8ba7e8d6 100644 --- a/src/core/avatarmanager.h +++ b/src/core/avatarmanager.h @@ -53,6 +53,8 @@ public: static unsigned ChunkReadAvatarFile(boost::shared_ptr fileState, unsigned char *data, unsigned chunkSize); static int AvatarFileToNetPackets(const std::string &fileName, unsigned requestId, NetPacketList &packets); + static AvatarFileType GetAvatarFileType(const std::string &fileName); + static std::string GetAvatarFileExtension(AvatarFileType fileType); bool GetHashForAvatar(const std::string &fileName, MD5Buf &md5buf) const; bool GetAvatarFileName(const MD5Buf &md5buf, std::string &fileName) const; diff --git a/src/core/common/avatarmanager.cpp b/src/core/common/avatarmanager.cpp index 03640a5d..f98d489b 100644 --- a/src/core/common/avatarmanager.cpp +++ b/src/core/common/avatarmanager.cpp @@ -129,18 +129,10 @@ boost::shared_ptr AvatarManager::OpenAvatarFileForChunkRead(const std::string &fileName, unsigned &outFileSize, AvatarFileType &outFileType) { outFileSize = 0; - outFileType = AVATAR_FILE_TYPE_UNKNOWN; boost::shared_ptr retVal; try { - path filePath(fileName); - string ext(extension(filePath)); - if (boost::algorithm::iequals(ext, ".png")) - outFileType = AVATAR_FILE_TYPE_PNG; - else if (boost::algorithm::iequals(ext, ".jpg") || boost::algorithm::iequals(ext, ".jpeg")) - outFileType = AVATAR_FILE_TYPE_JPG; - else if (boost::algorithm::iequals(ext, ".gif")) - outFileType = AVATAR_FILE_TYPE_GIF; + outFileType = GetAvatarFileType(fileName); boost::shared_ptr fileState(new AvatarFileState); fileState->inputStream.open(fileName.c_str(), ios_base::in | ios_base::binary); if (!fileState->inputStream.fail()) @@ -243,6 +235,46 @@ AvatarManager::AvatarFileToNetPackets(const string &fileName, unsigned requestId return retVal; } +AvatarFileType +AvatarManager::GetAvatarFileType(const string &fileName) +{ + AvatarFileType fileType; + + path filePath(fileName); + string ext(extension(filePath)); + if (boost::algorithm::iequals(ext, ".png")) + fileType = AVATAR_FILE_TYPE_PNG; + else if (boost::algorithm::iequals(ext, ".jpg") || boost::algorithm::iequals(ext, ".jpeg")) + fileType = AVATAR_FILE_TYPE_JPG; + else if (boost::algorithm::iequals(ext, ".gif")) + fileType = AVATAR_FILE_TYPE_GIF; + else + fileType = AVATAR_FILE_TYPE_UNKNOWN; + + return fileType; +} + +string +AvatarManager::GetAvatarFileExtension(AvatarFileType fileType) +{ + string ext; + switch (fileType) + { + case AVATAR_FILE_TYPE_PNG: + ext = ".png"; + break; + case AVATAR_FILE_TYPE_JPG: + ext = ".jpg"; + break; + case AVATAR_FILE_TYPE_GIF: + ext = ".gif"; + break; + case AVATAR_FILE_TYPE_UNKNOWN: + break; + } + return ext; +} + bool AvatarManager::GetHashForAvatar(const std::string &fileName, MD5Buf &md5buf) const { @@ -337,21 +369,7 @@ AvatarManager::StoreAvatarInCache(const MD5Buf &md5buf, AvatarFileType avatarFil } try { - string ext; - switch (avatarFileType) - { - case AVATAR_FILE_TYPE_PNG: - ext = ".png"; - break; - case AVATAR_FILE_TYPE_JPG: - ext = ".jpg"; - break; - case AVATAR_FILE_TYPE_GIF: - ext = ".gif"; - break; - case AVATAR_FILE_TYPE_UNKNOWN: - break; - } + string ext(GetAvatarFileExtension(avatarFileType)); if (!ext.empty() && !cacheDir.empty()) { // Check header before storing file. diff --git a/src/net/common/clientthread.cpp b/src/net/common/clientthread.cpp index 8d0de2d7..deefd6ec 100644 --- a/src/net/common/clientthread.cpp +++ b/src/net/common/clientthread.cpp @@ -557,7 +557,7 @@ ClientThread::RetrieveAvatarIfNeeded(unsigned id, const PlayerInfo &info) string avatarServerAddress(GetContext().GetAvatarServerAddr()); if (!avatarServerAddress.empty() && m_avatarDownloader) { - string serverFileName(info.avatar.ToString() + ".jpg"); // TODO! + string serverFileName(info.avatar.ToString() + AvatarManager::GetAvatarFileExtension(info.avatarType)); m_avatarDownloader->QueueDownload( id, avatarServerAddress + serverFileName, GetContext().GetCacheDir() + TEMP_AVATAR_FILENAME); } @@ -621,7 +621,7 @@ ClientThread::PassAvatarDataToManager(unsigned playerId, boost::shared_ptrfileType == AVATAR_FILE_TYPE_UNKNOWN) - avatarData->fileType = AVATAR_FILE_TYPE_JPG; // TODO! + avatarData->fileType = tmpPlayerInfo.avatarType; if (!GetAvatarManager().StoreAvatarInCache(tmpPlayerInfo.avatar, avatarData->fileType, &avatarData->fileData[0], avatarData->reportedSize, false)) LOG_ERROR("Failed to store avatar in cache directory."); diff --git a/src/net/common/netpacket.cpp b/src/net/common/netpacket.cpp index 83b85b29..a5eaeda6 100644 --- a/src/net/common/netpacket.cpp +++ b/src/net/common/netpacket.cpp @@ -95,6 +95,7 @@ using namespace std; #define NET_PLAYER_FLAG_HUMAN 0x01 #define NET_PLAYER_FLAG_HAS_AVATAR 0x02 +#define NET_PLAYER_FLAG_AVATAR_TYPE_MASK 0x0c #define NET_START_FLAG_FILL_WITH_CPU_PLAYERS 0x01 @@ -2454,6 +2455,7 @@ NetPacketPlayerInfo::SetData(const NetPacketPlayerInfo::Data &inData) if (inData.playerInfo.hasAvatar) { tmpPlayerFlags |= NET_PLAYER_FLAG_HAS_AVATAR; + tmpPlayerFlags |= ((inData.playerInfo.avatarType) << 2); char *avatarPtr = (char *)tmpData + sizeof(NetPacketPlayerInfoData); memcpy(avatarPtr, inData.playerInfo.avatar.data, MD5_DATA_SIZE); } @@ -2479,6 +2481,21 @@ NetPacketPlayerInfo::GetData(NetPacketPlayerInfo::Data &outData) const if (outData.playerInfo.hasAvatar) { + switch ((tmpPlayerFlags & NET_PLAYER_FLAG_AVATAR_TYPE_MASK) >> 2) + { + case AVATAR_FILE_TYPE_PNG : + outData.playerInfo.avatarType = AVATAR_FILE_TYPE_PNG; + break; + case AVATAR_FILE_TYPE_JPG : + outData.playerInfo.avatarType = AVATAR_FILE_TYPE_JPG; + break; + case AVATAR_FILE_TYPE_GIF : + outData.playerInfo.avatarType = AVATAR_FILE_TYPE_GIF; + break; + default: + outData.playerInfo.avatarType = AVATAR_FILE_TYPE_UNKNOWN; + break; + } char *avatarPtr = (char *)tmpData + sizeof(NetPacketPlayerInfoData); memcpy(outData.playerInfo.avatar.data, avatarPtr, MD5_DATA_SIZE); } diff --git a/src/net/common/serverlobbythread.cpp b/src/net/common/serverlobbythread.cpp index 183a50f9..b3b42bcb 100644 --- a/src/net/common/serverlobbythread.cpp +++ b/src/net/common/serverlobbythread.cpp @@ -523,9 +523,10 @@ ServerLobbyThread::HandleNetPacketInit(SessionWrapper session, const NetPacketIn m_sessionManager.SetSessionPlayerData(session.sessionData->GetId(), tmpPlayerData); session.playerData = tmpPlayerData; + string avatarFileName; if (initData.showAvatar && !initData.avatar.IsZero() - && !GetAvatarManager().HasAvatar(initData.avatar)) + && !GetAvatarManager().GetAvatarFileName(initData.avatar, avatarFileName)) { bool avatarRecentlyRequested = false; { @@ -540,6 +541,8 @@ ServerLobbyThread::HandleNetPacketInit(SessionWrapper session, const NetPacketIn } else { + if (!avatarFileName.empty()) + session.playerData->SetAvatarFile(avatarFileName); EstablishSession(session); } } @@ -619,6 +622,10 @@ ServerLobbyThread::HandleNetPacketAvatarEnd(SessionWrapper session, const NetPac // Free memory. session.playerData->SetNetAvatarData(boost::shared_ptr()); + // Set avatar file name. + string avatarFileName; + if (GetAvatarManager().GetAvatarFileName(avatarMD5, avatarFileName)) + session.playerData->SetAvatarFile(avatarFileName); // Init finished - start session. EstablishSession(session); } @@ -656,7 +663,10 @@ ServerLobbyThread::HandleNetPacketRetrievePlayerInfo(SessionWrapper session, con infoData.playerInfo.playerName = tmpPlayer->GetName(); infoData.playerInfo.hasAvatar = !tmpPlayer->GetAvatarMD5().IsZero(); if (infoData.playerInfo.hasAvatar) + { infoData.playerInfo.avatar = tmpPlayer->GetAvatarMD5(); + infoData.playerInfo.avatarType = AvatarManager::GetAvatarFileType(tmpPlayer->GetAvatarFile()); + } static_cast(info.get())->SetData(infoData); session.sessionData->GetSender().Send(session.sessionData, info); } diff --git a/src/playerdata.h b/src/playerdata.h index c8395fa1..75357e77 100644 --- a/src/playerdata.h +++ b/src/playerdata.h @@ -61,11 +61,12 @@ struct AvatarData struct PlayerInfo { - PlayerInfo() : ptype(PLAYER_TYPE_HUMAN) {} + PlayerInfo() : ptype(PLAYER_TYPE_HUMAN), hasAvatar(false), avatarType(AVATAR_FILE_TYPE_UNKNOWN) {} std::string playerName; PlayerType ptype; bool hasAvatar; MD5Buf avatar; + AvatarFileType avatarType; }; class PlayerData