updater.lua

558 lines · 16.2 KB

Open raw

MAENGORN UPDATER

Copy & run

wget https://perlytiara.github.io/turtles.tips/raw/programs/perlytiara/Maengorn/updater.lua
1-- MAENGORN UPDATER
2-- Auto-updates programs based on turtle type detection
3-- Supports disk drive, phone, and master turtle configurations
4
5local w, h = term.getSize()
6local currentPage = 1
7local totalPages = 1
8local lines = {}
9local turtleType = "unknown"
10local selectedOption = 1
11local maxOptions = 5
12local startOption = 1
13local optionsPerPage = 5
14local installPath = "programs/perlytiara/Maengorn/"
15local useExtension = true
16local settingsFile = ".maengorn_settings"
17
18-- Colors for better UI
19local colors = {
20 white = colors.white,
21 gray = colors.gray,
22 black = colors.black,
23 blue = colors.blue,
24 green = colors.green,
25 red = colors.red,
26 yellow = colors.yellow,
27 orange = colors.orange
28}
29
30-- Repository configuration
31local REPO_BASE = "https://raw.githubusercontent.com/perlytiara/CC-Tweaked-TurtsAndComputers/refs/heads/main/programs/perlytiara/Maengorn/"
32local PROGRAMS_FOLDER = "programs/perlytiara/Maengorn/"
33
34-- Program definitions by turtle type
35local PROGRAM_CONFIGS = {
36 disk_drive = {
37 name = "Disk Drive",
38 programs = {
39 {name = "startup", file = "startup.lua", description = "Startup script"},
40 {name = "clientdig", file = "clientdig.lua", description = "Client mining"}
41 }
42 },
43 phone = {
44 name = "Phone Turtle",
45 programs = {
46 {name = "phone_server", file = "phone_server.lua", description = "Phone server"}
47 }
48 },
49 master = {
50 name = "Master Turtle",
51 programs = {
52 {name = "mineserver", file = "mineserver.lua", description = "Mining server"}
53 }
54 },
55 all = {
56 name = "All Programs",
57 programs = {
58 {name = "startup", file = "startup.lua", description = "Startup script"},
59 {name = "clientdig", file = "clientdig.lua", description = "Client mining"},
60 {name = "phone_server", file = "phone_server.lua", description = "Phone server"},
61 {name = "mineserver", file = "mineserver.lua", description = "Mining server"},
62 {name = "gps-deploy", file = "gps-deploy.lua", description = "GPS deployment"},
63 {name = "updater", file = "updater.lua", description = "This updater"}
64 }
65 }
66}
67
68-- Utility functions
69function loadSettings()
70 if fs.exists(settingsFile) then
71 local file = fs.open(settingsFile, "r")
72 if file then
73 local content = file.readAll()
74 file.close()
75
76 -- Parse settings from file
77 for line in content:gmatch("[^\r\n]+") do
78 if line:match("^installPath=") then
79 installPath = line:match("installPath=(.+)")
80 elseif line:match("^useExtension=") then
81 useExtension = line:match("useExtension=(.+)") == "true"
82 end
83 end
84 end
85 end
86end
87
88function saveSettings()
89 local file = fs.open(settingsFile, "w")
90 if file then
91 file.write("installPath=" .. installPath .. "\n")
92 file.write("useExtension=" .. tostring(useExtension) .. "\n")
93 file.close()
94 end
95end
96
97function detectTurtleType()
98 -- Check if we have a disk drive (disk drive turtles have disk access)
99 if fs.exists("disk/") then
100 return "disk_drive"
101 end
102
103 -- Check if we have mining server programs (master turtle)
104 if fs.exists("mineserver.lua") or fs.exists(PROGRAMS_FOLDER .. "mineserver.lua") then
105 return "master"
106 end
107
108 -- Check if we have phone server programs (phone turtle)
109 if fs.exists("phone_server.lua") or fs.exists(PROGRAMS_FOLDER .. "phone_server.lua") then
110 return "phone"
111 end
112
113 -- Default to all if we can't determine
114 return "all"
115end
116
117function clearScreen()
118 term.clear()
119 term.setCursorPos(1, 1)
120end
121
122function centerText(text, y)
123 local x = math.floor((w - string.len(text)) / 2) + 1
124 if x < 1 then x = 1 end
125 term.setCursorPos(x, y)
126 write(text)
127end
128
129function drawHeader()
130 term.setTextColor(colors.blue)
131 centerText("===================", 1)
132 centerText(" MAENGORN UPDATER ", 2)
133 centerText("===================", 3)
134 term.setTextColor(colors.white)
135end
136
137function drawFooter()
138 local y = h
139 term.setTextColor(colors.gray)
140 term.setCursorPos(1, y)
141 write("Arrows:Navigate | Enter:Select | Q:Quit")
142end
143
144function highlightOption(optionNum, text, y)
145 if optionNum == selectedOption then
146 term.setTextColor(colors.black)
147 term.setBackgroundColor(colors.white)
148 term.setCursorPos(2, y)
149 write("> " .. text)
150 term.setTextColor(colors.white)
151 term.setBackgroundColor(colors.black)
152 else
153 term.setTextColor(colors.blue)
154 term.setCursorPos(2, y)
155 write(" " .. text)
156 end
157end
158
159function splitText(text, width)
160 local words = {}
161 for word in text:gmatch("%S+") do
162 table.insert(words, word)
163 end
164
165 local lines = {}
166 local currentLine = ""
167
168 for _, word in ipairs(words) do
169 if string.len(currentLine .. " " .. word) <= width then
170 if currentLine == "" then
171 currentLine = word
172 else
173 currentLine = currentLine .. " " .. word
174 end
175 else
176 if currentLine ~= "" then
177 table.insert(lines, currentLine)
178 currentLine = word
179 else
180 table.insert(lines, word)
181 end
182 end
183 end
184
185 if currentLine ~= "" then
186 table.insert(lines, currentLine)
187 end
188
189 return lines
190end
191
192function displayText(text, startY)
193 lines = splitText(text, w - 2)
194 totalPages = math.max(1, math.ceil(#lines / (h - startY - 2)))
195
196 local startLine = (currentPage - 1) * (h - startY - 2) + 1
197 local endLine = math.min(startLine + (h - startY - 2) - 1, #lines)
198
199 for i = startLine, endLine do
200 if lines[i] then
201 term.setCursorPos(2, startY + (i - startLine))
202 write(lines[i])
203 end
204 end
205end
206
207function downloadProgram(programInfo, description)
208 local url = REPO_BASE .. programInfo.file
209 local finalPath = installPath .. programInfo.name
210 if useExtension then
211 finalPath = finalPath .. ".lua"
212 end
213
214 -- Ensure install folder exists
215 local pathParts = {}
216 for part in installPath:gmatch("[^/]+") do
217 table.insert(pathParts, part)
218 end
219
220 local currentPath = ""
221 for _, part in ipairs(pathParts) do
222 currentPath = currentPath .. part .. "/"
223 if not fs.exists(currentPath) then
224 fs.makeDir(currentPath)
225 end
226 end
227
228 -- Remove old file if it exists
229 if fs.exists(finalPath) then
230 fs.delete(finalPath)
231 end
232
233 clearScreen()
234 drawHeader()
235
236 term.setTextColor(colors.yellow)
237 centerText("Downloading: " .. programInfo.name, 5)
238 term.setTextColor(colors.white)
239
240 term.setCursorPos(2, 7)
241 write("From: " .. url)
242 term.setCursorPos(2, 8)
243 write("To: " .. finalPath)
244 term.setCursorPos(2, 9)
245 write("Desc: " .. description)
246
247 term.setTextColor(colors.blue)
248 term.setCursorPos(2, 11)
249 write("Status: Downloading...")
250
251 -- Download the file
252 local success, errorMsg = pcall(function()
253 shell.run("wget", url, finalPath)
254 end)
255
256 if success then
257 term.setTextColor(colors.green)
258 term.setCursorPos(2, 11)
259 write("Status: Success!")
260 else
261 term.setTextColor(colors.red)
262 term.setCursorPos(2, 11)
263 write("Status: Failed!")
264 term.setCursorPos(2, 12)
265 write("Error: " .. tostring(errorMsg))
266 end
267
268 term.setTextColor(colors.white)
269 term.setCursorPos(2, h - 1)
270 write("Press any key...")
271 os.pullEvent("key")
272end
273
274function showMainMenu()
275 clearScreen()
276 drawHeader()
277
278 term.setTextColor(colors.green)
279 term.setCursorPos(2, 5)
280 write("Type: " .. turtleType)
281
282 term.setTextColor(colors.white)
283 term.setCursorPos(2, 6)
284 write("Options:")
285
286 local y = 8
287 local config = PROGRAM_CONFIGS[turtleType]
288
289 -- Option 1: Update detected turtle type programs
290 if config then
291 highlightOption(1, "Update " .. config.name, y)
292 else
293 highlightOption(1, "Update Detected", y)
294 end
295 y = y + 1
296
297 -- Option 2: Update all programs
298 highlightOption(2, "Update All", y)
299 y = y + 1
300
301 -- Option 3: Manual selection
302 highlightOption(3, "Manual Select", y)
303 y = y + 1
304
305 -- Option 4: Settings
306 highlightOption(4, "Settings", y)
307 y = y + 1
308
309 -- Option 5: Exit
310 highlightOption(5, "Exit", y)
311
312 drawFooter()
313end
314
315function updatePrograms(config)
316 clearScreen()
317 drawHeader()
318
319 term.setTextColor(colors.yellow)
320 centerText("Updating " .. config.name .. " Programs", 5)
321 term.setTextColor(colors.white)
322
323 for i, program in ipairs(config.programs) do
324 term.setCursorPos(2, 7 + (i - 1) * 2)
325 write(string.format("[%d/%d] %s", i, #config.programs, program.file))
326
327 downloadProgram(program.file, program.description)
328 end
329
330 clearScreen()
331 drawHeader()
332 term.setTextColor(colors.green)
333 centerText("All programs updated successfully!", 5)
334 term.setTextColor(colors.white)
335 term.setCursorPos(2, 7)
336 write("Press any key to return to main menu...")
337 os.pullEvent("key")
338end
339
340function showManualSelection()
341 local programs = PROGRAM_CONFIGS.all.programs
342 local manualSelectedOption = 1
343
344 while true do
345 clearScreen()
346 drawHeader()
347
348 term.setTextColor(colors.yellow)
349 centerText("Manual Select", 5)
350 term.setTextColor(colors.white)
351
352 local y = 7
353
354 -- Show all programs (compact for small screens)
355 for i, program in ipairs(programs) do
356 if i == manualSelectedOption then
357 -- Show selected option with highlighting
358 term.setTextColor(colors.black)
359 term.setBackgroundColor(colors.white)
360 term.setCursorPos(2, y)
361 write("> " .. program.name)
362 term.setTextColor(colors.white)
363 term.setBackgroundColor(colors.black)
364 else
365 -- Show unselected option
366 term.setTextColor(colors.blue)
367 term.setCursorPos(2, y)
368 write(" " .. program.name)
369 end
370 y = y + 1
371 end
372
373 -- Footer
374 term.setTextColor(colors.gray)
375 term.setCursorPos(1, h)
376 write("Arrows:Navigate | Enter:Select | Q:Back")
377
378 local event, key = os.pullEvent("key")
379
380 if key == keys.q or key == keys.escape then
381 return
382 elseif key == keys.up then
383 if manualSelectedOption > 1 then
384 manualSelectedOption = manualSelectedOption - 1
385 end
386 elseif key == keys.down then
387 if manualSelectedOption < #programs then
388 manualSelectedOption = manualSelectedOption + 1
389 end
390 elseif key == keys.enter then
391 downloadProgram(programs[manualSelectedOption], programs[manualSelectedOption].description)
392 return
393 end
394 end
395end
396
397function showSettings()
398 local settingsSelected = 1
399 local maxSettings = 3
400
401 while true do
402 clearScreen()
403 drawHeader()
404
405 term.setTextColor(colors.yellow)
406 centerText("Settings", 5)
407 term.setTextColor(colors.white)
408
409 term.setCursorPos(2, 7)
410 write("Install Path: " .. installPath)
411 term.setCursorPos(2, 8)
412 write("Use .lua extension: " .. (useExtension and "Yes" or "No"))
413 term.setCursorPos(2, 9)
414 write("Current: " .. turtleType)
415
416 local y = 11
417 if settingsSelected == 1 then
418 highlightOption(1, "Change Install Path", y)
419 else
420 term.setTextColor(colors.blue)
421 term.setCursorPos(2, y)
422 write("Change Install Path")
423 end
424 y = y + 1
425
426 if settingsSelected == 2 then
427 highlightOption(2, "Toggle .lua Extension", y)
428 else
429 term.setTextColor(colors.blue)
430 term.setCursorPos(2, y)
431 write("Toggle .lua Extension")
432 end
433 y = y + 1
434
435 if settingsSelected == 3 then
436 highlightOption(3, "Back to Menu", y)
437 else
438 term.setTextColor(colors.blue)
439 term.setCursorPos(2, y)
440 write("Back to Menu")
441 end
442
443 term.setTextColor(colors.gray)
444 term.setCursorPos(1, h)
445 write("Arrows:Navigate | Enter:Select | Q:Back")
446
447 local event, key = os.pullEvent("key")
448
449 if key == keys.q or key == keys.escape then
450 return
451 elseif key == keys.up then
452 if settingsSelected > 1 then
453 settingsSelected = settingsSelected - 1
454 end
455 elseif key == keys.down then
456 if settingsSelected < maxSettings then
457 settingsSelected = settingsSelected + 1
458 end
459 elseif key == keys.enter then
460 if settingsSelected == 1 then
461 clearScreen()
462 drawHeader()
463 term.setTextColor(colors.white)
464 term.setCursorPos(2, 5)
465 write("Enter install path:")
466 term.setCursorPos(2, 6)
467 write("(e.g., programs/myfolder/ or just /)")
468 term.setCursorPos(2, 8)
469 write("Current: " .. installPath)
470 term.setCursorPos(2, 10)
471 write("New path: ")
472 local newPath = read()
473 if newPath and newPath ~= "" then
474 installPath = newPath
475 if not installPath:match("/$") then
476 installPath = installPath .. "/"
477 end
478 saveSettings()
479 end
480 elseif settingsSelected == 2 then
481 useExtension = not useExtension
482 saveSettings()
483 elseif settingsSelected == 3 then
484 return
485 end
486 end
487 end
488end
489
490function main()
491 -- Load saved settings
492 loadSettings()
493
494 -- Detect turtle type
495 turtleType = detectTurtleType()
496
497 while true do
498 showMainMenu()
499
500 local event, key = os.pullEvent("key")
501
502 if key == keys.q or key == keys.escape then
503 clearScreen()
504 term.setCursorPos(1, 1)
505 return
506 elseif key == keys.up then
507 if selectedOption > 1 then
508 selectedOption = selectedOption - 1
509 -- Adjust scrolling window if needed
510 local availableHeight = h - 10
511 local optionHeight = 3
512 local maxVisibleOptions = math.floor(availableHeight / optionHeight)
513
514 if selectedOption < startOption then
515 startOption = selectedOption
516 end
517
518 showMainMenu()
519 end
520 elseif key == keys.down then
521 if selectedOption < maxOptions then
522 selectedOption = selectedOption + 1
523 -- Adjust scrolling window if needed
524 local availableHeight = h - 10
525 local optionHeight = 3
526 local maxVisibleOptions = math.floor(availableHeight / optionHeight)
527
528 if selectedOption > startOption + maxVisibleOptions - 1 then
529 startOption = selectedOption - maxVisibleOptions + 1
530 end
531
532 showMainMenu()
533 end
534 elseif key == keys.enter then
535 if selectedOption == 1 then
536 local config = PROGRAM_CONFIGS[turtleType]
537 if config then
538 updatePrograms(config)
539 end
540 elseif selectedOption == 2 then
541 updatePrograms(PROGRAM_CONFIGS.all)
542 elseif selectedOption == 3 then
543 showManualSelection()
544 elseif selectedOption == 4 then
545 showSettings()
546 elseif selectedOption == 5 then
547 clearScreen()
548 term.setCursorPos(1, 1)
549 return
550 end
551 end
552 end
553end
554
555-- Start the updater
556main()
557
558