View difference between Paste ID: JxauVSec and g9gfxwsb
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)