13
0
geforkt von Mirrors/Velocity

Merge branch 'plugin-message-event' into merged

Dieser Commit ist enthalten in:
Andrew Steinborn 2018-09-19 14:52:28 -04:00
Commit c29b92c1bf
7 geänderte Dateien mit 127 neuen und 83 gelöschten Zeilen

Datei anzeigen

@ -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;
}
}
}

Datei anzeigen

@ -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.

Datei anzeigen

@ -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
}

Datei anzeigen

@ -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
}
}

Datei anzeigen

@ -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.

Datei anzeigen

@ -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());
}
}
}

Datei anzeigen

@ -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);
}
}