Advertisement
Alakazard12

GlassMon Client

Feb 18th, 2017
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.75 KB | None | 0 0
  1. local CHANNEL_GLASS = 10033
  2.  
  3. local modem = peripheral.find("modem", function(_, t) return t.isWireless() end)
  4. if not modem then
  5.     printError("no modem attached")
  6.     return
  7. end
  8.  
  9. local local_id = os.getComputerID()
  10.  
  11. modem.open(CHANNEL_GLASS)
  12.  
  13. local MSG_TYPE_NEW = 0x1
  14. local MSG_TYPE_UPDATE = 0x2
  15. local MSG_TYPE_INIT = 0x3
  16. local MSG_TYPE_LISTENER = 0x4
  17.  
  18. local MSG_REACTOR_SETACTIVE = 0xEE0
  19.  
  20. local MSG_TYPE_REPLY_NEW = 0xFF0
  21.  
  22. local function Send(type, message, component_id)
  23.     modem.transmit(CHANNEL_GLASS, local_id, {
  24.         protocol = "GLASS_MESSAGE";
  25.         destination = -1;
  26.         type = type;
  27.         message = message;
  28.         component_id = component_id;
  29.     })
  30. end
  31.  
  32. local function Receive(component_id)
  33.     while true do
  34.         local event, side, schannel, rchannel, message, dist = os.pullEventRaw("modem_message")
  35.         if event == "terminate" then
  36.             return nil
  37.         end
  38.         if schannel == CHANNEL_GLASS and type(message) == "table" and message.protocol == "GLASS_MESSAGE" and message.destination == local_id and message.component_id == component_id then
  39.             return message.type, message.message
  40.         end
  41.     end
  42. end
  43.  
  44. local function SendAndReceive(mtype, message, component_id)
  45.     local rid = math.random()
  46.     modem.transmit(CHANNEL_GLASS, local_id, {
  47.         protocol = "GLASS_MESSAGE";
  48.         rid = rid;
  49.         destination = -1;
  50.         type = mtype;
  51.         message = message;
  52.         component_id = component_id;
  53.     })
  54.  
  55.     while true do
  56.         local event, side, schannel, rchannel, message, dist = os.pullEventRaw("modem_message")
  57.         if event == "terminate" then
  58.             return nil
  59.         end
  60.  
  61.         if schannel == CHANNEL_GLASS and type(message) == "table" and message.protocol == "GLASS_MESSAGE" and message.destination == local_id and message.rid == rid then
  62.             return message.type, message.message
  63.         end
  64.     end
  65. end
  66.  
  67. local function RegisterNew(type, name, data)
  68.     local mType, message = SendAndReceive(MSG_TYPE_NEW, {type = type, name = name, data = data})
  69.     local component_id
  70.     if mType == MSG_TYPE_REPLY_NEW then
  71.         return message.component_id
  72.     end
  73. end
  74.  
  75. local listeners = {}
  76.  
  77. local function AddListener(id, callback, component_id)
  78.     if not listeners[id] then
  79.         listeners[id] = {}
  80.     end
  81.     table.insert(listeners[id], {callback, component_id})
  82. end
  83.  
  84. local handlers = {
  85.     ["draconic_rf_storage"] = function(name)
  86.         local storage = peripheral.wrap(name)
  87.         local component_id = RegisterNew("energy_storage", "Draconic Energy Storage")
  88.         if not component_id then
  89.             return
  90.         end
  91.  
  92.         while true do
  93.             sleep(1)
  94.  
  95.             Send(MSG_TYPE_UPDATE, {stored = storage.getEnergyStored(), max = storage.getMaxEnergyStored()}, component_id)
  96.         end
  97.     end;
  98.  
  99.     ["tileinterface"] = function(name)
  100.         local interface = peripheral.wrap(name)
  101.         local component_id = RegisterNew("me_storage", "ME Storage")
  102.         if not component_id then
  103.             return
  104.         end
  105.  
  106.         local last_cpu_avail = nil
  107.  
  108.         while true do
  109.             sleep(1)
  110.  
  111.             local cpus = interface.getCraftingCPUs()
  112.  
  113.             local cpu_avail = 0
  114.             local cpu_max = #cpus
  115.             for i,v in pairs(cpus) do
  116.                 if not v.busy then
  117.                     cpu_avail = cpu_avail + 1
  118.                 end
  119.             end
  120.  
  121.             if cpu_avail ~= last_cpu_avail then
  122.                 Send(MSG_TYPE_UPDATE, {cpu_avail = cpu_avail, cpu_max = cpu_max}, component_id)
  123.  
  124.                 last_cpu_avail = cpu_avail
  125.             end
  126.         end
  127.     end;
  128.  
  129.     ["openperipheral_sensor"] = function(name)
  130.         local sensor = peripheral.wrap(name)
  131.  
  132.         local component_id = RegisterNew("players", "Players")
  133.         if not component_id then
  134.             return
  135.         end
  136.  
  137.         while true do
  138.             sleep(1)
  139.  
  140.             local players = {}
  141.             for i,v in pairs(sensor.getPlayers()) do
  142.                 table.insert(players, v.name)
  143.             end
  144.  
  145.             Send(MSG_TYPE_UPDATE, {players = players}, component_id)
  146.         end
  147.     end;
  148.  
  149.     ["BigReactors-Reactor"] = function(name)
  150.         local reactor = peripheral.wrap(name)
  151.  
  152.         local component_id = RegisterNew("reactor", "Reactor")
  153.         if not component_id then
  154.             return
  155.         end
  156.  
  157.         AddListener(MSG_REACTOR_SETACTIVE, function(active)
  158.             reactor.setActive(active)
  159.         end, component_id)
  160.  
  161.         while true do
  162.             sleep(1)
  163.  
  164.             Send(MSG_TYPE_UPDATE, {active = reactor.getActive(), rate = reactor.getEnergyProducedLastTick()}, component_id)
  165.         end
  166.     end;
  167. }
  168.  
  169. local routines = {}
  170.  
  171. local function Start()
  172.     for i,v in pairs(peripheral.getNames()) do
  173.         local handler = handlers[peripheral.getType(v)]
  174.         if handler then
  175.             print("Adding handler for " .. peripheral.getType(v) .. " at " .. v)
  176.             local co = coroutine.create(handler)
  177.             local succ, want = coroutine.resume(co, v)
  178.             if not succ then
  179.                 printError("routine for " .. v .. " failed: " .. want)
  180.             else
  181.                 table.insert(routines, {co, want})
  182.             end
  183.             -- handler(v)
  184.         end
  185.     end
  186. end
  187.  
  188. Start()
  189.  
  190.  
  191. while true do
  192.     local event = {os.pullEvent()}
  193.     for i,v in pairs(routines) do
  194.         if coroutine.status(v[1]) == "suspended" then
  195.             if not v[2] or v[2] == event[1] then
  196.                 local succ, want = coroutine.resume(v[1], table.unpack(event))
  197.                 if not succ then
  198.                     printError("routine failed: " .. want)
  199.                 end
  200.                 v[2] = want
  201.             end
  202.         end
  203.     end
  204.  
  205.     if event[1] == "modem_message" then
  206.         local event, side, schannel, rchannel, message, dist = table.unpack(event)
  207.         if schannel == CHANNEL_GLASS and type(message) == "table" and message.protocol == "GLASS_MESSAGE" then
  208.             if message.type == MSG_TYPE_INIT then
  209.                 sleep(1) -- give it some time
  210.                 routines = {}
  211.                 listeners = {}
  212.                 Start()
  213.             elseif message.type == MSG_TYPE_LISTENER then
  214.                 if type(message.message) == "table" then
  215.                     local id = message.message.id
  216.                     local args = message.message.args
  217.  
  218.                     if id and listeners[id] then
  219.                         for i,v in pairs(listeners[id]) do
  220.                             if v[2] == message.component_id then
  221.                                 local success, err = pcall(v[1], table.unpack(args))
  222.                                 if not success then
  223.                                     printError("Error running listener " .. id .. ": " .. err)
  224.                                 end
  225.                             end
  226.                         end
  227.                     end
  228.                 end
  229.             end
  230.         end
  231.     end
  232. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement