fix(headless): complete connected movement gate
This commit is contained in:
parent
fd9559a063
commit
3f3401257c
11 changed files with 756 additions and 48 deletions
|
|
@ -23,7 +23,8 @@ internal sealed class HeadlessProcessHost : IDisposable
|
|||
TextWriter diagnostics,
|
||||
ILiveSessionOperations? sessionOperations = null,
|
||||
TimeProvider? timeProvider = null,
|
||||
IHeadlessProcessContentFactory? contentFactory = null)
|
||||
IHeadlessProcessContentFactory? contentFactory = null,
|
||||
HeadlessDirectCredentials? directCredentials = null)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(configuration);
|
||||
ArgumentNullException.ThrowIfNull(paths);
|
||||
|
|
@ -34,6 +35,12 @@ internal sealed class HeadlessProcessHost : IDisposable
|
|||
throw new HeadlessConfigurationException(
|
||||
"Headless run mode requires at least one session.");
|
||||
}
|
||||
if (directCredentials is not null
|
||||
&& configuration.Sessions.Count != 1)
|
||||
{
|
||||
throw new HeadlessConfigurationException(
|
||||
"Direct credentials require exactly one configured session.");
|
||||
}
|
||||
HeadlessStaticStateAudit.ValidateProcessIsolation();
|
||||
|
||||
_diagnostics = new HeadlessDiagnosticWriter(diagnostics);
|
||||
|
|
@ -61,10 +68,19 @@ internal sealed class HeadlessProcessHost : IDisposable
|
|||
HeadlessSessionDescriptor descriptor = candidate
|
||||
?? throw new HeadlessConfigurationException(
|
||||
"Headless run mode cannot contain a null session.");
|
||||
HeadlessCredentialSecret secret =
|
||||
credentials.Resolve(
|
||||
if (directCredentials is not null)
|
||||
{
|
||||
descriptor = WithAccount(
|
||||
descriptor,
|
||||
directCredentials.User);
|
||||
}
|
||||
HeadlessCredentialSecret secret = directCredentials is null
|
||||
? credentials.Resolve(
|
||||
descriptor.Id,
|
||||
descriptor.Credential);
|
||||
descriptor.Credential)
|
||||
: new HeadlessCredentialSecret(
|
||||
"command-line",
|
||||
directCredentials.Password);
|
||||
HeadlessProcessContentOwner.HeadlessProcessContentLease?
|
||||
contentLease = content?.AcquireLease(descriptor.Id);
|
||||
try
|
||||
|
|
@ -111,6 +127,19 @@ internal sealed class HeadlessProcessHost : IDisposable
|
|||
internal HeadlessProcessContentSnapshot? Content =>
|
||||
_content?.CaptureSnapshot();
|
||||
|
||||
private static HeadlessSessionDescriptor WithAccount(
|
||||
HeadlessSessionDescriptor source,
|
||||
string account) =>
|
||||
new()
|
||||
{
|
||||
Id = source.Id,
|
||||
Endpoint = source.Endpoint,
|
||||
Account = account,
|
||||
Character = source.Character,
|
||||
Policy = source.Policy,
|
||||
Credential = source.Credential,
|
||||
};
|
||||
|
||||
internal async Task<HeadlessExitCode> RunAsync(
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -293,10 +293,20 @@ internal sealed class HeadlessSessionWorldProjection
|
|||
|
||||
public void ProjectPosition(
|
||||
RuntimeEntityRecord record,
|
||||
bool isLocalPlayer)
|
||||
bool isLocalPlayer,
|
||||
PositionTimestampDisposition disposition)
|
||||
{
|
||||
if (isLocalPlayer)
|
||||
if (!isLocalPlayer)
|
||||
return;
|
||||
|
||||
if (_runtime.MovementOwner.Controller is null)
|
||||
{
|
||||
SynchronizeLocalPlayer(record);
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposition is PositionTimestampDisposition.ForcePosition)
|
||||
BlipLocalPlayer(record);
|
||||
}
|
||||
|
||||
public void BeginTeleport()
|
||||
|
|
@ -383,6 +393,28 @@ internal sealed class HeadlessSessionWorldProjection
|
|||
controller.SetBodyOrientation(orientation);
|
||||
}
|
||||
|
||||
private void BlipLocalPlayer(RuntimeEntityRecord record)
|
||||
{
|
||||
if (record.ServerGuid
|
||||
!= _runtime.PlayerIdentity.ServerGuid
|
||||
|| record.Snapshot.Position is not { } position
|
||||
|| _runtime.MovementOwner.Controller is not { } controller)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_collision.CenterOn(position.LandblockId);
|
||||
Vector3 wirePosition = new(
|
||||
position.PositionX,
|
||||
position.PositionY,
|
||||
position.PositionZ);
|
||||
controller.LocalEntityId = record.LocalEntityId ?? 0u;
|
||||
controller.BlipPosition(
|
||||
wirePosition,
|
||||
position.LandblockId,
|
||||
wirePosition);
|
||||
}
|
||||
|
||||
private PlayerMovementController CreateController(
|
||||
RuntimeEntityRecord record)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue