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; }
}