From 6bfd7cac508b89d198699f697abc94a22635d9b8 Mon Sep 17 00:00:00 2001 From: msdigital Date: Tue, 31 Mar 2026 09:51:27 +0200 Subject: [PATCH 1/3] Prepare plugin for Hytale Update 4 compatibility --- build.gradle.kts | 4 ++-- gradle.properties | 2 +- .../java/com/bumenfeld/clock/ClockTickSystem.java | 11 ++++------- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 382b599..b57521a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,7 +3,7 @@ import org.gradle.api.tasks.bundling.Jar import org.gradle.api.tasks.Copy import java.io.ByteArrayOutputStream import java.io.IOException -import java.net.URL +import java.net.URI import java.time.OffsetDateTime import java.time.ZoneOffset import java.time.format.DateTimeFormatter @@ -96,7 +96,7 @@ fun resolveServerVersion(raw: String?): String? { fun fetchLatestServerRelease(): String? { val metadataUrl = "https://maven.hytale.com/release/com/hypixel/hytale/Server/maven-metadata.xml" return try { - val xml = URL(metadataUrl).readText() + val xml = URI(metadataUrl).toURL().openStream().bufferedReader().use { it.readText() } Regex("([^<]+)").find(xml)?.groupValues?.get(1) ?: Regex("([^<]+)").find(xml)?.groupValues?.get(1) } catch (ex: IOException) { diff --git a/gradle.properties b/gradle.properties index b3eb447..47b94d0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,4 +14,4 @@ plugin_author=msdigital plugin_website=https://github.com/msdigital/bumenfeld-clock plugin_main_entrypoint=com.bumenfeld.clock.Clock enable_hytale_plugin=true -server_version=* +server_version=2026.03.26-89796e57b diff --git a/src/main/java/com/bumenfeld/clock/ClockTickSystem.java b/src/main/java/com/bumenfeld/clock/ClockTickSystem.java index 15d5661..0dc9015 100644 --- a/src/main/java/com/bumenfeld/clock/ClockTickSystem.java +++ b/src/main/java/com/bumenfeld/clock/ClockTickSystem.java @@ -2,12 +2,10 @@ import com.hypixel.hytale.component.ArchetypeChunk; import com.hypixel.hytale.component.CommandBuffer; -import com.hypixel.hytale.component.Holder; import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.query.Query; import com.hypixel.hytale.component.system.tick.EntityTickingSystem; import com.buuz135.mhud.MultipleHUD; -import com.hypixel.hytale.server.core.entity.EntityUtils; import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.entity.entities.player.hud.HudManager; import com.hypixel.hytale.server.core.modules.time.WorldTimeResource; @@ -51,9 +49,8 @@ public void tick(float dt, int index, ArchetypeChunk archetypeChunk return; } - Holder holder = EntityUtils.toHolder(index, archetypeChunk); - Player player = holder.getComponent(Player.getComponentType()); - PlayerRef playerRef = holder.getComponent(PlayerRef.getComponentType()); + Player player = archetypeChunk.getComponent(index, Player.getComponentType()); + PlayerRef playerRef = archetypeChunk.getComponent(index, PlayerRef.getComponentType()); if (player == null || playerRef == null) { return; } @@ -66,10 +63,10 @@ public void tick(float dt, int index, ArchetypeChunk archetypeChunk return; } - PlayerClockSettings settings = holder.getComponent(settingsComponent); + PlayerClockSettings settings = archetypeChunk.getComponent(index, settingsComponent); if (settings == null) { settings = PlayerClockSettings.fromDefaults(config.get()); - holder.putComponent(settingsComponent, settings); + commandBuffer.putComponent(archetypeChunk.getReferenceTo(index), settingsComponent, settings); } String formatted = formatTime(gameDateTime, settings); From 1051f8fe0ee6b005f5d56e586e33265ac872a835 Mon Sep 17 00:00:00 2001 From: msdigital Date: Tue, 31 Mar 2026 14:16:11 +0200 Subject: [PATCH 2/3] Synchronize extracted manifest on startup for compatibility --- src/main/java/com/bumenfeld/clock/Clock.java | 1 + .../ExtractedAssetPackManifestEnsurer.java | 41 ++++++++++++++++--- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/bumenfeld/clock/Clock.java b/src/main/java/com/bumenfeld/clock/Clock.java index 1a5d421..81856cd 100644 --- a/src/main/java/com/bumenfeld/clock/Clock.java +++ b/src/main/java/com/bumenfeld/clock/Clock.java @@ -19,6 +19,7 @@ public class Clock extends JavaPlugin { public Clock(JavaPluginInit init) { super(init); + ExtractedAssetPackManifestEnsurer.ensure(this); this.config = withConfig("BumenfeldClock", ClockConfig.CODEC); } diff --git a/src/main/java/com/bumenfeld/clock/ExtractedAssetPackManifestEnsurer.java b/src/main/java/com/bumenfeld/clock/ExtractedAssetPackManifestEnsurer.java index cc3656c..072c652 100644 --- a/src/main/java/com/bumenfeld/clock/ExtractedAssetPackManifestEnsurer.java +++ b/src/main/java/com/bumenfeld/clock/ExtractedAssetPackManifestEnsurer.java @@ -31,10 +31,6 @@ static void ensure(JavaPlugin plugin) { Files.createDirectories(dataDirectory); Path extractedManifest = dataDirectory.resolve("manifest.json"); String extractedPackName = extractedPackName(pluginManifest.getName()); - if (!shouldWriteExtractedManifest(extractedManifest, pluginManifest.getGroup(), pluginManifest.getName(), extractedPackName)) { - return; - } - try (InputStream stream = plugin.getClass().getClassLoader().getResourceAsStream("manifest.json")) { if (stream == null) { return; @@ -43,6 +39,15 @@ static void ensure(JavaPlugin plugin) { if (!(root instanceof ObjectNode rootObject)) { return; } + if (!shouldWriteExtractedManifest( + extractedManifest, + pluginManifest.getGroup(), + pluginManifest.getName(), + extractedPackName, + rootObject + )) { + return; + } rootObject.put("Name", extractedPackName); rootObject.put("IncludesAssetPack", false); @@ -55,17 +60,43 @@ static void ensure(JavaPlugin plugin) { } } - private static boolean shouldWriteExtractedManifest(Path path, String pluginGroup, String pluginName, String extractedPackName) { + private static boolean shouldWriteExtractedManifest( + Path path, + String pluginGroup, + String pluginName, + String extractedPackName, + JsonNode bundledManifest + ) { if (!Files.exists(path)) { return true; } try { JsonNode root = MAPPER.readTree(path.toFile()); + if (!(root instanceof ObjectNode)) { + return true; + } String group = root.path("Group").asText(""); String name = root.path("Name").asText(""); if (group.equals(pluginGroup) && name.equals(extractedPackName)) { + // Managed extracted manifest must keep IncludesAssetPack=false to avoid duplicate asset-pack registration. + if (root.path("IncludesAssetPack").asBoolean(true)) { + return true; + } + + String extractedBuildId = root.path("Build").path("Id").asText(""); + String bundledBuildId = bundledManifest.path("Build").path("Id").asText(""); + if (!bundledBuildId.isBlank() && !bundledBuildId.equals(extractedBuildId)) { + return true; + } + + String extractedServerVersion = root.path("ServerVersion").asText(""); + String bundledServerVersion = bundledManifest.path("ServerVersion").asText(""); + if (!bundledServerVersion.isBlank() && !bundledServerVersion.equals(extractedServerVersion)) { + return true; + } + return false; } if (group.equals(pluginGroup) && name.equals(pluginName)) { From 809b0d1867d4cb6829f6b26152bc8bdeb05ba5d6 Mon Sep 17 00:00:00 2001 From: msdigital Date: Tue, 31 Mar 2026 14:40:32 +0200 Subject: [PATCH 3/3] Add UpdateChecker CurseForge metadata to manifest --- src/main/resources/manifest.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/resources/manifest.json b/src/main/resources/manifest.json index 080d27f..f0cbeb0 100644 --- a/src/main/resources/manifest.json +++ b/src/main/resources/manifest.json @@ -21,5 +21,8 @@ "Id": "${build_id}", "Timestamp": "${build_timestamp}", "GitRevision": "${git_revision}" + }, + "UpdateChecker": { + "CurseForge": "1452160" } }