forked from metin2/client
454 lines
9.7 KiB
C++
454 lines
9.7 KiB
C++
#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;
|
||
}
|