ProgramCrafter

th_interfaces-v0.0.1

Mar 17th, 2021 (edited)
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.14 KB | None | 0 0
  1. -- ThunderNet - network interfaces.
  2. -- (c) ProgramCrafter
  3.  
  4. -- Last patch: Stem support (06.04.2021)
  5.  
  6. local function err(msg)
  7.   return function() error(msg) end
  8. end
  9.  
  10. local NYIMSG = 'Not yet implemented'
  11. local NULLMSG = 'Receiving data from /dev/null'
  12. local NULLADDR = '00000000-0000-0000-0000-000000000000'
  13.  
  14. local evt = require 'event'
  15.  
  16. -- Event callbacks (`parsers`)
  17. -- Input:     event
  18. -- Output:    thundernet::data, answer_info (such as network card address)
  19.  
  20. local function parse_null(proxy)
  21.   return function(event) end
  22. end
  23. local function parse_modem(proxy)
  24.   -- Use this function only to create MODEM parsers!
  25.   -- TUNNEL parsers are below in parse_tunnel.
  26.   return function(event)
  27.     -- Event format: modem_message(receiverAddress: string, senderAddress: string, port: number, distance: number, ...)
  28.     if not event then return end
  29.     if event[1] ~= 'modem_message' then return end
  30.     if event[2] ~= proxy.address then return end
  31.     if event[6] then
  32.       return event[6], event[3]
  33.     end
  34.   end
  35. end
  36. local function parse_tunnel(proxy)
  37.   return function(event)
  38.     -- Event format: modem_message(receiverAddress: string, senderAddress: string, port: number, distance: number, ...)
  39.     if not event then return end
  40.     if event[1] ~= 'modem_message' then return end
  41.     if event[2] ~= proxy.address then return end
  42.     if event[6] then
  43.       return event[6], event[3]
  44.     end
  45.   end
  46. end
  47.  
  48. local stem_inited = false
  49.  
  50. return {
  51.   ['null'] = function() return {
  52.     send = function() end,      broadcast = function() end,
  53.     recv = parse_null(),        addr = NULLADDR
  54.   } end,
  55.  
  56.   ['modem'] = function(proxy) return {
  57.     send = proxy.send,          broadcast = proxy.broadcast,
  58.     recv = parse_modem(proxy),  addr = proxy.address
  59.   } end,
  60.  
  61.   ['tunnel'] = function(proxy) return {
  62.     send = err(NYIMSG),         broadcast = err(NYIMSG),
  63.     recv = parse_tunnel(proxy), addr = proxy.address
  64.   } end,
  65.  
  66.   ['internet'] = function(proxy, uid)
  67.     local stem_installed, stem = pcall(require, 'stem')
  68.     local stem_channel = 'thunderlib~06042021161759~'
  69.     if stem_inited or not stem_installed then
  70.       if not stem_installed then
  71.         print('[Thunderlib interfaces] Install Stem library for connecting to Internet.')
  72.       end
  73.       return {send = parse_null(), broadcast = parse_null(),
  74.               recv = parse_null(), addr = proxy.address}
  75.     else
  76.       stem_inited = true
  77.       local server = stem.connect()
  78.       server:subscribe(stem_channel)
  79.       return {
  80.         send = function(addr, port, msg)
  81.           server:send(stem_channel, uid .. 'D' .. addr .. '\0' .. msg)
  82.         end,
  83.         broadcast = function(port, msg)
  84.           server:send(stem_channel, uid .. 'B' .. msg)
  85.         end,
  86.         recv = function(event)
  87.           if not event then return end
  88.           if event[1] == 'stem_message' then
  89.             local d = event[3]
  90.            
  91.             local sender = d:sub(1, #uid)
  92.             local _type = d:sub(#uid + 1, #uid + 1)
  93.             if d:sub(#uid + 1, #uid + 1) == 'B' then
  94.               return d:sub(#uid + 2), sender
  95.             end
  96.            
  97.             if d:sub(#uid + 2, #uid * 2 + 1) ~= uid then return end
  98.             return d:sub(#uid * 2 + 2), sender
  99.           end
  100.         end,
  101.         stop = function() server:disconnect() end,
  102.         addr = proxy.address
  103.       }
  104.     end
  105.   end,
  106.  
  107.   ['combine'] = function(connections)
  108.     return {
  109.       send = function(routes, addr, ...)
  110.         if not routes[addr] then return false end
  111.         return routes[addr][1].send(routes[addr][2], ...)
  112.       end,
  113.       broadcast = function(...)
  114.         for _, connection in pairs(connections) do
  115.           connection.broadcast(...)
  116.         end
  117.       end,
  118.       recv = function(is_timeout)
  119.         is_timeout = is_timeout or function() end
  120.         while not is_timeout() do
  121.           local e = {evt.pull(0.05)}
  122.           if e[1] then
  123.             for _, connection in pairs(connections) do
  124.               local flag, info = connection.recv(e)
  125.               if flag then return {connection, info}, flag end
  126.             end
  127.           end
  128.         end
  129.       end
  130.     }
  131.   end
  132. }
Add Comment
Please, Sign In to add comment