-
Notifications
You must be signed in to change notification settings - Fork 12
/
swarm
240 lines (227 loc) · 6.44 KB
/
swarm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
assert(turtle, "This program is for turtles only")
local function loadAPI(file)
local e = {}
setmetatable(e, {__index = _G})
local api
if load then
-- 5.2 compat
local f = fs.open(file,"r")
local data = f.readAll()
f.close()
api = load(data,fs.getName(file),nil,e)
else
-- 5.1 only
api = loadfile(file)
setfenv(api, e)
end
local ok, err = pcall(api)
if ok then
local out = {}
for k,v in pairs(e) do
out[k] = v
end
return out
else
return false, err
end
end
local go, err = loadAPI("relgo")
if go then
_G.go = go
else
error("failed to load api: "..err)
end
local config, err = loadAPI("config")
if config then
_G.config = config
config.init(".swarmconfig")
else
error("failed to load api: "..err)
end
local miner, err = loadAPI("miner")
if miner then
_G.miner = miner
else
error("failed to load api: "..err)
end
local json, err = loadAPI("json")
if json then
_G.json = json
else
error("failed to load api: "..err)
end
if (go and config and miner and json) then
print("All APIs loaded successfully.")
else
error("Failed to load APIs!")
end
if config.get("autoname",true) then
-- set turtle label automatically to prevent fuel loss on break
if not os.getComputerLabel() then
local lbl = "turtle_"..os.getComputerID()
os.setComputerLabel(lbl)
print("Computer label set to "..lbl)
end
end
function getShaft(host, swarmName, authtoken)
local request = ""
if authtoken then
request = host .. "/swarm/" .. swarmName .."/claimshaft/?token=" .. authtoken .. "&id=" .. os.getComputerID()
else
request = host .. "/swarm/" .. swarmName .."/claimshaft/?id=" .. os.getComputerID()
end
local data = http.get(request)
if data then
local t = json.decode(data.readAll())
if t.success then return t.success else
return false, t.error
end
else
return false, "no response"
end
end
function markFinished(shaft, host, swarmName, authtoken)
local request = ""
if authtoken then
request = host .. "/swarm/" .. swarmName .."/finishedshaft/?token=" .. authtoken .. "&x=" .. shaft.x .. "&z=" .. shaft.z
else
request = host .. "/swarm/" .. swarmName .."/finishedshaft/?x=" .. shaft.x .. "&z=" .. shaft.z
end
local data = http.get(request)
if data then
local t = json.decode(data.readAll())
if t.success then return t.success else
return false, t.error
end
else
return false, "no response"
end
end
local function dropoff(all)
for i = 1, 16 do
if turtle.getItemDetail(i) and (turtle.getItemDetail(i).name ~= "minecraft:bucket" or all) then
turtle.select(i)
-- put fuel in fuel chest if possible
if turtle.refuel(0) then
if not turtle.dropUp(64) then turtle.drop(64) end
else
turtle.drop(64)
end
end
end
end
if config.get("host") and config.get("dropoff") and config.get("swarmname") then
-- local host = config.get("host")
-- local dropoff = config.get("dropoff")
-- local name = config.get("swarmname")
-- resume states:
-- prep - preparing to mine new shaft
-- mining - currently mining a shaft(also needs coords)
-- done - mining is complete
--local ystart = config.get("y",64)
while true do
if config.get("state", "prep") == "prep" then
if not config.get("shaft") then
-- get a shaft
print("Getting shaft info...")
local shaft, err = getShaft(config.get("host"),config.get("swarmname"),config.get("authtoken"))
if shaft then
config.set("shaft", shaft)
else
if err == "no response" then
print("Server not responding. Retrying in 120 seconds.")
sleep(120)
elseif err == "no remaining shafts" then
print("All shafts mined.")
config.set("state","done")
end
end
end
if config.get("shaft") then
local shaft = config.get("shaft")
-- prepare to mine the shaft
print("Preparing to mine at "..shaft.x..", "..shaft.z)
-- check if turtle has enough fuel
local cpos = go.getPos()
local needed = config.get("fuelspare",25)
needed = needed + go.fuelTo(shaft.x, 64, shaft.z+2)
needed = needed + 70 * 2 -- for actual mining - assume 70 depth
needed = needed + go.fuelTo(config.get("dropoff"),{x=shaft.x,y=64,z=shaft.z+2})
miner.refuel(needed)
if turtle.getFuelLevel() < needed then
if not go.canReach(config.get("dropoff")) then
print("Please add fuel!")
while not go.canReach(config.get("dropoff")) do
os.pullEvent()
miner.refuel(go.fuelTo(config.get("dropoff")))
end
end
print("Getting more fuel")
go.goto(config.get("dropoff"))
miner.tossJunk("down")
dropoff()
while (turtle.getFuelLevel() <= needed) do
turtle.suckUp(64)
miner.refuel(needed + config.get("fuelbuffer",250))
end
dropoff()
end
local freeslots = 0
for i = 1, 16 do
if turtle.getItemCount(i) == 0 then
freeslots = freeslots + 1
end
end
if freeslots < config.get("freeslots",10) then
print("Dropping off items")
go.goto(config.get("dropoff"))
miner.tossJunk("down")
dropoff()
end
print("Going to shaft location")
local pos = go.getPos()
local dropoff = config.get("dropoff")
if pos.x == dropoff.x and pos.z == dropoff.z then
go.goto(nil,nil,pos.z+1) -- don't break fuel chest
end
go.goto(shaft.x,65,shaft.z+2) -- attempt to prevent turtles breaking eachother by having turtles use different Y levels
go.goto(nil,64,nil)
config.set("state","mining")
end
end
if config.get("state", "prep") == "mining" then
miner.mineShaft()
miner.tossJunk("down")
local ok, err = markFinished(config.get("shaft"), config.get("host"), config.get("swarmname"), config.get("authtoken"))
if not ok and err == "no response" then
while not ok and err == "no response" do
print("Server not responding. Retrying in 120 seconds.")
sleep(120)
ok, err = markFinished(config.get("shaft"), config.get("host"), config.get("swarmname"), config.get("authtoken"))
end
end
config.set("shaft",nil)
config.set("state","prep")
end
if config.get("state","prep") == "done" then
-- mining complete, clean up and uninstall
print("Quarry complete, dropping off items and uninstalling.")
go.goto(config.get("dropoff"))
miner.tossJunk("down")
dropoff(true)
-- uninstall
fs.delete(".position")
fs.delete(".swarmconfig")
fs.delete("miner")
fs.delete("json")
fs.delete("relgo")
fs.delete("config")
fs.delete("startup")
fs.delete("swarm")
print("Uninstall completed.")
break
end
end
else
error("Corrupt or missing config file, program cannot continue")
end