1
mirror of https://github.com/CarmJos/EasyPlugin.git synced 2026-06-05 00:58:17 +08:00

Compare commits

...

12 Commits

40 changed files with 1651 additions and 1186 deletions
+1 -1
View File
@@ -14,6 +14,7 @@ assignees: ''
### **问题来源**
描述一下通过哪些操作才发现的问题,如:
1. 使用了 ...
2. 输入了 ...
3. 出现了报错 ...
@@ -32,7 +33,6 @@ assignees: ''
- Java版本: `JDK11` / `OPENJDK8` / `JRE8` / `...`
- 服务端版本: 请在后台输入 `version` 并复制相关输出。
### **其他补充**
如有其他补充,可以在这里描述。
+4
View File
@@ -8,13 +8,17 @@ assignees: ''
---
### **功能简述**
简单的描述一下你想要的功能
### **需求来源**
简单的描述一下为什么需要这个功能。
### **功能参考**(可选)
如果有相关功能的参考,如文本、截图,请提供给我们。
### **附加内容**
如果有什么小细节需要重点注意,请在这里告诉我们。
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.4.6</version>
<version>1.4.10</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -1,4 +1,3 @@
package cc.carm.lib.easyplugin.command;
import org.bukkit.command.Command;
@@ -39,7 +38,9 @@ public abstract class CommandHandler implements TabExecutor, NamedExecutor {
public abstract void noArgs(CommandSender sender);
public abstract void unknownCommand(CommandSender sender, String[] args);
public void unknownCommand(CommandSender sender, String[] args) {
noArgs(sender);
}
public abstract void noPermission(CommandSender sender);
@@ -1,15 +1,18 @@
package cc.carm.lib.easyplugin.command;
import com.google.common.collect.ImmutableList;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.HumanEntity;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@@ -17,14 +20,22 @@ import java.util.stream.Stream;
public class SimpleCompleter {
public static @NotNull List<String> objects(@NotNull String input, List<?> objects) {
public static @NotNull List<String> none() {
return ImmutableList.of();
}
public static @NotNull List<String> objects(@NotNull String input, Collection<?> objects) {
return objects(input, objects.size(), objects);
}
public static @NotNull List<String> objects(@NotNull String input, int limit, List<?> objects) {
public static @NotNull List<String> objects(@NotNull String input, int limit, Collection<?> objects) {
return objects(input, limit, objects.stream());
}
public static @NotNull List<String> objects(@NotNull String input, Stream<?> stream) {
return objects(input, 20, stream);
}
public static @NotNull List<String> objects(@NotNull String input, int limit, Stream<?> stream) {
return stream.filter(Objects::nonNull).map(Object::toString)
.filter(s -> StringUtil.startsWithIgnoreCase(s, input))
@@ -39,11 +50,11 @@ public class SimpleCompleter {
return text(input, limit, Arrays.asList(texts));
}
public static @NotNull List<String> text(@NotNull String input, List<String> texts) {
public static @NotNull List<String> text(@NotNull String input, Collection<String> texts) {
return text(input, texts.size(), texts);
}
public static @NotNull List<String> text(@NotNull String input, int limit, List<String> texts) {
public static @NotNull List<String> text(@NotNull String input, int limit, Collection<String> texts) {
return objects(input, limit, texts);
}
@@ -87,4 +98,13 @@ public class SimpleCompleter {
return objects(input, limit, Arrays.stream(PotionEffectType.values()).map(PotionEffectType::getName));
}
public static @NotNull List<String> enchantments(@NotNull String input) {
return effects(input, 10);
}
@SuppressWarnings("deprecation")
public static @NotNull List<String> enchantments(@NotNull String input, int limit) {
return objects(input, limit, Arrays.stream(Enchantment.values()).map(Enchantment::getName));
}
}
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.4.6</version>
<version>1.4.10</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -156,7 +156,9 @@ public class GUI {
}
public void openGUI(Player player) {
if (this.type == GUIType.CANCEL) { throw new IllegalStateException("被取消或不存在的GUI"); }
if (this.type == GUIType.CANCEL) {
throw new IllegalStateException("被取消或不存在的GUI");
}
Inventory inv = Bukkit.createInventory(null, this.type.getSize(), this.name);
IntStream.range(0, inv.getSize()).forEach(index -> inv.setItem(index, new ItemStack(Material.AIR)));
@@ -3,18 +3,39 @@ package cc.carm.lib.easyplugin.gui.configuration;
import cc.carm.lib.easyplugin.gui.GUIItem;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class GUIActionConfiguration {
public static @NotNull GUIActionConfiguration of(@NotNull GUIActionType actionType,
@Nullable ClickType clickType,
@Nullable String actionContent) {
return new GUIActionConfiguration(actionType, clickType, actionContent);
}
@Nullable ClickType clickType;
final @NotNull GUIActionType actionType;
final @Nullable String actionContent;
public static @NotNull GUIActionConfiguration of(@NotNull GUIActionType actionType,
@Nullable String actionContent) {
return of(actionType, null, actionContent);
}
public GUIActionConfiguration(@Nullable ClickType clickType,
@NotNull GUIActionType actionType,
public static @NotNull GUIActionConfiguration of(@NotNull GUIActionType actionType,
@Nullable ClickType clickType) {
return of(actionType, clickType, null);
}
public static @NotNull GUIActionConfiguration of(@NotNull GUIActionType actionType) {
return of(actionType, null, null);
}
protected final @NotNull GUIActionType actionType;
protected final @Nullable ClickType clickType;
protected final @Nullable String actionContent;
public GUIActionConfiguration(@NotNull GUIActionType actionType,
@Nullable ClickType clickType,
@Nullable String actionContent) {
this.clickType = clickType;
this.actionType = actionType;
@@ -50,4 +71,36 @@ public class GUIActionConfiguration {
};
}
@Nullable
@Contract("null->null")
public static GUIActionConfiguration deserialize(@Nullable String actionString) {
if (actionString == null) return null;
int prefixStart = actionString.indexOf("[");
int prefixEnd = actionString.indexOf("]");
if (prefixStart < 0 || prefixEnd < 0) return null;
String prefix = actionString.substring(prefixStart + 1, prefixEnd);
ClickType clickType = null;
GUIActionType actionType;
if (prefix.contains(":")) {
String[] args = prefix.split(":");
clickType = GUIConfiguration.readClickType(args[0]);
actionType = GUIActionType.readActionType(args[1]);
} else {
actionType = GUIActionType.readActionType(prefix);
}
if (actionType == null) return null;
String content = actionString.substring(prefixEnd + 1).trim();
return of(actionType, clickType, content);
}
public @NotNull String serialize() {
String prefix = "[" + getActionType().name() + (getClickType() == null ? "" : ":" + getClickType().name()) + "]";
String content = getActionContent() == null ? "" : " " + getActionContent();
return prefix + content;
}
}
@@ -7,30 +7,29 @@ import cc.carm.lib.easyplugin.utils.MessageUtils;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;
public class GUIItemConfiguration {
Material material;
@NotNull Material type;
int amount;
int data;
String name;
@Nullable String name;
@NotNull List<String> lore;
@NotNull List<Integer> slots;
@NotNull List<GUIActionConfiguration> actions;
public GUIItemConfiguration(Material material, int data,
String name, @NotNull List<String> lore,
public GUIItemConfiguration(@NotNull Material type, int amount, int data,
@Nullable String name, @NotNull List<String> lore,
@NotNull List<GUIActionConfiguration> actions,
@NotNull List<Integer> slots) {
this.material = material;
this.type = type;
this.amount = amount;
this.data = data;
this.name = name;
this.lore = lore;
@@ -39,8 +38,7 @@ public class GUIItemConfiguration {
}
public void setupItems(Player player, GUI gui) {
ItemStackFactory icon = new ItemStackFactory(this.material);
icon.setDurability(this.data);
ItemStackFactory icon = new ItemStackFactory(this.type, this.amount, this.data);
if (this.name != null) icon.setDisplayName(this.name);
icon.setLore(MessageUtils.setPlaceholders(player, this.lore));
@@ -49,11 +47,32 @@ public class GUIItemConfiguration {
this.slots.forEach(slot -> gui.setItem(slot, item));
}
public @NotNull Map<String, Object> serialize() {
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
map.put("type", this.type.name());
if (this.name != null) map.put("name", this.name);
if (this.amount != 1) map.put("amount", this.amount);
if (this.data != 0) map.put("data", this.data);
if (!this.lore.isEmpty()) map.put("lore", this.lore);
if (this.slots.size() > 1) {
map.put("slots", this.slots);
} else if (slots.size() == 1) {
map.put("slot", this.slots.get(0));
}
if (!this.actions.isEmpty()) {
map.put("actions", this.actions.stream().map(GUIActionConfiguration::serialize).collect(Collectors.toList()));
}
return map;
}
@Nullable
public static GUIItemConfiguration readFrom(@Nullable ConfigurationSection itemSection) {
if (itemSection == null) return null;
Material material = Optional.ofNullable(Material.matchMaterial(itemSection.getString("material", "STONE"))).orElse(Material.STONE);
String material = Optional.ofNullable(itemSection.getString("type")).orElse("STONE");
Material type = Optional.ofNullable(Material.matchMaterial(material)).orElse(Material.STONE);
int data = itemSection.getInt("data", 0);
int amount = itemSection.getInt("amount", 1);
String name = itemSection.getString("name");
List<String> lore = itemSection.getStringList("lore");
@@ -63,30 +82,15 @@ public class GUIItemConfiguration {
List<String> actionsString = itemSection.getStringList("actions");
List<GUIActionConfiguration> actions = new ArrayList<>();
for (String actionString : actionsString) {
int prefixStart = actionString.indexOf("[");
int prefixEnd = actionString.indexOf("]");
if (prefixStart < 0 || prefixEnd < 0) continue;
String prefix = actionString.substring(prefixStart + 1, prefixEnd);
ClickType clickType = null;
GUIActionType actionType;
if (prefix.contains(":")) {
String[] args = prefix.split(":");
clickType = GUIConfiguration.readClickType(args[0]);
actionType = GUIActionType.readActionType(args[1]);
} else {
actionType = GUIActionType.readActionType(prefix);
}
if (actionType == null) continue;
actions.add(new GUIActionConfiguration(clickType, actionType, actionString.substring(prefixEnd + 1).trim()));
GUIActionConfiguration action = GUIActionConfiguration.deserialize(actionString);
if (action == null) continue;
actions.add(action);
}
return new GUIItemConfiguration(
material, data, name, lore, actions,
type, amount, data, name, lore, actions,
slots.size() > 0 ? slots : Collections.singletonList(slot)
);
}
}
@@ -1,4 +1,3 @@
import cc.carm.lib.easyplugin.gui.configuration.GUIActionType;
import cc.carm.lib.easyplugin.gui.configuration.GUIConfiguration;
import org.bukkit.event.inventory.ClickType;
+1 -2
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.4.6</version>
<version>1.4.10</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -56,7 +56,6 @@
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.10.9</version>
<scope>provided</scope>
</dependency>
@@ -9,10 +9,13 @@ import org.bukkit.command.PluginCommand;
import org.bukkit.command.TabCompleter;
import org.bukkit.event.Event;
import org.bukkit.event.Listener;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPluginLoader;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
@@ -22,18 +25,28 @@ import java.util.concurrent.CompletableFuture;
public abstract class EasyPlugin extends JavaPlugin {
protected EasyPluginMessageProvider messageProvider;
protected @NotNull EasyPluginMessageProvider messageProvider;
public EasyPlugin() {
this(EasyPluginMessageProvider.ZH_CN);
}
public EasyPlugin(EasyPluginMessageProvider messageProvider) {
public EasyPlugin(@NotNull EasyPluginMessageProvider messageProvider) {
this.messageProvider = messageProvider;
}
private SchedulerUtils scheduler;
private boolean initialized = false;
protected EasyPlugin(JavaPluginLoader loader, PluginDescriptionFile descriptionFile, File dataFolder, File file) {
this(EasyPluginMessageProvider.ZH_CN, loader, descriptionFile, dataFolder, file);
}
protected EasyPlugin(@NotNull EasyPluginMessageProvider messageProvider,
JavaPluginLoader loader, PluginDescriptionFile descriptionFile, File dataFolder, File file) {
super(loader, descriptionFile, dataFolder, file);
this.messageProvider = messageProvider;
}
protected SchedulerUtils scheduler;
protected boolean initialized = false;
@Override
public final void onLoad() {
@@ -66,7 +79,7 @@ public abstract class EasyPlugin extends JavaPlugin {
@Override
public final void onDisable() {
if (!hasOverride("shutdown") || !isInitialized()) return;
if (!hasOverride("shutdown") || !this.initialized) return;
outputInfo();
log(messageProvider.disabling(this));
@@ -90,10 +103,6 @@ public abstract class EasyPlugin extends JavaPlugin {
Optional.ofNullable(JarResourceUtils.readResource(this.getResource("PLUGIN_INFO"))).ifPresent(this::log);
}
public boolean isInitialized() {
return initialized;
}
public boolean isDebugging() {
return false;
}
@@ -136,15 +145,16 @@ public abstract class EasyPlugin extends JavaPlugin {
if (isDebugging()) print("&8[DEBUG] &r", messages);
}
public void callEventSync(Event event) {
getScheduler().run(() -> Bukkit.getPluginManager().callEvent(event));
public @NotNull <T extends Event> CompletableFuture<T> callSync(T event) {
CompletableFuture<T> future = new CompletableFuture<>();
getScheduler().run(() -> {
Bukkit.getPluginManager().callEvent(event);
future.complete(event);
});
return future;
}
public void callEventAsync(Event event) {
getScheduler().runAsync(() -> Bukkit.getPluginManager().callEvent(event));
}
public @NotNull <T extends Event> CompletableFuture<T> callEventFuture(T event) {
public @NotNull <T extends Event> CompletableFuture<T> callAsync(T event) {
return CompletableFuture.supplyAsync(() -> {
Bukkit.getPluginManager().callEvent(event);
return event;
@@ -8,7 +8,7 @@ import java.util.stream.Collectors;
public class ColorParser {
public static final Pattern HEX_PATTERN = Pattern.compile("&\\(&?#([0-9a-fA-F]{6})\\)");
public static final Pattern HEX_PATTERN = Pattern.compile("&\\(&?#([\\da-fA-F]{6})\\)");
public static String parse(String text) {
return parseBaseColor(parseHexColor(text));
+27
View File
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.4.10</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>${project.jdk.version}</maven.compiler.source>
<maven.compiler.target>${project.jdk.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<artifactId>easyplugin-storage</artifactId>
<packaging>jar</packaging>
<name>EasyPlugin-Storage</name>
<description>轻松插件存储接口模块,包含存储相关的统一接口。</description>
<url>https://github.com/CarmJos/EasyPlugin</url>
</project>
@@ -0,0 +1,40 @@
package cc.carm.lib.easyplugin.storage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface DataStorage<K, T> {
/**
* 在插件加载存储源时执行。
*
* @throws Exception 当出现任何错误时抛出
*/
void initialize() throws Exception;
/**
* 在插件被卸载时执行。
*/
void shutdown();
/**
* 用于加载数据的方法。<b>该方法应当异步运行!</b>
* <br>
* <br>若不存在对应数据,请返回 null 。
* <br>若加载出现任何错误,请抛出异常。
*
* @param key 数据主键
* @throws Exception 当出现任何错误时抛出
*/
@Nullable
T loadData(@NotNull K key) throws Exception;
/**
* 用于保存数据的方法。 <b>该方法应当被异步运行!</b>
*
* @param data 数据
* @throws Exception 当出现任何错误时抛出
*/
void saveData(@NotNull T data) throws Exception;
}
@@ -0,0 +1,19 @@
package cc.carm.lib.easyplugin.storage;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public interface StorageType<K, T, S extends DataStorage<K, T>> {
int getID();
@NotNull List<String> getAlias();
@NotNull Class<? extends S> getStorageClass();
default @NotNull S createStorage() throws Exception {
return getStorageClass().newInstance();
}
}
@@ -0,0 +1,31 @@
package cc.carm.lib.easyplugin.storage.file;
import cc.carm.lib.easyplugin.storage.DataStorage;
import org.jetbrains.annotations.NotNull;
import java.io.File;
public abstract class FileBasedStorage<K, T> implements DataStorage<K, T> {
protected final String fileName;
protected File dataFile;
public FileBasedStorage(String fileName) {
this.fileName = fileName;
}
protected @NotNull File initializeFile(@NotNull File parentFolder) throws Exception {
this.dataFile = new File(parentFolder, fileName);
if (!dataFile.exists()) {
if (!dataFile.createNewFile()) throw new Exception("无法创建数据文件!");
} else if (dataFile.isDirectory()) {
throw new Exception("文件路径对应的不是一个文件!");
}
return dataFile;
}
public File getDataFile() {
return dataFile;
}
}
@@ -0,0 +1,46 @@
package cc.carm.lib.easyplugin.storage.file;
import cc.carm.lib.easyplugin.storage.DataStorage;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public abstract class FolderBasedStorage<K, T> implements DataStorage<K, T> {
protected final @NotNull String folderPath;
protected File dataFolder;
public FolderBasedStorage(@NotNull String folderPath) {
this.folderPath = folderPath;
}
protected @NotNull File initializeFolder(@NotNull File parentFolder) throws Exception {
this.dataFolder = new File(parentFolder, folderPath);
if (!dataFolder.exists()) {
if (!dataFolder.mkdir()) {
throw new Exception("无法创建数据文件夹!");
}
} else if (!dataFolder.isDirectory()) {
throw new Exception("数据文件夹路径对应的不是一个文件夹!");
}
return dataFolder;
}
protected @NotNull List<File> listFiles() {
if (this.dataFolder == null) return Collections.emptyList();
if (!this.dataFolder.isDirectory()) return Collections.emptyList();
File[] files = this.dataFolder.listFiles();
if (files == null) return Collections.emptyList();
return Arrays.asList(files);
}
public File getDataFolder() {
return dataFolder;
}
}
@@ -0,0 +1,24 @@
package cc.carm.lib.easyplugin.storage.file;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.File;
public abstract class YAMLBasedStorage<K, T> extends FileBasedStorage<K, T> {
protected FileConfiguration configuration;
public YAMLBasedStorage(String fileName) {
super(fileName);
}
protected @NotNull FileConfiguration initializeConfiguration(@NotNull File parentFolder) throws Exception {
return this.configuration = YamlConfiguration.loadConfiguration(initializeFile(parentFolder));
}
public FileConfiguration getConfiguration() {
return configuration;
}
}
@@ -0,0 +1,31 @@
package cc.carm.lib.easyplugin.storage.plugin;
import cc.carm.lib.easyplugin.storage.DataStorage;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
public abstract class PluginBasedStorage<K, T> implements DataStorage<K, T> {
protected Plugin dependPlugin;
public PluginBasedStorage(String dependPluginName) {
this(Bukkit.getPluginManager().getPlugin(dependPluginName));
}
public PluginBasedStorage(Plugin dependPlugin) {
this.dependPlugin = dependPlugin;
}
@Override
public void initialize() throws NullPointerException {
if (dependPlugin == null) {
throw new NullPointerException("该存储类型依赖的插件不存在,请检查配置文件");
}
}
public Plugin getDependPlugin() {
return dependPlugin;
}
}
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.4.6</version>
<version>1.4.10</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.4.6</version>
<version>1.4.10</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.4.6</version>
<version>1.4.10</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+34
View File
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.4.10</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>${project.jdk.version}</maven.compiler.source>
<maven.compiler.target>${project.jdk.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<artifactId>easyplugin-githubchecker</artifactId>
<packaging>jar</packaging>
<name>EasyPlugin-GithubChecker</name>
<dependencies>
<dependency>
<groupId>cc.carm.lib</groupId>
<artifactId>githubreleases4j</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,84 @@
package cc.carm.lib.easyplugin.updatechecker;
import cc.carm.lib.githubreleases4j.GithubReleases4J;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class GHUpdateChecker {
protected static final @NotNull Pattern GH_URL_PATTERN = Pattern.compile("^https?://github.com/([A-Za-z\\d-_]+)/([^/]*?)/?");
public static @NotNull GHUpdateChecker of(@NotNull Logger logger, @NotNull String owner, @NotNull String repo) {
return new GHUpdateChecker(logger, owner, repo);
}
public static @NotNull GHUpdateChecker of(@NotNull Plugin plugin) {
return new GHUpdateChecker(plugin.getLogger(), getGithubOwner(plugin), plugin.getName());
}
public static @NotNull Runnable runner(@NotNull Logger logger,
@NotNull String owner, @NotNull String repo,
@NotNull String currentVersion) {
return of(logger, owner, repo).runner(currentVersion);
}
public static @NotNull Runnable runner(@NotNull Plugin plugin) {
return of(plugin).runner(plugin.getDescription().getVersion());
}
protected final @NotNull Logger logger;
protected final @NotNull String owner;
protected final @NotNull String repo;
public GHUpdateChecker(@NotNull Logger logger, @NotNull String owner, @NotNull String repo) {
this.logger = logger;
this.owner = owner;
this.repo = repo;
}
public void checkUpdate(@NotNull String currentVersion) {
Integer behindVersions = GithubReleases4J.getVersionBehind(owner, repo, currentVersion);
String downloadURL = GithubReleases4J.getReleasesURL(owner, repo);
if (behindVersions == null) {
this.logger.severe("检查更新失败,请您定期查看插件是否更新,避免安全问题。");
this.logger.severe("下载地址 " + downloadURL);
} else if (behindVersions == 0) {
this.logger.info("检查完成,当前已是最新版本。");
} else if (behindVersions > 0) {
this.logger.info("发现新版本! 目前已落后 " + behindVersions + " 个版本。");
this.logger.info("最新版下载地址 " + downloadURL);
} else {
this.logger.severe("检查更新失败! 当前版本未知,请您使用原生版本以避免安全问题。");
this.logger.severe("最新版下载地址 " + downloadURL);
}
}
public Runnable runner(@NotNull String currentVersion) {
return () -> checkUpdate(currentVersion);
}
protected static String getGithubOwner(Plugin plugin) {
// 首先,尝试从插件提供的网址中获取OWNER
String websiteOwner = getGithubOwner(plugin.getDescription().getWebsite());
if (websiteOwner != null && !websiteOwner.isEmpty()) return websiteOwner;
// 如果插件提供的网址中没有,则尝试获取插件的首位作者名
List<String> authors = plugin.getDescription().getAuthors();
if (!authors.isEmpty()) return authors.get(0);
// 再没有的话只能返回插件的名称了
return plugin.getName();
}
protected static String getGithubOwner(String url) {
Matcher matcher = GH_URL_PATTERN.matcher(url);
return matcher.find() ? matcher.group(1) : null;
}
}
@@ -0,0 +1,16 @@
package cc.carm.lib.easyplugin.updatechecker;
import org.junit.Test;
public class RegexTest {
@Test
public void onTest() {
System.out.println(GHUpdateChecker.getGithubOwner("https://github.com/CarmJos/EasyPlugin"));
System.out.println(GHUpdateChecker.getGithubOwner("https://github.com/Ghost-chu/QuickShop-Hikari/pulls"));
System.out.println(GHUpdateChecker.getGithubOwner("https://github.com/QWQ123/QuickShop"));
}
}
+1 -2
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.4.6</version>
<version>1.4.10</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -27,7 +27,6 @@
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.10.9</version>
<scope>provided</scope>
</dependency>
+2 -2
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.4.6</version>
<version>1.4.10</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -24,10 +24,10 @@
<dependencies>
<!--suppress VulnerableLibrariesLocal -->
<dependency>
<groupId>com.github.MilkBowl</groupId>
<artifactId>VaultAPI</artifactId>
<version>1.7</version>
<scope>provided</scope>
</dependency>
+23 -1
View File
@@ -15,7 +15,7 @@
<groupId>cc.carm.lib</groupId>
<artifactId>easyplugin-parent</artifactId>
<packaging>pom</packaging>
<version>1.4.6</version>
<version>1.4.10</version>
<modules>
<module>base/main</module>
@@ -24,10 +24,12 @@
<module>extension/papi</module>
<module>extension/vault</module>
<module>extension/gh-checker</module>
<module>collection/all</module>
<module>collection/bom</module>
<module>collection/common</module>
<module>base/storage</module>
</modules>
@@ -122,6 +124,26 @@
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.10.9</version>
</dependency>
<dependency>
<groupId>com.github.MilkBowl</groupId>
<artifactId>VaultAPI</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>cc.carm.lib</groupId>
<artifactId>githubreleases4j</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>