Add a warning message when ProtocolLib is started on untested version.
May decide to simply stop ProtocolLib unless this feature is specifically disabled.
Dieser Commit ist enthalten in:
Ursprung
6b5ecd7309
Commit
7ca3e916a5
153
ProtocolLib/src/main/java/com/comphenix/protocol/MinecraftVersion.java
Normale Datei
153
ProtocolLib/src/main/java/com/comphenix/protocol/MinecraftVersion.java
Normale Datei
@ -0,0 +1,153 @@
|
|||||||
|
package com.comphenix.protocol;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.bukkit.Server;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.collect.ComparisonChain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the current Minecraft version.
|
||||||
|
*
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
|
class MinecraftVersion implements Comparable<MinecraftVersion> {
|
||||||
|
/**
|
||||||
|
* Regular expression used to parse version strings.
|
||||||
|
*/
|
||||||
|
private static final String VERSION_PATTERN = ".*\\(MC:\\s*((?:\\d+\\.)*\\d)\\s*\\)";
|
||||||
|
|
||||||
|
private final int major;
|
||||||
|
private final int minor;
|
||||||
|
private final int build;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the current Minecraft version.
|
||||||
|
* @param server - the Bukkit server that will be used to examine the MC version.
|
||||||
|
*/
|
||||||
|
public MinecraftVersion(Server server) {
|
||||||
|
this(extractVersion(server.getVersion()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a version object from the format major.minor.build.
|
||||||
|
* @param versionOnly - the version in text form.
|
||||||
|
*/
|
||||||
|
public MinecraftVersion(String versionOnly) {
|
||||||
|
int[] numbers = parseVersion(versionOnly);
|
||||||
|
|
||||||
|
this.major = numbers[0];
|
||||||
|
this.minor = numbers[1];
|
||||||
|
this.build = numbers[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a version object directly.
|
||||||
|
* @param major - major version number.
|
||||||
|
* @param minor - minor version number.
|
||||||
|
* @param build - build version number.
|
||||||
|
*/
|
||||||
|
public MinecraftVersion(int major, int minor, int build) {
|
||||||
|
this.major = major;
|
||||||
|
this.minor = minor;
|
||||||
|
this.build = build;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] parseVersion(String version) {
|
||||||
|
String[] elements = version.split("\\.");
|
||||||
|
int[] numbers = new int[3];
|
||||||
|
|
||||||
|
// Make sure it's even a valid version
|
||||||
|
if (elements.length < 1)
|
||||||
|
throw new IllegalStateException("Corrupt MC version: " + version);
|
||||||
|
|
||||||
|
// 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());
|
||||||
|
return numbers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Major version number
|
||||||
|
* @return Current major version number.
|
||||||
|
*/
|
||||||
|
public int getMajor() {
|
||||||
|
return major;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minor version number
|
||||||
|
* @return Current minor version number.
|
||||||
|
*/
|
||||||
|
public int getMinor() {
|
||||||
|
return minor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build version number
|
||||||
|
* @return Current build version number.
|
||||||
|
*/
|
||||||
|
public int getBuild() {
|
||||||
|
return build;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(MinecraftVersion o) {
|
||||||
|
if (o == null)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return ComparisonChain.start().
|
||||||
|
compare(major, o.major).
|
||||||
|
compare(minor, o.minor).
|
||||||
|
compare(build, o.build).
|
||||||
|
result();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (obj == this)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (obj instanceof MinecraftVersion) {
|
||||||
|
MinecraftVersion other = (MinecraftVersion) obj;
|
||||||
|
|
||||||
|
return major == other.major &&
|
||||||
|
minor == other.minor &&
|
||||||
|
build == other.build;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(major, minor, build);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
// Convert to a String that we can parse back again
|
||||||
|
return String.format("(MC: %s.%s.%s)", major, minor, build);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the Minecraft version from CraftBukkit itself.
|
||||||
|
* @param server - the server object representing CraftBukkit.
|
||||||
|
* @return The underlying MC version.
|
||||||
|
* @throws IllegalStateException If we could not parse the version string.
|
||||||
|
*/
|
||||||
|
public static String extractVersion(String text) {
|
||||||
|
Pattern versionPattern = Pattern.compile(VERSION_PATTERN);
|
||||||
|
Matcher version = versionPattern.matcher(text);
|
||||||
|
|
||||||
|
if (version.matches() && version.group(1) != null) {
|
||||||
|
return version.group(1);
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Cannot parse version String '" + text + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,8 @@ class ProtocolConfig {
|
|||||||
|
|
||||||
private static final String METRICS_ENABLED = "metrics";
|
private static final String METRICS_ENABLED = "metrics";
|
||||||
|
|
||||||
|
private static final String IGNORE_VERSION_CHECK = "ignore version check";
|
||||||
|
|
||||||
private static final String BACKGROUND_COMPILER_ENABLED = "background compiler";
|
private static final String BACKGROUND_COMPILER_ENABLED = "background compiler";
|
||||||
|
|
||||||
private static final String UPDATER_NOTIFY = "notify";
|
private static final String UPDATER_NOTIFY = "notify";
|
||||||
@ -149,6 +151,26 @@ class ProtocolConfig {
|
|||||||
return updater.getLong(UPDATER_LAST_TIME, 0);
|
return updater.getLong(UPDATER_LAST_TIME, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The version of Minecraft to ignore the built-in safety feature.
|
||||||
|
* @return The version to ignore ProtocolLib's satefy.
|
||||||
|
*/
|
||||||
|
public String getIgnoreVersionCheck() {
|
||||||
|
return global.getString(IGNORE_VERSION_CHECK, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets under which version of Minecraft the version safety feature will be ignored.
|
||||||
|
* <p>
|
||||||
|
* This is useful if a server operator has tested and verified that a version of ProtocolLib works,
|
||||||
|
* but doesn't want or can't upgrade to a newer version.
|
||||||
|
*
|
||||||
|
* @param ignoreVersion - the version of Minecraft where the satefy will be disabled.
|
||||||
|
*/
|
||||||
|
public void setIgnoreVersionCheck(String ignoreVersion) {
|
||||||
|
global.set(IGNORE_VERSION_CHECK, ignoreVersion);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve whether or not metrics is enabled.
|
* Retrieve whether or not metrics is enabled.
|
||||||
* @return TRUE if metrics is enabled, FALSE otherwise.
|
* @return TRUE if metrics is enabled, FALSE otherwise.
|
||||||
|
@ -43,6 +43,15 @@ import com.comphenix.protocol.reflect.compiler.BackgroundCompiler;
|
|||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public class ProtocolLibrary extends JavaPlugin {
|
public class ProtocolLibrary extends JavaPlugin {
|
||||||
|
/**
|
||||||
|
* The minimum version ProtocolLib has been tested with.
|
||||||
|
*/
|
||||||
|
private static final String MINIMUM_MINECRAFT_VERSION = "1.0.0";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum version ProtocolLib has been tested with,
|
||||||
|
*/
|
||||||
|
private static final String MAXIMUM_MINECRAFT_VERSION = "1.4.5";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of milliseconds per second.
|
* The number of milliseconds per second.
|
||||||
@ -188,13 +197,13 @@ public class ProtocolLibrary extends JavaPlugin {
|
|||||||
logger.info("Structure compiler thread has been disabled.");
|
logger.info("Structure compiler thread has been disabled.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle unexpected Minecraft versions
|
||||||
|
verifyMinecraftVersion();
|
||||||
|
|
||||||
// Set up command handlers
|
// Set up command handlers
|
||||||
registerCommand(CommandProtocol.NAME, commandProtocol);
|
registerCommand(CommandProtocol.NAME, commandProtocol);
|
||||||
registerCommand(CommandPacket.NAME, commandPacket);
|
registerCommand(CommandPacket.NAME, commandPacket);
|
||||||
|
|
||||||
// Notify server managers of incompatible plugins
|
|
||||||
checkForIncompatibility(manager);
|
|
||||||
|
|
||||||
// Player login and logout events
|
// Player login and logout events
|
||||||
protocolManager.registerEvents(manager, this);
|
protocolManager.registerEvents(manager, this);
|
||||||
|
|
||||||
@ -220,6 +229,26 @@ public class ProtocolLibrary extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used to check Minecraft version
|
||||||
|
private void verifyMinecraftVersion() {
|
||||||
|
try {
|
||||||
|
MinecraftVersion minimum = new MinecraftVersion(MINIMUM_MINECRAFT_VERSION);
|
||||||
|
MinecraftVersion maximum = new MinecraftVersion(MAXIMUM_MINECRAFT_VERSION);
|
||||||
|
MinecraftVersion current = new MinecraftVersion(getServer());
|
||||||
|
|
||||||
|
// Skip certain versions
|
||||||
|
if (!config.getIgnoreVersionCheck().equals(current.toString())) {
|
||||||
|
// We'll just warn the user for now
|
||||||
|
if (current.compareTo(minimum) < 0)
|
||||||
|
reporter.reportWarning(this, "Version " + current + " is lower than the minimum " + minimum);
|
||||||
|
if (current.compareTo(maximum) > 0)
|
||||||
|
reporter.reportWarning(this, "Version " + current + " has not yet been tested! Proceed with caution.");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
reporter.reportWarning(this, "Unable to retrieve current Minecraft version.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void registerCommand(String name, CommandExecutor executor) {
|
private void registerCommand(String name, CommandExecutor executor) {
|
||||||
try {
|
try {
|
||||||
if (executor == null)
|
if (executor == null)
|
||||||
@ -296,18 +325,6 @@ public class ProtocolLibrary extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkForIncompatibility(PluginManager manager) {
|
|
||||||
// Plugin authors: Notify me to remove these
|
|
||||||
String[] incompatiblePlugins = {};
|
|
||||||
|
|
||||||
for (String plugin : incompatiblePlugins) {
|
|
||||||
if (manager.getPlugin(plugin) != null) {
|
|
||||||
// Check for versions, ect.
|
|
||||||
reporter.reportWarning(this, "Detected incompatible plugin: " + plugin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
// Disable compiler
|
// Disable compiler
|
||||||
|
@ -26,7 +26,7 @@ public class MinecraftReflection {
|
|||||||
/**
|
/**
|
||||||
* The package name of all the classes that belongs to the native code in Minecraft.
|
* The package name of all the classes that belongs to the native code in Minecraft.
|
||||||
*/
|
*/
|
||||||
private static String MINECRAFT_SERVER_PACKAGE = "net.minecraft.server";
|
private static String MINECRAFT_PREFIX_PACKAGE = "net.minecraft.server";
|
||||||
|
|
||||||
private static String MINECRAFT_FULL_PACKAGE = null;
|
private static String MINECRAFT_FULL_PACKAGE = null;
|
||||||
private static String CRAFTBUKKIT_PACKAGE = null;
|
private static String CRAFTBUKKIT_PACKAGE = null;
|
||||||
@ -74,7 +74,7 @@ public class MinecraftReflection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("Cannot find Bukkit. Is it running?");
|
throw new IllegalStateException("Could not find Bukkit. Is it running?");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ public class MinecraftReflection {
|
|||||||
throw new IllegalArgumentException("Cannot determine the type of a null object.");
|
throw new IllegalArgumentException("Cannot determine the type of a null object.");
|
||||||
|
|
||||||
// Doesn't matter if we don't check for the version here
|
// Doesn't matter if we don't check for the version here
|
||||||
return obj.getClass().getName().startsWith(MINECRAFT_SERVER_PACKAGE);
|
return obj.getClass().getName().startsWith(MINECRAFT_PREFIX_PACKAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -131,7 +131,7 @@ public class MinecraftReflection {
|
|||||||
throw new IllegalArgumentException("Cannot determine the type of a null object.");
|
throw new IllegalArgumentException("Cannot determine the type of a null object.");
|
||||||
|
|
||||||
String javaName = obj.getClass().getName();
|
String javaName = obj.getClass().getName();
|
||||||
return javaName.startsWith(MINECRAFT_SERVER_PACKAGE) && javaName.endsWith(className);
|
return javaName.startsWith(MINECRAFT_PREFIX_PACKAGE) && javaName.endsWith(className);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.comphenix.protocol;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class MinecraftVersionTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testComparision() {
|
||||||
|
MinecraftVersion within = new MinecraftVersion(1, 2, 5);
|
||||||
|
MinecraftVersion outside = new MinecraftVersion(1, 7, 0);
|
||||||
|
|
||||||
|
MinecraftVersion lower = new MinecraftVersion(1, 0, 0);
|
||||||
|
MinecraftVersion highest = new MinecraftVersion(1, 4, 5);
|
||||||
|
|
||||||
|
// Make sure this is valid
|
||||||
|
assertTrue(lower.compareTo(within) < 0 && within.compareTo(highest) < 0);
|
||||||
|
assertFalse(outside.compareTo(within) < 0 && outside.compareTo(highest) < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testParsing() {
|
||||||
|
assertEquals(MinecraftVersion.extractVersion("CraftBukkit R3.0 (MC: 1.4.3)"), "1.4.3");
|
||||||
|
assertEquals(MinecraftVersion.extractVersion("CraftBukkit Test Beta 1 (MC: 1.10.01 )"), "1.10.01");
|
||||||
|
assertEquals(MinecraftVersion.extractVersion("Hello (MC: 2.3.4 ) "), "2.3.4");
|
||||||
|
}
|
||||||
|
}
|
In neuem Issue referenzieren
Einen Benutzer sperren