osmarks

ARR Station

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