-- 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)
Comments
0 B
|👍
/👎