Compare commits
29 Commits
be756b0a56
...
master
Author | SHA1 | Date | |
---|---|---|---|
0b8614fec9 | |||
b9be8e4b0b | |||
594bdf15b6 | |||
d16602a06d | |||
ad216ef89b | |||
68747f76bb | |||
1c83615b7e | |||
1648a56453 | |||
0f942a7687 | |||
942239be91 | |||
b393ab96ea | |||
cb736bbbf1 | |||
c30e468635 | |||
571dd34bbd | |||
a4638be898 | |||
e03ad98272 | |||
fbd6608864 | |||
85e9130575 | |||
b17ad022d3 | |||
85ce774752 | |||
05b83dd248 | |||
3955f352c6 | |||
00d582a5ea | |||
6beabf4ec4 | |||
608a6ef289 | |||
a75853187c | |||
2263a74a77 | |||
865812c524 | |||
02836c9086 |
28
.gitea/workflows/main.yaml
Normal file
28
.gitea/workflows/main.yaml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
name: Publish Project
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "*"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
java-version: 21
|
||||||
|
distribution: temurin
|
||||||
|
cache: gradle
|
||||||
|
- name: Build Project
|
||||||
|
env:
|
||||||
|
ORG_GRADLE_PROJECT_MAVEN_AIRGAME_USERNAME: ${{ secrets.MAVEN_AIRGAME_USERNAME }}
|
||||||
|
ORG_GRADLE_PROJECT_MAVEN_AIRGAME_PASSWORD: ${{ secrets.MAVEN_AIRGAME_PASSWORD }}
|
||||||
|
run: chmod +x gradlew && ./gradlew build publish --console plain --no-daemon
|
||||||
|
- name: Publish to Release
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
files: build/*.jar
|
18
README.md
18
README.md
@@ -9,8 +9,6 @@
|
|||||||
3. 命令行窗口中执行`./gradlew clean build`
|
3. 命令行窗口中执行`./gradlew clean build`
|
||||||
4. 构建成品在 `build` 文件夹
|
4. 构建成品在 `build` 文件夹
|
||||||
|
|
||||||
也可访问我的[Jenkins网站](https://jenkins.airgame.net/job/opensource/job/hamster-core/)获取最新版
|
|
||||||
|
|
||||||
# 开发
|
# 开发
|
||||||
|
|
||||||
## 添加依赖
|
## 添加依赖
|
||||||
@@ -26,9 +24,9 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// 对于 Bukkit 插件
|
// 对于 Bukkit 插件
|
||||||
compileOnly("cn.hamster3.mc.plugin:core-bukkit:1.3.4-SNAPSHOT")
|
compileOnly("cn.hamster3.mc.plugin:core-bukkit:1.4.2")
|
||||||
// 对于 BungeeCord 插件
|
// 对于 BungeeCord 插件
|
||||||
compileOnly("cn.hamster3.mc.plugin:core-bungee:1.3.4-SNAPSHOT")
|
compileOnly("cn.hamster3.mc.plugin:core-bungee:1.4.2")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -54,13 +52,13 @@ dependencies {
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.hamster3.mc.plugin</groupId>
|
<groupId>cn.hamster3.mc.plugin</groupId>
|
||||||
<artifactId>core-bukkit</artifactId>
|
<artifactId>core-bukkit</artifactId>
|
||||||
<version>1.3.4-SNAPSHOT</version>
|
<version>1.4.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--对于 BungeeCord 插件-->
|
<!--对于 BungeeCord 插件-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.hamster3.mc.plugin</groupId>
|
<groupId>cn.hamster3.mc.plugin</groupId>
|
||||||
<artifactId>core-bungee</artifactId>
|
<artifactId>core-bungee</artifactId>
|
||||||
<version>1.3.4-SNAPSHOT</version>
|
<version>1.4.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@@ -74,10 +72,4 @@ dependencies {
|
|||||||
- 使用方法为:`CoreAPI.getInstance().xxx()`
|
- 使用方法为:`CoreAPI.getInstance().xxx()`
|
||||||
- 部分通用的工具代码在 `cn.hamster3.mc.plugin.core.common.util` 包中
|
- 部分通用的工具代码在 `cn.hamster3.mc.plugin.core.common.util` 包中
|
||||||
- 部分Bukkit的工具代码在 `cn.hamster3.mc.plugin.core.bukkit.util` 包中
|
- 部分Bukkit的工具代码在 `cn.hamster3.mc.plugin.core.bukkit.util` 包中
|
||||||
- 部分BungeeCord的工具代码在 `cn.hamster3.mc.plugin.core.bungee.util` 包中
|
- 部分BungeeCord的工具代码在 `cn.hamster3.mc.plugin.core.bungee.util` 包中
|
||||||
|
|
||||||
# 已知问题
|
|
||||||
|
|
||||||
部分 Windows 服务器在启动时偶尔会遇到 Redis 链接失败的问题
|
|
||||||
如果服务器启动时遇到报错 `Caused by: java.io.IOException: Unable to establish loopback connection`
|
|
||||||
可以通过在启动脚本中添加 `-Djava.net.preferIPv4Stack=true` 参数解决
|
|
@@ -1,18 +1,18 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("java-library")
|
id("java-library")
|
||||||
id("maven-publish")
|
id("maven-publish")
|
||||||
id("com.github.johnrengelman.shadow") version "8+"
|
id("com.gradleup.shadow") version "8.3.6"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "cn.hamster3.mc.plugin"
|
group = "cn.hamster3.mc.plugin"
|
||||||
version = "1.3.4-SNAPSHOT"
|
version = "1.4.2"
|
||||||
description = "叁只仓鼠的 Minecraft 插件开发通用工具包"
|
description = "叁只仓鼠的 Minecraft 插件开发通用工具包"
|
||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
apply {
|
apply {
|
||||||
plugin("java-library")
|
plugin("java-library")
|
||||||
plugin("maven-publish")
|
plugin("maven-publish")
|
||||||
plugin("com.github.johnrengelman.shadow")
|
plugin("com.gradleup.shadow")
|
||||||
}
|
}
|
||||||
|
|
||||||
group = rootProject.group
|
group = rootProject.group
|
||||||
@@ -38,6 +38,11 @@ subprojects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
processResources {
|
||||||
|
filesMatching("update.yml") {
|
||||||
|
expand(rootProject.properties)
|
||||||
|
}
|
||||||
|
}
|
||||||
withType<JavaCompile> {
|
withType<JavaCompile> {
|
||||||
options.encoding = "UTF-8"
|
options.encoding = "UTF-8"
|
||||||
}
|
}
|
||||||
@@ -45,11 +50,6 @@ subprojects {
|
|||||||
from(rootProject.file("LICENSE"))
|
from(rootProject.file("LICENSE"))
|
||||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
}
|
}
|
||||||
processResources {
|
|
||||||
filesMatching("update.yml") {
|
|
||||||
expand(rootProject.properties)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
build {
|
build {
|
||||||
dependsOn(shadowJar)
|
dependsOn(shadowJar)
|
||||||
}
|
}
|
||||||
@@ -64,10 +64,9 @@ subprojects {
|
|||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
url = uri("https://maven.airgame.net/public")
|
url = uri("https://maven.airgame.net/public")
|
||||||
|
|
||||||
credentials {
|
credentials {
|
||||||
username = rootProject.properties.getOrDefault("maven_username", "").toString()
|
username = findProperty("MAVEN_AIRGAME_USERNAME")?.toString() ?: ""
|
||||||
password = rootProject.properties.getOrDefault("maven_password", "").toString()
|
password = findProperty("MAVEN_AIRGAME_PASSWORD")?.toString() ?: ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,9 @@
|
|||||||
@file:Suppress("VulnerableLibrariesLocal")
|
@file:Suppress("VulnerableLibrariesLocal")
|
||||||
|
|
||||||
evaluationDependsOn(":core-common")
|
evaluationDependsOn(":core-common")
|
||||||
|
evaluationDependsOn(":core-relocate-lettuce")
|
||||||
|
|
||||||
|
val shade = configurations.create("shade")
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(project(":core-common")) { isTransitive = false }
|
api(project(":core-common")) { isTransitive = false }
|
||||||
@@ -10,32 +13,31 @@ dependencies {
|
|||||||
compileOnly("org.black_ixx:playerpoints:3.2.6") { isTransitive = false }
|
compileOnly("org.black_ixx:playerpoints:3.2.6") { isTransitive = false }
|
||||||
compileOnly("me.clip:placeholderapi:2.11.5") { isTransitive = false }
|
compileOnly("me.clip:placeholderapi:2.11.5") { isTransitive = false }
|
||||||
|
|
||||||
|
// https://www.spigotmc.org/resources/nbt-api.7939/
|
||||||
|
implementation("de.tr7zw:item-nbt-api:2.15.1")
|
||||||
|
|
||||||
api("net.kyori:adventure-platform-bukkit:4.3.2") {
|
api("net.kyori:adventure-platform-bukkit:4.3.2") {
|
||||||
exclude(group = "org.jetbrains")
|
exclude(group = "org.jetbrains")
|
||||||
exclude(group = "com.google.code.gson")
|
exclude(group = "com.google.code.gson")
|
||||||
|
exclude(group = "io.netty")
|
||||||
}
|
}
|
||||||
api("net.kyori:adventure-text-minimessage:4.15.0") {
|
api("net.kyori:adventure-text-minimessage:4.15.0") {
|
||||||
exclude(module = "adventure-api")
|
exclude(module = "adventure-api")
|
||||||
exclude(group = "org.jetbrains")
|
exclude(group = "org.jetbrains")
|
||||||
|
exclude(group = "io.netty")
|
||||||
}
|
}
|
||||||
// https://mvnrepository.com/artifact/redis.clients/jedis
|
|
||||||
api("redis.clients:jedis:5.1.2") {
|
implementation("com.zaxxer:HikariCP:4.0.3") { exclude(group = "org.slf4j") }
|
||||||
|
api("redis.clients:jedis:5.1.4") {
|
||||||
exclude(group = "com.google.code.gson")
|
exclude(group = "com.google.code.gson")
|
||||||
exclude(group = "org.slf4j")
|
exclude(group = "org.slf4j")
|
||||||
}
|
}
|
||||||
// https://mvnrepository.com/artifact/org.quartz-scheduler/quartz
|
compileOnlyApi("io.lettuce:lettuce-core:6.7.1.RELEASE") {
|
||||||
api("org.quartz-scheduler:quartz:2.3.2") { isTransitive = false }
|
exclude(group = "org.slf4j")
|
||||||
// https://mvnrepository.com/artifact/com.sun.mail/jakarta.mail
|
exclude(group = "io.netty")
|
||||||
api("com.sun.mail:jakarta.mail:2.0.1")
|
}
|
||||||
|
shade(project(":core-relocate-lettuce"))
|
||||||
// https://www.spigotmc.org/resources/nbt-api.7939/
|
|
||||||
implementation("de.tr7zw:item-nbt-api:+")
|
|
||||||
// https://mvnrepository.com/artifact/com.zaxxer/HikariCP
|
|
||||||
implementation("com.zaxxer:HikariCP:4.0.3") { exclude(group = "org.slf4j") }
|
|
||||||
// https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-stdlib-jdk8
|
|
||||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.23") { exclude(group = "org.jetbrains") }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
processResources {
|
processResources {
|
||||||
filesMatching("plugin.yml") {
|
filesMatching("plugin.yml") {
|
||||||
@@ -46,6 +48,9 @@ tasks {
|
|||||||
archiveBaseName = "HamsterCore-Bukkit"
|
archiveBaseName = "HamsterCore-Bukkit"
|
||||||
}
|
}
|
||||||
shadowJar {
|
shadowJar {
|
||||||
|
dependsOn(":core-relocate-lettuce:shadowJar")
|
||||||
|
val task = project(":core-relocate-lettuce").tasks.shadowJar.get()
|
||||||
|
from(task.outputs.files.map { if (it.isDirectory) it else zipTree(it) })
|
||||||
destinationDirectory = rootProject.layout.buildDirectory
|
destinationDirectory = rootProject.layout.buildDirectory
|
||||||
relocate("de.tr7zw.changeme.nbtapi", "cn.hamster3.mc.plugin.core.lib.de.tr7zw.nbtapi")
|
relocate("de.tr7zw.changeme.nbtapi", "cn.hamster3.mc.plugin.core.lib.de.tr7zw.nbtapi")
|
||||||
relocate("de.tr7zw.annotations", "cn.hamster3.mc.plugin.core.lib.de.tr7zw.nbtapi.annotations")
|
relocate("de.tr7zw.annotations", "cn.hamster3.mc.plugin.core.lib.de.tr7zw.nbtapi.annotations")
|
||||||
|
@@ -18,6 +18,7 @@ import cn.hamster3.mc.plugin.core.common.config.ConfigSection;
|
|||||||
import cn.hamster3.mc.plugin.core.common.config.YamlConfig;
|
import cn.hamster3.mc.plugin.core.common.config.YamlConfig;
|
||||||
import cn.hamster3.mc.plugin.core.common.util.UpdateCheckUtils;
|
import cn.hamster3.mc.plugin.core.common.util.UpdateCheckUtils;
|
||||||
import com.zaxxer.hikari.HikariDataSource;
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
|
import de.tr7zw.changeme.nbtapi.NBT;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@@ -35,7 +36,6 @@ import java.io.InputStreamReader;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
public class HamsterCorePlugin extends JavaPlugin {
|
public class HamsterCorePlugin extends JavaPlugin {
|
||||||
@Getter
|
@Getter
|
||||||
@@ -91,7 +91,7 @@ public class HamsterCorePlugin extends JavaPlugin {
|
|||||||
CoreBukkitAPI.init(configFile);
|
CoreBukkitAPI.init(configFile);
|
||||||
simpleLogger.info("已初始化 CoreAPI");
|
simpleLogger.info("已初始化 CoreAPI");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
simpleLogger.log(Level.WARNING, "初始化 CoreAPI 出错", e);
|
simpleLogger.error(e, "初始化 CoreAPI 出错");
|
||||||
}
|
}
|
||||||
CoreMessage.init(this);
|
CoreMessage.init(this);
|
||||||
simpleLogger.info("已初始化语言文本");
|
simpleLogger.info("已初始化语言文本");
|
||||||
@@ -103,6 +103,7 @@ public class HamsterCorePlugin extends JavaPlugin {
|
|||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
simpleLogger.info("仓鼠核心正在启动");
|
simpleLogger.info("仓鼠核心正在启动");
|
||||||
|
NBT.preloadApi();
|
||||||
audienceProvider = BukkitAudiences.create(this);
|
audienceProvider = BukkitAudiences.create(this);
|
||||||
simpleLogger.info("已创建 AudienceProvider");
|
simpleLogger.info("已创建 AudienceProvider");
|
||||||
CoreCommand.INSTANCE.register();
|
CoreCommand.INSTANCE.register();
|
||||||
@@ -114,6 +115,9 @@ public class HamsterCorePlugin extends JavaPlugin {
|
|||||||
simpleLogger.info("已注册 CallbackListener");
|
simpleLogger.info("已注册 CallbackListener");
|
||||||
Bukkit.getPluginManager().registerEvents(DebugListener.INSTANCE, this);
|
Bukkit.getPluginManager().registerEvents(DebugListener.INSTANCE, this);
|
||||||
simpleLogger.info("已注册 DebugListener");
|
simpleLogger.info("已注册 DebugListener");
|
||||||
|
simpleLogger.info("Redis 启用状态: %b", CoreAPI.getInstance().isEnableRedis());
|
||||||
|
simpleLogger.info("Database 启用状态: %b", CoreAPI.getInstance().isEnableDatabase());
|
||||||
|
simpleLogger.info("已注册 DebugListener");
|
||||||
long time = System.currentTimeMillis() - start;
|
long time = System.currentTimeMillis() - start;
|
||||||
sync(() -> {
|
sync(() -> {
|
||||||
PointAPI.reloadPlayerPointAPIHook();
|
PointAPI.reloadPlayerPointAPIHook();
|
||||||
@@ -126,8 +130,11 @@ public class HamsterCorePlugin extends JavaPlugin {
|
|||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
audienceProvider.close();
|
||||||
|
simpleLogger.info("已关闭 AudienceProvider.");
|
||||||
if (CoreAPI.getInstance().isEnableRedis()) {
|
if (CoreAPI.getInstance().isEnableRedis()) {
|
||||||
CoreAPI.getInstance().getJedisPool().close();
|
CoreAPI.getInstance().getJedisPool().close();
|
||||||
|
CoreAPI.getInstance().getRedisClient().close();
|
||||||
simpleLogger.info("已关闭 Redis 连接池");
|
simpleLogger.info("已关闭 Redis 连接池");
|
||||||
}
|
}
|
||||||
if (CoreAPI.getInstance().isEnableDatabase()) {
|
if (CoreAPI.getInstance().isEnableDatabase()) {
|
||||||
|
@@ -11,6 +11,10 @@ public abstract class ChildCommand implements TabExecutor {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public abstract String getUsage();
|
public abstract String getUsage();
|
||||||
|
|
||||||
|
public int getArgumentCount() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public abstract String getDescription();
|
public abstract String getDescription();
|
||||||
|
|
||||||
|
@@ -14,10 +14,10 @@ import java.util.stream.Collectors;
|
|||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public abstract class ParentCommand extends ChildCommand {
|
public abstract class ParentCommand extends ChildCommand {
|
||||||
@NotNull
|
@NotNull
|
||||||
private final List<ChildCommand> childCommands;
|
private final Map<String, ChildCommand> childCommands;
|
||||||
|
|
||||||
public ParentCommand() {
|
public ParentCommand() {
|
||||||
childCommands = new ArrayList<>();
|
childCommands = new LinkedHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -33,8 +33,8 @@ public abstract class ParentCommand extends ChildCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public List<ChildCommand> getChildCommands() {
|
public Collection<ChildCommand> getChildCommands() {
|
||||||
return childCommands;
|
return childCommands.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -78,7 +78,7 @@ public abstract class ParentCommand extends ChildCommand {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public List<ChildCommand> getEndChildCommands() {
|
public List<ChildCommand> getEndChildCommands() {
|
||||||
ArrayList<ChildCommand> list = new ArrayList<>();
|
ArrayList<ChildCommand> list = new ArrayList<>();
|
||||||
for (ChildCommand command : childCommands) {
|
for (ChildCommand command : getChildCommands()) {
|
||||||
if (command instanceof ParentCommand) {
|
if (command instanceof ParentCommand) {
|
||||||
list.addAll(((ParentCommand) command).getEndChildCommands());
|
list.addAll(((ParentCommand) command).getEndChildCommands());
|
||||||
} else {
|
} else {
|
||||||
@@ -89,13 +89,16 @@ public abstract class ParentCommand extends ChildCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addChildCommand(@NotNull ChildCommand command) {
|
public void addChildCommand(@NotNull ChildCommand command) {
|
||||||
childCommands.add(command);
|
if (childCommands.containsKey(command.getName())) {
|
||||||
|
throw new IllegalArgumentException("command " + command.getName() + " already exists!");
|
||||||
|
}
|
||||||
|
childCommands.put(command.getName(), command);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Map<String, String> getCommandHelp(CommandSender sender) {
|
public Map<String, String> getCommandHelp(CommandSender sender) {
|
||||||
HashMap<String, String> map = new HashMap<>();
|
Map<String, String> map = new LinkedHashMap<>();
|
||||||
for (ChildCommand child : childCommands) {
|
for (ChildCommand child : getChildCommands()) {
|
||||||
if (!child.hasPermission(sender)) {
|
if (!child.hasPermission(sender)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -110,17 +113,13 @@ public abstract class ParentCommand extends ChildCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void sendHelp(@NotNull CommandSender sender) {
|
public void sendHelp(@NotNull CommandSender sender) {
|
||||||
sender.sendMessage("§e==================== [ " + getName() + " 使用帮助] ====================");
|
sender.sendMessage("§2§l<<< 命令 [" + getUsage() + "] 帮助 >>>");
|
||||||
Map<String, String> helpMap = getCommandHelp(sender);
|
Map<String, String> map = getCommandHelp(sender);
|
||||||
int maxLength = helpMap.keySet().stream()
|
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||||
.map(String::length)
|
sender.sendMessage(" §3" + entry.getKey());
|
||||||
.max(Integer::compareTo)
|
sender.sendMessage(" §7" + entry.getValue());
|
||||||
.orElse(-1);
|
|
||||||
ArrayList<Map.Entry<String, String>> list = new ArrayList<>(helpMap.entrySet());
|
|
||||||
list.sort(Map.Entry.comparingByKey());
|
|
||||||
for (Map.Entry<String, String> entry : list) {
|
|
||||||
sender.sendMessage(String.format("§a%-" + maxLength + "s - %s", entry.getKey(), entry.getValue()));
|
|
||||||
}
|
}
|
||||||
|
sender.sendMessage("§2§l<<< 由插件 " + getPlugin().getName() + "-" + getPlugin().getDescription().getVersion() + " 提供 >>>");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -133,7 +132,7 @@ public abstract class ParentCommand extends ChildCommand {
|
|||||||
sendHelp(sender);
|
sendHelp(sender);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for (ChildCommand childCommand : childCommands) {
|
for (ChildCommand childCommand : getChildCommands()) {
|
||||||
if (!childCommand.getName().equalsIgnoreCase(args[0])) {
|
if (!childCommand.getName().equalsIgnoreCase(args[0])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -141,6 +140,10 @@ public abstract class ParentCommand extends ChildCommand {
|
|||||||
CoreMessage.COMMAND_NOT_HAS_PERMISSION.show(sender);
|
CoreMessage.COMMAND_NOT_HAS_PERMISSION.show(sender);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (args.length - 1 < childCommand.getArgumentCount()) {
|
||||||
|
sender.sendMessage(getUsage() + " " + childCommand.getUsage());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return childCommand.onCommand(sender, command, label, Arrays.copyOfRange(args, 1, args.length));
|
return childCommand.onCommand(sender, command, label, Arrays.copyOfRange(args, 1, args.length));
|
||||||
}
|
}
|
||||||
CoreMessage.COMMAND_NOT_FOUND.show(sender);
|
CoreMessage.COMMAND_NOT_FOUND.show(sender);
|
||||||
@@ -150,18 +153,18 @@ public abstract class ParentCommand extends ChildCommand {
|
|||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||||
if (args.length == 0) {
|
if (args.length == 0) {
|
||||||
return childCommands.stream()
|
return getChildCommands().stream()
|
||||||
.filter(o -> o.hasPermission(sender))
|
.filter(o -> o.hasPermission(sender))
|
||||||
.map(ChildCommand::getName)
|
.map(ChildCommand::getName)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
for (ChildCommand child : childCommands) {
|
for (ChildCommand child : getChildCommands()) {
|
||||||
if (args[0].equalsIgnoreCase(child.getName())) {
|
if (args[0].equalsIgnoreCase(child.getName())) {
|
||||||
return child.onTabComplete(sender, command, alias, Arrays.copyOfRange(args, 1, args.length));
|
return child.onTabComplete(sender, command, alias, Arrays.copyOfRange(args, 1, args.length));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
args[0] = args[0].toLowerCase();
|
args[0] = args[0].toLowerCase();
|
||||||
return childCommands.stream()
|
return getChildCommands().stream()
|
||||||
.filter(o -> o.hasPermission(sender))
|
.filter(o -> o.hasPermission(sender))
|
||||||
.map(ChildCommand::getName)
|
.map(ChildCommand::getName)
|
||||||
.filter(o -> o.toLowerCase().startsWith(args[0].toLowerCase()))
|
.filter(o -> o.toLowerCase().startsWith(args[0].toLowerCase()))
|
||||||
|
@@ -69,9 +69,9 @@ public class InfoModeCommand extends ChildCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (DebugListener.INFO_MODE_PLAYERS.contains(uuid)) {
|
if (DebugListener.INFO_MODE_PLAYERS.contains(uuid)) {
|
||||||
CoreMessage.COMMAND_DEBUG_INFO_MODE_OFF.show(player);
|
|
||||||
} else {
|
|
||||||
CoreMessage.COMMAND_DEBUG_INFO_MODE_ON.show(player);
|
CoreMessage.COMMAND_DEBUG_INFO_MODE_ON.show(player);
|
||||||
|
} else {
|
||||||
|
CoreMessage.COMMAND_DEBUG_INFO_MODE_OFF.show(player);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,11 @@ import cn.hamster3.mc.plugin.core.bukkit.HamsterCorePlugin;
|
|||||||
import cn.hamster3.mc.plugin.core.bukkit.command.ParentCommand;
|
import cn.hamster3.mc.plugin.core.bukkit.command.ParentCommand;
|
||||||
import cn.hamster3.mc.plugin.core.bukkit.constant.CoreMessage;
|
import cn.hamster3.mc.plugin.core.bukkit.constant.CoreMessage;
|
||||||
import cn.hamster3.mc.plugin.core.bukkit.util.CoreBukkitUtils;
|
import cn.hamster3.mc.plugin.core.bukkit.util.CoreBukkitUtils;
|
||||||
import de.tr7zw.changeme.nbtapi.*;
|
import de.tr7zw.changeme.nbtapi.NBT;
|
||||||
|
import de.tr7zw.changeme.nbtapi.NBTType;
|
||||||
|
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
|
||||||
|
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBTCompoundList;
|
||||||
|
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBTList;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -62,13 +66,12 @@ public class NBTCommand extends ParentCommand {
|
|||||||
sender.sendMessage("§c你的手持物品为空");
|
sender.sendMessage("§c你的手持物品为空");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
NBTItem nbtItem = new NBTItem(stack);
|
ReadWriteNBT readWriteNBT = NBT.itemStackToNBT(stack);
|
||||||
sendNBTCompound(nbtItem, sender, 0);
|
sendNBTCompound(readWriteNBT, sender, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("ForLoopReplaceableByForEach")
|
private void sendNBTCompound(ReadWriteNBT compound, CommandSender sender, int level) {
|
||||||
private void sendNBTCompound(NBTCompound compound, CommandSender sender, int level) {
|
|
||||||
StringBuilder prefixBuilder = new StringBuilder();
|
StringBuilder prefixBuilder = new StringBuilder();
|
||||||
for (int i = 0; i < level; i++) {
|
for (int i = 0; i < level; i++) {
|
||||||
prefixBuilder.append(" ");
|
prefixBuilder.append(" ");
|
||||||
@@ -78,31 +81,31 @@ public class NBTCommand extends ParentCommand {
|
|||||||
NBTType type = compound.getType(key);
|
NBTType type = compound.getType(key);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case NBTTagByte: {
|
case NBTTagByte: {
|
||||||
sender.sendMessage(String.format("%s- %s:%d §e§l[%s]", space, key, compound.getByte(key), NBT_TYPE_NAME.get(type)));
|
sender.sendMessage(String.format("%s- %s=%d §e§l[%s]", space, key, compound.getByte(key), NBT_TYPE_NAME.get(type)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NBTTagShort: {
|
case NBTTagShort: {
|
||||||
sender.sendMessage(String.format("%s- %s:%d §e§l[%s]", space, key, compound.getShort(key), NBT_TYPE_NAME.get(type)));
|
sender.sendMessage(String.format("%s- %s=%d §e§l[%s]", space, key, compound.getShort(key), NBT_TYPE_NAME.get(type)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NBTTagInt: {
|
case NBTTagInt: {
|
||||||
sender.sendMessage(String.format("%s- %s:%d §e§l[%s]", space, key, compound.getInteger(key), NBT_TYPE_NAME.get(type)));
|
sender.sendMessage(String.format("%s- %s=%d §e§l[%s]", space, key, compound.getInteger(key), NBT_TYPE_NAME.get(type)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NBTTagLong: {
|
case NBTTagLong: {
|
||||||
sender.sendMessage(String.format("%s- %s:%d §e§l[%s]", space, key, compound.getLong(key), NBT_TYPE_NAME.get(type)));
|
sender.sendMessage(String.format("%s- %s=%d §e§l[%s]", space, key, compound.getLong(key), NBT_TYPE_NAME.get(type)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NBTTagFloat: {
|
case NBTTagFloat: {
|
||||||
sender.sendMessage(String.format("%s- %s:%f §e§l[%s]", space, key, compound.getFloat(key), NBT_TYPE_NAME.get(type)));
|
sender.sendMessage(String.format("%s- %s=%f §e§l[%s]", space, key, compound.getFloat(key), NBT_TYPE_NAME.get(type)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NBTTagDouble: {
|
case NBTTagDouble: {
|
||||||
sender.sendMessage(String.format("%s- %s:%f §e§l[%s]", space, key, compound.getDouble(key), NBT_TYPE_NAME.get(type)));
|
sender.sendMessage(String.format("%s- %s=%f §e§l[%s]", space, key, compound.getDouble(key), NBT_TYPE_NAME.get(type)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NBTTagString: {
|
case NBTTagString: {
|
||||||
sender.sendMessage(String.format("%s- %s:%s §e§l[%s]", space, key, compound.getString(key), NBT_TYPE_NAME.get(type)));
|
sender.sendMessage(String.format("%s- %s=%s §e§l[%s]", space, key, compound.getString(key), NBT_TYPE_NAME.get(type)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NBTTagCompound: {
|
case NBTTagCompound: {
|
||||||
@@ -112,20 +115,20 @@ public class NBTCommand extends ParentCommand {
|
|||||||
}
|
}
|
||||||
case NBTTagByteArray: {
|
case NBTTagByteArray: {
|
||||||
byte[] array = compound.getByteArray(key);
|
byte[] array = compound.getByteArray(key);
|
||||||
sender.sendMessage(String.format("%s- %s:%s §e§l[%s]", space, key, Arrays.toString(array), NBT_TYPE_NAME.get(type)));
|
sender.sendMessage(String.format("%s- %s=%s §e§l[%s]", space, key, Arrays.toString(array), NBT_TYPE_NAME.get(type)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NBTTagIntArray: {
|
case NBTTagIntArray: {
|
||||||
int[] array = compound.getIntArray(key);
|
int[] array = compound.getIntArray(key);
|
||||||
sender.sendMessage(String.format("%s- %s:%s §e§l[%s]", space, key, Arrays.toString(array), NBT_TYPE_NAME.get(type)));
|
sender.sendMessage(String.format("%s- %s=%s §e§l[%s]", space, key, Arrays.toString(array), NBT_TYPE_NAME.get(type)));
|
||||||
if (array != null && array.length == 4) {
|
if (array != null && array.length == 4) {
|
||||||
sender.sendMessage(String.format("%s- %s:%s §e§l[uuid]", space, key, compound.getUUID(key)));
|
sender.sendMessage(String.format("%s- %s=%s §e§l[uuid]", space, key, compound.getUUID(key)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NBTTagLongArray: {
|
case NBTTagLongArray: {
|
||||||
long[] array = compound.getLongArray(key);
|
long[] array = compound.getLongArray(key);
|
||||||
sender.sendMessage(String.format("%s- %s:%s §e§l[%s]", space, key, Arrays.toString(array), NBT_TYPE_NAME.get(type)));
|
sender.sendMessage(String.format("%s- %s=%s §e§l[%s]", space, key, Arrays.toString(array), NBT_TYPE_NAME.get(type)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NBTTagList: {
|
case NBTTagList: {
|
||||||
@@ -137,7 +140,7 @@ public class NBTCommand extends ParentCommand {
|
|||||||
String listSpace = space + " ";
|
String listSpace = space + " ";
|
||||||
switch (listType) {
|
switch (listType) {
|
||||||
case NBTTagString: {
|
case NBTTagString: {
|
||||||
NBTList<String> list = compound.getStringList(key);
|
ReadWriteNBTList<String> list = compound.getStringList(key);
|
||||||
for (String string : list) {
|
for (String string : list) {
|
||||||
sender.sendMessage(String.format("%s- %s", listSpace, string));
|
sender.sendMessage(String.format("%s- %s", listSpace, string));
|
||||||
}
|
}
|
||||||
@@ -145,7 +148,7 @@ public class NBTCommand extends ParentCommand {
|
|||||||
}
|
}
|
||||||
case NBTTagIntArray: {
|
case NBTTagIntArray: {
|
||||||
boolean all4Length = true;
|
boolean all4Length = true;
|
||||||
NBTList<int[]> list = compound.getIntArrayList(key);
|
ReadWriteNBTList<int[]> list = compound.getIntArrayList(key);
|
||||||
for (int[] intArray : list) {
|
for (int[] intArray : list) {
|
||||||
if (intArray.length != 4) {
|
if (intArray.length != 4) {
|
||||||
all4Length = false;
|
all4Length = false;
|
||||||
@@ -153,7 +156,7 @@ public class NBTCommand extends ParentCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (all4Length) {
|
if (all4Length) {
|
||||||
NBTList<UUID> uuidList = compound.getUUIDList(key);
|
ReadWriteNBTList<UUID> uuidList = compound.getUUIDList(key);
|
||||||
for (int i = 0; i < list.size(); i++) {
|
for (int i = 0; i < list.size(); i++) {
|
||||||
int[] intArray = list.get(i);
|
int[] intArray = list.get(i);
|
||||||
UUID uuid = uuidList.get(i);
|
UUID uuid = uuidList.get(i);
|
||||||
@@ -169,37 +172,37 @@ public class NBTCommand extends ParentCommand {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NBTTagInt: {
|
case NBTTagInt: {
|
||||||
NBTList<Integer> list = compound.getIntegerList(key);
|
ReadWriteNBTList<Integer> list = compound.getIntegerList(key);
|
||||||
for (Integer value : list) {
|
for (Integer value : list) {
|
||||||
sender.sendMessage(String.format("%s- %d", listSpace, value));
|
sender.sendMessage(String.format("%s- %d", listSpace, value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NBTTagLong: {
|
case NBTTagLong: {
|
||||||
NBTList<Long> list = compound.getLongList(key);
|
ReadWriteNBTList<Long> list = compound.getLongList(key);
|
||||||
for (Long value : list) {
|
for (Long value : list) {
|
||||||
sender.sendMessage(String.format("%s- %d", listSpace, value));
|
sender.sendMessage(String.format("%s- %d", listSpace, value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NBTTagFloat: {
|
case NBTTagFloat: {
|
||||||
NBTList<Float> list = compound.getFloatList(key);
|
ReadWriteNBTList<Float> list = compound.getFloatList(key);
|
||||||
for (Float value : list) {
|
for (Float value : list) {
|
||||||
sender.sendMessage(String.format("%s- %f", listSpace, value));
|
sender.sendMessage(String.format("%s- %f", listSpace, value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NBTTagDouble: {
|
case NBTTagDouble: {
|
||||||
NBTList<Double> list = compound.getDoubleList(key);
|
ReadWriteNBTList<Double> list = compound.getDoubleList(key);
|
||||||
for (Double value : list) {
|
for (Double value : list) {
|
||||||
sender.sendMessage(String.format("%s- %f", listSpace, value));
|
sender.sendMessage(String.format("%s- %f", listSpace, value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NBTTagCompound: {
|
case NBTTagCompound: {
|
||||||
NBTCompoundList compoundList = compound.getCompoundList(key);
|
ReadWriteNBTCompoundList compoundList = compound.getCompoundList(key);
|
||||||
for (int i = 0; i < compoundList.size(); i++) {
|
for (int i = 0; i < compoundList.size(); i++) {
|
||||||
NBTListCompound listCompound = compoundList.get(i);
|
ReadWriteNBT listCompound = compoundList.get(i);
|
||||||
sendNBTCompound(listCompound, sender, level + 1);
|
sendNBTCompound(listCompound, sender, level + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,11 +27,10 @@ public class PointAPI {
|
|||||||
public static void reloadPlayerPointAPIHook() {
|
public static void reloadPlayerPointAPIHook() {
|
||||||
Plugin plugin = Bukkit.getPluginManager().getPlugin("PlayerPoints");
|
Plugin plugin = Bukkit.getPluginManager().getPlugin("PlayerPoints");
|
||||||
if (plugin == null) {
|
if (plugin == null) {
|
||||||
HamsterCorePlugin.getSimpleLogger().warn("未检测到 PlayerPointAPI 插件");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
playerPointsAPI = ((PlayerPoints) plugin).getAPI();
|
playerPointsAPI = ((PlayerPoints) plugin).getAPI();
|
||||||
HamsterCorePlugin.getSimpleLogger().info("PlayerPointAPI 挂接成功");
|
HamsterCorePlugin.getSimpleLogger().info("已挂接 PlayerPointAPI");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -34,34 +34,23 @@ public class VaultAPI {
|
|||||||
vaultEnabled = Bukkit.getPluginManager().isPluginEnabled("Vault");
|
vaultEnabled = Bukkit.getPluginManager().isPluginEnabled("Vault");
|
||||||
BukkitSimpleLogger logger = HamsterCorePlugin.getSimpleLogger();
|
BukkitSimpleLogger logger = HamsterCorePlugin.getSimpleLogger();
|
||||||
if (!vaultEnabled) {
|
if (!vaultEnabled) {
|
||||||
logger.warn("未检测到 Vault 插件");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
logger.info("已连接 Vault");
|
logger.info("检测到服务器已安装 Vault 插件");
|
||||||
|
|
||||||
RegisteredServiceProvider<Chat> chatProvider = Bukkit.getServer().getServicesManager().getRegistration(Chat.class);
|
RegisteredServiceProvider<Chat> chatProvider = Bukkit.getServer().getServicesManager().getRegistration(Chat.class);
|
||||||
|
|
||||||
if (chatProvider != null) {
|
if (chatProvider != null) {
|
||||||
chat = chatProvider.getProvider();
|
chat = chatProvider.getProvider();
|
||||||
logger.info("聊天系统挂接成功");
|
logger.info("聊天系统挂接成功");
|
||||||
} else {
|
|
||||||
logger.warn("未检测到聊天系统");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisteredServiceProvider<Economy> economyProvider = Bukkit.getServer().getServicesManager().getRegistration(Economy.class);
|
RegisteredServiceProvider<Economy> economyProvider = Bukkit.getServer().getServicesManager().getRegistration(Economy.class);
|
||||||
if (economyProvider != null) {
|
if (economyProvider != null) {
|
||||||
economy = economyProvider.getProvider();
|
economy = economyProvider.getProvider();
|
||||||
logger.info("经济系统挂接成功");
|
logger.info("经济系统挂接成功");
|
||||||
} else {
|
|
||||||
logger.warn("未检测到经济系统");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisteredServiceProvider<Permission> permissionProvider = Bukkit.getServer().getServicesManager().getRegistration(Permission.class);
|
RegisteredServiceProvider<Permission> permissionProvider = Bukkit.getServer().getServicesManager().getRegistration(Permission.class);
|
||||||
if (permissionProvider != null) {
|
if (permissionProvider != null) {
|
||||||
permission = permissionProvider.getProvider();
|
permission = permissionProvider.getProvider();
|
||||||
logger.info("权限系统挂接成功");
|
logger.info("权限系统挂接成功");
|
||||||
} else {
|
|
||||||
logger.warn("未检测到权限插件");
|
|
||||||
}
|
}
|
||||||
logger.info("已完成 VaultAPI 挂载");
|
logger.info("已完成 VaultAPI 挂载");
|
||||||
}
|
}
|
||||||
|
@@ -3,10 +3,10 @@ package cn.hamster3.mc.plugin.core.bukkit.util;
|
|||||||
import cn.hamster3.mc.plugin.core.bukkit.listener.CallbackListener;
|
import cn.hamster3.mc.plugin.core.bukkit.listener.CallbackListener;
|
||||||
import cn.hamster3.mc.plugin.core.common.data.DisplayMessage;
|
import cn.hamster3.mc.plugin.core.common.data.DisplayMessage;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import de.tr7zw.changeme.nbtapi.NBTContainer;
|
import de.tr7zw.changeme.nbtapi.NBT;
|
||||||
import de.tr7zw.changeme.nbtapi.NBTItem;
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPI;
|
import me.clip.placeholderapi.PlaceholderAPI;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
import net.kyori.adventure.title.Title;
|
import net.kyori.adventure.title.Title;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@@ -241,23 +241,45 @@ public final class CoreBukkitUtils {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public static DisplayMessage loadDisplayMessage(@NotNull ConfigurationSection config) {
|
public static DisplayMessage loadDisplayMessage(@NotNull ConfigurationSection config) {
|
||||||
DisplayMessage displayMessage = new DisplayMessage();
|
DisplayMessage displayMessage = new DisplayMessage();
|
||||||
String message = config.getString("message");
|
String miniMessage = config.getString("mini-message");
|
||||||
if (message != null) {
|
if (miniMessage != null) {
|
||||||
displayMessage.setMessage(LegacyComponentSerializer.legacySection().deserialize(message));
|
displayMessage.setMessage(MiniMessage.miniMessage().deserialize(miniMessage));
|
||||||
|
} else {
|
||||||
|
String message = config.getString("message");
|
||||||
|
if (message != null) {
|
||||||
|
displayMessage.setMessage(LegacyComponentSerializer.legacySection().deserialize(message));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
String actionbar = config.getString("actionbar");
|
String miniActionbar = config.getString("mini-actionbar");
|
||||||
if (actionbar != null) {
|
if (miniActionbar != null) {
|
||||||
displayMessage.setActionbar(LegacyComponentSerializer.legacySection().deserialize(actionbar));
|
displayMessage.setActionbar(MiniMessage.miniMessage().deserialize(miniActionbar));
|
||||||
|
} else {
|
||||||
|
String actionbar = config.getString("actionbar");
|
||||||
|
if (actionbar != null) {
|
||||||
|
displayMessage.setActionbar(LegacyComponentSerializer.legacySection().deserialize(actionbar));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
String title = config.getString("title");
|
String miniTitle = config.getString("mini-title");
|
||||||
String subtitle = config.getString("subtitle");
|
String miniSubtitle = config.getString("mini-subtitle");
|
||||||
if (title != null || subtitle != null) {
|
if (miniTitle != null || miniSubtitle != null) {
|
||||||
displayMessage.setTitle(
|
displayMessage.setTitle(
|
||||||
title, subtitle,
|
MiniMessage.miniMessage().deserialize(miniTitle == null ? "" : miniTitle),
|
||||||
|
MiniMessage.miniMessage().deserialize(miniSubtitle == null ? "" : miniSubtitle),
|
||||||
config.getInt("fade-in", 10),
|
config.getInt("fade-in", 10),
|
||||||
config.getInt("stay", 70),
|
config.getInt("stay", 70),
|
||||||
config.getInt("fade-out", 20)
|
config.getInt("fade-out", 20)
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
String title = config.getString("title");
|
||||||
|
String subtitle = config.getString("subtitle");
|
||||||
|
if (title != null || subtitle != null) {
|
||||||
|
displayMessage.setTitle(
|
||||||
|
title, subtitle,
|
||||||
|
config.getInt("fade-in", 10),
|
||||||
|
config.getInt("stay", 70),
|
||||||
|
config.getInt("fade-out", 20)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
String sound = config.getString("sound");
|
String sound = config.getString("sound");
|
||||||
if (sound != null) {
|
if (sound != null) {
|
||||||
@@ -330,7 +352,7 @@ public final class CoreBukkitUtils {
|
|||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public static String serializeItemStack(@NotNull ItemStack stack) {
|
public static String serializeItemStack(@NotNull ItemStack stack) {
|
||||||
return NBTItem.convertItemtoNBT(stack).toString();
|
return NBT.itemStackToNBT(stack).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -341,7 +363,7 @@ public final class CoreBukkitUtils {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public static ItemStack deserializeItemStack(@NotNull String string) {
|
public static ItemStack deserializeItemStack(@NotNull String string) {
|
||||||
return NBTItem.convertNBTtoItem(new NBTContainer(string));
|
return NBT.itemStackFromNBT(NBT.parseNBT(string));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -61,8 +61,10 @@ public class MinecraftVersion {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static Class<?> getNMSClass(@NotNull String className) throws ClassNotFoundException {
|
public static Class<?> getNMSClass(@NotNull String className) throws ClassNotFoundException {
|
||||||
if (version1 >= 1 && version2 >= 17) {
|
if (version1 >= 1) {
|
||||||
return Class.forName("net.minecraft.server." + className);
|
if (version2 >= 17) {
|
||||||
|
return Class.forName("net.minecraft.server." + className);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
String nmsVersion = getNMSVersion();
|
String nmsVersion = getNMSVersion();
|
||||||
return Class.forName("net.minecraft.server." + nmsVersion + "." + className);
|
return Class.forName("net.minecraft.server." + nmsVersion + "." + className);
|
||||||
@@ -79,8 +81,13 @@ public class MinecraftVersion {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static Class<?> getCraftBukkitClass(@NotNull String className) throws ClassNotFoundException {
|
public static Class<?> getCraftBukkitClass(@NotNull String className) throws ClassNotFoundException {
|
||||||
if (version1 >= 1 && version2 >= 20 && version3 >= 6) {
|
if (version1 >= 1) {
|
||||||
return Class.forName("org.bukkit.craftbukkit." + className);
|
if (version2 >= 21) {
|
||||||
|
return Class.forName("org.bukkit.craftbukkit." + className);
|
||||||
|
}
|
||||||
|
if (version2 == 20 && version3 >= 6) {
|
||||||
|
return Class.forName("org.bukkit.craftbukkit." + className);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
String nmsVersion = getNMSVersion();
|
String nmsVersion = getNMSVersion();
|
||||||
return Class.forName("org.bukkit.craftbukkit." + nmsVersion + "." + className);
|
return Class.forName("org.bukkit.craftbukkit." + nmsVersion + "." + className);
|
||||||
|
@@ -12,7 +12,6 @@ UPDATE_CHECKER:
|
|||||||
CHECK_TYPE: GITEA_RELEASES
|
CHECK_TYPE: GITEA_RELEASES
|
||||||
GIT_BASE_URL: https://git.airgame.net
|
GIT_BASE_URL: https://git.airgame.net
|
||||||
GIT_REPO: MiniDay/hamster-core
|
GIT_REPO: MiniDay/hamster-core
|
||||||
DOWNLOAD_URL: https://jenkins.airgame.net/job/opensource/job/hamster-core/
|
|
||||||
|
|
||||||
load: STARTUP
|
load: STARTUP
|
||||||
|
|
||||||
|
@@ -1,6 +1,9 @@
|
|||||||
@file:Suppress("VulnerableLibrariesLocal")
|
@file:Suppress("VulnerableLibrariesLocal")
|
||||||
|
|
||||||
evaluationDependsOn(":core-common")
|
evaluationDependsOn(":core-common")
|
||||||
|
evaluationDependsOn(":core-relocate-lettuce")
|
||||||
|
|
||||||
|
val shade = configurations.create("shade")
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(project(":core-common")) { isTransitive = false }
|
api(project(":core-common")) { isTransitive = false }
|
||||||
@@ -14,19 +17,17 @@ dependencies {
|
|||||||
exclude(module = "adventure-api")
|
exclude(module = "adventure-api")
|
||||||
exclude(group = "org.jetbrains")
|
exclude(group = "org.jetbrains")
|
||||||
}
|
}
|
||||||
// https://mvnrepository.com/artifact/redis.clients/jedis
|
|
||||||
api("redis.clients:jedis:5.1.2") {
|
implementation("com.zaxxer:HikariCP:4.0.3") { exclude(group = "org.slf4j") }
|
||||||
|
api("redis.clients:jedis:5.1.4") {
|
||||||
exclude(group = "com.google.code.gson")
|
exclude(group = "com.google.code.gson")
|
||||||
exclude(group = "org.slf4j")
|
exclude(group = "org.slf4j")
|
||||||
}
|
}
|
||||||
// https://mvnrepository.com/artifact/org.quartz-scheduler/quartz
|
compileOnlyApi("io.lettuce:lettuce-core:6.7.1.RELEASE") {
|
||||||
api("org.quartz-scheduler:quartz:2.3.2") { isTransitive = false }
|
exclude(group = "org.slf4j")
|
||||||
// https://mvnrepository.com/artifact/com.sun.mail/jakarta.mail
|
exclude(group = "io.netty")
|
||||||
api("com.sun.mail:jakarta.mail:2.0.1")
|
}
|
||||||
|
shade(project(":core-relocate-lettuce"))
|
||||||
implementation("com.zaxxer:HikariCP:4.0.3") { exclude(group = "org.slf4j") }
|
|
||||||
// https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-stdlib-jdk8
|
|
||||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.23") { exclude(group = "org.jetbrains") }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
@@ -39,6 +40,9 @@ tasks {
|
|||||||
archiveBaseName = "HamsterCore-BungeeCord"
|
archiveBaseName = "HamsterCore-BungeeCord"
|
||||||
}
|
}
|
||||||
shadowJar {
|
shadowJar {
|
||||||
|
dependsOn(":core-relocate-lettuce:shadowJar")
|
||||||
|
val task = project(":core-relocate-lettuce").tasks.shadowJar.get()
|
||||||
|
from(task.outputs.files.map { if (it.isDirectory) it else zipTree(it) })
|
||||||
destinationDirectory = rootProject.layout.buildDirectory
|
destinationDirectory = rootProject.layout.buildDirectory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -19,7 +19,6 @@ import java.io.InputStreamReader;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
public class HamsterCorePlugin extends Plugin {
|
public class HamsterCorePlugin extends Plugin {
|
||||||
@Getter
|
@Getter
|
||||||
@@ -51,7 +50,7 @@ public class HamsterCorePlugin extends Plugin {
|
|||||||
CoreBungeeAPI.init(configFile);
|
CoreBungeeAPI.init(configFile);
|
||||||
simpleLogger.info("已初始化 CoreAPI");
|
simpleLogger.info("已初始化 CoreAPI");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
simpleLogger.log(Level.WARNING, "初始化 CoreAPI 出错", e);
|
simpleLogger.error(e, "初始化 CoreAPI 出错");
|
||||||
}
|
}
|
||||||
long time = System.currentTimeMillis() - start;
|
long time = System.currentTimeMillis() - start;
|
||||||
simpleLogger.info("仓鼠核心初始化完成,总计耗时 " + time + " ms");
|
simpleLogger.info("仓鼠核心初始化完成,总计耗时 " + time + " ms");
|
||||||
@@ -71,8 +70,11 @@ public class HamsterCorePlugin extends Plugin {
|
|||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
audienceProvider.close();
|
||||||
|
simpleLogger.info("已关闭 AudienceProvider.");
|
||||||
if (CoreAPI.getInstance().isEnableRedis()) {
|
if (CoreAPI.getInstance().isEnableRedis()) {
|
||||||
CoreAPI.getInstance().getJedisPool().close();
|
CoreAPI.getInstance().getJedisPool().close();
|
||||||
|
CoreAPI.getInstance().getRedisClient().close();
|
||||||
simpleLogger.info("已关闭 Redis 连接池");
|
simpleLogger.info("已关闭 Redis 连接池");
|
||||||
}
|
}
|
||||||
if (CoreAPI.getInstance().isEnableDatabase()) {
|
if (CoreAPI.getInstance().isEnableDatabase()) {
|
||||||
|
@@ -11,4 +11,3 @@ UPDATE_CHECKER:
|
|||||||
CHECK_TYPE: GITEA_RELEASES
|
CHECK_TYPE: GITEA_RELEASES
|
||||||
GIT_BASE_URL: https://git.airgame.net
|
GIT_BASE_URL: https://git.airgame.net
|
||||||
GIT_REPO: MiniDay/hamster-core
|
GIT_REPO: MiniDay/hamster-core
|
||||||
DOWNLOAD_URL: https://jenkins.airgame.net/job/opensource/job/hamster-core/
|
|
||||||
|
@@ -17,17 +17,18 @@ dependencies {
|
|||||||
exclude(group = "com.google.code.gson")
|
exclude(group = "com.google.code.gson")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://mvnrepository.com/artifact/com.zaxxer/HikariCP
|
||||||
|
compileOnly("com.zaxxer:HikariCP:4.0.3") { isTransitive = false }
|
||||||
// https://mvnrepository.com/artifact/redis.clients/jedis
|
// https://mvnrepository.com/artifact/redis.clients/jedis
|
||||||
compileOnlyApi("redis.clients:jedis:5.1.2") {
|
compileOnlyApi("redis.clients:jedis:5.1.4") {
|
||||||
exclude(group = "com.google.code.gson")
|
exclude(group = "com.google.code.gson")
|
||||||
exclude(group = "org.slf4j")
|
exclude(group = "org.slf4j")
|
||||||
}
|
}
|
||||||
compileOnlyApi("org.quartz-scheduler:quartz:2.3.2") { isTransitive = false }
|
// https://mvnrepository.com/artifact/io.lettuce/lettuce-core
|
||||||
// https://mvnrepository.com/artifact/com.sun.mail/jakarta.mail
|
compileOnlyApi("io.lettuce:lettuce-core:6.7.1.RELEASE") {
|
||||||
compileOnlyApi("com.sun.mail:jakarta.mail:2.0.1")
|
exclude(group = "io.netty")
|
||||||
|
exclude(group = "org.slf4j")
|
||||||
// https://mvnrepository.com/artifact/com.zaxxer/HikariCP
|
}
|
||||||
compileOnly("com.zaxxer:HikariCP:4.0.3") { isTransitive = false }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
@@ -6,6 +6,9 @@ import cn.hamster3.mc.plugin.core.common.util.CoreUtils;
|
|||||||
import cn.hamster3.mc.plugin.core.common.util.SimpleLogger;
|
import cn.hamster3.mc.plugin.core.common.util.SimpleLogger;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.zaxxer.hikari.HikariDataSource;
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
|
import io.lettuce.core.RedisClient;
|
||||||
|
import io.lettuce.core.api.StatefulRedisConnection;
|
||||||
|
import io.lettuce.core.pubsub.StatefulRedisPubSubConnection;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.kyori.adventure.platform.AudienceProvider;
|
import net.kyori.adventure.platform.AudienceProvider;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -41,6 +44,11 @@ public abstract class CoreAPI {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
private JedisPool jedisPool;
|
private JedisPool jedisPool;
|
||||||
|
/**
|
||||||
|
* Lettuce Redis 连接池
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private RedisClient redisClient;
|
||||||
/**
|
/**
|
||||||
* 公用数据库连接池
|
* 公用数据库连接池
|
||||||
*/
|
*/
|
||||||
@@ -57,6 +65,7 @@ public abstract class CoreAPI {
|
|||||||
if (enableRedis) {
|
if (enableRedis) {
|
||||||
logger.info("正在创建 Redis 连接池");
|
logger.info("正在创建 Redis 连接池");
|
||||||
jedisPool = new JedisPool(config.getString("redis-url"));
|
jedisPool = new JedisPool(config.getString("redis-url"));
|
||||||
|
redisClient = RedisClient.create(config.getString("redis-url"));
|
||||||
logger.info("Redis 连接池创建完成");
|
logger.info("Redis 连接池创建完成");
|
||||||
} else {
|
} else {
|
||||||
logger.info("未启用 Redis 功能");
|
logger.info("未启用 Redis 功能");
|
||||||
@@ -108,6 +117,24 @@ public abstract class CoreAPI {
|
|||||||
throw new IllegalStateException("仓鼠核心未启用 Redis 功能");
|
throw new IllegalStateException("仓鼠核心未启用 Redis 功能");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public RedisClient getRedisClient() {
|
||||||
|
if (redisClient != null) {
|
||||||
|
return redisClient;
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("仓鼠核心未启用 Redis 功能");
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public StatefulRedisConnection<String, String> getRedisConnect() {
|
||||||
|
return getRedisClient().connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public StatefulRedisPubSubConnection<String, String> getRedisPubSub() {
|
||||||
|
return getRedisClient().connectPubSub();
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public abstract SimpleLogger getLogger();
|
public abstract SimpleLogger getLogger();
|
||||||
|
|
||||||
|
@@ -5,6 +5,8 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
@SuppressWarnings({"unused", "unchecked"})
|
@SuppressWarnings({"unused", "unchecked"})
|
||||||
@Getter
|
@Getter
|
||||||
@@ -71,16 +73,6 @@ public class ConfigSection {
|
|||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getStringList(@NotNull String key) {
|
|
||||||
Object o = map.get(key);
|
|
||||||
if (o instanceof List) {
|
|
||||||
return (List<String>) o;
|
|
||||||
}
|
|
||||||
ArrayList<String> list = new ArrayList<>();
|
|
||||||
map.put(key, list);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getBoolean(@NotNull String key) {
|
public boolean getBoolean(@NotNull String key) {
|
||||||
String string = getString(key);
|
String string = getString(key);
|
||||||
if (string == null) {
|
if (string == null) {
|
||||||
@@ -161,6 +153,45 @@ public class ConfigSection {
|
|||||||
return Long.parseLong(string);
|
return Long.parseLong(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T> List<T> getList(@NotNull String key, Function<Object, T> function) {
|
||||||
|
ArrayList<T> list = new ArrayList<>();
|
||||||
|
Object object = map.get(key);
|
||||||
|
if (object instanceof List) {
|
||||||
|
List<?> mapList = (List<?>) object;
|
||||||
|
for (Object o : mapList) {
|
||||||
|
T result = function.apply(o);
|
||||||
|
list.add(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getStringList(@NotNull String key) {
|
||||||
|
return getList(key, Object::toString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Integer> getIntegerList(@NotNull String key) {
|
||||||
|
return getList(key, o -> Integer.parseInt(o.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> List<T> toList(BiFunction<ConfigSection, String, T> function) {
|
||||||
|
ArrayList<T> list = new ArrayList<>();
|
||||||
|
for (String key : getKeys()) {
|
||||||
|
T result = function.apply(this, key);
|
||||||
|
list.add(result);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> Map<String, T> toMap(BiFunction<ConfigSection, String, T> function) {
|
||||||
|
HashMap<String, T> map = new HashMap<>();
|
||||||
|
for (String key : getKeys()) {
|
||||||
|
T result = function.apply(this, key);
|
||||||
|
map.put(key, result);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
public void set(@NotNull String key, @Nullable Object value) {
|
public void set(@NotNull String key, @Nullable Object value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
map.remove(key);
|
map.remove(key);
|
||||||
|
@@ -5,9 +5,12 @@ import org.yaml.snakeyaml.Yaml;
|
|||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Map;
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@SuppressWarnings({"unused", "VulnerableCodeUsages"})
|
@SuppressWarnings("unused")
|
||||||
public class YamlConfig extends ConfigSection {
|
public class YamlConfig extends ConfigSection {
|
||||||
public static final Yaml YAML_LOADER = new Yaml();
|
public static final Yaml YAML_LOADER = new Yaml();
|
||||||
|
|
||||||
@@ -19,11 +22,56 @@ public class YamlConfig extends ConfigSection {
|
|||||||
super(map);
|
super(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<YamlConfig> loadFolder(@NotNull File file) throws IOException {
|
||||||
|
if (file.isDirectory()) {
|
||||||
|
ArrayList<YamlConfig> list = new ArrayList<>();
|
||||||
|
for (File subFile : Objects.requireNonNull(file.listFiles())) {
|
||||||
|
list.addAll(loadFolder(subFile));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
if (file.isFile() && file.getName().endsWith(".yml")) {
|
||||||
|
return Collections.singletonList(load(file));
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<YamlConfig> loadFolder(@NotNull File file, @NotNull Consumer<Exception> exceptionHandler) {
|
||||||
|
if (file.isDirectory()) {
|
||||||
|
ArrayList<YamlConfig> list = new ArrayList<>();
|
||||||
|
for (File subFile : Objects.requireNonNull(file.listFiles())) {
|
||||||
|
list.addAll(loadFolder(subFile, exceptionHandler));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
if (file.isFile() && file.getName().endsWith(".yml")) {
|
||||||
|
try {
|
||||||
|
YamlConfig load = load(file);
|
||||||
|
return Collections.singletonList(load);
|
||||||
|
} catch (IOException e) {
|
||||||
|
exceptionHandler.accept(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static YamlConfig load(@NotNull Path path) {
|
||||||
|
try {
|
||||||
|
return load(Files.newInputStream(path));
|
||||||
|
} catch (IOException e) {
|
||||||
|
return new YamlConfig();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static YamlConfig load(@NotNull File file) throws IOException {
|
public static YamlConfig load(@NotNull File file) throws IOException {
|
||||||
try (FileInputStream stream = new FileInputStream(file)) {
|
try (FileInputStream stream = new FileInputStream(file)) {
|
||||||
try (InputStreamReader reader = new InputStreamReader(stream, StandardCharsets.UTF_8)) {
|
return load(stream);
|
||||||
return load(reader);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static YamlConfig load(@NotNull InputStream stream) throws IOException {
|
||||||
|
try (InputStreamReader reader = new InputStreamReader(stream, StandardCharsets.UTF_8)) {
|
||||||
|
return load(reader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,11 +80,25 @@ public class YamlConfig extends ConfigSection {
|
|||||||
return new YamlConfig(load);
|
return new YamlConfig(load);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save(@NotNull File file) throws IOException {
|
public void save(@NotNull Path path) throws IOException {
|
||||||
try (FileOutputStream stream = new FileOutputStream(file)) {
|
try (OutputStream stream = Files.newOutputStream(path)) {
|
||||||
try (OutputStreamWriter writer = new OutputStreamWriter(stream, StandardCharsets.UTF_8)) {
|
save(stream);
|
||||||
YAML_LOADER.dump(map, writer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void save(@NotNull File file) throws IOException {
|
||||||
|
try (FileOutputStream stream = new FileOutputStream(file)) {
|
||||||
|
save(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(@NotNull OutputStream stream) throws IOException {
|
||||||
|
try (OutputStreamWriter writer = new OutputStreamWriter(stream, StandardCharsets.UTF_8)) {
|
||||||
|
save(writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(@NotNull Writer writer) {
|
||||||
|
YAML_LOADER.dump(map, writer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package cn.hamster3.mc.plugin.core.common.util;
|
package cn.hamster3.mc.plugin.core.common.util;
|
||||||
|
|
||||||
import cn.hamster3.mc.plugin.core.common.config.ConfigSection;
|
import cn.hamster3.mc.plugin.core.common.config.ConfigSection;
|
||||||
|
import cn.hamster3.mc.plugin.core.common.config.YamlConfig;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.zaxxer.hikari.HikariConfig;
|
import com.zaxxer.hikari.HikariConfig;
|
||||||
import com.zaxxer.hikari.HikariDataSource;
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
@@ -8,42 +9,42 @@ import net.kyori.adventure.key.Key;
|
|||||||
import net.kyori.adventure.sound.Sound;
|
import net.kyori.adventure.sound.Sound;
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
import net.kyori.adventure.title.Title;
|
import net.kyori.adventure.title.Title;
|
||||||
|
import net.kyori.adventure.translation.TranslationRegistry;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.text.MessageFormat;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.HashMap;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public final class CoreUtils {
|
public final class CoreUtils {
|
||||||
private CoreUtils() {
|
private CoreUtils() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void zipCompressionFolder(@NotNull File folder, @NotNull File zipFile) throws IOException {
|
@NotNull
|
||||||
try (ZipOutputStream stream = new ZipOutputStream(Files.newOutputStream(zipFile.toPath()))) {
|
public static DataSource getDataSource(@NotNull ConfigSection datasourceConfig) {
|
||||||
putFileToZipStream(stream, "", folder);
|
HikariConfig hikariConfig = new HikariConfig();
|
||||||
|
hikariConfig.setDriverClassName(datasourceConfig.getString("driver"));
|
||||||
|
hikariConfig.setJdbcUrl(datasourceConfig.getString("url"));
|
||||||
|
hikariConfig.setUsername(datasourceConfig.getString("username"));
|
||||||
|
hikariConfig.setPassword(datasourceConfig.getString("password"));
|
||||||
|
hikariConfig.setMaximumPoolSize(datasourceConfig.getInt("maximum-pool-size", 3));
|
||||||
|
hikariConfig.setMinimumIdle(datasourceConfig.getInt("minimum-idle", 1));
|
||||||
|
long keepAliveTime = datasourceConfig.getLong("keep-alive-time", 0);
|
||||||
|
if (keepAliveTime > 5000) {
|
||||||
|
hikariConfig.setKeepaliveTime(keepAliveTime);
|
||||||
}
|
}
|
||||||
}
|
hikariConfig.setIdleTimeout(datasourceConfig.getLong("idle-timeout", 10 * 60 * 1000));
|
||||||
|
hikariConfig.setMaxLifetime(datasourceConfig.getLong("max-lifetime", 30 * 60 * 1000));
|
||||||
public static void putFileToZipStream(@NotNull ZipOutputStream stream, @NotNull String path, @NotNull File file) throws IOException {
|
hikariConfig.setValidationTimeout(datasourceConfig.getLong("validation-timeout", 5000));
|
||||||
if (file.isDirectory()) {
|
hikariConfig.setPoolName(datasourceConfig.getString("name", "HamsterCore-Pool"));
|
||||||
File[] files = file.listFiles();
|
return new HikariDataSource(hikariConfig);
|
||||||
if (files == null) {
|
|
||||||
throw new IOException();
|
|
||||||
}
|
|
||||||
for (File subFile : files) {
|
|
||||||
putFileToZipStream(stream, path + file.getName() + "/", subFile);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ZipEntry entry = new ZipEntry(path + file.getName());
|
|
||||||
stream.putNextEntry(entry);
|
|
||||||
stream.write(Files.readAllBytes(file.toPath()));
|
|
||||||
stream.closeEntry();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -125,24 +126,30 @@ public final class CoreUtils {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
public static void loadTranslation(@NotNull TranslationRegistry registry, @NotNull File folder) throws IOException {
|
||||||
public static DataSource getDataSource(@NotNull ConfigSection datasourceConfig) {
|
for (File subFile : Objects.requireNonNull(folder.listFiles())) {
|
||||||
HikariConfig hikariConfig = new HikariConfig();
|
String filename = subFile.getName().split("\\.")[0];
|
||||||
hikariConfig.setDriverClassName(datasourceConfig.getString("driver"));
|
String[] args = filename.split("_");
|
||||||
hikariConfig.setJdbcUrl(datasourceConfig.getString("url"));
|
Locale locale = new Locale.Builder().setLanguage(args[0]).setRegion(args[1]).build();
|
||||||
hikariConfig.setUsername(datasourceConfig.getString("username"));
|
YamlConfig config = YamlConfig.load(subFile);
|
||||||
hikariConfig.setPassword(datasourceConfig.getString("password"));
|
Map<String, MessageFormat> map = loadTranslation(locale, config, "");
|
||||||
hikariConfig.setMaximumPoolSize(datasourceConfig.getInt("maximum-pool-size", 3));
|
registry.registerAll(locale, map);
|
||||||
hikariConfig.setMinimumIdle(datasourceConfig.getInt("minimum-idle", 1));
|
|
||||||
long keepAliveTime = datasourceConfig.getLong("keep-alive-time", 0);
|
|
||||||
if (keepAliveTime > 5000) {
|
|
||||||
hikariConfig.setKeepaliveTime(keepAliveTime);
|
|
||||||
}
|
}
|
||||||
hikariConfig.setIdleTimeout(datasourceConfig.getLong("idle-timeout", 10 * 60 * 1000));
|
}
|
||||||
hikariConfig.setMaxLifetime(datasourceConfig.getLong("max-lifetime", 30 * 60 * 1000));
|
|
||||||
hikariConfig.setValidationTimeout(datasourceConfig.getLong("validation-timeout", 5000));
|
public static Map<String, MessageFormat> loadTranslation(@NotNull Locale locale, @NotNull ConfigSection config, @NotNull String prefix) {
|
||||||
hikariConfig.setPoolName(datasourceConfig.getString("name", "HamsterCore-Pool"));
|
HashMap<String, MessageFormat> result = new HashMap<>();
|
||||||
return new HikariDataSource(hikariConfig);
|
for (Map.Entry<String, Object> entry : config.getMap().entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
Object value = entry.getValue();
|
||||||
|
if (value instanceof String) {
|
||||||
|
String string = (String) value;
|
||||||
|
result.put(prefix + key, new MessageFormat(string, locale));
|
||||||
|
} else if (value instanceof Map) {
|
||||||
|
loadTranslation(locale, config.getSectionOrCreate(key), "$prefix$key.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -19,20 +19,16 @@ public abstract class SimpleLogger {
|
|||||||
try {
|
try {
|
||||||
log(level, String.format(msg, args));
|
log(level, String.format(msg, args));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log(Level.WARNING, "输出日志 " + msg + " 时遇到一个异常");
|
log(Level.WARNING, "输出日志 " + msg + Arrays.toString(args) + " 时遇到一个异常", e);
|
||||||
log(Level.WARNING, "日志参数: " + Arrays.toString(args));
|
|
||||||
log(Level.WARNING, "异常信息: ", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void log(@NotNull Level level, @NotNull Throwable throwable, @NotNull String msg, @NotNull Object... args) {
|
public void log(@NotNull Level level, @NotNull Throwable throwable, @NotNull String msg, @NotNull Object... args) {
|
||||||
try {
|
try {
|
||||||
log(level, String.format(msg, args), throwable);
|
log(level, throwable, String.format(msg, args));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log(Level.WARNING, "输出日志 " + msg + " 时遇到一个异常");
|
log(Level.WARNING, "输出日志 " + msg + Arrays.toString(args) + " 时遇到一个异常", e);
|
||||||
log(Level.WARNING, "日志参数: " + Arrays.toString(args));
|
log(Level.WARNING, "异常参数: ", e);
|
||||||
log(Level.WARNING, "异常参数: ", throwable);
|
|
||||||
log(Level.WARNING, "异常信息: ", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,6 +15,7 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -45,6 +46,9 @@ public final class UpdateCheckUtils {
|
|||||||
switch (checkType) {
|
switch (checkType) {
|
||||||
case "GITEA_RELEASES": {
|
case "GITEA_RELEASES": {
|
||||||
lastRelease = getGiteaLastRelease(baseUrl, gitRepo, gitToken);
|
lastRelease = getGiteaLastRelease(baseUrl, gitRepo, gitToken);
|
||||||
|
if (downloadUrl == null) {
|
||||||
|
downloadUrl = URI.create(baseUrl).resolve("/" + gitRepo).toString();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "GITLAB_RELEASES": {
|
case "GITLAB_RELEASES": {
|
||||||
@@ -53,6 +57,9 @@ public final class UpdateCheckUtils {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lastRelease = getGitlabLastRelease(baseUrl, projectID, gitToken);
|
lastRelease = getGitlabLastRelease(baseUrl, projectID, gitToken);
|
||||||
|
if (downloadUrl == null) {
|
||||||
|
downloadUrl = URI.create(baseUrl).resolve("/" + gitRepo).toString();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,7 +111,6 @@ public final class UpdateCheckUtils {
|
|||||||
JsonArray array = JSON_PARSER.parse(reader).getAsJsonArray();
|
JsonArray array = JSON_PARSER.parse(reader).getAsJsonArray();
|
||||||
for (JsonElement element : array) {
|
for (JsonElement element : array) {
|
||||||
JsonObject object = element.getAsJsonObject();
|
JsonObject object = element.getAsJsonObject();
|
||||||
//noinspection SpellCheckingInspection
|
|
||||||
if (object.get("prerelease").getAsBoolean()) {
|
if (object.get("prerelease").getAsBoolean()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
21
core-relocate-lettuce/build.gradle.kts
Normal file
21
core-relocate-lettuce/build.gradle.kts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
// lettuce-core 需要使用 netty,但低版本 bukkit 服务端核心自带的 netty 版本 lettuce 需要的版本有冲突
|
||||||
|
// 所以必须 shadow 并 relocate 依赖 io.netty,才能保证两个版本互不冲突
|
||||||
|
// 但由于 core-bukkit 同时也 shadow 了 adventure-platform-bukkit,且 adventure 内部通过反射调用 netty
|
||||||
|
// 如果在 core-bukkit 中直接 relocate netty,会导致 adventure 的反射调用也指向 relocate 后的 netty
|
||||||
|
// 此时会导致 shadow 后的 adventure 与服务端中其他同样需要使用 netty 的插件关联时发生冲突
|
||||||
|
// 例如:服务端上安装了 ViaVersion 时,core-bukkit 内置的 adventure 将会与其发生冲突
|
||||||
|
// 因为 adventure 使用 relocate 之后的类路径,ViaVersion 在将类转换成原版 netty 类时,会发生 ClassCastException
|
||||||
|
// 所以只能先将 lettuce-core 与其需要的 netty 一起打包,并 relocate netty,然后再使 core-bukkit 依赖这个打包后的版本
|
||||||
|
// 才能使得 adventure 与 lettuce-core 正常运行
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("io.lettuce:lettuce-core:6.7.1.RELEASE") {
|
||||||
|
exclude(group = "org.slf4j")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
shadowJar {
|
||||||
|
relocate("io.netty", "cn.hamster3.mc.plugin.core.lib.io.netty")
|
||||||
|
}
|
||||||
|
}
|
@@ -1,6 +1,9 @@
|
|||||||
@file:Suppress("VulnerableLibrariesLocal")
|
@file:Suppress("VulnerableLibrariesLocal")
|
||||||
|
|
||||||
evaluationDependsOn(":core-common")
|
evaluationDependsOn(":core-common")
|
||||||
|
evaluationDependsOn(":core-relocate-lettuce")
|
||||||
|
|
||||||
|
val shade = configurations.create("shade")
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(project(":core-common")) { isTransitive = false }
|
api(project(":core-common")) { isTransitive = false }
|
||||||
@@ -8,23 +11,20 @@ dependencies {
|
|||||||
annotationProcessor("com.velocitypowered:velocity-api:3.3.0-SNAPSHOT")
|
annotationProcessor("com.velocitypowered:velocity-api:3.3.0-SNAPSHOT")
|
||||||
|
|
||||||
compileOnlyApi("net.kyori:adventure-platform-api:4.3.2") { isTransitive = false }
|
compileOnlyApi("net.kyori:adventure-platform-api:4.3.2") { isTransitive = false }
|
||||||
// https://mvnrepository.com/artifact/redis.clients/jedis
|
|
||||||
api("redis.clients:jedis:5.1.2") {
|
implementation("com.zaxxer:HikariCP:5.1.0") { isTransitive = false }
|
||||||
|
api("redis.clients:jedis:5.1.4") {
|
||||||
exclude(group = "com.google.code.gson")
|
exclude(group = "com.google.code.gson")
|
||||||
exclude(group = "org.slf4j")
|
exclude(group = "org.slf4j")
|
||||||
}
|
}
|
||||||
// https://mvnrepository.com/artifact/org.quartz-scheduler/quartz
|
compileOnlyApi("io.lettuce:lettuce-core:6.7.1.RELEASE") {
|
||||||
api("org.quartz-scheduler:quartz:2.3.2") { isTransitive = false }
|
exclude(group = "org.slf4j")
|
||||||
// https://mvnrepository.com/artifact/com.sun.mail/jakarta.mail
|
exclude(group = "io.netty")
|
||||||
api("com.sun.mail:jakarta.mail:2.0.1")
|
}
|
||||||
|
shade(project(":core-relocate-lettuce"))
|
||||||
// https://mvnrepository.com/artifact/com.zaxxer/HikariCP
|
|
||||||
implementation("com.zaxxer:HikariCP:5.1.0") { isTransitive = false }
|
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/com.mysql/mysql-connector-j
|
// https://mvnrepository.com/artifact/com.mysql/mysql-connector-j
|
||||||
runtimeOnly("com.mysql:mysql-connector-j:8.3.0")
|
runtimeOnly("com.mysql:mysql-connector-j:8.4.0")
|
||||||
// https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-stdlib
|
|
||||||
runtimeOnly("org.jetbrains.kotlin:kotlin-stdlib:1.9.23") { exclude(group = "org.jetbrains") }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets.create("templates") {
|
sourceSets.create("templates") {
|
||||||
@@ -54,6 +54,9 @@ tasks {
|
|||||||
archiveBaseName = "HamsterCore-Velocity"
|
archiveBaseName = "HamsterCore-Velocity"
|
||||||
}
|
}
|
||||||
shadowJar {
|
shadowJar {
|
||||||
|
dependsOn(":core-relocate-lettuce:shadowJar")
|
||||||
|
val task = project(":core-relocate-lettuce").tasks.shadowJar.get()
|
||||||
|
from(task.outputs.files.map { if (it.isDirectory) it else zipTree(it) })
|
||||||
destinationDirectory = rootProject.layout.buildDirectory
|
destinationDirectory = rootProject.layout.buildDirectory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,6 +4,7 @@ import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
|||||||
import cn.hamster3.mc.plugin.core.common.config.YamlConfig;
|
import cn.hamster3.mc.plugin.core.common.config.YamlConfig;
|
||||||
import cn.hamster3.mc.plugin.core.common.util.UpdateCheckUtils;
|
import cn.hamster3.mc.plugin.core.common.util.UpdateCheckUtils;
|
||||||
import cn.hamster3.mc.plugin.core.velocity.api.CoreVelocityAPI;
|
import cn.hamster3.mc.plugin.core.velocity.api.CoreVelocityAPI;
|
||||||
|
import cn.hamster3.mc.plugin.core.velocity.impl.AudienceProviderImpl;
|
||||||
import cn.hamster3.mc.plugin.core.velocity.util.VelocitySimpleLogger;
|
import cn.hamster3.mc.plugin.core.velocity.util.VelocitySimpleLogger;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.velocitypowered.api.event.PostOrder;
|
import com.velocitypowered.api.event.PostOrder;
|
||||||
@@ -65,7 +66,7 @@ public class HamsterCorePlugin {
|
|||||||
CoreVelocityAPI.init(configFile);
|
CoreVelocityAPI.init(configFile);
|
||||||
simpleLogger.info("已初始化 CoreAPI");
|
simpleLogger.info("已初始化 CoreAPI");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
simpleLogger.error("初始化 CoreAPI 出错", e);
|
simpleLogger.error(e, "初始化 CoreAPI 出错");
|
||||||
}
|
}
|
||||||
long time = System.currentTimeMillis() - start;
|
long time = System.currentTimeMillis() - start;
|
||||||
simpleLogger.info("仓鼠核心初始化完成,总计耗时 " + time + " ms");
|
simpleLogger.info("仓鼠核心初始化完成,总计耗时 " + time + " ms");
|
||||||
@@ -83,8 +84,11 @@ public class HamsterCorePlugin {
|
|||||||
@Subscribe(order = PostOrder.LAST)
|
@Subscribe(order = PostOrder.LAST)
|
||||||
public void onProxyShutdown(ProxyShutdownEvent event) {
|
public void onProxyShutdown(ProxyShutdownEvent event) {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
AudienceProviderImpl.INSTANCE.close();
|
||||||
|
simpleLogger.info("已关闭 AudienceProvider.");
|
||||||
if (CoreAPI.getInstance().isEnableRedis()) {
|
if (CoreAPI.getInstance().isEnableRedis()) {
|
||||||
CoreAPI.getInstance().getJedisPool().close();
|
CoreAPI.getInstance().getJedisPool().close();
|
||||||
|
CoreAPI.getInstance().getRedisClient().close();
|
||||||
simpleLogger.info("已关闭 Redis 连接池");
|
simpleLogger.info("已关闭 Redis 连接池");
|
||||||
}
|
}
|
||||||
if (CoreAPI.getInstance().isEnableDatabase()) {
|
if (CoreAPI.getInstance().isEnableDatabase()) {
|
||||||
|
@@ -2,4 +2,3 @@ VERSION: ${version}
|
|||||||
CHECK_TYPE: GITEA_RELEASES
|
CHECK_TYPE: GITEA_RELEASES
|
||||||
GIT_BASE_URL: https://git.airgame.net
|
GIT_BASE_URL: https://git.airgame.net
|
||||||
GIT_REPO: MiniDay/hamster-core
|
GIT_REPO: MiniDay/hamster-core
|
||||||
DOWNLOAD_URL: https://jenkins.airgame.net/job/opensource/job/hamster-core/
|
|
||||||
|
@@ -1,8 +1,6 @@
|
|||||||
pluginManagement {
|
pluginManagement {
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven("https://maven.airgame.net/maven-public/")
|
||||||
url = uri("https://maven.airgame.net/maven-public/")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rootProject.name = "hamster-core"
|
rootProject.name = "hamster-core"
|
||||||
@@ -10,3 +8,4 @@ include("core-common")
|
|||||||
include("core-bukkit")
|
include("core-bukkit")
|
||||||
include("core-bungee")
|
include("core-bungee")
|
||||||
include("core-velocity")
|
include("core-velocity")
|
||||||
|
include("core-relocate-lettuce")
|
Reference in New Issue
Block a user