GetSignalRConnection now serves the SignalR URL on 192.168.1.136 to
clients whose remote IP is on the LAN, and keeps the public domain for
external clients. The real-time WebSocket (libwebsockets, incl. under
Proton/Wine) couldn't reach the public domain from inside the LAN
(hairpin NAT) — it failed right after the intro as "error code 5".
External friends are unaffected (still get the domain).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Switcher presets now use the public domains (tc.nfteam.ovh:8443 /
rd-tc.nfteam.ovh:8444) so the same target works for everyone; the
unified TLS cert covers both hostnames. LAN users add a hosts entry to
avoid hairpin NAT.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New console utility (net8.0, Linux/Proton + Windows) to point a client at
a server by writing backend.txt — the single value the Prospect agent
reads. Presets for PROD/PREPROD LAN and PROD internet, plus custom URL,
certificate import (native on Windows, guided with Proton-prefix
detection on Linux) and game launch. Interactive menu + scriptable CLI
(--folder/--set). Added to the solution; not built by the server CI.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds SquadService (singleton, process-local) tracking squads by the
squadId the client shares across party members, plus a user->squad index
so TryGetCompleteSquadInfo (no squadId in request) can resolve the
caller's squad. Members are lazily registered on any squad call.
- TryGetCompleteSquadInfo: returns the caller's real squad.
- SquadMemberReadyForMatch: joins the squad, records readiness/map,
returns the squad + whether everyone is ready.
- SquadMemberSelectedMap: records the member's selected map.
- DbUserService.FindByIdAsync: resolve display name for squad members.
Groundwork for the station lobby; assumes the client drives squads via
these calls with a shared squadId (to confirm with a 2-client session).
Real-time SignalR push (unknown event names) deferred; the squad is
carried in responses + TryGetCompleteSquadInfo for now.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- RequestUsersPingRequest: the client sends ping=2147483648 (int.MaxValue+1)
for "no ping", which overflowed the int field and made every ping request
return 500. Widened to long.
- ClientsideFriendsImport: persist the imported Steam friend ids per user.
- GetFriendList: resolve those ids to the players that exist on this server
(batch lookup by Steam auth key) and return them as friends. Response
shape is best-effort pending in-game confirmation.
- DbUserService.FindManyAsync: batch-resolve auth keys to players.
First step of the station lobby (see friends on the server). Squad
formation / invite flow to follow once friends are visible.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
GetUserInventory returned every vanity in the Vanities title data as an
owned item, so the client showed all Aurum-shop cosmetics as already
owned. Return only the cosmetics the player actually owns: purchased
(VanityItems) plus currently equipped (CharacterVanity slots and the
GlobalVanity sprays / banner / emotes / drop pod), so the starter outfit
stays owned while the rest of the Aurum shop becomes purchasable.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
GetStoreItems now also serves the cosmetic stores the client queries
(AurumShop, and the DailyShop_/WeeklyShop_ rotations) from the Vanities
title data: every vanity with StoreData.Amount > 0 is offered for that
price in Aurum (AU). AurumShop lists the full priced catalogue (632
items); the daily/weekly ids show a deterministic rotating slice so they
stay stable within a period but change across periods.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
GetStoreItems was a stub returning an empty object, so every shop
(Korolev / ICA / Osiris / QuickShop vendors) showed up empty. Build the
store on the fly from the Blueprints title data: for the requested
StoreId, list every item that declares an ItemShopsCraftingData entry
for that store, converting its currency recipe ingredients into
VirtualCurrencyPrices (SoftCurrency->SC, Aurum->AU, InsuranceCurrency->IN).
Item-ingredient (crafting) entries are left to the crafting UI.
Adds the StoreId/CatalogVersion fields to the request and the
FGetStoreItemsResult / FStoreItem PlayFab response models.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- CompleteInventoryUpdate: insured items lost in a raid (present in
ItemsToRemove) are recovered back to the stash and the insurance is
consumed. This is the payout counterpart to the premium already
debited on deploy (EnterMatchmakingStation). Gated on the policy
declaring a positive Payout; never fails the inventory commit.
- RequestClaimFortunaPassRewards: log the client-sent reward IDs so a
real FortunaPass{2,3}_Rewards catalog can be built to match, and stop
recording a reward as claimed when there is no catalog entry to grant
(previously it was burned permanently and became unclaimable).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Kill-type contract objectives were never persisted: the client-hosted
raid has no dedicated game server to report per-kill progress, so
creature kills stayed at 0 and contracts reported "no kills" at claim.
- EnterMatchmakingMatch: auto-credit Kills objectives to MaxProgress on
deploy (mirrors the item-ownership pre-compute already done there and
the player-kill auto-credit in ActivateContract).
- ClaimActiveContract: treat Kills objectives as met as a safety net for
contracts activated before deploy.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- RequestPlayerContracts: renvoie les vrais contrats actifs + job boards du joueur
(peuplement initial des boards vides) au lieu d'une liste hardcodée.
- RequestFactionProgression: renvoie la réputation réelle des 3 factions (au lieu de 0).
- StartTechTreeNodeUpgradeClient: dependency check PlayerQuarterLevelRequired.
- PurchaseWeaponShopItem: critère de déblocage par contrat (UnlockData.ContractLockPurchase).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Le code sélectionne la saison via #if SEASON_2_RELEASE ; sans cette config le
build échoue (#error Unsupported build type). Build validé en local.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>