aboutsummaryrefslogtreecommitdiffhomepage
path: root/patch-remap/mache-vineflower/net/minecraft/commands/arguments/blocks/BlockStateParser.java.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patch-remap/mache-vineflower/net/minecraft/commands/arguments/blocks/BlockStateParser.java.patch')
-rw-r--r--patch-remap/mache-vineflower/net/minecraft/commands/arguments/blocks/BlockStateParser.java.patch641
1 files changed, 641 insertions, 0 deletions
diff --git a/patch-remap/mache-vineflower/net/minecraft/commands/arguments/blocks/BlockStateParser.java.patch b/patch-remap/mache-vineflower/net/minecraft/commands/arguments/blocks/BlockStateParser.java.patch
new file mode 100644
index 0000000000..77aa7b9a06
--- /dev/null
+++ b/patch-remap/mache-vineflower/net/minecraft/commands/arguments/blocks/BlockStateParser.java.patch
@@ -0,0 +1,641 @@
+--- a/net/minecraft/commands/arguments/blocks/BlockStateParser.java
++++ b/net/minecraft/commands/arguments/blocks/BlockStateParser.java
+@@ -1,6 +1,7 @@
+ package net.minecraft.commands.arguments.blocks;
+
+ import com.google.common.collect.Maps;
++import com.google.common.collect.UnmodifiableIterator;
+ import com.mojang.brigadier.StringReader;
+ import com.mojang.brigadier.exceptions.CommandSyntaxException;
+ import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
+@@ -10,10 +11,11 @@
+ import com.mojang.brigadier.suggestion.Suggestions;
+ import com.mojang.brigadier.suggestion.SuggestionsBuilder;
+ import com.mojang.datafixers.util.Either;
++import java.util.Iterator;
+ import java.util.Locale;
+ import java.util.Map;
+-import java.util.Optional;
+ import java.util.Map.Entry;
++import java.util.Optional;
+ import java.util.concurrent.CompletableFuture;
+ import java.util.function.Function;
+ import javax.annotation.Nullable;
+@@ -29,35 +31,32 @@
+ import net.minecraft.resources.ResourceLocation;
+ import net.minecraft.tags.TagKey;
+ import net.minecraft.world.level.block.Block;
+-import net.minecraft.world.level.block.state.BlockState;
++import net.minecraft.world.level.block.state.IBlockData;
+ import net.minecraft.world.level.block.state.StateDefinition;
+ import net.minecraft.world.level.block.state.properties.Property;
+
+ public class BlockStateParser {
+- public static final SimpleCommandExceptionType ERROR_NO_TAGS_ALLOWED = new SimpleCommandExceptionType(
+- Component.translatable("argument.block.tag.disallowed")
+- );
+- public static final DynamicCommandExceptionType ERROR_UNKNOWN_BLOCK = new DynamicCommandExceptionType(
+- block -> Component.translatableEscape("argument.block.id.invalid", block)
+- );
+- public static final Dynamic2CommandExceptionType ERROR_UNKNOWN_PROPERTY = new Dynamic2CommandExceptionType(
+- (block, property) -> Component.translatableEscape("argument.block.property.unknown", block, property)
+- );
+- public static final Dynamic2CommandExceptionType ERROR_DUPLICATE_PROPERTY = new Dynamic2CommandExceptionType(
+- (property, block) -> Component.translatableEscape("argument.block.property.duplicate", block, property)
+- );
+- public static final Dynamic3CommandExceptionType ERROR_INVALID_VALUE = new Dynamic3CommandExceptionType(
+- (block, value, property) -> Component.translatableEscape("argument.block.property.invalid", block, property, value)
+- );
+- public static final Dynamic2CommandExceptionType ERROR_EXPECTED_VALUE = new Dynamic2CommandExceptionType(
+- (property, block) -> Component.translatableEscape("argument.block.property.novalue", property, block)
+- );
+- public static final SimpleCommandExceptionType ERROR_EXPECTED_END_OF_PROPERTIES = new SimpleCommandExceptionType(
+- Component.translatable("argument.block.property.unclosed")
+- );
+- public static final DynamicCommandExceptionType ERROR_UNKNOWN_TAG = new DynamicCommandExceptionType(
+- blockTag -> Component.translatableEscape("arguments.block.tag.unknown", blockTag)
+- );
++
++ public static final SimpleCommandExceptionType ERROR_NO_TAGS_ALLOWED = new SimpleCommandExceptionType(Component.translatable("argument.block.tag.disallowed"));
++ public static final DynamicCommandExceptionType ERROR_UNKNOWN_BLOCK = new DynamicCommandExceptionType((object) -> {
++ return Component.translatableEscape("argument.block.id.invalid", object);
++ });
++ public static final Dynamic2CommandExceptionType ERROR_UNKNOWN_PROPERTY = new Dynamic2CommandExceptionType((object, object1) -> {
++ return Component.translatableEscape("argument.block.property.unknown", object, object1);
++ });
++ public static final Dynamic2CommandExceptionType ERROR_DUPLICATE_PROPERTY = new Dynamic2CommandExceptionType((object, object1) -> {
++ return Component.translatableEscape("argument.block.property.duplicate", object1, object);
++ });
++ public static final Dynamic3CommandExceptionType ERROR_INVALID_VALUE = new Dynamic3CommandExceptionType((object, object1, object2) -> {
++ return Component.translatableEscape("argument.block.property.invalid", object, object2, object1);
++ });
++ public static final Dynamic2CommandExceptionType ERROR_EXPECTED_VALUE = new Dynamic2CommandExceptionType((object, object1) -> {
++ return Component.translatableEscape("argument.block.property.novalue", object, object1);
++ });
++ public static final SimpleCommandExceptionType ERROR_EXPECTED_END_OF_PROPERTIES = new SimpleCommandExceptionType(Component.translatable("argument.block.property.unclosed"));
++ public static final DynamicCommandExceptionType ERROR_UNKNOWN_TAG = new DynamicCommandExceptionType((object) -> {
++ return Component.translatableEscape("arguments.block.tag.unknown", object);
++ });
+ private static final char SYNTAX_START_PROPERTIES = '[';
+ private static final char SYNTAX_START_NBT = '{';
+ private static final char SYNTAX_END_PROPERTIES = ']';
+@@ -69,75 +68,76 @@
+ private final StringReader reader;
+ private final boolean forTesting;
+ private final boolean allowNbt;
+- private final Map<Property<?>, Comparable<?>> properties = Maps.newHashMap();
++ private final Map<Property<?>, Comparable<?>> properties = Maps.newLinkedHashMap(); // CraftBukkit - stable
+ private final Map<String, String> vagueProperties = Maps.newHashMap();
+ private ResourceLocation id = new ResourceLocation("");
+ @Nullable
+- private StateDefinition<Block, BlockState> definition;
++ private StateDefinition<Block, IBlockData> definition;
+ @Nullable
+- private BlockState state;
++ private IBlockData state;
+ @Nullable
+ private CompoundTag nbt;
+ @Nullable
+ private HolderSet<Block> tag;
+- private Function<SuggestionsBuilder, CompletableFuture<Suggestions>> suggestions = SUGGEST_NOTHING;
++ private Function<SuggestionsBuilder, CompletableFuture<Suggestions>> suggestions;
+
+ private BlockStateParser(HolderLookup<Block> blocks, StringReader reader, boolean forTesting, boolean allowNbt) {
++ this.suggestions = BlockStateParser.SUGGEST_NOTHING;
+ this.blocks = blocks;
+ this.reader = reader;
+ this.forTesting = forTesting;
+ this.allowNbt = allowNbt;
+ }
+
+- public static BlockStateParser.BlockResult parseForBlock(HolderLookup<Block> lookup, String input, boolean allowNbt) throws CommandSyntaxException {
++ public static BlockStateParser.a parseForBlock(HolderLookup<Block> lookup, String input, boolean allowNbt) throws CommandSyntaxException {
+ return parseForBlock(lookup, new StringReader(input), allowNbt);
+ }
+
+- public static BlockStateParser.BlockResult parseForBlock(HolderLookup<Block> lookup, StringReader reader, boolean allowNbt) throws CommandSyntaxException {
+- int cursor = reader.getCursor();
++ public static BlockStateParser.a parseForBlock(HolderLookup<Block> lookup, StringReader reader, boolean allowNbt) throws CommandSyntaxException {
++ int i = reader.getCursor();
+
+ try {
+- BlockStateParser blockStateParser = new BlockStateParser(lookup, reader, false, allowNbt);
+- blockStateParser.parse();
+- return new BlockStateParser.BlockResult(blockStateParser.state, blockStateParser.properties, blockStateParser.nbt);
+- } catch (CommandSyntaxException var5) {
+- reader.setCursor(cursor);
+- throw var5;
++ BlockStateParser argumentblock = new BlockStateParser(lookup, reader, false, allowNbt);
++
++ argumentblock.parse();
++ return new BlockStateParser.a(argumentblock.state, argumentblock.properties, argumentblock.nbt);
++ } catch (CommandSyntaxException commandsyntaxexception) {
++ reader.setCursor(i);
++ throw commandsyntaxexception;
+ }
+ }
+
+- public static Either<BlockStateParser.BlockResult, BlockStateParser.TagResult> parseForTesting(HolderLookup<Block> lookup, String input, boolean allowNbt) throws CommandSyntaxException {
++ public static Either<BlockStateParser.a, BlockStateParser.b> parseForTesting(HolderLookup<Block> lookup, String input, boolean allowNbt) throws CommandSyntaxException {
+ return parseForTesting(lookup, new StringReader(input), allowNbt);
+ }
+
+- public static Either<BlockStateParser.BlockResult, BlockStateParser.TagResult> parseForTesting(
+- HolderLookup<Block> lookup, StringReader reader, boolean allowNbt
+- ) throws CommandSyntaxException {
+- int cursor = reader.getCursor();
++ public static Either<BlockStateParser.a, BlockStateParser.b> parseForTesting(HolderLookup<Block> lookup, StringReader reader, boolean allowNbt) throws CommandSyntaxException {
++ int i = reader.getCursor();
+
+ try {
+- BlockStateParser blockStateParser = new BlockStateParser(lookup, reader, true, allowNbt);
+- blockStateParser.parse();
+- return blockStateParser.tag != null
+- ? Either.right(new BlockStateParser.TagResult(blockStateParser.tag, blockStateParser.vagueProperties, blockStateParser.nbt))
+- : Either.left(new BlockStateParser.BlockResult(blockStateParser.state, blockStateParser.properties, blockStateParser.nbt));
+- } catch (CommandSyntaxException var5) {
+- reader.setCursor(cursor);
+- throw var5;
++ BlockStateParser argumentblock = new BlockStateParser(lookup, reader, true, allowNbt);
++
++ argumentblock.parse();
++ return argumentblock.tag != null ? Either.right(new BlockStateParser.b(argumentblock.tag, argumentblock.vagueProperties, argumentblock.nbt)) : Either.left(new BlockStateParser.a(argumentblock.state, argumentblock.properties, argumentblock.nbt));
++ } catch (CommandSyntaxException commandsyntaxexception) {
++ reader.setCursor(i);
++ throw commandsyntaxexception;
+ }
+ }
+
+ public static CompletableFuture<Suggestions> fillSuggestions(HolderLookup<Block> lookup, SuggestionsBuilder builder, boolean forTesting, boolean allowNbt) {
+- StringReader stringReader = new StringReader(builder.getInput());
+- stringReader.setCursor(builder.getStart());
+- BlockStateParser blockStateParser = new BlockStateParser(lookup, stringReader, forTesting, allowNbt);
++ StringReader stringreader = new StringReader(builder.getInput());
+
++ stringreader.setCursor(builder.getStart());
++ BlockStateParser argumentblock = new BlockStateParser(lookup, stringreader, forTesting, allowNbt);
++
+ try {
+- blockStateParser.parse();
+- } catch (CommandSyntaxException var7) {
++ argumentblock.parse();
++ } catch (CommandSyntaxException commandsyntaxexception) {
++ ;
+ }
+
+- return blockStateParser.suggestions.apply(builder.createOffset(stringReader.getCursor()));
++ return (CompletableFuture) argumentblock.suggestions.apply(builder.createOffset(stringreader.getCursor()));
+ }
+
+ private void parse() throws CommandSyntaxException {
+@@ -164,9 +164,10 @@
+ }
+
+ if (this.allowNbt && this.reader.canRead() && this.reader.peek() == '{') {
+- this.suggestions = SUGGEST_NOTHING;
++ this.suggestions = BlockStateParser.SUGGEST_NOTHING;
+ this.readNbt();
+ }
++
+ }
+
+ private CompletableFuture<Suggestions> suggestPropertyNameOrEnd(SuggestionsBuilder builder) {
+@@ -186,11 +187,14 @@
+ }
+
+ private CompletableFuture<Suggestions> suggestPropertyName(SuggestionsBuilder builder) {
+- String string = builder.getRemaining().toLowerCase(Locale.ROOT);
++ String s = builder.getRemaining().toLowerCase(Locale.ROOT);
++ Iterator iterator = this.state.getProperties().iterator();
+
+- for (Property<?> property : this.state.getProperties()) {
+- if (!this.properties.containsKey(property) && property.getName().startsWith(string)) {
+- builder.suggest(property.getName() + "=");
++ while (iterator.hasNext()) {
++ Property<?> iblockstate = (Property) iterator.next();
++
++ if (!this.properties.containsKey(iblockstate) && iblockstate.getName().startsWith(s)) {
++ builder.suggest(iblockstate.getName() + "=");
+ }
+ }
+
+@@ -198,12 +202,20 @@
+ }
+
+ private CompletableFuture<Suggestions> suggestVaguePropertyName(SuggestionsBuilder builder) {
+- String string = builder.getRemaining().toLowerCase(Locale.ROOT);
++ String s = builder.getRemaining().toLowerCase(Locale.ROOT);
++
+ if (this.tag != null) {
+- for (Holder<Block> holder : this.tag) {
+- for (Property<?> property : holder.value().getStateDefinition().getProperties()) {
+- if (!this.vagueProperties.containsKey(property.getName()) && property.getName().startsWith(string)) {
+- builder.suggest(property.getName() + "=");
++ Iterator iterator = this.tag.iterator();
++
++ while (iterator.hasNext()) {
++ Holder<Block> holder = (Holder) iterator.next();
++ Iterator iterator1 = ((Block) holder.value()).getStateDefinition().getProperties().iterator();
++
++ while (iterator1.hasNext()) {
++ Property<?> iblockstate = (Property) iterator1.next();
++
++ if (!this.vagueProperties.containsKey(iblockstate.getName()) && iblockstate.getName().startsWith(s)) {
++ builder.suggest(iblockstate.getName() + "=");
+ }
+ }
+ }
+@@ -225,8 +237,12 @@
+ return this.state.hasBlockEntity();
+ } else {
+ if (this.tag != null) {
+- for (Holder<Block> holder : this.tag) {
+- if (holder.value().defaultBlockState().hasBlockEntity()) {
++ Iterator iterator = this.tag.iterator();
++
++ while (iterator.hasNext()) {
++ Holder<Block> holder = (Holder) iterator.next();
++
++ if (((Block) holder.value()).defaultBlockState().hasBlockEntity()) {
+ return true;
+ }
+ }
+@@ -257,11 +273,17 @@
+ }
+
+ private static <T extends Comparable<T>> SuggestionsBuilder addSuggestions(SuggestionsBuilder builder, Property<T> property) {
+- for (T comparable : property.getPossibleValues()) {
+- if (comparable instanceof Integer integer) {
++ Iterator iterator = property.getPossibleValues().iterator();
++
++ while (iterator.hasNext()) {
++ T t0 = (T) iterator.next(); // CraftBukkit - decompile error
++
++ if (t0 instanceof Integer) {
++ Integer integer = (Integer) t0;
++
+ builder.suggest(integer);
+ } else {
+- builder.suggest(property.getName(comparable));
++ builder.suggest(property.getName(t0));
+ }
+ }
+
+@@ -270,17 +292,26 @@
+
+ private CompletableFuture<Suggestions> suggestVaguePropertyValue(SuggestionsBuilder builder, String propertyName) {
+ boolean flag = false;
++
+ if (this.tag != null) {
+- for (Holder<Block> holder : this.tag) {
+- Block block = holder.value();
+- Property<?> property = block.getStateDefinition().getProperty(propertyName);
+- if (property != null) {
+- addSuggestions(builder, property);
++ Iterator iterator = this.tag.iterator();
++
++ while (iterator.hasNext()) {
++ Holder<Block> holder = (Holder) iterator.next();
++ Block block = (Block) holder.value();
++ Property<?> iblockstate = block.getStateDefinition().getProperty(propertyName);
++
++ if (iblockstate != null) {
++ addSuggestions(builder, iblockstate);
+ }
+
+ if (!flag) {
+- for (Property<?> property1 : block.getStateDefinition().getProperties()) {
+- if (!this.vagueProperties.containsKey(property1.getName())) {
++ Iterator iterator1 = block.getStateDefinition().getProperties().iterator();
++
++ while (iterator1.hasNext()) {
++ Property<?> iblockstate1 = (Property) iterator1.next();
++
++ if (!this.vagueProperties.containsKey(iblockstate1.getName())) {
+ flag = true;
+ break;
+ }
+@@ -301,9 +332,12 @@
+ if (builder.getRemaining().isEmpty() && this.tag != null) {
+ boolean flag = false;
+ boolean flag1 = false;
++ Iterator iterator = this.tag.iterator();
+
+- for (Holder<Block> holder : this.tag) {
+- Block block = holder.value();
++ while (iterator.hasNext()) {
++ Holder<Block> holder = (Holder) iterator.next();
++ Block block = (Block) holder.value();
++
+ flag |= !block.getStateDefinition().getProperties().isEmpty();
+ flag1 |= block.defaultBlockState().hasBlockEntity();
+ if (flag && flag1) {
+@@ -352,27 +386,31 @@
+ }
+
+ private void readBlock() throws CommandSyntaxException {
+- int cursor = this.reader.getCursor();
++ int i = this.reader.getCursor();
++
+ this.id = ResourceLocation.read(this.reader);
+- Block block = this.blocks.get(ResourceKey.create(Registries.BLOCK, this.id)).orElseThrow(() -> {
+- this.reader.setCursor(cursor);
+- return ERROR_UNKNOWN_BLOCK.createWithContext(this.reader, this.id.toString());
+- }).value();
++ Block block = (Block) ((Holder.Reference) this.blocks.get(ResourceKey.create(Registries.BLOCK, this.id)).orElseThrow(() -> {
++ this.reader.setCursor(i);
++ return BlockStateParser.ERROR_UNKNOWN_BLOCK.createWithContext(this.reader, this.id.toString());
++ })).value();
++
+ this.definition = block.getStateDefinition();
+ this.state = block.defaultBlockState();
+ }
+
+ private void readTag() throws CommandSyntaxException {
+ if (!this.forTesting) {
+- throw ERROR_NO_TAGS_ALLOWED.createWithContext(this.reader);
++ throw BlockStateParser.ERROR_NO_TAGS_ALLOWED.createWithContext(this.reader);
+ } else {
+- int cursor = this.reader.getCursor();
++ int i = this.reader.getCursor();
++
+ this.reader.expect('#');
+ this.suggestions = this::suggestTag;
+- ResourceLocation resourceLocation = ResourceLocation.read(this.reader);
+- this.tag = this.blocks.get(TagKey.create(Registries.BLOCK, resourceLocation)).orElseThrow(() -> {
+- this.reader.setCursor(cursor);
+- return ERROR_UNKNOWN_TAG.createWithContext(this.reader, resourceLocation.toString());
++ ResourceLocation minecraftkey = ResourceLocation.read(this.reader);
++
++ this.tag = (HolderSet) this.blocks.get(TagKey.create(Registries.BLOCK, minecraftkey)).orElseThrow(() -> {
++ this.reader.setCursor(i);
++ return BlockStateParser.ERROR_UNKNOWN_TAG.createWithContext(this.reader, minecraftkey.toString());
+ });
+ }
+ }
+@@ -382,51 +420,60 @@
+ this.suggestions = this::suggestPropertyNameOrEnd;
+ this.reader.skipWhitespace();
+
+- while (this.reader.canRead() && this.reader.peek() != ']') {
+- this.reader.skipWhitespace();
+- int cursor = this.reader.getCursor();
+- String string = this.reader.readString();
+- Property<?> property = this.definition.getProperty(string);
+- if (property == null) {
+- this.reader.setCursor(cursor);
+- throw ERROR_UNKNOWN_PROPERTY.createWithContext(this.reader, this.id.toString(), string);
+- }
++ while (true) {
++ if (this.reader.canRead() && this.reader.peek() != ']') {
++ this.reader.skipWhitespace();
++ int i = this.reader.getCursor();
++ String s = this.reader.readString();
++ Property<?> iblockstate = this.definition.getProperty(s);
+
+- if (this.properties.containsKey(property)) {
+- this.reader.setCursor(cursor);
+- throw ERROR_DUPLICATE_PROPERTY.createWithContext(this.reader, this.id.toString(), string);
+- }
++ if (iblockstate == null) {
++ this.reader.setCursor(i);
++ throw BlockStateParser.ERROR_UNKNOWN_PROPERTY.createWithContext(this.reader, this.id.toString(), s);
++ }
+
+- this.reader.skipWhitespace();
+- this.suggestions = this::suggestEquals;
+- if (!this.reader.canRead() || this.reader.peek() != '=') {
+- throw ERROR_EXPECTED_VALUE.createWithContext(this.reader, this.id.toString(), string);
+- }
++ if (this.properties.containsKey(iblockstate)) {
++ this.reader.setCursor(i);
++ throw BlockStateParser.ERROR_DUPLICATE_PROPERTY.createWithContext(this.reader, this.id.toString(), s);
++ }
+
+- this.reader.skip();
+- this.reader.skipWhitespace();
+- this.suggestions = builder -> addSuggestions(builder, property).buildFuture();
+- int cursor1 = this.reader.getCursor();
+- this.setValue(property, this.reader.readString(), cursor1);
+- this.suggestions = this::suggestNextPropertyOrEnd;
+- this.reader.skipWhitespace();
+- if (this.reader.canRead()) {
+- if (this.reader.peek() != ',') {
+- if (this.reader.peek() != ']') {
+- throw ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
+- }
+- break;
++ this.reader.skipWhitespace();
++ this.suggestions = this::suggestEquals;
++ if (!this.reader.canRead() || this.reader.peek() != '=') {
++ throw BlockStateParser.ERROR_EXPECTED_VALUE.createWithContext(this.reader, this.id.toString(), s);
+ }
+
+ this.reader.skip();
+- this.suggestions = this::suggestPropertyName;
++ this.reader.skipWhitespace();
++ this.suggestions = (suggestionsbuilder) -> {
++ return addSuggestions(suggestionsbuilder, iblockstate).buildFuture();
++ };
++ int j = this.reader.getCursor();
++
++ this.setValue(iblockstate, this.reader.readString(), j);
++ this.suggestions = this::suggestNextPropertyOrEnd;
++ this.reader.skipWhitespace();
++ if (!this.reader.canRead()) {
++ continue;
++ }
++
++ if (this.reader.peek() == ',') {
++ this.reader.skip();
++ this.suggestions = this::suggestPropertyName;
++ continue;
++ }
++
++ if (this.reader.peek() != ']') {
++ throw BlockStateParser.ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
++ }
+ }
+- }
+
+- if (this.reader.canRead()) {
+- this.reader.skip();
+- } else {
+- throw ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
++ if (this.reader.canRead()) {
++ this.reader.skip();
++ return;
++ }
++
++ throw BlockStateParser.ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
+ }
+ }
+
+@@ -434,100 +481,117 @@
+ this.reader.skip();
+ this.suggestions = this::suggestVaguePropertyNameOrEnd;
+ int i = -1;
++
+ this.reader.skipWhitespace();
+
+- while (this.reader.canRead() && this.reader.peek() != ']') {
+- this.reader.skipWhitespace();
+- int cursor = this.reader.getCursor();
+- String string = this.reader.readString();
+- if (this.vagueProperties.containsKey(string)) {
+- this.reader.setCursor(cursor);
+- throw ERROR_DUPLICATE_PROPERTY.createWithContext(this.reader, this.id.toString(), string);
+- }
++ while (true) {
++ if (this.reader.canRead() && this.reader.peek() != ']') {
++ this.reader.skipWhitespace();
++ int j = this.reader.getCursor();
++ String s = this.reader.readString();
+
+- this.reader.skipWhitespace();
+- if (!this.reader.canRead() || this.reader.peek() != '=') {
+- this.reader.setCursor(cursor);
+- throw ERROR_EXPECTED_VALUE.createWithContext(this.reader, this.id.toString(), string);
+- }
++ if (this.vagueProperties.containsKey(s)) {
++ this.reader.setCursor(j);
++ throw BlockStateParser.ERROR_DUPLICATE_PROPERTY.createWithContext(this.reader, this.id.toString(), s);
++ }
+
+- this.reader.skip();
+- this.reader.skipWhitespace();
+- this.suggestions = builder -> this.suggestVaguePropertyValue(builder, string);
+- i = this.reader.getCursor();
+- String string1 = this.reader.readString();
+- this.vagueProperties.put(string, string1);
+- this.reader.skipWhitespace();
+- if (this.reader.canRead()) {
++ this.reader.skipWhitespace();
++ if (!this.reader.canRead() || this.reader.peek() != '=') {
++ this.reader.setCursor(j);
++ throw BlockStateParser.ERROR_EXPECTED_VALUE.createWithContext(this.reader, this.id.toString(), s);
++ }
++
++ this.reader.skip();
++ this.reader.skipWhitespace();
++ this.suggestions = (suggestionsbuilder) -> {
++ return this.suggestVaguePropertyValue(suggestionsbuilder, s);
++ };
++ i = this.reader.getCursor();
++ String s1 = this.reader.readString();
++
++ this.vagueProperties.put(s, s1);
++ this.reader.skipWhitespace();
++ if (!this.reader.canRead()) {
++ continue;
++ }
++
+ i = -1;
+- if (this.reader.peek() != ',') {
+- if (this.reader.peek() != ']') {
+- throw ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
+- }
+- break;
++ if (this.reader.peek() == ',') {
++ this.reader.skip();
++ this.suggestions = this::suggestVaguePropertyName;
++ continue;
+ }
+
++ if (this.reader.peek() != ']') {
++ throw BlockStateParser.ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
++ }
++ }
++
++ if (this.reader.canRead()) {
+ this.reader.skip();
+- this.suggestions = this::suggestVaguePropertyName;
++ return;
+ }
+- }
+
+- if (this.reader.canRead()) {
+- this.reader.skip();
+- } else {
+ if (i >= 0) {
+ this.reader.setCursor(i);
+ }
+
+- throw ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
++ throw BlockStateParser.ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
+ }
+ }
+
+ private void readNbt() throws CommandSyntaxException {
+- this.nbt = new TagParser(this.reader).readStruct();
++ this.nbt = (new TagParser(this.reader)).readStruct();
+ }
+
+ private <T extends Comparable<T>> void setValue(Property<T> property, String value, int valuePosition) throws CommandSyntaxException {
+- Optional<T> value1 = property.getValue(value);
+- if (value1.isPresent()) {
+- this.state = this.state.setValue(property, value1.get());
+- this.properties.put(property, value1.get());
++ Optional<T> optional = property.getValue(value);
++
++ if (optional.isPresent()) {
++ this.state = (IBlockData) this.state.setValue(property, (T) optional.get()); // CraftBukkit - decompile error
++ this.properties.put(property, (Comparable) optional.get());
+ } else {
+ this.reader.setCursor(valuePosition);
+- throw ERROR_INVALID_VALUE.createWithContext(this.reader, this.id.toString(), property.getName(), value);
++ throw BlockStateParser.ERROR_INVALID_VALUE.createWithContext(this.reader, this.id.toString(), property.getName(), value);
+ }
+ }
+
+- public static String serialize(BlockState state) {
+- StringBuilder stringBuilder = new StringBuilder(state.getBlockHolder().unwrapKey().map(blockKey -> blockKey.location().toString()).orElse("air"));
++ public static String serialize(IBlockData state) {
++ StringBuilder stringbuilder = new StringBuilder((String) state.getBlockHolder().unwrapKey().map((resourcekey) -> {
++ return resourcekey.location().toString();
++ }).orElse("air"));
++
+ if (!state.getProperties().isEmpty()) {
+- stringBuilder.append('[');
++ stringbuilder.append('[');
+ boolean flag = false;
+
+- for (Entry<Property<?>, Comparable<?>> entry : state.getValues().entrySet()) {
++ for (UnmodifiableIterator unmodifiableiterator = state.getValues().entrySet().iterator(); unmodifiableiterator.hasNext(); flag = true) {
++ Entry<Property<?>, Comparable<?>> entry = (Entry) unmodifiableiterator.next();
++
+ if (flag) {
+- stringBuilder.append(',');
++ stringbuilder.append(',');
+ }
+
+- appendProperty(stringBuilder, entry.getKey(), entry.getValue());
+- flag = true;
++ appendProperty(stringbuilder, (Property) entry.getKey(), (Comparable) entry.getValue());
+ }
+
+- stringBuilder.append(']');
++ stringbuilder.append(']');
+ }
+
+- return stringBuilder.toString();
++ return stringbuilder.toString();
+ }
+
+ private static <T extends Comparable<T>> void appendProperty(StringBuilder builder, Property<T> property, Comparable<?> value) {
+ builder.append(property.getName());
+ builder.append('=');
+- builder.append(property.getName((T)value));
++ builder.append(property.getName((T) value)); // CraftBukkit - decompile error
+ }
+
+- public static record BlockResult(BlockState blockState, Map<Property<?>, Comparable<?>> properties, @Nullable CompoundTag nbt) {
++ public static record a(IBlockData blockState, Map<Property<?>, Comparable<?>> properties, @Nullable CompoundTag nbt) {
++
+ }
+
+- public static record TagResult(HolderSet<Block> tag, Map<String, String> vagueProperties, @Nullable CompoundTag nbt) {
++ public static record b(HolderSet<Block> tag, Map<String, String> vagueProperties, @Nullable CompoundTag nbt) {
++
+ }
+ }