init: 项目初始化
项目初始化
This commit is contained in:
62
hamster-core-bukkit/build.gradle
Normal file
62
hamster-core-bukkit/build.gradle
Normal file
@@ -0,0 +1,62 @@
|
||||
setArchivesBaseName("HamsterCore-Bukkit")
|
||||
|
||||
evaluationDependsOn(':hamster-core-common')
|
||||
|
||||
configurations {
|
||||
api.extendsFrom apiShade
|
||||
implementation.extendsFrom implementationShade
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly project(":hamster-core-common")
|
||||
compileOnly 'org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT'
|
||||
|
||||
// https://mvnrepository.com/artifact/com.zaxxer/HikariCP
|
||||
//noinspection GradlePackageUpdate
|
||||
apiShade 'com.zaxxer:HikariCP:4.0.3'
|
||||
// https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp
|
||||
apiShade 'com.squareup.okhttp3:okhttp:4.10.0'
|
||||
// https://mvnrepository.com/artifact/net.kyori/adventure-platform-bukkit
|
||||
apiShade 'net.kyori:adventure-platform-bukkit:4.1.2'
|
||||
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0'
|
||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property "version", project.version
|
||||
filesMatching("plugin.yml") {
|
||||
expand "version": project.version
|
||||
}
|
||||
}
|
||||
|
||||
task addSource {
|
||||
doLast {
|
||||
sourceSets {
|
||||
main {
|
||||
java.srcDirs += [
|
||||
project(':hamster-core-common').sourceSets.main.java
|
||||
]
|
||||
resources.srcDirs += [
|
||||
project(':hamster-core-common').sourceSets.main.resources
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
classes.dependsOn(addSource)
|
||||
|
||||
jar {
|
||||
from([
|
||||
configurations.implementationShade.collect {
|
||||
it.isDirectory() ? it : zipTree(it)
|
||||
},
|
||||
configurations.apiShade.collect {
|
||||
it.isDirectory() ? it : zipTree(it)
|
||||
}
|
||||
])
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
package cn.hamster3.core.bukkit;
|
||||
|
||||
import cn.hamster3.core.bukkit.page.listener.PageListener;
|
||||
import cn.hamster3.core.common.constant.ConstantObjects;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class HamsterCorePlugin extends JavaPlugin {
|
||||
private static HamsterCorePlugin instance;
|
||||
|
||||
public static HamsterCorePlugin getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static void sync(Runnable runnable) {
|
||||
Bukkit.getScheduler().runTask(instance, runnable);
|
||||
}
|
||||
|
||||
public static void async(Runnable runnable) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(instance, runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
instance = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
long start = System.currentTimeMillis();
|
||||
getLogger().info("仓鼠核心正在启动...");
|
||||
Bukkit.getPluginManager().registerEvents(PageListener.INSTANCE, this);
|
||||
getLogger().info("已注册 PageListener.");
|
||||
long time = System.currentTimeMillis() - start;
|
||||
getLogger().info("仓鼠核心已启动,总计耗时 " + time + " ms.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
long start = System.currentTimeMillis();
|
||||
getLogger().info("仓鼠核心正在关闭...");
|
||||
ConstantObjects.WORKER_EXECUTOR.shutdownNow();
|
||||
getLogger().info("已暂停 WORKER_EXECUTOR.");
|
||||
ConstantObjects.SCHEDULED_EXECUTOR.shutdownNow();
|
||||
getLogger().info("已暂停 SCHEDULED_EXECUTOR.");
|
||||
long time = System.currentTimeMillis() - start;
|
||||
getLogger().info("仓鼠核心已关闭,总计耗时 " + time + " ms.");
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
package cn.hamster3.core.bukkit.api;
|
||||
|
||||
import cn.hamster3.core.common.api.CommonAPI;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class BukkitAPI extends CommonAPI {
|
||||
public static BukkitAPI getInstance() {
|
||||
return (BukkitAPI) instance;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,184 @@
|
||||
package cn.hamster3.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 {
|
||||
private final String name;
|
||||
private final PageConfig config;
|
||||
private final HashMap<Character, String> buttonNameMap;
|
||||
|
||||
/**
|
||||
* 实例化这个按钮组
|
||||
*
|
||||
* @param pageConfig Page 设定
|
||||
* @param config 按钮组设定
|
||||
*/
|
||||
public ButtonGroup(PageConfig pageConfig, 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));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 以图形字符来获取按钮名称
|
||||
* <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(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(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 getButton(char graphicKey) {
|
||||
return getButton(getButtonName(graphicKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* 以按钮名称来获取按钮物品
|
||||
*
|
||||
* @param buttonName 按钮名称
|
||||
* @return 按钮物品
|
||||
*/
|
||||
public ItemStack getButton(String buttonName) {
|
||||
ItemStack stack = config.getButtons().get(buttonName);
|
||||
if (stack != null) {
|
||||
stack = stack.clone();
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取这个按钮组的名称
|
||||
*
|
||||
* @return 按钮组名称
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取把图形字符映射到按钮名称的表
|
||||
*
|
||||
* @return 把图形字符映射到按钮名称的表
|
||||
*/
|
||||
public HashMap<Character, String> getButtonNameMap() {
|
||||
return buttonNameMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof ButtonGroup)) 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,195 @@
|
||||
package cn.hamster3.core.bukkit.page;
|
||||
|
||||
import cn.hamster3.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 config;
|
||||
|
||||
@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 config) {
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
title = config.getString("title", "").replace("&", "§");
|
||||
|
||||
List<String> graphicString = config.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 = config.getConfigurationSection("buttons");
|
||||
for (String key : buttonsConfig.getKeys(false)) {
|
||||
buttons.put(key, buttonsConfig.getItemStack(key));
|
||||
}
|
||||
|
||||
buttonGroups = new ArrayList<>();
|
||||
ConfigurationSection buttonGroupsConfig = config.getConfigurationSection("groups");
|
||||
for (String key : buttonGroupsConfig.getKeys(false)) {
|
||||
buttonGroups.add(
|
||||
new ButtonGroup(this, buttonGroupsConfig.getConfigurationSection(key))
|
||||
);
|
||||
}
|
||||
|
||||
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.getButton(c));
|
||||
}
|
||||
}
|
||||
|
||||
buttonSounds = new HashMap<>();
|
||||
ConfigurationSection buttonSoundConfig = config.getConfigurationSection("sounds");
|
||||
for (String key : buttonSoundConfig.getKeys(false)) {
|
||||
try {
|
||||
buttonSounds.put(key, Sound.valueOf(buttonSoundConfig.getString(key)));
|
||||
} catch (IllegalArgumentException 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;
|
||||
}
|
||||
}
|
||||
return buttonGroups.get(0);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigurationSection getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@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,133 @@
|
||||
package cn.hamster3.core.bukkit.page;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public interface PageElement {
|
||||
|
||||
/**
|
||||
* 获取展示物品
|
||||
* <p>
|
||||
* 若返回 null 则使用 config 中的全局设置值
|
||||
*
|
||||
* @param player 占位符显示的目标玩家
|
||||
* @return 展示物品
|
||||
*/
|
||||
default ItemStack getDisplayItem(HumanEntity player) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取展示物品的显示材质
|
||||
* <p>
|
||||
* 若返回 null 则使用 config 中的全局设置值
|
||||
*
|
||||
* @param player 占位符显示的目标玩家
|
||||
* @return 展示物品的显示材质
|
||||
*/
|
||||
default Material getMaterial(HumanEntity player) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 替换物品的信息
|
||||
*
|
||||
* @param player 玩家
|
||||
* @param stack 物品
|
||||
* @param globalVariable 全局变量
|
||||
*/
|
||||
default void replaceItemInfo(HumanEntity player, ItemStack stack, HashMap<String, String> globalVariable) {
|
||||
if (stack == null) {
|
||||
return;
|
||||
}
|
||||
Material type = getMaterial(player);
|
||||
if (type != null) {
|
||||
stack.setType(type);
|
||||
}
|
||||
|
||||
ItemMeta meta = stack.getItemMeta();
|
||||
replaceMetaInfo(player, meta, globalVariable);
|
||||
stack.setItemMeta(meta);
|
||||
}
|
||||
|
||||
/**
|
||||
* 替换物品的信息
|
||||
*
|
||||
* @param player 玩家
|
||||
* @param meta 物品信息
|
||||
* @param globalVariable 全局变量
|
||||
*/
|
||||
default void replaceMetaInfo(HumanEntity player, ItemMeta meta, HashMap<String, String> globalVariable) {
|
||||
if (meta == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, String> replacer = getVariable(player, globalVariable);
|
||||
|
||||
if (meta.hasDisplayName()) {
|
||||
String displayName = replaceDisplayName(player, meta.getDisplayName(), globalVariable);
|
||||
meta.setDisplayName(displayName);
|
||||
}
|
||||
|
||||
List<String> lore = meta.getLore();
|
||||
if (lore != null) {
|
||||
lore = replaceLore(player, lore, globalVariable);
|
||||
meta.setLore(lore);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 替换物品展示名称
|
||||
*
|
||||
* @param player 玩家
|
||||
* @param displayName 物品原名称
|
||||
* @param globalVariable 全局变量
|
||||
* @return 替换后的物品展示名称
|
||||
*/
|
||||
default String replaceDisplayName(HumanEntity player, String displayName, HashMap<String, String> globalVariable) {
|
||||
return replacePlaceholder(player, displayName, globalVariable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 替换物品 lore 信息
|
||||
*
|
||||
* @param player 玩家
|
||||
* @param lore 物品原 lore 信息
|
||||
* @param globalReplacer 全局变量
|
||||
* @return 替换后的物品 lore 信息
|
||||
*/
|
||||
default List<String> replaceLore(HumanEntity player, List<String> lore, HashMap<String, String> globalReplacer) {
|
||||
if (lore == null) {
|
||||
return null;
|
||||
}
|
||||
Map<String, String> replacer = getVariable(player, globalReplacer);
|
||||
for (int i = 0; i < lore.size(); i++) {
|
||||
String s = lore.get(i);
|
||||
for (Map.Entry<String, String> entry : replacer.entrySet()) {
|
||||
s = s.replace(entry.getKey(), entry.getValue());
|
||||
}
|
||||
lore.set(i, s);
|
||||
}
|
||||
return lore;
|
||||
}
|
||||
|
||||
default String replacePlaceholder(HumanEntity player, String string, HashMap<String, String> globalVariable) {
|
||||
Map<String, String> replacer = getVariable(player, globalVariable);
|
||||
for (Map.Entry<String, String> entry : replacer.entrySet()) {
|
||||
string = string.replace(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
default Map<String, String> getVariable(HumanEntity player, HashMap<String, String> globalVariable) {
|
||||
return globalVariable;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
package cn.hamster3.core.bukkit.page;
|
||||
|
||||
import cn.hamster3.core.bukkit.HamsterCorePlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.HashMap;
|
||||
|
||||
public abstract class PageManager {
|
||||
private static final HashMap<String, PageConfig> PAGE_CONFIG = new HashMap<>();
|
||||
|
||||
public static PageConfig getPageConfig(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 value = annotation.value();
|
||||
Plugin plugin = Bukkit.getPluginManager().getPlugin(value);
|
||||
File pageFolder = new File(plugin.getDataFolder(), "pages");
|
||||
if (pageFolder.mkdirs()) {
|
||||
HamsterCorePlugin.getInstance().getLogger().info("为 " + value + " 创建页面配置文件夹...");
|
||||
}
|
||||
String pageFileName = clazz.getSimpleName() + ".yml";
|
||||
File pageFile = new File(pageFolder, pageFileName);
|
||||
if (pageFile.exists()) {
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(pageFile);
|
||||
pageConfig = new PageConfig(plugin, configuration);
|
||||
PAGE_CONFIG.put(clazz.getName(), pageConfig);
|
||||
return pageConfig;
|
||||
}
|
||||
try {
|
||||
Files.copy(plugin.getResource("/" + pageFileName), pageFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(pageFile);
|
||||
pageConfig = new PageConfig(plugin, configuration);
|
||||
PAGE_CONFIG.put(clazz.getName(), pageConfig);
|
||||
return pageConfig;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
package cn.hamster3.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,50 @@
|
||||
package cn.hamster3.core.bukkit.page.handler;
|
||||
|
||||
import cn.hamster3.core.bukkit.page.ButtonGroup;
|
||||
import cn.hamster3.core.bukkit.page.PageConfig;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
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 HumanEntity player, @NotNull String title) {
|
||||
super(player, title);
|
||||
}
|
||||
|
||||
public FixedPageHandler(@NotNull PageConfig pageConfig, @NotNull HumanEntity player) {
|
||||
super(pageConfig, player);
|
||||
}
|
||||
|
||||
public FixedPageHandler(@NotNull PageConfig pageConfig, @NotNull String title, @NotNull HumanEntity player) {
|
||||
super(pageConfig, title, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initPage() {
|
||||
HumanEntity player = getPlayer();
|
||||
|
||||
Inventory inventory = getInventory();
|
||||
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.getButton(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,130 @@
|
||||
package cn.hamster3.core.bukkit.page.handler;
|
||||
|
||||
import cn.hamster3.core.bukkit.HamsterCorePlugin;
|
||||
import cn.hamster3.core.bukkit.page.ButtonGroup;
|
||||
import cn.hamster3.core.bukkit.page.PageConfig;
|
||||
import cn.hamster3.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;
|
||||
|
||||
/**
|
||||
* GUI 处理类
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class PageHandler implements InventoryHolder {
|
||||
private final PageConfig pageConfig;
|
||||
private final HumanEntity player;
|
||||
private final Inventory inventory;
|
||||
|
||||
public PageHandler(@NotNull HumanEntity player) {
|
||||
try {
|
||||
pageConfig = PageManager.getPageConfig(getClass());
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("加载界面配置时遇到了一个异常!", e);
|
||||
}
|
||||
this.player = player;
|
||||
inventory = Bukkit.createInventory(this, pageConfig.getInventory().getSize(), pageConfig.getTitle());
|
||||
}
|
||||
|
||||
public PageHandler(@NotNull HumanEntity player, @NotNull String title) {
|
||||
try {
|
||||
pageConfig = PageManager.getPageConfig(getClass());
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("加载界面配置时遇到了一个异常!", e);
|
||||
}
|
||||
this.player = player;
|
||||
inventory = Bukkit.createInventory(this, pageConfig.getInventory().getSize(), title);
|
||||
}
|
||||
|
||||
public PageHandler(@NotNull PageConfig pageConfig, @NotNull HumanEntity player) {
|
||||
this(pageConfig, pageConfig.getTitle(), player);
|
||||
}
|
||||
|
||||
public PageHandler(@NotNull PageConfig pageConfig, @NotNull String title, @NotNull HumanEntity player) {
|
||||
this.pageConfig = pageConfig;
|
||||
this.player = player;
|
||||
inventory = Bukkit.createInventory(this, pageConfig.getInventory().getSize(), title);
|
||||
}
|
||||
|
||||
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) {
|
||||
Sound sound = getPageConfig().getButtonSound(getButtonGroup().getButtonName(index));
|
||||
if (sound == null) {
|
||||
return;
|
||||
}
|
||||
if (!(player instanceof Player)) {
|
||||
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();
|
||||
}
|
||||
HamsterCorePlugin.sync(() -> player.openInventory(getInventory()));
|
||||
}
|
||||
|
||||
public void close() {
|
||||
HamsterCorePlugin.sync(player::closeInventory);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PageConfig getPageConfig() {
|
||||
return pageConfig;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public HumanEntity getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ButtonGroup getButtonGroup() {
|
||||
return getPageConfig().getButtonGroup("default");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
}
|
@@ -0,0 +1,185 @@
|
||||
package cn.hamster3.core.bukkit.page.handler;
|
||||
|
||||
import cn.hamster3.core.bukkit.page.ButtonGroup;
|
||||
import cn.hamster3.core.bukkit.page.PageConfig;
|
||||
import cn.hamster3.core.bukkit.page.PageElement;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
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.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 支持翻页的 GUI
|
||||
*
|
||||
* @param <E> 页面元素
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class PageableHandler<E extends PageElement> extends FixedPageHandler {
|
||||
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, int page) {
|
||||
super(player);
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
public PageableHandler(@NotNull HumanEntity player, @NotNull String title, int page) {
|
||||
super(player, title);
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
public PageableHandler(@NotNull PageConfig pageConfig, @NotNull HumanEntity player, int page) {
|
||||
super(pageConfig, player);
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
public PageableHandler(@NotNull PageConfig pageConfig, @NotNull String title, @NotNull HumanEntity player, int page) {
|
||||
super(pageConfig, title, player);
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract List<E> getPageElements();
|
||||
|
||||
public abstract void onClickElement(@NotNull ClickType clickType, @NotNull InventoryAction action, @NotNull E element);
|
||||
|
||||
@NotNull
|
||||
public String getElementButtonName(@NotNull E element) {
|
||||
return elementButtonName;
|
||||
}
|
||||
|
||||
public void initElementButton(@NotNull E element, @NotNull ItemStack displayItem, HashMap<String, String> replacer) {
|
||||
element.replaceItemInfo(getPlayer(), displayItem, replacer);
|
||||
}
|
||||
|
||||
@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> replacer = getReplacer();
|
||||
|
||||
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);
|
||||
|
||||
ItemStack elementDisplayItem = element.getDisplayItem(player);
|
||||
if (elementDisplayItem != null) {
|
||||
elementDisplayItem = elementDisplayItem.clone();
|
||||
element.replaceItemInfo(player, elementDisplayItem, replacer);
|
||||
inventory.setItem(buttonIndex, elementDisplayItem);
|
||||
continue;
|
||||
}
|
||||
|
||||
ItemStack button = group.getButton(getElementButtonName(element));
|
||||
if (button == null) {
|
||||
inventory.setItem(buttonIndex, null);
|
||||
continue;
|
||||
}
|
||||
|
||||
ItemStack elementItem = button.clone();
|
||||
initElementButton(element, elementItem, replacer);
|
||||
inventory.setItem(buttonIndex, elementItem);
|
||||
}
|
||||
|
||||
if (page == 0) {
|
||||
// 如果页面已在首页则撤掉上一页按钮
|
||||
inventory.setItem(group.getButtonIndex(previewButtonName), group.getButton(barrierButtonName));
|
||||
}
|
||||
if (elements.size() <= (page + 1) * pageSize) {
|
||||
// 如果页面显示超出已有元素数量则撤掉下一页按钮
|
||||
inventory.setItem(group.getButtonIndex(nextButtonName), group.getButton(barrierButtonName));
|
||||
}
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public HashMap<String, String> getReplacer() {
|
||||
return new HashMap<>();
|
||||
}
|
||||
}
|
@@ -0,0 +1,120 @@
|
||||
package cn.hamster3.core.bukkit.page.listener;
|
||||
|
||||
import cn.hamster3.core.bukkit.HamsterCorePlugin;
|
||||
import cn.hamster3.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,194 @@
|
||||
package cn.hamster3.core.bukkit.util;
|
||||
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class BukkitUtils {
|
||||
@NotNull
|
||||
public static String getMCVersion() {
|
||||
return Bukkit.getBukkitVersion().split("-")[0];
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getNMSVersion() {
|
||||
return Bukkit.getServer().getClass().getName().split("\\.")[3];
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 让玩家以最高权限执行命令
|
||||
*
|
||||
* @param player 玩家
|
||||
* @param command 要执行的命令
|
||||
*/
|
||||
public static void opCommand(@NotNull Player player, @NotNull String command) {
|
||||
boolean isOp = player.isOp();
|
||||
player.setOp(true);
|
||||
Bukkit.dispatchCommand(player, command);
|
||||
player.setOp(isOp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家的头颅
|
||||
* 在1.11以上的服务端中获取头颅材质是在服务器上运行的
|
||||
* 因此建议使用异步线程调用该方法
|
||||
*
|
||||
* @param uuid 要获取的玩家
|
||||
* @return 玩家的头颅物品
|
||||
*/
|
||||
@NotNull
|
||||
public static ItemStack getPlayerHead(@NotNull UUID uuid) {
|
||||
return getPlayerHead(Bukkit.getOfflinePlayer(uuid));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家的头颅
|
||||
* 在1.11以上的服务端中获取头颅材质是在服务器上运行的
|
||||
* 因此建议使用异步线程调用该方法
|
||||
*
|
||||
* @param offlinePlayer 要获取的玩家
|
||||
* @return 玩家的头颅物品
|
||||
*/
|
||||
@NotNull
|
||||
public static ItemStack getPlayerHead(@NotNull OfflinePlayer offlinePlayer) {
|
||||
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.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();
|
||||
meta.setOwner(name);
|
||||
stack.setItemMeta(meta);
|
||||
return stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断物品是否为空
|
||||
* 当对象为null时返回true
|
||||
* 当物品的Material为AIR时返回true
|
||||
* 当物品的数量小于1时返回true
|
||||
*
|
||||
* @param stack 物品
|
||||
* @return 是否为空
|
||||
*/
|
||||
public static boolean isEmptyItemStack(ItemStack stack) {
|
||||
return stack == null || stack.getType() == Material.AIR || stack.getAmount() < 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 给予玩家一个物品, 当玩家背包满时
|
||||
* 将会在玩家附近生成这个物品的掉落物
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取物品的名称
|
||||
* 当物品为null时返回"null"
|
||||
* 当物品拥有DisplayName时返回DisplayName
|
||||
* 否则返回物品的Material的name
|
||||
*
|
||||
* @param stack 物品
|
||||
* @return 物品的名称
|
||||
*/
|
||||
@NotNull
|
||||
public static String getItemName(ItemStack stack) {
|
||||
if (stack == null) {
|
||||
return "null";
|
||||
}
|
||||
if (stack.hasItemMeta()) {
|
||||
ItemMeta meta = stack.getItemMeta();
|
||||
if (meta.hasDisplayName()) {
|
||||
return meta.getDisplayName();
|
||||
}
|
||||
}
|
||||
return stack.getType().name();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 SQL 连接池
|
||||
*
|
||||
* @param config SQL 配置
|
||||
* @return SQL 连接池
|
||||
*/
|
||||
@NotNull
|
||||
public static HikariDataSource getHikariDataSource(@NotNull ConfigurationSection config) {
|
||||
HikariConfig hikariConfig = new HikariConfig();
|
||||
|
||||
hikariConfig.setDriverClassName(config.getString("driver"));
|
||||
|
||||
hikariConfig.setJdbcUrl(config.getString("url"));
|
||||
hikariConfig.setUsername(config.getString("user"));
|
||||
hikariConfig.setPassword(config.getString("password"));
|
||||
|
||||
hikariConfig.setMaximumPoolSize(config.getInt("maximumPoolSize", 3));
|
||||
hikariConfig.setMinimumIdle(config.getInt("minimumIdle", 1));
|
||||
hikariConfig.setIdleTimeout(config.getLong("idleTimeout", 5 * 60 * 1000));
|
||||
hikariConfig.setMaxLifetime(config.getLong("maxLifetime", 0));
|
||||
|
||||
return new HikariDataSource(hikariConfig);
|
||||
}
|
||||
|
||||
// todo public static TextComponent getItemDisplayInfo(@NotNull ItemStack stack)
|
||||
}
|
3
hamster-core-bukkit/src/main/resources/plugin.yml
Normal file
3
hamster-core-bukkit/src/main/resources/plugin.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
name: HamsterCore
|
||||
main: cn.hamster3.core.bukkit.HamsterCorePlugin
|
||||
version: ${version}
|
Reference in New Issue
Block a user