Add command for toggling config options

This commit is contained in:
nea
2023-09-06 03:10:44 +02:00
parent 1229227051
commit 0f9ec29648
5 changed files with 196 additions and 133 deletions

View File

@@ -11,14 +11,14 @@ import com.mojang.brigadier.builder.ArgumentBuilder
import com.mojang.brigadier.builder.RequiredArgumentBuilder import com.mojang.brigadier.builder.RequiredArgumentBuilder
import com.mojang.brigadier.context.CommandContext import com.mojang.brigadier.context.CommandContext
import com.mojang.brigadier.suggestion.SuggestionProvider import com.mojang.brigadier.suggestion.SuggestionProvider
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
import java.lang.reflect.TypeVariable
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import moe.nea.firmament.Firmament import moe.nea.firmament.Firmament
import moe.nea.firmament.util.MinecraftDispatcher import moe.nea.firmament.util.MinecraftDispatcher
import moe.nea.firmament.util.iterate import moe.nea.firmament.util.iterate
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
import java.lang.reflect.TypeVariable
typealias DefaultSource = FabricClientCommandSource typealias DefaultSource = FabricClientCommandSource
@@ -68,7 +68,14 @@ data class TypeSafeArg<T : Any>(val name: String, val argument: ArgumentType<T>)
fun <S> get(ctx: CommandContext<S>): T { fun <S> get(ctx: CommandContext<S>): T {
return ctx.getArgument(name, argClass) as T try {
return ctx.getArgument(name, argClass) as T
} catch (e: Exception) {
if (ctx.child != null) {
return get(ctx.child)
}
throw e
}
} }
} }
@@ -86,9 +93,9 @@ fun <T : ArgumentBuilder<DefaultSource, T>, AT : Any> T.thenArgument(
block: RequiredArgumentBuilder<DefaultSource, AT>.(TypeSafeArg<AT>) -> Unit block: RequiredArgumentBuilder<DefaultSource, AT>.(TypeSafeArg<AT>) -> Unit
): T = then(argument(name, argument, block)) ): T = then(argument(name, argument, block))
fun <T : RequiredArgumentBuilder<DefaultSource, String>> T.suggestsList(provider: () -> Iterable<String>) { fun <T : RequiredArgumentBuilder<DefaultSource, String>> T.suggestsList(provider: CommandContext<DefaultSource>.() -> Iterable<String>) {
suggests(SuggestionProvider<DefaultSource> { context, builder -> suggests(SuggestionProvider<DefaultSource> { context, builder ->
provider() provider(context)
.asSequence() .asSequence()
.filter { it.startsWith(builder.remaining, ignoreCase = true) } .filter { it.startsWith(builder.remaining, ignoreCase = true) }
.forEach { .forEach {

View File

@@ -9,21 +9,18 @@ package moe.nea.firmament.commands
import com.mojang.brigadier.CommandDispatcher import com.mojang.brigadier.CommandDispatcher
import com.mojang.brigadier.arguments.StringArgumentType.string import com.mojang.brigadier.arguments.StringArgumentType.string
import io.ktor.client.statement.* import io.ktor.client.statement.*
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource
import net.minecraft.text.Text
import moe.nea.firmament.apis.UrsaManager import moe.nea.firmament.apis.UrsaManager
import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlayScreen import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlayScreen
import moe.nea.firmament.features.world.FairySouls import moe.nea.firmament.features.world.FairySouls
import moe.nea.firmament.gui.config.AllConfigsGui import moe.nea.firmament.gui.config.AllConfigsGui
import moe.nea.firmament.gui.config.BooleanHandler
import moe.nea.firmament.gui.config.ManagedOption
import moe.nea.firmament.gui.profileviewer.ProfileViewer import moe.nea.firmament.gui.profileviewer.ProfileViewer
import moe.nea.firmament.repo.HypixelStaticData import moe.nea.firmament.repo.HypixelStaticData
import moe.nea.firmament.repo.RepoManager import moe.nea.firmament.repo.RepoManager
import moe.nea.firmament.util.FirmFormatters import moe.nea.firmament.util.*
import moe.nea.firmament.util.MC import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource
import moe.nea.firmament.util.SBData import net.minecraft.text.Text
import moe.nea.firmament.util.ScreenUtil
import moe.nea.firmament.util.SkyblockId
import moe.nea.firmament.util.unformattedString
fun firmamentCommand() = literal("firmament") { fun firmamentCommand() = literal("firmament") {
@@ -31,11 +28,65 @@ fun firmamentCommand() = literal("firmament") {
thenExecute { thenExecute {
AllConfigsGui.showAllGuis() AllConfigsGui.showAllGuis()
} }
thenLiteral("toggle") {
thenArgument("config", string()) { config ->
suggestsList {
AllConfigsGui.allConfigs.asSequence().map { it.name }.asIterable()
}
thenArgument("property", string()) { property ->
suggestsList {
(AllConfigsGui.allConfigs.find { it.name == this[config] }?:return@suggestsList listOf())
.allOptions.entries.asSequence().filter { it.value.handler is BooleanHandler }.map { it.key }
.asIterable()
}
thenExecute {
val config = this[config]
val property = this[property]
val configObj = AllConfigsGui.allConfigs.find { it.name == config }
if (configObj == null) {
source.sendFeedback(Text.translatable("firmament.command.toggle.no-config-found", config))
return@thenExecute
}
val propertyObj = configObj.allOptions[property]
if (propertyObj == null) {
source.sendFeedback(
Text.translatable(
"firmament.command.toggle.no-property-found",
property
)
)
return@thenExecute
}
if (propertyObj.handler !is BooleanHandler) {
source.sendFeedback(
Text.translatable(
"firmament.command.toggle.not-a-toggle",
property
)
)
return@thenExecute
}
propertyObj as ManagedOption<Boolean>
propertyObj.value = !propertyObj.value
configObj.save()
source.sendFeedback(
Text.translatable(
"firmament.command.toggle.toggled",
configObj.labelText,
propertyObj.labelText,
Text.translatable("firmament.toggle.${propertyObj.value}")
)
)
}
}
}
}
} }
thenLiteral("storage") { thenLiteral("storage") {
thenExecute { thenExecute {
ScreenUtil.setScreenLater(StorageOverlayScreen()) ScreenUtil.setScreenLater(StorageOverlayScreen())
MC.player?.networkHandler?.sendChatCommand("ec") MC.player?.networkHandler?.sendChatCommand("storage")
} }
} }
thenLiteral("repo") { thenLiteral("repo") {

View File

@@ -11,34 +11,31 @@ import io.github.cottonmc.cotton.gui.client.CottonClientScreen
import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription
import io.github.cottonmc.cotton.gui.widget.WBox import io.github.cottonmc.cotton.gui.widget.WBox
import io.github.cottonmc.cotton.gui.widget.WButton import io.github.cottonmc.cotton.gui.widget.WButton
import io.github.cottonmc.cotton.gui.widget.WClippedPanel
import io.github.cottonmc.cotton.gui.widget.WGridPanel
import io.github.cottonmc.cotton.gui.widget.WLabel import io.github.cottonmc.cotton.gui.widget.WLabel
import io.github.cottonmc.cotton.gui.widget.WPanel
import io.github.cottonmc.cotton.gui.widget.WPanelWithInsets
import io.github.cottonmc.cotton.gui.widget.WScrollPanel import io.github.cottonmc.cotton.gui.widget.WScrollPanel
import io.github.cottonmc.cotton.gui.widget.data.Axis import io.github.cottonmc.cotton.gui.widget.data.Axis
import io.github.cottonmc.cotton.gui.widget.data.Insets import io.github.cottonmc.cotton.gui.widget.data.Insets
import io.ktor.http.*
import kotlin.streams.asSequence
import net.minecraft.client.gui.screen.Screen
import net.minecraft.text.Text
import moe.nea.firmament.features.FeatureManager import moe.nea.firmament.features.FeatureManager
import moe.nea.firmament.gui.WFixedPanel import moe.nea.firmament.gui.WFixedPanel
import moe.nea.firmament.gui.WSplitPanel import moe.nea.firmament.gui.WSplitPanel
import moe.nea.firmament.gui.WTightScrollPanel
import moe.nea.firmament.repo.RepoManager import moe.nea.firmament.repo.RepoManager
import moe.nea.firmament.util.MC import moe.nea.firmament.util.MC
import moe.nea.firmament.util.ScreenUtil.setScreenLater import moe.nea.firmament.util.ScreenUtil.setScreenLater
import net.minecraft.client.gui.screen.Screen
import net.minecraft.text.Text
import kotlin.streams.asSequence
object AllConfigsGui { object AllConfigsGui {
val allConfigs
get() = listOf(
RepoManager.Config
) + FeatureManager.allFeatures.mapNotNull { it.config }
fun makeScreen(parent: Screen? = null): CottonClientScreen { fun makeScreen(parent: Screen? = null): CottonClientScreen {
val lwgd = LightweightGuiDescription() val lwgd = LightweightGuiDescription()
var screen: CottonClientScreen? = null var screen: CottonClientScreen? = null
val configs = listOf( val configs = allConfigs
RepoManager.Config
) + FeatureManager.allFeatures.mapNotNull { it.config }
val box = WBox(Axis.VERTICAL) val box = WBox(Axis.VERTICAL)
configs.forEach { config -> configs.forEach { config ->
val panel = WSplitPanel( val panel = WSplitPanel(

View File

@@ -148,6 +148,8 @@ abstract class ManagedConfig(override val name: String) : ManagedConfigElement()
latestGuiAppender?.reloadables?.forEach { it() } latestGuiAppender?.reloadables?.forEach { it() }
} }
val labelText = Text.translatable("firmament.config.${name}")
fun getConfigEditor(parent: Screen? = null): CottonClientScreen { fun getConfigEditor(parent: Screen? = null): CottonClientScreen {
val lwgd = LightweightGuiDescription() val lwgd = LightweightGuiDescription()
var screen: Screen? = null var screen: Screen? = null
@@ -165,7 +167,7 @@ abstract class ManagedConfig(override val name: String) : ManagedConfigElement()
} }
} }
}) })
it.add(WLabel(Text.translatable("firmament.config.${name}")).also { it.add(WLabel(labelText).also {
it.verticalAlignment = VerticalAlignment.CENTER it.verticalAlignment = VerticalAlignment.CENTER
}) })
}) })

View File

@@ -1,106 +1,112 @@
{ {
"firmament.dev.resourcerebuild.start": "Invoking gradle resource rebuild (./gradlew :processResources)", "firmament.dev.resourcerebuild.start": "Invoking gradle resource rebuild (./gradlew :processResources)",
"firmament.dev.resourcerebuild.done": "Gradle resource rebuild done in %s", "firmament.dev.resourcerebuild.done": "Gradle resource rebuild done in %s",
"firmament.config.developer": "Developer Settings", "firmament.command.toggle.no-config-found": "Could not find config %s",
"firmament.config.developer.auto-rebuild": "Automatically rebuild resources", "firmament.command.toggle.no-property-found": "Could not find property %s",
"firmament.price": "Checking price for %s", "firmament.command.toggle.not-a-toggle": "Property %s is not a toggle",
"firmament.price.bazaar": "Bazaar stats:", "firmament.command.toggle.toggled": "Toggled %s / %s %s",
"firmament.price.bazaar.productid": "Stock id: %s", "firmament.toggle.true": "On",
"firmament.price.bazaar.buy.price": "Buy Price: %s", "firmament.toggle.false": "Off",
"firmament.price.bazaar.buy.order": "Buy orders: %d", "firmament.config.developer": "Developer Settings",
"firmament.tooltip.bazaar.sell-order": "Bazaar Sell Order: %s", "firmament.config.developer.auto-rebuild": "Automatically rebuild resources",
"firmament.tooltip.bazaar.buy-order": "Bazaar Buy Order: %s", "firmament.price": "Checking price for %s",
"firmament.tooltip.ah.lowestbin": "Lowest BIN: %d", "firmament.price.bazaar": "Bazaar stats:",
"firmament.pv.pets": "Pets", "firmament.price.bazaar.productid": "Stock id: %s",
"firmament.debug.skyblockid": "SkyBlock ID: %s", "firmament.price.bazaar.buy.price": "Buy Price: %s",
"firmament.debug.skyblockid.copy": "Click to copy SkyBlock ID", "firmament.price.bazaar.buy.order": "Buy orders: %d",
"firmament.price.bazaar.sell.price": "Sell Price: %s", "firmament.tooltip.bazaar.sell-order": "Bazaar Sell Order: %s",
"firmament.price.bazaar.sell.order": "Sell orders: %d", "firmament.tooltip.bazaar.buy-order": "Bazaar Buy Order: %s",
"firmament.price.lowestbin": "Lowest BIN: %s", "firmament.tooltip.ah.lowestbin": "Lowest BIN: %d",
"firmament.repo.reload.network": "Trying to redownload the repository", "firmament.pv.pets": "Pets",
"firmament.repo.reload.disk": "Reloading repository from disk. This may lag a bit.", "firmament.debug.skyblockid": "SkyBlock ID: %s",
"firmament.repo.cache": "Recaching items", "firmament.debug.skyblockid.copy": "Click to copy SkyBlock ID",
"firmament.repo.brokenitem": "Failed to render item: %s", "firmament.price.bazaar.sell.price": "Sell Price: %s",
"firmanent.config.edit": "Edit", "firmament.price.bazaar.sell.order": "Sell orders: %d",
"firmament.config.repo": "Firmament Repo Settings", "firmament.price.lowestbin": "Lowest BIN: %s",
"firmament.config.repo.autoUpdate": "Auto Update", "firmament.repo.reload.network": "Trying to redownload the repository",
"firmament.config.repo.username": "Repo Username", "firmament.repo.reload.disk": "Reloading repository from disk. This may lag a bit.",
"firmament.config.repo.username.hint": "NotEnoughUpdates", "firmament.repo.cache": "Recaching items",
"firmament.config.repo.reponame": "Repo Name", "firmament.repo.brokenitem": "Failed to render item: %s",
"firmament.config.repo.reponame.hint": "NotEnoughUpdates-REPO", "firmanent.config.edit": "Edit",
"firmament.config.repo.branch": "Repo Branch", "firmament.config.repo": "Firmament Repo Settings",
"firmament.config.repo.branch.hint": "dangerous", "firmament.config.repo.autoUpdate": "Auto Update",
"firmament.config.repo.reset": "Reset", "firmament.config.repo.username": "Repo Username",
"firmament.config.repo.disable-item-groups": "Disable Item Groups", "firmament.config.repo.username.hint": "NotEnoughUpdates",
"firmament.config.repo.reload": "Reload Item List", "firmament.config.repo.reponame": "Repo Name",
"firmament.config.repo.redownload": "Redownload Item List", "firmament.config.repo.reponame.hint": "NotEnoughUpdates-REPO",
"firmament.ursa.debugrequest.start": "Ursa request launched", "firmament.config.repo.branch": "Repo Branch",
"firmament.ursa.debugrequest.result": "Ursa request succeeded: %s", "firmament.config.repo.branch.hint": "dangerous",
"firmament.sbinfo.nolocraw": "No locraw data available", "firmament.config.repo.reset": "Reset",
"firmament.sbinfo.profile": "Current profile cutename: %s", "firmament.config.repo.disable-item-groups": "Disable Item Groups",
"firmament.sbinfo.server": "Locraw Server: %s", "firmament.config.repo.reload": "Reload Item List",
"firmament.sbinfo.gametype": "Locraw Gametype: %s", "firmament.config.repo.redownload": "Redownload Item List",
"firmament.sbinfo.mode": "Locraw Mode: %s", "firmament.ursa.debugrequest.start": "Ursa request launched",
"firmament.sbinfo.map": "Locraw Map: %s", "firmament.ursa.debugrequest.result": "Ursa request succeeded: %s",
"firmament.config.price-data": "Price data", "firmament.sbinfo.nolocraw": "No locraw data available",
"firmament.config.price-data.enable-always": "Enable Item Price", "firmament.sbinfo.profile": "Current profile cutename: %s",
"firmament.config.price-data.enable-keybind": "Enable only with Keybinding", "firmament.sbinfo.server": "Locraw Server: %s",
"firmament.config.fairy-souls": "Fairy Souls", "firmament.sbinfo.gametype": "Locraw Gametype: %s",
"firmament.config.fairy-souls.show": "Show Fairy Soul Waypoints", "firmament.sbinfo.mode": "Locraw Mode: %s",
"firmament.config.fairy-souls.reset": "Reset Collected Fairy Souls", "firmament.sbinfo.map": "Locraw Map: %s",
"firmament.config.fishing-warning": "Fishing Warning", "firmament.config.price-data": "Price data",
"firmament.config.fishing-warning.display-warning": "Display a warning when you are about to hook a fish", "firmament.config.price-data.enable-always": "Enable Item Price",
"firmament.config.fishing-warning.highlight-wake-chain": "Highlight fishing particles", "firmament.config.price-data.enable-keybind": "Enable only with Keybinding",
"firmament.key.slotlocking": "Lock Slot / Slot Binding", "firmament.config.fairy-souls": "Fairy Souls",
"firmament.key.category": "Firmament", "firmament.config.fairy-souls.show": "Show Fairy Soul Waypoints",
"firmament.protectitem": "Firmament protected your item: ", "firmament.config.fairy-souls.reset": "Reset Collected Fairy Souls",
"firmament.recipe.forge.time": "Forging Time: %s", "firmament.config.fishing-warning": "Fishing Warning",
"firmament.pv.skills": "Skills", "firmament.config.fishing-warning.display-warning": "Display a warning when you are about to hook a fish",
"firmament.pv.skills.farming": "Farming", "firmament.config.fishing-warning.highlight-wake-chain": "Highlight fishing particles",
"firmament.pv.skills.foraging": "Foraging", "firmament.key.slotlocking": "Lock Slot / Slot Binding",
"firmament.pv.skills.mining": "Mining", "firmament.key.category": "Firmament",
"firmament.pv.skills.alchemy": "Alchemy", "firmament.protectitem": "Firmament protected your item: ",
"firmament.pv.skills.taming": "Taming", "firmament.recipe.forge.time": "Forging Time: %s",
"firmament.pv.skills.fishing": "Fishing", "firmament.pv.skills": "Skills",
"firmament.pv.skills.runecrafting": "Runecrafting", "firmament.pv.skills.farming": "Farming",
"firmament.pv.skills.carpentry": "Carpentry", "firmament.pv.skills.foraging": "Foraging",
"firmament.pv.skills.combat": "Combat", "firmament.pv.skills.mining": "Mining",
"firmament.pv.skills.social": "Social", "firmament.pv.skills.alchemy": "Alchemy",
"firmament.pv.skills.rift": "Rift", "firmament.pv.skills.taming": "Taming",
"firmament.pv.skills.enchanting": "Enchanting", "firmament.pv.skills.fishing": "Fishing",
"firmament.pv.skills.total": "Total Exp: %s", "firmament.pv.skills.runecrafting": "Runecrafting",
"firmament.pv.lookingup": "Looking up %s", "firmament.pv.skills.carpentry": "Carpentry",
"firmament.pv.noprofile": "%s has no SkyBlock profiles", "firmament.pv.skills.combat": "Combat",
"firmament.pv.noplayer": "%s is not a Minecraft player", "firmament.pv.skills.social": "Social",
"firmament.config.save-cursor-position.enable": "Enable", "firmament.pv.skills.rift": "Rift",
"firmament.config.save-cursor-position.tolerance": "Tolerance", "firmament.pv.skills.enchanting": "Enchanting",
"firmament.config.save-cursor-position": "Save Cursor Position", "firmament.pv.skills.total": "Total Exp: %s",
"firmament.config.storage-overlay": "Storage Overlay", "firmament.pv.lookingup": "Looking up %s",
"firmament.config.storage-overlay.rows": "Rows", "firmament.pv.noprofile": "%s has no SkyBlock profiles",
"firmament.config.storage-overlay.padding": "Padding", "firmament.pv.noplayer": "%s is not a Minecraft player",
"firmament.config.storage-overlay.scroll-speed": "Scroll Speed", "firmament.config.save-cursor-position.enable": "Enable",
"firmament.config.storage-overlay.inverse-scroll": "Invert Scroll", "firmament.config.save-cursor-position.tolerance": "Tolerance",
"firmament.config.storage-overlay.margin": "Margin", "firmament.config.save-cursor-position": "Save Cursor Position",
"firmament.config.chat-links": "Chat Links", "firmament.config.storage-overlay": "Storage Overlay",
"firmament.config.chat-links.links-enabled": "Enable Clickable Links", "firmament.config.storage-overlay.rows": "Rows",
"firmament.config.chat-links.image-enabled": "Enable Image Preview", "firmament.config.storage-overlay.padding": "Padding",
"firmament.config.chat-links.allow-all-hosts": "Allow all Image Hosts", "firmament.config.storage-overlay.scroll-speed": "Scroll Speed",
"firmament.config.chat-links.allowed-hosts": "Allowed Image Hosts", "firmament.config.storage-overlay.inverse-scroll": "Invert Scroll",
"firmament.config.chat-links.position": "Chat Image Preview", "firmament.config.storage-overlay.margin": "Margin",
"firmament.hud.edit": "Edit %s", "firmament.config.chat-links": "Chat Links",
"firmament.keybinding.external": "External", "firmament.config.chat-links.links-enabled": "Enable Clickable Links",
"firmament.config.slot-locking": "Slot Locking", "firmament.config.chat-links.image-enabled": "Enable Image Preview",
"firmament.config.slot-locking.lock": "Lock Slot", "firmament.config.chat-links.allow-all-hosts": "Allow all Image Hosts",
"firmament.config.fixes.auto-sprint": "Auto Sprint", "firmament.config.chat-links.allowed-hosts": "Allowed Image Hosts",
"firmament.config.fixes.auto-sprint-keybinding": "Auto Sprint KeyBinding", "firmament.config.chat-links.position": "Chat Image Preview",
"firmament.config.fixes.auto-sprint-hud": "Sprint State Hud", "firmament.hud.edit": "Edit %s",
"firmament.config.fixes.peek-chat": "Peek Chat", "firmament.keybinding.external": "External",
"firmament.fixes.auto-sprint.on": "Sprint toggled", "firmament.config.slot-locking": "Slot Locking",
"firmament.fixes.auto-sprint.sprinting": "Sprinting", "firmament.config.slot-locking.lock": "Lock Slot",
"firmament.fixes.auto-sprint.not-sprinting": "Not Sprinting", "firmament.config.fixes.auto-sprint": "Auto Sprint",
"firmament.config.custom-skyblock-textures": "Custom SkyBlock Item Textures", "firmament.config.fixes.auto-sprint-keybinding": "Auto Sprint KeyBinding",
"firmament.config.custom-skyblock-textures.cache-duration": "Model Cache Duration", "firmament.config.fixes.auto-sprint-hud": "Sprint State Hud",
"firmament.config.custom-skyblock-textures.enabled": "Enable Custom Item Textures", "firmament.config.fixes.peek-chat": "Peek Chat",
"firmament.config.fixes": "Fixes", "firmament.fixes.auto-sprint.on": "Sprint toggled",
"firmament.config.fixes.player-skins": "Fix unsigned Player Skins" "firmament.fixes.auto-sprint.sprinting": "Sprinting",
"firmament.fixes.auto-sprint.not-sprinting": "Not Sprinting",
"firmament.config.custom-skyblock-textures": "Custom SkyBlock Item Textures",
"firmament.config.custom-skyblock-textures.cache-duration": "Model Cache Duration",
"firmament.config.custom-skyblock-textures.enabled": "Enable Custom Item Textures",
"firmament.config.fixes": "Fixes",
"firmament.config.fixes.player-skins": "Fix unsigned Player Skins"
} }