Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local width, height = term.getSize()
- local hostWindow = window.create(term.native(), 1, 1, width, height, false)
- local tTermFunctionsWithReturnValue = {"getCursorPos", "isColor", "isColour", "getSize", "getTextColor", "getTextColour", "getBackgroundColor", "getBackgroundColour", "getPalletteColor", "getPalletteColour", "getCursorBlink"}
- local tInteractionEvents = {"char", "key", "key_up", "paste", "terminate", "mouse_click", "mouse_up", "mouse_scroll", "mouse_drag"}
- local function has_value (tab, val)
- for index, value in ipairs(tab) do
- if value == val then
- return true
- end
- end
- return false
- end
- local function hostTermWrapper(coro, termCurrent, modem, channel, method, ...)
- if coroutine.status(coro) ~= "running" then
- --print("coro not running")
- return termCurrent[method](...)
- end
- if method == "redirect" then
- error("Terminal redirection is not enabled in remote mode.", 2)
- end
- if method == "current" or method == "native" then
- return termCurrent
- end
- modem.transmit(channel, channel, {
- origin = "host",
- type = "term",
- method = method,
- args = {...}
- })
- if has_value(tTermFunctionsWithReturnValue, method) then
- while true do
- local event, side, freq, replyFreq, packet, distance = coroutine.yield("modem_message")
- if event == "modem_message" and freq == channel and type(packet) == "table" then
- if packet.origin == "client" and packet.type == "term" and packet.method ~= nil and term[packet.method] ~= nil then
- return unpack(packet.result)
- end
- end
- end
- end
- end
- local function connect(modem, channel)
- modem.open(channel)
- while true do
- local tEvent = {coroutine.yield()}
- --print(textutils.serialize(tEvent))
- local sEventType = tEvent[1]
- if sEventType == "modem_message" then
- --print("Received modem message")
- local _, side, freq, replyFreq, packet, distance = unpack(tEvent)
- if freq == channel and type(packet) == "table" then
- if packet.origin == "host" and packet.type == "term" and packet.method ~= nil and term[packet.method] ~= nil and type(packet.args) == "table" then
- local tResults = {term[packet.method](unpack(packet.args))}
- if has_value(tTermFunctionsWithReturnValue,packet.method) then
- modem.transmit(channel, channel, {
- origin = "client",
- type = "term",
- method = packet.method,
- result = tResults
- })
- end
- end
- end
- elseif has_value(tInteractionEvents,sEventType) then
- modem.transmit(channel, channel, {
- origin = "client",
- type = "event",
- event = tEvent
- })
- end
- end
- end
- local function getHostThread(modem, channel)
- return function()
- local hostShell = coroutine.create(loadfile("/rom/programs/shell.lua"))
- local termCurrent = {}
- for k,v in pairs(term.current()) do
- termCurrent[k] = v
- end
- local termRedirect = term.redirect
- local termMirror = setmetatable({}, {
- __index = function(tab, method)
- if termCurrent[method] == nil then
- --print("method does not exist")
- return nil
- end
- return function(...)
- return hostTermWrapper(hostShell, termCurrent, modem, channel, method, ...)
- end
- end
- })
- modem.open(channel)
- termRedirect(termMirror)
- local filter = nil
- coroutine.resume(hostShell)
- repeat
- local tEvent = {coroutine.yield()}
- --print(textutils.serialize(tEvent))
- local sEventType = tEvent[1]
- if not has_value(tInteractionEvents,sEventType) then
- if sEventType == "modem_message" then
- --print("Received a modem message")
- local _, side, freq, replyFreq, packet, distance = unpack(tEvent)
- if freq == channel and type(packet) == "table" then
- --print("Received a packet")
- if packet.origin == "client" and packet.type == "event" and type(packet.event) == "table" then
- --print("Replaced event")
- tEvent = packet.event
- sEventType = packet.event[1]
- end
- end
- end
- end
- --print(textutils.serialize(tEvent))
- if filter == nil or filter == sEventType or sEventType == "terminate" then
- local tResult = {coroutine.resume(hostShell, unpack(tEvent))}
- --print(textutils.serialize(tResult))
- filter = tResult[2]
- end
- until coroutine.status(hostShell) == "dead"
- termRedirect(termCurrent)
- modem.close(channel)
- --print(coroutine.status(hostShell))
- return
- end
- end
- local tArgs = {...}
- local channel = tonumber(tArgs[2])
- if channel ~= nil and channel > 0 and channel < 65535 then
- if tArgs[1] == "host" then
- getHostThread(peripheral.find("modem"), channel)()
- elseif tArgs[1] == "connect" then
- connect(peripheral.find("modem"), channel)
- else
- printError("Usage: multi [host/connect] channel")
- end
- else
- printError("Usage: multi [host/connect] channel")
- end
Add Comment
Please, Sign In to add comment