Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Configuration Settings
- local serverUrl = "wss://://yourdomain.com"
- local token = "your_secure_secret_token"
- local FUEL_LIMIT = 400
- local FORWARD_BUFFER = 4 -- Blocks to travel forward safely BEFORE mining starts
- -- Operational & Spatial State Tracking
- local turtleId = tostring(os.computerID())
- local idNum = os.computerID()
- local ws = nil
- local stopRequested = false
- local lastHeartbeat = os.epoch("utc")
- -- Saved State for Resumption
- local jobActive = false
- local targetX, targetY, targetZ = 0, 0, 0
- local savedX, savedY, savedZ = 1, 1, 1
- -- Relative Position Tracking Matrix
- local currentX, currentY, currentZ = 0, 0, 0
- local currentDir = 0 -- 0=Forward (+X), 1=Right (+Y), 2=Back (-X), 3=Left (-Y)
- local function getFullSlots()
- local fullCount = 0
- for i = 1, 16 do if turtle.getItemCount(i) > 0 then fullCount = fullCount + 1 end end
- return fullCount
- end
- local function getTelemetry(currentStatus)
- return {
- fuel = turtle.getFuelLevel(),
- maxFuel = turtle.getFuelLimit(),
- inventorySlots = getFullSlots(),
- status = currentStatus or "Idle",
- pos = {x = currentX, y = currentY, z = currentZ}
- }
- end
- local function sendUpdate(status, logMessage)
- if ws then
- pcall(function()
- ws.send(textutils.serializeJSON({
- type = "telemetry",
- turtleId = turtleId,
- data = getTelemetry(status),
- logMessage = logMessage
- }))
- end)
- end
- end
- -- NEW & IMPROVED: Constant Automatic Refueling Hook
- local function autoRefuel()
- if turtle.getFuelLevel() == "unlimited" then return end
- -- Only consume items if we are below our maximum fuel capacity limit
- if turtle.getFuelLevel() < turtle.getFuelLimit() then
- local currentFuel = turtle.getFuelLevel()
- for i = 1, 16 do
- turtle.select(i)
- -- Check if slot has a fuel item without consuming it yet
- if turtle.refuel(0) then
- -- If we are critically low, eat everything.
- -- Otherwise, only eat if we have room so we don't waste fuel points.
- if currentFuel < FUEL_LIMIT or (turtle.getFuelLevel() < (turtle.getFuelLimit() - 80)) then
- local before = turtle.getFuelLevel()
- turtle.refuel(turtle.getItemCount(i)) -- Eat the stack!
- local gained = turtle.getFuelLevel() - before
- sendUpdate(nil, "Auto-Refuel: Consumed items from slot " .. i .. ". Added +" .. gained .. " fuel.")
- end
- end
- end
- turtle.select(1) -- Always default selection box back to slot 1
- end
- end
- -- Navigation Wrappers
- local function trackTurnRight()
- turtle.turnRight()
- currentDir = (currentDir + 1) % 4
- end
- local function trackTurnLeft()
- turtle.turnLeft()
- currentDir = (currentDir - 1) % 4
- end
- local function trackForward()
- while turtle.detect() do
- turtle.dig()
- os.sleep(0.4)
- end
- if turtle.forward() then
- if currentDir == 0 then currentX = currentX + 1
- elseif currentDir == 1 then currentY = currentY + 1
- elseif currentDir == 2 then currentX = currentX - 1
- elseif currentDir == 3 then currentY = currentY - 1
- end
- autoRefuel() -- Automatically scan and eat any fuel mined up or collected immediately
- return true
- end
- return false
- end
- local function trackDown()
- while turtle.detectDown() do turtle.digDown() end
- if turtle.down() then
- currentZ = currentZ - 1
- autoRefuel()
- return true
- end
- return false
- end
- local function trackUp()
- while turtle.detectUp() do turtle.digUp() end
- if turtle.up() then
- currentZ = currentZ + 1
- autoRefuel()
- return true
- end
- return false
- end
- local function navigateHome()
- sendUpdate("Returning Home", "Initiating return path tracking sequence to base dock.")
- while currentZ < 0 do trackUp() end
- while currentZ > 0 do trackDown() end
- if currentY > 0 then
- while currentDir ~= 3 do trackTurnRight() end
- while currentY > 0 do trackForward() end
- elseif currentY < 0 then
- while currentDir ~= 1 do trackTurnRight() end
- while currentY < 0 do trackForward() end
- end
- if currentX > 0 then
- while currentDir ~= 2 do trackTurnRight() end
- while currentX > 0 do trackForward() end
- end
- while currentDir ~= 0 do trackTurnRight() end
- sendUpdate("Idle", "Successfully docked at home station.")
- jobActive = false
- end
- local function checkFuelSafety()
- if turtle.getFuelLevel() == "unlimited" then return true end
- -- Always try to eat fuel right before checking safety values
- autoRefuel()
- local distanceHome = math.abs(currentX) + math.abs(currentY) + math.abs(currentZ)
- local absoluteMinimumNeeded = distanceHome + 5
- if turtle.getFuelLevel() <= absoluteMinimumNeeded then
- sendUpdate("Low Fuel Return", "Critical fuel fallback reached. Heading home.")
- navigateHome()
- return false
- end
- return true
- end
- -- Resumable Mining Engine Loop
- local function executeMiningJob()
- stopRequested = false
- if savedX == 1 and savedY == 1 and savedZ == 1 then
- sendUpdate("Buffer Transit", "Moving forward past the " .. FORWARD_BUFFER .. " block safety buffer zone.")
- for i = 1, FORWARD_BUFFER do
- if not checkFuelSafety() then return end
- trackForward()
- end
- local myOffsetSequence = (idNum - 1) * targetY
- if myOffsetSequence > 0 then
- sendUpdate("Positioning", "Shifting right by " .. myOffsetSequence .. " blocks to align team row.")
- trackTurnRight()
- for i = 1, myOffsetSequence do trackForward() end
- trackTurnLeft()
- end
- end
- sendUpdate("Mining Grid Active", "Resuming/Starting sector clearing: " .. targetX .. "x" .. targetY .. "x" .. targetZ)
- for z = savedZ, targetZ do
- savedZ = z
- for y = savedY, targetY do
- savedY = y
- for x = savedX, targetX - 1 do
- savedX = x
- os.sleep(0.05)
- if not ws then
- sendUpdate("Reconnecting", "Connection lost! Pausing mining operation until server is online...")
- print("Lost server handshake. Freezing task loop until reconnected...")
- while not ws do os.sleep(1) end
- lastHeartbeat = os.epoch("utc")
- sendUpdate("Mining Grid Active", "Connection restored! Resuming task.")
- end
- if stopRequested then
- sendUpdate("Aborted", "Halted by backend request.")
- navigateHome()
- return
- end
- if getFullSlots() >= 16 then
- sendUpdate("Returning Base", "Inventory full.")
- navigateHome()
- return
- end
- if not checkFuelSafety() then return end
- trackForward()
- end
- savedX = 1
- if y < targetY then
- if y % 2 == 1 then
- trackTurnRight()
- trackForward()
- trackTurnRight()
- else
- trackTurnLeft()
- trackForward()
- trackTurnLeft()
- end
- end
- end
- savedY = 1
- if z < targetZ then
- trackDown()
- trackTurnRight()
- trackTurnRight()
- end
- end
- navigateHome()
- end
- local function connect()
- print("Connecting to Central Control...")
- local success, socketOrErr = pcall(http.websocket, serverUrl)
- if not success or not socketOrErr then return false end
- ws = socketOrErr
- ws.send(textutils.serializeJSON({
- type = "handshake",
- token = token,
- turtleId = turtleId,
- data = getTelemetry(jobActive and "Mining Grid Active" or "Online")
- }))
- lastHeartbeat = os.epoch("utc")
- print("Connected safely.")
- return true
- end
- -- Global parallel handler threads
- local function listenToNetwork()
- while true do
- if not ws then
- if not connect() then os.sleep(5) end
- else
- local event, url, msg = os.pullEvent()
- if event == "websocket_message" then
- lastHeartbeat = os.epoch("utc")
- local success, payload = pcall(textutils.unserializeJSON, msg)
- if success and payload then
- if payload.command == "excavate" and not jobActive then
- targetX = payload.args.x
- targetY = payload.args.y
- targetZ = payload.args.z
- savedX, savedY, savedZ = 1, 1, 1
- jobActive = true
- elseif payload.command == "stop" then
- stopRequested = true
- end
- end
- elseif event == "websocket_closed" then
- ws = nil
- print("WebSocket closed by proxy.")
- end
- end
- end
- end
- local function jobWorker()
- while true do
- if jobActive then
- executeMiningJob()
- end
- os.sleep(1)
- end
- end
- parallel.waitForAll(listenToNetwork, jobWorker)
Advertisement