parent
bbb43c3185
commit
6909c32a0c
|
@ -0,0 +1,277 @@
|
||||||
|
#if ENABLE_HOOK_TEST_CASE
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEditor.Callbacks;
|
||||||
|
using UnityEngine;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace MonoHook.Test
|
||||||
|
{
|
||||||
|
// 有需求时可以打开,也可以手动按需注册Hook
|
||||||
|
[InitializeOnLoad]
|
||||||
|
public class BuildPipeline_StripDll_HookTest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 裁剪执行完毕的回调,可能会被调用多次,一般而言同一次打包只需要处理第一次回调
|
||||||
|
/// </summary>
|
||||||
|
public static Action<string, BuildPostProcessArgs, BeeDriverResult> OnAssemblyStripped;
|
||||||
|
|
||||||
|
// 尝试 Hook 4个函数,至少一个被调用就可以达到要求
|
||||||
|
private static MethodHook _hook_PostprocessBuildPlayer_CompleteBuild;
|
||||||
|
private static MethodHook _hook_Default_PostProcess;
|
||||||
|
private static MethodHook _hook_ReportBuildResults;
|
||||||
|
private static MethodHook _hook_StripAssembliesTo;
|
||||||
|
|
||||||
|
#region Fake Internal Structures
|
||||||
|
public struct BuildPostProcessArgs
|
||||||
|
{
|
||||||
|
public BuildTarget target;
|
||||||
|
public int subTarget;
|
||||||
|
public string stagingArea;
|
||||||
|
public string stagingAreaData;
|
||||||
|
public string stagingAreaDataManaged;
|
||||||
|
public string playerPackage;
|
||||||
|
public string installPath;
|
||||||
|
public string companyName;
|
||||||
|
public string productName;
|
||||||
|
public Guid productGUID;
|
||||||
|
public BuildOptions options;
|
||||||
|
public UnityEditor.Build.Reporting.BuildReport report;
|
||||||
|
internal /*RuntimeClassRegistry*/object usedClassRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class BeeDriverResult
|
||||||
|
{
|
||||||
|
public /*NodeResult*/object[] NodeResults { get; set; }
|
||||||
|
public bool Success { get; set; }
|
||||||
|
public /*Message*/object[] BeeDriverMessages { get; set; }
|
||||||
|
public override string ToString() => Success.ToString();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
static BuildPipeline_StripDll_HookTest()
|
||||||
|
{
|
||||||
|
InstallHook();
|
||||||
|
#if ENABLE_HOOK_TEST_CASE
|
||||||
|
OnAssemblyStripped = DemoStripCallback;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 示例裁剪回调函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="outputFolder"></param>
|
||||||
|
/// <param name="args"></param>
|
||||||
|
/// <param name="result"></param>
|
||||||
|
static void DemoStripCallback(string outputFolder, BuildPostProcessArgs args, BeeDriverResult result)
|
||||||
|
{
|
||||||
|
if (outputFolder != null)
|
||||||
|
Debug.Log($"stripped outputFolder is:{outputFolder}");
|
||||||
|
else if (args.stagingAreaDataManaged != null)
|
||||||
|
Debug.Log($"stripped staging folder is:{args.stagingAreaDataManaged}");
|
||||||
|
else if (result != null)
|
||||||
|
Debug.Log($"stripped result is: {result.Success}");
|
||||||
|
else
|
||||||
|
Debug.Log("stripped test called");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void InstallHook()
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Type type = Type.GetType("UnityEditor.PostprocessBuildPlayer,UnityEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
|
||||||
|
if (type == null)
|
||||||
|
{
|
||||||
|
Debug.LogError($"can not find type: UnityEditor.PostprocessBuildPlayer");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodInfo miTarget = type.GetMethod("PostProcessCompletedBuild", BindingFlags.Static | BindingFlags.Public);
|
||||||
|
|
||||||
|
if (miTarget == null)
|
||||||
|
{
|
||||||
|
Debug.LogError($"can not find method: UnityEditor.PostprocessBuildPlayer.PostProcessCompletedBuild");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodInfo miReplace = typeof(BuildPipeline_StripDll_HookTest).GetMethod(nameof(PostprocessBuildPlayer_CompleteBuild_Replace), BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
MethodInfo miProxy = typeof(BuildPipeline_StripDll_HookTest).GetMethod(nameof(PostprocessBuildPlayer_CompleteBuild_Proxy), BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
|
||||||
|
_hook_PostprocessBuildPlayer_CompleteBuild = new MethodHook(miTarget, miReplace, miProxy);
|
||||||
|
_hook_PostprocessBuildPlayer_CompleteBuild.Install();
|
||||||
|
|
||||||
|
Debug.Log("Hook BuildPipeline_StripDll_HookTest.PostprocessBuildPlayer_CompleteBuild installed");
|
||||||
|
} while (false);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Type type = Type.GetType("UnityEditor.Modules.DefaultBuildPostprocessor,UnityEditor.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
|
||||||
|
if (type == null)
|
||||||
|
{
|
||||||
|
Debug.LogError($"can not find type: UnityEditor.Modules.DefaultBuildPostprocessor");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodInfo[] miTargets = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
|
||||||
|
MethodInfo miTarget = (from mi in miTargets where mi.Name == "PostProcess" && mi.GetParameters().Length == 2 select mi).FirstOrDefault();
|
||||||
|
|
||||||
|
if (miTarget == null)
|
||||||
|
{
|
||||||
|
Debug.LogError($"can not find method: UnityEditor.Modules.DefaultBuildPostprocessor.PostProcess");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodInfo miReplace = typeof(BuildPipeline_StripDll_HookTest).GetMethod(nameof(Default_PostProcess_Replace), BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
MethodInfo miProxy = typeof(BuildPipeline_StripDll_HookTest).GetMethod(nameof(Default_PostProcess_Proxy), BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
|
||||||
|
_hook_Default_PostProcess = new MethodHook(miTarget, miReplace, miProxy);
|
||||||
|
_hook_Default_PostProcess.Install();
|
||||||
|
|
||||||
|
Debug.Log("Hook BuildPipeline_StripDll_HookTest.PostProcess installed");
|
||||||
|
} while (false);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Type type = Type.GetType("UnityEditor.Modules.BeeBuildPostprocessor,UnityEditor.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
|
||||||
|
if (type == null)
|
||||||
|
{
|
||||||
|
Debug.LogError($"can not find type: UnityEditor.Modules.BeeBuildPostprocessor");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodInfo miTarget = type.GetMethod("ReportBuildResults", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
if (miTarget == null)
|
||||||
|
{
|
||||||
|
Debug.LogError($"can not find method: UnityEditor.Modules.BeeBuildPostprocessor.ReportBuildResults");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodInfo miReplace = typeof(BuildPipeline_StripDll_HookTest).GetMethod(nameof(ReportBuildResults_Replace), BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
MethodInfo miProxy = typeof(BuildPipeline_StripDll_HookTest).GetMethod(nameof(ReportBuildResults_Proxy), BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
|
||||||
|
_hook_ReportBuildResults = new MethodHook(miTarget, miReplace, miProxy);
|
||||||
|
_hook_ReportBuildResults.Install();
|
||||||
|
|
||||||
|
Debug.Log("Hook BuildPipeline_StripDll_HookTest.ReportBuildResults installed");
|
||||||
|
} while (false);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Type type = Type.GetType("UnityEditorInternal.AssemblyStripper,UnityEditor.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
|
||||||
|
if (type == null)
|
||||||
|
{
|
||||||
|
Debug.LogError($"can not find type: UnityEditorInternal.AssemblyStripper");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodInfo miTarget = type.GetMethod("StripAssembliesTo", BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
if (miTarget == null)
|
||||||
|
{
|
||||||
|
Debug.LogError($"can not find method: UnityEditorInternal.AssemblyStripper.StripAssembliesTo");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodInfo miReplace = typeof(BuildPipeline_StripDll_HookTest).GetMethod(nameof(StripAssembliesTo_Replace), BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
MethodInfo miProxy = typeof(BuildPipeline_StripDll_HookTest).GetMethod(nameof(StripAssembliesTo_Proxy), BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
|
||||||
|
_hook_StripAssembliesTo = new MethodHook(miTarget, miReplace, miProxy);
|
||||||
|
_hook_StripAssembliesTo.Install();
|
||||||
|
|
||||||
|
Debug.Log("Hook BuildPipeline_StripDll_HookTest.StripAssembliesTo installed");
|
||||||
|
} while (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UninstallHook()
|
||||||
|
{
|
||||||
|
_hook_PostprocessBuildPlayer_CompleteBuild?.Uninstall();
|
||||||
|
_hook_Default_PostProcess?.Uninstall();
|
||||||
|
_hook_ReportBuildResults?.Uninstall();
|
||||||
|
_hook_StripAssembliesTo?.Uninstall();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PostprocessBuildPlayer_CompleteBuild_Replace(BuildPostProcessArgs args)
|
||||||
|
{
|
||||||
|
Debug.Log("PostprocessBuildPlayer_CompleteBuild_Replace called");
|
||||||
|
|
||||||
|
OnAssemblyStripped?.Invoke(null, args, null);
|
||||||
|
PostprocessBuildPlayer_CompleteBuild_Proxy(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Default_PostProcess_Replace(object obj, BuildPostProcessArgs args, out /*BuildProperties*/ object outProperties)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 注意:此函数中途可能会被 Unity throw Exception
|
||||||
|
Default_PostProcess_Proxy(obj, args, out outProperties);
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Debug.Log("PostProcess_Replace called");
|
||||||
|
OnAssemblyStripped?.Invoke(null, args, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ReportBuildResults_Replace(object obj, BeeDriverResult result)
|
||||||
|
{
|
||||||
|
// TODO: 可以在这里把 Library\Bee\artifacts\WinPlayerBuildProgram\ManagedStripped 目录下的文件复制出来
|
||||||
|
Debug.Log("ReportBuildResults_Replace called");
|
||||||
|
|
||||||
|
OnAssemblyStripped?.Invoke(null, default(BuildPostProcessArgs), result);
|
||||||
|
ReportBuildResults_Proxy(obj, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool StripAssembliesTo_Replace(string outputFolder, out string output, out string error, IEnumerable<string> linkXmlFiles, /*UnityLinkerRunInformation*/ object runInformation)
|
||||||
|
{
|
||||||
|
bool ret = StripAssembliesTo_Proxy(outputFolder, out output, out error, linkXmlFiles, runInformation);
|
||||||
|
|
||||||
|
// TODO: 可以在这里把 Temp\StagingArea\Data\Managed\tempStrip 目录下的文件复制出来
|
||||||
|
Debug.Log("StripAssembliesTo_Replace called");
|
||||||
|
|
||||||
|
OnAssemblyStripped?.Invoke(outputFolder, default(BuildPostProcessArgs), null);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Proxy Methods
|
||||||
|
[MethodImpl(MethodImplOptions.NoOptimization)]
|
||||||
|
static void PostprocessBuildPlayer_CompleteBuild_Proxy(BuildPostProcessArgs args)
|
||||||
|
{
|
||||||
|
Debug.Log("dummy code" + 200);
|
||||||
|
Debug.Log(args.companyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoOptimization)]
|
||||||
|
static void Default_PostProcess_Proxy(object obj, BuildPostProcessArgs args, out /*BuildProperties*/ object outProperties)
|
||||||
|
{
|
||||||
|
Debug.Log("dummy code" + 100);
|
||||||
|
outProperties = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoOptimization)]
|
||||||
|
static void ReportBuildResults_Proxy(object obj, /*BeeDriverResult*/ object result)
|
||||||
|
{
|
||||||
|
// dummy code
|
||||||
|
Debug.Log("something" + obj.ToString() + result.ToString() + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoOptimization)]
|
||||||
|
static bool StripAssembliesTo_Proxy(string outputFolder, out string output, out string error, IEnumerable<string> linkXmlFiles, /*UnityLinkerRunInformation*/ object runInformation)
|
||||||
|
{
|
||||||
|
Debug.Log("StripAssembliesTo_Proxy called");
|
||||||
|
output = null;
|
||||||
|
error = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ed8859610137d404e87f332b7082c19b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,55 @@
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using MonoHook;
|
||||||
|
using HybridCLR.Editor.BuildProcessors;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace HybridCLR.MonoHook
|
||||||
|
{
|
||||||
|
#if UNITY_2021_1_OR_NEWER && UNITY_WEBGL
|
||||||
|
[InitializeOnLoad]
|
||||||
|
public class PatchScriptingAssembliesJsonHook
|
||||||
|
{
|
||||||
|
private static MethodHook _hook;
|
||||||
|
|
||||||
|
static PatchScriptingAssembliesJsonHook()
|
||||||
|
{
|
||||||
|
if (_hook == null)
|
||||||
|
{
|
||||||
|
Type type = typeof(UnityEditor.EditorApplication);
|
||||||
|
MethodInfo miTarget = type.GetMethod("BuildMainWindowTitle", BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
|
||||||
|
MethodInfo miReplacement = new Func<string>(BuildMainWindowTitle).Method;
|
||||||
|
MethodInfo miProxy = new Func<string>(BuildMainWindowTitleProxy).Method;
|
||||||
|
|
||||||
|
_hook = new MethodHook(miTarget, miReplacement, miProxy);
|
||||||
|
_hook.Install();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string BuildMainWindowTitle()
|
||||||
|
{
|
||||||
|
string tempJsonPath = $"{Application.dataPath}/../Library/PlayerDataCache/WebGL/Data/ScriptingAssemblies.json";
|
||||||
|
if (File.Exists(tempJsonPath))
|
||||||
|
{
|
||||||
|
var patcher = new PatchScriptingAssemblyList();
|
||||||
|
patcher.PathScriptingAssembilesFile(Path.GetDirectoryName(tempJsonPath));
|
||||||
|
}
|
||||||
|
string newTitle = BuildMainWindowTitleProxy();
|
||||||
|
return newTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoOptimization)]
|
||||||
|
private static string BuildMainWindowTitleProxy()
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cc89a9041ab48ac41975fbd1e00b9b98
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace DotNetDetour
|
namespace DotNetDetour
|
||||||
{
|
{
|
||||||
|
@ -642,8 +641,15 @@ namespace DotNetDetour
|
||||||
if(s_isArm.HasValue)
|
if(s_isArm.HasValue)
|
||||||
return s_isArm.Value;
|
return s_isArm.Value;
|
||||||
|
|
||||||
var arch = RuntimeInformation.ProcessArchitecture;
|
string processorType = UnityEngine.SystemInfo.processorType;
|
||||||
s_isArm = arch == Architecture.Arm || arch == Architecture.Arm64;
|
|
||||||
|
/*
|
||||||
|
* appple M 系列
|
||||||
|
* SystemInfo.processorType 返回值为: Apple M1 Max, Apple M2 等
|
||||||
|
* SystemInfo.operatingSystem 返回值为: Mac OS X xx.x.x
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
s_isArm = processorType.Contains("ARM") || processorType.Contains("Apple M");
|
||||||
|
|
||||||
return s_isArm.Value;
|
return s_isArm.Value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -362,17 +362,11 @@ namespace MonoHook
|
||||||
private void OnEditorUpdate()
|
private void OnEditorUpdate()
|
||||||
{
|
{
|
||||||
if (s_fi_GUISkin_current.GetValue(null) != null)
|
if (s_fi_GUISkin_current.GetValue(null) != null)
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
DoInstall();
|
DoInstall();
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
EditorApplication.update -= OnEditorUpdate;
|
EditorApplication.update -= OnEditorUpdate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 82346623158bae349a8347ae74662b12
|
guid: 16b9dc031f67b4fe5ad79c230f75768c
|
||||||
folderAsset: yes
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace HybridCLR.Editor.BuildProcessors
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PathScriptingAssembilesFile(string path)
|
public void PathScriptingAssembilesFile(string path)
|
||||||
{
|
{
|
||||||
if (!SettingsUtil.Enable)
|
if (!SettingsUtil.Enable)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "com.focus-creative-games.hybridclr_unity",
|
"name": "com.focus-creative-games.hybridclr_unity",
|
||||||
"version": "2.0.8",
|
"version": "2.0.9",
|
||||||
"displayName": "HybridCLR",
|
"displayName": "HybridCLR",
|
||||||
"description": "Unity package for HybridCLR. It includes editor and runtime scripts and assets for HybridCLR",
|
"description": "Unity package for HybridCLR. It includes editor and runtime scripts and assets for HybridCLR",
|
||||||
"category": "Runtime",
|
"category": "Runtime",
|
||||||
|
|
Loading…
Reference in New Issue