diff --git a/gate.lua b/gate.lua index 52c084d..d9d47f2 100644 --- a/gate.lua +++ b/gate.lua @@ -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 = {} diff --git a/server/index.js b/server/index.js index 13764c4..211fba7 100644 --- a/server/index.js +++ b/server/index.js @@ -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); diff --git a/ticketmachine.lua b/ticketmachine.lua index 0713c4d..6396af6 100644 --- a/ticketmachine.lua +++ b/ticketmachine.lua @@ -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)