This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
lieudusty's profile picture

Remote shell?

Started by lieudusty, 29 October 2012 - 11:03 PM
lieudusty #1
Posted 30 October 2012 - 12:03 AM
Hi everyone! :P/>/>

I'm trying to make a remote shell but I don't even have the concept on how to record the terminal and display it back on another computer. Can someone explain to me how this will work or the concept of it?
Lyqyd #2
Posted 30 October 2012 - 12:43 AM
Use a redirect table to transmit the term calls and their parameters to the remote machine.
lieudusty #3
Posted 30 October 2012 - 01:54 AM
Use a redirect table to transmit the term calls and their parameters to the remote machine.
Can you show me a small example of getting the redirect table? I can't seem to find it in the term api
Lyqyd #4
Posted 30 October 2012 - 02:10 AM
You just kinda do this:


function redirectToID(targetID)
  local redirectTable = {
    sendTarget = targetID
  }
  redirectTable.write = function(text)
    rednet.send(redirectTable.sendTarget, "WR"..text)
  end
  redirectTable.setCursorPos = function(x,y)
    rednet.send(redirectTable.sendTarget, "SC"..x..","..y)
  end
  redirectTable.getCursorPos = function()
    rednet.send(redirectTable.sendTarget, "GC")
    id, message = rednet.receive(2)
    if id == redirectTable.sendTarget then
      if string.sub(message, 1, 2) == "CP" then
        return string.match(message, "CP(%d+),(%d+)")
      end
    end
  end
  --etc
  return redirectTable
end
lieudusty #5
Posted 30 October 2012 - 02:38 AM
You just kinda do this:


function redirectToID(targetID)
  local redirectTable = {
	sendTarget = targetID
  }
  redirectTable.write = function(text)
	rednet.send(redirectTable.sendTarget, "WR"..text)
  end
  redirectTable.setCursorPos = function(x,y)
	rednet.send(redirectTable.sendTarget, "SC"..x..","..y)
  end
  redirectTable.getCursorPos = function()
	rednet.send(redirectTable.sendTarget, "GC")
	id, message = rednet.receive(2)
	if id == redirectTable.sendTarget then
	  if string.sub(message, 1, 2) == "CP" then
		return string.match(message, "CP(%d+),(%d+)")
	  end
	end
  end
  --etc
  return redirectTable
end
Thanks! That helped me quite a lot considering its not finished but I get the concept now :P/>/> Thanks
EDIT: Arg…. I tried coding it but turns out I still don't get the concept. :/ Can someone explain this more clearly?
faubiguy #6
Posted 30 October 2012 - 04:06 AM
The redirect table contains a function to use in place of each function in the the term API. For example the write function would send a message to the target ID telling it to use term.write, the setCursorPos function would send a message to the target ID telling it to set the cursor position, the getCursorPos function would send a message to the target ID asking for the cursor position then wait for a response, and so on.
Lyqyd #7
Posted 30 October 2012 - 04:14 AM
Obviously, this requires a script on the other end listening for these packets and acting appropriately. There is a working example in LyqydNet, but obviously, the rednet operations are greatly simplified since it's dependent on LyqydNet. Here are the relevant portions of LyqydNet:

Spoiler

function text (conn)
    local textTable = {}
    textTable.conn = conn
    textTable.write = function(text)
        return connection.send(textTable.conn, "textWrite", text)
    end
    textTable.clear = function()
        return connection.send(textTable.conn, "textClear", "nil")
    end
    textTable.clearLine = function()
        return connection.send(textTable.conn, "textClearLine", "nil")
    end
    textTable.getCursorPos = function()
        if connection.send(textTable.conn, "textGetCursorPos", "nil") then
            local pType, message = connection.awaitResponse(textTable.conn, 2)
            if pType and pType == "textInfo" then
                local x, y = string.match(message, "(%d+),(%d+)")
                return tonumber(x), tonumber(y)
            end
        else return false end
    end
    textTable.setCursorPos = function(x, y)
        return connection.send(textTable.conn, "textCursorPos", math.floor(x)..","..math.floor(y))
    end
    textTable.setCursorBlink = function(:P/>/>
        if b then
            return connection.send(textTable.conn, "textBlink", "true")
        else
            return connection.send(textTable.conn, "textBlink", "false")
        end
    end
    textTable.getSize = function()
        if connection.send(textTable.conn, "textGetSize", "nil") then
            local pType, message = connection.awaitResponse(textTable.conn, 2)
            if pType and pType == "textInfo" then
                local x, y = string.match(message, "(%d+),(%d+)")
                return tonumber(x), tonumber(y)
            end
        else return false end
    end
    textTable.scroll = function(lines)
        return connection.send(textTable.conn, "textScroll", lines)
    end
    return textTable
end

function processText(conn, pType, value)
    if not pType then return false end
    if pType == "textWrite" and value then
        term.write(value)
    elseif pType == "textClear" then
        term.clear()
    elseif pType == "textClearLine" then
        term.clearLine()
    elseif pType == "textGetCursorPos" then
        local x, y = term.getCursorPos()
        connection.send(conn, "textInfo", math.floor(x)..","..math.floor(y))
    elseif pType == "textCursorPos" then
        local x, y = string.match(value, "(%d+),(%d+)")
        term.setCursorPos(x, y)
    elseif pType == "textBlink" then
        if value == "true" then
            term.setCursorBlink(true)
        else
            term.setCursorBlink(false)
        end
    elseif pType == "textGetSize" then
        x, y = term.getSize()
        connection.send(conn, "textInfo", x..","..y)
    elseif pType == "textScroll" and value then
        term.scroll(value)
    end
    return
end