1
0
mirror of https://github.com/kepler155c/opus synced 2025-02-02 10:29:09 +00:00
This commit is contained in:
kepler155c@gmail.com 2017-10-08 17:45:01 -04:00
parent 98ec840db1
commit a625b52bad
46 changed files with 334 additions and 319 deletions

View File

@ -1,5 +1,5 @@
local Ansi = setmetatable({ }, { local Ansi = setmetatable({ }, {
__call = function(self, ...) __call = function(_, ...)
local str = '\027[' local str = '\027['
for k,v in ipairs({ ...}) do for k,v in ipairs({ ...}) do
if k == 1 then if k == 1 then

View File

@ -1,5 +1,7 @@
local Util = require('util') local Util = require('util')
local fs = _G.fs
local Config = { } local Config = { }
Config.load = function(fname, data) Config.load = function(fname, data)

View File

@ -1,3 +1,5 @@
local os = _G.os
local Event = { local Event = {
uid = 1, -- unique id for handlers uid = 1, -- unique id for handlers
routines = { }, -- coroutines routines = { }, -- coroutines
@ -123,13 +125,13 @@ function Event.waitForEvent(event, timeout)
local e = { os.pullEvent() } local e = { os.pullEvent() }
if e[1] == event then if e[1] == event then
return table.unpack(e) return table.unpack(e)
end end
until e[1] == 'timer' and e[2] == timerId until e[1] == 'timer' and e[2] == timerId
end end
function Event.addRoutine(fn) function Event.addRoutine(fn)
local r = { local r = {
co = coroutine.create(fn), co = coroutine.create(fn),
uid = nextUID() uid = nextUID()
} }
setmetatable(r, { __index = Routine }) setmetatable(r, { __index = Routine })

View File

@ -1,5 +1,7 @@
local git = require('git') local git = require('git')
local fs = _G.fs
local gitfs = { } local gitfs = { }
function gitfs.mount(dir, repo) function gitfs.mount(dir, repo)

View File

@ -1,6 +1,8 @@
local fs = _G.fs
local linkfs = { } local linkfs = { }
local methods = { 'exists', 'getFreeSpace', 'getSize', local methods = { 'exists', 'getFreeSpace', 'getSize',
'isDir', 'isReadOnly', 'list', 'listEx', 'makeDir', 'open', 'getDrive' } 'isDir', 'isReadOnly', 'list', 'listEx', 'makeDir', 'open', 'getDrive' }
for _,m in pairs(methods) do for _,m in pairs(methods) do
@ -10,7 +12,7 @@ for _,m in pairs(methods) do
end end
end end
function linkfs.mount(dir, source) function linkfs.mount(_, source)
if not source then if not source then
error('Source is required') error('Source is required')
end end
@ -23,7 +25,7 @@ function linkfs.mount(dir, source)
end end
return { return {
source = source source = source
} }
end end
function linkfs.copy(node, s, t) function linkfs.copy(node, s, t)

View File

@ -1,11 +1,13 @@
local Socket = require('socket') local Socket = require('socket')
local synchronized = require('sync') local synchronized = require('sync')
local fs = _G.fs
local netfs = { } local netfs = { }
local function remoteCommand(node, msg) local function remoteCommand(node, msg)
for i = 1, 2 do for _ = 1, 2 do
if not node.socket then if not node.socket then
node.socket = Socket.connect(node.id, 139) node.socket = Socket.connect(node.id, 139)
end end
@ -49,7 +51,7 @@ for _,m in pairs(methods) do
end end
end end
function netfs.mount(dir, id, directory) function netfs.mount(_, id, directory)
if not id or not tonumber(id) then if not id or not tonumber(id) then
error('ramfs syntax: computerId [directory]') error('ramfs syntax: computerId [directory]')
end end

View File

@ -1,8 +1,10 @@
local Util = require('util') local Util = require('util')
local fs = _G.fs
local ramfs = { } local ramfs = { }
function ramfs.mount(dir, nodeType) function ramfs.mount(_, nodeType)
if nodeType == 'directory' then if nodeType == 'directory' then
return { return {
nodes = { }, nodes = { },
@ -34,7 +36,7 @@ function ramfs.isReadOnly()
return false return false
end end
function ramfs.makeDir(node, dir) function ramfs.makeDir(_, dir)
fs.mount(dir, 'ramfs', 'directory') fs.mount(dir, 'ramfs', 'directory')
end end
@ -46,10 +48,10 @@ function ramfs.getDrive()
return 'ram' return 'ram'
end end
function ramfs.list(node, dir, full) function ramfs.list(node, dir)
if node.nodes and node.mountPoint == dir then if node.nodes and node.mountPoint == dir then
local files = { } local files = { }
for k,v in pairs(node.nodes) do for k in pairs(node.nodes) do
table.insert(files, k) table.insert(files, k)
end end
return files return files

View File

@ -1,9 +1,11 @@
local synchronized = require('sync') local synchronized = require('sync')
local Util = require('util') local Util = require('util')
local fs = _G.fs
local urlfs = { } local urlfs = { }
function urlfs.mount(dir, url) function urlfs.mount(_, url)
if not url then if not url then
error('URL is required') error('URL is required')
end end
@ -12,7 +14,7 @@ function urlfs.mount(dir, url)
} }
end end
function urlfs.delete(node, dir) function urlfs.delete(_, dir)
fs.unmount(dir) fs.unmount(dir)
end end

View File

@ -6,9 +6,9 @@ local FILE_URL = 'https://raw.githubusercontent.com/%s/%s/%s/%s'
local git = { } local git = { }
function git.list(repo) function git.list(repository)
local t = Util.split(repo, '(.-)/') local t = Util.split(repository, '(.-)/')
local user = t[1] local user = t[1]
local repo = t[2] local repo = t[2]
@ -33,7 +33,7 @@ function git.list(repo)
local list = { } local list = { }
for k,v in pairs(data.tree) do for _,v in pairs(data.tree) do
if v.type == "blob" then if v.type == "blob" then
v.path = v.path:gsub("%s","%%20") v.path = v.path:gsub("%s","%%20")
list[v.path] = { list[v.path] = {

View File

@ -1,5 +1,9 @@
local GPS = { } local GPS = { }
local device = _G.device
local gps = _G.gps
local turtle = _G.turtle
function GPS.locate(timeout, debug) function GPS.locate(timeout, debug)
local pt = { } local pt = { }
timeout = timeout or 10 timeout = timeout or 10
@ -14,7 +18,6 @@ function GPS.isAvailable()
end end
function GPS.getPoint(timeout, debug) function GPS.getPoint(timeout, debug)
local pt = GPS.locate(timeout, debug) local pt = GPS.locate(timeout, debug)
if not pt then if not pt then
return return
@ -24,7 +27,7 @@ function GPS.getPoint(timeout, debug)
pt.y = math.floor(pt.y) pt.y = math.floor(pt.y)
pt.z = math.floor(pt.z) pt.z = math.floor(pt.z)
if pocket then if _G.pocket then
pt.y = pt.y - 1 pt.y = pt.y - 1
end end
@ -47,7 +50,7 @@ function GPS.getHeading(timeout)
while not turtle.forward() do while not turtle.forward() do
turtle.turnRight() turtle.turnRight()
if turtle.getHeading() == heading then if turtle.getHeading() == heading then
printError('GPS.getPoint: Unable to move forward') _G.printError('GPS.getPoint: Unable to move forward')
return return
end end
end end
@ -79,13 +82,13 @@ function GPS.getPointAndHeading(timeout)
end end
-- from stock gps API -- from stock gps API
local function trilaterate( A, B, C ) local function trilaterate(A, B, C)
local a2b = B.position - A.position local a2b = B.position - A.position
local a2c = C.position - A.position local a2c = C.position - A.position
if math.abs( a2b:normalize():dot( a2c:normalize() ) ) > 0.999 then if math.abs( a2b:normalize():dot( a2c:normalize() ) ) > 0.999 then
return nil return
end end
local d = a2b:length() local d = a2b:length()
local ex = a2b:normalize( ) local ex = a2b:normalize( )
@ -100,22 +103,22 @@ local function trilaterate( A, B, C )
local x = (r1*r1 - r2*r2 + d*d) / (2*d) local x = (r1*r1 - r2*r2 + d*d) / (2*d)
local y = (r1*r1 - r3*r3 - x*x + (x-i)*(x-i) + j*j) / (2*j) local y = (r1*r1 - r3*r3 - x*x + (x-i)*(x-i) + j*j) / (2*j)
local result = A.position + (ex * x) + (ey * y) local result = A.position + (ex * x) + (ey * y)
local zSquared = r1*r1 - x*x - y*y local zSquared = r1*r1 - x*x - y*y
if zSquared > 0 then if zSquared > 0 then
local z = math.sqrt( zSquared ) local z = math.sqrt( zSquared )
local result1 = result + (ez * z) local result1 = result + (ez * z)
local result2 = result - (ez * z) local result2 = result - (ez * z)
local rounded1, rounded2 = result1:round(), result2:round() local rounded1, rounded2 = result1:round(), result2:round()
if rounded1.x ~= rounded2.x or rounded1.y ~= rounded2.y or rounded1.z ~= rounded2.z then if rounded1.x ~= rounded2.x or rounded1.y ~= rounded2.y or rounded1.z ~= rounded2.z then
return rounded1, rounded2 return rounded1, rounded2
else else
return rounded1 return rounded1
end end
end end
return result:round() return result:round()
end end
@ -129,7 +132,7 @@ local function narrow( p1, p2, fix )
return p1:round() return p1:round()
else else
return p2:round() return p2:round()
end end
end end
-- end stock gps api -- end stock gps api

View File

@ -2,6 +2,10 @@ local DEFAULT_UPATH = 'https://raw.githubusercontent.com/kepler155c/opus/develop
local PASTEBIN_URL = 'http://pastebin.com/raw' local PASTEBIN_URL = 'http://pastebin.com/raw'
local GIT_URL = 'https://raw.githubusercontent.com' local GIT_URL = 'https://raw.githubusercontent.com'
local fs = _G.fs
local http = _G.http
local os = _G.os
-- fix broken http get -- fix broken http get
local syncLocks = { } local syncLocks = { }
@ -44,7 +48,7 @@ end
local function requireWrapper(env) local function requireWrapper(env)
local function standardSearcher(modname, env, shell) local function standardSearcher(modname)
if package.loaded[modname] then if package.loaded[modname] then
return function() return function()
return package.loaded[modname] return package.loaded[modname]
@ -52,18 +56,18 @@ local function requireWrapper(env)
end end
end end
local function shellSearcher(modname, env, shell) local function shellSearcher(modname)
local fname = modname:gsub('%.', '/') .. '.lua' local fname = modname:gsub('%.', '/') .. '.lua'
if shell and type(shell.dir) == 'function' then if env.shell and type(env.shell.dir) == 'function' then
local path = shell.resolve(fname) local path = env.shell.resolve(fname)
if fs.exists(path) and not fs.isDir(path) then if fs.exists(path) and not fs.isDir(path) then
return loadfile(path, env) return loadfile(path, env)
end end
end end
end end
local function pathSearcher(modname, env, shell) local function pathSearcher(modname)
local fname = modname:gsub('%.', '/') .. '.lua' local fname = modname:gsub('%.', '/') .. '.lua'
for dir in string.gmatch(package.path, "[^:]+") do for dir in string.gmatch(package.path, "[^:]+") do
@ -75,7 +79,7 @@ local function requireWrapper(env)
end end
-- require('BniCQPVf') -- require('BniCQPVf')
local function pastebinSearcher(modname, env, shell) local function pastebinSearcher(modname)
if #modname == 8 and not modname:match('%W') then if #modname == 8 and not modname:match('%W') then
local url = PASTEBIN_URL .. '/' .. modname local url = PASTEBIN_URL .. '/' .. modname
local c = loadUrl(url) local c = loadUrl(url)
@ -86,7 +90,7 @@ local function requireWrapper(env)
end end
-- require('kepler155c.opus.master.sys.apis.util') -- require('kepler155c.opus.master.sys.apis.util')
local function gitSearcher(modname, env, shell) local function gitSearcher(modname)
local fname = modname:gsub('%.', '/') .. '.lua' local fname = modname:gsub('%.', '/') .. '.lua'
local _, count = fname:gsub("/", "") local _, count = fname:gsub("/", "")
if count >= 3 then if count >= 3 then
@ -98,7 +102,7 @@ local function requireWrapper(env)
end end
end end
local function urlSearcher(modname, env, shell) local function urlSearcher(modname)
local fname = modname:gsub('%.', '/') .. '.lua' local fname = modname:gsub('%.', '/') .. '.lua'
if fname:sub(1, 1) ~= '/' then if fname:sub(1, 1) ~= '/' then
@ -113,7 +117,7 @@ local function requireWrapper(env)
end end
-- place package and require function into env -- place package and require function into env
package = { env.package = {
path = LUA_PATH or 'sys/apis', path = LUA_PATH or 'sys/apis',
upath = LUA_UPATH or DEFAULT_UPATH, upath = LUA_UPATH or DEFAULT_UPATH,
config = '/\n:\n?\n!\n-', config = '/\n:\n?\n!\n-',
@ -134,14 +138,14 @@ local function requireWrapper(env)
} }
} }
function require(modname) function env.require(modname)
for _,searcher in ipairs(package.loaders) do for _,searcher in ipairs(package.loaders) do
local fn, msg = searcher(modname, env, shell) local fn, msg = searcher(modname)
if fn then if fn then
local module, msg = fn(modname, env) local module, msg2 = fn(modname, env)
if not module then if not module then
error(msg or (modname .. ' module returned nil'), 2) error(msg2 or (modname .. ' module returned nil'), 2)
end end
package.loaded[modname] = module package.loaded[modname] = module
return module return module
@ -153,10 +157,11 @@ local function requireWrapper(env)
error('Unable to find module ' .. modname) error('Unable to find module ' .. modname)
end end
return require -- backwards compatible return env.require -- backwards compatible
end end
return function(env) return function(env)
env = env or getfenv(2)
setfenv(requireWrapper, env) setfenv(requireWrapper, env)
return requireWrapper(env) return requireWrapper(env)
end end

View File

@ -189,7 +189,7 @@ function json.parseObject(str)
local val = {} local val = {}
while str:sub(1, 1) ~= "}" do while str:sub(1, 1) ~= "}" do
local k, v = nil, nil local k, v
k, v, str = json.parseMember(str) k, v, str = json.parseMember(str)
val[k] = v val[k] = v
str = removeWhite(str) str = removeWhite(str)

View File

@ -21,7 +21,6 @@ function NFT.parse(imageText)
} }
local num = 1 local num = 1
local index = 1
for _,sLine in ipairs(Util.split(imageText)) do for _,sLine in ipairs(Util.split(imageText)) do
table.insert(image.fg, { }) table.insert(image.fg, { })
table.insert(image.bg, { }) table.insert(image.bg, { })
@ -47,7 +46,7 @@ function NFT.parse(imageText)
fgNext = false fgNext = false
else else
if nextChar ~= " " and currFG == nil then if nextChar ~= " " and currFG == nil then
currFG = colours.white currFG = _G.colors.white
end end
image.bg[num][writeIndex] = currBG image.bg[num][writeIndex] = currBG
image.fg[num][writeIndex] = currFG image.fg[num][writeIndex] = currFG

View File

@ -1,3 +1,9 @@
local colors = _G.colors
local fs = _G.fs
local os = _G.os
--local shell = _ENV.shell
local term = _G.term
local Opus = { } local Opus = { }
local function runDir(directory, open) local function runDir(directory, open)
@ -27,7 +33,7 @@ local function runDir(directory, open)
term.setTextColor(colors.white) term.setTextColor(colors.white)
term.write(fs.combine(directory, file)) term.write(fs.combine(directory, file))
if err then if err then
printError(err) _G.printError(err)
end end
success = false success = false
end end

View File

@ -1,16 +1,14 @@
local Util = require('util') local Util = require('util')
local Peripheral = { } local Peripheral = Util.shallowCopy(_G.peripheral)
local function getDeviceList()
function Peripheral.getList()
if _G.device then if _G.device then
return _G.device return _G.device
end end
local deviceList = { } local deviceList = { }
for _,side in pairs(Peripheral.getNames()) do
for _,side in pairs(peripheral.getNames()) do
Peripheral.addDevice(deviceList, side) Peripheral.addDevice(deviceList, side)
end end
@ -19,14 +17,14 @@ end
function Peripheral.addDevice(deviceList, side) function Peripheral.addDevice(deviceList, side)
local name = side local name = side
local ptype = peripheral.getType(side) local ptype = Peripheral.getType(side)
if not ptype then if not ptype then
return return
end end
if ptype == 'modem' then if ptype == 'modem' then
if peripheral.call(name, 'isWireless') then if Peripheral.call(name, 'isWireless') then
ptype = 'wireless_modem' ptype = 'wireless_modem'
else else
ptype = 'wired_modem' ptype = 'wired_modem'
@ -52,10 +50,10 @@ function Peripheral.addDevice(deviceList, side)
name = uniqueName name = uniqueName
end end
local s, m pcall(function() deviceList[name] = peripheral.wrap(side) end) local s, m = pcall(function() deviceList[name] = Peripheral.wrap(side) end)
if not s and m then if not s and m then
printError('wrap failed') _G.printError('wrap failed')
printError(m) _G.printError(m)
end end
if deviceList[name] then if deviceList[name] then
@ -70,15 +68,15 @@ function Peripheral.addDevice(deviceList, side)
end end
function Peripheral.getBySide(side) function Peripheral.getBySide(side)
return Util.find(getDeviceList(), 'side', side) return Util.find(Peripheral.getList(), 'side', side)
end end
function Peripheral.getByType(typeName) function Peripheral.getByType(typeName)
return Util.find(getDeviceList(), 'type', typeName) return Util.find(Peripheral.getList(), 'type', typeName)
end end
function Peripheral.getByMethod(method) function Peripheral.getByMethod(method)
for _,p in pairs(getDeviceList()) do for _,p in pairs(Peripheral.getList()) do
if p[method] then if p[method] then
return p return p
end end
@ -92,8 +90,6 @@ function Peripheral.get(args)
args = { type = args } args = { type = args }
end end
args = args or { type = pType }
if args.type then if args.type then
local p = Peripheral.getByType(args.type) local p = Peripheral.getByType(args.type)
if p then if p then

View File

@ -37,7 +37,7 @@ end
-- turtle distance (manhattan) -- turtle distance (manhattan)
function Point.turtleDistance(a, b) function Point.turtleDistance(a, b)
if a.y and b.y then if a.y and b.y then
return math.abs(a.x - b.x) + return math.abs(a.x - b.x) +
math.abs(a.y - b.y) + math.abs(a.y - b.y) +
math.abs(a.z - b.z) math.abs(a.z - b.z)
else else
@ -116,7 +116,7 @@ function Point.calculateMoves(pta, ptb, distance)
heading = ptb.heading heading = ptb.heading
end end
end end
return moves, heading return moves, heading
end end
@ -149,7 +149,7 @@ end
function Point.adjacentPoints(pt) function Point.adjacentPoints(pt)
local pts = { } local pts = { }
for _, hi in pairs(turtle.getHeadings()) do for _, hi in pairs(_G.turtle.getHeadings()) do
table.insert(pts, { x = pt.x + hi.xd, y = pt.y + hi.yd, z = pt.z + hi.zd }) table.insert(pts, { x = pt.x + hi.xd, y = pt.y + hi.yd, z = pt.z + hi.zd })
end end

View File

@ -28,7 +28,7 @@ function Security.getPublicKey()
local function modexp(base, exponent, modulo) local function modexp(base, exponent, modulo)
local remainder = base local remainder = base
for i = 1, exponent-1 do for _ = 1, exponent-1 do
remainder = remainder * remainder remainder = remainder * remainder
if remainder >= modulo then if remainder >= modulo then
remainder = remainder % modulo remainder = remainder % modulo

View File

@ -3,6 +3,10 @@ local Logger = require('logger')
local Security = require('security') local Security = require('security')
local Util = require('util') local Util = require('util')
local device = _G.device
local os = _G.os
local transport = _G.transport
local socketClass = { } local socketClass = { }
function socketClass:read(timeout) function socketClass:read(timeout)
@ -165,7 +169,7 @@ function Socket.server(port)
Logger.log('socket', 'Waiting for connections on port ' .. port) Logger.log('socket', 'Waiting for connections on port ' .. port)
while true do while true do
local e, _, sport, dport, msg = os.pullEvent('modem_message') local _, _, sport, dport, msg = os.pullEvent('modem_message')
if sport == port and if sport == port and
msg and msg and

View File

@ -1,5 +1,7 @@
local syncLocks = { } local syncLocks = { }
local os = _G.os
return function(obj, fn) return function(obj, fn)
local key = tostring(obj) local key = tostring(obj)
if syncLocks[key] then if syncLocks[key] then

View File

@ -1,14 +1,15 @@
local Util = require('util') local Util = require('util')
local colors = _G.colors
local term = _G.term
local _gsub = string.gsub
local Terminal = { } local Terminal = { }
local _sgsub = string.gsub
function Terminal.scrollable(ct, size) function Terminal.scrollable(ct, size)
local size = size or 25
local w, h = ct.getSize() local w, h = ct.getSize()
local win = window.create(ct, 1, 1, w, h + size, true) local win = _G.window.create(ct, 1, 1, w, h + size, true)
local oldWin = Util.shallowCopy(win) local oldWin = Util.shallowCopy(win)
local scrollPos = 0 local scrollPos = 0
@ -87,7 +88,7 @@ function Terminal.toGrayscale(ct)
local methods = { 'setBackgroundColor', 'setBackgroundColour', local methods = { 'setBackgroundColor', 'setBackgroundColour',
'setTextColor', 'setTextColour' } 'setTextColor', 'setTextColour' }
for _,v in pairs(methods) do for _,v in pairs(methods) do
local fn = ct[v] local fn = ct[v]
ct[v] = function(c) ct[v] = function(c)
fn(scolors[c]) fn(scolors[c])
end end
@ -110,7 +111,7 @@ function Terminal.toGrayscale(ct)
local function translate(s) local function translate(s)
if s then if s then
s = _sgsub(s, "%w", bcolors) s = _gsub(s, "%w", bcolors)
end end
return s return s
end end
@ -136,9 +137,9 @@ end
function Terminal.copy(it, ot) function Terminal.copy(it, ot)
ot = ot or { } ot = ot or { }
for k,v in pairs(it) do for k,v in pairs(it) do
if type(v) == 'function' then if type(v) == 'function' then
ot[k] = v ot[k] = v
end end
end end
return ot return ot
end end
@ -162,7 +163,7 @@ function Terminal.readPassword(prompt)
local fn = term.current().write local fn = term.current().write
term.current().write = function() end term.current().write = function() end
local s local s
pcall(function() s = read(prompt) end) pcall(function() s = _G.read(prompt) end)
term.current().write = fn term.current().write = fn
if s == '' then if s == '' then

View File

@ -1,19 +1,21 @@
requireInjector(getfenv(1)) _G.requireInjector()
local Grid = require ("jumper.grid") local Grid = require ("jumper.grid")
local Pathfinder = require ("jumper.pathfinder") local Pathfinder = require ("jumper.pathfinder")
local Point = require('point') local Point = require('point')
local Util = require('util') local Util = require('util')
local turtle = _G.turtle
local WALKABLE = 0 local WALKABLE = 0
local function createMap(dim) local function createMap(dim)
local map = { } local map = { }
for z = 1, dim.ez do for _ = 1, dim.ez do
local row = {} local row = {}
for x = 1, dim.ex do for _ = 1, dim.ex do
local col = { } local col = { }
for y = 1, dim.ey do for _ = 1, dim.ey do
table.insert(col, WALKABLE) table.insert(col, WALKABLE)
end end
table.insert(row, col) table.insert(row, col)
@ -80,10 +82,10 @@ local function mapDimensions(dest, blocks, boundingBox)
return { return {
ex = ex - sx + 1, ex = ex - sx + 1,
ez = ez - sz + 1, ez = ez - sz + 1,
ey = ey - sy + 1, ey = ey - sy + 1,
ox = -sx + 1, ox = -sx + 1,
oz = -sz + 1, oz = -sz + 1,
oy = -sy + 1 oy = -sy + 1
} }
end end
@ -149,7 +151,7 @@ local function selectDestination(pts, box, map, dim)
map[pt.z + dim.oz][pt.x + dim.ox][pt.y + dim.oy] == 1 then map[pt.z + dim.oz][pt.x + dim.ox][pt.y + dim.oy] == 1 then
Util.removeByValue(pts, pt) Util.removeByValue(pts, pt)
else else
return pt return pt
end end
end end
end end
@ -169,7 +171,7 @@ local function pathTo(dest, options)
end end
-- Creates a pathfinder object -- Creates a pathfinder object
local myFinder = Pathfinder(grid, 'ASTAR', walkable) local myFinder = Pathfinder(grid, 'ASTAR', WALKABLE)
myFinder:setMode('ORTHOGONAL') myFinder:setMode('ORTHOGONAL')
myFinder:setHeuristic(heuristic) myFinder:setHeuristic(heuristic)
@ -208,12 +210,14 @@ local function pathTo(dest, options)
local endPt = pointToMap(dim, dest) local endPt = pointToMap(dim, dest)
-- Calculates the path, and its length -- Calculates the path, and its length
local path = myFinder:getPath(startPt.x, startPt.y, startPt.z, turtle.point.heading, endPt.x, endPt.y, endPt.z, dest.heading) local path = myFinder:getPath(
startPt.x, startPt.y, startPt.z, turtle.point.heading,
endPt.x, endPt.y, endPt.z, dest.heading)
if not path then if not path then
Util.removeByValue(dests, dest) Util.removeByValue(dests, dest)
else else
for node, count in path:nodes() do for node in path:nodes() do
local pt = nodeToPoint(dim, node) local pt = nodeToPoint(dim, node)
if turtle.abort then if turtle.abort then
@ -223,10 +227,10 @@ local function pathTo(dest, options)
-- use single turn method so the turtle doesn't turn around -- use single turn method so the turtle doesn't turn around
-- when encountering obstacles -- IS THIS RIGHT ?? -- when encountering obstacles -- IS THIS RIGHT ??
if not turtle.gotoSingleTurn(pt.x, pt.z, pt.y, node.heading) then if not turtle.gotoSingleTurn(pt.x, pt.z, pt.y, node.heading) then
table.insert(blocks, pt) table.insert(blocks, pt)
--if device.turtlesensorenvironment then --if device.turtlesensorenvironment then
-- addSensorBlocks(blocks, device.turtlesensorenvironment.sonicScan()) -- addSensorBlocks(blocks, device.turtlesensorenvironment.sonicScan())
--end --end
break break
end end
end end

View File

@ -1320,7 +1320,7 @@ end
function UI.Grid:adjustWidth() function UI.Grid:adjustWidth()
local t = { } -- cols without width local t = { } -- cols without width
local w = self.width - #self.columns - 1 - self.marginRight -- width remaing local w = self.width - #self.columns - 1 - self.marginRight -- width remaining
for _,c in pairs(self.columns) do for _,c in pairs(self.columns) do
if c.width then if c.width then

View File

@ -1,6 +1,9 @@
local UI = require('ui') local UI = require('ui')
local Util = require('util') local Util = require('util')
local colors = _G.colors
local fs = _G.fs
return function(args) return function(args)
local columns = { local columns = {
@ -86,7 +89,7 @@ return function(args)
return row return row
end end
function selectFile.grid:getRowTextColor(file, selected) function selectFile.grid:getRowTextColor(file)
if file.isDir then if file.isDir then
return colors.cyan return colors.cyan
end end

View File

@ -162,7 +162,7 @@ end
function Util.findAll(t, name, value) function Util.findAll(t, name, value)
local rt = { } local rt = { }
for k,v in pairs(t) do for _,v in pairs(t) do
if v[name] == value then if v[name] == value then
table.insert(rt, v) table.insert(rt, v)
end end
@ -253,7 +253,7 @@ function Util.spairs(t, order)
local keys = Util.keys(t) local keys = Util.keys(t)
-- if order function given, sort by it by passing the table and keys a, b, -- if order function given, sort by it by passing the table and keys a, b,
-- otherwise just sort the keys -- otherwise just sort the keys
if order then if order then
table.sort(keys, function(a,b) return order(t[a], t[b]) end) table.sort(keys, function(a,b) return order(t[a], t[b]) end)
else else
@ -317,7 +317,7 @@ function Util.writeLines(fname, lines)
local file = fs.open(fname, 'w') local file = fs.open(fname, 'w')
if file then if file then
for _,line in ipairs(lines) do for _,line in ipairs(lines) do
line = file.writeLine(line) file.writeLine(line)
end end
file.close() file.close()
return true return true
@ -458,12 +458,12 @@ end
function Util.trim(s) function Util.trim(s)
return s:find'^%s*$' and '' or s:match'^%s*(.*%S)' return s:find'^%s*$' and '' or s:match'^%s*(.*%S)'
end end
-- trim whitespace from left end of string -- trim whitespace from left end of string
function Util.triml(s) function Util.triml(s)
return s:match'^%s*(.*)' return s:match'^%s*(.*)'
end end
-- trim whitespace from right end of string -- trim whitespace from right end of string
function Util.trimr(s) function Util.trimr(s)
return s:find'^%s*$' and '' or s:match'^(.*%S)' return s:find'^%s*$' and '' or s:match'^(.*%S)'
@ -548,7 +548,7 @@ end
function Util.showOptions(options) function Util.showOptions(options)
print('Arguments: ') print('Arguments: ')
for k, v in pairs(options) do for _, v in pairs(options) do
print(string.format('-%s %s', v.arg, v.desc)) print(string.format('-%s %s', v.arg, v.desc))
end end
end end
@ -561,7 +561,6 @@ function Util.getOptions(options, args, ignoreInvalid)
end end
end end
local rawOptions = getopt(args, argLetters) local rawOptions = getopt(args, argLetters)
local argCount = 0
for k,ro in pairs(rawOptions) do for k,ro in pairs(rawOptions) do
local found = false local found = false

View File

@ -1,11 +1,15 @@
requireInjector(getfenv(1)) _G.requireInjector()
local Config = require('config') local Config = require('config')
local Event = require('event') local Event = require('event')
local UI = require('ui') local UI = require('ui')
local Util = require('util') local Util = require('util')
local colors = _G.colors local colors = _G.colors
local fs = _G.fs
local multishell = _ENV.multishell
local os = _G.os
local shell = _ENV.shell
multishell.setTitle(multishell.getCurrent(), 'Files') multishell.setTitle(multishell.getCurrent(), 'Files')
UI:configure('Files', ...) UI:configure('Files', ...)
@ -158,7 +162,7 @@ function Browser:setStatus(status, ...)
end end
function Browser:unmarkAll() function Browser:unmarkAll()
for k,m in pairs(marked) do for _,m in pairs(marked) do
m.marked = false m.marked = false
end end
Util.clear(marked) Util.clear(marked)
@ -198,7 +202,6 @@ function Browser:updateDirectory(dir)
dir.size = #files dir.size = #files
for _, file in pairs(files) do for _, file in pairs(files) do
file.fullName = fs.combine(dir.name, file.name) file.fullName = fs.combine(dir.name, file.name)
file.directory = directory
file.flags = '' file.flags = ''
if not file.isDir then if not file.isDir then
dir.totalSize = dir.totalSize + file.size dir.totalSize = dir.totalSize + file.size
@ -232,7 +235,7 @@ function Browser:setDir(dirName, noStatus)
if self.dir then if self.dir then
self.dir.index = self.grid:getIndex() self.dir.index = self.grid:getIndex()
end end
DIR = fs.combine('', dirName) local DIR = fs.combine('', dirName)
shell.setDir(DIR) shell.setDir(DIR)
local s, dir = self:getDirectory(DIR) local s, dir = self:getDirectory(DIR)
if s then if s then

View File

@ -1,4 +1,4 @@
requireInjector(getfenv(1)) _G.requireInjector()
local UI = require('ui') local UI = require('ui')
local Util = require('util') local Util = require('util')

View File

@ -1,15 +1,18 @@
requireInjector = requireInjector or load(http.get('https://raw.githubusercontent.com/kepler155c/opus/master/sys/apis/injector.lua').readAll())() local injector = _G.requireInjector or load(http.get('https://raw.githubusercontent.com/kepler155c/opus/master/sys/apis/injector.lua').readAll())()
requireInjector(getfenv(1)) injector()
local Event = require('event') local Event = require('event')
local History = require('history') local History = require('history')
local UI = require('ui') local Peripheral = require('peripheral')
local Util = require('util') local UI = require('ui')
local Util = require('util')
local sandboxEnv = setmetatable(Util.shallowCopy(getfenv(1)), { __index = _G }) local multishell = _ENV.multishell
local sandboxEnv = setmetatable(Util.shallowCopy(_ENV), { __index = _G })
sandboxEnv.exit = function() Event.exitPullEvents() end sandboxEnv.exit = function() Event.exitPullEvents() end
sandboxEnv._echo = function( ... ) return ... end sandboxEnv._echo = function( ... ) return ... end
requireInjector(sandboxEnv) injector(sandboxEnv)
multishell.setTitle(multishell.getCurrent(), 'Lua') multishell.setTitle(multishell.getCurrent(), 'Lua')
UI:configure('Lua', ...) UI:configure('Lua', ...)
@ -112,12 +115,12 @@ function page:eventHandler(event)
if event.type == 'global' then if event.type == 'global' then
self:setPrompt('', true) self:setPrompt('', true)
self:executeStatement('getfenv(0)') self:executeStatement('_G')
command = nil command = nil
elseif event.type == 'local' then elseif event.type == 'local' then
self:setPrompt('', true) self:setPrompt('', true)
self:executeStatement('getfenv(1)') self:executeStatement('_ENV')
command = nil command = nil
elseif event.type == 'autocomplete' then elseif event.type == 'autocomplete' then
@ -129,11 +132,7 @@ function page:eventHandler(event)
elseif event.type == 'device' then elseif event.type == 'device' then
if not _G.device then if not _G.device then
sandboxEnv.device = { } sandboxEnv.device = Peripheral.getList()
for _,side in pairs(peripheral.getNames()) do
local key = string.format('%s:%s', peripheral.getType(side), side)
sandboxEnv.device[ key ] = peripheral.wrap(side)
end
end end
self:setPrompt('device', true) self:setPrompt('device', true)
self:executeStatement('device') self:executeStatement('device')
@ -187,8 +186,7 @@ function page:setResult(result)
local t = { } local t = { }
local function safeValue(v) local function safeValue(v)
local t = type(v) if type(v) == 'string' or type(v) == 'number' then
if t == 'string' or t == 'number' then
return v return v
end end
return tostring(v) return tostring(v)
@ -205,7 +203,7 @@ function page:setResult(result)
if type(v) == 'table' then if type(v) == 'table' then
if Util.size(v) == 0 then if Util.size(v) == 0 then
entry.value = 'table: (empty)' entry.value = 'table: (empty)'
else else
entry.value = 'table' entry.value = 'table'
end end
end end
@ -243,7 +241,7 @@ function page.grid:eventHandler(event)
if type(entry.rawName) == 'number' then if type(entry.rawName) == 'number' then
return command .. '[' .. entry.name .. ']' return command .. '[' .. entry.name .. ']'
end end
if entry.name:match("%W") or if entry.name:match("%W") or
entry.name:sub(1, 1):match("%d") then entry.name:sub(1, 1):match("%d") then
return command .. "['" .. tostring(entry.name) .. "']" return command .. "['" .. tostring(entry.name) .. "']"
end end

View File

@ -1,10 +1,16 @@
requireInjector(getfenv(1)) _G.requireInjector()
local Event = require('event') local Event = require('event')
local Socket = require('socket') local Socket = require('socket')
local UI = require('ui') local UI = require('ui')
local Util = require('util') local Util = require('util')
local colors = _G.colors
local device = _G.device
local multishell = _ENV.multishell
local network = _G.network
local shell = _ENV.shell
multishell.setTitle(multishell.getCurrent(), 'Network') multishell.setTitle(multishell.getCurrent(), 'Network')
UI:configure('Network', ...) UI:configure('Network', ...)
@ -124,14 +130,14 @@ Event.onInterval(1, function()
page:sync() page:sync()
end) end)
Event.on('device_attach', function(h, deviceName) Event.on('device_attach', function(_, deviceName)
if deviceName == 'wireless_modem' then if deviceName == 'wireless_modem' then
page.notification:success('Modem connected') page.notification:success('Modem connected')
page:sync() page:sync()
end end
end) end)
Event.on('device_detach', function(h, deviceName) Event.on('device_detach', function(_, deviceName)
if deviceName == 'wireless_modem' then if deviceName == 'wireless_modem' then
page.notification:error('Wireless modem not attached') page.notification:error('Wireless modem not attached')
page:sync() page:sync()

View File

@ -1,4 +1,4 @@
requireInjector(getfenv(1)) _G.requireInjector()
local class = require('class') local class = require('class')
local Config = require('config') local Config = require('config')
@ -10,19 +10,13 @@ local Tween = require('ui.tween')
local UI = require('ui') local UI = require('ui')
local Util = require('util') local Util = require('util')
local REGISTRY_DIR = 'usr/.registry' local fs = _G.fs
local TEMPLATE = [[ local multishell = _ENV.multishell
local env = { } local pocket = _G.pocket
for k,v in pairs(getfenv(1)) do local term = _G.term
env[k] = v local turtle = _G.turtle
end
setmetatable(env, { __index = _G })
local s, m = os.run(env, 'sys/apps/appRun.lua', %s, ...) local REGISTRY_DIR = 'usr/.registry'
if not s then
error(m)
end
]]
multishell.setTitle(multishell.getCurrent(), 'Overview') multishell.setTitle(multishell.getCurrent(), 'Overview')
UI:configure('Overview', ...) UI:configure('Overview', ...)
@ -93,13 +87,14 @@ end
local buttons = { } local buttons = { }
local categories = { } local categories = { }
table.insert(buttons, { text = 'Recent', event = 'category' })
for _,f in pairs(applications) do for _,f in pairs(applications) do
if not categories[f.category] then if not categories[f.category] then
categories[f.category] = true categories[f.category] = true
table.insert(buttons, { text = f.category, event = 'category' }) table.insert(buttons, { text = f.category, event = 'category' })
end end
end end
table.sort(buttons, function(a, b) return a.text < b.text end)
table.insert(buttons, 1, { text = 'Recent', event = 'category' })
table.insert(buttons, { text = '+', event = 'new' }) table.insert(buttons, { text = '+', event = 'new' })
local function parseIcon(iconText) local function parseIcon(iconText)
@ -159,17 +154,11 @@ local page = UI.Page {
f = 'files', f = 'files',
s = 'shell', s = 'shell',
l = 'lua', l = 'lua',
[ 'control-l' ] = 'refresh',
[ 'control-n' ] = 'new', [ 'control-n' ] = 'new',
delete = 'delete', delete = 'delete',
}, },
} }
function page:draw()
self.tabBar:draw()
self.container:draw()
end
UI.Icon = class(UI.Window) UI.Icon = class(UI.Window)
function UI.Icon:init(args) function UI.Icon:init(args)
local defaults = { local defaults = {
@ -194,7 +183,7 @@ function UI.Icon:eventHandler(event)
return UI.Window.eventHandler(self, event) return UI.Window.eventHandler(self, event)
end end
function page.container:setCategory(categoryName) function page.container:setCategory(categoryName, animate)
-- reset the viewport window -- reset the viewport window
self.children = { } self.children = { }
@ -223,7 +212,7 @@ function page.container:setCategory(categoryName)
end end
else else
filtered = filter(applications, function(a) filtered = filter(applications, function(a)
return a.category == categoryName -- and fs.exists(a.run) return a.category == categoryName -- and fs.exists(a.run)
end) end)
table.sort(filtered, function(a, b) return a.title < b.title end) table.sort(filtered, function(a, b) return a.title < b.title end)
@ -295,6 +284,11 @@ function page.container:setCategory(categoryName)
end end
child.tween = Tween.new(6, child, { x = col, y = row }, 'linear') child.tween = Tween.new(6, child, { x = col, y = row }, 'linear')
if not animate then
child.x = col
child.y = row
end
if k < count then if k < count then
col = col + child.width col = col + child.width
if col + self.children[k + 1].width + gutter - 2 > self.width then if col + self.children[k + 1].width + gutter - 2 > self.width then
@ -305,32 +299,30 @@ function page.container:setCategory(categoryName)
end end
self:initChildren() self:initChildren()
local function transition(args) if animate then -- need to fix transitions under layers
local i = 1 local function transition(args)
return function(device) local i = 1
self:clear() return function(device)
for _,child in pairs(self.children) do self:clear()
child.tween:update(1) for _,child in pairs(self.children) do
child.x = math.floor(child.x) child.tween:update(1)
child.y = math.floor(child.y) child.x = math.floor(child.x)
child:draw() child.y = math.floor(child.y)
child:draw()
end
args.canvas:blit(device, args, args)
i = i + 1
return i < 7
end end
args.canvas:blit(device, args, args)
i = i + 1
return i < 7
end end
self:addTransition(transition)
end end
self:addTransition(transition)
end
function page.container:draw()
UI.Viewport.draw(self)
end end
function page:refresh() function page:refresh()
local pos = self.container.offy local pos = self.container.offy
self:focusFirst(self) self:focusFirst(self)
self.container:setCategory(config.currentCategory) self.container:setCategory(config.currentCategory)
self.container:setScrollPosition(pos) self.container:setScrollPosition(pos)
end end
@ -343,9 +335,8 @@ function page:eventHandler(event)
if event.type == 'category' then if event.type == 'category' then
self.tabBar:selectTab(event.button.text) self.tabBar:selectTab(event.button.text)
self.container:setCategory(event.button.text) self.container:setCategory(event.button.text, true)
self.container:draw() self.container:draw()
self:sync()
config.currentCategory = event.button.text config.currentCategory = event.button.text
Config.update('Overview', config) Config.update('Overview', config)
@ -392,14 +383,7 @@ function page:eventHandler(event)
event.focused.parent:scrollIntoView() event.focused.parent:scrollIntoView()
end end
elseif event.type == 'tab_change' then elseif event.type == 'refresh' then -- remove this after fixing notification
if event.current > event.last then
--self.container:setTransition(UI.effect.slideLeft)
else
--self.container:setTransition(UI.effect.slideRight)
end
elseif event.type == 'refresh' then
loadApplications() loadApplications()
self:refresh() self:refresh()
self:draw() self:draw()
@ -458,7 +442,7 @@ local editor = UI.Dialog {
required = true, required = true,
}, },
loadIcon = UI.Button { loadIcon = UI.Button {
x = 11, y = 6, x = 11, y = 6,
text = 'Icon', event = 'loadIcon', help = 'Select icon' text = 'Icon', event = 'loadIcon', help = 'Select icon'
}, },
image = UI.NftImage { image = UI.NftImage {
@ -569,5 +553,4 @@ page.tabBar:selectTab(config.currentCategory or 'Apps')
page.container:setCategory(config.currentCategory or 'Apps') page.container:setCategory(config.currentCategory or 'Apps')
UI:setPage(page) UI:setPage(page)
Event.pullEvents() UI:pullEvents()
UI.term:reset()

View File

@ -1,10 +1,14 @@
requireInjector(getfenv(1)) _G.requireInjector()
local Config = require('config') local Config = require('config')
local Event = require('event')
local UI = require('ui') local UI = require('ui')
local Util = require('util') local Util = require('util')
local fs = _G.fs
local multishell = _ENV.multishell
local os = _G.os
local shell = _ENV.shell
multishell.setTitle(multishell.getCurrent(), 'System') multishell.setTitle(multishell.getCurrent(), 'System')
UI:configure('System', ...) UI:configure('System', ...)
@ -30,7 +34,6 @@ local systemPage = UI.Page {
}, },
grid = UI.Grid { grid = UI.Grid {
y = 4, y = 4,
values = paths,
disableHeader = true, disableHeader = true,
columns = { { key = 'value' } }, columns = { { key = 'value' } },
autospace = true, autospace = true,
@ -40,7 +43,7 @@ local systemPage = UI.Page {
aliasTab = UI.Window { aliasTab = UI.Window {
tabTitle = 'Aliases', tabTitle = 'Aliases',
alias = UI.TextEntry { alias = UI.TextEntry {
x = 2, y = 2, ex = -2, x = 2, y = 2, ex = -2,
limit = 32, limit = 32,
shadowText = 'Alias', shadowText = 'Alias',
}, },
@ -54,7 +57,6 @@ local systemPage = UI.Page {
}, },
grid = UI.Grid { grid = UI.Grid {
y = 5, y = 5,
values = aliases,
autospace = true, autospace = true,
sortColumn = 'alias', sortColumn = 'alias',
columns = { columns = {
@ -87,7 +89,7 @@ local systemPage = UI.Page {
{ name = '', value = '' }, { name = '', value = '' },
{ name = 'CC version', value = Util.getVersion() }, { name = 'CC version', value = Util.getVersion() },
{ name = 'Lua version', value = _VERSION }, { name = 'Lua version', value = _VERSION },
{ name = 'MC version', value = _MC_VERSION or 'unknown' }, { name = 'MC version', value = _G._MC_VERSION or 'unknown' },
{ name = 'Disk free', value = Util.toBytes(fs.getFreeSpace('/')) }, { name = 'Disk free', value = Util.toBytes(fs.getFreeSpace('/')) },
{ name = 'Computer ID', value = tostring(os.getComputerID()) }, { name = 'Computer ID', value = tostring(os.getComputerID()) },
{ name = 'Day', value = tostring(os.day()) }, { name = 'Day', value = tostring(os.day()) },
@ -129,7 +131,6 @@ end
function systemPage.tabs.aliasTab.grid:draw() function systemPage.tabs.aliasTab.grid:draw()
self.values = { } self.values = { }
local aliases = { }
for k,v in pairs(env.aliases) do for k,v in pairs(env.aliases) do
table.insert(self.values, { alias = k, path = v }) table.insert(self.values, { alias = k, path = v })
end end
@ -170,7 +171,7 @@ end
function systemPage:eventHandler(event) function systemPage:eventHandler(event)
if event.type == 'quit' then if event.type == 'quit' then
Event.exitPullEvents() UI:exitPullEvents()
elseif event.type == 'tab_activate' then elseif event.type == 'tab_activate' then
event.activated:focusFirst() event.activated:focusFirst()
else else
@ -180,5 +181,4 @@ function systemPage:eventHandler(event)
end end
UI:setPage(systemPage) UI:setPage(systemPage)
Event.pullEvents() UI:pullEvents()
UI.term:reset()

View File

@ -1,9 +1,11 @@
requireInjector(getfenv(1)) _G.requireInjector()
local Event = require('event') local Event = require('event')
local UI = require('ui') local UI = require('ui')
local Util = require('util') local Util = require('util')
local multishell = _ENV.multishell
multishell.setTitle(multishell.getCurrent(), 'Tabs') multishell.setTitle(multishell.getCurrent(), 'Tabs')
UI:configure('Tabs', ...) UI:configure('Tabs', ...)

View File

@ -1,31 +1,22 @@
-- Default label
if not os.getComputerLabel() then
local id = os.getComputerID()
if turtle then
os.setComputerLabel('turtle_' .. id)
elseif pocket then
os.setComputerLabel('pocket_' .. id)
elseif commands then
os.setComputerLabel('command_' .. id)
else
os.setComputerLabel('computer_' .. id)
end
end
multishell.term = term.current()
local defaultEnv = { } local defaultEnv = { }
for k,v in pairs(getfenv(1)) do for k,v in pairs(_ENV) do
defaultEnv[k] = v defaultEnv[k] = v
end end
requireInjector(getfenv(1)) _G.requireInjector()
local Config = require('config') local Config = require('config')
local Opus = require('opus') local Opus = require('opus')
local Util = require('util') local Util = require('util')
local SESSION_FILE = 'usr/config/multishell.session' local colors = _G.colors
local fs = _G.fs
local keys = _G.keys
local multishell = _ENV.multishell
local os = _G.os
local printError = _G.printError
local term = _G.term
local window = _G.window
local parentTerm = term.current() local parentTerm = term.current()
local w,h = parentTerm.getSize() local w,h = parentTerm.getSize()
@ -37,6 +28,22 @@ local runningTab
local tabsDirty = false local tabsDirty = false
local closeInd = '*' local closeInd = '*'
multishell.term = term.current()
-- Default label
if not os.getComputerLabel() then
local id = os.getComputerID()
if _G.turtle then
os.setComputerLabel('turtle_' .. id)
elseif _G.pocket then
os.setComputerLabel('pocket_' .. id)
elseif _G.commands then
os.setComputerLabel('command_' .. id)
else
os.setComputerLabel('computer_' .. id)
end
end
if Util.getVersion() >= 1.79 then if Util.getVersion() >= 1.79 then
closeInd = '\215' closeInd = '\215'
end end
@ -59,7 +66,6 @@ local config = {
focusBackgroundColor = colors.gray, focusBackgroundColor = colors.gray,
}, },
} }
Config.load('multishell', config) Config.load('multishell', config)
local _colors = config.standard local _colors = config.standard
@ -229,7 +235,6 @@ local function launchProcess(tab)
selectTab(previousTab) selectTab(previousTab)
end end
redrawMenu() redrawMenu()
saveSession()
end) end)
tabs[tab.tabId] = tab tabs[tab.tabId] = tab
@ -243,8 +248,7 @@ local function resizeWindows()
local windowY = 2 local windowY = 2
local windowHeight = h-1 local windowHeight = h-1
local keys = Util.keys(tabs) for _,key in pairs(Util.keys(tabs)) do
for _,key in pairs(keys) do
local tab = tabs[key] local tab = tabs[key]
local x,y = tab.window.getCursorPos() local x,y = tab.window.getCursorPos()
if y > windowHeight then if y > windowHeight then
@ -255,25 +259,11 @@ local function resizeWindows()
end end
-- Pass term_resize to all processes -- Pass term_resize to all processes
local keys = Util.keys(tabs) for _,key in pairs(Util.keys(tabs)) do
for _,key in pairs(keys) do
resumeTab(tabs[key], "term_resize") resumeTab(tabs[key], "term_resize")
end end
end end
local function saveSession()
local t = { }
for _,process in pairs(tabs) do
if process.path and not process.isOverview and not process.hidden then
table.insert(t, {
path = process.path,
args = process.args,
})
end
end
--Util.writeTable(SESSION_FILE, t)
end
local control local control
local hotkeys = { } local hotkeys = { }
@ -348,7 +338,6 @@ function multishell.terminate(tabId)
local tab = tabs[tabId] local tab = tabs[tabId]
if tab and not tab.isOverview then if tab and not tab.isOverview then
if coroutine.status(tab.co) ~= 'dead' then if coroutine.status(tab.co) ~= 'dead' then
--os.queueEvent('multishell', 'terminate', tab)
resumeTab(tab, "terminate") resumeTab(tab, "terminate")
else else
tabs[tabId] = nil tabs[tabId] = nil
@ -399,10 +388,6 @@ function multishell.openTab(tab)
redrawMenu() redrawMenu()
end end
if not tab.hidden then
saveSession()
end
return tab.tabId return tab.tabId
end end
@ -423,11 +408,7 @@ function multishell.unhideTab(tabId)
end end
function multishell.getCount() function multishell.getCount()
local count return Util.size(tabs)
for _,tab in pairs(tabs) do
count = count + 1
end
return count
end end
-- control-o - overview -- control-o - overview
@ -435,6 +416,10 @@ multishell.addHotkey(24, function()
multishell.setFocus(overviewTab.tabId) multishell.setFocus(overviewTab.tabId)
end) end)
multishell.addHotkey(20, function()
clipboard.useInternal(not clipboard.isInternal())
end)
-- control-backspace -- control-backspace
multishell.addHotkey(14, function() multishell.addHotkey(14, function()
local tabId = multishell.getFocus() local tabId = multishell.getFocus()
@ -474,7 +459,6 @@ end)
local function startup() local function startup()
local hasError local hasError
local session = Util.readTable(SESSION_FILE)
if not Opus.loadServices() then if not Opus.loadServices() then
hasError = true hasError = true
@ -492,12 +476,6 @@ local function startup()
hasError = true hasError = true
end end
if session then
for _,v in pairs(session) do
--multishell.openTab(v)
end
end
if hasError then if hasError then
print() print()
error('An autorun program has errored') error('An autorun program has errored')
@ -514,10 +492,6 @@ multishell.openTab({
title = 'Autorun', title = 'Autorun',
}) })
if not overviewTab or coroutine.status(overviewTab.co) == 'dead' then
--error('Overview aborted')
end
if not currentTab then if not currentTab then
multishell.setFocus(overviewTab.tabId) multishell.setFocus(overviewTab.tabId)
end end
@ -562,13 +536,12 @@ while true do
-- Keyboard event - Passthrough to current process -- Keyboard event - Passthrough to current process
resumeTab(currentTab, sEvent, tEventData) resumeTab(currentTab, sEvent, tEventData)
elseif sEvent == "mouse_click" then elseif sEvent == "mouse_click" then
local button, x, y = tEventData[1], tEventData[2], tEventData[3] local button, x, y = tEventData[1], tEventData[2], tEventData[3]
lastClicked = nil lastClicked = nil
if y == 1 then if y == 1 then
-- Switch process -- Switch process
local w, h = parentTerm.getSize()
if x == 1 then if x == 1 then
multishell.setFocus(overviewTab.tabId) multishell.setFocus(overviewTab.tabId)
elseif x == w then elseif x == w then
@ -616,8 +589,7 @@ while true do
else else
-- Other event -- Other event
-- Passthrough to all processes -- Passthrough to all processes
local keys = Util.keys(tabs) for _,key in pairs(Util.keys(tabs)) do
for _,key in pairs(keys) do
resumeTab(tabs[key], sEvent, tEventData) resumeTab(tabs[key], sEvent, tEventData)
end end
end end

View File

@ -1,4 +1,4 @@
requireInjector(getfenv(1)) _G.requireInjector()
local Security = require('security') local Security = require('security')
local SHA1 = require('sha1') local SHA1 = require('sha1')

View File

@ -1,10 +1,14 @@
requireInjector(getfenv(1)) _G.requireInjector()
local Event = require('event') local Event = require('event')
local Socket = require('socket') local Socket = require('socket')
local Terminal = require('terminal') local Terminal = require('terminal')
local Util = require('util') local Util = require('util')
local os = _G.os
local read = _G.read
local term = _G.term
local remoteId local remoteId
local args = { ... } local args = { ... }
if #args == 1 then if #args == 1 then

View File

@ -1,4 +1,4 @@
requireInjector(getfenv(1)) _G.requireInjector()
local Crypto = require('crypto') local Crypto = require('crypto')
local Security = require('security') local Security = require('security')
@ -6,6 +6,8 @@ local SHA1 = require('sha1')
local Socket = require('socket') local Socket = require('socket')
local Terminal = require('terminal') local Terminal = require('terminal')
local os = _G.os
local remoteId local remoteId
local args = { ... } local args = { ... }
@ -13,7 +15,7 @@ if #args == 1 then
remoteId = tonumber(args[1]) remoteId = tonumber(args[1])
else else
print('Enter host ID') print('Enter host ID')
remoteId = tonumber(read()) remoteId = tonumber(_G.read())
end end
if not remoteId then if not remoteId then
@ -34,9 +36,8 @@ if not socket then
end end
local publicKey = Security.getPublicKey() local publicKey = Security.getPublicKey()
local password = SHA1.sha1(password)
socket:write(Crypto.encrypt({ pk = publicKey, dh = os.getComputerID() }, password)) socket:write(Crypto.encrypt({ pk = publicKey, dh = os.getComputerID() }, SHA1.sha1(password)))
local data = socket:read(2) local data = socket:read(2)
socket:close() socket:close()

View File

@ -1,17 +1,21 @@
requireInjector(getfenv(1)) _G.requireInjector()
local Event = require('event') local Event = require('event')
local Socket = require('socket') local Socket = require('socket')
local Terminal = require('terminal') local Terminal = require('terminal')
local Util = require('util') local Util = require('util')
local colors = _G.colors
local multishell = _ENV.multishell
local term = _G.term
local remoteId local remoteId
local args = { ... } local args = { ... }
if #args == 1 then if #args == 1 then
remoteId = tonumber(args[1]) remoteId = tonumber(args[1])
else else
print('Enter host ID') print('Enter host ID')
remoteId = tonumber(read()) remoteId = tonumber(_G.read())
end end
if not remoteId then if not remoteId then
@ -73,7 +77,7 @@ while true do
print() print()
print('Connection lost') print('Connection lost')
print('Press enter to exit') print('Press enter to exit')
read() _G.read()
break break
end end

View File

@ -33,7 +33,7 @@ local BASE = 'https://raw.githubusercontent.com/' .. GIT_REPO
local function makeEnv() local function makeEnv()
local env = setmetatable({ }, { __index = _G }) local env = setmetatable({ }, { __index = _G })
for k,v in pairs(getfenv(1)) do for k,v in pairs(_ENV) do
env[k] = v env[k] = v
end end
return env return env
@ -53,7 +53,7 @@ local function runUrl(file, ...)
local h = http.get(url) local h = http.get(url)
if h then if h then
local fn, m = load(h.readAll(), url, nil, makeEnv()) local fn = load(h.readAll(), url, nil, makeEnv())
h.close() h.close()
if fn then if fn then
return fn(...) return fn(...)

View File

@ -2,11 +2,11 @@ if _G.clipboard then
return return
end end
requireInjector(getfenv(1)) _G.requireInjector()
local Util = require('util') local Util = require('util')
local os = _G.os
_G.clipboard = { internal, data } local clipboard = { }
function clipboard.getData() function clipboard.getData()
return clipboard.data return clipboard.data
@ -36,8 +36,4 @@ function clipboard.useInternal(mode)
end end
end end
if multishell and multishell.addHotkey then _G.clipboard = clipboard
multishell.addHotkey(20, function()
clipboard.useInternal(not clipboard.isInternal())
end)
end

View File

@ -1,13 +1,5 @@
if _G.device then _G.requireInjector()
return
end
requireInjector(getfenv(1))
local Peripheral = require('peripheral') local Peripheral = require('peripheral')
_G.device = { } _G.device = Peripheral.getList()
for _,side in pairs(peripheral.getNames()) do
Peripheral.addDevice(device, side)
end

View File

@ -1,8 +1,10 @@
local turtle = _G.turtle
if not turtle or turtle.enableGPS then if not turtle or turtle.enableGPS then
return return
end end
requireInjector(getfenv(1)) _G.requireInjector()
local GPS = require('gps') local GPS = require('gps')
local Config = require('config') local Config = require('config')

View File

@ -1,8 +1,12 @@
local os = _G.os
local peripheral = _G.peripheral
local turtle = _G.turtle
if not turtle or turtle.getPoint then if not turtle or turtle.getPoint then
return return
end end
requireInjector(getfenv(1)) _G.requireInjector()
local Point = require('point') local Point = require('point')
local synchronized = require('sync') local synchronized = require('sync')
@ -379,7 +383,7 @@ end
-- combine with setHeading -- combine with setHeading
function turtle.setNamedHeading(headingName) function turtle.setNamedHeading(headingName)
local headingInfo = namedHeadings[headingName] local headingInfo = namedHeadings[headingName]
if headingInfo then if headingInfo then
return turtle.setHeading(headingInfo.heading) return turtle.setHeading(headingInfo.heading)
end end
return false, 'Invalid heading' return false, 'Invalid heading'
@ -482,11 +486,11 @@ function turtle.moveTowardsX(dx)
local direction = dx - turtle.point.x local direction = dx - turtle.point.x
local move local move
if direction == 0 then if direction == 0 then
return true return true
end end
if direction > 0 and turtle.point.heading == 0 or if direction > 0 and turtle.point.heading == 0 or
direction < 0 and turtle.point.heading == 2 then direction < 0 and turtle.point.heading == 2 then
move = turtle.forward move = turtle.forward
@ -510,7 +514,7 @@ function turtle.moveTowardsZ(dz)
if direction == 0 then if direction == 0 then
return true return true
end end
if direction > 0 and turtle.point.heading == 1 or if direction > 0 and turtle.point.heading == 1 or
direction < 0 and turtle.point.heading == 3 then direction < 0 and turtle.point.heading == 3 then
move = turtle.forward move = turtle.forward
@ -591,13 +595,13 @@ local function gotoEx(dx, dz, dy)
-- determine the heading to ensure the least amount of turns -- determine the heading to ensure the least amount of turns
-- first check is 1 turn needed - remaining require 2 turns -- first check is 1 turn needed - remaining require 2 turns
if turtle.point.heading == 0 and turtle.point.x <= dx or if turtle.point.heading == 0 and turtle.point.x <= dx or
turtle.point.heading == 2 and turtle.point.x >= dx or turtle.point.heading == 2 and turtle.point.x >= dx or
turtle.point.heading == 1 and turtle.point.z <= dz or turtle.point.heading == 1 and turtle.point.z <= dz or
turtle.point.heading == 3 and turtle.point.z >= dz then turtle.point.heading == 3 and turtle.point.z >= dz then
-- maintain current heading -- maintain current heading
-- nop -- nop
elseif dz > turtle.point.z and turtle.point.heading == 0 or elseif dz > turtle.point.z and turtle.point.heading == 0 or
dz < turtle.point.z and turtle.point.heading == 2 or dz < turtle.point.z and turtle.point.heading == 2 or
dx < turtle.point.x and turtle.point.heading == 1 or dx < turtle.point.x and turtle.point.heading == 1 or
dx > turtle.point.x and turtle.point.heading == 3 then dx > turtle.point.x and turtle.point.heading == 3 then
@ -719,7 +723,7 @@ function turtle.gotoY(dy)
return false return false
end end
end end
while turtle.point.y < dy do while turtle.point.y < dy do
if not turtle.up() then if not turtle.up() then
return false return false
@ -969,10 +973,10 @@ function turtle.faceAgainst(pt, options) -- 4 sided
for i = 0, 3 do for i = 0, 3 do
local hi = turtle.getHeadingInfo(i) local hi = turtle.getHeadingInfo(i)
table.insert(options.dest, { table.insert(options.dest, {
x = pt.x + hi.xd, x = pt.x + hi.xd,
z = pt.z + hi.zd, z = pt.z + hi.zd,
y = pt.y + hi.yd, y = pt.y + hi.yd,
heading = (hi.heading + 2) % 4, heading = (hi.heading + 2) % 4,
}) })
end end
@ -998,8 +1002,8 @@ function turtle.moveAgainst(pt, options) -- 6 sided
end end
table.insert(options.dest, { table.insert(options.dest, {
x = pt.x + hi.xd, x = pt.x + hi.xd,
z = pt.z + hi.zd, z = pt.z + hi.zd,
y = pt.y + hi.yd, y = pt.y + hi.yd,
direction = direction, direction = direction,
heading = heading, heading = heading,
@ -1058,25 +1062,25 @@ local actionsAt = {
} }
local function _actionAt(action, pt, ...) local function _actionAt(action, pt, ...)
local pt = turtle.moveAgainst(pt) pt = turtle.moveAgainst(pt)
if pt then if pt then
return action[pt.direction](...) return action[pt.direction](...)
end end
end end
function _actionDownAt(action, pt, ...) local function _actionDownAt(action, pt, ...)
if turtle.pathfind(Point.above(pt)) then if turtle.pathfind(Point.above(pt)) then
return action.down(...) return action.down(...)
end end
end end
function _actionForwardAt(action, pt, ...) local function _actionForwardAt(action, pt, ...)
if turtle.faceAgainst(pt) then if turtle.faceAgainst(pt) then
return action.forward(...) return action.forward(...)
end end
end end
function _actionUpAt(action, pt, ...) local function _actionUpAt(action, pt, ...)
if turtle.pathfind(Point.below(pt)) then if turtle.pathfind(Point.below(pt)) then
return action.up(...) return action.up(...)
end end

View File

@ -2,9 +2,11 @@ if fs.native then
return return
end end
requireInjector(getfenv(1)) _G.requireInjector()
local Util = require('util') local Util = require('util')
local fs = _G.fs
fs.native = Util.shallowCopy(fs) fs.native = Util.shallowCopy(fs)
local fstypes = { } local fstypes = { }
@ -18,7 +20,7 @@ for k,fn in pairs(fs) do
end end
end end
function nativefs.list(node, dir, full) function nativefs.list(node, dir)
local files local files
if fs.native.isDir(dir) then if fs.native.isDir(dir) then

View File

@ -111,7 +111,7 @@ device.wireless_modem.open(999)
print('discovery: listening on port 999') print('discovery: listening on port 999')
Event.on('modem_message', function(e, s, sport, id, info, distance) Event.on('modem_message', function(e, s, sport, id, info, distance)
debug(info)
if sport == 999 and tonumber(id) and type(info) == 'table' then if sport == 999 and tonumber(id) and type(info) == 'table' then
if not network[id] then if not network[id] then
network[id] = { } network[id] = { }
@ -151,6 +151,7 @@ end
-- every 10 seconds, send out this computer's info -- every 10 seconds, send out this computer's info
Event.onInterval(10, function() Event.onInterval(10, function()
debug('timer')
sendInfo() sendInfo()
for _,c in pairs(_G.network) do for _,c in pairs(_G.network) do
local elapsed = os.clock()-c.timestamp local elapsed = os.clock()-c.timestamp

View File

@ -1,9 +1,15 @@
requireInjector(getfenv(1)) _G.requireInjector()
local Event = require('event') local Event = require('event')
local Peripheral = require('peripheral') local Peripheral = require('peripheral')
local Util = require('util') local Util = require('util')
local colors = _G.colors
local device = _G.device
local multishell = _ENV.multishell
local os = _G.os
local term = _G.term
multishell.setTitle(multishell.getCurrent(), 'Devices') multishell.setTitle(multishell.getCurrent(), 'Devices')
local attachColor = colors.green local attachColor = colors.green
@ -14,7 +20,7 @@ if not term.isColor() then
detachColor = colors.lightGray detachColor = colors.lightGray
end end
Event.on('peripheral', function(event, side) Event.on('peripheral', function(_, side)
if side then if side then
local dev = Peripheral.addDevice(device, side) local dev = Peripheral.addDevice(device, side)
if dev then if dev then
@ -25,7 +31,7 @@ Event.on('peripheral', function(event, side)
end end
end) end)
Event.on('peripheral_detach', function(event, side) Event.on('peripheral_detach', function(_, side)
if side then if side then
local dev = Util.find(device, 'side', side) local dev = Util.find(device, 'side', side)
if dev then if dev then

View File

@ -1,6 +1,6 @@
if device.wireless_modem then if device.wireless_modem then
requireInjector(getfenv(1)) _G.requireInjector()
local Config = require('config') local Config = require('config')
local config = { } local config = { }

View File

@ -1,14 +1,17 @@
requireInjector(getfenv(1)) _G.requireInjector()
local Terminal = require('terminal') local Terminal = require('terminal')
local Util = require('util') local Util = require('util')
local multishell = _ENV.multishell
local os = _G.os
local term = _G.term
multishell.setTitle(multishell.getCurrent(), 'Debug') multishell.setTitle(multishell.getCurrent(), 'Debug')
term.redirect(Terminal.scrollable(term.current(), 50)) term.redirect(Terminal.scrollable(term.current(), 50))
local tabId = multishell.getCurrent() local tabId = multishell.getCurrent()
local tab = multishell.getTab(tabId)
local terminal = term.current() local terminal = term.current()
local previousId local previousId