1
0
mirror of https://e.coding.net/circlecloud/CTZLauncher.git synced 2024-11-15 00:58:50 +00:00
CTZLauncher/KMCCC.Shared/Modules/JVersion/JVersionLocator.cs
j502647092 6e0fa413d2 首次提交项目文件...
Signed-off-by: j502647092 <jtb1@163.com>
2015-07-29 19:56:27 +08:00

239 lines
4.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

namespace KMCCC.Modules.JVersion
{
#region
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Launcher;
using LitJson;
using Tools;
#endregion
/// <summary>
/// 默认的版本定位器
/// </summary>
public class JVersionLocator : IVersionLocator
{
private readonly HashSet<string> _locatingVersion;
private readonly Dictionary<string, Version> _versions;
public JVersionLocator()
{
_versions = new Dictionary<string, Version>();
_locatingVersion = new HashSet<string>();
}
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<Version> GetAllVersions()
{
try
{
lock (_locatingVersion)
{
return new DirectoryInfo(GameRootPath + @"\versions").EnumerateDirectories()
.Select(dir => GetVersionInternal(dir.Name)).Where(item => item != null);
}
}
catch
{
return new Version[0];
}
}
/// <summary>
/// 获取Version信息当出现错误时会返回null
/// </summary>
/// <param name="id">版本id</param>
/// <returns>Version的信息</returns>
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;
}
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<Library>();
version.Natives = new List<Native>();
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<JVersion>(File.ReadAllText(jsonPath));
}
catch
{
return null;
}
}
/// <summary>
/// 判断一系列规则后是否启用
/// </summary>
/// <param name="rules">规则们</param>
/// <returns>是否启用</returns>
public bool IfAllowed(List<JRule> 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;
}
}
}