diff --git a/build.gradle b/build.gradle index 5d6565f..ec4b132 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ plugins { } group 'cn.hamster3.mc.plugin' -version '0.0.1-SNAPSHOT' +version '1.0.0' subprojects { apply plugin: 'java-library' @@ -19,12 +19,14 @@ subprojects { } configurations { + shade api.extendsFrom apiShade implementation.extendsFrom implementationShade } 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) { diff --git a/hamster-core-bukkit/build.gradle b/hamster-core-bukkit/build.gradle index 7c0a745..0d49ac4 100644 --- a/hamster-core-bukkit/build.gradle +++ b/hamster-core-bukkit/build.gradle @@ -8,20 +8,18 @@ dependencies { } 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 //noinspection GradlePackageUpdate 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 apiShade 'com.squareup.okhttp3:okhttp:4.10.0' // https://mvnrepository.com/artifact/net.kyori/adventure-platform-bukkit 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 { @@ -38,11 +36,14 @@ tasks.create("shadowJar", Jar) { tasks.jar.outputs.files.collect { it.isDirectory() ? it : zipTree(it) }, - configurations.implementationShade.collect { + configurations.shade.collect { it.isDirectory() ? it : zipTree(it) }, configurations.apiShade.collect { it.isDirectory() ? it : zipTree(it) + }, + configurations.implementationShade.collect { + it.isDirectory() ? it : zipTree(it) } ]) destinationDir(getRootProject().buildDir) diff --git a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/HamsterCorePlugin.java b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/HamsterCorePlugin.java index d656c64..22595e8 100644 --- a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/HamsterCorePlugin.java +++ b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/HamsterCorePlugin.java @@ -1,11 +1,25 @@ 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.common.constant.CoreConstantObjects; import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; import org.bukkit.plugin.java.JavaPlugin; +import java.util.List; +import java.util.logging.Logger; + public class HamsterCorePlugin extends JavaPlugin { + private static final ParentCommand COMMAND_EXECUTOR = new ParentCommand("core"); private static HamsterCorePlugin instance; public static HamsterCorePlugin getInstance() { @@ -16,10 +30,6 @@ public class HamsterCorePlugin extends JavaPlugin { Bukkit.getScheduler().runTask(instance, runnable); } - public static void async(Runnable runnable) { - Bukkit.getScheduler().runTaskAsynchronously(instance, runnable); - } - @Override public void onLoad() { instance = this; @@ -27,23 +37,49 @@ public class HamsterCorePlugin extends JavaPlugin { @Override public void onEnable() { + Logger logger = getLogger(); 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); - 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; - getLogger().info("仓鼠核心已启动,总计耗时 " + time + " ms."); + logger.info("仓鼠核心已启动,总计耗时 " + time + " ms."); } @Override public void onDisable() { + Logger logger = getLogger(); long start = System.currentTimeMillis(); - getLogger().info("仓鼠核心正在关闭..."); + logger.info("仓鼠核心正在关闭..."); CoreConstantObjects.WORKER_EXECUTOR.shutdownNow(); - getLogger().info("已暂停 WORKER_EXECUTOR."); + logger.info("已暂停 WORKER_EXECUTOR."); CoreConstantObjects.SCHEDULED_EXECUTOR.shutdownNow(); - getLogger().info("已暂停 SCHEDULED_EXECUTOR."); + logger.info("已暂停 SCHEDULED_EXECUTOR."); 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 onTabComplete(CommandSender sender, Command command, String alias, String[] args) { + return COMMAND_EXECUTOR.onTabComplete(sender, command, alias, args); } } diff --git a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/api/CoreBukkitAPI.java b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/api/CoreBukkitAPI.java index 3ed53e4..e16af95 100644 --- a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/api/CoreBukkitAPI.java +++ b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/api/CoreBukkitAPI.java @@ -1,31 +1,46 @@ package cn.hamster3.mc.plugin.core.bukkit.api; 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.HikariDataSource; import net.kyori.adventure.platform.AudienceProvider; import net.kyori.adventure.platform.bukkit.BukkitAudiences; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.NotNull; -import java.sql.Connection; -import java.sql.SQLException; - @SuppressWarnings("unused") -public class CoreBukkitAPI extends CoreCommonAPI { - private BukkitAudiences audienceProvider; - private HikariDataSource datasource; +public class CoreBukkitAPI extends CoreAPI { + private final BukkitAudiences audienceProvider; + 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() { return (CoreBukkitAPI) instance; } public static void init() { - CoreBukkitAPI api = new CoreBukkitAPI(); - instance = api; - api.audienceProvider = BukkitAudiences.create(HamsterCorePlugin.getInstance()); - HikariConfig hikariConfig = new HikariConfig(); - + instance = new CoreBukkitAPI(); } @Override @@ -38,17 +53,9 @@ public class CoreBukkitAPI extends CoreCommonAPI { return datasource; } - @Override - public @NotNull Connection getConnection() throws SQLException { - return datasource.getConnection(); + public void reportError(@NotNull String projectID, @NotNull Throwable exception) { } - @Override - 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) { + public void reportFile(@NotNull String projectID, @NotNull String filename, byte @NotNull [] bytes) { } } diff --git a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/command/ChildCommand.java b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/command/ChildCommand.java new file mode 100644 index 0000000..abf56c0 --- /dev/null +++ b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/command/ChildCommand.java @@ -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(); + +} diff --git a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/command/ParentCommand.java b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/command/ParentCommand.java new file mode 100644 index 0000000..a4b4f16 --- /dev/null +++ b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/command/ParentCommand.java @@ -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 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 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 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()); + } +} diff --git a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/command/debug/BlockInfoCommand.java b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/command/debug/BlockInfoCommand.java new file mode 100644 index 0000000..72be47c --- /dev/null +++ b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/command/debug/BlockInfoCommand.java @@ -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 onTabComplete(CommandSender sender, Command command, String alias, String[] args) { + return null; + } +} diff --git a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/command/debug/YamlCommand.java b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/command/debug/YamlCommand.java new file mode 100644 index 0000000..a9ac15b --- /dev/null +++ b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/command/debug/YamlCommand.java @@ -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 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 onTabComplete(CommandSender sender, Command command, String alias, String[] args) { + return Collections.emptyList(); + } +} diff --git a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/constant/CoreMessage.java b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/constant/CoreMessage.java new file mode 100644 index 0000000..b4ea243 --- /dev/null +++ b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/constant/CoreMessage.java @@ -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()); + } +} diff --git a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/hook/EconomyAPI.java b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/hook/EconomyAPI.java new file mode 100644 index 0000000..37a790e --- /dev/null +++ b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/hook/EconomyAPI.java @@ -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); + } + + /** + * 检查玩家有多少钱 + *

+ * 若没有安装经济插件则返回NaN + * + * @param player 玩家 + * @return 玩家的余额 + */ + public static double seeMoney(@NotNull final OfflinePlayer player) { + if (!isSetupEconomy()) { + return Double.NaN; + } + return VaultAPI.getEconomy().getBalance(player); + } + + /** + * 检查玩家有多少钱 + *

+ * 若没有安装经济插件则返回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); + } +} diff --git a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/hook/PointAPI.java b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/hook/PointAPI.java new file mode 100644 index 0000000..2c218ce --- /dev/null +++ b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/hook/PointAPI.java @@ -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; + } +} diff --git a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/hook/VaultAPI.java b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/hook/VaultAPI.java new file mode 100644 index 0000000..cebce7d --- /dev/null +++ b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/hook/VaultAPI.java @@ -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 chatProvider = Bukkit.getServer().getServicesManager().getRegistration(Chat.class); + + if (chatProvider != null) { + chat = chatProvider.getProvider(); + HamsterCorePlugin.getInstance().getLogger().info("聊天系统挂接成功."); + } else { + HamsterCorePlugin.getInstance().getLogger().warning("未检测到聊天系统!"); + } + + RegisteredServiceProvider economyProvider = Bukkit.getServer().getServicesManager().getRegistration(Economy.class); + if (economyProvider != null) { + economy = economyProvider.getProvider(); + HamsterCorePlugin.getInstance().getLogger().info("经济系统挂接成功."); + } else { + HamsterCorePlugin.getInstance().getLogger().warning("未检测到经济系统!"); + } + + RegisteredServiceProvider 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; + } + +} diff --git a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/listener/CallbackListener.java b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/listener/CallbackListener.java new file mode 100644 index 0000000..03ecce8 --- /dev/null +++ b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/listener/CallbackListener.java @@ -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> CHATS = new HashMap<>(); + public static final HashMap> BLOCKS = new HashMap<>(); + public static final HashMap> ENTITIES = new HashMap<>(); + + private CallbackListener() { + } + + @EventHandler(ignoreCancelled = true) + public void onAsyncPlayerChat(AsyncPlayerChatEvent event) { + Player player = event.getPlayer(); + CompletableFuture 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 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 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 chat = CHATS.remove(uuid); + if (chat != null) { + chat.cancel(true); + } + CompletableFuture block = BLOCKS.remove(uuid); + if (block != null) { + block.cancel(true); + } + CompletableFuture entity = ENTITIES.remove(uuid); + if (entity != null) { + entity.cancel(true); + } + } +} diff --git a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/listener/DebugListener.java b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/listener/DebugListener.java new file mode 100644 index 0000000..3b80e9a --- /dev/null +++ b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/listener/DebugListener.java @@ -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 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); + } +} diff --git a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/page/handler/PageHandler.java b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/page/handler/PageHandler.java index df34e1c..7652733 100644 --- a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/page/handler/PageHandler.java +++ b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/page/handler/PageHandler.java @@ -1,9 +1,9 @@ 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.page.ButtonGroup; 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.Sound; import org.bukkit.entity.HumanEntity; diff --git a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/page/handler/PageableHandler.java b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/page/handler/PageableHandler.java index 6172eb0..98eb92d 100644 --- a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/page/handler/PageableHandler.java +++ b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/page/handler/PageableHandler.java @@ -1,8 +1,8 @@ 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.PageElement; 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.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryAction; diff --git a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/util/BukkitUtils.java b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/util/BukkitUtils.java index ca02007..aa4681b 100644 --- a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/util/BukkitUtils.java +++ b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/util/BukkitUtils.java @@ -1,12 +1,9 @@ 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.Material; import org.bukkit.OfflinePlayer; import org.bukkit.World; -import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -17,7 +14,10 @@ import org.jetbrains.annotations.NotNull; import java.util.UUID; @SuppressWarnings("unused") -public class BukkitUtils { +public final class BukkitUtils { + private BukkitUtils() { + } + @NotNull public static String getMCVersion() { return Bukkit.getBukkitVersion().split("-")[0]; @@ -68,8 +68,10 @@ public class BukkitUtils { /** * 获取玩家的头颅 - * 在1.11以上的服务端中获取头颅材质是在服务器上运行的 - * 因此建议使用异步线程调用该方法 + *

+ * 在 1.11 以上的服务端建议使用异步线程调用该方法 + *

+ * 因为这些服务端中通过网络获取头颅材质是在服务器上运行的 * * @param offlinePlayer 要获取的玩家 * @return 玩家的头颅物品 @@ -165,30 +167,4 @@ public class BukkitUtils { } 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) } diff --git a/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/util/CallbackUtils.java b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/util/CallbackUtils.java new file mode 100644 index 0000000..ee10987 --- /dev/null +++ b/hamster-core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/util/CallbackUtils.java @@ -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 getPlayerChat(HumanEntity player) { + return CallbackListener.CHATS.computeIfAbsent(player.getUniqueId(), o -> new CompletableFuture<>()); + } + + public static CompletableFuture getPlayerClickedBlock(HumanEntity player) { + return CallbackListener.BLOCKS.computeIfAbsent(player.getUniqueId(), o -> new CompletableFuture<>()); + } + + public static CompletableFuture getPlayerClickedEntity(HumanEntity player) { + return CallbackListener.ENTITIES.computeIfAbsent(player.getUniqueId(), o -> new CompletableFuture<>()); + } +} diff --git a/hamster-core-bukkit/src/main/resources/config.yml b/hamster-core-bukkit/src/main/resources/config.yml new file mode 100644 index 0000000..2b73503 --- /dev/null +++ b/hamster-core-bukkit/src/main/resources/config.yml @@ -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 diff --git a/hamster-core-bukkit/src/main/resources/plugin.yml b/hamster-core-bukkit/src/main/resources/plugin.yml index 43e40dd..e006814 100644 --- a/hamster-core-bukkit/src/main/resources/plugin.yml +++ b/hamster-core-bukkit/src/main/resources/plugin.yml @@ -1,3 +1,22 @@ name: HamsterCore main: cn.hamster3.mc.plugin.core.bukkit.HamsterCorePlugin 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 diff --git a/hamster-core-proxy/build.gradle b/hamster-core-bungeecord/build.gradle similarity index 83% rename from hamster-core-proxy/build.gradle rename to hamster-core-bungeecord/build.gradle index 27a78c6..ddb6c82 100644 --- a/hamster-core-proxy/build.gradle +++ b/hamster-core-bungeecord/build.gradle @@ -1,4 +1,4 @@ -setArchivesBaseName("HamsterCore-Proxy") +setArchivesBaseName("HamsterCore-BungeeCord") evaluationDependsOn(':hamster-core-common') @@ -8,21 +8,16 @@ dependencies { } //noinspection GradlePackageUpdate 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 //noinspection GradlePackageUpdate 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 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 { @@ -39,11 +34,14 @@ tasks.create("shadowJar", Jar) { tasks.jar.outputs.files.collect { it.isDirectory() ? it : zipTree(it) }, - configurations.implementationShade.collect { + configurations.shade.collect { it.isDirectory() ? it : zipTree(it) }, configurations.apiShade.collect { it.isDirectory() ? it : zipTree(it) + }, + configurations.implementationShade.collect { + it.isDirectory() ? it : zipTree(it) } ]) destinationDir(getRootProject().buildDir) diff --git a/hamster-core-proxy/src/main/java/cn/hamster3/mc/plugin/core/proxy/HamsterCorePlugin.java b/hamster-core-bungeecord/src/main/java/cn/hamster3/mc/plugin/core/bungee/HamsterCorePlugin.java similarity index 55% rename from hamster-core-proxy/src/main/java/cn/hamster3/mc/plugin/core/proxy/HamsterCorePlugin.java rename to hamster-core-bungeecord/src/main/java/cn/hamster3/mc/plugin/core/bungee/HamsterCorePlugin.java index e033124..bd147c9 100644 --- a/hamster-core-proxy/src/main/java/cn/hamster3/mc/plugin/core/proxy/HamsterCorePlugin.java +++ b/hamster-core-bungeecord/src/main/java/cn/hamster3/mc/plugin/core/bungee/HamsterCorePlugin.java @@ -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 net.md_5.bungee.api.plugin.Plugin; +import java.util.logging.Logger; + public class HamsterCorePlugin extends Plugin { private static HamsterCorePlugin instance; @@ -17,21 +20,25 @@ public class HamsterCorePlugin extends Plugin { @Override public void onEnable() { + Logger logger = getLogger(); long start = System.currentTimeMillis(); - getLogger().info("仓鼠核心正在启动..."); + logger.info("仓鼠核心正在启动..."); + CoreBungeeAPI.init(); + logger.info("CoreAPI 已初始化."); long time = System.currentTimeMillis() - start; - getLogger().info("仓鼠核心已启动,总计耗时 " + time + " ms."); + logger.info("仓鼠核心已启动,总计耗时 " + time + " ms."); } @Override public void onDisable() { + Logger logger = getLogger(); long start = System.currentTimeMillis(); - getLogger().info("仓鼠核心正在关闭..."); + logger.info("仓鼠核心正在关闭..."); CoreConstantObjects.WORKER_EXECUTOR.shutdownNow(); - getLogger().info("已暂停 WORKER_EXECUTOR."); + logger.info("已暂停 WORKER_EXECUTOR."); CoreConstantObjects.SCHEDULED_EXECUTOR.shutdownNow(); - getLogger().info("已暂停 SCHEDULED_EXECUTOR."); + logger.info("已暂停 SCHEDULED_EXECUTOR."); long time = System.currentTimeMillis() - start; - getLogger().info("仓鼠核心已关闭,总计耗时 " + time + " ms."); + logger.info("仓鼠核心已关闭,总计耗时 " + time + " ms."); } } diff --git a/hamster-core-bungeecord/src/main/java/cn/hamster3/mc/plugin/core/bungee/api/CoreBungeeAPI.java b/hamster-core-bungeecord/src/main/java/cn/hamster3/mc/plugin/core/bungee/api/CoreBungeeAPI.java new file mode 100644 index 0000000..7438522 --- /dev/null +++ b/hamster-core-bungeecord/src/main/java/cn/hamster3/mc/plugin/core/bungee/api/CoreBungeeAPI.java @@ -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; + } +} diff --git a/hamster-core-bungeecord/src/main/java/cn/hamster3/mc/plugin/core/bungee/util/BungeeCordUtils.java b/hamster-core-bungeecord/src/main/java/cn/hamster3/mc/plugin/core/bungee/util/BungeeCordUtils.java new file mode 100644 index 0000000..e0f4bd0 --- /dev/null +++ b/hamster-core-bungeecord/src/main/java/cn/hamster3/mc/plugin/core/bungee/util/BungeeCordUtils.java @@ -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; + } +} diff --git a/hamster-core-bungeecord/src/main/resources/bungee.yml b/hamster-core-bungeecord/src/main/resources/bungee.yml new file mode 100644 index 0000000..e32ed21 --- /dev/null +++ b/hamster-core-bungeecord/src/main/resources/bungee.yml @@ -0,0 +1,3 @@ +name: HamsterCore-BungeeCord +main: cn.hamster3.mc.plugin.core.bungee.HamsterCorePlugin +version: ${version} diff --git a/hamster-core-bungeecord/src/main/resources/config.yml b/hamster-core-bungeecord/src/main/resources/config.yml new file mode 100644 index 0000000..2b73503 --- /dev/null +++ b/hamster-core-bungeecord/src/main/resources/config.yml @@ -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 diff --git a/hamster-core-common/build.gradle b/hamster-core-common/build.gradle index 1a76020..989cf55 100644 --- a/hamster-core-common/build.gradle +++ b/hamster-core-common/build.gradle @@ -13,7 +13,7 @@ dependencies { // https://mvnrepository.com/artifact/net.kyori/adventure-text-minimessage api 'net.kyori:adventure-text-minimessage:4.11.0' // 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 api 'net.kyori:adventure-text-serializer-gson:4.11.0' diff --git a/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/api/CoreAPI.java b/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/api/CoreAPI.java new file mode 100644 index 0000000..1ff26f7 --- /dev/null +++ b/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/api/CoreAPI.java @@ -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) { + + } +} diff --git a/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/api/CoreCommonAPI.java b/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/api/CoreCommonAPI.java deleted file mode 100644 index dd40b28..0000000 --- a/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/api/CoreCommonAPI.java +++ /dev/null @@ -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); -} diff --git a/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/constant/CoreConstantObjects.java b/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/constant/CoreConstantObjects.java index e4b56dd..e23a6e4 100644 --- a/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/constant/CoreConstantObjects.java +++ b/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/constant/CoreConstantObjects.java @@ -5,9 +5,16 @@ import com.google.gson.*; import org.jetbrains.annotations.NotNull; import java.lang.reflect.Type; +import java.util.UUID; import java.util.concurrent.*; +@SuppressWarnings("unused") public interface CoreConstantObjects { + /** + * Minecraft 默认指定的空 UUID + */ + UUID NIL_UUID = new UUID(0L, 0L); + /** * GSON 工具 */ @@ -28,14 +35,14 @@ public interface CoreConstantObjects { */ 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")); + /** + * 调度器线程 + */ + ScheduledExecutorService SCHEDULED_EXECUTOR = Executors.newScheduledThreadPool(1, new APIThreadFactory("HamsterCore - Scheduler")); class APIThreadFactory implements ThreadFactory { private final String name; diff --git a/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/util/Calculator.java b/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/util/Calculator.java index 8e17bc4..875feab 100644 --- a/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/util/Calculator.java +++ b/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/util/Calculator.java @@ -6,15 +6,19 @@ import java.util.Collections; import java.util.Stack; /** - * 算数表达式求值 + * 算数表达式求值工具 + *

* 传入算数表达式,将返回一个浮点值结果 + *

* 如果计算过程错误,将返回一个NaN *

* 我也忘了这个类是哪里抄来的 - * 反正它运行起来比直接用JavaScript引擎计算要快很多 + *

+ * 反正它运行起来比直接用 JavaScript 引擎计算要快很多 */ @SuppressWarnings("unused") -public class Calculator { +public final class Calculator { + public static final Calculator INSTANCE = new Calculator(); // 默认除法运算精度 private static final int DEF_DIV_SCALE = 16; diff --git a/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/util/CaseUtils.java b/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/util/CaseUtils.java index 018f35f..ad19997 100644 --- a/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/util/CaseUtils.java +++ b/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/util/CaseUtils.java @@ -2,6 +2,9 @@ package cn.hamster3.mc.plugin.core.common.util; @SuppressWarnings("unused") public final class CaseUtils { + private CaseUtils() { + } + @SuppressWarnings("unchecked") public static T caseObject(Object o) { return (T) o; diff --git a/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/util/CommonUtils.java b/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/util/CommonUtils.java new file mode 100644 index 0000000..c8002ec --- /dev/null +++ b/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/util/CommonUtils.java @@ -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("&", "§"); + } + + /** + * 替换颜色代码 + *

+ * 添加这个方法是因为 ConfigurationSection 中的 getString 方法有 @Nullable 注解 + *

+ * 导致 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 replaceColorCode(@Nullable Iterable strings) { + ArrayList 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 replaceColorCode(@Nullable String[] strings) { + ArrayList 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 replaceStringList(@NotNull Iterable strings, @NotNull String key, @NotNull String value) { + ArrayList list = new ArrayList<>(); + for (String s : strings) { + list.add(s.replace(key, value)); + } + return list; + } + + @NotNull + public static List replaceStringList(@NotNull List 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 startsWith(@NotNull Iterable strings, @NotNull String with) { + ArrayList list = new ArrayList<>(); + for (String string : strings) { + if (string.startsWith(with)) { + list.add(string); + } + } + return list; + } + + @NotNull + public static ArrayList endsWith(@NotNull Iterable strings, @NotNull String with) { + ArrayList list = new ArrayList<>(); + for (String string : strings) { + if (string.endsWith(with)) { + list.add(string); + } + } + return list; + } + + @NotNull + public static ArrayList startsWithIgnoreCase(@NotNull Iterable strings, @NotNull String start) { + ArrayList list = new ArrayList<>(); + for (String string : strings) { + if (startsWithIgnoreCase(string, start)) { + list.add(string); + } + } + return list; + } + + @NotNull + public static ArrayList endsWithIgnoreCase(@NotNull Iterable strings, @NotNull String end) { + ArrayList list = new ArrayList<>(); + for (String string : strings) { + if (endsWithIgnoreCase(string, end)) { + list.add(string); + } + } + return list; + } + + +} diff --git a/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/util/FileUtils.java b/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/util/FileUtils.java deleted file mode 100644 index c026eb9..0000000 --- a/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/util/FileUtils.java +++ /dev/null @@ -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(); - } -} diff --git a/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/util/SerializeUtils.java b/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/util/SerializeUtils.java index d460126..e84da98 100644 --- a/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/util/SerializeUtils.java +++ b/hamster-core-common/src/main/java/cn/hamster3/mc/plugin/core/common/util/SerializeUtils.java @@ -11,7 +11,19 @@ import org.jetbrains.annotations.NotNull; import java.time.Duration; -public class SerializeUtils { +/** + * 序列化相关工具 + */ +public final class SerializeUtils { + private SerializeUtils() { + } + + /** + * 将 adventure 中的 title 对象序列化为 json + * + * @param title - + * @return - + */ @NotNull public static JsonObject serializeTitle(@NotNull Title title) { JsonObject object = new JsonObject(); @@ -24,6 +36,12 @@ public class SerializeUtils { return object; } + /** + * 将 json 反序列化为 adventure 中的 title + * + * @param object - + * @return - + */ @NotNull public static Title deserializeTitle(@NotNull JsonObject object) { if (object.has("times")) { diff --git a/hamster-core-proxy/src/main/resources/bungee.yml b/hamster-core-proxy/src/main/resources/bungee.yml deleted file mode 100644 index 85ba80a..0000000 --- a/hamster-core-proxy/src/main/resources/bungee.yml +++ /dev/null @@ -1,3 +0,0 @@ -name: HamsterCore-Proxy -main: cn.hamster3.mc.plugin.core.proxy.HamsterCorePlugin -version: ${version} diff --git a/settings.gradle b/settings.gradle index 7f95422..495ad8f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,5 @@ rootProject.name = 'hamster-core' include 'hamster-core-common' include 'hamster-core-bukkit' -include 'hamster-core-proxy' +include 'hamster-core-bungeecord'