Advertisement
Myros27

spatialBot

Jun 12th, 2025 (edited)
966
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 24.33 KB | None | 0 0
  1. -- print(textutils.serialize(x))
  2.  
  3. local function findPeripheralByType(typeName)
  4.     for _, name in ipairs(peripheral.getNames()) do
  5.         if peripheral.getType(name) == typeName then return name, name end
  6.     end
  7.     return nil, nil
  8. end
  9.  
  10. function levenshtein(s1, s2, limit)
  11.     local len1, len2 = #s1, #s2
  12.     if len1 > len2 then s1, s2, len1, len2 = s2, s1, len2, len1 end
  13.     if len2 - len1 >= limit then return limit end
  14.     local v0 = {}
  15.     for i = 1, len2 + 1 do v0[i] = i - 1 end
  16.     for i = 1, len1 do
  17.         local v1 = { [1] = i }
  18.         local min_in_row = i
  19.         for j = 1, len2 do
  20.             local cost = s1:sub(i, i) == s2:sub(j, j) and 0 or 1
  21.             v1[j + 1] = math.min(v1[j] + 1, v0[j + 1] + 1, v0[j] + cost)
  22.             if v1[j + 1] < min_in_row then min_in_row = v1[j + 1] end
  23.         end
  24.         if min_in_row >= limit then return limit end
  25.         v0 = v1
  26.     end
  27.     return math.min(v0[len2 + 1], limit)
  28. end
  29.  
  30. function normalize(s)
  31.     s = string.lower(s)
  32.     s = string.gsub(s, " ", "")
  33.     s = string.gsub(s, ",", "")
  34.     s = string.gsub(s, "\"", "")
  35.     s = string.gsub(s, "%*", "")
  36.     s = string.gsub(s, "%(", "")
  37.     s = string.gsub(s, "%)", "")
  38.     s = string.gsub(s, "%[", "")
  39.     s = string.gsub(s, "%]", "")
  40.     s = string.gsub(s, "{", "")
  41.     s = string.gsub(s, "}", "")
  42.     s = string.gsub(s, "%.", "")
  43.     s = string.gsub(s, "%-", "")
  44.     s = string.gsub(s, "'", "")
  45.     return s
  46. end
  47.  
  48. function compareStrings(str1, str2)
  49.     local norm_str1 = normalize(str1)
  50.     local norm_str2 = normalize(str2)
  51.     return levenshtein(norm_str1, norm_str2, 3)
  52. end
  53.  
  54. --print("Match (0):", compareStrings("Test String!", "teststring"))
  55. --print("Distance 1 (1):", compareStrings("My Test [Disk]", "my test diskk"))
  56. --print("Distance 2 (2):", compareStrings("My Test (Disk)", "my best diskk"))
  57. --print("Distance 3+ (3):", compareStrings("My Test {Disk}", "your best diskk"))
  58.  
  59. function getDiskName()
  60.     local oppositeDirection = { top = "down", bottom = "up" }
  61.     local bridgeName, bridgeLocation = findPeripheralByType("meBridge")
  62.     if not bridgeName then return nil, "ME Bridge peripheral not found." end
  63.     local direction = oppositeDirection[bridgeLocation]
  64.     if not direction then return nil, "ME Bridge must be on top or bottom." end
  65.     local bridge = peripheral.wrap(bridgeName)
  66.     local item_details = turtle.getItemDetail(1)
  67.     if not item_details or not item_details.nbt then return nil, "Item in slot 1 has no NBT data." end
  68.     local import_filter = { name = item_details.name, nbt = item_details.nbt }
  69.     local items_before = {}
  70.     for _, item in ipairs(bridge.listItems()) do
  71.         items_before[item.fingerprint] = item.count
  72.     end
  73.     if bridge.importItem(import_filter, direction, 1) < 1 then
  74.         return nil, "Failed to import item into ME system."
  75.     end
  76.     local items_after = bridge.listItems()
  77.     local found_item_data = nil
  78.     for _, item_after in ipairs(items_after) do
  79.         local count_before = items_before[item_after.fingerprint] or 0
  80.         if item_after.count > count_before then
  81.             found_item_data = item_after
  82.             break
  83.         end
  84.     end
  85.     if not found_item_data then
  86.         bridge.exportItem(import_filter, direction)
  87.         return nil, "CRITICAL: Item imported but vanished inside the ME system."
  88.     end
  89.     local disk_name = found_item_data.displayName
  90.     if bridge.exportItem(found_item_data, direction) < 1 then
  91.         return nil, "CRITICAL: Failed to export item back. Item is stuck in ME system."
  92.     end
  93.  
  94.     disk_name = string.gsub(disk_name, "[%[%]]", "")
  95.     disk_name = string.gsub(disk_name, "^%s*(.-)%s*$", "%1")
  96.     return disk_name, nil
  97. end
  98.  
  99. --local name, err = getDiskName()
  100. --if name then
  101. --    print("Success! Disk name is: '" .. name .. "'")
  102. --else
  103. --    print("Failed! Reason: " .. err)
  104. --end
  105.  
  106. function returnDisk()
  107.     local oppositeDirection = { top = "down", bottom = "up" }
  108.     local bridgeName, bridgeLocation = findPeripheralByType("meBridge")
  109.     if not bridgeName then return nil, "ME Bridge peripheral not found." end
  110.     local direction = oppositeDirection[bridgeLocation]
  111.     if not direction then return nil, "ME Bridge must be on top or bottom." end
  112.     local bridge = peripheral.wrap(bridgeName)
  113.     local item_details = turtle.getItemDetail(1)
  114.     if not item_details or not item_details.nbt then return nil, "Item in slot 1 has no NBT data." end
  115.     local import_filter = { name = item_details.name, nbt = item_details.nbt }
  116.     if bridge.importItem(import_filter, direction, 1) < 1 then
  117.         return nil, "Failed to import item into ME system."
  118.     end
  119. end
  120.  
  121. --- Lists all storage disks in the ME system, providing their name and fingerprint.
  122. -- @return ({ {name=string, fingerprint=string}, ... }, nil) A table of disk data on success.
  123. -- @return (nil, string) An error message on any failure.
  124. function listMeDiskNames()
  125.     local bridgeName = findPeripheralByType("meBridge")
  126.     if not bridgeName then return nil, "ME Bridge peripheral not found." end
  127.     local bridge = peripheral.wrap(bridgeName)
  128.     local all_items = bridge.listItems()
  129.     local disk_data = {}
  130.  
  131.     if not all_items then
  132.         return nil, "Could not access ME system contents (is it powered and connected?)."
  133.     end
  134.    
  135.     for _, item in ipairs(all_items) do
  136.         if item.name and string.find(item.name, "storage_cell") then
  137.             local cleaned_name = string.gsub(item.displayName, "[%[%]]", "")
  138.             cleaned_name = string.gsub(cleaned_name, "^%s*(.-)%s*$", "%1")
  139.             table.insert(disk_data, { name = cleaned_name, fingerprint = item.fingerprint })
  140.         end
  141.     end
  142.     return disk_data, nil
  143. end
  144.  
  145. --- Finds a disk by name in the ME system and exports it to the turtle's inventory.
  146. -- @param diskNameToFind The name of the disk to search for.
  147. -- @return (true, nil) On successful export.
  148. -- @return (nil, string) An error message on failure.
  149. function getMeDiskByName(diskNameToFind)
  150.     local oppositeDirection = { top = "down", bottom = "up" }
  151.     local bridgeName, bridgeLocation = findPeripheralByType("meBridge")
  152.     if not bridgeName then return nil, "ME Bridge not found." end
  153.     local direction = oppositeDirection[bridgeLocation]
  154.     if not direction then return nil, "ME Bridge must be on top or bottom." end
  155.     local bridge = peripheral.wrap(bridgeName)
  156.  
  157.     local disks, err = listMeDiskNames()
  158.     if err then return nil, err end
  159.  
  160.     local found_fingerprint = nil
  161.     for _, disk in ipairs(disks) do
  162.         if compareStrings(disk.name, diskNameToFind) == 0 then
  163.             found_fingerprint = disk.fingerprint
  164.             break
  165.         end
  166.     end
  167.  
  168.     if not found_fingerprint then
  169.         return nil, "Disk with name '" .. diskNameToFind .. "' not found in ME system."
  170.     end
  171.  
  172.     local export_filter = { fingerprint = found_fingerprint }
  173.     if bridge.exportItem(export_filter, direction, 1) < 1 then
  174.         return nil, "Found disk but failed to export it from the ME system."
  175.     end
  176.  
  177.     return true, nil
  178. end
  179.  
  180. --- A utility function to get a simple, comma-separated string of all disk names.
  181. -- @return string A list of names, or an error message.
  182. function getDiskNamesAsString()
  183.     local disks, err = listMeDiskNames()
  184.     if err then return "Error: " .. err end
  185.     if #disks == 0 then return "No disks found in the ME system." end
  186.  
  187.     local names_only = {}
  188.     for _, disk in ipairs(disks) do
  189.         table.insert(names_only, disk.name)
  190.     end
  191.     return table.concat(names_only, ", ")
  192. end
  193.  
  194. --print("Available disks: " .. getDiskNamesAsString())
  195.  
  196.  
  197. function set(filename, content)
  198.     local file, err = fs.open(filename, "w")
  199.     if not file then
  200.         printError("Failed to open file for setting: " .. tostring(err))
  201.         return
  202.     end
  203.     file.write(content)
  204.     file.close()
  205. end
  206.  
  207. function retrieve(filename)
  208.     if not fs.exists(filename) then
  209.         return ""
  210.     end
  211.  
  212.     local file, err = fs.open(filename, "r")
  213.     if not file then
  214.         printError("Failed to open file for retrieving: " .. tostring(err))
  215.         return ""
  216.     end
  217.     local content = file.readAll()
  218.     file.close()
  219.     return content
  220. end
  221.  
  222. function clear(filename)
  223.     set(filename, "")
  224. end
  225.  
  226. --local test_file = "my_data"
  227. --fs.delete(test_file)
  228. --print("Initial state: '" .. retrieve(test_file) .. "' (Should be empty)")
  229. --set(test_file, "This is the first test.")
  230. --print("After set: '" .. retrieve(test_file) .. "'")
  231. --clear(test_file)
  232. --print("After clear: '" .. retrieve(test_file) .. "' (Should be empty)")
  233. --fs.delete(test_file)
  234.  
  235. function isPortReady()
  236.     local success, data = turtle.inspect()
  237.     if not success then
  238.         return false
  239.     end
  240.     if data and data.state and data.state.powered then
  241.         return true
  242.     end
  243.     return false
  244. end
  245.  
  246. --print("Function isPortReady() returned: " .. tostring(isPortReady()))
  247.  
  248.  
  249. local function splitString(inputString)
  250.     local args = {}
  251.     for word in string.gmatch(inputString, "[^%s]+") do
  252.         table.insert(args, word)
  253.     end
  254.     return args
  255. end
  256.  
  257. --- Sends a message with support for multiple, advanced, inline formatted components.
  258. --
  259. --  Use { key = 'value', ... } to format text.
  260. --  - For clickable links, provide: msg, value, clickAction.
  261. --  - For formatted text, provide: msg, and optionally color, underlined.
  262. --
  263. -- @param message The template message string.
  264. -- @param options (optional) A table of global options for the message.
  265. function notifyUser(message, options)
  266.     local chatBox = peripheral.find("chatBox")
  267.     if not chatBox then printError("Chat Box not found.") return end
  268.  
  269.     -- 1. SET UP GLOBAL DEFAULTS
  270.     options = options or {}
  271.     local prefix = options.prefix or "Turtle"
  272.     local brackets = options.brackets or "[]"
  273.     local bracketColor = options.bracketColor or "&7"
  274.     local targetUser = options.user
  275.  
  276.     -- 2. PARSE THE MESSAGE TEMPLATE
  277.     local messageBody = {}
  278.     local lastPos = 1
  279.     while true do
  280.         local start, finish = string.find(message, "{(.-)}", lastPos)
  281.         if not start then break end
  282.  
  283.         -- Add the plain text before this block, explicitly setting color to white.
  284.         local beforeText = message:sub(lastPos, start - 1)
  285.         if #beforeText > 0 then
  286.             table.insert(messageBody, { text = beforeText, color = "white", underlined = false })
  287.         end
  288.  
  289.         -- Extract and parse the content inside the {}
  290.         local inside = message:sub(start + 1, finish - 1)
  291.         local inlineOpts = {}
  292.         for key, value in string.gmatch(inside, "(%w+)%s*=%s*'([^']*)'") do
  293.             inlineOpts[string.gsub(key, "%s", "")] = value
  294.         end
  295.  
  296.         -- Construct the component.
  297.         if inlineOpts.msg then
  298.             local component = {
  299.                 text = inlineOpts.msg,
  300.                 color = inlineOpts.color or "aqua", -- Default to aqua if color isn't specified
  301.                 underlined = (inlineOpts.underlined == 'true')
  302.             }
  303.  
  304.             -- **THE FIX**: Only add a clickEvent if both action and value are present.
  305.             if inlineOpts.clickAction and inlineOpts.value then
  306.                 component.clickEvent = {
  307.                     action = inlineOpts.clickAction,
  308.                     value = inlineOpts.value
  309.                 }
  310.             end
  311.             table.insert(messageBody, component)
  312.         else
  313.             -- If malformed, treat as plain text.
  314.             table.insert(messageBody, { text = "{" .. inside .. "}", color = "white", underlined = false })
  315.         end
  316.  
  317.         lastPos = finish + 1
  318.     end
  319.  
  320.     -- Add any remaining text after the last block, explicitly setting color to white.
  321.     local remainingText = message:sub(lastPos)
  322.     if #remainingText > 0 then
  323.         table.insert(messageBody, { text = remainingText, color = "white", underlined = false })
  324.     end
  325.    
  326.     -- 3. SERIALIZE AND SEND
  327.     local jsonMessage = textutils.serialiseJSON(messageBody)
  328.     if targetUser and targetUser ~= "" then
  329.         chatBox.sendFormattedMessageToPlayer(jsonMessage, targetUser, prefix, brackets, bracketColor)
  330.     else
  331.         chatBox.sendFormattedMessage(jsonMessage, prefix, brackets, bracketColor)
  332.     end
  333. end
  334.  
  335. --notifyUser("Did you mean to load { msg = '<ExpFarm>', clickAction = 'suggest_command', color = 'gold', underlined = 'true', value = '@spatial load n3 expFarm' } or was that a mistake?",{ user = "", prefix = "Confirm", brackets = "()", bracketColor = "&b" })
  336. --notifyUser("Your { msg = 'reward', value = '/claim_reward 123' } is ready to be claimed.",{ user = "Myros27", prefix = "Quest", bracketColor = "&a" })
  337. --notifyUser("This is just a standard broadcast.",{ prefix = "Info" })
  338.  
  339.  
  340. function handleDiskStatusCommand(userName)
  341.     local turtleName = retrieve("turtleName")
  342.     local currentDisk = retrieve("currentDisk")
  343.  
  344.     if currentDisk == "" then
  345.         return
  346.     end
  347.     local clearCommand = "@spatial clear " .. currentDisk
  348.     local moveCommand = "@spatial move " .. currentDisk .. " here"
  349.  
  350.     notifyUser("{ msg = '"..currentDisk.."', underlined = 'true', clickAction = 'suggest_command', value = '" .. clearCommand .. "' } is loaded at { msg = '" .. retrieve("turtleName") .. "', underlined = 'true', clickAction = 'suggest_command', value = '" .. moveCommand .. "' }.", { prefix = retrieve("turtleName")})
  351. end
  352.  
  353. function getQuadrant(username)
  354.     local BASE_X = 24
  355.     local BASE_Z = 232
  356.     local HEIGHT_LETTERS = { "B", "D", "F", "H", "J", "L", "N", "P", "R", "T", "V" }
  357.     local player_detector = peripheral.find("playerDetector")
  358.     if not player_detector then
  359.         printError("Player Detector peripheral not found.")
  360.         return ""
  361.     end
  362.     local playerData = player_detector.getPlayer(username)
  363.  
  364.     if not playerData then
  365.         return ""
  366.     end
  367.  
  368.     if playerData.dimension ~= "minecraft:overworld" then
  369.         return ""
  370.     end
  371.  
  372.     if playerData.y < -56 or playerData.y >= 296 then
  373.         return ""
  374.     end
  375.  
  376.     local normalized_y = playerData.y + 56
  377.     local height_index = math.floor(normalized_y / 32) + 1
  378.     local height_letter = HEIGHT_LETTERS[height_index]
  379.  
  380.     local quadrant_number = 0
  381.     if playerData.x >= BASE_X and playerData.z <= BASE_Z then
  382.         quadrant_number = 9 -- Northeast
  383.     elseif playerData.x < BASE_X and playerData.z <= BASE_Z then
  384.         quadrant_number = 7 -- Northwest
  385.     elseif playerData.x >= BASE_X and playerData.z > BASE_Z then
  386.         quadrant_number = 3 -- Southeast
  387.     else
  388.         quadrant_number = 1 -- Southwest
  389.     end
  390.  
  391.     return height_letter .. quadrant_number
  392. end
  393.  
  394.  
  395. --local locationCode = getQuadrant("Myros27")
  396. --if locationCode ~= "" then
  397. --    print("Myros27's location code is: " .. locationCode)
  398. --else
  399. --    print("Could not get location for Myros27 (or they are out of bounds).")
  400. --end
  401.  
  402.  
  403. function sanitizeQuadrant(input)
  404.     if not input or type(input) ~= "string" then
  405.         return ""
  406.     end
  407.  
  408.     local s = string.lower(input)
  409.     local letters = {}
  410.     local digits = {}
  411.  
  412.     for char in string.gmatch(s, ".") do
  413.         if string.match(char, "%a") then
  414.             table.insert(letters, char)
  415.         elseif string.match(char, "%d") then
  416.             table.insert(digits, char)
  417.         end
  418.     end
  419.  
  420.     table.sort(letters)
  421.     table.sort(digits)
  422.     return table.concat(letters) .. table.concat(digits)
  423. end
  424.  
  425. --print("'N3' -> '" .. sanitizeQuadrant("N3") .. "'")
  426. --print("'3n' -> '" .. sanitizeQuadrant("3n") .. "'")
  427. --print("'z9a1' -> '" .. sanitizeQuadrant("z9a1") .. "'")
  428.  
  429.  
  430. function confirmQuadrant(sanitizedInput)
  431.     if not sanitizedInput or type(sanitizedInput) ~= "string" or #sanitizedInput ~= 2 then
  432.         return false
  433.     end
  434.     local letter = sanitizedInput:sub(1, 1)
  435.     local digit = sanitizedInput:sub(2, 2)
  436.     local validLetters = "bdfhjlnprtv"
  437.     local validDigits = "1379"
  438.     if string.find(validLetters, letter, 1, true) and string.find(validDigits, digit, 1, true) then
  439.         return true
  440.     else
  441.         return false
  442.     end
  443. end
  444.  
  445. --print("'n3' -> " .. tostring(confirmQuadrant("n3")))
  446. --print("'b9x' -> " .. tostring(confirmQuadrant("b9x"))) -- Fails because length is wrong
  447.  
  448.  
  449. function isInfront(blockName)
  450.     local success, blockData = turtle.inspect()
  451.     if not success or not blockData or not blockData.name then
  452.         return false
  453.     end
  454.     local result = compareStrings(blockName, blockData.name)
  455.     return result == 0
  456. end
  457.  
  458. --print(isInfront("ae2:spatial_io_port"))
  459.  
  460. --- The main function that listens for chat events and dispatches commands.
  461. local function runChatListener()
  462.     print("Chat command listener is now active. Waiting for messages...")
  463.     while true do
  464.         local event, username, message = os.pullEvent("chat")
  465.         local args = splitString(message)
  466.         handleCommand(username, args[1] or "", args[2] or "", args[3] or "", args[4] or "", args[5] or "")
  467.     end
  468. end
  469.  
  470.  
  471. function handleInit()
  472.     turtle.select(1)
  473.     rs.setOutput("front", false)
  474.     rs.setOutput("back", false)
  475.     local chatBox = peripheral.find("chatBox")
  476.     if not chatBox then
  477.         printError("Chat Box not found.")
  478.         os.sleep(100)
  479.         os.shutdown()
  480.         return
  481.     end
  482.    
  483.     local turtleName = retrieve("turtleName")
  484.     if (turtleName == "") then
  485.         term.write("Please enter the Name of the Turtle\n")
  486.         turtleName = read()
  487.         turtleName = sanitizeQuadrant(turtleName)
  488.         if (confirmQuadrant(turtleName)) then
  489.             set("turtleName", turtleName)
  490.         else
  491.             printError("Invalid Name")
  492.             os.sleep(1)
  493.             os.shutdown()
  494.         end
  495.     end
  496.  
  497.     if (isInfront("ae2:spatial_io_port")) then
  498.         turtle.turnRight()
  499.         rs.setOutput("front", true)
  500.         rs.setOutput("back", true)
  501.         os.sleep(0.05)
  502.         rs.setOutput("front", false)
  503.         rs.setOutput("back", false)
  504.         turtle.turnLeft()
  505.     else
  506.         turtle.turnLeft()
  507.         if (isInfront("ae2:spatial_io_port")) then
  508.             turtle.turnRight()
  509.             rs.setOutput("front", true)
  510.             rs.setOutput("back", true)
  511.             os.sleep(0.05)
  512.             rs.setOutput("front", false)
  513.             rs.setOutput("back", false)
  514.             turtle.turnLeft()
  515.         else
  516.             notifyUser("ae2:spatial_io_port not found",{ prefix = retrieve("turtleName")})
  517.             os.sleep(1)
  518.             os.shutdown()
  519.         end
  520.     end
  521.    
  522.     local player_detector = peripheral.find("playerDetector")
  523.     if not player_detector then
  524.         notifyUser("upgrade not found",{ prefix = retrieve("turtleName")})
  525.         os.sleep(1)
  526.         os.shutdown()
  527.     end
  528.    
  529.     local bridgeName, bridgeLocation = findPeripheralByType("meBridge")
  530.     if not bridgeName then
  531.         notifyUser("ME Bridge",{ prefix = retrieve("turtleName")})
  532.         os.sleep(1)
  533.         os.shutdown()
  534.     end
  535.    
  536.     local oppositeDirection = { top = "down", bottom = "up" }
  537.     local direction = oppositeDirection[bridgeLocation]
  538.     if not direction then
  539.         notifyUser("ME Bridge must be on top or bottom.",{ prefix = retrieve("turtleName")})
  540.         os.sleep(1)
  541.         os.shutdown()
  542.     end
  543. end
  544.  
  545. function waitForPortReady(timeout)
  546.     timeout = timeout or 2
  547.     local startTime = os.clock()
  548.     while true do
  549.         if isPortReady() then
  550.             return true
  551.         end
  552.         if os.clock() - startTime >= timeout then
  553.             notifyUser("Port was never ready",{ prefix = retrieve("turtleName")})
  554.             return false
  555.         end
  556.         os.sleep(0.05)
  557.     end
  558. end
  559.  
  560. function waitForSuck(timeout)
  561.     timeout = timeout or 2
  562.     local startTime = os.clock()
  563.     while true do
  564.         if turtle.suck() then
  565.             return true
  566.         end
  567.         if os.clock() - startTime >= timeout then
  568.             return false
  569.         end
  570.         os.sleep(0)
  571.     end
  572. end
  573.  
  574. function update()
  575.     fs.makeDir("startup")
  576.     shell.setDir("startup")
  577.     fs.delete("startup/spatialBot")
  578.     shell.run("pastebin get na90MBPy spatialBot")
  579.     os.reboot()
  580. end
  581.  
  582. function hasN(quadrant)
  583.     local q = string.lower(quadrant or "")
  584.     return string.find(q, "n") ~= nil
  585. end
  586.  
  587.  
  588. function saveTrigger()
  589.     if (isPortReady()) then
  590.         turtle.drop()
  591.         rs.setOutput("front", true)
  592.         os.sleep(0.05)
  593.         if (waitForSuck(1) == false) then
  594.             notifyUser("Unable to get Disk back at " .. retrieve("turtleName"),{ prefix = retrieve("turtleName")})
  595.             rs.setOutput("front", false)
  596.             return false
  597.         end
  598.     else
  599.         notifyUser("Unable to get ME Sytsm online at " .. retrieve("turtleName"),{ prefix = retrieve("turtleName")})
  600.         rs.setOutput("front", false)
  601.         return false
  602.     end
  603.     rs.setOutput("front", false)
  604.     return true
  605. end
  606.  
  607. function enableMe()
  608.     rs.setOutput("back", true)
  609.     waitForPortReady(2)
  610. end
  611.  
  612. function disableMe()
  613.     rs.setOutput("back", false)
  614. end
  615.  
  616. function clearSpace(userName)
  617.     if (retrieve("currentDisk") == "") then
  618.         notifyUser("Nothing to Clear",{ prefix = retrieve("turtleName")})
  619.         return
  620.     end
  621.     if (hasN(retrieve("turtleName")) and userName ~= "Myros27") then --only Myros27 may use the Level "n"
  622.         notifyUser("FATAL ERROR",{ prefix = retrieve("turtleName")})
  623.         return
  624.     end
  625.     enableMe()
  626.     if (saveTrigger()) then
  627.         os.sleep(0.05)
  628.         local diskName = retrieve("currentDisk")
  629.         clear("currentDisk")
  630.         returnDisk()
  631.         disableMe()
  632.         notifyUser("Returned disk " .. diskName .. " to the Base",{ prefix = retrieve("turtleName")})
  633.         return
  634.     end
  635.     disableMe()
  636.     notifyUser("Unable to Clear",{ prefix = retrieve("turtleName")})
  637. end
  638.  
  639. function loadSpace(userName, disk, slow)
  640.     if (hasN(retrieve("turtleName")) and userName ~= "Myros27") then --only Myros27 may use the Level "n"
  641.         notifyUser("FATAL ERROR",{ prefix = retrieve("turtleName")})
  642.         return
  643.     end
  644.     if (slow) then --wait for another unload
  645.         os.sleep(2)
  646.     end
  647.     if (retrieve("currentDisk") ~= "") then
  648.         clearSpace(userName)
  649.     end
  650.     enableMe()
  651.     local didWork,message = getMeDiskByName(disk) -- get Disk From ME System
  652.     if (didWork) then
  653.         if (saveTrigger()) then
  654.             os.sleep(0.05)
  655.             set("currentDisk", disk)
  656.             notifyUser("Loaded disk " .. disk .. " at " .. retrieve("turtleName") ,{ prefix = retrieve("turtleName")})
  657.             disableMe()
  658.             return
  659.         else
  660.             rs.setOutput("back", false)
  661.             os.sleep(2)-- are we here because the disk is still in the spatial port? we should check inventory
  662.             rs.setOutput("back", true)
  663.             if (saveTrigger()) then -- lets try again
  664.                 os.sleep(0.05)
  665.                 set("currentDisk", disk)
  666.                 notifyUser("Loaded disk " .. disk .. " at " .. retrieve("turtleName") ,{ prefix = retrieve("turtleName")})
  667.                 disableMe()
  668.                 return             
  669.             end
  670.         end
  671.     else
  672.         notifyUser("Unable to find a Disk named " .. disk .. "." ,{ prefix = retrieve("turtleName")})
  673.     end
  674.     disableMe()
  675.     if (slow) then
  676.         notifyUser("Unable to Move",{ prefix = retrieve("turtleName")})
  677.         return
  678.     end
  679.     notifyUser("Unable to Load",{ prefix = retrieve("turtleName")})
  680. end
  681.  
  682. function handleCommand(userName, arg1, arg2, arg3, arg4, arg5)
  683.     if (userName == "Myros27" and arg1 == "@spatial" and arg2 == "update") then
  684.         notifyUser("updating now",{ prefix = retrieve("turtleName")})
  685.         update()
  686.     end
  687.    
  688.     if (arg1 == "@disks") then
  689.         handleDiskStatusCommand(userName)
  690.         return
  691.     end
  692.    
  693.     local myGroupDist = compareStrings(arg1, "@spatial")
  694.     if (myGroupDist > 2) then
  695.         return
  696.     end
  697.    
  698.     local loadDist = compareStrings(arg2, "load")
  699.     local clearDist = compareStrings(arg2, "clear")
  700.     local moveDist = compareStrings(arg2, "move")
  701.     if (loadDist > 2 and clearDist > 2 and moveDist > 2) then
  702.         return
  703.     end
  704.    
  705.     local turtleName = retrieve("turtleName")
  706.    
  707.     local quadrant = arg3
  708.     local disk = arg4
  709.     if (quadrant == "here") then
  710.         quadrant = getQuadrant(userName)
  711.     end
  712.     quadrant = sanitizeQuadrant(quadrant)
  713.    
  714.     local validQuadrant = true
  715.    
  716.     if not confirmQuadrant(quadrant) then
  717.         disk = arg3
  718.         quadrant = arg4
  719.         if (quadrant == "here") then
  720.             quadrant = getQuadrant(userName)
  721.         end
  722.         quadrant = sanitizeQuadrant(quadrant)
  723.         if not confirmQuadrant(quadrant) then
  724.             validQuadrant = false
  725.         end
  726.     end
  727.    
  728.     local currentDisk = retrieve("currentDisk")
  729.    
  730.     if (clearDist < 3) then
  731.         local isItMyName = compareStrings(turtleName, quadrant)
  732.         if (isItMyName == 0) then
  733.             clearSpace(userName)
  734.             return
  735.         end
  736.         if (validQuadrant == false) then
  737.             local isItMyDisk = compareStrings(disk, currentDisk)
  738.             if (isItMyDisk < 2) then
  739.                 clearSpace(userName)
  740.                 return
  741.             end
  742.         end
  743.         return
  744.     end
  745.    
  746.     if (loadDist < 3) then
  747.         local isItMyName = compareStrings(turtleName, quadrant)
  748.         if (isItMyName == 0) then
  749.             loadSpace(userName, disk, false)
  750.             return
  751.         end
  752.         return
  753.     end
  754.    
  755.     if (moveDist < 3) then
  756.         local isItMyName = compareStrings(turtleName, quadrant)
  757.         if (isItMyName == 0) then
  758.             loadSpace(userName, disk, true)
  759.             return
  760.         end
  761.         local isItMyDisk = compareStrings(disk, currentDisk)
  762.         if (isItMyDisk < 2) then
  763.             clearSpace(userName)
  764.             return
  765.         end
  766.         return
  767.     end
  768.     notifyUser("Overrun",{ prefix = retrieve("turtleName")})
  769. end
  770.  
  771. --init:
  772. handleInit()
  773. runChatListener()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement