hybridclr_unity/Editor/Installer/InstallerController.cs

331 lines
12 KiB
C#
Raw Normal View History

2022-09-22 08:56:07 +08:00
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Diagnostics;
using Debug = UnityEngine.Debug;
using System.Text.RegularExpressions;
namespace HybridCLR.Editor.Installer
{
public enum InstallErrorCode
{
Ok,
}
public partial class InstallerController
{
private const string hybridclr_repo_path = "hybridclr_repo";
private const string il2cpp_plus_repo_path = "il2cpp_plus_repo";
2022-09-22 08:56:07 +08:00
public int MajorVersion => _curVersion.major;
2022-09-22 08:56:07 +08:00
private UnityVersion _curVersion;
2022-09-22 08:56:07 +08:00
public InstallerController()
{
_curVersion = ParseUnityVersion(Application.unityVersion);
}
public class UnityVersion
{
public int major;
public int minor1;
public int minor2;
public override string ToString()
{
return $"{major}.{minor1}.{minor2}";
}
2022-09-22 08:56:07 +08:00
}
private static readonly Regex s_unityVersionPat = new Regex(@"(\d+)\.(\d+)\.(\d+)");
public const int min2019_4_CompatibleMinorVersion = 40;
public const int min2020_3_CompatibleMinorVersion = 21;
public const int min2021_3_CompatibleMinorVersion = 0;
private UnityVersion ParseUnityVersion(string versionStr)
2022-09-22 08:56:07 +08:00
{
var matches = s_unityVersionPat.Matches(versionStr);
2022-09-22 08:56:07 +08:00
if (matches.Count == 0)
{
return null;
2022-09-22 08:56:07 +08:00
}
// 找最后一个匹配的
2022-09-22 08:56:07 +08:00
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);
return new UnityVersion { major = major, minor1 = minor1, minor2 = minor2 };
2022-09-22 08:56:07 +08:00
}
public string GetCurrentUnityVersionMinCompatibleVersionStr()
2022-09-22 08:56:07 +08:00
{
return GetMinCompatibleVersion(MajorVersion);
2022-09-22 08:56:07 +08:00
}
public string GetMinCompatibleVersion(int majorVersion)
2022-09-22 08:56:07 +08:00
{
switch(majorVersion)
2022-09-22 08:56:07 +08:00
{
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}");
2022-09-22 08:56:07 +08:00
}
}
public bool IsComaptibleVersion()
2022-09-22 08:56:07 +08:00
{
UnityVersion version = _curVersion;
switch (version.major)
2022-09-22 08:56:07 +08:00
{
case 2019:
2022-09-22 08:56:07 +08:00
{
if (version.major != 2019 || version.minor1 != 4)
2022-09-22 08:56:07 +08:00
{
return false;
}
return version.minor2 >= min2019_4_CompatibleMinorVersion;
2022-09-22 08:56:07 +08:00
}
case 2020:
2022-09-22 08:56:07 +08:00
{
if (version.major != 2020 || version.minor1 != 3)
2022-09-22 08:56:07 +08:00
{
return false;
}
return version.minor2 >= min2020_3_CompatibleMinorVersion;
2022-09-22 08:56:07 +08:00
}
case 2021:
2022-09-22 08:56:07 +08:00
{
if (version.major != 2021 || version.minor1 != 3)
2022-09-22 08:56:07 +08:00
{
return false;
}
return version.minor2 >= min2021_3_CompatibleMinorVersion;
2022-09-22 08:56:07 +08:00
}
default: throw new Exception($"not support il2cpp_plus branch:{version.major}");
2022-09-22 08:56:07 +08:00
}
}
private string _hybridclrLocalVersion;
2022-09-22 08:56:07 +08:00
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))
2022-09-22 08:56:07 +08:00
{
var ret = BashUtil.RunCommand2(hybridclrRepoDir, "git",
new string[] { "log", "HEAD", "-n", "1", "--pretty=format:\"%H\"", },
false);
if (ret.ExitCode == 0)
2022-09-22 08:56:07 +08:00
{
return ret.StdOut.Trim();
2022-09-22 08:56:07 +08:00
}
else
2022-09-22 08:56:07 +08:00
{
return "ERROR";
2022-09-22 08:56:07 +08:00
}
}
return "";
2022-09-22 08:56:07 +08:00
}
private string _il2cppPlusLocalVersion;
public string Il2cppPlusLocalVersion => _il2cppPlusLocalVersion != null ? _il2cppPlusLocalVersion : _il2cppPlusLocalVersion = GetIl2cppPlusLocalVersion();
private string GetIl2cppPlusLocalVersion()
2022-09-22 08:56:07 +08:00
{
string workDir = SettingsUtil.HybridCLRDataDir;
string il2cppPlusRepoDir = $"{workDir}/{il2cpp_plus_repo_path}";
if (Directory.Exists(il2cppPlusRepoDir))
2022-09-22 08:56:07 +08:00
{
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";
}
2022-09-22 08:56:07 +08:00
}
return "";
2022-09-22 08:56:07 +08:00
}
private string GetIl2CppPathByContentPath(string contentPath)
2022-09-22 08:56:07 +08:00
{
return $"{contentPath}/il2cpp";
2022-09-22 08:56:07 +08:00
}
public void InstallLocalHybridCLR(string hybridclrVer, string il2cppPlusVer)
2022-09-22 08:56:07 +08:00
{
RunInitLocalIl2CppData(GetIl2CppPathByContentPath(EditorApplication.applicationContentsPath), _curVersion, hybridclrVer, il2cppPlusVer);
2022-09-22 08:56:07 +08:00
}
public bool HasInstalledHybridCLR()
2022-09-22 08:56:07 +08:00
{
return Directory.Exists($"{SettingsUtil.LocalIl2CppDir}/libil2cpp/hybridclr");
2022-09-22 08:56:07 +08:00
}
private string GetUnityIl2CppDllInstallLocation()
{
#if UNITY_EDITOR_WIN
return $"{SettingsUtil.LocalIl2CppDir}/build/deploy/net471/Unity.IL2CPP.dll";
#else
return $"{SettingsUtil.LocalIl2CppDir}/build/deploy/il2cppcore/Unity.IL2CPP.dll";
#endif
}
private string GetUnityIl2CppDllModifiedPath(string curVersionStr)
{
#if UNITY_EDITOR_WIN
return $"{SettingsUtil.ProjectDir}/{SettingsUtil.HybridCLRDataPathInPackage}/ModifiedUnityAssemblies/{curVersionStr}/Unity.IL2CPP-Win.dll.bytes";
#else
return $"{SettingsUtil.ProjectDir}/{SettingsUtil.HybridCLRDataPathInPackage}/ModifiedUnityAssemblies/{curVersionStr}/Unity.IL2CPP-Mac.dll.bytes";
#endif
}
private void RunInitLocalIl2CppData(string editorIl2cppPath, UnityVersion version, string hybridclrVer, string il2cppPlusVer)
2022-09-22 08:56:07 +08:00
{
#if UNITY_EDITOR_WIN
if (!BashUtil.ExistProgram("git"))
{
throw new Exception($"安装本地il2cpp需要使用git从远程拉取仓库请先安装git");
}
#endif
string workDir = SettingsUtil.HybridCLRDataDir;
Directory.CreateDirectory(workDir);
//BashUtil.RecreateDir(workDir);
string buildiOSDir = $"{workDir}/iOSBuild";
BashUtil.RemoveDir(buildiOSDir);
BashUtil.CopyDir($"{SettingsUtil.HybridCLRDataPathInPackage}/iOSBuild", buildiOSDir, true);
// clone hybridclr
string hybridclrRepoURL = HybridCLRSettings.Instance.hybridclrRepoURL;
string hybridclrRepoDir = $"{workDir}/{hybridclr_repo_path}";
2022-09-22 08:56:07 +08:00
{
BashUtil.RemoveDir(hybridclrRepoDir);
string[] args = string.IsNullOrWhiteSpace(hybridclrVer) ? new string[]
2022-09-22 08:56:07 +08:00
{
"clone",
"--depth=1",
hybridclrRepoURL,
2022-09-22 08:56:07 +08:00
hybridclrRepoDir,
}
:
new string[]
{
"clone",
"--depth=1",
"-b",
hybridclrVer,
hybridclrRepoURL,
hybridclrRepoDir,
};
var ret = BashUtil.RunCommand(workDir, "git", args);
2022-09-22 08:56:07 +08:00
//if (ret != 0)
//{
// throw new Exception($"git clone 失败");
//}
}
// clone il2cpp_plus
string il2cppPlusRepoURL = HybridCLRSettings.Instance.il2cppPlusRepoURL;
string il2cppPlusRepoDir = $"{workDir}/{il2cpp_plus_repo_path}";
2022-09-22 08:56:07 +08:00
{
BashUtil.RemoveDir(il2cppPlusRepoDir);
string[] args = string.IsNullOrWhiteSpace(il2cppPlusVer) ?
new string[]
2022-09-22 08:56:07 +08:00
{
"clone",
"--depth=1",
"-b",
$"{version.major}-main",
il2cppPlusRepoURL,
il2cppPlusRepoDir,
}
:
new string[]
{
"clone",
"--depth=1",
"-b",
il2cppPlusVer,
il2cppPlusRepoURL,
2022-09-22 08:56:07 +08:00
il2cppPlusRepoDir,
};
var ret = BashUtil.RunCommand(workDir, "git", args);
2022-09-22 08:56:07 +08:00
//if (ret != 0)
//{
// throw new Exception($"git clone 失败");
//}
}
// create LocalIl2Cpp
string localUnityDataDir = SettingsUtil.LocalUnityDataDir;
BashUtil.RecreateDir(localUnityDataDir);
// copy MonoBleedingEdge
BashUtil.CopyDir($"{Directory.GetParent(editorIl2cppPath)}/MonoBleedingEdge", $"{localUnityDataDir}/MonoBleedingEdge", true);
2022-09-22 08:56:07 +08:00
// copy il2cpp
BashUtil.CopyDir(editorIl2cppPath, SettingsUtil.LocalIl2CppDir, true);
2022-09-22 08:56:07 +08:00
// replace libil2cpp
string dstLibil2cppDir = $"{SettingsUtil.LocalIl2CppDir}/libil2cpp";
BashUtil.CopyDir($"{il2cppPlusRepoDir}/libil2cpp", dstLibil2cppDir, true);
BashUtil.CopyDir($"{hybridclrRepoDir}/hybridclr", $"{dstLibil2cppDir}/hybridclr", true);
// clean Il2cppBuildCache
BashUtil.RemoveDir($"{SettingsUtil.ProjectDir}/Library/Il2cppBuildCache", true);
if (version.major == 2019)
2022-09-22 08:56:07 +08:00
{
string curVersionStr = version.ToString();
2022-09-22 08:56:07 +08:00
string srcIl2CppDll = GetUnityIl2CppDllModifiedPath(curVersionStr);
if (File.Exists(srcIl2CppDll))
{
string dstIl2CppDll = GetUnityIl2CppDllInstallLocation();
File.Copy(srcIl2CppDll, dstIl2CppDll, true);
Debug.Log($"copy {srcIl2CppDll} => {dstIl2CppDll}");
}
else
{
Debug.LogError($"未找到当前版本:{curVersionStr} 对应的改造过的 Unity.IL2CPP.dll打包出的程序将会崩溃");
}
}
if (HasInstalledHybridCLR())
{
Debug.Log("安装成功!");
_hybridclrLocalVersion = null;
_il2cppPlusLocalVersion = null;
2022-09-22 08:56:07 +08:00
}
else
{
Debug.LogError("安装失败!");
}
}
}
}