From 4b4c656af148a39f50827cbee763d7b412b55d47 Mon Sep 17 00:00:00 2001 From: Jacob Babor Date: Mon, 26 Feb 2024 01:37:03 -0600 Subject: [PATCH] Rework the script into something much simpler holy shit --- storage-net/README.md | 73 +------------------ storage-net/common.lua | 161 +++++++++-------------------------------- storage-net/deploy.sh | 9 +-- 3 files changed, 42 insertions(+), 201 deletions(-) diff --git a/storage-net/README.md b/storage-net/README.md index 107bf1b..785abcb 100644 --- a/storage-net/README.md +++ b/storage-net/README.md @@ -4,72 +4,7 @@ This is an implementation of a centralized storage network architecture that use ## Deployment -The master node must have a modem attached and be within range of all slave nodes. - -1. Deploy at least one slave turtle - * The inventory it is to monitor must be above the unit - * The unit should be able to drop below itself to push items to the master node - * Any subsequent slaves should be placed in front of the unit -2. Set up a return system that pushes into the first slave node (can be a hopper or similar) - -## Communication Protocol - -Messages are sent over rednet with the protocol `ccstoragenet`. - -### Packet Format - -Packet format is uniform between master <-> slaves and is structured like so: - -``` -{ - // Metadata - networkid: int() - sourceid: int() - sourcetype: str() - destid: int() - - // Payload - type: str() - - // Optional Arguments - itemname: str() - itemquant: int() - destination: int() - location: [int(),int(),int()] - - // Dump for additional body data - body: any -} -``` - -| Name | Required? | Type | Description -| :-- | :--: | :-- | :-- -| `networkid` | true | int | The ID of the network | -| `sourceid` | true | int | The CC ID of the machine sending the packet | -| `sourcetype` | true | string | The mode of the machine sending the packet | -| `destid` | true | int | The CC ID of the intended recipient of the packet | -| `type` | true | string | An arbitrary string literal corresponding to the type of the request. Common examplse include `ping`, `query`, etc. | -| `itemname` | false | string | The unlocalized name of an item. Used for querying, crafting, movement, etc. | -| `itemquant` | false | int | Quantity of the aforementioned item | -| `destination` | false | int | The CC ID of the intended recipient of the item | -| `body` | false | any | Any additional body data per the requirements of a query, such as a detailed list of inventory contents | - -### Slave Node Initialization - -* The slave starts up and immediately listens for messages - -### Master Node Initialization - -* The master node starts up -* The master node sends a packet with type `ping`. -* The master node listens for `pong` packets from all slaves. -* The `sourceid` of all `pong` packets is recorded for statistics displays. This cached data is only used for user display. Node availability is evaluated at request time. - -### Inventory Search (query) - -* The sender node sends a packet with type `query`. Field `itemname` is populated with an item to query for. -* Each available slave responds with type `query`. - * `itemname` is populated with data from the previous packet - * `itemquantity` is populated with the quantity of that item attached to storages the slave has access to. -* The requester waits for a response from each slave that responded to the `ping` or until a configurable timeout is reached. -* Results are consumed +1. Deploy a Smart Computer +2. Connect the computer to at least 1 chest and 1 hopper via physical modem lines. Chests need to be attached from the bottom and hoppers from their output direction +3. Put a chest on top of the Smart Computer +4. Deploy the script \ No newline at end of file diff --git a/storage-net/common.lua b/storage-net/common.lua index 35fd47b..6716eed 100644 --- a/storage-net/common.lua +++ b/storage-net/common.lua @@ -3,142 +3,53 @@ -- For information on this script, physical in-world setup, and configuration, -- see: https://git.desu.ltd/salt/mc-scripts/src/branch/master/storage-net --- Default configuration values. Override in config.lua. DO NOT CHANGE HERE -mode = "ConfigureMe" -- The mode of function for this node -networkid = 0 -- Unique ID for this network -port_broadcast = 42914 -- Port for M->S traffic -port_return = 42915 -- Port for S->M traffic -packet_magic = "ccstoragenet" -- Just a random string - --- This loads config.lua. See masterconfig.lua and slaveconfig.lua for example --- configurations. -require "config" - -- Startup diagnostics print("Salt's CC Storage Net") print("Computer " .. os.getComputerID() .. " configured as " .. mode) --- Common globals -modem = peripheral.find("modem") or error("No modem attached", 0) -modem_side = peripheral.getName(modem) --- Master globals -m_slaves = {} --- Slave globals -s_chest = peripheral.wrap("top") or nil +-- Global scope locals +local output = peripheral.wrap("top") or error("Put a chest on top of this terminal for output items", 0) + +-- Helper functions +function getDepositHoppers() + -- Get all connected inventories that push items into the system + return {peripheral.find("inventory", function(name,i) + return string.find(name, "minecraft:hopper") + end)} +end +function getConnectedChests() + -- Get all connected inventories that store items + return {peripheral.find("inventory", function(name,i) + return string.find(name, "minecraft:chest") + end)} +end -- Common functions -function c_mainLoop(loopfunc) - -- Loops a thing forever - while true do - loopfunc() - end -end -function c_waitForMessage() - -- Waits for a message on the modem, timing out after some duration - local sender, message = rednet.receive(packet_magic, 1) - if message then - if - (not message["type"]) or -- Message type is required - (message["sourcetype"] == mode) or -- Ignore packets from our class of machines - (message["networkid"] ~= networkid) or -- Ignore packets from other networks - (message["targetid"] and message["targetid"] ~= os.getComputerID) -- Ignore packets for other machines - then - return nil +function pushDepositsToChests() + -- Take all the contents of all connected hoppers and stuff them into any other connected inventory + -- These things are wrapped into tables because that's how you take multiple return values and stuff them in a table, apparently + local hoppers = getDepositHoppers() + local chests = {peripheral.find("inventory", function(name,i) return string.find(name, "minecraft:chest") end)} + -- For each hopper connected to the network... + for k,hopper in ipairs(hoppers) do + -- For each item in that hopper's inventory... + for hslot,hitem in pairs(hopper.list()) do + -- For each connected "chest"... + for k,chest in ipairs(chests) do + -- Attempt to push our items in + hopper.pushItems(peripheral.getName(chest),hslot) + end end - return message - end - return nil -end -function c_sendMessage(message) - -- Sends a message, either to the master or all slaves depending on mode - local msg = { - networkid = networkid, - sourceid = os.getComputerID(), - sourcetype = mode, - } - -- Override basic message object with args - for k,v in pairs(message) do - msg[k] = v - end - --print("Transmitting message: " .. textutils.serialize(msg)) - rednet.broadcast(msg, packet_magic) -end - --- Master functions -function m_loop() - -- The main loop of the master server - -- Listen for packets on the return net - local msg = c_waitForMessage() - if not msg then - return - end - if msg["type"] == "pong" then - local source = msg["sourceid"] - print("Received pong from slave: " .. source) - if (not m_slaves[source]) then - m_slaves[source] = {} - end - end -end -function m_ping() - -- Clear out the list of all slaves and send out a fresh ping - -- Ping information isn't used for much, so delay in clearing cache and - -- repopulating the data isn't a big deal. - m_slaves = {} - c_sendMessage({type="ping"}) -end - --- Slave functions -function s_loop() - -- The main loop of any slave nodes - -- Listen for packets from the master - local msg = c_waitForMessage() - if not msg then - return - end - if (msg["type"] == "ping") then - -- Respond to pings with pongs - print("Received ping from master: " .. msg["sourceid"]) - c_sendMessage({type="pong"}) - elseif (msg["type"] == "query") then - -- Analyze the attached inventory and see if we have the item - else - print("Unknown message: " .. textutils.serialize(msg)) - end - -- If we have any items, we should stow them away. Put them in our chest if - -- we can fit it, otherwise pass it along - for i=1,16 do - turtle.select(i) - while turtle.getItemCount(i) > 0 do - -- We have items in this slot -- push up until we can't anymore - if not turtle.dropUp() then break end - end - if turtle.getItemCount(i) > 0 then turtle.drop() end end end -- Application entrypoint -function main () - if (mode == "master") then - print("Beginning initialization as master...") - rednet.open(modem_side) - - print("Pinging for slaves...") - m_ping() - - print("Entering main loop") - c_mainLoop(m_loop) - elseif (mode == "slave") then - print("Beginning initialization as slave...") - rednet.open(modem_side) - if not s_chest then - error("No connected inventory. Place one above this node.", 0) - end - - print("Entering main loop") - c_mainLoop(s_loop) - else - error("Invalid mode: " .. mode .. ", please configure this node appropriately", 0) +function main() + while true do + -- Manage inventory cleanup tasks + pushDepositsToChests() -- Take all deposit terminals and push them into the inventory network + -- Sleep for a tick + sleep(0.05) -- This is to stop CC from killing us end end diff --git a/storage-net/deploy.sh b/storage-net/deploy.sh index bb9c54e..b1b1cee 100755 --- a/storage-net/deploy.sh +++ b/storage-net/deploy.sh @@ -10,17 +10,12 @@ mcroot="$HOME/.var/app/org.prismlauncher.PrismLauncher/data/PrismLauncher/instan world="New World" masterid="0" -slaves=("1" "8" "9") _ccroot="$mcroot/.minecraft/saves/$world/computercraft/computer" echo "Root: $_ccroot" -for computer in "$masterid" ${slaves[*]}; do +for computer in "$masterid"; do echo "Deploying to: $computer" mkdir -p "$_ccroot/$computer" - cp common.lua "$_ccroot/$computer/autostart.lua" + cp common.lua "$_ccroot/$computer/autostart" done cp masterconfig.lua "$_ccroot/$masterid/config.lua" -for slave in ${slaves[*]}; do - echo "Deploying slave config: $slave" - cp slaveconfig.lua "$_ccroot/$slave/config.lua" -done