diff --git a/core/DiskCopy.lua b/core/DiskCopy.lua new file mode 100644 index 0000000..b2bbe00 --- /dev/null +++ b/core/DiskCopy.lua @@ -0,0 +1,200 @@ +local Ansi = require('ansi') +local Event = require('event') +local UI = require('ui') +local Util = require('util') + +local colors = _G.colors +local fs = _G.fs +local peripheral = _G.peripheral + +local drives = { } +peripheral.find('drive', function(n, v) + if not drives.left then + drives.left = Util.shallowCopy(v) + drives.left.name = n + else + drives.right = Util.shallowCopy(v) + drives.right.name = n + end +end) + +if not (drives.left and drives.right) then + error('Two drives are required') +end + +local COPY_LEFT = 1 +local COPY_RIGHT = 2 +local directions = { + [ COPY_LEFT ] = { text = '-->>' }, + [ COPY_RIGHT ] = { text = '<<--' }, +} +local copyDir = COPY_LEFT + +local page = UI.Page { + linfo = UI.Window { + x = 2, y = 2, ey = 5, width = 18, + }, + rinfo = UI.Window { + x = -19, y = 2, ey = 5, width = 18, + }, + dir = UI.Button { + x = 17, y = 7, width = 6, + event = 'change_dir', + }, + progress = UI.ProgressBar { + x = 2, ex = -2, y = -4, + backgroundColor = colors.black, + }, + copyButton = UI.Button { + x = -7, y = -2, + text = 'Copy', + event = 'copy', + inactive = true, + }, + warning = UI.Text { + x = 2, ex = -9, y = -2, + textColor = colors.orange, + }, + notification = UI.Notification { }, +} + +function page:enable() + Util.merge(self.dir, directions[copyDir]) + UI.Page.enable(self) +end + +local function isValid(drive) + return drive.isDiskPresent() and drive.getMountPath() +end + +local function needsLabel(drive) + return drive.isDiskPresent() and not drive.getMountPath() +end + +function page:drawInfo(drive, textArea) + local function getLabel() + return not drive.isDiskPresent() and 'empty' or + not drive.getMountPath() and 'invalid' or + drive.getDiskLabel() or 'unlabeled' + end + + local function getUsed() + return isValid(drive) and fs.getSize(drive.getMountPath(), true) or 0 + end + + local function getFree() + return isValid(drive) and fs.getFreeSpace(drive.getMountPath()) or 0 + end + + textArea:setCursorPos(1, 1) + textArea:print(string.format('Drive: %s%s%s\nLabel: %s%s%s\nUsed: %s%s%s\nFree: %s%s%s', + Ansi.yellow, drive.name, Ansi.reset, + isValid(drive) and Ansi.yellow or Ansi.orange, getLabel():sub(1, 10), Ansi.reset, + Ansi.yellow, Util.toBytes(getUsed()), Ansi.reset, + Ansi.yellow, Util.toBytes(getFree()), Ansi.reset)) +end + +function page:scan() + local showWarning = needsLabel(drives.left) or needsLabel(drives.right) + local valid = isValid(drives.left) and isValid(drives.right) + + self.warning.value = showWarning and 'Computers must be labeled' + self.copyButton.inactive = not valid + + self:draw() + self.progress:centeredWrite(1, 'Analyzing Disks..') + self.progress:sync() + + self:drawInfo(drives.left, self.linfo) + self:drawInfo(drives.right, self.rinfo) + + self.progress:clear() +end + +function page:copy(sdrive, tdrive) + local totalFiles = 0 + local throttle = Util.throttle() + + local function countFiles(source, target) + if fs.isDir(source) then + local list = fs.list(source) + for _,f in pairs(list) do + countFiles(fs.combine(source, f), fs.combine(target, f)) + end + else + totalFiles = totalFiles + 1 + end + throttle() + end + + local copied = 0 + local function rawCopy(source, target) + if fs.isDir(source) then + if not fs.exists(target) then + fs.makeDir(target) + end + local list = fs.list(source) + for _,f in pairs(list) do + rawCopy(fs.combine(source, f), fs.combine(target, f)) + end + + else + if fs.exists(target) then + fs.delete(target) + end + + fs.copy(source, target) + copied = copied + 1 + self.progress.value = copied * 100 / totalFiles + self.progress:draw() + self.progress:sync() + end + throttle() + end + + self.progress:centeredWrite(1, 'Computing..') + self.progress:sync() + countFiles(sdrive.getMountPath(), tdrive.getMountPath()) + + self.progress:clear() + rawCopy(sdrive.getMountPath(), tdrive.getMountPath()) + self.progress:centeredWrite(1, 'Copy Complete', colors.lime, colors.black) + self.progress:sync() + + self.progress.value = 0 + self.progress:clear() + + self:scan() +end + +function page:eventHandler(event) + if event.type == 'change_dir' then + copyDir = (copyDir) % 2 + 1 + Util.merge(self.dir, directions[copyDir]) + self.dir:draw() + + elseif event.type == 'copy' then + if copyDir == COPY_LEFT then + self:copy(drives.left, drives.right) + else + self:copy(drives.right, drives.left) + end + + else + return UI.Page.eventHandler(self, event) + end + return true +end + +Event.on({ 'disk', 'disk_eject' }, function() + page:scan() + page:sync() +end) + +Event.onTimeout(.2, function() + page:scan() + page:sync() +end) + +UI:setPage(page) +UI:pullEvents() diff --git a/core/etc/apps.db b/core/etc/apps.db index 55b708a..fea7ff9 100644 --- a/core/etc/apps.db +++ b/core/etc/apps.db @@ -24,6 +24,11 @@ Needs work \130\139\141\0311\130\131\0310\142\135\129", run = "Events.lua", }, + [ "f1e14c30480042e8c71b5482d92ef161815b915e" ] = { + title = "DiskCopy", + category = "System", + run = "DiskCopy", + }, [ "7ef35cac539f84722b0a988caee03b2df734c56a" ] = { title = "AppStore", category = "System", diff --git a/farms/attack.lua b/farms/attack.lua index 4747bee..041ad0a 100644 --- a/farms/attack.lua +++ b/farms/attack.lua @@ -96,6 +96,7 @@ local function dropOff() end end end + turtle.condense() turtle.select(1) end diff --git a/milo/apps/storageGen.lua b/milo/apps/storageGen.lua new file mode 100644 index 0000000..4bbc4f2 --- /dev/null +++ b/milo/apps/storageGen.lua @@ -0,0 +1,29 @@ +--[[ + For initially setting up large amounts of storage chests. +]] + +local Util = require('util') + +local peripheral = _G.peripheral + +local args = { ... } +local st = args[1] or error('Specify a storage type (ie. minecraft:chest)') + +local config = { } +peripheral.find(st, function(n) + config[n] = { + name = n, + category = 'storage', + mtype = 'storage', + } +end) + +print('Found ' .. Util.size(config)) + +if Util.size(config) == 0 then + error('Invalid peripheral type') +end + +Util.writeTable('usr/config/storageGen', config) +print('storageGen file created in usr/config') +print('update /usr/config/storage with contents (or rename to storage)')