Move Aetheria EveUnity hooks into provider package

This commit is contained in:
Meta Vens 2026-07-09 20:39:54 +01:00
commit 074eab26fe
9 changed files with 188 additions and 69 deletions

View file

@ -9597,7 +9597,8 @@ static void RequireClientTargetBootAuthority(string root)
var mainMenuSurfaceBuilderPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.state", "Runtime", "AetheriaRuntimeMainMenuSurfaceBuilder.cs");
var bootstrapPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.eve-runtime", "Runtime", "AetheriaEveRuntimeBootstrap.cs");
var presenterPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.eve-runtime", "Runtime", "AetheriaEveSurfacePresenter.cs");
var unityEveRuntimeHooksPath = Path.Combine(root, "Assets", "Scripts", "Gameplay", "AetheriaUnityEveRuntimeHooks.cs");
var eveRuntimeClientCachePath = Path.Combine(root, "Packages", "org.gamecult.aetheria.eve-runtime", "Runtime", "AetheriaEveRuntimeUnityClientCache.cs");
var eveRuntimeHookInstallerPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.eve-runtime", "Runtime", "AetheriaEveRuntimeUnityHookInstaller.cs");
var actionGameManagerPath = Path.Combine(root, "Assets", "Scripts", "Gameplay", "ActionGameManager.cs");
var gameplayBootShellPath = Path.Combine(root, "Assets", "Scripts", "Gameplay", "AetheriaUnityGameplayBootShell.cs");
var mainMenuPath = Path.Combine(root, "Assets", "Scripts", "UI", "MainMenu.cs");
@ -9615,7 +9616,8 @@ static void RequireClientTargetBootAuthority(string root)
mainMenuSurfaceBuilderPath,
bootstrapPath,
presenterPath,
unityEveRuntimeHooksPath,
eveRuntimeClientCachePath,
eveRuntimeHookInstallerPath,
actionGameManagerPath,
gameplayBootShellPath,
mainMenuPath
@ -9643,7 +9645,8 @@ static void RequireClientTargetBootAuthority(string root)
var mainMenuSurfaceBuilder = File.ReadAllText(mainMenuSurfaceBuilderPath);
var bootstrap = File.ReadAllText(bootstrapPath);
var presenter = File.ReadAllText(presenterPath);
var unityEveRuntimeHooks = File.ReadAllText(unityEveRuntimeHooksPath);
var eveRuntimeClientCache = File.ReadAllText(eveRuntimeClientCachePath);
var eveRuntimeHookInstaller = File.ReadAllText(eveRuntimeHookInstallerPath);
var actionGameManager = File.ReadAllText(actionGameManagerPath);
var gameplayBootShell = File.ReadAllText(gameplayBootShellPath);
var mainMenu = File.ReadAllText(mainMenuPath);
@ -9992,11 +9995,55 @@ static void RequireClientTargetBootAuthority(string root)
string.Join(", ", missingPresenterSymbols));
}
if (!unityEveRuntimeHooks.Contains("AetheriaRuntimeStateBoot.Inspect(", StringComparison.Ordinal) ||
!unityEveRuntimeHooks.Contains("AetheriaUnityRuntimePaths.GameDataDirectory", StringComparison.Ordinal))
var requiredEveRuntimeClientCacheSymbols = new[]
{
"public static class AetheriaEveRuntimeUnityClientCache",
"new DirectoryInfo(Application.dataPath).Parent.CreateSubdirectory(\"GameData\")",
"AetheriaRuntimeStateBoot.Inspect(GameDataDirectory).StateFilePath",
"AetheriaClient",
".OpenAsync(",
"startServer: false",
"pullOnOpen: true",
"CreateEveSurfaceCultMeshStateRefResolver()",
"public static void Dispose()"
};
var missingEveRuntimeClientCacheSymbols = requiredEveRuntimeClientCacheSymbols
.Where(symbol => !eveRuntimeClientCache.Contains(symbol, StringComparison.Ordinal))
.ToArray();
if (missingEveRuntimeClientCacheSymbols.Length > 0)
{
throw new InvalidOperationException(
"Aetheria Eve runtime hooks no longer own Unity client-target boot resolution.");
"Aetheria Eve runtime package no longer owns its generic Unity client cache: " +
string.Join(", ", missingEveRuntimeClientCacheSymbols));
}
var requiredEveRuntimeHookInstallerSymbols = new[]
{
"public static class AetheriaEveRuntimeUnityHookInstaller",
"RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)",
"public static void Install()",
"AetheriaEveRuntimeUnityHooks.ResolveStateBoot",
"AetheriaRuntimeStateBoot.Inspect(",
"AetheriaEveRuntimeUnityClientCache.GameDataDirectory",
"AetheriaEveRuntimeUnityHooks.RuntimeState",
"AetheriaEveRuntimeUnityHooks.Control",
"AetheriaEveRuntimeUnityHooks.Ui",
"AetheriaEveRuntimeUnityHooks.StateRefResolver"
};
var missingEveRuntimeHookInstallerSymbols = requiredEveRuntimeHookInstallerSymbols
.Where(symbol => !eveRuntimeHookInstaller.Contains(symbol, StringComparison.Ordinal))
.ToArray();
if (missingEveRuntimeHookInstallerSymbols.Length > 0)
{
throw new InvalidOperationException(
"Aetheria Eve runtime package no longer owns Unity client-target hook installation: " +
string.Join(", ", missingEveRuntimeHookInstallerSymbols));
}
if (File.Exists(Path.Combine(root, "Assets", "Scripts", "Gameplay", "AetheriaUnityEveRuntimeHooks.cs")))
{
throw new InvalidOperationException(
"Aetheria Eve runtime hooks are still installed by the legacy Unity gameplay assembly; the provider package must own this boundary.");
}
if (bootstrap.Contains("StatePathEnvironmentVariable", StringComparison.Ordinal) ||

View file

@ -1,23 +0,0 @@
using GameCult.Aetheria.EveRuntime;
using GameCult.Aetheria.State.Verse;
using UnityEngine;
public static class AetheriaUnityEveRuntimeHooks
{
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void Install()
{
AetheriaEveRuntimeUnityHooks.ResolveStateBoot =
overridePath => AetheriaRuntimeStateBoot.Inspect(
AetheriaUnityRuntimePaths.GameDataDirectory,
overridePath ?? "");
AetheriaEveRuntimeUnityHooks.RuntimeState =
(stateBoot, runtimeId) => AetheriaUnityRuntimeClientProvider.RuntimeState(stateBoot, runtimeId);
AetheriaEveRuntimeUnityHooks.Control =
(stateBoot, runtimeId) => AetheriaUnityRuntimeClientProvider.Control(stateBoot, runtimeId);
AetheriaEveRuntimeUnityHooks.Ui =
(stateBoot, runtimeId) => AetheriaUnityRuntimeClientProvider.Ui(stateBoot, runtimeId);
AetheriaEveRuntimeUnityHooks.StateRefResolver =
(stateBoot, runtimeId) => AetheriaUnityRuntimeClientProvider.EveSurfaceCultMeshStateRefResolver(stateBoot, runtimeId);
}
}

View file

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 72069f7b0885490fb690dc771e422aac
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -2777,29 +2777,6 @@ public class DaemonRuntimeDocumentTests
0.02);
PublishLatestFrameThroughVerseClient(statePath, frame);
using var client = AetheriaClient
.OpenAsync(statePath, "unity-scene-receipt-test", startServer: false, pullOnOpen: true)
.GetAwaiter()
.GetResult();
var stateBoot = new AetheriaRuntimeStateBootReport(
"",
"",
"state-path-override",
"Aetheria daemon test",
"aetheria.local",
"unity-scene-receipt-test",
"",
statePath,
"",
stateFileExists: true,
supportsLocalStateFileRead: true,
"",
Array.Empty<string>(),
Array.Empty<AetheriaRuntimeDiscoveredVerse>(),
"",
"",
"",
"");
var previousResolveStateBoot = AetheriaEveRuntimeUnityHooks.ResolveStateBoot;
var previousRuntimeState = AetheriaEveRuntimeUnityHooks.RuntimeState;
var previousControl = AetheriaEveRuntimeUnityHooks.Control;
@ -2808,12 +2785,7 @@ public class DaemonRuntimeDocumentTests
try
{
AetheriaEveRuntimeUnityHooks.ResolveStateBoot = _ => stateBoot;
AetheriaEveRuntimeUnityHooks.RuntimeState = (_, __) => client.State;
AetheriaEveRuntimeUnityHooks.Control = (_, __) => client.Control;
AetheriaEveRuntimeUnityHooks.Ui = (_, __) => client.Ui;
AetheriaEveRuntimeUnityHooks.StateRefResolver = (_, __) =>
client.State.CreateEveSurfaceCultMeshStateRefResolver();
AetheriaEveRuntimeUnityHookInstaller.Install();
using var bridge = new AetheriaEveUnitySceneProviderBridge(
statePath,
@ -2850,6 +2822,7 @@ public class DaemonRuntimeDocumentTests
}
finally
{
AetheriaEveRuntimeUnityClientCache.Dispose();
AetheriaEveRuntimeUnityHooks.ResolveStateBoot = previousResolveStateBoot;
AetheriaEveRuntimeUnityHooks.RuntimeState = previousRuntimeState;
AetheriaEveRuntimeUnityHooks.Control = previousControl;

View file

@ -49,10 +49,12 @@
<ItemGroup>
<Compile Include="Packages\org.gamecult.aetheria.eve-runtime\Runtime\AetheriaEveSurfacePresenter.cs" />
<Compile Include="Packages\org.gamecult.aetheria.eve-runtime\Runtime\AetheriaEveUnitySceneProviderComponent.cs" />
<Compile Include="Packages\org.gamecult.aetheria.eve-runtime\Runtime\AetheriaEveRuntimeUnityClientCache.cs" />
<Compile Include="Packages\org.gamecult.aetheria.eve-runtime\Runtime\AetheriaEveRuntimeBootstrap.cs" />
<Compile Include="Packages\org.gamecult.aetheria.eve-runtime\Runtime\AetheriaEveUnitySceneProviderBridge.cs" />
<Compile Include="Packages\org.gamecult.aetheria.eve-runtime\Runtime\AetheriaEveFileSurfacePresenter.cs" />
<Compile Include="Packages\org.gamecult.aetheria.eve-runtime\Runtime\AetheriaEveUnitySurfaceHost.cs" />
<Compile Include="Packages\org.gamecult.aetheria.eve-runtime\Runtime\AetheriaEveRuntimeUnityHookInstaller.cs" />
<None Include="Packages\org.gamecult.aetheria.eve-runtime\Runtime\GameCult.Aetheria.EveRuntime.asmdef" />
<Reference Include="UnityEngine">
<HintPath>C:\Program Files\Unity\Hub\Editor\6000.4.2f1\Editor\Data\Managed\UnityEngine\UnityEngine.dll</HintPath>

View file

@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using System.IO;
using GameCult.Aetheria.State.Verse;
using GameCult.Mesh;
using UnityEngine;
#nullable enable
namespace GameCult.Aetheria.EveRuntime
{
public static class AetheriaEveRuntimeUnityClientCache
{
private static readonly Dictionary<string, AetheriaClient> RuntimeClients =
new Dictionary<string, AetheriaClient>(StringComparer.Ordinal);
private static DirectoryInfo? s_gameDataDirectory;
private static string? s_runtimeStateFilePath;
public static DirectoryInfo GameDataDirectory =>
s_gameDataDirectory ??= new DirectoryInfo(Application.dataPath).Parent.CreateSubdirectory("GameData");
public static string RuntimeStateFilePath =>
s_runtimeStateFilePath ??= AetheriaRuntimeStateBoot.Inspect(GameDataDirectory).StateFilePath;
public static AetheriaClientState RuntimeState(
AetheriaRuntimeStateBootReport stateBoot,
string runtimeId = "")
{
return RuntimeClient(stateBoot, runtimeId).State;
}
public static AetheriaControl Control(
AetheriaRuntimeStateBootReport stateBoot,
string runtimeId = "")
{
return RuntimeClient(stateBoot, runtimeId).Control;
}
public static AetheriaUi Ui(
AetheriaRuntimeStateBootReport stateBoot,
string runtimeId = "")
{
return RuntimeClient(stateBoot, runtimeId).Ui;
}
public static CultMeshStateRefResolver EveSurfaceCultMeshStateRefResolver(
AetheriaRuntimeStateBootReport stateBoot,
string runtimeId = "")
{
return RuntimeState(stateBoot, runtimeId).CreateEveSurfaceCultMeshStateRefResolver();
}
public static void ClearRuntimeStateFilePathCache()
{
s_runtimeStateFilePath = null;
}
public static void Dispose()
{
foreach (var client in RuntimeClients.Values)
client.Dispose();
RuntimeClients.Clear();
s_runtimeStateFilePath = null;
}
private static AetheriaClient RuntimeClient(
AetheriaRuntimeStateBootReport stateBoot,
string runtimeId = "")
{
return ResolveClient(
stateBoot.StateFilePath,
string.IsNullOrWhiteSpace(runtimeId) ? stateBoot.RuntimeId : runtimeId);
}
private static AetheriaClient ResolveClient(string stateFilePath, string runtimeId)
{
var effectiveStateFilePath = stateFilePath ?? "";
var effectiveRuntimeId = string.IsNullOrWhiteSpace(runtimeId)
? AetheriaRuntimeStateBoundary.DefaultClientRuntimeId
: runtimeId;
var cacheKey = effectiveStateFilePath + "\n" + effectiveRuntimeId;
if (RuntimeClients.TryGetValue(cacheKey, out var runtimeClient))
return runtimeClient;
runtimeClient = AetheriaClient
.OpenAsync(
effectiveStateFilePath,
effectiveRuntimeId,
"local",
startServer: false,
pullOnOpen: true)
.GetAwaiter()
.GetResult();
RuntimeClients[cacheKey] = runtimeClient;
return runtimeClient;
}
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 2a2c3bf5e2954d1f8aeab60ee92f7f0a

View file

@ -0,0 +1,28 @@
using GameCult.Aetheria.State.Verse;
using UnityEngine;
#nullable enable
namespace GameCult.Aetheria.EveRuntime
{
public static class AetheriaEveRuntimeUnityHookInstaller
{
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
public static void Install()
{
AetheriaEveRuntimeUnityHooks.ResolveStateBoot =
overridePath => AetheriaRuntimeStateBoot.Inspect(
AetheriaEveRuntimeUnityClientCache.GameDataDirectory,
overridePath ?? "");
AetheriaEveRuntimeUnityHooks.RuntimeState =
(stateBoot, runtimeId) => AetheriaEveRuntimeUnityClientCache.RuntimeState(stateBoot, runtimeId);
AetheriaEveRuntimeUnityHooks.Control =
(stateBoot, runtimeId) => AetheriaEveRuntimeUnityClientCache.Control(stateBoot, runtimeId);
AetheriaEveRuntimeUnityHooks.Ui =
(stateBoot, runtimeId) => AetheriaEveRuntimeUnityClientCache.Ui(stateBoot, runtimeId);
AetheriaEveRuntimeUnityHooks.StateRefResolver =
(stateBoot, runtimeId) =>
AetheriaEveRuntimeUnityClientCache.EveSurfaceCultMeshStateRefResolver(stateBoot, runtimeId);
}
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d60d5ddc6b3240438128f85f90464b42