This annotation is marked with {@link ApiStatus.Internal}, indicating that it is for internal use only
* and should not be relied upon by external code.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.0
+ * @author CraftsBlock
* @see Transformer
* @since 3.0.2-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/BooleanTransformer.java b/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/BooleanTransformer.java
index 8d98bc28..b90fd2af 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/BooleanTransformer.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/BooleanTransformer.java
@@ -2,7 +2,6 @@
import de.craftsblock.craftsnet.api.transformers.Transformable;
import de.craftsblock.craftsnet.api.transformers.exceptions.NotTransformableException;
-import org.jetbrains.annotations.Nullable;
/**
* A transformer class for converting a string representation of a boolean value to a Boolean object.
@@ -10,7 +9,6 @@
*
* @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.1
* @see Transformable
* @since 3.0.2-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/ByteTransformer.java b/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/ByteTransformer.java
index 837c106f..132b7912 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/ByteTransformer.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/ByteTransformer.java
@@ -7,9 +7,8 @@
* A transformer class for converting a string representation of a byte value to a Byte object.
* Implements the {@link Transformable} interface.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.1
+ * @author CraftsBlock
* @see Transformable
* @since 3.0.2-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/DoubleTransformer.java b/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/DoubleTransformer.java
index e26b02fe..b4fab266 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/DoubleTransformer.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/DoubleTransformer.java
@@ -7,9 +7,8 @@
* A transformer class for converting a string representation of a double value to a Double object.
* Implements the {@link Transformable} interface.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.1
+ * @author CraftsBlock
* @see Transformable
* @since 3.0.2-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/FloatTransformer.java b/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/FloatTransformer.java
index f142eaa5..bbac8195 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/FloatTransformer.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/FloatTransformer.java
@@ -7,9 +7,8 @@
* A transformer class for converting a string representation of a float value to a Float object.
* Implements the {@link Transformable} interface.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.1
+ * @author CraftsBlock
* @see Transformable
* @since 3.0.2-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/IntTransformer.java b/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/IntTransformer.java
index de450895..cc4425ea 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/IntTransformer.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/IntTransformer.java
@@ -7,9 +7,8 @@
* A transformer class for converting a string representation of an integer value to an Integer object.
* Implements the {@link Transformable} interface.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.1
+ * @author CraftsBlock
* @see Transformable
* @since 3.0.2-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/LongTransformer.java b/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/LongTransformer.java
index 6188b5f5..c670d438 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/LongTransformer.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/LongTransformer.java
@@ -7,9 +7,8 @@
* A transformer class for converting a string representation of a long value to a Long object.
* Implements the {@link Transformable} interface.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.1
+ * @author CraftsBlock
* @see Transformable
* @since 3.0.2-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/ShortTransformer.java b/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/ShortTransformer.java
index 97019ab5..cdc9e06c 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/ShortTransformer.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/ShortTransformer.java
@@ -7,9 +7,8 @@
* A transformer class for converting a string representation of a short value to a Short object.
* Implements the {@link Transformable} interface.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.1
+ * @author CraftsBlock
* @see Transformable
* @since 3.0.2-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/UUIDTransformer.java b/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/UUIDTransformer.java
index 389666fc..5c6a0cc2 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/UUIDTransformer.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/transformers/builtin/UUIDTransformer.java
@@ -9,9 +9,8 @@
* A transformer class for converting a string representation of an uuid value to an {@link UUID} object.
* Implements the {@link Transformable} interface.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.0
+ * @author CraftsBlock
* @see Transformable
* @since 3.5.5
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/api/transformers/exceptions/NotTransformableException.java b/src/main/java/de/craftsblock/craftsnet/api/transformers/exceptions/NotTransformableException.java
index 347231ce..72b58cff 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/transformers/exceptions/NotTransformableException.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/transformers/exceptions/NotTransformableException.java
@@ -4,9 +4,8 @@
* This exception is thrown when a parameter cannot be transformed to a specified target type.
* It extends the TransformerException class, indicating a specific type of transformation failure.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.0
+ * @author CraftsBlock
* @see TransformerException
* @since 3.0.2-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/api/transformers/exceptions/TransformerException.java b/src/main/java/de/craftsblock/craftsnet/api/transformers/exceptions/TransformerException.java
index 18a16266..c4362ed4 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/transformers/exceptions/TransformerException.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/transformers/exceptions/TransformerException.java
@@ -4,9 +4,8 @@
* This class represents an exception that occurs during data transformation operations.
* It extends the RuntimeException class, making it an unchecked exception.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.0
+ * @author CraftsBlock
* @since 3.0.2-SNAPSHOT
*/
public class TransformerException extends RuntimeException {
diff --git a/src/main/java/de/craftsblock/craftsnet/api/utils/Context.java b/src/main/java/de/craftsblock/craftsnet/api/utils/Context.java
index 8e1392f1..a70774e3 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/utils/Context.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/utils/Context.java
@@ -12,9 +12,8 @@
* A specialized {@link ConcurrentHashMap} implementation that serves as a type-safe context
* for storing and retrieving objects associated with their respective {@link Class} types.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.0
+ * @author CraftsBlock
* @since 3.6.0
*/
public class Context extends ConcurrentHashMap, Object> {
diff --git a/src/main/java/de/craftsblock/craftsnet/api/utils/ProtocolVersion.java b/src/main/java/de/craftsblock/craftsnet/api/utils/ProtocolVersion.java
index b911f112..08fb00f3 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/utils/ProtocolVersion.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/utils/ProtocolVersion.java
@@ -14,7 +14,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.0
* @since 3.3.2-SNAPSHOT
*/
public record ProtocolVersion(@NotNull Scheme scheme, @Range(from = 0, to = Integer.MAX_VALUE) int major,
diff --git a/src/main/java/de/craftsblock/craftsnet/api/utils/Scheme.java b/src/main/java/de/craftsblock/craftsnet/api/utils/Scheme.java
index 8fbfb3d6..dc049d82 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/utils/Scheme.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/utils/Scheme.java
@@ -17,7 +17,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.1
* @since 3.3.2-SNAPSHOT
*/
public enum Scheme {
diff --git a/src/main/java/de/craftsblock/craftsnet/api/websocket/ClosureCode.java b/src/main/java/de/craftsblock/craftsnet/api/websocket/ClosureCode.java
index f3bb1f55..120ad63c 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/websocket/ClosureCode.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/websocket/ClosureCode.java
@@ -7,9 +7,8 @@
* Enumeration representing WebSocket closure codes along with their integer values and internal status.
* These codes are defined in RFC 6455 (https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1).
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.2.0
+ * @author CraftsBlock
* @since 3.0.5-SNAPSHOT
*/
public enum ClosureCode {
diff --git a/src/main/java/de/craftsblock/craftsnet/api/websocket/DefaultPingResponder.java b/src/main/java/de/craftsblock/craftsnet/api/websocket/DefaultPingResponder.java
index d03c4fc6..3d322b87 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/websocket/DefaultPingResponder.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/websocket/DefaultPingResponder.java
@@ -9,9 +9,8 @@
* A default implementation of a ping responder for handling incoming ping messages.
* This responder sends a pong message back to the client when a ping message is received.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.2
+ * @author CraftsBlock
* @see ReceivedPingMessageEvent
* @see WebSocketClient
* @since 3.0.5-SNAPSHOT
diff --git a/src/main/java/de/craftsblock/craftsnet/api/websocket/Frame.java b/src/main/java/de/craftsblock/craftsnet/api/websocket/Frame.java
index 334d737a..c3dc0546 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/websocket/Frame.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/websocket/Frame.java
@@ -37,9 +37,8 @@
* and decoding the payload data. It also provides methods to access frame attributes
* and manipulate the payload data.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.1.0
+ * @author CraftsBlock
* @since 3.0.6-SNAPSHOT
*/
public class Frame implements RequireAble {
diff --git a/src/main/java/de/craftsblock/craftsnet/api/websocket/Opcode.java b/src/main/java/de/craftsblock/craftsnet/api/websocket/Opcode.java
index 40dc8854..d00cfe26 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/websocket/Opcode.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/websocket/Opcode.java
@@ -8,9 +8,8 @@
* Enumeration representing WebSocket opcodes along with their integer values.
* These opcodes are defined in the WebSocket protocol.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.1.0
+ * @author CraftsBlock
* @since 3.0.5-SNAPSHOT
*/
public enum Opcode {
diff --git a/src/main/java/de/craftsblock/craftsnet/api/websocket/SocketExchange.java b/src/main/java/de/craftsblock/craftsnet/api/websocket/SocketExchange.java
index fc9bc924..e5eb9c0a 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/websocket/SocketExchange.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/websocket/SocketExchange.java
@@ -12,9 +12,8 @@
* with the WebSocket server and client within the context of a WebSocket connection.
* It allows sending broadcast messages to all clients connected to the same WebSocket path.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.3.1
+ * @author CraftsBlock
* @see BaseExchange
* @see Socket
* @see SocketHandler
diff --git a/src/main/java/de/craftsblock/craftsnet/api/websocket/SocketHandler.java b/src/main/java/de/craftsblock/craftsnet/api/websocket/SocketHandler.java
index deea84c6..9201319f 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/websocket/SocketHandler.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/websocket/SocketHandler.java
@@ -7,9 +7,8 @@
* Represents a contract for classes that handle WebSocket connections in a server application.
* WebSocket server handlers must implement this interface to define their behavior.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0
+ * @author CraftsBlock
* @see Socket
* @since 2.1.1-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/api/websocket/WebSocketClient.java b/src/main/java/de/craftsblock/craftsnet/api/websocket/WebSocketClient.java
index 9bfc2a2a..22704340 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/websocket/WebSocketClient.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/websocket/WebSocketClient.java
@@ -61,9 +61,8 @@
*
* The class also handles the disconnection of the client, sending messages, and reading headers and messages from the socket.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 3.8.1
+ * @author CraftsBlock
* @see WebSocketServer
* @since 2.1.1-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/api/websocket/WebSocketServer.java b/src/main/java/de/craftsblock/craftsnet/api/websocket/WebSocketServer.java
index c9afd280..9c20f51f 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/websocket/WebSocketServer.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/websocket/WebSocketServer.java
@@ -31,9 +31,8 @@
* The server can be configured to use SSL encryption by providing the necessary SSL key file.
* It uses a ServerSocket to listen for incoming connections on the specified port.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.2.5
+ * @author CraftsBlock
* @see WebSocketClient
* @since 2.1.1-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/api/websocket/annotations/ApplyDecoder.java b/src/main/java/de/craftsblock/craftsnet/api/websocket/annotations/ApplyDecoder.java
index 70c421b5..3edaea51 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/websocket/annotations/ApplyDecoder.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/websocket/annotations/ApplyDecoder.java
@@ -17,7 +17,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.0
* @see WebSocketSafeTypeDecoder
* @since 3.5.0
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/api/websocket/annotations/RequireMessageType.java b/src/main/java/de/craftsblock/craftsnet/api/websocket/annotations/RequireMessageType.java
index 46e26991..4edb8420 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/websocket/annotations/RequireMessageType.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/websocket/annotations/RequireMessageType.java
@@ -12,9 +12,8 @@
* Specifies the message type that should be received.
* This annotation can be applied to methods or classes.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.1.0
+ * @author CraftsBlock
* @see WebServer
* @since 3.0.5-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/api/websocket/annotations/Socket.java b/src/main/java/de/craftsblock/craftsnet/api/websocket/annotations/Socket.java
index ef1324c2..ba851608 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/websocket/annotations/Socket.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/websocket/annotations/Socket.java
@@ -10,9 +10,8 @@
/**
* Custom annotation used to mark classes as WebSocket handlers.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.1.0
+ * @author CraftsBlock
* @see SocketHandler
* @since 2.1.1-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/api/websocket/codec/WebSocketSafeTypeDecoder.java b/src/main/java/de/craftsblock/craftsnet/api/websocket/codec/WebSocketSafeTypeDecoder.java
index 55f60adc..53892723 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/websocket/codec/WebSocketSafeTypeDecoder.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/websocket/codec/WebSocketSafeTypeDecoder.java
@@ -12,7 +12,6 @@
* @param The result type produced after decoding the WebSocket {@link Frame}.
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.0
* @since 3.5.0
*/
public interface WebSocketSafeTypeDecoder extends Decoder {
diff --git a/src/main/java/de/craftsblock/craftsnet/api/websocket/codec/WebSocketSafeTypeEncoder.java b/src/main/java/de/craftsblock/craftsnet/api/websocket/codec/WebSocketSafeTypeEncoder.java
index eb2b09ff..67d9e3d0 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/websocket/codec/WebSocketSafeTypeEncoder.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/websocket/codec/WebSocketSafeTypeEncoder.java
@@ -20,7 +20,6 @@
* @param The input type to be encoded.
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.1.0
* @see TypeToBufferUtilEncoder
* @see TypeToByteArrayEncoder
* @see TypeToByteBufferEncoder
@@ -41,7 +40,6 @@ public sealed interface WebSocketSafeTypeEncoder extends Encoder
* @param The type of the object to encode.
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.0
* @since 3.5.0
*/
non-sealed interface TypeToByteArrayEncoder extends WebSocketSafeTypeEncoder {
@@ -53,7 +51,6 @@ non-sealed interface TypeToByteArrayEncoder extends WebSocketSafeTypeEncoder<
* @param The type of the object to encode.
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.0
* @since 3.7.0
*/
non-sealed interface TypeToBufferUtilEncoder extends WebSocketSafeTypeEncoder {
@@ -65,7 +62,6 @@ non-sealed interface TypeToBufferUtilEncoder extends WebSocketSafeTypeEncoder
* @param The type of the object to encode.
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.0
* @since 3.7.0
*/
non-sealed interface TypeToByteBufferEncoder extends WebSocketSafeTypeEncoder {
@@ -77,7 +73,6 @@ non-sealed interface TypeToByteBufferEncoder extends WebSocketSafeTypeEncoder
* @param The type of the object to encode.
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.0
* @since 3.5.0
* @deprecated in favor of {@link TypeToBufferUtilEncoder}
*/
@@ -94,7 +89,6 @@ non-sealed interface TypeToCraftsByteBufferEncoder extends WebSocketSafeTypeE
* @param The type of the object to encode.
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.0
* @since 3.5.0
*/
non-sealed interface TypeToJsonEncoder extends WebSocketSafeTypeEncoder {
@@ -107,7 +101,6 @@ non-sealed interface TypeToJsonEncoder extends WebSocketSafeTypeEncoder The type of the object to encode.
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.0
* @since 3.5.0
*/
non-sealed interface TypeToStringEncoder extends WebSocketSafeTypeEncoder {
diff --git a/src/main/java/de/craftsblock/craftsnet/api/websocket/extensions/WebSocketExtension.java b/src/main/java/de/craftsblock/craftsnet/api/websocket/extensions/WebSocketExtension.java
index 8aa263eb..8aab0624 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/websocket/extensions/WebSocketExtension.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/websocket/extensions/WebSocketExtension.java
@@ -12,9 +12,8 @@
* the {@link #encode(Frame)} and {@link #decode(Frame)} methods to define how frames
* are transformed by the extension.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.0
+ * @author CraftsBlock
* @since 3.0.6-SNAPSHOT
*/
public abstract class WebSocketExtension {
diff --git a/src/main/java/de/craftsblock/craftsnet/api/websocket/extensions/WebSocketExtensionRegistry.java b/src/main/java/de/craftsblock/craftsnet/api/websocket/extensions/WebSocketExtensionRegistry.java
index 129945dd..fab0a624 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/websocket/extensions/WebSocketExtensionRegistry.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/websocket/extensions/WebSocketExtensionRegistry.java
@@ -8,9 +8,8 @@
* unregistration, and lookup of WebSocket extensions by their protocol names. It is designed
* to be thread-safe, using a concurrent hash map to store the extensions.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.1
+ * @author CraftsBlock
* @since 3.0.6-SNAPSHOT
*/
public class WebSocketExtensionRegistry {
diff --git a/src/main/java/de/craftsblock/craftsnet/api/websocket/extensions/builtin/PerMessageDeflateExtension.java b/src/main/java/de/craftsblock/craftsnet/api/websocket/extensions/builtin/PerMessageDeflateExtension.java
index 67f0ab63..914943e0 100644
--- a/src/main/java/de/craftsblock/craftsnet/api/websocket/extensions/builtin/PerMessageDeflateExtension.java
+++ b/src/main/java/de/craftsblock/craftsnet/api/websocket/extensions/builtin/PerMessageDeflateExtension.java
@@ -16,9 +16,8 @@
* RFC 7692. This extension allows for
* compressing and decompressing WebSocket frames.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.0
+ * @author CraftsBlock
* @since 3.0.6-SNAPSHOT
*/
public class PerMessageDeflateExtension extends WebSocketExtension {
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/AutoRegisterHandler.java b/src/main/java/de/craftsblock/craftsnet/autoregister/AutoRegisterHandler.java
index f22d0833..a974467d 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/AutoRegisterHandler.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/AutoRegisterHandler.java
@@ -14,7 +14,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.1.0
* @since 3.2.0-SNAPSHOT
*/
public abstract class AutoRegisterHandler {
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/AutoRegisterRegistry.java b/src/main/java/de/craftsblock/craftsnet/autoregister/AutoRegisterRegistry.java
index d2687e50..5740cfb3 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/AutoRegisterRegistry.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/AutoRegisterRegistry.java
@@ -36,7 +36,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.2.5
* @see AutoRegisterInfo
* @see AutoRegisterHandler
* @since 3.2.0-SNAPSHOT
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/MiddlewareAutoRegisterHandler.java b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/MiddlewareAutoRegisterHandler.java
index 847442d5..bed49d29 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/MiddlewareAutoRegisterHandler.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/MiddlewareAutoRegisterHandler.java
@@ -13,7 +13,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.1
* @since 3.4.0-SNAPSHOT
*/
public class MiddlewareAutoRegisterHandler extends AutoRegisterHandler {
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/addons/ServiceLoaderAutoRegisterHandler.java b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/addons/ServiceLoaderAutoRegisterHandler.java
index b17f87a7..702bce5f 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/addons/ServiceLoaderAutoRegisterHandler.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/addons/ServiceLoaderAutoRegisterHandler.java
@@ -13,7 +13,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.4
* @since 3.2.0-SNAPSHOT
*/
public class ServiceLoaderAutoRegisterHandler extends AutoRegisterHandler> {
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/cli/LogStreamMutatorAutoRegisterHandler.java b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/cli/LogStreamMutatorAutoRegisterHandler.java
index 13f069e5..8a2deec9 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/cli/LogStreamMutatorAutoRegisterHandler.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/cli/LogStreamMutatorAutoRegisterHandler.java
@@ -13,7 +13,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.0
* @since 3.5.2
*/
public class LogStreamMutatorAutoRegisterHandler extends AutoRegisterHandler {
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/events/ListenerAutoRegisterHandler.java b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/events/ListenerAutoRegisterHandler.java
index 2eec2e49..3caa1bbf 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/events/ListenerAutoRegisterHandler.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/events/ListenerAutoRegisterHandler.java
@@ -13,7 +13,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.4
* @since 3.2.0-SNAPSHOT
*/
public class ListenerAutoRegisterHandler extends AutoRegisterHandler {
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/http/BodyAutoRegisterHandler.java b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/http/BodyAutoRegisterHandler.java
index 827eb094..46fe3f0a 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/http/BodyAutoRegisterHandler.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/http/BodyAutoRegisterHandler.java
@@ -14,7 +14,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.4
* @since 3.2.0-SNAPSHOT
*/
public class BodyAutoRegisterHandler extends AutoRegisterHandler> {
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/http/HandlerAutoRegisterHandler.java b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/http/HandlerAutoRegisterHandler.java
index 50351a17..15cecf38 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/http/HandlerAutoRegisterHandler.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/http/HandlerAutoRegisterHandler.java
@@ -13,7 +13,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.4
* @since 3.2.0-SNAPSHOT
*/
public class HandlerAutoRegisterHandler extends AutoRegisterHandler {
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/http/StreamEncoderAutoRegisterHandler.java b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/http/StreamEncoderAutoRegisterHandler.java
index f1e6b38f..224d45ee 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/http/StreamEncoderAutoRegisterHandler.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/http/StreamEncoderAutoRegisterHandler.java
@@ -13,7 +13,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.4
* @since 3.3.3-SNAPSHOT
*/
public class StreamEncoderAutoRegisterHandler extends AutoRegisterHandler {
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/http/WebRequirementAutoRegisterHandler.java b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/http/WebRequirementAutoRegisterHandler.java
index 58d438b6..fec229f0 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/http/WebRequirementAutoRegisterHandler.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/http/WebRequirementAutoRegisterHandler.java
@@ -13,7 +13,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.4
* @since 3.2.0-SNAPSHOT
*/
public class WebRequirementAutoRegisterHandler extends AutoRegisterHandler {
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/sockets/WebSocketExtensionAutoRegisterHandler.java b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/sockets/WebSocketExtensionAutoRegisterHandler.java
index f1501dbc..e6c03b3f 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/sockets/WebSocketExtensionAutoRegisterHandler.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/sockets/WebSocketExtensionAutoRegisterHandler.java
@@ -13,7 +13,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.4
* @since 3.2.0-SNAPSHOT
*/
public class WebSocketExtensionAutoRegisterHandler extends AutoRegisterHandler {
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/sockets/WebSocketRequirementAutoRegisterHandler.java b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/sockets/WebSocketRequirementAutoRegisterHandler.java
index 77684a2a..d86bc3b7 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/sockets/WebSocketRequirementAutoRegisterHandler.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/sockets/WebSocketRequirementAutoRegisterHandler.java
@@ -14,7 +14,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.4
* @since 3.2.0-SNAPSHOT
*/
public class WebSocketRequirementAutoRegisterHandler extends AutoRegisterHandler> {
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/sockets/codec/WebSocketTypeDecoderAutoRegisterHandler.java b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/sockets/codec/WebSocketTypeDecoderAutoRegisterHandler.java
index f928a855..03bb4a9b 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/sockets/codec/WebSocketTypeDecoderAutoRegisterHandler.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/sockets/codec/WebSocketTypeDecoderAutoRegisterHandler.java
@@ -13,7 +13,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.1
* @since 3.5.0
*/
public class WebSocketTypeDecoderAutoRegisterHandler extends AutoRegisterHandler> {
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/sockets/codec/WebSocketTypeEncoderAutoRegisterHandler.java b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/sockets/codec/WebSocketTypeEncoderAutoRegisterHandler.java
index 0b2a4f83..f8c430d1 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/sockets/codec/WebSocketTypeEncoderAutoRegisterHandler.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/builtin/sockets/codec/WebSocketTypeEncoderAutoRegisterHandler.java
@@ -13,7 +13,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.0
* @since 3.5.0
*/
public class WebSocketTypeEncoderAutoRegisterHandler extends AutoRegisterHandler> {
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/loaders/AutoRegisterLoader.java b/src/main/java/de/craftsblock/craftsnet/autoregister/loaders/AutoRegisterLoader.java
index 89f7a741..85008cd7 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/loaders/AutoRegisterLoader.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/loaders/AutoRegisterLoader.java
@@ -25,7 +25,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.2.2
* @see AutoRegisterInfo
* @since 3.2.0-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/meta/AutoRegister.java b/src/main/java/de/craftsblock/craftsnet/autoregister/meta/AutoRegister.java
index 4cf530ea..0e54ab4c 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/meta/AutoRegister.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/meta/AutoRegister.java
@@ -12,9 +12,8 @@
* The default value of the annotation is {@link Startup#ENABLE}, meaning auto registration
* is performed after the addon has been enabled.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.1.2
+ * @author CraftsBlock
* @since 3.2.0-SNAPSHOT
*/
@Documented
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/meta/Instantiate.java b/src/main/java/de/craftsblock/craftsnet/autoregister/meta/Instantiate.java
index 5f612d28..caa42a3c 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/meta/Instantiate.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/meta/Instantiate.java
@@ -10,7 +10,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.2
* @since 3.3.2-SNAPSHOT
*/
public enum Instantiate {
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/meta/constructors/ConstructorType.java b/src/main/java/de/craftsblock/craftsnet/autoregister/meta/constructors/ConstructorType.java
index 07108163..e255b6b5 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/meta/constructors/ConstructorType.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/meta/constructors/ConstructorType.java
@@ -13,7 +13,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.0
* @see FallbackConstructor
* @see IgnoreConstructor
* @see PreferConstructor
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/meta/constructors/FallbackConstructor.java b/src/main/java/de/craftsblock/craftsnet/autoregister/meta/constructors/FallbackConstructor.java
index ff7a3f99..6eb0e601 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/meta/constructors/FallbackConstructor.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/meta/constructors/FallbackConstructor.java
@@ -8,7 +8,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.0
* @since 3.3.5-SNAPSHOT
*/
@Documented
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/meta/constructors/IgnoreConstructor.java b/src/main/java/de/craftsblock/craftsnet/autoregister/meta/constructors/IgnoreConstructor.java
index 83b67c21..6e7cb27c 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/meta/constructors/IgnoreConstructor.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/meta/constructors/IgnoreConstructor.java
@@ -9,7 +9,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.0
* @since 3.3.5-SNAPSHOT
*/
@Documented
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/meta/constructors/PreferConstructor.java b/src/main/java/de/craftsblock/craftsnet/autoregister/meta/constructors/PreferConstructor.java
index 6d55c91b..9e040893 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/meta/constructors/PreferConstructor.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/meta/constructors/PreferConstructor.java
@@ -10,7 +10,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.0
* @since 3.3.5-SNAPSHOT
*/
@Documented
diff --git a/src/main/java/de/craftsblock/craftsnet/builder/ActivateType.java b/src/main/java/de/craftsblock/craftsnet/builder/ActivateType.java
index f85f3726..4366b0a9 100644
--- a/src/main/java/de/craftsblock/craftsnet/builder/ActivateType.java
+++ b/src/main/java/de/craftsblock/craftsnet/builder/ActivateType.java
@@ -3,9 +3,8 @@
/**
* Enum representing activation types for various components in the CraftsNet framework.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.0
+ * @author CraftsBlock
* @since 3.0.3
*/
public enum ActivateType {
diff --git a/src/main/java/de/craftsblock/craftsnet/builder/AddonContainingBuilder.java b/src/main/java/de/craftsblock/craftsnet/builder/AddonContainingBuilder.java
index 389ef434..71712ca3 100644
--- a/src/main/java/de/craftsblock/craftsnet/builder/AddonContainingBuilder.java
+++ b/src/main/java/de/craftsblock/craftsnet/builder/AddonContainingBuilder.java
@@ -19,9 +19,8 @@
/**
* Builder class for configuring the CraftsNet with a set of addons.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.3.2
+ * @author CraftsBlock
* @see CraftsNetBuilder
* @since 3.1.0-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/builder/CraftsNetBuilder.java b/src/main/java/de/craftsblock/craftsnet/builder/CraftsNetBuilder.java
index 88c097c0..04f901b5 100644
--- a/src/main/java/de/craftsblock/craftsnet/builder/CraftsNetBuilder.java
+++ b/src/main/java/de/craftsblock/craftsnet/builder/CraftsNetBuilder.java
@@ -16,9 +16,8 @@
/**
* Builder class for configuring the CraftsNet.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.2.3
+ * @author CraftsBlock
* @see ActivateType
* @since 3.0.3-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/events/EventWithCancelReason.java b/src/main/java/de/craftsblock/craftsnet/events/EventWithCancelReason.java
index f0b55cf9..d167047a 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/EventWithCancelReason.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/EventWithCancelReason.java
@@ -6,9 +6,8 @@
* An abstract class extending {@link CancellableEvent}, providing the ability to set and retrieve
* a custom cancellation reason. It can be used by listeners to communicate why an event was canceled.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.0
+ * @author CraftsBlock
* @see CancellableEvent
* @since 3.1.0-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/events/addons/AllAddonsDisabledEvent.java b/src/main/java/de/craftsblock/craftsnet/events/addons/AllAddonsDisabledEvent.java
index c3c45c41..6d7c870c 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/addons/AllAddonsDisabledEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/addons/AllAddonsDisabledEvent.java
@@ -6,9 +6,8 @@
* The {@link AllAddonsDisabledEvent} class represents an event triggered when all addons are disabled within CraftsNet.
* This event serves as a notification mechanism to inform listeners that all addons have been successfully disabled.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.0
+ * @author CraftsBlock
* @since 3.4.2-SNAPSHOT
*/
public class AllAddonsDisabledEvent extends Event {
diff --git a/src/main/java/de/craftsblock/craftsnet/events/addons/AllAddonsLoadedEvent.java b/src/main/java/de/craftsblock/craftsnet/events/addons/AllAddonsLoadedEvent.java
index 1a98060b..b4f38a3b 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/addons/AllAddonsLoadedEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/addons/AllAddonsLoadedEvent.java
@@ -9,9 +9,8 @@
* By listening for this event, developers can perform additional actions or initialization steps
* that depend on the availability of addons within the application environment.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.0
+ * @author CraftsBlock
* @since 3.0.3-SNAPSHOT
*/
public class AllAddonsLoadedEvent extends Event {
diff --git a/src/main/java/de/craftsblock/craftsnet/events/requests/GenericRequestEventBase.java b/src/main/java/de/craftsblock/craftsnet/events/requests/GenericRequestEventBase.java
index 791cdcaf..32937d12 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/requests/GenericRequestEventBase.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/requests/GenericRequestEventBase.java
@@ -10,7 +10,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.1
* @see Exchange
* @see Request
* @see Response
diff --git a/src/main/java/de/craftsblock/craftsnet/events/requests/PostRequestEvent.java b/src/main/java/de/craftsblock/craftsnet/events/requests/PostRequestEvent.java
index 02932ca1..368ea13b 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/requests/PostRequestEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/requests/PostRequestEvent.java
@@ -11,7 +11,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.1.1
* @see GenericRequestEventBase
* @since 3.1.0-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/events/requests/PreRequestEvent.java b/src/main/java/de/craftsblock/craftsnet/events/requests/PreRequestEvent.java
index 17db2112..7e6b4c66 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/requests/PreRequestEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/requests/PreRequestEvent.java
@@ -12,7 +12,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.1.1
* @see GenericRequestEventBase
* @since 3.1.0-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/events/requests/routes/RouteRequestEvent.java b/src/main/java/de/craftsblock/craftsnet/events/requests/routes/RouteRequestEvent.java
index 43b16c47..2ff2803d 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/requests/routes/RouteRequestEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/requests/routes/RouteRequestEvent.java
@@ -13,9 +13,8 @@
* This class provides information about the {@link Exchange} and the {@link RouteRegistry.EndpointMapping}
* involved in the request event.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.2.1
+ * @author CraftsBlock
* @see EventWithCancelReason
* @see GenericRequestEventBase
* @since 1.0.0-SNAPSHOT
diff --git a/src/main/java/de/craftsblock/craftsnet/events/requests/shares/ShareFileLoadedEvent.java b/src/main/java/de/craftsblock/craftsnet/events/requests/shares/ShareFileLoadedEvent.java
index 457c8349..32f093b2 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/requests/shares/ShareFileLoadedEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/requests/shares/ShareFileLoadedEvent.java
@@ -16,9 +16,8 @@
* Represents an event that is triggered when a share file has been loaded.
* This event provides information about the loaded file.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.2.1
+ * @author CraftsBlock
* @see CancellableEvent
* @see GenericRequestEventBase
* @since 2.3.2-SNAPSHOT
diff --git a/src/main/java/de/craftsblock/craftsnet/events/requests/shares/ShareRequestEvent.java b/src/main/java/de/craftsblock/craftsnet/events/requests/shares/ShareRequestEvent.java
index 88b16ae7..4d3500c4 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/requests/shares/ShareRequestEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/requests/shares/ShareRequestEvent.java
@@ -15,9 +15,8 @@
* Represents an event that is triggered when a share request is made.
* This event can be canceled to prevent the share request from being processed.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.1.1
+ * @author CraftsBlock
* @see EventWithCancelReason
* @see GenericRequestEventBase
* @since 2.3.2-SNAPSHOT
diff --git a/src/main/java/de/craftsblock/craftsnet/events/sockets/ClientConnectEvent.java b/src/main/java/de/craftsblock/craftsnet/events/sockets/ClientConnectEvent.java
index c1dd49f4..136eb9f6 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/sockets/ClientConnectEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/sockets/ClientConnectEvent.java
@@ -13,9 +13,8 @@
* The ClientConnectEvent class represents an event related to a client connection to a socket.
* It extends the base {@link EventWithCancelReason} to support event cancellation.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.2.0
+ * @author CraftsBlock
* @see EventWithCancelReason
* @see GenericSocketEventBase
* @since 2.1.1-SNAPSHOT
diff --git a/src/main/java/de/craftsblock/craftsnet/events/sockets/ClientDisconnectEvent.java b/src/main/java/de/craftsblock/craftsnet/events/sockets/ClientDisconnectEvent.java
index 4cbca245..b0f41066 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/sockets/ClientDisconnectEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/sockets/ClientDisconnectEvent.java
@@ -14,9 +14,8 @@
* The ClientDisconnectEvent class represents an event related to a client disconnection from a websocket connection.
* It extends the base Event class and provides information about the SocketExchange and the SocketMapping associated with the disconnection event.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.1.0
+ * @author CraftsBlock
* @see GenericSocketEventBase
* @since 2.1.1-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/events/sockets/GenericSocketEventBase.java b/src/main/java/de/craftsblock/craftsnet/events/sockets/GenericSocketEventBase.java
index 43269de9..d942ae6c 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/sockets/GenericSocketEventBase.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/sockets/GenericSocketEventBase.java
@@ -10,7 +10,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.0
* @see SocketExchange
* @see WebSocketClient
* @see WebSocketServer
diff --git a/src/main/java/de/craftsblock/craftsnet/events/sockets/message/GenericSocketMessageEventBase.java b/src/main/java/de/craftsblock/craftsnet/events/sockets/message/GenericSocketMessageEventBase.java
index 49866f5d..0d116a84 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/sockets/message/GenericSocketMessageEventBase.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/sockets/message/GenericSocketMessageEventBase.java
@@ -14,7 +14,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.1.0
* @see Frame
* @see ByteBuffer
* @see Opcode
diff --git a/src/main/java/de/craftsblock/craftsnet/events/sockets/message/IncomingSocketMessageEvent.java b/src/main/java/de/craftsblock/craftsnet/events/sockets/message/IncomingSocketMessageEvent.java
index 08cf09f4..567fab1a 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/sockets/message/IncomingSocketMessageEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/sockets/message/IncomingSocketMessageEvent.java
@@ -9,9 +9,8 @@
* The IncomingSocketMessageEvent class represents an event related to an incoming message on a websocket connection.
* It extends the base {@link CancellableEvent} to support event cancellation.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.2.0
+ * @author CraftsBlock
* @see GenericSocketMessageEventBase
* @since 2.1.1-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/events/sockets/message/OutgoingSocketMessageEvent.java b/src/main/java/de/craftsblock/craftsnet/events/sockets/message/OutgoingSocketMessageEvent.java
index 3c145c14..efc7228e 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/sockets/message/OutgoingSocketMessageEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/sockets/message/OutgoingSocketMessageEvent.java
@@ -10,9 +10,8 @@
* The OutgoingSocketMessageEvent class represents an event related to an outgoing message on a websocket connection.
* It extends the base {@link CancellableEvent} to support event cancellation.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.1.0
+ * @author CraftsBlock
* @see GenericSocketMessageEventBase
* @since 2.1.1-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/events/sockets/message/ReceivedPingMessageEvent.java b/src/main/java/de/craftsblock/craftsnet/events/sockets/message/ReceivedPingMessageEvent.java
index e9e08004..6590bef6 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/sockets/message/ReceivedPingMessageEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/sockets/message/ReceivedPingMessageEvent.java
@@ -11,9 +11,8 @@
/**
* An event indicating that a Ping message has been received.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.1.0
+ * @author CraftsBlock
* @see GenericSocketMessageEventBase
* @since 3.0.5-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/events/sockets/message/ReceivedPongMessageEvent.java b/src/main/java/de/craftsblock/craftsnet/events/sockets/message/ReceivedPongMessageEvent.java
index fe79c90e..b302e25e 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/sockets/message/ReceivedPongMessageEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/sockets/message/ReceivedPongMessageEvent.java
@@ -11,9 +11,8 @@
/**
* An event indicating that a Pong message has been received.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.1.0
+ * @author CraftsBlock
* @see GenericSocketMessageEventBase
* @since 3.0.5-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/logging/LogLevel.java b/src/main/java/de/craftsblock/craftsnet/logging/LogLevel.java
index 8d7e2851..af71800f 100644
--- a/src/main/java/de/craftsblock/craftsnet/logging/LogLevel.java
+++ b/src/main/java/de/craftsblock/craftsnet/logging/LogLevel.java
@@ -4,9 +4,8 @@
* An enumeration of log levels used for categorizing log messages.
* Each log level has an associated color-coded prefix for formatting purposes.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.0.1
+ * @author CraftsBlock
* @since 3.1.0-SNAPSHOT
*/
public enum LogLevel {
diff --git a/src/main/java/de/craftsblock/craftsnet/logging/Logger.java b/src/main/java/de/craftsblock/craftsnet/logging/Logger.java
index 58d81b58..e8ca9406 100644
--- a/src/main/java/de/craftsblock/craftsnet/logging/Logger.java
+++ b/src/main/java/de/craftsblock/craftsnet/logging/Logger.java
@@ -9,9 +9,8 @@
* Implementations of this interface can be used for logging messages to various destinations
* such as console, files, databases, etc.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 2.1.0
+ * @author CraftsBlock
* @since 1.0.0-SNAPSHOT
*/
public interface Logger {
diff --git a/src/main/java/de/craftsblock/craftsnet/logging/impl/LoggerImpl.java b/src/main/java/de/craftsblock/craftsnet/logging/impl/LoggerImpl.java
index cd827374..277671b1 100644
--- a/src/main/java/de/craftsblock/craftsnet/logging/impl/LoggerImpl.java
+++ b/src/main/java/de/craftsblock/craftsnet/logging/impl/LoggerImpl.java
@@ -17,9 +17,8 @@
* to log error messages along with exception stack traces. The log messages include timestamps, log levels, thread names, and the
* actual log text to help with debugging and tracking application behavior.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.1.0
+ * @author CraftsBlock
* @since 3.0.5-SNAPSHOT
*/
public class LoggerImpl implements Logger {
diff --git a/src/main/java/de/craftsblock/craftsnet/logging/impl/NoOpLogger.java b/src/main/java/de/craftsblock/craftsnet/logging/impl/NoOpLogger.java
index 06676554..62777495 100644
--- a/src/main/java/de/craftsblock/craftsnet/logging/impl/NoOpLogger.java
+++ b/src/main/java/de/craftsblock/craftsnet/logging/impl/NoOpLogger.java
@@ -9,9 +9,8 @@
* The {@link NoOpLogger} simply accepts log messages and errors but does not process
* them in any way.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.1.1
+ * @author CraftsBlock
* @since 3.4.0-SNAPSHOT
*/
public record NoOpLogger(Logger previous) implements Logger {
diff --git a/src/main/java/de/craftsblock/craftsnet/logging/impl/PlainLogger.java b/src/main/java/de/craftsblock/craftsnet/logging/impl/PlainLogger.java
index 41b603a7..6ab4b71a 100644
--- a/src/main/java/de/craftsblock/craftsnet/logging/impl/PlainLogger.java
+++ b/src/main/java/de/craftsblock/craftsnet/logging/impl/PlainLogger.java
@@ -9,9 +9,8 @@
* in the {@link System#out} or the {@link System#err} stream, without any
* further formating.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.1.0
+ * @author CraftsBlock
* @since 3.1.0-SNAPSHOT
*/
public record PlainLogger(Logger previous) implements Logger {
diff --git a/src/main/java/de/craftsblock/craftsnet/logging/mutate/LogStream.java b/src/main/java/de/craftsblock/craftsnet/logging/mutate/LogStream.java
index 4bbfb592..ddd3180c 100644
--- a/src/main/java/de/craftsblock/craftsnet/logging/mutate/LogStream.java
+++ b/src/main/java/de/craftsblock/craftsnet/logging/mutate/LogStream.java
@@ -31,9 +31,8 @@
* A utility class for logging to files.
* This class provides methods to log messages to files, handle error logs, and redirect standard output and error streams to log files.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.2.6
+ * @author CraftsBlock
* @see MutatedPrintStream
* @since 3.0.2-SNAPSHOT
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/logging/mutate/LogStreamMutator.java b/src/main/java/de/craftsblock/craftsnet/logging/mutate/LogStreamMutator.java
index f359f805..d8862967 100644
--- a/src/main/java/de/craftsblock/craftsnet/logging/mutate/LogStreamMutator.java
+++ b/src/main/java/de/craftsblock/craftsnet/logging/mutate/LogStreamMutator.java
@@ -11,7 +11,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.1
* @see LogStream
* @since 3.5.0
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/logging/mutate/builtin/BlurIPsMutator.java b/src/main/java/de/craftsblock/craftsnet/logging/mutate/builtin/BlurIPsMutator.java
index db2563ac..2ac9f265 100644
--- a/src/main/java/de/craftsblock/craftsnet/logging/mutate/builtin/BlurIPsMutator.java
+++ b/src/main/java/de/craftsblock/craftsnet/logging/mutate/builtin/BlurIPsMutator.java
@@ -17,7 +17,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.0
* @see Utils#blurIPs(String)
* @since 3.5.0
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/logging/mutate/stream/LogOutputStream.java b/src/main/java/de/craftsblock/craftsnet/logging/mutate/stream/LogOutputStream.java
index 881e9685..a8fedebd 100644
--- a/src/main/java/de/craftsblock/craftsnet/logging/mutate/stream/LogOutputStream.java
+++ b/src/main/java/de/craftsblock/craftsnet/logging/mutate/stream/LogOutputStream.java
@@ -16,7 +16,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.0
* @since 3.5.4
*/
public class LogOutputStream extends FilterOutputStream {
diff --git a/src/main/java/de/craftsblock/craftsnet/logging/mutate/stream/MutatedPrintStream.java b/src/main/java/de/craftsblock/craftsnet/logging/mutate/stream/MutatedPrintStream.java
index b0d71b9a..7fed072b 100644
--- a/src/main/java/de/craftsblock/craftsnet/logging/mutate/stream/MutatedPrintStream.java
+++ b/src/main/java/de/craftsblock/craftsnet/logging/mutate/stream/MutatedPrintStream.java
@@ -12,9 +12,8 @@
* A subclass of {@link PrintStream} used for logging.
* This class intercepts the output written to the stream and writes it to the provided output stream while removing any ASCII colors.
*
- * @author CraftsBlock
* @author Philipp Maywald
- * @version 1.3.0
+ * @author CraftsBlock
* @since 3.0.2-SNAPSHOT
*/
public class MutatedPrintStream extends PrintStream {
diff --git a/src/main/java/de/craftsblock/craftsnet/utils/ByteBuffer.java b/src/main/java/de/craftsblock/craftsnet/utils/ByteBuffer.java
index 370dc203..942695ee 100644
--- a/src/main/java/de/craftsblock/craftsnet/utils/ByteBuffer.java
+++ b/src/main/java/de/craftsblock/craftsnet/utils/ByteBuffer.java
@@ -20,7 +20,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.1
* @since 3.1.0-SNAPSHOT
* @deprecated in favor of {@link java.nio.ByteBuffer} and {@link de.craftsblock.craftscore.buffer.BufferUtil}
*/
diff --git a/src/main/java/de/craftsblock/craftsnet/utils/FileHelper.java b/src/main/java/de/craftsblock/craftsnet/utils/FileHelper.java
index bbd7d609..ab5237bc 100644
--- a/src/main/java/de/craftsblock/craftsnet/utils/FileHelper.java
+++ b/src/main/java/de/craftsblock/craftsnet/utils/FileHelper.java
@@ -27,7 +27,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.2
* @since 3.1.0-SNAPSHOT
*/
public class FileHelper {
diff --git a/src/main/java/de/craftsblock/craftsnet/utils/PassphraseUtils.java b/src/main/java/de/craftsblock/craftsnet/utils/PassphraseUtils.java
index 25eedc96..7ac8a771 100644
--- a/src/main/java/de/craftsblock/craftsnet/utils/PassphraseUtils.java
+++ b/src/main/java/de/craftsblock/craftsnet/utils/PassphraseUtils.java
@@ -14,7 +14,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 2.1.0
* @since 3.3.5-SNAPSHOT
*/
public class PassphraseUtils {
diff --git a/src/main/java/de/craftsblock/craftsnet/utils/SecureEncodingUtils.java b/src/main/java/de/craftsblock/craftsnet/utils/SecureEncodingUtils.java
index 185365ab..a2711430 100644
--- a/src/main/java/de/craftsblock/craftsnet/utils/SecureEncodingUtils.java
+++ b/src/main/java/de/craftsblock/craftsnet/utils/SecureEncodingUtils.java
@@ -18,7 +18,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.1.1
* @since 3.4.1-SNAPSHOT
*/
public class SecureEncodingUtils {
diff --git a/src/main/java/de/craftsblock/craftsnet/utils/Utils.java b/src/main/java/de/craftsblock/craftsnet/utils/Utils.java
index 8782ae67..5585f80e 100644
--- a/src/main/java/de/craftsblock/craftsnet/utils/Utils.java
+++ b/src/main/java/de/craftsblock/craftsnet/utils/Utils.java
@@ -12,7 +12,6 @@
*
* @author CraftsBlock
* @author Philipp Maywald
- * @version 2.2.1
* @since 2.1.1-SNAPSHOT
*/
public class Utils {
diff --git a/src/main/java/de/craftsblock/craftsnet/utils/reflection/ReflectionUtils.java b/src/main/java/de/craftsblock/craftsnet/utils/reflection/ReflectionUtils.java
index d865b3e2..cd4d2ae0 100644
--- a/src/main/java/de/craftsblock/craftsnet/utils/reflection/ReflectionUtils.java
+++ b/src/main/java/de/craftsblock/craftsnet/utils/reflection/ReflectionUtils.java
@@ -16,7 +16,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.4.4
* @since 3.2.0-SNAPSHOT
*/
public class ReflectionUtils {
diff --git a/src/main/java/de/craftsblock/craftsnet/utils/reflection/TypeUtils.java b/src/main/java/de/craftsblock/craftsnet/utils/reflection/TypeUtils.java
index 10838d1c..a1deb074 100644
--- a/src/main/java/de/craftsblock/craftsnet/utils/reflection/TypeUtils.java
+++ b/src/main/java/de/craftsblock/craftsnet/utils/reflection/TypeUtils.java
@@ -18,7 +18,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0.3
* @since 3.5.0
*/
public class TypeUtils {
diff --git a/src/main/java/de/craftsblock/craftsnet/utils/versions/Comparison.java b/src/main/java/de/craftsblock/craftsnet/utils/versions/Comparison.java
index 7c334833..19af8512 100644
--- a/src/main/java/de/craftsblock/craftsnet/utils/versions/Comparison.java
+++ b/src/main/java/de/craftsblock/craftsnet/utils/versions/Comparison.java
@@ -13,7 +13,6 @@
*
* @author Philipp Maywald
* @author CraftsBlock
- * @version 1.0
* @since 3.1.0-SNAPSHOT
*/
enum Comparison {
From e8d0a4dcb038816e3fd4d35a68f42c7f32398b61 Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Sun, 29 Mar 2026 19:26:37 +0200
Subject: [PATCH 03/23] fix: Sort addons correctly respecting thier depends
(#33)
---
.../addon/loaders/AddonLoadOrder.java | 315 +++++++++++-------
1 file changed, 187 insertions(+), 128 deletions(-)
diff --git a/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoadOrder.java b/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoadOrder.java
index 6381de42..09aad062 100644
--- a/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoadOrder.java
+++ b/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoadOrder.java
@@ -1,208 +1,277 @@
package de.craftsblock.craftsnet.addon.loaders;
import de.craftsblock.craftsnet.addon.Addon;
-import de.craftsblock.craftsnet.autoregister.loaders.AutoRegisterLoader;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable;
import java.io.Closeable;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
import java.util.*;
-import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* Represents a system for managing the load order of addons.
- * This class may be used to organize and control the order in which addons are loaded or executed.
- * It provides methods for adding addons, specifying dependencies, and retrieving the load order.
*
- * @author CraftsBlock
+ * This implementation is based on a directed dependency graph and uses
+ * a topological sorting algorithm (Kahn's Algorithm) to determine a valid
+ * and efficient load order.
+ *
* @author Philipp Maywald
+ * @author CraftsBlock
* @since 3.0.2-SNAPSHOT
*/
-final class AddonLoadOrder implements Closeable {
+public final class AddonLoadOrder implements Closeable {
+
+ /**
+ * Stores all known addons mapped by their name.
+ */
+ private final Map addonLoadOrder =
+ Collections.synchronizedMap(new LinkedHashMap<>());
+
+ /**
+ * Stores required dependencies.
+ */
+ private final Map> dependencies = new HashMap<>();
- private final Map addonLoadOrder = Collections.synchronizedMap(new LinkedHashMap<>());
+ /**
+ * Stores optional dependencies.
+ */
+ private final Map> softDependencies = new HashMap<>();
/**
- * Adds an Addon to the system, considering its load order.
- * The method utilizes a ConcurrentHashMap to efficiently manage the load order of addons based on their names.
- * If an addon with the same name already exists, the load order is updated accordingly.
+ * Adds an Addon to the system.
*
- * @param addon The Addon object to be added to the system.
+ * @param addon The Addon to add
*/
public void addAddon(Addon addon) {
- addonLoadOrder.compute(addon.getName(), (name, bootMapping) ->
- (bootMapping == null) ? new BootMapping(name, 0, addon, true) : bootMapping.addon(addon));
+ addonLoadOrder.compute(
+ addon.getName(),
+ (name, mapping) -> {
+ if (mapping == null) {
+ return new BootMapping(name, addon, true);
+ }
+
+ return mapping.setAddon(addon);
+ }
+ );
}
/**
- * Perform cleanup for the current {@link AddonLoadOrder}
- * when it is no longer used.
+ * Clears all stored data.
*/
@Override
public void close() {
addonLoadOrder.clear();
+ dependencies.clear();
+ softDependencies.clear();
}
/**
- * Checks if the specified addon is present in the addon load order and has a non-null association.
+ * Checks if the given addon exists.
*
- * @param addon The addon to be checked for presence.
- * @return true if the addon is present in the addon load order and has a non-null association, false otherwise.
+ * @param addon The addon instance
+ * @return true if present
*/
public boolean contains(Addon addon) {
return contains(addon.getName());
}
/**
- * Checks if the specified addon is present in the addon load order and has a non-null association.
+ * Checks if the given addon exists.
*
- * @param addon The addon to be checked for presence.
- * @return true if the addon is present in the addon load order and has a non-null association, false otherwise.
+ * @param addon The addon name
+ * @return true if present
*/
public boolean contains(String addon) {
- return addonLoadOrder.containsKey(addon) && addonLoadOrder.get(addon).addon() != null;
+ return addonLoadOrder.containsKey(addon)
+ && addonLoadOrder.get(addon).getAddon() != null;
}
/**
- * Registers a required dependency for the specified addon.
+ * Registers a required dependency.
*
- * @param addon the addon that declares the dependency
- * @param dependsOn the name of the addon that is depended on
+ * @param addon The addon declaring the dependency
+ * @param dependsOn The required dependency
*/
public void depends(String addon, String dependsOn) {
- this.dryDepends(addon, dependsOn, true);
+ dryDepends(addon, dependsOn, dependencies, true);
}
/**
- * Registers an optional (soft) dependency for the specified addon.
+ * Registers an optional dependency.
*
- * @param addon the addon that declares the dependency
- * @param dependsOn the name of the addon that is optionally depended on
- * @since 3.3.4-SNAPSHOT
+ * @param addon The addon declaring the dependency
+ * @param dependsOn The optional dependency
*/
public void softDepends(String addon, String dependsOn) {
- this.dryDepends(addon, dependsOn, false);
+ this.dryDepends(addon, dependsOn, softDependencies, false);
}
/**
- * Registers a dependency for the specified addon on another addon.
- *
- * The dependency can be either required or optional based on the {@code required} parameter.
- * This method updates the internal addon load order by merging a new {@link BootMapping} into the existing mapping.
- * If a dependency mapping for {@code dependsOn} already exists, the method adjusts its priority and, if necessary,
- * marks it as required.
- *
+ * Registers a dependency with the specified required state.
*
- * @param addon the addon that declares the dependency
- * @param dependsOn the name of the addon that is being depended on
- * @param required {@code true} if the dependency is required, {@code false} otherwise.
- * @throws IllegalStateException if the addon attempts to depend on itself
- * @since 3.3.4-SNAPSHOT
+ * @param addon The addon declaring the dependency.
+ * @param dependsOn The dependency.
+ * @param dependencies The dependencies the dependency should be registered to.
+ * @param required Whether the dependency is forcibly required.
*/
- private void dryDepends(String addon, String dependsOn, boolean required) {
- if (addon.equalsIgnoreCase(dependsOn)) {
- throw new IllegalStateException("Can not add " + addon + " as depends to itself!");
+ private void dryDepends(String addon, String dependsOn,
+ Map> dependencies,
+ boolean required) {
+ validateSelfDependency(addon, dependsOn);
+
+ dependencies.computeIfAbsent(addon, k -> new HashSet<>())
+ .add(dependsOn);
+
+ addonLoadOrder.putIfAbsent(addon, new BootMapping(addon, null, false));
+
+ if (addonLoadOrder.containsKey(dependsOn)) {
+ addonLoadOrder.get(dependsOn).mergeRequired(required);
+ } else {
+ addonLoadOrder.put(dependsOn, new BootMapping(dependsOn, null, required));
}
+ }
- final int addonPriority = getPriority(addon);
- addonLoadOrder.merge(dependsOn, new BootMapping(dependsOn, addonPriority + 1, null, required),
- (existingMapping, newMapping) -> {
- int dependsOnPriority = getPriority(dependsOn);
+ /**
+ * Creates a new sorted stream of the currently registered
+ * {@link BootMapping}'s.
+ *
+ * @return The created and sorted stream.
+ */
+ private @Unmodifiable Stream createSortedBootMappingStream() {
+ Map> graph = new HashMap<>();
+ Map inDegree = new HashMap<>();
- if (required) {
- existingMapping.require();
- }
+ for (String name : addonLoadOrder.keySet()) {
+ graph.putIfAbsent(name, new ArrayList<>());
+ inDegree.putIfAbsent(name, 0);
+ }
+
+ for (Map.Entry> entry : dependencies.entrySet()) {
+ String addon = entry.getKey();
- return (addonPriority <= dependsOnPriority) ?
- existingMapping.priority(addonPriority + 1) :
- existingMapping;
- });
+ for (String dep : entry.getValue()) {
+ if (!addonLoadOrder.containsKey(dep)) {
+ throw new IllegalStateException("Missing required dependency: " + dep);
+ }
+
+ graph.computeIfAbsent(dep, k -> new ArrayList<>()).add(addon);
+ inDegree.put(addon, inDegree.getOrDefault(addon, 0) + 1);
+ }
+ }
+
+ for (Map.Entry> entry : softDependencies.entrySet()) {
+ String addon = entry.getKey();
+
+ for (String dep : entry.getValue()) {
+ if (!addonLoadOrder.containsKey(dep)) {
+ continue;
+ }
+
+ graph.computeIfAbsent(dep, k -> new ArrayList<>()).add(addon);
+ inDegree.put(addon, inDegree.getOrDefault(addon, 0) + 1);
+ }
+ }
+
+ Queue queue = new ArrayDeque<>();
+ for (Map.Entry entry : inDegree.entrySet()) {
+ if (entry.getValue() == 0) {
+ queue.add(entry.getKey());
+ }
+ }
+
+ List sorted = new ArrayList<>();
+ while (!queue.isEmpty()) {
+ String current = queue.poll();
+ sorted.add(current);
+
+ for (String next : graph.getOrDefault(current, Collections.emptyList())) {
+ int newDegree = inDegree.merge(next, -1, Integer::sum);
+ if (newDegree == 0) {
+ queue.add(next);
+ }
+ }
+ }
+
+ if (sorted.size() != addonLoadOrder.size()) {
+ throw new IllegalStateException("Dependency cycle detected!");
+ }
+
+ return sorted.stream().map(addonLoadOrder::get);
}
/**
- * Retrieves an unmodifiable collection representing the load order of addons names.
- * The method generates a sorted list of addon names based on their load priorities,
- * and then maps the names to their corresponding addons using the addonLoadOrder map.
+ * Builds and returns the final load order.
+ *
+ * This method performs a topological sort over the dependency graph.
*
- * @return An unmodifiable Collection of addons, representing the load order.
- * @since 3.4.3
+ * @return ordered list of addons
+ * @throws IllegalStateException if dependencies are missing or cyclic
*/
public @Unmodifiable List getPreLoadOrder() {
- List bootOrderList = new ArrayList<>(addonLoadOrder.keySet());
- bootOrderList.sort(Comparator.comparingInt(value -> addonLoadOrder.get(value.toString()).priority()).reversed());
- return bootOrderList;
+ return createSortedBootMappingStream()
+ .filter(Objects::nonNull)
+ .map(BootMapping::getName)
+ .toList();
}
/**
- * Retrieves an unmodifiable collection representing the load order of addons.
- * The resulting list of addons is filtered to exclude any null values, and the final collection is returned.
+ * Builds and returns the final load order.
+ *
+ * This method performs a topological sort over the dependency graph.
*
- * @return An unmodifiable Collection of addons, representing the load order.
+ * @return ordered list of addons
+ * @throws IllegalStateException if dependencies are missing or cyclic
*/
public @Unmodifiable List getLoadOrder() {
- return getPreLoadOrder().stream()
- .map(addonLoadOrder::get)
+ return createSortedBootMappingStream()
.filter(Objects::nonNull)
.filter(BootMapping::presenceFilter)
- .sorted((o1, o2) -> Integer.compare(o2.priority(), o1.priority()))
- .map(BootMapping::addon)
+ .map(BootMapping::getAddon)
.filter(Objects::nonNull)
- .collect(Collectors.toCollection(ArrayList::new));
+ .toList();
}
/**
- * Retrieves the priority of an addon in the load order.
- * If the addon is not found in the load order, a default BootMapping with priority 0 is used.
- *
- * @param addon The name of the addon for which the priority is to be retrieved.
- * @return The priority of the specified addon in the load order.
+ * Validates that an addon does not depend on itself.
*/
- private int getPriority(String addon) {
- if (addonLoadOrder.containsKey(addon)) {
- return addonLoadOrder.get(addon).priority();
+ private void validateSelfDependency(String addon, String dependsOn) {
+ if (addon.equalsIgnoreCase(dependsOn)) {
+ throw new IllegalStateException("Can not add " + addon + " as depends to itself!");
}
-
- return 0;
}
/**
- * Represents a mapping used in the context of addon load order, associating a priority level with an addon.
- * This class is utilized for organizing and managing the load order of addons within the system.
+ * Represents an internal mapping for an addon.
*/
private static class BootMapping {
private final String name;
- private int priority;
- private Addon addon;
private boolean required;
+ private Addon addon;
/**
- * Constructs a BootMapping with the specified priority and addon.
+ * Constructs a BootMapping for the specified addon.
*
* @param name The name of the addon.
- * @param priority The priority level assigned to the addon in the load order.
* @param addon The addon associated with this mapping.
* @param required Whether this {@link BootMapping} is required to properly start or not.
*/
- public BootMapping(@NotNull String name, int priority, @Nullable Addon addon, boolean required) {
+ public BootMapping(@NotNull String name,
+ @Nullable Addon addon,
+ boolean required) {
this.name = name;
- this.priority = priority;
this.addon = addon;
this.required = required;
}
/**
- * Sets the priority level for the addon in the load order.
+ * Gets the addon name associated with this mapping.
*
- * @param priority The new priority level to be set.
- * @return The modified BootMapping instance with the updated priority.
+ * @return The addon name.
*/
- public BootMapping priority(int priority) {
- this.priority = priority;
- return this;
+ public String getName() {
+ return name;
}
/**
@@ -211,56 +280,46 @@ public BootMapping priority(int priority) {
* @param addon The addon to be associated with this mapping.
* @return The modified BootMapping instance with the updated addon.
*/
- public BootMapping addon(Addon addon) {
+ public BootMapping setAddon(Addon addon) {
this.addon = addon;
return this;
}
/**
- * Marks this {@link BootMapping} as required to properly start.
+ * Retrieves the addon associated with this mapping.
*
- * @since 3.3.4-SNAPSHOT
+ * @return The addon associated with this mapping.
*/
- public void require() {
- this.required = true;
+ public Addon getAddon() {
+ return addon;
}
/**
- * Retrieves the priority level assigned to the addon in the load order.
+ * Merges the required state into this mapping.
*
- * @return The priority level of the addon in the load order.
+ * @param required The required state to apply if this mapping is not already required.
*/
- public int priority() {
- return priority;
- }
+ public void mergeRequired(boolean required) {
+ if (this.required) {
+ return;
+ }
- /**
- * Retrieves the addon associated with this mapping.
- *
- * @return The addon associated with this mapping.
- */
- public Addon addon() {
- return addon;
+ this.required = required;
}
/**
- * Filter for the presence check of this {@link BootMapping}.
+ * Ensures required addons are present.
*
- * @return {@code true} if the {@link BootMapping} is properly present.
- * @throws IllegalStateException If the addon is required but not present.
- * @since 3.3.4-SNAPSHOT
+ * @return true if valid
*/
public boolean presenceFilter() {
- if (!required) {
+ if (!required || addon != null) {
return true;
}
- if (addon != null) {
- return true;
- }
-
- throw new IllegalStateException("The addon \"" + this.name + "\" is required but not found!");
+ throw new IllegalStateException(
+ "The addon " + this.name + " is required but not found!"
+ );
}
-
}
-}
+}
\ No newline at end of file
From 0152e59ff78fc720f144ea768675fa5012c8eba7 Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Sun, 29 Mar 2026 19:28:55 +0200
Subject: [PATCH 04/23] chore: Allow more chars and limit names to 128 chars
(#34)
---
.../craftsnet/addon/loaders/AddonLoader.java | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoader.java b/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoader.java
index 7ca757e0..6912cd9f 100644
--- a/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoader.java
+++ b/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoader.java
@@ -45,6 +45,8 @@
*/
public final class AddonLoader {
+ public static final Pattern PLUGIN_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9\\-_.]{1,128}$");
+
private final Stack addons = new Stack<>();
private final CraftsNet craftsNet;
private final Logger logger;
@@ -388,9 +390,10 @@ private Addon instantiateAddon(AddonConfiguration configuration) {
AddonMeta meta = configuration.meta().get();
String name = meta.name();
- Pattern pattern = Pattern.compile("^[a-zA-Z0-9]*$");
- if (!pattern.matcher(name).matches()) {
- throw new IllegalArgumentException("Plugin names must not contain special characters / spaces! Plugin name: \"" + name + "\"");
+ if (!PLUGIN_NAME_PATTERN.matcher(name).matches()) {
+ throw new IllegalArgumentException("Invalid plugin name: " + name.substring(0, 128) + ". " +
+ "Only letters, numbers, hyphens, underscores and dots are allowed, " +
+ "up to 128 characters.");
}
logger.info("Found addon %s, add it to load order", name);
@@ -407,7 +410,6 @@ private Addon instantiateAddon(AddonConfiguration configuration) {
") is not an instance of " + Addon.class.getSimpleName() + "!");
}
- // Create an instance of the main class and inject dependencies using reflection
Class extends Addon> addonClass = clazz.asSubclass(Addon.class);
Addon addon = ReflectionUtils.getNewInstance(addonClass);
ReflectionUtils.setField("craftsNet", addon, craftsNet);
From d5a68077f657996457d2531cac9d33d0fa5168ee Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Mon, 6 Apr 2026 11:13:33 +0200
Subject: [PATCH 05/23] fix: No longer clear short ttl lists (#35)
---
.../craftsnet/addon/loaders/AddonLoader.java | 64 ++++++++-----------
1 file changed, 26 insertions(+), 38 deletions(-)
diff --git a/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoader.java b/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoader.java
index 6912cd9f..a866d128 100644
--- a/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoader.java
+++ b/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoader.java
@@ -202,49 +202,40 @@ public void load(List rawConfigurations) {
configurations = new ArrayList<>(rawConfigurations);
}
- AddonLoadOrder loadOrder = new AddonLoadOrder();
- HashMap>> codesSources = new HashMap<>();
- configurations.forEach(configuration -> {
- configuration.meta().set(AddonMeta.of(configuration));
+ try (AddonLoadOrder loadOrder = new AddonLoadOrder()) {
+ configurations.forEach(configuration -> {
+ configuration.meta().set(AddonMeta.of(configuration));
- configuration.classLoader().set(new AddonClassLoader(this.craftsNet, configuration));
- preBuildLoadOrder(loadOrder, configuration);
- });
-
- sortConfigurations(loadOrder, configurations);
-
- // Initialize tasks
- configurations.forEach(configuration -> {
- Addon addon = instantiateAddon(configuration);
- if (addon == null) {
- return;
- }
+ configuration.classLoader().set(new AddonClassLoader(this.craftsNet, configuration));
+ preBuildLoadOrder(loadOrder, configuration);
+ });
- craftsNet.getAddonManager().register(addon);
- configuration.addon().set(addon);
+ sortConfigurations(loadOrder, configurations);
- addToLoadOrder(loadOrder, addon);
- addCodeSource(configuration, addon, codesSources);
- });
+ HashMap>> codesSources = new HashMap<>();
+ configurations.forEach(configuration -> {
+ Addon addon = instantiateAddon(configuration);
+ if (addon == null) {
+ return;
+ }
- configurations.forEach(this::loadServices);
+ craftsNet.getAddonManager().register(addon);
+ configuration.addon().set(addon);
- HashMap> autoRegisterInfos;
- try (AutoRegisterLoader autoRegisterLoader = new AutoRegisterLoader()) {
- autoRegisterInfos = convertToAutoRegister(autoRegisterLoader, codesSources);
- }
+ addToLoadOrder(loadOrder, addon);
+ addCodeSource(configuration, addon, codesSources);
+ });
- Collection orderedLoad = enableAddons(loadOrder, autoRegisterInfos);
+ configurations.forEach(this::loadServices);
- autoRegisterInfos.clear();
- orderedLoad.clear();
- loadOrder.close();
+ HashMap> autoRegisterInfos;
+ try (AutoRegisterLoader autoRegisterLoader = new AutoRegisterLoader()) {
+ autoRegisterInfos = convertToAutoRegister(autoRegisterLoader, codesSources);
+ }
- try {
+ enableAddons(loadOrder, autoRegisterInfos);
craftsNet.getListenerRegistry().call(new AllAddonsLoadedEvent());
- } catch (Exception e) {
- logger.error("Can not fire addons loaded event!", e);
}
}
@@ -253,10 +244,9 @@ public void load(List rawConfigurations) {
*
* @param loadOrder The {@link AddonLoadOrder load order} in which the addons will be loaded.
* @param autoRegisterInfos A list of {@link AutoRegisterInfo} which should be applied for the addons.
- * @return The list of all loaded addons.
* @since 3.5.0
*/
- private @NotNull Collection enableAddons(AddonLoadOrder loadOrder, HashMap> autoRegisterInfos) {
+ private void enableAddons(AddonLoadOrder loadOrder, HashMap> autoRegisterInfos) {
Collection orderedLoad = loadOrder.getLoadOrder();
// Loading all addons
@@ -282,8 +272,6 @@ public void load(List rawConfigurations) {
craftsNet.getAutoRegisterRegistry().handleAll(autoRegisterInfos.get(addon), Startup.ENABLE);
});
-
- return orderedLoad;
}
/**
@@ -294,7 +282,7 @@ public void load(List rawConfigurations) {
* @since 3.4.3
*/
private void sortConfigurations(AddonLoadOrder loadOrder, List configurations) {
- var orderedConfigurationNames = loadOrder.getPreLoadOrder();
+ List orderedConfigurationNames = loadOrder.getPreLoadOrder();
Map sortMap = new HashMap<>();
for (int i = 0; i < orderedConfigurationNames.size(); i++) {
sortMap.put(orderedConfigurationNames.get(i), i);
From 7a47d6827fcf9a98682ee81622ecb28ab7623cba Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Mon, 6 Apr 2026 14:30:06 +0200
Subject: [PATCH 06/23] chore: Load the artifact loader only if needed (#36)
---
.../addon/artifacts/ArtifactLoader.java | 25 +++++---
.../craftsnet/addon/loaders/AddonLoader.java | 23 ++++---
.../addon/meta/AddonConfiguration.java | 63 +++++++++++++------
3 files changed, 78 insertions(+), 33 deletions(-)
diff --git a/src/main/java/de/craftsblock/craftsnet/addon/artifacts/ArtifactLoader.java b/src/main/java/de/craftsblock/craftsnet/addon/artifacts/ArtifactLoader.java
index 125a395d..9b3312b9 100644
--- a/src/main/java/de/craftsblock/craftsnet/addon/artifacts/ArtifactLoader.java
+++ b/src/main/java/de/craftsblock/craftsnet/addon/artifacts/ArtifactLoader.java
@@ -19,7 +19,6 @@
import org.eclipse.aether.resolution.DependencyResult;
import org.eclipse.aether.supplier.RepositorySystemSupplier;
import org.eclipse.aether.util.artifact.DefaultArtifactTypeRegistry;
-import org.eclipse.aether.util.filter.OrDependencyFilter;
import org.eclipse.aether.util.graph.manager.ClassicDependencyManager;
import org.eclipse.aether.util.graph.selector.AndDependencySelector;
import org.eclipse.aether.util.graph.selector.ExclusionDependencySelector;
@@ -45,16 +44,20 @@
*/
public final class ArtifactLoader {
- private final RepositorySystem repository;
- private final RepositorySystemSession.CloseableSession session;
- private final List repositories;
- private final List defaultRepos;
+ private RepositorySystem repository;
+ private RepositorySystemSession.CloseableSession session;
+ private List repositories;
+ private List defaultRepos;
/**
- * Creates a new instance of the artifact loader
+ * Sets up the artifact loading.
*/
@SuppressWarnings("deprecation")
- public ArtifactLoader() {
+ public void setup() {
+ if (repository != null) {
+ return;
+ }
+
RepositorySystemSupplier repositorySupplier = new RepositorySystemSupplier();
repository = repositorySupplier.get();
@@ -90,6 +93,10 @@ public ArtifactLoader() {
* Cleanup internal repository cache
*/
public void cleanup() {
+ if (repositories == null) {
+ return;
+ }
+
repositories.removeIf(remoteRepository -> !defaultRepos.contains(remoteRepository));
}
@@ -97,6 +104,10 @@ public void cleanup() {
* Cleanup and shutdown of the internal repository resolver
*/
public void stop() {
+ if (repository == null) {
+ return;
+ }
+
cleanup();
session.close();
repository.shutdown();
diff --git a/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoader.java b/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoader.java
index a866d128..5e482487 100644
--- a/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoader.java
+++ b/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoader.java
@@ -159,22 +159,29 @@ public Collection load() throws IOException {
}
artifactLoader.cleanup();
- if (addon.contains("repositories")) {
- for (String repo : addon.getStringList("repositories")) {
- artifactLoader.addRepository(repo);
- }
+
+ var mavenRepositories = addon.getStringList("repositories");
+ if (!mavenRepositories.isEmpty()) {
+ artifactLoader.setup();
+ mavenRepositories.forEach(artifactLoader::addRepository);
}
URL[] dependencies;
- if (addon.contains("dependencies")) {
- dependencies = artifactLoader.loadLibraries(this.craftsNet, this, configuration.services(),
- name, addon.getStringList("dependencies").toArray(String[]::new));
+ var mavenDependencies = addon.getStringList("dependencies");
+ if (!mavenDependencies.isEmpty()) {
+ artifactLoader.setup();
+ dependencies = artifactLoader.loadLibraries(
+ this.craftsNet, this,
+ configuration.services(),
+ name, mavenDependencies.toArray(String[]::new)
+ );
} else {
dependencies = new URL[0];
}
DependencyClassLoader[] dependencyClassLoaders = Arrays.stream(dependencies)
- .map(url -> DependencyClassLoader.safelyNew(craftsNet, url)).toArray(DependencyClassLoader[]::new);
+ .map(url -> DependencyClassLoader.safelyNew(craftsNet, url))
+ .toArray(DependencyClassLoader[]::new);
URL[] classpath = new URL[]{path.toUri().toURL()};
configurations.put(name, new AddonConfiguration(path, configuration.json(), classpath, dependencyClassLoaders,
diff --git a/src/main/java/de/craftsblock/craftsnet/addon/meta/AddonConfiguration.java b/src/main/java/de/craftsblock/craftsnet/addon/meta/AddonConfiguration.java
index 8e55b100..d470b712 100644
--- a/src/main/java/de/craftsblock/craftsnet/addon/meta/AddonConfiguration.java
+++ b/src/main/java/de/craftsblock/craftsnet/addon/meta/AddonConfiguration.java
@@ -75,8 +75,9 @@ public static AddonConfiguration of(Path path, Json json, URL[] classpath, Depen
*/
public static List of(CraftsNet craftsNet, AddonLoader loader, Class extends Addon> addon) {
Meta meta = addon.getDeclaredAnnotation(Meta.class);
- if (meta == null && !MAPPED_NAMES.containsKey(addon))
+ if (meta == null && !MAPPED_NAMES.containsKey(addon)) {
throw new IllegalStateException("The addon class " + addon.getName() + " is not annotated with @" + Meta.class.getSimpleName() + "!");
+ }
String name = MAPPED_NAMES.getOrDefault(addon, meta != null ? meta.name() : null);
Depends depends = addon.getDeclaredAnnotation(Depends.class);
@@ -89,16 +90,21 @@ public static List of(CraftsNet craftsNet, AddonLoader loade
.set("main", addon.getName());
Set classes = new HashSet<>();
- if (depends != null) classes.add(depends);
- else {
+ if (depends != null) {
+ classes.add(depends);
+ } else {
DependsCollection collection = addon.getDeclaredAnnotation(DependsCollection.class);
- if (collection != null) classes.addAll(List.of(collection.value()));
+ if (collection != null) {
+ classes.addAll(List.of(collection.value()));
+ }
}
List configurations = new ArrayList<>();
for (Depends depend : classes) {
List subs = of(craftsNet, loader, depend.value());
- if (subs.isEmpty()) continue;
+ if (subs.isEmpty()) {
+ continue;
+ }
configurations.addAll(subs);
AddonConfiguration subConfig = subs.get(subs.size() - 1);
@@ -111,29 +117,47 @@ public static List of(CraftsNet craftsNet, AddonLoader loade
Shadow shadow = addon.getDeclaredAnnotation(Shadow.class);
EnumMap> shadows = new EnumMap<>(ShadowType.class);
- if (shadow != null) shadows.computeIfAbsent(shadow.type(), s -> new ArrayList<>()).add(shadow.value());
- else {
+ if (shadow != null) {
+ shadows.computeIfAbsent(shadow.type(), s -> new ArrayList<>()).add(shadow.value());
+ } else {
ShadowCollection collection = addon.getDeclaredAnnotation(ShadowCollection.class);
- if (collection != null)
- for (Shadow nested : collection.value())
+ if (collection != null) {
+ for (Shadow nested : collection.value()) {
shadows.computeIfAbsent(nested.type(), s -> new ArrayList<>()).add(nested.value());
+ }
+ }
}
- // Inject all repositories
- if (shadows.containsKey(ShadowType.REPOSITORY))
- for (String repo : shadows.get(ShadowType.REPOSITORY))
+ var mavenRepos = shadows.get(ShadowType.REPOSITORY);
+ if (mavenRepos != null && !mavenRepos.isEmpty()) {
+ artifactLoader.setup();
+ for (String repo : mavenRepos) {
artifactLoader.addRepository(repo);
+ }
+ }
// Load all required dependencies
URL[] dependencies;
- if (shadows.containsKey(ShadowType.DEPENDENCY))
- dependencies = artifactLoader.loadLibraries(craftsNet, loader, services, name, shadows.get(ShadowType.DEPENDENCY).toArray(String[]::new));
- else dependencies = new URL[0];
+ var mavenDependencies = shadows.get(ShadowType.DEPENDENCY);
+ if (mavenDependencies != null && !mavenDependencies.isEmpty()) {
+ artifactLoader.setup();
+ dependencies = artifactLoader.loadLibraries(
+ craftsNet, loader,
+ services, name,
+ shadows.get(ShadowType.DEPENDENCY).toArray(String[]::new)
+ );
+ } else {
+ dependencies = new URL[0];
+ }
- classpath.addAll(Arrays.stream(dependencies).collect(Collectors.toSet()));
artifactLoader.stop();
- configurations.add(of(null, conf, classpath.toArray(URL[]::new), new DependencyClassLoader[0], services));
+ DependencyClassLoader[] dependencyClassLoaders = Arrays.stream(dependencies)
+ .map(url -> DependencyClassLoader.safelyNew(craftsNet, url))
+ .toArray(DependencyClassLoader[]::new);
+ classpath.addAll(Arrays.stream(dependencies).collect(Collectors.toSet()));
+
+ configurations.add(of(null, conf, classpath.toArray(URL[]::new), dependencyClassLoaders, services));
return configurations;
}
@@ -164,7 +188,10 @@ public int compareTo(@NotNull AddonConfiguration o) {
*/
private static String sanitizeName(String name) {
if (NAME_VALIDATOR.matcher(name).matches()) return name;
- throw new IllegalArgumentException("Addon names must not contain special characters / spaces! Provided: \"" + name + "\"");
+
+ throw new IllegalArgumentException("Invalid addon name: " + name.substring(0, 128) + ". " +
+ "Only letters, numbers, hyphens, underscores and dots are allowed, " +
+ "up to 128 characters.");
}
/**
From 6278f76470dd82a5668c79edb3115c859b4d27f2 Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Mon, 6 Apr 2026 14:46:14 +0200
Subject: [PATCH 07/23] chore: Allow more characters for addon names (#37)
---
.../craftsnet/addon/loaders/AddonLoader.java | 14 ++---------
.../addon/meta/AddonConfiguration.java | 24 ++++++++++---------
.../addon/meta/annotations/Meta.java | 4 +++-
3 files changed, 18 insertions(+), 24 deletions(-)
diff --git a/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoader.java b/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoader.java
index 5e482487..22d52193 100644
--- a/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoader.java
+++ b/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonLoader.java
@@ -17,7 +17,6 @@
import de.craftsblock.craftsnet.events.addons.AllAddonsLoadedEvent;
import de.craftsblock.craftsnet.logging.Logger;
import de.craftsblock.craftsnet.utils.reflection.ReflectionUtils;
-import org.jetbrains.annotations.NotNull;
import java.io.*;
import java.net.URI;
@@ -30,7 +29,6 @@
import java.util.function.BiConsumer;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
-import java.util.regex.Pattern;
import java.util.zip.ZipFile;
/**
@@ -45,8 +43,6 @@
*/
public final class AddonLoader {
- public static final Pattern PLUGIN_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9\\-_.]{1,128}$");
-
private final Stack addons = new Stack<>();
private final CraftsNet craftsNet;
private final Logger logger;
@@ -309,7 +305,7 @@ private void preBuildLoadOrder(AddonLoadOrder loadOrder, AddonConfiguration conf
AddonMeta meta = configuration.meta().get();
String name = meta.name();
if (loadOrder.contains(name)) {
- throw new IllegalStateException("There are two plugins with the same name: \"%s\"!".formatted(name));
+ throw new IllegalStateException("There are two addons with the same name: \"%s\"!".formatted(name));
}
processDepends(name, meta.depends(), loadOrder::depends);
@@ -383,13 +379,7 @@ private void addCodeSource(AddonConfiguration configuration, Addon addon,
private Addon instantiateAddon(AddonConfiguration configuration) {
try {
AddonMeta meta = configuration.meta().get();
-
- String name = meta.name();
- if (!PLUGIN_NAME_PATTERN.matcher(name).matches()) {
- throw new IllegalArgumentException("Invalid plugin name: " + name.substring(0, 128) + ". " +
- "Only letters, numbers, hyphens, underscores and dots are allowed, " +
- "up to 128 characters.");
- }
+ String name = AddonConfiguration.ensureValidAddonName(meta.name());
logger.info("Found addon %s, add it to load order", name);
diff --git a/src/main/java/de/craftsblock/craftsnet/addon/meta/AddonConfiguration.java b/src/main/java/de/craftsblock/craftsnet/addon/meta/AddonConfiguration.java
index d470b712..a9b61d26 100644
--- a/src/main/java/de/craftsblock/craftsnet/addon/meta/AddonConfiguration.java
+++ b/src/main/java/de/craftsblock/craftsnet/addon/meta/AddonConfiguration.java
@@ -43,6 +43,11 @@ public record AddonConfiguration(Path path, Json json, URL[] classpath, Dependen
AtomicReference meta, AtomicReference classLoader)
implements Comparable {
+ /**
+ * Pattern for validating addon names.
+ */
+ public static final Pattern ADDON_NAME_VALIDATOR = Pattern.compile("^[a-zA-Z0-9\\-_.]{1,128}$");
+
@ApiStatus.Internal
private static final ConcurrentHashMap, String> MAPPED_NAMES = new ConcurrentHashMap<>();
@@ -86,7 +91,7 @@ public static List of(CraftsNet craftsNet, AddonLoader loade
List classpath = new ArrayList<>();
classpath.add(addon.getProtectionDomain().getCodeSource().getLocation());
- Json conf = Json.empty().set("name", sanitizeName(name))
+ Json conf = Json.empty().set("name", ensureValidAddonName(name))
.set("main", addon.getName());
Set classes = new HashSet<>();
@@ -174,20 +179,16 @@ public int compareTo(@NotNull AddonConfiguration o) {
}
/**
- * Pattern for validating addon names.
- * Addon names can only contain alphanumeric characters.
- */
- public static final Pattern NAME_VALIDATOR = Pattern.compile("^[a-zA-Z0-9]*$");
-
- /**
- * Sanitizes the name of the addon through checking the name against the {@link AddonConfiguration#NAME_VALIDATOR}.
+ * Sanitizes the name of the addon through checking the name against the {@link AddonConfiguration#ADDON_NAME_VALIDATOR}.
*
* @param name The name of the addon.
* @return The sanitized name of the addon.
- * @throws IllegalArgumentException If the addon name does not match with {@link AddonConfiguration#NAME_VALIDATOR}.
+ * @throws IllegalArgumentException If the addon name does not match with {@link AddonConfiguration#ADDON_NAME_VALIDATOR}.
*/
- private static String sanitizeName(String name) {
- if (NAME_VALIDATOR.matcher(name).matches()) return name;
+ public static String ensureValidAddonName(String name) {
+ if (ADDON_NAME_VALIDATOR.matcher(name).matches()) {
+ return name;
+ }
throw new IllegalArgumentException("Invalid addon name: " + name.substring(0, 128) + ". " +
"Only letters, numbers, hyphens, underscores and dots are allowed, " +
@@ -200,6 +201,7 @@ private static String sanitizeName(String name) {
* @param addon The addon class.
* @param name The name to associate with the addon class.
*/
+ @ApiStatus.Internal
public static void map(Class extends Addon> addon, String name) {
MAPPED_NAMES.put(addon, name);
}
diff --git a/src/main/java/de/craftsblock/craftsnet/addon/meta/annotations/Meta.java b/src/main/java/de/craftsblock/craftsnet/addon/meta/annotations/Meta.java
index ac1fcdb7..56024111 100644
--- a/src/main/java/de/craftsblock/craftsnet/addon/meta/annotations/Meta.java
+++ b/src/main/java/de/craftsblock/craftsnet/addon/meta/annotations/Meta.java
@@ -1,5 +1,7 @@
package de.craftsblock.craftsnet.addon.meta.annotations;
+import org.intellij.lang.annotations.Pattern;
+
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -29,6 +31,6 @@
*
* @return The name of the addon.
*/
- String name();
+ @Pattern("^[a-zA-Z0-9\\-_.]{1,128}$") String name();
}
From 41c2f8df2eafa7d2f0714c97e8eb58cb266a6b74 Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Mon, 6 Apr 2026 14:46:28 +0200
Subject: [PATCH 08/23] chore: Add the print format annotation (#38)
---
.../craftsblock/craftsnet/logging/Logger.java | 18 ++++++++++--------
.../craftsnet/logging/impl/LoggerImpl.java | 2 +-
.../craftsnet/logging/impl/NoOpLogger.java | 2 +-
.../craftsnet/logging/impl/PlainLogger.java | 2 +-
4 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/src/main/java/de/craftsblock/craftsnet/logging/Logger.java b/src/main/java/de/craftsblock/craftsnet/logging/Logger.java
index e8ca9406..12af8b68 100644
--- a/src/main/java/de/craftsblock/craftsnet/logging/Logger.java
+++ b/src/main/java/de/craftsblock/craftsnet/logging/Logger.java
@@ -1,5 +1,6 @@
package de.craftsblock.craftsnet.logging;
+import org.intellij.lang.annotations.PrintFormat;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -32,7 +33,7 @@ public interface Logger {
* @param args Arguments referenced by the format specifiers in the format string.
* @since 3.5.2
*/
- default void info(@NotNull String format, Object... args) {
+ default void info(@NotNull @PrintFormat String format, Object @Nullable ... args) {
info(format(format, args));
}
@@ -53,7 +54,7 @@ default void info(@NotNull String format, Object... args) {
* @param args Arguments referenced by the format specifiers in the format string.
* @since 3.5.2
*/
- default void warning(@NotNull String format, Object... args) {
+ default void warning(@NotNull @PrintFormat String format, Object @Nullable ... args) {
warning(format(format, args));
}
@@ -74,7 +75,7 @@ default void warning(@NotNull String format, Object... args) {
* @param args Arguments referenced by the format specifiers in the format string.
* @since 3.5.2
*/
- default void error(@NotNull String format, Object... args) {
+ default void error(@NotNull @PrintFormat String format, Object @Nullable ... args) {
error(format(format, args));
}
@@ -121,7 +122,8 @@ default void error(@NotNull Throwable throwable, @Nullable String comment) {
* @param args Arguments referenced by the format specifiers in the format string.
* @since 3.5.2
*/
- default void error(@NotNull String format, @NotNull Throwable throwable, Object... args) {
+ default void error(@NotNull @PrintFormat String format, @NotNull Throwable throwable,
+ Object @Nullable ... args) {
error(format(format, args), throwable);
}
@@ -142,7 +144,7 @@ default void error(@NotNull String format, @NotNull Throwable throwable, Object.
* @param args Arguments referenced by the format specifiers in the format string.
* @since 3.5.2
*/
- default void debug(@NotNull String format, Object... args) {
+ default void debug(@NotNull @PrintFormat String format, Object @Nullable ... args) {
debug(format(format, args));
}
@@ -152,7 +154,7 @@ default void debug(@NotNull String format, Object... args) {
* @param name The name for the cloned logger.
* @return A new {@code Logger} instance cloned from this logger with the given name.
*/
- Logger cloneWithName(String name);
+ Logger cloneWithName(@Nullable String name);
/**
* Creates a clone of this {@link Logger} with a formatted name.
@@ -166,7 +168,7 @@ default void debug(@NotNull String format, Object... args) {
* @return A new {@code Logger} instance cloned from this logger with the formatted name.
* @since 3.5.2
*/
- default Logger cloneWithName(String format, Object... args) {
+ default Logger cloneWithName(@NotNull @PrintFormat String format, Object @Nullable ... args) {
return cloneWithName(format(format, args));
}
@@ -180,7 +182,7 @@ default Logger cloneWithName(String format, Object... args) {
* @return A formatted string.
* @since 3.5.2
*/
- default String format(@NotNull String format, Object... args) {
+ default String format(@NotNull @PrintFormat String format, Object @Nullable ... args) {
return String.format(format, args);
}
diff --git a/src/main/java/de/craftsblock/craftsnet/logging/impl/LoggerImpl.java b/src/main/java/de/craftsblock/craftsnet/logging/impl/LoggerImpl.java
index 277671b1..c4bbdd2c 100644
--- a/src/main/java/de/craftsblock/craftsnet/logging/impl/LoggerImpl.java
+++ b/src/main/java/de/craftsblock/craftsnet/logging/impl/LoggerImpl.java
@@ -121,7 +121,7 @@ public void debug(@Nullable String text) {
* @return {@inheritDoc}
*/
@Override
- public Logger cloneWithName(String name) {
+ public Logger cloneWithName(@Nullable String name) {
return new LoggerImpl(this.debug, name);
}
diff --git a/src/main/java/de/craftsblock/craftsnet/logging/impl/NoOpLogger.java b/src/main/java/de/craftsblock/craftsnet/logging/impl/NoOpLogger.java
index 62777495..fbd90dc8 100644
--- a/src/main/java/de/craftsblock/craftsnet/logging/impl/NoOpLogger.java
+++ b/src/main/java/de/craftsblock/craftsnet/logging/impl/NoOpLogger.java
@@ -91,7 +91,7 @@ public void debug(@Nullable String text) {
* @return {@inheritDoc}
*/
@Override
- public Logger cloneWithName(String name) {
+ public Logger cloneWithName(@Nullable String name) {
return this;
}
diff --git a/src/main/java/de/craftsblock/craftsnet/logging/impl/PlainLogger.java b/src/main/java/de/craftsblock/craftsnet/logging/impl/PlainLogger.java
index 6ab4b71a..cabbb5fc 100644
--- a/src/main/java/de/craftsblock/craftsnet/logging/impl/PlainLogger.java
+++ b/src/main/java/de/craftsblock/craftsnet/logging/impl/PlainLogger.java
@@ -103,7 +103,7 @@ public void debug(@Nullable String text) {
* @return {@inheritDoc}
*/
@Override
- public Logger cloneWithName(String name) {
+ public Logger cloneWithName(@Nullable String name) {
return this;
}
From 2901430e6a06782eafb8cf9d879cfced917555ed Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Mon, 6 Apr 2026 14:50:23 +0200
Subject: [PATCH 09/23] chore: Add .jfr files to gitignore
---
.gitignore | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index 59518501..7c979a7f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -54,5 +54,8 @@ test/
### Mac OS ###
.DS_Store
+### JFR ###
+*.jfr
+
.env
-.env.repo
\ No newline at end of file
+.env.repo
From a4363c3111466165c31a780b94626e0d939be42c Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Mon, 6 Apr 2026 14:57:07 +0200
Subject: [PATCH 10/23] chore: Bump version of gradle to 9.4.1
---
gradle/wrapper/gradle-wrapper.properties | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index bad7c246..c61a118f 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
From 308b2b598f7b47ad5a7462c5cf7c3c91dda48953 Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Mon, 6 Apr 2026 21:22:51 +0200
Subject: [PATCH 11/23] Revert "chore: Add the print format annotation (#38)"
This reverts commit 41c2f8df2eafa7d2f0714c97e8eb58cb266a6b74.
---
.../craftsblock/craftsnet/logging/Logger.java | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/src/main/java/de/craftsblock/craftsnet/logging/Logger.java b/src/main/java/de/craftsblock/craftsnet/logging/Logger.java
index 12af8b68..e8ca9406 100644
--- a/src/main/java/de/craftsblock/craftsnet/logging/Logger.java
+++ b/src/main/java/de/craftsblock/craftsnet/logging/Logger.java
@@ -1,6 +1,5 @@
package de.craftsblock.craftsnet.logging;
-import org.intellij.lang.annotations.PrintFormat;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -33,7 +32,7 @@ public interface Logger {
* @param args Arguments referenced by the format specifiers in the format string.
* @since 3.5.2
*/
- default void info(@NotNull @PrintFormat String format, Object @Nullable ... args) {
+ default void info(@NotNull String format, Object... args) {
info(format(format, args));
}
@@ -54,7 +53,7 @@ default void info(@NotNull @PrintFormat String format, Object @Nullable ... args
* @param args Arguments referenced by the format specifiers in the format string.
* @since 3.5.2
*/
- default void warning(@NotNull @PrintFormat String format, Object @Nullable ... args) {
+ default void warning(@NotNull String format, Object... args) {
warning(format(format, args));
}
@@ -75,7 +74,7 @@ default void warning(@NotNull @PrintFormat String format, Object @Nullable ... a
* @param args Arguments referenced by the format specifiers in the format string.
* @since 3.5.2
*/
- default void error(@NotNull @PrintFormat String format, Object @Nullable ... args) {
+ default void error(@NotNull String format, Object... args) {
error(format(format, args));
}
@@ -122,8 +121,7 @@ default void error(@NotNull Throwable throwable, @Nullable String comment) {
* @param args Arguments referenced by the format specifiers in the format string.
* @since 3.5.2
*/
- default void error(@NotNull @PrintFormat String format, @NotNull Throwable throwable,
- Object @Nullable ... args) {
+ default void error(@NotNull String format, @NotNull Throwable throwable, Object... args) {
error(format(format, args), throwable);
}
@@ -144,7 +142,7 @@ default void error(@NotNull @PrintFormat String format, @NotNull Throwable throw
* @param args Arguments referenced by the format specifiers in the format string.
* @since 3.5.2
*/
- default void debug(@NotNull @PrintFormat String format, Object @Nullable ... args) {
+ default void debug(@NotNull String format, Object... args) {
debug(format(format, args));
}
@@ -154,7 +152,7 @@ default void debug(@NotNull @PrintFormat String format, Object @Nullable ... arg
* @param name The name for the cloned logger.
* @return A new {@code Logger} instance cloned from this logger with the given name.
*/
- Logger cloneWithName(@Nullable String name);
+ Logger cloneWithName(String name);
/**
* Creates a clone of this {@link Logger} with a formatted name.
@@ -168,7 +166,7 @@ default void debug(@NotNull @PrintFormat String format, Object @Nullable ... arg
* @return A new {@code Logger} instance cloned from this logger with the formatted name.
* @since 3.5.2
*/
- default Logger cloneWithName(@NotNull @PrintFormat String format, Object @Nullable ... args) {
+ default Logger cloneWithName(String format, Object... args) {
return cloneWithName(format(format, args));
}
@@ -182,7 +180,7 @@ default Logger cloneWithName(@NotNull @PrintFormat String format, Object @Nullab
* @return A formatted string.
* @since 3.5.2
*/
- default String format(@NotNull @PrintFormat String format, Object @Nullable ... args) {
+ default String format(@NotNull String format, Object... args) {
return String.format(format, args);
}
From 5064af57c42086782be3fe23cddbc8983f033694 Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Mon, 6 Apr 2026 21:27:26 +0200
Subject: [PATCH 12/23] chore: Merge in app and file addon loading process
(#39)
---
.../addon/loaders/AddonClassLoader.java | 6 +++++-
.../addon/meta/AddonConfiguration.java | 18 ++++++++----------
2 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonClassLoader.java b/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonClassLoader.java
index 29b6524c..4b839997 100644
--- a/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonClassLoader.java
+++ b/src/main/java/de/craftsblock/craftsnet/addon/loaders/AddonClassLoader.java
@@ -5,6 +5,8 @@
import de.craftsblock.craftsnet.addon.Addon;
import de.craftsblock.craftsnet.addon.meta.AddonConfiguration;
import de.craftsblock.craftsnet.logging.Logger;
+import de.craftsblock.craftsnet.utils.reflection.ReflectionUtils;
+import org.jetbrains.annotations.ApiStatus;
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;
@@ -39,8 +41,10 @@ public final class AddonClassLoader extends CraftsNetUrlClassLoader of(CraftsNet craftsNet, AddonLoader loade
Depends depends = addon.getDeclaredAnnotation(Depends.class);
List services = new ArrayList<>();
- List classpath = new ArrayList<>();
- classpath.add(addon.getProtectionDomain().getCodeSource().getLocation());
-
- Json conf = Json.empty().set("name", ensureValidAddonName(name))
+ Json conf = Json.empty().set("name", name)
.set("main", addon.getName());
Set classes = new HashSet<>();
@@ -104,7 +100,7 @@ public static List of(CraftsNet craftsNet, AddonLoader loade
}
}
- List configurations = new ArrayList<>();
+ Set configurations = new HashSet<>();
for (Depends depend : classes) {
List subs = of(craftsNet, loader, depend.value());
if (subs.isEmpty()) {
@@ -114,7 +110,7 @@ public static List of(CraftsNet craftsNet, AddonLoader loade
AddonConfiguration subConfig = subs.get(subs.size() - 1);
conf.set((depend.soft() ? "softD" : "d") + "epends.$new", subConfig.json().get("name"));
- classpath.addAll(Arrays.stream(subConfig.classpath()).collect(Collectors.toSet()));
+ configurations.addAll(subs);
}
// Create a new artifact loader
@@ -160,10 +156,12 @@ public static List of(CraftsNet craftsNet, AddonLoader loade
DependencyClassLoader[] dependencyClassLoaders = Arrays.stream(dependencies)
.map(url -> DependencyClassLoader.safelyNew(craftsNet, url))
.toArray(DependencyClassLoader[]::new);
- classpath.addAll(Arrays.stream(dependencies).collect(Collectors.toSet()));
+ URL[] classpath = new URL[]{addon.getProtectionDomain().getCodeSource().getLocation()};
- configurations.add(of(null, conf, classpath.toArray(URL[]::new), dependencyClassLoaders, services));
- return configurations;
+ AddonConfiguration configuration = of(null, conf, classpath, dependencyClassLoaders, services);
+ configuration.classLoader().set(new AddonClassLoader(craftsNet, configuration));
+ configurations.add(configuration);
+ return new ArrayList<>(configurations);
}
/**
From 416e81321a370ee1f656a124034f93ab2be0e031 Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Mon, 6 Apr 2026 21:29:12 +0200
Subject: [PATCH 13/23] fix: Fix ReflectionUtils#restrictToCallers (#40)
---
.../craftsnet/utils/reflection/ReflectionUtils.java | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/main/java/de/craftsblock/craftsnet/utils/reflection/ReflectionUtils.java b/src/main/java/de/craftsblock/craftsnet/utils/reflection/ReflectionUtils.java
index cd4d2ae0..4006ee35 100644
--- a/src/main/java/de/craftsblock/craftsnet/utils/reflection/ReflectionUtils.java
+++ b/src/main/java/de/craftsblock/craftsnet/utils/reflection/ReflectionUtils.java
@@ -75,8 +75,7 @@ public static Class> getCallerClass(@Range(from = 1, to = Integer.MAX_VALUE) i
* @since 3.5.0
*/
public static void restrictToCallers(Class>... allowed) {
- Class> caller = ReflectionUtils.getCallerClass();
- Class> callersCaller = ReflectionUtils.getCallerClass(4);
+ Class> callersCaller = ReflectionUtils.getCallerClass(3);
for (Class> allow : allowed) {
if (allow.isAssignableFrom(callersCaller)) {
@@ -84,7 +83,7 @@ public static void restrictToCallers(Class>... allowed) {
}
}
- throw new IllegalStateException(callersCaller.getName() + " is not permitted to call a " + caller.getSimpleName());
+ throw new IllegalStateException(callersCaller.getName() + " is not permitted to call this");
}
/**
From b9baa2358b6305f1f3c0d3171fcf6d5166198fce Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Mon, 6 Apr 2026 21:32:46 +0200
Subject: [PATCH 14/23] refactor: Use addon class name if no meta annotation is
present (#41)
---
.../addon/meta/AddonConfiguration.java | 17 ++++++++++++++---
.../builder/AddonContainingBuilder.java | 6 ++++++
2 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/src/main/java/de/craftsblock/craftsnet/addon/meta/AddonConfiguration.java b/src/main/java/de/craftsblock/craftsnet/addon/meta/AddonConfiguration.java
index 3d625aec..bb3d9b10 100644
--- a/src/main/java/de/craftsblock/craftsnet/addon/meta/AddonConfiguration.java
+++ b/src/main/java/de/craftsblock/craftsnet/addon/meta/AddonConfiguration.java
@@ -78,12 +78,18 @@ public static AddonConfiguration of(Path path, Json json, URL[] classpath, Depen
* @throws IllegalStateException If the provided addon class is not annotated with {@link Meta}.
*/
public static List of(CraftsNet craftsNet, AddonLoader loader, Class extends Addon> addon) {
+ String name;
Meta meta = addon.getDeclaredAnnotation(Meta.class);
- if (meta == null && !MAPPED_NAMES.containsKey(addon)) {
- throw new IllegalStateException("The addon class " + addon.getName() + " is not annotated with @" + Meta.class.getSimpleName() + "!");
+ if (meta != null) {
+ name = meta.name();
+ } else if (MAPPED_NAMES.containsKey(addon)) {
+ name = MAPPED_NAMES.get(addon);
+ craftsNet.getLogger().warning("Deprecated: " + addon.getName() + " still uses a mapped addon name!");
+ } else {
+ name = addon.getSimpleName();
}
- String name = MAPPED_NAMES.getOrDefault(addon, meta != null ? meta.name() : null);
+ ensureValidAddonName(name);
Depends depends = addon.getDeclaredAnnotation(Depends.class);
List services = new ArrayList<>();
@@ -198,8 +204,13 @@ public static String ensureValidAddonName(String name) {
*
* @param addon The addon class.
* @param name The name to associate with the addon class.
+ * @deprecated Addon classes will use the class name as it's mapped name
+ * if no {@link de.craftsblock.craftsnet.addon.meta.annotations.Meta} annotation is present.
+ * There will be no replacement as custom mapped names are no longer supported.
*/
@ApiStatus.Internal
+ @Deprecated(since = "3.7.2", forRemoval = true)
+ @ApiStatus.ScheduledForRemoval(inVersion = "3.8.0")
public static void map(Class extends Addon> addon, String name) {
MAPPED_NAMES.put(addon, name);
}
diff --git a/src/main/java/de/craftsblock/craftsnet/builder/AddonContainingBuilder.java b/src/main/java/de/craftsblock/craftsnet/builder/AddonContainingBuilder.java
index 71712ca3..b50dfd8a 100644
--- a/src/main/java/de/craftsblock/craftsnet/builder/AddonContainingBuilder.java
+++ b/src/main/java/de/craftsblock/craftsnet/builder/AddonContainingBuilder.java
@@ -44,7 +44,13 @@ public AddonContainingBuilder(Collection> addons) {
* @param type The addon class.
* @param name The name to associate with the addon class.
* @return The {@link AddonContainingBuilder} instance.
+ * @deprecated Addon classes will use the class name as it's mapped name
+ * if no {@link de.craftsblock.craftsnet.addon.meta.annotations.Meta} annotation is present.
+ * There will be no replacement as custom mapped names are no longer supported.
*/
+ @SuppressWarnings("removal")
+ @Deprecated(since = "3.7.2", forRemoval = true)
+ @ApiStatus.ScheduledForRemoval(inVersion = "3.8.0")
public AddonContainingBuilder map(Class extends Addon> type, String name) {
AddonConfiguration.map(type, name);
return this;
From e499f8db2d9e44e35d78e7e60f05125fae2480e9 Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Sun, 12 Apr 2026 12:47:23 +0200
Subject: [PATCH 15/23] chore: Bump version of craftscore to 3.8.14
---
build.gradle | 2 +-
.../events/addons/AllAddonsDisabledEvent.java | 11 +++++++++++
.../craftsnet/events/addons/AllAddonsLoadedEvent.java | 10 ++++++++++
.../craftsnet/events/requests/PostRequestEvent.java | 10 ++++++++++
.../craftsnet/events/requests/PreRequestEvent.java | 10 ++++++++++
.../events/requests/routes/RouteRequestEvent.java | 10 ++++++++++
.../events/requests/shares/ShareFileLoadedEvent.java | 10 ++++++++++
.../events/requests/shares/ShareRequestEvent.java | 10 ++++++++++
.../craftsnet/events/sockets/ClientConnectEvent.java | 10 ++++++++++
.../events/sockets/ClientDisconnectEvent.java | 10 ++++++++++
.../sockets/message/IncomingSocketMessageEvent.java | 10 ++++++++++
.../sockets/message/OutgoingSocketMessageEvent.java | 10 ++++++++++
.../sockets/message/ReceivedPingMessageEvent.java | 10 ++++++++++
.../sockets/message/ReceivedPongMessageEvent.java | 10 ++++++++++
14 files changed, 132 insertions(+), 1 deletion(-)
diff --git a/build.gradle b/build.gradle
index cce8f7e8..e8c5e6d6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -29,7 +29,7 @@ dependencies {
// CraftsBlock related dependencies ---------------------------------------------------------------------------------------
// https://repo.craftsblock.de/#/releases/de/craftsblock/craftscore/bom
- implementation platform("de.craftsblock.craftscore:bom:3.8.13-pre9")
+ implementation platform("de.craftsblock.craftscore:bom:3.8.14")
// https://repo.craftsblock.de/#/releases/de/craftsblock/craftscore/buffer
api "de.craftsblock.craftscore:buffer"
diff --git a/src/main/java/de/craftsblock/craftsnet/events/addons/AllAddonsDisabledEvent.java b/src/main/java/de/craftsblock/craftsnet/events/addons/AllAddonsDisabledEvent.java
index 6d7c870c..957dd8a8 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/addons/AllAddonsDisabledEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/addons/AllAddonsDisabledEvent.java
@@ -11,4 +11,15 @@
* @since 3.4.2-SNAPSHOT
*/
public class AllAddonsDisabledEvent extends Event {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected boolean isAsyncAllowed() {
+ return false;
+ }
+
}
diff --git a/src/main/java/de/craftsblock/craftsnet/events/addons/AllAddonsLoadedEvent.java b/src/main/java/de/craftsblock/craftsnet/events/addons/AllAddonsLoadedEvent.java
index b4f38a3b..5e1bde17 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/addons/AllAddonsLoadedEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/addons/AllAddonsLoadedEvent.java
@@ -15,4 +15,14 @@
*/
public class AllAddonsLoadedEvent extends Event {
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected boolean isAsyncAllowed() {
+ return false;
+ }
+
}
diff --git a/src/main/java/de/craftsblock/craftsnet/events/requests/PostRequestEvent.java b/src/main/java/de/craftsblock/craftsnet/events/requests/PostRequestEvent.java
index 368ea13b..7adc28a8 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/requests/PostRequestEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/requests/PostRequestEvent.java
@@ -32,6 +32,16 @@ public PostRequestEvent(Exchange exchange, boolean found, boolean shared) {
this.shared = shared;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected boolean isAsyncAllowed() {
+ return false;
+ }
+
/**
* {@inheritDoc}
*
diff --git a/src/main/java/de/craftsblock/craftsnet/events/requests/PreRequestEvent.java b/src/main/java/de/craftsblock/craftsnet/events/requests/PreRequestEvent.java
index 7e6b4c66..537f5e3d 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/requests/PreRequestEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/requests/PreRequestEvent.java
@@ -28,6 +28,16 @@ public PreRequestEvent(Exchange exchange) {
this.exchange = exchange;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected boolean isAsyncAllowed() {
+ return false;
+ }
+
/**
* {@inheritDoc}
*
diff --git a/src/main/java/de/craftsblock/craftsnet/events/requests/routes/RouteRequestEvent.java b/src/main/java/de/craftsblock/craftsnet/events/requests/routes/RouteRequestEvent.java
index 2ff2803d..1474de1a 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/requests/routes/RouteRequestEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/requests/routes/RouteRequestEvent.java
@@ -32,6 +32,16 @@ public RouteRequestEvent(Exchange exchange) {
this.exchange = exchange;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected boolean isAsyncAllowed() {
+ return false;
+ }
+
/**
* {@inheritDoc}
*
diff --git a/src/main/java/de/craftsblock/craftsnet/events/requests/shares/ShareFileLoadedEvent.java b/src/main/java/de/craftsblock/craftsnet/events/requests/shares/ShareFileLoadedEvent.java
index 32f093b2..10af2e5d 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/requests/shares/ShareFileLoadedEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/requests/shares/ShareFileLoadedEvent.java
@@ -41,6 +41,16 @@ public ShareFileLoadedEvent(@NotNull Exchange exchange, @NotNull Path path) {
this.path = path;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected boolean isAsyncAllowed() {
+ return false;
+ }
+
/**
* {@inheritDoc}
*
diff --git a/src/main/java/de/craftsblock/craftsnet/events/requests/shares/ShareRequestEvent.java b/src/main/java/de/craftsblock/craftsnet/events/requests/shares/ShareRequestEvent.java
index 4d3500c4..42603f59 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/requests/shares/ShareRequestEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/requests/shares/ShareRequestEvent.java
@@ -44,6 +44,16 @@ public ShareRequestEvent(@NotNull String httpPath, @NotNull String filePath, @No
this.mapping = mapping;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected boolean isAsyncAllowed() {
+ return false;
+ }
+
/**
* {@inheritDoc}
*
diff --git a/src/main/java/de/craftsblock/craftsnet/events/sockets/ClientConnectEvent.java b/src/main/java/de/craftsblock/craftsnet/events/sockets/ClientConnectEvent.java
index 136eb9f6..e3b2f894 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/sockets/ClientConnectEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/sockets/ClientConnectEvent.java
@@ -36,6 +36,16 @@ public ClientConnectEvent(SocketExchange exchange) {
this.mappings = exchange.client().getEndpoint();
}
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected boolean isAsyncAllowed() {
+ return false;
+ }
+
/**
* {@inheritDoc}
*
diff --git a/src/main/java/de/craftsblock/craftsnet/events/sockets/ClientDisconnectEvent.java b/src/main/java/de/craftsblock/craftsnet/events/sockets/ClientDisconnectEvent.java
index b0f41066..06e4744e 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/sockets/ClientDisconnectEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/sockets/ClientDisconnectEvent.java
@@ -47,6 +47,16 @@ public ClientDisconnectEvent(SocketExchange exchange, int closeCode, String clos
this.closeByServer = closeByServer;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected boolean isAsyncAllowed() {
+ return false;
+ }
+
/**
* {@inheritDoc}
*
diff --git a/src/main/java/de/craftsblock/craftsnet/events/sockets/message/IncomingSocketMessageEvent.java b/src/main/java/de/craftsblock/craftsnet/events/sockets/message/IncomingSocketMessageEvent.java
index 567fab1a..035352d1 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/sockets/message/IncomingSocketMessageEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/sockets/message/IncomingSocketMessageEvent.java
@@ -30,6 +30,16 @@ public IncomingSocketMessageEvent(SocketExchange exchange, @NotNull Frame frame)
this.frame = frame;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected boolean isAsyncAllowed() {
+ return false;
+ }
+
/**
* {@inheritDoc}
*
diff --git a/src/main/java/de/craftsblock/craftsnet/events/sockets/message/OutgoingSocketMessageEvent.java b/src/main/java/de/craftsblock/craftsnet/events/sockets/message/OutgoingSocketMessageEvent.java
index efc7228e..7dc119e9 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/sockets/message/OutgoingSocketMessageEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/sockets/message/OutgoingSocketMessageEvent.java
@@ -31,6 +31,16 @@ public OutgoingSocketMessageEvent(@NotNull SocketExchange exchange, @NotNull Fra
this.frame = frame;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected boolean isAsyncAllowed() {
+ return false;
+ }
+
/**
* {@inheritDoc}
*
diff --git a/src/main/java/de/craftsblock/craftsnet/events/sockets/message/ReceivedPingMessageEvent.java b/src/main/java/de/craftsblock/craftsnet/events/sockets/message/ReceivedPingMessageEvent.java
index 6590bef6..95dd86fb 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/sockets/message/ReceivedPingMessageEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/sockets/message/ReceivedPingMessageEvent.java
@@ -32,6 +32,16 @@ public ReceivedPingMessageEvent(SocketExchange exchange, @NotNull Frame frame) {
this.frame = frame;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected boolean isAsyncAllowed() {
+ return false;
+ }
+
/**
* {@inheritDoc}
*
diff --git a/src/main/java/de/craftsblock/craftsnet/events/sockets/message/ReceivedPongMessageEvent.java b/src/main/java/de/craftsblock/craftsnet/events/sockets/message/ReceivedPongMessageEvent.java
index b302e25e..c9afb1bc 100644
--- a/src/main/java/de/craftsblock/craftsnet/events/sockets/message/ReceivedPongMessageEvent.java
+++ b/src/main/java/de/craftsblock/craftsnet/events/sockets/message/ReceivedPongMessageEvent.java
@@ -32,6 +32,16 @@ public ReceivedPongMessageEvent(SocketExchange exchange, @NotNull Frame frame) {
this.frame = frame;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected boolean isAsyncAllowed() {
+ return false;
+ }
+
/**
* {@inheritDoc}
*
From b14d7c323deeb1b9a48dee1bfb534c3738a24720 Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Sun, 12 Apr 2026 13:55:38 +0200
Subject: [PATCH 16/23] refactor: Use CompletableFuture#allOf
---
.../loaders/AutoRegisterLoader.java | 50 +++++++++++--------
1 file changed, 29 insertions(+), 21 deletions(-)
diff --git a/src/main/java/de/craftsblock/craftsnet/autoregister/loaders/AutoRegisterLoader.java b/src/main/java/de/craftsblock/craftsnet/autoregister/loaders/AutoRegisterLoader.java
index 85008cd7..df2ec154 100644
--- a/src/main/java/de/craftsblock/craftsnet/autoregister/loaders/AutoRegisterLoader.java
+++ b/src/main/java/de/craftsblock/craftsnet/autoregister/loaders/AutoRegisterLoader.java
@@ -83,22 +83,21 @@ protected List loadFrom(@Nullable ClassLoader loader, @Nullabl
Set infos = Collections.newSetFromMap(new ConcurrentHashMap<>());
ClassLoader classLoader = (loader != null ? loader : ClassLoader.getSystemClassLoader());
- ConcurrentLinkedQueue> futures = new ConcurrentLinkedQueue<>();
-
- // Process each entry in the JAR file
+ Collection> futures = new ArrayList<>();
StreamSupport.stream(file.stream().spliterator(), true)
.filter(this::isValidClassEntry)
.map(JarEntry::getName)
.map(this::convertToJvmName)
- .map(jvmName -> executor.submit(() -> processEntry(jvmName, bounding, classLoader, type, infos)))
- .forEach(futures::add);
-
- // Wait for all futures to complete
- for (Future> future : futures)
- try {
- future.get();
- } catch (InterruptedException | ExecutionException ignored) {
- }
+ .map(jvmName -> CompletableFuture.runAsync(
+ () -> processEntry(jvmName, bounding, classLoader, type, infos),
+ executor
+ )).forEach(futures::add);
+
+ try {
+ CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new)).get();
+ } catch (InterruptedException | ExecutionException e) {
+ throw new RuntimeException("Failed to await auto registration", e);
+ }
futures.clear();
return infos.stream().distinct().collect(Collectors.toCollection(ArrayList::new));
@@ -111,14 +110,17 @@ protected List loadFrom(@Nullable ClassLoader loader, @Nullabl
* @return True if the entry is a valid class file, false otherwise.
*/
private boolean isValidClassEntry(JarEntry entry) {
- if (entry.isDirectory()) return false;
+ if (entry.isDirectory()) {
+ return false;
+ }
String name = entry.getName();
- // Skip classes that belong to certain packages
- for (String skip : SKIP_PACKAGES)
- if (name.startsWith(skip)) return false;
+ for (String skip : SKIP_PACKAGES) {
+ if (name.startsWith(skip)) {
+ return false;
+ }
+ }
- // Only process .class files and exclude module-info.class
return name.endsWith(".class") && !entry.getName().endsWith("module-info.class");
}
@@ -145,8 +147,11 @@ private void processEntry(@NotNull String jvmName, @Nullable Collection b
@NotNull Class extends Annotation> type, @NotNull Set infos) {
try {
Class> clazz = Class.forName(jvmName, false, classLoader);
- if (clazz.isInterface() || clazz.isEnum() || Modifier.isAbstract(clazz.getModifiers())) return;
- if (!clazz.isAnnotationPresent(type)) return;
+ if (clazz.isInterface() || clazz.isEnum()
+ || Modifier.isAbstract(clazz.getModifiers())
+ || !clazz.isAnnotationPresent(type)) {
+ return;
+ }
Annotation annotation = clazz.getDeclaredAnnotation(type);
List parentTypes = new ArrayList<>();
@@ -169,8 +174,9 @@ private List loadSuperclasses(Class> clazz) {
while (clazz != null && !clazz.equals(Object.class)) {
clazz = clazz.getSuperclass();
- if (clazz != null)
+ if (clazz != null) {
superclasses.add(clazz.getName());
+ }
}
return superclasses;
@@ -195,7 +201,9 @@ private List loadInterfaces(Class> clazz) {
* @param interfaces A set to collect interface names.
*/
private void collectInterfaces(Class> clazz, Set interfaces) {
- if (clazz == null || clazz.equals(Object.class)) return;
+ if (clazz == null || clazz.equals(Object.class)) {
+ return;
+ }
for (Class> iface : clazz.getInterfaces()) {
if (interfaces.add(iface.getName())) {
From 61800574fdee25942efec07745a3172793a7039d Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Sun, 12 Apr 2026 14:00:50 +0200
Subject: [PATCH 17/23] refactor: Replace stream with for loop
---
src/main/java/de/craftsblock/craftsnet/CraftsNet.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/java/de/craftsblock/craftsnet/CraftsNet.java b/src/main/java/de/craftsblock/craftsnet/CraftsNet.java
index 050041fb..d7e73075 100644
--- a/src/main/java/de/craftsblock/craftsnet/CraftsNet.java
+++ b/src/main/java/de/craftsblock/craftsnet/CraftsNet.java
@@ -120,10 +120,10 @@ public void start(CraftsNetBuilder builder) throws IOException {
logStream.start();
if (instance != null) {
- Arrays.stream(new Logger[]{logger, instance.logger}).forEach(log -> {
+ for (Logger log : new Logger[]{logger, instance.logger}) {
log.warning("Detected another instance of CraftsNet in the jvm!");
log.warning("This may cause some errors.");
- });
+ }
}
instance = this;
From c250431d9a7432f82aa616fffcdb6a6058f75587 Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Sun, 12 Apr 2026 17:23:14 +0200
Subject: [PATCH 18/23] fix: Fix code sources for in app addons
---
.../de/craftsblock/craftsnet/CraftsNet.java | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/src/main/java/de/craftsblock/craftsnet/CraftsNet.java b/src/main/java/de/craftsblock/craftsnet/CraftsNet.java
index d7e73075..21a510e8 100644
--- a/src/main/java/de/craftsblock/craftsnet/CraftsNet.java
+++ b/src/main/java/de/craftsblock/craftsnet/CraftsNet.java
@@ -35,7 +35,6 @@
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.security.CodeSource;
-import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.jar.JarFile;
@@ -546,7 +545,7 @@ public static CraftsNetBuilder create() {
*/
@SafeVarargs
public static AddonContainingBuilder create(Class extends Addon>... addons) {
- return CraftsNet.create(List.of(addons));
+ return create(ReflectionUtils.getCallerClass(), List.of(addons));
}
/**
@@ -559,8 +558,21 @@ public static AddonContainingBuilder create(Class extends Addon>... addons) {
* @return A new {@link AddonContainingBuilder} instance initialized with the specified addons.
*/
public static AddonContainingBuilder create(Collection> addons) {
+ return create(ReflectionUtils.getCallerClass(), addons);
+ }
+
+ /**
+ * Creates a new builder instance for configuring CraftsNet with the specified addons
+ * and caller class.
+ *
+ * @param caller The caller that called the create method.
+ * @param addons A {@link Collection} of {@link Addon} classes to include in the configuration.
+ * @return A new {@link AddonContainingBuilder} instance initialized with the specified addons.
+ * @since 3.8.14
+ */
+ private static AddonContainingBuilder create(Class> caller, Collection> addons) {
return new AddonContainingBuilder(addons)
- .addCodeSource(ReflectionUtils.getCallerClass().getProtectionDomain().getCodeSource());
+ .addCodeSource(caller.getProtectionDomain().getCodeSource());
}
}
From cfb4f164f66e3de6fcf7160feea44d5bc2532d82 Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Sun, 12 Apr 2026 17:25:47 +0200
Subject: [PATCH 19/23] refactor: STACK_WALKER is now accessible
---
.../craftsblock/craftsnet/utils/reflection/ReflectionUtils.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/de/craftsblock/craftsnet/utils/reflection/ReflectionUtils.java b/src/main/java/de/craftsblock/craftsnet/utils/reflection/ReflectionUtils.java
index 4006ee35..43e9fe28 100644
--- a/src/main/java/de/craftsblock/craftsnet/utils/reflection/ReflectionUtils.java
+++ b/src/main/java/de/craftsblock/craftsnet/utils/reflection/ReflectionUtils.java
@@ -21,7 +21,7 @@
public class ReflectionUtils {
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
- private static final StackWalker STACK_WALKER = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
+ public static final StackWalker STACK_WALKER = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
/**
* Private constructor to prevent direct instantiation
From fe426f5c1485ff77e6dd6f0167d63ccca2ddea20 Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Sun, 12 Apr 2026 17:26:11 +0200
Subject: [PATCH 20/23] chore: Bump version of tika-core to 3.3.0
---
build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build.gradle b/build.gradle
index e8c5e6d6..8d45a9e7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -49,7 +49,7 @@ dependencies {
// Third party needed dependencies ----------------------------------------------------------------------------------------
// https://mvnrepository.com/artifact/org.apache.tika/tika-core
- implementation "org.apache.tika:tika-core:3.2.3"
+ implementation "org.apache.tika:tika-core:3.3.0"
// https://mvnrepository.com/artifact/org.jetbrains/annotations
implementation "org.jetbrains:annotations:26.1.0"
From 7a3a9f1e2447c87d533d109834f3aa776a331068 Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Sun, 12 Apr 2026 17:28:17 +0200
Subject: [PATCH 21/23] chore: Bump version to 3.7.2
---
build.gradle | 2 +-
src/main/java/de/craftsblock/craftsnet/CraftsNet.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/build.gradle b/build.gradle
index 8d45a9e7..e759db64 100644
--- a/build.gradle
+++ b/build.gradle
@@ -17,7 +17,7 @@ application {
}
group = "de.craftsblock"
-version = "3.7.1"
+version = "3.7.2"
repositories {
mavenCentral()
diff --git a/src/main/java/de/craftsblock/craftsnet/CraftsNet.java b/src/main/java/de/craftsblock/craftsnet/CraftsNet.java
index 21a510e8..8831ae9d 100644
--- a/src/main/java/de/craftsblock/craftsnet/CraftsNet.java
+++ b/src/main/java/de/craftsblock/craftsnet/CraftsNet.java
@@ -52,7 +52,7 @@ public class CraftsNet {
/**
* The current version of CraftsNet.
*/
- public static final String version = "3.7.1";
+ public static final String version = "3.7.2";
private static CraftsNet instance;
From 3dcb8d69759516570ed1c3a1ed962fe04a003528 Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Sun, 19 Apr 2026 21:50:25 +0200
Subject: [PATCH 22/23] chore: Better version matching (#42)
---
.gitignore | 3 -
build.gradle | 17 +++-
.../de/craftsblock/craftsnet/CraftsNet.java | 4 +-
.../craftsnet/utils/versions/Comparison.java | 38 ++++++--
.../craftsnet/utils/versions/Versions.java | 17 ++--
.../utils/versions/ComparisonTest.java | 96 +++++++++++++++++++
.../utils/versions/VersionsTest.java | 93 ++++++++++++++++++
7 files changed, 247 insertions(+), 21 deletions(-)
create mode 100644 src/test/java/de/craftsblock/craftsnet/utils/versions/ComparisonTest.java
create mode 100644 src/test/java/de/craftsblock/craftsnet/utils/versions/VersionsTest.java
diff --git a/.gitignore b/.gitignore
index 7c979a7f..03d7f0bc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,9 +48,6 @@ bin/
/logs/
/sessions/
-### Test Stuff ###
-test/
-
### Mac OS ###
.DS_Store
diff --git a/build.gradle b/build.gradle
index e759db64..4b515f2d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,6 +2,7 @@ plugins {
id "java-library"
id "application"
id "de.craftsblock.gradle.publish" version "0.0.20"
+ id("com.autonomousapps.dependency-analysis") version "3.8.0"
}
java {
@@ -29,7 +30,7 @@ dependencies {
// CraftsBlock related dependencies ---------------------------------------------------------------------------------------
// https://repo.craftsblock.de/#/releases/de/craftsblock/craftscore/bom
- implementation platform("de.craftsblock.craftscore:bom:3.8.14")
+ implementation platform("de.craftsblock.craftscore:bom:3.8.15")
// https://repo.craftsblock.de/#/releases/de/craftsblock/craftscore/buffer
api "de.craftsblock.craftscore:buffer"
@@ -76,6 +77,20 @@ dependencies {
// https://mvnrepository.com/artifact/org.apache.maven.resolver/maven-resolver-util
implementation "org.apache.maven.resolver:maven-resolver-util:2.0.16"
+
+ // Testing ----------------------------------------------------------------------------------------------------------------
+
+ // https://mvnrepository.com/artifact/org.junit/junit-bom
+ testImplementation platform('org.junit:junit-bom:6.1.0-M1')
+
+ // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api
+ testImplementation 'org.junit.jupiter:junit-jupiter-api'
+
+ // https://mvnrepository.com/artifact/org.junit.platform/junit-platform-launcher
+ testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
+
+ // https://mvnrepository.com/artifact/org.assertj/assertj-core
+ testImplementation 'org.assertj:assertj-core:4.0.0-M1'
}
tasks.withType(JavaCompile).configureEach {
diff --git a/src/main/java/de/craftsblock/craftsnet/CraftsNet.java b/src/main/java/de/craftsblock/craftsnet/CraftsNet.java
index 8831ae9d..a67b47d2 100644
--- a/src/main/java/de/craftsblock/craftsnet/CraftsNet.java
+++ b/src/main/java/de/craftsblock/craftsnet/CraftsNet.java
@@ -132,8 +132,8 @@ public void start(CraftsNetBuilder builder) throws IOException {
logger.debug("JVM Version: %s; Max recognizable class file version: %s.%s",
jvmVersion.toString(), jvmVersion.feature() + 44, jvmVersion.interim());
- if (!builder.shouldSkipVersionCheck() && version.matches("^\\d+(?:\\.\\d+)*$")) {
- Versions.verbalCheck(this);
+ if (!builder.shouldSkipVersionCheck() && version.matches("^\\d+(?:[.-]\\d+)*$")) {
+ Versions.verbalCheckCraftsNet(this);
}
logger.debug("Preloading gson for faster processing");
diff --git a/src/main/java/de/craftsblock/craftsnet/utils/versions/Comparison.java b/src/main/java/de/craftsblock/craftsnet/utils/versions/Comparison.java
index 19af8512..6d2d54c4 100644
--- a/src/main/java/de/craftsblock/craftsnet/utils/versions/Comparison.java
+++ b/src/main/java/de/craftsblock/craftsnet/utils/versions/Comparison.java
@@ -1,5 +1,8 @@
package de.craftsblock.craftsnet.utils.versions;
+import org.jetbrains.annotations.Range;
+
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -23,11 +26,15 @@ enum Comparison {
GREATER_OR_EQUAL(">="),
EQUAL("=");
- private static final Map SYMBOLS = new HashMap<>();
+ private static final Map SYMBOLS;
static {
- for (Comparison comparison : Comparison.values())
- SYMBOLS.put(comparison.symbol, comparison);
+ HashMap symbols = new HashMap<>();
+ for (Comparison comparison : Comparison.values()) {
+ symbols.put(comparison.symbol, comparison);
+ }
+
+ SYMBOLS = Collections.unmodifiableMap(symbols);
}
private final String symbol;
@@ -60,10 +67,17 @@ public boolean suitable(String current, String expected) {
int c = parsePart(cs, i);
int e = parsePart(es, i);
- if (e == Integer.MIN_VALUE) continue;
+ if (e == Integer.MIN_VALUE) {
+ continue;
+ }
+
+ if (c < e) {
+ return apply(-1);
+ }
- if (c < e) return apply(-1);
- else if (c > e) return apply(1);
+ if (c > e) {
+ return apply(1);
+ }
}
return apply(0);
@@ -78,10 +92,16 @@ public boolean suitable(String current, String expected) {
* @return the parsed integer value of the version part, or 0 if not valid
*/
private int parsePart(String[] parts, int index) {
- if (index >= parts.length) return 0;
+ if (index >= parts.length) {
+ return 0;
+ }
+
try {
String part = parts[index];
- if (part.equals("*")) return Integer.MIN_VALUE;
+ if (part.equals("*")) {
+ return Integer.MIN_VALUE;
+ }
+
return Integer.parseInt(part);
} catch (NumberFormatException e) {
return 0;
@@ -104,7 +124,7 @@ private String sanitize(String version) {
* @param result the result of the comparison: -1 (less than), 0 (equal), or 1 (greater than)
* @return true if the comparison satisfies the operation, false otherwise
*/
- public boolean apply(int result) {
+ public boolean apply(@Range(from = -1, to = 1) int result) {
return switch (this) {
case LESS -> result < 0;
case GREATER -> result > 0;
diff --git a/src/main/java/de/craftsblock/craftsnet/utils/versions/Versions.java b/src/main/java/de/craftsblock/craftsnet/utils/versions/Versions.java
index ca06e4fd..c457fc34 100644
--- a/src/main/java/de/craftsblock/craftsnet/utils/versions/Versions.java
+++ b/src/main/java/de/craftsblock/craftsnet/utils/versions/Versions.java
@@ -52,7 +52,8 @@ public static boolean suitable(String current, String expected) {
* @return the cleaned version string containing only digits and dots
*/
private static String cleanVersion(String version) {
- return version.replaceAll("[^\\d.]", "");
+ return version.replace("-", ".")
+ .replaceAll("[^\\d.]", "");
}
/**
@@ -66,8 +67,11 @@ private static Comparison extractOperator(String version) {
Matcher matcher = pattern.matcher(version.substring(0, Math.min(version.length(), 2)));
String operator;
- if (matcher.find()) operator = matcher.group();
- else operator = "=";
+ if (matcher.find()) {
+ operator = matcher.group();
+ } else {
+ operator = "=";
+ }
return Comparison.from(operator);
}
@@ -77,7 +81,7 @@ private static Comparison extractOperator(String version) {
*
* @param craftsNet The current {@link CraftsNet} instance.
*/
- public static void verbalCheck(CraftsNet craftsNet) {
+ public static void verbalCheckCraftsNet(CraftsNet craftsNet) {
Logger logger = craftsNet.getLogger();
logger.info("Checking for new version...");
try {
@@ -90,12 +94,13 @@ public static void verbalCheck(CraftsNet craftsNet) {
return;
}
- if (Versions.suitable(CraftsNet.version, ">=" + json.getString("version"))) {
+ String latest = json.getString("version");
+ if (Versions.suitable(CraftsNet.version, ">=" + latest)) {
logger.info("You are using the newest version");
return;
}
- logger.warning("There is a newer version (%s) of CraftsNet available", json.getString("version"));
+ logger.warning("There is a newer version (%s) of CraftsNet available", latest);
}
} catch (Exception e) {
logger.error("Failed to fetch the latest version of CraftsNet!", e);
diff --git a/src/test/java/de/craftsblock/craftsnet/utils/versions/ComparisonTest.java b/src/test/java/de/craftsblock/craftsnet/utils/versions/ComparisonTest.java
new file mode 100644
index 00000000..a544b7b2
--- /dev/null
+++ b/src/test/java/de/craftsblock/craftsnet/utils/versions/ComparisonTest.java
@@ -0,0 +1,96 @@
+package de.craftsblock.craftsnet.utils.versions;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class ComparisonTest {
+
+ @Test
+ void shouldDetectEqualVersions() {
+ assertThat(Comparison.EQUAL.suitable("1.2.3", "1.2.3")).isTrue();
+ assertThat(Comparison.EQUAL.suitable("1.2.3", "1.2.4")).isFalse();
+ }
+
+ @Test
+ void shouldDetectGreaterVersions() {
+ assertThat(Comparison.GREATER.suitable("1.3.0", "1.2.0")).isTrue();
+ assertThat(Comparison.GREATER.suitable("1.2.0", "1.2.0")).isFalse();
+ }
+
+ @Test
+ void shouldDetectLessVersions() {
+ assertThat(Comparison.LESS.suitable("1.1.9", "1.2.0")).isTrue();
+ assertThat(Comparison.LESS.suitable("1.2.0", "1.2.0")).isFalse();
+ }
+
+ @Test
+ void shouldSupportGreaterOrEqual() {
+ assertThat(Comparison.GREATER_OR_EQUAL.suitable("1.2.0", "1.2.0")).isTrue();
+ assertThat(Comparison.GREATER_OR_EQUAL.suitable("1.3.0", "1.2.0")).isTrue();
+ assertThat(Comparison.GREATER_OR_EQUAL.suitable("1.1.9", "1.2.0")).isFalse();
+ }
+
+ @Test
+ void shouldSupportLessOrEqual() {
+ assertThat(Comparison.LESS_OR_EQUAL.suitable("1.2.0", "1.2.0")).isTrue();
+ assertThat(Comparison.LESS_OR_EQUAL.suitable("1.1.9", "1.2.0")).isTrue();
+ assertThat(Comparison.LESS_OR_EQUAL.suitable("1.3.0", "1.2.0")).isFalse();
+ }
+
+ @Test
+ void shouldHandleDifferentLengths() {
+ assertThat(Comparison.EQUAL.suitable("1.2", "1.2.0")).isTrue();
+ assertThat(Comparison.GREATER.suitable("1.2.1", "1.2")).isTrue();
+ assertThat(Comparison.LESS.suitable("1.2", "1.2.1")).isTrue();
+ }
+
+ @Test
+ void shouldHandleNullAndEmptyVersions() {
+ assertThat(Comparison.EQUAL.suitable(null, "0")).isTrue();
+ assertThat(Comparison.EQUAL.suitable("", "0")).isTrue();
+ }
+
+ @Test
+ void shouldTrimWhitespace() {
+ assertThat(Comparison.EQUAL.suitable(" 1.2.3 ", "1.2.3")).isTrue();
+ }
+
+ @Test
+ void shouldTreatInvalidPartsAsZero() {
+ assertThat(Comparison.EQUAL.suitable("1.a.3", "1.0.3")).isTrue();
+ }
+
+ @Test
+ void shouldIgnoreWildcardInExpected() {
+ assertThat(Comparison.EQUAL.suitable("1.2.3", "1.*.3")).isTrue();
+ assertThat(Comparison.GREATER_OR_EQUAL.suitable("1.2.3", "1.*.3")).isTrue();
+ }
+
+ @Test
+ void shouldApplyComparisonCorrectly() {
+ assertThat(Comparison.LESS.apply(-1)).isTrue();
+ assertThat(Comparison.LESS.apply(0)).isFalse();
+
+ assertThat(Comparison.GREATER.apply(1)).isTrue();
+ assertThat(Comparison.GREATER.apply(0)).isFalse();
+
+ assertThat(Comparison.EQUAL.apply(0)).isTrue();
+ }
+
+ @Test
+ void shouldResolveFromSymbol() {
+ assertThat(Comparison.from("<")).isEqualTo(Comparison.LESS);
+ assertThat(Comparison.from(">")).isEqualTo(Comparison.GREATER);
+ assertThat(Comparison.from("<=")).isEqualTo(Comparison.LESS_OR_EQUAL);
+ assertThat(Comparison.from(">=")).isEqualTo(Comparison.GREATER_OR_EQUAL);
+ assertThat(Comparison.from("=")).isEqualTo(Comparison.EQUAL);
+ }
+
+ @Test
+ void shouldDefaultToEqualForUnknownSymbol() {
+ assertThat(Comparison.from("??")).isEqualTo(Comparison.EQUAL);
+ assertThat(Comparison.from("")).isEqualTo(Comparison.EQUAL);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/de/craftsblock/craftsnet/utils/versions/VersionsTest.java b/src/test/java/de/craftsblock/craftsnet/utils/versions/VersionsTest.java
new file mode 100644
index 00000000..accabb08
--- /dev/null
+++ b/src/test/java/de/craftsblock/craftsnet/utils/versions/VersionsTest.java
@@ -0,0 +1,93 @@
+package de.craftsblock.craftsnet.utils.versions;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class VersionsTest {
+
+ @Test
+ void shouldReturnTrueWhenVersionsAreEqualWithoutOperator() {
+ boolean result = Versions.suitable("1.2.3", "1.2.3");
+ assertThat(result).isTrue();
+ }
+
+ @Test
+ void shouldReturnTrueWhenCurrentIsGreaterThanExpected() {
+ boolean result = Versions.suitable("1.3.0", ">1.2.0");
+ assertThat(result).isTrue();
+ }
+
+ @Test
+ void shouldReturnFalseWhenCurrentIsLessThanExpected() {
+ boolean result = Versions.suitable("1.1.9", ">1.2.0");
+ assertThat(result).isFalse();
+ }
+
+ @Test
+ void shouldSupportGreaterOrEqualOperator() {
+ assertThat(Versions.suitable("1.2.0", ">=1.2.0")).isTrue();
+ assertThat(Versions.suitable("1.3.0", ">=1.2.0")).isTrue();
+ assertThat(Versions.suitable("1.1.9", ">=1.2.0")).isFalse();
+ }
+
+ @Test
+ void shouldSupportLessOrEqualOperator() {
+ assertThat(Versions.suitable("1.2.0", "<=1.2.0")).isTrue();
+ assertThat(Versions.suitable("1.1.9", "<=1.2.0")).isTrue();
+ assertThat(Versions.suitable("1.3.0", "<=1.2.0")).isFalse();
+ }
+
+ @Test
+ void shouldSupportLessThanOperator() {
+ assertThat(Versions.suitable("1.1.9", "<1.2.0")).isTrue();
+ assertThat(Versions.suitable("1.2.0", "<1.2.0")).isFalse();
+ }
+
+ @Test
+ void shouldCleanVersionStrings() {
+ boolean result = Versions.suitable("1.2.3-SNAPSHOT", "1.2.3");
+ assertThat(result).isTrue();
+ }
+
+ @Test
+ void shouldHandleWeirdCharactersInVersion() {
+ boolean result = Versions.suitable("v1.2.3", "=1.2.3");
+ assertThat(result).isTrue();
+ }
+
+ @Test
+ void shouldDefaultToEqualsWhenNoOperatorProvided() {
+ assertThat(Versions.suitable("1.2.3", "1.2.3")).isTrue();
+ assertThat(Versions.suitable("1.2.4", "1.2.3")).isFalse();
+ }
+
+ @Test
+ void shouldHandleDashAsDotReplacement() {
+ boolean result = Versions.suitable("1-2-3", "1.2.3");
+ assertThat(result).isTrue();
+ }
+
+ @Test
+ void shouldCompareMultiSegmentVersionsCorrectly() {
+ assertThat(Versions.suitable("1.10.0", ">1.2.0")).isTrue();
+ assertThat(Versions.suitable("1.2.0", ">1.10.0")).isFalse();
+ }
+
+ @Test
+ void shouldHandleShortVersions() {
+ assertThat(Versions.suitable("1.2", "1.2.0")).isTrue();
+ assertThat(Versions.suitable("1.2.0", "1.2")).isTrue();
+ }
+
+ @Test
+ void shouldHandleTrailingDotsOrEmptyParts() {
+ assertThat(Versions.suitable("1.2.", "1.2.0")).isTrue();
+ }
+
+ @Test
+ void shouldHandleOnlyOperatorAsExpected() {
+ assertThat(Versions.suitable("1.2.3", ">")).isTrue();
+ }
+
+}
From 21171c4601fed0e7f045da7cf004bf36b006b9ef Mon Sep 17 00:00:00 2001
From: Philipp <62473021+CrAfTsArMy@users.noreply.github.com>
Date: Sun, 19 Apr 2026 21:54:05 +0200
Subject: [PATCH 23/23] chore: Bump version to 3.7.2-2
---
build.gradle | 4 ++--
src/main/java/de/craftsblock/craftsnet/CraftsNet.java | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/build.gradle b/build.gradle
index 4b515f2d..625bd919 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,7 +1,7 @@
plugins {
id "java-library"
id "application"
- id "de.craftsblock.gradle.publish" version "0.0.20"
+ id "de.craftsblock.gradle.publish" version "0.0.21"
id("com.autonomousapps.dependency-analysis") version "3.8.0"
}
@@ -18,7 +18,7 @@ application {
}
group = "de.craftsblock"
-version = "3.7.2"
+version = "3.7.2-2"
repositories {
mavenCentral()
diff --git a/src/main/java/de/craftsblock/craftsnet/CraftsNet.java b/src/main/java/de/craftsblock/craftsnet/CraftsNet.java
index a67b47d2..1e990713 100644
--- a/src/main/java/de/craftsblock/craftsnet/CraftsNet.java
+++ b/src/main/java/de/craftsblock/craftsnet/CraftsNet.java
@@ -52,7 +52,7 @@ public class CraftsNet {
/**
* The current version of CraftsNet.
*/
- public static final String version = "3.7.2";
+ public static final String version = "3.7.2-2";
private static CraftsNet instance;