package com.intellectualcrafters.plot.commands; import com.intellectualcrafters.plot.PS; import com.intellectualcrafters.plot.database.DBFunc; import com.intellectualcrafters.plot.database.MySQL; import com.intellectualcrafters.plot.database.SQLManager; import com.intellectualcrafters.plot.database.SQLite; import com.intellectualcrafters.plot.object.Plot; import com.intellectualcrafters.plot.object.PlotArea; import com.intellectualcrafters.plot.object.PlotId; import com.intellectualcrafters.plot.object.PlotPlayer; import com.intellectualcrafters.plot.object.worlds.SinglePlotArea; import com.intellectualcrafters.plot.util.MainUtil; import com.intellectualcrafters.plot.util.TaskManager; import com.plotsquared.general.commands.CommandDeclaration; import java.io.File; import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; @CommandDeclaration( command = "database", aliases = {"convert"}, category = CommandCategory.ADMINISTRATION, permission = "plots.database", description = "Convert/Backup Storage", requiredType = RequiredType.CONSOLE, usage = "/plot database [area] <sqlite|mysql|import>") public class Database extends SubCommand { public static void insertPlots(final SQLManager manager, final List<Plot> plots, final PlotPlayer player) { TaskManager.runTaskAsync(new Runnable() { @Override public void run() { try { ArrayList<Plot> ps = new ArrayList<>(); for (Plot p : plots) { ps.add(p); } MainUtil.sendMessage(player, "&6Starting..."); manager.createPlotsAndData(ps, new Runnable() { @Override public void run() { MainUtil.sendMessage(player, "&6Database conversion finished!"); manager.close(); } }); } catch (Exception e) { MainUtil.sendMessage(player, "Failed to insert plot objects, see stacktrace for info"); e.printStackTrace(); } } }); } @Override public boolean onCommand(final PlotPlayer player, String[] args) { if (args.length < 1) { MainUtil.sendMessage(player, "/plot database [area] <sqlite|mysql|import>"); return false; } List<Plot> plots; PlotArea area = PS.get().getPlotAreaByString(args[0]); if (area != null) { plots = PS.get().sortPlotsByTemp(area.getPlots()); args = Arrays.copyOfRange(args, 1, args.length); } else { plots = PS.get().sortPlotsByTemp(PS.get().getPlots()); } if (args.length < 1) { MainUtil.sendMessage(player, "/plot database [world] <sqlite|mysql|import>"); MainUtil.sendMessage(player, "[arg] indicates an optional argument"); return false; } try { com.intellectualcrafters.plot.database.Database implementation; String prefix = ""; switch (args[0].toLowerCase()) { case "import": if (args.length < 2) { MainUtil.sendMessage(player, "/plot database import <sqlite file> [prefix]"); return false; } File file = MainUtil.getFile(PS.get().IMP.getDirectory(), args[1].endsWith(".db") ? args[1] : args[1] + ".db"); if (!file.exists()) { MainUtil.sendMessage(player, "&6Database does not exist: " + file); return false; } MainUtil.sendMessage(player, "&6Starting..."); implementation = new SQLite(file); SQLManager manager = new SQLManager(implementation, args.length == 3 ? args[2] : "", true); HashMap<String, HashMap<PlotId, Plot>> map = manager.getPlots(); plots = new ArrayList<>(); for (Entry<String, HashMap<PlotId, Plot>> entry : map.entrySet()) { String areaname = entry.getKey(); PlotArea pa = PS.get().getPlotAreaByString(areaname); if (pa != null) { for (Entry<PlotId, Plot> entry2 : entry.getValue().entrySet()) { Plot plot = entry2.getValue(); if (pa.getOwnedPlotAbs(plot.getId()) != null) { if (pa instanceof SinglePlotArea) { Plot newPlot = pa.getNextFreePlot(null, plot.getId()); if (newPlot != null) { PlotId newId = newPlot.getId(); PlotId id = plot.getId(); File worldFile = new File(PS.imp().getWorldContainer(), id.toCommaSeparatedString()); if (worldFile.exists()) { File newFile = new File(PS.imp().getWorldContainer(), newId.toCommaSeparatedString()); worldFile.renameTo(newFile); } id.x = newId.x; id.y = newId.y; id.recalculateHash(); plot.setArea(pa); plots.add(plot); continue; } } MainUtil.sendMessage(player, "Skipping duplicate plot: " + plot + " | id=" + plot.temp); continue; } plot.setArea(pa); plots.add(plot); } } else { HashMap<PlotId, Plot> plotmap = PS.get().plots_tmp.get(areaname); if (plotmap == null) { plotmap = new HashMap<>(); PS.get().plots_tmp.put(areaname, plotmap); } plotmap.putAll(entry.getValue()); } } DBFunc.createPlotsAndData(plots, new Runnable() { @Override public void run() { MainUtil.sendMessage(player, "&6Database conversion finished!"); } }); return true; case "mysql": if (args.length < 6) { return MainUtil.sendMessage(player, "/plot database mysql [host] [port] [username] [password] [database] {prefix}"); } String host = args[1]; String port = args[2]; String username = args[3]; String password = args[4]; String database = args[5]; if (args.length > 6) { prefix = args[6]; } implementation = new MySQL(host, port, database, username, password); break; case "sqlite": if (args.length < 2) { return MainUtil.sendMessage(player, "/plot database sqlite [file]"); } File sqliteFile = MainUtil.getFile(PS.get().IMP.getDirectory(), args[1] + ".db"); implementation = new SQLite(sqliteFile); break; default: return MainUtil.sendMessage(player, "/plot database [sqlite/mysql]"); } try { SQLManager manager = new SQLManager(implementation, prefix, true); Database.insertPlots(manager, plots, player); return true; } catch (ClassNotFoundException | SQLException e) { MainUtil.sendMessage(player, "$1Failed to save plots, read stacktrace for info"); MainUtil.sendMessage(player, "&d==== Here is an ugly stacktrace, if you are interested in those things ==="); e.printStackTrace(); MainUtil.sendMessage(player, "&d==== End of stacktrace ===="); MainUtil.sendMessage(player, "$1Please make sure you are using the correct arguments!"); return false; } } catch (ClassNotFoundException | SQLException e) { MainUtil.sendMessage(player, "$1Failed to open connection, read stacktrace for info"); MainUtil.sendMessage(player, "&d==== Here is an ugly stacktrace, if you are interested in those things ==="); e.printStackTrace(); MainUtil.sendMessage(player, "&d==== End of stacktrace ===="); MainUtil.sendMessage(player, "$1Please make sure you are using the correct arguments!"); return false; } } }