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 IGNORE_VERSION_CHECK = "ignore version check";
|
||||
|
||||
private static final String BACKGROUND_COMPILER_ENABLED = "background compiler";
|
||||
|
||||
private static final String UPDATER_NOTIFY = "notify";
|
||||
@ -148,6 +150,26 @@ class ProtocolConfig {
|
||||
public long getAutoLastTime() {
|
||||
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.
|
||||
|
@ -43,6 +43,15 @@ import com.comphenix.protocol.reflect.compiler.BackgroundCompiler;
|
||||
* @author Kristian
|
||||
*/
|
||||
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.
|
||||
@ -188,13 +197,13 @@ public class ProtocolLibrary extends JavaPlugin {
|
||||
logger.info("Structure compiler thread has been disabled.");
|
||||
}
|
||||
|
||||
// Handle unexpected Minecraft versions
|
||||
verifyMinecraftVersion();
|
||||
|
||||
// Set up command handlers
|
||||
registerCommand(CommandProtocol.NAME, commandProtocol);
|
||||
registerCommand(CommandPacket.NAME, commandPacket);
|
||||
|
||||
// Notify server managers of incompatible plugins
|
||||
checkForIncompatibility(manager);
|
||||
|
||||
// Player login and logout events
|
||||
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) {
|
||||
try {
|
||||
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
|
||||
public void onDisable() {
|
||||
// Disable compiler
|
||||
|
@ -26,8 +26,8 @@ public class MinecraftReflection {
|
||||
/**
|
||||
* 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 CRAFTBUKKIT_PACKAGE = null;
|
||||
|
||||
@ -74,7 +74,7 @@ public class MinecraftReflection {
|
||||
}
|
||||
|
||||
} 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.");
|
||||
|
||||
// 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.");
|
||||
|
||||
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