@Override public void simulateBlockMine(Vector pt) { BaseBlock block = getLazyBlock(pt); BaseItemStack stack = BlockType.getBlockDrop(block.getId(), (short) block.getData()); if (stack != null) { final int amount = stack.getAmount(); if (amount > 1) { dropItem(pt, new BaseItemStack(stack.getType(), 1, stack.getData()), amount); } else { dropItem(pt, stack, amount); } } try { setBlock(pt, new BaseBlock(BlockID.AIR)); } catch (WorldEditException e) { throw new RuntimeException(e); } }
@SuppressWarnings({"deprecation"}) @Override public MaterialAndData getBlock(Vector v) { int x = v.getBlockX() + center.getBlockX(); int y = v.getBlockY() + center.getBlockY(); int z = v.getBlockZ() + center.getBlockZ(); try { if (x < 0 || x >= size.getBlockZ() || y < 0 || y >= size.getBlockY() || z < 0 || z >= size.getBlockZ()) { return null; } com.sk89q.worldedit.Vector vector = new com.sk89q.worldedit.Vector(x, y, z); BaseBlock baseBlock = weSchematic.getBlock(vector); Material material = Material.getMaterial(baseBlock.getId()); int materialData = baseBlock.getData(); MaterialAndData blockData = new MaterialAndData(material, (byte) materialData); // Note.. we don't actually get a SignBlock here, for some reason. // May have something to do with loading schematics not actually supporting sign // text, it doesn't work with //schematic and //paste, either. // It looks like //paste works in a dev build of WE, but it still doesn't give me the blocks // Looking at WE's code, it seems like the part that's needed is commented out... ?? if (material == Material.SIGN_POST || material == Material.WALL_SIGN) { try { if (baseBlock.hasNbtData()) { SignBlock signBlock = new SignBlock(material.getId(), materialData); CompoundTag nbtData = baseBlock.getNbtData(); signBlock.setNbtData(nbtData); blockData.setSignLines(signBlock.getText()); } } catch (Throwable ex) { ex.printStackTrace(); } } else if (material == Material.COMMAND) { try { if (baseBlock.hasNbtData()) { CompoundTag nbtRoot = baseBlock.getNbtData(); Map<String, Tag> rootValues = nbtRoot.getValue(); if (rootValues.containsKey("Command")) { Object commandValue = rootValues.get("Command").getValue(); blockData.setCommandLine((String) commandValue); } if (rootValues.containsKey("CustomName")) { Object nameValue = rootValues.get("CustomName").getValue(); blockData.setCustomName((String) nameValue); } } } catch (Throwable ex) { ex.printStackTrace(); } } else if (material == Material.CHEST) { try { if (baseBlock.hasNbtData()) { ChestBlock chestBlock = new ChestBlock(materialData); CompoundTag nbtRoot = baseBlock.getNbtData(); chestBlock.setNbtData(nbtRoot); BaseItemStack[] items = chestBlock.getItems(); if (items != null && items.length > 0) { ItemStack[] contents = new ItemStack[items.length]; for (int i = 0; i < items.length; i++) { if (items[i] != null) { Material itemMaterial = Material.getMaterial(items[i].getType()); // Bukkit.getLogger().info("Item from chest: " + itemMaterial + " at " + i + " / " // + contents.length); short itemData = items[i].getData(); int itemAmount = items[i].getAmount(); ItemStack newStack = new ItemStack(itemMaterial, itemAmount, itemData); Map<Integer, Integer> enchantments = items[i].getEnchantments(); if (enchantments != null && enchantments.size() > 0) { for (Entry<Integer, Integer> enchantment : enchantments.entrySet()) { try { Enchantment enchantmentType = Enchantment.getById(enchantment.getKey()); newStack.addEnchantment(enchantmentType, enchantment.getValue()); } catch (Exception ex) { // This seems to happen a lot .. like on potions especially. ex.printStackTrace(); } } } contents[i] = newStack; } } blockData.setInventoryContents(contents); } } } catch (Throwable ex) { ex.printStackTrace(); } } return blockData; } catch (ArrayIndexOutOfBoundsException ex) { // TODO: Figure out why this still happens, even with the size check } catch (Throwable ex) { ex.printStackTrace(); } return null; }
@Command( aliases = {"/set"}, usage = "[pattern]", desc = "Set all blocks within selection", min = 1, max = 1) @CommandPermissions("worldedit.region.set") @Logging(REGION) public void set( Player player, EditSession editSession, LocalSession session, @Selection Region selection, Pattern to) throws WorldEditException { if (selection instanceof CuboidRegion && editSession.hasFastMode() && to instanceof BlockPattern) { try { CuboidRegion cuboid = (CuboidRegion) selection; RegionWrapper current = new RegionWrapper(cuboid.getMinimumPoint(), cuboid.getMaximumPoint()); BaseBlock block = ((BlockPattern) to).getBlock(); final FaweQueue queue = editSession.getQueue(); final int minY = cuboid.getMinimumY(); final int maxY = cuboid.getMaximumY(); final int id = block.getId(); final byte data = (byte) block.getData(); final FaweChunk<?> fc = queue.getFaweChunk(0, 0); fc.fillCuboid(0, 15, minY, maxY, 0, 15, id, data); fc.optimize(); int bcx = (current.minX) >> 4; int bcz = (current.minZ) >> 4; int tcx = (current.maxX) >> 4; int tcz = (current.maxZ) >> 4; // [chunkx, chunkz, pos1x, pos1z, pos2x, pos2z, isedge] MainUtil.chunkTaskSync( current, new RunnableVal<int[]>() { @Override public void run(int[] value) { FaweChunk newChunk; if (value[6] == 0) { newChunk = fc.copy(true); newChunk.setLoc(queue, value[0], value[1]); } else { int bx = value[2] & 15; int tx = value[4] & 15; int bz = value[3] & 15; int tz = value[5] & 15; if (bx == 0 && tx == 15 && bz == 0 && tz == 15) { newChunk = fc.copy(true); newChunk.setLoc(queue, value[0], value[1]); } else { newChunk = queue.getFaweChunk(value[0], value[1]); newChunk.fillCuboid( value[2] & 15, value[4] & 15, minY, maxY, value[3] & 15, value[5] & 15, id, data); } } newChunk.addToQueue(); } }); queue.enqueue(); long start = System.currentTimeMillis(); BBC.OPERATION.send(player, BBC.VISITOR_BLOCK.format(cuboid.getArea())); queue.flush(); BBC.ACTION_COMPLETE.send(player, (System.currentTimeMillis() - start) / 1000d); return; } catch (Throwable e) { MainUtil.handleError(e); } } int affected = editSession.setBlocks(selection, Patterns.wrap(to)); BBC.OPERATION.send(player, affected); }
@Override public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException { int id = block.getType(); switch (id) { case 54: case 130: case 142: case 27: case 137: case 52: case 154: case 84: case 25: case 144: case 138: case 176: case 177: case 63: case 68: case 323: case 117: case 116: case 28: case 66: case 157: case 61: case 62: case 140: case 146: case 149: case 150: case 158: case 23: case 123: case 124: case 29: case 33: case 151: case 178: { if (this.BSblocked) { return false; } this.BScount++; if (this.BScount > Settings.CHUNK_PROCESSOR_MAX_BLOCKSTATES) { this.BSblocked = true; PS.debug( "&cPlotSquared detected unsafe WorldEdit: " + location.getBlockX() + "," + location.getBlockZ()); } if (WEManager.maskContains( this.mask, location.getBlockX(), location.getBlockY(), location.getBlockZ())) { if (this.count++ > this.max) { if (this.parent != null) { try { Field field = AbstractDelegateExtent.class.getDeclaredField("extent"); field.setAccessible(true); field.set(this.parent, new com.sk89q.worldedit.extent.NullExtent()); } catch (Exception e) { e.printStackTrace(); } this.parent = null; } return false; } return super.setBlock(location, block); } break; } default: { int x = location.getBlockX(); int y = location.getBlockY(); int z = location.getBlockZ(); if (WEManager.maskContains( this.mask, location.getBlockX(), location.getBlockY(), location.getBlockZ())) { if (this.count++ > this.max) { if (this.parent != null) { try { Field field = AbstractDelegateExtent.class.getDeclaredField("extent"); field.setAccessible(true); field.set(this.parent, new com.sk89q.worldedit.extent.NullExtent()); } catch (Exception e) { e.printStackTrace(); } this.parent = null; } return false; } switch (id) { case 0: case 2: case 4: case 13: case 14: case 15: case 20: case 21: case 22: case 24: case 25: case 30: case 32: case 37: case 39: case 40: case 41: case 42: case 45: case 46: case 47: case 48: case 49: case 51: case 52: case 54: case 55: case 56: case 57: case 58: case 60: case 61: case 62: case 7: case 8: case 9: case 10: case 11: case 73: case 74: case 78: case 79: case 80: case 81: case 82: case 83: case 84: case 85: case 87: case 88: case 101: case 102: case 103: case 110: case 112: case 113: case 117: case 121: case 122: case 123: case 124: case 129: case 133: case 138: case 137: case 140: case 165: case 166: case 169: case 170: case 172: case 173: case 174: case 176: case 177: case 181: case 182: case 188: case 189: case 190: case 191: case 192: { if (Settings.EXPERIMENTAL_FAST_ASYNC_WORLDEDIT) { SetQueue.IMP.setBlock(this.world, x, y, z, id); } else { super.setBlock(location, block); } break; } default: { if (Settings.EXPERIMENTAL_FAST_ASYNC_WORLDEDIT) { SetQueue.IMP.setBlock( this.world, x, y, z, new PlotBlock((short) id, (byte) block.getData())); } else { super.setBlock(location, block); } break; } } return true; } } } return false; }
@Override public void save(CuboidClipboard clipboard, File file) throws IOException, DataException { int width = clipboard.getWidth(); int height = clipboard.getHeight(); int length = clipboard.getLength(); if (width > MAX_SIZE) { throw new DataException("Width of region too large for a .schematic"); } if (height > MAX_SIZE) { throw new DataException("Height of region too large for a .schematic"); } if (length > MAX_SIZE) { throw new DataException("Length of region too large for a .schematic"); } HashMap<String, Tag> schematic = new HashMap<String, Tag>(); schematic.put("Width", new ShortTag((short) width)); schematic.put("Length", new ShortTag((short) length)); schematic.put("Height", new ShortTag((short) height)); schematic.put("Materials", new StringTag("Alpha")); schematic.put("WEOriginX", new IntTag(clipboard.getOrigin().getBlockX())); schematic.put("WEOriginY", new IntTag(clipboard.getOrigin().getBlockY())); schematic.put("WEOriginZ", new IntTag(clipboard.getOrigin().getBlockZ())); schematic.put("WEOffsetX", new IntTag(clipboard.getOffset().getBlockX())); schematic.put("WEOffsetY", new IntTag(clipboard.getOffset().getBlockY())); schematic.put("WEOffsetZ", new IntTag(clipboard.getOffset().getBlockZ())); // Copy byte[] blocks = new byte[width * height * length]; byte[] addBlocks = null; byte[] blockData = new byte[width * height * length]; ArrayList<Tag> tileEntities = new ArrayList<Tag>(); for (int x = 0; x < width; ++x) { for (int y = 0; y < height; ++y) { for (int z = 0; z < length; ++z) { int index = y * width * length + z * width + x; BaseBlock block = clipboard.getPoint(new BlockVector(x, y, z)); // Save 4096 IDs in an AddBlocks section if (block.getType() > 255) { if (addBlocks == null) { // Lazily create section addBlocks = new byte[(blocks.length >> 1) + 1]; } addBlocks[index >> 1] = (byte) (((index & 1) == 0) ? addBlocks[index >> 1] & 0xF0 | (block.getType() >> 8) & 0xF : addBlocks[index >> 1] & 0xF | ((block.getType() >> 8) & 0xF) << 4); } blocks[index] = (byte) block.getType(); blockData[index] = (byte) block.getData(); // Get the list of key/values from the block CompoundTag rawTag = block.getNbtData(); if (rawTag != null) { Map<String, Tag> values = new HashMap<String, Tag>(); for (Entry<String, Tag> entry : rawTag.getValue().entrySet()) { values.put(entry.getKey(), entry.getValue()); } values.put("id", new StringTag(block.getNbtId())); values.put("x", new IntTag(x)); values.put("y", new IntTag(y)); values.put("z", new IntTag(z)); CompoundTag tileEntityTag = new CompoundTag(values); tileEntities.add(tileEntityTag); } } } } schematic.put("Blocks", new ByteArrayTag(blocks)); schematic.put("Data", new ByteArrayTag(blockData)); schematic.put("Entities", new ListTag(CompoundTag.class, new ArrayList<Tag>())); schematic.put("TileEntities", new ListTag(CompoundTag.class, tileEntities)); if (addBlocks != null) { schematic.put("AddBlocks", new ByteArrayTag(addBlocks)); } // Build and output CompoundTag schematicTag = new CompoundTag(schematic); NBTOutputStream stream = new NBTOutputStream(new GZIPOutputStream(new FileOutputStream(file))); stream.writeNamedTag("Schematic", schematicTag); stream.close(); }