2023-11-28 11:27:58 +08:00
using HybridCLR.Editor.UnityBinFileReader ;
using System ;
2022-09-22 08:56:07 +08:00
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.UnityLinker ;
using UnityEngine ;
2023-11-28 11:27:58 +08:00
using UnityFS ;
2024-05-20 11:44:38 +08:00
#if !UNITY_2021_1_OR_NEWER
using UnityEditor.Il2Cpp ;
# endif
2022-09-22 08:56:07 +08:00
namespace HybridCLR.Editor.BuildProcessors
{
public class PatchScriptingAssemblyList :
#if UNITY_ANDROID
IPostGenerateGradleAndroidProject ,
2024-01-04 11:48:30 +08:00
#elif UNITY_OPENHARMONY
UnityEditor . OpenHarmony . IPostGenerateOpenHarmonyProject ,
2022-09-22 08:56:07 +08:00
# endif
IPostprocessBuildWithReport
2022-10-19 14:20:17 +08:00
#if !UNITY_2021_1_OR_NEWER && UNITY_WEBGL
2023-09-28 20:18:22 +08:00
, IIl2CppProcessor
2022-10-19 14:20:17 +08:00
# endif
2023-09-28 20:18:22 +08:00
#if UNITY_PS5
, IUnityLinkerProcessor
# endif
2022-09-22 08:56:07 +08:00
{
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
}
2024-01-04 11:48:30 +08:00
#if UNITY_OPENHARMONY
public void OnPostGenerateOpenHarmonyProject ( string path )
{
OnPostGenerateGradleAndroidProject ( path ) ;
}
# endif
2022-09-22 08:56:07 +08:00
public void OnPostprocessBuild ( BuildReport report )
{
// 如果target为Android,由于已经在OnPostGenerateGradelAndroidProject中处理过,
// 这里不再重复处理
2024-01-04 11:48:30 +08:00
#if !UNITY_ANDROID && !UNITY_WEBGL && !UNITY_OPENHARMONY
2022-09-22 08:56:07 +08:00
PathScriptingAssembilesFile ( report . summary . outputPath ) ;
# endif
}
2023-09-28 20:18:22 +08:00
#if UNITY_PS5
/// <summary>
/// 打包模式如果是 Package 需要在这个阶段提前处理 .json , PC Hosted 和 GP5 模式不受影响
/// </summary>
public string GenerateAdditionalLinkXmlFile ( UnityEditor . Build . Reporting . BuildReport report , UnityEditor . UnityLinker . UnityLinkerBuildPipelineData data )
{
string path = $"{SettingsUtil.ProjectDir}/Library/PlayerDataCache/PS5/Data" ;
PathScriptingAssembilesFile ( path ) ;
return null ;
}
# endif
2023-03-13 09:55:26 +08:00
public void PathScriptingAssembilesFile ( string path )
2022-09-22 08:56:07 +08:00
{
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}" ) ;
}
2023-11-28 11:27:58 +08:00
#if UNITY_2020_1_OR_NEWER
2022-09-22 08:56:07 +08:00
AddHotFixAssembliesToScriptingAssembliesJson ( path ) ;
2023-11-28 11:27:58 +08:00
# else
AddHotFixAssembliesToBinFile ( path ) ;
# endif
2022-09-22 08:56:07 +08:00
}
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 )
{
2023-09-28 20:18:22 +08:00
Debug . LogWarning ( $"can not find file {SettingsUtil.ScriptingAssembliesJsonFile}" ) ;
2022-09-22 08:56:07 +08:00
return ;
}
foreach ( string file in jsonFiles )
{
var patcher = new ScriptingAssembliesJsonPatcher ( ) ;
patcher . Load ( file ) ;
2023-01-11 17:41:44 +08:00
patcher . AddScriptingAssemblies ( SettingsUtil . HotUpdateAssemblyFilesIncludePreserved ) ;
2022-09-22 08:56:07 +08:00
patcher . Save ( file ) ;
}
}
2023-11-28 11:27:58 +08:00
private void AddHotFixAssembliesToBinFile ( string path )
{
2023-11-29 16:09:05 +08:00
#if UNITY_STANDALONE_OSX
path = Path . GetDirectoryName ( path ) ;
# endif
2023-11-28 11:27:58 +08:00
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 . HotUpdateAssemblyFilesIncludePreserved ) ;
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 . HotUpdateAssemblyFilesIncludePreserved ) ;
Debug . Log ( $"[PatchScriptingAssemblyList] patch {binPath}" ) ;
}
return true ;
}
2022-09-22 08:56:07 +08:00
2022-10-19 14:20:17 +08:00
#if UNITY_WEBGL
public void OnBeforeConvertRun ( BuildReport report , Il2CppBuildPipelineData data )
{
PathScriptingAssembilesFile ( $"{SettingsUtil.ProjectDir}/Temp/StagingArea/Data" ) ;
}
# endif
2022-09-22 08:56:07 +08:00
}
}