Пример #1
0
  @Command(
      aliases = {"/copy"},
      flags = "e",
      desc = "Копирует выделенную территорию в буфер обмена",
      help =
          "Копирует выделенную территорию в буфер обмен\n"
              + "Флаги:\n"
              + "  -e определяет, будут ли объекты копироваться в буфер обмена\n"
              + "ПРЕДУПРЕЖДЕНИЕ: Вставленные объекты не могут быть отменены!",
      min = 0,
      max = 0)
  @CommandPermissions("worldedit.clipboard.copy")
  public void copy(
      CommandContext args, LocalSession session, LocalPlayer player, EditSession editSession)
      throws WorldEditException {

    Region region = session.getSelection(player.getWorld());
    Vector min = region.getMinimumPoint();
    Vector max = region.getMaximumPoint();
    Vector pos = session.getPlacementPosition(player);

    CuboidClipboard clipboard =
        new CuboidClipboard(max.subtract(min).add(new Vector(1, 1, 1)), min, min.subtract(pos));
    clipboard.copy(editSession);
    if (args.hasFlag('e')) {
      for (LocalEntity entity : player.getWorld().getEntities(region)) {
        clipboard.storeEntity(entity);
      }
    }
    session.setClipboard(clipboard);

    player.print("Блок(и) скопирован(ы).");
  }
Пример #2
0
  @Command(
      aliases = {"/cut"},
      usage = "[leave-id]",
      desc = "Вырезает выделенную территорию в буфер обмена",
      help =
          "Вырезает выделенную территорию в буфер обмена\n"
              + "Флаги:\n"
              + "  -e controls определяет, будут ли объекты копироваться в буфер обмена\n"
              + "ПРЕДУПРЕЖДЕНИЕ: Вырезанные и вставленные объекты не могут быть отменены!",
      flags = "e",
      min = 0,
      max = 1)
  @CommandPermissions("worldedit.clipboard.cut")
  @Logging(REGION)
  public void cut(
      CommandContext args, LocalSession session, LocalPlayer player, EditSession editSession)
      throws WorldEditException {

    BaseBlock block = new BaseBlock(BlockID.AIR);
    LocalWorld world = player.getWorld();

    if (args.argsLength() > 0) {
      block = we.getBlock(player, args.getString(0));
    }

    Region region = session.getSelection(world);
    Vector min = region.getMinimumPoint();
    Vector max = region.getMaximumPoint();
    Vector pos = session.getPlacementPosition(player);

    CuboidClipboard clipboard =
        new CuboidClipboard(max.subtract(min).add(new Vector(1, 1, 1)), min, min.subtract(pos));
    clipboard.copy(editSession);
    if (args.hasFlag('e')) {
      LocalEntity[] entities = world.getEntities(region);
      for (LocalEntity entity : entities) {
        clipboard.storeEntity(entity);
      }
      world.killEntities(entities);
    }
    session.setClipboard(clipboard);

    int affected = editSession.setBlocks(session.getSelection(world), block);
    player.print(
        affected
            + " "
            + StringUtil.plural(affected, "блок вырезан", "блока вырезано", "блоков вырезано")
            + ".");
  }
Пример #3
0
  @Command(
      aliases = {"/rotate"},
      usage = "<angle-in-degrees>",
      desc = "Поворот содержимого буфера обмена",
      min = 1,
      max = 1)
  @CommandPermissions("worldedit.clipboard.rotate")
  public void rotate(
      CommandContext args, LocalSession session, LocalPlayer player, EditSession editSession)
      throws WorldEditException {

    int angle = args.getInteger(0);

    if (angle % 90 == 0) {
      CuboidClipboard clipboard = session.getClipboard();
      clipboard.rotate2D(angle);
      player.print("Содержимое буфера обмена повернуто на " + angle + " градусов.");
    } else {
      player.printError("Углы должны делиться на 90 градусов.");
    }
  }
Пример #4
0
  @Command(
      aliases = {"/flip"},
      usage = "[dir]",
      flags = "p",
      desc = "Переворачивает содержимое буфера обмена.",
      help =
          "Переворачивает содержимое буфера обмена.\n"
              + "Флаг -p переворачивает выделенную территорию вокруг игрока,\n"
              + "а не центра выделения.",
      min = 0,
      max = 1)
  @CommandPermissions("worldedit.clipboard.flip")
  public void flip(
      CommandContext args, LocalSession session, LocalPlayer player, EditSession editSession)
      throws WorldEditException {

    CuboidClipboard.FlipDirection dir =
        we.getFlipDirection(player, args.argsLength() > 0 ? args.getString(0).toLowerCase() : "me");

    CuboidClipboard clipboard = session.getClipboard();
    clipboard.flip(dir, args.hasFlag('p'));
    player.print("Содержимое буфера обмена перевернуто.");
  }
Пример #5
0
  public WorldEditSchematic(Object schematic) {
    weSchematic = (CuboidClipboard) schematic;

    // Center at the bottom X,Z center
    // This should be configurable, maybe?
    try {
      com.sk89q.worldedit.Vector weSize = weSchematic.getSize();
      size = new Vector(weSize.getBlockX(), weSize.getBlockY(), weSize.getBlockZ());
      center = new Vector(Math.floor(size.getBlockX() / 2), 0, Math.floor(size.getBlockZ() / 2));
    } catch (Exception ex) {
      ex.printStackTrace();
    }

    if (center == null) {
      center = new Vector(0, 0, 0);
    }

    if (size == null) {
      size = new Vector(0, 0, 0);
    }
  }
Пример #6
0
  @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;
  }
Пример #7
0
 @SuppressWarnings("deprecation")
 public Material getMaterialAt(int x, int y, int z) {
   return Material.getMaterial(
       clipboard.getBlock(new com.sk89q.worldedit.Vector(x, y, z)).getType());
 }
Пример #8
0
 public int getLength() {
   return clipboard.getLength();
 }
Пример #9
0
 public int getHeight() {
   return clipboard.getHeight();
 }
Пример #10
0
 public int getWidth() {
   return clipboard.getWidth();
 }
Пример #11
0
  public CuboidClipboard load(InputStream stream) throws IOException, DataException {
    NBTInputStream nbtStream = new NBTInputStream(new GZIPInputStream(stream));

    Vector origin = new Vector();
    Vector offset = new Vector();

    // Schematic tag
    NamedTag rootTag = nbtStream.readNamedTag();
    nbtStream.close();
    if (!rootTag.getName().equals("Schematic")) {
      throw new DataException("Tag \"Schematic\" does not exist or is not first");
    }

    CompoundTag schematicTag = (CompoundTag) rootTag.getTag();

    // Check
    Map<String, Tag> schematic = schematicTag.getValue();
    if (!schematic.containsKey("Blocks")) {
      throw new DataException("Schematic file is missing a \"Blocks\" tag");
    }

    // Get information
    short width = getChildTag(schematic, "Width", ShortTag.class).getValue();
    short length = getChildTag(schematic, "Length", ShortTag.class).getValue();
    short height = getChildTag(schematic, "Height", ShortTag.class).getValue();

    try {
      int originX = getChildTag(schematic, "WEOriginX", IntTag.class).getValue();
      int originY = getChildTag(schematic, "WEOriginY", IntTag.class).getValue();
      int originZ = getChildTag(schematic, "WEOriginZ", IntTag.class).getValue();
      origin = new Vector(originX, originY, originZ);
    } catch (DataException e) {
      // No origin data
    }

    try {
      int offsetX = getChildTag(schematic, "WEOffsetX", IntTag.class).getValue();
      int offsetY = getChildTag(schematic, "WEOffsetY", IntTag.class).getValue();
      int offsetZ = getChildTag(schematic, "WEOffsetZ", IntTag.class).getValue();
      offset = new Vector(offsetX, offsetY, offsetZ);
    } catch (DataException e) {
      // No offset data
    }

    // Check type of Schematic
    String materials = getChildTag(schematic, "Materials", StringTag.class).getValue();
    if (!materials.equals("Alpha")) {
      throw new DataException("Schematic file is not an Alpha schematic");
    }

    // Get blocks
    byte[] blockId = getChildTag(schematic, "Blocks", ByteArrayTag.class).getValue();
    byte[] blockData = getChildTag(schematic, "Data", ByteArrayTag.class).getValue();
    byte[] addId = new byte[0];
    short[] blocks = new short[blockId.length]; // Have to later combine IDs

    // We support 4096 block IDs using the same method as vanilla Minecraft, where
    // the highest 4 bits are stored in a separate byte array.
    if (schematic.containsKey("AddBlocks")) {
      addId = getChildTag(schematic, "AddBlocks", ByteArrayTag.class).getValue();
    }

    // Combine the AddBlocks data with the first 8-bit block ID
    for (int index = 0; index < blockId.length; index++) {
      if ((index >> 1) >= addId.length) { // No corresponding AddBlocks index
        blocks[index] = (short) (blockId[index] & 0xFF);
      } else {
        if ((index & 1) == 0) {
          blocks[index] = (short) (((addId[index >> 1] & 0x0F) << 8) + (blockId[index] & 0xFF));
        } else {
          blocks[index] = (short) (((addId[index >> 1] & 0xF0) << 4) + (blockId[index] & 0xFF));
        }
      }
    }

    // Need to pull out tile entities
    List<Tag> tileEntities = getChildTag(schematic, "TileEntities", ListTag.class).getValue();
    Map<BlockVector, Map<String, Tag>> tileEntitiesMap =
        new HashMap<BlockVector, Map<String, Tag>>();

    for (Tag tag : tileEntities) {
      if (!(tag instanceof CompoundTag)) continue;
      CompoundTag t = (CompoundTag) tag;

      int x = 0;
      int y = 0;
      int z = 0;

      Map<String, Tag> values = new HashMap<String, Tag>();

      for (Map.Entry<String, Tag> entry : t.getValue().entrySet()) {
        if (entry.getKey().equals("x")) {
          if (entry.getValue() instanceof IntTag) {
            x = ((IntTag) entry.getValue()).getValue();
          }
        } else if (entry.getKey().equals("y")) {
          if (entry.getValue() instanceof IntTag) {
            y = ((IntTag) entry.getValue()).getValue();
          }
        } else if (entry.getKey().equals("z")) {
          if (entry.getValue() instanceof IntTag) {
            z = ((IntTag) entry.getValue()).getValue();
          }
        }

        values.put(entry.getKey(), entry.getValue());
      }

      BlockVector vec = new BlockVector(x, y, z);
      tileEntitiesMap.put(vec, values);
    }

    Vector size = new Vector(width, height, length);
    CuboidClipboard clipboard = new CuboidClipboard(size);
    clipboard.setOrigin(origin);
    clipboard.setOffset(offset);

    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;
          BlockVector pt = new BlockVector(x, y, z);
          BaseBlock block = getBlockForId(blocks[index], blockData[index]);

          if (tileEntitiesMap.containsKey(pt)) {
            block.setNbtData(new CompoundTag(tileEntitiesMap.get(pt)));
          }
          clipboard.setBlock(pt, block);
        }
      }
    }

    return clipboard;
  }
Пример #12
0
  @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();
  }