Files
DorkNet/launcher/ui/index.html
T
Alexa df9dac053d launcher: v0.1 — PhotinoNET shell + multi-version orchestration
Single-download .NET 9 self-contained launcher for hosting / joining
DorkNet servers. Reads versions.json from main to discover supported
client builds, fetches the matching server binary + client patcher
from GitHub Releases per branch, manages the server subprocess +
Cloudflare quick-tunnel, and wraps it all in a PhotinoNET window.

Code layout:
- Program.cs           PhotinoNET window + message bridge bootstrap
- Backend/             AppPaths, AppState, VersionsManifest,
                       ReleaseDownloader, ServerProcess, ClientPatcher,
                       Tunnel, RecRoomPicker, JoinCode, MessageBridge
- ui/                  index.html + style.css + app.js (no build step)
- RELEASES.md          GitHub Releases artifact contract per-version
                       branches must publish to

Per-version branches need to ship two release assets per tag:
- dorknet-server-{version_key}-win-x64.zip
- dorknet-clientpatch-{version_key}.zip
(see launcher/RELEASES.md for the full naming + arg contract)

Photon AppIds, JWT secret, and the picked Rec Room path stay
per-machine; the launcher never bundles them.
2026-05-26 20:54:16 +03:00

150 lines
5.4 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>DorkNet</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<main id="app">
<!-- First-run wizard. Hidden once state.mode flips to host or join. -->
<section data-view="first-run" hidden>
<header>
<div class="logo">DorkNet</div>
<p class="tagline">Self-hostable 2020 Rec Room backend</p>
</header>
<div class="card-row">
<button class="card" data-mode-pick="host">
<span class="card-emoji">🛠️</span>
<span class="card-title">Host a server</span>
<span class="card-body">Run a server for you and your friends. Picks a Rec Room version, downloads the matching server, opens a tunnel, shares a join code.</span>
</button>
<button class="card" data-mode-pick="join">
<span class="card-emoji">🎮</span>
<span class="card-title">Join a friend</span>
<span class="card-body">Paste a join code, point at your Rec Room install. The launcher fetches the matching patcher.</span>
</button>
</div>
<p class="footnote">You can switch modes later under Settings.</p>
</section>
<!-- Host view: pick version → server downloads → tunnel + patcher → share code. -->
<section data-view="host" hidden>
<nav class="topbar">
<span class="topbar-title">Host</span>
<button class="link" data-action="open-settings">Settings</button>
</nav>
<div class="row">
<label>Rec Room install</label>
<div class="path-row">
<code id="recroom-path-display">(not picked)</code>
<button data-action="pick-recroom">Pick…</button>
</div>
</div>
<div class="row">
<label for="server-name">Server name (shown to joiners)</label>
<input id="server-name" type="text" placeholder="e.g. Saturday Hangout" />
</div>
<div class="row">
<label for="version-select">Rec Room version to host for</label>
<select id="version-select"></select>
</div>
<div class="row" id="photon-config">
<label>Photon AppIds (free at <a href="https://dashboard.photonengine.com" target="_blank">dashboard.photonengine.com</a>)</label>
<input id="photon-app-id" type="text" placeholder="Realtime AppId (UUID)" />
<input id="photon-voice-app-id" type="text" placeholder="Voice AppId (UUID, optional)" />
<select id="photon-region">
<option value="us">US</option>
<option value="eu">EU</option>
<option value="asia">Asia</option>
<option value="jp">Japan</option>
<option value="sa">South America</option>
<option value="kr">Korea</option>
<option value="in">India</option>
<option value="au">Australia</option>
</select>
</div>
<div class="actions">
<button id="host-start" class="primary">Start hosting</button>
<button id="host-stop" class="secondary" hidden>Stop</button>
</div>
<div id="host-status" class="status"></div>
<div id="join-code-row" class="row" hidden>
<label>Join code (share this)</label>
<div class="join-code-display">
<code id="join-code-value"></code>
<button data-action="copy-join-code">Copy</button>
</div>
<small>Joiners paste this into their DorkNet launcher's Join screen.</small>
</div>
</section>
<!-- Join view: paste code → patcher downloads + installs → launch Rec Room. -->
<section data-view="join" hidden>
<nav class="topbar">
<span class="topbar-title">Join</span>
<button class="link" data-action="open-settings">Settings</button>
</nav>
<div class="row">
<label for="join-code-input">Paste the join code your host shared</label>
<textarea id="join-code-input" rows="3" placeholder="A long base64-looking string"></textarea>
<button data-action="decode-join-code">Preview</button>
</div>
<div id="join-preview" class="status" hidden></div>
<div class="row">
<label>Rec Room install</label>
<div class="path-row">
<code id="recroom-path-display-join">(not picked)</code>
<button data-action="pick-recroom">Pick…</button>
</div>
</div>
<div class="actions">
<button id="join-apply" class="primary" disabled>Patch and launch</button>
</div>
<div id="join-status" class="status"></div>
</section>
<!-- Settings drawer (overlay). -->
<section data-view="settings" hidden>
<nav class="topbar">
<span class="topbar-title">Settings</span>
<button class="link" data-action="back-from-settings">← back</button>
</nav>
<div class="row">
<label>Mode</label>
<button data-mode-pick="host">Switch to Host</button>
<button data-mode-pick="join">Switch to Join</button>
</div>
<div class="row">
<label>Cache location</label>
<small id="cache-paths"></small>
</div>
<div class="row">
<label>About</label>
<small>DorkNet Launcher v0.1 — <a href="https://github.com/DorkSquadRR/DorkNet" target="_blank">GitHub</a> — AGPL-3.0</small>
</div>
</section>
<!-- Toast container for transient errors / progress flashes. -->
<div id="toasts"></div>
</main>
<script src="app.js"></script>
</body>
</html>