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>
191 lines
4.5 KiB
C++
191 lines
4.5 KiB
C++
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SocketIO Class
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
#include "SocketIO.h"
|
|
|
|
#include <Network/XORCrypt/XORCrypt.h>
|
|
#include <Utility/Compress/MiniLZO/MiniLZOWrapper.h>
|
|
|
|
SocketIO::SocketIO(void)
|
|
: m_ServerState(ServerInfo::SS_SMOOTH), m_PacketCount(0), m_Crypt(CXORCrypt::GetInstance())
|
|
{
|
|
Socket::InitWinsock();
|
|
}
|
|
|
|
SocketIO::~SocketIO(void)
|
|
{
|
|
Socket::ReleaseWinsock();
|
|
}
|
|
|
|
int SocketIO::Send(SOCKET Socket_In, WSABUF SendData_In)
|
|
{
|
|
int send_byte;
|
|
|
|
send_byte = send(Socket_In, (char *)SendData_In.buf, SendData_In.len, 0);
|
|
if(send_byte == SOCKET_ERROR || (int)SendData_In.len != send_byte)
|
|
return 0;
|
|
|
|
return send_byte;
|
|
}
|
|
|
|
int SocketIO::SendTo(SOCKET Socket_In, SOCKADDR_IN Addreess_In, WSABUF SendData_In)
|
|
{
|
|
int AddressSize = sizeof(SOCKADDR_IN);
|
|
int send_byte = 0;
|
|
|
|
send_byte = sendto(Socket_In, (char *)SendData_In.buf, SendData_In.len, 0, (struct sockaddr *)&Addreess_In, AddressSize);
|
|
if(send_byte == SOCKET_ERROR || (int)SendData_In.len != send_byte)
|
|
return 0;
|
|
|
|
return send_byte;
|
|
}
|
|
|
|
int SocketIO::Recv(SOCKET Socket_In, WSABUF &RecvData_In)
|
|
{
|
|
DWORD recv_byte;
|
|
|
|
if((recv_byte = recv(Socket_In, RecvData_In.buf, BufferSize, 0)) != SOCKET_ERROR)
|
|
{
|
|
RecvData_In.len = recv_byte;
|
|
return recv_byte;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int SocketIO::RecvFrom(SOCKET Socket_In, WSABUF &RecvData_In, LPSOCKADDR_IN Address_Out)
|
|
{
|
|
int AddressSize = sizeof(SOCKADDR_IN);
|
|
|
|
DWORD recv_byte;
|
|
|
|
if((recv_byte = recvfrom(Socket_In, RecvData_In.buf, BufferSize, 0, (struct sockaddr *)Address_Out, &AddressSize)) != SOCKET_ERROR)
|
|
{
|
|
RecvData_In.len = recv_byte;
|
|
return recv_byte;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int SocketIO::PutRecvBufferToPtBuffer(char *pBuffer_Out, int BufferSize_In, WSABUF &RecvData_In, char *RecvBuffer_In, unsigned short PageVer_In, unsigned char PageNum_In)
|
|
{
|
|
LPPktBase lpPktBase = NULL;;
|
|
if(pBuffer_Out == NULL || RecvData_In.len == 0)
|
|
return false;
|
|
|
|
try
|
|
{
|
|
lpPktBase = (LPPktBase)RecvData_In.buf;
|
|
|
|
if(lpPktBase->GetStartBit() != StartBit)
|
|
{
|
|
// 패킷 시작 아닐 경우
|
|
|
|
if(RecvData_In.buf != RecvBuffer_In)
|
|
{
|
|
// 이전 패킷 존재 ( 패킷 연결 )
|
|
RecvData_In.len = static_cast<u_long>((RecvData_In.buf - RecvBuffer_In) + RecvData_In.len);
|
|
RecvData_In.buf = RecvBuffer_In;
|
|
}
|
|
else
|
|
{
|
|
// 이전 패킷 존재 하지 않음 잘못된 패킷 ( 버퍼 리셋 )
|
|
|
|
RecvData_In.len = 0;
|
|
RecvData_In.buf = RecvBuffer_In;
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
lpPktBase = (LPPktBase)RecvData_In.buf;
|
|
if(lpPktBase->GetStartBit() == StartBit)
|
|
{
|
|
// 디코딩 해더
|
|
if(RecvData_In.len < PktBaseSize)
|
|
{
|
|
// 잘린 패킷 전송 ( 데이터 버퍼 포인터 이동 )
|
|
RecvData_In.buf = RecvData_In.buf + RecvData_In.len;
|
|
RecvData_In.len = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
m_Crypt.DecodeHeader((char *)lpPktBase + 1, PktBaseSize - 1, PageVer_In, PageNum_In);
|
|
|
|
unsigned short PacketLength = lpPktBase->GetLen();
|
|
if(PktMinLen <= PacketLength && PacketLength <= PktMaxLen)
|
|
{
|
|
// 정상 길이의 패킷
|
|
if(PacketLength <= RecvData_In.len)
|
|
{
|
|
if(lpPktBase->IsCrypt())
|
|
{
|
|
m_Crypt.DecodePacket((char *)lpPktBase + PktBaseSize, PacketLength - PktBaseSize, lpPktBase->GetCodePage());
|
|
}
|
|
|
|
if(lpPktBase->IsCompress())
|
|
{
|
|
// 압축 패킷 처리
|
|
DWORD Len = BufferSize_In;
|
|
|
|
CopyMemory(pBuffer_Out, (char *)lpPktBase, PktBaseSize);
|
|
CMiniLZOCompress::Decompress((char *)lpPktBase + PktBaseSize, PacketLength - PktBaseSize, pBuffer_Out + PktBaseSize, &Len);
|
|
lpPktBase->SetLen((unsigned short)Len + PktBaseSize);
|
|
}
|
|
else
|
|
{
|
|
// 비 압축 패킷 처리
|
|
CopyMemory(pBuffer_Out, (char *)lpPktBase, PacketLength);
|
|
}
|
|
|
|
RecvData_In.len = RecvData_In.len - PacketLength;
|
|
if(RecvData_In.len)
|
|
{
|
|
// 받은 데이터가 남았을 경우
|
|
|
|
CopyMemory((char *)lpPktBase, (char *)lpPktBase + PacketLength, RecvData_In.len);
|
|
}
|
|
|
|
return PacketLength;
|
|
}
|
|
else
|
|
{
|
|
m_Crypt.EncodeHeader((char *)lpPktBase + 1, PktBaseSize - 1, PageVer_In, PageNum_In);
|
|
|
|
// 잘린 패킷 전송 ( 데이터 버퍼 포인터 이동 )
|
|
RecvData_In.buf = RecvData_In.buf + RecvData_In.len;
|
|
RecvData_In.len = 0;
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 비정상적 길이의 패킷
|
|
RecvData_In.buf = RecvBuffer_In;
|
|
RecvData_In.len = 0;
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 잘못된 패킷 ( 버퍼 리셋 )
|
|
|
|
RecvData_In.buf = RecvBuffer_In;
|
|
RecvData_In.len = 0;
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return 0;
|
|
} |