using SilkroadBot.Plugins.SDK.Attributes; using SilkroadBot.Plugins.SDK.Interfaces; using SilkroadBot.Plugins.SDK.Models; namespace SilkroadBot.Plugin.CommandCenter; /// /// Command Center plugin - provides a command-based interface for controlling the bot. /// Supports custom commands, macros, and scheduled tasks. /// [Plugin("command-center", "Command Center", "Command-based bot control with macros and scheduled tasks")] public class CommandCenterPlugin : PluginBase { public override string Id => "command-center"; public override string Name => "Command Center"; public override Version Version => new(1, 0, 0); public override string Author => "SilkroadBot Team"; public override string Description => "Bot control via commands, macros, and task scheduling"; private readonly Dictionary> _commands = new(); private readonly List _scheduledTasks = new(); private CancellationTokenSource? _schedulerCts; public override Task InitializeAsync(IPluginContext context) { base.InitializeAsync(context); RegisterDefaultCommands(); return Task.CompletedTask; } public override Task StartAsync(CancellationToken ct = default) { _schedulerCts = new CancellationTokenSource(); _ = Task.Run(() => SchedulerLoopAsync(_schedulerCts.Token)); return base.StartAsync(ct); } public override Task StopAsync() { _schedulerCts?.Cancel(); return base.StopAsync(); } /// /// Register a custom command. /// public void RegisterCommand(string name, Func handler) { _commands[name.ToLower()] = handler; Log(LogLevel.Debug, $"Registered command: {name}"); } /// /// Execute a command string. /// public async Task ExecuteAsync(string commandLine) { var parts = commandLine.Split(' ', StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 0) return new CommandResult(false, "Empty command"); var cmdName = parts[0].ToLower(); var args = parts.Skip(1).ToArray(); if (!_commands.TryGetValue(cmdName, out var handler)) return new CommandResult(false, $"Unknown command: {cmdName}"); try { await handler(args); return new CommandResult(true, $"Command '{cmdName}' executed successfully"); } catch (Exception ex) { return new CommandResult(false, $"Command error: {ex.Message}"); } } /// /// Schedule a command to run periodically. /// public void ScheduleCommand(string name, string command, TimeSpan interval) { _scheduledTasks.Add(new ScheduledTask { Name = name, Command = command, Interval = interval, NextRun = DateTime.UtcNow + interval, IsEnabled = true }); Log(LogLevel.Information, $"Scheduled '{name}' every {interval.TotalSeconds}s"); } private void RegisterDefaultCommands() { RegisterCommand("status", async args => { var state = Context.GetGameState(); Log(LogLevel.Information, $"Status: {state.ConnectionState} | HP: {state.HP}/{state.MaxHP} | Pos: {state.Position}"); await Task.CompletedTask; }); RegisterCommand("heal", async args => { Log(LogLevel.Information, "Executing heal command..."); // TODO: Send heal skill/potion packet await Task.CompletedTask; }); RegisterCommand("move", async args => { if (args.Length < 2) { Log(LogLevel.Warning, "Usage: move "); return; } Log(LogLevel.Information, $"Moving to ({args[0]}, {args[1]})..."); await Task.CompletedTask; }); RegisterCommand("stop", async args => { Log(LogLevel.Information, "Stopping all actions..."); await Task.CompletedTask; }); RegisterCommand("help", async args => { Log(LogLevel.Information, $"Available commands: {string.Join(", ", _commands.Keys)}"); await Task.CompletedTask; }); } private async Task SchedulerLoopAsync(CancellationToken ct) { while (!ct.IsCancellationRequested) { var now = DateTime.UtcNow; foreach (var task in _scheduledTasks.Where(t => t.IsEnabled && t.NextRun <= now)) { await ExecuteAsync(task.Command); task.NextRun = now + task.Interval; } await Task.Delay(1000, ct); } } } public record CommandResult(bool Success, string Message); public class ScheduledTask { public string Name { get; set; } = string.Empty; public string Command { get; set; } = string.Empty; public TimeSpan Interval { get; set; } public DateTime NextRun { get; set; } public bool IsEnabled { get; set; } }