diff --git a/minehost.lua b/minehost.lua index 8e4698f..9a6b3bd 100644 --- a/minehost.lua +++ b/minehost.lua @@ -17,7 +17,9 @@ local STATUS = "status" local POSITION = "position" local HEADING = "heading" local QUARRY = "quarry" --- Constant log +local TASK = "task" +local FAILED = "failed" +-- Constant messsage types local LOG = "LOG" local REQUEST = "REQ" -- Constant requests @@ -50,18 +52,17 @@ local function printPrompt() write(PROMPT .. "> ") end -local function sendDirective(unit, directive) +local function sendDirective(unit, directive, ...) print("Sending directive \"" .. directive .. "\" to " .. unit .. ".") - modem.transmit(CHANNEL, CHANNEL, TOKEN .. ":" .. unit .. ":" .. HOST .. ":" .. REQUEST .. ":" .. directive) -end - -local function interpretData(data) - res = captureString(data, "([^%\][^%:]+)") - if res ~= nil then - res[5] = table.concat(res, ":", 5) - return res[1], res[2], res[3], res[4], res[5] - end - return nil + dir = { + token=TOKEN, + recipient=unit, + sender=HOST, + type=REQUEST, + request=directive, + content=arg + } + modem.transmit(CHANNEL, CHANNEL, textutils.serialise(dir)) end -- User command loop @@ -73,11 +74,11 @@ local function listenForCommands() if string.find(input, MOVEBY) == 1 then coordsRaw = string.sub(input, string.len(MOVEBY) + 1 + 1) local coords = captureString(coordsRaw, "([+-]?%d+)") - sendDirective(LEADER, MOVEBY .. ":" .. coords[1] .. "," .. coords[2] .. "," .. coords[3]) + sendDirective(LEADER, MOVEBY, coords[1], coords[2], coords[3]) elseif string.find(input, MOVETO) == 1 then coordsRaw = string.sub(input, string.len(MOVETO) + 1 + 1) local coords = captureString(coordsRaw, "([+-]?%d+)") - sendDirective(LEADER, MOVETO .. ":" .. coords[1] .. "," .. coords[2] .. "," .. coords[3]) + sendDirective(LEADER, MOVETO, coords[1], coords[2], coords[3]) elseif string.find(input, STATUS) == 1 then sendDirective(LEADER, STATUS) elseif string.find(input, POSITION) == 1 then @@ -93,17 +94,15 @@ end -- Status and requests from turtles -local function handleRequest(unit, request) +local function handleRequest(unit, request, content) end -local function handleMessage(unit, str, type) +local function handleMessage(sender, type, data) if type == LOG then - local log = string.sub(str, string.len(LOG) + 1 + 1) - print("[" .. unit .. "]: " .. str) + print("[" .. unit .. "]: " .. data["log"] .. textutils.serialise(data["content"])) elseif type == REQUEST then - local request = string.sub(str, string.len(REQUEST) + 1 + 1) - handleRequest(unit, request) + handleRequest(unit, data["request"], data["content"]) end end @@ -112,11 +111,11 @@ end local function listenToMiners() print("Listening to miners.") while running do - local event, side, sendChannel, replyChannel, data, distance = os.pullEvent("modem_message") + local event, side, sendChannel, replyChannel, serialized, distance = os.pullEvent("modem_message") print("") - local token, recipient, sender, type, content = interpretData(data) - if token == TOKEN and recipient == HOST then - handleMessage(sender, content, type) + local data = textutils.unserialise(serialised) + if data["token"] == TOKEN and data["recipient"] == HOST then + handleMessage(data["sender"], data["type"], data) else print("Invalid header information. Ignoring.") end diff --git a/mineleader.lua b/mineleader.lua index 247759b..84fc913 100644 --- a/mineleader.lua +++ b/mineleader.lua @@ -13,7 +13,9 @@ local STATUS = "status" local POSITION = "position" local HEADING = "heading" local QUARRY = "quarry" --- Constant log +local TASK = "task" +local FAILED = "failed" +-- Constant messaging local LOG = "LOG" local REQUEST = "REQ" -- Constant requests @@ -61,14 +63,30 @@ local function getMessage(data) return nil end -local function SendRequest(request) +local function SendRequest(request, ...) print("Sending request: " .. request) - modem.transmit(CHANNEL, CHANNEL, TOKEN .. ":" .. HOST .. ":" .. UNIT .. ":" .. REQUEST .. ":" .. request) + reqData = { + token=TOKEN, + recipient=HOST, + sender=UNIT, + type=REQUEST, + request=request, + content=arg + } + modem.transmit(CHANNEL, CHANNEL, textutils.serialise(reqData)) end -local function sendLog(log) +local function sendLog(log, ...) print("Sending message: " .. log) - modem.transmit(CHANNEL, CHANNEL, TOKEN .. ":" .. HOST .. ":" .. UNIT .. ":" .. LOG .. ":" .. log) + logData = { + token=TOKEN, + recipient=HOST, + sender=UNIT, + type=LOG, + log=log, + CONTENT=arg + } + modem.transmit(CHANNEL, CHANNEL, textutils.serialise(logData)) end local function captureString(str, seq) @@ -80,15 +98,6 @@ local function captureString(str, seq) return res end -local function interpretData(data) - res = captureString(data, "([^%\][^%:]+)") - if res ~= nil then - res[5] = table.concat(res, ":", 5) - return res[1], res[2], res[3], res[4], res[5] - end - return nil -end - local function findItem(str) for s=1,16 do if string.sub(str, -string.len(str)) == str then @@ -213,9 +222,9 @@ local function orient(v, forward, right) end local function attemptStartTask(f, ...) - sendLog("attempting to start a task.") + sendLog(TASK, "Attempting to start task.") if task ~= nil then - sendLog("failed: unable to start task due to another task running.") + sendLog(FAILED, "Unable to start task due to another task running.") return end task = f @@ -225,43 +234,43 @@ end -- actions local function locatePosition() - sendLog("position: using GPS to determine position.") + sendLog(POSITION, "Using GPS to determine position.") local x, y, z = gps.locate() - if x == nil then sendLog("failed: could not locate.") end + if x == nil then sendLog(POSITION, "could not locate.") end position = vector.new(x, y, z) end local function determineHeading() - sendLog("heading: calculating heading.") + sendLog(HEADING, "Calculating heading.") if position == nil then - sendLog("failed: no current position") + sendLog(FAILED, "No current position") return end local oldPos = vector.new(position.x, position.y, position.z) if not attemptMoveForward() then - sendLog("failed: could not move to get delta.") + sendLog(FAILED, "Could not move to get delta.") return end if x == nil then - sendLog("failed: could not locate.") + sendLog(FAILED, "Could not locate.") return end heading = position - oldPos if not attemptMoveRight() then - sendLog("failed: unable to rotate right.") + sendLog(FAILED, "Unable to rotate right.") heading = nil return end local oldPos = vector.new(position.x, position.y, position.z) if not attemptMoveForward() then - sendLog("failed: unable to move forward after rotation.") + sendLog(FAILED, "Unable to move forward after rotation.") heading = nil return end if not attemptMoveLeft() then - sendLog("failed: unable to rotate left.") + sendLog(FAILED, "Unable to rotate left.") heading = nil return end @@ -272,26 +281,26 @@ local function moveBy(delta, forward, right) sendLog("Attempting to move by (" .. delta.x .. "," .. delta.y .. "," .. delta.z .. ") (x,y,z).") -- x first if delta.x ~= 0 then - sendLog("Moving on x axis by: " .. delta.x) + sendLog(MOVEBY, "Moving on x axis by: " .. delta.x) orient(vector.new(delta.x, 0, 0):normalize(), forward, right) for x=1,math.abs(delta.x) do attemptMoveForward() end end if delta.z ~= 0 then - sendLog("Moving on z axis by: " .. delta.z) + sendLog(MOVEBY, "Moving on z axis by: " .. delta.z) orient(vector.new(0, 0, delta.z):normalize(), forward, right) for z=1,math.abs(delta.z) do attemptMoveForward() end end if delta.y > 0 then - sendLog("Moving on y axis by: " .. delta.y) + sendLog(MOVEBY, "Moving on y axis by: " .. delta.y) for y=1,delta.y do attemptMoveUp() end elseif delta.y < 0 then - sendLog("Moving on y axis by: " .. delta.y) + sendLog(MOVEBY, "Moving on y axis by: " .. delta.y) for y=1,math.abs(delta.y) do attemptMoveDown() end @@ -299,7 +308,7 @@ local function moveBy(delta, forward, right) end local function quarry(a, b) - sendLog("quarry: Starting quarry task from positions " .. tostring(a) .. " to " .. tostring(b) ".") + sendLog(QUARRY, "Starting quarry task from positions " .. tostring(a) .. " to " .. tostring(b) ".") end local function executeTasks() @@ -315,52 +324,51 @@ end local function listen() while running do print("Listening for directives...") - local event, side, sendChannel, replyChannel, data, distance = os.pullEvent("modem_message") - print("Recieved data: " .. data) - local token, recipient, sender, type, content = interpretData(data) - if token == TOKEN and recipient == UNIT then - print("Got content: " .. content) - if string.find(content, LUA_PREFIX) == 1 then - local luaScript = string.sub(content, string.len(LUA_PREFIX) + 1) - print("Executing: " .. luaScript) + local event, side, sendChannel, replyChannel, serialized, distance = os.pullEvent("modem_message") + print("Recieved data...") + local data = textutils.unserialise(serialized) + if data["token"] == TOKEN and data["recipient"] == UNIT then + print("Got content: " .. data["type"]) + + if data["type"] == LUA_PREFIX then + print("Executing: " .. data["content"][0]) local f = loadstring(luaScript) if f ~= nil then local freturn = f() if freturn ~= nil then - modem.transmit(CHANNEL, CHANNEL, TOKEN .. ":" .. UNIT .. ":" .. "obj" .. ":") - modem.transmit(CHANNEL, CHANNEL, freturn) + sendLog(LUA_PREFIX, textutils.serialise(freturn)) end else printError("Unable to load lua string.") end - elseif string.find(content, MOVETO .. ":") == 1 then - local coordsRaw = string.sub(content, string.len(MOVETO .. ":") + 1) - print("Raw coordinate data: " .. coordsRaw) - local coords = captureString(coordsRaw, "([+-]?%d+)") - local x = coords[1] - local y = coords[2] - local z = coords[3] - if heading ~= nil then - attemptStartTask(moveTo, vector.new(x,y,z), heading, rightAxis) - else - attemptStartTask(moveTo, vector.new(x,y,z), relHeading, relRightAxis) - end - elseif string.find(content, MOVEBY .. ":") == 1 then - local valuesRaw = string.sub(content, string.len(MOVEBY .. ":") + 1) - print("Raw coordinate data: " .. valuesRaw) - local deltas = captureString(valuesRaw, "([+-]?%d+)") - local x = deltas[1] - local y = deltas[2] - local z = deltas[3] + elseif data["type"] == MOVETO then + local x = data["content"][1] + local y = data["content"][2] + local z = data["content"][3] if heading ~= nil then print("Using actual coordinates.") + sendLog(MOVETO, "Using actual coordinates to move.") + attemptStartTask(moveTo, vector.new(x,y,z), heading, rightAxis) + else + print("Using relative coordinates.") + sendLog(MOVETO, "Using relative coordinates to move.") + attemptStartTask(moveTo, vector.new(x,y,z), relHeading, relRightAxis) + end + elseif data["type"] == MOVEBY then + local x = data["content"][1] + local y = data["content"][2] + local z = data["content"][3] + if heading ~= nil then + print("Using actual coordinates.") + sendLog(MOVEBY, "Using actual coordinates to move.") attemptStartTask(moveBy, vector.new(x,y,z), heading, rightAxis) else print("Using relative coordinates.") + sendLog(MOVEBY, "Using relative coordinates to move.") attemptStartTask(moveBy, vector.new(x,y,z), relHeading, relRightAxis) end - elseif string.find(content, STATUS) == 1 then + elseif data["type"] == STATUS then status = { relative_position = { coordinates=relativePos, @@ -374,7 +382,7 @@ local function listen() }, fuel=turtle.getFuelLevel(), } - sendLog("status:" .. textutils.serialise(status)) + sendLog(STATUS, status) elseif string.find(content, POSITION) == 1 then locatePosition() elseif string.find(content, HEADING) == 1 then