Advertisement
osmarks

Skyrelay

Sep 16th, 2018
1,118
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
Advertisement