From 1eea756ab36093a4e6ae83486b1aff6702b971c8 Mon Sep 17 00:00:00 2001 From: bbassie <17990055+bbassie@users.noreply.github.com> Date: Wed, 28 Oct 2026 23:58:13 +0000 Subject: [PATCH] Check connection and status in subspace_storage timers Co-Authored-By: Claude Opus 5.5 --- plugins/subspace_storage/instance.ts | 21 +++++++--------- plugins/subspace_storage/test/plugin.js | 33 +++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/plugins/subspace_storage/instance.ts b/plugins/subspace_storage/instance.ts index 0bba2336..651f5154 100644 --- a/plugins/subspace_storage/instance.ts +++ b/plugins/subspace_storage/instance.ts @@ -88,19 +88,12 @@ export default async function(context: InstancePluginContext) { }); function sendPing() { - if (!host.connected) { - return; // Only ping if we are actually connected to the controller. - } instance.sendRcon( "/sc __subspace_storage__ global.ticksSinceMasterPinged = 0", true, plugin.name ).catch(err => unexpectedError(err)); } function sendInventory() { - if (instance.status !== "running") { - return; - } - const payloadItems = [ ...cachedInventoryItems, new Item("signal-unixtime", Math.floor(Date.now() / 1000), "normal"), @@ -116,7 +109,8 @@ export default async function(context: InstancePluginContext) { instance.hooks.start.attach(plugin.name, async () => { // Each command runs a tick on an auto paused game. pingId = setInterval(() => { - if (!instance.autoPaused) { + // Only ping if we are actually connected to the controller. + if (host.connected && !instance.autoPaused) { sendPing(); } }, 5000); @@ -129,17 +123,20 @@ export default async function(context: InstancePluginContext) { // Ensure a payload with updated time is sent every second timeUpdateId = setInterval(() => { - if (!instance.autoPaused) { + if (instance.status === "running" && !instance.autoPaused) { sendInventory(); } }, 1000); }); instance.hooks.autoPauseChanged.attach(plugin.name, async (paused: boolean) => { - if (!paused && instance.status === "running") { - sendPing(); - sendInventory(); + if (paused || instance.status !== "running") { + return; } + if (host.connected) { + sendPing(); + } + sendInventory(); }); instance.hooks.stop.attach(plugin.name, async () => { diff --git a/plugins/subspace_storage/test/plugin.js b/plugins/subspace_storage/test/plugin.js index 29f18eda..b9019a29 100644 --- a/plugins/subspace_storage/test/plugin.js +++ b/plugins/subspace_storage/test/plugin.js @@ -154,5 +154,38 @@ describe("subspace_storage plugin", function() { nodeMock.timers.reset(); } }); + describe("timers and unpause", function() { + const ping = "/sc __subspace_storage__ global.ticksSinceMasterPinged = 0"; + const isInventory = command => command.includes("UpdateInvData"); + let startedInstance; + let host; + beforeEach(async function() { + nodeMock.timers.enable({ apis: ["setInterval", "Date"], now: 1000000 }); + ({ instance: startedInstance, host } = await mock.loadInstancePlugin(instanceEntrypoint, info)); + host.connected = true; + startedInstance.sendTo = async () => []; + await startedInstance.hooks.start.invoke(); + startedInstance.server.rconCommands.length = 0; + }); + afterEach(async function() { + await startedInstance.hooks.stop.invoke(); + nodeMock.timers.reset(); + }); + + it("should not ping while the host is disconnected", async function() { + host.connected = false; + nodeMock.timers.tick(5000); + await startedInstance.hooks.autoPauseChanged.invoke(false); + const commands = startedInstance.server.rconCommands; + assert(!commands.includes(ping), "ping was sent"); + assert.equal(commands.filter(isInventory).length, 6); + }); + it("should not send inventory while not running", async function() { + startedInstance.status = "stopping"; + nodeMock.timers.tick(5000); + await startedInstance.hooks.autoPauseChanged.invoke(false); + assert.deepEqual(startedInstance.server.rconCommands, [ping]); + }); + }); }); });