
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
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.
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..
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