valence/crates/packet_inspector
Ryan Johnson 11ba70586e
Decoupled Packet Handlers (#315)
## Description

Closes #296 

- Redesigned the packet decoder to return packet _frames_ which are just
the packet ID + data in raw form.
- Made packet frame decoding happen in the client's tokio task. This has
a few advantages:
- Packet frame decoding (decompression + decryption + more) can happen
in parallel.
- Because packets are parsed as soon as they arrive, an accurate
timestamp can be included with the packet. This enables us to implement
client ping calculation accurately.
- `PacketEvent`s are now sent in the event loop instead of a giant match
on the serverbound packets. This is good because:
- Packets can now be handled from completely decoupled systems by
reading `PacketEvent` events.
- The entire packet is available in binary form to users, so we don't
need to worry about losing information when transforming packets to
events. I.e. an escape hatch is always available.
  - The separate packet handlers can run in parallel thanks to bevy_ecs.
- The inventory packet handler systems have been unified and moved
completely to the inventory module. This also fixed some issues where
certain inventory events could _only_ be handled one tick late.
- Reorganized the client module and moved things into submodules.
- The "default event handler" has been removed in favor of making
clients a superset of `PlayerEntityBundle`. It is no longer necessary to
insert `PlayerEntityBundle` when clients join. This does mean you can't
insert other entity types on the client, but that design doesn't work
for a variety of reasons. We will need an "entity visibility" system
later anyway.

## Test Plan

Steps:
1. Run examples and tests.
2023-04-08 19:55:31 +00:00
..
src Decoupled Packet Handlers (#315) 2023-04-08 19:55:31 +00:00
Cargo.toml Update to 1.19.4 (#302) 2023-03-31 14:58:47 -07:00
README.md Packet inspector gui (#238) 2023-03-09 03:09:53 -08:00

What's This?

The packet inspector is a Minecraft proxy for viewing the contents of packets as they are sent/received. It uses Valence's protocol facilities to display packet contents. This was made for three purposes:

  • Check that packets between Valence and client are matching your expectations.
  • Check that packets between vanilla server and client are parsed correctly by Valence.
  • Understand how the protocol works between the vanilla server and client.

Usage

Firstly, we should have a server running that we're going to be proxying/inspecting.

cargo r -r --example conway

Next up, we need to run the proxy server, this can be done in 2 different ways, either using the GUI application (default) or using the --nogui flag to log the packets to a terminal instance.

To assist, --help will produce the following:

A simple Minecraft proxy for inspecting packets.

Usage: packet_inspector [OPTIONS] [CLIENT_ADDR] [SERVER_ADDR]

Arguments:
  [CLIENT_ADDR]  The socket address to listen for connections on. This is the address clients should connect to
  [SERVER_ADDR]  The socket address the proxy will connect to. This is the address of the server

Options:
  -m, --max-connections <MAX_CONNECTIONS>
          The maximum number of connections allowed to the proxy. By default, there is no limit
      --nogui
          Disable the GUI. Logging to stdout
  -i, --include-filter <INCLUDE_FILTER>
          Only show packets that match the filter
  -e, --exclude-filter <EXCLUDE_FILTER>
          Hide packets that match the filter. Note: Only in effect if nogui is set
  -h, --help
          Print help
  -V, --version
          Print version

To launch in a Gui environment, simply launch packet_inspector[.exe] (or cargo r -r -p packet_inspector to run from source). The gui will prompt you for the CLIENT_ADDR and SERVER_ADDR if they have not been supplied via the command line arguments.

In a terminal only environment, use the --nogui option and supply CLIENT_ADDR and SERVER_ADDR as arguments.

cargo r -r -p packet_inspector -- --nogui 127.0.0.1:25566 127.0.0.1:25565

The client must connect to localhost:25566. You should see the packets in stdout when running in --nogui, or you should see packets streaming in on the Gui.

The -i and -e flags accept a regex to filter packets according to their name. The -i regex includes matching packets while the -e regex excludes matching packets. Do note that -e only applies in --nogui environment, as the Gui has a "packet selector" to enable/disable packets dynamically. The -i parameter value will be included in the Filter input field on the Gui.

For instance, if you only want to print the packets Foo, Bar, and Baz, you can use a regex such as ^(Foo|Bar|Baz)$ with the -i flag.

cargo r -r -p packet_inspector -- --nogui 127.0.0.1:25566 127.0.0.1:25565 -i '^(Foo|Bar|Baz)$'

Packets are printed to stdout while errors are printed to stderr. If you only want to see errors in your terminal, direct stdout elsewhere.

cargo r -r -p packet_inspector -- --nogui 127.0.0.1:25566 127.0.0.1:25565 > log.txt

Quick start with Vanilla Server via Docker

Start the server

docker run -e EULA=TRUE -e ONLINE_MODE=false -d -p 25565:25565 --name mc itzg/minecraft-server

View server logs

docker logs -f mc

Server Rcon

docker exec -i mc rcon-cli

In a separate terminal, start the packet inspector.

cargo r -r -p packet_inspector -- --nogui 127.0.0.1:25566 127.0.0.1:25565

Open Minecraft and connect to localhost:25566.

Clean up

docker stop mc
docker rm mc