114 lines
4.2 KiB
C#
114 lines
4.2 KiB
C#
using System.Collections.Generic;
|
||||
|
|
using PCL.Core.App.Localization;
|
|||
|
|
|
|||
|
|
namespace PCL;
|
|||
|
|
|
|||
|
|
public static class McVersionComparer
|
|||
|
|
{
|
|||
|
|
public const string UNKNOWN_VERSION_KEY = "UnknownVersion";
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 比较两个版本名;等同 Left >= Right。
|
|||
|
|
/// 无法比较两个预发布版的大小。
|
|||
|
|
/// 支持的格式:未知版本, 1.13.2, 1.7.10-pre4, 1.8_pre, 1.14 Pre-Release 2, 1.14.4 C6
|
|||
|
|
/// </summary>
|
|||
|
|
public static bool CompareVersionGe(string left, string right)
|
|||
|
|
{
|
|||
|
|
return CompareVersion(left, right) >= 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 比较两个版本名,若 Left 较新则返回 1,相同则返回 0,Right 较新则返回 -1;等同 Left - Right。
|
|||
|
|
/// 无法比较两个预发布版的大小。
|
|||
|
|
/// 支持的格式:未知版本, 26.1-snapshot-1,1.13.2, 1.7.10-pre4, 1.8_pre, 1.14 Pre-Release 2, 1.14.4 C6
|
|||
|
|
/// </summary>
|
|||
|
|
public static int CompareVersion(string left, string right)
|
|||
|
|
{
|
|||
|
|
if (left == Lang.Text("Minecraft.Version.Unknown") || right == Lang.Text("Minecraft.Version.Unknown"))
|
|||
|
|
{
|
|||
|
|
if (left == Lang.Text("Minecraft.Version.Unknown") && right != Lang.Text("Minecraft.Version.Unknown"))
|
|||
|
|
return 1;
|
|||
|
|
if (left == Lang.Text("Minecraft.Version.Unknown") && right == Lang.Text("Minecraft.Version.Unknown"))
|
|||
|
|
return 0;
|
|||
|
|
if (left != Lang.Text("Minecraft.Version.Unknown") && right == Lang.Text("Minecraft.Version.Unknown"))
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
left = left.ToLowerInvariant();
|
|||
|
|
right = right.ToLowerInvariant();
|
|||
|
|
var lefts = left.Replace("快照", "snapshot").Replace("预览版", "pre").RegexSearch("[a-z]+|[0-9]+");
|
|||
|
|
var rights = right.Replace("快照", "snapshot").Replace("预览版", "pre").RegexSearch("[a-z]+|[0-9]+");
|
|||
|
|
var i = 0;
|
|||
|
|
while (true)
|
|||
|
|
{
|
|||
|
|
// 两边均缺失,感觉是一个东西
|
|||
|
|
if (lefts.Count - 1 < i && rights.Count - 1 < i)
|
|||
|
|
{
|
|||
|
|
if (string.CompareOrdinal(left, right) > 0)
|
|||
|
|
return 1;
|
|||
|
|
if (string.CompareOrdinal(left, right) < 0)
|
|||
|
|
return -1;
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 确定两边的数值
|
|||
|
|
var leftValue = lefts.Count - 1 < i ? "0" : lefts[i];
|
|||
|
|
var rightValue = rights.Count - 1 < i ? "0" : rights[i];
|
|||
|
|
if ((leftValue ?? "") == (rightValue ?? ""))
|
|||
|
|
goto NextEntry;
|
|||
|
|
if (leftValue == "rc")
|
|||
|
|
leftValue = (-1).ToString();
|
|||
|
|
if (leftValue == "pre")
|
|||
|
|
leftValue = (-2).ToString();
|
|||
|
|
if (leftValue == "snapshot")
|
|||
|
|
leftValue = (-3).ToString();
|
|||
|
|
if (leftValue == "experimental")
|
|||
|
|
leftValue = (-4).ToString();
|
|||
|
|
var leftValValue = ModBase.Val(leftValue);
|
|||
|
|
if (rightValue == "rc")
|
|||
|
|
rightValue = (-1).ToString();
|
|||
|
|
if (rightValue == "pre")
|
|||
|
|
rightValue = (-2).ToString();
|
|||
|
|
if (rightValue == "snapshot")
|
|||
|
|
rightValue = (-3).ToString();
|
|||
|
|
if (rightValue == "experimental")
|
|||
|
|
rightValue = (-4).ToString();
|
|||
|
|
var rightValValue = ModBase.Val(rightValue);
|
|||
|
|
if (leftValValue == 0d && rightValValue == 0d)
|
|||
|
|
{
|
|||
|
|
// 如果没有数值则直接比较字符串
|
|||
|
|
if (string.CompareOrdinal(leftValue, rightValue) > 0) return 1;
|
|||
|
|
|
|||
|
|
if (string.CompareOrdinal(leftValue, rightValue) < 0) return -1;
|
|||
|
|
}
|
|||
|
|
// 如果有数值则比较数值
|
|||
|
|
// 这会使得一边是数字一边是字母时数字方更大
|
|||
|
|
else if (leftValValue > rightValValue)
|
|||
|
|
{
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
else if (leftValValue < rightValValue)
|
|||
|
|
{
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
NextEntry: ;
|
|||
|
|
|
|||
|
|
i += 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 比较两个版本名的排序器。
|
|||
|
|
/// </summary>
|
|||
|
|
public class VersionComparer : IComparer<string>
|
|||
|
|
{
|
|||
|
|
public int Compare(string x, string y)
|
|||
|
|
{
|
|||
|
|
return CompareVersion(x, y);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|