upload tutel

This commit is contained in:
2025-05-06 18:07:46 -03:00
commit d9efbc7536
2 changed files with 392 additions and 0 deletions
+208
View File
@@ -0,0 +1,208 @@
--[[
tutel client
__
.,-;-;-,. /'_\
_/_/_/_|_\_\) /
'-<_><_><_><_>=/\
`/_/====/_/-'\_\
"" "" ""
]]
--[[
network variables
]]
local HOST_CHANNEL
local TURTLE_CHANNEL
local MSG_HEADER = 0x747574656C
local modem = peripheral.find("modem") or error("No modems found", 0)
modem.open(0) -- general port used for scanning
--[[
logging
]]
local logTypes = {
["general"] = {
["BG"] = colours.green,
["FG"] = colours.white
},
["info"] = {
["BG"] = colours.blue,
["FG"] = colours.white
},
["warning"] = {
["BG"] = colours.orange,
["FG"] = colours.black,
["AffectContent"] = true
},
["error"] = {
["BG"] = colours.red,
["FG"] = colours.black,
["AffectContent"] = true
}
}
local log = {}
for typeName, format in pairs(logTypes) do
log[typeName] = function(fmt, ...)
local prevColourBg = term.getBackgroundColour()
local prevColourFg = term.getTextColour()
term.setBackgroundColour(format["BG"])
term.setTextColour(format["FG"])
io.write(("[%s @ line %d]"):format(typeName, debug.getinfo(2, "l").currentline))
if format["AffectContent"] then
io.write(" ", string.format(fmt, ...), "\n")
term.setBackgroundColour(prevColourBg)
term.setTextColour(prevColourFg)
else
term.setBackgroundColour(prevColourBg)
term.setTextColour(prevColourFg)
io.write(" ", string.format(fmt, ...), "\n")
end
end
end
--[[
helper networking functions
]]
function sendToHost(name, msgData)
local message = {
["header"] = MSG_HEADER,
["name"] = name,
["data"] = msgData or {},
["id"] = os.getComputerID()
}
modem.transmit(HOST_CHANNEL, TURTLE_CHANNEL or 0, message)
end
--[[
command handling
]]
local commands = {}
function declareCommandHandler(name, handler, requiredKeys)
commands[name] = {
["keys"] = requiredKeys or {},
["handler"] = handler
}
end
-- scan
function handleScan(keys)
-- to-do: check and maybe inform if turtle is already linked to another host
HOST_CHANNEL = keys.hostChannel
modem.close(0)
log.info("received scan, host channel assigned to %d, replying...", keys.hostChannel)
local x, y, z = gps.locate()
sendToHost("SCAN", {
["positionX"] = x,
["positionY"] = y,
["positionZ"] = z,
["fuel"] = turtle.getFuelLevel()
})
-- HOST_CHANNEL = keys.hostChannel
-- REPLY_CHANNEL = keys.replyChannel
-- log.info("Received scan, HOST_CHANNEL: %d - REPLY_CHANNEL: %d", HOST_CHANNEL, REPLY_CHANNEL)
end
declareCommandHandler("SCAN", handleScan, { ["hostChannel"] = "number" })
-- register
function handleRegister(keys)
log.info("received register for id:", keys.id)
if (keys.id ~= os.getComputerID()) then return end -- message was not meant for this computer
TURTLE_CHANNEL = keys.turtleChannel
log.info("received register, host assigned channel: %d", keys.turtleChannel)
modem.open(keys.turtleChannel)
end
declareCommandHandler("REGISTER", handleRegister, { ["id"] = "number", ["turtleChannel"] = "number" })
-- status
function handleStatus(keys)
end
declareCommandHandler("STATUS", handleStatus)
-- goto
function handleGoTo(keys)
end
declareCommandHandler("GOTO", handleGoTo, { ["destX"] = "number", ["destY"] = "number", ["destZ"] = "number" })
-- mine area
function handleMineArea(keys)
end
declareCommandHandler("MINE-AREA", handleGoTo,
{ ["startX"] = "number", ["startY"] = "number", ["destX"] = "number", ["destZ"] = "number" })
-- abort
function handleAbort()
end
declareCommandHandler("ABORT", handleAbort)
--[[
main
]]
function pollAndProcessMessages()
local eventType, side, channel, replyChannel, message, dist = os.pullEvent("modem_message")
-- ignore messages not from host, HOST_CHANNEL and REPLY_CHANNEL will get assigned after receiving SCAN on channel 0
if TURTLE_CHANNEL and channel ~= TURTLE_CHANNEL then return end
-- message validation
if type(message) ~= "table" then return end
if not message.header or message.header ~= MSG_HEADER then return end
if not message.data then message.data = {} end
-- command validation
if not message.name then
log.warning("received nameless message")
return
end
if not commands[message.name] then
log.error("unhandled message (%s)", message.name)
return
end
local cmd = commands[message.name]
for i, v in pairs(cmd.keys) do
if type(message.data[i]) ~= v and v ~= "optional" then
log.error("command %s requires key %s of type %s (was %s)", message.name, i, v, type(message[i]))
return
end
end
cmd.handler(message.data)
-- message handling
log.info("processed command (%s)", message.name)
end
log.general("tutel client init")
while true do
pollAndProcessMessages()
end
+184
View File
@@ -0,0 +1,184 @@
--[[
tutel host
__
.,-;-;-,. /'_\
_/_/_/_|_\_\) /
'-<_><_><_><_>=/\
`/_/====/_/-'\_\
"" "" ""
]]
--[[
network variables
]]
local HOST_CHANNEL = 1337
local TURTLE_CHANNEL_BASE = 1338
local MSG_HEADER = 0x747574656C
local modem = peripheral.find("modem") or error("No modems found", 0)
modem.open(HOST_CHANNEL)
--[[
logging
]]
local logTypes = {
["general"] = {
["BG"] = colours.green,
["FG"] = colours.white
},
["info"] = {
["BG"] = colours.blue,
["FG"] = colours.white
},
["warning"] = {
["BG"] = colours.orange,
["FG"] = colours.black,
["AffectContent"] = true
},
["error"] = {
["BG"] = colours.red,
["FG"] = colours.black,
["AffectContent"] = true
}
}
local log = {}
for typeName, format in pairs(logTypes) do
log[typeName] = function(fmt, ...)
local prevColourBg = term.getBackgroundColour()
local prevColourFg = term.getTextColour()
term.setBackgroundColour(format["BG"])
term.setTextColour(format["FG"])
io.write(("[%s @ line %d]"):format(typeName, debug.getinfo(2, "l").currentline))
if format["AffectContent"] then
io.write(" ", string.format(fmt, ...), "\n")
term.setBackgroundColour(prevColourBg)
term.setTextColour(prevColourFg)
else
term.setBackgroundColour(prevColourBg)
term.setTextColour(prevColourFg)
io.write(" ", string.format(fmt, ...), "\n")
end
end
end
--[[
turtle tracking
]]
local turtles = {}
function registerTurtle(pos, fuel, id)
local channel = TURTLE_CHANNEL_BASE + #turtles
local turt = {
["channel"] = channel,
["index"] = #turtles,
["position"] = pos,
["fuel"] = fuel,
["status"] = "IDLE",
["id"] = id
}
table.insert(turtles, turt)
return turt
end
--[[
helper networking functions
]]
function sendToAll(name, msgData)
local message = {
["header"] = MSG_HEADER,
["name"] = name,
["data"] = msgData or {}
}
modem.transmit(0, 0, message)
end
--[[
command handling
]]
local commands = {}
function declareCommandHandler(name, handler, requiredKeys)
commands[name] = {
["keys"] = requiredKeys or {},
["handler"] = handler
}
end
-- scan
function handleScan(keys, id)
local turt = registerTurtle({ keys.positionX, keys.positionY, keys.positionZ }, keys.fuel, id)
log.info("Received turtle info (pos: %d, %d, %d - fuel: %d - channel: %d - id: %d)", turt.position[1],
turt.position[2], turt.position[3], turt.fuel, turt.channel, id)
sendToAll("REGISTER", { ["id"] = id, ["turtleChannel"] = turt.channel })
end
declareCommandHandler("SCAN", handleScan,
{
["positionX"] = "number",
["positionY"] = "number",
["positionZ"] = "number",
["fuel"] = "number"
})
--[[
main
]]
function pollAndProcessMessages()
local eventType, side, channel, replyChannel, message, dist = os.pullEvent("modem_message")
-- to-do: check if reply channel is valid turtle channel
if channel ~= HOST_CHANNEL then return end
-- message validation
if type(message) ~= "table" then return end
if not message.header or message.header ~= MSG_HEADER then return end
if not message.data then message.data = {} end
-- command validation
if not message.name then
log.warning("received nameless message")
return
end
if not commands[message.name] then
log.error("unhandled message (%s)", message.name)
return
end
local cmd = commands[message.name]
for i, v in pairs(cmd.keys) do
if type(message.data[i]) ~= v and v ~= "optional" then
log.error("command %s requires key %s of type %s (was %s)", message.name, i, v, type(message[i]))
return
end
end
cmd.handler(message.data, message.id)
-- message handling
log.info("received command (%s)", message.name)
end
log.general("tutel host init")
-- transmit scan
sendToAll("SCAN", { ["hostChannel"] = HOST_CHANNEL })
log.info("broadcasted scan message")
while true do
pollAndProcessMessages()
end