mirror of
https://github.com/kepler155c/opus
synced 2024-12-24 15:40:26 +00:00
custom help files + redo System UI
This commit is contained in:
parent
3de03bef22
commit
26564cbcc1
@ -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')
|
||||
|
42
sys/apis/turtle/home.lua
Normal file
42
sys/apis/turtle/home.lua
Normal file
@ -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
|
@ -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
|
||||
|
@ -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()
|
||||
|
66
sys/apps/system/aliases.lua
Normal file
66
sys/apps/system/aliases.lua
Normal file
@ -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
|
49
sys/apps/system/label.lua
Normal file
49
sys/apps/system/label.lua
Normal file
@ -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
|
56
sys/apps/system/network.lua
Normal file
56
sys/apps/system/network.lua
Normal file
@ -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
|
53
sys/apps/system/password.lua
Normal file
53
sys/apps/system/password.lua
Normal file
@ -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
|
50
sys/apps/system/path.lua
Normal file
50
sys/apps/system/path.lua
Normal file
@ -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
|
47
sys/apps/system/settings.lua
Normal file
47
sys/apps/system/settings.lua
Normal file
@ -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
|
62
sys/apps/system/turtle.lua
Normal file
62
sys/apps/system/turtle.lua
Normal file
@ -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
|
@ -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
|
||||
|
@ -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, ';')
|
||||
|
30
sys/help/Opus Applications
Normal file
30
sys/help/Opus Applications
Normal file
@ -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.
|
7
sys/help/Wireless Networking
Normal file
7
sys/help/Wireless Networking
Normal file
@ -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>
|
Loading…
Reference in New Issue
Block a user