Advertisement
MCFunRide

bios.lua from CC

Aug 1st, 2015
216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.63 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.  
  110. -- Install fix for luaj's broken string.sub/string.find
  111. local nativestringfind = string.find
  112. local nativestringsub = string.sub
  113. function string.sub( ... )
  114. local r = nativestringsub( ... )
  115. if r then
  116. return r .. ""
  117. end
  118. return nil
  119. end
  120. function string.find( s, ... )
  121. return nativestringfind( s .. "", ... );
  122. end
  123.  
  124. -- Install lua parts of the os api
  125. function os.version()
  126. return "CraftOS 1.7"
  127. end
  128.  
  129. function os.pullEventRaw( sFilter )
  130. return coroutine.yield( sFilter )
  131. end
  132.  
  133. function os.pullEvent( sFilter )
  134. local eventData = { os.pullEventRaw( sFilter ) }
  135. if eventData[1] == "terminate" then
  136. error( "Terminated", 0 )
  137. end
  138. return unpack( eventData )
  139. end
  140.  
  141. -- Install globals
  142. function sleep( nTime )
  143. local timer = os.startTimer( nTime or 0 )
  144. repeat
  145. local sEvent, param = os.pullEvent( "timer" )
  146. until param == timer
  147. end
  148.  
  149. function write( sText )
  150. local w,h = term.getSize()
  151. local x,y = term.getCursorPos()
  152.  
  153. local nLinesPrinted = 0
  154. local function newLine()
  155. if y + 1 <= h then
  156. term.setCursorPos(1, y + 1)
  157. else
  158. term.setCursorPos(1, h)
  159. term.scroll(1)
  160. end
  161. x, y = term.getCursorPos()
  162. nLinesPrinted = nLinesPrinted + 1
  163. end
  164.  
  165. -- Print the line with proper word wrapping
  166. while string.len(sText) > 0 do
  167. local whitespace = string.match( sText, "^[ \t]+" )
  168. if whitespace then
  169. -- Print whitespace
  170. term.write( whitespace )
  171. x,y = term.getCursorPos()
  172. sText = string.sub( sText, string.len(whitespace) + 1 )
  173. end
  174.  
  175. local newline = string.match( sText, "^\n" )
  176. if newline then
  177. -- Print newlines
  178. newLine()
  179. sText = string.sub( sText, 2 )
  180. end
  181.  
  182. local text = string.match( sText, "^[^ \t\n]+" )
  183. if text then
  184. sText = string.sub( sText, string.len(text) + 1 )
  185. if string.len(text) > w then
  186. -- Print a multiline word
  187. while string.len( text ) > 0 do
  188. if x > w then
  189. newLine()
  190. end
  191. term.write( text )
  192. text = string.sub( text, (w-x) + 2 )
  193. x,y = term.getCursorPos()
  194. end
  195. else
  196. -- Print a word normally
  197. if x + string.len(text) - 1 > w then
  198. newLine()
  199. end
  200. term.write( text )
  201. x,y = term.getCursorPos()
  202. end
  203. end
  204. end
  205.  
  206. return nLinesPrinted
  207. end
  208.  
  209. function print( ... )
  210. local nLinesPrinted = 0
  211. for n,v in ipairs( { ... } ) do
  212. nLinesPrinted = nLinesPrinted + write( tostring( v ) )
  213. end
  214. nLinesPrinted = nLinesPrinted + write( "\n" )
  215. return nLinesPrinted
  216. end
  217.  
  218. function printError( ... )
  219. if term.isColour() then
  220. term.setTextColour( colours.red )
  221. end
  222. local x,y = term.getCursorPos()
  223. print( ... )
  224. term.setTextColour( colours.white )
  225. end
  226.  
  227. function read( _sReplaceChar, _tHistory )
  228. term.setCursorBlink( true )
  229.  
  230. local sLine = ""
  231. local nHistoryPos
  232. local nPos = 0
  233. if _sReplaceChar then
  234. _sReplaceChar = string.sub( _sReplaceChar, 1, 1 )
  235. end
  236.  
  237. local w = term.getSize()
  238. local sx = term.getCursorPos()
  239.  
  240. local function redraw( _sCustomReplaceChar )
  241. local nScroll = 0
  242. if sx + nPos >= w then
  243. nScroll = (sx + nPos) - w
  244. end
  245.  
  246. local cx,cy = term.getCursorPos()
  247. term.setCursorPos( sx, cy )
  248. local sReplace = _sCustomReplaceChar or _sReplaceChar
  249. if sReplace then
  250. term.write( string.rep( sReplace, math.max( string.len(sLine) - nScroll, 0 ) ) )
  251. else
  252. term.write( string.sub( sLine, nScroll + 1 ) )
  253. end
  254. term.setCursorPos( sx + nPos - nScroll, cy )
  255. end
  256.  
  257. while true do
  258. local sEvent, param = os.pullEvent()
  259. if sEvent == "char" then
  260. -- Typed key
  261. sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )
  262. nPos = nPos + 1
  263. redraw()
  264.  
  265. elseif sEvent == "paste" then
  266. -- Pasted text
  267. sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )
  268. nPos = nPos + string.len( param )
  269. redraw()
  270.  
  271. elseif sEvent == "key" then
  272. if param == keys.enter then
  273. -- Enter
  274. break
  275.  
  276. elseif param == keys.left then
  277. -- Left
  278. if nPos > 0 then
  279. nPos = nPos - 1
  280. redraw()
  281. end
  282.  
  283. elseif param == keys.right then
  284. -- Right
  285. if nPos < string.len(sLine) then
  286. redraw(" ")
  287. nPos = nPos + 1
  288. redraw()
  289. end
  290.  
  291. elseif param == keys.up or param == keys.down then
  292. -- Up or down
  293. if _tHistory then
  294. redraw(" ")
  295. if param == keys.up then
  296. -- Up
  297. if nHistoryPos == nil then
  298. if #_tHistory > 0 then
  299. nHistoryPos = #_tHistory
  300. end
  301. elseif nHistoryPos > 1 then
  302. nHistoryPos = nHistoryPos - 1
  303. end
  304. else
  305. -- Down
  306. if nHistoryPos == #_tHistory then
  307. nHistoryPos = nil
  308. elseif nHistoryPos ~= nil then
  309. nHistoryPos = nHistoryPos + 1
  310. end
  311. end
  312. if nHistoryPos then
  313. sLine = _tHistory[nHistoryPos]
  314. nPos = string.len( sLine )
  315. else
  316. sLine = ""
  317. nPos = 0
  318. end
  319. redraw()
  320. end
  321. elseif param == keys.backspace then
  322. -- Backspace
  323. if nPos > 0 then
  324. redraw(" ")
  325. sLine = string.sub( sLine, 1, nPos - 1 ) .. string.sub( sLine, nPos + 1 )
  326. nPos = nPos - 1
  327. redraw()
  328. end
  329. elseif param == keys.home then
  330. -- Home
  331. redraw(" ")
  332. nPos = 0
  333. redraw()
  334. elseif param == keys.delete then
  335. -- Delete
  336. if nPos < string.len(sLine) then
  337. redraw(" ")
  338. sLine = string.sub( sLine, 1, nPos ) .. string.sub( sLine, nPos + 2 )
  339. redraw()
  340. end
  341. elseif param == keys["end"] then
  342. -- End
  343. redraw(" ")
  344. nPos = string.len(sLine)
  345. redraw()
  346. end
  347.  
  348. elseif sEvent == "term_resize" then
  349. -- Terminal resized
  350. w = term.getSize()
  351. redraw()
  352.  
  353. end
  354. end
  355.  
  356. local cx, cy = term.getCursorPos()
  357. term.setCursorBlink( false )
  358. term.setCursorPos( w + 1, cy )
  359. print()
  360.  
  361. return sLine
  362. end
  363.  
  364. loadfile = function( _sFile )
  365. local file = fs.open( _sFile, "r" )
  366. if file then
  367. local func, err = loadstring( file.readAll(), fs.getName( _sFile ) )
  368. file.close()
  369. return func, err
  370. end
  371. return nil, "File not found"
  372. end
  373.  
  374. dofile = function( _sFile )
  375. local fnFile, e = loadfile( _sFile )
  376. if fnFile then
  377. setfenv( fnFile, getfenv(2) )
  378. return fnFile()
  379. else
  380. error( e, 2 )
  381. end
  382. end
  383.  
  384. -- Install the rest of the OS api
  385. function os.run( _tEnv, _sPath, ... )
  386. local tArgs = { ... }
  387. local fnFile, err = loadfile( _sPath )
  388. if fnFile then
  389. local tEnv = _tEnv
  390. --setmetatable( tEnv, { __index = function(t,k) return _G[k] end } )
  391. setmetatable( tEnv, { __index = _G } )
  392. setfenv( fnFile, tEnv )
  393. local ok, err = pcall( function()
  394. fnFile( unpack( tArgs ) )
  395. end )
  396. if not ok then
  397. if err and err ~= "" then
  398. printError( err )
  399. end
  400. return false
  401. end
  402. return true
  403. end
  404. if err and err ~= "" then
  405. printError( err )
  406. end
  407. return false
  408. end
  409.  
  410. -- Prevent access to metatables or environments of strings, as these are global between all computers
  411. do
  412. local nativegetfenv = getfenv
  413. local nativegetmetatable = getmetatable
  414. local nativeerror = error
  415. local nativetype = type
  416. local string_metatable = nativegetmetatable("")
  417. local string_env = nativegetfenv(("").gsub)
  418. function getmetatable( t )
  419. local mt = nativegetmetatable( t )
  420. if mt == string_metatable or mt == string_env then
  421. nativeerror( "Attempt to access string metatable", 2 )
  422. else
  423. return mt
  424. end
  425. end
  426. function getfenv( env )
  427. if env == nil then
  428. env = 2
  429. elseif nativetype( env ) == "number" and env > 0 then
  430. env = env + 1
  431. end
  432. local fenv = nativegetfenv(env)
  433. if fenv == string_metatable or fenv == string_env then
  434. --nativeerror( "Attempt to access string metatable", 2 )
  435. return nativegetfenv( 0 )
  436. else
  437. return fenv
  438. end
  439. end
  440. end
  441.  
  442. local tAPIsLoading = {}
  443. function os.loadAPI( _sPath )
  444. local sName = fs.getName( _sPath )
  445. if tAPIsLoading[sName] == true then
  446. printError( "API "..sName.." is already being loaded" )
  447. return false
  448. end
  449. tAPIsLoading[sName] = true
  450.  
  451. local tEnv = {}
  452. setmetatable( tEnv, { __index = _G } )
  453. local fnAPI, err = loadfile( _sPath )
  454. if fnAPI then
  455. setfenv( fnAPI, tEnv )
  456. local ok, err = pcall( fnAPI )
  457. if not ok then
  458. printError( err )
  459. tAPIsLoading[sName] = nil
  460. return false
  461. end
  462. else
  463. printError( err )
  464. tAPIsLoading[sName] = nil
  465. return false
  466. end
  467.  
  468. local tAPI = {}
  469. for k,v in pairs( tEnv ) do
  470. tAPI[k] = v
  471. end
  472.  
  473. _G[sName] = tAPI
  474. tAPIsLoading[sName] = nil
  475. return true
  476. end
  477.  
  478. function os.unloadAPI( _sName )
  479. if _sName ~= "_G" and type(_G[_sName]) == "table" then
  480. _G[_sName] = nil
  481. end
  482. end
  483.  
  484. function os.sleep( nTime )
  485. sleep( nTime )
  486. end
  487.  
  488. local nativeShutdown = os.shutdown
  489. function os.shutdown()
  490. nativeShutdown()
  491. while true do
  492. coroutine.yield()
  493. end
  494. end
  495.  
  496. local nativeReboot = os.reboot
  497. function os.reboot()
  498. nativeReboot()
  499. while true do
  500. coroutine.yield()
  501. end
  502. end
  503.  
  504. -- Install the lua part of the HTTP api (if enabled)
  505. if http then
  506. local nativeHTTPRequest = http.request
  507.  
  508. local function wrapRequest( _url, _post, _headers )
  509. local ok, err = nativeHTTPRequest( _url, _post, _headers )
  510. if ok then
  511. while true do
  512. local event, param1, param2 = os.pullEvent()
  513. if event == "http_success" and param1 == _url then
  514. return param2
  515. elseif event == "http_failure" and param1 == _url then
  516. return nil, param2
  517. end
  518. end
  519. end
  520. return nil, err
  521. end
  522.  
  523. http.get = function( _url, _headers )
  524. return wrapRequest( _url, nil, _headers )
  525. end
  526.  
  527. http.post = function( _url, _post, _headers )
  528. return wrapRequest( _url, _post or "", _headers )
  529. end
  530.  
  531. http.request = function( _url, _post, _headers )
  532. local ok, err = nativeHTTPRequest( _url, _post, _headers )
  533. if not ok then
  534. os.queueEvent( "http_failure", _url, err )
  535. end
  536. return ok, err
  537. end
  538. end
  539.  
  540. -- Load APIs
  541. local bAPIError = false
  542. local tApis = fs.list( "rom/apis" )
  543. for n,sFile in ipairs( tApis ) do
  544. if string.sub( sFile, 1, 1 ) ~= "." then
  545. local sPath = fs.combine( "rom/apis", sFile )
  546. if not fs.isDir( sPath ) then
  547. if not os.loadAPI( sPath ) then
  548. bAPIError = true
  549. end
  550. end
  551. end
  552. end
  553.  
  554. if turtle then
  555. -- Load turtle APIs
  556. local tApis = fs.list( "rom/apis/turtle" )
  557. for n,sFile in ipairs( tApis ) do
  558. if string.sub( sFile, 1, 1 ) ~= "." then
  559. local sPath = fs.combine( "rom/apis/turtle", sFile )
  560. if not fs.isDir( sPath ) then
  561. if not os.loadAPI( sPath ) then
  562. bAPIError = true
  563. end
  564. end
  565. end
  566. end
  567. end
  568.  
  569. if pocket and fs.isDir( "rom/apis/pocket" ) then
  570. -- Load pocket APIs
  571. local tApis = fs.list( "rom/apis/pocket" )
  572. for n,sFile in ipairs( tApis ) do
  573. if string.sub( sFile, 1, 1 ) ~= "." then
  574. local sPath = fs.combine( "rom/apis/pocket", sFile )
  575. if not fs.isDir( sPath ) then
  576. if not os.loadAPI( sPath ) then
  577. bAPIError = true
  578. end
  579. end
  580. end
  581. end
  582. end
  583.  
  584. if commands and fs.isDir( "rom/apis/command" ) then
  585. -- Load command APIs
  586. if os.loadAPI( "rom/apis/command/commands" ) then
  587. -- Add a special case-insensitive metatable to the commands api
  588. local tCaseInsensitiveMetatable = {
  589. __index = function( table, key )
  590. local value = rawget( table, key )
  591. if value ~= nil then
  592. return value
  593. end
  594. if type(key) == "string" then
  595. local value = rawget( table, string.lower(key) )
  596. if value ~= nil then
  597. return value
  598. end
  599. end
  600. return nil
  601. end
  602. }
  603. setmetatable( commands, tCaseInsensitiveMetatable )
  604. setmetatable( commands.async, tCaseInsensitiveMetatable )
  605.  
  606. -- Add global "exec" function
  607. exec = commands.exec
  608. else
  609. bAPIError = true
  610. end
  611. end
  612.  
  613. if bAPIError then
  614. print( "Press any key to continue" )
  615. os.pullEvent( "key" )
  616. term.clear()
  617. term.setCursorPos( 1,1 )
  618. end
  619.  
  620. -- Run the shell
  621. local ok, err = pcall( function()
  622. parallel.waitForAny(
  623. function()
  624. if term.isColour() then
  625. os.run( {}, "rom/programs/advanced/multishell" )
  626. else
  627. os.run( {}, "rom/programs/shell" )
  628. end
  629. os.run( {}, "rom/programs/shutdown" )
  630. end,
  631. function()
  632. rednet.run()
  633. end )
  634. end )
  635.  
  636. -- If the shell errored, let the user read it.
  637. term.redirect( term.native() )
  638. if not ok then
  639. printError( err )
  640. pcall( function()
  641. term.setCursorBlink( false )
  642. print( "Press any key to continue" )
  643. os.pullEvent( "key" )
  644. end )
  645. end
  646.  
  647. -- End
  648. os.shutdown()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement