453 lines
9.5 KiB
C++
453 lines
9.5 KiB
C++
#include "StdAfx.h"
|
|
#include "GuildMarkUploader.h"
|
|
#include "Packet.h"
|
|
|
|
#include "stb_image.h"
|
|
#include "stb_image_write.h"
|
|
|
|
#ifdef __VTUNE__
|
|
#else
|
|
|
|
CGuildMarkUploader::CGuildMarkUploader()
|
|
: m_pbySymbolBuf(NULL)
|
|
{
|
|
SetRecvBufferSize(1024);
|
|
SetSendBufferSize(1024);
|
|
__Inialize();
|
|
}
|
|
|
|
CGuildMarkUploader::~CGuildMarkUploader()
|
|
{
|
|
__OfflineState_Set();
|
|
}
|
|
|
|
void CGuildMarkUploader::Disconnect()
|
|
{
|
|
__OfflineState_Set();
|
|
}
|
|
|
|
bool CGuildMarkUploader::IsCompleteUploading()
|
|
{
|
|
return STATE_OFFLINE == m_eState;
|
|
}
|
|
|
|
bool CGuildMarkUploader::__Save(const char* c_szFileName)
|
|
{
|
|
/*
|
|
int width = CGuildMarkImage::WIDTH;
|
|
int height = CGuildMarkImage::HEIGHT;
|
|
std::vector<unsigned char> rgba(width * height * 4);
|
|
|
|
for (int i = 0; i < width * height; ++i) {
|
|
rgba[i * 4 + 0] = m_kMark.m_apxBuf[i * 4 + 2]; // R
|
|
rgba[i * 4 + 1] = m_kMark.m_apxBuf[i * 4 + 1]; // G
|
|
rgba[i * 4 + 2] = m_kMark.m_apxBuf[i * 4 + 0]; // B
|
|
rgba[i * 4 + 3] = m_kMark.m_apxBuf[i * 4 + 3]; // A
|
|
}
|
|
|
|
// Save as PNG
|
|
if (!stbi_write_png(c_szFileName, width, height, 4, rgba.data(), width * 4)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
*/
|
|
return true;
|
|
}
|
|
|
|
bool CGuildMarkUploader::__Load(const char* c_szFileName, UINT* peError)
|
|
{
|
|
int width, height, channels;
|
|
unsigned char* data = stbi_load(c_szFileName, &width, &height, &channels, 4); // force RGBA
|
|
|
|
if (!data) {
|
|
*peError = ERROR_LOAD;
|
|
return false;
|
|
}
|
|
|
|
if (width != SGuildMark::WIDTH) {
|
|
stbi_image_free(data);
|
|
*peError = ERROR_WIDTH;
|
|
return false;
|
|
}
|
|
|
|
if (height != SGuildMark::HEIGHT) {
|
|
stbi_image_free(data);
|
|
*peError = ERROR_HEIGHT;
|
|
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);
|
|
}
|
|
|
|
stbi_image_free(data);
|
|
return true;
|
|
}
|
|
|
|
bool CGuildMarkUploader::__LoadSymbol(const char* c_szFileName, UINT* peError)
|
|
{
|
|
int width, height, channels;
|
|
unsigned char* data = stbi_load(c_szFileName, &width, &height, &channels, 4);
|
|
|
|
if (!data) {
|
|
*peError = ERROR_LOAD;
|
|
return false;
|
|
}
|
|
|
|
if (width != 64) {
|
|
stbi_image_free(data);
|
|
*peError = ERROR_WIDTH;
|
|
return false;
|
|
}
|
|
|
|
if (height != 128) {
|
|
stbi_image_free(data);
|
|
*peError = ERROR_HEIGHT;
|
|
return false;
|
|
}
|
|
|
|
stbi_image_free(data);
|
|
|
|
// Now read raw file into m_pbySymbolBuf (same as original code did)
|
|
FILE* file = fopen(c_szFileName, "rb");
|
|
if (!file) {
|
|
*peError = ERROR_LOAD;
|
|
return false;
|
|
}
|
|
|
|
fseek(file, 0, SEEK_END);
|
|
m_dwSymbolBufSize = ftell(file);
|
|
fseek(file, 0, SEEK_SET);
|
|
|
|
m_pbySymbolBuf = new uint8_t[m_dwSymbolBufSize];
|
|
fread(m_pbySymbolBuf, m_dwSymbolBufSize, 1, file);
|
|
fclose(file);
|
|
|
|
m_dwSymbolCRC32 = GetFileCRC32(c_szFileName);
|
|
return true;
|
|
}
|
|
|
|
bool CGuildMarkUploader::Connect(const CNetworkAddress& c_rkNetAddr, DWORD dwHandle, DWORD dwRandomKey, DWORD dwGuildID, const char* c_szFileName, UINT* peError)
|
|
{
|
|
__OfflineState_Set();
|
|
SetRecvBufferSize(1024);
|
|
SetSendBufferSize(1024);
|
|
|
|
if (!CNetworkStream::Connect(c_rkNetAddr))
|
|
{
|
|
*peError=ERROR_CONNECT;
|
|
return false;
|
|
}
|
|
|
|
m_dwSendType=SEND_TYPE_MARK;
|
|
m_dwHandle=dwHandle;
|
|
m_dwRandomKey=dwRandomKey;
|
|
m_dwGuildID=dwGuildID;
|
|
|
|
if (!__Load(c_szFileName, peError))
|
|
return false;
|
|
|
|
//if (!__Save(CGraphicMarkInstance::GetImageFileName().c_str()))
|
|
// return false;
|
|
//CGraphicMarkInstance::ReloadImageFile();
|
|
return true;
|
|
}
|
|
|
|
bool CGuildMarkUploader::ConnectToSendSymbol(const CNetworkAddress& c_rkNetAddr, DWORD dwHandle, DWORD dwRandomKey, DWORD dwGuildID, const char* c_szFileName, UINT* peError)
|
|
{
|
|
__OfflineState_Set();
|
|
SetRecvBufferSize(1024);
|
|
SetSendBufferSize(64*1024);
|
|
|
|
if (!CNetworkStream::Connect(c_rkNetAddr))
|
|
{
|
|
*peError=ERROR_CONNECT;
|
|
return false;
|
|
}
|
|
|
|
m_dwSendType=SEND_TYPE_SYMBOL;
|
|
m_dwHandle=dwHandle;
|
|
m_dwRandomKey=dwRandomKey;
|
|
m_dwGuildID=dwGuildID;
|
|
|
|
if (!__LoadSymbol(c_szFileName, peError))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void CGuildMarkUploader::Process()
|
|
{
|
|
CNetworkStream::Process();
|
|
|
|
if (!__StateProcess())
|
|
{
|
|
__OfflineState_Set();
|
|
Disconnect();
|
|
}
|
|
}
|
|
|
|
void CGuildMarkUploader::OnConnectFailure()
|
|
{
|
|
__OfflineState_Set();
|
|
}
|
|
|
|
void CGuildMarkUploader::OnConnectSuccess()
|
|
{
|
|
__LoginState_Set();
|
|
}
|
|
|
|
void CGuildMarkUploader::OnRemoteDisconnect()
|
|
{
|
|
__OfflineState_Set();
|
|
}
|
|
|
|
void CGuildMarkUploader::OnDisconnect()
|
|
{
|
|
__OfflineState_Set();
|
|
}
|
|
|
|
void CGuildMarkUploader::__Inialize()
|
|
{
|
|
m_eState = STATE_OFFLINE;
|
|
|
|
m_dwGuildID = 0;
|
|
m_dwHandle = 0;
|
|
m_dwRandomKey = 0;
|
|
|
|
if (m_pbySymbolBuf)
|
|
{
|
|
delete[] m_pbySymbolBuf;
|
|
}
|
|
|
|
m_dwSymbolBufSize = 0;
|
|
m_pbySymbolBuf = NULL;
|
|
}
|
|
|
|
bool CGuildMarkUploader::__StateProcess()
|
|
{
|
|
switch (m_eState)
|
|
{
|
|
case STATE_LOGIN:
|
|
return __LoginState_Process();
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void CGuildMarkUploader::__OfflineState_Set()
|
|
{
|
|
__Inialize();
|
|
}
|
|
|
|
void CGuildMarkUploader::__CompleteState_Set()
|
|
{
|
|
m_eState=STATE_COMPLETE;
|
|
|
|
__OfflineState_Set();
|
|
}
|
|
|
|
|
|
void CGuildMarkUploader::__LoginState_Set()
|
|
{
|
|
m_eState=STATE_LOGIN;
|
|
}
|
|
|
|
bool CGuildMarkUploader::__LoginState_Process()
|
|
{
|
|
if (!__AnalyzePacket(HEADER_GC_PHASE, sizeof(TPacketGCPhase), &CGuildMarkUploader::__LoginState_RecvPhase))
|
|
return false;
|
|
|
|
if (!__AnalyzePacket(HEADER_GC_HANDSHAKE, sizeof(TPacketGCHandshake), &CGuildMarkUploader::__LoginState_RecvHandshake))
|
|
return false;
|
|
|
|
if (!__AnalyzePacket(HEADER_GC_PING, sizeof(TPacketGCPing), &CGuildMarkUploader::__LoginState_RecvPing))
|
|
return false;
|
|
|
|
if (!__AnalyzePacket(HEADER_GC_KEY_CHALLENGE, sizeof(TPacketGCKeyChallenge), &CGuildMarkUploader::__LoginState_RecvKeyChallenge))
|
|
return false;
|
|
|
|
if (!__AnalyzePacket(HEADER_GC_KEY_COMPLETE, sizeof(TPacketGCKeyComplete), &CGuildMarkUploader::__LoginState_RecvKeyComplete))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CGuildMarkUploader::__SendMarkPacket()
|
|
{
|
|
TPacketCGMarkUpload kPacketMarkUpload;
|
|
kPacketMarkUpload.header=HEADER_CG_MARK_UPLOAD;
|
|
kPacketMarkUpload.gid=m_dwGuildID;
|
|
|
|
assert(sizeof(kPacketMarkUpload.image) == sizeof(m_kMark.m_apxBuf));
|
|
memcpy(kPacketMarkUpload.image, m_kMark.m_apxBuf, sizeof(kPacketMarkUpload.image));
|
|
|
|
if (!Send(sizeof(kPacketMarkUpload), &kPacketMarkUpload))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
bool CGuildMarkUploader::__SendSymbolPacket()
|
|
{
|
|
if (!m_pbySymbolBuf)
|
|
return false;
|
|
|
|
TPacketCGSymbolUpload kPacketSymbolUpload;
|
|
kPacketSymbolUpload.header=HEADER_CG_GUILD_SYMBOL_UPLOAD;
|
|
kPacketSymbolUpload.handle=m_dwGuildID;
|
|
kPacketSymbolUpload.size=sizeof(TPacketCGSymbolUpload) + m_dwSymbolBufSize;
|
|
|
|
if (!Send(sizeof(TPacketCGSymbolUpload), &kPacketSymbolUpload))
|
|
return false;
|
|
if (!Send(m_dwSymbolBufSize, m_pbySymbolBuf))
|
|
return false;
|
|
|
|
#ifdef _DEBUG
|
|
printf("__SendSymbolPacket : [GuildID:%d/PacketSize:%d/BufSize:%d/CRC:%d]\n", m_dwGuildID, kPacketSymbolUpload.size, m_dwSymbolBufSize, m_dwSymbolCRC32);
|
|
#endif
|
|
|
|
CNetworkStream::__SendInternalBuffer();
|
|
__CompleteState_Set();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CGuildMarkUploader::__LoginState_RecvPhase()
|
|
{
|
|
TPacketGCPhase kPacketPhase;
|
|
if (!Recv(sizeof(kPacketPhase), &kPacketPhase))
|
|
return false;
|
|
|
|
if (kPacketPhase.phase==PHASE_LOGIN)
|
|
{
|
|
if (SEND_TYPE_MARK == m_dwSendType)
|
|
{
|
|
if (!__SendMarkPacket())
|
|
return false;
|
|
}
|
|
else if (SEND_TYPE_SYMBOL == m_dwSendType)
|
|
{
|
|
if (!__SendSymbolPacket())
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CGuildMarkUploader::__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 CGuildMarkUploader::__LoginState_RecvPing()
|
|
{
|
|
TPacketGCPing kPacketPing;
|
|
if (!Recv(sizeof(kPacketPing), &kPacketPing))
|
|
return false;
|
|
|
|
TPacketCGPong kPacketPong;
|
|
kPacketPong.bHeader = HEADER_CG_PONG;
|
|
kPacketPong.bSequence = GetNextSequence();
|
|
|
|
if (!Send(sizeof(TPacketCGPong), &kPacketPong))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CGuildMarkUploader::__LoginState_RecvKeyChallenge()
|
|
{
|
|
TPacketGCKeyChallenge packet;
|
|
if (!Recv(sizeof(packet), &packet))
|
|
return false;
|
|
|
|
Tracen("KEY_CHALLENGE RECV");
|
|
|
|
SecureCipher& cipher = GetSecureCipher();
|
|
if (!cipher.Initialize())
|
|
{
|
|
Disconnect();
|
|
return false;
|
|
}
|
|
|
|
if (!cipher.ComputeClientKeys(packet.server_pk))
|
|
{
|
|
Disconnect();
|
|
return false;
|
|
}
|
|
|
|
TPacketCGKeyResponse response;
|
|
response.bHeader = HEADER_CG_KEY_RESPONSE;
|
|
cipher.GetPublicKey(response.client_pk);
|
|
cipher.ComputeResponse(packet.challenge, response.challenge_response);
|
|
|
|
if (!Send(sizeof(response), &response))
|
|
return false;
|
|
|
|
Tracen("KEY_RESPONSE SENT");
|
|
return true;
|
|
}
|
|
|
|
bool CGuildMarkUploader::__LoginState_RecvKeyComplete()
|
|
{
|
|
TPacketGCKeyComplete packet;
|
|
if (!Recv(sizeof(packet), &packet))
|
|
return false;
|
|
|
|
Tracen("KEY_COMPLETE RECV");
|
|
|
|
SecureCipher& cipher = GetSecureCipher();
|
|
|
|
uint8_t session_token[SecureCipher::SESSION_TOKEN_SIZE];
|
|
if (!cipher.DecryptToken(packet.encrypted_token, sizeof(packet.encrypted_token),
|
|
packet.nonce, session_token))
|
|
{
|
|
Disconnect();
|
|
return false;
|
|
}
|
|
|
|
cipher.SetSessionToken(session_token);
|
|
cipher.SetActivated(true);
|
|
|
|
Tracen("SECURE CIPHER ACTIVATED");
|
|
return true;
|
|
}
|
|
|
|
bool CGuildMarkUploader::__AnalyzePacket(UINT uHeader, UINT uPacketSize, bool (CGuildMarkUploader::*pfnDispatchPacket)())
|
|
{
|
|
BYTE bHeader;
|
|
if (!Peek(sizeof(bHeader), &bHeader))
|
|
return true;
|
|
|
|
if (bHeader!=uHeader)
|
|
return true;
|
|
|
|
if (!Peek(uPacketSize))
|
|
return true;
|
|
|
|
return (this->*pfnDispatchPacket)();
|
|
}
|
|
#endif
|