Advertisement
MCFunRide

and again...

Aug 1st, 2015
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 20.62 KB | None | 0 0
  1.  
  2.  
  3. -- Install safe versions of various library functions
  4. -- These will not put cfunctions on the stack, so don't break serialisation
  5. xpcall = function( _fn, _fnErrorHandler )
  6.     local typeT = type( _fn )
  7.     assert( typeT == "function", "bad argument #1 to xpcall (function expected, got "..typeT..")" )
  8.     local co = coroutine.create( _fn )
  9.     local tResults = { coroutine.resume( co ) }
  10.     while coroutine.status( co ) ~= "dead" do
  11.         tResults = { coroutine.resume( co, coroutine.yield() ) }
  12.     end
  13.     if tResults[1] == true then
  14.         return true, unpack( tResults, 2 )
  15.     else
  16.         return false, _fnErrorHandler( tResults[2] )
  17.     end
  18. end
  19.  
  20. pcall = function( _fn, ... )
  21.     local typeT = type( _fn )
  22.     assert( typeT == "function", "bad argument #1 to pcall (function expected, got "..typeT..")" )
  23.     local tArgs = { ... }
  24.     return xpcall(
  25.         function()
  26.             return _fn( unpack( tArgs ) )
  27.         end,
  28.         function( _error )
  29.             return _error
  30.         end
  31.     )
  32. end
  33.  
  34. function pairs( _t )
  35.     local typeT = type( _t )
  36.     if typeT ~= "table" then
  37.         error( "bad argument #1 to pairs (table expected, got "..typeT..")", 2 )
  38.     end
  39.     return next, _t, nil
  40. end
  41.  
  42. function ipairs( _t )
  43.     local typeT = type( _t )
  44.     if typeT ~= "table" then
  45.         error( "bad argument #1 to ipairs (table expected, got "..typeT..")", 2 )
  46.     end
  47.     return function( t, var )
  48.         var = var + 1
  49.         local value = t[var]
  50.         if value == nil then
  51.             return
  52.         end
  53.         return var, value
  54.     end, _t, 0
  55. end
  56.  
  57. function coroutine.wrap( _fn )
  58.     local typeT = type( _fn )
  59.     if typeT ~= "function" then
  60.         error( "bad argument #1 to coroutine.wrap (function expected, got "..typeT..")", 2 )
  61.     end
  62.     local co = coroutine.create( _fn )
  63.     return function( ... )
  64.         local tResults = { coroutine.resume( co, ... ) }
  65.         if tResults[1] then
  66.             return unpack( tResults, 2 )
  67.         else
  68.             error( tResults[2], 2 )
  69.         end
  70.     end
  71. end
  72.  
  73. function string.gmatch( _s, _pattern )
  74.     local type1 = type( _s )
  75.     if type1 ~= "string" then
  76.         error( "bad argument #1 to string.gmatch (string expected, got "..type1..")", 2 )
  77.     end
  78.     local type2 = type( _pattern )
  79.     if type2 ~= "string" then
  80.         error( "bad argument #2 to string.gmatch (string expected, got "..type2..")", 2 )
  81.     end
  82.    
  83.     local nPos = 1
  84.     return function()
  85.         local nFirst, nLast = string.find( _s, _pattern, nPos )
  86.         if nFirst == nil then
  87.             return
  88.         end        
  89.         nPos = nLast + 1
  90.         return string.match( _s, _pattern, nFirst )
  91.     end
  92. end
  93.  
  94. local nativesetmetatable = setmetatable
  95. function setmetatable( _o, _t )
  96.     if _t and type(_t) == "table" then
  97.         local idx = rawget( _t, "__index" )
  98.         if idx and type( idx ) == "table" then
  99.             rawset( _t, "__index", function( t, k ) return idx[k] end )
  100.         end
  101.         local newidx = rawget( _t, "__newindex" )
  102.         if newidx and type( newidx ) == "table" then
  103.             rawset( _t, "__newindex", function( t, k, v ) newidx[k] = v end )
  104.         end
  105.     end
  106.     return nativesetmetatable( _o, _t )
  107. end
  108.  
  109. -- Install fix for luaj's broken string.sub/string.find
  110. local nativestringfind = string.find
  111. local nativestringsub = string.sub
  112. function string.sub( ... )
  113.     local r = nativestringsub( ... )
  114.     if r then
  115.         return r .. ""
  116.     end
  117.     return nil
  118. end
  119. function string.find( s, ... )
  120.     return nativestringfind( s .. "", ... );
  121. end
  122.  
  123. -- Install lua parts of the os api
  124. function os.version()
  125.     return "CraftOS 1.7"
  126. end
  127.  
  128. function os.pullEventRaw( sFilter )
  129.     return coroutine.yield( sFilter )
  130. end
  131.  
  132. function os.pullEvent( sFilter )
  133.     local eventData = { os.pullEventRaw( sFilter ) }
  134.     if eventData[1] == "terminate" then
  135.         error( "Terminated", 0 )
  136.     end
  137.     return unpack( eventData )
  138. end
  139.  
  140. -- Install globals
  141. function sleep( nTime )
  142.     local timer = os.startTimer( nTime or 0 )
  143.     repeat
  144.         local sEvent, param = os.pullEvent( "timer" )
  145.     until param == timer
  146. end
  147.  
  148. function write( sText )
  149.     local w,h = term.getSize()        
  150.     local x,y = term.getCursorPos()
  151.    
  152.     local nLinesPrinted = 0
  153.     local function newLine()
  154.         if y + 1 <= h then
  155.             term.setCursorPos(1, y + 1)
  156.         else
  157.             term.setCursorPos(1, h)
  158.             term.scroll(1)
  159.         end
  160.         x, y = term.getCursorPos()
  161.         nLinesPrinted = nLinesPrinted + 1
  162.     end
  163.    
  164.     -- Print the line with proper word wrapping
  165.     while string.len(sText) > 0 do
  166.         local whitespace = string.match( sText, "^[ \t]+" )
  167.         if whitespace then
  168.             -- Print whitespace
  169.             term.write( whitespace )
  170.             x,y = term.getCursorPos()
  171.             sText = string.sub( sText, string.len(whitespace) + 1 )
  172.         end
  173.        
  174.         local newline = string.match( sText, "^\n" )
  175.         if newline then
  176.             -- Print newlines
  177.             newLine()
  178.             sText = string.sub( sText, 2 )
  179.         end
  180.        
  181.         local text = string.match( sText, "^[^ \t\n]+" )
  182.         if text then
  183.             sText = string.sub( sText, string.len(text) + 1 )
  184.             if string.len(text) > w then
  185.                 -- Print a multiline word                
  186.                 while string.len( text ) > 0 do
  187.                     if x > w then
  188.                         newLine()
  189.                     end
  190.                     term.write( text )
  191.                     text = string.sub( text, (w-x) + 2 )
  192.                     x,y = term.getCursorPos()
  193.                 end
  194.             else
  195.                 -- Print a word normally
  196.                 if x + string.len(text) - 1 > w then
  197.                     newLine()
  198.                 end
  199.                 term.write( text )
  200.                 x,y = term.getCursorPos()
  201.             end
  202.         end
  203.     end
  204.    
  205.     return nLinesPrinted
  206. end
  207.  
  208. function print( ... )
  209.     local nLinesPrinted = 0
  210.     for n,v in ipairs( { ... } ) do
  211.         nLinesPrinted = nLinesPrinted + write( tostring( v ) )
  212.     end
  213.     nLinesPrinted = nLinesPrinted + write( "\n" )
  214.     return nLinesPrinted
  215. end
  216.  
  217. function printError( ... )
  218.     if term.isColour() then
  219.         term.setTextColour( colours.red )
  220.     end
  221.     local x,y = term.getCursorPos()
  222.     print( ... )
  223.     term.setTextColour( colours.white )
  224. end
  225.  
  226. function read( _sReplaceChar, _tHistory )
  227.     term.setCursorBlink( true )
  228.  
  229.     local sLine = ""
  230.     local nHistoryPos
  231.     local nPos = 0
  232.     if _sReplaceChar then
  233.         _sReplaceChar = string.sub( _sReplaceChar, 1, 1 )
  234.     end
  235.    
  236.     local w = term.getSize()
  237.     local sx = term.getCursorPos()
  238.    
  239.     local function redraw( _sCustomReplaceChar )
  240.         local nScroll = 0
  241.         if sx + nPos >= w then
  242.             nScroll = (sx + nPos) - w
  243.         end
  244.  
  245.         local cx,cy = term.getCursorPos()
  246.         term.setCursorPos( sx, cy )
  247.         local sReplace = _sCustomReplaceChar or _sReplaceChar
  248.         if sReplace then
  249.             term.write( string.rep( sReplace, math.max( string.len(sLine) - nScroll, 0 ) ) )
  250.         else
  251.             term.write( string.sub( sLine, nScroll + 1 ) )
  252.         end
  253.         term.setCursorPos( sx + nPos - nScroll, cy )
  254.     end
  255.    
  256.     while true do
  257.         local sEvent, param = os.pullEvent()
  258.         if sEvent == "char" then
  259.             -- Typed key
  260.             sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )
  261.             nPos = nPos + 1
  262.             redraw()
  263.  
  264.         elseif sEvent == "paste" then
  265.             -- Pasted text
  266.             sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )
  267.             nPos = nPos + string.len( param )
  268.             redraw()
  269.  
  270.         elseif sEvent == "key" then
  271.             if param == keys.enter then
  272.                 -- Enter
  273.                 break
  274.                
  275.             elseif param == keys.left then
  276.                 -- Left
  277.                 if nPos > 0 then
  278.                     nPos = nPos - 1
  279.                     redraw()
  280.                 end
  281.                
  282.             elseif param == keys.right then
  283.                 -- Right                
  284.                 if nPos < string.len(sLine) then
  285.                     redraw(" ")
  286.                     nPos = nPos + 1
  287.                     redraw()
  288.                 end
  289.            
  290.             elseif param == keys.up or param == keys.down then
  291.                 -- Up or down
  292.                 if _tHistory then
  293.                     redraw(" ")
  294.                     if param == keys.up then
  295.                         -- Up
  296.                         if nHistoryPos == nil then
  297.                             if #_tHistory > 0 then
  298.                                 nHistoryPos = #_tHistory
  299.                             end
  300.                         elseif nHistoryPos > 1 then
  301.                             nHistoryPos = nHistoryPos - 1
  302.                         end
  303.                     else
  304.                         -- Down
  305.                         if nHistoryPos == #_tHistory then
  306.                             nHistoryPos = nil
  307.                         elseif nHistoryPos ~= nil then
  308.                             nHistoryPos = nHistoryPos + 1
  309.                         end                        
  310.                     end
  311.                     if nHistoryPos then
  312.                         sLine = _tHistory[nHistoryPos]
  313.                         nPos = string.len( sLine )
  314.                     else
  315.                         sLine = ""
  316.                         nPos = 0
  317.                     end
  318.                     redraw()
  319.                 end
  320.             elseif param == keys.backspace then
  321.                 -- Backspace
  322.                 if nPos > 0 then
  323.                     redraw(" ")
  324.                     sLine = string.sub( sLine, 1, nPos - 1 ) .. string.sub( sLine, nPos + 1 )
  325.                     nPos = nPos - 1                    
  326.                     redraw()
  327.                 end
  328.             elseif param == keys.home then
  329.                 -- Home
  330.                 redraw(" ")
  331.                 nPos = 0
  332.                 redraw()        
  333.             elseif param == keys.delete then
  334.                 -- Delete
  335.                 if nPos < string.len(sLine) then
  336.                     redraw(" ")
  337.                     sLine = string.sub( sLine, 1, nPos ) .. string.sub( sLine, nPos + 2 )                
  338.                     redraw()
  339.                 end
  340.             elseif param == keys["end"] then
  341.                 -- End
  342.                 redraw(" ")
  343.                 nPos = string.len(sLine)
  344.                 redraw()
  345.             end
  346.  
  347.         elseif sEvent == "term_resize" then
  348.             -- Terminal resized
  349.             w = term.getSize()
  350.             redraw()
  351.  
  352.         end
  353.     end
  354.  
  355.     local cx, cy = term.getCursorPos()
  356.     term.setCursorBlink( false )
  357.     term.setCursorPos( w + 1, cy )
  358.     print()
  359.    
  360.     return sLine
  361. end
  362.  
  363. loadfile = function( _sFile )
  364.     local file = fs.open( _sFile, "r" )
  365.     if file then
  366.         local func, err = loadstring( file.readAll(), fs.getName( _sFile ) )
  367.         file.close()
  368.         return func, err
  369.     end
  370.     return nil, "File not found"
  371. end
  372.  
  373. dofile = function( _sFile )
  374.     local fnFile, e = loadfile( _sFile )
  375.     if fnFile then
  376.         setfenv( fnFile, getfenv(2) )
  377.         return fnFile()
  378.     else
  379.         error( e, 2 )
  380.     end
  381. end
  382.  
  383. -- Install the rest of the OS api
  384. function os.run( _tEnv, _sPath, ... )
  385.     local tArgs = { ... }
  386.     local fnFile, err = loadfile( _sPath )
  387.     if fnFile then
  388.         local tEnv = _tEnv
  389.         --setmetatable( tEnv, { __index = function(t,k) return _G[k] end } )
  390.         setmetatable( tEnv, { __index = _G } )
  391.         setfenv( fnFile, tEnv )
  392.         local ok, err = pcall( function()
  393.             fnFile( unpack( tArgs ) )
  394.         end )
  395.         if not ok then
  396.             if err and err ~= "" then
  397.                 printError( err )
  398.             end
  399.             return false
  400.         end
  401.         return true
  402.     end
  403.     if err and err ~= "" then
  404.         printError( err )
  405.     end
  406.     return false
  407. end
  408.  
  409. -- Prevent access to metatables or environments of strings, as these are global between all computers
  410. do
  411.     local getfenv = getfenv
  412.     local nativegetmetatable = getmetatable
  413.     local nativeerror = error
  414.     local nativetype = type
  415.     local string_metatable = nativegetmetatable("")
  416.     local string_env = getfenv(("").gsub)
  417.     function getmetatable( t )
  418.         local mt = nativegetmetatable( t )
  419.         if mt == string_metatable or mt == string_env then
  420.             nativeerror( "Attempt to access string metatable", 2 )
  421.         else
  422.             return mt
  423.         end
  424.     end
  425.     function getfenv( env )
  426.         if env == nil then
  427.             env = 2
  428.         elseif nativetype( env ) == "number" and env > 0 then
  429.             env = env + 1
  430.         end
  431.         local fenv = getfenv(env)
  432.         if fenv == string_metatable or fenv == string_env then
  433.             --nativeerror( "Attempt to access string metatable", 2 )
  434.             return getfenv( 0 )
  435.         else
  436.             return fenv
  437.         end
  438.     end
  439. end
  440.  
  441. local tAPIsLoading = {}
  442. function os.loadAPI( _sPath )
  443.     local sName = fs.getName( _sPath )
  444.     if tAPIsLoading[sName] == true then
  445.         printError( "API "..sName.." is already being loaded" )
  446.         return false
  447.     end
  448.     tAPIsLoading[sName] = true
  449.        
  450.     local tEnv = {}
  451.     setmetatable( tEnv, { __index = _G } )
  452.     local fnAPI, err = loadfile( _sPath )
  453.     if fnAPI then
  454.         setfenv( fnAPI, tEnv )
  455.         local ok, err = pcall( fnAPI )
  456.         if not ok then
  457.             printError( err )
  458.             tAPIsLoading[sName] = nil
  459.             return false
  460.         end
  461.     else
  462.         printError( err )
  463.         tAPIsLoading[sName] = nil
  464.         return false
  465.     end
  466.    
  467.     local tAPI = {}
  468.     for k,v in pairs( tEnv ) do
  469.         tAPI[k] =  v
  470.     end
  471.    
  472.     _G[sName] = tAPI    
  473.     tAPIsLoading[sName] = nil
  474.     return true
  475. end
  476.  
  477. function os.unloadAPI( _sName )
  478.     if _sName ~= "_G" and type(_G[_sName]) == "table" then
  479.         _G[_sName] = nil
  480.     end
  481. end
  482.  
  483. function os.sleep( nTime )
  484.     sleep( nTime )
  485. end
  486.  
  487. local nativeShutdown = os.shutdown
  488. function os.shutdown()
  489.     nativeShutdown()
  490.     while true do
  491.         coroutine.yield()
  492.     end
  493. end
  494.  
  495. local nativeReboot = os.reboot
  496. function os.reboot()
  497.     nativeReboot()
  498.     while true do
  499.         coroutine.yield()
  500.     end
  501. end
  502.  
  503. -- Install the lua part of the HTTP api (if enabled)
  504. if http then
  505.     local nativeHTTPRequest = http.request
  506.  
  507.     local function wrapRequest( _url, _post, _headers )
  508.         local ok, err = nativeHTTPRequest( _url, _post, _headers )
  509.         if ok then
  510.             while true do
  511.                 local event, param1, param2 = os.pullEvent()
  512.                 if event == "http_success" and param1 == _url then
  513.                     return param2
  514.                 elseif event == "http_failure" and param1 == _url then
  515.                     return nil, param2
  516.                 end
  517.             end
  518.         end
  519.         return nil, err
  520.     end
  521.    
  522.     http.get = function( _url, _headers )
  523.         return wrapRequest( _url, nil, _headers )
  524.     end
  525.  
  526.     http.post = function( _url, _post, _headers )
  527.         return wrapRequest( _url, _post or "", _headers )
  528.     end
  529.  
  530.     http.request = function( _url, _post, _headers )
  531.         local ok, err = nativeHTTPRequest( _url, _post, _headers )
  532.         if not ok then
  533.             os.queueEvent( "http_failure", _url, err )
  534.         end
  535.         return ok, err
  536.     end
  537. end
  538.  
  539. -- Load APIs
  540. local bAPIError = false
  541. local tApis = fs.list( "rom/apis" )
  542. for n,sFile in ipairs( tApis ) do
  543.     if string.sub( sFile, 1, 1 ) ~= "." then
  544.         local sPath = fs.combine( "rom/apis", sFile )
  545.         if not fs.isDir( sPath ) then
  546.             if not os.loadAPI( sPath ) then
  547.                 bAPIError = true
  548.             end
  549.         end
  550.     end
  551. end
  552.  
  553. if turtle then
  554.     -- Load turtle APIs
  555.     local tApis = fs.list( "rom/apis/turtle" )
  556.     for n,sFile in ipairs( tApis ) do
  557.         if string.sub( sFile, 1, 1 ) ~= "." then
  558.             local sPath = fs.combine( "rom/apis/turtle", sFile )
  559.             if not fs.isDir( sPath ) then
  560.                 if not os.loadAPI( sPath ) then
  561.                     bAPIError = true
  562.                 end
  563.             end
  564.         end
  565.     end
  566. end
  567.  
  568. if pocket and fs.isDir( "rom/apis/pocket" ) then
  569.     -- Load pocket APIs
  570.     local tApis = fs.list( "rom/apis/pocket" )
  571.     for n,sFile in ipairs( tApis ) do
  572.         if string.sub( sFile, 1, 1 ) ~= "." then
  573.             local sPath = fs.combine( "rom/apis/pocket", sFile )
  574.             if not fs.isDir( sPath ) then
  575.                 if not os.loadAPI( sPath ) then
  576.                     bAPIError = true
  577.                 end
  578.             end
  579.         end
  580.     end
  581. end
  582.  
  583. if commands and fs.isDir( "rom/apis/command" ) then
  584.     -- Load command APIs
  585.     if os.loadAPI( "rom/apis/command/commands" ) then
  586.         -- Add a special case-insensitive metatable to the commands api
  587.         local tCaseInsensitiveMetatable = {
  588.             __index = function( table, key )
  589.                 local value = rawget( table, key )
  590.                 if value ~= nil then
  591.                     return value
  592.                 end
  593.                 if type(key) == "string" then
  594.                     local value = rawget( table, string.lower(key) )
  595.                     if value ~= nil then
  596.                         return value
  597.                     end
  598.                 end
  599.                 return nil
  600.             end
  601.         }
  602.         setmetatable( commands, tCaseInsensitiveMetatable )
  603.         setmetatable( commands.async, tCaseInsensitiveMetatable )
  604.  
  605.         -- Add global "exec" function
  606.         exec = commands.exec
  607.     else
  608.         bAPIError = true
  609.     end
  610. end
  611.  
  612. if bAPIError then
  613.     print( "Press any key to continue" )
  614.     os.pullEvent( "key" )
  615.     term.clear()
  616.     term.setCursorPos( 1,1 )
  617. end
  618.  
  619. -- Run the shell
  620. local ok, err = pcall( function()
  621.     parallel.waitForAny(
  622.         function()
  623.             if term.isColour() then
  624.                 os.run( {}, "rom/programs/advanced/multishell" )
  625.             else
  626.                 os.run( {}, "rom/programs/shell" )
  627.             end
  628.             os.run( {}, "rom/programs/shutdown" )
  629.         end,
  630.         function()
  631.             rednet.run()
  632.         end )
  633. end )
  634.  
  635. -- If the shell errored, let the user read it.
  636. term.redirect( term.native() )
  637. if not ok then
  638.     printError( err )
  639.     pcall( function()
  640.         term.setCursorBlink( false )
  641.         print( "Press any key to continue" )
  642.         os.pullEvent( "key" )
  643.     end )
  644. end
  645.  
  646.  
  647. -- Setup paths
  648. local sPath = ".:/rom/programs"
  649. if term.isColor() then
  650.     sPath = sPath..":/rom/programs/advanced"
  651. end
  652. if turtle then
  653.     sPath = sPath..":/rom/programs/turtle"
  654. else
  655.     sPath = sPath..":/rom/programs/rednet:/rom/programs/fun"
  656.     if term.isColor() then
  657.         sPath = sPath..":/rom/programs/fun/advanced"
  658.     end
  659. end
  660. if pocket then
  661.     sPath = sPath..":/rom/programs/pocket"
  662. end
  663. if commands then
  664.     sPath = sPath..":/rom/programs/command"
  665. end
  666. if http then
  667.     sPath = sPath..":/rom/programs/http"
  668. end
  669. shell.setPath( sPath )
  670. help.setPath( "/rom/help" )
  671.  
  672. -- Setup aliases
  673. shell.setAlias( "ls", "list" )
  674. shell.setAlias( "dir", "list" )
  675. shell.setAlias( "cp", "copy" )
  676. shell.setAlias( "mv", "move" )
  677. shell.setAlias( "rm", "delete" )
  678. shell.setAlias( "clr", "clear" )
  679. shell.setAlias( "rs", "redstone" )
  680. shell.setAlias( "sh", "shell" )
  681. if term.isColor() then
  682.     shell.setAlias( "background", "bg" )
  683.     shell.setAlias( "foreground", "fg" )
  684. end
  685.  
  686. -- Run autorun files
  687. if fs.exists( "/rom/autorun" ) and fs.isDir( "/rom/autorun" ) then
  688.     local tFiles = fs.list( "/rom/autorun" )
  689.     table.sort( tFiles )
  690.     for n, sFile in ipairs( tFiles ) do
  691.         if string.sub( sFile, 1, 1 ) ~= "." then
  692.             local sPath = "/rom/autorun/"..sFile
  693.             if not fs.isDir( sPath ) then
  694.                 shell.run( sPath )
  695.             end
  696.         end
  697.     end
  698. end
  699.  
  700. -- Run the user created startup, either from disk drives or the root
  701. local sUserStartup = shell.resolveProgram( "/startup" )
  702. local bEnableDiskStartup = (commands == nil)
  703. if bEnableDiskStartup then
  704.     for n,sName in pairs( peripheral.getNames() ) do
  705.         if disk.isPresent( sName ) and disk.hasData( sName ) then
  706.             local sDiskStartup = shell.resolveProgram( "/" .. disk.getMountPath( sName ) .. "/startup" )
  707.             if sDiskStartup then
  708.                 sUserStartup = sDiskStartup
  709.                 break
  710.             end
  711.         end
  712.     end
  713. end
  714. if sUserStartup then
  715.     shell.run( sUserStartup )
  716. end
  717.  
  718.  
  719. -- End
  720. os.shutdown()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement