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

Rednet Turtle Controler

Started by Craftplorer, 22 November 2013 - 04:40 PM
Craftplorer #1
Posted 22 November 2013 - 05:40 PM
Hi,
first im from germany so sorry if my grammar is bad.

I want to have a server/monitor in my base like 3*4 advanced monitor with a list of names of turtles like Woodchopper1….
My problem is that i have no idea how i can make the handshake between server and turtle and how i can storge data.
I already try it but i have only trouble with the handshake and rednet. Caus i dont wanne loose messages and if turtle crash the data like id is still in my table…
Below you see my try to create a system. How would you guys make the handshake and the data sending thing(so that no data get lost)?

Client:

rednet.open("right")
local pass = "123"
local spass = "456"
local handShake = true
while handShake do
  loginShake = true
  rednet.broadcast("hs")
  event, id, message, dist = os.pullEvent("rednet_message")
  if message == pass then
    while loginShake do
	  rednet.send(id, spass)
	  l1, p1, p2, p3 = os.pullEvent("rednet_message")
	  if p1 == id then
	    if p2 == "ok" then
		  loginShake = false
		  handShake = false
	    end
	  end
    end
  end
end
print("Handshake!")

Server:

rednet.open("right")
local pass = "123"
local rpass = "456"
local hs = {}
local hsc = 1

while true do
  event, id, message, dist = os.pullEvent("rednet_message")
  if message == "hs" then
    rednet.send(id, pass)
    hs[hsc] = {}
    hs[hsc].id = id
    hs[hsc].phase = 1
    hsc = hsc + 1
  elseif message == rpass then
    for i = 1, hsc-1 do
	  if id == hs[i].id then
	    rednet.send(hs[i].id, "ok")
	    hs[i].phase = 2
	    print("ok")
	    print(id)
	  end
    end
  end
end
Bomb Bloke #2
Posted 23 November 2013 - 01:40 AM
I think that's a good start. It just needs to be expanded out so that the server discards turtles occasionally.

A couple of points. Any computer/turtle can "pretend" to be sending from any ID it wants to. It can also receive messages intended for any ID it wants. It would be easy to spy on your transmissions and learn your passwords, then spoof the IDs of your turtles, etc.

To make it properly secure you'd need to encrypt everything, but quite frankly you're probably better off just forgetting about that side of things entirely.

Anyway, an example as to how I might do it:

Server
rednet.open("top")
local turtleList = {}
local myEvent
local myColours = {colours.white, colours.yellow, colours.red}
term.clear()

while true do
  myEvent = {os.pullEvent()}  -- Builds a table out of everything the event returned.

  if myEvent[1] == "rednet_message" and myEvent[3] == "Hello turtle server" then
    rednet.send(myEvent[2], "Hello turtle")

    --   A variable is treated as "false" if it doesn't exist, so
    --   we can quickly check to see if the turtle is in the table.
    if not turtleList[myEvent[2]] then turtleList[myEvent[2]] = {} end

    turtleList[myEvent[2]].strikes = 1                  -- More then three and it's out!
    turtleList[myEvent[2]].timerID = os.startTimer(60)  -- Set a 60 second timer from now.

  elseif myEvent[1] == "timer" then
    -- One of the timers we set expired. Check if it matched one of our turtles:

    for id in pairs(turtleList) do
      if myEvent[2] == turtleList[id].timerID then

        -- Turtle gets a strike!
        turtleList[id].strikes = turtleList[id].strikes + 1

        if turtleList[id].strikes < 4 then   -- Turtle still has more chances to report in.
          turtleList[id].timerID = os.startTimer(60)
        else
          turtleList[id] = nil  -- Turtle ran out of chances and is removed from the table!
        end

        break
      end
    end
  end

  -- Draw the list of turtles every time we get an event.
  term.clear()
  term.setCursorPos(1,1)
  term.setTextColor(colours.white)

  for id in pairs(turtleList) do
    term.setTextColor(myColours[turtleList[id].strikes])  -- Choose a colour depending on how many strikes the turtle has left.
    print(id)
  end
end

Client
rednet.open("right")
local serverID

rednet.broadcast("Hello turtle server")

while true do
  local myEvent = {os.pullEvent("rednet_message")}

  if myEvent[3] == "Hello turtle" then
    serverID = myEvent[2]
    break
  end
end

print("Reported in!")

This code puts your turtles in a table whenever they check in, but if they don't keep checking in, eventually removes them from that table. You'd need to devise a system for your turtles where they keep sending "Hello turtle server" messages at least once every few minutes, and I'm sure you can expand it further to deal with turtle names and so on.

To explain a couple of points, say you receive a rednet message event with:

myEvent = {os.pullEvent()}

"myEvent[1]" will be "rednet_message", "myEvent[2]" will be the ID that sent it, "myEvent[3]" will be the message and so on.

See here for info on the timer function.
Craftplorer #3
Posted 23 November 2013 - 05:48 AM
Ok thank you. That helps alot.