aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/features/debug/PowerUserTools.kt
blob: dccf8f7f042608c55145f84491abd781e14a3fa7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
package moe.nea.firmament.features.debug

import net.minecraft.block.SkullBlock
import net.minecraft.block.entity.SkullBlockEntity
import net.minecraft.client.gui.screen.Screen
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

    @Subscribe
    fun resetLastCopiedStack(event: TickEvent) {
        if (!lastCopiedStackViewTime)
            lastCopiedStack = null
        lastCopiedStackViewTime = false
    }

    @Subscribe
    fun resetLastCopiedStackOnScreenChange(event: ScreenChangeEvent) {
        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)
    }


}