using System; using System.Linq; using System.Threading; using System.Threading.Tasks; IEntity? targetUser = null; CancellationTokenSource? followCts = null; string initialTargetUsername = "Dengat"; async Task FollowLoop(IEntity userToFollow, CancellationToken cancellationToken) { targetUser = userToFollow; while (!cancellationToken.IsCancellationRequested) { IEntity? currentTargetState = null; try { currentTargetState = Users.FirstOrDefault(u => u.Id == userToFollow.Id); if (currentTargetState == null || cancellationToken.IsCancellationRequested) { break; } int targetX = currentTargetState.Location.X; int targetY = currentTargetState.Location.Y; Move(targetX, targetY); await Task.Delay(500, cancellationToken); } catch (OperationCanceledException) { break; } catch (Exception ex) { Log($"FollowLoop: Error following {userToFollow?.Name ?? "Unknown"}: {ex.Message}"); break; } } if (ReferenceEquals(targetUser, userToFollow)) { targetUser = null; } } void StopFollowing() { if (followCts != null) { try { if (!followCts.IsCancellationRequested) { followCts.Cancel(); } } catch (ObjectDisposedException) { } catch (Exception ex) { Log($"StopFollowing: Error during Cancel: {ex.Message}"); } try { followCts.Dispose(); } catch (ObjectDisposedException) { } catch (Exception ex) { Log($"StopFollowing: Error during Dispose: {ex.Message}"); } finally { followCts = null; } } targetUser = null; } async Task StartFollowing(string targetName) { if (string.IsNullOrWhiteSpace(targetName) || targetName.Equals(Self.Name, StringComparison.OrdinalIgnoreCase)) { return; } var userToFollow = Users.FirstOrDefault(u => u.Name.Equals(targetName, StringComparison.OrdinalIgnoreCase)); if (userToFollow != null) { StopFollowing(); followCts = new CancellationTokenSource(); CancellationToken token = followCts.Token; _ = Task.Run(() => FollowLoop(userToFollow, token), token); } else { Log($"StartFollowing: User '{targetName}' not found."); } } OnChat(async e => { string message = e.Message.Trim(); string[] parts = message.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 0) return; string command = parts[0].ToLowerInvariant(); if (command == "+followstop") { StopFollowing(); } }); OnIntercept(In["UserRemove"], e => { int userIndexLeaving = e.Packet.ReadInt(); if (targetUser != null && targetUser.Index == userIndexLeaving) { StopFollowing(); } }); Task.Run(async () => { await Task.Delay(2000); await StartFollowing(initialTargetUsername); }); Wait();