# Protocol

## Encoding

PluginQuery uses BigEndian. Both sender and receiver must have the same encryption and compression method. Otherwise, it will be rejected as a corrupted packet.

| Type       | Length          |
| ---------- | --------------- |
| Byte       | 1 Byte          |
| Long       | 8 Byte          |
| Integer    | 4 Byte          |
| Byte Array | Max. 4 GigaByte |

## Handshaking

Handshaking is required to make a connection between servers. Handshaking used to make sure that you're trying to send and receive query messages. It also used to check the compression and encryption method on client and server. Once the client and the server handshaken, the client doesn't have to send a handshake packet again, except if the client disconnects from the server.

#### Request Packet

| Type       | Description                                      | Value |
| ---------- | ------------------------------------------------ | ----- |
| Byte       | Length of PluginQuery protocol name              | 5     |
| Byte Array | PluginQuery protocol name (Maximum Length: 127)  | query |
| Long       | Most Significant Bits (UUID)                     |       |
| Long       | Least Significant Bits (UUID)                    |       |
| Byte       | Length of Encrypted Stringified UUID             |       |
| Byte Array | Encrypted Stringified UUID (Maximum Length: 127) |       |

```java
/***
 * Generate UUID to String
 * @param mostSigBits
 * @param leastSigBits
 * @return Stringified UUID
 */
public static String UUIDtoString(long mostSigBits, long leastSigBits) {
    return (digits(mostSigBits >> 32, 8) + "-" +
            digits(mostSigBits >> 16, 4) + "-" +
            digits(mostSigBits, 4) + "-" +
            digits(leastSigBits >> 48, 4) + "-" +
            digits(leastSigBits, 12));
}

private static String digits(long val, int digits) {
    long hi = 1L << (digits * 4);
    return Long.toHexString(hi | (val & (hi - 1))).substring(1);
}
```

## Sending Query Message

Query Messages are compressed and encrypted. You need to know the compression algorithm and the encryption key in order to encode the packet. Decompression and Decryption are happening before the packet decoded.

| Type       | Description                            |
| ---------- | -------------------------------------- |
| Byte       | Channel name length                    |
| Byte Array | Channel name (Maximum Length: 127)     |
| Integer    | Message length                         |
| Byte Array | Query Message (Maximum Length: 4 Giga) |

## Pipeline

### Inbound

| Order      |
| ---------- |
| Decrypt    |
| Decompress |
| Decode     |

### Outbound

| Order    |
| -------- |
| Encode   |
| Compress |
| Encrypt  |
