Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Node Script
- -- Variables
- local PROTOCOL = "mobFarm"
- local LOCAL_ID = "MOB_" .. os.getComputerID()
- local status = "STOPPED"
- local cID = nil -- Controller ID
- local startDelay = 3
- local stopDelay = 0
- local delay = 0
- local monitor = peripheral.wrap("front")
- local REDSTONE_BACK = "back" -- Lights
- local REDSTONE_RIGHT = "left" -- Fans and grinder
- local version = "1.0.4" -- Version of the startup.lua
- -- Ensure update.lua exists with version and Pastebin checks
- local pastebinID = "8DnZvWtP" -- Pastebin ID for update.lua
- local pastebinURL = "https://pastebin.com/raw/" .. pastebinID
- local updateScriptName = "update.lua"
- local localVersionFile = "update_version.txt" -- File to store the local version
- -- Function to check if the Pastebin file exists
- local function checkPastebinFileExists()
- print("Checking if Pastebin file exists...")
- local response = http.get(pastebinURL)
- if response then
- response.close()
- print("Pastebin file exists.")
- return true
- else
- print("Pastebin file does not exist or cannot be accessed.")
- return false
- end
- end
- -- Function to read the local version of update.lua
- local function readLocalVersion()
- if fs.exists(localVersionFile) then
- local file = fs.open(localVersionFile, "r")
- local version = file.readLine()
- file.close()
- return version
- else
- return nil -- No local version exists
- end
- end
- -- Function to write the local version of update.lua
- local function writeLocalVersion(version)
- local file = fs.open(localVersionFile, "w")
- file.writeLine(version)
- file.close()
- end
- -- Function to fetch the remote version from Pastebin
- local function fetchRemoteVersion()
- print("Fetching remote version from Pastebin...")
- local response = http.get(pastebinURL)
- if response then
- local content = response.readAll()
- response.close()
- -- Extract the version from the script content
- local remoteVersion = content:match('local version%s*=%s*"(.-)"')
- if remoteVersion then
- print("Remote version found: " .. remoteVersion)
- return remoteVersion
- else
- print("Failed to extract version from remote script.")
- return nil
- end
- else
- print("Failed to fetch remote script. Check network or Pastebin ID.")
- return nil
- end
- end
- -- Function to compare versions
- local function isUpdateRequired(localVersion, remoteVersion)
- if not localVersion then
- print("No local version found. Update required.")
- return true
- end
- if localVersion ~= remoteVersion then
- print("Version mismatch: Local (" .. localVersion .. ") vs Remote (" .. remoteVersion .. "). Update required.")
- return true
- else
- print("Local version (" .. localVersion .. ") is up-to-date.")
- return false
- end
- end
- -- Main logic to ensure update.lua exists and is up-to-date
- print("Checking update.lua...")
- -- Check if the Pastebin file exists
- if not checkPastebinFileExists() then
- print("Pastebin file does not exist. Aborting check.")
- end
- -- Read local version
- local localVersion = readLocalVersion()
- -- Fetch remote version
- local remoteVersion = fetchRemoteVersion()
- -- Check if an update is required
- if remoteVersion and isUpdateRequired(localVersion, remoteVersion) then
- -- Remove outdated update.lua
- if fs.exists(updateScriptName) then
- print("Removing outdated " .. updateScriptName)
- fs.delete(updateScriptName)
- end
- -- Download the new update.lua
- print("Downloading updated " .. updateScriptName .. " from Pastebin...")
- local success = shell.run("pastebin get " .. pastebinID .. " " .. updateScriptName)
- if success then
- print(updateScriptName .. " downloaded successfully.")
- -- Write the new version to the local version file
- writeLocalVersion(remoteVersion)
- else
- print("Failed to download " .. updateScriptName .. ". Please check the Pastebin ID or your connection.")
- end
- else
- print(updateScriptName .. " is up-to-date. No action required.")
- end
- -- Peripherals
- peripheral.find("modem", rednet.open)
- rednet.host(PROTOCOL, LOCAL_ID)
- -- Helper Functions
- local function setRedstoneOutput(side, state)
- redstone.setOutput(side, state)
- end
- local function toggleLights(state)
- setRedstoneOutput(REDSTONE_BACK, state)
- end
- local function toggleFans(state)
- sleep(delay) -- Delay for fans
- setRedstoneOutput(REDSTONE_RIGHT, state)
- end
- local function updateMonitor(farmStatus)
- if not monitor then
- print("No monitor detected.")
- return
- end
- monitor.setTextScale(2)
- monitor.clear()
- monitor.setTextColor(colors.white)
- local bgColor = (farmStatus == "RUNNING") and colors.red or colors.green
- monitor.setBackgroundColor(bgColor)
- monitor.clear()
- local screenWidth, screenHeight = monitor.getSize()
- local centeredX = math.floor(screenWidth / 2)
- local centeredY = math.floor(screenHeight / 2)
- monitor.setCursorPos(centeredX - math.floor(#LOCAL_ID / 2), centeredY)
- monitor.write(LOCAL_ID)
- monitor.setCursorPos(centeredX - math.floor(#farmStatus / 2), centeredY+1)
- monitor.write(farmStatus)
- monitor.setBackgroundColor(colors.black)
- end
- local function toggleFarm()
- if status == "RUNNING" then
- print("Stopping farm...")
- delay = startDelay
- toggleLights(true)
- toggleFans(false)
- status = "STOPPED"
- else
- print("Starting farm...")
- delay = stopDelay
- toggleLights(false)
- toggleFans(true)
- status = "RUNNING"
- end
- updateMonitor(status)
- end
- local function validateStatus()
- local lightsState = redstone.getOutput(REDSTONE_BACK)
- local fansState = redstone.getOutput(REDSTONE_RIGHT)
- if lightsState == fansState then
- print("Error: Lights and fans in the same state. Resetting...")
- toggleLights(true)
- toggleFans(false)
- status = "STOPPED"
- else
- status = fansState and "RUNNING" or "STOPPED"
- end
- end
- local function sendStatus()
- validateStatus()
- local packet = {
- type = "status",
- hostName = LOCAL_ID,
- status = status
- }
- rednet.send(cID, packet, PROTOCOL)
- print("Sent status update:", textutils.serialize(packet))
- updateMonitor(status)
- end
- -- Restore redstone state explicitly based on the saved status
- local function restoreRedstoneState()
- if status == "RUNNING" then
- toggleLights(false)
- toggleFans(true)
- else
- toggleLights(true)
- toggleFans(false)
- end
- print("Redstone state restored to:", status)
- end
- -- Send immediate status update with handshake
- local function connectToController()
- while not cID do
- cID = rednet.lookup(PROTOCOL, "controller")
- if cID then
- print("Connected to controller (ID: " .. cID .. ")")
- rednet.send(cID, {
- type = "handshake",
- hostName = LOCAL_ID,
- status = status -- Include current status in the handshake
- }, PROTOCOL)
- restoreRedstoneState()
- else
- print("Controller not found. Retrying in 3 seconds...")
- sleep(3)
- end
- end
- end
- local function maintainConnection()
- while true do
- if cID then
- rednet.send(cID, {
- type = "handshake",
- hostName = LOCAL_ID,
- status = status -- Include current status in the handshake
- }, PROTOCOL)
- else
- connectToController()
- end
- sleep(5) -- Send handshakes every 5 seconds
- end
- end
- -- Storage Monitoring
- local function monitorStorage()
- local chest = peripheral.wrap("top") -- Ensure this matches your setup
- if not chest or not chest.list then
- print("No chest detected above. Skipping storage monitoring.")
- return
- end
- while true do
- local items = chest.list()
- local totalSlots = chest.size()
- local usedSlots = 0
- for _, item in pairs(items) do
- if item.count > 0 then
- usedSlots = usedSlots + 1
- end
- end
- local storagePercent = math.floor((usedSlots / totalSlots) * 100)
- print("Calculated storage: " .. storagePercent .. "%")
- -- Send storage update to controller
- if cID then
- rednet.send(cID, {
- type = "storageUpdate",
- hostName = LOCAL_ID,
- storagePercent = storagePercent
- }, PROTOCOL)
- print("Sent storage update to controller: " .. storagePercent .. "%")
- else
- print("No controller connected. Skipping storage update.")
- end
- -- Stop the farm if storage exceeds 95%
- if storagePercent > 95 and status == "RUNNING" then
- print("Storage exceeds 95%. Stopping farm...")
- toggleFarm()
- end
- sleep(5) -- Update storage every 5 seconds
- end
- end
- -- Message Handling with Debug Logs
- local function handleMessages()
- while true do
- local senderId, message = rednet.receive(PROTOCOL)
- if senderId then
- print("Message received from:", senderId, "Type:", message and message.type or "nil")
- if message and message.type == "requestId" then
- -- Respond to requestId with CLIENT_ID
- rednet.send(senderId, { type = "responseId", CLIENT_ID = LOCAL_ID }, PROTOCOL)
- print("Responded to requestId with CLIENT_ID:", LOCAL_ID)
- elseif message and message.type == "toggle" then
- toggleFarm()
- sendStatus()
- elseif message and message.type == "requestStatus" then
- sendStatus()
- elseif message and message.type == "update" then
- print("Update command received. Updating...")
- shell.run("update.lua")
- return
- end
- else
- print("No message received.")
- end
- end
- end
- -- Startup Logic
- connectToController() -- Ensure connection on startup
- updateMonitor(status)
- -- Parallel Tasks
- parallel.waitForAll(
- handleMessages, -- Listen and process incoming messages
- maintainConnection, -- Maintain connection with the controller
- monitorStorage -- Periodically monitor chest storage
- )
Advertisement
Comments
-
- This is a lua script used to create nodes for a mob farm. Each node will self assign a UID and communicate with a singular controller. The node will send status comms through a rednet protocol to the controller such as the current status (Running, or Stopped), the amount of storage used in the farm, among others.
Add Comment
Please, Sign In to add comment
Advertisement