Skip to content

Commit

Permalink
Refactor permission checking with scope enum
Browse files Browse the repository at this point in the history
  • Loading branch information
benwoo1110 committed Feb 23, 2025
1 parent 95bd849 commit 61e2d00
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ void onCheckCommand(
@Syntax("<destination>")
@Description("{@@mv-core.check.destination.description}")
DestinationInstance<?, ?> destination) {
issuer.sendInfo(this.corePermissionsChecker.checkTeleportPermissions(player, player, destination)
issuer.sendInfo(this.corePermissionsChecker.checkTeleportPermission(player, player, destination)
? MVCorei18n.CHECK_HASPERMISSION
: MVCorei18n.CHECK_NOPERMISSION,
Replace.PLAYER.with(player.getName()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,61 +78,56 @@ void onSpawnTpCommand(
String[] flags) {
ParsedCommandFlags parsedFlags = parseFlags(flags);

Map<World, List<Player>> playersByWorld = Arrays.stream(players)
Map<World, List<Entity>> playersByWorld = Arrays.stream(players)
.collect(Collectors.groupingBy(Entity::getWorld));
playersByWorld.forEach((world, playerList) ->
teleportPlayersToSpawn(issuer, world, playerList, !parsedFlags.hasFlag(unsafeFlag)));
playersByWorld.forEach((world, entities) ->
teleportPlayersToSpawn(issuer, world, entities, !parsedFlags.hasFlag(unsafeFlag)));
}

private void teleportPlayersToSpawn(MVCommandIssuer issuer, World world,
List<Player> players, boolean checkSafety) {
List<Entity> entities, boolean checkSafety) {
LoadedMultiverseWorld mvWorld = worldManager.getLoadedWorld(world).getOrNull();
if (mvWorld == null) {
issuer.sendMessage("The world '" + world.getName() + "' is not a multiverse world!");
return;
}

Player selfOrOther = players.stream()
.filter(p -> !p.equals(issuer.getPlayer()))
.findFirst()
.orElse(issuer.getPlayer());
if (!permissionsChecker.checkSpawnPermission(issuer.getIssuer(), selfOrOther, mvWorld)) {
if (!permissionsChecker.checkSpawnPermission(issuer.getIssuer(), entities, mvWorld)) {
issuer.sendMessage("You do not have permission to use this command in this world!");
return;
}

if (players.size() == 1) {
handleSingleTeleport(issuer, mvWorld, players.get(0), checkSafety);
if (entities.size() == 1) {
handleSingleTeleport(issuer, mvWorld, entities.get(0), checkSafety);
} else {
handleMultiTeleport(issuer, mvWorld, players, checkSafety);
handleMultiTeleport(issuer, mvWorld, entities, checkSafety);
}
}

private void handleSingleTeleport(MVCommandIssuer issuer, LoadedMultiverseWorld mvWorld,
Player player, boolean checkSafety) {
Entity entity, boolean checkSafety) {
safetyTeleporter.to(mvWorld.getSpawnLocation())
.by(issuer)
.checkSafety(checkSafety)
.teleport(player)
.teleport(entity)
.onSuccess(() -> issuer.sendInfo(MVCorei18n.SPAWN_SUCCESS,
Replace.PLAYER.with(player.equals(issuer.getPlayer())
Replace.PLAYER.with(entity.equals(issuer.getPlayer())
? Message.of(MVCorei18n.GENERIC_YOU)
: Message.of(player.getName())),
: Message.of(entity.getName())),
Replace.WORLD.with(mvWorld.getName())))
.onFailure(failure -> issuer.sendError(MVCorei18n.SPAWN_FAILED,
Replace.PLAYER.with(player.equals(issuer.getPlayer())
Replace.PLAYER.with(entity.equals(issuer.getPlayer())
? Message.of(MVCorei18n.GENERIC_YOU)
: Message.of(player.getName())),
: Message.of(entity.getName())),
Replace.WORLD.with(mvWorld.getName()),
Replace.REASON.with(failure.getFailureMessage())));
}

private void handleMultiTeleport(MVCommandIssuer issuer, LoadedMultiverseWorld mvWorld,
List<Player> players, boolean checkSafety) {
List<Entity> entities, boolean checkSafety) {
safetyTeleporter.to(mvWorld.getSpawnLocation())
.by(issuer)
.checkSafety(checkSafety)
.teleport(players)
.teleport(entities)
.thenAccept(attempts -> {
int successCount = 0;
Map<TeleportFailureReason, Integer> failures = new EnumMap<>(TeleportFailureReason.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ void onTeleportCommand(
private void teleportSinglePlayer(MVCommandIssuer issuer, Player player,
DestinationInstance<?, ?> destination,
ParsedCommandFlags parsedFlags) {
if (!permissionsChecker.checkTeleportPermissions(issuer.getIssuer(), player, destination)) {
if (!permissionsChecker.checkTeleportPermission(issuer.getIssuer(), player, destination)) {
// TODO localize
issuer.sendMessage(player == issuer.getPlayer()
? "You do not have permission to teleport yourself!"
Expand Down Expand Up @@ -124,18 +124,9 @@ private Message getYouOrName(MVCommandIssuer issuer, Player player) {
private void teleportMultiplePlayers(MVCommandIssuer issuer, Player[] players,
DestinationInstance<?, ?> destination,
ParsedCommandFlags parsedFlags) {
var selfPlayer = Arrays.stream(players).filter(p -> p == issuer.getPlayer()).findFirst();
var otherPlayer = Arrays.stream(players).filter(p -> p != issuer.getPlayer()).findFirst();
if (selfPlayer.isPresent()
&& !permissionsChecker.checkTeleportPermissions(issuer.getIssuer(), selfPlayer.get(), destination)) {
if (!permissionsChecker.checkTeleportPermission(issuer.getIssuer(), Arrays.asList(players), destination)) {
// TODO localize
issuer.sendMessage("You do not have permission to teleport yourself!");
return;
}
if (otherPlayer.isPresent()
&& !permissionsChecker.checkTeleportPermissions(issuer.getIssuer(), otherPlayer.get(), destination)) {
// TODO localize
issuer.sendMessage("You do not have permission to teleport other players!");
issuer.sendMessage("You do not have permission to teleport all these players!");
return;
}
safetyTeleporter.to(destination)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,14 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import co.aikar.commands.BukkitCommandCompletionContext;
import co.aikar.commands.BukkitCommandIssuer;
import co.aikar.commands.CommandIssuer;
import co.aikar.commands.PaperCommandCompletions;
import co.aikar.commands.RegisteredCommand;
import co.aikar.commands.RootCommand;
import com.dumptruckman.minecraft.util.Logging;
import com.google.common.collect.Sets;
import io.vavr.control.Try;
import jakarta.inject.Inject;
import org.apache.commons.lang.Validate;
Expand Down Expand Up @@ -179,28 +176,24 @@ private boolean checkPerms(CommandIssuer issuer, RegisteredCommand<?> command) {
private Collection<String> suggestDestinations(BukkitCommandCompletionContext context) {
return Try.of(() -> context.getContextValue(Player[].class))
.map(players -> {
Player player = Arrays.stream(players)
.filter(p -> !Objects.equals(p, context.getPlayer()))
.findFirst()
.orElse(context.getPlayer());
if (player == null) {
if (players.length == 0) {
// Most likely console did not specify a player
return Collections.<String>emptyList();
}
if (context.hasConfig("othersOnly") && player.equals(context.getPlayer())) {
if (context.hasConfig("othersOnly") && (players.length == 1 && players[0].equals(context.getIssuer().getIssuer()))) {
return Collections.<String>emptyList();
}
return suggestDestinationsWithPerms(context.getIssuer().getIssuer(), player, context.getInput());
return suggestDestinationsWithPerms(context.getIssuer().getIssuer(), players, context.getInput());
})
.getOrElse(Collections.emptyList());
}

private Collection<String> suggestDestinationsWithPerms(CommandSender teleporter, Player teleportee, String deststring) {
private Collection<String> suggestDestinationsWithPerms(CommandSender teleporter, Player[] players, String deststring) {
return destinationsProvider.getDestinations().stream()
.filter(destination -> corePermissionsChecker.hasDestinationPermission(teleporter, teleportee, destination))
.flatMap(destination -> destination.suggestDestinations(teleporter, deststring).stream()
.filter(packet -> corePermissionsChecker.hasFinerDestinationPermission(
teleporter, teleportee, destination, packet.finerPermissionSuffix()))
.flatMap(destination -> destination.suggestDestinations(teleporter, deststring)
.stream()
.filter(packet -> corePermissionsChecker
.checkDestinationPacketPermission(teleporter, Arrays.asList(players), destination, packet))
.map(packet -> destination instanceof WorldDestination
? packet.destinationString()
: destination.getIdentifier() + ":" + packet.destinationString()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ public class MVCommandPermissions {

registerPermissionChecker("mvteleport", issuer -> permissionsChecker.hasAnyTeleportPermission(issuer.getIssuer()));
registerPermissionChecker("mvteleportother", issuer -> permissionsChecker.hasTeleportOtherPermission(issuer.getIssuer()));
registerPermissionChecker("mvspawn", issuer -> permissionsChecker.hasMinimumSpawnPermission(issuer.getIssuer()));
registerPermissionChecker("mvspawnother", issuer -> permissionsChecker.hasSpawnOtherPermission(issuer.getIssuer()));
registerPermissionChecker("mvspawn", issuer -> permissionsChecker.hasAnySpawnPermission(issuer.getIssuer()));
registerPermissionChecker("mvspawnother", issuer -> permissionsChecker.hasAnySpawnOtherPermission(issuer.getIssuer()));
}

/**
Expand Down
Loading

0 comments on commit 61e2d00

Please sign in to comment.