mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2024-11-24 11:36:51 +01:00
After Minecraft 1.4.4, CraftBukkit no longer redirects MAP_CHUNK.
We can therefore relax the requirements in NetworkFieldInjector and NetworkObjectInjetor.
This commit is contained in:
parent
a798147e71
commit
3c97cffc09
@ -43,6 +43,7 @@ import com.comphenix.protocol.metrics.Updater;
|
||||
import com.comphenix.protocol.metrics.Updater.UpdateResult;
|
||||
import com.comphenix.protocol.reflect.compiler.BackgroundCompiler;
|
||||
import com.comphenix.protocol.utility.ChatExtensions;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
|
||||
/**
|
||||
* The main entry point for ProtocolLib.
|
||||
@ -132,12 +133,15 @@ public class ProtocolLibrary extends JavaPlugin {
|
||||
// Check for other versions
|
||||
checkConflictingVersions();
|
||||
|
||||
// Handle unexpected Minecraft versions
|
||||
MinecraftVersion version = verifyMinecraftVersion();
|
||||
|
||||
// Set updater
|
||||
updater = new Updater(this, logger, "protocollib", getFile(), "protocol.info");
|
||||
|
||||
unhookTask = new DelayedSingleTask(this);
|
||||
protocolManager = new PacketFilterManager(
|
||||
getClassLoader(), getServer(), unhookTask, detailedReporter);
|
||||
getClassLoader(), getServer(), version, unhookTask, detailedReporter);
|
||||
|
||||
// Setup error reporter
|
||||
detailedReporter.addGlobalParameter("manager", protocolManager);
|
||||
@ -248,10 +252,7 @@ public class ProtocolLibrary extends JavaPlugin {
|
||||
} else {
|
||||
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);
|
||||
@ -282,7 +283,7 @@ public class ProtocolLibrary extends JavaPlugin {
|
||||
}
|
||||
|
||||
// Used to check Minecraft version
|
||||
private void verifyMinecraftVersion() {
|
||||
private MinecraftVersion verifyMinecraftVersion() {
|
||||
try {
|
||||
MinecraftVersion minimum = new MinecraftVersion(MINIMUM_MINECRAFT_VERSION);
|
||||
MinecraftVersion maximum = new MinecraftVersion(MAXIMUM_MINECRAFT_VERSION);
|
||||
@ -296,9 +297,14 @@ public class ProtocolLibrary extends JavaPlugin {
|
||||
if (current.compareTo(maximum) > 0)
|
||||
logger.warning("Version " + current + " has not yet been tested! Proceed with caution.");
|
||||
}
|
||||
return current;
|
||||
|
||||
} catch (Exception e) {
|
||||
reporter.reportWarning(this, "Unable to retrieve current Minecraft version.", e);
|
||||
}
|
||||
|
||||
// Unknown version
|
||||
return null;
|
||||
}
|
||||
|
||||
private void checkConflictingVersions() {
|
||||
|
@ -61,6 +61,7 @@ import com.comphenix.protocol.injector.spigot.SpigotPacketInjector;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
@ -149,9 +150,15 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
|
||||
|
||||
/**
|
||||
* Only create instances of this class if protocol lib is disabled.
|
||||
* @param unhookTask
|
||||
*/
|
||||
public PacketFilterManager(ClassLoader classLoader, Server server, DelayedSingleTask unhookTask, ErrorReporter reporter) {
|
||||
this(classLoader, server, new MinecraftVersion(server), unhookTask, reporter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only create instances of this class if protocol lib is disabled.
|
||||
*/
|
||||
public PacketFilterManager(ClassLoader classLoader, Server server, MinecraftVersion mcVersion, DelayedSingleTask unhookTask, ErrorReporter reporter) {
|
||||
if (reporter == null)
|
||||
throw new IllegalArgumentException("reporter cannot be NULL.");
|
||||
if (classLoader == null)
|
||||
@ -201,6 +208,7 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
|
||||
classLoader(classLoader).
|
||||
packetListeners(packetListeners).
|
||||
injectionFilter(isInjectionNecessary).
|
||||
version(mcVersion).
|
||||
buildHandler();
|
||||
|
||||
this.packetInjector = PacketInjectorBuilder.newBuilder().
|
||||
@ -561,7 +569,7 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
|
||||
return;
|
||||
}
|
||||
|
||||
playerInjection.processPacket(sender, mcPacket);
|
||||
playerInjection.recieveClientPacket(sender, mcPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -39,6 +39,7 @@ import com.comphenix.protocol.reflect.FieldUtils;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.reflect.VolatileField;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
@ -56,6 +57,12 @@ class NetworkFieldInjector extends PlayerInjector {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
// After commit 336a4e00668fd2518c41242755ed6b3bdc3b0e6c (Update CraftBukkit to Minecraft 1.4.4.),
|
||||
// CraftBukkit stopped redirecting map chunk and map chunk bulk packets to a separate queue.
|
||||
// Thus, NetworkFieldInjector can safely handle every packet (though not perfectly - some packets
|
||||
// will be slightly processed).
|
||||
private MinecraftVersion safeVersion = new MinecraftVersion("1.4.4");
|
||||
|
||||
// Packets to ignore
|
||||
private Set<Object> ignoredPackets = Sets.newSetFromMap(new ConcurrentHashMap<Object, Boolean>());
|
||||
|
||||
@ -99,7 +106,6 @@ class NetworkFieldInjector extends PlayerInjector {
|
||||
|
||||
@Override
|
||||
public void sendServerPacket(Object packet, boolean filtered) throws InvocationTargetException {
|
||||
|
||||
if (networkManager != null) {
|
||||
try {
|
||||
if (!filtered) {
|
||||
@ -122,14 +128,19 @@ class NetworkFieldInjector extends PlayerInjector {
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnsupportedListener checkListener(PacketListener listener) {
|
||||
int[] unsupported = { Packets.Server.MAP_CHUNK, Packets.Server.MAP_CHUNK_BULK };
|
||||
|
||||
// Unfortunately, we don't support chunk packets
|
||||
if (ListeningWhitelist.containsAny(listener.getSendingWhitelist(), unsupported)) {
|
||||
return new UnsupportedListener("The NETWORK_FIELD_INJECTOR hook doesn't support map chunk listeners.", unsupported);
|
||||
} else {
|
||||
public UnsupportedListener checkListener(MinecraftVersion version, PacketListener listener) {
|
||||
if (version != null && version.compareTo(safeVersion) > 0) {
|
||||
return null;
|
||||
|
||||
} else {
|
||||
int[] unsupported = { Packets.Server.MAP_CHUNK, Packets.Server.MAP_CHUNK_BULK };
|
||||
|
||||
// Unfortunately, we don't support chunk packets
|
||||
if (ListeningWhitelist.containsAny(listener.getSendingWhitelist(), unsupported)) {
|
||||
return new UnsupportedListener("The NETWORK_FIELD_INJECTOR hook doesn't support map chunk listeners.", unsupported);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@ import com.comphenix.protocol.injector.GamePhase;
|
||||
import com.comphenix.protocol.injector.ListenerInvoker;
|
||||
import com.comphenix.protocol.injector.PacketFilterManager.PlayerInjectHooks;
|
||||
import com.comphenix.protocol.injector.server.TemporaryPlayerFactory;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
|
||||
/**
|
||||
* Injection method that overrides the NetworkHandler itself, and its queue-method.
|
||||
@ -53,6 +54,12 @@ public class NetworkObjectInjector extends PlayerInjector {
|
||||
// Used to construct proxy objects
|
||||
private ClassLoader classLoader;
|
||||
|
||||
// After commit 336a4e00668fd2518c41242755ed6b3bdc3b0e6c (Update CraftBukkit to Minecraft 1.4.4.),
|
||||
// CraftBukkit stopped redirecting map chunk and map chunk bulk packets to a separate queue.
|
||||
// Thus, NetworkFieldInjector can safely handle every packet (though not perfectly - some packets
|
||||
// will be slightly processed).
|
||||
private MinecraftVersion safeVersion = new MinecraftVersion("1.4.4");
|
||||
|
||||
// Shared callback filter - avoid creating a new class every time
|
||||
private volatile static CallbackFilter callbackFilter;
|
||||
|
||||
@ -117,14 +124,19 @@ public class NetworkObjectInjector extends PlayerInjector {
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnsupportedListener checkListener(PacketListener listener) {
|
||||
int[] unsupported = { Packets.Server.MAP_CHUNK, Packets.Server.MAP_CHUNK_BULK };
|
||||
|
||||
// Unfortunately, we don't support chunk packets
|
||||
if (ListeningWhitelist.containsAny(listener.getSendingWhitelist(), unsupported)) {
|
||||
return new UnsupportedListener("The NETWORK_OBJECT_INJECTOR hook doesn't support map chunk listeners.", unsupported);
|
||||
} else {
|
||||
public UnsupportedListener checkListener(MinecraftVersion version, PacketListener listener) {
|
||||
if (version != null && version.compareTo(safeVersion) > 0) {
|
||||
return null;
|
||||
|
||||
} else {
|
||||
int[] unsupported = { Packets.Server.MAP_CHUNK, Packets.Server.MAP_CHUNK_BULK };
|
||||
|
||||
// Unfortunately, we don't support chunk packets
|
||||
if (ListeningWhitelist.containsAny(listener.getSendingWhitelist(), unsupported)) {
|
||||
return new UnsupportedListener("The NETWORK_OBJECT_INJECTOR hook doesn't support map chunk listeners.", unsupported);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@ import com.comphenix.protocol.reflect.instances.DefaultInstances;
|
||||
import com.comphenix.protocol.reflect.instances.ExistingGenerator;
|
||||
import com.comphenix.protocol.utility.MinecraftMethods;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
|
||||
/**
|
||||
* Represents a player hook into the NetServerHandler class.
|
||||
@ -326,7 +327,7 @@ class NetworkServerInjector extends PlayerInjector {
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnsupportedListener checkListener(PacketListener listener) {
|
||||
public UnsupportedListener checkListener(MinecraftVersion version, PacketListener listener) {
|
||||
// We support everything
|
||||
return null;
|
||||
}
|
||||
|
@ -126,11 +126,12 @@ public interface PlayerInjectionHandler {
|
||||
* @throws IllegalAccessException If the reflection machinery failed.
|
||||
* @throws InvocationTargetException If the underlying method caused an error.
|
||||
*/
|
||||
public abstract void processPacket(Player player, Object mcPacket)
|
||||
public abstract void recieveClientPacket(Player player, Object mcPacket)
|
||||
throws IllegalAccessException, InvocationTargetException;
|
||||
|
||||
/**
|
||||
* Determine if the given listeners are valid.
|
||||
* @param version - the current Minecraft version, or NULL if unknown.
|
||||
* @param listeners - listeners to check.
|
||||
*/
|
||||
public abstract void checkListener(Set<PacketListener> listeners);
|
||||
@ -139,6 +140,7 @@ public interface PlayerInjectionHandler {
|
||||
* Determine if a listener is valid or not.
|
||||
* <p>
|
||||
* If not, a warning will be printed to the console.
|
||||
* @param version - the current Minecraft version, or NULL if unknown.
|
||||
* @param listener - listener to check.
|
||||
*/
|
||||
public abstract void checkListener(PacketListener listener);
|
||||
|
@ -43,6 +43,7 @@ import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.reflect.VolatileField;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
|
||||
abstract class PlayerInjector implements SocketInjector {
|
||||
|
||||
@ -508,11 +509,13 @@ abstract class PlayerInjector implements SocketInjector {
|
||||
* Invoked before a new listener is registered.
|
||||
* <p>
|
||||
* The player injector should only return a non-null value if some or all of the packet IDs are unsupported.
|
||||
* @param version
|
||||
*
|
||||
* @param version - the current Minecraft version, or NULL if unknown.
|
||||
* @param listener - the listener that is about to be registered.
|
||||
* @return A error message with the unsupported packet IDs, or NULL if this listener is valid.
|
||||
*/
|
||||
public abstract UnsupportedListener checkListener(PacketListener listener);
|
||||
public abstract UnsupportedListener checkListener(MinecraftVersion version, PacketListener listener);
|
||||
|
||||
/**
|
||||
* Allows a packet to be sent by the listeners.
|
||||
|
@ -14,6 +14,7 @@ import com.comphenix.protocol.events.PacketListener;
|
||||
import com.comphenix.protocol.injector.GamePhase;
|
||||
import com.comphenix.protocol.injector.ListenerInvoker;
|
||||
import com.comphenix.protocol.injector.PacketFilterManager;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
@ -37,6 +38,7 @@ public class PlayerInjectorBuilder {
|
||||
protected ListenerInvoker invoker;
|
||||
protected Set<PacketListener> packetListeners;
|
||||
protected Server server;
|
||||
protected MinecraftVersion version;
|
||||
|
||||
/**
|
||||
* Set the class loader to use during class generation.
|
||||
@ -107,6 +109,16 @@ public class PlayerInjectorBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current Minecraft version.
|
||||
* @param server - the current Minecraft version, or NULL if unknown.
|
||||
* @return This builder, for chaining.
|
||||
*/
|
||||
public PlayerInjectorBuilder version(MinecraftVersion version) {
|
||||
this.version = version;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called before an object is created with this builder.
|
||||
*/
|
||||
@ -140,6 +152,6 @@ public class PlayerInjectorBuilder {
|
||||
|
||||
return new ProxyPlayerInjectionHandler(
|
||||
classLoader, reporter, injectionFilter,
|
||||
invoker, packetListeners, server);
|
||||
invoker, packetListeners, server, version);
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ import com.comphenix.protocol.injector.server.AbstractInputStreamLookup;
|
||||
import com.comphenix.protocol.injector.server.InputStreamLookupBuilder;
|
||||
import com.comphenix.protocol.injector.server.SocketInjector;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.cache.Cache;
|
||||
@ -91,6 +92,9 @@ class ProxyPlayerInjectionHandler implements PlayerInjectionHandler {
|
||||
// Used to invoke events
|
||||
private ListenerInvoker invoker;
|
||||
|
||||
// Current Minecraft version
|
||||
private MinecraftVersion version;
|
||||
|
||||
// Enabled packet filters
|
||||
private IntegerSet sendingFilters = new IntegerSet(Packets.MAXIMUM_PACKET_ID + 1);
|
||||
|
||||
@ -105,13 +109,14 @@ class ProxyPlayerInjectionHandler implements PlayerInjectionHandler {
|
||||
|
||||
public ProxyPlayerInjectionHandler(
|
||||
ClassLoader classLoader, ErrorReporter reporter, Predicate<GamePhase> injectionFilter,
|
||||
ListenerInvoker invoker, Set<PacketListener> packetListeners, Server server) {
|
||||
ListenerInvoker invoker, Set<PacketListener> packetListeners, Server server, MinecraftVersion version) {
|
||||
|
||||
this.classLoader = classLoader;
|
||||
this.reporter = reporter;
|
||||
this.invoker = invoker;
|
||||
this.injectionFilter = injectionFilter;
|
||||
this.packetListeners = packetListeners;
|
||||
this.version = version;
|
||||
|
||||
this.inputStreamLookup = InputStreamLookupBuilder.newBuilder().
|
||||
server(server).
|
||||
@ -501,14 +506,14 @@ class ProxyPlayerInjectionHandler implements PlayerInjectionHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a packet as if it were sent by the given player.
|
||||
* Recieve a packet as if it were sent by the given player.
|
||||
* @param player - the sender.
|
||||
* @param mcPacket - the packet to process.
|
||||
* @throws IllegalAccessException If the reflection machinery failed.
|
||||
* @throws InvocationTargetException If the underlying method caused an error.
|
||||
*/
|
||||
@Override
|
||||
public void processPacket(Player player, Object mcPacket) throws IllegalAccessException, InvocationTargetException {
|
||||
public void recieveClientPacket(Player player, Object mcPacket) throws IllegalAccessException, InvocationTargetException {
|
||||
PlayerInjector injector = getInjector(player);
|
||||
|
||||
// Process the given packet, or simply give up
|
||||
@ -619,7 +624,7 @@ class ProxyPlayerInjectionHandler implements PlayerInjectionHandler {
|
||||
@Override
|
||||
public void checkListener(PacketListener listener) {
|
||||
if (lastSuccessfulHook != null) {
|
||||
UnsupportedListener result = lastSuccessfulHook.checkListener(listener);
|
||||
UnsupportedListener result = lastSuccessfulHook.checkListener(version, listener);
|
||||
|
||||
// We won't prevent the listener, as it may still have valid packets
|
||||
if (result != null) {
|
||||
|
@ -74,7 +74,7 @@ class DummyPlayerHandler implements PlayerInjectionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPacket(Player player, Object mcPacket) throws IllegalAccessException, InvocationTargetException {
|
||||
public void recieveClientPacket(Player player, Object mcPacket) throws IllegalAccessException, InvocationTargetException {
|
||||
injector.processPacket(player, mcPacket);
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
|
||||
package com.comphenix.protocol;
|
||||
package com.comphenix.protocol.utility;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@ -31,7 +31,7 @@ import com.google.common.collect.Ordering;
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
class MinecraftVersion implements Comparable<MinecraftVersion> {
|
||||
public class MinecraftVersion implements Comparable<MinecraftVersion> {
|
||||
/**
|
||||
* Regular expression used to parse version strings.
|
||||
*/
|
@ -21,6 +21,8 @@ import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
|
||||
public class MinecraftVersionTest {
|
||||
|
||||
@Test
|
||||
|
Loading…
Reference in New Issue
Block a user