Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- This will be the main computer program.
- It wil listen to user inputs to make new swarm robots and
- also listen for the swarm robot positions.
- -- todo
- Create something so we can recall turtle's
- ]]
- if not fs.exists("digMonitor") then
- shell.run("pastebin", "get", "2RMg3kFa", "digMonitor")
- end
- os.loadAPI("digMonitor")
- if not fs.exists("rnApi") then
- shell.run("pastebin", "get", "HQVEqt0C", "rnApi")
- end
- os.loadAPI("rnApi")
- local rn = rnApi.BetterRN:new()
- rn:open()
- local monitor = digMonitor.Mon:new()
- local swarmBots = {}
- local config = {}
- local skips = {}
- function removeDoubles(list)
- local list = list
- local hash = {}
- local res = {}
- for _, v in ipairs(list) do
- if (not hash[v]) then
- res[#res + 1] = v -- you could print here instead of saving to result table if you wanted
- hash[v] = true
- end
- end
- return res
- end
- if fs.exists("data/config") then
- local file = fs.open("data/config", "r")
- local data = file.readAll()
- file.close()
- config = textutils.unserialize(data)
- else
- if not fs.exists("configProgram") then
- shell.run("pastebin", "get", "izEfQHMQ", "configProgram")
- end
- shell.run("configProgram")
- local file = fs.open("data/config", "r")
- local data = file.readAll()
- file.close()
- config = textutils.unserialize(data)
- end
- if fs.exists("data/swarmBots") then
- local file = fs.open("data/swarmBots", "r")
- local data = file.readAll()
- file.close()
- swarmBots = textutils.unserialize(data)
- swarmBots = removeDoubles(swarmBots)
- monitor:setData(swarmBots)
- monitor:showData()
- end
- if fs.exists("data/skips") then
- local file = fs.open("data/skips", "r")
- local data = file.readAll()
- file.close()
- skips = textutils.unserialize(data)
- end
- -- Listen for the register command of a bot
- function registerBot()
- local response
- -- Fake data
- local newTurtle = {
- [1] = {1, 1},
- [2] = 85,
- [3] = 85,
- [4] = 85,
- [4] = vector.new(1, 1, 1),
- [5] = "s",
- [6] = 128,
- [7] = skips
- }
- response = rn:listen("swarmbotRegisterRequest")
- if next(response) ~= nil then
- newTurtle[1] = calculateNextChunk(calculateStartDir())
- newTurtle[2] = config.startHeight
- newTurtle[3] = config.parkHeight
- newTurtle[4] = config.flyHeight
- newTurtle[5] = calculateHomePos()
- newTurtle[6] = calculateStartDir()
- newTurtle[7] = config.maxLength
- newTurtle[8] = skips
- rn:send(response[1], newTurtle, "swarmbotRegister")
- swarmBots[#swarmBots + 1] = {response[1], "Starting", os.clock()}
- swarmBots = removeDoubles(swarmBots)
- monitor:setData(swarmBots)
- monitor:showData()
- saveSwarmBots()
- end
- end
- -- Calculate functions needed for registration
- function calculateStartDir()
- local number = #swarmBots % #config.directions
- if number == 0 then
- number = #config.directions
- end
- return config.directions[number]
- end
- function calculateNextChunk(dir)
- local dir = dir:lower()
- if dir ~= "e" and dir ~= "s" and dir ~= "w" and dir ~= "n" then
- error("calculateHomePos direction is not e,s,w or n, currently is " .. dir)
- end
- local number = math.ceil((#swarmBots + 1) / #config.directions)
- if dir == "e" then
- return {config.chunk[1] + number, config.chunk[2]}
- elseif dir == "s" then
- return {config.chunk[1], config.chunk[2] + number}
- elseif dir == "w" then
- return {config.chunk[1] - number, config.chunk[2]}
- elseif dir == "n" then
- return {config.chunk[1], config.chunk[2] - number}
- end
- end
- function calculateHomePos()
- local pos = vector.new(0, 0, 0)
- pos.x = (config.chunk[1] * 16) + math.floor(#swarmBots % 16)
- pos.y = (config.chunk[2] * 16) + math.floor(#swarmBots / 16)
- pos.z = math.ceil((#swarmBots + 1) / 256) + config.parkHeight
- return pos
- end
- -- Save swarmbot function
- function saveSwarmBots()
- local file = fs.open("data/swarmBots", "w")
- -- Make a hard copy..
- local hardCopy = copy(swarmBots)
- file.writeLine(textutils.serialize(hardCopy))
- file.close()
- end
- function saveSkips()
- local file = fs.open("data/skips", "w")
- -- Make a hard copy..
- print(textutils.serialise(skips))
- file.writeLine(textutils.serialize(skips))
- file.close()
- end
- -- hardcopy a obj.
- function copy(obj)
- if type(obj) ~= "table" then
- return obj
- end
- local res = {}
- for k, v in pairs(obj) do
- res[copy(k)] = copy(v)
- end
- return res
- end
- -- Listen for user inputs
- function listenUserInput()
- while true do
- term.clear()
- term.setCursorPos(1, 1)
- print("<Spawn {number}> to start swarmBots")
- print("Put enough mining turtles and enderchests")
- print("<Skip {x,y}> to skip a certain chunk")
- print("<Broadcast {message}> to send message to all swarmBots")
- print("'home' to home all bots")
- print("'mine' to start all bots")
- print("'pause' to pause all bots")
- print("'ping' to ping all bots")
- print("'update' to update all bots")
- readInput()
- sleep(1)
- end
- end
- function readInput()
- input = read()
- if input ~= nil or input ~= "" then
- if string.match(input:lower(), "spawn") and string.match(input, "%d+") then
- local amount = string.match(input, "%d+")
- print("Spawning " .. amount .. " swarmBots")
- placeBots(amount)
- elseif string.match(input:lower(), "skip") and string.match(input, "%d+") then
- local chunk = string.gsub(input:lower(), "skip", "")
- chunk = string.gsub(chunk, " ", "")
- local results = {}
- for match in string.gmatch(chunk, "[^,]+") do
- results[#results + 1] = tonumber(match)
- end
- local dontSave = false
- for k, v in pairs(skips) do
- if v[1] == results[1] and v[2] == results[2] then
- dontSave = true
- break
- end
- end
- if not dontSave then
- skips[#skips + 1] = results
- saveSkips()
- local sendTimes = 4
- if math.ceil(#swarmBots / 3) > sendTimes then
- sendTimes = math.ceil(#swarmBots / 3)
- end
- for i = 1, sendTimes do
- print("sending " .. sendTimes - i .. " times")
- rn:broadcast("skip " .. chunk, "swarmbot")
- end
- print("Send 'skip " .. chunk .. "' on the 'swarmbot' channel")
- sleep(2)
- else
- print("Already skipping " .. chunk)
- sleep(2)
- end
- elseif
- (string.match(input:lower(), "broadcast") or string.match(input:lower(), "br ")) and
- (string.match(input:lower(), "home") or string.match(input:lower(), "mine") or
- string.match(input:lower(), "pause") or
- string.match(input:lower(), "ping") or string.match(input:lower(), "update"))
- then
- local sendTimes = 5
- -- if math.ceil(#swarmBots / 3) > sendTimes then
- -- sendTimes = math.ceil(#swarmBots / 3)
- -- end
- if string.match(input:lower(), "home") then
- for i = 1, sendTimes do
- print("sending " .. sendTimes - i .. " times")
- rn:broadcast("home", "swarmbot")
- end
- print("Send 'home' on the 'swarmbot' channel")
- sleep(2)
- elseif string.match(input:lower(), "mine") then
- for i = 1, sendTimes do
- print("sending " .. sendTimes - i .. " times")
- rn:broadcast("mine", "swarmbot")
- end
- print("Send 'mine' on the 'swarmbot' channel")
- sleep(2)
- elseif string.match(input:lower(), "pause") then
- for i = 1, sendTimes do
- print("sending " .. sendTimes - i .. " times")
- rn:broadcast("pause", "swarmbot")
- end
- print("Send 'pause' on the 'swarmbot' channel")
- sleep(2)
- elseif string.match(input:lower(), "ping") then
- for i = 1, sendTimes do
- print("sending " .. sendTimes - i .. " times")
- rn:broadcast("ping", "swarmbot")
- end
- print("Send 'ping' on the 'swarmbot' channel")
- sleep(2)
- elseif string.match(input:lower(), "update") then
- for i = 1, 3 do
- print("sending " .. 3 - i .. " times")
- rn:broadcast("update", "swarmbot")
- end
- print("Send 'update' on the 'swarmbot' channel")
- sleep(2)
- end
- else
- print("I didn't understand that..")
- end
- end
- sleep(0.2)
- end
- function placeBots(amount)
- local amount = tonumber(amount)
- if amount < 1 or amount > 120000 or type(amount) ~= "number" then
- print("Amount is wrong, it is a" .. type(amount) .. "with a value of " .. amount)
- print("(min = 1, max = 120000")
- else
- for i = 1, amount do
- -- Do some checks
- -- Create a bot and place it
- local turtleSlot = 0
- local enderSlot = 0
- while turtleSlot == 0 do
- for i = 1, 16 do
- if
- turtle.getItemDetail(i) and
- (turtle.getItemDetail(i).name == "ComputerCraft:CC-Turtle" or
- turtle.getItemDetail(i).name == "ComputerCraft:CC-TurtleExpanded")
- then
- turtleSlot = i
- break
- else
- turtle.suckUp()
- end
- end
- sleep(1)
- end
- while enderSlot == 0 do
- for i = 1, 16 do
- if turtle.getItemDetail(i) and turtle.getItemDetail(i).name == "EnderStorage:enderChest" then
- enderSlot = i
- break
- end
- end
- sleep(1)
- end
- turtle.select(turtleSlot)
- turtle.place(1)
- turtle.select(enderSlot)
- turtle.drop(1)
- peripheral.call("front", "turnOn")
- registerBot()
- if amount > 1 then
- print("Placed bot " .. i .. ". " .. amount - i .. " to go.")
- sleep(2)
- end
- end
- end
- end
- -- Listen for rednet updates
- local messages = {}
- function listenRednet()
- while true do
- local response = {}
- response = rn:listen("swarmbotPing")
- if next(response) ~= nil then
- rednet.send(response[1], "OK", "swarmbotReceived")
- messages[#messages + 1] = response
- response = nil
- else
- sleep(0.1)
- end
- end
- end
- function messageController()
- local counter = 0
- while true do
- if next(messages) ~= nil then
- local response = {next(messages)}
- local found = false
- response = response[2]
- for i = 1, #swarmBots do
- if tonumber(swarmBots[i][1]) == tonumber(response[1]) then
- swarmBots[i][2] = response[2]
- swarmBots[i][3] = os.clock()
- saveSwarmBots()
- if #messages < 2 or counter == 20 then
- counter = 0
- monitor:setData(swarmBots)
- monitor:showData()
- end
- found = true
- break
- end
- end
- if found == false then
- print("Unkown bot: " .. tonumber(response[1]))
- end
- local newMessages = {}
- counter = counter + 1
- messages[next(messages)] = nil
- for i = 1,#messages do
- if messages[i] ~= nil then
- newMessages[#newMessages+1] = messages[i]
- end
- end
- messages = newMessages
- response = nil
- else
- sleep(1)
- end
- end
- end
- function listenMonitor()
- monitor:listen()
- end
- function updateMonitor()
- while 1 do
- monitor:showData()
- sleep(120)
- end
- end
- parallel.waitForAll(listenRednet, messageController, listenUserInput, listenMonitor, updateMonitor)
Add Comment
Please, Sign In to add comment