diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5b8830d..2dea06c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -207,6 +207,9 @@ jobs: strategy: matrix: build-type: [Release, Debug] + env: + VCPKG_ROOT: C:\vcpkg + VCPKG_DEFAULT_TRIPLET: x64-windows steps: - name: Checkout code @@ -215,30 +218,45 @@ jobs: - name: Setup MSVC uses: microsoft/setup-msbuild@v2 - - name: Setup vcpkg - uses: lukka/run-vcpkg@v11 + - name: Cache vcpkg packages + uses: actions/cache@v4 with: - vcpkgGitCommitId: '8eb57355a4ffb410a2e94c07b4dca2dffbee8e50' + path: C:\vcpkg\installed + key: vcpkg-win-x64-${{ hashFiles('vcpkg.json') }} + restore-keys: vcpkg-win-x64- - - name: Install dependencies + - name: Install vcpkg dependencies run: | - vcpkg install sdl2:x64-windows libsodium:x64-windows opus:x64-windows + & "$env:VCPKG_ROOT\vcpkg.exe" integrate install + & "$env:VCPKG_ROOT\vcpkg.exe" install --triplet x64-windows - name: Configure CMake run: | cmake -B build -S . ` -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} ` - -DCMAKE_TOOLCHAIN_FILE="${env:VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" ` + -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake" ` -DVCPKG_TARGET_TRIPLET=x64-windows - name: Build run: cmake --build build --config ${{ matrix.build-type }} + - name: Verify build + run: | + if (Test-Path "build\${{ matrix.build-type }}\rootstream-client.exe") { + Write-Host "✓ Windows client built successfully" + Get-Item "build\${{ matrix.build-type }}\rootstream-client.exe" + } else { + Write-Host "Looking for built executable..." + Get-ChildItem -Recurse build -Filter "*.exe" | ForEach-Object { $_.FullName } + } + - name: Upload Windows client uses: actions/upload-artifact@v4 with: name: rootstream-windows-${{ matrix.build-type }} - path: build/${{ matrix.build-type }}/rootstream-client.exe + path: | + build/${{ matrix.build-type }}/rootstream-client.exe + build/rootstream-client.exe if-no-files-found: warn cmake-linux-build: diff --git a/include/rootstream.h b/include/rootstream.h index 668d3f5..07862b1 100644 --- a/include/rootstream.h +++ b/include/rootstream.h @@ -7,6 +7,15 @@ /* Platform abstraction for cross-platform socket types */ #include "../src/platform/platform.h" +/* Cross-platform packed struct support */ +#ifdef _MSC_VER + #define PACKED_STRUCT __pragma(pack(push, 1)) struct + #define PACKED_STRUCT_END __pragma(pack(pop)) +#else + #define PACKED_STRUCT struct __attribute__((packed)) + #define PACKED_STRUCT_END +#endif + /* * ============================================================================ * RootStream - Secure Peer-to-Peer Game Streaming @@ -155,7 +164,7 @@ typedef struct { * ============================================================================ */ /* Packet header (always plaintext for routing) */ -typedef struct __attribute__((packed)) { +typedef PACKED_STRUCT { uint32_t magic; /* 0x524F4F54 "ROOT" */ uint8_t version; /* Protocol version (1) */ uint8_t type; /* Packet type (see below) */ @@ -164,6 +173,7 @@ typedef struct __attribute__((packed)) { uint16_t payload_size; /* Encrypted payload size */ uint8_t mac[CRYPTO_MAC_BYTES]; /* Authentication tag */ } packet_header_t; +PACKED_STRUCT_END /* Packet types */ #define PKT_HANDSHAKE 0x01 /* Initial key exchange */ @@ -186,17 +196,19 @@ typedef enum { } control_cmd_t; /* Control packet payload (encrypted) */ -typedef struct __attribute__((packed)) { +typedef PACKED_STRUCT { uint8_t cmd; /* control_cmd_t command */ uint32_t value; /* Command-specific value */ } control_packet_t; +PACKED_STRUCT_END /* Encrypted input event payload */ -typedef struct __attribute__((packed)) { +typedef PACKED_STRUCT { uint8_t type; /* EV_KEY, EV_REL, etc */ uint16_t code; /* Key/button code */ int32_t value; /* Value/delta */ } input_event_pkt_t; +PACKED_STRUCT_END /* ============================================================================ * PEER MANAGEMENT - Connected peer tracking