service live configslop

This commit is contained in:
legop3
2026-09-14 17:56:53 -04:00
parent 881583ee0a
commit 91e0cc3886
69 changed files with 1188 additions and 619 deletions
@@ -8,7 +8,7 @@ module.exports = {
feature: true,
defaultValue: { enabled: false },
schema: strictObject({
enabled: boolean({ description: 'Registers the physical button-box input route and enables its persistent button rewards and effects after restart.' }),
enabled: boolean({ description: 'Immediately enables the physical button-box input route and its persistent button rewards and effects.' }),
}, {
title: 'Button box',
description: 'Optional physical button-box input and reward system.',
@@ -10,6 +10,7 @@ function registerButtonBoxRoute(deps) {
buttonCount,
normalizeIp,
isLocalNetwork,
isEnabled,
applyPress,
} = deps;
@@ -39,6 +40,13 @@ function registerButtonBoxRoute(deps) {
}
app.post('/buttonbox/press', express.text({ type: 'text/plain' }), async (req, res) => {
// The route stays registered for the life of Express, but the service gate
// is evaluated per request so the physical endpoint enables and disables
// immediately without accumulating duplicate routes.
if (!isEnabled()) {
res.status(503).json({ error: 'Button box is disabled' });
return;
}
if (denyIfNotLocal(req, res)) return;
const buttonId = parseButtonId(req.body);
if (!Number.isFinite(buttonId) || buttonId < 1 || buttonId > buttonCount) {
+25 -15
View File
@@ -4,7 +4,7 @@
const { app } = require('../../globals/http');
const io = require('../../globals/io');
const logger = require('../../globals/logger').child('buttonBoxService');
const { loadConfig } = require('../../configuration');
const { loadConfig, registerConfigurationHandler } = require('../../configuration');
const { resolveDataDir, resolveDataPath } = require('../../helpers/dataPaths');
const { publishEvent } = require('../eventBus');
const { getRewardById, listRewards } = require('../../rewards');
@@ -30,7 +30,7 @@ const DATA_DIR = resolveDataDir();
const STORE_PATH = resolveDataPath('buttonbox-state.json');
const BUTTON_COUNT = 4;
const STORE_VERSION = 1;
const enabled = Boolean(loadConfig().buttonBox?.enabled);
let enabled = Boolean(loadConfig().buttonBox?.enabled);
const store = createButtonBoxStore({
logger,
@@ -73,28 +73,38 @@ const core = createButtonBoxCore({
store,
});
if (enabled) {
/*
The button box is physical local hardware, so disabled public installs
should not expose its LAN-only press endpoint or initialize its reward file.
*/
registerButtonBoxRoute({
app,
logger,
buttonCount: BUTTON_COUNT,
normalizeIp,
isLocalNetwork,
applyPress: core.applyPress,
});
registerButtonBoxRoute({
app,
logger,
buttonCount: BUTTON_COUNT,
normalizeIp,
isLocalNetwork,
isEnabled: () => enabled,
applyPress: core.applyPress,
});
function enableButtonBox() {
store.loadState();
core.recoverEffects().catch((err) => {
logger.warn('Button box effect recovery failed', err.message);
});
}
if (enabled) {
enableButtonBox();
} else {
logger.info('Button box disabled by config');
}
registerConfigurationHandler('buttonBox', (buttonBoxConfig = {}) => {
const wasEnabled = enabled;
enabled = Boolean(buttonBoxConfig.enabled);
// Persistent state is loaded only on the transition to enabled. The core has
// no long-running hardware client, so disabling is completely represented by
// the route and public-method gates.
if (!wasEnabled && enabled) enableButtonBox();
});
module.exports = {
getButtonBoxState: () => {
/*