mirror of
https://github.com/PaperMC/Velocity.git
synced 2026-02-17 14:37:43 +01:00
Further improvements.
The main component here is the total revamp of the plugin channel identifier system - instead of Legacy/Modern channel IDs, you can have a modern channel or a modern channel paired with a legacy channel, which is much less confusing to work with.
This commit is contained in:
@@ -11,9 +11,9 @@ import com.google.common.io.ByteArrayDataInput;
|
||||
import com.velocitypowered.api.event.ResultedEvent;
|
||||
import com.velocitypowered.api.proxy.connection.Player;
|
||||
import com.velocitypowered.api.proxy.connection.ServerConnection;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelMessageSink;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelMessageSource;
|
||||
import com.velocitypowered.api.proxy.messages.PluginChannelId;
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
/**
|
||||
@@ -26,7 +26,7 @@ public interface PluginMessageEvent extends ResultedEvent<PluginMessageEvent.For
|
||||
|
||||
ChannelMessageSink sink();
|
||||
|
||||
ChannelIdentifier channel();
|
||||
PluginChannelId channel();
|
||||
|
||||
byte[] rawMessage();
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@ import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.velocitypowered.api.proxy.connection.Player;
|
||||
import com.velocitypowered.api.proxy.connection.ServerConnection;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelMessageSink;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelMessageSource;
|
||||
import com.velocitypowered.api.proxy.messages.PluginChannelId;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
@@ -26,7 +26,7 @@ public final class PluginMessageEventImpl implements PluginMessageEvent {
|
||||
|
||||
private final ChannelMessageSource source;
|
||||
private final ChannelMessageSink target;
|
||||
private final ChannelIdentifier identifier;
|
||||
private final PluginChannelId identifier;
|
||||
private final byte[] data;
|
||||
private ForwardResult result;
|
||||
|
||||
@@ -39,7 +39,7 @@ public final class PluginMessageEventImpl implements PluginMessageEvent {
|
||||
* @param data the payload of the plugin message
|
||||
*/
|
||||
public PluginMessageEventImpl(ChannelMessageSource source, ChannelMessageSink target,
|
||||
ChannelIdentifier identifier, byte[] data) {
|
||||
PluginChannelId identifier, byte[] data) {
|
||||
this.source = Preconditions.checkNotNull(source, "source");
|
||||
this.target = Preconditions.checkNotNull(target, "target");
|
||||
this.identifier = Preconditions.checkNotNull(identifier, "identifier");
|
||||
@@ -68,7 +68,7 @@ public final class PluginMessageEventImpl implements PluginMessageEvent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelIdentifier channel() {
|
||||
public PluginChannelId channel() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
package com.velocitypowered.api.event.player;
|
||||
|
||||
import com.velocitypowered.api.proxy.connection.Player;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||
import com.velocitypowered.api.proxy.messages.PluginChannelId;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -19,5 +19,5 @@ public interface PlayerChannelRegisterEvent {
|
||||
|
||||
Player player();
|
||||
|
||||
List<ChannelIdentifier> channels();
|
||||
List<PluginChannelId> channels();
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ package com.velocitypowered.api.event.player;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.velocitypowered.api.proxy.connection.Player;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||
import com.velocitypowered.api.proxy.messages.PluginChannelId;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -19,9 +19,9 @@ import java.util.List;
|
||||
public final class PlayerChannelRegisterEventImpl implements PlayerChannelRegisterEvent {
|
||||
|
||||
private final Player player;
|
||||
private final List<ChannelIdentifier> channels;
|
||||
private final List<PluginChannelId> channels;
|
||||
|
||||
public PlayerChannelRegisterEventImpl(Player player, List<ChannelIdentifier> channels) {
|
||||
public PlayerChannelRegisterEventImpl(Player player, List<PluginChannelId> channels) {
|
||||
this.player = Preconditions.checkNotNull(player, "player");
|
||||
this.channels = Preconditions.checkNotNull(channels, "channels");
|
||||
}
|
||||
@@ -32,7 +32,7 @@ public final class PlayerChannelRegisterEventImpl implements PlayerChannelRegist
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChannelIdentifier> channels() {
|
||||
public List<PluginChannelId> channels() {
|
||||
return channels;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ public interface PluginManager {
|
||||
*
|
||||
* @return the plugins
|
||||
*/
|
||||
Collection<PluginContainer> getPlugins();
|
||||
Collection<PluginContainer> plugins();
|
||||
|
||||
/**
|
||||
* Checks if a plugin is loaded based on its ID.
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Velocity Contributors
|
||||
*
|
||||
* The Velocity API is licensed under the terms of the MIT License. For more details,
|
||||
* reference the LICENSE file in the api top-level directory.
|
||||
*/
|
||||
|
||||
package com.velocitypowered.api.proxy.messages;
|
||||
|
||||
/**
|
||||
* Represents a channel identifier for use with plugin messaging.
|
||||
*/
|
||||
public interface ChannelIdentifier {
|
||||
|
||||
/**
|
||||
* Returns the textual representation of this identifier.
|
||||
*
|
||||
* @return the textual representation of the identifier
|
||||
*/
|
||||
String id();
|
||||
}
|
||||
@@ -19,5 +19,5 @@ public interface ChannelMessageSink {
|
||||
* @param data the data to send
|
||||
* @return whether or not the message could be sent
|
||||
*/
|
||||
boolean sendPluginMessage(ChannelIdentifier identifier, byte[] data);
|
||||
boolean sendPluginMessage(PluginChannelId identifier, byte[] data);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ package com.velocitypowered.api.proxy.messages;
|
||||
import com.velocitypowered.api.event.connection.PluginMessageEventImpl;
|
||||
|
||||
/**
|
||||
* Represents an interface to register and unregister {@link ChannelIdentifier}s for the proxy to
|
||||
* Represents an interface to register and unregister {@link PluginChannelId}s for the proxy to
|
||||
* listen on.
|
||||
*/
|
||||
public interface ChannelRegistrar {
|
||||
@@ -21,12 +21,12 @@ public interface ChannelRegistrar {
|
||||
*
|
||||
* @param identifiers the channel identifiers to register
|
||||
*/
|
||||
void register(ChannelIdentifier... identifiers);
|
||||
void register(PluginChannelId... identifiers);
|
||||
|
||||
/**
|
||||
* Removes the intent to listen for the specified channel.
|
||||
*
|
||||
* @param identifiers the identifiers to unregister
|
||||
*/
|
||||
void unregister(ChannelIdentifier... identifiers);
|
||||
void unregister(PluginChannelId... identifiers);
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Velocity Contributors
|
||||
*
|
||||
* The Velocity API is licensed under the terms of the MIT License. For more details,
|
||||
* reference the LICENSE file in the api top-level directory.
|
||||
*/
|
||||
|
||||
package com.velocitypowered.api.proxy.messages;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Strings;
|
||||
import java.util.Objects;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Reperesents a legacy channel identifier (for Minecraft 1.12 and below). For modern 1.13 plugin
|
||||
* messages, please see {@link MinecraftChannelIdentifier}. This class is immutable and safe for
|
||||
* multi-threaded use.
|
||||
*/
|
||||
public final class LegacyChannelIdentifier implements ChannelIdentifier {
|
||||
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Creates a new legacy channel identifier.
|
||||
*
|
||||
* @param name the name for the channel
|
||||
*/
|
||||
public LegacyChannelIdentifier(String name) {
|
||||
Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "provided name is empty");
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + " (legacy)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
LegacyChannelIdentifier that = (LegacyChannelIdentifier) o;
|
||||
return Objects.equals(name, that.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return this.getName();
|
||||
}
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Velocity Contributors
|
||||
*
|
||||
* The Velocity API is licensed under the terms of the MIT License. For more details,
|
||||
* reference the LICENSE file in the api top-level directory.
|
||||
*/
|
||||
|
||||
package com.velocitypowered.api.proxy.messages;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Strings;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a Minecraft 1.13+ channel identifier. This class is immutable and safe for
|
||||
* multi-threaded use.
|
||||
*/
|
||||
public final class MinecraftChannelIdentifier implements ChannelIdentifier {
|
||||
|
||||
private static final Pattern VALID_IDENTIFIER_REGEX = Pattern.compile("[a-z0-9/\\-_]*");
|
||||
|
||||
private final String namespace;
|
||||
private final String name;
|
||||
|
||||
private MinecraftChannelIdentifier(String namespace, String name) {
|
||||
this.namespace = namespace;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an identifier in the default namespace ({@code minecraft}). Plugins are strongly
|
||||
* encouraged to provide their own namespace.
|
||||
*
|
||||
* @param name the name in the default namespace to use
|
||||
* @return a new channel identifier
|
||||
*/
|
||||
public static MinecraftChannelIdentifier forDefaultNamespace(String name) {
|
||||
return new MinecraftChannelIdentifier("minecraft", name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an identifier in the specified namespace.
|
||||
*
|
||||
* @param namespace the namespace to use
|
||||
* @param name the channel name inside the specified namespace
|
||||
* @return a new channel identifier
|
||||
*/
|
||||
public static MinecraftChannelIdentifier create(String namespace, String name) {
|
||||
Preconditions.checkArgument(!Strings.isNullOrEmpty(namespace), "namespace is null or empty");
|
||||
Preconditions.checkArgument(name != null, "namespace is null or empty");
|
||||
Preconditions.checkArgument(VALID_IDENTIFIER_REGEX.matcher(namespace).matches(),
|
||||
"namespace is not valid");
|
||||
Preconditions
|
||||
.checkArgument(VALID_IDENTIFIER_REGEX.matcher(name).matches(), "name is not valid");
|
||||
return new MinecraftChannelIdentifier(namespace, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an channel identifier from the specified Minecraft identifier.
|
||||
*
|
||||
* @param identifier the Minecraft identifier
|
||||
* @return a new channel identifier
|
||||
*/
|
||||
public static MinecraftChannelIdentifier from(String identifier) {
|
||||
int colonPos = identifier.indexOf(':');
|
||||
if (colonPos == -1) {
|
||||
throw new IllegalArgumentException("Identifier does not contain a colon.");
|
||||
}
|
||||
if (colonPos + 1 == identifier.length()) {
|
||||
throw new IllegalArgumentException("Identifier is empty.");
|
||||
}
|
||||
String namespace = identifier.substring(0, colonPos);
|
||||
String name = identifier.substring(colonPos + 1);
|
||||
return create(namespace, name);
|
||||
}
|
||||
|
||||
public String getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return namespace + ":" + name + " (modern)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
MinecraftChannelIdentifier that = (MinecraftChannelIdentifier) o;
|
||||
return Objects.equals(namespace, that.namespace)
|
||||
&& Objects.equals(name, that.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(namespace, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return namespace + ":" + name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Velocity Contributors
|
||||
*
|
||||
* The Velocity API is licensed under the terms of the MIT License. For more details,
|
||||
* reference the LICENSE file in the api top-level directory.
|
||||
*/
|
||||
|
||||
package com.velocitypowered.api.proxy.messages;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Strings;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a Minecraft 1.13+ channel identifier.
|
||||
*/
|
||||
public final class MinecraftPluginChannelId implements PluginChannelId {
|
||||
|
||||
private final Key key;
|
||||
|
||||
MinecraftPluginChannelId(Key key) {
|
||||
this.key = Preconditions.checkNotNull(key, "key");
|
||||
}
|
||||
|
||||
public Key key() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MinecraftPluginChannelId that = (MinecraftPluginChannelId) o;
|
||||
|
||||
return key.equals(that.key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return key.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return key.asString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Velocity Contributors
|
||||
*
|
||||
* The Velocity API is licensed under the terms of the MIT License. For more details,
|
||||
* reference the LICENSE file in the api top-level directory.
|
||||
*/
|
||||
|
||||
package com.velocitypowered.api.proxy.messages;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Strings;
|
||||
import net.kyori.adventure.key.Key;
|
||||
|
||||
/**
|
||||
* Reperesents a legacy channel identifier (for Minecraft 1.12 and below). For modern 1.13 plugin
|
||||
* messages, please see {@link MinecraftPluginChannelId}. This class is immutable and safe for
|
||||
* multi-threaded use.
|
||||
*/
|
||||
public final class PairedPluginChannelId implements PluginChannelId {
|
||||
|
||||
private final String legacyChannel;
|
||||
private final Key modernChannelKey;
|
||||
|
||||
/**
|
||||
* Creates a new legacy channel identifier.
|
||||
*
|
||||
* @param legacyChannel the name for the legacy channel name
|
||||
* @param modernChannelKey the modern channel key to use
|
||||
*/
|
||||
PairedPluginChannelId(String legacyChannel, Key modernChannelKey) {
|
||||
Preconditions.checkArgument(!Strings.isNullOrEmpty(legacyChannel), "provided name is empty");
|
||||
this.legacyChannel = legacyChannel;
|
||||
this.modernChannelKey = Preconditions.checkNotNull(modernChannelKey, "modernChannelKey");
|
||||
}
|
||||
|
||||
public String legacyChannel() {
|
||||
return legacyChannel;
|
||||
}
|
||||
|
||||
public Key modernChannelKey() {
|
||||
return modernChannelKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return legacyChannel + "/" + modernChannelKey.asString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PairedPluginChannelId that = (PairedPluginChannelId) o;
|
||||
|
||||
if (!legacyChannel.equals(that.legacyChannel)) {
|
||||
return false;
|
||||
}
|
||||
return modernChannelKey.equals(that.modernChannelKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = legacyChannel.hashCode();
|
||||
result = 31 * result + modernChannelKey.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Velocity Contributors
|
||||
*
|
||||
* The Velocity API is licensed under the terms of the MIT License. For more details,
|
||||
* reference the LICENSE file in the api top-level directory.
|
||||
*/
|
||||
|
||||
package com.velocitypowered.api.proxy.messages;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
|
||||
/**
|
||||
* Represents a channel identifier for use with plugin messaging.
|
||||
*/
|
||||
public interface PluginChannelId {
|
||||
|
||||
/**
|
||||
* Wraps the specified Minecraft key so it can be used as a {@link PluginChannelId}.
|
||||
* If the client is connected using Minecraft 1.12.2 or earlier, use the key as the
|
||||
* channel name.
|
||||
*
|
||||
* @param key the key instance to wrap
|
||||
* @return a wrapped plugin channel ID
|
||||
*/
|
||||
static MinecraftPluginChannelId wrap(Key key) {
|
||||
return new MinecraftPluginChannelId(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the specified Minecraft key so it can be used as a {@link PluginChannelId},
|
||||
* with the specified {@code legacyChannel} for clients onnected using Minecraft 1.12.2
|
||||
* or earlier.
|
||||
*
|
||||
* @param legacyChannel the legacy channel name
|
||||
* @param modernChannelKey the key instance to wrap
|
||||
* @return a wrapped plugin channel ID
|
||||
*/
|
||||
static PairedPluginChannelId withLegacy(String legacyChannel, Key modernChannelKey) {
|
||||
return new PairedPluginChannelId(legacyChannel, modernChannelKey);
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Velocity Contributors
|
||||
*
|
||||
* The Velocity API is licensed under the terms of the MIT License. For more details,
|
||||
* reference the LICENSE file in the api top-level directory.
|
||||
*/
|
||||
|
||||
package com.velocitypowered.api.proxy.messages;
|
||||
|
||||
import static com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier.create;
|
||||
import static com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier.from;
|
||||
import static org.junit.jupiter.api.Assertions.assertAll;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class MinecraftChannelIdentifierTest {
|
||||
|
||||
@Test
|
||||
void createAllowsValidNamespaces() {
|
||||
create("minecraft", "brand");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createAllowsEmptyName() {
|
||||
create("minecraft", "");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createDisallowsNull() {
|
||||
assertAll(
|
||||
() -> assertThrows(IllegalArgumentException.class, () -> create(null, "")),
|
||||
() -> assertThrows(IllegalArgumentException.class, () -> create("", "")),
|
||||
() -> assertThrows(IllegalArgumentException.class, () -> create("minecraft", null))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void fromIdentifierIsCorrect() {
|
||||
MinecraftChannelIdentifier expected = MinecraftChannelIdentifier.create("velocity", "test");
|
||||
assertEquals(expected, MinecraftChannelIdentifier.from("velocity:test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void createAllowsSlashes() {
|
||||
create("velocity", "test/test2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fromIdentifierThrowsOnBadValues() {
|
||||
assertAll(
|
||||
() -> assertThrows(IllegalArgumentException.class, () -> from("")),
|
||||
() -> assertThrows(IllegalArgumentException.class, () -> from(":")),
|
||||
() -> assertThrows(IllegalArgumentException.class, () -> from(":a")),
|
||||
() -> assertThrows(IllegalArgumentException.class, () -> from("a:")),
|
||||
() -> assertThrows(IllegalArgumentException.class, () -> from("hello:$$$$$$")),
|
||||
() -> assertThrows(IllegalArgumentException.class, () -> from("hello::"))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user