feat: add TrapOS manifest install flow
This commit is contained in:
parent
c7d925cf18
commit
c47b6e0ae4
19
README.md
19
README.md
@ -1,21 +1,32 @@
|
|||||||
# Trap's ComputerCraft APIs
|
# TrapOS
|
||||||
|
|
||||||
|
A small in-game operating system for ComputerCraft / CC:Tweaked, built around a single-threaded event loop and a routed networking layer.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```
|
```
|
||||||
wget run https://raw.githubusercontent.com/guillaumearm/cc-libs/master/install.lua
|
wget run https://raw.githubusercontent.com/guillaumearm/cc-libs/master/install.lua
|
||||||
```
|
```
|
||||||
|
|
||||||
Install the beta branch:
|
Install the beta branch (one-time opt-in, asks for confirmation):
|
||||||
```
|
```
|
||||||
wget run https://raw.githubusercontent.com/guillaumearm/cc-libs/next/install.lua --beta
|
wget run https://raw.githubusercontent.com/guillaumearm/cc-libs/next/install.lua --beta
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Once a machine is on beta, `upgrade` keeps it on beta — `--beta` is not needed again. Use `upgrade --stable` to go back to the stable branch.
|
||||||
|
|
||||||
|
After install, every boot shows a colored MOTD with the installed version and branch (lime for stable, orange + `[BETA]` for beta).
|
||||||
|
|
||||||
|
## Manifest
|
||||||
|
|
||||||
|
The installed file list, version, autostart servers, and current branch all live in `manifest.json` at the repo root. A copy is persisted locally at `/trapos/manifest.json` after install, and drives `upgrade`, `startup/motd.lua`, and `startup/servers.lua`.
|
||||||
|
|
||||||
## APIs
|
## APIs
|
||||||
- `/apis/eventloop`: a simple event loop API.
|
- `/apis/eventloop`: a simple event loop API.
|
||||||
- `/apis/net`: an API to simplify sending and receiving routed messages, based on the `eventloop` library.
|
- `/apis/net`: an API to simplify sending and receiving routed messages, based on the `eventloop` library.
|
||||||
|
|
||||||
## Servers
|
## Servers
|
||||||
All servers are automatically started at boot.
|
Servers listed in `manifest.autostart` are launched at boot by `startup/servers.lua`.
|
||||||
|
|
||||||
- `/servers/ping-server`: allows a machine to respond to a `ping` command.
|
- `/servers/ping-server`: allows a machine to respond to a `ping` command.
|
||||||
|
|
||||||
@ -23,7 +34,7 @@ All servers are automatically started at boot.
|
|||||||
- `router`: routes messages. You need to set up a router to use all `apis/net`-based programs and libraries.
|
- `router`: routes messages. You need to set up a router to use all `apis/net`-based programs and libraries.
|
||||||
- `ping`: pings machines using `apis/net`.
|
- `ping`: pings machines using `apis/net`.
|
||||||
- `events`: emits and logs computer events.
|
- `events`: emits and logs computer events.
|
||||||
- `upgrade`: upgrades the machine. Use `upgrade --beta` to install from the beta branch.
|
- `upgrade`: upgrades the machine. Reads `/trapos/manifest.json` to stay on the current branch; use `--beta` to opt in or `--stable` to opt out.
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
See [DEVELOPMENT.md](./DEVELOPMENT.md) for development setup and workflow.
|
See [DEVELOPMENT.md](./DEVELOPMENT.md) for development setup and workflow.
|
||||||
|
|||||||
@ -11,3 +11,4 @@ Future ADRs can reuse the shape of the existing files when it is useful.
|
|||||||
- [`adr-0001-target-computercraft.md`](adr-0001-target-computercraft.md) - Target ComputerCraft.
|
- [`adr-0001-target-computercraft.md`](adr-0001-target-computercraft.md) - Target ComputerCraft.
|
||||||
- [`adr-0002-use-eventloop-for-async-code.md`](adr-0002-use-eventloop-for-async-code.md) - Use eventloop for async code.
|
- [`adr-0002-use-eventloop-for-async-code.md`](adr-0002-use-eventloop-for-async-code.md) - Use eventloop for async code.
|
||||||
- [`adr-0003-current-net-api-state.md`](adr-0003-current-net-api-state.md) - Current net API state.
|
- [`adr-0003-current-net-api-state.md`](adr-0003-current-net-api-state.md) - Current net API state.
|
||||||
|
- [`adr-0004-trapos-branding-and-manifest.md`](adr-0004-trapos-branding-and-manifest.md) - TrapOS branding and manifest-driven installs.
|
||||||
|
|||||||
47
docs/adrs/adr-0004-trapos-branding-and-manifest.md
Normal file
47
docs/adrs/adr-0004-trapos-branding-and-manifest.md
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# ADR 0004: TrapOS Branding And Manifest-Driven Installs
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Date
|
||||||
|
|
||||||
|
2026-06-07
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
The project started as a loose collection of ComputerCraft / CC:Tweaked APIs and programs. As the surface area grew (eventloop, net, router, ping, events, upgrade) and the install/upgrade flow gained a beta channel, three pain points emerged:
|
||||||
|
|
||||||
|
- `install.lua` carries a hardcoded `LIST_FILES` table that has to be edited every time a file is added or removed. Adding a single shipped file means editing the file itself, the installer, and sometimes `startup/servers.lua`.
|
||||||
|
- The `--beta` flag is not persisted. The user has to remember to pass it on every `upgrade`, which makes the beta channel awkward to live on.
|
||||||
|
- The system has no visible identity at boot. There is no name, no version line, nothing that confirms which branch is installed.
|
||||||
|
|
||||||
|
At the same time, the codebase has outgrown the "Trap's ComputerCraft APIs" framing. It is closer to a small in-game operating system than a library, and treating it as one unlocks a clearer story (a name, a version, a manifest, a boot banner).
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Adopt the name **TrapOS** and a manifest-driven install architecture.
|
||||||
|
|
||||||
|
- A single `manifest.json` at the repo root is the source of truth for the project: name, version, branch, list of shipped files, and the list of servers to autostart at boot. Parsed with `textutils.unserializeJSON` / `textutils.serializeJSON` (built-in to CC:Tweaked).
|
||||||
|
- A local copy of that manifest is written to `/trapos/manifest.json` at the end of every install. This local file is the authoritative system state on the computer:
|
||||||
|
- `branch` is the persisted beta opt-in. Once a user installs with `--beta` (and confirms a one-time `(y/N)` prompt), subsequent `upgrade` calls auto-target the `next` branch with no flag needed.
|
||||||
|
- `version` is what the boot MOTD displays.
|
||||||
|
- `files` and `autostart` drive the next install and the boot sequence.
|
||||||
|
- A new `startup/motd.lua` prints a colored `TrapOS v<version>` line at boot — lime for stable, orange with a `[BETA]` tag for beta. Guarded on `term.isColor()` so monochrome terminals still get the text.
|
||||||
|
- `startup/servers.lua` reads `autostart` from the local manifest instead of carrying its own hardcoded list.
|
||||||
|
- The shipped install URL stays at `https://raw.githubusercontent.com/guillaumearm/cc-libs/...` for now. Renaming the GitHub repository is a follow-up, tracked in the "Future Work" section below.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- Adding a new file or autostart server is now a one-line edit to `manifest.json`. Both `install.lua` and `startup/servers.lua` pick it up automatically.
|
||||||
|
- The beta channel becomes a real opt-in: a single confirmed `upgrade --beta` is enough to live on `next`. A new `--stable` flag exists for the symmetric opt-out.
|
||||||
|
- The boot banner gives users an immediate sanity check ("am I on the right branch, the right version?").
|
||||||
|
- The system gains an explicit local state directory (`/trapos/`) and a clear contract for what lives there.
|
||||||
|
- The installer takes a hard dependency on `textutils.serializeJSON` / `unserializeJSON`, which require CC:Tweaked ≥ 1.79. This is well within any reasonable target version for Minecraft 1.21.
|
||||||
|
- Existing computers running the old installer still upgrade cleanly: the old `upgrade` fetches the new `install.lua`, which then creates `/trapos/manifest.json` from the manifest it just downloaded.
|
||||||
|
|
||||||
|
## Future Work
|
||||||
|
|
||||||
|
- **Repository rename.** Once the install flow has stabilized on `TrapOS`, the GitHub repository will be renamed from `cc-libs` to a name that matches (likely `trapos`). The install URL inside `install.lua` and `programs/upgrade.lua` will be updated in the same PR, and a redirect at the old URL is sufficient for in-the-wild installs.
|
||||||
|
- **Package manager.** The longer-term direction floated during planning was a small package manager where each directory in the repo is a package. The current manifest is a deliberate step toward that — same shape (name, version, files), single-package case — and can grow into multi-manifest discovery without changing the install/upgrade contract.
|
||||||
|
- **Per-version migration system.** Today the installer carries a static list of legacy files to delete. A future change can replace this with a per-version migration block driven by the manifest.
|
||||||
150
install.lua
150
install.lua
@ -1,66 +1,142 @@
|
|||||||
local _VERSION = '2.3.0'
|
local _VERSION = '3.0.0';
|
||||||
|
|
||||||
local LIST_FILES = {
|
local REPO_BASE = 'https://raw.githubusercontent.com/guillaumearm/cc-libs/';
|
||||||
-- startup
|
local LOCAL_STATE_DIR = '/trapos';
|
||||||
'startup/servers.lua',
|
local LOCAL_MANIFEST_PATH = '/trapos/manifest.json';
|
||||||
-- servers
|
|
||||||
'servers/ping-server.lua',
|
|
||||||
-- programs
|
|
||||||
'programs/router.lua', -- router is not in servers folder because he's not ran on every machines
|
|
||||||
'programs/events.lua',
|
|
||||||
'programs/ping.lua',
|
|
||||||
'programs/upgrade.lua',
|
|
||||||
-- apis
|
|
||||||
'apis/net.lua',
|
|
||||||
'apis/eventloop.lua',
|
|
||||||
};
|
|
||||||
|
|
||||||
local function printUsage()
|
local function printUsage()
|
||||||
print('install usage:');
|
print('install usage:');
|
||||||
print();
|
print();
|
||||||
print('\t\t\twget run <install-url>');
|
print('\t\twget run <install-url>');
|
||||||
print('\t\t\twget run <install-url> --beta');
|
print('\t\twget run <install-url> --beta');
|
||||||
|
print('\t\twget run <install-url> --stable');
|
||||||
|
end
|
||||||
|
|
||||||
|
local function readLocalManifest()
|
||||||
|
if not fs.exists(LOCAL_MANIFEST_PATH) then return nil end
|
||||||
|
local f = fs.open(LOCAL_MANIFEST_PATH, 'r');
|
||||||
|
if not f then return nil end
|
||||||
|
local data = f.readAll();
|
||||||
|
f.close();
|
||||||
|
if not data or data == '' then return nil end
|
||||||
|
return textutils.unserializeJSON(data);
|
||||||
|
end
|
||||||
|
|
||||||
|
local function writeLocalManifest(manifest)
|
||||||
|
fs.makeDir(LOCAL_STATE_DIR);
|
||||||
|
local f = fs.open(LOCAL_MANIFEST_PATH, 'w');
|
||||||
|
if not f then return false end
|
||||||
|
f.write(textutils.serializeJSON(manifest));
|
||||||
|
f.close();
|
||||||
|
return true;
|
||||||
|
end
|
||||||
|
|
||||||
|
local function confirmBeta()
|
||||||
|
print();
|
||||||
|
print('You are about to install the BETA branch (next).');
|
||||||
|
print('Beta builds may be unstable. Continue? (y/N)');
|
||||||
|
write('> ');
|
||||||
|
local answer = read();
|
||||||
|
if not answer then return false end
|
||||||
|
answer = answer:lower();
|
||||||
|
return answer == 'y' or answer == 'yes';
|
||||||
|
end
|
||||||
|
|
||||||
|
local function fetchManifest(branch)
|
||||||
|
local url = REPO_BASE .. branch .. '/manifest.json';
|
||||||
|
local response = http.get(url);
|
||||||
|
if not response then return nil end
|
||||||
|
local body = response.readAll();
|
||||||
|
response.close();
|
||||||
|
if not body or body == '' then return nil end
|
||||||
|
return textutils.unserializeJSON(body);
|
||||||
end
|
end
|
||||||
|
|
||||||
local command = ...;
|
local command = ...;
|
||||||
local branch = 'master';
|
local forceBeta = false;
|
||||||
|
local forceStable = false;
|
||||||
|
|
||||||
|
if command == 'version' or command == '-version' or command == '--version' then
|
||||||
|
print('install v' .. _VERSION);
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
if command == 'help' or command == '-help' or command == '--help' then
|
||||||
|
printUsage();
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
if command == '--beta' or command == '-beta' then
|
if command == '--beta' or command == '-beta' then
|
||||||
branch = 'next';
|
forceBeta = true;
|
||||||
|
elseif command == '--stable' or command == '-stable' then
|
||||||
|
forceStable = true;
|
||||||
elseif command ~= nil and command ~= '' then
|
elseif command ~= nil and command ~= '' then
|
||||||
printUsage();
|
printUsage();
|
||||||
return;
|
return;
|
||||||
end
|
end
|
||||||
|
|
||||||
-- remove old files
|
local localManifest = readLocalManifest();
|
||||||
fs.delete('ping-server.lua'); -- replaced by `servers/ping-server.lua`
|
local localBranch = localManifest and localManifest.branch or nil;
|
||||||
fs.delete('ping.lua') -- replaced by `programs/ping.lua`
|
local branch;
|
||||||
fs.delete('cube.lua') -- replaced by `programs/cube.lua`
|
|
||||||
fs.delete('router.lua') -- replaced by `programs/router.lua`
|
if forceBeta then
|
||||||
fs.delete('servers/cube-startup.lua'); -- replaced by `servers/cube-boot.lua`
|
branch = 'next';
|
||||||
|
if localBranch ~= 'next' then
|
||||||
|
if not confirmBeta() then
|
||||||
|
print('Aborted.');
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif forceStable then
|
||||||
|
branch = 'master';
|
||||||
|
else
|
||||||
|
branch = localBranch or 'master';
|
||||||
|
end
|
||||||
|
|
||||||
|
print('Fetching manifest from branch: ' .. branch);
|
||||||
|
local manifest = fetchManifest(branch);
|
||||||
|
if not manifest or type(manifest.files) ~= 'table' then
|
||||||
|
print('Failed to fetch or parse manifest.json from ' .. branch);
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
-- The persisted branch reflects the actually-used branch, not the manifest default.
|
||||||
|
manifest.branch = branch;
|
||||||
|
|
||||||
|
local REPO_PREFIX = REPO_BASE .. branch .. '/';
|
||||||
|
|
||||||
|
-- Legacy file cleanup (pre-manifest installs).
|
||||||
|
fs.delete('ping-server.lua');
|
||||||
|
fs.delete('ping.lua');
|
||||||
|
fs.delete('cube.lua');
|
||||||
|
fs.delete('router.lua');
|
||||||
|
fs.delete('servers/cube-startup.lua');
|
||||||
fs.delete('programs/cube.lua');
|
fs.delete('programs/cube.lua');
|
||||||
fs.delete('programs/goo.lua');
|
fs.delete('programs/goo.lua');
|
||||||
fs.delete('servers/cube-server.lua');
|
fs.delete('servers/cube-server.lua');
|
||||||
fs.delete('servers/cube-boot.lua');
|
fs.delete('servers/cube-boot.lua');
|
||||||
|
|
||||||
local REPO_PREFIX = 'https://raw.githubusercontent.com/guillaumearm/cc-libs/' .. branch .. '/'
|
local previousDir = shell.dir();
|
||||||
|
shell.setDir('/');
|
||||||
local previousDir = shell.dir()
|
|
||||||
|
|
||||||
shell.setDir('/')
|
|
||||||
|
|
||||||
fs.makeDir('/programs');
|
fs.makeDir('/programs');
|
||||||
fs.makeDir('/apis');
|
fs.makeDir('/apis');
|
||||||
fs.makeDir('/startup');
|
fs.makeDir('/startup');
|
||||||
fs.makeDir('/servers');
|
fs.makeDir('/servers');
|
||||||
|
fs.makeDir(LOCAL_STATE_DIR);
|
||||||
|
|
||||||
for _, filePath in pairs(LIST_FILES) do
|
for _, filePath in ipairs(manifest.files) do
|
||||||
fs.delete(filePath)
|
fs.delete(filePath);
|
||||||
shell.execute('wget', REPO_PREFIX .. filePath, filePath)
|
shell.execute('wget', REPO_PREFIX .. filePath, filePath);
|
||||||
end
|
end
|
||||||
|
|
||||||
print()
|
if not writeLocalManifest(manifest) then
|
||||||
print('=> Execute startup/servers.lua')
|
print('Warning: failed to write local manifest');
|
||||||
shell.execute('/startup/servers.lua')
|
end
|
||||||
|
|
||||||
shell.setDir(previousDir)
|
print();
|
||||||
|
print('=> TrapOS v' .. (manifest.version or '?') .. ' installed (branch: ' .. branch .. ')');
|
||||||
|
print('=> Execute startup/servers.lua');
|
||||||
|
shell.execute('/startup/servers.lua');
|
||||||
|
|
||||||
|
shell.setDir(previousDir);
|
||||||
|
|||||||
19
manifest.json
Normal file
19
manifest.json
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"name": "TrapOS",
|
||||||
|
"version": "0.2.0",
|
||||||
|
"branch": "master",
|
||||||
|
"files": [
|
||||||
|
"startup/motd.lua",
|
||||||
|
"startup/servers.lua",
|
||||||
|
"servers/ping-server.lua",
|
||||||
|
"programs/router.lua",
|
||||||
|
"programs/events.lua",
|
||||||
|
"programs/ping.lua",
|
||||||
|
"programs/upgrade.lua",
|
||||||
|
"apis/net.lua",
|
||||||
|
"apis/eventloop.lua"
|
||||||
|
],
|
||||||
|
"autostart": [
|
||||||
|
"servers/ping-server"
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -1,19 +1,31 @@
|
|||||||
local _VERSION = '1.3.0';
|
local _VERSION = '1.4.0';
|
||||||
|
|
||||||
local INSTALL_URL = 'https://raw.githubusercontent.com/guillaumearm/cc-libs/master/install.lua';
|
local REPO_BASE = 'https://raw.githubusercontent.com/guillaumearm/cc-libs/';
|
||||||
local BETA_INSTALL_URL = 'https://raw.githubusercontent.com/guillaumearm/cc-libs/next/install.lua';
|
local LOCAL_MANIFEST_PATH = '/trapos/manifest.json';
|
||||||
|
|
||||||
local command = ...;
|
|
||||||
|
|
||||||
local function printUsage()
|
local function printUsage()
|
||||||
print('upgrade usage:');
|
print('upgrade usage:');
|
||||||
print();
|
print();
|
||||||
print('\t\t\tupgrade');
|
print('\t\tupgrade');
|
||||||
print('\t\t\tupgrade --beta');
|
print('\t\tupgrade --beta');
|
||||||
print('\t\t\tupgrade version');
|
print('\t\tupgrade --stable');
|
||||||
print('\t\t\tupgrade help');
|
print('\t\tupgrade version');
|
||||||
|
print('\t\tupgrade help');
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function readLocalBranch()
|
||||||
|
if not fs.exists(LOCAL_MANIFEST_PATH) then return nil end
|
||||||
|
local f = fs.open(LOCAL_MANIFEST_PATH, 'r');
|
||||||
|
if not f then return nil end
|
||||||
|
local data = f.readAll();
|
||||||
|
f.close();
|
||||||
|
if not data or data == '' then return nil end
|
||||||
|
local manifest = textutils.unserializeJSON(data);
|
||||||
|
return manifest and manifest.branch or nil;
|
||||||
|
end
|
||||||
|
|
||||||
|
local command = ...;
|
||||||
|
|
||||||
if command == 'version' or command == '-version' or command == '--version' then
|
if command == 'version' or command == '-version' or command == '--version' then
|
||||||
print('upgrade v' .. _VERSION);
|
print('upgrade v' .. _VERSION);
|
||||||
return;
|
return;
|
||||||
@ -24,14 +36,26 @@ if command == 'help' or command == '-help' or command == '--help' then
|
|||||||
return;
|
return;
|
||||||
end
|
end
|
||||||
|
|
||||||
if command == '--beta' or command == '-beta' then
|
local branch;
|
||||||
shell.execute('wget', 'run', BETA_INSTALL_URL, '--beta');
|
local extraFlag;
|
||||||
return;
|
|
||||||
end
|
|
||||||
|
|
||||||
if command ~= nil and command ~= '' then
|
if command == '--beta' or command == '-beta' then
|
||||||
|
branch = 'next';
|
||||||
|
extraFlag = '--beta';
|
||||||
|
elseif command == '--stable' or command == '-stable' then
|
||||||
|
branch = 'master';
|
||||||
|
extraFlag = '--stable';
|
||||||
|
elseif command ~= nil and command ~= '' then
|
||||||
printUsage();
|
printUsage();
|
||||||
return;
|
return;
|
||||||
|
else
|
||||||
|
branch = readLocalBranch() or 'master';
|
||||||
end
|
end
|
||||||
|
|
||||||
shell.execute('wget', 'run', INSTALL_URL);
|
local installUrl = REPO_BASE .. branch .. '/install.lua';
|
||||||
|
|
||||||
|
if extraFlag then
|
||||||
|
shell.execute('wget', 'run', installUrl, extraFlag);
|
||||||
|
else
|
||||||
|
shell.execute('wget', 'run', installUrl);
|
||||||
|
end
|
||||||
|
|||||||
45
startup/motd.lua
Normal file
45
startup/motd.lua
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
local _VERSION = '1.0.0';
|
||||||
|
|
||||||
|
local LOCAL_MANIFEST_PATH = '/trapos/manifest.json';
|
||||||
|
|
||||||
|
local function readLocalManifest()
|
||||||
|
if not fs.exists(LOCAL_MANIFEST_PATH) then return nil end
|
||||||
|
local f = fs.open(LOCAL_MANIFEST_PATH, 'r');
|
||||||
|
if not f then return nil end
|
||||||
|
local data = f.readAll();
|
||||||
|
f.close();
|
||||||
|
if not data or data == '' then return nil end
|
||||||
|
return textutils.unserializeJSON(data);
|
||||||
|
end
|
||||||
|
|
||||||
|
local manifest = readLocalManifest();
|
||||||
|
if not manifest then return end
|
||||||
|
|
||||||
|
local name = manifest.name or 'TrapOS';
|
||||||
|
local version = manifest.version or '?';
|
||||||
|
local branch = manifest.branch or 'master';
|
||||||
|
local isBeta = branch == 'next';
|
||||||
|
|
||||||
|
local hasColor = term.isColor and term.isColor();
|
||||||
|
local previousColor;
|
||||||
|
|
||||||
|
if hasColor then
|
||||||
|
previousColor = term.getTextColor();
|
||||||
|
if isBeta then
|
||||||
|
term.setTextColor(colors.orange);
|
||||||
|
else
|
||||||
|
term.setTextColor(colors.lime);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if isBeta then
|
||||||
|
print(name .. ' v' .. version .. ' [BETA]');
|
||||||
|
else
|
||||||
|
print(name .. ' v' .. version);
|
||||||
|
end
|
||||||
|
|
||||||
|
if hasColor and previousColor then
|
||||||
|
term.setTextColor(previousColor);
|
||||||
|
end
|
||||||
|
|
||||||
|
print();
|
||||||
@ -1,8 +1,16 @@
|
|||||||
local _VERSION = '1.1.2'
|
local _VERSION = '1.2.0'
|
||||||
|
|
||||||
local SERVERS = {
|
local LOCAL_MANIFEST_PATH = '/trapos/manifest.json';
|
||||||
"servers/ping-server",
|
|
||||||
};
|
local function readLocalManifest()
|
||||||
|
if not fs.exists(LOCAL_MANIFEST_PATH) then return nil end
|
||||||
|
local f = fs.open(LOCAL_MANIFEST_PATH, 'r');
|
||||||
|
if not f then return nil end
|
||||||
|
local data = f.readAll();
|
||||||
|
f.close();
|
||||||
|
if not data or data == '' then return nil end
|
||||||
|
return textutils.unserializeJSON(data);
|
||||||
|
end
|
||||||
|
|
||||||
local function init()
|
local function init()
|
||||||
shell.setPath(shell.path() .. ':/programs');
|
shell.setPath(shell.path() .. ':/programs');
|
||||||
@ -54,12 +62,16 @@ local function getServerFns(serverList)
|
|||||||
return servers;
|
return servers;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local manifest = readLocalManifest();
|
||||||
|
local SERVERS = (manifest and manifest.autostart) or {};
|
||||||
|
|
||||||
local servers = getServerFns(SERVERS);
|
local servers = getServerFns(SERVERS);
|
||||||
|
|
||||||
print("\nStarting servers...");
|
if #SERVERS > 0 then
|
||||||
|
print("\nStarting servers...");
|
||||||
for _, v in ipairs(SERVERS) do
|
for _, v in ipairs(SERVERS) do
|
||||||
print("\t\t" .. v)
|
print("\t\t" .. v)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
parallel.waitForAll(shellFn, table.unpack(servers));
|
parallel.waitForAll(shellFn, table.unpack(servers));
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user