diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java index e60e2a97..70ec509a 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -83,6 +83,14 @@ public interface Server { */ public int broadcastMessage(String message); + /** + * Gets the name of the update folder. The update folder is used to safely update + * plugins at the right moment on a plugin load. + * + * @return The name of the update folder + */ + public String getUpdateFolder(); + /** * Gets a player object by the given username * diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java index 38345b26..2ee897fe 100644 --- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java +++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java @@ -24,6 +24,8 @@ import org.bukkit.event.Event; import org.bukkit.event.Event.Priority; import org.bukkit.event.Listener; +import org.bukkit.util.FileUtil; + /** * Handles all plugin management from the Server */ @@ -33,6 +35,7 @@ public final class SimplePluginManager implements PluginManager { private final List plugins = new ArrayList(); private final Map lookupNames = new HashMap(); private final Map> listeners = new EnumMap>(Event.Type.class); + private static File updateDirectory = null; private final Comparator comparer = new Comparator() { public int compare(RegisteredListener i, RegisteredListener j) { int result = i.getPriority().compareTo(j.getPriority()); @@ -97,6 +100,10 @@ public final class SimplePluginManager implements PluginManager { LinkedList filesList = new LinkedList(Arrays.asList(files)); + if (!(server.getUpdateFolder().equals(""))) { + updateDirectory = new File(directory, server.getUpdateFolder()); + } + while(!allFailed || finalPass) { allFailed = true; Iterator itr = filesList.iterator(); @@ -164,6 +171,14 @@ public final class SimplePluginManager implements PluginManager { * @throws InvalidDescriptionException Thrown when the specified file contains an invalid description */ public synchronized Plugin loadPlugin(File file, boolean ignoreSoftDependencies) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException { + File updateFile = null; + + if (updateDirectory != null && updateDirectory.isDirectory() && (updateFile = new File(updateDirectory, file.getName())).isFile()) { + if (FileUtil.copy(updateFile, file)) { + updateFile.delete(); + } + } + Set filters = fileAssociations.keySet(); Plugin result = null; @@ -279,7 +294,7 @@ public final class SimplePluginManager implements PluginManager { String author = ""; if (plugin.getDescription().getAuthors().size() > 0) { - author = plugin.getDescription().getAuthors().get(0); + author = plugin.getDescription().getAuthors().get(0); } server.getLogger().log(Level.SEVERE, String.format( "Nag author: '%s' of '%s' about the following: %s", diff --git a/src/main/java/org/bukkit/util/FileUtil.java b/src/main/java/org/bukkit/util/FileUtil.java new file mode 100644 index 00000000..66129c39 --- /dev/null +++ b/src/main/java/org/bukkit/util/FileUtil.java @@ -0,0 +1,59 @@ +package org.bukkit.util; + +import java.nio.channels.FileChannel; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +/** + * Class containing file utilities + */ + +public class FileUtil { + + /** + * This method copies one file to another location + * + * @param inFile the source filename + * @param outFile the target filename + * @return true on success + */ + + public static boolean copy(File inFile, File outFile) { + if (!inFile.exists()) { + return false; + } + + FileChannel in = null; + FileChannel out = null; + + try { + in = new FileInputStream(inFile).getChannel(); + out = new FileOutputStream(outFile).getChannel(); + + long pos = 0; + long size = in.size(); + + while (pos < size) { + pos += in.transferTo(pos, 10*1024*1024, out); + } + } catch (IOException ioe) { + return false; + } finally { + try { + if (in != null) { + in.close(); + } + if (out != null) { + out.close(); + } + } catch (IOException ioe) { + return false; + } + } + + return true; + + } +}