aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2024-09-01 22:21:19 +0200
committerLinnea Gräf <nea@nea.moe>2024-09-01 22:21:19 +0200
commit5ed74f2df49c93ed1617520a935078b59ad7e195 (patch)
treef0d52699fff7f820bd724902878988859bd43516 /src
parent816f80f862d2f5de6bc9b0ae84cd6df0da341228 (diff)
downloadFirmament-5ed74f2df49c93ed1617520a935078b59ad7e195.tar.gz
Firmament-5ed74f2df49c93ed1617520a935078b59ad7e195.tar.bz2
Firmament-5ed74f2df49c93ed1617520a935078b59ad7e195.zip
Add per compat project event listeners
[no changelog]
Diffstat (limited to 'src')
-rw-r--r--src/main/java/moe/nea/firmament/init/MixinPlugin.java12
-rw-r--r--src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java3
-rw-r--r--src/main/kotlin/commands/rome.kt33
-rw-r--r--src/main/kotlin/events/FirmamentEventBus.kt24
-rw-r--r--src/main/kotlin/events/subscription/Subscription.kt1
-rw-r--r--src/main/kotlin/events/subscription/SubscriptionList.kt25
-rw-r--r--src/main/kotlin/features/FeatureManager.kt12
-rw-r--r--src/main/kotlin/features/debug/DebugView.kt11
-rw-r--r--src/main/kotlin/features/debug/PowerUserTools.kt18
-rw-r--r--src/main/kotlin/features/diana/DianaWaypoints.kt24
-rw-r--r--src/main/kotlin/features/texturepack/CustomBlockTextures.kt10
-rw-r--r--src/main/kotlin/gui/hud/MoulConfigHud.kt4
-rw-r--r--src/main/kotlin/util/MC.kt2
-rw-r--r--src/main/kotlin/util/SBData.kt8
-rw-r--r--src/main/kotlin/util/WarpUtil.kt2
-rw-r--r--src/main/kotlin/util/async/input.kt2
-rw-r--r--src/main/kotlin/util/data/IDataHolder.kt2
-rw-r--r--src/main/resources/assets/firmament/lang/en_us.json4
18 files changed, 134 insertions, 63 deletions
diff --git a/src/main/java/moe/nea/firmament/init/MixinPlugin.java b/src/main/java/moe/nea/firmament/init/MixinPlugin.java
index e7a02b5..61e8f14 100644
--- a/src/main/java/moe/nea/firmament/init/MixinPlugin.java
+++ b/src/main/java/moe/nea/firmament/init/MixinPlugin.java
@@ -7,16 +7,19 @@ import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
+import java.util.ArrayList;
import java.util.List;
import java.util.Set;
+import java.util.stream.Collectors;
public class MixinPlugin implements IMixinConfigPlugin {
AutoDiscoveryPlugin autoDiscoveryPlugin = new AutoDiscoveryPlugin();
-
+ public static String mixinPackage;
@Override
public void onLoad(String mixinPackage) {
MixinExtrasBootstrap.init();
+ MixinPlugin.mixinPackage = mixinPackage;
autoDiscoveryPlugin.setMixinPackage(mixinPackage);
}
@@ -40,7 +43,8 @@ public class MixinPlugin implements IMixinConfigPlugin {
@Override
public List<String> getMixins() {
- return autoDiscoveryPlugin.getMixins();
+ return autoDiscoveryPlugin.getMixins().stream().filter(it -> this.shouldApplyMixin(null, it))
+ .toList();
}
@Override
@@ -48,8 +52,10 @@ public class MixinPlugin implements IMixinConfigPlugin {
}
+ public static List<String> appliedMixins = new ArrayList<>();
+
@Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
-
+ appliedMixins.add(mixinClassName);
}
}
diff --git a/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java b/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java
index ebb060c..f2c6c53 100644
--- a/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java
+++ b/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java
@@ -54,7 +54,8 @@ public class SectionBuilderRiser extends RiserUtils {
private void handle(ClassNode classNode) {
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$")) {
handleIndigo(method);
return;
diff --git a/src/main/kotlin/commands/rome.kt b/src/main/kotlin/commands/rome.kt
index 015512d..fbcad07 100644
--- a/src/main/kotlin/commands/rome.kt
+++ b/src/main/kotlin/commands/rome.kt
@@ -1,5 +1,3 @@
-
-
package moe.nea.firmament.commands
import com.mojang.brigadier.CommandDispatcher
@@ -9,6 +7,7 @@ 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.PowerUserTools
import moe.nea.firmament.features.inventory.buttons.InventoryButtons
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.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
@@ -201,7 +201,8 @@ fun firmamentCommand() = literal("firmament") {
thenLiteral("copyEntities") {
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") {
@@ -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))
}
diff --git a/src/main/kotlin/events/FirmamentEventBus.kt b/src/main/kotlin/events/FirmamentEventBus.kt
index ee9e6c8..71331d1 100644
--- a/src/main/kotlin/events/FirmamentEventBus.kt
+++ b/src/main/kotlin/events/FirmamentEventBus.kt
@@ -1,8 +1,7 @@
-
-
package moe.nea.firmament.events
import java.util.concurrent.CopyOnWriteArrayList
+import org.apache.commons.lang3.reflect.TypeUtils
import moe.nea.firmament.Firmament
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.
*/
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>(
val invocation: (T) -> Unit, val receivesCancelled: Boolean,
var knownErrors: MutableSet<Class<*>> = mutableSetOf(),
+ val label: String,
)
private val toHandle: MutableList<Handler<T>> = CopyOnWriteArrayList()
- fun subscribe(handle: (T) -> Unit) {
- subscribe(false, handle)
+ val handlers: List<Handler<T>> get() = toHandle
+
+ fun subscribe(label: String, handle: (T) -> Unit) {
+ subscribe(false, label, handle)
}
- fun subscribe(receivesCancelled: Boolean, handle: (T) -> Unit) {
- toHandle.add(Handler(handle, receivesCancelled))
+ fun subscribe(receivesCancelled: Boolean, label: String, handle: (T) -> Unit) {
+ toHandle.add(Handler(handle, receivesCancelled, label = label))
}
fun publish(event: T): T {
diff --git a/src/main/kotlin/events/subscription/Subscription.kt b/src/main/kotlin/events/subscription/Subscription.kt
index 83b91c9..1c1d3bd 100644
--- a/src/main/kotlin/events/subscription/Subscription.kt
+++ b/src/main/kotlin/events/subscription/Subscription.kt
@@ -13,4 +13,5 @@ data class Subscription<T : FirmamentEvent>(
val owner: Any,
val invoke: (T) -> Unit,
val eventBus: FirmamentEventBus<T>,
+ val methodName: String,
)
diff --git a/src/main/kotlin/events/subscription/SubscriptionList.kt b/src/main/kotlin/events/subscription/SubscriptionList.kt
new file mode 100644
index 0000000..e74a65a
--- /dev/null
+++ b/src/main/kotlin/events/subscription/SubscriptionList.kt
@@ -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()
+ }
+ }
+}
diff --git a/src/main/kotlin/features/FeatureManager.kt b/src/main/kotlin/features/FeatureManager.kt
index 19b91de..c2889eb 100644
--- a/src/main/kotlin/features/FeatureManager.kt
+++ b/src/main/kotlin/features/FeatureManager.kt
@@ -1,14 +1,12 @@
-
-
package moe.nea.firmament.features
import kotlinx.serialization.Serializable
import kotlinx.serialization.serializer
import moe.nea.firmament.Firmament
-import moe.nea.firmament.annotations.generated.AllSubscriptions
import moe.nea.firmament.events.FeaturesInitializedEvent
import moe.nea.firmament.events.FirmamentEvent
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.ChatLinks
import moe.nea.firmament.features.chat.QuickCommands
@@ -88,13 +86,15 @@ object FeatureManager : DataHolder<FeatureManager.Config>(serializer(), "feature
}
fun subscribeEvents() {
- AllSubscriptions.provideSubscriptions {
- subscribeSingleEvent(it)
+ SubscriptionList.allLists.forEach {
+ it.provideSubscriptions {
+ subscribeSingleEvent(it)
+ }
}
}
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) {
diff --git a/src/main/kotlin/features/debug/DebugView.kt b/src/main/kotlin/features/debug/DebugView.kt
index 7e1b8ec..ee54260 100644
--- a/src/main/kotlin/features/debug/DebugView.kt
+++ b/src/main/kotlin/features/debug/DebugView.kt
@@ -3,6 +3,7 @@
package moe.nea.firmament.features.debug
import moe.nea.firmament.Firmament
+import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.TickEvent
import moe.nea.firmament.features.FirmamentFeature
import moe.nea.firmament.util.TimeMark
@@ -25,14 +26,4 @@ object DebugView : FirmamentFeature {
}
}
- fun recalculateDebugWidget() {
- }
-
- override fun onLoad() {
- TickEvent.subscribe {
- synchronized(this) {
- recalculateDebugWidget()
- }
- }
- }
}
diff --git a/src/main/kotlin/features/debug/PowerUserTools.kt b/src/main/kotlin/features/debug/PowerUserTools.kt
index 7893eff..dccf8f7 100644
--- a/src/main/kotlin/features/debug/PowerUserTools.kt
+++ b/src/main/kotlin/features/debug/PowerUserTools.kt
@@ -4,6 +4,7 @@ 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
@@ -54,15 +55,16 @@ object PowerUserTools : FirmamentFeature {
}
var lastCopiedStackViewTime = false
- override fun onLoad() {
- TickEvent.subscribe {
- if (!lastCopiedStackViewTime)
- lastCopiedStack = null
- lastCopiedStackViewTime = false
- }
- ScreenChangeEvent.subscribe {
+ @Subscribe
+ fun resetLastCopiedStack(event: TickEvent) {
+ if (!lastCopiedStackViewTime)
lastCopiedStack = null
- }
+ lastCopiedStackViewTime = false
+ }
+
+ @Subscribe
+ fun resetLastCopiedStackOnScreenChange(event: ScreenChangeEvent) {
+ lastCopiedStack = null
}
fun debugFormat(itemStack: ItemStack): Text {
diff --git a/src/main/kotlin/features/diana/DianaWaypoints.kt b/src/main/kotlin/features/diana/DianaWaypoints.kt
index 0a34eaa..205e237 100644
--- a/src/main/kotlin/features/diana/DianaWaypoints.kt
+++ b/src/main/kotlin/features/diana/DianaWaypoints.kt
@@ -1,14 +1,8 @@
-
package moe.nea.firmament.features.diana
+import moe.nea.firmament.annotations.Subscribe
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.WorldKeyboardEvent
-import moe.nea.firmament.events.WorldReadyEvent
-import moe.nea.firmament.events.WorldRenderLastEvent
import moe.nea.firmament.features.FirmamentFeature
import moe.nea.firmament.gui.config.ManagedConfig
@@ -22,13 +16,15 @@ object DianaWaypoints : FirmamentFeature {
val nearbyWaypoints by toggle("nearby-waypoints") { true }
}
- override fun onLoad() {
- UseBlockEvent.subscribe {
- NearbyBurrowsSolver.onBlockClick(it.hitResult.blockPos)
- }
- AttackBlockEvent.subscribe {
- NearbyBurrowsSolver.onBlockClick(it.blockPos)
- }
+
+ @Subscribe
+ fun onBlockUse(event: UseBlockEvent) {
+ NearbyBurrowsSolver.onBlockClick(event.hitResult.blockPos)
+ }
+
+ @Subscribe
+ fun onBlockAttack(event: AttackBlockEvent) {
+ NearbyBurrowsSolver.onBlockClick(event.blockPos)
}
}
diff --git a/src/main/kotlin/features/texturepack/CustomBlockTextures.kt b/src/main/kotlin/features/texturepack/CustomBlockTextures.kt
index 0f2c2e6..a149928 100644
--- a/src/main/kotlin/features/texturepack/CustomBlockTextures.kt
+++ b/src/main/kotlin/features/texturepack/CustomBlockTextures.kt
@@ -168,7 +168,11 @@ object CustomBlockTextures {
}
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 {
if (FabricLoader.getInstance().isModLoaded("sodium"))
logger.error("Could not create sodium chunk reloader")
@@ -192,7 +196,9 @@ object CustomBlockTextures {
@JvmStatic
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
for (replacement in replacements) {
if (replacement.checks == null || matchesPosition(replacement, blockPos))
diff --git a/src/main/kotlin/gui/hud/MoulConfigHud.kt b/src/main/kotlin/gui/hud/MoulConfigHud.kt
index e77d9af..e99b069 100644
--- a/src/main/kotlin/gui/hud/MoulConfigHud.kt
+++ b/src/main/kotlin/gui/hud/MoulConfigHud.kt
@@ -37,7 +37,7 @@ abstract class MoulConfigHud(
init {
require(name.matches("^[a-z_/]+$".toRegex()))
- HudRenderEvent.subscribe {
+ HudRenderEvent.subscribe("MoulConfigHud:render") {
if (!shouldRender()) return@subscribe
val renderContext = componentWrapper.createContext(it.context)
if (fragment == null)
@@ -50,7 +50,7 @@ abstract class MoulConfigHud(
fragment!!.root.render(renderContextTranslated)
it.context.matrices.pop()
}
- FinalizeResourceManagerEvent.subscribe {
+ FinalizeResourceManagerEvent.subscribe("MoulConfigHud:finalizeResourceManager") {
MC.resourceManager.registerReloader(object : SynchronousResourceReloader {
override fun reload(manager: ResourceManager?) {
fragment = null
diff --git a/src/main/kotlin/util/MC.kt b/src/main/kotlin/util/MC.kt
index b0d3056..db8eccb 100644
--- a/src/main/kotlin/util/MC.kt
+++ b/src/main/kotlin/util/MC.kt
@@ -19,7 +19,7 @@ object MC {
private val messageQueue = ConcurrentLinkedQueue<Text>()
init {
- TickEvent.subscribe {
+ TickEvent.subscribe("MC:push") {
while (true) {
inGameHud.chatHud.addMessage(messageQueue.poll() ?: break)
}
diff --git a/src/main/kotlin/util/SBData.kt b/src/main/kotlin/util/SBData.kt
index b30c6fb..5af8548 100644
--- a/src/main/kotlin/util/SBData.kt
+++ b/src/main/kotlin/util/SBData.kt
@@ -26,7 +26,7 @@ object SBData {
val isOnSkyblock get() = locraw?.gametype == "SKYBLOCK"
var lastProfileIdRequest = TimeMark.farPast()
fun init() {
- ServerConnectedEvent.subscribe {
+ ServerConnectedEvent.subscribe("SBData:onServerConnected") {
HypixelModAPI.getInstance().subscribeToEventPacket(ClientboundLocationPacket::class.java)
}
HypixelModAPI.getInstance().createHandler(ClientboundLocationPacket::class.java) {
@@ -39,18 +39,18 @@ object SBData {
SkyblockServerUpdateEvent.publish(SkyblockServerUpdateEvent(lastLocraw, null))
}
}
- SkyblockServerUpdateEvent.subscribe {
+ SkyblockServerUpdateEvent.subscribe("SBData:sendProfileId") {
if (!hasReceivedProfile && isOnSkyblock && lastProfileIdRequest.passedTime() > 30.seconds) {
lastProfileIdRequest = TimeMark.now()
MC.sendServerCommand("profileid")
}
}
- AllowChatEvent.subscribe { event ->
+ AllowChatEvent.subscribe("SBData:hideProfileSuggest") { event ->
if (event.unformattedString in profileSuggestTexts && lastProfileIdRequest.passedTime() < 5.seconds) {
event.cancel()
}
}
- ProcessChatEvent.subscribe(receivesCancelled = true) { event ->
+ ProcessChatEvent.subscribe(receivesCancelled = true, "SBData:loadProfile") { event ->
val profileMatch = profileRegex.matchEntire(event.unformattedString)
if (profileMatch != null) {
try {
diff --git a/src/main/kotlin/util/WarpUtil.kt b/src/main/kotlin/util/WarpUtil.kt
index 8fca6f3..e37f56f 100644
--- a/src/main/kotlin/util/WarpUtil.kt
+++ b/src/main/kotlin/util/WarpUtil.kt
@@ -57,7 +57,7 @@ object WarpUtil {
}
init {
- ProcessChatEvent.subscribe {
+ ProcessChatEvent.subscribe("WarpUtil:processChat") {
if (it.unformattedString == "You haven't unlocked this fast travel destination!"
&& lastWarpAttempt.passedTime() < 2.seconds
) {
diff --git a/src/main/kotlin/util/async/input.kt b/src/main/kotlin/util/async/input.kt
index 9aab5cf..f22c595 100644
--- a/src/main/kotlin/util/async/input.kt
+++ b/src/main/kotlin/util/async/input.kt
@@ -24,7 +24,7 @@ private object InputHandler {
}
init {
- HandledScreenKeyPressedEvent.subscribe { event ->
+ HandledScreenKeyPressedEvent.subscribe("Input:resumeAfterInput") { event ->
synchronized(InputHandler) {
val toRemove = activeContinuations.filter {
event.matches(it.keybind)
diff --git a/src/main/kotlin/util/data/IDataHolder.kt b/src/main/kotlin/util/data/IDataHolder.kt
index 5d09bcd..cc97b58 100644
--- a/src/main/kotlin/util/data/IDataHolder.kt
+++ b/src/main/kotlin/util/data/IDataHolder.kt
@@ -56,7 +56,7 @@ interface IDataHolder<T> {
}
fun registerEvents() {
- ScreenChangeEvent.subscribe { event ->
+ ScreenChangeEvent.subscribe("IDataHolder:saveOnScreenChange") { event ->
performSaves()
val p = MinecraftClient.getInstance().player
if (p != null) {
diff --git a/src/main/resources/assets/firmament/lang/en_us.json b/src/main/resources/assets/firmament/lang/en_us.json
index 2e516df..7e86368 100644
--- a/src/main/resources/assets/firmament/lang/en_us.json
+++ b/src/main/resources/assets/firmament/lang/en_us.json
@@ -20,6 +20,10 @@
"firmament.poweruser.entity.armor": "Entity Armor:",
"firmament.poweruser.entity.armor.item": " - %s",
"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.anniversary": "Anniversary Features",
"firmament.config.anniversary.shiny-pigs": "Shiny Pigs Tracker",