MinecraftRules.cs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. using System.Text.Json.Nodes;
  2. using System.Text.RegularExpressions;
  3. namespace PCL.Communist.Core;
  4. public static class MinecraftRules
  5. {
  6. public static bool Allows(JsonNode? rules, PlatformInfo platform, IReadOnlyDictionary<string, bool>? features = null)
  7. {
  8. if (rules is not JsonArray entries) return true;
  9. var allowed = false;
  10. foreach (var entry in entries)
  11. {
  12. if (entry is null) continue;
  13. var os = entry["os"];
  14. if (os?["name"] is JsonNode name && name.GetValue<string>() != platform.MinecraftOs) continue;
  15. if (os?["arch"] is JsonNode arch && !Match(arch.GetValue<string>(), platform.MinecraftArch)) continue;
  16. if (os?["version"] is JsonNode version && !Match(version.GetValue<string>(), platform.Version)) continue;
  17. if (entry["features"] is JsonObject required && required.Any(f =>
  18. (features?.GetValueOrDefault(f.Key) ?? false) != (f.Value?.GetValue<bool>() ?? false))) continue;
  19. allowed = entry["action"]?.GetValue<string>() == "allow";
  20. }
  21. return allowed;
  22. }
  23. private static bool Match(string pattern, string value) =>
  24. Regex.IsMatch(value, pattern, RegexOptions.CultureInvariant, TimeSpan.FromSeconds(1));
  25. public static string? NativeClassifier(JsonNode library, PlatformInfo platform)
  26. {
  27. if (platform.IsMobile) throw new PlatformNotSupportedException("桌面原生库不适用于移动端。");
  28. var classifier = library["natives"]?[platform.MinecraftOs]?.GetValue<string>();
  29. return classifier?.Replace("${arch}", platform.Architecture == System.Runtime.InteropServices.Architecture.X86 ? "32" : "64");
  30. }
  31. public static void ValidateNativeArchitecture(JsonObject metadata, PlatformInfo platform)
  32. {
  33. if (platform.IsMobile || platform.Architecture != System.Runtime.InteropServices.Architecture.Arm64) return;
  34. foreach (var library in metadata["libraries"]!.AsArray())
  35. {
  36. if (library is null || !Allows(library["rules"], platform)) continue;
  37. var classifier = NativeClassifier(library, platform);
  38. if (classifier is null || classifier.Contains("arm64", StringComparison.OrdinalIgnoreCase) || classifier.Contains("aarch64", StringComparison.OrdinalIgnoreCase)) continue;
  39. throw new PlatformNotSupportedException(platform.Kind == PlatformKind.MacOS
  40. ? "此旧版本仅提供 Intel Mac 原生库,请使用 Intel 构建与 Intel Java(需要 Rosetta),或选择提供 Apple Silicon 原生库的版本。"
  41. : "此版本的旧式原生库没有标明 ARM64 支持,请使用匹配的 x64 构建与 Java,或选择提供 ARM64 原生库的版本。");
  42. }
  43. }
  44. }