cli: range parser, more entity readers

This commit is contained in:
Bixilon 2022-05-19 15:23:51 +02:00
parent f5f797ff3f
commit b846fc3e02
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
43 changed files with 748 additions and 99 deletions

View File

@ -65,6 +65,6 @@ class LiteralNode : ExecutableNode {
stack.push(name, name)
return super.getSuggestions(reader, stack)
}
return suggester.suggest(literalName) ?: listOf()
return suggester.suggest(literalName) ?: emptyList()
}
}

View File

@ -44,7 +44,7 @@ class DoubleParser(
if (reader.readString()?.isBlank() != false) {
return examples
}
return listOf()
return emptyList()
}
companion object : ArgumentParserFactory<DoubleParser> {

View File

@ -44,7 +44,7 @@ class FloatParser(
if (reader.readString()?.isBlank() != false) {
return examples
}
return listOf()
return emptyList()
}
companion object : ArgumentParserFactory<FloatParser> {

View File

@ -44,7 +44,7 @@ class IntParser(
if (reader.readString()?.isBlank() != false) {
return examples
}
return listOf()
return emptyList()
}
companion object : ArgumentParserFactory<IntParser> {

View File

@ -44,7 +44,7 @@ class LongParser(
if (reader.readString()?.isBlank() != false) {
return examples
}
return listOf()
return emptyList()
}
companion object : ArgumentParserFactory<LongParser> {

View File

@ -27,7 +27,7 @@ import de.bixilon.minosoft.util.KUtil.toResourceLocation
class StringParser(
val mode: StringModes = StringModes.SINGLE,
) : BrigadierParser<String> {
override val examples: List<String> = listOf()
override val examples: List<String> = emptyList()
override val placeholder = ChatComponent.of("<string>")
override fun parse(reader: CommandReader): String {

View File

@ -20,6 +20,9 @@ import de.bixilon.minosoft.commands.parser.brigadier._long.LongParser
import de.bixilon.minosoft.commands.parser.brigadier.bool.BooleanParser
import de.bixilon.minosoft.commands.parser.brigadier.string.StringParser
import de.bixilon.minosoft.commands.parser.minecraft.target.TargetParser
import de.bixilon.minosoft.commands.parser.minosoft.range.RangeParserFactory
import de.bixilon.minosoft.commands.parser.minosoft.range._float.FloatRangeParser
import de.bixilon.minosoft.commands.parser.minosoft.range._int.IntRangeParser
import de.bixilon.minosoft.data.registries.factory.DefaultFactory
object ArgumentParserFactories : DefaultFactory<ArgumentParserFactory<*>>(
@ -31,4 +34,8 @@ object ArgumentParserFactories : DefaultFactory<ArgumentParserFactory<*>>(
StringParser,
TargetParser,
RangeParserFactory,
FloatRangeParser,
IntRangeParser,
)

View File

@ -13,9 +13,13 @@
package de.bixilon.minosoft.commands.parser.minecraft.target
import de.bixilon.minosoft.commands.parser.minecraft.target.properties.*
import de.bixilon.minosoft.commands.parser.minecraft.target.properties.rotation.PitchRotation
import de.bixilon.minosoft.commands.parser.minecraft.target.properties.rotation.YawRotation
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.DistanceProperty
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.GamemodeProperty
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.NameProperty
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.TypeProperty
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.rotation.PitchRotation
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.rotation.YawRotation
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.sort.Sorting
data class TargetProperties(
val selector: TargetSelectors,

View File

@ -13,10 +13,21 @@
package de.bixilon.minosoft.commands.parser.minecraft.target
enum class TargetSelectors(val char: Char) {
NEAREST('p'),
RANDOM('r'),
ALL_PLAYERS('a'),
ALL_ENTITIES('e'),
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.sort.Sorting
import de.bixilon.minosoft.data.entities.entities.Entity
enum class TargetSelectors(
val char: Char,
val sorting: Sorting,
) {
NEAREST('p', Sorting.NEAREST),
RANDOM('r', Sorting.RANDOM),
ALL_PLAYERS('a', Sorting.ARBITRARY),
ALL_ENTITIES('e', Sorting.ARBITRARY),
;
fun sort(selected: MutableList<Entity>) {
sorting.sort(selected)
}
}

View File

@ -13,4 +13,10 @@
package de.bixilon.minosoft.commands.parser.minecraft.target.targets
interface EntityTarget
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.data.world.WorldEntities
interface EntityTarget {
fun getEntities(entities: WorldEntities): List<Entity>
}

View File

@ -14,11 +14,30 @@
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.identifier.name
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.EntityTarget
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.data.world.WorldEntities
class NameEntityTarget(
val name: String,
) : EntityTarget {
override fun getEntities(entities: WorldEntities): List<Entity> {
var entity: Entity? = null
entities.lock.acquire()
for (entry in entities) {
if (entry.customName?.message == name) {
entity = entry
break
}
}
entities.lock.release()
if (entity == null) {
return emptyList()
}
return listOf(entity)
}
override fun toString(): String {
return "{Bixilon}"
}

View File

@ -14,12 +14,19 @@
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.identifier.uuid
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.EntityTarget
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.data.world.WorldEntities
import java.util.*
class UUIDEntityTarget(
val uuid: UUID,
) : EntityTarget {
override fun getEntities(entities: WorldEntities): List<Entity> {
val entity = entities[uuid] ?: return emptyList()
return listOf(entity)
}
override fun toString(): String {
return "{$uuid}"
}

View File

@ -0,0 +1,51 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.commands.parser.minecraft.target.targets.selector
import de.bixilon.kutil.cast.CastUtil.nullCast
import de.bixilon.minosoft.commands.parser.minecraft.target.TargetSelectors
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.EntityTarget
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.TargetProperty
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.sort.SortProperty
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.data.world.WorldEntities
class SelectorEntityTarget(
val selector: TargetSelectors,
val properties: Map<String, TargetProperty>,
) : EntityTarget {
override fun getEntities(entities: WorldEntities): List<Entity> {
val selected: MutableList<Entity> = mutableListOf()
entities.lock.acquire()
for (entity in entities) {
selected += entity
}
entities.lock.release()
properties[SortProperty.name]?.nullCast<SortProperty>()?.sort(selected) ?: selector.sort(selected)
val output: MutableList<Entity> = mutableListOf()
entityLoop@ for (entity in selected) {
for (property in properties.values) {
if (!property.passes(output, entity)) {
continue@entityLoop
}
}
output += entity
}
return output
}
}

View File

@ -0,0 +1,40 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.commands.parser.minecraft.target.targets.selector.properties
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.data.entities.entities.Entity
class DistanceProperty(
val min: Double = 0.0,
val max: Double = Double.MAX_VALUE,
) : TargetProperty {
init {
check(min >= 0.0) { "Minimum distance can not be below 0" }
check(max >= min) { "Maximum distance can not be smaller than minimum distance" }
}
override fun passes(selected: List<Entity>, entity: Entity): Boolean {
TODO()
}
companion object : TargetPropertyFactory<DistanceProperty> {
override val name: String = "distance"
override fun read(reader: CommandReader): DistanceProperty {
TODO("Not yet implemented")
}
}
}

View File

@ -11,20 +11,21 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.commands.parser.minecraft.target.properties
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties
import de.bixilon.minosoft.commands.parser.minecraft.target.TargetProperties
import de.bixilon.minosoft.commands.errors.ExpectedArgumentError
import de.bixilon.minosoft.commands.parser.minosoft.enums.EnumParser
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.data.abilities.Gamemodes
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
class GamemodeProperty(
val gamemode: Gamemodes,
val negated: Boolean,
) : TargetProperty {
override fun passes(properties: TargetProperties, connection: PlayConnection, entity: Entity): Boolean {
override fun passes(selected: List<Entity>, entity: Entity): Boolean {
if (entity !is PlayerEntity) {
return false
}
@ -33,4 +34,15 @@ class GamemodeProperty(
}
return entity.gamemode == gamemode
}
companion object : TargetPropertyFactory<GamemodeProperty> {
override val name: String = "gamemode"
private val parser = EnumParser(Gamemodes)
override fun read(reader: CommandReader): GamemodeProperty {
val (gamemode, negated) = reader.readNegateable { parser.parse(reader) } ?: throw ExpectedArgumentError(reader)
return GamemodeProperty(gamemode, negated)
}
}
}

View File

@ -11,22 +11,31 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.commands.parser.minecraft.target.properties
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties
import de.bixilon.minosoft.commands.parser.minecraft.target.TargetProperties
import de.bixilon.minosoft.commands.errors.ExpectedArgumentError
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
class NameProperty(
val name: String,
val negated: Boolean,
) : TargetProperty {
override fun passes(properties: TargetProperties, connection: PlayConnection, entity: Entity): Boolean {
override fun passes(selected: List<Entity>, entity: Entity): Boolean {
// ToDo: Check player name?
if (negated) {
return entity.customName?.message != name
}
return entity.customName?.message == name
}
companion object : TargetPropertyFactory<NameProperty> {
override val name: String = "name"
override fun read(reader: CommandReader): NameProperty {
val (word, negated) = reader.readNegateable { readWord() ?: throw ExpectedArgumentError(reader) } ?: throw ExpectedArgumentError(reader)
return NameProperty(word, negated)
}
}
}

View File

@ -0,0 +1,37 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.commands.parser.minecraft.target.targets.selector.properties
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.rotation.PitchRotation
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.rotation.YawRotation
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.sort.SortProperty
object TargetProperties {
val properties: MutableMap<String, TargetPropertyFactory<*>> = mutableMapOf()
init {
register(SortProperty)
register(PitchRotation)
register(YawRotation)
register(DistanceProperty)
register(GamemodeProperty)
register(NameProperty)
register(TypeProperty)
}
fun register(factory: TargetPropertyFactory<*>) {
properties[factory.name] = factory
}
}

View File

@ -11,13 +11,11 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.commands.parser.minecraft.target.properties
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties
import de.bixilon.minosoft.commands.parser.minecraft.target.TargetProperties
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
interface TargetProperty {
fun passes(properties: TargetProperties, connection: PlayConnection, entity: Entity): Boolean
fun passes(selected: List<Entity>, entity: Entity): Boolean
}

View File

@ -11,15 +11,13 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.commands.parser.minecraft.target.properties
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties
class DistanceProperty(
val min: Double = 0.0,
val max: Double = Double.MAX_VALUE,
) {
import de.bixilon.minosoft.commands.util.CommandReader
init {
check(min >= 0.0) { "Minimum distance can not be below 0" }
check(max >= min) { "Maximum distance can not be smaller than minimum distance" }
}
interface TargetPropertyFactory<T : TargetProperty> {
val name: String
fun read(reader: CommandReader): T
}

View File

@ -0,0 +1,42 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.commands.parser.minecraft.target.targets.selector.properties
import de.bixilon.minosoft.commands.errors.ExpectedArgumentError
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.data.registries.ResourceLocation
class TypeProperty(
val type: ResourceLocation,
val negated: Boolean,
) : TargetProperty {
override fun passes(selected: List<Entity>, entity: Entity): Boolean {
if (negated) {
return entity.type.resourceLocation != type
}
return entity.type.resourceLocation == type
}
companion object : TargetPropertyFactory<TypeProperty> {
override val name: String = "type"
override fun read(reader: CommandReader): TypeProperty {
val (resourceLocation, negated) = reader.readNegateable { readResourceLocation() ?: throw ExpectedArgumentError(reader) } ?: throw ExpectedArgumentError(reader)
return TypeProperty(resourceLocation, negated)
}
}
}

View File

@ -0,0 +1,45 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.commands.parser.minecraft.target.targets.selector.properties.rotation
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.TargetPropertyFactory
import de.bixilon.minosoft.commands.parser.minosoft.range._float.FloatRange
import de.bixilon.minosoft.commands.parser.minosoft.range._float.FloatRangeParser
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.data.entities.EntityRotation
class PitchRotation(
override val range: FloatRange,
) : RotationProperty {
override fun getValue(rotation: EntityRotation): Double {
return rotation.pitch
}
companion object : TargetPropertyFactory<YawRotation> {
const val MIN = -90.0f
const val MAX = 90.0f
override val name: String = "x_rotation"
private val parser = FloatRangeParser(false)
override fun read(reader: CommandReader): YawRotation {
val range = reader.readResult { parser.parse(reader) }
if (range.result.min < MIN || range.result.max > MAX) {
throw RotationOutOfRangeError(reader, range)
}
return YawRotation(range.result)
}
}
}

View File

@ -0,0 +1,24 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.commands.parser.minecraft.target.targets.selector.properties.rotation
import de.bixilon.minosoft.commands.errors.parser.ParserError
import de.bixilon.minosoft.commands.parser.minosoft.range._float.FloatRange
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.commands.util.ReadResult
class RotationOutOfRangeError(
reader: CommandReader,
result: ReadResult<FloatRange>,
) : ParserError(reader, result)

View File

@ -11,25 +11,22 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.commands.parser.minecraft.target.properties.rotation
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.rotation
import de.bixilon.minosoft.commands.parser.minecraft.target.TargetProperties
import de.bixilon.minosoft.commands.parser.minecraft.target.properties.TargetProperty
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.TargetProperty
import de.bixilon.minosoft.commands.parser.minosoft.range._float.FloatRange
import de.bixilon.minosoft.data.entities.EntityRotation
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
interface RotationProperty : TargetProperty {
val min: Float
val max: Float
val range: FloatRange
fun getValue(rotation: EntityRotation): Double
override fun passes(properties: TargetProperties, connection: PlayConnection, entity: Entity): Boolean {
override fun passes(selected: List<Entity>, entity: Entity): Boolean {
val rotation = getValue(entity.rotation)
return rotation in min..max
return rotation.toFloat() in range
}
}

View File

@ -0,0 +1,44 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.commands.parser.minecraft.target.targets.selector.properties.rotation
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.TargetPropertyFactory
import de.bixilon.minosoft.commands.parser.minosoft.range._float.FloatRange
import de.bixilon.minosoft.commands.parser.minosoft.range._float.FloatRangeParser
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.data.entities.EntityRotation
class YawRotation(
override val range: FloatRange,
) : RotationProperty {
override fun getValue(rotation: EntityRotation): Double {
return rotation.yaw
}
companion object : TargetPropertyFactory<YawRotation> {
const val MIN = -180.0f
const val MAX = 180.0f
override val name: String = "y_rotation"
private val parser = FloatRangeParser(false)
override fun read(reader: CommandReader): YawRotation {
val range = reader.readResult { parser.parse(reader) }
if (range.result.min < MIN || range.result.max > MAX) {
throw RotationOutOfRangeError(reader, range)
}
return YawRotation(range.result)
}
}
}

View File

@ -0,0 +1,42 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.commands.parser.minecraft.target.targets.selector.properties.sort
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.TargetProperty
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.TargetPropertyFactory
import de.bixilon.minosoft.commands.parser.minosoft.enums.EnumParser
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.data.entities.entities.Entity
class SortProperty(
val sorting: Sorting,
) : TargetProperty {
override fun passes(selected: List<Entity>, entity: Entity): Boolean {
return true
}
fun sort(selected: MutableList<Entity>) {
sorting.sort(selected)
}
companion object : TargetPropertyFactory<SortProperty> {
override val name: String = "sort"
private val parser = EnumParser(Sorting)
override fun read(reader: CommandReader): SortProperty {
return SortProperty(parser.parse(reader))
}
}
}

View File

@ -11,22 +11,26 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.commands.parser.minecraft.target.properties
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.sort
import de.bixilon.minosoft.commands.parser.minecraft.target.TargetProperties
import de.bixilon.kutil.enums.EnumUtil
import de.bixilon.kutil.enums.ValuesEnum
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.data.registries.entities.EntityType
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
class TypeProperty(
val type: EntityType,
val negated: Boolean,
) : TargetProperty {
enum class Sorting {
NEAREST,
FURTHEST,
RANDOM,
ARBITRARY,
;
override fun passes(properties: TargetProperties, connection: PlayConnection, entity: Entity): Boolean {
if (negated) {
return entity.type != type
}
return entity.type == type
fun sort(selected: MutableList<Entity>) {
sort(selected)
}
companion object : ValuesEnum<Sorting> {
override val VALUES: Array<Sorting> = values()
override val NAME_MAP: Map<String, Sorting> = EnumUtil.getEnumValues(VALUES)
}
}

View File

@ -41,7 +41,7 @@ class EnumParser<E : Enum<*>>(
}
override fun getSuggestions(reader: CommandReader): List<E> {
val text = reader.readResult { reader.readString() }
val text = reader.readResult { reader.readWord() }
if (text.result == null) {
return examples
}

View File

@ -11,12 +11,11 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.commands.parser.minecraft.target.properties
package de.bixilon.minosoft.commands.parser.minosoft.range
enum class Sorting {
NEAREST,
FURTHEST,
RANDOM,
ARBITRARY,
;
interface Range<T : Number> {
val min: T
val max: T
fun contains(number: T): Boolean
}

View File

@ -0,0 +1,60 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.commands.parser.minosoft.range
import de.bixilon.minosoft.commands.parser.ArgumentParser
import de.bixilon.minosoft.commands.parser.factory.ArgumentParserFactory
import de.bixilon.minosoft.commands.parser.minosoft.range._float.FloatRangeParser
import de.bixilon.minosoft.commands.parser.minosoft.range._int.IntRangeParser
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.util.KUtil.toResourceLocation
object RangeParserFactory : ArgumentParserFactory<ArgumentParser<*>> {
override val RESOURCE_LOCATION: ResourceLocation = "minosoft:range".toResourceLocation()
override fun build(connection: PlayConnection?) = TODO("Can not construct range parser!")
override fun read(buffer: PlayInByteBuffer): ArgumentParser<*> {
val decimals = buffer.readBoolean()
return if (decimals) {
FloatRangeParser.read(buffer)
} else {
IntRangeParser.read(buffer)
}
}
fun <T> CommandReader.readRange(reader: CommandReader.() -> T): Pair<T?, T?>? {
if (!canPeek()) {
return null
}
val first = reader(this) ?: return null
if (!canPeek()) {
return Pair(first, null)
}
if (peekNext() != '.'.code || peekNext(pointer + 1) != '.'.code) {
return null
}
readNext()
readNext()
val second = reader(this) ?: return null
return Pair(first, second)
}
}

View File

@ -11,16 +11,16 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.commands.parser.minecraft.target.properties.rotation
package de.bixilon.minosoft.commands.parser.minosoft.range._float
import de.bixilon.minosoft.data.entities.EntityRotation
import de.bixilon.minosoft.commands.parser.minosoft.range.Range
class YawRotation(
override val min: Float = -180.0f,
override val max: Float = 180.0f,
) : RotationProperty {
class FloatRange(
override val min: Float = -Float.MAX_VALUE,
override val max: Float = Float.MAX_VALUE,
) : Range<Float> {
override fun getValue(rotation: EntityRotation): Double {
return rotation.yaw
override operator fun contains(number: Float): Boolean {
return number in min..max
}
}

View File

@ -0,0 +1,23 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.commands.parser.minosoft.range._float
import de.bixilon.minosoft.commands.errors.parser.ParserError
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.commands.util.ReadResult
class FloatRangeParseError(
reader: CommandReader,
result: ReadResult<FloatRange?>,
) : ParserError(reader, result)

View File

@ -0,0 +1,62 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.commands.parser.minosoft.range._float
import de.bixilon.minosoft.commands.parser.ArgumentParser
import de.bixilon.minosoft.commands.parser.brigadier._float.FloatParser.Companion.readFloat
import de.bixilon.minosoft.commands.parser.factory.ArgumentParserFactory
import de.bixilon.minosoft.commands.parser.minosoft.range.RangeParserFactory.readRange
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.util.KUtil.toResourceLocation
class FloatRangeParser(
val defaultMin: Boolean = true,
) : ArgumentParser<FloatRange> {
override val examples: List<Any> = listOf(1.0f, "1.0..10")
override val placeholder = ChatComponent.of("<float..float>")
override fun parse(reader: CommandReader): FloatRange {
return reader.readResult { reader.readFloatRange(defaultMin) }.let { return@let it.result ?: throw FloatRangeParseError(reader, it) }
}
override fun getSuggestions(reader: CommandReader): List<Any> {
if (reader.readString()?.isBlank() != false) {
return examples
}
return emptyList()
}
companion object : ArgumentParserFactory<FloatRangeParser> {
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:float_range".toResourceLocation()
override fun build(connection: PlayConnection?) = FloatRangeParser()
override fun read(buffer: PlayInByteBuffer) = FloatRangeParser()
fun CommandReader.readFloatRange(defaultMin: Boolean = true): FloatRange? {
val (first, second) = readRange { readFloat() } ?: return null
if (first == null) {
return null
}
if (second == null) {
return FloatRange(min = if (defaultMin) -Float.MAX_VALUE else first, max = first)
}
return FloatRange(min = first, max = second)
}
}
}

View File

@ -11,16 +11,13 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.commands.parser.minecraft.target.properties.rotation
package de.bixilon.minosoft.commands.parser.minosoft.range._int
import de.bixilon.minosoft.data.entities.EntityRotation
import de.bixilon.minosoft.commands.errors.parser.ParserError
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.commands.util.ReadResult
class PitchRotation(
override val min: Float = -90.0f,
override val max: Float = 90.0f,
) : RotationProperty {
override fun getValue(rotation: EntityRotation): Double {
return rotation.pitch
}
}
class IntRangeParseError(
reader: CommandReader,
result: ReadResult<IntRange?>,
) : ParserError(reader, result)

View File

@ -0,0 +1,66 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.commands.parser.minosoft.range._int
import de.bixilon.minosoft.commands.parser.ArgumentParser
import de.bixilon.minosoft.commands.parser.brigadier._int.IntParser.Companion.readInt
import de.bixilon.minosoft.commands.parser.factory.ArgumentParserFactory
import de.bixilon.minosoft.commands.parser.minosoft.range.RangeParserFactory.readRange
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.util.KUtil.toResourceLocation
class IntRangeParser(
val defaultMin: Boolean = true,
) : ArgumentParser<IntRange> {
override val examples: List<Any> = listOf(1, "1..10")
override val placeholder = ChatComponent.of("<int..int>")
override fun parse(reader: CommandReader): IntRange {
return reader.readResult { reader.readIntRange(defaultMin) }.let { return@let it.result ?: throw IntRangeParseError(reader, it) }
}
override fun getSuggestions(reader: CommandReader): List<Any> {
if (reader.readString()?.isBlank() != false) {
return examples
}
return emptyList()
}
companion object : ArgumentParserFactory<IntRangeParser> {
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:float_range".toResourceLocation()
override fun build(connection: PlayConnection?) = IntRangeParser()
override fun read(buffer: PlayInByteBuffer) = IntRangeParser()
fun CommandReader.readIntRange(defaultMin: Boolean = true): IntRange? {
val (first, second) = readRange { readInt() } ?: return null
if (first == null) {
return null
}
if (second == null) {
return if (defaultMin) {
Int.MIN_VALUE..first
} else {
first..first
}
}
return first..second
}
}
}

View File

@ -15,6 +15,8 @@ package de.bixilon.minosoft.commands.util
import de.bixilon.minosoft.commands.errors.reader.*
import de.bixilon.minosoft.commands.errors.reader.number.NegativeNumberError
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.util.KUtil.toResourceLocation
open class CommandReader(val string: String) {
var pointer = 0
@ -228,7 +230,7 @@ open class CommandReader(val string: String) {
}
fun readNumeric(decimal: Boolean = true, negative: Boolean = true): String? {
if (!canPeekNext()) {
if (!canPeek()) {
return null
}
val builder = StringBuilder()
@ -254,6 +256,49 @@ open class CommandReader(val string: String) {
return builder.toString()
}
fun readWord(): String? {
if (!canPeek()) {
return null
}
val builder = StringBuilder()
while (true) {
val peek = peek() ?: break
if (peek in '0'.code..'9'.code || peek in 'a'.code..'z'.code || peek in 'A'.code..'Z'.code || peek == '_'.code || peek == '-'.code || peek == '/'.code) {
builder.appendCodePoint(peek)
pointer++
continue
} else {
break
}
}
return builder.toString()
}
fun readResourceLocation(): ResourceLocation? {
val namespace = readWord() ?: return null
if (peek() != ':'.code) {
return namespace.toResourceLocation()
}
read()
val path = readWord() ?: return null
return ResourceLocation(namespace, path)
}
fun <T> readNegateable(reader: CommandReader.() -> T): Pair<T, Boolean>? {
if (!canPeek()) {
return null
}
var negated = false
if (peek() == '!'.code) {
read()
negated = true
}
val it = reader(this) ?: return null
return Pair(it, negated)
}
fun <T> readResult(reader: CommandReader.() -> T): ReadResult<T> {
val start = pointer
val result = reader(this)

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2021 Moritz Zwerger
* Copyright (C) 2020-2022 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.
*
@ -38,7 +38,7 @@ class Language(
val ret = BaseComponent()
val arguments: MutableList<Any?> = mutableListOf()
var splitPlaceholder: List<String> = listOf()
var splitPlaceholder: List<String> = emptyList()
// Bring arguments in correct oder
FORMATTER_ORDER_REGEX.findAll(placeholder).toList().let {

View File

@ -23,7 +23,7 @@ data class ErosAccountType<T : Account>(
override val resourceLocation: ResourceLocation,
override val translationKey: ResourceLocation? = null,
val icon: Ikon,
val additionalDetails: List<Pair<ResourceLocation, (account: T) -> Any?>> = listOf(),
val additionalDetails: List<Pair<ResourceLocation, (account: T) -> Any?>> = emptyList(),
val addHandler: ((accountController: AccountController) -> Unit)? = null,
val refreshHandler: ((accountController: AccountController, account: T) -> Unit)? = null,
) : ResourceLocationAble, Translatable

View File

@ -35,7 +35,7 @@ open class TextFlowElement(
var messageExpireTime: Long,
) : Element(guiRenderer), AbstractLayout<TextElement> {
private val messages: MutableList<TextFlowTextElement> = synchronizedListOf() // all messages **from newest to oldest**
private var visibleLines: List<TextFlowLineElement> = listOf() // all visible lines **from bottom to top**
private var visibleLines: List<TextFlowLineElement> = emptyList() // all visible lines **from bottom to top**
override var activeElement: TextElement? = null
override var activeDragElement: TextElement? = null

View File

@ -52,7 +52,7 @@ class TabListElement(guiRenderer: GUIRenderer) : Element(guiRenderer), LayoutedE
private var entriesSize = Vec2i.EMPTY
private val entries: MutableMap<UUID, TabListEntryElement> = synchronizedMapOf()
private var toRender: List<TabListEntryElement> = listOf()
private var toRender: List<TabListEntryElement> = emptyList()
private val lock = ReentrantLock()
var needsApply = false
private set

View File

@ -33,7 +33,7 @@ class SkeletalInstance(
private var currentAnimation: SkeletalAnimation? = null
private var animationTime = 0.0f
private var animationLastFrame = -1L
private var transforms: List<Mat4> = listOf()
private var transforms: List<Mat4> = emptyList()
var light: Int = 0xFF

View File

@ -32,10 +32,10 @@ data class SkeletalModel(
val geometryName: String = name,
val visibleBox: Vec3 = Vec3.EMPTY,
val resolution: SkeletalResolution = SkeletalResolution(),
val elements: List<SkeletalElement> = listOf(),
val outliner: List<SkeletalOutliner> = listOf(),
val textures: List<SkeletalTexture> = listOf(),
val animations: List<SkeletalAnimation> = listOf(),
val elements: List<SkeletalElement> = emptyList(),
val outliner: List<SkeletalOutliner> = emptyList(),
val textures: List<SkeletalTexture> = emptyList(),
val animations: List<SkeletalAnimation> = emptyList(),
) {
fun bake(renderWindow: RenderWindow, textureOverride: MutableMap<Int, AbstractTexture>): BakedSkeletalModel {

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2021 Moritz Zwerger
* Copyright (C) 2020-2022 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.
*
@ -23,7 +23,7 @@ data class AnimationProperties(
var width: Int = -1,
var height: Int = -1,
@JsonProperty("frametime") private val frameTime: Int = 1,
@JsonProperty("frames") private val _frames: List<Any> = listOf(),
@JsonProperty("frames") private val _frames: List<Any> = emptyList(),
) {
@JsonIgnore
private var initialized = false

View File

@ -65,7 +65,7 @@ object RunConfiguration {
var VERSION_STRING = "Minosoft ${StaticConfiguration.VERSION}"
var SKIP_RENDERERS: List<ResourceLocation> = listOf()
var SKIP_RENDERERS: List<ResourceLocation> = emptyList()
var OPEN_Gl_ON_FIRST_THREAD = PlatformInfo.OS == OSTypes.MAC
var VERBOSE_LOGGING = false