From b7de6f2ea57ccfea471c09033bd49ef5542b4b31 Mon Sep 17 00:00:00 2001 From: Space Walker Date: Sat, 12 Sep 2026 17:22:55 +0200 Subject: [PATCH 1/2] [networking] improve handling of legacy channel format --- libraries/networking/README.md | 6 +- .../IdentifierChannelIdentifierParser.java | 2 +- .../osl/networking/api/PacketBuffer.java | 1 - .../osl/networking/impl/HandshakePayload.java | 14 ++-- .../IdentifierChannelIdentifierParser.java | 2 +- .../osl/networking/impl/HandshakePayload.java | 14 ++-- .../osl/networking/impl/HandshakePayload.java | 14 ++-- .../osl/networking/impl/HandshakePayload.java | 14 ++-- .../osl/networking/impl/HandshakePayload.java | 14 ++-- .../osl/networking/impl/HandshakePayload.java | 14 ++-- .../networking/api/ChannelIdentifiers.java | 80 ++++++++++++------- .../api/LegacyChannelIdentifier.java | 37 +++++++++ .../api/StringChannelIdentifierParser.java | 48 ++++++----- .../osl/networking/impl/Constants.java | 2 +- .../impl/LegacyChannelIdentifierImpl.java | 71 ++++++++++++++++ 15 files changed, 221 insertions(+), 112 deletions(-) create mode 100644 libraries/networking/src/main/java/net/ornithemc/osl/networking/api/LegacyChannelIdentifier.java create mode 100644 libraries/networking/src/main/java/net/ornithemc/osl/networking/impl/LegacyChannelIdentifierImpl.java diff --git a/libraries/networking/README.md b/libraries/networking/README.md index 71591f717..c74e75d88 100644 --- a/libraries/networking/README.md +++ b/libraries/networking/README.md @@ -24,13 +24,13 @@ Channels identifiers should be constructed through the `ChannelIdentifieres` cla and snake case for the identifier. ```java -public static final NamespacedIdentifier COOKIE_CHANNEL = ChannelIdentifiers.from("example", "cookie"); +public static final NamespacedIdentifier COOKIE_CHANNEL = ChannelIdentifiers.register("example", "cookie"); ``` -You are expected to register your channels through the `ChannelRegistry`. +In 1.13-pre2 and below, the game did not validate channel names, so Minecraft itself used names like `MC|Brand`. If you require a channel name with this convention, you can use the `legacy` factory methods instead. ```java -ChannelRegistry.register(COOKIE_CHANNEL); +ChannelRegistry.register(ChannelIdentifiers.legacy("EXAMPLE", "Cookie")); // -> "EXAMPLE|Cookie" ``` You are expected to register your packet listeners in your mod initializer through `ClientPlayNetworking` and `ServerPlayNetworking`. diff --git a/libraries/networking/networking-mc13w41a-mc18w30b/src/main/java/net/ornithemc/osl/networking/api/IdentifierChannelIdentifierParser.java b/libraries/networking/networking-mc13w41a-mc18w30b/src/main/java/net/ornithemc/osl/networking/api/IdentifierChannelIdentifierParser.java index e3de1820c..7c4ac3f50 100644 --- a/libraries/networking/networking-mc13w41a-mc18w30b/src/main/java/net/ornithemc/osl/networking/api/IdentifierChannelIdentifierParser.java +++ b/libraries/networking/networking-mc13w41a-mc18w30b/src/main/java/net/ornithemc/osl/networking/api/IdentifierChannelIdentifierParser.java @@ -34,7 +34,7 @@ public static NamespacedIdentifier fromIdentifier(Identifier id) { */ public static NamespacedIdentifier fromIdentifierOrThrow(Identifier id) { try { - return ChannelIdentifiers.from(id.getNamespace(), id.getPath()); + return ChannelIdentifiers.validate(id); } catch (ChannelIdentifierException e) { throw ChannelIdentifierParseException.invalid(id.toString(), e); } diff --git a/libraries/networking/networking-mc13w41a-mc18w30b/src/main/java/net/ornithemc/osl/networking/api/PacketBuffer.java b/libraries/networking/networking-mc13w41a-mc18w30b/src/main/java/net/ornithemc/osl/networking/api/PacketBuffer.java index 81e5a6cff..fb146366a 100644 --- a/libraries/networking/networking-mc13w41a-mc18w30b/src/main/java/net/ornithemc/osl/networking/api/PacketBuffer.java +++ b/libraries/networking/networking-mc13w41a-mc18w30b/src/main/java/net/ornithemc/osl/networking/api/PacketBuffer.java @@ -23,7 +23,6 @@ import net.minecraft.resource.Identifier; import net.minecraft.text.Text; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3i; import net.ornithemc.osl.core.api.util.NamespacedIdentifier; import net.ornithemc.osl.core.api.util.NamespacedIdentifiers; diff --git a/libraries/networking/networking-mc13w41a-mc18w30b/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java b/libraries/networking/networking-mc13w41a-mc18w30b/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java index a9bbf2bac..48bff49d1 100644 --- a/libraries/networking/networking-mc13w41a-mc18w30b/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java +++ b/libraries/networking/networking-mc13w41a-mc18w30b/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java @@ -5,16 +5,15 @@ import java.util.Set; import net.ornithemc.osl.core.api.util.NamespacedIdentifier; -import net.ornithemc.osl.networking.api.ChannelIdentifiers; -import net.ornithemc.osl.networking.api.ChannelRegistry; import net.ornithemc.osl.networking.api.PacketBuffer; import net.ornithemc.osl.networking.api.PacketPayload; +import net.ornithemc.osl.networking.api.StringChannelIdentifierParser; import net.ornithemc.osl.networking.impl.client.ClientPlayNetworkingImpl; import net.ornithemc.osl.networking.impl.server.ServerPlayNetworkingImpl; public class HandshakePayload implements PacketPayload { - public static final NamespacedIdentifier CHANNEL = ChannelRegistry.register(Constants.OSL_HANDSHAKE_CHANNEL); + public static final NamespacedIdentifier CHANNEL = Constants.OSL_HANDSHAKE_CHANNEL; public byte protocol; public Set channels; @@ -24,10 +23,7 @@ public HandshakePayload() { public HandshakePayload(Set channels) { this.protocol = Constants.OSL_HANDSHAKE_PROTOCOL; - // we allow registering listeners on channels that do not conform to OSL spec - // but payloads sent over these channels aren't sent via OSL so we can ignore - // them for the OSL handshake. - this.channels = ChannelIdentifiers.dropInvalid(channels); + this.channels = channels; } public static HandshakePayload client() { @@ -46,7 +42,7 @@ public void read(PacketBuffer buffer) throws IOException { int channelCount = buffer.readInt(); for (int i = 0; i < channelCount; i++) { - channels.add(buffer.readNamespacedIdentifier()); + channels.add(StringChannelIdentifierParser.fromString(buffer.readString())); } } @@ -56,7 +52,7 @@ public void write(PacketBuffer buffer) throws IOException { buffer.writeInt(channels.size()); for (NamespacedIdentifier channel : channels) { - buffer.writeNamespacedIdentifier(channel); + buffer.writeString(StringChannelIdentifierParser.toString(channel)); } } } diff --git a/libraries/networking/networking-mc18w31a-mc1.14.4/src/main/java/net/ornithemc/osl/networking/api/IdentifierChannelIdentifierParser.java b/libraries/networking/networking-mc18w31a-mc1.14.4/src/main/java/net/ornithemc/osl/networking/api/IdentifierChannelIdentifierParser.java index e3de1820c..7c4ac3f50 100644 --- a/libraries/networking/networking-mc18w31a-mc1.14.4/src/main/java/net/ornithemc/osl/networking/api/IdentifierChannelIdentifierParser.java +++ b/libraries/networking/networking-mc18w31a-mc1.14.4/src/main/java/net/ornithemc/osl/networking/api/IdentifierChannelIdentifierParser.java @@ -34,7 +34,7 @@ public static NamespacedIdentifier fromIdentifier(Identifier id) { */ public static NamespacedIdentifier fromIdentifierOrThrow(Identifier id) { try { - return ChannelIdentifiers.from(id.getNamespace(), id.getPath()); + return ChannelIdentifiers.validate(id); } catch (ChannelIdentifierException e) { throw ChannelIdentifierParseException.invalid(id.toString(), e); } diff --git a/libraries/networking/networking-mc18w31a-mc1.14.4/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java b/libraries/networking/networking-mc18w31a-mc1.14.4/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java index a9bbf2bac..48bff49d1 100644 --- a/libraries/networking/networking-mc18w31a-mc1.14.4/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java +++ b/libraries/networking/networking-mc18w31a-mc1.14.4/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java @@ -5,16 +5,15 @@ import java.util.Set; import net.ornithemc.osl.core.api.util.NamespacedIdentifier; -import net.ornithemc.osl.networking.api.ChannelIdentifiers; -import net.ornithemc.osl.networking.api.ChannelRegistry; import net.ornithemc.osl.networking.api.PacketBuffer; import net.ornithemc.osl.networking.api.PacketPayload; +import net.ornithemc.osl.networking.api.StringChannelIdentifierParser; import net.ornithemc.osl.networking.impl.client.ClientPlayNetworkingImpl; import net.ornithemc.osl.networking.impl.server.ServerPlayNetworkingImpl; public class HandshakePayload implements PacketPayload { - public static final NamespacedIdentifier CHANNEL = ChannelRegistry.register(Constants.OSL_HANDSHAKE_CHANNEL); + public static final NamespacedIdentifier CHANNEL = Constants.OSL_HANDSHAKE_CHANNEL; public byte protocol; public Set channels; @@ -24,10 +23,7 @@ public HandshakePayload() { public HandshakePayload(Set channels) { this.protocol = Constants.OSL_HANDSHAKE_PROTOCOL; - // we allow registering listeners on channels that do not conform to OSL spec - // but payloads sent over these channels aren't sent via OSL so we can ignore - // them for the OSL handshake. - this.channels = ChannelIdentifiers.dropInvalid(channels); + this.channels = channels; } public static HandshakePayload client() { @@ -46,7 +42,7 @@ public void read(PacketBuffer buffer) throws IOException { int channelCount = buffer.readInt(); for (int i = 0; i < channelCount; i++) { - channels.add(buffer.readNamespacedIdentifier()); + channels.add(StringChannelIdentifierParser.fromString(buffer.readString())); } } @@ -56,7 +52,7 @@ public void write(PacketBuffer buffer) throws IOException { buffer.writeInt(channels.size()); for (NamespacedIdentifier channel : channels) { - buffer.writeNamespacedIdentifier(channel); + buffer.writeString(StringChannelIdentifierParser.toString(channel)); } } } diff --git a/libraries/networking/networking-mca0.1.0-mca0.2.1/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java b/libraries/networking/networking-mca0.1.0-mca0.2.1/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java index c07137a52..af1662778 100644 --- a/libraries/networking/networking-mca0.1.0-mca0.2.1/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java +++ b/libraries/networking/networking-mca0.1.0-mca0.2.1/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java @@ -5,15 +5,14 @@ import java.util.Set; import net.ornithemc.osl.core.api.util.NamespacedIdentifier; -import net.ornithemc.osl.networking.api.ChannelIdentifiers; -import net.ornithemc.osl.networking.api.ChannelRegistry; import net.ornithemc.osl.networking.api.PacketBuffer; import net.ornithemc.osl.networking.api.PacketPayload; +import net.ornithemc.osl.networking.api.StringChannelIdentifierParser; import net.ornithemc.osl.networking.impl.server.ServerPlayNetworkingImpl; public class HandshakePayload implements PacketPayload { - public static final NamespacedIdentifier CHANNEL = ChannelRegistry.register(Constants.OSL_HANDSHAKE_CHANNEL); + public static final NamespacedIdentifier CHANNEL = Constants.OSL_HANDSHAKE_CHANNEL; public byte protocol; public Set channels; @@ -23,10 +22,7 @@ public HandshakePayload() { public HandshakePayload(Set channels) { this.protocol = Constants.OSL_HANDSHAKE_PROTOCOL; - // we allow registering listeners on channels that do not conform to OSL spec - // but payloads sent over these channels aren't sent via OSL so we can ignore - // them for the OSL handshake. - this.channels = ChannelIdentifiers.dropInvalid(channels); + this.channels = channels; } public static HandshakePayload server() { @@ -41,7 +37,7 @@ public void read(PacketBuffer buffer) throws IOException { int channelCount = buffer.readInt(); for (int i = 0; i < channelCount; i++) { - channels.add(buffer.readNamespacedIdentifier()); + channels.add(StringChannelIdentifierParser.fromString(buffer.readString())); } } @@ -51,7 +47,7 @@ public void write(PacketBuffer buffer) throws IOException { buffer.writeInt(channels.size()); for (NamespacedIdentifier channel : channels) { - buffer.writeNamespacedIdentifier(channel); + buffer.writeString(StringChannelIdentifierParser.toString(channel)); } } } diff --git a/libraries/networking/networking-mca0.2.2-mca0.2.8/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java b/libraries/networking/networking-mca0.2.2-mca0.2.8/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java index c07137a52..af1662778 100644 --- a/libraries/networking/networking-mca0.2.2-mca0.2.8/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java +++ b/libraries/networking/networking-mca0.2.2-mca0.2.8/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java @@ -5,15 +5,14 @@ import java.util.Set; import net.ornithemc.osl.core.api.util.NamespacedIdentifier; -import net.ornithemc.osl.networking.api.ChannelIdentifiers; -import net.ornithemc.osl.networking.api.ChannelRegistry; import net.ornithemc.osl.networking.api.PacketBuffer; import net.ornithemc.osl.networking.api.PacketPayload; +import net.ornithemc.osl.networking.api.StringChannelIdentifierParser; import net.ornithemc.osl.networking.impl.server.ServerPlayNetworkingImpl; public class HandshakePayload implements PacketPayload { - public static final NamespacedIdentifier CHANNEL = ChannelRegistry.register(Constants.OSL_HANDSHAKE_CHANNEL); + public static final NamespacedIdentifier CHANNEL = Constants.OSL_HANDSHAKE_CHANNEL; public byte protocol; public Set channels; @@ -23,10 +22,7 @@ public HandshakePayload() { public HandshakePayload(Set channels) { this.protocol = Constants.OSL_HANDSHAKE_PROTOCOL; - // we allow registering listeners on channels that do not conform to OSL spec - // but payloads sent over these channels aren't sent via OSL so we can ignore - // them for the OSL handshake. - this.channels = ChannelIdentifiers.dropInvalid(channels); + this.channels = channels; } public static HandshakePayload server() { @@ -41,7 +37,7 @@ public void read(PacketBuffer buffer) throws IOException { int channelCount = buffer.readInt(); for (int i = 0; i < channelCount; i++) { - channels.add(buffer.readNamespacedIdentifier()); + channels.add(StringChannelIdentifierParser.fromString(buffer.readString())); } } @@ -51,7 +47,7 @@ public void write(PacketBuffer buffer) throws IOException { buffer.writeInt(channels.size()); for (NamespacedIdentifier channel : channels) { - buffer.writeNamespacedIdentifier(channel); + buffer.writeString(StringChannelIdentifierParser.toString(channel)); } } } diff --git a/libraries/networking/networking-mca1.0.16-mca1.2.6/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java b/libraries/networking/networking-mca1.0.16-mca1.2.6/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java index d09f7dbd7..59e0dcd80 100644 --- a/libraries/networking/networking-mca1.0.16-mca1.2.6/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java +++ b/libraries/networking/networking-mca1.0.16-mca1.2.6/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java @@ -5,15 +5,14 @@ import java.util.Set; import net.ornithemc.osl.core.api.util.NamespacedIdentifier; -import net.ornithemc.osl.networking.api.ChannelIdentifiers; -import net.ornithemc.osl.networking.api.ChannelRegistry; import net.ornithemc.osl.networking.api.PacketBuffer; import net.ornithemc.osl.networking.api.PacketPayload; +import net.ornithemc.osl.networking.api.StringChannelIdentifierParser; import net.ornithemc.osl.networking.impl.client.ClientPlayNetworkingImpl; public class HandshakePayload implements PacketPayload { - public static final NamespacedIdentifier CHANNEL = ChannelRegistry.register(Constants.OSL_HANDSHAKE_CHANNEL); + public static final NamespacedIdentifier CHANNEL = Constants.OSL_HANDSHAKE_CHANNEL; public byte protocol; public Set channels; @@ -23,10 +22,7 @@ public HandshakePayload() { public HandshakePayload(Set channels) { this.protocol = Constants.OSL_HANDSHAKE_PROTOCOL; - // we allow registering listeners on channels that do not conform to OSL spec - // but payloads sent over these channels aren't sent via OSL so we can ignore - // them for the OSL handshake. - this.channels = ChannelIdentifiers.dropInvalid(channels); + this.channels = channels; } public static HandshakePayload client() { @@ -41,7 +37,7 @@ public void read(PacketBuffer buffer) throws IOException { int channelCount = buffer.readInt(); for (int i = 0; i < channelCount; i++) { - channels.add(buffer.readNamespacedIdentifier()); + channels.add(StringChannelIdentifierParser.fromString(buffer.readString())); } } @@ -51,7 +47,7 @@ public void write(PacketBuffer buffer) throws IOException { buffer.writeInt(channels.size()); for (NamespacedIdentifier channel : channels) { - buffer.writeNamespacedIdentifier(channel); + buffer.writeString(StringChannelIdentifierParser.toString(channel)); } } } diff --git a/libraries/networking/networking-mcb1.0-mc13w39b/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java b/libraries/networking/networking-mcb1.0-mc13w39b/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java index a9bbf2bac..48bff49d1 100644 --- a/libraries/networking/networking-mcb1.0-mc13w39b/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java +++ b/libraries/networking/networking-mcb1.0-mc13w39b/src/main/java/net/ornithemc/osl/networking/impl/HandshakePayload.java @@ -5,16 +5,15 @@ import java.util.Set; import net.ornithemc.osl.core.api.util.NamespacedIdentifier; -import net.ornithemc.osl.networking.api.ChannelIdentifiers; -import net.ornithemc.osl.networking.api.ChannelRegistry; import net.ornithemc.osl.networking.api.PacketBuffer; import net.ornithemc.osl.networking.api.PacketPayload; +import net.ornithemc.osl.networking.api.StringChannelIdentifierParser; import net.ornithemc.osl.networking.impl.client.ClientPlayNetworkingImpl; import net.ornithemc.osl.networking.impl.server.ServerPlayNetworkingImpl; public class HandshakePayload implements PacketPayload { - public static final NamespacedIdentifier CHANNEL = ChannelRegistry.register(Constants.OSL_HANDSHAKE_CHANNEL); + public static final NamespacedIdentifier CHANNEL = Constants.OSL_HANDSHAKE_CHANNEL; public byte protocol; public Set channels; @@ -24,10 +23,7 @@ public HandshakePayload() { public HandshakePayload(Set channels) { this.protocol = Constants.OSL_HANDSHAKE_PROTOCOL; - // we allow registering listeners on channels that do not conform to OSL spec - // but payloads sent over these channels aren't sent via OSL so we can ignore - // them for the OSL handshake. - this.channels = ChannelIdentifiers.dropInvalid(channels); + this.channels = channels; } public static HandshakePayload client() { @@ -46,7 +42,7 @@ public void read(PacketBuffer buffer) throws IOException { int channelCount = buffer.readInt(); for (int i = 0; i < channelCount; i++) { - channels.add(buffer.readNamespacedIdentifier()); + channels.add(StringChannelIdentifierParser.fromString(buffer.readString())); } } @@ -56,7 +52,7 @@ public void write(PacketBuffer buffer) throws IOException { buffer.writeInt(channels.size()); for (NamespacedIdentifier channel : channels) { - buffer.writeNamespacedIdentifier(channel); + buffer.writeString(StringChannelIdentifierParser.toString(channel)); } } } diff --git a/libraries/networking/src/main/java/net/ornithemc/osl/networking/api/ChannelIdentifiers.java b/libraries/networking/src/main/java/net/ornithemc/osl/networking/api/ChannelIdentifiers.java index 55358b7d1..4867d8644 100644 --- a/libraries/networking/src/main/java/net/ornithemc/osl/networking/api/ChannelIdentifiers.java +++ b/libraries/networking/src/main/java/net/ornithemc/osl/networking/api/ChannelIdentifiers.java @@ -1,12 +1,10 @@ package net.ornithemc.osl.networking.api; -import java.util.Set; -import java.util.stream.Collectors; - import net.ornithemc.osl.core.api.util.NamespacedIdentifier; import net.ornithemc.osl.core.api.util.NamespacedIdentifiers; import net.ornithemc.osl.core.impl.util.NamespacedIdentifierException; import net.ornithemc.osl.networking.impl.ChannelIdentifierException; +import net.ornithemc.osl.networking.impl.LegacyChannelIdentifierImpl; /** * Utility methods for creating and validating channel identifiers. @@ -28,6 +26,37 @@ public final class ChannelIdentifiers { */ public static final int MAX_LENGTH_IDENTIFIER = Byte.MAX_VALUE; + /** + * Construct, validate, and register a channel identifier with the default namespace and given identifier. + */ + public static NamespacedIdentifier register(String identifier) { + return register(DEFAULT_NAMESPACE, identifier); + } + + /** + * Construct, validate, and register a channel identifier with the given namespace and identifier. + */ + public static NamespacedIdentifier register(String namespace, String identifier) { + return ChannelRegistry.register(NamespacedIdentifiers.from( + validateNamespace(namespace), + validateIdentifier(identifier) + )); + } + + /** + * Construct, validate, and register a channel identifier with the default namespace and given identifier. + */ + public static NamespacedIdentifier register(String identifier, boolean clientbound, boolean serverbound) { + return register(DEFAULT_NAMESPACE, identifier, clientbound, serverbound); + } + + /** + * Construct, validate, and register a channel identifier with the given namespace and identifier. + */ + public static NamespacedIdentifier register(String namespace, String identifier, boolean clientbound, boolean serverbound) { + return ChannelRegistry.register(from(namespace, identifier), clientbound, serverbound); + } + /** * Construct and validate a channel identifier with the default namespace and the given identifier. */ @@ -45,6 +74,24 @@ public static NamespacedIdentifier from(String namespace, String identifier) { ); } + /** + * Construct a legacy format channel identifier with the given identifier. + * + * @see LegacyChannelIdentifier + */ + public static NamespacedIdentifier legacy(String identifier) { + return legacy("", identifier); + } + + /** + * Construct a legacy format channel identifier with the given namespace and identifier. + * + * @see LegacyChannelIdentifier + */ + public static NamespacedIdentifier legacy(String namespace, String identifier) { + return new LegacyChannelIdentifierImpl(namespace, identifier); + } + /** * Check whether the given channel identifier is valid, or throw an exception. */ @@ -54,7 +101,7 @@ public static NamespacedIdentifier validate(NamespacedIdentifier id) { validateIdentifier(id.identifier()); return id; - } catch (ChannelIdentifierException e) { + } catch (ChannelIdentifierException | NamespacedIdentifierException e) { throw ChannelIdentifierException.invalid(id, e); } } @@ -63,15 +110,9 @@ public static NamespacedIdentifier validate(NamespacedIdentifier id) { * Check that the given namespace is valid for a channel identifier. */ public static String validateNamespace(String namespace) { - if (namespace == null || namespace.isEmpty()) { - throw ChannelIdentifierException.invalidNamespace(namespace, "null or empty"); - } if (namespace.length() > MAX_LENGTH_NAMESPACE) { throw ChannelIdentifierException.invalidNamespace(namespace, "length " + namespace.length() + " is greater than maximum allowed " + MAX_LENGTH_NAMESPACE); } - if (!namespace.chars().allMatch(chr -> chr == '-' || chr == '.' || chr == '_' || (chr >= 'a' && chr <= 'z') || (chr >= '0' && chr <= '9'))) { - throw ChannelIdentifierException.invalidNamespace(namespace, "contains illegal characters - only [a-z0-9-._] are allowed"); - } return NamespacedIdentifiers.validateNamespace(namespace); } @@ -80,29 +121,10 @@ public static String validateNamespace(String namespace) { * Check that the given identifier is valid for a channel identifier. */ public static String validateIdentifier(String identifier) { - if (identifier == null || identifier.isEmpty()) { - throw ChannelIdentifierException.invalidIdentifier(identifier, "null or empty"); - } if (identifier.length() > MAX_LENGTH_IDENTIFIER) { throw ChannelIdentifierException.invalidIdentifier(identifier, "length " + identifier.length() + " is greater than maximum allowed " + MAX_LENGTH_IDENTIFIER); } - if (!identifier.chars().allMatch(chr -> chr == '-' || chr == '.' || chr == '_' || chr == '/' || (chr >= 'a' && chr <= 'z') || (chr >= '0' && chr <= '9'))) { - throw ChannelIdentifierException.invalidIdentifier(identifier, "contains illegal characters - only [a-z0-9-._/] are allowed"); - } return NamespacedIdentifiers.validateIdentifier(identifier); } - - public static Set dropInvalid(Set channels) { - return channels - .stream() - .filter(channel -> { - try { - return ChannelIdentifiers.validate(channel) != null; - } catch (ChannelIdentifierException | NamespacedIdentifierException e) { - return false; - } - }) - .collect(Collectors.toSet()); - } } diff --git a/libraries/networking/src/main/java/net/ornithemc/osl/networking/api/LegacyChannelIdentifier.java b/libraries/networking/src/main/java/net/ornithemc/osl/networking/api/LegacyChannelIdentifier.java new file mode 100644 index 000000000..01a1b1c63 --- /dev/null +++ b/libraries/networking/src/main/java/net/ornithemc/osl/networking/api/LegacyChannelIdentifier.java @@ -0,0 +1,37 @@ +package net.ornithemc.osl.networking.api; + +import net.ornithemc.osl.core.api.util.NamespacedIdentifier; + +/** + * A {@linkplain NamespacedIdentifier} implementation that represents a packet + * channel in the legacy format used in 1.13-pre2 and below. The legacy format + * uses the vertical bar character ({@code '|'}) as the separator, but that is + * only by convention, as no format is strictly enforced, and any character in + * the UTF-8 character set is allowed. As such, strings like {@code "MC|Brand"} + * and {@code "REGISTER"} are valid channel identifiers in the legacy format. + */ +public interface LegacyChannelIdentifier extends NamespacedIdentifier { + + char SEPARATOR = '|'; + + @Override + default char separator() { + return SEPARATOR; + } + + @Override + LegacyChannelIdentifier namespaced(String namespace); + + @Override + LegacyChannelIdentifier prefixed(String prefix); + + @Override + LegacyChannelIdentifier suffixed(String suffix); + + @Override + LegacyChannelIdentifier subidentifier(int beginIndex); + + @Override + LegacyChannelIdentifier subidentifier(int beginIndex, int endIndex); + +} diff --git a/libraries/networking/src/main/java/net/ornithemc/osl/networking/api/StringChannelIdentifierParser.java b/libraries/networking/src/main/java/net/ornithemc/osl/networking/api/StringChannelIdentifierParser.java index 35b2fa805..3b027b8d4 100644 --- a/libraries/networking/src/main/java/net/ornithemc/osl/networking/api/StringChannelIdentifierParser.java +++ b/libraries/networking/src/main/java/net/ornithemc/osl/networking/api/StringChannelIdentifierParser.java @@ -2,8 +2,8 @@ import net.ornithemc.osl.core.api.util.NamespacedIdentifier; import net.ornithemc.osl.core.impl.util.NamespacedIdentifierImpl; -import net.ornithemc.osl.networking.impl.ChannelIdentifierException; import net.ornithemc.osl.networking.impl.ChannelIdentifierParseException; +import net.ornithemc.osl.networking.impl.LegacyChannelIdentifierImpl; /** * Utility methods for converting channel identifiers from and to {@link String}s. @@ -23,15 +23,20 @@ public final class StringChannelIdentifierParser { * which may or may not be a valid identifier. */ public static NamespacedIdentifier fromString(String s) { - int i = s.indexOf('|'); + int i = s.indexOf(LegacyChannelIdentifier.SEPARATOR); - if (i < 1) { - // allow null namespaces to support channel ids that do not conform - // to OSL spec - MC did not enforce a strict spec before 1.13 - return new NamespacedIdentifierImpl("", s); - } else { - return new NamespacedIdentifierImpl(s.substring(0, i), s.substring(i + 1)); + if (i > 0) { + return new LegacyChannelIdentifierImpl(s.substring(0, i), s.substring(i + 1)); } + + i = s.indexOf(NamespacedIdentifier.SEPARATOR); + + if (i < 0) { + // allow empty namespaces since MC did not enforce a strict spec before 1.13 + return new LegacyChannelIdentifierImpl("", s); + } + + return new NamespacedIdentifierImpl(s.substring(0, i), s.substring(i + 1)); } /** @@ -45,27 +50,26 @@ public static NamespacedIdentifier fromString(String s) { * if no valid channel identifier can be parsed from the given {@code String}. */ public static NamespacedIdentifier fromStringOrThrow(String s) { - int i = s.indexOf('|'); + int i = s.indexOf(LegacyChannelIdentifier.SEPARATOR); - try { - if (i < 0) { - return ChannelIdentifiers.from(s); - } else if (i > 0) { - return ChannelIdentifiers.from(s.substring(0, i), s.substring(i + 1)); - } else { - throw ChannelIdentifierParseException.invalid(s, "badly formatted"); - } - } catch (ChannelIdentifierException e) { - throw ChannelIdentifierParseException.invalid(s, e); + if (i > 0) { + return new LegacyChannelIdentifierImpl(s.substring(0, i), s.substring(i + 1)); } + + i = s.indexOf(NamespacedIdentifier.SEPARATOR); + + if (i < 0) { + // allow empty namespaces since MC did not enforce a strict spec before 1.13 + return new LegacyChannelIdentifierImpl("", s); + } + + return ChannelIdentifiers.validate(new NamespacedIdentifierImpl(s.substring(0, i), s.substring(i + 1))); } /** * Convert the given {@code NamespacedIdentifier} to its {@code String} representation. */ public static String toString(NamespacedIdentifier id) { - return id.namespace().isEmpty() - ? id.identifier() - : id.namespace() + "|" + id.identifier(); + return id.toString(); } } diff --git a/libraries/networking/src/main/java/net/ornithemc/osl/networking/impl/Constants.java b/libraries/networking/src/main/java/net/ornithemc/osl/networking/impl/Constants.java index 5ae8b5981..d828c191c 100644 --- a/libraries/networking/src/main/java/net/ornithemc/osl/networking/impl/Constants.java +++ b/libraries/networking/src/main/java/net/ornithemc/osl/networking/impl/Constants.java @@ -23,6 +23,6 @@ public final class Constants { /** * The channel identifier for OSL's handshake payload. */ - public static final NamespacedIdentifier OSL_HANDSHAKE_CHANNEL = ChannelIdentifiers.from("osl", "handshake"); + public static final NamespacedIdentifier OSL_HANDSHAKE_CHANNEL = ChannelIdentifiers.register("osl", "handshake"); } diff --git a/libraries/networking/src/main/java/net/ornithemc/osl/networking/impl/LegacyChannelIdentifierImpl.java b/libraries/networking/src/main/java/net/ornithemc/osl/networking/impl/LegacyChannelIdentifierImpl.java new file mode 100644 index 000000000..b62587812 --- /dev/null +++ b/libraries/networking/src/main/java/net/ornithemc/osl/networking/impl/LegacyChannelIdentifierImpl.java @@ -0,0 +1,71 @@ +package net.ornithemc.osl.networking.impl; + +import net.ornithemc.osl.core.api.util.NamespacedIdentifiers; +import net.ornithemc.osl.networking.api.LegacyChannelIdentifier; + +public final class LegacyChannelIdentifierImpl implements LegacyChannelIdentifier { + + private final String namespace; + private final String identifier; + + public LegacyChannelIdentifierImpl(String namespace, String identifier) { + this.namespace = namespace; + this.identifier = identifier; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof LegacyChannelIdentifier)) { + return false; + } + return NamespacedIdentifiers.equals(this, (LegacyChannelIdentifier) o); + } + + @Override + public int hashCode() { + return 31 * namespace.hashCode() + identifier.hashCode(); + } + + @Override + public String toString() { + return namespace.isEmpty() ? identifier : (namespace + SEPARATOR + identifier); + } + + @Override + public String namespace() { + return namespace; + } + + @Override + public String identifier() { + return identifier; + } + + @Override + public LegacyChannelIdentifier namespaced(String namespace) { + return new LegacyChannelIdentifierImpl(namespace, identifier); + } + + @Override + public LegacyChannelIdentifier prefixed(String prefix) { + return new LegacyChannelIdentifierImpl(namespace, prefix + identifier); + } + + @Override + public LegacyChannelIdentifier suffixed(String suffix) { + return new LegacyChannelIdentifierImpl(namespace, identifier + suffix); + } + + @Override + public LegacyChannelIdentifier subidentifier(int beginIndex) { + return new LegacyChannelIdentifierImpl(namespace, identifier.substring(beginIndex)); + } + + @Override + public LegacyChannelIdentifier subidentifier(int beginIndex, int endIndex) { + return new LegacyChannelIdentifierImpl(namespace, identifier.substring(beginIndex, endIndex)); + } +} From ddcd5ff0fc3f10c2d162ba6e6ff7190cf076c313 Mon Sep 17 00:00:00 2001 From: Space Walker Date: Mon, 28 Sep 2026 16:23:35 +0200 Subject: [PATCH 2/2] [registries] update networking --- .../main/java/net/ornithemc/osl/registries/impl/Constants.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/registries/src/main/java/net/ornithemc/osl/registries/impl/Constants.java b/libraries/registries/src/main/java/net/ornithemc/osl/registries/impl/Constants.java index 909bc52f8..de9c5041c 100644 --- a/libraries/registries/src/main/java/net/ornithemc/osl/registries/impl/Constants.java +++ b/libraries/registries/src/main/java/net/ornithemc/osl/registries/impl/Constants.java @@ -2,7 +2,6 @@ import net.ornithemc.osl.core.api.util.NamespacedIdentifier; import net.ornithemc.osl.networking.api.ChannelIdentifiers; -import net.ornithemc.osl.networking.api.ChannelRegistry; public final class Constants { @@ -11,6 +10,6 @@ public final class Constants { public static final String FORMAT_NBT_KEY = "format"; public static final String REGISTRIES_NBT_KEY = "registries"; - public static final NamespacedIdentifier OSL_REGISTRY_SYNC_CHANNEL = ChannelRegistry.register(ChannelIdentifiers.from("osl", "registries")); + public static final NamespacedIdentifier OSL_REGISTRY_SYNC_CHANNEL = ChannelIdentifiers.register("osl", "registries"); }