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,
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-26 13:11:38 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class InstallerController
|
2022-09-22 08:56:07 +08:00
|
|
|
|
{
|
2022-10-25 17:26:21 +08:00
|
|
|
|
private const string hybridclr_repo_path = "hybridclr_repo";
|
2022-12-06 11:52:47 +08:00
|
|
|
|
|
2022-10-25 17:26:21 +08:00
|
|
|
|
private const string il2cpp_plus_repo_path = "il2cpp_plus_repo";
|
2022-09-22 08:56:07 +08:00
|
|
|
|
|
2022-12-06 11:52:47 +08:00
|
|
|
|
public int MajorVersion => _curVersion.major;
|
2022-09-22 08:56:07 +08:00
|
|
|
|
|
2023-01-26 13:11:38 +08:00
|
|
|
|
private readonly UnityVersion _curVersion;
|
|
|
|
|
|
|
|
|
|
private readonly HybridclrVersionManifest _versionManifest;
|
|
|
|
|
private readonly HybridclrVersionInfo _curDefaultVersion;
|
2022-09-22 08:56:07 +08:00
|
|
|
|
|
|
|
|
|
public InstallerController()
|
|
|
|
|
{
|
2022-12-06 11:52:47 +08:00
|
|
|
|
_curVersion = ParseUnityVersion(Application.unityVersion);
|
2023-01-26 13:11:38 +08:00
|
|
|
|
_versionManifest = GetHybridCLRVersionManifest();
|
|
|
|
|
_curDefaultVersion = _versionManifest.versions.Find(v => v.unity_version == _curVersion.major.ToString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private HybridclrVersionManifest GetHybridCLRVersionManifest()
|
|
|
|
|
{
|
|
|
|
|
string versionFile = $"{SettingsUtil.ProjectDir}/{SettingsUtil.HybridCLRDataPathInPackage}/hybridclr_version.json";
|
|
|
|
|
return JsonUtility.FromJson<HybridclrVersionManifest>(File.ReadAllText(versionFile, Encoding.UTF8));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
class VersionDesc
|
|
|
|
|
{
|
|
|
|
|
public string branch;
|
|
|
|
|
|
|
|
|
|
public string hash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
class HybridclrVersionInfo
|
|
|
|
|
{
|
|
|
|
|
public string unity_version;
|
|
|
|
|
|
|
|
|
|
public VersionDesc hybridclr;
|
|
|
|
|
|
|
|
|
|
public VersionDesc il2cpp_plus;
|
2022-12-06 11:52:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-01-26 13:11:38 +08:00
|
|
|
|
[Serializable]
|
|
|
|
|
class HybridclrVersionManifest
|
|
|
|
|
{
|
|
|
|
|
public List<HybridclrVersionInfo> versions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private class UnityVersion
|
2022-12-06 11:52:47 +08:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2022-12-06 11:52:47 +08:00
|
|
|
|
private UnityVersion ParseUnityVersion(string versionStr)
|
2022-09-22 08:56:07 +08:00
|
|
|
|
{
|
2022-12-06 11:52:47 +08:00
|
|
|
|
var matches = s_unityVersionPat.Matches(versionStr);
|
2022-09-22 08:56:07 +08:00
|
|
|
|
if (matches.Count == 0)
|
|
|
|
|
{
|
2022-12-06 11:52:47 +08:00
|
|
|
|
return null;
|
2022-09-22 08:56:07 +08:00
|
|
|
|
}
|
2022-12-06 11:52:47 +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);
|
2022-12-06 11:52:47 +08:00
|
|
|
|
return new UnityVersion { major = major, minor1 = minor1, minor2 = minor2 };
|
2022-09-22 08:56:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-12-06 11:52:47 +08:00
|
|
|
|
public string GetCurrentUnityVersionMinCompatibleVersionStr()
|
2022-09-22 08:56:07 +08:00
|
|
|
|
{
|
2022-12-06 11:52:47 +08:00
|
|
|
|
return GetMinCompatibleVersion(MajorVersion);
|
2022-09-22 08:56:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-12-06 11:52:47 +08:00
|
|
|
|
public string GetMinCompatibleVersion(int majorVersion)
|
2022-09-22 08:56:07 +08:00
|
|
|
|
{
|
2022-12-06 11:52:47 +08:00
|
|
|
|
switch(majorVersion)
|
2022-09-22 08:56:07 +08:00
|
|
|
|
{
|
2022-12-06 11:52:47 +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
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-06 11:52:47 +08:00
|
|
|
|
public bool IsComaptibleVersion()
|
2022-09-22 08:56:07 +08:00
|
|
|
|
{
|
2022-12-06 11:52:47 +08:00
|
|
|
|
UnityVersion version = _curVersion;
|
|
|
|
|
switch (version.major)
|
2022-09-22 08:56:07 +08:00
|
|
|
|
{
|
2022-12-06 11:52:47 +08:00
|
|
|
|
case 2019:
|
2022-09-22 08:56:07 +08:00
|
|
|
|
{
|
2022-12-06 11:52:47 +08:00
|
|
|
|
if (version.major != 2019 || version.minor1 != 4)
|
2022-09-22 08:56:07 +08:00
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-12-06 11:52:47 +08:00
|
|
|
|
return version.minor2 >= min2019_4_CompatibleMinorVersion;
|
2022-09-22 08:56:07 +08:00
|
|
|
|
}
|
2022-12-06 11:52:47 +08:00
|
|
|
|
case 2020:
|
2022-09-22 08:56:07 +08:00
|
|
|
|
{
|
2022-12-06 11:52:47 +08:00
|
|
|
|
if (version.major != 2020 || version.minor1 != 3)
|
2022-09-22 08:56:07 +08:00
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-12-06 11:52:47 +08:00
|
|
|
|
return version.minor2 >= min2020_3_CompatibleMinorVersion;
|
2022-09-22 08:56:07 +08:00
|
|
|
|
}
|
2022-12-06 11:52:47 +08:00
|
|
|
|
case 2021:
|
2022-09-22 08:56:07 +08:00
|
|
|
|
{
|
2022-12-06 11:52:47 +08:00
|
|
|
|
if (version.major != 2021 || version.minor1 != 3)
|
2022-09-22 08:56:07 +08:00
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-12-06 11:52:47 +08:00
|
|
|
|
return version.minor2 >= min2021_3_CompatibleMinorVersion;
|
2022-09-22 08:56:07 +08:00
|
|
|
|
}
|
2022-12-06 11:52:47 +08:00
|
|
|
|
default: throw new Exception($"not support il2cpp_plus branch:{version.major}");
|
2022-09-22 08:56:07 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-26 13:11:38 +08:00
|
|
|
|
public string HybridclrLocalVersion => _curDefaultVersion.hybridclr.hash;
|
2022-12-06 18:57:48 +08:00
|
|
|
|
|
2023-01-26 13:11:38 +08:00
|
|
|
|
public string Il2cppPlusLocalVersion => _curDefaultVersion.il2cpp_plus.hash;
|
2022-12-06 18:57:48 +08:00
|
|
|
|
|
|
|
|
|
|
2023-01-26 13:11:38 +08:00
|
|
|
|
private string GetIl2CppPathByContentPath(string contentPath)
|
2022-12-06 11:52:47 +08:00
|
|
|
|
{
|
2023-01-26 13:11:38 +08:00
|
|
|
|
return $"{contentPath}/il2cpp";
|
2022-09-22 08:56:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-12-06 11:52:47 +08:00
|
|
|
|
|
2023-01-26 13:11:38 +08:00
|
|
|
|
public void InstallDefaultHybridCLR()
|
2022-09-22 08:56:07 +08:00
|
|
|
|
{
|
2023-01-26 13:11:38 +08:00
|
|
|
|
InstallLocalHybridCLR(HybridclrLocalVersion, Il2cppPlusLocalVersion);
|
2022-09-22 08:56:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-12-06 11:52:47 +08:00
|
|
|
|
public void InstallLocalHybridCLR(string hybridclrVer, string il2cppPlusVer)
|
2022-09-22 08:56:07 +08:00
|
|
|
|
{
|
2022-12-06 11:52:47 +08:00
|
|
|
|
RunInitLocalIl2CppData(GetIl2CppPathByContentPath(EditorApplication.applicationContentsPath), _curVersion, hybridclrVer, il2cppPlusVer);
|
2022-09-22 08:56:07 +08:00
|
|
|
|
}
|
2022-12-06 11:52:47 +08:00
|
|
|
|
|
|
|
|
|
public bool HasInstalledHybridCLR()
|
2022-09-22 08:56:07 +08:00
|
|
|
|
{
|
2022-12-06 11:52:47 +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
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-26 13:11:38 +08:00
|
|
|
|
void CloneSpeicificCommitId(string workDir, string repoUrl, string branch, string repoDir, string commitId)
|
|
|
|
|
{
|
|
|
|
|
BashUtil.RemoveDir(repoDir);
|
|
|
|
|
BashUtil.RunCommand(workDir, "git", new string[] {"clone", "-b", branch, repoUrl, repoDir});
|
|
|
|
|
BashUtil.RunCommand($"{repoDir}", "git", new string[] { "checkout", commitId });
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-06 11:52:47 +08:00
|
|
|
|
private void RunInitLocalIl2CppData(string editorIl2cppPath, UnityVersion version, string hybridclrVer, string il2cppPlusVer)
|
2022-09-22 08:56:07 +08:00
|
|
|
|
{
|
2023-01-26 13:11:38 +08:00
|
|
|
|
if (!IsComaptibleVersion())
|
|
|
|
|
{
|
|
|
|
|
Debug.LogError($"il2cpp 版本不兼容,最小版本为 {GetCurrentUnityVersionMinCompatibleVersionStr()}");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-09-22 08:56:07 +08:00
|
|
|
|
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
|
2022-11-28 12:20:52 +08:00
|
|
|
|
string hybridclrRepoURL = HybridCLRSettings.Instance.hybridclrRepoURL;
|
2022-10-25 17:26:21 +08:00
|
|
|
|
string hybridclrRepoDir = $"{workDir}/{hybridclr_repo_path}";
|
2023-01-26 13:11:38 +08:00
|
|
|
|
CloneSpeicificCommitId(workDir, hybridclrRepoURL, _curDefaultVersion.hybridclr.branch, hybridclrRepoDir, hybridclrVer);
|
2022-09-22 08:56:07 +08:00
|
|
|
|
|
|
|
|
|
// clone il2cpp_plus
|
2022-11-28 12:20:52 +08:00
|
|
|
|
string il2cppPlusRepoURL = HybridCLRSettings.Instance.il2cppPlusRepoURL;
|
2022-10-25 17:26:21 +08:00
|
|
|
|
string il2cppPlusRepoDir = $"{workDir}/{il2cpp_plus_repo_path}";
|
2023-01-26 13:11:38 +08:00
|
|
|
|
CloneSpeicificCommitId(workDir, il2cppPlusRepoURL, _curDefaultVersion.il2cpp_plus.branch, il2cppPlusRepoDir, il2cppPlusVer);
|
2022-09-22 08:56:07 +08:00
|
|
|
|
|
|
|
|
|
// create LocalIl2Cpp
|
|
|
|
|
string localUnityDataDir = SettingsUtil.LocalUnityDataDir;
|
|
|
|
|
BashUtil.RecreateDir(localUnityDataDir);
|
|
|
|
|
|
|
|
|
|
// copy MonoBleedingEdge
|
2022-12-06 11:52:47 +08:00
|
|
|
|
BashUtil.CopyDir($"{Directory.GetParent(editorIl2cppPath)}/MonoBleedingEdge", $"{localUnityDataDir}/MonoBleedingEdge", true);
|
2022-09-22 08:56:07 +08:00
|
|
|
|
|
|
|
|
|
// copy il2cpp
|
2022-12-06 11:52:47 +08:00
|
|
|
|
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);
|
|
|
|
|
|
2022-12-06 11:52:47 +08:00
|
|
|
|
if (version.major == 2019)
|
2022-09-22 08:56:07 +08:00
|
|
|
|
{
|
2022-12-06 11:52:47 +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,打包出的程序将会崩溃");
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-01-26 13:11:38 +08:00
|
|
|
|
if (version.major >= 2021)
|
|
|
|
|
{
|
|
|
|
|
Debug.LogError($"如果需要打包iOS,必须手动替换UnityEditor.CoreModule.dll为修改后的版本,否则无法获得AOT dlls。详见 https://focus-creative-games.github.io/hybridclr/modify_unity_dll/#unityeditor-coremodule-dll");
|
|
|
|
|
}
|
2022-09-22 08:56:07 +08:00
|
|
|
|
if (HasInstalledHybridCLR())
|
|
|
|
|
{
|
2023-01-26 13:11:38 +08:00
|
|
|
|
Debug.Log("安装成功");
|
2022-09-22 08:56:07 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-01-26 13:11:38 +08:00
|
|
|
|
Debug.LogError("安装失败");
|
2022-09-22 08:56:07 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|