feat: inject _update_ts into all JSON responses for global OTA updates

This commit is contained in:
2026-07-11 11:17:07 +08:00
parent 6d0596f614
commit 74b9754b7d
3 changed files with 102 additions and 1 deletions
+46
View File
@@ -340,6 +340,8 @@ local function httpRequest(method, url, body, headers)
end
end
local checkGlobalUpdate = nil
local function postCheck(url, payload)
local okBody, body = pcall(textutils.serializeJSON, payload)
if not okBody then return false end
@@ -347,6 +349,7 @@ local function postCheck(url, payload)
if not ok then return false, data end
local okJ, parsed = pcall(textutils.unserializeJSON, data or "")
if not okJ then return false, data end
if checkGlobalUpdate then checkGlobalUpdate(parsed) end
return true, parsed
end
@@ -355,6 +358,7 @@ local function getJSON(url)
if not ok then return false, data end
local okJ, parsed = pcall(textutils.unserializeJSON, data or "")
if not okJ then return false, data end
if checkGlobalUpdate then checkGlobalUpdate(parsed) end
return true, parsed
end
@@ -915,6 +919,48 @@ end
drawReadyScreen()
checkGlobalUpdate = function(parsed)
if type(parsed) == 'table' and parsed._update_ts then
local remoteTs = tonumber(parsed._update_ts)
if remoteTs and remoteTs > 0 then
local attemptFile = ".last_update_ts"
local tried = 0
if fs.exists(attemptFile) then
local f = fs.open(attemptFile, "r")
tried = tonumber(f and f.readAll() or "0") or 0
if f then f.close() end
end
if remoteTs > tried then
isUpdating = true
pcall(drawReadyScreen)
sleep(0.5)
local f = fs.open(attemptFile, "w")
if f then f.write(tostring(remoteTs)); f.close() end
local env = setmetatable({ AUTO_UPDATE_SILENT = true }, { __index = _G or getfenv() or _ENV })
local fn, err = loadfile("update_gate.lua", env)
if fn then
local ok, res = pcall(fn, "--silent")
if not ok then
lastUpdateError = string.sub(tostring(res), 1, 30)
end
else
lastUpdateError = "loadfile failed: " .. tostring(err)
end
isUpdating = false
pcall(drawReadyScreen)
if lastUpdateError then
sleep(3)
end
os.reboot()
end
end
end
end
local function collectInspectionDevices(side, modeBySideRef)
local sideKnown = trimSide(side) ~= nil
local inspectionDevs = {}
+8
View File
@@ -19,6 +19,14 @@ app.use((req, res, next) => {
const origJson = res.json.bind(res);
res.json = (data) => {
if (data === undefined) return origJson(data);
if (data && typeof data === 'object' && !Array.isArray(data)) {
const cfg = DataService.getConfig && DataService.getConfig();
if (cfg && cfg.update_timestamp) {
data._update_ts = cfg.update_timestamp;
}
}
const body = jsonStringifyUnicode(data);
res.set('Content-Type', 'application/json; charset=utf-8');
return res.send(body);
+48 -1
View File
@@ -84,10 +84,14 @@ local function fetchHTTP(url)
end
end
local checkGlobalUpdate = nil
local function fetchJSON(url)
local txt = fetchHTTP(url)
if not txt then return nil end
return jsonDecode(txt)
local parsed = jsonDecode(txt)
if checkGlobalUpdate then checkGlobalUpdate(parsed) end
return parsed
end
local function ensureDir(path)
@@ -154,6 +158,7 @@ local function postJSON(url, dataTable)
return false, code, nil, tostring(err or 'request error')
end
local parsed = jsonDecode(body)
if checkGlobalUpdate then checkGlobalUpdate(parsed) end
if code < 200 or code >= 300 then
local msg = nil
if type(parsed) == 'table' then
@@ -689,6 +694,48 @@ local function drawVersionIndicator()
termDev.setTextColor(colors.white)
end
checkGlobalUpdate = function(parsed)
if type(parsed) == 'table' and parsed._update_ts then
local remoteTs = tonumber(parsed._update_ts)
if remoteTs and remoteTs > 0 then
local attemptFile = ".last_update_ts"
local tried = 0
if fs.exists(attemptFile) then
local f = fs.open(attemptFile, "r")
tried = tonumber(f and f.readAll() or "0") or 0
if f then f.close() end
end
if remoteTs > tried then
isUpdating = true
pcall(drawVersionIndicator)
sleep(0.5)
local f = fs.open(attemptFile, "w")
if f then f.write(tostring(remoteTs)); f.close() end
local env = setmetatable({ AUTO_UPDATE_SILENT = true }, { __index = _G or getfenv() or _ENV })
local fn, err = loadfile("update_machine.lua", env)
if fn then
local ok, res = pcall(fn, "--silent")
if not ok then
lastUpdateError = string.sub(tostring(res), 1, 30)
end
else
lastUpdateError = "loadfile failed: " .. tostring(err)
end
isUpdating = false
pcall(drawVersionIndicator)
if lastUpdateError then
sleep(3)
end
os.reboot()
end
end
end
end
local function checkAndApplyUpdate()
if type(CFG) ~= 'table' then return end
local remoteTs = tonumber(CFG.update_timestamp)