mirror of
https://github.com/SunNetservers/MiniGames.git
synced 2025-07-27 02:05:27 +02:00
Implements #42
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
package net.knarcraft.minigames.command;
|
||||
|
||||
import net.knarcraft.minigames.config.DropperConfiguration;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* An abstract arena edit command, implementing input validation
|
||||
*/
|
||||
public abstract class EditArenaCommand implements CommandExecutor {
|
||||
|
||||
private final DropperConfiguration configuration;
|
||||
|
||||
/**
|
||||
* Instantiates a new edit arena command
|
||||
*
|
||||
* @param configuration <p>The configuration to use</p>
|
||||
*/
|
||||
public EditArenaCommand(DropperConfiguration configuration) {
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the specified max players
|
||||
*
|
||||
* @param maxPlayers <p>The max players string to parse</p>
|
||||
* @return <p>The parsed value, or -1 if not parse-able</p>
|
||||
*/
|
||||
protected int parseMaxPlayers(@NotNull String maxPlayers) {
|
||||
try {
|
||||
return Integer.parseInt(maxPlayers);
|
||||
} catch (NumberFormatException exception) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes the player's specified vertical velocity
|
||||
*
|
||||
* @param velocityString <p>The string to parse into a velocity</p>
|
||||
* @return <p>The parsed velocity, defaulting to 0.5 if not parse-able</p>
|
||||
*/
|
||||
protected double sanitizeVerticalVelocity(@NotNull String velocityString) {
|
||||
// Vertical velocity should not be negative, as it would make the player go upwards. There is technically not a
|
||||
// max speed limit, but setting it too high makes the arena unplayable
|
||||
double velocity;
|
||||
try {
|
||||
velocity = Double.parseDouble(velocityString);
|
||||
} catch (NumberFormatException exception) {
|
||||
velocity = configuration.getVerticalVelocity();
|
||||
}
|
||||
|
||||
// Require at least speed of 0.001, and at most 75 blocks/s
|
||||
return Math.min(Math.max(velocity, 0.001), 75);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes the user's specified horizontal velocity
|
||||
*
|
||||
* @param velocityString <p>The string to parse into a velocity</p>
|
||||
* @return <p>The parsed velocity, defaulting to 1 if not parse-able</p>
|
||||
*/
|
||||
protected float sanitizeHorizontalVelocity(@NotNull String velocityString) {
|
||||
// Horizontal velocity is valid between -1 and 1, where negative values swaps directions
|
||||
float velocity;
|
||||
try {
|
||||
velocity = Float.parseFloat(velocityString);
|
||||
} catch (NumberFormatException exception) {
|
||||
velocity = configuration.getHorizontalVelocity();
|
||||
}
|
||||
|
||||
// If outside bonds, choose the most extreme value
|
||||
return Math.min(Math.max(0.1f, velocity), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given location string
|
||||
*
|
||||
* @param player <p>The player changing a location</p>
|
||||
* @param locationString <p>The location string to parse</p>
|
||||
* @return <p>The parsed location, or the player's location if not parse-able</p>
|
||||
*/
|
||||
protected @NotNull Location parseLocation(Player player, String locationString) {
|
||||
if ((locationString.trim() + ",").matches("([0-9]+.?[0-9]*,){3}")) {
|
||||
String[] parts = locationString.split(",");
|
||||
Location newLocation = player.getLocation().clone();
|
||||
newLocation.setX(Double.parseDouble(parts[0].trim()));
|
||||
newLocation.setY(Double.parseDouble(parts[1].trim()));
|
||||
newLocation.setZ(Double.parseDouble(parts[2].trim()));
|
||||
return newLocation;
|
||||
} else {
|
||||
return player.getLocation().clone();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given material name
|
||||
*
|
||||
* @param materialName <p>The material name to parse</p>
|
||||
* @return <p>The parsed material, or AIR if not valid</p>
|
||||
*/
|
||||
protected @NotNull Material parseMaterial(String materialName) {
|
||||
Material material = Material.matchMaterial(materialName);
|
||||
if (material == null) {
|
||||
material = Material.AIR;
|
||||
}
|
||||
return material;
|
||||
}
|
||||
|
||||
}
|
@@ -5,6 +5,7 @@ import net.knarcraft.minigames.arena.Arena;
|
||||
import net.knarcraft.minigames.arena.reward.Reward;
|
||||
import net.knarcraft.minigames.arena.reward.RewardCondition;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.util.InputValidationHelper;
|
||||
import net.knarcraft.minigames.util.RewardHelper;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
@@ -60,7 +61,7 @@ public class SetArenaRewardCommand implements CommandExecutor {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (arguments[0].equalsIgnoreCase("clear")) {
|
||||
if (InputValidationHelper.isEmptyValue(arguments[0])) {
|
||||
arena.clearRewards(condition);
|
||||
MiniGames.getInstance().getStringFormatter().displaySuccessMessage(player,
|
||||
MiniGameMessage.SUCCESS_REWARDS_CLEARED);
|
||||
|
@@ -6,6 +6,7 @@ import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.Arena;
|
||||
import net.knarcraft.minigames.arena.reward.RewardCondition;
|
||||
import net.knarcraft.minigames.arena.reward.RewardType;
|
||||
import net.knarcraft.minigames.util.InputValidationHelper;
|
||||
import net.knarcraft.minigames.util.TabCompleteHelper;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.Command;
|
||||
@@ -40,7 +41,7 @@ public class SetArenaRewardTabCompleter implements TabCompleter {
|
||||
}
|
||||
if (arguments.length >= 2) {
|
||||
// If the first argument is invalid, stop further tab completion
|
||||
if (!arguments[0].equalsIgnoreCase("add") && !arguments[0].equalsIgnoreCase("clear")) {
|
||||
if (!arguments[0].equalsIgnoreCase("add") && !InputValidationHelper.isEmptyValue(arguments[0])) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
@@ -73,8 +74,7 @@ public class SetArenaRewardTabCompleter implements TabCompleter {
|
||||
}
|
||||
if (arguments.length >= 5) {
|
||||
// If the condition is invalid, or it's the clear action, stop tab-completion
|
||||
if (RewardCondition.getFromString(arguments[3]) == null ||
|
||||
arguments[0].equalsIgnoreCase("clear")) {
|
||||
if (RewardCondition.getFromString(arguments[3]) == null || InputValidationHelper.isEmptyValue(arguments[0])) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@ import net.knarcraft.minigames.arena.dropper.DropperArena;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaGroup;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaHandler;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.util.InputValidationHelper;
|
||||
import net.knarcraft.minigames.util.StringSanitizer;
|
||||
import net.knarcraft.minigames.util.TabCompleteHelper;
|
||||
import org.bukkit.command.Command;
|
||||
@@ -46,7 +47,7 @@ public class DropperGroupSetCommand implements TabExecutor {
|
||||
}
|
||||
|
||||
DropperArenaGroup arenaGroup;
|
||||
if (groupName.equalsIgnoreCase("null") || groupName.equalsIgnoreCase("none")) {
|
||||
if (InputValidationHelper.isEmptyValue(groupName)) {
|
||||
arenaGroup = null;
|
||||
} else {
|
||||
arenaGroup = arenaHandler.getGroup(groupName);
|
||||
|
@@ -4,12 +4,10 @@ import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArena;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaEditableProperty;
|
||||
import net.knarcraft.minigames.command.EditArenaCommand;
|
||||
import net.knarcraft.minigames.config.DropperConfiguration;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -17,9 +15,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* The command for editing an existing dropper arena
|
||||
*/
|
||||
public class EditDropperArenaCommand implements CommandExecutor {
|
||||
|
||||
private final DropperConfiguration configuration;
|
||||
public class EditDropperArenaCommand extends EditArenaCommand {
|
||||
|
||||
/**
|
||||
* Instantiates a new edit arena command
|
||||
@@ -27,7 +23,7 @@ public class EditDropperArenaCommand implements CommandExecutor {
|
||||
* @param configuration <p>The configuration to use</p>
|
||||
*/
|
||||
public EditDropperArenaCommand(DropperConfiguration configuration) {
|
||||
this.configuration = configuration;
|
||||
super(configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -93,80 +89,8 @@ public class EditDropperArenaCommand implements CommandExecutor {
|
||||
case SPAWN_LOCATION -> arena.setSpawnLocation(parseLocation(player, value));
|
||||
case NAME -> arena.setName(value);
|
||||
case EXIT_LOCATION -> arena.setExitLocation(parseLocation(player, value));
|
||||
case MAX_PLAYERS -> arena.setMaxPlayers(parseMaxPlayers(value));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes the player's specified vertical velocity
|
||||
*
|
||||
* @param velocityString <p>The string to parse into a velocity</p>
|
||||
* @return <p>The parsed velocity, defaulting to 0.5 if not parse-able</p>
|
||||
*/
|
||||
private double sanitizeVerticalVelocity(@NotNull String velocityString) {
|
||||
// Vertical velocity should not be negative, as it would make the player go upwards. There is technically not a
|
||||
// max speed limit, but setting it too high makes the arena unplayable
|
||||
double velocity;
|
||||
try {
|
||||
velocity = Double.parseDouble(velocityString);
|
||||
} catch (NumberFormatException exception) {
|
||||
velocity = configuration.getVerticalVelocity();
|
||||
}
|
||||
|
||||
// Require at least speed of 0.001, and at most 75 blocks/s
|
||||
return Math.min(Math.max(velocity, 0.001), 75);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes the user's specified horizontal velocity
|
||||
*
|
||||
* @param velocityString <p>The string to parse into a velocity</p>
|
||||
* @return <p>The parsed velocity, defaulting to 1 if not parse-able</p>
|
||||
*/
|
||||
private float sanitizeHorizontalVelocity(@NotNull String velocityString) {
|
||||
// Horizontal velocity is valid between -1 and 1, where negative values swaps directions
|
||||
float velocity;
|
||||
try {
|
||||
velocity = Float.parseFloat(velocityString);
|
||||
} catch (NumberFormatException exception) {
|
||||
velocity = configuration.getHorizontalVelocity();
|
||||
}
|
||||
|
||||
// If outside bonds, choose the most extreme value
|
||||
return Math.min(Math.max(0.1f, velocity), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given location string
|
||||
*
|
||||
* @param player <p>The player changing a location</p>
|
||||
* @param locationString <p>The location string to parse</p>
|
||||
* @return <p>The parsed location, or the player's location if not parse-able</p>
|
||||
*/
|
||||
private @NotNull Location parseLocation(Player player, String locationString) {
|
||||
if ((locationString.trim() + ",").matches("([0-9]+.?[0-9]*,){3}")) {
|
||||
String[] parts = locationString.split(",");
|
||||
Location newLocation = player.getLocation().clone();
|
||||
newLocation.setX(Double.parseDouble(parts[0].trim()));
|
||||
newLocation.setY(Double.parseDouble(parts[1].trim()));
|
||||
newLocation.setZ(Double.parseDouble(parts[2].trim()));
|
||||
return newLocation;
|
||||
} else {
|
||||
return player.getLocation().clone();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given material name
|
||||
*
|
||||
* @param materialName <p>The material name to parse</p>
|
||||
* @return <p>The parsed material, or AIR if not valid</p>
|
||||
*/
|
||||
private @NotNull Material parseMaterial(String materialName) {
|
||||
Material material = Material.matchMaterial(materialName);
|
||||
if (material == null) {
|
||||
material = Material.AIR;
|
||||
}
|
||||
return material;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -60,6 +60,13 @@ public class JoinDropperArenaCommand implements CommandExecutor {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Deny joining full arenas
|
||||
int playingNow = MiniGames.getInstance().getDropperArenaPlayerRegistry().getPlayingPlayers(specifiedArena).size();
|
||||
if (specifiedArena.getMaxPlayers() > 0 && playingNow >= specifiedArena.getMaxPlayers()) {
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_JOIN_ARENA_FULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
joinArena(specifiedArena, player, arguments);
|
||||
return true;
|
||||
}
|
||||
|
@@ -4,16 +4,12 @@ import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArena;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaEditableProperty;
|
||||
import net.knarcraft.minigames.command.EditArenaCommand;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.util.InputValidationHelper;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -21,12 +17,13 @@ import java.util.List;
|
||||
/**
|
||||
* The command for editing an existing dropper arena
|
||||
*/
|
||||
public class EditParkourArenaCommand implements CommandExecutor {
|
||||
public class EditParkourArenaCommand extends EditArenaCommand {
|
||||
|
||||
/**
|
||||
* Instantiates a new edit arena command
|
||||
*/
|
||||
public EditParkourArenaCommand() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -101,43 +98,8 @@ public class EditParkourArenaCommand implements CommandExecutor {
|
||||
case CHECKPOINT_CLEAR -> arena.clearCheckpoints();
|
||||
case KILL_PLANE_BLOCKS -> arena.setKillPlaneBlocks(new HashSet<>(List.of(value.split(","))));
|
||||
case OBSTACLE_BLOCKS -> arena.setObstacleBlocks(new HashSet<>(List.of(value.split(","))));
|
||||
case MAX_PLAYERS -> arena.setMaxPlayers(parseMaxPlayers(value));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given location string
|
||||
*
|
||||
* @param player <p>The player changing a location</p>
|
||||
* @param locationString <p>The location string to parse</p>
|
||||
* @return <p>The parsed location, or the player's location if not parse-able</p>
|
||||
*/
|
||||
private @Nullable Location parseLocation(Player player, String locationString) {
|
||||
if ((locationString.trim() + ",").matches("([0-9]+.?[0-9]*,){3}")) {
|
||||
String[] parts = locationString.split(",");
|
||||
Location newLocation = player.getLocation().clone();
|
||||
newLocation.setX(Double.parseDouble(parts[0].trim()));
|
||||
newLocation.setY(Double.parseDouble(parts[1].trim()));
|
||||
newLocation.setZ(Double.parseDouble(parts[2].trim()));
|
||||
return newLocation;
|
||||
} else if (InputValidationHelper.isEmptyValue(locationString)) {
|
||||
return null;
|
||||
} else {
|
||||
return player.getLocation().clone();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given material name
|
||||
*
|
||||
* @param materialName <p>The material name to parse</p>
|
||||
* @return <p>The parsed material, or AIR if not valid</p>
|
||||
*/
|
||||
private @NotNull Material parseMaterial(String materialName) {
|
||||
Material material = Material.matchMaterial(materialName);
|
||||
if (material == null) {
|
||||
material = Material.AIR;
|
||||
}
|
||||
return material;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -54,6 +54,13 @@ public class JoinParkourArenaCommand implements CommandExecutor {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Deny joining full arenas
|
||||
int playingNow = MiniGames.getInstance().getParkourArenaPlayerRegistry().getPlayingPlayers(specifiedArena).size();
|
||||
if (specifiedArena.getMaxPlayers() > 0 && playingNow >= specifiedArena.getMaxPlayers()) {
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_JOIN_ARENA_FULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
joinArena(specifiedArena, player, arguments);
|
||||
return true;
|
||||
}
|
||||
@@ -69,7 +76,7 @@ public class JoinParkourArenaCommand implements CommandExecutor {
|
||||
// Find the specified game-mode
|
||||
ParkourArenaGameMode gameMode;
|
||||
if (arguments.length > 1) {
|
||||
gameMode = ParkourArenaGameMode.matchGamemode(arguments[1]);
|
||||
gameMode = ParkourArenaGameMode.matchGameMode(arguments[1]);
|
||||
} else {
|
||||
gameMode = ParkourArenaGameMode.DEFAULT;
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ import net.knarcraft.minigames.arena.parkour.ParkourArena;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaGroup;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaHandler;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.util.InputValidationHelper;
|
||||
import net.knarcraft.minigames.util.StringSanitizer;
|
||||
import net.knarcraft.minigames.util.TabCompleteHelper;
|
||||
import org.bukkit.command.Command;
|
||||
@@ -47,7 +48,7 @@ public class ParkourGroupSetCommand implements TabExecutor {
|
||||
}
|
||||
|
||||
ParkourArenaGroup arenaGroup;
|
||||
if (groupName.equalsIgnoreCase("null") || groupName.equalsIgnoreCase("none")) {
|
||||
if (InputValidationHelper.isEmptyValue(groupName)) {
|
||||
arenaGroup = null;
|
||||
} else {
|
||||
arenaGroup = arenaHandler.getGroup(groupName);
|
||||
|
Reference in New Issue
Block a user