aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/features/debug
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2024-08-28 19:04:24 +0200
committerLinnea Gräf <nea@nea.moe>2024-08-28 19:04:24 +0200
commitd2f240ff0ca0d27f417f837e706c781a98c31311 (patch)
tree0db7aff6cc14deaf36eed83889d59fd6b3a6f599 /src/main/kotlin/features/debug
parenta6906308163aa3b2d18fa1dc1aa71ac9bbcc83ab (diff)
downloadfirmament-d2f240ff0ca0d27f417f837e706c781a98c31311.tar.gz
firmament-d2f240ff0ca0d27f417f837e706c781a98c31311.tar.bz2
firmament-d2f240ff0ca0d27f417f837e706c781a98c31311.zip
Refactor source layout
Introduce compat source sets and move all kotlin sources to the main directory [no changelog]
Diffstat (limited to 'src/main/kotlin/features/debug')
-rw-r--r--src/main/kotlin/features/debug/DebugLogger.kt13
-rw-r--r--src/main/kotlin/features/debug/DebugView.kt38
-rw-r--r--src/main/kotlin/features/debug/DeveloperFeatures.kt55
-rw-r--r--src/main/kotlin/features/debug/MinorTrolling.kt27
-rw-r--r--src/main/kotlin/features/debug/PowerUserTools.kt193
5 files changed, 326 insertions, 0 deletions
diff --git a/src/main/kotlin/features/debug/DebugLogger.kt b/src/main/kotlin/features/debug/DebugLogger.kt
new file mode 100644
index 0000000..ab06030
--- /dev/null
+++ b/src/main/kotlin/features/debug/DebugLogger.kt
@@ -0,0 +1,13 @@
+
+package moe.nea.firmament.features.debug
+
+import net.minecraft.text.Text
+import moe.nea.firmament.util.MC
+
+class DebugLogger(val tag: String) {
+ fun isEnabled() = DeveloperFeatures.isEnabled // TODO: allow filtering by tag
+ fun log(text: () -> String) {
+ if (!isEnabled()) return
+ MC.sendChat(Text.literal(text()))
+ }
+}
diff --git a/src/main/kotlin/features/debug/DebugView.kt b/src/main/kotlin/features/debug/DebugView.kt
new file mode 100644
index 0000000..7e1b8ec
--- /dev/null
+++ b/src/main/kotlin/features/debug/DebugView.kt
@@ -0,0 +1,38 @@
+
+
+package moe.nea.firmament.features.debug
+
+import moe.nea.firmament.Firmament
+import moe.nea.firmament.events.TickEvent
+import moe.nea.firmament.features.FirmamentFeature
+import moe.nea.firmament.util.TimeMark
+
+object DebugView : FirmamentFeature {
+ private data class StoredVariable<T>(
+ val obj: T,
+ val timer: TimeMark,
+ )
+
+ private val storedVariables: MutableMap<String, StoredVariable<*>> = sortedMapOf()
+ override val identifier: String
+ get() = "debug-view"
+ override val defaultEnabled: Boolean
+ get() = Firmament.DEBUG
+
+ fun <T : Any?> showVariable(label: String, obj: T) {
+ synchronized(this) {
+ storedVariables[label] = StoredVariable(obj, TimeMark.now())
+ }
+ }
+
+ fun recalculateDebugWidget() {
+ }
+
+ override fun onLoad() {
+ TickEvent.subscribe {
+ synchronized(this) {
+ recalculateDebugWidget()
+ }
+ }
+ }
+}
diff --git a/src/main/kotlin/features/debug/DeveloperFeatures.kt b/src/main/kotlin/features/debug/DeveloperFeatures.kt
new file mode 100644
index 0000000..20c0cfd
--- /dev/null
+++ b/src/main/kotlin/features/debug/DeveloperFeatures.kt
@@ -0,0 +1,55 @@
+
+
+package moe.nea.firmament.features.debug
+
+import java.nio.file.Path
+import java.util.concurrent.CompletableFuture
+import kotlin.io.path.absolute
+import kotlin.io.path.exists
+import net.minecraft.client.MinecraftClient
+import net.minecraft.text.Text
+import moe.nea.firmament.Firmament
+import moe.nea.firmament.features.FirmamentFeature
+import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.MC
+import moe.nea.firmament.util.TimeMark
+import moe.nea.firmament.util.errorBoundary
+import moe.nea.firmament.util.iterate
+
+object DeveloperFeatures : FirmamentFeature {
+ override val identifier: String
+ get() = "developer"
+ override val config: TConfig
+ get() = TConfig
+ override val defaultEnabled: Boolean
+ get() = Firmament.DEBUG
+
+ val gradleDir =
+ Path.of(".").absolute()
+ .iterate { it.parent }
+ .find { it.resolve("settings.gradle.kts").exists() }
+
+ object TConfig : ManagedConfig("developer") {
+ val autoRebuildResources by toggle("auto-rebuild") { false }
+ }
+
+ @JvmStatic
+ fun hookOnBeforeResourceReload(client: MinecraftClient): CompletableFuture<Void> {
+ val reloadFuture = if (TConfig.autoRebuildResources && isEnabled && gradleDir != null) {
+ val builder = ProcessBuilder("./gradlew", ":processResources")
+ builder.directory(gradleDir.toFile())
+ builder.inheritIO()
+ val process = builder.start()
+ MC.player?.sendMessage(Text.translatable("firmament.dev.resourcerebuild.start"))
+ val startTime = TimeMark.now()
+ process.toHandle().onExit().thenApply {
+ MC.player?.sendMessage(Text.stringifiedTranslatable("firmament.dev.resourcerebuild.done", startTime.passedTime()))
+ Unit
+ }
+ } else {
+ CompletableFuture.completedFuture(Unit)
+ }
+ return reloadFuture.thenCompose { client.reloadResources() }
+ }
+}
+
diff --git a/src/main/kotlin/features/debug/MinorTrolling.kt b/src/main/kotlin/features/debug/MinorTrolling.kt
new file mode 100644
index 0000000..32035a6
--- /dev/null
+++ b/src/main/kotlin/features/debug/MinorTrolling.kt
@@ -0,0 +1,27 @@
+
+
+package moe.nea.firmament.features.debug
+
+import net.minecraft.text.Text
+import moe.nea.firmament.annotations.Subscribe
+import moe.nea.firmament.events.ModifyChatEvent
+import moe.nea.firmament.features.FirmamentFeature
+
+
+// In memorian Dulkir
+object MinorTrolling : FirmamentFeature {
+ override val identifier: String
+ get() = "minor-trolling"
+
+ val trollers = listOf("nea89o", "lrg89")
+ val t = "From(?: \\[[^\\]]+])? ([^:]+): (.*)".toRegex()
+
+ @Subscribe
+ fun onTroll(it: ModifyChatEvent) {
+ val m = t.matchEntire(it.unformattedString) ?: return
+ val (_, name, text) = m.groupValues
+ if (name !in trollers) return
+ if (!text.startsWith("c:")) return
+ it.replaceWith = Text.literal(text.substring(2).replace("&", "§"))
+ }
+}
diff --git a/src/main/kotlin/features/debug/PowerUserTools.kt b/src/main/kotlin/features/debug/PowerUserTools.kt
new file mode 100644
index 0000000..7893eff
--- /dev/null
+++ b/src/main/kotlin/features/debug/PowerUserTools.kt
@@ -0,0 +1,193 @@
+
+
+package moe.nea.firmament.features.debug
+
+import net.minecraft.block.SkullBlock
+import net.minecraft.block.entity.SkullBlockEntity
+import net.minecraft.component.DataComponentTypes
+import net.minecraft.entity.Entity
+import net.minecraft.entity.LivingEntity
+import net.minecraft.item.ItemStack
+import net.minecraft.item.Items
+import net.minecraft.text.Text
+import net.minecraft.util.hit.BlockHitResult
+import net.minecraft.util.hit.EntityHitResult
+import net.minecraft.util.hit.HitResult
+import moe.nea.firmament.annotations.Subscribe
+import moe.nea.firmament.events.CommandEvent
+import moe.nea.firmament.events.CustomItemModelEvent
+import moe.nea.firmament.events.HandledScreenKeyPressedEvent
+import moe.nea.firmament.events.ItemTooltipEvent
+import moe.nea.firmament.events.ScreenChangeEvent
+import moe.nea.firmament.events.TickEvent
+import moe.nea.firmament.events.WorldKeyboardEvent
+import moe.nea.firmament.features.FirmamentFeature
+import moe.nea.firmament.features.texturepack.CustomSkyBlockTextures
+import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.mixins.accessor.AccessorHandledScreen
+import moe.nea.firmament.util.ClipboardUtils
+import moe.nea.firmament.util.MC
+import moe.nea.firmament.util.focusedItemStack
+import moe.nea.firmament.util.skyBlockId
+
+object PowerUserTools : FirmamentFeature {
+ override val identifier: String
+ get() = "power-user"
+
+ object TConfig : ManagedConfig(identifier) {
+ val showItemIds by toggle("show-item-id") { false }
+ val copyItemId by keyBindingWithDefaultUnbound("copy-item-id")
+ val copyTexturePackId by keyBindingWithDefaultUnbound("copy-texture-pack-id")
+ val copyNbtData by keyBindingWithDefaultUnbound("copy-nbt-data")
+ val copySkullTexture by keyBindingWithDefaultUnbound("copy-skull-texture")
+ val copyEntityData by keyBindingWithDefaultUnbound("entity-data")
+ }
+
+ override val config
+ get() = TConfig
+
+ var lastCopiedStack: Pair<ItemStack, Text>? = null
+ set(value) {
+ field = value
+ if (value != null)
+ lastCopiedStackViewTime = true
+ }
+ var lastCopiedStackViewTime = false
+
+ override fun onLoad() {
+ TickEvent.subscribe {
+ if (!lastCopiedStackViewTime)
+ lastCopiedStack = null
+ lastCopiedStackViewTime = false
+ }
+ ScreenChangeEvent.subscribe {
+ lastCopiedStack = null
+ }
+ }
+
+ fun debugFormat(itemStack: ItemStack): Text {
+ return Text.literal(itemStack.skyBlockId?.toString() ?: itemStack.toString())
+ }
+
+ @Subscribe
+ fun onEntityInfo(event: WorldKeyboardEvent) {
+ if (!event.matches(TConfig.copyEntityData)) return
+ val target = (MC.instance.crosshairTarget as? EntityHitResult)?.entity
+ if (target == null) {
+ MC.sendChat(Text.translatable("firmament.poweruser.entity.fail"))
+ return
+ }
+ showEntity(target)
+ }
+
+ fun showEntity(target: Entity) {
+ MC.sendChat(Text.translatable("firmament.poweruser.entity.type", target.type))
+ MC.sendChat(Text.translatable("firmament.poweruser.entity.name", target.name))
+ MC.sendChat(Text.stringifiedTranslatable("firmament.poweruser.entity.position", target.pos))
+ if (target is LivingEntity) {
+ MC.sendChat(Text.translatable("firmament.poweruser.entity.armor"))
+ for (armorItem in target.armorItems) {
+ MC.sendChat(Text.translatable("firmament.poweruser.entity.armor.item", debugFormat(armorItem)))
+ }
+ }
+ MC.sendChat(Text.stringifiedTranslatable("firmament.poweruser.entity.passengers", target.passengerList.size))
+ target.passengerList.forEach {
+ showEntity(it)
+ }
+ }
+
+
+ @Subscribe
+ fun copyInventoryInfo(it: HandledScreenKeyPressedEvent) {
+ if (it.screen !is AccessorHandledScreen) return
+ val item = it.screen.focusedItemStack ?: return
+ if (it.matches(TConfig.copyItemId)) {
+ val sbId = item.skyBlockId
+ if (sbId == null) {
+ lastCopiedStack = Pair(item, Text.translatable("firmament.tooltip.copied.skyblockid.fail"))
+ return
+ }
+ ClipboardUtils.setTextContent(sbId.neuItem)
+ lastCopiedStack =
+ Pair(item, Text.stringifiedTranslatable("firmament.tooltip.copied.skyblockid", sbId.neuItem))
+ } else if (it.matches(TConfig.copyTexturePackId)) {
+ val model = CustomItemModelEvent.getModelIdentifier(item)
+ if (model == null) {
+ lastCopiedStack = Pair(item, Text.translatable("firmament.tooltip.copied.modelid.fail"))
+ return
+ }
+ ClipboardUtils.setTextContent(model.toString())
+ lastCopiedStack =
+ Pair(item, Text.stringifiedTranslatable("firmament.tooltip.copied.modelid", model.toString()))
+ } else if (it.matches(TConfig.copyNbtData)) {
+ // TODO: copy full nbt
+ val nbt = item.get(DataComponentTypes.CUSTOM_DATA)?.nbt?.toString() ?: "<empty>"
+ ClipboardUtils.setTextContent(nbt)
+ lastCopiedStack = Pair(item, Text.translatable("firmament.tooltip.copied.nbt"))
+ } else if (it.matches(TConfig.copySkullTexture)) {
+ if (item.item != Items.PLAYER_HEAD) {
+ lastCopiedStack = Pair(item, Text.translatable("firmament.tooltip.copied.skull-id.fail.no-skull"))
+ return
+ }
+ val profile = item.get(DataComponentTypes.PROFILE)
+ if (profile == null) {
+ lastCopiedStack = Pair(item, Text.translatable("firmament.tooltip.copied.skull-id.fail.no-profile"))
+ return
+ }
+ val skullTexture = CustomSkyBlockTextures.getSkullTexture(profile)
+ if (skullTexture == null) {
+ lastCopiedStack = Pair(item, Text.translatable("firmament.tooltip.copied.skull-id.fail.no-texture"))
+ return
+ }
+ ClipboardUtils.setTextContent(skullTexture.toString())
+ lastCopiedStack =
+ Pair(
+ item,
+ Text.stringifiedTranslatable("firmament.tooltip.copied.skull-id", skullTexture.toString())
+ )
+ println("Copied skull id: $skullTexture")
+ }
+ }
+
+ @Subscribe
+ fun onCopyWorldInfo(it: WorldKeyboardEvent) {
+ if (it.matches(TConfig.copySkullTexture)) {
+ val p = MC.camera ?: return
+ val blockHit = p.raycast(20.0, 0.0f, false) ?: return
+ if (blockHit.type != HitResult.Type.BLOCK || blockHit !is BlockHitResult) {
+ MC.sendChat(Text.translatable("firmament.tooltip.copied.skull.fail"))
+ return
+ }
+ val blockAt = p.world.getBlockState(blockHit.blockPos)?.block
+ val entity = p.world.getBlockEntity(blockHit.blockPos)
+ if (blockAt !is SkullBlock || entity !is SkullBlockEntity || entity.owner == null) {
+ MC.sendChat(Text.translatable("firmament.tooltip.copied.skull.fail"))
+ return
+ }
+ val id = CustomSkyBlockTextures.getSkullTexture(entity.owner!!)
+ if (id == null) {
+ MC.sendChat(Text.translatable("firmament.tooltip.copied.skull.fail"))
+ } else {
+ ClipboardUtils.setTextContent(id.toString())
+ MC.sendChat(Text.stringifiedTranslatable("firmament.tooltip.copied.skull", id.toString()))
+ }
+ }
+ }
+
+ @Subscribe
+ fun addItemId(it: ItemTooltipEvent) {
+ if (TConfig.showItemIds) {
+ val id = it.stack.skyBlockId ?: return
+ it.lines.add(Text.stringifiedTranslatable("firmament.tooltip.skyblockid", id.neuItem))
+ }
+ val (item, text) = lastCopiedStack ?: return
+ if (!ItemStack.areEqual(item, it.stack)) {
+ lastCopiedStack = null
+ return
+ }
+ lastCopiedStackViewTime = true
+ it.lines.add(text)
+ }
+
+
+}