summaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/features
diff options
context:
space:
mode:
authorRoman / Linnea Gräf <nea@nea.moe>2023-04-12 12:38:00 +0200
committerGitHub <noreply@github.com>2023-04-12 12:38:00 +0200
commite9a6b9f6de0fd8d6bc0d97b03d07d9a8c2757f95 (patch)
treef8a29569864aa798e85906fac1412f0583b684c6 /src/main/java/at/hannibal2/skyhanni/features
parent0e2276bad532ffe06e1364900e6456cd5b50214e (diff)
downloadskyhanni-e9a6b9f6de0fd8d6bc0d97b03d07d9a8c2757f95.tar.gz
skyhanni-e9a6b9f6de0fd8d6bc0d97b03d07d9a8c2757f95.tar.bz2
skyhanni-e9a6b9f6de0fd8d6bc0d97b03d07d9a8c2757f95.zip
Add AutoUpdater and license info gui (#26)
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/features')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/update/ConfigVersionDisplay.java11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/update/GuiOptionEditorUpdateCheck.kt88
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/update/UpdateManager.kt128
3 files changed, 227 insertions, 0 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/update/ConfigVersionDisplay.java b/src/main/java/at/hannibal2/skyhanni/features/misc/update/ConfigVersionDisplay.java
new file mode 100644
index 000000000..ddb837efb
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/update/ConfigVersionDisplay.java
@@ -0,0 +1,11 @@
+package at.hannibal2.skyhanni.features.misc.update;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface ConfigVersionDisplay {
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/update/GuiOptionEditorUpdateCheck.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/update/GuiOptionEditorUpdateCheck.kt
new file mode 100644
index 000000000..395975aa6
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/update/GuiOptionEditorUpdateCheck.kt
@@ -0,0 +1,88 @@
+package at.hannibal2.skyhanni.features.misc.update
+
+import io.github.moulberry.moulconfig.gui.GuiOptionEditor
+import io.github.moulberry.moulconfig.internal.TextRenderUtils
+import io.github.moulberry.moulconfig.processor.ProcessedOption
+import io.github.moulberry.notenoughupdates.itemeditor.GuiElementButton
+import net.minecraft.client.Minecraft
+import net.minecraft.client.renderer.GlStateManager
+import net.minecraft.util.EnumChatFormatting.GREEN
+import net.minecraft.util.EnumChatFormatting.RED
+import org.lwjgl.input.Mouse
+
+class GuiOptionEditorUpdateCheck(option: ProcessedOption) : GuiOptionEditor(option) {
+ val button = GuiElementButton("", -1) { }
+
+ override fun render(x: Int, y: Int, width: Int) {
+ val fr = Minecraft.getMinecraft().fontRendererObj
+
+ GlStateManager.pushMatrix()
+ GlStateManager.translate(x.toFloat() + 10, y.toFloat(), 1F)
+ val width = width - 20
+ val nextVersion = UpdateManager.getNextVersion()
+
+ button.text = when (UpdateManager.updateState) {
+ UpdateManager.UpdateState.AVAILABLE -> "Download update"
+ UpdateManager.UpdateState.QUEUED -> "Downloading..."
+ UpdateManager.UpdateState.DOWNLOADED -> "Downloaded"
+ UpdateManager.UpdateState.NONE -> if (nextVersion == null) "Check for Updates" else "Up to date"
+ }
+ button.render(getButtonPosition(width), 10)
+
+ if (UpdateManager.updateState == UpdateManager.UpdateState.DOWNLOADED) {
+ TextRenderUtils.drawStringCentered(
+ "${GREEN}The update will be installed after your next restart.",
+ fr,
+ width / 2F,
+ 40F,
+ true,
+ -1
+ )
+ }
+
+ val widthRemaining = width - button.width - 10
+
+ GlStateManager.scale(2F, 2F, 1F)
+ TextRenderUtils.drawStringCenteredScaledMaxWidth(
+ "${if (UpdateManager.updateState == UpdateManager.UpdateState.NONE) GREEN else RED}${UpdateManager.getCurrentVersion()}" +
+ if (nextVersion != null) "➜ ${GREEN}${nextVersion}" else "",
+ fr,
+ widthRemaining / 4F,
+ 10F,
+ true,
+ widthRemaining / 2,
+ -1
+ )
+
+ GlStateManager.popMatrix()
+ }
+
+ fun getButtonPosition(width: Int) = width - button.width
+ override fun getHeight(): Int {
+ return 55
+ }
+
+ override fun mouseInput(x: Int, y: Int, width: Int, mouseX: Int, mouseY: Int): Boolean {
+ val width = width - 20
+ if (Mouse.getEventButtonState()) {
+ if ((mouseX - getButtonPosition(width) - x) in (0..button.width) && (mouseY - 10 - y) in (0..button.height)) {
+ when (UpdateManager.updateState) {
+ UpdateManager.UpdateState.AVAILABLE -> UpdateManager.queueUpdate()
+ UpdateManager.UpdateState.QUEUED -> {}
+ UpdateManager.UpdateState.DOWNLOADED -> {}
+ UpdateManager.UpdateState.NONE -> UpdateManager.checkUpdate()
+ }
+ return true
+ }
+ }
+ return false
+ }
+
+ override fun keyboardInput(): Boolean {
+ return false
+ }
+
+ override fun fulfillsSearch(word: String): Boolean {
+ return super.fulfillsSearch(word) || word in "download" || word in "update"
+ }
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/update/UpdateManager.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/update/UpdateManager.kt
new file mode 100644
index 000000000..adb130a76
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/update/UpdateManager.kt
@@ -0,0 +1,128 @@
+package at.hannibal2.skyhanni.features.misc.update
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.features.About
+import at.hannibal2.skyhanni.events.ConfigLoadEvent
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import io.github.moulberry.moulconfig.processor.MoulConfigProcessor
+import io.github.moulberry.notenoughupdates.util.MinecraftExecutor
+import moe.nea.libautoupdate.*
+import net.minecraft.client.Minecraft
+import net.minecraftforge.common.MinecraftForge
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import net.minecraftforge.fml.common.gameevent.TickEvent
+import java.util.concurrent.CompletableFuture
+
+object UpdateManager {
+
+ private val logger = SkyHanniMod.getLogger("UpdateManager")
+ private var _activePromise: CompletableFuture<*>? = null
+ private var activePromise: CompletableFuture<*>?
+ get() = _activePromise
+ set(value) {
+ _activePromise?.cancel(true)
+ _activePromise = value
+ }
+
+ var updateState: UpdateState = UpdateState.NONE
+ private set
+
+ fun getNextVersion(): String? {
+ return potentialUpdate?.update?.versionNumber?.asString
+ }
+
+ @SubscribeEvent
+ fun onConfigLoad(event: ConfigLoadEvent) {
+ SkyHanniMod.feature.about.updateStream.whenChanged { oldValue, newValue ->
+ if (oldValue != newValue)
+ reset()
+ }
+ }
+
+ @SubscribeEvent
+ fun onPlayerAvailableOnce(event: TickEvent.ClientTickEvent) {
+ val p = Minecraft.getMinecraft().thePlayer ?: return
+ MinecraftForge.EVENT_BUS.unregister(this)
+ if (config.autoUpdates)
+ checkUpdate()
+ }
+
+ fun getCurrentVersion(): String {
+ return SkyHanniMod.getVersion()
+ }
+
+ fun injectConfigProcessor(processor: MoulConfigProcessor<*>) {
+ processor.registerConfigEditor(ConfigVersionDisplay::class.java) { option, _ ->
+ GuiOptionEditorUpdateCheck(option)
+ }
+ }
+
+ fun isBetaRelease(): Boolean {
+ return getCurrentVersion().contains("beta", ignoreCase = true)
+ }
+
+ val config get() = SkyHanniMod.feature.about
+
+ fun reset() {
+ updateState = UpdateState.NONE
+ _activePromise = null
+ potentialUpdate = null
+ logger.info("Reset update state")
+ }
+
+ fun checkUpdate() {
+ if (updateState != UpdateState.NONE) {
+ logger.error("Trying to perform update check while another update is already in progress")
+ return
+ }
+ logger.info("Starting update check")
+ var updateStream = config.updateStream.get()
+ if (updateStream == About.UpdateStream.RELEASES && isBetaRelease()) {
+ updateStream = About.UpdateStream.BETA
+ }
+ activePromise = context.checkUpdate(updateStream.stream)
+ .thenAcceptAsync({
+ logger.info("Update check completed")
+ if (updateState != UpdateState.NONE) {
+ logger.warn("This appears to be the second update check. Ignoring this one")
+ return@thenAcceptAsync
+ }
+ potentialUpdate = it
+ if (it.isUpdateAvailable) {
+ updateState = UpdateState.AVAILABLE
+ LorenzUtils.chat("§e[SkyHanni] §aSkyhanni found a new update: ${it.update.versionName}. Go check §b/sh download update §afor more info.")
+ }
+ }, MinecraftExecutor.OnThread)
+ }
+
+ fun queueUpdate() {
+ if (updateState != UpdateState.AVAILABLE) {
+ logger.error("Trying to enqueue an update while another one is already downloaded or none is present")
+ }
+ updateState = UpdateState.QUEUED
+ activePromise = CompletableFuture.supplyAsync {
+ logger.info("Update download started")
+ potentialUpdate!!.prepareUpdate()
+ }.thenAcceptAsync({
+ logger.info("Update download completed, setting exit hook")
+ updateState = UpdateState.DOWNLOADED
+ potentialUpdate!!.executeUpdate()
+ }, MinecraftExecutor.OnThread)
+ }
+
+ val context = UpdateContext(
+ UpdateSource.githubUpdateSource("hannibal002", "Skyhanni"),
+ UpdateTarget.deleteAndSaveInTheSameFolder(UpdateManager::class.java),
+ CurrentVersion.ofTag(SkyHanniMod.getVersion()),
+ SkyHanniMod.MODID,
+ )
+
+ enum class UpdateState {
+ AVAILABLE,
+ QUEUED,
+ DOWNLOADED,
+ NONE
+ }
+
+ var potentialUpdate: PotentialUpdate? = null
+} \ No newline at end of file