Two launcher behaviors vPOD only simulated are now available for real,
matching the pod exactly:
- "Actually set system volume": set_VolumeLevel drives this machine's
master volume through the launcher's own chain — nircmd.exe in the
games root, else Core Audio (Vista+), else winmm. The chain moved out
of TeslaLauncher.cs into Launcher/VolumeControl.cs and is compiled
into both apps as linked source (the MiniZip pattern); launcher
behavior is unchanged. Off by default: the value is stored/echoed
only, as before.
- pre-uninstall.bat now runs before the product directory is deleted on
UninstallApp (working dir, hidden window, 120 s wait, exit code
logged — mirrors CleanupProductDirectory). Gated behind the renamed
"Run package install/uninstall scripts" checkbox (was "Run
postinstall.bat after install"; RunPostInstall -> RunPackageScripts),
closing the asymmetry where install scripts had an opt-in but
uninstall scripts silently never ran.
Verified: 106/106 diff tests; live master-volume set/restore through
vPOD's build of VolumeControl; functional probe of UninstallApp against
an isolated games root with the flag off (script skipped, dir removed)
and on (script ran, then dir removed).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Launcher's XP11 port (8730b9b) now extends to everything: one net40
flavor across Console, vPOD, Contract, and SecureConfig (Newtonsoft.Json
everywhere; the net48/System.Text.Json legs and their #if splits are gone
since nothing consumed them).
Console (net40, single TFM like the Launcher):
- The ~31 BinaryFormatter bitmap blobs in the .resx files became raw
embedded files under assets/icons/ (extracted byte-faithfully via a
serialization surrogate — the animated square_throbber.gif survives),
loaded by Properties.Resources.EmbeddedBitmap/EmbeddedIcon. Reason:
System.Resources.Extensions' DeserializingResourceReader is net461+
and cannot load on net40. Strings stay in the .resx.
- IReadOnlyList -> IList in AppRegistry (net45+ interface).
vPOD (net40, single TFM):
- Zip extraction now shares the Launcher's MiniZip.cs (linked source), so
the diff-test install round-trip exercises it against ZipArchive zips.
- RPC args as JTokens; LaunchApps.json persistence via Newtonsoft;
Thread.VolatileRead instead of Volatile.Read.
Contract/SecureConfig: net40-only; Client/** (PodManagerConnection) now
ships in the one build. The Launcher package gains
TeslaSecureConfiguration.dll as a dependency of the client half.
Tests: the net48 xunit host loads the net40 assemblies (both CLR4), so
the suite exercises exactly what ships — 106/106 green. Also verified
live: net40 console provisioned, managed, and ran a full RP mission
against net40 vPOD (beacon/passphrase/RSA, 53290 RPC, egg load,
Run/Stop Mission).
Version: 4.11.4.3 across Launcher, Console, and vPOD (vPOD joins the
suite version line; was 1.0.0). Ship the dotNetFx40 redistributable in
Launcher/assets for XP-era pods.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Adopt the launch-key convention (documented in the Apps.xml header):
fresh Guid = product id, first Launch key reuses it, each extra entry
increments the last hex digit (wrapping F->0). Never a -1 suffix:
keys parse as System.Guid and silently collapse to Guid.Empty.
- Rewrite BT411 LC/MR + RIOJoy keys to the convention. RP4.11 LC/MR stay
pinned to the original console's hardcoded Guids (SiteManagement
constants + diff tests).
- Remove vPOD from the shipped catalog: dev tool, never a console-deployed
product (README documents the ad-hoc Add Product path instead).
- Add TeslaRel410 (DOSBox-X preservation pods): six entries, BT/RP 4.10 x
GameClient/LC/MR, all C:\Games\TeslaPod410\pod-launch.exe with mode
bt/rp. LC/MR boot identically (role assigned via egg hostType) and no
{res} token (output size fixed per rig at postinstall).
- CatalogTests: now 5 products / 14 entries; full diff suite 106/106.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two additions to the virtual launcher's real-process mode:
- Auto-restart watchdog. Replaces the poll-on-query PruneExitedProcesses
with a per-process watcher thread (StartWatcher): when a real-launched
app exits on its own -- not via a Kill*/Uninstall, which untrack it
first -- it is dropped from the running list and, if its LaunchData has
AutoRestart and the "Auto-restart after the app exits (watchdog)"
toggle is on, relaunched after the Agent's 2 s delay. A watchdog
generation counter cancels pending restarts when the pod goes dark
(power off / reboot / reprovision / WipeApps); the console's KillAllApps
leaves them pending, matching the real Agent's race.
- postinstall.bat toggle. A "Run postinstall.bat after install" checkbox
(above "Actually launch apps", off by default) makes an install execute
a packaged postinstall.bat via cmd /c (waited up to 5 min) before
deleting it, like the real service. Off, it is logged and removed unrun
as before -- it runs package script code on the host.
Both are opt-in from the vPOD window. Verified against the real
LauncherRpcServer over a loopback socket: the watchdog test relaunches an
exited ping.exe with a new PID and stops once toggled off; a crafted
package's postinstall.bat runs (and is removed) only when enabled. Full
differential suite 103/103.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- InstallProduct now extracts into the real C:\Games (the launcher's
GAMES_DIR) so deployed products land where their catalog launch entries
point; uninstall removes the real product folder. Tests pass an isolated
games root through the VirtualLauncher ctor.
- New "Actually launch apps (real processes)" toggle (off by default =
simulated PIDs): LaunchApp starts the entry's exe exactly like the Agent
(same start info, same registered-but-not-installed error), Kill*/
Uninstall/Wipe terminate the real processes (kill before folder delete),
and self-exited apps are pruned from GetLaunchedApps/FullUpdate. Real
processes die with the machine: power off, reboot, or closing vPOD. The
Agent's autoRestart watchdog is deliberately not emulated.
- Pod Power and Mimicking Game groups swapped (game left, power right).
- Provisioning round-trip test now skips as inconclusive when a running
TeslaConsole holds UDP 53291 instead of failing the suite; two new tests
cover real launch/kill (ping.exe) and the missing-exe error path.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
vPOD has outgrown its home inside the console's folder: it now emulates both
halves of a pod (Munga game client + TeslaLauncher service / provisioning),
so it lives at the repo root beside Console/, Launcher/, Contract/ and
SecureConfig/, like the peer it has become.
Accompanying changes: project references rebased (Contract, SecureConfig,
the console's vendored Munga Net.dll), solution + DiffTests reference paths,
the console csproj's now-obsolete vPOD source exclusion removed, and the
root README / Apps.xml / vPOD README path mentions updated. pack.ps1 is
self-relative and now emits vPOD/dist/vPOD.zip.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>