blob: 774a99583d61feb5b0ceecd8f606356df4c5cc2a [file] [log] [blame] [raw]
package net.glowstone.command.minecraft;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.glowstone.GlowWorld;
import net.glowstone.block.GlowBlock;
import net.glowstone.command.CommandUtils;
import net.glowstone.i18n.LocalizedStringImpl;
import net.glowstone.util.RectangularRegion;
import net.glowstone.util.nbt.CompoundTag;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import java.util.Iterator;
import java.util.Objects;
import java.util.ResourceBundle;
import static net.glowstone.util.RectangularRegion.IterationDirection.FORWARDS;
public class TestForBlocksCommand extends GlowVanillaCommand {
@RequiredArgsConstructor
public enum MatchMode {
ALL("all") {
@Override
public boolean isFiltered(GlowBlock fromBlock) {
return false;
}
},
MASKED("masked") {
@Override
public boolean isFiltered(GlowBlock fromBlock) {
return fromBlock.getType() == Material.AIR;
}
};
@Getter
private final String commandName;
/**
* Returns the MatchMode with a given subcommand name, or null if none match.
*
* @param commandName the subcommand name to look up.
* @return the mask mode.
*/
public static MatchMode fromCommandName(
String commandName) {
for (MatchMode matchMode : values()) {
if (matchMode.getCommandName().equals(commandName)) {
return matchMode;
}
}
return null;
}
/**
* Whether the source region's block is filtered from matching.
*
* @param fromBlock The block in the source region.
* @return true if the block is filtered, false otherwise.
*/
public abstract boolean isFiltered(GlowBlock fromBlock);
/**
* Whether the block from the source region matches the block from the destination region.
*
* @param fromBlock The block from the source region.
* @param toBlock The block from the destination region.
* @return true if the blocks match, false otherwise.
*/
public boolean matches(GlowBlock fromBlock, GlowBlock toBlock) {
if (isFiltered(fromBlock)) {
return true;
}
CompoundTag fromEntityTag = null;
if (fromBlock.getBlockEntity() != null) {
fromEntityTag = new CompoundTag();
fromBlock.getBlockEntity().saveNbt(fromEntityTag);
}
CompoundTag toEntityTag = null;
if (toBlock.getBlockEntity() != null) {
toEntityTag = new CompoundTag();
toBlock.getBlockEntity().saveNbt(fromEntityTag);
}
Material fromType = fromBlock.getType();
Material toType = toBlock.getType();
byte fromData = fromBlock.getData();
byte toData = toBlock.getData();
return Objects.equals(fromType, toType)
&& Objects.equals(fromData, toData)
&& Objects.equals(fromEntityTag, toEntityTag);
}
}
/**
* Creates the instance for this command.
*/
public TestForBlocksCommand() {
super("testforblocks");
setPermission("minecraft.command.testforblocks"); // NON-NLS
}
@Override
public boolean execute(CommandSender sender, String commandLabel, String[] args,
CommandMessages commandMessages) {
if (!testPermission(sender, commandMessages.getPermissionMessage())) {
return true;
}
if (args.length < 9) {
sendUsageMessage(sender, commandMessages);
return false;
}
if (!CommandUtils.isPhysical(sender)) {
commandMessages.getGeneric(GenericMessage.NOT_PHYSICAL).send(sender);
return false;
}
GlowWorld world = CommandUtils.getWorld(sender);
Location parsedFrom1 = CommandUtils.getLocation(sender, args[0], args[1], args[2]);
Location parsedFrom2 = CommandUtils.getLocation(sender, args[3], args[4], args[5]);
Location to = CommandUtils.getLocation(sender, args[6], args[7], args[8]);
MatchMode matchMode = args.length >= 10
? MatchMode
.fromCommandName(args[9]) :
MatchMode.ALL;
if (matchMode == null) {
sendUsageMessage(sender, commandMessages);
return false;
}
RectangularRegion fromRegion = new RectangularRegion(parsedFrom1, parsedFrom2);
RectangularRegion toRegion = fromRegion.moveTo(to);
Iterator<Location> fromIterator = fromRegion
.blockLocations(FORWARDS, FORWARDS, FORWARDS).iterator();
Iterator<Location> toIterator = toRegion
.blockLocations(FORWARDS, FORWARDS, FORWARDS).iterator();
int blocksMatched = 0;
ResourceBundle bundle = commandMessages.getResourceBundle();
while (fromIterator.hasNext() && toIterator.hasNext()) {
Location fromLocation = fromIterator.next();
Location toLocation = toIterator.next();
GlowBlock fromBlock = world.getBlockAt(fromLocation);
GlowBlock toBlock = world.getBlockAt(toLocation);
if (matchMode.matches(fromBlock, toBlock)) {
if (!matchMode.isFiltered(fromBlock)) {
blocksMatched++;
}
} else {
new LocalizedStringImpl("testforblocks.no-match", bundle)
.sendInColor(ChatColor.RED, sender);
return false;
}
}
new LocalizedStringImpl("testforblocks.done", bundle)
.send(sender, blocksMatched);
return true;
}
}