feat: 初版完成
初版完成
This commit is contained in:
@@ -3,7 +3,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group 'cn.hamster3.mc.plugin'
|
group 'cn.hamster3.mc.plugin'
|
||||||
version '0.0.1-SNAPSHOT'
|
version '1.0.0'
|
||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
apply plugin: 'java-library'
|
apply plugin: 'java-library'
|
||||||
@@ -19,12 +19,14 @@ subprojects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
|
shade
|
||||||
api.extendsFrom apiShade
|
api.extendsFrom apiShade
|
||||||
implementation.extendsFrom implementationShade
|
implementation.extendsFrom implementationShade
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly group: 'org.jetbrains', name: 'annotations', version: '21.0.1'
|
// https://mvnrepository.com/artifact/org.jetbrains/annotations
|
||||||
|
compileOnly 'org.jetbrains:annotations:23.0.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType(JavaCompile) {
|
tasks.withType(JavaCompile) {
|
||||||
|
@@ -8,20 +8,18 @@ dependencies {
|
|||||||
}
|
}
|
||||||
compileOnly 'org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT'
|
compileOnly 'org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT'
|
||||||
|
|
||||||
|
compileOnly 'net.milkbowl.vault:VaultAPI:1.7'
|
||||||
|
compileOnly 'org.black_ixx:playerpoints:2.1.3'
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/com.zaxxer/HikariCP
|
// https://mvnrepository.com/artifact/com.zaxxer/HikariCP
|
||||||
//noinspection GradlePackageUpdate
|
//noinspection GradlePackageUpdate
|
||||||
apiShade 'com.zaxxer:HikariCP:4.0.3'
|
apiShade 'com.zaxxer:HikariCP:4.0.3'
|
||||||
|
// https://mvnrepository.com/artifact/mysql/mysql-connector-java
|
||||||
|
shade 'mysql:mysql-connector-java:8.0.31'
|
||||||
// https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp
|
// https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp
|
||||||
apiShade 'com.squareup.okhttp3:okhttp:4.10.0'
|
apiShade 'com.squareup.okhttp3:okhttp:4.10.0'
|
||||||
// https://mvnrepository.com/artifact/net.kyori/adventure-platform-bukkit
|
// https://mvnrepository.com/artifact/net.kyori/adventure-platform-bukkit
|
||||||
apiShade 'net.kyori:adventure-platform-bukkit:4.1.2'
|
apiShade 'net.kyori:adventure-platform-bukkit:4.1.2'
|
||||||
|
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0'
|
|
||||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
|
|
||||||
}
|
|
||||||
|
|
||||||
test {
|
|
||||||
useJUnitPlatform()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
@@ -38,11 +36,14 @@ tasks.create("shadowJar", Jar) {
|
|||||||
tasks.jar.outputs.files.collect {
|
tasks.jar.outputs.files.collect {
|
||||||
it.isDirectory() ? it : zipTree(it)
|
it.isDirectory() ? it : zipTree(it)
|
||||||
},
|
},
|
||||||
configurations.implementationShade.collect {
|
configurations.shade.collect {
|
||||||
it.isDirectory() ? it : zipTree(it)
|
it.isDirectory() ? it : zipTree(it)
|
||||||
},
|
},
|
||||||
configurations.apiShade.collect {
|
configurations.apiShade.collect {
|
||||||
it.isDirectory() ? it : zipTree(it)
|
it.isDirectory() ? it : zipTree(it)
|
||||||
|
},
|
||||||
|
configurations.implementationShade.collect {
|
||||||
|
it.isDirectory() ? it : zipTree(it)
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
destinationDir(getRootProject().buildDir)
|
destinationDir(getRootProject().buildDir)
|
||||||
|
@@ -1,11 +1,25 @@
|
|||||||
package cn.hamster3.mc.plugin.core.bukkit;
|
package cn.hamster3.mc.plugin.core.bukkit;
|
||||||
|
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.api.CoreBukkitAPI;
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.command.ParentCommand;
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.command.debug.BlockInfoCommand;
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.command.debug.YamlCommand;
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.hook.PointAPI;
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.hook.VaultAPI;
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.listener.CallbackListener;
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.listener.DebugListener;
|
||||||
import cn.hamster3.mc.plugin.core.bukkit.page.listener.PageListener;
|
import cn.hamster3.mc.plugin.core.bukkit.page.listener.PageListener;
|
||||||
import cn.hamster3.mc.plugin.core.common.constant.CoreConstantObjects;
|
import cn.hamster3.mc.plugin.core.common.constant.CoreConstantObjects;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class HamsterCorePlugin extends JavaPlugin {
|
public class HamsterCorePlugin extends JavaPlugin {
|
||||||
|
private static final ParentCommand COMMAND_EXECUTOR = new ParentCommand("core");
|
||||||
private static HamsterCorePlugin instance;
|
private static HamsterCorePlugin instance;
|
||||||
|
|
||||||
public static HamsterCorePlugin getInstance() {
|
public static HamsterCorePlugin getInstance() {
|
||||||
@@ -16,10 +30,6 @@ public class HamsterCorePlugin extends JavaPlugin {
|
|||||||
Bukkit.getScheduler().runTask(instance, runnable);
|
Bukkit.getScheduler().runTask(instance, runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void async(Runnable runnable) {
|
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(instance, runnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
instance = this;
|
instance = this;
|
||||||
@@ -27,23 +37,49 @@ public class HamsterCorePlugin extends JavaPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
|
Logger logger = getLogger();
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
getLogger().info("仓鼠核心正在启动...");
|
logger.info("仓鼠核心正在启动...");
|
||||||
|
CoreBukkitAPI.init();
|
||||||
|
logger.info("CoreAPI 已初始化.");
|
||||||
|
VaultAPI.reloadVaultHook();
|
||||||
|
logger.info("完成 VaultAPI 挂载.");
|
||||||
|
PointAPI.reloadPlayerPointAPIHook();
|
||||||
|
logger.info("完成 PlayerPoints 挂载.");
|
||||||
Bukkit.getPluginManager().registerEvents(PageListener.INSTANCE, this);
|
Bukkit.getPluginManager().registerEvents(PageListener.INSTANCE, this);
|
||||||
getLogger().info("已注册 PageListener.");
|
logger.info("已注册 PageListener.");
|
||||||
|
Bukkit.getPluginManager().registerEvents(CallbackListener.INSTANCE, this);
|
||||||
|
logger.info("已注册 CallbackListener.");
|
||||||
|
Bukkit.getPluginManager().registerEvents(DebugListener.INSTANCE, this);
|
||||||
|
logger.info("已注册 DebugListener.");
|
||||||
|
COMMAND_EXECUTOR.addChildCommand(BlockInfoCommand.INSTANCE);
|
||||||
|
logger.info("已添加指令: " + BlockInfoCommand.INSTANCE.getName() + " .");
|
||||||
|
COMMAND_EXECUTOR.addChildCommand(YamlCommand.INSTANCE);
|
||||||
|
logger.info("已添加指令: " + YamlCommand.INSTANCE.getName() + " .");
|
||||||
long time = System.currentTimeMillis() - start;
|
long time = System.currentTimeMillis() - start;
|
||||||
getLogger().info("仓鼠核心已启动,总计耗时 " + time + " ms.");
|
logger.info("仓鼠核心已启动,总计耗时 " + time + " ms.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
|
Logger logger = getLogger();
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
getLogger().info("仓鼠核心正在关闭...");
|
logger.info("仓鼠核心正在关闭...");
|
||||||
CoreConstantObjects.WORKER_EXECUTOR.shutdownNow();
|
CoreConstantObjects.WORKER_EXECUTOR.shutdownNow();
|
||||||
getLogger().info("已暂停 WORKER_EXECUTOR.");
|
logger.info("已暂停 WORKER_EXECUTOR.");
|
||||||
CoreConstantObjects.SCHEDULED_EXECUTOR.shutdownNow();
|
CoreConstantObjects.SCHEDULED_EXECUTOR.shutdownNow();
|
||||||
getLogger().info("已暂停 SCHEDULED_EXECUTOR.");
|
logger.info("已暂停 SCHEDULED_EXECUTOR.");
|
||||||
long time = System.currentTimeMillis() - start;
|
long time = System.currentTimeMillis() - start;
|
||||||
getLogger().info("仓鼠核心已关闭,总计耗时 " + time + " ms.");
|
logger.info("仓鼠核心已关闭,总计耗时 " + time + " ms.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||||
|
return COMMAND_EXECUTOR.onCommand(sender, command, label, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||||
|
return COMMAND_EXECUTOR.onTabComplete(sender, command, alias, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,31 +1,46 @@
|
|||||||
package cn.hamster3.mc.plugin.core.bukkit.api;
|
package cn.hamster3.mc.plugin.core.bukkit.api;
|
||||||
|
|
||||||
import cn.hamster3.mc.plugin.core.bukkit.HamsterCorePlugin;
|
import cn.hamster3.mc.plugin.core.bukkit.HamsterCorePlugin;
|
||||||
import cn.hamster3.mc.plugin.core.common.api.CoreCommonAPI;
|
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
||||||
import com.zaxxer.hikari.HikariConfig;
|
import com.zaxxer.hikari.HikariConfig;
|
||||||
import com.zaxxer.hikari.HikariDataSource;
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
import net.kyori.adventure.platform.AudienceProvider;
|
import net.kyori.adventure.platform.AudienceProvider;
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class CoreBukkitAPI extends CoreCommonAPI {
|
public class CoreBukkitAPI extends CoreAPI {
|
||||||
private BukkitAudiences audienceProvider;
|
private final BukkitAudiences audienceProvider;
|
||||||
private HikariDataSource datasource;
|
private final HikariDataSource datasource;
|
||||||
|
|
||||||
|
public CoreBukkitAPI() {
|
||||||
|
HamsterCorePlugin plugin = HamsterCorePlugin.getInstance();
|
||||||
|
audienceProvider = BukkitAudiences.create(plugin);
|
||||||
|
|
||||||
|
plugin.saveDefaultConfig();
|
||||||
|
FileConfiguration config = plugin.getConfig();
|
||||||
|
|
||||||
|
ConfigurationSection datasourceConfig = config.getConfigurationSection("datasource");
|
||||||
|
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));
|
||||||
|
hikariConfig.setIdleTimeout(datasourceConfig.getLong("idle-timeout", 5 * 60 * 1000));
|
||||||
|
hikariConfig.setMaxLifetime(datasourceConfig.getLong("max-lifetime", 0));
|
||||||
|
datasource = new HikariDataSource(hikariConfig);
|
||||||
|
}
|
||||||
|
|
||||||
public static CoreBukkitAPI getInstance() {
|
public static CoreBukkitAPI getInstance() {
|
||||||
return (CoreBukkitAPI) instance;
|
return (CoreBukkitAPI) instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
CoreBukkitAPI api = new CoreBukkitAPI();
|
instance = new CoreBukkitAPI();
|
||||||
instance = api;
|
|
||||||
api.audienceProvider = BukkitAudiences.create(HamsterCorePlugin.getInstance());
|
|
||||||
HikariConfig hikariConfig = new HikariConfig();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -38,17 +53,9 @@ public class CoreBukkitAPI extends CoreCommonAPI {
|
|||||||
return datasource;
|
return datasource;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void reportError(@NotNull String projectID, @NotNull Throwable exception) {
|
||||||
public @NotNull Connection getConnection() throws SQLException {
|
|
||||||
return datasource.getConnection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void reportFile(@NotNull String projectID, @NotNull String filename, byte @NotNull [] bytes) {
|
||||||
public void reportError(@NotNull String apiKey, @NotNull String projectID, @NotNull Throwable exception) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reportFile(@NotNull String apiKey, @NotNull String projectID, @NotNull String filename, byte @NotNull [] bytes) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,20 @@
|
|||||||
|
package cn.hamster3.mc.plugin.core.bukkit.command;
|
||||||
|
|
||||||
|
import org.bukkit.command.TabExecutor;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public abstract class ChildCommand implements TabExecutor {
|
||||||
|
@NotNull
|
||||||
|
public abstract String getName();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public abstract String getUsage();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public abstract String getPermission();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public abstract String getDescription();
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,93 @@
|
|||||||
|
package cn.hamster3.mc.plugin.core.bukkit.command;
|
||||||
|
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.constant.CoreMessage;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.command.TabExecutor;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class ParentCommand implements TabExecutor {
|
||||||
|
@NotNull
|
||||||
|
private final String name;
|
||||||
|
@Nullable
|
||||||
|
private final ParentCommand parent;
|
||||||
|
@NotNull
|
||||||
|
private final List<ChildCommand> childCommands;
|
||||||
|
|
||||||
|
public ParentCommand(@NotNull String name) {
|
||||||
|
this.name = name;
|
||||||
|
parent = null;
|
||||||
|
childCommands = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParentCommand(@NotNull String name, @Nullable ParentCommand parent) {
|
||||||
|
this.name = name;
|
||||||
|
this.parent = parent;
|
||||||
|
childCommands = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String getUsage() {
|
||||||
|
if (parent == null) {
|
||||||
|
return "/" + name;
|
||||||
|
}
|
||||||
|
return parent.getUsage() + " " + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public List<ChildCommand> getChildCommands() {
|
||||||
|
return childCommands;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addChildCommand(@NotNull ChildCommand command) {
|
||||||
|
childCommands.add(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||||
|
if (args.length == 0) {
|
||||||
|
sender.sendMessage("§e==================== [" + name + "使用帮助] ====================");
|
||||||
|
int maxLength = childCommands.stream()
|
||||||
|
.filter(o -> o.getPermission() == null || sender.hasPermission(o.getPermission()))
|
||||||
|
.map(o -> o.getUsage().length())
|
||||||
|
.max(Integer::compareTo)
|
||||||
|
.orElse(-1);
|
||||||
|
for (ChildCommand child : childCommands) {
|
||||||
|
String permission = child.getPermission();
|
||||||
|
if (permission != null && !sender.hasPermission(permission)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sender.sendMessage(String.format("§a%s %-" + maxLength + "s - %s", getUsage(), child.getUsage(), child.getDescription()));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (ChildCommand childCommand : childCommands) {
|
||||||
|
if (childCommand.getName().equalsIgnoreCase(args[0])) {
|
||||||
|
return childCommand.onCommand(sender, command, label, Arrays.copyOfRange(args, 1, args.length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CoreMessage.COMMAND_NOT_FOUND.show(sender);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||||
|
for (ChildCommand child : childCommands) {
|
||||||
|
if (args[0].equalsIgnoreCase(child.getName())) {
|
||||||
|
return child.onTabComplete(sender, command, alias, Arrays.copyOfRange(args, 1, args.length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args[0] = args[0].toLowerCase();
|
||||||
|
return childCommands.stream()
|
||||||
|
.map(ChildCommand::getName)
|
||||||
|
.filter(o -> o.toLowerCase().startsWith(args[0]))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,81 @@
|
|||||||
|
package cn.hamster3.mc.plugin.core.bukkit.command.debug;
|
||||||
|
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.command.ChildCommand;
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.constant.CoreMessage;
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.listener.DebugListener;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@SuppressWarnings("SpellCheckingInspection")
|
||||||
|
public class BlockInfoCommand extends ChildCommand {
|
||||||
|
public static final BlockInfoCommand INSTANCE = new BlockInfoCommand();
|
||||||
|
|
||||||
|
private BlockInfoCommand() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getName() {
|
||||||
|
return "blockinfo";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getUsage() {
|
||||||
|
return "blockinfo [on/off]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getPermission() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getDescription() {
|
||||||
|
return "开启方块信息查询模式";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||||
|
if (!(sender instanceof Player)) {
|
||||||
|
CoreMessage.COMMAND_MUST_USED_BY_PLAYER.show(sender);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Player player = (Player) sender;
|
||||||
|
UUID uuid = player.getUniqueId();
|
||||||
|
if (args.length >= 1) {
|
||||||
|
switch (args[0]) {
|
||||||
|
case "1":
|
||||||
|
case "on": {
|
||||||
|
DebugListener.BLOCK_INFO.add(uuid);
|
||||||
|
CoreMessage.COMMAND_DEBUG_BLOCK_INFO_ON.show(player);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case "0":
|
||||||
|
case "off": {
|
||||||
|
DebugListener.BLOCK_INFO.remove(uuid);
|
||||||
|
CoreMessage.COMMAND_DEBUG_BLOCK_INFO_OFF.show(player);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DebugListener.BLOCK_INFO.contains(uuid)) {
|
||||||
|
DebugListener.BLOCK_INFO.remove(uuid);
|
||||||
|
CoreMessage.COMMAND_DEBUG_BLOCK_INFO_OFF.show(player);
|
||||||
|
} else {
|
||||||
|
DebugListener.BLOCK_INFO.add(uuid);
|
||||||
|
CoreMessage.COMMAND_DEBUG_BLOCK_INFO_ON.show(player);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,98 @@
|
|||||||
|
package cn.hamster3.mc.plugin.core.bukkit.command.debug;
|
||||||
|
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.HamsterCorePlugin;
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.command.ChildCommand;
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.util.BukkitUtils;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemFlag;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class YamlCommand extends ChildCommand {
|
||||||
|
public static final YamlCommand INSTANCE = new YamlCommand();
|
||||||
|
|
||||||
|
private YamlCommand() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getName() {
|
||||||
|
return "yaml";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getUsage() {
|
||||||
|
return "yaml";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getPermission() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getDescription() {
|
||||||
|
return "将当前信息保存至 yaml 中";
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||||
|
YamlConfiguration config = new YamlConfiguration();
|
||||||
|
config.set("mc-version", BukkitUtils.getMCVersion());
|
||||||
|
config.set("nms-version", BukkitUtils.getNMSVersion());
|
||||||
|
config.set("server-version", Bukkit.getBukkitVersion());
|
||||||
|
config.set("bukkit-version", Bukkit.getVersion());
|
||||||
|
|
||||||
|
if (sender instanceof Player) {
|
||||||
|
Player player = (Player) sender;
|
||||||
|
config.set("player-name", player.getName());
|
||||||
|
config.set("player-uuid", player.getUniqueId().toString());
|
||||||
|
config.set("location", player.getLocation());
|
||||||
|
config.set("hand-item", player.getInventory().getItemInHand());
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack stack = new ItemStack(Material.DIAMOND_SWORD);
|
||||||
|
ItemMeta meta = stack.getItemMeta();
|
||||||
|
List<String> lore = new ArrayList<>();
|
||||||
|
lore.add("§e测试 lore 1");
|
||||||
|
lore.add("§e测试 lore 2");
|
||||||
|
lore.add("§e测试 lore 3");
|
||||||
|
meta.addEnchant(Enchantment.DAMAGE_ALL, 1, true);
|
||||||
|
meta.setDisplayName("§a测试物品");
|
||||||
|
meta.setLore(lore);
|
||||||
|
meta.addItemFlags(ItemFlag.values());
|
||||||
|
stack.setItemMeta(meta);
|
||||||
|
config.set("test-item", stack);
|
||||||
|
File dataFolder = new File(HamsterCorePlugin.getInstance().getDataFolder(), "yaml");
|
||||||
|
if (dataFolder.mkdirs()) {
|
||||||
|
HamsterCorePlugin.getInstance().getLogger().info("创建 yaml 存档文件夹...");
|
||||||
|
}
|
||||||
|
File saveFile = new File(dataFolder, sender.getName() + "_" + System.currentTimeMillis() + ".yml");
|
||||||
|
try {
|
||||||
|
config.save(saveFile);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
sender.sendMessage("§a信息已保存至文件 " + saveFile.getAbsolutePath());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,20 @@
|
|||||||
|
package cn.hamster3.mc.plugin.core.bukkit.constant;
|
||||||
|
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
public enum CoreMessage {
|
||||||
|
COMMAND_NOT_FOUND,
|
||||||
|
COMMAND_MUST_USED_BY_PLAYER,
|
||||||
|
|
||||||
|
COMMAND_DEBUG_BLOCK_INFO_ON,
|
||||||
|
COMMAND_DEBUG_BLOCK_INFO_OFF;
|
||||||
|
|
||||||
|
public void show(CommandSender sender) {
|
||||||
|
sender.sendMessage(name());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show(Player player) {
|
||||||
|
player.sendMessage(name());
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,158 @@
|
|||||||
|
package cn.hamster3.mc.plugin.core.bukkit.hook;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vault Economy API
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class EconomyAPI {
|
||||||
|
private EconomyAPI() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回服务器是否安装了经济插件
|
||||||
|
*
|
||||||
|
* @return true代表安装了,false代表未安装
|
||||||
|
*/
|
||||||
|
public static boolean isSetupEconomy() {
|
||||||
|
return VaultAPI.isSetupVault() && VaultAPI.getEconomy() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给玩家钱
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @param money 钱的数量
|
||||||
|
* @return 成功则返回 true
|
||||||
|
*/
|
||||||
|
public static boolean giveMoney(@NotNull final OfflinePlayer player, final double money) {
|
||||||
|
if (isSetupEconomy()) {
|
||||||
|
return VaultAPI.getEconomy().depositPlayer(player, money).transactionSuccess();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给玩家钱
|
||||||
|
*
|
||||||
|
* @param uuid 玩家的uuid
|
||||||
|
* @param money 钱的数量
|
||||||
|
* @return 成功则返回 true
|
||||||
|
*/
|
||||||
|
public static boolean giveMoney(@NotNull final UUID uuid, final double money) {
|
||||||
|
return giveMoney(Bukkit.getOfflinePlayer(uuid), money);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从玩家账户上扣钱
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @param money 钱的数量
|
||||||
|
* @return 成功则返回 true
|
||||||
|
*/
|
||||||
|
public static boolean takeMoney(@NotNull final OfflinePlayer player, final double money) {
|
||||||
|
if (isSetupEconomy()) {
|
||||||
|
return VaultAPI.getEconomy().withdrawPlayer(player, money).transactionSuccess();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从玩家账户上扣钱
|
||||||
|
*
|
||||||
|
* @param uuid 玩家的uuid
|
||||||
|
* @param money 钱的数量
|
||||||
|
* @return 成功则返回 true
|
||||||
|
*/
|
||||||
|
public static boolean takeMoney(@NotNull final UUID uuid, final double money) {
|
||||||
|
return takeMoney(Bukkit.getOfflinePlayer(uuid), money);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置玩家的余额
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @param money 钱的数量
|
||||||
|
* @return 成功则返回 true
|
||||||
|
*/
|
||||||
|
public static boolean setMoney(@NotNull OfflinePlayer player, final double money) {
|
||||||
|
if (!isSetupEconomy()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
double v = seeMoney(player);
|
||||||
|
if (v > money) {
|
||||||
|
return takeMoney(player, v - money);
|
||||||
|
} else if (v < money) {
|
||||||
|
return giveMoney(player, money - v);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置玩家的余额
|
||||||
|
*
|
||||||
|
* @param uuid 玩家的uuid
|
||||||
|
* @param money 钱的数量
|
||||||
|
* @return 成功则返回 true
|
||||||
|
*/
|
||||||
|
public static boolean setMoney(@NotNull final UUID uuid, final double money) {
|
||||||
|
return setMoney(Bukkit.getOfflinePlayer(uuid), money);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查玩家有多少钱
|
||||||
|
* <p>
|
||||||
|
* 若没有安装经济插件则返回NaN
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @return 玩家的余额
|
||||||
|
*/
|
||||||
|
public static double seeMoney(@NotNull final OfflinePlayer player) {
|
||||||
|
if (!isSetupEconomy()) {
|
||||||
|
return Double.NaN;
|
||||||
|
}
|
||||||
|
return VaultAPI.getEconomy().getBalance(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查玩家有多少钱
|
||||||
|
* <p>
|
||||||
|
* 若没有安装经济插件则返回NaN
|
||||||
|
*
|
||||||
|
* @param uuid 玩家的uuid
|
||||||
|
* @return 玩家的余额
|
||||||
|
*/
|
||||||
|
public static double seeMoney(@NotNull final UUID uuid) {
|
||||||
|
return seeMoney(Bukkit.getOfflinePlayer(uuid));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测玩家是否有足够的钱
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @param money 金钱的数量
|
||||||
|
* @return 是否有足够的钱(若没有安装经济插件则直接返回 false
|
||||||
|
*/
|
||||||
|
public static boolean hasMoney(@NotNull final OfflinePlayer player, final double money) {
|
||||||
|
if (!isSetupEconomy()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return VaultAPI.getEconomy().has(player, money);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测玩家是否有足够的钱
|
||||||
|
*
|
||||||
|
* @param uuid 玩家的uuid
|
||||||
|
* @param money 金钱的数量
|
||||||
|
* @return 是否有足够的钱(若没有安装经济插件则直接返回 false
|
||||||
|
*/
|
||||||
|
public static boolean hasMoney(@NotNull final UUID uuid, final double money) {
|
||||||
|
return hasMoney(Bukkit.getOfflinePlayer(uuid), money);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,178 @@
|
|||||||
|
package cn.hamster3.mc.plugin.core.bukkit.hook;
|
||||||
|
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.HamsterCorePlugin;
|
||||||
|
import org.black_ixx.playerpoints.PlayerPoints;
|
||||||
|
import org.black_ixx.playerpoints.PlayerPointsAPI;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PlayerPointsAPI
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class PointAPI {
|
||||||
|
private static PlayerPointsAPI playerPointsAPI;
|
||||||
|
|
||||||
|
private PointAPI() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重载 PlayerPointAPI 点券系统挂接
|
||||||
|
*/
|
||||||
|
public static void reloadPlayerPointAPIHook() {
|
||||||
|
Plugin plugin = Bukkit.getPluginManager().getPlugin("PlayerPoints");
|
||||||
|
if (plugin == null) {
|
||||||
|
HamsterCorePlugin.getInstance().getLogger().warning("未检测到 PlayerPointAPI 插件!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
playerPointsAPI = ((PlayerPoints) plugin).getAPI();
|
||||||
|
HamsterCorePlugin.getInstance().getLogger().info("PlayerPointAPI 挂接成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 PlayerPointsAPI 实例
|
||||||
|
*
|
||||||
|
* @return PlayerPointsAPI 实例
|
||||||
|
*/
|
||||||
|
public static PlayerPointsAPI getPlayerPointsAPI() {
|
||||||
|
return playerPointsAPI;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回服务器是否安装了 PlayerPointAPI 插件
|
||||||
|
*
|
||||||
|
* @return true代表安装了,false代表未安装
|
||||||
|
*/
|
||||||
|
public static boolean isSetupPlayerPointAPI() {
|
||||||
|
return playerPointsAPI != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给予玩家点券
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @param point 点券数量
|
||||||
|
*/
|
||||||
|
public static void givePoint(final OfflinePlayer player, final int point) {
|
||||||
|
if (playerPointsAPI != null) {
|
||||||
|
playerPointsAPI.give(player.getUniqueId(), point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给予玩家点券
|
||||||
|
*
|
||||||
|
* @param uuid 玩家的uuid
|
||||||
|
* @param point 点券数量
|
||||||
|
*/
|
||||||
|
public static void givePoint(final UUID uuid, final int point) {
|
||||||
|
if (playerPointsAPI != null) {
|
||||||
|
playerPointsAPI.give(uuid, point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扣除玩家点券
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @param point 点券数量
|
||||||
|
*/
|
||||||
|
public static void takePoint(final OfflinePlayer player, final int point) {
|
||||||
|
if (playerPointsAPI != null) {
|
||||||
|
playerPointsAPI.take(player.getUniqueId(), point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扣除玩家点券
|
||||||
|
*
|
||||||
|
* @param uuid 玩家的uuid
|
||||||
|
* @param point 点券数量
|
||||||
|
*/
|
||||||
|
public static void takePoint(final UUID uuid, final int point) {
|
||||||
|
if (playerPointsAPI != null) {
|
||||||
|
playerPointsAPI.take(uuid, point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置玩家的点券
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @param point 点券数量
|
||||||
|
*/
|
||||||
|
public static void setPoint(final OfflinePlayer player, final int point) {
|
||||||
|
if (playerPointsAPI != null) {
|
||||||
|
playerPointsAPI.set(player.getUniqueId(), point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置玩家的点券
|
||||||
|
*
|
||||||
|
* @param uuid 玩家的uuid
|
||||||
|
* @param point 点券数量
|
||||||
|
*/
|
||||||
|
public static void setPoint(final UUID uuid, final int point) {
|
||||||
|
if (playerPointsAPI != null) {
|
||||||
|
playerPointsAPI.set(uuid, point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看玩家的点券数量
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @return 玩家的点券数量
|
||||||
|
*/
|
||||||
|
public static int seePoint(final OfflinePlayer player) {
|
||||||
|
if (playerPointsAPI != null) {
|
||||||
|
return playerPointsAPI.look(player.getUniqueId());
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看玩家的点券数量
|
||||||
|
*
|
||||||
|
* @param uuid 玩家的uuid
|
||||||
|
* @return 玩家的点券数量
|
||||||
|
*/
|
||||||
|
public static int seePoint(final UUID uuid) {
|
||||||
|
if (playerPointsAPI != null) {
|
||||||
|
return playerPointsAPI.look(uuid);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查玩家是否有足够的点券
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @param point 点券数量
|
||||||
|
* @return 若未安装 PlayerPointAPI 则直接返回 false
|
||||||
|
*/
|
||||||
|
public static boolean hasPoint(final OfflinePlayer player, final int point) {
|
||||||
|
if (playerPointsAPI != null) {
|
||||||
|
return playerPointsAPI.look(player.getUniqueId()) >= point;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查玩家是否有足够的点券
|
||||||
|
*
|
||||||
|
* @param uuid 玩家的uuid
|
||||||
|
* @param point 点券数量
|
||||||
|
* @return 若未安装 PlayerPointAPI 则直接返回 false
|
||||||
|
*/
|
||||||
|
public static boolean hasPoint(final UUID uuid, final int point) {
|
||||||
|
if (playerPointsAPI != null) {
|
||||||
|
return playerPointsAPI.look(uuid) >= point;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,96 @@
|
|||||||
|
package cn.hamster3.mc.plugin.core.bukkit.hook;
|
||||||
|
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.HamsterCorePlugin;
|
||||||
|
import net.milkbowl.vault.chat.Chat;
|
||||||
|
import net.milkbowl.vault.economy.Economy;
|
||||||
|
import net.milkbowl.vault.permission.Permission;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vault API
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class VaultAPI {
|
||||||
|
private static boolean vaultEnabled;
|
||||||
|
private static Chat chat;
|
||||||
|
private static Economy economy;
|
||||||
|
private static Permission permission;
|
||||||
|
|
||||||
|
private VaultAPI() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void reloadVaultHook() {
|
||||||
|
chat = null;
|
||||||
|
economy = null;
|
||||||
|
permission = null;
|
||||||
|
vaultEnabled = Bukkit.getPluginManager().isPluginEnabled("Vault");
|
||||||
|
if (!vaultEnabled) {
|
||||||
|
HamsterCorePlugin.getInstance().getLogger().warning("未检测到 Vault 插件!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
HamsterCorePlugin.getInstance().getLogger().info("已连接 Vault!");
|
||||||
|
|
||||||
|
RegisteredServiceProvider<Chat> chatProvider = Bukkit.getServer().getServicesManager().getRegistration(Chat.class);
|
||||||
|
|
||||||
|
if (chatProvider != null) {
|
||||||
|
chat = chatProvider.getProvider();
|
||||||
|
HamsterCorePlugin.getInstance().getLogger().info("聊天系统挂接成功.");
|
||||||
|
} else {
|
||||||
|
HamsterCorePlugin.getInstance().getLogger().warning("未检测到聊天系统!");
|
||||||
|
}
|
||||||
|
|
||||||
|
RegisteredServiceProvider<Economy> economyProvider = Bukkit.getServer().getServicesManager().getRegistration(Economy.class);
|
||||||
|
if (economyProvider != null) {
|
||||||
|
economy = economyProvider.getProvider();
|
||||||
|
HamsterCorePlugin.getInstance().getLogger().info("经济系统挂接成功.");
|
||||||
|
} else {
|
||||||
|
HamsterCorePlugin.getInstance().getLogger().warning("未检测到经济系统!");
|
||||||
|
}
|
||||||
|
|
||||||
|
RegisteredServiceProvider<Permission> permissionProvider = Bukkit.getServer().getServicesManager().getRegistration(Permission.class);
|
||||||
|
if (permissionProvider != null) {
|
||||||
|
permission = permissionProvider.getProvider();
|
||||||
|
HamsterCorePlugin.getInstance().getLogger().info("权限系统挂接成功.");
|
||||||
|
} else {
|
||||||
|
HamsterCorePlugin.getInstance().getLogger().warning("未检测到权限插件!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回服务器是否安装了 Vault 插件
|
||||||
|
*
|
||||||
|
* @return true 代表服务器已安装
|
||||||
|
*/
|
||||||
|
public static boolean isSetupVault() {
|
||||||
|
return vaultEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回 Vault 的 Chat 前置系统
|
||||||
|
*
|
||||||
|
* @return Chat 系统
|
||||||
|
*/
|
||||||
|
public static Chat getChat() {
|
||||||
|
return chat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回 Vault 的 Economy 前置系统
|
||||||
|
*
|
||||||
|
* @return Economy 系统
|
||||||
|
*/
|
||||||
|
public static Economy getEconomy() {
|
||||||
|
return economy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回 Vault 的 Permission 前置系统
|
||||||
|
*
|
||||||
|
* @return Permission 系统
|
||||||
|
*/
|
||||||
|
public static Permission getPermission() {
|
||||||
|
return permission;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,78 @@
|
|||||||
|
package cn.hamster3.mc.plugin.core.bukkit.listener;
|
||||||
|
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
|
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class CallbackListener implements Listener {
|
||||||
|
public static final CallbackListener INSTANCE = new CallbackListener();
|
||||||
|
|
||||||
|
public static final HashMap<UUID, CompletableFuture<String>> CHATS = new HashMap<>();
|
||||||
|
public static final HashMap<UUID, CompletableFuture<Block>> BLOCKS = new HashMap<>();
|
||||||
|
public static final HashMap<UUID, CompletableFuture<Entity>> ENTITIES = new HashMap<>();
|
||||||
|
|
||||||
|
private CallbackListener() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(ignoreCancelled = true)
|
||||||
|
public void onAsyncPlayerChat(AsyncPlayerChatEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
CompletableFuture<String> future = CHATS.remove(player.getUniqueId());
|
||||||
|
if (future == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
future.complete(event.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(ignoreCancelled = true)
|
||||||
|
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||||
|
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
CompletableFuture<Block> future = BLOCKS.remove(player.getUniqueId());
|
||||||
|
if (future == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
future.complete(event.getClickedBlock());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(ignoreCancelled = true)
|
||||||
|
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
CompletableFuture<Entity> future = ENTITIES.remove(player.getUniqueId());
|
||||||
|
if (future == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
future.complete(event.getRightClicked());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(ignoreCancelled = true)
|
||||||
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
UUID uuid = player.getUniqueId();
|
||||||
|
CompletableFuture<String> chat = CHATS.remove(uuid);
|
||||||
|
if (chat != null) {
|
||||||
|
chat.cancel(true);
|
||||||
|
}
|
||||||
|
CompletableFuture<Block> block = BLOCKS.remove(uuid);
|
||||||
|
if (block != null) {
|
||||||
|
block.cancel(true);
|
||||||
|
}
|
||||||
|
CompletableFuture<Entity> entity = ENTITIES.remove(uuid);
|
||||||
|
if (entity != null) {
|
||||||
|
entity.cancel(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,57 @@
|
|||||||
|
package cn.hamster3.mc.plugin.core.bukkit.listener;
|
||||||
|
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class DebugListener implements Listener {
|
||||||
|
public static final DebugListener INSTANCE = new DebugListener();
|
||||||
|
/**
|
||||||
|
* 要查看方块信息的玩家
|
||||||
|
*/
|
||||||
|
public static final HashSet<UUID> BLOCK_INFO = new HashSet<>();
|
||||||
|
|
||||||
|
private DebugListener() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(ignoreCancelled = true)
|
||||||
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
UUID uuid = player.getUniqueId();
|
||||||
|
BLOCK_INFO.remove(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(ignoreCancelled = true)
|
||||||
|
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
UUID uuid = player.getUniqueId();
|
||||||
|
if (!BLOCK_INFO.contains(uuid)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (event.getAction()) {
|
||||||
|
case LEFT_CLICK_BLOCK:
|
||||||
|
case LEFT_CLICK_AIR: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Block block = event.getClickedBlock();
|
||||||
|
player.sendMessage("§e==============================");
|
||||||
|
player.sendMessage(String.format("§a方块位置: %s %d %d %d", block.getWorld().getName(), block.getX(), block.getY(), block.getZ()));
|
||||||
|
player.sendMessage("§a方块材质: " + block.getType().name());
|
||||||
|
player.sendMessage("§a方块能量: " + block.getBlockPower());
|
||||||
|
player.sendMessage("§a方块湿度: " + block.getHumidity());
|
||||||
|
player.sendMessage("§a自发光亮度: " + block.getLightLevel());
|
||||||
|
player.sendMessage("§a获取天空亮度: " + block.getLightFromSky());
|
||||||
|
player.sendMessage("§a方块吸收亮度: " + block.getLightFromBlocks());
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
@@ -1,9 +1,9 @@
|
|||||||
package cn.hamster3.mc.plugin.core.bukkit.page.handler;
|
package cn.hamster3.mc.plugin.core.bukkit.page.handler;
|
||||||
|
|
||||||
import cn.hamster3.mc.plugin.core.bukkit.page.ButtonGroup;
|
|
||||||
import cn.hamster3.mc.plugin.core.bukkit.page.PageManager;
|
|
||||||
import cn.hamster3.mc.plugin.core.bukkit.HamsterCorePlugin;
|
import cn.hamster3.mc.plugin.core.bukkit.HamsterCorePlugin;
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.page.ButtonGroup;
|
||||||
import cn.hamster3.mc.plugin.core.bukkit.page.PageConfig;
|
import cn.hamster3.mc.plugin.core.bukkit.page.PageConfig;
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.page.PageManager;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
package cn.hamster3.mc.plugin.core.bukkit.page.handler;
|
package cn.hamster3.mc.plugin.core.bukkit.page.handler;
|
||||||
|
|
||||||
import cn.hamster3.mc.plugin.core.bukkit.page.ButtonGroup;
|
import cn.hamster3.mc.plugin.core.bukkit.page.ButtonGroup;
|
||||||
import cn.hamster3.mc.plugin.core.bukkit.page.PageElement;
|
|
||||||
import cn.hamster3.mc.plugin.core.bukkit.page.PageConfig;
|
import cn.hamster3.mc.plugin.core.bukkit.page.PageConfig;
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.page.PageElement;
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
import org.bukkit.event.inventory.ClickType;
|
import org.bukkit.event.inventory.ClickType;
|
||||||
import org.bukkit.event.inventory.InventoryAction;
|
import org.bukkit.event.inventory.InventoryAction;
|
||||||
|
@@ -1,12 +1,9 @@
|
|||||||
package cn.hamster3.mc.plugin.core.bukkit.util;
|
package cn.hamster3.mc.plugin.core.bukkit.util;
|
||||||
|
|
||||||
import com.zaxxer.hikari.HikariConfig;
|
|
||||||
import com.zaxxer.hikari.HikariDataSource;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
@@ -17,7 +14,10 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class BukkitUtils {
|
public final class BukkitUtils {
|
||||||
|
private BukkitUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static String getMCVersion() {
|
public static String getMCVersion() {
|
||||||
return Bukkit.getBukkitVersion().split("-")[0];
|
return Bukkit.getBukkitVersion().split("-")[0];
|
||||||
@@ -68,8 +68,10 @@ public class BukkitUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取玩家的头颅
|
* 获取玩家的头颅
|
||||||
* 在1.11以上的服务端中获取头颅材质是在服务器上运行的
|
* <p>
|
||||||
* 因此建议使用异步线程调用该方法
|
* 在 1.11 以上的服务端建议使用异步线程调用该方法
|
||||||
|
* <p>
|
||||||
|
* 因为这些服务端中通过网络获取头颅材质是在服务器上运行的
|
||||||
*
|
*
|
||||||
* @param offlinePlayer 要获取的玩家
|
* @param offlinePlayer 要获取的玩家
|
||||||
* @return 玩家的头颅物品
|
* @return 玩家的头颅物品
|
||||||
@@ -165,30 +167,4 @@ public class BukkitUtils {
|
|||||||
}
|
}
|
||||||
return stack.getType().name();
|
return stack.getType().name();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建 SQL 连接池
|
|
||||||
*
|
|
||||||
* @param config SQL 配置
|
|
||||||
* @return SQL 连接池
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
public static HikariDataSource getHikariDataSource(@NotNull ConfigurationSection config) {
|
|
||||||
HikariConfig hikariConfig = new HikariConfig();
|
|
||||||
|
|
||||||
hikariConfig.setDriverClassName(config.getString("driver"));
|
|
||||||
|
|
||||||
hikariConfig.setJdbcUrl(config.getString("url"));
|
|
||||||
hikariConfig.setUsername(config.getString("user"));
|
|
||||||
hikariConfig.setPassword(config.getString("password"));
|
|
||||||
|
|
||||||
hikariConfig.setMaximumPoolSize(config.getInt("maximumPoolSize", 3));
|
|
||||||
hikariConfig.setMinimumIdle(config.getInt("minimumIdle", 1));
|
|
||||||
hikariConfig.setIdleTimeout(config.getLong("idleTimeout", 5 * 60 * 1000));
|
|
||||||
hikariConfig.setMaxLifetime(config.getLong("maxLifetime", 0));
|
|
||||||
|
|
||||||
return new HikariDataSource(hikariConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo public static TextComponent getItemDisplayInfo(@NotNull ItemStack stack)
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,26 @@
|
|||||||
|
package cn.hamster3.mc.plugin.core.bukkit.util;
|
||||||
|
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.listener.CallbackListener;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.HumanEntity;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public final class CallbackUtils {
|
||||||
|
private CallbackUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CompletableFuture<String> getPlayerChat(HumanEntity player) {
|
||||||
|
return CallbackListener.CHATS.computeIfAbsent(player.getUniqueId(), o -> new CompletableFuture<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CompletableFuture<Block> getPlayerClickedBlock(HumanEntity player) {
|
||||||
|
return CallbackListener.BLOCKS.computeIfAbsent(player.getUniqueId(), o -> new CompletableFuture<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CompletableFuture<Entity> getPlayerClickedEntity(HumanEntity player) {
|
||||||
|
return CallbackListener.ENTITIES.computeIfAbsent(player.getUniqueId(), o -> new CompletableFuture<>());
|
||||||
|
}
|
||||||
|
}
|
23
hamster-core-bukkit/src/main/resources/config.yml
Normal file
23
hamster-core-bukkit/src/main/resources/config.yml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
datasource:
|
||||||
|
# 数据库链接驱动地址
|
||||||
|
# 除非你知道自己在做什么,否则不建议更改该项
|
||||||
|
driver: "com.mysql.cj.jdbc.Driver"
|
||||||
|
# 数据库链接填写格式:
|
||||||
|
# jdbc:mysql://{数据库地址}:{数据库端口}/{使用的库名}?参数
|
||||||
|
# 除非你知道自己在做什么,否则不建议随意更改参数
|
||||||
|
url: "jdbc:mysql://sql.hamster3.cn:3306/Test1?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false"
|
||||||
|
# 用户名
|
||||||
|
username: "Test"
|
||||||
|
# 密码
|
||||||
|
password: "Test123.."
|
||||||
|
# 最大链接数
|
||||||
|
maximum-pool-size: 10
|
||||||
|
# 最小链接数
|
||||||
|
minimum-idle: 1
|
||||||
|
# 超时回收时间
|
||||||
|
# 单位:毫秒
|
||||||
|
idle-timeout: 300000
|
||||||
|
# 链接最长存活时间
|
||||||
|
# 单位:毫秒
|
||||||
|
# 建议设置为比数据库上的 wait_timeout 参数少 30 秒
|
||||||
|
max-lifetime: 1800000
|
@@ -1,3 +1,22 @@
|
|||||||
name: HamsterCore
|
name: HamsterCore
|
||||||
main: cn.hamster3.mc.plugin.core.bukkit.HamsterCorePlugin
|
main: cn.hamster3.mc.plugin.core.bukkit.HamsterCorePlugin
|
||||||
version: ${version}
|
version: ${version}
|
||||||
|
|
||||||
|
author: MiniDay
|
||||||
|
website: https://github.com/MiniDay/hamster-core
|
||||||
|
description: 仓鼠核心:Minecraft 插件开发通用工具包
|
||||||
|
|
||||||
|
softdepend:
|
||||||
|
- Vault
|
||||||
|
- PlayerPoints
|
||||||
|
|
||||||
|
commands:
|
||||||
|
hamstercore:
|
||||||
|
aliases: [ hcore, core ]
|
||||||
|
description: 仓鼠核心调试指令
|
||||||
|
permission: hamster.core.admin
|
||||||
|
permission-message: §c你没有这个权限!
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
hamster.core.admin:
|
||||||
|
default: op
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
setArchivesBaseName("HamsterCore-Proxy")
|
setArchivesBaseName("HamsterCore-BungeeCord")
|
||||||
|
|
||||||
evaluationDependsOn(':hamster-core-common')
|
evaluationDependsOn(':hamster-core-common')
|
||||||
|
|
||||||
@@ -8,21 +8,16 @@ dependencies {
|
|||||||
}
|
}
|
||||||
//noinspection GradlePackageUpdate
|
//noinspection GradlePackageUpdate
|
||||||
compileOnly('net.md-5:bungeecord-api:1.17-R0.1-SNAPSHOT')
|
compileOnly('net.md-5:bungeecord-api:1.17-R0.1-SNAPSHOT')
|
||||||
|
// https://mvnrepository.com/artifact/net.kyori/adventure-platform-bungeecord
|
||||||
|
apiShade 'net.kyori:adventure-platform-bungeecord:4.1.2'
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/com.zaxxer/HikariCP
|
// https://mvnrepository.com/artifact/com.zaxxer/HikariCP
|
||||||
//noinspection GradlePackageUpdate
|
//noinspection GradlePackageUpdate
|
||||||
apiShade 'com.zaxxer:HikariCP:4.0.3'
|
apiShade 'com.zaxxer:HikariCP:4.0.3'
|
||||||
|
// https://mvnrepository.com/artifact/mysql/mysql-connector-java
|
||||||
|
shade 'mysql:mysql-connector-java:8.0.31'
|
||||||
// https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp
|
// https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp
|
||||||
apiShade 'com.squareup.okhttp3:okhttp:4.10.0'
|
apiShade 'com.squareup.okhttp3:okhttp:4.10.0'
|
||||||
// https://mvnrepository.com/artifact/net.kyori/adventure-platform-bungeecord
|
|
||||||
apiShade 'net.kyori:adventure-platform-bungeecord:4.1.2'
|
|
||||||
|
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0'
|
|
||||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
|
|
||||||
}
|
|
||||||
|
|
||||||
test {
|
|
||||||
useJUnitPlatform()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
@@ -39,11 +34,14 @@ tasks.create("shadowJar", Jar) {
|
|||||||
tasks.jar.outputs.files.collect {
|
tasks.jar.outputs.files.collect {
|
||||||
it.isDirectory() ? it : zipTree(it)
|
it.isDirectory() ? it : zipTree(it)
|
||||||
},
|
},
|
||||||
configurations.implementationShade.collect {
|
configurations.shade.collect {
|
||||||
it.isDirectory() ? it : zipTree(it)
|
it.isDirectory() ? it : zipTree(it)
|
||||||
},
|
},
|
||||||
configurations.apiShade.collect {
|
configurations.apiShade.collect {
|
||||||
it.isDirectory() ? it : zipTree(it)
|
it.isDirectory() ? it : zipTree(it)
|
||||||
|
},
|
||||||
|
configurations.implementationShade.collect {
|
||||||
|
it.isDirectory() ? it : zipTree(it)
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
destinationDir(getRootProject().buildDir)
|
destinationDir(getRootProject().buildDir)
|
@@ -1,8 +1,11 @@
|
|||||||
package cn.hamster3.mc.plugin.core.proxy;
|
package cn.hamster3.mc.plugin.core.bungee;
|
||||||
|
|
||||||
|
import cn.hamster3.mc.plugin.core.bungee.api.CoreBungeeAPI;
|
||||||
import cn.hamster3.mc.plugin.core.common.constant.CoreConstantObjects;
|
import cn.hamster3.mc.plugin.core.common.constant.CoreConstantObjects;
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class HamsterCorePlugin extends Plugin {
|
public class HamsterCorePlugin extends Plugin {
|
||||||
private static HamsterCorePlugin instance;
|
private static HamsterCorePlugin instance;
|
||||||
|
|
||||||
@@ -17,21 +20,25 @@ public class HamsterCorePlugin extends Plugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
|
Logger logger = getLogger();
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
getLogger().info("仓鼠核心正在启动...");
|
logger.info("仓鼠核心正在启动...");
|
||||||
|
CoreBungeeAPI.init();
|
||||||
|
logger.info("CoreAPI 已初始化.");
|
||||||
long time = System.currentTimeMillis() - start;
|
long time = System.currentTimeMillis() - start;
|
||||||
getLogger().info("仓鼠核心已启动,总计耗时 " + time + " ms.");
|
logger.info("仓鼠核心已启动,总计耗时 " + time + " ms.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
|
Logger logger = getLogger();
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
getLogger().info("仓鼠核心正在关闭...");
|
logger.info("仓鼠核心正在关闭...");
|
||||||
CoreConstantObjects.WORKER_EXECUTOR.shutdownNow();
|
CoreConstantObjects.WORKER_EXECUTOR.shutdownNow();
|
||||||
getLogger().info("已暂停 WORKER_EXECUTOR.");
|
logger.info("已暂停 WORKER_EXECUTOR.");
|
||||||
CoreConstantObjects.SCHEDULED_EXECUTOR.shutdownNow();
|
CoreConstantObjects.SCHEDULED_EXECUTOR.shutdownNow();
|
||||||
getLogger().info("已暂停 SCHEDULED_EXECUTOR.");
|
logger.info("已暂停 SCHEDULED_EXECUTOR.");
|
||||||
long time = System.currentTimeMillis() - start;
|
long time = System.currentTimeMillis() - start;
|
||||||
getLogger().info("仓鼠核心已关闭,总计耗时 " + time + " ms.");
|
logger.info("仓鼠核心已关闭,总计耗时 " + time + " ms.");
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -0,0 +1,54 @@
|
|||||||
|
package cn.hamster3.mc.plugin.core.bungee.api;
|
||||||
|
|
||||||
|
import cn.hamster3.mc.plugin.core.bungee.HamsterCorePlugin;
|
||||||
|
import cn.hamster3.mc.plugin.core.bungee.util.BungeeCordUtils;
|
||||||
|
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
||||||
|
import com.zaxxer.hikari.HikariConfig;
|
||||||
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
|
import net.kyori.adventure.platform.AudienceProvider;
|
||||||
|
import net.kyori.adventure.platform.bungeecord.BungeeAudiences;
|
||||||
|
import net.md_5.bungee.config.Configuration;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class CoreBungeeAPI extends CoreAPI {
|
||||||
|
private final BungeeAudiences audienceProvider;
|
||||||
|
private final HikariDataSource datasource;
|
||||||
|
|
||||||
|
public CoreBungeeAPI() {
|
||||||
|
HamsterCorePlugin plugin = HamsterCorePlugin.getInstance();
|
||||||
|
audienceProvider = BungeeAudiences.create(plugin);
|
||||||
|
|
||||||
|
Configuration config = BungeeCordUtils.getPluginConfig(plugin);
|
||||||
|
|
||||||
|
Configuration datasourceConfig = config.getSection("datasource");
|
||||||
|
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));
|
||||||
|
hikariConfig.setIdleTimeout(datasourceConfig.getLong("idle-timeout", 5 * 60 * 1000));
|
||||||
|
hikariConfig.setMaxLifetime(datasourceConfig.getLong("max-lifetime", 0));
|
||||||
|
datasource = new HikariDataSource(hikariConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CoreBungeeAPI getInstance() {
|
||||||
|
return (CoreBungeeAPI) instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
instance = new CoreBungeeAPI();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull AudienceProvider getAudienceProvider() {
|
||||||
|
return audienceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull HikariDataSource getDataSource() {
|
||||||
|
return datasource;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,43 @@
|
|||||||
|
package cn.hamster3.mc.plugin.core.bungee.util;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
|
import net.md_5.bungee.config.Configuration;
|
||||||
|
import net.md_5.bungee.config.ConfigurationProvider;
|
||||||
|
import net.md_5.bungee.config.YamlConfiguration;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
|
||||||
|
public final class BungeeCordUtils {
|
||||||
|
private BungeeCordUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Configuration getPluginConfig(Plugin plugin) {
|
||||||
|
File configFile = new File(plugin.getDataFolder(), "config.yml");
|
||||||
|
if (!configFile.exists()) {
|
||||||
|
return saveDefaultConfig(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Configuration saveDefaultConfig(Plugin plugin) {
|
||||||
|
try {
|
||||||
|
if (plugin.getDataFolder().mkdir()) {
|
||||||
|
plugin.getLogger().info("创建插件文件夹...");
|
||||||
|
}
|
||||||
|
File configFile = new File(plugin.getDataFolder(), "config.yml");
|
||||||
|
InputStream in = plugin.getResourceAsStream("config.yml");
|
||||||
|
Files.copy(in, configFile.toPath());
|
||||||
|
return ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
3
hamster-core-bungeecord/src/main/resources/bungee.yml
Normal file
3
hamster-core-bungeecord/src/main/resources/bungee.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
name: HamsterCore-BungeeCord
|
||||||
|
main: cn.hamster3.mc.plugin.core.bungee.HamsterCorePlugin
|
||||||
|
version: ${version}
|
23
hamster-core-bungeecord/src/main/resources/config.yml
Normal file
23
hamster-core-bungeecord/src/main/resources/config.yml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
datasource:
|
||||||
|
# 数据库链接驱动地址
|
||||||
|
# 除非你知道自己在做什么,否则不建议更改该项
|
||||||
|
driver: "com.mysql.cj.jdbc.Driver"
|
||||||
|
# 数据库链接填写格式:
|
||||||
|
# jdbc:mysql://{数据库地址}:{数据库端口}/{使用的库名}?参数
|
||||||
|
# 除非你知道自己在做什么,否则不建议随意更改参数
|
||||||
|
url: "jdbc:mysql://sql.hamster3.cn:3306/Test1?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false"
|
||||||
|
# 用户名
|
||||||
|
username: "Test"
|
||||||
|
# 密码
|
||||||
|
password: "Test123.."
|
||||||
|
# 最大链接数
|
||||||
|
maximum-pool-size: 10
|
||||||
|
# 最小链接数
|
||||||
|
minimum-idle: 1
|
||||||
|
# 超时回收时间
|
||||||
|
# 单位:毫秒
|
||||||
|
idle-timeout: 300000
|
||||||
|
# 链接最长存活时间
|
||||||
|
# 单位:毫秒
|
||||||
|
# 建议设置为比数据库上的 wait_timeout 参数少 30 秒
|
||||||
|
max-lifetime: 1800000
|
@@ -13,7 +13,7 @@ dependencies {
|
|||||||
// https://mvnrepository.com/artifact/net.kyori/adventure-text-minimessage
|
// https://mvnrepository.com/artifact/net.kyori/adventure-text-minimessage
|
||||||
api 'net.kyori:adventure-text-minimessage:4.11.0'
|
api 'net.kyori:adventure-text-minimessage:4.11.0'
|
||||||
// https://mvnrepository.com/artifact/net.kyori/adventure-platform-api
|
// https://mvnrepository.com/artifact/net.kyori/adventure-platform-api
|
||||||
implementation 'net.kyori:adventure-platform-api:4.1.2'
|
api 'net.kyori:adventure-platform-api:4.1.2'
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/net.kyori/adventure-text-serializer-gson
|
// https://mvnrepository.com/artifact/net.kyori/adventure-text-serializer-gson
|
||||||
api 'net.kyori:adventure-text-serializer-gson:4.11.0'
|
api 'net.kyori:adventure-text-serializer-gson:4.11.0'
|
||||||
|
@@ -0,0 +1,36 @@
|
|||||||
|
package cn.hamster3.mc.plugin.core.common.api;
|
||||||
|
|
||||||
|
import net.kyori.adventure.platform.AudienceProvider;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public abstract class CoreAPI {
|
||||||
|
protected static CoreAPI instance;
|
||||||
|
|
||||||
|
public static CoreAPI getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public abstract AudienceProvider getAudienceProvider();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public abstract DataSource getDataSource();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public Connection getConnection() throws SQLException {
|
||||||
|
return getDataSource().getConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reportError(@NotNull String apiKey, @NotNull String projectID, @NotNull Throwable exception) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reportFile(@NotNull String apiKey, @NotNull String projectID, @NotNull String filename, byte @NotNull [] bytes) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -1,30 +0,0 @@
|
|||||||
package cn.hamster3.mc.plugin.core.common.api;
|
|
||||||
|
|
||||||
import net.kyori.adventure.platform.AudienceProvider;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public abstract class CoreCommonAPI {
|
|
||||||
protected static CoreCommonAPI instance;
|
|
||||||
|
|
||||||
public static CoreCommonAPI getInstance() {
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public abstract AudienceProvider getAudienceProvider();
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public abstract DataSource getDataSource();
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public abstract Connection getConnection() throws SQLException;
|
|
||||||
|
|
||||||
public abstract void reportError(@NotNull String apiKey, @NotNull String projectID, @NotNull Throwable exception);
|
|
||||||
|
|
||||||
public abstract void reportFile(@NotNull String apiKey, @NotNull String projectID, @NotNull String filename, byte @NotNull [] bytes);
|
|
||||||
}
|
|
@@ -5,9 +5,16 @@ import com.google.gson.*;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
public interface CoreConstantObjects {
|
public interface CoreConstantObjects {
|
||||||
|
/**
|
||||||
|
* Minecraft 默认指定的空 UUID
|
||||||
|
*/
|
||||||
|
UUID NIL_UUID = new UUID(0L, 0L);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GSON 工具
|
* GSON 工具
|
||||||
*/
|
*/
|
||||||
@@ -28,14 +35,14 @@ public interface CoreConstantObjects {
|
|||||||
*/
|
*/
|
||||||
JsonParser JSON_PARSER = new JsonParser();
|
JsonParser JSON_PARSER = new JsonParser();
|
||||||
|
|
||||||
/**
|
|
||||||
* 调度器线程
|
|
||||||
*/
|
|
||||||
ScheduledExecutorService SCHEDULED_EXECUTOR = Executors.newScheduledThreadPool(1, new APIThreadFactory("HamsterCore - Scheduler"));
|
|
||||||
/**
|
/**
|
||||||
* 异步线程
|
* 异步线程
|
||||||
*/
|
*/
|
||||||
ExecutorService WORKER_EXECUTOR = new ThreadPoolExecutor(1, Integer.MAX_VALUE, 60, TimeUnit.MINUTES, new SynchronousQueue<>(), new APIThreadFactory("HamsterCore - Executor"));
|
ExecutorService WORKER_EXECUTOR = new ThreadPoolExecutor(1, Integer.MAX_VALUE, 60, TimeUnit.MINUTES, new SynchronousQueue<>(), new APIThreadFactory("HamsterCore - Executor"));
|
||||||
|
/**
|
||||||
|
* 调度器线程
|
||||||
|
*/
|
||||||
|
ScheduledExecutorService SCHEDULED_EXECUTOR = Executors.newScheduledThreadPool(1, new APIThreadFactory("HamsterCore - Scheduler"));
|
||||||
|
|
||||||
class APIThreadFactory implements ThreadFactory {
|
class APIThreadFactory implements ThreadFactory {
|
||||||
private final String name;
|
private final String name;
|
||||||
|
@@ -6,15 +6,19 @@ import java.util.Collections;
|
|||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 算数表达式求值
|
* 算数表达式求值工具
|
||||||
|
* <p>
|
||||||
* 传入算数表达式,将返回一个浮点值结果
|
* 传入算数表达式,将返回一个浮点值结果
|
||||||
|
* <p>
|
||||||
* 如果计算过程错误,将返回一个NaN
|
* 如果计算过程错误,将返回一个NaN
|
||||||
* <p>
|
* <p>
|
||||||
* 我也忘了这个类是哪里抄来的
|
* 我也忘了这个类是哪里抄来的
|
||||||
* 反正它运行起来比直接用JavaScript引擎计算要快很多
|
* <p>
|
||||||
|
* 反正它运行起来比直接用 JavaScript 引擎计算要快很多
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class Calculator {
|
public final class Calculator {
|
||||||
|
public static final Calculator INSTANCE = new Calculator();
|
||||||
// 默认除法运算精度
|
// 默认除法运算精度
|
||||||
private static final int DEF_DIV_SCALE = 16;
|
private static final int DEF_DIV_SCALE = 16;
|
||||||
|
|
||||||
|
@@ -2,6 +2,9 @@ package cn.hamster3.mc.plugin.core.common.util;
|
|||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public final class CaseUtils {
|
public final class CaseUtils {
|
||||||
|
private CaseUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> T caseObject(Object o) {
|
public static <T> T caseObject(Object o) {
|
||||||
return (T) o;
|
return (T) o;
|
||||||
|
@@ -0,0 +1,182 @@
|
|||||||
|
package cn.hamster3.mc.plugin.core.common.util;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public final class CommonUtils {
|
||||||
|
private CommonUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void zipCompressionFolder(@NotNull File folder, @NotNull File zipFile) throws IOException {
|
||||||
|
ZipOutputStream stream = new ZipOutputStream(Files.newOutputStream(zipFile.toPath()));
|
||||||
|
putFileToZipStream(stream, "", folder);
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void putFileToZipStream(@NotNull ZipOutputStream stream, @NotNull String path, @NotNull File file) throws IOException {
|
||||||
|
if (file.isDirectory()) {
|
||||||
|
File[] files = file.listFiles();
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换颜色代码
|
||||||
|
*
|
||||||
|
* @param string 要替换的字符串
|
||||||
|
* @return 替换后的字符串
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static String replaceColorCode(@Nullable String string) {
|
||||||
|
if (string == null) return null;
|
||||||
|
return string.replace("&", "§");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换颜色代码
|
||||||
|
* <p>
|
||||||
|
* 添加这个方法是因为 ConfigurationSection 中的 getString 方法有 @Nullable 注解
|
||||||
|
* <p>
|
||||||
|
* 导致 idea 会弹出某些警告,让人非常不爽
|
||||||
|
*
|
||||||
|
* @param string 要替换的字符串
|
||||||
|
* @param defaultValue 若 string 为空则使用该字符串
|
||||||
|
* @return 替换后的字符串
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static String replaceColorCode(@Nullable String string, @NotNull String defaultValue) {
|
||||||
|
if (string == null) {
|
||||||
|
return replaceColorCode(defaultValue);
|
||||||
|
}
|
||||||
|
return replaceColorCode(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换颜色代码
|
||||||
|
*
|
||||||
|
* @param strings 要替换的字符串
|
||||||
|
* @return 替换后的字符串
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static ArrayList<String> replaceColorCode(@Nullable Iterable<String> strings) {
|
||||||
|
ArrayList<String> list = new ArrayList<>();
|
||||||
|
if (strings == null) return list;
|
||||||
|
for (String s : strings) {
|
||||||
|
list.add(replaceColorCode(s));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换颜色代码
|
||||||
|
*
|
||||||
|
* @param strings 要替换的字符串
|
||||||
|
* @return 替换后的字符串
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static ArrayList<String> replaceColorCode(@Nullable String[] strings) {
|
||||||
|
ArrayList<String> list = new ArrayList<>();
|
||||||
|
if (strings == null) return list;
|
||||||
|
for (String s : strings) {
|
||||||
|
list.add(replaceColorCode(s));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static String[] replaceStringList(@NotNull String[] strings, @NotNull String key, @NotNull String value) {
|
||||||
|
for (int i = 0; i < strings.length; i++) {
|
||||||
|
strings[i] = strings[i].replace(key, value);
|
||||||
|
}
|
||||||
|
return strings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static List<String> replaceStringList(@NotNull Iterable<String> strings, @NotNull String key, @NotNull String value) {
|
||||||
|
ArrayList<String> list = new ArrayList<>();
|
||||||
|
for (String s : strings) {
|
||||||
|
list.add(s.replace(key, value));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static List<String> replaceStringList(@NotNull List<String> strings, @NotNull String key, @NotNull String value) {
|
||||||
|
strings.replaceAll(s -> s.replace(key, value));
|
||||||
|
return strings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean startsWithIgnoreCase(@NotNull String string, @NotNull String prefix) {
|
||||||
|
return string.regionMatches(true, 0, prefix, 0, prefix.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean endsWithIgnoreCase(@NotNull String string, @NotNull String suffix) {
|
||||||
|
int strOffset = string.length() - suffix.length();
|
||||||
|
return string.regionMatches(true, strOffset, suffix, 0, suffix.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static ArrayList<String> startsWith(@NotNull Iterable<String> strings, @NotNull String with) {
|
||||||
|
ArrayList<String> list = new ArrayList<>();
|
||||||
|
for (String string : strings) {
|
||||||
|
if (string.startsWith(with)) {
|
||||||
|
list.add(string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static ArrayList<String> endsWith(@NotNull Iterable<String> strings, @NotNull String with) {
|
||||||
|
ArrayList<String> list = new ArrayList<>();
|
||||||
|
for (String string : strings) {
|
||||||
|
if (string.endsWith(with)) {
|
||||||
|
list.add(string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static ArrayList<String> startsWithIgnoreCase(@NotNull Iterable<String> strings, @NotNull String start) {
|
||||||
|
ArrayList<String> list = new ArrayList<>();
|
||||||
|
for (String string : strings) {
|
||||||
|
if (startsWithIgnoreCase(string, start)) {
|
||||||
|
list.add(string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static ArrayList<String> endsWithIgnoreCase(@NotNull Iterable<String> strings, @NotNull String end) {
|
||||||
|
ArrayList<String> list = new ArrayList<>();
|
||||||
|
for (String string : strings) {
|
||||||
|
if (endsWithIgnoreCase(string, end)) {
|
||||||
|
list.add(string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -1,35 +0,0 @@
|
|||||||
package cn.hamster3.mc.plugin.core.common.util;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipOutputStream;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public class FileUtils {
|
|
||||||
@SuppressWarnings("IOStreamConstructor")
|
|
||||||
public static void zipCompressionFolder(File folder, File zipFile) throws IOException {
|
|
||||||
ZipOutputStream stream = new ZipOutputStream(new FileOutputStream(zipFile));
|
|
||||||
putFileToZipStream(stream, "", folder);
|
|
||||||
stream.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void putFileToZipStream(ZipOutputStream stream, String path, File file) throws IOException {
|
|
||||||
if (file.isDirectory()) {
|
|
||||||
File[] files = file.listFiles();
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -11,7 +11,19 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
|
||||||
public class SerializeUtils {
|
/**
|
||||||
|
* 序列化相关工具
|
||||||
|
*/
|
||||||
|
public final class SerializeUtils {
|
||||||
|
private SerializeUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将 adventure 中的 title 对象序列化为 json
|
||||||
|
*
|
||||||
|
* @param title -
|
||||||
|
* @return -
|
||||||
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JsonObject serializeTitle(@NotNull Title title) {
|
public static JsonObject serializeTitle(@NotNull Title title) {
|
||||||
JsonObject object = new JsonObject();
|
JsonObject object = new JsonObject();
|
||||||
@@ -24,6 +36,12 @@ public class SerializeUtils {
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将 json 反序列化为 adventure 中的 title
|
||||||
|
*
|
||||||
|
* @param object -
|
||||||
|
* @return -
|
||||||
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public static Title deserializeTitle(@NotNull JsonObject object) {
|
public static Title deserializeTitle(@NotNull JsonObject object) {
|
||||||
if (object.has("times")) {
|
if (object.has("times")) {
|
||||||
|
@@ -1,3 +0,0 @@
|
|||||||
name: HamsterCore-Proxy
|
|
||||||
main: cn.hamster3.mc.plugin.core.proxy.HamsterCorePlugin
|
|
||||||
version: ${version}
|
|
@@ -1,5 +1,5 @@
|
|||||||
rootProject.name = 'hamster-core'
|
rootProject.name = 'hamster-core'
|
||||||
include 'hamster-core-common'
|
include 'hamster-core-common'
|
||||||
include 'hamster-core-bukkit'
|
include 'hamster-core-bukkit'
|
||||||
include 'hamster-core-proxy'
|
include 'hamster-core-bungeecord'
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user