# Computercraft Storage Network

This is an implementation of a centralized storage network architecture that uses just ComputerCraft and vanilla Minecraft.

## Deployment

A GPS will need to be established and be accurate within range of the entire network to the block.

Slave nodes must have a modem attached and be within range of the GPS and master.

The master node must have a modem attached and be within range of all slave nodes.

1. Deploy at least one slave node
  * The inventory it is to monitor must be above or in front of the unit
  * The unit should be able to drop below itself to push items to the master node

## Communication Protocol

Port 42914 is used for Master => Slave broadcasting

Port 42915 is used for Slave => Master return broadcasting

### Packet Format

Packet format is uniform between master <-> slaves and is structured like so:

```
{
    // Metadata
    magic:                  str("ccstoragenet")
    networkid:              int()
    sourceid:               int()
    destid:                 int()

    // Payload
    type:                   str()

    // Optional Arguments
    itemname:               str()
    itemquant:              int()
    destination:            int()
    location:               [int(),int(),int()]
}
```

| Name | Required? | Type | Description
| :-- | :--: | :-- | :--
| `magic` | true | string | Must be `ccstoragenet`. If it is not, the packet is immediately discarded |
| `networkid` | true | int | The ID of the network |
| `sourceid` | true | int | The CC ID 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 |

### Slave Node Initialization

* The slave starts up
* The slave receives a `ping` packet from a master server. The slave compares it to any stored `/pairednetwork` file in the root of the filesystem:
  * If the file exists and the ID does not match, processing is halted
  * The `networkid` of the packet is stored as `/pairednetwork`
* The slave responds with a `pong` packet.

### Master Node Initialization

* The master node starts up
* The master node sends a packet with type `ping` and `networkid` initialized to its CC ID.
* The master node listens for `pong` packets for a configurable timeout.
* 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)

* A sender node (master or slave) sends out a `ping`
* All available slaves respond with `pong`
* 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