first off hi all
this is the second post i am making on these forums. I have only a limiteds experience with hobby programing in BASIC and a very small amount of C++ experience. I started learning lua about start of year or so. This is the first program that i am posing ( I have many that are not up to scratch that i wont post EVER )
down to business
GPS based IP relay System or "GP-IS" for short
Spoiler
is a system for transferring packets from one computer to another via a set of node's . each node decides where to forward the packed based on the receivers IP. this IP is the computers GPS location eg 101.-80.23.6 translates to X = 101 Y = -80 Z = 23 and the computers ID is 6 so based on that the node calculates distance to the node nearest the target and sends it there or sends the packet directly to target if the computer is registered to it (on its routing table).
sounds kinda complex ha. But it is not really. Benefits of this system.
Extremely hard to shutdown the hole network as it can reroute around damage ( not currently implemented)
All packets are sent from one system to another using rednet.send with the exception of Control packets.making it extremely hard to intercept and low lag to.
The way routers handle packets means it is impossible to spoof being another computer.
ease of setup and use allow for rapid expantion of dynamic networks quickly with out needing to manuly alter routing tables. ( its all automatic some parts still need work thought.)
nodes double as gps beacons
How to useis a system for transferring packets from one computer to another via a set of node's . each node decides where to forward the packed based on the receivers IP. this IP is the computers GPS location eg 101.-80.23.6 translates to X = 101 Y = -80 Z = 23 and the computers ID is 6 so based on that the node calculates distance to the node nearest the target and sends it there or sends the packet directly to target if the computer is registered to it (on its routing table).
sounds kinda complex ha. But it is not really. Benefits of this system.
Extremely hard to shutdown the hole network as it can reroute around damage ( not currently implemented)
All packets are sent from one system to another using rednet.send with the exception of Control packets.making it extremely hard to intercept and low lag to.
The way routers handle packets means it is impossible to spoof being another computer.
ease of setup and use allow for rapid expantion of dynamic networks quickly with out needing to manuly alter routing tables. ( its all automatic some parts still need work thought.)
nodes double as gps beacons
If you are experienced please conceder helping me by bug testing thank you in advance
This is for experienced lua programmer only at the moment for bug testing
this is very complex code and is currently buged / hard to operate
Spoiler
There are two codes bellow one is for the nodes the other is a example of a user application that would use this network/ it is a debugging tool.
for best results you should set up four or five normal computers with a wireless modem and set them to run gps host on startup.like picture 1 bellow
This line in a file Named "startup" with out "" marks will make it be a broadcaster on startup
shell.run("/rom/programs/gps","host",0,5,15)
edit coords and needed.
Place computer with wifi on top. Run node2 it will automatically sets own GPS-IP tag if it asks for coords then it is out of range of your gps beacons or there is a problem with a beacon / or there is no beacons. If you know the GPS location enter it. of fix/build beacons.
place another node and run node2 notice that it registers node one automatically. keep adding nodes till you have a good group of them in a spread out area.
make two normal computers a far distance but still inrange of four nodes. if they will be closer han 64 blocks extend your network by adding more nodes eatchone needs to be inrange or at least foru nodes or GPS location beaons.
run cnode on both computers. press c on one computer right down the IP press enter. go to the other computer with cnode. press c but type mesager. follow the instructions that mesager asks you. go to the first computer and you will see your mesage now press c and go into mesager again. but this time when asked for a ip DONT type anything and press ENTER you will see that is send automatically to your other computer. a cnode remember addresses of computers that contact it.
BUT this needs a stable location how does it work for turtles ?There are two codes bellow one is for the nodes the other is a example of a user application that would use this network/ it is a debugging tool.
for best results you should set up four or five normal computers with a wireless modem and set them to run gps host on startup.like picture 1 bellow
This line in a file Named "startup" with out "" marks will make it be a broadcaster on startup
shell.run("/rom/programs/gps","host",0,5,15)
edit coords and needed.
Place computer with wifi on top. Run node2 it will automatically sets own GPS-IP tag if it asks for coords then it is out of range of your gps beacons or there is a problem with a beacon / or there is no beacons. If you know the GPS location enter it. of fix/build beacons.
place another node and run node2 notice that it registers node one automatically. keep adding nodes till you have a good group of them in a spread out area.
make two normal computers a far distance but still inrange of four nodes. if they will be closer han 64 blocks extend your network by adding more nodes eatchone needs to be inrange or at least foru nodes or GPS location beaons.
run cnode on both computers. press c on one computer right down the IP press enter. go to the other computer with cnode. press c but type mesager. follow the instructions that mesager asks you. go to the first computer and you will see your mesage now press c and go into mesager again. but this time when asked for a ip DONT type anything and press ENTER you will see that is send automatically to your other computer. a cnode remember addresses of computers that contact it.
Spoiler
that is a very good question. it is currently not implemented but it is possible. If you hade one computer acting as a location server that holds the GPS-IP tags of where the turtles are and the turtles update this database server then you can send to turtles by sending packets to that server witch will route them to the correct node and ofc to the turtle.
Currently it is also possible to send to a node directly if you know that your target is in range of it. I may remove this feature if it is to much of a security risk. this is because the node doesn't check of the GPS-IP matches only if the ID matches and sends direct. as such the packet will end up in the right area by sending it at the node it is connected to..
To conclude this wall of text.that is a very good question. it is currently not implemented but it is possible. If you hade one computer acting as a location server that holds the GPS-IP tags of where the turtles are and the turtles update this database server then you can send to turtles by sending packets to that server witch will route them to the correct node and ofc to the turtle.
Currently it is also possible to send to a node directly if you know that your target is in range of it. I may remove this feature if it is to much of a security risk. this is because the node doesn't check of the GPS-IP matches only if the ID matches and sends direct. as such the packet will end up in the right area by sending it at the node it is connected to..
This system of packet routing could revolutionize the way data is transfered long distance in a minceraft world. If you have the time and experience i would really appreciate anyone testing this as it realy needs to be on a server to really be tested.
please post bug reports here with as mutch info as possible
Picture one my GPS tower services GPS requests.
Spoiler
NEW Latest testing candidates.
node 0.25
Spoiler
StartVer = 0.1 -- rember to change it in the start up too nodeVer = 0.25 testmode = true -- this turns on and off certin print functions -- function logPrint(...) if testmode then print(...) end end if fs.exists("startup") == false then sStartup = [[ -- This is the startup program that is installed by Node. startVer = 0.1 print("inisilizing node") if fs.exists("install") then print("installed new ver of Node") fs.delete("node") fs.move("install","node") end while true do sleep(2) local value1, value2 = shell.run("node") if value1 == nil then print("nil") else print(value1) end if value2 == nil then print("nil") else print(value2) end if value1 then break end end -- end of ]] print("Installing startup") local file = io.open( "startup", "w" ) file:write(sStartup) file:close() print("Rebooting in 3 seconds") sleep(3) os.reboot() else sStartup = nil end local x,y,z -- local location of this terminal -- wifi modem test -- local function openRednet() local listOfSides = { "top" , "bottom" , "front" , "left" , "right" , "back" } local listofPossibles = {} local counter1 = 0 while true do counter1 = counter1 +1 if peripheral.isPresent(tostring(listOfSides[counter1])) and peripheral.getType(listOfSides[counter1]) == "modem" then table.insert(listofPossibles,tostring(listOfSides[counter1])) end if counter1 == 6 and table.maxn(listofPossibles) == 0 then print("no wifi present") return nil end if counter1 == 6 and table.maxn(listofPossibles) ~= 0 then rednet.open(listofPossibles[1]) return listofPossibles[1] end end end modemOn = openRednet() if modemOn == nil then print("No WIFI Modem") print("Will shutdown in 3 seconds") sleep(3) os.shutdown() else print("Opened wifi on "..modemOn.." side") end -- wifi modem test end -- if fs.exists("config") then print("Loading config") file = io.open("config","r") x = file:read() y = file:read() z = file:read() file:close() print("Config loaded") else print("No config finding location") x,y,z = gps.locate( 2, true ) end if x == nil or y == nil or z == nil then local runagain = true while runagain do term.clear() term.setCursorPos(1,1) logPrint("please enter the X Y Z as auto location failed") logPrint("or type >exit< to end with out the ><") write(" X : ")x = io.read() if x == "exit" then return else x = tonumber(x) end write(" y : ")y = tonumber(io.read()) if y == "exit" then return else y = tonumber(y) end write(" z : ")z = tonumber(io.read()) if z == "exit" then return else z = tonumber(z) end if x == nil or y == nil or z == nil then runagain = true else runagain = false end end end -- save config if fs.exists("config") == false then if x ~= nil and y ~= nil and z ~= nil then file = io.open("config","w") file:write(x.."\n") file:write(y.."\n") file:write(z.."\n") file:close() print("Config created") end end local computersID = {} local computersX = {} local computersY = {} local computersZ = {} local computersM = {} local computersW = {} -- used for detection of down nodes -- local nodesID = {} local nodesX = {} local nodesY = {} local nodesZ = {} local nodesM = {} local nodesW = {} -- used for detection of down nodes -- local packetsID = {} local packetsTM = {} local packetsD = {} local loger = {} local value = "" local function rmsin(inf) inf = tostring(inf) if string.byte(inf,1) == 45 then inf = string.sub(inf,2,string.len(inf)) end return tonumber(inf) end local function checkFor(this,inhere) local loopn = 0 local maxedn = table.maxn(inhere) while true do if maxedn == loopn then return nil end loopn = loopn+1 if inhere[loopn] == this then return loopn end end end local function stringLocator(acton,looking,stpos) local tempvar = tonumber(stpos) if tempvar == nil then tempvar = 1 end local this = string.byte(looking) local endof = string.len(acton) while true do if string.byte(acton,tempvar) == this then return tempvar end if tempvar == endof then return end tempvar = tempvar + 1 end end local function decodeIP(pxq) -- this takes a string eg "1001.22030.11.12" and decodes it to 1001 22030 11 12 eatch local tabel = {} local st = tostring(pxq) -- a seprate value to be added to a routing table latter start = 1 -- start pos of where to look for the charicter "." loc = 0 -- this tracks where the last . was found so it will look further along fin = string.len(st) -- this is the end position to look to. local pass = 1 -- when pass = 4 the function will be made to return ( not yet coded ) -- while true do -- break down loop takes string apart local loc = stringLocator(st,".",start) -- finds the closes "." this is where the probblems begin if loc == nil then tabel[pass] = (string.sub(st,start,fin)) else tabel[pass] = (string.sub(st,start,loc-1)) start = loc+1 end if pass == 4 then break end pass = pass + 1 end return tonumber(tabel[1]),tonumber(tabel[2]),tonumber(tabel[3]),tonumber(tabel[4]) end local nextAlam = os.startTimer(120 + math.random(1,30)) rednet.broadcast("REG-NOD "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID())) sleep(0.1) while true do -- main loop -- this recives a message in this format "REG-COM 100.202.100.12" and should act acordinly. local event, var1, var2, var3, var4, var5 = os.pullEventRaw() local handled = false if event == "char" and var1 == "q" then term.clear() term.setCursorPos(1,1) print("closing down") sleep(3) term.clear() term.setCursorPos(1,1) return"exit" end if event == "timer" then if var1 == nextAlam then logPrint("refreshing nodes list") if table.maxn(loger) >= 20 then--- this is the loging system table.remove(loger,1) end table.insert(loger,tostring(os.time()).." : nodePingtTmer : "..tostring(var1).." con : "..tostring(var2)) rednet.broadcast("REG-NOD "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID())) nextAlam = os.startTimer(120 + math.random(1,30)) sleep(0.1) else local position2 = checkFor(var1,packetsTM) if position2 == nil then else local position = packetsID[position2] -- position is now the ID of the omputer local masterloc = checkFor(position,nodesID) if masterloc == nil then else if nodesW[masterloc] == "true" then logPrint("removing node"..nodesID[masterloc]) table.remove(nodesID,masterloc) table.remove(nodesX,masterloc) table.remove(nodesY,masterloc) table.remove(nodesZ,masterloc) table.remove(nodesM,masterloc) table.remove(nodesW,masterloc) event = "rednet_message" ---- experimental var1 = packetsID[position2] var2 = packetsD[position2] table.remove(packetsID,position2) table.remove(packetsTM,position2) table.remove(packetsD,position2) ---- very experimental end end table.remove(packetsID,position2) table.remove(packetsTM,position2) table.remove(packetsD,position2) end end end if event == "rednet_message" then if table.maxn(loger) >= 20 then --- this is the loging system table.remove(loger,1) end table.insert(loger,tostring(os.time()).." : rnet : "..var1.." con : "..var2) -- end of loging system if var2 == "PING" then rednet.send(tonumber(var1)+1-1, textutils.serialize({x,y,z})) handled = true end value = string.sub(var2,1,7) if value == "PING2--" then rednet.send(tonumber(var1)+1-1,"OPN-NOD "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID())) handled = true end if value == "REG-COM" then logPrint("regstering computer") local x4,y4,z4,id4 = decodeIP(string.sub(var2,9,string.len(var2))) if checkFor(id4,computersID) == nil then logPrint(x4.." "..y4.." "..z4.." "..id4) local newentry = table.maxn(computersID)+1 computersID[newentry] = tonumber(id4) -- i dont need the tonumbers computersX[newentry] = tonumber(x4) computersY[newentry] = tonumber(y4) computersZ[newentry] = tonumber(z4) computersM[newentry] = tonumber(var3) computersW[newentry] = "false" else logPrint("compuer already reged") end rednet.send(tonumber(var1)+1-1,"REG-RPL "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID())) handled = true end if value == "REG-RPL" then logPrint("reciving reply") local x4,y4,z4,id4 = decodeIP(string.sub(var2,9,string.len(var2))) if checkFor(id4,computersID) == nil then logPrint(x4.." "..y4.." "..z4.." "..id4) local newentry = table.maxn(computersID)+1 computersID[newentry] = tonumber(id) -- i dont need the tonumbers computersX[newentry] = tonumber(x4) computersY[newentry] = tonumber(y4) computersZ[newentry] = tonumber(z4) computersM[newentry] = tonumber(var3) computersW[newentry] = "false" else logPrint("computer already reged") end handled = true end if value == "INSTALL" then local tempvar = string.sub(var2,9) file = io.open("install","w") file:write(tempvar) file:close() logPrint(tempvar) logPrint("bellow temp var") sleep(0.5) os.reboot() sleep(0.5) handled = true end if value == "REG-NOD" then -- this will be used latter for simlor perpous to above if statment logPrint("regstering Node") x6,y6,z6,id6 = decodeIP(string.sub(var2,9,string.len(var2))) if checkFor(id6,nodesID) == nil then logPrint(x6.." "..y6.." "..x6.." "..id6) local newentry = table.maxn(nodesID)+1 nodesID[newentry] = tonumber(id6) -- i dont need the tonumbers nodesX[newentry] = tonumber(x6) nodesY[newentry] = tonumber(y6) nodesZ[newentry] = tonumber(z6) nodesM[newentry] = tonumber(var3) nodesW[newentry] = "false" else logPrint("node already reged") end logPrint("replying to :"..var1) rednet.send(tonumber(var1+1-1),"REGNRPL "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID())) handled = true end if value == "REGNRPL" then -- this will be used latter for simlor perpous to above if statment logPrint("node replyed to reg") x6,y6,z6,id6 = decodeIP(string.sub(var2,9,string.len(var2))) if checkFor(id6,nodesID) == nil then logPrint(x6.." "..y6.." "..x6.." "..id6) local newentry = table.maxn(nodesID)+1 nodesID[newentry] = tonumber(id6) -- i dont need the tonumbers nodesX[newentry] = tonumber(x6) nodesY[newentry] = tonumber(y6) nodesZ[newentry] = tonumber(z6) nodesM[newentry] = tonumber(var3) nodesW[newentry] = "false" else logPrint("node already reged") end handled = true end if value == "S-ALIVE" then -- this is part of the is node alive check system. if checkFor(var1,nodesID) ~= nill then local row = checkFor(var1,nodesID) nodesW[row] = "false" -- node is still alive -- end handled = true logPrint(var1.." Is still around") end if tonumber(var1) == os.getComputerID() then handled = true end if handled == false then local pos1 = stringLocator(var2," ") local x1,y1,z1,id1 = decodeIP(string.sub(var2,1,pos1-1)) local pos2 = stringLocator(var2," ",pos1+1) local x2,y2,z2,id2 = decodeIP(string.sub(var2,pos1+1,pos2-1)) payload = string.sub(var2,pos2+1,string.len(var2)) if x1 == nil or y1 == nil or z1 == nil or id1 == nil or x2 == nil or y2 == nil or z2 == nil or id2 == nil or pos1 == nil or pos2 == nil then logPrint("Network error 05 - Packet not corect format") else if testmod == true then -- TEST FLAG logPrint(payload) logPrint("from: "..x1.." "..y1.." "..z1.." "..id1) logPrint("for : "..x2.." "..y2.." "..z2.." "..id2) end -- end TEST FLAG local test = checkFor(id2,computersID) if test == nil then local test = checkFor(id2,nodesID) if test == nil then logPrint("cant send direct") -- find closest node and send there after printing local loopz = 1 local bestM = nil local sendID = nil while true do if nodesID[loopz] == id2 then logPrint("cant send back to sorce, will keep looking") else local tp1 = x2 - nodesX[loopz] local tp2 = y2 - nodesY[loopz] local tp3 = math.sqrt((tp1^2) + (tp2^2)) local tp4 = z2 - nodesZ[loopz] local tp5 = math.sqrt(tp3^2 + tp4^2) logPrint (nodesID[loopz].." is meters : "..tp5) if bestM == nil then bestM = tp5 sendID = nodesID[loopz] else if bestM > tp5 then bestM = tp5 sendID = nodesID[loopz] logPrint("new best is "..sendID.." M - "..bestM) end end end if loopz == table.maxn(nodesID) then break end loopz = loopz+1 end if sendID == nil then logPrint("sending to nil ") end sendID = math.ceil(sendID) rednet.send(sendID,var2) logPrint("packet sent to M1 :"..sendID) local blue = tonumber(checkFor(sendID,nodesID)) nodesW[blue] = "true" rednet.send(tonumber(var1),"S-ALIVE "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID())) logPrint("Relpy to node: "..tonumber(var1)) local o = table.maxn(packetsID)+1 packetsID[o] = sendID packetsTM[o] = os.startTimer(10) packetsD[o] = var2 else rednet.send(nodesID[test],var2) nodesW[test] = "true" logPrint("sending to node : "..nodesID[test]) rednet.send(tonumber(var1),"S-ALIVE "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID())) logPrint("Replyed to: "..tonumber(var1)) o = table.maxn(packetsID)+1 packetsID[o] = nodesID[test] packetsTM[o] = os.startTimer(10) packetsD[o] = var2 end else test = tonumber(test) rednet.send(tonumber(computersID[test])+1-1,var2) logPrint("sending to comp : "..computersID[test]) rednet.send(tonumber(var1)+1-1,"S-ALIVE "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID())) logPrint("sent reply node "..var1) end end end end if event == "char" then -- char events . mostly tests if var1 == "t" then term.clear() term.setCursorPos(1,1) local loops = 0 while true do if loops == table.maxn(computersID) then logPrint("end of Computer table") break end loops = loops +1 logPrint("entry "..loops.." : "..computersID[loops].." X "..computersX[loops].." Y "..computersY[loops].." Z "..computersZ[loops].." M "..computersM[loops]) end end if var1 == "y" then term.clear() term.setCursorPos(1,1) local loops = 0 while true do if loops == table.maxn(nodesID) then logPrint("end of Nodes table") break end loops = loops +1 logPrint("entry "..loops.." : "..nodesID[loops].." X "..nodesX[loops].." Y "..nodesY[loops].." Z "..nodesZ[loops].." M "..nodesM[loops]) end end if var1 == "u" then term.clear() term.setCursorPos(1,1) local loops = 0 while true do if loops == table.maxn(packetsID) then logPrint("end of packets") break end loops = loops +1 logPrint("entry "..loops.." : "..packetsID[loops].." : "..tostring(packetsTM[loops]).." : "..packetsD[loops]) end end if var1 == "r" then loops = 0 term.clear() term.setCursorPos(1,1) logPrint("This is Node ver"..tostring(nodeVer).." : "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID())) while true do if loops == table.maxn(loger) then logPrint("end of log") break end loops = loops +1 logPrint("entry "..loops.." : "..loger[loops]) end end if var1 == "c" then term.clear() term.setCursorPos(1,1) if testmode == true then print("This will be console access test mode OFF") tempvarvar = false end if testmode == false then print("This will be console access test mode ON") tempvarvar = true end testmode = tempvarvar end end -- end of char events end
cnode 0.31
Spoiler
cnodeVer = 0.31 -- wifi modem test -- local function openRednet() -- local listOfSides = { "top" , "bottom" , "front" , "left" , "right" , "back" } local listOfSides = rs.getSides() local listofPossibles = {} local counter1 = 0 while true do counter1 = counter1 +1 if peripheral.isPresent(tostring(listOfSides[counter1])) and peripheral.getType(listOfSides[counter1]) == "modem" then table.insert(listofPossibles,tostring(listOfSides[counter1])) end if counter1 == 6 and table.maxn(listofPossibles) == 0 then print("no wifi present") return nil end if counter1 == 6 and table.maxn(listofPossibles) ~= 0 then rednet.open(listofPossibles[1]) return listofPossibles[1] end end end modemOn = openRednet() if modemOn == nil then print("No WIFI Modem") print("Will shutdown in 3 seconds") sleep(3) os.shutdown() else print("Opened wifi on "..modemOn.." side") end -- wifi modem test end -- local x,y,z = gps.locate(2) local id = os.getComputerID() local nx , ny , nz , nid local idTable = {} local mTable = {} local ipTable = {} local value = "" local savtoconfig = "y" local function checkFor(this,inhere) local loopn = 0 local maxedn = table.maxn(inhere) while true do if maxedn == loopn then return nil end loopn = loopn+1 if inhere[loopn] == this then return loopn end end end local function coordcalc(i1,i2,i3,v1,v2,v3) if i1 == nil or i2 == nil or i3 == nil or v1 == nil or v2 == nil or v3 ==nil then return nil end local temp = math.sqrt(((i1-v1)^2) + ((i2-v2)^2)) m = math.sqrt(temp^2 + ((i3-v3)^2)) return m end local function stringLocator(acton,looking,stpos) local tempvar = tonumber(stpos) if tempvar == nil then tempvar = 1 end local this = string.byte(looking) local endof = string.len(acton) while true do if string.byte(acton,tempvar) == this then return tempvar end if tempvar == endof then return end tempvar = tempvar + 1 end end local function decodeIP(pxq) -- this takes a string eg "1001.22030.11.12" and decodes it to 1001 22030 11 12 eatch local tabel = {} local st = tostring(pxq) -- a seprate value to be added to a routing table latter local start = 1 -- start pos of where to look for the charicter "." local loc = 0 -- this tracks where the last . was found so it will look further along local fin = string.len(st) -- this is the end position to look to. local pass = 1 -- when pass = 4 the function will be made to return ( not yet coded ) -- while true do -- break down loop takes string apart local loc = stringLocator(st,".",start) -- finds the closes "." this is where the probblems begin if loc == nil then tabel[pass] = (string.sub(st,start,fin)) else tabel[pass] = (string.sub(st,start,loc-1)) start = loc+1 end if pass == 4 then break end pass = pass + 1 end return tonumber(tabel[1]),tonumber(tabel[2]),tonumber(tabel[3]),tonumber(tabel[4]) end if fs.exists("config") then print("loading config") file = io.open("config","r") x = tonumber(file:read()) y = tonumber(file:read()) z = tonumber(file:read()) file:close() print("config loaded") end if x == nil or y == nil or z == nil then local runagain = true while runagain do term.clear() term.setCursorPos(1,1) print("please enter the X Y Z as auto location failed") print("or type >exit< to end with out the ><") write(" X : ")x = io.read() if x == "exit" then return else x = tonumber(x) end write(" y : ")y = tonumber(io.read()) if y == "exit" then error() else y = tonumber(y) end write(" z : ")z = tonumber(io.read()) if z == "exit" then error() else z = tonumber(z) end if x == nil or y == nil or z == nil then runagain = true else runagain = false end end end if fs.exists("config") == false and savtoconfig == "y" then if x ~= nil and y ~= nil and z ~= nil then print("Config created") file = io.open("config","w") file:write(x.."\n") file:write(y.."\n") file:write(z.."\n") file:write(id.."\n") file:close() end end rednet.broadcast("PING2-- "..x..y..z..id) local timer = os.startTimer(3) while true do local event, var1, var2, var3, var4, var5 = os.pullEventRaw() if event == "timer" then if var1 == timer then local pos = 1 local current = mTable[1] local pos2 = 1 if table.maxn(mTable) <= 0 then print("no nodes in range") break else while true do if mTable[pos] < current then current = mTable[pos] pos2 = pos end if pos == table.maxn(mTable) then break end pos = pos+1 end nid = idTable[pos2] nx,ny,nz = decodeIP(ipTable[pos2]) local timer1 = os.startTimer(90) while true do rednet.send(nid,"REG-COM "..x.."."..y.."."..z.."."..id) event, var1, var2, var3, var4, var5 = os.pullEvent() if string.sub(tostring(var2),1,7) == "REG-RPL" then break end if var1 == timer1 then print("failed to regester") error() end end print("we have regestered to node") print(nx.."."..ny.."."..nz.."."..nid) break end end end if event == "rednet_message" then value = string.sub(var2,1,7) if value == "OPN-NOD" then table.insert(idTable,tonumber(var1)) table.insert(mTable,var3) table.insert(ipTable,string.sub(var2,9,string.len(var2))) end end end local tComputers = {} tComputers['ID'] = {} tComputers['X'] = {} tComputers['Y'] = {} tComputers['Z'] = {} tComputers['IP'] = {} local function eventOrNode() while true do event, var1, var2, var3, var4, var5 = os.pullEventRaw() if event == "rednet_message" then value = string.sub(var2,1,7) if value == "PING2--" or value == "REG-COM" or value == "REG-RPL" or value == "INSTALL" or value == "REG-NOD" or value == "REGNRPL" or value == "S-ALIVE" then else local pos3 = stringLocator(var2," ") if pos3 == nil then return event, var1, var2, var3, var4, var5 else local pos4 = stringLocator(var2," ",pos3+1) if pos4 == nil then return event, var1, var2, var3, var4, var5 else x3,y3,z3,id3 = decodeIP(string.sub(var2,1,pos3-1)) -- sender x4,y4,z4,id4 = decodeIP(string.sub(var2,pos3+1,pos4-1)) -- reciver if x3 == nil or y3 == nil or z3 == nil or id3 == nil or x4 == nil or y4 == nil or z4 == nil or id4 == nil then return event, var1, var2, var3, var4, var5 else local testvar = checkFor(id3,tComputers['ID']) if testvar == nil then local tempvar = table.maxn(tComputers['ID'])+1 tComputers['ID'][tempvar] = id3 tComputers['X'][tempvar] = x3 tComputers['Y'][tempvar] = y3 tComputers['Z'][tempvar] = z3 tComputers['IP'][tempvar] = string.sub(var2,1,pos3-1) end distance = coordcalc(x3,y3,z3,x4,y4,z4) return event, id3, string.sub(var2,pos4+1,string.len(var2)),distance,"nodeNet" -- check if it is already known -- regester if unknown -- return the packet with the computers id as var 1 and data asn var2 -- take a vacation you have erned it end end end end else return event, var1, var2, var3, var4, var5 end end end function nodeSender(id12,mes,ip2) --- need to add more safty proticols if id12 == nil or mes == nil then return nil end if ip2 == nil then local value2two = checkFor(id12,tComputers['ID']) if value2two == nil then print("GPS-IP unknown for ID: "..tostring(value2two)) print("Please enter GPS-IP in xxx.xxx.xxx.xxformat") else rednet.send(nid,x.."."..y.."."..z.."."..id.." "..tComputers['IP'][value2two].." "..mes) end else rednet.send(nid,x.."."..y.."."..z.."."..id.." "..ip2.." "..mes) end end while true do local e,e1,e2,e3,e4,e5 = eventOrNode() if e == "char" and e1 == "q" then break end if e == "char" and e1 == "c" then term.clear() term.setCursorPos(1,1) print("opened Console -- You are "..x.."."..y.."."..z.."."..id) inval = io.read() if inval == "mesager" then print("mesager opened") write("Enter ID : ") local idsend = tonumber(io.read()) write("Enter Mseage : ") local message = io.read() print("Enter ip or blank for look up") local gpsiptag = io.read() if gpsiptag == "" then gpsiptag = nil end nodeSender(idsend,message,gpsiptag) end end print(tostring(e).." "..tostring(e1).." "..tostring(e2).." "..tostring(e3).." "..tostring(e4).." "..tostring(e5)) end
nodeFTP ( a command line file transfer application ) 0.24 built on cnode 0.31
Spoiler
nodeFTPver = 0.24 -- alpha -- cnodeVer = 0.31 -- wifi modem test -- local function openRednet() -- local listOfSides = { "top" , "bottom" , "front" , "left" , "right" , "back" } local listOfSides = rs.getSides() local listofPossibles = {} local counter1 = 0 while true do counter1 = counter1 +1 if peripheral.isPresent(tostring(listOfSides[counter1])) and peripheral.getType(listOfSides[counter1]) == "modem" then table.insert(listofPossibles,tostring(listOfSides[counter1])) end if counter1 == 6 and table.maxn(listofPossibles) == 0 then print("no wifi present") return nil end if counter1 == 6 and table.maxn(listofPossibles) ~= 0 then rednet.open(listofPossibles[1]) return listofPossibles[1] end end end modemOn = openRednet() if modemOn == nil then print("No WIFI Modem") print("Will shutdown in 3 seconds") sleep(3) os.shutdown() else print("Opened wifi on "..modemOn.." side") end -- wifi modem test end -- local x,y,z = gps.locate(2) local id = os.getComputerID() local nx , ny , nz , nid local idTable = {} local mTable = {} local ipTable = {} local value = "" local savtoconfig = "y" local function checkFor(this,inhere) local loopn = 0 local maxedn = table.maxn(inhere) while true do if maxedn == loopn then return nil end loopn = loopn+1 if inhere[loopn] == this then return loopn end end end local function coordcalc(i1,i2,i3,v1,v2,v3) if i1 == nil or i2 == nil or i3 == nil or v1 == nil or v2 == nil or v3 ==nil then return nil end local temp = math.sqrt(((i1-v1)^2) + ((i2-v2)^2)) m = math.sqrt(temp^2 + ((i3-v3)^2)) return m end local function stringLocator(acton,looking,stpos,reverse,last) -- added reverse function -- experemental local tempvar = tonumber(stpos) if tempvar == nil then tempvar = 1 end local this = string.byte(looking) local endof = string.len(acton) while true do if last == "p" then print(string.sub(acton,tempvar,tempvar).." "..looking) end if string.byte(acton,tempvar) == this then return tempvar end if tempvar == endof and reverse ~= "r" or tempvar == 1 and reverse == "r" then return end if reverse == "r" then tempvar = tempvar - 1 else tempvar = tempvar + 1 end end end local function decodeIP(pxq) -- this takes a string eg "1001.22030.11.12" and decodes it to 1001 22030 11 12 eatch local tabel = {} local st = tostring(pxq) -- a seprate value to be added to a routing table latter local start = 1 -- start pos of where to look for the charicter "." local loc = 0 -- this tracks where the last . was found so it will look further along local fin = string.len(st) -- this is the end position to look to. local pass = 1 -- when pass = 4 the function will be made to return ( not yet coded ) -- while true do -- break down loop takes string apart local loc = stringLocator(st,".",start) -- finds the closes "." this is where the probblems begin if loc == nil then tabel[pass] = (string.sub(st,start,fin)) else tabel[pass] = (string.sub(st,start,loc-1)) start = loc+1 end if pass == 4 then break end pass = pass + 1 end return tonumber(tabel[1]),tonumber(tabel[2]),tonumber(tabel[3]),tonumber(tabel[4]) end if fs.exists("config") then print("loading config") file = io.open("config","r") x = tonumber(file:read()) y = tonumber(file:read()) z = tonumber(file:read()) file:close() print("config loaded") end if x == nil or y == nil or z == nil then local runagain = true while runagain do term.clear() term.setCursorPos(1,1) print("please enter the X Y Z as auto location failed") print("or type >exit< to end with out the ><") write(" X : ")x = io.read() if x == "exit" then return else x = tonumber(x) end write(" y : ")y = tonumber(io.read()) if y == "exit" then error() else y = tonumber(y) end write(" z : ")z = tonumber(io.read()) if z == "exit" then error() else z = tonumber(z) end if x == nil or y == nil or z == nil then runagain = true else runagain = false end end end if fs.exists("config") == false and savtoconfig == "y" then if x ~= nil and y ~= nil and z ~= nil then print("Config created") file = io.open("config","w") file:write(x.."\n") file:write(y.."\n") file:write(z.."\n") file:write(id.."\n") file:close() end end rednet.broadcast("PING2-- "..x..y..z..id) local timer = os.startTimer(3) while true do local event, var1, var2, var3, var4, var5 = os.pullEventRaw() if event == "timer" then if var1 == timer then local pos = 1 local current = mTable[1] local pos2 = 1 if table.maxn(mTable) <= 0 then print("no nodes in range") break else while true do if mTable[pos] < current then current = mTable[pos] pos2 = pos end if pos == table.maxn(mTable) then break end pos = pos+1 end nid = idTable[pos2] nx,ny,nz = decodeIP(ipTable[pos2]) local timer1 = os.startTimer(90) while true do rednet.send(nid,"REG-COM "..x.."."..y.."."..z.."."..id) event, var1, var2, var3, var4, var5 = os.pullEvent() if string.sub(tostring(var2),1,7) == "REG-RPL" then break end if var1 == timer1 then print("failed to regester") error() end end print("we have regestered to node") print(nx.."."..ny.."."..nz.."."..nid) break end end end if event == "rednet_message" then value = string.sub(var2,1,7) if value == "OPN-NOD" then table.insert(idTable,tonumber(var1)) table.insert(mTable,var3) table.insert(ipTable,string.sub(var2,9,string.len(var2))) end end end local tComputers = {} tComputers['ID'] = {} tComputers['X'] = {} tComputers['Y'] = {} tComputers['Z'] = {} tComputers['IP'] = {} local function eventOrNode() while true do event, var1, var2, var3, var4, var5 = os.pullEventRaw() if event == "rednet_message" then value = string.sub(var2,1,7) if value == "PING2--" or value == "REG-COM" or value == "REG-RPL" or value == "INSTALL" or value == "REG-NOD" or value == "REGNRPL" or value == "S-ALIVE" then else local pos3 = stringLocator(var2," ") if pos3 == nil then return event, var1, var2, var3, var4, var5 else local pos4 = stringLocator(var2," ",pos3+1) if pos4 == nil then return event, var1, var2, var3, var4, var5 else x3,y3,z3,id3 = decodeIP(string.sub(var2,1,pos3-1)) -- sender x4,y4,z4,id4 = decodeIP(string.sub(var2,pos3+1,pos4-1)) -- reciver if x3 == nil or y3 == nil or z3 == nil or id3 == nil or x4 == nil or y4 == nil or z4 == nil or id4 == nil then return event, var1, var2, var3, var4, var5 else local testvar = checkFor(id3,tComputers['ID']) if testvar == nil then local tempvar = table.maxn(tComputers['ID'])+1 tComputers['ID'][tempvar] = id3 tComputers['X'][tempvar] = x3 tComputers['Y'][tempvar] = y3 tComputers['Z'][tempvar] = z3 tComputers['IP'][tempvar] = string.sub(var2,1,pos3-1) end distance = coordcalc(x3,y3,z3,x4,y4,z4) return event, id3, string.sub(var2,pos4+1,string.len(var2)),distance,"nodeNet" -- check if it is already known -- regester if unknown -- return the packet with the computers id as var 1 and data asn var2 -- take a vacation you have erned it end end end end else return event, var1, var2, var3, var4, var5 end end end function nodeSender(id12,mes,ip2) --- need to add more safty proticols if id12 == nil or mes == nil then return nil end if ip2 == nil then local value2two = checkFor(id12,tComputers['ID']) if value2two == nil then print("GPS-IP unknown for ID: "..tostring(value2two)) print("Please enter GPS-IP in xxx.xxx.xxx.xxformat") else rednet.send(nid,x.."."..y.."."..z.."."..id.." "..tComputers['IP'][value2two].." "..mes) end else rednet.send(nid,x.."."..y.."."..z.."."..id.." "..ip2.." "..mes) end end -- end of cnode -- start of program -- local ftpSever = nil local taskrunning = "event" local tempStore = {} local q2 = 0 local mode = "comline" testmode = true -- this turns on and off certin print functions -- function logPrint(...) if mode == "comline" then print(...) end end function uiPrint(...) if mode == "userInterface" then print(...) end end local function makeDir() local sNewDir = shell.resolve("FTP") fs.makeDir(sNewDir) print(tostring(sNewDir)) end while true do local e,e1,e2,e3,e4,e5 = eventOrNode() if e == "char" and e1 == "q" then break end if e == "char" and e1 == "c" then term.clear() term.setCursorPos(1,1) print("ver "..nodeFTPver.." Opened Console for FTP you are: "..x.."."..y.."."..z.."."..id.." "..taskrunning) inval = io.read() if inval == "help" then term.clear() term.setCursorPos(1,1) print("Avalibe Options") print("help - exit - mesager - FTPsever - FTPclient - eON - eOFF") end if inval == "mesager" then print("mesager opened") write("Enter ID : ") local idsend = tonumber(io.read()) write("Enter Mseage : ") local message = io.read() print("Enter ip or blank for look up") local gpsiptag = io.read() if gpsiptag == "" then gpsiptag = nil end nodeSender(idsend,message,gpsiptag) end if inval == "exit" then return "ended" end if inval == "FTPsever" then term.clear() term.setCursorPos(1,1) print("running as FTP server") taskrunning = "ftpsev" end if inval == "FTPclient" then term.clear() term.setCursorPos(1,1) print("running as FTP client") taskrunning = "ftprec" end if inval == "eON" then print("events on") taskrunning = "event" end if inval == "eOFF" then print("events off") taskrunning = "" end if inval == "mk" then makeDir() end if inval == "list" and taskrunning == "ftprec" then print("requesting list") nodeSender(ftpSever,"REQ-DIR") end if inval == "download" then print("what file") info = io.read() nodeSender(ftpSever,"DOWNLOD "..info) end if inval == "upload" then print("please Enter full file location") print("Example /rom/programs/redset") info = io.read() if fs.exists(info)then print("uploading") file = fs.open(info,"r") local sTempfile = file.readAll() file.close() local vlocate = stringLocator(info,"/",string.len(info),"r","p") if vlocate == nil then print("found no / ") nodeSender(ftpSever,"UP-LOAD "..":"..info..":"..sTempfile) else nodeSender(ftpSever,"UP-LOAD "..":"..string.sub(info,vlocate+1,string.len(info))..":"..sTempfile) end print("file uploaded") print(string.sub(info,vlocate+1,string.len(info))) else print("file not found upload aborted") end end end if taskrunning == "event" then print(tostring(e).." "..tostring(e1).." "..tostring(e2).." "..tostring(e3).." "..tostring(e4).." "..tostring(e5)) end if taskrunning == "ftpsev" then --SEVER-- if e4 == "nodeNet" then local tagLine = string.sub(e2,1,7) if tagLine == "REQUEST" then print("Replied to request from: "..e1) nodeSender(e1,"FTP--ON") end if tagLine == "REQ-DIR" then local tFiles = fs.list("FTP") local sThis = "" for n, sItem in pairs(tFiles) do sThis = sThis..sItem.." " end nodeSender(e1,"LISTDIR".." "..sThis) end if tagLine == "DOWNLOD" then print("/FTP/"..string.sub(e2,9,string.len(e2))) if fs.exists("/FTP/"..string.sub(e2,9,string.len(e2))) then file = fs.open("/FTP/"..string.sub(e2,9,string.len(e2)),"r") local sholding = file.readAll() file.close() nodeSender(e1,"FILEDAT "..sholding) print("file sent") sholding = nil else print("failed to send File not found") end end if tagLine == "UP-LOAD" then print(tostring(stringLocator(e2,":",10)-1)) local fileName = string.sub(e2,10,stringLocator(e2,":",10)-1) print("filename: "..fileName) file = fs.open("/FTP/"..fileName,"w") print(tostring(stringLocator(e2,":",10))) print(tostring(string.len(e2))) local sFiles = string.sub(e2,stringLocator(e2,":",10)+1,string.len(e2)) file.write(sFiles) file.close() end end end if taskrunning == "ftprec" then --CLIENT-- if e4 == "nodeNet" then local tagLine = string.sub(e2,1,7) if tagLine == "FTP--ON" then print("FTP server online ID: "..tostring(e1)) ftpSever = e1 end if tagLine == "LISTDIR" then term.clear() term.setCursorPos(1,1) print("recived list") print(string.sub(e2,9,string.len(e2))) end if tagLine == "FILEDAT" then print("reciving file") file = fs.open("/"..info,"w") file.write(string.sub(e2,9,string.len(e2))) file.close() print("download Compleet") end end if ftpSever == nil then print("please Enter GPS-IP for server") invar = io.read() a1,a2,a3,a4 = decodeIP(invar) if a1 == nil or a2 == nil or a3 == nil or a4 == nil then print("IP incorect format") print("please enter it again") else nodeSender(a4,"REQUEST",invar) end end end end