Files
Client/Server/RylServerProject/RylServerLibrary/Network/ClientNetwork/NetworkMsgBlock.cpp
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

543 lines
14 KiB
C++

#include "stdafx.h"
#include "NetworkMsgBlock.h"
#include <Network/Packet/PacketBase.h>
#include <Network/XORCrypt/XORCrypt.h>
#include <Utility/Compress/MiniLZO/miniLZOWrapper.h>
#include <cstdio>
#include "GMMemory.h"
namespace ClientNet
{
CNetworkMsgBlock::CNetworkMsgBlock(size_t n)
: CMessageBlock(n), m_next(0),
m_eMsgType(NET_MSG_FREE), m_dwID(0)
{
}
CNetworkMsgBlock::CNetworkMsgBlock(size_t n, INET_Addr& addr)
: CMessageBlock(n), m_dstaddr(addr), m_next(0),
m_eMsgType(NET_MSG_FREE), m_dwID(0)
{
}
CNetworkMsgBlock::~CNetworkMsgBlock()
{
}
bool CNetworkMsgBlock::WrapHeader(unsigned short usUsed_In, unsigned char cCMD_In,
unsigned short usState_In, unsigned short usError_In)
{
char* lpBuffer = rd_ptr();
if(NULL != lpBuffer && sizeof(PktBase) <= usUsed_In && usUsed_In <= remain())
{
reinterpret_cast<PktBase*>(lpBuffer)->InitPtHead(usUsed_In, cCMD_In, usState_In, usError_In);
CXORCrypt::GetInstance().EncodeHeader(lpBuffer + 1, sizeof(PktBase) - 1, 0, 0);
wr_ptr(usUsed_In);
return true;
}
fprintf(stderr, "CNetworkMsgBlock::WrapHeader - Packet wrapping error. CMD:0x%02x, usUsed:%d, capacity:%d\n",
cCMD_In, usUsed_In, capacity());
return false;
}
bool CNetworkMsgBlock::WrapCryptOld(unsigned short usUsed_In, unsigned char cCMD_In,
unsigned long Tick_In)
{
char* lpBuffer = rd_ptr();
if(NULL != lpBuffer && sizeof(PktBase) <= usUsed_In && usUsed_In <= remain())
{
CXORCrypt& Crypt = CXORCrypt::GetInstance();
DWORD dwCodePage = Crypt.GetCodePage(1);
if(Crypt.EncodePacket(lpBuffer + sizeof(PktBase), usUsed_In - sizeof(PktBase), dwCodePage))
{
PktBase* lpPktBase = reinterpret_cast<PktBase*>(lpBuffer);
lpPktBase->InitPtHead(usUsed_In, cCMD_In, Tick_In);
lpPktBase->SetCodePage(dwCodePage);
lpPktBase->SetCrypt();
// Çì´õ ÀÎÄÚµù
Crypt.EncodeHeader(lpBuffer + 1, sizeof(PktBase) - 1, 0, 0);
wr_ptr(usUsed_In);
return true;
}
}
fprintf(stderr, "CNetworkMsgBlock::WrapCrypt - Packet wrapping error. CMD:0x%02x, usUsed:%d, capacity:%d\n",
cCMD_In, usUsed_In, capacity());
return false;
}
bool CNetworkMsgBlock::WrapCryptOld(unsigned short usUsed_In, unsigned char cCMD_In,
unsigned short usState_In, unsigned short usError_In)
{
char* lpBuffer = rd_ptr();
if(NULL != lpBuffer && sizeof(PktBase) <= usUsed_In && usUsed_In <= remain())
{
CXORCrypt& Crypt = CXORCrypt::GetInstance();
DWORD dwCodePage = Crypt.GetCodePage(1);
if(Crypt.EncodePacket(lpBuffer + sizeof(PktBase), usUsed_In - sizeof(PktBase), dwCodePage))
{
PktBase* lpPktBase = reinterpret_cast<PktBase*>(lpBuffer);
lpPktBase->InitPtHead(usUsed_In, cCMD_In, usState_In, usError_In);
lpPktBase->SetCodePage(dwCodePage);
lpPktBase->SetCrypt();
// Çì´õ ÀÎÄÚµù
Crypt.EncodeHeader(lpBuffer + 1, sizeof(PktBase) - 1, 0, 0);
wr_ptr(usUsed_In);
return true;
}
}
fprintf(stderr, "CNetworkMsgBlock::WrapCrypt - Packet wrapping error. CMD:0x%02x, usUsed:%d, capacity:%d\n",
cCMD_In, usUsed_In, capacity());
return false;
}
bool CNetworkMsgBlock::WrapCrypt(unsigned short usUsed_In, unsigned char cCMD_In,
unsigned long Tick_In)
{
char* lpBuffer = rd_ptr();
if(NULL != lpBuffer && sizeof(PktBase) <= usUsed_In && usUsed_In <= remain())
{
CXORCrypt& Crypt = CXORCrypt::GetInstance();
DWORD dwCodePage = Crypt.GetCodePage();
if(Crypt.EncodePacket(lpBuffer + sizeof(PktBase), usUsed_In - sizeof(PktBase), dwCodePage))
{
PktBase* lpPktBase = reinterpret_cast<PktBase*>(lpBuffer);
lpPktBase->InitPtHead(usUsed_In, cCMD_In, Tick_In);
lpPktBase->SetCodePage(dwCodePage);
lpPktBase->SetCrypt();
// Çì´õ ÀÎÄÚµù
Crypt.EncodeHeader(lpBuffer + 1, sizeof(PktBase) - 1, 0, 0);
wr_ptr(usUsed_In);
return true;
}
}
fprintf(stderr, "CNetworkMsgBlock::WrapCrypt - Packet wrapping error. CMD:0x%02x, usUsed:%d, capacity:%d\n",
cCMD_In, usUsed_In, capacity());
return false;
}
bool CNetworkMsgBlock::WrapCrypt(unsigned short usUsed_In, unsigned char cCMD_In,
unsigned short usState_In, unsigned short usError_In)
{
char* lpBuffer = rd_ptr();
if(NULL != lpBuffer && sizeof(PktBase) <= usUsed_In && usUsed_In <= remain())
{
CXORCrypt& Crypt = CXORCrypt::GetInstance();
DWORD dwCodePage = Crypt.GetCodePage();
if(Crypt.EncodePacket(lpBuffer + sizeof(PktBase), usUsed_In - sizeof(PktBase), dwCodePage))
{
PktBase* lpPktBase = reinterpret_cast<PktBase*>(lpBuffer);
lpPktBase->InitPtHead(usUsed_In, cCMD_In, usState_In, usError_In);
lpPktBase->SetCodePage(dwCodePage);
lpPktBase->SetCrypt();
// Çì´õ ÀÎÄÚµù
Crypt.EncodeHeader(lpBuffer + 1, sizeof(PktBase) - 1, 0, 0);
wr_ptr(usUsed_In);
return true;
}
}
fprintf(stderr, "CNetworkMsgBlock::WrapCrypt - Packet wrapping error. CMD:0x%02x, usUsed:%d, capacity:%d\n",
cCMD_In, usUsed_In, capacity());
return false;
}
unsigned long CNetworkMsgBlock::GetMinCompressSize(unsigned short usSourceLength)
{
return usSourceLength + (usSourceLength / 64) + 16 + 3;
}
bool CNetworkMsgBlock::WrapCompress(char* lpSourceData, unsigned short usSourceLength,
unsigned char cCMD_In, unsigned short usState_In,
unsigned short usError_In)
{
unsigned long dwDstBufferSize = static_cast<unsigned long>(remain());
if(usSourceLength < sizeof(PktBase) || PktMaxLen < usSourceLength)
{
fprintf(stderr, "CNetworkMsgBlock::WrapCompress - Packet wrapping error. CMD:0x%02x, usSourceLength:%d, dwDstBufferSize:%d\n",
cCMD_In, usSourceLength, dwDstBufferSize);
}
else
{
if(dwDstBufferSize < sizeof(PktBase) || dwDstBufferSize < GetMinCompressSize(usSourceLength))
{
fprintf(stderr, "CNetworkMsgBlock::WrapCompress - Too small buffer size. CMD:0x%02x, usSourceLength:%d, dwDstBufferSize:%d\n",
cCMD_In, usSourceLength, dwDstBufferSize);
}
else
{
char* lpDstBuffer = rd_ptr();
unsigned long dwCompressedSize = dwDstBufferSize - sizeof(PktBase);
if(!CMiniLZO::Compress(lpSourceData + sizeof(PktBase), usSourceLength - sizeof(PktBase),
lpDstBuffer + sizeof(PktBase), &dwCompressedSize))
{
fprintf(stderr, "CNetworkMsgBlock::WrapCompress - Packet Compress failed. CMD:0x%02x, usSourceLength:%d, "
"dwDstBufferSize:%d\n", cCMD_In, usSourceLength, dwDstBufferSize);
}
else
{
if(dwDstBufferSize <= dwCompressedSize)
{
fprintf(stderr, "CNetworkMsgBlock::WrapCompress - Compressed size is over than buffer size."
"CMD:0x%02x, dwDstBufferSize:%d, dwCompressedSize:%d\n", cCMD_In, dwDstBufferSize, dwCompressedSize);
}
dwCompressedSize += sizeof(PktBase);
PktBase* lpPktDst = reinterpret_cast<PktBase*>(lpDstBuffer);
lpPktDst->InitPtHead(static_cast<PktBase::LengthType>(dwCompressedSize), cCMD_In, usState_In, usError_In);
lpPktDst->SetCompress();
// ÀÎÄÚµù Çì´õ
CXORCrypt::GetInstance().EncodeHeader(lpDstBuffer + 1, sizeof(PktBase) - 1, 0, 0);
wr_ptr(dwCompressedSize);
return true;
}
}
}
return false;
}
CNetworkMsgQueue::CNetworkMsgQueue()
: m_lpListHead(NULL), m_lpListTail(NULL), m_nListNum(0)
{
}
CNetworkMsgQueue::~CNetworkMsgQueue()
{
clear();
}
void CNetworkMsgQueue::clear()
{
CNetworkMsgPool::GetInstance().FreeNetworkMsgBlock(*this);
}
void CNetworkMsgQueue::Enqueue(CNetworkMsgBlock* lpMsgBlock, bool bPendHead)
{
if(NULL != lpMsgBlock)
{
if(m_lpListHead == NULL)
{
m_lpListHead = m_lpListTail = lpMsgBlock;
lpMsgBlock->next(NULL);
}
else if(!bPendHead)
{
m_lpListTail->next(lpMsgBlock);
m_lpListTail = lpMsgBlock;
lpMsgBlock->next(NULL);
}
else
{
lpMsgBlock->next(m_lpListHead);
m_lpListHead = lpMsgBlock;
}
++m_nListNum;
}
}
CNetworkMsgBlock* CNetworkMsgQueue::Dequeue()
{
CNetworkMsgBlock* lpMsgBlock = NULL;
if(m_lpListTail != NULL)
{
lpMsgBlock = m_lpListHead;
m_lpListHead = m_lpListHead->next();
if(m_lpListTail == lpMsgBlock)
{
m_lpListTail = NULL;
}
lpMsgBlock->next(NULL);
--m_nListNum;
}
return lpMsgBlock;
}
CNetworkMsgBlock* CNetworkMsgPool::GetNetworkMsgBlock(unsigned long dwSize, INET_Addr& addr)
{
MsgBlockLock::Syncronize sync(m_MsgBlockLock);
CNetworkMsgBlock* lpMsgBlock = 0;
if (m_MsgBlockList.empty())
{
lpMsgBlock = new CNetworkMsgBlock(dwSize);
}
else
{
lpMsgBlock = m_MsgBlockList.front();
m_MsgBlockList.pop_front();
if (0 != lpMsgBlock)
{
lpMsgBlock->init(dwSize);
}
}
if (0 != lpMsgBlock && lpMsgBlock->is_valid()
&& dwSize <= lpMsgBlock->capacity())
{
return lpMsgBlock;
}
delete lpMsgBlock;
return 0;
}
void CNetworkMsgPool::FreeNetworkMsgBlock(CNetworkMsgBlock* lpMsgBlock)
{
MsgBlockLock::Syncronize sync(m_MsgBlockLock);
if (0 != lpMsgBlock)
{
if (m_MsgBlockList.size() < m_dwMaxBlockNum)
{
m_MsgBlockList.push_back(lpMsgBlock);
}
else
{
delete lpMsgBlock;
}
}
}
void CNetworkMsgPool::FreeNetworkMsgBlock(CNetworkMsgQueue& msgQueue)
{
MsgBlockLock::Syncronize sync(m_MsgBlockLock);
CNetworkMsgBlock* lpMsgBlock = 0;
while (0 != (lpMsgBlock = msgQueue.Dequeue()))
{
if (m_MsgBlockList.size() < m_dwMaxBlockNum)
{
m_MsgBlockList.push_back(lpMsgBlock);
}
else
{
delete lpMsgBlock;
}
}
}
CNetworkMsgPool& CNetworkMsgPool::GetInstance()
{
static CNetworkMsgPool msgPool;
return msgPool;
}
CNetworkMsgPool::CNetworkMsgPool()
: m_dwMaxBlockNum(50)
{
}
CNetworkMsgPool::~CNetworkMsgPool()
{
MsgBlockLock::Syncronize sync(m_MsgBlockLock);
MsgBlockList::iterator pos = m_MsgBlockList.begin();
MsgBlockList::iterator end = m_MsgBlockList.end();
for(; pos != end; ++pos)
{
delete *pos;
}
m_MsgBlockList.clear();
}
CLockedMsgQueue::~CLockedMsgQueue()
{
MsgQueueLock::Syncronize sync(m_MsgQueueLock);
m_MessageQueue.clear();
}
CNetworkMsgBlock* CLockedMsgQueue::GetMessage()
{
MsgQueueLock::Syncronize sync(m_MsgQueueLock);
return m_MessageQueue.Dequeue();
}
void CLockedMsgQueue::GetMessages(CNetworkMsgQueue& msgQueue, DWORD dwItemNum)
{
CNetworkMsgBlock* lpMsg = 0;
MsgQueueLock::Syncronize sync(m_MsgQueueLock);
for(DWORD dwCount = 0; dwCount < dwItemNum; ++dwCount)
{
if(0 != (lpMsg = m_MessageQueue.Dequeue()))
{
msgQueue.Enqueue(lpMsg);
}
else
{
break;
}
}
}
void CLockedMsgQueue::PutMessage(CNetworkMsgBlock* lpMsg, bool bPendHead)
{
MsgQueueLock::Syncronize sync(m_MsgQueueLock);
m_MessageQueue.Enqueue(lpMsg, bPendHead);
}
void CLockedMsgQueue::PutMessages(CNetworkMsgQueue& msgQueue)
{
CNetworkMsgBlock* lpMsg = 0;
MsgQueueLock::Syncronize sync(m_MsgQueueLock);
while(0 != (lpMsg = msgQueue.Dequeue()))
{
m_MessageQueue.Enqueue(lpMsg);
}
}
CUnboundedWaitableMsgQueue::CUnboundedWaitableMsgQueue()
{
// Create Auto-Reset Event
m_hNotEmpty = CreateEvent(0, FALSE, FALSE, 0);
}
CUnboundedWaitableMsgQueue::~CUnboundedWaitableMsgQueue()
{
CloseHandle(m_hNotEmpty);
}
DWORD CUnboundedWaitableMsgQueue::WaitForNotEmptyQueue(DWORD dwMilliseconds)
{
return WaitForSingleObject(m_hNotEmpty, dwMilliseconds);
}
CNetworkMsgBlock* CUnboundedWaitableMsgQueue::GetMessage()
{
MsgQueueLock::Syncronize sync(m_MsgQueueLock);
CNetworkMsgBlock* lpMsg = m_MessageQueue.Dequeue();
InternalResetNotEmpty();
return lpMsg;
}
void CUnboundedWaitableMsgQueue::GetMessages(CNetworkMsgQueue& msgQueue, DWORD dwItemNum)
{
CNetworkMsgBlock* lpMsg = 0;
MsgQueueLock::Syncronize sync(m_MsgQueueLock);
for(DWORD dwCount = 0; dwCount < dwItemNum; ++dwCount)
{
if(0 != (lpMsg = m_MessageQueue.Dequeue()))
{
msgQueue.Enqueue(lpMsg);
}
else
{
break;
}
}
InternalResetNotEmpty();
}
void CUnboundedWaitableMsgQueue::PutMessage(CNetworkMsgBlock* lpMsg, bool bPendHead)
{
MsgQueueLock::Syncronize sync(m_MsgQueueLock);
m_MessageQueue.Enqueue(lpMsg, bPendHead);
InternalSetNotEmpty();
}
void CUnboundedWaitableMsgQueue::PutMessages(CNetworkMsgQueue& msgQueue)
{
CNetworkMsgBlock* lpMsg = 0;
MsgQueueLock::Syncronize sync(m_MsgQueueLock);
while(0 != (lpMsg = msgQueue.Dequeue()))
{
m_MessageQueue.Enqueue(lpMsg);
}
InternalSetNotEmpty();
}
void CUnboundedWaitableMsgQueue::InternalSetNotEmpty()
{
if(!m_bNotEmpty && 0 != m_MessageQueue.GetQueuedNum())
{
SetEvent(m_hNotEmpty); m_bNotEmpty = true;
}
}
void CUnboundedWaitableMsgQueue::InternalResetNotEmpty()
{
if(m_bNotEmpty && 0 == m_MessageQueue.GetQueuedNum())
{
ResetEvent(m_hNotEmpty);
m_bNotEmpty = false;
}
}
}