a1331212cb
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.
91 lines
3.9 KiB
C#
91 lines
3.9 KiB
C#
using System.Diagnostics;
|
|
using BrassAndSigil.Server.Models;
|
|
using BrassAndSigil.Server.Services;
|
|
using Spectre.Console;
|
|
using Spectre.Console.Cli;
|
|
|
|
namespace BrassAndSigil.Server.Commands;
|
|
|
|
public sealed class CheckCommand : AsyncCommand<BaseCommandSettings>
|
|
{
|
|
public override async Task<int> ExecuteAsync(CommandContext context, BaseCommandSettings settings)
|
|
{
|
|
var config = ServerConfig.Load(settings.ConfigPath);
|
|
AnsiConsole.MarkupLine("[bold]Checking server install...[/]");
|
|
var ok = true;
|
|
|
|
// 1. Java available?
|
|
var javaVersion = await TryRunForOutputAsync(config.JavaPath, "-version");
|
|
if (javaVersion is not null)
|
|
AnsiConsole.MarkupLine($" [green]✓[/] Java reachable: {javaVersion.Split('\n')[0].Trim().EscapeMarkup()}");
|
|
else
|
|
{ AnsiConsole.MarkupLine($" [red]✗[/] Java not found at '{config.JavaPath}'"); ok = false; }
|
|
|
|
// 2. Server dir
|
|
var serverDir = Path.GetFullPath(config.ServerDir);
|
|
if (Directory.Exists(serverDir))
|
|
AnsiConsole.MarkupLine($" [green]✓[/] Server dir exists: {serverDir}");
|
|
else
|
|
{ AnsiConsole.MarkupLine($" [yellow]?[/] Server dir missing -- run [yellow]install[/] first"); ok = false; }
|
|
|
|
// 3. EULA
|
|
var eulaPath = Path.Combine(serverDir, "eula.txt");
|
|
if (File.Exists(eulaPath) && File.ReadAllText(eulaPath).Contains("eula=true"))
|
|
AnsiConsole.MarkupLine(" [green]✓[/] EULA accepted");
|
|
else
|
|
{ AnsiConsole.MarkupLine(" [yellow]?[/] EULA not accepted (re-run [yellow]install --accept-eula[/])"); ok = false; }
|
|
|
|
// 4. NeoForge run script
|
|
var runScript = Path.Combine(serverDir, OperatingSystem.IsWindows() ? "run.bat" : "run.sh");
|
|
if (File.Exists(runScript))
|
|
AnsiConsole.MarkupLine($" [green]✓[/] Loader start script: {Path.GetFileName(runScript)}");
|
|
else
|
|
AnsiConsole.MarkupLine($" [yellow]?[/] No {Path.GetFileName(runScript)} -- install the NeoForge server first");
|
|
|
|
// 5. Manifest reachable
|
|
try
|
|
{
|
|
using var http = new HttpClient { Timeout = TimeSpan.FromSeconds(10) };
|
|
var resp = await http.GetAsync(config.ManifestUrl);
|
|
if (resp.IsSuccessStatusCode)
|
|
AnsiConsole.MarkupLine($" [green]✓[/] Manifest reachable: {config.ManifestUrl}");
|
|
else
|
|
{ AnsiConsole.MarkupLine($" [red]✗[/] Manifest HTTP {(int)resp.StatusCode}: {config.ManifestUrl}"); ok = false; }
|
|
}
|
|
catch (Exception ex)
|
|
{ AnsiConsole.MarkupLine($" [red]✗[/] Manifest fetch error: {ex.Message.EscapeMarkup()}"); ok = false; }
|
|
|
|
// 6. Pack version on disk
|
|
var packVer = Path.Combine(serverDir, "pack-version.json");
|
|
if (File.Exists(packVer))
|
|
AnsiConsole.MarkupLine($" [green]✓[/] Pack synced: {File.ReadAllText(packVer).Replace("\n", " ").Replace("\r", "").Trim().EscapeMarkup()}");
|
|
else
|
|
AnsiConsole.MarkupLine(" [yellow]?[/] Pack not synced yet (run [yellow]sync[/])");
|
|
|
|
AnsiConsole.MarkupLine("");
|
|
AnsiConsole.MarkupLine(ok ? "[green]All required checks passed.[/]" : "[yellow]Some checks failed; see above.[/]");
|
|
return ok ? 0 : 1;
|
|
}
|
|
|
|
private static async Task<string?> TryRunForOutputAsync(string fileName, string args)
|
|
{
|
|
try
|
|
{
|
|
var p = Process.Start(new ProcessStartInfo
|
|
{
|
|
FileName = fileName,
|
|
Arguments = args,
|
|
RedirectStandardOutput = true,
|
|
RedirectStandardError = true,
|
|
UseShellExecute = false,
|
|
CreateNoWindow = true,
|
|
});
|
|
if (p is null) return null;
|
|
var output = await p.StandardError.ReadToEndAsync() + await p.StandardOutput.ReadToEndAsync();
|
|
await p.WaitForExitAsync();
|
|
return output;
|
|
}
|
|
catch { return null; }
|
|
}
|
|
}
|