diff --git a/ProtocolLib/dependency-reduced-pom.xml b/ProtocolLib/dependency-reduced-pom.xml index 4c88f2ae..c69963b3 100644 --- a/ProtocolLib/dependency-reduced-pom.xml +++ b/ProtocolLib/dependency-reduced-pom.xml @@ -139,7 +139,7 @@ org.bukkit craftbukkit - 1.4.5-R0.3-SNAPSHOT + 1.4.6-R0.1 provided @@ -154,6 +154,36 @@ + + org.mockito + mockito-all + 1.8.4 + test + + + org.powermock + powermock-module-junit4 + 1.5 + test + + + powermock-module-junit4-common + org.powermock + + + + + org.powermock + powermock-api-mockito + 1.5 + test + + + powermock-api-support + org.powermock + + + @@ -181,6 +211,7 @@ + 1.5 cp1252 diff --git a/ProtocolLib/pom.xml b/ProtocolLib/pom.xml index 4fa87e38..d1803e54 100644 --- a/ProtocolLib/pom.xml +++ b/ProtocolLib/pom.xml @@ -216,6 +216,7 @@ org.mockito mockito-all 1.8.4 + test org.powermock diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/MinecraftVersion.java b/ProtocolLib/src/main/java/com/comphenix/protocol/MinecraftVersion.java index 6544ac11..963c8430 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/MinecraftVersion.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/MinecraftVersion.java @@ -7,13 +7,14 @@ import org.bukkit.Server; import com.google.common.base.Objects; import com.google.common.collect.ComparisonChain; +import com.google.common.collect.Ordering; /** * Determine the current Minecraft version. * * @author Kristian */ -class MinecraftVersion implements Comparable { +public class MinecraftVersion implements Comparable { /** * Regular expression used to parse version strings. */ @@ -22,6 +23,9 @@ class MinecraftVersion implements Comparable { private final int major; private final int minor; private final int build; + + // The development stage + private final String development; /** * Determine the current Minecraft version. @@ -36,11 +40,13 @@ class MinecraftVersion implements Comparable { * @param versionOnly - the version in text form. */ public MinecraftVersion(String versionOnly) { - int[] numbers = parseVersion(versionOnly); + String[] section = versionOnly.split("-"); + int[] numbers = parseVersion(section[0]); this.major = numbers[0]; this.minor = numbers[1]; this.build = numbers[2]; + this.development = section.length > 1 ? section[1] : null; } /** @@ -50,9 +56,21 @@ class MinecraftVersion implements Comparable { * @param build - build version number. */ public MinecraftVersion(int major, int minor, int build) { + this(major, minor, build, null); + } + + /** + * Construct a version object directly. + * @param major - major version number. + * @param minor - minor version number. + * @param build - build version number. + * @param development - development stage. + */ + public MinecraftVersion(int major, int minor, int build, String development) { this.major = major; this.minor = minor; this.build = build; + this.development = development; } private int[] parseVersion(String version) { @@ -65,7 +83,7 @@ class MinecraftVersion implements Comparable { // The String 1 or 1.2 is interpreted as 1.0.0 and 1.2.0 respectively. for (int i = 0; i < Math.min(numbers.length, elements.length); i++) - numbers[i] = Integer.parseInt(elements[i].trim()); + numbers[i] = Integer.parseInt(elements[i].trim()); return numbers; } @@ -93,12 +111,23 @@ class MinecraftVersion implements Comparable { return build; } + /** + * Retrieve the development stage. + * @return Development stage, or NULL if this is a release. + */ + public String getDevelopmentStage() { + return development; + } + /** * Retrieve the version String (major.minor.build) only. * @return A normal version string. */ public String getVersion() { - return String.format("%s.%s.%s", major, minor, build); + if (development == null) + return String.format("%s.%s.%s", major, minor, build); + else + return String.format("%s.%s.%s-%s", major, minor, build, development); } @Override @@ -110,6 +139,8 @@ class MinecraftVersion implements Comparable { compare(major, o.major). compare(minor, o.minor). compare(build, o.build). + // No development String means it's a release + compare(development, o.development, Ordering.natural().nullsLast()). result(); } @@ -125,7 +156,8 @@ class MinecraftVersion implements Comparable { return major == other.major && minor == other.minor && - build == other.build; + build == other.build && + Objects.equal(development, other.development); } return false; diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java b/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java index e82f47ff..c8c3e0a8 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java @@ -17,11 +17,14 @@ package com.comphenix.protocol; +import java.io.File; import java.io.IOException; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.bukkit.Server; import org.bukkit.command.CommandExecutor; @@ -97,6 +100,9 @@ public class ProtocolLibrary extends JavaPlugin { private CommandProtocol commandProtocol; private CommandPacket commandPacket; + // Whether or not disable is not needed + private boolean skipDisable; + @Override public void onLoad() { // Load configuration @@ -104,7 +110,6 @@ public class ProtocolLibrary extends JavaPlugin { // Add global parameters DetailedErrorReporter detailedReporter = new DetailedErrorReporter(this); - updater = new Updater(this, logger, "protocollib", getFile(), "protocol.info"); reporter = detailedReporter; try { @@ -121,6 +126,12 @@ public class ProtocolLibrary extends JavaPlugin { } try { + // Check for other versions + checkConflictingVersions(); + + // Set updater + updater = new Updater(this, logger, "protocollib", getFile(), "protocol.info"); + unhookTask = new DelayedSingleTask(this); protocolManager = new PacketFilterManager(getClassLoader(), getServer(), unhookTask, detailedReporter); detailedReporter.addGlobalParameter("manager", protocolManager); @@ -252,6 +263,45 @@ public class ProtocolLibrary extends JavaPlugin { reporter.reportWarning(this, "Unable to retrieve current Minecraft version.", e); } } + + private void checkConflictingVersions() { + Pattern ourPlugin = Pattern.compile("ProtocolLib-(.*)\\.jar"); + MinecraftVersion currentVersion = new MinecraftVersion(this.getDescription().getVersion()); + MinecraftVersion newestVersion = null; + + try { + // Scan the plugin folder for newer versions of ProtocolLib + File pluginFolder = new File("plugins/"); + + for (File candidate : pluginFolder.listFiles()) { + if (candidate.isFile()) { + Matcher match = ourPlugin.matcher(candidate.getName()); + + if (match.matches()) { + MinecraftVersion version = new MinecraftVersion(match.group(1)); + + if (newestVersion == null || newestVersion.compareTo(version) < 0) { + newestVersion = version; + } + } + } + } + + } catch (Exception e) { + reporter.reportWarning(this, "Unable to detect conflicting plugin versions.", e); + } + + // See if the newest version is actually higher + if (newestVersion != null && currentVersion.compareTo(newestVersion) < 0) { + // We don't need to set internal classes or instances to NULL - that would break the other loaded plugin + skipDisable = true; + + throw new IllegalStateException( + String.format("Detected a newer version of ProtocolLib (%s) in plugin folder than the current (%s). Disabling.", + newestVersion.getVersion(), currentVersion.getVersion()) + ); + } + } private void registerCommand(String name, CommandExecutor executor) { try { @@ -331,6 +381,10 @@ public class ProtocolLibrary extends JavaPlugin { @Override public void onDisable() { + if (skipDisable) { + return; + } + // Disable compiler if (backgroundCompiler != null) { backgroundCompiler.shutdownAll();