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

Out/In bound protocol injection improvements #1524

Merged
merged 9 commits into from Mar 8, 2022

Conversation

derklaro
Copy link
Contributor

@derklaro derklaro commented Feb 27, 2022

This pull request introduces quite some changes to the way protocol lib handles and sends packets to the clients.

Current stuff which isn't done yet completely:

  • make injection into the channel more sane, it's current a bit harsh regarding field overrides...

Some changes I made to the api:

  • I removed some very old api, for example the socket based injection and byte-array based packet interception. These changes are mainly done because there is no good way to do both, good injection and supporting api that nobody should use as we provide way better and cleaner ways to intercept a packet (WirePackets are still a thing though).
  • I removed some exception declarations from api methods, for example the InvocationTargetException from sendServerPacket. It requires the api user to catch these exceptions while they are never thrown by the underlying code and are arguably relicts from ancient days.
  • There is no SocketInjector anymore (which provided access to a Socket which wrapped the incoming channel), mainly as that api was probably unused by most users and was already broken, depending which server software a user was using.
  • Theres maybe more breakages if a user was using non-api methods...

But this pull request also includes some very nice changes:

  • ProtocolLib no longer wraps the en/decoder of minecraft, instead it hooks into the pipeline allowing other injectors to get into it far more easily. (The general way on how we intercepted outbound packets is still the same, we're proxying the channel field and read the packets before they are actually written into the pipeline. This has 2 main bright sides:
    • there is no need for netty to excute something in the pipeline if the outbound packet is cancelled anyway
    • packet listeners which explicitly require tasks on the main thread will be easier to call as the invocation of write / writeAndFlush will always be on the main thread (on the vanilla server at least).
  • Explicit uninjection from a player is now a thing
  • A very much overall performance improvement by removing as much as reflection as possible from the main thread and replacing very old code without a need anymore (which was still executed!)
  • Maybe not the biggest thing, but the code is much cleaner and more easy to maintain and update for further versions of ProtocolLib!

Just a few more notes I want to conclude this with:

  • This change is heavily experimental, but I did quite a few test
  • Other than that I think a separate branch to work further would be really nice, as there are quite a lot of other things which can be improved which I didn't want to include in this pull request as the diff is already massive and more than enough imho 😂

I think this pull request resolves any Issue regarding performance and/or how we inject into the channel pipeline! Love to get some feedback on this from everybody who previously reported such issues 😀

I would no recommend anyone to use this in production as this change might still contain bugs

@dmulloy2
Copy link
Owner

dmulloy2 commented Feb 28, 2022

Looks great! Thank you for your work on this!

My thinking is to release 4.8.0 after merging in 1.18.2 support, bump the version to 5.0.0, then release this on jenkins for some testing. Metrics would imply that at least most people aren't using the bleeding edge builds: https://bstats.org/plugin/bukkit/ProtocolLib/1453

@derklaro
Copy link
Contributor Author

Sounds good 👍

@Rothes
Copy link

Rothes commented Mar 5, 2022

And is it possible to use ReflectASM for better performance?

@derklaro
Copy link
Contributor Author

derklaro commented Mar 5, 2022

Well, not really (I guess)... I can recheck if that is possible but from the code I see the library will not be able to override "trusted" final fields, as for example used in records.

Furthermore, I don't like that the lib doesn't get any "real" updates, for example the asm library dependency is 5 years out of date...

@retrooper
Copy link

Looks great! Thank you for your work on this!

My thinking is to release 4.8.0 after merging in 1.18.2 support, bump the version to 5.0.0, then release this on jenkins for some testing. Metrics would imply that at least most people aren't using the bleeding edge builds: https://bstats.org/plugin/bukkit/ProtocolLib/1453

I guess we can bump it now?

@derklaro
Copy link
Contributor Author

derklaro commented Mar 8, 2022

@dmulloy2 was the merge into master rather than dev intentional?

@dmulloy2
Copy link
Owner

dmulloy2 commented Mar 8, 2022

yeah im just messing around with formatting and linting on dev

@derklaro
Copy link
Contributor Author

derklaro commented Mar 8, 2022

ah i see 👍

@retrooper
Copy link

Love you guys <3

@retrooper
Copy link

Now we are just waiting for ViaVersion to do the same... But they might take much longer.

@matipoirierg
Copy link

matipoirierg commented May 30, 2022

Hi, is this already on latest dev builds? I'd love to do some testing

@derklaro
Copy link
Contributor Author

Yes

@matipoirierg
Copy link

Yes

thanks

Copy link

@Dreig-Michihi Dreig-Michihi left a comment

Choose a reason for hiding this comment

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

What to do with INTERCEPT_INPUT_BUFFER removing?

/**
* Retrieve the serialized client packet as it appears on the network stream.
*/
INTERCEPT_INPUT_BUFFER,
Copy link

Choose a reason for hiding this comment

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

Why did you remove this enum? What to use instead?

What about the method
com.comphenix.protocol.events.PacketEvent.getNetworkMarker()
throwing exception, which asks to "Add the option ListenerOptions.INTERCEPT_INPUT_BUFFER to your listener."
@derklaro
@dmulloy2

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is no replacement for this. See my initial PR comment for details

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.

None yet

6 participants