package com.plotsquared.bukkit.database.plotme;
import com.intellectualcrafters.configuration.ConfigurationSection;
import com.intellectualcrafters.configuration.MemorySection;
import com.intellectualcrafters.configuration.file.FileConfiguration;
import com.intellectualcrafters.configuration.file.YamlConfiguration;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.util.TaskManager;
import com.plotsquared.bukkit.generator.BukkitPlotGenerator;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.WorldCreator;
import org.bukkit.command.CommandException;
public class LikePlotMeConverter {
private final String plugin;
public LikePlotMeConverter(String plugin) {
this.plugin = plugin;
}
public static String getWorld(String world) {
for (World newWorld : Bukkit.getWorlds()) {
if (newWorld.getName().equalsIgnoreCase(world)) {
return newWorld.getName();
}
}
return world;
}
private void sendMessage(String message) {
PS.debug("&3PlotMe&8->&3" + PS.imp().getPluginName() + "&8: &7" + message);
}
public String getPlotMePath() {
return new File(".").getAbsolutePath() + File.separator + "plugins" + File.separator + plugin + File.separator;
}
public FileConfiguration getPlotMeConfig(String dataFolder) {
File plotMeFile = new File(dataFolder + "config.yml");
if (!plotMeFile.exists()) {
return null;
}
return YamlConfiguration.loadConfiguration(plotMeFile);
}
public Set<String> getPlotMeWorlds(FileConfiguration plotConfig) {
return plotConfig.getConfigurationSection("worlds").getKeys(false);
}
public void mergeWorldYml(FileConfiguration plotConfig) {
try {
File genConfig =
new File("plugins" + File.separator + plugin + File.separator + "PlotMe-DefaultGenerator" + File.separator + "config.yml");
if (genConfig.exists()) {
YamlConfiguration yml = YamlConfiguration.loadConfiguration(genConfig);
for (String key : yml.getKeys(true)) {
if (!plotConfig.contains(key)) {
Object value = yml.get(key);
if (!(value instanceof MemorySection)) {
plotConfig.set(key, value);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void updateWorldYml(String location) {
try {
Path path = Paths.get(location);
File file = new File(location);
if (!file.exists()) {
return;
}
String content = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
String pluginName = PS.imp().getPluginName();
content = content.replace("PlotMe-DefaultGenerator", pluginName);
content = content.replace("PlotMe", pluginName);
content = content.replace("AthionPlots", pluginName);
content = content.replace("PlotZWorld", pluginName);
Files.write(path, content.getBytes(StandardCharsets.UTF_8));
} catch (IOException ignored) {}
}
private void copyConfig(ConfigurationSection plotmeDgYml, String world) throws IOException {
String actualWorldName = getWorld(world);
String plotMeWorldName = world.toLowerCase();
Integer pathWidth = plotmeDgYml.getInt("worlds." + plotMeWorldName + ".PathWidth"); //
PS.get().worlds.set("worlds." + world + ".road.width", pathWidth);
int height = plotmeDgYml.getInt("worlds." + plotMeWorldName + ".RoadHeight", plotmeDgYml.getInt("worlds." + plotMeWorldName + ".GroundHeight", 64)); //
PS.get().worlds.set("worlds." + world + ".road.height", height);
PS.get().worlds.set("worlds." + world + ".wall.height", height);
PS.get().worlds.set("worlds." + world + ".plot.height", height);
int plotSize = plotmeDgYml.getInt("worlds." + plotMeWorldName + ".PlotSize", 32); //
PS.get().worlds.set("worlds." + world + ".plot.size", plotSize);
String wallblock = plotmeDgYml.getString("worlds." + plotMeWorldName + ".UnclaimedBorder", plotmeDgYml.getString("worlds." + plotMeWorldName + ".WallBlock", "44")); //
PS.get().worlds.set("worlds." + world + ".wall.block", wallblock);
String claimed = plotmeDgYml.getString("worlds." + plotMeWorldName + ".ProtectedWallBlock", "44:1"); //
PS.get().worlds.set("worlds." + world + ".wall.block_claimed", claimed);
String floor = plotmeDgYml.getString("worlds." + plotMeWorldName + ".PlotFloorBlock", "2"); //
PS.get().worlds.set("worlds." + world + ".plot.floor", Collections.singletonList(floor));
String filling = plotmeDgYml.getString("worlds." + plotMeWorldName + ".FillBlock", "3"); //
PS.get().worlds.set("worlds." + world + ".plot.filling", Collections.singletonList(filling));
String road = plotmeDgYml.getString("worlds." + plotMeWorldName + ".RoadMainBlock", "5");
PS.get().worlds.set("worlds." + world + ".road.block", road);
PS.get().worlds.set("worlds." + actualWorldName + ".road.height", height);
PS.get().worlds.set("worlds." + actualWorldName + ".plot.height", height);
PS.get().worlds.set("worlds." + actualWorldName + ".wall.height", height);
PS.get().worlds.save(PS.get().worldsFile);
}
public boolean run(APlotMeConnector connector) {
try {
String dataFolder = getPlotMePath();
FileConfiguration plotConfig = getPlotMeConfig(dataFolder);
if (plotConfig == null) {
return false;
}
String version = plotConfig.getString("Version");
if (version == null) {
version = plotConfig.getString("version");
}
if (!connector.accepts(version)) {
return false;
}
PS.debug("&3Using connector: " + connector.getClass().getCanonicalName());
Connection connection = connector.getPlotMeConnection(plugin,plotConfig, dataFolder);
if (!connector.isValidConnection(connection)) {
sendMessage("Cannot connect to PlotMe DB. Conversion process will not continue");
return false;
}
sendMessage("PlotMe conversion has started. To disable this, please set 'enabled-components -> plotme-converter' to false in the 'settings.yml'");
mergeWorldYml(plotConfig);
sendMessage("Connecting to PlotMe DB");
ArrayList<Plot> createdPlots = new ArrayList<>();
sendMessage("Collecting plot data");
String dbPrefix = "PlotMe".toLowerCase();
sendMessage(" - " + dbPrefix + "Plots");
final Set<String> worlds = getPlotMeWorlds(plotConfig);
if (Settings.Enabled_Components.PLOTME_CONVERTER) {
sendMessage("Updating bukkit.yml");
updateWorldYml("bukkit.yml");
updateWorldYml("plugins/Multiverse-Core/worlds.yml");
for (String world : plotConfig.getConfigurationSection("worlds").getKeys(false)) {
sendMessage("Copying config for: " + world);
try {
String actualWorldName = getWorld(world);
connector.copyConfig(plotConfig, world, actualWorldName);
PS.get().worlds.save(PS.get().worldsFile);
} catch (IOException e) {
e.printStackTrace();
sendMessage("&c-- &lFailed to save configuration for world '" + world
+ "'\nThis will need to be done using the setup command, or manually");
}
}
}
HashMap<String, HashMap<PlotId, Plot>> plots = connector.getPlotMePlots(connection);
int plotCount = 0;
for (Entry<String, HashMap<PlotId, Plot>> entry : plots.entrySet()) {
plotCount += entry.getValue().size();
}
if (!Settings.Enabled_Components.PLOTME_CONVERTER) {
return false;
}
sendMessage(" - " + dbPrefix + "Allowed");
sendMessage("Collected " + plotCount + " plots from PlotMe");
File plotmeDgFile = new File(dataFolder + File.separator + "PlotMe-DefaultGenerator" + File.separator + "config.yml");
if (plotmeDgFile.exists()) {
YamlConfiguration plotmeDgYml = YamlConfiguration.loadConfiguration(plotmeDgFile);
try {
HashSet<String> allWorlds = new HashSet<>(plots.keySet());
allWorlds.addAll(worlds);
for (String world : allWorlds) {
copyConfig(plotmeDgYml, world);
}
} catch (IOException ignored) {
ignored.printStackTrace();
}
}
for (Entry<String, HashMap<PlotId, Plot>> entry : plots.entrySet()) {
String world = entry.getKey();
PlotArea area = PS.get().getPlotArea(world, null);
int duplicate = 0;
if (area != null) {
for (Entry<PlotId, Plot> entry2 : entry.getValue().entrySet()) {
if (area.getOwnedPlotAbs(entry2.getKey()) != null) {
duplicate++;
} else {
createdPlots.add(entry2.getValue());
}
}
if (duplicate > 0) {
PS.debug("&c[WARNING] Found " + duplicate + " duplicate plots already in DB for world: '" + world
+ "'. Have you run the converter already?");
}
} else {
if (PS.get().plots_tmp != null) {
HashMap<PlotId, Plot> map = PS.get().plots_tmp.get(world);
if (map != null) {
for (Entry<PlotId, Plot> entry2 : entry.getValue().entrySet()) {
if (map.containsKey(entry2.getKey())) {
duplicate++;
} else {
createdPlots.add(entry2.getValue());
}
}
if (duplicate > 0) {
PS.debug("&c[WARNING] Found " + duplicate + " duplicate plots already in DB for world: '" + world
+ "'. Have you run the converter already?");
}
continue;
}
}
createdPlots.addAll(entry.getValue().values());
}
}
sendMessage("Creating plot DB");
Thread.sleep(1000);
final AtomicBoolean done = new AtomicBoolean(false);
DBFunc.createPlotsAndData(createdPlots, new Runnable() {
@Override
public void run() {
if (done.get()) {
done();
sendMessage("&aDatabase conversion is now complete!");
PS.debug("&c - Stop the server");
PS.debug("&c - Disable 'plotme-converter' and 'plotme-convert.cache-uuids' in the settings.yml");
PS.debug("&c - Correct any generator settings that haven't copied to 'settings.yml' properly");
PS.debug("&c - Start the server");
PS.get().setPlots(DBFunc.getPlots());
} else {
sendMessage("&cPlease wait until database conversion is complete. You will be notified with instructions when this happens!");
done.set(true);
}
}
});
sendMessage("Saving configuration...");
try {
PS.get().worlds.save(PS.get().worldsFile);
} catch (IOException ignored) {
sendMessage(" - &cFailed to save configuration.");
}
TaskManager.runTask(new Runnable() {
@Override
public void run() {
try {
boolean mv = false;
boolean mw = false;
if ((Bukkit.getPluginManager().getPlugin("Multiverse-Core") != null) && Bukkit.getPluginManager().getPlugin("Multiverse-Core")
.isEnabled()) {
mv = true;
} else if ((Bukkit.getPluginManager().getPlugin("MultiWorld") != null) && Bukkit.getPluginManager().getPlugin("MultiWorld")
.isEnabled()) {
mw = true;
}
for (String worldName : worlds) {
World world = Bukkit.getWorld(getWorld(worldName));
if (world == null) {
sendMessage("&cInvalid world in PlotMe configuration: " + worldName);
continue;
}
String actualWorldName = world.getName();
sendMessage("Reloading generator for world: '" + actualWorldName + "'...");
if (!Bukkit.getWorlds().isEmpty() && Bukkit.getWorlds().get(0).getName().equals(worldName)) {
sendMessage("&cYou need to stop the server to reload this world properly");
} else {
PS.get().removePlotAreas(actualWorldName);
if (mv) {
// unload world with MV
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mv unload " + actualWorldName);
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
}
// load world with MV
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(),
"mv import " + actualWorldName + " normal -g " + PS.imp().getPluginName());
} else if (mw) {
// unload world with MW
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mw unload " + actualWorldName);
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
}
// load world with MW
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(),
"mw create " + actualWorldName + " plugin:" + PS.imp().getPluginName());
} else {
// Load using Bukkit API
// - User must set generator manually
Bukkit.getServer().unloadWorld(world, true);
World myWorld = WorldCreator.name(actualWorldName).generator(new BukkitPlotGenerator(PS.get().IMP.getDefaultGenerator())).createWorld();
myWorld.save();
}
}
}
} catch (CommandException e) {
e.printStackTrace();
}
if (done.get()) {
done();
sendMessage("&aDatabase conversion is now complete!");
PS.debug("&c - Stop the server");
PS.debug("&c - Disable 'plotme-converter' and 'plotme-convert.cache-uuids' in the settings.yml");
PS.debug("&c - Correct any generator settings that haven't copied to 'settings.yml' properly");
PS.debug("&c - Start the server");
} else {
sendMessage("&cPlease wait until database conversion is complete. You will be notified with instructions when this happens!");
done.set(true);
}
}
});
} catch (InterruptedException | SQLException e) {
e.printStackTrace();
PS.debug("&/end/");
}
return true;
}
public void done() {
PS.get().setPlots(DBFunc.getPlots());
}
}