Optimize lookup of getBukkitEntity.
Dieser Commit ist enthalten in:
Ursprung
b84aace585
Commit
4259a86740
@ -56,6 +56,7 @@ import com.comphenix.protocol.reflect.ClassAnalyser;
|
|||||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||||
import com.comphenix.protocol.reflect.ClassAnalyser.AsmMethod;
|
import com.comphenix.protocol.reflect.ClassAnalyser.AsmMethod;
|
||||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||||
|
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
|
||||||
import com.comphenix.protocol.reflect.compiler.EmptyClassVisitor;
|
import com.comphenix.protocol.reflect.compiler.EmptyClassVisitor;
|
||||||
import com.comphenix.protocol.reflect.compiler.EmptyMethodVisitor;
|
import com.comphenix.protocol.reflect.compiler.EmptyMethodVisitor;
|
||||||
import com.comphenix.protocol.reflect.fuzzy.AbstractFuzzyMatcher;
|
import com.comphenix.protocol.reflect.fuzzy.AbstractFuzzyMatcher;
|
||||||
@ -69,6 +70,9 @@ import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
|||||||
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
|
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
|
||||||
import com.comphenix.protocol.wrappers.nbt.NbtType;
|
import com.comphenix.protocol.wrappers.nbt.NbtType;
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Methods and constants specifically used in conjuction with reflecting Minecraft object.
|
* Methods and constants specifically used in conjuction with reflecting Minecraft object.
|
||||||
@ -141,6 +145,14 @@ public class MinecraftReflection {
|
|||||||
// net.minecraft.server
|
// net.minecraft.server
|
||||||
private static Class<?> itemStackArrayClass;
|
private static Class<?> itemStackArrayClass;
|
||||||
|
|
||||||
|
// Cache of getBukkitEntity
|
||||||
|
private static Cache<Class<?>, MethodAccessor> getBukkitEntityCache = CacheBuilder.newBuilder().build(
|
||||||
|
new CacheLoader<Class<?>, MethodAccessor>() {
|
||||||
|
public MethodAccessor load(java.lang.Class<?> paramK) throws Exception {
|
||||||
|
return Accessors.getMethodAccessor(paramK, "getBukkitEntity");
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
// The current class source
|
// The current class source
|
||||||
private static ClassSource classSource;
|
private static ClassSource classSource;
|
||||||
|
|
||||||
@ -367,9 +379,9 @@ public class MinecraftReflection {
|
|||||||
|
|
||||||
// We will have to do this dynamically, unfortunately
|
// We will have to do this dynamically, unfortunately
|
||||||
try {
|
try {
|
||||||
return nmsObject.getClass().getMethod("getBukkitEntity").invoke(nmsObject);
|
return getBukkitEntityCache.apply(nmsObject.getClass()).invoke(nmsObject);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Cannot get Bukkit entity from " + nmsObject, e);
|
throw new IllegalArgumentException("Cannot get Bukkit entity from " + nmsObject, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,24 +106,32 @@ public class SimpleCraftBukkitITCase {
|
|||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
private static void setupPlugins() throws IOException {
|
private static void setupPlugins() throws IOException {
|
||||||
File pluginDirectory = new File("plugins/");
|
File pluginDirectory = new File("plugins/");
|
||||||
|
File srcDirectory = new File("../");
|
||||||
File bestFile = null;
|
File bestFile = null;
|
||||||
int bestLength = Integer.MAX_VALUE;
|
int bestLength = Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
for (File file : srcDirectory.listFiles()) {
|
||||||
|
String name = file.getName();
|
||||||
|
|
||||||
|
if (file.isFile() && name.startsWith("ProtocolLib") && name.length() < bestLength) {
|
||||||
|
bestLength = name.length();
|
||||||
|
bestFile = file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestFile == null) {
|
||||||
|
throw new IllegalStateException("Cannot find ProtocolLib in " + srcDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
// Copy the ProtocolLib plugin to the server
|
// Copy the ProtocolLib plugin to the server
|
||||||
if (pluginDirectory.exists()) {
|
if (pluginDirectory.exists()) {
|
||||||
Files.deleteDirectoryContents(pluginDirectory);
|
Files.deleteDirectoryContents(pluginDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (File file : new File("../").listFiles()) {
|
|
||||||
String name = file.getName();
|
|
||||||
|
|
||||||
if (name.startsWith("ProtocolLib") && name.length() < bestLength) {
|
|
||||||
bestLength = name.length();
|
|
||||||
bestFile = file;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pluginDirectory.mkdirs();
|
pluginDirectory.mkdirs();
|
||||||
Files.copy(bestFile, new File(pluginDirectory, bestFile.getName()));
|
|
||||||
|
File destination = new File(pluginDirectory, bestFile.getName()).getAbsoluteFile();
|
||||||
|
Files.copy(bestFile, destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.comphenix.protocol.utility;
|
package com.comphenix.protocol.utility;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
import net.minecraft.server.v1_7_R1.ChatComponentText;
|
import net.minecraft.server.v1_7_R1.ChatComponentText;
|
||||||
import net.minecraft.server.v1_7_R1.ChatSerializer;
|
import net.minecraft.server.v1_7_R1.ChatSerializer;
|
||||||
@ -11,6 +12,8 @@ import net.minecraft.server.v1_7_R1.ServerPing;
|
|||||||
import net.minecraft.server.v1_7_R1.ServerPingPlayerSample;
|
import net.minecraft.server.v1_7_R1.ServerPingPlayerSample;
|
||||||
import net.minecraft.server.v1_7_R1.ServerPingServerData;
|
import net.minecraft.server.v1_7_R1.ServerPingServerData;
|
||||||
|
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -19,6 +22,15 @@ import com.comphenix.protocol.BukkitInitialization;
|
|||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
public class MinecraftReflectionTest {
|
public class MinecraftReflectionTest {
|
||||||
|
// Mocking objects
|
||||||
|
private interface FakeEntity {
|
||||||
|
public Entity getBukkitEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface FakeBlock {
|
||||||
|
public Block getBukkitEntity();
|
||||||
|
}
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void initializeReflection() throws IllegalAccessException {
|
public static void initializeReflection() throws IllegalAccessException {
|
||||||
BukkitInitialization.initializePackage();
|
BukkitInitialization.initializePackage();
|
||||||
@ -32,7 +44,24 @@ public class MinecraftReflectionTest {
|
|||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void undoMocking() {
|
public static void undoMocking() {
|
||||||
MinecraftReflection.minecraftPackage = null;
|
// NOP
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBukkitMethod() {
|
||||||
|
FakeEntity entity = mock(FakeEntity.class);
|
||||||
|
FakeBlock block = mock(FakeBlock.class);
|
||||||
|
|
||||||
|
MinecraftReflection.getBukkitEntity(entity);
|
||||||
|
MinecraftReflection.getBukkitEntity(block);
|
||||||
|
|
||||||
|
verify(entity, times(1)).getBukkitEntity();
|
||||||
|
verify(block, times(1)).getBukkitEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testIllegalClass() {
|
||||||
|
MinecraftReflection.getBukkitEntity("Hello");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren