Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --rsh: Remotely access other comptuercraft Terminals.
- --(C) 2016 Harrison Cook (1cook)
- local argv = {...}
- local PROTOCOL = "rsh"
- local NORMAL_SIZE = 51,19
- local modemSide
- local EVENT_WHITELIST = {}
- EVENT_WHITELIST["key"] = true
- EVENT_WHITELIST["mouse_click"] = term.isColor()
- EVENT_WHITELIST["mouse_scroll"] = term.isColor()
- EVENT_WHITELIST["mouse_drag"] = term.isColor()
- EVENT_WHITELIST["char"] = true
- EVENT_WHITELIST["key_up"] = true
- local TERM_BLACKLIST = {} --For Non-color screens
- TERM_BLACKLIST["setTextColor"] = not term.isColor()
- TERM_BLACKLIST["setBackgroundColor"] = not term.isColor()
- TERM_BLACKLIST["blit"] = not term.isColor()
- --prints the incorrect usage message
- local function usage()
- print("usage: rsh --help")
- print(" rsh --host <hostname> <program>")
- print(" rsh --hostReadOnly <hostname> <program>")
- print(" rsh <hostname>")
- end
- --Opens a modem placed on any side
- local function modemGet()
- local SIDES = {"right","left","top","bottom","front","back"}
- for i=1,#SIDES do
- if peripheral.getType(SIDES[i]) == "modem" then
- rednet.open(SIDES[i])
- return SIDES[i]
- end
- end
- print("Please Place a modem on your computer.")
- error()
- end
- local timer = 0 --regulates sends
- local function sendDelay()
- timer = timer + 1
- if timer >= 110 then
- sleep()
- timer = 0
- end
- end
- --Table of connected computers
- local ids = {}
- function sendToAll(mesg)
- for id,value in pairs(ids) do
- rednet.send(id,mesg,PROTOCOL)
- end
- end
- --Local Terminal Object (Usually the screen, but can also be a monitor)
- local lTerm
- --Terminal Object which is to be redirected to.
- rTerm = {}
- --Writes to the terminal
- function rTerm.write(arg1)
- sendDelay()
- lTerm.write(arg1)
- local mesg = {}
- mesg.type = "call"
- mesg.fn = "write"
- mesg.args = {arg1}
- sendToAll(mesg)
- end
- --Blits to the Terminal
- function rTerm.blit(arg1,arg2,arg3)
- sendDelay()
- lTerm.blit(arg1,arg2,arg3)
- local mesg= {}
- mesg.type = "call"
- mesg.fn = "blit"
- mesg.args = {arg1,arg2,arg3}
- sendToAll(mesg)
- end
- --Clears Terminal
- function rTerm.clear()
- sendDelay()
- lTerm.clear()
- local mesg = {}
- mesg.type = "call"
- mesg.fn = "clear"
- mesg.args = {nil}
- sendToAll(mesg)
- end
- --Clears terminal Line
- function rTerm.clearLine()
- sendDelay()
- lTerm.clearLine()
- local mesg = {}
- mesg.type = "call"
- mesg.fn = "clearLine"
- mesg.args = {nil}
- sendToAll(mesg)
- end
- --Returns cursor position tuple
- function rTerm.getCursorPos()
- return lTerm.getCursorPos()
- end
- --Returns terminal color support
- function rTerm.isColor()
- return lTerm.isColor()
- end
- --Returns terminal colour support for british people
- rTerm.isColour = rTerm.isColor
- --Retruns the tuple size of the terminal
- function rTerm.getSize()
- return lTerm.getSize()
- end
- --Scrolls the terminal
- function rTerm.scroll(arg1)
- sendDelay()
- lTerm.scroll(arg1)
- local mesg = {}
- mesg.type = "call"
- mesg.fn = "scroll"
- mesg.args = {arg1}
- sendToAll(mesg)
- end
- --For rsh this does nothing
- function rTerm.redirect()
- rTerm.write("Silently Ignoring Attempt to redirect Terminal")
- end
- --Returns the remote terminal object
- function rTerm.current()
- return rTerm
- end
- --sets the text color
- function rTerm.setTextColor(arg1)
- sendDelay()
- lTerm.setTextColor(arg1)
- local mesg = {}
- mesg.type = "call"
- mesg.fn = "setTextColor"
- mesg.args = {arg1}
- sendToAll(mesg)
- end
- --sets the text color for british people
- rTerm.setTextColour = rTerm.setTextColor
- --gets the text color
- function rTerm.getTextColor()
- return lTerm.getTextColor()
- end
- --sets cursor blink
- function rTerm.setCursorBlink(arg1)
- sendDelay()
- lTerm.setCursorBlink(arg1)
- local mesg = {}
- mesg.type = "call"
- mesg.fn = "setCursorBlink"
- mesg.args = {arg1}
- sendToAll(mesg)
- end
- function rTerm.getCursorBlink()
- return lTerm.setCursorBlink()
- end
- --gets the text color for british people
- rTerm.getTextColour = rTerm.getTextColor
- --sets the background color
- function rTerm.setBackgroundColor(arg1)
- sendDelay()
- lTerm.setBackgroundColour(arg1)
- local mesg = {}
- mesg.type = "call"
- mesg.fn = "setBackgroundColor"
- mesg.args = {arg1}
- sendToAll(mesg)
- end
- --sets the background color for british people
- rTerm.setBackgroundColour = rTerm.setBackgroundColor
- --gets the background color
- function rTerm.getBackgroundColor()
- return lTerm.getBackgroundColor()
- end
- --gets the background color for british people
- rTerm.getBackgroundColour = rTerm.getBackgroundColor
- --Sets cursor pos
- function rTerm.setCursorPos(arg1,arg2)
- sendDelay()
- lTerm.setCursorPos(arg1,arg2)
- local mesg = {}
- mesg.type = "call"
- mesg.fn = "setCursorPos"
- mesg.args = {arg1,arg2}
- sendToAll(mesg)
- end
- --Functions for responding to clients
- local fn = {}
- function fn.query()
- local mesg = {}
- mesg.width,mesg.height = lTerm.getSize()
- mesg.color = lTerm.isColor()
- return mesg
- end
- function fn.login(id)
- ids[id] = true
- return "success"
- end
- function fn.logout(id)
- ids[id] = nil
- return "success"
- end
- --Happens when we are the host
- if #argv >= 3 and (argv[1] == "--host" or argv[1] == "--hostReadOnly") then
- if argv[1] == "--hostReadOnly" then
- EVENT_WHITELIST = {} --Client is not allowed to send Events
- end
- local modemSide = modemGet()
- rednet.host(PROTOCOL,argv[2])
- --terminal object that will be redirected to
- lTerm = term.redirect(rTerm)
- local coSh = coroutine.create(
- function ()
- --runs the program
- shell.run(table.unpack(argv,3))
- end
- )
- local currentEvent = {}
- local pullFor
- local status
- repeat
- if pullFor == nil or pullFor == currentEvent[1] then
- status, pullFor = coroutine.resume(coSh, table.unpack(currentEvent))
- end
- if status then
- currentEvent = {os.pullEventRaw()}
- if currentEvent[1] == "rednet_message" and currentEvent[4] == PROTOCOL then
- if ids[currentEvent[2]] and currentEvent[3].type and currentEvent[3].type == "event" then
- if EVENT_WHITELIST[currentEvent[3].args[1]] then
- currentEvent = currentEvent[3].args
- else
- currentEvent = {}
- end
- elseif currentEvent[3].type and fn[currentEvent[3].type] then
- local status = pcall(function () mesg = fn[currentEvent[3].type](currentEvent[2],currentEvent[3].args) end)
- if status then
- rednet.send(currentEvent[2],mesg,PROTOCOL)
- else
- local mesg = {} --disconnect client for invalid message
- mesg.type = "disconnect"
- rednet.send(currentEvent[2],mesg,PROTOCOL) --Disconnect client
- ids[currentEvent[2]] = false
- end
- currentEvent = {}
- end
- end
- if currentEvent[1] == "timer" then
- timer = 0
- end
- else
- break
- end
- until coroutine.status(coSh) == "dead"
- local mesg = {}
- mesg.type = "disconnect"
- sendToAll(mesg)
- rednet.close(modemSide)
- term.redirect(lTerm)
- --happens when we are the client
- elseif #argv == 1 then
- local modemSide = modemGet()
- local id = rednet.lookup(PROTOCOL,argv[1])
- if not id then
- print("Unable to find computer with specified hostname.")
- error()
- end
- local mesg = {}
- mesg.type = "query"
- mesg.args = {}
- rednet.send(id,mesg,PROTOCOL)
- local _,reply = rednet.receive(PROTOCOL)
- mesg.type = "login"
- mesg.args = {}
- rednet.send(id,mesg,PROTOCOL)
- term.setCursorBlink(true)
- while true do
- local event = {os.pullEvent()}
- --received message from host
- if event[1] == "rednet_message" and event[2] == id and event[4] == PROTOCOL then
- local reply = event[3]
- if reply.type then
- if reply.type == "call" and not TERM_BLACKLIST[reply.fn] then
- term[reply.fn](table.unpack(reply.args))
- elseif reply.type == "disconnect" then
- break
- end
- end
- --disconnecting
- elseif event == "terminate" then
- mesg = {}
- mesg.type = "logout"
- mesg.args = {}
- rednet.send(id,mesg,protocol)
- break
- --sending event to host
- elseif EVENT_WHITELIST[event[1]] then
- mesg = {}
- mesg.type = "event"
- mesg.args = event
- rednet.send(id,mesg,PROTOCOL)
- end
- end
- rednet.close(modemSide)
- --user wants help
- elseif argv[1] == "help"
- print("Remote shell")
- else
- usage()
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement