From 8574f7bb360e3e19924a4cdd57ab1fa955fab037 Mon Sep 17 00:00:00 2001 From: wizjany Date: Sun, 1 Dec 2013 14:13:34 -0500 Subject: [PATCH] Update NMS access to 1.7.2. --- pom.xml | 2 +- .../worldedit/bukkit/DefaultNmsBlock.java | 185 ++++++++++-------- .../resources/nmsblocks/CBXNmsBlock_164.class | Bin 0 -> 12590 bytes 3 files changed, 105 insertions(+), 82 deletions(-) create mode 100644 src/main/resources/nmsblocks/CBXNmsBlock_164.class diff --git a/pom.xml b/pom.xml index 805bddd15..ad0bec651 100644 --- a/pom.xml +++ b/pom.xml @@ -125,7 +125,7 @@ org.bukkit craftbukkit - 1.6.4-R0.1-SNAPSHOT + 1.7.2-R0.1-SNAPSHOT compile jar true diff --git a/src/main/java/com/sk89q/worldedit/bukkit/DefaultNmsBlock.java b/src/main/java/com/sk89q/worldedit/bukkit/DefaultNmsBlock.java index 298443475..7e1f6600c 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/DefaultNmsBlock.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/DefaultNmsBlock.java @@ -18,6 +18,7 @@ package com.sk89q.worldedit.bukkit; */ import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -25,23 +26,23 @@ import java.util.List; import java.util.Map; import java.util.logging.Logger; -import net.minecraft.server.v1_6_R3.NBTBase; -import net.minecraft.server.v1_6_R3.NBTTagByte; -import net.minecraft.server.v1_6_R3.NBTTagByteArray; -import net.minecraft.server.v1_6_R3.NBTTagCompound; -import net.minecraft.server.v1_6_R3.NBTTagDouble; -import net.minecraft.server.v1_6_R3.NBTTagEnd; -import net.minecraft.server.v1_6_R3.NBTTagFloat; -import net.minecraft.server.v1_6_R3.NBTTagInt; -import net.minecraft.server.v1_6_R3.NBTTagIntArray; -import net.minecraft.server.v1_6_R3.NBTTagList; -import net.minecraft.server.v1_6_R3.NBTTagLong; -import net.minecraft.server.v1_6_R3.NBTTagShort; -import net.minecraft.server.v1_6_R3.NBTTagString; -import net.minecraft.server.v1_6_R3.TileEntity; +import net.minecraft.server.v1_7_R1.NBTBase; +import net.minecraft.server.v1_7_R1.NBTTagByte; +import net.minecraft.server.v1_7_R1.NBTTagByteArray; +import net.minecraft.server.v1_7_R1.NBTTagCompound; +import net.minecraft.server.v1_7_R1.NBTTagDouble; +import net.minecraft.server.v1_7_R1.NBTTagEnd; +import net.minecraft.server.v1_7_R1.NBTTagFloat; +import net.minecraft.server.v1_7_R1.NBTTagInt; +import net.minecraft.server.v1_7_R1.NBTTagIntArray; +import net.minecraft.server.v1_7_R1.NBTTagList; +import net.minecraft.server.v1_7_R1.NBTTagLong; +import net.minecraft.server.v1_7_R1.NBTTagShort; +import net.minecraft.server.v1_7_R1.NBTTagString; +import net.minecraft.server.v1_7_R1.TileEntity; import org.bukkit.World; -import org.bukkit.craftbukkit.v1_6_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_7_R1.CraftWorld; import com.sk89q.jnbt.ByteArrayTag; import com.sk89q.jnbt.ByteTag; @@ -81,7 +82,7 @@ public class DefaultNmsBlock extends NmsBlock { static { Field field; try { - field = net.minecraft.server.v1_6_R3.Block.class.getDeclaredField("isTileEntity"); + field = net.minecraft.server.v1_7_R1.Block.class.getDeclaredField("isTileEntity"); field.setAccessible(true); } catch (NoSuchFieldException e) { // logger.severe("Could not find NMS block tile entity field!"); @@ -133,9 +134,9 @@ public class DefaultNmsBlock extends NmsBlock { return null; } - nbtData.set("x", new NBTTagInt("x", pt.getBlockX())); - nbtData.set("y", new NBTTagInt("y", pt.getBlockY())); - nbtData.set("z", new NBTTagInt("z", pt.getBlockZ())); + nbtData.set("x", new NBTTagInt(pt.getBlockX())); + nbtData.set("y", new NBTTagInt(pt.getBlockY())); + nbtData.set("z", new NBTTagInt(pt.getBlockZ())); return nbtData; } @@ -253,7 +254,7 @@ public class DefaultNmsBlock extends NmsBlock { // TileEntity te = craftWorld.getHandle().getTileEntity(x, y, z); // craftWorld.getHandle().tileEntityList.remove(te); - boolean changed = craftWorld.getHandle().setTypeIdAndData(x, y, z, block.getId(), block.getData(), 0); + boolean changed = craftWorld.getHandle().setTypeAndData(x, y, z, getNmsBlock(block.getId()), block.getData(), 0); if (block instanceof BaseBlock) { world.copyToWorld(position, (BaseBlock) block); @@ -262,14 +263,14 @@ public class DefaultNmsBlock extends NmsBlock { changed = craftWorld.getHandle().setData(x, y, z, block.getData(), 0) || changed; if (changed && notifyAdjacent) { craftWorld.getHandle().notify(x, y, z); - craftWorld.getHandle().update(x, y, z, block.getId()); + craftWorld.getHandle().update(x, y, z, getNmsBlock(block.getId())); } return changed; } public static boolean hasTileEntity(int type) { - net.minecraft.server.v1_6_R3.Block nmsBlock = getNmsBlock(type); + net.minecraft.server.v1_7_R1.Block nmsBlock = getNmsBlock(type); if (nmsBlock == null) { return false; } @@ -281,11 +282,8 @@ public class DefaultNmsBlock extends NmsBlock { } } - public static net.minecraft.server.v1_6_R3.Block getNmsBlock(int type) { - if (type < 0 || type >= net.minecraft.server.v1_6_R3.Block.byId.length) { - return null; - } - return net.minecraft.server.v1_6_R3.Block.byId[type]; + public static net.minecraft.server.v1_7_R1.Block getNmsBlock(int type) { + return net.minecraft.server.v1_7_R1.Block.e(type); } /** @@ -295,19 +293,33 @@ public class DefaultNmsBlock extends NmsBlock { * @param foreign non-native NMS NBT structure * @return native WorldEdit NBT structure */ - @SuppressWarnings("unchecked") private static Tag toNative(NBTBase foreign) { + // temporary fix since mojang removed names from tags + // our nbt spec will need to be updated to theirs + return toNative(NBTBase.getTagName(foreign.getTypeId()), foreign); + } + + /** + * Converts from a non-native NMS NBT structure to a native WorldEdit NBT + * structure. + * + * @param foreign non-native NMS NBT structure + * @param name name for the tag, if it has one + * @return native WorldEdit NBT structure + */ + @SuppressWarnings("unchecked") + private static Tag toNative(String name, NBTBase foreign) { if (foreign == null) { return null; } if (foreign instanceof NBTTagCompound) { Map values = new HashMap(); - Collection foreignValues = null; + Collection foreignKeys = null; if (compoundMapField == null) { try { // Method name may change! - foreignValues = ((NBTTagCompound) foreign).c(); + foreignKeys = ((NBTTagCompound) foreign).c(); } catch (Throwable t) { try { logger.warning("WorldEdit: Couldn't get NBTTagCompound.c(), " + @@ -326,51 +338,49 @@ public class DefaultNmsBlock extends NmsBlock { if (compoundMapField != null) { try { - foreignValues = ((HashMap) compoundMapField.get(foreign)).values(); + foreignKeys = ((HashMap) compoundMapField.get(foreign)).keySet(); } catch (Throwable e) { // Can't do much beyond this throw new RuntimeException(e); } } - for (Object obj : foreignValues) { - NBTBase base = (NBTBase) obj; - values.put(base.getName(), toNative(base)); + for (Object obj : foreignKeys) { + String key = (String) obj; + NBTBase base = (NBTBase) ((NBTTagCompound) foreign).get(key); + values.put(key, toNative(key, base)); } - return new CompoundTag(foreign.getName(), values); + return new CompoundTag(name, values); } else if (foreign instanceof NBTTagByte) { - return new ByteTag(foreign.getName(), ((NBTTagByte) foreign).data); + return new ByteTag(name, ((NBTTagByte) foreign).f()); // getByte } else if (foreign instanceof NBTTagByteArray) { - return new ByteArrayTag(foreign.getName(), - ((NBTTagByteArray) foreign).data); + return new ByteArrayTag(name, + ((NBTTagByteArray) foreign).c()); // data } else if (foreign instanceof NBTTagDouble) { - return new DoubleTag(foreign.getName(), - ((NBTTagDouble) foreign).data); + return new DoubleTag(name, + ((NBTTagDouble) foreign).g()); // getDouble } else if (foreign instanceof NBTTagFloat) { - return new FloatTag(foreign.getName(), ((NBTTagFloat) foreign).data); + return new FloatTag(name, ((NBTTagFloat) foreign).h()); // getFloat } else if (foreign instanceof NBTTagInt) { - return new IntTag(foreign.getName(), ((NBTTagInt) foreign).data); + return new IntTag(name, ((NBTTagInt) foreign).d()); // getInt } else if (foreign instanceof NBTTagIntArray) { - return new IntArrayTag(foreign.getName(), - ((NBTTagIntArray) foreign).data); + return new IntArrayTag(name, + ((NBTTagIntArray) foreign).c()); // data } else if (foreign instanceof NBTTagList) { - List values = new ArrayList(); - NBTTagList foreignList = (NBTTagList) foreign; - int type = NBTConstants.TYPE_BYTE; - for (int i = 0; i < foreignList.size(); i++) { - NBTBase foreignTag = foreignList.get(i); - values.add(toNative(foreignTag)); - type = foreignTag.getTypeId(); - } - Class cls = NBTConstants.getClassFromType(type); - return new ListTag(foreign.getName(), cls, values); + try { + return transmorgifyList(name, (NBTTagList) foreign); + } catch (NoSuchFieldException e) { + } catch (SecurityException e) { + } catch (IllegalArgumentException e) { + } catch (IllegalAccessException e) {} + return new ListTag(name, ByteTag.class, new ArrayList()); } else if (foreign instanceof NBTTagLong) { - return new LongTag(foreign.getName(), ((NBTTagLong) foreign).data); + return new LongTag(name, ((NBTTagLong) foreign).c()); // getLong } else if (foreign instanceof NBTTagShort) { - return new ShortTag(foreign.getName(), ((NBTTagShort) foreign).data); + return new ShortTag(name, ((NBTTagShort) foreign).e()); // getShort } else if (foreign instanceof NBTTagString) { - return new StringTag(foreign.getName(), - ((NBTTagString) foreign).data); + return new StringTag(name, + ((NBTTagString) foreign).a_()); // data } else if (foreign instanceof NBTTagEnd) { return new EndTag(); } else { @@ -379,6 +389,22 @@ public class DefaultNmsBlock extends NmsBlock { } } + private static ListTag transmorgifyList(String name, NBTTagList foreign) + throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + List values = new ArrayList(); + int type = foreign.d(); + Field listField = NBTTagList.class.getDeclaredField("list"); + listField.setAccessible(true); + List foreignList; + foreignList = (List) listField.get(foreign); + for (int i = 0; i < foreign.size(); i++) { + NBTBase element = (NBTBase) foreignList.get(i); + values.add(toNative(null, element)); // list elements shouldn't have names + } + Class cls = NBTConstants.getClassFromType(type); + return new ListTag(name, cls, values); + } + /** * Converts a WorldEdit-native NBT structure to a NMS structure. * @@ -390,48 +416,45 @@ public class DefaultNmsBlock extends NmsBlock { return null; } if (foreign instanceof CompoundTag) { - NBTTagCompound tag = new NBTTagCompound(foreign.getName()); + NBTTagCompound tag = new NBTTagCompound(); for (Map.Entry entry : ((CompoundTag) foreign) .getValue().entrySet()) { tag.set(entry.getKey(), fromNative(entry.getValue())); } return tag; } else if (foreign instanceof ByteTag) { - return new NBTTagByte(foreign.getName(), - ((ByteTag) foreign).getValue()); + return new NBTTagByte(((ByteTag) foreign).getValue()); } else if (foreign instanceof ByteArrayTag) { - return new NBTTagByteArray(foreign.getName(), - ((ByteArrayTag) foreign).getValue()); + return new NBTTagByteArray(((ByteArrayTag) foreign).getValue()); } else if (foreign instanceof DoubleTag) { - return new NBTTagDouble(foreign.getName(), - ((DoubleTag) foreign).getValue()); + return new NBTTagDouble(((DoubleTag) foreign).getValue()); } else if (foreign instanceof FloatTag) { - return new NBTTagFloat(foreign.getName(), - ((FloatTag) foreign).getValue()); + return new NBTTagFloat(((FloatTag) foreign).getValue()); } else if (foreign instanceof IntTag) { - return new NBTTagInt(foreign.getName(), - ((IntTag) foreign).getValue()); + return new NBTTagInt(((IntTag) foreign).getValue()); } else if (foreign instanceof IntArrayTag) { - return new NBTTagIntArray(foreign.getName(), - ((IntArrayTag) foreign).getValue()); + return new NBTTagIntArray(((IntArrayTag) foreign).getValue()); } else if (foreign instanceof ListTag) { - NBTTagList tag = new NBTTagList(foreign.getName()); + NBTTagList tag = new NBTTagList(); ListTag foreignList = (ListTag) foreign; for (Tag t : foreignList.getValue()) { tag.add(fromNative(t)); } return tag; } else if (foreign instanceof LongTag) { - return new NBTTagLong(foreign.getName(), - ((LongTag) foreign).getValue()); + return new NBTTagLong(((LongTag) foreign).getValue()); } else if (foreign instanceof ShortTag) { - return new NBTTagShort(foreign.getName(), - ((ShortTag) foreign).getValue()); + return new NBTTagShort(((ShortTag) foreign).getValue()); } else if (foreign instanceof StringTag) { - return new NBTTagString(foreign.getName(), - ((StringTag) foreign).getValue()); + return new NBTTagString(((StringTag) foreign).getValue()); } else if (foreign instanceof EndTag) { - return new NBTTagEnd(); + try { + Method tagMaker = NBTBase.class.getDeclaredMethod("createTag", byte.class); + tagMaker.setAccessible(true); + return (NBTBase) tagMaker.invoke(null, (byte) 0); + } catch (Exception e) { + return null; + } } else { throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName()); @@ -439,7 +462,7 @@ public class DefaultNmsBlock extends NmsBlock { } public static boolean isValidBlockType(int type) throws NoClassDefFoundError { - return type == 0 || (type >= 1 && type < net.minecraft.server.v1_6_R3.Block.byId.length - && net.minecraft.server.v1_6_R3.Block.byId[type] != null); + return type == 0 || (type >= 1 && net.minecraft.server.v1_7_R1.Block.e(type) != null); } + } diff --git a/src/main/resources/nmsblocks/CBXNmsBlock_164.class b/src/main/resources/nmsblocks/CBXNmsBlock_164.class new file mode 100644 index 0000000000000000000000000000000000000000..7520a85a14b996e82a55764fdb0746fd98843170 GIT binary patch literal 12590 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