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) |