Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-12-23 23:00:35 +01:00
Merge branch 'plugin-message-event' into merged
Dieser Commit ist enthalten in:
Commit
c29b92c1bf
@ -0,0 +1,94 @@
|
||||
package com.velocitypowered.api.event.connection;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.velocitypowered.api.event.ResultedEvent;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelMessageSink;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelMessageSource;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This event is fired when a plugin message is sent to the proxy, either from a client ({@link com.velocitypowered.api.proxy.Player})
|
||||
* or a server ({@link com.velocitypowered.api.proxy.ServerConnection}).
|
||||
*/
|
||||
public class PluginMessageEvent implements ResultedEvent<PluginMessageEvent.ForwardResult> {
|
||||
private final ChannelMessageSource source;
|
||||
private final ChannelMessageSink target;
|
||||
private final ChannelIdentifier identifier;
|
||||
private final byte[] data;
|
||||
private ForwardResult result;
|
||||
|
||||
public PluginMessageEvent(ChannelMessageSource source, ChannelMessageSink target, ChannelIdentifier identifier, byte[] data) {
|
||||
this.source = Preconditions.checkNotNull(source, "source");
|
||||
this.target = Preconditions.checkNotNull(target, "target");
|
||||
this.identifier = Preconditions.checkNotNull(identifier, "identifier");
|
||||
this.data = Preconditions.checkNotNull(data, "data");
|
||||
this.result = ForwardResult.forward();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForwardResult getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResult(@NonNull ForwardResult result) {
|
||||
this.result = Preconditions.checkNotNull(result, "result");
|
||||
}
|
||||
|
||||
public ChannelMessageSource getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public ChannelMessageSink getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public ChannelIdentifier getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return Arrays.copyOf(data, data.length);
|
||||
}
|
||||
|
||||
public ByteArrayDataInput dataAsDataStream() {
|
||||
return ByteStreams.newDataInput(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* A result determining whether or not to forward this message on.
|
||||
*/
|
||||
public static class ForwardResult implements ResultedEvent.Result {
|
||||
private static final ForwardResult ALLOWED = new ForwardResult(true);
|
||||
private static final ForwardResult DENIED = new ForwardResult(false);
|
||||
|
||||
private final boolean allowed;
|
||||
|
||||
private ForwardResult(boolean b) {
|
||||
this.allowed = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowed() {
|
||||
return allowed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return allowed ? "forward to sink" : "handled message at proxy";
|
||||
}
|
||||
|
||||
public static ForwardResult forward() {
|
||||
return ALLOWED;
|
||||
}
|
||||
|
||||
public static ForwardResult handled() {
|
||||
return DENIED;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,16 +1,14 @@
|
||||
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.
|
||||
* Represents an interface to register and unregister {@link ChannelIdentifier}s for the proxy to listen on.
|
||||
*/
|
||||
public interface ChannelRegistrar {
|
||||
/**
|
||||
* Registers the specified message handler to listen for plugin messages on the specified channels.
|
||||
* @param handler the handler to register
|
||||
* Registers the specified message identifiers to listen on for the
|
||||
* @param identifiers the channel identifiers to register
|
||||
*/
|
||||
void register(MessageHandler handler, ChannelIdentifier... identifiers);
|
||||
void register(ChannelIdentifier... identifiers);
|
||||
|
||||
/**
|
||||
* Unregisters the handler for the specified channel.
|
||||
|
@ -1,15 +0,0 @@
|
||||
package com.velocitypowered.api.proxy.messages;
|
||||
|
||||
/**
|
||||
* Represents from "which side" of the proxy the plugin message came from.
|
||||
*/
|
||||
public enum ChannelSide {
|
||||
/**
|
||||
* The plugin message came from a server that a client was connected to.
|
||||
*/
|
||||
FROM_SERVER,
|
||||
/**
|
||||
* The plugin message came from the client.
|
||||
*/
|
||||
FROM_CLIENT
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package com.velocitypowered.api.proxy.messages;
|
||||
|
||||
/**
|
||||
* Represents a handler for handling plugin messages.
|
||||
*/
|
||||
public interface MessageHandler {
|
||||
/**
|
||||
* Handles an incoming plugin message.
|
||||
* @param source the source of the plugin message
|
||||
* @param side from where the plugin message originated
|
||||
* @param identifier the channel on which the message was sent
|
||||
* @param data the data inside the plugin message
|
||||
* @return a {@link ForwardStatus} indicating whether or not to forward this plugin message on
|
||||
*/
|
||||
ForwardStatus handle(ChannelMessageSource source, ChannelSide side, ChannelIdentifier identifier, byte[] data);
|
||||
|
||||
enum ForwardStatus {
|
||||
/**
|
||||
* Forwards this plugin message on to the client or server, depending on the {@link ChannelSide} it originated
|
||||
* from.
|
||||
*/
|
||||
FORWARD,
|
||||
/**
|
||||
* Discard the plugin message and do not forward it on.
|
||||
*/
|
||||
HANDLED
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
package com.velocitypowered.proxy.connection.backend;
|
||||
|
||||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||
import com.velocitypowered.api.event.player.ServerConnectedEvent;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelSide;
|
||||
import com.velocitypowered.api.proxy.messages.MessageHandler;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||
import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.connection.VelocityConstants;
|
||||
import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
|
||||
@ -86,10 +86,17 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
MessageHandler.ForwardStatus status = server.getChannelRegistrar().handlePluginMessage(connection,
|
||||
ChannelSide.FROM_SERVER, pm);
|
||||
if (status == MessageHandler.ForwardStatus.FORWARD) {
|
||||
ChannelIdentifier id = server.getChannelRegistrar().getFromId(pm.getChannel());
|
||||
if (id == null) {
|
||||
connection.getPlayer().getConnection().write(pm);
|
||||
} else {
|
||||
PluginMessageEvent event = new PluginMessageEvent(connection, connection.getPlayer(), id, pm.getData());
|
||||
server.getEventManager().fire(event)
|
||||
.thenAcceptAsync(pme -> {
|
||||
if (pme.getResult().isAllowed()) {
|
||||
connection.getPlayer().getConnection().write(pm);
|
||||
}
|
||||
}, connection.getMinecraftConnection().getChannel().eventLoop());
|
||||
}
|
||||
} else if (connection.hasCompletedJoin()) {
|
||||
// Just forward the packet on. We don't have anything to handle at this time.
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.velocitypowered.proxy.connection.client;
|
||||
|
||||
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelSide;
|
||||
import com.velocitypowered.api.proxy.messages.MessageHandler;
|
||||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||
import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.connection.VelocityConstants;
|
||||
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
||||
@ -299,10 +299,17 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
loginPluginMessages.add(packet);
|
||||
}
|
||||
} else {
|
||||
MessageHandler.ForwardStatus status = server.getChannelRegistrar().handlePluginMessage(player,
|
||||
ChannelSide.FROM_CLIENT, packet);
|
||||
if (status == MessageHandler.ForwardStatus.FORWARD) {
|
||||
player.getConnectedServer().writeIfJoined(packet);
|
||||
ChannelIdentifier id = server.getChannelRegistrar().getFromId(packet.getChannel());
|
||||
if (id == null) {
|
||||
player.getConnectedServer().getMinecraftConnection().write(packet);
|
||||
} else {
|
||||
PluginMessageEvent event = new PluginMessageEvent(player, player.getConnectedServer(), id, packet.getData());
|
||||
server.getEventManager().fire(event)
|
||||
.thenAcceptAsync(pme -> {
|
||||
if (pme.getResult().isAllowed()) {
|
||||
player.getConnectedServer().getMinecraftConnection().write(packet);
|
||||
}
|
||||
}, player.getConnectedServer().getMinecraftConnection().getChannel().eventLoop());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,6 @@ package com.velocitypowered.proxy.messages;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
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.Collection;
|
||||
import java.util.Map;
|
||||
@ -13,39 +10,20 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class VelocityChannelRegistrar implements ChannelRegistrar {
|
||||
private static final Logger logger = LogManager.getLogger(VelocityChannelRegistrar.class);
|
||||
private final Map<String, MessageHandler> handlers = new ConcurrentHashMap<>();
|
||||
private final Map<String, ChannelIdentifier> identifierMap = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void register(MessageHandler handler, ChannelIdentifier... identifiers) {
|
||||
public void register(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);
|
||||
identifierMap.put(identifier.getId(), identifier);
|
||||
}
|
||||
}
|
||||
|
||||
public MessageHandler.ForwardStatus handlePluginMessage(ChannelMessageSource source, ChannelSide side, PluginMessage message) {
|
||||
MessageHandler handler = handlers.get(message.getChannel());
|
||||
ChannelIdentifier identifier = identifierMap.get(message.getChannel());
|
||||
if (handler == null || identifier == null) {
|
||||
return MessageHandler.ForwardStatus.FORWARD;
|
||||
}
|
||||
|
||||
try {
|
||||
return handler.handle(source, side, identifier, 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) {
|
||||
for (ChannelIdentifier identifier : identifiers) {
|
||||
@ -54,7 +32,6 @@ public class VelocityChannelRegistrar implements ChannelRegistrar {
|
||||
}
|
||||
|
||||
for (ChannelIdentifier identifier : identifiers) {
|
||||
handlers.remove(identifier.getId());
|
||||
identifierMap.remove(identifier.getId());
|
||||
}
|
||||
}
|
||||
@ -73,4 +50,8 @@ public class VelocityChannelRegistrar implements ChannelRegistrar {
|
||||
public boolean registered(String id) {
|
||||
return identifierMap.containsKey(id);
|
||||
}
|
||||
|
||||
public ChannelIdentifier getFromId(String id) {
|
||||
return identifierMap.get(id);
|
||||
}
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren