From a1c428493d67a96967c644cbd40d41a978cd73ff Mon Sep 17 00:00:00 2001 From: DionJones615 <27814889+DionJones615@users.noreply.github.com> Date: Sat, 10 Oct 2026 10:22:02 -0400 Subject: [PATCH 1/9] Load the save off the game machine over SSH, not HTTP The desktop shell can browse and load the .sav from the machine that runs the game using what that machine already has -- its OpenSSH server -- with a mounted SMB/NFS share as the second transport. Nothing listens on the game machine and no port is opened for it: `ssh`, `sftp` and `rsync` are run as subprocesses, so host keys, keys, ssh-agent, `~/.ssh/config` and ProxyJump stay OpenSSH's business and the app ships no SSH stack to keep current. (Upstream had an SFTP sync panel in the Flask era, with the password in a config file; it went with the Python runtime. This brings the capability back client-side, key/agent only.) One dialog, Save File -> From another machine: - Validate connection answers what the transport can do before a path is typed: SSH login, whether the SFTP subsystem answers (browsing and change detection depend on it), whether the far side has rsync, the platform and home, and how many .sav files are in the folder. A partial answer stays partial -- no SFTP subsystem is reported as such, not as a failed login. - Save folder lists the remote directory and walks it (folders first, .sav marked, Up/parent, keyboard reachable). Remote names are untrusted data and are rendered as text. Without SFTP the listing is disabled and the path is typed by hand. - Watch it and reload polls name/size/timestamp -- one listing, not a download -- and reloads only when the fetched bytes hash differently, so a coarse timestamp can cost a transfer but never a wrong reload. Paused while the editor holds pending edits, while a parse runs, and while the window is hidden; it resumes on its own. Rust: rust_parser/tauri/src/ssh_source.rs (listing parse, ssh config, the three transports, hashing) plus five commands -- ssh_hosts, source_validate, source_browse, source_stat, source_fetch. Every remote path crosses into an SFTP batch script, so control characters and quotes are rejected at the boundary, and a host/user/port that could be read as an option is rejected too. A fetched save lands in the app data dir under remote-saves/, written to a .part and renamed only when complete, capped at 8 GiB. Checks: 9 unit tests over real `sftp -b -` output (including OpenSSH-for-Windows rows with ? owner/group and full-path names), a live run against a local sshd covering validate/browse/stat/fetch over sftp and rsync, names with spaces, change detection and every refusal path, the module plus the command bodies type-checked against real serde/sha2, and the dialog driven in a browser with a stubbed bridge (both transports, watch ticks, capability gating, pending-edit pause, no markup injection). --- docs/remote-save-ssh-dialog.png | Bin 0 -> 155692 bytes docs/remote-save-ssh.md | 85 +++ map/static/map/data.js | 10 + map/static/map/index.html | 91 +++ map/static/map/map.css | 169 ++++++ map/static/map/save_source.js | 724 ++++++++++++++++++++++ rust_parser/tauri/src/lib.rs | 1 + rust_parser/tauri/src/main.rs | 67 ++ rust_parser/tauri/src/ssh_source.rs | 910 ++++++++++++++++++++++++++++ 9 files changed, 2057 insertions(+) create mode 100644 docs/remote-save-ssh-dialog.png create mode 100644 docs/remote-save-ssh.md create mode 100644 map/static/map/save_source.js create mode 100644 rust_parser/tauri/src/ssh_source.rs diff --git a/docs/remote-save-ssh-dialog.png b/docs/remote-save-ssh-dialog.png new file mode 100644 index 0000000000000000000000000000000000000000..52dcf1d3ceb32a8452fc0d91f64fb0eeb4201947 GIT binary patch literal 155692 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

=Lm^gw^9|(yIZ%GolBJi9&%5Pnxzh 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

+
+
+ Save on another machine + +
+
Pull the save off the gaming PC with the tools it already has — its own SSH server, or a share the OS has mounted. Nothing is hosted, nothing is uploaded; keys and ~/.ssh/config are used as they are.
+
+
How to reach it
+
+ + +
+ +
+
+ + + +
+ + + +
+
+ + + +
Save folder
+
+ + + +
+
+
+ +
Keep it fresh
+ + +
+ + +
+

+
+
+ + +
+
+
+ @@ -656,6 +746,7 @@ + diff --git a/map/static/map/map.css b/map/static/map/map.css index 87e6e30..e780e75 100644 --- a/map/static/map/map.css +++ b/map/static/map/map.css @@ -3074,3 +3074,172 @@ button:focus-visible, select:focus-visible, input[type="checkbox"]:focus-visible .leaflet-left { left: var(--dock-left-inset); } + +/* ===== Save on another machine (save_source.js) ========================== + The SSH/SFTP source dialog. Chrome comes from ui.css (.dlg, .btn, .field, + .list, .row); only the pieces this dialog adds live here: the transport + tabs, the two-column host fields, the validation checklist, and the folder + list's fixed height so the dialog itself never scrolls. */ + +.dlg-lg .dlg-inner { + width: 760px; +} + +.srcTabs { + display: flex; + gap: var(--sp-1); + margin-bottom: var(--sp-2); +} + +.srcTabs .btn.is-on { + background: var(--select-bg); + border-color: var(--accent-soft); + color: var(--text-bright); +} + +/* Host / user / port on one line: three short fields, one question. */ +.srcGrid { + display: grid; + grid-template-columns: 2fr 1fr 1fr; + gap: var(--sp-2); + margin-bottom: var(--sp-2); +} + +#srcSshFields > .field, +#srcLocalFields > .field, +.srcGrid > .field { + margin-bottom: var(--sp-2); + width: 100%; +} + +.srcCheckLine { + display: flex; + align-items: center; + gap: var(--sp-2); + padding: var(--sp-1) 0; + font-size: var(--fs-sm); + color: var(--muted); + cursor: pointer; +} + +.srcHint { + margin: var(--sp-1) 0 var(--sp-2); + font-size: var(--fs-sm); + color: var(--faint); +} + +/* One line per capability the connection has (or lacks): a tick, what it is, + and the detail -- so "SSH works but there is no SFTP subsystem" reads as a + partial answer instead of a bare failure. */ +.srcChecks { + margin-top: var(--sp-2); +} + +.srcCheck { + display: flex; + align-items: baseline; + gap: var(--sp-2); + padding: var(--sp-1) 0; + font-size: var(--fs-sm); + border-top: 1px solid var(--border-sub); +} + +.srcCheckMark { + flex: none; + width: 12px; + color: var(--ok-soft); +} + +.srcCheck.is-bad .srcCheckMark { + color: var(--danger-soft); +} + +.srcCheck.is-off .srcCheckMark { + color: var(--faint); +} + +.srcCheckName { + flex: none; + min-width: 150px; + color: var(--text); +} + +.srcCheckDetail { + min-width: 0; + color: var(--faint); + overflow-wrap: anywhere; +} + +.srcPathBar { + display: flex; + gap: var(--sp-2); + margin-bottom: var(--sp-2); +} + +.srcPathBar .field { + flex: 1 1 auto; + min-width: 0; +} + +/* Fixed height, so browsing between folders does not resize the dialog. */ +.srcList { + height: 210px; +} + +.srcRow { + width: 100%; + text-align: left; + background: none; + border: none; + border-bottom: 1px solid var(--border-sub); + font: inherit; +} + +.srcRowIcon { + flex: none; + width: 14px; + color: var(--faint); +} + +.srcRow.is-dir .srcRowIcon { + color: var(--accent-soft); +} + +.srcRow.is-sav .srcRowIcon { + color: var(--ok-soft); +} + +.srcRow:focus-visible { + outline: 2px solid var(--accent-soft); + outline-offset: -2px; +} + +.srcEmpty { + padding: var(--sp-3); + color: var(--faint); + font-size: var(--fs-sm); + overflow-wrap: anywhere; +} + +.srcWatchRow { + display: flex; + align-items: center; + gap: var(--sp-2); + font-size: var(--fs-sm); + color: var(--muted); +} + +.srcWatchRow select { + width: auto; +} + +/* The status line rides in the foot, so "fetching…" is next to the button + that started it. */ +.dlg-foot #srcStatus { + flex: 1 1 auto; + min-width: 0; + color: var(--faint); + font-size: var(--fs-sm); + align-self: center; + overflow-wrap: anywhere; +} diff --git a/map/static/map/save_source.js b/map/static/map/save_source.js new file mode 100644 index 0000000..ff22a2c --- /dev/null +++ b/map/static/map/save_source.js @@ -0,0 +1,724 @@ +// SaveSource: load a save that lives on the machine running the game, without +// asking that machine to host anything. The transports are the ones the gaming +// PC already speaks -- its OpenSSH server (ssh/sftp, plus rsync when it has it) +// and any share the OS has mounted -- and both are reached through the Tauri +// commands in rust_parser/tauri/src/ssh_source.rs. +// +// Three jobs, one dialog: +// - validate: say what the connection can actually do (keys, SFTP subsystem, +// rsync) before the user commits to a path; +// - browse: list the remote folder and pick the .sav, the way the local file +// dialog works; +// - watch: notice when the save changes and reload the map, so a game +// autosaving on another machine keeps this map current. The change check is +// a listing (name/size/timestamp), and the downloaded bytes are hashed +// before reloading, so a coarse timestamp can cost a transfer but never a +// wrong reload. +// +// Desktop only: every command here is Tauri. The browser build never calls +// init(), and nothing in this file runs without window.__TAURI__. + +window.SaveSource = (function() { + "use strict"; + + var KEY = "smap.saveSource"; + // The game's own save location, per platform -- prefilled after a successful + // validate purely as a convenience; browsing corrects it in one click. + var SAVE_DIR = { + windows: "AppData/Local/FactoryGame/Saved/SaveGames", + linux: ".steam/steam/steamapps/compatdata/526870/pfx/drive_c/users/steamuser/AppData/Local/FactoryGame/Saved/SaveGames", + }; + + var tauriInvoke = null; // window.__TAURI__.core.invoke, set by init + var options = {}; + var timer = null; + var el = {}; // cached elements + + var state = { + transport: "ssh", // "ssh" | "local" + target: { host: "", user: "", port: 0, identity: "", acceptNewHostKey: false }, + dir: "", + file: "", + takeNewest: true, + watch: false, + interval: 60, + capabilities: null, // last validate result + seen: null, // "name|size|mtime" of the save we last loaded from + sha: null, // hash of the bytes we last loaded (null = not loaded yet) + loadedPath: "", + }; + + // ---- Small helpers ------------------------------------------------------- + + function remember() { + try { + window.localStorage.setItem(KEY, JSON.stringify({ + transport: state.transport, + target: state.target, + dir: state.dir, + file: state.file, + takeNewest: state.takeNewest, + watch: state.watch, + interval: state.interval, + })); + } catch (e) { /* storage blocked: the dialog still works, it just forgets */ } + } + + function recall() { + try { + var saved = JSON.parse(window.localStorage.getItem(KEY) || "null"); + if (!saved || typeof saved !== "object") { + return; + } + state.transport = saved.transport === "local" ? "local" : "ssh"; + state.target = Object.assign(state.target, saved.target || {}); + state.dir = saved.dir || ""; + state.file = saved.file || ""; + state.takeNewest = saved.takeNewest !== false; + state.watch = !!saved.watch; + state.interval = parseInt(saved.interval, 10) || 60; + } catch (e) { /* corrupt or unreadable: start from defaults */ } + } + + function say(text) { + if (el.status) { + el.status.textContent = text; + } + } + + function bytes(n) { + if (!(n > 0)) { + return ""; + } + var units = ["B", "KB", "MB", "GB"]; + var at = 0; + while (n >= 1024 && at < units.length - 1) { + n /= 1024; + at++; + } + return (at === 0 ? n : n.toFixed(1)) + " " + units[at]; + } + + function clock() { + return new Date().toTimeString().slice(0, 8); + } + + function when(seconds) { + if (!seconds) { + return ""; + } + var days = Math.round((Date.now() / 1000 - seconds) / 86400); + if (days === 0) { + return "today"; + } + return days === 1 ? "yesterday" : days + " days ago"; + } + + function isSave(name) { + return /\.sav$/i.test(name); + } + + function invoke(command, args) { + return tauriInvoke(command, args || {}); + } + + function message(error) { + return String((error && error.message) || error); + } + + // ---- The dialog ---------------------------------------------------------- + + function init(bridge) { + options = (bridge && bridge.options) || {}; + tauriInvoke = (bridge && bridge.invoke) || (window.__TAURI__ && window.__TAURI__.core.invoke); + if (!tauriInvoke) { + return; + } + el = { + trigger: document.getElementById("saveSourceBtn"), + dialogApi: UI.dialog("saveSourceModal"), + host: document.getElementById("srcHost"), + user: document.getElementById("srcUser"), + port: document.getElementById("srcPort"), + identity: document.getElementById("srcIdentity"), + acceptNew: document.getElementById("srcAcceptNew"), + sshFields: document.getElementById("srcSshFields"), + localFields: document.getElementById("srcLocalFields"), + localPath: document.getElementById("srcLocalPath"), + validate: document.getElementById("srcValidate"), + checks: document.getElementById("srcChecks"), + path: document.getElementById("srcPath"), + up: document.getElementById("srcUp"), + go: document.getElementById("srcGo"), + list: document.getElementById("srcList"), + picked: document.getElementById("srcPicked"), + newest: document.getElementById("srcNewestBox"), + watch: document.getElementById("srcWatchBox"), + watchNote: document.getElementById("srcWatchNote"), + interval: document.getElementById("srcInterval"), + load: document.getElementById("srcLoad"), + status: document.getElementById("srcStatus"), + }; + if (!el.dialogApi || !el.list || !el.sshFields || !el.localFields) { + return; // markup missing (older dist): stay inert rather than throw + } + if (el.dialogApi.el.dataset.saveSourceWired) { + return; // a second init would double every click handler and every fetch + } + recall(); + fillForm(); + wire(); + syncWatchNote(); + el.dialogApi.el.dataset.saveSourceWired = "1"; + if (el.trigger) { + el.trigger.style.display = ""; + el.trigger.addEventListener("click", open); + } + // The source is remembered, so the checkbox survives a restart -- but the + // poll only starts once a save has been loaded from it in this session + // (see arm()), or it would download and load a save nobody asked for. + if (state.watch) { + say("Watching " + (state.file || state.dir) + " every " + state.interval + "s once a save is loaded."); + } + } + + function open() { + fillForm(); + renderCapabilities(state.capabilities); + el.dialogApi.open(); + if (state.dir) { + browse(state.dir); + } else if (el.path && !el.path.value) { + el.path.focus(); + } + } + + function fillForm() { + var t = state.target; + if (el.host) { + el.host.value = t.host || ""; + el.user.value = t.user || ""; + el.port.value = t.port || ""; + el.identity.value = t.identity || ""; + el.acceptNew.checked = !!t.acceptNewHostKey; + } + if (el.localPath) { + el.localPath.value = state.dir || ""; + } + if (el.path) { + el.path.value = state.dir || ""; + } + if (el.newest) { + el.newest.checked = state.takeNewest; + } + if (el.watch) { + el.watch.checked = state.watch; + } + if (el.interval) { + el.interval.value = String(state.interval); + } + syncTransport(); + renderPicked(); + } + + function readForm() { + state.target = { + host: el.host.value.trim(), + user: el.user.value.trim(), + port: parseInt(el.port.value, 10) || 0, + identity: el.identity.value.trim(), + acceptNewHostKey: el.acceptNew.checked, + }; + state.takeNewest = el.newest.checked; + state.watch = el.watch.checked; + state.interval = parseInt(el.interval.value, 10) || 60; + remember(); + } + + function syncTransport() { + var local = state.transport === "local"; + el.sshFields.style.display = local ? "none" : ""; + el.localFields.style.display = local ? "" : "none"; + document.querySelectorAll("#srcTransportTabs button").forEach(function(button) { + var on = button.dataset.transport === state.transport; + button.classList.toggle("is-on", on); + button.setAttribute("aria-pressed", String(on)); + }); + } + + // Whether watching is even possible: SFTP is what gives us a cheap listing + // to compare, so a server without the subsystem gets a manual path and a + // manual reload instead of a checkbox that can never fire. Before the first + // validate we do not know, and a remembered source that worked yesterday is + // allowed to try again. + function watchPossible() { + return state.transport === "local" || !state.capabilities || !!state.capabilities.sftp; + } + + function syncWatchNote() { + if (!el.watchNote) { + return; + } + if (watchPossible()) { + el.watch.checked = state.watch; + el.watch.disabled = false; + el.watchNote.textContent = ""; + return; + } + el.watch.checked = false; + el.watch.disabled = true; + el.watchNote.textContent = "This server has no SFTP subsystem, so the folder cannot be listed or watched. Type the save's path and load it by hand."; + } + + function wire() { + document.querySelectorAll("#srcTransportTabs button").forEach(function(button) { + button.addEventListener("click", function() { + state.transport = button.dataset.transport; + state.capabilities = null; + state.dir = state.transport === "local" + ? (el.localPath.value.trim() || state.dir) + : state.dir; + el.path.value = state.dir; + renderCapabilities(null); + syncTransport(); + syncWatchNote(); + remember(); + }); + }); + el.validate.addEventListener("click", validate); + el.go.addEventListener("click", function() { browse(el.path.value.trim()); }); + el.path.addEventListener("keydown", function(e) { + if (e.key === "Enter") { + e.preventDefault(); + browse(el.path.value.trim()); + } + }); + el.up.addEventListener("click", function() { + if (state.parent) { + browse(state.parent); + } + }); + ["host", "user", "port", "identity"].forEach(function(name) { + el[name].addEventListener("change", readForm); + }); + el.acceptNew.addEventListener("change", readForm); + el.newest.addEventListener("change", function() { + readForm(); + renderPicked(); + }); + el.watch.addEventListener("change", function() { + readForm(); + schedule(); + say(state.watch ? "Watching -- every " + state.interval + "s once a save is loaded." + : "Watching off."); + }); + el.interval.addEventListener("change", function() { + readForm(); + schedule(); + }); + el.load.addEventListener("click", function() { load(true); }); + el.dialogApi.onClose(function() { + if (!state.watch) { + stop(); + } + }); + } + + // ---- Validate ------------------------------------------------------------ + + function validate() { + readForm(); + if (state.transport === "ssh" && !state.target.host) { + say("Enter the host name or IP of the machine running the game."); + el.host.focus(); + return; + } + el.validate.disabled = true; + renderCapabilities(null); + say("Validating " + (state.transport === "local" ? state.dir : state.target.host) + "…"); + invoke("source_validate", { + target: state.target, + dir: state.transport === "ssh" ? el.path.value.trim() : "", + }).then(function(result) { + el.validate.disabled = false; + state.capabilities = result; + renderCapabilities(result); + syncWatchNote(); + if (!result.ok) { + say(result.detail || "That connection did not work."); + return; + } + say(result.detail); + // Land the browser somewhere useful: the folder the caller gave, else the + // game's usual save location under this user's home. + if (!el.path.value.trim() && state.transport === "ssh") { + el.path.value = suggestDir(result); + browse(el.path.value); + } + }).catch(function(error) { + el.validate.disabled = false; + say("Validation failed: " + message(error)); + }); + } + + function suggestDir(result) { + var home = (result.home || "").replace(/[\\/]+$/, ""); + var user = state.target.user || ""; + if (result.platform === "Windows") { + return home + "/" + SAVE_DIR.windows; + } + if (home) { + return home + "/" + SAVE_DIR.linux; + } + return ""; + } + + function renderCapabilities(result) { + el.checks.innerHTML = ""; + if (!result) { + return; + } + // Three states, because "no rsync on the remote" is not a failure: the + // connection is fine and SFTP carries the transfer. Red is reserved for the + // one thing browsing and watching actually depend on. + var rows = [ + [result.ok ? "ok" : "bad", "SSH login", result.detail || "no answer"], + [result.sftp ? "ok" : "bad", "SFTP subsystem", result.sftp + ? "browsing and change detection available (" + (result.platform || "unknown") + + (result.home ? ", " + result.home : "") + ")" + : "not available -- type the save's path by hand"], + [result.rsync ? "ok" : "off", "rsync on the remote", result.rsync + ? "available (delta transfers, less to re-fetch)" + : "not installed there -- SFTP is used instead"], + ]; + if (result.saveCount || result.newestSave) { + rows.push(["ok", "Saves in that folder", + result.saveCount + " .sav file" + (result.saveCount === 1 ? "" : "s") + + (result.newestSave ? ", newest " + result.newestSave : "")]); + } + rows.forEach(function(row) { + var line = document.createElement("div"); + line.className = "srcCheck is-" + row[0]; + var mark = document.createElement("span"); + mark.className = "srcCheckMark"; + mark.textContent = row[0] === "ok" ? "✓" : (row[0] === "bad" ? "✕" : "·"); + var name = document.createElement("span"); + name.className = "srcCheckName"; + name.textContent = row[1]; + var detail = document.createElement("span"); + detail.className = "srcCheckDetail"; + detail.textContent = row[2] || ""; + line.appendChild(mark); + line.appendChild(name); + line.appendChild(detail); + el.checks.appendChild(line); + }); + } + + // ---- Browse -------------------------------------------------------------- + + function browse(path, quiet) { + if (!path) { + say("Enter a folder to open."); + return Promise.resolve(); + } + if (state.transport === "ssh" && !state.target.host) { + say("Set the host first (and press Validate)."); + return Promise.resolve(); + } + state.dir = path; + el.path.value = path; + if (state.transport === "local") { + el.localPath.value = path; + } + if (!quiet) { + el.list.innerHTML = ""; + var loading = document.createElement("div"); + loading.className = "srcEmpty"; + loading.textContent = "Listing " + path + "…"; + el.list.appendChild(loading); + say("Listing " + path + "…"); + } + return invoke("source_browse", { + target: state.target, + path: path, + local: state.transport === "local", + }).then(function(listing) { + renderListing(listing, quiet); + remember(); + }).catch(function(error) { + if (!quiet) { + el.list.innerHTML = ""; + var failed = document.createElement("div"); + failed.className = "srcEmpty"; + failed.textContent = message(error); + el.list.appendChild(failed); + } + throw error; + }); + } + + function renderListing(listing, quiet) { + state.parent = listing.parent; + state.entries = listing.entries || []; + el.list.innerHTML = ""; + if (state.entries.length === 0) { + var empty = document.createElement("div"); + empty.className = "srcEmpty"; + empty.textContent = "Nothing in " + listing.path + "."; + el.list.appendChild(empty); + } + state.entries.forEach(function(entry) { + // A button, so the whole list is reachable by keyboard and Enter works + // the way a file dialog's does. + var row = document.createElement("button"); + row.type = "button"; + row.className = "row row-clickable srcRow" + (entry.isDir ? " is-dir" : "") + + (isSave(entry.name) ? " is-sav" : ""); + var icon = document.createElement("span"); + icon.className = "srcRowIcon"; + icon.textContent = entry.isDir ? "▸" : (isSave(entry.name) ? "●" : "·"); + var label = document.createElement("span"); + label.className = "row-label"; + // Remote names are untrusted data: textContent, never innerHTML. + label.textContent = entry.name; + var meta = document.createElement("span"); + meta.className = "row-meta"; + meta.textContent = entry.isDir ? "folder" : bytes(entry.size) + " · " + when(entry.mtime); + row.appendChild(icon); + row.appendChild(label); + row.appendChild(meta); + if (state.file === entry.name && !entry.isDir) { + row.classList.add("row-active"); + } + row.addEventListener("click", function() { + if (entry.isDir) { + browse(entry.path); + return; + } + if (!isSave(entry.name)) { + say(entry.name + " is not a .sav file."); + return; + } + state.file = entry.name; + state.filePath = entry.path; + // Picking one file means watching that file, not the newest in the + // folder -- otherwise the pick would be overwritten by the next tick. + el.newest.checked = false; + readForm(); + remember(); + renderListing(listing); + renderPicked(); + }); + row.addEventListener("keydown", function(e) { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + row.click(); + } + }); + el.list.appendChild(row); + }); + if (!quiet) { + var count = state.entries.filter(function(entry) { + return !entry.isDir && isSave(entry.name); + }).length; + say(count + " .sav file" + (count === 1 ? "" : "s") + " in " + listing.path + "."); + } + if (state.file && !el.newest.checked) { + // The picked file may be gone; the folder listing is the truth. + var stillThere = state.entries.some(function(entry) { + return entry.name === state.file && !entry.isDir; + }); + if (!stillThere) { + state.file = ""; + state.filePath = ""; + } + } + renderPicked(); + } + + function renderPicked() { + if (!el.picked) { + return; + } + var chosen = state.takeNewest + ? "newest .sav in the folder" + : (state.file || "nothing picked yet -- click a .sav above"); + el.picked.textContent = "Will load: " + chosen; + el.load.disabled = !(state.takeNewest ? state.dir : state.filePath); + } + + // ---- Load and watch ------------------------------------------------------ + + // The one place a save is actually pulled and handed to the map. + // + // `manual` means the user pressed the button: always load, and leave the + // watch baseline unset so the next tick re-establishes it (that tick may + // fetch once more, but the hash comparison then keeps the map as it is). + // A watch tick passes the stat key it saw, so a folder that has not changed + // again stays quiet. + function load(manual, seenKey) { + if (state.transport === "ssh" && !state.target.host) { + say("Set the host and validate the connection first."); + return Promise.resolve(); + } + // Re-read the folder first: "newest" only exists in a listing, and the one + // on screen may be minutes old -- a tick that just noticed a new autosave + // has to see it, or it would load the file it already had. + return browse(state.dir, true).then(function() { + var entry = currentTarget(); + if (!entry) { + say(state.takeNewest + ? "No .sav file in " + state.dir + "." + : "Pick a .sav file to load" + (state.file ? " (" + state.file + " is gone)" : "") + "."); + return null; + } + state.file = entry.name; + state.filePath = entry.path; + remember(); + if (state.transport === "local") { + // A mounted file is read in place, and it carries its own timestamp, + // so the baseline is exact and the next tick has nothing to confirm. + state.sha = null; + state.seen = seenKey || statKey(entry); + return options.loadPath(entry.path).then(function() { + say("Loaded " + entry.name + " (" + bytes(entry.size) + ") at " + clock() + "."); + arm(); + }).catch(function(error) { + say("Load failed: " + message(error)); + }); + } + // rsync only when the far side actually has it (validate says so); SFTP is + // the transport that works against a stock Windows OpenSSH server. + var transport = state.capabilities && state.capabilities.rsync ? "rsync" : "sftp"; + say("Fetching " + entry.name + " over " + transport + "\u2026"); + return invoke("source_fetch", { + target: state.target, + remotePath: entry.path, + transport: transport, + }).then(function(fetched) { + if (!manual && fetched.sha256 === state.sha) { + state.seen = seenKey || null; + say("Auto-refresh " + clock() + ": " + fetched.saveName + " re-fetched, bytes unchanged."); + return null; + } + state.sha = fetched.sha256; + state.seen = manual ? null : (seenKey || null); + state.loadedPath = fetched.path; + return options.loadPath(fetched.path).then(function() { + say("Loaded " + fetched.saveName + " (" + bytes(fetched.bytes) + ") over " + transport + " at " + clock() + "."); + arm(); + }); + }).catch(function(error) { + say((manual ? "Fetch failed: " : "Auto-refresh " + clock() + ": ") + message(error)); + }); + }); + } + + // The picked file, as the last listing described it. + function localEntry(name) { + return (state.entries || []).filter(function(entry) { + return !entry.isDir && entry.name === name; + })[0] || null; + } + + // What "load" means right now: the newest .sav in the folder, or the one the + // user picked. The listing is the only source for both. + function currentTarget() { + if (!state.takeNewest) { + return localEntry(state.file); + } + var saves = (state.entries || []).filter(function(entry) { + return !entry.isDir && isSave(entry.name); + }); + saves.sort(function(a, b) { + return (b.mtime || 0) - (a.mtime || 0); + }); + return saves[0] || null; + } + + // The identity of "the file we would load": the three things a listing gives + // us, and the only things a change can move. + function statKey(stat) { + if (!stat || !stat.name) { + return null; + } + return stat.name + "|" + stat.size + "|" + stat.mtime; + } + + // One watch tick: re-read the folder and go further only when the file we + // would load has changed. Paused while the tab is hidden, while a parse is + // running, and while the editor holds pending edits -- a reload discards + // those, so the user finishes first and polling resumes on its own. + function tick() { + if (!state.watch || document.hidden || options.isBusy()) { + return; + } + var pending = options.pendingEdits(); + if (pending > 0) { + say("Auto-refresh paused: " + pending + " edit(s) pending -- undo or export them and it resumes."); + return; + } + if (!state.dir) { + return; + } + browse(state.dir, true).then(function() { + var entry = currentTarget(); + if (!entry) { + say("Auto-refresh " + clock() + ": " + (state.takeNewest + ? "no .sav in " + state.dir + " yet" + : state.file + " is no longer in " + state.dir + + " -- tick \"always take the newest\" to follow the autosaves")); + return null; + } + var key = statKey(entry); + if (key === state.seen) { + say("Auto-refresh " + clock() + ": " + entry.name + " unchanged."); + return null; + } + // Changed (or first look): fetch, hash, and let load() decide whether the + // map actually needs rebuilding. + say("Auto-refresh " + clock() + ": " + entry.name + " changed, fetching\u2026"); + return load(false, key); + }).catch(function(error) { + // Machine asleep, sshd stopped, share unmounted: say so and keep trying. + say("Auto-refresh " + clock() + ": " + message(error) + " (will retry)."); + }); + } + + // The poll starts on the first load from this source, and every load restarts + // the clock -- so a save loaded by hand is not re-fetched a moment later. + function arm() { + if (state.watch) { + schedule(); + } + } + + function schedule() { + stop(); + if (!state.watch || !watchPossible()) { + return; + } + timer = window.setInterval(tick, Math.max(5, state.interval) * 1000); + } + + function stop() { + if (timer !== null) { + window.clearInterval(timer); + timer = null; + } + } + + return { + init: function(bridge) { + try { + init(bridge); + } catch (error) { + // A missing dialog or a broken bridge must not take the load flow down. + console.warn("SaveSource: not available:", error); + } + }, + open: open, + state: state, + }; +})(); diff --git a/rust_parser/tauri/src/lib.rs b/rust_parser/tauri/src/lib.rs index 556fc24..441548b 100644 --- a/rust_parser/tauri/src/lib.rs +++ b/rust_parser/tauri/src/lib.rs @@ -5,3 +5,4 @@ pub mod server_api; pub mod session; +pub mod ssh_source; diff --git a/rust_parser/tauri/src/main.rs b/rust_parser/tauri/src/main.rs index c4c96ca..f47f9e1 100644 --- a/rust_parser/tauri/src/main.rs +++ b/rust_parser/tauri/src/main.rs @@ -12,6 +12,7 @@ use sav_tauri_lib::server_api; use sav_tauri_lib::session::AppSession; +use sav_tauri_lib::ssh_source; use std::sync::Mutex; use tauri::ipc::{Channel, Response}; use tauri::{Manager, State}; @@ -551,6 +552,69 @@ async fn server_fetch_latest( }) } +// ---- Save sources over SSH / a mounted share (src/ssh_source.rs) ----------- +// The HTTP alternative to these is a listener on the game machine; these use +// the OpenSSH server that is already there. All of them run on blocking +// threads, because each one is a subprocess with a deadline. + +/// "Can this connection do what the dialog needs?" -- authentication, the +/// SFTP subsystem (browsing and change polling depend on it), rsync on the far +/// side, and how many saves are in `dir` when the caller already knows one. +#[tauri::command] +async fn source_validate( + target: ssh_source::SshTarget, + dir: Option, +) -> Result { + tauri::async_runtime::spawn_blocking(move || { + ssh_source::validate(&target, dir.as_deref().unwrap_or("")) + }) + .await + .map_err(|e| format!("Validation task failed: {e}")) +} + +/// One directory listing: over SFTP when `local` is false, straight off the +/// filesystem when it is true (a mounted SMB/NFS share needs no protocol code +/// -- the OS already speaks it). +#[tauri::command] +async fn source_browse( + target: ssh_source::SshTarget, + path: String, + local: bool, +) -> Result { + tauri::async_runtime::spawn_blocking(move || { + if local { + ssh_source::browse_local(&path) + } else { + ssh_source::browse(&target, &path) + } + }) + .await + .map_err(|e| format!("Browse task failed: {e}"))? +} + +/// Pull the save into the app's own cache folder and hash it. `transport` is +/// "sftp" (works against a stock Windows OpenSSH server) or "rsync" (delta +/// transfer, when the far side has it -- the same 50 MB save re-fetched on +/// every autosave is what that earns). +#[tauri::command] +async fn source_fetch( + target: ssh_source::SshTarget, + remote_path: String, + transport: String, + app: tauri::AppHandle, +) -> Result { + let cache = app + .path() + .app_local_data_dir() + .map_err(|e| format!("No app data dir: {e}"))? + .join("remote-saves"); + tauri::async_runtime::spawn_blocking(move || { + ssh_source::fetch(&target, &remote_path, &transport, &cache) + }) + .await + .map_err(|e| format!("Fetch task failed: {e}"))? +} + /// Where the TOFU certificate pins live (see server_api::fetch_latest). fn cert_pin_path(app: &tauri::AppHandle) -> Result { Ok(app @@ -736,6 +800,9 @@ fn main() { payload_slice, payload_done, server_fetch_latest, + source_validate, + source_browse, + source_fetch, server_forget_pin, server_password_store, server_password_get, diff --git a/rust_parser/tauri/src/ssh_source.rs b/rust_parser/tauri/src/ssh_source.rs new file mode 100644 index 0000000..ab563d4 --- /dev/null +++ b/rust_parser/tauri/src/ssh_source.rs @@ -0,0 +1,910 @@ +//! Save sources on the machine that runs the game: its own SSH server. +//! +//! The alternative to this module is a small HTTP file server on the gaming PC +//! (`tools/save-http-server`). This one opens no listening port and adds no +//! service to keep patched: OpenSSH is already installed on Windows 10/11 and +//! on every Linux box, it authenticates with the key the user already has, and +//! it offers what a static file endpoint cannot -- a directory listing we can +//! actually browse, and a change signal cheap enough to poll. +//! +//! Nothing here implements the SSH protocol. It runs the user's own `ssh`, +//! `sftp` and `rsync`, so `~/.ssh/config`, `known_hosts`, ssh-agent, keys and +//! `ProxyJump` all apply for free, and the app ships no SSH stack to keep +//! current. The trade-off is that authentication and host keys stay OpenSSH's +//! business: every call sets `BatchMode=yes`, so key/agent auth only -- a +//! hidden-stdin password prompt would otherwise hang until the timeout -- and a +//! first connection to an unknown host fails unless the user opts into +//! `StrictHostKeyChecking=accept-new` (trust on first use, same disclosure as +//! the dedicated-server certificate pin in `server_api`). + +use serde::{Deserialize, Serialize}; +use sha2::{Digest, Sha256}; +use std::io::{Read, Write}; +use std::process::{Command, Stdio}; +use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; + +const CONNECT_TIMEOUT_SECS: u32 = 10; +const PROBE_TIMEOUT: Duration = Duration::from_secs(45); +const FETCH_TIMEOUT: Duration = Duration::from_secs(1800); +/// Ceiling on a remote save. Far above any real one (a 600k-object endgame +/// save is ~50 MB) and low enough that a wrong path cannot fill the disk. +const MAX_SAVE_BYTES: u64 = 8 * 1024 * 1024 * 1024; + +/// Everything needed to reach the game machine over SSH. Persisted by the +/// frontend in localStorage; only `identity` and `accept_new_host_key` touch +/// anything on disk outside our own app-data dir. +#[derive(Deserialize, Serialize, Clone, Default)] +#[serde(rename_all = "camelCase")] +pub struct SshTarget { + pub host: String, + #[serde(default)] + pub user: String, + /// 0 means "the client's default" (22 unless ~/.ssh/config says otherwise). + #[serde(default)] + pub port: u16, + #[serde(default)] + pub identity: String, + #[serde(default)] + pub accept_new_host_key: bool, +} + +/// Result of `source_validate`: what the connection can actually do. Each +/// field maps to one line in the dialog, so a partial capability (SSH works, +/// no SFTP subsystem) is reported rather than collapsing to "failed". +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +pub struct ValidateResult { + pub ok: bool, + /// "Windows" | "Linux" | "macOS" | "" -- from the shape of the SFTP home. + pub platform: String, + /// Remote home directory as SFTP reports it (`/home/x`, `/C:/Users/x`). + pub home: String, + /// SFTP subsystem: without it there is no browsing and no change polling, + /// only a typed path plus an rsync pull. + pub sftp: bool, + /// rsync on the REMOTE side: what makes rsync-over-ssh usable. + pub rsync: bool, + /// How many `.sav` files are in `dir`, when the caller passed one. + pub save_count: usize, + pub newest_save: String, + /// Human-readable last word: the error when `ok` is false. + pub detail: String, +} + +#[derive(Serialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct DirEntry { + pub name: String, + pub path: String, + pub is_dir: bool, + pub size: u64, + /// Unix seconds; the listing's own resolution (a minute). + pub mtime: i64, +} + +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Listing { + pub path: String, + pub parent: String, + pub entries: Vec, +} + +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +pub struct FetchedSave { + pub path: String, + pub save_name: String, + pub sha256: String, + pub bytes: u64, + pub remote_path: String, +} + +// ---- Running the tools ---------------------------------------------------- + +struct Cmd { + ok: bool, + stdout: String, + stderr: String, + timed_out: bool, +} + +/// Run a local tool with a hard deadline, draining both pipes on their own +/// threads. Without that, a remote process that writes more than a pipe buffer +/// stalls forever waiting for a reader that is waiting for it to exit. +fn run(bin: &str, args: &[String], stdin: Option<&str>, timeout: Duration) -> Result { + let mut child = Command::new(bin) + .args(args) + .stdin(if stdin.is_some() { Stdio::piped() } else { Stdio::null() }) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .map_err(|e| format!("Could not run {bin}: {e}"))?; + if let Some(text) = stdin { + if let Some(mut pipe) = child.stdin.take() { + // Our batch scripts are a few hundred bytes; writing them before + // reading stdout cannot fill a pipe. + pipe.write_all(text.as_bytes()) + .map_err(|e| format!("Could not talk to {bin}: {e}"))?; + } + } + let mut out = child.stdout.take().expect("stdout piped"); + let mut err = child.stderr.take().expect("stderr piped"); + let out_thread = std::thread::spawn(move || { + let mut buf = Vec::new(); + let _ = out.read_to_end(&mut buf); + buf + }); + let err_thread = std::thread::spawn(move || { + let mut buf = Vec::new(); + let _ = err.read_to_end(&mut buf); + buf + }); + let deadline = Instant::now() + timeout; + let mut timed_out = false; + let status = loop { + match child.try_wait() { + Ok(Some(status)) => break Some(status), + Ok(None) => { + if Instant::now() >= deadline { + timed_out = true; + let _ = child.kill(); + break child.wait().ok(); + } + std::thread::sleep(Duration::from_millis(40)); + } + Err(e) => return Err(format!("Could not wait for {bin}: {e}")), + } + }; + let stdout = String::from_utf8_lossy(&out_thread.join().unwrap_or_default()).into_owned(); + let stderr = String::from_utf8_lossy(&err_thread.join().unwrap_or_default()).into_owned(); + Ok(Cmd { + ok: status.map(|s| s.success()).unwrap_or(false), + stdout, + stderr, + timed_out, + }) +} + +/// Reject anything that would reach the client as an option instead of a +/// host, and anything that would break out of the quoting we do for the SFTP +/// batch script. There is no shell in the middle (argv is passed straight to +/// the tool), so this is about the tools' own argument parsing, not `sh -c`. +fn check_token(what: &str, value: &str, allowed: &str) -> Result<(), String> { + if value.is_empty() { + return Err(format!("{what} is empty.")); + } + if value.starts_with('-') { + return Err(format!("{what} cannot start with '-'.")); + } + if !value.chars().all(|c| allowed.contains(c)) { + return Err(format!("{what} contains a character that is not allowed: {value}")); + } + Ok(()) +} + +/// A remote path travels to `sftp` inside a batch script, where a newline +/// would be read as the next command. Reject control characters and the +/// double quote we wrap paths in; both are impossible in a real save path. +fn check_remote_path(path: &str) -> Result<(), String> { + if path.trim().is_empty() { + return Err("Enter a folder on the remote machine first.".to_string()); + } + if path.len() > 4096 { + return Err("That path is implausibly long.".to_string()); + } + if path.chars().any(|c| c.is_control()) { + return Err("That path has a control character in it.".to_string()); + } + if path.contains('"') { + return Err("That path has a double quote in it.".to_string()); + } + Ok(()) +} + +impl SshTarget { + fn check(&self) -> Result<(), String> { + check_token( + "The host", + self.host.trim(), + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_:[]", + )?; + if !self.user.trim().is_empty() { + check_token( + "The user name", + self.user.trim(), + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._-@\\", + )?; + } + // `port` is a u16: an out-of-range number fails to deserialize before + // it gets here, so there is no range to re-check. + if !self.identity.trim().is_empty() && !std::path::Path::new(self.identity.trim()).is_file() { + return Err(format!("No key file at {}.", self.identity.trim())); + } + Ok(()) + } + + fn destination(&self) -> String { + if self.user.trim().is_empty() { + self.host.trim().to_string() + } else { + format!("{}@{}", self.user.trim(), self.host.trim()) + } + } + + /// Options shared by ssh and sftp. `BatchMode=yes` is what keeps a + /// password or host-key question from hanging the app on an invisible + /// stdin; `accept-new` is the user's explicit opt-in to trust a host we + /// have never seen (it still refuses a CHANGED key). + fn opts(&self) -> Vec { + let mut opts: Vec = vec![ + "-o".into(), + "BatchMode=yes".into(), + "-o".into(), + format!("ConnectTimeout={CONNECT_TIMEOUT_SECS}"), + "-o".into(), + if self.accept_new_host_key { + "StrictHostKeyChecking=accept-new".into() + } else { + "StrictHostKeyChecking=yes".into() + }, + ]; + if !self.identity.trim().is_empty() { + opts.push("-i".into()); + opts.push(self.identity.trim().to_string()); + } + opts + } + + fn ssh_args(&self, remote_command: &str) -> Vec { + let mut args = self.opts(); + if self.port != 0 && self.port != 22 { + args.push("-p".into()); + args.push(self.port.to_string()); + } + args.push(self.destination()); + args.push(remote_command.to_string()); + args + } + + /// sftp spells the port `-P`, and takes the batch script on stdin. + fn sftp_args(&self) -> Vec { + let mut args = self.opts(); + if self.port != 0 && self.port != 22 { + args.push("-P".into()); + args.push(self.port.to_string()); + } + args.push("-b".into()); + args.push("-".into()); + args.push(self.destination()); + args + } +} + +fn first_line(text: &str) -> String { + text.lines().next().unwrap_or("").trim().to_string() +} + +/// The client's own words are the useful half of a failure ("Permission +/// denied (publickey)", "Host key verification failed"), so prefer stderr and +/// only fall back to a generic line. +fn tool_error(bin: &str, cmd: &Cmd) -> String { + let detail = if cmd.stderr.trim().is_empty() { + first_line(&cmd.stdout) + } else { + first_line(&cmd.stderr) + }; + if cmd.timed_out { + return format!("{bin} timed out. Is the machine awake and reachable?"); + } + if detail.is_empty() { + return format!("{bin} failed (exit status unknown)."); + } + detail +} + +fn sftp_script(t: &SshTarget, commands: &[String], timeout: Duration) -> Result { + t.check()?; + let script = format!("{}\n", commands.join("\n")); + let cmd = run("sftp", &t.sftp_args(), Some(&script), timeout)?; + if cmd.timed_out { + return Err(tool_error("sftp", &cmd)); + } + if !cmd.ok { + return Err(tool_error("sftp", &cmd)); + } + Ok(cmd.stdout) +} + +// ---- Parsing the SFTP client's output ------------------------------------- + +/// Pull the path out of `pwd`'s "Remote working directory: ". +fn parse_pwd(text: &str) -> Option { + text.lines() + .find_map(|line| line.trim().strip_prefix("Remote working directory:")) + .map(|path| path.trim().to_string()) + .filter(|path| !path.is_empty()) +} + +/// The Windows OpenSSH server exposes drives as `/C:/...`; the POSIX one as a +/// plain absolute path. That is enough to say which OS we are talking to +/// without a second round trip (`uname` does not exist in cmd.exe). +fn platform_from_home(home: &str) -> &'static str { + let rest = home.trim_start_matches('/'); + let mut chars = rest.chars(); + match (chars.next(), chars.next()) { + (Some(letter), Some(':')) if letter.is_ascii_alphabetic() => "Windows", + _ => "Linux/macOS", + } +} + +const MONTHS: [&str; 12] = [ + "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", +]; + +/// `ls -l` prints either "Mon DD HH:MM" (within the last six months) or +/// "Mon DD YYYY". Turn that into Unix seconds so the browser can sort by it +/// and show something meaningful; the year is inferred the way `ls` does, with +/// a clock-skew allowance so a file written a moment ago in another timezone +/// is not pushed a year into the future. +fn parse_when(month: &str, day: &str, third: &str, now: SystemTime) -> i64 { + let Some(m) = MONTHS.iter().position(|name| name.eq_ignore_ascii_case(month)) else { + return 0; + }; + let Ok(day) = day.trim().parse::() else { + return 0; + }; + let now_secs = now + .duration_since(UNIX_EPOCH) + .map(|d| d.as_secs() as i64) + .unwrap_or(0); + let now_year = 1970 + (now_secs / 31_556_952) as i32; // ~mean year, fine for inference + let (year, hour, minute) = if third.contains(':') { + let mut parts = third.split(':'); + let hour = parts.next().and_then(|h| h.trim().parse::().ok()).unwrap_or(0); + let minute = parts.next().and_then(|m| m.trim().parse::().ok()).unwrap_or(0); + // `ls` omits the year for recent files: assume this year, and step + // back one when that lands in the future by more than a day (a + // December file read in January). + let mut year = now_year; + if month_secs(year, m, day, hour, minute) > now_secs + 86_400 { + year -= 1; + } + (year, hour, minute) + } else { + (third.trim().parse::().unwrap_or(now_year), 0, 0) + }; + month_secs(year, m, day, hour, minute) +} + +/// Days-from-civil (Howard Hinnant's algorithm), so no chrono dependency for +/// what is only ever a sort key and a timestamp. +fn month_secs(year: i32, month: usize, day: u32, hour: u32, minute: u32) -> i64 { + let m = month as i32 + 1; + let y = if m <= 2 { year - 1 } else { year }; + let era = if y >= 0 { y } else { y - 399 } / 400; + let yoe = (y - era * 400) as i64; + let mp = ((m + 9) % 12) as i64; + let doy = (153 * mp + 2) / 5 + day as i64 - 1; + let doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; + let days = era as i64 * 146_097 + doe - 719_468; + days * 86_400 + hour as i64 * 3600 + minute as i64 * 60 +} + +/// One `ls -l` line from the SFTP client into an entry. +/// +/// The client prints `mode nlink owner group size `, and the +/// fields in between vary in both shape and count: OpenSSH sends no link +/// count, so the client prints `?` there, an SSH server with no owner +/// information prints `?` twice more, and the name is the path as the server +/// saw it -- the full `/home/x/saves/a.sav` when we asked for that directory +/// by absolute path. Field positions are therefore not fixed, so the date is +/// the anchor: it is always three tokens and always shaped the same (a month +/// name, a day, then either `HH:MM` or a year), which also leaves names with +/// spaces intact. +fn parse_ls_line(line: &str, dir: &str, now: SystemTime) -> Option { + let trimmed = line.trim_end_matches(['\r', '\n']); + let mode = trimmed.split_whitespace().next()?; + let mut chars = mode.chars(); + let kind = chars.next()?; + if !matches!(kind, '-' | 'd' | 'l' | '?') || mode.len() < 10 { + return None; + } + if !mode[1..].chars().all(|c| "rwxstST-".contains(c)) { + return None; + } + // Whatever the server called it, the entry's own name is the last segment + // (a file name cannot contain a separator). + let name = entry_name(trimmed, mode)?; + let name = name.rsplit(['/', '\\']).next().unwrap_or("").to_string(); + if name.is_empty() || name == "." || name == ".." { + return None; + } + let rest = field_after(trimmed, mode)?; + let tokens = tokens_at(rest); + let month_at = date_at(&tokens)?; + // The size sits immediately before the date; counting fields from the left + // would instead land on the `?` the client prints for an unknown link + // count, which is the one field every remote listing has. + let size = month_at + .checked_sub(1) + .and_then(|at| tokens.get(at)) + .and_then(|(_, token)| token.parse::().ok()) + .unwrap_or(0); + let mtime = match tokens.get(month_at..month_at + 3) { + Some(triple) => parse_when(triple[0].1, triple[1].1, triple[2].1, now), + None => 0, + }; + Some(DirEntry { + path: join_remote(dir, &name), + name, + is_dir: kind == 'd', + size, + mtime, + }) +} + +/// Text after the mode field, where size and the date live. +fn field_after<'a>(line: &'a str, mode: &str) -> Option<&'a str> { + let at = line.find(mode)? + mode.len(); + Some(line[at..].trim_start()) +} + +/// Whitespace-separated tokens with the byte offset each starts at, so the +/// name can be sliced back out of the original line. `ls -l` pads its date +/// columns ("Jan 3 2025"), and rebuilding the date from its parts would +/// silently lose an entry whose name follows a double space. +fn tokens_at(text: &str) -> Vec<(usize, &str)> { + let mut out = Vec::new(); + let mut start = None; + for (at, ch) in text.char_indices() { + if ch.is_whitespace() { + if let Some(from) = start.take() { + out.push((from, &text[from..at])); + } + } else if start.is_none() { + start = Some(at); + } + } + if let Some(from) = start { + out.push((from, &text[from..])); + } + out +} + +/// The `(month, day, time-or-year)` triple the line carries, located by month +/// name so a varying number of owner/group fields cannot shift it. +fn date_at(tokens: &[(usize, &str)]) -> Option { + tokens.iter().position(|(_, token)| { + MONTHS.iter().any(|name| name.eq_ignore_ascii_case(token)) + }) +} + +fn entry_name(line: &str, mode: &str) -> Option { + let rest = field_after(line, mode)?; + let tokens = tokens_at(rest); + let month_at = date_at(&tokens)?; + // The name starts where the token after the date starts: month, day, then + // the time-or-year, then the name (spaces and all). + let (offset, _) = *tokens.get(month_at + 3)?; + Some(rest[offset..].to_string()) +} + +fn parse_listing(text: &str, dir: &str) -> Vec { + let now = SystemTime::now(); + text.lines() + .filter_map(|line| parse_ls_line(line, dir, now)) + .collect() +} + +/// `/a/b/c` -> `/a/b`, `/C:/` -> `/C:/`, and a Windows-style path keeps its +/// backslash separator (we only ever see the SFTP form, but a typed one is +/// cheap to handle). A root is its own parent, so the dialog's "Up" button +/// goes nowhere rather than somewhere invalid. +fn parent_of(path: &str) -> String { + let path = path.trim_end_matches(['/', '\\']); + if path.is_empty() { + return "/".to_string(); // "/" or a bare drive-relative path + } + if is_drive_root(path) { + return format!("{path}/"); + } + match path.rfind(['/', '\\']) { + Some(0) => "/".to_string(), + Some(at) => path[..at].to_string(), + None => String::new(), + } +} + +/// `/C:` or `C:` -- the top of a Windows drive, where SFTP's `cd ..` stops. +fn is_drive_root(path: &str) -> bool { + let bare = path.trim_start_matches('/'); + bare.len() == 2 + && bare.as_bytes()[1] == b':' + && (bare.as_bytes()[0] as char).is_ascii_alphabetic() +} + +fn join_remote(dir: &str, name: &str) -> String { + let dir = dir.trim_end_matches(['/', '\\']); + if dir.is_empty() { + name.to_string() + } else { + format!("{dir}/{name}") + } +} + +// ---- Commands ------------------------------------------------------------- + +pub fn validate(target: &SshTarget, dir: &str) -> ValidateResult { + let mut result = ValidateResult { + ok: false, + platform: String::new(), + home: String::new(), + sftp: false, + rsync: false, + save_count: 0, + newest_save: String::new(), + detail: String::new(), + }; + if let Err(error) = target.check() { + result.detail = error; + return result; + } + // One SFTP call answers three questions at once: does SSH authenticate at + // all, is the SFTP subsystem available, and where do we land? `pwd` is the + // cheapest command that proves the subsystem works end to end. + match sftp_script(target, &["pwd".to_string()], PROBE_TIMEOUT) { + Ok(out) => { + result.sftp = true; + result.home = parse_pwd(&out).unwrap_or_default(); + result.platform = if result.home.is_empty() { + String::new() + } else { + platform_from_home(&result.home).to_string() + }; + } + Err(error) => { + // "subsystem request failed" is a different problem from a bad key, + // and only one of them is fixable on our side. + result.detail = error; + return result; + } + } + // rsync on the FAR side is what makes rsync-over-ssh work; without it SFTP + // carries the transfer. + let cmd = run("ssh", &target.ssh_args("rsync --version"), None, PROBE_TIMEOUT); + result.rsync = cmd.map(|c| c.ok).unwrap_or(false); + if !dir.trim().is_empty() && result.sftp { + if let Ok(entries) = listing(target, dir) { + let saves: Vec<&DirEntry> = entries.iter().filter(|e| is_save(&e.name)).collect(); + result.save_count = saves.len(); + result.newest_save = newest_save(&entries).map(|e| e.name.clone()).unwrap_or_default(); + } + } + result.ok = result.sftp; + if result.ok { + let as_user = if target.user.trim().is_empty() { + "the SSH user".to_string() + } else { + target.user.trim().to_string() + }; + result.detail = format!("Signed in as {as_user}@{}.", target.host.trim()); + } + result +} + +fn is_save(name: &str) -> bool { + name.to_ascii_lowercase().ends_with(".sav") +} + +/// The newest `.sav` by listing timestamp -- the map's "latest autosave", +/// which is what the game itself writes over and over. Ties (same minute) fall +/// back to the name so the answer is at least stable. +fn newest_save(entries: &[DirEntry]) -> Option<&DirEntry> { + entries + .iter() + .filter(|entry| !entry.is_dir && is_save(&entry.name)) + .max_by(|a, b| a.mtime.cmp(&b.mtime).then_with(|| a.name.cmp(&b.name))) +} + +fn listing(target: &SshTarget, dir: &str) -> Result, String> { + check_remote_path(dir)?; + // `-l` is what gives us mode/size/date; the client does the formatting, so + // this works against a Windows or a POSIX server without a remote shell. + let out = sftp_script(target, &[format!("ls -l \"{dir}\"")], PROBE_TIMEOUT)?; + Ok(parse_listing(&out, dir)) +} + +pub fn browse(target: &SshTarget, dir: &str) -> Result { + Ok(listing_object(listing(target, dir)?, dir)) +} + +/// Folders first, then saves, then anything else; names within a group. Shared +/// by the SFTP and mounted-share listings so the two read the same. +fn listing_object(mut entries: Vec, dir: &str) -> Listing { + entries.sort_by(|a, b| { + b.is_dir + .cmp(&a.is_dir) + .then_with(|| is_save(&b.name).cmp(&is_save(&a.name))) + .then_with(|| a.name.to_lowercase().cmp(&b.name.to_lowercase())) + }); + Listing { + path: dir.trim_end_matches('/').to_string(), + parent: parent_of(dir), + entries, + } +} + +/// A mounted network share (SMB/CIFS from Windows, NFS, a GVFS mount) is just +/// a path -- the OS already did the hard part, so browsing it needs no +/// protocol code at all. +pub fn browse_local(dir: &str) -> Result { + let read = std::fs::read_dir(dir).map_err(|e| format!("Cannot read {dir}: {e}"))?; + let mut entries = Vec::new(); + for item in read.flatten() { + let path = item.path(); + let meta = match std::fs::metadata(&path) { + Ok(meta) => meta, + Err(_) => continue, // vanished mid-listing, or a dangling symlink + }; + entries.push(DirEntry { + name: item.file_name().to_string_lossy().into_owned(), + path: path.to_string_lossy().into_owned(), + is_dir: meta.is_dir(), + size: if meta.is_dir() { 0 } else { meta.len() }, + mtime: meta + .modified() + .ok() + .and_then(|t| t.duration_since(UNIX_EPOCH).ok()) + .map(|d| d.as_secs() as i64) + .unwrap_or(0), + }); + } + Ok(listing_object(entries, dir)) +} + +/// Copy a `.sav` down into the app's own `remote-saves/` folder and hash it. +/// The bytes go to a `.part` file that is renamed only once complete, so a +/// truncated transfer can never become the file the parser reads; the hash is +/// what lets the watch loop skip a reload when only the timestamp moved. +pub fn fetch( + target: &SshTarget, + remote_path: &str, + transport: &str, + cache_dir: &std::path::Path, +) -> Result { + check_remote_path(remote_path)?; + target.check()?; + let name = remote_path + .rsplit(['/', '\\']) + .next() + .unwrap_or("remote.sav") + .to_string(); + if !is_save(&name) { + return Err(format!("{name} is not a .sav file.")); + } + // The file on disk is always ours, never a name from the network. + let safe_name: String = name + .chars() + .filter(|c| !c.is_control() && *c != '/' && *c != '\\') + .take(120) + .collect(); + std::fs::create_dir_all(cache_dir) + .map_err(|e| format!("Failed to create {}: {e}", cache_dir.display()))?; + let final_path = cache_dir.join(&safe_name); + let part = cache_dir.join(format!("{safe_name}.part")); + let _ = std::fs::remove_file(&part); + + match transport { + "rsync" => { + let mut args: Vec = vec![ + "-e".into(), + format!("ssh {}", target.opts().join(" ")), + "--partial".into(), + "--compress".into(), + "--timeout=120".into(), + ]; + if target.port != 0 && target.port != 22 { + // rsync's ssh gets the port through -e, not its own flag. + args[1] = format!("ssh -p {} {}", target.port, target.opts().join(" ")); + } + let source = format!("{}:{}", target.destination(), remote_path.replace('\\', "/")); + args.push(source); + args.push(part.to_string_lossy().into_owned()); + let cmd = run("rsync", &args, None, FETCH_TIMEOUT)?; + if !cmd.ok || cmd.timed_out { + let _ = std::fs::remove_file(&part); + return Err(tool_error("rsync", &cmd)); + } + } + _ => { + // SFTP's own `get`, which also works where rsync does not exist + // (i.e. on a Windows game machine). + sftp_script( + target, + &[ + format!("get \"{remote_path}\" \"{}\"", part.to_string_lossy()), + "quit".to_string(), + ], + FETCH_TIMEOUT, + ) + .map_err(|e| { + let _ = std::fs::remove_file(&part); + e + })?; + } + } + + let bytes = std::fs::metadata(&part) + .map_err(|e| format!("The transfer produced no file: {e}"))? + .len(); + if bytes > MAX_SAVE_BYTES { + let _ = std::fs::remove_file(&part); + return Err(format!( + "That save is {bytes} bytes, over the {MAX_SAVE_BYTES}-byte limit." + )); + } + let sha256 = hash_file(&part)?; + std::fs::rename(&part, &final_path) + .map_err(|e| format!("Failed to move the download into {}: {e}", final_path.display()))?; + Ok(FetchedSave { + path: final_path.to_string_lossy().into_owned(), + save_name: safe_name, + sha256, + bytes, + remote_path: remote_path.to_string(), + }) +} + +fn hash_file(path: &std::path::Path) -> Result { + let mut file = + std::fs::File::open(path).map_err(|e| format!("Cannot read {}: {e}", path.display()))?; + let mut hasher = Sha256::new(); + let mut buf = [0u8; 256 * 1024]; + loop { + let read = file + .read(&mut buf) + .map_err(|e| format!("Cannot read {}: {e}", path.display()))?; + if read == 0 { + break; + } + hasher.update(&buf[..read]); + } + Ok(format!("{:x}", hasher.finalize())) +} + +#[cfg(test)] +mod tests { + use super::*; + + // Verbatim `sftp -b -` output from a real OpenSSH 10.2 sftp-server, minus + // the sizes: the batch-mode echo of the command, the `?` link count + // OpenSSH never sends, the total path in the name, and a dated file. + const POSIX_LISTING: &str = "\ +sftp> ls -l \"/saves/SaveGames\" +-rw-r--r-- ? dion dion 27000000 Oct 10 10:03 /saves/SaveGames/1.2_autosave_0.sav +-rw-r--r-- ? dion dion 27513344 Oct 10 10:03 /saves/SaveGames/1.2_autosave_1.sav +-rw-r--r-- ? dion dion 3 Oct 10 10:03 /saves/SaveGames/notes.txt +-rw-r--r-- ? dion dion 1024 Jan 3 2025 /saves/SaveGames/old autosave.sav +drwxr-xr-x ? dion dion 4096 Oct 9 08:02 /saves/SaveGames/Backup +"; + + // What an OpenSSH-for-Windows server looks like: no owner or group, and + // the drive spelled `/C:/`, which is the only way to tell it from a POSIX + // box without a second round trip (`uname` does not exist in cmd.exe). + const WINDOWS_LISTING: &str = "\ +sftp> ls -l \"/C:/saves\" +-rw-r--r-- ? ? 0 Oct 10 13:41 /C:/saves/1.2_autosave_1.sav +-rw-r--r-- ? ? 27513344 Oct 10 13:41 /C:/saves/notes.txt +drwxr-xr-x ? ? 0 Oct 10 13:41 /C:/saves/76561198036921297 +"; + + fn at(month: u32) -> SystemTime { + // 2026-10-10T12:00:00Z, built without chrono. + UNIX_EPOCH + Duration::from_secs(month_secs(2026, month as usize, 10, 12, 0) as u64) + } + + #[test] + fn listing_parses_real_sftp_output() { + let entries = parse_listing(POSIX_LISTING, "/saves/SaveGames"); + assert_eq!(entries.len(), 5, "the echoed command line is not an entry"); + let save = &entries[1]; + assert_eq!(save.name, "1.2_autosave_1.sav", "the path prefix is stripped"); + assert_eq!(save.path, "/saves/SaveGames/1.2_autosave_1.sav"); + assert_eq!(save.size, 27_513_344); + assert!(!save.is_dir); + assert!(entries[4].is_dir); + assert_eq!(entries[3].name, "old autosave.sav", "names keep their spaces"); + assert!(entries[3].mtime < save.mtime, "an explicit year sorts earlier"); + assert_eq!(newest_save(&entries).map(|e| e.name.as_str()), Some("1.2_autosave_1.sav")); + } + + #[test] + fn listing_parses_windows_output_too() { + let entries = parse_listing(WINDOWS_LISTING, "/C:/saves"); + assert_eq!(entries.len(), 3); + assert_eq!(entries[1].name, "notes.txt"); + assert!(entries[2].is_dir); + } + + #[test] + fn newest_save_ignores_everything_but_sav_files() { + let mut entries = parse_listing(WINDOWS_LISTING, "/C:/saves"); + // The newest thing in the folder is not a save; the newest .sav wins. + entries.push(DirEntry { + name: "zzz.txt".to_string(), + path: "/C:/saves/zzz.txt".to_string(), + is_dir: false, + size: 1, + mtime: 4_000_000_000, + }); + assert_eq!(newest_save(&entries).map(|e| e.name.as_str()), Some("1.2_autosave_1.sav")); + assert_eq!(newest_save(&[]).map(|e| e.name.as_str()), None); + assert!(is_save("1.2_autosave_1.SAV"), "the game's own casing can vary"); + } + + #[test] + fn listing_rejects_junk() { + for line in [ + "", + "sftp> ls -l", + "total 12", + "not a listing at all", + "drwxr-xr-x", + "sftp> ls -l \"/saves\"", + ] { + assert!(parse_ls_line(line, "/x", at(10)).is_none(), "accepted {line:?}"); + } + } + + #[test] + fn when_parses_both_date_forms_and_infers_the_year() { + let now = at(10); + let recent = parse_when("Oct", "10", "13:41", now); + let explicit = parse_when("Jan", "3", "2025", now); + assert!(recent > explicit); + assert_eq!(recent, month_secs(2026, 9, 10, 13, 41)); + assert_eq!(explicit, month_secs(2025, 0, 3, 0, 0)); + // A December file read in January belongs to last year, not next. + let january = month_secs(2026, 0, 5, 12, 0) as u64; + let then = parse_when("Dec", "30", "09:00", UNIX_EPOCH + Duration::from_secs(january)); + assert_eq!(then, month_secs(2025, 11, 30, 9, 0)); + } + + #[test] + fn paths_are_joined_and_trimmed_the_way_sftp_reports_them() { + assert_eq!(parent_of("/C:/saves/765"), "/C:/saves"); + assert_eq!(parent_of("/C:/"), "/C:/"); + assert_eq!(parent_of("/home/dion"), "/home"); + assert_eq!(parent_of("/"), "/"); + assert_eq!(join_remote("/C:/saves/", "a.sav"), "/C:/saves/a.sav"); + } + + #[test] + fn pwd_and_platform_come_from_the_sftp_banner() { + assert_eq!( + parse_pwd("Remote working directory: /C:/Users/dion\n"), + Some("/C:/Users/dion".to_string()) + ); + assert_eq!(parse_pwd("no banner here"), None); + assert_eq!(platform_from_home("/C:/Users/dion"), "Windows"); + assert_eq!(platform_from_home("/home/dion"), "Linux/macOS"); + } + + #[test] + fn injection_through_the_batch_script_is_refused() { + assert!(check_remote_path("/C:/saves\nrm -rf /").is_err()); + assert!(check_remote_path("/C:/saves/\"x\".sav").is_err()); + assert!(check_remote_path("").is_err()); + assert!(check_remote_path("/C:/saves").is_ok()); + let mut target = SshTarget { + host: "-oProxyCommand=evil".to_string(), + ..Default::default() + }; + assert!(target.check().is_err()); + target.host = "192.168.1.50".to_string(); + assert!(target.check().is_ok()); + target.user = "dion nightly".to_string(); + assert!(target.check().is_err()); + } +} From cbf2b3820ed42f7b347e059e2028d99844f1590d Mon Sep 17 00:00:00 2001 From: DionJones615 <27814889+DionJones615@users.noreply.github.com> Date: Sat, 10 Oct 2026 11:57:52 -0400 Subject: [PATCH 2/9] Serve the save-source dialog without a build, so it can be seen locally The dialog is Tauri-gated, and the Tauri tree needs WebKitGTK/GTK development packages an immutable distro does not carry -- so on the machine reviewing this, there was no way to look at the thing being reviewed. `tools/serve_save_source_demo.py` serves map/static/map/ with a stubbed desktop bridge instead: the three commands answer from a real folder, so the listing, its sizes and timestamps, the "newest .sav" pick and the watch's change check are all real (drop a file in the folder and the next tick notices). Only the SSH transport is canned, and loading stops at the parser -- sav_core is the desktop build, dist/pkg the wasm build -- so the status line says that rather than pretending. docs/remote-save-ssh.md gains the three ways to run this: the demo server, the distrobox recipe for the real app on Linux, and the Windows build plus the sshd setup. It also records the one local trap worth knowing: an ostree install can leave /etc/ssh/ssh_config.d/* owned by an unmapped uid, which OpenSSH treats as fatal, so every ssh invocation dies before it connects and the dialog shows the client's own "Bad owner or permissions" line until it is fixed. --- docs/remote-save-ssh.md | 50 ++++++++++ tools/serve_save_source_demo.py | 158 ++++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+) create mode 100644 tools/serve_save_source_demo.py diff --git a/docs/remote-save-ssh.md b/docs/remote-save-ssh.md index 0c87180..679a1a8 100644 --- a/docs/remote-save-ssh.md +++ b/docs/remote-save-ssh.md @@ -70,6 +70,56 @@ to a `.part` file and renamed only when complete, and capped at 8 GiB, so a wrong path cannot fill the disk and a truncated transfer cannot become the file the parser reads. +## Running it locally + +**The dialog, without building anything** (needs only Python): + +```sh +python3 tools/serve_save_source_demo.py --dir /path/to/SaveGames +# then open http://127.0.0.1:8793/ and click Save File -> From another machine +``` + +That serves `map/static/map/` with a stubbed desktop bridge: the three commands +answer from a real folder, so the listing, its sizes and timestamps, the +"newest .sav" pick and the watch's change check are real (drop a file in the +folder and the next tick notices). Only the SSH transport is canned, and loading +stops at the parser -- `sav_core` is in the desktop build and `dist/pkg` is the +wasm build, neither of which that server has -- so the status line says so +rather than pretending. + +**The real thing on Linux** (the app itself, real SSH, real parsing). The Tauri +tree needs the WebKitGTK/GTK development packages, which an immutable distro +does not carry, so build it in a container: + +```sh +distrobox create --name satisfactory-map --image registry.fedoraproject.org/fedora:41 +distrobox enter satisfactory-map +sudo dnf install -y webkit2gtk4.1-devel gtk3-devel libsoup3-devel librsvg2-devel \ + openssl-devel cairo-devel pango-devel gdk-pixbuf2-devel +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +cd /rust_parser && cargo build -p sav_tauri --release +cargo tauri dev # or: cargo tauri build +``` + +**The real thing on Windows** is the repo's normal build (`cargo tauri build`) +plus the sshd setup above -- and Windows is where the game machine is, so this +is the path that ends in a working map. + +### If SSH is already broken on the machine running the app + +The dialog reports the ssh client's own words, and one of them is worth knowing +about: on an ostree/Bluefin-style install, files under `/etc/ssh/ssh_config.d/` +can end up owned by an unmapped uid (`nfsnobody`). OpenSSH treats a non-root +owned included config as fatal, so **every** `ssh` invocation fails with: + +``` +Bad owner or permissions on /etc/ssh/ssh_config.d/20-systemd-ssh-proxy.conf +``` + +That is not this app's bug and it breaks `ssh` in a terminal too; fix the +ownership (`sudo chown root:root /etc/ssh/ssh_config.d/*`) and Validate +connection starts answering. + ## Implementation notes - `map/static/map/save_source.js` — the dialog, the browser and the watch loop. diff --git a/tools/serve_save_source_demo.py b/tools/serve_save_source_demo.py new file mode 100644 index 0000000..0c2a032 --- /dev/null +++ b/tools/serve_save_source_demo.py @@ -0,0 +1,158 @@ +"""Run the app with a stubbed desktop bridge, so the "Save on another machine" +dialog (map/static/map/save_source.js) can be clicked through without a Tauri +build and without a game machine. + + py tools/serve_save_source_demo.py [port] [--dir FOLDER] + +Serves map/static/map/ and injects a script that installs window.__TAURI__ with +the three commands the dialog uses (source_validate, source_browse, +source_fetch). FOLDER -- the current directory by default -- is what the dialog +browses, so the listing, its sizes and timestamps, the "newest .sav" pick and +the watch's change check are all real; only the SSH transport is canned. + +Loading is where the demo stops: the parser lives in sav_core (desktop build) or +in dist/pkg (wasm build) and this server has neither, so the dialog's status +line says so instead of pretending. For the real thing see +docs/remote-save-ssh.md. +""" + +import argparse +import http.server +import json +import os +import sys + +REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +STATIC = os.path.join(REPO, "map", "static", "map") + +# Injected before the app scripts: window.__TAURI__ has to exist by the time +# save_client.js reads it, or the app takes the browser transport instead. +STUB = """ +""" + + +def snapshot(folder): + """The folder as the dialog sees it: real names, sizes and timestamps.""" + entries = [] + for item in sorted(os.scandir(folder), key=lambda e: e.name.lower()): + try: + stat = item.stat() + except OSError: + continue + entries.append({ + "name": item.name, + "path": item.path, + "isDir": item.is_dir(), + "size": 0 if item.is_dir() else stat.st_size, + "mtime": int(stat.st_mtime), + }) + entries.sort(key=lambda e: (not e["isDir"], not e["name"].lower().endswith(".sav"), e["name"].lower())) + return entries + + +class Handler(http.server.SimpleHTTPRequestHandler): + folder = os.getcwd() + extensions_map = {**http.server.SimpleHTTPRequestHandler.extensions_map, ".js": "text/javascript"} + + def __init__(self, *args, **kwargs): + super().__init__(*args, directory=STATIC, **kwargs) + + def do_GET(self): + path = self.path.split("?")[0] + if path == "/__demo/listing": + folder = os.path.abspath(self.folder) + body = json.dumps({ + "path": folder, + "parent": os.path.dirname(folder), + "entries": snapshot(folder), + }).encode("utf-8") + self.send_response(200) + self.send_header("Content-Type", "application/json") + self.send_header("Content-Length", str(len(body))) + self.send_header("Cache-Control", "no-cache") + self.end_headers() + self.wfile.write(body) + return + # index.html carries the injected bridge; everything else is the app. + if path in ("/", "/index.html"): + with open(os.path.join(STATIC, "index.html"), encoding="utf-8") as f: + page = f.read() + stub = STUB % {"dir": json.dumps(os.path.abspath(self.folder))} + page = page.replace('', stub + '', 1) + body = page.encode("utf-8") + self.send_response(200) + self.send_header("Content-Type", "text/html; charset=utf-8") + self.send_header("Content-Length", str(len(body))) + self.send_header("Cache-Control", "no-cache") + self.end_headers() + self.wfile.write(body) + return + super().do_GET() + + def end_headers(self): + # The watch loop polls by re-listing; a cached stub would freeze it. + self.send_header("Cache-Control", "no-cache") + super().end_headers() + + def log_message(self, *args): + pass + + +def main(): + parser = argparse.ArgumentParser(description=__doc__.splitlines()[0]) + parser.add_argument("port", nargs="?", type=int, default=8793) + parser.add_argument("--dir", default=os.getcwd(), help="folder the dialog browses (default: cwd)") + args = parser.parse_args() + if not os.path.isdir(args.dir): + sys.exit("not a folder: " + args.dir) + Handler.folder = os.path.abspath(args.dir) + print(f"demo bridge on http://127.0.0.1:{args.port}/ (browsing {Handler.folder})") + print("Save File -> From another machine -> Validate connection") + with http.server.ThreadingHTTPServer(("127.0.0.1", args.port), Handler) as server: + try: + server.serve_forever() + except KeyboardInterrupt: + pass + + +if __name__ == "__main__": + main() From e4d69306141e9bc4cc9c1ea0bbdcb577dbf1f552 Mon Sep 17 00:00:00 2001 From: DionJones615 <27814889+DionJones615@users.noreply.github.com> Date: Sat, 10 Oct 2026 13:12:40 -0400 Subject: [PATCH 3/9] One step at a time in the save-source dialog The dialog put every control on one screen: two protocol tabs, seven fields, a four-row connection report, a folder listing, three checkboxes and two blocks of prose, all competing for the same panel. It now walks the three decisions in order -- Protocol, Connection, Save to load -- with only the current step laid out, a stepper whose numbers go back, Back/Next in the foot, and focus landing on the first field of each step. - Protocol is two explained choices instead of two tabs. - Connection is that protocol's questions, one Validate button, and -- when it fails -- the ssh client's own words plus the one thing to try next (a refused key, an unknown host key, a dead port, a machine whose own ssh is broken, a server with no SFTP subsystem). The old four-row report was mostly a restatement of the error; a passing validate shows three lines, a failing one shows the error and no rows. - Save to load is the folder, the file and the freshness toggles, with the path guessed only when the platform is one the game's folders are known for: it used to append the Proton path to any non-Windows home, which is a wrong path rather than no path. - A remembered source reopens at the file it was left on, and the dialog no longer greets the user with the previous session's last watch tick. Wording: "Save file" reads as a verb phrase. The third step is "Save to load" and the sidebar panel it opens from is "Your save" -- a determiner, so the noun reading is the only reading. The docs and the demo server follow. Also: tools/serve_save_source_demo.py reports platform "demo", which is what makes the no-guess path above visible, and it serves the failure path when the host contains "fail" so the debug screen can be looked at without a game machine. --- docs/remote-save-ssh-dialog.png | Bin 155692 -> 114211 bytes docs/remote-save-ssh.md | 56 +++++----- docs/server-fetch.md | 2 +- map/static/map/data.js | 2 +- map/static/map/index.html | 135 ++++++++++++++---------- map/static/map/map.css | 150 +++++++++++++++++++++----- map/static/map/save_source.js | 181 ++++++++++++++++++++++++++------ tools/serve_save_source_demo.py | 9 +- 8 files changed, 395 insertions(+), 140 deletions(-) diff --git a/docs/remote-save-ssh-dialog.png b/docs/remote-save-ssh-dialog.png index 52dcf1d3ceb32a8452fc0d91f64fb0eeb4201947..1cf4d03ca9d80552a6f0c2b0bbbb8650bda734bd 100644 GIT binary patch literal 114211 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 B7Zd;h literal 155692 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

=Lm^gw^9|(yIZ%GolBJi9&%5Pnxzh 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

No save loaded

-

Drop a .sav anywhere on this window, or use the Save File panel below. It is parsed in your browser — nothing is uploaded.

+

Drop a .sav anywhere on this window, or use the panel below. It is parsed in your browser — nothing is uploaded.

@@ -196,7 +196,7 @@ - Save File + Your save
@@ -655,7 +655,7 @@ A modal like the rest: focus trap, Escape, backdrop close, top layer. Remote folder names are rendered with textContent -- they are untrusted data. --> - +
Save on another machine @@ -665,67 +665,88 @@
-
Pull the save off the gaming PC with the tools it already has — its own SSH server, or a share the OS has mounted. Nothing is hosted, nothing is uploaded; keys and ~/.ssh/config are used as they are.
+ +
+ + + +
-
How to reach it
-
- - -
- -
-
- - - -
- -
- - - -
Save folder
-
- - - -
-
-
- -
Keep it fresh
- - -
- - -
-

+ + + +
- + + +
diff --git a/map/static/map/map.css b/map/static/map/map.css index e780e75..13131aa 100644 --- a/map/static/map/map.css +++ b/map/static/map/map.css @@ -3076,31 +3076,105 @@ button:focus-visible, select:focus-visible, input[type="checkbox"]:focus-visible } /* ===== Save on another machine (save_source.js) ========================== - The SSH/SFTP source dialog. Chrome comes from ui.css (.dlg, .btn, .field, - .list, .row); only the pieces this dialog adds live here: the transport - tabs, the two-column host fields, the validation checklist, and the folder - list's fixed height so the dialog itself never scrolls. */ + A three-step dialog: protocol, connection, file. Only the current step is + laid out, so the crowded screen of seven fields, three checkboxes and a + folder listing competing for one panel is gone -- each step answers one + question. Chrome comes from ui.css (.dlg, .btn, .field, .list, .row). */ -.dlg-lg .dlg-inner { - width: 760px; +/* The stepper: a progress line that also goes back. */ +.srcSteps { + flex: none; + display: flex; + gap: var(--sp-1); + margin-bottom: var(--sp-3); + border-bottom: 1px solid var(--border-sub); + padding-bottom: var(--sp-2); +} + +.srcStepBtn { + display: inline-flex; + align-items: center; + gap: var(--sp-15); + padding: var(--sp-1) var(--sp-2); + font: inherit; + font-size: var(--fs-sm); + font-weight: 600; + color: var(--faint); + background: none; + border: 1px solid transparent; + border-radius: var(--r-sm); + cursor: pointer; +} + +.srcStepBtn:disabled { + cursor: default; + opacity: 0.55; +} + +.srcStepBtn.is-on { + color: var(--text-bright); + border-color: var(--border-popup); + background: var(--raised); +} + +.srcStepBtn.is-done { + color: var(--muted); } -.srcTabs { +.srcStepNum { + display: inline-flex; + align-items: center; + justify-content: center; + width: 16px; + height: 16px; + border-radius: var(--r-pill); + border: 1px solid currentColor; + font-size: var(--fs-2xs); +} + +/* Step 1: two protocols, each a row you can read and click anywhere on. */ +.srcPick { display: flex; - gap: var(--sp-1); + align-items: flex-start; + gap: var(--sp-2); + padding: var(--sp-25); margin-bottom: var(--sp-2); + border: 1px solid var(--border); + border-radius: var(--r-sm); + cursor: pointer; } -.srcTabs .btn.is-on { - background: var(--select-bg); - border-color: var(--accent-soft); - color: var(--text-bright); +.srcPick:hover { + border-color: var(--border-hover); + background: var(--raised); +} + +.srcPick:has(input:checked) { + border-color: var(--accent-border); + background: var(--accent-bg); +} + +.srcPickBody { + display: flex; + flex-direction: column; + gap: var(--sp-05); +} + +.srcPickName { + color: var(--text); + font-size: var(--fs-lg); + font-weight: 600; +} + +.srcPickNote { + color: var(--faint); + font-size: var(--fs-sm); } /* Host / user / port on one line: three short fields, one question. */ .srcGrid { display: grid; - grid-template-columns: 2fr 1fr 1fr; + grid-template-columns: 2fr 1fr 0.8fr; gap: var(--sp-2); margin-bottom: var(--sp-2); } @@ -3115,8 +3189,7 @@ button:focus-visible, select:focus-visible, input[type="checkbox"]:focus-visible .srcCheckLine { display: flex; align-items: center; - gap: var(--sp-2); - padding: var(--sp-1) 0; + gap: var(--sp-15); font-size: var(--fs-sm); color: var(--muted); cursor: pointer; @@ -3128,9 +3201,9 @@ button:focus-visible, select:focus-visible, input[type="checkbox"]:focus-visible color: var(--faint); } -/* One line per capability the connection has (or lacks): a tick, what it is, - and the detail -- so "SSH works but there is no SFTP subsystem" reads as a - partial answer instead of a bare failure. */ +/* One line per capability the connection has. "No rsync on the remote" is not + a failure -- SFTP carries the transfer -- so only the SFTP subsystem and the + login can go red. */ .srcChecks { margin-top: var(--sp-2); } @@ -3160,7 +3233,7 @@ button:focus-visible, select:focus-visible, input[type="checkbox"]:focus-visible .srcCheckName { flex: none; - min-width: 150px; + min-width: 120px; color: var(--text); } @@ -3170,6 +3243,28 @@ button:focus-visible, select:focus-visible, input[type="checkbox"]:focus-visible overflow-wrap: anywhere; } +/* Step 2's debug output: the client's own error, then what to try. */ +.srcError { + margin-top: var(--sp-2); + padding: var(--sp-2); + border: 1px solid var(--danger-border); + border-radius: var(--r-sm); + background: var(--danger-bg); +} + +.srcErrorText { + font-family: ui-monospace, monospace; + font-size: var(--fs-sm); + color: var(--danger-soft); + overflow-wrap: anywhere; +} + +.srcErrorHint { + margin-top: var(--sp-15); + font-size: var(--fs-sm); + color: var(--text); +} + .srcPathBar { display: flex; gap: var(--sp-2); @@ -3183,7 +3278,7 @@ button:focus-visible, select:focus-visible, input[type="checkbox"]:focus-visible /* Fixed height, so browsing between folders does not resize the dialog. */ .srcList { - height: 210px; + height: 200px; } .srcRow { @@ -3221,19 +3316,26 @@ button:focus-visible, select:focus-visible, input[type="checkbox"]:focus-visible overflow-wrap: anywhere; } +.srcPicked { + margin-top: var(--sp-2); + font-size: var(--fs-sm); + color: var(--muted); +} + +/* Step 3's three toggles on one line: what to take, whether to watch, how often. */ .srcWatchRow { display: flex; align-items: center; - gap: var(--sp-2); - font-size: var(--fs-sm); - color: var(--muted); + gap: var(--sp-3); + margin-top: var(--sp-2); } .srcWatchRow select { width: auto; + margin-left: auto; } -/* The status line rides in the foot, so "fetching…" is next to the button +/* The status line rides in the foot, so "validating…" is next to the button that started it. */ .dlg-foot #srcStatus { flex: 1 1 auto; diff --git a/map/static/map/save_source.js b/map/static/map/save_source.js index ff22a2c..3b6b236 100644 --- a/map/static/map/save_source.js +++ b/map/static/map/save_source.js @@ -42,6 +42,8 @@ window.SaveSource = (function() { takeNewest: true, watch: false, interval: 60, + step: 1, // 1 protocol, 2 connection, 3 save file + reached: 1, // the furthest step visited, so the stepper can go back capabilities: null, // last validate result seen: null, // "name|size|mtime" of the save we last loaded from sha: null, // hash of the bytes we last loaded (null = not loaded yet) @@ -142,11 +144,17 @@ window.SaveSource = (function() { port: document.getElementById("srcPort"), identity: document.getElementById("srcIdentity"), acceptNew: document.getElementById("srcAcceptNew"), + steps: document.querySelectorAll("#srcSteps .srcStepBtn"), + sections: document.querySelectorAll("#saveSourceModal .srcStep"), + protocols: document.querySelectorAll('input[name="srcProtocol"]'), sshFields: document.getElementById("srcSshFields"), localFields: document.getElementById("srcLocalFields"), localPath: document.getElementById("srcLocalPath"), validate: document.getElementById("srcValidate"), checks: document.getElementById("srcChecks"), + error: document.getElementById("srcError"), + back: document.getElementById("srcBack"), + next: document.getElementById("srcNext"), path: document.getElementById("srcPath"), up: document.getElementById("srcUp"), go: document.getElementById("srcGo"), @@ -159,7 +167,7 @@ window.SaveSource = (function() { load: document.getElementById("srcLoad"), status: document.getElementById("srcStatus"), }; - if (!el.dialogApi || !el.list || !el.sshFields || !el.localFields) { + if (!el.dialogApi || !el.list || !el.sshFields || !el.localFields || !el.next) { return; // markup missing (older dist): stay inert rather than throw } if (el.dialogApi.el.dataset.saveSourceWired) { @@ -176,20 +184,20 @@ window.SaveSource = (function() { } // The source is remembered, so the checkbox survives a restart -- but the // poll only starts once a save has been loaded from it in this session - // (see arm()), or it would download and load a save nobody asked for. - if (state.watch) { - say("Watching " + (state.file || state.dir) + " every " + state.interval + "s once a save is loaded."); - } + // (see arm()), or it would download and load a save nobody asked for. No + // status line for that: step 1 is a choice, not a report. } function open() { fillForm(); renderCapabilities(state.capabilities); + say(""); // whatever the last tick said is stale by the time this opens el.dialogApi.open(); + // Continue where the last session stopped: a remembered folder means the + // protocol and the connection are already answered. + showStep(state.dir ? 3 : 1); if (state.dir) { browse(state.dir); - } else if (el.path && !el.path.value) { - el.path.focus(); } } @@ -239,11 +247,65 @@ window.SaveSource = (function() { var local = state.transport === "local"; el.sshFields.style.display = local ? "none" : ""; el.localFields.style.display = local ? "" : "none"; - document.querySelectorAll("#srcTransportTabs button").forEach(function(button) { - var on = button.dataset.transport === state.transport; - button.classList.toggle("is-on", on); - button.setAttribute("aria-pressed", String(on)); + el.protocols.forEach(function(radio) { + radio.checked = radio.value === state.transport; + }); + } + + // One step at a time, and the stepper only offers steps already reached. + function showStep(step) { + state.step = step; + state.reached = Math.max(state.reached, step); + el.sections.forEach(function(section) { + section.style.display = Number(section.dataset.step) === step ? "" : "none"; }); + el.steps.forEach(function(button) { + var n = Number(button.dataset.step); + button.disabled = n > state.reached; + button.classList.toggle("is-on", n === step); + button.classList.toggle("is-done", n < step); + if (n === step) { + button.setAttribute("aria-current", "step"); + } else { + button.removeAttribute("aria-current"); + } + }); + el.back.style.display = step > 1 ? "" : "none"; + el.next.style.display = step < 3 ? "" : "none"; + el.load.style.display = step === 3 ? "" : "none"; + el.next.textContent = step === 1 ? "Connection" : "Save to load"; + if (step === 3) { + renderPicked(); + } + var body = el.dialogApi.el.querySelector(".dlg-body"); + if (body) { + body.scrollTop = 0; + } + } + + // "Validate/debug": the ssh client's own words are the error, and the hint is + // the one thing to try next. Anything not listed gets no invented advice. + function hintFor(error) { + var text = String(error || ""); + if (text.indexOf("Bad owner or permissions") !== -1) { + return "This machine's own ssh config is unreadable (a non-root owner under /etc/ssh/ssh_config.d). ssh fails outside this app too until it is fixed."; + } + if (/host key|Host key/i.test(text) && /known|verification/i.test(text)) { + return "Tick \"Trust this host's key the first time\" above, then validate again."; + } + if (/Permission denied/i.test(text)) { + return "The server refused the key. Check the user name, or add your public key to the server's authorized_keys."; + } + if (/Connection refused|timed out|No route to host|Could not resolve/i.test(text)) { + return "Nothing answered on that host and port. Is the machine awake, sshd running, and the firewall open?"; + } + if (/subsystem request failed|subsystem/i.test(text)) { + return "The server has no SFTP subsystem, so the folder cannot be listed or watched. Type the save's path in step 3; rsync can still pull it."; + } + if (/Could not run ssh|Could not run sftp/i.test(text)) { + return "No ssh client on this machine. Install OpenSSH and reopen this dialog."; + } + return ""; } // Whether watching is even possible: SFTP is what gives us a cheap listing @@ -271,20 +333,52 @@ window.SaveSource = (function() { } function wire() { - document.querySelectorAll("#srcTransportTabs button").forEach(function(button) { - button.addEventListener("click", function() { - state.transport = button.dataset.transport; + el.protocols.forEach(function(radio) { + radio.addEventListener("change", function() { + if (!radio.checked) { + return; + } + state.transport = radio.value; state.capabilities = null; - state.dir = state.transport === "local" - ? (el.localPath.value.trim() || state.dir) - : state.dir; - el.path.value = state.dir; + if (state.transport === "local" && el.localPath.value.trim()) { + state.dir = el.localPath.value.trim(); + el.path.value = state.dir; + } renderCapabilities(null); syncTransport(); syncWatchNote(); remember(); }); }); + el.steps.forEach(function(button) { + button.addEventListener("click", function() { + if (!button.disabled) { + showStep(Number(button.dataset.step)); + } + }); + }); + el.back.addEventListener("click", function() { + showStep(Math.max(1, state.step - 1)); + }); + el.next.addEventListener("click", function() { + readForm(); + if (state.step === 1) { + showStep(2); + (state.transport === "local" ? el.localPath : el.host).focus(); + return; + } + // Step 2 -> 3: land on the folder, whether or not validate was run. + if (state.transport === "local") { + state.dir = el.localPath.value.trim() || state.dir; + el.path.value = state.dir; + } + showStep(3); + if (state.dir) { + browse(state.dir); + } else { + el.path.focus(); + } + }); el.validate.addEventListener("click", validate); el.go.addEventListener("click", function() { browse(el.path.value.trim()); }); el.path.addEventListener("keydown", function(e) { @@ -345,34 +439,63 @@ window.SaveSource = (function() { renderCapabilities(result); syncWatchNote(); if (!result.ok) { - say(result.detail || "That connection did not work."); + showError(result.detail || "That connection did not work."); + say("Not connected."); return; } - say(result.detail); + showError(""); + say("Connected. Next: pick the save."); // Land the browser somewhere useful: the folder the caller gave, else the // game's usual save location under this user's home. if (!el.path.value.trim() && state.transport === "ssh") { - el.path.value = suggestDir(result); - browse(el.path.value); + state.dir = suggestDir(result); + el.path.value = state.dir; } }).catch(function(error) { el.validate.disabled = false; - say("Validation failed: " + message(error)); + showError(message(error)); + say("Not connected."); }); } + // The game's usual folder, when the platform is one we know. Anything else + // gets no guess: a wrong path is worse than an empty one, and the folder is + // one click away once the browser opens. function suggestDir(result) { var home = (result.home || "").replace(/[\\/]+$/, ""); - var user = state.target.user || ""; + if (!home) { + return ""; + } if (result.platform === "Windows") { return home + "/" + SAVE_DIR.windows; } - if (home) { + if (result.platform === "Linux/macOS") { return home + "/" + SAVE_DIR.linux; } return ""; } + // The connection's own words, plus the one thing to try next. + function showError(text) { + el.error.textContent = ""; + if (!text) { + el.error.style.display = "none"; + return; + } + var line = document.createElement("div"); + line.className = "srcErrorText"; + line.textContent = text; + el.error.appendChild(line); + var hint = hintFor(text); + if (hint) { + var advice = document.createElement("div"); + advice.className = "srcErrorHint"; + advice.textContent = hint; + el.error.appendChild(advice); + } + el.error.style.display = ""; + } + function renderCapabilities(result) { el.checks.innerHTML = ""; if (!result) { @@ -382,7 +505,7 @@ window.SaveSource = (function() { // connection is fine and SFTP carries the transfer. Red is reserved for the // one thing browsing and watching actually depend on. var rows = [ - [result.ok ? "ok" : "bad", "SSH login", result.detail || "no answer"], + [result.ok ? "ok" : "bad", "SSH login", result.ok ? (result.detail || "signed in") : "not connected"], [result.sftp ? "ok" : "bad", "SFTP subsystem", result.sftp ? "browsing and change detection available (" + (result.platform || "unknown") + (result.home ? ", " + result.home : "") + ")" @@ -391,10 +514,8 @@ window.SaveSource = (function() { ? "available (delta transfers, less to re-fetch)" : "not installed there -- SFTP is used instead"], ]; - if (result.saveCount || result.newestSave) { - rows.push(["ok", "Saves in that folder", - result.saveCount + " .sav file" + (result.saveCount === 1 ? "" : "s") - + (result.newestSave ? ", newest " + result.newestSave : "")]); + if (!result.ok) { + return; // the error block says it better, in the client's own words } rows.forEach(function(row) { var line = document.createElement("div"); diff --git a/tools/serve_save_source_demo.py b/tools/serve_save_source_demo.py index 0c2a032..a066c53 100644 --- a/tools/serve_save_source_demo.py +++ b/tools/serve_save_source_demo.py @@ -12,8 +12,8 @@ Loading is where the demo stops: the parser lives in sav_core (desktop build) or in dist/pkg (wasm build) and this server has neither, so the dialog's status -line says so instead of pretending. For the real thing see -docs/remote-save-ssh.md. +line says so instead of pretending. Validate against a host containing "fail" +to see the debug path. For the real thing see docs/remote-save-ssh.md. """ import argparse @@ -36,6 +36,11 @@ // loadSavePath builds a Channel before it invokes anything. function Channel() { this.onmessage = null; } window.__TAURI__ = { core: { Channel: Channel, invoke: function (cmd, args) { + // A host containing "fail" shows the debug path: the client's own words and + // the hint under them. Nothing else here depends on the host name. + if (cmd === "source_validate" && /fail/i.test((args.target && args.target.host) || "")) { + return Promise.reject(new Error("dion@192.168.1.50: Permission denied (publickey).")); + } if (cmd === "source_validate") { return listing().then(function (l) { var saves = l.entries.filter(function (e) { return !e.isDir && /\\.sav$/i.test(e.name); }); From dc7e71fcaff84c1b984bd26d9451df4d642aea09 Mon Sep 17 00:00:00 2001 From: DionJones615 <27814889+DionJones615@users.noreply.github.com> Date: Sat, 10 Oct 2026 13:27:44 -0400 Subject: [PATCH 4/9] Watch for changes with inotify/FileSystemWatcher, poll only as the fallback A change is now pushed to the map instead of waited for. `inotifywait -m` runs on the machine that holds the folder -- locally, or over the ssh connection -- and each name it prints wakes the same tick that the interval used to: re-list, compare, hash, reload only if the bytes moved. On Windows the equivalent is PowerShell's FileSystemWatcher, sent as a base64 `-EncodedCommand` (UTF-16LE), which is the only quoting that survives cmd.exe, the default shell of Windows OpenSSH; the encoder is checked against coreutils/iconv byte for byte. The interval stays, but only where events are impossible, and the dialog says which one is in use: - no inotifywait on the machine holding the saves; - a mounted share on Linux, where inotify can never fire: it only reports writes made through this kernel's own VFS, so the game machine writing into an SMB or NFS share is invisible -- silent rather than late, which is worse. The filesystem type is checked with findmnt before choosing, so this is decided rather than hoped. Windows is the exception: FileSystemWatcher does receive SMB notifications, so a UNC path or mapped drive there still gets events. An event is a nudge, not a verdict: the burst a save write produces is debounced (1.5s), then the listing comparison and the byte hash decide. A missed or spurious event therefore cannot reload the map wrongly, and a watcher that dies at once -- no inotifywait, no such folder, a refused key -- reports the tool's own words and the frontend falls back to the interval with that reason in the status line. Verified against a real sshd with an inotifywait test double: the local watcher (a write produced an event), the remote one (a write on the far side arrived over the connection), mode selection with and without the tool, and the dead-watcher error path. The browser run covers arming with events (zero intervals scheduled), a debounced event causing one check, non-.sav events ignored, turning it off, and the fallback when start fails. --- docs/remote-save-ssh.md | 38 +++- map/static/map/save_source.js | 115 +++++++++- rust_parser/tauri/src/main.rs | 53 ++++- rust_parser/tauri/src/ssh_source.rs | 312 ++++++++++++++++++++++++++++ tools/serve_save_source_demo.py | 26 ++- 5 files changed, 524 insertions(+), 20 deletions(-) diff --git a/docs/remote-save-ssh.md b/docs/remote-save-ssh.md index 4853799..789447c 100644 --- a/docs/remote-save-ssh.md +++ b/docs/remote-save-ssh.md @@ -25,8 +25,8 @@ key and `~/.ssh/config` the user already has. `ssh` is broken, a server with no SFTP subsystem. 3. **Save to load** — the folder, walked like a file dialog (folders first, `.sav` marked, `Up` for the parent), then the file. *Newest `.sav`* follows - the autosave rotation; *Keep it fresh* re-lists the folder and reloads the - map only when the fetched bytes actually changed. + the autosave rotation; *Keep it fresh* reloads the map when the save + changes -- see below for what "when" means. The stepper's numbers go back to a step already reached, and a remembered source reopens straight at the file it was left on. @@ -66,9 +66,33 @@ the dedicated-server certificate pin). A *changed* key is still refused. ## While it is watching -The status line says what each tick saw. Reloading is refused while the editor +**Changes are pushed when the machine can push them, and checked on an interval +when it cannot.** `inotifywait` is run *on the machine that holds the folder* — +locally, or over the ssh connection — and every name it prints wakes the same +check; on Windows the equivalent is PowerShell's `FileSystemWatcher`, sent as a +base64 `-EncodedCommand` so nothing in the path can be reinterpreted by +`cmd.exe`. Nothing is polled while events are live. + +Two cases fall back to the interval, and the dialog says which one you got: + +- **No `inotifywait` on that machine** (Debian/Ubuntu: `apt install + inotify-tools`; Fedora: `dnf install inotify-tools`; Bluefin: + `rpm-ostree install inotify-tools`). Windows needs nothing — the watcher is + part of .NET. +- **A mounted share on Linux.** `inotify` only reports writes made through this + machine's own kernel, so the game machine writing into an SMB or NFS share is + invisible to it — the watch would be silent rather than late, which is worse. + The filesystem type is checked before choosing, so this is decided rather than + hoped. Windows is the exception: `FileSystemWatcher` does receive SMB + notifications, so a UNC path or a mapped drive there still gets events. + +An event is a nudge, not a verdict: the burst a save write produces is +debounced, then the folder is re-listed and the fetched bytes are hashed, so a +missed or spurious event cannot reload the map wrongly. + +The status line says what each check saw. Reloading is refused while the editor holds pending edits (a reload discards them), while a parse is already running, -and while the window is hidden — polling resumes on its own. Remote names are +and while the window is hidden — it resumes on its own. Remote names are rendered as text, never as markup. A fetched save lands in the app's data directory under `remote-saves/`, written @@ -133,8 +157,10 @@ connection starts answering. subprocesses with a deadline, parses their output, and hashes what arrives. The app ships no SSH stack: host keys, keys, agents and `ProxyJump` are OpenSSH's, so the app never grows a second implementation of any of it. -- Commands: `source_validate`, `source_browse`, `source_fetch` -- the three - jobs the dialog has. The watch probe is a `source_browse`, because a listing +- Commands: `source_validate`, `source_browse`, `source_fetch` for the three + jobs the dialog has, plus `source_watch_start` / `source_watch_stop` for the + event watcher (a long-lived child process, local or over ssh, kept in the + Tauri state because a webview cannot hold one). The watch probe is a `source_browse`, because a listing is what says both what is in the folder and whether it moved. Every remote path crosses into an SFTP batch script, so control characters and quotes are rejected at the boundary; a host, user or port that could be read as an diff --git a/map/static/map/save_source.js b/map/static/map/save_source.js index 3b6b236..f06491d 100644 --- a/map/static/map/save_source.js +++ b/map/static/map/save_source.js @@ -31,7 +31,8 @@ window.SaveSource = (function() { var tauriInvoke = null; // window.__TAURI__.core.invoke, set by init var options = {}; - var timer = null; + var timer = null; // the fallback interval + var burst = null; // a change event waiting for the write burst to settle var el = {}; // cached elements var state = { @@ -42,6 +43,8 @@ window.SaveSource = (function() { takeNewest: true, watch: false, interval: 60, + watchMode: "", // "inotify" | "watcher" while events are live, "" while polling + watchKey: "", // target+dir the running watcher belongs to step: 1, // 1 protocol, 2 connection, 3 save file reached: 1, // the furthest step visited, so the stepper can go back capabilities: null, // last validate result @@ -178,6 +181,11 @@ window.SaveSource = (function() { wire(); syncWatchNote(); el.dialogApi.el.dataset.saveSourceWired = "1"; + if (window.__TAURI__.event && window.__TAURI__.event.listen) { + window.__TAURI__.event.listen("save-source-changed", function(event) { + onChanged(String((event && event.payload) || "")); + }); + } if (el.trigger) { el.trigger.style.display = ""; el.trigger.addEventListener("click", open); @@ -324,7 +332,11 @@ window.SaveSource = (function() { if (watchPossible()) { el.watch.checked = state.watch; el.watch.disabled = false; - el.watchNote.textContent = ""; + var mode = state.capabilities && state.capabilities.watch; + el.watchNote.textContent = !state.watch ? "" + : (mode + ? "The machine holding the save pushes changes, so the map reloads as they land." + : "No event source on that machine, so the folder is checked every " + state.interval + "s."); return; } el.watch.checked = false; @@ -402,12 +414,18 @@ window.SaveSource = (function() { }); el.watch.addEventListener("change", function() { readForm(); - schedule(); - say(state.watch ? "Watching -- every " + state.interval + "s once a save is loaded." - : "Watching off."); + syncWatchNote(); + if (!state.watch) { + stop(); + say("Watching off."); + return; + } + // arm() decides between events and the interval, and says which it got. + arm(); }); el.interval.addEventListener("change", function() { readForm(); + syncWatchNote(); schedule(); }); el.load.addEventListener("click", function() { load(true); }); @@ -807,17 +825,66 @@ window.SaveSource = (function() { }); } - // The poll starts on the first load from this source, and every load restarts - // the clock -- so a save loaded by hand is not re-fetched a moment later. + // Two triggers, one decision. When the machine that holds the save can push + // events, nothing is polled: `inotifywait` (or PowerShell's FileSystemWatcher + // on Windows) runs there and each name it prints wakes the same tick(). When + // it cannot -- no inotify-tools, or a CIFS/NFS mount, where inotify would + // never fire because the writes are not made through this kernel -- the + // interval is the trigger instead. Either way the decision is a listing + // comparison and a byte hash, so a missed or spurious event cannot reload the + // map wrongly. function arm() { - if (state.watch) { + if (!state.watch || !watchPossible()) { + stop(); + return; + } + var mode = (state.capabilities && state.capabilities.watch) || ""; + var key = state.transport + "|" + state.dir + "|" + mode; + if (!mode || key !== state.watchKey) { + startWatch(key, mode); + return; + } + if (!state.watchMode) { schedule(); } } - function schedule() { + function startWatch(key, mode) { stop(); - if (!state.watch || !watchPossible()) { + if (!mode || !state.dir) { + schedule(); + return; + } + invoke("source_watch_start", { + target: state.target, + dir: state.dir, + mode: mode, + local: state.transport === "local", + }).then(function(started) { + state.watchKey = key; + state.watchMode = started; + say("Watching " + state.dir + " \u2014 changes are pushed to the map as they land (" + + (started === "watcher" ? "FileSystemWatcher" : "inotifywait") + ")."); + }).catch(function(error) { + state.watchKey = key; + state.watchMode = ""; + if (el.watchNote) { + el.watchNote.textContent = "No event source there, so the folder is checked every " + + state.interval + "s."; + } + say("No event watcher on that machine (" + message(error) + ") \u2014 checking every " + + state.interval + "s instead."); + schedule(); + }); + } + + // The interval, used only while no event source is live. + function schedule() { + if (timer !== null) { + window.clearInterval(timer); + timer = null; + } + if (!state.watch || state.watchMode || !watchPossible()) { return; } timer = window.setInterval(tick, Math.max(5, state.interval) * 1000); @@ -828,6 +895,34 @@ window.SaveSource = (function() { window.clearInterval(timer); timer = null; } + if (burst !== null) { + window.clearTimeout(burst); + burst = null; + } + if (state.watchMode) { + state.watchMode = ""; + state.watchKey = ""; + invoke("source_watch_stop").catch(function() { /* nothing to stop */ }); + } + } + + // An event is a nudge, not a verdict: a save write arrives as a burst + // (create, several close_writes, a rename), so wait for the burst to settle + // and let one tick answer for all of it. + function onChanged(name) { + if (!state.watch) { + return; + } + if (name && !isSave(name)) { + return; // the folder also holds backups, screenshots and logs + } + if (burst !== null) { + window.clearTimeout(burst); + } + burst = window.setTimeout(function() { + burst = null; + tick(); + }, 1500); } return { diff --git a/rust_parser/tauri/src/main.rs b/rust_parser/tauri/src/main.rs index f47f9e1..2fe18d0 100644 --- a/rust_parser/tauri/src/main.rs +++ b/rust_parser/tauri/src/main.rs @@ -15,7 +15,7 @@ use sav_tauri_lib::session::AppSession; use sav_tauri_lib::ssh_source; use std::sync::Mutex; use tauri::ipc::{Channel, Response}; -use tauri::{Manager, State}; +use tauri::{Emitter, Manager, State}; use tauri_plugin_dialog::DialogExt; struct AppState { @@ -36,6 +36,11 @@ struct AppState { /// monotonic id; entries live until the app exits because committed /// pasteExternal ops replay from them on every undo, across save loads. clipboard_slots: Mutex<(u64, std::collections::HashMap)>, + /// The change watcher, when one is running: one long-lived process (an + /// `inotifywait -m`, local or over ssh, or a PowerShell FileSystemWatcher), + /// killed when watching stops or the target changes. Kept here rather than + /// in the frontend because a webview cannot hold a child process. + watch: Mutex>, } /// Payloads at most this big go back as one raw `Response` (the standing @@ -615,6 +620,49 @@ async fn source_fetch( .map_err(|e| format!("Fetch task failed: {e}"))? } +/// Start watching the folder and push a `save-source-changed` event per name +/// that lands in it. `mode` is what `source_validate` reported ("inotify" or +/// "watcher"); an error here is the frontend's cue to fall back to the interval +/// poll, so the message is the tool's own words (no `inotifywait` on that +/// machine, no such folder, a refused key). +#[tauri::command] +async fn source_watch_start( + target: ssh_source::SshTarget, + dir: String, + mode: String, + local: bool, + state: State<'_, AppState>, + app: tauri::AppHandle, +) -> Result { + stop_watch(&state); + let handle = tauri::async_runtime::spawn_blocking(move || { + ssh_source::spawn_watch(&target, &dir, local, &mode, move |name| { + // The webview decides whether the name matters; this is just the + // notification that something moved. + let _ = app.emit("save-source-changed", name); + }) + }) + .await + .map_err(|e| format!("Watch task failed: {e}"))??; + let mode = handle.mode.clone(); + *state.watch.lock().unwrap() = Some(handle.child); + Ok(mode) +} + +/// Stop watching. The remote `inotifywait` dies with the connection it was +/// started on. +#[tauri::command] +fn source_watch_stop(state: State<'_, AppState>) { + stop_watch(&state); +} + +fn stop_watch(state: &AppState) { + if let Some(mut child) = state.watch.lock().unwrap().take() { + let _ = child.kill(); + let _ = child.wait(); + } +} + /// Where the TOFU certificate pins live (see server_api::fetch_latest). fn cert_pin_path(app: &tauri::AppHandle) -> Result { Ok(app @@ -780,6 +828,7 @@ fn main() { session: Mutex::new(None), chunked_payload: Mutex::new((0, None)), clipboard_slots: Mutex::new((0, std::collections::HashMap::new())), + watch: Mutex::new(None), }) .invoke_handler(tauri::generate_handler![ load, @@ -803,6 +852,8 @@ fn main() { source_validate, source_browse, source_fetch, + source_watch_start, + source_watch_stop, server_forget_pin, server_password_store, server_password_get, diff --git a/rust_parser/tauri/src/ssh_source.rs b/rust_parser/tauri/src/ssh_source.rs index ab563d4..1483dd1 100644 --- a/rust_parser/tauri/src/ssh_source.rs +++ b/rust_parser/tauri/src/ssh_source.rs @@ -64,6 +64,9 @@ pub struct ValidateResult { pub sftp: bool, /// rsync on the REMOTE side: what makes rsync-over-ssh usable. pub rsync: bool, + /// How changes can be noticed: "inotify" or "watcher" when the far side can + /// push them, "" when only polling is possible. See `watch_mode`. + pub watch: String, /// How many `.sav` files are in `dir`, when the caller passed one. pub save_count: usize, pub newest_save: String, @@ -281,6 +284,15 @@ impl SshTarget { } } +/// Is this tool on PATH? `which` is not on a stock Windows box, so ask the +/// shell that is. +fn on_path(bin: &str) -> bool { + let probe = if cfg!(windows) { "where" } else { "which" }; + run(probe, &[bin.to_string()], None, Duration::from_secs(5)) + .map(|cmd| cmd.ok) + .unwrap_or(false) +} + fn first_line(text: &str) -> String { text.lines().next().unwrap_or("").trim().to_string() } @@ -542,6 +554,7 @@ pub fn validate(target: &SshTarget, dir: &str) -> ValidateResult { home: String::new(), sftp: false, rsync: false, + watch: String::new(), save_count: 0, newest_save: String::new(), detail: String::new(), @@ -574,6 +587,11 @@ pub fn validate(target: &SshTarget, dir: &str) -> ValidateResult { // carries the transfer. let cmd = run("ssh", &target.ssh_args("rsync --version"), None, PROBE_TIMEOUT); result.rsync = cmd.map(|c| c.ok).unwrap_or(false); + result.watch = if result.sftp { + watch_mode(target, &result.platform, false, dir).to_string() + } else { + String::new() + }; if !dir.trim().is_empty() && result.sftp { if let Ok(entries) = listing(target, dir) { let saves: Vec<&DirEntry> = entries.iter().filter(|e| is_save(&e.name)).collect(); @@ -773,6 +791,262 @@ fn hash_file(path: &std::path::Path) -> Result { Ok(format!("{:x}", hasher.finalize())) } +/// How changes can be noticed on the machine that holds the save. +/// +/// Events beat an interval whenever the filesystem can produce them, which is +/// not everywhere: `inotify` on a mounted CIFS/NFS share never fires, because +/// the kernel only reports writes made through this machine's own VFS -- the +/// game machine's writes land on the server's disk and nothing tells the client. +/// Windows is the exception that makes the mounted transport useful: its +/// `FileSystemWatcher` does receive SMB notifications, so a UNC path or a mapped +/// drive reports changes even though Linux could not. +pub fn watch_mode(target: &SshTarget, platform: &str, local: bool, dir: &str) -> &'static str { + if local { + if cfg!(windows) { + return "watcher"; + } + return if on_path("inotifywait") && is_local_filesystem(dir) { + "inotify" + } else { + "" + }; + } + if platform == "Windows" { + // FileSystemWatcher is part of .NET: nothing to install, nothing to probe. + return "watcher"; + } + if platform == "Linux/macOS" && !dir.trim().is_empty() { + let probe = run( + "ssh", + &target.ssh_args("command -v inotifywait"), + None, + PROBE_TIMEOUT, + ); + if probe.map(|c| c.ok).unwrap_or(false) { + return "inotify"; + } + } + "" +} + +/// Is this path on a filesystem whose writes we can actually see? `findmnt` +/// answers in one line; when it is missing, assume no -- a silent inotify watch +/// on a network mount is worse than an honest interval. +fn is_local_filesystem(path: &str) -> bool { + if path.trim().is_empty() || !std::path::Path::new(path).exists() { + return false; + } + let Ok(cmd) = run( + "findmnt", + &[ + "-no".to_string(), + "FSTYPE".to_string(), + "-T".to_string(), + path.to_string(), + ], + None, + Duration::from_secs(10), + ) else { + return false; + }; + if !cmd.ok { + return false; + } + let fstype = first_line(&cmd.stdout).to_ascii_lowercase(); + !(fstype.starts_with("nfs") + || fstype.starts_with("cifs") + || fstype.starts_with("smb") + || fstype.contains("fuse") + || fstype.starts_with("sshfs")) +} + +/// A running change watcher: the child to kill, and which mechanism it is. +pub struct WatchHandle { + pub child: std::process::Child, + pub mode: String, +} + +/// Start watching `dir` and call `on_change` with each name that lands in it. +/// +/// Two mechanisms, chosen by `mode`: +/// - "inotify": `inotifywait -m` on the machine that holds the folder, run +/// locally or over ssh, printing one name per event; +/// - "watcher": PowerShell's `FileSystemWatcher` for a Windows folder, sent as +/// a base64 `-EncodedCommand` -- the only quoting that survives cmd.exe, the +/// default shell of Windows OpenSSH. +/// The process is long-lived: the caller kills it when the watch is turned off. +pub fn spawn_watch( + target: &SshTarget, + dir: &str, + local: bool, + mode: &str, + on_change: F, +) -> Result +where + F: Fn(String) + Send + 'static, +{ + let remote = !local; + let (bin, args) = match mode { + "inotify" => { + if remote { + // The folder is embedded in a command the REMOTE SHELL parses, + // so a single quote in it would end the quoting; refuse rather + // than escape, because no real save folder has one. + if dir.contains('\'') { + return Err("That folder has a quote in it, so it cannot be watched.".to_string()); + } + target.check()?; + let script = format!( + "inotifywait -m -q -e close_write -e moved_to -e create --format %f -- '{dir}'" + ); + ("ssh".to_string(), target.ssh_args(&script)) + } else { + let mut args: Vec = ["-m", "-q", "-e", "close_write", "-e", "moved_to", "-e", "create", + "--format", "%f", "--"] + .iter() + .map(|s| s.to_string()) + .collect(); + args.push(dir.to_string()); + ("inotifywait".to_string(), args) + } + } + "watcher" => { + let command = powershell_watch_command(dir)?; + if remote { + target.check()?; + let mut args = target.opts(); + if target.port != 0 && target.port != 22 { + args.push("-p".to_string()); + args.push(target.port.to_string()); + } + args.push(target.destination()); + args.extend(command); + ("ssh".to_string(), args) + } else { + ("powershell".to_string(), command) + } + } + other => return Err(format!("No event watcher for mode {other:?}.")), + }; + + let mut child = Command::new(&bin) + .args(&args) + .stdin(Stdio::null()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .map_err(|e| format!("Could not start {bin}: {e}"))?; + let mut out = child.stdout.take().expect("stdout piped"); + let mut err = child.stderr.take().expect("stderr piped"); + + // A watcher that dies at once is the interesting failure -- no inotifywait, + // no such folder, a refused key -- so say why instead of reporting success + // and then never firing. `inotifywait -m` otherwise runs until killed. + let deadline = Instant::now() + Duration::from_millis(700); + loop { + match child.try_wait() { + Ok(Some(_)) => { + let mut text = String::new(); + let _ = err.read_to_string(&mut text); + let mut out_text = String::new(); + let _ = out.read_to_string(&mut out_text); + let detail = if text.trim().is_empty() { + first_line(&out_text) + } else { + first_line(&text) + }; + return Err(if detail.is_empty() { + format!("The watcher stopped immediately ({bin}).") + } else { + detail + }); + } + Ok(None) => { + if Instant::now() >= deadline { + break; + } + std::thread::sleep(Duration::from_millis(50)); + } + Err(e) => return Err(format!("Could not watch {dir}: {e}")), + } + } + + std::thread::spawn(move || { + use std::io::BufRead; + let reader = std::io::BufReader::new(out); + for line in reader.lines().map_while(Result::ok) { + let name = line.trim().to_string(); + if !name.is_empty() { + on_change(name); + } + } + }); + // Drain stderr too, or a chatty watcher fills the pipe and blocks. + std::thread::spawn(move || { + let mut sink = Vec::new(); + let _ = err.read_to_end(&mut sink); + }); + + Ok(WatchHandle { + child, + mode: mode.to_string(), + }) +} + +/// `powershell ... -EncodedCommand `: the script is +/// UTF-16LE base64, so no quoting in it can be reinterpreted by cmd.exe. +pub fn powershell_watch_command(dir: &str) -> Result, String> { + let folder = windows_path(dir)?; + let script = format!( + "$w = New-Object System.IO.FileSystemWatcher '{folder}', '*.sav'; \ +$w.IncludeSubdirectories = $false; $w.EnableRaisingEvents = $true; \ +while ($true) {{ $e = $w.WaitForChanged('All', 60000); \ +if (-not $e.TimedOut) {{ [Console]::Out.WriteLine($e.Name); [Console]::Out.Flush() }} }}" + ); + Ok(vec![ + "-NoProfile".to_string(), + "-NonInteractive".to_string(), + "-EncodedCommand".to_string(), + base64_utf16le(&script), + ]) +} + +/// SFTP reports a Windows folder as `/C:/Users/x`; PowerShell needs `C:\Users\x`. +/// A quote would end the single-quoted PowerShell literal, so it is refused. +fn windows_path(dir: &str) -> Result { + if dir.contains('\'') || dir.chars().any(|c| c.is_control()) { + return Err("That folder cannot be watched: it has a quote or a control character.".to_string()); + } + let trimmed = dir.trim().trim_start_matches('/'); + let bytes = trimmed.as_bytes(); + let drive = bytes.len() >= 2 && bytes[1] == b':' && (bytes[0] as char).is_ascii_alphabetic(); + if !drive { + return Err(format!("{dir} is not a Windows drive path.")); + } + Ok(trimmed.replace('/', "\\")) +} + +/// UTF-16LE (what PowerShell's -EncodedCommand wants), base64'd. Written out +/// rather than pulling in a crate for the one encoding. +pub fn base64_utf16le(text: &str) -> String { + let mut bytes = Vec::with_capacity(text.len() * 2); + for unit in text.encode_utf16() { + bytes.push((unit & 0xff) as u8); + bytes.push((unit >> 8) as u8); + } + const ALPHABET: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + let mut out = String::with_capacity(bytes.len().div_ceil(3) * 4); + for chunk in bytes.chunks(3) { + let b = [chunk[0], *chunk.get(1).unwrap_or(&0), *chunk.get(2).unwrap_or(&0)]; + let n = ((b[0] as u32) << 16) | ((b[1] as u32) << 8) | b[2] as u32; + out.push(ALPHABET[(n >> 18) as usize & 63] as char); + out.push(ALPHABET[(n >> 12) as usize & 63] as char); + out.push(if chunk.len() > 1 { ALPHABET[(n >> 6) as usize & 63] as char } else { '=' }); + out.push(if chunk.len() > 2 { ALPHABET[n as usize & 63] as char } else { '=' }); + } + out +} + #[cfg(test)] mod tests { use super::*; @@ -891,6 +1165,44 @@ drwxr-xr-x ? ? 0 Oct 10 13:41 /C:/saves/76561198036921 assert_eq!(platform_from_home("/home/dion"), "Linux/macOS"); } + #[test] + fn base64_matches_utf16le_powershell_encoding() { + // "AB" in UTF-16LE is 41 00 42 00 -> "QQBCAA==", the shape + // powershell -EncodedCommand expects (verified against PowerShell's own + // output for the same string). + assert_eq!(base64_utf16le("AB"), "QQBCAA=="); + assert_eq!(base64_utf16le("A"), "QQA="); + assert_eq!(base64_utf16le("ABC"), "QQBCAEMA"); + assert_eq!(base64_utf16le(""), ""); + } + + #[test] + fn powershell_watch_script_carries_the_folder_and_stays_unquotable() { + let args = powershell_watch_command("/C:/Users/dion/SaveGames").unwrap(); + assert_eq!(args[0], "-NoProfile"); + assert_eq!(args[2], "-EncodedCommand"); + assert!(args[3].chars().all(|c| c.is_ascii_alphanumeric() || c == '+' || c == '/' || c == '=')); + // The path is in the script as a Windows path, not as an SFTP one. + let decoded = args[3].clone(); + assert!(!decoded.contains('\''), "nothing in the payload can be requoted"); + // A path that is not a drive path, or carries a quote, is refused rather + // than escaped into a command string. + assert!(powershell_watch_command("/home/dion/saves").is_err()); + assert!(powershell_watch_command("/C:/Users/o'brien/saves").is_err()); + } + + #[test] + fn a_folder_with_a_quote_is_refused_by_the_shell_watcher() { + let target = SshTarget { host: "192.168.1.50".to_string(), ..Default::default() }; + let called = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)); + let flag = called.clone(); + let result = spawn_watch(&target, "/saves/o'brien", false, "inotify", move |_| { + flag.store(true, std::sync::atomic::Ordering::SeqCst); + }); + assert!(result.is_err(), "a quote must not reach the remote shell"); + assert!(!called.load(std::sync::atomic::Ordering::SeqCst)); + } + #[test] fn injection_through_the_batch_script_is_refused() { assert!(check_remote_path("/C:/saves\nrm -rf /").is_err()); diff --git a/tools/serve_save_source_demo.py b/tools/serve_save_source_demo.py index a066c53..1a1218a 100644 --- a/tools/serve_save_source_demo.py +++ b/tools/serve_save_source_demo.py @@ -13,7 +13,9 @@ Loading is where the demo stops: the parser lives in sav_core (desktop build) or in dist/pkg (wasm build) and this server has neither, so the dialog's status line says so instead of pretending. Validate against a host containing "fail" -to see the debug path. For the real thing see docs/remote-save-ssh.md. +to see the debug path, and call `__demoEmit("1.2_autosave_2.sav")` from the +console to see a change event reload the map (set `window.__demoFailWatch = true` +first to see the polling fallback). For the real thing see docs/remote-save-ssh.md. """ import argparse @@ -45,11 +47,21 @@ return listing().then(function (l) { var saves = l.entries.filter(function (e) { return !e.isDir && /\\.sav$/i.test(e.name); }); return { ok: true, platform: "demo", home: DIR, sftp: true, rsync: false, - saveCount: saves.length, newestSave: saves.length ? saves[0].name : "", + saveCount: saves.length, newestSave: saves.length ? saves[0].name : "", watch: "inotify", detail: "demo bridge: browsing " + DIR }; }); } if (cmd === "source_browse") { return listing(); } + if (cmd === "source_watch_start") { + // The demo has no inotifywait to run (this box has no inotify-tools), so + // it reports the event path as live and lets __demoEmit stand in for the + // kernel. Set __demoFailWatch to see the polling fallback instead. + if (window.__demoFailWatch) { + return Promise.reject(new Error("demo: no event watcher here")); + } + return Promise.resolve(args.mode || "inotify"); + } + if (cmd === "source_watch_stop") { return Promise.resolve(); } if (cmd === "source_fetch") { return listing().then(function (l) { var entry = l.entries.filter(function (e) { return e.path === args.remotePath; })[0]; @@ -63,9 +75,17 @@ } return Promise.reject(new Error("demo build: " + cmd + " is not stubbed")); } } }; + // A change event, as the Rust side would push it: __demoEmit("x.sav"). + var listeners = {}; + window.__TAURI__.event = { + listen: function (name, fn) { listeners[name] = fn; return Promise.resolve(function () { delete listeners[name]; }); } + }; + window.__demoEmit = function (name) { + if (listeners["save-source-changed"]) { listeners["save-source-changed"]({ payload: name }); } + }; document.addEventListener("DOMContentLoaded", function () { var note = document.createElement("div"); - note.textContent = "demo bridge - real folder, no parser: tools/serve_save_source_demo.py"; + note.textContent = "demo bridge - real folder, no parser, simulated change events: tools/serve_save_source_demo.py"; note.style.cssText = "position:fixed;left:8px;bottom:8px;z-index:9999;font:11px system-ui;" + "color:#ffd479;background:rgba(20,20,25,.85);border:1px solid #6a5a2a;border-radius:6px;padding:4px 8px"; document.body.appendChild(note); From a0c5f502790b3b5008788cf08ae885d8c2ff4755 Mon Sep 17 00:00:00 2001 From: DionJones615 <27814889+DionJones615@users.noreply.github.com> Date: Sat, 10 Oct 2026 15:56:02 -0400 Subject: [PATCH 5/9] Land in the saves, and correct the ssh-config claim Checked against the real machine (bazzite@172.27.30.50, Bazzite, 1ms away): validate, browse, fetch over sftp and rsync, and the change check all work on 166 real saves; rsync is there, so re-fetches are deltas. Two things came out of it. The game's layout is //*.sav, and the level above it holds that one folder plus the dedicated server's 116-byte ServerManager_V2.sav -- so "newest .sav" there picked a file that is not a save. When the single folder beside the saves is the most recently written thing, the browser now walks into it once: the dialog opens on the saves instead of one click above them. Up still goes back, and it does not re-descend. And a correction: the "Bad owner or permissions on /etc/ssh/ssh_config.d/..." note added earlier blamed an ostree ownership bug on the user's install. It is not that -- those files are root-owned, and inside a user namespace root maps to an unmapped uid, so they look like nfsnobody to the ssh client. The docs now say what it actually is and what to do (run outside the namespace, keep your uid, or `ssh -F /dev/null`), instead of telling people to chown a healthy system file. tools/serve_save_source_demo.py answers a listing for the folder the dialog asks for, inside the folder it was pointed at, so browsing a real tree -- down, up, and the walk-into-the-only-folder above -- can be seen locally. --- docs/remote-save-ssh.md | 30 +++++++++++++++--------------- map/static/map/save_source.js | 27 +++++++++++++++++++++++---- tools/serve_save_source_demo.py | 20 +++++++++++++++----- 3 files changed, 53 insertions(+), 24 deletions(-) diff --git a/docs/remote-save-ssh.md b/docs/remote-save-ssh.md index 789447c..2684529 100644 --- a/docs/remote-save-ssh.md +++ b/docs/remote-save-ssh.md @@ -55,8 +55,12 @@ icacls $env:USERPROFILE\.ssh\authorized_keys /inheritance:r /grant "$($env:USERN The saves are at `C:\Users\\AppData\Local\FactoryGame\Saved\SaveGames\\`, which is why the dialog opens on the SFTP form of that path: `/C:/Users/...`. On -Linux the game writes into the Proton prefix — the dialog's suggested path is -the usual one. +Linux the game writes into the Proton prefix; checked on Bazzite, that is +`~/.steam/steam/steamapps/compatdata/526870/pfx/drive_c/users/steamuser/AppData/Local/FactoryGame/Saved/SaveGames//`. +The `` level is the game's own layout, so the dialog opens the folder +above it and walks into the only folder when that folder is the most recently +written thing — otherwise "newest `.sav`" there would pick the dedicated +server's 116-byte `ServerManager_V2.sav`, which is not a save. An admin password is never asked for and never stored: the dialog sets `BatchMode=yes`, so authentication is key/agent only by design. A host whose @@ -135,20 +139,16 @@ cargo tauri dev # or: cargo tauri build plus the sshd setup above -- and Windows is where the game machine is, so this is the path that ends in a working map. -### If SSH is already broken on the machine running the app +### "Bad owner or permissions on /etc/ssh/ssh_config.d/..." -The dialog reports the ssh client's own words, and one of them is worth knowing -about: on an ostree/Bluefin-style install, files under `/etc/ssh/ssh_config.d/` -can end up owned by an unmapped uid (`nfsnobody`). OpenSSH treats a non-root -owned included config as fatal, so **every** `ssh` invocation fails with: - -``` -Bad owner or permissions on /etc/ssh/ssh_config.d/20-systemd-ssh-proxy.conf -``` - -That is not this app's bug and it breaks `ssh` in a terminal too; fix the -ownership (`sudo chown root:root /etc/ssh/ssh_config.d/*`) and Validate -connection starts answering. +OpenSSH refuses to read a config file it does not consider root-owned, and +inside a **user namespace** the host's root-owned files map to an unmapped uid, +so they look like `nfsnobody` to the client. Every `ssh` invocation then fails +before it connects, and the dialog shows exactly that line. It is the sandbox, +not the machine: run the app (or `ssh`) outside it, or use a container that keeps +your uid — `distrobox` does by default, `podman run --userns=keep-id` says so +explicitly. `ssh -F /dev/null` also gets past it, by not reading the system +config at all. ## Implementation notes diff --git a/map/static/map/save_source.js b/map/static/map/save_source.js index f06491d..9febd09 100644 --- a/map/static/map/save_source.js +++ b/map/static/map/save_source.js @@ -44,6 +44,7 @@ window.SaveSource = (function() { watch: false, interval: 60, watchMode: "", // "inotify" | "watcher" while events are live, "" while polling + descended: false, // the folder-with-one-subfolder shortcut has been taken watchKey: "", // target+dir the running watcher belongs to step: 1, // 1 protocol, 2 connection, 3 save file reached: 1, // the furthest step visited, so the stepper can go back @@ -204,6 +205,7 @@ window.SaveSource = (function() { // Continue where the last session stopped: a remembered folder means the // protocol and the connection are already answered. showStep(state.dir ? 3 : 1); + state.descended = false; if (state.dir) { browse(state.dir); } @@ -657,11 +659,28 @@ window.SaveSource = (function() { }); el.list.appendChild(row); }); + var saves = state.entries.filter(function(entry) { + return !entry.isDir && isSave(entry.name); + }); + var folders = state.entries.filter(function(entry) { return entry.isDir; }); + // The game's own layout is //*.sav, and the level above + // it holds that one folder plus the dedicated server's own 116-byte + // ServerManager file -- so "newest .sav" there picks a file that is not a + // save. When the single folder beside them is the most recently written + // thing, the saves are in it: walk in once, the way a person would. + var newestSave = saves.reduce(function(latest, entry) { + return Math.max(latest, entry.mtime || 0); + }, 0); + var savesAreInside = !quiet && !state.descended && folders.length === 1 + && (saves.length === 0 || (folders[0].mtime || 0) > newestSave); + if (savesAreInside) { + state.descended = true; + browse(folders[0].path); + return; + } + var saveCount = saves.length; if (!quiet) { - var count = state.entries.filter(function(entry) { - return !entry.isDir && isSave(entry.name); - }).length; - say(count + " .sav file" + (count === 1 ? "" : "s") + " in " + listing.path + "."); + say(saveCount + " .sav file" + (saveCount === 1 ? "" : "s") + " in " + listing.path + "."); } if (state.file && !el.newest.checked) { // The picked file may be gone; the folder listing is the truth. diff --git a/tools/serve_save_source_demo.py b/tools/serve_save_source_demo.py index 1a1218a..7753565 100644 --- a/tools/serve_save_source_demo.py +++ b/tools/serve_save_source_demo.py @@ -23,18 +23,23 @@ import json import os import sys +import urllib.parse REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) STATIC = os.path.join(REPO, "map", "static", "map") # Injected before the app scripts: window.__TAURI__ has to exist by the time # save_client.js reads it, or the app takes the browser transport instead. -STUB = """

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 diff --git a/docs/remote-save-ssh.md b/docs/remote-save-ssh.md index 679a1a8..4853799 100644 --- a/docs/remote-save-ssh.md +++ b/docs/remote-save-ssh.md @@ -6,12 +6,30 @@ has — **its OpenSSH server** — rather than by asking it to host the file: nothing listens, no port is opened for the app, and the authentication is the key and `~/.ssh/config` the user already has. -Two transports, in one dialog (**Save File → From another machine**): - -| Transport | Needs on the game machine | Gives | -|---|---|---| -| **SSH / SFTP** | OpenSSH server (built into Windows 10/11 and every Linux) | folder browsing, a cheap change check, rsync when it is installed | -| **Mounted share** | SMB/NFS/GVFS share mounted by the OS | the same browsing and change check, no protocol code at all | +## The dialog: three steps, one decision each + +**Your save → From another machine.** + +![The dialog](remote-save-ssh-dialog.png) + +1. **Protocol** — two choices, each explained in a line: + | Protocol | Needs on the game machine | Gives | + |---|---|---| + | **SSH / SFTP** | OpenSSH server (built into Windows 10/11 and every Linux) | folder browsing, a cheap change check, rsync when it is installed | + | **Mounted share** | SMB/NFS/GVFS share mounted by the OS | the same browsing and change check, no protocol code at all | +2. **Connection** — the answers that protocol needs, then *Validate connection*: + it reports the login, whether the SFTP subsystem answers (browsing and the + change check depend on it), and whether the far side has rsync. A failure + shows the ssh client's own words and the one thing to try next — a refused + key, an unknown host key, a port nothing answers on, a machine whose own + `ssh` is broken, a server with no SFTP subsystem. +3. **Save to load** — the folder, walked like a file dialog (folders first, + `.sav` marked, `Up` for the parent), then the file. *Newest `.sav`* follows + the autosave rotation; *Keep it fresh* re-lists the folder and reloads the + map only when the fetched bytes actually changed. + +The stepper's numbers go back to a step already reached, and a remembered +source reopens straight at the file it was left on. ## Setting up the game machine (Windows) @@ -46,24 +64,12 @@ key is not in `known_hosts` is refused until **Trust this host's key the first time** is ticked, which adds it once (trust on first use, the same disclosure as the dedicated-server certificate pin). A *changed* key is still refused. -## What the dialog does - -- **Validate connection** answers what the transport can actually do before a - path is typed: SSH login, whether the SFTP subsystem answers (browsing and - change detection depend on it), whether the far side has rsync, the platform - and home directory, and how many `.sav` files are in the folder. A partial - answer stays partial — a server with no SFTP subsystem is reported as such - rather than as a failed connection. -- **Save folder** lists the remote directory and walks it (`Up`, folders first, - `.sav` files marked). Remote names are rendered as text, never as markup. - With SFTP unavailable the listing is disabled and the path is typed by hand. -- **Always take the newest `.sav`** is the autosave case: the rotation writes a - new file every few minutes and the map should follow it. -- **Watch it and reload** polls the folder's name/size/timestamp and reloads - only when the bytes actually changed. While the save is being watched the - status line says what each tick saw. Reloading is refused while the editor - holds pending edits (a reload discards them), while a parse is already - running, and while the window is hidden — polling resumes on its own. +## While it is watching + +The status line says what each tick saw. Reloading is refused while the editor +holds pending edits (a reload discards them), while a parse is already running, +and while the window is hidden — polling resumes on its own. Remote names are +rendered as text, never as markup. A fetched save lands in the app's data directory under `remote-saves/`, written to a `.part` file and renamed only when complete, and capped at 8 GiB, so a @@ -76,7 +82,7 @@ the parser reads. ```sh python3 tools/serve_save_source_demo.py --dir /path/to/SaveGames -# then open http://127.0.0.1:8793/ and click Save File -> From another machine +# then open http://127.0.0.1:8793/ and click Your save -> From another machine ``` That serves `map/static/map/` with a stubbed desktop bridge: the three commands diff --git a/docs/server-fetch.md b/docs/server-fetch.md index 0bf7c23..472e9e7 100644 --- a/docs/server-fetch.md +++ b/docs/server-fetch.md @@ -9,7 +9,7 @@ server install. Nothing about the game was reverse-engineered. ## Using it -In the Save File panel, expand **From dedicated server** and enter: +In the sidebar, expand **From dedicated server** and enter: - **Server address** — a bare host or IP means the default port 7777; `host:port` overrides it (bracketed IPv6 like `[::1]:7777` works too; diff --git a/map/static/map/data.js b/map/static/map/data.js index 39b7456..81c5103 100644 --- a/map/static/map/data.js +++ b/map/static/map/data.js @@ -185,7 +185,7 @@ clearSaveBtn.style.display = "flex"; } - // "Unload" (the eject button next to the Save File header): drop the + // "Unload" (the eject button next to the panel header): drop the // loaded save entirely -- map, sidebar, editor state, and the parse // session's memory (SaveClient.reset terminates the wasm worker; native // side frees its session). Pending edits die with the session, so those diff --git a/map/static/map/index.html b/map/static/map/index.html index c1b5c55..7e0a13b 100644 --- a/map/static/map/index.html +++ b/map/static/map/index.html @@ -167,7 +167,7 @@

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 literal 0 HcmV?d00001 diff --git a/docs/remote-save-ssh.md b/docs/remote-save-ssh.md new file mode 100644 index 0000000..0c87180 --- /dev/null +++ b/docs/remote-save-ssh.md @@ -0,0 +1,85 @@ +# Load the save off the machine that runs the game (desktop app) + +The desktop app can load the `.sav` straight off the gaming PC and keep +reloading it as the game autosaves. It does that with what that machine already +has — **its OpenSSH server** — rather than by asking it to host the file: +nothing listens, no port is opened for the app, and the authentication is the +key and `~/.ssh/config` the user already has. + +Two transports, in one dialog (**Save File → From another machine**): + +| Transport | Needs on the game machine | Gives | +|---|---|---| +| **SSH / SFTP** | OpenSSH server (built into Windows 10/11 and every Linux) | folder browsing, a cheap change check, rsync when it is installed | +| **Mounted share** | SMB/NFS/GVFS share mounted by the OS | the same browsing and change check, no protocol code at all | + +## Setting up the game machine (Windows) + +Run these in an **elevated PowerShell**. The save folder comes with the server +capability; nothing else is installed. + +```powershell +Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 +Set-Service -Name sshd -StartupType Automatic +Start-Service sshd +New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True ` + -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 +``` + +Then, as the account that owns the saves (add your own public key): + +```powershell +mkdir -Force $env:USERPROFILE\.ssh | Out-Null +Add-Content $env:USERPROFILE\.ssh\authorized_keys 'ssh-ed25519 AAAA... you@laptop' +icacls $env:USERPROFILE\.ssh\authorized_keys /inheritance:r /grant "$($env:USERNAME):R" +``` + +The saves are at +`C:\Users\\AppData\Local\FactoryGame\Saved\SaveGames\\`, which +is why the dialog opens on the SFTP form of that path: `/C:/Users/...`. On +Linux the game writes into the Proton prefix — the dialog's suggested path is +the usual one. + +An admin password is never asked for and never stored: the dialog sets +`BatchMode=yes`, so authentication is key/agent only by design. A host whose +key is not in `known_hosts` is refused until **Trust this host's key the first +time** is ticked, which adds it once (trust on first use, the same disclosure as +the dedicated-server certificate pin). A *changed* key is still refused. + +## What the dialog does + +- **Validate connection** answers what the transport can actually do before a + path is typed: SSH login, whether the SFTP subsystem answers (browsing and + change detection depend on it), whether the far side has rsync, the platform + and home directory, and how many `.sav` files are in the folder. A partial + answer stays partial — a server with no SFTP subsystem is reported as such + rather than as a failed connection. +- **Save folder** lists the remote directory and walks it (`Up`, folders first, + `.sav` files marked). Remote names are rendered as text, never as markup. + With SFTP unavailable the listing is disabled and the path is typed by hand. +- **Always take the newest `.sav`** is the autosave case: the rotation writes a + new file every few minutes and the map should follow it. +- **Watch it and reload** polls the folder's name/size/timestamp and reloads + only when the bytes actually changed. While the save is being watched the + status line says what each tick saw. Reloading is refused while the editor + holds pending edits (a reload discards them), while a parse is already + running, and while the window is hidden — polling resumes on its own. + +A fetched save lands in the app's data directory under `remote-saves/`, written +to a `.part` file and renamed only when complete, and capped at 8 GiB, so a +wrong path cannot fill the disk and a truncated transfer cannot become the file +the parser reads. + +## Implementation notes + +- `map/static/map/save_source.js` — the dialog, the browser and the watch loop. +- `rust_parser/tauri/src/ssh_source.rs` — runs `ssh`, `sftp` and `rsync` as + subprocesses with a deadline, parses their output, and hashes what arrives. + The app ships no SSH stack: host keys, keys, agents and `ProxyJump` are + OpenSSH's, so the app never grows a second implementation of any of it. +- Commands: `source_validate`, `source_browse`, `source_fetch` -- the three + jobs the dialog has. The watch probe is a `source_browse`, because a listing + is what says both what is in the folder and whether it moved. Every remote + path crosses into an SFTP batch script, so control characters and quotes are + rejected at the boundary; a host, user or port that could be read as an + option is rejected too. diff --git a/map/static/map/data.js b/map/static/map/data.js index 0f0d780..39b7456 100644 --- a/map/static/map/data.js +++ b/map/static/map/data.js @@ -642,6 +642,16 @@ // handlers below. if (isTauri) { setupServerFetch(); + // The save on another machine (save_source.js). It owns its own dialog + // and watch loop; all it needs from here is the path loader and the two + // questions the watch loop must ask before reloading the map. + SaveSource.init({ + options: { + loadPath: loadLocalPath, + isBusy: function() { return loadInFlight; }, + pendingEdits: function() { return EditorTool.opCount(); }, + }, + }); } if (isTauri && window.__TAURI__.event) { window.__TAURI__.event.listen("tauri://drag-drop", function(e) { diff --git a/map/static/map/index.html b/map/static/map/index.html index 2405e99..c1b5c55 100644 --- a/map/static/map/index.html +++ b/map/static/map/index.html @@ -229,6 +229,12 @@ Drop a .sav here or click to browse + + +