Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-11-17 05:20:14 +01:00
Implement optional permission check method for commands
This allows plugins to customize which players can use their commands. For players without permission, the command is effectively invisible, and the handling is passed through to the backend server.
Dieser Commit ist enthalten in:
Ursprung
8763573ae6
Commit
97e4ff91e7
@ -26,4 +26,19 @@ public interface Command {
|
|||||||
default List<String> suggest(@NonNull CommandSource source, @NonNull String[] currentArgs) {
|
default List<String> suggest(@NonNull CommandSource source, @NonNull String[] currentArgs) {
|
||||||
return ImmutableList.of();
|
return ImmutableList.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests to check if the {@code source} has permission to use this command
|
||||||
|
* with the provided {@code args}.
|
||||||
|
*
|
||||||
|
* <p>If this method returns false, the handling will be forwarded onto
|
||||||
|
* the players current server.</p>
|
||||||
|
*
|
||||||
|
* @param source the source of the command
|
||||||
|
* @param args the arguments for this command
|
||||||
|
* @return whether the source has permission
|
||||||
|
*/
|
||||||
|
default boolean hasPermission(@NonNull CommandSource source, @NonNull String[] args) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,5 +29,5 @@ public interface PermissionFunction {
|
|||||||
* @param permission the permission
|
* @param permission the permission
|
||||||
* @return the value the permission is set to
|
* @return the value the permission is set to
|
||||||
*/
|
*/
|
||||||
@NonNull Tristate getPermissionSetting(@NonNull String permission);
|
@NonNull Tristate getPermissionValue(@NonNull String permission);
|
||||||
}
|
}
|
||||||
|
@ -12,5 +12,15 @@ public interface PermissionSubject {
|
|||||||
* @param permission the permission to check for
|
* @param permission the permission to check for
|
||||||
* @return whether or not the subject has the permission
|
* @return whether or not the subject has the permission
|
||||||
*/
|
*/
|
||||||
boolean hasPermission(@NonNull String permission);
|
default boolean hasPermission(@NonNull String permission) {
|
||||||
|
return getPermissionValue(permission).asBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the subjects setting for a particular permission.
|
||||||
|
*
|
||||||
|
* @param permission the permission
|
||||||
|
* @return the value the permission is set to
|
||||||
|
*/
|
||||||
|
@NonNull Tristate getPermissionValue(@NonNull String permission);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import com.velocitypowered.api.command.CommandSource;
|
|||||||
import com.velocitypowered.api.event.EventManager;
|
import com.velocitypowered.api.event.EventManager;
|
||||||
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||||||
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
|
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
|
||||||
|
import com.velocitypowered.api.permission.Tristate;
|
||||||
import com.velocitypowered.api.plugin.PluginManager;
|
import com.velocitypowered.api.plugin.PluginManager;
|
||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import com.velocitypowered.api.proxy.ProxyServer;
|
import com.velocitypowered.api.proxy.ProxyServer;
|
||||||
@ -39,6 +40,7 @@ import net.kyori.text.serializer.ComponentSerializers;
|
|||||||
import net.kyori.text.serializer.GsonComponentSerializer;
|
import net.kyori.text.serializer.GsonComponentSerializer;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
@ -77,8 +79,8 @@ public class VelocityServer implements ProxyServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasPermission(String permission) {
|
public @NonNull Tristate getPermissionValue(@NonNull String permission) {
|
||||||
return true;
|
return Tristate.TRUE;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private Ratelimiter ipAttemptLimiter;
|
private Ratelimiter ipAttemptLimiter;
|
||||||
|
@ -3,6 +3,7 @@ package com.velocitypowered.proxy.command;
|
|||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.velocitypowered.api.command.Command;
|
import com.velocitypowered.api.command.Command;
|
||||||
import com.velocitypowered.api.command.CommandSource;
|
import com.velocitypowered.api.command.CommandSource;
|
||||||
|
import com.velocitypowered.api.permission.Tristate;
|
||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import com.velocitypowered.api.proxy.ProxyServer;
|
import com.velocitypowered.api.proxy.ProxyServer;
|
||||||
import com.velocitypowered.api.proxy.ServerConnection;
|
import com.velocitypowered.api.proxy.ServerConnection;
|
||||||
@ -12,6 +13,7 @@ import net.kyori.text.TextComponent;
|
|||||||
import net.kyori.text.event.ClickEvent;
|
import net.kyori.text.event.ClickEvent;
|
||||||
import net.kyori.text.event.HoverEvent;
|
import net.kyori.text.event.HoverEvent;
|
||||||
import net.kyori.text.format.TextColor;
|
import net.kyori.text.format.TextColor;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -88,4 +90,9 @@ public class ServerCommand implements Command {
|
|||||||
return ImmutableList.of();
|
return ImmutableList.of();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(@NonNull CommandSource source, @NonNull String[] args) {
|
||||||
|
return source.getPermissionValue("velocity.command.server") != Tristate.FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import com.velocitypowered.api.command.CommandSource;
|
|||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
import net.kyori.text.TextComponent;
|
import net.kyori.text.TextComponent;
|
||||||
import net.kyori.text.format.TextColor;
|
import net.kyori.text.format.TextColor;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
public class ShutdownCommand implements Command {
|
public class ShutdownCommand implements Command {
|
||||||
private final VelocityServer server;
|
private final VelocityServer server;
|
||||||
@ -21,4 +22,9 @@ public class ShutdownCommand implements Command {
|
|||||||
}
|
}
|
||||||
server.shutdown();
|
server.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(@NonNull CommandSource source, @NonNull String[] args) {
|
||||||
|
return source == server.getConsoleCommandSource();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,12 @@ package com.velocitypowered.proxy.command;
|
|||||||
|
|
||||||
import com.velocitypowered.api.command.Command;
|
import com.velocitypowered.api.command.Command;
|
||||||
import com.velocitypowered.api.command.CommandSource;
|
import com.velocitypowered.api.command.CommandSource;
|
||||||
|
import com.velocitypowered.api.permission.Tristate;
|
||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
import net.kyori.text.TextComponent;
|
import net.kyori.text.TextComponent;
|
||||||
import net.kyori.text.event.ClickEvent;
|
import net.kyori.text.event.ClickEvent;
|
||||||
import net.kyori.text.format.TextColor;
|
import net.kyori.text.format.TextColor;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
public class VelocityCommand implements Command {
|
public class VelocityCommand implements Command {
|
||||||
@Override
|
@Override
|
||||||
@ -37,4 +39,9 @@ public class VelocityCommand implements Command {
|
|||||||
source.sendMessage(velocityInfo);
|
source.sendMessage(velocityInfo);
|
||||||
source.sendMessage(velocityWebsite);
|
source.sendMessage(velocityWebsite);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(@NonNull CommandSource source, @NonNull String[] args) {
|
||||||
|
return source.getPermissionValue("velocity.command.info") != Tristate.FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,10 @@ public class VelocityCommandManager implements CommandManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (!command.hasPermission(source, actualArgs)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
command.execute(source, actualArgs);
|
command.execute(source, actualArgs);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -62,24 +66,29 @@ public class VelocityCommandManager implements CommandManager {
|
|||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
String command = split[0];
|
String alias = split[0];
|
||||||
if (split.length == 1) {
|
if (split.length == 1) {
|
||||||
return Optional.of(commands.keySet().stream()
|
return Optional.of(commands.entrySet().stream()
|
||||||
.filter(cmd -> cmd.regionMatches(true, 0, command, 0, command.length()))
|
.filter(ent -> ent.getKey().regionMatches(true, 0, alias, 0, alias.length()))
|
||||||
.map(cmd -> "/" + cmd)
|
.filter(ent -> ent.getValue().hasPermission(source, new String[0]))
|
||||||
|
.map(ent -> "/" + ent.getKey())
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] actualArgs = Arrays.copyOfRange(split, 1, split.length);
|
String[] actualArgs = Arrays.copyOfRange(split, 1, split.length);
|
||||||
Command executor = commands.get(command);
|
Command command = commands.get(alias.toLowerCase(Locale.ENGLISH));
|
||||||
if (executor == null) {
|
if (command == null) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return Optional.of(executor.suggest(source, actualArgs));
|
if (!command.hasPermission(source, actualArgs)) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.of(command.suggest(source, actualArgs));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Unable to invoke suggestions for command " + command + " for " + source, e);
|
throw new RuntimeException("Unable to invoke suggestions for command " + alias + " for " + source, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import com.velocitypowered.api.event.player.PlayerSettingsChangedEvent;
|
|||||||
import com.velocitypowered.api.event.player.ServerPreConnectEvent;
|
import com.velocitypowered.api.event.player.ServerPreConnectEvent;
|
||||||
import com.velocitypowered.api.permission.PermissionFunction;
|
import com.velocitypowered.api.permission.PermissionFunction;
|
||||||
import com.velocitypowered.api.permission.PermissionProvider;
|
import com.velocitypowered.api.permission.PermissionProvider;
|
||||||
|
import com.velocitypowered.api.permission.Tristate;
|
||||||
import com.velocitypowered.api.proxy.ConnectionRequestBuilder;
|
import com.velocitypowered.api.proxy.ConnectionRequestBuilder;
|
||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import com.velocitypowered.api.proxy.ServerConnection;
|
import com.velocitypowered.api.proxy.ServerConnection;
|
||||||
@ -335,8 +336,8 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasPermission(String permission) {
|
public @NonNull Tristate getPermissionValue(@NonNull String permission) {
|
||||||
return permissionFunction.getPermissionSetting(permission).asBoolean();
|
return permissionFunction.getPermissionValue(permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren