diff options
| author | Linnea Gräf <nea@nea.moe> | 2025-10-13 18:59:48 +0200 |
|---|---|---|
| committer | Linnea Gräf <nea@nea.moe> | 2025-10-13 18:59:48 +0200 |
| commit | f73a0e4e8e7c4306cdaf0ed163d312c6a0b2c1d5 (patch) | |
| tree | ce0f1b13e8cc852a76d834a9d1d221dcf8a4f591 /src/main | |
| parent | 584955e8f857f1f919bc1485d811ee5d6dbd688c (diff) | |
| download | Firmament-f73a0e4e8e7c4306cdaf0ed163d312c6a0b2c1d5.tar.gz Firmament-f73a0e4e8e7c4306cdaf0ed163d312c6a0b2c1d5.tar.bz2 Firmament-f73a0e4e8e7c4306cdaf0ed163d312c6a0b2c1d5.zip | |
fix: /warp autocompletion breaking all warps
Diffstat (limited to 'src/main')
| -rw-r--r-- | src/main/kotlin/commands/dsl.kt | 132 | ||||
| -rw-r--r-- | src/main/kotlin/commands/rome.kt | 108 | ||||
| -rw-r--r-- | src/main/kotlin/features/chat/AutoCompletions.kt | 20 |
3 files changed, 160 insertions, 100 deletions
diff --git a/src/main/kotlin/commands/dsl.kt b/src/main/kotlin/commands/dsl.kt index c5955d7..4f76c69 100644 --- a/src/main/kotlin/commands/dsl.kt +++ b/src/main/kotlin/commands/dsl.kt @@ -1,5 +1,3 @@ - - package moe.nea.firmament.commands import com.mojang.brigadier.arguments.ArgumentType @@ -22,97 +20,95 @@ typealias DefaultSource = FabricClientCommandSource inline val <T : CommandContext<*>> T.context get() = this operator fun <T : Any, C : CommandContext<*>> C.get(arg: TypeSafeArg<T>): T { - return arg.get(this) + return arg.get(this) } fun literal( - name: String, - block: CaseInsensitiveLiteralCommandNode.Builder<DefaultSource>.() -> Unit + name: String, + block: CaseInsensitiveLiteralCommandNode.Builder<DefaultSource>.() -> Unit ): CaseInsensitiveLiteralCommandNode.Builder<DefaultSource> = - CaseInsensitiveLiteralCommandNode.Builder<DefaultSource>(name).also(block) + CaseInsensitiveLiteralCommandNode.Builder<DefaultSource>(name).also(block) private fun normalizeGeneric(argument: Type): Class<*> { - return when (argument) { - is Class<*> -> argument - is TypeVariable<*> -> normalizeGeneric(argument.bounds[0]) - is ParameterizedType -> normalizeGeneric(argument.rawType) - else -> Any::class.java - } + return when (argument) { + is Class<*> -> argument + is TypeVariable<*> -> normalizeGeneric(argument.bounds[0]) + is ParameterizedType -> normalizeGeneric(argument.rawType) + else -> Any::class.java + } } data class TypeSafeArg<T : Any>(val name: String, val argument: ArgumentType<T>) { - val argClass by lazy { - argument.javaClass - .iterate<Class<in ArgumentType<T>>> { - it.superclass - } - .flatMap { - it.genericInterfaces.toList() - } - .filterIsInstance<ParameterizedType>() - .find { it.rawType == ArgumentType::class.java }!! - .let { normalizeGeneric(it.actualTypeArguments[0]) } - } - - @JvmName("getWithThis") - fun <S> CommandContext<S>.get(): T = - get(this) - - - fun <S> get(ctx: CommandContext<S>): T { - try { - return ctx.getArgument(name, argClass) as T - } catch (e: Exception) { - if (ctx.child != null) { - return get(ctx.child) - } - throw e - } - } + val argClass by lazy { + argument.javaClass + .iterate<Class<in ArgumentType<T>>> { + it.superclass + } + .flatMap { + it.genericInterfaces.toList() + } + .filterIsInstance<ParameterizedType>() + .find { it.rawType == ArgumentType::class.java }!! + .let { normalizeGeneric(it.actualTypeArguments[0]) } + } + + @JvmName("getWithThis") + fun <S> CommandContext<S>.get(): T = + get(this) + + + fun <S> get(ctx: CommandContext<S>): T { + try { + return ctx.getArgument(name, argClass) as T + } catch (e: Exception) { + if (ctx.child != null) { + return get(ctx.child) + } + throw e + } + } } fun <T : Any> argument( - name: String, - argument: ArgumentType<T>, - block: RequiredArgumentBuilder<DefaultSource, T>.(TypeSafeArg<T>) -> Unit + name: String, + argument: ArgumentType<T>, + block: RequiredArgumentBuilder<DefaultSource, T>.(TypeSafeArg<T>) -> Unit ): RequiredArgumentBuilder<DefaultSource, T> = - RequiredArgumentBuilder.argument<DefaultSource, T>(name, argument).also { block(it, TypeSafeArg(name, argument)) } + RequiredArgumentBuilder.argument<DefaultSource, T>(name, argument).also { block(it, TypeSafeArg(name, argument)) } fun <T : ArgumentBuilder<DefaultSource, T>, AT : Any> T.thenArgument( - name: String, - argument: ArgumentType<AT>, - block: RequiredArgumentBuilder<DefaultSource, AT>.(TypeSafeArg<AT>) -> Unit + name: String, + argument: ArgumentType<AT>, + block: RequiredArgumentBuilder<DefaultSource, AT>.(TypeSafeArg<AT>) -> Unit ): T = then(argument(name, argument, block)) fun <T : RequiredArgumentBuilder<DefaultSource, String>> T.suggestsList(provider: CommandContext<DefaultSource>.() -> Iterable<String>) { - suggests(SuggestionProvider<DefaultSource> { context, builder -> - provider(context) - .asSequence() - .filter { it.startsWith(builder.remaining, ignoreCase = true) } - .forEach { - builder.suggest(it) - } - builder.buildFuture() - }) + suggests(SuggestionProvider<DefaultSource> { context, builder -> + provider(context) + .asSequence() + .filter { it.startsWith(builder.remaining, ignoreCase = true) } + .forEach { + builder.suggest(it) + } + builder.buildFuture() + }) } fun <T : ArgumentBuilder<DefaultSource, T>> T.thenLiteral( - name: String, - block: CaseInsensitiveLiteralCommandNode.Builder<DefaultSource>.() -> Unit + name: String, + block: CaseInsensitiveLiteralCommandNode.Builder<DefaultSource>.() -> Unit ): T = - then(literal(name, block)) + then(literal(name, block)) fun <T : ArgumentBuilder<DefaultSource, T>> T.then(node: ArgumentBuilder<DefaultSource, *>, block: T.() -> Unit): T = - then(node).also(block) - -fun <T : ArgumentBuilder<DefaultSource, T>> T.thenExecute(block: suspend CommandContext<DefaultSource>.() -> Unit): T = - executes { - Firmament.coroutineScope.launch(MinecraftDispatcher) { - block(it) - } - 1 - } + then(node).also(block) + +fun <T : ArgumentBuilder<DefaultSource, T>> T.thenExecute(block: CommandContext<DefaultSource>.() -> Unit): T = + executes { + block(it) + 1 + } diff --git a/src/main/kotlin/commands/rome.kt b/src/main/kotlin/commands/rome.kt index b1b2aa2..affc860 100644 --- a/src/main/kotlin/commands/rome.kt +++ b/src/main/kotlin/commands/rome.kt @@ -5,9 +5,11 @@ import com.mojang.brigadier.arguments.IntegerArgumentType import com.mojang.brigadier.arguments.StringArgumentType.string import io.ktor.client.statement.bodyAsText import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource +import kotlinx.coroutines.launch import net.minecraft.nbt.NbtOps import net.minecraft.text.Text import net.minecraft.text.TextCodecs +import moe.nea.firmament.Firmament import moe.nea.firmament.apis.UrsaManager import moe.nea.firmament.events.CommandEvent import moe.nea.firmament.events.FirmamentEventBus @@ -151,7 +153,7 @@ fun firmamentCommand() = literal("firmament") { } thenExecute { source.sendFeedback(Text.translatable("firmament.repo.reload.disk")) - RepoManager.reload() + Firmament.coroutineScope.launch { RepoManager.reload() } } } } @@ -232,11 +234,15 @@ fun firmamentCommand() = literal("firmament") { } thenLiteral("screens") { thenExecute { - MC.sendChat(Text.literal(""" + MC.sendChat( + Text.literal( + """ |Screen: ${MC.screen} (${MC.screen?.title}) |Screen Handler: ${MC.handledScreen?.screenHandler} ${MC.handledScreen?.screenHandler?.syncId} |Player Screen Handler: ${MC.player?.currentScreenHandler} ${MC.player?.currentScreenHandler?.syncId} - """.trimMargin())) + """.trimMargin() + ) + ) } } thenLiteral("blocks") { @@ -273,8 +279,12 @@ fun firmamentCommand() = literal("firmament") { source.sendFeedback(Text.stringifiedTranslatable("firmament.sbinfo.gametype", locrawInfo.gametype)) source.sendFeedback(Text.stringifiedTranslatable("firmament.sbinfo.mode", locrawInfo.mode)) source.sendFeedback(Text.stringifiedTranslatable("firmament.sbinfo.map", locrawInfo.map)) - source.sendFeedback(tr("firmament.sbinfo.custommining", - "Custom Mining: ${formatBool(locrawInfo.skyblockLocation?.hasCustomMining ?: false)}")) + source.sendFeedback( + tr( + "firmament.sbinfo.custommining", + "Custom Mining: ${formatBool(locrawInfo.skyblockLocation?.hasCustomMining ?: false)}" + ) + ) } } } @@ -289,9 +299,11 @@ fun firmamentCommand() = literal("firmament") { thenLiteral("callUrsa") { thenArgument("path", string()) { path -> thenExecute { - source.sendFeedback(Text.translatable("firmament.ursa.debugrequest.start")) - val text = UrsaManager.request(this[path].split("/")).bodyAsText() - source.sendFeedback(Text.stringifiedTranslatable("firmament.ursa.debugrequest.result", text)) + Firmament.coroutineScope.launch { + source.sendFeedback(Text.translatable("firmament.ursa.debugrequest.start")) + val text = UrsaManager.request(get(path).split("/")).bodyAsText() + source.sendFeedback(Text.stringifiedTranslatable("firmament.ursa.debugrequest.result", text)) + } } } } @@ -300,13 +312,19 @@ fun firmamentCommand() = literal("firmament") { source.sendFeedback(tr("firmament.event.start", "Event Bus Readout:")) FirmamentEventBus.allEventBuses.forEach { eventBus -> val prefixName = eventBus.eventType.typeName.removePrefix("moe.nea.firmament") - source.sendFeedback(tr( - "firmament.event.bustype", - "- $prefixName:")) + source.sendFeedback( + tr( + "firmament.event.bustype", + "- $prefixName:" + ) + ) eventBus.handlers.forEach { handler -> - source.sendFeedback(tr( - "firmament.event.handler", - " * ${handler.label}")) + source.sendFeedback( + tr( + "firmament.event.handler", + " * ${handler.label}" + ) + ) } } } @@ -330,8 +348,10 @@ fun firmamentCommand() = literal("firmament") { plugin.appliedMixins .map { it.removePrefix(plugin.mixinPackage) } .forEach { - source.sendFeedback(Text.literal(" - ").withColor(0xD020F0) - .append(Text.literal(it).withColor(0xF6BA20))) + source.sendFeedback( + Text.literal(" - ").withColor(0xD020F0) + .append(Text.literal(it).withColor(0xF6BA20)) + ) } } } @@ -339,21 +359,47 @@ fun firmamentCommand() = literal("firmament") { thenLiteral("repo") { thenExecute { source.sendFeedback(tr("firmament.repo.info.ref", "Repo Upstream: ${RepoManager.getRepoRef()}")) - source.sendFeedback(tr("firmament.repo.info.downloadedref", - "Downloaded ref: ${RepoDownloadManager.latestSavedVersionHash}")) - source.sendFeedback(tr("firmament.repo.info.location", - "Saved location: ${debugPath(RepoDownloadManager.repoSavedLocation)}")) - source.sendFeedback(tr("firmament.repo.info.reloadstatus", - "Incomplete: ${ - formatBool(RepoManager.neuRepo.isIncomplete, - trueIsGood = false) - }, Unstable ${formatBool(RepoManager.neuRepo.isUnstable, trueIsGood = false)}")) - source.sendFeedback(tr("firmament.repo.info.items", - "Loaded items: ${RepoManager.neuRepo.items?.items?.size}")) - source.sendFeedback(tr("firmament.repo.info.itemcache", - "ItemCache flawless: ${formatBool(ItemCache.isFlawless)}")) - source.sendFeedback(tr("firmament.repo.info.itemdir", - "Items on disk: ${debugPath(RepoDownloadManager.repoSavedLocation.resolve("items"))}")) + source.sendFeedback( + tr( + "firmament.repo.info.downloadedref", + "Downloaded ref: ${RepoDownloadManager.latestSavedVersionHash}" + ) + ) + source.sendFeedback( + tr( + "firmament.repo.info.location", + "Saved location: ${debugPath(RepoDownloadManager.repoSavedLocation)}" + ) + ) + source.sendFeedback( + tr( + "firmament.repo.info.reloadstatus", + "Incomplete: ${ + formatBool( + RepoManager.neuRepo.isIncomplete, + trueIsGood = false + ) + }, Unstable ${formatBool(RepoManager.neuRepo.isUnstable, trueIsGood = false)}" + ) + ) + source.sendFeedback( + tr( + "firmament.repo.info.items", + "Loaded items: ${RepoManager.neuRepo.items?.items?.size}" + ) + ) + source.sendFeedback( + tr( + "firmament.repo.info.itemcache", + "ItemCache flawless: ${formatBool(ItemCache.isFlawless)}" + ) + ) + source.sendFeedback( + tr( + "firmament.repo.info.itemdir", + "Items on disk: ${debugPath(RepoDownloadManager.repoSavedLocation.resolve("items"))}" + ) + ) } } } diff --git a/src/main/kotlin/features/chat/AutoCompletions.kt b/src/main/kotlin/features/chat/AutoCompletions.kt index b48069d..c9fd133 100644 --- a/src/main/kotlin/features/chat/AutoCompletions.kt +++ b/src/main/kotlin/features/chat/AutoCompletions.kt @@ -1,6 +1,15 @@ package moe.nea.firmament.features.chat +import com.mojang.brigadier.Message import com.mojang.brigadier.arguments.StringArgumentType.string +import com.mojang.brigadier.context.CommandContext +import com.mojang.brigadier.exceptions.BuiltInExceptions +import com.mojang.brigadier.exceptions.CommandExceptionType +import com.mojang.brigadier.exceptions.CommandSyntaxException +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType +import kotlin.concurrent.thread +import net.minecraft.SharedConstants +import net.minecraft.command.TranslatableBuiltInExceptions import moe.nea.firmament.annotations.Subscribe import moe.nea.firmament.commands.get import moe.nea.firmament.commands.suggestsList @@ -12,6 +21,7 @@ import moe.nea.firmament.repo.RepoManager import moe.nea.firmament.util.MC import moe.nea.firmament.util.data.Config import moe.nea.firmament.util.data.ManagedConfig +import moe.nea.firmament.util.tr object AutoCompletions { @@ -45,10 +55,18 @@ object AutoCompletions { if (warpName == "is" && TConfig.replaceWarpIsByWarpIsland) { MC.sendCommand("warp island") } else { - MC.sendCommand("warp $warpName") + redirectToServer() } } } } } + + fun CommandContext<*>.redirectToServer() { + val message = tr( + "firmament.warp.auto-complete.internal-throw", + "This is an internal syntax exception that should not show up in gameplay, used to pass on a command to the server" + ) + throw CommandSyntaxException(CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownCommand(), message) + } } |
