build: 更改项目结构
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit;
|
||||
|
||||
import cn.hamster3.mc.plugin.core.bukkit.api.CoreBukkitAPI;
|
||||
import cn.hamster3.mc.plugin.core.bukkit.command.core.ParentCoreCommand;
|
||||
import cn.hamster3.mc.plugin.core.bukkit.command.lore.ParentLoreCommand;
|
||||
import cn.hamster3.mc.plugin.core.bukkit.constant.CoreMessage;
|
||||
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.handler.PageHandler;
|
||||
import cn.hamster3.mc.plugin.core.bukkit.page.listener.PageListener;
|
||||
import cn.hamster3.mc.plugin.core.bukkit.util.serializer.ItemStackAdapter;
|
||||
import cn.hamster3.mc.plugin.core.bukkit.util.serializer.PotionEffectAdapter;
|
||||
import cn.hamster3.mc.plugin.core.common.data.DisplayMessage;
|
||||
import cn.hamster3.mc.plugin.core.common.util.serializer.ComponentTypeAdapter;
|
||||
import cn.hamster3.mc.plugin.core.common.util.serializer.MessageTypeAdapter;
|
||||
import cn.hamster3.mc.plugin.core.common.util.CoreUtils;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class HamsterCorePlugin extends JavaPlugin {
|
||||
private static HamsterCorePlugin instance;
|
||||
|
||||
private BukkitAudiences audienceProvider;
|
||||
|
||||
public static HamsterCorePlugin getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
instance = this;
|
||||
Logger logger = getLogger();
|
||||
long start = System.currentTimeMillis();
|
||||
logger.info("仓鼠核心正在初始化...");
|
||||
saveDefaultConfig();
|
||||
reloadConfig();
|
||||
logger.info("已读取配置文件.");
|
||||
CoreUtils.GSON = new GsonBuilder()
|
||||
.registerTypeAdapter(Component.class, ComponentTypeAdapter.INSTANCE)
|
||||
.registerTypeAdapter(DisplayMessage.class, MessageTypeAdapter.INSTANCE)
|
||||
.registerTypeAdapter(ItemStack.class, ItemStackAdapter.INSTANCE)
|
||||
.registerTypeAdapter(PotionEffect.class, PotionEffectAdapter.INSTANCE)
|
||||
.create();
|
||||
CoreBukkitAPI.init();
|
||||
logger.info("已初始化 CoreBukkitAPI.");
|
||||
CoreMessage.init(this);
|
||||
logger.info("已初始化语言文本.");
|
||||
long time = System.currentTimeMillis() - start;
|
||||
logger.info("仓鼠核心初始化完成,总计耗时 " + time + " ms.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
Logger logger = getLogger();
|
||||
long start = System.currentTimeMillis();
|
||||
logger.info("仓鼠核心正在启动...");
|
||||
VaultAPI.reloadVaultHook();
|
||||
logger.info("已完成 VaultAPI 挂载.");
|
||||
PointAPI.reloadPlayerPointAPIHook();
|
||||
logger.info("已完成 PlayerPoints 挂载.");
|
||||
audienceProvider = BukkitAudiences.create(this);
|
||||
logger.info("已完成 BukkitAudiences 挂载.");
|
||||
Bukkit.getPluginManager().registerEvents(PageListener.INSTANCE, this);
|
||||
logger.info("已注册 PageListener.");
|
||||
Bukkit.getPluginManager().registerEvents(CallbackListener.INSTANCE, this);
|
||||
logger.info("已注册 CallbackListener.");
|
||||
Bukkit.getPluginManager().registerEvents(DebugListener.INSTANCE, this);
|
||||
logger.info("已注册 DebugListener.");
|
||||
ParentCoreCommand.INSTANCE.hook();
|
||||
ParentLoreCommand.INSTANCE.hook();
|
||||
long time = System.currentTimeMillis() - start;
|
||||
logger.info("仓鼠核心启动完成,总计耗时 " + time + " ms.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
Logger logger = getLogger();
|
||||
long start = System.currentTimeMillis();
|
||||
logger.info("仓鼠核心正在关闭...");
|
||||
CoreUtils.WORKER_EXECUTOR.shutdownNow();
|
||||
logger.info("已暂停 WORKER_EXECUTOR.");
|
||||
CoreUtils.SCHEDULED_EXECUTOR.shutdownNow();
|
||||
logger.info("已暂停 SCHEDULED_EXECUTOR.");
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
InventoryView view = player.getOpenInventory();
|
||||
Inventory inventory = view.getTopInventory();
|
||||
if (!(inventory.getHolder() instanceof PageHandler)) {
|
||||
continue;
|
||||
}
|
||||
player.closeInventory();
|
||||
}
|
||||
long time = System.currentTimeMillis() - start;
|
||||
logger.info("仓鼠核心已关闭,总计耗时 " + time + " ms.");
|
||||
}
|
||||
|
||||
public BukkitAudiences getAudienceProvider() {
|
||||
return audienceProvider;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,69 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.api;
|
||||
|
||||
import cn.hamster3.mc.plugin.core.bukkit.HamsterCorePlugin;
|
||||
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class CoreBukkitAPI extends CoreAPI {
|
||||
private final HikariDataSource datasource;
|
||||
|
||||
private CoreBukkitAPI() {
|
||||
FileConfiguration config = HamsterCorePlugin.getInstance().getConfig();
|
||||
|
||||
ConfigurationSection datasourceConfig = config.getConfigurationSection("datasource");
|
||||
if (datasourceConfig == null) {
|
||||
throw new IllegalArgumentException("配置文件中未找到 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));
|
||||
long keepAliveTime = datasourceConfig.getLong("keep-alive-time", 0);
|
||||
if (keepAliveTime > 5000) {
|
||||
hikariConfig.setKeepaliveTime(keepAliveTime);
|
||||
}
|
||||
hikariConfig.setIdleTimeout(datasourceConfig.getLong("idle-timeout", 10 * 60 * 1000));
|
||||
hikariConfig.setMaxLifetime(datasourceConfig.getLong("max-lifetime", 30 * 60 * 1000));
|
||||
hikariConfig.setValidationTimeout(datasourceConfig.getLong("validation-timeout", 5000));
|
||||
hikariConfig.setPoolName("HamsterCore-Pool");
|
||||
|
||||
datasource = new HikariDataSource(hikariConfig);
|
||||
}
|
||||
|
||||
public static CoreBukkitAPI getInstance() {
|
||||
return (CoreBukkitAPI) instance;
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
if (instance != null) {
|
||||
return;
|
||||
}
|
||||
instance = new CoreBukkitAPI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull BukkitAudiences getAudienceProvider() {
|
||||
return HamsterCorePlugin.getInstance().getAudienceProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull HikariDataSource getDataSource() {
|
||||
return datasource;
|
||||
}
|
||||
|
||||
public void reportError(@NotNull String projectID, @NotNull Throwable exception) {
|
||||
}
|
||||
|
||||
public void reportFile(@NotNull String projectID, @NotNull String filename, byte @NotNull [] bytes) {
|
||||
}
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.command;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class ChildCommand implements TabExecutor {
|
||||
@NotNull
|
||||
public abstract String getName();
|
||||
|
||||
@NotNull
|
||||
public abstract String getUsage();
|
||||
|
||||
public abstract boolean hasPermission(@NotNull CommandSender sender);
|
||||
|
||||
@NotNull
|
||||
public abstract String getDescription();
|
||||
|
||||
}
|
@@ -0,0 +1,174 @@
|
||||
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.PluginCommand;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class ParentCommand extends ChildCommand {
|
||||
@NotNull
|
||||
private final String name;
|
||||
@NotNull
|
||||
private final List<ChildCommand> childCommands;
|
||||
|
||||
public ParentCommand(@NotNull String name) {
|
||||
this.name = name;
|
||||
childCommands = new ArrayList<>();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract JavaPlugin getPlugin();
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ParentCommand getParent() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<ChildCommand> getChildCommands() {
|
||||
return childCommands;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getUsage() {
|
||||
ParentCommand parent = getParent();
|
||||
if (parent == null) {
|
||||
return "/" + name;
|
||||
}
|
||||
return parent.getUsage() + " " + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull CommandSender sender) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getDescription() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有子命令
|
||||
* <p>
|
||||
* 如果子命令也是 ParentCommand 类型,则继续递归获取该 ParentCommand 的子命令
|
||||
*
|
||||
* @return 所有子命令
|
||||
*/
|
||||
@NotNull
|
||||
public List<ChildCommand> getEndChildCommands() {
|
||||
ArrayList<ChildCommand> list = new ArrayList<>();
|
||||
for (ChildCommand command : childCommands) {
|
||||
if (command instanceof ParentCommand) {
|
||||
list.addAll(((ParentCommand) command).getEndChildCommands());
|
||||
} else {
|
||||
list.add(command);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public void addChildCommand(@NotNull ChildCommand command) {
|
||||
childCommands.add(command);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Map<String, String> getCommandHelp(CommandSender sender) {
|
||||
HashMap<String, String> map = new HashMap<>();
|
||||
for (ChildCommand child : childCommands) {
|
||||
if (!child.hasPermission(sender)) {
|
||||
continue;
|
||||
}
|
||||
if (child instanceof ParentCommand) {
|
||||
Map<String, String> childMap = ((ParentCommand) child).getCommandHelp(sender);
|
||||
map.putAll(childMap);
|
||||
continue;
|
||||
}
|
||||
map.put(getUsage() + " " + child.getUsage(), child.getDescription());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public void sendHelp(@NotNull CommandSender sender) {
|
||||
sender.sendMessage("§e==================== [ " + name + " 使用帮助] ====================");
|
||||
Map<String, String> helpMap = getCommandHelp(sender);
|
||||
int maxLength = helpMap.keySet().stream()
|
||||
.map(String::length)
|
||||
.max(Integer::compareTo)
|
||||
.orElse(-1);
|
||||
ArrayList<Map.Entry<String, String>> list = new ArrayList<>(helpMap.entrySet());
|
||||
list.sort(Map.Entry.comparingByKey());
|
||||
for (Map.Entry<String, String> entry : list) {
|
||||
sender.sendMessage(String.format("§a%-" + maxLength + "s - %s", entry.getKey(), entry.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
public void hook() {
|
||||
JavaPlugin plugin = getPlugin();
|
||||
PluginCommand command = plugin.getCommand(getName());
|
||||
if (command == null) {
|
||||
throw new IllegalArgumentException("在插件 " + plugin.getName() + " 中未找到指令 " + getName() + ".");
|
||||
}
|
||||
command.setExecutor(this);
|
||||
command.setTabCompleter(this);
|
||||
plugin.getLogger().info("已注册指令 " + getUsage() + ".");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
if (!hasPermission(sender)) {
|
||||
CoreMessage.COMMAND_NOT_HAS_PERMISSION.show(sender);
|
||||
return true;
|
||||
}
|
||||
if (args.length == 0) {
|
||||
sendHelp(sender);
|
||||
return true;
|
||||
}
|
||||
for (ChildCommand childCommand : childCommands) {
|
||||
if (!childCommand.getName().equalsIgnoreCase(args[0])) {
|
||||
continue;
|
||||
}
|
||||
if (!childCommand.hasPermission(sender)) {
|
||||
CoreMessage.COMMAND_NOT_HAS_PERMISSION.show(sender);
|
||||
return true;
|
||||
}
|
||||
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(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||
if (args.length == 0) {
|
||||
return childCommands.stream()
|
||||
.filter(o -> o.hasPermission(sender))
|
||||
.map(ChildCommand::getName)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
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()
|
||||
.filter(o -> o.hasPermission(sender))
|
||||
.map(ChildCommand::getName)
|
||||
.filter(o -> o.toLowerCase().startsWith(args[0].toLowerCase()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.command.core;
|
||||
|
||||
import cn.hamster3.mc.plugin.core.bukkit.HamsterCorePlugin;
|
||||
import cn.hamster3.mc.plugin.core.bukkit.command.ParentCommand;
|
||||
import cn.hamster3.mc.plugin.core.bukkit.command.core.sub.*;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ParentCoreCommand extends ParentCommand {
|
||||
public static final ParentCoreCommand INSTANCE = new ParentCoreCommand();
|
||||
|
||||
private ParentCoreCommand() {
|
||||
super("hamster-core");
|
||||
addChildCommand(EnvCommand.INSTANCE);
|
||||
addChildCommand(GCCommand.INSTANCE);
|
||||
addChildCommand(YamlCommand.INSTANCE);
|
||||
addChildCommand(InfoModeCommand.INSTANCE);
|
||||
addChildCommand(ReloadCommand.INSTANCE);
|
||||
addChildCommand(MemoryCommand.INSTANCE);
|
||||
addChildCommand(SystemCommand.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull JavaPlugin getPlugin() {
|
||||
return HamsterCorePlugin.getInstance();
|
||||
}
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.command.core.sub;
|
||||
|
||||
import cn.hamster3.mc.plugin.core.bukkit.command.ChildCommand;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class EnvCommand extends ChildCommand {
|
||||
public static final EnvCommand INSTANCE = new EnvCommand();
|
||||
|
||||
private EnvCommand() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return "env";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getUsage() {
|
||||
return "env [变量名]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull CommandSender sender) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getDescription() {
|
||||
return "获取系统环境变量";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
if (args.length < 1) {
|
||||
sender.sendMessage(System.getenv().toString());
|
||||
return true;
|
||||
}
|
||||
sender.sendMessage(args[0] + "=" + System.getenv().getOrDefault(args[0], ""));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||
if (args.length == 1) {
|
||||
String lowerCase = args[0].toLowerCase();
|
||||
return System.getenv().keySet()
|
||||
.stream()
|
||||
.filter(o -> o.toLowerCase().startsWith(lowerCase))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.command.core.sub;
|
||||
|
||||
import cn.hamster3.mc.plugin.core.bukkit.command.ChildCommand;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class GCCommand extends ChildCommand {
|
||||
public static final GCCommand INSTANCE = new GCCommand();
|
||||
|
||||
private GCCommand() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return "gc";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getUsage() {
|
||||
return "gc";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull CommandSender sender) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getDescription() {
|
||||
return "通知 JVM 进行一次垃圾回收";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
System.gc();
|
||||
sender.sendMessage("§a已发送 GC 信号.");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
@@ -0,0 +1,81 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.command.core.sub;
|
||||
|
||||
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 java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class InfoModeCommand extends ChildCommand {
|
||||
public static final InfoModeCommand INSTANCE = new InfoModeCommand();
|
||||
|
||||
private InfoModeCommand() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("SpellCheckingInspection")
|
||||
public @NotNull String getName() {
|
||||
return "infomode";
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("SpellCheckingInspection")
|
||||
public @NotNull String getUsage() {
|
||||
return "infomode [on/off]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull CommandSender sender) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getDescription() {
|
||||
return "开启信息查询模式";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull 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.INFO_MODE_PLAYERS.add(uuid);
|
||||
CoreMessage.COMMAND_DEBUG_INFO_MODE_ON.show(player);
|
||||
return true;
|
||||
}
|
||||
case "0":
|
||||
case "off": {
|
||||
DebugListener.INFO_MODE_PLAYERS.remove(uuid);
|
||||
CoreMessage.COMMAND_DEBUG_INFO_MODE_OFF.show(player);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DebugListener.INFO_MODE_PLAYERS.contains(uuid)) {
|
||||
DebugListener.INFO_MODE_PLAYERS.remove(uuid);
|
||||
CoreMessage.COMMAND_DEBUG_INFO_MODE_OFF.show(player);
|
||||
} else {
|
||||
DebugListener.INFO_MODE_PLAYERS.add(uuid);
|
||||
CoreMessage.COMMAND_DEBUG_INFO_MODE_ON.show(player);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.command.core.sub;
|
||||
|
||||
import cn.hamster3.mc.plugin.core.bukkit.command.ChildCommand;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class MemoryCommand extends ChildCommand {
|
||||
public static final MemoryCommand INSTANCE = new MemoryCommand();
|
||||
|
||||
private MemoryCommand() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return "memory";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getUsage() {
|
||||
return "memory";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull CommandSender sender) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getDescription() {
|
||||
return "查看内存信息";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
sender.sendMessage(String.format("活跃内存:%.2f MB", (runtime.totalMemory() - runtime.freeMemory()) / 1024.0 / 1024.0));
|
||||
sender.sendMessage(String.format("空闲内存:%.2f MB", runtime.freeMemory() / 1024.0 / 1024.0));
|
||||
sender.sendMessage(String.format("占用系统内存:%.2f MB", runtime.totalMemory() / 1024.0 / 1024.0));
|
||||
sender.sendMessage(String.format("最大可用内存:%.2f MB", runtime.maxMemory() / 1024.0 / 1024.0));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.command.core.sub;
|
||||
|
||||
import cn.hamster3.mc.plugin.core.bukkit.command.ChildCommand;
|
||||
import cn.hamster3.mc.plugin.core.bukkit.page.PageManager;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ReloadCommand extends ChildCommand {
|
||||
public static final ReloadCommand INSTANCE = new ReloadCommand();
|
||||
|
||||
private ReloadCommand() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return "reload";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getUsage() {
|
||||
return "reload";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull CommandSender sender) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getDescription() {
|
||||
return "重载页面配置文件";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
PageManager.PAGE_CONFIG.clear();
|
||||
sender.sendMessage("§a已重载页面配置文件.");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.command.core.sub;
|
||||
|
||||
import cn.hamster3.mc.plugin.core.bukkit.command.ChildCommand;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SystemCommand extends ChildCommand {
|
||||
public static final SystemCommand INSTANCE = new SystemCommand();
|
||||
|
||||
private SystemCommand() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return "system";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getUsage() {
|
||||
return "system";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull CommandSender sender) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getDescription() {
|
||||
return "查看系统属性";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
if (args.length < 1) {
|
||||
sender.sendMessage(System.getProperties().toString());
|
||||
return true;
|
||||
}
|
||||
sender.sendMessage(args[0] + "=" + System.getProperty(args[0], ""));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||
if (args.length == 1) {
|
||||
String lowerCase = args[0].toLowerCase();
|
||||
return System.getProperties().keySet()
|
||||
.stream()
|
||||
.map(Object::toString)
|
||||
.filter(o -> o.toLowerCase().startsWith(lowerCase))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
@@ -0,0 +1,97 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.command.core.sub;
|
||||
|
||||
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.CoreBukkitUtils;
|
||||
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 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 boolean hasPermission(@NotNull CommandSender sender) {
|
||||
return sender.hasPermission("hamster.core.admin");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getDescription() {
|
||||
return "将当前信息保存至 yaml 中";
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "ConstantConditions"})
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
YamlConfiguration config = new YamlConfiguration();
|
||||
config.set("mc-version", CoreBukkitUtils.getMCVersion());
|
||||
config.set("nms-version", CoreBukkitUtils.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.setDisplayName("§a测试物品");
|
||||
meta.setLore(lore);
|
||||
meta.addItemFlags(ItemFlag.values());
|
||||
meta.addEnchant(Enchantment.DAMAGE_ALL, 1, true);
|
||||
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(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.command.lore;
|
||||
|
||||
import cn.hamster3.mc.plugin.core.bukkit.HamsterCorePlugin;
|
||||
import cn.hamster3.mc.plugin.core.bukkit.command.ParentCommand;
|
||||
import cn.hamster3.mc.plugin.core.bukkit.command.lore.sub.*;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class ParentLoreCommand extends ParentCommand {
|
||||
public static final ParentLoreCommand INSTANCE = new ParentLoreCommand();
|
||||
|
||||
public ParentLoreCommand() {
|
||||
super("lore");
|
||||
addChildCommand(LoreAddCommand.INSTANCE);
|
||||
addChildCommand(LoreRemoveCommand.INSTANCE);
|
||||
addChildCommand(LoreSetCommand.INSTANCE);
|
||||
addChildCommand(LoreClearCommand.INSTANCE);
|
||||
addChildCommand(LoreNameCommand.INSTANCE);
|
||||
addChildCommand(LoreCustomModelDataCommand.INSTANCE);
|
||||
addChildCommand(LoreFlagCommand.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull JavaPlugin getPlugin() {
|
||||
return HamsterCorePlugin.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
args[i] = args[i].replace("&", "§");
|
||||
}
|
||||
return super.onCommand(sender, command, label, args);
|
||||
}
|
||||
}
|
@@ -0,0 +1,77 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.command.lore.sub;
|
||||
|
||||
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.util.CoreBukkitUtils;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class LoreAddCommand extends ChildCommand {
|
||||
public static final LoreAddCommand INSTANCE = new LoreAddCommand();
|
||||
|
||||
private LoreAddCommand() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return "add";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getUsage() {
|
||||
return "add <lore>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull CommandSender sender) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getDescription() {
|
||||
return "为手持物品添加一条 lore";
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
if (args.length < 1) {
|
||||
CoreMessage.COMMAND_LORE_EMPTY_INPUT.show(sender);
|
||||
return true;
|
||||
}
|
||||
if (!(sender instanceof Player)) {
|
||||
CoreMessage.COMMAND_MUST_USED_BY_PLAYER.show(sender);
|
||||
return true;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
ItemStack stack = player.getItemInHand();
|
||||
if (CoreBukkitUtils.isEmptyItemStack(stack)) {
|
||||
CoreMessage.COMMAND_LORE_HAND_EMPTY.show(player);
|
||||
return true;
|
||||
}
|
||||
ItemMeta meta = stack.getItemMeta();
|
||||
if (meta != null) {
|
||||
List<String> lore = meta.getLore();
|
||||
if (lore == null) {
|
||||
lore = new ArrayList<>();
|
||||
}
|
||||
lore.add(String.join(" ", args));
|
||||
meta.setLore(lore);
|
||||
}
|
||||
stack.setItemMeta(meta);
|
||||
CoreMessage.COMMAND_LORE_ADD_SUCCESS.show(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.command.lore.sub;
|
||||
|
||||
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.util.CoreBukkitUtils;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class LoreClearCommand extends ChildCommand {
|
||||
public static final LoreClearCommand INSTANCE = new LoreClearCommand();
|
||||
|
||||
private LoreClearCommand() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return "clear";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getUsage() {
|
||||
return "clear";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull CommandSender sender) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getDescription() {
|
||||
return "清除手持物品的所有 lore";
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
if (!(sender instanceof Player)) {
|
||||
CoreMessage.COMMAND_MUST_USED_BY_PLAYER.show(sender);
|
||||
return true;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
ItemStack stack = player.getItemInHand();
|
||||
if (CoreBukkitUtils.isEmptyItemStack(stack)) {
|
||||
CoreMessage.COMMAND_LORE_HAND_EMPTY.show(player);
|
||||
return true;
|
||||
}
|
||||
ItemMeta meta = stack.getItemMeta();
|
||||
if (meta != null) {
|
||||
List<String> lore = meta.getLore();
|
||||
if (lore == null || lore.isEmpty()) {
|
||||
CoreMessage.COMMAND_LORE_CLEAR_NOTHING.show(player);
|
||||
return true;
|
||||
}
|
||||
meta.setLore(new ArrayList<>());
|
||||
}
|
||||
stack.setItemMeta(meta);
|
||||
CoreMessage.COMMAND_LORE_CLEAR_SUCCESS.show(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,83 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.command.lore.sub;
|
||||
|
||||
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.util.CoreBukkitUtils;
|
||||
import net.kyori.adventure.text.TextReplacementConfig;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LoreCustomModelDataCommand extends ChildCommand {
|
||||
public static final LoreCustomModelDataCommand INSTANCE = new LoreCustomModelDataCommand();
|
||||
|
||||
private LoreCustomModelDataCommand() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return "cmd";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getUsage() {
|
||||
return "cmd [data]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull CommandSender sender) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getDescription() {
|
||||
return "设置手持物品的自定义模型数据";
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
if (!(sender instanceof Player)) {
|
||||
CoreMessage.COMMAND_MUST_USED_BY_PLAYER.show(sender);
|
||||
return true;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
ItemStack stack = player.getItemInHand();
|
||||
if (CoreBukkitUtils.isEmptyItemStack(stack)) {
|
||||
CoreMessage.COMMAND_LORE_HAND_EMPTY.show(player);
|
||||
return true;
|
||||
}
|
||||
ItemMeta meta = stack.getItemMeta();
|
||||
if (meta == null) {
|
||||
return true;
|
||||
}
|
||||
if (args.length < 1) {
|
||||
meta.setCustomModelData(null);
|
||||
stack.setItemMeta(meta);
|
||||
CoreMessage.COMMAND_LORE_CMD_CLEAR_SUCCESS.show(sender);
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
int data = Integer.parseInt(args[0]);
|
||||
meta.setCustomModelData(data);
|
||||
stack.setItemMeta(meta);
|
||||
CoreMessage.COMMAND_LORE_CMD_SET_SUCCESS.show(sender, TextReplacementConfig.builder()
|
||||
.matchLiteral("%data%").replacement(args[0])
|
||||
.build());
|
||||
} catch (NumberFormatException e) {
|
||||
CoreMessage.COMMAND_LORE_CMD_SET_INPUT_ERROR.show(sender);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,91 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.command.lore.sub;
|
||||
|
||||
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.util.CoreBukkitUtils;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
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 java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class LoreFlagCommand extends ChildCommand {
|
||||
public static final LoreFlagCommand INSTANCE = new LoreFlagCommand();
|
||||
|
||||
private LoreFlagCommand() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return "flag";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getUsage() {
|
||||
return "flag <ItemFlag>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull CommandSender sender) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getDescription() {
|
||||
return "为手持物品添加一条 lore";
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
if (args.length < 1) {
|
||||
CoreMessage.COMMAND_LORE_EMPTY_INPUT.show(sender);
|
||||
return true;
|
||||
}
|
||||
if (!(sender instanceof Player)) {
|
||||
CoreMessage.COMMAND_MUST_USED_BY_PLAYER.show(sender);
|
||||
return true;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
ItemStack stack = player.getItemInHand();
|
||||
if (CoreBukkitUtils.isEmptyItemStack(stack)) {
|
||||
CoreMessage.COMMAND_LORE_HAND_EMPTY.show(player);
|
||||
return true;
|
||||
}
|
||||
ItemFlag flag;
|
||||
try {
|
||||
flag = ItemFlag.valueOf(args[0]);
|
||||
} catch (IllegalArgumentException e) {
|
||||
CoreMessage.COMMAND_LORE_FLAG_SET_INPUT_ERROR.show(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
ItemMeta meta = stack.getItemMeta();
|
||||
if (meta != null) {
|
||||
if (meta.hasItemFlag(flag)) {
|
||||
meta.removeItemFlags(flag);
|
||||
CoreMessage.COMMAND_LORE_FLAG_REMOVE_SUCCESS.show(player);
|
||||
} else {
|
||||
meta.addItemFlags(flag);
|
||||
CoreMessage.COMMAND_LORE_FLAG_SET_SUCCESS.show(player);
|
||||
}
|
||||
}
|
||||
stack.setItemMeta(meta);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||
return Arrays.stream(ItemFlag.values())
|
||||
.map(Enum::name)
|
||||
.filter(o -> o.startsWith(args[0].toUpperCase()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.command.lore.sub;
|
||||
|
||||
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.util.CoreBukkitUtils;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LoreNameCommand extends ChildCommand {
|
||||
public static final LoreNameCommand INSTANCE = new LoreNameCommand();
|
||||
|
||||
private LoreNameCommand() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return "name";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getUsage() {
|
||||
return "name <name>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull CommandSender sender) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getDescription() {
|
||||
return "更改手持物品的显示名称";
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
if (args.length < 1) {
|
||||
CoreMessage.COMMAND_LORE_EMPTY_INPUT.show(sender);
|
||||
return true;
|
||||
}
|
||||
if (!(sender instanceof Player)) {
|
||||
CoreMessage.COMMAND_MUST_USED_BY_PLAYER.show(sender);
|
||||
return true;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
ItemStack stack = player.getItemInHand();
|
||||
if (CoreBukkitUtils.isEmptyItemStack(stack)) {
|
||||
CoreMessage.COMMAND_LORE_HAND_EMPTY.show(player);
|
||||
return true;
|
||||
}
|
||||
ItemMeta meta = stack.getItemMeta();
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(String.join(" ", args));
|
||||
}
|
||||
stack.setItemMeta(meta);
|
||||
CoreMessage.COMMAND_LORE_NAME_SUCCESS.show(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,86 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.command.lore.sub;
|
||||
|
||||
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.util.CoreBukkitUtils;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class LoreRemoveCommand extends ChildCommand {
|
||||
public static final LoreRemoveCommand INSTANCE = new LoreRemoveCommand();
|
||||
|
||||
private LoreRemoveCommand() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return "remove";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getUsage() {
|
||||
return "remove <line>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull CommandSender sender) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getDescription() {
|
||||
return "为手持物品删除一条 lore";
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
if (args.length < 1) {
|
||||
CoreMessage.COMMAND_LORE_REMOVE_NOT_INPUT_NUMBER.show(sender);
|
||||
return true;
|
||||
}
|
||||
if (!(sender instanceof Player)) {
|
||||
CoreMessage.COMMAND_MUST_USED_BY_PLAYER.show(sender);
|
||||
return true;
|
||||
}
|
||||
int i = Integer.parseInt(args[0]);
|
||||
if (i <= 0) {
|
||||
CoreMessage.COMMAND_LORE_REMOVE_INPUT_NUMBER_ERROR.show(sender);
|
||||
return true;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
ItemStack stack = player.getItemInHand();
|
||||
if (CoreBukkitUtils.isEmptyItemStack(stack)) {
|
||||
CoreMessage.COMMAND_LORE_HAND_EMPTY.show(player);
|
||||
return true;
|
||||
}
|
||||
ItemMeta meta = stack.getItemMeta();
|
||||
if (meta != null) {
|
||||
List<String> lore = meta.getLore();
|
||||
if (lore == null) {
|
||||
lore = new ArrayList<>();
|
||||
}
|
||||
if (lore.size() < i) {
|
||||
CoreMessage.COMMAND_LORE_REMOVE_INDEX_OUT_OF_RANGE.show(player);
|
||||
return true;
|
||||
}
|
||||
lore.remove(i - 1);
|
||||
meta.setLore(lore);
|
||||
}
|
||||
stack.setItemMeta(meta);
|
||||
CoreMessage.COMMAND_LORE_REMOVE_SUCCESS.show(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,92 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.command.lore.sub;
|
||||
|
||||
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.util.CoreBukkitUtils;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class LoreSetCommand extends ChildCommand {
|
||||
public static final LoreSetCommand INSTANCE = new LoreSetCommand();
|
||||
|
||||
private LoreSetCommand() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return "set";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getUsage() {
|
||||
return "set <line> <lore>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull CommandSender sender) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getDescription() {
|
||||
return "设置指定行数的 lore";
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
if (args.length < 1) {
|
||||
CoreMessage.COMMAND_LORE_SET_NOT_INPUT_NUMBER.show(sender);
|
||||
return true;
|
||||
}
|
||||
if (args.length < 2) {
|
||||
CoreMessage.COMMAND_LORE_SET_NOT_INPUT_TEXT.show(sender);
|
||||
return true;
|
||||
}
|
||||
if (!(sender instanceof Player)) {
|
||||
CoreMessage.COMMAND_MUST_USED_BY_PLAYER.show(sender);
|
||||
return true;
|
||||
}
|
||||
int i = Integer.parseInt(args[0]);
|
||||
if (i <= 0) {
|
||||
CoreMessage.COMMAND_LORE_SET_INPUT_NUMBER_ERROR.show(sender);
|
||||
return true;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
ItemStack stack = player.getItemInHand();
|
||||
if (CoreBukkitUtils.isEmptyItemStack(stack)) {
|
||||
CoreMessage.COMMAND_LORE_HAND_EMPTY.show(player);
|
||||
return true;
|
||||
}
|
||||
ItemMeta meta = stack.getItemMeta();
|
||||
if (meta != null) {
|
||||
List<String> lore = meta.getLore();
|
||||
if (lore == null) {
|
||||
lore = new ArrayList<>();
|
||||
}
|
||||
if (lore.size() < i) {
|
||||
CoreMessage.COMMAND_LORE_SET_INDEX_OUT_OF_RANGE.show(player);
|
||||
return true;
|
||||
}
|
||||
args = Arrays.copyOfRange(args, 1, args.length);
|
||||
lore.set(i - 1, String.join(" ", args));
|
||||
meta.setLore(lore);
|
||||
}
|
||||
stack.setItemMeta(meta);
|
||||
CoreMessage.COMMAND_LORE_SET_SUCCESS.show(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,76 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.constant;
|
||||
|
||||
import cn.hamster3.mc.plugin.core.bukkit.api.CoreBukkitAPI;
|
||||
import cn.hamster3.mc.plugin.core.bukkit.util.CoreBukkitUtils;
|
||||
import cn.hamster3.mc.plugin.core.common.data.DisplayMessage;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.kyori.adventure.text.TextReplacementConfig;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public enum CoreMessage {
|
||||
COMMAND_NOT_FOUND,
|
||||
COMMAND_NOT_HAS_PERMISSION,
|
||||
COMMAND_MUST_USED_BY_PLAYER,
|
||||
COMMAND_DEBUG_INFO_MODE_ON,
|
||||
COMMAND_DEBUG_INFO_MODE_OFF,
|
||||
COMMAND_LORE_HAND_EMPTY,
|
||||
COMMAND_LORE_EMPTY_INPUT,
|
||||
COMMAND_LORE_ADD_SUCCESS,
|
||||
COMMAND_LORE_CLEAR_NOTHING,
|
||||
COMMAND_LORE_CLEAR_SUCCESS,
|
||||
COMMAND_LORE_CMD_CLEAR_SUCCESS,
|
||||
COMMAND_LORE_CMD_SET_SUCCESS,
|
||||
COMMAND_LORE_CMD_SET_INPUT_ERROR,
|
||||
COMMAND_LORE_FLAG_SET_SUCCESS,
|
||||
COMMAND_LORE_FLAG_REMOVE_SUCCESS,
|
||||
COMMAND_LORE_FLAG_SET_INPUT_ERROR,
|
||||
COMMAND_LORE_NAME_SUCCESS,
|
||||
COMMAND_LORE_REMOVE_NOT_INPUT_NUMBER,
|
||||
COMMAND_LORE_REMOVE_INPUT_NUMBER_ERROR,
|
||||
COMMAND_LORE_REMOVE_INDEX_OUT_OF_RANGE,
|
||||
COMMAND_LORE_REMOVE_SUCCESS,
|
||||
COMMAND_LORE_SET_NOT_INPUT_NUMBER,
|
||||
COMMAND_LORE_SET_INPUT_NUMBER_ERROR,
|
||||
COMMAND_LORE_SET_NOT_INPUT_TEXT,
|
||||
COMMAND_LORE_SET_INDEX_OUT_OF_RANGE,
|
||||
COMMAND_LORE_SET_SUCCESS;
|
||||
|
||||
private DisplayMessage message;
|
||||
|
||||
public static void init(@NotNull Plugin plugin) {
|
||||
ConfigurationSection config = plugin.getConfig().getConfigurationSection("messages");
|
||||
if (config == null) {
|
||||
plugin.getLogger().warning("加载消息失败: 配置文件中未找到 messages 节点!");
|
||||
return;
|
||||
}
|
||||
for (CoreMessage value : values()) {
|
||||
ConfigurationSection section = config.getConfigurationSection(value.name());
|
||||
if (section == null) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
value.message = CoreBukkitUtils.getDisplayMessage(section);
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().warning("加载消息设置 " + value.name() + " 时遇到了一个异常: ");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void show(CommandSender sender, TextReplacementConfig... replacement) {
|
||||
if (message == null) {
|
||||
sender.sendMessage(name());
|
||||
return;
|
||||
}
|
||||
Audience audience = CoreBukkitAPI.getInstance().getAudienceProvider().sender(sender);
|
||||
message.show(audience, replacement);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public DisplayMessage getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
@@ -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 getPoint(final OfflinePlayer player) {
|
||||
if (playerPointsAPI != null) {
|
||||
return playerPointsAPI.look(player.getUniqueId());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看玩家的点券数量
|
||||
*
|
||||
* @param uuid 玩家的uuid
|
||||
* @return 玩家的点券数量
|
||||
*/
|
||||
public static int getPoint(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,81 @@
|
||||
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());
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@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());
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@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());
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@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,90 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.listener;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
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> INFO_MODE_PLAYERS = new HashSet<>();
|
||||
|
||||
private DebugListener() {
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOW)
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
UUID uuid = player.getUniqueId();
|
||||
INFO_MODE_PLAYERS.remove(uuid);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOW)
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
UUID uuid = player.getUniqueId();
|
||||
if (!INFO_MODE_PLAYERS.contains(uuid)) {
|
||||
return;
|
||||
}
|
||||
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
|
||||
return;
|
||||
}
|
||||
event.setCancelled(true);
|
||||
Block block = event.getClickedBlock();
|
||||
if (block == null) {
|
||||
return;
|
||||
}
|
||||
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());
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOW)
|
||||
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
UUID uuid = player.getUniqueId();
|
||||
if (!INFO_MODE_PLAYERS.contains(uuid)) {
|
||||
return;
|
||||
}
|
||||
event.setCancelled(true);
|
||||
Entity entity = event.getRightClicked();
|
||||
player.sendMessage("§e==============================");
|
||||
Location location = entity.getLocation();
|
||||
player.sendMessage(String.format("§a实体位置: %s %.2f %.2f %.2f %.2f %.2f",
|
||||
entity.getWorld().getName(), location.getX(),
|
||||
location.getY(),
|
||||
location.getZ(),
|
||||
location.getPitch(),
|
||||
location.getYaw()
|
||||
));
|
||||
player.sendMessage("§a实体UUID: " + entity.getUniqueId());
|
||||
player.sendMessage("§a实体类型: " + entity.getType().name());
|
||||
player.sendMessage("§a实体名称: " + entity.getName());
|
||||
player.sendMessage("§a自定义名称: " + entity.getCustomName());
|
||||
player.sendMessage("§a名称可见: " + entity.isCustomNameVisible());
|
||||
player.sendMessage("§a计分板标签: " + entity.getScoreboardTags());
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,195 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.page;
|
||||
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class ButtonGroup {
|
||||
@NotNull
|
||||
private final String name;
|
||||
@NotNull
|
||||
private final PageConfig config;
|
||||
@NotNull
|
||||
private final Map<Character, String> buttonNameMap;
|
||||
|
||||
/**
|
||||
* 实例化这个按钮组
|
||||
*
|
||||
* @param pageConfig Page 设定
|
||||
* @param config 按钮组设定
|
||||
*/
|
||||
public ButtonGroup(@NotNull PageConfig pageConfig, @NotNull ConfigurationSection config) {
|
||||
this.config = pageConfig;
|
||||
name = config.getName();
|
||||
buttonNameMap = new HashMap<>();
|
||||
for (String key : config.getKeys(false)) {
|
||||
buttonNameMap.put(key.charAt(0), config.getString(key));
|
||||
}
|
||||
}
|
||||
|
||||
public ButtonGroup(@NotNull String name, @NotNull PageConfig config, @NotNull Map<Character, String> buttonNameMap) {
|
||||
this.name = name;
|
||||
this.config = config;
|
||||
this.buttonNameMap = buttonNameMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 以图形字符来获取按钮名称
|
||||
* <p>
|
||||
* 若未找到则返回 "empty"
|
||||
*
|
||||
* @param graphicKey 图形字符
|
||||
* @return 按钮名称
|
||||
*/
|
||||
@NotNull
|
||||
public String getButtonName(char graphicKey) {
|
||||
return buttonNameMap.getOrDefault(graphicKey, "empty");
|
||||
}
|
||||
|
||||
/**
|
||||
* 以索引位置来获取按钮名称
|
||||
* <p>
|
||||
* 若未找到则返回 "empty"
|
||||
*
|
||||
* @param index 索引位置
|
||||
* @return 按钮名称
|
||||
*/
|
||||
@NotNull
|
||||
public String getButtonName(int index) {
|
||||
return buttonNameMap.getOrDefault(config.getButtonKey(index), "empty");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取按钮在 GUI 中的第一个索引位置
|
||||
*
|
||||
* @param buttonName 按钮名称
|
||||
* @return 按钮在 GUI 中的第一个索引位置
|
||||
*/
|
||||
public int getButtonIndex(String buttonName) {
|
||||
Character graphicKey = getGraphicKey(buttonName);
|
||||
if (graphicKey == null) {
|
||||
return -1;
|
||||
}
|
||||
List<String> graphic = config.getGraphic();
|
||||
for (int i = 0; i < graphic.size(); i++) {
|
||||
char[] chars = graphic.get(i).toCharArray();
|
||||
for (int j = 0; j < chars.length; j++) {
|
||||
if (chars[j] == graphicKey) {
|
||||
return i * 9 + j;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得按钮在 GUI 中全部的索引位置
|
||||
*
|
||||
* @param buttonName 按钮名称
|
||||
* @return 按钮在 GUI 中全部的索引位置
|
||||
*/
|
||||
public ArrayList<Integer> getButtonAllIndex(@NotNull String buttonName) {
|
||||
ArrayList<Integer> list = new ArrayList<>();
|
||||
|
||||
Character graphicKey = getGraphicKey(buttonName);
|
||||
if (graphicKey == null) {
|
||||
return list;
|
||||
}
|
||||
|
||||
List<String> graphic = config.getGraphic();
|
||||
for (int i = 0; i < graphic.size(); i++) {
|
||||
char[] chars = graphic.get(i).toCharArray();
|
||||
for (int j = 0; j < chars.length; j++) {
|
||||
if (chars[j] == graphicKey) {
|
||||
list.add(i * 9 + j);
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 以按钮名称来获取图形字符
|
||||
*
|
||||
* @param buttonName 按钮名称
|
||||
* @return 图形中的字符
|
||||
*/
|
||||
@Nullable
|
||||
public Character getGraphicKey(@NotNull String buttonName) {
|
||||
for (Map.Entry<Character, String> entry : buttonNameMap.entrySet()) {
|
||||
if (entry.getValue().equalsIgnoreCase(buttonName)) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 以图形字符来获取按钮物品
|
||||
*
|
||||
* @param graphicKey 图形字符
|
||||
* @return 按钮物品
|
||||
*/
|
||||
public ItemStack getButtonItem(char graphicKey) {
|
||||
return getButtonItem(getButtonName(graphicKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* 以按钮名称来获取按钮物品
|
||||
*
|
||||
* @param buttonName 按钮名称
|
||||
* @return 按钮物品
|
||||
*/
|
||||
public ItemStack getButtonItem(@NotNull String buttonName) {
|
||||
ItemStack stack = config.getButtons().get(buttonName);
|
||||
if (stack != null) {
|
||||
stack = stack.clone();
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取这个按钮组的名称
|
||||
*
|
||||
* @return 按钮组名称
|
||||
*/
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取把图形字符映射到按钮名称的表
|
||||
*
|
||||
* @return 把图形字符映射到按钮名称的表
|
||||
*/
|
||||
@NotNull
|
||||
public Map<Character, String> getButtonNameMap() {
|
||||
return buttonNameMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ButtonGroup that = (ButtonGroup) o;
|
||||
return name.equals(that.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ButtonGroup{" +
|
||||
"name='" + name + '\'' +
|
||||
", buttonNameMap=" + buttonNameMap +
|
||||
'}';
|
||||
}
|
||||
}
|
@@ -0,0 +1,206 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.page;
|
||||
|
||||
import cn.hamster3.mc.plugin.core.bukkit.HamsterCorePlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class PageConfig implements InventoryHolder {
|
||||
@NotNull
|
||||
private final Plugin plugin;
|
||||
@NotNull
|
||||
private final ConfigurationSection rawConfig;
|
||||
|
||||
@NotNull
|
||||
private final String title;
|
||||
@NotNull
|
||||
private final List<String> graphic;
|
||||
|
||||
@NotNull
|
||||
private final ArrayList<ButtonGroup> buttonGroups;
|
||||
@NotNull
|
||||
private final HashMap<String, Sound> buttonSounds;
|
||||
@NotNull
|
||||
private final HashMap<String, ItemStack> buttons;
|
||||
|
||||
@NotNull
|
||||
private final Inventory inventory;
|
||||
|
||||
public PageConfig(@NotNull Plugin plugin, @NotNull ConfigurationSection rawConfig) {
|
||||
this.plugin = plugin;
|
||||
this.rawConfig = rawConfig;
|
||||
title = rawConfig.getString("title", "").replace("&", "§");
|
||||
|
||||
List<String> graphicString = rawConfig.getStringList("graphic");
|
||||
if (graphicString.size() > 6) {
|
||||
graphicString = graphicString.subList(0, 6);
|
||||
}
|
||||
for (int i = 0; i < graphicString.size(); i++) {
|
||||
String s = graphicString.get(i);
|
||||
if (s.length() > 9) {
|
||||
s = s.substring(0, 9);
|
||||
}
|
||||
graphicString.set(i, s);
|
||||
}
|
||||
graphic = graphicString;
|
||||
|
||||
inventory = Bukkit.createInventory(this, graphicString.size() * 9, title);
|
||||
|
||||
buttons = new HashMap<>();
|
||||
ConfigurationSection buttonsConfig = rawConfig.getConfigurationSection("buttons");
|
||||
if (buttonsConfig != null) {
|
||||
for (String key : buttonsConfig.getKeys(false)) {
|
||||
buttons.put(key, buttonsConfig.getItemStack(key));
|
||||
}
|
||||
}
|
||||
|
||||
buttonGroups = new ArrayList<>();
|
||||
ConfigurationSection buttonGroupsConfig = rawConfig.getConfigurationSection("groups");
|
||||
if (buttonGroupsConfig != null) {
|
||||
for (String key : buttonGroupsConfig.getKeys(false)) {
|
||||
//noinspection ConstantConditions
|
||||
ButtonGroup buttonGroup = new ButtonGroup(this, buttonGroupsConfig.getConfigurationSection(key));
|
||||
buttonGroups.add(buttonGroup);
|
||||
}
|
||||
}
|
||||
|
||||
ButtonGroup group = getButtonGroup("default");
|
||||
for (int i = 0; i < graphicString.size(); i++) {
|
||||
char[] chars = graphicString.get(i).toCharArray();
|
||||
for (int j = 0; j < chars.length; j++) {
|
||||
char c = chars[j];
|
||||
int index = i * 9 + j;
|
||||
inventory.setItem(index, group.getButtonItem(c));
|
||||
}
|
||||
}
|
||||
|
||||
buttonSounds = new HashMap<>();
|
||||
ConfigurationSection buttonSoundConfig = rawConfig.getConfigurationSection("sounds");
|
||||
if (buttonSoundConfig != null) {
|
||||
for (String key : buttonSoundConfig.getKeys(false)) {
|
||||
String soundName = buttonSoundConfig.getString(key, "");
|
||||
if (soundName.isEmpty() || soundName.equalsIgnoreCase("null")) {
|
||||
buttonSounds.put(key, null);
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
buttonSounds.put(key, Sound.valueOf(soundName));
|
||||
} catch (Exception e) {
|
||||
HamsterCorePlugin.getInstance().getLogger().warning("初始化 PageConfig 时遇到了一个异常:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取把 buttonName 映射到 展示物品 的表
|
||||
*
|
||||
* @return 把 buttonName 映射到 展示物品 的表
|
||||
*/
|
||||
@NotNull
|
||||
public HashMap<String, ItemStack> getButtons() {
|
||||
return buttons;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取索引位置上的 graphicKey
|
||||
*
|
||||
* @param index 索引
|
||||
* @return 若超出 graphic 范围则返回 null
|
||||
*/
|
||||
@Nullable
|
||||
public Character getButtonKey(int index) {
|
||||
if (index < 0) return null;
|
||||
if (index / 9 >= graphic.size()) return null;
|
||||
String s = graphic.get(index / 9);
|
||||
return s.charAt(index % 9);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取该显示物品对应的 buttonName
|
||||
*
|
||||
* @param stack 显示物品
|
||||
* @return 按钮名称,若无法找到则返回 "empty"
|
||||
*/
|
||||
@NotNull
|
||||
public String getButtonName(@Nullable ItemStack stack) {
|
||||
if (stack == null) {
|
||||
return "empty";
|
||||
}
|
||||
for (Map.Entry<String, ItemStack> entry : buttons.entrySet()) {
|
||||
if (entry.getValue().isSimilar(stack)) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
return "empty";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Sound getButtonSound(@NotNull String buttonName) {
|
||||
return buttonSounds.get(buttonName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ButtonGroup getButtonGroup(@NotNull String groupName) {
|
||||
for (ButtonGroup group : buttonGroups) {
|
||||
if (group.getName().equalsIgnoreCase(groupName)) {
|
||||
return group;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("未找到名称为 " + groupName + " 的按钮编组!");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigurationSection getRawConfig() {
|
||||
return rawConfig;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<String> getGraphic() {
|
||||
return graphic;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ArrayList<ButtonGroup> getButtonGroups() {
|
||||
return buttonGroups;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PageConfig{" +
|
||||
", title='" + title + '\'' +
|
||||
", graphic=" + graphic +
|
||||
", buttonMap=" + buttons +
|
||||
", buttonGroups=" + buttonGroups +
|
||||
'}';
|
||||
}
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.page;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class PageManager {
|
||||
public static final HashMap<String, PageConfig> PAGE_CONFIG = new HashMap<>();
|
||||
|
||||
@NotNull
|
||||
public static PageConfig getPageConfig(@NotNull Class<?> clazz) {
|
||||
PageConfig pageConfig = PAGE_CONFIG.get(clazz.getName());
|
||||
if (pageConfig != null) {
|
||||
return pageConfig;
|
||||
}
|
||||
if (!clazz.isAnnotationPresent(PluginPage.class)) {
|
||||
throw new IllegalArgumentException(clazz.getName() + " 未被 @PluginPage 注解修饰!");
|
||||
}
|
||||
PluginPage annotation = clazz.getAnnotation(PluginPage.class);
|
||||
String pluginName = annotation.value();
|
||||
Plugin plugin = Bukkit.getPluginManager().getPlugin(pluginName);
|
||||
if (plugin == null) {
|
||||
throw new IllegalArgumentException("未找到插件 " + pluginName + " !");
|
||||
}
|
||||
pageConfig = getPageConfig(plugin, clazz.getSimpleName());
|
||||
PAGE_CONFIG.put(clazz.getName(), pageConfig);
|
||||
return pageConfig;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PageConfig getPageConfig(@NotNull Plugin plugin, @NotNull String pageName) {
|
||||
String pluginName = plugin.getName();
|
||||
File pageFolder = new File(plugin.getDataFolder(), "pages");
|
||||
if (pageFolder.mkdirs()) {
|
||||
plugin.getLogger().info("创建页面配置文件夹...");
|
||||
}
|
||||
String filename = pageName + ".yml";
|
||||
File pageConfigFile = new File(pageFolder, filename);
|
||||
if (pageConfigFile.exists()) {
|
||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(pageConfigFile);
|
||||
return new PageConfig(plugin, config);
|
||||
}
|
||||
try (InputStream resource = plugin.getResource("pages/" + filename)) {
|
||||
if (resource == null) {
|
||||
throw new IllegalArgumentException("在插件 " + plugin.getName() + " 的 Jar 文件内部未找到 /pages/" + filename + " !");
|
||||
}
|
||||
Files.copy(resource, pageConfigFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(pageConfigFile);
|
||||
return new PageConfig(plugin, config);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException("为插件 " + pluginName + " 加载页面配置文件 " + filename + " 时出错!", e);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.page;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface PluginPage {
|
||||
/**
|
||||
* @return 插件名称
|
||||
*/
|
||||
String value();
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
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.PageConfig;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 固定页面的 GUI
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class FixedPageHandler extends PageHandler {
|
||||
public FixedPageHandler(@NotNull HumanEntity player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
public FixedPageHandler(@NotNull PageConfig config, @NotNull HumanEntity player) {
|
||||
super(config, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initPage() {
|
||||
if (inventory == null) {
|
||||
inventory = Bukkit.createInventory(this, getPageConfig().getInventory().getSize(), getTitle());
|
||||
}
|
||||
HumanEntity player = getPlayer();
|
||||
|
||||
PageConfig config = getPageConfig();
|
||||
ButtonGroup group = getButtonGroup();
|
||||
|
||||
List<String> graphic = config.getGraphic();
|
||||
for (int i = 0; i < graphic.size(); i++) {
|
||||
char[] chars = graphic.get(i).toCharArray();
|
||||
for (int j = 0; j < chars.length; j++) {
|
||||
char c = chars[j];
|
||||
int index = i * 9 + j;
|
||||
inventory.setItem(index, group.getButtonItem(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,137 @@
|
||||
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.PageConfig;
|
||||
import cn.hamster3.mc.plugin.core.bukkit.page.PageManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.*;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* GUI 处理类
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class PageHandler implements InventoryHolder {
|
||||
private final PageConfig pageConfig;
|
||||
private final HumanEntity player;
|
||||
protected Inventory inventory;
|
||||
|
||||
public PageHandler(@NotNull HumanEntity player) {
|
||||
pageConfig = PageManager.getPageConfig(getClass());
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public PageHandler(@NotNull PageConfig pageConfig, @NotNull HumanEntity player) {
|
||||
this.pageConfig = pageConfig;
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public abstract void initPage();
|
||||
|
||||
public void onOpen(@NotNull InventoryOpenEvent event) {
|
||||
}
|
||||
|
||||
public void onClick(@NotNull InventoryClickEvent event) {
|
||||
if (event.getSlot() == event.getRawSlot()) {
|
||||
return;
|
||||
}
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
public void onClickInside(@NotNull InventoryClickEvent event) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
public void onClickInside(@NotNull ClickType clickType, @NotNull InventoryAction action, int index) {
|
||||
}
|
||||
|
||||
public void onPlayButtonSound(@NotNull ClickType clickType, @NotNull InventoryAction action, int index) {
|
||||
if (!(player instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
PageConfig config = getPageConfig();
|
||||
String buttonName = getButtonGroup().getButtonName(index);
|
||||
Sound sound = config.getButtonSound(buttonName);
|
||||
if (sound == null) {
|
||||
switch (buttonName) {
|
||||
case "empty":
|
||||
case "barrier":
|
||||
break;
|
||||
default:
|
||||
sound = config.getButtonSound("default");
|
||||
}
|
||||
}
|
||||
if (sound == null) {
|
||||
return;
|
||||
}
|
||||
((Player) player).playSound(player.getLocation(), sound, 1, 1);
|
||||
}
|
||||
|
||||
public void onDrag(@NotNull InventoryDragEvent event) {
|
||||
}
|
||||
|
||||
public void onDragInside(@NotNull InventoryDragEvent event) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
public void onClose(@NotNull InventoryCloseEvent event) {
|
||||
}
|
||||
|
||||
public void show() {
|
||||
show(true);
|
||||
}
|
||||
|
||||
public void show(boolean init) {
|
||||
if (init) {
|
||||
initPage();
|
||||
}
|
||||
Bukkit.getScheduler().runTask(pageConfig.getPlugin(), () -> player.openInventory(getInventory()));
|
||||
}
|
||||
|
||||
public void close() {
|
||||
Bukkit.getScheduler().runTask(pageConfig.getPlugin(), player::closeInventory);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PageConfig getPageConfig() {
|
||||
return pageConfig;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public HumanEntity getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ButtonGroup getButtonGroup() {
|
||||
return getPageConfig().getButtonGroup("default");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getTitle() {
|
||||
String title = pageConfig.getTitle();
|
||||
for (Map.Entry<String, String> entry : getPageVariables().entrySet()) {
|
||||
title = title.replace(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return title;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public HashMap<String, String> getPageVariables() {
|
||||
return new HashMap<>();
|
||||
}
|
||||
}
|
@@ -0,0 +1,225 @@
|
||||
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.PageConfig;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryAction;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 支持翻页的 GUI
|
||||
*
|
||||
* @param <E> 页面元素
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class PageableHandler<E> extends FixedPageHandler {
|
||||
private static final ItemStack EMPTY_STACK = new ItemStack(Material.AIR);
|
||||
|
||||
private String previewButtonName = "preview";
|
||||
private String nextButtonName = "next";
|
||||
private String barrierButtonName = "barrier";
|
||||
private String elementButtonName = "element";
|
||||
|
||||
private int page;
|
||||
private HashMap<Integer, E> elementSlot;
|
||||
|
||||
public PageableHandler(@NotNull HumanEntity player) {
|
||||
super(player);
|
||||
this.page = 0;
|
||||
}
|
||||
|
||||
public PageableHandler(@NotNull HumanEntity player, int page) {
|
||||
super(player);
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
public PageableHandler(@NotNull PageConfig config, @NotNull HumanEntity player, int page) {
|
||||
super(config, player);
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract List<E> getPageElements();
|
||||
|
||||
public abstract void onClickElement(@NotNull ClickType clickType, @NotNull InventoryAction action, @NotNull E element);
|
||||
|
||||
public String getElementButtonName() {
|
||||
return elementButtonName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getElementButtonName(@NotNull E element) {
|
||||
return elementButtonName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickInside(@NotNull InventoryClickEvent event) {
|
||||
event.setCancelled(true);
|
||||
int slot = event.getSlot();
|
||||
E e = elementSlot.get(slot);
|
||||
if (e != null) {
|
||||
onClickElement(event.getClick(), event.getAction(), e);
|
||||
return;
|
||||
}
|
||||
String name = getPageConfig().getButtonName(event.getCurrentItem());
|
||||
if (name.equalsIgnoreCase(nextButtonName)) {
|
||||
showNextPage();
|
||||
return;
|
||||
}
|
||||
if (name.equalsIgnoreCase(previewButtonName)) {
|
||||
showPreviewPage();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayButtonSound(@NotNull ClickType clickType, @NotNull InventoryAction action, int index) {
|
||||
HumanEntity player = getPlayer();
|
||||
if (!(player instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
PageConfig config = getPageConfig();
|
||||
String buttonName = getButtonGroup().getButtonName(index);
|
||||
Sound sound = config.getButtonSound(buttonName);
|
||||
if (sound == null) {
|
||||
switch (buttonName) {
|
||||
case "empty":
|
||||
case "barrier": {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sound = config.getButtonSound("default");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (buttonName.equals("element") && elementSlot.get(index) == null) {
|
||||
sound = null;
|
||||
}
|
||||
if (sound == null) {
|
||||
return;
|
||||
}
|
||||
((Player) player).playSound(player.getLocation(), sound, 1, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initPage() {
|
||||
super.initPage();
|
||||
List<E> elements = getPageElements();
|
||||
ButtonGroup group = getButtonGroup();
|
||||
Inventory inventory = getInventory();
|
||||
HumanEntity player = getPlayer();
|
||||
|
||||
ArrayList<Integer> buttonIndexes = group.getButtonAllIndex(elementButtonName);
|
||||
int pageSize = buttonIndexes.size(); // 一页有多少个按钮
|
||||
elementSlot = new HashMap<>();
|
||||
|
||||
HashMap<String, String> variables = getPageVariables();
|
||||
|
||||
for (int i = 0; i < pageSize; i++) {
|
||||
// 元素在当前 page 中的索引位置
|
||||
int elementIndex = page * pageSize + i;
|
||||
// 按钮在 GUI 中的索引位置
|
||||
int buttonIndex = buttonIndexes.get(i);
|
||||
|
||||
if (elementIndex >= elements.size()) {
|
||||
inventory.setItem(buttonIndex, null);
|
||||
continue;
|
||||
}
|
||||
|
||||
E element = elements.get(elementIndex);
|
||||
elementSlot.put(buttonIndex, element);
|
||||
|
||||
String buttonName = getElementButtonName(element);
|
||||
ItemStack buttonItem = group.getButtonItem(buttonName);
|
||||
initElementButton(buttonIndex, element, buttonItem, variables);
|
||||
}
|
||||
|
||||
if (page == 0) {
|
||||
// 如果页面已在首页则撤掉上一页按钮
|
||||
inventory.setItem(group.getButtonIndex(previewButtonName), group.getButtonItem(barrierButtonName));
|
||||
}
|
||||
if (elements.size() <= (page + 1) * pageSize) {
|
||||
// 如果页面显示超出已有元素数量则撤掉下一页按钮
|
||||
inventory.setItem(group.getButtonIndex(nextButtonName), group.getButtonItem(barrierButtonName));
|
||||
}
|
||||
}
|
||||
|
||||
public void initElementButton(int index, @NotNull E element, @NotNull ItemStack stack, @NotNull Map<String, String> variables) {
|
||||
ItemMeta meta = stack.getItemMeta();
|
||||
if (meta == null) {
|
||||
return;
|
||||
}
|
||||
if (meta.hasDisplayName()) {
|
||||
String displayName = meta.getDisplayName();
|
||||
for (Map.Entry<String, String> entry : variables.entrySet()) {
|
||||
displayName = displayName.replace(entry.getKey(), entry.getValue());
|
||||
}
|
||||
meta.setDisplayName(displayName);
|
||||
}
|
||||
List<String> lore = meta.getLore();
|
||||
if (lore != null) {
|
||||
for (int i = 0; i < lore.size(); i++) {
|
||||
String s = lore.get(i);
|
||||
for (Map.Entry<String, String> entry : variables.entrySet()) {
|
||||
s = s.replace(entry.getKey(), entry.getValue());
|
||||
}
|
||||
lore.set(i, s);
|
||||
}
|
||||
meta.setLore(lore);
|
||||
}
|
||||
stack.setItemMeta(meta);
|
||||
inventory.setItem(index, stack);
|
||||
}
|
||||
|
||||
public void showPreviewPage() {
|
||||
page--;
|
||||
show();
|
||||
}
|
||||
|
||||
public void showNextPage() {
|
||||
page++;
|
||||
show();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public HashMap<Integer, E> getElementSlot() {
|
||||
return elementSlot;
|
||||
}
|
||||
|
||||
public int getPage() {
|
||||
return page;
|
||||
}
|
||||
|
||||
public void setPage(int page) {
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
public void setPreviewButtonName(String previewButtonName) {
|
||||
this.previewButtonName = previewButtonName;
|
||||
}
|
||||
|
||||
public void setNextButtonName(String nextButtonName) {
|
||||
this.nextButtonName = nextButtonName;
|
||||
}
|
||||
|
||||
public void setBarrierButtonName(String barrierButtonName) {
|
||||
this.barrierButtonName = barrierButtonName;
|
||||
}
|
||||
|
||||
public void setElementButtonName(String elementButtonName) {
|
||||
this.elementButtonName = elementButtonName;
|
||||
}
|
||||
}
|
@@ -0,0 +1,120 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.page.listener;
|
||||
|
||||
import cn.hamster3.mc.plugin.core.bukkit.HamsterCorePlugin;
|
||||
import cn.hamster3.mc.plugin.core.bukkit.page.handler.PageHandler;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||
import org.bukkit.event.inventory.InventoryOpenEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
/**
|
||||
* GUI 监听器
|
||||
*/
|
||||
public class PageListener implements Listener {
|
||||
public static final PageListener INSTANCE = new PageListener();
|
||||
|
||||
private PageListener() {
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryOpen(InventoryOpenEvent event) {
|
||||
Inventory inventory = event.getView().getTopInventory();
|
||||
if (!(inventory.getHolder() instanceof PageHandler)) {
|
||||
return;
|
||||
}
|
||||
PageHandler pageHandler = (PageHandler) inventory.getHolder();
|
||||
pageHandler.onOpen(event);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClick(InventoryClickEvent event) {
|
||||
Inventory inventory = event.getView().getTopInventory();
|
||||
if (!(inventory.getHolder() instanceof PageHandler)) {
|
||||
return;
|
||||
}
|
||||
PageHandler pageHandler = (PageHandler) inventory.getHolder();
|
||||
try {
|
||||
pageHandler.onClick(event);
|
||||
} catch (Exception e) {
|
||||
HamsterCorePlugin.getInstance().getLogger().warning(String.format("执行 %s 的 onClick(event) 时遇到了一个异常: ", pageHandler.getClass().getName()));
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
int index = event.getRawSlot();
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
if (index != event.getSlot()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
pageHandler.onClickInside(event);
|
||||
} catch (Exception e) {
|
||||
HamsterCorePlugin.getInstance().getLogger().warning(String.format("执行 %s 的 onClickInside(event) 时遇到了一个异常: ", pageHandler.getClass().getName()));
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
pageHandler.onClickInside(event.getClick(), event.getAction(), index);
|
||||
} catch (Exception e) {
|
||||
HamsterCorePlugin.getInstance().getLogger().warning(String.format(
|
||||
"执行 %s 的 onClickInside(%s, %s, %d) 时遇到了一个异常: ",
|
||||
pageHandler.getClass().getName(),
|
||||
event.getClick().name(),
|
||||
event.getAction().name(),
|
||||
index
|
||||
));
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
pageHandler.onPlayButtonSound(event.getClick(), event.getAction(), index);
|
||||
} catch (Exception e) {
|
||||
HamsterCorePlugin.getInstance().getLogger().warning(String.format(
|
||||
"执行 %s 的 onPlayButtonSound(%s, %s, %d) 时遇到了一个异常: ",
|
||||
pageHandler.getClass().getName(),
|
||||
event.getClick().name(),
|
||||
event.getAction().name(),
|
||||
index
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryDrag(InventoryDragEvent event) {
|
||||
Inventory inventory = event.getView().getTopInventory();
|
||||
if (!(inventory.getHolder() instanceof PageHandler)) {
|
||||
return;
|
||||
}
|
||||
PageHandler pageHandler = (PageHandler) inventory.getHolder();
|
||||
try {
|
||||
pageHandler.onDrag(event);
|
||||
} catch (Exception e) {
|
||||
HamsterCorePlugin.getInstance().getLogger().warning(String.format("执行 %s 的 onDrag(event) 时遇到了一个异常: ", pageHandler.getClass().getName()));
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
int size = inventory.getSize();
|
||||
for (Integer slot : event.getRawSlots()) {
|
||||
if (slot < size) {
|
||||
pageHandler.onDragInside(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClose(InventoryCloseEvent event) {
|
||||
Inventory inventory = event.getView().getTopInventory();
|
||||
if (!(inventory.getHolder() instanceof PageHandler)) {
|
||||
return;
|
||||
}
|
||||
PageHandler pageHandler = (PageHandler) inventory.getHolder();
|
||||
pageHandler.onClose(event);
|
||||
}
|
||||
}
|
@@ -0,0 +1,291 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.util;
|
||||
|
||||
import cn.hamster3.mc.plugin.core.bukkit.listener.CallbackListener;
|
||||
import cn.hamster3.mc.plugin.core.common.data.DisplayMessage;
|
||||
import com.google.gson.JsonObject;
|
||||
import de.tr7zw.changeme.nbtapi.NBTContainer;
|
||||
import de.tr7zw.changeme.nbtapi.NBTItem;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class CoreBukkitUtils {
|
||||
private CoreBukkitUtils() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getMCVersion() {
|
||||
return Bukkit.getBukkitVersion().split("-")[0];
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getNMSVersion() {
|
||||
return Bukkit.getServer().getClass().getName().split("\\.")[3];
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@NotNull
|
||||
public static Package getNMSPackage() {
|
||||
String nmsVersion = getNMSVersion();
|
||||
return Package.getPackage("net.minecraft.server." + nmsVersion);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Class<?> getNMSClass(@NotNull String className) throws ClassNotFoundException {
|
||||
String nmsVersion = getNMSVersion();
|
||||
return Class.forName("net.minecraft.server." + nmsVersion + "." + className);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家的头颅
|
||||
* 在1.11以上的服务端中获取头颅材质是在服务器上运行的
|
||||
* 因此建议使用异步线程调用该方法
|
||||
*
|
||||
* @param uuid 要获取的玩家
|
||||
* @return 玩家的头颅物品
|
||||
*/
|
||||
@NotNull
|
||||
public static ItemStack getPlayerHead(@NotNull UUID uuid) {
|
||||
return getPlayerHead(Bukkit.getOfflinePlayer(uuid));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家的头颅
|
||||
* <p>
|
||||
* 在 1.11 以上的服务端建议使用异步线程调用该方法
|
||||
* <p>
|
||||
* 因为这些服务端中通过网络获取头颅材质是在服务器上运行的
|
||||
*
|
||||
* @param offlinePlayer 要获取的玩家
|
||||
* @return 玩家的头颅物品
|
||||
*/
|
||||
@NotNull
|
||||
public static ItemStack getPlayerHead(@NotNull OfflinePlayer offlinePlayer) {
|
||||
ItemStack stack;
|
||||
try {
|
||||
stack = new ItemStack(Material.valueOf("PLAYER_HEAD"));
|
||||
} catch (IllegalArgumentException e) {
|
||||
//noinspection deprecation
|
||||
stack = new ItemStack(Material.valueOf("SKULL_ITEM"), 1, (short) 3);
|
||||
}
|
||||
SkullMeta meta = (SkullMeta) stack.getItemMeta();
|
||||
if (meta != null) {
|
||||
meta.setOwningPlayer(offlinePlayer);
|
||||
}
|
||||
stack.setItemMeta(meta);
|
||||
return stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家的头颅
|
||||
* 在1.11以上的服务端中获取头颅材质是在服务器上运行的
|
||||
* 因此建议使用异步线程调用该方法
|
||||
*
|
||||
* @param name 要获取的玩家
|
||||
* @return 玩家的头颅物品
|
||||
*/
|
||||
@NotNull
|
||||
@SuppressWarnings("deprecation")
|
||||
public static ItemStack getPlayerHead(@NotNull String name) {
|
||||
ItemStack stack;
|
||||
try {
|
||||
stack = new ItemStack(Material.valueOf("PLAYER_HEAD"));
|
||||
} catch (IllegalArgumentException e) {
|
||||
stack = new ItemStack(Material.valueOf("SKULL_ITEM"), 1, (short) 3);
|
||||
}
|
||||
SkullMeta meta = (SkullMeta) stack.getItemMeta();
|
||||
if (meta != null) {
|
||||
meta.setOwner(name);
|
||||
stack.setItemMeta(meta);
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断物品是否为空
|
||||
* 当对象为null时返回true
|
||||
* 当物品的Material为AIR时返回true
|
||||
* 当物品的数量小于1时返回true
|
||||
*
|
||||
* @param stack 物品
|
||||
* @return 是否为空
|
||||
*/
|
||||
public static boolean isEmptyItemStack(@Nullable ItemStack stack) {
|
||||
return stack == null || stack.getAmount() < 1 || stack.getType() == Material.AIR;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断物品是否包含某条 lore
|
||||
*
|
||||
* @param stack 要检测的物品
|
||||
* @param string 需要包含的 lore
|
||||
* @return 检测结果
|
||||
*/
|
||||
public static boolean containsLore(@Nullable ItemStack stack, @NotNull String string) {
|
||||
if (stack == null) {
|
||||
return false;
|
||||
}
|
||||
ItemMeta meta = stack.getItemMeta();
|
||||
if (meta == null) {
|
||||
return false;
|
||||
}
|
||||
List<String> lore = meta.getLore();
|
||||
if (lore == null) {
|
||||
return false;
|
||||
}
|
||||
for (String s : lore) {
|
||||
if (s.contains(string)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 给予玩家一个物品, 当玩家背包满时
|
||||
* <p>
|
||||
* 将会在玩家附近生成这个物品的掉落物
|
||||
*
|
||||
* @param player 玩家
|
||||
* @param stack 物品
|
||||
*/
|
||||
public static void giveItem(@NotNull HumanEntity player, @NotNull ItemStack stack) {
|
||||
if (isEmptyItemStack(stack)) {
|
||||
return;
|
||||
}
|
||||
World world = player.getWorld();
|
||||
for (ItemStack dropItem : player.getInventory().addItem(stack).values()) {
|
||||
world.dropItem(player.getLocation(), dropItem);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static DisplayMessage getDisplayMessage(@NotNull ConfigurationSection config) {
|
||||
DisplayMessage displayMessage = new DisplayMessage();
|
||||
String message = config.getString("message");
|
||||
if (message != null) {
|
||||
displayMessage.setMessage(message);
|
||||
}
|
||||
String actionbar = config.getString("actionbar");
|
||||
if (actionbar != null) {
|
||||
displayMessage.setActionbar(actionbar);
|
||||
}
|
||||
String title = config.getString("title");
|
||||
String subtitle = config.getString("subtitle");
|
||||
if (title != null || subtitle != null) {
|
||||
displayMessage.setTitle(
|
||||
title,
|
||||
subtitle,
|
||||
config.getInt("fade-in", 10),
|
||||
config.getInt("stay", 70),
|
||||
config.getInt("fade-out", 20)
|
||||
);
|
||||
}
|
||||
String sound = config.getString("sound");
|
||||
if (sound != null) {
|
||||
displayMessage.setSound(sound,
|
||||
(float) config.getDouble("volume", 1f),
|
||||
(float) config.getDouble("pitch", 1f)
|
||||
);
|
||||
}
|
||||
return displayMessage;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static YamlConfiguration getPluginConfig(@NotNull Plugin plugin, @NotNull String filename) {
|
||||
File dataFolder = plugin.getDataFolder();
|
||||
if (dataFolder.mkdirs()) {
|
||||
plugin.getLogger().info("已生成插件存档文件夹...");
|
||||
}
|
||||
File file = new File(dataFolder, filename);
|
||||
if (!file.exists()) {
|
||||
try (InputStream stream = plugin.getResource(filename)) {
|
||||
if (stream == null) {
|
||||
throw new IllegalArgumentException("在插件 " + plugin.getName() + " 的文件内部未找到 " + filename + " !");
|
||||
}
|
||||
Files.copy(stream, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException("在插件 " + plugin.getName() + " 内部读取文件 " + filename + " 时发生错误!");
|
||||
}
|
||||
}
|
||||
return YamlConfiguration.loadConfiguration(file);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String serializeItemStack(@NotNull ItemStack stack) {
|
||||
NBTContainer container = NBTItem.convertItemtoNBT(stack);
|
||||
return container.toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ItemStack deserializeItemStack(@NotNull String s) {
|
||||
return NBTItem.convertNBTtoItem(new NBTContainer(s));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ItemStack deserializeItemStack(@NotNull String s, @NotNull ItemStack defaultValue) {
|
||||
try {
|
||||
return NBTItem.convertNBTtoItem(new NBTContainer(s));
|
||||
} catch (Exception e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsonObject serializePotionEffect(@NotNull PotionEffect effect) {
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty("type", effect.getType().getName());
|
||||
object.addProperty("duration", effect.getDuration());
|
||||
object.addProperty("amplifier", effect.getAmplifier());
|
||||
return object;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PotionEffect deserializePotionEffect(@NotNull JsonObject object) {
|
||||
//noinspection ConstantConditions
|
||||
return new PotionEffect(
|
||||
PotionEffectType.getByName(object.get("type").getAsString()),
|
||||
object.get("duration").getAsInt(),
|
||||
object.get("amplifier").getAsInt()
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CompletableFuture<String> getPlayerChat(HumanEntity player) {
|
||||
return CallbackListener.CHATS.computeIfAbsent(player.getUniqueId(), o -> new CompletableFuture<>());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CompletableFuture<Block> getPlayerClickedBlock(HumanEntity player) {
|
||||
return CallbackListener.BLOCKS.computeIfAbsent(player.getUniqueId(), o -> new CompletableFuture<>());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CompletableFuture<Entity> getPlayerClickedEntity(HumanEntity player) {
|
||||
return CallbackListener.ENTITIES.computeIfAbsent(player.getUniqueId(), o -> new CompletableFuture<>());
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.util.serializer;
|
||||
|
||||
import cn.hamster3.mc.plugin.core.bukkit.util.CoreBukkitUtils;
|
||||
import com.google.gson.*;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public final class ItemStackAdapter implements JsonSerializer<ItemStack>, JsonDeserializer<ItemStack> {
|
||||
public static final ItemStackAdapter INSTANCE = new ItemStackAdapter();
|
||||
|
||||
private ItemStackAdapter() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
if (json.isJsonNull()) {
|
||||
return null;
|
||||
}
|
||||
return CoreBukkitUtils.deserializeItemStack(json.getAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(ItemStack src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
if (src == null) {
|
||||
return JsonNull.INSTANCE;
|
||||
}
|
||||
String s = CoreBukkitUtils.serializeItemStack(src);
|
||||
return new JsonPrimitive(s);
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
package cn.hamster3.mc.plugin.core.bukkit.util.serializer;
|
||||
|
||||
import cn.hamster3.mc.plugin.core.bukkit.util.CoreBukkitUtils;
|
||||
import com.google.gson.*;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public final class PotionEffectAdapter implements JsonSerializer<PotionEffect>, JsonDeserializer<PotionEffect> {
|
||||
public static final PotionEffectAdapter INSTANCE = new PotionEffectAdapter();
|
||||
|
||||
private PotionEffectAdapter() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PotionEffect deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
if (json.isJsonNull()) {
|
||||
return null;
|
||||
}
|
||||
return CoreBukkitUtils.deserializePotionEffect(json.getAsJsonObject());
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(PotionEffect src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
if (src == null) {
|
||||
return JsonNull.INSTANCE;
|
||||
}
|
||||
return CoreBukkitUtils.serializePotionEffect(src);
|
||||
}
|
||||
}
|
79
core-bukkit/src/main/resources/config.yml
Normal file
79
core-bukkit/src/main/resources/config.yml
Normal file
@@ -0,0 +1,79 @@
|
||||
datasource:
|
||||
# 数据库链接驱动地址
|
||||
# 除非你知道自己在做什么,否则不建议更改该项
|
||||
# 旧版服务端(低于1.13)请使用:com.mysql.jdbc.Driver
|
||||
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&allowPublicKeyRetrieval=true"
|
||||
# 如果你不需要做多端跨服,那么请使用 sqlite 作本地数据库
|
||||
# driver: "org.sqlite.JDBC"
|
||||
# url: "jdbc:sqlite:./plugins/HamsterCore/database.db"
|
||||
# 用户名
|
||||
username: "Test"
|
||||
# 密码
|
||||
password: "Test123.."
|
||||
# 最小闲置链接数
|
||||
# 推荐值:1~3
|
||||
minimum-idle: 0
|
||||
# 最大链接数
|
||||
# 推荐值:不低于3
|
||||
maximum-pool-size: 3
|
||||
# 保持连接池可用的间隔
|
||||
# 除非你的服务器数据库连接经常断开,否则不建议启用该选项
|
||||
# 单位:毫秒
|
||||
# 默认值为0(禁用)
|
||||
keep-alive-time: 0
|
||||
# 连接闲置回收时间
|
||||
# 单位:毫秒
|
||||
# 推荐值:600000(10分钟)
|
||||
idle-timeout: 600000
|
||||
# 链接最长存活时间
|
||||
# 单位:毫秒
|
||||
max-lifetime: 1800000
|
||||
# 验证连接存活的超时时间
|
||||
# 单位:毫秒
|
||||
validation-timeout: 5000
|
||||
|
||||
messages:
|
||||
COMMAND_NOT_FOUND:
|
||||
message: "§c未找到该指令!"
|
||||
COMMAND_NOT_HAS_PERMISSION:
|
||||
message: "§c你没有这个权限!"
|
||||
COMMAND_MUST_USED_BY_PLAYER:
|
||||
message: "§c这个命令只能由玩家执行!"
|
||||
COMMAND_DEBUG_INFO_MODE_ON:
|
||||
message: "§a已开启信息查询模式!"
|
||||
COMMAND_DEBUG_INFO_MODE_OFF:
|
||||
message: "§a已关闭信息查询模式!"
|
||||
COMMAND_LORE_HAND_EMPTY:
|
||||
message: "§c你必须手持一个物品才能使用这个命令!"
|
||||
COMMAND_LORE_EMPTY_INPUT:
|
||||
message: "§c你没有输入lore文本!"
|
||||
COMMAND_LORE_ADD_SUCCESS:
|
||||
message: "§a已成功添加lore文本!"
|
||||
COMMAND_LORE_CLEAR_NOTHING:
|
||||
message: "§c这个物品没有lore文本!"
|
||||
COMMAND_LORE_CLEAR_SUCCESS:
|
||||
message: "§c已清理该物品的全部lore文本!"
|
||||
COMMAND_LORE_NAME_SUCCESS:
|
||||
message: "§a已成功设置物品名称!"
|
||||
COMMAND_LORE_REMOVE_NOT_INPUT_NUMBER:
|
||||
message: "§c请输入要删除的行号!"
|
||||
COMMAND_LORE_REMOVE_INPUT_NUMBER_ERROR:
|
||||
message: "§c行号必须是一个大于0的整数!"
|
||||
COMMAND_LORE_REMOVE_INDEX_OUT_OF_RANGE:
|
||||
message: "§c你的手持物品没有这么多行lore文本!"
|
||||
COMMAND_LORE_REMOVE_SUCCESS:
|
||||
message: "§a已成功删除lore文本!"
|
||||
COMMAND_LORE_SET_NOT_INPUT_NUMBER:
|
||||
message: "§c请输入要设置的行号!"
|
||||
COMMAND_LORE_SET_INPUT_NUMBER_ERROR:
|
||||
message: "§c行号必须是一个大于0的整数!"
|
||||
COMMAND_LORE_SET_NOT_INPUT_TEXT:
|
||||
message: "§c请输入要设置的lore文本!"
|
||||
COMMAND_LORE_SET_INDEX_OUT_OF_RANGE:
|
||||
message: "§c你的手持物品没有这么多行lore文本!"
|
||||
COMMAND_LORE_SET_SUCCESS:
|
||||
message: "§a已成功设置lore文本!"
|
58
core-bukkit/src/main/resources/pages/FixedPage.yml
Normal file
58
core-bukkit/src/main/resources/pages/FixedPage.yml
Normal file
@@ -0,0 +1,58 @@
|
||||
title: "&c固定页面"
|
||||
|
||||
graphic:
|
||||
- "####!####"
|
||||
- "# 1 2 3 #"
|
||||
- "#########"
|
||||
|
||||
groups:
|
||||
default:
|
||||
'#': "barrier"
|
||||
'1': "accept"
|
||||
'2': "deny"
|
||||
'3': "close"
|
||||
'!': "info"
|
||||
|
||||
sounds:
|
||||
"empty": ""
|
||||
"default": "UI_BUTTON_CLICK"
|
||||
"accept": "ENTITY_PLAYER_LEVELUP"
|
||||
"deny": "BLOCK_ANVIL_HIT"
|
||||
|
||||
buttons:
|
||||
'barrier':
|
||||
==: org.bukkit.inventory.ItemStack
|
||||
type: STAINED_GLASS_PANE
|
||||
damage: 4
|
||||
meta:
|
||||
==: ItemMeta
|
||||
meta-type: UNSPECIFIC
|
||||
display-name: "§c屏障"
|
||||
'accept':
|
||||
==: org.bukkit.inventory.ItemStack
|
||||
type: ARROW
|
||||
meta:
|
||||
==: ItemMeta
|
||||
meta-type: UNSPECIFIC
|
||||
display-name: "§a同意"
|
||||
'deny':
|
||||
==: org.bukkit.inventory.ItemStack
|
||||
type: BARRIER
|
||||
meta:
|
||||
==: ItemMeta
|
||||
meta-type: UNSPECIFIC
|
||||
display-name: "§c拒绝"
|
||||
'close':
|
||||
==: org.bukkit.inventory.ItemStack
|
||||
type: REDSTONE
|
||||
meta:
|
||||
==: ItemMeta
|
||||
meta-type: UNSPECIFIC
|
||||
display-name: "§c关闭"
|
||||
'info':
|
||||
==: org.bukkit.inventory.ItemStack
|
||||
type: REDSTONE
|
||||
meta:
|
||||
==: ItemMeta
|
||||
meta-type: UNSPECIFIC
|
||||
display-name: "§c页面信息展示"
|
50
core-bukkit/src/main/resources/pages/PageablePage.yml
Normal file
50
core-bukkit/src/main/resources/pages/PageablePage.yml
Normal file
@@ -0,0 +1,50 @@
|
||||
title: "&c分页页面"
|
||||
|
||||
graphic:
|
||||
- "#########"
|
||||
- "# #"
|
||||
- "# 11111 #"
|
||||
- "# 11111 #"
|
||||
- "# #"
|
||||
- "<#######>"
|
||||
|
||||
groups:
|
||||
default:
|
||||
'#': "barrier"
|
||||
'<': "preview"
|
||||
'>': "next"
|
||||
'1': "element"
|
||||
|
||||
sounds:
|
||||
"default": "UI_BUTTON_CLICK"
|
||||
|
||||
buttons:
|
||||
'barrier':
|
||||
==: org.bukkit.inventory.ItemStack
|
||||
type: STAINED_GLASS_PANE
|
||||
damage: 4
|
||||
meta:
|
||||
==: ItemMeta
|
||||
meta-type: UNSPECIFIC
|
||||
display-name: "§c屏障"
|
||||
'preview':
|
||||
==: org.bukkit.inventory.ItemStack
|
||||
type: REDSTONE
|
||||
meta:
|
||||
==: ItemMeta
|
||||
meta-type: UNSPECIFIC
|
||||
display-name: "§c上一页"
|
||||
'next':
|
||||
==: org.bukkit.inventory.ItemStack
|
||||
type: ARROW
|
||||
meta:
|
||||
==: ItemMeta
|
||||
meta-type: UNSPECIFIC
|
||||
display-name: "§a下一页"
|
||||
'element':
|
||||
==: org.bukkit.inventory.ItemStack
|
||||
type: ARROW
|
||||
meta:
|
||||
==: ItemMeta
|
||||
meta-type: UNSPECIFIC
|
||||
display-name: "§a玩家信息"
|
32
core-bukkit/src/main/resources/plugin.yml
Normal file
32
core-bukkit/src/main/resources/plugin.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
name: HamsterCore
|
||||
main: cn.hamster3.mc.plugin.core.bukkit.HamsterCorePlugin
|
||||
version: ${version}
|
||||
api-version: 1.13
|
||||
|
||||
author: MiniDay
|
||||
website: https://github.com/MiniDay/hamster-core
|
||||
description: 仓鼠核心:叁只仓鼠的 Minecraft 插件开发通用工具包
|
||||
|
||||
load: STARTUP
|
||||
|
||||
softdepend:
|
||||
- Vault
|
||||
- PlayerPoints
|
||||
|
||||
loadbefore:
|
||||
- HamsterAPI
|
||||
|
||||
commands:
|
||||
hamster-core:
|
||||
aliases: [ hcore, hc, core ]
|
||||
description: 仓鼠核心调试指令
|
||||
permission: hamster.core.admin
|
||||
permission-message: §c你没有这个权限!
|
||||
lore:
|
||||
description: 仓鼠核心的 lore 修改指令
|
||||
permission: hamster.lore.admin
|
||||
permission-message: §c你没有这个权限!
|
||||
|
||||
permissions:
|
||||
hamster.core.admin:
|
||||
default: op
|
Reference in New Issue
Block a user