mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2025-04-09 13:45:46 +02:00
feat(api): add immutable packet listener
This commit is contained in:
parent
30fe6465db
commit
0b03f1da71
@ -37,13 +37,9 @@ public class Example {
|
||||
|
||||
packet.accessor().update(a -> {
|
||||
a.update(ParticleData.class, 0, b -> {
|
||||
|
||||
b.set(int.class, 0, -1);
|
||||
});
|
||||
});
|
||||
|
||||
packet.accessor().getAccessor(ParticleData.class, 0).update(accessor -> {
|
||||
|
||||
});
|
||||
|
||||
packet.accessor().update(accessor -> {
|
||||
|
||||
@ -51,8 +47,10 @@ public class Example {
|
||||
accessor.set(Integer.class, 1, 1235);
|
||||
accessor.set(String.class, 1, "world");
|
||||
|
||||
accessor.getAccessor(Object.class, 1).getAccessor(Object.class, 1).update(mutableAccessor -> {
|
||||
|
||||
accessor.update(Object.class, 1, a -> {
|
||||
a.update(Object.class, 1, b -> {
|
||||
b.set(int.class, 2, -1);
|
||||
});
|
||||
});
|
||||
|
||||
accessor.update(Object.class, 1, mutableAccessor -> {
|
||||
@ -98,7 +96,7 @@ public class Example {
|
||||
// do processing here ...
|
||||
// write changes to packet ...
|
||||
|
||||
context.addAsyncTransmissionListener(chunk::markSent);
|
||||
context.addTransmissionListener(chunk::markSent);
|
||||
context.resumeProcessing();
|
||||
});
|
||||
|
||||
@ -115,7 +113,7 @@ public class Example {
|
||||
// do heavy processing here ...
|
||||
// write changes to packet ...
|
||||
|
||||
context.addAsyncTransmissionListener(chunk::markSent);
|
||||
context.addTransmissionListener(chunk::markSent);
|
||||
context.resumeProcessing();
|
||||
});
|
||||
});
|
||||
|
@ -1,23 +0,0 @@
|
||||
package dev.protocollib.api.listener;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Representing the context of an asynchronous packet listener.
|
||||
*/
|
||||
public interface AsyncPacketListenerContext extends SyncPacketListenerContext {
|
||||
|
||||
/**
|
||||
* Singles the listener is done with processing the packet.
|
||||
*/
|
||||
void resumeProcessing();
|
||||
|
||||
/**
|
||||
* Singles the listener is done with processing the packet and finished
|
||||
* with an exception.
|
||||
*
|
||||
* @param throwable the processing exception
|
||||
*/
|
||||
void resumeProcessingWithException(@NotNull Throwable throwable);
|
||||
|
||||
}
|
@ -4,9 +4,21 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import dev.protocollib.api.packet.PacketContainer;
|
||||
|
||||
/**
|
||||
* Functional interface for handling immutable packets.
|
||||
*
|
||||
* <p>An immutable packet listener can be executed either synchronously or asynchronously
|
||||
* depending on how it was registered. If registered asynchronously, it will be executed
|
||||
* in parallel with other listeners, ensuring non-blocking packet processing.</p>
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ImmutablePacketListener {
|
||||
|
||||
/**
|
||||
* Handles a packet that was sent or received.
|
||||
*
|
||||
* @param packet the immutable packet to handle
|
||||
* @param context the context providing additional information about the packet
|
||||
*/
|
||||
void handlePacket(@NotNull PacketContainer packet, @NotNull ImmutablePacketListenerContext context);
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import dev.protocollib.api.Connection;
|
||||
|
||||
/**
|
||||
* Context for immutable packet listeners.
|
||||
*/
|
||||
public interface ImmutablePacketListenerContext {
|
||||
|
||||
/**
|
||||
@ -19,12 +22,14 @@ public interface ImmutablePacketListenerContext {
|
||||
*
|
||||
* @return true if the packet is cancelled, false otherwise
|
||||
*/
|
||||
boolean isCancelledVolatile();
|
||||
boolean isCancelled();
|
||||
|
||||
/**
|
||||
* Adds a listener to be invoked after the packet is sent or received.
|
||||
* Adds a listener to be invoked after the packet is fully sent or received.
|
||||
* The transmission listener will get invoked on the underlying channel's
|
||||
* event-loop.
|
||||
*
|
||||
* @param listener the transmission listener to invoke
|
||||
*/
|
||||
void addAsyncTransmissionListener(@NotNull PacketTransmissionListener listener);// TODO async via netty
|
||||
void addTransmissionListener(@NotNull PacketTransmissionListener listener);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import dev.protocollib.api.packet.MutablePacketContainer;
|
||||
|
||||
/**
|
||||
* Functional interface for handling packets asynchronously.
|
||||
* Functional interface for handling and manipulating packets asynchronously.
|
||||
*
|
||||
* <p>Once a packet is processed by the listener, the context's
|
||||
* {@code resumeProcessing()} or {@code resumeProcessingWithException(Throwable)}
|
||||
@ -16,19 +16,19 @@ import dev.protocollib.api.packet.MutablePacketContainer;
|
||||
* </p>
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface AsyncPacketListener {
|
||||
public interface MutableAsyncPacketListener {
|
||||
|
||||
/**
|
||||
* Handles a packet that was sent or received, asynchronously.
|
||||
*
|
||||
* <p>Once processing is complete, ensure that one of the {@code resumeProcessing}
|
||||
* methods from the {@link AsyncPacketListenerContext} is called. This allows the
|
||||
* methods from the {@link MutableAsyncPacketListenerContext} is called. This allows the
|
||||
* packet to continue to the next listener. If not called, the packet will remain
|
||||
* in a waiting state and will only proceed after a timeout occurs.</p>
|
||||
* in a waiting state and will eventually timeout.</p>
|
||||
*
|
||||
* @param packet the packet to handle
|
||||
* @param context the context providing additional information about the packet and connection
|
||||
*/
|
||||
void handlePacket(@NotNull MutablePacketContainer packet, @NotNull AsyncPacketListenerContext context);
|
||||
void handlePacket(@NotNull MutablePacketContainer packet, @NotNull MutableAsyncPacketListenerContext context);
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package dev.protocollib.api.listener;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Context of a mutable asynchronous packet listener.
|
||||
*/
|
||||
public interface MutableAsyncPacketListenerContext extends MutableSyncPacketListenerContext {
|
||||
|
||||
/**
|
||||
* Singles the listener is done with processing the packet. Handing
|
||||
* it over to the next asynchronous packet listener.
|
||||
*/
|
||||
void resumeProcessing();
|
||||
|
||||
/**
|
||||
* Singles the listener is done with processing the packet and finished
|
||||
* with an exception. Handing it over to the next asynchronous packet
|
||||
* listener.
|
||||
*
|
||||
* @param throwable the processing exception
|
||||
*/
|
||||
void resumeProcessingWithException(@NotNull Throwable throwable);
|
||||
|
||||
}
|
@ -5,17 +5,17 @@ import org.jetbrains.annotations.NotNull;
|
||||
import dev.protocollib.api.packet.MutablePacketContainer;
|
||||
|
||||
/**
|
||||
* Functional interface for handling packets synchronously.
|
||||
* Functional interface for handling and manipulating packets synchronously.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface SyncPacketListener {
|
||||
public interface MutableSyncPacketListener {
|
||||
|
||||
/**
|
||||
* Synchronously handles a packet that was sent or received.
|
||||
* Handles a packet that was sent or received, synchronously.
|
||||
*
|
||||
* @param packet the packet to handle
|
||||
* @param context the context providing additional information about the packet and functions
|
||||
*/
|
||||
void handlePacket(@NotNull MutablePacketContainer packet, @NotNull SyncPacketListenerContext context);
|
||||
void handlePacket(@NotNull MutablePacketContainer packet, @NotNull MutableSyncPacketListenerContext context);
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package dev.protocollib.api.listener;
|
||||
|
||||
/**
|
||||
* Context of a mutable synchronous packet listener.
|
||||
*/
|
||||
public interface MutableSyncPacketListenerContext extends ImmutablePacketListenerContext {
|
||||
|
||||
/**
|
||||
* Sets whether the packet handling is cancelled. If cancelled, the packet will
|
||||
* not be processed further unless a listener is using the
|
||||
* {@link PacketListenerBuilder.WithType#includeCanceledPackets() includeCanceledPackets} flag.
|
||||
*
|
||||
* @param cancelled true to cancel the packet, false to allow processing
|
||||
*
|
||||
* @see PacketListenerBuilder
|
||||
*/
|
||||
void setCancelled(boolean cancelled);
|
||||
}
|
@ -9,6 +9,10 @@ import dev.protocollib.api.packet.PacketType;
|
||||
|
||||
/**
|
||||
* Builder for creating and registering packet listeners.
|
||||
*
|
||||
* <p>This builder allows configuring packet listeners with various settings,
|
||||
* including the packet types they should handle, execution priority, and behavior
|
||||
* regarding canceled packets and packet bundles.</p>
|
||||
*/
|
||||
public interface PacketListenerBuilder {
|
||||
|
||||
@ -49,6 +53,7 @@ public interface PacketListenerBuilder {
|
||||
*
|
||||
* @param bundleBehavior the bundle behavior to apply
|
||||
* @return the same builder for further configuration
|
||||
*
|
||||
* @see PacketListenerBundleBehavior
|
||||
*/
|
||||
@Contract("_ -> this")
|
||||
@ -67,37 +72,55 @@ public interface PacketListenerBuilder {
|
||||
* Allows the listener to modify packets. By default, listeners are read-only and
|
||||
* cannot modify packets.
|
||||
*
|
||||
* @return the same builder for further configuration
|
||||
* @return the mutable packet listener builder for further configuration
|
||||
*/
|
||||
@NotNull
|
||||
PacketListenerBuilder.Mutable mutable();
|
||||
|
||||
/**
|
||||
* Registers the packet listener to operate synchronously. The listener will be executed
|
||||
* in order relative to other synchronous listeners.
|
||||
*
|
||||
* @param listener the immutable synchronous packet listener to register
|
||||
* @return the packet listener registration instance
|
||||
*/
|
||||
@NotNull
|
||||
PacketListenerRegistration registerSync(@NotNull ImmutablePacketListener listener);
|
||||
|
||||
/**
|
||||
* Registers the packet listener to operate asynchronously. The listener will be executed
|
||||
* in parallel with other asynchronous listeners, ensuring non-blocking packet processing.
|
||||
*
|
||||
* @param listener the immutable asynchronous packet listener to register
|
||||
* @return the packet listener registration instance
|
||||
*/
|
||||
@NotNull
|
||||
PacketListenerRegistration registerAsync(@NotNull ImmutablePacketListener listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for building a mutable packet listener, allowing packet modifications.
|
||||
*/
|
||||
public interface Mutable {
|
||||
|
||||
/**
|
||||
* Registers the packet listener to operate synchronously. The listener
|
||||
* will always get called on the main game thread.
|
||||
* Registers the packet listener to operate synchronously. The listener will always
|
||||
* be executed on the main game thread.
|
||||
*
|
||||
* @param listener the synchronous packet listener to register
|
||||
* @return the same builder for further configuration
|
||||
* @param listener the synchronous mutable packet listener to register
|
||||
* @return the packet listener registration instance
|
||||
*/
|
||||
@NotNull
|
||||
PacketListenerRegistration registerSync(@NotNull SyncPacketListener listener);
|
||||
PacketListenerRegistration registerSync(@NotNull MutableSyncPacketListener listener);
|
||||
|
||||
/**
|
||||
* Registers the packet listener to operate asynchronously.
|
||||
* Registers the packet listener to operate asynchronously. The listener will be executed
|
||||
* in parallel with other asynchronous listeners, ensuring non-blocking packet processing.
|
||||
*
|
||||
* @param listener the asynchronous packet listener to register
|
||||
* @return the same builder for further configuration
|
||||
* @param listener the asynchronous mutable packet listener to register
|
||||
* @return the packet listener registration instance
|
||||
*/
|
||||
@NotNull
|
||||
PacketListenerRegistration registerAsync(@NotNull AsyncPacketListener listener);
|
||||
PacketListenerRegistration registerAsync(@NotNull MutableAsyncPacketListener listener);
|
||||
}
|
||||
}
|
||||
|
@ -1,41 +0,0 @@
|
||||
package dev.protocollib.api.listener;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import dev.protocollib.api.Connection;
|
||||
|
||||
/**
|
||||
* Representing the context of a synchronous packet listener.
|
||||
*/
|
||||
public interface SyncPacketListenerContext {
|
||||
|
||||
/**
|
||||
* Retrieves the connection associated with the packet.
|
||||
*
|
||||
* @return the connection handling the packet
|
||||
*/
|
||||
@NotNull
|
||||
Connection connection();
|
||||
|
||||
/**
|
||||
* Checks if the packet handling has been cancelled.
|
||||
*
|
||||
* @return true if the packet is cancelled, false otherwise
|
||||
*/
|
||||
boolean isCancelled();
|
||||
|
||||
/**
|
||||
* Sets whether the packet handling is cancelled. If cancelled, the packet
|
||||
* will not be processed further.
|
||||
*
|
||||
* @param cancelled true to cancel the packet, false to allow processing
|
||||
*/
|
||||
void setCancelled(boolean cancelled);
|
||||
|
||||
/**
|
||||
* Adds a listener to be invoked after the packet is sent or received.
|
||||
*
|
||||
* @param listener the transmission listener to invoke
|
||||
*/
|
||||
void addAsyncTransmissionListener(@NotNull PacketTransmissionListener listener);// TODO async via netty
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package dev.protocollib.api.packet;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Representing a raw binary packet with a packet id and payload.
|
||||
*/
|
||||
@ -17,5 +19,6 @@ public non-sealed interface BinaryPacket extends PacketLike {
|
||||
*
|
||||
* @return the packet payload as a byte array
|
||||
*/
|
||||
@NotNull
|
||||
byte[] payload();
|
||||
}
|
||||
|
@ -5,22 +5,45 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import dev.protocollib.api.reflect.MutableGenericAccessor;
|
||||
|
||||
/**
|
||||
* Represents a mutable packet container that allows modifications.
|
||||
*/
|
||||
public interface MutablePacketContainer extends PacketContainer {
|
||||
|
||||
/**
|
||||
* Retrieves the raw packet object.
|
||||
*
|
||||
* @return the packet object
|
||||
* <p>This method provides access to the underlying packet instance,
|
||||
* allowing direct interaction with its data.</p>
|
||||
*
|
||||
* @return the raw packet object
|
||||
*/
|
||||
@NotNull
|
||||
Object packet();
|
||||
|
||||
/**
|
||||
* Provides a {@link MutableGenericAccessor} for modifying packet fields reflectively.
|
||||
*
|
||||
* @return the mutable generic accessor for packet data
|
||||
*/
|
||||
@NotNull
|
||||
MutableGenericAccessor accessor();
|
||||
|
||||
/**
|
||||
* Retrieves the packet bundle that this packet is part of, if any.
|
||||
*
|
||||
* @return the packet bundle containing this packet, or {@code null} if not part of a bundle
|
||||
*/
|
||||
@Nullable
|
||||
MutablePacketContainer bundle();
|
||||
|
||||
/**
|
||||
* Creates and returns a mutable copy of this packet.
|
||||
*
|
||||
* <p>The cloned packet retains mutability, allowing further modifications.</p>
|
||||
*
|
||||
* @return a mutable clone of this packet container
|
||||
*/
|
||||
@Nullable
|
||||
MutablePacketContainer clone();
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import dev.protocollib.api.reflect.GenericAccessor;
|
||||
|
||||
/**
|
||||
* Representing a container for a packet.
|
||||
* Represents a container for a packet.
|
||||
*/
|
||||
public non-sealed interface PacketContainer extends PacketLike {
|
||||
|
||||
@ -18,6 +18,11 @@ public non-sealed interface PacketContainer extends PacketLike {
|
||||
@NotNull
|
||||
PacketType packetType();
|
||||
|
||||
/**
|
||||
* Provides a {@link GenericAccessor} for accessing packet fields reflectively.
|
||||
*
|
||||
* @return the generic accessor for packet data
|
||||
*/
|
||||
@NotNull
|
||||
GenericAccessor accessor();
|
||||
|
||||
@ -32,8 +37,10 @@ public non-sealed interface PacketContainer extends PacketLike {
|
||||
|
||||
/**
|
||||
* Creates and returns a mutable copy of this packet.
|
||||
*
|
||||
* @return a clone of this instance
|
||||
*
|
||||
* <p>The cloned packet allows modifications, unlike the immutable {@code PacketContainer}.</p>
|
||||
*
|
||||
* @return a mutable clone of this packet container
|
||||
*/
|
||||
@Nullable
|
||||
PacketContainer clone();
|
||||
|
@ -26,6 +26,8 @@ public interface PacketOperationBuilder {
|
||||
|
||||
/**
|
||||
* Registers a listener to be called once the packet has been sent or received.
|
||||
* The transmission listener will get invoked on the underlying channel's
|
||||
* event-loop.
|
||||
*
|
||||
* @param listener the listener to be notified upon packet transmission
|
||||
* @return the same builder for further configuration
|
||||
|
@ -2,6 +2,8 @@ package dev.protocollib.api.packet;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import dev.protocollib.api.ProtocolDirection;
|
||||
import dev.protocollib.api.ProtocolPhase;
|
||||
import net.kyori.adventure.key.Keyed;
|
||||
@ -20,6 +22,7 @@ public interface PacketType extends Keyed {
|
||||
*
|
||||
* @return the {@link ProtocolDirection} of the packet, either clientbound or serverbound
|
||||
*/
|
||||
@NotNull
|
||||
ProtocolDirection protocolDirection();
|
||||
|
||||
/**
|
||||
@ -29,6 +32,7 @@ public interface PacketType extends Keyed {
|
||||
*
|
||||
* @return the {@link ProtocolPhase} associated with this packet
|
||||
*/
|
||||
@NotNull
|
||||
ProtocolPhase protocolPhase();
|
||||
|
||||
/**
|
||||
@ -42,6 +46,7 @@ public interface PacketType extends Keyed {
|
||||
*
|
||||
* @return an {@link Optional} containing the class of the packet, or empty if not applicable
|
||||
*/
|
||||
@NotNull
|
||||
Optional<Class<?>> packetClass();
|
||||
|
||||
/**
|
||||
|
@ -5,9 +5,6 @@ import java.util.function.UnaryOperator;
|
||||
|
||||
public interface GenericMutator extends GenericAccessor {
|
||||
|
||||
MutableGenericAccessor getAccessor(Class<?> type, int ordinal);
|
||||
MutableGenericAccessor getAccessorOrThrow(Class<?> type, int ordinal);
|
||||
|
||||
// ====================================================
|
||||
// Value Modification
|
||||
// ====================================================
|
||||
|
@ -4,9 +4,6 @@ import java.util.function.Consumer;
|
||||
|
||||
public interface MutableGenericAccessor extends GenericAccessor {
|
||||
|
||||
MutableGenericAccessor getAccessor(Class<?> type, int ordinal);
|
||||
MutableGenericAccessor getAccessorOrThrow(Class<?> type, int ordinal);
|
||||
|
||||
void update(Consumer<GenericMutator> consumer);
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user