|
| 1 | +using System; |
| 2 | +using System.Collections.Generic; |
| 3 | +using System.IO; |
| 4 | +using System.Linq; |
| 5 | + |
| 6 | +namespace BrickForceDevTools.Patch |
| 7 | +{ |
| 8 | + public static class PatchBuilder |
| 9 | + { |
| 10 | + public sealed record DiffEntry( |
| 11 | + string BaseName, |
| 12 | + string RegMapPath, |
| 13 | + string GeometryPath, |
| 14 | + bool HasGeometry, |
| 15 | + string MapName, |
| 16 | + string Creator |
| 17 | + ); |
| 18 | + |
| 19 | + /// <summary> |
| 20 | + /// Compute B - A by base filename (without extension). |
| 21 | + /// </summary> |
| 22 | + public static List<DiffEntry> ComputeDiff(string folderA, string folderB, bool skipMissingGeometry, Action<string>? log = null) |
| 23 | + { |
| 24 | + // Index A |
| 25 | + var aKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase); |
| 26 | + foreach (var regA in Directory.EnumerateFiles(folderA, "*.regmap")) |
| 27 | + { |
| 28 | + var baseName = Path.GetFileNameWithoutExtension(regA); |
| 29 | + var geoA = Path.Combine(folderA, baseName + ".geometry"); |
| 30 | + |
| 31 | + if (skipMissingGeometry && !File.Exists(geoA)) |
| 32 | + continue; |
| 33 | + |
| 34 | + aKeys.Add(baseName); |
| 35 | + } |
| 36 | + |
| 37 | + // Scan B |
| 38 | + var diffs = new List<DiffEntry>(); |
| 39 | + |
| 40 | + foreach (var regB in Directory.EnumerateFiles(folderB, "*.regmap")) |
| 41 | + { |
| 42 | + var baseName = Path.GetFileNameWithoutExtension(regB); |
| 43 | + if (aKeys.Contains(baseName)) |
| 44 | + continue; |
| 45 | + |
| 46 | + var geoB = Path.Combine(folderB, baseName + ".geometry"); |
| 47 | + var hasGeo = File.Exists(geoB); |
| 48 | + |
| 49 | + if (skipMissingGeometry && !hasGeo) |
| 50 | + { |
| 51 | + log?.Invoke($"[Patch] Missing Geometry (skipped): {Path.GetFileName(geoB)}"); |
| 52 | + continue; |
| 53 | + } |
| 54 | + |
| 55 | + // Load map metadata from regmap (adjust fields if needed) |
| 56 | + var regMap = RegMapManager.Load(regB); |
| 57 | + |
| 58 | + // These names come from your earlier regmap loader snippet: alias + developer |
| 59 | + string mapName = regMap.alias ?? baseName; |
| 60 | + string creator = regMap.developer ?? "Unknown"; |
| 61 | + |
| 62 | + diffs.Add(new DiffEntry(baseName, regB, geoB, hasGeo, mapName, creator)); |
| 63 | + } |
| 64 | + |
| 65 | + return diffs |
| 66 | + .OrderBy(d => d.MapName, StringComparer.OrdinalIgnoreCase) |
| 67 | + .ThenBy(d => d.Creator, StringComparer.OrdinalIgnoreCase) |
| 68 | + .ToList(); |
| 69 | + } |
| 70 | + |
| 71 | + /// <summary> |
| 72 | + /// Copy files and generate changelog.txt and info. |
| 73 | + /// </summary> |
| 74 | + public static void BuildPatchOutput(IEnumerable<DiffEntry> diffs, string outputFolder, Action<string>? log = null) |
| 75 | + { |
| 76 | + Directory.CreateDirectory(outputFolder); |
| 77 | + |
| 78 | + var changelogLines = new List<string>(); |
| 79 | + var infoLines = new List<string>(); |
| 80 | + if (Global.IncludeAssemblyLineInPatchInfo) |
| 81 | + { |
| 82 | + infoLines.Add("Assembly-CSharp.dll=/BrickForce_Data/Managed/"); |
| 83 | + } |
| 84 | + |
| 85 | + int copiedMaps = 0; |
| 86 | + int copiedFiles = 0; |
| 87 | + |
| 88 | + foreach (var d in diffs) |
| 89 | + { |
| 90 | + var outReg = Path.Combine(outputFolder, d.BaseName + ".regmap"); |
| 91 | + File.Copy(d.RegMapPath, outReg, overwrite: true); |
| 92 | + copiedFiles++; |
| 93 | + |
| 94 | + changelogLines.Add($"{d.MapName} by {d.Creator}"); |
| 95 | + infoLines.Add($"{Path.GetFileName(outReg)}=/BrickForce_Data/Resources/Cache"); |
| 96 | + |
| 97 | + if (d.HasGeometry) |
| 98 | + { |
| 99 | + var outGeo = Path.Combine(outputFolder, d.BaseName + ".geometry"); |
| 100 | + File.Copy(d.GeometryPath, outGeo, overwrite: true); |
| 101 | + copiedFiles++; |
| 102 | + |
| 103 | + infoLines.Add($"{Path.GetFileName(outGeo)}=/BrickForce_Data/Resources/Cache"); |
| 104 | + } |
| 105 | + |
| 106 | + copiedMaps++; |
| 107 | + } |
| 108 | + |
| 109 | + File.WriteAllLines(Path.Combine(outputFolder, "changelog.txt"), changelogLines); |
| 110 | + File.WriteAllLines(Path.Combine(outputFolder, "info"), infoLines); |
| 111 | + |
| 112 | + log?.Invoke($"[Patch] Done. Maps: {copiedMaps}, Files: {copiedFiles}, Output: {outputFolder}"); |
| 113 | + } |
| 114 | + } |
| 115 | +} |
0 commit comments