2026-06-21 08:56:07 +01:00
|
|
|
using System;
|
2026-06-29 07:01:38 +01:00
|
|
|
using GameCult.Eve.Surface;
|
2026-06-25 18:09:33 +01:00
|
|
|
using GameCult.Mesh;
|
|
|
|
|
|
|
|
|
|
#nullable enable
|
2026-06-21 08:56:07 +01:00
|
|
|
|
2026-06-22 14:08:25 +01:00
|
|
|
namespace GameCult.Aetheria.State.Verse
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-22 14:08:25 +01:00
|
|
|
public sealed class AetheriaRuntimeDaemonOperationsClient
|
|
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
private readonly Func<Func<AetheriaRuntimeDaemonOperationClient, AetheriaRuntimeDaemonFrameDocument?, AetheriaRuntimeDaemonCommandEnvelope>, AetheriaRuntimeDaemonCommandEnvelope> _submit;
|
2026-06-21 08:56:07 +01:00
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
internal AetheriaRuntimeDaemonOperationsClient(
|
2026-06-29 02:56:43 +01:00
|
|
|
Func<Func<AetheriaRuntimeDaemonOperationClient, AetheriaRuntimeDaemonFrameDocument?, AetheriaRuntimeDaemonCommandEnvelope>, AetheriaRuntimeDaemonCommandEnvelope> submit)
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-22 14:08:25 +01:00
|
|
|
_submit = submit ?? throw new ArgumentNullException(nameof(submit));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-07-10 04:39:16 +01:00
|
|
|
public static bool TryCreateSurfaceCommandDocument(
|
|
|
|
|
EveSurfaceCommandRequest request,
|
|
|
|
|
AetheriaRuntimeDaemonFrameDocument? frame,
|
|
|
|
|
string stateFilePath,
|
|
|
|
|
string clientId,
|
|
|
|
|
string sessionId,
|
|
|
|
|
out AetheriaRuntimeDaemonCommandDocument? command)
|
|
|
|
|
{
|
|
|
|
|
command = null;
|
|
|
|
|
if (request == null)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
AetheriaRuntimeDaemonCommandDocument? translated = null;
|
|
|
|
|
var operations = new AetheriaRuntimeDaemonOperationsClient(submit =>
|
|
|
|
|
{
|
|
|
|
|
var client = new AetheriaRuntimeDaemonOperationClient(
|
|
|
|
|
string.IsNullOrWhiteSpace(stateFilePath) ? "." : stateFilePath,
|
|
|
|
|
clientId,
|
|
|
|
|
sessionId,
|
|
|
|
|
document =>
|
|
|
|
|
{
|
|
|
|
|
translated = document;
|
|
|
|
|
return AetheriaRuntimeDaemonOperationClient.ToEnvelope(document);
|
|
|
|
|
});
|
|
|
|
|
return submit(client, frame);
|
|
|
|
|
});
|
|
|
|
|
var accepted = operations.TrySubmitSurfaceCommand(request, out _);
|
2026-07-10 05:05:27 +01:00
|
|
|
var actorEntityKey = ReadPayloadString(request, "entityId", "");
|
|
|
|
|
if (translated != null && !string.IsNullOrWhiteSpace(actorEntityKey))
|
|
|
|
|
translated.ActorEntityKey = actorEntityKey;
|
|
|
|
|
if (string.Equals(Environment.GetEnvironmentVariable("AETHERIA_TRACE_EVE_SNAPSHOTS"), "1", StringComparison.Ordinal))
|
|
|
|
|
Console.WriteLine(
|
|
|
|
|
$"Eve command translated command={request.Command} actor={translated?.ActorEntityKey ?? "missing"} " +
|
|
|
|
|
$"direction={translated?.DirectionX},{translated?.DirectionY} scalar={translated?.ScalarValue}");
|
2026-07-10 04:39:16 +01:00
|
|
|
command = translated;
|
|
|
|
|
return accepted && command != null;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-21 08:56:07 +01:00
|
|
|
public AetheriaRuntimeDaemonCommandEnvelope SetTarget(string targetEntityKey)
|
|
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Submit((client, frame) => client.SetTarget(frame, targetEntityKey));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt ClearTarget()
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.ClearTarget(frame));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt TargetNearest()
|
2026-06-21 11:41:32 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.TargetNearest(frame));
|
2026-06-21 11:41:32 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt TargetNext()
|
2026-06-21 11:41:32 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.TargetNext(frame));
|
2026-06-21 11:41:32 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt TargetPrevious()
|
2026-06-21 11:41:32 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.TargetPrevious(frame));
|
2026-06-21 11:41:32 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt TargetReticle(double directionX, double directionY, double directionZ)
|
2026-06-21 11:45:58 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.TargetReticle(frame, directionX, directionY, directionZ));
|
2026-06-21 11:45:58 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-21 08:56:07 +01:00
|
|
|
public AetheriaRuntimeDaemonCommandEnvelope SetMoveVector(
|
|
|
|
|
double directionX,
|
|
|
|
|
double directionY,
|
|
|
|
|
double scalarValue = 1.0)
|
|
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Submit((client, frame) => client.SetMoveVector(frame, directionX, directionY, scalarValue));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt SetLookDirection(double directionX, double directionY, double directionZ)
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.SetLookDirection(frame, directionX, directionY, directionZ));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt SetTractorPower(double power)
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.SetTractorPower(frame, power));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt FireWeaponGroup(int weaponGroup)
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.FireWeaponGroup(frame, weaponGroup));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt SetWeaponGroupActive(int weaponGroup, bool active)
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.SetWeaponGroupActive(frame, weaponGroup, active));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt SetWeaponGroupMembership(
|
2026-06-21 08:56:07 +01:00
|
|
|
string targetEntityKey,
|
|
|
|
|
int equipmentIndex,
|
|
|
|
|
int weaponGroup,
|
|
|
|
|
bool assigned)
|
|
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.SetWeaponGroupMembership(
|
|
|
|
|
frame,
|
2026-06-21 11:26:41 +01:00
|
|
|
targetEntityKey,
|
|
|
|
|
equipmentIndex,
|
|
|
|
|
weaponGroup,
|
|
|
|
|
assigned));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt SetBehaviorActive(int equipmentIndex, int behaviorIndex, bool active)
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.SetBehaviorActive(frame, equipmentIndex, behaviorIndex, active));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt ActivateConsumable(string itemKey)
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.ActivateConsumable(frame, itemKey));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt SensorPing()
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.SensorPing(frame));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt SetHeatsinksEnabled(bool enabled)
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.SetHeatsinksEnabled(frame, enabled));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt SetOverrideShutdown(bool enabled)
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.SetOverrideShutdown(frame, enabled));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt SetEntityOverrideShutdown(string targetEntityKey, bool enabled)
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.SetOverrideShutdown(frame, targetEntityKey, enabled));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt SetItemEnabled(int equipmentIndex, bool enabled)
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.SetItemEnabled(frame, equipmentIndex, enabled));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt ToggleShieldEnabled()
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.ToggleShieldEnabled(frame));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt SetItemOverrideShutdown(
|
2026-06-21 08:56:07 +01:00
|
|
|
string targetEntityKey,
|
|
|
|
|
int equipmentIndex,
|
|
|
|
|
bool enabled)
|
|
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.SetItemOverrideShutdown(
|
|
|
|
|
frame,
|
2026-06-21 11:26:41 +01:00
|
|
|
targetEntityKey,
|
|
|
|
|
equipmentIndex,
|
|
|
|
|
enabled));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt SetThermotoggleTargetTemperature(
|
2026-06-21 08:56:07 +01:00
|
|
|
string targetEntityKey,
|
|
|
|
|
int equipmentIndex,
|
|
|
|
|
int behaviorIndex,
|
|
|
|
|
double targetTemperature)
|
|
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.SetThermotoggleTargetTemperature(
|
|
|
|
|
frame,
|
2026-06-21 11:26:41 +01:00
|
|
|
targetEntityKey,
|
|
|
|
|
equipmentIndex,
|
|
|
|
|
behaviorIndex,
|
|
|
|
|
targetTemperature));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt SetShutdownPerformance(
|
2026-06-21 08:56:07 +01:00
|
|
|
string targetEntityKey,
|
|
|
|
|
double shutdownPerformance)
|
|
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.SetShutdownPerformance(
|
|
|
|
|
frame,
|
2026-06-21 11:26:41 +01:00
|
|
|
targetEntityKey,
|
|
|
|
|
shutdownPerformance));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt ToggleHullConductivity(
|
2026-06-21 08:56:07 +01:00
|
|
|
string targetEntityKey,
|
|
|
|
|
int x,
|
|
|
|
|
int y,
|
|
|
|
|
int axis)
|
|
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.ToggleHullConductivity(frame, targetEntityKey, x, y, axis));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt SetEntityName(string targetEntityKey, string name)
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.SetEntityName(frame, targetEntityKey, name));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt Dock(string targetEntityKey)
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.Dock(frame, targetEntityKey));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt DockNearest()
|
2026-06-21 11:32:46 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.DockNearest(frame));
|
2026-06-21 11:32:46 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt Undock()
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.Undock(frame));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt Interact()
|
2026-06-21 11:51:37 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.Interact(frame));
|
2026-06-21 11:51:37 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt SetDockedCurrentShip(string targetEntityKey)
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.SetDockedCurrentShip(frame, targetEntityKey));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt EnterWormhole(
|
2026-06-21 08:56:07 +01:00
|
|
|
int targetZoneIndex,
|
|
|
|
|
double positionX,
|
|
|
|
|
double positionY)
|
|
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.EnterWormhole(frame, targetZoneIndex, positionX, positionY));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt TowToStation(string stationEntityKey)
|
2026-06-21 08:56:07 +01:00
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.TowToStation(frame, stationEntityKey));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt TransferCargoItem(
|
2026-06-21 08:56:07 +01:00
|
|
|
string originEntityKey,
|
|
|
|
|
int originCargoIndex,
|
|
|
|
|
string destinationEntityKey,
|
|
|
|
|
int destinationCargoIndex,
|
|
|
|
|
string itemKey,
|
|
|
|
|
int quantity,
|
|
|
|
|
int sourceX,
|
|
|
|
|
int sourceY,
|
|
|
|
|
int destinationX,
|
|
|
|
|
int destinationY,
|
|
|
|
|
bool hasDestinationPosition)
|
|
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.TransferCargoItem(
|
|
|
|
|
frame,
|
2026-06-21 11:26:41 +01:00
|
|
|
originEntityKey,
|
|
|
|
|
originCargoIndex,
|
|
|
|
|
destinationEntityKey,
|
|
|
|
|
destinationCargoIndex,
|
|
|
|
|
itemKey,
|
|
|
|
|
quantity,
|
|
|
|
|
sourceX,
|
|
|
|
|
sourceY,
|
|
|
|
|
destinationX,
|
|
|
|
|
destinationY,
|
|
|
|
|
hasDestinationPosition));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt TradePurchase(
|
2026-06-21 08:56:07 +01:00
|
|
|
string purchaseKind,
|
|
|
|
|
string itemKey,
|
|
|
|
|
int quantity,
|
|
|
|
|
int unitPrice,
|
|
|
|
|
int totalPrice,
|
|
|
|
|
string stationEntityKey,
|
|
|
|
|
int stationCargoIndex,
|
|
|
|
|
string targetEntityKey,
|
|
|
|
|
int targetCargoIndex,
|
|
|
|
|
int sourceX,
|
|
|
|
|
int sourceY,
|
|
|
|
|
bool createsDockedShip)
|
|
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.TradePurchase(
|
|
|
|
|
frame,
|
2026-06-21 11:26:41 +01:00
|
|
|
purchaseKind,
|
|
|
|
|
itemKey,
|
|
|
|
|
quantity,
|
|
|
|
|
unitPrice,
|
|
|
|
|
totalPrice,
|
|
|
|
|
stationEntityKey,
|
|
|
|
|
stationCargoIndex,
|
|
|
|
|
targetEntityKey,
|
|
|
|
|
targetCargoIndex,
|
|
|
|
|
sourceX,
|
|
|
|
|
sourceY,
|
|
|
|
|
createsDockedShip));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt PickUpLoot(
|
2026-06-21 08:56:07 +01:00
|
|
|
string targetEntityKey,
|
|
|
|
|
string itemKey,
|
|
|
|
|
int quantity,
|
|
|
|
|
double positionX,
|
|
|
|
|
double positionY,
|
|
|
|
|
double positionZ)
|
|
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.PickUpLoot(
|
|
|
|
|
frame,
|
2026-06-21 11:26:41 +01:00
|
|
|
targetEntityKey,
|
|
|
|
|
itemKey,
|
|
|
|
|
quantity,
|
|
|
|
|
positionX,
|
|
|
|
|
positionY,
|
|
|
|
|
positionZ));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt RestoreLoadout(
|
2026-06-21 08:56:07 +01:00
|
|
|
string dockedEntityKey,
|
|
|
|
|
string templateName,
|
|
|
|
|
int price)
|
|
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.RestoreLoadout(frame, dockedEntityKey, templateName, price));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt EquipItem(
|
2026-06-21 08:56:07 +01:00
|
|
|
string sourceKind,
|
|
|
|
|
string originEntityKey,
|
|
|
|
|
int originIndex,
|
|
|
|
|
string destinationEntityKey,
|
|
|
|
|
string itemKey,
|
|
|
|
|
int sourceX,
|
|
|
|
|
int sourceY,
|
|
|
|
|
int destinationX,
|
|
|
|
|
int destinationY,
|
|
|
|
|
bool hasDestinationPosition)
|
|
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.EquipItem(
|
|
|
|
|
frame,
|
2026-06-21 11:26:41 +01:00
|
|
|
sourceKind,
|
|
|
|
|
originEntityKey,
|
|
|
|
|
originIndex,
|
|
|
|
|
destinationEntityKey,
|
|
|
|
|
itemKey,
|
|
|
|
|
sourceX,
|
|
|
|
|
sourceY,
|
|
|
|
|
destinationX,
|
|
|
|
|
destinationY,
|
|
|
|
|
hasDestinationPosition));
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public CultMeshOperationReceipt StoreItem(
|
2026-06-21 08:56:07 +01:00
|
|
|
string originEntityKey,
|
|
|
|
|
int sourceEquipmentIndex,
|
|
|
|
|
string destinationEntityKey,
|
|
|
|
|
int destinationCargoIndex,
|
|
|
|
|
string itemKey,
|
|
|
|
|
int destinationX,
|
|
|
|
|
int destinationY,
|
|
|
|
|
bool hasDestinationPosition)
|
|
|
|
|
{
|
2026-06-29 02:56:43 +01:00
|
|
|
return Send((client, frame) => client.StoreItem(
|
|
|
|
|
frame,
|
2026-06-21 11:26:41 +01:00
|
|
|
originEntityKey,
|
|
|
|
|
sourceEquipmentIndex,
|
|
|
|
|
destinationEntityKey,
|
|
|
|
|
destinationCargoIndex,
|
|
|
|
|
itemKey,
|
|
|
|
|
destinationX,
|
|
|
|
|
destinationY,
|
|
|
|
|
hasDestinationPosition));
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-29 07:01:38 +01:00
|
|
|
public bool TrySubmitSurfaceCommand(
|
|
|
|
|
EveSurfaceCommandRequest request,
|
|
|
|
|
out AetheriaRuntimeDaemonCommandEnvelope? envelope)
|
|
|
|
|
{
|
|
|
|
|
envelope = null;
|
|
|
|
|
if (request == null ||
|
|
|
|
|
!string.Equals(request.ProviderId, "aetheria.daemon", StringComparison.Ordinal) ||
|
|
|
|
|
!TryResolveSurfaceCommandKind(request, out var kind))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
envelope = Submit((client, frame) =>
|
2026-07-09 19:47:24 +01:00
|
|
|
TrySubmitSurfaceCommand(client, frame, kind, request, out var submitted)
|
2026-06-29 07:01:38 +01:00
|
|
|
? submitted!
|
|
|
|
|
: throw new UnsupportedSurfaceCommandException());
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch (UnsupportedSurfaceCommandException)
|
|
|
|
|
{
|
|
|
|
|
envelope = null;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
private CultMeshOperationReceipt Send(
|
2026-06-29 02:56:43 +01:00
|
|
|
Func<AetheriaRuntimeDaemonOperationClient, AetheriaRuntimeDaemonFrameDocument?, AetheriaRuntimeDaemonCommandEnvelope> submit)
|
2026-06-25 18:09:33 +01:00
|
|
|
{
|
|
|
|
|
return Submit(submit);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private AetheriaRuntimeDaemonCommandEnvelope Submit(
|
2026-06-29 02:56:43 +01:00
|
|
|
Func<AetheriaRuntimeDaemonOperationClient, AetheriaRuntimeDaemonFrameDocument?, AetheriaRuntimeDaemonCommandEnvelope> submit)
|
2026-06-21 11:26:41 +01:00
|
|
|
{
|
2026-06-22 14:08:25 +01:00
|
|
|
return _submit(submit);
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
2026-06-29 07:01:38 +01:00
|
|
|
|
|
|
|
|
private static bool TryResolveSurfaceCommandKind(
|
|
|
|
|
EveSurfaceCommandRequest request,
|
|
|
|
|
out AetheriaRuntimeDaemonCommandKinds kind)
|
|
|
|
|
{
|
|
|
|
|
kind = AetheriaRuntimeDaemonCommandKinds.None;
|
2026-07-09 21:05:06 +01:00
|
|
|
var command = NormalizeSurfaceCommandName(request.Operation?.OperationId ?? "");
|
|
|
|
|
if (!Enum.TryParse(command, ignoreCase: false, out kind) ||
|
|
|
|
|
kind == AetheriaRuntimeDaemonCommandKinds.None)
|
|
|
|
|
{
|
|
|
|
|
command = NormalizeSurfaceCommandName(ReadPayloadString(request, "commandId", ""));
|
|
|
|
|
}
|
2026-06-29 07:01:38 +01:00
|
|
|
|
|
|
|
|
return Enum.TryParse(command, ignoreCase: false, out kind) &&
|
|
|
|
|
kind != AetheriaRuntimeDaemonCommandKinds.None;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-09 21:05:06 +01:00
|
|
|
private static string NormalizeSurfaceCommandName(string command)
|
|
|
|
|
{
|
|
|
|
|
if (command.StartsWith(AetheriaRuntimeDaemonSurfaceCommandCatalog.CommandPrefix, StringComparison.Ordinal))
|
|
|
|
|
command = command.Substring(AetheriaRuntimeDaemonSurfaceCommandCatalog.CommandPrefix.Length);
|
|
|
|
|
return command;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-09 19:47:24 +01:00
|
|
|
private static bool TrySubmitSurfaceCommand(
|
|
|
|
|
AetheriaRuntimeDaemonOperationClient client,
|
|
|
|
|
AetheriaRuntimeDaemonFrameDocument? frame,
|
|
|
|
|
AetheriaRuntimeDaemonCommandKinds kind,
|
|
|
|
|
EveSurfaceCommandRequest request,
|
|
|
|
|
out AetheriaRuntimeDaemonCommandEnvelope? envelope)
|
|
|
|
|
{
|
|
|
|
|
envelope = null;
|
|
|
|
|
if (client == null)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
envelope = kind switch
|
|
|
|
|
{
|
|
|
|
|
AetheriaRuntimeDaemonCommandKinds.SetMoveVector => client.SetMoveVector(
|
|
|
|
|
frame,
|
|
|
|
|
ReadPayloadDouble(request, "directionX", 0.0),
|
|
|
|
|
ReadPayloadDouble(request, "directionY", 0.0),
|
|
|
|
|
ReadPayloadDouble(request, "scalarValue", 1.0)),
|
|
|
|
|
AetheriaRuntimeDaemonCommandKinds.SetLookDirection => client.SetLookDirection(
|
|
|
|
|
frame,
|
|
|
|
|
ReadPayloadDouble(request, "directionX", 0.0),
|
|
|
|
|
ReadPayloadDouble(request, "directionY", 1.0),
|
|
|
|
|
ReadPayloadDouble(request, "directionZ", 0.0)),
|
|
|
|
|
AetheriaRuntimeDaemonCommandKinds.SetTractorPower => client.SetTractorPower(
|
|
|
|
|
frame,
|
|
|
|
|
ReadPayloadDouble(request, "scalarValue", 1.0)),
|
|
|
|
|
AetheriaRuntimeDaemonCommandKinds.FireWeaponGroup => client.FireWeaponGroup(
|
|
|
|
|
frame,
|
|
|
|
|
ReadWeaponGroup(request)),
|
|
|
|
|
AetheriaRuntimeDaemonCommandKinds.SetWeaponGroupActive => client.SetWeaponGroupActive(
|
|
|
|
|
frame,
|
|
|
|
|
ReadWeaponGroup(request),
|
|
|
|
|
ReadPayloadBool(request, "active", true)),
|
|
|
|
|
AetheriaRuntimeDaemonCommandKinds.SetTarget => client.SetTarget(
|
|
|
|
|
frame,
|
|
|
|
|
ReadPayloadString(request, "targetEntityId", ReadPayloadString(request, "entityId", ""))),
|
|
|
|
|
_ => AetheriaRuntimeDaemonSurfaceCommandCatalog.TrySubmitArgumentless(
|
|
|
|
|
client,
|
|
|
|
|
frame,
|
|
|
|
|
kind,
|
|
|
|
|
out var submitted)
|
|
|
|
|
? submitted
|
|
|
|
|
: null
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return envelope != null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static string ReadPayloadString(
|
|
|
|
|
EveSurfaceCommandRequest request,
|
|
|
|
|
string key,
|
|
|
|
|
string defaultValue)
|
|
|
|
|
{
|
|
|
|
|
var value = request.Payload.GetString(key);
|
|
|
|
|
return string.IsNullOrWhiteSpace(value) ? defaultValue : value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static double ReadPayloadDouble(
|
|
|
|
|
EveSurfaceCommandRequest request,
|
|
|
|
|
string key,
|
|
|
|
|
double defaultValue)
|
|
|
|
|
{
|
|
|
|
|
return request.Payload.GetDouble(key, defaultValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static bool ReadPayloadBool(
|
|
|
|
|
EveSurfaceCommandRequest request,
|
|
|
|
|
string key,
|
|
|
|
|
bool defaultValue)
|
|
|
|
|
{
|
|
|
|
|
var value = request.Payload.GetString(key);
|
|
|
|
|
return string.IsNullOrWhiteSpace(value)
|
|
|
|
|
? defaultValue
|
|
|
|
|
: string.Equals(value, "true", StringComparison.OrdinalIgnoreCase) ||
|
|
|
|
|
string.Equals(value, "1", StringComparison.Ordinal);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static int ReadWeaponGroup(EveSurfaceCommandRequest request)
|
|
|
|
|
{
|
|
|
|
|
var value = request.Payload.GetString("weaponGroup");
|
|
|
|
|
if (int.TryParse(value, out var parsed))
|
|
|
|
|
return parsed;
|
|
|
|
|
|
|
|
|
|
value = request.Payload.GetString("actionId");
|
|
|
|
|
return int.TryParse(value, out parsed) ? parsed : 0;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-29 07:01:38 +01:00
|
|
|
private sealed class UnsupportedSurfaceCommandException : Exception
|
|
|
|
|
{
|
|
|
|
|
}
|
2026-06-21 08:56:07 +01:00
|
|
|
}
|
2026-06-22 14:08:25 +01:00
|
|
|
}
|