Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local ALTPROTO_PORT = 16660
- local function Log(text)
- print(text)
- end
- local proto_id
- local file = fs.open("altproto_id", "r")
- if file then
- proto_id = tonumber(file.readAll())
- file.close()
- if not proto_id then
- Log("Invalid protocol id, setting to computer id")
- proto_id = os.getComputerID()
- end
- else
- Log("No protocol id found, setting to computer id")
- proto_id = os.getComputerID()
- file = fs.open("altproto_id", "w")
- file.write(tostring(proto_id))
- file.close()
- end
- local modem = peripheral.find("modem", function(_, p) return p.isWireless() end)
- if not modem then
- Log("No modem found.. waiting")
- repeat
- local event, side = os.pullEvent("peripheral")
- if peripheral.getType(side) == "modem" and peripheral.call(side, "isWireless") then
- modem = peripheral.wrap(side)
- end
- until modem
- end
- modem.open(ALTPROTO_PORT)
- local RECIPIENT_ALL = 0
- local function SendMessage(id, recipient, data)
- modem.transmit(ALTPROTO_PORT, 0, {id = id, data = data, recipient = recipient, sender = proto_id})
- end
- local timers = {}
- local event_listeners = {}
- local message_handlers = {}
- local module_env = setmetatable({
- CreateTimer = function(callback, timeout, loop)
- local id = os.startTimer(timeout)
- timers[id] = {callback, timeout, loop}
- end;
- OnEvent = function(callback, filter)
- table.insert(event_listeners, {callback, filter})
- end;
- OnMessage = function(callback, id)
- if not id then
- id = "all"
- end
- if not message_handlers[id] then
- message_handlers[id] = {}
- end
- table.insert(message_handlers[id], callback)
- end;
- Log = Log;
- SendMessage = SendMessage;
- RECIPIENT_ALL = RECIPIENT_ALL;
- }, {__index = _G})
- local function LoadModules()
- if not fs.exists("modules") then
- Log("Creating modules directory")
- fs.makeDir("modules")
- end
- for _, name in ipairs(fs.list("modules")) do
- if not fs.isDir("modules/" .. name) then
- Log("Loading module: " .. name)
- local file = fs.open("modules/" .. name, "r")
- local data = file.readAll()
- file.close()
- local func, err = loadstring(data, name)
- if func then
- local env = {}
- setmetatable(env, {__index = module_env})
- setfenv(func, env)
- local success, err = pcall(func)
- if not success then
- Log("ERROR: in module " .. name .. ": " .. err)
- end
- else
- Log("ERROR: " .. err)
- end
- end
- end
- end
- local function ReloadModules()
- timers = {}
- event_listeners = {}
- message_handlers = {}
- LoadModules()
- end
- LoadModules()
- local function HandleMessage(id, real_id, recipient, sender, data)
- if message_handlers[id] then
- for i,v in pairs(message_handlers[id]) do
- local success, err = pcall(v, real_id, recipient, sender, data)
- if not success then
- Log("Error in message handler: " .. err)
- end
- end
- end
- end
- while true do
- local success, err = pcall(function()
- local event = {os.pullEvent()}
- if event[1] == "modem_message" then
- local event, side, sender, reply, message, distance = unpack(event)
- if sender == ALTPROTO_PORT then
- if type(message) ~= "table" then
- Log("ERROR: Message was not a table")
- return
- end
- local recipient = message.recipient
- if not recipient then
- Log("ERROR: Message has no recipient")
- return
- end
- local sender = message.sender
- if not sender then
- Log("ERROR: Message has no sender")
- return
- end
- if recipient == proto_id or recipient == RECIPIENT_ALL then
- local id = message.id
- if not id then
- Log("ERROR: Message has no ID")
- return
- end
- if id == "GPING" then
- SendMessage("GPONG", RECIPIENT_ALL, os.getComputerLabel())
- Log("Send GPONG")
- elseif id == "UPDATE" then
- local func, err = loadstring(message.data)
- if not func then
- Log("Attempt to update with bad code: " .. err)
- else
- local file = fs.open("startup", "w")
- file.write(message.data)
- file.close()
- os.reboot()
- end
- elseif id == "UPDATEMOD" then
- local data = message.data
- local file = fs.open("modules/" .. data.name, "w")
- file.write(data.code)
- file.close()
- ReloadModules()
- elseif id == "EXEC" then
- if type(message.data) == "string" then
- local func, err = loadstring(message.data, "exec")
- if func then
- local success, err = pcall(func)
- if not success then
- Log("Error executing: " .. err)
- end
- else
- Log("Cannot execute: " .. err)
- end
- else
- Log("Cannot execute: not a string")
- end
- end
- HandleMessage("all", id, recipient, sender, message.data)
- HandleMessage(id, id, recipient, sender, message.data)
- end
- end
- elseif event[1] == "timer" then
- local timer = timers[event[2]]
- if timer then
- local success, err = pcall(timer[1])
- if not success then
- Log("Error in timer: " .. err)
- end
- timers[event[2]] = nil
- if timer[3] then
- timers[os.startTimer(timer[2])] = timer
- end
- end
- end
- for i,v in pairs(event_listeners) do
- if v[2] == event[1] or not v[2] then
- local success, err = pcall(v[1], unpack(event))
- if not success then
- Log("Error in event handler: " .. err)
- end
- end
- end
- end)
- if err == "Terminated" then
- break
- end
- if not success then
- Log("Fatal error: " .. err)
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement