Skip to content

Commit

Permalink
Backend: Add skyhanni notifications (#2630)
Browse files Browse the repository at this point in the history
  • Loading branch information
CalMWolfs authored Oct 16, 2024
1 parent f2bff36 commit 58ba6a5
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 14 deletions.
112 changes: 112 additions & 0 deletions src/main/java/at/hannibal2/skyhanni/data/NotificationManager.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package at.hannibal2.skyhanni.data

import at.hannibal2.skyhanni.api.event.HandleEvent
import at.hannibal2.skyhanni.config.commands.CommandCategory
import at.hannibal2.skyhanni.config.commands.CommandRegistrationEvent
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.LorenzKeyPressEvent
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.utils.GuiRenderUtils
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.SimpleTimeMark
import at.hannibal2.skyhanni.utils.TimeUtils.format
import at.hannibal2.skyhanni.utils.compat.GuiScreenUtils
import io.github.notenoughupdates.moulconfig.internal.RenderUtils
import net.minecraft.client.Minecraft
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import org.lwjgl.input.Keyboard
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds

@SkyHanniModule
object NotificationManager {

private val notificationQueue = mutableListOf<SkyHanniNotification>()

private var currentNotification: SkyHanniNotification? = null
private var lastNotificationClosed = SimpleTimeMark.farPast()

private const val CLOSE_TEXT = "§c[X] Close"

@SubscribeEvent
fun onKeyClick(event: LorenzKeyPressEvent) {
currentNotification ?: return
if (lastNotificationClosed.passedSince() < 200.milliseconds) return
if (event.keyCode != Keyboard.KEY_X) return
currentNotification = null
lastNotificationClosed = SimpleTimeMark.now()
}

@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent) {
val notification = getCurrentNotification() ?: return

if (InventoryUtils.inInventory() && !notification.showOverInventory) return

val midX = GuiScreenUtils.scaledWindowWidth / 2
val topY = (GuiScreenUtils.scaledWindowHeight * 0.75 - notification.height / 2).toInt()

RenderUtils.drawFloatingRectDark(midX - notification.width / 2, topY, notification.width, notification.height)
val closeTextWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(CLOSE_TEXT)

GuiRenderUtils.drawString(CLOSE_TEXT, midX + notification.width / 2 - 3 - closeTextWidth, topY + 4)

if (notification.length.isFinite()) {
val remainingTime = "§8" + notification.endTime.timeUntil().format()
GuiRenderUtils.drawString(remainingTime, midX - notification.width / 2 + 4, topY + 4)
}

notification.message.forEachIndexed { index, line ->
GuiRenderUtils.drawStringCentered("§7$line", midX, topY + 19 + index * 10)
}
}

private fun getCurrentNotification(): SkyHanniNotification? {
currentNotification?.let {
if (it.endTime.isInPast()) currentNotification = null
}
if (currentNotification == null) {
currentNotification = notificationQueue.removeFirstOrNull()
currentNotification?.setEndTime()
}
return currentNotification
}

fun queueNotification(notification: SkyHanniNotification) {
notificationQueue.add(notification)
}

@HandleEvent
fun onCommandRegistration(event: CommandRegistrationEvent) {
event.register("shtestnotification") {
description = "Shows a test notification"
category = CommandCategory.DEVELOPER_TEST
callback {
val testingText = it.joinToString(" ").replace("\\n", "\n")
queueNotification(SkyHanniNotification(testingText, Duration.INFINITE))
}
}
}
}

data class SkyHanniNotification(
val message: List<String>,
val length: Duration,
val showOverInventory: Boolean = false,
) {
constructor(message: String, length: Duration, showOverInventory: Boolean = false) : this(
message.lines(),
length,
showOverInventory,
)

var endTime = SimpleTimeMark.farFuture()

val width by lazy { (message.maxOfOrNull { Minecraft.getMinecraft().fontRendererObj.getStringWidth(it) } ?: 0) + 8 }
val height by lazy { message.size * 10 + 18 }

fun setEndTime() {
if (length.isInfinite()) return
endTime = SimpleTimeMark.now() + length
}
}
30 changes: 16 additions & 14 deletions src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package at.hannibal2.skyhanni.utils

import at.hannibal2.skyhanni.data.NotificationManager
import at.hannibal2.skyhanni.data.PetAPI
import at.hannibal2.skyhanni.data.SkyHanniNotification
import at.hannibal2.skyhanni.events.DebugDataCollectEvent
import at.hannibal2.skyhanni.features.misc.items.EstimatedItemValueCalculator.getAttributeName
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
Expand All @@ -19,8 +21,6 @@ import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.isRecombobulated
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import at.hannibal2.skyhanni.utils.StringUtils.removeResets
import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern
import com.google.common.collect.Lists
import io.github.moulberry.notenoughupdates.util.NotificationHandler
import net.minecraft.client.Minecraft
import net.minecraft.init.Items
import net.minecraft.item.Item
Expand All @@ -32,6 +32,8 @@ import net.minecraftforge.common.util.Constants
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.util.LinkedList
import java.util.regex.Matcher
import kotlin.time.Duration.Companion.INFINITE
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds

@SkyHanniModule
Expand All @@ -40,6 +42,7 @@ object ItemUtils {
private val itemNameCache = mutableMapOf<NEUInternalName, String>() // internal name -> item name

private val missingRepoItems = mutableSetOf<String>()
private var lastRepoWarning = SimpleTimeMark.farPast()

fun ItemStack.cleanName() = this.displayName.removeColor()

Expand Down Expand Up @@ -544,20 +547,19 @@ object ItemUtils {
fun addMissingRepoItem(name: String, message: String) {
if (!missingRepoItems.add(name)) return
ChatUtils.debug(message)
// showRepoWarning()

if (lastRepoWarning.passedSince() < 3.minutes) return
lastRepoWarning = SimpleTimeMark.now()
showRepoWarning(name)
}

// Running NEU's function `Utils.showOutdatedRepoNotification()` caused a NoSuchMethodError in dev env.
// Therefore we run NotificationHandler.displayNotification directly
private fun showRepoWarning() {
NotificationHandler.displayNotification(
Lists.newArrayList(
"§c§lMissing repo data",
"§cData used for some SkyHanni features is not up to date, this should normally not be the case.",
"§cYou can try §l/neuresetrepo§r§c and restart your game to see if that fixes the issue.",
"§cIf the problem persists please join the SkyHanni Discord and message in §l#support§r§c to get support.",
),
true, true,
private fun showRepoWarning(item: String) {
val text = listOf(
"§c§lMissing repo data for item: $item",
"§cData used for some SkyHanni features is not up to date, this should normally not be the case.",
"§cYou can try §l/neuresetrepo§r§c and restart your game to see if that fixes the issue.",
"§cIf the problem persists please join the SkyHanni Discord and message in §l#support§r§c to get support.",
)
NotificationManager.queueNotification(SkyHanniNotification(text, INFINITE, true))
}
}

0 comments on commit 58ba6a5

Please sign in to comment.