package net.minecraft.command; import com.google.common.base.Predicate; import com.google.common.collect.Lists; import java.util.Collections; import java.util.Deque; import java.util.List; import javax.annotation.Nullable; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.inventory.IInventory; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.server.MinecraftServer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.world.NextTickListEntry; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; public class CommandClone extends CommandBase { /** * Gets the name of the command */ public String getName() { return "clone"; } /** * Return the required permission level for this command. */ public int getRequiredPermissionLevel() { return 2; } /** * Gets the usage string for the command. */ public String getUsage(ICommandSender sender) { return "commands.clone.usage"; } /** * Callback for when the command is executed */ public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { if (args.length < 9) { throw new WrongUsageException("commands.clone.usage", new Object[0]); } else { sender.setCommandStat(CommandResultStats.Type.AFFECTED_BLOCKS, 0); BlockPos blockpos = parseBlockPos(sender, args, 0, false); BlockPos blockpos1 = parseBlockPos(sender, args, 3, false); BlockPos blockpos2 = parseBlockPos(sender, args, 6, false); StructureBoundingBox structureboundingbox = new StructureBoundingBox(blockpos, blockpos1); StructureBoundingBox structureboundingbox1 = new StructureBoundingBox(blockpos2, blockpos2.add(structureboundingbox.getLength())); int i = structureboundingbox.getXSize() * structureboundingbox.getYSize() * structureboundingbox.getZSize(); if (i > 32768) { throw new CommandException("commands.clone.tooManyBlocks", new Object[] {i, Integer.valueOf(32768)}); } else { boolean flag = false; Block block = null; Predicate predicate = null; if ((args.length < 11 || !"force".equals(args[10]) && !"move".equals(args[10])) && structureboundingbox.intersectsWith(structureboundingbox1)) { throw new CommandException("commands.clone.noOverlap", new Object[0]); } else { if (args.length >= 11 && "move".equals(args[10])) { flag = true; } if (structureboundingbox.minY >= 0 && structureboundingbox.maxY < 256 && structureboundingbox1.minY >= 0 && structureboundingbox1.maxY < 256) { World world = sender.getEntityWorld(); if (world.isAreaLoaded(structureboundingbox) && world.isAreaLoaded(structureboundingbox1)) { boolean flag1 = false; if (args.length >= 10) { if ("masked".equals(args[9])) { flag1 = true; } else if ("filtered".equals(args[9])) { if (args.length < 12) { throw new WrongUsageException("commands.clone.usage", new Object[0]); } block = getBlockByText(sender, args[11]); if (args.length >= 13) { predicate = convertArgToBlockStatePredicate(block, args[12]); } } } List list = Lists.newArrayList(); List list1 = Lists.newArrayList(); List list2 = Lists.newArrayList(); Deque deque = Lists.newLinkedList(); BlockPos blockpos3 = new BlockPos(structureboundingbox1.minX - structureboundingbox.minX, structureboundingbox1.minY - structureboundingbox.minY, structureboundingbox1.minZ - structureboundingbox.minZ); for (int j = structureboundingbox.minZ; j <= structureboundingbox.maxZ; ++j) { for (int k = structureboundingbox.minY; k <= structureboundingbox.maxY; ++k) { for (int l = structureboundingbox.minX; l <= structureboundingbox.maxX; ++l) { BlockPos blockpos4 = new BlockPos(l, k, j); BlockPos blockpos5 = blockpos4.add(blockpos3); IBlockState iblockstate = world.getBlockState(blockpos4); if ((!flag1 || iblockstate.getBlock() != Blocks.AIR) && (block == null || iblockstate.getBlock() == block && (predicate == null || predicate.apply(iblockstate)))) { TileEntity tileentity = world.getTileEntity(blockpos4); if (tileentity != null) { NBTTagCompound nbttagcompound = tileentity.writeToNBT(new NBTTagCompound()); list1.add(new CommandClone.StaticCloneData(blockpos5, iblockstate, nbttagcompound)); deque.addLast(blockpos4); } else if (!iblockstate.isFullBlock() && !iblockstate.isFullCube()) { list2.add(new CommandClone.StaticCloneData(blockpos5, iblockstate, (NBTTagCompound)null)); deque.addFirst(blockpos4); } else { list.add(new CommandClone.StaticCloneData(blockpos5, iblockstate, (NBTTagCompound)null)); deque.addLast(blockpos4); } } } } } if (flag) { for (BlockPos blockpos6 : deque) { TileEntity tileentity1 = world.getTileEntity(blockpos6); if (tileentity1 instanceof IInventory) { ((IInventory)tileentity1).clear(); } world.setBlockState(blockpos6, Blocks.BARRIER.getDefaultState(), 2); } for (BlockPos blockpos7 : deque) { world.setBlockState(blockpos7, Blocks.AIR.getDefaultState(), 3); } } List list3 = Lists.newArrayList(); list3.addAll(list); list3.addAll(list1); list3.addAll(list2); List list4 = Lists.reverse(list3); for (CommandClone.StaticCloneData commandclone$staticclonedata : list4) { TileEntity tileentity2 = world.getTileEntity(commandclone$staticclonedata.pos); if (tileentity2 instanceof IInventory) { ((IInventory)tileentity2).clear(); } world.setBlockState(commandclone$staticclonedata.pos, Blocks.BARRIER.getDefaultState(), 2); } i = 0; for (CommandClone.StaticCloneData commandclone$staticclonedata1 : list3) { if (world.setBlockState(commandclone$staticclonedata1.pos, commandclone$staticclonedata1.blockState, 2)) { ++i; } } for (CommandClone.StaticCloneData commandclone$staticclonedata2 : list1) { TileEntity tileentity3 = world.getTileEntity(commandclone$staticclonedata2.pos); if (commandclone$staticclonedata2.nbt != null && tileentity3 != null) { commandclone$staticclonedata2.nbt.setInteger("x", commandclone$staticclonedata2.pos.getX()); commandclone$staticclonedata2.nbt.setInteger("y", commandclone$staticclonedata2.pos.getY()); commandclone$staticclonedata2.nbt.setInteger("z", commandclone$staticclonedata2.pos.getZ()); tileentity3.readFromNBT(commandclone$staticclonedata2.nbt); tileentity3.markDirty(); } world.setBlockState(commandclone$staticclonedata2.pos, commandclone$staticclonedata2.blockState, 2); } for (CommandClone.StaticCloneData commandclone$staticclonedata3 : list4) { world.notifyNeighborsRespectDebug(commandclone$staticclonedata3.pos, commandclone$staticclonedata3.blockState.getBlock(), false); } List list5 = world.getPendingBlockUpdates(structureboundingbox, false); if (list5 != null) { for (NextTickListEntry nextticklistentry : list5) { if (structureboundingbox.isVecInside(nextticklistentry.position)) { BlockPos blockpos8 = nextticklistentry.position.add(blockpos3); world.scheduleBlockUpdate(blockpos8, nextticklistentry.getBlock(), (int)(nextticklistentry.scheduledTime - world.getWorldInfo().getWorldTotalTime()), nextticklistentry.priority); } } } if (i <= 0) { throw new CommandException("commands.clone.failed", new Object[0]); } else { sender.setCommandStat(CommandResultStats.Type.AFFECTED_BLOCKS, i); notifyCommandListener(sender, this, "commands.clone.success", new Object[] {i}); } } else { throw new CommandException("commands.clone.outOfWorld", new Object[0]); } } else { throw new CommandException("commands.clone.outOfWorld", new Object[0]); } } } } } /** * Get a list of options for when the user presses the TAB key */ public List getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos) { if (args.length > 0 && args.length <= 3) { return getTabCompletionCoordinate(args, 0, targetPos); } else if (args.length > 3 && args.length <= 6) { return getTabCompletionCoordinate(args, 3, targetPos); } else if (args.length > 6 && args.length <= 9) { return getTabCompletionCoordinate(args, 6, targetPos); } else if (args.length == 10) { return getListOfStringsMatchingLastWord(args, new String[] {"replace", "masked", "filtered"}); } else if (args.length == 11) { return getListOfStringsMatchingLastWord(args, new String[] {"normal", "force", "move"}); } else { return args.length == 12 && "filtered".equals(args[9]) ? getListOfStringsMatchingLastWord(args, Block.REGISTRY.getKeys()) : Collections.emptyList(); } } static class StaticCloneData { public final BlockPos pos; public final IBlockState blockState; public final NBTTagCompound nbt; public StaticCloneData(BlockPos posIn, IBlockState stateIn, NBTTagCompound compoundIn) { this.pos = posIn; this.blockState = stateIn; this.nbt = compoundIn; } } }