client/UserInterface/GuildMarkDownloader.cpp

454 lines
9.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "StdAfx.h"
#include "GuildMarkDownloader.h"
#include "PythonCharacterManager.h"
#include "Packet.h"
#include "Test.h"
// MARK_BUG_FIX
struct SMarkIndex
{
WORD guild_id;
WORD mark_id;
};
// END_OFMARK_BUG_FIX
CGuildMarkDownloader::CGuildMarkDownloader()
{
SetRecvBufferSize(640*1024);
SetSendBufferSize(1024);
__Initialize();
}
CGuildMarkDownloader::~CGuildMarkDownloader()
{
__OfflineState_Set();
}
bool CGuildMarkDownloader::Connect(const CNetworkAddress& c_rkNetAddr, DWORD dwHandle, DWORD dwRandomKey)
{
__OfflineState_Set();
m_dwHandle=dwHandle;
m_dwRandomKey=dwRandomKey;
m_dwTodo=TODO_RECV_MARK;
return CNetworkStream::Connect(c_rkNetAddr);
}
bool CGuildMarkDownloader::ConnectToRecvSymbol(const CNetworkAddress& c_rkNetAddr, DWORD dwHandle, DWORD dwRandomKey, const std::vector<DWORD> & c_rkVec_dwGuildID)
{
__OfflineState_Set();
m_dwHandle=dwHandle;
m_dwRandomKey=dwRandomKey;
m_dwTodo=TODO_RECV_SYMBOL;
m_kVec_dwGuildID = c_rkVec_dwGuildID;
return CNetworkStream::Connect(c_rkNetAddr);
}
void CGuildMarkDownloader::Process()
{
CNetworkStream::Process();
if (!__StateProcess())
{
__OfflineState_Set();
Disconnect();
}
}
void CGuildMarkDownloader::OnConnectFailure()
{
__OfflineState_Set();
}
void CGuildMarkDownloader::OnConnectSuccess()
{
__LoginState_Set();
}
void CGuildMarkDownloader::OnRemoteDisconnect()
{
__OfflineState_Set();
}
void CGuildMarkDownloader::OnDisconnect()
{
__OfflineState_Set();
}
void CGuildMarkDownloader::__Initialize()
{
m_eState=STATE_OFFLINE;
m_pkMarkMgr=NULL;
m_currentRequestingImageIndex=0;
m_dwBlockIndex=0;
m_dwBlockDataPos=0;
m_dwBlockDataSize=0;
m_dwHandle=0;
m_dwRandomKey=0;
m_dwTodo=TODO_RECV_NONE;
m_kVec_dwGuildID.clear();
}
bool CGuildMarkDownloader::__StateProcess()
{
switch (m_eState)
{
case STATE_LOGIN:
return __LoginState_Process();
break;
case STATE_COMPLETE:
return false;
}
return true;
}
void CGuildMarkDownloader::__OfflineState_Set()
{
__Initialize();
}
void CGuildMarkDownloader::__CompleteState_Set()
{
m_eState = STATE_COMPLETE;
CPythonCharacterManager::instance().RefreshAllGuildMark();
}
void CGuildMarkDownloader::__LoginState_Set()
{
m_eState = STATE_LOGIN;
}
bool CGuildMarkDownloader::__LoginState_Process()
{
BYTE header;
if (!Peek(sizeof(BYTE), &header))
return true;
UINT needPacketSize = __GetPacketSize(header);
if (!needPacketSize)
return false;
if (!Peek(needPacketSize))
return true;
__DispatchPacket(header);
return true;
}
// MARK_BUG_FIX
UINT CGuildMarkDownloader::__GetPacketSize(UINT header)
{
switch (header)
{
case HEADER_GC_PHASE:
return sizeof(TPacketGCPhase);
case HEADER_GC_HANDSHAKE:
return sizeof(TPacketGCHandshake);
case HEADER_GC_PING:
return sizeof(TPacketGCPing);
case HEADER_GC_MARK_IDXLIST:
return sizeof(TPacketGCMarkIDXList);
case HEADER_GC_MARK_BLOCK:
return sizeof(TPacketGCMarkBlock);
case HEADER_GC_GUILD_SYMBOL_DATA:
return sizeof(TPacketGCGuildSymbolData);
case HEADER_GC_MARK_DIFF_DATA: // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
return sizeof(BYTE);
}
return 0;
}
bool CGuildMarkDownloader::__DispatchPacket(UINT header)
{
switch (header)
{
case HEADER_GC_PHASE:
return __LoginState_RecvPhase();
case HEADER_GC_HANDSHAKE:
return __LoginState_RecvHandshake();
case HEADER_GC_PING:
return __LoginState_RecvPing();
case HEADER_GC_MARK_IDXLIST:
return __LoginState_RecvMarkIndex();
case HEADER_GC_MARK_BLOCK:
return __LoginState_RecvMarkBlock();
case HEADER_GC_GUILD_SYMBOL_DATA:
return __LoginState_RecvSymbolData();
case HEADER_GC_MARK_DIFF_DATA: // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
return true;
}
return false;
}
// END_OF_MARK_BUG_FIX
bool CGuildMarkDownloader::__LoginState_RecvHandshake()
{
TPacketGCHandshake kPacketHandshake;
if (!Recv(sizeof(kPacketHandshake), &kPacketHandshake))
return false;
TPacketCGMarkLogin kPacketMarkLogin;
kPacketMarkLogin.header = HEADER_CG_MARK_LOGIN;
kPacketMarkLogin.handle = m_dwHandle;
kPacketMarkLogin.random_key = m_dwRandomKey;
if (!Send(sizeof(kPacketMarkLogin), &kPacketMarkLogin))
return false;
return true;
}
bool CGuildMarkDownloader::__LoginState_RecvPing()
{
TPacketGCPing kPacketPing;
if (!Recv(sizeof(kPacketPing), &kPacketPing))
return false;
TPacketCGPong kPacketPong;
kPacketPong.bHeader = HEADER_CG_PONG;
if (!Send(sizeof(TPacketCGPong), &kPacketPong))
return false;
return SendSequence();
}
bool CGuildMarkDownloader::__LoginState_RecvPhase()
{
TPacketGCPhase kPacketPhase;
if (!Recv(sizeof(kPacketPhase), &kPacketPhase))
return false;
if (kPacketPhase.phase == PHASE_LOGIN)
{
switch (m_dwTodo)
{
case TODO_RECV_NONE:
{
assert(!"CGuildMarkDownloader::__LoginState_RecvPhase - Todo type is none");
break;
}
case TODO_RECV_MARK:
{
// MARK_BUG_FIX
if (!__SendMarkIDXList())
return false;
// END_OF_MARK_BUG_FIX
break;
}
case TODO_RECV_SYMBOL:
{
if (!__SendSymbolCRCList())
return false;
break;
}
}
}
return true;
}
// MARK_BUG_FIX
bool CGuildMarkDownloader::__SendMarkIDXList()
{
TPacketCGMarkIDXList kPacketMarkIDXList;
kPacketMarkIDXList.header = HEADER_CG_MARK_IDXLIST;
if (!Send(sizeof(kPacketMarkIDXList), &kPacketMarkIDXList))
return false;
return true;
}
bool CGuildMarkDownloader::__LoginState_RecvMarkIndex()
{
TPacketGCMarkIDXList kPacketMarkIndex;
if (!Peek(sizeof(kPacketMarkIndex), &kPacketMarkIndex))
return false;
//DWORD bufSize = sizeof(WORD) * 2 * kPacketMarkIndex.count;
if (!Peek(kPacketMarkIndex.bufSize))
return false;
Recv(sizeof(kPacketMarkIndex));
WORD guildID, markID;
for (DWORD i = 0; i < kPacketMarkIndex.count; ++i)
{
Recv(sizeof(WORD), &guildID);
Recv(sizeof(WORD), &markID);
// <20><><EFBFBD><EFBFBD>ID -> <20><>ũID <20>ε<EFBFBD><CEB5><EFBFBD> <20><><EFBFBD><EFBFBD>
CGuildMarkManager::Instance().AddMarkIDByGuildID(guildID, markID);
}
// <20><><EFBFBD><EFBFBD> <20><>ũ <20>̹<EFBFBD><CCB9><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5>Ѵ<EFBFBD>. (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
CGuildMarkManager::Instance().LoadMarkImages();
m_currentRequestingImageIndex = 0;
__SendMarkCRCList();
return true;
}
bool CGuildMarkDownloader::__SendMarkCRCList()
{
TPacketCGMarkCRCList kPacketMarkCRCList;
if (!CGuildMarkManager::Instance().GetBlockCRCList(m_currentRequestingImageIndex, kPacketMarkCRCList.crclist))
__CompleteState_Set();
else
{
kPacketMarkCRCList.header = HEADER_CG_MARK_CRCLIST;
kPacketMarkCRCList.imgIdx = m_currentRequestingImageIndex;
++m_currentRequestingImageIndex;
if (!Send(sizeof(kPacketMarkCRCList), &kPacketMarkCRCList))
return false;
}
return true;
}
bool CGuildMarkDownloader::__LoginState_RecvMarkBlock()
{
TPacketGCMarkBlock kPacket;
if (!Peek(sizeof(kPacket), &kPacket))
return false;
if (!Peek(kPacket.bufSize))
return false;
Recv(sizeof(kPacket));
BYTE posBlock;
DWORD compSize;
char compBuf[SGuildMarkBlock::MAX_COMP_SIZE];
for (DWORD i = 0; i < kPacket.count; ++i)
{
Recv(sizeof(BYTE), &posBlock);
Recv(sizeof(DWORD), &compSize);
if (compSize > SGuildMarkBlock::MAX_COMP_SIZE)
{
TraceError("RecvMarkBlock: data corrupted");
Recv(compSize);
}
else
{
Recv(compSize, compBuf);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̹<EFBFBD><CCB9><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>. CRC<52><43> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Բ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD>.
CGuildMarkManager::Instance().SaveBlockFromCompressedData(kPacket.imgIdx, posBlock, (const BYTE *) compBuf, compSize);
}
}
if (kPacket.count > 0)
{
// <20><>ũ <20>̹<EFBFBD><CCB9><EFBFBD> <20><><EFBFBD><EFBFBD>
CGuildMarkManager::Instance().SaveMarkImage(kPacket.imgIdx);
// <20><><EFBFBD>ҽ<EFBFBD> <20><><EFBFBD>ε<EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ص<EFBFBD> <20><><EFBFBD>ΰ<EFBFBD><CEB0><EFBFBD> <20><> <20><><EFBFBD>̰<EFBFBD> <20><>)
std::string imagePath;
if (CGuildMarkManager::Instance().GetMarkImageFilename(kPacket.imgIdx, imagePath))
{
CResource * pResource = CResourceManager::Instance().GetResourcePointer(imagePath.c_str());
if (pResource->IsType(CGraphicImage::Type()))
{
CGraphicImage* pkGrpImg=static_cast<CGraphicImage*>(pResource);
pkGrpImg->Reload();
}
}
}
// <20><> <20><>û<EFBFBD><C3BB> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>û<EFBFBD>ϰ<EFBFBD> <20>ƴϸ<C6B4> <20>̹<EFBFBD><CCB9><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD>
if (m_currentRequestingImageIndex < CGuildMarkManager::Instance().GetMarkImageCount())
__SendMarkCRCList();
else
__CompleteState_Set();
return true;
}
// END_OF_MARK_BUG_FIX
bool CGuildMarkDownloader::__SendSymbolCRCList()
{
for (DWORD i=0; i<m_kVec_dwGuildID.size(); ++i)
{
TPacketCGSymbolCRC kSymbolCRCPacket;
kSymbolCRCPacket.header = HEADER_CG_GUILD_SYMBOL_CRC;
kSymbolCRCPacket.dwGuildID = m_kVec_dwGuildID[i];
std::string strFileName = GetGuildSymbolFileName(m_kVec_dwGuildID[i]);
kSymbolCRCPacket.dwCRC = GetFileCRC32(strFileName.c_str());
kSymbolCRCPacket.dwSize = GetFileSize(strFileName.c_str());
#ifdef _DEBUG
printf("__SendSymbolCRCList [GuildID:%d / CRC:%u]\n", m_kVec_dwGuildID[i], kSymbolCRCPacket.dwCRC);
#endif
if (!Send(sizeof(kSymbolCRCPacket), &kSymbolCRCPacket))
return false;
}
return true;
}
bool CGuildMarkDownloader::__LoginState_RecvSymbolData()
{
TPacketGCBlankDynamic packet;
if (!Peek(sizeof(TPacketGCBlankDynamic), &packet))
return true;
#ifdef _DEBUG
printf("__LoginState_RecvSymbolData [%d/%d]\n", GetRecvBufferSize(), packet.size);
#endif
if (packet.size > GetRecvBufferSize())
return true;
//////////////////////////////////////////////////////////////
TPacketGCGuildSymbolData kPacketSymbolData;
if (!Recv(sizeof(kPacketSymbolData), &kPacketSymbolData))
return false;
WORD wDataSize = kPacketSymbolData.size - sizeof(kPacketSymbolData);
DWORD dwGuildID = kPacketSymbolData.guild_id;
BYTE * pbyBuf = new BYTE [wDataSize];
if (!Recv(wDataSize, pbyBuf))
{
delete[] pbyBuf;
return false;
}
MyCreateDirectory(g_strGuildSymbolPathName.c_str());
std::string strFileName = GetGuildSymbolFileName(dwGuildID);
FILE * File = fopen(strFileName.c_str(), "wb");
if (!File)
{
delete[] pbyBuf;
return false;
}
fwrite(pbyBuf, wDataSize, 1, File);
fclose(File);
#ifdef _DEBUG
printf("__LoginState_RecvSymbolData(filename:%s, datasize:%d, guildid:%d)\n", strFileName.c_str(), wDataSize, dwGuildID);
#endif
delete[] pbyBuf;
return true;
}