aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gradle/libs.versions.toml2
-rw-r--r--src/main/java/moe/nea/firmament/mixins/MixinCommandNode.java29
-rw-r--r--src/main/kotlin/moe/nea/firmament/commands/CaseInsensitiveLiteralCommandNode.kt79
-rw-r--r--src/main/kotlin/moe/nea/firmament/commands/dsl.kt9
4 files changed, 113 insertions, 6 deletions
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index c3f3c43..37f5295 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -63,7 +63,7 @@ runtime_optional = [
"freecammod",
"sodium",
"qolify",
- "citresewn",
+# "citresewn",
"ncr",
]
diff --git a/src/main/java/moe/nea/firmament/mixins/MixinCommandNode.java b/src/main/java/moe/nea/firmament/mixins/MixinCommandNode.java
new file mode 100644
index 0000000..aa8e584
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/MixinCommandNode.java
@@ -0,0 +1,29 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+package moe.nea.firmament.mixins;
+
+import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
+import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import com.mojang.brigadier.tree.CommandNode;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+
+import java.util.Locale;
+import java.util.Map;
+
+@Mixin(value = CommandNode.class, remap = false)
+public class MixinCommandNode<S> {
+ @WrapOperation(method = "getRelevantNodes", at = @At(value = "INVOKE", target = "Ljava/util/Map;get(Ljava/lang/Object;)Ljava/lang/Object;"), remap = false)
+ public Object modify(Map map, Object text, Operation<Object> op) {
+ var original = op.call(map, text);
+ if (original == null) {
+ return map.get(((String) text).toLowerCase(Locale.ROOT));
+ }
+ return original;
+ }
+
+}
diff --git a/src/main/kotlin/moe/nea/firmament/commands/CaseInsensitiveLiteralCommandNode.kt b/src/main/kotlin/moe/nea/firmament/commands/CaseInsensitiveLiteralCommandNode.kt
new file mode 100644
index 0000000..b819a5a
--- /dev/null
+++ b/src/main/kotlin/moe/nea/firmament/commands/CaseInsensitiveLiteralCommandNode.kt
@@ -0,0 +1,79 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+package moe.nea.firmament.commands
+
+import com.mojang.brigadier.Command
+import com.mojang.brigadier.RedirectModifier
+import com.mojang.brigadier.StringReader
+import com.mojang.brigadier.builder.LiteralArgumentBuilder
+import com.mojang.brigadier.context.CommandContextBuilder
+import com.mojang.brigadier.context.StringRange
+import com.mojang.brigadier.exceptions.CommandSyntaxException
+import com.mojang.brigadier.tree.CommandNode
+import com.mojang.brigadier.tree.LiteralCommandNode
+import java.util.function.Predicate
+
+class CaseInsensitiveLiteralCommandNode<S>(
+ literal: String, command: Command<S>?, requirement: Predicate<S>?,
+ redirect: CommandNode<S>?, modifier: RedirectModifier<S>?, forks: Boolean
+) : LiteralCommandNode<S>(
+ literal.lowercase(), command, requirement, redirect, modifier, forks
+) {
+ class Builder<S>(literal: String) : LiteralArgumentBuilder<S>(literal) {
+ override fun build(): LiteralCommandNode<S> {
+ val result = CaseInsensitiveLiteralCommandNode(
+ literal,
+ command, requirement, redirect, redirectModifier, isFork
+ )
+ for (argument in arguments) {
+ result.addChild(argument)
+ }
+ return result
+ }
+ }
+
+ override fun createBuilder(): LiteralArgumentBuilder<S> {
+ return Builder<S>(literal).also {
+ it.requires(requirement)
+ it.forward(redirect, redirectModifier, isFork)
+ if (command != null)
+ it.executes(command)
+ }
+ }
+
+ override fun parse(reader: StringReader, contextBuilder: CommandContextBuilder<S>) {
+ val start = reader.cursor
+ val end = parse0(reader)
+ if (end > -1) {
+ contextBuilder.withNode(this, StringRange.between(start, end))
+ return
+ }
+
+ throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.literalIncorrect().createWithContext(reader, literal)
+ }
+
+ override fun toString(): String {
+ return "<iliteral $literal>"
+ }
+
+ private fun parse0(reader: StringReader): Int {
+ val start = reader.cursor
+ if (reader.canRead(literal.length)) {
+ val end = start + literal.length
+ if (reader.string.substring(start, end).equals(literal, true)) {
+ reader.cursor = end
+ if (!reader.canRead() || reader.peek() == ' ') {
+ return end
+ } else {
+ reader.cursor = start
+ }
+ }
+ }
+ return -1
+ }
+
+}
diff --git a/src/main/kotlin/moe/nea/firmament/commands/dsl.kt b/src/main/kotlin/moe/nea/firmament/commands/dsl.kt
index d6eaf85..551f560 100644
--- a/src/main/kotlin/moe/nea/firmament/commands/dsl.kt
+++ b/src/main/kotlin/moe/nea/firmament/commands/dsl.kt
@@ -8,7 +8,6 @@ package moe.nea.firmament.commands
import com.mojang.brigadier.arguments.ArgumentType
import com.mojang.brigadier.builder.ArgumentBuilder
-import com.mojang.brigadier.builder.LiteralArgumentBuilder
import com.mojang.brigadier.builder.RequiredArgumentBuilder
import com.mojang.brigadier.context.CommandContext
import com.mojang.brigadier.suggestion.SuggestionProvider
@@ -32,9 +31,9 @@ operator fun <T : Any, C : CommandContext<*>> C.get(arg: TypeSafeArg<T>): T {
fun literal(
name: String,
- block: LiteralArgumentBuilder<DefaultSource>.() -> Unit
-): LiteralArgumentBuilder<DefaultSource> =
- LiteralArgumentBuilder.literal<DefaultSource>(name).also(block)
+ block: CaseInsensitiveLiteralCommandNode.Builder<DefaultSource>.() -> Unit
+): CaseInsensitiveLiteralCommandNode.Builder<DefaultSource> =
+ CaseInsensitiveLiteralCommandNode.Builder<DefaultSource>(name).also(block)
private fun normalizeGeneric(argument: Type): Class<*> {
@@ -101,7 +100,7 @@ fun <T : RequiredArgumentBuilder<DefaultSource, String>> T.suggestsList(provider
fun <T : ArgumentBuilder<DefaultSource, T>> T.thenLiteral(
name: String,
- block: LiteralArgumentBuilder<DefaultSource>.() -> Unit
+ block: CaseInsensitiveLiteralCommandNode.Builder<DefaultSource>.() -> Unit
): T =
then(literal(name, block))