Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local g = require("simple-graphics")
- local mon = peripheral.wrap("monitor_24")
- local W, H = mon.getSize()
- local RUNNING = true -- Flag to indicate global program state.
- -- Export flags
- local EXPORTING = false -- Flag to indicate if we're exporting.
- local EXPORT_SKIP = false -- Flag to indicate we should skip the current item.
- local EXPORT_REPORT = false -- Flag to indicate we should report the current item as invalid.
- local function startsWith(str, start)
- return str:sub(1, #start) == start
- end
- local function getTotalItemCount(itemList)
- local total = 0
- for name, value in pairs(itemList) do
- if not startsWith(name, "__") then
- total = total + value
- end
- end
- local count = 1
- if itemList.__COUNT__ then count = itemList.__COUNT__ end
- return count * total
- end
- local function findItem(items, name)
- for _, item in pairs(items) do
- if item.name == name then return item end
- end
- return nil
- end
- local function attemptItemExport(name, count)
- local P_NAME = "meBridge_4"
- local p = peripheral.wrap(P_NAME)
- if p == nil then
- return nil, "Missing peripheral "..P_NAME
- end
- local func = function()
- return p.exportItem({name=name, count=count}, "south")
- end
- local success, result = pcall(func)
- if success then
- return result
- else
- return nil, result
- end
- end
- local function playNotes(instrument, pitches, delay)
- local speaker = peripheral.find("speaker")
- if speaker == nil then return end
- delay = delay or 0.25
- for i, pitch in pairs(pitches) do
- speaker.playNote(instrument, 3, pitch)
- if i < #pitches then
- os.sleep(delay)
- end
- end
- end
- local function drawProgress(p)
- local discreteWidth = W - 2
- local filled = p * discreteWidth
- g.drawXLine(mon, 2, W-1, 5, colors.lightGray)
- g.drawXLine(mon, 2, 2+filled-1, 5, colors.green)
- local s = string.format("%.0f%%", p*100)
- for i = 1, #s do
- local x = 2+i
- local c = s:sub(i,i)
- local bg = colors.lightGray
- if x < filled then bg = colors.green end
- g.drawText(mon, x, 5, c, colors.white, bg)
- end
- end
- local function setProgressText(text)
- g.drawXLine(mon, 2, W-1, 6, colors.gray)
- if text ~= nil and #text > 0 then
- g.drawText(mon, 2, 6, text, colors.white, colors.gray)
- end
- end
- local function clearMainPanel()
- g.fillRect(mon, 1, 7, W, H-6, colors.black)
- end
- local function clearExportPanel()
- g.fillRect(mon, 1, 7, W, H-9, colors.black)
- end
- local function promptForUrlInput()
- clearMainPanel()
- drawProgress(0)
- setProgressText(nil)
- g.drawText(mon, 1, 8, "Please enter a schematic URL that", colors.white, colors.black)
- g.drawText(mon, 1, 9, "you've obtained from", colors.white, colors.black)
- g.drawText(mon, 1, 10, "schematics.andrewlalis.com in the", colors.white, colors.black)
- g.drawText(mon, 1, 11, "computer to your right to continue.", colors.white, colors.black)
- g.clear(term, colors.black)
- g.drawText(term, 1, 1, "Paste your schematic URL here (CTRL+V): ", colors.white)
- g.drawText(term, 2, 2, "*Press enter without pasting to quit*", colors.gray)
- term.setCursorPos(1, 3)
- term.setTextColor(colors.lightGray)
- local link = io.read()
- if link == nil or #link == 0 then
- g.drawText(term, 1, 8, "No URL entered. Quitting.", colors.white)
- return nil
- else
- g.drawText(term, 1, 8, "URL was pasted. Please continue on the monitor.", colors.white)
- return link
- end
- end
- local function fetchItemLists(url)
- local response = http.get(url)
- if response == nil then
- return nil, "HTTP request failed."
- end
- if response.getResponseCode() ~= 200 then
- return nil, "HTTP code " .. response.getResponseCode()
- end
- local rawText = response.readAll()
- response.close()
- local itemLists, jsonErr = textutils.unserializeJSON(rawText)
- if not itemLists then
- return nil, "Failed to parse JSON: "..jsonErr
- end
- return itemLists
- end
- local function exportItem(name, count)
- clearExportPanel()
- g.drawText(mon, 1, 7, "Exporting "..count.." of", colors.white, colors.black)
- g.drawText(mon, 1, 8, name, colors.lime, colors.black)
- -- Check for flags and do different stuff if so.
- if EXPORT_REPORT then
- -- Report the item issue to the schematic site.
- g.drawText(mon, 1, 10, "Reporting item. Skipping to next one.", colors.yellow, colors.black)
- http.post("https://schematics.andrewlalis.com/item-reports", name)
- g.drawText(mon, 1, 11, "Contact an admin if urgent.", colors.yellow, colors.black)
- os.sleep(3)
- return count
- elseif EXPORT_SKIP then
- -- Skip this item.
- g.drawText(mon, 1, 10, "Skipping this item.", colors.yellow, colors.black)
- os.sleep(2)
- return count
- end
- local me = peripheral.find("meBridge")
- if me == nil then
- g.drawText(mon, 1, 10, "Error: No \"meBridge\" peripheral.", colors.red, colors.black)
- g.drawText(mon, 1, 11, "Attach one please.", colors.red, colors.black)
- os.sleep(0.5)
- return 0
- end
- local allItems, err = me.listItems()
- if allItems == nil or #allItems < 5 then
- g.drawText(mon, 1, 10, "Error: Couldn't list AE items.", colors.red, colors.black)
- g.drawText(mon, 1, 11, "Msg: " .. err, colors.red, colors.black)
- os.sleep(0.5)
- return 0
- end
- local item = findItem(allItems, name)
- if item ~= nil and item.amount > 0 then
- local exported, err = attemptItemExport(name, count)
- if exported ~= nil then
- if exported == 0 then
- g.drawText(mon, 1, 10, "Exported 0 items. Make sure there is", colors.yellow, colors.black)
- g.drawText(mon, 1, 11, "space in the output container.", colors.yellow, colors.black)
- else
- g.drawText(mon, 1, 10, "Exported " .. exported .. " items.", colors.white, colors.black)
- end
- os.sleep(0.5)
- return exported
- end
- g.drawText(mon, 1, 10, "Transfer failed: " .. err, colors.red, colors.black)
- os.sleep(0.5)
- return 0
- else
- g.drawText(mon, 1, 10, "Item isn't present in the AE system.", colors.yellow, colors.black)
- g.drawText(mon, 1, 11, "Please add some, craft, or skip.", colors.yellow, colors.black)
- os.sleep(0.5)
- return 0
- end
- end
- local function exportSchematics(itemLists)
- -- First build a list of instances of schematics, each with a task list.
- local totalItemCount = 0
- local listInstances = {}
- for _, list in pairs(itemLists) do
- totalItemCount = totalItemCount + getTotalItemCount(list)
- for i = 1, list.__COUNT__ do
- local instance = {
- name = list.__NAME__,
- instanceNumber = i,
- countOfThisType = list.__COUNT__,
- tasks = {}
- }
- for name, amount in pairs(list) do
- if not startsWith(name, "__") then
- table.insert(instance.tasks, {name=name, amount=amount})
- end
- end
- table.insert(listInstances, instance)
- end
- end
- -- Now execute on that task list, quitting if the EXPORTING flag goes false.
- local totalItemsExported = 0
- local instanceIndex = 1
- while instanceIndex <= #listInstances and EXPORTING do
- local listInstance = listInstances[instanceIndex]
- setProgressText(listInstance.instanceNumber.."/"..listInstance.countOfThisType.." "..listInstance.name)
- local taskIndex = 1
- while taskIndex <= #listInstance.tasks and EXPORTING do
- local task = listInstance.tasks[taskIndex]
- local itemsExported = 0
- -- Reset item-specific control flags.
- EXPORT_REPORT = false
- EXPORT_SKIP = false
- while itemsExported < task.amount and EXPORTING do
- local exportedCount = exportItem(task.name, task.amount - itemsExported)
- itemsExported = itemsExported + exportedCount
- totalItemsExported = totalItemsExported + exportedCount
- drawProgress(totalItemsExported / totalItemCount)
- end
- taskIndex = taskIndex + 1
- end
- instanceIndex = instanceIndex + 1
- end
- -- Done! Show a small message, then set the EXPORTING flag to false.
- EXPORTING = false
- RUNNING = false -- Exit back to the desktop.
- for i = 1, 3 do -- Queue up some no-op touch events make sure the event handler quits.
- os.queueEvent("monitor_touch", "monitor_24", 1, 1)
- end
- clearMainPanel()
- g.drawText(mon, 1, 8, "Export complete!", colors.lime, colors.black)
- g.drawText(mon, 1, 10, totalItemsExported .. " items exported.", colors.white, colors.black)
- playNotes("bell", {8, 12, 16, 20}, 0.5)
- os.sleep(3)
- end
- local function handleExportEvents()
- while EXPORTING do
- local event, monName, x, y = os.pullEvent("monitor_touch")
- if monName == "monitor_24" and y >= H-2 then
- if x >= 27 then
- EXPORTING = false
- playNotes("harp", {12, 8})
- elseif x >= 14 then
- EXPORT_REPORT = true
- playNotes("hat", {14, 10})
- else
- EXPORT_SKIP = true
- playNotes("snare", {12})
- end
- end
- end
- end
- local function handleSchematicUrl(url)
- clearMainPanel()
- if url == nil then
- g.drawText(mon, 1, 8, "No URL was entered. Quitting.", colors.white, colors.black)
- RUNNING = false
- os.sleep(2)
- return
- end
- g.drawText(mon, 1, 7, "Fetching item lists from URL...", colors.lightGray, colors.black)
- local itemLists, err = fetchItemLists(url)
- if not itemLists then
- g.drawText(mon, 1, 8, "Failed to fetch item lists.", colors.red, colors.black)
- g.drawText(mon, 1, 9, err, colors.red, colors.black)
- os.sleep(3)
- return
- end
- g.drawText(mon, 1, 8, "Got lists for "..(#itemLists).." schematics:", colors.white, colors.black)
- local y = 9
- for i, itemList in pairs(itemLists) do
- local count = itemList.__COUNT__
- local name = itemList.__NAME__
- g.drawText(mon, 2, y, count.."x "..name, colors.white, colors.black)
- y = y+1
- if y == H-3 and i < #itemLists then
- local numRemaining = #itemLists - i
- g.drawText(mon, 2, y, "... and "..numRemaining.." more.")
- break
- end
- end
- -- Draw continue and cancel buttons and wait for user input.
- g.fillRect(mon, 1, H-2, 18, 3, colors.gray)
- g.drawTextCenter(mon, 9, H-1, "Cancel", colors.white)
- g.fillRect(mon, 19, H-2, 21, 3, colors.green)
- g.drawTextCenter(mon, 29, H-1, "Continue", colors.white)
- local waiting = true
- while waiting do
- local event, monName, x, y = os.pullEvent("monitor_touch")
- if monName == "monitor_24" and y >= H-2 then
- if x <= 18 then
- -- Canceled, so quit the whole application.
- playNotes("harp", {12, 8})
- RUNNING = false
- return
- else
- playNotes("bell", {12, 16})
- waiting = false
- end
- end
- end
- -- Write instructions
- clearMainPanel()
- g.drawText(mon, 1, 8, "Export beginning shortly. Please read", colors.white, colors.black)
- g.drawText(mon, 1, 9, "these instructions beforehand:", colors.white, colors.black)
- g.drawText(mon, 1, 10, "Press", colors.white, colors.black)
- g.drawText(mon, 7, 10, "Skip", colors.white, colors.blue)
- g.drawText(mon, 13, 10, "to skip an item.", colors.white, colors.black)
- g.drawText(mon, 1, 11, "Press", colors.white, colors.black)
- g.drawText(mon, 7, 11, "Report", colors.white, colors.orange)
- g.drawText(mon, 14, 11, "to report an invalid item.", colors.white, colors.black)
- g.drawText(mon, 1, 12, "Press", colors.white, colors.black)
- g.drawText(mon, 7, 12, "Quit", colors.white, colors.red)
- g.drawText(mon, 12, 12, "to stop the export.", colors.white, colors.black)
- -- Draw control buttons.
- g.fillRect(mon, 1, H-2, 13, 3, colors.blue)
- g.drawText(mon, 5, H-1, "Skip", colors.white)
- g.fillRect(mon, 14, H-2, 13, 3, colors.orange)
- g.drawText(mon, 17, H-1, "Report", colors.white)
- g.fillRect(mon, 27, H-2, 13, 3, colors.red)
- g.drawText(mon, 31, H-1, "Quit", colors.white)
- for i = 1, 5 do
- g.drawText(mon, 1, H-4, "Starting in "..(5-i+1), colors.white, colors.black)
- os.sleep(1)
- end
- EXPORTING = true
- local fExport = function() exportSchematics(itemLists) end
- local fHandleEvents = function() handleExportEvents() end
- parallel.waitForAll(fExport, fHandleEvents)
- end
- -- MAIN SCRIPT
- g.clear(mon, colors.black)
- g.fillRect(mon, 1, 1, W, 3, colors.yellow)
- g.drawTextCenter(mon, W/2, 2, "Schematic Exporter", colors.black)
- g.fillRect(mon, 1, 4, W, 3, colors.gray)
- g.drawText(mon, 2, 4, "Progress", colors.white)
- g.drawXLine(mon, 2, W-1, 5, colors.lightGray)
- while RUNNING do
- local url = promptForUrlInput()
- handleSchematicUrl(url)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement