Thank you tomass1996 it works now.
node program form GP-IP ver ALPHA 0.2 – ignore the fact is says o.1 in the code havent released it yet.
When you run it near GPS servers (at least 4) it will automatically create a startup program and a config file. must be in computers root.
Spoiler
--[[
-- 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
]]--
nodeVer = 0.1
if fs.exists("startup") == false then
print("installing startup")
local tempStore = {}
local q2 = 0
local file = io.open("node","r")
while true do
q2 = q2+1
tempStore[q2] = file:read()
if q2 == 27 then break end
end
file:close()
local file = io.open( "startup", "w" )
q2 = 1
while true do
q2 = q2+1
file:write(tempStore[q2].."n")
if q2 == 27 then break end
end
file:close()
print("rebooting")
sleep(2)
os.reboot()
end
local x,y,z
rednet.open("top")
if fs.exists("config") then
print("loading config")
file = io.open("config","r")
x = 0
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)
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 error()
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
-- save config
if fs.exists("config") == false 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:close()
end
end
testmod = true -- this turns on and off certin print functions --
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
print("closing down")
sleep(3)
term.clear()
term.setCursorPos(1,1)
return"exit"
end
if event == "timer" then
if var1 == nextAlam then
print("refreshing nodes list")
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
print("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
table.insert(loger,"r-net mess from "..var1.." contence "..var2)
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
print("regstering computer")
local x4,y4,z4,id4 = decodeIP(string.sub(var2,9,string.len(var2)))
if checkFor(id4,computersID) == nil then
print(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
print("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
print("reciving reply")
local x4,y4,z4,id4 = decodeIP(string.sub(var2,9,string.len(var2)))
if checkFor(id4,computersID) == nil then
print(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
print("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()
print(tempvar)
print("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
print("regstering Node")
x6,y6,z6,id6 = decodeIP(string.sub(var2,9,string.len(var2)))
if checkFor(id6,nodesID) == nil then
print(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
print("node already reged")
end
print("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
print("node replyed to reg")
x6,y6,z6,id6 = decodeIP(string.sub(var2,9,string.len(var2)))
if checkFor(id6,nodesID) == nil then
print(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
print("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
print(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 then
print("Network error 05 - Packet not corect format")
else
if testmod == true then -- TEST FLAG
print(payload)
print("from: "..x1.." "..y1.." "..z1.." "..id1)
print("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
print("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
print("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)
print (nodesID[loopz].." is meters : "..tp5)
if bestM == nil then
bestM = tp5
sendID = nodesID[loopz]
else
if bestM > tp5 then
bestM = tp5
sendID = nodesID[loopz]
print("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
print("sending to nil ")
end
sendID = math.ceil(sendID)
rednet.send(sendID,var2)
print("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()))
print("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"
print("sending to node : "..nodesID[test])
rednet.send(tonumber(var1),"S-ALIVE "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID()))
print("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)
print("sending to comp : "..computersID[test])
rednet.send(tonumber(var1)+1-1,"S-ALIVE "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID()))
print("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
print("end of Computer table")
break
end
loops = loops +1
print("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
print("end of Nodes table")
break
end
loops = loops +1
print("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
print("end of packets")
break
end
loops = loops +1
print("entry "..loops.." : "..packetsID[loops].." : "..tostring(packetsTM[loops]).." : "..packetsD[loops])
end
end
if var1 == "r" then
loops = 0
term.clear()
term.setCursorPos(1,1)
print("This is Node ver"..tostring(nodeVer).." : "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID()))
while true do
if loops == table.maxn(loger) then
print("end of log")
break
end
loops = loops +1
print("entry "..loops.." : "..loger[loops])
end
end
end -- end of char events
end