Advertisement
Guest User

rsh

a guest
Jul 24th, 2016
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.03 KB | None | 0 0
  1. --rsh: Remotely access other comptuercraft Terminals.
  2. --(C) 2016 Harrison Cook (1cook)
  3.  
  4. local argv = {...}
  5.  
  6. local PROTOCOL = "rsh"
  7. local NORMAL_SIZE = 51,19
  8.  
  9. local modemSide
  10.  
  11. local EVENT_WHITELIST = {}
  12. EVENT_WHITELIST["key"] = true
  13. EVENT_WHITELIST["mouse_click"] = term.isColor()
  14. EVENT_WHITELIST["mouse_scroll"] = term.isColor()
  15. EVENT_WHITELIST["mouse_drag"] = term.isColor()
  16. EVENT_WHITELIST["char"] = true
  17. EVENT_WHITELIST["key_up"] = true
  18.  
  19. local TERM_BLACKLIST = {} --For Non-color screens
  20. TERM_BLACKLIST["setTextColor"] = not term.isColor()
  21. TERM_BLACKLIST["setBackgroundColor"] = not term.isColor()
  22. TERM_BLACKLIST["blit"] = not term.isColor()
  23.  
  24.  
  25. --prints the incorrect usage message
  26. local function usage()
  27.     print("usage: rsh --help")
  28.     print("       rsh --host <hostname> <program>")
  29.     print("       rsh --hostReadOnly <hostname> <program>")
  30.     print("       rsh <hostname>")
  31. end
  32.  
  33. --Opens a modem placed on any side
  34. local function modemGet()
  35.     local SIDES = {"right","left","top","bottom","front","back"}
  36.     for i=1,#SIDES do
  37.         if peripheral.getType(SIDES[i]) == "modem" then
  38.             rednet.open(SIDES[i])
  39.             return SIDES[i]
  40.         end
  41.     end
  42.     print("Please Place a modem on your computer.")
  43.     error()
  44. end
  45.  
  46.  
  47. local timer = 0 --regulates sends
  48. local function sendDelay()
  49.     timer = timer + 1
  50.     if timer >= 110 then
  51.         sleep()
  52.         timer = 0
  53.     end
  54. end
  55.  
  56. --Table of connected computers
  57. local ids = {}
  58.  
  59. function sendToAll(mesg)
  60.     for id,value in pairs(ids) do
  61.         rednet.send(id,mesg,PROTOCOL)
  62.     end
  63. end
  64.  
  65. --Local Terminal Object (Usually the screen, but can also be a monitor)
  66. local lTerm
  67. --Terminal Object which is to be redirected to.
  68. rTerm = {}
  69.  
  70. --Writes to the terminal
  71. function rTerm.write(arg1)
  72.     sendDelay()
  73.     lTerm.write(arg1)
  74.     local mesg = {}
  75.     mesg.type = "call"
  76.     mesg.fn = "write"
  77.     mesg.args = {arg1}
  78.     sendToAll(mesg)
  79. end
  80.  
  81. --Blits to the Terminal
  82. function rTerm.blit(arg1,arg2,arg3)
  83.     sendDelay()
  84.     lTerm.blit(arg1,arg2,arg3)
  85.     local mesg= {}
  86.     mesg.type = "call"
  87.     mesg.fn = "blit"
  88.     mesg.args = {arg1,arg2,arg3}
  89.     sendToAll(mesg)
  90. end
  91.  
  92. --Clears Terminal
  93. function rTerm.clear()
  94.     sendDelay()
  95.     lTerm.clear()
  96.     local mesg = {}
  97.     mesg.type = "call"
  98.     mesg.fn = "clear"
  99.     mesg.args = {nil}
  100.     sendToAll(mesg)
  101. end
  102.  
  103. --Clears terminal Line
  104. function rTerm.clearLine()
  105.     sendDelay()
  106.     lTerm.clearLine()
  107.     local mesg = {}
  108.     mesg.type = "call"
  109.     mesg.fn = "clearLine"
  110.     mesg.args = {nil}
  111.     sendToAll(mesg)
  112. end
  113.  
  114. --Returns cursor position tuple
  115. function rTerm.getCursorPos()
  116.     return lTerm.getCursorPos()
  117. end
  118.  
  119. --Returns terminal color support
  120. function rTerm.isColor()
  121.     return lTerm.isColor()
  122. end
  123.  
  124. --Returns terminal colour support for british people
  125. rTerm.isColour = rTerm.isColor
  126.  
  127. --Retruns the tuple size of the terminal
  128. function rTerm.getSize()
  129.     return lTerm.getSize()
  130. end
  131.  
  132. --Scrolls the terminal
  133. function rTerm.scroll(arg1)
  134.     sendDelay()
  135.     lTerm.scroll(arg1)
  136.     local mesg = {}
  137.     mesg.type = "call"
  138.     mesg.fn = "scroll"
  139.     mesg.args = {arg1}
  140.     sendToAll(mesg)
  141. end
  142.  
  143. --For rsh this does nothing
  144. function rTerm.redirect()
  145.     rTerm.write("Silently Ignoring Attempt to redirect Terminal")
  146. end
  147.  
  148. --Returns the remote terminal object
  149. function rTerm.current()
  150.     return rTerm
  151. end
  152.  
  153. --sets the text color
  154. function rTerm.setTextColor(arg1)
  155.     sendDelay()
  156.     lTerm.setTextColor(arg1)
  157.     local mesg = {}
  158.     mesg.type = "call"
  159.     mesg.fn = "setTextColor"
  160.     mesg.args = {arg1}
  161.     sendToAll(mesg)
  162. end
  163.  
  164. --sets the text color for british people
  165. rTerm.setTextColour = rTerm.setTextColor
  166.  
  167. --gets the text color
  168. function rTerm.getTextColor()
  169.     return lTerm.getTextColor()
  170. end
  171.  
  172. --sets cursor blink
  173. function rTerm.setCursorBlink(arg1)
  174.     sendDelay()
  175.     lTerm.setCursorBlink(arg1)
  176.     local mesg = {}
  177.     mesg.type = "call"
  178.     mesg.fn = "setCursorBlink"
  179.     mesg.args = {arg1}
  180.     sendToAll(mesg)
  181. end
  182.  
  183. function rTerm.getCursorBlink()
  184.     return lTerm.setCursorBlink()
  185. end
  186.  
  187. --gets the text color for british people
  188. rTerm.getTextColour = rTerm.getTextColor
  189.  
  190. --sets the background color
  191. function rTerm.setBackgroundColor(arg1)
  192.     sendDelay()
  193.     lTerm.setBackgroundColour(arg1)
  194.     local mesg = {}
  195.     mesg.type = "call"
  196.     mesg.fn = "setBackgroundColor"
  197.     mesg.args = {arg1}
  198.     sendToAll(mesg)
  199. end
  200.  
  201. --sets the background color for british people
  202. rTerm.setBackgroundColour = rTerm.setBackgroundColor
  203.  
  204. --gets the background color
  205. function rTerm.getBackgroundColor()
  206.     return lTerm.getBackgroundColor()
  207. end
  208.  
  209. --gets the background color for british people
  210. rTerm.getBackgroundColour = rTerm.getBackgroundColor
  211.  
  212. --Sets cursor pos
  213. function rTerm.setCursorPos(arg1,arg2)
  214.     sendDelay()
  215.     lTerm.setCursorPos(arg1,arg2)
  216.     local mesg = {}
  217.     mesg.type = "call"
  218.     mesg.fn = "setCursorPos"
  219.     mesg.args = {arg1,arg2}
  220.     sendToAll(mesg)
  221. end
  222.  
  223. --Functions for responding to clients
  224. local fn = {}
  225. function fn.query()
  226.     local mesg = {}
  227.     mesg.width,mesg.height = lTerm.getSize()
  228.     mesg.color = lTerm.isColor()
  229.     return mesg
  230. end
  231. function fn.login(id)
  232.     ids[id] = true
  233.     return "success"
  234. end
  235. function fn.logout(id)
  236.     ids[id] = nil
  237.     return "success"
  238. end
  239.  
  240. --Happens when we are the host
  241. if #argv >= 3 and (argv[1] == "--host" or argv[1] == "--hostReadOnly") then
  242.     if argv[1] == "--hostReadOnly" then
  243.         EVENT_WHITELIST = {} --Client is not allowed to send Events
  244.     end
  245.     local modemSide = modemGet()
  246.     rednet.host(PROTOCOL,argv[2])
  247.     --terminal object that will be redirected to
  248.     lTerm = term.redirect(rTerm)
  249.     local coSh = coroutine.create(
  250.         function ()
  251.             --runs the program
  252.             shell.run(table.unpack(argv,3))
  253.         end
  254.     )
  255.     local currentEvent = {}
  256.     local pullFor
  257.     local status
  258.     repeat
  259.         if pullFor == nil or pullFor == currentEvent[1] then
  260.             status, pullFor = coroutine.resume(coSh, table.unpack(currentEvent))
  261.         end
  262.         if status then
  263.             currentEvent = {os.pullEventRaw()}
  264.             if currentEvent[1] == "rednet_message" and currentEvent[4] == PROTOCOL then
  265.                 if ids[currentEvent[2]] and currentEvent[3].type and currentEvent[3].type == "event" then
  266.                     if EVENT_WHITELIST[currentEvent[3].args[1]] then
  267.                         currentEvent = currentEvent[3].args
  268.                     else
  269.                         currentEvent = {}
  270.                     end
  271.                 elseif currentEvent[3].type and fn[currentEvent[3].type] then
  272.                     local status = pcall(function () mesg = fn[currentEvent[3].type](currentEvent[2],currentEvent[3].args) end)
  273.                     if status then
  274.                         rednet.send(currentEvent[2],mesg,PROTOCOL)
  275.                     else
  276.                         local mesg = {} --disconnect client for invalid message
  277.                         mesg.type = "disconnect"
  278.                         rednet.send(currentEvent[2],mesg,PROTOCOL) --Disconnect client
  279.                         ids[currentEvent[2]] = false
  280.                     end
  281.                     currentEvent = {}
  282.                 end
  283.             end
  284.             if currentEvent[1] == "timer" then
  285.                 timer = 0
  286.             end
  287.         else
  288.             break
  289.         end
  290.     until coroutine.status(coSh) == "dead"
  291.     local mesg = {}
  292.     mesg.type = "disconnect"
  293.     sendToAll(mesg)
  294.     rednet.close(modemSide)
  295.     term.redirect(lTerm)
  296. --happens when we are the client
  297. elseif #argv == 1 then
  298.     local modemSide = modemGet()
  299.     local id = rednet.lookup(PROTOCOL,argv[1])
  300.     if not id then
  301.         print("Unable to find computer with specified hostname.")
  302.         error()
  303.     end
  304.     local mesg = {}
  305.     mesg.type = "query"
  306.     mesg.args = {}
  307.     rednet.send(id,mesg,PROTOCOL)
  308.     local _,reply = rednet.receive(PROTOCOL)
  309.     mesg.type = "login"
  310.     mesg.args = {}
  311.     rednet.send(id,mesg,PROTOCOL)
  312.     term.setCursorBlink(true)
  313.     while true do
  314.         local event = {os.pullEvent()}
  315.         --received message from host
  316.         if event[1] == "rednet_message" and event[2] == id and event[4] == PROTOCOL then
  317.             local reply = event[3]
  318.             if reply.type then
  319.                 if reply.type == "call" and not TERM_BLACKLIST[reply.fn] then
  320.                     term[reply.fn](table.unpack(reply.args))
  321.                 elseif reply.type == "disconnect" then
  322.                     break
  323.                 end
  324.             end
  325.         --disconnecting
  326.         elseif event == "terminate" then
  327.             mesg = {}
  328.             mesg.type = "logout"
  329.             mesg.args = {}
  330.             rednet.send(id,mesg,protocol)
  331.             break
  332.         --sending event to host
  333.         elseif EVENT_WHITELIST[event[1]] then
  334.             mesg = {}
  335.             mesg.type = "event"
  336.             mesg.args = event
  337.             rednet.send(id,mesg,PROTOCOL)
  338.         end
  339.     end
  340.     rednet.close(modemSide)
  341. --user wants help
  342. elseif argv[1] == "help"
  343.     print("Remote shell")
  344. else
  345.     usage()
  346. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement