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,191 @@
#ifndef _CLOCK_H_
#define _CLOCK_H_
#include <winsock2.h>
#include <windows.h>
// 다중 CPU환경에서는 Cache-Line에 대한 고려를 해야만 할 것.
#define CACHE_ALIGN 32
#define CACHE_PAD(Name, BytesSoFar) \
BYTE Name[CACHE_ALIGN - ((BytesSoFar) % CACHE_ALIGN)]
template<class DerivedLockClass>
class CLock
{
public:
class Syncronize
{
public:
Syncronize(DerivedLockClass* pLockClass) : m_Lock(*pLockClass) { m_Lock.Lock(); }
Syncronize(DerivedLockClass& LockClass) : m_Lock(LockClass) { m_Lock.Lock(); }
~Syncronize() { m_Lock.Unlock();}
protected:
DerivedLockClass& m_Lock;
};
};
// 이 Lock클래스들은 더이상 상속을 받아서는 안 된다.
// ----------------------------------------------------------------------------
// DummyLock ------------------------------------------------------------------
class CDummyLock : public CLock<CDummyLock>
{
public:
void Lock() { }
void Unlock() { }
bool IsVaildLock() { return true; }
};
// ----------------------------------------------------------------------------
// SpinLock -------------------------------------------------------------------
class CSpinLock : public CLock<CSpinLock>
{
public:
CSpinLock() : m_bLocked(FALSE) { }
~CSpinLock() { }
void Lock() { while(TRUE == InterlockedExchange(&m_bLocked, TRUE)) { Sleep(0); } }
void Unlock() { InterlockedExchange(&m_bLocked, FALSE); }
bool IsVaildLock() { return true; }
private:
volatile LONG m_bLocked;
};
// ----------------------------------------------------------------------------
// Critical Section -----------------------------------------------------------
class CCSLock : public CLock<CCSLock>
{
public:
CCSLock() { InitializeCriticalSection(&m_CSLock); }
~CCSLock() { DeleteCriticalSection(&m_CSLock); }
void Lock() { EnterCriticalSection(&m_CSLock); }
void Unlock() { LeaveCriticalSection(&m_CSLock); }
bool IsVaildLock() { return true; }
private:
CRITICAL_SECTION m_CSLock;
};
// ----------------------------------------------------------------------------
// Mutex Lock -----------------------------------------------------------------
class CMutex : public CLock<CMutex>
{
public:
CMutex() : m_hMutex(CreateMutex(NULL, FALSE, NULL)) { }
~CMutex() { if(0 != m_hMutex) { CloseHandle(m_hMutex); } }
unsigned long Lock() { return WaitForSingleObject(m_hMutex, INFINITE); }
unsigned long Unlock() { return ReleaseMutex(m_hMutex); }
bool IsVaildLock() { return (NULL != m_hMutex); }
private:
HANDLE m_hMutex;
};
class CNamedMutex : public CLock<CNamedMutex>
{
public:
CNamedMutex(const TCHAR* szMutexName, BOOL bInitialOwner)
: m_hMutex(CreateMutex(NULL, bInitialOwner, szMutexName)) { }
~CNamedMutex() { if(0 != m_hMutex) { CloseHandle(m_hMutex); } }
unsigned long Lock() { return WaitForSingleObject(m_hMutex, INFINITE); }
unsigned long Unlock() { return ReleaseMutex(m_hMutex); }
bool IsVaildLock() { return (NULL != m_hMutex); }
private:
HANDLE m_hMutex;
};
/*
class CFairRWLock : private CCSLock
{
private:
Semaphore access_lock; // used as a one-at-a-time release valve
CCSLock read_barrier; // used to block/wakeup readers
unsigned int is_write_lock; // nonzero if locked for writing
unsigned int writer_count; // # of writers waiting for or holding the lock
unsigned int reader_count; // # of readers holding the lock
unsigned int readers_waiting; // # of readers waiting for the lock
public:
ReadLock()
: access_lock(1), is_write_lock(0),
writers_waiting(0), reader_count(0), readers_waiting(0)
{
}
void ReadLock()
{
Mutex::Lock();
// if there is at least one writer using the lock or waiting for it,
// we need to wait for access
if (writer_count > 0))
{
if (readers_waiting++ == 0) // if we're the first reader in line
Mutex::Unlock();
access_lock.Wait(); // get the access lock
Mutex::Lock();
if (readers_waiting > 1) // then if there are other readers
read_barrier.Open(); // let them go
}
else
{
Mutex::Unlock();
read_barrier.Wait(); // otherwise wait until someone lets us go
Mutex::Lock();
}
readers_waiting--;
}
reader_count++;
Mutex::Unlock();
}
void WriteLock()
{
Mutex::Lock();
writer_count++; // one more writer
Mutex::Unlock();
access_lock.Wait(); // wait until the access lock is available
Mutex::Lock();
is_write_lock = 1; // lock is a write lock
read_barrier.Close(); // give readers something to wait for
Mutex::Unlock();
}
void Unlock()
{
Mutex::Lock();
if (is_write_lock)
{ // if this is a write lock
is_write_lock = 0; // let it go
writer_count--; // one less writer
access_lock.Post(); // now let someone else have a chance
}
else if (--reader_count == 0)
{
// if we're the last reader
access_lock.Post(); // release the access lock
}
Mutex::Unlock();
}
};
*/
#endif

View File

@@ -0,0 +1,35 @@
#ifndef _CTHREAD_H_
#define _CTHREAD_H_
#include <winsock2.h>
#include <windows.h>
class CThread
{
public:
CThread() : m_hThreadHandle(INVALID_HANDLE_VALUE) { }
virtual ~CThread() { }
protected:
virtual unsigned int Run() = 0; // 실제 실행 되는 루프를 넣는다.
virtual BOOL End() = 0; // 루프가 끝날 수 있는 루틴을 넣는다.
typedef unsigned int(__stdcall *LPThreadFunc)(void*);
static inline unsigned int __stdcall ThreadFunc(void* pArg);
inline void SetHandle(HANDLE hHandle) { m_hThreadHandle = hHandle; }
inline HANDLE GetHandle() { return m_hThreadHandle; }
HANDLE m_hThreadHandle;
friend class CThreadMgr;
};
inline unsigned int __stdcall CThread::ThreadFunc(void* pArg)
{
return static_cast<CThread*>(pArg)->Run();
}
#endif

View File

@@ -0,0 +1,126 @@
#include "stdafx.h"
#include "Thread.h"
#include "ThreadMgr.h"
#include <algorithm>
#include <functional>
#include "GMMemory.h"
// constructor and destructor
CThreadMgr::CThreadMgr()
: m_nThreadNum(0), m_bJoinStarted(FALSE)
{
std::fill_n(m_lpThreads, size_t(MAX_THREAD_NUM), reinterpret_cast<CThread*>(0));
std::fill_n(m_hThreads, size_t(MAX_THREAD_NUM), INVALID_HANDLE_VALUE);
}
CThreadMgr::~CThreadMgr()
{
JoinThread();
}
bool CThreadMgr::RegisterAndRun(CThread* llpThread)
{
unsigned int nThreadID = 0;
unsigned int nThreadIndex = 0;
if(0 == llpThread)
{
return false;
}
// Lock
{
ThreadLock::Syncronize sync(m_ThreadLock);
if(63 <= m_nThreadNum || TRUE == m_bJoinStarted)
{
return false;
}
nThreadIndex = m_nThreadNum;
++m_nThreadNum;
}
m_lpThreads[nThreadIndex] = llpThread;
m_hThreads[nThreadIndex] = reinterpret_cast<HANDLE>(_beginthreadex(0, 0,
CThread::ThreadFunc, llpThread, 0, &nThreadID));
return (0 != m_hThreads[nThreadIndex]);
}
bool CThreadMgr::JoinThread()
{
{
ThreadLock::Syncronize sync(m_ThreadLock);
if(0 == m_nThreadNum)
{
return true;
}
// 조인이 시작되면, 더이상의 스레드 생성 및 등록을 금지함.
m_bJoinStarted = TRUE;
}
// 스레드 전부 종료 & 대기.
std::for_each(&m_lpThreads[0], &m_lpThreads[m_nThreadNum], std::mem_fun(&CThread::End));
WaitForMultipleObjects(m_nThreadNum, m_hThreads, TRUE, INFINITE);
CThread** lppPastEndThread = m_lpThreads + MAX_THREAD_NUM;
HANDLE* lppPastEndHandle = m_hThreads + MAX_THREAD_NUM;
// 스레드 소멸.
for(CThread** lplpThread = m_lpThreads;
lplpThread != lppPastEndThread; ++lplpThread)
{
delete *lplpThread;
}
// 스레드 핸들 소멸.
for(HANDLE* lppHandle = m_hThreads;
lppHandle != lppPastEndHandle; ++lppHandle)
{
CloseHandle(*lppHandle);
}
{
// 스레드 개수 및 조인 여부 리셋.
ThreadLock::Syncronize sync(m_ThreadLock);
m_nThreadNum = 0;
m_bJoinStarted = FALSE;
}
return true;
}
HANDLE CThreadMgr::Run(CThread* lpThread)
{
unsigned int nThreadID = 0;
HANDLE hThread = reinterpret_cast<HANDLE>(_beginthreadex(0,
0, CThread::ThreadFunc, lpThread, 0, &nThreadID));
lpThread->SetHandle(hThread);
return hThread;
}
bool CThreadMgr::Stop(CThread* lpThread, unsigned long dwTimeout)
{
if(0 == lpThread)
{
return false;
}
HANDLE hThread = lpThread->GetHandle();
if(INVALID_HANDLE_VALUE == hThread)
{
return false;
}
lpThread->SetHandle(INVALID_HANDLE_VALUE);
lpThread->End();
WaitForSingleObject(hThread, dwTimeout);
return (TRUE == CloseHandle(hThread));
}

View File

@@ -0,0 +1,61 @@
#ifndef _CTHREADMGR_H_
#define _CTHREADMGR_H_
#ifndef WINDOWS_LEAN_AND_MEAN
#define WINDOWS_LEAN_AND_MEAN
#endif
#include <winsock2.h>
#include <windows.h>
#include <process.h>
#include "Lock.h"
// forward decl
class CThread;
class CThreadMgr
{
public:
enum { MAX_THREAD_NUM = 63 };
CThreadMgr();
virtual ~CThreadMgr();
bool RegisterAndRun(CThread* lpThread); // 스레드를 등록한다. 최대 63개까지 등록할 수 있다.
bool JoinThread(); // 모든 스레드를 종료시킨다.
inline int GetNum()
{
return m_nThreadNum;
}
inline int GetMaxNum()
{
return MAX_THREAD_NUM;
}
CThread* GetThread(int iPos)
{
return m_lpThreads[iPos];
}
// 매니저에 등록하지 않고, 그냥 실행 시킨다.
static HANDLE Run(CThread* lpThread);
static bool Stop(CThread* lpThread, unsigned long dwTimeout = INFINITE);
private:
typedef CCSLock ThreadLock;
CThread* m_lpThreads[MAX_THREAD_NUM];
HANDLE m_hThreads[MAX_THREAD_NUM];
ThreadLock m_ThreadLock;
unsigned int m_nThreadNum;
unsigned int m_bJoinStarted;
};
#endif