4594cb9c00
Bake each file's "side" (client / server / both) into manifest.json at build time so both the launcher and the server filter deterministically and offline. This replaces the launcher's previous "download everything" default and lets the server short-circuit its runtime Modrinth lookup when a file already has an authoritative tag. Schema: - ManifestFile.Side: "client" | "server" | "both" (null = "both" for backward compat with manifests pre-dating this field) - Files marked "both" omit the field entirely to keep the JSON tight Code changes: - launcher Manifest.cs + ManifestSyncService: filter out "server" files in both the prune+download path and FindMissingFiles - server Manifest.cs + ManifestSync: drop "client" files outright; only fall back to the existing runtime Modrinth lookup for files with no explicit side (legacy/un-tagged mods stay protected) - server LockedMod: side field propagates into manifest at build time - scripts/Build-Pack.ps1: propagate side from lockfile to manifest - scripts/Bootstrap-Sides.ps1: one-off populator; queries Modrinth's client_side/server_side per project, conservatively marks restricted only when one side is "unsupported", leaves ambiguous cases as "both" - pack/pack.lock.json: bootstrap-populated sides (3 client, 5 server, rest both); CurseForge mods default to "both" pending manual review; version bumped 0.9.3 -> 0.10.0 since clients must re-sync Compatibility: - Old launcher + new manifest: ignores unknown "side", downloads all - New launcher + old manifest: side null -> "both", installs all - Old server + new manifest: same -- runtime Modrinth lookup still works - New server + old manifest: side null -> runtime lookup, same behaviour
70 lines
2.6 KiB
C#
70 lines
2.6 KiB
C#
using System.Text.Json.Serialization;
|
|
|
|
namespace BrassAndSigil.Server.Models;
|
|
|
|
public sealed class Manifest
|
|
{
|
|
[JsonPropertyName("name")]
|
|
public string? Name { get; set; }
|
|
|
|
[JsonPropertyName("version")]
|
|
public string? Version { get; set; }
|
|
|
|
[JsonPropertyName("minecraft")]
|
|
public MinecraftSpec Minecraft { get; set; } = new();
|
|
|
|
[JsonPropertyName("loader")]
|
|
public LoaderSpec? Loader { get; set; }
|
|
|
|
[JsonPropertyName("files")]
|
|
public List<ManifestFile> Files { get; set; } = new();
|
|
}
|
|
|
|
public sealed class MinecraftSpec
|
|
{
|
|
[JsonPropertyName("version")] public string Version { get; set; } = "";
|
|
}
|
|
|
|
public sealed class LoaderSpec
|
|
{
|
|
[JsonPropertyName("type")] public string Type { get; set; } = "vanilla";
|
|
[JsonPropertyName("version")] public string Version { get; set; } = "";
|
|
}
|
|
|
|
public sealed class ManifestFile
|
|
{
|
|
[JsonPropertyName("path")] public string Path { get; set; } = "";
|
|
[JsonPropertyName("url")] public string Url { get; set; } = "";
|
|
[JsonPropertyName("sha1")] public string? Sha1 { get; set; }
|
|
[JsonPropertyName("size")] public long? Size { get; set; }
|
|
|
|
/// <summary>
|
|
/// "both" (default), "client", or "server". Server skips "client" files;
|
|
/// launcher skips "server" files. Null/missing = "both".
|
|
/// </summary>
|
|
[JsonPropertyName("side")] public string? Side { get; set; }
|
|
}
|
|
|
|
public sealed class PackLock
|
|
{
|
|
[JsonPropertyName("name")] public string Name { get; set; } = "";
|
|
[JsonPropertyName("version")] public string Version { get; set; } = "";
|
|
[JsonPropertyName("minecraft")] public string Minecraft { get; set; } = "";
|
|
[JsonPropertyName("loader")] public LoaderSpec Loader { get; set; } = new();
|
|
[JsonPropertyName("mods")] public List<LockedMod> Mods { get; set; } = new();
|
|
}
|
|
|
|
public sealed class LockedMod
|
|
{
|
|
[JsonPropertyName("source")] public string Source { get; set; } = "";
|
|
[JsonPropertyName("slug")] public string? Slug { get; set; }
|
|
[JsonPropertyName("versionId")] public string? VersionId { get; set; }
|
|
[JsonPropertyName("fileId")] public string? FileId { get; set; }
|
|
[JsonPropertyName("version")] public string Version { get; set; } = "";
|
|
[JsonPropertyName("path")] public string Path { get; set; } = "";
|
|
[JsonPropertyName("url")] public string Url { get; set; } = "";
|
|
[JsonPropertyName("sha1")] public string Sha1 { get; set; } = "";
|
|
[JsonPropertyName("size")] public long Size { get; set; }
|
|
[JsonPropertyName("side")] public string? Side { get; set; }
|
|
}
|