package moe.nea.firmament.commands import com.mojang.brigadier.CommandDispatcher import com.mojang.brigadier.arguments.StringArgumentType.string import io.ktor.client.statement.bodyAsText import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource import net.minecraft.text.Text import moe.nea.firmament.apis.UrsaManager import moe.nea.firmament.events.CommandEvent import moe.nea.firmament.events.FirmamentEventBus import moe.nea.firmament.features.debug.DebugLogger import moe.nea.firmament.features.debug.PowerUserTools import moe.nea.firmament.features.inventory.buttons.InventoryButtons import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlayScreen import moe.nea.firmament.features.inventory.storageoverlay.StorageOverviewScreen 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.init.MixinPlugin import moe.nea.firmament.repo.HypixelStaticData import moe.nea.firmament.repo.RepoManager import moe.nea.firmament.util.FirmFormatters import moe.nea.firmament.util.MC import moe.nea.firmament.util.SBData import moe.nea.firmament.util.ScreenUtil import moe.nea.firmament.util.SkyblockId import moe.nea.firmament.util.collections.InstanceList import moe.nea.firmament.util.collections.WeakCache fun firmamentCommand() = literal("firmament") { thenLiteral("config") { thenExecute { 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.stringifiedTranslatable( "firmament.command.toggle.no-config-found", config ) ) return@thenExecute } val propertyObj = configObj.allOptions[property] if (propertyObj == null) { source.sendFeedback( Text.stringifiedTranslatable("firmament.command.toggle.no-property-found", property) ) return@thenExecute } if (propertyObj.handler !is BooleanHandler) { source.sendFeedback( Text.stringifiedTranslatable("firmament.command.toggle.not-a-toggle", property) ) return@thenExecute } propertyObj as ManagedOption propertyObj.value = !propertyObj.value configObj.save() source.sendFeedback( Text.stringifiedTranslatable( "firmament.command.toggle.toggled", configObj.labelText, propertyObj.labelText, Text.translatable("firmament.toggle.${propertyObj.value}") ) ) } } } } } thenLiteral("buttons") { thenExecute { InventoryButtons.openEditor() } } thenLiteral("sendcoords") { thenExecute { val p = MC.player ?: return@thenExecute MC.sendServerChat("x: ${p.blockX}, y: ${p.blockY}, z: ${p.blockZ}") } thenArgument("rest", RestArgumentType) { rest -> thenExecute { val p = MC.player ?: return@thenExecute MC.sendServerChat("x: ${p.blockX}, y: ${p.blockY}, z: ${p.blockZ} ${this[rest]}") } } } thenLiteral("storageoverview") { thenExecute { ScreenUtil.setScreenLater(StorageOverviewScreen()) MC.player?.networkHandler?.sendChatCommand("storage") } } thenLiteral("storage") { thenExecute { ScreenUtil.setScreenLater(StorageOverlayScreen()) MC.player?.networkHandler?.sendChatCommand("storage") } } thenLiteral("repo") { thenLiteral("reload") { thenLiteral("fetch") { thenExecute { source.sendFeedback(Text.translatable("firmament.repo.reload.network")) // TODO better reporting RepoManager.launchAsyncUpdate() } } thenExecute { source.sendFeedback(Text.translatable("firmament.repo.reload.disk")) RepoManager.reload() } } } thenLiteral("price") { thenArgument("item", string()) { item -> suggestsList { RepoManager.neuRepo.items.items.keys } thenExecute { val itemName = SkyblockId(get(item)) source.sendFeedback(Text.stringifiedTranslatable("firmament.price", itemName.neuItem)) val bazaarData = HypixelStaticData.bazaarData[itemName] if (bazaarData != null) { source.sendFeedback(Text.translatable("firmament.price.bazaar")) source.sendFeedback( Text.stringifiedTranslatable("firmament.price.bazaar.productid", bazaarData.productId.bazaarId) ) source.sendFeedback( Text.stringifiedTranslatable( "firmament.price.bazaar.buy.price", FirmFormatters.formatCommas(bazaarData.quickStatus.buyPrice, 1) ) ) source.sendFeedback( Text.stringifiedTranslatable( "firmament.price.bazaar.buy.order", bazaarData.quickStatus.buyOrders ) ) source.sendFeedback( Text.stringifiedTranslatable( "firmament.price.bazaar.sell.price", FirmFormatters.formatCommas(bazaarData.quickStatus.sellPrice, 1) ) ) source.sendFeedback( Text.stringifiedTranslatable( "firmament.price.bazaar.sell.order", bazaarData.quickStatus.sellOrders ) ) } val lowestBin = HypixelStaticData.lowestBin[itemName] if (lowestBin != null) { source.sendFeedback( Text.stringifiedTranslatable( "firmament.price.lowestbin", FirmFormatters.formatCommas(lowestBin, 1) ) ) } } } } thenLiteral("dev") { thenLiteral("simulate") { thenArgument("message", RestArgumentType) { message -> thenExecute { MC.instance.messageHandler.onGameMessage(Text.literal(get(message)), false) } } } thenLiteral("debuglog") { thenLiteral("toggle") { thenArgument("tag", string()) { tag -> suggestsList { DebugLogger.allInstances.getAll().map { it.tag } + DebugLogger.EnabledLogs.data } thenExecute { val tagText = this[tag] val enabled = DebugLogger.EnabledLogs.data if (tagText in enabled) { enabled.remove(tagText) source.sendFeedback(Text.literal("Disabled $tagText debug logging")) } else { enabled.add(tagText) source.sendFeedback(Text.literal("Enabled $tagText debug logging")) } } } } } thenLiteral("sbdata") { thenExecute { source.sendFeedback(Text.stringifiedTranslatable("firmament.sbinfo.profile", SBData.profileId)) val locrawInfo = SBData.locraw if (locrawInfo == null) { source.sendFeedback(Text.translatable("firmament.sbinfo.nolocraw")) } else { source.sendFeedback(Text.stringifiedTranslatable("firmament.sbinfo.server", locrawInfo.server)) 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)) } } } thenLiteral("copyEntities") { thenExecute { val player = MC.player ?: return@thenExecute player.world.getOtherEntities(player, player.boundingBox.expand(12.0)) .forEach(PowerUserTools::showEntity) } } 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)) } } } thenLiteral("events") { thenExecute { source.sendFeedback(Text.translatable("firmament.event.start")) FirmamentEventBus.allEventBuses.forEach { eventBus -> source.sendFeedback(Text.translatable( "firmament.event.bustype", eventBus.eventType.typeName.removePrefix("moe.nea.firmament"))) eventBus.handlers.forEach { handler -> source.sendFeedback(Text.translatable( "firmament.event.handler", handler.label)) } } } } thenLiteral("caches") { thenExecute { source.sendFeedback(Text.literal("Caches:")) WeakCache.allInstances.getAll().forEach { source.sendFeedback(Text.literal(" - ${it.name}: ${it.size}")) } source.sendFeedback(Text.translatable("Instance lists:")) InstanceList.allInstances.getAll().forEach { source.sendFeedback(Text.literal(" - ${it.name}: ${it.size}")) } } } thenLiteral("mixins") { thenExecute { source.sendFeedback(Text.translatable("firmament.mixins.start")) MixinPlugin.appliedMixins .map { it.removePrefix(MixinPlugin.mixinPackage) } .forEach { source.sendFeedback(Text.literal(" - ").withColor(0xD020F0) .append(Text.literal(it).withColor(0xF6BA20))) } } } } CommandEvent.SubCommand.publish(CommandEvent.SubCommand(this@literal)) } fun registerFirmamentCommand(dispatcher: CommandDispatcher) { val firmament = dispatcher.register(firmamentCommand()) dispatcher.register(literal("firm") { redirect(firmament) }) }