From ecb3af467230ede2916d865b6fda81233f3914a4 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sun, 14 Oct 2018 15:35:40 -0400 Subject: [PATCH 01/50] new icon set + scanning miner --- sys/apis/point.lua | 21 ++++++++++++++------- sys/apps/Overview.lua | 29 ++++++++++++++++++++--------- sys/etc/app.db | 26 +++++++++++++++++++++++++- sys/extensions/6.tl3.lua | 32 +++++++++++++++++++++++++------- 4 files changed, 84 insertions(+), 24 deletions(-) diff --git a/sys/apis/point.lua b/sys/apis/point.lua index 1bd68ba..9eca46d 100644 --- a/sys/apis/point.lua +++ b/sys/apis/point.lua @@ -144,14 +144,21 @@ function Point.calculateMoves(pta, ptb, distance) end end - if ptb.heading then - if heading ~= ptb.heading then - moves = moves + Point.calculateTurns(heading, ptb.heading) - heading = ptb.heading - end + if not ptb.heading then + return moves, heading, moves end - return moves, heading + -- calc turns as slightly less than moves + local weighted = moves + if heading ~= ptb.heading then + local turns = Point.calculateTurns(heading, ptb.heading) + moves = moves + turns + local wturns = { [0] = 0, [1] = .9, [2] = 1.9 } + weighted = weighted + wturns[turns] + heading = ptb.heading + end + + return moves, heading, weighted end -- given a set of points, find the one taking the least moves @@ -164,7 +171,7 @@ function Point.closest(reference, pts) for _,pt in pairs(pts) do local distance = Point.turtleDistance(reference, pt) if distance < lm then - local m = Point.calculateMoves(reference, pt, distance) + local _, _, m = Point.calculateMoves(reference, pt, distance) if m < lm then lpt = pt lm = m diff --git a/sys/apps/Overview.lua b/sys/apps/Overview.lua index 1d1961d..0b95299 100644 --- a/sys/apps/Overview.lua +++ b/sys/apps/Overview.lua @@ -32,9 +32,9 @@ local config = { Config.load('Overview', config) local applications = { } +local extSupport = Util.getVersion() >= 1.76 local function loadApplications() - local requirements = { turtle = function() return turtle end, advancedTurtle = function() return turtle and term.isColor() end, @@ -117,7 +117,7 @@ local function parseIcon(iconText) icon = NFT.parse(iconText) if icon then if icon.height > 3 or icon.width > 8 then - error('Invalid size') + error('Must be an NFT image - 3 rows, 8 cols max') end end return icon @@ -174,6 +174,10 @@ local page = UI.Page { }, } +if extSupport then + page.container.backgroundColor = colors.black +end + UI.Icon = class(UI.Window) UI.Icon.defaults = { UIElement = 'Icon', @@ -194,7 +198,6 @@ function UI.Icon:eventHandler(event) end function page.container:setCategory(categoryName, animate) - -- reset the viewport window self.children = { } self.offy = 0 @@ -231,7 +234,10 @@ function page.container:setCategory(categoryName, animate) for _,program in ipairs(filtered) do local icon - if program.icon then + if extSupport and program.iconExt then + icon = parseIcon(program.iconExt) + end + if not icon and program.icon then icon = parseIcon(program.icon) end if not icon then @@ -344,7 +350,6 @@ function page:resize() end function page:eventHandler(event) - if event.type == 'tab_select' then self.container:setCategory(event.button.text, true) self.container:draw() @@ -455,7 +460,10 @@ function editor:enable(app) self.form:setValues(app) local icon - if app.icon then + if extSupport and app.iconExt then + icon = parseIcon(app.iconExt) + end + if not icon and app.icon then icon = parseIcon(app.icon) end self.form.image:setImage(icon) @@ -479,7 +487,6 @@ function editor:updateApplications(app) end function editor:eventHandler(event) - if event.type == 'form_cancel' or event.type == 'cancel' then UI:setPreviousPage() @@ -501,13 +508,17 @@ function editor:eventHandler(event) local s, m = pcall(function() local iconLines = Util.readFile(fileName) if not iconLines then - error('Unable to load file') + error('Must be an NFT image - 3 rows, 8 cols max') end local icon, m = parseIcon(iconLines) if not icon then error(m) end - self.form.values.icon = iconLines + if extSupport then + self.form.values.iconExt = iconLines + else + self.form.values.icon = iconLines + end self.form.image:setImage(icon) self.form.image:draw() end) diff --git a/sys/etc/app.db b/sys/etc/app.db index 2990a65..fffc917 100644 --- a/sys/etc/app.db +++ b/sys/etc/app.db @@ -1,10 +1,13 @@ { [ "53ebc572b4a44802ba114729f07bdaaf5409a9d7" ] = { + title = "Network", category = "Apps", icon = "\0304 \030 \ \030f \0304 \0307 \030 \031 \031f)\ \030f \0304 \0307 \030 \031f)", - title = "Network", + iconExt = "\030 \031f \0305\031f\140\030f\0315\137\144\ +\030 \031f\030f\0314\131\131\0304\031f\148\030 \0305\155\150\149\ +\030 \031f\030f\0310\147\0300\031f\141\0304\149\0307\0318\149\030 ", run = "Network.lua", }, c7116629a6a855cb774d9c7c8ad822fd83c71fb5 = { @@ -21,6 +24,9 @@ icon = "\0301\03171\03180\030 \031 \ \0301\03181\030 \031 \ \0301\03170\03180\03171\0307\031f>", + iconExt = "\031f\128\0315\152\131\131\132\031f\128\ +\0315\139\159\129\0305\031f\159\129\139\ +\031f\128\0315\136\0305\031f\143\143\030f\0315\134\031f\128", run = "http://pastebin.com/raw/UzGHLbNC", }, c47ae15370cfe1ed2781eedc1dc2547d12d9e972 = { @@ -29,6 +35,9 @@ icon = " \031f?\031 \ \031f?\031 \ \031f?", + iconExt = "\0300\031f\129\030f\0310\131\0300\031f\148\030f\0310\148\ +\030 \031 \0300\031f\131\030f\0310\142\129\ +\030 \031 \0300\031f\131\030f\128", run = "Help.lua", }, b0832074630eb731d7fbe8074de48a90cd9bb220 = { @@ -53,6 +62,9 @@ icon = " \0307\031f| \ \0307\031f---o\030 \031 \ \0307\031f| ", + iconExt = "\0318\138\0308\031f\130\0318\128\031f\129\030f\0318\133\ +\0318\143\0308\128\0317\143\0318\128\030f\143\ +\0318\138\135\143\139\133", run = "System.lua", }, c5497bca58468ae64aed6c0fd921109217988db3 = { @@ -69,6 +81,9 @@ icon = "\030f\031f \0315/\ \030f\031f \0315/\\/ \ \030f\0315/\031f ", + iconExt = "\031f\128\128\0305\159\030f\128\0305\159\030f\0315\134\031f\128\ +\031f\128\0315\152\129\137\0305\031f\158\139\030f\0315\144\ +\0315\134\031f\128\128\128\128\0305\154\030f\0315\144", run = "Tasks.lua", }, [ "6ce6c512ea433a7fc5c8841628e7696cd0ff7f2b" ] = { @@ -77,6 +92,9 @@ icon = "\0300\0317==\031 \0307 \ \0300\0317====\ \0300\0317====", + iconExt = "\030 \031f\0300\031f\136\140\132\0308\130\030f\0318\144\ +\030 \031f\030f\0310\157\0300\031f\147\030f\0310\142\143\149\ +\030 \031f\0300\031f\136\140\132\140\030f\0310\149", run = "Files.lua", }, [ "7fddb7d8d1d60b1eeefa9af01082e0811d4b484d" ] = { @@ -127,6 +145,9 @@ icon = "\030d \030 \030e \030 \ \030d \030 \ \030d ", + iconExt = "\030 \031f\0305\031f\151\030f\0315\135\131\0305\031f\146\ +\030 \031f\030f\0315\130\141\0305\031f\139\030f\0315\130\ +\030 \031f\0305\031f\146\143\030f\0315\158\031e\130", run = "/rom/programs/fun/worm", }, [ "9f46ca3ef617166776ef6014a58d4e66859caa62" ] = { @@ -135,6 +156,9 @@ icon = " \030f \ \030f \0307 \ \030f \0307 \0300 ", + iconExt = "\031f\128\0307\143\131\131\131\131\143\030f\128\ +\0307\031f\129\0317\128\0319\136\0309\031b\136\132\0307\0319\132\0317\128\031f\130\ +\0317\130\143\0307\128\128\128\128\030f\143\129", run = "/rom/programs/fun/dj", }, } diff --git a/sys/extensions/6.tl3.lua b/sys/extensions/6.tl3.lua index fab4b90..5c41c49 100644 --- a/sys/extensions/6.tl3.lua +++ b/sys/extensions/6.tl3.lua @@ -662,11 +662,11 @@ function turtle._goto(pt) local dx, dy, dz, dh = pt.x, pt.y, pt.z, pt.heading if not turtle.gotoSingleTurn(dx, dy, dz, dh) then if not gotoMultiTurn(dx, dy, dz) then - return false + return false, 'Failed to reach location' end end turtle.setHeading(dh) - return true + return pt end -- avoid lint errors @@ -738,6 +738,8 @@ function turtle.getSlot(indexOrId, slots) } end + -- inconsistent return value + -- null is returned if indexOrId is a string and no item is present return { qty = 0, -- deprecate count = 0, @@ -794,8 +796,12 @@ function turtle.getSummedInventory() end function turtle.has(item, count) - local slot = turtle.getSummedInventory()[item] - return slot and slot.count >= (count or 1) + if item:match('.*:%d') then + local slot = turtle.getSummedInventory()[item] + return slot and slot.count >= (count or 1) + end + local slot = turtle.getSlot(item) + return slot and slot.count > 0 end function turtle.getFilledSlots(startSlot) @@ -966,6 +972,18 @@ function turtle.addWorldBlock(pt) Pathing.addBlock(pt) end +local movementStrategy = turtle.pathfind + +function turtle.setMovementStrategy(strategy) + if strategy == 'pathing' then + movementStrategy = turtle.pathfind + elseif strategy == 'goto' then + movementStrategy = turtle._goto + else + error('Invalid movement strategy') + end +end + function turtle.faceAgainst(pt, options) -- 4 sided options = options or { } options.dest = { } @@ -980,7 +998,7 @@ function turtle.faceAgainst(pt, options) -- 4 sided }) end - return turtle.pathfind(Point.closest(turtle.point, options.dest), options) + return movementStrategy(Point.closest(turtle.point, options.dest), options) end -- move against this point @@ -1012,7 +1030,7 @@ function turtle.moveAgainst(pt, options) -- 6 sided }) end - return turtle.pathfind(Point.closest(turtle.point, options.dest), options) + return movementStrategy(Point.closest(turtle.point, options.dest), options) end local actionsAt = { @@ -1097,7 +1115,7 @@ local function _actionAt(action, pt, ...) direction = 'up' end - if turtle.pathfind(apt) then + if movementStrategy(apt) then return action[direction](...) end end From 8b50127f21dfbda6e998cf0093c3d4abd486ae83 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Mon, 15 Oct 2018 16:05:43 -0400 Subject: [PATCH 02/50] new icon set + scanning miner --- sys/apis/event.lua | 23 ++++++++++++++++++++--- sys/apis/util.lua | 1 - sys/apps/telnet.lua | 8 ++++---- sys/etc/app.db | 30 ++++++++++++++++++++++++------ sys/extensions/6.tl3.lua | 1 + 5 files changed, 49 insertions(+), 14 deletions(-) diff --git a/sys/apis/event.lua b/sys/apis/event.lua index fda4946..ad0715f 100644 --- a/sys/apis/event.lua +++ b/sys/apis/event.lua @@ -136,6 +136,18 @@ function Event.waitForEvent(event, timeout) until e[1] == 'timer' and e[2] == timerId end +-- Set a handler for the terminate event. Within the function, return +-- true or false to indicate whether the event should be propagated to +-- all sub-threads +function Event.onTerminate(fn) + Event.termFn = fn +end + +function Event.termFn() + Event.terminate = true + return true -- propagate +end + function Event.addRoutine(fn) local r = setmetatable({ co = coroutine.create(fn), @@ -204,11 +216,16 @@ end function Event.pullEvent(eventType) while true do local e = { os.pullEventRaw() } + local propagate = true -- don't like this... - Event.terminate = Event.terminate or e[1] == 'terminate' + if e[1] == 'terminate' then + propagate = Event.termFn() + end - processHandlers(e[1]) - processRoutines(table.unpack(e)) + if propagate then + processHandlers(e[1]) + processRoutines(table.unpack(e)) + end if Event.terminate then return { 'terminate' } diff --git a/sys/apis/util.lua b/sys/apis/util.lua index 29fd5e1..3529583 100644 --- a/sys/apis/util.lua +++ b/sys/apis/util.lua @@ -653,7 +653,6 @@ function Util.getOptions(options, args, ignoreInvalid) end end return true, Util.size(rawOptions) - end return Util diff --git a/sys/apps/telnet.lua b/sys/apps/telnet.lua index 0684f8f..25c6c05 100644 --- a/sys/apps/telnet.lua +++ b/sys/apps/telnet.lua @@ -10,7 +10,7 @@ local os = _G.os local read = _G.read local term = _G.term -local options, args = Util.args({ ... }) +local args = { ... } local remoteId = tonumber(table.remove(args, 1) or '') if not remoteId then @@ -19,11 +19,11 @@ if not remoteId then end if not remoteId then - error('Syntax: telnet [-title TITLE] ID [PROGRAM]') + error('Syntax: telnet ID [PROGRAM] [ARGS]') end -if options.title and multishell then - multishell.setTitle(multishell.getCurrent(), options.title) +if multishell then + multishell.setTitle(multishell.getCurrent(), 'Telnet ' .. remoteId) end local socket, msg = Socket.connect(remoteId, 23) diff --git a/sys/etc/app.db b/sys/etc/app.db index fffc917..68b9abc 100644 --- a/sys/etc/app.db +++ b/sys/etc/app.db @@ -16,6 +16,9 @@ icon = "\0304\031f \030f\0310o..\0304\031f \ \0304\031f \030f\0310.o.\0304\031f \ \0304\031f - ", + iconExt = "\0307\031f\135\0300\0317\159\0307\0310\144\031f\139\ +\0300\0317\131\0307\0310\147\0300\0317\156\131\ +\130\143\143\129", run = "rom/programs/reboot", }, fb91e24fa52d8d2b32937bf04d843f730319a902 = { @@ -24,9 +27,9 @@ icon = "\0301\03171\03180\030 \031 \ \0301\03181\030 \031 \ \0301\03170\03180\03171\0307\031f>", - iconExt = "\031f\128\0315\152\131\131\132\031f\128\ -\0315\139\159\129\0305\031f\159\129\139\ -\031f\128\0315\136\0305\031f\143\143\030f\0315\134\031f\128", + iconExt = "\031f\128\0313\152\131\131\132\031f\128\ +\0313\139\159\129\0303\031f\159\129\139\ +\031f\128\0313\136\0303\031f\143\143\030f\0313\134\031f\128", run = "http://pastebin.com/raw/UzGHLbNC", }, c47ae15370cfe1ed2781eedc1dc2547d12d9e972 = { @@ -46,6 +49,9 @@ icon = "\030f \ \030f\0310lua>\031 \ \030f ", + iconExt = "\0300\031f\151\030f\128\0300\159\159\159\030f\0310\144\0304\031f\159\030f\128\ +\0300\031f\149\030f\128\0300\149\149\151\145\030f\128\0314\153\ +\130\131\130\131\130\131\0314\130\031f\128", run = "sys/apps/Lua.lua", }, df485c871329671f46570634d63216761441bcd6 = { @@ -54,6 +60,9 @@ icon = "\0304 \030 \ \030f \0304 \0307 \030 \031 \031f_\ \030f \0304 \0307 \030 \031f/", + iconExt = "\031f\128\128\128\0308\159\143\0300\0317\151\0307\0310\140\148\ +\0314\151\131\0304\031f\148\030f\0318\138\148\0307\0310\138\131\129\ +\0304\031f\138\143\133\030f\0318\131\129\031f\128\128\128", run = "Devices.lua", }, bc0792d8dc81e8aa30b987246a5ce97c40cd6833 = { @@ -73,6 +82,9 @@ icon = "\0304\031f \030 \0311e\ \030f\031f \0304 \030 \0311ee\031f \ \030f\031f \0304 \030 \0311e\031f ", + iconExt = "\0300\031f\159\135\030f\0310\156\0301\031f\159\030f\0311\144\0300\031f\147\139\030f\0310\144\ +\0300\128\128\030f\149\0311\157\142\0300\031f\149\0310\128\128\ +\130\139\141\0311\130\131\0310\142\135\129", run = "Events.lua", }, [ "2a4d562b1d9a9c90bdede6fac8ce4f7402462b86" ] = { @@ -82,8 +94,8 @@ \030f\031f \0315/\\/ \ \030f\0315/\031f ", iconExt = "\031f\128\128\0305\159\030f\128\0305\159\030f\0315\134\031f\128\ -\031f\128\0315\152\129\137\0305\031f\158\139\030f\0315\144\ -\0315\134\031f\128\128\128\128\0305\154\030f\0315\144", +\031f\128\0315\152\129\137\0305\031f\158\139\030f\0317 \ +\0315\134\031f\128\128\128\128\0305\154\030f\0317 ", run = "Tasks.lua", }, [ "6ce6c512ea433a7fc5c8841628e7696cd0ff7f2b" ] = { @@ -103,12 +115,18 @@ icon = "\0304\031f \ \0304\031f \030f\0310zz\031 \ \0304\031f \030f ", + iconExt = "\030e\031f\135\030f\031e\148\030e\128\031f\151\139\ +\030e\031e\128\030f\031f\128\031e\143\031f\128\030e\031e\128\ +\031e\139\030e\031f\130\131\129\030f\031e\135", run = "/rom/programs/shutdown", }, bdc1fd5d3c0f3dcfd55d010426e61bf9451e680d = { title = "Shell", category = "Apps", - icon = "\030f\0314\151\131\131\131\131\ + icon = "\0304 \030 \ +\0304 \030f\0314> \0310_\031 \ +\0304 \030f \030 ", + iconExt = "\030f\0314\151\131\131\131\131\ \030f\0314\149\030f\0314> \0310_ \ \030f\0314\149\030f ", run = "shell", diff --git a/sys/extensions/6.tl3.lua b/sys/extensions/6.tl3.lua index 5c41c49..3985dcf 100644 --- a/sys/extensions/6.tl3.lua +++ b/sys/extensions/6.tl3.lua @@ -458,6 +458,7 @@ function turtle.back() end local function moveTowardsX(dx) + if not tonumber(dx) then error('moveTowardsX: Invalid arguments') end local direction = dx - turtle.point.x local move From b7176e55adf369f62b02e73e303b53e401399eca Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sat, 20 Oct 2018 20:35:48 -0400 Subject: [PATCH 03/50] package manager wip --- sys/apis/packages.lua | 32 +++++++++++++++++++++++++++++ sys/apps/Packages.lua | 13 ++++++++++++ sys/extensions/6.packages.lua | 38 +++++++++++++++++++++++++++++++++++ sys/packageList.lua | 4 ++++ 4 files changed, 87 insertions(+) create mode 100644 sys/apis/packages.lua create mode 100644 sys/apps/Packages.lua create mode 100644 sys/extensions/6.packages.lua create mode 100644 sys/packageList.lua diff --git a/sys/apis/packages.lua b/sys/apis/packages.lua new file mode 100644 index 0000000..c3b4473 --- /dev/null +++ b/sys/apis/packages.lua @@ -0,0 +1,32 @@ +_G.requireInjector(_ENV) + +local Util = require('util') + +local fs = _G.fs + +local PACKAGE_DIR = 'packages' + +local Packages = { } + +function Packages:installed() + self.cache = { } + + if fs.exists(PACKAGE_DIR) then + for _, dir in pairs(fs.list(PACKAGE_DIR)) do + local path = fs.combine(fs.combine(PACKAGE_DIR, dir), '.package') + self.cache[dir] = Util.readTable(path) + end + end + + return self.cache +end + +function Packages:list() + return Util.readTable('sys/packageList.lua') or { } +end + +function Packages:isInstalled(package) + return self:installed()[package] +end + +return Packages diff --git a/sys/apps/Packages.lua b/sys/apps/Packages.lua new file mode 100644 index 0000000..14e5c5b --- /dev/null +++ b/sys/apps/Packages.lua @@ -0,0 +1,13 @@ +_G.requireInjector(_ENV) + +local Packages = require('packages') +local Util = require('util') + +local args = { ... } + +if args[1] == 'list' then + for k,v in pairs(Packages:list()) do + Util.print('[%s] %s', Packages:isInstalled(k) and 'x' or ' ', k) + end +end + diff --git a/sys/extensions/6.packages.lua b/sys/extensions/6.packages.lua new file mode 100644 index 0000000..09fcaff --- /dev/null +++ b/sys/extensions/6.packages.lua @@ -0,0 +1,38 @@ +_G.requireInjector(_ENV) + +local Packages = require('packages') +local Util = require('util') + +local shell = _ENV.shell +local fs = _G.fs + +local appPaths = Util.split(shell.path(), '(.-):') +local luaPaths = Util.split(_G.LUA_PATH, '(.-):') + +local function addPath(t, e) + local function hasEntry() + for _,v in ipairs(t) do + if v == e then + return true + end + end + end + if not hasEntry() then + table.insert(t, 1, e) + end +end + +-- dependency graph +-- https://github.com/mpeterv/depgraph/blob/master/src/depgraph/init.lua + +for name, package in pairs(Packages:installed()) do + if package.mount then + fs.mount(table.unpack(Util.matches(package.mount))) + end + + addPath(appPaths, fs.combine(fs.combine('packages', name), 'apps')) + addPath(luaPaths, fs.combine(fs.combine('packages', name), 'apis')) +end + +shell.setPath(table.concat(appPaths, ':')) +_G.LUA_PATH = table.concat(luaPaths, ':') diff --git a/sys/packageList.lua b/sys/packageList.lua new file mode 100644 index 0000000..622f2c1 --- /dev/null +++ b/sys/packageList.lua @@ -0,0 +1,4 @@ +{ + [ 'opus-neural' ] = 'file://packages/opus-neural/.package', + [ 'opus-miners' ] = 'file://packages/opus-miners/.package', +} \ No newline at end of file From 97c4b7a090e3068d59566e44054e6019ab8c1e71 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sun, 21 Oct 2018 04:46:40 -0400 Subject: [PATCH 04/50] package manager wip --- sys/apis/config.lua | 5 ++++- sys/extensions/6.packages.lua | 7 +++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/sys/apis/config.lua b/sys/apis/config.lua index 52ce0c0..20f4e86 100644 --- a/sys/apis/config.lua +++ b/sys/apis/config.lua @@ -15,7 +15,10 @@ function Config.load(fname, data) if not fs.exists(filename) then Util.writeTable(filename, data) else - Util.merge(data, Util.readTable(filename) or { }) + local contents = Util.readTable(filename) or + error('Configuration file is corrupt:' .. filename) + + Util.merge(data, contents) end end diff --git a/sys/extensions/6.packages.lua b/sys/extensions/6.packages.lua index 09fcaff..3f46c7e 100644 --- a/sys/extensions/6.packages.lua +++ b/sys/extensions/6.packages.lua @@ -30,8 +30,11 @@ for name, package in pairs(Packages:installed()) do fs.mount(table.unpack(Util.matches(package.mount))) end - addPath(appPaths, fs.combine(fs.combine('packages', name), 'apps')) - addPath(luaPaths, fs.combine(fs.combine('packages', name), 'apis')) + addPath(appPaths, fs.combine('packages', name)) + local apiPath = fs.combine(fs.combine('packages', name), 'apis') + if fs.exists(apiPath) then + addPath(luaPaths, apiPath) + end end shell.setPath(table.concat(appPaths, ':')) From 0cd709a525530a1da7946bda95a7822ff887aecd Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sun, 21 Oct 2018 18:48:08 -0400 Subject: [PATCH 05/50] missing pages definition --- sys/apis/ui.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/apis/ui.lua b/sys/apis/ui.lua index d49501f..f17d05d 100644 --- a/sys/apis/ui.lua +++ b/sys/apis/ui.lua @@ -306,6 +306,9 @@ function Manager:setDefaultDevice(dev) end function Manager:addPage(name, page) + if not self.pages then + self.pages = { } + end self.pages[name] = page end From a59fef30f09d40b1cb832ab494e65c52349e29f2 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Tue, 23 Oct 2018 03:05:47 -0400 Subject: [PATCH 06/50] ui improvements + wireless modem over wired network --- sys/apis/peripheral.lua | 8 ++- sys/apis/ui.lua | 108 +++++++++++++++++++++++++++++----------- 2 files changed, 87 insertions(+), 29 deletions(-) diff --git a/sys/apis/peripheral.lua b/sys/apis/peripheral.lua index 0d527fb..077e959 100644 --- a/sys/apis/peripheral.lua +++ b/sys/apis/peripheral.lua @@ -55,7 +55,13 @@ function Peripheral.addDevice(deviceList, side) end -- this can randomly fail - pcall(function() deviceList[name] = Peripheral.wrap(side) end) + pcall(function() + deviceList[name] = Peripheral.wrap(side) + if ptype == 'wireless_modem' and not deviceList.wireless_modem then + -- TODO: fix this + deviceList.wireless_modem = deviceList[name] + end + end) if deviceList[name] then Util.merge(deviceList[name], { diff --git a/sys/apis/ui.lua b/sys/apis/ui.lua index f17d05d..19e34fa 100644 --- a/sys/apis/ui.lua +++ b/sys/apis/ui.lua @@ -1058,6 +1058,17 @@ function UI.StringBuffer:insert(s, width) end end +function UI.StringBuffer:insertRight(s, width) + local len = #tostring(s or '') + if len > width then + s = _sub(s, 1, width) + end + if len < width then + table.insert(self.buffer, _rep(' ', width - len)) + end + table.insert(self.buffer, s) +end + function UI.StringBuffer:get(sep) return Util.widthify(table.concat(self.buffer, sep or ''), self.bufSize) end @@ -1511,7 +1522,11 @@ function UI.Grid:drawRows() end for _,col in pairs(self.columns) do - sb:insert(ind .. safeValue(row[col.key] or ''), col.cw + 1) + if col.justify == 'right' then + sb:insertRight(ind .. safeValue(row[col.key] or ''), col.cw + 1) + else + sb:insert(ind .. safeValue(row[col.key] or ''), col.cw + 1) + end ind = ' ' end @@ -2327,18 +2342,32 @@ function UI.Wizard:prevView() end end +function UI.Wizard:isViewValid() + local currentView = Util.find(self.pages, 'enabled', true) + return not currentView.validate and true or currentView:validate() +end + function UI.Wizard:eventHandler(event) if event.type == 'nextView' then local currentView = Util.find(self.pages, 'enabled', true) local nextView = Util.find(self.pages, 'index', currentView.index + 1) - currentView:emit({ type = 'enable_view', next = nextView, current = currentView }) + if self:isViewValid() then + currentView:emit({ type = 'enable_view', next = nextView, current = currentView }) + end elseif event.type == 'previousView' then local currentView = Util.find(self.pages, 'enabled', true) local nextView = Util.find(self.pages, 'index', currentView.index - 1) - currentView:emit({ type = 'enable_view', prev = nextView, current = currentView }) + if self:isViewValid() then + currentView:emit({ type = 'enable_view', prev = nextView, current = currentView }) + end return true + elseif event.type == 'wizard_complete' then + if self:isViewValid() then + self:emit({ type = 'accept' }) + end + elseif event.type == 'enable_view' then if event.current then if event.next then @@ -2350,6 +2379,8 @@ function UI.Wizard:eventHandler(event) end local current = event.next or event.prev + if not current then error('property "index" is required on wizard pages') end + if Util.find(self.pages, 'index', current.index - 1) then self.previousButton:enable() else @@ -2361,7 +2392,7 @@ function UI.Wizard:eventHandler(event) self.nextButton.event = 'nextView' else self.nextButton.text = 'Accept' - self.nextButton.event = 'accept' + self.nextButton.event = 'wizard_complete' end -- a new current view current:enable() @@ -3183,16 +3214,18 @@ function UI.Form:createForm() end end - table.insert(self.children, UI.Button { - y = -self.margin, x = -12 - self.margin, - text = 'Ok', - event = 'form_ok', - }) - table.insert(self.children, UI.Button { - y = -self.margin, x = -7 - self.margin, - text = 'Cancel', - event = 'form_cancel', - }) + if not self.manualControls then + table.insert(self.children, UI.Button { + y = -self.margin, x = -12 - self.margin, + text = 'Ok', + event = 'form_ok', + }) + table.insert(self.children, UI.Button { + y = -self.margin, x = -7 - self.margin, + text = 'Cancel', + event = 'form_cancel', + }) + end end function UI.Form:validateField(field) @@ -3201,25 +3234,44 @@ function UI.Form:validateField(field) return false, 'Field is required' end end + if field.validate == 'numeric' then + if #tostring(field.value) > 0 then + if not tonumber(field.value) then + return false, 'Invalid number' + end + end + end + return true +end + +function UI.Form:save() + for _,child in pairs(self.children) do + if child.formKey then + local s, m = self:validateField(child) + if not s then + self:setFocus(child) + self:emit({ type = 'form_invalid', message = m, field = child }) + return false + end + end + end + for _,child in pairs(self.children) do + if child.formKey then + if child.pruneEmpty and type(child.value) == 'string' and #child.value == 0 then + self.values[child.formKey] = nil + else + self.values[child.formKey] = child.value + end + end + end + return true end function UI.Form:eventHandler(event) if event.type == 'form_ok' then - for _,child in pairs(self.children) do - if child.formKey then - local s, m = self:validateField(child) - if not s then - self:setFocus(child) - self:emit({ type = 'form_invalid', message = m, field = child }) - return false - end - end - end - for _,child in pairs(self.children) do - if child.formKey then - self.values[child.formKey] = child.value - end + if not self:save() then + return false end self:emit({ type = self.event, UIElement = self }) else From adc5eb286dbcd3ec3dd5ef4f58207eef71f87957 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Tue, 23 Oct 2018 22:33:40 -0400 Subject: [PATCH 07/50] ui improvements --- sys/apis/ui.lua | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/sys/apis/ui.lua b/sys/apis/ui.lua index 19e34fa..9ef1efd 100644 --- a/sys/apis/ui.lua +++ b/sys/apis/ui.lua @@ -1232,7 +1232,8 @@ function UI.Page:setFocus(child) self.focused = child if not child.focused then child.focused = true - self:emit({ type = 'focus_change', focused = child }) + child:emit({ type = 'focus_change', focused = child }) + --self:emit({ type = 'focus_change', focused = child }) end child:focus() @@ -2304,13 +2305,13 @@ function UI.Wizard:add(pages) end end -function UI.Wizard:enable() +function UI.Wizard:enable(...) self.enabled = true for _,child in ipairs(self.children) do if not child.index then - child:enable() + child:enable(...) elseif child.index == 1 then - child:enable() + child:enable(...) else child:disable() end @@ -2415,12 +2416,12 @@ function UI.SlideOut:enable() self.enabled = false end -function UI.SlideOut:show() +function UI.SlideOut:show(...) self:addTransition('expandUp') self.canvas:setVisible(true) self.enabled = true for _,child in pairs(self.children) do - child:enable() + child:enable(...) end self:draw() self:capture(self) @@ -2973,7 +2974,7 @@ function UI.Chooser:draw() value = choice.name end self:write(1, 1, '<', bg, colors.black) - self:write(2, 1, ' ' .. Util.widthify(value, self.width-4) .. ' ', bg) + self:write(2, 1, ' ' .. Util.widthify(tostring(value), self.width-4) .. ' ', bg) self:write(self.width, 1, '>', bg, colors.black) end @@ -3257,7 +3258,8 @@ function UI.Form:save() end for _,child in pairs(self.children) do if child.formKey then - if child.pruneEmpty and type(child.value) == 'string' and #child.value == 0 then + if (child.pruneEmpty and type(child.value) == 'string' and #child.value == 0) or + (child.pruneEmpty and type(child.value) == 'boolean' and not child.value) then self.values[child.formKey] = nil else self.values[child.formKey] = child.value From 605e923d4879d1c2bc9dbdf3dd04a7c8abcbec55 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Wed, 24 Oct 2018 06:50:16 -0400 Subject: [PATCH 08/50] ui improvements - disable shell scrolling --- sys/apis/ui.lua | 2 ++ sys/apps/shell | 2 +- sys/extensions/7.multishell.lua | 6 +++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/sys/apis/ui.lua b/sys/apis/ui.lua index 9ef1efd..c922973 100644 --- a/sys/apis/ui.lua +++ b/sys/apis/ui.lua @@ -3261,6 +3261,8 @@ function UI.Form:save() if (child.pruneEmpty and type(child.value) == 'string' and #child.value == 0) or (child.pruneEmpty and type(child.value) == 'boolean' and not child.value) then self.values[child.formKey] = nil + elseif child.validate == 'numeric' then + self.values[child.formKey] = tonumber(child.value) else self.values[child.formKey] = child.value end diff --git a/sys/apps/shell b/sys/apps/shell index 124d9fc..6aaaed7 100644 --- a/sys/apps/shell +++ b/sys/apps/shell @@ -365,7 +365,7 @@ local term = _G.term local textutils = _G.textutils local terminal = term.current() -Terminal.scrollable(terminal, 100) +--Terminal.scrollable(terminal, 100) terminal.noAutoScroll = true local config = { diff --git a/sys/extensions/7.multishell.lua b/sys/extensions/7.multishell.lua index 0a4a81d..b3c2a99 100644 --- a/sys/extensions/7.multishell.lua +++ b/sys/extensions/7.multishell.lua @@ -32,6 +32,7 @@ local config = { backgroundColor = colors.gray, tabBarBackgroundColor = colors.gray, focusBackgroundColor = colors.gray, + errorColor = colors.red, }, color = { textColor = colors.lightGray, @@ -40,6 +41,7 @@ local config = { backgroundColor = colors.gray, tabBarBackgroundColor = colors.gray, focusBackgroundColor = colors.gray, + errorColor = colors.black, }, } Config.load('multishell', config) @@ -129,6 +131,7 @@ function multishell.openTab(tab) print('\nPress enter to close') routine.isDead = true routine.hidden = false + redrawMenu() while true do local e, code = os.pullEventRaw('key') if e == 'terminate' or e == 'key' and code == keys.enter then @@ -252,8 +255,9 @@ kernel.hook('multishell_redraw', function() tab.ex = tabX + tab.width tabX = tabX + tab.width if tab ~= currentTab then + local textColor = tab.isDead and _colors.errorColor or _colors.textColor write(tab.sx, tab.title:sub(1, tab.width - 1), - _colors.backgroundColor, _colors.textColor) + _colors.backgroundColor, textColor) end end end From c75938bef9e428c41c74738281b1a9eb81c705f7 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Wed, 24 Oct 2018 19:13:05 -0400 Subject: [PATCH 09/50] prune method in utils --- sys/apis/util.lua | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sys/apis/util.lua b/sys/apis/util.lua index 3529583..33344fa 100644 --- a/sys/apis/util.lua +++ b/sys/apis/util.lua @@ -172,6 +172,20 @@ function Util.deepMerge(obj, args) end end +-- remove table entries if passed function returns false +function Util.prune(t, fn) + for _,k in pairs(Util.keys(t)) do + local v = t[k] + if type(v) == 'table' then + t[k] = Util.prune(v, fn) + end + if not fn(t[k]) then + t[k] = nil + end + end + return t +end + function Util.transpose(t) local tt = { } for k,v in pairs(t) do From 7220b372bde5f338159228962aa0be3032d94574 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Fri, 26 Oct 2018 18:45:22 -0400 Subject: [PATCH 10/50] new checkbox control --- sys/apis/ui.lua | 57 ++++++++++++++++++++++++++++++++++++++++++-- sys/etc/ext.theme | 9 +++++++ sys/network/snmp.lua | 12 ++++++---- 3 files changed, 71 insertions(+), 7 deletions(-) diff --git a/sys/apis/ui.lua b/sys/apis/ui.lua index c922973..f7363c0 100644 --- a/sys/apis/ui.lua +++ b/sys/apis/ui.lua @@ -2948,6 +2948,8 @@ UI.Chooser.defaults = { choices = { }, nochoice = 'Select', backgroundFocusColor = colors.lightGray, + leftIndicator = '<', + rightIndicator = '>', height = 1, } function UI.Chooser:setParent() @@ -2973,9 +2975,9 @@ function UI.Chooser:draw() if choice then value = choice.name end - self:write(1, 1, '<', bg, colors.black) + self:write(1, 1, self.leftIndicator, self.backgroundColor, colors.black) self:write(2, 1, ' ' .. Util.widthify(tostring(value), self.width-4) .. ' ', bg) - self:write(self.width, 1, '>', bg, colors.black) + self:write(self.width, 1, self.rightIndicator, self.backgroundColor, colors.black) end function UI.Chooser:focus() @@ -3016,6 +3018,57 @@ function UI.Chooser:eventHandler(event) end end +--[[-- Chooser --]]-- +UI.Checkbox = class(UI.Window) +UI.Checkbox.defaults = { + UIElement = 'Checkbox', + nochoice = 'Select', + checkedIndicator = 'X', + leftMarker = '[', + rightMarker = ']', + value = false, + textColor = colors.white, + backgroundColor = colors.black, + backgroundFocusColor = colors.lightGray, + height = 1, + width = 3, + accelerators = { + space = 'checkbox_toggle', + mouse_click = 'checkbox_toggle', + } +} +function UI.Checkbox:draw() + local bg = self.backgroundColor + if self.focused then + bg = self.backgroundFocusColor + end + if type(self.value) == 'string' then + self.value = nil -- TODO: fix form + end + local text = string.format('[%s]', not self.value and ' ' or self.checkedIndicator) + self:write(1, 1, text, bg) + self:write(1, 1, self.leftMarker, self.backgroundColor, self.textColor) + self:write(2, 1, not self.value and ' ' or self.checkedIndicator, bg) + self:write(3, 1, self.rightMarker, self.backgroundColor, self.textColor) +end + +function UI.Checkbox:focus() + self:draw() +end + +function UI.Checkbox:reset() + self.value = false +end + +function UI.Checkbox:eventHandler(event) + if event.type == 'checkbox_toggle' then + self.value = not self.value + self:emit({ type = 'checkbox_change', checked = self.value, element = self }) + self:draw() + return true + end +end + --[[-- Text --]]-- UI.Text = class(UI.Window) UI.Text.defaults = { diff --git a/sys/etc/ext.theme b/sys/etc/ext.theme index e09bfc6..492529e 100644 --- a/sys/etc/ext.theme +++ b/sys/etc/ext.theme @@ -8,6 +8,15 @@ Button = { --focusIndicator = '\183', }, + Checkbox = { + checkedIndicator = '\4', + leftMarker = '\124', + rightMarker = '\124', + }, + Chooser = { + leftIndicator = '\17', + rightIndicator = '\16', + }, Grid = { focusIndicator = '\183', inverseSortIndicator = '\24', diff --git a/sys/network/snmp.lua b/sys/network/snmp.lua index d9fa82d..50297b1 100644 --- a/sys/network/snmp.lua +++ b/sys/network/snmp.lua @@ -150,11 +150,13 @@ local function sendInfo() end if device.neuralInterface then info.status = device.neuralInterface.status - if not info.status and device.neuralInterface.getMetaOwner then - info.status = 'health: ' .. - math.floor(device.neuralInterface.getMetaOwner().health / - device.neuralInterface.getMetaOwner().maxHealth * 100) - end + pcall(function() + if not info.status and device.neuralInterface.getMetaOwner then + info.status = 'health: ' .. + math.floor(device.neuralInterface.getMetaOwner().health / + device.neuralInterface.getMetaOwner().maxHealth * 100) + end + end) end device.wireless_modem.transmit(999, os.getComputerID(), info) end From b564b1e9be1015e4b12ea4c277398a8431b3e554 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sat, 27 Oct 2018 21:34:34 -0400 Subject: [PATCH 11/50] parameter validation --- sys/apis/ui.lua | 2 +- sys/apis/util.lua | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/apis/ui.lua b/sys/apis/ui.lua index f7363c0..f444c00 100644 --- a/sys/apis/ui.lua +++ b/sys/apis/ui.lua @@ -1219,7 +1219,7 @@ function UI.Page:focusNext() end function UI.Page:setFocus(child) - if not child.focus then + if not child or not child.focus then return end diff --git a/sys/apis/util.lua b/sys/apis/util.lua index 33344fa..eb50f58 100644 --- a/sys/apis/util.lua +++ b/sys/apis/util.lua @@ -489,6 +489,7 @@ function Util.insertString(str, istr, pos) end function Util.split(str, pattern) + if not str then error('Util:split: invalid parameters', 2) end pattern = pattern or "(.-)\n" local t = {} local function helper(line) table.insert(t, line) return "" end From 9484153f38ac16842da2199e9eb58eef6cf6aa00 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Mon, 29 Oct 2018 22:03:46 -0400 Subject: [PATCH 12/50] on the fly grid table filtering in ui --- sys/apis/ui.lua | 19 +++++++++++++++---- sys/apis/util.lua | 3 ++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/sys/apis/ui.lua b/sys/apis/ui.lua index f444c00..ead3543 100644 --- a/sys/apis/ui.lua +++ b/sys/apis/ui.lua @@ -1463,7 +1463,14 @@ function UI.Grid:update() end end - self.sorted = Util.keys(self.values) + self.sorted = { } + for k,v in pairs(self.values) do + if self:isRowValid(k, v) then + table.insert(self.sorted, k) + end + end + + --self.sorted = Util.keys(self.values) if order then table.sort(self.sorted, function(a,b) return order(self.values[a], self.values[b]) @@ -1545,6 +1552,12 @@ function UI.Grid:drawRows() end end +-- Non-intuitive: update must be called if the table was specified +-- in the shortcut definition (as this callback was not yet overridden) +function UI.Grid:isRowValid(--[[ key, value ]]) + return true +end + function UI.Grid:getRowTextColor(row, selected) if selected then if self.focused then @@ -2359,9 +2372,7 @@ function UI.Wizard:eventHandler(event) elseif event.type == 'previousView' then local currentView = Util.find(self.pages, 'enabled', true) local nextView = Util.find(self.pages, 'index', currentView.index - 1) - if self:isViewValid() then - currentView:emit({ type = 'enable_view', prev = nextView, current = currentView }) - end + currentView:emit({ type = 'enable_view', prev = nextView, current = currentView }) return true elseif event.type == 'wizard_complete' then diff --git a/sys/apis/util.lua b/sys/apis/util.lua index eb50f58..41a3f1c 100644 --- a/sys/apis/util.lua +++ b/sys/apis/util.lua @@ -356,6 +356,7 @@ function Util.readFile(fname) end function Util.writeFile(fname, data) + if not fname or not data then error('Util.writeFile: invalid parameters', 2) end local file = io.open(fname, "w") if not file then error('Unable to open ' .. fname, 2) @@ -489,7 +490,7 @@ function Util.insertString(str, istr, pos) end function Util.split(str, pattern) - if not str then error('Util:split: invalid parameters', 2) end + if not str then error('Util.split: Invalid parameters', 2) end pattern = pattern or "(.-)\n" local t = {} local function helper(line) table.insert(t, line) return "" end From 846569952c9aa90d4985af7e2613f2eeb9ca20f3 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Wed, 31 Oct 2018 00:05:29 -0400 Subject: [PATCH 13/50] rename debug function --- sys/apis/json.lua | 1 - sys/boot/opus.boot | 2 +- sys/extensions/7.multishell.lua | 4 ++-- sys/kernel.lua | 2 +- sys/network/transport.lua | 14 +++++++------- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/sys/apis/json.lua b/sys/apis/json.lua index 6a1a921..64f8825 100644 --- a/sys/apis/json.lua +++ b/sys/apis/json.lua @@ -68,7 +68,6 @@ local function encodeCommon(val, pretty, tabLevel, tTracking) str = str .. encodeCommon(v, pretty, tabLevel, tTracking) end) else -debug(val) arrEncoding(val, "{", "}", pairs, function(k,v) assert(type(k) == "string", "JSON object keys must be strings", 2) str = str .. encodeCommon(k, pretty, tabLevel, tTracking) diff --git a/sys/boot/opus.boot b/sys/boot/opus.boot index 32c7010..8c5c413 100644 --- a/sys/boot/opus.boot +++ b/sys/boot/opus.boot @@ -11,7 +11,7 @@ for k,v in pairs(_ENV) do sandboxEnv[k] = v end -_G.debug = function() end +_G._debug = function() end local function makeEnv() local env = setmetatable({ }, { __index = _G }) diff --git a/sys/extensions/7.multishell.lua b/sys/extensions/7.multishell.lua index b3c2a99..341800b 100644 --- a/sys/extensions/7.multishell.lua +++ b/sys/extensions/7.multishell.lua @@ -32,7 +32,7 @@ local config = { backgroundColor = colors.gray, tabBarBackgroundColor = colors.gray, focusBackgroundColor = colors.gray, - errorColor = colors.red, + errorColor = colors.black, }, color = { textColor = colors.lightGray, @@ -41,7 +41,7 @@ local config = { backgroundColor = colors.gray, tabBarBackgroundColor = colors.gray, focusBackgroundColor = colors.gray, - errorColor = colors.black, + errorColor = colors.red, }, } Config.load('multishell', config) diff --git a/sys/kernel.lua b/sys/kernel.lua index 2f5b457..b130204 100644 --- a/sys/kernel.lua +++ b/sys/kernel.lua @@ -28,7 +28,7 @@ local focusedRoutineEvents = Util.transpose { 'paste', 'terminate', } -_G.debug = function(pattern, ...) +_G._debug = function(pattern, ...) local oldTerm = term.redirect(kernel.window) Util.print(pattern, ...) term.redirect(oldTerm) diff --git a/sys/network/transport.lua b/sys/network/transport.lua index 77342c2..48d7a62 100644 --- a/sys/network/transport.lua +++ b/sys/network/transport.lua @@ -33,7 +33,7 @@ function transport.read(socket) end function transport.write(socket, data) - --debug('>> ' .. Util.tostring({ type = 'DATA', seq = socket.wseq })) + --_debug('>> ' .. Util.tostring({ type = 'DATA', seq = socket.wseq })) socket.transmit(socket.dport, socket.dhost, data) --local timerId = os.startTimer(3) @@ -45,7 +45,7 @@ function transport.write(socket, data) end function transport.ping(socket) - --debug('>> ' .. Util.tostring({ type = 'DATA', seq = socket.wseq })) + --_debug('>> ' .. Util.tostring({ type = 'DATA', seq = socket.wseq })) if os.clock() - socket.activityTimer > 10 then socket.activityTimer = os.clock() socket.transmit(socket.dport, socket.dhost, { @@ -78,7 +78,7 @@ Event.on('modem_message', function(_, _, dport, dhost, msg, distance) local socket = transport.sockets[dport] if socket and socket.connected then - --if msg.type then debug('<< ' .. Util.tostring(msg)) end + --if msg.type then _debug('<< ' .. Util.tostring(msg)) end if msg.type == 'DISC' then -- received disconnect from other end @@ -108,9 +108,9 @@ Event.on('modem_message', function(_, _, dport, dhost, msg, distance) socket.activityTimer = os.clock() if msg.seq ~= socket.rseq then print('transport seq error - closing socket ' .. socket.sport) - debug(msg.data) - debug('current ' .. socket.rseq) - debug('expected ' .. msg.seq) + _debug(msg.data) + _debug('current ' .. socket.rseq) + _debug('expected ' .. msg.seq) -- socket:close() -- os.queueEvent('transport_' .. socket.uid) else @@ -122,7 +122,7 @@ Event.on('modem_message', function(_, _, dport, dhost, msg, distance) os.queueEvent('transport_' .. socket.uid) end - --debug('>> ' .. Util.tostring({ type = 'ACK', seq = msg.seq })) + --_debug('>> ' .. Util.tostring({ type = 'ACK', seq = msg.seq })) --socket.transmit(socket.dport, socket.dhost, { -- type = 'ACK', -- seq = msg.seq, From 88f126bf2f931f02549675b52fd47d0507fdeb0e Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Wed, 31 Oct 2018 19:38:09 -0400 Subject: [PATCH 14/50] sync module improvements --- sys/apis/fs/netfs.lua | 2 +- sys/apis/sync.lua | 49 ++++++++++++++++++++++++++++++++++------ sys/apis/ui.lua | 4 +++- sys/extensions/6.tl3.lua | 2 +- sys/kernel.lua | 6 +++++ 5 files changed, 53 insertions(+), 10 deletions(-) diff --git a/sys/apis/fs/netfs.lua b/sys/apis/fs/netfs.lua index 58089a4..d7eb2eb 100644 --- a/sys/apis/fs/netfs.lua +++ b/sys/apis/fs/netfs.lua @@ -1,5 +1,5 @@ local Socket = require('socket') -local synchronized = require('sync') +local synchronized = require('sync').sync local fs = _G.fs diff --git a/sys/apis/sync.lua b/sys/apis/sync.lua index e0b841e..7987cb4 100644 --- a/sys/apis/sync.lua +++ b/sys/apis/sync.lua @@ -1,26 +1,61 @@ -local syncLocks = { } +local Sync = { + syncLocks = { } +} local os = _G.os -return function(obj, fn) +function Sync.sync(obj, fn) local key = tostring(obj) - if syncLocks[key] then + if Sync.syncLocks[key] then local cos = tostring(coroutine.running()) - table.insert(syncLocks[key], cos) + table.insert(Sync.syncLocks[key], cos) repeat local _, co = os.pullEvent('sync_lock') until co == cos else - syncLocks[key] = { } + Sync.syncLocks[key] = { } end local s, m = pcall(fn) - local co = table.remove(syncLocks[key], 1) + local co = table.remove(Sync.syncLocks[key], 1) if co then os.queueEvent('sync_lock', co) else - syncLocks[key] = nil + Sync.syncLocks[key] = nil end if not s then error(m) end end + +function Sync.lock(obj) + local key = tostring(obj) + if Sync.syncLocks[key] then + local cos = tostring(coroutine.running()) + table.insert(Sync.syncLocks[key], cos) + repeat + local _, co = os.pullEvent('sync_lock') + until co == cos + else + Sync.syncLocks[key] = { } + end +end + +function Sync.release(obj) + local key = tostring(obj) + if not Sync.syncLocks[key] then + error('Sync.release: Lock was not obtained', 2) + end + local co = table.remove(Sync.syncLocks[key], 1) + if co then + os.queueEvent('sync_lock', co) + else + Sync.syncLocks[key] = nil + end +end + +function Sync.isLocked(obj) + local key = tostring(obj) + return not not Sync.syncLocks[key] +end + +return Sync diff --git a/sys/apis/ui.lua b/sys/apis/ui.lua index ead3543..fbc3f5c 100644 --- a/sys/apis/ui.lua +++ b/sys/apis/ui.lua @@ -2959,6 +2959,7 @@ UI.Chooser.defaults = { choices = { }, nochoice = 'Select', backgroundFocusColor = colors.lightGray, + textInactiveColor = colors.gray, leftIndicator = '<', rightIndicator = '>', height = 1, @@ -2981,13 +2982,14 @@ function UI.Chooser:draw() if self.focused then bg = self.backgroundFocusColor end + local fg = self.inactive and self.textInactiveColor or self.textColor local choice = Util.find(self.choices, 'value', self.value) local value = self.nochoice if choice then value = choice.name end self:write(1, 1, self.leftIndicator, self.backgroundColor, colors.black) - self:write(2, 1, ' ' .. Util.widthify(tostring(value), self.width-4) .. ' ', bg) + self:write(2, 1, ' ' .. Util.widthify(tostring(value), self.width-4) .. ' ', bg, fg) self:write(self.width, 1, self.rightIndicator, self.backgroundColor, colors.black) end diff --git a/sys/extensions/6.tl3.lua b/sys/extensions/6.tl3.lua index 3985dcf..d82930a 100644 --- a/sys/extensions/6.tl3.lua +++ b/sys/extensions/6.tl3.lua @@ -7,7 +7,7 @@ _G.requireInjector(_ENV) local Pathing = require('turtle.pathfind') local GPS = require('gps') local Point = require('point') -local synchronized = require('sync') +local synchronized = require('sync').sync local Util = require('util') local os = _G.os diff --git a/sys/kernel.lua b/sys/kernel.lua index b130204..b686bd8 100644 --- a/sys/kernel.lua +++ b/sys/kernel.lua @@ -34,6 +34,12 @@ _G._debug = function(pattern, ...) term.redirect(oldTerm) end +if not _G.debug then -- don't clobber lua debugger + function _G.debug(...) + _G._debug(...) + end +end + -- any function that runs in a kernel hook does not run in -- a separate coroutine or have a window. an error in a hook -- function will crash the system. From c478781cba0398cf0d14e953f686e9aef50c94a7 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sat, 3 Nov 2018 18:13:41 -0400 Subject: [PATCH 15/50] package management --- sys/apis/git.lua | 18 +++++++++++++++--- sys/apis/packages.lua | 27 +++++++++++++++++++++++--- sys/apis/util.lua | 2 +- sys/apps/Overview.lua | 32 +++++++++++++++++-------------- sys/apps/Package.lua | 36 +++++++++++++++++++++++++++++++++++ sys/apps/Packages.lua | 13 ------------- sys/apps/shell | 4 ++-- sys/extensions/4.user.lua | 8 ++++---- sys/extensions/6.packages.lua | 12 +++++++++--- sys/packageList.lua | 1 + 10 files changed, 110 insertions(+), 43 deletions(-) create mode 100644 sys/apps/Package.lua delete mode 100644 sys/apps/Packages.lua diff --git a/sys/apis/git.lua b/sys/apis/git.lua index 67f27b3..ca4a870 100644 --- a/sys/apis/git.lua +++ b/sys/apis/git.lua @@ -3,11 +3,15 @@ local Util = require('util') local TREE_URL = 'https://api.github.com/repos/%s/%s/git/trees/%s?recursive=1' local FILE_URL = 'https://raw.githubusercontent.com/%s/%s/%s/%s' - local git = { } -function git.list(repository) +local os = _G.os +if not _G.GIT then + _G.GIT = { } +end + +function git.list(repository, cache) local t = Util.split(repository, '(.-)/') local user = t[1] @@ -15,6 +19,14 @@ function git.list(repository) local branch = t[3] or 'master' local dataUrl = string.format(TREE_URL, user, repo, branch) +if _G.GIT[dataUrl] then + _G.GIT[dataUrl].count = _G.GIT[dataUrl].count + 1 +else + _G.GIT[dataUrl] = { + count = 1 + } +end + local contents = Util.download(dataUrl) if not contents then @@ -22,7 +34,7 @@ function git.list(repository) end local data = json.decode(contents) - +Util.writeTable('.git/' .. dataUrl, { day = os.day(), data = data }) if data.message and data.message:find("API rate limit exceeded") then error("Out of API calls, try again later") end diff --git a/sys/apis/packages.lua b/sys/apis/packages.lua index c3b4473..7fdc982 100644 --- a/sys/apis/packages.lua +++ b/sys/apis/packages.lua @@ -1,8 +1,7 @@ -_G.requireInjector(_ENV) - local Util = require('util') local fs = _G.fs +local textutils = _G.textutils local PACKAGE_DIR = 'packages' @@ -22,11 +21,33 @@ function Packages:installed() end function Packages:list() - return Util.readTable('sys/packageList.lua') or { } + if self.packageList then + return self.packageList + end + self.packageList = Util.readTable('sys/packageList.lua') or { } + + return self.packageList end function Packages:isInstalled(package) return self:installed()[package] end +function Packages:getManifest(package) +-- local fname = 'packages/' .. package .. '/.package' + local fname = 'usr/milo/.package' + if fs.exists(fname) then + return Util.readTable(fname) + end + local list = self:list() + local url = list and list[package] + + if url then + local c = Util.httpGet(url) -- will need to call load + if c then + return textutils.unserialize(c) + end + end +end + return Packages diff --git a/sys/apis/util.lua b/sys/apis/util.lua index 41a3f1c..9fe0111 100644 --- a/sys/apis/util.lua +++ b/sys/apis/util.lua @@ -430,7 +430,7 @@ end function Util.download(url, filename) local contents, msg = Util.httpGet(url) if not contents then - error(string.format('Failed to download %s\n%s', url, msg)) + error(string.format('Failed to download %s\n%s', url, msg), 2) end if filename then diff --git a/sys/apps/Overview.lua b/sys/apps/Overview.lua index 0b95299..30fb9fd 100644 --- a/sys/apps/Overview.lua +++ b/sys/apps/Overview.lua @@ -1,14 +1,15 @@ _G.requireInjector(_ENV) -local class = require('class') -local Config = require('config') -local Event = require('event') -local FileUI = require('ui.fileui') -local NFT = require('nft') -local SHA1 = require('sha1') -local Tween = require('ui.tween') -local UI = require('ui') -local Util = require('util') +local class = require('class') +local Config = require('config') +local Event = require('event') +local FileUI = require('ui.fileui') +local NFT = require('nft') +local Packages = require('packages') +local SHA1 = require('sha1') +local Tween = require('ui.tween') +local UI = require('ui') +local Util = require('util') local colors = _G.colors local fs = _G.fs @@ -46,11 +47,14 @@ local function loadApplications() applications = Util.readTable('sys/etc/app.db') - if fs.exists('usr/etc/apps') then - local dbs = fs.list('usr/etc/apps') - for _, db in pairs(dbs) do - local apps = Util.readTable('usr/etc/apps/' .. db) or { } - Util.merge(applications, apps) + for dir in pairs(Packages:installed()) do + local path = fs.combine('packages/' .. dir, 'etc/apps') + if fs.exists(path) then + local dbs = fs.list(path) + for _, db in pairs(dbs) do + local apps = Util.readTable(fs.combine(path, db)) or { } + Util.merge(applications, apps) + end end end diff --git a/sys/apps/Package.lua b/sys/apps/Package.lua new file mode 100644 index 0000000..48b87f9 --- /dev/null +++ b/sys/apps/Package.lua @@ -0,0 +1,36 @@ +_G.requireInjector(_ENV) + +local Packages = require('packages') +local Util = require('util') + +local fs = _G.fs + +local args = { ... } +local action = table.remove(args, 1) + +local function Syntax(msg) + error(msg) +end + +if action == 'list' then + for k in pairs(Packages:list()) do + Util.print('[%s] %s', Packages:isInstalled(k) and 'x' or ' ', k) + end +end + +if action == 'install' then + local name = args[1] or Syntax('Invalid package') + if Packages:isInstalled(name) then + error('Package is already installed') + end + local manifest = Packages:getManifest(name) or error('Invalid package') + local packageDir = 'packages/' .. name + local method = args[2] or 'remote' + if method == 'remote' then + Util.writeTable(packageDir .. '/.install', { + mount = string.format('%s gitfs %s', packageDir, manifest.repository), + }) + Util.writeTable(fs.combine(packageDir, '.package'), manifest) + print('success') + end +end diff --git a/sys/apps/Packages.lua b/sys/apps/Packages.lua deleted file mode 100644 index 14e5c5b..0000000 --- a/sys/apps/Packages.lua +++ /dev/null @@ -1,13 +0,0 @@ -_G.requireInjector(_ENV) - -local Packages = require('packages') -local Util = require('util') - -local args = { ... } - -if args[1] == 'list' then - for k,v in pairs(Packages:list()) do - Util.print('[%s] %s', Packages:isInstalled(k) and 'x' or ' ', k) - end -end - diff --git a/sys/apps/shell b/sys/apps/shell index 6aaaed7..31ce233 100644 --- a/sys/apps/shell +++ b/sys/apps/shell @@ -568,10 +568,10 @@ local function shellRead(history) local ie = Input:translate(event, p1, p2, p3) if ie then if ie.code == 'scroll_up' then - terminal.scrollUp() + --terminal.scrollUp() elseif ie.code == 'scroll_down' then - terminal.scrollDown() + --terminal.scrollDown() elseif ie.code == 'terminate' then bExit = true diff --git a/sys/extensions/4.user.lua b/sys/extensions/4.user.lua index 7688c4c..e7dfa61 100644 --- a/sys/extensions/4.user.lua +++ b/sys/extensions/4.user.lua @@ -11,10 +11,10 @@ end if not fs.exists('usr/autorun') then fs.makeDir('usr/autorun') end -if not fs.exists('usr/config/fstab') then - Util.writeFile('usr/config/fstab', - 'usr gitfs kepler155c/opus-apps/' .. _G.OPUS_BRANCH) -end +--if not fs.exists('usr/config/fstab') then +-- Util.writeFile('usr/config/fstab', +-- 'usr gitfs kepler155c/opus-apps/' .. _G.OPUS_BRANCH) +--end if not fs.exists('usr/config/shell') then Util.writeTable('usr/config/shell', { diff --git a/sys/extensions/6.packages.lua b/sys/extensions/6.packages.lua index 3f46c7e..458be13 100644 --- a/sys/extensions/6.packages.lua +++ b/sys/extensions/6.packages.lua @@ -26,11 +26,17 @@ end -- https://github.com/mpeterv/depgraph/blob/master/src/depgraph/init.lua for name, package in pairs(Packages:installed()) do - if package.mount then - fs.mount(table.unpack(Util.matches(package.mount))) + local packageDir = fs.combine('packages', name) + debug(fs.combine(packageDir, '.install')) + if fs.exists(fs.combine(packageDir, '.install')) then + local install = Util.readTable(fs.combine(packageDir, '.install')) + if install and install.mount then +debug('mounting: ' .. install.mount) + fs.mount(table.unpack(Util.matches(install.mount))) + end end - addPath(appPaths, fs.combine('packages', name)) + addPath(appPaths, packageDir) local apiPath = fs.combine(fs.combine('packages', name), 'apis') if fs.exists(apiPath) then addPath(luaPaths, apiPath) diff --git a/sys/packageList.lua b/sys/packageList.lua index 622f2c1..07c0821 100644 --- a/sys/packageList.lua +++ b/sys/packageList.lua @@ -1,4 +1,5 @@ { [ 'opus-neural' ] = 'file://packages/opus-neural/.package', [ 'opus-miners' ] = 'file://packages/opus-miners/.package', + [ 'opus-milo' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/milo/.package', } \ No newline at end of file From 67be1e0f2f2ee6b4eff1b3caf9852433197b366a Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sat, 3 Nov 2018 18:25:49 -0400 Subject: [PATCH 16/50] package management --- sys/extensions/6.packages.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/extensions/6.packages.lua b/sys/extensions/6.packages.lua index 458be13..fbf3ed7 100644 --- a/sys/extensions/6.packages.lua +++ b/sys/extensions/6.packages.lua @@ -27,11 +27,9 @@ end for name, package in pairs(Packages:installed()) do local packageDir = fs.combine('packages', name) - debug(fs.combine(packageDir, '.install')) if fs.exists(fs.combine(packageDir, '.install')) then local install = Util.readTable(fs.combine(packageDir, '.install')) if install and install.mount then -debug('mounting: ' .. install.mount) fs.mount(table.unpack(Util.matches(install.mount))) end end From 99b2fa1b0bccccce88d215143ae6e3a420ef1279 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sun, 4 Nov 2018 13:00:37 -0500 Subject: [PATCH 17/50] package manager --- sys/apis/git.lua | 71 +++++++++++++++++++----------- sys/apis/packages.lua | 3 +- sys/apis/util.lua | 2 +- sys/apps/Overview.lua | 2 +- sys/apps/Package.lua | 81 ++++++++++++++++++++++++++++++----- sys/extensions/6.packages.lua | 2 +- sys/packageList.lua | 14 ++++-- 7 files changed, 132 insertions(+), 43 deletions(-) diff --git a/sys/apis/git.lua b/sys/apis/git.lua index ca4a870..77c398c 100644 --- a/sys/apis/git.lua +++ b/sys/apis/git.lua @@ -1,40 +1,52 @@ local json = require('json') local Util = require('util') +-- Limit queries to once per minecraft day +-- TODO: will not work if time is stopped + local TREE_URL = 'https://api.github.com/repos/%s/%s/git/trees/%s?recursive=1' local FILE_URL = 'https://raw.githubusercontent.com/%s/%s/%s/%s' local git = { } +local fs = _G.fs local os = _G.os if not _G.GIT then _G.GIT = { } end -function git.list(repository, cache) +function git.list(repository) local t = Util.split(repository, '(.-)/') - local user = t[1] - local repo = t[2] - local branch = t[3] or 'master' + local user = table.remove(t, 1) + local repo = table.remove(t, 1) + local branch = table.remove(t, 1) or 'master' + local path - local dataUrl = string.format(TREE_URL, user, repo, branch) -if _G.GIT[dataUrl] then - _G.GIT[dataUrl].count = _G.GIT[dataUrl].count + 1 -else - _G.GIT[dataUrl] = { - count = 1 - } -end - - local contents = Util.download(dataUrl) - - if not contents then - error('Invalid repository') + if not Util.empty(t) then + path = table.concat(t, '/') .. '/' end - local data = json.decode(contents) -Util.writeTable('.git/' .. dataUrl, { day = os.day(), data = data }) + local cacheKey = table.concat({ user, repo, branch }, '-') + local fname = fs.combine('.git', cacheKey) + + local function getContents() + if fs.exists(fname) then + local contents = Util.readTable(fname) + if contents and contents.data == os.day() then + return contents.data + end + fs.delete(fname) + end + local dataUrl = string.format(TREE_URL, user, repo, branch) + local contents = Util.download(dataUrl) + if contents then + return json.decode(contents) + end + end + + local data = getContents() or error('Invalid repository') + if data.message and data.message:find("API rate limit exceeded") then error("Out of API calls, try again later") end @@ -43,15 +55,26 @@ Util.writeTable('.git/' .. dataUrl, { day = os.day(), data = data }) error("Invalid repository") end - local list = { } + if not fs.exists(fname) then + Util.writeTable('.git/' .. cacheKey, { day = os.day(), data = data }) + end + local list = { } for _,v in pairs(data.tree) do if v.type == "blob" then v.path = v.path:gsub("%s","%%20") - list[v.path] = { - url = string.format(FILE_URL, user, repo, branch, v.path), - size = v.size, - } + if not path then + list[v.path] = { + url = string.format(FILE_URL, user, repo, branch, v.path), + size = v.size, + } + elseif Util.startsWith(v.path, path) then + local p = string.sub(v.path, #path) + list[p] = { + url = string.format(FILE_URL, user, repo, branch, path .. p), + size = v.size, + } + end end end diff --git a/sys/apis/packages.lua b/sys/apis/packages.lua index 7fdc982..ba671c5 100644 --- a/sys/apis/packages.lua +++ b/sys/apis/packages.lua @@ -34,8 +34,7 @@ function Packages:isInstalled(package) end function Packages:getManifest(package) --- local fname = 'packages/' .. package .. '/.package' - local fname = 'usr/milo/.package' + local fname = 'packages/' .. package .. '/.package' if fs.exists(fname) then return Util.readTable(fname) end diff --git a/sys/apis/util.lua b/sys/apis/util.lua index 9fe0111..54a992c 100644 --- a/sys/apis/util.lua +++ b/sys/apis/util.lua @@ -507,7 +507,7 @@ function Util.matches(str, pattern) return t end -function Util.startsWidth(s, match) +function Util.startsWith(s, match) return string.sub(s, 1, #match) == match end diff --git a/sys/apps/Overview.lua b/sys/apps/Overview.lua index 30fb9fd..fb0bbc0 100644 --- a/sys/apps/Overview.lua +++ b/sys/apps/Overview.lua @@ -82,7 +82,7 @@ local function loadApplications() end end - return true -- Util.startsWidth(a.run, 'http') or shell.resolveProgram(a.run) + return true -- Util.startsWith(a.run, 'http') or shell.resolveProgram(a.run) end) end diff --git a/sys/apps/Package.lua b/sys/apps/Package.lua index 48b87f9..d30a77d 100644 --- a/sys/apps/Package.lua +++ b/sys/apps/Package.lua @@ -1,9 +1,11 @@ _G.requireInjector(_ENV) +local Git = require('git') local Packages = require('packages') local Util = require('util') -local fs = _G.fs +local fs = _G.fs +local term = _G.term local args = { ... } local action = table.remove(args, 1) @@ -16,6 +18,47 @@ if action == 'list' then for k in pairs(Packages:list()) do Util.print('[%s] %s', Packages:isInstalled(k) and 'x' or ' ', k) end + return +end + +local function progress(max) + -- modified from: https://pastebin.com/W5ZkVYSi (apemanzilla) + local _, y = term.getCursorPos() + local wide, _ = term.getSize() + term.setCursorPos(1, y) + term.write("[") + term.setCursorPos(wide - 6, y) + term.write("]") + local done = 0 + return function() + done = done + 1 + local value = done / max + term.setCursorPos(2,y) + term.write(("="):rep(math.floor(value * (wide - 8)))) + local percent = math.floor(value * 100) .. "%" + term.setCursorPos(wide - percent:len(),y) + term.write(percent) + end +end + +local function install(name) + local manifest = Packages:getManifest(name) or error('Invalid package') + local packageDir = fs.combine('packages', name) + local method = args[2] or 'local' + if method == 'remote' then + Util.writeTable(packageDir .. '/.install', { + mount = string.format('%s gitfs %s', packageDir, manifest.repository), + }) + Util.writeTable(fs.combine(packageDir, '.package'), manifest) + else + local list = Git.list(manifest.repository) + local showProgress = progress(Util.size(list)) + for path, entry in pairs(list) do + Util.download(entry.url, fs.combine(packageDir, path)) + showProgress() + end + end + return end if action == 'install' then @@ -23,14 +66,30 @@ if action == 'install' then if Packages:isInstalled(name) then error('Package is already installed') end - local manifest = Packages:getManifest(name) or error('Invalid package') - local packageDir = 'packages/' .. name - local method = args[2] or 'remote' - if method == 'remote' then - Util.writeTable(packageDir .. '/.install', { - mount = string.format('%s gitfs %s', packageDir, manifest.repository), - }) - Util.writeTable(fs.combine(packageDir, '.package'), manifest) - print('success') - end + install(name) + print('installation complete') + return end + +if action == 'update' then + local name = args[1] or Syntax('Invalid package') + if not Packages:isInstalled(name) then + error('Package is not installed') + end + install(name) + print('update complete') + return +end + +if action == 'uninstall' then + local name = args[1] or Syntax('Invalid package') + if not Packages:isInstalled(name) then + error('Package is not installed') + end + local packageDir = fs.combine('packages', name) + fs.delete(packageDir) + print('removed: ' .. packageDir) + return +end + +error('Syntax: Package [list | install [name] ... | update [name] | uninstall [name]') diff --git a/sys/extensions/6.packages.lua b/sys/extensions/6.packages.lua index fbf3ed7..8fb598a 100644 --- a/sys/extensions/6.packages.lua +++ b/sys/extensions/6.packages.lua @@ -25,7 +25,7 @@ end -- dependency graph -- https://github.com/mpeterv/depgraph/blob/master/src/depgraph/init.lua -for name, package in pairs(Packages:installed()) do +for name in pairs(Packages:installed()) do local packageDir = fs.combine('packages', name) if fs.exists(fs.combine(packageDir, '.install')) then local install = Util.readTable(fs.combine(packageDir, '.install')) diff --git a/sys/packageList.lua b/sys/packageList.lua index 07c0821..99ddd82 100644 --- a/sys/packageList.lua +++ b/sys/packageList.lua @@ -1,5 +1,13 @@ { - [ 'opus-neural' ] = 'file://packages/opus-neural/.package', - [ 'opus-miners' ] = 'file://packages/opus-miners/.package', - [ 'opus-milo' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/milo/.package', + [ 'core' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/core/.package', + [ 'builder' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/builder/.package', + [ 'farms' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/farms/.package', + [ 'forestry' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/forestry/.package', + [ 'glasses' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/glasses/.package', + [ 'milo' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/milo/.package', + [ 'miners' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/miners/.package', + [ 'neural' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/neural/.package', + [ 'pickup' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/pickup/.package', + [ 'recipeBook' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/recipeBook/.package', + [ 'storage' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/storage/.package', } \ No newline at end of file From 1a4ef3e5819f0d09fd1976c3c774d9170dd06876 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Tue, 6 Nov 2018 16:43:24 -0500 Subject: [PATCH 18/50] package manager UI --- sys/apis/util.lua | 1 + sys/apps/Package.lua | 28 ++++--- sys/apps/PackageManager.lua | 159 ++++++++++++++++++++++++++++++++++++ sys/etc/app.db | 29 ++++--- 4 files changed, 192 insertions(+), 25 deletions(-) create mode 100644 sys/apps/PackageManager.lua diff --git a/sys/apis/util.lua b/sys/apis/util.lua index 54a992c..40f3cb2 100644 --- a/sys/apis/util.lua +++ b/sys/apis/util.lua @@ -221,6 +221,7 @@ function Util.findAll(t, name, value) end function Util.shallowCopy(t) + if not t then error('Util.shallowCopy: invalid table', 2) end local t2 = { } for k,v in pairs(t) do t2[k] = v diff --git a/sys/apps/Package.lua b/sys/apps/Package.lua index d30a77d..1f0d212 100644 --- a/sys/apps/Package.lua +++ b/sys/apps/Package.lua @@ -4,21 +4,16 @@ local Git = require('git') local Packages = require('packages') local Util = require('util') -local fs = _G.fs -local term = _G.term +local fs = _G.fs +local term = _G.term -local args = { ... } -local action = table.remove(args, 1) +local args = { ... } +local action = table.remove(args, 1) local function Syntax(msg) - error(msg) -end - -if action == 'list' then - for k in pairs(Packages:list()) do - Util.print('[%s] %s', Packages:isInstalled(k) and 'x' or ' ', k) - end - return + _G.printError(msg) + print('\nSyntax: Package list | install [name] ... | update [name] | uninstall [name]') + error(0) end local function progress(max) @@ -61,6 +56,13 @@ local function install(name) return end +if action == 'list' then + for k in pairs(Packages:list()) do + Util.print('[%s] %s', Packages:isInstalled(k) and 'x' or ' ', k) + end + return +end + if action == 'install' then local name = args[1] or Syntax('Invalid package') if Packages:isInstalled(name) then @@ -92,4 +94,4 @@ if action == 'uninstall' then return end -error('Syntax: Package [list | install [name] ... | update [name] | uninstall [name]') +Syntax('Invalid command') diff --git a/sys/apps/PackageManager.lua b/sys/apps/PackageManager.lua new file mode 100644 index 0000000..717c167 --- /dev/null +++ b/sys/apps/PackageManager.lua @@ -0,0 +1,159 @@ +_G.requireInjector(_ENV) + +local Ansi = require('ansi') +local Packages = require('packages') +local UI = require('ui') +local Util = require('util') + +local colors = _G.colors +local shell = _ENV.shell +local term = _G.term + +UI:configure('PackageManager', ...) + +local page = UI.Page { + grid = UI.ScrollingGrid { + y = 2, ey = 7, x = 2, ex = -6, + values = { }, + columns = { + { heading = 'Package', key = 'name' }, + }, + sortColumn = 'name', + autospace = true, + help = 'Select a package', + }, + add = UI.Button { + x = -4, y = 4, + text = '+', + event = 'action', + help = 'Install or update', + }, + remove = UI.Button { + x = -4, y = 6, + text = '-', + event = 'action', + operation = 'uninstall', + operationText = 'Remove', + help = 'Remove', + }, + description = UI.TextArea { + x = 2, y = 9, ey = -2, + --backgroundColor = colors.white, + }, + statusBar = UI.StatusBar { }, + action = UI.SlideOut { + backgroundColor = colors.cyan, + titleBar = UI.TitleBar { + event = 'hide-action', + }, + button = UI.Button { + ex = -4, y = 4, width = 7, + text = 'Begin', event = 'begin', + }, + output = UI.Embedded { + y = 6, ey = -2, x = 2, ex = -2, + }, + statusBar = UI.StatusBar { + backgroundColor = colors.cyan, + }, + }, +} + +function page.grid:getRowTextColor(row, selected) + if row.installed then + return colors.yellow + end + return UI.Grid.getRowTextColor(self, row, selected) +end + +function page.action:show() + UI.SlideOut.show(self) + self.output:draw() + self.output.win.redraw() +end + +function page:run(operation, name) + local oterm = term.redirect(self.action.output.win) + self.action.output:clear() + local cmd = string.format('Package %s %s', operation, name) + --for _ = 1, 3 do + -- print(cmd .. '\n') + -- os.sleep(1) + --end + term.setCursorPos(1, 1) + term.clear() + term.setTextColor(colors.yellow) + print(cmd .. '\n') + term.setTextColor(colors.white) + shell.run(cmd) + term.redirect(oterm) + self.action.output:draw() +end + +function page:updateSelection(selected) + self.add.operation = selected.installed and 'update' or 'install' + self.add.operationText = selected.installed and 'Update' or 'Install' +end + +function page:eventHandler(event) + if event.type == 'focus_change' then + self.statusBar:setStatus(event.focused.help) + + elseif event.type == 'grid_focus_row' then + local manifest = event.selected.manifest + + self.description.value = string.format('%s%s\n\n%s%s', + Ansi.yellow, manifest.title, + Ansi.white, manifest.description) + self.description:draw() + self:updateSelection(event.selected) + + elseif event.type == 'action' then + local selected = self.grid:getSelected() + if selected then + self.operation = event.button.operation + self.action.button.text = event.button.operationText + self.action.titleBar.title = selected.manifest.title + self.action.button.text = 'Begin' + self.action.button.event = 'begin' + self.action:show() + end + + elseif event.type == 'hide-action' then + self.action:hide() + + elseif event.type == 'begin' then + local selected = self.grid:getSelected() + self:run(self.operation, selected.name) + selected.installed = Packages:isInstalled(selected.name) + + self:updateSelection(selected) + self.action.button.text = 'Done' + self.action.button.event = 'hide-action' + self.action.button:draw() + + elseif event.type == 'quit' then + UI:exitPullEvents() + end + UI.Page.eventHandler(self, event) +end + +for k in pairs(Packages:list()) do + local manifest = Packages:getManifest(k) + if not manifest then + manifest = { + invalid = true, + description = 'Unable to download manifest', + title = '', + } + end + table.insert(page.grid.values, { + installed = not not Packages:isInstalled(k), + name = k, + manifest = manifest, + }) +end +page.grid:update() + +UI:setPage(page) +UI:pullEvents() diff --git a/sys/etc/app.db b/sys/etc/app.db index 68b9abc..19611c5 100644 --- a/sys/etc/app.db +++ b/sys/etc/app.db @@ -1,11 +1,16 @@ { + [ "0a999012ffb87b3edac99adbdfc498b12831a1e2" ] = { + title = "Packages", + category = "System", + run = "PackageManager.lua", + }, [ "53ebc572b4a44802ba114729f07bdaaf5409a9d7" ] = { title = "Network", category = "Apps", icon = "\0304 \030 \ \030f \0304 \0307 \030 \031 \031f)\ \030f \0304 \0307 \030 \031f)", - iconExt = "\030 \031f \0305\031f\140\030f\0315\137\144\ + iconExt = "\030 \031f \0305\031f\140\030f\0315\137\144\ \030 \031f\030f\0314\131\131\0304\031f\148\030 \0305\155\150\149\ \030 \031f\030f\0310\147\0300\031f\141\0304\149\0307\0318\149\030 ", run = "Network.lua", @@ -16,7 +21,7 @@ icon = "\0304\031f \030f\0310o..\0304\031f \ \0304\031f \030f\0310.o.\0304\031f \ \0304\031f - ", - iconExt = "\0307\031f\135\0300\0317\159\0307\0310\144\031f\139\ + iconExt = "\0307\031f\135\0300\0317\159\0307\0310\144\031f\139\ \0300\0317\131\0307\0310\147\0300\0317\156\131\ \130\143\143\129", run = "rom/programs/reboot", @@ -27,7 +32,7 @@ icon = "\0301\03171\03180\030 \031 \ \0301\03181\030 \031 \ \0301\03170\03180\03171\0307\031f>", - iconExt = "\031f\128\0313\152\131\131\132\031f\128\ + iconExt = "\031f\128\0313\152\131\131\132\031f\128\ \0313\139\159\129\0303\031f\159\129\139\ \031f\128\0313\136\0303\031f\143\143\030f\0313\134\031f\128", run = "http://pastebin.com/raw/UzGHLbNC", @@ -38,7 +43,7 @@ icon = " \031f?\031 \ \031f?\031 \ \031f?", - iconExt = "\0300\031f\129\030f\0310\131\0300\031f\148\030f\0310\148\ + iconExt = "\0300\031f\129\030f\0310\131\0300\031f\148\030f\0310\148\ \030 \031 \0300\031f\131\030f\0310\142\129\ \030 \031 \0300\031f\131\030f\128", run = "Help.lua", @@ -49,7 +54,7 @@ icon = "\030f \ \030f\0310lua>\031 \ \030f ", - iconExt = "\0300\031f\151\030f\128\0300\159\159\159\030f\0310\144\0304\031f\159\030f\128\ + iconExt = "\0300\031f\151\030f\128\0300\159\159\159\030f\0310\144\0304\031f\159\030f\128\ \0300\031f\149\030f\128\0300\149\149\151\145\030f\128\0314\153\ \130\131\130\131\130\131\0314\130\031f\128", run = "sys/apps/Lua.lua", @@ -60,7 +65,7 @@ icon = "\0304 \030 \ \030f \0304 \0307 \030 \031 \031f_\ \030f \0304 \0307 \030 \031f/", - iconExt = "\031f\128\128\128\0308\159\143\0300\0317\151\0307\0310\140\148\ + iconExt = "\031f\128\128\128\0308\159\143\0300\0317\151\0307\0310\140\148\ \0314\151\131\0304\031f\148\030f\0318\138\148\0307\0310\138\131\129\ \0304\031f\138\143\133\030f\0318\131\129\031f\128\128\128", run = "Devices.lua", @@ -71,7 +76,7 @@ icon = " \0307\031f| \ \0307\031f---o\030 \031 \ \0307\031f| ", - iconExt = "\0318\138\0308\031f\130\0318\128\031f\129\030f\0318\133\ + iconExt = "\0318\138\0308\031f\130\0318\128\031f\129\030f\0318\133\ \0318\143\0308\128\0317\143\0318\128\030f\143\ \0318\138\135\143\139\133", run = "System.lua", @@ -82,7 +87,7 @@ icon = "\0304\031f \030 \0311e\ \030f\031f \0304 \030 \0311ee\031f \ \030f\031f \0304 \030 \0311e\031f ", - iconExt = "\0300\031f\159\135\030f\0310\156\0301\031f\159\030f\0311\144\0300\031f\147\139\030f\0310\144\ + iconExt = "\0300\031f\159\135\030f\0310\156\0301\031f\159\030f\0311\144\0300\031f\147\139\030f\0310\144\ \0300\128\128\030f\149\0311\157\142\0300\031f\149\0310\128\128\ \130\139\141\0311\130\131\0310\142\135\129", run = "Events.lua", @@ -93,7 +98,7 @@ icon = "\030f\031f \0315/\ \030f\031f \0315/\\/ \ \030f\0315/\031f ", - iconExt = "\031f\128\128\0305\159\030f\128\0305\159\030f\0315\134\031f\128\ + iconExt = "\031f\128\128\0305\159\030f\128\0305\159\030f\0315\134\031f\128\ \031f\128\0315\152\129\137\0305\031f\158\139\030f\0317 \ \0315\134\031f\128\128\128\128\0305\154\030f\0317 ", run = "Tasks.lua", @@ -104,7 +109,7 @@ icon = "\0300\0317==\031 \0307 \ \0300\0317====\ \0300\0317====", - iconExt = "\030 \031f\0300\031f\136\140\132\0308\130\030f\0318\144\ + iconExt = "\030 \031f\0300\031f\136\140\132\0308\130\030f\0318\144\ \030 \031f\030f\0310\157\0300\031f\147\030f\0310\142\143\149\ \030 \031f\0300\031f\136\140\132\140\030f\0310\149", run = "Files.lua", @@ -115,7 +120,7 @@ icon = "\0304\031f \ \0304\031f \030f\0310zz\031 \ \0304\031f \030f ", - iconExt = "\030e\031f\135\030f\031e\148\030e\128\031f\151\139\ + iconExt = "\030e\031f\135\030f\031e\148\030e\128\031f\151\139\ \030e\031e\128\030f\031f\128\031e\143\031f\128\030e\031e\128\ \031e\139\030e\031f\130\131\129\030f\031e\135", run = "/rom/programs/shutdown", @@ -163,7 +168,7 @@ icon = "\030d \030 \030e \030 \ \030d \030 \ \030d ", - iconExt = "\030 \031f\0305\031f\151\030f\0315\135\131\0305\031f\146\ + iconExt = "\030 \031f\0305\031f\151\030f\0315\135\131\0305\031f\146\ \030 \031f\030f\0315\130\141\0305\031f\139\030f\0315\130\ \030 \031f\0305\031f\146\143\030f\0315\158\031e\130", run = "/rom/programs/fun/worm", From cb03e56a1f0af95280869aae1b4eb00ee3f84640 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Tue, 6 Nov 2018 17:28:21 -0500 Subject: [PATCH 19/50] package manager UI --- sys/extensions/7.multishell.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sys/extensions/7.multishell.lua b/sys/extensions/7.multishell.lua index 341800b..4da07e8 100644 --- a/sys/extensions/7.multishell.lua +++ b/sys/extensions/7.multishell.lua @@ -1,7 +1,8 @@ _G.requireInjector(_ENV) -local Config = require('config') -local Util = require('util') +local Config = require('config') +local Packages = require('packages') +local Util = require('util') local colors = _G.colors local fs = _G.fs @@ -375,6 +376,10 @@ local function startup() end runDir('sys/autorun', shell.run) + for name in pairs(Packages:installed()) do + local packageDir = 'packages/' .. name .. '/autorun' + runDir(packageDir, shell.run) + end runDir('usr/autorun', shell.run) if not success then From 68ee419d83e7a9cb80aa63dd5dbea6d391ee7d32 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Fri, 9 Nov 2018 15:07:55 -0500 Subject: [PATCH 20/50] fix invalid msg crashing socket --- sys/apis/config.lua | 4 +++- sys/apis/socket.lua | 2 +- sys/apps/PackageManager.lua | 3 +-- sys/apps/{Package.lua => package.lua} | 0 4 files changed, 5 insertions(+), 4 deletions(-) rename sys/apps/{Package.lua => package.lua} (100%) diff --git a/sys/apis/config.lua b/sys/apis/config.lua index 20f4e86..13ab441 100644 --- a/sys/apis/config.lua +++ b/sys/apis/config.lua @@ -20,6 +20,8 @@ function Config.load(fname, data) Util.merge(data, contents) end + + return data end function Config.loadWithCheck(fname, data) @@ -36,7 +38,7 @@ function Config.loadWithCheck(fname, data) shell.run('edit ' .. filename) end - Config.load(fname, data) + return Config.load(fname, data) end function Config.update(fname, data) diff --git a/sys/apis/socket.lua b/sys/apis/socket.lua index df47a79..6cfca6a 100644 --- a/sys/apis/socket.lua +++ b/sys/apis/socket.lua @@ -183,7 +183,7 @@ function Socket.server(port) local _, _, sport, dport, msg = os.pullEvent('modem_message') if sport == port and - msg and + msg and type(msg) == 'table' and msg.dhost == os.getComputerID() and msg.type == 'OPEN' then diff --git a/sys/apps/PackageManager.lua b/sys/apps/PackageManager.lua index 717c167..fd05cf0 100644 --- a/sys/apps/PackageManager.lua +++ b/sys/apps/PackageManager.lua @@ -3,7 +3,6 @@ _G.requireInjector(_ENV) local Ansi = require('ansi') local Packages = require('packages') local UI = require('ui') -local Util = require('util') local colors = _G.colors local shell = _ENV.shell @@ -75,7 +74,7 @@ end function page:run(operation, name) local oterm = term.redirect(self.action.output.win) self.action.output:clear() - local cmd = string.format('Package %s %s', operation, name) + local cmd = string.format('package %s %s', operation, name) --for _ = 1, 3 do -- print(cmd .. '\n') -- os.sleep(1) diff --git a/sys/apps/Package.lua b/sys/apps/package.lua similarity index 100% rename from sys/apps/Package.lua rename to sys/apps/package.lua From 10a0c3a7244a8b3f815e69d3ce5e8ba5c095a13c Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Fri, 9 Nov 2018 15:27:13 -0500 Subject: [PATCH 21/50] modem packet validation --- sys/apis/socket.lua | 4 +++- sys/network/redserver.lua | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/sys/apis/socket.lua b/sys/apis/socket.lua index 6cfca6a..7db64ae 100644 --- a/sys/apis/socket.lua +++ b/sys/apis/socket.lua @@ -128,6 +128,7 @@ function Socket.connect(host, port) local e, id, sport, dport, msg = os.pullEvent() if e == 'modem_message' and sport == socket.sport and + type(msg) == 'table' and msg.dhost == socket.shost then os.cancelTimer(timerId) @@ -183,7 +184,8 @@ function Socket.server(port) local _, _, sport, dport, msg = os.pullEvent('modem_message') if sport == port and - msg and type(msg) == 'table' and + msg and + type(msg) == 'table' and msg.dhost == os.getComputerID() and msg.type == 'OPEN' then diff --git a/sys/network/redserver.lua b/sys/network/redserver.lua index f4f9351..fda019c 100644 --- a/sys/network/redserver.lua +++ b/sys/network/redserver.lua @@ -83,11 +83,15 @@ Event.on('modem_message', function(_, _, dport, dhost, request) if dport == 80 and dhost == computerId and type(request) == 'table' then if request.method == 'GET' then local query + if not request.path or type(request.path) ~= 'string' then + return + end local path = request.path:gsub('%?(.*)', function(v) query = parseQuery(v) return '' end) if fs.isDir(path) then + -- TODO: more validation modem.transmit(request.replyPort, request.replyAddress, { statusCode = 200, contentType = 'table/directory', From b3a061d39b707cf40b61ca6609a8b9ff0ee66301 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sat, 10 Nov 2018 13:00:22 -0500 Subject: [PATCH 22/50] vnc auto-reconnect --- sys/apps/System.lua | 100 ++++++++++++++--------------- sys/apps/vnc.lua | 149 ++++++++++++++++++++++++++------------------ 2 files changed, 141 insertions(+), 108 deletions(-) diff --git a/sys/apps/System.lua b/sys/apps/System.lua index 10e4816..ce2a2b1 100644 --- a/sys/apps/System.lua +++ b/sys/apps/System.lua @@ -141,61 +141,63 @@ local systemPage = UI.Page { } if turtle then - local Home = require('turtle.home') + pcall(function() + local Home = require('turtle.home') +-- TODO: dont rely on turtle.home + local values = { } + Config.load('gps', values.home and { values.home } or { }) - 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' }, + 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', }, }, - 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 { }) + }) + 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() - systemPage.notification:success('Location set') - else - systemPage.notification:error('Unable to determine location') + return true end - return true - elseif event.type == 'gps_clear' then - fs.delete('usr/config/gps') - self.grid:setValues({ }) - self.grid:draw() - return true end - end + end) end if settings then diff --git a/sys/apps/vnc.lua b/sys/apps/vnc.lua index 6ea3852..ca8b670 100644 --- a/sys/apps/vnc.lua +++ b/sys/apps/vnc.lua @@ -1,12 +1,13 @@ _G.requireInjector(_ENV) -local Event = require('event') -local Socket = require('socket') -local Terminal = require('terminal') -local Util = require('util') +local Event = require('event') +local Socket = require('socket') +local Terminal = require('terminal') +local Util = require('util') local colors = _G.colors local multishell = _ENV.multishell +local os = _G.os local term = _G.term local remoteId @@ -26,75 +27,105 @@ if multishell then multishell.setTitle(multishell.getCurrent(), 'VNC-' .. remoteId) end -print('connecting...') -local socket, msg = Socket.connect(remoteId, 5900) +local function connect() + local socket, msg = Socket.connect(remoteId, 5900) -if not socket then - error(msg) -end + if not socket then + return false, msg + end -local function writeTermInfo() - local w, h = term.getSize() - socket:write({ - type = 'termInfo', - width = w, - height = h, - isColor = term.isColor(), + local function writeTermInfo() + local w, h = term.getSize() + socket:write({ + type = 'termInfo', + width = w, + height = h, + isColor = term.isColor(), + }) + end + + writeTermInfo() + + local ct = Util.shallowCopy(term.current()) + + if not ct.isColor() then + Terminal.toGrayscale(ct) + end + + ct.clear() + ct.setCursorPos(1, 1) + + Event.addRoutine(function() + while true do + local data = socket:read() + if not data then + _debug('exiting routine') + break + end + for _,v in ipairs(data) do + ct[v.f](unpack(v.args)) + end + end + end) + + local filter = Util.transpose({ + 'char', 'paste', 'key', 'key_up', + 'mouse_scroll', 'mouse_click', 'mouse_drag', 'mouse_up', }) -end -writeTermInfo() - -local ct = Util.shallowCopy(term.current()) - -if not ct.isColor() then - Terminal.toGrayscale(ct) -end - -Event.addRoutine(function() while true do - local data = socket:read() - if not data then + local e = Event.pullEvent() + local event = e[1] + + if not socket.connected then break end - for _,v in ipairs(data) do - ct[v.f](unpack(v.args)) + + if filter[event] then + socket:write({ + type = 'shellRemote', + event = e, + }) + elseif event == 'term_resize' then + writeTermInfo() + elseif event == 'terminate' then + socket:close() + ct.setBackgroundColor(colors.black) + ct.clear() + ct.setCursorPos(1, 1) + return true end end -end) - -ct.clear() -ct.setCursorPos(1, 1) - -local filter = Util.transpose({ - 'char', 'paste', 'key', 'key_up', - 'mouse_scroll', 'mouse_click', 'mouse_drag', 'mouse_up', -}) + return false, "Connection Lost" +end while true do - local e = Event.pullEvent() - local event = e[1] + term.clear() + term.setCursorPos(1, 1) - if not socket.connected then - print() - print('Connection lost') - print('Press enter to exit') - _G.read() + print('connecting...') + local s, m = connect() + if s then break end - if filter[event] then - socket:write({ - type = 'shellRemote', - event = e, - }) - elseif event == 'term_resize' then - writeTermInfo() - elseif event == 'terminate' then - socket:close() - ct.setBackgroundColor(colors.black) - ct.clear() - ct.setCursorPos(1, 1) - break + term.setBackgroundColor(colors.black) + term.setTextColor(colors.white) + term.clear() + term.setCursorPos(1, 1) + print(m) + print('\nPress any key to exit') + print('\nRetrying in ... ') + local x, y = term.getCursorPos() + for i = 5, 1, -1 do + local timerId = os.startTimer(1) + term.setCursorPos(x, y) + term.write(i) + repeat + local e, id = os.pullEvent() + if e == 'char' or e == 'key' then + return + end + until e == 'timer' and id == timerId end end From 4721b6aec130264602f8140189c7e6ce703416eb Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sat, 10 Nov 2018 13:04:32 -0500 Subject: [PATCH 23/50] vnc auto-reconnect --- sys/apps/vnc.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/apps/vnc.lua b/sys/apps/vnc.lua index ca8b670..5b17700 100644 --- a/sys/apps/vnc.lua +++ b/sys/apps/vnc.lua @@ -59,7 +59,6 @@ local function connect() while true do local data = socket:read() if not data then - _debug('exiting routine') break end for _,v in ipairs(data) do From 17d55e75cee9d64d57e0cf58bbe3523e5cc2d4e3 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sun, 11 Nov 2018 14:45:04 -0500 Subject: [PATCH 24/50] support preferred wireless modems --- sys/apis/peripheral.lua | 10 +++----- sys/extensions/5.network.lua | 46 +++++++++++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/sys/apis/peripheral.lua b/sys/apis/peripheral.lua index 077e959..e4638d7 100644 --- a/sys/apis/peripheral.lua +++ b/sys/apis/peripheral.lua @@ -28,9 +28,9 @@ function Peripheral.addDevice(deviceList, side) end if ptype == 'modem' then - if Peripheral.call(name, 'isWireless') then - ptype = 'wireless_modem' - else + if not Peripheral.call(name, 'isWireless') then +-- ptype = 'wireless_modem' +-- else ptype = 'wired_modem' end end @@ -57,10 +57,6 @@ function Peripheral.addDevice(deviceList, side) -- this can randomly fail pcall(function() deviceList[name] = Peripheral.wrap(side) - if ptype == 'wireless_modem' and not deviceList.wireless_modem then - -- TODO: fix this - deviceList.wireless_modem = deviceList[name] - end end) if deviceList[name] then diff --git a/sys/extensions/5.network.lua b/sys/extensions/5.network.lua index b776653..80defd9 100644 --- a/sys/extensions/5.network.lua +++ b/sys/extensions/5.network.lua @@ -1,5 +1,10 @@ -local kernel = _G.kernel -local os = _G.os +_G.requireInjector(_ENV) + +local Config = require('config') + +local device = _G.device +local kernel = _G.kernel +local os = _G.os _G.network = { } @@ -11,15 +16,44 @@ local function startNetwork() }) 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 + device.wireless_modem = dev + os.queueEvent('device_attach', 'wireless_modem') + return dev + end + end +end + +-- create a psuedo-device named 'wireleess_modem' kernel.hook('device_attach', function(_, eventData) - if eventData[1] == 'wireless_modem' then - startNetwork() + local dev = device[eventData[1]] + if dev.type == 'modem' then + if setModem(dev) then + startNetwork() + end end end) -if _G.device.wireless_modem then +kernel.hook('device_detach', function(_, eventData) + if device.wireless_modem and eventData[1] == device.wireless_modem.name then + device['wireless_modem'] = nil + os.queueEvent('device_detach', 'wireless_modem') + end +end) + +for _,dev in pairs(device) do + if dev.type == 'modem' then + if setModem(dev) then + break + end + end +end + +if device.wireless_modem then print('waiting for network...') startNetwork() os.pullEvent('network_up') end - From f9359cf77ff02eff536b33749677ccc5155b4ff4 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Mon, 12 Nov 2018 15:22:29 -0500 Subject: [PATCH 25/50] wizard - modem fixes --- sys/apis/ui.lua | 2 +- sys/extensions/5.network.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/apis/ui.lua b/sys/apis/ui.lua index fbc3f5c..3dc03c0 100644 --- a/sys/apis/ui.lua +++ b/sys/apis/ui.lua @@ -2364,8 +2364,8 @@ end function UI.Wizard:eventHandler(event) if event.type == 'nextView' then local currentView = Util.find(self.pages, 'enabled', true) - local nextView = Util.find(self.pages, 'index', currentView.index + 1) if self:isViewValid() then + local nextView = Util.find(self.pages, 'index', currentView.index + 1) currentView:emit({ type = 'enable_view', next = nextView, current = currentView }) end diff --git a/sys/extensions/5.network.lua b/sys/extensions/5.network.lua index 80defd9..3963ae2 100644 --- a/sys/extensions/5.network.lua +++ b/sys/extensions/5.network.lua @@ -30,7 +30,7 @@ end -- create a psuedo-device named 'wireleess_modem' kernel.hook('device_attach', function(_, eventData) local dev = device[eventData[1]] - if dev.type == 'modem' then + if dev and dev.type == 'modem' then if setModem(dev) then startNetwork() end From 62ac7a52ece69a8c9f860399617540a898c147f2 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Mon, 12 Nov 2018 20:21:35 -0500 Subject: [PATCH 26/50] overview cleanup + chooser better events --- sys/apis/ui.lua | 16 ++++++++++------ sys/apps/Overview.lua | 17 +++++++---------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/sys/apis/ui.lua b/sys/apis/ui.lua index 3dc03c0..4162f3a 100644 --- a/sys/apis/ui.lua +++ b/sys/apis/ui.lua @@ -3001,22 +3001,26 @@ function UI.Chooser:eventHandler(event) if event.type == 'key' then if event.key == 'right' or event.key == 'space' then local _,k = Util.find(self.choices, 'value', self.value) + local choice if k and k < #self.choices then - self.value = self.choices[k+1].value + choice = self.choices[k+1] else - self.value = self.choices[1].value + choice = self.choices[1] end - self:emit({ type = 'choice_change', value = self.value }) + self.value = choice.value + self:emit({ type = 'choice_change', value = self.value, element = self, choice = choice }) self:draw() return true elseif event.key == 'left' then local _,k = Util.find(self.choices, 'value', self.value) + local choice if k and k > 1 then - self.value = self.choices[k-1].value + choice = self.choices[k-1] else - self.value = self.choices[#self.choices].value + choice = self.choices[#self.choices] end - self:emit({ type = 'choice_change', value = self.value }) + self.value = choice.value + self:emit({ type = 'choice_change', value = self.value, element = self, choice = choice }) self:draw() return true end diff --git a/sys/apps/Overview.lua b/sys/apps/Overview.lua index fb0bbc0..14740fc 100644 --- a/sys/apps/Overview.lua +++ b/sys/apps/Overview.lua @@ -37,12 +37,12 @@ local extSupport = Util.getVersion() >= 1.76 local function loadApplications() local requirements = { - turtle = function() return turtle end, - advancedTurtle = function() return turtle and term.isColor() end, - advanced = function() return term.isColor() end, - pocket = function() return pocket end, - advancedPocket = function() return pocket and term.isColor() end, - advancedComputer = function() return not turtle and not pocket and term.isColor() end, + turtle = not not turtle, + advancedTurtle = turtle and term.isColor(), + advanced = term.isColor(), + pocket = not not pocket, + advancedPocket = pocket and term.isColor(), + advancedComputer = not turtle and not pocket and term.isColor(), } applications = Util.readTable('sys/etc/app.db') @@ -76,10 +76,7 @@ local function loadApplications() end if a.requires then - local fn = requirements[a.requires] - if fn and not fn() then - return false - end + return requirements[a.requires] end return true -- Util.startsWith(a.run, 'http') or shell.resolveProgram(a.run) From ccd1711d206df436bb161d1b84c5c731c66fceb0 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Tue, 13 Nov 2018 21:31:55 -0500 Subject: [PATCH 27/50] fix titlebar look --- sys/apis/ui.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/apis/ui.lua b/sys/apis/ui.lua index 4162f3a..e022b2f 100644 --- a/sys/apis/ui.lua +++ b/sys/apis/ui.lua @@ -1886,6 +1886,8 @@ function UI.TitleBar:draw() sb:center(string.format(' %s ', self.title)) if self.previousPage or self.event then sb:insert(-1, self.closeInd) + else + sb:insert(-2, self.frameChar) end self:write(1, 1, sb:get()) end From c6fd959371fd5783b60feb84b29cb8e703cc6b40 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Wed, 14 Nov 2018 21:37:05 -0500 Subject: [PATCH 28/50] new icons - thx LDD --- sys/etc/app.db | 68 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 22 deletions(-) diff --git a/sys/etc/app.db b/sys/etc/app.db index 19611c5..22b2c17 100644 --- a/sys/etc/app.db +++ b/sys/etc/app.db @@ -3,6 +3,9 @@ title = "Packages", category = "System", run = "PackageManager.lua", + iconExt = "\030c\0317\151\131\131\131\0307\031c\148\ +\030c\0317\151\131\0310\143\0317\131\0307\031c\148\ +\0307\031c\138\030f\0317\151\131\131\131", }, [ "53ebc572b4a44802ba114729f07bdaaf5409a9d7" ] = { title = "Network", @@ -59,17 +62,6 @@ \130\131\130\131\130\131\0314\130\031f\128", run = "sys/apps/Lua.lua", }, - df485c871329671f46570634d63216761441bcd6 = { - title = "Devices", - category = "System", - icon = "\0304 \030 \ -\030f \0304 \0307 \030 \031 \031f_\ -\030f \0304 \0307 \030 \031f/", - iconExt = "\031f\128\128\128\0308\159\143\0300\0317\151\0307\0310\140\148\ -\0314\151\131\0304\031f\148\030f\0318\138\148\0307\0310\138\131\129\ -\0304\031f\138\143\133\030f\0318\131\129\031f\128\128\128", - run = "Devices.lua", - }, bc0792d8dc81e8aa30b987246a5ce97c40cd6833 = { title = "System", category = "System", @@ -81,17 +73,6 @@ \0318\138\135\143\139\133", run = "System.lua", }, - c5497bca58468ae64aed6c0fd921109217988db3 = { - title = "Events", - category = "System", - icon = "\0304\031f \030 \0311e\ -\030f\031f \0304 \030 \0311ee\031f \ -\030f\031f \0304 \030 \0311e\031f ", - iconExt = "\0300\031f\159\135\030f\0310\156\0301\031f\159\030f\0311\144\0300\031f\147\139\030f\0310\144\ -\0300\128\128\030f\149\0311\157\142\0300\031f\149\0310\128\128\ -\130\139\141\0311\130\131\0310\142\135\129", - run = "Events.lua", - }, [ "2a4d562b1d9a9c90bdede6fac8ce4f7402462b86" ] = { title = "Tasks", category = "System", @@ -103,6 +84,41 @@ \0315\134\031f\128\128\128\128\0305\154\030f\0317 ", run = "Tasks.lua", }, + [ "a0365977708b7387ee9ce2c13e5820e6e11732cb" ] = { + title = "Pain", + category = "Apps", + icon = "\030 \031f\0307\031f\159\030 \159\030 \ +\030 \031f\0308\031f\135\0307\0318\144\140\030f\0317\159\143\031c\139\0302\135\030f\0312\157\ +\030 \031f\030f\0318\143\133\0312\136\0302\031f\159\159\143\131\030f\0312\132", + run = "http://pastebin.com/raw/wJQ7jav0", + }, + [ "48d6857f6b2869d031f463b13aa34df47e18c548" ] = { + title = "Breakout", + category = "Games", + icon = "\0301\031f \0309 \030c \030b \030e \030c \0306 \ +\030 \031f \ +\030 \031f \0300 \0310 ", + iconExt = "\030 \031f\030f\0319\144\030d\031f\159\030b\159\030f\0311\144\031b\144\030c\031f\159\030f\0311\144\ +\030 \031f\030f\0311\130\031b\129\0319\130\031e\130\0310\144\031d\129\0316\129\ +\030 \031f\030f\0310\136\140\140\030 ", + run = "https://gist.github.com/LDDestroier/c7528d95bc0103545c2a/raw", + }, + [ "53a5d150062b1e03206b9e15854b81060e3c7552" ] = { + title = "Minesweeper", + category = "Games", + icon = "\030f\031f \03131\0308\031f \030f\031d2\ +\030f\031f \031d2\03131\0308\031f \030f\03131\ +\030f\03131\0308\031f \030f\03131\031e3", + run = "https://pastebin.com/raw/nsKrHTbN", + }, + [ "01c933b2a36ad8ed2d54089cb2903039046c1216" ] = { + title = "Enchat", + icon = "\030e\031f\151\030f\031e\156\0311\140\0314\140\0315\140\031d\140\031b\140\031a\132\ +\030f\0314\128\030e\031f\132\030f\031e\132\0318nchat\ +\030f\031e\138\141\0311\140\0314\140\0315\132\0317v\03183\031a\132", + category = "Apps", + run = "https://raw.githubusercontent.com/LDDestroier/enchat/master/enchat3.lua", + }, [ "6ce6c512ea433a7fc5c8841628e7696cd0ff7f2b" ] = { title = "Files", category = "Apps", @@ -184,4 +200,12 @@ \0317\130\143\0307\128\128\128\128\030f\143\129", run = "/rom/programs/fun/dj", }, + [ "76b849f460640bc789c433894382fb5acbac42a2" ] = { + title = "Tron", + category = "Games", + iconExt = "\030 \031f\0305\031f\151\030f\0315\135\131\0305\031f\146\ +\030 \031f\030f\0315\130\141\0305\031f\139\030f\0315\130\ +\030 \031f\0305\031f\146\143\030f\0315\158\031e\130", + run = "https://raw.githubusercontent.com/LDDestroier/CC/master/tron", + }, } From 407b9f38fed4cdc24e21e35906ec9814c075c6e2 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sun, 18 Nov 2018 11:11:58 -0500 Subject: [PATCH 29/50] reenable storage manager --- sys/packageList.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/packageList.lua b/sys/packageList.lua index 99ddd82..1abc2ec 100644 --- a/sys/packageList.lua +++ b/sys/packageList.lua @@ -2,12 +2,12 @@ [ 'core' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/core/.package', [ 'builder' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/builder/.package', [ 'farms' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/farms/.package', - [ 'forestry' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/forestry/.package', - [ 'glasses' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/glasses/.package', +-- [ 'forestry' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/forestry/.package', +-- [ 'glasses' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/glasses/.package', [ 'milo' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/milo/.package', [ 'miners' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/miners/.package', - [ 'neural' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/neural/.package', - [ 'pickup' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/pickup/.package', - [ 'recipeBook' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/recipeBook/.package', - [ 'storage' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/storage/.package', +-- [ 'neural' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/neural/.package', +-- [ 'pickup' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/pickup/.package', +-- [ 'recipeBook' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/recipeBook/.package', + [ 'storage' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/storageManager/.package', } \ No newline at end of file From 3b0ac4e338f28e20f6c904f0d05c82e08fef298a Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Wed, 21 Nov 2018 09:24:55 -0500 Subject: [PATCH 30/50] new release prep --- sys/packageList.lua | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 sys/packageList.lua diff --git a/sys/packageList.lua b/sys/packageList.lua deleted file mode 100644 index 1abc2ec..0000000 --- a/sys/packageList.lua +++ /dev/null @@ -1,13 +0,0 @@ -{ - [ 'core' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/core/.package', - [ 'builder' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/builder/.package', - [ 'farms' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/farms/.package', --- [ 'forestry' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/forestry/.package', --- [ 'glasses' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/glasses/.package', - [ 'milo' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/milo/.package', - [ 'miners' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/miners/.package', --- [ 'neural' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/neural/.package', --- [ 'pickup' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/pickup/.package', --- [ 'recipeBook' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/recipeBook/.package', - [ 'storage' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/storageManager/.package', -} \ No newline at end of file From 99687c3d28775f5befc9b2105b094882bfa940a8 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Wed, 21 Nov 2018 12:10:20 -0500 Subject: [PATCH 31/50] new release prep --- sys/apis/packages.lua | 12 ++++++++---- sys/extensions/4.user.lua | 11 +++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/sys/apis/packages.lua b/sys/apis/packages.lua index ba671c5..f8d2aa1 100644 --- a/sys/apis/packages.lua +++ b/sys/apis/packages.lua @@ -1,6 +1,6 @@ local Util = require('util') -local fs = _G.fs +local fs = _G.fs local textutils = _G.textutils local PACKAGE_DIR = 'packages' @@ -24,7 +24,7 @@ function Packages:list() if self.packageList then return self.packageList end - self.packageList = Util.readTable('sys/packageList.lua') or { } + self.packageList = Util.readTable('usr/config/packages') or { } return self.packageList end @@ -42,9 +42,13 @@ function Packages:getManifest(package) local url = list and list[package] if url then - local c = Util.httpGet(url) -- will need to call load + local c = Util.httpGet(url) if c then - return textutils.unserialize(c) + c = textutils.unserialize(c) + if c then + c.repository = c.repository:gsub('{{OPUS_BRANCH}}', _G.OPUS_BRANCH) + return c + end end end end diff --git a/sys/extensions/4.user.lua b/sys/extensions/4.user.lua index e7dfa61..662fc6f 100644 --- a/sys/extensions/4.user.lua +++ b/sys/extensions/4.user.lua @@ -24,6 +24,17 @@ if not fs.exists('usr/config/shell') then }) end +if not fs.exists('usr/config/packages') then + local packages = { + [ 'develop-1.8' ] = 'https://pastebin.com/raw/WhEiNGZE', + [ 'master-1.8' ] = 'https://pastebin.com/raw/pexZpAxt', + } + + if packages[_G.OPUS_BRANCH] then + Util.download(packages[_G.OPUS_BRANCH], 'usr/config/packages') + end +end + local config = Util.readTable('usr/config/shell') if config.aliases then for k in pairs(shell.aliases()) do From 39e83075116a4d535cc107d98f5b875b334e9f90 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Wed, 21 Nov 2018 22:06:00 -0500 Subject: [PATCH 32/50] update rabbit --- sys/apis/ui.lua | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/sys/apis/ui.lua b/sys/apis/ui.lua index e022b2f..0b51ab1 100644 --- a/sys/apis/ui.lua +++ b/sys/apis/ui.lua @@ -2592,9 +2592,10 @@ UI.Throttle = class(UI.Window) UI.Throttle.defaults = { UIElement = 'Throttle', backgroundColor = colors.gray, - height = 6, + bordercolor = colors.cyan, + height = 4, width = 10, - timeout = .095, + timeout = .075, ctr = 0, image = { ' //) (O )~@ &~&-( ?Q ', @@ -2610,6 +2611,7 @@ function UI.Throttle:setParent() end function UI.Throttle:enable() + self.c = os.clock() self.enabled = false end @@ -2618,27 +2620,26 @@ function UI.Throttle:disable() self.enabled = false self.canvas:removeLayer() self.canvas = nil - self.c = nil + self.ctr = 0 end end function UI.Throttle:update() local cc = os.clock() - if not self.c then - self.c = cc - elseif cc > self.c + self.timeout then + if cc > self.c + self.timeout then os.sleep(0) self.c = os.clock() self.enabled = true if not self.canvas then - self.canvas = self:addLayer(self.backgroundColor, colors.cyan) + self.canvas = self:addLayer(self.backgroundColor, self.borderColor) self.canvas:setVisible(true) - self:clear(colors.cyan) + self:clear(self.borderColor) end local image = self.image[self.ctr + 1] local width = self.width - 2 for i = 0, #self.image do - self:write(2, i + 2, image:sub(width * i + 1, width * i + width), colors.black, colors.white) + self:write(2, i + 1, image:sub(width * i + 1, width * i + width), + self.backgroundColor, self.textColor) end self.ctr = (self.ctr + 1) % #self.image From d5896ca873f7a1779502c6e083358ae59026ed02 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Thu, 22 Nov 2018 13:52:45 -0500 Subject: [PATCH 33/50] reduce coroutine creation --- sys/apis/event.lua | 53 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/sys/apis/event.lua b/sys/apis/event.lua index ad0715f..e228e5e 100644 --- a/sys/apis/event.lua +++ b/sys/apis/event.lua @@ -1,4 +1,5 @@ -local os = _G.os +local os = _G.os +local table = _G.table local Event = { uid = 1, -- unique id for handlers @@ -6,8 +7,29 @@ local Event = { types = { }, -- event handlers timers = { }, -- named timers terminate = false, + free = { }, } +-- Use a pool of coroutines for event handlers +local function createCoroutine(h) + local co = table.remove(Event.free) + if not co then + co = coroutine.create(function(_, ...) + local args = { ... } + while true do + h.fn(table.unpack(args)) + h.co = nil + table.insert(Event.free, co) + args = { coroutine.yield() } + h = table.remove(args, 1) + h.co = co + end + end) + end + h.primeCo = true -- TODO: fix... + return co +end + local Routine = { } function Routine:isDead() @@ -24,18 +46,20 @@ function Routine:terminate() end function Routine:resume(event, ...) - --if coroutine.status(self.co) == 'running' then - --return - --end - if not self.co then error('Cannot resume a dead routine') end if not self.filter or self.filter == event or event == "terminate" then - local s, m = coroutine.resume(self.co, event, ...) - - if coroutine.status(self.co) == 'dead' then + local s, m + if self.primeCo then + -- Only need self passed when using a coroutine from the pool + s, m = coroutine.resume(self.co, self, event, ...) + self.primeCo = nil + else + s, m = coroutine.resume(self.co, event, ...) + end + if self:isDead() then self.co = nil self.filter = nil Event.routines[self.uid] = nil @@ -83,8 +107,12 @@ end function Event.off(h) if h and h.event then for _,event in pairs(h.event) do + local handler = Event.types[event][h.uid] + handler:terminate() Event.types[event][h.uid] = nil end + elseif h and h.co then + h:terminate() end end @@ -107,7 +135,12 @@ local function addTimer(interval, recurring, fn) end function Event.onInterval(interval, fn) - return addTimer(interval, true, fn) + return Event.addRoutine(function() + while true do + os.sleep(interval) + fn() + end + end) end function Event.onTimeout(timeout, fn) @@ -183,7 +216,7 @@ local function processHandlers(event) for _,h in pairs(handlers) do if not h.co then -- callbacks are single threaded (only 1 co per handler) - h.co = coroutine.create(h.fn) + h.co = createCoroutine(h) Event.routines[h.uid] = h end end From 9c43a261a8d43d0396ae30a8146bd5a3e91424ab Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Thu, 22 Nov 2018 19:57:00 -0500 Subject: [PATCH 34/50] reduce coroutine creation --- sys/apis/event.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/apis/event.lua b/sys/apis/event.lua index e228e5e..2a66542 100644 --- a/sys/apis/event.lua +++ b/sys/apis/event.lua @@ -108,7 +108,9 @@ function Event.off(h) if h and h.event then for _,event in pairs(h.event) do local handler = Event.types[event][h.uid] - handler:terminate() + if handler then + handler:terminate() + end Event.types[event][h.uid] = nil end elseif h and h.co then From 95178b04521eeac66d363988f56c5af33393053f Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Fri, 23 Nov 2018 11:57:32 -0500 Subject: [PATCH 35/50] package manager fix --- sys/apis/packages.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/apis/packages.lua b/sys/apis/packages.lua index f8d2aa1..6379e1a 100644 --- a/sys/apis/packages.lua +++ b/sys/apis/packages.lua @@ -13,7 +13,11 @@ function Packages:installed() if fs.exists(PACKAGE_DIR) then for _, dir in pairs(fs.list(PACKAGE_DIR)) do local path = fs.combine(fs.combine(PACKAGE_DIR, dir), '.package') - self.cache[dir] = Util.readTable(path) + local c = Util.readTable(path) + if c then + c.repository = c.repository:gsub('{{OPUS_BRANCH}}', _G.OPUS_BRANCH) + self.cache[dir] = c + end end end From 0545ff0c68acd2331d457d9d0086b27035d99beb Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Fri, 23 Nov 2018 12:14:47 -0500 Subject: [PATCH 36/50] package manager fix --- sys/apis/packages.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/apis/packages.lua b/sys/apis/packages.lua index 6379e1a..ae7375a 100644 --- a/sys/apis/packages.lua +++ b/sys/apis/packages.lua @@ -13,11 +13,7 @@ function Packages:installed() if fs.exists(PACKAGE_DIR) then for _, dir in pairs(fs.list(PACKAGE_DIR)) do local path = fs.combine(fs.combine(PACKAGE_DIR, dir), '.package') - local c = Util.readTable(path) - if c then - c.repository = c.repository:gsub('{{OPUS_BRANCH}}', _G.OPUS_BRANCH) - self.cache[dir] = c - end + self.cache[dir] = Util.readTable(path) end end @@ -40,7 +36,11 @@ end function Packages:getManifest(package) local fname = 'packages/' .. package .. '/.package' if fs.exists(fname) then - return Util.readTable(fname) + local c = Util.readTable(fname) + if c then + c.repository = c.repository:gsub('{{OPUS_BRANCH}}', _G.OPUS_BRANCH) + return c + end end local list = self:list() local url = list and list[package] From a0d47a5f1a3e963778636531f5b5183cea398168 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sat, 24 Nov 2018 21:45:10 -0500 Subject: [PATCH 37/50] allow up to 10 sec diff in connect time due to clock mismatch in dims --- sys/apis/point.lua | 7 +++++++ sys/apis/socket.lua | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/sys/apis/point.lua b/sys/apis/point.lua index 9eca46d..1d83eab 100644 --- a/sys/apis/point.lua +++ b/sys/apis/point.lua @@ -48,6 +48,13 @@ function Point.copy(pt) return { x = pt.x, y = pt.y, z = pt.z } end +function Point.round(pt) + pt.x = Util.round(pt.x) + pt.y = Util.round(pt.y) + pt.z = Util.round(pt.z) + return pt +end + function Point.same(pta, ptb) return pta.x == ptb.x and pta.y == ptb.y and diff --git a/sys/apis/socket.lua b/sys/apis/socket.lua index 7db64ae..9b91750 100644 --- a/sys/apis/socket.lua +++ b/sys/apis/socket.lua @@ -172,7 +172,7 @@ local function trusted(msg, port) local data = Crypto.decrypt(msg.t or '', pubKey) --local sharedKey = modexp(pubKey, exchange.secretKey, public.primeMod) - return data.ts and tonumber(data.ts) and math.abs(os.time() - data.ts) < 1 + return data.ts and tonumber(data.ts) and math.abs(os.time() - data.ts) < 10 end end From eb799004f8770c2ae75276e52e325244d60eac8f Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Mon, 26 Nov 2018 20:53:28 -0500 Subject: [PATCH 38/50] sounds --- sys/apis/socket.lua | 3 ++- sys/apis/sound.lua | 12 ++++++++++++ sys/apis/ui.lua | 2 ++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 sys/apis/sound.lua diff --git a/sys/apis/socket.lua b/sys/apis/socket.lua index 9b91750..bdd1ff5 100644 --- a/sys/apis/socket.lua +++ b/sys/apis/socket.lua @@ -81,7 +81,8 @@ local function loopback(port, sport, msg) end local function newSocket(isLoopback) - for i = 16384, 32767 do + for _ = 16384, 32767 do + local i = math.random(16384, 32767) if not device.wireless_modem.isOpen(i) then local socket = { shost = os.getComputerID(), diff --git a/sys/apis/sound.lua b/sys/apis/sound.lua new file mode 100644 index 0000000..888131a --- /dev/null +++ b/sys/apis/sound.lua @@ -0,0 +1,12 @@ +local peripheral = _G.peripheral +local speaker = peripheral.find('speaker') + +local Sound = { } + +function Sound.play(sound, vol) + if speaker then + speaker.playSound('minecraft:' .. sound, vol or 1) + end +end + +return Sound diff --git a/sys/apis/ui.lua b/sys/apis/ui.lua index 0b51ab1..4fd6bed 100644 --- a/sys/apis/ui.lua +++ b/sys/apis/ui.lua @@ -3,6 +3,7 @@ local class = require('class') local Event = require('event') local Input = require('input') local Peripheral = require('peripheral') +local Sound = require('sound') local Transition = require('ui.transition') local Util = require('util') @@ -2542,6 +2543,7 @@ end function UI.Notification:error(value, timeout) self.backgroundColor = colors.red + Sound.play('entity.villager.no', .5) self:display(value, timeout) end From 880a81f65515b894064f71f3a7136bb61fdb9bf6 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Thu, 29 Nov 2018 15:12:25 -0500 Subject: [PATCH 39/50] socket dim / clock issue --- sys/apis/socket.lua | 2 +- sys/apis/sound.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/apis/socket.lua b/sys/apis/socket.lua index bdd1ff5..7926234 100644 --- a/sys/apis/socket.lua +++ b/sys/apis/socket.lua @@ -173,7 +173,7 @@ local function trusted(msg, port) local data = Crypto.decrypt(msg.t or '', pubKey) --local sharedKey = modexp(pubKey, exchange.secretKey, public.primeMod) - return data.ts and tonumber(data.ts) and math.abs(os.time() - data.ts) < 10 + return data.ts and tonumber(data.ts) and math.abs(os.time() - data.ts) < 24 end end diff --git a/sys/apis/sound.lua b/sys/apis/sound.lua index 888131a..28ca11c 100644 --- a/sys/apis/sound.lua +++ b/sys/apis/sound.lua @@ -1,9 +1,9 @@ local peripheral = _G.peripheral -local speaker = peripheral.find('speaker') local Sound = { } function Sound.play(sound, vol) + local speaker = peripheral.find('speaker') if speaker then speaker.playSound('minecraft:' .. sound, vol or 1) end From beae4e6eafc6acd0b234e49406cd18d01b2b9209 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Fri, 30 Nov 2018 04:53:59 -0500 Subject: [PATCH 40/50] grid sort event --- sys/apis/ui.lua | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/sys/apis/ui.lua b/sys/apis/ui.lua index 4fd6bed..668aa80 100644 --- a/sys/apis/ui.lua +++ b/sys/apis/ui.lua @@ -1266,6 +1266,7 @@ UI.Grid.defaults = { backgroundSelectedColor = colors.gray, headerBackgroundColor = colors.cyan, headerTextColor = colors.white, + headerSortColor = colors.yellow, unfocusedTextSelectedColor = colors.white, unfocusedBackgroundSelectedColor = colors.gray, focusIndicator = '>', @@ -1482,7 +1483,7 @@ function UI.Grid:update() end function UI.Grid:drawHeadings() - local sb = UI.StringBuffer(self.width) + local x = 1 for _,col in ipairs(self.columns) do local ind = ' ' if col.key == self.sortColumn then @@ -1492,9 +1493,13 @@ function UI.Grid:drawHeadings() ind = self.sortIndicator end end - sb:insert(ind .. col.heading, col.cw + 1) + self:write(x, + 1, + Util.widthify(ind .. col.heading, col.cw + 1), + self.headerBackgroundColor, + col.key == self.sortColumn and self.headerSortColor or self.headerTextColor) + x = x + col.cw + 1 end - self:write(1, 1, sb:get(), self.headerBackgroundColor, self.headerTextColor) end function UI.Grid:sortCompare(a, b) @@ -1636,13 +1641,12 @@ function UI.Grid:eventHandler(event) local col = 2 for _,c in ipairs(self.columns) do if event.x < col + c.cw then - if self.sortColumn == c.key then - self:setInverseSort(not self.inverseSort) - else - self.sortColumn = c.key - self:setInverseSort(false) - end - self:draw() + self:emit({ + type = 'grid_sort', + sortColumn = c.key, + inverseSort = self.sortColumn == c.key and not self.inverseSort, + element = self, + }) break end col = col + c.cw + 1 @@ -1665,6 +1669,10 @@ function UI.Grid:eventHandler(event) end return false + elseif event.type == 'grid_sort' then + self.sortColumn = event.sortColumn + self:setInverseSort(event.inverseSort) + self:draw() elseif event.type == 'scroll_down' then self:setIndex(self.index + 1) elseif event.type == 'scroll_up' then From 1fb5379b119a1bb423f39fdaa821e257cb9b0d21 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sat, 1 Dec 2018 00:55:42 -0500 Subject: [PATCH 41/50] grid setSelected, update tron url/icon --- sys/apis/ui.lua | 27 +++++++++++++-------------- sys/apis/ui/canvas.lua | 4 ++-- sys/etc/app.db | 8 ++++---- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/sys/apis/ui.lua b/sys/apis/ui.lua index 668aa80..b2a585e 100644 --- a/sys/apis/ui.lua +++ b/sys/apis/ui.lua @@ -1424,6 +1424,18 @@ function UI.Grid:getSelected() end end +function UI.Grid:setSelected(name, value) + if self.sorted then + for k,v in pairs(self.sorted) do + if self.values[v][name] == value then + self:setIndex(k) + return + end + end + end + self:setIndex(1) +end + function UI.Grid:focus() self:drawRows() end @@ -1465,14 +1477,7 @@ function UI.Grid:update() end end - self.sorted = { } - for k,v in pairs(self.values) do - if self:isRowValid(k, v) then - table.insert(self.sorted, k) - end - end - - --self.sorted = Util.keys(self.values) + self.sorted = Util.keys(self.values) if order then table.sort(self.sorted, function(a,b) return order(self.values[a], self.values[b]) @@ -1558,12 +1563,6 @@ function UI.Grid:drawRows() end end --- Non-intuitive: update must be called if the table was specified --- in the shortcut definition (as this callback was not yet overridden) -function UI.Grid:isRowValid(--[[ key, value ]]) - return true -end - function UI.Grid:getRowTextColor(row, selected) if selected then if self.focused then diff --git a/sys/apis/ui/canvas.lua b/sys/apis/ui/canvas.lua index baa011c..ea45ecf 100644 --- a/sys/apis/ui/canvas.lua +++ b/sys/apis/ui/canvas.lua @@ -137,7 +137,7 @@ function Canvas:writeBlit(x, y, text, bg, fg) if bg then bg = _sub(bg, 2 - x) end - if bg then + if fg then fg = _sub(fg, 2 - x) end width = width + x - 1 @@ -149,7 +149,7 @@ function Canvas:writeBlit(x, y, text, bg, fg) if bg then bg = _sub(bg, 1, self.width - x + 1) end - if bg then + if fg then fg = _sub(fg, 1, self.width - x + 1) end width = #text diff --git a/sys/etc/app.db b/sys/etc/app.db index 22b2c17..353b20b 100644 --- a/sys/etc/app.db +++ b/sys/etc/app.db @@ -203,9 +203,9 @@ [ "76b849f460640bc789c433894382fb5acbac42a2" ] = { title = "Tron", category = "Games", - iconExt = "\030 \031f\0305\031f\151\030f\0315\135\131\0305\031f\146\ -\030 \031f\030f\0315\130\141\0305\031f\139\030f\0315\130\ -\030 \031f\0305\031f\146\143\030f\0315\158\031e\130", - run = "https://raw.githubusercontent.com/LDDestroier/CC/master/tron", + iconExt = "\030 \031f\030b\031f\143\030f\128\128\030b\143\143\143\030f\128\128\ +\030 \031f\0309\031b\140\030b\031f\151\030f\031b\131\0307\148\0317\128\030b\151\030f\031b\131\148\ +\030 \031f\030f\031b\131\031f\128\031b\131\0317\131\031f\128\0317\131\031b\131\031f\128", + run = "https://raw.githubusercontent.com/LDDestroier/CC/master/tron.lua", }, } From 34c653ca1b6ba58bceb175a57eab129733ced58b Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sat, 1 Dec 2018 19:09:24 -0500 Subject: [PATCH 42/50] manipulator device driver --- sys/apis/peripheral.lua | 24 ++++++++------- sys/extensions/1.device.lua | 58 +++++++++++++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 13 deletions(-) diff --git a/sys/apis/peripheral.lua b/sys/apis/peripheral.lua index e4638d7..33a1df1 100644 --- a/sys/apis/peripheral.lua +++ b/sys/apis/peripheral.lua @@ -55,19 +55,21 @@ function Peripheral.addDevice(deviceList, side) end -- this can randomly fail - pcall(function() - deviceList[name] = Peripheral.wrap(side) - end) + if not deviceList[name] then + pcall(function() + deviceList[name] = Peripheral.wrap(side) + end) - if deviceList[name] then - Util.merge(deviceList[name], { - name = name, - type = ptype, - side = side, - }) - - return deviceList[name] + if deviceList[name] then + Util.merge(deviceList[name], { + name = name, + type = ptype, + side = side, + }) + end end + + return deviceList[name] end function Peripheral.getBySide(side) diff --git a/sys/extensions/1.device.lua b/sys/extensions/1.device.lua index 2ec843a..0bc80c3 100644 --- a/sys/extensions/1.device.lua +++ b/sys/extensions/1.device.lua @@ -33,12 +33,25 @@ local keyboard = _G.device.keyboard local mouse = _G.device.mouse local os = _G.os +local drivers = { } + kernel.hook('peripheral', function(_, eventData) local side = eventData[1] if side then local dev = Peripheral.addDevice(device, side) if dev then - os.queueEvent('device_attach', dev.name) + if drivers[dev.type] then + local e = drivers[dev.type](dev) + if type(e) == 'table' then + for _, v in pairs(e) do + os.queueEvent('device_attach', v.name) + end + elseif e then + os.queueEvent('device_attach', e.name) + end + end + + os.queueEvent('device_attach', dev.name, dev) end end end) @@ -48,7 +61,12 @@ kernel.hook('peripheral_detach', function(_, eventData) if side then local dev = Util.find(device, 'side', side) if dev then - os.queueEvent('device_detach', dev.name) + os.queueEvent('device_detach', dev.name, dev) + if dev._children then + for _,v in pairs(dev._children) do + os.queueEvent('peripheral_detach', v.name) + end + end device[dev.name] = nil end end @@ -109,3 +127,39 @@ kernel.hook('monitor_touch', function(event, eventData) return true -- stop propagation end end) + +local function createDevice(name, devType, methods, parent) + methods.name = name + methods.side = name + methods.type = devType + device[name] = methods + + if not parent._children then + parent._children = { methods } + else + table.insert(parent._children, methods) + end +end + +drivers['manipulator'] = function(dev) + pcall(function() + local name = dev.getName() + if dev.getInventory then + createDevice(name .. ':inventory', 'inventory', dev.getInventory(), dev) + end + if dev.getEquipment then + createDevice(name .. ':equipment', 'equipment', dev.getEquipment(), dev) + end + if dev.getEnder then + createDevice(name .. ':enderChest', 'enderChest', dev.getEnder(), dev) + end + end) + return dev._children +end + +-- initialize drivers +for _,v in pairs(device) do + if drivers[v.type] then + drivers[v.type](v) + end +end From c5a821f26463633015862fc5ab97cd0d1c14b25f Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sun, 2 Dec 2018 14:35:58 -0500 Subject: [PATCH 43/50] manipulator :( --- sys/extensions/1.device.lua | 55 ++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/sys/extensions/1.device.lua b/sys/extensions/1.device.lua index 0bc80c3..9da4d3d 100644 --- a/sys/extensions/1.device.lua +++ b/sys/extensions/1.device.lua @@ -128,32 +128,43 @@ kernel.hook('monitor_touch', function(event, eventData) end end) -local function createDevice(name, devType, methods, parent) - methods.name = name - methods.side = name - methods.type = devType - device[name] = methods - - if not parent._children then - parent._children = { methods } - else - table.insert(parent._children, methods) +local function createDevice(name, devType, method, manipulator) + local dev = { + name = name, + side = name, + type = devType, + } + local methods = { + 'drop', 'getDocs', 'getItem', 'getItemMeta', 'getTransferLocations', + 'list', 'pullItems', 'pushItems', 'size', 'suck', + } + if manipulator[method] then + for _,k in pairs(methods) do + dev[k] = function(...) + return manipulator[method]()[k](...) + end + end + if not manipulator._children then + manipulator._children = { dev } + else + table.insert(manipulator._children, dev) + end + device[name] = dev end end drivers['manipulator'] = function(dev) - pcall(function() - local name = dev.getName() - if dev.getInventory then - createDevice(name .. ':inventory', 'inventory', dev.getInventory(), dev) - end - if dev.getEquipment then - createDevice(name .. ':equipment', 'equipment', dev.getEquipment(), dev) - end - if dev.getEnder then - createDevice(name .. ':enderChest', 'enderChest', dev.getEnder(), dev) - end - end) + local name = dev.getName() + if dev.getInventory then + createDevice(name .. ':inventory', 'inventory', 'getInventory', dev) + end + if dev.getEquipment then + createDevice(name .. ':equipment', 'equipment', 'getEquipment', dev) + end + if dev.getEnder then + createDevice(name .. ':enderChest', 'enderChest', 'getEnder', dev) + end + return dev._children end From 2517612622267fa594c7c8a031c0232f70b09c71 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sun, 2 Dec 2018 15:10:21 -0500 Subject: [PATCH 44/50] manipulator :( --- sys/extensions/1.device.lua | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/sys/extensions/1.device.lua b/sys/extensions/1.device.lua index 9da4d3d..e2e39f1 100644 --- a/sys/extensions/1.device.lua +++ b/sys/extensions/1.device.lua @@ -154,18 +154,20 @@ local function createDevice(name, devType, method, manipulator) end drivers['manipulator'] = function(dev) - local name = dev.getName() - if dev.getInventory then - createDevice(name .. ':inventory', 'inventory', 'getInventory', dev) - end - if dev.getEquipment then - createDevice(name .. ':equipment', 'equipment', 'getEquipment', dev) - end - if dev.getEnder then - createDevice(name .. ':enderChest', 'enderChest', 'getEnder', dev) - end + if dev.getName then + local name = dev.getName() + if dev.getInventory then + createDevice(name .. ':inventory', 'inventory', 'getInventory', dev) + end + if dev.getEquipment then + createDevice(name .. ':equipment', 'equipment', 'getEquipment', dev) + end + if dev.getEnder then + createDevice(name .. ':enderChest', 'enderChest', 'getEnder', dev) + end - return dev._children + return dev._children + end end -- initialize drivers From c9a42e2502810cc89d764d88466f4c0232b41e09 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sun, 2 Dec 2018 18:40:19 -0500 Subject: [PATCH 45/50] transport timeout on dead process --- sys/network/transport.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/network/transport.lua b/sys/network/transport.lua index 48d7a62..2eeb801 100644 --- a/sys/network/transport.lua +++ b/sys/network/transport.lua @@ -79,8 +79,11 @@ Event.on('modem_message', function(_, _, dport, dhost, msg, distance) if socket and socket.connected then --if msg.type then _debug('<< ' .. Util.tostring(msg)) end + if socket.co and coroutine.status(socket.co) == 'dead' then + _G._debug('socket coroutine dead') + socket:close() - if msg.type == 'DISC' then + elseif msg.type == 'DISC' then -- received disconnect from other end if socket.connected then os.queueEvent('transport_' .. socket.uid) From 0e3fb88f1dd243dc2d02aa8af89f07231212ad2b Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Tue, 4 Dec 2018 01:33:58 -0500 Subject: [PATCH 46/50] set sound volume --- sys/apis/sound.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sys/apis/sound.lua b/sys/apis/sound.lua index 28ca11c..b4dab46 100644 --- a/sys/apis/sound.lua +++ b/sys/apis/sound.lua @@ -1,12 +1,18 @@ local peripheral = _G.peripheral -local Sound = { } +local Sound = { + _volume = 1, +} function Sound.play(sound, vol) local speaker = peripheral.find('speaker') if speaker then - speaker.playSound('minecraft:' .. sound, vol or 1) + speaker.playSound('minecraft:' .. sound, vol or Sound._volume) end end +function Sound.setVolume(volume) + Sound._volume = math.max(0, math.min(volume, 1)) +end + return Sound From 7d17a21aa41a5164c218183041ca4a6c7c232350 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Tue, 4 Dec 2018 20:55:08 -0500 Subject: [PATCH 47/50] rework wizard page handling --- sys/apis/ui.lua | 59 ++++++++++++++++++------------------------------- 1 file changed, 22 insertions(+), 37 deletions(-) diff --git a/sys/apis/ui.lua b/sys/apis/ui.lua index b2a585e..dffb370 100644 --- a/sys/apis/ui.lua +++ b/sys/apis/ui.lua @@ -944,6 +944,7 @@ function UI.Device:postInit() end function UI.Device:resize() + self.device.setTextScale(self.textScale) self.width, self.height = self.device.getSize() self.lines = { } self.canvas:resize(self.width, self.height) @@ -2328,61 +2329,45 @@ function UI.Wizard:add(pages) end end +function UI.Wizard:getPage(index) + return Util.find(self.pages, 'index', index) +end + function UI.Wizard:enable(...) self.enabled = true - for _,child in ipairs(self.children) do - if not child.index then - child:enable(...) - elseif child.index == 1 then + self.index = 1 + local initial = self:getPage(1) + for _,child in pairs(self.children) do + if child == initial or not child.index then child:enable(...) else child:disable() end end - self:emit({ type = 'enable_view', next = Util.find(self.pages, 'index', 1) }) -end - -function UI.Wizard:nextView() - local currentView = Util.find(self.pages, 'enabled', true) - local nextView = Util.find(self.pages, 'index', currentView.index + 1) - - if nextView then - self:emit({ type = 'enable_view', view = nextView }) - self:addTransition('slideLeft') - currentView:disable() - nextView:enable() - end -end - -function UI.Wizard:prevView() - local currentView = Util.find(self.pages, 'enabled', true) - local nextView = Util.find(self.pages, 'index', currentView.index - 1) - - if nextView then - self:emit({ type = 'enable_view', view = nextView }) - self:addTransition('slideRight') - currentView:disable() - nextView:enable() - end + self:emit({ type = 'enable_view', next = initial }) end function UI.Wizard:isViewValid() - local currentView = Util.find(self.pages, 'enabled', true) + local currentView = self:getPage(self.index) return not currentView.validate and true or currentView:validate() end function UI.Wizard:eventHandler(event) if event.type == 'nextView' then - local currentView = Util.find(self.pages, 'enabled', true) + local currentView = self:getPage(self.index) if self:isViewValid() then - local nextView = Util.find(self.pages, 'index', currentView.index + 1) + self.index = self.index + 1 + local nextView = self:getPage(self.index) currentView:emit({ type = 'enable_view', next = nextView, current = currentView }) end elseif event.type == 'previousView' then - local currentView = Util.find(self.pages, 'enabled', true) - local nextView = Util.find(self.pages, 'index', currentView.index - 1) - currentView:emit({ type = 'enable_view', prev = nextView, current = currentView }) + local currentView = self:getPage(self.index) + local nextView = self:getPage(self.index - 1) + if nextView then + self.index = self.index - 1 + currentView:emit({ type = 'enable_view', prev = nextView, current = currentView }) + end return true elseif event.type == 'wizard_complete' then @@ -2403,13 +2388,13 @@ function UI.Wizard:eventHandler(event) local current = event.next or event.prev if not current then error('property "index" is required on wizard pages') end - if Util.find(self.pages, 'index', current.index - 1) then + if self:getPage(self.index - 1) then self.previousButton:enable() else self.previousButton:disable() end - if Util.find(self.pages, 'index', current.index + 1) then + if self:getPage(self.index + 1) then self.nextButton.text = 'Next >' self.nextButton.event = 'nextView' else From 72142e12cca456c574030b2b1a699f76bed5dc04 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Tue, 4 Dec 2018 21:16:48 -0500 Subject: [PATCH 48/50] toggle show trusted in network app --- sys/apps/Network.lua | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/sys/apps/Network.lua b/sys/apps/Network.lua index e6d50c4..04e223a 100644 --- a/sys/apps/Network.lua +++ b/sys/apps/Network.lua @@ -1,5 +1,6 @@ _G.requireInjector(_ENV) +local Config = require('config') local Event = require('event') local Socket = require('socket') local UI = require('ui') @@ -20,6 +21,9 @@ local gridColumns = { { heading = 'Status', key = 'status' }, } +local trusted = Util.readTable('usr/.known_hosts') +local config = Config.load('network', { }) + if UI.term.width >= 30 then table.insert(gridColumns, { heading = 'Fuel', key = 'fuel', width = 5 }) table.insert(gridColumns, { heading = 'Uptime', key = 'uptime' }) @@ -40,6 +44,15 @@ local page = UI.Page { { text = 'Remove', event = 'untrust' }, } }, { text = 'Help', event = 'help' }, + { + text = '\206', + x = -3, + dropdown = { + { text = 'Show all', event = 'show_all' }, + UI.MenuBar.spacer, + { text = 'Show trusted', event = 'show_trusted' }, + }, + }, }, }, grid = UI.ScrollingGrid { @@ -143,6 +156,15 @@ This only needs to be done once. q = 'cancel', } }) + + elseif event.type == 'show_all' then + config.showTrusted = false + Config.update('network', config) + + elseif event.type == 'show_trusted' then + config.showTrusted = true + Config.update('network', config) + elseif event.type == 'quit' then Event.exitPullEvents() end @@ -184,7 +206,17 @@ function page.grid:getDisplayValues(row) end Event.onInterval(1, function() - page.grid:update() + local t = { } + if config.showTrusted then + for k,v in pairs(network) do + if trusted[k] then + t[k] = v + end + end + page.grid:setValues(t) + else + page.grid:update() + end page.grid:draw() page:sync() end) From 6674c715e061d87dcf3ce60cf9fa9159027896ab Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Wed, 5 Dec 2018 21:21:30 -0500 Subject: [PATCH 49/50] pcall driver init --- sys/apps/Network.lua | 9 +++++---- sys/extensions/1.device.lua | 5 ++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/sys/apps/Network.lua b/sys/apps/Network.lua index 04e223a..0fceb8c 100644 --- a/sys/apps/Network.lua +++ b/sys/apps/Network.lua @@ -43,14 +43,14 @@ local page = UI.Page { { text = 'Establish', event = 'trust' }, { text = 'Remove', event = 'untrust' }, } }, - { text = 'Help', event = 'help' }, + { text = 'Help', event = 'help', noCheck = true }, { text = '\206', x = -3, dropdown = { - { text = 'Show all', event = 'show_all' }, + { text = 'Show all', event = 'show_all', noCheck = true }, UI.MenuBar.spacer, - { text = 'Show trusted', event = 'show_trusted' }, + { text = 'Show trusted', event = 'show_trusted', noCheck = true }, }, }, }, @@ -159,6 +159,7 @@ This only needs to be done once. elseif event.type == 'show_all' then config.showTrusted = false + self.grid:setValues(network) Config.update('network', config) elseif event.type == 'show_trusted' then @@ -177,7 +178,7 @@ function page.menuBar:getActive(menuItem) local trustList = Util.readTable('usr/.known_hosts') or { } return t and trustList[t.id] end - return not not t + return menuItem.noCheck or not not t end function page.grid:getRowTextColor(row, selected) diff --git a/sys/extensions/1.device.lua b/sys/extensions/1.device.lua index e2e39f1..4eabc34 100644 --- a/sys/extensions/1.device.lua +++ b/sys/extensions/1.device.lua @@ -173,6 +173,9 @@ end -- initialize drivers for _,v in pairs(device) do if drivers[v.type] then - drivers[v.type](v) + local s, m = pcall(drivers[v.type], v) + if not s and m then + _G.printError(m) + end end end From 00fea37f3f733b7a4d12424e9eaac979c152d8ec Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Thu, 6 Dec 2018 23:13:43 -0500 Subject: [PATCH 50/50] manipulators! --- sys/extensions/1.device.lua | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/sys/extensions/1.device.lua b/sys/extensions/1.device.lua index 4eabc34..003ae14 100644 --- a/sys/extensions/1.device.lua +++ b/sys/extensions/1.device.lua @@ -155,18 +155,23 @@ end drivers['manipulator'] = function(dev) if dev.getName then - local name = dev.getName() - if dev.getInventory then - createDevice(name .. ':inventory', 'inventory', 'getInventory', dev) - end - if dev.getEquipment then - createDevice(name .. ':equipment', 'equipment', 'getEquipment', dev) - end - if dev.getEnder then - createDevice(name .. ':enderChest', 'enderChest', 'getEnder', dev) - end + local name + pcall(function() + name = dev.getName() + end) + if name then + if dev.getInventory then + createDevice(name .. ':inventory', 'inventory', 'getInventory', dev) + end + if dev.getEquipment then + createDevice(name .. ':equipment', 'equipment', 'getEquipment', dev) + end + if dev.getEnder then + createDevice(name .. ':enderChest', 'enderChest', 'getEnder', dev) + end - return dev._children + return dev._children + end end end