Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74089df9a1 |
No files matched your search
@@ -27,13 +27,17 @@
|
||||
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
<id>vault-repo</id>
|
||||
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>minebench-repo</id>
|
||||
<url>https://repo.minebench.de/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>CodeMC</id>
|
||||
<url>https://repo.codemc.org/repository/maven-public</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
@@ -219,7 +223,6 @@
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<minimizeJar>true</minimizeJar>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>me.main__.util</pattern>
|
||||
@@ -302,7 +305,7 @@
|
||||
<!-- End of SerializationConfig Dependency -->
|
||||
<!-- Start of Economy Dependency -->
|
||||
<dependency>
|
||||
<groupId>com.github.MilkBowl</groupId>
|
||||
<groupId>net.milkbowl.vault</groupId>
|
||||
<artifactId>VaultAPI</artifactId>
|
||||
<version>1.7</version>
|
||||
<scope>provided</scope>
|
||||
@@ -322,7 +325,13 @@
|
||||
<dependency>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-bukkit</artifactId>
|
||||
<version>2.2.1</version>
|
||||
<version>1.8</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.dumptruckman.minecraft</groupId>
|
||||
|
||||
@@ -68,7 +68,6 @@ import com.onarandombox.MultiverseCore.commands.TeleportCommand;
|
||||
import com.onarandombox.MultiverseCore.commands.UnloadCommand;
|
||||
import com.onarandombox.MultiverseCore.commands.VersionCommand;
|
||||
import com.onarandombox.MultiverseCore.commands.WhoCommand;
|
||||
import com.onarandombox.MultiverseCore.commandtools.queue.CommandQueueManager;
|
||||
import com.onarandombox.MultiverseCore.destination.AnchorDestination;
|
||||
import com.onarandombox.MultiverseCore.destination.BedDestination;
|
||||
import com.onarandombox.MultiverseCore.destination.CannonDestination;
|
||||
@@ -78,6 +77,8 @@ import com.onarandombox.MultiverseCore.destination.PlayerDestination;
|
||||
import com.onarandombox.MultiverseCore.destination.WorldDestination;
|
||||
import com.onarandombox.MultiverseCore.event.MVDebugModeEvent;
|
||||
import com.onarandombox.MultiverseCore.event.MVVersionEvent;
|
||||
import com.onarandombox.MultiverseCore.generators.GeneratorManager;
|
||||
import com.onarandombox.MultiverseCore.api.MVGeneratorManager;
|
||||
import com.onarandombox.MultiverseCore.listeners.MVAsyncPlayerChatListener;
|
||||
import com.onarandombox.MultiverseCore.listeners.MVChatListener;
|
||||
import com.onarandombox.MultiverseCore.listeners.MVEntityListener;
|
||||
@@ -205,7 +206,6 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
|
||||
// Setup our Map for our Commands using the CommandHandler.
|
||||
private CommandHandler commandHandler;
|
||||
private CommandQueueManager commandQueueManager;
|
||||
|
||||
private static final String LOG_TAG = "[Multiverse-Core]";
|
||||
|
||||
@@ -215,6 +215,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
// Configurations
|
||||
private FileConfiguration multiverseConfig = null;
|
||||
|
||||
private MVGeneratorManager generatorManager;
|
||||
private final MVWorldManager worldManager = new WorldManager(this);
|
||||
|
||||
// Setup the block/player/entity listener.
|
||||
@@ -282,7 +283,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
this.messaging = new MVMessaging();
|
||||
this.economist = new MVEconomist(this);
|
||||
// Load the defaultWorldGenerators
|
||||
this.worldManager.getDefaultWorldGenerators();
|
||||
this.generatorManager = new GeneratorManager(this);
|
||||
|
||||
this.registerEvents();
|
||||
// Setup Permissions, we'll do an initial check for the Permissions plugin then fall back on isOP().
|
||||
@@ -290,7 +291,6 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
|
||||
// Setup the command manager
|
||||
this.commandHandler = new CommandHandler(this, this.ph);
|
||||
this.commandQueueManager = new CommandQueueManager(this);
|
||||
// Call the Function to assign all the Commands to their Class.
|
||||
this.registerCommands();
|
||||
|
||||
@@ -367,9 +367,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
// Add global variable "multiverse" to javascript environment
|
||||
buscript.setScriptVariable("multiverse", this);
|
||||
} catch (NullPointerException e) {
|
||||
Logging.warning("Buscript failed to load! The script command will be disabled! " +
|
||||
"If you would like not to see this message, " +
|
||||
"use `/mv conf enablebuscript false` to disable Buscript from loading.");
|
||||
Logging.warning("Buscript failed to load! The script command will be disabled!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -922,15 +920,6 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
return this.commandHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public CommandQueueManager getCommandQueueManager() {
|
||||
return commandQueueManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the log-tag.
|
||||
*
|
||||
@@ -1028,6 +1017,14 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
this.serverFolder = newServerFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public MVGeneratorManager getMVGeneratorManager() {
|
||||
return generatorManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@@ -1131,22 +1128,12 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @deprecated This is deprecated! Do not use!
|
||||
* @deprecated This is deprecated!
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public Boolean regenWorld(String name, Boolean useNewSeed, Boolean randomSeed, String seed) {
|
||||
return this.worldManager.regenWorld(name, useNewSeed, randomSeed, seed, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @deprecated This is deprecated! Do not use!
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public Boolean regenWorld(String name, Boolean useNewSeed, Boolean randomSeed, String seed, Boolean keepGameRules) {
|
||||
return this.worldManager.regenWorld(name, useNewSeed, randomSeed, seed, keepGameRules);
|
||||
return this.worldManager.regenWorld(name, useNewSeed, randomSeed, seed);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.onarandombox.MultiverseCore;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.api.MultiverseCoreConfig;
|
||||
import com.onarandombox.MultiverseCore.event.MVDebugModeEvent;
|
||||
@@ -8,8 +10,6 @@ import me.main__.util.SerializationConfig.Property;
|
||||
import me.main__.util.SerializationConfig.SerializationConfig;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Our configuration.
|
||||
*/
|
||||
@@ -77,8 +77,6 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
|
||||
private volatile boolean autopurge;
|
||||
@Property
|
||||
private volatile boolean idonotwanttodonate;
|
||||
@Property
|
||||
private volatile boolean allowunsafeworldname;
|
||||
|
||||
public MultiverseCoreConfiguration() {
|
||||
super();
|
||||
@@ -98,7 +96,7 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
|
||||
// BEGIN CHECKSTYLE-SUPPRESSION: MagicNumberCheck
|
||||
enforceaccess = false;
|
||||
useasyncchat = true;
|
||||
prefixchat = false;
|
||||
prefixchat = true;
|
||||
prefixchatformat = "[%world%]%chat%";
|
||||
teleportintercept = true;
|
||||
firstspawnoverride = true;
|
||||
@@ -113,7 +111,6 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
|
||||
portalsearchradius = 128;
|
||||
autopurge = true;
|
||||
idonotwanttodonate = false;
|
||||
allowunsafeworldname = false;
|
||||
// END CHECKSTYLE-SUPPRESSION: MagicNumberCheck
|
||||
}
|
||||
|
||||
@@ -385,14 +382,4 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
|
||||
public void setShowDonateMessage(boolean showDonateMessage) {
|
||||
this.idonotwanttodonate = !showDonateMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowUnsafeWorldName() {
|
||||
return allowunsafeworldname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAllowUnsafeWorldName(boolean allowUnsafeWorldName) {
|
||||
this.allowunsafeworldname = allowUnsafeWorldName;
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@
|
||||
package com.onarandombox.MultiverseCore.api;
|
||||
|
||||
import buscript.Buscript;
|
||||
import com.onarandombox.MultiverseCore.commandtools.queue.CommandQueueManager;
|
||||
import com.onarandombox.MultiverseCore.destination.DestinationFactory;
|
||||
import com.onarandombox.MultiverseCore.utils.AnchorManager;
|
||||
import com.onarandombox.MultiverseCore.utils.MVEconomist;
|
||||
@@ -87,15 +86,6 @@ public interface Core {
|
||||
*/
|
||||
CommandHandler getCommandHandler();
|
||||
|
||||
/**
|
||||
* Manager for command that requires /mv confirm before execution.
|
||||
*
|
||||
* @return A non-null {@link CommandQueueManager}.
|
||||
* @deprecated To be moved to new command manager in 5.0.0
|
||||
*/
|
||||
@Deprecated
|
||||
CommandQueueManager getCommandQueueManager();
|
||||
|
||||
/**
|
||||
* Gets the factory class responsible for loading many different destinations
|
||||
* on demand.
|
||||
@@ -104,6 +94,13 @@ public interface Core {
|
||||
*/
|
||||
DestinationFactory getDestFactory();
|
||||
|
||||
/**
|
||||
* Gets the class responsible for managing world generators plugins installed on the server.
|
||||
*
|
||||
* @return A valid {@link MVGeneratorManager}.
|
||||
*/
|
||||
MVGeneratorManager getMVGeneratorManager();
|
||||
|
||||
/**
|
||||
* Gets the primary class responsible for managing Multiverse Worlds.
|
||||
*
|
||||
@@ -126,38 +123,20 @@ public interface Core {
|
||||
AnchorManager getAnchorManager();
|
||||
|
||||
/**
|
||||
* Previously used by queued commands to regenerate a world on a delay.
|
||||
* Do not use api method for any other purpose.
|
||||
* Used by queued commands to regenerate a world on a delay.
|
||||
*
|
||||
* @param name Name of the world to regenerate
|
||||
* @param useNewSeed If a new seed should be used
|
||||
* @param randomSeed If the new seed should be random
|
||||
* @param seed The seed of the world.
|
||||
* @param name Name of the world to regenerate
|
||||
* @param useNewSeed If a new seed should be used
|
||||
* @param randomSeed IF the new seed should be random
|
||||
* @param seed The seed of the world.
|
||||
*
|
||||
* @return True if success, false if fail.
|
||||
*
|
||||
* @deprecated Use {@link MVWorldManager#regenWorld(String, boolean, boolean, String, boolean)} instead.
|
||||
* @deprecated Use {@link MVWorldManager#regenWorld(String, boolean, boolean, String)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
Boolean regenWorld(String name, Boolean useNewSeed, Boolean randomSeed, String seed);
|
||||
|
||||
/**
|
||||
* Used by queued commands to regenerate a world on a delay.
|
||||
* Do not use api method for any other purpose.
|
||||
*
|
||||
* @param name Name of the world to regenerate
|
||||
* @param useNewSeed If a new seed should be used
|
||||
* @param randomSeed If the new seed should be random
|
||||
* @param seed The seed of the world.
|
||||
* @param keepGameRules If GameRules should be kept on world regen.
|
||||
*
|
||||
* @return True if success, false if fail.
|
||||
*
|
||||
* @deprecated Use {@link MVWorldManager#regenWorld(String, boolean, boolean, String, boolean)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
Boolean regenWorld(String name, Boolean useNewSeed, Boolean randomSeed, String seed, Boolean keepGameRules);
|
||||
|
||||
/**
|
||||
* Decrements the number of plugins that have specifically hooked into core.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.onarandombox.MultiverseCore.api;
|
||||
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* <p>A generator API for Multiverse.</p>
|
||||
*
|
||||
* <p>Any generator plugin can register themselves to Multiverse. This will provide Multiverse with addition
|
||||
* information about your generator plugin such as generator id suggestions, example usages and link to more
|
||||
* info on your generator plugin.</p>
|
||||
*
|
||||
* <p>To register your plugin, implement this class and see {@link MVGeneratorManager#register(GeneratorPlugin)}.</p>
|
||||
*/
|
||||
public interface GeneratorPlugin {
|
||||
|
||||
/**
|
||||
* <p>Suggest possible generator ids. To be used in command tab-completion.</p>
|
||||
*
|
||||
* <p>These suggestions can be static without relying on currentIdInput, or dynamically changed based
|
||||
* on the currentIdInput.</p>
|
||||
*
|
||||
* @param currentIdInput The current state user input. This may be null or empty if user has not started
|
||||
* any input for generator id.
|
||||
* @return Collection of suggested generator ids.
|
||||
*/
|
||||
@NotNull
|
||||
Collection<String> suggestIds(@Nullable String currentIdInput);
|
||||
|
||||
/**
|
||||
* <p>Gets a default or any valid {@link ChunkGenerator}.</p>
|
||||
*
|
||||
* <p>This is used on {@link MVGeneratorManager#register(GeneratorPlugin)} to prove to Multiverse that
|
||||
* you are a valid generator plugin. If this returns null or throw an exception, your generator plugin
|
||||
* will not be registered.</p>
|
||||
*
|
||||
* @return A {@link ChunkGenerator} if possible, else null.
|
||||
* @throws Exception When an error occurs in getting {@link ChunkGenerator}.
|
||||
*/
|
||||
@Nullable
|
||||
ChunkGenerator getDefaultChunkGenerator() throws Exception;
|
||||
|
||||
/**
|
||||
* <p>Gets a chunk generator based on a world name and id specified.</p>
|
||||
*
|
||||
* <p>If this returns null or throw an exception, it will indicate to Multiverse that there is either an issue
|
||||
* with your plugin, or the generator id given is invalid.</p>
|
||||
*
|
||||
* @param id Target generator id.
|
||||
* @param worldName Target world name to use generator on.
|
||||
* @return A {@link ChunkGenerator} if possible, else null.
|
||||
* @throws Exception When an error occurs in getting a {@link ChunkGenerator}.
|
||||
*/
|
||||
@Nullable
|
||||
ChunkGenerator getChunkGenerator(String id, String worldName) throws Exception;
|
||||
|
||||
/**
|
||||
* <p>Gets command usages that users can try to generate a world with your generator plugin. Returning null means
|
||||
* you do not wish to show any usage examples for your generator plugin.</p>
|
||||
*
|
||||
* <p>An example command: '/mv create myworld normal -g CoolGen:FunWorld'</p>
|
||||
*
|
||||
* <p>Notes on usage of this method:</p>
|
||||
* <ul>
|
||||
* <li>Feel free to have colors in your command usage, but not Multiverse won't parse color codes for you.</li>
|
||||
* <li>Please include the starting slash '/' in your usage examples.</li>
|
||||
* <li>We suggest keeping the usage to at most 5 examples.</li>
|
||||
* <li>This should not be a full explanation on all your generator plugin, just basics usages to get people
|
||||
* started. For full guide, you can use {@link #getInfoLink()} to direct users.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return A collection of command usage examples.
|
||||
*/
|
||||
@Nullable
|
||||
Collection<String> getExampleUsages();
|
||||
|
||||
/**
|
||||
* <p>Gets a link with more information on your generator plugin. Returning null means you do not wish to link
|
||||
* users to any website related to your generator plugin.</p>
|
||||
*
|
||||
* <p>An example info: 'Click on https://www.amazinggenerator.io ;)'</p>
|
||||
*
|
||||
* <p>Some suggested places you can link to are: spigot resource page, github repo or your own plugin site.</p>
|
||||
*
|
||||
* @return Link to more info on your generator plugin.
|
||||
*/
|
||||
@Nullable
|
||||
String getInfoLink();
|
||||
|
||||
/**
|
||||
* Gets the java plugin for this generator. In short, return your own generator plugin instance.
|
||||
*
|
||||
* @return The associated plugin for this generator.
|
||||
*/
|
||||
@NotNull
|
||||
Plugin getPlugin();
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package com.onarandombox.MultiverseCore.api;
|
||||
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* API for handling generator plugins installed on the user's server.
|
||||
*/
|
||||
public interface MVGeneratorManager {
|
||||
|
||||
/**
|
||||
* Register a generator plugin.
|
||||
*
|
||||
* @param generatorPlugin The {@link GeneratorPlugin} to register.
|
||||
* @return True if successfully registered, else false.
|
||||
*/
|
||||
boolean register(@NotNull GeneratorPlugin generatorPlugin);
|
||||
|
||||
/**
|
||||
* Check if a given generator string is valid.
|
||||
*
|
||||
* @param genString The generator string to check on.
|
||||
* @param worldName The target world name to generate on.
|
||||
* @return True if valid, else false.
|
||||
*/
|
||||
boolean isValidGenerator(@NotNull String genString, @NotNull String worldName);
|
||||
|
||||
/**
|
||||
* Check if a given generator string is valid with reason of failure with {@link TestResult}.
|
||||
*
|
||||
* @param genString The generator string to check on.
|
||||
* @param worldName The target world name to generate on.
|
||||
* @return Result of the validation.
|
||||
*/
|
||||
@NotNull
|
||||
TestResult validateGenerator(@NotNull String genString, @NotNull String worldName);
|
||||
|
||||
/**
|
||||
* Checks if a plugin is a registered generator plugin.
|
||||
*
|
||||
* @param genPlugin The plugin to check on.
|
||||
* @return True if is valid, else false.
|
||||
*/
|
||||
boolean isGeneratorPlugin(@NotNull Plugin genPlugin);
|
||||
|
||||
/**
|
||||
* Checks if a plugin is a registered generator plugin.
|
||||
*
|
||||
* @param pluginName The plugin name to check on.
|
||||
* @return True if is valid, else false.
|
||||
*/
|
||||
boolean isGeneratorPlugin(@NotNull String pluginName);
|
||||
|
||||
/**
|
||||
* Gets the {@link GeneratorPlugin} for a given plugin if present.
|
||||
*
|
||||
* @param genPlugin The plugin that is associated to a {@link GeneratorPlugin}.
|
||||
* @return The {@link GeneratorPlugin} if present, else null.
|
||||
*/
|
||||
@Nullable
|
||||
GeneratorPlugin getGeneratorPlugin(@NotNull Plugin genPlugin);
|
||||
|
||||
/**
|
||||
* Gets the {@link GeneratorPlugin} for a given plugin if present.
|
||||
*
|
||||
* @param pluginName The plugin name that is associated to a {@link GeneratorPlugin}.
|
||||
* @return The {@link GeneratorPlugin} if present, else null.
|
||||
*/
|
||||
@Nullable
|
||||
GeneratorPlugin getGeneratorPlugin(@NotNull String pluginName);
|
||||
|
||||
/**
|
||||
* Gets all registered {@link GeneratorPlugin}.
|
||||
*
|
||||
* @return A collection of registered generator plugins.
|
||||
*/
|
||||
@NotNull
|
||||
Collection<GeneratorPlugin> getGeneratorPlugins();
|
||||
|
||||
/**
|
||||
* Gets all registered plugin names associate with {@link GeneratorPlugin}.
|
||||
*
|
||||
* @return A collection of registered generator plugin names.
|
||||
*/
|
||||
@NotNull
|
||||
Collection<String> getGeneratorPluginNames();
|
||||
|
||||
/**
|
||||
* Gets the default world generator string defined in 'bukkit.yml' for a given world.
|
||||
*
|
||||
* @param worldName The world to get default generator of.
|
||||
* @return The generator string if present, else null.
|
||||
*/
|
||||
@Nullable
|
||||
String getDefaultWorldGen(String worldName);
|
||||
|
||||
/**
|
||||
* Gets all the world generator strings defined in 'bukkit.yml'.
|
||||
*
|
||||
* @return Map if world names and its respective default world generator strings.
|
||||
*/
|
||||
@NotNull
|
||||
Map<String, String> getDefaultWorldGens();
|
||||
|
||||
/**
|
||||
* Results from validating a generator.
|
||||
*/
|
||||
enum TestResult {
|
||||
/**
|
||||
* Successfully got {@link ChunkGenerator} from the world generator plugin.
|
||||
*/
|
||||
VALID,
|
||||
|
||||
/**
|
||||
* Exceptions thrown while trying to get {@link ChunkGenerator} from the world generator plugin.
|
||||
*/
|
||||
ERRORS,
|
||||
|
||||
/**
|
||||
* Plugin is present on the server, but doesnt look like a world generator.
|
||||
*/
|
||||
INVALID_GENERATOR,
|
||||
|
||||
/**
|
||||
* Plugin not installed on the server.
|
||||
*/
|
||||
PLUGIN_DOES_NOT_EXIST
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
package com.onarandombox.MultiverseCore.api;
|
||||
|
||||
import com.onarandombox.MultiverseCore.generators.GeneratorManager;
|
||||
import com.onarandombox.MultiverseCore.utils.PurgeWorlds;
|
||||
import com.onarandombox.MultiverseCore.utils.SimpleWorldPurger;
|
||||
import org.bukkit.World;
|
||||
@@ -154,7 +155,9 @@ public interface MVWorldManager {
|
||||
* @param generatorID The generator id.
|
||||
* @param worldName The worldName to use as the default.
|
||||
* @return A {@link ChunkGenerator} or null
|
||||
* @deprecated Use {@link MVGeneratorManager#validateGenerator(String, String)}
|
||||
*/
|
||||
@Deprecated
|
||||
ChunkGenerator getChunkGenerator(String generator, String generatorID, String worldName);
|
||||
|
||||
/**
|
||||
@@ -174,16 +177,6 @@ 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.
|
||||
*
|
||||
@@ -193,24 +186,13 @@ public interface MVWorldManager {
|
||||
MultiverseWorld getMVWorld(World world);
|
||||
|
||||
/**
|
||||
* Checks to see if the given name is a valid {@link MultiverseWorld}
|
||||
* Searches based on world name AND alias.
|
||||
* Checks to see if the given name is a valid {@link MultiverseWorld}.
|
||||
*
|
||||
* @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}.
|
||||
*
|
||||
@@ -270,7 +252,9 @@ public interface MVWorldManager {
|
||||
|
||||
/**
|
||||
* This method populates an internal list and needs to be called after multiverse initialization.
|
||||
* @deprecated This is now done by {@link GeneratorManager}.
|
||||
*/
|
||||
@Deprecated
|
||||
void getDefaultWorldGenerators();
|
||||
|
||||
/**
|
||||
@@ -313,28 +297,15 @@ public interface MVWorldManager {
|
||||
/**
|
||||
* Regenerates a world.
|
||||
*
|
||||
* @param name Name of the world to regenerate
|
||||
* @param useNewSeed If a new seed should be used
|
||||
* @param randomSeed If the new seed should be random
|
||||
* @param seed The seed of the world.
|
||||
* @param name Name of the world to regenerate
|
||||
* @param useNewSeed If a new seed should be used
|
||||
* @param randomSeed IF the new seed should be random
|
||||
* @param seed The seed of the world.
|
||||
*
|
||||
* @return True if success, false if fail.
|
||||
*/
|
||||
boolean regenWorld(String name, boolean useNewSeed, boolean randomSeed, String seed);
|
||||
|
||||
/**
|
||||
* Regenerates a world.
|
||||
*
|
||||
* @param name Name of the world to regenerate
|
||||
* @param useNewSeed If a new seed should be used
|
||||
* @param randomSeed If the new seed should be random
|
||||
* @param seed The seed of the world.
|
||||
* @param keepGameRules If GameRules should be kept on world regen.
|
||||
*
|
||||
* @return True if success, false if fail.
|
||||
*/
|
||||
boolean regenWorld(String name, boolean useNewSeed, boolean randomSeed, String seed, boolean keepGameRules);
|
||||
|
||||
boolean isKeepingSpawnInMemory(World world);
|
||||
|
||||
/**
|
||||
@@ -348,11 +319,4 @@ 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();
|
||||
}
|
||||
@@ -239,8 +239,4 @@ public interface MultiverseCoreConfig extends ConfigurationSerializable {
|
||||
* @param idonotwanttodonate True if donation/patreon messages should be shown.
|
||||
*/
|
||||
void setShowDonateMessage(boolean idonotwanttodonate);
|
||||
|
||||
boolean isAllowUnsafeWorldName();
|
||||
|
||||
void setAllowUnsafeWorldName(boolean allowUnsafeWorldName);
|
||||
}
|
||||
@@ -33,7 +33,7 @@ public class ConfirmCommand extends MultiverseCommand {
|
||||
|
||||
@Override
|
||||
public void runCommand(CommandSender sender, List<String> args) {
|
||||
this.plugin.getCommandQueueManager().runQueuedCommand(sender);
|
||||
this.plugin.getCommandHandler().confirmQueuedCommand(sender);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,7 +9,7 @@ package com.onarandombox.MultiverseCore.commands;
|
||||
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import com.onarandombox.MultiverseCore.utils.WorldNameChecker;
|
||||
import com.onarandombox.MultiverseCore.api.MVGeneratorManager;
|
||||
import com.pneumaticraft.commandhandler.CommandHandler;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.World.Environment;
|
||||
@@ -18,8 +18,7 @@ import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -50,6 +49,7 @@ 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);
|
||||
@@ -66,19 +66,13 @@ public class CreateCommand extends MultiverseCommand {
|
||||
}
|
||||
}
|
||||
|
||||
if(!this.plugin.getMVConfig().isAllowUnsafeWorldName() && !WorldNameChecker.isValidWorldName(worldName)) {
|
||||
sender.sendMessage(ChatColor.RED + "Multiverse cannot create the world as the world name '"
|
||||
+ worldName + "' contains spaces or invalid characters!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.worldManager.isMVWorld(worldName)) {
|
||||
sender.sendMessage(ChatColor.RED + "Multiverse cannot create " + ChatColor.GOLD + ChatColor.UNDERLINE
|
||||
+ "another" + ChatColor.RESET + ChatColor.RED + " world named " + worldName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (WorldNameChecker.checkFolder(worldName) != WorldNameChecker.FolderStatus.DOES_NOT_EXIST) {
|
||||
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");
|
||||
return;
|
||||
@@ -103,14 +97,26 @@ public class CreateCommand extends MultiverseCommand {
|
||||
}
|
||||
// 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) {
|
||||
MVGeneratorManager.TestResult result = this.plugin.getMVGeneratorManager().validateGenerator(generator, worldName);
|
||||
if (result != MVGeneratorManager.TestResult.VALID) {
|
||||
// We have an invalid generator.
|
||||
sender.sendMessage("Invalid generator! '" + generator + "'. " + ChatColor.RED + "Aborting world creation.");
|
||||
switch (result) {
|
||||
case ERRORS:
|
||||
sender.sendMessage("An issue occurred while validating generator string '" + generator +
|
||||
"'! This may indicate an issue with your generator plugin or an invalid generator id. Check console for errors!");
|
||||
break;
|
||||
case INVALID_GENERATOR:
|
||||
sender.sendMessage("Invalid generator string '" + generator +
|
||||
"'! The generator id you use is probably not supported by your generator plugin.");
|
||||
break;
|
||||
case PLUGIN_DOES_NOT_EXIST:
|
||||
sender.sendMessage("That generator plugin is not installed on your server!");
|
||||
break;
|
||||
default:
|
||||
sender.sendMessage("Invalid generator string '" + generator + "'!");
|
||||
break;
|
||||
}
|
||||
sender.sendMessage(ChatColor.RED + "Aborting world creation...");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -122,4 +128,4 @@ public class CreateCommand extends MultiverseCommand {
|
||||
Command.broadcastCommandMessage(sender, "FAILED.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,9 @@
|
||||
package com.onarandombox.MultiverseCore.commands;
|
||||
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.commandtools.queue.QueuedCommand;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -37,24 +35,11 @@ public class DeleteCommand extends MultiverseCommand {
|
||||
public void runCommand(CommandSender sender, List<String> args) {
|
||||
String worldName = args.get(0);
|
||||
|
||||
this.plugin.getCommandQueueManager().addToQueue(new QueuedCommand(
|
||||
sender,
|
||||
deleteRunnable(sender, worldName),
|
||||
String.format("Are you sure you want to delete world '%s'? You cannot undo this action.", worldName)
|
||||
));
|
||||
}
|
||||
|
||||
private Runnable deleteRunnable(@NotNull CommandSender sender,
|
||||
@NotNull String worldName) {
|
||||
|
||||
return () -> {
|
||||
sender.sendMessage(String.format("Deleting world '%s'...", worldName));
|
||||
if (this.plugin.getMVWorldManager().deleteWorld(worldName)) {
|
||||
sender.sendMessage(String.format("%sWorld %s was deleted!", ChatColor.GREEN, worldName));
|
||||
return;
|
||||
}
|
||||
sender.sendMessage(String.format("%sThere was an issue deleting '%s'! Please check console for errors.",
|
||||
ChatColor.RED, worldName));
|
||||
};
|
||||
Class<?>[] paramTypes = {String.class};
|
||||
List<Object> objectArgs = new ArrayList<Object>(args);
|
||||
this.plugin.getCommandHandler()
|
||||
.queueCommand(sender, "mvdelete", "deleteWorld", objectArgs,
|
||||
paramTypes, ChatColor.GREEN + "World '" + worldName + "' Deleted!",
|
||||
ChatColor.RED + "World '" + worldName + "' could NOT be deleted!");
|
||||
}
|
||||
}
|
||||
@@ -9,12 +9,19 @@ package com.onarandombox.MultiverseCore.commands;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.GeneratorPlugin;
|
||||
import com.onarandombox.MultiverseCore.generators.SimpleGeneratorPlugin;
|
||||
import net.milkbowl.vault.chat.Chat;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -25,36 +32,70 @@ public class GeneratorCommand extends MultiverseCommand {
|
||||
public GeneratorCommand(MultiverseCore plugin) {
|
||||
super(plugin);
|
||||
this.setName("World Information");
|
||||
this.setCommandUsage("/mv generators");
|
||||
this.setArgRange(0, 0);
|
||||
this.setCommandUsage("/mv generators [plugin]");
|
||||
this.setArgRange(0, 1);
|
||||
this.addKey("mv generators");
|
||||
this.addKey("mvgenerators");
|
||||
this.addKey("mv gens");
|
||||
this.addKey("mvgens");
|
||||
this.addCommandExample("/mv generators");
|
||||
this.setPermission("multiverse.core.generator", "Returns a list of Loaded Generator Plugins.", PermissionDefault.OP);
|
||||
this.addCommandExample("/mv generators VoidGenerator");
|
||||
this.setPermission("multiverse.core.generator", "Returns info of Loaded Generator Plugins.", PermissionDefault.OP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runCommand(CommandSender sender, List<String> args) {
|
||||
Logging.info("PLEASE IGNORE the 'Plugin X does not contain any generators' message below!");
|
||||
Plugin[] plugins = this.plugin.getServer().getPluginManager().getPlugins();
|
||||
List<String> generators = new ArrayList<String>();
|
||||
for (Plugin p : plugins) {
|
||||
if (p.isEnabled() && p.getDefaultWorldGenerator("world", "") != null) {
|
||||
generators.add(p.getDescription().getName());
|
||||
}
|
||||
if (args.size() == 0) {
|
||||
listKnownGenerators(sender);
|
||||
return;
|
||||
}
|
||||
showGeneratorDetails(sender, args.get(0));
|
||||
}
|
||||
|
||||
private void listKnownGenerators(CommandSender sender) {
|
||||
sender.sendMessage(ChatColor.AQUA + "--- Loaded Generator Plugins ---");
|
||||
String loadedGens = "";
|
||||
StringBuilder loadedGens = new StringBuilder();
|
||||
boolean altColor = false;
|
||||
for (String s : generators) {
|
||||
loadedGens += (altColor ? ChatColor.YELLOW : ChatColor.WHITE) + s + " ";
|
||||
for (String s : this.plugin.getMVGeneratorManager().getGeneratorPluginNames()) {
|
||||
loadedGens.append(altColor ? ChatColor.YELLOW : ChatColor.WHITE).append(s).append(' ');
|
||||
altColor = !altColor;
|
||||
}
|
||||
if (loadedGens.length() == 0) {
|
||||
loadedGens = ChatColor.RED + "No Generator Plugins found.";
|
||||
loadedGens.append(ChatColor.RED).append("No Generator Plugins found.");
|
||||
}
|
||||
sender.sendMessage(loadedGens.toString());
|
||||
}
|
||||
|
||||
private void showGeneratorDetails(CommandSender sender, String pluginName) {
|
||||
Plugin genPlugin = Bukkit.getPluginManager().getPlugin(pluginName);
|
||||
if (genPlugin == null) {
|
||||
sender.sendMessage(ChatColor.RED + "You do not have a plugin named '"+ pluginName + "' on your server.");
|
||||
return;
|
||||
}
|
||||
|
||||
GeneratorPlugin generatorPlugin = this.plugin.getMVGeneratorManager().getGeneratorPlugin(genPlugin);
|
||||
if (generatorPlugin == null) {
|
||||
sender.sendMessage(ChatColor.RED + "'" + pluginName + "' does not look like a generator plugin.");
|
||||
return;
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.AQUA + "--- Info on " + generatorPlugin.getPlugin().getName() + " ---");
|
||||
boolean hasAddInfo = false;
|
||||
|
||||
Collection<String> exampleUsages = generatorPlugin.getExampleUsages();
|
||||
if (exampleUsages != null && exampleUsages.size() > 0) {
|
||||
hasAddInfo = true;
|
||||
sender.sendMessage("Usages:");
|
||||
exampleUsages.forEach(sender::sendMessage);
|
||||
}
|
||||
String infoLink = generatorPlugin.getInfoLink();
|
||||
if (infoLink != null) {
|
||||
hasAddInfo = true;
|
||||
sender.sendMessage("More Info: " + infoLink);
|
||||
}
|
||||
|
||||
if (!hasAddInfo) {
|
||||
sender.sendMessage(ChatColor.RED + "'" + pluginName + "' did not provide additional info to Multiverse.");
|
||||
}
|
||||
sender.sendMessage(loadedGens);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +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;
|
||||
@@ -17,6 +18,9 @@ import org.bukkit.command.Command;
|
||||
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;
|
||||
|
||||
@@ -42,25 +46,46 @@ public class ImportCommand extends MultiverseCommand {
|
||||
this.worldManager = this.plugin.getMVWorldManager();
|
||||
}
|
||||
|
||||
private String getPotentialWorldStrings() {
|
||||
final Collection<String> potentialWorlds = this.worldManager.getPotentialWorlds();
|
||||
StringBuilder worldList = new StringBuilder();
|
||||
ChatColor currColor = ChatColor.WHITE;
|
||||
|
||||
for (String world : potentialWorlds) {
|
||||
worldList.append(currColor).append(world).append(' ');
|
||||
currColor = currColor == ChatColor.WHITE ? ChatColor.YELLOW : ChatColor.WHITE;
|
||||
private String getPotentialWorlds() {
|
||||
File worldFolder = this.plugin.getServer().getWorldContainer();
|
||||
if (worldFolder == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return worldList.toString();
|
||||
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);
|
||||
}
|
||||
ChatColor currColor = ChatColor.WHITE;
|
||||
for (File file : files) {
|
||||
if (file.isDirectory() && WorldNameChecker.isValidWorldFolder(file) && !worldStrings.contains(file.getName())) {
|
||||
worldList += currColor + file.getName() + " ";
|
||||
if (currColor == ChatColor.WHITE) {
|
||||
currColor = ChatColor.YELLOW;
|
||||
} else {
|
||||
currColor = ChatColor.WHITE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return worldList;
|
||||
}
|
||||
|
||||
private String trimWorldName(String userInput) {
|
||||
// Removes relative paths.
|
||||
return userInput.replaceAll("^[./\\\\]+", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runCommand(CommandSender sender, List<String> args) {
|
||||
String worldName = args.get(0);
|
||||
String worldName = trimWorldName(args.get(0));
|
||||
|
||||
if (worldName.toLowerCase().equals("--list") || worldName.toLowerCase().equals("-l")) {
|
||||
String worldList = this.getPotentialWorldStrings();
|
||||
String worldList = this.getPotentialWorlds();
|
||||
if (worldList.length() > 2) {
|
||||
sender.sendMessage(ChatColor.AQUA + "====[ These look like worlds ]====");
|
||||
sender.sendMessage(worldList);
|
||||
@@ -75,12 +100,6 @@ public class ImportCommand extends MultiverseCommand {
|
||||
this.showHelp(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!this.plugin.getMVConfig().isAllowUnsafeWorldName() && !WorldNameChecker.isValidWorldName(worldName)) {
|
||||
sender.sendMessage(ChatColor.RED + "Multiverse cannot import the world as the world name '"
|
||||
+ worldName + "' contains spaces or invalid characters!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure we don't already know about this world.
|
||||
if (this.worldManager.isMVWorld(worldName)) {
|
||||
@@ -89,18 +108,7 @@ public class ImportCommand extends MultiverseCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (WorldNameChecker.checkFolder(worldName)) {
|
||||
case DOES_NOT_EXIST:
|
||||
sender.sendMessage(ChatColor.RED + "FAILED.");
|
||||
sender.sendMessage(ChatColor.RED + "That world folder does not exist. These look like worlds to me:");
|
||||
sender.sendMessage(this.getPotentialWorldStrings());
|
||||
return;
|
||||
case NOT_A_WORLD:
|
||||
sender.sendMessage(ChatColor.RED + "FAILED.");
|
||||
sender.sendMessage(String.format("%s'%s' does not appear to be a world. It is lacking a .dat file.",
|
||||
ChatColor.RED, worldName));
|
||||
return;
|
||||
}
|
||||
File worldFile = new File(this.plugin.getServer().getWorldContainer(), worldName);
|
||||
|
||||
String generator = CommandHandler.getFlag("-g", args);
|
||||
boolean useSpawnAdjust = true;
|
||||
@@ -118,18 +126,25 @@ public class ImportCommand extends MultiverseCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
if (env == null) {
|
||||
if (!worldFile.exists()) {
|
||||
sender.sendMessage(ChatColor.RED + "FAILED.");
|
||||
String worldList = this.getPotentialWorlds();
|
||||
sender.sendMessage("That world folder does not exist. These look like worlds to me:");
|
||||
sender.sendMessage(worldList);
|
||||
} 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));
|
||||
} else if (env == null) {
|
||||
sender.sendMessage(ChatColor.RED + "FAILED.");
|
||||
sender.sendMessage("That world environment did not exist.");
|
||||
sender.sendMessage("For a list of available world types, type: " + ChatColor.AQUA + "/mvenv");
|
||||
return;
|
||||
}
|
||||
|
||||
Command.broadcastCommandMessage(sender, String.format("Starting import of world '%s'...", worldName));
|
||||
if (this.worldManager.addWorld(worldName, environment, null, null, null, generator, useSpawnAdjust)) {
|
||||
Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Complete!");
|
||||
} else {
|
||||
Command.broadcastCommandMessage(sender, ChatColor.RED + "Failed!");
|
||||
Command.broadcastCommandMessage(sender, String.format("Starting import of world '%s'...", worldName));
|
||||
if (this.worldManager.addWorld(worldName, environment, null, null, null, generator, useSpawnAdjust))
|
||||
Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Complete!");
|
||||
else
|
||||
Command.broadcastCommandMessage(sender, ChatColor.RED + "Failed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,13 +8,11 @@
|
||||
package com.onarandombox.MultiverseCore.commands;
|
||||
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.commandtools.queue.QueuedCommand;
|
||||
import com.pneumaticraft.commandhandler.CommandHandler;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -25,8 +23,8 @@ public class RegenCommand extends MultiverseCommand {
|
||||
public RegenCommand(MultiverseCore plugin) {
|
||||
super(plugin);
|
||||
this.setName("Regenerates a World");
|
||||
this.setCommandUsage("/mv regen" + ChatColor.GREEN + " {WORLD}" + ChatColor.GOLD + " [-s [SEED]] [--keep-gamerules]");
|
||||
this.setArgRange(1, 4);
|
||||
this.setCommandUsage("/mv regen" + ChatColor.GREEN + " {WORLD}" + ChatColor.GOLD + " [-s [SEED]]");
|
||||
this.setArgRange(1, 3);
|
||||
this.addKey("mvregen");
|
||||
this.addKey("mv regen");
|
||||
this.addCommandExample("You can use the -s with no args to get a new seed:");
|
||||
@@ -39,31 +37,17 @@ public class RegenCommand extends MultiverseCommand {
|
||||
|
||||
@Override
|
||||
public void runCommand(CommandSender sender, List<String> args) {
|
||||
String worldName = args.get(0);
|
||||
boolean useseed = (!(args.size() == 1));
|
||||
boolean randomseed = (args.size() == 2 && args.get(1).equalsIgnoreCase("-s"));
|
||||
Boolean useseed = (!(args.size() == 1));
|
||||
Boolean randomseed = (args.size() == 2 && args.get(1).equalsIgnoreCase("-s"));
|
||||
String seed = (args.size() == 3) ? args.get(2) : "";
|
||||
boolean keepGamerules = CommandHandler.hasFlag("--keep-gamerules", args);
|
||||
this.plugin.getCommandQueueManager().addToQueue(new QueuedCommand(
|
||||
sender,
|
||||
doWorldRegen(sender, worldName, useseed, randomseed, seed, keepGamerules),
|
||||
String.format("Are you sure you want to regen '%s'? You cannot undo this action.", worldName)
|
||||
));
|
||||
}
|
||||
|
||||
private Runnable doWorldRegen(@NotNull CommandSender sender,
|
||||
@NotNull String worldName,
|
||||
boolean useSeed,
|
||||
boolean randomSeed,
|
||||
@NotNull String seed,
|
||||
boolean keepGamerules) {
|
||||
|
||||
return () -> {
|
||||
if (this.plugin.getMVWorldManager().regenWorld(worldName, useSeed, randomSeed, seed, keepGamerules)) {
|
||||
sender.sendMessage(ChatColor.GREEN + "World Regenerated!");
|
||||
return;
|
||||
}
|
||||
sender.sendMessage(ChatColor.RED + "World could NOT be regenerated!");
|
||||
};
|
||||
Class<?>[] paramTypes = {String.class, Boolean.class, Boolean.class, String.class};
|
||||
List<Object> objectArgs = new ArrayList<Object>();
|
||||
objectArgs.add(args.get(0));
|
||||
objectArgs.add(useseed);
|
||||
objectArgs.add(randomseed);
|
||||
objectArgs.add(seed);
|
||||
this.plugin.getCommandHandler().queueCommand(sender, "mvregen", "regenWorld", objectArgs,
|
||||
paramTypes, ChatColor.GREEN + "World Regenerated!", ChatColor.RED + "World could NOT be regenerated!");
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,6 @@ import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.Teleporter;
|
||||
import com.onarandombox.MultiverseCore.api.MVDestination;
|
||||
import com.onarandombox.MultiverseCore.commandtools.queue.QueuedCommand;
|
||||
import com.onarandombox.MultiverseCore.destination.CustomTeleporterDestination;
|
||||
import com.onarandombox.MultiverseCore.destination.DestinationFactory;
|
||||
import com.onarandombox.MultiverseCore.destination.InvalidDestination;
|
||||
@@ -153,27 +152,24 @@ public class TeleportCommand extends MultiverseCommand {
|
||||
if (result == TeleportResult.FAIL_UNSAFE) {
|
||||
Logging.fine("Could not teleport " + teleportee.getName()
|
||||
+ " to " + plugin.getLocationManipulation().strCoordsRaw(d.getLocation(teleportee)));
|
||||
|
||||
Logging.fine("Queueing Command");
|
||||
Class<?>[] paramTypes = { CommandSender.class, Player.class, Location.class };
|
||||
List<Object> items = new ArrayList<Object>();
|
||||
items.add(teleporter);
|
||||
items.add(teleportee);
|
||||
items.add(d.getLocation(teleportee));
|
||||
String player = "you";
|
||||
if (!teleportee.equals(teleporter)) {
|
||||
player = teleportee.getName();
|
||||
}
|
||||
|
||||
this.plugin.getCommandQueueManager().addToQueue(new QueuedCommand(
|
||||
sender,
|
||||
doUnsafeTeleport(teleporter, teleportee, d.getLocation(teleportee)),
|
||||
String.format("%sMultiverse %sdid not teleport %s%s %sto %s%s %sbecause it was unsafe. Would you like to try anyway?",
|
||||
ChatColor.GREEN, ChatColor.WHITE, ChatColor.AQUA, player, ChatColor.WHITE, ChatColor.DARK_AQUA, d.getName(), ChatColor.WHITE),
|
||||
UNSAFE_TELEPORT_EXPIRE_DELAY
|
||||
));
|
||||
String message = String.format("%sMultiverse %sdid not teleport %s%s %sto %s%s %sbecause it was unsafe.",
|
||||
ChatColor.GREEN, ChatColor.WHITE, ChatColor.AQUA, player, ChatColor.WHITE, ChatColor.DARK_AQUA, d.getName(), ChatColor.WHITE);
|
||||
this.plugin.getCommandHandler().queueCommand(sender, "mvteleport", "teleportPlayer", items,
|
||||
paramTypes, message, "Would you like to try anyway?", "", "", UNSAFE_TELEPORT_EXPIRE_DELAY);
|
||||
}
|
||||
// else: Player was teleported successfully (or the tp event was fired I should say)
|
||||
}
|
||||
|
||||
private Runnable doUnsafeTeleport(CommandSender teleporter, Player player, Location location) {
|
||||
return () -> this.plugin.getSafeTTeleporter().safelyTeleport(teleporter, player, location, false);
|
||||
}
|
||||
|
||||
private boolean checkSendPermissions(CommandSender teleporter, Player teleportee, MVDestination destination) {
|
||||
if (teleporter.equals(teleportee)) {
|
||||
if (!this.plugin.getMVPerms().hasPermission(teleporter, "multiverse.teleport.self." + destination.getIdentifier(), true)) {
|
||||
|
||||
-158
@@ -1,158 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Multiverse 2 Copyright (c) the Multiverse Team 2020. *
|
||||
* Multiverse 2 is licensed under the BSD License. *
|
||||
* For more information please check the README.md file included *
|
||||
* with this project. *
|
||||
******************************************************************************/
|
||||
|
||||
package com.onarandombox.MultiverseCore.commandtools.queue;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.block.data.type.CommandBlock;
|
||||
import org.bukkit.command.BlockCommandSender;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* Managers the queuing of dangerous commands that needs to use '/mv confirm' before executing.
|
||||
*/
|
||||
public class CommandQueueManager {
|
||||
|
||||
private static final long TICKS_PER_SECOND = 20;
|
||||
private static final DummyCommandBlockSender COMMAND_BLOCK = new DummyCommandBlockSender();
|
||||
|
||||
private final MultiverseCore plugin;
|
||||
private final Map<CommandSender, QueuedCommand> queuedCommandMap;
|
||||
|
||||
public CommandQueueManager(@NotNull MultiverseCore plugin) {
|
||||
this.plugin = plugin;
|
||||
this.queuedCommandMap = new WeakHashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a queue command into queue.
|
||||
*
|
||||
* @param queuedCommand The queue command to add.
|
||||
*/
|
||||
public void addToQueue(QueuedCommand queuedCommand) {
|
||||
CommandSender targetSender = parseSender(queuedCommand.getSender());
|
||||
|
||||
// Since only one command is stored in queue per sender, we remove the old one.
|
||||
this.removeFromQueue(targetSender);
|
||||
|
||||
Logging.finer("Add new command to queue for sender %s.", targetSender);
|
||||
this.queuedCommandMap.put(targetSender, queuedCommand);
|
||||
queuedCommand.setExpireTask(runExpireLater(queuedCommand));
|
||||
|
||||
queuedCommand.getSender().sendMessage(queuedCommand.getPrompt());
|
||||
queuedCommand.getSender().sendMessage(String.format("Run %s/mv confirm %sto continue. This will expire in %s seconds.",
|
||||
ChatColor.GREEN, ChatColor.WHITE, queuedCommand.getValidDuration()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Expire task that remove {@link QueuedCommand} from queue after valid duration defined.
|
||||
*
|
||||
* @param queuedCommand Command to run the expire task on.
|
||||
* @return The expire {@link BukkitTask}.
|
||||
*/
|
||||
@NotNull
|
||||
private BukkitTask runExpireLater(@NotNull QueuedCommand queuedCommand) {
|
||||
return Bukkit.getScheduler().runTaskLater(
|
||||
this.plugin,
|
||||
expireRunnable(queuedCommand),
|
||||
queuedCommand.getValidDuration() * TICKS_PER_SECOND
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runnable responsible for expiring the queued command.
|
||||
*
|
||||
* @param queuedCommand Command to create the expire task on.
|
||||
* @return The expire runnable.
|
||||
*/
|
||||
@NotNull
|
||||
private Runnable expireRunnable(@NotNull QueuedCommand queuedCommand) {
|
||||
return () -> {
|
||||
CommandSender targetSender = parseSender(queuedCommand.getSender());
|
||||
QueuedCommand matchingQueuedCommand = this.queuedCommandMap.get(targetSender);
|
||||
if (!queuedCommand.equals(matchingQueuedCommand) || queuedCommand.getExpireTask().isCancelled()) {
|
||||
// To be safe, but this shouldn't happen since we cancel old commands before add new once.
|
||||
Logging.finer("This is an old queue command already.");
|
||||
return;
|
||||
}
|
||||
queuedCommand.getSender().sendMessage("Your queued command has expired.");
|
||||
this.queuedCommandMap.remove(queuedCommand.getSender());
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the command in queue for the given sender, if any.
|
||||
*
|
||||
* @param sender {@link CommandSender} that confirmed the command.
|
||||
* @return True if queued command ran successfully, else false.
|
||||
*/
|
||||
public boolean runQueuedCommand(@NotNull CommandSender sender) {
|
||||
CommandSender targetSender = parseSender(sender);
|
||||
QueuedCommand queuedCommand = this.queuedCommandMap.get(targetSender);
|
||||
if (queuedCommand == null) {
|
||||
sender.sendMessage(ChatColor.RED + "You do not have any commands in queue.");
|
||||
return false;
|
||||
}
|
||||
Logging.finer("Running queued command...");
|
||||
queuedCommand.getAction().run();
|
||||
return removeFromQueue(targetSender);
|
||||
}
|
||||
|
||||
/**
|
||||
* Since only one command is stored in queue per sender, we remove the old one.
|
||||
*
|
||||
* @param sender The {@link CommandSender} that executed the command.
|
||||
* @return True if queue command is removed from sender successfully, else false.
|
||||
*/
|
||||
public boolean removeFromQueue(@NotNull CommandSender sender) {
|
||||
CommandSender targetSender = parseSender(sender);
|
||||
QueuedCommand previousCommand = this.queuedCommandMap.remove(targetSender);
|
||||
if (previousCommand == null) {
|
||||
Logging.finer("No queue command to remove for sender %s.", targetSender.getName());
|
||||
return false;
|
||||
}
|
||||
previousCommand.getExpireTask().cancel();
|
||||
Logging.finer("Removed queue command for sender %s.", targetSender.getName());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* To allow all CommandBlocks to be a common sender with use of {@link DummyCommandBlockSender}.
|
||||
* So confirm command can be used for a queue command on another command block.
|
||||
*
|
||||
* @param sender The sender to parse.
|
||||
* @return The sender, or if its a command block, a {@link DummyCommandBlockSender}.
|
||||
*/
|
||||
@NotNull
|
||||
private CommandSender parseSender(@NotNull CommandSender sender) {
|
||||
Logging.fine(sender.getClass().getName());
|
||||
if (isCommandBlock(sender)) {
|
||||
Logging.finer("Is command block.");
|
||||
return COMMAND_BLOCK;
|
||||
}
|
||||
return sender;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if sender is a command block.
|
||||
*
|
||||
* @param sender The sender to check on.
|
||||
* @return True if sender is a command block, else false.
|
||||
*/
|
||||
private boolean isCommandBlock(@NotNull CommandSender sender) {
|
||||
return sender instanceof BlockCommandSender
|
||||
&& ((BlockCommandSender) sender).getBlock().getBlockData() instanceof CommandBlock;
|
||||
}
|
||||
}
|
||||
-104
@@ -1,104 +0,0 @@
|
||||
package com.onarandombox.MultiverseCore.commandtools.queue;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionAttachment;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Used by {@link CommandQueueManager}, so different commands block can be recognised as one.
|
||||
*/
|
||||
class DummyCommandBlockSender implements CommandSender {
|
||||
|
||||
@Override
|
||||
public void sendMessage(@NotNull String message) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(@NotNull String[] messages) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Server getServer() {
|
||||
return Bukkit.getServer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return "DummyCommandBlockSender";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPermissionSet(@NotNull String name) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPermissionSet(@NotNull Permission perm) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull String name) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull Permission perm) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull PermissionAttachment addAttachment(@NotNull Plugin plugin, @NotNull String name, boolean value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull PermissionAttachment addAttachment(@NotNull Plugin plugin) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable PermissionAttachment addAttachment(@NotNull Plugin plugin, @NotNull String name, boolean value, int ticks) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable PermissionAttachment addAttachment(@NotNull Plugin plugin, int ticks) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttachment(@NotNull PermissionAttachment attachment) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recalculatePermissions() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Set<PermissionAttachmentInfo> getEffectivePermissions() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOp(boolean value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Multiverse 2 Copyright (c) the Multiverse Team 2020. *
|
||||
* Multiverse 2 is licensed under the BSD License. *
|
||||
* For more information please check the README.md file included *
|
||||
* with this project. *
|
||||
******************************************************************************/
|
||||
|
||||
package com.onarandombox.MultiverseCore.commandtools.queue;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Represents a single command used in {@link CommandQueueManager} for confirming before running potentially
|
||||
* dangerous action.
|
||||
*/
|
||||
public class QueuedCommand {
|
||||
|
||||
private static final String DEFAULT_PROMPT_MESSAGE = "The command you are trying to run is deemed dangerous.";
|
||||
private static final int DEFAULT_VALID_TIME = 10;
|
||||
|
||||
private final CommandSender sender;
|
||||
private final Runnable action;
|
||||
private final String prompt;
|
||||
private final int validDuration;
|
||||
private BukkitTask expireTask;
|
||||
|
||||
public QueuedCommand(CommandSender sender, Runnable action) {
|
||||
this(sender, action, DEFAULT_PROMPT_MESSAGE, DEFAULT_VALID_TIME);
|
||||
}
|
||||
|
||||
public QueuedCommand(CommandSender sender, Runnable action, String prompt) {
|
||||
this(sender, action, prompt, DEFAULT_VALID_TIME);
|
||||
}
|
||||
|
||||
public QueuedCommand(CommandSender sender, Runnable action, int validDuration) {
|
||||
this(sender, action, DEFAULT_PROMPT_MESSAGE, validDuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new queue command, to be registered at {@link CommandQueueManager#addToQueue(QueuedCommand)}.
|
||||
*
|
||||
* @param sender The sender that ran the command needed for confirmation.
|
||||
* @param action The logic to execute upon confirming.
|
||||
* @param prompt Question to ask sender to confirm.
|
||||
* @param validDuration Duration in which the command is valid for confirm in seconds.
|
||||
*/
|
||||
public QueuedCommand(CommandSender sender, Runnable action, String prompt, int validDuration) {
|
||||
this.sender = sender;
|
||||
this.action = action;
|
||||
this.prompt = prompt;
|
||||
this.validDuration = validDuration;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
CommandSender getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
String getPrompt() {
|
||||
return prompt;
|
||||
}
|
||||
|
||||
int getValidDuration() {
|
||||
return validDuration;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
Runnable getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
BukkitTask getExpireTask() {
|
||||
return expireTask;
|
||||
}
|
||||
|
||||
void setExpireTask(@NotNull BukkitTask expireTask) {
|
||||
if (this.expireTask != null) {
|
||||
throw new IllegalStateException("This queue command already has an expire task. You can't register twice!");
|
||||
}
|
||||
this.expireTask = expireTask;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
/**
|
||||
* Manager queuing of dangerous commands in need of confirmation.
|
||||
*/
|
||||
package com.onarandombox.MultiverseCore.commandtools.queue;
|
||||
@@ -21,15 +21,12 @@ 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.
|
||||
*/
|
||||
/** 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]+)?");
|
||||
@@ -167,13 +164,4 @@ public class DestinationFactory {
|
||||
this.teleportCommand.addAdditonalPermission(other);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the {@link MVDestination} identifiers registered.
|
||||
*
|
||||
* @return A collection of destination identifiers.
|
||||
*/
|
||||
public Collection<String> getRegisteredIdentifiers() {
|
||||
return this.destList.keySet();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
package com.onarandombox.MultiverseCore.generators;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.GeneratorPlugin;
|
||||
import com.onarandombox.MultiverseCore.api.MVGeneratorManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.event.server.PluginEnableEvent;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link MVGeneratorManager} to facilitate the detection and management of generator
|
||||
* plugins installed on user's server.
|
||||
*/
|
||||
public class GeneratorManager implements MVGeneratorManager {
|
||||
|
||||
private final MultiverseCore plugin;
|
||||
private final Map<String, String> defaultGens;
|
||||
private Map<String, GeneratorPlugin> generatorPluginMap;
|
||||
|
||||
public GeneratorManager(MultiverseCore plugin) {
|
||||
this.plugin = plugin;
|
||||
this.defaultGens = new HashMap<>();
|
||||
loadDefaultWorldGenerators();
|
||||
findAndRegisterAllGeneratorPlugins();
|
||||
Bukkit.getPluginManager().registerEvents(new GeneratorListener(), this.plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads default generator strings defined in 'bukkit.yml'.
|
||||
*/
|
||||
private void loadDefaultWorldGenerators() {
|
||||
this.generatorPluginMap = new HashMap<>();
|
||||
|
||||
File[] files = this.plugin.getServerFolder().listFiles((file, s) -> s.equalsIgnoreCase("bukkit.yml"));
|
||||
if (files == null || files.length != 1) {
|
||||
Logging.fine("Could not read 'bukkit.yml'. Any Default worldgenerators will not be loaded!");
|
||||
return;
|
||||
}
|
||||
|
||||
FileConfiguration bukkitConfig = YamlConfiguration.loadConfiguration(files[0]);
|
||||
if (!bukkitConfig.isConfigurationSection("worlds")) {
|
||||
Logging.fine("'bukkit.yml' missing worlds config section. No default generators found!");
|
||||
return;
|
||||
}
|
||||
|
||||
Set<String> keys = bukkitConfig.getConfigurationSection("worlds").getKeys(false);
|
||||
for (String key : keys) {
|
||||
this.defaultGens.put(key, bukkitConfig.getString("worlds." + key + ".generator", ""));
|
||||
}
|
||||
|
||||
this.generatorPluginMap = Collections.unmodifiableMap(this.generatorPluginMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register all generator plugins detected.
|
||||
*/
|
||||
private void findAndRegisterAllGeneratorPlugins() {
|
||||
Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(this::register);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to register a plugin as {@link SimpleGeneratorPlugin}.
|
||||
*
|
||||
* @param genPlugin The plugin to register.
|
||||
* @return True if registered successfully, else false.
|
||||
*/
|
||||
private boolean register(@NotNull Plugin genPlugin) {
|
||||
return this.register(genPlugin, SimpleGeneratorPlugin.DEFAULT_TEST_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to register a plugin as {@link SimpleGeneratorPlugin}.
|
||||
*
|
||||
* @param genPlugin The plugin to register.
|
||||
* @param id Generator Id to test for valid chunk generator.
|
||||
* @return True if registered successfully, else false.
|
||||
*/
|
||||
private boolean register(@NotNull Plugin genPlugin, String id) {
|
||||
Logging.finer("Attempting to register %s as a generator...", genPlugin.getName());
|
||||
if (this.isGeneratorPlugin(genPlugin)) {
|
||||
return false;
|
||||
}
|
||||
if (!simpleTestGen(genPlugin, id)) {
|
||||
Logging.finer("%s is probably not a generator plugin!", genPlugin.getName());
|
||||
return false;
|
||||
}
|
||||
this.generatorPluginMap.put(genPlugin.getName(), new SimpleGeneratorPlugin(genPlugin));
|
||||
Logging.finer("Registered %s as a simple generator plugin.", genPlugin.getName());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic test to see if plugin is a valid generator.
|
||||
*
|
||||
* @param generator The potential generator plugin.
|
||||
* @param id Generator Id to test for valid chunk generator.
|
||||
* @return True if plugin is a valid generator, else false.
|
||||
*/
|
||||
private boolean simpleTestGen(@Nullable Plugin generator, String id) {
|
||||
if (generator == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Since we are unsure if the plugin is even suppose to be a generator, we assume any error means its
|
||||
// not a generator plugin.
|
||||
try {
|
||||
return generator.getDefaultWorldGenerator(SimpleGeneratorPlugin.TEST_WORLDNAME, id) != null;
|
||||
} catch (Exception ignore) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters a plugin.
|
||||
*
|
||||
* @param genPlugin The plugin to unregister.
|
||||
* @return True if the plugin was present and now unregistered, else false.
|
||||
*/
|
||||
private boolean unregister(@NotNull Plugin genPlugin) {
|
||||
return this.generatorPluginMap.remove(genPlugin.getName()) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean register(@NotNull GeneratorPlugin generatorPlugin) {
|
||||
Plugin genPlugin = generatorPlugin.getPlugin();
|
||||
|
||||
// Make sure not registered before.
|
||||
GeneratorPlugin registeredGeneratorPlugin = this.getGeneratorPlugin(genPlugin);
|
||||
if (registeredGeneratorPlugin != null) {
|
||||
if (!(registeredGeneratorPlugin instanceof SimpleGeneratorPlugin)) {
|
||||
throw new IllegalStateException("You cannot register plugin for '" + genPlugin.getName() + "' twice!");
|
||||
}
|
||||
// If it's auto registration by MV, we can remove in favour of the custom one.
|
||||
this.unregister(genPlugin);
|
||||
}
|
||||
|
||||
if (this.safelyTestGenerator(genPlugin, generatorPlugin::getDefaultChunkGenerator) != TestResult.VALID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.generatorPluginMap.put(genPlugin.getName(), generatorPlugin);
|
||||
Logging.fine("Registered %s as a simple generator plugin.", genPlugin.getName());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isValidGenerator(@NotNull String genString, @NotNull String worldName) {
|
||||
return validateGenerator(genString, worldName) == TestResult.VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@NotNull
|
||||
public TestResult validateGenerator(@NotNull String genString, @NotNull String worldName) {
|
||||
String[] genArray = genString.split(":", 2);
|
||||
String pluginName = genArray[0];
|
||||
String id = (genArray.length == 1) ? "" : genArray[1];
|
||||
|
||||
Plugin genPlugin = Bukkit.getPluginManager().getPlugin(pluginName);
|
||||
if (genPlugin == null) {
|
||||
return TestResult.PLUGIN_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (!this.isGeneratorPlugin(genPlugin)) {
|
||||
// Tries to register again with specific Id defined.
|
||||
if (!this.register(genPlugin, id)) {
|
||||
return TestResult.INVALID_GENERATOR;
|
||||
}
|
||||
}
|
||||
|
||||
GeneratorPlugin generatorPlugin = this.getGeneratorPlugin(genPlugin);
|
||||
if (generatorPlugin == null) {
|
||||
return TestResult.INVALID_GENERATOR;
|
||||
}
|
||||
|
||||
TestResult testResult = safelyTestGenerator(generatorPlugin.getPlugin(), () -> generatorPlugin.getChunkGenerator(id, worldName));
|
||||
if (testResult == TestResult.VALID && generatorPlugin instanceof SimpleGeneratorPlugin) {
|
||||
((SimpleGeneratorPlugin) generatorPlugin).addKnownWorkingId(id);
|
||||
}
|
||||
return testResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to get chunk generator with wrapper to catch any exceptions that may occur.
|
||||
*
|
||||
* @param genPlugin The generator plugin.
|
||||
* @param genGetter Logic to get the chunk generator.
|
||||
* @return VALID if successfully got a not-null chunk generator, INVALID_GENERATOR if null,
|
||||
* ERRORS if exception is thrown.
|
||||
*/
|
||||
@NotNull
|
||||
private TestResult safelyTestGenerator(Plugin genPlugin, Callable<ChunkGenerator> genGetter) {
|
||||
TestResult result = this.plugin.getUnsafeCallWrapper().wrap(
|
||||
() -> genGetter.call() == null ? TestResult.INVALID_GENERATOR : TestResult.VALID,
|
||||
genPlugin.getName(),
|
||||
"Failed to get the chunk generator: %s"
|
||||
);
|
||||
return (result == null) ? TestResult.ERRORS : result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isGeneratorPlugin(@NotNull Plugin genPlugin) {
|
||||
return this.isGeneratorPlugin(genPlugin.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isGeneratorPlugin(@NotNull String pluginName) {
|
||||
return this.generatorPluginMap.containsKey(pluginName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
public GeneratorPlugin getGeneratorPlugin(@NotNull Plugin genPlugin) {
|
||||
return this.getGeneratorPlugin(genPlugin.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
public GeneratorPlugin getGeneratorPlugin(@NotNull String pluginName) {
|
||||
return this.generatorPluginMap.get(pluginName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@NotNull
|
||||
public Collection<GeneratorPlugin> getGeneratorPlugins() {
|
||||
return this.generatorPluginMap.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@NotNull
|
||||
public Collection<String> getGeneratorPluginNames() {
|
||||
return this.generatorPluginMap.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
public String getDefaultWorldGen(String worldName) {
|
||||
return this.defaultGens.get(worldName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@NotNull
|
||||
public Map<String, String> getDefaultWorldGens() {
|
||||
return this.defaultGens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen to when a plugin enables/disable to register and unregister accordingly.
|
||||
*/
|
||||
private class GeneratorListener implements Listener {
|
||||
@EventHandler
|
||||
public void onEnable(PluginEnableEvent event) {
|
||||
register(event.getPlugin());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDisable(PluginDisableEvent event) {
|
||||
unregister(event.getPlugin());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.onarandombox.MultiverseCore.generators;
|
||||
|
||||
import com.onarandombox.MultiverseCore.api.GeneratorPlugin;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A default implementation of {@link GeneratorPlugin} for those generator plugins that do not provide their own
|
||||
* custom {@link GeneratorPlugin} implementation to Multiverse.
|
||||
*/
|
||||
public class SimpleGeneratorPlugin implements GeneratorPlugin {
|
||||
|
||||
public static String TEST_WORLDNAME = "test";
|
||||
public static String DEFAULT_TEST_ID = "";
|
||||
|
||||
private final Plugin plugin;
|
||||
private final List<String> workingIds;
|
||||
|
||||
SimpleGeneratorPlugin(Plugin plugin) {
|
||||
this(plugin, DEFAULT_TEST_ID);
|
||||
}
|
||||
|
||||
SimpleGeneratorPlugin(Plugin plugin, String testedId) {
|
||||
this.plugin = plugin;
|
||||
this.workingIds = new ArrayList<>();
|
||||
this.workingIds.add(testedId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a known generator id that was tested to be working.
|
||||
*
|
||||
* @param id The known working generator id.
|
||||
*/
|
||||
void addKnownWorkingId(String id) {
|
||||
if (!this.workingIds.contains(id)) {
|
||||
this.workingIds.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public @NotNull Collection<String> suggestIds(@Nullable String currentIdInput) {
|
||||
return this.workingIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public @Nullable ChunkGenerator getDefaultChunkGenerator() throws Exception {
|
||||
return this.plugin.getDefaultWorldGenerator(TEST_WORLDNAME, this.workingIds.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public @Nullable ChunkGenerator getChunkGenerator(String id, String worldName) throws Exception {
|
||||
return this.plugin.getDefaultWorldGenerator(worldName, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public @Nullable Collection<String> getExampleUsages() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public @Nullable String getInfoLink() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public @NotNull Plugin getPlugin() {
|
||||
return this.plugin;
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,6 @@ import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
|
||||
import com.onarandombox.MultiverseCore.utils.CompatibilityLayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -19,7 +18,6 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
||||
import org.bukkit.event.entity.EntityPortalEvent;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
|
||||
import org.bukkit.event.entity.FoodLevelChangeEvent;
|
||||
@@ -109,17 +107,4 @@ public class MVEntityListener implements Listener {
|
||||
event.setCancelled(this.plugin.getMVWorldManager().getTheWorldPurger().shouldWeKillThisCreature(mvworld, event.getEntity()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles portal search radius adjustment.
|
||||
* @param event The Event that was fired.
|
||||
*/
|
||||
@EventHandler
|
||||
public void entityPortal(EntityPortalEvent event) {
|
||||
if (event.isCancelled() || event.getTo() == null) {
|
||||
return;
|
||||
}
|
||||
if (!this.plugin.getMVConfig().isUsingDefaultPortalSearch()) {
|
||||
CompatibilityLayer.setPortalSearchRadius(event, this.plugin.getMVConfig().getPortalSearchRadius());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,10 @@
|
||||
|
||||
package com.onarandombox.MultiverseCore.listeners;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
@@ -31,9 +35,6 @@ import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Multiverse's {@link Listener} for players.
|
||||
*/
|
||||
@@ -312,8 +313,16 @@ public class MVPlayerListener implements Listener {
|
||||
+ "' was allowed to go to '" + event.getTo().getWorld().getName()
|
||||
+ "' because enforceaccess is off.");
|
||||
}
|
||||
if (!this.plugin.getMVConfig().isUsingDefaultPortalSearch()) {
|
||||
CompatibilityLayer.setPortalSearchRadius(event, this.plugin.getMVConfig().getPortalSearchRadius());
|
||||
if (!plugin.getMVConfig().isUsingDefaultPortalSearch()) {
|
||||
try {
|
||||
Class.forName("org.bukkit.TravelAgent");
|
||||
if (event.getPortalTravelAgent() != null) {
|
||||
event.getPortalTravelAgent().setSearchRadius(plugin.getMVConfig().getPortalSearchRadius());
|
||||
}
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
Logging.fine("TravelAgent not available for PlayerPortalEvent for " + event.getPlayer().getName());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,35 +1,32 @@
|
||||
package com.onarandombox.MultiverseCore.utils;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import org.bukkit.event.entity.EntityPortalEvent;
|
||||
import org.bukkit.event.player.PlayerPortalEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Utility class to enable version specific minecraft features.
|
||||
* A utility class to enable version specific minecraft features.
|
||||
*/
|
||||
public class CompatibilityLayer {
|
||||
|
||||
private static Method checkAnchorSpawn;
|
||||
private static boolean useTravelAgent;
|
||||
private static Method playerPortalSearchRadius;
|
||||
private static Method entityPortalSearchRadius;
|
||||
|
||||
/**
|
||||
* Initialise the reflection class, methods and fields.
|
||||
* Initialise the reflection methods.
|
||||
*/
|
||||
public static void init() {
|
||||
checkAnchorSpawn = ReflectHelper.getMethod(PlayerRespawnEvent.class, "isAnchorSpawn");
|
||||
useTravelAgent = ReflectHelper.hasClass("org.bukkit.TravelAgent");
|
||||
playerPortalSearchRadius = ReflectHelper.getMethod(PlayerPortalEvent.class, "setSearchRadius", int.class);
|
||||
entityPortalSearchRadius = ReflectHelper.getMethod(EntityPortalEvent.class, "setSearchRadius", int.class);
|
||||
try {
|
||||
checkAnchorSpawn = PlayerRespawnEvent.class.getDeclaredMethod("isAnchorSpawn");
|
||||
} catch (NoSuchMethodException e) {
|
||||
Logging.fine("%s does not support respawn anchors.", Bukkit.getVersion());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Check if the respawn point is of respawn anchor type.</p>
|
||||
* <p>Introduced in minecraft 1.16</p>
|
||||
* Check if the respawn point is of respawn anchor type.
|
||||
* Introduced in minecraft 1.16
|
||||
*
|
||||
* @param event A player respawn event.
|
||||
* @return If the respawn location is an anchor point.
|
||||
@@ -38,69 +35,12 @@ public class CompatibilityLayer {
|
||||
if (checkAnchorSpawn == null) {
|
||||
return false;
|
||||
}
|
||||
Boolean result = ReflectHelper.invokeMethod(event, checkAnchorSpawn);
|
||||
if (result == null) {
|
||||
Logging.warning("Unable to check if spawning at respawn anchor!");
|
||||
return false;
|
||||
try {
|
||||
return (boolean) checkAnchorSpawn.invoke(event);
|
||||
} catch (Exception e) {
|
||||
Logging.warning("Error checking for: %s", checkAnchorSpawn);
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gets if Travel Agent is supported on the server's minecraft version.</p>
|
||||
* <p>Removed in minecraft 1.14</p>
|
||||
*
|
||||
* @return True if Travel Agent is supported, else false.
|
||||
*/
|
||||
public static boolean isUseTravelAgent() {
|
||||
return useTravelAgent;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets search radius for a PlayerPortalEvent.</p>
|
||||
*
|
||||
* <p>Use travel agent if available, else using new PlayerPortalEvent.setSearchRadius(int) method
|
||||
* introduced in minecraft 1.15</p>
|
||||
*
|
||||
* @param event A Player Portal Event.
|
||||
* @param searchRadius Target search radius to set to.
|
||||
*/
|
||||
public static void setPortalSearchRadius(PlayerPortalEvent event, int searchRadius) {
|
||||
if (useTravelAgent) {
|
||||
event.getPortalTravelAgent().setSearchRadius(searchRadius);
|
||||
event.useTravelAgent(true);
|
||||
Logging.finer("Used travel agent to set player portal search radius.");
|
||||
return;
|
||||
}
|
||||
if (playerPortalSearchRadius == null) {
|
||||
Logging.warning("Unable to set player portal search radius!");
|
||||
return;
|
||||
}
|
||||
ReflectHelper.invokeMethod(event, playerPortalSearchRadius, searchRadius);
|
||||
Logging.finer("Used new method to set player portal search radius.");
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets search radius for a EntityPortalEvent.</p>
|
||||
*
|
||||
* <p>Use travel agent if available, else using new EntityPortalEvent.setSearchRadius(int) method
|
||||
* introduced in minecraft 1.15</p>
|
||||
*
|
||||
* @param event A Entity Portal Event.
|
||||
* @param searchRadius Target search radius to set to.
|
||||
*/
|
||||
public static void setPortalSearchRadius(EntityPortalEvent event, int searchRadius) {
|
||||
if (useTravelAgent) {
|
||||
event.getPortalTravelAgent().setSearchRadius(searchRadius);
|
||||
event.useTravelAgent(true);
|
||||
Logging.finer("Used travel agent to set entity portal search radius.");
|
||||
return;
|
||||
}
|
||||
if (entityPortalSearchRadius == null) {
|
||||
Logging.warning("Unable to set entity portal search radius!");
|
||||
return;
|
||||
}
|
||||
ReflectHelper.invokeMethod(event, entityPortalSearchRadius, searchRadius);
|
||||
Logging.finer("Used new method to set entity portal search radius.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
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 UUID_REGEX = Pattern.compile("[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[34][0-9a-fA-F]{3}-[89ab][0-9a-fA-F]{3}-[0-9a-fA-F]{12}");
|
||||
private static final Pattern COMMA_SPLIT = Pattern.compile(",");
|
||||
|
||||
/**
|
||||
@@ -135,7 +135,7 @@ public class PlayerFinder {
|
||||
|
||||
List<Player> matchedPlayers = getMultiBySelector(playerSelector, sender);
|
||||
if (matchedPlayers == null || matchedPlayers.isEmpty()) {
|
||||
Logging.fine("No player found with selector '%s' for %s.", playerSelector, sender.getName());
|
||||
Logging.warning("No player found with selector '%s' for %s.", playerSelector, sender.getName());
|
||||
return null;
|
||||
}
|
||||
if (matchedPlayers.size() > 1) {
|
||||
|
||||
@@ -18,7 +18,6 @@ import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
|
||||
import com.onarandombox.MultiverseCore.api.WorldPurger;
|
||||
import com.onarandombox.MultiverseCore.event.MVWorldDeleteEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameRule;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.World.Environment;
|
||||
@@ -37,24 +36,26 @@ 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.stream.Collectors;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Public facing API to add/remove Multiverse worlds.
|
||||
*/
|
||||
public class WorldManager implements MVWorldManager {
|
||||
private final MultiverseCore plugin;
|
||||
private final Pattern worldNamePattern = Pattern.compile("[a-zA-Z0-9/._-]+");
|
||||
private final WorldPurger worldPurger;
|
||||
private final Map<String, MultiverseWorld> worlds;
|
||||
private Map<String, WorldProperties> worldsFromTheConfig;
|
||||
@@ -73,6 +74,7 @@ public class WorldManager implements MVWorldManager {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void getDefaultWorldGenerators() {
|
||||
this.defaultGens = new HashMap<String, String>();
|
||||
File[] files = this.plugin.getServerFolder().listFiles(new FilenameFilter() {
|
||||
@@ -129,11 +131,7 @@ public class WorldManager implements MVWorldManager {
|
||||
}
|
||||
|
||||
// Check for valid world name
|
||||
if (!this.plugin.getMVConfig().isAllowUnsafeWorldName() && !WorldNameChecker.isValidWorldName(newName)) {
|
||||
Logging.warning("Unable to clone world as world name '" + newName + "' is invalid.");
|
||||
Logging.warning("World name should not contain spaces or special characters!");
|
||||
Logging.warning("Enable allowunsafeworldname to bypass the check if you are absolutely sure this world is valid.");
|
||||
Logging.warning("However, MV is not response of any damage to your world if you enable this option.");
|
||||
if (!(WorldNameChecker.isValidWorldName(oldName) && WorldNameChecker.isValidWorldName(oldName))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -237,12 +235,13 @@ public class WorldManager implements MVWorldManager {
|
||||
@Override
|
||||
public boolean addWorld(String name, Environment env, String seedString, WorldType type, Boolean generateStructures,
|
||||
String generator, boolean useSpawnAdjust) {
|
||||
if (name.equalsIgnoreCase("plugins") || name.equalsIgnoreCase("logs")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.plugin.getMVConfig().isAllowUnsafeWorldName() && !WorldNameChecker.isValidWorldName(name)) {
|
||||
Logging.warning("Unable to add world as world name '" + name + "' is invalid.");
|
||||
if (!WorldNameChecker.isValidWorldName(name)) {
|
||||
Logging.warning("Invalid world name '" + name + "'");
|
||||
Logging.warning("World name should not contain spaces or special characters!");
|
||||
Logging.warning("Enable allowunsafeworldname to bypass the check if you are absolutely sure this world is valid.");
|
||||
Logging.warning("However, MV is not response of any damage to your world if you enable this option.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -303,6 +302,7 @@ public class WorldManager implements MVWorldManager {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public ChunkGenerator getChunkGenerator(String generator, final String generatorID, final String worldName) {
|
||||
if (generator == null) {
|
||||
return null;
|
||||
@@ -389,14 +389,14 @@ public class WorldManager implements MVWorldManager {
|
||||
this.worldsFromTheConfig.get(name).cacheVirtualProperties();
|
||||
if (unloadBukkit && this.unloadWorldFromBukkit(name, true)) {
|
||||
this.worlds.remove(name);
|
||||
Logging.info("World '%s' was unloaded from Bukkit.", name);
|
||||
Logging.info("World '%s' was unloaded from memory.", name);
|
||||
return true;
|
||||
} else if (!unloadBukkit){
|
||||
this.worlds.remove(name);
|
||||
Logging.info("World '%s' was unloaded from Multiverse.", name);
|
||||
Logging.info("World '%s' was unloaded from memory.", name);
|
||||
return true;
|
||||
} else {
|
||||
Logging.warning("World '%s' could not be unloaded from Bukkit. Is it a default world?", name);
|
||||
Logging.warning("World '%s' could not be unloaded. Is it a default world?", name);
|
||||
}
|
||||
} else if (this.plugin.getServer().getWorld(name) != null) {
|
||||
Logging.warning("Hmm Multiverse does not know about this world but it's loaded in memory.");
|
||||
@@ -619,14 +619,6 @@ 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;
|
||||
}
|
||||
@@ -634,7 +626,7 @@ public class WorldManager implements MVWorldManager {
|
||||
if (world != null) {
|
||||
return world;
|
||||
}
|
||||
return (checkAliases) ? this.getMVWorldByAlias(name) : null;
|
||||
return this.getMVWorldByAlias(name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -643,7 +635,7 @@ public class WorldManager implements MVWorldManager {
|
||||
@Override
|
||||
public MultiverseWorld getMVWorld(World world) {
|
||||
if (world != null) {
|
||||
return this.getMVWorld(world.getName(), false);
|
||||
return this.getMVWorld(world.getName());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -668,15 +660,7 @@ public class WorldManager implements MVWorldManager {
|
||||
*/
|
||||
@Override
|
||||
public boolean isMVWorld(final String 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));
|
||||
return (this.worlds.containsKey(name) || isMVWorldAlias(name));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -712,10 +696,7 @@ public class WorldManager implements MVWorldManager {
|
||||
for (World w : myWorlds) {
|
||||
String name = w.getName();
|
||||
if (!worldsFromTheConfig.containsKey(name)) {
|
||||
String generator = null;
|
||||
if (this.defaultGens.containsKey(name)) {
|
||||
generator = this.defaultGens.get(name);
|
||||
}
|
||||
String generator = this.plugin.getMVGeneratorManager().getDefaultWorldGen(name);
|
||||
this.addWorld(name, w.getEnvironment(), String.valueOf(w.getSeed()), w.getWorldType(), w.canGenerateStructures(), generator);
|
||||
}
|
||||
}
|
||||
@@ -899,23 +880,12 @@ public class WorldManager implements MVWorldManager {
|
||||
*/
|
||||
@Override
|
||||
public boolean regenWorld(String name, boolean useNewSeed, boolean randomSeed, String seed) {
|
||||
return regenWorld(name, useNewSeed, randomSeed, seed, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean regenWorld(String name, boolean useNewSeed, boolean randomSeed, String seed, boolean keepGameRules) {
|
||||
MultiverseWorld world = this.getMVWorld(name);
|
||||
if (world == null) {
|
||||
Logging.warning("Unable to regen a world that does not exist!");
|
||||
if (world == null)
|
||||
return false;
|
||||
}
|
||||
|
||||
List<Player> ps = world.getCBWorld().getPlayers();
|
||||
|
||||
// Apply new seed if needed.
|
||||
if (useNewSeed) {
|
||||
long theSeed;
|
||||
|
||||
@@ -931,64 +901,19 @@ public class WorldManager implements MVWorldManager {
|
||||
|
||||
world.setSeed(theSeed);
|
||||
}
|
||||
|
||||
WorldType type = world.getWorldType();
|
||||
|
||||
// Save current GameRules if needed.
|
||||
Map<GameRule<?>, Object> gameRuleMap = null;
|
||||
if (keepGameRules) {
|
||||
gameRuleMap = new HashMap<>(GameRule.values().length);
|
||||
World CBWorld = world.getCBWorld();
|
||||
for (GameRule<?> gameRule : GameRule.values()) {
|
||||
// Only save if not default value.
|
||||
Object value = CBWorld.getGameRuleValue(gameRule);
|
||||
if (value != CBWorld.getGameRuleDefault(gameRule)) {
|
||||
gameRuleMap.put(gameRule, value);
|
||||
}
|
||||
if (this.deleteWorld(name, false, false)) {
|
||||
this.doLoad(name, true, type);
|
||||
SafeTTeleporter teleporter = this.plugin.getSafeTTeleporter();
|
||||
Location newSpawn = world.getSpawnLocation();
|
||||
// Send all players that were in the old world, BACK to it!
|
||||
for (Player p : ps) {
|
||||
teleporter.safelyTeleport(null, p, newSpawn, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Do the regen.
|
||||
if (!this.deleteWorld(name, false, false)) {
|
||||
Logging.severe("Unable to regen world as world cannot be deleted.");
|
||||
return false;
|
||||
}
|
||||
if (!this.doLoad(name, true, type)) {
|
||||
Logging.severe("Unable to regen world as world cannot be loaded.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get new MultiverseWorld reference.
|
||||
world = this.getMVWorld(name);
|
||||
|
||||
// Load back GameRules if needed.
|
||||
if (keepGameRules) {
|
||||
Logging.fine("Restoring previous world's GameRules...");
|
||||
World CBWorld = world.getCBWorld();
|
||||
for (Map.Entry<GameRule<?>, Object> gameRuleEntry : gameRuleMap.entrySet()) {
|
||||
if (!setGameRuleValue(CBWorld, gameRuleEntry.getKey(), gameRuleEntry.getValue())) {
|
||||
Logging.warning("Unable to set GameRule '%s' to '%s' on regen world.",
|
||||
gameRuleEntry.getKey().getName(), gameRuleEntry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send all players that were in the old world, BACK to it!
|
||||
SafeTTeleporter teleporter = this.plugin.getSafeTTeleporter();
|
||||
Location newSpawn = world.getSpawnLocation();
|
||||
for (Player p : ps) {
|
||||
teleporter.safelyTeleport(null, p, newSpawn, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private <T> boolean setGameRuleValue(World world, GameRule<T> gameRule, Object value) {
|
||||
try {
|
||||
return world.setGameRule(gameRule, (T) value);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1014,21 +939,4 @@ 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());
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
public class WorldNameChecker {
|
||||
|
||||
private static final Pattern WORLD_NAME_PATTERN = Pattern.compile("[a-zA-Z0-9_-]+");
|
||||
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");
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package com.onarandombox.MultiverseCore.utils.metrics;
|
||||
|
||||
import org.bstats.charts.AdvancedPie;
|
||||
import org.bstats.charts.MultiLineChart;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.bstats.bukkit.Metrics;
|
||||
|
||||
enum MetricsHelper {
|
||||
;
|
||||
|
||||
@@ -18,16 +17,16 @@ enum MetricsHelper {
|
||||
map.put(key, count + 1);
|
||||
}
|
||||
|
||||
static AdvancedPie createAdvancedPieChart(String chartId, Consumer<Map<String, Integer>> metricsFunc) {
|
||||
static Metrics.AdvancedPie createAdvancedPieChart(String chartId, Consumer<Map<String, Integer>> metricsFunc) {
|
||||
Map<String, Integer> map = new HashMap<>();
|
||||
metricsFunc.accept(map);
|
||||
return new AdvancedPie(chartId, () -> map);
|
||||
return new Metrics.AdvancedPie(chartId, () -> map);
|
||||
}
|
||||
|
||||
static MultiLineChart createMultiLineChart(String chartId, Consumer<Map<String, Integer>> metricsFunc) {
|
||||
static Metrics.MultiLineChart createMultiLineChart(String chartId, Consumer<Map<String, Integer>> metricsFunc) {
|
||||
Map<String, Integer> map = new HashMap<>();
|
||||
metricsFunc.accept(map);
|
||||
return new MultiLineChart(chartId, () -> map);
|
||||
return new Metrics.MultiLineChart(chartId, () -> map);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.internal.verification.VerificationModeFactory;
|
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
@@ -37,14 +38,8 @@ import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static junit.framework.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static junit.framework.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({ PluginManager.class, MultiverseCore.class, Permission.class, Bukkit.class, WorldManager.class,
|
||||
@@ -97,7 +92,7 @@ public class TestWorldStuff {
|
||||
// Import the first world. The world folder does not exist.
|
||||
plugin.onCommand(mockCommandSender, mockCommand, "", normalArgs);
|
||||
verify(mockCommandSender).sendMessage(ChatColor.RED + "FAILED.");
|
||||
verify(mockCommandSender).sendMessage(ChatColor.RED + "That world folder does not exist. These look like worlds to me:");
|
||||
verify(mockCommandSender).sendMessage("That world folder does not exist. These look like worlds to me:");
|
||||
|
||||
// We should still have no worlds.
|
||||
assertEquals(0, creator.getCore().getMVWorldManager().getMVWorlds().size());
|
||||
@@ -212,7 +207,7 @@ public class TestWorldStuff {
|
||||
assertEquals(0, creator.getCore().getMVWorldManager().getMVWorlds().size());
|
||||
|
||||
// Verify
|
||||
verify(mockCommandSender).sendMessage("Invalid generator! 'BogusGen'. " + ChatColor.RED + "Aborting world creation.");
|
||||
verify(mockCommandSender).sendMessage("That generator plugin is not installed on your server!");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in new issue
Block a user