Compare commits
15
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e843b0711d | ||
|
|
eddfaf7df0 | ||
|
|
d1150ab5f8 | ||
|
|
1965aecfba | ||
|
|
ce34ae44d8 | ||
|
|
f5a2d7bc47 | ||
|
|
24295025ef | ||
|
|
e3f56f6498 | ||
|
|
bd0c3cff3f | ||
|
|
7c4ab035a0 | ||
|
|
2593080f77 | ||
|
|
0d4595d511 | ||
|
|
bf820c2c27 | ||
|
|
a12718d354 | ||
|
|
62b789dff5 |
No files matched your search
@@ -174,6 +174,16 @@ public interface MVWorldManager {
|
||||
*/
|
||||
MultiverseWorld getMVWorld(String name);
|
||||
|
||||
/**
|
||||
* Returns a {@link MultiverseWorld} if the world with name given exists, and null if it does not.
|
||||
* This will search optionally for alias names.
|
||||
*
|
||||
* @param name The name or optionally the alias of the world to get.
|
||||
* @param checkAliases Indicates whether to check for world alias name.
|
||||
* @return A {@link MultiverseWorld} or null.
|
||||
*/
|
||||
MultiverseWorld getMVWorld(String name, boolean checkAliases);
|
||||
|
||||
/**
|
||||
* Returns a {@link MultiverseWorld} if it exists, and null if it does not.
|
||||
*
|
||||
@@ -183,13 +193,24 @@ public interface MVWorldManager {
|
||||
MultiverseWorld getMVWorld(World world);
|
||||
|
||||
/**
|
||||
* Checks to see if the given name is a valid {@link MultiverseWorld}.
|
||||
* Checks to see if the given name is a valid {@link MultiverseWorld}
|
||||
* Searches based on world name AND alias.
|
||||
*
|
||||
* @param name The name or alias of the world to check.
|
||||
* @return True if the world exists, false if not.
|
||||
*/
|
||||
boolean isMVWorld(String name);
|
||||
|
||||
/**
|
||||
* Checks to see if the given name is a valid {@link MultiverseWorld}.
|
||||
* Optionally searches by alias is specified.
|
||||
*
|
||||
* @param name The name or alias of the world to check.
|
||||
* @param checkAliases Indicates whether to check for world alias name.
|
||||
* @return True if the world exists, false if not.
|
||||
*/
|
||||
boolean isMVWorld(String name, boolean checkAliases);
|
||||
|
||||
/**
|
||||
* Checks to see if the given world is a valid {@link MultiverseWorld}.
|
||||
*
|
||||
@@ -314,4 +335,11 @@ public interface MVWorldManager {
|
||||
* does not exist. {@code includeLoaded} if the world exists and is loaded.
|
||||
*/
|
||||
boolean hasUnloadedWorld(String name, boolean includeLoaded);
|
||||
|
||||
/**
|
||||
* Get all the possible worlds that Multiverse has detected to be importable.
|
||||
*
|
||||
* @return A collection of world names that are deemed importable.
|
||||
*/
|
||||
Collection<String> getPotentialWorlds();
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVDestination;
|
||||
import com.onarandombox.MultiverseCore.destination.InvalidDestination;
|
||||
import com.onarandombox.MultiverseCore.utils.MVPermissions;
|
||||
import com.onarandombox.MultiverseCore.utils.PlayerFinder;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -37,7 +38,7 @@ public class CheckCommand extends MultiverseCommand {
|
||||
|
||||
@Override
|
||||
public void runCommand(CommandSender sender, List<String> args) {
|
||||
Player p = this.plugin.getServer().getPlayerExact(args.get(0));
|
||||
Player p = PlayerFinder.get(args.get(0), sender);
|
||||
if (p == null) {
|
||||
sender.sendMessage("Could not find player " + ChatColor.GREEN + args.get(0));
|
||||
sender.sendMessage("Are they online?");
|
||||
|
||||
@@ -8,12 +8,7 @@
|
||||
package com.onarandombox.MultiverseCore.commands;
|
||||
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.Core;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import com.onarandombox.MultiverseCore.commandtools.flag.CoreFlags;
|
||||
import com.onarandombox.MultiverseCore.commandtools.flag.FlagGroup;
|
||||
import com.onarandombox.MultiverseCore.commandtools.flag.FlagParseFailedException;
|
||||
import com.onarandombox.MultiverseCore.commandtools.flag.FlagResult;
|
||||
import com.pneumaticraft.commandhandler.CommandHandler;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.World.Environment;
|
||||
@@ -31,16 +26,7 @@ import java.util.List;
|
||||
* Creates a new world and loads it.
|
||||
*/
|
||||
public class CreateCommand extends MultiverseCommand {
|
||||
|
||||
private static final FlagGroup FLAG_GROUP = FlagGroup.of(
|
||||
CoreFlags.SEED,
|
||||
CoreFlags.WORLD_TYPE,
|
||||
CoreFlags.GENERATOR,
|
||||
CoreFlags.GENERATE_STRUCTURES,
|
||||
CoreFlags.SPAWN_ADJUST
|
||||
);
|
||||
|
||||
private final MVWorldManager worldManager;
|
||||
private MVWorldManager worldManager;
|
||||
|
||||
public CreateCommand(MultiverseCore plugin) {
|
||||
super(plugin);
|
||||
@@ -64,7 +50,22 @@ public class CreateCommand extends MultiverseCommand {
|
||||
@Override
|
||||
public void runCommand(CommandSender sender, List<String> args) {
|
||||
String worldName = args.get(0);
|
||||
File worldFile = new File(this.plugin.getServer().getWorldContainer(), worldName);
|
||||
String env = args.get(1);
|
||||
String seed = CommandHandler.getFlag("-s", args);
|
||||
String generator = CommandHandler.getFlag("-g", args);
|
||||
boolean allowStructures = true;
|
||||
String structureString = CommandHandler.getFlag("-a", args);
|
||||
if (structureString != null) {
|
||||
allowStructures = Boolean.parseBoolean(structureString);
|
||||
}
|
||||
String typeString = CommandHandler.getFlag("-t", args);
|
||||
boolean useSpawnAdjust = true;
|
||||
for (String s : args) {
|
||||
if (s.equalsIgnoreCase("-n")) {
|
||||
useSpawnAdjust = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.worldManager.isMVWorld(worldName)) {
|
||||
sender.sendMessage(ChatColor.RED + "Multiverse cannot create " + ChatColor.GOLD + ChatColor.UNDERLINE
|
||||
@@ -72,7 +73,6 @@ public class CreateCommand extends MultiverseCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
File worldFile = new File(this.plugin.getServer().getWorldContainer(), worldName);
|
||||
if (worldFile.exists()) {
|
||||
sender.sendMessage(ChatColor.RED + "A Folder/World already exists with this name!");
|
||||
sender.sendMessage(ChatColor.RED + "If you are confident it is a world you can import with /mvimport");
|
||||
@@ -86,28 +86,35 @@ public class CreateCommand extends MultiverseCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
FlagResult flags;
|
||||
try {
|
||||
flags = FLAG_GROUP.calculateResult(args.subList(2, args.size()).toArray(new String[0]));
|
||||
} catch (FlagParseFailedException e) {
|
||||
sender.sendMessage(String.format("%sError: %s", ChatColor.RED, e.getMessage()));
|
||||
// If they didn't specify a type, default to NORMAL
|
||||
if (typeString == null) {
|
||||
typeString = "NORMAL";
|
||||
}
|
||||
WorldType type = EnvironmentCommand.getWorldTypeFromString(typeString);
|
||||
if (type == null) {
|
||||
sender.sendMessage(ChatColor.RED + "That is not a valid World Type.");
|
||||
EnvironmentCommand.showWorldTypes(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine if the generator is valid. #918
|
||||
if (generator != null) {
|
||||
List<String> genarray = new ArrayList<String>(Arrays.asList(generator.split(":")));
|
||||
if (genarray.size() < 2) {
|
||||
// If there was only one arg specified, pad with another empty one.
|
||||
genarray.add("");
|
||||
}
|
||||
if (this.worldManager.getChunkGenerator(genarray.get(0), genarray.get(1), "test") == null) {
|
||||
// We have an invalid generator.
|
||||
sender.sendMessage("Invalid generator! '" + generator + "'. " + ChatColor.RED + "Aborting world creation.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
Command.broadcastCommandMessage(sender, "Starting creation of world '" + worldName + "'...");
|
||||
|
||||
if (this.worldManager.addWorld(
|
||||
worldName,
|
||||
environment,
|
||||
flags.getValue(CoreFlags.SEED),
|
||||
flags.getValue(CoreFlags.WORLD_TYPE),
|
||||
flags.getValue(CoreFlags.GENERATE_STRUCTURES),
|
||||
flags.getValue(CoreFlags.GENERATOR),
|
||||
flags.getValue(CoreFlags.SPAWN_ADJUST))) {
|
||||
|
||||
if (this.worldManager.addWorld(worldName, environment, seed, type, allowStructures, generator, useSpawnAdjust)) {
|
||||
Command.broadcastCommandMessage(sender, "Complete!");
|
||||
return;
|
||||
} else {
|
||||
Command.broadcastCommandMessage(sender, "FAILED.");
|
||||
}
|
||||
Command.broadcastCommandMessage(sender, "FAILED.");
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ package com.onarandombox.MultiverseCore.commands;
|
||||
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
|
||||
import com.onarandombox.MultiverseCore.utils.WorldNameChecker;
|
||||
import com.pneumaticraft.commandhandler.CommandHandler;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.World.Environment;
|
||||
@@ -18,8 +18,6 @@ import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@@ -45,55 +43,17 @@ public class ImportCommand extends MultiverseCommand {
|
||||
this.worldManager = this.plugin.getMVWorldManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* A very basic check to see if a folder has a level.dat file.
|
||||
* If it does, we can safely assume it's a world folder.
|
||||
*
|
||||
* @param worldFolder The File that may be a world.
|
||||
* @return True if it looks like a world, false if not.
|
||||
*/
|
||||
private static boolean checkIfIsWorld(File worldFolder) {
|
||||
if (worldFolder.isDirectory()) {
|
||||
File[] files = worldFolder.listFiles(new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File file, String name) {
|
||||
return name.toLowerCase().endsWith(".dat");
|
||||
}
|
||||
});
|
||||
if (files != null && files.length > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getPotentialWorlds() {
|
||||
File worldFolder = this.plugin.getServer().getWorldContainer();
|
||||
if (worldFolder == null) {
|
||||
return "";
|
||||
}
|
||||
File[] files = worldFolder.listFiles();
|
||||
String worldList = "";
|
||||
Collection<MultiverseWorld> worlds = this.worldManager.getMVWorlds();
|
||||
List<String> worldStrings = new ArrayList<String>();
|
||||
for (MultiverseWorld world : worlds) {
|
||||
worldStrings.add(world.getName());
|
||||
}
|
||||
for (String world : this.worldManager.getUnloadedWorlds()) {
|
||||
worldStrings.add(world);
|
||||
}
|
||||
private String getPotentialWorldStrings() {
|
||||
final Collection<String> potentialWorlds = this.worldManager.getPotentialWorlds();
|
||||
StringBuilder worldList = new StringBuilder();
|
||||
ChatColor currColor = ChatColor.WHITE;
|
||||
for (File file : files) {
|
||||
if (file.isDirectory() && checkIfIsWorld(file) && !worldStrings.contains(file.getName())) {
|
||||
worldList += currColor + file.getName() + " ";
|
||||
if (currColor == ChatColor.WHITE) {
|
||||
currColor = ChatColor.YELLOW;
|
||||
} else {
|
||||
currColor = ChatColor.WHITE;
|
||||
}
|
||||
}
|
||||
|
||||
for (String world : potentialWorlds) {
|
||||
worldList.append(currColor).append(world).append(' ');
|
||||
currColor = currColor == ChatColor.WHITE ? ChatColor.YELLOW : ChatColor.WHITE;
|
||||
}
|
||||
return worldList;
|
||||
|
||||
return worldList.toString();
|
||||
}
|
||||
|
||||
private String trimWorldName(String userInput) {
|
||||
@@ -106,7 +66,7 @@ public class ImportCommand extends MultiverseCommand {
|
||||
String worldName = trimWorldName(args.get(0));
|
||||
|
||||
if (worldName.toLowerCase().equals("--list") || worldName.toLowerCase().equals("-l")) {
|
||||
String worldList = this.getPotentialWorlds();
|
||||
String worldList = this.getPotentialWorldStrings();
|
||||
if (worldList.length() > 2) {
|
||||
sender.sendMessage(ChatColor.AQUA + "====[ These look like worlds ]====");
|
||||
sender.sendMessage(worldList);
|
||||
@@ -149,10 +109,10 @@ public class ImportCommand extends MultiverseCommand {
|
||||
|
||||
if (!worldFile.exists()) {
|
||||
sender.sendMessage(ChatColor.RED + "FAILED.");
|
||||
String worldList = this.getPotentialWorlds();
|
||||
String worldList = this.getPotentialWorldStrings();
|
||||
sender.sendMessage("That world folder does not exist. These look like worlds to me:");
|
||||
sender.sendMessage(worldList);
|
||||
} else if (!checkIfIsWorld(worldFile)) {
|
||||
} else if (!WorldNameChecker.isValidWorldFolder(worldFile)) {
|
||||
sender.sendMessage(ChatColor.RED + "FAILED.");
|
||||
sender.sendMessage(String.format("'%s' does not appear to be a world. It is lacking a .dat file.",
|
||||
worldName));
|
||||
|
||||
@@ -9,6 +9,7 @@ package com.onarandombox.MultiverseCore.commands;
|
||||
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
|
||||
import com.onarandombox.MultiverseCore.utils.PlayerFinder;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -50,7 +51,7 @@ public class SpawnCommand extends MultiverseCommand {
|
||||
sender.sendMessage("You don't have permission to teleport another player to spawn. (multiverse.core.spawn.other)");
|
||||
return;
|
||||
}
|
||||
Player target = this.plugin.getServer().getPlayerExact(args.get(0));
|
||||
Player target = PlayerFinder.get(args.get(0), sender);
|
||||
if (target != null) {
|
||||
target.sendMessage("Teleporting to this world's spawn...");
|
||||
spawnAccurately(target);
|
||||
|
||||
@@ -18,6 +18,7 @@ import com.onarandombox.MultiverseCore.destination.WorldDestination;
|
||||
import com.onarandombox.MultiverseCore.enums.TeleportResult;
|
||||
import com.onarandombox.MultiverseCore.event.MVTeleportEvent;
|
||||
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
|
||||
import com.onarandombox.MultiverseCore.utils.PlayerFinder;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
@@ -28,7 +29,6 @@ import org.bukkit.permissions.PermissionDefault;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Used to teleport players.
|
||||
@@ -59,7 +59,7 @@ public class TeleportCommand extends MultiverseCommand {
|
||||
String destinationName;
|
||||
|
||||
if (args.size() == 2) {
|
||||
teleportee = this.plugin.getServer().getPlayerExact(args.get(0));
|
||||
teleportee = PlayerFinder.get(args.get(0), sender);
|
||||
if (teleportee == null) {
|
||||
this.messaging.sendMessage(sender, String.format("Sorry, I couldn't find player: %s%s",
|
||||
ChatColor.GOLD, args.get(0)), false);
|
||||
@@ -75,22 +75,9 @@ public class TeleportCommand extends MultiverseCommand {
|
||||
}
|
||||
teleportee = (Player) sender;
|
||||
}
|
||||
// Special case for cannons:
|
||||
if (destinationName.matches("(?i)cannon-[\\d]+(\\.[\\d]+)?")) {
|
||||
String[] cannonSpeed = destinationName.split("-");
|
||||
try {
|
||||
double speed = Double.parseDouble(cannonSpeed[1]);
|
||||
destinationName = "ca:" + teleportee.getWorld().getName() + ":" + teleportee.getLocation().getX()
|
||||
+ "," + teleportee.getLocation().getY() + "," + teleportee.getLocation().getZ() + ":"
|
||||
+ teleportee.getLocation().getPitch() + ":" + teleportee.getLocation().getYaw() + ":" + speed;
|
||||
} catch (Exception e) {
|
||||
destinationName = "i:invalid";
|
||||
}
|
||||
|
||||
}
|
||||
DestinationFactory df = this.plugin.getDestFactory();
|
||||
MVDestination d = df.getDestination(destinationName);
|
||||
|
||||
MVDestination d = df.getPlayerAwareDestination(teleportee, destinationName);
|
||||
|
||||
MVTeleportEvent teleportEvent = new MVTeleportEvent(d, teleportee, teleporter, true);
|
||||
this.plugin.getServer().getPluginManager().callEvent(teleportEvent);
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
package com.onarandombox.MultiverseCore.commandtools.flag;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* <p>Represents a flag that can be used in commands. This works as a key value pair.</p>
|
||||
*
|
||||
* <p>Key is the {@link #identifier} and {@link #aliases} set.</p>
|
||||
* <p>Value is the {@link T} parsed based on 3 scenarios during command input:</p>
|
||||
* <ol>
|
||||
* <li>Flag completely not present. {@link #getDefaultValue()}</li>
|
||||
* <li>Flag key present but no value. {@link #getValue()}</li>
|
||||
* <li>Flag key and value present. {@link #getValue(String)}</li>
|
||||
* </ol>
|
||||
*
|
||||
* @param <T> The flag Type.
|
||||
*/
|
||||
public abstract class CommandFlag<T> {
|
||||
|
||||
protected final String name;
|
||||
protected final String identifier;
|
||||
protected final Class<T> type;
|
||||
protected final Collection<String> aliases;
|
||||
|
||||
/**
|
||||
* @param name Readable name for the flag.
|
||||
* @param identifier Unique key to identify the flag in command arguments.
|
||||
* @param type The type of value this flag represents.
|
||||
*/
|
||||
protected CommandFlag(@NotNull String name,
|
||||
@NotNull String identifier,
|
||||
@NotNull Class<T> type) {
|
||||
|
||||
this.name = name;
|
||||
this.identifier = identifier;
|
||||
this.type = type;
|
||||
this.aliases = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets name of the Command Flag.
|
||||
*
|
||||
* @return The Command Flag name.
|
||||
*/
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets identifier of the Command Flag.
|
||||
*
|
||||
* @return The Command Flag identifier.
|
||||
*/
|
||||
@NotNull
|
||||
public String getIdentifier() {
|
||||
return this.identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets {@link T} Type of the Command Flag.
|
||||
*
|
||||
* @return The Command Flag type.
|
||||
*/
|
||||
@NotNull
|
||||
public Class<T> getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the alternative key identifiers set for this Command Flag.
|
||||
*
|
||||
* @return Collection of aliases.
|
||||
*/
|
||||
@NotNull
|
||||
public Collection<String> getAliases() {
|
||||
return this.aliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add alternative key identifiers for this Command Flag.
|
||||
*
|
||||
* @param aliases Alias(es) to be added.
|
||||
* @return A {@link CommandFlag}.
|
||||
*/
|
||||
public CommandFlag<T> addAliases(String...aliases) {
|
||||
Collections.addAll(this.aliases, aliases);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tab-complete suggestion for this Command Flag values.
|
||||
*
|
||||
* @return Collection of suggested values available.
|
||||
*/
|
||||
public abstract Collection<String> suggestValue();
|
||||
|
||||
/**
|
||||
* When this Command Flag can get value by a user input.
|
||||
*
|
||||
* @return The {@link T} value.
|
||||
*/
|
||||
public abstract T getValue(@NotNull String input) throws FlagParseFailedException;
|
||||
|
||||
/**
|
||||
* When this Command Flag user input value is null/not present.
|
||||
*
|
||||
* @return The {@link T} value.
|
||||
*/
|
||||
public T getValue() throws FlagParseFailedException {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* When this Command Flag is not present in command input.
|
||||
*
|
||||
* @return The {@link T} value.
|
||||
*/
|
||||
public T getDefaultValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CommandFlag{" +
|
||||
"name='" + name + '\'' +
|
||||
", identifier='" + identifier + '\'' +
|
||||
", type=" + type +
|
||||
", aliases=" + aliases +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,217 +0,0 @@
|
||||
package com.onarandombox.MultiverseCore.commandtools.flag;
|
||||
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.utils.webpaste.PasteServiceType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.WorldType;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CoreFlags {
|
||||
|
||||
private static MultiverseCore multiverse;
|
||||
|
||||
public static void setCoreInstance(MultiverseCore plugin) {
|
||||
multiverse = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag for custom seed.
|
||||
*/
|
||||
public static final CommandFlag<String> SEED = new RequiredCommandFlag<String>
|
||||
("Seed", "--seed", String.class) {
|
||||
@Override
|
||||
public Collection<String> suggestValue() {
|
||||
return Collections.singleton(String.valueOf(new Random().nextLong()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(@NotNull String input) throws FlagParseFailedException {
|
||||
return input;
|
||||
}
|
||||
}.addAliases("-s");
|
||||
|
||||
/**
|
||||
* Flag for custom seed. No value means random seed.
|
||||
*/
|
||||
public static final CommandFlag<String> RANDOM_SEED = new OptionalCommandFlag<String>
|
||||
("Seed", "--seed", String.class) {
|
||||
@Override
|
||||
public Collection<String> suggestValue() {
|
||||
return Collections.singletonList(String.valueOf(new Random().nextLong()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(@NotNull String input) throws FlagParseFailedException {
|
||||
return input;
|
||||
}
|
||||
}.addAliases("-s");
|
||||
|
||||
/**
|
||||
* Flag for world type used.
|
||||
*/
|
||||
public static final CommandFlag<WorldType> WORLD_TYPE = new RequiredCommandFlag<WorldType>
|
||||
("WorldType", "--type", WorldType.class) {
|
||||
|
||||
private final Map<String, String> typeAlias = new HashMap<String, String>(4){{
|
||||
put("normal", "NORMAL");
|
||||
put("flat", "FLAT");
|
||||
put("largebiomes", "LARGE_BIOMES");
|
||||
put("amplified", "AMPLIFIED");
|
||||
}};
|
||||
|
||||
@Override
|
||||
public Collection<String> suggestValue() {
|
||||
return typeAlias.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldType getValue(@NotNull String input) throws FlagParseFailedException {
|
||||
String typeName = typeAlias.getOrDefault(input, input);
|
||||
try {
|
||||
return WorldType.valueOf(input.toUpperCase());
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
throw new FlagParseFailedException("'%s' is not a valid World Type. See /mv env for available World Types.", input);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldType getDefaultValue() {
|
||||
return WorldType.NORMAL;
|
||||
}
|
||||
}.addAliases("-t");
|
||||
|
||||
/**
|
||||
* Flag for world generator.
|
||||
*/
|
||||
public static final CommandFlag<String> GENERATOR = new RequiredCommandFlag<String>
|
||||
("Generator", "--gen", String.class) {
|
||||
@Override
|
||||
public Collection<String> suggestValue() {
|
||||
return Arrays.stream(Bukkit.getServer().getPluginManager().getPlugins())
|
||||
.filter(Plugin::isEnabled)
|
||||
.filter(plugin -> multiverse.getUnsafeCallWrapper().wrap(
|
||||
() -> plugin.getDefaultWorldGenerator("world", ""),
|
||||
plugin.getName(),
|
||||
"Get generator"
|
||||
) != null)
|
||||
.map(plugin -> plugin.getDescription().getName())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(@NotNull String input) throws FlagParseFailedException {
|
||||
String[] genArray = input.split(":");
|
||||
String generator = genArray[0];
|
||||
String generatorId = (genArray.length > 1) ? genArray[1] : "";
|
||||
try {
|
||||
if (multiverse.getMVWorldManager().getChunkGenerator(generator, generatorId, "test") == null) {
|
||||
throw new Exception();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new FlagParseFailedException("Invalid generator string '%s'. See /mv gens for available generators.", input);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
}.addAliases("-g");
|
||||
|
||||
/**
|
||||
* Flag to toggle if world should generate structures.
|
||||
*/
|
||||
public static final CommandFlag<Boolean> GENERATE_STRUCTURES = new RequiredCommandFlag<Boolean>
|
||||
("GenerateStructures", "--structures", Boolean.class) {
|
||||
@Override
|
||||
public Collection<String> suggestValue() {
|
||||
return Arrays.asList("true", "false");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getValue(@NotNull String input) throws FlagParseFailedException {
|
||||
return input.equalsIgnoreCase("true");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getDefaultValue() {
|
||||
return true;
|
||||
}
|
||||
}.addAliases("--structure", "-a");
|
||||
|
||||
/**
|
||||
* Flag to toggle if world spawn should be adjusted.
|
||||
*/
|
||||
public static final CommandFlag<Boolean> SPAWN_ADJUST = new NoValueCommandFlag<Boolean>
|
||||
("AdjustSpawn", "--dont-adjust-spawn", Boolean.class) {
|
||||
@Override
|
||||
public Boolean getValue() throws FlagParseFailedException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getDefaultValue() {
|
||||
return true;
|
||||
}
|
||||
}.addAliases("-n");
|
||||
|
||||
/**
|
||||
* Flag to specify a paste service.
|
||||
*/
|
||||
public static final CommandFlag<PasteServiceType> PASTE_SERVICE_TYPE = new OptionalCommandFlag<PasteServiceType>
|
||||
("PasteServiceType", "--paste", PasteServiceType.class) {
|
||||
|
||||
private final List<String> pasteTypes = Arrays.stream(PasteServiceType.values())
|
||||
.filter(pt -> pt != PasteServiceType.NONE)
|
||||
.map(p -> p.toString().toLowerCase())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@Override
|
||||
public Collection<String> suggestValue() {
|
||||
return pasteTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PasteServiceType getValue(@NotNull String input) throws FlagParseFailedException {
|
||||
try {
|
||||
return PasteServiceType.valueOf(input.toUpperCase());
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
throw new FlagParseFailedException(String.format("Invalid paste service type '%s'.", input));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PasteServiceType getValue() throws FlagParseFailedException {
|
||||
return PasteServiceType.PASTEGG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PasteServiceType getDefaultValue() {
|
||||
return PasteServiceType.NONE;
|
||||
}
|
||||
}.addAliases("-p");
|
||||
|
||||
/**
|
||||
* Flag to toggle if plugin list should be included.
|
||||
*/
|
||||
public static final CommandFlag<Boolean> INCLUDE_PLUGIN_LIST = new NoValueCommandFlag<Boolean>
|
||||
("IncludePlugins", "--include-plugin-list", Boolean.class) {
|
||||
@Override
|
||||
public Boolean getValue() throws FlagParseFailedException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getDefaultValue() {
|
||||
return true;
|
||||
}
|
||||
}.addAliases("-pl");
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
package com.onarandombox.MultiverseCore.commandtools.flag;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A group of {@link CommandFlag}, with indexed keys for efficient lookup.
|
||||
*/
|
||||
public class FlagGroup {
|
||||
|
||||
/**
|
||||
* Create a new Flag Group with multiple {@link CommandFlag}.
|
||||
*
|
||||
* @param flags Multiple flags.
|
||||
* @return A new {@link FlagGroup} generated from the flags.
|
||||
*/
|
||||
public static FlagGroup of(CommandFlag<?>...flags) {
|
||||
return new FlagGroup(flags);
|
||||
}
|
||||
|
||||
private final List<String> identifiers;
|
||||
private final Map<String, CommandFlag<?>> keyMap;
|
||||
|
||||
/**
|
||||
* Create a new Flag Group with multiple {@link CommandFlag}.
|
||||
*
|
||||
* @param commandFlags Array of flags
|
||||
*/
|
||||
public FlagGroup(CommandFlag<?>[] commandFlags) {
|
||||
this.identifiers = new ArrayList<>(commandFlags.length);
|
||||
this.keyMap = new HashMap<>();
|
||||
for (CommandFlag<?> flag : commandFlags) {
|
||||
addFlag(flag);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add and indexes a flag.
|
||||
*
|
||||
* @param flag The flag to add.
|
||||
*/
|
||||
private void addFlag(CommandFlag<?> flag) {
|
||||
this.identifiers.add(flag.getIdentifier());
|
||||
this.keyMap.put(flag.getIdentifier(), flag);
|
||||
for (String flagAlias : flag.getAliases()) {
|
||||
this.keyMap.put(flagAlias, flag);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the arguments to get it's flag values.
|
||||
*
|
||||
* @param args The arguments to parse.
|
||||
* @return A {@link FlagResult} containing value results.
|
||||
* @throws FlagParseFailedException When there is an error parsing, such as invalid format.
|
||||
*/
|
||||
@NotNull
|
||||
public FlagResult calculateResult(String[] args) throws FlagParseFailedException {
|
||||
return FlagResult.parse(args,this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets flag from pre-indexed key mapping.
|
||||
*
|
||||
* @param key The target key.
|
||||
* @return A {@link CommandFlag} if found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public CommandFlag<?> getByKey(String key) {
|
||||
return this.keyMap.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Suggest possible identifiers available for this Flag Group.
|
||||
*
|
||||
* @return A collection of identifier strings.
|
||||
*/
|
||||
@NotNull
|
||||
public Collection<String> suggestIdentifiers() {
|
||||
return identifiers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FlagGroup{" +
|
||||
"flagIdentifiers=" + identifiers +
|
||||
", keyFlagMap=" + keyMap +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
package com.onarandombox.MultiverseCore.commandtools.flag;
|
||||
|
||||
/**
|
||||
* Thrown when there is an issue with parsing flags from string arguments.
|
||||
*/
|
||||
//TODO: extend this from ACF CommandArgumentFailed exception class.
|
||||
public class FlagParseFailedException extends Exception {
|
||||
|
||||
public FlagParseFailedException() {
|
||||
}
|
||||
|
||||
public FlagParseFailedException(String message, Object...replacements) {
|
||||
super(String.format(message, replacements));
|
||||
}
|
||||
|
||||
public FlagParseFailedException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public FlagParseFailedException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public FlagParseFailedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
package com.onarandombox.MultiverseCore.commandtools.flag;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents the value result parsed from command arguments.
|
||||
*/
|
||||
public class FlagResult {
|
||||
|
||||
/**
|
||||
* Parse arguments into its flag key and values.
|
||||
*
|
||||
* @param args The arguments to parse.
|
||||
* @param flagGroup The flags available to parse into.
|
||||
* @return The {@link FlagResult} from the parse.
|
||||
* @throws FlagParseFailedException there is an issue with parsing flags from string arguments.
|
||||
*/
|
||||
public static FlagResult parse(@Nullable String[] args,
|
||||
@NotNull FlagGroup flagGroup) throws FlagParseFailedException {
|
||||
|
||||
FlagResult flagResult = new FlagResult();
|
||||
|
||||
// No args to parse.
|
||||
if (args == null || args.length <= 0) {
|
||||
return flagResult;
|
||||
}
|
||||
|
||||
// First arg must be a flag.
|
||||
CommandFlag<?> currentFlag = flagGroup.getByKey(args[0]);
|
||||
boolean completed = false;
|
||||
|
||||
// Parse the arguments.
|
||||
for (int i = 1, argsLength = args.length; i <= argsLength; i++) {
|
||||
if (currentFlag == null) {
|
||||
throw new FlagParseFailedException("%s is not a valid flag.", args[i-1]);
|
||||
}
|
||||
// This ensures that flag is not null during final parse.
|
||||
if (i >= argsLength) {
|
||||
break;
|
||||
}
|
||||
|
||||
String arg = args[i];
|
||||
if (arg == null) {
|
||||
throw new FlagParseFailedException("Arguments cannot be null!");
|
||||
}
|
||||
|
||||
CommandFlag<?> nextFlag = flagGroup.getByKey(arg);
|
||||
|
||||
// Arg must be a flag key.
|
||||
if (currentFlag instanceof NoValueCommandFlag) {
|
||||
flagResult.add(currentFlag, currentFlag.getValue(), false);
|
||||
currentFlag = nextFlag;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Arg can be a flag key or value.
|
||||
if (currentFlag instanceof OptionalCommandFlag) {
|
||||
if (nextFlag != null) {
|
||||
// It's a key.
|
||||
flagResult.add(currentFlag, currentFlag.getValue(), false);
|
||||
currentFlag = nextFlag;
|
||||
continue;
|
||||
}
|
||||
// It's a value.
|
||||
flagResult.add(currentFlag, currentFlag.getValue(arg), true);
|
||||
if (i == argsLength - 1) {
|
||||
completed = true;
|
||||
break;
|
||||
}
|
||||
currentFlag = flagGroup.getByKey(args[++i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Arg must be a flag value.
|
||||
if (currentFlag instanceof RequiredCommandFlag) {
|
||||
if (nextFlag != null) {
|
||||
// It's a key, error!
|
||||
throw new FlagParseFailedException("%s flag '%s' requires a value input.",
|
||||
currentFlag.getName(), currentFlag.getIdentifier());
|
||||
}
|
||||
// It's a value.
|
||||
flagResult.add(currentFlag, currentFlag.getValue(arg), true);
|
||||
if (i == argsLength - 1) {
|
||||
completed = true;
|
||||
break;
|
||||
}
|
||||
currentFlag = flagGroup.getByKey(args[++i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Parse last flag.
|
||||
if (!completed) {
|
||||
if (currentFlag instanceof RequiredCommandFlag) {
|
||||
throw new FlagParseFailedException("%s flag '%s' requires a value input.",
|
||||
currentFlag.getName(), currentFlag.getIdentifier());
|
||||
}
|
||||
flagResult.add(currentFlag, currentFlag.getValue(), false);
|
||||
}
|
||||
|
||||
return flagResult;
|
||||
}
|
||||
|
||||
private final Map<CommandFlag<?>, SingleFlagResult<?>> resultMap;
|
||||
|
||||
private FlagResult() {
|
||||
resultMap = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new value result from parsing arguments.
|
||||
*
|
||||
* @param flag The flag that the value represents.
|
||||
* @param value The value of the flag.
|
||||
* @param fromInput Denotes if flag was parsed by a user input.
|
||||
*/
|
||||
private void add(CommandFlag<?> flag, Object value, boolean fromInput) {
|
||||
resultMap.put(flag, new SingleFlagResult<>(value, fromInput));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets value of a flag.
|
||||
*
|
||||
* @param flag The flag to get value from.
|
||||
* @param <T> The type of value.
|
||||
* @return The value which is associated with the flag.
|
||||
*/
|
||||
public <T> T getValue(CommandFlag<T> flag) {
|
||||
SingleFlagResult<?> result = resultMap.get(flag);
|
||||
if (result == null) {
|
||||
return flag.getDefaultValue();
|
||||
}
|
||||
return (T) result.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if the flag value is by a user input.
|
||||
*
|
||||
* @param flag The flag to check against.
|
||||
* @return True if value is by user input, else false.
|
||||
*/
|
||||
public boolean isByUserInput(CommandFlag<?> flag) {
|
||||
SingleFlagResult<?> result = resultMap.get(flag);
|
||||
if (result == null) {
|
||||
return false;
|
||||
}
|
||||
return result.isFromUserInput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if the flag is a default value, and key was not present in user's command arguments.
|
||||
* i.e. Not in the {@link #resultMap}.
|
||||
*
|
||||
* @param flag The flag to check against.
|
||||
* @return True if flag was not present in user's command arguments, else false.
|
||||
*/
|
||||
public boolean isDefaulted(CommandFlag<?> flag) {
|
||||
return resultMap.get(flag) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FlagResult{" +
|
||||
"resultMap=" + resultMap +
|
||||
'}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a single value result parsed.
|
||||
* Stores value and addition data such as if value is by user input.
|
||||
*
|
||||
* @param <T> The type of value.
|
||||
*/
|
||||
private static class SingleFlagResult<T> {
|
||||
private final T value;
|
||||
private final boolean isFromUserInput;
|
||||
|
||||
/**
|
||||
* @param value The resultant value from argument parsing.
|
||||
* @param fromInput Indicates if value is parsed by user input.
|
||||
*/
|
||||
private SingleFlagResult(T value, boolean fromInput) {
|
||||
this.value = value;
|
||||
this.isFromUserInput = fromInput;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SingleFlagResult{" +
|
||||
"value=" + value +
|
||||
", isFromUserInput=" + isFromUserInput +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
package com.onarandombox.MultiverseCore.commandtools.flag;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* This flag will always not require a user input to parse value.
|
||||
*
|
||||
* @param <T> The flag Type.
|
||||
*/
|
||||
public abstract class NoValueCommandFlag<T> extends CommandFlag<T> {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public NoValueCommandFlag(String name, String identifier, Class<T> type) {
|
||||
super(name, identifier, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link NoValueCommandFlag} will always not require a user input to parse value.
|
||||
* Thus, no value suggestion needed.
|
||||
*/
|
||||
@Override
|
||||
public final Collection<String> suggestValue() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link NoValueCommandFlag} will always not require a user input to parse value.
|
||||
* Thus, this operation is not allowed.
|
||||
*/
|
||||
@Override
|
||||
public final T getValue(@NotNull String input) throws FlagParseFailedException {
|
||||
throw new FlagParseFailedException("%s flag '%s' does not require a value.", this.name, this.identifier);
|
||||
}
|
||||
}
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
package com.onarandombox.MultiverseCore.commandtools.flag;
|
||||
|
||||
/**
|
||||
* Command Flag that optionally allows a user input value.
|
||||
*
|
||||
* @param <T> The flag Type.
|
||||
*/
|
||||
public abstract class OptionalCommandFlag<T> extends CommandFlag<T> {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public OptionalCommandFlag(String name, String identifier, Class<T> type) {
|
||||
super(name, identifier, type);
|
||||
}
|
||||
}
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
package com.onarandombox.MultiverseCore.commandtools.flag;
|
||||
|
||||
/**
|
||||
* This flag will always require a user input to parse value.
|
||||
*
|
||||
* @param <T> The flag Type.
|
||||
*/
|
||||
public abstract class RequiredCommandFlag<T> extends CommandFlag<T> {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public RequiredCommandFlag(String name, String identifier, Class<T> type) {
|
||||
super(name, identifier, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link RequiredCommandFlag} will always require a user input to parse value.
|
||||
* Thus, this operation is not allowed.
|
||||
*/
|
||||
@Override
|
||||
public final T getValue() throws FlagParseFailedException {
|
||||
throw new FlagParseFailedException("%s flag '%s' requires a value input.", this.name, this.identifier);
|
||||
}
|
||||
}
|
||||
@@ -11,16 +11,27 @@ import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVDestination;
|
||||
import com.onarandombox.MultiverseCore.commands.TeleportCommand;
|
||||
import com.onarandombox.MultiverseCore.utils.PermissionTools;
|
||||
import com.onarandombox.MultiverseCore.utils.PlayerFinder;
|
||||
import com.pneumaticraft.commandhandler.Command;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** A factory class that will create destinations from specific strings. */
|
||||
public class DestinationFactory {
|
||||
|
||||
private static final Pattern CANNON_PATTERN = Pattern.compile("(?i)cannon-[\\d]+(\\.[\\d]+)?");
|
||||
|
||||
private MultiverseCore plugin;
|
||||
private Map<String, Class<? extends MVDestination>> destList;
|
||||
private Command teleportCommand;
|
||||
@@ -36,6 +47,59 @@ public class DestinationFactory {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a destination that has relation to sender, such as a cannon or player destination.
|
||||
*
|
||||
* @param teleportee The player that is going to be teleported.
|
||||
* @param destinationName The destination to parse.
|
||||
* @return A non-null MVDestination
|
||||
*/
|
||||
@NotNull
|
||||
public MVDestination getPlayerAwareDestination(@NotNull Player teleportee,
|
||||
@NotNull String destinationName) {
|
||||
|
||||
// Prioritise world, in the event that a world is named after a player online.
|
||||
if (Bukkit.getWorld(destinationName) != null) {
|
||||
return getDestination(destinationName);
|
||||
}
|
||||
|
||||
Player targetPlayer = PlayerFinder.get(destinationName, teleportee);
|
||||
if (targetPlayer != null) {
|
||||
return getDestination("pl:" + targetPlayer.getName());
|
||||
}
|
||||
|
||||
if (CANNON_PATTERN.matcher(destinationName).matches()) {
|
||||
return getDestination(parseCannonDest(teleportee, destinationName));
|
||||
}
|
||||
|
||||
return getDestination(destinationName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a cannon destination.
|
||||
*
|
||||
* @param teleportee The player that is going to be teleported.
|
||||
* @param destinationName The destination to parse.
|
||||
* @return A destination string.
|
||||
*/
|
||||
@NotNull
|
||||
private String parseCannonDest(@NotNull Player teleportee,
|
||||
@NotNull String destinationName) {
|
||||
|
||||
String[] cannonSpeed = destinationName.split("-");
|
||||
try {
|
||||
double speed = Double.parseDouble(cannonSpeed[1]);
|
||||
destinationName = "ca:" + teleportee.getWorld().getName() + ":" + teleportee.getLocation().getX()
|
||||
+ "," + teleportee.getLocation().getY() + "," + teleportee.getLocation().getZ() + ":"
|
||||
+ teleportee.getLocation().getPitch() + ":" + teleportee.getLocation().getYaw() + ":" + speed;
|
||||
}
|
||||
catch (Exception e) {
|
||||
destinationName = "i:invalid";
|
||||
}
|
||||
|
||||
return destinationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a new destination from a string.
|
||||
* Returns a new InvalidDestination if the string could not be parsed.
|
||||
@@ -101,4 +165,8 @@ public class DestinationFactory {
|
||||
this.teleportCommand.addAdditonalPermission(other);
|
||||
return true;
|
||||
}
|
||||
|
||||
public Collection<String> getRegisteredIdentifiers() {
|
||||
return this.destList.keySet();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
package com.onarandombox.MultiverseCore.utils;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Helper class to get {@link Player} from name, UUID or Selectors.
|
||||
*/
|
||||
public class PlayerFinder {
|
||||
|
||||
private static final Pattern UUID_REGEX = Pattern.compile("[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}");
|
||||
private static final Pattern COMMA_SPLIT = Pattern.compile(",");
|
||||
|
||||
/**
|
||||
* Get a {@link Player} based on an identifier of name UUID or selector.
|
||||
*
|
||||
* @param playerIdentifier An identifier of name UUID or selector.
|
||||
* @param sender Target sender for selector.
|
||||
* @return The player if found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static Player get(@NotNull String playerIdentifier,
|
||||
@NotNull CommandSender sender) {
|
||||
|
||||
Player targetPlayer = getByName(playerIdentifier);
|
||||
if (targetPlayer != null) {
|
||||
return targetPlayer;
|
||||
}
|
||||
targetPlayer = getByUuid(playerIdentifier);
|
||||
if (targetPlayer != null) {
|
||||
return targetPlayer;
|
||||
}
|
||||
return getBySelector(playerIdentifier, sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get multiple {@link Player} based on many identifiers of name UUID or selector.
|
||||
*
|
||||
* @param playerIdentifiers An identifier of multiple names, UUIDs or selectors, separated by comma.
|
||||
* @param sender Target sender for selector.
|
||||
* @return A list of all the {@link Player} found.
|
||||
*/
|
||||
@Nullable
|
||||
public static List<Player> getMulti(@NotNull String playerIdentifiers,
|
||||
@NotNull CommandSender sender) {
|
||||
|
||||
String[] playerIdentifierArray = COMMA_SPLIT.split(playerIdentifiers);
|
||||
if (playerIdentifierArray == null || playerIdentifierArray.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Player> playerResults = new ArrayList<>();
|
||||
for (String playerIdentifier : playerIdentifierArray) {
|
||||
Player targetPlayer = getByName(playerIdentifier);
|
||||
if (targetPlayer != null) {
|
||||
playerResults.add(targetPlayer);
|
||||
continue;
|
||||
}
|
||||
targetPlayer = getByUuid(playerIdentifier);
|
||||
if (targetPlayer != null) {
|
||||
playerResults.add(targetPlayer);
|
||||
continue;
|
||||
}
|
||||
List<Player> targetPlayers = getMultiBySelector(playerIdentifier, sender);
|
||||
if (targetPlayers != null) {
|
||||
playerResults.addAll(targetPlayers);
|
||||
}
|
||||
}
|
||||
return playerResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a {@link Player} based on player name.
|
||||
*
|
||||
* @param playerName Name of a {@link Player}.
|
||||
* @return The player if found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static Player getByName(@NotNull String playerName) {
|
||||
return Bukkit.getPlayerExact(playerName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a {@link Player} based on player UUID.
|
||||
*
|
||||
* @param playerUuid UUID of a player.
|
||||
* @return The player if found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static Player getByUuid(@NotNull String playerUuid) {
|
||||
if (!UUID_REGEX.matcher(playerUuid).matches()) {
|
||||
return null;
|
||||
}
|
||||
UUID uuid;
|
||||
try {
|
||||
uuid = UUID.fromString(playerUuid);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
return getByUuid(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a {@link Player} based on playerUUID.
|
||||
*
|
||||
* @param playerUuid UUID of a player.
|
||||
* @return The player if found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static Player getByUuid(@NotNull UUID playerUuid) {
|
||||
return Bukkit.getPlayer(playerUuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a {@link Player} based on vanilla selectors.
|
||||
* https://minecraft.gamepedia.com/Commands#Target_selectors
|
||||
*
|
||||
* @param playerSelector A target selector, usually starts with an '@'.
|
||||
* @param sender Target sender for selector.
|
||||
* @return The player if only one found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static Player getBySelector(@NotNull String playerSelector,
|
||||
@NotNull CommandSender sender) {
|
||||
|
||||
List<Player> matchedPlayers = getMultiBySelector(playerSelector, sender);
|
||||
if (matchedPlayers == null || matchedPlayers.isEmpty()) {
|
||||
Logging.warning("No player found with selector '%s' for %s.", playerSelector, sender.getName());
|
||||
return null;
|
||||
}
|
||||
if (matchedPlayers.size() > 1) {
|
||||
Logging.warning("Ambiguous selector result '%s' for %s (more than one player matched) - %s",
|
||||
playerSelector, sender.getName(), matchedPlayers.toString());
|
||||
return null;
|
||||
}
|
||||
return matchedPlayers.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get multiple {@link Player} based on selector.
|
||||
* https://minecraft.gamepedia.com/Commands#Target_selectors
|
||||
*
|
||||
* @param playerSelector A target selector, usually starts with an '@'.
|
||||
* @param sender Target sender for selector.
|
||||
* @return A list of all the {@link Player} found.
|
||||
*/
|
||||
@Nullable
|
||||
public static List<Player> getMultiBySelector(@NotNull String playerSelector,
|
||||
@NotNull CommandSender sender) {
|
||||
|
||||
if (playerSelector.charAt(0) != '@') {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Bukkit.selectEntities(sender, playerSelector).stream()
|
||||
.filter(e -> e instanceof Player)
|
||||
.map(e -> ((Player) e))
|
||||
.collect(Collectors.toList());
|
||||
} catch (IllegalArgumentException e) {
|
||||
Logging.warning("An error occurred while parsing selector '%s' for %s. Is it is the correct format?",
|
||||
playerSelector, sender.getName());
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
package com.onarandombox.MultiverseCore.utils;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Utility class used to help in doing various reflection actions.
|
||||
*/
|
||||
public class ReflectHelper {
|
||||
|
||||
/**
|
||||
* Try to get the {@link Class} based on its classpath.
|
||||
*
|
||||
* @param classPath The target classpath.
|
||||
* @return A {@link Class} if found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static Class<?> getClass(String classPath) {
|
||||
try {
|
||||
return Class.forName(classPath);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the {@link Class} for a give classpath is present/valid.
|
||||
*
|
||||
* @param classPath Target classpath.
|
||||
* @return True if class path is a valid class, else false.
|
||||
*/
|
||||
public static boolean hasClass(String classPath) {
|
||||
return getClass(classPath) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to get a {@link Method} from a given class.
|
||||
*
|
||||
* @param clazz The class to search the method on.
|
||||
* @param methodName Name of the method to get.
|
||||
* @param parameterTypes Parameters present for that method.
|
||||
* @param <C> The class type.
|
||||
* @return A {@link Method} if found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static <C> Method getMethod(Class<C> clazz, String methodName, Class<?>... parameterTypes) {
|
||||
try {
|
||||
Method method = clazz.getDeclaredMethod(methodName, parameterTypes);
|
||||
method.setAccessible(true);
|
||||
return method;
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to get a {@link Method} from a given class.
|
||||
*
|
||||
* @param classInstance Instance of the class to search the method on.
|
||||
* @param methodName Name of the method to get.
|
||||
* @param parameterTypes Parameters present for that method.
|
||||
* @param <C> The class type.
|
||||
* @return A {@link Method} if found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static <C> Method getMethod(C classInstance, String methodName, Class<?>... parameterTypes) {
|
||||
return getMethod(classInstance.getClass(), methodName, parameterTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a {@link Method}.
|
||||
*
|
||||
* @param classInstance Instance of the class responsible for the method.
|
||||
* @param method The method to call.
|
||||
* @param parameters Parameters needed when calling the method.
|
||||
* @param <C> The class type.
|
||||
* @param <R> The return type.
|
||||
* @return Return value of the method call if any, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static <C, R> R invokeMethod(C classInstance, Method method, Object...parameters) {
|
||||
try {
|
||||
return (R) method.invoke(classInstance, parameters);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to get a {@link Field} from a given class.
|
||||
*
|
||||
* @param clazz The class to search the field on.
|
||||
* @param fieldName Name of the field to get.
|
||||
* @param <C> The class type.
|
||||
* @return A {@link Field} if found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static <C> Field getField(Class<C> clazz, String fieldName) {
|
||||
try {
|
||||
Field field = clazz.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
return field;
|
||||
} catch (NoSuchFieldException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to get a {@link Field} from a given class.
|
||||
*
|
||||
* @param classInstance Instance of the class to search the field on.
|
||||
* @param fieldName Name of the field to get.
|
||||
* @param <C> The class type.
|
||||
* @return A {@link Field} if found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static <C> Field getField(C classInstance, String fieldName) {
|
||||
return getField(classInstance.getClass(), fieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of an {@link Field} from an instance of the class responsible.
|
||||
*
|
||||
* @param classInstance Instance of the class to get the field value from.
|
||||
* @param field The field to get value from.
|
||||
* @param <C> The class type.
|
||||
* @param <V> The field value type.
|
||||
* @return The field value if any, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static <C, V> V getFieldValue(C classInstance, Field field) {
|
||||
try {
|
||||
return (V) field.get(classInstance);
|
||||
} catch (IllegalAccessException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,19 +36,19 @@ import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Public facing API to add/remove Multiverse worlds.
|
||||
@@ -130,7 +130,7 @@ public class WorldManager implements MVWorldManager {
|
||||
}
|
||||
|
||||
// Check for valid world name
|
||||
if (!(isValidWorldName(oldName) && isValidWorldName(newName))) {
|
||||
if (!(WorldNameChecker.isValidWorldName(oldName) && WorldNameChecker.isValidWorldName(oldName))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -238,7 +238,9 @@ public class WorldManager implements MVWorldManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isValidWorldName(name)) {
|
||||
if (!WorldNameChecker.isValidWorldName(name)) {
|
||||
Logging.warning("Invalid world name '" + name + "'");
|
||||
Logging.warning("World name should not contain spaces or special characters!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -424,21 +426,6 @@ public class WorldManager implements MVWorldManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the world name is allowed
|
||||
*
|
||||
* @param name Name of the world
|
||||
* @return True if the world world name is valid based on regex
|
||||
*/
|
||||
private boolean isValidWorldName(String name) {
|
||||
if (!worldNamePattern.matcher(name).matches()) {
|
||||
Logging.warning("Invalid world name '" + name + "'");
|
||||
Logging.warning("World name should not contain spaces or special characters!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void brokenWorld(String name) {
|
||||
Logging.severe("The world '" + name + "' could NOT be loaded because it contains errors and is probably corrupt!");
|
||||
Logging.severe("Try using Minecraft Region Fixer to repair your world! '" + name + "'");
|
||||
@@ -630,6 +617,14 @@ public class WorldManager implements MVWorldManager {
|
||||
*/
|
||||
@Override
|
||||
public MultiverseWorld getMVWorld(String name) {
|
||||
return this.getMVWorld(name, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public MultiverseWorld getMVWorld(String name, boolean checkAliases) {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -637,7 +632,7 @@ public class WorldManager implements MVWorldManager {
|
||||
if (world != null) {
|
||||
return world;
|
||||
}
|
||||
return this.getMVWorldByAlias(name);
|
||||
return (checkAliases) ? this.getMVWorldByAlias(name) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -646,7 +641,7 @@ public class WorldManager implements MVWorldManager {
|
||||
@Override
|
||||
public MultiverseWorld getMVWorld(World world) {
|
||||
if (world != null) {
|
||||
return this.getMVWorld(world.getName());
|
||||
return this.getMVWorld(world.getName(), false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -671,7 +666,15 @@ public class WorldManager implements MVWorldManager {
|
||||
*/
|
||||
@Override
|
||||
public boolean isMVWorld(final String name) {
|
||||
return (this.worlds.containsKey(name) || isMVWorldAlias(name));
|
||||
return this.isMVWorld(name, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isMVWorld(final String name, boolean checkAliases) {
|
||||
return this.worlds.containsKey(name) || (checkAliases && this.isMVWorldAlias(name));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -953,4 +956,21 @@ public class WorldManager implements MVWorldManager {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Collection<String> getPotentialWorlds() {
|
||||
File worldContainer = this.plugin.getServer().getWorldContainer();
|
||||
if (worldContainer == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Arrays.stream(worldContainer.listFiles())
|
||||
.filter(File::isDirectory)
|
||||
.filter(folder -> !this.isMVWorld(folder.getName(), false))
|
||||
.filter(WorldNameChecker::isValidWorldFolder)
|
||||
.map(File::getName)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
package com.onarandombox.MultiverseCore.utils;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* <p>Utility class in helping to check the status of a world name and it's associated world folder.</p>
|
||||
*
|
||||
* <p>Note this is for preliminary checks and better command output. A valid result will suggest but not
|
||||
* 100% determine that a world name can be created, loaded or imported.</p>
|
||||
*/
|
||||
public class WorldNameChecker {
|
||||
|
||||
private static final Pattern WORLD_NAME_PATTERN = Pattern.compile("[a-zA-Z0-9/._-]+");
|
||||
private static final Set<String> BLACKLIST_NAMES = Collections.unmodifiableSet(new HashSet<String>() {{
|
||||
add("plugins");
|
||||
add("logs");
|
||||
add("cache");
|
||||
add("crash-reports");
|
||||
}});
|
||||
|
||||
/**
|
||||
* Checks if a world name is valid.
|
||||
*
|
||||
* @param worldName The world name to check on.
|
||||
* @return True if check result is valid, else false.
|
||||
*/
|
||||
public static boolean isValidWorldName(@Nullable String worldName) {
|
||||
return checkName(worldName) == NameStatus.VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the current validity status of a world name.
|
||||
*
|
||||
* @param worldName The world name to check on.
|
||||
* @return The resulting name status.
|
||||
*/
|
||||
@NotNull
|
||||
public static NameStatus checkName(@Nullable String worldName) {
|
||||
if (BLACKLIST_NAMES.contains(worldName)) {
|
||||
return NameStatus.BLACKLISTED;
|
||||
}
|
||||
if (worldName == null || !WORLD_NAME_PATTERN.matcher(worldName).matches()) {
|
||||
return NameStatus.INVALID_CHARS;
|
||||
}
|
||||
return NameStatus.VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a world name has a valid world folder.
|
||||
*
|
||||
* @param worldName The world name to check on.
|
||||
* @return True if check result is valid, else false.
|
||||
*/
|
||||
public static boolean isValidWorldFolder(@Nullable String worldName) {
|
||||
return checkFolder(worldName) == FolderStatus.VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a world folder is valid.
|
||||
*
|
||||
* @param worldFolder The world folder to check on.
|
||||
* @return True if check result is valid, else false.
|
||||
*/
|
||||
public static boolean isValidWorldFolder(@Nullable File worldFolder) {
|
||||
return checkFolder(worldFolder) == FolderStatus.VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the current folder status for a world name.
|
||||
*
|
||||
* @param worldName The world name to check on.
|
||||
* @return The resulting folder status.
|
||||
*/
|
||||
@NotNull
|
||||
public static FolderStatus checkFolder(@Nullable String worldName) {
|
||||
if (worldName == null) {
|
||||
return FolderStatus.DOES_NOT_EXIST;
|
||||
}
|
||||
File worldFolder = new File(Bukkit.getWorldContainer(), worldName);
|
||||
return checkFolder(worldFolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the current folder status.
|
||||
*
|
||||
* @param worldFolder The world folder to check on.
|
||||
* @return The resulting folder status.
|
||||
*/
|
||||
@NotNull
|
||||
public static FolderStatus checkFolder(@Nullable File worldFolder) {
|
||||
if (worldFolder == null || !worldFolder.exists() || !worldFolder.isDirectory()) {
|
||||
return FolderStatus.DOES_NOT_EXIST;
|
||||
}
|
||||
if (!folderHasDat(worldFolder)) {
|
||||
return FolderStatus.NOT_A_WORLD;
|
||||
}
|
||||
return FolderStatus.VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* A very basic check to see if a folder has a level.dat file. If it does, we can safely assume
|
||||
* it's a world folder.
|
||||
*
|
||||
* @param worldFolder The File that may be a world.
|
||||
* @return True if it looks like a world, else false.
|
||||
*/
|
||||
private static boolean folderHasDat(@NotNull File worldFolder) {
|
||||
File[] files = worldFolder.listFiles((file, name) -> name.toLowerCase().endsWith(".dat"));
|
||||
return files != null && files.length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Result after checking validity of world name.
|
||||
*/
|
||||
public enum NameStatus {
|
||||
/**
|
||||
* Name is valid.
|
||||
*/
|
||||
VALID,
|
||||
|
||||
/**
|
||||
* Name not valid as it contains invalid characters.
|
||||
*/
|
||||
INVALID_CHARS,
|
||||
|
||||
/**
|
||||
* Name not valid as it is deemed blacklisted.
|
||||
*/
|
||||
BLACKLISTED
|
||||
}
|
||||
|
||||
/**
|
||||
* Result after checking validity of world folder.
|
||||
*/
|
||||
public enum FolderStatus {
|
||||
/**
|
||||
* Folder is valid.
|
||||
*/
|
||||
VALID,
|
||||
|
||||
/**
|
||||
* Folder exist, but contents in it doesnt look like a world.
|
||||
*/
|
||||
NOT_A_WORLD,
|
||||
|
||||
/**
|
||||
* Folder does not exist.
|
||||
*/
|
||||
DOES_NOT_EXIST
|
||||
}
|
||||
}
|
||||
@@ -22,9 +22,5 @@ public enum PasteServiceType {
|
||||
/**
|
||||
* @see GitHubPasteService
|
||||
*/
|
||||
GITHUB,
|
||||
/**
|
||||
* No paste service used.
|
||||
*/
|
||||
NONE
|
||||
GITHUB
|
||||
}
|
||||
@@ -207,7 +207,7 @@ public class TestWorldStuff {
|
||||
assertEquals(0, creator.getCore().getMVWorldManager().getMVWorlds().size());
|
||||
|
||||
// Verify
|
||||
verify(mockCommandSender).sendMessage("§cError: Invalid generator string 'BogusGen'. See /mv gens for available generators.");
|
||||
verify(mockCommandSender).sendMessage("Invalid generator! 'BogusGen'. " + ChatColor.RED + "Aborting world creation.");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in new issue
Block a user