use of com.fastasyncworldedit.core.util.MutableCharSequence in project FastAsyncWorldEdit by IntellectualSites.
the class BlockState method get.
/**
* Returns a temporary BlockState for a given type and string.
*
* <p>It's faster if a BlockType is provided compared to parsing the string.</p>
*
* @param type BlockType e.g., BlockTypes.STONE (or null)
* @param state String e.g., minecraft:water[level=4]
* @return BlockState
*/
public static BlockState get(@Nullable BlockType type, String state, BlockState defaultState) throws InputParseException {
int propStrStart = state.indexOf('[');
if (type == null) {
CharSequence key;
if (propStrStart == -1) {
key = state;
} else {
MutableCharSequence charSequence = MutableCharSequence.getTemporal();
charSequence.setString(state);
charSequence.setSubstring(0, propStrStart);
key = charSequence;
}
type = BlockTypes.get(key);
if (type == null) {
String input = key.toString();
throw new SuggestInputParseException("Does not match a valid block type: " + input, input, () -> Stream.of(BlockTypesCache.values).map(BlockType::getId).filter(id -> StringMan.blockStateMatches(input, id)).sorted(StringMan.blockStateComparator(input)).collect(Collectors.toList()));
}
}
if (propStrStart == -1) {
return type.getDefaultState();
}
List<? extends Property<?>> propList = type.getProperties();
if (state.charAt(state.length() - 1) != ']') {
state = state + "]";
}
MutableCharSequence charSequence = MutableCharSequence.getTemporal();
charSequence.setString(state);
if (propList.size() == 1) {
AbstractProperty<?> property = (AbstractProperty<?>) propList.get(0);
String name = property.getName();
charSequence.setSubstring(propStrStart + name.length() + 2, state.length() - 1);
int index = charSequence.length() <= 0 ? -1 : property.getIndexFor(charSequence);
if (index != -1) {
return type.withPropertyId(index);
}
}
int stateId;
if (defaultState != null) {
stateId = defaultState.getInternalId();
} else {
stateId = type.getDefaultState().getInternalId();
}
int length = state.length();
AbstractProperty<?> property = null;
int last = propStrStart + 1;
for (int i = last; i < length; i++) {
char c = state.charAt(i);
switch(c) {
case ']':
case ',':
{
charSequence.setSubstring(last, i);
if (property != null) {
int index = property.getIndexFor(charSequence);
if (index == -1) {
throw SuggestInputParseException.of(charSequence.toString(), (List<Object>) property.getValues());
}
stateId = property.modifyIndex(stateId, index);
} else {
// suggest
PropertyKey key = PropertyKey.getByName(charSequence);
if (key == null || !type.hasProperty(key)) {
// Suggest property
String input = charSequence.toString();
BlockType finalType = type;
throw new SuggestInputParseException("Invalid property " + key + ":" + input + " for type " + type, input, () -> finalType.getProperties().stream().map(Property::getName).filter(p -> StringMan.blockStateMatches(input, p)).sorted(StringMan.blockStateComparator(input)).collect(Collectors.toList()));
} else {
throw new SuggestInputParseException("No operator for " + state, "", () -> Collections.singletonList("="));
}
}
property = null;
last = i + 1;
break;
}
case '=':
{
charSequence.setSubstring(last, i);
property = (AbstractProperty) type.getPropertyMap().get(charSequence);
last = i + 1;
break;
}
default:
continue;
}
}
return type.withPropertyId(stateId >> BlockTypesCache.BIT_OFFSET);
}
Aggregations