diff --git a/build.gradle.kts b/build.gradle.kts index 6f835f9..ec383b3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,7 +11,7 @@ val PLUGIN_NAME = "OriginBlacklist" val PLUGIN_IDEN = "originblacklist" val PLUGIN_DOMN = "xyz.webmc" val PLUGIN_DESC = "An eaglercraft client blacklist plugin." -val PLUGIN_VERS = "2.0.2" +val PLUGIN_VERS = "2.0.3" val PLUGIN_SITE = "https://github.com/WebMCDevelopment/$PLUGIN_IDEN" val PLUGIN_DEPA = listOf("EaglercraftXServer") val PLUGIN_DEPB = listOf("EaglercraftXServer") diff --git a/src/main/java/xyz/webmc/originblacklist/base/OriginBlacklist.java b/src/main/java/xyz/webmc/originblacklist/base/OriginBlacklist.java index a075ab5..24f4f2c 100644 --- a/src/main/java/xyz/webmc/originblacklist/base/OriginBlacklist.java +++ b/src/main/java/xyz/webmc/originblacklist/base/OriginBlacklist.java @@ -10,9 +10,13 @@ import xyz.webmc.originblacklist.base.util.IOriginBlacklistPlugin; import xyz.webmc.originblacklist.base.util.OPlayer; import xyz.webmc.originblacklist.base.util.UpdateChecker; +import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.Base64; import java.util.List; @@ -40,12 +44,11 @@ public final class OriginBlacklist { private final IOriginBlacklistPlugin plugin; private final OriginBlacklistConfig config; - private boolean updateAvailable; + private String updateURL; public OriginBlacklist(final IOriginBlacklistPlugin plugin) { this.plugin = plugin; this.config = new OriginBlacklistConfig(plugin); - this.checkForUpdate(); plugin.scheduleRepeat(() -> { this.checkForUpdate(); }, 60, TimeUnit.MINUTES); @@ -282,13 +285,48 @@ public final class OriginBlacklist { } private final void checkForUpdate() { - CompletableFuture.runAsync(() -> { - this.updateAvailable = UpdateChecker.checkForUpdate(PLUGIN_REPO, this.plugin.getPluginVersion(), - this.config.get("update_checker.allow_snapshots").getAsBoolean()); - if (this.updateAvailable) { - this.plugin.log(EnumLogLevel.INFO, "An update is available! Download it at https://github.com/" + PLUGIN_REPO + ".git"); - } - }); + if (this.config.get("update_checker.enabled").getAsBoolean()) { + CompletableFuture.runAsync(() -> { + this.updateURL = UpdateChecker.checkForUpdate(PLUGIN_REPO, this.plugin.getPluginVersion(), + this.config.get("update_checker.allow_snapshots").getAsBoolean()); + if (isNonNull((this.updateURL))) { + if (!this.config.get("update_checker.auto_update").getAsBoolean()) { + this.plugin.log(EnumLogLevel.INFO, "An update is available! Download it at " + this.updateURL); + } else { + final Path jar = this.plugin.getPluginJarPath(); + final Path bak = jar.resolveSibling(jar.getFileName().toString() + ".bak"); + final Path tmp = jar.resolveSibling(jar.getFileName().toString() + ".tmp"); + try { + Files.copy(jar, bak, StandardCopyOption.REPLACE_EXISTING); + } catch (final Throwable t) { + t.printStackTrace(); + } + try { + final URL url = new URL(this.updateURL); + final HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + conn.setConnectTimeout(15000); + conn.setReadTimeout(15000); + conn.connect(); + try (final InputStream in = conn.getInputStream()) { + Files.copy(in, tmp, StandardCopyOption.REPLACE_EXISTING); + } finally { + conn.disconnect(); + } + Files.move(tmp, jar, StandardCopyOption.REPLACE_EXISTING); + Files.delete(bak); + } catch (final Throwable t) { + t.printStackTrace(); + try { + Files.move(bak, jar, StandardCopyOption.REPLACE_EXISTING); + } catch (final Throwable _t) { + _t.printStackTrace(); + } + } + } + } + }); + } } public static final String getComponentString(final Component comp) { diff --git a/src/main/java/xyz/webmc/originblacklist/base/command/CommandContext.java b/src/main/java/xyz/webmc/originblacklist/base/command/CommandContext.java index d9f1a03..70a9b08 100644 --- a/src/main/java/xyz/webmc/originblacklist/base/command/CommandContext.java +++ b/src/main/java/xyz/webmc/originblacklist/base/command/CommandContext.java @@ -1,8 +1,8 @@ package xyz.webmc.originblacklist.base.command; public interface CommandContext { - String getPlayerName(); - void reply(final String message); - boolean hasPermission(final String permission); - String[] getArgs(); + public String getPlayerName(); + public void reply(final String message); + public boolean hasPermission(final String permission); + public String[] getArgs(); } diff --git a/src/main/java/xyz/webmc/originblacklist/base/command/ICommand.java b/src/main/java/xyz/webmc/originblacklist/base/command/ICommand.java index 5791ab7..87f4769 100644 --- a/src/main/java/xyz/webmc/originblacklist/base/command/ICommand.java +++ b/src/main/java/xyz/webmc/originblacklist/base/command/ICommand.java @@ -3,8 +3,8 @@ package xyz.webmc.originblacklist.base.command; import java.util.List; public interface ICommand { - static final String NO_PERMISSION = "You don't have permission to use this command."; - boolean execute(final CommandContext ctx); - List suggest(final CommandContext ctx); - void usage(final CommandContext ctx); + public static final String NO_PERMISSION = "You don't have permission to use this command."; + public boolean execute(final CommandContext ctx); + public List suggest(final CommandContext ctx); + public void usage(final CommandContext ctx); } diff --git a/src/main/java/xyz/webmc/originblacklist/base/config/OriginBlacklistConfig.java b/src/main/java/xyz/webmc/originblacklist/base/config/OriginBlacklistConfig.java index 53441ad..c99fe23 100644 --- a/src/main/java/xyz/webmc/originblacklist/base/config/OriginBlacklistConfig.java +++ b/src/main/java/xyz/webmc/originblacklist/base/config/OriginBlacklistConfig.java @@ -221,7 +221,7 @@ public final class OriginBlacklistConfig { final Json5Object uobj = new Json5Object(); addJSONObj(uobj, "enabled", Json5Primitive.fromBoolean(true), null); addJSONObj(uobj, "allow_snapshots", Json5Primitive.fromBoolean(false), null); - addJSONObj(uobj, "auto_update", Json5Primitive.fromBoolean(false), null); + addJSONObj(uobj, "auto_update", Json5Primitive.fromBoolean(true), null); addJSONObj(obj, "update_checker", uobj, null); addJSONObj(obj, "bStats", Json5Primitive.fromBoolean(true), null); return obj; diff --git a/src/main/java/xyz/webmc/originblacklist/base/util/IOriginBlacklistPlugin.java b/src/main/java/xyz/webmc/originblacklist/base/util/IOriginBlacklistPlugin.java index b94e6ae..1c2dfde 100644 --- a/src/main/java/xyz/webmc/originblacklist/base/util/IOriginBlacklistPlugin.java +++ b/src/main/java/xyz/webmc/originblacklist/base/util/IOriginBlacklistPlugin.java @@ -4,6 +4,7 @@ import xyz.webmc.originblacklist.base.enums.EnumLogLevel; import xyz.webmc.originblacklist.base.events.OriginBlacklistLoginEvent; import xyz.webmc.originblacklist.base.events.OriginBlacklistMOTDEvent; +import java.nio.file.Path; import java.util.concurrent.TimeUnit; import net.kyori.adventure.text.Component; @@ -12,6 +13,7 @@ import org.semver4j.Semver; public interface IOriginBlacklistPlugin { public String getPluginId(); public Semver getPluginVersion(); + public Path getPluginJarPath(); public void log(final EnumLogLevel level, final String txt); public void kickPlayer(final Component txt, final OriginBlacklistLoginEvent event); public void setMOTD(final Component txt, final OriginBlacklistMOTDEvent event); diff --git a/src/main/java/xyz/webmc/originblacklist/base/util/UpdateChecker.java b/src/main/java/xyz/webmc/originblacklist/base/util/UpdateChecker.java index 5fd3f8c..d19e52e 100644 --- a/src/main/java/xyz/webmc/originblacklist/base/util/UpdateChecker.java +++ b/src/main/java/xyz/webmc/originblacklist/base/util/UpdateChecker.java @@ -1,5 +1,7 @@ package xyz.webmc.originblacklist.base.util; +import xyz.webmc.originblacklist.base.OriginBlacklist; + import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; @@ -15,15 +17,16 @@ import org.semver4j.Semver.VersionDiff; public class UpdateChecker { private static final Json5 json5 = Json5.builder(builder -> builder.build()); - public static final boolean checkForUpdate(final String repo, final Semver currentVersion, final boolean allowPreRelease) { + public static final String checkForUpdate(final String repo, final Semver currentVersion, final boolean allowPreRelease) { try { - final URL url = new URL("https://api.github.com/repos/" + repo + "/releases"); - final HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + URL url = new URL("https://api.github.com/repos/" + repo + "/releases"); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); conn.connect(); - final BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); + BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); + String ret = null; Json5Element element = json5.parse(reader); if (element instanceof Json5Array) { final Json5Array arr = element.getAsJson5Array(); @@ -34,16 +37,38 @@ public class UpdateChecker { final String tag = obj.get("tag_name").getAsString(); final Semver ver = new Semver(tag.substring(1)); if (ver.isGreaterThan(currentVersion) && (allowPreRelease || currentVersion.diff(ver) != VersionDiff.BUILD)) { - return true; + element = obj.get("assets"); + if (element instanceof Json5Array) { + final Json5Array aArr = element.getAsJson5Array(); + element = aArr.get(0); + if (element instanceof Json5Object) { + final Json5Object vObj = element.getAsJson5Object(); + ret = vObj.get("url").getAsString(); + } + } } } } } conn.disconnect(); - return false; + if (OriginBlacklist.isNonNull(ret)) { + url = new URL(ret); + conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + conn.setConnectTimeout(5000); + conn.setReadTimeout(5000); + conn.connect(); + reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); + element = json5.parse(reader); + if (element instanceof Json5Object) { + final Json5Object obj = element.getAsJson5Object(); + ret = obj.get("browser_download_url").getAsString(); + } + } + return ret; } catch (final Throwable t) { t.printStackTrace(); - return false; + return null; } } } diff --git a/src/main/java/xyz/webmc/originblacklist/bukkit/OriginBlacklistBukkit.java b/src/main/java/xyz/webmc/originblacklist/bukkit/OriginBlacklistBukkit.java index 7922b2e..1f0706a 100644 --- a/src/main/java/xyz/webmc/originblacklist/bukkit/OriginBlacklistBukkit.java +++ b/src/main/java/xyz/webmc/originblacklist/bukkit/OriginBlacklistBukkit.java @@ -12,6 +12,8 @@ import xyz.webmc.originblacklist.bukkit.command.OriginBlacklistCommandBukkit; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Base64; import java.util.HashMap; import java.util.Map; @@ -127,6 +129,11 @@ public final class OriginBlacklistBukkit extends JavaPlugin implements Listener, return new Semver(this.getDescription().getVersion()); } + @Override + public final Path getPluginJarPath() { + return Paths.get(this.getFile().getAbsolutePath()); + } + @Override public final void log(final EnumLogLevel level, final String txt) { if (level == EnumLogLevel.WARN) { @@ -224,7 +231,7 @@ public final class OriginBlacklistBukkit extends JavaPlugin implements Listener, public final void scheduleRepeat(final Runnable task, final int period, final TimeUnit unit) { long ms = unit.toMillis((long) period); long ticks = Math.max(1L, ms / 50L); - Bukkit.getScheduler().runTaskTimer(this, task, ticks, ticks); + Bukkit.getScheduler().runTaskTimer(this, task, 0, ticks); } @Override diff --git a/src/main/java/xyz/webmc/originblacklist/bungee/OriginBlacklistBungee.java b/src/main/java/xyz/webmc/originblacklist/bungee/OriginBlacklistBungee.java index 3d6a713..8c4daa8 100644 --- a/src/main/java/xyz/webmc/originblacklist/bungee/OriginBlacklistBungee.java +++ b/src/main/java/xyz/webmc/originblacklist/bungee/OriginBlacklistBungee.java @@ -10,6 +10,8 @@ import xyz.webmc.originblacklist.base.util.IncompatibleDependencyException; import xyz.webmc.originblacklist.base.util.OPlayer; import xyz.webmc.originblacklist.bungee.command.OriginBlacklistCommandBungee; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -129,6 +131,11 @@ public final class OriginBlacklistBungee extends Plugin implements Listener, IOr return new Semver(this.getDescription().getVersion()); } + @Override + public final Path getPluginJarPath() { + return Paths.get(this.getFile().getAbsolutePath()); + } + @Override public final void log(final EnumLogLevel level, final String txt) { if (level == EnumLogLevel.WARN) { @@ -188,7 +195,7 @@ public final class OriginBlacklistBungee extends Plugin implements Listener, IOr @Override public final void scheduleRepeat(final Runnable task, final int period, final TimeUnit unit) { - this.proxy.getScheduler().schedule(this, task, period, period, unit); + this.proxy.getScheduler().schedule(this, task, 0, period, unit); } @Override diff --git a/src/main/java/xyz/webmc/originblacklist/velocity/OriginBlacklistVelocity.java b/src/main/java/xyz/webmc/originblacklist/velocity/OriginBlacklistVelocity.java index 641029a..61e25e4 100644 --- a/src/main/java/xyz/webmc/originblacklist/velocity/OriginBlacklistVelocity.java +++ b/src/main/java/xyz/webmc/originblacklist/velocity/OriginBlacklistVelocity.java @@ -10,6 +10,8 @@ import xyz.webmc.originblacklist.base.util.IncompatibleDependencyException; import xyz.webmc.originblacklist.base.util.OPlayer; import xyz.webmc.originblacklist.velocity.command.OriginBlacklistCommandVelocity; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -147,6 +149,15 @@ public final class OriginBlacklistVelocity implements IOriginBlacklistPlugin { return new Semver(this.plugin.getDescription().getVersion().get()); } + @Override + public final Path getPluginJarPath() { + try { + return Paths.get(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).toAbsolutePath(); + } catch (Throwable t) { + throw new RuntimeException("Unable to determine plugin JAR path"); + } + } + @Override public final void log(final EnumLogLevel level, final String txt) { if (level == EnumLogLevel.WARN) {