From 0b0461f5f46c1156e54e49c3cd42ecd6e7561b89 Mon Sep 17 00:00:00 2001 From: boy0001 Date: Mon, 6 Jul 2015 19:38:37 +1000 Subject: [PATCH] Update checking, plugin disabling, code cleanup Now compatible with various plugin managers: - Will attempt to unload depending/softdepending plugins on disable - Will attempt to load disabled depending/softdepending plugins on enable Update checking: - Currently subscribed to be notified about updates on Spigot - You can use "/plot update" to download the latest version, or specify a new source URL Plugin disabling: - new command /plot disable --- PlotSquared/pom.xml | 2 +- .../intellectualcrafters/plot/BukkitMain.java | 281 +++++++++++++++--- .../intellectualcrafters/plot/IPlotMain.java | 4 + .../com/intellectualcrafters/plot/PS.java | 146 ++++++++- .../plot/commands/Database.java | 2 +- .../plot/commands/Disable.java | 47 +++ .../plot/commands/Update.java | 83 ++++++ .../plot/commands/plugin.java | 32 +- .../plot/database/Database.java | 15 - .../plot/database/MySQL.java | 5 +- .../plot/database/SQLite.java | 3 +- .../plotme/ClassicPlotMeConnector.java | 2 +- .../plot/listeners/PlayerEvents.java | 3 + .../plot/util/ConsoleColors.java | 48 ++- .../plot/util/Updater.java | 32 ++ .../plot/util/bukkit/UUIDHandler.java | 2 +- 16 files changed, 579 insertions(+), 128 deletions(-) create mode 100644 PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Disable.java create mode 100644 PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Update.java create mode 100644 PlotSquared/src/main/java/com/intellectualcrafters/plot/util/Updater.java diff --git a/PlotSquared/pom.xml b/PlotSquared/pom.xml index feb9f887b..dc434168b 100644 --- a/PlotSquared/pom.xml +++ b/PlotSquared/pom.xml @@ -8,7 +8,7 @@ UTF-8 PlotSquared - 2.11.27 + 2.12.0 PlotSquared jar diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/BukkitMain.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/BukkitMain.java index 8429a9e7c..62ac491fa 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/BukkitMain.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/BukkitMain.java @@ -1,21 +1,35 @@ package com.intellectualcrafters.plot; import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.lang.reflect.Field; +import java.net.URLClassLoader; +import java.nio.file.Files; import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Stack; import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Chunk; import org.bukkit.World; +import org.bukkit.command.Command; import org.bukkit.command.PluginCommand; +import org.bukkit.command.SimpleCommandMap; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.Listener; import org.bukkit.generator.ChunkGenerator; import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.plugin.java.JavaPluginLoader; import com.intellectualcrafters.plot.commands.Add; import com.intellectualcrafters.plot.commands.Auto; @@ -42,6 +56,7 @@ import com.intellectualcrafters.plot.commands.DebugSaveTest; import com.intellectualcrafters.plot.commands.DebugUUID; import com.intellectualcrafters.plot.commands.Delete; import com.intellectualcrafters.plot.commands.Deny; +import com.intellectualcrafters.plot.commands.Disable; import com.intellectualcrafters.plot.commands.FlagCmd; import com.intellectualcrafters.plot.commands.Help; import com.intellectualcrafters.plot.commands.Home; @@ -73,6 +88,7 @@ import com.intellectualcrafters.plot.commands.Unclaim; import com.intellectualcrafters.plot.commands.Undeny; import com.intellectualcrafters.plot.commands.Unlink; import com.intellectualcrafters.plot.commands.Untrust; +import com.intellectualcrafters.plot.commands.Update; import com.intellectualcrafters.plot.commands.Visit; import com.intellectualcrafters.plot.commands.WE_Anywhere; import com.intellectualcrafters.plot.commands.list; @@ -136,9 +152,9 @@ import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.bukkit.WorldEditPlugin; public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { - + public static BukkitMain THIS = null; - + private int[] version; @Override @@ -152,14 +168,13 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { if (version.length == 3) { version[2] = Integer.parseInt(split[2]); } - } - catch (Exception e) { + } catch (Exception e) { return false; } } return (version[0] > major) || ((version[0] == major) && (version[1] > minor)) || ((version[0] == major) && (version[1] == minor) && (version[2] >= minor2)); } - + @Override public void onEnable() { THIS = this; @@ -175,6 +190,18 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { } else { log("&dUsing metrics will allow us to improve the plugin, please consider it :)"); } + File file = new File(this.getDirectory() + File.separator + "disabled.yml"); + if (file.exists()) { + try { + String[] split = new String(Files.readAllBytes(file.toPath())).split(","); + for (String plugin : split) { + loadPlugin(plugin); + } + } catch (IOException e) { + e.printStackTrace(); + } + file.delete(); + } List worlds = Bukkit.getWorlds(); if (worlds.size() > 0) { UUIDHandler.cacheAll(worlds.get(0).getName()); @@ -189,40 +216,46 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { } } - @Override public void onDisable() { PS.get().disable(); + try { + unloadRecursively(this); + } + catch (Exception e) {}; THIS = null; } - + @Override public void log(String message) { if (message == null) { return; } message = message.replaceAll("\u00B2", "2"); - if ((THIS == null) || (Bukkit.getServer().getConsoleSender() == null)) { - System.out.println(ChatColor.stripColor(ConsoleColors.fromString(message))); - } else { - message = ChatColor.translateAlternateColorCodes('&', message); - if (!Settings.CONSOLE_COLOR) { - message = ChatColor.stripColor(message); + if (THIS != null && Bukkit.getServer().getConsoleSender() != null) { + try { + message = ChatColor.translateAlternateColorCodes('&', message); + if (!Settings.CONSOLE_COLOR) { + message = ChatColor.stripColor(message); + } + Bukkit.getServer().getConsoleSender().sendMessage(message); + return; } - Bukkit.getServer().getConsoleSender().sendMessage(message); + catch (Throwable e) {}; } + System.out.println(ConsoleColors.fromString(message)); } - + @Override public void disable() { onDisable(); } - + @Override public String getVersion() { return this.getDescription().getVersion(); } - + @Override public void handleKick(UUID uuid, C c) { Player player = Bukkit.getPlayer(uuid); @@ -231,10 +264,12 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { player.teleport(player.getWorld().getSpawnLocation()); } } - + @Override public void registerCommands() { new MainCommand(); + MainCommand.subCommands.add(new Disable()); + MainCommand.subCommands.add(new Update()); MainCommand.subCommands.add(new Template()); MainCommand.subCommands.add(new Setup()); MainCommand.subCommands.add(new DebugUUID()); @@ -257,14 +292,12 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { if (Settings.ENABLE_CLUSTERS) { MainCommand.subCommands.add(new Cluster()); } - MainCommand.subCommands.add(new Trust()); MainCommand.subCommands.add(new Add()); MainCommand.subCommands.add(new Deny()); MainCommand.subCommands.add(new Untrust()); MainCommand.subCommands.add(new Remove()); MainCommand.subCommands.add(new Undeny()); - MainCommand.subCommands.add(new Info()); MainCommand.subCommands.add(new list()); MainCommand.subCommands.add(new Help()); @@ -302,17 +335,17 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { plotCommand.setAliases(Arrays.asList("p", "ps", "plotme", "plot")); plotCommand.setTabCompleter(bcmd); } - + @Override public File getDirectory() { return getDataFolder(); } - + @Override public TaskManager getTaskManager() { return new BukkitTaskManager(); } - + @Override public void runEntityTask() { log(C.PREFIX.s() + "KillAllEntities started."); @@ -354,7 +387,164 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { } }, 20); } - + + public boolean unloadPlugin(Plugin plugin) { + try { + plugin.getClass().getClassLoader().getResources("*"); + } catch (IOException e1) { + e1.printStackTrace(); + } + PluginManager pm = Bukkit.getServer().getPluginManager(); + Map ln; + List pl; + try { + Field lnF = pm.getClass().getDeclaredField("lookupNames"); + lnF.setAccessible(true); + ln = (Map) lnF.get(pm); + + Field plF = pm.getClass().getDeclaredField("plugins"); + plF.setAccessible(true); + pl = (List) plF.get(pm); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + pm.disablePlugin(plugin); + synchronized (pm) { + ln.remove(plugin.getName()); + pl.remove(plugin); + } + JavaPluginLoader jpl = (JavaPluginLoader) plugin.getPluginLoader(); + Field loadersF = null; + try { + loadersF = jpl.getClass().getDeclaredField("loaders"); + loadersF.setAccessible(true); + } catch (Exception e) { + e.printStackTrace(); + } + try { + Map loaderMap = (Map) loadersF.get(jpl); + loaderMap.remove(plugin.getDescription().getName()); + } catch (Exception e) { + e.printStackTrace(); + } + closeClassLoader(plugin); + System.gc(); + System.gc(); + return true; + } + + public boolean closeClassLoader(Plugin plugin) { + try { + ((URLClassLoader) plugin.getClass().getClassLoader()).close(); + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + + public boolean unloadRecursively(Plugin plugin) { + try { + Stack pluginFiles = unloadRecursively(plugin.getName(), plugin, new Stack()); + File file = new File(this.getDirectory() + File.separator + "disabled.yml"); + file.createNewFile(); + String prefix = ""; + String all = ""; + while (pluginFiles.size() > 0) { + String pop = pluginFiles.pop(); + all += prefix + pop.substring(0, pop.length() - 4); + prefix = ","; + } + if (all.length() != 0) { + PrintWriter out = new PrintWriter(this.getDirectory() + File.separator + "disabled.yml"); + out.write(all); + out.close(); + } + } catch (Exception e) { + e.printStackTrace(); + } + return true; + } + + @Override + public void loadPlugin(String name) { + try { + PluginManager manager = Bukkit.getServer().getPluginManager(); + Plugin plugin = manager.getPlugin(name); + if (plugin != null) { + manager.enablePlugin(plugin); + return; + } + plugin = manager.loadPlugin(new File("plugins" + File.separator + name + (name.endsWith(".jar") ? "" : ".jar"))); + plugin.onLoad(); + manager.enablePlugin(plugin); + } catch (Exception e) {} + } + + @Override + public File getFile() { + return getFile(this); + } + + public File getFile(JavaPlugin p) { + try { + Field f = JavaPlugin.class.getDeclaredField("file"); + f.setAccessible(true); + return (File) f.get(p); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + public Stack unloadRecursively(String doNotLoad, Plugin plugin, Stack pluginFiles) { + if (!plugin.getName().equals(doNotLoad)) { + File file = getFile((JavaPlugin) plugin); + pluginFiles.push(file.getName()); + } + PluginManager pm = Bukkit.getPluginManager(); + for (Plugin p : pm.getPlugins()) { + List depend = p.getDescription().getDepend(); + if (depend != null) { + for (String s : depend) { + if (s.equals(plugin.getName())) { + unloadRecursively(doNotLoad, p, pluginFiles); + } + } + } + List softDepend = p.getDescription().getSoftDepend(); + if (softDepend != null) { + for (String s : softDepend) { + if (s.equals(plugin.getName())) { + unloadRecursively(doNotLoad, p, pluginFiles); + } + } + } + } + if (unloadPlugin(plugin)) { + List depend = plugin.getDescription().getDepend(); + if (depend != null) { + for (String s : depend) { + Plugin p = pm.getPlugin(s); + if (p != null) { + unloadRecursively(doNotLoad, p, pluginFiles); + } + } + } + List softDepend = plugin.getDescription().getSoftDepend(); + if (softDepend != null) { + for (String s : softDepend) { + Plugin p = pm.getPlugin(s); + if (p != null) { + unloadRecursively(doNotLoad, p, pluginFiles); + } + } + } + } + return pluginFiles; + } + @Override final public ChunkGenerator getDefaultWorldGenerator(final String world, final String id) { WorldEvents.lastWorld = world; @@ -372,7 +562,7 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { }, 20); return result; } - + @Override public void registerPlayerEvents() { getServer().getPluginManager().registerEvents(new PlayerEvents(), this); @@ -383,23 +573,23 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { getServer().getPluginManager().registerEvents(new PlayerEvents_1_8_3(), this); } } - + @Override public void registerInventoryEvents() { getServer().getPluginManager().registerEvents(new InventoryListener(), this); } - + @Override public void registerPlotPlusEvents() { PlotPlusListener.startRunnable(this); getServer().getPluginManager().registerEvents(new PlotPlusListener(), this); } - + @Override public void registerForceFieldEvents() { getServer().getPluginManager().registerEvents(new ForceFieldListener(), this); } - + @Override public void registerWorldEditEvents() { if (getServer().getPluginManager().getPlugin("WorldEdit") != null) { @@ -416,7 +606,7 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { } } } - + @Override public EconHandler getEconomyHandler() { try { @@ -428,7 +618,7 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { } return null; } - + @Override public BlockManager initBlockManager() { if (checkVersion(1, 8, 0)) { @@ -455,7 +645,7 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { BlockUpdateUtil.setBlockManager = BukkitSetBlockManager.setBlockManager; return BlockManager.manager = new BukkitUtil(); } - + @Override public boolean initPlotMeConverter() { TaskManager.runTaskLaterAsync(new Runnable() { @@ -468,7 +658,7 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { }, 20); return Bukkit.getPluginManager().getPlugin("PlotMe") != null || Bukkit.getPluginManager().getPlugin("AthionPlots") != null; } - + @Override public ChunkGenerator getGenerator(final String world, final String name) { final Plugin gen_plugin = Bukkit.getPluginManager().getPlugin(name); @@ -478,7 +668,7 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { return new HybridGen(world); } } - + @Override public HybridUtils initHybridUtils() { return new BukkitHybridUtils(); @@ -495,8 +685,7 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { if (Settings.OFFLINE_MODE) { if (Settings.UUID_LOWERCASE) { UUIDHandler.uuidWrapper = new LowerOfflineUUIDWrapper(); - } - else { + } else { UUIDHandler.uuidWrapper = new OfflineUUIDWrapper(); } Settings.OFFLINE_MODE = true; @@ -506,8 +695,7 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { } else { if (Settings.UUID_LOWERCASE) { UUIDHandler.uuidWrapper = new LowerOfflineUUIDWrapper(); - } - else { + } else { UUIDHandler.uuidWrapper = new OfflineUUIDWrapper(); } Settings.OFFLINE_MODE = true; @@ -520,8 +708,7 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { AbstractTitle.TITLE_CLASS = new DefaultTitle(); if (UUIDHandler.uuidWrapper instanceof DefaultUUIDWrapper) { Settings.TWIN_MODE_UUID = true; - } - else if (UUIDHandler.uuidWrapper instanceof OfflineUUIDWrapper && !Bukkit.getOnlineMode()) { + } else if (UUIDHandler.uuidWrapper instanceof OfflineUUIDWrapper && !Bukkit.getOnlineMode()) { Settings.TWIN_MODE_UUID = true; } } @@ -537,27 +724,27 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { public ChunkManager initChunkManager() { return new BukkitChunkManager(); } - + @Override public EventUtil initEventUtil() { return new BukkitEventUtil(); } - + @Override public void registerTNTListener() { getServer().getPluginManager().registerEvents(new TNTListener(), this); } - + @Override public void unregister(PlotPlayer player) { BukkitUtil.removePlayer(player.getName()); } - + @Override public APlotListener initPlotListener() { return new PlotListener(); } - + @Override public void registerChunkProcessor() { getServer().getPluginManager().registerEvents(new ChunkListener(), this); @@ -567,12 +754,12 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { public void registerWorldEvents() { getServer().getPluginManager().registerEvents(new WorldEvents(), this); } - + @Override public PlayerManager initPlayerManager() { return new BukkitPlayerManager(); } - + @Override public InventoryUtil initInventoryUtil() { return new BukkitInventoryUtil(); diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/IPlotMain.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/IPlotMain.java index 4ea64b9d3..4ec0296c0 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/IPlotMain.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/IPlotMain.java @@ -23,6 +23,8 @@ public interface IPlotMain { public void log(String message); public File getDirectory(); + + public File getFile(); public void disable(); @@ -79,4 +81,6 @@ public interface IPlotMain { public PlayerManager initPlayerManager(); public boolean checkVersion(int major, int minor, int minor2); + + public void loadPlugin(String plugin); } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/PS.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/PS.java index 9dae6edd9..deac9cae2 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/PS.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/PS.java @@ -1,9 +1,16 @@ package com.intellectualcrafters.plot; +import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.SQLException; @@ -21,9 +28,12 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.UUID; +import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; +import org.bukkit.Bukkit; + import com.intellectualcrafters.configuration.file.YamlConfiguration; import com.intellectualcrafters.plot.config.C; import com.intellectualcrafters.plot.config.Configuration; @@ -95,6 +105,7 @@ public class PS { public YamlConfiguration storage; public IPlotMain IMP = null; public TaskManager TASK; + public URL update; // private: private File styleFile; @@ -178,6 +189,20 @@ public class PS { // Player manager PlayerManager.manager = IMP.initPlayerManager(); + // Check for updates + TaskManager.runTaskAsync(new Runnable() { + @Override + public void run() { + URL url = getUpdate(); + if (url != null) { + update = url; + log("&6You are running an older version of PlotSquared..."); + log("&8 - &3Use: &7/plot update"); + log("&8 - &3Or: &7" + url); + } + } + }); + // PlotMe if (Settings.CONVERT_PLOTME || Settings.CACHE_PLOTME) { TaskManager.runTaskLater(new Runnable() { @@ -804,6 +829,123 @@ public class PS { } return true; } + + private boolean canUpdate(String current, String other) { + String s1 = normalisedVersion(current); + String s2 = normalisedVersion(other); + int cmp = s1.compareTo(s2); + return cmp < 0; + } + + public String normalisedVersion(String version) { + return normalisedVersion(version, ".", 4); + } + + public String normalisedVersion(String version, String sep, int maxWidth) { + String[] split = Pattern.compile(sep, Pattern.LITERAL).split(version); + StringBuilder sb = new StringBuilder(); + for (String s : split) { + sb.append(String.format("%" + maxWidth + 's', s)); + } + return sb.toString(); + } + + /** + * Gets the default update URL, or null if the plugin is up to date + * @return + */ + public URL getUpdate() { + String resource = "plotsquared.1177"; + String url = "https://www.spigotmc.org/resources/" + resource + "/history"; + String download = ""; + try { + URL history = new URL(url); + URLConnection con = history.openConnection(); + con.addRequestProperty("User-Agent", "Mozilla/4.0"); + InputStream stream = con.getInputStream(); + BufferedReader in = new BufferedReader(new InputStreamReader(stream)); + String l; + URL link = null; + String cur_ver = config.getString("version"); + String new_ver = null; + while ((l = in.readLine()) != null) { + if (l.length() > version.length() && l.startsWith(version)) { + new_ver = l.substring(version.length(), l.length() - 5); + break; + } + if (link == null && l.length() > download.length() && l.startsWith(download)) { + String subString = l.substring(download.length()); + link = new URL("https://www.spigotmc.org/resources/" + resource + "/download?version=" + subString.substring(0, subString.indexOf("\""))); + continue; + } + } + stream.close(); + in.close(); + if (new_ver == null || !canUpdate(cur_ver, new_ver)) { + PS.log("&7PlotSquared is already up to date!"); + return null; + } + if (link == null) { + PS.log("&dCould not check for updates"); + PS.log("&7 - Manually check for updates: " + url); + return null; + } + return link; + } catch (Exception e) { + PS.log("&dCould not check for updates"); + PS.log("&7 - Manually check for updates: " + url); + return null; + } + } + + public boolean update(URL url) { + if (url == null) { + return false; + } + try { + File jar = PS.get().IMP.getFile(); + File newJar = new File("plugins/update/PlotSquared.jar"); + PS.log("&6Downloading from provided URL: &7" + url); + PS.log("&7 - User-Agent: " + "Mozilla/4.0"); + URLConnection con = url.openConnection(); + con.addRequestProperty("User-Agent", "Mozilla/4.0"); + InputStream stream = con.getInputStream(); + File parent = newJar.getParentFile(); + if (!parent.exists()) { + parent.mkdirs(); + } + PS.log("&7 - Output: " + newJar); + newJar.delete(); + Files.copy(stream, newJar.toPath()); + stream.close(); + PS.log("&6Disabling PlotSquared"); + PS.get().IMP.disable(); + System.out.println("Deleting file: " + jar); + jar.delete(); + System.out.println("Copying: " + jar + " >> " + newJar); + try { + Files.move(newJar.toPath(), jar.toPath(), StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + System.out.println("Failed to reload PlotSquared"); + System.out.println(" - Restart the server manually"); + System.out.println("============ Stacktrace ============"); + e.printStackTrace(); + System.out.println("===================================="); + return false; + } + Bukkit.reload(); + return true; + } + catch (Exception e) { + System.out.println("Failed to update PlotSquared"); + System.out.println(" - Please update manually"); + System.out.println("============ Stacktrace ============"); + e.printStackTrace(); + System.out.println("===================================="); + } + return false; + } /** @@ -876,7 +1018,7 @@ public class PS { public void setupDatabase() { if (Settings.DB.USE_MYSQL) { try { - database = new MySQL(this, Settings.DB.HOST_NAME, Settings.DB.PORT, Settings.DB.DATABASE, Settings.DB.USER, Settings.DB.PASSWORD); + database = new MySQL(Settings.DB.HOST_NAME, Settings.DB.PORT, Settings.DB.DATABASE, Settings.DB.USER, Settings.DB.PASSWORD); connection = database.openConnection(); { if (DBFunc.dbManager == null) { @@ -904,7 +1046,7 @@ public class PS { log(C.PREFIX.s() + "MongoDB is not yet implemented"); } else if (Settings.DB.USE_SQLITE) { try { - this.database = new SQLite(this, IMP.getDirectory() + File.separator + Settings.DB.SQLITE_DB + ".db"); + this.database = new SQLite(IMP.getDirectory() + File.separator + Settings.DB.SQLITE_DB + ".db"); connection = this.database.openConnection(); { DBFunc.dbManager = new SQLManager(connection, Settings.DB.PREFIX); diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Database.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Database.java index b093bc068..f1e3dbd4f 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Database.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Database.java @@ -92,7 +92,7 @@ public class Database extends SubCommand { } Connection n; try { - n = new MySQL(PS.get(), host, port, database, username, password).openConnection(); + n = new MySQL(host, port, database, username, password).openConnection(); // Connection if (n.isClosed()) { return sendMessage(plr, "Failed to open connection"); diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Disable.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Disable.java new file mode 100644 index 000000000..9880a6766 --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Disable.java @@ -0,0 +1,47 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// PlotSquared - A plot manager and world generator for the Bukkit API / +// Copyright (c) 2014 IntellectualSites/IntellectualCrafters / +// / +// This program is free software; you can redistribute it and/or modify / +// it under the terms of the GNU General Public License as published by / +// the Free Software Foundation; either version 3 of the License, or / +// (at your option) any later version. / +// / +// This program is distributed in the hope that it will be useful, / +// but WITHOUT ANY WARRANTY; without even the implied warranty of / +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the / +// GNU General Public License for more details. / +// / +// You should have received a copy of the GNU General Public License / +// along with this program; if not, write to the Free Software Foundation, / +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA / +// / +// You can contact us via: support@intellectualsites.com / +//////////////////////////////////////////////////////////////////////////////////////////////////// +package com.intellectualcrafters.plot.commands; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; + +import com.intellectualcrafters.plot.PS; +import com.intellectualcrafters.plot.object.PlotPlayer; +import com.intellectualcrafters.plot.util.MainUtil; +import com.intellectualcrafters.plot.util.TaskManager; + +public class Disable extends SubCommand { + public static String downloads, version; + + public Disable() { + super("disable", "plots.admin", "Disable PlotSquared", "disable", "unload", CommandCategory.DEBUG, false); + } + + @Override + public boolean execute(final PlotPlayer plr, final String... args) { + PS.log("&cDisabling PlotSquared and all dependencies!"); + PS.get().IMP.disable(); + return true; + } +} diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Update.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Update.java new file mode 100644 index 000000000..1d46629ba --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Update.java @@ -0,0 +1,83 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// PlotSquared - A plot manager and world generator for the Bukkit API / +// Copyright (c) 2014 IntellectualSites/IntellectualCrafters / +// / +// This program is free software; you can redistribute it and/or modify / +// it under the terms of the GNU General Public License as published by / +// the Free Software Foundation; either version 3 of the License, or / +// (at your option) any later version. / +// / +// This program is distributed in the hope that it will be useful, / +// but WITHOUT ANY WARRANTY; without even the implied warranty of / +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the / +// GNU General Public License for more details. / +// / +// You should have received a copy of the GNU General Public License / +// along with this program; if not, write to the Free Software Foundation, / +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA / +// / +// You can contact us via: support@intellectualsites.com / +//////////////////////////////////////////////////////////////////////////////////////////////////// +package com.intellectualcrafters.plot.commands; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; + +import javax.net.ssl.HttpsURLConnection; + +import org.bukkit.Bukkit; + +import com.intellectualcrafters.plot.PS; +import com.intellectualcrafters.plot.config.C; +import com.intellectualcrafters.plot.object.PlotPlayer; +import com.intellectualcrafters.plot.util.MainUtil; +import com.intellectualcrafters.plot.util.TaskManager; + +public class Update extends SubCommand { + public static String downloads, version; + + public Update() { + super("update", "plots.admin", "Update PlotSquared", "update", "updateplugin", CommandCategory.DEBUG, false); + } + + @Override + public boolean execute(final PlotPlayer plr, final String... args) { + if (plr != null) { + MainUtil.sendMessage(plr, C.NOT_CONSOLE); + return false; + } + URL url; + if (args.length == 0) { + url = PS.get().update; + } + else if (args.length == 1) { + try { + url = new URL(args[0]); + } catch (MalformedURLException e) { + MainUtil.sendMessage(plr, "&cInvalid url: " + args[0]); + MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot update [url]"); + return false; + } + } + else { + MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot update"); + return false; + } + if (url == null) { + MainUtil.sendMessage(plr, "&cNo update found!"); + MainUtil.sendMessage(plr, "&cTo manually specify an update URL: /plot update "); + return false; + } + PS.get().update(url); + return true; + } +} diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/plugin.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/plugin.java index d99d1c512..6cab22269 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/plugin.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/plugin.java @@ -32,36 +32,11 @@ import com.intellectualcrafters.plot.util.MainUtil; import com.intellectualcrafters.plot.util.TaskManager; public class plugin extends SubCommand { - public static String downloads, version; public plugin() { super("plugin", "plots.use", "Show plugin information", "plugin", "version", CommandCategory.INFO, false); } - public static void setup() { - TaskManager.runTaskAsync(new Runnable() { - @Override - public void run() { - try { - downloads = convertToNumericString(getInfo("https://intellectualsites.com/spigot_api.php?method=downloads&url=http://www.spigotmc.org/resources/plotsquared.1177/"), false); - } catch (final Exception e) { - downloads = "unknown"; - } - } - }); - TaskManager.runTaskLaterAsync(new Runnable() { - @Override - public void run() { - try { - version = convertToNumericString(getInfo("https://intellectualsites.com/spigot_api.php?method=version&resource=1177"), true); - } catch (final Exception e) { - // Let's just ignore this, most likely error 500... - version = "unknown"; - } - } - }, 200); - } - private static String convertToNumericString(final String str, final boolean dividers) { final StringBuilder builder = new StringBuilder(); for (final char c : str.toCharArray()) { @@ -94,10 +69,9 @@ public class plugin extends SubCommand { final ArrayList strings = new ArrayList() { { add(String.format("&c>> &6PlotSquared (Version: %s)", PS.get().IMP.getVersion())); - add(String.format("&c>> &6Made by Citymonstret and Empire92")); - add(String.format("&c>> &6Download at &lhttp://www.spigotmc.org/resources/1177")); - add(String.format("&c>> &cNewest Version (Spigot): %s", version)); - add(String.format("&c>> &cTotal Downloads (Spigot): %s", downloads)); + add(String.format("&c>> &6Authors: Citymonstret and Empire92")); + add(String.format("&c>> &6Wiki: \n&chttps://github.com/IntellectualCrafters/PlotSquared/wiki")); + add(String.format("&c>> &6Newest Version:\n&c" + (PS.get().update == null ? PS.get().IMP.getVersion() : PS.get().update))); } }; for (final String s : strings) { diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/Database.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/Database.java index 9378d9df7..226a95955 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/Database.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/Database.java @@ -24,8 +24,6 @@ import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; -import com.intellectualcrafters.plot.PS; - /** * Abstract Database class, serves as a base for any connection method (MySQL, SQLite, etc.) * @@ -33,19 +31,6 @@ import com.intellectualcrafters.plot.PS; * @author tips48 */ public abstract class Database { - /** - * Plugin instance, use for plugin.getDataFolder() - */ - protected final PS plotsquared; - - /** - * Creates a new Database - * - * @param plotsquared Plugin instance - */ - protected Database(final PS plotsquared) { - this.plotsquared = plotsquared; - } public abstract Connection forceConnection() throws SQLException, ClassNotFoundException ; diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/MySQL.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/MySQL.java index 7c76a8452..60119f692 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/MySQL.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/MySQL.java @@ -26,8 +26,6 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; -import com.intellectualcrafters.plot.PS; - /** * Connects to and uses a MySQL database * @@ -51,8 +49,7 @@ public class MySQL extends Database { * @param username Username * @param password Password */ - public MySQL(final PS plotsquared, final String hostname, final String port, final String database, final String username, final String password) { - super(plotsquared); + public MySQL(final String hostname, final String port, final String database, final String username, final String password) { this.hostname = hostname; this.port = port; this.database = database; diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/SQLite.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/SQLite.java index d521efa00..b7f6f0185 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/SQLite.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/SQLite.java @@ -45,8 +45,7 @@ public class SQLite extends Database { * * @param dbLocation Location of the Database (Must end in .db) */ - public SQLite(final PS plotsquared, final String dbLocation) { - super(plotsquared); + public SQLite(final String dbLocation) { this.dbLocation = dbLocation; } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/plotme/ClassicPlotMeConnector.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/plotme/ClassicPlotMeConnector.java index f6390e410..267b50fa1 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/plotme/ClassicPlotMeConnector.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/plotme/ClassicPlotMeConnector.java @@ -48,7 +48,7 @@ public class ClassicPlotMeConnector extends APlotMeConnector { return DriverManager.getConnection(con, user, password); // return new MySQL(plotsquared, hostname, port, database, username, password) } else { - return new SQLite(PS.get(), dataFolder + File.separator + "plots.db").openConnection(); + return new SQLite(dataFolder + File.separator + "plots.db").openConnection(); } } catch (SQLException | ClassNotFoundException e) {} diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlayerEvents.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlayerEvents.java index cf476c71e..23d9ab901 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlayerEvents.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlayerEvents.java @@ -334,6 +334,9 @@ public class PlayerEvents extends com.intellectualcrafters.plot.listeners.PlotLi WEManager.bypass.add(pp.getName()); } } + if (PS.get().update != null && pp.hasPermission("plots.admin")) { + MainUtil.sendMessage(pp, "&6An update for PlotSquared is available: &7/plot update"); + } final Location loc = BukkitUtil.getLocation(player.getLocation()); final Plot plot = MainUtil.getPlot(loc); if (plot == null) { diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/ConsoleColors.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/ConsoleColors.java index b1cdaf604..b3758cad5 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/ConsoleColors.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/ConsoleColors.java @@ -20,12 +20,10 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// package com.intellectualcrafters.plot.util; -import org.bukkit.ChatColor; - public class ConsoleColors { public static String fromString(String input) { - input = input.replaceAll("&0", fromChatColor(ChatColor.BLACK)).replaceAll("&1", fromChatColor(ChatColor.DARK_BLUE)).replaceAll("&2", fromChatColor(ChatColor.DARK_GREEN)).replaceAll("&3", fromChatColor(ChatColor.DARK_AQUA)).replaceAll("&4", fromChatColor(ChatColor.DARK_RED)).replaceAll("&5", fromChatColor(ChatColor.DARK_PURPLE)).replaceAll("&6", fromChatColor(ChatColor.GOLD)).replaceAll("&7", fromChatColor(ChatColor.GRAY)).replaceAll("&8", fromChatColor(ChatColor.DARK_GRAY)).replaceAll("&9", fromChatColor(ChatColor.BLUE)).replaceAll("&a", fromChatColor(ChatColor.GREEN)).replaceAll("&b", fromChatColor(ChatColor.AQUA)).replaceAll("&c", fromChatColor(ChatColor.RED)).replaceAll("&d", fromChatColor(ChatColor.LIGHT_PURPLE)).replaceAll("&e", fromChatColor(ChatColor.YELLOW)).replaceAll("&f", fromChatColor(ChatColor.WHITE)).replaceAll("&k", fromChatColor(ChatColor.MAGIC)).replaceAll("&l", fromChatColor(ChatColor.BOLD)).replaceAll("&m", fromChatColor(ChatColor.STRIKETHROUGH)) - .replaceAll("&n", fromChatColor(ChatColor.UNDERLINE)).replaceAll("&o", fromChatColor(ChatColor.ITALIC)).replaceAll("&r", fromChatColor(ChatColor.RESET)); + input = input.replaceAll("&0", fromChatColor("&0")).replaceAll("&1", fromChatColor("&1")).replaceAll("&2", fromChatColor("&2")).replaceAll("&3", fromChatColor("&3")).replaceAll("&4", fromChatColor("&4")).replaceAll("&5", fromChatColor("&5")).replaceAll("&6", fromChatColor("&6")).replaceAll("&7", fromChatColor("&7")).replaceAll("&8", fromChatColor("&8")).replaceAll("&9", fromChatColor("&9")).replaceAll("&a", fromChatColor("&a")).replaceAll("&b", fromChatColor("&b")).replaceAll("&c", fromChatColor("&c")).replaceAll("&d", fromChatColor("&d")).replaceAll("&e", fromChatColor("&e")).replaceAll("&f", fromChatColor("&f")).replaceAll("&k", fromChatColor("&k")).replaceAll("&l", fromChatColor("&l")).replaceAll("&m", fromChatColor("&m")) + .replaceAll("&n", fromChatColor("&n")).replaceAll("&o", fromChatColor("&o")).replaceAll("&r", fromChatColor("&r")); return input + "\u001B[0m"; } @@ -41,42 +39,42 @@ public class ConsoleColors { * String ANSI_UNDERLINE = "\033[0m"; public static final String ANSI_ITALIC * = "\033[3m]"; */ - public static String fromChatColor(final ChatColor color) { + public static String fromChatColor(final String color) { return chatColor(color).getLin(); } - public static ConsoleColor chatColor(final ChatColor color) { + public static ConsoleColor chatColor(final String color) { switch (color) { - case RESET: + case "&r": return ConsoleColor.RESET; - case GRAY: - case DARK_GRAY: + case "&7": + case "&8": return ConsoleColor.WHITE; - case BLACK: + case "&0": return ConsoleColor.BLACK; - case DARK_RED: - case RED: + case "&4": + case "&c": return ConsoleColor.RED; - case GOLD: - case YELLOW: + case "&6": + case "&e": return ConsoleColor.YELLOW; - case DARK_GREEN: - case GREEN: + case "&a": + case "&2": return ConsoleColor.GREEN; - case AQUA: - case DARK_AQUA: + case "&b": + case "&3": return ConsoleColor.CYAN; - case LIGHT_PURPLE: - case DARK_PURPLE: + case "&d": + case "&5": return ConsoleColor.PURPLE; - case BLUE: - case DARK_BLUE: + case "&9": + case "&1": return ConsoleColor.BLUE; - case UNDERLINE: + case "&n": return ConsoleColor.UNDERLINE; - case ITALIC: + case "&o": return ConsoleColor.ITALIC; - case BOLD: + case "&l": return ConsoleColor.BOLD; default: return ConsoleColor.RESET; diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/Updater.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/Updater.java new file mode 100644 index 000000000..5a41f3d08 --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/Updater.java @@ -0,0 +1,32 @@ +package com.intellectualcrafters.plot.util; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URL; + +public class Updater { + public Updater() { + // https://www.spigotmc.org/resources/plotsquared.1177/history + try { + + String resource = "plotsquared.1177"; + String url = "https://www.spigotmc.org/resources/" + resource + "/history"; + String download = " all = getAllUUIDS(); - PS.log("&aFast mod UUID caching enabled!"); + PS.log("&aFast mode UUID caching enabled!"); final File playerdataFolder = new File(container, world + File.separator + "playerdata"); String[] dat = playerdataFolder.list(new FilenameFilter() { @Override