Files
LGram16 dd97ddec92 Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code:
- Client: Game client source (moved to Client/Client/)
- Server: Game server source
- GameTools: Development tools
- CryptoSource: Encryption utilities
- database: Database scripts
- Script: Game scripts
- rylCoder_16.02.2008_src: Legacy coder tools
- GMFont, Game: Additional resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 20:17:20 +09:00

233 lines
7.8 KiB
C++

#include "stdafx.h"
#include "WrapPacket.h"
#include "PacketStatistics.h"
#include <Log/ServerLog.h>
#include <Stream/Buffer/Buffer.h>
#include <Network/XORCrypt/XORCrypt.h>
#include <Utility/Compress/MiniLZO/MiniLZOWrapper.h>
bool PacketWrap::WrapHeader(CBuffer* lpBuffer_In, unsigned short usUsed_In, unsigned char cCMD_In,
unsigned short usState_In, unsigned short usError_In)
{
if (WrapHeader(lpBuffer_In->wr_ptr(), usUsed_In, cCMD_In, usState_In, usError_In))
{
lpBuffer_In->wr_ptr(usUsed_In);
return true;
}
return false;
}
bool PacketWrap::WrapCryptOld(CBuffer* lpBuffer_In, unsigned short usUsed_In, unsigned char cCMD_In,
unsigned short usState_In, unsigned short usError_In)
{
if (WrapCryptOld(lpBuffer_In->wr_ptr(), usUsed_In, cCMD_In, usState_In, usError_In))
{
lpBuffer_In->wr_ptr(usUsed_In);
return true;
}
return false;
}
bool PacketWrap::WrapCrypt(CBuffer* lpBuffer_In, unsigned short usUsed_In, unsigned char cCMD_In,
unsigned short usState_In, unsigned short usError_In)
{
if (WrapCrypt(lpBuffer_In->wr_ptr(), usUsed_In, cCMD_In, usState_In, usError_In))
{
lpBuffer_In->wr_ptr(usUsed_In);
return true;
}
return false;
}
bool PacketWrap::WrapCompress(CBuffer* lpDstBuffer, const char* lpSourceData, unsigned short usSourceLength,
unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In)
{
char* lpBuffer = lpDstBuffer->wr_ptr();
unsigned long dwDstBufferSize_InOut = static_cast<unsigned long>(lpDstBuffer->remain());
if (WrapCompress(lpBuffer, dwDstBufferSize_InOut,
lpSourceData, usSourceLength, cCMD_In, usState_In, usError_In))
{
// 압축된 길이를 알아야 하기 때문.
lpDstBuffer->wr_ptr(dwDstBufferSize_InOut);
return true;
}
return false;
}
bool PacketWrap::WrapHeader(char* lpBuffer_In, unsigned short usUsed_In,
unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In)
{
reinterpret_cast<PktBase*>(lpBuffer_In)->InitPtHead(usUsed_In, cCMD_In, usState_In, usError_In);
CXORCrypt::GetInstance().EncodeHeader(lpBuffer_In + 1, sizeof(PktBase) - 1, 0, 0);
return true;
}
bool PacketWrap::WrapCryptOld(char* lpBuffer_In, unsigned short usUsed_In,
unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In)
{
CXORCrypt& Crypt = CXORCrypt::GetInstance();
unsigned long dwCodePage = Crypt.GetCodePage(1);
if(Crypt.EncodePacket(lpBuffer_In + sizeof(PktBase), usUsed_In - sizeof(PktBase), dwCodePage))
{
PktBase* lpPktBase = reinterpret_cast<PktBase*>(lpBuffer_In);
lpPktBase->InitPtHead(usUsed_In, cCMD_In, usState_In, usError_In);
lpPktBase->SetCodePage(dwCodePage);
lpPktBase->SetCrypt();
// 헤더 인코딩
Crypt.EncodeHeader(lpBuffer_In + 1, sizeof(PktBase) - 1, 0, 0);
return true;
}
return false;
}
bool PacketWrap::WrapCryptOld(char* lpBuffer_In, unsigned short usUsed_In,
unsigned char cCMD_In, unsigned long dwTick)
{
CXORCrypt& Crypt = CXORCrypt::GetInstance();
unsigned long dwCodePage = Crypt.GetCodePage(1);
if(Crypt.EncodePacket(lpBuffer_In + sizeof(PktBase), usUsed_In - sizeof(PktBase), dwCodePage))
{
PktBase* lpPktBase = reinterpret_cast<PktBase*>(lpBuffer_In);
lpPktBase->InitPtHead(usUsed_In, cCMD_In, dwTick);
lpPktBase->SetCodePage(dwCodePage);
lpPktBase->SetCrypt();
// 헤더 인코딩
Crypt.EncodeHeader(lpBuffer_In + 1, sizeof(PktBase) - 1, 0, 0);
return true;
}
return false;
}
bool PacketWrap::WrapCrypt(char* lpBuffer_In, unsigned short usUsed_In,
unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In)
{
CXORCrypt& Crypt = CXORCrypt::GetInstance();
unsigned long dwCodePage = Crypt.GetCodePage();
if(Crypt.EncodePacket(lpBuffer_In + sizeof(PktBase), usUsed_In - sizeof(PktBase), dwCodePage))
{
PktBase* lpPktBase = reinterpret_cast<PktBase*>(lpBuffer_In);
lpPktBase->InitPtHead(usUsed_In, cCMD_In, usState_In, usError_In);
lpPktBase->SetCodePage(dwCodePage);
lpPktBase->SetCrypt();
// 헤더 인코딩
Crypt.EncodeHeader(lpBuffer_In + 1, sizeof(PktBase) - 1, 0, 0);
return true;
}
return false;
}
bool PacketWrap::WrapCrypt(char* lpBuffer_In, unsigned short usUsed_In,
unsigned char cCMD_In, unsigned long dwTick)
{
CXORCrypt& Crypt = CXORCrypt::GetInstance();
unsigned long dwCodePage = Crypt.GetCodePage();
if(Crypt.EncodePacket(lpBuffer_In + sizeof(PktBase), usUsed_In - sizeof(PktBase), dwCodePage))
{
PktBase* lpPktBase = reinterpret_cast<PktBase*>(lpBuffer_In);
lpPktBase->InitPtHead(usUsed_In, cCMD_In, dwTick);
lpPktBase->SetCodePage(dwCodePage);
lpPktBase->SetCrypt();
// 헤더 인코딩
Crypt.EncodeHeader(lpBuffer_In + 1, sizeof(PktBase) - 1, 0, 0);
return true;
}
return false;
}
bool PacketWrap::WrapCompress(char* lpDstBuffer, unsigned long& dwDstBufferSize_InOut,
const char* lpSourceData, unsigned short usSourceLength,
unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In)
{
if(usSourceLength < sizeof(PktBase) || PktMaxLen < usSourceLength)
{
// 패킷 크기가 헤더 크기보다 작거나, 소스 크기가 최대 패킷 길이보다 큰 경우
ERRLOG2(g_Log, "Cmd:0x%02x Invalid packet size, Can't compress now.",
reinterpret_cast<const PktBase*>(lpSourceData)->GetCmd(), usSourceLength);
}
else if(dwDstBufferSize_InOut < usSourceLength)
{
// 압축할 버퍼 크기가 소스 크기보다 작은 경우
SERLOG1(g_Log, "Cmd:0x%02x Insufficient buffer size, Can't compress now.",
reinterpret_cast<const PktBase*>(lpSourceData)->GetCmd());
}
else
{
unsigned long dwArchiveSrcLen = usSourceLength - sizeof(PktBase);
unsigned long dwArchiveDstLen = dwDstBufferSize_InOut - sizeof(PktBase);
bool bCompressResult =
CMiniLZO::Compress(lpSourceData + sizeof(PktBase), dwArchiveSrcLen,
lpDstBuffer + sizeof(PktBase), &dwArchiveDstLen);
// 전체 버퍼 크기를 맞춘다.
dwArchiveDstLen += sizeof(PktBase);
if (!bCompressResult)
{
// 압축 실패 로그를 남긴다.
SERLOG2(g_Log, "Cmd:0x%02x Packet compress failed. Packet length is %d.",
reinterpret_cast<const PktBase*>(lpSourceData)->GetCmd(), usSourceLength);
}
else
{
// 압축후 패킷 통계를 낸다. 패킷 커맨드, 원본 크기, 압축본 크기를 넘긴다.
CPacketStatistics::GetInstance().CheckCompression(cCMD_In,
usSourceLength, dwArchiveDstLen);
}
if (!bCompressResult || usSourceLength <= dwArchiveDstLen)
{
// 압축에 실패했거나, 압축한 후 크기가 같거나, 오히려 더 커진 경우이다
// 데이터를 복사한 후에, WrapCrypt로 다시 작업한다.
memcpy(lpDstBuffer, lpSourceData, usSourceLength);
dwDstBufferSize_InOut = usSourceLength;
return PacketWrap::WrapCrypt(lpDstBuffer, usSourceLength,
cCMD_In, usState_In, usError_In);
}
else
{
PktBase* lpPktDst = reinterpret_cast<PktBase*>(lpDstBuffer);
lpPktDst->InitPtHead(static_cast<PktBase::LengthType>(dwArchiveDstLen),
cCMD_In, usState_In, usError_In);
lpPktDst->SetCompress();
// 헤더 인코딩
CXORCrypt::GetInstance().EncodeHeader(lpDstBuffer + 1, sizeof(PktBase) - 1, 0, 0);
dwDstBufferSize_InOut = dwArchiveDstLen;
return true;
}
}
return false;
}