Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Network Refactor Pt. 3: Introduce a packet Codec and Connection type #105

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

StripedMonkey
Copy link
Contributor

This introduces a series of Codecs for encoding and decoding packets, as well as a Connection type which frames streams with encryption and protocol framing.

I have withheld hooking this up to anything, in favor of some tests to show that it works due to the large burden of refactoring code to use it. Partial refactors containing code hooking this up can be found in a dump commit on my fork of Pumpkin.

@Snowiiii
Copy link
Owner

Snowiiii commented Oct 5, 2024

So what benefits this gives us?

@StripedMonkey
Copy link
Contributor Author

StripedMonkey commented Oct 5, 2024

This makes connections composable, and encapsulates connections as frameable streams of any type. Encryption is handled transparently.

This is a part of my continued efforts to make the networking stack better through more encapsulation and rigid API boundaries.

All the code here does is handle taking an incoming TCP (or any impl AsyncStream) Connection and turn them into UncompressedPackets to then be (de)serialized.

@StripedMonkey
Copy link
Contributor Author

This PR is not designed to actually add features that did not exist before, but make it easier to maintain and extend the existing code. I'm trying to get to the point where working with network connections is completely abstracted out of the core game logic like it currently is.

@Bryntet
Copy link
Contributor

Bryntet commented Oct 16, 2024

That crate paste has the same functionality as unstable concat_idents 👍

@StripedMonkey
Copy link
Contributor Author

It saves like 10 lines of repetitive code, but honestly I don't think it's worth the extra dependency. It's nice to have but not necessary here.

Comment on lines +7 to 13
#[derive(Deserialize)]
pub struct SHandShake {
pub protocol_version: VarInt,
pub server_address: String, // 255
pub server_port: u16,
pub next_state: ConnectionState,
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, The only reason i used manuel Deserialization here is because the server address has a max length of 255. There where plans of implementing maybe some kinda struct called BoundedString, Not sure tough how

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been playing with a solution to this problem for fixed length bitsets or similar, but not addressed it in depth.

In theory, it's possible to make a newtype wrapper like

struct BoundedLengthString<const LEN: usize>(String);

and implement a string visitor that restricts the size, implementing From/Into would allow you to use

#[serde(try_from = BoundedLengthString<255>)]
pub server_address: String

but there are some considerations to make regarding strings in general. The current implementation is actually incorrect in that it assumes string length is in bytes. However, according to the wiki Strings are actually prefixed with their length in characters, making the implementation faulty on Non-ASCII/english characters.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Snowiiii Imo @StripedMonkey 's solution is cleaner, since we dont need to cast to a different type when using the packet.


@StripedMonkey

but there are some considerations to make regarding strings in general. The current implementation is actually incorrect in that it assumes string length is in bytes. However, according to the wiki Strings are actually prefixed with their length in characters, making the implementation faulty on Non-ASCII/english characters.

^^ regarding this, i dont think thats true tho, on wiki.vg it says that a string is a UTF-8 string prefixed with its size in bytes as a VarInt., the size here does not refer to amount of characters, but amount of bytes. This can be easily checked, by simply sending a chat message in pumpkin with the current implementation, with characters outside of the single byte range of UTF-8
image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I missread, Max string length in characters is what I was actually reading. So the limits provided in the wki aren't in bytes.

This introduces a series of Codecs for encoding and decoding packets, as well as a Connection<T> type which frames streams with encryption and protocol framing.
This introduces a `format` module which (currently) contains the (de)serialization for the module.
@Snowiiii
Copy link
Owner

Hey @StripedMonkey, I would love to merge or close this PR soon. Do you have any plans finishing the PR soon ?

@StripedMonkey
Copy link
Contributor Author

Life has been busy for the last bit, so I've not dedicated much time to this.

The largest outstanding issue here is that I depend on things implementing Serialize and Deserialize and not everything actually implements those traits, i.e chunk serialization is not actually using serde, and it's just a lot of work to get everything correct and reimplemented using serde.

It should be relatively straightforward to do, but it's still time consuming.

If you would like to take my code and work on it, maintainers should have commit access to the pr. Otherwise feel free to copy what you like, and discard the rest.

I have no timeline at this point. Not this weekend for sure.

@StripedMonkey StripedMonkey mentioned this pull request Nov 7, 2024
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants