diff options
Diffstat (limited to 'src/main/kotlin/features/debug/DeveloperFeatures.kt')
| -rw-r--r-- | src/main/kotlin/features/debug/DeveloperFeatures.kt | 78 |
1 files changed, 61 insertions, 17 deletions
diff --git a/src/main/kotlin/features/debug/DeveloperFeatures.kt b/src/main/kotlin/features/debug/DeveloperFeatures.kt index 8f0c25c..8638bb6 100644 --- a/src/main/kotlin/features/debug/DeveloperFeatures.kt +++ b/src/main/kotlin/features/debug/DeveloperFeatures.kt @@ -3,33 +3,38 @@ package moe.nea.firmament.features.debug import java.io.File import java.nio.file.Path import java.util.concurrent.CompletableFuture +import org.objectweb.asm.ClassReader +import org.objectweb.asm.Type +import org.objectweb.asm.tree.ClassNode +import org.spongepowered.asm.mixin.Mixin import kotlinx.serialization.json.encodeToStream import kotlin.io.path.absolute import kotlin.io.path.exists -import net.minecraft.client.MinecraftClient -import net.minecraft.text.Text +import net.minecraft.client.Minecraft +import net.minecraft.network.chat.Component import moe.nea.firmament.Firmament import moe.nea.firmament.annotations.Subscribe +import moe.nea.firmament.events.DebugInstantiateEvent import moe.nea.firmament.events.TickEvent -import moe.nea.firmament.features.FirmamentFeature -import moe.nea.firmament.gui.config.ManagedConfig +import moe.nea.firmament.init.MixinPlugin import moe.nea.firmament.util.MC import moe.nea.firmament.util.TimeMark +import moe.nea.firmament.util.asm.AsmAnnotationUtil +import moe.nea.firmament.util.data.Config +import moe.nea.firmament.util.data.ManagedConfig import moe.nea.firmament.util.iterate -object DeveloperFeatures : FirmamentFeature { - override val identifier: String +object DeveloperFeatures { + val DEVELOPER_SUBCOMMAND: String = "dev" + 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() } + @Config object TConfig : ManagedConfig("developer", Category.DEV) { val autoRebuildResources by toggle("auto-rebuild") { false } } @@ -42,6 +47,42 @@ object DeveloperFeatures : FirmamentFeature { } @Subscribe + fun loadAllMixinClasses(event: DebugInstantiateEvent) { + val allMixinClasses = mutableSetOf<String>() + MixinPlugin.instances.forEach { plugin -> + val prefix = plugin.mixinPackage + "." + val classes = plugin.mixins.map { prefix + it } + allMixinClasses.addAll(classes) + for (cls in classes) { + val targets = javaClass.classLoader.getResourceAsStream("${cls.replace(".", "/")}.class").use { + val node = ClassNode() + ClassReader(it).accept(node, 0) + val mixins = mutableListOf<Mixin>() + (node.visibleAnnotations.orEmpty() + node.invisibleAnnotations.orEmpty()).forEach { + val annotationType = Type.getType(it.desc) + val mixinType = Type.getType(Mixin::class.java) + if (mixinType == annotationType) { + mixins.add(AsmAnnotationUtil.createProxy(Mixin::class.java, it)) + } + } + mixins.flatMap { it.targets.toList() } + mixins.flatMap { it.value.map { it.java.name } } + } + for (target in targets) + try { + Firmament.logger.debug("Loading ${target} to force instantiate ${cls}") + Class.forName(target, true, javaClass.classLoader) + } catch (ex: Throwable) { + Firmament.logger.error("Could not load class ${target} that has been mixind by $cls", ex) + } + } + } + Firmament.logger.info("Forceloaded all Firmament mixins:") + val applied = MixinPlugin.instances.flatMap { it.appliedMixins }.toSet() + applied.forEach { Firmament.logger.info(" - ${it}") } + require(allMixinClasses == applied) + } + + @Subscribe fun dumpMissingTranslations(tickEvent: TickEvent) { val toDump = missingTranslations ?: return missingTranslations = null @@ -51,24 +92,27 @@ object DeveloperFeatures : FirmamentFeature { } @JvmStatic - fun hookOnBeforeResourceReload(client: MinecraftClient): CompletableFuture<Void> { - val reloadFuture = if (TConfig.autoRebuildResources && isEnabled && gradleDir != null) { + fun hookOnBeforeResourceReload(client: Minecraft): CompletableFuture<Void> { + val reloadFuture = if (TConfig.autoRebuildResources && Firmament.DEBUG && gradleDir != null) { val builder = ProcessBuilder("./gradlew", ":processResources") builder.directory(gradleDir.toFile()) builder.inheritIO() val process = builder.start() - MC.sendChat(Text.translatable("firmament.dev.resourcerebuild.start")) + MC.sendChat(Component.translatable("firmament.dev.resourcerebuild.start")) val startTime = TimeMark.now() process.toHandle().onExit().thenApply { - MC.sendChat(Text.stringifiedTranslatable( - "firmament.dev.resourcerebuild.done", - startTime.passedTime())) + MC.sendChat( + Component.translatableEscape( + "firmament.dev.resourcerebuild.done", + startTime.passedTime() + ) + ) Unit } } else { CompletableFuture.completedFuture(Unit) } - return reloadFuture.thenCompose { client.reloadResources() } + return reloadFuture.thenCompose { client.reloadResourcePacks() } } } |
