Advertisement
Tag365

OpenComputers Script Executer

May 22nd, 2017
314
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 17.98 KB | None | 0 0
  1. -- The Main Bootup Disk.
  2. do
  3.     _G._OSVERSION = "Script Executer V1.0"
  4.  
  5.     local component = component
  6.     local computer = computer
  7.     local unicode = unicode
  8.  
  9.     -- Runlevel information.
  10.     local runlevel, shutdown = "S", computer.shutdown
  11.     computer.runlevel = function() return runlevel end
  12.     computer.shutdown = function(reboot)
  13.         runlevel = reboot and 6 or 0
  14.         if os.sleep then
  15.             computer.pushSignal("shutdown")
  16.             os.sleep(0.1) -- Allow shutdown processing.
  17.         end
  18.         shutdown(reboot)
  19.     end
  20.  
  21.     -- Low level dofile implementation to read filesystem libraries.
  22.     local rom = {}
  23.     function rom.invoke(method, ...)
  24.         return component.invoke(computer.getBootAddress(), method, ...)
  25.     end
  26.     function rom.open(file) return rom.invoke("open", file) end
  27.     function rom.read(handle) return rom.invoke("read", handle, math.huge) end
  28.     function rom.close(handle) return rom.invoke("close", handle) end
  29.     function rom.inits() return ipairs(rom.invoke("list", "boot")) end
  30.     function rom.isDirectory(path) return rom.invoke("isDirectory", path) end
  31.  
  32.     local screen = component.list('screen')()
  33.     for address in component.list('screen') do
  34.         if #component.invoke(address, 'getKeyboards') > 0 then
  35.             screen = address
  36.         end
  37.     end
  38.  
  39.     -- Report boot progress if possible.
  40.     local gpu = component.list("gpu", true)()
  41.     local w, h
  42.     if gpu and screen then
  43.         component.invoke(gpu, "bind", screen)
  44.         w, h = component.invoke(gpu, "getResolution")
  45.         w, h = math.min(70, w), math.min(20, w)
  46.         component.invoke(gpu, "setResolution", w, h)
  47.         component.invoke(gpu, "setBackground", 0x000000)
  48.         component.invoke(gpu, "setForeground", 0xFFFFFF)
  49.         component.invoke(gpu, "fill", 1, 1, w, h, " ")
  50.     end
  51.     local x, y = 1, 1
  52.     local function status(msg)
  53.         if gpu and screen then
  54.             component.invoke(gpu, "set", x, y, msg)
  55.             if y == h then
  56.                 component.invoke(gpu, "copy", 1, 2, w, h - 1, 0, -1)
  57.                 component.invoke(gpu, "fill", 1, h, w, 1, " ")
  58.             else
  59.                 y = y + 1
  60.             end
  61.             x = 1
  62.         end
  63.     end
  64.     local function write(msg)
  65.         if gpu and screen then
  66.             component.invoke(gpu, "set", x, y, msg)
  67.             x = x + #msg
  68.         end
  69.     end
  70.    
  71.     local screenAPI = {}
  72.     function screenAPI.getResolution()
  73.         return w, h
  74.     end
  75.    
  76.     function screenAPI.setFgColor(color)
  77.         component.invoke(gpu, "setForeground", color)
  78.     end
  79.     function screenAPI.setBgColor(color)
  80.         component.invoke(gpu, "setBackground", color)
  81.     end
  82.     function screenAPI.set(...)
  83.         component.invoke(gpu, "set", ...)
  84.     end
  85.     function screenAPI.copy(...)
  86.         component.invoke(gpu, "copy", ...)
  87.     end
  88.     function screenAPI.fill(...)
  89.         component.invoke(gpu, "fill", ...)
  90.     end
  91.     function screenAPI.clear()
  92.         component.invoke(gpu, "setBackground", 0x000000)
  93.         component.invoke(gpu, "setForeground", 0xFFFFFF)
  94.         component.invoke(gpu, "fill", 1, 1, w, h, " ")
  95.     end
  96.     function screenAPI.cursor(newX, newY)
  97.         x, y = newX, newY
  98.     end
  99.     function screenAPI.getCursor()
  100.         return x, y
  101.     end
  102.    
  103.     _G.screen = screenAPI
  104.     _G.print = function(...)
  105.         local args = table.pack(...)
  106.         local stringToWrite = ""
  107.         for i = 1, args.n do
  108.             local arg = tostring(args[i])
  109.             if i > 1 then
  110.                 arg = string.rep(" ", 5 - (#stringToWrite%5)) .. arg
  111.             end
  112.             stringToWrite = stringToWrite..arg
  113.         end
  114.         status(stringToWrite)
  115.     end
  116.     _G.write = function(...)
  117.         local args = table.pack(...)
  118.         local stringToWrite = ""
  119.         for i = 1, args.n do
  120.             local arg = tostring(args[i])
  121.             if i > 1 then
  122.                 arg = " " .. arg
  123.             end
  124.             stringToWrite = stringToWrite..arg
  125.         end
  126.         write(stringToWrite)
  127.     end
  128. end
  129.  
  130. print(_OSVERSION)
  131.  
  132. -- Select a file system from one of the available filesystems.
  133. local filesystemComponents = {}
  134. local currentFS = component.list("filesystem")
  135. for address in component.list("filesystem") do
  136.     filesystemComponents[#filesystemComponents + 1] = address
  137. end
  138.  
  139. local selectedFilesystem = computer.getBootAddress()
  140.  
  141. -- Set up the filesystem API
  142. do
  143.     local filesystem = {}
  144.  
  145.     for key, value in pairs(component.methods(selectedFilesystem)) do
  146.         filesystem[key] = function(...)
  147.             return component.invoke(selectedFilesystem, key, ...)
  148.         end
  149.     end
  150.    
  151.     _G.filesystem = filesystem
  152. end
  153.  
  154. -- Set up some extra functions
  155. do
  156.     function loadfile(path, ...)
  157.         local handle, reason = filesystem.open(path)
  158.         if not handle then
  159.             error(reason, 2)
  160.         end
  161.         local buffer = ""
  162.         repeat
  163.             local data, reason = filesystem.read(handle)
  164.             if not data and reason then
  165.                 error(reason)
  166.             end
  167.             buffer = buffer .. (data or "")
  168.         until not data
  169.         filesystem.close(handle)
  170.         return load(buffer, "=" .. path)
  171.     end
  172.    
  173.     local loadfilefordofile = function(path, ...)
  174.         local handle, reason = filesystem.open(path)
  175.         if not handle then
  176.             return false, reason
  177.         end
  178.         local buffer = ""
  179.         repeat
  180.             local data, reason = filesystem.read(handle, 2048)
  181.             if not data and reason then
  182.                 error(reason)
  183.             end
  184.             buffer = buffer .. (data or "")
  185.         until not data
  186.         filesystem.close(handle)
  187.         return load(buffer, "=" .. path)
  188.     end
  189.  
  190.     function dofile(file, ...)
  191.         local program, reason = loadfilefordofile(file)
  192.         if program then
  193.             local result = table.pack(pcall(program, ...))
  194.             if result[1] then
  195.                 return table.unpack(result, 2, result.n)
  196.             else
  197.                 error(result[2], 2)
  198.             end
  199.         else
  200.             error(reason, 2)
  201.         end
  202.     end
  203. end
  204.  
  205. local commands = {}
  206. local keysDown = {}
  207.  
  208. local keysToCharsShift = {
  209.     [2] = "!",
  210.     [3] = "@",
  211.     [4] = "#",
  212.     [5] = "$",
  213.     [6] = "%",
  214.     [7] = "^",
  215.     [8] = "&",
  216.     [9] = "*",
  217.     [10] = "(",
  218.     [11] = ")",
  219.     [12] = "_",
  220.     [13] = "+",
  221.    
  222.     [26] = "{",
  223.     [27] = "}",
  224.     [43] = "|",
  225.    
  226.     [39] = ":",
  227.     [40] = '"',
  228.    
  229.     [51] = "<",
  230.     [52] = ">",
  231.     [53] = "?",
  232. }
  233. local keysToChars = {
  234.     [2] = "1",
  235.     [3] = "2",
  236.     [4] = "3",
  237.     [5] = "4",
  238.     [6] = "5",
  239.     [7] = "6",
  240.     [8] = "7",
  241.     [9] = "8",
  242.     [10] = "9",
  243.     [11] = "0",
  244.     [12] = "-",
  245.     [13] = "=",
  246.    
  247.     [16] = "q",
  248.     [17] = "w",
  249.     [18] = "e",
  250.     [19] = "r",
  251.     [20] = "t",
  252.     [21] = "y",
  253.     [22] = "u",
  254.     [23] = "i",
  255.     [24] = "o",
  256.     [25] = "p",
  257.     [26] = "[",
  258.     [27] = "]",
  259.     [43] = "\\",
  260.    
  261.     [30] = "a",
  262.     [31] = "s",
  263.     [32] = "d",
  264.     [33] = "f",
  265.     [34] = "g",
  266.     [35] = "h",
  267.     [36] = "j",
  268.     [37] = "k",
  269.     [38] = "l",
  270.     [39] = ";",
  271.     [40] = "'",
  272.    
  273.     [44] = "z",
  274.     [45] = "x",
  275.     [46] = "c",
  276.     [47] = "v",
  277.     [48] = "b",
  278.     [49] = "n",
  279.     [50] = "m",
  280.     [51] = ",",
  281.     [52] = ".",
  282.     [53] = "/",
  283.    
  284.     [57] = " ",
  285. }
  286.  
  287. -- Allows for obtaining text input from the user.
  288. function read(history)
  289.     local text, lastText = "", ""
  290.     local inputPosX, inputPosY = screen.getCursor()
  291.     local cursorX = 1
  292.     local selectedOption = 1
  293.    
  294.     --
  295.     if history then
  296.         selectedOption = #history + 1
  297.     end
  298.    
  299.     while true do
  300.         screen.cursor(inputPosX, inputPosY)
  301.         write(text.."              ")
  302.         screen.cursor(inputPosX + cursorX - 1, inputPosY)
  303.         write(unicode.char(0x2588))
  304.        
  305.         -- Wait for the next event and then perform an operation relating to the operation
  306.         local event = {computer.pullSignal()}
  307.         if event[1] == "key_up" then
  308.             keysDown[event[4]] = false
  309.         elseif event[1] == "key_down" then
  310.             keysDown[event[4]] = true
  311.         end
  312.         if event[1] == "key_down" then
  313.             -- Try to add the character.
  314.             if keysDown[42] then -- The shift key was held.
  315.                 if keysToCharsShift[event[4]] then
  316.                     text = text:sub(1, cursorX - 1)..keysToCharsShift[event[4]]..text:sub(cursorX)
  317.                     cursorX = cursorX + 1
  318.                     lastText = text
  319.                 elseif keysToChars[event[4]] then
  320.                     text = text:sub(1, cursorX - 1)..string.upper(keysToChars[event[4]])..text:sub(cursorX)
  321.                     cursorX = cursorX + 1
  322.                     lastText = text
  323.                 end
  324.             else -- The shift key was not held.
  325.                 if keysToChars[event[4]] then
  326.                     text = text:sub(1, cursorX - 1)..keysToChars[event[4]]..text:sub(cursorX)
  327.                     cursorX = cursorX + 1
  328.                     lastText = text
  329.                 end
  330.             end
  331.            
  332.             if event[4] == 14 then -- The user pressed the backspace button.
  333.                 if cursorX > 1 then
  334.                     text = text:sub(1, cursorX - 2)..text:sub(cursorX)
  335.                     cursorX = math.max(1, cursorX - 1)
  336.                     lastText = text
  337.                 end
  338.             elseif event[4] == 211 then -- The user pressed the delete button.
  339.                 if cursorX < #text then
  340.                     text = text:sub(1, cursorX)..text:sub(cursorX + 2)
  341.                     cursorX = math.min(cursorX, #text)
  342.                     lastText = text
  343.                 end
  344.             elseif event[4] == 28 then -- The user pressed the enter button.
  345.                 screen.cursor(inputPosX, inputPosY)
  346.                 print(text.."    ")
  347.                 return text
  348.             elseif event[4] == 199 then -- The user pressed the home button.
  349.                 cursorX = 1
  350.             elseif event[4] == 207 then -- The user pressed the end button.
  351.                 cursorX = #text + 1
  352.             elseif event[4] == 203 then -- The user pressed the left button.
  353.                 cursorX = math.max(1, cursorX - 1)
  354.             elseif event[4] == 205 then -- The user pressed the right button.
  355.                 cursorX = math.min(#text + 1, cursorX + 1)
  356.             elseif event[4] == 200 then -- The user pressed the up button.
  357.                 if type(history) == "table" then
  358.                     if #history > 0 then
  359.                         selectedOption = math.max(selectedOption - 1, 1)
  360.                         text = history[selectedOption]
  361.                     end
  362.                 end
  363.             elseif event[4] == 208 then -- The user pressed the down button.
  364.                 if type(history) == "table" then
  365.                     if #history > 0 then
  366.                         selectedOption = math.min(selectedOption + 1, #history + 1)
  367.                         text = history[selectedOption] or lastText
  368.                     end
  369.                 end
  370.             end
  371.         end
  372.  
  373.         -- Shut down the computer if the Ctrl-s key combo is pressed.
  374.         if keysDown[29] and keysDown[31] then
  375.             computer.shutdown(false)
  376.         elseif keysDown[29] and keysDown[19] then
  377.             computer.shutdown(true)
  378.         end
  379.     end
  380. end
  381.  
  382. -- Edit a script --
  383. commands[18] = function()
  384.     print("Type in the path of the script you want to edit.")
  385.     local path = read()
  386.     if path == "" then
  387.         return
  388.     end
  389.    
  390.     -- Load the script
  391.     local scriptLines = {}
  392.     do
  393.         local handle, reason = filesystem.open(path)
  394.         if handle then
  395.             local buffer = ""
  396.             repeat
  397.                 local data, reason = filesystem.read(handle, 2048)
  398.                 if not data and reason then
  399.                     error(reason)
  400.                 end
  401.                 buffer = buffer .. (data or "")
  402.             until not data
  403.             filesystem.close(handle)
  404.             for line in buffer:gmatch("[^\r\n]*") do
  405.                 scriptLines[#scriptLines + 1] = line
  406.             end
  407.         end
  408.     end
  409.    
  410.     -- Set up the commands
  411.     local getArgument = function(value, expectedType, messageString)
  412.         while true do
  413.             if expectedType == "number" and tonumber(value) then
  414.                 break
  415.             elseif expectedType == "string" and type(value) == "string" then
  416.                 break
  417.             elseif expectedType == "boolean" then
  418.                 local evalValue = value:lower()
  419.                 if evalValue == ("yes"):sub(1, #evalValue) then
  420.                     return true
  421.                 elseif evalValue == ("true"):sub(1, #evalValue) then
  422.                     return true
  423.                 elseif evalValue == ("no"):sub(1, #evalValue) then
  424.                     return false
  425.                 elseif evalValue == ("false"):sub(1, #evalValue) then
  426.                     return false
  427.                 elseif evalValue == ("cancel"):sub(1, #evalValue) then
  428.                     return false
  429.                 end
  430.             end
  431.             print(messageString)
  432.             value = read()
  433.         end
  434.         return value
  435.     end
  436.     local editCommands = {}
  437.    
  438.     -- Show a list of actions
  439.     function editCommands.actions()
  440.         print("Actions: ")
  441.         print("'Actions' shows this again")
  442.         print("'Edit [line] [text]' edits a line of text")
  443.         print("'View [line]' displays a line of text")
  444.         --print("'Insert [otherpath] [line]' inserts another script into this one")
  445.         print("'Save [newpath]' saves the script")
  446.         print("'Exit' will exit the script editor.")
  447.         print("Save before exiting if you wanted to modify the script.")
  448.     end
  449.     editCommands.help = editCommands.actions
  450.    
  451.     -- Edits a line of text
  452.     function editCommands.edit(line, text)
  453.         line = getArgument(line, "number", "Type in the line you want to edit.")
  454.         text = getArgument(line, "string", "Type in the text you want to replace line '"..line.."' with.")
  455.         scriptLines[line] = text
  456.     end
  457.    
  458.     -- Displays a line of text
  459.     function editCommands.view(line)
  460.         line = getArgument(line, "number", "Type in the line you want to view.")
  461.         print(scriptLines[line])
  462.     end
  463.    
  464.     -- Saves the script
  465.     function editCommands.save(newpath)
  466.         newpath = newpath or path
  467.         local savehandle, errorMessage = filesystem.open(newpath)
  468.         if savehandle then
  469.             filesystem.write(savehandle, scriptLines[1])
  470.             for line = 2, #scriptLines do
  471.                 filesystem.write(savehandle, "\n"..scriptLines[line])
  472.             end
  473.             filesystem.close()
  474.             print("Saved to '"..newpath.."'")
  475.         else
  476.             screen.setFgColor(0xFF0000)
  477.             print("Save failed: "..tostring(errorMessage))
  478.             screen.setFgColor(0xFFFFFF)
  479.         end
  480.     end
  481.    
  482.     -- Open the text editor
  483.     editCommands.actions()
  484.     while true do
  485.         local givenCommand = read()
  486.         local command
  487.         local arguments = {}
  488.         for word in givenCommand:gmatch("%w+") do
  489.             if command then
  490.                 arguments[#arguments + 1] = word
  491.             else
  492.                 command = word:lower()
  493.             end
  494.         end
  495.        
  496.         if editCommands[command] then
  497.             editCommands[command](table.unpack(arguments))
  498.         elseif command == "exit" or command == "end" or command == "return" then
  499.             return
  500.         else
  501.             print("That is not a known command.")
  502.         end
  503.     end
  504. end
  505.  
  506. -- Run a script --
  507. commands[19] = function()
  508.     print("Type in the path of the script you want to run.")
  509.     local scriptName = read()
  510.     local ok, errorMessage = pcall(dofile, scriptName)
  511.     if not ok then
  512.         screen.setFgColor(0xFF0000)
  513.         print(errorMessage)
  514.         screen.setFgColor(0xFFFFFF)
  515.     end
  516. end
  517.  
  518. -- Directory listing --
  519. commands[32] = function()
  520.     print("Type in the directory to list.")
  521.     local path = read()
  522.     local items = filesystem.list(path)
  523.     if items then
  524.         print((#items == 1 and "One item" or (#items.." items")).." found in "..(path ~= "" and "'"..path.."'" or "the root")..".")
  525.         for key, value in ipairs(items) do
  526.             print(value)
  527.         end
  528.     else
  529.         print("'"..path.."' is not a directory.")
  530.     end
  531. end
  532.  
  533. -- Select a new filesystem --
  534. commands[31] = function()
  535.     print("List of filesystems")
  536.     local selections = {}
  537.     for key, value in pairs(filesystemComponents) do
  538.         selections[key] = value
  539.         print(key..": "..value, (component.invoke(value, "getLabel") or "No label"))
  540.         local totalSpace, usedSpace = component.invoke(value, "spaceTotal"), component.invoke(value, "spaceUsed")
  541.         local freeSpace = totalSpace - usedSpace
  542.         local freeSpacePercent = math.floor(((totalSpace - usedSpace)/totalSpace)*1000)*.1
  543.         print(freeSpacePercent.."% free", "Total space: "..totalSpace.." bytes", "Used space: "..usedSpace.." bytes")
  544.     end
  545.     print("Select a filesystem: ")
  546.     while true do
  547.         local answer = read(selections)
  548.         if tonumber(answer) then
  549.             answer = selections[tonumber(answer)] or answer
  550.         end
  551.        
  552.         -- Select the correct address.
  553.         local newSelectedFilesystem
  554.         for key, value in pairs(filesystemComponents) do
  555.             local label = component.invoke(value, "getLabel")
  556.             if answer == value:sub(1, #answer) then
  557.                 -- The user typed in the address of the filesystem. We are done, select it.
  558.                 newSelectedFilesystem = value
  559.                 break
  560.             elseif (answer == label) and label then
  561.                 -- Similarly, the user can type in the label of the filesystem.
  562.                 answer = value
  563.                 break
  564.             end
  565.         end
  566.        
  567.         -- If the newSelectedFilesystem variable has been set, then we can select it as the filesystem.
  568.         if newSelectedFilesystem then
  569.             -- Check if the filesystem exists first.
  570.             selectedFilesystem = newSelectedFilesystem
  571.            
  572.             print("The selected filesystem is now "..selectedFilesystem)
  573.             return
  574.         end
  575.         print("That is not a valid filesystem. Please type in the number of the filesystem you want to use.")
  576.     end
  577. end
  578.  
  579. -- Lua prompt --
  580. commands[38] = function()
  581.     print("Lua prompt")
  582.     local history = {}
  583.     while true do
  584.         local line = read(history)
  585.        
  586.         -- Insert this line into the history, but only if is not in the history.
  587.         local doInsert = true
  588.         for key = 1, #history do
  589.             if history[key] == line then
  590.                 doInsert = false
  591.             end
  592.         end
  593.        
  594.         if doInsert then
  595.             history[#history + 1] = line
  596.         end
  597.        
  598.         -- Load the script if possible. If not, return an error.
  599.         local script, errorMessage = load(line, "=script")
  600.         if script then
  601.             local returnedValues = {pcall(script)}
  602.            
  603.             -- Print returned values unless an error occured, in which case print the error in red.
  604.             if returnedValues[1] then
  605.                 table.remove(returnedValues, 1)
  606.                 if #returnedValues > 0 then
  607.                     print(table.unpack(returnedValues))
  608.                 end
  609.             else
  610.                 screen.setFgColor(0xFF0000)
  611.                 print(returnedValues[2])
  612.                 screen.setFgColor(0xFFFFFF)
  613.             end
  614.         else
  615.             screen.setFgColor(0xFF0000)
  616.             print(errorMessage)
  617.             screen.setFgColor(0xFFFFFF)
  618.         end
  619.     end
  620. end
  621.  
  622. -- Print components --
  623. commands[46] = function()
  624.     for key, value in component.list() do
  625.         print(key, value)
  626.         local methods = component.methods(key)
  627.         if type(methods) == "table" then
  628.             for key2, value2 in pairs(methods) do
  629.                 print("    ", key2, ((value2 == true and "Direct") or "Indirect").." function")
  630.             end
  631.             computer.pullSignal("key_up")
  632.         end
  633.     end
  634. end
  635.  
  636. -- Command list --
  637. commands[35] = function()
  638.     print("Selected filesystem is "..selectedFilesystem)
  639.     print("Press 's' to select a new filesystem")
  640.     print("Press 'e' to edit a script")
  641.     print("Press 'd' to show a list of files")
  642.     print("Press 'l' to open a Lua prompt")
  643.     print("Press 'r' to run a script")
  644.     print("Press 'c' to print all available components")
  645.     print("Press 'h' to show this again")
  646.     print("Hold 'Ctrl' and 'e' to enable or disable the printing of events here")
  647.     print("Hold 'Ctrl' and 'r' to reboot")
  648.     print("Hold 'Ctrl' and 's' to shutdown")
  649. end
  650.  
  651. local ok, errorMessage = pcall(dofile, "autorun.lua")
  652. if not ok and errorMessage ~= "file not found" then
  653.     screen.setFgColor(0xFF0000)
  654.     print(errorMessage)
  655.     screen.setFgColor(0xFFFFFF)
  656. end
  657.  
  658. local printEvents = false
  659. commands[35]()
  660. while true do
  661.     local event = {computer.pullSignal()}
  662.     if printEvents then
  663.         print(table.unpack(event))
  664.     end
  665.     if event[1] == "key_up" then
  666.         keysDown[event[4]] = false
  667.     elseif event[1] == "key_down" then
  668.         keysDown[event[4]] = true
  669.     end
  670.     if keysDown[29] and keysDown[31] then
  671.         computer.shutdown(false)
  672.     elseif keysDown[29] and keysDown[19] then
  673.         computer.shutdown(true)
  674.     elseif keysDown[29] and keysDown[18] then
  675.         printEvents = not printEvents
  676.         print((printEvents and "Now" or "No longer").." printing events on this screen")
  677.     elseif commands[event[4]] then
  678.         print("")
  679.         commands[event[4]]()
  680.     end
  681. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement