CI / Go Backend (push) Canceled after 0s
初始化 monorepo: Go后端(7微服务) + Unity客户端(9模块) + 启动器 HTML5原型: Three.js 3D体素世界, Perlin噪声地形, 原版材质, 22种方块 Minecraft创造模式背包: 双栏布局, 拖拽移动物品, 方向性元件引脚 AI助搭策划文档 + 客户端/服务端骨架 + Docker Compose + CI
92 lines
3.3 KiB
C#
92 lines
3.3 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.IO.Compression;
|
||
using System.Linq;
|
||
using System.Text.Json.Nodes;
|
||
|
||
namespace PCL;
|
||
|
||
/// <summary>
|
||
/// Jar-in-Jar(内嵌模组)解析。
|
||
/// </summary>
|
||
public static class ModJarInJar
|
||
{
|
||
private const int MaxDepth = 5;
|
||
|
||
/// <summary>
|
||
/// 解析 <paramref name="jar" /> 内嵌套的其它 Mod jar,返回内嵌 Mod 列表。
|
||
/// </summary>
|
||
public static List<ModLocalComp.LocalCompFile> Resolve(string parentPath, ZipArchive jar, int depth = 0)
|
||
{
|
||
var result = new List<ModLocalComp.LocalCompFile>();
|
||
if (depth >= MaxDepth) return result;
|
||
|
||
var nestedPaths = new List<string>();
|
||
_CollectFabricNestedJars(jar, nestedPaths);
|
||
_CollectForgeNestedJars(jar, nestedPaths);
|
||
|
||
foreach (var nestedPath in nestedPaths.Distinct())
|
||
{
|
||
try
|
||
{
|
||
var entry = jar.GetEntry(nestedPath);
|
||
if (entry is null) continue;
|
||
using var ms = new MemoryStream();
|
||
using (var es = entry.Open()) es.CopyTo(ms);
|
||
ms.Position = 0;
|
||
using var nestedJar = new ZipArchive(ms, ZipArchiveMode.Read);
|
||
|
||
var childPath = parentPath + "!/" + nestedPath;
|
||
var child = new ModLocalComp.LocalCompFile(childPath);
|
||
child.LookupMetadata(nestedJar);
|
||
child.MarkLoaded();
|
||
child.EmbeddedMods = Resolve(childPath, nestedJar, depth + 1);
|
||
result.Add(child);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
ModBase.Log(ex, "解析内嵌 Mod 失败(" + parentPath + " -> " + nestedPath + ")", ModBase.LogLevel.Developer);
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
private static void _CollectFabricNestedJars(ZipArchive jar, List<string> paths)
|
||
{
|
||
try
|
||
{
|
||
var entry = jar.GetEntry("fabric.mod.json");
|
||
if (entry is null) return;
|
||
var obj = (JsonObject)ModBase.GetJson(ModBase.ReadFile(entry.Open()));
|
||
if (obj.TryGetPropertyValue("jars", out var jars) && jars is JsonArray arr)
|
||
foreach (var j in arr)
|
||
if (j is JsonObject jo && jo.TryGetPropertyValue("file", out var file) && file is not null)
|
||
paths.Add(file.ToString());
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
ModBase.Log(ex, "解析 fabric.mod.json 内嵌清单失败", ModBase.LogLevel.Developer);
|
||
}
|
||
}
|
||
|
||
private static void _CollectForgeNestedJars(ZipArchive jar, List<string> paths)
|
||
{
|
||
try
|
||
{
|
||
var entry = jar.GetEntry("META-INF/jarjar/metadata.json");
|
||
if (entry is null) return;
|
||
var obj = (JsonObject)ModBase.GetJson(ModBase.ReadFile(entry.Open()));
|
||
if (obj.TryGetPropertyValue("jars", out var jars) && jars is JsonArray arr)
|
||
foreach (var j in arr)
|
||
if (j is JsonObject jo && jo.TryGetPropertyValue("path", out var p) && p is not null)
|
||
paths.Add(p.ToString());
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
ModBase.Log(ex, "解析 META-INF/jarjar/metadata.json 内嵌清单失败", ModBase.LogLevel.Developer);
|
||
}
|
||
}
|
||
}
|