From 26564cbcc13e4478bac82b928c2f8c35ee5d8bd9 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" <kepler155c@gmail.com> Date: Sat, 22 Dec 2018 22:11:16 -0500 Subject: [PATCH] custom help files + redo System UI --- sys/apis/config.lua | 1 + sys/apis/turtle/home.lua | 42 +++++ sys/apis/ui.lua | 10 +- sys/apps/System.lua | 339 +++++----------------------------- sys/apps/system/aliases.lua | 66 +++++++ sys/apps/system/label.lua | 49 +++++ sys/apps/system/network.lua | 56 ++++++ sys/apps/system/password.lua | 53 ++++++ sys/apps/system/path.lua | 50 +++++ sys/apps/system/settings.lua | 47 +++++ sys/apps/system/turtle.lua | 62 +++++++ sys/extensions/5.network.lua | 8 +- sys/extensions/6.packages.lua | 13 +- sys/help/Opus Applications | 30 +++ sys/help/Wireless Networking | 7 + 15 files changed, 541 insertions(+), 292 deletions(-) create mode 100644 sys/apis/turtle/home.lua create mode 100644 sys/apps/system/aliases.lua create mode 100644 sys/apps/system/label.lua create mode 100644 sys/apps/system/network.lua create mode 100644 sys/apps/system/password.lua create mode 100644 sys/apps/system/path.lua create mode 100644 sys/apps/system/settings.lua create mode 100644 sys/apps/system/turtle.lua create mode 100644 sys/help/Opus Applications create mode 100644 sys/help/Wireless Networking diff --git a/sys/apis/config.lua b/sys/apis/config.lua index 13ab441..35f7310 100644 --- a/sys/apis/config.lua +++ b/sys/apis/config.lua @@ -7,6 +7,7 @@ local Config = { } function Config.load(fname, data) local filename = 'usr/config/' .. fname + data = data or { } if not fs.exists('usr/config') then fs.makeDir('usr/config') diff --git a/sys/apis/turtle/home.lua b/sys/apis/turtle/home.lua new file mode 100644 index 0000000..29a1cbc --- /dev/null +++ b/sys/apis/turtle/home.lua @@ -0,0 +1,42 @@ +local Config = require('config') +local GPS = require('gps') + +local turtle = _G.turtle + +local Home = { } + +function Home.go() + local config = { } + Config.load('gps', config) + + if config.home then + if turtle.enableGPS() then + return turtle.pathfind(config.home) + end + end +end + +function Home.set() + local config = { } + Config.load('gps', config) + + local pt = GPS.getPoint() + if pt then + local originalHeading = turtle.point.heading + local heading = GPS.getHeading() + if heading then + local turns = (turtle.point.heading - originalHeading) % 4 + pt.heading = (heading - turns) % 4 + config.home = pt + Config.update('gps', config) + + pt = GPS.getPoint() + pt.heading = heading + turtle.setPoint(pt, true) + turtle._goto(config.home) + return config.home + end + end +end + +return Home diff --git a/sys/apis/ui.lua b/sys/apis/ui.lua index dffb370..c9bcabc 100644 --- a/sys/apis/ui.lua +++ b/sys/apis/ui.lua @@ -2250,6 +2250,13 @@ function UI.Tabs:add(children) end end +function UI.Tabs:selectTab(tab) + local menuItem = Util.find(self.tabBar:getFocusables(), 'tabUid', tab.uid) + if menuItem then + self.tabBar:emit({ type = 'tab_select', button = { uid = menuItem.uid } }) + end +end + function UI.Tabs:enable() self.enabled = true self.tabBar:enable() @@ -2999,6 +3006,7 @@ function UI.Chooser:eventHandler(event) if event.key == 'right' or event.key == 'space' then local _,k = Util.find(self.choices, 'value', self.value) local choice + if not k then k = 1 end if k and k < #self.choices then choice = self.choices[k+1] else @@ -3021,7 +3029,7 @@ function UI.Chooser:eventHandler(event) self:draw() return true end - elseif event.type == 'mouse_click' then + elseif event.type == 'mouse_click' or event.type == 'mouse_doubleclick' then if event.x == 1 then self:emit({ type = 'key', key = 'left' }) return true diff --git a/sys/apps/System.lua b/sys/apps/System.lua index ce2a2b1..ed742ef 100644 --- a/sys/apps/System.lua +++ b/sys/apps/System.lua @@ -1,16 +1,9 @@ -_G.requireInjector(_ENV) +local Config = require('config') +local UI = require('ui') +local Util = require('util') -local Config = require('config') -local Security = require('security') -local SHA1 = require('sha1') -local UI = require('ui') -local Util = require('util') - -local fs = _G.fs -local os = _G.os -local settings = _G.settings -local shell = _ENV.shell -local turtle = _G.turtle +local fs = _G.fs +local shell = _ENV.shell UI:configure('System', ...) @@ -23,116 +16,18 @@ Config.load('shell', env) local systemPage = UI.Page { tabs = UI.Tabs { - pathTab = UI.Window { - tabTitle = 'Path', - entry = UI.TextEntry { - x = 2, y = 2, ex = -2, - limit = 256, - value = shell.path(), - shadowText = 'enter system path', - accelerators = { - enter = 'update_path', - }, - }, + settings = UI.Window { + tabTitle = 'Category', grid = UI.Grid { - y = 4, - disableHeader = true, - columns = { { key = 'value' } }, + y = 2, + columns = { + { heading = 'Name', key = 'name' }, + { heading = 'Description', key = 'description' }, + }, + sortColumn = 'name', autospace = true, }, }, - - aliasTab = UI.Window { - tabTitle = 'Alias', - alias = UI.TextEntry { - x = 2, y = 2, ex = -2, - limit = 32, - shadowText = 'Alias', - }, - path = UI.TextEntry { - y = 3, x = 2, ex = -2, - limit = 256, - shadowText = 'Program path', - accelerators = { - enter = 'new_alias', - }, - }, - grid = UI.Grid { - y = 5, - sortColumn = 'alias', - columns = { - { heading = 'Alias', key = 'alias' }, - { heading = 'Program', key = 'path' }, - }, - accelerators = { - delete = 'delete_alias', - }, - }, - }, - - passwordTab = UI.Window { - tabTitle = 'Password', - oldPass = UI.TextEntry { - x = 2, y = 2, ex = -2, - limit = 32, - mask = true, - shadowText = 'old password', - inactive = not Security.getPassword(), - }, - newPass = UI.TextEntry { - y = 3, x = 2, ex = -2, - limit = 32, - mask = true, - shadowText = 'new password', - accelerators = { - enter = 'new_password', - }, - }, - button = UI.Button { - x = 2, y = 5, - text = 'Update', - event = 'update_password', - }, - info = UI.TextArea { - x = 2, ex = -2, - y = 7, - inactive = true, - value = 'Add a password to enable other computers to connect to this one.', - } - }, - - infoTab = UI.Window { - tabTitle = 'Info', - labelText = UI.Text { - x = 3, y = 2, - value = 'Label' - }, - label = UI.TextEntry { - x = 9, y = 2, ex = -4, - limit = 32, - value = os.getComputerLabel(), - accelerators = { - enter = 'update_label', - }, - }, - grid = UI.ScrollingGrid { - y = 3, - values = { - { name = '', value = '' }, - { name = 'CC version', value = Util.getVersion() }, - { name = 'Lua version', value = _VERSION }, - { name = 'MC version', value = Util.getMinecraftVersion() }, - { name = 'Disk free', value = Util.toBytes(fs.getFreeSpace('/')) }, - { name = 'Computer ID', value = tostring(os.getComputerID()) }, - { name = 'Day', value = tostring(os.day()) }, - }, - inactive = true, - columns = { - { key = 'name', width = 12 }, - { key = 'value' }, - }, - }, - }, }, notification = UI.Notification(), accelerators = { @@ -140,177 +35,15 @@ local systemPage = UI.Page { }, } -if turtle then - pcall(function() - local Home = require('turtle.home') --- TODO: dont rely on turtle.home - local values = { } - Config.load('gps', values.home and { values.home } or { }) - - systemPage.tabs:add({ - gpsTab = UI.Window { - tabTitle = 'GPS', - labelText = UI.Text { - x = 3, y = 2, - value = 'On restart, return to this location' - }, - grid = UI.Grid { - x = 3, ex = -3, y = 4, - height = 2, - values = values, - inactive = true, - columns = { - { heading = 'x', key = 'x' }, - { heading = 'y', key = 'y' }, - { heading = 'z', key = 'z' }, - }, - }, - button1 = UI.Button { - x = 3, y = 7, - text = 'Set home', - event = 'gps_set', - }, - button2 = UI.Button { - ex = -3, y = 7, width = 7, - text = 'Clear', - event = 'gps_clear', - }, - }, - }) - function systemPage.tabs.gpsTab:eventHandler(event) - if event.type == 'gps_set' then - systemPage.notification:info('Determining location', 10) - systemPage:sync() - if Home.set() then - Config.load('gps', values) - self.grid:setValues(values.home and { values.home } or { }) - self.grid:draw() - systemPage.notification:success('Location set') - else - systemPage.notification:error('Unable to determine location') - end - return true - elseif event.type == 'gps_clear' then - fs.delete('usr/config/gps') - self.grid:setValues({ }) - self.grid:draw() - return true - end +function systemPage.tabs.settings:eventHandler(event) + if event.type == 'grid_select' then + local tab = event.selected.tab + if not systemPage.tabs[tab.tabTitle] then + systemPage.tabs:add({ [ tab.tabTitle ] = tab }) + tab:disable() end - end) -end - -if settings then - local values = { } - for _,v in pairs(settings.getNames()) do - local value = settings.get(v) - if not value then - value = false - end - table.insert(values, { - name = v, - value = value, - }) - end - - systemPage.tabs:add({ - settingsTab = UI.Window { - tabTitle = 'Settings', - grid = UI.Grid { - y = 1, - values = values, - autospace = true, - sortColumn = 'name', - columns = { - { heading = 'Setting', key = 'name' }, - { heading = 'Value', key = 'value' }, - }, - }, - } - }) - function systemPage.tabs.settingsTab:eventHandler(event) - if event.type == 'grid_select' then - if not event.selected.value or type(event.selected.value) == 'boolean' then - event.selected.value = not event.selected.value - end - settings.set(event.selected.name, event.selected.value) - settings.save('.settings') - self.grid:draw() - return true - end - end -end - -function systemPage.tabs.pathTab.grid:draw() - self.values = { } - for _,v in ipairs(Util.split(env.path, '(.-):')) do - table.insert(self.values, { value = v }) - end - self:update() - UI.Grid.draw(self) -end - -function systemPage.tabs.pathTab:eventHandler(event) - if event.type == 'update_path' then - env.path = self.entry.value - self.grid:setIndex(self.grid:getIndex()) - self.grid:draw() - Config.update('shell', env) - systemPage.notification:success('reboot to take effect') - return true - end -end - -function systemPage.tabs.aliasTab.grid:draw() - self.values = { } - for k,v in pairs(env.aliases) do - table.insert(self.values, { alias = k, path = v }) - end - self:update() - UI.Grid.draw(self) -end - -function systemPage.tabs.aliasTab:eventHandler(event) - if event.type == 'delete_alias' then - env.aliases[self.grid:getSelected().alias] = nil - self.grid:setIndex(self.grid:getIndex()) - self.grid:draw() - Config.update('shell', env) - systemPage.notification:success('reboot to take effect') - return true - - elseif event.type == 'new_alias' then - env.aliases[self.alias.value] = self.path.value - self.alias:reset() - self.path:reset() - self:draw() - self:setFocus(self.alias) - Config.update('shell', env) - systemPage.notification:success('reboot to take effect') - return true - end -end - -function systemPage.tabs.passwordTab:eventHandler(event) - if event.type == 'update_password' then - if #self.newPass.value == 0 then - systemPage.notification:error('Invalid password') - elseif Security.getPassword() and not Security.verifyPassword(SHA1.sha1(self.oldPass.value)) then - systemPage.notification:error('Passwords do not match') - else - Security.updatePassword(SHA1.sha1(self.newPass.value)) - self.oldPass.inactive = false - systemPage.notification:success('Password updated') - end - - return true - end -end - -function systemPage.tabs.infoTab:eventHandler(event) - if event.type == 'update_label' then - os.setComputerLabel(self.label.value) - systemPage.notification:success('Label updated') + systemPage.tabs:selectTab(tab) + self.parent:draw() return true end end @@ -318,13 +51,43 @@ end function systemPage:eventHandler(event) if event.type == 'quit' then UI:exitPullEvents() + + elseif event.type == 'success_message' then + self.notification:success(event.message) + + elseif event.type == 'info_message' then + self.notification:info(event.message) + + elseif event.type == 'error_message' then + self.notification:error(event.message) + elseif event.type == 'tab_activate' then event.activated:focusFirst() + else return UI.Page.eventHandler(self, event) end return true end +local function loadDirectory(dir) + local plugins = { } + for _, file in pairs(fs.list(dir)) do + local s, m = Util.run(_ENV, fs.combine(dir, file)) + if not s and m then + _G.printError('Error loading: ' .. file) + error(m or 'Unknown error') + elseif s and m then + table.insert(plugins, { tab = m, name = m.tabTitle, description = m.description }) + end + end + return plugins +end + +local programDir = fs.getDir(shell.getRunningProgram()) +local plugins = loadDirectory(fs.combine(programDir, 'system'), { }) + +systemPage.tabs.settings.grid:setValues(plugins) + UI:setPage(systemPage) UI:pullEvents() diff --git a/sys/apps/system/aliases.lua b/sys/apps/system/aliases.lua new file mode 100644 index 0000000..cdb38ca --- /dev/null +++ b/sys/apps/system/aliases.lua @@ -0,0 +1,66 @@ +local Config = require('config') +local UI = require('ui') + +local aliasTab = UI.Window { + tabTitle = 'Aliases', + description = 'Shell aliases', + alias = UI.TextEntry { + x = 2, y = 2, ex = -2, + limit = 32, + shadowText = 'Alias', + }, + path = UI.TextEntry { + y = 3, x = 2, ex = -2, + limit = 256, + shadowText = 'Program path', + accelerators = { + enter = 'new_alias', + }, + }, + grid = UI.Grid { + y = 5, + sortColumn = 'alias', + columns = { + { heading = 'Alias', key = 'alias' }, + { heading = 'Program', key = 'path' }, + }, + accelerators = { + delete = 'delete_alias', + }, + }, +} + +function aliasTab.grid:draw() + self.values = { } + local env = Config.load('shell') + for k,v in pairs(env.aliases) do + table.insert(self.values, { alias = k, path = v }) + end + self:update() + UI.Grid.draw(self) +end + +function aliasTab:eventHandler(event) + if event.type == 'delete_alias' then + local env = Config.load('shell') + env.aliases[self.grid:getSelected().alias] = nil + self.grid:setIndex(self.grid:getIndex()) + self.grid:draw() + Config.update('shell', env) + self:emit({ type = 'success_message', message = 'reboot to take effect' }) + return true + + elseif event.type == 'new_alias' then + local env = Config.load('shell') + env.aliases[self.alias.value] = self.path.value + self.alias:reset() + self.path:reset() + self:draw() + self:setFocus(self.alias) + Config.update('shell', env) + self:emit({ type = 'success_message', message = 'reboot to take effect' }) + return true + end +end + +return aliasTab diff --git a/sys/apps/system/label.lua b/sys/apps/system/label.lua new file mode 100644 index 0000000..0d03425 --- /dev/null +++ b/sys/apps/system/label.lua @@ -0,0 +1,49 @@ +local UI = require('ui') +local Util = require('util') + +local fs = _G.fs +local os = _G.os + +local labelTab = UI.Window { + tabTitle = 'Label', + description = 'Set the computer label', + labelText = UI.Text { + x = 3, y = 2, + value = 'Label' + }, + label = UI.TextEntry { + x = 9, y = 2, ex = -4, + limit = 32, + value = os.getComputerLabel(), + accelerators = { + enter = 'update_label', + }, + }, + grid = UI.ScrollingGrid { + y = 3, + values = { + { name = '', value = '' }, + { name = 'CC version', value = Util.getVersion() }, + { name = 'Lua version', value = _VERSION }, + { name = 'MC version', value = Util.getMinecraftVersion() }, + { name = 'Disk free', value = Util.toBytes(fs.getFreeSpace('/')) }, + { name = 'Computer ID', value = tostring(os.getComputerID()) }, + { name = 'Day', value = tostring(os.day()) }, + }, + inactive = true, + columns = { + { key = 'name', width = 12 }, + { key = 'value' }, + }, + }, +} + +function labelTab:eventHandler(event) + if event.type == 'update_label' then + os.setComputerLabel(self.label.value) + self:emit({ type = 'success_message', message = 'Label updated' }) + return true + end +end + +return labelTab diff --git a/sys/apps/system/network.lua b/sys/apps/system/network.lua new file mode 100644 index 0000000..0b9737d --- /dev/null +++ b/sys/apps/system/network.lua @@ -0,0 +1,56 @@ +local Config = require('config') +local UI = require('ui') + +local device = _G.device + +local tab = UI.Window { + tabTitle = 'Network', + description = 'Networking options', + form = UI.Form { + x = 2, + manualControls = true, + modem = UI.Chooser { + formLabel = 'Modem', formKey = 'modem', + nochoice = 'auto', + }, + update = UI.Button { + x = 9, y = 4, + text = 'Update', event = 'form_complete', + }, + }, +} + +function tab:enable() + local width = 7 + local choices = { + { name = 'auto', value = 'auto' }, + { name = 'disable', value = 'none' }, + } + + for k,v in pairs(device) do + if v.isWireless and v.isWireless() and k ~= 'wireless_modem' then + table.insert(choices, { name = k, value = v.name }) + width = math.max(width, #k) + end + end + + self.form.modem.choices = choices + self.form.modem.width = width + 4 + + local config = Config.load('os') + self.form.modem.value = config.wirelessModem or 'auto' + + UI.Window.enable(self) +end + +function tab:eventHandler(event) + if event.type == 'form_complete' then + local config = Config.load('os') + config.wirelessModem = self.form.modem.value + Config.update('os', config) + self:emit({ type = 'success_message', message = 'reboot to take effect' }) + return true + end +end + +return tab diff --git a/sys/apps/system/password.lua b/sys/apps/system/password.lua new file mode 100644 index 0000000..23524fd --- /dev/null +++ b/sys/apps/system/password.lua @@ -0,0 +1,53 @@ +local Security = require('security') +local SHA1 = require('sha1') +local UI = require('ui') + +local passwordTab = UI.Window { + tabTitle = 'Password', + description = 'Wireless network password', + oldPass = UI.TextEntry { + x = 2, y = 2, ex = -2, + limit = 32, + mask = true, + shadowText = 'old password', + inactive = not Security.getPassword(), + }, + newPass = UI.TextEntry { + y = 3, x = 2, ex = -2, + limit = 32, + mask = true, + shadowText = 'new password', + accelerators = { + enter = 'new_password', + }, + }, + button = UI.Button { + x = 2, y = 5, + text = 'Update', + event = 'update_password', + }, + info = UI.TextArea { + x = 2, ex = -2, + y = 7, + inactive = true, + value = 'Add a password to enable other computers to connect to this one.', + } +} +function passwordTab:eventHandler(event) + if event.type == 'update_password' then + if #self.newPass.value == 0 then + self:emit({ type = 'error_message', message = 'Invalid password' }) + + elseif Security.getPassword() and not Security.verifyPassword(SHA1.sha1(self.oldPass.value)) then + self:emit({ type = 'error_message', message = 'Passwords do not match' }) + + else + Security.updatePassword(SHA1.sha1(self.newPass.value)) + self.oldPass.inactive = false + self:emit({ type = 'success_message', message = 'Password updated' }) + end + return true + end +end + +return passwordTab diff --git a/sys/apps/system/path.lua b/sys/apps/system/path.lua new file mode 100644 index 0000000..d55211a --- /dev/null +++ b/sys/apps/system/path.lua @@ -0,0 +1,50 @@ +local Config = require('config') +local UI = require('ui') +local Util = require('util') + +local shell = _ENV.shell + +local pathTab = UI.Window { + tabTitle = 'Path', + description = 'Set the shell path', + tabClose = true, + entry = UI.TextEntry { + x = 2, y = 2, ex = -2, + limit = 256, + value = shell.path(), + shadowText = 'enter system path', + accelerators = { + enter = 'update_path', + }, + }, + grid = UI.Grid { + y = 4, + disableHeader = true, + columns = { { key = 'value' } }, + autospace = true, + }, +} + +function pathTab.grid:draw() + self.values = { } + local env = Config.load('shell') + for _,v in ipairs(Util.split(env.path, '(.-):')) do + table.insert(self.values, { value = v }) + end + self:update() + UI.Grid.draw(self) +end + +function pathTab:eventHandler(event) + if event.type == 'update_path' then + local env = Config.load('shell') + env.path = self.entry.value + self.grid:setIndex(self.grid:getIndex()) + self.grid:draw() + Config.update('shell', env) + self:emit({ type = 'success_message', message = 'reboot to take effect' }) + return true + end +end + +return pathTab diff --git a/sys/apps/system/settings.lua b/sys/apps/system/settings.lua new file mode 100644 index 0000000..2722dab --- /dev/null +++ b/sys/apps/system/settings.lua @@ -0,0 +1,47 @@ +local UI = require('ui') + +local settings = _G.settings + +if settings then + + local values = { } + for _,v in pairs(settings.getNames()) do + local value = settings.get(v) + if not value then + value = false + end + table.insert(values, { + name = v, + value = value, + }) + end + + local settingsTab = UI.Window { + tabTitle = 'Settings', + description = 'Computercraft configurable settings', + grid = UI.Grid { + y = 1, + values = values, + autospace = true, + sortColumn = 'name', + columns = { + { heading = 'Setting', key = 'name' }, + { heading = 'Value', key = 'value' }, + }, + }, + } + + function settingsTab:eventHandler(event) + if event.type == 'grid_select' then + if not event.selected.value or type(event.selected.value) == 'boolean' then + event.selected.value = not event.selected.value + end + settings.set(event.selected.name, event.selected.value) + settings.save('.settings') + self.grid:draw() + return true + end + end + + return settingsTab +end diff --git a/sys/apps/system/turtle.lua b/sys/apps/system/turtle.lua new file mode 100644 index 0000000..18150de --- /dev/null +++ b/sys/apps/system/turtle.lua @@ -0,0 +1,62 @@ +local Config = require('config') +local UI = require('ui') + +local fs = _G.fs +local turtle = _G.turtle + +if turtle then + local Home = require('turtle.home') + local values = { } + Config.load('gps', values.home and { values.home } or { }) + + local gpsTab = UI.Window { + tabTitle = 'GPS', + labelText = UI.Text { + x = 3, y = 2, + value = 'On restart, return to this location' + }, + grid = UI.Grid { + x = 3, ex = -3, y = 4, + height = 2, + values = values, + inactive = true, + columns = { + { heading = 'x', key = 'x' }, + { heading = 'y', key = 'y' }, + { heading = 'z', key = 'z' }, + }, + }, + button1 = UI.Button { + x = 3, y = 7, + text = 'Set home', + event = 'gps_set', + }, + button2 = UI.Button { + ex = -3, y = 7, width = 7, + text = 'Clear', + event = 'gps_clear', + }, + } + function gpsTab:eventHandler(event) + if event.type == 'gps_set' then + self:emit({ type = 'info_message', message = 'Determining location' }) + self:sync() + if Home.set() then + Config.load('gps', values) + self.grid:setValues(values.home and { values.home } or { }) + self.grid:draw() + self:emit({ type = 'success_message', message = 'Location set' }) + else + self:emit({ type = 'error_message', message = 'Unable to determine location' }) + end + return true + elseif event.type == 'gps_clear' then + fs.delete('usr/config/gps') + self.grid:setValues({ }) + self.grid:draw() + return true + end + end + + return gpsTab +end diff --git a/sys/extensions/5.network.lua b/sys/extensions/5.network.lua index 3963ae2..417126e 100644 --- a/sys/extensions/5.network.lua +++ b/sys/extensions/5.network.lua @@ -18,8 +18,12 @@ end local function setModem(dev) if not device.wireless_modem and dev.isWireless() then - local config = Config.load('os', { }) - if not config.wirelessModem or dev.name == config.wirelessModem then + local config = Config.load('os') + + if not config.wirelessModem or + config.wirelessModem == 'auto' or + dev.name == config.wirelessModem then + device.wireless_modem = dev os.queueEvent('device_attach', 'wireless_modem') return dev diff --git a/sys/extensions/6.packages.lua b/sys/extensions/6.packages.lua index cc68ddd..876e2d6 100644 --- a/sys/extensions/6.packages.lua +++ b/sys/extensions/6.packages.lua @@ -3,8 +3,9 @@ _G.requireInjector(_ENV) local Packages = require('packages') local Util = require('util') +local fs = _G.fs +local help = _G.help local shell = _ENV.shell -local fs = _G.fs local appPaths = Util.split(shell.path(), '(.-);') local luaPaths = Util.split(_G.LUA_PATH, '(.-);') @@ -26,6 +27,9 @@ end -- dependency graph -- https://github.com/mpeterv/depgraph/blob/master/src/depgraph/init.lua +local helpPaths = Util.split(help.path(), '(.-):') +table.insert(helpPaths, '/sys/help') + for name in pairs(Packages:installed()) do local packageDir = fs.combine('packages', name) if fs.exists(fs.combine(packageDir, '.install')) then @@ -40,7 +44,14 @@ for name in pairs(Packages:installed()) do if fs.exists(apiPath) then addPath(luaPaths, apiPath) end + + local helpPath = fs.combine(fs.combine('packages', name), 'help') + if fs.exists(helpPath) then + table.insert(helpPaths, helpPath) + end end +help.setPath(table.concat(helpPaths, ':')) + shell.setPath(table.concat(appPaths, ':')) _G.LUA_PATH = table.concat(luaPaths, ';') diff --git a/sys/help/Opus Applications b/sys/help/Opus Applications new file mode 100644 index 0000000..a7747a3 --- /dev/null +++ b/sys/help/Opus Applications @@ -0,0 +1,30 @@ +Opus applications are grouped into packages with a common theme. + +To install a package, use either the System -> Packages program or the package command line program. + +Shell usage: + +> package list +> package install <name> +> package update <name> +> package uninstall <name> + +Package definitions are located in usr/apps/packages. This file can be modified to add custom packages. + +Current stable packages +======================= + +* core +Programming and miscellaneous applications. Also contains drivers needed for other packages. + +* builder +A program for creating structures from schematic files using a turtle (requires core). + +* farms +Various programs for farming resources (wood, crops, animals). + +* milo +An A/E like storage implementation (requires core). + +* miners +Mining programs. diff --git a/sys/help/Wireless Networking b/sys/help/Wireless Networking new file mode 100644 index 0000000..9411058 --- /dev/null +++ b/sys/help/Wireless Networking @@ -0,0 +1,7 @@ +To establish one-way trust between two computers with modems, run the following in a shell prompt: + +On the target computer, run: +> password + +On the source computer, run: +> trust <target computer ID>