only run inbound listeners on the main thread if requested (#1851)

This commit is contained in:
Pasqual Koschmieder 2022-08-17 05:51:54 +02:00 committed by GitHub
parent 2092b8f48e
commit 6707c4811e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 20 deletions

View File

@ -23,5 +23,11 @@ public enum ListenerOptions {
/** /**
* Notify ProtocolLib that {@link PacketListener#onPacketSending(PacketEvent)} is thread safe. * Notify ProtocolLib that {@link PacketListener#onPacketSending(PacketEvent)} is thread safe.
*/ */
ASYNC; ASYNC,
/**
* Notify ProtocolLib that {@link PacketListener#onPacketReceiving(PacketEvent)} must be executed on the main server
* thread.
*/
SYNC
} }

View File

@ -405,7 +405,7 @@ public abstract class PacketAdapter implements PacketListener {
} }
/** /**
* Set the listener option to {@link ListenerOptions#ASYNC}, indicating that our listener is thread safe. * Set the listener option to {@link ListenerOptions#ASYNC}, indicating that our outbound listener is thread safe.
* <p> * <p>
* This allows ProtocolLib to perform certain optimizations. * This allows ProtocolLib to perform certain optimizations.
* *
@ -415,6 +415,16 @@ public abstract class PacketAdapter implements PacketListener {
return addOption(ListenerOptions.ASYNC); return addOption(ListenerOptions.ASYNC);
} }
/**
* Set the listener option to {@link ListenerOptions#SYNC}, indicating that our inbound listener must be executed
* on the main server thread.
*
* @return This builder, for chaining.
*/
public AdapterParameteters optionSync() {
return addOption(ListenerOptions.SYNC);
}
/** /**
* Set the packet types the listener is looking for. * Set the packet types the listener is looking for.
* <p> * <p>

View File

@ -23,49 +23,53 @@ import org.bukkit.plugin.Plugin;
* Represents a listener that receives notifications when packets are sending or being received. * Represents a listener that receives notifications when packets are sending or being received.
* <p> * <p>
* Use {@link PacketAdapter} for a simple wrapper around this interface. * Use {@link PacketAdapter} for a simple wrapper around this interface.
*
* @author Kristian * @author Kristian
*/ */
public interface PacketListener { public interface PacketListener {
/** /**
* Invoked right before a packet is transmitted from the server to the client. * Invoked right before a packet is transmitted from the server to the client.
* <p> * <p>
* Note that the packet may be replaced, if needed. * Note that the packet may be replaced, if needed.
* <p> * <p>
* This method is executed on the main thread in 1.6.4 and earlier, and thus the Bukkit API is safe to use. * This method is executed on the main server thread by default. However, some spigot forks (like paper) schedule
* <p> * specific packets off the main thread. If the {@link ListenerOptions#ASYNC} option is not specified any invocation
* In Minecraft 1.7.2 and later, this method MAY be executed asynchronously, but only if {@link ListenerOptions#ASYNC} * of this method will be on the main server thread.
* have been specified in the listener. This is off by default. *
* @param event - the packet that should be sent. * @param event - the packet that should be sent.
*/ */
public void onPacketSending(PacketEvent event); void onPacketSending(PacketEvent event);
/** /**
* Invoked right before a received packet from a client is being processed. * Invoked right before a received packet from a client is being processed.
* <p> * <p>
* <b>WARNING</b>: <br> * This method will be called asynchronously (or on the netty event loop) by default. If the
* This method will be called <i>asynchronously</i>! You should synchronize with the main * {@link ListenerOptions#SYNC} option is specified, the invocation of this method will be synced to the main server
* thread using {@link org.bukkit.scheduler.BukkitScheduler#scheduleSyncDelayedTask(Plugin, Runnable, long) scheduleSyncDelayedTask} * thread which might cause issues due to delayed packets.
* if you need to call the Bukkit API. *
* @param event - the packet that has been received. * @param event - the packet that has been received.
*/ */
public void onPacketReceiving(PacketEvent event); void onPacketReceiving(PacketEvent event);
/** /**
* Retrieve which packets sent by the server this listener will observe. * Retrieve which packets sent by the server this listener will observe.
*
* @return List of server packets to observe, along with the priority. * @return List of server packets to observe, along with the priority.
*/ */
public ListeningWhitelist getSendingWhitelist(); ListeningWhitelist getSendingWhitelist();
/** /**
* Retrieve which packets sent by the client this listener will observe. * Retrieve which packets sent by the client this listener will observe.
*
* @return List of server packets to observe, along with the priority. * @return List of server packets to observe, along with the priority.
*/ */
public ListeningWhitelist getReceivingWhitelist(); ListeningWhitelist getReceivingWhitelist();
/** /**
* Retrieve the plugin that created list packet listener. * Retrieve the plugin that created list packet listener.
*
* @return The plugin, or NULL if not available. * @return The plugin, or NULL if not available.
*/ */
public Plugin getPlugin(); Plugin getPlugin();
} }

View File

@ -33,7 +33,7 @@ final class NetworkManagerPacketInjector extends AbstractPacketInjector {
@Override @Override
public boolean addPacketHandler(PacketType type, Set<ListenerOptions> options) { public boolean addPacketHandler(PacketType type, Set<ListenerOptions> options) {
if (!type.isAsyncForced() && (options == null || !options.contains(ListenerOptions.ASYNC))) { if (!type.isAsyncForced() && options != null && options.contains(ListenerOptions.SYNC)) {
this.mainThreadListeners.addType(type); this.mainThreadListeners.addType(type);
} }