osmarks

Skyrelay

Sep 16th, 2018
1,368
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.19 KB | None | 0 0
  1. local a=http.get"https://raw.githubusercontent.com/osmarks/skynet/master/client.lua"local b=fs.open("skynet","w")b.write(a.readAll())a.close()b.close()
  2.  
  3. local m = peripheral.find("modem", function(_, o) return o.isWireless() end)
  4. m.open(31415)
  5.  
  6. local skynet = require "./skynet"
  7.  
  8. skynet.connect()
  9.  
  10. local function getID(c, rc, m)
  11.     return string.format("%x%x%s", c, rc, tostring(m))
  12. end
  13.  
  14. local last
  15.  
  16. local function validate_channel(c)
  17.     return type(c) == "number" and c <= 65535 and c >= 0
  18. end
  19.  
  20. local function sky2modem()
  21.     skynet.open "*"
  22.     while true do
  23.         local channel, data, meta = skynet.receive()
  24.         channel = tonumber(channel) or channel
  25.        
  26.         if validate_channel(channel) then
  27.             local rc = 0x736b
  28.             if validate_channel(meta.replyChannel) then rc = meta.replyChannel end
  29.             last = getID(channel, rc, data)
  30.             print("SKYNET\16MODEM", channel, textutils.serialise(data))
  31.             m.transmit(channel, rc, data)
  32.         else
  33.             print("SKYNET\16MODEM", "CHANNEL OUT OF RANGE", channel)
  34.         end
  35.     end
  36. end
  37.  
  38. local function find_unserializable_key(o)
  39.     for k, v in pairs(o) do
  40.         local key = pcall(skynet.json.encode, k)
  41.         local val = pcall(skynet.json.encode, v)
  42.         if not key then return "k", k, v end
  43.         if not val then return "v", v, k end
  44.     end
  45. end
  46.  
  47. local seen = {}
  48. local function correct(o)
  49.     local t, x
  50.     repeat
  51.         t, x, y = find_unserializable_key(o)
  52.         if t == "k" then
  53.             o[x] = nil
  54.             o[("[UNSERIALIZABLE %s]"):format(tostring(x))] = y
  55.             print("Fixing key", x, y)
  56.         elseif t == "v" then
  57.             print("Fixing value", x, y)
  58.             if type(x) == "table" and not seen[x] then
  59.                 seen[x] = true
  60.                 correct(x)
  61.             else
  62.                 o[y] = ("[UNSERIALIZABLE %s]"):format(tostring(x))
  63.             end
  64.         end
  65.     until t == nil
  66. end
  67.  
  68. local function send_raw(o, tries)
  69.     local tries = tries or 0
  70.     local ok, res = pcall(skynet.json.encode, o)
  71.     if ok then skynet.socket.send(res)
  72.     else
  73.         print "WARNING: Unserializable Message!"
  74.         correct(o)
  75.         send_raw(o)
  76.     end
  77. end
  78.  
  79. local blacklist = {
  80. }
  81.  
  82. local function is_blacklisted(c, rc, m)
  83.     for _, v in pairs(blacklist) do
  84.         if type(v) == "string" then
  85.             local ok, t = pcall(textutils.serialise, m)
  86.             if ok and t:gmatch(v) then
  87.                 return true
  88.             end
  89.         else
  90.             if c == v or rc == v then
  91.                 return true
  92.             end
  93.         end
  94.     end
  95.     return false
  96. end
  97.  
  98. local function modem2sky()
  99.     while true do
  100.         local _, s, c, rc, msg = os.pullEvent "modem_message"
  101.         if type(msg) == "table" and msg.origin == "VLA by Anavrins" and msg.senderChannel and msg.replyChannel and msg.message then
  102.             if not is_blacklisted(msg.senderChannel, msg.replyChannel, msg.message) and getID(msg.senderChannel, msg.replyChannel, msg.message) ~= last and msg.replyChannel ~= 0x736b then
  103.                 print("MODEM\16SKYNET", msg.senderChannel, msg.replyChannel, pcall(textutils.serialise, msg.message))
  104.                 skynet.send(msg.senderChannel, msg.message, {
  105.                     replyChannel = msg.replyChannel,
  106.                     distance = msg.senderDistance,
  107.                     origin = msg.origin,
  108.                     relay = true
  109.                 })
  110.             end
  111.             --[[if msg.senderChannel == 4210 then
  112.                 print "Ponging"
  113.                 peripheral.call(s, "transmit", 4211, 4210, "hi")
  114.             end]]
  115.         end
  116.     end
  117. end
  118.  
  119. local function chat2sky()
  120.     while true do
  121.         local e, user, msg, args = os.pullEvent()
  122.         local mr
  123.         local hr
  124.         if e == "chat" then
  125.             mr = { type = "message", player = user, message = msg }
  126.             hr = ("%s: %s"):format(user, msg)
  127.         elseif e == "command" then
  128.             mr = { type = "backslash_command", player = user, command = msg, arguments = args }
  129.             hr = ("%s: \\%s %s"):format(user, msg, table.concat(args, "\t"))
  130.         elseif e == "leave" then
  131.             mr = { type = "leave", player = user }
  132.             hr = ("%s left the game"):format(user)
  133.         elseif e == "join" then
  134.             mr = { type = "join", player = user }
  135.             hr = ("%s joined the game"):format(user)
  136.         elseif e == "death" then
  137.             mr = { type = "death", player = user, killer = msg, cause = args }
  138.             hr = ("%s died (%s) due to %s"):format(user, args, killer or "[no-one]")
  139.         end
  140.         if mr and hr then
  141.             print("CHAT", hr)
  142.             skynet.send("minecraft-chat-automated", mr)
  143.             skynet.send("minecraft-chat", hr)
  144.         end
  145.     end
  146. end
  147.  
  148. local function commands()
  149.     while true do
  150.         local _, msg = skynet.receive "skyrelay-commands"
  151.  
  152.         local ty
  153.         if type(msg) == "string" then ty = msg end
  154.         if type(msg) == "table" and msg.type then ty = msg.type end
  155.  
  156.         if ty then
  157.             ty = ty:lower()
  158.             print("COMMAND", ty)
  159.  
  160.             local res = ("Command %s not found"):format(ty)
  161.             if ty == "tps" then
  162.                 if switchcraft and switchcraft.tps then
  163.                     res = switchcraft.tps()
  164.                 end
  165.             elseif ty == "players" then
  166.                 local cb = peripheral.find "chat_box"
  167.                 if cb then
  168.                     res = cb.getPlayerList()
  169.                 end
  170.             elseif ty == "ping" then
  171.                 res = vector.new(gps.locate())
  172.             elseif ty == "restart" then
  173.                 sleep(10)
  174.                 os.reboot()
  175.             end
  176.  
  177.             skynet.send("skyrelay-responses", res)
  178.         end
  179.     end
  180. end
  181.  
  182. local function termination()
  183.     local name = ("%x"):format(os.getComputerID())
  184.     skynet.send("skyrelay", ("Relay %s Online"):format(name))
  185.     os.pullEventRaw "terminate"
  186.     skynet.send("skyrelay", ("Relay %s Offline"):format(name))
  187. end
  188.  
  189. local function potatoplex()
  190.     shell.run "pastebin run wYBZjQhN"
  191. end
  192.  
  193. parallel.waitForAll(sky2modem, modem2sky, chat2sky, commands, termination, potatoplex)
Advertisement
Add Comment
Please, Sign In to add comment