Initial commit: Brass & Sigil monorepo

Self-hosted Minecraft modpack distribution + administration system.

- launcher/  Avalonia 12 desktop client; single-file win-x64 publish.
             Microsoft auth via XboxAuthNet, manifest+SHA-1 mod sync,
             portable install path, sidecar settings.
- server/    brass-sigil-server daemon (.NET 8, linux-x64). Wraps the
             MC subprocess, embedded Kestrel admin panel with cookie
             auth + rate limiting, RCON bridge, scheduled backups,
             BlueMap CLI integration with player markers + skin proxy,
             friend-side whitelist request flow, world wipe with seed
             selection (keep current / random / custom).
- pack/      pack.lock.json (Modrinth + manual CurseForge entries),
             data-only tweak source under tweaks/, build outputs in
             overrides/ (gitignored).
- scripts/   Build-Pack / Build-Tweaks / Update-Pack / Check-Updates
             plus Deploy-Brass.ps1 unified one-shot deploy with
             version-bump pre-flight and daemon-state detection.
This commit is contained in:
Matt Sijbers
2026-05-05 00:19:05 +01:00
commit a1331212cb
99 changed files with 12640 additions and 0 deletions
+95
View File
@@ -0,0 +1,95 @@
using System;
using System.Threading.Tasks;
using CmlLib.Core.Auth;
using CmlLib.Core.Auth.Microsoft;
using XboxAuthNet.Game.Msal;
using XboxAuthNet.Game.Msal.OAuth;
namespace ModpackLauncher.Services;
/// <summary>
/// Microsoft auth wrapper. Two modes:
/// 1. Custom Azure AD client ID (msalClientId set) -> MSAL flow. Requires Microsoft
/// to have approved the app for Minecraft API access.
/// 2. No custom client ID (default) -> CmlLib's BuildDefault() which uses the
/// WebView2-driven Microsoft Live OAuth flow with the Xbox Live SDK client ID.
/// Doesn't require an Azure registration; works out of the box on any Win10/11
/// machine that has the WebView2 Runtime installed (preinstalled since 2021).
/// </summary>
public sealed class AuthService
{
private readonly string _clientId;
public AuthService(string clientId)
{
_clientId = clientId;
}
/// <summary>True when the user has provided their own Azure App Registration ID.</summary>
public bool HasCustomClientId => !string.IsNullOrWhiteSpace(_clientId)
&& _clientId != "00000000-0000-0000-0000-000000000000";
/// <summary>Auth is always available now (BuildDefault provides a fallback).</summary>
public bool IsConfigured => true;
public async Task<MSession> AuthenticateAsync()
{
var loginHandler = await BuildLoginHandlerAsync();
try
{
return await loginHandler.AuthenticateSilently();
}
catch
{
return await loginHandler.AuthenticateInteractively();
}
}
public async Task<MSession> SignInInteractivelyAsync()
{
var loginHandler = await BuildLoginHandlerAsync();
return await loginHandler.AuthenticateInteractively();
}
public async Task<MSession?> TryAuthenticateSilentlyAsync()
{
try
{
var loginHandler = await BuildLoginHandlerAsync();
return await loginHandler.AuthenticateSilently();
}
catch
{
return null;
}
}
public async Task SignOutAsync()
{
try
{
var loginHandler = await BuildLoginHandlerAsync();
await loginHandler.Signout();
}
catch
{
// best-effort
}
}
private async Task<JELoginHandler> BuildLoginHandlerAsync()
{
if (HasCustomClientId)
{
// Custom Azure AD MSAL flow -- requires the app to be approved by Microsoft.
var app = await MsalClientHelper.BuildApplicationWithCache(_clientId);
return new JELoginHandlerBuilder()
.WithOAuthProvider(new MsalCodeFlowProvider(app))
.Build();
}
// Default path: WebView2 + Xbox Live SDK community client ID. No Azure registration.
// Note: requires WebView2 Runtime on Windows (preinstalled on Win10/11 since 2021).
return JELoginHandlerBuilder.BuildDefault();
}
}