osmarks

ARR Station

Mar 2nd, 2022 (edited)
755
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. local sign = peripheral.find "minecraft:sign"
  2. local sensor = peripheral.find "plethora:sensor"
  3. local label = os.getComputerLabel()
  4. local chest = peripheral.wrap "bottom"
  5.  
  6. sign.setSignText "Rotating"
  7.  
  8. local powered_rail_side = "right"
  9.  
  10. --[[
  11. while true do
  12.     local presence, meta = turtle.inspect()
  13.     if presence and meta.name == "minecraft:activator_rail" then
  14.         break
  15.     end
  16.     turtle.turnRight()
  17. end
  18. ]]
  19.  
  20. turtle.turnLeft()
  21. local presence, meta = turtle.inspect()
  22. if presence and meta.name == "minecraft:golden_rail" then
  23.     powered_rail_side = "left"
  24. end
  25. turtle.turnRight()
  26.  
  27. local function sign_display(player)
  28.     local l2, l3 = "", ""
  29.     if player then
  30.         l2 = "Welcome, "
  31.         l3 = player
  32.     end
  33.     sign.setSignText(label, l2, l3, "\\arr goto [dest]")
  34. end
  35. sign_display()
  36.  
  37. local function spudnet()
  38.     if not http or not http.websocket then return "Websockets do not actually exist on this platform" end
  39.  
  40.     local ws
  41.  
  42.     local function send_packet(msg)
  43.         local ok, err = pcall(ws.send, textutils.serialiseJSON(msg))
  44.         if not ok then printError(err) try_connect_loop() end
  45.     end
  46.  
  47.     local function send(data)
  48.         send_packet { type = "send", channel = "comm:arr", data = data }
  49.     end
  50.  
  51.     local function connect()
  52.         if ws then ws.close() end
  53.         ws, err = http.websocket "wss://spudnet.osmarks.net/v4?enc=json"
  54.         if not ws then print("websocket failure %s", err) return false end
  55.         ws.url = "wss://spudnet.osmarks.net/v4?enc=json"
  56.  
  57.         send_packet { type = "identify", implementation = "ARR station unit", key = settings.get "spudnet_key" }
  58.         send_packet { type = "set_channels", channels = { "comm:arr" } }
  59.  
  60.         print("websocket connected")
  61.  
  62.         return true
  63.     end
  64.  
  65.     local function try_connect_loop()
  66.         while not connect() do
  67.             sleep(0.5)
  68.         end
  69.     end
  70.  
  71.     try_connect_loop()
  72.  
  73.     local function recv()
  74.         while true do
  75.             local e, u, x = os.pullEvent "websocket_message"
  76.             if u == ws.url then return textutils.unserialiseJSON(x) end
  77.         end
  78.     end
  79.  
  80.     local ping_timeout_timer = nil
  81.  
  82.     local function ping_timer()
  83.         while true do
  84.             local _, t = os.pullEvent "timer"
  85.             if t == ping_timeout_timer and ping_timeout_timer then
  86.                 -- 15 seconds since last ping, we probably got disconnected
  87.                 print "SPUDNET timed out, attempting reconnect"
  88.                 try_connect_loop()
  89.             end
  90.         end
  91.     end
  92.  
  93.     local function main()
  94.         while true do
  95.             local packet = recv()
  96.             if packet.type == "ping" then
  97.                 send_packet { type = "pong", seq = packet.seq }
  98.                 if ping_timeout_timer then os.cancelTimer(ping_timeout_timer) end
  99.                 ping_timeout_timer = os.startTimer(15)
  100.             elseif packet.type == "error" then
  101.                 print("SPUDNET error", packet["for"], packet.error, packet.detail, textutils.serialise(packet))
  102.             elseif packet.type == "message" then
  103.                 os.queueEvent("spudnet_message", packet.data)
  104.             end
  105.         end
  106.     end
  107.  
  108.     return send, function() parallel.waitForAll(ping_timer, main) end
  109. end
  110.  
  111. local spudnet_send, spudnet_handler = spudnet()
  112.  
  113. local function main()
  114.     while true do
  115.         local entities = sensor.sense()
  116.         local players = {}
  117.         for _, entity in pairs(entities) do
  118.             entity.position = vector.new(entity.x, entity.y, entity.z)
  119.             if entity.position:length() < 5 and entity.displayName == entity.name then
  120.                 table.insert(players, entity.displayName)
  121.             end
  122.         end
  123.         if #players > 0 then
  124.             sign_display(players[1])
  125.             spudnet_send { id = label, type = "st_ping", players = players }
  126.         end
  127.         if turtle.suck() then
  128.             turtle.select(1)
  129.             chest.pullItems("up", 1)
  130.         end
  131.         sleep(1)
  132.     end
  133. end
  134.  
  135. local busy
  136. local function spudnet_listen()
  137.     while true do
  138.         --[[
  139.         local _, data = os.pullEvent "spudnet_message"
  140.         if type(data) == "table" and data.type == "st_cmd" and (data.id == label or data.id == nil) then
  141.             --print(data.type, data.cmd)
  142.             if data.cmd == "place_cart" then
  143.                 if busy then
  144.                     spudnet_send { id = label, cid = data.cid, type = "st_ack", status = "busy" }
  145.                 else
  146.                     busy = true
  147.                     chest.pullItems("up", 1)
  148.                     local items = chest.list()
  149.                     local cart_slot
  150.                     for slot, content in pairs(items) do
  151.                         cart_slot = slot
  152.                     end
  153.                     if not cart_slot then
  154.                         spudnet_send { id = label, cid = data.cid, type = "st_ack", status = "no_cart" }
  155.                     else
  156.                         chest.pushItems("up", cart_slot, 1, 1)
  157.                         if powered_rail_side == "left" then turtle.turnLeft() else turtle.turnRight() end
  158.                         turtle.place()
  159.                         if powered_rail_side == "left" then turtle.turnRight() else turtle.turnLeft() end
  160.                         spudnet_send { id = label, cid = data.cid, type = "st_ack", status = "done" }
  161.                     end
  162.                     busy = false
  163.                 end
  164.             elseif data.cmd == "update" then
  165.                 local h, e = http.get "https://pastebin.com/raw/JxauVSec"
  166.                 if not h then printError(e)
  167.                 else
  168.                     sign.setSignText("Update", "in progress")
  169.                     local t = h.readAll()
  170.                     h.close()
  171.                     local f, e = load(t)
  172.                     if f then
  173.                         local f = fs.open("startup", "w")
  174.                         f.write(t)
  175.                         f.close()
  176.                         print "reboot"
  177.                         sleep(1)
  178.                         os.reboot()
  179.                     else printError(e) end
  180.  
  181.                 end
  182.             end
  183.         end
  184.         ]]
  185.         write "> "
  186.         local x = read()
  187.         spudnet_send { id = label, type = "control", msg = x }
  188.     end
  189. end
  190.  
  191. parallel.waitForAll(spudnet_handler, main, spudnet_listen)
  192.  
Advertisement
Add Comment
Please, Sign In to add comment