style: update OTA version indicators to lime/yellow/red and output errors to CC terminal

This commit is contained in:
2026-07-11 13:03:44 +08:00
parent d5b7a51dae
commit 2eddb8b84c
2 changed files with 94 additions and 31 deletions
+80 -23
View File
@@ -89,7 +89,6 @@ local speaker = peripheral.find("speaker")
local inspection = peripheral.find("ticket_inspection_machine") local inspection = peripheral.find("ticket_inspection_machine")
local serverConnected = nil local serverConnected = nil
local versionMismatch = nil
local isUpdating = false local isUpdating = false
@@ -98,18 +97,73 @@ local function nowMs()
end end
local function fetchHTTP(url)
if not http then
print('Error: HTTP API is disabled in ComputerCraft config!')
setServerConnected(false)
return nil
end
if http.get then
local ok, res, err = pcall(http.get, url)
if not ok or not res then
if err then print('HTTP GET failed: ' .. tostring(err) .. ' url=' .. tostring(url)) end
setServerConnected(false)
return nil
end
local data = res.readAll()
res.close()
setServerConnected(true)
return data
end
if not http.request then
print('Error: HTTP API is disabled in ComputerCraft config!')
return nil
end
local okReq, reqOkOrErr = pcall(http.request, { url = url, method = 'GET' })
if not okReq or not reqOkOrErr then
print('HTTP request failed: ' .. tostring(reqOkOrErr) .. ' url=' .. tostring(url))
setServerConnected(false)
return nil
end
while true do
local ev, u, p1, p2 = os.pullEvent()
if ev == 'http_success' and u == url then
local res = p1
local data = res.readAll()
res.close()
setServerConnected(true)
return data
elseif ev == 'http_failure' and u == url then
print('HTTP GET failed: ' .. tostring(p1 or p2 or 'http_failure') .. ' url=' .. tostring(url))
setServerConnected(false)
return nil
else
os.queueEvent(ev, u, p1, p2)
sleep(0)
end
end
end
local function jsonDecode(str)
if not str then return nil end
local ok, res = pcall(textutils.unserializeJSON, str)
if ok then return res else return nil end
end
local function checkAndApplyUpdate() local function checkAndApplyUpdate()
local serverBase = guessBaseFromStatusURL(serverURL) local serverBase = guessBaseFromStatusURL(serverURL)
if #serverBase == 0 then return end local txt = fetchHTTP(serverBase .. '/check-update?_t=' .. tostring(os.epoch and os.epoch("utc") or math.random(1, 999999)))
local url = serverBase:gsub("/+$", "") .. "/api/check-update?_t=" .. tostring(nowMs() + math.random(1, 999999)) if not txt then return end
local ok, data = getJSON(url) local data = jsonDecode(txt)
if not ok or not data or not data.update_counter then return end if not data or not data.update_counter then return end
local remoteTs = tonumber(data.update_counter) local remoteTs = tonumber(data.update_counter)
if not remoteTs or remoteTs <= 0 then return end if not remoteTs or remoteTs <= 0 then return end
-- Prevent infinite reboot loops: only update once per timestamp
local attemptFile = ".last_update_ts" local attemptFile = ".last_update_ts"
if fs.exists(attemptFile) then if fs.exists(attemptFile) then
local f = fs.open(attemptFile, "r") local f = fs.open(attemptFile, "r")
@@ -119,37 +173,43 @@ local function checkAndApplyUpdate()
return return
end end
end end
-- We have a NEW remote timestamp. Trigger update!
isUpdating = true isUpdating = true
pcall(drawReadyScreen) pcall(drawReadyScreen)
sleep(0.5) sleep(0.5)
-- Record that we are attempting this timestamp
local f = fs.open(attemptFile, "w") local f = fs.open(attemptFile, "w")
if f then f.write(tostring(remoteTs)); f.close() end if f then f.write(tostring(remoteTs)); f.close() end
-- Load and run update script
local env = setmetatable({ AUTO_UPDATE_SILENT = true }, { __index = _G or getfenv() or _ENV }) local env = setmetatable({ AUTO_UPDATE_SILENT = true }, { __index = _G or getfenv() or _ENV })
local fn, err = loadfile("update_gate.lua", env) local fn, err = loadfile("update_gate.lua", env)
if fn then if fn then
local ok, res = pcall(fn, "--silent") local ok, res = pcall(fn, "--silent")
if not ok then if not ok then
lastUpdateError = string.sub(tostring(res), 1, 30) lastUpdateError = string.sub(tostring(res), 1, 30)
if term and term.setTextColor then
term.setTextColor(colors.red)
print("OTA Update Error: " .. tostring(res))
term.setTextColor(colors.white)
end
end end
else else
lastUpdateError = "loadfile failed: " .. tostring(err) lastUpdateError = "loadfile failed: " .. tostring(err)
if term and term.setTextColor then
term.setTextColor(colors.red)
print("OTA Update Error: " .. tostring(err))
term.setTextColor(colors.white)
end
end end
isUpdating = false isUpdating = false
pcall(drawReadyScreen) if pcall then
pcall(drawReadyScreen)
end
if lastUpdateError then if not lastUpdateError then
sleep(3) os.reboot()
end end
-- Reboot
os.reboot()
end end
local function setServerConnected(ok) local function setServerConnected(ok)
@@ -199,17 +259,14 @@ local function drawVersionIndicator(w)
local s = tostring(VERSION or "") local s = tostring(VERSION or "")
if #s == 0 then return end if #s == 0 then return end
if w < #s then return end if w < #s then return end
local markerColor = colors.yellow local markerColor = colors.lime
local markerText = "* " local markerText = "* "
if isUpdating then if isUpdating then
markerColor = colors.yellow markerColor = colors.yellow
markerText = "^ing" markerText = "^ing"
elseif versionMismatch == true then elseif lastUpdateError then
markerColor = colors.red markerColor = colors.red
markerText = "* " markerText = "* "
elseif versionMismatch == false then
markerColor = colors.lime
markerText = " "
end end
termDev.setBackgroundColor(colors.black) termDev.setBackgroundColor(colors.black)
termDev.setTextColor(colors.gray) termDev.setTextColor(colors.gray)
+14 -8
View File
@@ -661,17 +661,14 @@ local lastUpdateError = nil
local function drawVersionIndicator() local function drawVersionIndicator()
if w < 1 then return end if w < 1 then return end
local markerColor = colors.yellow local markerColor = colors.lime
local markerText = '* ' local markerText = '* '
if isUpdating then if isUpdating then
markerColor = colors.yellow markerColor = colors.yellow
markerText = '^ing' markerText = '^ing'
elseif versionMismatch == true then elseif lastUpdateError then
markerColor = colors.red markerColor = colors.red
markerText = '* ' markerText = '* '
elseif versionMismatch == false then
markerColor = colors.lime
markerText = ' '
end end
termDev.setBackgroundColor(colors.black) termDev.setBackgroundColor(colors.black)
termDev.setTextColor(colors.gray) termDev.setTextColor(colors.gray)
@@ -720,18 +717,27 @@ local function checkAndApplyUpdate()
local ok, res = pcall(fn, "--silent") local ok, res = pcall(fn, "--silent")
if not ok then if not ok then
lastUpdateError = string.sub(tostring(res), 1, 30) lastUpdateError = string.sub(tostring(res), 1, 30)
if term and term.setTextColor then
term.setTextColor(colors.red)
print("OTA Update Error: " .. tostring(res))
term.setTextColor(colors.white)
end
end end
else else
lastUpdateError = "loadfile failed: " .. tostring(err) lastUpdateError = "loadfile failed: " .. tostring(err)
if term and term.setTextColor then
term.setTextColor(colors.red)
print("OTA Update Error: " .. tostring(err))
term.setTextColor(colors.white)
end
end end
isUpdating = false isUpdating = false
pcall(drawVersionIndicator) pcall(drawVersionIndicator)
if lastUpdateError then if not lastUpdateError then
sleep(3) os.reboot()
end end
os.reboot()
end end
local function backgroundSyncTask() local function backgroundSyncTask()