bowmap-2 Server List Ping
Bowmap · bowmap.git · Tickets
A Bowmap Ticket (Closed):
Ticket · History
Git branch: ticket/server-list-ping
Implementation
This ticket served as the basis of the project for a while, and included much more than just server list ping. This work will probably be moved to bowmap-3 Rewrite?
Tasks:
- Project structure
- TCP server
- Add packets
- Add stream frame functions
- Add packet codecs
- Add packet encoding and decoding functions
- Accept packets from clients
- Move protocol level stuff to protocol namespaces/Great namespace shuffle to net.bowmap.server
- Move magical packet stream stuff into the actual handler. Take
(client, packet)and return[client', [packet*]] - Respond to SLP via packet
- Make
net.bowmap.server.protocol.schemafor keys. - Add MOTD with text components
- Clean up packet definitions.
- Test all functions
Potential:
- Look into using a core.async-based networking library and just a transducer. Then you can have a
net.bowmap.network.framenamespace that has the frame transducer and explains what a frame even is (explain why not) - How to send packets to players:
- Either give players a channel where packets can be sent
- Or just give players a uuid and maybe that uuid maps to a client that packets can be sent to
- Best would probably be to have one thing in control of sending out packets so that it can't just be done anywhere. Return packets from functions and have them be sent as a top level IO wrapper
Related & Causing:
- Move true TCP-level concern to
net.bowmap.tcp.*, and use a stateful transducer to frame packets in a clearer way? - Packet that should generally only be sent once to the server may be sent multiple times, which differs from vanilla behavior (I think)
- Reader and writers look the same as functions that return readers and writers (this may be fine, not sure)
- Packet encoding and decoding is untested
- Stream functions are untested
Make into separate tickets:
- Legacy Ping is unsupported
- Connection handling failing can close the server
printlnis used for logging.- Server list ping player count numbers do not update
- Codecs are untested
Finished:
- Rename
to-readerandto-writerto->readerand->writer - It is hard to find serverbound and clientbound packet definitions from
packet.clj. - "Schema" is not defined anywhere (add spec)
- "Schema" is an overloaded term. It refers to both the shape of a packet (its keys), and the definition of the packet codec (which can be a codec or a table). Come up with a better name for the latter. Or make a
ReaderandWriterprotocol and support vectors? - This notion was removed, and codecs are always used instead. - Normalize codecs as always being functions rather than sometimes being vectors
- "Codec" is not defined anywhere (specs has been added)
- Packets, frames, codecs, readers, writers, and schemas are undefined and undocumented
- Should a protocol +
reifybe used to make connections? (no, I think it's more coupled than channels are, though could be useful for some things) - Packet definitions couple schema with protocol order. split back out into two things again - a list of packet ids in each phase, and either a map of id to schema, or a map of phases to maps of id to schema, but that is only for the login disconnect packet so it's not really all that important at all. The coupling of these two packets was purely done to make the code smaller, which is never a good idea or a good reasoning.
- What exactly the numeric id and payload of a frame are is not clear. These are technically specified in the serverbound and clientbound packet namespaces, but not in an obvious way.
net.bowmap.server.network.serverhas too many responsibilities- Enable TCP_NODELAY
- It is unclear what keys a client has (missing a spec)
socketnamespace is not generic, and actually starts a Minecraft server, not just a "socket". Could makesocketgeneric and pass a "framer" for clarity. Or just mapconnectionover the channel.- Protocol code unrelated to networking is in
net.bowmap.network.* - Client sockets are never closed, even when client ends up in a bad state, and when the client disconnects.
- Error message is sent when clients should cleanly disconnect
- Client phase update is not atomic and could fail? (I don't think this is a concern)
- Clientbound status response packet has no JSON validation (not a big deal)
- nils are propagated through
net.bowmap.network.frame.writers/to-writer - Client
::receive-packetis not thread-safe - Client phase is never updated
- Reader and writer functions are not documented despite being unintuative
- Can't cache packet readers without REPL reloading problems / Packet schema lookup is inefficient (not a known problem)