feat(plugins): complete Campaign LA5 cross-host hosting
This commit is contained in:
parent
6c4cd2bbc6
commit
95f4be94db
26 changed files with 1630 additions and 99 deletions
|
|
@ -56,6 +56,11 @@ internal sealed class HeadlessProcessHost : IDisposable
|
|||
paths.ConfigDirectory);
|
||||
var sessions = new List<HeadlessSessionHost>(
|
||||
configuration.Sessions.Count);
|
||||
string[] pluginRoots =
|
||||
[
|
||||
Path.Combine(AppContext.BaseDirectory, "plugins"),
|
||||
paths.PluginsDirectory,
|
||||
];
|
||||
HeadlessProcessContentOwner? content = null;
|
||||
HeadlessProcessResourceSampler? resources = null;
|
||||
// FA6: constructed unconditionally — cheap, and every non-gate
|
||||
|
|
@ -104,7 +109,8 @@ internal sealed class HeadlessProcessHost : IDisposable
|
|||
sessionOperations,
|
||||
timeProvider,
|
||||
contentLease: contentLease,
|
||||
gateCoordinator: gateCoordinator));
|
||||
gateCoordinator: gateCoordinator,
|
||||
pluginRoots: pluginRoots));
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using AcDream.Headless.Configuration;
|
||||
using AcDream.Headless.Credentials;
|
||||
using AcDream.Headless.Diagnostics;
|
||||
using AcDream.Headless.Plugins;
|
||||
using AcDream.Headless.Policies;
|
||||
using AcDream.Core.Net.Messages;
|
||||
using AcDream.Core.Physics;
|
||||
|
|
@ -155,6 +156,7 @@ internal sealed class HeadlessSessionHost : IDisposable
|
|||
private readonly IDisposable _hostLease;
|
||||
private readonly IHeadlessBotPolicy _policy;
|
||||
private readonly IDisposable _policySubscription;
|
||||
private readonly HeadlessPluginSession _pluginSession;
|
||||
private readonly LiveSessionHost _liveSession;
|
||||
private readonly RuntimeLocalPlayerFrameController _localPlayerFrame;
|
||||
private readonly HeadlessProcessContentOwner.HeadlessProcessContentLease?
|
||||
|
|
@ -238,7 +240,8 @@ internal sealed class HeadlessSessionHost : IDisposable
|
|||
contentLease = null,
|
||||
IHeadlessBotPolicy? policyOverride = null,
|
||||
IRuntimePlacementProjectionSink? placementSinkOverride = null,
|
||||
FellowshipAllegianceGateCoordinator? gateCoordinator = null)
|
||||
FellowshipAllegianceGateCoordinator? gateCoordinator = null,
|
||||
IEnumerable<string>? pluginRoots = null)
|
||||
{
|
||||
_descriptor = descriptor
|
||||
?? throw new ArgumentNullException(nameof(descriptor));
|
||||
|
|
@ -263,6 +266,7 @@ internal sealed class HeadlessSessionHost : IDisposable
|
|||
IDisposable? hostLease = null;
|
||||
IHeadlessBotPolicy? policy = null;
|
||||
IDisposable? policySubscription = null;
|
||||
HeadlessPluginSession? pluginSession = null;
|
||||
try
|
||||
{
|
||||
var gameplay = new HeadlessGameplayOperations();
|
||||
|
|
@ -297,6 +301,13 @@ internal sealed class HeadlessSessionHost : IDisposable
|
|||
// descriptor.StatusFile is unset — every call site below stays
|
||||
// unconditional.
|
||||
var statusWriter = new SessionStatusWriter(descriptor.StatusFile);
|
||||
pluginSession = HeadlessPluginSession.Start(
|
||||
runtime,
|
||||
diagnostics,
|
||||
statusWriter,
|
||||
descriptor.Id,
|
||||
pluginRoots ?? [],
|
||||
descriptor.Plugins);
|
||||
var liveSession = new LiveSessionHost(
|
||||
runtime.Session,
|
||||
new LiveSessionHostBindings(
|
||||
|
|
@ -402,9 +413,11 @@ internal sealed class HeadlessSessionHost : IDisposable
|
|||
_hostLease = hostLease;
|
||||
_policy = policy;
|
||||
_policySubscription = policySubscription;
|
||||
_pluginSession = pluginSession;
|
||||
}
|
||||
catch
|
||||
{
|
||||
pluginSession?.Dispose();
|
||||
policySubscription?.Dispose();
|
||||
policy?.Dispose();
|
||||
hostLease?.Dispose();
|
||||
|
|
@ -427,6 +440,7 @@ internal sealed class HeadlessSessionHost : IDisposable
|
|||
/// production code uses to reach the same state.
|
||||
/// </summary>
|
||||
internal HeadlessCharacterOptionsSeeder? OptionsSeeder => _optionsSeeder;
|
||||
internal HeadlessPluginSession Plugins => _pluginSession;
|
||||
internal string SessionId => _descriptor.Id;
|
||||
internal string ActiveCharacterName { get; private set; } =
|
||||
string.Empty;
|
||||
|
|
@ -638,22 +652,26 @@ internal sealed class HeadlessSessionHost : IDisposable
|
|||
_disposeStage++;
|
||||
break;
|
||||
case 4:
|
||||
_hostLease.Dispose();
|
||||
_pluginSession.Dispose();
|
||||
_disposeStage++;
|
||||
break;
|
||||
case 5:
|
||||
_credential.Dispose();
|
||||
_hostLease.Dispose();
|
||||
_disposeStage++;
|
||||
break;
|
||||
case 6:
|
||||
Runtime.Dispose();
|
||||
_credential.Dispose();
|
||||
_disposeStage++;
|
||||
break;
|
||||
case 7:
|
||||
_contentLease?.Dispose();
|
||||
Runtime.Dispose();
|
||||
_disposeStage++;
|
||||
break;
|
||||
case 8:
|
||||
_contentLease?.Dispose();
|
||||
_disposeStage++;
|
||||
break;
|
||||
case 9:
|
||||
_diagnostics.Message(
|
||||
_descriptor.Id,
|
||||
"disposed",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue