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 유틸리티들
doc/ - 문서 파일들include/ - C++ 개발을 위한 헤더 파일들lib/ - .NET과 C++ 모두를 위한 라이브러리 파일들Sample/ - 예제 프로젝트들util/ - 유틸리티 도구들과 라이선스 인증서버와 클라이언트 구현 모두에서 사용되는 공유 리소스들을 포함합니다.
내용:
주요 파일들:
Tank.PIDL - 탱크 게임 프로토콜 정의CompilePIDL_cs.bat - PIDL 컴파일 스크립트 (C#)CompilePIDL_cpp.bat - PIDL 컴파일 스크립트 (C++)Vars.cs - C# 설정Vars.h - C++ 설정탱크 게임 서버의 C# 구현입니다.
기능:
주요 파일들:
TankServer.cs - 메인 서버 구현TankServer.csproj - .NET 프로젝트 파일build.bat - DLL 복사 포함 빌드 스크립트탱크 게임을 위한 C# 콘솔 기반 클라이언트입니다.
기능:
주요 파일들:
TankClient.cs - 메인 클라이언트 구현TankClient.csproj - .NET 프로젝트 파일build.bat - DLL 복사 포함 빌드 스크립트Linux 지원과 함께 제공되는 탱크 게임 서버의 C++ 구현입니다.
기능:
주요 파일들:
src/TankServer.cpp - 메인 C++ 서버 구현CMakeLists.txt - CMake 설정Dockerfile - Docker 컨테이너 설정docker-compose.yml - Docker Compose 설정run.bat - Windows 실행 스크립트빌드 옵션들:
tank_server/와 같은 레벨에 ProudNet/ 디렉터리를 생성합니다ProudNet/util/PIDL.exe가 존재하는지 확인합니다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 파일은 다음을 정의합니다:
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 . . .
이 스크립트는 다음을 수행합니다:
ProudNet/util/PIDL.exe -cs Tank.PIDL -outdir ../Server 실행ProudNet/util/PIDL.exe -cs Tank.PIDL -outdir ../Client 실행Tank_stub.cs - 들어오는 RMI 호출을 처리Tank_proxy.cs - 나가는 RMI 호출을 전송Tank_common.cs - 공통 정의 및 상수들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 . . .
빌드 스크립트는 다음을 수행합니다:
dotnet build --configuration Debug를 사용하여 C# 프로젝트를 컴파일ProudDotNetServer.dll, ProudDotNetClient.dllProudNetServer.dll, ProudNetServerPlugin.dlllibcrypto-3-x64.dll, libssl-3-x64.dllcd 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)
서버는 다음을 수행합니다:
status, health, damage, heal, respawn, q (종료)클라이언트는 서버와 동일한 Tank.PIDL 파일을 사용하여 완벽한 프로토콜 호환성을 보장합니다:
CompilePIDL_cs.bat 스크립트가 두 프로젝트 모두에 동일한 네트워킹 코드 생성이 접근 방식은 다음을 보장합니다:
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 . . .
클라이언트 빌드 스크립트는 서버와 동일한 작업을 수행합니다:
dotnet build --configuration Debug를 사용하여 C# 프로젝트 컴파일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)
📝 서버 로그 설명:
Client 3 connected - 새 클라이언트가 성공적으로 연결되어 ID 3이 할당됨New tank created for client 3 with tank type -1 and health 100/100 - 서버가 새 클라이언트를 위한 탱크 객체를 생성:
-1은 아직 탱크 타입이 선택되지 않았음을 의미Not enough clients to create P2P group (need at least 2) - P2P 그룹 생성에는 피어투피어 통신을 위해 최소 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
📝 다중 클라이언트 연결 분석:
두 번째 클라이언트가 연결될 때:
클라이언트 측 P2P 이벤트:
P2P: Member X joined group Y - P2P 그룹 멤버십 알림OnPlayerJoined: Tank 3 joined at (x,y) - 기존 플레이어에 대한 정보 수신OnTankHealthUpdated: Tank 3 health: 100/100 - 다른 탱크의 체력 상태 수신P2P: Received group info, Group ID: 5 - P2P 그룹 설정 확인🎮 이제 멀티플레이어 기능을 테스트할 수 있습니다:
msg hello를 한 클라이언트에서 사용하여 다른 클라이언트들에게 P2P 메시지 전송move x y dir를 사용하여 클라이언트 간 위치 업데이트 확인fire dir를 사용하여 발사체 동기화 테스트C++ 서버 구현은 C# 서버와 정확히 동일한 기능을 제공하며, 크로스 플랫폼 지원과 컨테이너 배포 옵션을 제공합니다. 이는 ProudNet의 다중 언어 기능을 보여주는 선택적 고급 구현입니다.
C#과 C++ 서버 모두 동일한 Tank.PIDL 파일을 사용하므로 완전히 호환됩니다:
먼저 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 클래스를 생성합니다:
Tank_stub.cpp/.h - 들어오는 RMI 호출 처리Tank_proxy.cpp/.h - 나가는 RMI 호출 전송Tank_common.cpp/.h - 공통 정의 및 상수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 . . .
빌드 프로세스 분석:
TankServer.cpp와 Vars.cpp 빌드빌드 스크립트는 다음을 수행합니다:
ProudNetServer.lib, ProudNetClient.libws2_32 (Windows Sockets), winmm (Multimedia), iphlpapi (IP Helper)atls (Active Template Library)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
서버 시작 분석:
run.bat이 빌드된 실행 파일을 자동으로 찾음🔄 프로토콜 호환성 검증:
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)
서버 로그 분석:
✅ 완전한 기능 동등성:
status, health, damage, heal, respawn)이 동일하게 작동🎯 이는 C++ 서버가 100% 프로토콜 호환성을 가진 C# 서버의 완전한 대체재임을 보여줍니다.
C++ 서버는 프로덕션 환경을 위해 Ubuntu 24.04에서 Docker 컨테이너로 배포할 수 있습니다.
Windows에서 실행하는 경우 Docker가 Linux 컨테이너용으로 구성되어 있는지 확인하세요:
기본적으로 서버는 라이선스 키 없이 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).
🔑 라이선스 혜택:
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 빌드 프로세스 분석:
📋 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
🌐 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
🚀 성능:
🐧 크로스 플랫폼:
📦 컨테이너화:
🔄 프로토콜 호환성:
🌐 추가 WebSocket 서버 (포트 33335):
C++ 서버 구현에는 메인 TCP 서버와 함께 실행되는 추가 WebSocket 서버가 포함되어 있습니다:
🎮 Unity WebGL 클라이언트 지원:
이 WebSocket 기능은 WebGL 애플리케이션으로 빌드될 Unity 탱크 클라이언트를 위해 특별히 설계되었습니다:
연결 예시:
ws://localhost:33335/ws // 로컬 개발 ws://your-server.com:33335/ws // 프로덕션 배포
이 이중 프로토콜 아키텍처는 전통적인 데스크톱 애플리케이션과 현대적인 웹 기반 게임 플랫폼 간의 원활한 통합을 가능하게 합니다.
이 섹션에서는 두 클라이언트가 동시에 연결하여 탱크 이동 기능을 테스트하는 실제 시나리오를 보여줍니다.
move 1 1 0 명령으로 위치 (1,1)로 이동, 방향 0도move 2 2 90 명령으로 위치 (2,2)로 이동, 방향 90도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 로그 분석:
move 1 1 0 명령 실행 후 자신의 탱크 상태가 업데이트됨OnPlayerJoined 이벤트를 수신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 로그 분석:
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
서버 로그 분석:
SendMove RMI 호출을 수신하고 처리🔄 실시간 동기화:
🌐 P2P 네트워킹:
📊 상태 관리:
🎮 게임 로직:
이동 외에도 클라이언트는 발사체 발사 및 P2P 메시징 기능을 테스트할 수 있습니다.
fire 180 10 - 180도 방향으로 힘 10으로 발사체 발사msg hi - 다른 연결된 클라이언트에게 P2P 메시지 "hi" 전송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 명령 분석:
fire 180 10으로 180도 방향과 힘 값 10으로 발사체 전송msg hi로 모든 연결된 클라이언트에게 P2P 메시지 전송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 수신 분석:
OnSpawnBullet RMI 호출을 수신🔫 발사체 시스템:
💬 P2P 메시징:
🔄 이벤트 브로드캐스팅:
ProudNet/util/PIDL.exe가 존재하고 접근 가능한지 확인