Airship autopilot: role-based wget installer for server

Mirrors the live CC autopilot (computer 0) and cockpit (computer 4) from the
Modda wii world. install.lua fetches each role's manifest over HTTP so the
system installs on any server regardless of computer id.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-23 12:53:41 +02:00
commit 4cd2573f56
36 changed files with 2897 additions and 0 deletions

115
install.lua Normal file
View File

@@ -0,0 +1,115 @@
-- install.lua -- role-based installer for the Create: Aeronautics airship autopilot.
-- Fetches every file for the chosen role over HTTP and writes it to this computer,
-- so it works on any server regardless of the computer's id. Re-run to update.
--
-- Usage on a CC computer:
-- wget run https://raw.githubusercontent.com/Sterister/airship-autopilot/main/install.lua
-- wget run https://raw.githubusercontent.com/Sterister/airship-autopilot/main/install.lua autopilot
-- wget run https://raw.githubusercontent.com/Sterister/airship-autopilot/main/install.lua cockpit
--
-- Roles:
-- autopilot machine-room PC: full v3 observer autopilot (boots to standby)
-- cockpit pilot-house PC: control console
local BASE = "https://raw.githubusercontent.com/Sterister/airship-autopilot/main"
local ROLES = { "autopilot", "cockpit" }
local args = { ... }
-- ---- helpers ---------------------------------------------------------------
local function die(msg)
term.setTextColor(colors.red)
print(msg)
term.setTextColor(colors.white)
error("", 0)
end
local function get(url)
local h, err = http.get(url)
if not h then return nil, tostring(err) end
local body = h.readAll()
h.close()
return body
end
local function writeFile(path, data)
local dir = fs.getDir(path)
if dir ~= "" and not fs.exists(dir) then fs.makeDir(dir) end
local f = fs.open(path, "w")
f.write(data)
f.close()
end
local function chooseRole()
print("Select role to install:")
for i, r in ipairs(ROLES) do print((" %d) %s"):format(i, r)) end
write("> ")
local sel = read()
local n = tonumber(sel)
if n and ROLES[n] then return ROLES[n] end
for _, r in ipairs(ROLES) do if r == sel then return r end end
die("Unknown role: " .. tostring(sel))
end
-- ---- preflight -------------------------------------------------------------
if not http then
die("HTTP API is disabled on this server.\n" ..
"Enable it in the server's computercraft-server.toml:\n" ..
" [http] enabled = true then restart the server.")
end
local role = args[1]
if not role then
role = chooseRole()
else
local ok = false
for _, r in ipairs(ROLES) do if r == role then ok = true end end
if not ok then die("Unknown role '" .. role .. "'. Valid: " .. table.concat(ROLES, ", ")) end
end
-- ---- fetch manifest --------------------------------------------------------
print("Installing role: " .. role)
local manifestUrl = BASE .. "/files/" .. role .. "/manifest"
local manifest, mErr = get(manifestUrl)
if not manifest then die("Could not fetch manifest (" .. mErr .. ")\n" .. manifestUrl) end
local files = {}
for line in manifest:gmatch("[^\r\n]+") do
local p = line:match("^%s*(.-)%s*$")
if p ~= "" then files[#files + 1] = p end
end
if #files == 0 then die("Manifest is empty: " .. manifestUrl) end
-- ---- download --------------------------------------------------------------
local ok, fail = 0, {}
for i, rel in ipairs(files) do
term.write(("[%d/%d] %s "):format(i, #files, rel))
local data, err = get(BASE .. "/files/" .. role .. "/" .. rel)
if data then
writeFile(rel, data)
term.setTextColor(colors.green); print("ok"); term.setTextColor(colors.white)
ok = ok + 1
else
term.setTextColor(colors.red); print("FAIL"); term.setTextColor(colors.white)
fail[#fail + 1] = rel .. " (" .. tostring(err) .. ")"
end
end
print(("Installed %d/%d files."):format(ok, #files))
if #fail > 0 then
term.setTextColor(colors.red)
print("Failed:")
for _, f in ipairs(fail) do print(" " .. f) end
term.setTextColor(colors.white)
die("Install incomplete -- re-run after fixing the errors above.")
end
term.setTextColor(colors.green)
print("Done. Reboot to auto-start (startup.lua).")
term.setTextColor(colors.white)
write("Reboot now? [y/N] ")
if read():lower() == "y" then os.reboot() end