Skip to content

Improve injector listener tracking and fix terminal packets breaking injection#2951

Merged
dmulloy2 merged 11 commits intodmulloy2:masterfrom
Imprex-Development:improve-listener-tracking
Jun 6, 2024
Merged

Improve injector listener tracking and fix terminal packets breaking injection#2951
dmulloy2 merged 11 commits intodmulloy2:masterfrom
Imprex-Development:improve-listener-tracking

Conversation

@Ingrim4
Copy link
Copy Markdown
Collaborator

@Ingrim4 Ingrim4 commented May 25, 2024

Description

This PR marks the initial phase of enhancements for the injector, addressing #2919. Additionally, it resolves an issue with inbound terminal packets like ClientIntentionPacket and ServerboundFinishConfigurationPacket. ProtocolLib is unable to retrieve the inbound PacketType.Protocol for these packets, a consequence of the PacketDecoder removing itself when a decoded packet is terminal. While indirectly related to #2933 and #2945, this PR distinguishes itself by implementing a (probably) accurate/robust solution for the underlying problem.

This PR primarily focuses on revamping the registration process for packet listeners. Instead of maintaining multiple lists of packet listeners per packet type and sets of packet types, we now primarily use two PacketTypeMultiMaps to track the registered packet listeners. I also reworked the collections used to track packet listeners, addressing several issues such as race conditions, performance regressions, and overall readability. The new implementation ensures thread-safe modifications to the collections and uses locks only when necessary, resulting in faster read operations. Additionally, the new code is more readable and accurately represents the current injector.

Related Issue

How Has This Been Tested?

Tested with latest spigot 1.20.6 build with latest build of orebfuscator for 1.20.5. I couldn't observe any obvious errors.

Types of Changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

@Ingrim4
Copy link
Copy Markdown
Collaborator Author

Ingrim4 commented May 25, 2024

I also considered removing some more internal interfaces. Although they provide useful abstraction, they are outdated and poorly maintained. Moreover, they are only used within internal code, making them somewhat obsolete. I wanted to get your opinion on this matter, @derklaro. Here is a list of the interfaces:

The only interfaces I removed so far wouldn't have any functionality in the new system. I would also move some dependencies from methods calls into the constructor such as the NetworkManagerInjector because it's effectively a singleton.

@derklaro
Copy link
Copy Markdown
Contributor

Gonna take a first look later, but I would like to subject to using syncronized over a concurrent map/set. It's just easier and scales better than using syncronized. Just to put it here as well: computeIfAbsent in ConcurrentHashMap locks the map even if the entry already exists in JDK8, should use something else in that case :)

@Ingrim4
Copy link
Copy Markdown
Collaborator Author

Ingrim4 commented May 27, 2024

Gonna take a first look later, but I would like to subject to using syncronized over a concurrent map/set. It's just easier and scales better than using syncronized. Just to put it here as well: computeIfAbsent in ConcurrentHashMap locks the map even if the entry already exists in JDK8, should use something else in that case :)

I don't believe syncronized is an issue in this context because we only synchronize methods that are invoked when a listener is registered or unregistered, which occurs infrequently. Additionally, it is impossible to safely remove an entry from the map without some form of exclusive locking because there's no guarantee that another thread hasn't registered a new listener between the isEmpty check and the removal operation.

Comment thread src/main/java/com/comphenix/protocol/concurrent/PacketTypeMultiMap.java Outdated
Comment thread src/main/java/com/comphenix/protocol/injector/collection/PacketListenerSet.java Outdated
.build());
// reset packet to previous packet
event.setPacket(originalPacket);
}
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This method should now handle null packets and complain about naughty plugins.

PacketContainer packet = subPacketEvent.getPacket();
if (packet == null || packet.getHandle() == null) {
// super.invoke() should prevent us from getting new null packet so we just ignore it here
continue;
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This should now be fine without any warning etc.

@Ingrim4 Ingrim4 marked this pull request as ready for review June 5, 2024 21:53
@dmulloy2 dmulloy2 enabled auto-merge (squash) June 6, 2024 13:38
@dmulloy2 dmulloy2 merged commit 56fb51e into dmulloy2:master Jun 6, 2024
@Ingrim4 Ingrim4 deleted the improve-listener-tracking branch June 6, 2024 17:05
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.

3 participants