1
mirror of https://github.com/CarmJos/UserPrefix.git synced 2026-06-04 15:28:21 +08:00

refactor(all): 重构项目代码,变更配置文件格式

BREAKING CHANGE: 所有API接口变更,大部分配置文件变更。
This commit is contained in:
2022-06-18 06:12:24 +08:00
parent 6904f5a6d6
commit 969844dae9
52 changed files with 1032 additions and 3215 deletions
+50 -107
View File
@@ -1,9 +1,12 @@
package cc.carm.plugin.userprefix;
import cc.carm.plugin.userprefix.command.UserPrefixAdminCommand;
import cc.carm.plugin.userprefix.command.UserPrefixCommand;
import cc.carm.lib.easyplugin.EasyPlugin;
import cc.carm.lib.easyplugin.gui.GUI;
import cc.carm.lib.easyplugin.updatechecker.GHUpdateChecker;
import cc.carm.lib.easyplugin.utils.MessageUtils;
import cc.carm.plugin.userprefix.command.AdminCommand;
import cc.carm.plugin.userprefix.command.UserCommand;
import cc.carm.plugin.userprefix.configuration.PluginConfig;
import cc.carm.plugin.userprefix.hooker.UpdateChecker;
import cc.carm.plugin.userprefix.hooker.UserPrefixExpansion;
import cc.carm.plugin.userprefix.listener.ChatListener;
import cc.carm.plugin.userprefix.listener.UserListener;
@@ -12,64 +15,62 @@ import cc.carm.plugin.userprefix.manager.ConfigManager;
import cc.carm.plugin.userprefix.manager.PrefixManager;
import cc.carm.plugin.userprefix.manager.ServiceManager;
import cc.carm.plugin.userprefix.manager.UserManager;
import cc.carm.plugin.userprefix.util.ColorParser;
import cc.carm.plugin.userprefix.util.MessageUtil;
import cc.carm.plugin.userprefix.wrapper.ItemStackWrapper;
import net.luckperms.api.event.user.UserDataRecalculateEvent;
import org.bstats.bukkit.Metrics;
import org.bstats.charts.SimplePie;
import org.bstats.charts.SingleLineChart;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.PluginCommand;
import org.bukkit.command.TabCompleter;
import org.bukkit.configuration.serialization.ConfigurationSerialization;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class Main extends JavaPlugin {
public class Main extends EasyPlugin {
private static Main instance;
protected ConfigManager configManager;
protected PrefixManager prefixManager;
protected UserManager userManager;
@Override
public void onEnable() {
protected boolean initialize() {
instance = this;
showPluginName();
log(getName() + " " + getDescription().getVersion() + " &7开始加载...");
long startTime = System.currentTimeMillis();
log("注入序列化处理工具...");
ConfigurationSerialization.registerClass(ItemStackWrapper.class);
log("加载插件配置...");
this.configManager = new ConfigManager(getDataFolder());
this.prefixManager = new PrefixManager();
log("加载配置文件...");
ConfigManager.initConfig();
PrefixManager.init();
log("加载前缀配置...");
int loaded = prefixManager.loadPrefixes();
log(" 成功加载了 " + loaded + " 个前缀配置。");
log("加载用户管理器...");
this.userManager = new UserManager();
log("注册指令...");
registerCommand("UserPrefix", new UserPrefixCommand());
registerCommand("UserPrefixAdmin", new UserPrefixAdminCommand());
registerCommand("UserPrefix", new UserCommand());
registerCommand("UserPrefixAdmin", new AdminCommand());
log("注册监听器...");
regListener(new UserListener());
regListener(new ChatListener());
ServiceManager.getService().getEventBus().subscribe(this, UserDataRecalculateEvent.class, UserNodeUpdateProcessor::process);
GUI.initialize(this);
registerListener(new UserListener());
registerListener(new ChatListener());
ServiceManager.getService().getEventBus().subscribe(
this, UserDataRecalculateEvent.class,
UserNodeUpdateProcessor::process
);
if (MessageUtil.hasPlaceholderAPI()) {
if (MessageUtils.hasPlaceholderAPI()) {
log("注册变量...");
new UserPrefixExpansion(getInstance()).register();
} else {
log("未安装 PlaceholderAPI 不进行变量注册...");
log("未安装 PlaceholderAPI ,跳过变量注册...");
log("若您想使用变量进行前缀的显示,请安装PlaceholderAPI");
}
if (PluginConfig.METRICS.get()) {
if (PluginConfig.METRICS.getNotNull()) {
log("启用统计数据...");
Metrics metrics = new Metrics(this, 13776);
metrics.addCustomChart(new SingleLineChart("active_prefixes", () -> PrefixManager.getPrefixes().size()));
metrics.addCustomChart(new SimplePie("custom_storage", () -> PluginConfig.CustomStorage.ENABLE.get() ? "ENABLE" : "DISABLE"));
metrics.addCustomChart(new SingleLineChart("active_prefixes", () -> prefixManager.getPrefixes().size()));
metrics.addCustomChart(new SimplePie("custom_storage", () -> PluginConfig.CUSTOM_STORAGE.ENABLE.getNotNull() ? "ENABLE" : "DISABLE"));
metrics.addCustomChart(new SimplePie("lp_version", () -> ServiceManager.getService().getPluginMetadata().getVersion()));
metrics.addCustomChart(new SimplePie("papi_version", () -> {
Plugin plugin = Bukkit.getPluginManager().getPlugin("PlaceholderAPI");
@@ -78,96 +79,38 @@ public class Main extends JavaPlugin {
}));
}
if (PluginConfig.CHECK_UPDATE.get()) {
if (PluginConfig.CHECK_UPDATE.getNotNull()) {
log("开始检查更新...");
UpdateChecker.checkUpdate(getDescription().getVersion());
getScheduler().runAsync(GHUpdateChecker.runner(this));
} else {
log("已禁用检查更新,跳过。");
}
log("加载完成 ,共耗时 " + (System.currentTimeMillis() - startTime) + " ms 。");
showAD();
if (Bukkit.getOnlinePlayers().size() > 0) {
Bukkit.getOnlinePlayers().forEach(UserManager::initPlayer); // 适配热重载
}
Bukkit.getOnlinePlayers().forEach(userManager::initPlayer); // 适配热重载
log("&7感谢您使用 &3&lUserPrefix " + getDescription().getVersion() + "&7!");
log("&7本插件由 &b&lYourCraft &7提供长期支持与维护。");
return true;
}
@Override
public void onDisable() {
showPluginName();
log(getName() + " " + getDescription().getVersion() + " 开始卸载...");
long startTime = System.currentTimeMillis();
log("卸载监听器...");
Bukkit.getServicesManager().unregisterAll(this);
log("卸载完成 ,共耗时 " + (System.currentTimeMillis() - startTime) + " ms 。");
showAD();
public boolean isDebugging() {
return PluginConfig.DEBUG.getNotNull();
}
/**
* 注册监听器
*
* @param listener 监听器
*/
public static void regListener(Listener listener) {
Bukkit.getPluginManager().registerEvents(listener, getInstance());
public static void info(String... message) {
getInstance().log(message);
}
public static void log(String message) {
Bukkit.getConsoleSender().sendMessage(ColorParser.parse("[" + getInstance().getName() + "] " + message));
public static void debugging(String... message) {
getInstance().debug(message);
}
public static void debug(String message) {
if (PluginConfig.DEBUG.get()) {
log("[DEBUG] " + message);
}
public static void serve(String... message) {
getInstance().error(message);
}
public static void error(String message) {
log("&c[ERROR] &r" + message);
}
public static JavaPlugin getInstance() {
public static Main getInstance() {
return instance;
}
public static void registerCommand(String commandName,
@NotNull CommandExecutor executor) {
registerCommand(commandName, executor, null);
}
public static void registerCommand(String commandName,
@NotNull CommandExecutor executor,
@Nullable TabCompleter tabCompleter) {
PluginCommand command = Bukkit.getPluginCommand(commandName);
if (command == null) return;
command.setExecutor(executor);
if (tabCompleter != null) command.setTabCompleter(tabCompleter);
}
private void showPluginName() {
log("&b _ _ &f _____ __ _ ");
log("&b| | | | &f| __ \\ / _|(_) ");
log("&b| | | | ___ ___ _ __ &f| |__) |_ __ ___ | |_ _ __ __");
log("&b| | | |/ __| / _ \\| '__|&f| ___/| '__|/ _ \\| _|| |\\ \\/ /");
log("&b| |__| |\\__ \\| __/| | &f| | | | | __/| | | | > < ");
log("&b \\____/ |___/ \\___||_| &f|_| |_| \\___||_| |_|/_/\\_\\");
log("&8 ");
log("&8> &f" + getDescription().getWebsite());
}
private void showAD() {
log("&7感谢您使用 &3&lUserPrefix " + getDescription().getVersion() + "&7!");
log("&7本插件由 &b&lYourCraft &7提供长期支持与维护。");
}
}
@@ -0,0 +1,26 @@
package cc.carm.plugin.userprefix;
import cc.carm.plugin.userprefix.configuration.prefix.PrefixConfig;
import cc.carm.plugin.userprefix.manager.ConfigManager;
import cc.carm.plugin.userprefix.manager.PrefixManager;
import cc.carm.plugin.userprefix.manager.UserManager;
public class UserPrefix {
public static PrefixManager getPrefixManager() {
return Main.getInstance().prefixManager;
}
public static ConfigManager getConfigManager() {
return Main.getInstance().configManager;
}
public static UserManager getUserManager() {
return Main.getInstance().userManager;
}
public static PrefixConfig getDefaultPrefix(){
return getPrefixManager().getDefaultPrefix();
}
}
@@ -0,0 +1,63 @@
package cc.carm.plugin.userprefix.command;
import cc.carm.plugin.userprefix.UserPrefix;
import cc.carm.plugin.userprefix.configuration.PluginMessages;
import cc.carm.plugin.userprefix.configuration.prefix.PrefixConfig;
import cc.carm.plugin.userprefix.ui.PrefixSelectGUI;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class AdminCommand implements CommandExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s, @NotNull String[] args) {
if (args.length == 1) {
String aim = args[0];
if (aim.equalsIgnoreCase("list")) {
PluginMessages.LIST.HEADER.send(sender);
for (PrefixConfig value : UserPrefix.getPrefixManager().getPrefixes().values()) {
PluginMessages.LIST.VALUE.send(sender,
value.getWeight(), value.getIdentifier(),
value.getName(), value.getPermission(),
value.getContent(), sender.getName()
);
}
return true;
} else if (aim.equalsIgnoreCase("reload")) {
long s1 = System.currentTimeMillis();
PrefixSelectGUI.closeAll(); // 关掉所有正在显示的前缀列表
try {
UserPrefix.getConfigManager().reload(); // 重载配置文件
int num = UserPrefix.getPrefixManager().loadPrefixes(); //加载重载后了的前缀配置
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
UserPrefix.getUserManager().checkPrefix(onlinePlayer, false);
/*
* 这里关掉loadOthers(为其他玩家更新)了。
* 因为每个玩家更新的时候会为其他人更新自己,
* 全部走完一遍后,所有玩家都会加载最新的前缀内容。
*/
UserPrefix.getUserManager().updatePrefixView(onlinePlayer, false);
}
PluginMessages.RELOAD.SUCCESS.send(sender, System.currentTimeMillis() - s1, num);
} catch (Exception e) {
PluginMessages.RELOAD.FAILED.send(sender, e.getMessage());
e.printStackTrace();
}
return true;
}
return help(sender);
}
return help(sender);
}
public static boolean help(CommandSender sender) {
PluginMessages.COMMAND_USAGE.ADMIN.send(sender);
return true;
}
}
@@ -1,5 +1,6 @@
package cc.carm.plugin.userprefix.command;
import cc.carm.plugin.userprefix.configuration.PluginMessages;
import cc.carm.plugin.userprefix.ui.PrefixSelectGUI;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
@@ -8,7 +9,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class UserPrefixCommand implements CommandExecutor {
public class UserCommand implements CommandExecutor {
@Override
@@ -17,7 +18,7 @@ public class UserPrefixCommand implements CommandExecutor {
PrefixSelectGUI.open((Player) sender);
} else {
if (strings.length != 1) {
sender.sendMessage("输入 /prefix <ID> 为玩家打开前缀GUI。");
PluginMessages.COMMAND_USAGE.CONSOLE.send(sender);
} else {
Player player = Bukkit.getPlayer(strings[0]);
if (player != null) {
@@ -1,73 +0,0 @@
package cc.carm.plugin.userprefix.command;
import cc.carm.plugin.userprefix.configuration.PluginConfig;
import cc.carm.plugin.userprefix.manager.ConfigManager;
import cc.carm.plugin.userprefix.manager.PrefixManager;
import cc.carm.plugin.userprefix.manager.UserManager;
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
import cc.carm.plugin.userprefix.ui.PrefixSelectGUI;
import cc.carm.plugin.userprefix.util.MessageUtil;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class UserPrefixAdminCommand implements CommandExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s, @NotNull String[] args) {
if (args.length == 1) {
String aim = args[0];
if (aim.equalsIgnoreCase("list")) {
MessageUtil.sendWithPlaceholders(sender, PluginConfig.Messages.LIST_TITLE.get());
for (ConfiguredPrefix value : PrefixManager.getPrefixes().values()) {
MessageUtil.sendWithPlaceholders(
sender, PluginConfig.Messages.LIST_VALUE.get(),
new String[]{
"%(weight)", "%(identifier)",
"%(name)", "%(permission)",
"%(content)", "%(sender_name)"
},
new Object[]{
value.getWeight(), value.getIdentifier(),
value.getName(), value.getPermission(),
value.getContent(), sender.getName()
}
);
}
return true;
} else if (aim.equalsIgnoreCase("reload")) {
long s1 = System.currentTimeMillis();
PrefixSelectGUI.closeAll(); // 关掉所有正在显示的前缀列表
ConfigManager.reload(); // 重载配置文件
PrefixManager.loadPrefixes(); //加载重载后了的前缀配置
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
UserManager.checkPrefix(onlinePlayer, false);
/*
* 这里关掉loadOthers(为其他玩家更新)了。
* 因为每个玩家更新的时候会为其他人更新自己,
* 全部走完一遍后,所有玩家都会加载最新的前缀内容。
*/
UserManager.updatePrefixView(onlinePlayer, false);
}
MessageUtil.sendWithPlaceholders(
sender, PluginConfig.Messages.RELOAD.get(),
new String[]{"%(time)"}, new Object[]{(System.currentTimeMillis() - s1)}
);
return true;
}
return help(sender);
}
return help(sender);
}
public static boolean help(CommandSender sender) {
MessageUtil.send(sender, PluginConfig.Messages.HELP.get());
return true;
}
}
@@ -1,87 +1,174 @@
package cc.carm.plugin.userprefix.configuration;
import cc.carm.plugin.userprefix.configuration.message.ConfigMessageList;
import cc.carm.plugin.userprefix.configuration.values.ConfigSound;
import cc.carm.plugin.userprefix.configuration.values.ConfigValue;
import cc.carm.plugin.userprefix.util.ItemStackFactory;
import cc.carm.lib.configuration.core.ConfigurationRoot;
import cc.carm.lib.configuration.core.annotation.ConfigPath;
import cc.carm.lib.configuration.core.annotation.HeaderComment;
import cc.carm.lib.configuration.core.value.ConfigValue;
import cc.carm.lib.configuration.core.value.type.ConfiguredValue;
import cc.carm.lib.easyplugin.gui.configuration.GUIActionConfiguration;
import cc.carm.lib.easyplugin.gui.configuration.GUIActionType;
import cc.carm.lib.easyplugin.gui.configuration.GUIItemConfiguration;
import cc.carm.lib.mineconfiguration.bukkit.value.ConfiguredItem;
import cc.carm.lib.mineconfiguration.bukkit.value.ConfiguredSound;
import cc.carm.plugin.userprefix.configuration.reader.GUIItemReader;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag;
public class PluginConfig {
import java.util.Collections;
public static ConfigValue<Boolean> DEBUG = new ConfigValue<>("debug", Boolean.class, false);
public class PluginConfig extends ConfigurationRoot {
public static ConfigValue<Boolean> METRICS = new ConfigValue<>("metrics", Boolean.class, true);
@HeaderComment({"开发者查错模式"})
public static final ConfigValue<Boolean> DEBUG = ConfiguredValue.of(Boolean.class, false);
public static final ConfigValue<Boolean> CHECK_UPDATE = new ConfigValue<>("check-update", Boolean.class, true);
@HeaderComment({
"统计数据设定",
" 该选项用于帮助开发者统计插件版本与使用情况,且绝不会影响性能与使用体验。",
" 当然,您也可以选择在这里关闭,或在plugins/bStats下的配置文件中关闭。"
})
public static final ConfigValue<Boolean> METRICS = ConfiguredValue.of(Boolean.class, true);
public static class CustomStorage {
@HeaderComment({
"检查更新设定",
"该选项用于插件判断是否要检查更新,若您不希望插件检查更新并提示您,可以选择关闭。",
"检查更新为异步操作,绝不会影响性能与使用体验。"
})
public static final ConfigValue<Boolean> CHECK_UPDATE = ConfiguredValue.of(Boolean.class, true);
public static ConfigValue<Boolean> ENABLE = new ConfigValue<>("custom-storage.enable", Boolean.class, false);
@HeaderComment({"自定义存储位置设定", "可以规定到远程文件夹中去加载前缀配置"})
public static final class CUSTOM_STORAGE {
public static ConfigValue<String> PATH = new ConfigValue<>("custom-storage.path", String.class, "prefixes/");
@HeaderComment({"是否启用自定义存储位置"})
public static final ConfigValue<Boolean> ENABLE = ConfiguredValue.of(Boolean.class, false);
@HeaderComment({
"目标存储路径,必须指向一个文件夹。",
"默认存储位置为 “插件文件夹”/prefixes",
"支持绝对文件路径,如 \"/etc/minecraft/configurations/prefixes/\""
})
public static final ConfigValue<String> PATH = ConfiguredValue.of(String.class, "prefixes/");
}
public static class Functions {
@HeaderComment("功能设定")
public static class FUNCTIONS {
public static ConfigValue<Boolean> NAME_PREFIX = new ConfigValue<>("functions.on-name-prefix.enable", Boolean.class, true);
public static ConfigValue<Boolean> NAME_ORDER_DESC = new ConfigValue<>("functions.on-name-prefix.order-desc", Boolean.class, true);
@ConfigPath("on-name-prefix")
@HeaderComment({"头顶与TabList前缀功能,该方法用到了玩家名计分板接口,如有冲突请关掉哦~"})
public static final class NAME_PREFIX {
public static ConfigValue<Boolean> AUTO_USE = new ConfigValue<>("functions.auto-prefix-use", Boolean.class, true);
@HeaderComment("是否开启本功能")
public static final ConfigValue<Boolean> ENABLE = ConfiguredValue.of(Boolean.class, true);
public static class Chat {
@HeaderComment("是否按降序排列,即权重越高的前缀显示在越上面;若为false则按升序排列。")
public static final ConfigValue<Boolean> ORDER_DESC = ConfiguredValue.of(Boolean.class, true);
public static ConfigValue<Boolean> ENABLE = new ConfigValue<>("functions.chat.enable", Boolean.class, false);
public static ConfigValue<String> FORMAT = new ConfigValue<>("functions.chat.format", String.class, "<%1$s> %2$s");
}
@ConfigPath("auto-prefix-use")
@HeaderComment("自动使用前缀,即当玩家没有自己选择一个前缀的时候,会自动使用所拥有的的前缀中权重最高的那一个")
public static final ConfigValue<Boolean> AUTO_USE = ConfiguredValue.of(Boolean.class, true);
@HeaderComment({
"聊天功能设定",
"- 我不推荐使用本插件的聊天功能,而是建议使用其他的聊天插件。",
"- 本插件仅仅提供了**最基本**的格式变量支持,不包含其他任何功能。",
"- 注意聊天格式需要遵守Bukkit原格式,即不得缺失 “%1$s” 和 “%2$s” 。",
"- 本插件的聊天功能不影响其他插件对聊天事件的操作。"
})
public static final class CHAT {
@HeaderComment("是否开启本功能")
public static ConfigValue<Boolean> ENABLE = ConfiguredValue.of(Boolean.class, false);
@HeaderComment({
"聊天的格式,注意 “%1$s” 和 “%2$s” 不可缺少。",
"- %1$s -> 玩家名", "- %2$s -> 聊天内容"
})
public static ConfigValue<String> FORMAT = ConfiguredValue.of(String.class, "<%1$s> %2$s");
}
}
@HeaderComment({"前缀GUI界面设定"})
public static class GUI {
public static ConfigValue<String> TITLE = new ConfigValue<>("GUI.title", String.class, "&f&l我的前缀 &8| 列表");
@HeaderComment("GUI的标题")
public static final ConfigValue<String> TITLE = ConfiguredValue.of(String.class, "&f&l我的前缀 &8| 列表");
public static class Items {
@HeaderComment("GUI中的按钮")
public static final class ITEMS {
public static ConfigValue<ItemStack> NEXT_PAGE = new ConfigValue<>("GUI.items.next-page", ItemStack.class,
new ItemStackFactory(Material.ARROW)
.setDisplayName("下一页")
.addLore("&7&o右键可前往最后一页")
.toItemStack()
);
public static ConfigValue<ItemStack> PREVIOUS_PAGE = new ConfigValue<>("GUI.items.previous-page", ItemStack.class,
new ItemStackFactory(Material.ARROW)
.setDisplayName("上一页")
.addLore("&7&o右键可前往第一页哦")
.toItemStack()
);
@HeaderComment("前往下一页的物品 (只有存在下一页时才会显示)")
public static final ConfiguredItem NEXT_PAGE = ConfiguredItem.create()
.defaultType(Material.ARROW)
.defaultName("一页")
.defaultLore("&7&o右键可前往最后一页哦")
.build();
@ConfigPath("previous-page")
@HeaderComment({"前往上一页时的物品 (只有当前页不是第一页时才会显示)"})
public static final ConfiguredItem PREV_PAGE = ConfiguredItem.create()
.defaultType(Material.ARROW)
.defaultName("上一页")
.defaultLore("&7&o右键可前往第一页哦")
.build();
@HeaderComment("GUI中其他的物品配置")
public static final ConfigValue<GUIItemConfiguration> BACK = ConfiguredValue.builder(GUIItemConfiguration.class)
.fromSection()
.serializeValue(GUIItemConfiguration::serialize)
.parseValue((v, d) -> GUIItemReader.readFrom(v))
.defaults(new GUIItemConfiguration(
Material.BARRIER, 0, "&c&l返回",
Collections.singletonList("&f点击即可返回上一菜单"),
Collections.singletonList(GUIActionConfiguration.of(GUIActionType.CHAT, "/menu")),
Collections.singletonList(49)
)).build();
}
}
public static class Messages {
@HeaderComment({"相关的声音,留空则不播放声音", "格式为 【声音名:音量:音调】 或 【声音名:音量】 或 【声音名】"})
public static final class SOUNDS {
public static ConfigMessageList SELECTED = new ConfigMessageList("selected");
public static ConfigMessageList EXPIRED = new ConfigMessageList("expired");
public static ConfigMessageList REMOVED = new ConfigMessageList("removed");
public static ConfigMessageList RELOAD = new ConfigMessageList("reload");
public static ConfigMessageList HELP = new ConfigMessageList("help");
public static ConfigMessageList LIST_TITLE = new ConfigMessageList("list-title");
public static ConfigMessageList LIST_VALUE = new ConfigMessageList("list-value");
public static final ConfiguredSound GUI_OPEN = ConfiguredSound.of("BLOCK_NOTE_BLOCK_PLING", 0.5F, 0.8F);
public static final ConfiguredSound GUI_CLICK = ConfiguredSound.of("UI_BUTTON_CLICK");
public static final ConfiguredSound PREFIX_CHANGE = ConfiguredSound.of("ENTITY_VILLAGER_YES");
public static final ConfiguredSound PREFIX_EXPIRED = ConfiguredSound.of("ENTITY_VILLAGER_NO");
}
public static class Sounds {
@HeaderComment({"默认前缀配置"})
public static final class DEFAULT_PREFIX {
public static ConfigSound GUI_OPEN = new ConfigSound("Sounds.openGUI");
public static ConfigSound GUI_CLICK = new ConfigSound("Sounds.guiClick");
public static ConfigSound PREFIX_CHANGE = new ConfigSound("Sounds.prefixChange");
public static ConfigSound PREFIX_EXPIRED = new ConfigSound("Sounds.prefixExpired");
@HeaderComment("默认前缀的显示名称,用于在消息提示中显示。")
public static final ConfigValue<String> NAME = ConfiguredValue.of(String.class, "默认前缀");
@HeaderComment({"默认前缀的权重,默认为0。"})
public static final ConfigValue<Integer> WEIGHT = ConfiguredValue.of(Integer.class, 0);
@HeaderComment({"默认前缀的内容,即用于显示的实际前缀"})
public static final ConfigValue<String> CONTENT = ConfiguredValue.of(String.class, "&r");
@HeaderComment({"当未选择默认前缀时显示的物品"})
public static final ConfiguredItem ITEM_NOT_USING = ConfiguredItem.create()
.defaultType(Material.NAME_TAG)
.defaultName("&f默认玩家前缀 &f(点击切换)")
.defaultLore("", "&a➥ 点击切换到该前缀")
.build();
@HeaderComment({"当选择了默认前缀时显示的物品"})
public static final ConfiguredItem ITEM_USING = ConfiguredItem.create()
.defaultType(Material.NAME_TAG)
.defaultEnchant(Enchantment.PROTECTION_ENVIRONMENTAL, 1)
.defaultFlags(ItemFlag.HIDE_ENCHANTS)
.defaultName("&f默认玩家前缀")
.defaultLore("", "&a✔ 您正在使用该前缀")
.build();
}
@@ -0,0 +1,67 @@
package cc.carm.plugin.userprefix.configuration;
import cc.carm.lib.configuration.core.ConfigurationRoot;
import cc.carm.lib.configuration.core.annotation.HeaderComment;
import cc.carm.lib.mineconfiguration.bukkit.value.ConfiguredMessageList;
public class PluginMessages extends ConfigurationRoot {
public static final class COMMAND_USAGE {
public static ConfiguredMessageList<String> CONSOLE = ConfiguredMessageList.asStrings().defaults(
"&f请输入 &b/prefix <玩家ID> &f为指定玩家打开前缀GUI。"
).build();
public static ConfiguredMessageList<String> ADMIN = ConfiguredMessageList.asStrings().defaults(
"&3&l用户前缀系统 &f帮助",
"&8# &f/upa list",
"&8- &7查看当前前缀列表。",
"&8# &f/upa reload",
"&8- &7重载前缀配置。"
).build();
}
public static ConfiguredMessageList<String> SELECTED = ConfiguredMessageList.asStrings()
.defaults("&7您选择了 &f%(name) &7作为当前显示的前缀。")
.params("name").build();
public static ConfiguredMessageList<String> EXPIRED = ConfiguredMessageList.asStrings()
.defaults(
"&7您先前使用的前缀 &f%(oldName) &7已到期。",
"&7现在已为您重新调整为 &f%(newName) &7。"
).params("oldName", "newName").build();
public static ConfiguredMessageList<String> REMOVED = ConfiguredMessageList.asStrings()
.defaults("&7您先前使用的前缀已被移除,现在已为您重新调整为 &f%(newName) &7。")
.params("newName").build();
public static final class RELOAD {
public static ConfiguredMessageList<String> SUCCESS = ConfiguredMessageList.asStrings()
.defaults("&a&l重载完成!&7耗时 &f%(time)ms&7,共加载了 &b%(count) &7个前缀。")
.params("time", "count").build();
public static ConfiguredMessageList<String> FAILED = ConfiguredMessageList.asStrings()
.defaults("&c&l重载出错!&7错误提示为 &8“&r%(error)&8”。")
.params("error").build();
}
@HeaderComment("管理员使用的 “/upa list” 指令的格式")
public static final class LIST {
public static ConfiguredMessageList<String> HEADER = ConfiguredMessageList.asStrings()
.defaults("&3&l用户前缀系统 &f前缀列表").build();
public static ConfiguredMessageList<String> VALUE = ConfiguredMessageList.asStrings().defaults(
"&8#%(weight) &f%(identifier)",
"&8- &7显示名 &r%(name) &7权限 &r%(permission)",
"&8- &7内容示例&r %(content) %(sender_name)"
).params("weight", "identifier", "name", "permission", "sender_name").build();
}
}
@@ -1,64 +0,0 @@
package cc.carm.plugin.userprefix.configuration.file;
import cc.carm.plugin.userprefix.util.ConfigurationUtil;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.io.IOException;
public class FileConfig {
private final JavaPlugin plugin;
private final String fileName;
private File file;
private FileConfiguration config;
public FileConfig(final JavaPlugin plugin) {
this(plugin, "config.yml");
}
public FileConfig(final JavaPlugin plugin, final String name) {
this.plugin = plugin;
this.fileName = name;
initFile();
}
private void initFile() {
this.file = new File(plugin.getDataFolder(), fileName);
if (!this.file.exists()) {
if (!this.file.getParentFile().exists()) {
this.file.getParentFile().mkdirs();
}
plugin.saveResource(fileName, true);
}
this.config = ConfigurationUtil.bang(this.file);
}
public File getFile() {
return file;
}
public FileConfiguration getConfig() {
return config;
}
public void save() {
try {
getConfig().save(getFile());
} catch (IOException e) {
e.printStackTrace();
}
}
public void reload() {
if (getFile().exists()) {
this.config = ConfigurationUtil.bang(getFile());
} else {
initFile();
}
}
}
@@ -1,32 +0,0 @@
package cc.carm.plugin.userprefix.configuration.message;
import cc.carm.plugin.userprefix.configuration.values.ConfigValue;
import cc.carm.plugin.userprefix.manager.ConfigManager;
import cc.carm.plugin.userprefix.util.MessageUtil;
import org.bukkit.command.CommandSender;
import java.util.Arrays;
public class ConfigMessage extends ConfigValue<String> {
public ConfigMessage(String configSection) {
this(configSection, null);
}
public ConfigMessage(String configSection, String defaultValue) {
super(ConfigManager.getMessageConfig(), configSection, String.class, defaultValue);
}
public void send(CommandSender sender) {
MessageUtil.send(sender, get());
}
public void sendWithPlaceholders(CommandSender sender) {
MessageUtil.sendWithPlaceholders(sender, get());
}
public void sendWithPlaceholders(CommandSender sender, String[] params, Object[] values) {
MessageUtil.sendWithPlaceholders(sender, Arrays.asList(get()), params, values);
}
}
@@ -1,29 +0,0 @@
package cc.carm.plugin.userprefix.configuration.message;
import cc.carm.plugin.userprefix.configuration.values.ConfigValueList;
import cc.carm.plugin.userprefix.manager.ConfigManager;
import cc.carm.plugin.userprefix.util.MessageUtil;
import org.bukkit.command.CommandSender;
public class ConfigMessageList extends ConfigValueList<String> {
public ConfigMessageList(String configSection) {
super(ConfigManager.getMessageConfig(), configSection, String.class);
}
public ConfigMessageList(String configSection, String[] defaultValue) {
super(ConfigManager.getMessageConfig(), configSection, String.class, defaultValue);
}
public void send(CommandSender sender) {
MessageUtil.send(sender, get());
}
public void sendWithPlaceholders(CommandSender sender) {
MessageUtil.sendWithPlaceholders(sender, get());
}
public void sendWithPlaceholders(CommandSender sender, String[] params, Object[] values) {
MessageUtil.sendWithPlaceholders(sender, get(), params, values);
}
}
@@ -0,0 +1,107 @@
package cc.carm.plugin.userprefix.configuration.prefix;
import cc.carm.lib.easyplugin.utils.ColorParser;
import cc.carm.lib.mineconfiguration.bukkit.data.ItemConfig;
import cc.carm.plugin.userprefix.manager.ServiceManager;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
public class PrefixConfig {
private @Nullable File dataFile;
private @Nullable FileConfiguration configuration;
protected final @NotNull String identifier;
protected final @NotNull String name;
protected final @NotNull String content;
protected final int weight;
protected final @Nullable String permission;
protected final @NotNull ItemConfig itemHasPermission;
protected final @Nullable ItemConfig itemNoPermission;
protected final @Nullable ItemConfig itemWhenUsing;
public PrefixConfig(@NotNull String identifier, @NotNull String name,
@NotNull String content, int weight, @Nullable String permission,
@NotNull ItemConfig itemHasPermission,
@Nullable ItemConfig itemNoPermission,
@Nullable ItemConfig itemWhenUsing) {
this.identifier = identifier;
this.name = name;
this.content = content;
this.weight = weight;
this.permission = permission;
this.itemHasPermission = itemHasPermission;
this.itemNoPermission = itemNoPermission;
this.itemWhenUsing = itemWhenUsing;
}
@NotNull
public String getIdentifier() {
return identifier;
}
@NotNull
public String getName() {
return name;
}
@NotNull
public String getContent() {
return ColorParser.parse(content);
}
public int getWeight() {
return weight;
}
@Nullable
public String getPermission() {
return permission;
}
@NotNull
public ItemStack getItemHasPermission(@Nullable Player player) {
return this.itemHasPermission.getItemStack(player);
}
@Nullable
public ItemStack getItemNoPermission(@Nullable Player player) {
if (this.itemNoPermission == null) return null;
return this.itemNoPermission.getItemStack(player);
}
@Nullable
public ItemStack getItemWhenUsing(@Nullable Player player) {
if (this.itemWhenUsing == null) return getItemHasPermission(player);
else return this.itemWhenUsing.getItemStack(player);
}
public boolean isPublic() {
return getPermission() == null;
}
public boolean isVisible(Player player) {
return this.itemWhenUsing != null || checkPermission(player);
}
/**
* 判断某玩家是否有权限使用该前缀
*
* @param player 玩家
* @return 若前缀标识不存在,则返回false;若前缀为默认前缀,或该前缀无权限,或玩家有该前缀的权限,则返回true。
*/
public boolean checkPermission(Player player) {
return permission == null || ServiceManager.hasPermission(player, permission);
}
}
@@ -0,0 +1,41 @@
package cc.carm.plugin.userprefix.configuration.reader;
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
import cc.carm.lib.easyplugin.gui.configuration.GUIActionConfiguration;
import cc.carm.lib.easyplugin.gui.configuration.GUIItemConfiguration;
import org.bukkit.Material;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
public class GUIItemReader {
public static @Nullable GUIItemConfiguration readFrom(@Nullable ConfigurationWrapper section) {
if (section == null) return null;
String material = Optional.ofNullable(section.getString("type")).orElse("STONE");
Material type = Optional.ofNullable(Material.matchMaterial(material)).orElse(Material.STONE);
int data = section.getInt("data", 0);
String name = section.getString("name");
List<String> lore = section.getStringList("lore");
List<Integer> slots = section.getIntegerList("slots");
int slot = section.getInt("slot", 0);
List<String> actionsString = section.getStringList("actions");
List<GUIActionConfiguration> actions = new ArrayList<>();
for (String actionString : actionsString) {
GUIActionConfiguration action = GUIActionConfiguration.deserialize(actionString);
if (action == null) continue;
actions.add(action);
}
return new GUIItemConfiguration(
type, data, name, lore, actions,
slots.size() > 0 ? slots : Collections.singletonList(slot)
);
}
}
@@ -1,73 +0,0 @@
package cc.carm.plugin.userprefix.configuration.values;
import cc.carm.plugin.userprefix.Main;
import cc.carm.plugin.userprefix.configuration.file.FileConfig;
import cc.carm.plugin.userprefix.manager.ConfigManager;
import org.bukkit.Sound;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
public class ConfigSound {
FileConfig source;
String configSection;
Sound defaultValue;
public ConfigSound(String configSection) {
this(configSection, null);
}
public ConfigSound(String configSection, Sound defaultValue) {
this(ConfigManager.getPluginConfig(), configSection, defaultValue);
}
public ConfigSound(FileConfig source, String configSection, Sound defaultValue) {
this.source = source;
this.configSection = configSection;
this.defaultValue = defaultValue;
}
public FileConfiguration getConfiguration() {
return this.source.getConfig();
}
public void set(Sound value, float volume) {
getConfiguration().set(this.configSection, value.name() + ":" + volume);
this.save();
}
public void set(Sound value, float volume, float pitch) {
getConfiguration().set(this.configSection, value.name() + ":" + volume + ":" + pitch);
this.save();
}
public void play(Player player) {
Sound finalSound = defaultValue;
float pitch = 1;
float volume = 1;
String soundString = getConfiguration().getString(this.configSection);
if (soundString != null) {
String[] args = soundString.contains(":") ? soundString.split(":") : new String[]{soundString};
try {
if (args.length >= 1) finalSound = Sound.valueOf(args[0]);
if (args.length >= 2) volume = Float.parseFloat(args[1]);
if (args.length >= 3) volume = Float.parseFloat(args[2]);
} catch (Exception exception) {
Main.error("声音 " + this.configSection + " 配置错误,不存在 " + soundString + " ,请检查。");
Main.error("There's no sound matches in " + this.configSection + " , please check the configuration");
}
}
if (finalSound != null) {
player.playSound(player.getLocation(), finalSound, volume, pitch);
}
}
public void save() {
this.source.save();
}
}
@@ -1,58 +0,0 @@
package cc.carm.plugin.userprefix.configuration.values;
import cc.carm.plugin.userprefix.configuration.file.FileConfig;
import cc.carm.plugin.userprefix.manager.ConfigManager;
import org.bukkit.configuration.file.FileConfiguration;
public class ConfigValue<V> {
FileConfig source;
String configSection;
Class<V> clazz;
V defaultValue;
public ConfigValue(String configSection, Class<V> clazz) {
this(configSection, clazz, null);
}
public ConfigValue(String configSection, Class<V> clazz, V defaultValue) {
this(ConfigManager.getPluginConfig(), configSection, clazz, defaultValue);
}
public ConfigValue(FileConfig source, String configSection, Class<V> clazz, V defaultValue) {
this.source = source;
this.configSection = configSection;
this.clazz = clazz;
this.defaultValue = defaultValue;
}
public FileConfiguration getConfiguration() {
return this.source.getConfig();
}
public V get() {
if (getConfiguration().contains(this.configSection)) {
Object val = getConfiguration().get(this.configSection, this.defaultValue);
return this.clazz.isInstance(val) ? this.clazz.cast(val) : this.defaultValue;
} else {
// 如果没有默认值,就把配置写进去,便于配置
return setDefault();
}
}
public void set(V value) {
getConfiguration().set(this.configSection, value);
this.save();
}
public void save() {
this.source.save();
}
public V setDefault() {
set(this.defaultValue);
return this.defaultValue;
}
}
@@ -1,71 +0,0 @@
package cc.carm.plugin.userprefix.configuration.values;
import cc.carm.plugin.userprefix.configuration.file.FileConfig;
import cc.carm.plugin.userprefix.manager.ConfigManager;
import org.bukkit.configuration.file.FileConfiguration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ConfigValueList<V> {
FileConfig source;
String configSection;
Class<V> clazz;
V[] defaultValue;
public ConfigValueList(String configSection, Class<V> clazz) {
this(ConfigManager.getPluginConfig(), configSection, clazz);
}
public ConfigValueList(String configSection, Class<V> clazz, V[] defaultValue) {
this(ConfigManager.getPluginConfig(), configSection, clazz, defaultValue);
}
public ConfigValueList(FileConfig configuration, String configSection, Class<V> clazz) {
this(configuration, configSection, clazz, null);
}
public ConfigValueList(FileConfig configuration, String configSection, Class<V> clazz, V[] defaultValue) {
this.source = configuration;
this.configSection = configSection;
this.clazz = clazz;
this.defaultValue = defaultValue;
}
public FileConfiguration getConfiguration() {
return this.source.getConfig();
}
public ArrayList<V> get() {
List<?> list = getConfiguration().getList(this.configSection);
if (list == null) {
if (defaultValue != null) {
return new ArrayList<>(Arrays.asList(defaultValue));
} else {
return new ArrayList(0);
}
} else {
ArrayList<V> result = new ArrayList();
for (Object object : list) {
if (this.clazz.isInstance(object)) {
result.add(this.clazz.cast(object));
}
}
return result;
}
}
public void set(ArrayList<V> value) {
getConfiguration().set(this.configSection, value);
this.save();
}
public void save() {
this.source.save();
}
}
@@ -1,12 +1,11 @@
package cc.carm.plugin.userprefix.event;
import cc.carm.plugin.userprefix.Main;
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
import cc.carm.plugin.userprefix.configuration.prefix.PrefixConfig;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -14,62 +13,59 @@ import java.util.function.Consumer;
public class UserPrefixChangeEvent extends UserPrefixEvent implements Cancellable {
public static HandlerList handler = new HandlerList();
public static HandlerList handler = new HandlerList();
private boolean cancelled;
private boolean cancelled;
private final @Nullable ConfiguredPrefix before;
private @NotNull ConfiguredPrefix after;
private final @Nullable PrefixConfig before;
private @NotNull PrefixConfig after;
public UserPrefixChangeEvent(@NotNull Player who,
@Nullable ConfiguredPrefix before,
@NotNull ConfiguredPrefix after) {
super(who);
this.before = before;
this.after = after;
}
public UserPrefixChangeEvent(@NotNull Player who,
@Nullable PrefixConfig before,
@NotNull PrefixConfig after) {
super(who);
this.before = before;
this.after = after;
}
public @Nullable ConfiguredPrefix getBefore() {
return before;
}
public @Nullable PrefixConfig getBefore() {
return before;
}
public @NotNull ConfiguredPrefix getAfter() {
return after;
}
public @NotNull PrefixConfig getAfter() {
return after;
}
public void setAfter(@NotNull ConfiguredPrefix after) {
this.after = after;
}
public void setAfter(@NotNull PrefixConfig after) {
this.after = after;
}
@Override
public boolean isCancelled() {
if (before == null) return false; //Could not be cancelled when prefix is null.
else return this.cancelled;
}
@Override
public boolean isCancelled() {
if (before == null) return false; //Could not be cancelled when prefix is null.
else return this.cancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
@NotNull
@Override
public HandlerList getHandlers() {
return handler;
}
@NotNull
@Override
public HandlerList getHandlers() {
return handler;
}
public static void call(@NotNull Player who,
@Nullable ConfiguredPrefix before,
@NotNull ConfiguredPrefix after,
@Nullable Consumer<@Nullable ConfiguredPrefix> finish) {
new BukkitRunnable() {
@Override
public void run() {
UserPrefixChangeEvent event = new UserPrefixChangeEvent(who, before, after);
Bukkit.getPluginManager().callEvent(event);
if (finish != null) finish.accept(event.isCancelled() ? null : event.getAfter());
}
}.runTask(Main.getInstance());
}
public static void call(@NotNull Player who,
@Nullable PrefixConfig before,
@NotNull PrefixConfig after,
@Nullable Consumer<@Nullable PrefixConfig> finish) {
Main.getInstance().getScheduler().run(() -> {
UserPrefixChangeEvent event = new UserPrefixChangeEvent(who, before, after);
Bukkit.getPluginManager().callEvent(event);
if (finish != null) finish.accept(event.isCancelled() ? null : event.getAfter());
});
}
}
@@ -1,43 +1,36 @@
package cc.carm.plugin.userprefix.event;
import cc.carm.plugin.userprefix.Main;
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
import org.bukkit.Bukkit;
import cc.carm.plugin.userprefix.configuration.prefix.PrefixConfig;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull;
public class UserPrefixExpireEvent extends UserPrefixEvent {
public static HandlerList handler = new HandlerList();
public static HandlerList handler = new HandlerList();
public final @NotNull ConfiguredPrefix expiredPrefix;
public final @NotNull PrefixConfig expiredPrefix;
public UserPrefixExpireEvent(@NotNull Player who,
@NotNull ConfiguredPrefix expiredPrefix) {
super(who);
this.expiredPrefix = expiredPrefix;
}
public UserPrefixExpireEvent(@NotNull Player who,
@NotNull PrefixConfig expiredPrefix) {
super(who);
this.expiredPrefix = expiredPrefix;
}
public @NotNull ConfiguredPrefix getExpiredPrefix() {
return expiredPrefix;
}
public @NotNull PrefixConfig getExpiredPrefix() {
return expiredPrefix;
}
@NotNull
@Override
public HandlerList getHandlers() {
return handler;
}
@NotNull
@Override
public HandlerList getHandlers() {
return handler;
}
public static void call(@NotNull Player player, @NotNull ConfiguredPrefix currentPrefix) {
new BukkitRunnable() {
@Override
public void run() {
Bukkit.getPluginManager().callEvent(new UserPrefixExpireEvent(player, currentPrefix));
}
}.runTask(Main.getInstance());
}
public static void call(@NotNull Player player, @NotNull PrefixConfig currentPrefix) {
Main.getInstance().callEventSync(new UserPrefixExpireEvent(player, currentPrefix));
}
}
@@ -1,35 +0,0 @@
package cc.carm.plugin.userprefix.hooker;
import cc.carm.lib.githubreleases4j.GithubReleases4J;
import cc.carm.plugin.userprefix.Main;
import org.bukkit.scheduler.BukkitRunnable;
public class UpdateChecker {
public static void checkUpdate(String currentVersion) {
new BukkitRunnable() {
@Override
public void run() {
String downloadURL = GithubReleases4J.getReleasesURL("CarmJos", "UserPrefix");
Integer behindVersions = GithubReleases4J.getVersionBehind(
"CarmJos", "UserPrefix", currentVersion
);
if (behindVersions == null) {
Main.error("检查更新失败,请您定期查看插件是否更新,避免安全问题。");
Main.error("下载地址 " + downloadURL);
} else if (behindVersions == 0) {
Main.log("检查完成,当前已是最新版本。");
} else if (behindVersions > 0) {
Main.log("发现新版本! 目前已落后 " + behindVersions + " 个版本。");
Main.log("最新版下载地址 " + downloadURL);
} else {
Main.error("检查更新失败! 当前版本未知,请您使用原生版本以避免安全问题。");
Main.error("最新版下载地址 " + downloadURL);
}
}
}.runTaskAsynchronously(Main.getInstance());
}
}
@@ -1,33 +1,31 @@
package cc.carm.plugin.userprefix.hooker;
import cc.carm.plugin.userprefix.manager.PrefixManager;
import cc.carm.plugin.userprefix.manager.UserManager;
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
import cc.carm.plugin.userprefix.Main;
import cc.carm.plugin.userprefix.UserPrefix;
import cc.carm.plugin.userprefix.configuration.prefix.PrefixConfig;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class UserPrefixExpansion extends PlaceholderExpansion {
JavaPlugin plugin;
protected final @NotNull Main plugin;
protected final @NotNull List<String> placeholders = Arrays.asList(
"%UserPrefix_prefix%", "%UserPrefix_weight%",
"%UserPrefix_identifier%", "%UserPrefix_name%",
"%UserPrefix_has_<Identifier>%"
);
public UserPrefixExpansion(JavaPlugin plugin) {
public UserPrefixExpansion(@NotNull Main plugin) {
this.plugin = plugin;
}
@Override
public @NotNull List<String> getPlaceholders() {
List<String> placeholders = new ArrayList<>();
placeholders.add("%UserPrefix_prefix%");
placeholders.add("%UserPrefix_weight%");
placeholders.add("%UserPrefix_identifier%");
placeholders.add("%UserPrefix_name%");
placeholders.add("%UserPrefix_has_<Identifier>%");
return placeholders;
return this.placeholders;
}
@Override
@@ -62,25 +60,25 @@ public class UserPrefixExpansion extends PlaceholderExpansion {
switch (args[0].toLowerCase()) {
case "identifier": {
return UserManager.getPrefix(player).getIdentifier();
return UserPrefix.getUserManager().getPrefix(player).getIdentifier();
}
case "prefix": {
return UserManager.getPrefix(player).getContent();
return UserPrefix.getUserManager().getPrefix(player).getContent();
}
case "name": {
return UserManager.getPrefix(player).getName();
return UserPrefix.getUserManager().getPrefix(player).getName();
}
case "weight": {
return Integer.toString(UserManager.getPrefix(player).getWeight());
return Integer.toString(UserPrefix.getUserManager().getPrefix(player).getWeight());
}
case "has": {
if (args.length < 2) return "参数不足";
ConfiguredPrefix prefix = PrefixManager.getPrefix(args[1]);
PrefixConfig prefix = UserPrefix.getPrefixManager().getPrefix(args[1]);
if (prefix == null) return "该前缀不存在";
return Boolean.toString(UserManager.isPrefixUsable(player, prefix));
return Boolean.toString(prefix.checkPermission(player));
}
case "version": {
return getVersion().replace("-SNAPSHOT", "");
return getVersion();
}
default: {
return "参数错误";
@@ -1,8 +1,8 @@
package cc.carm.plugin.userprefix.listener;
import cc.carm.lib.easyplugin.utils.MessageUtils;
import cc.carm.plugin.userprefix.Main;
import cc.carm.plugin.userprefix.configuration.PluginConfig;
import cc.carm.plugin.userprefix.util.MessageUtil;
import me.clip.placeholderapi.PlaceholderAPI;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -10,23 +10,22 @@ import org.bukkit.event.player.AsyncPlayerChatEvent;
public class ChatListener implements Listener {
@EventHandler
public void onChat(AsyncPlayerChatEvent event) {
if (!PluginConfig.Functions.Chat.ENABLE.get()) return;
String format = PluginConfig.Functions.Chat.FORMAT.get();
if (format == null || format.length() < 1) return;
@EventHandler
public void onChat(AsyncPlayerChatEvent event) {
if (!PluginConfig.FUNCTIONS.CHAT.ENABLE.getNotNull()) return;
if (!MessageUtil.hasPlaceholderAPI()) return;
String format = PluginConfig.FUNCTIONS.CHAT.FORMAT.get();
if (format == null || format.length() < 1) return;
try {
event.setFormat(PlaceholderAPI.setPlaceholders(event.getPlayer(), format));
} catch (Exception exception) {
Main.error("请检查配置文件中聊天相关是否配置正确。");
Main.error("Please check the chat configuration.");
exception.printStackTrace();
}
try {
event.setFormat(MessageUtils.setPlaceholders(event.getPlayer(), format));
} catch (Exception exception) {
Main.serve("请检查配置文件中聊天相关是否配置正确。");
Main.serve("Please check the chat configuration.");
exception.printStackTrace();
}
}
}
}
@@ -1,6 +1,6 @@
package cc.carm.plugin.userprefix.listener;
import cc.carm.plugin.userprefix.manager.UserManager;
import cc.carm.plugin.userprefix.UserPrefix;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
@@ -8,17 +8,14 @@ import org.bukkit.event.player.PlayerQuitEvent;
public class UserListener implements Listener {
@EventHandler
public void onJoin(PlayerJoinEvent event) {
UserManager.initPlayer(event.getPlayer());
UserPrefix.getUserManager().initPlayer(event.getPlayer());
}
@EventHandler
public void onLeave(PlayerQuitEvent event) {
UserManager.unloadPlayer(event.getPlayer());
UserPrefix.getUserManager().unloadPlayer(event.getPlayer());
}
}
@@ -1,28 +1,24 @@
package cc.carm.plugin.userprefix.listener.processor;
import cc.carm.plugin.userprefix.Main;
import cc.carm.plugin.userprefix.manager.UserManager;
import cc.carm.plugin.userprefix.UserPrefix;
import cc.carm.plugin.userprefix.ui.PrefixSelectGUI;
import net.luckperms.api.event.user.UserDataRecalculateEvent;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
public class UserNodeUpdateProcessor {
public static void process(UserDataRecalculateEvent event) {
Player player = Bukkit.getPlayer(event.getUser().getUniqueId());
if (player == null) return;
UserManager.checkPrefix(player, true);
UserPrefix.getUserManager().checkPrefix(player, true);
if (PrefixSelectGUI.openingUsers.contains(player)) {
new BukkitRunnable() {
@Override
public void run() {
// 玩家权限更新,同步关闭其GUI,以令其重新打开刷新自己的前缀。
player.closeInventory();
PrefixSelectGUI.removeOpening(player);
}
}.runTask(Main.getInstance());
Main.getInstance().getScheduler().run(() -> {
// 玩家权限更新,同步关闭其GUI,以令其重新打开刷新自己的前缀。
player.closeInventory();
PrefixSelectGUI.removeOpening(player);
});
}
}
@@ -1,48 +1,51 @@
package cc.carm.plugin.userprefix.manager;
import cc.carm.plugin.userprefix.Main;
import cc.carm.plugin.userprefix.configuration.file.FileConfig;
import cc.carm.lib.configuration.core.source.ConfigurationProvider;
import cc.carm.lib.easyplugin.utils.JarResourceUtils;
import cc.carm.lib.mineconfiguration.bukkit.MineConfiguration;
import cc.carm.plugin.userprefix.configuration.PluginConfig;
import cc.carm.plugin.userprefix.configuration.PluginMessages;
import java.io.File;
import java.io.IOException;
public class ConfigManager {
private static FileConfig config;
private static FileConfig messageConfig;
private final ConfigurationProvider<?> configProvider;
private final ConfigurationProvider<?> messageProvider;
public ConfigManager(File dataFolder) {
firstInitialize(dataFolder);
this.configProvider = MineConfiguration.from(new File(dataFolder, "config.yml"));
this.messageProvider = MineConfiguration.from(new File(dataFolder, "messages.yml"));
this.configProvider.initialize(PluginConfig.class);
this.messageProvider.initialize(PluginMessages.class);
}
public static void initConfig() {
File configFile = new File(Main.getInstance().getDataFolder(), "config.yml");
protected void firstInitialize(File dataFolder) {
File configFile = new File(dataFolder, "config.yml");
if (!configFile.exists()) {
//没找到配置文件,可能是第一次加载此插件
//把一些英文版的东西复制出来,方便英文用户使用。
Main.getInstance().saveResource("prefixes/example-prefix.yml", false);
Main.getInstance().saveResource("en_US/config.yml", false);
Main.getInstance().saveResource("en_US/messages.yml", false);
Main.getInstance().saveResource("en_US/example-prefix.yml", false);
try {
JarResourceUtils.copyFolderFromJar("en_US", dataFolder, JarResourceUtils.CopyOption.COPY_IF_NOT_EXIST);
JarResourceUtils.copyFolderFromJar("prefixes", dataFolder, JarResourceUtils.CopyOption.COPY_IF_NOT_EXIST);
} catch (IOException e) {
e.printStackTrace();
}
}
ConfigManager.config = new FileConfig(Main.getInstance(), "config.yml");
ConfigManager.messageConfig = new FileConfig(Main.getInstance(), "messages.yml");
}
public static FileConfig getPluginConfig() {
return config;
public ConfigurationProvider<?> getConfigProvider() {
return configProvider;
}
public static FileConfig getMessageConfig() {
return messageConfig;
public ConfigurationProvider<?> getMessageProvider() {
return messageProvider;
}
public static void reload() {
getPluginConfig().reload();
getMessageConfig().reload();
public void reload() throws Exception {
getConfigProvider().reload();
getMessageProvider().reload();
}
public static void saveConfig() {
getPluginConfig().save();
getMessageConfig().save();
}
}
@@ -1,171 +1,155 @@
package cc.carm.plugin.userprefix.manager;
import cc.carm.lib.mineconfiguration.bukkit.data.ItemConfig;
import cc.carm.lib.mineconfiguration.bukkit.source.CraftSectionWrapper;
import cc.carm.plugin.userprefix.Main;
import cc.carm.plugin.userprefix.configuration.PluginConfig;
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
import cc.carm.plugin.userprefix.util.ItemStackFactory;
import cc.carm.plugin.userprefix.configuration.prefix.PrefixConfig;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
public class PrefixManager {
public static ConfiguredPrefix defaultPrefix;
public static HashMap<String, ConfiguredPrefix> prefixes = new HashMap<>();
protected static final String FOLDER_NAME = "prefixes";
private static final String FOLDER_NAME = "prefixes";
protected @NotNull Map<String, PrefixConfig> prefixes = new HashMap<>();
protected PrefixConfig defaultPrefix;
public static void init() {
loadPrefixes();
Main.log("共加载了 " + prefixes.size() + " 个前缀。");
}
public int loadPrefixes() {
loadDefaultPrefix();
loadConfiguredPrefixes();
return prefixes.size();
}
public static void loadPrefixes() {
loadDefaultPrefix();
loadConfiguredPrefixes();
}
@SuppressWarnings("ResultOfMethodCallIgnored")
public void loadConfiguredPrefixes() {
@SuppressWarnings("ResultOfMethodCallIgnored")
public static void loadConfiguredPrefixes() {
File prefixDataFolder = getStorageFolder();
if (!prefixDataFolder.isDirectory() || !prefixDataFolder.exists()) {
prefixDataFolder.mkdir();
}
File prefixDataFolder = getStorageFolder();
if (!prefixDataFolder.isDirectory() || !prefixDataFolder.exists()) {
prefixDataFolder.mkdir();
}
String[] filesList = prefixDataFolder.list();
if (filesList == null || filesList.length < 1) {
Main.serve("配置文件夹中暂无任何前缀配置问,请检查。");
Main.serve("There's no configured prefix.");
Main.serve("Path: " + prefixDataFolder.getAbsolutePath());
return;
}
String[] filesList = prefixDataFolder.list();
if (filesList == null || filesList.length < 1) {
Main.error("配置文件夹中暂无任何前缀配置问,请检查。");
Main.error("There's no configured prefix.");
Main.error("Path: " + prefixDataFolder.getAbsolutePath());
return;
}
List<File> files = Arrays.stream(filesList)
.map(s -> new File(prefixDataFolder, s))
.filter(File::isFile)
.collect(Collectors.toList());
List<File> files = Arrays.stream(filesList)
.map(s -> new File(prefixDataFolder, s))
.filter(File::isFile)
.collect(Collectors.toList());
HashMap<String, PrefixConfig> loaded = new HashMap<>();
HashMap<String, ConfiguredPrefix> dataPrefixes = new HashMap<>();
if (files.size() > 0) {
for (File file : files) {
try {
PrefixConfig prefix = adPrefix(file);
Main.debugging("完成前缀加载 " + prefix.getIdentifier() + " : " + prefix.getName());
loaded.put(prefix.getIdentifier(), prefix);
} catch (Exception ex) {
Main.serve("在加载前缀 " + file.getAbsolutePath() + " 时出错,请检查配置!");
Main.serve("Error occurred when loading prefix #" + file.getAbsolutePath() + " !");
ex.printStackTrace();
}
}
}
if (files.size() > 0) {
for (File file : files) {
try {
ConfiguredPrefix prefix = new ConfiguredPrefix(file);
Main.log("完成前缀加载 " + prefix.getIdentifier() + " : " + prefix.getName());
Main.log("Successfully loaded " + prefix.getIdentifier() + " : " + prefix.getName());
dataPrefixes.put(prefix.getIdentifier(), prefix);
} catch (Exception ex) {
Main.error("在加载前缀 " + file.getAbsolutePath() + " 时出错,请检查配置!");
Main.error("Error occurred when loading prefix #" + file.getAbsolutePath() + " !");
ex.printStackTrace();
}
}
}
this.prefixes = loaded;
}
PrefixManager.prefixes.clear();
PrefixManager.prefixes = dataPrefixes;
}
public void loadDefaultPrefix() {
this.defaultPrefix = new PrefixConfig(
"default",
PluginConfig.DEFAULT_PREFIX.NAME.getNotNull(),
PluginConfig.DEFAULT_PREFIX.CONTENT.getNotNull(),
PluginConfig.DEFAULT_PREFIX.WEIGHT.getNotNull(),
null,
PluginConfig.DEFAULT_PREFIX.ITEM_NOT_USING.getNotNull(),
null,
PluginConfig.DEFAULT_PREFIX.ITEM_USING.get()
);
Main.debugging(" 完成默认前缀加载 " + defaultPrefix.getName());
}
public static void loadDefaultPrefix() {
PrefixManager.defaultPrefix = null;
ConfigurationSection defaultPrefixSection = ConfigManager.getPluginConfig()
.getConfig().getConfigurationSection("defaultPrefix");
if (defaultPrefixSection != null) {
try {
String name = defaultPrefixSection.getString("name", "默认前缀");
String content = defaultPrefixSection.getString("content", "&r");
ItemStack itemNotUsing = defaultPrefixSection.getItemStack(
"itemNotUsing",
new ItemStackFactory(Material.NAME_TAG)
.setDisplayName("&f默认前缀")
.addLore(" ")
.addLore("§a➥ 点击切换到该前缀")
.toItemStack()
);
ItemStack itemUsing = defaultPrefixSection.getItemStack("itemUsing",
new ItemStackFactory(Material.NAME_TAG)
.setDisplayName("&f默认前缀")
.addLore(" ")
.addLore("§a✔ 您正在使用该前缀")
.addEnchant(Enchantment.DURABILITY, 1, false)
.addFlag(ItemFlag.HIDE_ENCHANTS)
.toItemStack()
);
PrefixManager.defaultPrefix = new ConfiguredPrefix("default", name, content, 0, null, itemNotUsing, null, itemUsing);
} catch (Exception ex) {
Main.error("在加载默认前缀时出错,请检查配置!");
Main.error("Error occurred when loading default prefix, please check the configuration.");
ex.printStackTrace();
}
} else {
PrefixManager.defaultPrefix = new ConfiguredPrefix("default", "默认前缀", "&r", 0, null,
new ItemStackFactory(Material.NAME_TAG)
.setDisplayName("&f默认前缀")
.addLore(" ")
.addLore("§a➥ 点击切换到该前缀")
.toItemStack(),
null,
new ItemStackFactory(Material.NAME_TAG)
.setDisplayName("&f默认前缀")
.addLore(" ")
.addLore("§a✔ 您正在使用该前缀")
.addEnchant(Enchantment.DURABILITY, 1, false)
.addFlag(ItemFlag.HIDE_ENCHANTS)
.toItemStack()
);
}
public List<PrefixConfig> getVisiblePrefix(Player player) {
return getPrefixes().values().stream()
.filter(c -> c.isVisible(player))
.sorted(Comparator.comparingInt(PrefixConfig::getWeight))
.collect(Collectors.toList());
}
Main.log("完成默认前缀加载 " + defaultPrefix.getName());
Main.log("Successfully loaded default prefix " + defaultPrefix.getName());
}
@NotNull
public PrefixConfig getDefaultPrefix() {
return defaultPrefix;
}
public static List<ConfiguredPrefix> getVisiblePrefix() {
return PrefixManager.getPrefixes().values().stream()
.filter(ConfiguredPrefix::isVisibleNoPermission)
.sorted(Comparator.comparingInt(ConfiguredPrefix::getWeight))
.collect(Collectors.toList());
}
@NotNull
public Map<String, PrefixConfig> getPrefixes() {
return prefixes;
}
@NotNull
public static ConfiguredPrefix getDefaultPrefix() {
return defaultPrefix;
}
@Nullable
public PrefixConfig getPrefix(String identifier) {
if (identifier == null) {
return null;
} else if (identifier.equalsIgnoreCase("default")) {
return getDefaultPrefix();
} else {
return getPrefixes().get(identifier);
}
}
@NotNull
public static HashMap<String, ConfiguredPrefix> getPrefixes() {
return prefixes;
}
@Nullable
public static ConfiguredPrefix getPrefix(String identifier) {
if (identifier == null) {
return null;
} else if (identifier.equalsIgnoreCase("default")) {
return getDefaultPrefix();
} else {
return getPrefixes().get(identifier);
}
}
protected File getStorageFolder() {
if (PluginConfig.CUSTOM_STORAGE.ENABLE.getNotNull()) {
return new File(PluginConfig.CUSTOM_STORAGE.PATH.getNotNull());
} else {
return new File(Main.getInstance().getDataFolder() + File.separator + FOLDER_NAME);
}
}
private static File getStorageFolder() {
if (PluginConfig.CustomStorage.ENABLE.get()) {
return new File(PluginConfig.CustomStorage.PATH.get());
} else {
return new File(Main.getInstance().getDataFolder() + File.separator + FOLDER_NAME);
}
}
public static @NotNull PrefixConfig adPrefix(@NotNull File file) throws Exception {
FileConfiguration configuration = YamlConfiguration.loadConfiguration(file);
String identifier = configuration.getString("identifier");
if (identifier == null) throw new Exception("配置文件 " + file.getAbsolutePath() + " 中没有配置前缀的唯一标识。");
String name = configuration.getString("name");
if (name == null) throw new Exception("配置文件 " + file.getAbsolutePath() + " 中没有配置前缀的显示名称。");
return new PrefixConfig(
identifier, name,
configuration.getString("content", "&r"),
configuration.getInt("weight", 1),
configuration.getString("permission"),
readItem(
configuration.getConfigurationSection("itemHasPermission"),
new ItemConfig(Material.STONE, (short) 0, name, Arrays.asList(" ", "§a➥ 点击切换到该前缀"))
),
readItem(configuration.getConfigurationSection("itemNoPermission"), null),
readItem(configuration.getConfigurationSection("itemUsing"), null)
);
}
@Contract("_,!null->!null")
protected static ItemConfig readItem(@Nullable ConfigurationSection section, @Nullable ItemConfig defaultValue) throws Exception {
if (section == null) return defaultValue;
else return ItemConfig.deserialize(CraftSectionWrapper.of(section));
}
}
@@ -42,4 +42,8 @@ public class ServiceManager {
return user.getCachedData().getPermissionData().checkPermission(permission).asBoolean();
}
public static boolean hasPermission(Player player, String permission) {
return hasPermission(getUser(player), permission);
}
}
@@ -1,13 +1,15 @@
package cc.carm.plugin.userprefix.manager;
import cc.carm.lib.easyplugin.gui.GUI;
import cc.carm.plugin.userprefix.Main;
import cc.carm.plugin.userprefix.UserPrefix;
import cc.carm.plugin.userprefix.configuration.PluginConfig;
import cc.carm.plugin.userprefix.configuration.PluginMessages;
import cc.carm.plugin.userprefix.configuration.prefix.PrefixConfig;
import cc.carm.plugin.userprefix.event.UserPrefixChangeEvent;
import cc.carm.plugin.userprefix.event.UserPrefixExpireEvent;
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
import cc.carm.plugin.userprefix.nametag.UserNameTag;
import cc.carm.plugin.userprefix.ui.PrefixSelectGUI;
import cc.carm.plugin.userprefix.util.gui.GUI;
import net.luckperms.api.model.user.User;
import net.luckperms.api.node.NodeType;
import net.luckperms.api.node.types.MetaNode;
@@ -21,13 +23,16 @@ import java.util.stream.Collectors;
public class UserManager {
public static HashMap<UUID, UserNameTag> nameTags = new HashMap<>();
// LuckPerms竟然会把所有的metaKey全部转换为小写... 那我这里就直接写成小写吧~
public static final @NotNull String META_KEY = "userprefix";
public static HashSet<UUID> checkingPlayers = new HashSet<>();
protected final HashMap<UUID, UserNameTag> nameTags = new HashMap<>();
protected final HashSet<UUID> checkingPlayers = new HashSet<>();
@Nullable
public static UserNameTag getNameTag(Player player) {
if (PluginConfig.Functions.NAME_PREFIX.get()) {
public UserNameTag getNameTag(Player player) {
if (PluginConfig.FUNCTIONS.NAME_PREFIX.ENABLE.getNotNull()) {
if (nameTags.containsKey(player.getUniqueId())) {
return nameTags.get(player.getUniqueId());
} else {
@@ -39,25 +44,25 @@ public class UserManager {
}
@NotNull
public static UserNameTag createNameTag(Player player) {
public UserNameTag createNameTag(Player player) {
if (nameTags.containsKey(player.getUniqueId())) return nameTags.get(player.getUniqueId());
UserNameTag nameTag = new UserNameTag(player);
nameTags.put(player.getUniqueId(), nameTag);
return nameTag;
}
public static void initPlayer(Player player) {
UserManager.checkPrefix(player, false);
if (PluginConfig.Functions.NAME_PREFIX.get()) {
UserManager.createNameTag(player);
UserManager.updatePrefixView(player, true);
public void initPlayer(Player player) {
checkPrefix(player, false);
if (PluginConfig.FUNCTIONS.NAME_PREFIX.ENABLE.getNotNull()) {
createNameTag(player);
updatePrefixView(player, true);
}
}
public static void unloadPlayer(Player player) {
public void unloadPlayer(Player player) {
PrefixSelectGUI.removeOpening(player);
UserManager.unloadNameTag(player.getUniqueId());
UserManager.checkingPlayers.remove(player.getUniqueId());
unloadNameTag(player.getUniqueId());
checkingPlayers.remove(player.getUniqueId());
GUI.removeOpenedGUI(player); // 清空打开过的GUI缓存 (用于记录物品点击的
}
@@ -67,18 +72,18 @@ public class UserManager {
* @param player 玩家
* @param loadOthers 是否为玩家更新其他人的前缀(一般用于加入游戏)
*/
public static void updatePrefixView(Player player, boolean loadOthers) {
if (!PluginConfig.Functions.NAME_PREFIX.get()) return; //未启用的情况下,不需要进行任何操作。
public void updatePrefixView(Player player, boolean loadOthers) {
if (!PluginConfig.FUNCTIONS.NAME_PREFIX.ENABLE.getNotNull()) return; //未启用的情况下,不需要进行任何操作。
UserNameTag tag = getNameTag(player);
if (tag == null) return; //未启用的情况下,不需要进行任何操作。
ConfiguredPrefix playerPrefix = UserManager.getPrefix(player);
boolean descOrder = PluginConfig.Functions.NAME_ORDER_DESC.get();
PrefixConfig playerPrefix = getPrefix(player);
boolean descOrder = PluginConfig.FUNCTIONS.NAME_PREFIX.ORDER_DESC.getNotNull();
tag.setPrefix(playerPrefix.getContent());
tag.setOrder(descOrder ? 999 - playerPrefix.getWeight() : playerPrefix.getWeight());
Main.debug("为玩家 " + player.getName() + " 设置了 " + player.getName() + "的前缀为 #" + playerPrefix.getWeight() + " " + playerPrefix.getName());
Main.debugging("为玩家 " + player.getName() + " 设置了 " + player.getName() + "的前缀为 #" + playerPrefix.getWeight() + " " + playerPrefix.getName());
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
if (onlinePlayer.equals(player)) continue;
@@ -87,15 +92,15 @@ public class UserManager {
if (onlinePlayerTag != null) {
onlinePlayerTag.setPrefix(player, playerPrefix.getContent());
onlinePlayerTag.setOrder(player, descOrder ? 999 - playerPrefix.getWeight() : playerPrefix.getWeight());
Main.debug("为玩家 " + onlinePlayer.getName() + " 设置了 " + player.getName() + "的前缀为 #" + playerPrefix.getWeight() + " " + playerPrefix.getName());
Main.debugging("为玩家 " + onlinePlayer.getName() + " 设置了 " + player.getName() + "的前缀为 #" + playerPrefix.getWeight() + " " + playerPrefix.getName());
}
if (loadOthers) {
ConfiguredPrefix onlinePlayerPrefix = UserManager.getPrefix(onlinePlayer);
PrefixConfig onlinePlayerPrefix = getPrefix(onlinePlayer);
tag.setPrefix(onlinePlayer, onlinePlayerPrefix.getContent());
tag.setOrder(onlinePlayer, descOrder ? 999 - onlinePlayerPrefix.getWeight() : onlinePlayerPrefix.getWeight());
Main.debug("为玩家 " + player.getName() + " 设置了 " + onlinePlayer.getName() + "的前缀为 #" + onlinePlayerPrefix.getWeight() + " " + onlinePlayerPrefix.getName());
Main.debugging("为玩家 " + player.getName() + " 设置了 " + onlinePlayer.getName() + "的前缀为 #" + onlinePlayerPrefix.getWeight() + " " + onlinePlayerPrefix.getName());
}
}
}
@@ -106,7 +111,7 @@ public class UserManager {
* @param player 玩家
* @param updateView 是否更新头顶与TabList中的前缀
*/
public static void checkPrefix(Player player, boolean updateView) {
public void checkPrefix(Player player, boolean updateView) {
if (checkingPlayers.contains(player.getUniqueId())) {
/*
* 这里为了避免极短时间内的重复触发导致多次判断且结果相同误导玩家,
@@ -115,35 +120,29 @@ public class UserManager {
return;
}
checkingPlayers.add(player.getUniqueId());
String currentPrefixData = UserManager.getPrefixData(player);
String currentPrefixData = getPrefixData(player);
if (!UserManager.isPrefixUsable(player, currentPrefixData)) {
ConfiguredPrefix currentPrefix = PrefixManager.getPrefix(currentPrefixData);
ConfiguredPrefix newPrefix = UserManager.getHighestPrefix(player);
if (!isPrefixUsable(player, currentPrefixData)) {
PrefixConfig currentPrefix = UserPrefix.getPrefixManager().getPrefix(currentPrefixData);
PrefixConfig newPrefix = getHighestPrefix(player);
if (currentPrefix != null) {
//当前前缀不为空,则代表属于前缀过期的情况
UserPrefixExpireEvent.call(player, currentPrefix);
// 发送消息
PluginConfig.Messages.EXPIRED.sendWithPlaceholders(player,
new String[]{"%(newName)", "%(oldName)"},
new Object[]{newPrefix.getName(), currentPrefix.getName()}
);
PluginMessages.EXPIRED.send(player, newPrefix.getName(), currentPrefix.getName());
// 播放声音
PluginConfig.Sounds.PREFIX_EXPIRED.play(player);
PluginConfig.SOUNDS.PREFIX_EXPIRED.playTo(player);
} else {
// 当前前缀为空,则代表是旧的前缀不存在了,
PluginConfig.Messages.REMOVED.sendWithPlaceholders(player,
new String[]{"%(newName)", "%(oldName)"},
new Object[]{newPrefix.getName(), currentPrefixData}
);
PluginMessages.REMOVED.send(player, newPrefix.getName(), currentPrefixData);
}
UserPrefixChangeEvent.call(player, currentPrefix, newPrefix, (after) -> {
if (after != null) {
UserManager.setPrefix(player, after, updateView);
setPrefix(player, after, updateView);
}
checkingPlayers.remove(player.getUniqueId());
});
@@ -153,7 +152,7 @@ public class UserManager {
}
}
public static void unloadNameTag(UUID uuid) {
public void unloadNameTag(UUID uuid) {
nameTags.remove(uuid);
}
@@ -165,13 +164,13 @@ public class UserManager {
* @return 前缀配置
*/
@NotNull
public static ConfiguredPrefix getPrefix(Player player) {
public PrefixConfig getPrefix(Player player) {
String identifier = getPrefixData(player);
if (identifier == null || !isPrefixUsable(player, identifier)) {
return getHighestPrefix(player);
} else {
ConfiguredPrefix prefix = PrefixManager.getPrefix(identifier);
return prefix == null ? PrefixManager.getDefaultPrefix() : prefix;
PrefixConfig prefix = UserPrefix.getPrefixManager().getPrefix(identifier);
return prefix == null ? UserPrefix.getDefaultPrefix() : prefix;
}
}
@@ -182,7 +181,7 @@ public class UserManager {
* @param prefix 前缀配置
* @param updateView 是否更新头顶上、TabList的前缀
*/
public static void setPrefix(Player player, ConfiguredPrefix prefix, boolean updateView) {
public void setPrefix(Player player, PrefixConfig prefix, boolean updateView) {
setPrefixData(player, prefix.getIdentifier());
if (updateView) updatePrefixView(player, false);
}
@@ -194,10 +193,10 @@ public class UserManager {
* @return 可用前缀列表
*/
@NotNull
public static List<ConfiguredPrefix> getUsablePrefixes(Player player) {
return PrefixManager.getPrefixes().values().stream()
.filter(configuredPrefix -> isPrefixUsable(player, configuredPrefix)) //过滤出玩家可用的前缀
.sorted(Comparator.comparingInt(ConfiguredPrefix::getWeight)) // 以前缀排序
public List<PrefixConfig> getUsablePrefixes(Player player) {
return UserPrefix.getPrefixManager().getPrefixes().values().stream()
.filter(prefix -> prefix.checkPermission(player)) //过滤出玩家可用的前缀
.sorted(Comparator.comparingInt(PrefixConfig::getWeight)) // 以前缀排序
.collect(Collectors.toList()); // 返回集合
}
@@ -210,14 +209,14 @@ public class UserManager {
* @return 权限内容
*/
@NotNull
public static ConfiguredPrefix getHighestPrefix(Player player) {
if (PluginConfig.Functions.AUTO_USE.get()) {
public PrefixConfig getHighestPrefix(Player player) {
if (PluginConfig.FUNCTIONS.AUTO_USE.getNotNull()) {
// 关闭了自动选择,就直接给默认的前缀,让玩家自己去设置吧~
return PrefixManager.getDefaultPrefix();
return UserPrefix.getDefaultPrefix();
}
return getUsablePrefixes(player).stream()
.max(Comparator.comparingInt(ConfiguredPrefix::getWeight)) // 取权重最大
.orElseGet(PrefixManager::getDefaultPrefix); // 啥都没有? 返回默认前缀。
.max(Comparator.comparingInt(PrefixConfig::getWeight)) // 取权重最大
.orElseGet(UserPrefix::getDefaultPrefix); // 啥都没有? 返回默认前缀。
}
/**
@@ -228,24 +227,12 @@ public class UserManager {
* @return 若前缀标识不存在,则返回false;若前缀为默认前缀,或该前缀无权限,或玩家有该前缀的权限,则返回true。
*/
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
public static boolean isPrefixUsable(Player player, String prefixIdentifier) {
public boolean isPrefixUsable(Player player, String prefixIdentifier) {
if (prefixIdentifier == null || prefixIdentifier.equalsIgnoreCase("default")) return true;
ConfiguredPrefix prefix = PrefixManager.getPrefix(prefixIdentifier);
if (prefix == null) return false;
return isPrefixUsable(player, prefix);
PrefixConfig prefix = UserPrefix.getPrefixManager().getPrefix(prefixIdentifier);
return prefix != null && prefix.checkPermission(player);
}
/**
* 判断一个前缀对某玩家是否可用
*
* @param player 玩家
* @param configuredPrefix 前缀配置
* @return 若前缀标识不存在,则返回false;若前缀为默认前缀,或该前缀无权限,或玩家有该前缀的权限,则返回true。
*/
public static boolean isPrefixUsable(Player player, ConfiguredPrefix configuredPrefix) {
return configuredPrefix.isPublic()
|| ServiceManager.hasPermission(ServiceManager.getUser(player), configuredPrefix.getPermission());
}
/**
* 得到用户当前正在使用的前缀Identifier。
@@ -255,9 +242,9 @@ public class UserManager {
* @return 正在使用的前缀Identifier(若不存在则返回null, 代表未设置前缀)
*/
@Nullable
public static String getPrefixData(Player player) {
public String getPrefixData(Player player) {
return ServiceManager.getAPI().getMetaData(player)
.getMetaValue("userprefix", String::valueOf)
.getMetaValue(META_KEY, String::valueOf)
.orElse(null);
}
@@ -268,11 +255,11 @@ public class UserManager {
* @param player 玩家
* @param prefixIdentifier 前缀的标识
*/
public static void setPrefixData(Player player, String prefixIdentifier) {
public void setPrefixData(Player player, String prefixIdentifier) {
User user = ServiceManager.getUser(player);
clearPrefixData(player); // 清除掉旧的数据,LuckPerms不会去覆盖一个Meta,需要手动清除。
if (prefixIdentifier != null) {
user.data().add(MetaNode.builder("userprefix", prefixIdentifier).build());
user.data().add(MetaNode.builder(META_KEY, prefixIdentifier).build());
ServiceManager.getService().getUserManager().saveUser(user); // 保存数据
}
}
@@ -282,11 +269,9 @@ public class UserManager {
*
* @param player 玩家
*/
public static void clearPrefixData(Player player) {
public void clearPrefixData(Player player) {
User user = ServiceManager.getUser(player);
// LuckPerms竟然会把所有的metaKey全部转换为小写... 那我这里就直接写成小写吧~
user.data().clear(NodeType.META.predicate(mn -> mn.getMetaKey().equals("userprefix")));
user.data().clear(NodeType.META.predicate(mn -> mn.getMetaKey().equals(META_KEY)));
}
}
@@ -1,163 +0,0 @@
package cc.carm.plugin.userprefix.model;
import cc.carm.plugin.userprefix.util.ColorParser;
import cc.carm.plugin.userprefix.util.ConfigurationUtil;
import cc.carm.plugin.userprefix.util.ItemStackFactory;
import cc.carm.plugin.userprefix.util.MessageUtil;
import org.bukkit.Material;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.List;
public class ConfiguredPrefix {
@Nullable
private File dataFile;
@Nullable
private FileConfiguration configuration;
String identifier;
String name;
String content;
int weight;
String permission;
ItemStack itemHasPermission;
ItemStack itemNoPermission;
ItemStack itemWhenUsing;
public ConfiguredPrefix(@NotNull File dataFile) {
this.dataFile = dataFile;
try {
this.configuration = ConfigurationUtil.bang(dataFile);
} catch (Exception e) {
e.printStackTrace();
}
if (getConfiguration() != null) {
this.identifier = getConfiguration().getString("identifier", "ERROR");
this.name = getConfiguration().getString("name", "ERROR");
this.content = getConfiguration().getString("content", "&r");
this.permission = getConfiguration().getString("permission");
this.weight = getConfiguration().getInt("weight", 1);
this.itemHasPermission = (ItemStack) getConfiguration().get("itemHasPermission",
new ItemStackFactory(Material.STONE).setDisplayName(name).addLore(" ").addLore("§a➥ 点击切换到该前缀").toItemStack()
);
this.itemNoPermission = (ItemStack) getConfiguration().get("itemNoPermission", itemHasPermission);
this.itemWhenUsing = (ItemStack) getConfiguration().get("itemUsing", itemHasPermission);
}
}
public ConfiguredPrefix(@NotNull String identifier,
@NotNull String name,
@NotNull String content,
int weight, @Nullable String permission,
@NotNull ItemStack itemHasPermission,
@Nullable ItemStack itemNoPermission,
@Nullable ItemStack itemWhenUsing) {
this.identifier = identifier;
this.name = name;
this.content = content;
this.weight = weight;
this.permission = permission;
this.itemHasPermission = itemHasPermission;
this.itemNoPermission = itemNoPermission;
this.itemWhenUsing = itemWhenUsing;
}
@Nullable
public FileConfiguration getConfiguration() {
return configuration;
}
@NotNull
public String getIdentifier() {
return identifier;
}
@NotNull
public String getName() {
return name;
}
@NotNull
public String getContent() {
return ColorParser.parse(content);
}
public int getWeight() {
return weight;
}
@Nullable
public String getPermission() {
return permission;
}
@NotNull
public ItemStack getItemHasPermission(@Nullable Player player) {
return parseItemStackText(this.itemHasPermission, player);
}
@NotNull
public ItemStack getItemHasPermission() {
return getItemHasPermission(null);
}
@Nullable
public ItemStack getItemNoPermission(@Nullable Player player) {
return parseItemStackText(itemNoPermission, player);
}
@Nullable
public ItemStack getItemNoPermission() {
return getItemNoPermission(null);
}
@Nullable
public ItemStack getItemWhenUsing(@Nullable Player player) {
return parseItemStackText(itemWhenUsing, player);
}
@Nullable
public ItemStack getItemWhenUsing() {
return getItemWhenUsing(null);
}
public boolean isPublic() {
return getPermission() == null;
}
public boolean isVisibleNoPermission() {
return this.itemNoPermission != null;
}
@NotNull
private static ItemStack parseItemStackText(@NotNull ItemStack source, @Nullable Player player) {
if (player == null) return source;
ItemMeta meta = source.getItemMeta();
String displayName = null;
List<String> lore = null;
if (meta != null) {
if (meta.hasDisplayName()) displayName = meta.getDisplayName();
if (meta.hasLore()) lore = meta.getLore();
}
ItemStackFactory factory = new ItemStackFactory(source);
if (displayName != null) factory.setDisplayName(MessageUtil.setPlaceholders(player, displayName));
if (lore != null) factory.setLore(MessageUtil.setPlaceholders(player, lore));
return factory.toItemStack();
}
}
@@ -1,13 +1,12 @@
package cc.carm.plugin.userprefix.ui;
import cc.carm.lib.easyplugin.gui.GUIItem;
import cc.carm.lib.easyplugin.gui.GUIType;
import cc.carm.lib.easyplugin.gui.paged.AutoPagedGUI;
import cc.carm.plugin.userprefix.UserPrefix;
import cc.carm.plugin.userprefix.configuration.PluginConfig;
import cc.carm.plugin.userprefix.manager.PrefixManager;
import cc.carm.plugin.userprefix.manager.UserManager;
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
import cc.carm.plugin.userprefix.util.MessageUtil;
import cc.carm.plugin.userprefix.util.gui.AutoPagedGUI;
import cc.carm.plugin.userprefix.util.gui.GUIItem;
import cc.carm.plugin.userprefix.util.gui.GUIType;
import cc.carm.plugin.userprefix.configuration.PluginMessages;
import cc.carm.plugin.userprefix.configuration.prefix.PrefixConfig;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
@@ -17,81 +16,84 @@ import java.util.List;
public class PrefixSelectGUI extends AutoPagedGUI {
public static HashSet<Player> openingUsers = new HashSet<>();
public static HashSet<Player> openingUsers = new HashSet<>();
Player player;
Player player;
public PrefixSelectGUI(Player player) {
super(GUIType.SIXBYNINE, PluginConfig.GUI.TITLE.get(), 10, 43);
this.player = player;
public PrefixSelectGUI(Player player) {
super(GUIType.SIX_BY_NINE, PluginConfig.GUI.TITLE.get(), 10, 43);
this.player = player;
setPreviousPageSlot(18);
setNextPageSlot(26);
setPreviousPageSlot(18);
setNextPageSlot(26);
loadItems();
}
loadBackButton();
loadItems();
}
public Player getPlayer() {
return player;
}
public Player getPlayer() {
return player;
}
public void loadItems() {
List<ConfiguredPrefix> prefixList = new ArrayList<>();
prefixList.add(PrefixManager.getDefaultPrefix());
prefixList.addAll(PrefixManager.getVisiblePrefix()); //只需要读取看得见的
public void loadBackButton() {
PluginConfig.GUI.ITEMS.BACK.getOptional().ifPresent(item -> item.setupItems(player, this));
}
ConfiguredPrefix usingPrefix = UserManager.getPrefix(getPlayer());
public void loadItems() {
List<PrefixConfig> prefixList = new ArrayList<>();
prefixList.add(UserPrefix.getPrefixManager().getDefaultPrefix());
prefixList.addAll(UserPrefix.getPrefixManager().getVisiblePrefix(player)); //只需要读取看得见的
for (ConfiguredPrefix prefix : prefixList) {
if (prefix.getIdentifier().equals(usingPrefix.getIdentifier())) {
addItem(new GUIItem(prefix.getItemWhenUsing(player) != null ? prefix.getItemWhenUsing(player) : prefix.getItemHasPermission(player)));
} else if (UserManager.isPrefixUsable(player, prefix)) {
addItem(new GUIItem(prefix.getItemHasPermission(player)) {
@Override
public void onClick(ClickType type) {
//再次检查,防止打开GUI后、选择前的时间段内权限消失
if (UserManager.isPrefixUsable(player, prefix)) {
player.closeInventory();
UserManager.setPrefix(player, prefix, true);
PrefixConfig usingPrefix = UserPrefix.getUserManager().getPrefix(getPlayer());
PluginConfig.Sounds.PREFIX_CHANGE.play(player);
MessageUtil.sendWithPlaceholders(player, PluginConfig.Messages.SELECTED.get(),
new String[]{"%(name)"},
new Object[]{prefix.getName()});
for (PrefixConfig prefix : prefixList) {
if (prefix.getIdentifier().equals(usingPrefix.getIdentifier())) {
addItem(new GUIItem(prefix.getItemWhenUsing(player) != null ? prefix.getItemWhenUsing(player) : prefix.getItemHasPermission(player)));
} else if (prefix.checkPermission(player)) {
addItem(new GUIItem(prefix.getItemHasPermission(player)) {
@Override
public void onClick(ClickType type) {
//再次检查,防止打开GUI后、选择前的时间段内权限消失
if (prefix.checkPermission(player)) {
player.closeInventory();
UserPrefix.getUserManager().setPrefix(player, prefix, true);
}
}
});
} else {
addItem(new GUIItem(prefix.getItemNoPermission(player)));
}
}
PluginConfig.SOUNDS.PREFIX_CHANGE.playTo(player);
PluginMessages.SELECTED.send(player, prefix.getName());
}
}
});
} else {
addItem(new GUIItem(prefix.getItemNoPermission(player)));
}
}
}
}
@Override
public void onClose() {
removeOpening(player);
}
@Override
public void onClose() {
removeOpening(player);
}
public static void removeOpening(Player player) {
openingUsers.remove(player);
}
public static void removeOpening(Player player) {
openingUsers.remove(player);
}
public static void closeAll() {
for (Player player : new HashSet<>(openingUsers)) {
player.closeInventory();
}
openingUsers.clear();
}
public static void closeAll() {
for (Player player : new HashSet<>(openingUsers)) {
player.closeInventory();
}
openingUsers.clear();
}
public static void open(Player player) {
player.closeInventory(); // 防止冲突
PluginConfig.Sounds.GUI_OPEN.play(player);
new PrefixSelectGUI(player).openGUI(player);
openingUsers.add(player);
}
public static void open(Player player) {
player.closeInventory(); // 防止冲突
PluginConfig.SOUNDS.GUI_OPEN.playTo(player);
new PrefixSelectGUI(player).openGUI(player);
openingUsers.add(player);
}
}
@@ -1,33 +0,0 @@
package cc.carm.plugin.userprefix.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ColorParser {
public static String parse(String text) {
text = parseHexColor(text);
return parseColor(text);
}
public static String parseColor(final String text) {
return text.replaceAll("&", "§").replace("§§", "&");
}
public static String parseHexColor(String text) {
Pattern pattern = Pattern.compile("&\\((&?#[0-9a-fA-F]{6})\\)");
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
String hexColor = text.substring(matcher.start() + 2, matcher.end() - 1);
hexColor = hexColor.replace("&", "");
StringBuilder bukkitColorCode = new StringBuilder('§' + "x");
for (int i = 1; i < hexColor.length(); i++) {
bukkitColorCode.append('§').append(hexColor.charAt(i));
}
text = text.replaceAll("&\\(" + hexColor + "\\)", bukkitColorCode.toString().toLowerCase());
matcher.reset(text);
}
return text;
}
}
@@ -1,38 +0,0 @@
package cc.carm.plugin.userprefix.util;
import cc.carm.plugin.userprefix.wrapper.ItemStackWrapper;
import com.google.common.io.Files;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.inventory.ItemStack;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.StringJoiner;
public class ConfigurationUtil {
public static FileConfiguration bang(File file) {
YamlConfiguration conf = new YamlConfiguration();
StringJoiner builder = new StringJoiner("\n");
try {
//noinspection UnstableApiUsage
Files.readLines(file, StandardCharsets.UTF_8).forEach(builder::add);
} catch (IOException e) {
e.printStackTrace();
return conf;
}
String tmpConf = builder.toString().replace("==: "+ ItemStack.class.getName(), "==: "+ ItemStackWrapper.class.getName());
try {
conf.loadFromString(tmpConf);
} catch (InvalidConfigurationException e) {
e.printStackTrace();
}
return conf;
}
public static String dong(FileConfiguration conf) {
return conf.saveToString().replace("==: "+ ItemStackWrapper.class.getName(),"==: "+ ItemStack.class.getName());
}
}
@@ -1,139 +0,0 @@
package cc.carm.plugin.userprefix.util;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class ItemStackFactory {
ItemStack item;
private ItemStackFactory() {
}
public ItemStackFactory(ItemStack is) {
this.item = is.clone();
}
public ItemStackFactory(Material type) {
this(type, 1);
}
public ItemStackFactory(Material type, int amount) {
this(type, amount, (short) 0);
}
public ItemStackFactory(Material type, int amount, short data) {
this.item = new ItemStack(type, amount, data);
}
public ItemStackFactory(Material type, int amount, int data) {
this(type, amount, (short) data);
}
public ItemStack toItemStack() {
return this.item;
}
public ItemStackFactory setType(Material type) {
this.item.setType(type);
return this;
}
public ItemStackFactory setDurability(int i) {
this.item.setDurability((short) i);
return this;
}
public ItemStackFactory setAmount(int a) {
this.item.setAmount(a);
return this;
}
public ItemStackFactory setDisplayName(@NotNull String name) {
ItemMeta im = this.item.getItemMeta();
if (im != null) {
im.setDisplayName(ColorParser.parse(name));
this.item.setItemMeta(im);
}
return this;
}
public ItemStackFactory setLore(@NotNull List<String> loreList) {
ItemMeta im = this.item.getItemMeta();
if (im != null) {
im.setLore(
loreList.stream()
.map(ColorParser::parse)
.collect(Collectors.toList())
);
this.item.setItemMeta(im);
}
return this;
}
public ItemStackFactory addLore(@NotNull String s) {
ItemMeta im = this.item.getItemMeta();
if (im != null) {
List<String> lore = im.getLore() != null ? im.getLore() : new ArrayList<>();
lore.add(ColorParser.parse(s));
im.setLore(lore);
this.item.setItemMeta(im);
}
return this;
}
public ItemStackFactory addEnchant(@NotNull Enchantment enchant, int level, boolean ignoreLevelRestriction) {
ItemMeta im = this.item.getItemMeta();
if (im != null) {
im.addEnchant(enchant, level, ignoreLevelRestriction);
this.item.setItemMeta(im);
}
return this;
}
public ItemStackFactory removeEnchant(@NotNull Enchantment enchant) {
ItemMeta im = this.item.getItemMeta();
if (im != null) {
im.removeEnchant(enchant);
this.item.setItemMeta(im);
}
return this;
}
public ItemStackFactory addFlag(@NotNull ItemFlag flag) {
ItemMeta im = this.item.getItemMeta();
if (im != null) {
im.addItemFlags(flag);
this.item.setItemMeta(im);
}
return this;
}
public ItemStackFactory removeFlag(@NotNull ItemFlag flag) {
ItemMeta im = this.item.getItemMeta();
if (im != null) {
im.removeItemFlags(flag);
this.item.setItemMeta(im);
}
return this;
}
public ItemStackFactory setUnbreakable(boolean unbreakable) {
ItemMeta im = this.item.getItemMeta();
if (im != null) {
im.setUnbreakable(unbreakable);
this.item.setItemMeta(im);
}
return this;
}
}
@@ -1,102 +0,0 @@
package cc.carm.plugin.userprefix.util;
import me.clip.placeholderapi.PlaceholderAPI;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.stream.Collectors;
public class MessageUtil {
public static boolean hasPlaceholderAPI() {
return Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null;
}
public static void send(@Nullable CommandSender sender, List<String> messages) {
if (messages == null || messages.isEmpty() || sender == null) return;
for (String s : messages) {
sender.sendMessage(ColorParser.parse(s));
}
}
public static void send(@Nullable CommandSender sender, String... messages) {
send(sender, Arrays.asList(messages));
}
public static void sendWithPlaceholders(CommandSender sender, String... messages) {
sendWithPlaceholders(sender, Arrays.asList(messages));
}
public static void sendWithPlaceholders(@Nullable CommandSender sender, List<String> messages) {
if (messages == null || messages.isEmpty() || sender == null) return;
send(sender, setPlaceholders(sender, messages));
}
public static void sendWithPlaceholders(@Nullable CommandSender sender, List<String> messages, String param, Object value) {
sendWithPlaceholders(sender, messages, new String[]{param}, new Object[]{value});
}
public static void sendWithPlaceholders(@Nullable CommandSender sender, List<String> messages, String[] params, Object[] values) {
sendWithPlaceholders(sender, setCustomParams(messages, params, values));
}
public static String setPlaceholders(@Nullable CommandSender sender, String message) {
if (message == null) return null;
message = ColorParser.parse(message);
if (sender == null) return message;
if (hasPlaceholderAPI() && sender instanceof Player) {
return PlaceholderAPI.setPlaceholders((Player) sender, message);
} else {
return message;
}
}
public static List<String> setPlaceholders(@Nullable CommandSender sender, List<String> messages) {
if (messages == null || messages.isEmpty()) return new ArrayList<>();
messages = messages.stream().map(ColorParser::parse).collect(Collectors.toList());
if (sender == null) return messages;
if (hasPlaceholderAPI() && sender instanceof Player) {
return PlaceholderAPI.setPlaceholders((Player) sender, messages);
} else {
return messages;
}
}
public static List<String> setPlaceholders(@Nullable CommandSender sender, List<String> messages, String[] params, Object[] values) {
return setPlaceholders(sender, setCustomParams(messages, params, values));
}
public static List<String> setCustomParams(List<String> messages, String param, Object value) {
return setCustomParams(messages, new String[]{param}, new Object[]{value});
}
public static List<String> setCustomParams(List<String> messages, String[] params, Object[] values) {
if (params.length != values.length) return messages;
HashMap<String, Object> paramsMap = new HashMap<>();
for (int i = 0; i < params.length; i++) {
paramsMap.put(params[i], values[i]);
}
return setCustomParams(messages, paramsMap);
}
public static List<String> setCustomParams(List<String> messages, HashMap<String, Object> params) {
List<String> list = new ArrayList<>();
for (String message : messages) {
String afterMessage = message;
for (Map.Entry<String, Object> entry : params.entrySet()) {
afterMessage = afterMessage.replace(entry.getKey(), entry.getValue().toString());
}
list.add(afterMessage);
}
return list;
}
}
@@ -1,93 +0,0 @@
package cc.carm.plugin.userprefix.util.gui;
import cc.carm.plugin.userprefix.configuration.PluginConfig;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
public class AutoPagedGUI extends CommonPagedGUI {
ItemStack previousPageUI;
ItemStack nextPageUI;
ItemStack noPreviousPageUI;
ItemStack noNextPageUI;
int previousPageSlot = -1;
int nextPageSlot = -1;
public AutoPagedGUI(GUIType type, String name, int[] range) {
super(type, name, range);
}
public AutoPagedGUI(GUIType type, String name, int a, int b) {
super(type, name, a, b);
}
public void setPreviousPageUI(ItemStack lastPageUI) {
this.previousPageUI = lastPageUI;
}
public void setNextPageUI(ItemStack nextPageUI) {
this.nextPageUI = nextPageUI;
}
public void setNoPreviousPageUI(ItemStack noPreviousPageUI) {
this.noPreviousPageUI = noPreviousPageUI;
}
public void setNoNextPageUI(ItemStack noNextPageUI) {
this.noNextPageUI = noNextPageUI;
}
public void setPreviousPageSlot(int slot) {
this.previousPageSlot = slot;
}
public void setNextPageSlot(int slot) {
this.nextPageSlot = slot;
}
@Override
public void openGUI(Player user) {
if (previousPageSlot >= 0) {
if (hasPreviousPage()) {
setItem(previousPageSlot, new GUIItem(previousPageUI == null ? PluginConfig.GUI.Items.PREVIOUS_PAGE.get() : previousPageUI) {
@Override
public void onClick(ClickType type) {
if (type == ClickType.RIGHT) {
goFirstPage();
} else {
goPreviousPage();
}
PluginConfig.Sounds.GUI_CLICK.play(user);
openGUI(user);
}
});
} else {
setItem(previousPageSlot, null);
}
}
if (nextPageSlot >= 0) {
if (hasNextPage()) {
setItem(nextPageSlot, new GUIItem(nextPageUI == null ? PluginConfig.GUI.Items.NEXT_PAGE.get() : nextPageUI) {
@Override
public void onClick(ClickType type) {
if (type == ClickType.RIGHT) {
goLastPage();
} else {
goNextPage();
}
PluginConfig.Sounds.GUI_CLICK.play(user);
openGUI(user);
}
});
} else {
setItem(nextPageSlot, null);
}
}
super.openGUI(user);
}
}
@@ -1,170 +0,0 @@
package cc.carm.plugin.userprefix.util.gui;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CommonPagedGUI extends PagedGUI {
private int[] range;
int a;
int b;
int lineA;
int columnA;
int lineB;
int columnB;
private CommonPagedGUI(GUIType type, String name) {
super(type, name);
}
public CommonPagedGUI(GUIType type, String Name, int[] range) {
super(type, Name);
Arrays.sort(range);
this.range = range;
}
public CommonPagedGUI(GUIType type, String Name, int a, int b) {
super(type, Name);
this.a = a;
this.b = b;
toRange(a, b);
}
/*
int[] matrix = new int[]{
0, 1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44,
45, 46, 47, 48, 49, 50, 51, 52, 53
}
*/
private void toRange(int a, int b) {
if (a > b) {
a = a ^ b;
b = a ^ b;
a = a ^ b;
}
lineA = getLine(a);
columnA = getColumn(a);
lineB = getLine(b);
columnB = getColumn(b);
if (lineB > this.items.length / 9)
throw new IndexOutOfBoundsException("页面内容范围超过了GUI的大小");
int[] range = new int[(lineB - lineA + 1) * (columnB - columnA + 1)];
for (int i = 0, l = 0; i < this.items.length; i++) {
int li = getLine(i);
int ci = getColumn(i);
if (li >= lineA && li <= lineB && ci >= columnA && ci <= columnB) {
range[l] = i;
l++;
}
}
this.range = range;
}
int getLine(int i) {
return i / 9 + 1;
}
int getColumn(int i) {
return i % 9 + 1;
}
@Override
public boolean hasPreviousPage() {
return page > 1;
}
@Override
public boolean hasNextPage() {
return page < getLastPageNumber();
}
/**
* 前往第一页
*/
public void goFirstPage() {
if (hasPreviousPage())
this.page = 1;
else
throw new IndexOutOfBoundsException();
}
/**
* 前往最后一页
*/
public void goLastPage() {
if (hasNextPage())
this.page = getLastPageNumber();
else
throw new IndexOutOfBoundsException();
}
/**
* 得到最后一页的页码
*
* @return 最后一页的页码
*/
public int getLastPageNumber() {
return (this.container.size() / range.length) + 1;
}
/**
* 得到第一页的页码
*
* @return 第一页页码(默认为1)
*/
public int getFirstPageNumber() {
return 1;
}
@Override
public void openGUI(Player player) {
if (container.isEmpty()) {
super.openGUI(player);
return;
}
List<GUIItem> list = new ArrayList<>();
int start = (page - 1) * range.length;
for (int i = start; i < start + range.length; i++) {
if (i < container.size()) {
list.add(container.get(i));
} else {
break;
}
}
int i = 0;
for (int index : range) {
setItem(index, null);
}
for (int index : range) {
if (i < list.size()) {
setItem(index, list.get(i));
i++;
} else {
break;
}
}
super.openGUI(player);
}
}
@@ -1,291 +0,0 @@
package cc.carm.plugin.userprefix.util.gui;
import cc.carm.plugin.userprefix.Main;
import cc.carm.plugin.userprefix.util.ColorParser;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
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.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class GUI {
private static final HashMap<Player, GUI> openedGUIs = new HashMap<>();
GUIType type;
String name;
public GUIItem[] items;
public Inventory inv;
boolean setCancelledIfClickOnTarget = true;
boolean setCancelledIfClickOnSelf = true;
boolean setCancelledIfClickOnOuter = true;
Map<String, Object> flags;
public Listener listener;
public GUI(GUIType type, String name) {
this.type = type;
this.name = ColorParser.parse(name);
switch (type) {
case ONEBYNINE:
this.items = new GUIItem[9];
break;
case TWOBYNINE:
this.items = new GUIItem[18];
break;
case THREEBYNINE:
this.items = new GUIItem[27];
break;
case FOURBYNINE:
this.items = new GUIItem[36];
break;
case FIVEBYNINE:
this.items = new GUIItem[45];
break;
case SIXBYNINE:
this.items = new GUIItem[54];
break;
case CANCEL:
default:
this.items = null;
}
}
public final void setItem(int index, GUIItem item) {
if (item == null) {
this.items[index] = new GUIItem(new ItemStack(Material.AIR));
} else {
this.items[index] = item;
}
}
/**
* 批量添加GUI Item
*
* @param item
* @param index
*/
public void setItem(GUIItem item, int... index) {
for (int i : index) {
setItem(i, item);
}
}
public GUIItem getItem(int index) {
return this.items[index];
}
/**
* 更新玩家箱子的视图
*/
public void updateView() {
if (this.inv != null) {
List<HumanEntity> viewers = this.inv.getViewers();
for (int index = 0; index < this.items.length; index++) {
if (items[index] == null) {
inv.setItem(index, new ItemStack(Material.AIR));
} else {
inv.setItem(index, items[index].display);
}
}
for (HumanEntity p : viewers) {
((Player) p).updateInventory();
}
}
}
/**
* 设置是否取消点击GUI内物品的事件
* 如果不取消,玩家可以从GUI中拿取物品。
*
* @param b 是否取消
*/
public void setCancelledIfClickOnTarget(boolean b) {
this.setCancelledIfClickOnTarget = b;
}
/**
* 设置是否取消点击自己背包内物品的事件
* 如果不取消,玩家可以从自己的背包中拿取物品。
*
* @param b 是否取消
*/
public void setCancelledIfClickOnSelf(boolean b) {
this.setCancelledIfClickOnSelf = b;
}
/**
* 设置是否取消点击GUI外的事件
* 如果不取消,玩家可以把物品从GUI或背包中丢出去
*
* @param b 是否取消
*/
public void setCancelledIfClickOnOuter(boolean b) {
this.setCancelledIfClickOnOuter = b;
}
public void addFlag(String flag, Object obj) {
if (this.flags == null) this.flags = new HashMap<>();
this.flags.put(flag, obj);
}
public Object getFlag(String flag) {
if (this.flags == null) return null;
else
return this.flags.get(flag);
}
public void setFlag(String flag, Object obj) {
if (this.flags == null) this.flags = new HashMap<>();
this.flags.replace(flag, obj);
}
public void removeFlag(String flag) {
if (this.flags == null) this.flags = new HashMap<>();
this.flags.remove(flag);
}
public void rawClickListener(InventoryClickEvent event) {
}
public void openGUI(Player player) {
Inventory inv;
if (this.type == GUIType.CANCEL) {
throw new NullPointerException("被取消或不存在的GUI");
}
inv = Bukkit.createInventory(null, this.items.length, this.name);
for (int index = 0; index < this.items.length; index++) {
if (items[index] == null) {
inv.setItem(index, new ItemStack(Material.AIR));
} else {
inv.setItem(index, items[index].display);
}
}
setOpenedGUI(player, this);
this.inv = inv;
player.openInventory(inv);
if (listener == null)
Bukkit.getPluginManager().registerEvents(listener = new Listener() {
@EventHandler
public void onInventoryClickEvent(InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof Player)) return;
Player p = (Player) event.getWhoClicked();
rawClickListener(event);
if (event.getSlot() != -999) {
try {
if (getOpenedGUI(p) == GUI.this
&& event.getClickedInventory() != null
&& event.getClickedInventory().equals(GUI.this.inv)
&& GUI.this.items[event.getSlot()] != null) {
GUI.this.items[event.getSlot()].realRawClickAction(event);
}
} catch (ArrayIndexOutOfBoundsException e) {
System.err.print("err cause by GUI(" + GUI.this + "), name=" + name);
e.printStackTrace();
return;
}
} else if (setCancelledIfClickOnOuter) {
event.setCancelled(true);
}
if (hasOpenedGUI(p)
&& getOpenedGUI(p) == GUI.this
&& event.getClickedInventory() != null) {
if (event.getClickedInventory().equals(GUI.this.inv)) {
if (setCancelledIfClickOnTarget) event.setCancelled(true);
if (event.getSlot() != -999 && GUI.this.items[event.getSlot()] != null) {
if (GUI.this.items[event.getSlot()].isActionActive()) {
GUI.this.items[event.getSlot()].onClick(event.getClick());
GUI.this.items[event.getSlot()].rawClickAction(event);
if (!GUI.this.items[event.getSlot()].actions.isEmpty()) {
for (GUIItem.GUIClickAction action : GUI.this.items[event.getSlot()].actions) {
action.run(event.getClick(), player);
}
}
}
if (!GUI.this.items[event.getSlot()].actionsIgnoreActive.isEmpty()) {
for (GUIItem.GUIClickAction action : GUI.this.items[event.getSlot()].actionsIgnoreActive) {
action.run(event.getClick(), player);
}
}
}
} else if (event.getClickedInventory().equals(p.getInventory()) && setCancelledIfClickOnSelf) {
event.setCancelled(true);
}
}
}
@EventHandler
public void onDrag(InventoryDragEvent e) {
if (e.getWhoClicked() instanceof Player) {
Player p = (Player) e.getWhoClicked();
if (e.getInventory().equals(inv) || e.getInventory().equals(p.getInventory())) {
GUI.this.onDrag(e);
}
}
}
@EventHandler
public void onInventoryCloseEvent(InventoryCloseEvent event) {
if (event.getPlayer() instanceof Player && event.getInventory().equals(inv)) {
Player p = (Player) event.getPlayer();
if (event.getInventory().equals(inv)) {
HandlerList.unregisterAll(this);
listener = null;
removeOpenedGUI(p);
onClose();
}
}
}
}, Main.getInstance());
}
/**
* 拖动GUI内物品是执行的代码
*
* @param event InventoryDragEvent
*/
public void onDrag(InventoryDragEvent event) {
}
/**
* 关闭GUI时执行的代码
*/
public void onClose() {
}
public static void setOpenedGUI(Player player, GUI gui) {
openedGUIs.put(player, gui);
}
public static boolean hasOpenedGUI(Player player) {
return openedGUIs.containsKey(player);
}
public static GUI getOpenedGUI(Player player) {
return openedGUIs.get(player);
}
public static void removeOpenedGUI(Player player) {
openedGUIs.remove(player);
}
}
@@ -1,77 +0,0 @@
package cc.carm.plugin.userprefix.util.gui;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import java.util.HashSet;
import java.util.Set;
public class GUIItem {
ItemStack display;
boolean actionActive = true;
public Set<GUIClickAction> actions = new HashSet<>();
public Set<GUIClickAction> actionsIgnoreActive = new HashSet<>();
public GUIItem(ItemStack display) {
this.display = display;
}
public final ItemStack getDisplay() {
return this.display;
}
public final void setDisplay(ItemStack display) {
this.display = display;
}
public final boolean isActionActive() {
return this.actionActive;
}
public final void setActionActive(boolean b) {
actionActive = b;
}
/**
* 玩家点击GUI后执行的代码
*
* @param type 点击的类型
*/
public void onClick(ClickType type) {
}
public void addClickAction(GUIClickAction action) {
actions.add(action);
}
public void addActionIgnoreActive(GUIClickAction action) {
actionsIgnoreActive.add(action);
}
public void rawClickAction(InventoryClickEvent event) {
}
public void realRawClickAction(InventoryClickEvent event) {
}
/**
* 玩家点击GUI后执行的代码
*
* @param player 点击GUI的玩家
*/
public void customAction(Player player) {
}
public abstract static class GUIClickAction {
public abstract void run(ClickType type, Player player);
}
}
@@ -1,16 +0,0 @@
package cc.carm.plugin.userprefix.util.gui;
/**
* @author LSeng
*/
public enum GUIType {
ONEBYNINE,
TWOBYNINE,
THREEBYNINE,
FOURBYNINE,
FIVEBYNINE,
SIXBYNINE,
CANCEL;
}
@@ -1,75 +0,0 @@
package cc.carm.plugin.userprefix.util.gui;
import java.util.ArrayList;
import java.util.List;
public abstract class PagedGUI extends GUI {
List<GUIItem> container = new ArrayList<>();
public int page = 1;
public PagedGUI(GUIType type, String name) {
super(type, name);
}
public int addItem(GUIItem i) {
container.add(i);
return container.size() - 1;
}
/**
* 从GUI中移除一个物品
*
* @param item 物品
*/
public void removeItem(GUIItem item) {
container.remove(item);
}
/**
* 从GUI中移除一个物品
*
* @param slot 物品格子数
*/
public void removeItem(int slot) {
container.remove(slot);
}
public List<GUIItem> getItemsContainer() {
return new ArrayList<>(container);
}
/**
* 前往上一页
*/
public void goPreviousPage() {
if (hasPreviousPage())
page--;
else
throw new IndexOutOfBoundsException();
}
/**
* 前往下一页
*/
public void goNextPage() {
if (hasNextPage())
page++;
else
throw new IndexOutOfBoundsException();
}
/**
* @return 是否有上一页
*/
public abstract boolean hasPreviousPage();
/**
* @return 是否有下一页
*/
public abstract boolean hasNextPage();
}
@@ -1,49 +0,0 @@
package cc.carm.plugin.userprefix.wrapper;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
public class ItemStackWrapper implements ConfigurationSerializable {
private static boolean unsafeAvailable;
static {
// 用于判断是否支持unsafe
try {
Class.forName("org.bukkit.UnsafeValues");
int dataVersion = Bukkit.getServer().getUnsafe().getDataVersion();
unsafeAvailable = true;
} catch (Exception e) {
unsafeAvailable = false;
}
}
@NotNull
@Override
public Map<String, Object> serialize() {
throw new UnsupportedOperationException("Use ConfigurationUtil#dong to save configuration");
}
@NotNull
public static ItemStack deserialize(@NotNull Map<String, Object> args) {
// static define will cause problem, lazy load it
if (unsafeAvailable) {
if (!args.containsKey("v")) {
String itemName = args.get("type").toString();
Material legacyMaterial = Material.matchMaterial(itemName, true);
if (legacyMaterial == null) {
Material material = Material.matchMaterial(args.get("type").toString());
if (material == null) {
throw new IllegalArgumentException("物品 " + args.get("type") + " 不存在");
}
args.put("v", Bukkit.getServer().getUnsafe().getDataVersion());
}
}
}
return ItemStack.deserialize(args);
}
}
+6
View File
@@ -0,0 +1,6 @@
&f __ __ &3___ ____
&f / / / /__ ___ ____&3/ _ \_______ / _(_)_ __
&f/ /_/ (_-</ -_) __&3/ ___/ __/ -_) _/ /\ \ /
&f\____/___/\__/_/ &3/_/ /_/ \__/_//_//_\_\
&8| &fUser&3Prefix &8(&fv${project.version}&8) &7by &bYourCraft
&8| &7更多详情信息请参阅 &f${project.url} &7。
-93
View File
@@ -1,93 +0,0 @@
version: ${project.version} #配置文件版本,若与插件版本不同请记得检查配置文件内容
debug: false
# 统计数据设定
# 改选项用于帮助开发者统计插件版本与使用情况,且绝不会影响性能与使用体验。
# 当然,您也可以选择在这里关闭,或在plugins/bStats下的配置文件中关闭。
metrics: true
# 检查更新设定
# 该选项用于插件判断是否要检查更新,若您不希望插件检查更新并提示您,可以选择关闭。
# 检查更新为异步操作,绝不会影响性能与使用体验。
check-update: true
custom-storage:
# 自定义存储位置
# 默认存储位置为 “插件文件夹”/prefixes
# 可以规定到远程文件夹中去寻找前缀相关的设定
# 支持绝对文件路径,如 "/etc/minecraft/configurations/prefixes/"
enable: false # 是否启用
path: "prefixes/" # 一定要指向一个文件夹!
functions:
# 头顶与TabList前缀功能,该方法用到了玩家名计分板接口,如有冲突请关掉哦~
on-name-prefix:
enable: true # 是否开启本功能
order-desc: true # 是否按降序排列,即权重越高的前缀显示在越上面;若为false则按升序排列。
auto-prefix-use: true # 自动使用前缀,即当玩家没有自己选择一个前缀的时候,会自动使用所拥有的的前缀中权重最高的那一个
chat:
# 聊天功能
# - 我不推荐使用本插件的聊天功能,而是建议使用其他的聊天插件。
# - 本插件仅仅提供了**最基本**的格式变量支持,不包含其他任何功能。
# - 注意聊天格式需要遵守Bukkit原格式,即不得缺失 “%1$s” 和 “%2$s” 。
# - 本插件的聊天功能不影响其他插件对聊天事件的操作。
enable: false # 是否启用
format: "<%UserPrefix_prefix%%1$s> %2$s" #聊天的格式,注意 “%1$s” 和 “%2$s” 不可缺少,分别代表 玩家名 与 消息内容 。
GUI:
title: "&f&l我的前缀 &8| 列表"
items:
# 【必须】 GUI中可能存在的其他物品
next-page: # 下一页物品,如果没有下一页则不显示
==: org.bukkit.inventory.ItemStack
type: ARROW
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "&f下一页"
lore:
- ""
- "&f右键可前往最后一页哦~"
previous-page: # 上一页物品,如果没有上一页则不显示
==: org.bukkit.inventory.ItemStack
type: ARROW
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "&f上一页"
lore:
- ""
- "&f右键可前往第一页哦~"
Sounds: #相关的声音,注释掉则不播放声音 格式为 【声音名:音量:音调】 或 【声音名:音量】 或 【声音名】
openGUI: "BLOCK_NOTE_BLOCK_PLING:1:1"
guiClick: "UI_BUTTON_CLICK"
prefixChange: "ENTITY_VILLAGER_YES"
prefixExpired: "ENTITY_VILLAGER_NO"
# 默认前缀的配置
# 默认前缀的权重为0哦
defaultPrefix:
name: "默认前缀"
content: "&b"
itemNotUsing:
==: org.bukkit.inventory.ItemStack
type: NAME_TAG
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "&f默认玩家前缀 &f(点击切换)"
lore:
- ""
- "&a➥ 点击切换到该前缀"
itemUsing:
==: org.bukkit.inventory.ItemStack
type: NAME_TAG
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "&f默认玩家前缀"
lore:
- ""
- "&a✔ 您正在使用该前缀"
-92
View File
@@ -1,92 +0,0 @@
version: ${project.version} # DO NOT EDIT IT
debug: false #DEBUG OUT PUT
metrics: true #Metrics stats (to help developer know the stats)
# Auto check the updates.
check-update: true
custom-storage:
# Custom storage location
# default location is "./prefixes"
# Support absolute file path , such as "/etc/minecraft/configurations/prefixes/"
enable: false
path: "prefixes/" # Must be a folder!
GUI:
title: "&f&lMy Prefixes List" # Title of the GUI
items:
next-page: # only show has next page
==: org.bukkit.inventory.ItemStack
type: ARROW
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "§fNext Page"
lore:
- ""
- "§fRight-Click to the last page"
previous-page: # only show has previous page
==: org.bukkit.inventory.ItemStack
type: ARROW
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "§fPrevious Page"
lore:
- ""
- "§fRight-Click to the first page"
functions:
# Add a prefix to the top of the head,
# this method uses the scoreboard above the head,
# please turn it off if there is a conflict.
on-name-prefix:
enable: true # enable or disable
order-desc: true # using desc ( higher weight for higher display in TabList)
# Automatic prefix select.
# When the player does not choose a prefix by himself,
# the prefix with the highest weight will be used automatically
auto-prefix-use: true
chat:
# Chat Function
# - I recommend using other chat plugins instead of using this plugin,
# - this plugin only provides very basic chat format placeholders.
# - Notice that: format must has “%1$s” and “%2$s” for PlayerName and Message (Bukkit Chat Event)
enable: false
format: "<%UserPrefix_prefix%%1$s> %2$s"
Sounds:
# Format is [SOUND_NAME:Volume:Pitch] or [SOUND_NAME:Volume] or [SOUND_NAME]
openGUI: "BLOCK_NOTE_BLOCK_PLING:1:1"
guiClick: "UI_BUTTON_CLICK"
prefixChange: "ENTITY_VILLAGER_YES"
prefixExpired: "ENTITY_VILLAGER_NO"
# The default prefix's weight is 0.
defaultPrefix:
name: "Default prefix"
content: "&b"
itemNotUsing:
==: org.bukkit.inventory.ItemStack
type: NAME_TAG
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "§fThe default prefix §f(Click to select)"
lore:
- ""
- "§a➥ Click to use"
itemUsing:
==: org.bukkit.inventory.ItemStack
type: NAME_TAG
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "§fThe default prefix"
lore:
- ""
- "§a✔ Selected"
+15 -28
View File
@@ -1,4 +1,3 @@
# identifier [Necessary]
# This will be used for data-storage.
identifier: "pro"
@@ -26,43 +25,31 @@ permission: "yc.vip"
# itemHasPermission [Necessary]
# This Item will be displayed when player has permission
itemHasPermission:
==: org.bukkit.inventory.ItemStack
type: DIAMOND
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "&b&lVIP Prefix"
lore:
- ""
- "&a➥ Click to use"
name: "&b&lVIP Prefix"
lore:
- ""
- "&a➥ Click to use"
# itemUsing [Unnecessary]
# This Item will be displayed when the prefix is selected.
# If there is no such configuration, it will automatically display "itemHasPermission".
itemUsing:
==: org.bukkit.inventory.ItemStack
type: DIAMOND
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "&b&lVIP Prefix"
enchants:
PROTECTION_ENVIRONMENTAL: 1 #Add an enchantment so it looks like its selected
lore:
- ""
- "&a✔ Selected"
name: "&b&lVIP Prefix"
enchants:
PROTECTION_ENVIRONMENTAL: 1 #Add an enchantment so it looks like its selected
lore:
- ""
- "&a✔ Selected"
# itemNoPermission [Unnecessary]
# If player doesn't have the permission,this item will be displayed.
# If this item is not configured, it will not be displayed in the GUI when the player does not have permission to use it.
itemNoPermission:
==: org.bukkit.inventory.ItemStack
type: INK_SACK
damage: 8
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "&b&lVIP &c(Buy it!)"
lore:
- ""
- "&e✯ Buy the VIP to use it!"
data: 8
name: "&b&lVIP &c(Buy it!)"
lore:
- ""
- "&e✯ Buy the VIP to use it!"
-21
View File
@@ -1,21 +0,0 @@
selected:
- "&7You have selected the &f%(name) &7as current prefix."
expired:
- "&7Your prefix &f%(oldName) &7has expired,"
- "&7Now the prefix is changed to &f%(newName) &7."
removed:
- "&7Your using prefix has been removed, now the prefix is changed to &f%(newName) &7."
reload:
- "&a&lReload completed&7costs &f%(time)ms&7."
help:
- "&3&lUserPrefixAdmin &fHelp"
- "&8#/upa&f list"
- "&8- &7Show configured prefixes."
- "&8#/upa&f reload"
- "&8- &7Reload configuration."
list-title:
- "&3&lUserPrefixAdmin &fList"
list-value:
- "&8#%(weight) &f%(identifier)"
- "&8- &7Name &r%(name) &7Perm &r%(permission)"
- "&8- &7Example&r %(content) %(sender_name)"
-21
View File
@@ -1,21 +0,0 @@
selected:
- "&7您选择了 &f%(name) &7作为当前显示的前缀。"
expired:
- "&7您先前使用的前缀 &f%(oldName) &7已到期。"
- "&7现在已为您重新调整为 &f%(newName) &7。"
removed:
- "&7您先前使用的前缀已被移除,现在已为您重新调整为 &f%(newName) &7。"
reload:
- "&a&l重载完成!&7共耗时 &f%(time)ms&7。"
help:
- "&3&l用户前缀系统 &f帮助"
- "&8#/upa&f list"
- "&8- &7查看当前前缀列表。"
- "&8#/upa&f reload"
- "&8- &7重载前缀配置。"
list-title:
- "&3&l用户前缀系统 &f前缀列表"
list-value:
- "&8#%(weight) &f%(identifier)"
- "&8- &7显示名 &r%(name) &7权限 &r%(permission)"
- "&8- &7内容示例&r %(content) %(sender_name)"
+7 -2
View File
@@ -1,4 +1,4 @@
main: cc.carm.plugin.userprefix.Main
main: ${project.package}.Main
name: ${project.name}
version: ${project.version}
authors:
@@ -13,6 +13,12 @@ depend:
- LuckPerms
softdepend:
- PlaceholderAPI
permissions:
"UserPrefix.admin":
description: "用户前缀系统的管理命令权限。"
default: op
commands:
UserPrefix:
aliases:
@@ -21,6 +27,5 @@ commands:
UserPrefixAdmin:
aliases:
- upa
- prefixAdmin
permission: "UserPrefix.admin"
description: "用户前缀系统管理指令,可以查看前缀列表与重载配置文件。"
+30 -40
View File
@@ -25,54 +25,44 @@ permission: "yc.pro"
# 有权限时显示的物品 [必须]
# 当用户有权限且未选中时,会显示该物品
itemHasPermission: #
==: org.bukkit.inventory.ItemStack
type: DIAMOND
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "&b&lPro &b会员前缀"
lore:
- "&7Pro会员专属称号"
- ""
- "&f尊贵的Pro会员专属称号。"
- "&f您将获得多种特权与更好的游戏体验。"
- ""
- "&a➥ 点击切换到该前缀"
name: "&b&lPro &b会员前缀"
lore:
- "&7Pro会员专属称号"
- ""
- "&f尊贵的Pro会员专属称号。"
- "&f您将获得多种特权与更好的游戏体验。"
- ""
- "&a➥ 点击切换到该前缀"
# 正在使用时显示的物品 [非必需]
# 当用户正在使用时会显示这个物品,不配置即自动加载“itemHasPermission”
itemUsing:
==: org.bukkit.inventory.ItemStack
type: DIAMOND
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "&b&lPro &b会员前缀"
enchants:
PROTECTION_ENVIRONMENTAL: 1 #加一个附魔这样看上去就像是选中了的
lore:
- "&7Pro会员专属称号"
- ""
- "&f尊贵的Pro会员专属称号。"
- "&f您将获得多种特权与更好的游戏体验。"
- ""
- "&a✔ 您正在使用该前缀"
name: "&b&lPro &b会员前缀"
flags:
- HIDE_ENCHANTS # 隐藏附魔显示
enchants:
PROTECTION_ENVIRONMENTAL: 1 #加一个附魔这样看上去就像是选中了的
lore:
- "&7Pro会员专属称号"
- ""
- "&f尊贵的Pro会员专属称号。"
- "&f您将获得多种特权与更好的游戏体验。"
- ""
- "&a✔ 您正在使用该前缀"
# 没有权限时显示的物品 [非必需]
# 如果没有权限就会显示这个item。如果不配置该物品,则玩家没有使用权限时不会显示在GUI里面。
itemNoPermission:
==: org.bukkit.inventory.ItemStack
type: INK_SACK
damage: 8
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "&b&lPro+ &b会员前缀 &c(未拥有)"
lore:
- "&7Pro+会员专属称号"
- ""
- "&f尊贵的Pro会员专属称号。"
- "&f您将获得多种特权与更好的游戏体验。"
- "&f您可以输入 &b/vip &f指令查看详细特权!"
- ""
- "&e✯ 加入Pro+会员以使用该前缀!"
data: 8
name: "&b&lPro+ &b会员前缀 &c(未拥有)"
lore:
- "&7Pro+会员专属称号"
- ""
- "&f尊贵的Pro会员专属称号。"
- "&f您将获得多种特权与更好的游戏体验。"
- "&f您可以输入 &b/vip &f指令查看详细特权!"
- ""
- "&e✯ 加入Pro+会员以使用该前缀!"
+1 -1
View File
@@ -1,4 +1,4 @@
import cc.carm.plugin.userprefix.util.ColorParser;
import cc.carm.lib.easyplugin.utils.ColorParser;
import org.junit.Test;
public class ColorParseTest {