Preserve navigation authority through Unity discovery
This commit is contained in:
parent
ef83ba78bb
commit
781e612c23
6 changed files with 47 additions and 10 deletions
|
|
@ -1601,7 +1601,8 @@ namespace GameCult.Eve.UnityScene
|
|||
receipt.Navigation.ProviderId,
|
||||
receipt.Navigation.SurfaceId,
|
||||
receipt.Navigation.SurfaceKind,
|
||||
receipt.Navigation.RendezvousEndpoints)));
|
||||
receipt.Navigation.RendezvousEndpoints,
|
||||
receipt.Navigation.AuthorityRuntimeId)));
|
||||
}
|
||||
|
||||
private sealed class ReceiptSubscription : IDisposable
|
||||
|
|
|
|||
|
|
@ -170,6 +170,7 @@ namespace GameCult.Eve.UnityScene
|
|||
target.SurfaceId,
|
||||
requiredSurfaceKind,
|
||||
target.VerseId,
|
||||
target.AuthorityRuntimeId,
|
||||
_navigationAuthorityTrust,
|
||||
CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
|
|
@ -352,6 +353,7 @@ namespace GameCult.Eve.UnityScene
|
|||
surfaceFilter,
|
||||
surfaceKind,
|
||||
verseFilter,
|
||||
"",
|
||||
_authorityTrust,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
TraceStartup($"discovery and transport preparation {elapsed.Elapsed.TotalMilliseconds:0.###}ms");
|
||||
|
|
@ -364,6 +366,7 @@ namespace GameCult.Eve.UnityScene
|
|||
string requiredSurfaceId,
|
||||
string requiredSurfaceKind,
|
||||
string requiredVerseId,
|
||||
string requiredAuthorityRuntimeId,
|
||||
CultMeshAuthorityTrustPolicy trust,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
|
|
@ -379,7 +382,8 @@ namespace GameCult.Eve.UnityScene
|
|||
requiredSurfaceId,
|
||||
requiredSurfaceKind,
|
||||
requiredVerseId,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
cancellationToken,
|
||||
requiredAuthorityRuntimeId).ConfigureAwait(false);
|
||||
var resolvedCachePath = string.IsNullOrWhiteSpace(cacheDirectory)
|
||||
? Path.Combine(Application.temporaryCachePath, $"eve-unity-{GetInstanceID()}")
|
||||
: cacheDirectory;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,8 @@ namespace GameCult.Eve.UnityScene
|
|||
string surfaceId = "",
|
||||
string surfaceKind = "interactive-world",
|
||||
string verseId = "",
|
||||
CancellationToken cancellationToken = default)
|
||||
CancellationToken cancellationToken = default,
|
||||
string requiredAuthorityRuntimeId = "")
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(rendezvousEndpoint))
|
||||
throw new ArgumentException("Rendezvous endpoint must be non-empty.", nameof(rendezvousEndpoint));
|
||||
|
|
@ -101,10 +102,9 @@ namespace GameCult.Eve.UnityScene
|
|||
});
|
||||
foreach (var candidate in candidates)
|
||||
{
|
||||
foreach (var authorityRuntimeId in (candidate.AuthorityRuntimeIds ?? Array.Empty<string>())
|
||||
.Where(id => !string.IsNullOrWhiteSpace(id))
|
||||
.Distinct(StringComparer.Ordinal)
|
||||
.OrderBy(id => id, StringComparer.Ordinal))
|
||||
foreach (var authorityRuntimeId in EligibleAuthorityRuntimeIds(
|
||||
candidate.AuthorityRuntimeIds,
|
||||
requiredAuthorityRuntimeId))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -146,11 +146,22 @@ namespace GameCult.Eve.UnityScene
|
|||
}
|
||||
}
|
||||
|
||||
var filter = $"provider='{providerId}', surface='{surfaceId}', kind='{surfaceKind}'";
|
||||
var filter = $"provider='{providerId}', surface='{surfaceId}', kind='{surfaceKind}', authority='{requiredAuthorityRuntimeId}'";
|
||||
var detail = failures.Count == 0 ? "" : $" Endpoint failures: {string.Join(" | ", failures)}";
|
||||
var observedDetail = observed.Count == 0 ? "" : $" Observed: {string.Join(" | ", observed)}";
|
||||
throw new InvalidOperationException($"No advertised Eve surface matched {filter}.{detail}{observedDetail}");
|
||||
}
|
||||
|
||||
internal static IReadOnlyList<string> EligibleAuthorityRuntimeIds(
|
||||
IEnumerable<string>? authorityRuntimeIds,
|
||||
string requiredAuthorityRuntimeId) =>
|
||||
(authorityRuntimeIds ?? Array.Empty<string>())
|
||||
.Where(id => !string.IsNullOrWhiteSpace(id))
|
||||
.Where(id => string.IsNullOrWhiteSpace(requiredAuthorityRuntimeId) ||
|
||||
string.Equals(id, requiredAuthorityRuntimeId, StringComparison.Ordinal))
|
||||
.Distinct(StringComparer.Ordinal)
|
||||
.OrderBy(id => id, StringComparer.Ordinal)
|
||||
.ToArray();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -253,9 +253,11 @@ namespace GameCult.Eve.UnityScene
|
|||
string providerId,
|
||||
string surfaceId,
|
||||
string surfaceKind,
|
||||
IReadOnlyList<string>? rendezvousEndpoints = null)
|
||||
IReadOnlyList<string>? rendezvousEndpoints = null,
|
||||
string authorityRuntimeId = "")
|
||||
{
|
||||
VerseId = verseId ?? "";
|
||||
AuthorityRuntimeId = authorityRuntimeId ?? "";
|
||||
ProviderId = providerId ?? "";
|
||||
SurfaceId = surfaceId ?? "";
|
||||
SurfaceKind = surfaceKind ?? "";
|
||||
|
|
@ -263,6 +265,7 @@ namespace GameCult.Eve.UnityScene
|
|||
}
|
||||
|
||||
public string VerseId { get; }
|
||||
public string AuthorityRuntimeId { get; }
|
||||
public string ProviderId { get; }
|
||||
public string SurfaceId { get; }
|
||||
public string SurfaceKind { get; }
|
||||
|
|
|
|||
|
|
@ -168,6 +168,24 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
Assert.That(typeof(EveUnityCultMeshProviderSelection).GetProperty("Endpoint"), Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NavigationAuthorityCannotBeReplacedByAlphabeticallyEarlierPeer()
|
||||
{
|
||||
var target = new EveUnitySceneNavigationTarget(
|
||||
"gamecult.aetheria",
|
||||
"aetheria.daemon",
|
||||
"aetheria.pilot",
|
||||
"interactive-world",
|
||||
new[] { "cultnet+tcp://odin.example:3075" },
|
||||
"z-owner");
|
||||
var eligible = EveUnityCultMeshProviderDiscovery.EligibleAuthorityRuntimeIds(
|
||||
new[] { "a-decoy", "z-owner" },
|
||||
target.AuthorityRuntimeId);
|
||||
|
||||
Assert.That(target.AuthorityRuntimeId, Is.EqualTo("z-owner"));
|
||||
CollectionAssert.AreEqual(new[] { "z-owner" }, eligible);
|
||||
}
|
||||
|
||||
private static EveSurfaceCommandRequest Request(string id, string command) => new EveSurfaceCommandRequest(
|
||||
"test.provider",
|
||||
"test.surface",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "org.gamecult.eve.unity-scene",
|
||||
"displayName": "Eve Unity Scene Lowering",
|
||||
"version": "0.3.119",
|
||||
"version": "0.3.120",
|
||||
"unity": "6000.0",
|
||||
"description": "Provider-agnostic Unity scene shell for gamecult.eve.surface.v1 interactive world surfaces.",
|
||||
"dependencies": {
|
||||
|
|
|
|||
Reference in a new issue