muffin v7.38.9
This commit is contained in:
parent
ada27cf05b
commit
8a7847ff37
21 changed files with 1296 additions and 689 deletions
|
|
@ -85,6 +85,8 @@ internal sealed class MovementController : IDisposable
|
|||
|
||||
private readonly AetheryteData _aetheryteData;
|
||||
|
||||
private readonly Configuration _configuration;
|
||||
|
||||
private readonly ILogger<MovementController> _logger;
|
||||
|
||||
private CancellationTokenSource? _cancellationTokenSource;
|
||||
|
|
@ -93,6 +95,14 @@ internal sealed class MovementController : IDisposable
|
|||
|
||||
private long _pathfindStartTime;
|
||||
|
||||
private Vector3? _lastKnownPosition;
|
||||
|
||||
private long _lastPositionUpdateTime;
|
||||
|
||||
private Vector3? _expectedPosition;
|
||||
|
||||
private bool _isTrackingPlayerInput;
|
||||
|
||||
public bool IsNavmeshReady
|
||||
{
|
||||
get
|
||||
|
|
@ -146,7 +156,9 @@ internal sealed class MovementController : IDisposable
|
|||
|
||||
public int NumQueuedPathfindRequests => _navmeshIpc.NumQueuedPathfindRequests;
|
||||
|
||||
public MovementController(NavmeshIpc navmeshIpc, IClientState clientState, IObjectTable objectTable, GameFunctions gameFunctions, ChatFunctions chatFunctions, ICondition condition, MovementOverrideController movementOverrideController, AetheryteData aetheryteData, ILogger<MovementController> logger)
|
||||
public event EventHandler? PlayerInputDetected;
|
||||
|
||||
public MovementController(NavmeshIpc navmeshIpc, IClientState clientState, IObjectTable objectTable, GameFunctions gameFunctions, ChatFunctions chatFunctions, ICondition condition, MovementOverrideController movementOverrideController, AetheryteData aetheryteData, Configuration configuration, ILogger<MovementController> logger)
|
||||
{
|
||||
_navmeshIpc = navmeshIpc;
|
||||
_clientState = clientState;
|
||||
|
|
@ -156,11 +168,19 @@ internal sealed class MovementController : IDisposable
|
|||
_condition = condition;
|
||||
_movementOverrideController = movementOverrideController;
|
||||
_aetheryteData = aetheryteData;
|
||||
_configuration = configuration;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public unsafe void Update()
|
||||
{
|
||||
if (IsPathRunning && _isTrackingPlayerInput && DetectPlayerInputInterference())
|
||||
{
|
||||
_logger.LogInformation("Player input detected during automatic movement, raising event to stop automation");
|
||||
this.PlayerInputDetected?.Invoke(this, EventArgs.Empty);
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
if (_pathfindTask != null && Destination != null)
|
||||
{
|
||||
if (!_pathfindTask.IsCompleted && Environment.TickCount64 - _pathfindStartTime > 30000 && _navmeshIpc.NumQueuedPathfindRequests > 5)
|
||||
|
|
@ -188,6 +208,11 @@ internal sealed class MovementController : IDisposable
|
|||
if (Destination.IsFlying && Destination.Land)
|
||||
{
|
||||
_logger.LogWarning("Adjusted destination failed, trying tolerance-based pathfinding");
|
||||
if (!IsNavmeshReady)
|
||||
{
|
||||
_logger.LogWarning("Navmesh not ready for tolerance-based pathfinding");
|
||||
return;
|
||||
}
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
_cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(30L));
|
||||
Vector3 vector2 = _objectTable[0]?.Position ?? Vector3.Zero;
|
||||
|
|
@ -218,6 +243,11 @@ internal sealed class MovementController : IDisposable
|
|||
(list, _) = tuple;
|
||||
if (tuple.Item2 && Destination.ShouldRecalculateNavmesh())
|
||||
{
|
||||
if (!IsNavmeshReady)
|
||||
{
|
||||
_logger.LogWarning("Navmesh not ready for recalculation");
|
||||
return;
|
||||
}
|
||||
Destination.NavmeshCalculations++;
|
||||
Destination.PartialRoute.AddRange(list);
|
||||
_logger.LogInformation("Running navmesh recalculation with fudged point ({From} to {To})", list.Last(), Destination.Position);
|
||||
|
|
@ -232,6 +262,7 @@ internal sealed class MovementController : IDisposable
|
|||
_logger.LogInformation("Navigating via route: [{Route}]", string.Join(" → ", _pathfindTask.Result.Select((Vector3 x) => x.ToString("G", CultureInfo.InvariantCulture))));
|
||||
_navmeshIpc.MoveTo(list, Destination.IsFlying);
|
||||
MovementStartedAt = DateTime.Now;
|
||||
StartPlayerInputTracking();
|
||||
ResetPathfinding();
|
||||
}
|
||||
else if (_pathfindTask.IsCompleted)
|
||||
|
|
@ -321,6 +352,72 @@ internal sealed class MovementController : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
private void StartPlayerInputTracking()
|
||||
{
|
||||
IGameObject gameObject = _objectTable[0];
|
||||
if (gameObject != null)
|
||||
{
|
||||
_lastKnownPosition = gameObject.Position;
|
||||
_expectedPosition = gameObject.Position;
|
||||
_lastPositionUpdateTime = Environment.TickCount64;
|
||||
_isTrackingPlayerInput = true;
|
||||
}
|
||||
}
|
||||
|
||||
private bool DetectPlayerInputInterference()
|
||||
{
|
||||
if (!_configuration.General.StopOnPlayerInput)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!_isTrackingPlayerInput || !_lastKnownPosition.HasValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
IGameObject gameObject = _objectTable[0];
|
||||
if (gameObject == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Vector3 position = gameObject.Position;
|
||||
long tickCount = Environment.TickCount64;
|
||||
if (tickCount - _lastPositionUpdateTime < 100)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
List<Vector3> waypoints = _navmeshIpc.GetWaypoints();
|
||||
if (waypoints.Count > 0)
|
||||
{
|
||||
_expectedPosition = waypoints[0];
|
||||
}
|
||||
if (_expectedPosition.HasValue)
|
||||
{
|
||||
Vector3 vector = Vector3.Normalize(_expectedPosition.Value - _lastKnownPosition.Value);
|
||||
Vector3 value = position - _lastKnownPosition.Value;
|
||||
if (value.Length() > 0.1f)
|
||||
{
|
||||
Vector3 vector2 = Vector3.Normalize(value);
|
||||
float num = Vector3.Dot(vector, vector2);
|
||||
if (num < 0.7f)
|
||||
{
|
||||
_logger.LogDebug("Player movement detected: alignment={Alignment:F2}, actual={Actual}, expected={Expected}", num, value.ToString("G", CultureInfo.InvariantCulture), vector.ToString("G", CultureInfo.InvariantCulture));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
_lastKnownPosition = position;
|
||||
_lastPositionUpdateTime = tickCount;
|
||||
return false;
|
||||
}
|
||||
|
||||
private void StopPlayerInputTracking()
|
||||
{
|
||||
_isTrackingPlayerInput = false;
|
||||
_lastKnownPosition = null;
|
||||
_expectedPosition = null;
|
||||
_lastPositionUpdateTime = 0L;
|
||||
}
|
||||
|
||||
private void Restart(DestinationData destination)
|
||||
{
|
||||
Stop();
|
||||
|
|
@ -364,6 +461,11 @@ internal sealed class MovementController : IDisposable
|
|||
|
||||
public void NavigateTo(EMovementType type, uint? dataId, Vector3 to, bool fly, bool sprint, float? stopDistance = null, float? verticalStopDistance = null, bool land = false)
|
||||
{
|
||||
if (!IsNavmeshReady)
|
||||
{
|
||||
_logger.LogWarning("Navmesh not ready, cannot start navigation to {Position}", to.ToString("G", CultureInfo.InvariantCulture));
|
||||
return;
|
||||
}
|
||||
fly |= _condition[ConditionFlag.Diving];
|
||||
if (fly && land)
|
||||
{
|
||||
|
|
@ -404,6 +506,11 @@ internal sealed class MovementController : IDisposable
|
|||
|
||||
public void NavigateTo(EMovementType type, uint? dataId, List<Vector3> to, bool fly, bool sprint, float? stopDistance, float? verticalStopDistance = null, bool land = false)
|
||||
{
|
||||
if (!IsNavmeshReady)
|
||||
{
|
||||
_logger.LogWarning("Navmesh not ready, cannot start navigation to {Position}", to.Last().ToString("G", CultureInfo.InvariantCulture));
|
||||
return;
|
||||
}
|
||||
fly |= _condition[ConditionFlag.Diving];
|
||||
if (fly && land && to.Count > 0)
|
||||
{
|
||||
|
|
@ -416,6 +523,7 @@ internal sealed class MovementController : IDisposable
|
|||
_logger.LogInformation("Moving to {Destination}", Destination);
|
||||
_navmeshIpc.MoveTo(to, fly);
|
||||
MovementStartedAt = DateTime.Now;
|
||||
StartPlayerInputTracking();
|
||||
}
|
||||
|
||||
public void ResetPathfinding()
|
||||
|
|
@ -436,6 +544,11 @@ internal sealed class MovementController : IDisposable
|
|||
|
||||
private Vector3? TryFindAccessibleDestination(Vector3 target, bool flying, bool landing)
|
||||
{
|
||||
if (!IsNavmeshReady)
|
||||
{
|
||||
_logger.LogWarning("Navmesh not ready, cannot find accessible destination");
|
||||
return null;
|
||||
}
|
||||
float[] array = ((!(flying && landing)) ? ((!flying) ? new float[3] { 1f, 3f, 5f } : new float[3] { 2f, 5f, 10f }) : new float[3] { 5f, 10f, 15f });
|
||||
float[] array2 = ((!flying) ? new float[3] { 1f, 2f, 3f } : new float[3] { 3f, 5f, 10f });
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
|
|
@ -504,17 +617,52 @@ internal sealed class MovementController : IDisposable
|
|||
if (Math.Abs((double)num - Destination.LastWaypoint.Distance2DAtLastUpdate) < 0.5)
|
||||
{
|
||||
int navmeshCalculations = Destination.NavmeshCalculations;
|
||||
if (navmeshCalculations % 6 == 1)
|
||||
switch (navmeshCalculations)
|
||||
{
|
||||
_logger.LogWarning("Jumping to try and resolve navmesh problem (n = {Calculations})", navmeshCalculations);
|
||||
case 1:
|
||||
case 7:
|
||||
_logger.LogWarning("Jumping to try and resolve navmesh problem (n = {Calculations}) at {Position}", navmeshCalculations, Destination.Position.ToString("G", CultureInfo.InvariantCulture));
|
||||
ActionManager.Instance()->UseAction(ActionType.GeneralAction, 2u, 3758096384uL, 0u, ActionManager.UseActionMode.None, 0u, null);
|
||||
Destination.NavmeshCalculations++;
|
||||
Destination.LastWaypoint.UpdatedAt = Environment.TickCount64;
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("Recalculating navmesh (n = {Calculations})", navmeshCalculations);
|
||||
break;
|
||||
case 5:
|
||||
_logger.LogWarning("Reloading navmesh (n = {Calculations}) at {Position}", navmeshCalculations, Destination.Position.ToString("G", CultureInfo.InvariantCulture));
|
||||
_navmeshIpc.Reload();
|
||||
Destination.LastWaypoint.UpdatedAt = Environment.TickCount64;
|
||||
break;
|
||||
case 6:
|
||||
if (!IsNavmeshReady)
|
||||
{
|
||||
_logger.LogWarning("Navmesh not ready after reload (n = {Calculations})", navmeshCalculations);
|
||||
return false;
|
||||
}
|
||||
_logger.LogInformation("Navmesh ready after reload, restarting navigation (n = {Calculations})", navmeshCalculations);
|
||||
Restart(Destination);
|
||||
break;
|
||||
case 8:
|
||||
_logger.LogWarning("Rebuilding navmesh (n = {Calculations}) at {Position}", navmeshCalculations, Destination.Position.ToString("G", CultureInfo.InvariantCulture));
|
||||
_navmeshIpc.Rebuild();
|
||||
Destination.LastWaypoint.UpdatedAt = Environment.TickCount64;
|
||||
break;
|
||||
case 9:
|
||||
if (!IsNavmeshReady)
|
||||
{
|
||||
_logger.LogWarning("Navmesh not ready after rebuild (n = {Calculations})", navmeshCalculations);
|
||||
return false;
|
||||
}
|
||||
_logger.LogInformation("Navmesh ready after rebuild, restarting navigation (n = {Calculations})", navmeshCalculations);
|
||||
Restart(Destination);
|
||||
break;
|
||||
default:
|
||||
if (!IsNavmeshReady)
|
||||
{
|
||||
_logger.LogWarning("Navmesh not ready for recalculation (n = {Calculations})", navmeshCalculations);
|
||||
return false;
|
||||
}
|
||||
_logger.LogWarning("Recalculating navmesh (n = {Calculations}) at {Position}", navmeshCalculations, Destination.Position.ToString("G", CultureInfo.InvariantCulture));
|
||||
Restart(Destination);
|
||||
break;
|
||||
}
|
||||
Destination.NavmeshCalculations = navmeshCalculations + 1;
|
||||
return true;
|
||||
|
|
@ -570,6 +718,7 @@ internal sealed class MovementController : IDisposable
|
|||
|
||||
public void Stop()
|
||||
{
|
||||
StopPlayerInputTracking();
|
||||
_navmeshIpc.Stop();
|
||||
ResetPathfinding();
|
||||
Destination = null;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue