CCCPaste

minecraft_cc_tweek_mineing_ws

-- Configuration Settings
local serverUrl = "wss://://yourdomain.com" 
local token = "your_secure_secret_token"    
local FUEL_LIMIT = 400                      

-- 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 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
        return true
    end
    return false
end

local function trackDown()
    while turtle.detectDown() do turtle.digDown() end
    if turtle.down() then
        currentZ = currentZ - 1
        return true
    end
    return false
end

local function trackUp()
    while turtle.detectUp() do turtle.digUp() end
    if turtle.up() then
        currentZ = currentZ + 1
        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 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

local function checkFuelSafety()
    if turtle.getFuelLevel() == "unlimited" then return true end
    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
    
    -- Handle Initial Shift Alignment only if we haven't started mining yet
    if savedX == 1 and savedY == 1 and savedZ == 1 then
        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)

    -- Resume directly from the saved structural pointers
    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 connection drops out, wait right here until ws is alive again!
                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 -- Reset row index for next sequence loop line
            
            if y < targetY then
                if y % 2 == 1 then
                    trackTurnRight()
                    trackForward()
                    trackTurnRight()
                else
                    trackTurnLeft()
                    trackForward()
                    trackTurnLeft()
                end
            end
        end
        savedY = 1 -- Reset grid column index for next depth drop
        
        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 -- Reset step pointers
                        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

-- Fire up networking threads and engine workers side-by-side
parallel.waitForAll(listenToNetwork, jobWorker)