탱크 게임 서버 프로젝트

ProudNet 네트워킹 라이브러리를 사용한 멀티플레이어 탱크 게임 서버 구현으로, C#과 C++ 버전을 모두 제공하여 크로스 플랫폼을 지원합니다.

📋 목차

사전 요구사항

이 프로젝트를 빌드하기 전에 tank_server 프로젝트 폴더와 같은 레벨에 ProudNet 폴더가 설치되어 있어야 합니다.

필수 디렉터리 구조

project_root/
├── tank_server/          # 이 프로젝트
│   ├── Common/
│   ├── Server/
│   ├── Client/
│   └── Server_CPP/
└── ProudNet/            # 필수: ProudNet 설치에서 가져온 파일들
    ├── doc/             # ProudNet 문서
    ├── include/         # ProudNet 헤더 파일들
    ├── lib/             # ProudNet 라이브러리 파일들
    ├── Sample/          # ProudNet 샘플 프로젝트들
    └── util/            # ProudNet 유틸리티들

ProudNet 설치

  1. 공식 웹사이트에서 ProudNet을 다운로드하고 설치합니다
  2. ProudNet 폴더에 다음 하위 디렉터리들이 포함되어 있는지 확인합니다:
    • doc/ - 문서 파일들
    • include/ - C++ 개발을 위한 헤더 파일들
    • lib/ - .NET과 C++ 모두를 위한 라이브러리 파일들
    • Sample/ - 예제 프로젝트들
    • util/ - 유틸리티 도구들과 라이선스 인증

프로젝트 구조

📁 Common

서버와 클라이언트 구현 모두에서 사용되는 공유 리소스들을 포함합니다.

내용:

주요 파일들:

🖥️ Server

탱크 게임 서버의 C# 구현입니다.

기능:

주요 파일들:

🎮 Client

탱크 게임을 위한 C# 콘솔 기반 클라이언트입니다.

기능:

주요 파일들:

🐧 Server_CPP

Linux 지원과 함께 제공되는 탱크 게임 서버의 C++ 구현입니다.

기능:

주요 파일들:

빌드 옵션들:

개발 노트

시작하기

사전 요구사항

  1. ProudNet 설치 위치에서 ProudNet 파일들을 복사하여 tank_server/와 같은 레벨에 ProudNet/ 디렉터리를 생성합니다
  2. 프로토콜 컴파일을 위해 ProudNet/util/PIDL.exe가 존재하는지 확인합니다

1. C# 서버 구현

1단계: 프로토콜 정의 이해 (Tank.PIDL)

Tank.PIDL 파일은 서버와 클라이언트 간 통신 프로토콜을 정의합니다:

// Tank.PIDL - 프로토콜 인터페이스 정의 언어
global Tank 2000 // 클라이언트-서버 및 서버-클라이언트 RMI, 첫 번째 메시지 ID = 2000
{
    // 클라이언트에서 서버로 보내는 함수들
    SendMove([in] float posX, [in] float posY, [in] float direction);
    SendFire([in] int shooterId, [in] float direction, [in] float launchForce, ...);
    SendTankType([in] int tankType);
    
    // 서버에서 클라이언트로 보내는 함수들
    OnPlayerJoined([in] int clientId, [in] float posX, [in] float posY, [in] int tankType);
    OnTankPositionUpdated([in] int clientId, [in] float posX, [in] float posY, [in] float direction);
    OnSpawnBullet([in] int clientId, [in] int shooterId, ...);
    // ... 더 많은 RMI 함수들
}

이 PIDL 파일은 다음을 정의합니다:

2단계: C# Stub 및 Proxy 클래스 생성

PIDL 컴파일러를 실행하여 C# 네트워킹 코드를 생성합니다:

cd tank_server/Common
CompilePIDL_cs.bat

예상 출력:

C:\Users\wayne\Documents\proud_tank\tank_server\Common [master +5 ~14 -15 !]> .\CompilePIDL_cs.bat 
PIDL compile complete!
Press any key to continue . . .

이 스크립트는 다음을 수행합니다:

3단계: 서버 빌드

Server 디렉터리로 이동하여 빌드합니다:

cd tank_server/Server
build.bat

예상 출력:

C:\Users\wayne\Documents\proud_tank\tank_server\Server [master +15 ~13 -15 !]> ./build.bat
========================================
Tank Server Build Script
========================================
Build configuration: Debug
Building Tank Server...
Restore complete (0.2s)
  TankServer succeeded (1.8s) → bin\Debug\net9.0\TankServer.dll

Build succeeded in 2.3s
Build completed successfully!
Using build output path: bin\Debug\net9.0
Build output directory exists: bin\Debug\net9.0
ProudNet DotNet directory exists: ..\..\ProudNet\lib\DotNet
ProudNet x64 directory exists: ..\..\ProudNet\lib\DotNet\x64
========================================
Copying ProudNet DLLs...
========================================
Copying libcrypto-3-x64.dll...
        1 file(s) copied.
Copying libssl-3-x64.dll...
        1 file(s) copied.
Copying ProudDotNetClient.dll...
        1 file(s) copied.
Copying ProudDotNetClient.pdb...
        1 file(s) copied.
Copying ProudDotNetServer.dll...
        1 file(s) copied.
Copying ProudDotNetServer.pdb...
        1 file(s) copied.
Copying ProudNetClient.dll...
        1 file(s) copied.
Copying ProudNetClientPlugin.dll...
        1 file(s) copied.
Copying ProudNetServer.dll...
        1 file(s) copied.
Copying ProudNetServerPlugin.dll...
        1 file(s) copied.
Copying ProudNetServerPlugin.pdb...
        1 file(s) copied.
========================================
Build and DLL copy completed!
========================================

Output directory: bin\Debug\net9.0
You can now run the Tank Server executable.

Press any key to continue . . .

빌드 스크립트는 다음을 수행합니다:

4단계: 서버 실행

cd tank_server/Server/bin/Debug/net9.0
TankServer.exe

예상 출력:

C:\Users\wayne\Documents\proud_tank\tank_server\Server [master +5 ~14 -15 !]> .\bin\Debug\net9.0\TankServer.exe      
Tank Server started on port 33334
Server is running. Commands:
status: Show connected clients
health [id]: Show tank health (all or specific ID)
damage id amount: Apply damage to a tank
heal id amount: Heal a tank
respawn id x y: Respawn a tank at position (x,y)
q: Quit server
Client 3 connected
New tank created for client 3 with tank type -1 and health 100/100
Not enough clients to create P2P group (need at least 2)

서버는 다음을 수행합니다:

2. C# 클라이언트 구현

1단계: 공유 프로토콜 이해

클라이언트는 서버와 동일한 Tank.PIDL 파일을 사용하여 완벽한 프로토콜 호환성을 보장합니다:

이 접근 방식은 다음을 보장합니다:

2단계: 클라이언트 빌드

Client 디렉터리로 이동하여 빌드합니다:

cd tank_server/Client  
build.bat

예상 출력:

C:\Users\wayne\Documents\proud_tank\tank_server\Client [master +5 ~14 -15 !]> .\build.bat
========================================
Tank Client Build Script
========================================
Build configuration: Debug
Building Tank Client...
Restore complete (0.3s)
  TankClient succeeded (0.2s) → bin\Debug\net9.0\TankClient.dll

Build succeeded in 0.8s
Build completed successfully!
Using build output path: bin\Debug\net9.0
Build output directory exists: bin\Debug\net9.0
ProudNet DotNet directory exists: ..\..\ProudNet\lib\DotNet
ProudNet x64 directory exists: ..\..\ProudNet\lib\DotNet\x64
========================================
Copying ProudNet DLLs...
========================================
Copying libcrypto-3-x64.dll...
        1 file(s) copied.
Copying libssl-3-x64.dll...
        1 file(s) copied.
Copying ProudDotNetClient.dll...
        1 file(s) copied.
Copying ProudDotNetClient.pdb...
        1 file(s) copied.
Copying ProudDotNetServer.dll...
        1 file(s) copied.
Copying ProudNetClient.dll...
        1 file(s) copied.
Copying ProudNetClientPlugin.dll...
        1 file(s) copied.
Copying ProudNetServer.dll...
        1 file(s) copied.
========================================
Build and DLL copy completed!
========================================

Output directory: bin\Debug\net9.0
You can now run the Tank Client executable.

Press any key to continue . . .

클라이언트 빌드 스크립트는 서버와 동일한 작업을 수행합니다:

3단계: 클라이언트 실행

cd tank_server/Client/bin/Debug/net9.0
TankClient.exe

예상 출력:

C:\Users\wayne\Documents\proud_tank\tank_server\Client [master +6 ~14 -15 !]> .\bin\Debug\net9.0\TankClient.exe
Connecting to server...
Commands:
move x y dir : Move tank to position (x,y) with direction dir
fire dir [force] : Fire in direction dir with optional force (default 25.0)
tank n       : Select tank type (0-3)
health h [max]: Update tank health to h with optional max health
destroy [id] : Send tank destroyed event (id of destroyer, default 0 = environment)
spawn x y dir type health: Spawn/respawn tank
msg text     : Send P2P message to other clients
history      : Show message history
status       : Show P2P connection status
auto         : Toggle auto movement
q            : Quit
Connected to server. My ID: 3

🔍 서버 연결 확인:

클라이언트가 성공적으로 연결되면 서버 콘솔에서도 연결 메시지를 확인할 수 있습니다:

서버 콘솔 출력:

C:\Users\wayne\Documents\proud_tank\tank_server\Server [master +5 ~14 -15 !]> .\bin\Debug\net9.0\TankServer.exe
Tank Server started on port 33334
Server is running. Commands:
status: Show connected clients
health [id]: Show tank health (all or specific ID)
damage id amount: Apply damage to a tank
heal id amount: Heal a tank
respawn id x y: Respawn a tank at position (x,y)
q: Quit server
Client 3 connected
New tank created for client 3 with tank type -1 and health 100/100
Not enough clients to create P2P group (need at least 2)

📝 서버 로그 설명:

💡 P2P 기능을 테스트하려면:

다른 터미널에서 두 번째 클라이언트를 실행하면 다음을 확인할 수 있습니다:

두 번째 클라이언트 출력:

C:\Users\wayne\Documents\proud_tank\tank_server\Client [master +5 ~14 -15 !]> .\bin\Debug\net9.0\TankClient.exe          
Connecting to server...                                                                                                                                                                                                                             
Commands:                                                                                                                                                                                                                                           
move x y dir : Move tank to position (x,y) with direction dir                                                                                                                                                                                       
fire dir [force] : Fire in direction dir with optional force (default 25.0)
tank n       : Select tank type (0-3)
health h [max]: Update tank health to h with optional max health
destroy [id] : Send tank destroyed event (id of destroyer, default 0 = environment)
spawn x y dir type health: Spawn/respawn tank
msg text     : Send P2P message to other clients
history      : Show message history
status       : Show P2P connection status
auto         : Toggle auto movement
q            : Quit
Connected to server. My ID: 4
P2P: Member 4 joined group 5
P2P: Member 3 joined group 5
P2P: Added member 3 to group member list
OnPlayerJoined: Tank 3 joined at (12.939716,28.795837) with tank type -1
OnTankHealthUpdated: Tank 3 health: 100/100
P2P: Received group info, Group ID: 5

업데이트된 서버 콘솔 출력:

C:\Users\wayne\Documents\proud_tank\tank_server\Server [master +5 ~14 -15 !]> .\bin\Debug\net9.0\TankServer.exe
Tank Server started on port 33334
Server is running. Commands:
status: Show connected clients
health [id]: Show tank health (all or specific ID)
damage id amount: Apply damage to a tank
heal id amount: Heal a tank
respawn id x y: Respawn a tank at position (x,y)
q: Quit server
Client 3 connected
New tank created for client 3 with tank type -1 and health 100/100
Not enough clients to create P2P group (need at least 2)
Client 4 connected
New tank created for client 4 with tank type -1 and health 100/100
Sending existing player info to new client: ID=3, Type=-1, Health=100/100
Notifying existing client 3 about new player: ID=4, Type=-1, Health=100/100
P2P group created with 2 members, Group ID: 5
Sent P2P group info to client 3: P2P_GROUP_INFO:5
Sent P2P group info to client 4: P2P_GROUP_INFO:5

📝 다중 클라이언트 연결 분석:

두 번째 클라이언트가 연결될 때:

  1. 클라이언트 4 연결 - 서버가 새 ID를 할당하고 탱크 객체 생성
  2. 플레이어 동기화 - 서버가 플레이어 정보를 교환:
    • 기존 플레이어 정보(클라이언트 3)를 새 클라이언트(클라이언트 4)에게 전송
    • 기존 클라이언트(클라이언트 3)에게 새 플레이어(클라이언트 4)에 대해 알림
  3. P2P 그룹 생성 - 이제 2개 이상의 클라이언트가 있으므로:
    • 서버가 ID 5로 P2P 그룹 생성
    • 두 클라이언트 모두 P2P 그룹 정보 수신
    • 클라이언트들이 이제 P2P 메시징을 통해 직접 통신 가능

클라이언트 측 P2P 이벤트:

🎮 이제 멀티플레이어 기능을 테스트할 수 있습니다:

3. C++ 서버 구현 (선택사항)

C++ 서버 구현은 C# 서버와 정확히 동일한 기능을 제공하며, 크로스 플랫폼 지원과 컨테이너 배포 옵션을 제공합니다. 이는 ProudNet의 다중 언어 기능을 보여주는 선택적 고급 구현입니다.

프로토콜 호환성

C#과 C++ 서버 모두 동일한 Tank.PIDL 파일을 사용하므로 완전히 호환됩니다:

C++ 구현의 주요 장점

단계 1: C++ Stub 및 Proxy 클래스 생성

먼저 PIDL 파일에서 C++ 네트워킹 코드를 생성합니다:

cd tank_server/Common
CompilePIDL_cpp.bat

예상 출력:

C:\Users\wayne\Documents\proud_tank\tank_server\Common [master +5 ~14 -15 !]> .\CompilePIDL_cpp.bat
[INFO] Generating C++ files from Tank.PIDL...
[INFO] PIDL C++ compilation complete!
[INFO] Generated files in ..\Server_CPP\include directory.
Press any key to continue . . .

이것은 Server_CPP/include/ 디렉토리에 C++ stub/proxy 클래스를 생성합니다:

단계 2: C++ 서버 빌드 (Windows)

Windows 빌드 사전 요구사항

C++ 서버를 빌드하기 전에 다음 구성 요소가 설치되어 있는지 확인하세요:

필수 소프트웨어:

필수 Visual Studio 구성 요소:

Visual Studio를 설치할 때 다음 워크로드와 구성 요소를 포함해야 합니다:

ATL에 대한 중요 참고사항:

ATL(Active Template Library)은 Windows에서 ProudNet 링킹에 필수적입니다. CMakeLists.txt에서 명시적으로 링크되는 것을 볼 수 있습니다:

target_link_libraries(TankGameServer
    # ... other libraries ...
    atls       # ATL library addition
)

빌드 프로세스

Server_CPP 디렉토리로 이동하여 제공된 스크립트를 사용하여 빌드합니다:

cd tank_server/Server_CPP
build.bat

예상 빌드 출력:

C:\Users\wayne\Documents\proud_tank\tank_server\Server_CPP [master +5 ~14 -15 !]> .\build.bat
[INFO] =========================================
[INFO] Starting TankGameServer C++ Build...
[INFO] =========================================
[INFO] Detecting Visual Studio installation...
[INFO] Visual Studio 2022 Community found
[INFO] Setting up VS2022 environment...
**********************************************************************
** Visual Studio 2022 Developer Command Prompt v17.14.0
** Copyright (c) 2022 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
[INFO] Using Visual Studio 2022 with generator: NMake Makefiles
[INFO] ProudNet Path: C:\Users\wayne\Documents\proud_tank\ProudNet
[INFO] Build Type: Release
[INFO] Using: Visual Studio 2022 with NMake Makefiles
[INFO] Checking and generating PIDL files...
[INFO] Compiling PIDL files...
[INFO] Generating C++ files from Tank.PIDL...
[INFO] PIDL C++ compilation complete
[INFO] Generated files in ..\Server_CPP\include directory.
Press any key to continue . . .
[INFO] Creating build directory...
[INFO] Removing existing build directory...
[INFO] Configuring CMake...
[INFO] Using NMake Makefiles generator
-- The C compiler identification is MSVC 19.44.35207.1
-- The CXX compiler identification is MSVC 19.44.35207.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.44.35207/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.44.35207/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Building on Windows - Using OpenSSL and CURL from ProudNet
-- System check: Windows
-- Current working directory: C:/Users/wayne/Documents/proud_tank/tank_server/Server_CPP
-- Build type: Release
-- ProudNet Path: C:\Users\wayne\Documents\proud_tank\ProudNet
-- Operating System: Windows
-- Using Visual Studio version from command line: 2022
-- Found Visual Studio installation: C:/Program Files/Microsoft Visual Studio/2022/Community
-- Visual Studio Path: C:/Program Files/Microsoft Visual Studio/2022/Community
-- Using Release Library Path: C:\Users\wayne\Documents\proud_tank\ProudNet/lib/x64/v140/Release
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/wayne/Documents/proud_tank/tank_server/Server_CPP/build
[INFO] Building project...
[ 33%] Building CXX object CMakeFiles/TankGameServer.dir/src/TankServer.cpp.obj
TankServer.cpp
[ 66%] Building CXX object CMakeFiles/TankGameServer.dir/C_/Users/wayne/Documents/proud_tank/tank_server/Common/Vars.cpp.obj
Vars.cpp
[100%] Linking CXX executable TankServer.exe
[100%] Built target TankGameServer
[INFO] Build successful
[INFO] Executable: C:\Users\wayne\Documents\proud_tank\tank_server\Server_CPP\build\Release\TankGameServer.exe
[INFO] Copying required DLL files...
[INFO] =========================================
[INFO] Build completed
[INFO] Executable: C:\Users\wayne\Documents\proud_tank\tank_server\Server_CPP\build\TankServer.exe
[INFO] =========================================
Press any key to continue . . .

빌드 프로세스 분석:

  1. Visual Studio 감지: VS 2022 Community 설치를 자동으로 감지
  2. 환경 설정: x64 도구로 VS 2022 Developer Command Prompt 초기화
  3. PIDL 컴파일: C++ stub/proxy 클래스 자동 생성
  4. CMake 구성: MSVC 컴파일러용 NMake Makefiles 생성기 사용
  5. 컴파일: C++17 표준으로 TankServer.cppVars.cpp 빌드
  6. 링킹: ProudNet 라이브러리, Windows 시스템 라이브러리, ATL과 링크
  7. DLL 복사: 필요한 ProudNet DLL을 실행 파일 디렉토리로 복사

빌드 스크립트는 다음을 수행합니다:

단계 3: C++ 서버 실행 (Windows)

cd tank_server/Server_CPP
run.bat

예상 서버 출력:

C:\Users\wayne\Documents\proud_tank\tank_server\Server_CPP [master +5 ~14 -15 !]> .\run.bat
[INFO] Starting TankGameServer C++ Server...
[INFO] Found executable at build\TankServer.exe (NMake build
[INFO] Server is starting. Press 'q' to quit.
[INFO] Running: C:\Users\wayne\Documents\proud_tank\tank_server\Server_CPP\build\TankServer.exe
========== Tank Server Started ==========
TCP Server listening on 0.0.0.0:33334
WebSocket Server listening on 0.0.0.0:33335/ws
Ready to accept connections from all network interfaces
==========================================
Server is running. Commands:
status: Show connected clients
health [id]: Show tank health (all or specific ID)
damage id amount: Apply damage to a tank
heal id amount: Heal a tank
respawn id x y: Respawn a tank at position (x,y)
q: Quit server

서버 시작 분석:

  1. 실행 파일 감지: run.bat이 빌드된 실행 파일을 자동으로 찾음
  2. 네트워크 바인딩: 서버가 모든 네트워크 인터페이스에 바인딩 (0.0.0.0)
    • TCP 서버: 게임 연결용 포트 33334
    • WebSocket 서버: 웹 클라이언트 지원용 포트 33335/ws
  3. 명령 인터페이스: C# 버전과 동일한 서버 명령
  4. 준비 상태: 서버가 클라이언트 연결을 받을 준비 완료

단계 4: C# 클라이언트 호환성 테스트

🔄 프로토콜 호환성 검증:

C++ 서버는 기존 C# 클라이언트와 완전히 호환됩니다. 단계 2의 동일한 C# 클라이언트를 수정 없이 이 C++ 서버에 연결할 수 있습니다.

C# 클라이언트를 C++ 서버에 연결:

# 다른 터미널에서 C# 클라이언트 실행
cd tank_server/Client/bin/Debug/net9.0
TankClient.exe

C++ 서버 콘솔 로그 (클라이언트 연결):

Client 3 connected from 127.0.0.1:52341
New tank created for client 3 with tank type -1 and health 100/100
Not enough clients to create P2P group (need at least 2)

서버 로그 분석:

  1. 동일한 클라이언트 처리: C++ 서버가 C# 서버와 정확히 동일하게 클라이언트 연결을 처리
  2. 동일한 탱크 생성: 동일한 초기 상태(체력 100/100, 타입 -1)로 탱크 객체 생성
  3. 플레이어 동기화: 클라이언트 간 플레이어 정보 교환이 동일함
  4. P2P 그룹 관리: 동일한 로직과 그룹 ID 할당으로 P2P 그룹 생성
  5. 프로토콜 호환성: 모든 RMI 함수와 메시지 형식이 원활하게 작동

✅ 완전한 기능 동등성:

🎯 이는 C++ 서버가 100% 프로토콜 호환성을 가진 C# 서버의 완전한 대체재임을 보여줍니다.

단계 5: Docker 배포 (Linux/Ubuntu)

C++ 서버는 프로덕션 환경을 위해 Ubuntu 24.04에서 Docker 컨테이너로 배포할 수 있습니다.

Docker 배포 사전 요구사항

Windows Docker 설정

Windows에서 실행하는 경우 Docker가 Linux 컨테이너용으로 구성되어 있는지 확인하세요:

  1. Docker Desktop 설치 공식 웹사이트에서
  2. Linux 컨테이너로 전환:
    • 시스템 트레이의 Docker Desktop 아이콘 우클릭
    • "Switch to Linux containers..." 선택
    • Docker가 Linux 컨테이너 모드로 재시작될 때까지 기다림

ProudNet 라이선스 구성 (선택사항)

기본적으로 서버는 라이선스 키 없이 50 CCU 제한 모드로 실행됩니다. 무제한 동시 사용자로 프로덕션 배포를 위해서는 ProudNet 라이선스를 구성할 수 있습니다:

단계 1: 라이선스 키 설정

tank_server/licensekey.txt 파일을 편집합니다:

# 기본 내용 (50 CCU 제한): 실제 ProudNet 라이선스 키로 교체:
PUT_YOUR_PROUDNET_LICENSE_KEY_HERE

단계 2: 라이선스 검증

Docker 빌드 프로세스는 자동으로 라이선스를 감지하고 적용합니다:

라이선스 포함 Docker 출력 예상:

tank-server-1  | License key found: /app/licensekey.txt
tank-server-1  | ProudNet license validation successful
tank-server-1  | Starting server with full license (unlimited CCU)

라이선스 미포함 Docker 출력 예상 (기본값):

tank-server-1  | License key file not found: /app/licensekey.txt
tank-server-1  | Building without ProudNet license.
tank-server-1  | Starting server without license (50 CCU limitation mode).

🔑 라이선스 혜택:

Docker 배포 명령

cd tank_server/Server_CPP
docker-compose up

예상 Docker 출력:

C:\Users\wayne\Documents\proud_tank\tank_server\Server_CPP [master +5 ~14 -15 !]> docker-compose up
Compose can now delegate builds to bake for better performance.
 To do so, set COMPOSE_BAKE=true.
[+] Building 2.3s (22/22)                                                                                                                                 docker:desktop-linux 
[+] Building 2.3s (22/23)                                                                                                                                 docker:desktop-linux 
[+] Building 2.3s (23/23) FINISHED                                                                                                                        docker:desktop-linux 
 => [tank-server internal] load build definition from Dockerfile                                                                                                          0.0s 
 => => transferring dockerfile: 6.39kB                                                                                                                                    0.0s 
 => [tank-server internal] load metadata for docker.io/library/ubuntu:24.04                                                                                               1.9s 
 => [tank-server auth] library/ubuntu:pull token for registry-1.docker.io                                                                                                 0.0s 
 => [tank-server internal] load .dockerignore                                                                                                                             0.0s 
 => => transferring context: 2B                                                                                                                                           0.0s 
 => [tank-server  1/16] FROM docker.io/library/ubuntu:24.04@sha256:6015f66923d7afbc53558d7ccffd325d43b4e249f41a6e93eef074c9505d2233                                       0.0s 
 => [tank-server internal] load build context                                                                                                                             0.1s
 => => transferring context: 106.41kB                                                                                                                                     0.0s
 => CACHED [tank-server  2/16] RUN apt-get update && apt-get install -y     build-essential     cmake     git     libssl-dev     libssl3     libcurl4-openssl-dev     tz  0.0s
 => CACHED [tank-server  3/16] WORKDIR /app                                                                                                                               0.0s
 => CACHED [tank-server  4/16] COPY tank_server/Server_CPP/src /app/src/                                                                                                  0.0s
 => CACHED [tank-server  5/16] COPY tank_server/Server_CPP/include /app/include/                                                                                          0.0s
 => CACHED [tank-server  6/16] COPY tank_server/Server_CPP/CMakeLists.txt /app/CMakeLists.txt                                                                             0.0s
 => CACHED [tank-server  7/16] COPY tank_server/Common/Vars.cpp /app/Common/Vars.cpp                                                                                      0.0s
 => CACHED [tank-server  8/16] COPY tank_server/Common/Vars.h /app/Common/Vars.h                                                                                          0.0s
 => CACHED [tank-server  9/16] COPY ProudNet/include /app/ProudNet/include/                                                                                               0.0s
 => CACHED [tank-server 10/16] COPY ProudNet/lib/x86_x64-linux /app/ProudNet/lib/x86_x64-linux/                                                                           0.0s
 => CACHED [tank-server 11/16] COPY ProudNet/util/PNLicenseAuth /app/ProudNet/util/                                                                                       0.0s 
 => CACHED [tank-server 12/16] RUN if [ -f "tank_server/licensekey.txt" ] &&     [ "$(cat tank_server/licensekey.txt)" != "PUT_YOUR_PROUDNET_LICENSE_KEY_HERE" ]; then    0.0s 
 => CACHED [tank-server 13/16] RUN chmod +x /app/ProudNet/util/PNLicenseAuth &&     echo "System information:" &&     uname -a &&     echo "Current directory:" &&     p  0.0s 
 => CACHED [tank-server 14/16] RUN echo "Copied file structure:" &&     ls -la /app &&     echo "Common directory:" &&     ls -la /app/Common/ || echo "Failed to copy C  0.0s 
 => CACHED [tank-server 15/16] RUN echo '#!/bin/bash \necho "Server build starting..." \n\ncheck_file() { \n  if [ ! -f "$1" ]; then \n    echo "File not found: $1" \n   0.0s
 => CACHED [tank-server 16/16] RUN chmod +x /app/start.sh                                                                                                                 0.0s
 => [tank-server] exporting to image                                                                                                                                      0.0s 
 => => exporting layers                                                                                                                                                   0.0s 
 => => writing image sha256:cf987b1363c26bf89aa7ced6c0eca898573679bc92001c3aedee2ff1fe7c649e                                                                              0.0s 
 => => naming to docker.io/library/server_cpp-tank-server                                                                                                                 0.0s 
 => [tank-server] resolving provenance for metadata file                                                                                                                  0.0s 
[+] Running 2/2
 ✔ tank-server                         Built                                                                                                                              0.0s 
 ✔ Container server_cpp-tank-server-1  Created                                                                                                                            0.0s 
Attaching to tank-server-1
tank-server-1  | Server build starting...
tank-server-1  | File found: /app/Common/Vars.cpp
tank-server-1  | File found: /app/Common/Vars.h                                                                                                                                
tank-server-1  | Directory found: /app/ProudNet/lib/x86_64-linux                                                                                                              
tank-server-1  | ProudNet license check in progress...                                                                                                                         
tank-server-1  | License file information:                                                                                                                                     
tank-server-1  | total 18560                                                                                                                                                   
tank-server-1  | drwxr-xr-x 1 root root     4096 Jun  2 15:03 .
tank-server-1  | drwxr-xr-x 1 root root     4096 Jun  2 15:03 ..                                                                                                               
tank-server-1  | -rwxr-xr-x 1 root root 18987960 May 20 23:14 PNLicenseAuth                                                                                                    
tank-server-1  | License key file not found: /app/licensekey.txt                                                                                                               
tank-server-1  | Building without ProudNet license.                                                                                                                            
tank-server-1  | ODBC driver information:                                                                                                                                      
tank-server-1  | /app/start.sh: line 72: odbcinst: command not found                                                                                                           
tank-server-1  | Could not get ODBC information.
tank-server-1  | -- OpenSSL found: /usr/include
tank-server-1  | -- OpenSSL libraries: /usr/lib/x86_64-linux-gnu/libssl.so;/usr/lib/x86_64-linux-gnu/libcrypto.so
tank-server-1  | -- OpenSSL version: 3.0.13                                                                                                                                    
tank-server-1  | -- CURL found: /usr/include/x86_64-linux-gnu                                                                                                                  
tank-server-1  | -- CURL libraries: /usr/lib/x86_64-linux-gnu/libcurl.so
tank-server-1  | -- CURL version: 8.5.0                                                                                                                                        
tank-server-1  | -- System check: Linux                                                                                                                                        
tank-server-1  | -- Current working directory: /app                                                                                                                            
tank-server-1  | -- Build type:                                                                                                                                                
tank-server-1  | -- ProudNet Path: /app/ProudNet                                                                                                                               
tank-server-1  | -- Operating System: Linux
tank-server-1  | -- Library path check: /app/ProudNet/lib/x86_64-linux                                                                                                        
tank-server-1  | -- Found Linux ProudNet library: /app/ProudNet/lib/x86_64-linux                                                                                              
tank-server-1  | -- Library file list: /app/ProudNet/lib/x86_64-linux/Debug;/app/ProudNet/lib/x86_64-linux/Release                                                           
tank-server-1  | -- Found ODBC library: /usr/lib/x86_64-linux-gnu/libodbc.so                                                                                                   
tank-server-1  | -- Found ODBCINST library: /usr/lib/x86_64-linux-gnu/libodbcinst.so
tank-server-1  | -- Linking OpenSSL libraries: /usr/lib/x86_64-linux-gnu/libssl.so;/usr/lib/x86_64-linux-gnu/libcrypto.so                                                      
tank-server-1  | -- Linking CURL library: /usr/lib/x86_64-linux-gnu/libcurl.so                                                                                                 
tank-server-1  | -- Configuring done (0.1s)                                                                                                                                    
tank-server-1  | -- Generating done (0.0s)                                                                                                                                     
tank-server-1  | -- Build files have been written to: /app/build                                                                                                               
tank-server-1  | [100%] Built target TankGameServer
tank-server-1  | Build completed, attempting to start server...
tank-server-1  | Starting server without license (50 CCU limitation mode).                                                                                                     
tank-server-1  | No NIC binding though multiple NIC detected##Process=/app/build                                                                                               
tank-server-1  | ========== Tank Server Started ==========
tank-server-1  | TCP Server listening on 0.0.0.0:33334                                                                                                                         
tank-server-1  | WebSocket Server listening on 0.0.0.0:33335/ws                                                                                                                
tank-server-1  | Ready to accept connections from all network interfaces                                                                                                       
tank-server-1  | ==========================================                                                                                                                    
tank-server-1  | Server is running. Commands:                                                                                                                                  
tank-server-1  | status: Show connected clients                                                                                                                                
tank-server-1  | health [id]: Show tank health (all or specific ID)
tank-server-1  | damage id amount: Apply damage to a tank                                                                                                                      
tank-server-1  | heal id amount: Heal a tank                                                                                                                                   
tank-server-1  | respawn id x y: Respawn a tank at position (x,y)                                                                                                              
tank-server-1  | q: Quit server

Docker 빌드 프로세스 분석:

  1. 다단계 빌드: 캐시된 빌드 레이어가 있는 Ubuntu 24.04 기본 이미지 사용
  2. 의존성 설치: build-essential, cmake, OpenSSL, CURL 개발 라이브러리 설치
  3. 파일 구조 복사: 소스 파일, ProudNet 라이브러리, 빌드 구성 복사
  4. 라이선스 감지: ProudNet 라이선스 키 확인 (50 CCU 제한 모드로 대체)
  5. 라이브러리 감지: 시스템 라이브러리 자동 검색 및 링크:
    • OpenSSL 3.0.13: SSL/TLS 지원
    • CURL 8.5.0: HTTP 클라이언트 지원
    • ODBC: 데이터베이스 연결 지원
  6. CMake 구성: Linux 전용 ProudNet 라이브러리로 빌드 구성
  7. 컴파일: TankGameServer 실행 파일 성공적으로 빌드
  8. 서버 시작: 50 CCU 제한 모드로 시작 (라이선스 키 미제공)

📋 Docker 컨테이너 세부사항:

Docker 컨테이너 관리

실행 중인 컨테이너 보기:

docker ps

예상 출력:

CONTAINER ID   IMAGE                    COMMAND                   CREATED       STATUS         PORTS                                  NAMES
dd96172cd51d   server_cpp-tank-server   "/bin/bash /app/star…"   2 hours ago   Up 7 seconds   0.0.0.0:33334-33335->33334-33335/tcp   server_cpp-tank-server-1

서버 로그 보기:

docker logs server_cpp-tank-server-1

서버 중지:

docker-compose down

단계 6: 크로스 플랫폼 클라이언트 테스트

🌐 C# 클라이언트 → C++ Docker 서버 테스트:

C# 클라이언트는 Ubuntu에서 실행되는 Docker화된 C++ 서버에 연결할 수 있습니다:

# 다른 터미널에서 C# 클라이언트 실행
cd tank_server/Client/bin/Debug/net9.0
TankClient.exe

예상 클라이언트 연결:

Connected to server. My ID: 3

예상 Docker 서버 로그:

tank-server-cpp  | Client 3 connected from 172.17.0.1:52341
tank-server-cpp  | New tank created for client 3 with tank type -1 and health 100/100

C++ 구현의 주요 이점:

🚀 성능:

🐧 크로스 플랫폼:

📦 컨테이너화:

🔄 프로토콜 호환성:

WebSocket 통합

🌐 추가 WebSocket 서버 (포트 33335):

C++ 서버 구현에는 메인 TCP 서버와 함께 실행되는 추가 WebSocket 서버가 포함되어 있습니다:

🎮 Unity WebGL 클라이언트 지원:

이 WebSocket 기능은 WebGL 애플리케이션으로 빌드될 Unity 탱크 클라이언트를 위해 특별히 설계되었습니다:

연결 예시:

ws://localhost:33335/ws  // 로컬 개발
ws://your-server.com:33335/ws  // 프로덕션 배포

이 이중 프로토콜 아키텍처는 전통적인 데스크톱 애플리케이션과 현대적인 웹 기반 게임 플랫폼 간의 원활한 통합을 가능하게 합니다.

4. 멀티플레이어 움직임 테스트

이 섹션에서는 두 클라이언트가 동시에 연결하여 탱크 이동 기능을 테스트하는 실제 시나리오를 보여줍니다.

테스트 시나리오

클라이언트 1 (ID=3) 콘솔 로그:

Connected to server. My ID: 3
move 1 1 0
Status: Tank ID=3, Position=(1,1), Type=0, Health=100/100
OnPlayerJoined: Tank 4 joined at (64.18131,34.385406) with tank type -1
P2P: Member 3 joined group 5
P2P: Member 4 joined group 5
P2P: Added member 4 to group member list
OnTankHealthUpdated: Tank 4 health: 100/100
P2P: Received group info, Group ID: 5
>>> OTHER TANK 4 MOVED TO (2,2) dir=90

클라이언트 1 로그 분석:

  1. 자체 이동 처리: move 1 1 0 명령 실행 후 자신의 탱크 상태가 업데이트됨
  2. 새 플레이어 감지: 클라이언트 4가 서버에 연결될 때 OnPlayerJoined 이벤트를 수신
  3. P2P 그룹 형성: 2개 이상의 클라이언트가 연결되면 P2P 그룹(ID: 5)이 생성됨
  4. 다른 탱크 이동 알림: 클라이언트 4의 이동을 실시간으로 수신하여 표시

클라이언트 2 (ID=4) 콘솔 로그:

Connected to server. My ID: 4
P2P: Member 4 joined group 5
P2P: Member 3 joined group 5
P2P: Added member 3 to group member list
OnPlayerJoined: Tank 3 joined at (1,1) with tank type -1
OnTankHealthUpdated: Tank 3 health: 100/100
P2P: Received group info, Group ID: 5
move 2 2 90
Status: Tank ID=4, Position=(2,2), Type=0, Health=100/100

클라이언트 2 로그 분석:

  1. 서버 연결: 서버에 성공적으로 연결되어 ID 4가 할당됨
  2. P2P 그룹 참여: 기존 클라이언트 3과 함께 P2P 그룹 5에 참여
  3. 기존 플레이어 정보 수신: 이미 연결된 클라이언트 3의 탱크 정보(위치, 체력)를 수신
  4. 자체 이동 실행: move 2 2 90 명령을 사용하여 탱크를 위치 (2,2)로 90도 방향으로 이동

서버 콘솔 로그:

New tank created for client 4 with tank type -1 and health 100/100
Sending existing player info to new client: ID=3, Type=-1, Health=100/100
Notifying existing client 3 about new player: ID=4, Type=-1, Health=100/100
P2P group created with 2 members, Group ID: 5
Sent P2P group info to client 3: P2P_GROUP_INFO:5
Sent P2P group info to client 4: P2P_GROUP_INFO:5
SendMove from client 4: pos=(2,2), direction=90

서버 로그 분석:

  1. 새 클라이언트 처리: 클라이언트 4를 위한 새 탱크 객체 생성 (초기 체력 100/100)
  2. 플레이어 정보 동기화:
    • 기존 플레이어(ID=3) 정보를 새 클라이언트(ID=4)에게 전송
    • 기존 클라이언트(ID=3)에게 새 플레이어(ID=4)에 대해 알림
  3. P2P 그룹 관리: 2개 이상의 클라이언트가 있을 때 P2P 그룹(ID: 5)을 생성하고 그룹 정보를 배포
  4. 이동 명령 처리: 클라이언트 4의 SendMove RMI 호출을 수신하고 처리

핵심 멀티플레이어 기능 검증:

🔄 실시간 동기화:

🌐 P2P 네트워킹:

📊 상태 관리:

🎮 게임 로직:

5. 발사 및 메시징 테스트

이동 외에도 클라이언트는 발사체 발사 및 P2P 메시징 기능을 테스트할 수 있습니다.

확장 테스트 명령어

클라이언트 1 (ID=3) 발사 및 메시지 명령:

fire 180 10
Fire request sent: direction=180, force=10, position=(1, 1, 1)
Status: Tank ID=3, Position=(1,1), Type=0, Health=100/100
msg hi
P2P message sent via server: hi
Status: Tank ID=3, Position=(1,1), Type=0, Health=100/100

클라이언트 1 명령 분석:

  1. 발사 명령 실행: fire 180 10으로 180도 방향과 힘 값 10으로 발사체 전송
  2. 발사 확인: 클라이언트가 발사 위치 및 매개변수 확인을 수신
  3. 메시지 명령 실행: msg hi로 모든 연결된 클라이언트에게 P2P 메시지 전송
  4. 메시지 확인: 클라이언트가 서버 릴레이를 통해 메시지가 전송되었다는 확인을 수신

클라이언트 2 (ID=4) 발사 및 메시지 이벤트 수신:

OnSpawnBullet: Tank 3 fired from (1,1) dir=180, force=10
Fire position: (1, 1, 1), shooter ID=3
P2P Message from Client ID 3 (relayed): hi

클라이언트 2 수신 분석:

  1. 총알 생성 이벤트: 발사 탱크의 위치 및 발사체 매개변수와 함께 OnSpawnBullet RMI 호출을 수신
  2. 발사 세부사항: 사수 ID, 위치, 방향, 힘에 대한 완전한 정보를 얻음
  3. P2P 메시지 수신: 서버를 통해 릴레이된 클라이언트 3의 P2P 메시지를 수신

주요 멀티플레이어 통신 기능:

🔫 발사체 시스템:

💬 P2P 메시징:

🔄 이벤트 브로드캐스팅:

문제 해결