Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local CHANNEL_GLASS = 10033
- local modem = peripheral.find("modem", function(_, t) return t.isWireless() end)
- if not modem then
- printError("no modem attached")
- return
- end
- local local_id = os.getComputerID()
- modem.open(CHANNEL_GLASS)
- local MSG_TYPE_NEW = 0x1
- local MSG_TYPE_UPDATE = 0x2
- local MSG_TYPE_INIT = 0x3
- local MSG_TYPE_LISTENER = 0x4
- local MSG_REACTOR_SETACTIVE = 0xEE0
- local MSG_TYPE_REPLY_NEW = 0xFF0
- local function Send(type, message, component_id)
- modem.transmit(CHANNEL_GLASS, local_id, {
- protocol = "GLASS_MESSAGE";
- destination = -1;
- type = type;
- message = message;
- component_id = component_id;
- })
- end
- local function Receive(component_id)
- while true do
- local event, side, schannel, rchannel, message, dist = os.pullEventRaw("modem_message")
- if event == "terminate" then
- return nil
- end
- 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
- return message.type, message.message
- end
- end
- end
- local function SendAndReceive(mtype, message, component_id)
- local rid = math.random()
- modem.transmit(CHANNEL_GLASS, local_id, {
- protocol = "GLASS_MESSAGE";
- rid = rid;
- destination = -1;
- type = mtype;
- message = message;
- component_id = component_id;
- })
- while true do
- local event, side, schannel, rchannel, message, dist = os.pullEventRaw("modem_message")
- if event == "terminate" then
- return nil
- end
- if schannel == CHANNEL_GLASS and type(message) == "table" and message.protocol == "GLASS_MESSAGE" and message.destination == local_id and message.rid == rid then
- return message.type, message.message
- end
- end
- end
- local function RegisterNew(type, name, data)
- local mType, message = SendAndReceive(MSG_TYPE_NEW, {type = type, name = name, data = data})
- local component_id
- if mType == MSG_TYPE_REPLY_NEW then
- return message.component_id
- end
- end
- local listeners = {}
- local function AddListener(id, callback, component_id)
- if not listeners[id] then
- listeners[id] = {}
- end
- table.insert(listeners[id], {callback, component_id})
- end
- local handlers = {
- ["draconic_rf_storage"] = function(name)
- local storage = peripheral.wrap(name)
- local component_id = RegisterNew("energy_storage", "Draconic Energy Storage")
- if not component_id then
- return
- end
- while true do
- sleep(1)
- Send(MSG_TYPE_UPDATE, {stored = storage.getEnergyStored(), max = storage.getMaxEnergyStored()}, component_id)
- end
- end;
- ["tileinterface"] = function(name)
- local interface = peripheral.wrap(name)
- local component_id = RegisterNew("me_storage", "ME Storage")
- if not component_id then
- return
- end
- local last_cpu_avail = nil
- while true do
- sleep(1)
- local cpus = interface.getCraftingCPUs()
- local cpu_avail = 0
- local cpu_max = #cpus
- for i,v in pairs(cpus) do
- if not v.busy then
- cpu_avail = cpu_avail + 1
- end
- end
- if cpu_avail ~= last_cpu_avail then
- Send(MSG_TYPE_UPDATE, {cpu_avail = cpu_avail, cpu_max = cpu_max}, component_id)
- last_cpu_avail = cpu_avail
- end
- end
- end;
- ["openperipheral_sensor"] = function(name)
- local sensor = peripheral.wrap(name)
- local component_id = RegisterNew("players", "Players")
- if not component_id then
- return
- end
- while true do
- sleep(1)
- local players = {}
- for i,v in pairs(sensor.getPlayers()) do
- table.insert(players, v.name)
- end
- Send(MSG_TYPE_UPDATE, {players = players}, component_id)
- end
- end;
- ["BigReactors-Reactor"] = function(name)
- local reactor = peripheral.wrap(name)
- local component_id = RegisterNew("reactor", "Reactor")
- if not component_id then
- return
- end
- AddListener(MSG_REACTOR_SETACTIVE, function(active)
- reactor.setActive(active)
- end, component_id)
- while true do
- sleep(1)
- Send(MSG_TYPE_UPDATE, {active = reactor.getActive(), rate = reactor.getEnergyProducedLastTick()}, component_id)
- end
- end;
- }
- local routines = {}
- local function Start()
- for i,v in pairs(peripheral.getNames()) do
- local handler = handlers[peripheral.getType(v)]
- if handler then
- print("Adding handler for " .. peripheral.getType(v) .. " at " .. v)
- local co = coroutine.create(handler)
- local succ, want = coroutine.resume(co, v)
- if not succ then
- printError("routine for " .. v .. " failed: " .. want)
- else
- table.insert(routines, {co, want})
- end
- -- handler(v)
- end
- end
- end
- Start()
- while true do
- local event = {os.pullEvent()}
- for i,v in pairs(routines) do
- if coroutine.status(v[1]) == "suspended" then
- if not v[2] or v[2] == event[1] then
- local succ, want = coroutine.resume(v[1], table.unpack(event))
- if not succ then
- printError("routine failed: " .. want)
- end
- v[2] = want
- end
- end
- end
- if event[1] == "modem_message" then
- local event, side, schannel, rchannel, message, dist = table.unpack(event)
- if schannel == CHANNEL_GLASS and type(message) == "table" and message.protocol == "GLASS_MESSAGE" then
- if message.type == MSG_TYPE_INIT then
- sleep(1) -- give it some time
- routines = {}
- listeners = {}
- Start()
- elseif message.type == MSG_TYPE_LISTENER then
- if type(message.message) == "table" then
- local id = message.message.id
- local args = message.message.args
- if id and listeners[id] then
- for i,v in pairs(listeners[id]) do
- if v[2] == message.component_id then
- local success, err = pcall(v[1], table.unpack(args))
- if not success then
- printError("Error running listener " .. id .. ": " .. err)
- end
- end
- end
- end
- end
- end
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement