Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,4 @@ release-notes.md
result
.deriveddata/
.deriveddata-device/
.opencode
90 changes: 39 additions & 51 deletions locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"done": "Done",
"open": "Open",
"play": "Play",
"buy": "Buy",
"refresh": "Refresh",
"remove": "Remove",
"reset": "Reset",
Expand Down Expand Up @@ -52,6 +53,7 @@
"hours": "{{value}}h",
"hoursLeft": "{{value}}h left",
"hoursUsed": "{{value}}h used",
"durationLeft": "{{value}} left",
"milliseconds": "{{value}}ms",
"minutes": "{{value}} min",
"percent": "{{value}}%",
Expand Down Expand Up @@ -150,13 +152,47 @@
"noGamesFound": "No games found",
"tryAdjustingSearch": "Try adjusting your search terms or filters",
"checkBackLater": "Check back later for new additions"
},
"controller": {
"eyebrow": "CONTROLLER STORE",
"title": "Store Theater",
"hints": "D-pad browse / A launch / Space select",
"featured": "Featured",
"emptyTitle": "No Store collections found",
"emptyBody": "The cloud storefront returned empty panels. Try again after the catalog service refreshes.",
"readyToStream": "Ready to stream",
"cloudReady": "Cloud ready",
"owned": "Owned",
"notOwned": "Not owned",
"purchaseUnavailable": "Purchase unavailable",
"playNow": "Play Now",
"variant": "{{variant}}",
"storeCount": "{{count}} stores"
}
},
"library": {
"title": "My Library",
"controllerTitle": "Library",
"searchPlaceholder": "Search your library...",
"gameCount": "{{count}} game",
"gameCount_plural": "{{count}} games",
"filter": "Filter",
"allStores": "All Stores",
"storeFilter": "Store Filter",
"chooseStore": "Choose a Store",
"storeFilterHint": "Hold Y, use up/down, release Y to apply",
"moreInfo": "More Info",
"moreOptions": "More Options",
"storeNotListed": "Store not listed",
"selectedStore": "Selected Store: {{store}}",
"loadingGameDetails": "Loading game details...",
"developer": "Developer: {{developer}}",
"publisher": "Publisher: {{publisher}}",
"players": "Players: {{players}}",
"controls": "Controls: {{controls}}",
"nvidiaTech": "NVIDIA Tech: {{tech}}",
"genres": "Genres: {{genres}}",
"rating": "Rating: {{rating}}",
"lastPlayed": {
"never": "Never played",
"justNow": "Just now",
Expand Down Expand Up @@ -467,20 +503,14 @@
"showAntiAfkIndicatorHint": "Show the ANTI-AFK ON badge while Anti-AFK is enabled during streaming.",
"autoFullScreen": "Auto Full Screen",
"autoFullScreenHint": "Automatically enter fullscreen when connecting to or starting a session.",
"controllerMode": "Controller Mode",
"controllerModeHint": "Use a large-screen console-style shell with controller button hints and a horizontal library layout.",
"escapeExitsFullscreen": "Escape Exits Fullscreen",
"escapeExitsFullscreenHint": "When enabled, pressing Escape will exit fullscreen. When disabled (default), Escape is forwarded to the game while the mouse is pointer-locked.",
"discordRichPresence": "Discord Rich Presence",
"discordRichPresenceHint": "Show the game you are streaming as your Discord activity, including elapsed time.",
"controllerModeLibrary": "Controller Mode Library",
"controllerModeLibraryHint": "Replace the desktop library/settings navigation with the controller-first layout only when controller mode is enabled.",
"controllerUiSounds": "Controller UI Sounds",
"controllerUiSoundsHint": "Play subtle move, open, and back sounds inside controller mode only.",
"controllerBackgroundAnimations": "Background Animations (Controller Mode)",
"controllerBackgroundAnimationsHint": "Show animated background visuals on controller-mode loading screens only.",
"autoLoadControllerLibrary": "Auto-Load Controller Library",
"autoLoadControllerLibraryHint": "Automatically open the controller library at startup when controller mode is enabled.",
"posterSize": "Poster Size",
"posterSizeHint": "Adjusts game posters in real time across the library and controller views.",
"posterSizeHint": "Adjusts game posters in real time across the library.",
"sessionElapsedCounter": "Session Elapsed Counter",
"sessionElapsedCounterHint": "Enable or disable the live session elapsed counter while streaming.",
"sessionTimerReappear": "Session Timer Reappear",
Expand Down Expand Up @@ -613,48 +643,6 @@
"notAvailable": "N/A"
}
},
"controllerMode": {
"hints": {
"dpadNavigate": "D-pad Navigate",
"aSelect": "A Select",
"bBack": "B Back",
"lbRbTabs": "LB/RB Tabs"
},
"gameHub": {
"ariaLabel": "{{title}} game hub",
"actions": "Game hub actions"
},
"library": {
"loadingTitle": "Loading your library",
"loadingSubtitle": "Please wait",
"gameHub": "Game hub",
"games": "Games",
"gameLibrary": "Game library",
"emptySlot": "Empty slot",
"emptyRecentSlot": "Empty recent slot",
"recentlyPlayed": "Recently played",
"recentlyPlayedHint": "Recently played · Enter opens this title in your library",
"recentlyPlayedEmptyHint": "Recently played · Empty slot - play games to fill your shelf",
"recentlyPlayedGames": "Recently played games",
"resumeGame": "Resume {{title}}",
"library": "Library",
"detailRow": "Detail row",
"options": "Options",
"browseLeftRight": "Browse · Left / Right",
"backToMedia": "Back To Media",
"libraryFiltersUp": "Library filters · Up",
"bandwidthLimit": "Bandwidth Limit (Mbps)",
"theme": "Theme {{label}}"
},
"streamLoading": {
"adQueue": "Ad Queue",
"queuePaused": "Session queue paused",
"settingUpRig": "Setting up your gaming rig...",
"startingStream": "Starting stream...",
"settingUpStream": "Setting up stream...",
"loading": "Loading..."
}
},
"errors": {
"launchUnknown": "The game could not start. Please try again.",
"launchFailedTitle": "Launch Failed",
Expand Down
8 changes: 6 additions & 2 deletions opennow-stable/src/main/gfn/clientHeaders.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import crypto from "node:crypto";

export const GFN_USER_AGENT =
const GFN_WINDOWS_USER_AGENT =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 NVIDIACEFClient/HEAD/debb5919f6 GFN-PC/2.0.80.173";
const GFN_MACOS_USER_AGENT =
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 GFN-PC/2.0.80.173";

export const GFN_USER_AGENT = process.platform === "darwin" ? GFN_MACOS_USER_AGENT : GFN_WINDOWS_USER_AGENT;
export const GFN_CLIENT_VERSION = "2.0.80.173";
export const LCARS_CLIENT_ID = "ec7e38d4-03af-4b58-b131-cfb0495903ab";

Expand Down Expand Up @@ -104,7 +108,7 @@ export function buildGfnGraphQlHeaders(token?: string): Record<string, string> {
"nv-client-type": "NATIVE",
"nv-client-version": GFN_CLIENT_VERSION,
"nv-client-streamer": "NVIDIA-CLASSIC",
"nv-device-os": "WINDOWS",
"nv-device-os": platformToGfnDeviceOs(),
"nv-device-type": "DESKTOP",
"nv-device-make": "UNKNOWN",
"nv-device-model": "UNKNOWN",
Expand Down
25 changes: 25 additions & 0 deletions opennow-stable/src/main/gfn/games.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,31 @@ test("merges supplemental public launcher variants into catalog games by title",
assert.deepEqual(game?.availableStores, ["Steam", "NCSoft"]);
});

test("preserves public Steam hero fallback when merging supplemental variants", () => {
const [game] = mergePublicGameVariants(
[
{
id: "third-party-steam-game",
title: "Third Party Steam Game",
selectedVariantIndex: 0,
variants: [{ id: "third-party", store: "GOG", supportedControls: [] }],
availableStores: ["GOG"],
},
],
[
publicGameToGameInfo({
id: 456,
title: "Third Party Steam Game",
steamUrl: "https://store.steampowered.com/app/456",
store: "Steam",
status: "AVAILABLE",
}),
],
);

assert.equal(game?.heroImageUrl, "https://cdn.cloudflare.steamstatic.com/steam/apps/456/library_hero.jpg");
});

test("merges same-id public launcher variants when the store is missing from catalog data", () => {
const [game] = mergePublicGameVariants(
[
Expand Down
Loading
Loading