diff --git a/.github/workflows/ci-main.yml b/.github/workflows/ci-main.yml index 032019c21..1b3e334ab 100644 --- a/.github/workflows/ci-main.yml +++ b/.github/workflows/ci-main.yml @@ -364,7 +364,7 @@ jobs: body_path: ${{ needs.meta.outputs.channel == 'release' && 'release-notes.md' || '' }} generate_release_notes: ${{ needs.meta.outputs.channel != 'release' }} - - name: Strip auto-generated 'New Contributors' from nightly notes + - name: Strip 'New Contributors' + author handles from nightly notes if: needs.meta.outputs.channel == 'nightly' shell: pwsh env: @@ -379,10 +379,13 @@ jobs: # the regex below never match. Always -join "`n" first. $body = (gh release view nightly --repo "$env:GITHUB_REPOSITORY" --json body --jq '.body') -join "`n" $clean = [regex]::Replace($body, "(?s)\r?\n?## New Contributors\r?\n(?:\*.*\r?\n?)*\r?\n?(?=\*\*Full Changelog\*\*)", "`n`n") + # Drop the "by @author" credit from each "What's Changed" bullet - the notes + # should describe the change, not the committer. + $clean = [regex]::Replace($clean, ' by @[A-Za-z0-9-]+ in (https://\S+)', ' in $1') Set-Content nightly-notes.md $clean -Encoding utf8 if ($clean -notmatch "## What's Changed") { throw "nightly notes look wrong after strip - aborting rather than publishing mangled notes" } gh release edit nightly --repo "$env:GITHUB_REPOSITORY" --notes-file nightly-notes.md - Write-Host "Stripped 'New Contributors' from nightly notes" + Write-Host "Stripped 'New Contributors' + author handles from nightly notes" # 32-bit static WinXP binary, MinGW cross-compiled on Linux via MXE. Shares no # artifact with the x64 build, so it starts as soon as `meta` has the version and diff --git a/CHANGELOG.md b/CHANGELOG.md index 73c664ef7..df9b823b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,19 +10,11 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Newest first. ## [Unreleased] - Notes for the next release accumulate here; rename to `## [x.y.z]` when tagging. -### Fixed -- Co-op transfers: fixed a use-after-free when transferring a craft with crew to - a co-op base — kept crew are now unassigned before the craft is freed, so their - craft pointer is never left dangling (could crash or corrupt saves). -- Co-op transfers: the receiver now validates that the target base exists before - acknowledging a transfer/purchase, so the sender no longer removes goods (or - deducts funds) for a transfer that can never be applied (silent item loss). -- Co-op transfers: restored the peer notification dropped in the purchase-sync - rework — an immediate soldier/equipment transfer to a co-op base again arrives - at the receiving base (fixes gear not moving with a transferred soldier). - - + +## [2.0.0] - 2026-07-28 + +The first official release since v1.8.4, and the biggest update the mod has +had: a brand-new SHARED campaign mode, host-authoritative saving, an automatic +save upgrader, in-game voting, and a long list of desync, crash and item-loss +fixes. Windows x64, Windows XP (32-bit) and Linux packages now ship together +with every release. + +### Added +- **SHARED co-op campaign** — a second co-op mode where both players run one + world together: shared bases, funds, research, manufacturing and craft. + Either player can command any craft, fly interceptions and dogfights, and a + battle can mix soldiers from both players in a single squad. The campaign + type is chosen at NEW GAME (Solo / Co-op (Separate) / Co-op (Shared)). + Includes a periodic desync checksum with automatic repair, live economy + refresh, and a landing broker so simultaneous craft arrivals stay ordered. +- **Save upgrader** — saves from older versions (including legacy v1.8.4 co-op + saves) are detected on load and upgraded in-game, step by step, to the + current format; mid-battle saves are supported. Solo saves are never + touched. +- **Host-authoritative saving** — the host's save now embeds the client's + world, making it the single authority for both players' campaigns; clients + resume straight from the host's copy, so there is no more guessing which + machine has the "right" save. +- **Multiplayer voting** — in-game vote dialogs (for example, voting to abort + a battle), with matching lobby improvements. +- **Clipboard paste** — text fields accept paste (Ctrl+V) on Windows, Linux + and macOS. +- **Skirmish co-op lobby** — NEW BATTLE co-op is redesigned around a + host-driven lobby with a BATTLE SETTINGS screen and a join popup shown over + the lobby; battles in progress can be rejoined. +- **Soldier gifting and transfers** — gift soldiers to the other player + (optionally with their gear), including a reworked in-battle gifting flow, + and transfer soldiers between players with rollback if the receiver cannot + take them. +- **Server browser** — the server list can aggregate multiple rendezvous + servers. +- **Geoscape ally indicator** — your partner's craft and bases are marked on + the globe. +- **Off-turn scanner indicators** in battle while it is not your turn. +- **Crash reporting** — crash logs are actionable and minidumps are written + next to them. +- Text labels in the Add Server menu and a Hotseat tooltip in the Host menu. + +### Changed +- The neutral side in battle is reported as "Outsiders Activity" instead of + "Alien Activity". +- The main menu shows a readable version block (coop version plus the OXCE + engine version), and official releases drop the channel suffix. +- Equipment stored at the other player's bases is hidden from your own + equip screens. +- Release packaging: the Windows x64, Windows XP i686 and Linux x86_64 + packages are built, tested and published together, and every package now + includes the co-op art, a working official-server `rendezvous.json` and + `LICENSE.txt`. + +### Fixed +- Geoscape sync no longer floods the connection: position updates ride a + last-write-wins lane, packet queues are thread-safe, and the "TX queue + full" / multi-second-ping stalls are gone. +- Purchases and transfers between players: fixed a use-after-free when + transferring a craft with crew; the receiver validates the target base + before acknowledging, so goods are no longer silently lost; restored the + dropped transfer notification; a transfer can no longer be applied twice; + and a client's out-craft keeps its co-op destination across a host save. +- Battlescape item sync: battles no longer lose or duplicate items across + machines, and a proximity-grenade blast no longer sweeps every loose item + off the other player's floor. +- Mid-battle disconnects: a peer dropping mid-battle no longer freezes the + game (or dumps you into a lobby), the host is no longer trapped behind the + reconnect dialog, and "Waiting for host to resume" can no longer strand a + client forever. +- Returning to the main menu tears the co-op session down cleanly, fixing + crashes and palette corruption after leaving a battle. +- SHARED mode: mission sites and waypoints keep a consistent lifecycle on + both machines, and UFO/mission detection stays in parity. +- SEPARATE mode: duplicate mission ids are de-duplicated at the snapshot + sender. +- Chryssalid zombies no longer double-spawn in co-op battles. +- The cursor no longer misbehaves during the other player's turn. +- Craft status stays in sync between players. +- Password-protected lobbies can be joined — and left — cleanly. +- Co-op menu entry points no longer crash when no save is active. +- Fixed a crash when unloading a weapon at a base. diff --git a/src/Engine/CrossPlatform.cpp b/src/Engine/CrossPlatform.cpp index bea3b31f0..b73c36a5e 100644 --- a/src/Engine/CrossPlatform.cpp +++ b/src/Engine/CrossPlatform.cpp @@ -1795,7 +1795,7 @@ std::array parseVersion(const std::string& newVersion) */ bool isHigherThanCurrentVersion(const std::string& newVersion) { - return isHigherThanCurrentVersion(parseVersion(newVersion), { OPENXCOM_VERSION_NUMBER }); + return isHigherThanCurrentVersion(parseVersion(newVersion), { OPENXCOM_VERSION_OXCE_NUMBER }); } /** diff --git a/src/Engine/ModInfo.cpp b/src/Engine/ModInfo.cpp index cca815d3e..22779ec7d 100644 --- a/src/Engine/ModInfo.cpp +++ b/src/Engine/ModInfo.cpp @@ -180,7 +180,7 @@ struct EngineData * List of engines that current version support. */ const EngineData supportedEngines[] = { - { OPENXCOM_VERSION_ENGINE, { OPENXCOM_VERSION_NUMBER }}, + { OPENXCOM_VERSION_ENGINE, { OPENXCOM_VERSION_OXCE_NUMBER }}, { "", { 0, 0, 0, 0 } }, // assume that every engine support mods from base game, remove if its not true. }; @@ -314,11 +314,11 @@ static auto dummy = ([] return std::array{{i, j, k, l}}; }; - assert(findCompatibleEngine(supportedEngines, "Extended", create(OPENXCOM_VERSION_NUMBER))); + assert(findCompatibleEngine(supportedEngines, "Extended", create(OPENXCOM_VERSION_OXCE_NUMBER))); assert(findCompatibleEngine(supportedEngines, "Extended", create(1, 0, 0, 0))); assert(findCompatibleEngine(supportedEngines, "", create(0, 0, 0, 0))); - assert(!findCompatibleEngine(supportedEngines, "Extended", create(OPENXCOM_VERSION_NUMBER + 1))); - assert(!findCompatibleEngine(supportedEngines, "XYZ", create(OPENXCOM_VERSION_NUMBER))); + assert(!findCompatibleEngine(supportedEngines, "Extended", create(OPENXCOM_VERSION_OXCE_NUMBER + 1))); + assert(!findCompatibleEngine(supportedEngines, "XYZ", create(OPENXCOM_VERSION_OXCE_NUMBER))); assert(!findCompatibleEngine(supportedEngines, "XYZ", create(0, 0, 0, 0))); diff --git a/src/version.h b/src/version.h index 626e5e863..8865ebc9d 100644 --- a/src/version.h +++ b/src/version.h @@ -36,6 +36,16 @@ // mod's own build version, e.g. 8.4.13201) - bump it by hand on each OXCE rebase. #define OPENXCOM_VERSION_OXCE "8.4.2" +// Numeric form of OPENXCOM_VERSION_OXCE, for OXCE engine-compat checks (mod +// requiredExtendedVersion in ModInfo.cpp) and the update check +// (CrossPlatform::isHigherThanCurrentVersion). Like OPENXCOM_VERSION_OXCE it is +// NEVER stamped by CI - bump both together on each OXCE rebase. The stamped +// OPENXCOM_VERSION_NUMBER above is the coop mod's own version (e.g. 2,0,0,0) +// and must never be used for OXCE compatibility comparisons: a coop version +// numerically below the OXCE version would silently fail every mod's +// engine-version requirement. +#define OPENXCOM_VERSION_OXCE_NUMBER 8,4,2,0 + // Release channel of this build; stamped by tools/ci/stamp_version.sh. // Local/dev builds keep "dev". #ifndef OPENXCOM_VERSION_CHANNEL