Carry authenticated Verse transport through Unity

This commit is contained in:
Meta Vens 2026-08-18 20:14:02 +02:00
commit e8e116ecc4
7 changed files with 72 additions and 8 deletions

View file

@ -0,0 +1,49 @@
using System;
using GameCult.Mesh;
using GameCult.Networking;
using GameCult.Networking.WebSockets;
#nullable enable
namespace GameCult.Eve.UnityScene
{
/// <summary>
/// Owns the transport set used by EveUnity for both rendezvous discovery and
/// the selected provider. Trust remains caller-owned; this class only makes
/// every supported secure plane reachable through the same configuration.
/// </summary>
internal static class EveUnityCultMeshConnectivity
{
public static CultMeshVerseDiscoveryClientOptions Discovery() => new()
{
CreateClientForEndpoint = CreateSchemaClient
};
public static ICultMeshTransportConnector[] SchemaConnectors() => new ICultMeshTransportConnector[]
{
new CultMeshTcpSchemaTransportConnector(),
new CultMeshUriSchemaTransportConnector(
"cultnet-websocket",
new[] { "ws", "wss" },
_ => new CultNetWebSocketSchemaClient())
};
public static ICultMeshContentTransportConnector[] ContentConnectors() =>
new ICultMeshContentTransportConnector[]
{
new CultMeshHttpsContentTransportConnector(),
new CultMeshTcpContentTransportConnector()
};
private static ICultNetSchemaClient CreateSchemaClient(string endpoint)
{
if (Uri.TryCreate(endpoint, UriKind.Absolute, out var uri) &&
(string.Equals(uri.Scheme, "ws", StringComparison.OrdinalIgnoreCase) ||
string.Equals(uri.Scheme, "wss", StringComparison.OrdinalIgnoreCase)))
{
return new CultNetWebSocketSchemaClient();
}
return CultNetSchemaClients.CreateForEndpoint(endpoint);
}
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 7f7cb06716fd4f319ade147a69acb74a

View file

@ -513,7 +513,10 @@ namespace GameCult.Eve.UnityScene
_meshClient = new CultMeshClient(new CultMeshClientOptions
{
RendezvousEndpoints = new[] { _rendezvousEndpoint },
Discovery = EveUnityCultMeshConnectivity.Discovery(),
Sessions = new CultMeshSessionManagerOptions { Trust = _authorityTrust },
Connectors = EveUnityCultMeshConnectivity.SchemaConnectors(),
ContentConnectors = EveUnityCultMeshConnectivity.ContentConnectors(),
RealtimeConnectors = new ICultMeshRealtimeTransportConnector[]
{
new CultMeshNativeQuicRealtimeTransportConnector()

View file

@ -42,6 +42,8 @@ namespace GameCult.Eve.UnityScene
[SerializeField] private string runtimeId = "eve-unity";
private CultMeshAuthorityTrustPolicy _authorityTrust = new CultMeshAuthorityTrustPolicy(
CultMeshAuthorityTrustMode.AuthenticatedRemote);
private CultMeshAuthorityTrustPolicy _navigationAuthorityTrust = new CultMeshAuthorityTrustPolicy(
CultMeshAuthorityTrustMode.AuthenticatedRemote);
private EveUnityCultMeshLiveProviderTransport? _transport;
private EveUnitySceneLiveProviderBridge? _bridge;
@ -90,7 +92,8 @@ namespace GameCult.Eve.UnityScene
string verseId = "",
string requiredSurfaceKind = "interactive-world",
string clientRuntimeId = "eve-unity",
CultMeshAuthorityTrustPolicy? authorityTrust = null)
CultMeshAuthorityTrustPolicy? authorityTrust = null,
CultMeshAuthorityTrustPolicy? navigationAuthorityTrust = null)
{
if (_bridge != null || _preparation != null)
throw new InvalidOperationException("Disconnect the active provider before changing discovery configuration.");
@ -104,6 +107,7 @@ namespace GameCult.Eve.UnityScene
runtimeId = string.IsNullOrWhiteSpace(clientRuntimeId) ? "eve-unity" : clientRuntimeId;
_authorityTrust = authorityTrust ?? new CultMeshAuthorityTrustPolicy(
CultMeshAuthorityTrustMode.AuthenticatedRemote);
_navigationAuthorityTrust = navigationAuthorityTrust ?? _authorityTrust;
}
public void Connect()
@ -141,7 +145,10 @@ namespace GameCult.Eve.UnityScene
var navigationEndpoint = target.RendezvousEndpoints
.FirstOrDefault(endpoint => !string.IsNullOrWhiteSpace(endpoint));
if (!string.IsNullOrWhiteSpace(navigationEndpoint))
{
rendezvousEndpoint = navigationEndpoint;
_authorityTrust = _navigationAuthorityTrust;
}
verseFilter = target.VerseId;
providerFilter = target.ProviderId;
surfaceFilter = target.SurfaceId;

View file

@ -61,7 +61,7 @@ namespace GameCult.Eve.UnityScene
CultMeshVerseCatalogResponseMessage response;
try
{
response = await CultMesh.CreateVerseDiscoveryClient().FetchAsync(
response = await CultMesh.CreateVerseDiscoveryClient(EveUnityCultMeshConnectivity.Discovery()).FetchAsync(
rendezvousEndpoint,
new CultMeshVerseCatalogRequestMessage
{
@ -94,7 +94,10 @@ namespace GameCult.Eve.UnityScene
using var mesh = new CultMeshClient(new CultMeshClientOptions
{
RendezvousEndpoints = new[] { rendezvousEndpoint },
Sessions = new CultMeshSessionManagerOptions { Trust = _authorityTrust }
Discovery = EveUnityCultMeshConnectivity.Discovery(),
Sessions = new CultMeshSessionManagerOptions { Trust = _authorityTrust },
Connectors = EveUnityCultMeshConnectivity.SchemaConnectors(),
ContentConnectors = EveUnityCultMeshConnectivity.ContentConnectors()
});
foreach (var candidate in candidates)
{

View file

@ -1,14 +1,14 @@
{
"name": "org.gamecult.eve.unity-scene",
"displayName": "Eve Unity Scene Lowering",
"version": "0.3.110",
"version": "0.3.111",
"unity": "6000.0",
"description": "Provider-agnostic Unity scene shell for gamecult.eve.surface.v1 interactive world surfaces.",
"dependencies": {
"org.gamecult.cultlib": "1.0.48",
"org.gamecult.cultlib": "1.0.49",
"org.gamecult.eve.plugin-fields": "0.2.3",
"org.gamecult.eve.surface": "0.3.3",
"org.gamecult.eve.unity-uitoolkit": "0.1.4",
"org.gamecult.eve.unity-uitoolkit": "0.1.5",
"com.unity.mathematics": "1.3.2",
"com.unity.render-pipelines.universal": "17.4.0",
"com.unity.modules.particlesystem": "1.0.0"

View file

@ -1,11 +1,11 @@
{
"name": "org.gamecult.eve.unity-uitoolkit",
"displayName": "Eve UI Toolkit Lowering",
"version": "0.1.4",
"version": "0.1.5",
"unity": "2021.3",
"description": "Unity UI Toolkit lowering for gamecult.eve.surface.v1 documents.",
"dependencies": {
"org.gamecult.eve.surface": "0.3.2"
"org.gamecult.eve.surface": "0.3.3"
},
"keywords": [
"Eve",