Advertisement
Tag365

Remote Terminal

May 7th, 2015
532
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.94 KB | None | 0 0
  1. remoteTerminal = {}
  2. local tArgs = {...}
  3. remoteTerminal.termCommands = {}
  4. remoteTerminal.termServerFunctions = {}
  5. remoteTerminal.queuedFunctionCalls = {}
  6. local scrWidth, scrHeight = term.getSize()
  7.  
  8. local sides = peripheral.getNames()
  9.  
  10. function getModem()
  11. while true do
  12. for k, v in ipairs(sides) do
  13. if peripheral.getType(v) == "modem" then
  14. selectedside = v
  15. return v
  16. end
  17. end
  18. sleep()
  19. end
  20. end
  21. getModem()
  22.  
  23. rednet.open(selectedside)
  24.  
  25. function yield(time)
  26. for k=1, time or 1 do
  27. os.queueEvent("yield")
  28. os.pullEvent("yield")
  29. end
  30. end
  31.  
  32. function addToQueuedFunctionCalls(name, ...)
  33. if type(name) == "function" then
  34. error("Name cannot be of type function", 2)
  35. end
  36. local tArgs = {...}
  37. local valuesToRemove = {}
  38. local varsRemoved = 0
  39. for k, v in pairs(tArgs) do
  40. if type(v) == "function" then
  41. valuesToRemove[#valuesToRemove + 1] = k
  42. elseif v == "true" then
  43. tArgs[k] = true
  44. elseif v == "false" then
  45. tArgs[k] = false
  46. end
  47. end
  48. for k, v in pairs(valuesToRemove) do
  49. table.remove(tArgs, k - varsRemoved)
  50. varsRemoved = varsRemoved + 1
  51. end
  52. remoteTerminal.queuedFunctionCalls[#remoteTerminal.queuedFunctionCalls + 1] = {tostring(name), unpack(tArgs)}
  53. end
  54.  
  55. function newCommand(name, funct)
  56. function onUse(...)
  57. local tArgs = {...}
  58. local removedElements = 0
  59. for k=1, #tArgs do
  60. if checkTableForFunctions(tArgs[k]) then
  61. table.remove(tArgs, k - removedElements)
  62. removedElements = removedElements + 1
  63. end
  64. end
  65. addToQueuedFunctionCalls(name, unpack(tArgs))
  66. return funct(...)
  67. end
  68. remoteTerminal.termServerFunctions[name] = onUse
  69. return onUse
  70. end
  71.  
  72. for k, v in pairs(term) do
  73. remoteTerminal.termCommands[k] = v
  74. end
  75. local redrawTimer = os.startTimer(.1)
  76.  
  77. function checkTableForFunctions(tab)
  78. if type(tab) ~= "table" then return false end
  79. for k, v in pairs(tab) do
  80. if type(v) == "function" then
  81. return true
  82. elseif type(v) == "table" then
  83. if checkTableForFunctions(tab[k]) then
  84. return true
  85. end
  86. end
  87. end
  88. return false
  89. end
  90.  
  91. function server(id)
  92. if id == os.getComputerID() then
  93. error("The client ID must not be the same as the server computer's ID.", 0)
  94. end
  95. remoteTerminal.id = id or tonumber(tArgs[2]) or 4 or rednet.receive("Connect")
  96. sleep(.1)
  97. for k, v in pairs(term) do
  98. term[k] = newCommand(k, term[k])
  99. end
  100. for k, v in pairs(remoteTerminal.termServerFunctions) do
  101. term[k] = remoteTerminal.termServerFunctions[k]
  102. end
  103. local oldRaw = os.pullEventRaw
  104. function os.pullEventRaw(...)
  105. local event, p1, p2, p3, p4, p5 = oldRaw(...)
  106. if event == "rednet_message" then
  107. if p1 == remoteTerminal.id or id or p1 then
  108. local eTab = textutils.unserialize(p2)
  109. local sE, sE1, sE2, sE3, sE4, sE5 = eTab[1], eTab[2], eTab[3], eTab[4], eTab[5], eTab[6]
  110. if not (sE == le and sE1 == lp1 and sE2 == lp2 and sE3 == lp3 and sE4 == lp4 and sE5 == lp5) then
  111. os.queueEvent(sE, sE1, sE2, sE3, sE4, sE5)
  112. end
  113. le, lp1, lp2, lp3, lp4, lp5 = sE, sE1, sE2, sE3, sE4, sE5
  114. end
  115. elseif event == "timer" and p1 == redrawTimer then
  116. local removedElements = 0
  117. for k=1, #remoteTerminal.queuedFunctionCalls do
  118. if checkTableForFunctions(remoteTerminal.queuedFunctionCalls[k]) then
  119. table.remove(remoteTerminal.queuedFunctionCalls, k - removedElements)
  120. removedElements = removedElements + 1
  121. end
  122. end
  123. local str = textutils.serialize(remoteTerminal.queuedFunctionCalls)
  124. for k=1, 2 do
  125. yield()
  126. rednet.send(id, str)
  127. end
  128. remoteTerminal.queuedFunctionCalls = {}
  129. redrawTimer = os.startTimer(.1)
  130. else
  131. return event, p1, p2, p3, p4, p5
  132. end
  133. return event, p1, p2, p3, p4, p5
  134. end
  135. function os.pullEvent( sFilter )
  136. local eventData = { os.pullEventRaw( sFilter ) }
  137. if eventData[1] == "terminate" then
  138. error( "Terminated", 0 )
  139. end
  140. return unpack( eventData )
  141. end
  142. remoteTerminal.queuedFunctionCalls = {}
  143. redrawTimer = os.startTimer(.1)
  144. print("To disconnect, reboot the computer.")
  145. end
  146.  
  147. function drawDebug(functName, ...)
  148. local tArgs = {...}
  149. local ox, oy = term.getCursorPos()
  150. term.setCursorPos(1, scrHeight)
  151. term.clearLine()
  152. term.write(functName)
  153. for k, v in ipairs(tArgs) do
  154. term.write(", "..tostring(v))
  155. end
  156. term.setCursorPos(ox, oy)
  157. end
  158.  
  159. function client(id)
  160. remoteTerminal.id = id or tonumber(tArgs[2]) or 3
  161. print("Redirected to remote terminal")
  162. local clearScreenOnFirstDrawMessageSent = true
  163. while true do
  164. local event, p1, p2, p3, p4, p5 = os.pullEventRaw()
  165. if event == "rednet_message" then
  166. if p1 == remoteTerminal.id or id or p1 then
  167. local drawTab = textutils.unserialize(p2)
  168. for k, v in pairs(drawTab) do
  169. if v[1] == "print" then
  170. local f = _G[v[1]]
  171. f(v[2], v[3], v[4], v[5], v[6], v[7])
  172. else
  173. local f = term[v[1]]
  174. if v[1] ~= "scroll" then
  175. if v[1] ~= "setCursorPos" and v[1] ~= "getCursorPos" then
  176. --drawDebug(v[1], v[2], v[3], v[4], v[5], v[6])
  177. end
  178. end
  179. if v[1] == "redirect" then
  180. f(v[2] or term.native())
  181. elseif v[1] == "current" then
  182.  
  183. elseif v[1] == "setCursorBlink" then
  184. if type(v[2]) == "string" then
  185. v[2] = v[2] == "true"
  186. end
  187. f(v[2])
  188. elseif v[1] == "scroll" then
  189. f(tonumber(v[2]) or 0)
  190. elseif v[1] == "setCursorPos" then
  191. f(tonumber(v[2]) or 0, tonumber(v[3]) or 0)
  192. elseif v[1] == "setTextColor" or v[1] == "setTextColour" or v[1] == "setBackgroundColor" or v[1] == "setBackgroundColour" then
  193. f(tonumber(v[2]) or 0)
  194. else
  195. f(v[2], v[3], v[4], v[5], v[6], v[7])
  196. if clearScreenOnFirstDrawMessageSent then
  197. term.clear()
  198. clearScreenOnFirstDrawMessageSent = false
  199. end
  200. end
  201. end
  202. end
  203. else
  204. rednet.send(id, textutils.serialize({event, p1, p2, p3, p4, p5}))
  205. end
  206. elseif event == "terminate" then
  207. error("Terminated", 0)
  208. else
  209. rednet.send(id, textutils.serialize({event, p1, p2, p3, p4, p5}))
  210. end
  211. end
  212. end
  213.  
  214. if tArgs[1] == "server" then
  215. if not tArgs[2] then
  216. print("Usage: "..shell.getRunningProgram().." server <computer id>")
  217. print("Only the computer with the ID you typed in will be able to affect this computer.")
  218. return false
  219. end
  220. server(tonumber(tArgs[2]))
  221. elseif tArgs[1] == "client" then
  222. if not tArgs[2] then
  223. print("Usage: "..shell.getRunningProgram().." client <computer id>")
  224. print("The computer ID must be the same as the server you want to connect to.")
  225. return false
  226. end
  227. local canceled, err = pcall(client, tonumber(tArgs[2]))
  228. if not canceled then
  229. term.setCursorPos(1, 1)
  230. error(err, 0)
  231. end
  232. else
  233. print("On the computer you want to connect to, run remoteTerminal server <computer id>")
  234. print("Only the computer with the ID you typed in will be able to affect this computer.")
  235. print("Then, on this computer run "..shell.getRunningProgram().." client <computer id>")
  236. print("The computer ID must be the same as the server you want to connect to.")
  237. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement