Last active
February 23, 2024 00:09
-
-
Save Ryex/20f35ef69539949a5b83b5da5387d57c to your computer and use it in GitHub Desktop.
Create computercraft RadialQuary
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local CWD = fs.getDir(shell.getRunningProgram()) | |
local tArgs = {...} | |
local function usage() | |
print("Usage: config <rotation|level|receiver> <ID>") | |
print("Start the receiver first and then run rotation and level on respective computers") | |
print("Use a unique quarry ID and use the same ID on all three computers") | |
end | |
local SettingFile = fs.combine(CWD, "settings.cfg") | |
settings.load(SettingFile) | |
settings.define("local.quarryID", { | |
description = "local Quarry ID", | |
type = "string", | |
}) | |
settings.define("local.receiverCompID", { | |
description = "receiver host ID", | |
type = "number" | |
}) | |
settings.define("local.rotationCompID", { | |
description = "rotation client ID", | |
type = "number", | |
}) | |
settings.define("local.levelCompID", { | |
description = "level client ID", | |
type = "number", | |
}) | |
settings.save(SettingFile) | |
if #tArgs < 2 then | |
return usage() | |
end | |
local mode, quarryID = tArgs[1], tArgs[2] | |
local function openRednet() | |
peripheral.find("modem", rednet.open) | |
end | |
---@enum ConfigMsgType | |
local ConfigMsgType = { | |
SendID = 0, | |
SetupRot = 1, | |
SetupLevel = 2, | |
SendingID = 3, | |
SendingConfig = 4, | |
} | |
---@class ConfigMsg | |
---@field msg ConfigMsgType | |
---@field val number | table | nil | |
local function receiver() | |
settings.set("local.quarryID", quarryID) | |
settings.save(SettingFile) | |
openRednet() | |
rednet.host("ryry.quarry.radial.config", quarryID .. "_" .. os.getComputerID()) | |
local foundRot, foundLevel = false, false | |
local config = { receiverID = os.getComputerID() } | |
print("Setting up config host") | |
while true do | |
---@type number | nil | |
local senderID | |
---@type ConfigMsg | |
local msg | |
senderID, msg = rednet.receive("ryry.quarry.radial.config", 60 * 5) | |
print("Got message", senderID, textutils.serialize(msg)) | |
if senderID == nil then | |
print("Config Server timed out.") | |
break | |
end | |
if msg.msg == ConfigMsgType.SendID then | |
rednet.send(senderID, {msg = ConfigMsgType.SendingID, val = quarryID}, "ryry.quarry.radial.config") | |
elseif msg.msg == ConfigMsgType.SetupRot then | |
foundRot = true | |
settings.set("local.rotationCompID", msg.val) | |
settings.save(SettingFile) | |
rednet.send(senderID, {msg = ConfigMsgType.SendingConfig, val = config}, "ryry.quarry.radial.config") | |
elseif msg.msg == ConfigMsgType.SetupLevel then | |
foundLevel = true | |
settings.set("local.levelCompID", msg.val) | |
settings.save(SettingFile) | |
rednet.send(senderID, {msg = ConfigMsgType.SendingConfig, val = config}, "ryry.quarry.radial.config") | |
end | |
if foundRot and foundLevel then | |
print("Rotation and Level Client Found") | |
break | |
end | |
end | |
rednet.unhost("ryry.quarry.radial.config") | |
rednet.close() | |
end | |
local function rotationSetup() | |
settings.set("local.quarryID", quarryID) | |
settings.save(SettingFile) | |
openRednet() | |
local configHostID = nil | |
print("Looking for config host...") | |
local lookupCount = 0 | |
while configHostID == nil do | |
configHostID = rednet.lookup("ryry.quarry.radial.config") | |
print("Found comp ID", configHostID) | |
lookupCount = lookupCount + 1 | |
if lookupCount > 60 then | |
print("Failed to find config host") | |
return nil | |
end | |
sleep(0.2) | |
end | |
rednet.send(configHostID, {msg = ConfigMsgType.SendID}, "ryry.quarry.radial.config") | |
while true do | |
local senderID, msg = rednet.receive("ryry.quarry.radial.config", 60 * 5) | |
if senderID == nil then | |
print("Config attempt timed out") | |
return nil | |
elseif senderID == configHostID and msg.msg == ConfigMsgType.SendingID then | |
if msg.val == quarryID then | |
rednet.send(configHostID, {msg = ConfigMsgType.SetupRot, val = os.getComputerID()}, "ryry.quarry.radial.config") | |
end | |
elseif senderID == configHostID and msg.msg == ConfigMsgType.SendingConfig then | |
local config = msg.val | |
settings.set("local.receiverCompID", config.receiverID) | |
settings.save(SettingFile) | |
break | |
end | |
end | |
rednet.close() | |
end | |
local function levelSetup() | |
settings.set("local.quarryID", quarryID) | |
settings.save(SettingFile) | |
openRednet() | |
local configHostID = nil | |
print("Looking for config host...") | |
local lookupCount = 0 | |
while configHostID == nil do | |
configHostID = rednet.lookup("ryry.quarry.radial.config") | |
print("Found comp ID", configHostID) | |
lookupCount = lookupCount + 1 | |
if lookupCount > 60 then | |
print("Failed to find config host") | |
return nil | |
end | |
sleep(0.2) | |
end | |
rednet.send(configHostID, {msg = ConfigMsgType.SendID}, "ryry.quarry.radial.config") | |
while true do | |
local senderID, msg = rednet.receive("ryry.quarry.radial.config", 60 * 5) | |
if senderID == nil then | |
print("Config attempt timed out") | |
return nil | |
elseif senderID == configHostID and msg.msg == ConfigMsgType.SendingID then | |
if msg.val == quarryID then | |
rednet.send(configHostID, {msg = ConfigMsgType.SetupLevel, val = os.getComputerID()}, "ryry.quarry.radial.config") | |
end | |
elseif senderID == configHostID and msg.msg == ConfigMsgType.SendingConfig then | |
local config = msg.val | |
settings.set("local.receiverCompID", config.receiverID) | |
settings.save(SettingFile) | |
break | |
end | |
end | |
rednet.close() | |
end | |
if mode == "receiver" then | |
receiver() | |
elseif mode == "rotation" then | |
rotationSetup() | |
elseif mode == "level" then | |
levelSetup() | |
else | |
return usage() | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- install the code | |
-- | |
--- GIST Fetch and Install | |
--- | |
local CWD = fs.getDir(shell.getRunningProgram()) | |
local function installFile(url, path) | |
print("Downloading", url, "to", path) | |
local req, reqErr = http.get(url) | |
if req == nil then | |
print("Failed to fetch " .. url .. ":", reqErr) | |
return nil | |
end | |
local res = req.readAll() | |
req.close() | |
local file, fileErr = fs.open(path, "w") | |
if file == nil then | |
print("Failed to open " .. path ..":", fileErr) | |
return nil | |
end | |
file.write(res) | |
file.close() | |
end | |
local function getLatestGist(gist) | |
assert( not not http, "HTTP not available") | |
local apiEndpoint = "https://api.github.com/gists/" .. gist .. "/commits" | |
print("Querying " .. apiEndpoint) | |
local req = http.get(apiEndpoint) | |
if req == nil then return nil end | |
local res = req.readAll() | |
req.close() | |
local versions = textutils.unserializeJSON(res) | |
local datePattern = "(%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+)Z" | |
local printVers = {} | |
local max, maxTimestamp = nil, nil | |
for i, ver in ipairs(versions) do | |
local y, mon, d, h, min, s = ver.committed_at:match(datePattern) | |
local timestampt = {year = tonumber(y), month = tonumber(mon), day = tonumber(d), hour = tonumber(h), min = tonumber(min), sec = tonumber(s), isdst = false} | |
local timestamp = os.time(timestampt) | |
if max == nil or maxTimestamp < timestamp then | |
max = i | |
maxTimestamp = timestamp | |
end | |
-- printVers[i] = {i, ver.version:sub(1, 7), os.date("%Y/%m/%d - %T", timestamp)} | |
printVers[i] = {i, ver.version:sub(1, 7)} | |
end | |
textutils.pagedTabulate(colors.lightBlue, {"Version", "Hash"}, colors.orange, table.unpack(printVers)) | |
if max ~= nil then | |
print("Latest Version:", max, "Hash:", versions[max].version:sub(1, 7), ", Released At:", os.date("%Y/%m/%d - %T", maxTimestamp)) | |
print("Querying " .. versions[max].url) | |
local gistReq = http.get(versions[max].url) | |
if gistReq == nil then return nil end | |
local gistRes = gistReq.readAll() | |
gistReq.close() | |
local gist = textutils.unserializeJSON(gistRes) | |
return gist | |
end | |
return nil | |
end | |
local function installGistFiles(files) | |
for _, file in pairs(files) do | |
installFile(file.raw_url, fs.combine(CWD, file.filename)) | |
end | |
end | |
local latest = getLatestGist("20f35ef69539949a5b83b5da5387d57c") | |
if latest ~= nil then | |
installGistFiles(latest.files) | |
else | |
print("Invalid Gist or no latest version!") | |
end | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- main controll | |
local CWD = fs.getDir(shell.getRunningProgram()) | |
local SettingFile = fs.combine(CWD, "settings.cfg") | |
local QuarryMsgType = require("types") | |
settings.load(SettingFile) | |
settings.define("local.quarryID", { | |
description = "local Quarry ID", | |
type = "string", | |
}) | |
settings.define("local.rotationCompID", { | |
description = "rotation client ID", | |
type = "number", | |
}) | |
settings.define("local.levelCompID", { | |
description = "level client ID", | |
type = "number", | |
}) | |
settings.define("local.clutchSide", { | |
description = "redsone side for clutch", | |
type = "string" | |
}) | |
settings.define("local.gantrySide", { | |
description = "redstone side for gantry shaft", | |
type = "string" | |
}) | |
settings.save(SettingFile) | |
peripheral.find("modem", rednet.open) | |
local quarryID = settings.get("local.quarryID") | |
local clutchSide = settings.get("local.clutchSide") | |
local gantrySide = settings.get("local.gantrySide") | |
if clutchSide == nil then return print("Set the redstone contact side with 'set local.clutchSide <side>'") end | |
if gantrySide == nil then return print("Set the redstone piston side with 'set local.gantrySide <side>'") end | |
local rotationCompID = settings.get("local.rotationCompID") | |
local levelCompID = settings.get("levelCompID") | |
if rotationCompID == nil or levelCompID == nil or quarryID == nil then | |
return print("Run the config with `config receiver <ID>`") | |
end | |
local rotationState | |
local rotationCount | |
local levelState | |
local function watchState() | |
while true do | |
---@type number | |
local senderID | |
---@type QuarryMsg | |
local msg | |
senderID, msg = rednet.receive("ryry.guarry.radial.state") | |
if senderID ~= nil and msg.id ~= nil and msg.id == quarryID then | |
if senderID == levelCompID and msg.msg == QuarryMsgType.LevelStateChange then | |
levelState = msg.state.new | |
elseif senderID == rotationCompID and msg.msg == QuarryMsgType.RotationStateChange then | |
if not msg.state.old and msg.state.new then | |
rotationCount = rotationCount + 1 | |
end | |
rotationState = msg.state.new | |
end | |
end | |
end | |
end | |
local function moveDown() | |
redstone.setOutput(clutchSide, true) | |
sleep(0.1) | |
redstone.setOutput(gantrySide, true) | |
sleep(0.1) | |
redstone.setOutput(clutchSide, false) | |
while not levelState do | |
sleep(0.05) | |
end | |
redstone.setOutput(gantrySide, false) | |
end | |
local function controlLoop() | |
while true do | |
if rotationCount >=2 and levelState ~= nil and not levelState then | |
rotationCount = 0 | |
moveDown() | |
end | |
sleep(0.05) | |
end | |
end | |
parallel.waitForAll(watchState, controlLoop) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- level controll | |
local CWD = fs.getDir(shell.getRunningProgram()) | |
local SettingFile = fs.combine(CWD, "settings.cfg") | |
local QuarryMsgType = require("types") | |
settings.load(SettingFile) | |
settings.define("local.quarryID", { | |
description = "local Quarry ID", | |
type = "string", | |
}) | |
settings.define("local.receiverCompID", { | |
description = "receiver host ID", | |
type = "number" | |
}) | |
settings.define("local.contactSide", { | |
description = "redstone contact side", | |
type = "string", | |
}) | |
settings.save(SettingFile) | |
peripheral.find("modem", rednet.open) | |
local quarryID = settings.get("local.quarryID") | |
local contactSide = settings.get("local.contactSide") | |
if contactSide == nil then return print("Set the redstone contact side with 'set local.contactSide <side>'") end | |
local receiverCompID = settings.get("local.receiverCompID") | |
if receiverCompID == nil or receiverCompID < 0 or quarryID == nil then | |
return print("Run the config with `config level <ID>`") | |
end | |
local state = nil | |
while true do | |
local newState = redstone.getInput(contactSide) | |
if state ~= newState then | |
rednet.send( | |
receiverCompID, | |
{ | |
msg = QuarryMsgType.LevelStateChange, | |
id = quarryID, | |
state = { | |
old = state, | |
new = newState | |
}, | |
}, | |
"ryry.quarry.radial.state" | |
) | |
state = newState | |
end | |
sleep(0.05) | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- rotation control | |
-- | |
local CWD = fs.getDir(shell.getRunningProgram()) | |
local SettingFile = fs.combine(CWD, "settings.cfg") | |
local QuarryMsgType = require("types") | |
settings.load(SettingFile) | |
settings.define("local.quarryID", { | |
description = "local Quarry ID", | |
type = "string", | |
}) | |
settings.define("local.receiverCompID", { | |
description = "receiver host ID", | |
type = "number" | |
}) | |
settings.define("local.pistonSide", { | |
description = "redstone piston side", | |
type = "string" | |
}) | |
settings.define("local.levelSide", { | |
description = "redstone level contact side", | |
type = "string" | |
}) | |
settings.define("local.contactSide", { | |
description = "redstone contact side", | |
type = "string", | |
}) | |
settings.save(SettingFile) | |
peripheral.find("modem", rednet.open) | |
local quarryID = settings.get("local.quarryID") | |
local contactSide = settings.get("local.contactSide") | |
local pistonSide = settings.get("local.pistonSide") | |
local levelSide = settings.get("local.levelSide") | |
if contactSide == nil then return print("Set the redstone contact side with 'set local.contactSide <side>'") end | |
if pistonSide == nil then return print("Set the redstone piston side with 'set local.pistonSide <side>'") end | |
if levelSide == nil then return print("Set the level redstone contact side with 'set local.levelSide <side>'") end | |
local receiverCompID = settings.get("local.receiverCompID") | |
if receiverCompID == nil or receiverCompID < 0 or quarryID == nil then | |
return print("Run the config with `config level <ID>`") | |
end | |
local state = nil | |
local function watchRotation() | |
while true do | |
local newState = redstone.getInput(contactSide) | |
if state ~= newState then | |
rednet.send( | |
receiverCompID, | |
{ | |
msg = QuarryMsgType.RotationStateChange, | |
id = quarryID, | |
state = { | |
old = state, | |
new = newState, | |
}, | |
}, | |
"ryry.quarry.radial.state" | |
) | |
state = newState | |
end | |
sleep(0.05) | |
end | |
end | |
local function watchLevel() | |
while true do | |
local levelState = redstone.getInput(levelSide) | |
if levelState then | |
redstone.setOutput(pistonSide, true) | |
sleep(3) | |
redstone.setOutput(pistonSide, false) | |
sleep(3) | |
end | |
sleep(0.05) | |
end | |
end | |
parallel.waitForAll(watchRotation, watchLevel) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
---@enum QuarryMsgType | |
local QuarryMsgType = { | |
LevelStateChange = 0, | |
RotationStateChange = 1, | |
} | |
---@class RedstoneState | |
---@field old boolean | |
---@field new boolean | |
---@class QuarryMsg | |
---@field msg QuarryMsgType | |
---@field id string | |
---@field state RedstoneState | |
return QuarryMsgType |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment