diff --git a/patches/server/0006-Leaves-Server-Config-And-Command.patch b/patches/server/0006-Leaves-Server-Config-And-Command.patch index 48835967..f7f734f7 100644 --- a/patches/server/0006-Leaves-Server-Config-And-Command.patch +++ b/patches/server/0006-Leaves-Server-Config-And-Command.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Leaves Server Config And Command diff --git a/build.gradle.kts b/build.gradle.kts -index 5025c5df3ee6ed84106782e3f9228874bebe63ca..268193499b9f1fae0c01963e8004a3e7422f77ca 100644 +index d0caefc335e85afede34ad3b804bd6996fa0181c..c90b8c6c6293cca5c59a7f369ff6e90c7b75fbba 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -212,6 +212,14 @@ tasks.registerRunTask("runDevServer") { @@ -65,7 +65,7 @@ index caf6ff33b42472d30f28629470e12889f50490cc..0de0d0d290625ad4f6cacc1d6374a5d0 @Override public void restart() { diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 459f47244bdfeab63b5f16d780b0291d36310de8..a872421bc3e67fdcc929f104f4b085fbc47760a8 100644 +index e863c947d6d8d4c9af113fd6472b7ddbe1fdd26e..b4a1a430ce2c361d24ffa46cfdf00b5f8b53586a 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -168,6 +168,14 @@ public class Main { @@ -85,10 +85,10 @@ index 459f47244bdfeab63b5f16d780b0291d36310de8..a872421bc3e67fdcc929f104f4b085fb .withRequiredArg() diff --git a/src/main/java/org/leavesmc/leaves/LeavesConfig.java b/src/main/java/org/leavesmc/leaves/LeavesConfig.java new file mode 100644 -index 0000000000000000000000000000000000000000..cf5b38338e0349cf75cf7004407fc82a91019c5d +index 0000000000000000000000000000000000000000..ad8d79e1c9e1168436538a23f6215b1e70029857 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/LeavesConfig.java -@@ -0,0 +1,907 @@ +@@ -0,0 +1,913 @@ +package org.leavesmc.leaves; + +import com.destroystokyo.paper.util.SneakyThrow; @@ -860,6 +860,12 @@ index 0000000000000000000000000000000000000000..cf5b38338e0349cf75cf7004407fc82a + } + } + ++ @GlobalConfig(name = "download-source", category = {"misc", "auto-update"}, verify = ConfigVerify.StringConfigVerify.class) ++ public static String autoUpdateSource = "application"; ++ ++ @GlobalConfig(name = "allow-experimental", category = {"misc", "auto-update"}) ++ public static Boolean autoUpdateAllowExperimental = false; ++ + @GlobalConfig(name = "time", category = {"misc", "auto-update"}, lock = true, verify = ConfigVerify.ListConfigVerify.class) + public static List autoUpdateTime = List.of("14:00", "2:00"); + diff --git a/patches/server/0095-Leaves-Updater.patch b/patches/server/0095-Leaves-Updater.patch index 7fb397cb..8eeaab84 100644 --- a/patches/server/0095-Leaves-Updater.patch +++ b/patches/server/0095-Leaves-Updater.patch @@ -48,10 +48,10 @@ index 0000000000000000000000000000000000000000..7f94df607e8ffd48ab2cb7c90d520c2b +} diff --git a/src/main/java/org/leavesmc/leaves/util/LeavesUpdateHelper.java b/src/main/java/org/leavesmc/leaves/util/LeavesUpdateHelper.java new file mode 100644 -index 0000000000000000000000000000000000000000..8620305f3330a856ad7445259f565bf8e281ea52 +index 0000000000000000000000000000000000000000..d5e6e6eacabf97ed63a84ea6dcb849f5574a8c67 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/util/LeavesUpdateHelper.java -@@ -0,0 +1,268 @@ +@@ -0,0 +1,257 @@ +package org.leavesmc.leaves.util; + +import com.google.common.base.Charsets; @@ -85,6 +85,7 @@ index 0000000000000000000000000000000000000000..8620305f3330a856ad7445259f565bf8 +import java.security.MessageDigest; +import java.time.Duration; +import java.time.LocalTime; ++import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; @@ -163,20 +164,21 @@ index 0000000000000000000000000000000000000000..8620305f3330a856ad7445259f565bf8 + + private static void downloadLeaves() { + String minecraftVersion = Bukkit.getMinecraftVersion(); -+ String version = Bukkit.getVersion(); -+ -+ if (version.startsWith("null")) { ++ String version = LeavesUpdateHelper.class.getPackage().getImplementationVersion(); ++ if (version == null) { + LeavesLogger.LOGGER.info("IDE? Can not update!"); + updateTaskStarted = false; + return; + } ++ String[] versionSplit = version.split("-"); + -+ String gitHash = version.substring("git-Leaves-".length()).split("[-\\s]")[0].replaceAll("\"", ""); ++ String gitHash = versionSplit[2]; ++ LeavesLogger.LOGGER.info("Now gitHash: " + gitHash); + + LeavesLogger.LOGGER.info("Trying to get latest build info."); + LeavesBuildInfo buildInfo = getLatestBuildInfo(minecraftVersion, gitHash); + -+ if (buildInfo != LeavesBuildInfo.NULL) { ++ if (buildInfo != LeavesBuildInfo.ERROR) { + if (!buildInfo.needUpdate) { + LeavesLogger.LOGGER.warning("You are running the latest version, stopping update."); + updateTaskStarted = false; @@ -188,34 +190,21 @@ index 0000000000000000000000000000000000000000..8620305f3330a856ad7445259f565bf8 + Path outFile = Path.of(autoUpdateDir, "leaves", buildInfo.fileName + ".cache"); + Files.deleteIfExists(outFile); + -+ boolean downloadFlag = false; -+ URL cdnUrl = new URI(buildInfo.cdnUrl).toURL(); + try ( -+ final ReadableByteChannel source = Channels.newChannel(cdnUrl.openStream()); ++ final ReadableByteChannel source = Channels.newChannel(new URI( ++ buildInfo.url + LeavesConfig.autoUpdateSource).toURL().openStream() ++ ); + final FileChannel fileChannel = FileChannel.open(outFile, CREATE, WRITE, TRUNCATE_EXISTING) + ) { + fileChannel.transferFrom(source, 0, Long.MAX_VALUE); -+ downloadFlag = true; ++ LeavesLogger.LOGGER.info("Download " + buildInfo.fileName + " completed."); + } catch (final IOException e) { ++ LeavesLogger.LOGGER.warning("Download " + buildInfo.fileName + " failed.", e); + Files.deleteIfExists(outFile); ++ updateTaskStarted = false; ++ return; + } + -+ if (!downloadFlag) { -+ URL githubUrl = new URI(buildInfo.githubUrl).toURL(); -+ try ( -+ final ReadableByteChannel source = Channels.newChannel(githubUrl.openStream()); -+ final FileChannel fileChannel = FileChannel.open(outFile, CREATE, WRITE, TRUNCATE_EXISTING) -+ ) { -+ fileChannel.transferFrom(source, 0, Long.MAX_VALUE); -+ } catch (final IOException e) { -+ LeavesLogger.LOGGER.warning("Download " + buildInfo.fileName + " failed.", e); -+ Files.deleteIfExists(outFile); -+ updateTaskStarted = false; -+ return; -+ } -+ } -+ -+ LeavesLogger.LOGGER.info("Download " + buildInfo.fileName + " completed."); + if (!isFileValid(outFile, buildInfo.sha256)) { + LeavesLogger.LOGGER.warning("Hash check failed for downloaded file " + buildInfo.fileName); + Files.deleteIfExists(outFile); @@ -240,7 +229,7 @@ index 0000000000000000000000000000000000000000..8620305f3330a856ad7445259f565bf8 + LeavesLogger.LOGGER.severe("Leaves update failed", e); + } + } else { -+ LeavesLogger.LOGGER.warning("Can't get build info, stopping update."); ++ LeavesLogger.LOGGER.warning("Stopping update."); + } + updateTaskStarted = false; + } @@ -272,51 +261,51 @@ index 0000000000000000000000000000000000000000..8620305f3330a856ad7445259f565bf8 + + private static LeavesBuildInfo getLatestBuildInfo(String mcVersion, String gitHash) { + try { -+ HttpURLConnection connection = (HttpURLConnection) new URI("https://api.leavesmc.org/projects/leaves/versions/" + mcVersion + "/builds/latest").toURL().openConnection(); ++ HttpURLConnection connection = (HttpURLConnection) new URI( ++ "https://api.leavesmc.org/v2/projects/leaves/versions/" + mcVersion + "/builds/latest" ++ ).toURL().openConnection(); + connection.connect(); -+ boolean useApiV2 = false; -+ if (connection.getResponseCode() / 100 != 2) { -+ connection = (HttpURLConnection) new URI("https://api.leavesmc.org/v2/projects/leaves/versions/" + mcVersion + "/builds/latest").toURL().openConnection(); -+ connection.connect(); -+ useApiV2 = true; ++ if (connection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) { ++ return LeavesBuildInfo.ERROR; + } -+ if (connection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) return LeavesBuildInfo.NULL; + try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), Charsets.UTF_8))) { + JsonObject obj = new Gson().fromJson(reader, JsonObject.class); + String channel = obj.get("channel").getAsString(); -+ -+ if (channel.equals("default")) { -+ int build = obj.get("build").getAsInt(); -+ -+ JsonArray changes = obj.get("changes").getAsJsonArray(); -+ boolean needUpdate = true; -+ for (JsonElement change : changes) { -+ if (change.getAsJsonObject().get("commit").getAsString().startsWith(gitHash)) { -+ needUpdate = false; -+ break; -+ } ++ if ("experimental".equals(channel) && !LeavesConfig.autoUpdateAllowExperimental) { ++ LeavesLogger.LOGGER.warning("Experimental version is not allowed to update for default, if you really want to update, please set misc.auto-update.allow-experimental to true in leaves.yml"); ++ return LeavesBuildInfo.ERROR; ++ } ++ int build = obj.get("build").getAsInt(); ++ ++ JsonArray changes = obj.get("changes").getAsJsonArray(); ++ boolean needUpdate = true; ++ for (JsonElement change : changes) { ++ if (change.getAsJsonObject().get("commit").getAsString().startsWith(gitHash)) { ++ needUpdate = false; ++ break; + } -+ -+ JsonObject downloadInfo = obj.get("downloads").getAsJsonObject().get("application").getAsJsonObject(); -+ String name = downloadInfo.get("name").getAsString(); -+ String sha256 = downloadInfo.get("sha256").getAsString(); -+ String githubUrl = useApiV2 ? "https://api.leavesmc.org/v2/projects/leaves/versions/" + mcVersion + "/builds/" + build + "/downloads/" + name : downloadInfo.get("url").getAsString(); -+ String cdnUrl = useApiV2 ? "https://cdn.leavesmc.z0z0r4.top/cache/" + name : downloadInfo.get("cdn_url").getAsString(); -+ return new LeavesBuildInfo(build, name, sha256, needUpdate, cdnUrl, githubUrl); -+ } else { -+ return LeavesBuildInfo.NULL; + } ++ ++ JsonObject downloadInfo = obj.get("downloads").getAsJsonObject().get("application").getAsJsonObject(); ++ String fileName = downloadInfo.get("name").getAsString(); ++ String sha256 = downloadInfo.get("sha256").getAsString(); ++ String url = "https://api.leavesmc.org/v2/projects/leaves/versions/" + mcVersion + "/builds/" + build + "/downloads/"; ++ return new LeavesBuildInfo(build, fileName, sha256, needUpdate, url); + } catch (JsonSyntaxException | NumberFormatException e) { + LeavesLogger.LOGGER.warning("Fail to get latest build info", e); -+ return LeavesBuildInfo.NULL; ++ return LeavesBuildInfo.ERROR; + } + } catch (IOException | URISyntaxException e) { + LeavesLogger.LOGGER.warning("Fail to get latest build info", e); -+ return LeavesBuildInfo.NULL; ++ return LeavesBuildInfo.ERROR; + } + } + -+ private record LeavesBuildInfo(int build, String fileName, String sha256, boolean needUpdate, String cdnUrl, String githubUrl) { -+ public static LeavesBuildInfo NULL = new LeavesBuildInfo(-1, null, null, false, null, null); ++ private record LeavesBuildInfo(int build, ++ String fileName, ++ String sha256, ++ boolean needUpdate, ++ String url) { ++ public static LeavesBuildInfo ERROR = null; + } +}