#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 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