MudkipTheEpic

Remote Control CC

Dec 21st, 2020 (edited)
345
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.75 KB | None | 0 0
  1. local width, height = term.getSize()
  2.  
  3. local hostWindow = window.create(term.native(), 1, 1, width, height, false)
  4.  
  5. local tTermFunctionsWithReturnValue = {"getCursorPos", "isColor", "isColour", "getSize", "getTextColor", "getTextColour", "getBackgroundColor", "getBackgroundColour", "getPalletteColor", "getPalletteColour", "getCursorBlink"}
  6.  
  7. local tInteractionEvents = {"char", "key", "key_up", "paste", "terminate", "mouse_click", "mouse_up", "mouse_scroll", "mouse_drag"}
  8.  
  9. local function has_value (tab, val)
  10.     for index, value in ipairs(tab) do
  11.         if value == val then
  12.             return true
  13.         end
  14.     end
  15.  
  16.     return false
  17. end
  18.  
  19. local function hostTermWrapper(coro, termCurrent, modem, channel, method, ...)
  20.     if coroutine.status(coro) ~= "running" then
  21.         --print("coro not running")
  22.         return termCurrent[method](...)
  23.     end
  24.     if method == "redirect" then
  25.         error("Terminal redirection is not enabled in remote mode.", 2)
  26.     end
  27.     if method == "current" or method == "native" then
  28.         return termCurrent
  29.     end
  30.     modem.transmit(channel, channel, {
  31.         origin = "host",
  32.         type = "term",
  33.         method = method,
  34.         args = {...}
  35.     })
  36.     if has_value(tTermFunctionsWithReturnValue, method) then
  37.         while true do
  38.             local event, side, freq, replyFreq, packet, distance = coroutine.yield("modem_message")
  39.             if event == "modem_message" and freq == channel and type(packet) == "table" then
  40.                 if packet.origin == "client" and packet.type == "term" and packet.method ~= nil and term[packet.method] ~= nil then
  41.                     return unpack(packet.result)
  42.                 end
  43.             end
  44.         end
  45.     end
  46. end
  47.  
  48. local function connect(modem, channel)
  49.     modem.open(channel)
  50.     while true do
  51.         local tEvent = {coroutine.yield()}
  52.         --print(textutils.serialize(tEvent))
  53.         local sEventType = tEvent[1]
  54.         if sEventType == "modem_message" then
  55.             --print("Received modem message")
  56.             local _, side, freq, replyFreq, packet, distance = unpack(tEvent)
  57.             if freq == channel and type(packet) == "table" then
  58.                 if packet.origin == "host" and packet.type == "term" and packet.method ~= nil and term[packet.method] ~= nil and type(packet.args) == "table" then
  59.                     local tResults = {term[packet.method](unpack(packet.args))}
  60.                     if has_value(tTermFunctionsWithReturnValue,packet.method) then
  61.                         modem.transmit(channel, channel, {
  62.                             origin = "client",
  63.                             type = "term",
  64.                             method = packet.method,
  65.                             result = tResults
  66.                         })
  67.                     end
  68.                 end
  69.             end
  70.         elseif has_value(tInteractionEvents,sEventType) then
  71.             modem.transmit(channel, channel, {
  72.                 origin = "client",
  73.                 type = "event",
  74.                 event = tEvent
  75.             })
  76.         end
  77.     end
  78. end
  79.  
  80. local function getHostThread(modem, channel)
  81.     return function()
  82.         local hostShell = coroutine.create(loadfile("/rom/programs/shell.lua"))
  83.         local termCurrent = {}
  84.         for k,v in pairs(term.current()) do
  85.             termCurrent[k] = v
  86.         end
  87.         local termRedirect = term.redirect
  88.         local termMirror = setmetatable({}, {
  89.             __index = function(tab, method)
  90.                 if termCurrent[method] == nil then
  91.                     --print("method does not exist")
  92.                     return nil
  93.                 end
  94.                 return function(...)
  95.                     return hostTermWrapper(hostShell, termCurrent, modem, channel, method, ...)
  96.                 end
  97.             end
  98.         })
  99.         modem.open(channel)
  100.         termRedirect(termMirror)
  101.         local filter = nil
  102.         coroutine.resume(hostShell)
  103.         repeat
  104.             local tEvent = {coroutine.yield()}
  105.             --print(textutils.serialize(tEvent))
  106.             local sEventType = tEvent[1]
  107.             if not has_value(tInteractionEvents,sEventType) then
  108.                 if sEventType == "modem_message" then
  109.                     --print("Received a modem message")
  110.                     local _, side, freq, replyFreq, packet, distance = unpack(tEvent)
  111.                     if freq == channel and type(packet) == "table" then
  112.                         --print("Received a packet")
  113.                         if packet.origin == "client" and packet.type == "event" and type(packet.event) == "table" then
  114.                             --print("Replaced event")
  115.                             tEvent = packet.event
  116.                             sEventType = packet.event[1]
  117.                         end
  118.                     end
  119.                 end
  120.             end
  121.             --print(textutils.serialize(tEvent))
  122.             if filter == nil or filter == sEventType or sEventType == "terminate" then
  123.                 local tResult = {coroutine.resume(hostShell, unpack(tEvent))}
  124.                 --print(textutils.serialize(tResult))
  125.                 filter = tResult[2]
  126.             end
  127.         until coroutine.status(hostShell) == "dead"
  128.         termRedirect(termCurrent)
  129.         modem.close(channel)
  130.         --print(coroutine.status(hostShell))
  131.         return
  132.     end
  133. end
  134.  
  135. local tArgs = {...}
  136. local channel = tonumber(tArgs[2])
  137.  
  138. if channel ~= nil and channel > 0 and channel < 65535 then
  139.     if tArgs[1] == "host" then
  140.         getHostThread(peripheral.find("modem"), channel)()
  141.     elseif tArgs[1] == "connect" then
  142.         connect(peripheral.find("modem"), channel)
  143.     else
  144.         printError("Usage: multi [host/connect] channel")
  145.     end
  146. else
  147.     printError("Usage: multi [host/connect] channel")
  148. end
Add Comment
Please, Sign In to add comment