# NeoRylClient 실행 시퀀스

**분석 날짜**: 2025-11-29
**프로젝트**: NeoRylClient (ROW - Reign of Revolution)

---

## 개요

NeoRylClient는 Windows 기반 MMORPG 클라이언트로, DirectX 8과 커스텀 게임 엔진을 사용하여 실행됩니다. 이 문서는 프로그램 시작부터 종료까지의 전체 실행 흐름을 설명합니다.

---

## 1. 진입점 (Entry Point)

### WinMain 함수

**파일**: `RYLClient/RYLClient/RYLClientMain.cpp:417`

```cpp
int _stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                     LPSTR lpCmdLine, int nCmdShow)
{
    // 1. Exception Handler 설정
    Exception::EnableUnhandledExceptioinFilterEx(UserUnhandledExceptionFilterEx, true);
    Exception::SetDumpType(Exception::NormalDump);
    Exception::EnableSaveDump(true);

    // 2. AntiHack 초기화 (현재 비활성화, USE_ANTIHACK = 0)
    USE_ANTIHACK1();                    // 디버거 체크
    USE_ANTIHACK2(AntiFunc);            // 함수 주소 암호화
    USE_ANTIHACK3(hInstance);           // 실행

    // AntiFunc 함수가 실제 메인 로직 실행
    // (USE_ANTIHACK2/3 매크로를 통해 호출됨)

    return 0;
}
```

**역할**:
- 예외 처리 핸들러 등록 (크래시 덤프 생성)
- AntiHack 시스템 초기화 (현재 비활성화 상태)
- 실제 게임 로직은 `AntiFunc` 함수에서 실행

---

## 2. 메인 초기화 (AntiFunc)

### AntiFunc 함수

**파일**: `RYLClient/RYLClient/RYLClientMain.cpp:139`

```cpp
BOOL WINAPI AntiFunc(HINSTANCE hInstance)
{
    MSG msg;
    msg.wParam = 0;

    // 1. 언어 설정
    LANGID li = GetUserDefaultLangID();

    // 2. Login.exe 실행 확인 (Release 빌드만)
    HWND hLoginWnd = FindWindow(NULL, "Login");
#ifdef NDEBUG
    if (!hLoginWnd && g_ClientMain.m_wAdminMode != ADMIN_L3)
    {
        MessageBox(NULL, "Please execute login.exe", "Program Error", MB_OK);
        return 0;
    }
#endif

    // 3. 서버 정보 가져오기
    g_ClientMain.GetServerInfo(hLoginWnd);

    // 4. 레지스트리에서 화면 설정 읽기
    g_ClientMain.QueryRegScreenValue();

    // 5. 게임 클래스 생성
    if (!g_ClientMain.InitCreateGameClass())
    {
        g_ClientMain.Destroy();
        return 0;
    }

    // 6. 클라이언트 초기화
    if (!g_ClientMain.Init(hInstance,
                           g_ClientMain.m_iScreenWidth,
                           g_ClientMain.m_iScreenHeight))
    {
        g_ClientMain.Destroy();
        return 0;
    }

    // 7. 씬 생성
    if (FAILED(g_ClientMain.CreateScene()))
    {
        g_ClientMain.Destroy();
        return 0;
    }

    // 8. 메인 루프
    while(1)
    {
        CProfileManager::Increment_Frame_Counter();

        if (PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE))
        {
            if (0 == GetMessage(&msg, NULL, 0, 0))
            {
                return (int)msg.wParam;  // 종료
            }
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            CSimpleProfile::GetInstance().IncrementFrameCounter();

            PROFILE("Update");
            Sleep(1);                       // CPU 사용률 조절
            g_ClientMain.Update();          // 게임 로직 업데이트
            g_ClientMain.Render();          // 화면 렌더링
        }
    }

    // 9. 종료 처리
    g_ClientMain.Destroy();

    return msg.wParam;
}
```

---

## 3. 초기화 단계별 상세

### 3.1. 서버 정보 가져오기 (GetServerInfo)

```cpp
void CClientMain::GetServerInfo(HWND hLoginWnd)
{
    // Login.exe로부터 서버 정보 수신
    // - 서버 타입 (테스트/정식/배틀로한)
    // - 국가 코드 (한국/글로벌/중국/일본 등)
    // - 게임가드 문자열
}
```

### 3.2. 화면 설정 읽기 (QueryRegScreenValue)

**레지스트리 경로**: `HKEY_LOCAL_MACHINE\Software\ROW\MP-Client`

```cpp
void CClientMain::QueryRegScreenValue()
{
    // 레지스트리에서 읽기:
    // - m_iScreenWidth (해상도 너비)
    // - m_iScreenHeight (해상도 높이)
    // - m_iBpp (색상 깊이)
    // - m_iRefresh (주사율)
    // - m_iWindowMode (창모드/전체화면)
    // - m_iLanguage (언어 설정)
    // - m_iMultiSupport (멀티 서버 지원)
}
```

### 3.3. 게임 클래스 생성 (InitCreateGameClass)

**파일**: `RYLClientMain.cpp:474`

```cpp
bool CClientMain::InitCreateGameClass()
{
    // 1. 실행 파일 경로 분석
    GetModuleFileName(NULL, szFileName, MAX_PATH - 1);
    _tsplitpath(szFileName, szDrive, szDir, szName, szExt);

    // 2. 스크립트 파일 경로 설정
    // Language/{언어}/Script.mcf
    sprintf(szScriptPath, "%s%sLanguage\\%s\\%s",
            szDrive, szDir, szLanguage[m_iLanguage], "Script.mcf");

    // 3. 게임 데이터 클래스 생성
    m_pRYLGameData = CRYLGameData::Instance();
    m_pRYLGameData->m_eInternationalCode = /* 국가 코드 */;

    // 4. 네트워크 데이터 클래스 생성
    m_pRYLNetworkData = CRYLNetworkData::Instance();
    m_pRYLNetworkData->m_eServerType = /* 서버 타입 */;

    // 5. 커뮤니티 데이터 클래스 생성
    m_pRYLCommunityData = CRYLCommunityData::Instance();

    // 6. 문자열 테이블 로드
    CRYLStringTable::InitStringTable(szScriptPath);

    // 7. 기타 매니저 생성
    m_pCastleManager = new CRYLCastleManager();
    m_pCampManager = new CRYLCampManager();
    m_pSkillScriptManager = new CRYLSkillScriptMgr();

    return true;
}
```

---

## 4. 클라이언트 초기화 (Init)

**파일**: `RYLClientMain.cpp:900+`

### 4.1. HackShield 업데이트 및 초기화

```cpp
bool CClientMain::Init(HINSTANCE hInstance, int iWidth, int iHeight)
{
    // 1. HackShield 업데이트
    if (!CRYLNetworkData::UpdateHShield())
    {
        MessageBox(NULL, "HackShield 업데이트 실패", "ERROR", MB_OK);
        return FALSE;
    }

    // 2. 화면 모드 설정 (전체화면만, Release 빌드)
#ifdef NDEBUG
    if (!m_iWindowMode)
        SetDisplay();
#endif
```

### 4.2. 윈도우 생성

```cpp
    // 3. 윈도우 클래스 등록
    WNDCLASS wc;
    wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
    wc.lpfnWndProc = (WNDPROC)WindowProc;
    wc.lpszClassName = "Return Of Warrior";
    RegisterClass(&wc);

    // 4. 윈도우 생성
    DWORD dwWinStyle = m_iWindowMode ?
        (WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX) :
        (WS_VISIBLE | WS_POPUP);

    m_hWnd = CreateWindow("Return Of Warrior",
                          "Return Of Warrior",
                          dwWinStyle, 0, 0,
                          m_iScreenWidth, m_iScreenHeight,
                          NULL, NULL, hInstance, NULL);
```

### 4.3. 레지스트리 설정 로드

**레지스트리**: `HKEY_LOCAL_MACHINE\Software\ROW\MP-Client`

```cpp
    // 5. 클라이언트 경로 및 설정 로드
    RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\ROW\\MP-Client", 0, KEY_READ, &hMPClientReg);

    // 서버 타입에 따라 다른 경로 읽기
    switch (m_pRYLNetworkData->m_eServerType)
    {
        case GameRYL::SERVER_TEST:
            RegQueryValueEx(hMPClientReg, "TestFolder", ...);
            break;
        case GameRYL::SERVER_REGULAR:
            RegQueryValueEx(hMPClientReg, "Folder", ...);
            break;
        case GameRYL::SERVER_BATTLE_LOHAN:
            RegQueryValueEx(hMPClientReg, "BGFolder", ...);
            break;
    }

    // InitValue 로드 (비디오 카드 설정)
    m_InitValue.Load(hMPClientReg);

    // 렌더링 옵션 로드
    CRenderOption::Load(hMPClientReg);

    // 조이스틱 설정
    RegQueryValueEx(hMPClientReg, "UseJoyStick", ...);
```

### 4.4. 시스템 정보 확인 및 최적화

```cpp
    // 6. 시스템 사양 확인
    CSystemInfo* pSystemInfo = new CSystemInfo;
    pSystemInfo->GetMemoryInfo();
    pSystemInfo->GetCPUInfo();
    pSystemInfo->GetVideoCardInfo();

    // 최소 사양 미달 시 렌더링 옵션 자동 최적화
    if (!pSystemInfo->IsMinimum())
    {
        CRenderOption::m_CharacterProjectShadowTerrain = 0;
        CRenderOption::m_BuildingLightmap = 0;
        CRenderOption::m_ObjectLOD = 1;
        CRenderOption::m_GrassRendering = 0;
        CRenderOption::m_bWeather = 0;
        // ... 기타 옵션 최소화

        MessageBox(NULL, "시스템 사양에 맞춰 그래픽 옵션을 조정했습니다.", ...);
    }
```

### 4.5. 게임가드 초기화

```cpp
    // 7. GameGuard 초기화
    if (!m_pRYLNetworkData->InitNPGameLib(m_hWnd))
    {
        return FALSE;
    }

    // 8. HackShield 초기화 및 시작
    if (!m_pRYLNetworkData->InitHShield(m_hWnd))
    {
        return FALSE;
    }

    if (!m_pRYLNetworkData->StartHShield(m_hWnd))
    {
        m_pRYLNetworkData->StopHShield();
        return FALSE;
    }
```

### 4.6. DirectX 및 그래픽 초기화

```cpp
    // 9. 입력 장치 초기화
    CInputDevice::GetInstance()->Initialize(m_hWnd, false, false, true);

    // 10. Direct3D 열거 및 설정
    CEnumD3D::Enum();
    CEnumD3D::m_nAdapter = m_InitValue.m_nAdapter;
    CEnumD3D::m_nDevice = m_InitValue.m_nDevice;
    CEnumD3D::m_nMode = m_InitValue.m_nMode;

    // 11. 그래픽 레이어 생성 (DirectX 디바이스 생성)
    m_BaseGraphicLayer.Create(m_hWnd, true, true, 0, 0,
                              m_iScreenWidth, m_iScreenHeight);

    // 12. 씬 매니저 생성
    m_pRYLGameData->m_lpSceneManager = new CSceneManager();
    m_pRYLGameData->m_lpSceneManager->SetDevice(m_BaseGraphicLayer.GetDevice());
    m_pRYLGameData->m_lpSceneManager->SetCamera(&m_BaseGraphicLayer.m_ViewCamera);
    m_pRYLGameData->m_lpSceneManager->Create(m_InitValue, m_strClientPath);
```

### 4.7. UI 및 사운드 초기화

```cpp
    // 13. UI 시스템 초기화
    g_TextEdit.Create(m_hWnd, m_BaseGraphicLayer.GetDevice());
    g_MessageBoxManager.Create();

    // 14. 사운드 시스템 초기화
    SoundMgrInit sndInit;
    sndInit.m_hWnd = m_hWnd;
    CSoundMgr::_GetInstance()->Init(sndInit);
```

### 4.8. 게임 데이터 로드

```cpp
    // 15. 게임 스크립트 로드
    sprintf(strScriptPath, "%s\\Language\\%s\\ItemScript.gsf",
            m_strClientPath, szLanguage[iLanguage]);
    g_ItemMgr.LoadItemProtoTypeBinary(strScriptPath);

    sprintf(strScriptPath, "%s\\Language\\%s\\SkillScript.gsf",
            m_strClientPath, szLanguage[iLanguage]);
    g_SkillMgr.LoadSkillsFromBinary(strScriptPath);

    sprintf(strScriptPath, "%s\\Language\\%s\\MonsterProtoType.gsf",
            m_strClientPath, szLanguage[iLanguage]);
    g_MonsterMgr.LoadMonstersFromBinary(strScriptPath);

    sprintf(strQuestPath, "%s\\Language\\%s\\Quest.mcf",
            m_strClientPath, szLanguage[iLanguage]);
    g_QuestList.Load(strQuestPath);

    // 16. 타이머 초기화
    GRYLTimer.InitTimer();

    // 17. 캐릭터 데이터 생성
    g_CharacterData.Create();
    EnemyCheck::CCheckTable::GetInstance().Initialize();

    return TRUE;
}
```

---

## 5. 씬 생성 (CreateScene)

**파일**: `RYLClientMain.cpp:1595`

```cpp
HRESULT CClientMain::CreateScene()
{
    // 1. 씬 매니저 생성 (이미 Init에서 생성됨)
    m_pRYLSceneManager = new CRYLSceneManager();

    // 2. 각종 씬 생성 및 등록
    // - 인트로 씬 (회사 로고)
    CRYLIntroScene* pIntroScene = new CRYLIntroScene();
    m_pRYLSceneManager->AddScene(INTRO_SCENE, pIntroScene);

    // - 로그인 씬
    CRYLLoginScene* pLoginScene = new CRYLLoginScene();
    m_pRYLSceneManager->AddScene(LOGIN_SCENE, pLoginScene);

    // - 종족 선택 씬
    CRYLRaceSelectScene* pRaceSelectScene = new CRYLRaceSelectScene();
    m_pRYLSceneManager->AddScene(RACE_SELECT_SCENE, pRaceSelectScene);

    // - 캐릭터 선택 씬
    CRYLCharacterSelectScene* pCharSelectScene = new CRYLCharacterSelectScene();
    m_pRYLSceneManager->AddScene(CHARACTER_SELECT_SCENE, pCharSelectScene);

    // - 로딩 씬
    CRYLLoadingScene* pLoadingScene = new CRYLLoadingScene();
    m_pRYLSceneManager->AddScene(LOADING_SCENE, pLoadingScene);

    // - 게임 씬 (실제 게임 플레이)
    CRYLGameScene* pGameScene = new CRYLGameScene();
    m_pRYLSceneManager->AddScene(GAME_SCENE, pGameScene);

    // 3. 초기 씬 활성화 (인트로 씬)
    m_pRYLSceneManager->ChangeScene(INTRO_SCENE);

    return S_OK;
}
```

**씬 구조**:
```
INTRO_SCENE          # 회사 로고
    ↓
LOGIN_SCENE          # 로그인
    ↓
RACE_SELECT_SCENE    # 종족 선택 (Akkan/Human)
    ↓
CHARACTER_SELECT_SCENE  # 캐릭터 선택/생성/삭제
    ↓
LOADING_SCENE        # 맵 로딩
    ↓
GAME_SCENE          # 실제 게임 플레이
```

---

## 6. 메인 루프

### 6.1. 메시지 루프

**파일**: `RYLClientMain.cpp:192-214`

```cpp
while(1)
{
    // 프레임 카운터 증가
    CProfileManager::Increment_Frame_Counter();

    // Windows 메시지 처리
    if (PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE))
    {
        // 종료 메시지 확인
        if (0 == GetMessage(&msg, NULL, 0, 0))
        {
            return (int)msg.wParam;
        }

        // 메시지 처리
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    else  // 메시지가 없으면 게임 로직 실행
    {
        CSimpleProfile::GetInstance().IncrementFrameCounter();

        PROFILE("Update");

        Sleep(1);                   // CPU 사용률 조절 (1ms)
        g_ClientMain.Update();      // 게임 상태 업데이트
        g_ClientMain.Render();      // 화면 렌더링
    }
}
```

### 6.2. Update (게임 로직 업데이트)

**추정 실행 순서**:

```cpp
void CClientMain::Update()
{
    // 1. 타이머 업데이트
    GRYLTimer.Update();

    // 2. 입력 처리
    CInputDevice::GetInstance()->Update();

    // 3. 네트워크 패킷 처리
    m_pRYLNetworkData->ProcessNetworkMessages();

    // 4. 현재 씬 업데이트
    m_pRYLSceneManager->Update(deltaTime);

    // 5. 사운드 업데이트
    CSoundMgr::_GetInstance()->Update();

    // 6. UI 업데이트
    // - 채팅 메시지
    // - 인벤토리
    // - 캐릭터 상태
    // - 각종 다이얼로그

    // 7. 캐릭터 및 몬스터 AI 업데이트
    RYLCreatureManager::Instance()->Update();

    // 8. 이펙트 시스템 업데이트
    // - 파티클
    // - 스킬 이펙트
    // - 날씨 효과

    // 9. 카메라 업데이트
    g_CharacterData.m_Camera.Update();

    // 10. 충돌 검사
    // 11. 물리 시뮬레이션
}
```

### 6.3. Render (화면 렌더링)

**추정 실행 순서**:

```cpp
void CClientMain::Render()
{
    // 1. 렌더링 시작
    m_BaseGraphicLayer.BeginScene();

    // 2. 씬 렌더링
    m_pRYLGameData->m_lpSceneManager->Render();

    // 3. 현재 씬 렌더링 (오버라이드)
    m_pRYLSceneManager->Render();

    // 4. 3D 오브젝트 렌더링
    // - 지형
    // - 캐릭터
    // - 몬스터
    // - NPC
    // - 건물
    // - 아이템

    // 5. 이펙트 렌더링
    // - 파티클
    // - 스킬 이펙트
    // - 날씨

    // 6. UI 렌더링 (2D)
    // - 채팅창
    // - 미니맵
    // - 캐릭터 정보
    // - 인벤토리
    // - 각종 다이얼로그

    // 7. 디버그 정보 (Debug 빌드만)
#ifdef _DEBUG
    // - FPS
    // - 네트워크 상태
    // - 메모리 사용량
#endif

    // 8. 렌더링 종료 및 화면 출력
    m_BaseGraphicLayer.EndScene();
    m_BaseGraphicLayer.Present();
}
```

---

## 7. 윈도우 메시지 처리

### WindowProc 함수

**파일**: `RYLClientMain.cpp:133`

```cpp
unsigned long __stdcall WindowProc(HWND hWnd, unsigned uMsg,
                                    WPARAM wParam, LPARAM lParam)
{
    return g_ClientMain.ClientProc(hWnd, uMsg, wParam, lParam);
}
```

### ClientProc에서 처리하는 주요 메시지

```cpp
unsigned long CClientMain::ClientProc(HWND hWnd, unsigned uMsg,
                                       WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
        case WM_KEYDOWN:
        case WM_KEYUP:
            // 키보드 입력 처리
            g_DeviceInput.OnKeyboard(uMsg, wParam, lParam);
            break;

        case WM_LBUTTONDOWN:
        case WM_LBUTTONUP:
        case WM_RBUTTONDOWN:
        case WM_RBUTTONUP:
        case WM_MOUSEMOVE:
            // 마우스 입력 처리
            g_DeviceInput.OnMouse(uMsg, wParam, lParam);
            break;

        case WM_TIMER:
            if (wParam == 255)  // HackShield 체크 타이머 (10초마다)
            {
                // HackShield 상태 확인
            }
            break;

        case WM_ACTIVATE:
            // 윈도우 활성화/비활성화
            if (LOWORD(wParam) == WA_INACTIVE)
            {
                // 비활성화 시 일시정지
            }
            break;

        case WM_CLOSE:
        case WM_DESTROY:
            // 종료 처리
            PostQuitMessage(0);
            break;

        case WM_CHAR:
            // 문자 입력 (채팅)
            g_TextEdit.OnChar(wParam);
            break;

        case WM_IME_*:
            // 한글 입력 (IME)
            g_TextEdit.OnIME(uMsg, wParam, lParam);
            break;
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
```

---

## 8. 네트워크 통신 흐름

### 8.1. 연결 수립

```
1. Login.exe 실행
   └─ 사용자 ID/PW 입력
   └─ 인증 서버 연결

2. Client.exe 실행
   └─ Login.exe로부터 서버 정보 수신
   └─ AuthHandler를 통해 인증 서버 연결
   └─ 로그인 성공 시 게임 서버 목록 수신

3. 게임 서버 선택
   └─ GameHandler를 통해 게임 서버 연결
   └─ 캐릭터 목록 수신

4. 캐릭터 선택/생성
   └─ 게임 월드 진입
```

### 8.2. 패킷 처리

**AuthHandler** (인증 서버):
```cpp
// RYLClient/EventHandler/AuthHandler.cpp
int CAuthEventHandler::OnDispatch(PktBase* lpPktBase, INET_Addr& peerAddr)
{
    // 로그인, 서버 목록 등 인증 관련 패킷 처리
}
```

**GameHandler** (게임 서버):
```cpp
// RYLClient/EventHandler/GameHandler.cpp
int CGameEventHandler::OnDispatch(PktBase* lpPktBase, INET_Addr& peerAddr)
{
    // 등록된 이벤트 핸들러 호출
    unsigned char cCmd = lpPktBase->GetCommand();

    // 명령어에 해당하는 핸들러 실행
    EventFunc fnEvent = FindHandler(cCmd);
    if (fnEvent)
    {
        fnEvent(this, lpPktBase);
    }
}
```

**GameProcess 핸들러들**:
```
LoginoutProcess     # 로그인/로그아웃
CharInfoProcess     # 캐릭터 정보
MoveProcess         # 이동
FightProcess        # 전투
ItemProcess         # 아이템
SkillProcess        # 스킬
ChatProcess         # 채팅
QuestProcess        # 퀘스트
CastleProcess       # 공성전
BattleGroundProcess # 전장
CommunityProcess    # 길드/친구
BroadcastProcess    # 공지
EtcProcess          # 기타
```

---

## 9. 종료 절차

### 9.1. 정상 종료

```cpp
// 사용자가 게임 종료 선택
1. 메뉴에서 "게임 종료" 클릭
   └─ 종료 확인 메시지 박스
   └─ "예" 클릭

2. 로그아웃 패킷 전송
   └─ SendPacket::Logout(...)
   └─ 서버 응답 대기

3. WM_CLOSE 메시지 발생
   └─ PostQuitMessage(0)

4. 메인 루프 종료
   └─ GetMessage(...) == 0

5. g_ClientMain.Destroy() 호출
```

### 9.2. Destroy 함수

```cpp
void CClientMain::Destroy()
{
    // 1. 씬 정리
    if (m_pRYLSceneManager)
    {
        m_pRYLSceneManager->DestroyAllScenes();
        delete m_pRYLSceneManager;
    }

    // 2. 네트워크 종료
    if (m_pRYLNetworkData)
    {
        m_pRYLNetworkData->Disconnect();

        // GameGuard 종료
        if (m_pRYLNetworkData->m_lpNPGameLib)
        {
            delete m_pRYLNetworkData->m_lpNPGameLib;
        }

        // HackShield 종료
        m_pRYLNetworkData->StopHShield();
        m_pRYLNetworkData->UnInstHShield();
    }

    // 3. 사운드 시스템 종료
    CSoundMgr::_GetInstance()->Destroy();

    // 4. 그래픽 시스템 종료
    m_BaseGraphicLayer.Destroy();

    // 5. UI 시스템 종료
    g_TextEdit.Destroy();
    g_MessageBoxManager.Destroy();

    // 6. 입력 장치 해제
    CInputDevice::GetInstance()->Destroy();

    // 7. 각종 매니저 해제
    delete m_pCastleManager;
    delete m_pCampManager;
    delete m_pSkillScriptManager;

    // 8. 윈도우 파괴
    if (m_hWnd)
    {
        DestroyWindow(m_hWnd);
        m_hWnd = NULL;
    }

    // 9. 레지스트리 정리 (필요시)
    // 10. 임시 파일 삭제 (필요시)
}
```

---

## 10. 실행 시퀀스 다이어그램

### 전체 흐름

```
[시작]
  │
  ├─ WinMain()
  │   ├─ Exception Handler 등록
  │   └─ AntiFunc() 호출
  │
  ├─ AntiFunc()
  │   ├─ Login.exe 확인 (Release만)
  │   ├─ 서버 정보 획득
  │   ├─ 화면 설정 읽기
  │   │
  │   ├─ InitCreateGameClass()
  │   │   ├─ 게임 데이터 클래스 생성
  │   │   ├─ 네트워크 데이터 클래스 생성
  │   │   ├─ 문자열 테이블 로드
  │   │   └─ 매니저 클래스 생성
  │   │
  │   ├─ Init()
  │   │   ├─ HackShield 업데이트
  │   │   ├─ 윈도우 생성
  │   │   ├─ 레지스트리 설정 로드
  │   │   ├─ 시스템 사양 확인
  │   │   ├─ 게임가드 초기화
  │   │   │   ├─ GameGuard 초기화
  │   │   │   └─ HackShield 시작
  │   │   ├─ DirectX 초기화
  │   │   ├─ 씬 매니저 생성
  │   │   ├─ UI 시스템 초기화
  │   │   ├─ 사운드 시스템 초기화
  │   │   └─ 게임 데이터 로드
  │   │
  │   ├─ CreateScene()
  │   │   ├─ 인트로 씬 생성
  │   │   ├─ 로그인 씬 생성
  │   │   ├─ 종족 선택 씬 생성
  │   │   ├─ 캐릭터 선택 씬 생성
  │   │   ├─ 로딩 씬 생성
  │   │   ├─ 게임 씬 생성
  │   │   └─ 인트로 씬 활성화
  │   │
  │   └─ 메인 루프
  │       ├─ Windows 메시지 처리
  │       │   ├─ WM_KEYDOWN/UP
  │       │   ├─ WM_*BUTTON*
  │       │   ├─ WM_TIMER (HackShield 체크)
  │       │   └─ WM_CLOSE (종료)
  │       │
  │       └─ 게임 로직 (메시지 없을 때)
  │           ├─ Update()
  │           │   ├─ 타이머
  │           │   ├─ 입력 처리
  │           │   ├─ 네트워크 패킷 처리
  │           │   ├─ 씬 업데이트
  │           │   ├─ 사운드 업데이트
  │           │   ├─ UI 업데이트
  │           │   ├─ 캐릭터/AI 업데이트
  │           │   └─ 물리/충돌 처리
  │           │
  │           └─ Render()
  │               ├─ BeginScene()
  │               ├─ 3D 씬 렌더링
  │               ├─ 캐릭터/몬스터 렌더링
  │               ├─ 이펙트 렌더링
  │               ├─ UI 렌더링 (2D)
  │               ├─ EndScene()
  │               └─ Present()
  │
  └─ Destroy()
      ├─ 씬 정리
      ├─ 네트워크 종료
      ├─ 게임가드 종료
      ├─ 사운드 종료
      ├─ 그래픽 종료
      ├─ UI 종료
      └─ 윈도우 파괴

[종료]
```

---

## 11. 씬 전환 흐름

### 게임 플레이 진행 순서

```
1. INTRO_SCENE (인트로)
   - 회사 로고 표시
   - 자동으로 LOGIN_SCENE으로 전환
   ↓

2. LOGIN_SCENE (로그인)
   - 사용자 ID/PW 입력 또는 자동 로그인
   - 인증 서버 연결
   - 로그인 성공 → RACE_SELECT_SCENE
   ↓

3. RACE_SELECT_SCENE (종족 선택)
   - Akkan vs Human 선택
   - 게임 서버 선택
   - 서버 연결 → CHARACTER_SELECT_SCENE
   ↓

4. CHARACTER_SELECT_SCENE (캐릭터 선택)
   - 캐릭터 목록 표시
   - 캐릭터 생성/삭제/선택
   - 선택 완료 → LOADING_SCENE
   ↓

5. LOADING_SCENE (로딩)
   - 맵 데이터 로딩
   - 리소스 로딩
   - 로딩 완료 → GAME_SCENE
   ↓

6. GAME_SCENE (게임 플레이)
   - 실제 MMORPG 게임 플레이
   - 이동, 전투, 퀘스트, 아이템, 스킬
   - 로그아웃 → LOGIN_SCENE 또는 종료
```

---

## 12. 타이밍 및 성능

### 프레임 레이트 제어

```cpp
while(1)
{
    if (PeekMessage(...))
    {
        // 메시지 처리 (즉시)
    }
    else
    {
        Sleep(1);           // 1ms 대기 (CPU 사용률 조절)
        Update();           // 게임 로직
        Render();           // 렌더링
    }
}
```

**특징**:
- VSync 없음 (프레임 제한 없음)
- `Sleep(1)` 로 CPU 점유율 조절
- 프레임 레이트는 하드웨어 성능에 의존

### HackShield 주기적 체크

```cpp
// 초기화 시 타이머 설정 (10초마다)
SetTimer(hWnd, 255, 10000, NULL);

// WM_TIMER 메시지 처리
case WM_TIMER:
    if (wParam == 255)
    {
        // HackShield 상태 확인
        _AhnHS_CheckHackShieldRunningStatus();
    }
    break;
```

---

## 13. 에러 처리

### 초기화 실패 시

```cpp
if (!g_ClientMain.InitCreateGameClass())
{
    g_ClientMain.Destroy();
    return 0;
}

if (!g_ClientMain.Init(...))
{
    g_ClientMain.Destroy();
    return 0;
}

if (FAILED(g_ClientMain.CreateScene()))
{
    g_ClientMain.Destroy();
    return 0;
}
```

**각 단계에서 실패 시 즉시 정리 후 종료**

### 크래시 덤프

```cpp
// WinMain에서 Exception Handler 등록
Exception::EnableUnhandledExceptioinFilterEx(UserUnhandledExceptionFilterEx, true);
Exception::SetDumpType(Exception::NormalDump);
Exception::EnableSaveDump(true);
```

**크래시 발생 시**:
- 덤프 파일 생성 (`.dmp`)
- 사용자 정보 수집
- 에러 리포트 생성

---

## 14. 디버그 vs Release 차이

| 기능 | Debug 빌드 | Release 빌드 |
|------|-----------|-------------|
| **AdminMode** | `ADMIN_L3` (게임가드 비활성화) | `ADMIN_NONE` (게임가드 활성화) |
| **Login.exe 확인** | 건너뜀 | 필수 |
| **전체화면 강제** | 아니오 | 예 (`SetDisplay()`) |
| **최적화** | 없음 | SSE2, OpenMP |
| **디버그 출력** | FPS, 네트워크 상태 등 | 없음 |
| **GameGuard** | 비활성화 | 활성화 |
| **HackShield** | 비활성화 | 활성화 (Release_MY) |

---

## 15. 요약

### 핵심 실행 단계

1. **WinMain** → Exception Handler + AntiHack
2. **AntiFunc** → 메인 초기화 및 루프
3. **InitCreateGameClass** → 게임 클래스 생성
4. **Init** → 윈도우, DirectX, 게임가드, 리소스 초기화
5. **CreateScene** → 6개 씬 생성 및 활성화
6. **메인 루프** → Update + Render (무한 반복)
7. **Destroy** → 정리 및 종료

### 의존 관계

```
WinMain
 └─ AntiFunc
     ├─ InitCreateGameClass (클래스 생성)
     │   ├─ CRYLGameData
     │   ├─ CRYLNetworkData
     │   └─ 각종 매니저
     │
     ├─ Init (시스템 초기화)
     │   ├─ HackShield
     │   ├─ GameGuard
     │   ├─ DirectX
     │   └─ 리소스 로드
     │
     ├─ CreateScene (씬 생성)
     │   └─ 6개 씬 등록
     │
     └─ 메인 루프
         ├─ Update (로직)
         └─ Render (렌더링)
```

---

**문서 작성일**: 2025-11-29
**분석 도구**: Claude Code
**프로젝트**: NeoRylClient - ROW (Reign of Revolution)
