Make a lot of progress on legacy conversions.

This commit is contained in:
Matthew Miller
2018-07-31 16:14:36 +10:00
parent fdb7ada295
commit c05c33cab0
6 changed files with 280 additions and 241 deletions

View File

@ -19,7 +19,9 @@
package com.sk89q.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
@ -301,4 +303,24 @@ public final class StringUtil {
return type;
}
public static List<String> parseListInQuotes(String[] input, char delimiter, char quoteOpen, char quoteClose) {
List<String> parsableBlocks = new ArrayList<>();
StringBuilder buffer = new StringBuilder();
for (String split : input) {
if (split.indexOf(quoteOpen) != -1 && split.indexOf(quoteClose) == -1) {
buffer.append(split).append(delimiter);
} else if (split.indexOf(quoteClose) != -1 && split.indexOf(quoteOpen) == -1) {
buffer.append(split);
parsableBlocks.add(buffer.toString());
buffer = new StringBuilder();
} else if (buffer.length() == 0) {
parsableBlocks.add(split);
} else {
buffer.append(split).append(delimiter);
}
}
return parsableBlocks;
}
}

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.extension.factory;
import com.sk89q.util.StringUtil;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extension.input.InputParseException;
@ -59,7 +60,8 @@ public class BlockFactory extends AbstractFactory<BlockStateHolder> {
*/
public Set<BlockStateHolder> parseFromListInput(String input, ParserContext context) throws InputParseException {
Set<BlockStateHolder> blocks = new HashSet<>();
for (String token : input.split(",")) {
String[] splits = input.split(",");
for (String token : StringUtil.parseListInQuotes(splits, ',', '[', ']')) {
blocks.add(parseFromInput(token, context));
}
return blocks;

View File

@ -48,8 +48,6 @@ import com.sk89q.worldedit.world.registry.LegacyMapper;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Parses block input strings.
@ -98,7 +96,6 @@ class DefaultBlockParser extends InputParser<BlockStateHolder> {
}
}
private static Pattern blockStatePattern = Pattern.compile("([a-z:_]+)(?:\\[([a-zA-Z0-9=, _]+)])?", Pattern.CASE_INSENSITIVE);
private static String[] EMPTY_STRING_ARRAY = new String[]{};
/**
@ -210,14 +207,21 @@ class DefaultBlockParser extends InputParser<BlockStateHolder> {
}
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) {
String typeString;
String stateString = null;
int stateStart = blockAndExtraData[0].indexOf('[');
if (stateStart == -1) {
typeString = blockAndExtraData[0];
} else {
typeString = blockAndExtraData[0].substring(0, stateStart);
stateString = blockAndExtraData[0].substring(stateStart + 1, blockAndExtraData[0].length() - 1);
}
if (typeString == null || typeString.isEmpty()) {
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 (stateString != null) {
stateProperties = stateString.split(",");
}
if ("hand".equalsIgnoreCase(typeString)) {

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.extension.factory;
import com.sk89q.util.StringUtil;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
@ -39,7 +40,8 @@ class RandomPatternParser extends InputParser<Pattern> {
BlockFactory blockRegistry = worldEdit.getBlockFactory();
RandomPattern randomPattern = new RandomPattern();
for (String token : input.split(",")) {
String[] splits = input.split(",");
for (String token : StringUtil.parseListInQuotes(splits, ',', '[', ']')) {
BlockStateHolder block;
double chance;

View File

@ -19,8 +19,8 @@
package com.sk89q.worldedit.world.registry;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.io.Resources;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@ -48,8 +48,10 @@ public class LegacyMapper {
private static final Logger log = Logger.getLogger(LegacyMapper.class.getCanonicalName());
private static LegacyMapper INSTANCE;
private BiMap<String, BlockState> blockMap = HashBiMap.create();
private BiMap<String, ItemType> itemMap = HashBiMap.create();
private Multimap<String, BlockState> stringToBlockMap = HashMultimap.create();
private Multimap<BlockState, String> blockToStringMap = HashMultimap.create();
private Multimap<String, ItemType> stringToItemMap = HashMultimap.create();
private Multimap<ItemType, String> itemToStringMap = HashMultimap.create();
/**
* Create a new instance.
@ -85,58 +87,63 @@ public class LegacyMapper {
for (Map.Entry<String, String> blockEntry : dataFile.blocks.entrySet()) {
try {
blockMap.put(blockEntry.getKey(),
(BlockState) WorldEdit.getInstance().getBlockFactory().parseFromInput(blockEntry.getValue(), parserContext));
String id = blockEntry.getKey();
BlockState state = WorldEdit.getInstance().getBlockFactory().parseFromInput(blockEntry.getValue(), parserContext).toImmutableState();
blockToStringMap.put(state, id);
stringToBlockMap.put(id, state);
} catch (Exception e) {
log.fine("Unknown block: " + blockEntry.getValue());
log.warning("Unknown block: " + blockEntry.getValue());
}
}
for (Map.Entry<String, String> itemEntry : dataFile.items.entrySet()) {
try {
itemMap.put(itemEntry.getKey(), ItemTypes.get(itemEntry.getValue()));
String id = itemEntry.getKey();
ItemType type = ItemTypes.get(itemEntry.getValue());
itemToStringMap.put(type, id);
stringToItemMap.put(id, type);
} catch (Exception e) {
log.fine("Unknown item: " + itemEntry.getValue());
log.warning("Unknown item: " + itemEntry.getValue());
}
}
}
@Nullable
public ItemType getItemFromLegacy(int legacyId) {
return itemMap.get(legacyId + ":0");
return getItemFromLegacy(legacyId, 0);
}
@Nullable
public ItemType getItemFromLegacy(int legacyId, int data) {
return itemMap.get(legacyId + ":" + data);
return stringToItemMap.get(legacyId + ":" + data).stream().findFirst().orElse(null);
}
@Nullable
public int[] getLegacyFromItem(ItemType itemType) {
if (!itemMap.inverse().containsKey(itemType)) {
if (!itemToStringMap.containsKey(itemType)) {
return null;
} else {
String value = itemMap.inverse().get(itemType);
String value = itemToStringMap.get(itemType).stream().findFirst().get();
return Arrays.stream(value.split(":")).mapToInt(Integer::parseInt).toArray();
}
}
@Nullable
public BlockState getBlockFromLegacy(int legacyId) {
return blockMap.get(legacyId + ":0");
return getBlockFromLegacy(legacyId, 0);
}
@Nullable
public BlockState getBlockFromLegacy(int legacyId, int data) {
return blockMap.get(legacyId + ":" + data);
return stringToBlockMap.get(legacyId + ":" + data).stream().findFirst().orElse(null);
}
@Nullable
public int[] getLegacyFromBlock(BlockState blockState) {
if (!blockMap.inverse().containsKey(blockState)) {
if (!blockToStringMap.containsKey(blockState)) {
return null;
} else {
String value = blockMap.inverse().get(blockState);
String value = blockToStringMap.get(blockState).stream().findFirst().get();
return Arrays.stream(value.split(":")).mapToInt(Integer::parseInt).toArray();
}
}