namespace KMCCC.Modules.JVersion { #region using System.Collections.Generic; using System.IO; using System.Linq; using Launcher; using LitJson; using Tools; #endregion /// /// 默认的版本定位器 /// public class JVersionLocator : IVersionLocator { private readonly HashSet _locatingVersion; private readonly Dictionary _versions; public JVersionLocator() { _versions = new Dictionary(); _locatingVersion = new HashSet(); } public string GameRootPath { get; set; } private LauncherCore _core; public LauncherCore Core { set { GameRootPath = value.GameRootPath; _core = value; } } public Version Locate(string id) { lock (_locatingVersion) { return GetVersionInternal(id); } } public IEnumerable GetAllVersions() { try { lock (_locatingVersion) { return new DirectoryInfo(GameRootPath + @"\versions").EnumerateDirectories() .Select(dir => GetVersionInternal(dir.Name)).Where(item => item != null); } } catch { return new Version[0]; } } /// /// 获取Version信息,当出现错误时会返回null /// /// 版本id /// Version的信息 internal Version GetVersionInternal(string id) { try { if (_locatingVersion.Contains(id)) { return null; } _locatingVersion.Add(id); Version version; if (_versions.TryGetValue(id, out version)) { return version; } var jver = LoadVersion(_core.GetVersionJsonPath(id)); if (jver == null) { return null; } version = new Version(); //if (string.IsNullOrWhiteSpace(jver.Id)) //{ // jver.Id = id; //} jver.Id = id; if (string.IsNullOrWhiteSpace(jver.MinecraftArguments)) { return null; } if (string.IsNullOrWhiteSpace(jver.MainClass)) { return null; } if (string.IsNullOrWhiteSpace(jver.Assets)) { jver.Assets = "legacy"; } if (jver.Libraries == null) { return null; } version.Id = jver.Id; version.MinecraftArguments = jver.MinecraftArguments; version.Assets = jver.Assets; version.MainClass = jver.MainClass; version.JarId = jver.JarId; version.Libraries = new List(); version.Natives = new List(); foreach (var lib in jver.Libraries) { if (string.IsNullOrWhiteSpace(lib.Name)) { continue; } var names = lib.Name.Split(':'); if (names.Length != 3) { continue; } if (lib.Natives == null) { if (!IfAllowed(lib.Rules)) { continue; } version.Libraries.Add(new Library { NS = names[0], Name = names[1], Version = names[2] }); } else { if (!IfAllowed(lib.Rules)) { continue; } var native = new Native { NS = names[0], Name = names[1], Version = names[2], NativeSuffix = lib.Natives["windows"].Replace("${arch}", SystemTools.GetArch()) }; version.Natives.Add(native); if (lib.Extract != null) { native.Options = new UnzipOptions { Exclude = lib.Extract.Exculde }; } } } if (jver.InheritsVersion != null) { var target = GetVersionInternal(jver.InheritsVersion); if (target == null) { return null; } else { version.Assets = version.Assets ?? target.Assets; version.JarId = version.JarId ?? target.JarId; version.MainClass = version.MainClass ?? target.MainClass; version.MinecraftArguments = version.MinecraftArguments ?? target.MinecraftArguments; version.Natives.AddRange(target.Natives); version.Libraries.AddRange(target.Libraries); } } version.JarId = version.JarId ?? version.Id; _versions.Add(version.Id, version); return version; } catch { return null; } finally { _locatingVersion.Remove(id); } } public JVersion LoadVersion(string jsonPath) { try { return JsonMapper.ToObject(File.ReadAllText(jsonPath)); } catch { return null; } } /// /// 判断一系列规则后是否启用 /// /// 规则们 /// 是否启用 public bool IfAllowed(List rules) { if (rules == null) { return true; } if (rules.Count == 0) { return true; } var allowed = false; foreach (var rule in rules) { if (rule.OS == null) { allowed = rule.Action == "allow"; continue; } if (rule.OS.Name == "windows") { allowed = rule.Action == "allow"; } } return allowed; } } }