热更clr进版
This commit is contained in:
parent
0675dc291c
commit
cd60cb26a0
8
MD/iOSMigration.meta
Normal file
8
MD/iOSMigration.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17a20616b59b4a50aea9057818b224a5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
49
MD/iOSMigration/HybridCLR_Phase1.md
Normal file
49
MD/iOSMigration/HybridCLR_Phase1.md
Normal file
@ -0,0 +1,49 @@
|
||||
# HybridCLR Phase 1
|
||||
|
||||
## Scope
|
||||
|
||||
This phase only adds the hot-update foundation. It must not move turn actions, AI, network sync, MapData, replay, save compatibility, MemoryPack, Steam lobby/P2P, Workshop, or backend auth into hotfix assemblies.
|
||||
|
||||
## Added Layout
|
||||
|
||||
- `Assets/Scripts/TH1_Hotfix/TH1.Hotfix.asmdef`: first hot-update assembly.
|
||||
- `Assets/Scripts/TH1_Hotfix/HotfixEntry.cs`: smoke-test hotfix entry.
|
||||
- `Assets/Scripts/TH1_Logic/Hotfix/HotfixBootstrap.cs`: AOT-side loader.
|
||||
- `Assets/Scripts/TH1_Logic/Editor/HybridCLR/TH1HybridCLRBuildTools.cs`: TH1 menu shortcuts.
|
||||
|
||||
Runtime artifact layout:
|
||||
|
||||
```text
|
||||
Assets/StreamingAssets/HybridCLR/
|
||||
HotfixDlls/
|
||||
TH1.Hotfix.dll.bytes
|
||||
AOTAssemblies/
|
||||
mscorlib.dll.bytes
|
||||
System.dll.bytes
|
||||
System.Core.dll.bytes
|
||||
```
|
||||
|
||||
The loader silently skips when `TH1.Hotfix.dll.bytes` is missing, so the Steam/editor flow can still run without any hotfix package.
|
||||
|
||||
## First Local Verification
|
||||
|
||||
1. Let Unity resolve `com.code-philosophy.hybridclr`.
|
||||
2. Run `HybridCLR/Installer...`.
|
||||
3. Run `Tools/TH1/iOS Migration/HybridCLR/2. Configure TH1 Hotfix Settings`.
|
||||
4. Run `Tools/TH1/iOS Migration/HybridCLR/3. Generate All`.
|
||||
5. Run `Tools/TH1/iOS Migration/HybridCLR/4. Compile Hotfix Dll`.
|
||||
6. Run `Tools/TH1/iOS Migration/HybridCLR/5. Copy Hotfix Artifacts To StreamingAssets`.
|
||||
7. Run `Tools/TH1/iOS Migration/HybridCLR/6. Test Load StreamingAssets Hotfix In Editor`.
|
||||
|
||||
Expected editor console smoke output:
|
||||
|
||||
```text
|
||||
[TH1.Hotfix] Initialize version 0.1.0
|
||||
[TH1.Hotfix] Loaded TH1.Hotfix, ...
|
||||
```
|
||||
|
||||
## Next Boundaries
|
||||
|
||||
- Keep first hotfix content limited to UI presentation helpers, non-networked fixes, and feature flags.
|
||||
- Do not add Steamworks references to `TH1.Hotfix`.
|
||||
- Do not use hotfix as a way to bypass App Store review. Prefer resources/config for content updates and reserve code hotfix for cautious compatibility fixes.
|
||||
7
MD/iOSMigration/HybridCLR_Phase1.md.meta
Normal file
7
MD/iOSMigration/HybridCLR_Phase1.md.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6b8e7fe2c7074d9e99bf77214afb1e74
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Unity/Assets/HybridCLRGenerate.meta
Normal file
8
Unity/Assets/HybridCLRGenerate.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69da6df6a219a4b41815c8b315d5c2d9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
20
Unity/Assets/HybridCLRGenerate/AOTGenericReferences.cs
Normal file
20
Unity/Assets/HybridCLRGenerate/AOTGenericReferences.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
public class AOTGenericReferences : UnityEngine.MonoBehaviour
|
||||
{
|
||||
|
||||
// {{ AOT assemblies
|
||||
public static readonly IReadOnlyList<string> PatchedAOTAssemblyList = new List<string>
|
||||
{
|
||||
};
|
||||
// }}
|
||||
|
||||
// {{ constraint implement type
|
||||
// }}
|
||||
|
||||
// {{ AOT generic types
|
||||
// }}
|
||||
|
||||
public void RefMethods()
|
||||
{
|
||||
}
|
||||
}
|
||||
11
Unity/Assets/HybridCLRGenerate/AOTGenericReferences.cs.meta
Normal file
11
Unity/Assets/HybridCLRGenerate/AOTGenericReferences.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82d467b90d646a34e9f91bb15a58752d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
24
Unity/Assets/HybridCLRGenerate/link.xml
Normal file
24
Unity/Assets/HybridCLRGenerate/link.xml
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<linker>
|
||||
<assembly fullname="System">
|
||||
<type fullname="System.CodeDom.Compiler.GeneratedCodeAttribute" preserve="all" />
|
||||
<type fullname="System.ComponentModel.EditorBrowsableAttribute" preserve="all" />
|
||||
<type fullname="System.ComponentModel.EditorBrowsableState" preserve="all" />
|
||||
</assembly>
|
||||
<assembly fullname="UnityEngine.CoreModule">
|
||||
<type fullname="UnityEngine.Debug" preserve="all" />
|
||||
</assembly>
|
||||
<assembly fullname="mscorlib">
|
||||
<type fullname="System.Array" preserve="all" />
|
||||
<type fullname="System.Byte" preserve="all" />
|
||||
<type fullname="System.Diagnostics.DebuggableAttribute" preserve="all" />
|
||||
<type fullname="System.Diagnostics.DebuggableAttribute/DebuggingModes" preserve="all" />
|
||||
<type fullname="System.Object" preserve="all" />
|
||||
<type fullname="System.Runtime.CompilerServices.CompilationRelaxationsAttribute" preserve="all" />
|
||||
<type fullname="System.Runtime.CompilerServices.CompilerGeneratedAttribute" preserve="all" />
|
||||
<type fullname="System.Runtime.CompilerServices.RuntimeCompatibilityAttribute" preserve="all" />
|
||||
<type fullname="System.Runtime.CompilerServices.RuntimeHelpers" preserve="all" />
|
||||
<type fullname="System.RuntimeFieldHandle" preserve="all" />
|
||||
<type fullname="System.ValueType" preserve="all" />
|
||||
</assembly>
|
||||
</linker>
|
||||
7
Unity/Assets/HybridCLRGenerate/link.xml.meta
Normal file
7
Unity/Assets/HybridCLRGenerate/link.xml.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09e7d09de0ac0dc46aa9c5ae2f43a611
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Unity/Assets/Scripts/TH1_Hotfix.meta
Normal file
8
Unity/Assets/Scripts/TH1_Hotfix.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a31ef57469b74a26802d55500df1fb90
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
14
Unity/Assets/Scripts/TH1_Hotfix/HotfixEntry.cs
Normal file
14
Unity/Assets/Scripts/TH1_Hotfix/HotfixEntry.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace TH1_Hotfix
|
||||
{
|
||||
public static class HotfixEntry
|
||||
{
|
||||
public const string Version = "0.1.0";
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
Debug.Log($"[TH1.Hotfix] Initialize version {Version}");
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Unity/Assets/Scripts/TH1_Hotfix/HotfixEntry.cs.meta
Normal file
11
Unity/Assets/Scripts/TH1_Hotfix/HotfixEntry.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e0a1f19517144ff8a49726755c99516
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
14
Unity/Assets/Scripts/TH1_Hotfix/TH1.Hotfix.asmdef
Normal file
14
Unity/Assets/Scripts/TH1_Hotfix/TH1.Hotfix.asmdef
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "TH1.Hotfix",
|
||||
"rootNamespace": "TH1_Hotfix",
|
||||
"references": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
7
Unity/Assets/Scripts/TH1_Hotfix/TH1.Hotfix.asmdef.meta
Normal file
7
Unity/Assets/Scripts/TH1_Hotfix/TH1.Hotfix.asmdef.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 267e9d456fb04f7cb0386f921d67598c
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Unity/Assets/Scripts/TH1_Logic/Editor/HybridCLR.meta
Normal file
8
Unity/Assets/Scripts/TH1_Logic/Editor/HybridCLR.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fcb6bf33c8f24eb394c0f2385ff60b64
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using TH1_Logic.Hotfix;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TH1_Logic.Editor.HybridCLR
|
||||
{
|
||||
public static class TH1HybridCLRBuildTools
|
||||
{
|
||||
private const string HybridClrInstallerMenu = "HybridCLR/Installer...";
|
||||
private const string HybridClrGenerateAllMenu = "HybridCLR/Generate/All";
|
||||
private const string HybridClrCompileDllMenu = "HybridCLR/CompileDll/ActiveBuildTarget";
|
||||
|
||||
[MenuItem("Tools/TH1/iOS Migration/HybridCLR/1. Run HybridCLR Installer")]
|
||||
public static void RunHybridClrInstaller()
|
||||
{
|
||||
ExecuteHybridClrMenu(HybridClrInstallerMenu);
|
||||
}
|
||||
|
||||
[MenuItem("Tools/TH1/iOS Migration/HybridCLR/2. Configure TH1 Hotfix Settings")]
|
||||
public static void ConfigureHotfixSettings()
|
||||
{
|
||||
var settingsType = FindType("HybridCLR.Editor.Settings.HybridCLRSettings");
|
||||
if (settingsType == null)
|
||||
{
|
||||
Debug.LogWarning("[TH1.HybridCLR] HybridCLR package is not available yet. Let Unity resolve packages, then run this menu again.");
|
||||
return;
|
||||
}
|
||||
|
||||
var instance = settingsType.GetProperty("Instance", BindingFlags.Public | BindingFlags.Static)?.GetValue(null);
|
||||
if (instance == null)
|
||||
{
|
||||
Debug.LogWarning("[TH1.HybridCLR] HybridCLRSettings.Instance is unavailable.");
|
||||
return;
|
||||
}
|
||||
|
||||
SetBoolField(settingsType, instance, "enable", true);
|
||||
AddStringToArrayField(settingsType, instance, "hotUpdateAssemblies", HotfixManifest.HotfixAssemblyName);
|
||||
AddStringToArrayField(settingsType, instance, "patchAOTAssemblies", "mscorlib");
|
||||
AddStringToArrayField(settingsType, instance, "patchAOTAssemblies", "System");
|
||||
AddStringToArrayField(settingsType, instance, "patchAOTAssemblies", "System.Core");
|
||||
|
||||
settingsType.GetMethod("Save", BindingFlags.Public | BindingFlags.Static)?.Invoke(null, null);
|
||||
Debug.Log("[TH1.HybridCLR] Configured HybridCLRSettings for TH1.Hotfix.");
|
||||
}
|
||||
|
||||
[MenuItem("Tools/TH1/iOS Migration/HybridCLR/3. Generate All")]
|
||||
public static void GenerateAll()
|
||||
{
|
||||
ExecuteHybridClrMenu(HybridClrGenerateAllMenu);
|
||||
}
|
||||
|
||||
[MenuItem("Tools/TH1/iOS Migration/HybridCLR/4. Compile Hotfix Dll")]
|
||||
public static void CompileHotfixDll()
|
||||
{
|
||||
if (!ExecuteHybridClrMenu(HybridClrCompileDllMenu))
|
||||
{
|
||||
Debug.LogWarning("[TH1.HybridCLR] Compile menu was not found. Run HybridCLR/Generate/All or use the package CompileDll menu manually.");
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("Tools/TH1/iOS Migration/HybridCLR/5. Copy Hotfix Artifacts To StreamingAssets")]
|
||||
public static void CopyHotfixArtifactsToStreamingAssets()
|
||||
{
|
||||
CopyHotfixDll();
|
||||
CopyAotMetadataDlls();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
[MenuItem("Tools/TH1/iOS Migration/HybridCLR/6. Test Load StreamingAssets Hotfix In Editor")]
|
||||
public static void TestLoadHotfixInEditor()
|
||||
{
|
||||
var loaded = HotfixBootstrap.InitializeFromStreamingAssets(true);
|
||||
Debug.Log($"[TH1.HybridCLR] Test load result: {loaded}, assembly: {HotfixBootstrap.LoadedAssemblyFullName}");
|
||||
}
|
||||
|
||||
private static void CopyHotfixDll()
|
||||
{
|
||||
var buildTarget = EditorUserBuildSettings.activeBuildTarget.ToString();
|
||||
var source = Path.Combine("HybridCLRData", "HotUpdateDlls", buildTarget, HotfixManifest.HotfixAssemblyName + ".dll");
|
||||
if (!File.Exists(source))
|
||||
{
|
||||
source = Path.Combine("Library", "ScriptAssemblies", HotfixManifest.HotfixAssemblyName + ".dll");
|
||||
}
|
||||
|
||||
var destination = Path.Combine(
|
||||
Application.streamingAssetsPath,
|
||||
HotfixManifest.RootFolderName,
|
||||
HotfixManifest.HotfixDllFolderName,
|
||||
HotfixManifest.HotfixAssemblyFileName);
|
||||
|
||||
CopyFile(source, destination, "hotfix dll");
|
||||
}
|
||||
|
||||
private static void CopyAotMetadataDlls()
|
||||
{
|
||||
var buildTarget = EditorUserBuildSettings.activeBuildTarget.ToString();
|
||||
var sourceDir = Path.Combine("HybridCLRData", "AssembliesPostIl2CppStrip", buildTarget);
|
||||
var destinationDir = Path.Combine(Application.streamingAssetsPath, HotfixManifest.RootFolderName, HotfixManifest.AotMetadataFolderName);
|
||||
|
||||
if (!Directory.Exists(sourceDir))
|
||||
{
|
||||
Debug.LogWarning($"[TH1.HybridCLR] AOT metadata source missing: {sourceDir}. Run HybridCLR/Generate/All after an IL2CPP target is selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(destinationDir);
|
||||
foreach (var fileName in HotfixManifest.AotMetadataAssemblyFileNames)
|
||||
{
|
||||
var source = Path.Combine(sourceDir, fileName.Replace(".bytes", ""));
|
||||
var destination = Path.Combine(destinationDir, fileName);
|
||||
if (!File.Exists(source))
|
||||
{
|
||||
Debug.LogWarning($"[TH1.HybridCLR] AOT metadata dll missing: {source}");
|
||||
continue;
|
||||
}
|
||||
|
||||
File.Copy(source, destination, true);
|
||||
Debug.Log($"[TH1.HybridCLR] Copied AOT metadata: {destination}");
|
||||
}
|
||||
}
|
||||
|
||||
private static bool ExecuteHybridClrMenu(string menuPath)
|
||||
{
|
||||
if (EditorApplication.ExecuteMenuItem(menuPath))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Debug.LogWarning($"[TH1.HybridCLR] Unity menu not found: {menuPath}. Make sure the HybridCLR package has been resolved.");
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void CopyFile(string source, string destination, string label)
|
||||
{
|
||||
if (!File.Exists(source))
|
||||
{
|
||||
Debug.LogWarning($"[TH1.HybridCLR] {label} source missing: {source}");
|
||||
return;
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(destination));
|
||||
File.Copy(source, destination, true);
|
||||
Debug.Log($"[TH1.HybridCLR] Copied {label}: {destination}");
|
||||
}
|
||||
|
||||
private static Type FindType(string fullName)
|
||||
{
|
||||
return AppDomain.CurrentDomain.GetAssemblies()
|
||||
.Select(assembly => assembly.GetType(fullName, false))
|
||||
.FirstOrDefault(type => type != null);
|
||||
}
|
||||
|
||||
private static void SetBoolField(Type type, object instance, string fieldName, bool value)
|
||||
{
|
||||
type.GetField(fieldName, BindingFlags.Public | BindingFlags.Instance)?.SetValue(instance, value);
|
||||
}
|
||||
|
||||
private static void AddStringToArrayField(Type type, object instance, string fieldName, string value)
|
||||
{
|
||||
var field = type.GetField(fieldName, BindingFlags.Public | BindingFlags.Instance);
|
||||
if (field == null) return;
|
||||
|
||||
var values = ((string[])field.GetValue(instance) ?? Array.Empty<string>()).ToList();
|
||||
if (!values.Contains(value))
|
||||
{
|
||||
values.Add(value);
|
||||
field.SetValue(instance, values.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1aa132302254cd386955a4c94487eab
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Unity/Assets/Scripts/TH1_Logic/Hotfix.meta
Normal file
8
Unity/Assets/Scripts/TH1_Logic/Hotfix.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 46d4a569e4eb49caa31e4dc5a2522a85
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
117
Unity/Assets/Scripts/TH1_Logic/Hotfix/HotfixBootstrap.cs
Normal file
117
Unity/Assets/Scripts/TH1_Logic/Hotfix/HotfixBootstrap.cs
Normal file
@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TH1_Logic.Hotfix
|
||||
{
|
||||
public static class HotfixBootstrap
|
||||
{
|
||||
private static bool _initialized;
|
||||
|
||||
public static bool IsLoaded { get; private set; }
|
||||
public static string LoadedAssemblyFullName { get; private set; }
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
private static void AutoInitialize()
|
||||
{
|
||||
InitializeFromStreamingAssets(false);
|
||||
}
|
||||
|
||||
public static bool InitializeFromStreamingAssets(bool requireHotfix)
|
||||
{
|
||||
if (_initialized) return IsLoaded;
|
||||
|
||||
try
|
||||
{
|
||||
var root = Path.Combine(Application.streamingAssetsPath, HotfixManifest.RootFolderName);
|
||||
LoadAotMetadata(root);
|
||||
|
||||
var hotfixPath = Path.Combine(root, HotfixManifest.HotfixDllFolderName, HotfixManifest.HotfixAssemblyFileName);
|
||||
if (!File.Exists(hotfixPath))
|
||||
{
|
||||
if (requireHotfix)
|
||||
{
|
||||
Debug.LogWarning($"[TH1.Hotfix] Hotfix dll missing: {hotfixPath}");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var assembly = Assembly.Load(File.ReadAllBytes(hotfixPath));
|
||||
LoadedAssemblyFullName = assembly.FullName;
|
||||
InvokeHotfixEntry(assembly);
|
||||
_initialized = true;
|
||||
IsLoaded = true;
|
||||
Debug.Log($"[TH1.Hotfix] Loaded {LoadedAssemblyFullName}");
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[TH1.Hotfix] Initialize failed: {e}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void LoadAotMetadata(string root)
|
||||
{
|
||||
var runtimeApiType = FindType("HybridCLR.RuntimeApi");
|
||||
var modeType = FindType("HybridCLR.HomologousImageMode");
|
||||
if (runtimeApiType == null || modeType == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var method = runtimeApiType.GetMethod(
|
||||
"LoadMetadataForAOTAssembly",
|
||||
BindingFlags.Public | BindingFlags.Static,
|
||||
null,
|
||||
new[] { typeof(byte[]), modeType },
|
||||
null);
|
||||
if (method == null)
|
||||
{
|
||||
Debug.LogWarning("[TH1.Hotfix] HybridCLR RuntimeApi.LoadMetadataForAOTAssembly not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
var mode = Enum.Parse(modeType, "SuperSet");
|
||||
var aotDir = Path.Combine(root, HotfixManifest.AotMetadataFolderName);
|
||||
|
||||
foreach (var fileName in HotfixManifest.AotMetadataAssemblyFileNames)
|
||||
{
|
||||
var path = Path.Combine(aotDir, fileName);
|
||||
if (!File.Exists(path)) continue;
|
||||
|
||||
var result = method.Invoke(null, new object[] { File.ReadAllBytes(path), mode });
|
||||
Debug.Log($"[TH1.Hotfix] Load AOT metadata {fileName}: {result}");
|
||||
}
|
||||
}
|
||||
|
||||
private static void InvokeHotfixEntry(Assembly assembly)
|
||||
{
|
||||
var entryType = assembly.GetType(HotfixManifest.EntryTypeName);
|
||||
if (entryType == null)
|
||||
{
|
||||
Debug.LogWarning($"[TH1.Hotfix] Entry type not found: {HotfixManifest.EntryTypeName}");
|
||||
return;
|
||||
}
|
||||
|
||||
var method = entryType.GetMethod(HotfixManifest.EntryMethodName, BindingFlags.Public | BindingFlags.Static);
|
||||
if (method == null)
|
||||
{
|
||||
Debug.LogWarning($"[TH1.Hotfix] Entry method not found: {HotfixManifest.EntryMethodName}");
|
||||
return;
|
||||
}
|
||||
|
||||
method.Invoke(null, null);
|
||||
}
|
||||
|
||||
private static Type FindType(string fullName)
|
||||
{
|
||||
return AppDomain.CurrentDomain.GetAssemblies()
|
||||
.Select(assembly => assembly.GetType(fullName, false))
|
||||
.FirstOrDefault(type => type != null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 219e5d567ddb4e638c9148177e53f87a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
25
Unity/Assets/Scripts/TH1_Logic/Hotfix/HotfixManifest.cs
Normal file
25
Unity/Assets/Scripts/TH1_Logic/Hotfix/HotfixManifest.cs
Normal file
@ -0,0 +1,25 @@
|
||||
namespace TH1_Logic.Hotfix
|
||||
{
|
||||
public static class HotfixManifest
|
||||
{
|
||||
public const string BaseAppVersion = "0.1.0";
|
||||
public const string HotfixManifestVersion = "0.1.0";
|
||||
public const string MinCompatibleAppVersion = "0.1.0";
|
||||
|
||||
public const string RootFolderName = "HybridCLR";
|
||||
public const string AotMetadataFolderName = "AOTAssemblies";
|
||||
public const string HotfixDllFolderName = "HotfixDlls";
|
||||
|
||||
public const string HotfixAssemblyName = "TH1.Hotfix";
|
||||
public const string HotfixAssemblyFileName = HotfixAssemblyName + ".dll.bytes";
|
||||
public const string EntryTypeName = "TH1_Hotfix.HotfixEntry";
|
||||
public const string EntryMethodName = "Initialize";
|
||||
|
||||
public static readonly string[] AotMetadataAssemblyFileNames =
|
||||
{
|
||||
"mscorlib.dll.bytes",
|
||||
"System.dll.bytes",
|
||||
"System.Core.dll.bytes",
|
||||
};
|
||||
}
|
||||
}
|
||||
11
Unity/Assets/Scripts/TH1_Logic/Hotfix/HotfixManifest.cs.meta
Normal file
11
Unity/Assets/Scripts/TH1_Logic/Hotfix/HotfixManifest.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c598a2c57a1a4f35bcf8a5b2b4f72621
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,5 +1,6 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"com.code-philosophy.hybridclr": "https://github.com/focus-creative-games/hybridclr_unity.git#v8.12.0",
|
||||
"com.cysharp.memorypack": "https://github.com/Cysharp/MemoryPack.git?path=src/MemoryPack.Unity/Assets/Plugins/MemoryPack#1.10.0",
|
||||
"com.github-glitchenzo.nugetforunity": "https://github.com/GlitchEnzo/NuGetForUnity.git?path=/src/NuGetForUnity",
|
||||
"com.tuyoogame.yooasset": "2.1.1",
|
||||
|
||||
@ -1,5 +1,12 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"com.code-philosophy.hybridclr": {
|
||||
"version": "https://github.com/focus-creative-games/hybridclr_unity.git#v8.12.0",
|
||||
"depth": 0,
|
||||
"source": "git",
|
||||
"dependencies": {},
|
||||
"hash": "e4def761d69b27b7b51a5de0f6d272861416a2d6"
|
||||
},
|
||||
"com.cysharp.memorypack": {
|
||||
"version": "https://github.com/Cysharp/MemoryPack.git?path=src/MemoryPack.Unity/Assets/Plugins/MemoryPack#1.10.0",
|
||||
"depth": 0,
|
||||
@ -27,11 +34,11 @@
|
||||
"url": "https://package.openupm.com"
|
||||
},
|
||||
"com.unity.2d.animation": {
|
||||
"version": "9.1.3",
|
||||
"version": "9.0.3",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.2d.common": "8.0.4",
|
||||
"com.unity.2d.common": "8.0.1",
|
||||
"com.unity.2d.sprite": "1.0.0",
|
||||
"com.unity.collections": "1.1.0",
|
||||
"com.unity.modules.animation": "1.0.0",
|
||||
@ -40,7 +47,7 @@
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.2d.aseprite": {
|
||||
"version": "1.1.6",
|
||||
"version": "1.0.0",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
@ -52,7 +59,7 @@
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.2d.common": {
|
||||
"version": "8.0.4",
|
||||
"version": "8.0.1",
|
||||
"depth": 2,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
@ -72,13 +79,13 @@
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.2d.psdimporter": {
|
||||
"version": "8.0.5",
|
||||
"version": "8.0.2",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.2d.common": "8.0.2",
|
||||
"com.unity.2d.common": "8.0.1",
|
||||
"com.unity.2d.sprite": "1.0.0",
|
||||
"com.unity.2d.animation": "9.1.1"
|
||||
"com.unity.2d.animation": "9.0.1"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
@ -89,11 +96,11 @@
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.2d.spriteshape": {
|
||||
"version": "9.0.5",
|
||||
"version": "9.0.2",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.2d.common": "8.0.4",
|
||||
"com.unity.2d.common": "8.0.1",
|
||||
"com.unity.mathematics": "1.1.0",
|
||||
"com.unity.modules.physics2d": "1.0.0"
|
||||
},
|
||||
@ -109,7 +116,7 @@
|
||||
}
|
||||
},
|
||||
"com.unity.2d.tilemap.extras": {
|
||||
"version": "3.1.3",
|
||||
"version": "3.1.1",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
@ -121,12 +128,11 @@
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.burst": {
|
||||
"version": "1.8.18",
|
||||
"version": "1.8.8",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.mathematics": "1.2.1",
|
||||
"com.unity.modules.jsonserialize": "1.0.0"
|
||||
"com.unity.mathematics": "1.2.1"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
@ -159,14 +165,14 @@
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.2d.animation": "9.1.3",
|
||||
"com.unity.2d.animation": "9.0.3",
|
||||
"com.unity.2d.pixel-perfect": "5.0.3",
|
||||
"com.unity.2d.psdimporter": "8.0.5",
|
||||
"com.unity.2d.psdimporter": "8.0.2",
|
||||
"com.unity.2d.sprite": "1.0.0",
|
||||
"com.unity.2d.spriteshape": "9.0.5",
|
||||
"com.unity.2d.spriteshape": "9.0.2",
|
||||
"com.unity.2d.tilemap": "1.0.0",
|
||||
"com.unity.2d.tilemap.extras": "3.1.3",
|
||||
"com.unity.2d.aseprite": "1.1.6"
|
||||
"com.unity.2d.tilemap.extras": "3.1.1",
|
||||
"com.unity.2d.aseprite": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.ide.rider": {
|
||||
@ -195,7 +201,7 @@
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.render-pipelines.core": {
|
||||
"version": "14.0.11",
|
||||
"version": "14.0.8",
|
||||
"depth": 1,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
@ -211,22 +217,13 @@
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.mathematics": "1.2.1",
|
||||
"com.unity.burst": "1.8.9",
|
||||
"com.unity.render-pipelines.core": "14.0.11",
|
||||
"com.unity.shadergraph": "14.0.11",
|
||||
"com.unity.render-pipelines.universal-config": "14.0.9"
|
||||
}
|
||||
},
|
||||
"com.unity.render-pipelines.universal-config": {
|
||||
"version": "14.0.10",
|
||||
"depth": 1,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.render-pipelines.core": "14.0.10"
|
||||
"com.unity.burst": "1.8.4",
|
||||
"com.unity.render-pipelines.core": "14.0.8",
|
||||
"com.unity.shadergraph": "14.0.8"
|
||||
}
|
||||
},
|
||||
"com.unity.scriptablebuildpipeline": {
|
||||
"version": "1.21.25",
|
||||
"version": "1.21.21",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
@ -240,11 +237,11 @@
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.shadergraph": {
|
||||
"version": "14.0.11",
|
||||
"version": "14.0.8",
|
||||
"depth": 1,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.render-pipelines.core": "14.0.11",
|
||||
"com.unity.render-pipelines.core": "14.0.8",
|
||||
"com.unity.searcher": "4.9.2"
|
||||
}
|
||||
},
|
||||
|
||||
33
Unity/ProjectSettings/HybridCLRSettings.asset
Normal file
33
Unity/ProjectSettings/HybridCLRSettings.asset
Normal file
@ -0,0 +1,33 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &1
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: e189374413a3f00468e49d51d8b27a09, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
enable: 1
|
||||
useGlobalIl2cpp: 0
|
||||
hybridclrRepoURL: https://gitee.com/focus-creative-games/hybridclr
|
||||
il2cppPlusRepoURL: https://gitee.com/focus-creative-games/il2cpp_plus
|
||||
hotUpdateAssemblyDefinitions: []
|
||||
hotUpdateAssemblies:
|
||||
- TH1.Hotfix
|
||||
preserveHotUpdateAssemblies: []
|
||||
hotUpdateDllCompileOutputRootDir: HybridCLRData/HotUpdateDlls
|
||||
externalHotUpdateAssembliyDirs: []
|
||||
strippedAOTDllOutputRootDir: HybridCLRData/AssembliesPostIl2CppStrip
|
||||
patchAOTAssemblies:
|
||||
- mscorlib
|
||||
- System
|
||||
- System.Core
|
||||
outputLinkFile: HybridCLRGenerate/link.xml
|
||||
outputAOTGenericReferenceFile: HybridCLRGenerate/AOTGenericReferences.cs
|
||||
maxGenericReferenceIteration: 10
|
||||
maxMethodBridgeGenericIteration: 10
|
||||
@ -13,7 +13,7 @@ PlayerSettings:
|
||||
useOnDemandResources: 0
|
||||
accelerometerFrequency: 60
|
||||
companyName: Remilia Command
|
||||
productName: TOHOTOPIA
|
||||
productName: TOHOTOPIA v0.7.3e
|
||||
defaultCursor: {fileID: 0}
|
||||
cursorHotspot: {x: 0, y: 0}
|
||||
m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1}
|
||||
@ -48,13 +48,12 @@ PlayerSettings:
|
||||
defaultScreenHeightWeb: 600
|
||||
m_StereoRenderingPath: 0
|
||||
m_ActiveColorSpace: 1
|
||||
unsupportedMSAAFallback: 0
|
||||
m_SpriteBatchVertexThreshold: 300
|
||||
m_MTRendering: 1
|
||||
mipStripping: 0
|
||||
numberOfMipsStripped: 0
|
||||
numberOfMipsStrippedPerMipmapLimitGroup: {}
|
||||
m_StackTraceTypes: 010000000100000000000000000000000100000001000000
|
||||
m_StackTraceTypes: 010000000100000001000000010000000100000001000000
|
||||
iosShowActivityIndicatorOnLoading: -1
|
||||
androidShowActivityIndicatorOnLoading: -1
|
||||
iosUseCustomAppBackgroundBehavior: 0
|
||||
@ -76,7 +75,6 @@ PlayerSettings:
|
||||
androidMinimumWindowWidth: 400
|
||||
androidMinimumWindowHeight: 300
|
||||
androidFullscreenMode: 1
|
||||
androidAutoRotationBehavior: 1
|
||||
defaultIsNativeResolution: 0
|
||||
macRetinaSupport: 1
|
||||
runInBackground: 0
|
||||
@ -84,11 +82,10 @@ PlayerSettings:
|
||||
muteOtherAudioSources: 0
|
||||
Prepare IOS For Recording: 0
|
||||
Force IOS Speakers When Recording: 0
|
||||
audioSpatialExperience: 0
|
||||
deferSystemGesturesMode: 0
|
||||
hideHomeButton: 0
|
||||
submitAnalytics: 1
|
||||
usePlayerLog: 0
|
||||
usePlayerLog: 1
|
||||
dedicatedServerOptimizations: 0
|
||||
bakeCollisionMeshes: 0
|
||||
forceSingleInstance: 0
|
||||
@ -138,8 +135,6 @@ PlayerSettings:
|
||||
vulkanEnableLateAcquireNextImage: 0
|
||||
vulkanEnableCommandBufferRecycling: 1
|
||||
loadStoreDebugModeEnabled: 0
|
||||
visionOSBundleVersion: 1.0
|
||||
tvOSBundleVersion: 1.0
|
||||
bundleVersion: 0.7.3e
|
||||
preloadedAssets: []
|
||||
metroInputSource: 0
|
||||
@ -152,7 +147,6 @@ PlayerSettings:
|
||||
isWsaHolographicRemotingEnabled: 0
|
||||
enableFrameTimingStats: 0
|
||||
enableOpenGLProfilerGPURecorders: 1
|
||||
allowHDRDisplaySupport: 0
|
||||
useHDRDisplay: 0
|
||||
hdrBitDepth: 0
|
||||
m_ColorGamuts: 00000000
|
||||
@ -234,7 +228,6 @@ PlayerSettings:
|
||||
iOSMetalForceHardShadows: 0
|
||||
metalEditorSupport: 1
|
||||
metalAPIValidation: 1
|
||||
metalCompileShaderBinary: 0
|
||||
iOSRenderExtraFrameOnPause: 0
|
||||
iosCopyPluginsCodeInsteadOfSymlink: 0
|
||||
appleDeveloperTeamID:
|
||||
@ -447,7 +440,7 @@ PlayerSettings:
|
||||
playModeTestRunnerEnabled: 0
|
||||
runPlayModeTestAsEditModeTest: 0
|
||||
actionOnDotNetUnhandledException: 1
|
||||
enableInternalProfiler: 0
|
||||
enableInternalProfiler: 1
|
||||
logObjCUncaughtExceptions: 1
|
||||
enableCrashReportAPI: 0
|
||||
cameraUsageDescription:
|
||||
@ -462,7 +455,7 @@ PlayerSettings:
|
||||
switchSocketConcurrencyLimit: 14
|
||||
switchScreenResolutionBehavior: 2
|
||||
switchUseCPUProfiler: 0
|
||||
switchEnableFileSystemTrace: 0
|
||||
switchUseGOLDLinker: 0
|
||||
switchLTOSetting: 0
|
||||
switchApplicationID: 0x01004b9000490000
|
||||
switchNSODependencies:
|
||||
@ -592,6 +585,7 @@ PlayerSettings:
|
||||
switchSocketBufferEfficiency: 4
|
||||
switchSocketInitializeEnabled: 1
|
||||
switchNetworkInterfaceManagerInitializeEnabled: 1
|
||||
switchPlayerConnectionEnabled: 1
|
||||
switchUseNewStyleFilepaths: 0
|
||||
switchUseLegacyFmodPriorities: 0
|
||||
switchUseMicroSleepForYield: 1
|
||||
@ -702,7 +696,7 @@ PlayerSettings:
|
||||
webGLMemoryGeometricGrowthCap: 96
|
||||
webGLPowerPreference: 2
|
||||
scriptingDefineSymbols:
|
||||
Standalone: UNITY;ENABLE_VIEW;NODECANVAS;STEAMWORKS_NET;STEAM_CHANNEL
|
||||
Standalone: UNITY;ENABLE_VIEW;NODECANVAS;STEAMWORKS_NET;STEAM_CHANNEL;USE_INPUT
|
||||
additionalCompilerArguments: {}
|
||||
platformArchitecture: {}
|
||||
scriptingBackend:
|
||||
@ -756,7 +750,6 @@ PlayerSettings:
|
||||
metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0}
|
||||
metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, a: 1}
|
||||
metroSplashScreenUseBackgroundColor: 0
|
||||
syncCapabilities: 0
|
||||
platformCapabilities: {}
|
||||
metroTargetDeviceFamilies: {}
|
||||
metroFTAName:
|
||||
@ -814,7 +807,7 @@ PlayerSettings:
|
||||
embeddedLinuxEnableGamepadInput: 1
|
||||
hmiLogStartupTiming: 0
|
||||
hmiCpuConfiguration:
|
||||
apiCompatibilityLevel: 6
|
||||
apiCompatibilityLevel: 3
|
||||
activeInputHandler: 0
|
||||
windowsGamepadBackendHint: 0
|
||||
cloudProjectId: e4975dbe-fc42-475f-a775-250045253218
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
m_EditorVersion: 2022.3.53f1c1
|
||||
m_EditorVersionWithRevision: 2022.3.53f1c1 (f16e16b78e06)
|
||||
m_EditorVersion: 2022.3.8f1c1
|
||||
m_EditorVersionWithRevision: 2022.3.8f1c1 (4ec8ee1b2212)
|
||||
|
||||
@ -12,6 +12,5 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: de02f9e1d18f588468e474319d09a723, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
shaderVariantLimit: 2048
|
||||
customInterpolatorErrorThreshold: 32
|
||||
customInterpolatorWarningThreshold: 16
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user