Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-11-17 05:20:14 +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.
Dieser Commit ist enthalten in:
Ursprung
0ed8352012
Commit
9645fb59da
@ -11,9 +11,9 @@ import com.google.common.io.ByteArrayDataInput;
|
|||||||
import com.velocitypowered.api.event.ResultedEvent;
|
import com.velocitypowered.api.event.ResultedEvent;
|
||||||
import com.velocitypowered.api.proxy.connection.Player;
|
import com.velocitypowered.api.proxy.connection.Player;
|
||||||
import com.velocitypowered.api.proxy.connection.ServerConnection;
|
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.ChannelMessageSink;
|
||||||
import com.velocitypowered.api.proxy.messages.ChannelMessageSource;
|
import com.velocitypowered.api.proxy.messages.ChannelMessageSource;
|
||||||
|
import com.velocitypowered.api.proxy.messages.PluginChannelId;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,7 +26,7 @@ public interface PluginMessageEvent extends ResultedEvent<PluginMessageEvent.For
|
|||||||
|
|
||||||
ChannelMessageSink sink();
|
ChannelMessageSink sink();
|
||||||
|
|
||||||
ChannelIdentifier channel();
|
PluginChannelId channel();
|
||||||
|
|
||||||
byte[] rawMessage();
|
byte[] rawMessage();
|
||||||
|
|
||||||
|
@ -12,9 +12,9 @@ import com.google.common.io.ByteArrayDataInput;
|
|||||||
import com.google.common.io.ByteStreams;
|
import com.google.common.io.ByteStreams;
|
||||||
import com.velocitypowered.api.proxy.connection.Player;
|
import com.velocitypowered.api.proxy.connection.Player;
|
||||||
import com.velocitypowered.api.proxy.connection.ServerConnection;
|
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.ChannelMessageSink;
|
||||||
import com.velocitypowered.api.proxy.messages.ChannelMessageSource;
|
import com.velocitypowered.api.proxy.messages.ChannelMessageSource;
|
||||||
|
import com.velocitypowered.api.proxy.messages.PluginChannelId;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ public final class PluginMessageEventImpl implements PluginMessageEvent {
|
|||||||
|
|
||||||
private final ChannelMessageSource source;
|
private final ChannelMessageSource source;
|
||||||
private final ChannelMessageSink target;
|
private final ChannelMessageSink target;
|
||||||
private final ChannelIdentifier identifier;
|
private final PluginChannelId identifier;
|
||||||
private final byte[] data;
|
private final byte[] data;
|
||||||
private ForwardResult result;
|
private ForwardResult result;
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ public final class PluginMessageEventImpl implements PluginMessageEvent {
|
|||||||
* @param data the payload of the plugin message
|
* @param data the payload of the plugin message
|
||||||
*/
|
*/
|
||||||
public PluginMessageEventImpl(ChannelMessageSource source, ChannelMessageSink target,
|
public PluginMessageEventImpl(ChannelMessageSource source, ChannelMessageSink target,
|
||||||
ChannelIdentifier identifier, byte[] data) {
|
PluginChannelId identifier, byte[] data) {
|
||||||
this.source = Preconditions.checkNotNull(source, "source");
|
this.source = Preconditions.checkNotNull(source, "source");
|
||||||
this.target = Preconditions.checkNotNull(target, "target");
|
this.target = Preconditions.checkNotNull(target, "target");
|
||||||
this.identifier = Preconditions.checkNotNull(identifier, "identifier");
|
this.identifier = Preconditions.checkNotNull(identifier, "identifier");
|
||||||
@ -68,7 +68,7 @@ public final class PluginMessageEventImpl implements PluginMessageEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelIdentifier channel() {
|
public PluginChannelId channel() {
|
||||||
return identifier;
|
return identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
package com.velocitypowered.api.event.player;
|
package com.velocitypowered.api.event.player;
|
||||||
|
|
||||||
import com.velocitypowered.api.proxy.connection.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;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -19,5 +19,5 @@ public interface PlayerChannelRegisterEvent {
|
|||||||
|
|
||||||
Player player();
|
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.google.common.base.Preconditions;
|
||||||
import com.velocitypowered.api.proxy.connection.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;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -19,9 +19,9 @@ import java.util.List;
|
|||||||
public final class PlayerChannelRegisterEventImpl implements PlayerChannelRegisterEvent {
|
public final class PlayerChannelRegisterEventImpl implements PlayerChannelRegisterEvent {
|
||||||
|
|
||||||
private final Player player;
|
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.player = Preconditions.checkNotNull(player, "player");
|
||||||
this.channels = Preconditions.checkNotNull(channels, "channels");
|
this.channels = Preconditions.checkNotNull(channels, "channels");
|
||||||
}
|
}
|
||||||
@ -32,7 +32,7 @@ public final class PlayerChannelRegisterEventImpl implements PlayerChannelRegist
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ChannelIdentifier> channels() {
|
public List<PluginChannelId> channels() {
|
||||||
return channels;
|
return channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ public interface PluginManager {
|
|||||||
*
|
*
|
||||||
* @return the plugins
|
* @return the plugins
|
||||||
*/
|
*/
|
||||||
Collection<PluginContainer> getPlugins();
|
Collection<PluginContainer> plugins();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a plugin is loaded based on its ID.
|
* 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
|
* @param data the data to send
|
||||||
* @return whether or not the message could be sent
|
* @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;
|
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.
|
* listen on.
|
||||||
*/
|
*/
|
||||||
public interface ChannelRegistrar {
|
public interface ChannelRegistrar {
|
||||||
@ -21,12 +21,12 @@ public interface ChannelRegistrar {
|
|||||||
*
|
*
|
||||||
* @param identifiers the channel identifiers to register
|
* @param identifiers the channel identifiers to register
|
||||||
*/
|
*/
|
||||||
void register(ChannelIdentifier... identifiers);
|
void register(PluginChannelId... identifiers);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the intent to listen for the specified channel.
|
* Removes the intent to listen for the specified channel.
|
||||||
*
|
*
|
||||||
* @param identifiers the identifiers to unregister
|
* @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::"))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -277,7 +277,7 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Register the plugin main classes so that we can fire the proxy initialize event
|
// Register the plugin main classes so that we can fire the proxy initialize event
|
||||||
for (PluginContainer plugin : pluginManager.getPlugins()) {
|
for (PluginContainer plugin : pluginManager.plugins()) {
|
||||||
Optional<?> instance = plugin.instance();
|
Optional<?> instance = plugin.instance();
|
||||||
if (instance.isPresent()) {
|
if (instance.isPresent()) {
|
||||||
try {
|
try {
|
||||||
@ -289,7 +289,7 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("Loaded {} plugins", pluginManager.getPlugins().size());
|
logger.info("Loaded {} plugins", pluginManager.plugins().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bootstrap createBootstrap(@Nullable EventLoopGroup group, SocketAddress target) {
|
public Bootstrap createBootstrap(@Nullable EventLoopGroup group, SocketAddress target) {
|
||||||
|
@ -270,7 +270,7 @@ public class VelocityCommand implements SimpleCommand {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<PluginContainer> plugins = ImmutableList.copyOf(server.pluginManager().getPlugins());
|
List<PluginContainer> plugins = ImmutableList.copyOf(server.pluginManager().plugins());
|
||||||
int pluginCount = plugins.size();
|
int pluginCount = plugins.size();
|
||||||
|
|
||||||
if (pluginCount == 0) {
|
if (pluginCount == 0) {
|
||||||
|
@ -28,7 +28,7 @@ import com.velocitypowered.api.event.command.PlayerAvailableCommandsEventImpl;
|
|||||||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||||
import com.velocitypowered.api.event.connection.PluginMessageEventImpl;
|
import com.velocitypowered.api.event.connection.PluginMessageEventImpl;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.PluginChannelId;
|
||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||||
@ -160,7 +160,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChannelIdentifier id = server.channelRegistrar().getFromId(packet.getChannel());
|
PluginChannelId id = server.channelRegistrar().getFromId(packet.getChannel());
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,8 @@ package com.velocitypowered.proxy.connection.backend;
|
|||||||
|
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.api.proxy.connection.Player;
|
import com.velocitypowered.api.proxy.connection.Player;
|
||||||
import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.PairedPluginChannelId;
|
||||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.PluginChannelId;
|
||||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||||
import com.velocitypowered.api.util.UuidUtils;
|
import com.velocitypowered.api.util.UuidUtils;
|
||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
@ -40,6 +40,7 @@ import java.net.SocketAddress;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
import net.kyori.adventure.identity.Identity;
|
import net.kyori.adventure.identity.Identity;
|
||||||
|
import net.kyori.adventure.key.Key;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.serializer.ComponentSerializer;
|
import net.kyori.adventure.text.serializer.ComponentSerializer;
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
@ -50,10 +51,8 @@ import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
|||||||
+ "nothing.")
|
+ "nothing.")
|
||||||
public class BungeeCordMessageResponder {
|
public class BungeeCordMessageResponder {
|
||||||
|
|
||||||
private static final MinecraftChannelIdentifier MODERN_CHANNEL = MinecraftChannelIdentifier
|
private static final PairedPluginChannelId CHANNEL = PluginChannelId
|
||||||
.create("bungeecord", "main");
|
.withLegacy("BungeeCord", Key.key("bungeecord", "main"));
|
||||||
private static final LegacyChannelIdentifier LEGACY_CHANNEL =
|
|
||||||
new LegacyChannelIdentifier("BungeeCord");
|
|
||||||
|
|
||||||
private final VelocityServer proxy;
|
private final VelocityServer proxy;
|
||||||
private final ConnectedPlayer player;
|
private final ConnectedPlayer player;
|
||||||
@ -64,8 +63,8 @@ public class BungeeCordMessageResponder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isBungeeCordMessage(AbstractPluginMessagePacket<?> message) {
|
public static boolean isBungeeCordMessage(AbstractPluginMessagePacket<?> message) {
|
||||||
return MODERN_CHANNEL.id().equals(message.getChannel()) || LEGACY_CHANNEL.id()
|
return CHANNEL.modernChannelKey().asString().equals(message.getChannel())
|
||||||
.equals(message.getChannel());
|
|| CHANNEL.legacyChannel().equals(message.getChannel());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processConnect(ByteBufDataInput in) {
|
private void processConnect(ByteBufDataInput in) {
|
||||||
@ -293,7 +292,7 @@ public class BungeeCordMessageResponder {
|
|||||||
if (target.equals("ALL")) {
|
if (target.equals("ALL")) {
|
||||||
try {
|
try {
|
||||||
for (RegisteredServer rs : proxy.registeredServers()) {
|
for (RegisteredServer rs : proxy.registeredServers()) {
|
||||||
((VelocityRegisteredServer) rs).sendPluginMessage(LEGACY_CHANNEL,
|
((VelocityRegisteredServer) rs).sendPluginMessage(CHANNEL,
|
||||||
toForward.retainedSlice());
|
toForward.retainedSlice());
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@ -302,7 +301,7 @@ public class BungeeCordMessageResponder {
|
|||||||
} else {
|
} else {
|
||||||
Optional<RegisteredServer> server = proxy.server(target);
|
Optional<RegisteredServer> server = proxy.server(target);
|
||||||
if (server.isPresent()) {
|
if (server.isPresent()) {
|
||||||
((VelocityRegisteredServer) server.get()).sendPluginMessage(LEGACY_CHANNEL, toForward);
|
((VelocityRegisteredServer) server.get()).sendPluginMessage(CHANNEL, toForward);
|
||||||
} else {
|
} else {
|
||||||
toForward.release();
|
toForward.release();
|
||||||
}
|
}
|
||||||
@ -310,8 +309,8 @@ public class BungeeCordMessageResponder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static String getBungeeCordChannel(ProtocolVersion version) {
|
static String getBungeeCordChannel(ProtocolVersion version) {
|
||||||
return version.gte(ProtocolVersion.MINECRAFT_1_13) ? MODERN_CHANNEL.id()
|
return version.gte(ProtocolVersion.MINECRAFT_1_13) ? CHANNEL.modernChannelKey().asString()
|
||||||
: LEGACY_CHANNEL.id();
|
: CHANNEL.legacyChannel();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: this method will always release the buffer!
|
// Note: this method will always release the buffer!
|
||||||
|
@ -20,12 +20,13 @@ package com.velocitypowered.proxy.connection.backend;
|
|||||||
import static com.velocitypowered.proxy.VelocityServer.GENERAL_GSON;
|
import static com.velocitypowered.proxy.VelocityServer.GENERAL_GSON;
|
||||||
import static com.velocitypowered.proxy.connection.forge.legacy.LegacyForgeConstants.HANDSHAKE_HOSTNAME_TOKEN;
|
import static com.velocitypowered.proxy.connection.forge.legacy.LegacyForgeConstants.HANDSHAKE_HOSTNAME_TOKEN;
|
||||||
import static com.velocitypowered.proxy.network.HandlerNames.HANDLER;
|
import static com.velocitypowered.proxy.network.HandlerNames.HANDLER;
|
||||||
|
import static com.velocitypowered.proxy.network.PluginMessageUtil.channelIdForVersion;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.api.proxy.connection.ServerConnection;
|
import com.velocitypowered.api.proxy.connection.ServerConnection;
|
||||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.PluginChannelId;
|
||||||
import com.velocitypowered.api.proxy.player.ConnectionRequestBuilder;
|
import com.velocitypowered.api.proxy.player.ConnectionRequestBuilder;
|
||||||
import com.velocitypowered.api.proxy.server.ServerInfo;
|
import com.velocitypowered.api.proxy.server.ServerInfo;
|
||||||
import com.velocitypowered.api.util.GameProfile.Property;
|
import com.velocitypowered.api.util.GameProfile.Property;
|
||||||
@ -236,7 +237,7 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean sendPluginMessage(ChannelIdentifier identifier, byte[] data) {
|
public boolean sendPluginMessage(PluginChannelId identifier, byte[] data) {
|
||||||
return sendPluginMessage(identifier, Unpooled.wrappedBuffer(data));
|
return sendPluginMessage(identifier, Unpooled.wrappedBuffer(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,13 +247,14 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
|
|||||||
* @param data the data
|
* @param data the data
|
||||||
* @return whether or not the message was sent
|
* @return whether or not the message was sent
|
||||||
*/
|
*/
|
||||||
public boolean sendPluginMessage(ChannelIdentifier identifier, ByteBuf data) {
|
public boolean sendPluginMessage(PluginChannelId identifier, ByteBuf data) {
|
||||||
Preconditions.checkNotNull(identifier, "identifier");
|
Preconditions.checkNotNull(identifier, "identifier");
|
||||||
Preconditions.checkNotNull(data, "data");
|
Preconditions.checkNotNull(data, "data");
|
||||||
|
|
||||||
MinecraftConnection mc = ensureConnected();
|
MinecraftConnection mc = ensureConnected();
|
||||||
|
|
||||||
ServerboundPluginMessagePacket message = new ServerboundPluginMessagePacket(identifier.id(), data);
|
ServerboundPluginMessagePacket message = new ServerboundPluginMessagePacket(
|
||||||
|
channelIdForVersion(identifier, mc.getProtocolVersion()), data);
|
||||||
mc.write(message);
|
mc.write(message);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -32,9 +32,7 @@ import com.velocitypowered.api.event.player.PlayerChatEventImpl;
|
|||||||
import com.velocitypowered.api.event.player.PlayerResourcePackStatusEventImpl;
|
import com.velocitypowered.api.event.player.PlayerResourcePackStatusEventImpl;
|
||||||
import com.velocitypowered.api.event.player.TabCompleteEventImpl;
|
import com.velocitypowered.api.event.player.TabCompleteEventImpl;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.PluginChannelId;
|
||||||
import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier;
|
|
||||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
|
||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
import com.velocitypowered.proxy.connection.ConnectionTypes;
|
import com.velocitypowered.proxy.connection.ConnectionTypes;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||||
@ -72,6 +70,7 @@ import java.util.Queue;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import net.kyori.adventure.identity.Identity;
|
import net.kyori.adventure.identity.Identity;
|
||||||
|
import net.kyori.adventure.key.Key;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
@ -218,16 +217,21 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
} else if (PluginMessageUtil.isRegister(packet)) {
|
} else if (PluginMessageUtil.isRegister(packet)) {
|
||||||
List<String> channels = PluginMessageUtil.getChannels(packet);
|
List<String> channels = PluginMessageUtil.getChannels(packet);
|
||||||
player.getKnownChannels().addAll(channels);
|
player.getKnownChannels().addAll(channels);
|
||||||
List<ChannelIdentifier> channelIdentifiers = new ArrayList<>();
|
|
||||||
for (String channel : channels) {
|
List<PluginChannelId> pluginChannelIds = new ArrayList<>();
|
||||||
try {
|
if (player.protocolVersion().gte(MINECRAFT_1_13)) {
|
||||||
channelIdentifiers.add(MinecraftChannelIdentifier.from(channel));
|
for (String channel : channels) {
|
||||||
} catch (IllegalArgumentException e) {
|
pluginChannelIds.add(PluginChannelId.wrap(Key.key(channel)));
|
||||||
channelIdentifiers.add(new LegacyChannelIdentifier(channel));
|
}
|
||||||
|
} else {
|
||||||
|
for (String channel : channels) {
|
||||||
|
pluginChannelIds.add(PluginChannelId.withLegacy(channel,
|
||||||
|
Key.key(PluginMessageUtil.transformLegacyToModernChannel(channel))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
server.eventManager().fireAndForget(new PlayerChannelRegisterEventImpl(player,
|
server.eventManager().fireAndForget(new PlayerChannelRegisterEventImpl(player,
|
||||||
ImmutableList.copyOf(channelIdentifiers)));
|
ImmutableList.copyOf(pluginChannelIds)));
|
||||||
backendConn.write(packet.retain());
|
backendConn.write(packet.retain());
|
||||||
} else if (PluginMessageUtil.isUnregister(packet)) {
|
} else if (PluginMessageUtil.isUnregister(packet)) {
|
||||||
player.getKnownChannels().removeAll(PluginMessageUtil.getChannels(packet));
|
player.getKnownChannels().removeAll(PluginMessageUtil.getChannels(packet));
|
||||||
@ -259,7 +263,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
// appropriately.
|
// appropriately.
|
||||||
loginPluginMessages.add(packet.retain());
|
loginPluginMessages.add(packet.retain());
|
||||||
} else {
|
} else {
|
||||||
ChannelIdentifier id = server.channelRegistrar().getFromId(packet.getChannel());
|
PluginChannelId id = server.channelRegistrar().getFromId(packet.getChannel());
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
backendConn.write(packet.retain());
|
backendConn.write(packet.retain());
|
||||||
} else {
|
} else {
|
||||||
|
@ -19,6 +19,7 @@ package com.velocitypowered.proxy.connection.client;
|
|||||||
|
|
||||||
import static com.velocitypowered.api.proxy.player.ConnectionRequestBuilder.Status.ALREADY_CONNECTED;
|
import static com.velocitypowered.api.proxy.player.ConnectionRequestBuilder.Status.ALREADY_CONNECTED;
|
||||||
import static com.velocitypowered.proxy.connection.util.ConnectionRequestResults.plainResult;
|
import static com.velocitypowered.proxy.connection.util.ConnectionRequestResults.plainResult;
|
||||||
|
import static com.velocitypowered.proxy.network.PluginMessageUtil.channelIdForVersion;
|
||||||
import static java.util.concurrent.CompletableFuture.completedFuture;
|
import static java.util.concurrent.CompletableFuture.completedFuture;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
@ -42,7 +43,7 @@ import com.velocitypowered.api.permission.PermissionProvider;
|
|||||||
import com.velocitypowered.api.permission.Tristate;
|
import com.velocitypowered.api.permission.Tristate;
|
||||||
import com.velocitypowered.api.proxy.connection.Player;
|
import com.velocitypowered.api.proxy.connection.Player;
|
||||||
import com.velocitypowered.api.proxy.connection.ServerConnection;
|
import com.velocitypowered.api.proxy.connection.ServerConnection;
|
||||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.PluginChannelId;
|
||||||
import com.velocitypowered.api.proxy.player.ClientSettings;
|
import com.velocitypowered.api.proxy.player.ClientSettings;
|
||||||
import com.velocitypowered.api.proxy.player.ConnectionRequestBuilder;
|
import com.velocitypowered.api.proxy.player.ConnectionRequestBuilder;
|
||||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||||
@ -709,10 +710,11 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean sendPluginMessage(ChannelIdentifier identifier, byte[] data) {
|
public boolean sendPluginMessage(PluginChannelId identifier, byte[] data) {
|
||||||
Preconditions.checkNotNull(identifier, "identifier");
|
Preconditions.checkNotNull(identifier, "identifier");
|
||||||
Preconditions.checkNotNull(data, "data");
|
Preconditions.checkNotNull(data, "data");
|
||||||
ClientboundPluginMessagePacket message = new ClientboundPluginMessagePacket(identifier.id(),
|
ClientboundPluginMessagePacket message = new ClientboundPluginMessagePacket(
|
||||||
|
channelIdForVersion(identifier, connection.getProtocolVersion()),
|
||||||
Unpooled.wrappedBuffer(data));
|
Unpooled.wrappedBuffer(data));
|
||||||
connection.write(message);
|
connection.write(message);
|
||||||
return true;
|
return true;
|
||||||
|
@ -22,6 +22,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.api.proxy.messages.MinecraftPluginChannelId;
|
||||||
|
import com.velocitypowered.api.proxy.messages.PairedPluginChannelId;
|
||||||
|
import com.velocitypowered.api.proxy.messages.PluginChannelId;
|
||||||
import com.velocitypowered.api.util.ProxyVersion;
|
import com.velocitypowered.api.util.ProxyVersion;
|
||||||
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
@ -174,6 +177,19 @@ public final class PluginMessageUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String channelIdForVersion(PluginChannelId id, ProtocolVersion version) {
|
||||||
|
if (id instanceof MinecraftPluginChannelId) {
|
||||||
|
return ((MinecraftPluginChannelId) id).key().asString();
|
||||||
|
} else if (id instanceof PairedPluginChannelId) {
|
||||||
|
if (version.gte(ProtocolVersion.MINECRAFT_1_13)) {
|
||||||
|
return ((PairedPluginChannelId) id).modernChannelKey().asString();
|
||||||
|
} else {
|
||||||
|
return ((PairedPluginChannelId) id).legacyChannel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Unknown channel ID " + id.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
private static final Pattern INVALID_IDENTIFIER_REGEX = Pattern.compile("[^a-z0-9\\-_]*");
|
private static final Pattern INVALID_IDENTIFIER_REGEX = Pattern.compile("[^a-z0-9\\-_]*");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,9 +32,6 @@ public abstract class AbstractPluginMessagePacket<S extends AbstractPluginMessag
|
|||||||
protected static <P extends AbstractPluginMessagePacket<P>> PacketReader<P> decoder(final Factory<P> factory) {
|
protected static <P extends AbstractPluginMessagePacket<P>> PacketReader<P> decoder(final Factory<P> factory) {
|
||||||
return (buf, version) -> {
|
return (buf, version) -> {
|
||||||
String channel = ProtocolUtils.readString(buf);
|
String channel = ProtocolUtils.readString(buf);
|
||||||
if (version.gte(ProtocolVersion.MINECRAFT_1_13)) {
|
|
||||||
channel = transformLegacyToModernChannel(channel);
|
|
||||||
}
|
|
||||||
final ByteBuf data;
|
final ByteBuf data;
|
||||||
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
data = buf.readRetainedSlice(buf.readableBytes());
|
data = buf.readRetainedSlice(buf.readableBytes());
|
||||||
|
@ -201,7 +201,7 @@ public class GS4QueryHandler extends SimpleChannelInboundHandler<DatagramPacket>
|
|||||||
|
|
||||||
private List<QueryResponse.PluginInformation> getRealPluginInformation() {
|
private List<QueryResponse.PluginInformation> getRealPluginInformation() {
|
||||||
List<QueryResponse.PluginInformation> result = new ArrayList<>();
|
List<QueryResponse.PluginInformation> result = new ArrayList<>();
|
||||||
for (PluginContainer plugin : server.pluginManager().getPlugins()) {
|
for (PluginContainer plugin : server.pluginManager().plugins()) {
|
||||||
PluginDescription description = plugin.description();
|
PluginDescription description = plugin.description();
|
||||||
result.add(QueryResponse.PluginInformation.of(description.name()
|
result.add(QueryResponse.PluginInformation.of(description.name()
|
||||||
.orElse(description.id()), description.version().orElse(null)));
|
.orElse(description.id()), description.version().orElse(null)));
|
||||||
|
@ -178,7 +178,7 @@ public class VelocityPluginManager implements PluginManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<PluginContainer> getPlugins() {
|
public Collection<PluginContainer> plugins() {
|
||||||
return Collections.unmodifiableCollection(plugins.values());
|
return Collections.unmodifiableCollection(plugins.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ import com.google.common.base.Preconditions;
|
|||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.api.proxy.connection.Player;
|
import com.velocitypowered.api.proxy.connection.Player;
|
||||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.PluginChannelId;
|
||||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||||
import com.velocitypowered.api.proxy.server.ServerInfo;
|
import com.velocitypowered.api.proxy.server.ServerInfo;
|
||||||
import com.velocitypowered.api.proxy.server.ServerPing;
|
import com.velocitypowered.api.proxy.server.ServerPing;
|
||||||
@ -137,7 +137,7 @@ public class VelocityRegisteredServer implements RegisteredServer, ForwardingAud
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean sendPluginMessage(ChannelIdentifier identifier, byte[] data) {
|
public boolean sendPluginMessage(PluginChannelId identifier, byte[] data) {
|
||||||
return sendPluginMessage(identifier, Unpooled.wrappedBuffer(data));
|
return sendPluginMessage(identifier, Unpooled.wrappedBuffer(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ public class VelocityRegisteredServer implements RegisteredServer, ForwardingAud
|
|||||||
* @param data the data
|
* @param data the data
|
||||||
* @return whether or not the message was sent
|
* @return whether or not the message was sent
|
||||||
*/
|
*/
|
||||||
public boolean sendPluginMessage(ChannelIdentifier identifier, ByteBuf data) {
|
public boolean sendPluginMessage(PluginChannelId identifier, ByteBuf data) {
|
||||||
for (ConnectedPlayer player : players.values()) {
|
for (ConnectedPlayer player : players.values()) {
|
||||||
VelocityServerConnection connection = player.getConnectedServer();
|
VelocityServerConnection connection = player.getConnectedServer();
|
||||||
if (connection != null && connection.target() == this) {
|
if (connection != null && connection.target() == this) {
|
||||||
|
@ -52,8 +52,7 @@ public enum InformationUtils {
|
|||||||
* @return {@link JsonArray} containing zero or more {@link JsonObject}
|
* @return {@link JsonArray} containing zero or more {@link JsonObject}
|
||||||
*/
|
*/
|
||||||
public static JsonArray collectPluginInfo(ProxyServer proxy) {
|
public static JsonArray collectPluginInfo(ProxyServer proxy) {
|
||||||
List<PluginContainer> allPlugins = ImmutableList.copyOf(
|
List<PluginContainer> allPlugins = ImmutableList.copyOf(proxy.pluginManager().plugins());
|
||||||
proxy.pluginManager().getPlugins());
|
|
||||||
JsonArray plugins = new JsonArray();
|
JsonArray plugins = new JsonArray();
|
||||||
|
|
||||||
for (PluginContainer plugin : allPlugins) {
|
for (PluginContainer plugin : allPlugins) {
|
||||||
@ -190,7 +189,7 @@ public enum InformationUtils {
|
|||||||
if (address instanceof InetSocketAddress) {
|
if (address instanceof InetSocketAddress) {
|
||||||
InetSocketAddress iaddr = (InetSocketAddress) address;
|
InetSocketAddress iaddr = (InetSocketAddress) address;
|
||||||
if (iaddr.isUnresolved()) {
|
if (iaddr.isUnresolved()) {
|
||||||
// Greetings form Netty 4aa10db9
|
// Greetings from Netty 4aa10db9
|
||||||
info.addProperty("host", iaddr.getHostString());
|
info.addProperty("host", iaddr.getHostString());
|
||||||
} else {
|
} else {
|
||||||
info.addProperty("host", anonymizeInetAddress(iaddr.getAddress()));
|
info.addProperty("host", anonymizeInetAddress(iaddr.getAddress()));
|
||||||
|
@ -18,55 +18,58 @@
|
|||||||
package com.velocitypowered.proxy.util;
|
package com.velocitypowered.proxy.util;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
|
||||||
import com.velocitypowered.api.proxy.messages.ChannelRegistrar;
|
import com.velocitypowered.api.proxy.messages.ChannelRegistrar;
|
||||||
import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.MinecraftPluginChannelId;
|
||||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.PairedPluginChannelId;
|
||||||
import com.velocitypowered.proxy.network.PluginMessageUtil;
|
import com.velocitypowered.api.proxy.messages.PluginChannelId;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
public class VelocityChannelRegistrar implements ChannelRegistrar {
|
public class VelocityChannelRegistrar implements ChannelRegistrar {
|
||||||
|
|
||||||
private final Map<String, ChannelIdentifier> identifierMap = new ConcurrentHashMap<>();
|
private final Map<String, PluginChannelId> byLegacyId = new ConcurrentHashMap<>();
|
||||||
|
private final Map<String, PluginChannelId> byKey = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void register(ChannelIdentifier... identifiers) {
|
public void register(PluginChannelId... identifiers) {
|
||||||
for (ChannelIdentifier identifier : identifiers) {
|
for (PluginChannelId identifier : identifiers) {
|
||||||
Preconditions.checkArgument(identifier instanceof LegacyChannelIdentifier
|
Preconditions.checkArgument(identifier instanceof PairedPluginChannelId
|
||||||
|| identifier instanceof MinecraftChannelIdentifier, "identifier is unknown");
|
|| identifier instanceof MinecraftPluginChannelId, "identifier is unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ChannelIdentifier identifier : identifiers) {
|
for (PluginChannelId identifier : identifiers) {
|
||||||
if (identifier instanceof MinecraftChannelIdentifier) {
|
if (identifier instanceof MinecraftPluginChannelId) {
|
||||||
identifierMap.put(identifier.id(), identifier);
|
MinecraftPluginChannelId modern = (MinecraftPluginChannelId) identifier;
|
||||||
|
byLegacyId.put(modern.key().asString(), identifier);
|
||||||
|
byKey.put(modern.key().asString(), identifier);
|
||||||
} else {
|
} else {
|
||||||
String rewritten = PluginMessageUtil.transformLegacyToModernChannel(identifier.id());
|
PairedPluginChannelId paired = (PairedPluginChannelId) identifier;
|
||||||
identifierMap.put(identifier.id(), identifier);
|
byLegacyId.put(paired.legacyChannel(), identifier);
|
||||||
identifierMap.put(rewritten, identifier);
|
byKey.put(paired.modernChannelKey().asString(), identifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unregister(ChannelIdentifier... identifiers) {
|
public void unregister(PluginChannelId... identifiers) {
|
||||||
for (ChannelIdentifier identifier : identifiers) {
|
for (PluginChannelId identifier : identifiers) {
|
||||||
Preconditions.checkArgument(identifier instanceof LegacyChannelIdentifier
|
Preconditions.checkArgument(identifier instanceof PairedPluginChannelId
|
||||||
|| identifier instanceof MinecraftChannelIdentifier,
|
|| identifier instanceof MinecraftPluginChannelId,
|
||||||
"identifier is unknown");
|
"identifier is unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ChannelIdentifier identifier : identifiers) {
|
for (PluginChannelId identifier : identifiers) {
|
||||||
if (identifier instanceof MinecraftChannelIdentifier) {
|
if (identifier instanceof MinecraftPluginChannelId) {
|
||||||
identifierMap.remove(identifier.id());
|
MinecraftPluginChannelId modern = (MinecraftPluginChannelId) identifier;
|
||||||
|
byKey.remove(modern.key().asString(), identifier);
|
||||||
} else {
|
} else {
|
||||||
String rewritten = PluginMessageUtil.transformLegacyToModernChannel(identifier.id());
|
PairedPluginChannelId paired = (PairedPluginChannelId) identifier;
|
||||||
identifierMap.remove(identifier.id());
|
byLegacyId.remove(paired.legacyChannel(), identifier);
|
||||||
identifierMap.remove(rewritten);
|
byKey.remove(paired.modernChannelKey().asString(), identifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,11 +80,7 @@ public class VelocityChannelRegistrar implements ChannelRegistrar {
|
|||||||
* @return all legacy channel IDs
|
* @return all legacy channel IDs
|
||||||
*/
|
*/
|
||||||
public Collection<String> getLegacyChannelIds() {
|
public Collection<String> getLegacyChannelIds() {
|
||||||
Collection<String> ids = new HashSet<>();
|
return ImmutableSet.copyOf(this.byLegacyId.keySet());
|
||||||
for (ChannelIdentifier value : identifierMap.values()) {
|
|
||||||
ids.add(value.id());
|
|
||||||
}
|
|
||||||
return ids;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -90,19 +89,14 @@ public class VelocityChannelRegistrar implements ChannelRegistrar {
|
|||||||
* @return the channel IDs for Minecraft 1.13 and above
|
* @return the channel IDs for Minecraft 1.13 and above
|
||||||
*/
|
*/
|
||||||
public Collection<String> getModernChannelIds() {
|
public Collection<String> getModernChannelIds() {
|
||||||
Collection<String> ids = new HashSet<>();
|
return ImmutableSet.copyOf(this.byKey.keySet());
|
||||||
for (ChannelIdentifier value : identifierMap.values()) {
|
|
||||||
if (value instanceof MinecraftChannelIdentifier) {
|
|
||||||
ids.add(value.id());
|
|
||||||
} else {
|
|
||||||
ids.add(PluginMessageUtil.transformLegacyToModernChannel(value.id()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ids;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable ChannelIdentifier getFromId(String id) {
|
public @Nullable PluginChannelId getFromId(String id) {
|
||||||
return identifierMap.get(id);
|
if (id.indexOf(':') >= 0) {
|
||||||
|
return byKey.get(id);
|
||||||
|
}
|
||||||
|
return byLegacyId.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -138,13 +138,12 @@ public class AdventureBossBarManager implements BossBar.Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bossBarPercentChanged(@NonNull BossBar bar, float oldPercent, float newPercent) {
|
public void bossBarProgressChanged(@NonNull BossBar bar, float oldProgress, float newProgress) {
|
||||||
BossBarHolder holder = this.getHandler(bar);
|
BossBarHolder holder = this.getHandler(bar);
|
||||||
if (holder == null) {
|
if (holder == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ClientboundBossBarPacket packet = holder
|
ClientboundBossBarPacket packet = holder.createPercentUpdate(newProgress);
|
||||||
.createPercentUpdate(newPercent);
|
|
||||||
for (ConnectedPlayer player : holder.subscribers) {
|
for (ConnectedPlayer player : holder.subscribers) {
|
||||||
player.getConnection().write(packet);
|
player.getConnection().write(packet);
|
||||||
}
|
}
|
||||||
@ -170,8 +169,7 @@ public class AdventureBossBarManager implements BossBar.Listener {
|
|||||||
if (holder == null) {
|
if (holder == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ClientboundBossBarPacket packet = holder
|
ClientboundBossBarPacket packet = holder.createOverlayUpdate(newOverlay);
|
||||||
.createOverlayUpdate(newOverlay);
|
|
||||||
for (ConnectedPlayer player : holder.subscribers) {
|
for (ConnectedPlayer player : holder.subscribers) {
|
||||||
player.getConnection().write(packet);
|
player.getConnection().write(packet);
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ public class MockPluginManager implements PluginManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<PluginContainer> getPlugins() {
|
public Collection<PluginContainer> plugins() {
|
||||||
return ImmutableList.of();
|
return ImmutableList.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ public class FakePluginManager implements PluginManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull Collection<PluginContainer> getPlugins() {
|
public @NonNull Collection<PluginContainer> plugins() {
|
||||||
return ImmutableList.of(PC_A, PC_B);
|
return ImmutableList.of(PC_A, PC_B);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,23 +20,18 @@ package com.velocitypowered.proxy.util;
|
|||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.MinecraftPluginChannelId;
|
||||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.PairedPluginChannelId;
|
||||||
|
import com.velocitypowered.api.proxy.messages.PluginChannelId;
|
||||||
|
import net.kyori.adventure.key.Key;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
class VelocityChannelRegistrarTest {
|
class VelocityChannelRegistrarTest {
|
||||||
|
|
||||||
private static final MinecraftChannelIdentifier MODERN = MinecraftChannelIdentifier
|
private static final MinecraftPluginChannelId MODERN = PluginChannelId.wrap(
|
||||||
.create("velocity", "test");
|
Key.key("velocity", "moderntest"));
|
||||||
private static final LegacyChannelIdentifier SIMPLE_LEGACY =
|
private static final PairedPluginChannelId SIMPLE_LEGACY =
|
||||||
new LegacyChannelIdentifier("VelocityTest");
|
PluginChannelId.withLegacy("VelocityTest", Key.key("velocity", "test"));
|
||||||
|
|
||||||
private static final MinecraftChannelIdentifier MODERN_SPECIAL_REMAP = MinecraftChannelIdentifier
|
|
||||||
.create("bungeecord", "main");
|
|
||||||
private static final LegacyChannelIdentifier SPECIAL_REMAP_LEGACY =
|
|
||||||
new LegacyChannelIdentifier("BungeeCord");
|
|
||||||
|
|
||||||
private static final String SIMPLE_LEGACY_REMAPPED = "legacy:velocitytest";
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void register() {
|
void register() {
|
||||||
@ -45,30 +40,21 @@ class VelocityChannelRegistrarTest {
|
|||||||
|
|
||||||
// Two channels cover the modern channel (velocity:test) and the legacy-mapped channel
|
// Two channels cover the modern channel (velocity:test) and the legacy-mapped channel
|
||||||
// (legacy:velocitytest). Make sure they're what we expect.
|
// (legacy:velocitytest). Make sure they're what we expect.
|
||||||
assertEquals(ImmutableSet.of(MODERN.id(), SIMPLE_LEGACY_REMAPPED), registrar
|
assertEquals(
|
||||||
.getModernChannelIds());
|
ImmutableSet.of(MODERN.key().asString(), SIMPLE_LEGACY.modernChannelKey().asString()),
|
||||||
assertEquals(ImmutableSet.of(SIMPLE_LEGACY.id(), MODERN.id()), registrar
|
registrar.getModernChannelIds());
|
||||||
|
assertEquals(
|
||||||
|
ImmutableSet.of(SIMPLE_LEGACY.legacyChannel(), MODERN.key().asString()), registrar
|
||||||
.getLegacyChannelIds());
|
.getLegacyChannelIds());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void registerSpecialRewrite() {
|
|
||||||
VelocityChannelRegistrar registrar = new VelocityChannelRegistrar();
|
|
||||||
registrar.register(SPECIAL_REMAP_LEGACY, MODERN_SPECIAL_REMAP);
|
|
||||||
|
|
||||||
// This one, just one channel for the modern case.
|
|
||||||
assertEquals(ImmutableSet.of(MODERN_SPECIAL_REMAP.id()), registrar.getModernChannelIds());
|
|
||||||
assertEquals(ImmutableSet.of(MODERN_SPECIAL_REMAP.id(), SPECIAL_REMAP_LEGACY.id()),
|
|
||||||
registrar.getLegacyChannelIds());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void unregister() {
|
void unregister() {
|
||||||
VelocityChannelRegistrar registrar = new VelocityChannelRegistrar();
|
VelocityChannelRegistrar registrar = new VelocityChannelRegistrar();
|
||||||
registrar.register(MODERN, SIMPLE_LEGACY);
|
registrar.register(MODERN);
|
||||||
registrar.unregister(SIMPLE_LEGACY);
|
registrar.unregister(SIMPLE_LEGACY);
|
||||||
|
|
||||||
assertEquals(ImmutableSet.of(MODERN.id()), registrar.getModernChannelIds());
|
assertEquals(ImmutableSet.of(MODERN.key().asString()), registrar.getModernChannelIds());
|
||||||
assertEquals(ImmutableSet.of(MODERN.id()), registrar.getLegacyChannelIds());
|
assertEquals(ImmutableSet.of(MODERN.key().asString()), registrar.getLegacyChannelIds());
|
||||||
}
|
}
|
||||||
}
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren