diff --git a/src/ScriptLib/Resource.cpp b/src/ScriptLib/Resource.cpp index 27dd34f..b30dc2d 100644 --- a/src/ScriptLib/Resource.cpp +++ b/src/ScriptLib/Resource.cpp @@ -94,6 +94,7 @@ CPythonResource::CPythonResource() m_resManager.RegisterResourceNewFunctionPointer("jpg", NewImage); m_resManager.RegisterResourceNewFunctionPointer("tga", NewImage); m_resManager.RegisterResourceNewFunctionPointer("bmp", NewImage); + m_resManager.RegisterResourceNewFunctionPointer("png", NewImage); m_resManager.RegisterResourceNewFunctionPointer("fnt", NewText); m_resManager.RegisterResourceNewFunctionPointer("gr2", NewThing); m_resManager.RegisterResourceNewFunctionPointer("mde", NewEffectMesh); diff --git a/src/UserInterface/GuildMarkUploader.cpp b/src/UserInterface/GuildMarkUploader.cpp index 130602d..4026948 100644 --- a/src/UserInterface/GuildMarkUploader.cpp +++ b/src/UserInterface/GuildMarkUploader.cpp @@ -76,15 +76,8 @@ bool CGuildMarkUploader::__Load(const char* c_szFileName, UINT* peError) return false; } - // Copy into our mark buffer (BGRA expected) - for (uint32_t i = 0; i < width * height; ++i) { - const uint8_t R = data[i * 4 + 0]; - const uint8_t G = data[i * 4 + 1]; - const uint8_t B = data[i * 4 + 2]; - const uint8_t A = data[i * 4 + 3]; - - m_kMark.m_apxBuf[i] = (uint32_t(A) << 24) | (uint32_t(R) << 16) | (uint32_t(G) << 8) | uint32_t(B); - } + // Copy into our mark buffer (native RGBA format) + memcpy(m_kMark.m_apxBuf, data, SGuildMark::SIZE * 4); stbi_image_free(data); return true; diff --git a/src/UserInterface/MarkManager.cpp b/src/UserInterface/MarkManager.cpp index 26b9916..b726b00 100644 --- a/src/UserInterface/MarkManager.cpp +++ b/src/UserInterface/MarkManager.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include #include "MarkManager.h" #if _MSC_VER < 1200 @@ -124,9 +125,14 @@ void CGuildMarkManager::SaveMarkImage(DWORD imgIdx) { std::string path; - if (GetMarkImageFilename(imgIdx, path)) - if (!__GetImage(imgIdx)->Save(path.c_str())) - sys_err("%s Save failed\n", path.c_str()); + if (!GetMarkImageFilename(imgIdx, path)) + return; + + CGuildMarkImage* pkImage = __GetImage(imgIdx); + if (!pkImage) + return; + + pkImage->Save(path.c_str()); } CGuildMarkImage * CGuildMarkManager::__GetImage(DWORD imgIdx) @@ -156,7 +162,6 @@ bool CGuildMarkManager::AddMarkIDByGuildID(DWORD guildID, DWORD markID) if (markID >= MAX_IMAGE_COUNT * CGuildMarkImage::MARK_TOTAL_COUNT) return false; - //sys_log(0, "MarkManager: guild_id=%d mark_id=%d", guildID, markID); m_mapGID_MarkID.insert(std::map::value_type(guildID, markID)); m_setFreeMarkID.erase(markID); return true; @@ -290,7 +295,7 @@ bool CGuildMarkManager::SaveBlockFromCompressedData(DWORD imgIdx, DWORD posBlock CGuildMarkImage * pkImage = __GetImage(imgIdx); if (pkImage) - pkImage->SaveBlockFromCompressedData(posBlock, pbBlock, dwSize); + return pkImage->SaveBlockFromCompressedData(posBlock, pbBlock, dwSize); return false; } @@ -313,6 +318,29 @@ bool CGuildMarkManager::GetBlockCRCList(DWORD imgIdx, uint32_t* crcList) return true; } +// CLIENT +void CGuildMarkManager::ReloadMarkImage(DWORD imgIdx) +{ + std::string imagePath; + if (!GetMarkImageFilename(imgIdx, imagePath)) + return; + + std::map::iterator it = m_mapIdx_Image.find(imgIdx); + if (it != m_mapIdx_Image.end()) + { + // Reload the image from disk + it->second->Load(imagePath.c_str()); + sys_log(0, "ReloadMarkImage: reloaded image data %u from %s", imgIdx, imagePath.c_str()); + } + + CResource* pResource = CResourceManager::Instance().GetResourcePointer(imagePath.c_str()); + if (pResource && pResource->IsType(CGraphicImage::Type())) + { + pResource->Reload(); + sys_log(0, "ReloadMarkImage: reloaded texture %u from %s", imgIdx, imagePath.c_str()); + } +} + /////////////////////////////////////////////////////////////////////////////////////// // Symbol /////////////////////////////////////////////////////////////////////////////////////// @@ -396,93 +424,4 @@ void CGuildMarkManager::UploadSymbol(DWORD guildID, int iSize, const uint8_t* pb std::copy(pbyData, (pbyData + iSize), std::back_inserter(rSymbol.raw)); rSymbol.crc = GetCRC32(reinterpret_cast(pbyData), iSize); } -} - -#ifdef __UNITTEST__ -#include "lzo_manager.h" - -Guild::CGuildMarkManager * mgr; - -void heartbeat(LPHEART ht, int pulse) -{ - return; -} - -void SaveMark(DWORD guildID, const char * filename) -{ - ILuint m_uImg; - - ilGenImages(1, &m_uImg); - ilBindImage(m_uImg); - ilEnable(IL_ORIGIN_SET); - ilOriginFunc(IL_ORIGIN_UPPER_LEFT); - - if (ilLoad(IL_TYPE_UNKNOWN, (const ILstring) filename)) - { - ILuint width = ilGetInteger(IL_IMAGE_WIDTH); - ILuint height = ilGetInteger(IL_IMAGE_HEIGHT); - - ilConvertImage(IL_BGRA, IL_UNSIGNED_BYTE); - - uint8_t* data = (uint8_t*) malloc(sizeof(DWORD) * width * height); - ilCopyPixels(0, 0, 0, width, height, 1, IL_BGRA, IL_UNSIGNED_BYTE, data); - ilDeleteImages(1, &m_uImg); - - printf("%s w%u h%u ", filename, width, height); - mgr->SaveMark(guildID, data); - } - else - printf("%s cannot open file.\n", filename); -} - -int main(int argc, char **argv) -{ - LZOManager lzo; - char f[64]; - - srandom(time(0)); - - ilInit(); // DevIL Initialize - thecore_init(25, heartbeat); - - std::vector vec_guild_id; - - for (int i = 1; i < 1281; ++i) - vec_guild_id.push_back(i); - - mgr = new CGuildMarkManager; - mgr->LoadMarkData(vec_guild_id); - /* - for (int i = 1401; i < 1500; ++i) - { - snprintf(f, sizeof(f), "%lu.jpg", (random() % 5) + 1); - //SaveMark(i, f); - mgr->DeleteMark(i); - } - */ - //snprintf(f, sizeof(f), "%lu.jpg", (random() % 5) + 1); - //SaveMark(1, f); - DWORD idx_client[CGuildMarkImage::BLOCK_TOTAL_COUNT]; - DWORD idx_server[CGuildMarkImage::BLOCK_TOTAL_COUNT]; - - mgr->GetBlockCRCList(0, idx_client); - mgr->GetBlockCRCList(1, idx_server); - - std::map mapDiff; - mgr->GetDiffBlocks(1, idx_client, mapDiff); - - printf("#1 Diff %u\n", mapDiff.size()); - - for (itertype(mapDiff) it = mapDiff.begin(); it != mapDiff.end(); ++it) - { - printf("Put Block pos %u crc %u\n", it->first, it->second->m_crc); - mgr->SaveBlockFromCompressedData(0, it->first, it->second->m_abCompBuf, it->second->m_sizeCompBuf); - } - - mgr->GetBlockCRCList(0, idx_client); - mgr->GetDiffBlocks(1, idx_client, mapDiff); - printf("#2 Diff %u\n", mapDiff.size()); - delete mgr; - return 1; -} -#endif +} \ No newline at end of file diff --git a/src/UserInterface/MarkManager.h b/src/UserInterface/MarkManager.h index 3240112..8bb3a9f 100644 --- a/src/UserInterface/MarkManager.h +++ b/src/UserInterface/MarkManager.h @@ -53,6 +53,7 @@ class CGuildMarkManager : public singleton // CLIENT bool SaveBlockFromCompressedData(DWORD imgIdx, DWORD idBlock, const uint8_t * pbBlock, DWORD dwSize); bool GetBlockCRCList(DWORD imgIdx, uint32_t * crcList); + void ReloadMarkImage(DWORD imgIdx); private: // diff --git a/src/UserInterface/PythonNetworkStreamPhaseGame.cpp b/src/UserInterface/PythonNetworkStreamPhaseGame.cpp index 021d4aa..5fbae95 100644 --- a/src/UserInterface/PythonNetworkStreamPhaseGame.cpp +++ b/src/UserInterface/PythonNetworkStreamPhaseGame.cpp @@ -2,6 +2,7 @@ #include "PythonNetworkStream.h" #include "Packet.h" #include "GuildMarkDownloader.h" +#include "MarkManager.h" #include "PythonGuild.h" #include "PythonCharacterManager.h" @@ -3603,6 +3604,8 @@ bool CPythonNetworkStream::RecvMarkUpdate() Tracef(" >> RecvMarkUpdate: guildID=%u, imgIdx=%u\n", packet.guildID, packet.imgIdx); + CGuildMarkManager::Instance().ReloadMarkImage(packet.imgIdx); + // Rate limit mark downloads to prevent connection spam from multiple simultaneous guild uploads // Allow at most one download request per 1 second from server-pushed updates DWORD dwCurrentTime = ELTimer_GetMSec(); diff --git a/src/UserInterface/PythonTextTail.cpp b/src/UserInterface/PythonTextTail.cpp index 54a7f1b..23167d9 100644 --- a/src/UserInterface/PythonTextTail.cpp +++ b/src/UserInterface/PythonTextTail.cpp @@ -925,10 +925,28 @@ void CPythonTextTail::RefreshAllGuildMark() { TTextTail* pTextTail = itor->second; + CInstanceBase* pInstance = CPythonCharacterManager::Instance().GetInstancePtr(itor->first); + if (!pInstance) + continue; + + DWORD dwGuildID = pInstance->GetGuildID(); + if (dwGuildID == 0) + continue; + if (!pTextTail->pMarkInstance) continue; - // Re-load the mark instance to get the updated texture + DWORD dwMarkID = CGuildMarkManager::Instance().GetMarkID(dwGuildID); + if (dwMarkID != CGuildMarkManager::INVALID_MARK_ID) + { + std::string markImagePath; + if (CGuildMarkManager::Instance().GetMarkImageFilename(dwMarkID / CGuildMarkImage::MARK_TOTAL_COUNT, markImagePath)) + { + pTextTail->pMarkInstance->SetImageFileName(markImagePath.c_str()); + pTextTail->pMarkInstance->SetIndex(dwMarkID % CGuildMarkImage::MARK_TOTAL_COUNT); + } + } + pTextTail->pMarkInstance->Load(); }