From 30d0a18dbdaba7046d377d75e82dfb1659d98b42 Mon Sep 17 00:00:00 2001
From: LT_Name <572413378@qq.com>
Date: Sun, 25 Dec 2022 15:52:08 +0800
Subject: [PATCH] =?UTF-8?q?=E5=B0=86GameCore=E4=B8=8B=E8=BD=BD=E6=95=B4?=
=?UTF-8?q?=E5=90=88=E5=88=B0GameCoreDownload=E5=B7=A5=E5=85=B7=E7=B1=BB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 1 +
src/main/java/com/smallaswater/npc/RsNPC.java | 38 +--
.../com/smallaswater/npc/utils/Download.java | 146 ----------
.../npc/utils/GameCoreDownload.java | 261 ++++++++++++++++++
.../com/smallaswater/npc/utils/Utils.java | 86 +-----
5 files changed, 269 insertions(+), 263 deletions(-)
delete mode 100644 src/main/java/com/smallaswater/npc/utils/Download.java
create mode 100644 src/main/java/com/smallaswater/npc/utils/GameCoreDownload.java
diff --git a/pom.xml b/pom.xml
index d884fd3..d10de93 100644
--- a/pom.xml
+++ b/pom.xml
@@ -141,6 +141,7 @@
${project.basedir}/src/main/resources/plugin.yml
${project.basedir}/src/main/java/com/smallaswater/npc/RsNPC.java
+ ${project.basedir}/src/main/java/com/smallaswater/npc/utils/GameCoreDownload.java
diff --git a/src/main/java/com/smallaswater/npc/RsNPC.java b/src/main/java/com/smallaswater/npc/RsNPC.java
index da65bbc..e4a086a 100644
--- a/src/main/java/com/smallaswater/npc/RsNPC.java
+++ b/src/main/java/com/smallaswater/npc/RsNPC.java
@@ -14,6 +14,7 @@
import com.smallaswater.npc.dialog.DialogManager;
import com.smallaswater.npc.entitys.EntityRsNPC;
import com.smallaswater.npc.tasks.CheckNpcEntityTask;
+import com.smallaswater.npc.utils.GameCoreDownload;
import com.smallaswater.npc.utils.MetricsLite;
import com.smallaswater.npc.utils.Utils;
import com.smallaswater.npc.utils.update.ConfigUpdateUtils;
@@ -59,13 +60,6 @@ public class RsNPC extends PluginBase {
private static final Skin DEFAULT_SKIN;
- public static final String MINIMUM_GAME_CORE_VERSION = "1.6.8";
-
- private static final String MAVEN_URL_CENTRAL = "https://repo1.maven.org/maven2/";
- private static final String MAVEN_URL_LANINK = "https://repo.lanink.cn/";
-
- private static final String GAME_CORE_URL = "cn/lanink/MemoriesOfTime-GameCore/" + MINIMUM_GAME_CORE_VERSION + "/MemoriesOfTime-GameCore-" + MINIMUM_GAME_CORE_VERSION + ".jar";
-
static {
Skin skin = new Skin();
skin.setTrusted(true);
@@ -82,8 +76,6 @@ public static RsNPC getInstance() {
public void onLoad() {
rsNPC = this;
- this.loadLanguage();
-
VariableManage.addVariable("%npcName%", (player, rsNpcConfig) -> rsNpcConfig.getName());
VariableManage.addVariable("@p", (player, rsNpcConfig) -> player.getName());
@@ -101,9 +93,7 @@ public void onLoad() {
@Override
public void onEnable() {
- this.getLogger().info(this.getLanguage().translateString("plugin.load.startLoad"));
-
- switch (Utils.checkAndDownloadDepend()) {
+ switch (GameCoreDownload.checkAndDownload()) {
case 1:
Server.getInstance().getPluginManager().disablePlugin(this);
return;
@@ -114,6 +104,10 @@ public void onEnable() {
break;
}
+ this.loadLanguage();
+
+ this.getLogger().info(this.getLanguage().translateString("plugin.load.startLoad"));
+
NukkitTypeUtils.NukkitType nukkitType = NukkitTypeUtils.getNukkitType();
if (nukkitType != NukkitTypeUtils.NukkitType.NUKKITX && nukkitType != NukkitTypeUtils.NukkitType.POWER_NUKKIT) {
this.getLogger().error("警告!您所使用的插件版本不支持此Nukkit分支!");
@@ -357,26 +351,6 @@ public Config getNpcConfigDescription() {
return this.npcConfigDescription;
}
- /**
- * @return 最低GameCore版本
- */
- public String getMinimumGameCoreVersion() {
- return MINIMUM_GAME_CORE_VERSION;
- }
-
- /**
- * @return GameCore下载链接
- */
- public String getGameCoreUrl(int i) {
- String maven;
- if (i > 0) {
- maven = MAVEN_URL_LANINK;
- }else {
- maven = MAVEN_URL_CENTRAL;
- }
- return maven + GAME_CORE_URL;
- }
-
public String getVersion() {
Config config = new Config(Config.PROPERTIES);
config.load(this.getResource("git.properties"));
diff --git a/src/main/java/com/smallaswater/npc/utils/Download.java b/src/main/java/com/smallaswater/npc/utils/Download.java
deleted file mode 100644
index 9e13df2..0000000
--- a/src/main/java/com/smallaswater/npc/utils/Download.java
+++ /dev/null
@@ -1,146 +0,0 @@
-package com.smallaswater.npc.utils;
-
-import lombok.NonNull;
-import lombok.SneakyThrows;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.RandomAccessFile;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.concurrent.ForkJoinPool;
-import java.util.concurrent.RecursiveAction;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-
-/**
- * @author iGxnon
- * 多线程下载
- */
-public class Download {
-
- private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36";
-
- // 每个任务下载 128 kb数据
- private static final int THRESHOLD = 128 * 1024;
-
-
- /**
- * 下载
- *
- * @param strUrl 目标url
- * @param saveFile 保存到文件
- * @param callback 下载完的回调
- */
- public static void download(String strUrl, File saveFile, BiConsumer callback) throws Exception {
- URL url = new URL(strUrl);
- HttpURLConnection connection = ((HttpURLConnection) url.openConnection());
- connection.setRequestMethod("GET");
- connection.setRequestProperty("Connection", "keep-alive");
- connection.setRequestProperty("Accept", "*/*");
- connection.setRequestProperty("User-Agent", USER_AGENT);
- connection.setReadTimeout(5000);
-
-
- long len = connection.getContentLength();
- if ("chunked".equals(connection.getHeaderField("Transfer-Encoding"))) { // chunked transfer 采用单线程下载
- RandomAccessFile out = new RandomAccessFile(saveFile, "rw");
- out.seek(0);
- byte[] b = new byte[1024];
- InputStream in = connection.getInputStream();
- int read;
- long count = 0;
- while ((read = in.read(b)) >= 0) {
- out.write(b, 0, read);
- count += read;
- if (callback != null) {
- callback.accept(count, len);
- }
- }
- in.close();
- out.close();
- return;
- }
- ForkJoinPool pool = new ForkJoinPool();
- AtomicLong atomicLong = new AtomicLong();
- pool.submit(new DownloadTask(strUrl,0, len, saveFile, (l) -> {
- atomicLong.addAndGet(l);
- callback.accept(atomicLong.get(), len);
- }));
- pool.shutdown();
- // 同步
- while (!pool.awaitTermination(1, TimeUnit.SECONDS)) {
- }
- if (len < 1 || saveFile.length() < 1) {
- throw new Exception("下载失败");
- }
- }
-
- static class DownloadTask extends RecursiveAction {
-
- private final String strUrl;
- private final File file;
- private final long start;
- private final long end;
-
- private final Consumer callback;
-
- public DownloadTask(@NonNull String strUrl, long start, long end, File file, Consumer callback) {
- this.strUrl = strUrl;
- this.start = start;
- this.end = end;
- this.file = file;
- this.callback = callback;
- }
-
- @SneakyThrows
- @Override
- protected void compute() {
- long l = end - start;
- if (l < THRESHOLD) {
- HttpURLConnection connection = getConnection();
- connection.setRequestProperty("Range", "bytes=" + start + "-" + end);
-
- RandomAccessFile out = new RandomAccessFile(file, "rw");
- out.seek(start);
- InputStream in = connection.getInputStream();
- byte[] b = new byte[1024];
- int len;
- while ((len = in.read(b)) >= 0) {
- out.write(b, 0, len);
- callback.accept(len);
- }
- in.close();
- out.close();
- }else {
- long mid = (start + end) / 2;
- new SubDownloadTask(strUrl, start, mid, file, callback).fork();
- new SubDownloadTask(strUrl, mid, end, file, callback).fork();
- }
- }
-
- public HttpURLConnection getConnection() throws IOException {
- HttpURLConnection connection = (HttpURLConnection) new URL(strUrl).openConnection();
- connection.setReadTimeout(5000);
- connection.setRequestMethod("GET");
- connection.setRequestProperty("Connection", "keep-alive");
- connection.setRequestProperty("Accept", "*/*");
- connection.setRequestProperty("User-Agent", USER_AGENT);
-
- return connection;
- }
- }
-
- static class SubDownloadTask extends DownloadTask {
-
- public SubDownloadTask(@NonNull String strUrl, long start, long end, File file, Consumer callback) {
- super(strUrl, start, end, file, callback);
- }
-
- }
-
-}
-
diff --git a/src/main/java/com/smallaswater/npc/utils/GameCoreDownload.java b/src/main/java/com/smallaswater/npc/utils/GameCoreDownload.java
new file mode 100644
index 0000000..17eb977
--- /dev/null
+++ b/src/main/java/com/smallaswater/npc/utils/GameCoreDownload.java
@@ -0,0 +1,261 @@
+package com.smallaswater.npc.utils;
+
+import cn.lanink.gamecore.utils.VersionUtils;
+import cn.nukkit.Server;
+import cn.nukkit.math.NukkitMath;
+import cn.nukkit.plugin.Plugin;
+import com.google.common.util.concurrent.AtomicDouble;
+import com.smallaswater.npc.RsNPC;
+import lombok.NonNull;
+import lombok.SneakyThrows;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLDecoder;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.RecursiveAction;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+/**
+ * 自动下载GameCore依赖工具类
+ */
+public class GameCoreDownload {
+
+ private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36";
+
+ // 每个任务下载 128 kb数据
+ private static final int THRESHOLD = 128 * 1024;
+
+ public static final String MINIMUM_GAME_CORE_VERSION = "1.6.8";
+
+ private static final String MAVEN_URL_CENTRAL = "https://repo1.maven.org/maven2/";
+ private static final String MAVEN_URL_LANINK = "https://repo.lanink.cn/";
+
+ private static final String GAME_CORE_URL_SUFFIX = "cn/lanink/MemoriesOfTime-GameCore/" + MINIMUM_GAME_CORE_VERSION + "/MemoriesOfTime-GameCore-" + MINIMUM_GAME_CORE_VERSION + ".jar";
+
+ private static final List GAME_CORE_URL_LIST;
+
+ static {
+ GAME_CORE_URL_LIST = Collections.unmodifiableList(Arrays.asList(
+ MAVEN_URL_CENTRAL + GAME_CORE_URL_SUFFIX,
+ MAVEN_URL_LANINK + GAME_CORE_URL_SUFFIX
+ ));
+ }
+
+ private GameCoreDownload() {
+ throw new RuntimeException("error");
+ }
+
+ /**
+ * 检查并下载GameCore依赖
+ *
+ * @return 0 - GameCore已加载且是最新版本 1 - 无法下载GameCore 2 下载成功
+ */
+ public static int checkAndDownload() {
+ return checkAndDownload(0);
+ }
+
+ /**
+ * 检查并下载GameCore依赖
+ *
+ * @param retry 重试次数(下载链接序号)
+ * @return 0 - GameCore已加载且是最新版本 1 - 无法下载GameCore 2 下载成功
+ */
+ private static int checkAndDownload(int retry) {
+ if (retry >= GAME_CORE_URL_LIST.size()) {
+ return 1;
+ }
+ String url = GAME_CORE_URL_LIST.get(retry);
+ if (retry > 0) {
+ RsNPC.getInstance().getLogger().info("尝试从 " + url + " 下载 GameCore");
+ }
+ Plugin plugin = Server.getInstance().getPluginManager().getPlugin("MemoriesOfTime-GameCore");
+
+ if (plugin != null) {
+ if (!VersionUtils.checkMinimumVersion(plugin, MINIMUM_GAME_CORE_VERSION)) {
+ RsNPC.getInstance().getLogger().warning("MemoriesOfTime-GameCore依赖版本太低!正在尝试更新版本...");
+ File file = getPluginFile(plugin);
+ if (file != null) {
+ Server.getInstance().getPluginManager().disablePlugin(plugin);
+ ClassLoader classLoader = plugin.getClass().getClassLoader();
+ try {
+ if (classLoader instanceof URLClassLoader) {
+ ((URLClassLoader) classLoader).close();
+ }
+ } catch (IOException ignored) {
+
+ }
+ if (file != null) {
+ file.delete();
+ }
+ }else {
+ RsNPC.getInstance().getLogger().error("删除旧版本失败!请手动删除!");
+ }
+ }
+ }
+
+ if (plugin == null || plugin.isDisabled()) {
+ RsNPC.getInstance().getLogger().info("下载MemoriesOfTime-GameCore依赖中...");
+
+ File file = new File(Server.getInstance().getFilePath() + "/plugins/MemoriesOfTime-GameCore-" + MINIMUM_GAME_CORE_VERSION + ".jar");
+
+ try {
+ AtomicDouble last = new AtomicDouble(-10);
+ download(url, file, (l, len) -> {
+ double d = NukkitMath.round(l * 1.0 / len * 100, 2);
+ if (d - last.get() > 10) { // 每10%提示一次
+ RsNPC.getInstance().getLogger().info("已下载:" + d + "%");
+ last.set(d);
+ }
+ });
+ } catch (Exception e) {
+ RsNPC.getInstance().getLogger().error("MemoriesOfTime-GameCore依赖下载失败!");
+ return checkAndDownload(++retry);
+ }
+
+ RsNPC.getInstance().getLogger().info("MemoriesOfTime-GameCore依赖下载成功!");
+ Server.getInstance().getPluginManager().loadPlugin(file);
+ return 2;
+ }
+ return 0;
+ }
+
+ public static File getPluginFile(Plugin plugin) {
+ File file = null;
+ ClassLoader PluginClass = plugin.getClass().getClassLoader();
+ try {
+ if (PluginClass instanceof URLClassLoader) {
+ URLClassLoader pluginClass = (URLClassLoader) PluginClass;
+ URL url = pluginClass.getURLs()[0];
+ file = new File(URLDecoder.decode(url.getFile(), "UTF-8"));
+ }
+ } catch (UnsupportedEncodingException ignored) {
+
+ }
+ return file;
+ }
+
+ /**
+ * 下载
+ *
+ * @param strUrl 目标url
+ * @param saveFile 保存到文件
+ * @param callback 下载完的回调
+ */
+ private static void download(String strUrl, File saveFile, BiConsumer callback) throws Exception {
+ URL url = new URL(strUrl);
+ HttpURLConnection connection = ((HttpURLConnection) url.openConnection());
+ connection.setRequestMethod("GET");
+ connection.setRequestProperty("Connection", "keep-alive");
+ connection.setRequestProperty("Accept", "*/*");
+ connection.setRequestProperty("User-Agent", USER_AGENT);
+ connection.setReadTimeout(5000);
+
+
+ long len = connection.getContentLength();
+ if ("chunked".equals(connection.getHeaderField("Transfer-Encoding"))) { // chunked transfer 采用单线程下载
+ RandomAccessFile out = new RandomAccessFile(saveFile, "rw");
+ out.seek(0);
+ byte[] b = new byte[1024];
+ InputStream in = connection.getInputStream();
+ int read;
+ long count = 0;
+ while ((read = in.read(b)) >= 0) {
+ out.write(b, 0, read);
+ count += read;
+ if (callback != null) {
+ callback.accept(count, len);
+ }
+ }
+ in.close();
+ out.close();
+ return;
+ }
+ ForkJoinPool pool = new ForkJoinPool();
+ AtomicLong atomicLong = new AtomicLong();
+ pool.submit(new DownloadTask(strUrl,0, len, saveFile, (l) -> {
+ atomicLong.addAndGet(l);
+ callback.accept(atomicLong.get(), len);
+ }));
+ pool.shutdown();
+ // 同步
+ while (!pool.awaitTermination(1, TimeUnit.SECONDS)) {
+ }
+ if (len < 1 || saveFile.length() < 1) {
+ throw new Exception("下载失败");
+ }
+ }
+
+ private static class DownloadTask extends RecursiveAction {
+
+ private final String strUrl;
+ private final File file;
+ private final long start;
+ private final long end;
+
+ private final Consumer callback;
+
+ public DownloadTask(@NonNull String strUrl, long start, long end, File file, Consumer callback) {
+ this.strUrl = strUrl;
+ this.start = start;
+ this.end = end;
+ this.file = file;
+ this.callback = callback;
+ }
+
+ @SneakyThrows
+ @Override
+ protected void compute() {
+ long l = end - start;
+ if (l < THRESHOLD) {
+ HttpURLConnection connection = getConnection();
+ connection.setRequestProperty("Range", "bytes=" + start + "-" + end);
+
+ RandomAccessFile out = new RandomAccessFile(file, "rw");
+ out.seek(start);
+ InputStream in = connection.getInputStream();
+ byte[] b = new byte[1024];
+ int len;
+ while ((len = in.read(b)) >= 0) {
+ out.write(b, 0, len);
+ callback.accept(len);
+ }
+ in.close();
+ out.close();
+ }else {
+ long mid = (start + end) / 2;
+ new SubDownloadTask(strUrl, start, mid, file, callback).fork();
+ new SubDownloadTask(strUrl, mid, end, file, callback).fork();
+ }
+ }
+
+ public HttpURLConnection getConnection() throws IOException {
+ HttpURLConnection connection = (HttpURLConnection) new URL(strUrl).openConnection();
+ connection.setReadTimeout(5000);
+ connection.setRequestMethod("GET");
+ connection.setRequestProperty("Connection", "keep-alive");
+ connection.setRequestProperty("Accept", "*/*");
+ connection.setRequestProperty("User-Agent", USER_AGENT);
+
+ return connection;
+ }
+ }
+
+ private static class SubDownloadTask extends DownloadTask {
+
+ public SubDownloadTask(@NonNull String strUrl, long start, long end, File file, Consumer callback) {
+ super(strUrl, start, end, file, callback);
+ }
+
+ }
+
+}
+
diff --git a/src/main/java/com/smallaswater/npc/utils/Utils.java b/src/main/java/com/smallaswater/npc/utils/Utils.java
index 8f877a1..679f8fe 100644
--- a/src/main/java/com/smallaswater/npc/utils/Utils.java
+++ b/src/main/java/com/smallaswater/npc/utils/Utils.java
@@ -1,13 +1,10 @@
package com.smallaswater.npc.utils;
-import cn.lanink.gamecore.utils.VersionUtils;
import cn.nukkit.Player;
import cn.nukkit.Server;
import cn.nukkit.item.Item;
import cn.nukkit.level.Location;
-import cn.nukkit.math.NukkitMath;
import cn.nukkit.plugin.Plugin;
-import com.google.common.util.concurrent.AtomicDouble;
import com.smallaswater.npc.RsNPC;
import com.smallaswater.npc.data.RsNpcConfig;
import com.smallaswater.npc.tasks.PlayerPermissionCheckTask;
@@ -16,11 +13,7 @@
import java.io.File;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.net.URLDecoder;
import java.util.List;
public class Utils {
@@ -131,84 +124,7 @@ public static double getYaw(@NotNull Location location) {
}
public static File getPluginFile(Plugin plugin) {
- File file = null;
- ClassLoader PluginClass = plugin.getClass().getClassLoader();
- try {
- if (PluginClass instanceof URLClassLoader) {
- URLClassLoader pluginClass = (URLClassLoader) PluginClass;
- URL url = pluginClass.getURLs()[0];
- file = new File(URLDecoder.decode(url.getFile(), "UTF-8"));
- }
- } catch (UnsupportedEncodingException ignored) {
-
- }
- return file;
- }
-
- public static int checkAndDownloadDepend() {
- return checkAndDownloadDepend(0);
- }
-
- public static int checkAndDownloadDepend(int retry) {
- if (retry > 0) {
- RsNPC.getInstance().getLogger().info("尝试更换下载链接为 " + RsNPC.getInstance().getGameCoreUrl(retry));
- }
- String version = RsNPC.getInstance().getMinimumGameCoreVersion();
- Plugin plugin = Server.getInstance().getPluginManager().getPlugin("MemoriesOfTime-GameCore");
-
- if (plugin != null) {
- if (!VersionUtils.checkMinimumVersion(plugin, version)) {
- RsNPC.getInstance().getLogger().warning("MemoriesOfTime-GameCore依赖版本太低!正在尝试更新版本...");
- File file = getPluginFile(plugin);
- Server.getInstance().getPluginManager().disablePlugin(plugin);
- ClassLoader classLoader = plugin.getClass().getClassLoader();
- try {
- if (classLoader instanceof URLClassLoader) {
- ((URLClassLoader) classLoader).close();
- }
- } catch (IOException ignored) {
-
- }
- if (file != null) {
- file.delete();
- }
- }
- }
-
- if (plugin == null || plugin.isDisabled()) {
- RsNPC.getInstance().getLogger().info("下载MemoriesOfTime-GameCore依赖中...");
-
- String gamecore = Server.getInstance().getFilePath() + "/plugins/MemoriesOfTime-GameCore-" + version + ".jar";
-
- try {
- AtomicDouble last = new AtomicDouble(-10);
- Download.download(RsNPC.getInstance().getGameCoreUrl(retry), new File(gamecore), (l, len) -> {
- double d = NukkitMath.round(l * 1.0 / len * 100, 2);
- if (d - last.get() > 10) {
- RsNPC.getInstance().getLogger().info("已下载:" + d + "%");
- last.set(d);
- }
- });
- /*FileOutputStream fos = new FileOutputStream(gamecore);
- URL url = new URL(RsNPC.getInstance().getGameCoreUrl());
- fos.getChannel().transferFrom(Channels.newChannel(url.openStream()), 0, Long.MAX_VALUE);
- fos.close();*/
- } catch (Exception e) {
- RsNPC.getInstance().getLogger().error(RsNPC.getInstance().getGameCoreUrl(retry) + " 下载失败!");
- if (retry >= 1) {
- RsNPC.getInstance().getLogger().error("无法下载MemoriesOfTime-GameCore依赖!", e);
- RsNPC.getInstance().getLogger().error("请尝试手动下载依赖!");
- RsNPC.getInstance().getLogger().error(RsNPC.getInstance().getGameCoreUrl(retry));
- return 1;
- }
- return checkAndDownloadDepend(++retry);
- }
-
- RsNPC.getInstance().getLogger().info("MemoriesOfTime-GameCore依赖下载成功!");
- Server.getInstance().getPluginManager().loadPlugin(gamecore);
- return 2;
- }
- return 0;
+ return GameCoreDownload.getPluginFile(plugin);
}
}