[refactor] 重构Installer,不再支持从其他版本安装HybridCLR,极大简化了代码。

main
walon 2022-12-06 11:52:47 +08:00
parent 38615500fb
commit 6be8b2671e
5 changed files with 113 additions and 327 deletions

View File

@ -18,45 +18,35 @@ namespace HybridCLR.Editor.Installer
public enum InstallErrorCode
{
Ok,
InvalidUnityInstallPath,
Il2CppInstallPathNotMatchIl2CppBranch,
Il2CppInstallPathNotExists,
NotIl2CppPath,
}
public partial class InstallerController
{
private const string hybridclr_repo_path = "hybridclr_repo";
private const string il2cpp_plus_repo_path = "il2cpp_plus_repo";
private string m_Il2CppInstallDirectory;
public string Il2CppInstallDirectory
{
get
{
return m_Il2CppInstallDirectory;
}
set
{
m_Il2CppInstallDirectory = value?.Replace('\\', '/');
if (!string.IsNullOrEmpty(m_Il2CppInstallDirectory))
{
EditorPrefs.SetString("UnityInstallDirectory", m_Il2CppInstallDirectory);
}
}
}
private string GetIl2CppPlusBranchByUnityVersion(string unityVersion)
{
return unityVersion.Split('.')[0];
}
public int MajorVersion => _curVersion.major;
public string Il2CppBranch => GetIl2CppPlusBranchByUnityVersion(Application.unityVersion);
private UnityVersion _curVersion;
public InstallerController()
{
PrepareIl2CppInstallPath();
_curVersion = ParseUnityVersion(Application.unityVersion);
}
public class UnityVersion
{
public int major;
public int minor1;
public int minor2;
public override string ToString()
{
return $"{major}.{minor1}.{minor2}";
}
}
private static readonly Regex s_unityVersionPat = new Regex(@"(\d+)\.(\d+)\.(\d+)");
@ -65,145 +55,129 @@ namespace HybridCLR.Editor.Installer
public const int min2020_3_CompatibleMinorVersion = 21;
public const int min2021_3_CompatibleMinorVersion = 0;
private bool TryParseMinorVersion(string installDir, out (int Major, int Minor1, int Minor2) unityVersion)
private UnityVersion ParseUnityVersion(string versionStr)
{
var matches = s_unityVersionPat.Matches(installDir);
var matches = s_unityVersionPat.Matches(versionStr);
if (matches.Count == 0)
{
unityVersion = default;
return false;
return null;
}
// 找最后一个匹配的有的人居然会把Unity安装目录放到其他安装版本下。无语
// 找最后一个匹配的
Match match = matches[matches.Count - 1];
// Debug.Log($"capture count:{match.Groups.Count} {match.Groups[1].Value} {match.Groups[2].Value}");
int major = int.Parse(match.Groups[1].Value);
int minor1 = int.Parse(match.Groups[2].Value);
int minor2 = int.Parse(match.Groups[3].Value);
unityVersion = (major, minor1, minor2);
return true;
return new UnityVersion { major = major, minor1 = minor1, minor2 = minor2 };
}
public string GetCurVersionStr(string installDir)
public string GetCurrentUnityVersionMinCompatibleVersionStr()
{
if (TryParseMinorVersion(installDir, out var version))
{
return $"{version.Major}.{version.Minor1}.{version.Minor2}";
}
throw new Exception($"not support version:{installDir}");
return GetMinCompatibleVersion(MajorVersion);
}
public string GetMinCompatibleVersion(string branch)
public string GetMinCompatibleVersion(int majorVersion)
{
switch(branch)
switch(majorVersion)
{
case "2019": return $"2019.4.{min2019_4_CompatibleMinorVersion}";
case "2020": return $"2020.3.{min2020_3_CompatibleMinorVersion}";
case "2021": return $"2021.3.{min2021_3_CompatibleMinorVersion}";
default: throw new Exception($"not support version:{branch}");
case 2019: return $"2019.4.{min2019_4_CompatibleMinorVersion}";
case 2020: return $"2020.3.{min2020_3_CompatibleMinorVersion}";
case 2021: return $"2021.3.{min2021_3_CompatibleMinorVersion}";
default: throw new Exception($"not support version:{majorVersion}");
}
}
private bool IsComaptibleWithIl2CppPlusBranch(string branch, string installDir)
public bool IsComaptibleVersion()
{
if (!TryParseMinorVersion(installDir, out var unityVersion))
UnityVersion version = _curVersion;
switch (version.major)
{
return false;
}
switch(branch)
{
case "2019":
case 2019:
{
if (unityVersion.Major != 2019 || unityVersion.Minor1 != 4)
if (version.major != 2019 || version.minor1 != 4)
{
return false;
}
return unityVersion.Minor2 >= min2019_4_CompatibleMinorVersion;
return version.minor2 >= min2019_4_CompatibleMinorVersion;
}
case "2020":
case 2020:
{
if (unityVersion.Major != 2020 || unityVersion.Minor1 != 3)
if (version.major != 2020 || version.minor1 != 3)
{
return false;
}
return unityVersion.Minor2 >= min2020_3_CompatibleMinorVersion;
return version.minor2 >= min2020_3_CompatibleMinorVersion;
}
case "2021":
case 2021:
{
if (unityVersion.Major != 2021 || unityVersion.Minor1 != 3)
if (version.major != 2021 || version.minor1 != 3)
{
return false;
}
return unityVersion.Minor2 >= min2021_3_CompatibleMinorVersion;
return version.minor2 >= min2021_3_CompatibleMinorVersion;
}
default: throw new Exception($"not support il2cpp_plus branch:{branch}");
default: throw new Exception($"not support il2cpp_plus branch:{version.major}");
}
}
void PrepareIl2CppInstallPath()
{
#if UNITY_EDITOR_WIN
private string _hybridclrLocalVersion;
m_Il2CppInstallDirectory = EditorPrefs.GetString("Il2CppInstallDirectory");
if (CheckValidIl2CppInstallDirectory(Il2CppBranch, m_Il2CppInstallDirectory) == InstallErrorCode.Ok)
public string HybridclrLocalVersion => _hybridclrLocalVersion != null ? _hybridclrLocalVersion : _hybridclrLocalVersion = GetHybridCLRLocalVersion();
private string GetHybridCLRLocalVersion()
{
string workDir = SettingsUtil.HybridCLRDataDir;
string hybridclrRepoDir = $"{workDir}/{hybridclr_repo_path}";
if (Directory.Exists(hybridclrRepoDir))
{
return;
}
var il2cppBranch = Il2CppBranch;
var curAppInstallPath = EditorApplication.applicationPath;
if (IsComaptibleWithIl2CppPlusBranch(il2cppBranch, curAppInstallPath))
{
Il2CppInstallDirectory = $"{Directory.GetParent(curAppInstallPath)}/Data/il2cpp";
return;
}
string unityHubRootDir = Directory.GetParent(curAppInstallPath).Parent.Parent.ToString();
// Debug.Log("unity hub root dir:" + unityHubRootDir);
foreach (var unityInstallDir in Directory.GetDirectories(unityHubRootDir, "*", SearchOption.TopDirectoryOnly))
{
// Debug.Log("Unity install dir:" + unityInstallDir);
if (IsComaptibleWithIl2CppPlusBranch(il2cppBranch, unityInstallDir))
var ret = BashUtil.RunCommand2(hybridclrRepoDir, "git",
new string[] { "log", "HEAD", "-n", "1", "--pretty=format:\"%H\"", },
false);
if (ret.ExitCode == 0)
{
Il2CppInstallDirectory = $"{unityInstallDir}/Editor/Data/il2cpp";
return;
return ret.StdOut.Trim();
}
else
{
return "ERROR";
}
}
Il2CppInstallDirectory = $"{Directory.GetParent(curAppInstallPath)}/Data/il2cpp";
#else
m_Il2CppInstallDirectory = EditorPrefs.GetString("Il2CppInstallDirectory");
if (CheckValidIl2CppInstallDirectory(Il2CppBranch, m_Il2CppInstallDirectory) == InstallErrorCode.Ok)
{
return;
}
var il2cppBranch = Il2CppBranch;
var curAppInstallPath = EditorApplication.applicationPath;
if (IsComaptibleWithIl2CppPlusBranch(il2cppBranch, curAppInstallPath))
{
Il2CppInstallDirectory = $"{curAppInstallPath}/Contents/il2cpp";
return;
}
string unityHubRootDir = Directory.GetParent(curAppInstallPath).Parent.Parent.ToString();
foreach (var unityInstallDir in Directory.GetDirectories(unityHubRootDir, "*", SearchOption.TopDirectoryOnly))
{
Debug.Log("nity install dir:" + unityInstallDir);
if (IsComaptibleWithIl2CppPlusBranch(il2cppBranch, unityInstallDir))
{
Il2CppInstallDirectory = $"{unityInstallDir}/Unity.app/Contents/il2cpp";
return;
}
}
Il2CppInstallDirectory = $"{curAppInstallPath}/Contents/il2cpp";
#endif
return "";
}
public void InitHybridCLR(string il2cppBranch, string il2cppInstallPath, string hybridclrVer, string il2cppPlusVer)
private string _il2cppPlusLocalVersion;
public string Il2cppPlusLocalVersion => _il2cppPlusLocalVersion != null ? _il2cppPlusLocalVersion : _il2cppPlusLocalVersion = GetIl2cppPlusLocalVersion();
private string GetIl2cppPlusLocalVersion()
{
if (CheckValidIl2CppInstallDirectory(il2cppBranch, il2cppInstallPath) != InstallErrorCode.Ok)
string workDir = SettingsUtil.HybridCLRDataDir;
string il2cppPlusRepoDir = $"{workDir}/{il2cpp_plus_repo_path}";
if (Directory.Exists(il2cppPlusRepoDir))
{
Debug.LogError($"请正确设置 il2cpp 安装目录");
return;
var ret = BashUtil.RunCommand2(il2cppPlusRepoDir, "git",
new string[] { "log", "HEAD", "-n", "1", "--pretty=format:\"%H\"", },
false);
if (ret.ExitCode == 0)
{
return ret.StdOut.Trim();
}
else
{
return "ERROR";
}
}
RunInitLocalIl2CppData(il2cppBranch, il2cppInstallPath, hybridclrVer, il2cppPlusVer);
return "";
}
private string GetIl2CppPathByContentPath(string contentPath)
{
return $"{contentPath}/il2cpp";
}
public void InstallLocalHybridCLR(string hybridclrVer, string il2cppPlusVer)
{
RunInitLocalIl2CppData(GetIl2CppPathByContentPath(EditorApplication.applicationContentsPath), _curVersion, hybridclrVer, il2cppPlusVer);
}
public bool HasInstalledHybridCLR()
@ -211,34 +185,6 @@ namespace HybridCLR.Editor.Installer
return Directory.Exists($"{SettingsUtil.LocalIl2CppDir}/libil2cpp/hybridclr");
}
public InstallErrorCode CheckValidIl2CppInstallDirectory(string il2cppBranch, string installDir)
{
installDir = installDir.Replace('\\', '/');
if (!Directory.Exists(installDir))
{
return InstallErrorCode.Il2CppInstallPathNotExists;
}
if (!IsComaptibleWithIl2CppPlusBranch(il2cppBranch, installDir))
{
return TryParseMinorVersion(installDir, out _) ?
InstallErrorCode.Il2CppInstallPathNotMatchIl2CppBranch
: InstallErrorCode.InvalidUnityInstallPath;
}
if (!installDir.EndsWith("/il2cpp"))
{
return InstallErrorCode.NotIl2CppPath;
}
return InstallErrorCode.Ok;
}
public bool IsUnity2019(string branch)
{
return branch.Contains("2019");
}
private string GetUnityIl2CppDllInstallLocation()
{
@ -258,7 +204,7 @@ namespace HybridCLR.Editor.Installer
#endif
}
private void RunInitLocalIl2CppData(string il2cppBranch, string il2cppInstallPath, string hybridclrVer, string il2cppPlusVer)
private void RunInitLocalIl2CppData(string editorIl2cppPath, UnityVersion version, string hybridclrVer, string il2cppPlusVer)
{
#if UNITY_EDITOR_WIN
if (!BashUtil.ExistProgram("git"))
@ -315,7 +261,7 @@ namespace HybridCLR.Editor.Installer
"clone",
"--depth=1",
"-b",
$"{il2cppBranch}-main",
$"{version.major}-main",
il2cppPlusRepoURL,
il2cppPlusRepoDir,
}
@ -341,10 +287,10 @@ namespace HybridCLR.Editor.Installer
BashUtil.RecreateDir(localUnityDataDir);
// copy MonoBleedingEdge
BashUtil.CopyDir($"{Directory.GetParent(il2cppInstallPath)}/MonoBleedingEdge", $"{localUnityDataDir}/MonoBleedingEdge", true);
BashUtil.CopyDir($"{Directory.GetParent(editorIl2cppPath)}/MonoBleedingEdge", $"{localUnityDataDir}/MonoBleedingEdge", true);
// copy il2cpp
BashUtil.CopyDir(Il2CppInstallDirectory, SettingsUtil.LocalIl2CppDir, true);
BashUtil.CopyDir(editorIl2cppPath, SettingsUtil.LocalIl2CppDir, true);
// replace libil2cpp
string dstLibil2cppDir = $"{SettingsUtil.LocalIl2CppDir}/libil2cpp";
@ -354,9 +300,9 @@ namespace HybridCLR.Editor.Installer
// clean Il2cppBuildCache
BashUtil.RemoveDir($"{SettingsUtil.ProjectDir}/Library/Il2cppBuildCache", true);
if (IsUnity2019(il2cppBranch))
if (version.major == 2019)
{
string curVersionStr = GetCurVersionStr(il2cppInstallPath);
string curVersionStr = version.ToString();
string srcIl2CppDll = GetUnityIl2CppDllModifiedPath(curVersionStr);
if (File.Exists(srcIl2CppDll))
{
@ -372,8 +318,8 @@ namespace HybridCLR.Editor.Installer
if (HasInstalledHybridCLR())
{
Debug.Log("安装成功!");
_hybridclrLocalVersion = hybridclrVer;
_il2cppPlusLocalVersion = il2cppPlusVer;
_hybridclrLocalVersion = null;
_il2cppPlusLocalVersion = null;
}
else
{

View File

@ -8,14 +8,14 @@ namespace HybridCLR.Editor.Installer
{
public class InstallerWindow : EditorWindow
{
private InstallerController m_Controller;
private InstallerController _controller;
string _hybridclrVersion = "";
string _il2cppPlusVersion = "";
private void OnEnable()
{
m_Controller = new InstallerController();
_controller = new InstallerController();
}
private void OnGUI()
@ -34,28 +34,22 @@ namespace HybridCLR.Editor.Installer
SettingsService.OpenProjectSettings("Project/HybridCLR Settings");
}
string il2cppBranch = m_Controller.Il2CppBranch;
string minCompatibleVersion = m_Controller.GetMinCompatibleVersion(il2cppBranch);
GUI.enabled = true;
GUILayout.Space(10f);
EditorGUILayout.BeginVertical("box");
bool hasInstall = m_Controller.HasInstalledHybridCLR();
bool hasInstall = _controller.HasInstalledHybridCLR();
EditorGUILayout.LabelField($"安装状态:{(hasInstall ? "" : "")}", EditorStyles.boldLabel);
string hybridclrLocalVersion = m_Controller.HybridclrLocalVersion;
string il2cppPlusLocalVersion = m_Controller.Il2cppPlusLocalVersion;
if (hasInstall)
{
EditorGUILayout.LabelField($"HybridCLR 版本: {hybridclrLocalVersion}");
EditorGUILayout.LabelField($"HybridCLR 版本: {_controller.HybridclrLocalVersion}");
GUILayout.Space(5f);
EditorGUILayout.LabelField($"il2cpp_plus 版本: {il2cppPlusLocalVersion}");
EditorGUILayout.LabelField($"il2cpp_plus 版本: {_controller.Il2cppPlusLocalVersion}");
GUILayout.Space(5f);
//GUIInstallButton("检查更新", "检查", UpdateHybridCLR);
//GUILayout.Space(40f);
}
GUISelectUnityDirectory($"il2cpp_plus分支对应的Unity兼容版本的il2cpp路径", "Select");
GUILayout.Space(10f);
@ -65,97 +59,36 @@ namespace HybridCLR.Editor.Installer
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField($"待安装的 il2cpp_plus 仓库版本号(或branch或tag)(默认取{il2cppBranch}-main分支最新版本):", GUILayout.MaxWidth(400));
EditorGUILayout.LabelField($"待安装的 il2cpp_plus 仓库版本号(或branch或tag)(默认取{_controller.MajorVersion}-main分支最新版本):", GUILayout.MaxWidth(400));
_il2cppPlusVersion = EditorGUILayout.TextField(_il2cppPlusVersion);
EditorGUILayout.EndHorizontal();
GUIInstallButton("安装hybridclr+il2cpp_plus代码到本地目录", "安装", InitHybridCLR);
GUIInstallButton("安装hybridclr+il2cpp_plus代码到本地目录", "安装");
EditorGUILayout.EndVertical();
}
private void GUIInstallButton(string content, string button, Action onClick)
private void GUIInstallButton(string content, string button)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(content);
GUI.enabled = m_Controller.CheckValidIl2CppInstallDirectory(m_Controller.Il2CppBranch, m_Controller.Il2CppInstallDirectory) == InstallErrorCode.Ok;
if (GUILayout.Button(button, GUILayout.Width(100)))
{
onClick?.Invoke();
InstallLocalHybridCLR();
GUIUtility.ExitGUI();
}
GUI.enabled = true;
EditorGUILayout.EndHorizontal();
}
private void GUISelectUnityDirectory(string content, string selectButton)
private void InstallLocalHybridCLR()
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(content, GUILayout.MaxWidth(300));
string il2cppInstallDirectory = m_Controller.Il2CppInstallDirectory = EditorGUILayout.TextField(m_Controller.Il2CppInstallDirectory);
if (GUILayout.Button(selectButton, GUILayout.Width(100)))
if (!_controller.IsComaptibleVersion())
{
string temp = EditorUtility.OpenFolderPanel(content, m_Controller.Il2CppInstallDirectory, string.Empty);
if (!string.IsNullOrEmpty(temp))
{
il2cppInstallDirectory = m_Controller.Il2CppInstallDirectory = temp;
}
}
EditorGUILayout.EndHorizontal();
InstallErrorCode err = m_Controller.CheckValidIl2CppInstallDirectory(m_Controller.Il2CppBranch, il2cppInstallDirectory);
switch (err)
{
case InstallErrorCode.Ok:
{
break;
}
case InstallErrorCode.Il2CppInstallPathNotExists:
{
EditorGUILayout.HelpBox("li2cpp 路径不存在", MessageType.Error);
break;
}
case InstallErrorCode.InvalidUnityInstallPath:
{
EditorGUILayout.HelpBox($"Unity安装目录必须包含版本号否则无法识别版本", MessageType.Error);
break;
}
case InstallErrorCode.Il2CppInstallPathNotMatchIl2CppBranch:
{
EditorGUILayout.HelpBox($"il2cpp 版本不兼容,最小版本为 {m_Controller.GetMinCompatibleVersion(m_Controller.Il2CppBranch)}", MessageType.Error);
break;
}
case InstallErrorCode.NotIl2CppPath:
{
EditorGUILayout.HelpBox($"当前选择的路径不是il2cpp目录必须类似 xxx/il2cpp", MessageType.Error);
break;
}
default: throw new Exception($"not support {err}");
}
}
private void InitHybridCLR()
{
m_Controller.InitHybridCLR(m_Controller.Il2CppBranch, m_Controller.Il2CppInstallDirectory, _hybridclrVersion, _il2cppPlusVersion);
}
private void UpdateHybridCLR()
{
bool hasUpdateIl2Cpp = m_Controller.HasUpdateIl2Cpp(m_Controller.Il2CppBranch);
if (hasUpdateIl2Cpp)
{
bool ret = EditorUtility.DisplayDialog("检查更新", "版本不一致", "更新","取消");
if (ret)
{
InitHybridCLR();
}
}
else
{
EditorUtility.DisplayDialog("检查更新", "暂无更新", "确定");
Debug.LogError($"il2cpp 版本不兼容,最小版本为 {_controller.GetCurrentUnityVersionMinCompatibleVersionStr()}");
return;
}
_controller.InstallLocalHybridCLR(_hybridclrVersion, _il2cppPlusVersion);
}
}
}

View File

@ -1,90 +0,0 @@
using System.IO;
namespace HybridCLR.Editor.Installer
{
public partial class InstallerController
{
private string _hybridclrLocalVersion;
public string HybridclrLocalVersion => _hybridclrLocalVersion != null ? _hybridclrLocalVersion : _hybridclrLocalVersion = GetHybridCLRLocalVersion();
private string GetHybridCLRLocalVersion()
{
string workDir = SettingsUtil.HybridCLRDataDir;
string hybridclrRepoDir = $"{workDir}/{hybridclr_repo_path}";
if (Directory.Exists(hybridclrRepoDir))
{
var ret = BashUtil.RunCommand2(hybridclrRepoDir, "git",
new string[] { "log", "HEAD", "-n", "1", "--pretty=format:\"%H\"", },
false);
if (ret.ExitCode == 0)
{
return ret.StdOut.Trim();
}
else
{
return "ERROR";
}
}
return "";
}
private string _il2cppPlusLocalVersion;
public string Il2cppPlusLocalVersion => _il2cppPlusLocalVersion != null ? _il2cppPlusLocalVersion : _il2cppPlusLocalVersion = GetIl2cppPlusLocalVersion();
private string GetIl2cppPlusLocalVersion()
{
string workDir = SettingsUtil.HybridCLRDataDir;
string il2cppPlusRepoDir = $"{workDir}/{il2cpp_plus_repo_path}";
if (Directory.Exists(il2cppPlusRepoDir))
{
var ret = BashUtil.RunCommand2(il2cppPlusRepoDir, "git",
new string[] { "log", "HEAD", "-n", "1", "--pretty=format:\"%H\"", },
false);
if (ret.ExitCode == 0)
{
return ret.StdOut.Trim();
}
else
{
return "ERROR";
}
}
return "";
}
public bool HasUpdateIl2Cpp(string il2cppBranch)
{
string workDir = SettingsUtil.HybridCLRDataDir;
// last hash hybridclr
{
string hybridclrRepoDir = $"{workDir}/{hybridclr_repo_path}";
var ret1 = BashUtil.RunCommand2(hybridclrRepoDir, "git", new string[] { "log", "HEAD", "-n", "1", "--pretty=format:\"%H\"", }, false);
BashUtil.RunCommand2(hybridclrRepoDir, "git", new string[] { "fetch", "--depth=1" }, false);
var ret2 = BashUtil.RunCommand2(hybridclrRepoDir, "git",
new string[] { "log", "remotes/origin/HEAD", "-n", "1", "--pretty=format:\"%H\"", }
, false);
if (ret1.StdOut != ret2.StdOut)
{
return true;
}
}
// last hash il2cpp_plus
{
string il2cppPlusRepoDir = $"{workDir}/{il2cpp_plus_repo_path}";
var ret1 = BashUtil.RunCommand2(il2cppPlusRepoDir, "git",
new string[] { "log", $"{il2cppBranch}", "-n", "1", "--pretty=format:\"%H\"", }, false);
BashUtil.RunCommand2(il2cppPlusRepoDir, "git",
new string[] { "fetch", "--depth=1" }, false);
var ret2 = BashUtil.RunCommand2(il2cppPlusRepoDir, "git",
new string[] { "log", $"remotes/origin/{il2cppBranch}", "-n", "1", "--pretty=format:\"%H\"", }, false);
if (ret1.StdOut != ret2.StdOut)
{
return true;
}
}
return false;
}
}
}

View File

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 91454a4f0a354d11830642b4d4474d7e
timeCreated: 1665546286

View File

@ -1,6 +1,6 @@
{
"name": "com.focus-creative-games.hybridclr_unity",
"version": "1.1.6",
"version": "1.1.7",
"displayName": "HybridCLR",
"description": "Unity package for HybridCLR. It includes editor and runtime scripts and assets for HybridCLR",
"category": "Runtime",