From 127a91c46ff499821390103c2894798dd7640f11 Mon Sep 17 00:00:00 2001 From: zhangyuheng Date: Sun, 7 Apr 2024 15:35:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=89=88=E6=9C=AC=E6=A3=80?= =?UTF-8?q?=E6=9F=A5=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 +- pom.xml | 2 +- .../liteworldedit/GiteaReleaseCheck.java | 195 ++++++++++++++++++ .../lunadeer/liteworldedit/LiteWorldEdit.java | 7 + .../liteworldedit/Managers/ConfigManager.java | 7 + src/main/resources/config.yml | 2 + 6 files changed, 219 insertions(+), 4 deletions(-) create mode 100644 src/main/java/cn/lunadeer/liteworldedit/GiteaReleaseCheck.java diff --git a/README.md b/README.md index f747cc6..4554002 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ ### [开源地址](https://ssl.lunadeer.cn:14446/zhangyuheng/LiteWorldEdit) | [文档地址](https://ssl.lunadeer.cn:14448/doc/3/) +### [下载页面](https://ssl.lunadeer.cn:14446/zhangyuheng/LiteWorldEdit/releases) +### [统计页面](https://bstats.org/plugin/bukkit/LiteWorldEdit/21436) | [Hangar](https://hangar.papermc.io/zhangyuheng/LiteWorldEdit) @@ -33,9 +35,9 @@ 4. 支持填充操作,填充操作需要消耗玩家物品栏中的物品; 5. 支持自动从背包中的盒子里提取物品; 6. 禁止超视距操作(128以外),防止玩家利用创世神插件加载大量区块导致服务器卡顿; -6. 支持自动从背包里的潜影盒补充材料; -7. 支持设置是否产生掉落物; -8. 支持设置速度倍率(整数,默认1表示每tick操作一个方块,设置为2则每次操作两个方块) +7. 支持自动从背包里的潜影盒补充材料; +8. 支持设置是否产生掉落物; +9. 支持设置速度倍率(整数,默认1表示每tick操作一个方块,设置为2则每次操作两个方块) ## 支持版本 @@ -118,6 +120,8 @@ DropItems: false Multiplier: 1 +CheckUpdate: true + Debug: false ``` diff --git a/pom.xml b/pom.xml index f142ef5..73fb29b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ cn.lunadeer LiteWorldEdit - 2.4.1.10 + 2.4.2.0 jar LiteWorldEdit diff --git a/src/main/java/cn/lunadeer/liteworldedit/GiteaReleaseCheck.java b/src/main/java/cn/lunadeer/liteworldedit/GiteaReleaseCheck.java new file mode 100644 index 0000000..7c0a769 --- /dev/null +++ b/src/main/java/cn/lunadeer/liteworldedit/GiteaReleaseCheck.java @@ -0,0 +1,195 @@ +package cn.lunadeer.liteworldedit; + +import org.bukkit.plugin.java.JavaPlugin; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; + +import javax.net.ssl.HttpsURLConnection; +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.File; +import java.io.InputStreamReader; +import java.net.URL; +import java.nio.file.Files; +import java.util.concurrent.TimeUnit; + +public class GiteaReleaseCheck { + private static class GiteaRelease { + public String tag_name; + public String message; + public String html_url; + public String download_url; + } + + public GiteaReleaseCheck(JavaPlugin plugin, String giteaServer, String owner, String repo) { + this.gitea_server = giteaServer; + this.owner = owner; + this.repo = repo; + this.plugin = plugin; + this.current_version = plugin.getPluginMeta().getVersion(); + // 异步每12小时检查一次更新 + plugin.getServer().getAsyncScheduler().runAtFixedRate(plugin, (instance) -> { + getLatestRelease(); + if (auto_update) { + downloadUpdate(); + } + }, 10, 60 * 60 * 12, TimeUnit.SECONDS); + } + + public void enableAutoUpdate() { + auto_update = true; + } + + private String repoReleases() { + return gitea_server + "/api/v1/repos/" + owner + "/" + repo + "/releases"; + } + + private String tag(String tagName) { + return gitea_server + "/api/v1/repos/" + owner + "/" + repo + "/tags/" + tagName; + } + + private void getLatestRelease() { + LoggerX.info("================================"); + LoggerX.info("正在检查更新..."); + // send get request to repoReleases() + try { + // 发送 GET 请求 + HttpsURLConnection connection = (HttpsURLConnection) new URL(repoReleases()).openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + connection.connect(); + // 获取响应 + StringBuilder builder = new StringBuilder(); + try (BufferedReader bufferedReader = + new BufferedReader(new InputStreamReader(connection.getInputStream()))) { + String line; + while ((line = bufferedReader.readLine()) != null) { + builder.append(line); + } + } + JSONArray releaseList = (JSONArray) new JSONParser().parse(builder.toString()); + JSONObject latestRelease = (JSONObject) releaseList.get(0); + GiteaRelease release = new GiteaRelease(); + release.tag_name = (String) latestRelease.get("tag_name"); + release.message = getTagMessage(release.tag_name); + release.html_url = (String) latestRelease.get("html_url"); + JSONArray assets = (JSONArray) latestRelease.get("assets"); + if (assets.size() > 0) { + JSONObject asset = (JSONObject) assets.get(0); + release.download_url = (String) asset.get("browser_download_url"); + } + latest_release = release; + LoggerX.debug("Latest release: " + latest_release.tag_name); + LoggerX.debug("Message: " + latest_release.message); + LoggerX.debug("Download URL: " + latest_release.download_url); + LoggerX.debug("HTML URL: " + latest_release.html_url); + if (isNewVersion(current_version, latest_release.tag_name)) { + LoggerX.info("发现新版本:" + latest_release.tag_name); + LoggerX.info("更新内容:" + latest_release.message); + LoggerX.info("下载页面:" + latest_release.html_url); + } else { + LoggerX.info("当前已是最新版本:" + current_version); + } + LoggerX.info("================================"); + } catch (Exception e) { + LoggerX.err("Failed to get latest release: " + e.getMessage()); + } + } + + private String getTagMessage(String tagName) { + try { + // 发送 GET 请求 + HttpsURLConnection connection = (HttpsURLConnection) new URL(tag(tagName)).openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + connection.connect(); + // 获取响应 + StringBuilder builder = new StringBuilder(); + try (BufferedReader bufferedReader = + new BufferedReader(new InputStreamReader(connection.getInputStream()))) { + String line; + while ((line = bufferedReader.readLine()) != null) { + builder.append(line); + } + } + JSONObject tag = (JSONObject) new JSONParser().parse(builder.toString()); + return (String) tag.get("message"); + } catch (Exception e) { + LoggerX.debug("Failed to get tag message: " + e.getMessage()); + return "null"; + } + } + + private void downloadUpdate() { + if (latest_release == null) { + getLatestRelease(); + if (latest_release == null) + return; + } + if (!isNewVersion(current_version, latest_release.tag_name)) { + LoggerX.info("当前已是最新版本"); + return; + } + if (latest_release.download_url == null) { + LoggerX.err("下载地址不可用"); + return; + } + try { + LoggerX.info("================================"); + LoggerX.info("正在下载更新..."); + File pluginsFolder = plugin.getDataFolder().getParentFile(); + File newJarFile = new File(pluginsFolder, latest_release.download_url.substring(latest_release.download_url.lastIndexOf("/") + 1)); + // send get request to download_url + HttpsURLConnection connection = (HttpsURLConnection) new URL(latest_release.download_url).openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + connection.connect(); + // 获取响应写入文件到 newJarFile + try (DataOutputStream outputStream = new DataOutputStream(Files.newOutputStream(newJarFile.toPath()))) { + byte[] buffer = new byte[1024]; + int length; + while ((length = connection.getInputStream().read(buffer)) != -1) { + outputStream.write(buffer, 0, length); + } + } + LoggerX.info("更新下载完成"); + LoggerX.info("新版本:" + latest_release.tag_name); + LoggerX.info("请删除旧版本插件,然后重启服务器。"); + LoggerX.info("================================"); + } catch (Exception e) { + LoggerX.err("Failed to auto update: " + e.getMessage()); + } + } + + private String gitea_server; + private String owner; + private String repo; + private JavaPlugin plugin; + private String current_version; + private GiteaRelease latest_release = null; + private boolean auto_update = false; + + private boolean isNewVersion(String current, String in_coming) { + // 只保留数字和点号 + current = current.replaceAll("[^0-9.]", ""); + in_coming = in_coming.replaceAll("[^0-9.]", ""); + LoggerX.debug("Current version: " + current); + LoggerX.debug("In-coming version: " + in_coming); + String[] current_version = current.split("\\."); + String[] in_coming_version = in_coming.split("\\."); + for (int i = 0; i < Math.min(current_version.length, in_coming_version.length); i++) { + int current_v = Integer.parseInt(current_version[i]); + int in_coming_v = Integer.parseInt(in_coming_version[i]); + if (current_v < in_coming_v) { + return true; + } else if (current_v > in_coming_v) { + return false; + } + } + return current_version.length < in_coming_version.length; + } +} diff --git a/src/main/java/cn/lunadeer/liteworldedit/LiteWorldEdit.java b/src/main/java/cn/lunadeer/liteworldedit/LiteWorldEdit.java index e85a5de..2a0f0e4 100644 --- a/src/main/java/cn/lunadeer/liteworldedit/LiteWorldEdit.java +++ b/src/main/java/cn/lunadeer/liteworldedit/LiteWorldEdit.java @@ -21,6 +21,12 @@ public final class LiteWorldEdit extends JavaPlugin { Objects.requireNonNull(Bukkit.getPluginCommand("LiteWorldEdit")).setTabCompleter(new Commands()); Metrics metrics = new Metrics(this, 21436); + if (config.isCheckUpdate()) { + giteaReleaseCheck = new GiteaReleaseCheck(this, + "https://ssl.lunadeer.cn:14446", + "zhangyuheng", + "LiteWorldEdit"); + } LoggerX.info("LiteWorldEdit 已加载"); LoggerX.info("版本: " + getPluginMeta().getVersion()); @@ -52,4 +58,5 @@ public final class LiteWorldEdit extends JavaPlugin { public static LiteWorldEdit instance; public static ConfigManager config; private Cache _cache; + private GiteaReleaseCheck giteaReleaseCheck; } diff --git a/src/main/java/cn/lunadeer/liteworldedit/Managers/ConfigManager.java b/src/main/java/cn/lunadeer/liteworldedit/Managers/ConfigManager.java index 72a9c8b..23ef600 100644 --- a/src/main/java/cn/lunadeer/liteworldedit/Managers/ConfigManager.java +++ b/src/main/java/cn/lunadeer/liteworldedit/Managers/ConfigManager.java @@ -18,6 +18,7 @@ public class ConfigManager { _z_max = _file.getInt("MaxZ", 64); _multiplier = _file.getInt("Multiplier", 1); _drop_items = _file.getBoolean("DropItems", false); + _check_update = _file.getBoolean("CheckUpdate", true); _plugin.saveConfig(); } @@ -68,6 +69,10 @@ public class ConfigManager { _plugin.saveConfig(); } + public Boolean isCheckUpdate() { + return _check_update; + } + private final LiteWorldEdit _plugin = LiteWorldEdit.instance; private FileConfiguration _file; @@ -81,4 +86,6 @@ public class ConfigManager { private Boolean _drop_items; private Integer _multiplier; + + private Boolean _check_update; } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 4fd863d..a0c61dd 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -8,4 +8,6 @@ Multiplier: 1 DropItems: false +CheckUpdate: true + Debug: false \ No newline at end of file