Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-12-25 07:40:13 +01:00
Merge branch 'plugin-messages'
Dieser Commit ist enthalten in:
Commit
db9f668290
@ -1,6 +1,7 @@
|
|||||||
package com.velocitypowered.api.proxy;
|
package com.velocitypowered.api.proxy;
|
||||||
|
|
||||||
import com.velocitypowered.api.command.CommandSource;
|
import com.velocitypowered.api.command.CommandSource;
|
||||||
|
import com.velocitypowered.api.proxy.messages.ChannelMessageSource;
|
||||||
import com.velocitypowered.api.server.ServerInfo;
|
import com.velocitypowered.api.server.ServerInfo;
|
||||||
import com.velocitypowered.api.util.MessagePosition;
|
import com.velocitypowered.api.util.MessagePosition;
|
||||||
import net.kyori.text.Component;
|
import net.kyori.text.Component;
|
||||||
@ -12,7 +13,7 @@ import java.util.UUID;
|
|||||||
/**
|
/**
|
||||||
* Represents a player who is connected to the proxy.
|
* Represents a player who is connected to the proxy.
|
||||||
*/
|
*/
|
||||||
public interface Player extends CommandSource, InboundConnection {
|
public interface Player extends CommandSource, InboundConnection, ChannelMessageSource {
|
||||||
/**
|
/**
|
||||||
* Returns the player's current username.
|
* Returns the player's current username.
|
||||||
* @return the username
|
* @return the username
|
||||||
|
@ -4,6 +4,7 @@ import com.velocitypowered.api.command.CommandSource;
|
|||||||
import com.velocitypowered.api.command.CommandManager;
|
import com.velocitypowered.api.command.CommandManager;
|
||||||
import com.velocitypowered.api.event.EventManager;
|
import com.velocitypowered.api.event.EventManager;
|
||||||
import com.velocitypowered.api.plugin.PluginManager;
|
import com.velocitypowered.api.plugin.PluginManager;
|
||||||
|
import com.velocitypowered.api.proxy.messages.ChannelRegistrar;
|
||||||
import com.velocitypowered.api.scheduler.Scheduler;
|
import com.velocitypowered.api.scheduler.Scheduler;
|
||||||
import com.velocitypowered.api.server.ServerInfo;
|
import com.velocitypowered.api.server.ServerInfo;
|
||||||
|
|
||||||
@ -101,4 +102,10 @@ public interface ProxyServer {
|
|||||||
* @return the scheduler instance
|
* @return the scheduler instance
|
||||||
*/
|
*/
|
||||||
Scheduler getScheduler();
|
Scheduler getScheduler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link ChannelRegistrar} instance.
|
||||||
|
* @return the channel registrar
|
||||||
|
*/
|
||||||
|
ChannelRegistrar getChannelRegistrar();
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package com.velocitypowered.api.proxy;
|
package com.velocitypowered.api.proxy;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.proxy.messages.ChannelMessageSource;
|
||||||
import com.velocitypowered.api.server.ServerInfo;
|
import com.velocitypowered.api.server.ServerInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a connection to a backend server from the proxy for a client.
|
* Represents a connection to a backend server from the proxy for a client.
|
||||||
*/
|
*/
|
||||||
public interface ServerConnection {
|
public interface ServerConnection extends ChannelMessageSource {
|
||||||
ServerInfo getServerInfo();
|
ServerInfo getServerInfo();
|
||||||
|
|
||||||
Player getPlayer();
|
Player getPlayer();
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.velocitypowered.api.proxy.messages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a kind of channel identifier.
|
||||||
|
*/
|
||||||
|
public interface ChannelIdentifier {
|
||||||
|
String getId();
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
package com.velocitypowered.api.proxy.messages;
|
||||||
|
|
||||||
|
public interface ChannelMessageSource {
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.velocitypowered.api.proxy.messages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an interface to register and unregister {@link MessageHandler} instances for handling plugin messages from
|
||||||
|
* the client or the server.
|
||||||
|
*/
|
||||||
|
public interface ChannelRegistrar {
|
||||||
|
void register(MessageHandler handler, ChannelIdentifier... identifiers);
|
||||||
|
|
||||||
|
void unregister(ChannelIdentifier... identifiers);
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.velocitypowered.api.proxy.messages;
|
||||||
|
|
||||||
|
public enum ChannelSide {
|
||||||
|
FROM_SERVER,
|
||||||
|
FROM_CLIENT
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.velocitypowered.api.proxy.messages;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
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 "LegacyChannelIdentifier{" +
|
||||||
|
"name='" + name + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(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 getId() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.velocitypowered.api.proxy.messages;
|
||||||
|
|
||||||
|
public interface MessageHandler {
|
||||||
|
ForwardStatus handle(ChannelMessageSource source, ChannelSide side, byte[] data);
|
||||||
|
|
||||||
|
enum ForwardStatus {
|
||||||
|
FORWARD,
|
||||||
|
HANDLED
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MinecraftChannelIdentifier forDefaultNamespace(String name) {
|
||||||
|
return new MinecraftChannelIdentifier("minecraft", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MinecraftChannelIdentifier create(String namespace, String name) {
|
||||||
|
Preconditions.checkArgument(!Strings.isNullOrEmpty(namespace), "namespace is null or empty");
|
||||||
|
Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "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);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
return namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "MinecraftChannelIdentifier{" +
|
||||||
|
"namespace='" + namespace + '\'' +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(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 getId() {
|
||||||
|
return namespace + ":" + name;
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,7 @@ import com.velocitypowered.proxy.config.VelocityConfiguration;
|
|||||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||||
import com.velocitypowered.proxy.connection.http.NettyHttpClient;
|
import com.velocitypowered.proxy.connection.http.NettyHttpClient;
|
||||||
import com.velocitypowered.proxy.command.VelocityCommandManager;
|
import com.velocitypowered.proxy.command.VelocityCommandManager;
|
||||||
|
import com.velocitypowered.proxy.messages.VelocityChannelRegistrar;
|
||||||
import com.velocitypowered.proxy.plugin.VelocityEventManager;
|
import com.velocitypowered.proxy.plugin.VelocityEventManager;
|
||||||
import com.velocitypowered.proxy.protocol.util.FaviconSerializer;
|
import com.velocitypowered.proxy.protocol.util.FaviconSerializer;
|
||||||
import com.velocitypowered.proxy.plugin.VelocityPluginManager;
|
import com.velocitypowered.proxy.plugin.VelocityPluginManager;
|
||||||
@ -84,6 +85,7 @@ public class VelocityServer implements ProxyServer {
|
|||||||
private Ratelimiter ipAttemptLimiter;
|
private Ratelimiter ipAttemptLimiter;
|
||||||
private VelocityEventManager eventManager;
|
private VelocityEventManager eventManager;
|
||||||
private VelocityScheduler scheduler;
|
private VelocityScheduler scheduler;
|
||||||
|
private VelocityChannelRegistrar channelRegistrar;
|
||||||
|
|
||||||
private VelocityServer() {
|
private VelocityServer() {
|
||||||
commandManager.register(new VelocityCommand(), "velocity");
|
commandManager.register(new VelocityCommand(), "velocity");
|
||||||
@ -137,6 +139,7 @@ public class VelocityServer implements ProxyServer {
|
|||||||
httpClient = new NettyHttpClient(this);
|
httpClient = new NettyHttpClient(this);
|
||||||
eventManager = new VelocityEventManager(pluginManager);
|
eventManager = new VelocityEventManager(pluginManager);
|
||||||
scheduler = new VelocityScheduler(pluginManager, Sleeper.SYSTEM);
|
scheduler = new VelocityScheduler(pluginManager, Sleeper.SYSTEM);
|
||||||
|
channelRegistrar = new VelocityChannelRegistrar();
|
||||||
loadPlugins();
|
loadPlugins();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -304,4 +307,9 @@ public class VelocityServer implements ProxyServer {
|
|||||||
public VelocityScheduler getScheduler() {
|
public VelocityScheduler getScheduler() {
|
||||||
return scheduler;
|
return scheduler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VelocityChannelRegistrar getChannelRegistrar() {
|
||||||
|
return channelRegistrar;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.velocitypowered.proxy.connection.backend;
|
package com.velocitypowered.proxy.connection.backend;
|
||||||
|
|
||||||
import com.velocitypowered.api.event.player.ServerConnectedEvent;
|
import com.velocitypowered.api.event.player.ServerConnectedEvent;
|
||||||
|
import com.velocitypowered.api.proxy.messages.ChannelSide;
|
||||||
|
import com.velocitypowered.api.proxy.messages.MessageHandler;
|
||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
|
import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
|
||||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
@ -65,7 +67,11 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
connection.getPlayer().getConnection().write(pm);
|
MessageHandler.ForwardStatus status = VelocityServer.getServer().getChannelRegistrar().handlePluginMessage(
|
||||||
|
connection, ChannelSide.FROM_SERVER, pm);
|
||||||
|
if (status == MessageHandler.ForwardStatus.FORWARD) {
|
||||||
|
connection.getPlayer().getConnection().write(pm);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Just forward the packet on. We don't have anything to handle at this time.
|
// Just forward the packet on. We don't have anything to handle at this time.
|
||||||
connection.getPlayer().getConnection().write(packet);
|
connection.getPlayer().getConnection().write(packet);
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.velocitypowered.proxy.connection.client;
|
package com.velocitypowered.proxy.connection.client;
|
||||||
|
|
||||||
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
||||||
|
import com.velocitypowered.api.proxy.messages.ChannelSide;
|
||||||
|
import com.velocitypowered.api.proxy.messages.MessageHandler;
|
||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
||||||
@ -220,8 +222,12 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We're going to forward on the original packet.
|
MessageHandler.ForwardStatus status = VelocityServer.getServer().getChannelRegistrar().handlePluginMessage(
|
||||||
player.getConnectedServer().getMinecraftConnection().write(packet);
|
player, ChannelSide.FROM_CLIENT, packet);
|
||||||
|
if (status == MessageHandler.ForwardStatus.FORWARD) {
|
||||||
|
// We're going to forward on the original packet.
|
||||||
|
player.getConnectedServer().getMinecraftConnection().write(packet);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getClientPluginMsgChannels() {
|
public Set<String> getClientPluginMsgChannels() {
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.velocitypowered.proxy.messages;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.velocitypowered.api.proxy.messages.*;
|
||||||
|
import com.velocitypowered.proxy.protocol.packet.PluginMessage;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class VelocityChannelRegistrar implements ChannelRegistrar {
|
||||||
|
private static final Logger logger = LogManager.getLogger(VelocityChannelRegistrar.class);
|
||||||
|
private final Map<String, MessageHandler> handlers = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register(MessageHandler handler, ChannelIdentifier... identifiers) {
|
||||||
|
for (ChannelIdentifier identifier : identifiers) {
|
||||||
|
Preconditions.checkArgument(identifier instanceof LegacyChannelIdentifier || identifier instanceof MinecraftChannelIdentifier,
|
||||||
|
"identifier is unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ChannelIdentifier identifier : identifiers) {
|
||||||
|
handlers.put(identifier.getId(), handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageHandler.ForwardStatus handlePluginMessage(ChannelMessageSource source, ChannelSide side, PluginMessage message) {
|
||||||
|
MessageHandler handler = handlers.get(message.getChannel());
|
||||||
|
if (handler == null) {
|
||||||
|
// Nothing we can do.
|
||||||
|
return MessageHandler.ForwardStatus.FORWARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return handler.handle(source, side, message.getData());
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.info("Unable to handle plugin message on channel {} for {}", message.getChannel(), source);
|
||||||
|
// In case of doubt, do not forward the message on.
|
||||||
|
return MessageHandler.ForwardStatus.HANDLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unregister(ChannelIdentifier... identifiers) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren