72 lines
4.2 KiB
C#
72 lines
4.2 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Collections;
|
|
using Newtonsoft.Json;
|
|
using UnityEngine;
|
|
|
|
public static class InspectHomeCampAot
|
|
{
|
|
public static string BuildAndCheck()
|
|
{
|
|
var built = AOT.Editor.YooAssetTools.BuildAndStageHotUpdate.BuildAndStage();
|
|
if (!built.StartsWith("ok", StringComparison.Ordinal)) throw new Exception(built);
|
|
return built + " | " + CheckHotUpdate();
|
|
}
|
|
|
|
public static string CheckHotUpdate()
|
|
{
|
|
var cecil = AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == "Mono.Cecil");
|
|
var definition = cecil.GetType("Mono.Cecil.AssemblyDefinition");
|
|
var stripped = Path.GetFullPath(Path.Combine(Application.dataPath, "../Library/Bee/artifacts/WebGL/ManagedStripped/YooAsset.dll"));
|
|
object original = definition.GetMethod("ReadAssembly", new[] { typeof(string) }).Invoke(null, new object[] { stripped });
|
|
object update = definition.GetMethod("ReadAssembly", new[] { typeof(string) }).Invoke(null, new object[] { Path.Combine(Application.dataPath, "Bundles/Raw/HotUpdate.Runtime.bytes") });
|
|
var calls = new System.Collections.Generic.List<string>();
|
|
using ((IDisposable)original)
|
|
using ((IDisposable)update)
|
|
{
|
|
var oldModule = Property(original, "MainModule");
|
|
var module = Property(update, "MainModule");
|
|
var references = (IEnumerable)module.GetType().GetMethod("GetMemberReferences", Type.EmptyTypes).Invoke(module, null);
|
|
foreach (object reference in references)
|
|
{
|
|
var declaring = Property(reference, "DeclaringType");
|
|
string typeName = (string)Property(declaring, "FullName");
|
|
if (typeName != "YooAsset.SceneHandle" && typeName != "YooAsset.HandleBase") continue;
|
|
string fullName = (string)Property(reference, "FullName");
|
|
object type = oldModule.GetType().GetMethod("GetType", new[] { typeof(string) }).Invoke(oldModule, new object[] { typeName });
|
|
var retained = ((IEnumerable)Property(type, "Methods")).Cast<object>().Any(m => (string)Property(m, "FullName") == fullName);
|
|
if (!retained) throw new Exception("Hot update uses a method absent from the shipped shell: " + fullName);
|
|
calls.Add(fullName);
|
|
}
|
|
}
|
|
var report = JsonConvert.SerializeObject(new { passed=true, baseline=stripped, retainedCalls=calls });
|
|
var output = Path.GetFullPath(Path.Combine(Application.dataPath, "../../Tools/output/homecamp_aot_compatibility"));
|
|
Directory.CreateDirectory(output); File.WriteAllText(Path.Combine(output, "aot_check.json"), report);
|
|
return report;
|
|
}
|
|
public static string Run()
|
|
{
|
|
var directory = Path.GetFullPath(Path.Combine(Application.dataPath, "../Library/Bee/artifacts/WebGL/ManagedStripped"));
|
|
var cecil = AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == "Mono.Cecil");
|
|
var definition = cecil.GetType("Mono.Cecil.AssemblyDefinition");
|
|
var output = new System.Collections.Generic.List<object>();
|
|
foreach (var file in new[] { "YooAsset.dll", "UnityEngine.CoreModule.dll" })
|
|
{
|
|
object assembly = definition.GetMethod("ReadAssembly", new[] { typeof(string) }).Invoke(null, new object[] { Path.Combine(directory, file) });
|
|
using ((IDisposable)assembly)
|
|
{
|
|
object module = Property(assembly, "MainModule");
|
|
foreach (var name in new[] { "YooAsset.SceneHandle", "YooAsset.HandleBase", "UnityEngine.SceneManagement.SceneManager" })
|
|
{
|
|
object type = module.GetType().GetMethod("GetType", new[] { typeof(string) }).Invoke(module, new object[] { name });
|
|
if (type != null) output.Add(new { file, written = File.GetLastWriteTimeUtc(Path.Combine(directory, file)), type = name,
|
|
methods = ((IEnumerable)Property(type, "Methods")).Cast<object>().Select(m => Property(m, "FullName")).ToArray() });
|
|
}
|
|
}
|
|
}
|
|
return JsonConvert.SerializeObject(output);
|
|
}
|
|
static object Property(object value, string name) => value.GetType().GetProperty(name).GetValue(value);
|
|
}
|