import { StellarPlugin, PluginContext } from "@stellarstack/plugin-sdk";
export default class BackupScheduler extends StellarPlugin {
private intervals = new Map<string, NodeJS.Timeout>();
manifest = {
id: "backup-scheduler",
name: "Backup Scheduler",
version: "1.0.0",
description: "Automatically create server backups on a schedule",
author: "StellarStack",
category: "automation" as const,
permissions: ["backups.create", "console.send"],
configSchema: {
type: "object",
properties: {
intervalHours: {
type: "number",
title: "Backup Interval (hours)",
minimum: 1,
maximum: 168,
default: 24,
},
warnPlayers: {
type: "boolean",
title: "Warn Players",
default: true,
},
},
},
defaultConfig: {
intervalHours: 24,
warnPlayers: true,
},
};
async onEnable(context: PluginContext): Promise<void> {
context.log.info("Backup scheduler enabled");
// Start backup schedule for all servers
const servers = await context.api.servers.list();
servers.forEach(server => {
this.scheduleBackup(context, server.id);
});
// Schedule backups for newly created servers
context.on("server:created", async (ctx) => {
this.scheduleBackup(context, ctx.serverId!);
});
// Clean up schedule when server is deleted
context.on("server:deleted", async (ctx) => {
const interval = this.intervals.get(ctx.serverId!);
if (interval) {
clearInterval(interval);
this.intervals.delete(ctx.serverId!);
}
});
}
async onDisable(context: PluginContext): Promise<void> {
// Stop all backup schedules
this.intervals.forEach(interval => clearInterval(interval));
this.intervals.clear();
context.log.info("Backup scheduler disabled");
}
private scheduleBackup(context: PluginContext, serverId: string): void {
const hours = context.config.intervalHours as number;
const interval = setInterval(async () => {
await this.createBackup(context, serverId);
}, hours * 60 * 60 * 1000);
this.intervals.set(serverId, interval);
context.log.info(`Scheduled backups every ${hours}h for ${serverId}`);
}
private async createBackup(context: PluginContext, serverId: string): Promise<void> {
try {
const warnPlayers = context.config.warnPlayers as boolean;
if (warnPlayers) {
await context.api.servers.sendCommand(
serverId,
"say Creating backup in 10 seconds..."
);
await new Promise(resolve => setTimeout(resolve, 10000));
}
const timestamp = new Date().toISOString().split("T")[0];
const backupName = `auto-${timestamp}-${Date.now()}`;
// Create backup through action execution would happen here
// For now just log
context.log.info(`Created backup: ${backupName}`);
if (warnPlayers) {
await context.api.servers.sendCommand(
serverId,
"say Backup complete!"
);
}
await context.api.notify.toast(serverId, "Backup created", "success");
} catch (error) {
context.log.error(`Backup failed for ${serverId}`, error);
await context.api.notify.toast(serverId, "Backup failed", "error");
}
}
}