Add per compat project event listeners

[no changelog]
This commit is contained in:
Linnea Gräf
2024-09-01 22:21:19 +02:00
parent 816f80f862
commit 5ed74f2df4
20 changed files with 161 additions and 73 deletions

View File

@@ -6,10 +6,11 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
import com.google.devtools.ksp.gradle.KspTaskJvm
import moe.nea.licenseextractificator.LicenseDiscoveryTask import moe.nea.licenseextractificator.LicenseDiscoveryTask
import net.fabricmc.loom.LoomGradleExtension import net.fabricmc.loom.LoomGradleExtension
import org.gradle.internal.extensions.stdlib.capitalized
import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins { plugins {
@@ -102,6 +103,7 @@ fun createIsolatedSourceSet(name: String, path: String = "compat/$name"): Source
compatSourceSets.add(ss) compatSourceSets.add(ss)
loom.createRemapConfigurations(ss) loom.createRemapConfigurations(ss)
val mainSS = sourceSets.main.get() val mainSS = sourceSets.main.get()
val upperName = ss.name.replaceFirstChar { it.uppercaseChar() }
configurations { configurations {
(ss.implementationConfigurationName) { (ss.implementationConfigurationName) {
extendsFrom(getByName(mainSS.compileClasspathConfigurationName)) extendsFrom(getByName(mainSS.compileClasspathConfigurationName))
@@ -112,10 +114,15 @@ fun createIsolatedSourceSet(name: String, path: String = "compat/$name"): Source
(mainSS.runtimeOnlyConfigurationName) { (mainSS.runtimeOnlyConfigurationName) {
extendsFrom(getByName(ss.runtimeClasspathConfigurationName)) extendsFrom(getByName(ss.runtimeClasspathConfigurationName))
} }
("ksp" + ss.name.replaceFirstChar { it.uppercaseChar() }) { ("ksp$upperName") {
extendsFrom(ksp.get()) extendsFrom(ksp.get())
} }
} }
afterEvaluate {
tasks.named("ksp${upperName}Kotlin", KspTaskJvm::class) {
this.options.add(SubpluginOption("apoption", "firmament.sourceset=${ss.name}"))
}
}
dependencies { dependencies {
runtimeOnly(ss.output) runtimeOnly(ss.output)
(ss.implementationConfigurationName)(sourceSets.main.get().output) (ss.implementationConfigurationName)(sourceSets.main.get().output)

View File

@@ -7,16 +7,19 @@ import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo; import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
public class MixinPlugin implements IMixinConfigPlugin { public class MixinPlugin implements IMixinConfigPlugin {
AutoDiscoveryPlugin autoDiscoveryPlugin = new AutoDiscoveryPlugin(); AutoDiscoveryPlugin autoDiscoveryPlugin = new AutoDiscoveryPlugin();
public static String mixinPackage;
@Override @Override
public void onLoad(String mixinPackage) { public void onLoad(String mixinPackage) {
MixinExtrasBootstrap.init(); MixinExtrasBootstrap.init();
MixinPlugin.mixinPackage = mixinPackage;
autoDiscoveryPlugin.setMixinPackage(mixinPackage); autoDiscoveryPlugin.setMixinPackage(mixinPackage);
} }
@@ -40,7 +43,8 @@ public class MixinPlugin implements IMixinConfigPlugin {
@Override @Override
public List<String> getMixins() { public List<String> getMixins() {
return autoDiscoveryPlugin.getMixins(); return autoDiscoveryPlugin.getMixins().stream().filter(it -> this.shouldApplyMixin(null, it))
.toList();
} }
@Override @Override
@@ -48,8 +52,10 @@ public class MixinPlugin implements IMixinConfigPlugin {
} }
public static List<String> appliedMixins = new ArrayList<>();
@Override @Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
appliedMixins.add(mixinClassName);
} }
} }

View File

@@ -54,7 +54,8 @@ public class SectionBuilderRiser extends RiserUtils {
private void handle(ClassNode classNode) { private void handle(ClassNode classNode) {
for (MethodNode method : classNode.methods) { for (MethodNode method : classNode.methods) {
if (method.name.endsWith("$fabric-renderer-indigo$hookChunkBuildTessellate") && if ((method.name.endsWith("$fabric-renderer-indigo$hookBuildRenderBlock")
|| method.name.endsWith("$fabric-renderer-indigo$hookChunkBuildTessellate")) &&
method.name.startsWith("redirect$")) { method.name.startsWith("redirect$")) {
handleIndigo(method); handleIndigo(method);
return; return;

View File

@@ -1,5 +1,3 @@
package moe.nea.firmament.commands package moe.nea.firmament.commands
import com.mojang.brigadier.CommandDispatcher import com.mojang.brigadier.CommandDispatcher
@@ -9,6 +7,7 @@ import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource
import net.minecraft.text.Text import net.minecraft.text.Text
import moe.nea.firmament.apis.UrsaManager import moe.nea.firmament.apis.UrsaManager
import moe.nea.firmament.events.CommandEvent import moe.nea.firmament.events.CommandEvent
import moe.nea.firmament.events.FirmamentEventBus
import moe.nea.firmament.features.debug.PowerUserTools import moe.nea.firmament.features.debug.PowerUserTools
import moe.nea.firmament.features.inventory.buttons.InventoryButtons import moe.nea.firmament.features.inventory.buttons.InventoryButtons
import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlayScreen import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlayScreen
@@ -16,6 +15,7 @@ import moe.nea.firmament.features.inventory.storageoverlay.StorageOverviewScreen
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.BooleanHandler
import moe.nea.firmament.gui.config.ManagedOption import moe.nea.firmament.gui.config.ManagedOption
import moe.nea.firmament.init.MixinPlugin
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.FirmFormatters
@@ -201,7 +201,8 @@ fun firmamentCommand() = literal("firmament") {
thenLiteral("copyEntities") { thenLiteral("copyEntities") {
thenExecute { thenExecute {
val player = MC.player ?: return@thenExecute val player = MC.player ?: return@thenExecute
player.world.getOtherEntities(player, player.boundingBox.expand(12.0)).forEach(PowerUserTools::showEntity) player.world.getOtherEntities(player, player.boundingBox.expand(12.0))
.forEach(PowerUserTools::showEntity)
} }
} }
thenLiteral("callUrsa") { thenLiteral("callUrsa") {
@@ -213,6 +214,32 @@ fun firmamentCommand() = literal("firmament") {
} }
} }
} }
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("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)) CommandEvent.SubCommand.publish(CommandEvent.SubCommand(this@literal))
} }

View File

@@ -1,8 +1,7 @@
package moe.nea.firmament.events package moe.nea.firmament.events
import java.util.concurrent.CopyOnWriteArrayList import java.util.concurrent.CopyOnWriteArrayList
import org.apache.commons.lang3.reflect.TypeUtils
import moe.nea.firmament.Firmament import moe.nea.firmament.Firmament
import moe.nea.firmament.util.MC import moe.nea.firmament.util.MC
@@ -13,18 +12,31 @@ import moe.nea.firmament.util.MC
* Subscriptions may not necessarily be delivered in the order of registering. * Subscriptions may not necessarily be delivered in the order of registering.
*/ */
open class FirmamentEventBus<T : FirmamentEvent> { open class FirmamentEventBus<T : FirmamentEvent> {
companion object {
val allEventBuses = mutableListOf<FirmamentEventBus<*>>()
}
val eventType = TypeUtils.getTypeArguments(javaClass, FirmamentEventBus::class.java)!!.values.single()
init {
allEventBuses.add(this)
}
data class Handler<T>( data class Handler<T>(
val invocation: (T) -> Unit, val receivesCancelled: Boolean, val invocation: (T) -> Unit, val receivesCancelled: Boolean,
var knownErrors: MutableSet<Class<*>> = mutableSetOf(), var knownErrors: MutableSet<Class<*>> = mutableSetOf(),
val label: String,
) )
private val toHandle: MutableList<Handler<T>> = CopyOnWriteArrayList() private val toHandle: MutableList<Handler<T>> = CopyOnWriteArrayList()
fun subscribe(handle: (T) -> Unit) { val handlers: List<Handler<T>> get() = toHandle
subscribe(false, handle)
fun subscribe(label: String, handle: (T) -> Unit) {
subscribe(false, label, handle)
} }
fun subscribe(receivesCancelled: Boolean, handle: (T) -> Unit) { fun subscribe(receivesCancelled: Boolean, label: String, handle: (T) -> Unit) {
toHandle.add(Handler(handle, receivesCancelled)) toHandle.add(Handler(handle, receivesCancelled, label = label))
} }
fun publish(event: T): T { fun publish(event: T): T {

View File

@@ -13,4 +13,5 @@ data class Subscription<T : FirmamentEvent>(
val owner: Any, val owner: Any,
val invoke: (T) -> Unit, val invoke: (T) -> Unit,
val eventBus: FirmamentEventBus<T>, val eventBus: FirmamentEventBus<T>,
val methodName: String,
) )

View File

@@ -0,0 +1,25 @@
package moe.nea.firmament.events.subscription
import java.util.ServiceLoader
import kotlin.streams.asSequence
import moe.nea.firmament.Firmament
interface SubscriptionList {
fun provideSubscriptions(addSubscription: (Subscription<*>) -> Unit)
companion object {
val allLists by lazy {
ServiceLoader.load(SubscriptionList::class.java)
.stream()
.asSequence()
.mapNotNull {
kotlin.runCatching { it.get() }
.getOrElse { ex ->
Firmament.logger.error("Could not load subscriptions from ${it.type()}", ex)
null
}
}
.toList()
}
}
}

View File

@@ -1,14 +1,12 @@
package moe.nea.firmament.features package moe.nea.firmament.features
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.serializer import kotlinx.serialization.serializer
import moe.nea.firmament.Firmament import moe.nea.firmament.Firmament
import moe.nea.firmament.annotations.generated.AllSubscriptions
import moe.nea.firmament.events.FeaturesInitializedEvent import moe.nea.firmament.events.FeaturesInitializedEvent
import moe.nea.firmament.events.FirmamentEvent import moe.nea.firmament.events.FirmamentEvent
import moe.nea.firmament.events.subscription.Subscription import moe.nea.firmament.events.subscription.Subscription
import moe.nea.firmament.events.subscription.SubscriptionList
import moe.nea.firmament.features.chat.AutoCompletions import moe.nea.firmament.features.chat.AutoCompletions
import moe.nea.firmament.features.chat.ChatLinks import moe.nea.firmament.features.chat.ChatLinks
import moe.nea.firmament.features.chat.QuickCommands import moe.nea.firmament.features.chat.QuickCommands
@@ -88,13 +86,15 @@ object FeatureManager : DataHolder<FeatureManager.Config>(serializer(), "feature
} }
fun subscribeEvents() { fun subscribeEvents() {
AllSubscriptions.provideSubscriptions { SubscriptionList.allLists.forEach {
subscribeSingleEvent(it) it.provideSubscriptions {
subscribeSingleEvent(it)
}
} }
} }
private fun <T : FirmamentEvent> subscribeSingleEvent(it: Subscription<T>) { private fun <T : FirmamentEvent> subscribeSingleEvent(it: Subscription<T>) {
it.eventBus.subscribe(false, it.invoke) it.eventBus.subscribe(false, "${it.owner.javaClass.simpleName}:${it.methodName}", it.invoke)
} }
fun loadFeature(feature: FirmamentFeature) { fun loadFeature(feature: FirmamentFeature) {

View File

@@ -3,6 +3,7 @@
package moe.nea.firmament.features.debug package moe.nea.firmament.features.debug
import moe.nea.firmament.Firmament import moe.nea.firmament.Firmament
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.TickEvent import moe.nea.firmament.events.TickEvent
import moe.nea.firmament.features.FirmamentFeature import moe.nea.firmament.features.FirmamentFeature
import moe.nea.firmament.util.TimeMark import moe.nea.firmament.util.TimeMark
@@ -25,14 +26,4 @@ object DebugView : FirmamentFeature {
} }
} }
fun recalculateDebugWidget() {
}
override fun onLoad() {
TickEvent.subscribe {
synchronized(this) {
recalculateDebugWidget()
}
}
}
} }

View File

@@ -4,6 +4,7 @@ package moe.nea.firmament.features.debug
import net.minecraft.block.SkullBlock import net.minecraft.block.SkullBlock
import net.minecraft.block.entity.SkullBlockEntity import net.minecraft.block.entity.SkullBlockEntity
import net.minecraft.client.gui.screen.Screen
import net.minecraft.component.DataComponentTypes import net.minecraft.component.DataComponentTypes
import net.minecraft.entity.Entity import net.minecraft.entity.Entity
import net.minecraft.entity.LivingEntity import net.minecraft.entity.LivingEntity
@@ -54,15 +55,16 @@ object PowerUserTools : FirmamentFeature {
} }
var lastCopiedStackViewTime = false var lastCopiedStackViewTime = false
override fun onLoad() { @Subscribe
TickEvent.subscribe { fun resetLastCopiedStack(event: TickEvent) {
if (!lastCopiedStackViewTime) if (!lastCopiedStackViewTime)
lastCopiedStack = null
lastCopiedStackViewTime = false
}
ScreenChangeEvent.subscribe {
lastCopiedStack = null lastCopiedStack = null
} lastCopiedStackViewTime = false
}
@Subscribe
fun resetLastCopiedStackOnScreenChange(event: ScreenChangeEvent) {
lastCopiedStack = null
} }
fun debugFormat(itemStack: ItemStack): Text { fun debugFormat(itemStack: ItemStack): Text {

View File

@@ -1,14 +1,8 @@
package moe.nea.firmament.features.diana package moe.nea.firmament.features.diana
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.AttackBlockEvent import moe.nea.firmament.events.AttackBlockEvent
import moe.nea.firmament.events.ParticleSpawnEvent
import moe.nea.firmament.events.ProcessChatEvent
import moe.nea.firmament.events.SoundReceiveEvent
import moe.nea.firmament.events.UseBlockEvent import moe.nea.firmament.events.UseBlockEvent
import moe.nea.firmament.events.WorldKeyboardEvent
import moe.nea.firmament.events.WorldReadyEvent
import moe.nea.firmament.events.WorldRenderLastEvent
import moe.nea.firmament.features.FirmamentFeature import moe.nea.firmament.features.FirmamentFeature
import moe.nea.firmament.gui.config.ManagedConfig import moe.nea.firmament.gui.config.ManagedConfig
@@ -22,13 +16,15 @@ object DianaWaypoints : FirmamentFeature {
val nearbyWaypoints by toggle("nearby-waypoints") { true } val nearbyWaypoints by toggle("nearby-waypoints") { true }
} }
override fun onLoad() {
UseBlockEvent.subscribe { @Subscribe
NearbyBurrowsSolver.onBlockClick(it.hitResult.blockPos) fun onBlockUse(event: UseBlockEvent) {
} NearbyBurrowsSolver.onBlockClick(event.hitResult.blockPos)
AttackBlockEvent.subscribe { }
NearbyBurrowsSolver.onBlockClick(it.blockPos)
} @Subscribe
fun onBlockAttack(event: AttackBlockEvent) {
NearbyBurrowsSolver.onBlockClick(event.blockPos)
} }
} }

View File

@@ -168,7 +168,11 @@ object CustomBlockTextures {
} }
private val sodiumReloadTask = runCatching { private val sodiumReloadTask = runCatching {
Class.forName("moe.nea.firmament.compat.sodium.SodiumChunkReloader").getConstructor().newInstance() as Runnable val r = Class.forName("moe.nea.firmament.compat.sodium.SodiumChunkReloader")
.getConstructor()
.newInstance() as Runnable
r.run()
r
}.getOrElse { }.getOrElse {
if (FabricLoader.getInstance().isModLoaded("sodium")) if (FabricLoader.getInstance().isModLoaded("sodium"))
logger.error("Could not create sodium chunk reloader") logger.error("Could not create sodium chunk reloader")
@@ -192,7 +196,9 @@ object CustomBlockTextures {
@JvmStatic @JvmStatic
fun getReplacement(block: BlockState, blockPos: BlockPos?): Replacement? { fun getReplacement(block: BlockState, blockPos: BlockPos?): Replacement? {
if (isInFallback() && blockPos == null) return null if (isInFallback() && blockPos == null) {
return null
}
val replacements = currentIslandReplacements?.lookup?.get(block.block) ?: return null val replacements = currentIslandReplacements?.lookup?.get(block.block) ?: return null
for (replacement in replacements) { for (replacement in replacements) {
if (replacement.checks == null || matchesPosition(replacement, blockPos)) if (replacement.checks == null || matchesPosition(replacement, blockPos))

View File

@@ -37,7 +37,7 @@ abstract class MoulConfigHud(
init { init {
require(name.matches("^[a-z_/]+$".toRegex())) require(name.matches("^[a-z_/]+$".toRegex()))
HudRenderEvent.subscribe { HudRenderEvent.subscribe("MoulConfigHud:render") {
if (!shouldRender()) return@subscribe if (!shouldRender()) return@subscribe
val renderContext = componentWrapper.createContext(it.context) val renderContext = componentWrapper.createContext(it.context)
if (fragment == null) if (fragment == null)
@@ -50,7 +50,7 @@ abstract class MoulConfigHud(
fragment!!.root.render(renderContextTranslated) fragment!!.root.render(renderContextTranslated)
it.context.matrices.pop() it.context.matrices.pop()
} }
FinalizeResourceManagerEvent.subscribe { FinalizeResourceManagerEvent.subscribe("MoulConfigHud:finalizeResourceManager") {
MC.resourceManager.registerReloader(object : SynchronousResourceReloader { MC.resourceManager.registerReloader(object : SynchronousResourceReloader {
override fun reload(manager: ResourceManager?) { override fun reload(manager: ResourceManager?) {
fragment = null fragment = null

View File

@@ -19,7 +19,7 @@ object MC {
private val messageQueue = ConcurrentLinkedQueue<Text>() private val messageQueue = ConcurrentLinkedQueue<Text>()
init { init {
TickEvent.subscribe { TickEvent.subscribe("MC:push") {
while (true) { while (true) {
inGameHud.chatHud.addMessage(messageQueue.poll() ?: break) inGameHud.chatHud.addMessage(messageQueue.poll() ?: break)
} }

View File

@@ -26,7 +26,7 @@ object SBData {
val isOnSkyblock get() = locraw?.gametype == "SKYBLOCK" val isOnSkyblock get() = locraw?.gametype == "SKYBLOCK"
var lastProfileIdRequest = TimeMark.farPast() var lastProfileIdRequest = TimeMark.farPast()
fun init() { fun init() {
ServerConnectedEvent.subscribe { ServerConnectedEvent.subscribe("SBData:onServerConnected") {
HypixelModAPI.getInstance().subscribeToEventPacket(ClientboundLocationPacket::class.java) HypixelModAPI.getInstance().subscribeToEventPacket(ClientboundLocationPacket::class.java)
} }
HypixelModAPI.getInstance().createHandler(ClientboundLocationPacket::class.java) { HypixelModAPI.getInstance().createHandler(ClientboundLocationPacket::class.java) {
@@ -39,18 +39,18 @@ object SBData {
SkyblockServerUpdateEvent.publish(SkyblockServerUpdateEvent(lastLocraw, null)) SkyblockServerUpdateEvent.publish(SkyblockServerUpdateEvent(lastLocraw, null))
} }
} }
SkyblockServerUpdateEvent.subscribe { SkyblockServerUpdateEvent.subscribe("SBData:sendProfileId") {
if (!hasReceivedProfile && isOnSkyblock && lastProfileIdRequest.passedTime() > 30.seconds) { if (!hasReceivedProfile && isOnSkyblock && lastProfileIdRequest.passedTime() > 30.seconds) {
lastProfileIdRequest = TimeMark.now() lastProfileIdRequest = TimeMark.now()
MC.sendServerCommand("profileid") MC.sendServerCommand("profileid")
} }
} }
AllowChatEvent.subscribe { event -> AllowChatEvent.subscribe("SBData:hideProfileSuggest") { event ->
if (event.unformattedString in profileSuggestTexts && lastProfileIdRequest.passedTime() < 5.seconds) { if (event.unformattedString in profileSuggestTexts && lastProfileIdRequest.passedTime() < 5.seconds) {
event.cancel() event.cancel()
} }
} }
ProcessChatEvent.subscribe(receivesCancelled = true) { event -> ProcessChatEvent.subscribe(receivesCancelled = true, "SBData:loadProfile") { event ->
val profileMatch = profileRegex.matchEntire(event.unformattedString) val profileMatch = profileRegex.matchEntire(event.unformattedString)
if (profileMatch != null) { if (profileMatch != null) {
try { try {

View File

@@ -57,7 +57,7 @@ object WarpUtil {
} }
init { init {
ProcessChatEvent.subscribe { ProcessChatEvent.subscribe("WarpUtil:processChat") {
if (it.unformattedString == "You haven't unlocked this fast travel destination!" if (it.unformattedString == "You haven't unlocked this fast travel destination!"
&& lastWarpAttempt.passedTime() < 2.seconds && lastWarpAttempt.passedTime() < 2.seconds
) { ) {

View File

@@ -24,7 +24,7 @@ private object InputHandler {
} }
init { init {
HandledScreenKeyPressedEvent.subscribe { event -> HandledScreenKeyPressedEvent.subscribe("Input:resumeAfterInput") { event ->
synchronized(InputHandler) { synchronized(InputHandler) {
val toRemove = activeContinuations.filter { val toRemove = activeContinuations.filter {
event.matches(it.keybind) event.matches(it.keybind)

View File

@@ -56,7 +56,7 @@ interface IDataHolder<T> {
} }
fun registerEvents() { fun registerEvents() {
ScreenChangeEvent.subscribe { event -> ScreenChangeEvent.subscribe("IDataHolder:saveOnScreenChange") { event ->
performSaves() performSaves()
val p = MinecraftClient.getInstance().player val p = MinecraftClient.getInstance().player
if (p != null) { if (p != null) {

View File

@@ -20,6 +20,10 @@
"firmament.poweruser.entity.armor": "Entity Armor:", "firmament.poweruser.entity.armor": "Entity Armor:",
"firmament.poweruser.entity.armor.item": " - %s", "firmament.poweruser.entity.armor.item": " - %s",
"firmament.poweruser.entity.passengers": "%s Passengers", "firmament.poweruser.entity.passengers": "%s Passengers",
"firmament.mixins.start": "Applied firmament mixins:",
"firmament.event.start": "Event Bus Readout:",
"firmament.event.bustype": " - %s:",
"firmament.event.handler": " * %s",
"firmament.config.all-configs": "- All Configs -", "firmament.config.all-configs": "- All Configs -",
"firmament.config.anniversary": "Anniversary Features", "firmament.config.anniversary": "Anniversary Features",
"firmament.config.anniversary.shiny-pigs": "Shiny Pigs Tracker", "firmament.config.anniversary.shiny-pigs": "Shiny Pigs Tracker",

View File

@@ -1,4 +1,3 @@
package moe.nea.firmament.annotations.process package moe.nea.firmament.annotations.process
import com.google.auto.service.AutoService import com.google.auto.service.AutoService
@@ -16,23 +15,24 @@ import com.google.devtools.ksp.symbol.KSFunctionDeclaration
import com.google.devtools.ksp.symbol.KSType import com.google.devtools.ksp.symbol.KSType
import com.google.devtools.ksp.symbol.Nullability import com.google.devtools.ksp.symbol.Nullability
import com.google.devtools.ksp.validate import com.google.devtools.ksp.validate
import java.text.SimpleDateFormat
import java.util.Date
import moe.nea.firmament.annotations.Subscribe import moe.nea.firmament.annotations.Subscribe
class SubscribeAnnotationProcessor( class SubscribeAnnotationProcessor(
val logger: KSPLogger, val logger: KSPLogger,
val codeGenerator: CodeGenerator, val codeGenerator: CodeGenerator,
val sourceSetName: String,
) : SymbolProcessor { ) : SymbolProcessor {
override fun finish() { override fun finish() {
subscriptions.sort() subscriptions.sort()
if (subscriptions.isEmpty()) return
val subscriptionSet = subscriptions.mapTo(mutableSetOf()) { it.parent.containingFile!! } val subscriptionSet = subscriptions.mapTo(mutableSetOf()) { it.parent.containingFile!! }
val dependencies = Dependencies( val dependencies = Dependencies(
aggregating = true, aggregating = true,
*subscriptionSet.toTypedArray()) *subscriptionSet.toTypedArray())
val generatedFileName = "AllSubscriptions${sourceSetName.replaceFirstChar { it.uppercaseChar() }}"
val subscriptionsFile = val subscriptionsFile =
codeGenerator codeGenerator
.createNewFile(dependencies, "moe.nea.firmament.annotations.generated", "AllSubscriptions") .createNewFile(dependencies, "moe.nea.firmament.annotations.generated", generatedFileName)
.bufferedWriter() .bufferedWriter()
subscriptionsFile.apply { subscriptionsFile.apply {
appendLine("// This file is @generated by SubscribeAnnotationProcessor") appendLine("// This file is @generated by SubscribeAnnotationProcessor")
@@ -44,8 +44,8 @@ class SubscribeAnnotationProcessor(
appendLine() appendLine()
appendLine("import moe.nea.firmament.events.subscription.*") appendLine("import moe.nea.firmament.events.subscription.*")
appendLine() appendLine()
appendLine("object AllSubscriptions {") appendLine("class $generatedFileName : SubscriptionList {")
appendLine(" fun provideSubscriptions(addSubscription: (Subscription<*>) -> Unit) {") appendLine(" override fun provideSubscriptions(addSubscription: (Subscription<*>) -> Unit) {")
for (subscription in subscriptions) { for (subscription in subscriptions) {
val owner = subscription.parent.qualifiedName!!.asString() val owner = subscription.parent.qualifiedName!!.asString()
val method = subscription.child.simpleName.asString() val method = subscription.child.simpleName.asString()
@@ -53,12 +53,20 @@ class SubscribeAnnotationProcessor(
appendLine(" addSubscription(Subscription<$type>(") appendLine(" addSubscription(Subscription<$type>(")
appendLine(" ${owner},") appendLine(" ${owner},")
appendLine(" ${owner}::${method},") appendLine(" ${owner}::${method},")
appendLine(" ${type}))") appendLine(" ${type},")
appendLine(" \"${method}\"))")
} }
appendLine(" }") appendLine(" }")
appendLine("}") appendLine("}")
} }
subscriptionsFile.close() subscriptionsFile.close()
val metaInf = codeGenerator.createNewFileByPath(
Dependencies(false),
"META-INF/services/moe.nea.firmament.events.subscription.SubscriptionList", extensionName = "")
.bufferedWriter()
metaInf.append("moe.nea.firmament.annotations.generated.")
metaInf.appendLine(generatedFileName)
metaInf.close()
} }
data class Subscription( data class Subscription(
@@ -121,6 +129,8 @@ class SubscribeAnnotationProcessor(
@AutoService(SymbolProcessorProvider::class) @AutoService(SymbolProcessorProvider::class)
class SubscribeAnnotationProcessorProvider : SymbolProcessorProvider { class SubscribeAnnotationProcessorProvider : SymbolProcessorProvider {
override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
return SubscribeAnnotationProcessor(environment.logger, environment.codeGenerator) return SubscribeAnnotationProcessor(environment.logger,
environment.codeGenerator,
environment.options["firmament.sourceset"] ?: "main")
} }
} }