Compare commits
26
Commits
4.2.0
...
clone-refactor
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e85e42bd0 | ||
|
|
3f2ec3d40f | ||
|
|
ed80083fe8 | ||
|
|
d041e0a8d1 | ||
|
|
de85be5832 | ||
|
|
81d59d8bf5 | ||
|
|
0c2d2f4e0a | ||
|
|
3d9108fb48 | ||
|
|
25c616bc32 | ||
|
|
148187025a | ||
|
|
115b0dc078 | ||
|
|
78bf6ba3bf | ||
|
|
e31c391af4 | ||
|
|
6ed4be9a64 | ||
|
|
d626e7e4b1 | ||
|
|
e7dd4fee51 | ||
|
|
146075de69 | ||
|
|
9fce6c54f6 | ||
|
|
f189eb3b7e | ||
|
|
2d4fe301cf | ||
|
|
e5fe1fe565 | ||
|
|
83010f1a28 | ||
|
|
864e50e38c | ||
|
|
0a99258f3e | ||
|
|
b345baf20e | ||
|
|
d532052c7b |
No files matched your search
@@ -2,7 +2,7 @@
|
||||
name: ❓ Help!
|
||||
about: Encountered a problem with Multiverse-Core? Not sure how to fix it?
|
||||
title: ''
|
||||
labels: 'type: Assistance'
|
||||
labels: 'Type: Assistance'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
@@ -40,7 +40,7 @@ If you're happy to wait (or you were sent here from Discord), read on:
|
||||
|
||||
* **Server version:** <!-- Insert output of `/version` command -->
|
||||
|
||||
* **Full output of `/mv version -b`:** <!-- Replace this with the command output's https://pastebin.com link -->
|
||||
* **Full output of `/mv version -p`:** <!-- Replace this with the command output's https://paste.gg/ link -->
|
||||
|
||||
* **Server log:** <!-- Upload `logs/latest.log` to https://gist.github.com/ -->
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name: 🐛 Report a Bug
|
||||
about: Report a Multiverse-Core bug. Only use this if you're 100% sure it's something wrong with Multiverse-Core - otherwise, try "Help!".
|
||||
title: ''
|
||||
labels: 'type: Bug'
|
||||
labels: 'Bug: Unconfirmed'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
@@ -39,7 +39,7 @@ If you are reporting a bug, please follow the following steps:
|
||||
|
||||
* **Server version:** <!-- Insert output of `/version` command -->
|
||||
|
||||
* **Full output of `/mv version -b`:** <!-- Replace this with the command output's https://pastebin.com link -->
|
||||
* **Full output of `/mv version -p`:** <!-- Replace this with the command output's https://paste.gg/ link -->
|
||||
|
||||
* **Server log:** <!-- Upload `logs/latest.log` to https://gist.github.com/ -->
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name: 💡 Request a Feature
|
||||
about: Suggest a feature you want to see in Multiverse-Core!
|
||||
title: ''
|
||||
labels: 'type: Suggestion'
|
||||
labels: 'Type: Idea'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
@@ -13,4 +13,4 @@ Copyright (c) 2011, The Multiverse Team All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the The Multiverse Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.onarandombox.multiversecore</groupId>
|
||||
<artifactId>Multiverse-Core</artifactId>
|
||||
<version>4.2.0</version>
|
||||
<version>4.2.3-SNAPSHOT</version>
|
||||
<name>Multiverse-Core</name>
|
||||
<description>World Management Plugin</description>
|
||||
<properties>
|
||||
|
||||
@@ -93,6 +93,7 @@ import com.onarandombox.MultiverseCore.utils.MVMessaging;
|
||||
import com.onarandombox.MultiverseCore.utils.MVPermissions;
|
||||
import com.onarandombox.MultiverseCore.utils.MVPlayerSession;
|
||||
import com.onarandombox.MultiverseCore.utils.MaterialConverter;
|
||||
import com.onarandombox.MultiverseCore.utils.TestingMode;
|
||||
import com.onarandombox.MultiverseCore.utils.metrics.MetricsConfigurator;
|
||||
import com.onarandombox.MultiverseCore.utils.SimpleBlockSafety;
|
||||
import com.onarandombox.MultiverseCore.utils.SimpleLocationManipulation;
|
||||
@@ -343,7 +344,9 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
}
|
||||
|
||||
private void setupMetrics() {
|
||||
MetricsConfigurator.configureMetrics(this);
|
||||
if (TestingMode.isDisabled()) {
|
||||
MetricsConfigurator.configureMetrics(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -380,7 +383,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
pm.registerEvents(this.entityListener, this);
|
||||
pm.registerEvents(this.weatherListener, this);
|
||||
pm.registerEvents(this.portalListener, this);
|
||||
log(Level.INFO, "We are aware of the warning about the deprecated event. There is no alternative that allows us to do what we need to do. The performance impact is negligible.");
|
||||
log(Level.INFO, ChatColor.GREEN + "We are aware of the warning about the deprecated event. There is no alternative that allows us to do what we need to do and performance impact is negligible. It is safe to ignore.");
|
||||
pm.registerEvents(this.worldListener, this);
|
||||
pm.registerEvents(new MVMapListener(this), this);
|
||||
}
|
||||
|
||||
@@ -26,12 +26,7 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -55,58 +50,58 @@ public class VersionCommand extends MultiverseCommand {
|
||||
}
|
||||
|
||||
private String getLegacyString() {
|
||||
return "[Multiverse-Core] Multiverse-Core Version: " + this.plugin.getDescription().getVersion() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] Bukkit Version: " + this.plugin.getServer().getVersion() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] Loaded Worlds: " + this.plugin.getMVWorldManager().getMVWorlds() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] Multiverse Plugins Loaded: " + this.plugin.getPluginCount() + System.lineSeparator()
|
||||
+"[Multiverse-Core] Economy being used: " + plugin.getEconomist().getEconomyName() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] Permissions Plugin: " + this.plugin.getMVPerms().getType() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] Dumping Config Values: (version " + this.plugin.getMVConfig().getVersion() + ")" + System.lineSeparator()
|
||||
+ "[Multiverse-Core] enforceaccess: " + plugin.getMVConfig().getEnforceAccess() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] prefixchat: " + plugin.getMVConfig().getPrefixChat() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] prefixchatformat: " + plugin.getMVConfig().getPrefixChatFormat() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] useasyncchat: " + plugin.getMVConfig().getUseAsyncChat() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] teleportintercept: " + plugin.getMVConfig().getTeleportIntercept() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] firstspawnoverride: " + plugin.getMVConfig().getFirstSpawnOverride() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] displaypermerrors: " + plugin.getMVConfig().getDisplayPermErrors() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] globaldebug: " + plugin.getMVConfig().getGlobalDebug() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] silentstart: " + plugin.getMVConfig().getSilentStart() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] messagecooldown: " + plugin.getMessaging().getCooldown() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] version: " + plugin.getMVConfig().getVersion() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] firstspawnworld: " + plugin.getMVConfig().getFirstSpawnWorld() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] teleportcooldown: " + plugin.getMVConfig().getTeleportCooldown() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] defaultportalsearch: " + plugin.getMVConfig().isUsingDefaultPortalSearch() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] portalsearchradius: " + plugin.getMVConfig().getPortalSearchRadius() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] autopurge: " + plugin.getMVConfig().isAutoPurgeEnabled() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] Special Code: FRN002" + System.lineSeparator();
|
||||
return "[Multiverse-Core] Multiverse-Core Version: " + this.plugin.getDescription().getVersion() + '\n'
|
||||
+ "[Multiverse-Core] Bukkit Version: " + this.plugin.getServer().getVersion() + '\n'
|
||||
+ "[Multiverse-Core] Loaded Worlds: " + this.plugin.getMVWorldManager().getMVWorlds() + '\n'
|
||||
+ "[Multiverse-Core] Multiverse Plugins Loaded: " + this.plugin.getPluginCount() + '\n'
|
||||
+"[Multiverse-Core] Economy being used: " + plugin.getEconomist().getEconomyName() + '\n'
|
||||
+ "[Multiverse-Core] Permissions Plugin: " + this.plugin.getMVPerms().getType() + '\n'
|
||||
+ "[Multiverse-Core] Dumping Config Values: (version " + this.plugin.getMVConfig().getVersion() + ")" + '\n'
|
||||
+ "[Multiverse-Core] enforceaccess: " + plugin.getMVConfig().getEnforceAccess() + '\n'
|
||||
+ "[Multiverse-Core] prefixchat: " + plugin.getMVConfig().getPrefixChat() + '\n'
|
||||
+ "[Multiverse-Core] prefixchatformat: " + plugin.getMVConfig().getPrefixChatFormat() + '\n'
|
||||
+ "[Multiverse-Core] useasyncchat: " + plugin.getMVConfig().getUseAsyncChat() + '\n'
|
||||
+ "[Multiverse-Core] teleportintercept: " + plugin.getMVConfig().getTeleportIntercept() + '\n'
|
||||
+ "[Multiverse-Core] firstspawnoverride: " + plugin.getMVConfig().getFirstSpawnOverride() + '\n'
|
||||
+ "[Multiverse-Core] displaypermerrors: " + plugin.getMVConfig().getDisplayPermErrors() + '\n'
|
||||
+ "[Multiverse-Core] globaldebug: " + plugin.getMVConfig().getGlobalDebug() + '\n'
|
||||
+ "[Multiverse-Core] silentstart: " + plugin.getMVConfig().getSilentStart() + '\n'
|
||||
+ "[Multiverse-Core] messagecooldown: " + plugin.getMessaging().getCooldown() + '\n'
|
||||
+ "[Multiverse-Core] version: " + plugin.getMVConfig().getVersion() + '\n'
|
||||
+ "[Multiverse-Core] firstspawnworld: " + plugin.getMVConfig().getFirstSpawnWorld() + '\n'
|
||||
+ "[Multiverse-Core] teleportcooldown: " + plugin.getMVConfig().getTeleportCooldown() + '\n'
|
||||
+ "[Multiverse-Core] defaultportalsearch: " + plugin.getMVConfig().isUsingDefaultPortalSearch() + '\n'
|
||||
+ "[Multiverse-Core] portalsearchradius: " + plugin.getMVConfig().getPortalSearchRadius() + '\n'
|
||||
+ "[Multiverse-Core] autopurge: " + plugin.getMVConfig().isAutoPurgeEnabled() + '\n'
|
||||
+ "[Multiverse-Core] Special Code: FRN002" + '\n';
|
||||
}
|
||||
|
||||
private String getMarkdownString() {
|
||||
return "# Multiverse-Core" + System.lineSeparator()
|
||||
+ "## Overview" + System.lineSeparator()
|
||||
+ "| Name | Value |" + System.lineSeparator()
|
||||
+ "| --- | --- |" + System.lineSeparator()
|
||||
+ "| Multiverse-Core Version | `" + this.plugin.getDescription().getVersion() + "` |" + System.lineSeparator()
|
||||
+ "| Bukkit Version | `" + this.plugin.getServer().getVersion() + "` |" + System.lineSeparator()
|
||||
+ "| Loaded Worlds | `" + this.plugin.getMVWorldManager().getMVWorlds() + "` |" + System.lineSeparator()
|
||||
+ "| Multiverse Plugins Loaded | `" + this.plugin.getPluginCount() + "` |" + System.lineSeparator()
|
||||
+ "| Economy being used | `" + plugin.getEconomist().getEconomyName() + "` |" + System.lineSeparator()
|
||||
+ "| Permissions Plugin | `" + this.plugin.getMVPerms().getType() + "` |" + System.lineSeparator()
|
||||
+ "## Parsed Config" + System.lineSeparator()
|
||||
+ "These are what Multiverse thought the in-memory values of the config were." + System.lineSeparator() + System.lineSeparator()
|
||||
+ "| Config Key | Value |" + System.lineSeparator()
|
||||
+ "| --- | --- |" + System.lineSeparator()
|
||||
+ "| version | `" + this.plugin.getMVConfig().getVersion() + "` |" + System.lineSeparator()
|
||||
+ "| messagecooldown | `" + plugin.getMessaging().getCooldown() + "` |" + System.lineSeparator()
|
||||
+ "| teleportcooldown | `" + plugin.getMVConfig().getTeleportCooldown() + "` |" + System.lineSeparator()
|
||||
+ "| worldnameprefix | `" + plugin.getMVConfig().getPrefixChat() + "` |" + System.lineSeparator()
|
||||
+ "| worldnameprefixFormat | `" + plugin.getMVConfig().getPrefixChatFormat() + "` |" + System.lineSeparator()
|
||||
+ "| enforceaccess | `" + plugin.getMVConfig().getEnforceAccess() + "` |" + System.lineSeparator()
|
||||
+ "| displaypermerrors | `" + plugin.getMVConfig().getDisplayPermErrors() + "` |" + System.lineSeparator()
|
||||
+ "| teleportintercept | `" + plugin.getMVConfig().getTeleportIntercept() + "` |" + System.lineSeparator()
|
||||
+ "| firstspawnoverride | `" + plugin.getMVConfig().getFirstSpawnOverride() + "` |" + System.lineSeparator()
|
||||
+ "| firstspawnworld | `" + plugin.getMVConfig().getFirstSpawnWorld() + "` |" + System.lineSeparator()
|
||||
+ "| debug | `" + plugin.getMVConfig().getGlobalDebug() + "` |" + System.lineSeparator();
|
||||
return "# Multiverse-Core" + '\n'
|
||||
+ "## Overview" + '\n'
|
||||
+ "| Name | Value |" + '\n'
|
||||
+ "| --- | --- |" + '\n'
|
||||
+ "| Multiverse-Core Version | `" + this.plugin.getDescription().getVersion() + "` |" + '\n'
|
||||
+ "| Bukkit Version | `" + this.plugin.getServer().getVersion() + "` |" + '\n'
|
||||
+ "| Loaded Worlds | `" + this.plugin.getMVWorldManager().getMVWorlds() + "` |" + '\n'
|
||||
+ "| Multiverse Plugins Loaded | `" + this.plugin.getPluginCount() + "` |" + '\n'
|
||||
+ "| Economy being used | `" + plugin.getEconomist().getEconomyName() + "` |" + '\n'
|
||||
+ "| Permissions Plugin | `" + this.plugin.getMVPerms().getType() + "` |" + '\n'
|
||||
+ "## Parsed Config" + '\n'
|
||||
+ "These are what Multiverse thought the in-memory values of the config were." + "\n\n"
|
||||
+ "| Config Key | Value |" + '\n'
|
||||
+ "| --- | --- |" + '\n'
|
||||
+ "| version | `" + this.plugin.getMVConfig().getVersion() + "` |" + '\n'
|
||||
+ "| messagecooldown | `" + plugin.getMessaging().getCooldown() + "` |" + '\n'
|
||||
+ "| teleportcooldown | `" + plugin.getMVConfig().getTeleportCooldown() + "` |" + '\n'
|
||||
+ "| worldnameprefix | `" + plugin.getMVConfig().getPrefixChat() + "` |" + '\n'
|
||||
+ "| worldnameprefixFormat | `" + plugin.getMVConfig().getPrefixChatFormat() + "` |" + '\n'
|
||||
+ "| enforceaccess | `" + plugin.getMVConfig().getEnforceAccess() + "` |" + '\n'
|
||||
+ "| displaypermerrors | `" + plugin.getMVConfig().getDisplayPermErrors() + "` |" + '\n'
|
||||
+ "| teleportintercept | `" + plugin.getMVConfig().getTeleportIntercept() + "` |" + '\n'
|
||||
+ "| firstspawnoverride | `" + plugin.getMVConfig().getFirstSpawnOverride() + "` |" + '\n'
|
||||
+ "| firstspawnworld | `" + plugin.getMVConfig().getFirstSpawnWorld() + "` |" + '\n'
|
||||
+ "| debug | `" + plugin.getMVConfig().getGlobalDebug() + "` |" + '\n';
|
||||
}
|
||||
|
||||
private void addVersionInfoToEvent(MVVersionEvent event) {
|
||||
@@ -114,15 +109,16 @@ public class VersionCommand extends MultiverseCommand {
|
||||
event.appendVersionInfo(this.getLegacyString());
|
||||
|
||||
// add the legacy file, but as markdown so it's readable
|
||||
event.putDetailedVersionInfo("version.md", this.getMarkdownString());
|
||||
// TODO Readd this in 5.0.0
|
||||
// event.putDetailedVersionInfo("version.md", this.getMarkdownString());
|
||||
|
||||
// add config.yml
|
||||
File configFile = new File(this.plugin.getDataFolder(), "config.yml");
|
||||
event.putDetailedVersionInfo("version.md", configFile);
|
||||
event.putDetailedVersionInfo("multiverse-core/config.yml", configFile);
|
||||
|
||||
// add worlds.yml
|
||||
File worldsFile = new File(this.plugin.getDataFolder(), "worlds.yml");
|
||||
event.putDetailedVersionInfo("version.md", worldsFile);
|
||||
event.putDetailedVersionInfo("multiverse-core/worlds.yml", worldsFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -138,18 +134,20 @@ public class VersionCommand extends MultiverseCommand {
|
||||
this.plugin.getServer().getPluginManager().callEvent(versionEvent);
|
||||
|
||||
if (CommandHandler.hasFlag("--include-plugin-list", args)) {
|
||||
versionEvent.appendVersionInfo(System.lineSeparator() + "Plugins: " + getPluginList());
|
||||
versionEvent.appendVersionInfo('\n' + "Plugins: " + getPluginList());
|
||||
versionEvent.putDetailedVersionInfo("plugins.txt", "Plugins: " + getPluginList());
|
||||
}
|
||||
|
||||
final String versionInfo = versionEvent.getVersionInfo();
|
||||
versionEvent.putDetailedVersionInfo("version.txt", versionInfo);
|
||||
|
||||
final Map<String, String> files = versionEvent.getDetailedVersionInfo();
|
||||
|
||||
// log to console
|
||||
String[] lines = versionInfo.split(System.lineSeparator());
|
||||
String[] lines = versionInfo.split("\\r?\\n");
|
||||
for (String line : lines) {
|
||||
if (!line.isEmpty()) {
|
||||
Logging.info(line);
|
||||
this.plugin.getServer().getLogger().info(line);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.bukkit.util.Vector;
|
||||
* A bed-{@link MVDestination}.
|
||||
*/
|
||||
public class BedDestination implements MVDestination {
|
||||
public static final String OLD_BED_STRING = "b:playerbed";
|
||||
public static final String OWN_BED_STRING = "playerbed";
|
||||
private String playername = "";
|
||||
private boolean isValid;
|
||||
private Location knownBedLoc;
|
||||
@@ -46,11 +46,11 @@ public class BedDestination implements MVDestination {
|
||||
boolean validFormat = split.length >= 1 && split.length <= 2 && split[0].equals(this.getIdentifier());
|
||||
|
||||
OfflinePlayer p = Bukkit.getOfflinePlayer(split[1]);
|
||||
boolean validPlayer = (p != null);
|
||||
boolean validPlayer = p.getName() != null && !p.getName().equals(OWN_BED_STRING);
|
||||
|
||||
if (validFormat && validPlayer) this.playername = p.getName();
|
||||
|
||||
this.isValid = destination.equals(OLD_BED_STRING) || (validFormat && validPlayer);
|
||||
this.isValid = destination.equals("b:" + OWN_BED_STRING) || (validFormat && validPlayer);
|
||||
|
||||
return this.isValid;
|
||||
}
|
||||
@@ -136,6 +136,6 @@ public class BedDestination implements MVDestination {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return playername.isEmpty() ? OLD_BED_STRING : ("b:" + playername);
|
||||
return "b:" + (playername.isEmpty() ? OWN_BED_STRING : playername);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.onarandombox.MultiverseCore.utils;
|
||||
|
||||
/**
|
||||
* A utility class that enables automated tests to flag Multiverse for testing. This allows Multiverse to not perform
|
||||
* certain behaviors such as enabled stats uploads.
|
||||
*/
|
||||
public class TestingMode {
|
||||
|
||||
private static boolean enabled = false;
|
||||
|
||||
public static void enable() {
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
public static boolean isDisabled() {
|
||||
return !enabled;
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,6 @@ import java.util.Arrays;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
@@ -63,6 +62,8 @@ public class WorldManager implements MVWorldManager {
|
||||
private Map<String, String> defaultGens;
|
||||
private String firstSpawn;
|
||||
|
||||
private static final List<String> CLONE_IGNORE_FILES = Arrays.asList("session.lock", "uid.dat");
|
||||
|
||||
public WorldManager(MultiverseCore core) {
|
||||
this.plugin = core;
|
||||
this.worldsFromTheConfig = new HashMap<String, WorldProperties>();
|
||||
@@ -95,6 +96,190 @@ public class WorldManager implements MVWorldManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes cloning easier to understand and manage.
|
||||
*/
|
||||
private class CloneHelper {
|
||||
private String oldName;
|
||||
private String newName;
|
||||
private File oldWorldFile;
|
||||
private File newWorldFile;
|
||||
private MultiverseWorld oldWorld;
|
||||
|
||||
public CloneHelper(String oldName, String newName) {
|
||||
this.oldName = oldName;
|
||||
this.newName = newName;
|
||||
}
|
||||
|
||||
/**
|
||||
* The clone operation.
|
||||
*
|
||||
* @return True if clone is successful, false otherwise.
|
||||
*/
|
||||
public boolean run() {
|
||||
if (!validCloneParameters()) {
|
||||
Logging.warning("Invalid clone parameters");
|
||||
return false;
|
||||
}
|
||||
|
||||
initWorldFiles();
|
||||
if (newWorldFile.exists()) {
|
||||
Logging.warning("Folder for new world '%s' already exists", newName);
|
||||
return false;
|
||||
}
|
||||
|
||||
oldWorld = getMVWorld(oldName);
|
||||
if (!isOldWorldLoadable()) {
|
||||
Logging.severe("Old world '%s' is not loadable", oldName);
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean wasAutoSave = manuallySaveWorld();
|
||||
|
||||
if (!copyWorldFolder()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
revertBackAutoSave(wasAutoSave);
|
||||
|
||||
return initNewCloneWorld();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that world with oldName can be clone to a world called newName.
|
||||
*
|
||||
* @return True if parameters are valid, otherwise false.
|
||||
*/
|
||||
private boolean validCloneParameters() {
|
||||
String originalOldName = oldName;
|
||||
if (!isWorldFromConfig(oldName)) {
|
||||
oldName = getWorldByAliasFromConfig(oldName);
|
||||
}
|
||||
|
||||
if (oldName == null) {
|
||||
Logging.warning("Old world '%s' does not exist", originalOldName);
|
||||
return false;
|
||||
}
|
||||
if (isWorldFromConfig(newName)) {
|
||||
Logging.warning("New world '%s' already exists", newName);
|
||||
return false;
|
||||
}
|
||||
if (!isValidWorldName(newName)) {
|
||||
Logging.warning("New world name '%s' is invalid", newName);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get world folders from world container.
|
||||
*/
|
||||
private void initWorldFiles() {
|
||||
oldWorldFile = new File(plugin.getServer().getWorldContainer(), oldName);
|
||||
newWorldFile = new File(plugin.getServer().getWorldContainer(), newName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that old world can be loaded and saved properly.
|
||||
*
|
||||
* @return True if old world can be loaded successfully, false otherwise.
|
||||
*/
|
||||
private boolean isOldWorldLoadable() {
|
||||
if (oldWorld != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Logging.fine("Old world '%s' is currently unloaded. Attempting to load it...", oldName);
|
||||
WorldProperties props = worldsFromTheConfig.get(oldName);
|
||||
boolean wasLoadSpawn = worldsFromTheConfig.get(oldName).isKeepingSpawnInMemory();
|
||||
if (wasLoadSpawn) {
|
||||
props.setKeepSpawnInMemory(false);
|
||||
}
|
||||
|
||||
if (!loadWorld(oldName)) {
|
||||
Logging.severe("Failed to load the old world '%s'", oldName);
|
||||
return false;
|
||||
}
|
||||
|
||||
getMVWorld(oldName).getCBWorld().setAutoSave(false);
|
||||
|
||||
if (!unloadWorld(oldName, true)) {
|
||||
Logging.severe("Failed to unload the old world '%S'", oldName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (wasLoadSpawn) {
|
||||
props.setKeepSpawnInMemory(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicating old world folder to the new world folder.
|
||||
*
|
||||
* @return True if copy process was successful, false otherwise.
|
||||
*/
|
||||
private boolean copyWorldFolder() {
|
||||
Logging.fine("Copying files for world '%s'", oldName);
|
||||
if (!FileUtils.copyFolder(oldWorldFile, newWorldFile, CLONE_IGNORE_FILES, Logging.getLogger()) || !newWorldFile.exists()) {
|
||||
Logging.severe("Failed to copy files for world '%s', see the log info", newName);
|
||||
return false;
|
||||
}
|
||||
Logging.fine("Succeeded at copying files");
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure world is save being copying world files.
|
||||
*
|
||||
* @return Previous auto-save setting for the old world.
|
||||
*/
|
||||
private boolean manuallySaveWorld() {
|
||||
if (oldWorld != null && oldWorld.getCBWorld().isAutoSave()) {
|
||||
Logging.config("Saving world '%s'", oldName);
|
||||
oldWorld.getCBWorld().setAutoSave(false);
|
||||
oldWorld.getCBWorld().save();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void revertBackAutoSave(boolean wasAutoSave) {
|
||||
if (oldWorld != null && wasAutoSave) {
|
||||
Logging.fine("Revert back to enabling auto-save");
|
||||
oldWorld.getCBWorld().setAutoSave(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize new properties with old ones.
|
||||
*/
|
||||
private void copyPropertiesToNewWorld() {
|
||||
WorldProperties newProps = new WorldProperties();
|
||||
newProps.copyValues(worldsFromTheConfig.get(oldName));
|
||||
newProps.setAlias(""); // don't keep the alias the same -- that would be useless
|
||||
worldsFromTheConfig.put(newName, newProps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load up the newly copied clone world.
|
||||
*/
|
||||
private boolean initNewCloneWorld() {
|
||||
copyPropertiesToNewWorld();
|
||||
if (!saveWorldsConfig()) {
|
||||
Logging.severe("Failed to save worlds.yml");
|
||||
return false;
|
||||
}
|
||||
if (!doLoad(newName)) {
|
||||
Logging.severe("Failed to load the cloned world '" + newName + "'");
|
||||
return false;
|
||||
}
|
||||
Logging.fine("Succeeded at loading cloned world '" + newName + "'");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @deprecated Use {@link #cloneWorld(String, String)} instead.
|
||||
@@ -110,119 +295,7 @@ public class WorldManager implements MVWorldManager {
|
||||
*/
|
||||
@Override
|
||||
public boolean cloneWorld(String oldName, String newName) {
|
||||
// Make sure we already know about the old world and that we don't
|
||||
// already know about the new world.
|
||||
if (!this.worldsFromTheConfig.containsKey(oldName)) {
|
||||
for (Map.Entry<String, WorldProperties> entry : this.worldsFromTheConfig.entrySet()) {
|
||||
if (oldName.equals(entry.getValue().getAlias())) {
|
||||
oldName = entry.getKey();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!this.worldsFromTheConfig.containsKey(oldName)) {
|
||||
Logging.warning("Old world '%s' does not exist", oldName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (this.isMVWorld(newName)) {
|
||||
Logging.warning("New world '%s' already exists", newName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for valid world name
|
||||
if (!(isValidWorldName(oldName) && isValidWorldName(newName))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final File oldWorldFile = new File(this.plugin.getServer().getWorldContainer(), oldName);
|
||||
final File newWorldFile = new File(this.plugin.getServer().getWorldContainer(), newName);
|
||||
final List<String> ignoreFiles = new ArrayList<>(Arrays.asList("session.lock", "uid.dat"));
|
||||
|
||||
// Make sure the new world doesn't exist outside of multiverse.
|
||||
if (newWorldFile.exists()) {
|
||||
Logging.warning("File for new world '%s' already exists", newName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load the old world... but just the metadata.
|
||||
boolean wasJustLoaded = false;
|
||||
boolean wasLoadSpawn = false;
|
||||
if (this.plugin.getServer().getWorld(oldName) == null) {
|
||||
wasJustLoaded = true;
|
||||
WorldProperties props = this.worldsFromTheConfig.get(oldName);
|
||||
wasLoadSpawn = props.isKeepingSpawnInMemory();
|
||||
if (wasLoadSpawn) {
|
||||
// No chunks please.
|
||||
props.setKeepSpawnInMemory(false);
|
||||
}
|
||||
if (!this.loadWorld(oldName)) {
|
||||
return false;
|
||||
}
|
||||
this.plugin.getServer().getWorld(oldName).setAutoSave(false);
|
||||
}
|
||||
|
||||
// Grab a bit of metadata from the old world.
|
||||
MVWorld oldWorld = (MVWorld) getMVWorld(oldName);
|
||||
Environment environment = oldWorld.getEnvironment();
|
||||
String seedString = oldWorld.getSeed() + "";
|
||||
WorldType worldType = oldWorld.getWorldType();
|
||||
Boolean generateStructures = oldWorld.getCBWorld().canGenerateStructures();
|
||||
String generator = oldWorld.getGenerator();
|
||||
boolean useSpawnAdjust = oldWorld.getAdjustSpawn();
|
||||
|
||||
// Don't need the loaded world anymore.
|
||||
if (wasJustLoaded) {
|
||||
this.unloadWorld(oldName, true);
|
||||
oldWorld = null;
|
||||
if (wasLoadSpawn) {
|
||||
this.worldsFromTheConfig.get(oldName).setKeepSpawnInMemory(true);
|
||||
}
|
||||
}
|
||||
|
||||
boolean wasAutoSave = false;
|
||||
if (oldWorld != null && oldWorld.getCBWorld().isAutoSave()) {
|
||||
wasAutoSave = true;
|
||||
Logging.config("Saving world '%s'", oldName);
|
||||
oldWorld.getCBWorld().setAutoSave(false);
|
||||
oldWorld.getCBWorld().save();
|
||||
}
|
||||
Logging.config("Copying files for world '%s'", oldName);
|
||||
if (!FileUtils.copyFolder(oldWorldFile, newWorldFile, ignoreFiles, Logging.getLogger())) {
|
||||
Logging.warning("Failed to copy files for world '%s', see the log info", newName);
|
||||
return false;
|
||||
}
|
||||
if (oldWorld != null && wasAutoSave) {
|
||||
oldWorld.getCBWorld().setAutoSave(true);
|
||||
}
|
||||
|
||||
if (newWorldFile.exists()) {
|
||||
Logging.fine("Succeeded at copying files");
|
||||
|
||||
// initialize new properties with old ones
|
||||
WorldProperties newProps = new WorldProperties();
|
||||
newProps.copyValues(this.worldsFromTheConfig.get(oldName));
|
||||
// don't keep the alias the same -- that would be useless
|
||||
newProps.setAlias("");
|
||||
// store the new properties in worlds config map
|
||||
this.worldsFromTheConfig.put(newName, newProps);
|
||||
|
||||
// save the worlds config to disk (worlds.yml)
|
||||
if (!saveWorldsConfig()) {
|
||||
this.plugin.log(Level.SEVERE, "Failed to save worlds.yml");
|
||||
return false;
|
||||
}
|
||||
|
||||
// actually load the world
|
||||
if (doLoad(newName)) {
|
||||
this.plugin.log(Level.FINE, "Succeeded at loading cloned world '" + newName + "'");
|
||||
return true;
|
||||
}
|
||||
this.plugin.log(Level.SEVERE, "Failed to load the cloned world '" + newName + "'");
|
||||
return false;
|
||||
}
|
||||
|
||||
Logging.warning("Failed to copy files for world '%s', see the log info", newName);
|
||||
return false;
|
||||
return new CloneHelper(oldName, newName).run();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -525,6 +598,13 @@ public class WorldManager implements MVWorldManager {
|
||||
*/
|
||||
@Override
|
||||
public boolean deleteWorld(String name, boolean removeFromConfig, boolean deleteWorldFolder) {
|
||||
if (this.hasUnloadedWorld(name, false)) {
|
||||
// Attempt to load if unloaded so we can actually delete the world
|
||||
if (!this.doLoad(name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
World world = this.plugin.getServer().getWorld(name);
|
||||
if (world == null) {
|
||||
// We can only delete loaded worlds
|
||||
@@ -696,6 +776,19 @@ public class WorldManager implements MVWorldManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isWorldFromConfig(String name) {
|
||||
return this.worldsFromTheConfig.containsKey(name);
|
||||
}
|
||||
|
||||
private String getWorldByAliasFromConfig(String name) {
|
||||
return this.worldsFromTheConfig.entrySet()
|
||||
.stream()
|
||||
.filter(worldEntry -> name.equals(worldEntry.getValue().getAlias()))
|
||||
.map(Map.Entry::getKey)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@@ -937,6 +1030,9 @@ public class WorldManager implements MVWorldManager {
|
||||
return this.configWorlds;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean hasUnloadedWorld(String name, boolean includeLoaded) {
|
||||
if (getMVWorld(name) != null) {
|
||||
|
||||
@@ -64,6 +64,7 @@ public class TestInstanceCreator {
|
||||
public static final File worldsDirectory = new File("bin/test/server");
|
||||
|
||||
public boolean setUp() {
|
||||
TestingMode.enable();
|
||||
try {
|
||||
pluginDirectory.mkdirs();
|
||||
assertTrue(pluginDirectory.exists());
|
||||
|
||||
Reference in new issue
Block a user