Archiviert
13
0

Fix missing TileEntity write methods

Fixes #249
Dieser Commit ist enthalten in:
Dan Mulloy 2016-08-27 13:07:49 -04:00
Ursprung 828302150a
Commit 588f736348
3 geänderte Dateien mit 58 neuen und 28 gelöschten Zeilen

Datei anzeigen

@ -46,7 +46,7 @@ class TileEntityAccessor<T extends BlockState> {
private boolean writeDetected; private boolean writeDetected;
private boolean readDetected; private boolean readDetected;
private TileEntityAccessor() { TileEntityAccessor() {
// Do nothing // Do nothing
} }
@ -59,27 +59,30 @@ class TileEntityAccessor<T extends BlockState> {
if (tileEntityField != null) { if (tileEntityField != null) {
this.tileEntityField = tileEntityField; this.tileEntityField = tileEntityField;
Class<?> type = tileEntityField.getField().getType(); Class<?> type = tileEntityField.getField().getType();
findMethods(type, state);
// Possible read/write methods
try {
findMethodsUsingASM();
} catch (IOException ex1) {
try {
// Much slower though
findMethodUsingCGLib(state);
} catch (Exception ex2) {
throw new RuntimeException("Cannot find read/write methods in " + type, ex2);
}
}
// Ensure we found them
if (readCompound == null)
throw new RuntimeException("Unable to find read method in " + type);
if (writeCompound == null)
throw new RuntimeException("Unable to find write method in " + type);
} }
} }
void findMethods(Class<?> type, T state) {
// Possible read/write methods
try {
findMethodsUsingASM();
} catch (IOException ex1) {
try {
// Much slower though
findMethodUsingCGLib(state);
} catch (Exception ex2) {
throw new RuntimeException("Cannot find read/write methods in " + type, ex2);
}
}
// Ensure we found them
if (readCompound == null)
throw new RuntimeException("Unable to find read method in " + type);
if (writeCompound == null)
throw new RuntimeException("Unable to find write method in " + type);
}
/** /**
* Find the read/write methods in TileEntity. * Find the read/write methods in TileEntity.
* @throws IOException If we cannot find these methods. * @throws IOException If we cannot find these methods.
@ -90,7 +93,7 @@ class TileEntityAccessor<T extends BlockState> {
final ClassReader reader = new ClassReader(tileEntityClass.getCanonicalName()); final ClassReader reader = new ClassReader(tileEntityClass.getCanonicalName());
final String tagCompoundName = getJarName(MinecraftReflection.getNBTCompoundClass()); final String tagCompoundName = getJarName(MinecraftReflection.getNBTCompoundClass());
final String expectedDesc = "(L" + tagCompoundName + ";)V"; final String expectedDesc = "(L" + tagCompoundName + ";)";
reader.accept(new EmptyClassVisitor() { reader.accept(new EmptyClassVisitor() {
@Override @Override
@ -98,7 +101,7 @@ class TileEntityAccessor<T extends BlockState> {
final String methodName = name; final String methodName = name;
// Detect read/write calls to NBTTagCompound // Detect read/write calls to NBTTagCompound
if (expectedDesc.equals(desc)) { if (desc.startsWith(expectedDesc)) {
return new EmptyMethodVisitor() { return new EmptyMethodVisitor() {
private int readMethods; private int readMethods;
private int writeMethods; private int writeMethods;
@ -106,9 +109,9 @@ class TileEntityAccessor<T extends BlockState> {
@Override @Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) { public void visitMethodInsn(int opcode, String owner, String name, String desc) {
// This must be a virtual call on NBTTagCompound that accepts a String // This must be a virtual call on NBTTagCompound that accepts a String
if (opcode == Opcodes.INVOKEVIRTUAL && if (opcode == Opcodes.INVOKEVIRTUAL
tagCompoundName.equals(owner) && && tagCompoundName.equals(owner)
desc.startsWith("(Ljava/lang/String")) { && desc.startsWith("(Ljava/lang/String")) {
// Is this a write call? // Is this a write call?
if (desc.endsWith(")V")) { if (desc.endsWith(")V")) {
@ -126,10 +129,12 @@ class TileEntityAccessor<T extends BlockState> {
} else if (writeMethods > readMethods) { } else if (writeMethods > readMethods) {
writeCompound = Accessors.getMethodAccessor(tileEntityClass, methodName, nbtCompoundClass); writeCompound = Accessors.getMethodAccessor(tileEntityClass, methodName, nbtCompoundClass);
} }
super.visitEnd(); super.visitEnd();
} }
}; };
} }
return null; return null;
} }
}, 0); }, 0);

Datei anzeigen

@ -24,6 +24,7 @@ import net.minecraft.server.v1_10_R1.DispenserRegistry;
*/ */
public class BukkitInitialization { public class BukkitInitialization {
private static boolean initialized; private static boolean initialized;
private static boolean packaged;
/** /**
* Initialize Bukkit and ProtocolLib such that we can perfrom unit testing. * Initialize Bukkit and ProtocolLib such that we can perfrom unit testing.
@ -34,6 +35,8 @@ public class BukkitInitialization {
// Denote that we're done // Denote that we're done
initialized = true; initialized = true;
initializePackage();
DispenserRegistry.c(); // Basically registers everything DispenserRegistry.c(); // Basically registers everything
// Mock the server object // Mock the server object
@ -50,7 +53,7 @@ public class BukkitInitialization {
// Inject this fake server // Inject this fake server
Bukkit.setServer(mockedServer); Bukkit.setServer(mockedServer);
initializePackage();
} }
} }
@ -58,8 +61,11 @@ public class BukkitInitialization {
* Ensure that package names are correctly set up. * Ensure that package names are correctly set up.
*/ */
public static void initializePackage() { public static void initializePackage() {
// Initialize reflection if (!packaged) {
MinecraftReflection.setMinecraftPackage(Constants.NMS, Constants.OBC); packaged = true;
MinecraftVersion.setCurrentVersion(MinecraftVersion.COMBAT_UPDATE);
MinecraftReflection.setMinecraftPackage(Constants.NMS, Constants.OBC);
MinecraftVersion.setCurrentVersion(MinecraftVersion.FROSTBURN_UPDATE);
}
} }
} }

Datei anzeigen

@ -1,3 +1,19 @@
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2016 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package com.comphenix.protocol; package com.comphenix.protocol;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -16,6 +32,9 @@ import com.comphenix.protocol.injector.netty.ProtocolRegistry;
import net.minecraft.server.v1_10_R1.PacketLoginInStart; import net.minecraft.server.v1_10_R1.PacketLoginInStart;
/**
* @author dmulloy2
*/
public class PacketTypeTest { public class PacketTypeTest {
@BeforeClass @BeforeClass