chore: Implement suggested changes

This commit is contained in:
Ben Woo 2023-02-21 00:24:38 +08:00
parent a196bbd3e0
commit 4833111a2c
No known key found for this signature in database
GPG Key ID: FB2A3645536E12C8
11 changed files with 139 additions and 34 deletions

View File

@ -142,7 +142,7 @@ public class AnchorManager {
}
MVWorld mvWorld = this.plugin.getMVWorldManager().getMVWorld(ancLoc.getWorld());
if (mvWorld != null) {
if (!this.plugin.getPlayerActionChecker().hasAccessToWorld(p, mvWorld).isSuccessful()) {
if (this.plugin.getPlayerActionChecker().hasAccessToWorld(p, mvWorld).isUnsuccessful()) {
Logging.finer("Player '%s' does not have access to anchor '%s' in world '%s'.",
p.getName(), anchor, mvWorld.getName());
continue;

View File

@ -12,16 +12,36 @@ import org.jetbrains.annotations.Nullable;
* A response that have multiple results.
*/
public class ActionResponse implements ActionResult {
/**
* Create a new {@link ActionResponse} instance.
* Does not continue if one result is not successful.
*
* @return The new {@link ActionResponse} instance.
*/
public static ActionResponse create() {
return new ActionResponse();
return new ActionResponse(false);
}
/**
* Create a new {@link ActionResponse} instance.
*
* @param continueIfFail If true, the response will continue to add results even if one of the results is not successful.
* @return The new {@link ActionResponse} instance.
*/
public static ActionResponse create(boolean continueIfFail) {
return new ActionResponse(continueIfFail);
}
/**
* Create a response with a single result.
* Does not continue if one result is not successful.
*
* @param result The result.
* @return The new {@link ActionResponse} instance.
*/
public static ActionResponse of(ActionResult result) {
return new ActionResponse().addResult(result);
return new ActionResponse(false).addResult(result);
}
private final Set<ActionResult> results;
@ -29,14 +49,10 @@ public class ActionResponse implements ActionResult {
private boolean isSuccessful = true;
public ActionResponse() {
this(false);
}
/**
* @param continueIfFail If true, the response will continue to add results even if one of the results is not successful.
*/
public ActionResponse(boolean continueIfFail) {
protected ActionResponse(boolean continueIfFail) {
this.results = new HashSet<>();
this.continueIfFail = continueIfFail;
}
@ -66,7 +82,7 @@ public class ActionResponse implements ActionResult {
}
results.add(result);
if (!result.isSuccessful()) {
if (result.isUnsuccessful()) {
isSuccessful = false;
}
return this;
@ -88,6 +104,14 @@ public class ActionResponse implements ActionResult {
return isSuccessful;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isUnsuccessful() {
return !isSuccessful;
}
/**
* {@inheritDoc}
*/

View File

@ -20,6 +20,13 @@ public interface ActionResult {
*/
boolean isSuccessful();
/**
* Check if the result is unsuccessful.
*
* @return true if the result is unsuccessful.
*/
boolean isUnsuccessful();
/**
* Check if the result is in the response.
*

View File

@ -2,7 +2,42 @@ package com.onarandombox.MultiverseCore.api.action;
import org.jetbrains.annotations.Nullable;
/**
* A simple implementation of {@link ActionResult}.
*/
public class SimpleActionResult implements ActionResult {
/**
* Creates a new ActionResult that is successful with the given name.
*
* @param name The name of the result.
* @return The new ActionResult.
*/
public static ActionResult forSuccess(String name) {
return new SimpleActionResult(name, true);
}
/**
* Creates a new ActionResult that is unsuccessful with the given name.
*
* @param name The name of the result.
* @return The new ActionResult.
*/
public static ActionResult forFailure(String name) {
return new SimpleActionResult(name, false);
}
/**
* Creates a new ActionResult.
*
* @param name The name of the result.
* @param isSuccessful true if the result is successful.
* @return The new ActionResult.
*/
public static ActionResult of(String name, boolean isSuccessful) {
return new SimpleActionResult(name, isSuccessful);
}
private final String name;
private final boolean isSuccessful;
@ -12,7 +47,7 @@ public class SimpleActionResult implements ActionResult {
* @param name The name of the result.
* @param isSuccessful true if the result is successful.
*/
public SimpleActionResult(String name, boolean isSuccessful) {
protected SimpleActionResult(String name, boolean isSuccessful) {
this.name = name;
this.isSuccessful = isSuccessful;
}
@ -33,6 +68,14 @@ public class SimpleActionResult implements ActionResult {
return isSuccessful;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isUnsuccessful() {
return !isSuccessful;
}
/**
* {@inheritDoc}
*/
@ -40,4 +83,12 @@ public class SimpleActionResult implements ActionResult {
public boolean hasResult(@Nullable ActionResult result) {
return result == this;
}
@Override
public String toString() {
return "SimpleActionResult{" +
"name='" + name + '\'' +
", isSuccessful=" + isSuccessful +
'}';
}
}

View File

@ -35,10 +35,10 @@ public class CheckCommand extends MultiverseCoreCommand {
) {
issuer.sendMessage("Checking " + player + " to " + destination + "...");
//TODO More detailed output on permissions required.
if (!this.plugin.getPlayerActionChecker().canUseDestinationToTeleport(issuer.getIssuer(), player, destination).isSuccessful()) {
if (this.plugin.getPlayerActionChecker().canUseDestinationToTeleport(issuer.getIssuer(), player, destination).isUnsuccessful()) {
issuer.sendMessage("You don't have permission to use this destination.");
}
if (!this.plugin.getPlayerActionChecker().canGoToDestination(issuer.getIssuer(), player, destination).isSuccessful()) {
if (this.plugin.getPlayerActionChecker().canGoToDestination(issuer.getIssuer(), player, destination).isUnsuccessful()) {
issuer.sendMessage("You don't have permission to teleport to this destination.");
}
}

View File

@ -35,7 +35,7 @@ public class TeleportCommand extends MultiverseCoreCommand {
) {
// TODO Add warning if teleporting too many players at once.
for (Player player : players) {
if (!this.plugin.getPlayerActionChecker().canUseDestinationToTeleport(issuer.getIssuer(), player, destination).isSuccessful()) {
if (this.plugin.getPlayerActionChecker().canUseDestinationToTeleport(issuer.getIssuer(), player, destination).isUnsuccessful()) {
issuer.sendMessage("You don't have permission to use this destination.");
continue;
}

View File

@ -56,8 +56,7 @@ public class DestinationsProvider {
@Nullable String deststring
) {
return destinationMap.values().stream()
.filter(destination -> this.plugin.getPermissionsTool().hasDestinationTeleportPermission(null, issuer.getIssuer(), destination)
|| this.plugin.getPermissionsTool().hasDestinationTeleportPermission(issuer.getIssuer(), this.plugin.getServer().getConsoleSender(), destination))
.filter(destination -> hasSelfOrOtherTeleportPermission(issuer, destination))
.map(destination -> destination.suggestDestinations(issuer, deststring).stream()
.map(s -> destination.getIdentifier() + SEPARATOR + s)
.collect(Collectors.toList()))
@ -65,6 +64,11 @@ public class DestinationsProvider {
.collect(Collectors.toList());
}
private boolean hasSelfOrOtherTeleportPermission(@NotNull BukkitCommandIssuer issuer, Destination<?> destination) {
return this.plugin.getPermissionsTool().hasDestinationTeleportPermission(issuer.getIssuer(), destination)
|| this.plugin.getPermissionsTool().hasDestinationTeleportPermission(issuer.getIssuer(), this.plugin.getServer().getConsoleSender(), destination);
}
/**
* Converts a destination string to a destination object.
*

View File

@ -22,6 +22,7 @@ import com.onarandombox.MultiverseCore.event.MVRespawnEvent;
import com.onarandombox.MultiverseCore.utils.player.PlayerActionChecker;
import com.onarandombox.MultiverseCore.utils.player.checkresult.BlacklistResult;
import com.onarandombox.MultiverseCore.utils.player.checkresult.EntryFeeResult;
import com.onarandombox.MultiverseCore.utils.player.checkresult.GameModeResult;
import com.onarandombox.MultiverseCore.utils.player.checkresult.NullPlaceResult;
import com.onarandombox.MultiverseCore.utils.player.checkresult.PlayerLimitResult;
import com.onarandombox.MultiverseCore.utils.player.checkresult.WorldAccessResult;
@ -135,7 +136,7 @@ public class MVPlayerListener implements Listener {
return;
}
if (!this.plugin.getPlayerActionChecker().hasAccessToWorld(player, world).isSuccessful()) {
if (this.plugin.getPlayerActionChecker().hasAccessToWorld(player, world).isUnsuccessful()) {
player.sendMessage("[MV] - Sorry you can't be in this world anymore!");
this.sendPlayerToDefaultWorld(player);
}
@ -200,9 +201,15 @@ public class MVPlayerListener implements Listener {
MVWorld fromWorld = this.worldManager.getMVWorld(event.getFrom().getWorld());
MVWorld toWorld = this.worldManager.getMVWorld(event.getTo().getWorld());
ActionResponse actionCheckResponse = this.actionChecker.canGoFromToWorld(teleporter, teleportee, fromWorld, toWorld);
ActionResponse actionCheckResponse = this.actionChecker.canGoFromWorldToWorld(teleporter, teleportee, fromWorld, toWorld);
Logging.fine(actionCheckResponse.toString());
if (!actionCheckResponse.isSuccessful()) {
if (actionCheckResponse.hasResult(NullPlaceResult.NOT_MV_WORLD)) {
Logging.fine("Player '" + teleportee.getName() + "' is teleporting to a non-MV world. Ignoring.");
return;
}
if (actionCheckResponse.isUnsuccessful()) {
tellReason(teleporter, teleportee, fromWorld, toWorld, actionCheckResponse);
event.setCancelled(true);
return;
@ -256,9 +263,9 @@ public class MVPlayerListener implements Listener {
MVWorld fromWorld = this.worldManager.getMVWorld(event.getFrom().getWorld());
MVWorld toWorld = this.worldManager.getMVWorld(event.getTo().getWorld());
ActionResponse actionCheckResponse = this.actionChecker.canGoFromToWorld(event.getPlayer(), event.getPlayer(), fromWorld, toWorld);
ActionResponse actionCheckResponse = this.actionChecker.canGoFromWorldToWorld(event.getPlayer(), event.getPlayer(), fromWorld, toWorld);
Logging.fine(actionCheckResponse.toString());
if (!actionCheckResponse.isSuccessful()) {
if (actionCheckResponse.isUnsuccessful()) {
tellReason(event.getPlayer(), event.getPlayer(), fromWorld, toWorld, actionCheckResponse);
event.setCancelled(true);
return;
@ -297,8 +304,9 @@ public class MVPlayerListener implements Listener {
* @param world The world the player is in.
*/
public void applyGameModeAndFlight(@NotNull Player player, @NotNull MVWorld world) {
if (MVPlayerListener.this.actionChecker.canKeepGameMode(player, world).isSuccessful()) {
Logging.fine("Player: " + player.getName() + " is IMMUNE to gamemode changes!");
GameModeResult keepGameModeResult = MVPlayerListener.this.actionChecker.canKeepGameMode(player, world);
if (keepGameModeResult.isSuccessful()) {
Logging.fine("Player: " + player.getName() + " can keep their gamemode. " + "Reason: " + keepGameModeResult.getName());
return;
}
@ -309,8 +317,7 @@ public class MVPlayerListener implements Listener {
return;
}
Logging.fine("Handling gamemode for player: %s, Changing to %s", player.getName(), world.getGameMode().toString());
Logging.finest("From World: %s", player.getWorld());
Logging.finest("To World: %s", world);
Logging.finest("From World: %s --> To World: %s", player.getWorld());
player.setGameMode(world.getGameMode());
// Check if their flight mode should change
@ -347,17 +354,13 @@ public class MVPlayerListener implements Listener {
if (result.hasResult(NullPlaceResult.NULL_DESTINATION)) {
issuer.sendMessage(targetName + " cannot be teleported to because the destination is null.");
return;
}
if (result.hasResult(NullPlaceResult.NULL_LOCATION)) {
issuer.sendMessage(targetName + " cannot be teleported to because the location is null.");
return;
}
if (result.hasResult(NullPlaceResult.NULL_WORLD)) {
issuer.sendMessage(targetName + " cannot be teleported because the world is null.");
return;
}
if (result.hasResult(WorldAccessResult.NO_WORLD_ACCESS)) {
issuer.sendMessage(targetName + " cannot be teleported to because you does not have access to " + toWorld.getName());
}

View File

@ -96,6 +96,9 @@ public class PlayerActionChecker {
if (location == null) {
return ActionResponse.of(NullPlaceResult.NULL_LOCATION);
}
if (location.getWorld() == null) {
return ActionResponse.of(NullPlaceResult.NULL_WORLD);
}
MVWorld toWorld = this.worldManager.getMVWorld(location.getWorld());
return canGoToWorld(teleporter, teleportee, toWorld);
}
@ -113,7 +116,7 @@ public class PlayerActionChecker {
@NotNull MVWorld toWorld
) {
MVWorld fromWorld = this.worldManager.getMVWorld(teleportee.getWorld());
return canGoFromToWorld(teleporter, teleportee, fromWorld, toWorld);
return canGoFromWorldToWorld(teleporter, teleportee, fromWorld, toWorld);
}
/**
@ -124,13 +127,13 @@ public class PlayerActionChecker {
* @param toWorld The world to teleport to.
* @return One or more of the above action results.
*/
public ActionResponse canGoFromToWorld(@Nullable CommandSender teleporter,
@NotNull CommandSender teleportee,
@Nullable MVWorld fromWorld,
@Nullable MVWorld toWorld
public ActionResponse canGoFromWorldToWorld(@Nullable CommandSender teleporter,
@NotNull CommandSender teleportee,
@Nullable MVWorld fromWorld,
@Nullable MVWorld toWorld
) {
if (toWorld == null) {
return ActionResponse.of(NullPlaceResult.NULL_WORLD);
return ActionResponse.of(NullPlaceResult.NOT_MV_WORLD);
}
CommandSender targetSender = (teleporter == null) ? teleportee : teleporter;
@ -229,6 +232,9 @@ public class PlayerActionChecker {
* @return The action check result.
*/
public GameModeResult canKeepGameMode(@NotNull Player player, @NotNull MVWorld toWorld) {
if (player.getGameMode().equals(toWorld.getGameMode())) {
return GameModeResult.KEEP_GAME_MODE;
}
//TODO: Add config option disable game mode enforcement
return permissionsTool.hasBypassGameModeEnforcement(player, toWorld)
? GameModeResult.KEEP_GAME_MODE : GameModeResult.ENFORCE_GAME_MODE;

View File

@ -13,6 +13,11 @@ public class GameModeResult extends SimpleActionResult {
*/
public static final GameModeResult BYPASS_ENFORCE_GAME_MODE = new GameModeResult("BYPASS_ENFORCE_GAME_MODE", true);
/**
* The player's game mode is the same as the destination's game mode.
*/
public static final GameModeResult SAME_GAME_MODE = new GameModeResult("SAME_GAME_MODE", true);
/**
* The player's game mode should be enforced.
*/

View File

@ -4,6 +4,11 @@ import com.onarandombox.MultiverseCore.api.action.ActionResult;
import com.onarandombox.MultiverseCore.api.action.SimpleActionResult;
public class NullPlaceResult extends SimpleActionResult {
/**
* The target world is not a Multiverse world. So we just let the player go there without any checks
*/
public static final ActionResult NOT_MV_WORLD = new NullPlaceResult("NOT_MV_WORLD", true);
/**
* The target destination is null.
*/