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>
This commit is contained in:
2025-11-29 20:17:20 +09:00
parent 5d3cd64a25
commit dd97ddec92
11602 changed files with 1446576 additions and 0 deletions

View File

@@ -0,0 +1,284 @@
#include "Socket.h"
void Socket::InitWinsock(void)
{
WSADATA WsaData;
WSAStartup(MAKEWORD( 2, 2), &WsaData);
}
void Socket::ReleaseWinsock(void)
{
WSACleanup();
}
SOCKADDR_IN Socket::MakeSockAddr(char *IP_In, int Port_In)
{
SOCKADDR_IN Address = {0,};
Address.sin_family = AF_INET;
Address.sin_addr.s_addr = (NULL == IP_In) ? htonl(INADDR_ANY) : inet_addr(IP_In);
Address.sin_port = (0 == Port_In) ? 0 : htons(Port_In);
return Address;
}
SOCKADDR_IN Socket::MakeSockAddr(IN_ADDR Addr, int Port_In)
{
SOCKADDR_IN Address = {0,};
Address.sin_family = AF_INET;
Address.sin_addr = Addr;
Address.sin_port = (0 == Port_In) ? 0 : htons(Port_In);
return Address;
}
bool Socket::CreateTCPSocket(SOCKET *Socket_Out, HWND hWnd_In, unsigned int Msg_In)
{
BOOL KeepAlive = TRUE;
linger Linger;
Linger.l_onoff = 1;
Linger.l_linger = 0;
if(Socket_Out == NULL)
return false;
if((*Socket_Out = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == SOCKET_ERROR)
return false;
if(setsockopt(*Socket_Out, SOL_SOCKET, SO_KEEPALIVE, (char *)&KeepAlive, sizeof(BOOL)) == SOCKET_ERROR)
return false;
if(setsockopt(*Socket_Out, SOL_SOCKET, SO_LINGER, (char *)&Linger, sizeof(linger)) == SOCKET_ERROR)
return false;
if(WSAAsyncSelect(*Socket_Out, hWnd_In, Msg_In, FD_READ | FD_CONNECT | FD_CLOSE) == SOCKET_ERROR)
return false;
return true;
}
bool Socket::CreateUDPSocket(SOCKET *Socket_Out, SOCKADDR_IN Address_In, HWND hWnd_In, unsigned int Msg_In)
{
BOOL ReUseAddr = TRUE;
if(Socket_Out == NULL)
return false;
if((*Socket_Out = socket(AF_INET, SOCK_DGRAM, 0)) == SOCKET_ERROR)
return false;
if(bind(*Socket_Out, (sockaddr *)&Address_In, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
return false;
if(setsockopt(*Socket_Out, SOL_SOCKET, SO_REUSEADDR, (char *)&ReUseAddr, sizeof(BOOL)) == SOCKET_ERROR)
return false;
if(WSAAsyncSelect(*Socket_Out, hWnd_In, Msg_In, FD_READ) == SOCKET_ERROR)
return false;
return true;
}
bool Socket::DeleteSocket(SOCKET *Socket_In, HWND hWnd_In)
{
if(Socket_In == NULL)
return false;
WSAAsyncSelect(*Socket_In, hWnd_In, 0, 0);
SAFE_CLOSESOCK(*Socket_In);
return true;
}
bool Socket::GetNATAddress(SOCKET Socket_In, SOCKADDR_IN *Address_Out, bool AllowVirtual)
{
int AddressSize = sizeof(SOCKADDR_IN);
if(getsockname(Socket_In, (struct sockaddr *)Address_Out, &AddressSize) != SOCKET_ERROR)
{
char HostName[256];
if(!gethostname(HostName, 255))
{
PHOSTENT pHost = gethostbyname(HostName);
if(NULL == pHost)
{
return false;
}
IN_ADDR& Addr = Address_Out->sin_addr;
for(int Count = 0;pHost->h_addr_list[Count]; ++Count)
{
memcpy(&(Addr.S_un.S_addr), pHost->h_addr_list[Count], sizeof(IN_ADDR));
if(!AllowVirtual)
{
// 가상 아이피 확인
// 10.0.0.0 ~ 10.255.255.255
// 172.16.0.0 ~ 172.31.255.255
// 192.168.0.0 ~ 192.168.255.255
if((unsigned char)10 == Addr.S_un.S_un_b.s_b1)
{
continue;
}
else if((unsigned char)172 == Addr.S_un.S_un_b.s_b1)
{
if(Addr.S_un.S_un_b.s_b2 >= (unsigned char)16 && Addr.S_un.S_un_b.s_b2 <= (unsigned char)31)
{
continue;
}
}
else if((unsigned char)192 == Addr.S_un.S_un_b.s_b1)
{
if((unsigned char)168 == Addr.S_un.S_un_b.s_b2)
{
continue;
}
}
}
// 잘못된 아이피
// 169.X.X.X 자동 아이피 할당 ( SyGate )
// 0.X.X.X
if((unsigned char)169 == Addr.S_un.S_un_b.s_b1)
{
continue;
}
else if((unsigned char)0 == Addr.S_un.S_un_b.s_b1)
{
continue;
}
return true;
}
if(0 != Count)
return true;
}
return false;
}
return false;
}
bool Socket::GetHostName(char *Name_Out, int Size)
{
if(!gethostname(Name_Out, Size))
return true;
return false;
}
bool Socket::GetHostIP(IN_ADDR &Addr, bool AllowVirtual)
{
char HostName[256];
if(!gethostname(HostName, 255))
{
PHOSTENT pHost = gethostbyname(HostName);
if(NULL == pHost)
{
return false;
}
for(int Count = 0;pHost->h_addr_list[Count]; ++Count)
{
memcpy(&(Addr.S_un.S_addr), pHost->h_addr_list[Count], sizeof(IN_ADDR));
if(!AllowVirtual)
{
// 가상 아이피 확인
// 10.0.0.0 ~ 10.255.255.255
// 172.16.0.0 ~ 172.31.255.255
// 192.168.0.0 ~ 192.168.255.255
if((unsigned char)10 == Addr.S_un.S_un_b.s_b1)
{
continue;
}
else if((unsigned char)172 == Addr.S_un.S_un_b.s_b1)
{
if(Addr.S_un.S_un_b.s_b2 >= (unsigned char)16 && Addr.S_un.S_un_b.s_b2 <= (unsigned char)31)
{
continue;
}
}
else if((unsigned char)192 == Addr.S_un.S_un_b.s_b1)
{
if((unsigned char)168 == Addr.S_un.S_un_b.s_b2)
{
continue;
}
}
}
// 잘못된 아이피
// 169.X.X.X 자동 아이피 할당 ( SyGate )
// 0.X.X.X
if((unsigned char)169 == Addr.S_un.S_un_b.s_b1)
{
continue;
}
else if((unsigned char)0 == Addr.S_un.S_un_b.s_b1)
{
continue;
}
return true;
}
if(0 != Count)
return true;
}
return false;
}
bool Socket::GetHostIP(IN_ADDR &Addr, char *Domain)
{
PHOSTENT pHost = gethostbyname(Domain);
if(NULL == pHost)
{
return false;
}
memcpy(&(Addr.S_un.S_addr), pHost->h_addr_list[0], sizeof(IN_ADDR));
return true;
}
bool Socket::IsWrongIP(IN_ADDR &Addr)
{
if((unsigned char)169 == Addr.S_un.S_un_b.s_b1)
{
if((unsigned char)254 == Addr.S_un.S_un_b.s_b2)
{
return true;
}
}
if((unsigned char)0 == Addr.S_un.S_un_b.s_b1)
return true;
return false;
}
bool Socket::IsEmptyAddr(IN_ADDR &Addr)
{
if((unsigned char)0 == Addr.S_un.S_un_b.s_b1)
{
return true;
}
return true;
}
bool Socket::Connect(SOCKET Socket_In, SOCKADDR_IN Address_In, WSABUF *WSABuf_In)
{
if(WSAConnect(Socket_In, (sockaddr *)&Address_In, sizeof(SOCKADDR_IN), 0, WSABuf_In, 0, 0) == SOCKET_ERROR)
{
DWORD dwError = GetLastError();
if(ERROR_IO_PENDING != dwError && WSAEWOULDBLOCK != (int)dwError)
return false;
}
return true;
}

View File

@@ -0,0 +1,33 @@
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <iphlpapi.h>
#include <windows.h>
#define SelectEvent(dwError) WSAGETSELECTEVENT(dwError)
#define SelectError(dwError) WSAGETSELECTERROR(dwError)
#define SAFE_CLOSESOCK(p) { if (INVALID_SOCKET != (p)) { closesocket(p); (p) = INVALID_SOCKET; } }
namespace Socket
{
void InitWinsock(void);
void ReleaseWinsock(void);
SOCKADDR_IN MakeSockAddr(IN_ADDR Addr, int Port_In);
SOCKADDR_IN MakeSockAddr(char *IP_In, int Port_In);
bool CreateTCPSocket(SOCKET *Socket_Out, HWND hWnd_In, unsigned int Msg_In);
bool CreateUDPSocket(SOCKET *Socket_Out, SOCKADDR_IN Address_In, HWND hWnd_In, unsigned int Msg_In);
bool DeleteSocket(SOCKET *Socket_In, HWND hWnd_In);
bool GetNATAddress(SOCKET Socket_In, SOCKADDR_IN *Address_Out, bool AllowVirtual);
bool GetHostName(char *Name_Out, int Size);
bool GetHostIP(IN_ADDR &Addr, bool AllowVirtual);
bool GetHostIP(IN_ADDR &Addr, char *Domain);
bool IsWrongIP(IN_ADDR &Addr);
bool IsEmptyAddr(IN_ADDR &Addr);
bool Connect(SOCKET Socket_In, SOCKADDR_IN Address_In, WSABUF *WSABuf_In);
};

View File

@@ -0,0 +1,191 @@
///////////////////////////////////////////////////////////////////////////////////////////////
//
// 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;
}

View File

@@ -0,0 +1,95 @@
///////////////////////////////////////////////////////////////////////////////////////////////
//
// SocketIO Class
//
// Last Update : 2002. 8. 28
//
///////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _SocketIO
#define _SocketIO
#include "Socket.h"
#include <Network/Packet/PacketBase.h>
// 전방 참조
class CXORCrypt;
///////////////////////////////////////////////////////////////////////////////////////////////
//
// 상수 설정
//
///////////////////////////////////////////////////////////////////////////////////////////////
const unsigned int BufferSize = 8192 * 100;
///////////////////////////////////////////////////////////////////////////////////////////////
//
// 클래스 정의
//
///////////////////////////////////////////////////////////////////////////////////////////////
class SocketIO
{
private:
ServerInfo::ServerState m_ServerState;
unsigned long m_PacketCount;
CXORCrypt& m_Crypt;
public:
SocketIO(void);
virtual ~SocketIO(void);
int Send(SOCKET Socket_In, WSABUF SendData_In);
int SendTo(SOCKET Socket_In, SOCKADDR_IN Addreess_In, WSABUF SendData_In);
int Recv(SOCKET Socket_In, WSABUF &RecvData_In);
int RecvFrom(SOCKET Socket_In, WSABUF &RecvData_In, LPSOCKADDR_IN Address_Out);
int PutRecvBufferToPtBuffer(char *pBuffer_Out, int BufferSize_In, WSABUF &RecvData_In, char *RecvBuffer_In, unsigned short PageVer_In, unsigned char PageNum_In);
inline char* InsertPtCount(char *Buffer_In);
inline unsigned long ExtractPtCount(char *Buffer_In);
inline bool CheckServerState();
};
inline char* SocketIO::InsertPtCount(char *Buffer_In)
{
((PktBase* )Buffer_In)->SetServerInfo(m_PacketCount);
if(++m_PacketCount >= 0xFFFFFFF0)
m_PacketCount = 0;
return Buffer_In;
}
inline unsigned long SocketIO::ExtractPtCount(char *Buffer_In)
{
PktBase* lpBasePt = (PktBase* )Buffer_In;
return lpBasePt->GetServerInfo();
}
inline bool SocketIO::CheckServerState()
{
if(m_ServerState == ServerInfo::SS_SMOOTH)
return true;
else if(m_ServerState == ServerInfo::SS_LOADED)
{
Sleep(25);
return true;
}
else if(m_ServerState == ServerInfo::SS_BUSY)
{
Sleep(100);
return true;
}
else if(m_ServerState == ServerInfo::SS_VERYBUSY)
{
Sleep(300);
return true;
}
return false;
}
#endif