From 19d7beaf39f0c015dbfc08b0c2038be806595ec0 Mon Sep 17 00:00:00 2001 From: Wizjany Date: Sun, 20 Jan 2013 00:58:23 -0500 Subject: [PATCH] Added NmsBlocks for MCPC+ running MC 1.4.7. Also fixed an issue with creative mode inventory usage not updating when gamemode changed. --- .../worldedit/bukkit/WorldEditListener.java | 11 +- .../nmsblocks/MCPCPlusXNmsBlock_147.class | Bin 0 -> 9277 bytes .../nmsblocks/MCPCPlusXNmsBlock_147.java | 415 ++++++++++++++++++ 3 files changed, 425 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/nmsblocks/MCPCPlusXNmsBlock_147.class create mode 100644 src/main/resources/nmsblocks/MCPCPlusXNmsBlock_147.java diff --git a/src/main/java/com/sk89q/worldedit/bukkit/WorldEditListener.java b/src/main/java/com/sk89q/worldedit/bukkit/WorldEditListener.java index b00c733dc..4b1dccb8a 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/WorldEditListener.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/WorldEditListener.java @@ -20,7 +20,6 @@ package com.sk89q.worldedit.bukkit; -import com.sk89q.util.StringUtil; import org.bukkit.Bukkit; import org.bukkit.block.Block; import org.bukkit.event.Event.Result; @@ -29,8 +28,11 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerGameModeChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerQuitEvent; + +import com.sk89q.util.StringUtil; import com.sk89q.worldedit.LocalPlayer; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.WorldEdit; @@ -69,6 +71,12 @@ public class WorldEditListener implements Listener { plugin.getWorldEdit().markExpire(plugin.wrapPlayer(event.getPlayer())); } + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onGamemode(PlayerGameModeChangeEvent event) { + // this will automatically refresh their sesssion, we don't have to do anything + WorldEdit.getInstance().getSession(plugin.wrapPlayer(event.getPlayer())); + } + /** * Called when a player attempts to use a command * @@ -129,6 +137,7 @@ public class WorldEditListener implements Listener { if (!ignoreLeftClickAir) { final int taskId = Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { + @Override public void run() { ignoreLeftClickAir = false; } diff --git a/src/main/resources/nmsblocks/MCPCPlusXNmsBlock_147.class b/src/main/resources/nmsblocks/MCPCPlusXNmsBlock_147.class new file mode 100644 index 0000000000000000000000000000000000000000..ba55cda21be7905e0c3da10402dfba719d772300 GIT binary patch literal 9277 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 BYNG%E literal 0 HcmV?d00001 diff --git a/src/main/resources/nmsblocks/MCPCPlusXNmsBlock_147.java b/src/main/resources/nmsblocks/MCPCPlusXNmsBlock_147.java new file mode 100644 index 000000000..839c8572d --- /dev/null +++ b/src/main/resources/nmsblocks/MCPCPlusXNmsBlock_147.java @@ -0,0 +1,415 @@ +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; + +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_4_R1.CraftWorld; + +import com.sk89q.jnbt.ByteArrayTag; +import com.sk89q.jnbt.ByteTag; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.DoubleTag; +import com.sk89q.jnbt.EndTag; +import com.sk89q.jnbt.FloatTag; +import com.sk89q.jnbt.IntArrayTag; +import com.sk89q.jnbt.IntTag; +import com.sk89q.jnbt.ListTag; +import com.sk89q.jnbt.LongTag; +import com.sk89q.jnbt.NBTConstants; +import com.sk89q.jnbt.ShortTag; +import com.sk89q.jnbt.StringTag; +import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.TileEntityBlock; +import com.sk89q.worldedit.bukkit.BukkitWorld; +import com.sk89q.worldedit.bukkit.NmsBlock; +import com.sk89q.worldedit.data.DataException; +import com.sk89q.worldedit.foundation.Block; + +/** + * Remapping tools are broken atm. + */ +public class MCPCPlusXNmsBlock_147 extends NmsBlock { + + private static final Logger logger = WorldEdit.logger; + private static Field compoundMapField; + private static final Field nmsBlock_isTileEntityField; // The field is deobfuscated but the method isn't. No idea why. + private bq nbtData = null; + + static { + Field field; + try { + field = amq.class.getDeclaredField("cs"); + field.setAccessible(true); + } catch (NoSuchFieldException e) { + // logger.severe("Could not find NMS block tile entity field!"); + field = null; + } + nmsBlock_isTileEntityField = field; + } + + public static boolean verify() { + try { + Class.forName("org.bukkit.craftbukkit.v1_4_R1.CraftWorld"); + } catch (Throwable e) { + return false; + } + return nmsBlock_isTileEntityField != null; + } + + /** + * Create a new instance with a given type ID, data value, and previous + * {@link TileEntityBlock}-implementing object. + * + * @param type block type ID + * @param data data value + * @param tileEntityBlock tile entity block + */ + public MCPCPlusXNmsBlock_147(int type, int data, TileEntityBlock tileEntityBlock) { + super(type, data); + + nbtData = (bq) fromNative(tileEntityBlock.getNbtData()); + } + + /** + * Create a new instance with a given type ID, data value, and raw + * {@link bq} copy. + * + * @param type block type ID + * @param data data value + * @param nbtData raw NBT data + */ + public MCPCPlusXNmsBlock_147(int type, int data, bq nbtData) { + super(type, data); + + this.nbtData = nbtData; + } + + /** + * Build a {@link bq} that has valid coordinates. + * + * @param pt coordinates to set + * @return the tag compound + */ + private bq getNmsData(Vector pt) { + if (nbtData == null) { + return null; + } + + nbtData.a("x", new bx("x", pt.getBlockX())); + nbtData.a("y", new bx("y", pt.getBlockY())); + nbtData.a("z", new bx("z", pt.getBlockZ())); + + return nbtData; + } + + @Override + public boolean hasNbtData() { + return nbtData != null; + } + + @Override + public String getNbtId() { + if (nbtData == null) { + return ""; + } + + return nbtData.i("id"); + } + + @Override + public CompoundTag getNbtData() { + if (nbtData == null) { + return new CompoundTag(getNbtId(), + new HashMap()); + } + return (CompoundTag) toNative(nbtData); + } + + @Override + public void setNbtData(CompoundTag tag) throws DataException { + if (tag == null) { + this.nbtData = null; + } + this.nbtData = (bq) fromNative(tag); + } + + /** + * Build an instance from the given information. + * + * @param world world to get the block from + * @param position position to get the block at + * @param type type ID of block + * @param data data value of block + * @return the block, or null + */ + public static MCPCPlusXNmsBlock_147 get(World world, Vector position, int type, int data) { + if (!hasTileEntity(type)) { + return null; + } + + any te = ((CraftWorld) world).getHandle().q(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + + if (te != null) { + bq tag = new bq(); + te.b(tag); // Load data + return new MCPCPlusXNmsBlock_147(type, data, tag); + } + + return null; + } + + /** + * Set an instance or a {@link TileEntityBlock} to the given position. + * + * @param world world to set the block in + * @param position position to set the block at + * @param block the block to set + * @return true if tile entity data was copied to the world + */ + public static boolean set(World world, Vector position, BaseBlock block) { + bq data = null; + if (!hasTileEntity(world.getBlockTypeIdAt(position.getBlockX(), position.getBlockY(), position.getBlockZ()))) { + return false; + } + + if (block instanceof MCPCPlusXNmsBlock_147) { + MCPCPlusXNmsBlock_147 nmsProxyBlock = (MCPCPlusXNmsBlock_147) block; + data = nmsProxyBlock.getNmsData(position); + } else if (block instanceof TileEntityBlock) { + MCPCPlusXNmsBlock_147 nmsProxyBlock = new MCPCPlusXNmsBlock_147( + block.getId(), block.getData(), block); + data = nmsProxyBlock.getNmsData(position); + } + + if (data != null) { + any te = ((CraftWorld) world).getHandle().q( + position.getBlockX(), position.getBlockY(), position.getBlockZ()); + if (te != null) { + te.a(data); // Load data + return true; + } + } + + return false; + } + + /** + * Tries to set a block 'safely', as in setting the block data to the location, and + * then triggering physics only at the end. + * + * @param world world to set the block in + * @param position position to set the block at + * @param block the block to set + * @param notifyAdjacent true to notify physics and what not + * @return true if block id or data was changed + */ + public static boolean setSafely(BukkitWorld world, Vector position, + Block block, boolean notifyAdjacent) { + + int x = position.getBlockX(); + int y = position.getBlockY(); + int z = position.getBlockZ(); + + CraftWorld craftWorld = ((CraftWorld) world.getWorld()); +// TileEntity te = craftWorld.getHandle().getTileEntity(x, y, z); +// craftWorld.getHandle().tileEntityList.remove(te); + + boolean changed = craftWorld.getHandle().c(x, y, z, block.getId(), block.getData()); + + if (block instanceof BaseBlock) { + world.copyToWorld(position, (BaseBlock) block); + } + + if (changed) { + if (notifyAdjacent) { + craftWorld.getHandle().f(x, y, z, block.getId()); + } else { + craftWorld.getHandle().i(x, y, z); + } + } + + return changed; + } + + public static boolean hasTileEntity(int type) { + amq nmsBlock = getNmsBlock(type); + if (nmsBlock == null) { + return false; + } + + try { + return nmsBlock_isTileEntityField.getBoolean(nmsBlock); // Once we have the field stord, gets are fast + } catch (IllegalAccessException e) { + return false; + } + } + + public static amq getNmsBlock(int type) { + if (type < 0 || type >= amq.p.length) { + return null; + } + return amq.p[type]; + } + + /** + * Converts from a non-native NMS NBT structure to a native WorldEdit NBT + * structure. + * + * @param foreign non-native NMS NBT structure + * @return native WorldEdit NBT structure + */ + @SuppressWarnings("unchecked") + private static Tag toNative(cd foreign) { + if (foreign == null) { + return null; + } + if (foreign instanceof bq) { + Map values = new HashMap(); + Collection foreignValues = null; + + if (compoundMapField == null) { + try { + // Method name may change! + foreignValues = ((bq) foreign).c(); + } catch (Throwable t) { + try { + logger.warning("WorldEdit: Couldn't get bq.c(), " + + "so we're going to try to get at the 'map' field directly from now on"); + + if (compoundMapField == null) { + compoundMapField = bq.class.getDeclaredField("map"); + compoundMapField.setAccessible(true); + } + } catch (Throwable e) { + // Can't do much beyond this + throw new RuntimeException(e); + } + } + } + + if (compoundMapField != null) { + try { + foreignValues = ((HashMap) compoundMapField.get(foreign)).values(); + } catch (Throwable e) { + // Can't do much beyond this + throw new RuntimeException(e); + } + } + + for (Object obj : foreignValues) { + cd base = (cd) obj; + values.put(base.e(), toNative(base)); + } + return new CompoundTag(foreign.e(), values); + } else if (foreign instanceof bp) { + return new ByteTag(foreign.e(), ((bp) foreign).a); + } else if (foreign instanceof bo) { + return new ByteArrayTag(foreign.e(), + ((bo) foreign).a); + } else if (foreign instanceof bt) { + return new DoubleTag(foreign.e(), + ((bt) foreign).a); + } else if (foreign instanceof bv) { + return new FloatTag(foreign.e(), ((bv) foreign).a); + } else if (foreign instanceof bx) { + return new IntTag(foreign.e(), ((bx) foreign).a); + } else if (foreign instanceof bw) { + return new IntArrayTag(foreign.e(), + ((bw) foreign).a); + } else if (foreign instanceof by) { + List values = new ArrayList(); + by foreignList = (by) foreign; + int type = NBTConstants.TYPE_BYTE; + for (int i = 0; i < foreignList.c(); i++) { + cd foreignTag = foreignList.b(i); + values.add(toNative(foreignTag)); + type = foreignTag.a(); + } + Class cls = NBTConstants.getClassFromType(type); + return new ListTag(foreign.e(), cls, values); + } else if (foreign instanceof bz) { + return new LongTag(foreign.e(), ((bz) foreign).a); + } else if (foreign instanceof cb) { + return new ShortTag(foreign.e(), ((cb) foreign).a); + } else if (foreign instanceof cc) { + return new StringTag(foreign.e(), + ((cc) foreign).a); + } else if (foreign instanceof bu) { + return new EndTag(); + } else { + throw new IllegalArgumentException("Don't know how to make native " + + foreign.getClass().getCanonicalName()); + } + } + + /** + * Converts a WorldEdit-native NBT structure to a NMS structure. + * + * @param foreign structure to convert + * @return non-native structure + */ + private static cd fromNative(Tag foreign) { + if (foreign == null) { + return null; + } + if (foreign instanceof CompoundTag) { + bq tag = new bq(foreign.getName()); + for (Map.Entry entry : ((CompoundTag) foreign) + .getValue().entrySet()) { + tag.a(entry.getKey(), fromNative(entry.getValue())); + } + return tag; + } else if (foreign instanceof ByteTag) { + return new bp(foreign.getName(), + ((ByteTag) foreign).getValue()); + } else if (foreign instanceof ByteArrayTag) { + return new bo(foreign.getName(), + ((ByteArrayTag) foreign).getValue()); + } else if (foreign instanceof DoubleTag) { + return new bt(foreign.getName(), + ((DoubleTag) foreign).getValue()); + } else if (foreign instanceof FloatTag) { + return new bv(foreign.getName(), + ((FloatTag) foreign).getValue()); + } else if (foreign instanceof IntTag) { + return new bx(foreign.getName(), + ((IntTag) foreign).getValue()); + } else if (foreign instanceof IntArrayTag) { + return new bw(foreign.getName(), + ((IntArrayTag) foreign).getValue()); + } else if (foreign instanceof ListTag) { + by tag = new by(foreign.getName()); + ListTag foreignList = (ListTag) foreign; + for (Tag t : foreignList.getValue()) { + tag.a(fromNative(t)); + } + return tag; + } else if (foreign instanceof LongTag) { + return new bz(foreign.getName(), + ((LongTag) foreign).getValue()); + } else if (foreign instanceof ShortTag) { + return new cb(foreign.getName(), + ((ShortTag) foreign).getValue()); + } else if (foreign instanceof StringTag) { + return new cc(foreign.getName(), + ((StringTag) foreign).getValue()); + } else if (foreign instanceof EndTag) { + return new bu(); + } else { + throw new IllegalArgumentException("Don't know how to make NMS " + + foreign.getClass().getCanonicalName()); + } + } + + public static boolean isValidBlockType(int type) throws NoClassDefFoundError { + return type == 0 || (type >= 1 && type < amq.p.length + && amq.p[type] != null); + } +}