Localtunnel hosting + admin panel + AppData db

- Default hosting mode is now Localtunnel — public *.loca.lt URL,
  no account, auto-fetched on first run. Replaces the prototyped
  Tailscale mode.
- Tailscale code purged from launcher + CLI; docs swapped to
  Localtunnel throughout (easy-setup, joining-a-server, server-cli,
  troubleshooting, faq, READMEs).
- Launcher sidebar gains an Open admin panel button — opens
  https://admin.<apex> in the browser once the server is live.
- SQLite db moves to %APPDATA%\DorkNet\dorknet.db (server reads
  Database__SqlitePath env var, launcher passes it). Existing dbs
  under <serverDir>\data\ are migrated on first run.
- CLI Program.cs: --mode default flips from tailscale to localtunnel;
  csproj links in LocaltunnelTunnel + LocaltunnelInstaller.
- New Backend files: LauncherNameServer, LocaltunnelInstaller,
  LocaltunnelTunnel, SingleOriginServiceMap.
- .gitignore: exclude installer/out/.
This commit is contained in:
Alexa
2026-05-28 01:39:38 +03:00
parent 7852b410ee
commit f5ad4b59ef
30 changed files with 942 additions and 184 deletions
+27 -21
View File
@@ -12,7 +12,8 @@ your own machine and hand a join code to your friends. The launcher is a
single Windows app that:
- runs the server,
- opens a public tunnel so friends anywhere can connect,
- opens a Localtunnel HTTPS URL (or, in LAN mode, publishes your local
address) so friends can connect,
- patches your local copy of Rec Room to point at the server,
- packages a join code your friends paste into their launcher.
@@ -24,6 +25,10 @@ single Windows app that:
[Getting the 2020 client](#getting-the-2020-client) below.
- A free Photon Cloud account — the launcher walks you through this on
first run.
- No account needed for the default "friends anywhere" hosting mode —
the launcher uses [Localtunnel](https://localtunnel.github.io/www/)
to get a free, anonymous `*.loca.lt` URL for your server. Auto-fetched
by the launcher on first run; no sign-in.
- ~5 GB free disk space
- About 10 minutes for first-run setup, ~30 seconds per subsequent launch
@@ -102,12 +107,11 @@ when you continue.
- **Server name** — what shows up in your join code. Use whatever your
friends will recognise ("Adam's Sunday games", "DorkSquad Test", etc.).
- **Who can join?** — three options, only one shows extra inputs:
- **Friends anywhere · Tunnelto** *(default, recommended)* — the
launcher runs a Tunnelto tunnel that gives your server a public
`*.tunnelto.me` URL. Works for anyone, anywhere. No router config.
- **Tunnelto wildcard base** — advanced. If you've got a wildcard
Tunnelto subscription, paste the apex domain. Subdomains like
`api.<base>`, `auth.<base>`, etc. get auto-generated.
- **Friends anywhere · Localtunnel** *(default, recommended)* — the
launcher fetches the Localtunnel client (no account, no sign-in)
and gets you a public `https://<random-name>.loca.lt` URL. Friends
can join from anywhere with just the join code; nothing extra to
install on their side.
- **Same WiFi only · sslip.io** — bind on your LAN only. Friends must
be on the same network. No tunnel, lowest latency.
@@ -161,10 +165,10 @@ session, the new values get used the next time you hit Start hosting.
- **REC ROOM VERSION TO HOST FOR** — dropdown. Pre-selects the version
matching your install. Picking a different version means the launcher
will fetch that server build the next time you Start hosting.
- **WHO CAN JOIN?** — the same three options as step 3 of the wizard.
- **TUNNELTO BASE HOST** — only visible when you pick the wildcard
option. Auto-generated otherwise; not needed for the default or LAN
modes.
- **WHO CAN JOIN?** — same options as step 3 of the wizard. The
Localtunnel option auto-fetches the tunnel client on first use; no
account or sign-in required, and the URL is regenerated every host
session.
### Photon Cloud panel
@@ -191,8 +195,9 @@ The launcher runs through six steps in order:
1. **Download server** — fetches the matching server build into
`%LOCALAPPDATA%\DorkNet\servers\<version>\`. ~50 MB the first time;
reused on subsequent launches.
2. **Open tunnel** — starts Tunnelto and assigns a public hostname.
Skipped in LAN mode.
2. **Open tunnel** — fetches the Localtunnel client on first run, then
opens a tunnel and waits for the `https://<random>.loca.lt` URL.
LAN mode skips this step and just resolves your local WiFi IP.
3. **Start server** — boots the server process. SQLite database lives
in `%APPDATA%\DorkNet\dorknet.db`.
4. **Download patcher** — fetches the client-patcher payload that
@@ -275,13 +280,11 @@ See [joining-a-server.md](joining-a-server.md) for the join-side flow.
| Mode | Tunnel | Public URL | Best for |
| --- | --- | --- | --- |
| Friends anywhere · Tunnelto | yes | `dorknet-<random>.tunnelto.me` | Default — works for everyone, no setup |
| Tunnelto wildcard base | yes | `<your-apex>` + `api.<apex>`, `auth.<apex>`, … | Power users with a wildcard Tunnelto plan |
| Friends anywhere · Localtunnel | public HTTPS, anonymous | `https://<random>.loca.lt` | Default — friends connect from anywhere with just the join code |
| Same WiFi only · sslip.io | no | `<lan-ip>.sslip.io` | LAN games, lowest latency, no internet exposure |
Default mode is the right pick for >95% of cases. The wildcard mode is
only useful if you've already got a stable apex domain set up. LAN mode
is for when everyone's in the same room.
Default mode is the right pick for >95% of cases. LAN mode is for when
everyone's in the same room and you do not want a public URL.
---
@@ -308,9 +311,12 @@ See [troubleshooting.md](troubleshooting.md) for the full list.
The most common problems:
- **Server starts but friend can't connect** — Cloudflare Quick Tunnels
rotate the URL on every restart. Re-share the join code if you've
restarted hosting.
- **Server starts but friend can't connect** — Localtunnel hands you a
fresh `*.loca.lt` URL every host session, so the join code from your
previous run is stale. Hit Start hosting again, copy the new join
code, re-share. (Localtunnel sometimes also shows a one-time "Click
to Continue" interstitial in the browser the first time a joiner's
machine touches the URL; friends might need to open the URL once.)
- **"Photon CustomAuth 401" in the server log** — your Realtime AppId
on the server doesn't match what the launcher patched into the
client. Make sure both sides use the same AppIds.
+9 -4
View File
@@ -80,11 +80,16 @@ the server config; the client mod handles the rest.
### My friend can't connect
Most common causes, in order:
1. **Tunnel URL stale.** Cloudflare Quick Tunnels rotate the URL on each
restart. Re-share the join code.
1. **Stale join code.** Localtunnel hands out a fresh `*.loca.lt` URL
on every host restart. Hit Start hosting, copy the new join code
from the launcher, send the new code to your friend.
2. **Photon region mismatch.** Both clients must use the same Photon
region — set in Settings.
3. **Friend didn't patch.** They need to run the Patch tab pointed at
their own Rec Room install, with your join code.
3. **Friend didn't patch.** They need to open the Join view in their
launcher, paste your join code, and click APPLY PATCH before
launching Rec Room.
4. **Localtunnel interstitial.** First time a joiner's machine hits a
given `*.loca.lt` URL, Localtunnel may show a one-time "Click to
Continue" page. Open the URL once in any browser and retry.
4. **Junior account / accessibility settings.** Server settings → relax
moderation gates if friends are on accounts with parental controls.
+16 -5
View File
@@ -16,6 +16,11 @@ locally — nothing is sent anywhere until you actually launch the game.
[Getting the 2020 client](easy-setup.md#getting-the-2020-client)
- The join code your friend gave you (a base64-looking blob a few hundred
characters long)
- No accounts / installs needed for the default **Friends anywhere ·
Localtunnel** join: the host's `*.loca.lt` URL is baked into the join
code, you just paste it and play. The first time your machine hits a
given `*.loca.lt` URL, your browser may show a one-time "Click to
Continue" interstitial — open the URL once in any browser to clear it.
- About 2 minutes
You **don't** need a Photon account of your own. The join code carries
@@ -71,8 +76,8 @@ HOST SHARED** textbox. Hit **Preview** — the launcher decodes the code
and pops a "Server preview" panel showing:
- the server's display name,
- the public host (Tunnelto hostname, sslip.io address, or wildcard
apex),
- the host address (Localtunnel `*.loca.lt`, LAN `sslip.io`, or a custom
host),
- the version key (must match your install — the patcher will warn if
not).
@@ -169,9 +174,15 @@ Almost always one of:
## "Check your internet connection" / black screen
Most often: your host's tunnel URL changed (Tunnelto sometimes rotates
hostnames between sessions). Get a fresh join code from them and
re-apply the patch.
Almost always: the host restarted hosting since they sent you the join
code, so the Localtunnel URL it points at no longer exists. Ask the
host to copy the current join code from their launcher and re-share it.
Re-apply the patch with the new code.
If that doesn't fix it, open the host's `*.loca.lt` URL in your browser
once — Localtunnel sometimes shows a one-time "Click to Continue"
interstitial that needs to be cleared by hand before the patched client
can reach the server.
## More troubleshooting
+3 -3
View File
@@ -41,15 +41,15 @@ card.
After login, click **CREATE A NEW APP** on the dashboard. The form asks
for:
- **Photon Type** — pick **Photon Realtime**. Not Fusion, not Quantum,
not Bolt.
- **Photon Type** — pick **Photon SDK**. Not Fusion, not Quantum, not
Bolt.
- **Name** — anything you'll recognise later ("DorkNet Realtime",
"Sunday Server", etc.). Joiners don't see this.
- **Description** — optional.
Click **CREATE**.
![photon "Create a new app" form, Realtime selected](images/photon-2-create-realtime.png)
![photon "Create a new app" form, Photon SDK selected](images/photon-2-create-realtime.png)
## Step 3 — Copy the Realtime AppId
+45 -32
View File
@@ -6,15 +6,17 @@
`dorknet-server` is a small command-line tool that does the host side
of what the Windows launcher does: downloads the server build, opens a
[Tunnelto](https://tunnelto.dev) tunnel, runs the server, and prints
a join code. It runs on Linux, macOS, and Windows.
[Localtunnel](https://localtunnel.github.io/www/) HTTPS URL (or binds
on the LAN), runs the server, and prints a join code. It runs on Linux,
macOS, and Windows.
## What you'll need
- A machine running Linux (x64 or arm64), macOS (Intel or Apple
Silicon), or Windows
- [Tunnelto](https://github.com/agrinman/tunnelto) on PATH (for the
default mode that exposes your server publicly)
- For the default friends-anywhere mode: Node.js on `PATH` (the CLI
invokes `npx localtunnel` to fetch a free `*.loca.lt` URL — no account
needed). LAN mode doesn't need this.
- A Photon Realtime AppId — see [photon-setup.md](photon-setup.md)
- ~500 MB free disk (server binary + SQLite database)
@@ -51,22 +53,21 @@ Expand-Archive dorknet-server.zip
.\dorknet-server\dorknet-server.exe --help
```
### Tunnelto
### Localtunnel
The CLI shells out to `tunnelto` for the public tunnel. Quickest install:
Default mode shells out to the [Localtunnel](https://localtunnel.github.io/www/)
client to get a free, anonymous `https://<random>.loca.lt` URL. The CLI
calls `npx localtunnel --port <local>` if `npx` is on `PATH`; if not,
install Node.js (16 or newer) or the standalone `lt` CLI from the
Localtunnel repo and put it on `PATH`.
```sh
# macOS (Homebrew)
brew install tunnelto
The URL is regenerated every host session — copy a fresh join code
after each restart and re-share it. Joiners might see a one-time
"Click to Continue" interstitial on first contact with a given URL;
opening it once in a browser clears it.
# Linux (cargo)
cargo install tunnelto
# Or grab a binary from github.com/agrinman/tunnelto/releases
```
Skip Tunnelto if you're running in `--mode lan` (LAN-only, no public
URL).
Skip Localtunnel only if you're running in `--mode lan` (same WiFi
only).
## Usage
@@ -81,24 +82,25 @@ The CLI prints progress, then a join code:
```
DorkNet server CLI · v0.1.0
mode: Internet
network: Localtunnel
server: DorkNet Server
photon: ********90ab (us)
[server] downloading…
54.2% (27.1 / 50.0 MB)
[server] cached at /home/alex/.local/share/DorkNet/servers/march_2020_03_10
[tunnel] starting tunnelto…
[tunnel] live at https://dorknet-abc123.tunnelto.me (apex=dorknet-abc123.tunnelto.me)
[tunnel] starting localtunnel…
[tunnel] live at https://lucky-pelican-42.loca.lt
[server] starting…
[server] listening (logs: /home/alex/.local/share/DorkNet/logs/server-…log)
══════════════════════════════════════════════════════
Server live: DorkNet Server
Address: https://dorknet-abc123.tunnelto.me
Address: https://lucky-pelican-42.loca.lt
Join code (paste this into your friend's launcher):
eyJob3N0IjoiZG9ya25ldC1hYmMxMjMudHVubmVsdG8ubWUiLCJ2I...
eyJob3N0IjoibHVja3ktcGVsaWNhbi00Mi5sb2NhLmx0IiwidiI...
Ctrl-C to stop.
══════════════════════════════════════════════════════
@@ -120,9 +122,11 @@ down cleanly.
in, au. Default: us. All joiners use the same.
--name "<text>" Server display name in the join code.
Default: "DorkNet Server".
--mode <kind> tunnelto (default) — public, friends anywhere
wildcard — your own Tunnelto apex
lan — same WiFi only, no tunnel
--mode <kind> localtunnel (default) — public *.loca.lt URL,
friends anywhere
wildcard — legacy Tunnelto wildcard
apex
lan — same WiFi only, no tunnel
--apex <hostname> Wildcard apex. Required for --mode wildcard.
Example: dorknet.example.tunnelto.me
--version <key> Rec Room version key. Default: march_2020_03_10
@@ -145,7 +149,7 @@ dorknet-server \
# LAN party — no tunnel, joiners must be on the same WiFi
dorknet-server --photon-id ... --mode lan
# Custom Tunnelto wildcard base
# Legacy custom Tunnelto wildcard base
dorknet-server \
--photon-id ... \
--mode wildcard \
@@ -190,10 +194,11 @@ sudo systemctl enable --now dorknet
journalctl -fu dorknet # follow the logs
```
> Heads-up: each new tunnel session gets a fresh `*.tunnelto.me`
> hostname, so the join code rotates on restart. Either re-share
> the new code with your friends, or use `--mode wildcard` with a
> stable apex.
> Heads-up: Localtunnel hands out a fresh `*.loca.lt` URL on every
> restart, so each time systemd restarts the service the join code
> rotates. Either commit to a stable apex via `--mode wildcard`, or
> arrange to re-share the join code (e.g. a tiny post-start hook that
> emails / Discord-webhooks the new code).
## Run as a launchd agent (macOS)
@@ -251,10 +256,18 @@ it's stateless across runs (all config comes from CLI args).
## Troubleshooting
### `tunnelto was not found`
### `localtunnel client wasn't found`
The CLI couldn't find a `tunnelto` binary. Install it (see above) or
drop the binary next to `dorknet-server`.
The CLI couldn't find an `lt` binary or an `npx` in `PATH`. Install
Node.js 16+ (which brings `npx`) or install the standalone Localtunnel
client (`npm install -g localtunnel` then `lt --version` to confirm).
For same-WiFi hosting without any tunnel, pass `--mode lan`.
### Joiner hits "Click to Continue" on a Localtunnel landing page
First-touch interstitial that Localtunnel shows once per (IP, URL)
pair. Tell the joiner to open the URL in any browser once; the gate
clears and the patched client connects normally on the next attempt.
### `couldn't fetch versions.json`
+21 -9
View File
@@ -16,10 +16,14 @@ this re-fetches the server's current pubkey before patching.
The watch can't reach the server URL. Verify:
1. The host string in `dorknet-clientmod.json` matches the server's
public URL (tunnel URL for Easy mode).
2. The server responds to `https://<host>/healthz` with `200 OK` from
the same machine the client runs on.
3. No corporate proxy / DNS filter is intercepting `*.trycloudflare.com`.
current join-code URL. (Localtunnel hands out a fresh
`<random>.loca.lt` URL on every host restart — the joiner needs the
most recent code.)
2. Open `https://<host>/healthz` in a browser from the joiner's machine
and confirm a `200 OK`. If you instead see Localtunnel's "Click to
Continue" page, click through once and retry the connect.
3. No corporate proxy / DNS filter is intercepting `loca.lt` /
`sslip.io`.
### Black screen after the loading bar fills
@@ -73,12 +77,20 @@ fixes:
## Easy app
### "Cloudflared exited unexpectedly"
### "Localtunnel couldn't get a URL"
The bundled `cloudflared.exe` couldn't start. Most likely a Windows
Defender false-positive — check Defender's quarantine. If you find a
cleaner alternative tunnel provider, open an issue; we've been looking
for one.
DorkNet shells out to the Localtunnel client and waits for it to
report back with a `*.loca.lt` URL. If that fails, the most common
causes are:
- Localtunnel's service is rate-limiting / down — wait a couple
minutes and retry, or switch to LAN mode if friends are local.
- No Node.js / `npx` available for the fallback path (the launcher
bundles a .NET Localtunnel client, but if both that and `npx`
fail you'll see this). Install Node.js 16+ from
[nodejs.org](https://nodejs.org/) and click Retry.
- Outbound HTTPS to `loca.lt` is blocked (corporate firewall, DNS
filter). Switch to LAN mode or use the wildcard option with your
own apex.
### Patch button is greyed out