User: joe Date: 20 Oct 26 22:51 Revision: 18f885586416e76ed624eb473fa5a81f13cee065 Summary: Add outdated IDE checker startup activity to remind users to update their IDE when it's old enough to continue getting MinecraftDev updates TeamCity URL: http://ci.mcdev.io:80/viewModification.html?tab=vcsModificationFiles&modId=10672&personal=false Index: src/main/kotlin/update/OutdatedIdeChecker.kt =================================================================== --- src/main/kotlin/update/OutdatedIdeChecker.kt (revision 18f885586416e76ed624eb473fa5a81f13cee065) +++ src/main/kotlin/update/OutdatedIdeChecker.kt (revision 18f885586416e76ed624eb473fa5a81f13cee065) @@ -0,0 +1,112 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2026 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.update + +import com.demonwav.mcdev.asset.MCDevBundle +import com.google.gson.JsonParser +import com.intellij.notification.NotificationGroupManager +import com.intellij.notification.NotificationType +import com.intellij.openapi.application.ApplicationInfo +import com.intellij.openapi.diagnostic.logger +import com.intellij.openapi.project.Project +import com.intellij.openapi.startup.ProjectActivity +import com.intellij.openapi.util.BuildNumber +import com.intellij.util.io.HttpRequests +import java.util.concurrent.atomic.AtomicBoolean +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +/** + * Warns the user once per IDE session when their IDE is so far behind the latest stable release that this plugin no + * longer publishes updates for it (e.g. running 2025.3 once 2026.3 is released). + */ +class OutdatedIdeChecker : ProjectActivity { + override suspend fun execute(project: Project) { + if (!checked.compareAndSet(false, true)) { + return + } + + val currentBuild = ApplicationInfo.getInstance().build + if (currentBuild.isSnapshot) { + return + } + + val latestBuild = try { + withContext(Dispatchers.IO) { fetchLatestReleaseBuild() } + } catch (e: CancellationException) { + throw e + } catch (e: Exception) { + LOGGER.info("Failed to check for the latest IDE release", e) + return + } ?: return + + if (releaseIndex(latestBuild) - releaseIndex(currentBuild) < UNSUPPORTED_RELEASE_DISTANCE) { + return + } + + NotificationGroupManager.getInstance().getNotificationGroup("Minecraft Development updates") + .createNotification( + MCDevBundle("update.outdated_ide.title"), + MCDevBundle("update.outdated_ide.content", ApplicationInfo.getInstance().fullApplicationName), + NotificationType.WARNING, + ) + .setImportant(true) + .notify(project) + } + + private fun fetchLatestReleaseBuild(): BuildNumber? { + val text = HttpRequests.request(RELEASES_URL) + .userAgent(PluginUtil.useragent) + .readString() + val build = JsonParser.parseString(text).asJsonObject + .getAsJsonArray(PRODUCT_CODE) + ?.firstOrNull() + ?.asJsonObject + ?.get("build") + ?.asString + ?: return null + return BuildNumber.fromStringOrNull(build) + } + + /** + * Maps a build baseline (e.g. 253 for 2025.3) to a sequential release index, so that consecutive major releases + * differ by exactly 1 (253 -> 261 -> 262 -> 263). + */ + private fun releaseIndex(build: BuildNumber): Int { + val baseline = build.baselineVersion + return (baseline / 10) * 3 + (baseline % 10 - 1) + } + + private companion object { + val LOGGER = logger() + + // All JetBrains IDEs share the same platform build numbers, so IntelliJ IDEA's releases are representative + const val PRODUCT_CODE = "IIU" + const val RELEASES_URL = + "https://data.services.jetbrains.com/products/releases?code=$PRODUCT_CODE&latest=true&type=release" + + // e.g. 2025.3 -> 2026.3 is 3 releases apart (2026.1, 2026.2, 2026.3) + const val UNSUPPORTED_RELEASE_DISTANCE = 3 + + val checked = AtomicBoolean(false) + } +} Index: src/main/resources/META-INF/plugin.xml =================================================================== --- src/main/resources/META-INF/plugin.xml (revision c48f1a3f909cbf2068cc9b19220d0bbe6cecbf3e) +++ src/main/resources/META-INF/plugin.xml (revision 18f885586416e76ed624eb473fa5a81f13cee065) @@ -361,6 +361,8 @@ + + Index: src/main/resources/messages/MinecraftDevelopment.properties =================================================================== --- src/main/resources/messages/MinecraftDevelopment.properties (revision c48f1a3f909cbf2068cc9b19220d0bbe6cecbf3e) +++ src/main/resources/messages/MinecraftDevelopment.properties (revision 18f885586416e76ed624eb473fa5a81f13cee065) @@ -372,3 +372,6 @@ template.provider.zip.label=Archive live.template.bukkit.event_handler.description=Create an event handler + +update.outdated_ide.title=IDE version no longer supported +update.outdated_ide.content=Minecraft Development has dropped support for {0}. To receive further updates to Minecraft Development, please update your IDE.