Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local gID={} gW={}
- local MyID=os.getComputerID()
- local MyIP
- local maxTTL=15 -- time to life
- local TimeRefr=300
- local ROUTER_BROADCAST = 65534
- local CHANNEL_BROADCAST = 65535
- local event,char,dID,sID,mess,t,dIP,sIP
- local Version = 'Craftnet ver. 1.2'
- function AddSPath(path,id)
- local gid=gID gw=gW
- for k in path:gmatch('([_%w]+)%.') do
- write(k..'.')
- if not gid[k] then gid[k]={} gw[k]={}
- elseif type(gid[k])=='number' then
- gid[k]={[0]=gid[k]}
- gw[k]={[0]=gw[k]}
- end
- gid=gid[k] gw=gw[k]
- end
- local k=path:match('([_%w]+)$')
- if id=='self' then
- MyIP=path
- if type(gid[k])=='table' then gid[k][0]=MyID gw[k][0]=0
- else gid[k]={[0]=MyID} gw[k]={[0]=0} end
- else gid[k]=tonumber(id) gw[k]=0 end
- print(k,'=',id)
- end
- function AddDPath(path,id,w)
- path=path..'.'
- w=w+1
- if w<=maxTTL then
- local gid=gID gw=gW
- for k in path:gmatch('([_%w]+)%.') do
- if type(gid[k])=='table' then
- gid=gid[k] gw=gw[k]
- else
- if not gid[k] or gw[k]>w then
- gid[k]=id
- gw[k]=w
- end
- return
- end
- end
- end
- end
- function loadTable(filename)
- MyIP=''
- MyID=os.getComputerID()
- gID={} gW={}
- local file=fs.open(filename,'r')
- if not file then
- print('File '..filename)
- AddSPath(tostring(MyID),'self') return
- end
- local line=file.readLine()
- while line do
- local path,id=line:match('^%s-([_%w%.]+)%s+(%w+)')
- if path then AddSPath(path,id) end
- line=file.readLine()
- end
- file.close()
- if MyIP=='' then MyIP=tostring(MyID) end
- end
- function aging(gid,gw)
- gid=gid or gID gw=gw or gW
- for k,v in pairs(gw) do
- if type(v)=='table' then aging(gid[k],gw[k])
- else
- if v>0 then
- gw[k]=v+1
- if gw[k]>maxTTL then
- gid[k]=nil
- gw[k]=nil
- return
- end
- end
- end
- end
- end
- function trace(ip)
- if ip=='*' then return MyID end
- ip=(ip or '')..'.'
- local t=gID
- for k in ip:gmatch('([_%w]+)%.') do
- if not t[k] then return tonumber(k) end
- if type(t[k])=='table' then t=t[k]
- else return t[k] end
- end
- return t[0]
- end
- function showTab(tab,addr)
- for k,v in pairs(tab) do
- if type(v)=='table' then
- showTab(v,(addr or '')..k..'.')
- else
- print((addr or '')..k..'=',v)
- end
- end
- end
- function open()
- for n,sSide in ipairs( rs.getSides() ) do
- if peripheral.getType( sSide )=='modem' then
- peripheral.call( sSide, "open", MyID )
- peripheral.call( sSide, "open", CHANNEL_BROADCAST )
- peripheral.call( sSide, "open", ROUTER_BROADCAST )
- return true
- end
- end
- return false
- end
- function TabToStr(tab,addr)
- addr=addr or ''
- local str=''
- for k,v in pairs(tab) do
- if type(v)=='table' then
- if v[0] then
- str=str..addr..k..'='..v[0]..'&'
- else
- str=str..TabToStr(v,addr..k..'.')
- end
- else
- str=str..addr..k..'='..v..'&'
- end
- end
- return str
- end
- local refr
- function Refresh()
- rednet.send(ROUTER_BROADCAST,TabToStr(gW))
- refr=os.startTimer(TimeRefr)
- end
- function send(dAddr,mess)
- --dID=trace(dAddr)
- if dID then rednet.send(sID,'T='..maxTTL..'|D='..dAddr..'|S='..MyIP..'|'..mess) end
- end
- function findName(id,tab)
- tab=tab or gID
- for k,v in pairs(tab) do
- if v==id then return k end
- if type(v)=='table' then
- local res=findName(id,v)
- if res then return k..'.'..res end
- end
- end
- end
- local commands={}
- commands.getip=function()
- send(findName(sID) or MyIP..'.'..sID,'setip')
- end
- commands.ping=function()
- send(sIP,'pong')
- end
- commands.ver=function()
- send(sIP,Version)
- end
- commands.addpath=function(param)
- print('Adding the path')
- for path,id in pairs(param) do
- AddSPath(path,id)
- print(path,'=',id)
- end
- send(sIP,'Ok')
- end
- commands.reload=function()
- if not http then
- send(sIP,'Requires http API')
- return
- end
- local response = http.get("http://pastebin.com/raw.php?i=gHBkt6gj")
- if response then
- local sFile = shell.getRunningProgram()
- local file = fs.open( sFile, "w" )
- file.write( response.readAll() )
- file.close()
- response.close()
- send(sIP,'Downloaded as '..sFile)
- os.reboot()
- else
- send(sIP,'Failed.')
- end
- end
- if not open() then
- print('Modem is not found')
- return
- end
- loadTable('rtable')
- --Refresh()
- refr=os.startTimer(math.random(TimeRefr))
- while true do
- event,char, dID , sID, mess=os.pullEvent()
- if event=='char' then
- if char=='i' then print('gID=') showTab(gID) end
- if char=='w' then print('gW=') showTab(gW) end
- if char=='q' then return end
- elseif event=='modem_message' then
- if dID==MyID then
- t,dIP,sIP,mess=string.match(mess['message'],'^T=(%d+)|D=([_%w%.]+)|S=([_%w%.]+)|(.*)')
- t=tonumber(t)
- if t then
- dID=trace(dIP)
- if dID then
- if dID==MyID then
- local command=mess:match('%w+')
- if commands[command] then
- local params={}
- for k,v in mess:gmatch('([^%s]+)=([^%s]+)') do params[k]=v end
- commands[command](params)
- end
- else
- if t>0 then
- if t>maxTTL then t=maxTTL end
- t=t-1
- rednet.send(dID,'T='..t ..'|D='..dIP..'|S='..sIP..'|'..mess)
- else
- send(sIP,'TTL ower')
- end
- end
- else
- send(sIP,'Adress '..dIP..' is unreachable')
- end
- end
- end
- if dID==ROUTER_BROADCAST and sID~=MyID then
- for path,w in mess:gmatch('([_%w%.]+)=(%d+)&') do
- AddDPath(path,sID,w)
- end
- end
- if dID==CHANNEL_BROADCAST then
- t,dIP=string.match(mess['message'],'^T=(%d+)|D=([_%*%w%.]+)|S=%*|getip')
- if t then
- dID=trace(dIP)
- if dID==MyID then commands.getip() end
- end
- end
- elseif event=='timer' and char==refr then
- Refresh()
- aging()
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement