Re-add legacy support to block parser, and fix query tool.

This commit is contained in:
Matthew Miller 2018-07-23 12:48:11 +10:00
parent 5f551d1ed4
commit 9f9fda72b7
6 changed files with 108 additions and 59 deletions

View File

@ -227,7 +227,11 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
@Override @Override
public String toString() { public String toString() {
return "Block{State: " + this.toImmutableState().toString() + ", NBT: " + String.valueOf(getNbtData()) + "}"; // if (getNbtData() != null) { // TODO Maybe make some JSON serialiser to make this not awful.
// return blockState.getAsString() + " {" + String.valueOf(getNbtData()) + "}";
// } else {
return blockState.getAsString();
// }
} }
} }

View File

@ -47,10 +47,10 @@ public class QueryTool implements BlockTool {
BlockStateHolder block = editSession.getFullBlock(clicked.toVector()); BlockStateHolder block = editSession.getFullBlock(clicked.toVector());
player.print("\u00A79@" + clicked.toVector() + ": " + "\u00A7e" player.print("\u00A79@" + clicked.toVector() + ": " + "\u00A7e"
+ "#" + block.getBlockType() + "\u00A77" + " (" + block.getBlockType().getName() + "\u00A77" + " ("
+ block.getBlockType().getId() + ") " + block.toString() + ") "
+ "\u00A7f" + "\u00A7f"
+ "[" + block.getStates().toString() + "]" + " (" + world.getBlockLightLevel(clicked.toVector()) + "/" + world.getBlockLightLevel(clicked.toVector().add(0, 1, 0)) + ")"); + " (" + world.getBlockLightLevel(clicked.toVector()) + "/" + world.getBlockLightLevel(clicked.toVector().add(0, 1, 0)) + ")");
if (block instanceof MobSpawnerBlock) { if (block instanceof MobSpawnerBlock) {
player.printRaw("\u00A7e" + "Mob Type: " player.printRaw("\u00A7e" + "Mob Type: "

View File

@ -44,6 +44,7 @@ import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -185,71 +186,90 @@ class DefaultBlockParser extends InputParser<BlockStateHolder> {
} }
private BlockStateHolder parseLogic(String input, ParserContext context) throws InputParseException { private BlockStateHolder parseLogic(String input, ParserContext context) throws InputParseException {
BlockType blockType; BlockType blockType = null;
Map<Property<?>, Object> blockStates = new HashMap<>(); Map<Property<?>, Object> blockStates = new HashMap<>();
String[] blockAndExtraData = input.trim().split("\\|"); String[] blockAndExtraData = input.trim().split("\\|");
blockAndExtraData[0] = woolMapper(blockAndExtraData[0]); blockAndExtraData[0] = woolMapper(blockAndExtraData[0]);
Matcher matcher = blockStatePattern.matcher(blockAndExtraData[0]);
if (!matcher.matches() || matcher.groupCount() < 2 || matcher.groupCount() > 3) {
throw new InputParseException("Invalid format");
}
String typeString = matcher.group(1);
String[] stateProperties = EMPTY_STRING_ARRAY;
if (matcher.groupCount() >= 2 && matcher.group(2) != null) {
stateProperties = matcher.group(2).split(",");
}
if ("hand".equalsIgnoreCase(typeString)) { BlockState state = null;
// Get the block type from the item in the user's hand.
final BaseBlock blockInHand = getBlockInHand(context.requireActor(), HandSide.MAIN_HAND);
if (blockInHand.getClass() != BaseBlock.class) {
return blockInHand;
}
blockType = blockInHand.getBlockType(); // Legacy matcher
blockStates = blockInHand.getStates(); if (context.isTryingLegacy()) {
} else if ("offhand".equalsIgnoreCase(typeString)) {
// Get the block type from the item in the user's off hand.
final BaseBlock blockInHand = getBlockInHand(context.requireActor(), HandSide.OFF_HAND);
if (blockInHand.getClass() != BaseBlock.class) {
return blockInHand;
}
blockType = blockInHand.getBlockType();
blockStates = blockInHand.getStates();
} else if ("pos1".equalsIgnoreCase(typeString)) {
// Get the block type from the "primary position"
final World world = context.requireWorld();
final BlockVector primaryPosition;
try { try {
primaryPosition = context.requireSession().getRegionSelector(world).getPrimaryPosition(); String[] split = blockAndExtraData[0].split(":");
} catch (IncompleteRegionException e) { if (split.length == 1) {
throw new InputParseException("Your selection is not complete."); state = LegacyMapper.getInstance().getBlockFromLegacy(Integer.parseInt(split[0]));
} } else {
final BlockState blockInHand = world.getBlock(primaryPosition); state = LegacyMapper.getInstance().getBlockFromLegacy(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
}
blockType = blockInHand.getBlockType(); if (state != null) {
blockStates = blockInHand.getStates(); blockType = state.getBlockType();
} else { }
// Attempt to lookup a block from ID or name. } catch (NumberFormatException e) {
blockType = BlockTypes.get(typeString);
if (blockType == null) {
throw new NoMatchException("Does not match a valid block type: '" + input + "'");
} }
} }
BlockState state; if (state == null) {
Matcher matcher = blockStatePattern.matcher(blockAndExtraData[0]); // TODO Move away from regex because it's hella slow
if (!matcher.matches() || matcher.groupCount() < 2 || matcher.groupCount() > 3) {
throw new InputParseException("Invalid format");
}
String typeString = matcher.group(1);
String[] stateProperties = EMPTY_STRING_ARRAY;
if (matcher.groupCount() >= 2 && matcher.group(2) != null) {
stateProperties = matcher.group(2).split(",");
}
if (!context.isPreferringWildcard()) { if ("hand".equalsIgnoreCase(typeString)) {
// No wildcards allowed => eliminate them. (Start with default state) // Get the block type from the item in the user's hand.
state = blockType.getDefaultState(); final BaseBlock blockInHand = getBlockInHand(context.requireActor(), HandSide.MAIN_HAND);
} else { if (blockInHand.getClass() != BaseBlock.class) {
state = new BlockState(blockType, blockStates); return blockInHand;
}
blockType = blockInHand.getBlockType();
blockStates = blockInHand.getStates();
} else if ("offhand".equalsIgnoreCase(typeString)) {
// Get the block type from the item in the user's off hand.
final BaseBlock blockInHand = getBlockInHand(context.requireActor(), HandSide.OFF_HAND);
if (blockInHand.getClass() != BaseBlock.class) {
return blockInHand;
}
blockType = blockInHand.getBlockType();
blockStates = blockInHand.getStates();
} else if ("pos1".equalsIgnoreCase(typeString)) {
// Get the block type from the "primary position"
final World world = context.requireWorld();
final BlockVector primaryPosition;
try {
primaryPosition = context.requireSession().getRegionSelector(world).getPrimaryPosition();
} catch (IncompleteRegionException e) {
throw new InputParseException("Your selection is not complete.");
}
final BlockState blockInHand = world.getBlock(primaryPosition);
blockType = blockInHand.getBlockType();
blockStates = blockInHand.getStates();
} else {
// Attempt to lookup a block from ID or name.
blockType = BlockTypes.get(typeString);
if (blockType == null) {
throw new NoMatchException("Does not match a valid block type: '" + input + "'");
}
}
if (!context.isPreferringWildcard()) {
// No wildcards allowed => eliminate them. (Start with default state)
state = blockType.getDefaultState();
} else {
state = new BlockState(blockType, blockStates);
}
state = applyProperties(state, stateProperties);
} }
state = applyProperties(state, stateProperties);
// Check if the item is allowed // Check if the item is allowed
if (context.isRestricted()) { if (context.isRestricted()) {
Actor actor = context.requireActor(); Actor actor = context.requireActor();

View File

@ -40,6 +40,7 @@ public class ParserContext {
private @Nullable World world; private @Nullable World world;
private @Nullable Actor actor; private @Nullable Actor actor;
private boolean restricted = true; private boolean restricted = true;
private boolean tryLegacy = true;
private boolean preferringWildcard; private boolean preferringWildcard;
/** /**
@ -60,6 +61,7 @@ public class ParserContext {
setActor(other.getActor()); setActor(other.getActor());
setRestricted(other.isRestricted()); setRestricted(other.isRestricted());
setPreferringWildcard(other.isPreferringWildcard()); setPreferringWildcard(other.isPreferringWildcard());
setTryLegacy(other.isTryingLegacy());
} }
/** /**
@ -229,4 +231,21 @@ public class ParserContext {
this.preferringWildcard = preferringWildcard; this.preferringWildcard = preferringWildcard;
} }
/**
* Set whether legacy IDs should be attempted.
*
* @param tryLegacy true if legacy IDs should be attempted
*/
public void setTryLegacy(boolean tryLegacy) {
this.tryLegacy = tryLegacy;
}
/**
* Get whether legacy IDs should be tried.
*
* @return true if legacy should be tried
*/
public boolean isTryingLegacy() {
return tryLegacy;
}
} }

View File

@ -212,4 +212,9 @@ public class BlockState implements BlockStateHolder<BlockState> {
this.values.put(property, value); this.values.put(property, value);
return this; return this;
} }
@Override
public String toString() {
return getAsString();
}
} }

View File

@ -81,13 +81,14 @@ public class LegacyMapper {
ParserContext parserContext = new ParserContext(); ParserContext parserContext = new ParserContext();
parserContext.setPreferringWildcard(false); parserContext.setPreferringWildcard(false);
parserContext.setRestricted(false); parserContext.setRestricted(false);
parserContext.setTryLegacy(false); // This is legacy. Don't match itself.
for (Map.Entry<String, String> blockEntry : dataFile.blocks.entrySet()) { for (Map.Entry<String, String> blockEntry : dataFile.blocks.entrySet()) {
try { try {
blockMap.put(blockEntry.getKey(), blockMap.put(blockEntry.getKey(),
(BlockState) WorldEdit.getInstance().getBlockFactory().parseFromInput(blockEntry.getValue(), parserContext)); (BlockState) WorldEdit.getInstance().getBlockFactory().parseFromInput(blockEntry.getValue(), parserContext));
} catch (Exception e) { } catch (Exception e) {
log.warning("Unknown block: " + blockEntry.getValue()); log.fine("Unknown block: " + blockEntry.getValue());
} }
} }
@ -95,7 +96,7 @@ public class LegacyMapper {
try { try {
itemMap.put(itemEntry.getKey(), ItemTypes.get(itemEntry.getValue())); itemMap.put(itemEntry.getKey(), ItemTypes.get(itemEntry.getValue()));
} catch (Exception e) { } catch (Exception e) {
log.warning("Unknown item: " + itemEntry.getValue()); log.fine("Unknown item: " + itemEntry.getValue());
} }
} }
} }