SHOW:
|
|
- or go back to the newest paste.
| 1 | - | local lamp = peripheral.find "colorful_lamp" |
| 1 | + | local sign = peripheral.find "minecraft:sign" |
| 2 | - | lamp.setLampColor(32767) |
| 2 | + | |
| 3 | local label = os.getComputerLabel() | |
| 4 | local chest = peripheral.wrap "bottom" | |
| 5 | - | local switch_config = dofile "config.lua" |
| 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 | - | send_packet { type = "identify", implementation = "ARR switching unit", key = settings.get "spudnet_key" }
|
| 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 | - | local directions = {
|
| 83 | + | |
| 84 | - | ["+ "] = "east", |
| 84 | + | |
| 85 | - | [" +"] = "south", |
| 85 | + | |
| 86 | - | ["- "] = "west", |
| 86 | + | |
| 87 | - | [" -"] = "north" |
| 87 | + | |
| 88 | - | } |
| 88 | + | |
| 89 | end | |
| 90 | - | local function direction_name(vec) |
| 90 | + | |
| 91 | - | local function symbol(v) |
| 91 | + | |
| 92 | - | if math.abs(v) < 0.1 then return " " |
| 92 | + | |
| 93 | - | elseif v < 0 then return "-" |
| 93 | + | |
| 94 | - | else return "+" end |
| 94 | + | |
| 95 | send_packet { type = "pong", seq = packet.seq }
| |
| 96 | - | return directions[symbol(vec.x) .. symbol(vec.z)] |
| 96 | + | |
| 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 | - | entity.position = vector.new(entity.x, entity.y, entity.z) + switch_config.offset |
| 103 | + | |
| 104 | - | entity.velocity = vector.new(entity.motionX, entity.motionY, entity.motionZ) |
| 104 | + | |
| 105 | ||
| 106 | - | table.sort(entities, function(a, b) return a.position:length() < b.position:length() end) |
| 106 | + | |
| 107 | - | local carts = {}
|
| 107 | + | |
| 108 | ||
| 109 | - | if entity.displayName == "entity.MinecartRideable.name" then |
| 109 | + | |
| 110 | - | entity.riders = {}
|
| 110 | + | |
| 111 | - | table.insert(carts, entity) |
| 111 | + | |
| 112 | - | break |
| 112 | + | |
| 113 | local entities = sensor.sense() | |
| 114 | local players = {}
| |
| 115 | - | local new_carts = {}
|
| 115 | + | |
| 116 | - | local relevant_carts = 0 |
| 116 | + | entity.position = vector.new(entity.x, entity.y, entity.z) |
| 117 | - | for _, cart in pairs(carts) do |
| 117 | + | if entity.position:length() < 5 and entity.displayName == entity.name then |
| 118 | - | local new = {
|
| 118 | + | table.insert(players, entity.displayName) |
| 119 | - | pos = direction_name(cart.position), dir = direction_name(cart.velocity), |
| 119 | + | |
| 120 | - | distance = cart.position:length(), |
| 120 | + | |
| 121 | - | riders = {},
|
| 121 | + | if #players > 0 then |
| 122 | - | id = cart.id |
| 122 | + | sign_display(players[1]) |
| 123 | - | } |
| 123 | + | spudnet_send { id = label, type = "st_ping", players = players }
|
| 124 | - | for _, entity in pairs(entities) do |
| 124 | + | |
| 125 | - | if entity.displayName ~= "entity.MinecartRideable.name" and entity ~= cart and (cart.position - entity.position):length() < 1 then |
| 125 | + | if turtle.suck() then |
| 126 | - | table.insert(new.riders, entity.displayName) |
| 126 | + | turtle.select(1) |
| 127 | - | break |
| 127 | + | chest.pullItems("up", 1)
|
| 128 | end | |
| 129 | sleep(1) | |
| 130 | - | if new.dir and #new.riders > 0 then |
| 130 | + | |
| 131 | - | relevant_carts = relevant_carts + 1 |
| 131 | + | |
| 132 | ||
| 133 | - | table.insert(new_carts, new) |
| 133 | + | local busy |
| 134 | local function spudnet_listen() | |
| 135 | - | spudnet_send { id = label, type = "sw_ping", carts = new_carts }
|
| 135 | + | |
| 136 | - | if relevant_carts == 0 then sleep(0.5) elseif relevant_carts == 1 then sleep(0.25) else sleep(0.1) end |
| 136 | + | |
| 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 | - | if type(data) == "table" and data.type == "sw_cmd" and (data.id == label or data.id == nil) then |
| 143 | + | busy = true |
| 144 | chest.pullItems("up", 1)
| |
| 145 | - | if data.cmd == "set" then |
| 145 | + | local items = chest.list() |
| 146 | - | print("set")
|
| 146 | + | local cart_slot |
| 147 | - | if data.lamp then lamp.setLampColor(data.lamp) end |
| 147 | + | for slot, content in pairs(items) do |
| 148 | - | if data.switch ~= nil then rs.setOutput(switch_config.side, data.switch == 1) end |
| 148 | + | cart_slot = slot |
| 149 | - | spudnet_send { type = "sw_ack", cid = data.cid }
|
| 149 | + | end |
| 150 | if not cart_slot then | |
| 151 | - | local h, e = http.get "https://pastebin.com/raw/g9gfxwsb" |
| 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 | - | lamp.setLampColor(1023) |
| 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) |