From 6b868fa9f84ccd688e8301e267ae57a6e969a69e Mon Sep 17 00:00:00 2001 From: Zoriot Date: Tue, 14 Jul 2026 15:38:02 +0200 Subject: [PATCH 1/5] Disable Java + Self Updater on Ptero --- .../client/configs/UpdaterConfig.java | 1 + .../tasks/updater/java/TaskJavaUpdater.java | 6 +++ .../tasks/updater/self/TaskSelfUpdater.java | 8 +++- .../client/utils/UtilsEnvironment.java | 28 +++++++++++++ .../client/utils/UtilsEnvironmentTest.java | 42 +++++++++++++++++++ 5 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/osiris/autoplug/client/utils/UtilsEnvironment.java create mode 100644 src/test/java/com/osiris/autoplug/client/utils/UtilsEnvironmentTest.java diff --git a/src/main/java/com/osiris/autoplug/client/configs/UpdaterConfig.java b/src/main/java/com/osiris/autoplug/client/configs/UpdaterConfig.java index 45437a41..a9aa9874 100644 --- a/src/main/java/com/osiris/autoplug/client/configs/UpdaterConfig.java +++ b/src/main/java/com/osiris/autoplug/client/configs/UpdaterConfig.java @@ -120,6 +120,7 @@ public UpdaterConfig() throws IOException, DuplicateKeyException, YamlReaderExce "AutoPlug is able to update itself automatically.", "Its strongly recommended to have this feature enabled,", "to benefit from new features, bug fixes and security enhancements.", + "Pterodactyl-managed servers disable this at runtime to avoid restart loops.", "Linux users, using screen read this: https://github.com/Osiris-Team/AutoPlug-Client/issues/75"); self_updater_profile = put(name, "self-updater", "profile").setDefValues("AUTOMATIC"); self_updater_build = put(name, "self-updater", "build").setDefValues("stable").setComments( diff --git a/src/main/java/com/osiris/autoplug/client/tasks/updater/java/TaskJavaUpdater.java b/src/main/java/com/osiris/autoplug/client/tasks/updater/java/TaskJavaUpdater.java index 9ce92741..3115e857 100644 --- a/src/main/java/com/osiris/autoplug/client/tasks/updater/java/TaskJavaUpdater.java +++ b/src/main/java/com/osiris/autoplug/client/tasks/updater/java/TaskJavaUpdater.java @@ -14,6 +14,7 @@ import com.osiris.autoplug.client.Server; import com.osiris.autoplug.client.configs.UpdaterConfig; import com.osiris.autoplug.client.utils.GD; +import com.osiris.autoplug.client.utils.UtilsEnvironment; import com.osiris.betterthread.BThread; import com.osiris.betterthread.BThreadManager; import com.osiris.jlib.logger.AL; @@ -45,6 +46,11 @@ public void runAtStart() throws Exception { skip(); return; } + if (new UtilsEnvironment().isPterodactylEnvironment()) { + setStatus("Java updater disabled on Pterodactyl-managed servers."); + skip(); + return; + } if (Server.isRunning()) throw new Exception("Cannot perform update while server is running!"); if (!updaterConfig.java_updater.asBoolean()) { diff --git a/src/main/java/com/osiris/autoplug/client/tasks/updater/self/TaskSelfUpdater.java b/src/main/java/com/osiris/autoplug/client/tasks/updater/self/TaskSelfUpdater.java index 379546a9..0517700e 100644 --- a/src/main/java/com/osiris/autoplug/client/tasks/updater/self/TaskSelfUpdater.java +++ b/src/main/java/com/osiris/autoplug/client/tasks/updater/self/TaskSelfUpdater.java @@ -15,6 +15,7 @@ import com.osiris.autoplug.client.managers.FileManager; import com.osiris.autoplug.client.tasks.updater.TaskDownload; import com.osiris.autoplug.client.utils.GD; +import com.osiris.autoplug.client.utils.UtilsEnvironment; import com.osiris.autoplug.client.utils.UtilsJar; import com.osiris.betterthread.BThread; import com.osiris.betterthread.BThreadManager; @@ -50,6 +51,11 @@ public void runAtStart() throws Exception { skip(); return; } + if (new UtilsEnvironment().isPterodactylEnvironment()) { + setStatus("Self-updater disabled on Pterodactyl-managed servers."); + skip(); + return; + } if (Server.isRunning()) throw new Exception("Cannot perform self update while server is running!"); if (updaterConfig.self_updater_build.asString().equals("stable")) @@ -180,5 +186,3 @@ private void doUpdating(String url) throws Exception { } } - - diff --git a/src/main/java/com/osiris/autoplug/client/utils/UtilsEnvironment.java b/src/main/java/com/osiris/autoplug/client/utils/UtilsEnvironment.java new file mode 100644 index 00000000..10fa5642 --- /dev/null +++ b/src/main/java/com/osiris/autoplug/client/utils/UtilsEnvironment.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2026 Osiris-Team. + * All rights reserved. + * + * This software is copyrighted work, licensed under the terms + * of the MIT-License. Consult the "LICENSE" file for details. + */ + +package com.osiris.autoplug.client.utils; + +import java.util.Locale; +import java.util.Map; + +public class UtilsEnvironment { + public boolean isPterodactylEnvironment() { + return isPterodactylEnvironment(System.getenv()); + } + + public boolean isPterodactylEnvironment(Map env) { + for (String key : env.keySet()) { + if (key == null) continue; + String upperKey = key.toUpperCase(Locale.ROOT); + if (upperKey.startsWith("PTERODACTYL_")) return true; + if (upperKey.startsWith("P_SERVER_")) return true; + } + return false; + } +} diff --git a/src/test/java/com/osiris/autoplug/client/utils/UtilsEnvironmentTest.java b/src/test/java/com/osiris/autoplug/client/utils/UtilsEnvironmentTest.java new file mode 100644 index 00000000..6c9e34ce --- /dev/null +++ b/src/test/java/com/osiris/autoplug/client/utils/UtilsEnvironmentTest.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2026 Osiris-Team. + * All rights reserved. + * + * This software is copyrighted work, licensed under the terms + * of the MIT-License. Consult the "LICENSE" file for details. + */ + +package com.osiris.autoplug.client.utils; + +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class UtilsEnvironmentTest { + @Test + void detectsPterodactylEnvVars() { + UtilsEnvironment utilsEnvironment = new UtilsEnvironment(); + + Map env = new HashMap<>(); + env.put("P_SERVER_UUID", "abc"); + assertTrue(utilsEnvironment.isPterodactylEnvironment(env)); + + env.clear(); + env.put("PTERODACTYL_SERVER_UUID", "abc"); + assertTrue(utilsEnvironment.isPterodactylEnvironment(env)); + } + + @Test + void ignoresNonPterodactylEnvVars() { + UtilsEnvironment utilsEnvironment = new UtilsEnvironment(); + + Map env = new HashMap<>(); + env.put("SERVER_UUID", "abc"); + env.put("PANEL_NAME", "AutoPlug"); + assertFalse(utilsEnvironment.isPterodactylEnvironment(env)); + } +} From 592f746a96860062874e8469f86f4fda564bcff2 Mon Sep 17 00:00:00 2001 From: Zoriot Date: Tue, 14 Jul 2026 16:05:38 +0200 Subject: [PATCH 2/5] Fix auto self updating for ptero Closes #287. --- .../client/tasks/updater/TaskDownload.java | 31 ++++++++++++------- .../tasks/updater/self/TaskSelfUpdater.java | 17 +++++++--- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/osiris/autoplug/client/tasks/updater/TaskDownload.java b/src/main/java/com/osiris/autoplug/client/tasks/updater/TaskDownload.java index 8a88b186..8f79aefa 100644 --- a/src/main/java/com/osiris/autoplug/client/tasks/updater/TaskDownload.java +++ b/src/main/java/com/osiris/autoplug/client/tasks/updater/TaskDownload.java @@ -22,6 +22,7 @@ import java.io.File; import java.io.FileOutputStream; import java.util.Arrays; +import java.util.Locale; import java.util.Random; public class TaskDownload extends BThread { @@ -76,18 +77,8 @@ public void runAtStart() throws Exception { body = response.body(); if (body == null) throw new Exception("Download of '" + dest.getName() + "' failed because of null response body!"); - else if (!ignoreContentType && body.contentType() == null) - throw new Exception("Download of '" + dest.getName() + "' failed due to null content type!"); - else if (!ignoreContentType && !body.contentType().type().equals("application")) - throw new Exception("Download of '" + dest.getName() + "' failed because of invalid content type: " + body.contentType().type()); - else if (!ignoreContentType && !body.contentType().subtype().equals("java-archive") - && !body.contentType().subtype().equals("jar") - && !body.contentType().subtype().equals("octet-stream")) { - if (allowedSubContentTypes == null) - throw new Exception("Download of '" + dest.getName() + "' failed because of invalid sub-content type: " + body.contentType().subtype()); - if (!Arrays.asList(allowedSubContentTypes).contains(body.contentType().subtype())) - throw new Exception("Download of '" + dest.getName() + "' failed because of invalid sub-content type: " + body.contentType().subtype()); - } + if (!isAllowedContentType(fileName, body.contentType(), ignoreContentType, allowedSubContentTypes)) + throw new Exception("Download of '" + dest.getName() + "' failed because of invalid content type: " + body.contentType()); long completeFileSize = body.contentLength(); setMax(completeFileSize); @@ -151,4 +142,20 @@ public boolean compareWithSHA256(String expectedHash) { return result; } + static boolean isAllowedContentType(String fileName, okhttp3.MediaType contentType, boolean ignoreContentType, String... allowedSubContentTypes) { + if (ignoreContentType) return true; + if (contentType == null) return false; + String type = contentType.type(); + String subtype = contentType.subtype(); + if ("application".equals(type)) { + if ("java-archive".equals(subtype) || "jar".equals(subtype) || "octet-stream".equals(subtype)) return true; + if (allowedSubContentTypes == null) return false; + return Arrays.asList(allowedSubContentTypes).contains(subtype); + } + return fileName != null + && fileName.toLowerCase(Locale.ROOT).endsWith(".jar") + && "text".equals(type) + && "plain".equals(subtype); + } + } diff --git a/src/main/java/com/osiris/autoplug/client/tasks/updater/self/TaskSelfUpdater.java b/src/main/java/com/osiris/autoplug/client/tasks/updater/self/TaskSelfUpdater.java index 0517700e..7d67e037 100644 --- a/src/main/java/com/osiris/autoplug/client/tasks/updater/self/TaskSelfUpdater.java +++ b/src/main/java/com/osiris/autoplug/client/tasks/updater/self/TaskSelfUpdater.java @@ -51,11 +51,6 @@ public void runAtStart() throws Exception { skip(); return; } - if (new UtilsEnvironment().isPterodactylEnvironment()) { - setStatus("Self-updater disabled on Pterodactyl-managed servers."); - skip(); - return; - } if (Server.isRunning()) throw new Exception("Cannot perform self update while server is running!"); if (updaterConfig.self_updater_build.asString().equals("stable")) @@ -166,6 +161,18 @@ private void doUpdating(String url) throws Exception { finish("Downloaded AutoPlug update is broken. Nothing changed!", false); return; } + boolean isPterodactyl = new UtilsEnvironment().isPterodactylEnvironment(); + if (isPterodactyl) { + File currentJarFile = currentInstallationPath != null + ? FileManager.convertRelativeToAbsolutePath(currentInstallationPath) + : new UtilsJar().getThisJar(); + setStatus("Installing AutoPlug update in place (" + currentVersion + " -> " + version + ")..."); + Files.copy(cache_dest.toPath(), currentJarFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + setStatus("AutoPlug update was installed successfully (" + currentVersion + " -> " + version + ")!"); + finish(true); + System.exit(0); + return; + } setStatus("Installing AutoPlug update (" + currentVersion + " -> " + version + ")..."); // Create the actual update copy file, by simply copying the newly downloaded file. Files.copy(cache_dest.toPath(), From b5e19ca772537f4bf9b99ea2234df346e6c24561 Mon Sep 17 00:00:00 2001 From: Zoriot Date: Thu, 16 Jul 2026 14:50:16 +0200 Subject: [PATCH 3/5] Add safe mode option for self-updater in Pterodactyl environment Was requested in the pull request, so you can skip the special handling. --- .../com/osiris/autoplug/client/configs/UpdaterConfig.java | 5 +++++ .../autoplug/client/tasks/updater/self/TaskSelfUpdater.java | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/osiris/autoplug/client/configs/UpdaterConfig.java b/src/main/java/com/osiris/autoplug/client/configs/UpdaterConfig.java index a9aa9874..a3d18a76 100644 --- a/src/main/java/com/osiris/autoplug/client/configs/UpdaterConfig.java +++ b/src/main/java/com/osiris/autoplug/client/configs/UpdaterConfig.java @@ -28,6 +28,7 @@ public class UpdaterConfig extends MyYaml { public YamlSection self_updater; public YamlSection self_updater_profile; public YamlSection self_updater_build; + public YamlSection self_updater_safe_mode; public YamlSection java_updater; public YamlSection java_updater_profile; @@ -126,6 +127,10 @@ public UpdaterConfig() throws IOException, DuplicateKeyException, YamlReaderExce self_updater_build = put(name, "self-updater", "build").setDefValues("stable").setComments( "Choose between 'stable' and 'beta' builds.", "Stable builds are recommended."); + self_updater_safe_mode = put(name, "self-updater", "safe-mode").setDefValues("true").setComments( + "If AutoPlug is disabled, it will update itself without advanced compatibility. Self-updating on Ptero will work in the same way as it does when not on Ptero.", + "Its strongly recommended to have this feature enabled on non AutoPlug specific eggs," + ); put(name, "java-updater").setCountTopLineBreaks(1); java_updater = put(name, "java-updater", "enable").setDefValues("true"); diff --git a/src/main/java/com/osiris/autoplug/client/tasks/updater/self/TaskSelfUpdater.java b/src/main/java/com/osiris/autoplug/client/tasks/updater/self/TaskSelfUpdater.java index 7d67e037..66cd2ecd 100644 --- a/src/main/java/com/osiris/autoplug/client/tasks/updater/self/TaskSelfUpdater.java +++ b/src/main/java/com/osiris/autoplug/client/tasks/updater/self/TaskSelfUpdater.java @@ -162,7 +162,7 @@ private void doUpdating(String url) throws Exception { return; } boolean isPterodactyl = new UtilsEnvironment().isPterodactylEnvironment(); - if (isPterodactyl) { + if (isPterodactyl && updaterConfig.self_updater_safe_mode.asBoolean()) { File currentJarFile = currentInstallationPath != null ? FileManager.convertRelativeToAbsolutePath(currentInstallationPath) : new UtilsJar().getThisJar(); From 783341f96936e253796f832f4defdd4da1fa7780 Mon Sep 17 00:00:00 2001 From: Zoriot Date: Fri, 17 Jul 2026 22:21:35 +0200 Subject: [PATCH 4/5] Make it possible to force enable Java updater on Ptero servers. Requested by pull request review, might be handy on AutoPlug egg for example. --- .../com/osiris/autoplug/client/configs/UpdaterConfig.java | 4 ++++ .../client/tasks/updater/java/TaskJavaUpdater.java | 7 +------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/osiris/autoplug/client/configs/UpdaterConfig.java b/src/main/java/com/osiris/autoplug/client/configs/UpdaterConfig.java index a3d18a76..3fad9467 100644 --- a/src/main/java/com/osiris/autoplug/client/configs/UpdaterConfig.java +++ b/src/main/java/com/osiris/autoplug/client/configs/UpdaterConfig.java @@ -36,6 +36,7 @@ public class UpdaterConfig extends MyYaml { public YamlSection java_updater_version; public YamlSection java_updater_build_id; public YamlSection java_updater_large_heap; + public YamlSection java_updater_force_enable; public YamlSection server_updater; public YamlSection server_updater_profile; @@ -147,6 +148,9 @@ public UpdaterConfig() throws IOException, DuplicateKeyException, YamlReaderExce "Otherwise don't touch this. It gets replaced after every successful update automatically."); java_updater_large_heap = put(name, "java-updater", "large-heap").setDefValues("false").setComments( "Only enable if you plan to give your server more than 57gb of ram, otherwise not recommended."); + java_updater_force_enable = put(name, "java-updater", "force-enable").setDefValues("false").setComments( + "If you are running AutoPlug via Pterodactyl Panel, the java-updater is disabled to avoid redundancy. Set to true to force the self-updater to run anyways." + ); put(name, "server-updater").setCountTopLineBreaks(1); diff --git a/src/main/java/com/osiris/autoplug/client/tasks/updater/java/TaskJavaUpdater.java b/src/main/java/com/osiris/autoplug/client/tasks/updater/java/TaskJavaUpdater.java index 3115e857..73084a2d 100644 --- a/src/main/java/com/osiris/autoplug/client/tasks/updater/java/TaskJavaUpdater.java +++ b/src/main/java/com/osiris/autoplug/client/tasks/updater/java/TaskJavaUpdater.java @@ -46,18 +46,13 @@ public void runAtStart() throws Exception { skip(); return; } - if (new UtilsEnvironment().isPterodactylEnvironment()) { + if (new UtilsEnvironment().isPterodactylEnvironment() && !updaterConfig.java_updater_force_enable.asBoolean()) { setStatus("Java updater disabled on Pterodactyl-managed servers."); skip(); return; } if (Server.isRunning()) throw new Exception("Cannot perform update while server is running!"); - if (!updaterConfig.java_updater.asBoolean()) { - skip(); - return; - } - setStatus("Searching for updates..."); // First set the details we need From 94655999a06edcfef214f5b4e6905c33977d4fd1 Mon Sep 17 00:00:00 2001 From: Zoriot Date: Fri, 17 Jul 2026 22:23:31 +0200 Subject: [PATCH 5/5] Remove unnecessary comnment --- .../java/com/osiris/autoplug/client/configs/UpdaterConfig.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/osiris/autoplug/client/configs/UpdaterConfig.java b/src/main/java/com/osiris/autoplug/client/configs/UpdaterConfig.java index 3fad9467..5c8cd00c 100644 --- a/src/main/java/com/osiris/autoplug/client/configs/UpdaterConfig.java +++ b/src/main/java/com/osiris/autoplug/client/configs/UpdaterConfig.java @@ -122,7 +122,6 @@ public UpdaterConfig() throws IOException, DuplicateKeyException, YamlReaderExce "AutoPlug is able to update itself automatically.", "Its strongly recommended to have this feature enabled,", "to benefit from new features, bug fixes and security enhancements.", - "Pterodactyl-managed servers disable this at runtime to avoid restart loops.", "Linux users, using screen read this: https://github.com/Osiris-Team/AutoPlug-Client/issues/75"); self_updater_profile = put(name, "self-updater", "profile").setDefValues("AUTOMATIC"); self_updater_build = put(name, "self-updater", "build").setDefValues("stable").setComments(