Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backend: Add skyhanni notifications #2630

Merged
merged 7 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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))
}
}
Loading