diff --git a/sys/apis/blocks.lua b/sys/apis/blocks.lua index bedc466..b78ebbe 100644 --- a/sys/apis/blocks.lua +++ b/sys/apis/blocks.lua @@ -769,14 +769,14 @@ function blockTypeDB:seedDB() { '+12', nil, nil }, }) blockTypeDB:addTemp('door', { - { 0, nil, 0, 'east-door' }, - { 1, nil, 0, 'south-door' }, - { 2, nil, 0, 'west-door' }, - { 3, nil, 0, 'north-door' }, - { 4, nil, 0, 'east-door' }, - { 5, nil, 0, 'south-door' }, - { 6, nil, 0, 'west-door' }, - { 7, nil, 0, 'north-door' }, + { 0, nil, 0, 'east-door', { door = true } }, + { 1, nil, 0, 'south-door', { door = true } }, + { 2, nil, 0, 'west-door', { door = true } }, + { 3, nil, 0, 'north-door', { door = true } }, + { 4, nil, 0, 'east-door', { door = true } }, + { 5, nil, 0, 'south-door', { door = true } }, + { 6, nil, 0, 'west-door', { door = true } }, + { 7, nil, 0, 'north-door', { door = true } }, { 8,'minecraft:air', 0 }, { 9,'minecraft:air', 0 }, { 10,'minecraft:air', 0 }, @@ -823,7 +823,13 @@ function Blocks:getRealBlock(id, dmg) local p = placementDB:get({id, dmg}) if p then - return { id = p.sid, dmg = p.sdmg, direction = p.direction, extra = p.extra } + return { + id = p.sid, + dmg = p.sdmg, + direction = p.direction, + extra = p.extra, + odmg = dmg + } end local b = blockDB:get({id, dmg}) diff --git a/sys/apis/chestProvider18.lua b/sys/apis/chestProvider18.lua index 5c61ded..8a748c8 100644 --- a/sys/apis/chestProvider18.lua +++ b/sys/apis/chestProvider18.lua @@ -24,6 +24,9 @@ function ChestProvider:init(args) Util.merge(self, args) local chest = Peripheral.getBySide(self.wrapSide) + if not chest then + chest = Peripheral.getByMethod('list') + end if chest then Util.merge(self, chest) end diff --git a/sys/apis/event.lua b/sys/apis/event.lua index 6232c00..4c71294 100644 --- a/sys/apis/event.lua +++ b/sys/apis/event.lua @@ -189,6 +189,11 @@ local function processRoutines(...) end end +function Event.processEvent(e) + processHandlers(e[1]) + processRoutines(table.unpack(e)) +end + function Event.pullEvent(eventType) while true do diff --git a/sys/apis/fs/netfs.lua b/sys/apis/fs/netfs.lua index 40b8903..00fa0b6 100644 --- a/sys/apis/fs/netfs.lua +++ b/sys/apis/fs/netfs.lua @@ -5,27 +5,29 @@ local netfs = { } local function remoteCommand(node, msg) - if not node.socket then - node.socket = Socket.connect(node.id, 139) - end + for i = 1, 2 do + if not node.socket then + node.socket = Socket.connect(node.id, 139) + end - if not node.socket then - error('netfs: Unable to establish connection to ' .. node.id) - fs.unmount(node.mountPoint) - return - end + if not node.socket then + error('netfs: Unable to establish connection to ' .. node.id) + fs.unmount(node.mountPoint) + return + end - local ret - synchronized(node.socket, function() - node.socket:write(msg) - ret = node.socket:read(2) - end) + local ret + synchronized(node.socket, function() + node.socket:write(msg) + ret = node.socket:read(1) + end) - if ret then - return ret.response + if ret then + return ret.response + end + node.socket:close() + node.socket = nil end - node.socket:close() - node.socket = nil error('netfs: Connection failed', 2) end diff --git a/sys/apis/schematic.lua b/sys/apis/schematic.lua index c27c64c..90de4e2 100644 --- a/sys/apis/schematic.lua +++ b/sys/apis/schematic.lua @@ -151,9 +151,9 @@ end function Schematic:copyBlocks(iblocks, oblocks, throttle) for k,b in ipairs(iblocks) do oblocks[k] = Util.shallowCopy(b) - if (k % 1000) == 0 then + --if (k % 1000) == 0 then throttle() - end + --end end end @@ -359,7 +359,7 @@ function Schematic:assignDamages(spinner) end end -function Schematic:findIndexAt(x, z, y) +function Schematic:findIndexAt(x, z, y, allBlocks) if y < 0 then return end @@ -369,8 +369,8 @@ function Schematic:findIndexAt(x, z, y) for i = ri.s, ri.e do local b = self.blocks[i] if b.x == x and b.z == z and b.y == y then - if b.id == 'minecraft:air' then - -- this will definitely screw up placement order if a substition is made with air after starting + if b.id == 'minecraft:air' and not allBlocks then + -- this will possibly screw up placement order if a substition is made with air after starting -- as blocks will be placed differently and could have a different heading break end diff --git a/sys/apis/terminal.lua b/sys/apis/terminal.lua index 27d7b55..fca79a0 100644 --- a/sys/apis/terminal.lua +++ b/sys/apis/terminal.lua @@ -10,7 +10,7 @@ function Terminal.scrollable(ct, size) local function drawScrollbar(oldPos, newPos) local x, y = oldWin.getCursorPos() - + local pos = math.floor(oldPos / size * (h - 1)) oldWin.setCursorPos(w, oldPos + pos + 1) oldWin.write(' ') @@ -18,7 +18,7 @@ function Terminal.scrollable(ct, size) pos = math.floor(newPos / size * (h - 1)) oldWin.setCursorPos(w, newPos + pos + 1) oldWin.write('#') - + oldWin.setCursorPos(x, y) end @@ -44,7 +44,8 @@ function Terminal.scrollable(ct, size) if p ~= scrollPos then drawScrollbar(scrollPos, p) scrollPos = p - win.reposition(1, -scrollPos + 1) +--local w, h = win.getSize() + win.reposition(1, -scrollPos + 1, w, h + size) end end diff --git a/sys/apis/util.lua b/sys/apis/util.lua index 84c6cf7..fe419c0 100644 --- a/sys/apis/util.lua +++ b/sys/apis/util.lua @@ -168,10 +168,10 @@ function Util.findAll(t, name, value) end function Util.shallowCopy(t) - local t2 = {} + local t2 = { } for k,v in pairs(t) do - t2[k] = v - end + t2[k] = v + end return t2 end diff --git a/sys/apps/builder.lua b/sys/apps/builder.lua index 257a5b2..1bf7253 100644 --- a/sys/apps/builder.lua +++ b/sys/apps/builder.lua @@ -1,4 +1,4 @@ -if not turtle then +if not turtle and not commands then error('Must be run on a turtle') end @@ -6,7 +6,6 @@ require = requireInjector(getfenv(1)) local class = require('class') local Event = require('event') local Message = require('message') -local Logger = require('logger') local UI = require('ui') local Schematic = require('schematic') local TableDB = require('tableDB') @@ -19,14 +18,6 @@ if os.getVersion() == 1.8 then ChestProvider = require('chestProvider18') end -Logger.filter('modem_send', 'event', 'ui') - -if device.wireless_modem then - Logger.setWirelessLogging() -else - Logger.setDaemonLogging() -end - local BUILDER_DIR = 'usr/builder' local schematic = Schematic() @@ -34,6 +25,7 @@ local blocks = Blocks({ dir = BUILDER_DIR }) local Builder = { version = '1.71', + isCommandComputer = not turtle, slots = { }, index = 1, mode = 'build', @@ -54,7 +46,7 @@ subDB = TableDB({ function subDB:load() if fs.exists(self.fileName) then TableDB.load(self) - else + elseif not Builder.isCommandComputer then self:seedDB() end end @@ -197,22 +189,24 @@ function Builder:getBlockCounts() local blocks = { } -- add a couple essential items to the supply list to allow replacements - local wrench = subDB:getSubstitutedItem('SubstituteAWrench', 0) - wrench.qty = 0 - wrench.need = 1 - blocks[wrench.id .. ':' .. wrench.dmg] = wrench + if not self.isCommandComputer then + local wrench = subDB:getSubstitutedItem('SubstituteAWrench', 0) + wrench.qty = 0 + wrench.need = 1 + blocks[wrench.id .. ':' .. wrench.dmg] = wrench - local fuel = subDB:getSubstitutedItem(Builder.fuelItem.id, Builder.fuelItem.dmg) - fuel.qty = 0 - fuel.need = 1 - blocks[fuel.id .. ':' .. fuel.dmg] = fuel + local fuel = subDB:getSubstitutedItem(Builder.fuelItem.id, Builder.fuelItem.dmg) + fuel.qty = 0 + fuel.need = 1 + blocks[fuel.id .. ':' .. fuel.dmg] = fuel - blocks['minecraft:piston:0'] = { - id = 'minecraft:piston', - dmg = 0, - qty = 0, - need = 1, - } + blocks['minecraft:piston:0'] = { + id = 'minecraft:piston', + dmg = 0, + qty = 0, + need = 1, + } + end for k,b in ipairs(schematic.blocks) do if k >= self.index then @@ -379,6 +373,7 @@ function Builder:substituteBlocks(throttle) b.dmg = pb.dmg b.direction = pb.direction b.extra = pb.extra + b.odmg = pb.odmg local sub = subDB:get({ b.id, b.dmg }) if sub then @@ -409,7 +404,6 @@ end function Builder:dumpInventoryWithCheck() while not self:dumpInventory() do - Logger.log('builder', 'Unable to dump inventory') print('Provider is full or missing - make space or replace') print('Press enter to continue') turtle.setHeading(0) @@ -467,8 +461,6 @@ function Builder:getSupplies() end if s.qty < s.need then table.insert(t, s) - local name = s.name or s.id .. ':' .. s.dmg - Logger.log('builder', 'Need %d %s', s.need - s.qty, name) end end @@ -481,14 +473,13 @@ end) function Builder:refuel() while turtle.getFuelLevel() < 4000 and self.fuelItem do - Logger.log('builder', 'Refueling') + print('Refueling') turtle.select(1) local fuel = subDB:getSubstitutedItem(self.fuelItem.id, self.fuelItem.dmg) self.itemProvider:provide(fuel, 64, 1) if turtle.getItemCount(1) == 0 then - Logger.log('builder', 'Out of fuel, add fuel to chest/ME system') print('Out of fuel, add fuel to chest/ME system') turtle.setHeading(0) turtle.status = 'waiting' @@ -668,7 +659,6 @@ function Builder:resupply() else turtle.setHeading(0) self:autocraft(supplies) - Logger.log('builder', 'Waiting for supplies') supplyPage:setSupplies(supplies) UI:setPage('supply') end @@ -850,7 +840,6 @@ end function Builder:goto(x, z, y, heading) if not turtle.goto(x, z, y, heading) then - Logger.log('builder', 'stuck') print('stuck') print('Press enter to continue') os.sleep(1) @@ -1080,7 +1069,7 @@ function Builder:placeDirectionalBlock(b, slot, travelPlane) b.placed = self:place(slot) end - if b.extra then + if b.extra and b.extra.facing then self:rotateBlock('down', b.extra.facing) end @@ -1101,7 +1090,6 @@ function Builder:reloadSchematic(throttle) end function Builder:log(...) - Logger.log('builder', ...) Util.print(...) end @@ -1115,10 +1103,6 @@ function Builder:logBlock(index, b) if device.wireless_modem then Message.broadcast('builder', { x = b.x, y = b.y, z = b.z, heading = b.heading }) end - - if b.info then - Logger.debug(b.info) - end end function Builder:saveProgress(index) @@ -1152,13 +1136,7 @@ function Builder:findTravelPlane(index) y = y + 1 end if not travelPlane or y > travelPlane then --- if not b.twoHigh then - travelPlane = y - - Logger.log('builder', 'adjusting travelPlane') - Logger.log('builder', b) - --read() --- end + travelPlane = y elseif travelPlane and travelPlane - y > 2 then break end @@ -1168,7 +1146,7 @@ function Builder:findTravelPlane(index) end function Builder:gotoTravelPlane(travelPlane) - if travelPlane > turtle.getPoint().y then + if travelPlane > turtle.point.y then turtle.gotoY(travelPlane) end end @@ -1179,12 +1157,15 @@ function Builder:build() local last = #schematic.blocks local travelPlane = 0 local minFuel = schematic.height + schematic.width + schematic.length + 100 + local throttle = Util.throttle() + + --commands.execAsync("fill " .. (x1 - 4) .. " " .. y .. " " .. (z1 - 4) .. " " .. (x1 + 131) .. " " .. y .. " " .. (z1 + 131) .. " minecraft:air") if self.mode == 'destroy' then direction = -1 last = 1 turtle.status = 'destroying' - else + elseif self.isCommandComputer then travelPlane = self:findTravelPlane(self.index) turtle.status = 'building' if not self.confirmFacing then @@ -1200,11 +1181,51 @@ function Builder:build() for i = self.index, last, direction do self.index = i + local b = schematic:getComputedBlock(i) if b.id ~= 'minecraft:air' then - if self.mode == 'destroy' then + if self.isCommandComputer then + self:logBlock(self.index, b) + + local id = b.id + if self.mode == 'destroy' then + id = 'minecraft:air' + end + + local function placeBlock(id, dmg, x, y, z) + + local cx, cy, cz = commands.getBlockPosition() + + local command = table.concat({ + "setblock", + cx + x + 1, + "~" .. y, + cz + z + 1, + id, + dmg, + }, ' ') + + commands.execAsync(command) + + local result = { os.pullEvent("task_complete") } + if not result[4] then + Util.print(result[5]) + if self.mode ~= 'destroy' then + read() + end + end + end + + placeBlock(id, b.odmg, b.x, b.y, b.z) + + if b.extra and b.extra.door then + local _, doorTop = schematic:findIndexAt(b.x, b.z, b.y + 1, true) + placeBlock(id, doorTop.odmg, b.x, b.y + 1, b.z) + end + + elseif self.mode == 'destroy' then b.heading = nil -- don't make the supplier follow the block heading self:logBlock(self.index, b) @@ -1217,7 +1238,6 @@ function Builder:build() -- if no supplier, then should fill all slots if turtle.getItemCount(self.resourceSlots) > 0 or turtle.getFuelLevel() < minFuel then - Logger.log('builder', 'Dropping off inventory') if turtle.getFuelLevel() < minFuel or not self:inAirDropoff() then turtle.gotoLocation('supplies') os.sleep(.1) -- random 'Computer is not connected' error... @@ -1265,13 +1285,16 @@ function Builder:build() if b.placed then slot.qty = slot.qty - 1 else - Logger.log('builder', 'failed to place block') print('failed to place block') end end - self:saveProgress(self.index+1) - elseif (i % 50) == 0 then -- is Air - os.sleep(0) -- sleep in case there are a large # of skipped blocks + if self.mode == 'destroy' then + self:saveProgress(math.max(self.index - 1, 1)) + else + self:saveProgress(self.index + 1) + end + else + throttle() -- sleep in case there are a large # of skipped blocks end if turtle.abort then @@ -1287,23 +1310,26 @@ function Builder:build() end end - Message.broadcast('finished') - self:gotoTravelPlane(travelPlane) - turtle.gotoLocation('supplies') - turtle.setHeading(0) - Builder:dumpInventory() + if device.wireless_modem then + Message.broadcast('finished') + end + if not self.isCommandComputer then + self:gotoTravelPlane(travelPlane) + turtle.gotoLocation('supplies') + turtle.setHeading(0) + Builder:dumpInventory() - for i = 1, 4 do - turtle.turnRight() + for i = 1, 4 do + turtle.turnRight() + end end --self.index = 1 --os.queueEvent('build') - Event.exitPullEvents() - UI.term:reset() + --UI.term:reset() fs.delete(schematic.filename .. '.progress') - Logger.log('builder', 'Finished') print('Finished') + Event.exitPullEvents() end --[[-- blankPage --]]-- @@ -1792,13 +1818,22 @@ function listingPage:manageBlock(selected) end --[[-- startPage --]]-- + +local wy = 2 +local my = 4 + +if UI.term.width < 30 then + wy = 9 + my = 2 +end + local startPage = UI.Page { -- titleBar = UI.TitleBar({ title = 'Builder v' .. Builder.version }), window = UI.Window { x = UI.term.width-16, - y = 2, + y = wy, width = 16, - height = UI.term.height-2, + height = 9, backgroundColor = colors.gray, grid = UI.Grid { columns = { @@ -1818,7 +1853,8 @@ local startPage = UI.Page { }, menu = UI.Menu { x = 2, - y = 4, + y = my, + height = 7, menuItems = { { prompt = 'Set starting level', event = 'startLevel' }, { prompt = 'Set starting block', event = 'startBlock' }, @@ -1845,7 +1881,7 @@ function startPage:draw() { name = 'mode', value = Builder.mode }, { name = 'start', value = Builder.index }, { name = 'blocks', value = #schematic.blocks }, - { name = 'fuel', value = fuel }, + --{ name = 'fuel', value = fuel }, { name = 'facing', value = Builder.facing }, { name = 'length', value = schematic.length }, { name = 'width', value = schematic.width }, @@ -2016,6 +2052,39 @@ if not Builder.itemProvider:isValid() then end end +if commands then + turtle = { + policies = { }, + point = { x = -1, y = 0, z = -1, heading = 0 }, + getFuelLevel = function() return 20000 end, + select = function() end, + getItemCount = function() return 0 end, + getHeadingInfo = function(heading) + local headings = { + [ 0 ] = { xd = 1, zd = 0, yd = 0, heading = 0, direction = 'east' }, + [ 1 ] = { xd = 0, zd = 1, yd = 0, heading = 1, direction = 'south' }, + [ 2 ] = { xd = -1, zd = 0, yd = 0, heading = 2, direction = 'west' }, + [ 3 ] = { xd = 0, zd = -1, yd = 0, heading = 3, direction = 'north' }, + [ 4 ] = { xd = 0, zd = 0, yd = 1, heading = 4, direction = 'up' }, + [ 5 ] = { xd = 0, zd = 0, yd = -1, heading = 5, direction = 'down' } + } + local namedHeadings = { + east = headings[0], + south = headings[1], + west = headings[2], + north = headings[3], + up = headings[4], + down = headings[5] + } + if heading and type(heading) == 'string' then + return namedHeadings[heading] + end + heading = heading or 0 + return headings[heading] + end, + } +end + multishell.setTitle(multishell.getCurrent(), 'Builder v' .. Builder.version) maxStackDB:load() @@ -2044,9 +2113,13 @@ UI:setPages({ UI:setPage('start') -local s, m = turtle.run(function() - turtle.setPolicy(turtle.policies.digAttack) - turtle.setPoint({ x = -1, z = -1, y = 0, heading = 0 }) - turtle.saveLocation('supplies') - UI:pullEvents() -end) +if Builder.isCommandComputer then + Event.pullEvents() +else + local s, m = turtle.run(function() + turtle.setPolicy(turtle.policies.digAttack) + turtle.setPoint({ x = -1, z = -1, y = 0, heading = 0 }) + turtle.saveLocation('supplies') + Event.pullEvents() + end) +end diff --git a/sys/apps/chestManager.lua b/sys/apps/chestManager.lua index 042fc6b..3542b55 100644 --- a/sys/apps/chestManager.lua +++ b/sys/apps/chestManager.lua @@ -1,5 +1,6 @@ require = requireInjector(getfenv(1)) local UI = require('ui') +local Event = require('event') local Config = require('config') local ChestProvider = require('chestProvider18') local RefinedProvider = require('refinedProvider') diff --git a/sys/apps/multishell b/sys/apps/multishell index dd72d79..d860681 100644 --- a/sys/apps/multishell +++ b/sys/apps/multishell @@ -5,6 +5,8 @@ if not os.getComputerLabel() 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 diff --git a/sys/apps/telnet.lua b/sys/apps/telnet.lua index 39666d4..a9277bc 100644 --- a/sys/apps/telnet.lua +++ b/sys/apps/telnet.lua @@ -51,14 +51,20 @@ ct.clear() ct.setCursorPos(1, 1) local filter = Util.transpose({ - 'char', 'paste', 'key', 'key_up', + 'char', 'paste', 'key', 'key_up', 'terminate', 'mouse_scroll', 'mouse_click', 'mouse_drag', 'mouse_up', }) while true do - local e = Event.pullEvent() + local e = { os.pullEventRaw() } local event = e[1] + if filter[event] then + socket:write(e) + else + Event.processEvent(e) + end + if not socket.connected then print() print('Connection lost') @@ -66,16 +72,4 @@ while true do read() break end - - if filter[event] then - - if not socket:write(e) then - socket:close() - break - end - - elseif event == 'terminate' then - socket:close() - break - end end