Compare commits

...
12 Commits
29 changed files with 253 additions and 179 deletions

No files matched your search

+14 -11
View File
@@ -2,9 +2,9 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<version>3.6.0-SNAPSHOT</version>
<name>ProtocolLib</name>
<artifactId>ProtocolLib-Legacy</artifactId>
<version>3.7.0</version>
<name>ProtocolLib-Legacy</name>
<description>Provides read/write access to the Minecraft protocol.</description>
<url>http://www.spigotmc.org/resources/protocollib.1997/</url>
@@ -17,20 +17,23 @@
<distributionManagement>
<repository>
<id>shadowvolt-repo</id>
<name>Shadowvolt Maven Repository</name>
<url>http://ci.shadowvolt.com/plugin/repository/everything/</url>
<id>dmulloy2-releases</id>
<url>http://repo.dmulloy2.net/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>dmulloy2-snapshots</id>
<url>http://repo.dmulloy2.net/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
<repositories>
<repository>
<id>md_5-repo</id>
<url>http://repo.md-5.net/content/repositories/public/</url>
<id>dmulloy2-repo</id>
<url>http://repo.dmulloy2.net/content/groups/public/</url>
</repository>
<repository>
<id>comphenix-releases</id>
<url>http://repo.comphenix.net/content/repositories/releases/</url>
<id>md_5-repo</id>
<url>http://repo.md-5.net/content/repositories/public/</url>
</repository>
</repositories>
@@ -225,7 +228,7 @@
<dependency>
<groupId>com.comphenix.executors</groupId>
<artifactId>BukkitExecutors</artifactId>
<version>1.0.0</version>
<version>1.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
@@ -30,7 +30,7 @@ import com.google.common.collect.Iterables;
* An implicitly sorted array list that preserves insertion order and maintains duplicates.
* @param <T> - type of the elements in the list.
*/
public class SortedCopyOnWriteArray<T extends Comparable<T>> implements Iterable<T>, Collection<T> {
public class SortedCopyOnWriteArray<T extends Comparable<T>> implements Collection<T> {
// Prevent reordering
private volatile List<T> list;
@@ -18,7 +18,6 @@ import org.bukkit.plugin.PluginManager;
import com.comphenix.protocol.AsynchronousManager;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Sender;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.error.Report;
import com.comphenix.protocol.error.ReportType;
@@ -42,7 +41,7 @@ import com.google.common.collect.Sets;
*
* @author Kristian
*/
public class DelayedPacketManager implements ProtocolManager, InternalManager {
public class DelayedPacketManager implements InternalManager {
// Registering packet IDs that are not supported
public static final ReportType REPORT_CANNOT_SEND_QUEUED_PACKET = new ReportType("Cannot send queued packet %s.");
public static final ReportType REPORT_CANNOT_REGISTER_QUEUED_LISTENER = new ReportType("Cannot register queued listener %s.");
@@ -25,6 +25,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bukkit.World;
@@ -52,6 +53,17 @@ class EntityUtilities {
private static Method scanPlayersMethod;
// Fix: PaperSpigot changed the trackedPlayers field
private static Collection<?> getCollection(Object value) {
if (value instanceof Collection<?>) {
return (Collection<?>) value;
} else if (value instanceof Map<?, ?>) {
return ((Map<?, ?>) value).keySet();
} else {
throw new IllegalArgumentException("Expected Collection or Map but got " + value.getClass());
}
}
/*
* While this function may look pretty bad, it's essentially just a reflection-warped
* version of the following:
@@ -85,19 +97,21 @@ class EntityUtilities {
*/
public static void updateEntity(Entity entity, List<Player> observers) throws FieldAccessException {
try {
//EntityTrackerEntry trackEntity = (EntityTrackerEntry) tracker.trackedEntities.get(entity.getEntityId());
// Fix: Throw a more informative error
Object trackerEntry = getEntityTrackerEntry(entity.getWorld(), entity.getEntityId());
if (trackerEntry == null) {
throw new IllegalArgumentException("Cannot find entity trackers for " + entity + (entity.isDead() ? " - entity is dead." : "."));
}
if (trackedPlayersField == null) {
// This one is fairly easy
trackedPlayersField = FuzzyReflection.fromObject(trackerEntry).getFieldByType("java\\.util\\..*");
}
// Phew, finally there.
Collection<?> trackedPlayers = (Collection<?>) FieldUtils.readField(trackedPlayersField, trackerEntry, false);
Collection<?> trackedPlayers = getCollection(FieldUtils.readField(trackedPlayersField, trackerEntry, false));
List<Object> nmsPlayers = unwrapBukkit(observers);
// trackEntity.trackedPlayers.clear();
trackedPlayers.removeAll(nmsPlayers);
// We have to rely on a NAME once again. Damn it.
@@ -105,7 +119,6 @@ class EntityUtilities {
scanPlayersMethod = trackerEntry.getClass().getMethod("scanPlayers", List.class);
}
//trackEntity.scanPlayers(server.players);
scanPlayersMethod.invoke(trackerEntry, nmsPlayers);
} catch (IllegalArgumentException e) {
@@ -130,17 +143,17 @@ class EntityUtilities {
public static List<Player> getEntityTrackers(Entity entity) {
try {
List<Player> result = new ArrayList<Player>();
Object trackerEntry = getEntityTrackerEntry(entity.getWorld(), entity.getEntityId());
if (trackerEntry == null) {
throw new IllegalArgumentException("Cannot find entity trackers for " + entity +
(entity.isDead() ? " - entity is dead." : "."));
throw new IllegalArgumentException("Cannot find entity trackers for " + entity + (entity.isDead() ? " - entity is dead." : "."));
}
if (trackedPlayersField == null) {
trackedPlayersField = FuzzyReflection.fromObject(trackerEntry).getFieldByType("java\\.util\\..*");
}
Collection<?> trackedPlayers = (Collection<?>) FieldUtils.readField(trackedPlayersField, trackerEntry, false);
Collection<?> trackedPlayers = getCollection(FieldUtils.readField(trackedPlayersField, trackerEntry, false));
// Wrap every player - we also ensure that the underlying tracker list is immutable
for (Object tracker : trackedPlayers) {
@@ -33,14 +33,14 @@ class LoginPackets {
clientSide.add(Packets.Client.GET_INFO);
// In 1.6.2, Minecraft started sending CUSTOM_PAYLOAD in the server list protocol
if (version.compareTo(MinecraftVersion.HORSE_UPDATE) >= 0) {
if (version.compareTo(MinecraftVersion.HORSE_UPDATE) >= 0 || triesForgeIntegration()) {
clientSide.add(Packets.Client.CUSTOM_PAYLOAD);
}
serverSide.add(Packets.Server.KICK_DISCONNECT);
// MCPC++ contains Forge, which uses packet 250 during login
if (isMCPC()) {
clientSide.add(Packets.Client.CUSTOM_PAYLOAD);
// Forge uses packet 250 during login
if (triesForgeIntegration()) {
serverSide.add(Packets.Client.CUSTOM_PAYLOAD);
}
}
@@ -48,8 +48,9 @@ class LoginPackets {
* Determine if we are runnign MCPC.
* @return TRUE if we are, FALSE otherwise.
*/
private static boolean isMCPC() {
return Bukkit.getServer().getVersion().contains("MCPC-Plus");
private static boolean triesForgeIntegration() {
String version = Bukkit.getVersion();
return version.contains("MCPC-Plus") || version.contains("Cauldron") || version.contains("Thermos");
}
/**
@@ -51,7 +51,6 @@ import org.bukkit.plugin.PluginManager;
import com.comphenix.protocol.AsynchronousManager;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Sender;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.async.AsyncFilterManager;
import com.comphenix.protocol.async.AsyncMarker;
import com.comphenix.protocol.error.ErrorReporter;
@@ -88,7 +87,7 @@ import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
public final class PacketFilterManager implements ProtocolManager, ListenerInvoker, InternalManager {
public final class PacketFilterManager implements ListenerInvoker, InternalManager {
public static final ReportType REPORT_CANNOT_LOAD_PACKET_LIST = new ReportType("Cannot load server and client packet list.");
public static final ReportType REPORT_CANNOT_INITIALIZE_PACKET_INJECTOR = new ReportType("Unable to initialize packet injector");
@@ -39,8 +39,8 @@ public class LegacyNetworkMarker extends NetworkMarker {
return ByteBuffer.wrap(Bytes.concat(new byte[] { (byte) type.getLegacyId() }, buffer.array()));
}
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
@SuppressWarnings("unchecked")
protected DataInputStream addHeader(final DataInputStream input, final PacketType type) {
InputSupplier<InputStream> header = new InputSupplier<InputStream>() {
@Override
@@ -59,7 +59,7 @@ public class LegacyNetworkMarker extends NetworkMarker {
// Combine them into a single stream
try {
return new DataInputStream(ByteStreams.join((InputSupplier) header, (InputSupplier) data).getInput());
return new DataInputStream(ByteStreams.join(header, data).getInput());
} catch (IOException e) {
throw new RuntimeException("Cannot add header.", e);
}
@@ -1,5 +1,7 @@
package com.comphenix.protocol.injector.packet;
import static com.google.common.base.Preconditions.checkNotNull;
import java.lang.reflect.Field;
import com.comphenix.protocol.reflect.FieldUtils;
@@ -10,17 +12,20 @@ import com.comphenix.protocol.reflect.FieldUtils;
*/
public class MapContainer {
// For detecting changes
private Field modCountField;
private final Field modCountField;
private int lastModCount;
// The object along with whether or not this is the initial run
private Object source;
private final Object source;
private boolean changed;
public MapContainer(Object source) {
this.source = source;
this.changed = true;
this.modCountField = FieldUtils.getField(source.getClass(), "modCount", true);
this.changed = false;
Field modCountField = FieldUtils.getField(source.getClass(), "modCount", true);
this.modCountField = checkNotNull(modCountField, "Failed to obtain modCount field");
this.lastModCount = getModificationCount();
}
/**
@@ -55,13 +60,13 @@ public class MapContainer {
/**
* Retrieve the current modification count.
* @return The current count, or something different than lastModCount if not accessible.
* @return The current count
*/
private int getModificationCount() {
try {
return modCountField != null ? modCountField.getInt(source) : lastModCount + 1;
} catch (Exception e) {
throw new RuntimeException("Unable to retrieve modCount.", e);
return modCountField.getInt(source);
} catch (Exception ex) {
throw new RuntimeException("Unable to retrieve modCount.", ex);
}
}
}
@@ -348,7 +348,7 @@ class ProxyPacketInjector implements PacketInjector {
@Override
public PacketEvent packetRecieved(PacketContainer packet, Player client, byte[] buffered) {
NetworkMarker marker = buffered != null ? new LegacyNetworkMarker(ConnectionSide.CLIENT_SIDE, buffered, packet.getType()) : null;
PacketEvent event = PacketEvent.fromClient((Object) manager, packet, marker, client);
PacketEvent event = PacketEvent.fromClient(manager, packet, marker, client);
manager.invokePacketRecieving(event);
return event;
@@ -176,7 +176,7 @@ public abstract class PlayerInjector implements SocketInjector {
* @param player - the player to hook.
*/
public void initializePlayer(Player player) {
Object notchEntity = getEntityPlayer((Player) player);
Object notchEntity = getEntityPlayer(player);
// Save the player too
this.player = player;
@@ -587,7 +587,7 @@ public abstract class PlayerInjector implements SocketInjector {
* @param packet - packet to sent.
* @return The given packet, or the packet replaced by the listeners.
*/
@SuppressWarnings("deprecation")
@SuppressWarnings({ "deprecation", "null" })
public Object handlePacketSending(Object packet) {
try {
// Get the packet ID too
@@ -8,7 +8,6 @@ import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.concurrency.PacketTypeSet;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.injector.packet.PacketInjector;
import com.google.common.collect.Sets;
/**
@@ -16,7 +15,7 @@ import com.google.common.collect.Sets;
*
* @author Kristian
*/
class DummyPacketInjector extends AbstractPacketInjector implements PacketInjector {
class DummyPacketInjector extends AbstractPacketInjector {
private SpigotPacketInjector injector;
private PacketTypeSet lastBufferedPackets = new PacketTypeSet();
@@ -1,5 +1,6 @@
package com.comphenix.protocol.reflect;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.Member;
@@ -72,6 +73,16 @@ public abstract class MethodInfo implements GenericDeclaration, Member {
public boolean isConstructor() {
return false;
}
public <T extends Annotation> T getAnnotation(Class<T> clazz) {
return method.getAnnotation(clazz);
}
public Annotation[] getAnnotations() {
return method.getAnnotations();
}
public Annotation[] getDeclaredAnnotations() {
return method.getDeclaredAnnotations();
}
};
}
@@ -152,6 +163,16 @@ public abstract class MethodInfo implements GenericDeclaration, Member {
public boolean isConstructor() {
return true;
}
public <T extends Annotation> T getAnnotation(Class<T> clazz) {
return constructor.getAnnotation(clazz);
}
public Annotation[] getAnnotations() {
return constructor.getAnnotations();
}
public Annotation[] getDeclaredAnnotations() {
return constructor.getAnnotations();
}
};
}
@@ -6,6 +6,8 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.apache.commons.lang.Validate;
/**
* Represents a cloner that can clone any class that implements Serializable.
* @author Kristian Stangeland
@@ -30,21 +32,18 @@ public class SerializableCloner implements Cloner {
* @return The cloned object.
* @throws RuntimeException If we were unable to clone the object.
*/
@SuppressWarnings("unchecked")
public static <T extends Serializable> T clone(final T obj) {
try {
if (obj instanceof Serializable) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(out);
@SuppressWarnings("unchecked")
public static <T extends Serializable> T clone(final T obj) {
try {
Validate.notNull(obj, "Object cannot be null!");
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(out);
oout.writeObject(obj);
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray()));
return (T) in.readObject();
} else {
throw new RuntimeException("Object " + obj + " is not serializable!");
}
} catch (Exception e) {
throw new RuntimeException("Unable to clone object " + obj + " (" + obj.getClass().getName() + ")", e);
}
}
oout.writeObject(obj);
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray()));
return (T) in.readObject();
} catch (Exception e) {
throw new RuntimeException("Unable to clone object " + obj + " (" + obj.getClass().getName() + ")", e);
}
}
}
@@ -73,7 +73,7 @@ public abstract class CompiledStructureModifier extends StructureModifier<Object
Integer index = entry.getValue();
Field field = entry.getKey();
write(index, (Object) generator.getDefault(field.getType()));
write(index, generator.getDefault(field.getType()));
}
return this;
@@ -165,7 +165,7 @@ class MethodDescriptor {
}
String t = type.substring(0, type.length() - sb.length() * 2);
String desc = (String) DESCRIPTORS.get(t);
String desc = DESCRIPTORS.get(t);
if (desc != null) {
sb.append(desc);
} else {
@@ -146,6 +146,8 @@ public final class StructureCompiler {
private static String SUPER_CLASS = "com/comphenix/protocol/reflect/StructureModifier";
private static String COMPILED_CLASS = PACKAGE_NAME + "/CompiledStructureModifier";
private static String FIELD_EXCEPTION_CLASS = "com/comphenix/protocol/reflect/FieldAccessException";
private static boolean attemptClassLoad = false;
/**
* Construct a structure compiler.
@@ -168,6 +170,11 @@ public final class StructureCompiler {
return true;
}
// Fix: Loading classes causes a ton of lag and isn't necessary
if (!attemptClassLoad) {
return false;
}
try {
String className = getCompiledName(source);
@@ -84,8 +84,8 @@ public abstract class AbstractFuzzyMatcher<T> implements Comparable<AbstractFuzz
@Override
public int compareTo(AbstractFuzzyMatcher<T> obj) {
if (obj instanceof AbstractFuzzyMatcher) {
AbstractFuzzyMatcher<?> matcher = (AbstractFuzzyMatcher<?>) obj;
if (obj != null) {
AbstractFuzzyMatcher<?> matcher = obj;
return Ints.compare(getRoundNumber(), matcher.getRoundNumber());
}
// No match
@@ -251,7 +251,7 @@ public class FuzzyClassContract extends AbstractFuzzyMatcher<Class<?>> {
(baseclassContracts.size() == 0 ||
processValue(value.getSuperclass(), parent, baseclassContracts)) &&
(interfaceContracts.size() == 0 ||
processContracts(Arrays.asList(value.getInterfaces()), (Class<?>) parent, interfaceContracts));
processContracts(Arrays.asList(value.getInterfaces()), parent, interfaceContracts));
}
private <T> boolean processContracts(Collection<T> values, Object parent, List<AbstractFuzzyMatcher<T>> matchers) {
@@ -326,7 +326,7 @@ public class DefaultInstances implements InstanceProvider {
*/
protected <T> T createInstance(Class<T> type, Constructor<T> constructor, Class<?>[] types, Object[] params) {
try {
return (T) constructor.newInstance(params);
return constructor.newInstance(params);
} catch (Exception e) {
//e.printStackTrace();
// Cannot create it
@@ -1,4 +1,4 @@
/*
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2012 Kristian S. Stangeland
*
@@ -14,11 +14,11 @@
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package com.comphenix.protocol.utility;
import java.util.Map;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
@@ -29,10 +29,10 @@ import com.google.common.collect.Maps;
* @author Kristian
*/
class CachedPackage {
private final Map<String, Class<?>> cache;
private final Map<String, Optional<Class<?>>> cache;
private final String packageName;
private final ClassSource source;
/**
* Construct a new cached package.
* @param packageName - the name of the current package.
@@ -43,16 +43,20 @@ class CachedPackage {
this.cache = Maps.newConcurrentMap();
this.source = source;
}
/**
* Associate a given class with a class name.
* @param className - class name.
* @param clazz - type of class.
*/
public void setPackageClass(String className, Class<?> clazz) {
cache.put(className, clazz);
if (clazz != null) {
cache.put(className, Optional.<Class<?>> of(clazz));
} else {
cache.remove(className);
}
}
/**
* Retrieve the class object of a specific class in the current package.
* @param className - the specific class.
@@ -60,25 +64,33 @@ class CachedPackage {
* @throws RuntimeException If we are unable to find the given class.
*/
public Class<?> getPackageClass(String className) {
Preconditions.checkNotNull(className, "className cannot be null!");
// See if we've already looked it up
if (cache.containsKey(className)) {
Optional<Class<?>> result = cache.get(className);
if (!result.isPresent()) {
throw new RuntimeException("Cannot find class " + className);
}
return result.get();
}
try {
Class<?> result = cache.get(Preconditions.checkNotNull(className, "className cannot be NULL"));
// Concurrency is not a problem - we don't care if we look up a class twice
if (result == null) {
// Look up the class dynamically
result = source.loadClass(combine(packageName, className));
if (result == null)
throw new IllegalArgumentException("Source " + source + " returned NULL for " + className);
cache.put(className, result);
}
return result;
} catch (ClassNotFoundException e) {
throw new RuntimeException("Cannot find class " + className, e);
// Try looking it up
Class<?> clazz = source.loadClass(combine(packageName, className));
if (clazz == null) {
throw new IllegalArgumentException("Source " + source + " returned null for " + className);
}
cache.put(className, Optional.<Class<?>> of(clazz));
return clazz;
} catch (ClassNotFoundException ex) {
cache.put(className, Optional.<Class<?>> absent());
throw new RuntimeException("Cannot find class " + className, ex);
}
}
/**
* Correctly combine a package name and the child class we're looking for.
* @param packageName - name of the package, or an empty string for the default package.
@@ -66,8 +66,8 @@ import com.comphenix.protocol.reflect.fuzzy.FuzzyClassContract;
import com.comphenix.protocol.reflect.fuzzy.FuzzyFieldContract;
import com.comphenix.protocol.reflect.fuzzy.FuzzyMatchers;
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
import com.comphenix.protocol.utility.RemappedClassSource.RemapperUnavaibleException;
import com.comphenix.protocol.utility.RemappedClassSource.RemapperUnavaibleException.Reason;
import com.comphenix.protocol.utility.RemappedClassSource.RemapperUnavailableException;
import com.comphenix.protocol.utility.RemappedClassSource.RemapperUnavailableException.Reason;
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
import com.comphenix.protocol.wrappers.nbt.NbtType;
@@ -942,6 +942,9 @@ public class MinecraftReflection {
return getMinecraftClass("MinecraftServer");
} catch (RuntimeException e) {
useFallbackServer();
// Reset the cache and try again
setMinecraftClass("MinecraftServer", null);
return getMinecraftClass("MinecraftServer");
}
}
@@ -990,8 +993,10 @@ public class MinecraftReflection {
try {
return getMinecraftClass("ServerConfigurationManager", "PlayerList");
} catch (RuntimeException e) {
// Try again
useFallbackServer();
// Reset cache and try again
setMinecraftClass("ServerConfigurationManager", null);
return getMinecraftClass("ServerConfigurationManager");
}
}
@@ -1578,6 +1583,9 @@ public class MinecraftReflection {
} catch (RuntimeException e) {
// Initialize first
getAttributeSnapshotClass();
// Reset cache and try again
setMinecraftClass("AttributeModifier", null);
return getMinecraftClass("AttributeModifier");
}
}
@@ -1893,9 +1901,11 @@ public class MinecraftReflection {
* @throws RuntimeException If we are unable to find the given class.
*/
public static Class<?> getCraftBukkitClass(String className) {
return getClass(getCraftBukkitPackage() + "." + className);
if (craftbukkitPackage == null)
craftbukkitPackage = new CachedPackage(getCraftBukkitPackage(), getClassSource());
return craftbukkitPackage.getPackageClass(className);
}
/**
* Retrieve the class object of a specific Minecraft class.
* @param className - the specific Minecraft class.
@@ -1903,30 +1913,9 @@ public class MinecraftReflection {
* @throws RuntimeException If we are unable to find the given class.
*/
public static Class<?> getMinecraftClass(String className) {
return getClass(getMinecraftPackage() + "." + className);
}
/**
* Retrieve the class object of a specific Minecraft library class.
* @param className - the specific library Minecraft class.
* @return Class object.
* @throws RuntimeException If we are unable to find the given class.
*/
public static Class<?> getMinecraftLibraryClass(String className) {
return getClass(getMinecraftLibraryPackage() + "." + className);
}
/**
* Set the class object for the specific library class.
* @param className - name of the Minecraft library class.
* @param clazz - the new class object.
* @return The provided clazz object.
*/
private static Class<?> setMinecraftLibraryClass(String className, Class<?> clazz) {
if (libraryPackage == null)
libraryPackage = new CachedPackage(getMinecraftLibraryPackage(), getClassSource());
libraryPackage.setPackageClass(className, clazz);
return clazz;
if (minecraftPackage == null)
minecraftPackage = new CachedPackage(getMinecraftPackage(), getClassSource());
return minecraftPackage.getPackageClass(className);
}
/**
@@ -1954,7 +1943,7 @@ public class MinecraftReflection {
// Attempt to use MCPC
try {
return classSource = new RemappedClassSource().initialize();
} catch (RemapperUnavaibleException e) {
} catch (RemapperUnavailableException e) {
if (e.getReason() != Reason.MCPC_NOT_PRESENT)
reporter.reportWarning(MinecraftReflection.class, Report.newBuilder(REPORT_CANNOT_FIND_MCPC_REMAPPER));
} catch (Exception e) {
@@ -1964,6 +1953,7 @@ public class MinecraftReflection {
// Just use the default class loader
classSource = ClassSource.fromClassLoader();
}
return classSource;
}
@@ -1978,7 +1968,7 @@ public class MinecraftReflection {
try {
// Try the main class first
return getMinecraftClass(className);
} catch (RuntimeException e1) {
} catch (RuntimeException e) {
Class<?> success = null;
// Try every alias too
@@ -1986,8 +1976,8 @@ public class MinecraftReflection {
try {
success = getMinecraftClass(alias);
break;
} catch (RuntimeException e2) {
// Swallov
} catch (RuntimeException e1) {
// e1.printStackTrace();
}
}
@@ -1997,15 +1987,37 @@ public class MinecraftReflection {
return success;
} else {
// Hack failed
throw new RuntimeException(
String.format("Unable to find %s (%s)",
className,
Joiner.on(", ").join(aliases))
);
throw new RuntimeException(String.format("Unable to find %s (%s)", className, Joiner.on(", ").join(aliases)));
}
}
}
/**
* Retrieve the class object of a specific Minecraft library class.
* @param className - the specific library Minecraft class.
* @return Class object.
* @throws RuntimeException If we are unable to find the given class.
*/
public static Class<?> getMinecraftLibraryClass(String className) {
if (libraryPackage == null)
libraryPackage = new CachedPackage(getMinecraftLibraryPackage(), getClassSource());
return libraryPackage.getPackageClass(className);
}
/**
* Set the class object for the specific library class.
* @param className - name of the Minecraft library class.
* @param clazz - the new class object.
* @return The provided clazz object.
*/
private static Class<?> setMinecraftLibraryClass(String className, Class<?> clazz) {
if (libraryPackage == null)
libraryPackage = new CachedPackage(getMinecraftLibraryPackage(), getClassSource());
libraryPackage.setPackageClass(className, clazz);
return clazz;
}
/**
* Dynamically retrieve the NetworkManager name.
* @return Name of the NetworkManager class.
@@ -27,7 +27,7 @@ import org.bukkit.Bukkit;
import com.comphenix.protocol.reflect.FieldUtils;
import com.comphenix.protocol.reflect.MethodUtils;
import com.comphenix.protocol.utility.RemappedClassSource.RemapperUnavaibleException.Reason;
import com.comphenix.protocol.utility.RemappedClassSource.RemapperUnavailableException.Reason;
class RemappedClassSource extends ClassSource {
private Object classRemapper;
@@ -52,19 +52,23 @@ class RemappedClassSource extends ClassSource {
/**
* Attempt to load the MCPC remapper.
* @return TRUE if we succeeded, FALSE otherwise.
* @throws RemapperUnavaibleException If the remapper is not present.
* @throws RemapperUnavailableException If the remapper is not present.
*/
public RemappedClassSource initialize() {
try {
if (Bukkit.getServer() == null || !Bukkit.getServer().getVersion().contains("MCPC-Plus")) {
throw new RemapperUnavaibleException(Reason.MCPC_NOT_PRESENT);
if (Bukkit.getServer() == null) {
throw new RemapperUnavailableException(Reason.BUKKIT_NOT_INIT);
}
// Obtain the Class remapper used by MCPC+
if (!triesForgeIntegration(Bukkit.getVersion())) {
throw new RemapperUnavailableException(Reason.MCPC_NOT_PRESENT);
}
// Obtain the Class remapper used by MCPC+/Cauldron/What have you
this.classRemapper = FieldUtils.readField(getClass().getClassLoader(), "remapper", true);
if (this.classRemapper == null) {
throw new RemapperUnavaibleException(Reason.REMAPPER_DISABLED);
throw new RemapperUnavailableException(Reason.REMAPPER_DISABLED);
}
// Initialize some fields and methods used by the Jar Remapper
@@ -75,7 +79,7 @@ class RemappedClassSource extends ClassSource {
return this;
} catch (RemapperUnavaibleException e) {
} catch (RemapperUnavailableException e) {
throw e;
} catch (Exception e) {
// Damn it
@@ -83,6 +87,10 @@ class RemappedClassSource extends ClassSource {
}
}
private boolean triesForgeIntegration(String version) {
return version.contains("MCPC") || version.contains("Cauldron") || version.contains("Thermos");
}
@Override
public Class<?> loadClass(String canonicalName) throws ClassNotFoundException {
final String remapped = getClassName(canonicalName);
@@ -108,12 +116,13 @@ class RemappedClassSource extends ClassSource {
}
}
public static class RemapperUnavaibleException extends RuntimeException {
public static class RemapperUnavailableException extends RuntimeException {
private static final long serialVersionUID = 1L;
public enum Reason {
MCPC_NOT_PRESENT("The server is not running MCPC+"),
REMAPPER_DISABLED("Running an MCPC+ server but the remapper is unavailable. Please turn it on!");
BUKKIT_NOT_INIT("Bukkit is not initialized"),
MCPC_NOT_PRESENT("The server is not running Forge+Bukkit"),
REMAPPER_DISABLED("Running a Forge+Bukkit server but the remapper is unavailable. Please turn it on!");
private final String message;
@@ -132,13 +141,13 @@ class RemappedClassSource extends ClassSource {
private final Reason reason;
public RemapperUnavaibleException(Reason reason) {
public RemapperUnavailableException(Reason reason) {
super(reason.getMessage());
this.reason = reason;
}
/**
* Retrieve the reasont he remapper is unavailable.
* Retrieve the reason the remapper is unavailable.
* @return The reason.
*/
public Reason getReason() {
@@ -33,7 +33,7 @@ public class SnapshotVersion implements Comparable<SnapshotVersion>, Serializabl
if (matcher.matches()) {
try {
this.snapshotDate = getDateFormat().parse(matcher.group(1));
this.snapshotWeekVersion = (int)matcher.group(2).charAt(0) - (int)'a';
this.snapshotWeekVersion = matcher.group(2).charAt(0) - 'a';
this.rawString = version;
} catch (ParseException e) {
throw new IllegalArgumentException("Date implied by snapshot version is invalid.", e);
@@ -83,7 +83,7 @@ public class SnapshotVersion implements Comparable<SnapshotVersion>, Serializabl
rawString = String.format("%02dw%02d%s",
current.get(Calendar.YEAR) % 100,
current.get(Calendar.WEEK_OF_YEAR),
(char) ((int)'a' + snapshotWeekVersion));
(char) ('a' + snapshotWeekVersion));
}
return rawString;
}
@@ -120,7 +120,8 @@ public class BukkitConverters {
* @author Kristian
* @param <T> - type that can be converted.
*/
private static abstract class IgnoreNullConverter<TType> implements EquivalentConverter<TType> {
public static abstract class IgnoreNullConverter<TType> implements EquivalentConverter<TType> {
@Override
public final Object getGeneric(Class<?> genericType, TType specific) {
if (specific != null)
return getGenericValue(genericType, specific);
@@ -153,20 +154,20 @@ public class BukkitConverters {
@Override
public boolean equals(Object obj) {
// Very short
if (this == obj)
return true;
if (obj == null)
return false;
// See if they're equivalent
if (this == obj) return true;
if (obj instanceof EquivalentConverter) {
@SuppressWarnings("rawtypes")
EquivalentConverter other = (EquivalentConverter) obj;
return Objects.equal(this.getSpecificType(), other.getSpecificType());
EquivalentConverter<?> that = (EquivalentConverter<?>) obj;
return Objects.equal(this.getSpecificType(), that.getSpecificType());
}
return false;
}
@Override
public int hashCode() {
return Objects.hashCode(this.getSpecificType());
}
}
/**
@@ -189,21 +190,21 @@ public class BukkitConverters {
@Override
public boolean equals(Object obj) {
// More shortcuts
if (obj == this)
return true;
if (obj == null)
return false;
if (obj == this) return true;
// Add another constraint
if (obj instanceof WorldSpecificConverter && super.equals(obj)) {
@SuppressWarnings("rawtypes")
WorldSpecificConverter other = (WorldSpecificConverter) obj;
return Objects.equal(world, other.world);
WorldSpecificConverter<?> that = (WorldSpecificConverter<?>) obj;
return Objects.equal(this.world, that.world);
}
return false;
}
@Override
public int hashCode() {
return Objects.hashCode(this.getSpecificType(), this.world);
}
}
/**
@@ -832,7 +833,6 @@ public class BukkitConverters {
*/
public static Unwrapper asUnwrapper(final Class<?> nativeType, final EquivalentConverter<Object> converter) {
return new Unwrapper() {
@SuppressWarnings("rawtypes")
@Override
public Object unwrapItem(Object wrappedObject) {
Class<?> type = PacketConstructor.getClass(wrappedObject);
@@ -842,7 +842,7 @@ public class BukkitConverters {
if (wrappedObject instanceof Class)
return nativeType;
else
return converter.getGeneric((Class) nativeType, wrappedObject);
return converter.getGeneric(nativeType, wrappedObject);
}
return null;
}
@@ -84,7 +84,7 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
this.secondaryValue = parameters.length > 1 ? Accessors.getFieldAccessor(spigotClass, "value2", true) : null;
} catch (ClassNotFoundException e) {
System.out.println("[ProtocolLib] Unable to find " + className);
// System.out.println("[ProtocolLib] Unable to find " + className);
this.spigotClass = null;
}
this.typeId = typeId;
@@ -519,7 +519,7 @@ public class NbtFactory {
if (type == NbtType.TAG_COMPOUND)
return (NbtWrapper<T>) new WrappedCompound(handle);
else if (type == NbtType.TAG_LIST)
return (NbtWrapper<T>) new WrappedList(handle);
return new WrappedList(handle);
else
return new WrappedElement<T>(handle);
}
@@ -532,7 +532,7 @@ public class NbtFactory {
if (type == NbtType.TAG_COMPOUND)
return (NbtWrapper<T>) new WrappedCompound(handle, name);
else if (type == NbtType.TAG_LIST)
return (NbtWrapper<T>) new WrappedList(handle, name);
return new WrappedList(handle, name);
else
return new WrappedElement<T>(handle, name);
}
@@ -31,7 +31,7 @@ import com.comphenix.protocol.wrappers.nbt.io.NbtBinarySerializer;
*
* @author Kristian
*/
class WrappedCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterable<NbtBase<?>>, NbtCompound {
class WrappedCompound implements NbtWrapper<Map<String, NbtBase<?>>>, NbtCompound {
// A list container
private WrappedElement<Map<String, Object>> container;
@@ -636,7 +636,7 @@ class WrappedCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterable<N
}
@Override
public <T> NbtBase<?> remove(String key) {
public NbtBase<?> remove(String key) {
return getValue().remove(key);
}
@@ -36,7 +36,7 @@ import com.google.common.collect.Iterables;
*
* @param <TType> - the type of the value in each NBT sub element.
*/
class WrappedList<TType> implements NbtWrapper<List<NbtBase<TType>>>, Iterable<TType>, NbtList<TType> {
class WrappedList<TType> implements NbtWrapper<List<NbtBase<TType>>>, NbtList<TType> {
// A list container
private WrappedElement<List<Object>> container;
@@ -6,7 +6,6 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
@@ -50,8 +49,7 @@ public class SimpleMinecraftClient {
Socket socket = null;
OutputStream output = null;
InputStream input = null;
InputStreamReader reader = null;
try {
socket = new Socket();
socket.connect(address, CONNECT_TIMEOUT);
@@ -76,10 +74,7 @@ public class SimpleMinecraftClient {
socket.close();
return ((ResponsePacket) packet).getPingJson();
} finally {
if (reader != null)
reader.close();
if (input != null)
input.close();
if (output != null)