Advertisement
Guest User

LyqydOs/env bug report version

a guest
Feb 23rd, 2017
194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 17.08 KB | None | 0 0
  1. --Peripheral modifications.
  2. do
  3.     local oldPeripheralCall = peripheral.call
  4.  
  5.     function peripheral.call(side, func, ...)
  6.         if peripheral.getType(side) == "modem" then
  7.             if func == "isOpen" then
  8.                 local proc = process.id() and process.list[process.id()]
  9.                 if not proc then return false end
  10.                 if not proc.modem then return false end
  11.                 if not proc.modem[side] then return false end
  12.                 if proc.modem[side][(...)] then return true end
  13.                 return false
  14.             elseif func == "open" then
  15.                 local proc = process.list[process.id()]
  16.                 if not proc.modem then proc.modem = {} end
  17.                 if not proc.modem[side] then proc.modem[side] = {} end
  18.                 local channel = (...)
  19.                 proc.modem[side][channel] = true
  20.                 oldPeripheralCall(side, func, channel)
  21.             elseif func == "close" then
  22.                 local proc = process.list[process.id()]
  23.                 if not proc.modem then return nil end
  24.                 if not proc.modem[side] then return nil end
  25.                 local channel = (...)
  26.                 if proc.modem[side][channel] then
  27.                     proc.modem[side][channel] = nil
  28.                     local close = true
  29.                     for pID, pInfo in pairs(process.list) do
  30.                         if pInfo and pInfo.modem and pInfo.modem[side] and pInfo.modem[side][channel] then
  31.                             close = false
  32.                             break
  33.                         end
  34.                     end
  35.                     if close then return oldPeripheralCall(side, func, channel) end
  36.                 end
  37.             elseif func == "closeAll" then
  38.                 local proc = process.list[process.id()]
  39.                 if not proc.modem then return nil end
  40.                 if not proc.modem[side] then return nil end
  41.                 for channel in pairs(proc.modem[side]) do
  42.                     peripheral.call(side, "close", channel)
  43.                 end
  44.             else
  45.                 return oldPeripheralCall(side, func, ...)
  46.             end
  47.         else
  48.             return oldPeripheralCall(side, func, ...)
  49.         end
  50.     end
  51. end
  52.  
  53. --Rednet modifications
  54. do
  55.     local validSides = {}
  56.     for k, v in pairs(rs.getSides()) do
  57.         validSides[v] = true
  58.     end
  59.  
  60.     local function validateSide(side)
  61.         if type(side) ~= "string" then
  62.             error("string expected", 3)
  63.         end
  64.         if not validSides[side] then
  65.             error("Invalid side", 3)
  66.         end
  67.         if peripheral.getType(side) ~= "modem" then
  68.             error("No modem on "..side.." side", 3)
  69.         end
  70.         return true
  71.     end
  72.  
  73.     function rednet.open(side)
  74.         if validateSide(side) then
  75.             local proc = process.this()
  76.             if not proc.rednet then proc.rednet = {} end
  77.             proc.rednet[side] = true
  78.             peripheral.call(side, "open", os.getComputerID())
  79.             peripheral.call(side, "open", 65535)
  80.         end
  81.     end
  82.  
  83.     function rednet.close(side)
  84.         if validateSide(side) then
  85.             local proc = process.this()
  86.             if not proc.rednet then return nil end
  87.             proc.rednet[side] = nil
  88.             peripheral.call(side, "close", os.getComputerID())
  89.             peripheral.call(side, "close", 65535)
  90.         end
  91.     end
  92.  
  93.     function rednet.isOpen(side)
  94.         if side then
  95.             if type(side) ~= "string" then
  96.                 error("expected string", 2)
  97.             end
  98.             if peripheral.getType(side) == "modem" then
  99.                 local proc = process.this()
  100.                 if not proc.modem then return false end
  101.                 if not proc.modem[side] then return false end
  102.                 return (proc.modem[side][os.getComputerID()] and proc.modem[side][65535]) or false
  103.             end
  104.         else
  105.             for n, side in ipairs(peripheral.getNames()) do
  106.                 if rednet.isOpen(side) then
  107.                     return true
  108.                 end
  109.             end
  110.         end
  111.     end
  112.  
  113.     function rednet.send(recipient, message, protocol)
  114.         for _, side in pairs(rs.getSides()) do
  115.             if peripheral.getType(side) == "modem" and rednet.isOpen(side) then
  116.                 if term.current then
  117.                     local id = math.random(1, 2147483547)
  118.                     local messTable = {
  119.                         nMessageID = id,
  120.                         nRecipient = recipient,
  121.                         message = message,
  122.                         sProtocol = protocol,
  123.                     }
  124.                     peripheral.call(side, "transmit", recipient, os.getComputerID(), messTable)
  125.                     peripheral.call(side, "transmit", 65533, os.getComputerID(), messTable)
  126.                 else
  127.                     peripheral.call(side, "transmit", recipient, os.getComputerID(), message)
  128.                 end
  129.                 return true
  130.             end
  131.         end
  132.         error("No open sides", 2)
  133.     end
  134.  
  135.     function rednet.broadcast(message, protocol)
  136.         return rednet.send(65535, message, protocol)
  137.     end
  138.  
  139.     function rednet.host(protocol, hostname)
  140.         if type(protocol) ~= "string" or type(hostname) ~= "string" then
  141.             error("expected string, string", 2)
  142.         end
  143.         if hostname == "localhost" then
  144.             error("Reserved hostname", 2)
  145.         end
  146.         local proc = process.this()
  147.         if not proc.rednet then proc.rednet = {} end
  148.         if not proc.rednet.hosting then proc.rednet.hosting = {} end
  149.         if rednet.lookup(protocol, hostname) ~= nil then
  150.             error("Hostname in use", 2)
  151.         end
  152.         proc.rednet.hosting[protocol] = hostname
  153.     end
  154.  
  155.     function rednet.unhost(protocol)
  156.         if type(protocol) ~= "string" then
  157.             error("expected string", 2)
  158.         end
  159.         local proc = process.this()
  160.         if not proc.rednet then return end
  161.         if not proc.rednet.hosting then return end
  162.         proc.rednet.hosting[protocol] = nil
  163.     end
  164.  
  165.     function rednet.lookup(protocol, hostname)
  166.         if type(protocol) ~= "string" then
  167.             error("expected string", 2)
  168.         end
  169.  
  170.         local result
  171.         if not hostname then
  172.             result = {}
  173.         end
  174.  
  175.         for pID, proc in ipairs(process.list) do
  176.             if proc and proc.rednet and proc.rednet.hosting then
  177.                 if proc.rednet.hosting[protocol] then
  178.                     if not hostname then
  179.                         table.insert(result, os.getComputerID())
  180.                     elseif hostname == "localhost" or hostname == proc.rednet.hosting[protocol] then
  181.                         return os.getComputerID()
  182.                     end
  183.                 end
  184.             end
  185.         end
  186.  
  187.         if not rednet.isOpen() then
  188.             if result then
  189.                 unpack(result)
  190.             end
  191.             return nil
  192.         end
  193.  
  194.         rednet.broadcast({sType = "lookup", sProtocol = protocol, sHostname = hostname,}, "dns")
  195.  
  196.         local timer = os.startTimer(2)
  197.         while true do
  198.             local event = {os.pullEvent()}
  199.             if event[1] == "rednet_message" then
  200.                 if event[4] == "dns" and event[3].sType == "lookup response" then
  201.                     if event[3].sProtocol == protocol then
  202.                         if not hostname then
  203.                             table.insert(result, event[2])
  204.                         elseif event[3].sHostname == hostname then
  205.                             return event[2]
  206.                         end
  207.                     end
  208.                 end
  209.             elseif event[1] == "timer" and event[2] == timer then
  210.                 break
  211.             end
  212.         end
  213.         if result then
  214.             return unpack(result)
  215.         end
  216.     end
  217. end
  218.  
  219. --FS modifications.
  220. do
  221.     local oldfs = {}
  222.     for k, v in pairs(fs) do
  223.         if type(k) == "string" and type(v) == "function" then
  224.             oldfs[k] = v
  225.         end
  226.     end
  227.  
  228.     LyqydOS.fs = {}
  229.     LyqydOS.fs.raw = oldfs
  230.     LyqydOS.fs.mounts = {}
  231.  
  232.     LyqydOS.fs.canMountToPath = function(path)
  233.         if string.sub(path, 1, 1) ~= "/" then
  234.             path = "/"..path
  235.         end
  236.         for i, mount in ipairs(LyqydOS.fs.mounts) do
  237.             if mount and mount.path == path then
  238.                 return false
  239.             end
  240.         end
  241.         if LyqydOS.fs.raw.exists(path) and LyqydOS.fs.raw.isDir(path) then
  242.             local list = LyqydOS.fs.raw.list(path)
  243.             if #list == 0 then
  244.                 return true
  245.             end
  246.         end
  247.         return false
  248.     end
  249.  
  250.     local function getMountID(path)
  251.         if string.sub(path, 1, 1) ~= "/" then
  252.             path = "/"..path
  253.         end
  254.         local matchLen, matchID = 0, false
  255.         for i, mnt in ipairs(LyqydOS.fs.mounts) do
  256.             local match = string.match(path, "^("..mnt.path..")")
  257.             if match and #match > matchLen then
  258.                 matchLen = #match
  259.                 matchID = i
  260.             end
  261.         end
  262.         if matchID then
  263.             return matchID
  264.         end
  265.     end
  266.  
  267.     local function getMount(path)
  268.         local id = getMountID(path)
  269.         if id then
  270.             return LyqydOS.fs.mounts[id]
  271.         end
  272.     end
  273.  
  274.     local function getRelativePath(path, mount)
  275.         if string.sub(path, 1, 1) ~= "/" then
  276.             path = "/"..path
  277.         end
  278.         return string.match(path, "^"..mount.path.."(.*)")
  279.     end
  280.  
  281.     local function yield()
  282.         local key = tostring({})
  283.         os.queueEvent("vfs_yield", key)
  284.         local event, val
  285.         repeat
  286.             event, val = os.pullEvent()
  287.         until event == "vfs_yield" and val == key
  288.     end
  289.  
  290.     local fsTransformTable = {
  291.         "list",
  292.         "exists",
  293.         "isDir",
  294.         "isReadOnly",
  295.         "getSize",
  296.         "getFreeSpace",
  297.         "makeDir",
  298.         "delete",
  299.         "find",
  300.     }
  301.  
  302.     for i, name in ipairs(fsTransformTable) do
  303.         fs[name] = function(path)
  304.             local mnt = getMount(path)
  305.             if mnt then
  306.                 return mnt.mount[name](getRelativePath(path, mnt))
  307.             else
  308.                 return oldfs[name](path)
  309.             end
  310.         end
  311.     end
  312.  
  313.     fs.getDrive = function(path)
  314.         local id = getMountID(path)
  315.         if id then
  316.             return "lyq_vfs_"..tostring(id)
  317.         else
  318.             return oldfs.getDrive(path)
  319.         end
  320.     end
  321.  
  322.     fs.move = function(origin, destination)
  323.         local omnt = getMount(origin)
  324.         local dmnt = getMount(destination)
  325.         if omnt == dmnt and omnt then
  326.             --both file paths are within the same mount point
  327.             omnt.mount.move(getRelativePath(origin, omnt), getRelativePath(destination, omnt))
  328.         elseif omnt then
  329.             --the origin file has a mount point.
  330.             local data = omnt.mount.get(getRelativePath(origin, omnt))
  331.             if dmnt then
  332.                 dmnt.mount.put(getRelativePath(destination, dmnt), data)
  333.             else
  334.                 local handle = oldfs.open(destination, "wb")
  335.                 if handle then
  336.                     for i = 1, #data do
  337.                         handle.write(data[i])
  338.                         if i % 1000 == 0 then yield() end
  339.                     end
  340.                     handle.close()
  341.                 end
  342.             end
  343.             omnt.mount.delete(getRelativePath(origin, omnt))
  344.         elseif dmnt then
  345.             --the origin file does not have a mount point, but the destination does.
  346.             local handle = oldfs.open(origin, "rb")
  347.             if handle then
  348.                 local data = {}
  349.                 local num = handle.read()
  350.                 while num do
  351.                     table.insert(data, num)
  352.                     num = handle.read()
  353.                     if #data % 1000 == 0 then yield() end
  354.                 end
  355.                 dmnt.mount.put(getRelativePath(destination, dmnt), data)
  356.                 handle.close()
  357.             end
  358.             oldfs.delete(origin)
  359.         else
  360.             oldfs.move(origin, destination)
  361.         end
  362.     end
  363.  
  364.     fs.copy = function(origin, destination)
  365.         local omnt = getMount(origin)
  366.         local dmnt = getMount(destination)
  367.         if omnt == dmnt and omnt then
  368.             --both file paths are within the same mount point
  369.             omnt.mount.copy(getRelativePath(origin, omnt), getRelativePath(destination, omnt))
  370.         elseif omnt then
  371.             --the origin file has a mount point.
  372.             local data = omnt.mount.get(getRelativePath(origin, omnt))
  373.             if dmnt then
  374.                 dmnt.mount.put(getRelativePath(destination, dmnt), data)
  375.             else
  376.                 local handle = oldfs.open(destination, "wb")
  377.                 if handle then
  378.                     for i = 1, #data do
  379.                         handle.write(data[i])
  380.                         if i % 1000 == 0 then yield() end
  381.                     end
  382.                     handle.close()
  383.                 end
  384.             end
  385.         elseif dmnt then
  386.             --the origin file does not have a mount point, but the destination does.
  387.             local handle = oldfs.open(origin, "rb")
  388.             if handle then
  389.                 local data = {}
  390.                 local num = handle.read()
  391.                 while num do
  392.                     table.insert(data, num)
  393.                     num = handle.read()
  394.                     if #data % 1000 == 0 then yield() end
  395.                 end
  396.                 dmnt.mount.put(getRelativePath(destination, dmnt), data)
  397.                 handle.close()
  398.             end
  399.         else
  400.             oldfs.copy(origin, destination)
  401.         end
  402.     end
  403.  
  404.     fs.open = function(path, mode)
  405.         local mount = getMount(path)
  406.         if mount then
  407.             if mode == "r" then
  408.                 local data = string.char(unpack(mount.mount.get(getRelativePath(path, mount))))
  409.                 local seek = 0
  410.                 local handle = {
  411.                     readLine = function()
  412.                         if seek < #data then
  413.                             local line
  414.                             line, seek = string.match(data, "([^\n]*)\r?\n-()", seek + 1)
  415.                             return line
  416.                         end
  417.                     end,
  418.                     readAll = function()
  419.                         if seek <= #data then
  420.                             local line
  421.                             line, seek = string.match(data, "(.*)()", seek)
  422.                             return line
  423.                         end
  424.                     end,
  425.                     close = function()
  426.                         seek = #data + 1
  427.                     end,
  428.                 }
  429.                 return handle
  430.             elseif mode == "rb" then
  431.                 local data = mount.mount.get(getRelativePath(path, mount))
  432.                 local seek = 0
  433.                 local handle = {
  434.                     read = function()
  435.                         if seek < #data then
  436.                             seek = seek + 1
  437.                             return data[seek]
  438.                         end
  439.                     end,
  440.                     close = function()
  441.                         seek = #data
  442.                     end
  443.                 }
  444.                 return handle
  445.             elseif mode == "w" or mode == "a" then
  446.                 local data = ""
  447.                 if mode == "a" then
  448.                     data = string.char(unpack(mount.mount.get(getRelativePath(path, mount))))
  449.                 end
  450.                 local open = true
  451.                 local handle = {
  452.                     writeLine = function(str)
  453.                         if open then
  454.                             data = data..str.."\n"
  455.                         end
  456.                     end,
  457.                     write = function(str)
  458.                         if open then
  459.                             data = data..str
  460.                         end
  461.                     end,
  462.                     flush = function()
  463.                         if open then
  464.                             mount.mount.put(getRelativePath(path, mount), {string.byte(data, 1, -1)})
  465.                         end
  466.                     end,
  467.                     close = function()
  468.                         if open then
  469.                             mount.mount.put(getRelativePath(path, mount), {string.byte(data, 1, -1)})
  470.                             open = false
  471.                         end
  472.                     end,
  473.                 }
  474.                 return handle
  475.             elseif mode == "wb" or mode == "ab" then
  476.                 local data = {}
  477.                 if mode == "ab" then
  478.                     data = mount.mount.get(getRelativePath(path, mount))
  479.                 end
  480.                 local open = true
  481.                 local handle = {
  482.                     write = function(num)
  483.                         if open then
  484.                             data[#data + 1] = num
  485.                         end
  486.                     end,
  487.                     flush = function()
  488.                         if open then
  489.                             mount.mount.put(getRelativePath(path, mount), data)
  490.                         end
  491.                     end,
  492.                     close = function()
  493.                         if open then
  494.                             mount.mount.put(getRelativePath(path, mount), data)
  495.                             open = false
  496.                         end
  497.                     end,
  498.                 }
  499.                 return handle
  500.             end
  501.         else
  502.             return oldfs.open(path, mode)
  503.         end
  504.     end
  505. end
  506.  
  507. --Disk modifications.
  508. do
  509.     local oldGetMountPath = disk.getMountPath
  510.  
  511.     disk.getMountPath = function(side)
  512.         local drive, num = string.match(side, "(.-)_(%d+)$")
  513.         if drive == "lyq_vfs" then
  514.             return LyqydOS.fs.mounts[tonumber(num)].path
  515.         else
  516.             return oldGetMountPath(side)
  517.         end
  518.     end
  519. end
  520.  
  521. --Redstone modifications.
  522. do
  523.     local oldrs = {}
  524.     for k, v in pairs(rs) do
  525.         if type(k) == "string" and type(v) == "function" then
  526.             oldrs[k] = v
  527.         end
  528.     end
  529.  
  530.     local validSides = {}
  531.     for k, v in pairs(rs.getSides()) do
  532.         validSides[v] = true
  533.     end
  534.  
  535.     local function validate(side, value, exType)
  536.         if type(side) ~= "string" or type(value) ~= exType then
  537.             error("Expected string, "..exType)
  538.         end
  539.         if not validSides[side] then
  540.             error("Invalid side")
  541.         end
  542.         return true
  543.     end
  544.  
  545.     local function getCurrentValue(side)
  546.         local value = 0
  547.         for pID, pInfo in pairs(process.list) do
  548.             if pInfo and pInfo.redstone and pInfo.redstone[side] and pID ~= process.id() then
  549.                 value = math.max(value, pInfo.redstone[side].value)
  550.             end
  551.         end
  552.         return value
  553.     end
  554.  
  555.     local function getCurrentBundled(side)
  556.         local value = 0
  557.         for pID, pInfo in pairs(process.list) do
  558.             if pInfo and pInfo.redstone and pInfo.redstone[side] and pID ~= process.id() then
  559.                 value = bit.bor(value, pInfo.redstone[side].bundled)
  560.             end
  561.         end
  562.         return value
  563.     end
  564.  
  565.     redstone.setAnalogOutput = function(side, value)
  566.         if validate(side, value, "number") then
  567.             local current = getCurrentValue(side)
  568.             local proc = process.list[process.id()]
  569.             if not proc.redstone then proc.redstone = {} end
  570.             if not proc.redstone[side] then proc.redstone[side] = {} end
  571.             proc.redstone[side].value = value
  572.             value = math.max(value, current)
  573.             oldrs.setAnalogOutput(side, value)
  574.         end
  575.     end
  576.  
  577.     redstone.setOutput = function(side, value)
  578.         if validate(side, value, "boolean") then
  579.             redstone.setAnalogOutput(side, value == true and 15 or 0)
  580.         end
  581.     end
  582.  
  583.     redstone.setBundledOutput = function(side, value)
  584.         if validate(side, value, number) then
  585.             local current = getCurrentBundled(side)
  586.             local proc = process.list[process.id()]
  587.             if not proc.redstone then proc.redstone = {} end
  588.             if not proc.redstone[side] then proc.redstone[side] = {} end
  589.             proc.redstone[side].bundled = value
  590.             value = bit.bor(value, current)
  591.             oldrs.setBundledOutput(side, value)
  592.         end
  593.     end
  594. end
  595.  
  596. --shell and multishell modifications
  597. do
  598.     LyqydOS.shell.multishell.getTitle = function(n)
  599.         if process.list[n] then
  600.             return process.list[n].name
  601.         end
  602.     end
  603.  
  604.     LyqydOS.shell.multishell.setTitle = function(n, title)
  605.         if process.list[n] then
  606.             process.list[n].name = title
  607.         end
  608.     end
  609.  
  610.     LyqydOS.shell.multishell.getCount = function()
  611.         return #process.list
  612.     end
  613.  
  614.     LyqydOS.shell.multishell.launch = function(env, path, ...)
  615.         local args = {...}
  616.         if path then
  617.             local pid = #process.list + 1
  618.             local redirect, bufNum = process.compositor:newBuffer(pid)
  619.             process.new(function() os.run(env, shell.resolveProgram("lsh"), path, unpack(args)) end, shell.resolveProgram("lsh"), redirect)
  620.             process.compositor:toBack(bufNum)
  621.             return pid
  622.         else
  623.             return false
  624.         end
  625.     end
  626.  
  627.     LyqydOS.shell.multishell.getCurrent = function()
  628.         return process.id()
  629.     end
  630.  
  631.     LyqydOS.shell.multishell.getFocus = function()
  632.         return process.focus
  633.     end
  634.  
  635.     LyqydOS.shell.multishell.setFocus = function(n)
  636.         if process.list[n] then
  637.             local proc = process.list[n]
  638.             process.focus = n
  639.             --bring the buffer to the top
  640.             local buf = proc.firstRedirect.buffer
  641.             for i, layer in ipairs(process.compositor.bufferStack) do
  642.                 if layer == buf then
  643.                     process.compositor:toFront(i)
  644.                     break
  645.                 end
  646.             end
  647.         end
  648.     end
  649.  
  650.     LyqydOS.shell.shell.openTab = function(...)
  651.         local env = {shell = LyqydOS.shell.shell, multishell = LyqydOS.shell.multishell}
  652.         local command = table.concat({...}, " ")
  653.         local args = {}
  654.         for match in string.gmatch(command, "[^ \t]+") do
  655.             table.insert(args, match)
  656.         end
  657.         local path = table.remove(args, 1)
  658.         return LyqydOS.shell.multishell.launch(env, path, unpack(args))
  659.     end
  660.  
  661.     LyqydOS.shell.shell.switchTab = function(n)
  662.         LyqydOS.shell.multishell.setFocus(n)
  663.     end
  664. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement