LoganDark

TLCO

Jan 2nd, 2021 (edited)
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.67 KB | None | 0 0
  1. local program, args = (select(1, ...)), table.pack(select(2, ...))
  2. if select('#', ...) < 1 then program = 'shell' end
  3.  
  4. if shell then
  5.     local resolved = shell.resolveProgram(program)
  6.  
  7.     if not resolved then
  8.         printError('Couldn\'t find program: ' .. program)
  9.         return 1
  10.     end
  11.  
  12.     program = resolved
  13. end
  14.  
  15. -- else hope the user knows what they are doing
  16. -- it probably won't even work unless some parent env has shell
  17.  
  18. local function pullEventAbsolute(filter)
  19.     local data
  20.  
  21.     while true do
  22.         data = table.pack(coroutine.yield(filter))
  23.  
  24.         if data[1] == filter then
  25.             return table.unpack(data, 1, data.n)
  26.         end
  27.     end
  28. end
  29.  
  30. local originalQueueEvent = os.queueEvent
  31. local function onError(err)
  32.     printError(err)
  33.     print('Press any key to continue')
  34.     originalQueueEvent('fast-forward')
  35.     pullEventAbsolute('fast-forward')
  36.     pullEventAbsolute('key')
  37.     os.shutdown()
  38.     os.shutdown()
  39. end
  40.  
  41. local eventName = 'tlco_' .. tostring(math.random(-20000, 20000))
  42.  
  43. local originalPrint = print
  44. local originalShutdown = os.shutdown
  45. local originalPullEvent = os.pullEvent
  46. local originalGetComputerID = os.getComputerID
  47.  
  48. local function restore()
  49.     _G.print = originalPrint
  50.     os.shutdown = originalShutdown
  51.     os.pullEvent = originalPullEvent
  52.     os.getComputerID = originalGetComputerID
  53. end
  54.  
  55. function _G.print() end -- prevent error text, and "press any key to continue"
  56.  
  57. local methodUsed = 'Unknown'
  58.  
  59. function os.shutdown() -- called at end of bios
  60.     pullEventAbsolute(eventName)
  61.  
  62.     restore()
  63.  
  64.     -- We have now achieved top-level coroutine override
  65.  
  66.     term.setTextColor(colors.cyan)
  67.     print('TLCO Activated, ' .. methodUsed .. ' method')
  68.     term.setTextColor(colors.white)
  69.  
  70.     local preShutdown = os.shutdown
  71.  
  72.     -- run directly in _G
  73.     local func, err = loadfile(program, nil, _G)
  74.     if not func then return onError(err) end
  75.  
  76.     local ok, err = pcall(func, table.unpack(args, 1, args.n))
  77.     if not ok then return onError(err) end
  78.  
  79.     -- Only run os.shutdown if it has changed, for nested TLCOs
  80.     if os.shutdown ~= preShutdown then
  81.         -- Run os.shutdown twice. Why? Because regular bios does it. Sane TLCOs hook the second shutdown after shell exit.
  82.         -- There is no rednet to crash, so TLCO will try to exit the shell. Give them something to hook if they so please.
  83.         -- I don't know why people would nest TLCOs, but maybe they do
  84.         os.shutdown()
  85.         os.shutdown()
  86.     end
  87. end
  88.  
  89. function os.pullEvent(filter) -- called in middle of bios
  90.     if filter == 'key' then
  91.         -- haha lol
  92.     else
  93.         return originalPullEvent(filter)
  94.     end
  95. end
  96.  
  97. function os.getComputerID() -- called on modem_message inside rednet.run
  98.     error('get hegged')
  99. end
  100.  
  101. methodUsed = 'Rednet'
  102.  
  103. os.queueEvent('modem_message', 0) -- crash rednet
  104. os.queueEvent(eventName)
  105. pullEventAbsolute(eventName) -- wait for the crash
  106.  
  107. -- If we are still running, try a different method
  108.  
  109. methodUsed = 'Shell'
  110.  
  111. do -- Expect two shutdowns
  112.     local hookedShutdown = os.shutdown
  113.     function os.shutdown()
  114.         os.shutdown = hookedShutdown
  115.     end
  116. end
  117.  
  118. do -- Prevent one second delay caused by rom/programs/shutdown.lua
  119.     local originalSleep = _G.sleep
  120.     function _G.sleep() end
  121.  
  122.     -- Restore os.sleep once TLCO executes
  123.  
  124.     local originalRestore = restore
  125.     restore = function()
  126.         originalRestore()
  127.         _G.sleep = originalSleep
  128.     end
  129. end
  130.  
  131. do -- Exit all shells
  132.     local exited = false
  133.  
  134.     if type(getfenv) ~= 'function' then
  135.         restore()
  136.         printError('TLCO failed: no getfenv')
  137.         return 1
  138.     end
  139.  
  140.     for i = 1, 100 do
  141.         local ok, fenv = pcall(getfenv, i)
  142.         if ok and fenv.shell then
  143.             fenv.shell.exit()
  144.             exited = true
  145.         end
  146.     end
  147.  
  148.     if not exited then
  149.         restore()
  150.         printError('TLCO failed: not running under CraftOS')
  151.         return 1
  152.     end
  153. end
  154.  
  155. os.queueEvent(eventName)
  156.  
Advertisement
Add Comment
Please, Sign In to add comment