Advertisement
Alakazard12

AltProto_Client

Mar 11th, 2017
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.42 KB | None | 0 0
  1. local ALTPROTO_PORT = 16660
  2.  
  3. local function Log(text)
  4.     print(text)
  5. end
  6.  
  7.  
  8. local proto_id
  9.  
  10. local file = fs.open("altproto_id", "r")
  11. if file then
  12.     proto_id = tonumber(file.readAll())
  13.     file.close()
  14.  
  15.     if not proto_id then
  16.         Log("Invalid protocol id, setting to computer id")
  17.         proto_id = os.getComputerID()
  18.     end
  19. else
  20.     Log("No protocol id found, setting to computer id")
  21.     proto_id = os.getComputerID()
  22.     file = fs.open("altproto_id", "w")
  23.     file.write(tostring(proto_id))
  24.     file.close()
  25. end
  26.  
  27. local modem = peripheral.find("modem", function(_, p) return p.isWireless() end)
  28. if not modem then
  29.     Log("No modem found.. waiting")
  30.  
  31.     repeat
  32.         local event, side = os.pullEvent("peripheral")
  33.         if peripheral.getType(side) == "modem" and peripheral.call(side, "isWireless") then
  34.             modem = peripheral.wrap(side)
  35.         end
  36.     until modem
  37. end
  38.  
  39.  
  40.  
  41.  
  42.  
  43. modem.open(ALTPROTO_PORT)
  44.  
  45.  
  46. local RECIPIENT_ALL = 0
  47. local function SendMessage(id, recipient, data)
  48.     modem.transmit(ALTPROTO_PORT, 0, {id = id, data = data, recipient = recipient, sender = proto_id})
  49. end
  50.  
  51.  
  52. local timers = {}
  53. local event_listeners = {}
  54. local message_handlers = {}
  55.  
  56. local module_env = setmetatable({
  57.     CreateTimer = function(callback, timeout, loop)
  58.         local id = os.startTimer(timeout)
  59.         timers[id] = {callback, timeout, loop}
  60.     end;
  61.  
  62.     OnEvent = function(callback, filter)
  63.         table.insert(event_listeners, {callback, filter})
  64.     end;
  65.  
  66.     OnMessage = function(callback, id)
  67.         if not id then
  68.             id = "all"
  69.         end
  70.  
  71.         if not message_handlers[id] then
  72.             message_handlers[id] = {}
  73.         end
  74.         table.insert(message_handlers[id], callback)
  75.     end;
  76.  
  77.     Log = Log;
  78.  
  79.     SendMessage = SendMessage;
  80.  
  81.     RECIPIENT_ALL = RECIPIENT_ALL;
  82. }, {__index = _G})
  83.  
  84.  
  85. local function LoadModules()
  86.     if not fs.exists("modules") then
  87.         Log("Creating modules directory")
  88.         fs.makeDir("modules")
  89.     end
  90.  
  91.     for _, name in ipairs(fs.list("modules")) do
  92.         if not fs.isDir("modules/" .. name) then
  93.             Log("Loading module: " .. name)
  94.             local file = fs.open("modules/" .. name, "r")
  95.             local data = file.readAll()
  96.             file.close()
  97.  
  98.             local func, err = loadstring(data, name)
  99.             if func then
  100.                 local env = {}
  101.                 setmetatable(env, {__index = module_env})
  102.                 setfenv(func, env)
  103.  
  104.                 local success, err = pcall(func)
  105.                 if not success then
  106.                     Log("ERROR: in module " .. name .. ": " .. err)
  107.                 end
  108.             else
  109.                 Log("ERROR: " .. err)
  110.             end
  111.         end
  112.     end
  113. end
  114.  
  115. local function ReloadModules()
  116.     timers = {}
  117.     event_listeners = {}
  118.     message_handlers = {}
  119.  
  120.     LoadModules()
  121. end
  122.  
  123.  
  124. LoadModules()
  125.  
  126. local function HandleMessage(id, real_id, recipient, sender, data)
  127.     if message_handlers[id] then
  128.         for i,v in pairs(message_handlers[id]) do
  129.             local success, err = pcall(v, real_id, recipient, sender, data)
  130.             if not success then
  131.                 Log("Error in message handler: " .. err)
  132.             end
  133.         end
  134.     end
  135. end
  136.  
  137. while true do
  138.     local success, err = pcall(function()
  139.         local event = {os.pullEvent()}
  140.  
  141.         if event[1] == "modem_message" then
  142.             local event, side, sender, reply, message, distance = unpack(event)
  143.  
  144.             if sender == ALTPROTO_PORT then
  145.                 if type(message) ~= "table" then
  146.                     Log("ERROR: Message was not a table")
  147.                     return
  148.                 end
  149.  
  150.                 local recipient = message.recipient
  151.                 if not recipient then
  152.                     Log("ERROR: Message has no recipient")
  153.                     return
  154.                 end
  155.                 local sender = message.sender
  156.                 if not sender then
  157.                     Log("ERROR: Message has no sender")
  158.                     return
  159.                 end
  160.  
  161.                 if recipient == proto_id or recipient == RECIPIENT_ALL then
  162.                     local id = message.id
  163.                     if not id then
  164.                         Log("ERROR: Message has no ID")
  165.                         return
  166.                     end
  167.  
  168.                     if id == "GPING" then
  169.                         SendMessage("GPONG", RECIPIENT_ALL, os.getComputerLabel())
  170.                         Log("Send GPONG")
  171.                     elseif id == "UPDATE" then
  172.                         local func, err = loadstring(message.data)
  173.                         if not func then
  174.                             Log("Attempt to update with bad code: " .. err)
  175.                         else
  176.                             local file = fs.open("startup", "w")
  177.                             file.write(message.data)
  178.                             file.close()
  179.  
  180.                             os.reboot()
  181.                         end
  182.                     elseif id == "UPDATEMOD" then
  183.                         local data = message.data
  184.                         local file = fs.open("modules/" .. data.name, "w")
  185.                         file.write(data.code)
  186.                         file.close()
  187.  
  188.                         ReloadModules()
  189.                     elseif id == "EXEC" then
  190.                         if type(message.data) == "string" then
  191.                             local func, err = loadstring(message.data, "exec")
  192.                             if func then
  193.                                 local success, err = pcall(func)
  194.                                 if not success then
  195.                                     Log("Error executing: " .. err)
  196.                                 end
  197.                             else
  198.                                 Log("Cannot execute: " .. err)
  199.                             end
  200.                         else
  201.                             Log("Cannot execute: not a string")
  202.                         end
  203.                     end
  204.  
  205.                     HandleMessage("all", id, recipient, sender, message.data)
  206.                     HandleMessage(id, id, recipient, sender, message.data)
  207.                 end
  208.             end
  209.         elseif event[1] == "timer" then
  210.             local timer = timers[event[2]]
  211.             if timer then
  212.                 local success, err = pcall(timer[1])
  213.                 if not success then
  214.                     Log("Error in timer: " .. err)
  215.                 end
  216.  
  217.                 timers[event[2]] = nil
  218.                 if timer[3] then
  219.                     timers[os.startTimer(timer[2])] = timer
  220.                 end
  221.             end
  222.         end
  223.  
  224.         for i,v in pairs(event_listeners) do
  225.             if v[2] == event[1] or not v[2] then
  226.                 local success, err = pcall(v[1], unpack(event))
  227.                 if not success then
  228.                     Log("Error in event handler: " .. err)
  229.                 end
  230.             end
  231.         end
  232.     end)
  233.  
  234.     if err == "Terminated" then
  235.         break
  236.     end
  237.  
  238.     if not success then
  239.         Log("Fatal error: " .. err)
  240.     end
  241. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement