2022-09-22 08:56:07 +08:00
using HybridCLR.Editor.UnityBinFileReader ;
using System ;
using System.Collections.Generic ;
using System.IO ;
using System.Linq ;
using System.Text ;
using System.Threading.Tasks ;
using UnityEditor ;
using UnityEditor.Android ;
using UnityEditor.Build ;
using UnityEditor.Build.Reporting ;
using UnityEditor.Il2Cpp ;
using UnityEditor.UnityLinker ;
using UnityEngine ;
using UnityFS ;
namespace HybridCLR.Editor.BuildProcessors
{
public class PatchScriptingAssemblyList :
#if UNITY_ANDROID
IPostGenerateGradleAndroidProject ,
# endif
IPostprocessBuildWithReport
{
public int callbackOrder = > 0 ;
public void OnPostGenerateGradleAndroidProject ( string path )
{
// 如果直接打包apk, 没有机会在PostprocessBuild中修改ScriptingAssemblies.json。
// 因此需要在这个时机处理
2022-09-22 11:20:47 +08:00
// Unity有bug, 偶然情况下会传入apk的路径, 导致替换失败
if ( Directory . Exists ( path ) )
{
PathScriptingAssembilesFile ( path ) ;
}
else
{
PathScriptingAssembilesFile ( $"{SettingsUtil.ProjectDir}/Library" ) ;
}
2022-09-22 08:56:07 +08:00
}
public void OnPostprocessBuild ( BuildReport report )
{
// 如果target为Android,由于已经在OnPostGenerateGradelAndroidProject中处理过,
// 这里不再重复处理
#if !UNITY_ANDROID
PathScriptingAssembilesFile ( report . summary . outputPath ) ;
# endif
}
private void PathScriptingAssembilesFile ( string path )
{
if ( ! SettingsUtil . Enable )
{
Debug . Log ( $"[PatchScriptingAssemblyList] disabled" ) ;
return ;
}
Debug . Log ( $"[PatchScriptingAssemblyList]. path:{path}" ) ;
if ( ! Directory . Exists ( path ) )
{
path = Path . GetDirectoryName ( path ) ;
Debug . Log ( $"[PatchScriptingAssemblyList] get path parent:{path}" ) ;
}
#if UNITY_2020_1_OR_NEWER
AddHotFixAssembliesToScriptingAssembliesJson ( path ) ;
# else
AddHotFixAssembliesToBinFile ( path ) ;
# endif
}
private void AddHotFixAssembliesToScriptingAssembliesJson ( string path )
{
Debug . Log ( $"[PatchScriptingAssemblyList]. path:{path}" ) ;
/ *
* ScriptingAssemblies . json 文 件 中 记 录 了 所 有 的 dll 名 称 , 此 列 表 在 游 戏 启 动 时 自 动 加 载 ,
* 不 在 此 列 表 中 的 dll 在 资 源 反 序 列 化 时 无 法 被 找 到 其 类 型
* 因 此 OnFilterAssemblies 中 移 除 的 条 目 需 要 再 加 回 来
* /
string [ ] jsonFiles = Directory . GetFiles ( path , SettingsUtil . ScriptingAssembliesJsonFile , SearchOption . AllDirectories ) ;
if ( jsonFiles . Length = = 0 )
{
Debug . LogError ( $"can not find file {SettingsUtil.ScriptingAssembliesJsonFile}" ) ;
return ;
}
foreach ( string file in jsonFiles )
{
var patcher = new ScriptingAssembliesJsonPatcher ( ) ;
patcher . Load ( file ) ;
patcher . AddScriptingAssemblies ( SettingsUtil . HotUpdateAssemblyFiles ) ;
patcher . Save ( file ) ;
}
}
private void AddHotFixAssembliesToBinFile ( string path )
{
if ( AddHotFixAssembliesToGlobalgamemanagers ( path ) )
{
return ;
}
if ( AddHotFixAssembliesTodataunity3d ( path ) )
{
return ;
}
Debug . LogError ( $"[PatchScriptingAssemblyList] can not find file '{SettingsUtil.GlobalgamemanagersBinFile}' or '{SettingsUtil.Dataunity3dBinFile}' in '{path}'" ) ;
}
private bool AddHotFixAssembliesToGlobalgamemanagers ( string path )
{
string [ ] binFiles = Directory . GetFiles ( path , SettingsUtil . GlobalgamemanagersBinFile , SearchOption . AllDirectories ) ;
if ( binFiles . Length = = 0 )
{
return false ;
}
foreach ( string binPath in binFiles )
{
var binFile = new UnityBinFile ( ) ;
binFile . Load ( binPath ) ;
binFile . AddScriptingAssemblies ( SettingsUtil . HotUpdateAssemblyFiles ) ;
binFile . Save ( binPath ) ;
Debug . Log ( $"[PatchScriptingAssemblyList] patch {binPath}" ) ;
}
return true ;
}
private bool AddHotFixAssembliesTodataunity3d ( string path )
{
string [ ] binFiles = Directory . GetFiles ( path , SettingsUtil . Dataunity3dBinFile , SearchOption . AllDirectories ) ;
if ( binFiles . Length = = 0 )
{
return false ;
}
foreach ( string binPath in binFiles )
{
var patcher = new Dataunity3dPatcher ( ) ;
patcher . ApplyPatch ( binPath , SettingsUtil . HotUpdateAssemblyFiles ) ;
Debug . Log ( $"[PatchScriptingAssemblyList] patch {binPath}" ) ;
}
return true ;
}
}
}