server-phone.lua

236 lines · 6.4 KB

Open raw

PHONE SERVER--

Copy & run

wget https://perlytiara.github.io/turtles.tips/raw/programs/perlytiara/BigBaemingGamers/server/server-phone.lua
1--PHONE SERVER--
2
3local SERVER_PORT = 420
4local CLIENT_PORT = 0
5local SLOT_COUNT = 16
6
7
8local segmentation = 5
9if (#arg == 1) then
10 segmentation = tonumber(arg[1])
11elseif (#arg == 0) then
12 print(string.format("No segmentation size selected, defaulting to %d", segmentation))
13else
14 print('Too many args given...')
15 exit(1)
16end
17
18
19local modem = peripheral.wrap("left")
20modem.open(SERVER_PORT)
21
22local target = vector.new()
23local size = vector.new()
24local finish = vector.new()
25
26-- I STOLE --
27function split (inputstr, sep)
28 if sep == nil then
29 sep = "%s"
30 end
31 local t={}
32 for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
33 table.insert(t, str)
34 end
35 return t
36end
37
38function parseParams(data)
39 coords = {}
40 params = split(data, " ")
41
42 coords[1] = vector.new(params[1], params[2], params[3])
43 coords[2] = vector.new(params[4], params[5], params[6])
44
45 return (coords)
46end
47
48function getItemIndex(itemName)
49 for slot = 1, SLOT_COUNT, 1 do
50 local item = turtle.getItemDetail(slot)
51 if(item ~= nil) then
52 if(item["name"] == itemName) then
53 return slot
54 end
55 end
56 end
57end
58
59-- Try multiple candidate item ids; returns first slot found or nil
60function getFirstItemIndex(candidates)
61 for i = 1, #candidates, 1 do
62 local idx = getItemIndex(candidates[i])
63 if idx ~= nil then return idx end
64 end
65 return nil
66end
67
68function checkFuel()
69 turtle.select(1)
70
71 if(turtle.getFuelLevel() < 50) then
72 print("Attempting Refuel...")
73 for slot = 1, SLOT_COUNT, 1 do
74 turtle.select(slot)
75 if(turtle.refuel(1)) then
76 return true
77 end
78 end
79 return false
80 else
81 return true
82 end
83end
84
85function deployFuelChest()
86 if (not checkFuel()) then
87 print("SERVER NEEDS FUEL...")
88 exit(1)
89 end
90 local chestIdx = getItemIndex("enderstorage:ender_storage")
91 if chestIdx == nil then
92 print("WARN: No EnderStorage found for fuel chest; skipping fuel chest deploy.")
93 return
94 end
95 turtle.select(chestIdx)
96 turtle.up()
97 turtle.place()
98 turtle.down()
99end
100
101
102function deploy(startCoords, quarySize, endCoords, options)
103 --Place turtle from inventory
104 local turtleCandidates = {
105 "computercraft:turtle_advanced",
106 "computercraft:turtle_expanded",
107 "computercraft:turtle_normal",
108 }
109 local turtleSlot = getFirstItemIndex(turtleCandidates)
110 if turtleSlot == nil then
111 print("ERROR: No turtle item found in inventory. Place advanced/normal turtle in inventory.")
112 os.exit(1)
113 end
114 turtle.select(turtleSlot)
115 while(turtle.detect()) do
116 os.sleep(0.3)
117 end
118
119 --Place and turn on turtle
120 turtle.place()
121 peripheral.call("front", "turnOn")
122
123
124 --Wait for client to send ping
125 event, side, senderChannel, replyChannel, msg, distance = os.pullEvent("modem_message")
126 if(msg ~= "CLIENT_DEPLOYED") then
127 print("No client deploy message, exitting...")
128 os.exit()
129 end
130
131
132 if(options["withStorage"]) then
133 --Set up ender chest
134 if (not checkFuel()) then
135 print("SERVER NEEDS FUEL...")
136 exit(1)
137 end
138 local chestIdx = getItemIndex("enderstorage:ender_storage")
139 if chestIdx ~= nil then
140 turtle.select(chestIdx)
141 turtle.up()
142 turtle.place()
143 turtle.down()
144 else
145 print("WARN: withStorage requested but no EnderStorage in inventory; continuing without storage for this bot.")
146 end
147 end
148
149 deployFuelChest()
150 local storageBit = options["withStorage"] and 1 or 0
151
152 -- Client is deployed
153 modem.transmit(CLIENT_PORT,
154 SERVER_PORT,
155 string.format("%d %d %d %d %d %d %d %d %d %d",
156 startCoords.x, startCoords.y, startCoords.z,
157 quarySize.x, quarySize.y, quarySize.z,
158 endCoords.x, endCoords.y, endCoords.z,
159 storageBit
160 ))
161end
162
163
164
165-- Return array of arbitrary size for each bot placement
166function getPositioningTable(x, z, segmaentationSize)
167 local xRemainder = x % segmaentationSize
168 local zRemainder = z % segmaentationSize
169
170 local xMain = x - xRemainder
171 local zMain = z - zRemainder
172
173 xRemainder = (xRemainder == 0 and segmaentationSize or xRemainder)
174 zRemainder = (zRemainder == 0 and segmaentationSize or zRemainder)
175
176 local positions = {}
177
178 for zi = 0, z - 1 , segmaentationSize do
179 for xi = 0, x - 1, segmaentationSize do
180
181 local dims = {xi, zi, segmaentationSize, segmaentationSize}
182 if(xi >= x - segmaentationSize and xi <= x - 1 ) then
183 dims = {xi, zi, xRemainder, segmaentationSize}
184 end
185
186 if(zi >= z - segmaentationSize and zi <= z - 1 ) then
187 dims = {xi, zi, segmaentationSize, zRemainder}
188 end
189
190 table.insert(positions, dims)
191 end
192 end
193
194 return table.pack(positions, xRemainder, zRemainder)
195end
196
197while (true) do
198 -- Wait for phone
199 print("Waiting for target signal...")
200 event, side, senderChannel, replyChannel, msg, distance = os.pullEvent("modem_message")
201
202 -- Parse out coordinates and options
203 local args = split(msg, " ")
204 local withStorageBit = args[#args]
205 local withStorage = (withStorageBit == "1")
206 data = parseParams(msg)
207 options = {}
208 options["withStorage"] = withStorage
209
210 target = data[1]
211 size = data[2]
212
213 finish = vector.new(gps.locate())
214 finish.y = finish.y + 1
215 print(string.format( "RECEIVED QUARY REQUEST AT: %d %d %d", target.x, target.y, target.z))
216
217 tab, xDf, zDf = table.unpack(getPositioningTable(size.x, size.z, segmentation))
218
219 print(string.format("Deploying %d bots...", #tab))
220 for i = 1, #tab, 1 do
221 xOffset, zOffset, width, height = table.unpack(tab[i])
222 local offsetTarget = vector.new(target.x + xOffset, target.y, target.z + zOffset)
223 local sclaedSize = vector.new(width, size.y, height)
224
225 deploy(offsetTarget, sclaedSize, finish, options)
226 os.sleep(1)
227 print(string.format( "Deploying to; %d %d %d %d %d", target.x + xOffset, target.y, target.z + zOffset, sclaedSize.x, sclaedSize.z))
228 end
229
230 -- All bots deployed, wait for last bot finished signal
231 event, side, senderChannel, replyChannel, msg, distance = os.pullEvent("modem_message")
232 turtle.digUp()
233
234end
235
236