Startoption -dev: lokale Test-Website (localhost:5080)

Eigene Anmeldung (settings.dev.json), bleibt bei Selbst-Installation und Update erhalten, DEV-Schild in der Oberflaeche.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-28 17:48:47 +01:00
co-authored by Claude Opus 5.5
parent b69b9638ff
commit 077e39fa8a
10 changed files with 46 additions and 9 deletions
+1 -1
View File
@@ -8,7 +8,7 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>BSO.Launcher</RootNamespace> <RootNamespace>BSO.Launcher</RootNamespace>
<AssemblyName>BSO-Launcher</AssemblyName> <AssemblyName>BSO-Launcher</AssemblyName>
<Version>0.1.0</Version> <Version>0.1.1</Version>
<Company>MBM.wtf</Company> <Company>MBM.wtf</Company>
<Product>BSO Launcher</Product> <Product>BSO Launcher</Product>
<Description>BSO Launcher - Bus Simulator Online</Description> <Description>BSO Launcher - Bus Simulator Online</Description>
+4 -2
View File
@@ -32,7 +32,8 @@ public sealed class MainForm : Form
ClientSize = new Size(1120, 700); ClientSize = new Size(1120, 700);
MinimumSize = new Size(900, 600); MinimumSize = new Size(900, 600);
StartPosition = FormStartPosition.CenterScreen; StartPosition = FormStartPosition.CenterScreen;
LauncherLog.Info("BSO Launcher " + SelfUpdate.CurrentVersion + " gestartet"); LauncherLog.Info("BSO Launcher " + SelfUpdate.CurrentVersion + " gestartet" + (Api.Dev ? " (-dev)" : "") + ", Website " + Api.Base);
if (Api.Base != Api.BaseUrl) Text += " (DEV)";
try { Icon = Icon.ExtractAssociatedIcon(Environment.ProcessPath ?? Application.ExecutablePath); } catch { } try { Icon = Icon.ExtractAssociatedIcon(Environment.ProcessPath ?? Application.ExecutablePath); } catch { }
Controls.Add(web); Controls.Add(web);
Load += async (_, _) => await InitWeb(); Load += async (_, _) => await InitWeb();
@@ -244,7 +245,8 @@ public sealed class MainForm : Form
version = SelfUpdate.CurrentVersion, version = SelfUpdate.CurrentVersion,
username = settings.Username, username = settings.Username,
loggedIn = settings.Token != null, loggedIn = settings.Token != null,
master = Api.Base master = Api.Base,
dev = Api.Dev || Api.Base != Api.BaseUrl
}; };
// --- Konto // --- Konto
+13 -2
View File
@@ -27,8 +27,19 @@ dotnet publish -c Release -o publish # eine .exe, ohne vorinstalliertes
.\release.ps1 -Product launcher -Version 0.1.0 -File publish\BSO-Launcher.exe -Changelog "..." .\release.ps1 -Product launcher -Version 0.1.0 -File publish\BSO-Launcher.exe -Changelog "..."
``` ```
Zum Testen gegen eine lokale Website: `$env:BSO_LAUNCHER_API = "http://localhost:5080"`, dann ## Gegen die lokale Test-Website (`-dev`)
`publish\BSO-Launcher.exe --portable`.
```powershell
BSO-Launcher.exe -dev # nimmt http://localhost:5080 statt https://bso.mbm.wtf
```
- `-dev` bleibt beim Selbst-Installieren und beim Selbst-Update erhalten; die installierte Kopie startet man genauso:
`"%LocalAppData%\Programs\BSO Launcher\BSO-Launcher.exe" -dev`.
- Eigene Anmeldung (`settings.dev.json`) – Test- und echtes Konto kommen sich nicht in die Quere.
- Gelbes **DEV**-Schild in der Titelleiste, im Fenstertitel und unter dem Anmelden-Formular steht die Adresse.
- Beliebiger anderer Server: Umgebungsvariable `BSO_LAUNCHER_API` (geht vor `-dev`).
Lokale Website starten: im BSO-Website-Repo `dotnet run --urls http://localhost:5080`.
## Release-Schlüssel ## Release-Schlüssel
+9 -2
View File
@@ -8,8 +8,15 @@ namespace BSO.Launcher;
public static class Api public static class Api
{ {
public const string BaseUrl = "https://bso.mbm.wtf"; public const string BaseUrl = "https://bso.mbm.wtf";
/// <summary>Zum Testen umstellbar: BSO_LAUNCHER_API=http://localhost:5080</summary> /// <summary>Lokale Test-Website (BSO-Website mit "dotnet run --urls http://localhost:5080").</summary>
public static string Base => (Environment.GetEnvironmentVariable("BSO_LAUNCHER_API") ?? BaseUrl).TrimEnd('/'); public const string DevUrl = "http://localhost:5080";
public const string DevArg = "-dev";
/// <summary>Mit -dev (oder --dev) gestartet: gegen die lokale Test-Website statt bso.mbm.wtf.</summary>
public static readonly bool Dev = Environment.GetCommandLineArgs().Skip(1).Any(a => a is "-dev" or "--dev");
/// <summary>Adresse der Website. BSO_LAUNCHER_API geht vor (beliebiger Test-Server), dann -dev, sonst bso.mbm.wtf.</summary>
public static string Base => (Environment.GetEnvironmentVariable("BSO_LAUNCHER_API") ?? (Dev ? DevUrl : BaseUrl)).TrimEnd('/');
public static readonly HttpClient Http = CreateHttp(); public static readonly HttpClient Http = CreateHttp();
+4 -1
View File
@@ -111,9 +111,12 @@ public static class Installer
catch { /* ohne Verknuepfung geht es auch */ } catch { /* ohne Verknuepfung geht es auch */ }
} }
/// <summary>Installierte Kopie starten - mit -dev, wenn diese hier mit -dev lief.</summary>
public static void StartInstalled() public static void StartInstalled()
{ {
Process.Start(new ProcessStartInfo(InstalledExe) { UseShellExecute = true, WorkingDirectory = InstallDir }); var start = new ProcessStartInfo(InstalledExe) { UseShellExecute = true, WorkingDirectory = InstallDir };
if (Api.Dev) start.ArgumentList.Add(Api.DevArg);
Process.Start(start);
} }
/// <summary>Ordner/Dateien loeschen, sobald dieser Prozess beendet ist (seine .exe ist bis dahin gesperrt).</summary> /// <summary>Ordner/Dateien loeschen, sobald dieser Prozess beendet ist (seine .exe ist bis dahin gesperrt).</summary>
+1
View File
@@ -45,6 +45,7 @@ public static class SelfUpdate
var start = new ProcessStartInfo(exe) { UseShellExecute = true }; var start = new ProcessStartInfo(exe) { UseShellExecute = true };
start.ArgumentList.Add(AfterUpdateArg); start.ArgumentList.Add(AfterUpdateArg);
if (!Installer.RunningInstalled) start.ArgumentList.Add("--portable"); if (!Installer.RunningInstalled) start.ArgumentList.Add("--portable");
if (Api.Dev) start.ArgumentList.Add(Api.DevArg);
Process.Start(start); Process.Start(start);
return release.version; return release.version;
} }
+2 -1
View File
@@ -11,7 +11,8 @@ namespace BSO.Launcher;
public sealed class Settings public sealed class Settings
{ {
public static string Folder => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "BSO Launcher"); public static string Folder => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "BSO Launcher");
static string FilePath => Path.Combine(Folder, "settings.json"); /// <summary>Mit -dev eigene Datei: die Anmeldung gilt nur fuer die Website, bei der sie gemacht wurde.</summary>
static string FilePath => Path.Combine(Folder, Api.Dev ? "settings.dev.json" : "settings.json");
static readonly JsonSerializerOptions Options = new() { WriteIndented = true }; static readonly JsonSerializerOptions Options = new() { WriteIndented = true };
public string? Username { get; set; } public string? Username { get; set; }
+2
View File
@@ -42,6 +42,8 @@ code, .mono { font-family: "Cascadia Mono", Consolas, monospace; font-size: 12.5
background: var(--sidebar); border-bottom: 1px solid #151922; } background: var(--sidebar); border-bottom: 1px solid #151922; }
.titlebar-drag { flex: 1; display: flex; align-items: center; gap: 8px; padding: 0 12px; color: var(--muted); font-size: 12px; font-weight: 600; } .titlebar-drag { flex: 1; display: flex; align-items: center; gap: 8px; padding: 0 12px; color: var(--muted); font-size: 12px; font-weight: 600; }
.titlebar-drag img { width: 18px; height: 18px; } .titlebar-drag img { width: 18px; height: 18px; }
.dev-badge { font-size: 10.5px; font-weight: 800; letter-spacing: .06em; padding: 1px 7px; border-radius: 6px;
color: #1a1400; background: var(--pending); }
.window-buttons { display: flex; } .window-buttons { display: flex; }
.window-buttons button { width: 46px; border: 0; background: transparent; color: #c4ccd8; font: 10px var(--icons); cursor: default; } .window-buttons button { width: 46px; border: 0; background: transparent; color: #c4ccd8; font: 10px var(--icons); cursor: default; }
.window-buttons button:hover { background: #1c212c; } .window-buttons button:hover { background: #1c212c; }
+8
View File
@@ -287,6 +287,14 @@ async function renderSettings(root) {
(async () => { (async () => {
const init = await call("init"); const init = await call("init");
$("meVersion").textContent = "Launcher " + init.version; $("meVersion").textContent = "Launcher " + init.version;
if (init.dev) {
// -dev: gegen die lokale Test-Website - gut sichtbar, damit niemand das verwechselt
const host = init.master.replace(/^https?:\/\//, "");
$("devBadge").textContent = "DEV · " + host;
$("devBadge").classList.remove("hidden");
$("meVersion").textContent += " · DEV";
}
$("authServer").textContent = "Server: " + init.master.replace(/^https?:\/\//, "");
if (!init.loggedIn) { showAuth(); return; } if (!init.loggedIn) { showAuth(); return; }
const me = await call("me"); const me = await call("me");
if (me.loggedIn) showApp(me.username); if (me.loggedIn) showApp(me.username);
+2
View File
@@ -13,6 +13,7 @@
<div class="titlebar-drag" id="titlebarDrag"> <div class="titlebar-drag" id="titlebarDrag">
<img src="logo.png" alt=""> <img src="logo.png" alt="">
<span>BSO Launcher</span> <span>BSO Launcher</span>
<span class="dev-badge hidden" id="devBadge" title="Mit -dev gestartet"></span>
</div> </div>
<div class="window-buttons"> <div class="window-buttons">
<button type="button" data-window="minimize" title="Minimieren" aria-label="Minimieren">&#xE921;</button> <button type="button" data-window="minimize" title="Minimieren" aria-label="Minimieren">&#xE921;</button>
@@ -50,6 +51,7 @@
<p id="authError" class="error hidden"></p> <p id="authError" class="error hidden"></p>
<button class="btn primary wide" id="authButton" type="submit">Anmelden</button> <button class="btn primary wide" id="authButton" type="submit">Anmelden</button>
<p class="muted small center">Dein Benutzername ist auch dein Name im Spiel. Passwoerter liegen nur verschluesselt auf dem BSO-Server.</p> <p class="muted small center">Dein Benutzername ist auch dein Name im Spiel. Passwoerter liegen nur verschluesselt auf dem BSO-Server.</p>
<p class="muted small center" id="authServer"></p>
</form> </form>
</main> </main>