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

[Dead Project] [ver=ALPHA]GPS based IP relay System "GP-IS"(working Internet in minecraft)

Started by BigSHinyToys, 19 March 2012 - 03:46 PM
BigSHinyToys #1
Posted 19 March 2012 - 04:46 PM

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
Spoileris 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 use

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

SpoilerThere 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 ?
Spoilerthat 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.

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
BigSHinyToys #2
Posted 21 March 2012 - 08:12 PM
I have fixed some major bugs

fixes
- client side computers "cmprec" no longer cause node crash from broadcasting
- stability major improved adjusted sleep timers ( still needs refinement )
- actually works properly now ( this was a big bug :(/>/> )

added
- nodes now will try a different node it it receives no confirmation. and will remove it from routing table.
- nodes log every rednet event to a log table ( this will be saved to file in a latter ver for error testing )
- nodes will display all connected computers by pressing t and all avalible nodes by pressing y alos all packets by pressign u and finally all loged events by pressing r


feel free to try the new alphas they are almost read to go full ver.

A few reasons to try it.
- Security it is impossible to collect your data off the air.
- it is impossible to spoof being another computer successful
- prefect for SMP ( maybe i a few vers time )





Big Shiny Toys

UPDATE SUN March 24th 2012 4:41 AM


First Message send from node to cnode then new client interface.
cnode will feature a function that works exactly like os.pullEvent() but it will decore the destination IP and return only the ID of the snender the Data the distance ( as you see it is future than 65 block limmit ) and finaly return nodeNet as a fifth value. all other rednet messages will be returned as is and all other events will work as before. I am close to a full release and after adding a nodeSend function should be ready. if not this weekend then next (Very bussy this week)


Big Shiny Toys
BigSHinyToys #3
Posted 28 March 2012 - 03:41 PM
- snip -
Liraal #4
Posted 28 March 2012 - 03:43 PM
add
Spoilertags to make reading it easier.
Ian-Moone #5
Posted 28 March 2012 - 09:07 PM
looking good ill keep my eye on this
tommyroyall #6
Posted 30 March 2012 - 01:41 AM
Nice man. I can just imagine setting a GPS tower up in my village and using a packet based mesh networking system to link it up to another village.
Jojo.bacon #7
Posted 02 April 2012 - 09:52 PM
I think that this is a great system, but it should be able to route regular rednet messages whithout too much setup on the client computer. That way programs that use regular rednet will be compatible. Maybe you could use a program that would register the client with the node when you run it.
BigSHinyToys #8
Posted 03 April 2012 - 08:02 AM
I think that this is a great system, but it should be able to route regular rednet messages whithout too much setup on the client computer. That way programs that use regular rednet will be compatible. Maybe you could use a program that would register the client with the node when you run it.
cnode the Client side node package does register all IP that send data to it. so for s sever it will always be able to reply to incoming message. as for the user side they would need to enter an address ounce and it will be stored. after an address is stored it can be referenced by its ID as the computer knows its address. this is to help with backwards compatibility with other software systems. But I would still need to tailor the system for each program as there is a lot more node can offer. for example to authenticate a user that is login on you could compare the GSP IP tag with the one they used last and if different refuse connection. or ignore packets from users that are not logged in.

I am currently working on some end user applications that use node I have a very basic FTP sever/client set up. it is currently command line operated.

New vers released.
ChunLing #9
Posted 15 October 2012 - 05:42 PM
I was working on a rednet forwarding host to replace the standard gps host program. It has some functionality that you might find useful. Right now it just allows the node running it to respond to a couple of messages other than "PING", but the code is written so that you can easily expand the variety of messages it can take. And the basic forwarding method itself could be useful for setting up stable communication over a distance.
Spoiler

local tArgs = { ... }
function opnmdm()
for i,v in pairs(rs.getSides()) do
  if peripheral.getType(v) == "modem" then
   if not rednet.isOpen(v) then rednet.open(v) end
  return true end
end
return false end
hstfnc = { --the functions in this table can be called directly by rednet messages, i.e. "PING"
PING = function() rednet.send(sndr,textutils.serialize({xPos,yPos,zPos})) end,
FINDHOSTS = function() --currently this function doesn't work as well as I'd hoped
local ndx,hstlst = 0,{}
rednet.broadcast("PING")
repeat ndx = ndx+1
  hstlst[ndx] = {rednet.receive(2)}
until not hstlst[ndx][1]
sleep(0.1)
print(textutils.serialize(hstlst))
rednet.send(sndr,textutils.serialize(hstlst))
end,
DROP = function() -- drops the relay of messages to/from the sender
local rID = rlylst[sndr]
rlylst[sndr],rlylst[rID] = nil
local hndl = fs.open("rlylst","w")
hndl.write(textutils.serialize(rlylst)) hndl.close()
sleep(0.1)
rednet.send(sndr,"Relay to ID"..rID.." dropped")
rednet.send(rID,"Relay to ID"..sndr.." dropped")
end,
}
if opnmdm() then
xPos,yPos,zPos = gps.locate(2,true )
if tArgs[1] == "host" then
  if not xPos then xPos,yPos,zPos = tArgs[2],tArgs[3],tArgs[4]
   local itr8 = 0
   while not (xPos and yPos and zPos) do
	write("Enter x coordinate :") xPos = tonumber(read())
	write("Enter y coordinate :") yPos = tonumber(read())
	write("Enter z coordinate :") zPos = tonumber(read())
   end itr8 = itr8+1
   if itr8 > 3 then print("Invalid input") return false end
  end
  print("GPS/Relay Node position "..xPos..","..yPos..","..zPos)
  local hndl,hstID = fs.open("startup","w"),os.computerID()
  hndl.writeLine("shell.run(\"rnhst\",\"host\","..xPos..","..yPos..","..zPos..")") hndl.close()
  if fs.exists("rlylst") then local hndl = fs.open("rlylst","r")
   rlylst = textutils.unserialize(hndl.readAll()) hndl.close()
  else rlylst = {} end
  repeat sndr,mssg,dstnc = rednet.receive()
   if hstfnc[mssg] then hstfnc[mssg]()
   elseif rlylst[sndr] then
	if rlylst[sndr] == hstID then rednet.broadcast(mssg)
	else rednet.send(rlylst[sndr],mssg) end
   elseif mssg:find("^RELAY:%d+") then
	rID = tonumber(mssg:sub(mssg:find("%d+")))
	rlylst[sndr],rlylst[rID] = rID,sndr
	local hndl = fs.open("rlylst","w")
	hndl.write(textutils.serialize(rlylst)) hndl.close()
	sleep(0.1)
	rednet.send(sndr,"Relaying to ID"..rlylst[sndr])
   elseif rlylst[hstID] then rednet.send(rlylst[hstID],mssg) end
  until false
return true end
else print("could not open modem") return false
end
The key functionality is defined for messages that take the form of ("RELAY:"..ID), where ID is a number ID for the computer that will receive relays of further messages from the sender. Once a relay has been successfully started in host mode (arguments are the same as for gps host setup), it writes a startup file so that it will restart with the same position information. A separate file is used to track the current forwarding table.

FINDHOSTS doesn't work reliably, the table of available node data gathered is printed out on the node terminal but doesn't get sent back to the requesting terminal in a timely fashion. This can probably be corrected by shortening the timeout for collecting node responses to it's PING, but may or may not affect quality of the host information gathered. It should also be solved by just having the requesting terminal wait longer for an answer. Which solution is better for your needs is up to you, I think.

You can define any number of other functions that will be called by a specific rednet string, simply adding them to hstfnc{}, as long as they do not require information other than the global variables defined in the program (all the information from the rednet message calling the function is available this way, though the message itself is already used to identify the function, so you only have the sender ID and the distance).

While the relay function currently only accepts one to one connections (a two-way relay between two computers) and a broadcast mode (accessed by setting the node ID as the relay value), it can be modified with relative ease by using a second layer table to hold multiple forwards for each ID. But that introduced a difficulty deciding whether to try to relay or execute "RELAY:ID" commands, so I just dropped it. But I guess the second table could be indexed by the ID and contain a value specifing the type of recipient, i.e. whether it was a relay node or not. But the IP address idea seems like it would also be a good way to solve that question.

Sorry, I fell asleep while posting.
Sebra #10
Posted 15 October 2012 - 07:12 PM
Shouldn't you define "sndr" at the top of program?
Other vars probably should be defined upper, then first read too.
ChunLing #11
Posted 15 October 2012 - 08:30 PM
Lua allows you to define global variables anywhere. Some people find this inconvenient, I sometimes think it is a bit obscure myself. But the logic is clear, it makes the language inherently very robust. So the answer is no, you shouldn't define global variables before you need them, but you also need to be careful not to use global variables by accident.

Which I haven't, as far as I know.
BigSHinyToys #12
Posted 16 October 2012 - 05:26 AM
This was one of my first programs and as such is incredibly badly coded. I am working on a new implementation of the basic GPS bases packet routing system as of yet there is no fixed date for its release. but seeing your interest in the my program here is a preview.
http://pastebin.com/fUrCNDUK

This shows netALPHA in a practical demonstration with a turtle allowing all turtles to both be receivers and transmitters making any turtle in range of one other connected into the network. also it has a hop embedded in the packet header table. As you can see it is far from completion.
ChunLing #13
Posted 16 October 2012 - 08:21 PM
I favor an approach of having the turtle/host side programming be very simple, but passing enough information back to the controller to allow it to tell everything it needs to know. For instance, the clfn remote control program goes ahead and sends back the result of any turtle API command you pass it, so you know whether or not the movement succeeded, how many items you sucked up, etc. There is also a gps location command, so the turtle tells the controller where it is (or that it can't tell where it is). If a move fails, then you can have the computer send the rctfncs command (like dfd), which will either work or give more specific feedback on why the turtle can't move ("unbreakable block in path", "Out of fuel", or "persistent impediment"). From that information the central controller can track the "inertial" location of the turtle if necessary.

I hope to apply the same kind of principle to the relay hosts, so that they are basically controlled by just a few simple commands over rednet.

Then it is just a matter of controlling the central computer to do something with all those turtles and hosts. Which is the hard (or fun, I guess it depends on perspective) part. The key is making sure that the turtles and relays can give all the useful feedback the central controller really needs.

I rather like the physical address idea, though given that the central computer can get all the locations of any relay or turtle it is in contact with, it can probably work out the best communication rout itself.
BigSHinyToys #14
Posted 17 October 2012 - 12:56 PM
I favor an approach of having the turtle/host side programming be very simple, but passing enough information back to the controller to allow it to tell everything it needs to know. For instance, the clfn remote control program goes ahead and sends back the result of any turtle API command you pass it, so you know whether or not the movement succeeded, how many items you sucked up, etc. There is also a gps location command, so the turtle tells the controller where it is (or that it can't tell where it is). If a move fails, then you can have the computer send the rctfncs command (like dfd), which will either work or give more specific feedback on why the turtle can't move ("unbreakable block in path", "Out of fuel", or "persistent impediment"). From that information the central controller can track the "inertial" location of the turtle if necessary.

I hope to apply the same kind of principle to the relay hosts, so that they are basically controlled by just a few simple commands over rednet.

Then it is just a matter of controlling the central computer to do something with all those turtles and hosts. Which is the hard (or fun, I guess it depends on perspective) part. The key is making sure that the turtles and relays can give all the useful feedback the central controller really needs.

I rather like the physical address idea, though given that the central computer can get all the locations of any relay or turtle it is in contact with, it can probably work out the best communication rout itself.

I have been working form a different prospective of making each node / repeater its own platform and creating a meshnet where all computers / turtles run the same program in the background. this eliminates the bottleneck at the one central computer and also loaded chunk problems. but mine was designed to one day be part of a turtle army / swarm. where I would not be interacting with the system at all and it would need to finds its own way. The GPS IP system is something that i came up with to make routing of packets easer as you could use math to work out the real shortest route. I think it could have real world applications in smart phone meshnets.
brett122798 #15
Posted 17 October 2012 - 04:04 PM
Abandoned? Seemed like a good idea..
BigSHinyToys #16
Posted 17 October 2012 - 04:19 PM
Abandoned? Seemed like a good idea..
GP - IS is abandoned the idea of using GPS coordinates as a IP address is not I will be releasing a new better system based on that idea called netALPHA it is built into TAMS witch I posted above. I have no fixed release date for it as of yet.

GPS based IP routing is not a propriety system If you or anyone else would like to make your own packet routing system using that concept please do Information wants to be free.
ChunLing #17
Posted 17 October 2012 - 05:07 PM
For now I'll probably be sticking to what is useful in the area of world chunks loaded around the player (me) when I'm at my central terminal. The idea of a fully automated swarm seems fun but too potentially damaging…maybe one day I'll unleash one on an isolated area a few kilometers from my base.
BigSHinyToys #18
Posted 17 October 2012 - 06:25 PM
If swarms are ever created they would be quite the persistent and dangerous Nemesis testing them in another world would be a much safer option and building in a rednet "kill" command just in case.
Sebra #19
Posted 17 October 2012 - 07:22 PM
Lua allows you to define global variables anywhere. Some people find this inconvenient, I sometimes think it is a bit obscure myself. But the logic is clear, it makes the language inherently very robust. So the answer is no, you shouldn't define global variables before you need them, but you also need to be careful not to use global variables by accident.

Which I haven't, as far as I know.
Try it, please. :D/>/>
Imho you still need to write or define above first read.
I think that leads to "no sender id for too early defined functions".
ChunLing #20
Posted 17 October 2012 - 08:37 PM
Oh, I'm already running this code on all the gps hosts in my main game world.

The only "problem" is that after you exit the host you can still access the global variables, so someone can get themselves up to my GPS array, terminate the relay program, and then use lua to access the tables holding the relay information or the variables holding information from the last message received. But they can get the relay information from the stored file anyway, and the variables only hold the last message processed…which might be a vital bit of intel, I admit.
Creator #21
Posted 27 January 2015 - 05:26 PM
Hi,

I love your idea. I would like to help you very much. I am not extremely advanced in lua but I can do some programming. Check out my pastebin account. I have iploaded some programs, but not all of them. I am working on something simmilar, but then I came accross your post and thought it is awonderful idea. Contact if you wish me to help you.

You are right, bbut you can always encrypt the messages. This is the link to a encryption API. I didn't do it myself, but I couldn't find it to provide you with the oroginal link.
Edited on 27 January 2015 - 04:23 PM