ZNZNCOOP

drouteV2

Jan 11th, 2015
195
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. local gID={} gW={}
  2. local MyID=os.getComputerID()
  3. local MyIP
  4. local maxTTL=15 -- time to life
  5. local TimeRefr=300
  6. local ROUTER_BROADCAST = 65534
  7. local CHANNEL_BROADCAST = 65535
  8. local event,char,dID,sID,mess,t,dIP,sIP
  9. local Version = 'Craftnet ver. 1.2'
  10.  
  11. function AddSPath(path,id)
  12.   local gid=gID gw=gW
  13.   for k in path:gmatch('([_%w]+)%.') do
  14.     write(k..'.')
  15.     if not gid[k] then gid[k]={} gw[k]={}
  16.     elseif type(gid[k])=='number' then
  17.       gid[k]={[0]=gid[k]}
  18.       gw[k]={[0]=gw[k]}
  19.     end
  20.     gid=gid[k] gw=gw[k]
  21.   end
  22.   local k=path:match('([_%w]+)$')
  23.   if id=='self' then
  24.     MyIP=path
  25.     if type(gid[k])=='table' then gid[k][0]=MyID gw[k][0]=0
  26.     else gid[k]={[0]=MyID} gw[k]={[0]=0} end
  27.   else gid[k]=tonumber(id) gw[k]=0 end
  28.   print(k,'=',id)
  29. end
  30.  
  31. function AddDPath(path,id,w)
  32.   path=path..'.'
  33.   w=w+1
  34.   if w<=maxTTL then
  35.   local gid=gID gw=gW
  36.   for k in path:gmatch('([_%w]+)%.') do
  37.     if type(gid[k])=='table' then
  38.       gid=gid[k] gw=gw[k]
  39.     else
  40.       if not gid[k] or gw[k]>w then
  41.         gid[k]=id
  42.         gw[k]=w
  43.       end
  44.       return
  45.     end
  46.   end
  47.   end
  48. end
  49.  
  50. function loadTable(filename)
  51.   MyIP=''
  52.   MyID=os.getComputerID()
  53.   gID={} gW={}
  54.   local file=fs.open(filename,'r')
  55.   if not file then
  56.     print('File '..filename)
  57.     AddSPath(tostring(MyID),'self') return
  58.   end
  59.   local line=file.readLine()
  60.   while line do
  61.     local path,id=line:match('^%s-([_%w%.]+)%s+(%w+)')
  62.     if path then AddSPath(path,id) end
  63.     line=file.readLine()
  64.   end
  65.   file.close()
  66.   if MyIP=='' then MyIP=tostring(MyID) end
  67. end
  68.  
  69. function aging(gid,gw)
  70.   gid=gid or gID gw=gw or gW
  71.   for k,v in pairs(gw) do
  72.     if type(v)=='table' then aging(gid[k],gw[k])
  73.     else
  74.       if v>0 then
  75.         gw[k]=v+1
  76.         if gw[k]>maxTTL then
  77.           gid[k]=nil
  78.           gw[k]=nil
  79.           return
  80.         end
  81.       end
  82.     end
  83.   end
  84. end
  85.  
  86. function trace(ip)
  87.   if ip=='*' then return MyID end
  88.   ip=(ip or '')..'.'
  89.   local t=gID
  90.   for k in ip:gmatch('([_%w]+)%.') do
  91.     if not t[k] then return tonumber(k) end
  92.     if type(t[k])=='table' then t=t[k]
  93.     else return t[k] end
  94.   end
  95.   return t[0]
  96. end
  97.  
  98. function showTab(tab,addr)
  99.   for k,v in pairs(tab) do
  100.     if type(v)=='table' then
  101.       showTab(v,(addr or '')..k..'.')
  102.     else
  103.       print((addr or '')..k..'=',v)
  104.     end
  105.   end
  106. end
  107.  
  108. function open()
  109.     for n,sSide in ipairs( rs.getSides() ) do
  110.         if peripheral.getType( sSide )=='modem' then
  111.           peripheral.call( sSide, "open", MyID )
  112.           peripheral.call( sSide, "open", CHANNEL_BROADCAST )
  113.           peripheral.call( sSide, "open", ROUTER_BROADCAST )
  114.           return true
  115.         end
  116.     end
  117.     return false
  118. end
  119.  
  120. function TabToStr(tab,addr)
  121. addr=addr or ''
  122. local str=''
  123.   for k,v in pairs(tab) do
  124.     if type(v)=='table' then
  125.       if v[0] then
  126.         str=str..addr..k..'='..v[0]..'&'
  127.       else
  128.         str=str..TabToStr(v,addr..k..'.')
  129.       end
  130.     else
  131.       str=str..addr..k..'='..v..'&'
  132.     end
  133.   end
  134.   return str
  135. end
  136.  
  137. local refr
  138. function Refresh()
  139.   rednet.send(ROUTER_BROADCAST,TabToStr(gW))
  140.   refr=os.startTimer(TimeRefr)
  141. end
  142.  
  143. function send(dAddr,mess)
  144.   --dID=trace(dAddr)
  145.   if dID then rednet.send(sID,'T='..maxTTL..'|D='..dAddr..'|S='..MyIP..'|'..mess) end
  146. end
  147.  
  148. function findName(id,tab)
  149.   tab=tab or gID
  150.   for k,v in pairs(tab) do
  151.     if v==id then return k end
  152.     if type(v)=='table' then
  153.       local res=findName(id,v)
  154.       if res then return k..'.'..res end
  155.     end
  156.   end
  157. end
  158.  
  159. local commands={}
  160. commands.getip=function()
  161.     send(findName(sID) or MyIP..'.'..sID,'setip')
  162. end
  163.  
  164. commands.ping=function()
  165.     send(sIP,'pong')
  166. end
  167.  
  168. commands.ver=function()
  169.     send(sIP,Version)
  170. end
  171.  
  172. commands.addpath=function(param)
  173.     print('Adding the path')
  174.     for path,id in pairs(param) do
  175.       AddSPath(path,id)
  176.       print(path,'=',id)
  177.     end
  178.     send(sIP,'Ok')
  179. end
  180.  
  181. commands.reload=function()
  182.   if not http then
  183.     send(sIP,'Requires http API')
  184.     return
  185.   end
  186.   local response = http.get("http://pastebin.com/raw.php?i=gHBkt6gj")
  187.   if response then
  188.     local sFile = shell.getRunningProgram()
  189.     local file = fs.open( sFile, "w" )
  190.     file.write( response.readAll() )
  191.     file.close()
  192.     response.close()
  193.     send(sIP,'Downloaded as '..sFile)
  194.     os.reboot()
  195.   else
  196.     send(sIP,'Failed.')
  197.   end  
  198. end
  199.  
  200. if not open() then
  201.   print('Modem is not found')
  202.   return
  203. end
  204.  
  205. loadTable('rtable')
  206. --Refresh()
  207. refr=os.startTimer(math.random(TimeRefr))
  208. while true do
  209.   event,char, dID , sID, mess=os.pullEvent()
  210.   if event=='char' then
  211.     if char=='i' then print('gID=') showTab(gID) end
  212.     if char=='w' then print('gW=') showTab(gW) end
  213.     if char=='q' then return end
  214.   elseif event=='modem_message' then
  215.     if dID==MyID then
  216.       t,dIP,sIP,mess=string.match(mess['message'],'^T=(%d+)|D=([_%w%.]+)|S=([_%w%.]+)|(.*)')
  217.       t=tonumber(t)
  218.       if t then
  219.         dID=trace(dIP)
  220.         if dID then
  221.           if dID==MyID then
  222.             local command=mess:match('%w+')
  223.             if commands[command] then
  224.               local params={}
  225.               for k,v in mess:gmatch('([^%s]+)=([^%s]+)') do params[k]=v end
  226.               commands[command](params)
  227.             end
  228.           else
  229.             if t>0 then
  230.               if t>maxTTL then t=maxTTL end
  231.               t=t-1
  232.               rednet.send(dID,'T='..t ..'|D='..dIP..'|S='..sIP..'|'..mess)
  233.             else
  234.               send(sIP,'TTL ower')
  235.             end
  236.           end
  237.         else
  238.             send(sIP,'Adress '..dIP..' is unreachable')
  239.         end
  240.       end
  241.     end
  242.     if dID==ROUTER_BROADCAST and sID~=MyID then
  243.       for path,w in mess:gmatch('([_%w%.]+)=(%d+)&') do
  244.         AddDPath(path,sID,w)
  245.       end
  246.     end
  247.     if dID==CHANNEL_BROADCAST then
  248.       t,dIP=string.match(mess['message'],'^T=(%d+)|D=([_%*%w%.]+)|S=%*|getip')
  249.       if t then
  250.         dID=trace(dIP)
  251.         if dID==MyID then commands.getip() end
  252.       end
  253.     end
  254.   elseif event=='timer' and char==refr then
  255.     Refresh()
  256.     aging()
  257.   end
  258. end
RAW Paste Data