auto-rejoin best server selection #636
Conversation
Replace the outdated Discord test-build link now that OpenNOW is available on Google Play.
- Add DNS interceptor (dnsInterceptor.ts) to resolve GFN hostnames via Cloudflare/Google DNS, fixing NXDOMAIN errors on non-standard networks - Add getSmartAutoJoinBaseUrl: pings all GFN datacenters in parallel via TCP, buckets by 15ms latency steps, then picks lowest queue in best bucket - Add startAutoRejoin: on session end, auto-rejoins the same game on the best available server (no user interaction needed) - Add enableFastQueueJoin setting toggle in Settings UI - Pre-fetch best server URL 15s before session expires for instant rejoin - Show 5s countdown notification before manual rejoin (window.__testAutoRejoin) - Cache active game ref so rejoin survives session teardown - Fixes TLS cert errors by using hostnames (not raw IPs) with intercepted DNS Closes OpenCloudGaming#612
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Capy auto-review is paused for this organization because the usage-cycle auto-review limit has been reached. Increase the limit or turn it off in billing settings to resume automatic reviews. |
There was a problem hiding this comment.
Pull request overview
This PR introduces an opt-in “Auto-Rejoin (test)” flow for GeForce NOW sessions, adding a new IPC API to select a “best” server (ping-first, then queue) and automatically relaunch the same game on disconnect/session end, plus a DNS lookup interceptor intended to mitigate NXDOMAIN failures on some networks.
Changes:
- Adds a new
window.openNow.getSmartAutoJoinBaseUrl()IPC path and main-process selection logic (PrintedWaste queue + parallel TCP ping ranking). - Implements renderer-side auto-rejoin behavior (prefetch near session end, rejoin on disconnect) and exposes a dev-only manual test hook.
- Introduces a global DNS lookup interceptor for NVIDIA hostnames and bumps the app version to 0.5.2.
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Updates Android distribution link to Google Play. |
| opennow-stable/src/shared/ipc.ts | Adds IPC channel for smart auto-join base URL retrieval. |
| opennow-stable/src/shared/gfn.ts | Extends shared contracts with enableFastQueueJoin and getSmartAutoJoinBaseUrl(). |
| opennow-stable/src/renderer/src/components/SettingsPage.tsx | Adds “Auto-Rejoin (test)” toggle in Settings UI. |
| opennow-stable/src/renderer/src/App.tsx | Implements prefetch + auto-rejoin orchestration and dev test helper. |
| opennow-stable/src/preload/index.ts | Exposes getSmartAutoJoinBaseUrl() via the preload bridge. |
| opennow-stable/src/main/settings.ts | Adds persisted settings flag + default for auto-rejoin. |
| opennow-stable/src/main/services/dnsInterceptor.ts | New DNS lookup interception layer for NVIDIA domains. |
| opennow-stable/src/main/index.ts | Initializes DNS interceptor and registers IPC handler. |
| opennow-stable/src/main/gfn/proxyFetch.ts | Routes non-proxy fetches through undiciFetch. |
| opennow-stable/src/main/gfn/cloudmatch.ts | Adds smart server selection logic using PrintedWaste + TCP pings. |
| opennow-stable/package.json | Bumps app version to 0.5.2. |
| opennow-stable/package-lock.json | Bumps lockfile package version to 0.5.2. |
Files not reviewed (1)
- opennow-stable/package-lock.json: Generated file
| if (typeof options === "function") { | ||
| actualCallback = options; | ||
| actualOptions = {}; | ||
| } | ||
|
|
| if (isNvidiaHostname(hostname)) { | ||
| const family = actualOptions.family; | ||
| if (family === 6) { | ||
| // Fall back to original for IPv6 lookup | ||
| originalLookup(hostname, actualOptions, actualCallback); |
| function haversineKm(lat1: number, lng1: number, lat2: number, lng2: number): number { | ||
| const R = 6371; | ||
| const dLat = (lat2 - lat1) * Math.PI / 180; | ||
| const dLng = (lng2 - lng1) * Math.PI / 180; | ||
| const a = |
| {"Auto-Rejoin (test)"} | ||
| <span className="settings-hint"> | ||
| {"Automatically picks the best server using distance and queue, and auto-rejoins when your session ends."} | ||
| </span> |
| /** Automatically select the GFN region with the shortest queue. */ | ||
| enableFastQueueJoin: boolean; |
| /** Automatically select the GFN region with the shortest queue. */ | ||
| enableFastQueueJoin?: boolean; |
| /** Automatically select a server and rejoin after a free-tier session ends. */ | ||
| enableFastQueueJoin: boolean; |
| if ( | ||
| sessionTimeRemainingSeconds !== null && | ||
| sessionTimeRemainingSeconds <= 15 && | ||
| prePingSmartUrlRef.current === null && | ||
| !prePingInFlightRef.current |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 94e39c9d03
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const QUEUE_API_URL = "https://api.printedwaste.com/gfn/queue/"; | ||
|
|
||
| try { | ||
| const queueRes = await fetchWithOptionalProxy(QUEUE_API_URL, { method: "GET" }, proxyUrl); |
There was a problem hiding this comment.
Add a timeout around smart-join queue fetch
When api.printedwaste.com stalls or accepts the connection without responding during the 15-second prefetch/post-disconnect fallback, this fetch has no AbortSignal or timeout, unlike the existing fetchPrintedWasteQueue path. The IPC promise can remain pending, leaving prePingInFlightRef stuck and preventing auto-rejoin from falling back; wrap this request and JSON parse in the same timeout pattern used by the PrintedWaste service.
Useful? React with 👍 / 👎.
| for (const [zoneId, zoneInfo] of Object.entries(queueBody.data)) { | ||
| const prefix = clusterPrefix(zoneId).toLowerCase(); | ||
| const dc = datacenters[prefix]; | ||
| if (dc) { | ||
| candidateZones.push({ |
There was a problem hiding this comment.
Filter unusable PrintedWaste zones before selecting
When the queue API includes zones that the existing flow excludes, such as nuked zones from the server mapping or non-standard/alliance entries, this loop still adds them and later treats a resolving hostname as eligible. The queue modal already requires standard non-nuked zones before routing; selecting a low-queue nuked zone here can send auto-rejoin to an unavailable CloudMatch LB and fail session creation, so fetch/use the mapping filter before adding candidates.
Useful? React with 👍 / 👎.
| IPC_CHANNELS.GET_SMART_AUTO_JOIN_BASE_URL, | ||
| async () => { | ||
| return await getSmartAutoJoinBaseUrl(); | ||
| }, |
There was a problem hiding this comment.
Pass the active session proxy into smart join
When a user has the session proxy enabled, the subsequent session create/poll calls still use activeSessionProxyUrl, but this IPC handler always calls the resolver with undefined, so queue fetching and latency selection are measured from the local network instead of the proxy egress. That can auto-rejoin proxy users to a region optimized for the wrong path; pass the enabled proxy URL through the IPC or read it from settings before calling the resolver.
Useful? React with 👍 / 👎.
Description
Implements smart auto-rejoin for GFN sessions.
How it works:
Closes #612