cssc: more parsers

This commit is contained in:
Bixilon 2020-12-25 11:36:59 +01:00
parent c84aea6c56
commit 73f95a4cc0
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
32 changed files with 627 additions and 28 deletions

View File

@ -77,7 +77,7 @@ public class Configuration {
Account account = switch (data.get("type").getAsString()) { Account account = switch (data.get("type").getAsString()) {
case "mojang" -> MojangAccount.deserialize(data); case "mojang" -> MojangAccount.deserialize(data);
case "offline" -> OfflineAccount.deserialize(data); case "offline" -> OfflineAccount.deserialize(data);
default -> throw new IllegalStateException("Unexpected value: " + data.get("type").getAsString()); default -> throw new IllegalArgumentException("Unexpected value: " + data.get("type").getAsString());
}; };
this.accountList.put(account.getId(), account); this.accountList.put(account.getId(), account);
} }

View File

@ -48,7 +48,7 @@ public class CommandArgumentNode extends CommandLiteralNode {
case "minecraft:available_sounds" -> CommandArgumentNode.SuggestionTypes.AVAILABLE_SOUNDS; case "minecraft:available_sounds" -> CommandArgumentNode.SuggestionTypes.AVAILABLE_SOUNDS;
case "minecraft:summonable_entities" -> CommandArgumentNode.SuggestionTypes.SUMMONABLE_ENTITIES; case "minecraft:summonable_entities" -> CommandArgumentNode.SuggestionTypes.SUMMONABLE_ENTITIES;
case "minecraft:available_biomes" -> CommandArgumentNode.SuggestionTypes.AVAILABLE_BIOMES; case "minecraft:available_biomes" -> CommandArgumentNode.SuggestionTypes.AVAILABLE_BIOMES;
default -> throw new IllegalStateException("Unexpected value: " + fullIdentifier); default -> throw new IllegalArgumentException("Unexpected value: " + fullIdentifier);
}; };
} else { } else {
this.suggestionType = null; this.suggestionType = null;

View File

@ -14,8 +14,8 @@
package de.bixilon.minosoft.data.commands; package de.bixilon.minosoft.data.commands;
import de.bixilon.minosoft.data.commands.parser.exceptions.BooleanCommandParseException; import de.bixilon.minosoft.data.commands.parser.exceptions.BooleanCommandParseException;
import de.bixilon.minosoft.data.commands.parser.exceptions.InvalidIdentifierCommandParseException;
import de.bixilon.minosoft.data.commands.parser.exceptions.StringCommandParseException; import de.bixilon.minosoft.data.commands.parser.exceptions.StringCommandParseException;
import de.bixilon.minosoft.data.commands.parser.exceptions.identifier.InvalidIdentifierCommandParseException;
import de.bixilon.minosoft.data.commands.parser.exceptions.number.DoubleCommandParseException; import de.bixilon.minosoft.data.commands.parser.exceptions.number.DoubleCommandParseException;
import de.bixilon.minosoft.data.commands.parser.exceptions.number.FloatCommandParseException; import de.bixilon.minosoft.data.commands.parser.exceptions.number.FloatCommandParseException;
import de.bixilon.minosoft.data.commands.parser.exceptions.number.IntegerCommandParseException; import de.bixilon.minosoft.data.commands.parser.exceptions.number.IntegerCommandParseException;
@ -24,6 +24,8 @@ import de.bixilon.minosoft.data.commands.parser.exceptions.properties.BadPropert
import de.bixilon.minosoft.data.commands.parser.exceptions.properties.DuplicatedPropertyKeyCommandParseException; import de.bixilon.minosoft.data.commands.parser.exceptions.properties.DuplicatedPropertyKeyCommandParseException;
import de.bixilon.minosoft.data.mappings.ModIdentifier; import de.bixilon.minosoft.data.mappings.ModIdentifier;
import de.bixilon.minosoft.util.Pair; import de.bixilon.minosoft.util.Pair;
import de.bixilon.minosoft.util.nbt.tag.CompoundTag;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -32,11 +34,11 @@ public class CommandStringReader {
private final String string; private final String string;
private int cursor; private int cursor;
public CommandStringReader(String string) { public CommandStringReader(@NotNull String string) {
this.string = string; this.string = string;
} }
public CommandStringReader(CommandStringReader stringReader) { public CommandStringReader(@NotNull CommandStringReader stringReader) {
this.string = stringReader.string; this.string = stringReader.string;
this.cursor = stringReader.cursor; this.cursor = stringReader.cursor;
} }
@ -105,6 +107,7 @@ public class CommandStringReader {
return skipped; return skipped;
} }
@NotNull
public String readUnquotedString() { public String readUnquotedString() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
while (canRead()) { while (canRead()) {
@ -119,6 +122,7 @@ public class CommandStringReader {
return builder.toString(); return builder.toString();
} }
@NotNull
public String readQuotedString() throws StringCommandParseException { public String readQuotedString() throws StringCommandParseException {
if (!canRead() || !peekExpected('"', '\'')) { if (!canRead() || !peekExpected('"', '\'')) {
throw new StringCommandParseException(this, String.valueOf(peek()), "String is not quoted!"); throw new StringCommandParseException(this, String.valueOf(peek()), "String is not quoted!");
@ -126,6 +130,7 @@ public class CommandStringReader {
return readStringUntil(read()); return readStringUntil(read());
} }
@NotNull
public String readNumericString() { public String readNumericString() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
while (canRead()) { while (canRead()) {
@ -140,6 +145,7 @@ public class CommandStringReader {
return builder.toString(); return builder.toString();
} }
@NotNull
public Pair<String, String> readProperty() throws StringCommandParseException, BadPropertyMapCommandParseException { public Pair<String, String> readProperty() throws StringCommandParseException, BadPropertyMapCommandParseException {
skipWhitespaces(); skipWhitespaces();
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
@ -154,6 +160,7 @@ public class CommandStringReader {
return new Pair<>(key, value); return new Pair<>(key, value);
} }
@NotNull
public Map<String, String> readProperties() throws StringCommandParseException, DuplicatedPropertyKeyCommandParseException, BadPropertyMapCommandParseException { public Map<String, String> readProperties() throws StringCommandParseException, DuplicatedPropertyKeyCommandParseException, BadPropertyMapCommandParseException {
Map<String, String> ret = new HashMap<>(); Map<String, String> ret = new HashMap<>();
if (peek() != '[') { if (peek() != '[') {
@ -180,6 +187,7 @@ public class CommandStringReader {
return ret; return ret;
} }
@NotNull
public Pair<String, ModIdentifier> readModIdentifier() throws InvalidIdentifierCommandParseException { public Pair<String, ModIdentifier> readModIdentifier() throws InvalidIdentifierCommandParseException {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
while (canRead()) { while (canRead()) {
@ -199,6 +207,7 @@ public class CommandStringReader {
} }
} }
@NotNull
public String readString() throws StringCommandParseException { public String readString() throws StringCommandParseException {
if (!canRead()) { if (!canRead()) {
return ""; return "";
@ -219,10 +228,12 @@ public class CommandStringReader {
return false; return false;
} }
@NotNull
private String readStringUntil(boolean requiresTerminator, char terminator) throws StringCommandParseException { private String readStringUntil(boolean requiresTerminator, char terminator) throws StringCommandParseException {
return readStringUntil(requiresTerminator, new char[]{terminator}).getKey(); return readStringUntil(requiresTerminator, new char[]{terminator}).getKey();
} }
@NotNull
private Pair<String, Character> readStringUntil(boolean requiresTerminator, char... terminators) throws StringCommandParseException { private Pair<String, Character> readStringUntil(boolean requiresTerminator, char... terminators) throws StringCommandParseException {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
boolean isNextCharEscaped = false; boolean isNextCharEscaped = false;
@ -297,6 +308,7 @@ public class CommandStringReader {
} }
} }
@NotNull
public Pair<String, Character> readStringUntilOrEnd(char... terminators) { public Pair<String, Character> readStringUntilOrEnd(char... terminators) {
try { try {
return readStringUntil(false, terminators); return readStringUntil(false, terminators);
@ -306,10 +318,12 @@ public class CommandStringReader {
} }
} }
@NotNull
public Pair<String, Character> readStringUntil(char... terminators) throws StringCommandParseException { public Pair<String, Character> readStringUntil(char... terminators) throws StringCommandParseException {
return readStringUntil(true, terminators); return readStringUntil(true, terminators);
} }
@NotNull
public String readStringUntilOrEnd(char terminator) { public String readStringUntilOrEnd(char terminator) {
try { try {
return readStringUntil(false, terminator); return readStringUntil(false, terminator);
@ -319,26 +333,34 @@ public class CommandStringReader {
} }
} }
@NotNull
public String readStringUntil(char terminator) throws StringCommandParseException { public String readStringUntil(char terminator) throws StringCommandParseException {
return readStringUntil(true, terminator); return readStringUntil(true, terminator);
} }
public CompoundTag readNBTCompoundTag() {
throw new IllegalArgumentException("TODO");
}
public boolean readExpected(char... expected) { public boolean readExpected(char... expected) {
boolean ret = peekExpected(expected); boolean ret = peekExpected(expected);
skip(); skip();
return ret; return ret;
} }
@NotNull
public String readRemaining() { public String readRemaining() {
String ret = this.string.substring(this.cursor); String ret = this.string.substring(this.cursor);
this.cursor = this.string.length() + 1; this.cursor = this.string.length() + 1;
return ret; return ret;
} }
@NotNull
public String peekRemaining() { public String peekRemaining() {
return this.string.substring(this.cursor); return this.string.substring(this.cursor);
} }
@NotNull
public String getString() { public String getString() {
return this.string; return this.string;
} }

View File

@ -0,0 +1,30 @@
/*
* Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.commands.parser
import de.bixilon.minosoft.data.commands.CommandStringReader
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException
import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties
import de.bixilon.minosoft.protocol.network.Connection
class AngleParser : CoordinateParser() {
@Throws(CommandParseException::class)
override fun isParsable(connection: Connection, properties: ParserProperties?, stringReader: CommandStringReader) {
readCoordinates(stringReader, true, 1)
}
companion object {
val ANGLE_PARSER = AngleParser()
}
}

View File

@ -0,0 +1,37 @@
/*
* Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.commands.parser
import de.bixilon.minosoft.data.commands.CommandStringReader
import de.bixilon.minosoft.data.commands.parser.exceptions.ColorNotFoundCommandParseException
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException
import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties
import de.bixilon.minosoft.data.text.ChatColors
import de.bixilon.minosoft.protocol.network.Connection
class ColorParser : CommandParser() {
@Throws(CommandParseException::class)
override fun isParsable(connection: Connection, properties: ParserProperties?, stringReader: CommandStringReader) {
val color = stringReader.readUnquotedString()
try {
ChatColors.getChatFormattingByName(color)
} catch (exception: IllegalArgumentException) {
throw ColorNotFoundCommandParseException(stringReader, color, exception)
}
}
companion object {
val COLOR_PARSER = ColorParser()
}
}

View File

@ -25,8 +25,9 @@ object CommandParsers {
ModIdentifier("brigadier:float") to FloatParser.FLOAT_PARSER, ModIdentifier("brigadier:float") to FloatParser.FLOAT_PARSER,
ModIdentifier("brigadier:integer") to IntegerParser.INTEGER_PARSER, ModIdentifier("brigadier:integer") to IntegerParser.INTEGER_PARSER,
ModIdentifier("brigadier:string") to StringParser.STRING_PARSER, ModIdentifier("brigadier:string") to StringParser.STRING_PARSER,
ModIdentifier("angle") to AngleParser.ANGLE_PARSER,
ModIdentifier("entity") to EntityParser.ENTITY_PARSER, ModIdentifier("entity") to EntityParser.ENTITY_PARSER,
// game_profile ModIdentifier("game_profile") to GameProfileParser.GAME_PROFILE_PARSER,
ModIdentifier("block_pos") to BlockPositionParser.BLOCK_POSITION_PARSER, ModIdentifier("block_pos") to BlockPositionParser.BLOCK_POSITION_PARSER,
ModIdentifier("column_pos") to ColumnPositionParser.COLUMN_POSITION_PARSER, ModIdentifier("column_pos") to ColumnPositionParser.COLUMN_POSITION_PARSER,
ModIdentifier("vec3") to Vec3Parser.VEC3_PARSER, ModIdentifier("vec3") to Vec3Parser.VEC3_PARSER,
@ -35,21 +36,21 @@ object CommandParsers {
// block_predicate // block_predicate
ModIdentifier("item_stack") to ItemStackParser.ITEM_STACK_PARSER, ModIdentifier("item_stack") to ItemStackParser.ITEM_STACK_PARSER,
// item_predicate // item_predicate
// color ModIdentifier("color") to ColorParser.COLOR_PARSER,
// chat component // chat component
ModIdentifier("message") to MessageParser.MESSAGE_PARSER, ModIdentifier("message") to MessageParser.MESSAGE_PARSER,
// nbt // nbt
// nbt_pat // nbt_path
ModIdentifier("objective") to ObjectiveParser.OBJECTIVE_PARSER, ModIdentifier("objective") to ObjectiveParser.OBJECTIVE_PARSER,
// objective_criteria // objective_criteria
// operation ModIdentifier("operation") to OperationParser.OPERATION_PARSER,
// particle // particle
// rotation ModIdentifier("rotation") to RotationParser.ROTATION_PARSER,
// scoreboard_slot ModIdentifier("scoreboard_slot") to ScoreboardSlotParser.SCOREBOARD_SLOT_PARSER,
ModIdentifier("score_holder") to ScoreHolderParser.SCORE_HOLDER_PARSER, ModIdentifier("score_holder") to ScoreHolderParser.SCORE_HOLDER_PARSER,
// swizzle ModIdentifier("swizzle") to SwizzleParser.SWIZZLE_PARSER,
// team ModIdentifier("team") to TeamParser.TEAM_PARSER,
// item_slot ModIdentifier("item_slot") to ItemSlotParser.ITEM_SLOT_PARSER,
ModIdentifier("resource_location") to IdentifierParser.IDENTIFIER_PARSER, ModIdentifier("resource_location") to IdentifierParser.IDENTIFIER_PARSER,
ModIdentifier("mob_effect") to IdentifierListParser.MOB_EFFECT_PARSER, ModIdentifier("mob_effect") to IdentifierListParser.MOB_EFFECT_PARSER,
// function // function
@ -58,8 +59,8 @@ object CommandParsers {
ModIdentifier("int_range") to IntRangeParser.INT_RANGE_PARSER, ModIdentifier("int_range") to IntRangeParser.INT_RANGE_PARSER,
ModIdentifier("float_range") to FloatRangeParser.FLOAT_RANGE_PARSER, ModIdentifier("float_range") to FloatRangeParser.FLOAT_RANGE_PARSER,
ModIdentifier("item_enchantment") to IdentifierListParser.ENCHANTMENT_PARSER, ModIdentifier("item_enchantment") to IdentifierListParser.ENCHANTMENT_PARSER,
// entity_summon ModIdentifier("entity_summon") to IdentifierListParser.SUMMONABLE_ENTITY_PARSER,
// dimension ModIdentifier("dimension") to IdentifierListParser.DIMENSION_EFFECT_PARSER,
ModIdentifier("uuid") to UUIDParser.UUID_PARSER, ModIdentifier("uuid") to UUIDParser.UUID_PARSER,
// nbt_tag // nbt_tag
// nbt_compound_tag // nbt_compound_tag

View File

@ -0,0 +1,36 @@
/*
* Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.commands.parser
import de.bixilon.minosoft.data.commands.CommandStringReader
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException
import de.bixilon.minosoft.data.commands.parser.properties.EntityParserProperties
import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties
import de.bixilon.minosoft.protocol.network.Connection
import de.bixilon.minosoft.protocol.protocol.InByteBuffer
class GameProfileParser(val properties: EntityParserProperties) : EntityParser() {
override fun readParserProperties(buffer: InByteBuffer?): ParserProperties? {
return null
}
@Throws(CommandParseException::class)
override fun isParsable(connection: Connection, properties: ParserProperties?, stringReader: CommandStringReader) {
super.isParsable(connection, properties, stringReader)
}
companion object {
val GAME_PROFILE_PARSER = GameProfileParser(EntityParserProperties(false, false)) // ToDo own parser?
}
}

View File

@ -12,10 +12,13 @@
*/ */
package de.bixilon.minosoft.data.commands.parser package de.bixilon.minosoft.data.commands.parser
import de.bixilon.minosoft.data.EntityClassMappings
import de.bixilon.minosoft.data.commands.CommandStringReader import de.bixilon.minosoft.data.commands.CommandStringReader
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException
import de.bixilon.minosoft.data.commands.parser.exceptions.EnchantmentNotFoundCommandParseException import de.bixilon.minosoft.data.commands.parser.exceptions.identifier.DimensionNotFoundCommandParseException
import de.bixilon.minosoft.data.commands.parser.exceptions.MobEffectNotFoundCommandParseException import de.bixilon.minosoft.data.commands.parser.exceptions.identifier.EnchantmentNotFoundCommandParseException
import de.bixilon.minosoft.data.commands.parser.exceptions.identifier.EntityNotFoundCommandParseException
import de.bixilon.minosoft.data.commands.parser.exceptions.identifier.MobEffectNotFoundCommandParseException
import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties
import de.bixilon.minosoft.protocol.network.Connection import de.bixilon.minosoft.protocol.network.Connection
@ -38,10 +41,26 @@ class IdentifierListParser : CommandParser() {
} }
return return
} }
if (this == DIMENSION_EFFECT_PARSER) {
if (!connection.mapping.doesDimensionExist(identifier.value)) {
throw DimensionNotFoundCommandParseException(stringReader, identifier.key)
}
return
}
if (this == SUMMONABLE_ENTITY_PARSER) {
// ToDo: only summonable entities, not all of them
if (EntityClassMappings.getByIdentifier(identifier.value) == null) {
throw EntityNotFoundCommandParseException(stringReader, identifier.key)
}
return
}
} }
companion object { companion object {
val ENCHANTMENT_PARSER = IdentifierListParser() val ENCHANTMENT_PARSER = IdentifierListParser()
val MOB_EFFECT_PARSER = IdentifierListParser() val MOB_EFFECT_PARSER = IdentifierListParser()
val DIMENSION_EFFECT_PARSER = IdentifierListParser()
val SUMMONABLE_ENTITY_PARSER = IdentifierListParser()
} }
} }

View File

@ -0,0 +1,61 @@
/*
* Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.commands.parser
import de.bixilon.minosoft.data.commands.CommandStringReader
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException
import de.bixilon.minosoft.data.commands.parser.exceptions.UnknownInventorySlotCommandParseException
import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties
import de.bixilon.minosoft.protocol.network.Connection
class ItemSlotParser : CommandParser() {
@Throws(CommandParseException::class)
override fun isParsable(connection: Connection, properties: ParserProperties?, stringReader: CommandStringReader) {
val slot = stringReader.readUnquotedString()
if (!SLOTS.contains(slot)) {
throw UnknownInventorySlotCommandParseException(stringReader, slot)
}
}
companion object {
private val SLOTS = HashSet<String>()
init {
for (i in 0 until 54) {
SLOTS.add("container.$i")
}
for (i in 0 until 9) {
SLOTS.add("hotbar.$i")
}
for (i in 0 until 27) {
SLOTS.add("inventory." + (9 + i))
}
for (i in 0 until 27) {
SLOTS.add("enderchest." + (200 + i))
}
for (i in 0 until 8) {
SLOTS.add("villager." + (300 + i))
}
for (i in 0 until 15) {
SLOTS.add("horse." + (500 + i))
}
SLOTS.addAll(setOf("weapon", "weapon.mainhand", "weapon.offhand", "armor.head", "armor.chest", "armor.legs", "armor.feet", "horse.saddle", "horse.armor", "horse.chest"))
}
val ITEM_SLOT_PARSER = ItemSlotParser()
}
}

View File

@ -14,7 +14,7 @@ package de.bixilon.minosoft.data.commands.parser
import de.bixilon.minosoft.data.commands.CommandStringReader import de.bixilon.minosoft.data.commands.CommandStringReader
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException
import de.bixilon.minosoft.data.commands.parser.exceptions.ItemNotFoundCommandParseException import de.bixilon.minosoft.data.commands.parser.exceptions.identifier.ItemNotFoundCommandParseException
import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties
import de.bixilon.minosoft.protocol.network.Connection import de.bixilon.minosoft.protocol.network.Connection
@ -27,7 +27,7 @@ class ItemStackParser : CommandParser() {
throw ItemNotFoundCommandParseException(stringReader, argument.key) throw ItemNotFoundCommandParseException(stringReader, argument.key)
} }
if (stringReader.peek() == '{') { if (stringReader.peek() == '{') {
throw TODO("NBT Data needs to be implemented") stringReader.readNBTCompoundTag()
} }
} }

View File

@ -14,7 +14,7 @@ package de.bixilon.minosoft.data.commands.parser
import de.bixilon.minosoft.data.commands.CommandStringReader import de.bixilon.minosoft.data.commands.CommandStringReader
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException
import de.bixilon.minosoft.data.commands.parser.exceptions.InvalidIdentifierCommandParseException import de.bixilon.minosoft.data.commands.parser.exceptions.identifier.InvalidIdentifierCommandParseException
import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties
import de.bixilon.minosoft.protocol.network.Connection import de.bixilon.minosoft.protocol.network.Connection
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition

View File

@ -0,0 +1,37 @@
/*
* Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.commands.parser
import de.bixilon.minosoft.data.commands.CommandStringReader
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException
import de.bixilon.minosoft.data.commands.parser.exceptions.UnknownOperationCommandParseException
import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties
import de.bixilon.minosoft.protocol.network.Connection
class OperationParser : CommandParser() {
@Throws(CommandParseException::class)
override fun isParsable(connection: Connection, properties: ParserProperties?, stringReader: CommandStringReader) {
val operation = stringReader.readUnquotedString()
if (!OPERATIONS.contains(operation)) {
throw UnknownOperationCommandParseException(stringReader, operation)
}
}
companion object {
private val OPERATIONS = setOf("=", "+=", "-=", "*=", "/=", "%=", "<", ">", "><")
val OPERATION_PARSER = OperationParser()
}
}

View File

@ -0,0 +1,30 @@
/*
* Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.commands.parser
import de.bixilon.minosoft.data.commands.CommandStringReader
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException
import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties
import de.bixilon.minosoft.protocol.network.Connection
class RotationParser : CoordinateParser() {
@Throws(CommandParseException::class)
override fun isParsable(connection: Connection, properties: ParserProperties?, stringReader: CommandStringReader) {
readCoordinates(stringReader, true, 2)
}
companion object {
val ROTATION_PARSER = RotationParser()
}
}

View File

@ -0,0 +1,49 @@
/*
* Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.commands.parser
import de.bixilon.minosoft.data.commands.CommandStringReader
import de.bixilon.minosoft.data.commands.parser.exceptions.ColorNotFoundCommandParseException
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException
import de.bixilon.minosoft.data.commands.parser.exceptions.UnknownOperationCommandParseException
import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties
import de.bixilon.minosoft.data.text.ChatColors
import de.bixilon.minosoft.protocol.network.Connection
class ScoreboardSlotParser : CommandParser() {
@Throws(CommandParseException::class)
override fun isParsable(connection: Connection, properties: ParserProperties?, stringReader: CommandStringReader) {
val slot = stringReader.readUnquotedString()
if (slot.startsWith("sidebar.team.")) {
val color = slot.substring("sidebar.team.".length)
try {
ChatColors.getChatFormattingByName(color)
} catch (exception: IllegalArgumentException) {
throw ColorNotFoundCommandParseException(stringReader, color)
}
return
}
if (!SCOREBOARD_SLOTS.contains(slot)) {
throw UnknownOperationCommandParseException(stringReader, slot)
}
}
companion object {
private val SCOREBOARD_SLOTS = setOf("list", "sidebar", "belowName")
val SCOREBOARD_SLOT_PARSER = ScoreboardSlotParser()
}
}

View File

@ -0,0 +1,46 @@
/*
* Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.commands.parser
import de.bixilon.minosoft.data.commands.CommandStringReader
import de.bixilon.minosoft.data.commands.parser.exceptions.BadSwizzleCombinationCommandParseException
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException
import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties
import de.bixilon.minosoft.protocol.network.Connection
class SwizzleParser : CommandParser() {
@Throws(CommandParseException::class)
override fun isParsable(connection: Connection, properties: ParserProperties?, stringReader: CommandStringReader) {
val swizzle = stringReader.readUnquotedString()
val containing: HashSet<Char> = HashSet()
for (char in swizzle.toCharArray()) {
when (char) {
'x', 'y', 'z' -> {
if (containing.contains(char)) {
throw BadSwizzleCombinationCommandParseException(stringReader, swizzle)
}
containing.add(char)
}
else -> throw BadSwizzleCombinationCommandParseException(stringReader, swizzle)
}
}
}
companion object {
val SWIZZLE_PARSER = SwizzleParser()
}
}

View File

@ -0,0 +1,30 @@
/*
* Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.commands.parser
import de.bixilon.minosoft.data.commands.CommandStringReader
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException
import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties
import de.bixilon.minosoft.protocol.network.Connection
class TeamParser : CommandParser() {
@Throws(CommandParseException::class)
override fun isParsable(connection: Connection, properties: ParserProperties?, stringReader: CommandStringReader) {
stringReader.readUnquotedString()
}
companion object {
val TEAM_PARSER = TeamParser()
}
}

View File

@ -0,0 +1,25 @@
/*
* Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.commands.parser.exceptions
import de.bixilon.minosoft.data.commands.CommandStringReader
class BadSwizzleCombinationCommandParseException : CommandParseException {
constructor(command: CommandStringReader, currentArgument: String) : super(ERROR_MESSAGE, command, currentArgument)
constructor(command: CommandStringReader, currentArgument: String, cause: Throwable) : super(ERROR_MESSAGE, command, currentArgument, cause)
companion object {
private const val ERROR_MESSAGE = "Bad combination (use x, y and/or z)!"
}
}

View File

@ -0,0 +1,25 @@
/*
* Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.commands.parser.exceptions
import de.bixilon.minosoft.data.commands.CommandStringReader
class ColorNotFoundCommandParseException : CommandParseException {
constructor(command: CommandStringReader, currentArgument: String) : super(ERROR_MESSAGE, command, currentArgument)
constructor(command: CommandStringReader, currentArgument: String, cause: Throwable) : super(ERROR_MESSAGE, command, currentArgument, cause)
companion object {
private const val ERROR_MESSAGE = "Unknown color!"
}
}

View File

@ -0,0 +1,25 @@
/*
* Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.commands.parser.exceptions
import de.bixilon.minosoft.data.commands.CommandStringReader
class UnknownInventorySlotCommandParseException : CommandParseException {
constructor(command: CommandStringReader, currentArgument: String) : super(ERROR_MESSAGE, command, currentArgument)
constructor(command: CommandStringReader, currentArgument: String, cause: Throwable) : super(ERROR_MESSAGE, command, currentArgument, cause)
companion object {
private const val ERROR_MESSAGE = "Unknown slot!"
}
}

View File

@ -0,0 +1,25 @@
/*
* Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.commands.parser.exceptions
import de.bixilon.minosoft.data.commands.CommandStringReader
class UnknownOperationCommandParseException : CommandParseException {
constructor(command: CommandStringReader, currentArgument: String) : super(ERROR_MESSAGE, command, currentArgument)
constructor(command: CommandStringReader, currentArgument: String, cause: Throwable) : super(ERROR_MESSAGE, command, currentArgument, cause)
companion object {
private const val ERROR_MESSAGE = "Unknown operation!"
}
}

View File

@ -0,0 +1,26 @@
/*
* Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.commands.parser.exceptions.identifier
import de.bixilon.minosoft.data.commands.CommandStringReader
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException
class DimensionNotFoundCommandParseException : CommandParseException {
constructor(command: CommandStringReader, currentArgument: String) : super(ERROR_MESSAGE, command, currentArgument)
constructor(command: CommandStringReader, currentArgument: String, cause: Throwable) : super(ERROR_MESSAGE, command, currentArgument, cause)
companion object {
private const val ERROR_MESSAGE = "Dimension not found!"
}
}

View File

@ -10,9 +10,10 @@
* *
* This software is not affiliated with Mojang AB, the original developer of Minecraft. * This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/ */
package de.bixilon.minosoft.data.commands.parser.exceptions package de.bixilon.minosoft.data.commands.parser.exceptions.identifier
import de.bixilon.minosoft.data.commands.CommandStringReader import de.bixilon.minosoft.data.commands.CommandStringReader
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException
class EnchantmentNotFoundCommandParseException : CommandParseException { class EnchantmentNotFoundCommandParseException : CommandParseException {
constructor(command: CommandStringReader, currentArgument: String) : super(ERROR_MESSAGE, command, currentArgument) constructor(command: CommandStringReader, currentArgument: String) : super(ERROR_MESSAGE, command, currentArgument)

View File

@ -0,0 +1,26 @@
/*
* Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.commands.parser.exceptions.identifier
import de.bixilon.minosoft.data.commands.CommandStringReader
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException
class EntityNotFoundCommandParseException : CommandParseException {
constructor(command: CommandStringReader, currentArgument: String) : super(ERROR_MESSAGE, command, currentArgument)
constructor(command: CommandStringReader, currentArgument: String, cause: Throwable) : super(ERROR_MESSAGE, command, currentArgument, cause)
companion object {
private const val ERROR_MESSAGE = "Entity not found!"
}
}

View File

@ -10,9 +10,10 @@
* *
* This software is not affiliated with Mojang AB, the original developer of Minecraft. * This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/ */
package de.bixilon.minosoft.data.commands.parser.exceptions package de.bixilon.minosoft.data.commands.parser.exceptions.identifier
import de.bixilon.minosoft.data.commands.CommandStringReader import de.bixilon.minosoft.data.commands.CommandStringReader
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException
class InvalidIdentifierCommandParseException : CommandParseException { class InvalidIdentifierCommandParseException : CommandParseException {
constructor(command: CommandStringReader, currentArgument: String) : super(ERROR_MESSAGE, command, currentArgument) constructor(command: CommandStringReader, currentArgument: String) : super(ERROR_MESSAGE, command, currentArgument)

View File

@ -10,9 +10,10 @@
* *
* This software is not affiliated with Mojang AB, the original developer of Minecraft. * This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/ */
package de.bixilon.minosoft.data.commands.parser.exceptions package de.bixilon.minosoft.data.commands.parser.exceptions.identifier
import de.bixilon.minosoft.data.commands.CommandStringReader import de.bixilon.minosoft.data.commands.CommandStringReader
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException
class ItemNotFoundCommandParseException : CommandParseException { class ItemNotFoundCommandParseException : CommandParseException {
constructor(command: CommandStringReader, currentArgument: String) : super(ERROR_MESSAGE, command, currentArgument) constructor(command: CommandStringReader, currentArgument: String) : super(ERROR_MESSAGE, command, currentArgument)

View File

@ -10,9 +10,10 @@
* *
* This software is not affiliated with Mojang AB, the original developer of Minecraft. * This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/ */
package de.bixilon.minosoft.data.commands.parser.exceptions package de.bixilon.minosoft.data.commands.parser.exceptions.identifier
import de.bixilon.minosoft.data.commands.CommandStringReader import de.bixilon.minosoft.data.commands.CommandStringReader
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException
class MobEffectNotFoundCommandParseException : CommandParseException { class MobEffectNotFoundCommandParseException : CommandParseException {
constructor(command: CommandStringReader, currentArgument: String) : super(ERROR_MESSAGE, command, currentArgument) constructor(command: CommandStringReader, currentArgument: String) : super(ERROR_MESSAGE, command, currentArgument)

View File

@ -26,6 +26,11 @@ public class EntityParserProperties implements ParserProperties {
this.onlyPlayers = BitByte.isBitMask(flags, 0x02); this.onlyPlayers = BitByte.isBitMask(flags, 0x02);
} }
public EntityParserProperties(boolean onlySingleEntity, boolean onlyPlayers) {
this.onlySingleEntity = onlySingleEntity;
this.onlyPlayers = onlyPlayers;
}
public boolean isOnlySingleEntity() { public boolean isOnlySingleEntity() {
return this.onlySingleEntity; return this.onlySingleEntity;
} }

View File

@ -53,7 +53,7 @@ public class BedEntityMetaData extends BlockEntityMetaData {
case 13 -> new RGBColor(77, 97, 34); // green case 13 -> new RGBColor(77, 97, 34); // green
case 14 -> new RGBColor(139, 30, 31); // red case 14 -> new RGBColor(139, 30, 31); // red
case 15 -> new RGBColor(15, 16, 19); // black case 15 -> new RGBColor(15, 16, 19); // black
default -> throw new IllegalStateException("Unexpected value: " + ((IntTag) nbt).getValue()); default -> throw new IllegalArgumentException("Unexpected value: " + ((IntTag) nbt).getValue());
}; };
} }

View File

@ -605,4 +605,14 @@ public class VersionMapping {
} }
return this.mobEffectMap.containsValue(identifier); return this.mobEffectMap.containsValue(identifier);
} }
public boolean doesDimensionExist(ModIdentifier identifier) {
if (this.parentMapping != null) {
if (this.parentMapping.doesDimensionExist(identifier)) {
return true;
}
}
return this.dimensionMap.containsValue(identifier);
}
} }

View File

@ -89,6 +89,10 @@ public final class ChatColors {
} }
public static RGBColor getColorByName(String name) { public static RGBColor getColorByName(String name) {
return (RGBColor) getChatFormattingByName(name);
}
public static ChatCode getChatFormattingByName(String name) {
return switch (name.toLowerCase()) { return switch (name.toLowerCase()) {
case "black" -> BLACK; case "black" -> BLACK;
case "dark_blue" -> DARK_BLUE; case "dark_blue" -> DARK_BLUE;
@ -106,7 +110,12 @@ public final class ChatColors {
case "light_purple" -> LIGHT_PURPLE; case "light_purple" -> LIGHT_PURPLE;
case "yellow" -> YELLOW; case "yellow" -> YELLOW;
case "white", "reset" -> WHITE; case "white", "reset" -> WHITE;
default -> throw new IllegalStateException("Unexpected value: " + name); case "bold" -> PreChatFormattingCodes.BOLD;
case "italic" -> PreChatFormattingCodes.ITALIC;
case "underlined" -> PreChatFormattingCodes.UNDERLINED;
case "strikethrough" -> PreChatFormattingCodes.STRIKETHROUGH;
case "obfuscated" -> PreChatFormattingCodes.OBFUSCATED;
default -> throw new IllegalArgumentException("Unexpected value: " + name);
}; };
} }
} }

View File

@ -15,6 +15,7 @@ package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.data.commands.CommandNode; import de.bixilon.minosoft.data.commands.CommandNode;
import de.bixilon.minosoft.data.commands.CommandRootNode; import de.bixilon.minosoft.data.commands.CommandRootNode;
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException;
import de.bixilon.minosoft.logging.Log; import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.network.Connection; import de.bixilon.minosoft.protocol.network.Connection;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket; import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
@ -37,6 +38,26 @@ public class PacketDeclareCommands extends ClientboundPacket {
@Override @Override
public void handle(Connection connection) { public void handle(Connection connection) {
connection.setCommandRootNode(getRootNode()); connection.setCommandRootNode(getRootNode());
// ToDo: Remove these dummy commands
String[] commands = {
"setblock ~3 ^3 3 minecraft:anvil",
"setblock ~3 3 3 minecraft:anvila",
"setblock ~3 3 3 minecraft:anvil[facing=east]",
"setblock ~3 3 3 minecraft:anvil[facing=\"east\"]",
"setblock ~3 3 3 minecraft:anvil[facing=east\"]",
"setblock ~3 3 3 minecraft:anvil[facing=aeast]",
};
for (String command : commands) {
try {
getRootNode().isSyntaxCorrect(connection, command);
Log.game("Command \"%s\" is valid", command);
} catch (CommandParseException e) {
Log.game("Command \"%s\" is invalid, %s: %s", command, e.getClass().getSimpleName(), e.getErrorMessage());
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
} }
@Override @Override

View File

@ -32,7 +32,7 @@ public class PacketSculkVibrationSignal extends ClientboundPacket {
this.vibrationTargetData = switch (this.vibrationTargetType.getFullIdentifier()) { this.vibrationTargetData = switch (this.vibrationTargetType.getFullIdentifier()) {
case "minecraft:block" -> buffer.readPosition(); // sculk source position case "minecraft:block" -> buffer.readPosition(); // sculk source position
case "minecraft:entity" -> buffer.readEntityId(); case "minecraft:entity" -> buffer.readEntityId();
default -> throw new IllegalStateException("Unexpected value: " + this.vibrationTargetType.getFullIdentifier()); default -> throw new IllegalArgumentException("Unexpected value: " + this.vibrationTargetType.getFullIdentifier());
}; };
this.arrivalTicks = buffer.readVarInt(); this.arrivalTicks = buffer.readVarInt();
return true; return true;