3
0
Mirror von https://github.com/PaperMC/Velocity.git synchronisiert 2024-11-17 05:20:14 +01:00

Respect nodes' requirements (#350)

Dieser Commit ist enthalten in:
Ivan Pekov 2020-08-05 18:33:03 +03:00 committet von GitHub
Ursprung 76173e4145
Commit bb4bff7d34
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 4AEE18F83AFDEB23

Datei anzeigen

@ -3,6 +3,7 @@ package com.velocitypowered.proxy.connection.backend;
import static com.velocitypowered.proxy.connection.backend.BungeeCordMessageResponder.getBungeeCordChannel; import static com.velocitypowered.proxy.connection.backend.BungeeCordMessageResponder.getBungeeCordChannel;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.mojang.brigadier.builder.ArgumentBuilder;
import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.RootCommandNode; import com.mojang.brigadier.tree.RootCommandNode;
import com.velocitypowered.api.command.CommandSource; import com.velocitypowered.api.command.CommandSource;
@ -29,9 +30,12 @@ import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.handler.timeout.ReadTimeoutException; import io.netty.handler.timeout.ReadTimeoutException;
import java.util.Collection; import java.util.Collection;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class BackendPlaySessionHandler implements MinecraftSessionHandler { public class BackendPlaySessionHandler implements MinecraftSessionHandler {
private static final Logger logger = LogManager.getLogger(BackendPlaySessionHandler.class);
private final VelocityServer server; private final VelocityServer server;
private final VelocityServerConnection serverConn; private final VelocityServerConnection serverConn;
private final ClientPlaySessionHandler playerSessionHandler; private final ClientPlaySessionHandler playerSessionHandler;
@ -166,8 +170,10 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
RootCommandNode<CommandSource> rootNode = commands.getRootNode(); RootCommandNode<CommandSource> rootNode = commands.getRootNode();
if (server.getConfiguration().isAnnounceProxyCommands()) { if (server.getConfiguration().isAnnounceProxyCommands()) {
// Inject commands from the proxy. // Inject commands from the proxy.
Collection<CommandNode<CommandSource>> proxyNodes = server.getCommandManager().getDispatcher() RootCommandNode<CommandSource> dispatcherRootNode =
.getRoot().getChildren(); (RootCommandNode<CommandSource>)
filterNode(server.getCommandManager().getDispatcher().getRoot());
Collection<CommandNode<CommandSource>> proxyNodes = dispatcherRootNode.getChildren();
for (CommandNode<CommandSource> node : proxyNodes) { for (CommandNode<CommandSource> node : proxyNodes) {
rootNode.addChild(node); rootNode.addChild(node);
} }
@ -179,6 +185,50 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
return true; return true;
} }
/**
* Creates a deep copy of the provided command node, but removes any node that are not accessible
* by the player (respecting the requirement of the node).
*
* @param source source node
* @return filtered node
*/
private CommandNode<CommandSource> filterNode(CommandNode<CommandSource> source) {
CommandNode<CommandSource> dest;
if (source instanceof RootCommandNode) {
dest = new RootCommandNode<>();
} else {
if (source.getRequirement() != null) {
try {
if (!source.getRequirement().test(serverConn.getPlayer())) {
return null;
}
} catch (Throwable e) {
// swallow everything cuz plugins being plugins
logger.error(
"Requirement test for command node " + source + " encountered an exception", e);
}
}
ArgumentBuilder<CommandSource, ?> destChildBuilder = source.createBuilder();
destChildBuilder.requires((commandSource) -> true);
if (destChildBuilder.getRedirect() != null) {
destChildBuilder.redirect(filterNode(destChildBuilder.getRedirect()));
}
dest = destChildBuilder.build();
}
for (CommandNode<CommandSource> sourceChild : source.getChildren()) {
CommandNode<CommandSource> destChild = filterNode(sourceChild);
if (destChild == null) {
continue;
}
dest.addChild(destChild);
}
return dest;
}
@Override @Override
public void handleGeneric(MinecraftPacket packet) { public void handleGeneric(MinecraftPacket packet) {
if (packet instanceof PluginMessage) { if (packet instanceof PluginMessage) {