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.dll
ProudNetServer.dll
, ProudNetServerPlugin.dll
libcrypto-3-x64.dll
, libssl-3-x64.dll
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)
서버는 다음을 수행합니다:
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.lib
ws2_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
가 존재하고 접근 가능한지 확인