mirror of
https://github.com/CarmJos/UserPrefix.git
synced 2024-09-19 20:15:47 +00:00
完成内容,首次提交。
This commit is contained in:
commit
c184e107cd
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/.idea/
|
||||||
|
/target/
|
||||||
|
./*.iml
|
175
README.md
Normal file
175
README.md
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
# 用户前缀系统插件
|
||||||
|
|
||||||
|
轻便、高效、实时的用户前缀系统。
|
||||||
|
|
||||||
|
数据部分基于 [LuckPerms](https://www.spigotmc.org/resources/luckperms.28140/) 实现。
|
||||||
|
|
||||||
|
## 特性
|
||||||
|
|
||||||
|
- 理论上全版本支持!
|
||||||
|
- 游戏内重载配置文件并实时更新到玩家!
|
||||||
|
- 当玩家权限变更时会实时监测前缀,若权限不足则自动更换前缀并提示!
|
||||||
|
- 可配置的声音、消息!
|
||||||
|
- 前缀图标可配置“选中”、“有权限”与“无权限”三种状态的物品
|
||||||
|
- 物品的配置通过ItemStack原生配置,支持MC所有的设定!
|
||||||
|
- 具体的设定请参考其他文档哦~
|
||||||
|
- TabList自动按照前缀的权重排序 (如有冲突可关掉)
|
||||||
|
- 玩家头顶前缀显示 (如有冲突可关掉)
|
||||||
|
- 自动排序,且可翻页的GUI
|
||||||
|
- 支持PlaceholderAPI变量
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
### 1. 版本支持问题
|
||||||
|
|
||||||
|
本插件理论全版本支持,如果出现图标不加载、声音无法播放等问题请检查配置文件中物品与声音的type在当前版本是否存在。
|
||||||
|
|
||||||
|
以声音举例,村民表示可以的声音在低版本中为 “`VILLAGER_YES`”,而在高版本中则变为了“`ENTITY_VILLAGER_YES`”。
|
||||||
|
|
||||||
|
### 2. 计分板异常问题
|
||||||
|
|
||||||
|
头顶上前缀的显示与TabList的排序均使用到了计分板API。
|
||||||
|
|
||||||
|
如有冲突导致其他插件的计分板无法显示,请关掉配置文件中`functions.OnNamePrefix`。
|
||||||
|
|
||||||
|
### 3. 物品图标配置问题
|
||||||
|
物品相关均通过Bukkit提供的ItemStack序列化方法读取,相关配置方式请参考其他文档。
|
||||||
|
|
||||||
|
## 指令
|
||||||
|
|
||||||
|
本插件指令部分较为简单。
|
||||||
|
|
||||||
|
```text
|
||||||
|
/UserPrefix 或 /prefix 打开前缀更换GUI
|
||||||
|
/UserPrefixAdmin 查看管理员指令帮助
|
||||||
|
/UserPrefixAdmin reload 重载配置文件
|
||||||
|
/UserPrefixAdmin list 查看已配置的前缀内容
|
||||||
|
```
|
||||||
|
|
||||||
|
## 变量 (PlaceholderAPI)
|
||||||
|
|
||||||
|
安装 [PlaceholderAPI](https://github.com/PlaceholderAPI/PlaceholderAPI) 后,可以输入 `/papi info UserPrefix` 查看相关变量。
|
||||||
|
|
||||||
|
变量内容如下
|
||||||
|
|
||||||
|
```text
|
||||||
|
# %UserPrefix_prefix%
|
||||||
|
- 得到当前正在使用的前缀
|
||||||
|
# %UserPrefix_weight%
|
||||||
|
- 得到当前正在使用的前缀权重
|
||||||
|
# %UserPrefix_identifier%
|
||||||
|
- 得到当前正在使用的前缀标识
|
||||||
|
# %UserPrefix_name%
|
||||||
|
- 得到当前正在使用的前缀名
|
||||||
|
# %UserPrefix_has_<Identifier>%
|
||||||
|
- 判断玩家是否拥有某个前缀(true/false)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 配置文件示例
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: 1.0.0-SNAPSHOT # 配置文件版本,一般不会动。
|
||||||
|
|
||||||
|
debug: false #debug输出,开发者用的
|
||||||
|
|
||||||
|
functions:
|
||||||
|
OnNamePrefix: true # 是否给头顶上添加前缀,该方法用到了头顶的那个计分板,如有冲突请关掉哦~
|
||||||
|
autoUsePrefix: true # 自动前缀显示 当玩家没有自己选择一个前缀的时候,会自动使用所拥有的的前缀中权重最高的那一个
|
||||||
|
|
||||||
|
messages:
|
||||||
|
selected:
|
||||||
|
- "&7您选择了 &f%(name) &7作为当前显示的前缀。"
|
||||||
|
expired:
|
||||||
|
- "&7您先前使用的前缀 &f%(oldName) &7已到期。"
|
||||||
|
- "&7现在已为您重新调整为 &f%(newName) &7。"
|
||||||
|
help:
|
||||||
|
- "&7输入 &b/prefix &7打开前缀选择菜单。"
|
||||||
|
|
||||||
|
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✔ 您正在使用该前缀"
|
||||||
|
|
||||||
|
prefixes:
|
||||||
|
VIP:
|
||||||
|
name: "&b&lPro&b" # [必须] 名字(切换的时候左下角会弹提示 用的就是这个名字)
|
||||||
|
content: "§b§lPro §b" # [必须] 显示在名字前面的内容
|
||||||
|
weight: 1 # [必须] 权重,用于GUI里面的排序(越大显示在越后面)和自动前缀显示
|
||||||
|
permission: "yc.pro" # [非必须] 检测的权限,如果没有就是人人都能用,也代表不用配置“itemNoPermission”了(因为压根不可能显示没权限时候的物品)
|
||||||
|
itemHasPermission:
|
||||||
|
# [必须] 当有权限的时候会显示这个Item
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: DIAMOND
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§b§lPro §b会员前缀"
|
||||||
|
lore:
|
||||||
|
- "§7Pro会员专属称号"
|
||||||
|
- ""
|
||||||
|
- "§f尊贵的Pro会员专属称号。"
|
||||||
|
- "§f您将获得多种特权与更好的游戏体验。"
|
||||||
|
- ""
|
||||||
|
- "§a➥ 点击切换到该前缀"
|
||||||
|
itemUsing:
|
||||||
|
# [非必需] 当有权限的时候会显示这个Item,如果没有这个配置就自动显示“itemHasPermission”的。
|
||||||
|
==: 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✔ 您正在使用该前缀"
|
||||||
|
itemNoPermission:
|
||||||
|
# [非必需] 如果没有权限就会显示这个item。如果不配置该物品,则玩家没有使用权限时不会显示在GUI里面。
|
||||||
|
==: 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+会员以使用该前缀!"
|
||||||
|
```
|
173
pom.xml
Normal file
173
pom.xml
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>cc.carm.plugin</groupId>
|
||||||
|
<artifactId>UserPrefix</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
<maven.deploy.skip>true</maven.deploy.skip>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
|
||||||
|
<repository>
|
||||||
|
<id>ycraft</id>
|
||||||
|
<url>https://maven.ycraft.cn/repository/maven-public/</url>
|
||||||
|
</repository>
|
||||||
|
|
||||||
|
<repository>
|
||||||
|
<id>luck-repo</id>
|
||||||
|
<url>https://repo.lucko.me/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>spigot</artifactId>
|
||||||
|
<version>1.17-R0.1-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>me.clip</groupId>
|
||||||
|
<artifactId>placeholderapi</artifactId>
|
||||||
|
<version>2.10.9</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.luckperms</groupId>
|
||||||
|
<artifactId>api</artifactId>
|
||||||
|
<version>5.3</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.comphenix.protocol</groupId>
|
||||||
|
<artifactId>ProtocolLib</artifactId>
|
||||||
|
<version>4.5.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.comphenix.packetwrapper</groupId>
|
||||||
|
<artifactId>PacketWrapper</artifactId>
|
||||||
|
<version>1.13-R0.1-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.13</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.22.1</version>
|
||||||
|
<configuration>
|
||||||
|
<useSystemClassLoader>false</useSystemClassLoader>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
<configuration>
|
||||||
|
<classifier>javadoc</classifier>
|
||||||
|
<links>
|
||||||
|
<link>https://javadoc.io/doc/org.jetbrains/annotations/</link>
|
||||||
|
</links>
|
||||||
|
<detectJavaApiLink>true</detectJavaApiLink>
|
||||||
|
<encoding>UTF-8</encoding>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>attach-javadocs</id>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
<encoding>UTF-8</encoding>
|
||||||
|
<compilerArgument>-parameters</compilerArgument>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>3.2.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<filters>
|
||||||
|
<filter>
|
||||||
|
<artifact>*:*</artifact>
|
||||||
|
<excludes>
|
||||||
|
<exclude>META-INF/MANIFEST.MF</exclude>
|
||||||
|
<exclude>META-INF/*.txt</exclude>
|
||||||
|
</excludes>
|
||||||
|
</filter>
|
||||||
|
</filters>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.22.1</version>
|
||||||
|
<configuration>
|
||||||
|
<useSystemClassLoader>false</useSystemClassLoader>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
86
src/main/java/cc/carm/plugin/userprefix/Main.java
Normal file
86
src/main/java/cc/carm/plugin/userprefix/Main.java
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package cc.carm.plugin.userprefix;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.command.UserPrefixAdminCommand;
|
||||||
|
import cc.carm.plugin.userprefix.command.UserPrefixCommand;
|
||||||
|
import cc.carm.plugin.userprefix.configuration.PrefixConfig;
|
||||||
|
import cc.carm.plugin.userprefix.hooker.UserPrefixExpansion;
|
||||||
|
import cc.carm.plugin.userprefix.listener.UserListener;
|
||||||
|
import cc.carm.plugin.userprefix.listener.processor.UserNodeUpdateProcessor;
|
||||||
|
import cc.carm.plugin.userprefix.manager.ServiceManager;
|
||||||
|
import net.luckperms.api.event.user.UserDataRecalculateEvent;
|
||||||
|
import cc.carm.plugin.userprefix.manager.ConfigManager;
|
||||||
|
import cc.carm.plugin.userprefix.manager.PrefixManager;
|
||||||
|
import cc.carm.plugin.userprefix.util.ColorParser;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
public class Main extends JavaPlugin {
|
||||||
|
|
||||||
|
private static Main instance;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
instance = this;
|
||||||
|
|
||||||
|
log(getName() + " " + getDescription().getVersion() + " &7开始加载...");
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
log("加载配置文件...");
|
||||||
|
ConfigManager.initConfig();
|
||||||
|
PrefixManager.init();
|
||||||
|
|
||||||
|
log("注册指令...");
|
||||||
|
Bukkit.getPluginCommand("UserPrefix").setExecutor(new UserPrefixCommand());
|
||||||
|
Bukkit.getPluginCommand("UserPrefixAdmin").setExecutor(new UserPrefixAdminCommand());
|
||||||
|
|
||||||
|
log("注册监听器...");
|
||||||
|
regListener(new UserListener());
|
||||||
|
ServiceManager.getService().getEventBus().subscribe(this, UserDataRecalculateEvent.class, UserNodeUpdateProcessor::process);
|
||||||
|
|
||||||
|
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
|
||||||
|
log("注册变量...");
|
||||||
|
new UserPrefixExpansion(getInstance()).register();
|
||||||
|
} else {
|
||||||
|
log("未安装 PlaceholderAPI 放弃注册变量...");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
log("加载完成 ,共耗时 " + (System.currentTimeMillis() - startTime) + " ms 。");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
log(getName() + " " + getDescription().getVersion() + " 开始卸载...");
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
log("卸载监听器...");
|
||||||
|
Bukkit.getServicesManager().unregisterAll(this);
|
||||||
|
|
||||||
|
log("卸载完成 ,共耗时 " + (System.currentTimeMillis() - startTime) + " ms 。");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册监听器
|
||||||
|
*
|
||||||
|
* @param listener 监听器
|
||||||
|
*/
|
||||||
|
public static void regListener(Listener listener) {
|
||||||
|
Bukkit.getPluginManager().registerEvents(listener, getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void log(String message) {
|
||||||
|
Bukkit.getConsoleSender().sendMessage(ColorParser.parseColor("[" + getInstance().getName() + "] " + message));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void debug(String message) {
|
||||||
|
if (PrefixConfig.DEBUG.get()) {
|
||||||
|
log("[DEBUG] " + ColorParser.parseColor(message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JavaPlugin getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
package cc.carm.plugin.userprefix.command;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.ui.PrefixSelectGUI;
|
||||||
|
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.ColorParser;
|
||||||
|
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")) {
|
||||||
|
sender.sendMessage(ColorParser.parseColor("&3&l用户前缀系统 &f前缀列表"));
|
||||||
|
for (ConfiguredPrefix value : PrefixManager.getPrefixes().values()) {
|
||||||
|
sender.sendMessage(ColorParser.parseColor("&8#" + value.getWeight() + " &f" + value.getIdentifier()));
|
||||||
|
sender.sendMessage(ColorParser.parseColor("&8- &7显示名 &r" + value.getName() + " &7权限&r " + value.getPermission()));
|
||||||
|
sender.sendMessage(ColorParser.parseColor("&8- &7内容示例&r " + value.getContent() + sender.getName()));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else if (aim.equalsIgnoreCase("reload")) {
|
||||||
|
long s1 = System.currentTimeMillis();
|
||||||
|
PrefixSelectGUI.closeAll(); // 关掉所有正在显示的前缀列表
|
||||||
|
PrefixManager.loadConfiguredPrefixes(); //重载配置文件
|
||||||
|
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
||||||
|
UserManager.checkPrefix(onlinePlayer, false);
|
||||||
|
/*
|
||||||
|
* 这里关掉loadOthers(为其他玩家更新)了。
|
||||||
|
* 因为每个玩家更新的时候会为其他人更新自己,
|
||||||
|
* 全部走完一遍后,所有玩家都会加载最新的前缀内容。
|
||||||
|
*/
|
||||||
|
UserManager.updatePrefixView(onlinePlayer, false);
|
||||||
|
}
|
||||||
|
sender.sendMessage(ColorParser.parseColor("&a&l重载完成!&7共耗时 &f" + (System.currentTimeMillis() - s1) + " ms&7。"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return help(sender);
|
||||||
|
}
|
||||||
|
return help(sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean help(CommandSender sender) {
|
||||||
|
sender.sendMessage(ColorParser.parseColor("&3&l用户前缀系统 &f帮助"));
|
||||||
|
sender.sendMessage(ColorParser.parseColor("&8#&f list"));
|
||||||
|
sender.sendMessage(ColorParser.parseColor("&8- &7查看当前前缀列表。"));
|
||||||
|
sender.sendMessage(ColorParser.parseColor("&8#&f reload"));
|
||||||
|
sender.sendMessage(ColorParser.parseColor("&8- &7重载前缀配置。"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package cc.carm.plugin.userprefix.command;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.ui.PrefixSelectGUI;
|
||||||
|
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 UserPrefixCommand implements CommandExecutor {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) {
|
||||||
|
if (sender instanceof Player) {
|
||||||
|
PrefixSelectGUI.open((Player) sender);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package cc.carm.plugin.userprefix.configuration;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.configuration.values.ConfigSound;
|
||||||
|
import cc.carm.plugin.userprefix.configuration.values.ConfigValue;
|
||||||
|
import cc.carm.plugin.userprefix.configuration.values.ConfigValueList;
|
||||||
|
|
||||||
|
public class PrefixConfig {
|
||||||
|
|
||||||
|
public static ConfigValue<Boolean> DEBUG = new ConfigValue<>("debug", Boolean.class, false);
|
||||||
|
|
||||||
|
public static class Functions {
|
||||||
|
|
||||||
|
public static ConfigValue<Boolean> NAME_PREFIX = new ConfigValue<>("functions.OnNamePrefix", Boolean.class, true);
|
||||||
|
public static ConfigValue<Boolean> AUTO_USE = new ConfigValue<>("functions.autoUsePrefix", Boolean.class, true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Messages {
|
||||||
|
|
||||||
|
public static ConfigValueList<String> SELECTED = new ConfigValueList<>("messages.selected", String.class);
|
||||||
|
public static ConfigValueList<String> EXPIRED = new ConfigValueList<>("messages.expired", String.class);
|
||||||
|
public static ConfigValueList<String> HELP = new ConfigValueList<>("messages.help", String.class);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Sounds {
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package cc.carm.plugin.userprefix.configuration.values;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.Main;
|
||||||
|
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 {
|
||||||
|
FileConfiguration source;
|
||||||
|
String configSection;
|
||||||
|
|
||||||
|
Sound defaultValue;
|
||||||
|
|
||||||
|
public ConfigSound(String configSection) {
|
||||||
|
this(configSection, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigSound(String configSection, Sound defaultValue) {
|
||||||
|
this.source = ConfigManager.getConfig();
|
||||||
|
this.configSection = configSection;
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(Sound value, float volume) {
|
||||||
|
this.source.set(this.configSection, value.name() + ":" + volume);
|
||||||
|
this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(Sound value, float volume, float pitch) {
|
||||||
|
this.source.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 = this.source.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.log("声音 " + this.configSection + " 配置错误,不存在 " + soundString + " ,请检查。");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (finalSound != null) {
|
||||||
|
player.playSound(player.getLocation(), finalSound, volume, pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save() {
|
||||||
|
ConfigManager.saveConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package cc.carm.plugin.userprefix.configuration.values;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.manager.ConfigManager;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
|
||||||
|
public class ConfigValue<V> {
|
||||||
|
FileConfiguration 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.source = ConfigManager.getConfig();
|
||||||
|
this.configSection = configSection;
|
||||||
|
this.clazz = clazz;
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public V get() {
|
||||||
|
Object val = this.source.get(this.configSection, this.defaultValue);
|
||||||
|
return this.clazz.isInstance(val) ? this.clazz.cast(val) : this.defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(V value) {
|
||||||
|
this.source.set(this.configSection, value);
|
||||||
|
this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save() {
|
||||||
|
ConfigManager.saveConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package cc.carm.plugin.userprefix.configuration.values;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.manager.ConfigManager;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ConfigValueList<V> {
|
||||||
|
FileConfiguration source;
|
||||||
|
String configSection;
|
||||||
|
Class<V> clazz;
|
||||||
|
|
||||||
|
public ConfigValueList(String configSection, Class<V> clazz) {
|
||||||
|
this.source = ConfigManager.getConfig();
|
||||||
|
this.configSection = configSection;
|
||||||
|
this.clazz = clazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<V> get() {
|
||||||
|
List<?> list = this.source.getList(this.configSection);
|
||||||
|
if (list == null) {
|
||||||
|
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) {
|
||||||
|
this.source.set(this.configSection, value);
|
||||||
|
this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save() {
|
||||||
|
ConfigManager.saveConfig();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
package cc.carm.plugin.userprefix.hooker;
|
||||||
|
|
||||||
|
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||||
|
import cc.carm.plugin.userprefix.manager.PrefixManager;
|
||||||
|
import cc.carm.plugin.userprefix.manager.UserManager;
|
||||||
|
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class UserPrefixExpansion extends PlaceholderExpansion {
|
||||||
|
|
||||||
|
JavaPlugin plugin;
|
||||||
|
|
||||||
|
public UserPrefixExpansion(JavaPlugin 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canRegister() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAuthor() {
|
||||||
|
return plugin.getDescription().getAuthors().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return "UserPrefix";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getVersion() {
|
||||||
|
return plugin.getDescription().getVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String onPlaceholderRequest(Player player, @NotNull String identifier) {
|
||||||
|
if (player == null) return "加载中...";
|
||||||
|
String[] args = identifier.split("_");
|
||||||
|
|
||||||
|
|
||||||
|
if (args.length < 1) {
|
||||||
|
return "参数不足";
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (args[0].toLowerCase()) {
|
||||||
|
case "identifier": {
|
||||||
|
return UserManager.getPrefix(player).getIdentifier();
|
||||||
|
}
|
||||||
|
case "prefix": {
|
||||||
|
return UserManager.getPrefix(player).getContent();
|
||||||
|
}
|
||||||
|
case "name": {
|
||||||
|
return UserManager.getPrefix(player).getName();
|
||||||
|
}
|
||||||
|
case "weight": {
|
||||||
|
return Integer.toString(UserManager.getPrefix(player).getWeight());
|
||||||
|
}
|
||||||
|
case "has": {
|
||||||
|
if (args.length < 2) return "参数不足";
|
||||||
|
ConfiguredPrefix prefix = PrefixManager.getPrefix(args[1]);
|
||||||
|
if (prefix == null) return "该前缀不存在";
|
||||||
|
return Boolean.toString(UserManager.isPrefixUsable(player, prefix));
|
||||||
|
}
|
||||||
|
case "version": {
|
||||||
|
return getVersion().replace("-SNAPSHOT", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package cc.carm.plugin.userprefix.listener;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.configuration.PrefixConfig;
|
||||||
|
import cc.carm.plugin.userprefix.manager.UserManager;
|
||||||
|
import cc.carm.plugin.userprefix.ui.PrefixSelectGUI;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
|
public class UserListener implements Listener {
|
||||||
|
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onJoin(PlayerJoinEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
|
UserManager.checkPrefix(player, false);
|
||||||
|
|
||||||
|
|
||||||
|
if (PrefixConfig.Functions.NAME_PREFIX.get()) {
|
||||||
|
UserManager.createNameTag(event.getPlayer());
|
||||||
|
UserManager.updatePrefixView(event.getPlayer(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onLeave(PlayerQuitEvent event) {
|
||||||
|
PrefixSelectGUI.removeOpening(event.getPlayer());
|
||||||
|
UserManager.unloadNameTag(event.getPlayer().getUniqueId());
|
||||||
|
UserManager.checkingPlayers.remove(event.getPlayer().getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package cc.carm.plugin.userprefix.listener.processor;
|
||||||
|
|
||||||
|
import net.luckperms.api.event.user.UserDataRecalculateEvent;
|
||||||
|
import net.luckperms.api.model.user.User;
|
||||||
|
import cc.carm.plugin.userprefix.manager.UserManager;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
public class UserNodeUpdateProcessor {
|
||||||
|
|
||||||
|
// public static void process(NodeRemoveEvent event) {
|
||||||
|
// if (event.getTarget() instanceof User) {
|
||||||
|
// if (!(event.getNode() instanceof PermissionNode)) return;
|
||||||
|
// User user = (User) event.getTarget();
|
||||||
|
// Player player = Bukkit.getPlayer(user.getUniqueId());
|
||||||
|
// if (player == null) return;
|
||||||
|
// UserManager.checkPrefix(player, true);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
public static void process(UserDataRecalculateEvent event) {
|
||||||
|
User user = event.getUser();
|
||||||
|
Player player = Bukkit.getPlayer(user.getUniqueId());
|
||||||
|
if (player == null) return;
|
||||||
|
UserManager.checkPrefix(player, true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package cc.carm.plugin.userprefix.manager;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.Main;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
|
||||||
|
public class ConfigManager {
|
||||||
|
|
||||||
|
private static FileConfiguration config;
|
||||||
|
|
||||||
|
public static void initConfig() {
|
||||||
|
Main.getInstance().saveDefaultConfig();
|
||||||
|
Main.getInstance().reloadConfig();
|
||||||
|
|
||||||
|
config = Main.getInstance().getConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FileConfiguration getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void reloadConfig() {
|
||||||
|
Main.getInstance().reloadConfig();
|
||||||
|
config = Main.getInstance().getConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveConfig() {
|
||||||
|
Main.getInstance().saveConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,129 @@
|
|||||||
|
package cc.carm.plugin.userprefix.manager;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.Main;
|
||||||
|
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
|
||||||
|
import cc.carm.plugin.userprefix.util.ItemStackFactory;
|
||||||
|
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 java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class PrefixManager {
|
||||||
|
|
||||||
|
public static ConfiguredPrefix defaultPrefix;
|
||||||
|
public static HashMap<String, ConfiguredPrefix> prefixes = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
loadConfiguredPrefixes();
|
||||||
|
Main.log("共加载了 " + prefixes.size() + " 个前缀。");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadConfiguredPrefixes() {
|
||||||
|
loadDefaultPrefix();
|
||||||
|
|
||||||
|
ConfigurationSection prefixesSection = ConfigManager.getConfig().getConfigurationSection("prefixes");
|
||||||
|
if (prefixesSection == null || prefixesSection.getKeys(false).isEmpty()) {
|
||||||
|
Main.log("配置文件中暂无任何前缀配置,请检查。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
HashMap<String, ConfiguredPrefix> dataPrefixes = new HashMap<>();
|
||||||
|
for (String prefixIdentifier : prefixesSection.getKeys(false)) {
|
||||||
|
ConfigurationSection configuredPrefixSection = prefixesSection.getConfigurationSection(prefixIdentifier);
|
||||||
|
if (configuredPrefixSection == null) continue;
|
||||||
|
|
||||||
|
String name = configuredPrefixSection.getString("name", "前缀名配置错误");
|
||||||
|
String content = configuredPrefixSection.getString("content", "&r");
|
||||||
|
String permission = configuredPrefixSection.getString("permission");
|
||||||
|
int weight = configuredPrefixSection.getInt("weight", 1);
|
||||||
|
|
||||||
|
ItemStack itemHasPermission = configuredPrefixSection.getItemStack("itemHasPermission",
|
||||||
|
new ItemStackFactory(Material.STONE).setDisplayName(name).addLore(" ").addLore("§a➥ 点击切换到该前缀").toItemStack()
|
||||||
|
);
|
||||||
|
ItemStack itemNoPermission = configuredPrefixSection.getItemStack("itemNoPermission", itemHasPermission);
|
||||||
|
ItemStack itemUsing = configuredPrefixSection.getItemStack("itemUsing", itemHasPermission);
|
||||||
|
|
||||||
|
|
||||||
|
Main.log("完成前缀加载 " + prefixIdentifier + " : " + name);
|
||||||
|
|
||||||
|
dataPrefixes.put(prefixIdentifier, new ConfiguredPrefix(prefixIdentifier, name, content, weight, permission, itemHasPermission, itemNoPermission, itemUsing));
|
||||||
|
}
|
||||||
|
|
||||||
|
prefixes = dataPrefixes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadDefaultPrefix() {
|
||||||
|
ConfigurationSection defaultPrefixSection = ConfigManager.getConfig().getConfigurationSection("defaultPrefix");
|
||||||
|
if (defaultPrefixSection != null) {
|
||||||
|
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()
|
||||||
|
);
|
||||||
|
defaultPrefix = new ConfiguredPrefix("default", name, content, 0, null, itemNotUsing, null, itemUsing);
|
||||||
|
} else {
|
||||||
|
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()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Main.log("完成默认前缀加载 " + defaultPrefix.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<ConfiguredPrefix> getVisiblePrefix() {
|
||||||
|
return PrefixManager.getPrefixes().values().stream()
|
||||||
|
.filter(ConfiguredPrefix::isVisibleNoPermission)
|
||||||
|
.sorted(Comparator.comparingInt(ConfiguredPrefix::getWeight))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ConfiguredPrefix getDefaultPrefix() {
|
||||||
|
return defaultPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HashMap<String, ConfiguredPrefix> getPrefixes() {
|
||||||
|
return prefixes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ConfiguredPrefix getPrefix(String identifier) {
|
||||||
|
if (identifier == null || identifier.equalsIgnoreCase("default")) {
|
||||||
|
return getDefaultPrefix();
|
||||||
|
} else {
|
||||||
|
return getPrefixes().get(identifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package cc.carm.plugin.userprefix.manager;
|
||||||
|
|
||||||
|
import net.luckperms.api.LuckPerms;
|
||||||
|
import net.luckperms.api.LuckPermsProvider;
|
||||||
|
import net.luckperms.api.model.user.User;
|
||||||
|
import net.luckperms.api.platform.PlayerAdapter;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务管理器,旨在于LuckPerms互联,调用其原始接口。
|
||||||
|
*/
|
||||||
|
public class ServiceManager {
|
||||||
|
|
||||||
|
public static User getUser(Player player) {
|
||||||
|
return getAPI().getUser(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LuckPerms getService() {
|
||||||
|
RegisteredServiceProvider<LuckPerms> provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class);
|
||||||
|
if (provider != null) {
|
||||||
|
return provider.getProvider();
|
||||||
|
} else {
|
||||||
|
return LuckPermsProvider.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlayerAdapter<Player> getAPI() {
|
||||||
|
return getService().getPlayerAdapter(Player.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过LuckPermsAPI判断玩家是否有对应的权限
|
||||||
|
*
|
||||||
|
* @param user 用户
|
||||||
|
* @param permission 权限
|
||||||
|
* @return true / false
|
||||||
|
*/
|
||||||
|
public static boolean hasPermission(User user, String permission) {
|
||||||
|
return user.getCachedData().getPermissionData().checkPermission(permission).asBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
222
src/main/java/cc/carm/plugin/userprefix/manager/UserManager.java
Normal file
222
src/main/java/cc/carm/plugin/userprefix/manager/UserManager.java
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
package cc.carm.plugin.userprefix.manager;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.Main;
|
||||||
|
import cc.carm.plugin.userprefix.configuration.PrefixConfig;
|
||||||
|
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
|
||||||
|
import cc.carm.plugin.userprefix.nametag.UserNameTag;
|
||||||
|
import cc.carm.plugin.userprefix.util.MessageUtil;
|
||||||
|
import net.luckperms.api.model.user.User;
|
||||||
|
import net.luckperms.api.node.NodeType;
|
||||||
|
import net.luckperms.api.node.types.MetaNode;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class UserManager {
|
||||||
|
|
||||||
|
public static HashMap<UUID, UserNameTag> nameTags = new HashMap<>();
|
||||||
|
|
||||||
|
public static HashSet<UUID> checkingPlayers = new HashSet<>();
|
||||||
|
|
||||||
|
public static UserNameTag getNameTag(Player player) {
|
||||||
|
return nameTags.get(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UserNameTag createNameTag(Player player) {
|
||||||
|
UserNameTag nameTag = new UserNameTag(player);
|
||||||
|
nameTags.put(player.getUniqueId(), nameTag);
|
||||||
|
return nameTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新前缀显示效果
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @param loadOthers 是否为玩家更新其他人的前缀(一般用于加入游戏)
|
||||||
|
*/
|
||||||
|
public static void updatePrefixView(Player player, boolean loadOthers) {
|
||||||
|
ConfiguredPrefix playerPrefix = UserManager.getPrefix(player);
|
||||||
|
|
||||||
|
UserNameTag tag = getNameTag(player);
|
||||||
|
|
||||||
|
tag.setPrefix(playerPrefix.getContent());
|
||||||
|
tag.setOrder(playerPrefix.getWeight());
|
||||||
|
|
||||||
|
Main.debug("为玩家 " + player.getName() + " 设置了 " + player.getName() + "的前缀为 #" + playerPrefix.getWeight() + " " + playerPrefix.getName());
|
||||||
|
|
||||||
|
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
||||||
|
if (onlinePlayer.equals(player)) continue;
|
||||||
|
UserNameTag onlinePlayerTag = getNameTag(onlinePlayer);
|
||||||
|
if (onlinePlayerTag != null) {
|
||||||
|
onlinePlayerTag.setPrefix(player, playerPrefix.getContent());
|
||||||
|
onlinePlayerTag.setOrder(player, playerPrefix.getWeight());
|
||||||
|
Main.debug("为玩家 " + onlinePlayer.getName() + " 设置了 " + player.getName() + "的前缀为 #" + playerPrefix.getWeight() + " " + playerPrefix.getName());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loadOthers) {
|
||||||
|
ConfiguredPrefix onlinePlayerPrefix = UserManager.getPrefix(onlinePlayer);
|
||||||
|
if (onlinePlayerPrefix != null) {
|
||||||
|
tag.setPrefix(onlinePlayer, onlinePlayerPrefix.getContent());
|
||||||
|
tag.setOrder(onlinePlayer, onlinePlayerPrefix.getWeight());
|
||||||
|
Main.debug("为玩家 " + player.getName() + " 设置了 " + player.getName() + "的前缀为 #" + onlinePlayerPrefix.getWeight() + " " + onlinePlayerPrefix.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查玩家的前缀的使用权
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @param updateView 是否更新头顶与TabList中的前缀
|
||||||
|
*/
|
||||||
|
public static void checkPrefix(Player player, boolean updateView) {
|
||||||
|
if (checkingPlayers.contains(player.getUniqueId())) return;
|
||||||
|
checkingPlayers.add(player.getUniqueId());
|
||||||
|
String currentPrefixIdentifier = UserManager.getPrefixData(player);
|
||||||
|
ConfiguredPrefix currentPrefix = PrefixManager.getPrefix(currentPrefixIdentifier);
|
||||||
|
if (!UserManager.isPrefixUsable(player, currentPrefixIdentifier)) {
|
||||||
|
ConfiguredPrefix newPrefix = UserManager.getHighestPrefix(player);
|
||||||
|
// 更新前缀
|
||||||
|
UserManager.setPrefix(player, newPrefix, updateView);
|
||||||
|
// 发送消息
|
||||||
|
MessageUtil.sendWithPlaceholders(player, PrefixConfig.Messages.EXPIRED.get(),
|
||||||
|
new String[]{"%(newName)", "%(oldName)"},
|
||||||
|
new Object[]{newPrefix.getName(), currentPrefix != null ? currentPrefix.getName() : currentPrefixIdentifier}
|
||||||
|
);
|
||||||
|
// 播放声音
|
||||||
|
PrefixConfig.Sounds.PREFIX_EXPIRED.play(player);
|
||||||
|
}
|
||||||
|
checkingPlayers.remove(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void unloadNameTag(UUID uuid) {
|
||||||
|
nameTags.remove(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 得到玩家的前缀。
|
||||||
|
* 该方法会自动判断玩家当前的前缀是否可用,并返回最终可用的前缀。
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @return 前缀配置
|
||||||
|
*/
|
||||||
|
public static ConfiguredPrefix getPrefix(Player player) {
|
||||||
|
String identifier = getPrefixData(player);
|
||||||
|
if (identifier == null || !isPrefixUsable(player, identifier)) {
|
||||||
|
return getHighestPrefix(player);
|
||||||
|
} else {
|
||||||
|
return PrefixManager.getPrefix(identifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设定玩家前缀
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @param prefix 前缀配置
|
||||||
|
* @param updateView 是否更新头顶上、TabList的前缀
|
||||||
|
*/
|
||||||
|
public static void setPrefix(Player player, ConfiguredPrefix prefix, boolean updateView) {
|
||||||
|
setPrefixData(player, prefix.getIdentifier());
|
||||||
|
if (updateView) updatePrefixView(player, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 得到玩家所有可用的前缀
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @return 可用前缀列表
|
||||||
|
*/
|
||||||
|
public static List<ConfiguredPrefix> getUsablePrefixes(Player player) {
|
||||||
|
return PrefixManager.getPrefixes().values().stream()
|
||||||
|
.filter(configuredPrefix -> isPrefixUsable(player, configuredPrefix))
|
||||||
|
.sorted(Comparator.comparingInt(ConfiguredPrefix::getWeight))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 得到玩家可使用的最高权重的权限
|
||||||
|
* 注意:若配置文件中关闭了 “autoUsePrefix” ,则会返回默认前缀。
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @return 权限内容
|
||||||
|
*/
|
||||||
|
public static ConfiguredPrefix getHighestPrefix(Player player) {
|
||||||
|
if (PrefixConfig.Functions.AUTO_USE.get()) {
|
||||||
|
// 关闭了自动选择,就直接给默认的前缀,让玩家自己去设置吧
|
||||||
|
return PrefixManager.getDefaultPrefix();
|
||||||
|
}
|
||||||
|
List<ConfiguredPrefix> prefixes = getUsablePrefixes(player);
|
||||||
|
return prefixes.stream().max(Comparator.comparingInt(ConfiguredPrefix::getWeight)).orElseGet(PrefixManager::getDefaultPrefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断一个前缀对某玩家是否可用
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @param prefixIdentifier 前缀标识
|
||||||
|
* @return 若前缀标识不存在,则返回false;若前缀为默认前缀,或该前缀无权限,或玩家有该前缀的权限,则返回true。
|
||||||
|
*/
|
||||||
|
public static 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断一个前缀对某玩家是否可用
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @param configuredPrefix 前缀配置
|
||||||
|
* @return 若前缀标识不存在,则返回false;若前缀为默认前缀,或该前缀无权限,或玩家有该前缀的权限,则返回true。
|
||||||
|
*/
|
||||||
|
public static boolean isPrefixUsable(Player player, ConfiguredPrefix configuredPrefix) {
|
||||||
|
return configuredPrefix.getPermission() == null || ServiceManager.hasPermission(ServiceManager.getUser(player), configuredPrefix.getPermission());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 得到用户当前正在使用的前缀Identifier。
|
||||||
|
* 该方法通过LuckPerms的MetaData实现,因此可以通过指令去操作。
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @return 正在使用的前缀Identifier(若不存在则返回null)
|
||||||
|
*/
|
||||||
|
public static String getPrefixData(Player player) {
|
||||||
|
return ServiceManager.getAPI().getMetaData(player).getMetaValue("userprefix", String::valueOf).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设定用户所使用的的prefix。
|
||||||
|
* 该方法通过LuckPerms的MetaData实现,因此可以通过指令去操作。
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @param prefixIdentifier 前缀的标识
|
||||||
|
*/
|
||||||
|
public static void setPrefixData(Player player, String prefixIdentifier) {
|
||||||
|
User user = ServiceManager.getUser(player);
|
||||||
|
clearPrefixData(player);
|
||||||
|
// LuckPerms竟然会把所有的metaKey全部转换为小写... 那我这里就直接写成小写吧~
|
||||||
|
MetaNode node = MetaNode.builder("userprefix", prefixIdentifier).build();
|
||||||
|
user.data().add(node);
|
||||||
|
ServiceManager.getService().getUserManager().saveUser(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除玩家所选择的前缀数据
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
*/
|
||||||
|
public static void clearPrefixData(Player player) {
|
||||||
|
User user = ServiceManager.getUser(player);
|
||||||
|
// LuckPerms竟然会把所有的metaKey全部转换为小写... 那我这里就直接写成小写吧~
|
||||||
|
user.data().clear(NodeType.META.predicate(mn -> mn.getMetaKey().equals("userprefix")));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
package cc.carm.plugin.userprefix.model;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.util.ColorParser;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
public class ConfiguredPrefix {
|
||||||
|
|
||||||
|
String identifier;
|
||||||
|
|
||||||
|
String name;
|
||||||
|
String content;
|
||||||
|
|
||||||
|
int weight;
|
||||||
|
|
||||||
|
String permission;
|
||||||
|
|
||||||
|
ItemStack itemHasPermission;
|
||||||
|
ItemStack itemNoPermission;
|
||||||
|
ItemStack itemWhenUsing;
|
||||||
|
|
||||||
|
public ConfiguredPrefix(String identifier, String name, String content, int weight, String permission, ItemStack itemHasPermission, ItemStack itemNoPermission, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIdentifier() {
|
||||||
|
return identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContent() {
|
||||||
|
return ColorParser.parseColor(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(String content) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWeight() {
|
||||||
|
return weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeight(int weight) {
|
||||||
|
this.weight = weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPermission() {
|
||||||
|
return permission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPermission(String permission) {
|
||||||
|
this.permission = permission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack getItemHasPermission() {
|
||||||
|
return itemHasPermission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItemHasPermission(ItemStack itemHasPermission) {
|
||||||
|
this.itemHasPermission = itemHasPermission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack getItemNoPermission() {
|
||||||
|
return itemNoPermission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItemNoPermission(ItemStack itemNoPermission) {
|
||||||
|
this.itemNoPermission = itemNoPermission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack getItemWhenUsing() {
|
||||||
|
return itemWhenUsing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItemWhenUsing(ItemStack itemWhenUsing) {
|
||||||
|
this.itemWhenUsing = itemWhenUsing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isVisibleNoPermission() {
|
||||||
|
return this.itemNoPermission != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
153
src/main/java/cc/carm/plugin/userprefix/nametag/UserNameTag.java
Normal file
153
src/main/java/cc/carm/plugin/userprefix/nametag/UserNameTag.java
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
package cc.carm.plugin.userprefix.nametag;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.scoreboard.Scoreboard;
|
||||||
|
import org.bukkit.scoreboard.Team;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class UserNameTag {
|
||||||
|
|
||||||
|
private final Player viewer;
|
||||||
|
private Team team;
|
||||||
|
private final Scoreboard sb;
|
||||||
|
private int order = 99999;
|
||||||
|
private final Map<UUID, Integer> targetOrders = new HashMap<>();
|
||||||
|
private final Map<UUID, String> previousTeamNames = new HashMap<>();
|
||||||
|
|
||||||
|
public UserNameTag(Player viewer) {
|
||||||
|
this.viewer = viewer;
|
||||||
|
Scoreboard sb = viewer.getScoreboard();
|
||||||
|
if (sb == Bukkit.getServer().getScoreboardManager().getMainScoreboard()) {
|
||||||
|
sb = Bukkit.getScoreboardManager().getNewScoreboard();
|
||||||
|
}
|
||||||
|
team = sb.registerNewTeam(order + viewer.getUniqueId().toString().substring(0, 10));
|
||||||
|
team.setCanSeeFriendlyInvisibles(true);
|
||||||
|
team.addEntry(viewer.getName());
|
||||||
|
this.sb = sb;
|
||||||
|
viewer.setScoreboard(sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置自己的前缀
|
||||||
|
*
|
||||||
|
* @param prefix
|
||||||
|
*/
|
||||||
|
public void setPrefix(String prefix) {
|
||||||
|
team.setPrefix(prefix);
|
||||||
|
update(viewer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置某个玩家的前缀
|
||||||
|
*
|
||||||
|
* @param target
|
||||||
|
* @param prefix
|
||||||
|
*/
|
||||||
|
public void setPrefix(Player target, String prefix) {
|
||||||
|
if (target == viewer) {
|
||||||
|
setPrefix(prefix);
|
||||||
|
} else {
|
||||||
|
Team targetTeam = checkTeam(target);
|
||||||
|
targetTeam.setPrefix(prefix);
|
||||||
|
}
|
||||||
|
update(viewer);
|
||||||
|
if (viewer != target)
|
||||||
|
update(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置名字在TabList中的顺序
|
||||||
|
*
|
||||||
|
* @param order
|
||||||
|
*/
|
||||||
|
public void setOrder(int order) {
|
||||||
|
if (order < 0 || order > 99999)
|
||||||
|
throw new IllegalArgumentException("order must be in 0~99999");
|
||||||
|
this.order = order;
|
||||||
|
targetOrders.put(viewer.getUniqueId(), order);
|
||||||
|
update(viewer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置名字在TabList中的顺序
|
||||||
|
*
|
||||||
|
* @param order 顺序
|
||||||
|
*/
|
||||||
|
public void setOrder(Player target, int order) {
|
||||||
|
if (order < 0 || order > 99999)
|
||||||
|
throw new IllegalArgumentException("order must be in 0~99999");
|
||||||
|
Team targetTeam = checkTeam(target);
|
||||||
|
String teamName = order + UUID.randomUUID().toString().substring(0, 10);
|
||||||
|
targetTeam.setDisplayName(teamName);
|
||||||
|
targetOrders.put(target.getUniqueId(), order);
|
||||||
|
update(viewer);
|
||||||
|
if (viewer != target)
|
||||||
|
update(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(Player target) {
|
||||||
|
if (target == viewer) {
|
||||||
|
Set<String> entries = team.getEntries();
|
||||||
|
String name = order + viewer.getUniqueId().toString().substring(0, 10);
|
||||||
|
if (sb.getTeam(name) == null) {
|
||||||
|
Team newTeam = sb.registerNewTeam(name);
|
||||||
|
newTeam.setDisplayName(name);
|
||||||
|
entries.forEach(newTeam::addEntry);
|
||||||
|
team.getPrefix();
|
||||||
|
if (!team.getPrefix().isEmpty())
|
||||||
|
newTeam.setPrefix(team.getPrefix());
|
||||||
|
team.getSuffix();
|
||||||
|
if (!team.getSuffix().isEmpty())
|
||||||
|
newTeam.setSuffix(team.getSuffix());
|
||||||
|
newTeam.setNameTagVisibility(team.getNameTagVisibility());
|
||||||
|
newTeam.setCanSeeFriendlyInvisibles(true);
|
||||||
|
team.unregister();
|
||||||
|
team = newTeam;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int order = targetOrders.getOrDefault(target.getUniqueId(), 99999);
|
||||||
|
String previousTeamName = previousTeamNames.get(target.getUniqueId());
|
||||||
|
if (previousTeamName == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String name = order + target.getUniqueId().toString().substring(0, 10);
|
||||||
|
Team targetTeam = this.sb.getTeam(previousTeamName);
|
||||||
|
if (targetTeam == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sb.getTeam(name) == null) {
|
||||||
|
Team newTeam = sb.registerNewTeam(name);
|
||||||
|
newTeam.setDisplayName(name);
|
||||||
|
newTeam.addEntry(target.getName());
|
||||||
|
newTeam.setNameTagVisibility(targetTeam.getNameTagVisibility());
|
||||||
|
newTeam.setCanSeeFriendlyInvisibles(true);
|
||||||
|
targetTeam.getPrefix();
|
||||||
|
if (!targetTeam.getPrefix().isEmpty()) newTeam.setPrefix(targetTeam.getPrefix());
|
||||||
|
targetTeam.getSuffix();
|
||||||
|
if (!targetTeam.getSuffix().isEmpty()) newTeam.setSuffix(targetTeam.getSuffix());
|
||||||
|
targetTeam.unregister();
|
||||||
|
previousTeamNames.put(target.getUniqueId(), name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Team checkTeam(Player target) {
|
||||||
|
int order = targetOrders.getOrDefault(target.getUniqueId(), 99999);
|
||||||
|
String name = order + target.getUniqueId().toString().substring(0, 10);
|
||||||
|
Team targetTeam = this.sb.getTeam(name);
|
||||||
|
if (targetTeam == null) {
|
||||||
|
targetTeam = this.sb.registerNewTeam(name);
|
||||||
|
targetTeam.addEntry(target.getName());
|
||||||
|
previousTeamNames.put(target.getUniqueId(), name);
|
||||||
|
}
|
||||||
|
return targetTeam;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
package cc.carm.plugin.userprefix.ui;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.configuration.PrefixConfig;
|
||||||
|
import cc.carm.plugin.userprefix.util.MessageUtil;
|
||||||
|
import cc.carm.plugin.userprefix.util.gui.GUIType;
|
||||||
|
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.gui.AutoPagedGUI;
|
||||||
|
import cc.carm.plugin.userprefix.util.gui.GUIItem;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PrefixSelectGUI extends AutoPagedGUI {
|
||||||
|
|
||||||
|
public static HashSet<Player> openingUsers = new HashSet<>();
|
||||||
|
|
||||||
|
Player player;
|
||||||
|
|
||||||
|
public PrefixSelectGUI(Player player) {
|
||||||
|
super(GUIType.SIXBYNINE, "&f&l我的前缀 &8| 列表", 10, 43);
|
||||||
|
this.player = player;
|
||||||
|
|
||||||
|
setPreviousPageSlot(18);
|
||||||
|
setNextPageSlot(26);
|
||||||
|
|
||||||
|
loadItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player getPlayer() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadItems() {
|
||||||
|
List<ConfiguredPrefix> prefixList = new ArrayList<>();
|
||||||
|
prefixList.add(PrefixManager.getDefaultPrefix());
|
||||||
|
prefixList.addAll(PrefixManager.getVisiblePrefix());
|
||||||
|
|
||||||
|
ConfiguredPrefix usingPrefix = UserManager.getPrefix(getPlayer());
|
||||||
|
|
||||||
|
for (ConfiguredPrefix prefix : prefixList) {
|
||||||
|
if (prefix.getIdentifier().equals(usingPrefix.getIdentifier())) {
|
||||||
|
addItem(new GUIItem(prefix.getItemWhenUsing() != null ? prefix.getItemWhenUsing() : prefix.getItemHasPermission()));
|
||||||
|
} else if (UserManager.isPrefixUsable(player, prefix)) {
|
||||||
|
addItem(new GUIItem(prefix.getItemHasPermission()) {
|
||||||
|
@Override
|
||||||
|
public void onClick(ClickType type) {
|
||||||
|
if (UserManager.isPrefixUsable(player, prefix)) { //再次检查,防止打开GUI后、选择前的时间段内权限消失
|
||||||
|
player.closeInventory();
|
||||||
|
UserManager.setPrefix(player, prefix, true);
|
||||||
|
|
||||||
|
PrefixConfig.Sounds.PREFIX_CHANGE.play(player);
|
||||||
|
MessageUtil.sendWithPlaceholders(player, PrefixConfig.Messages.SELECTED.get(),
|
||||||
|
new String[]{"%(name)"},
|
||||||
|
new Object[]{prefix.getName()});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
addItem(new GUIItem(prefix.getItemNoPermission()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClose() {
|
||||||
|
openingUsers.remove(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void removeOpening(Player player) {
|
||||||
|
openingUsers.remove(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void closeAll() {
|
||||||
|
for (Player player : new HashSet<>(openingUsers)) {
|
||||||
|
player.closeInventory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void open(Player player) {
|
||||||
|
PrefixConfig.Sounds.GUI_OPEN.play(player);
|
||||||
|
new PrefixSelectGUI(player).openGUI(player);
|
||||||
|
openingUsers.add(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
package cc.carm.plugin.userprefix.util;
|
||||||
|
|
||||||
|
public class ColorParser {
|
||||||
|
|
||||||
|
public static String parseColor(final String text) {
|
||||||
|
return text.replaceAll("&", "§").replace("§§", "&");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,141 @@
|
|||||||
|
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.bukkit.inventory.meta.SkullMeta;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
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(String name) {
|
||||||
|
ItemMeta im = this.item.getItemMeta();
|
||||||
|
im.setDisplayName(name.replace("&", "§").replace("§§", "&&"));
|
||||||
|
this.item.setItemMeta(im);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStackFactory setLore(List<String> lores) {
|
||||||
|
ItemMeta im = this.item.getItemMeta();
|
||||||
|
List<String> lores_ = new ArrayList();
|
||||||
|
Iterator var4 = lores.iterator();
|
||||||
|
|
||||||
|
while (var4.hasNext()) {
|
||||||
|
String lore = (String) var4.next();
|
||||||
|
lores_.add(lore.replace("&", "§").replace("§§", "&&"));
|
||||||
|
}
|
||||||
|
|
||||||
|
im.setLore(lores_);
|
||||||
|
this.item.setItemMeta(im);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStackFactory addLore(String name) {
|
||||||
|
ItemMeta im = this.item.getItemMeta();
|
||||||
|
Object lores;
|
||||||
|
if (im.hasLore()) {
|
||||||
|
lores = im.getLore();
|
||||||
|
} else {
|
||||||
|
lores = new ArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
((List) lores).add(name.replace("&", "§").replace("§§", "&&"));
|
||||||
|
im.setLore((List) lores);
|
||||||
|
this.item.setItemMeta(im);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStackFactory addEnchant(Enchantment ench, int level, boolean ignoreLevelRestriction) {
|
||||||
|
ItemMeta im = this.item.getItemMeta();
|
||||||
|
im.addEnchant(ench, level, ignoreLevelRestriction);
|
||||||
|
this.item.setItemMeta(im);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStackFactory removeEnchant(Enchantment ench) {
|
||||||
|
ItemMeta im = this.item.getItemMeta();
|
||||||
|
im.removeEnchant(ench);
|
||||||
|
this.item.setItemMeta(im);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStackFactory addFlag(ItemFlag flag) {
|
||||||
|
ItemMeta im = this.item.getItemMeta();
|
||||||
|
im.addItemFlags(new ItemFlag[]{flag});
|
||||||
|
this.item.setItemMeta(im);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStackFactory removeFlag(ItemFlag flag) {
|
||||||
|
ItemMeta im = this.item.getItemMeta();
|
||||||
|
im.removeItemFlags(new ItemFlag[]{flag});
|
||||||
|
this.item.setItemMeta(im);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStackFactory setUnbreakable(boolean unbreakable) {
|
||||||
|
ItemMeta im = this.item.getItemMeta();
|
||||||
|
im.setUnbreakable(unbreakable);
|
||||||
|
this.item.setItemMeta(im);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStackFactory setSkullOwner(String name) {
|
||||||
|
if (this.item.getType() == Material.PLAYER_HEAD || this.item.getType() == Material.PLAYER_WALL_HEAD) {
|
||||||
|
SkullMeta im = (SkullMeta) this.item.getItemMeta();
|
||||||
|
im.setOwner(name);
|
||||||
|
this.item.setItemMeta(im);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package cc.carm.plugin.userprefix.util;
|
||||||
|
|
||||||
|
import me.clip.placeholderapi.PlaceholderAPI;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class MessageUtil {
|
||||||
|
|
||||||
|
public static void send(Player player, List<String> messages) {
|
||||||
|
for (String s : messages) {
|
||||||
|
player.sendMessage(ColorParser.parseColor(s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void send(Player player, String... messages) {
|
||||||
|
send(player, Arrays.asList(messages));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendWithPlaceholders(Player player, String... messages) {
|
||||||
|
sendWithPlaceholders(player, Arrays.asList(messages));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendWithPlaceholders(Player player, List<String> messages) {
|
||||||
|
send(player, PlaceholderAPI.setPlaceholders(player, messages));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendWithPlaceholders(Player player, List<String> messages, String param, Object value) {
|
||||||
|
sendWithPlaceholders(player, messages, new String[]{param}, new Object[]{value});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendWithPlaceholders(Player player, List<String> messages, String[] params, Object[] values) {
|
||||||
|
sendWithPlaceholders(player, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,105 @@
|
|||||||
|
package cc.carm.plugin.userprefix.util.gui;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.configuration.PrefixConfig;
|
||||||
|
import cc.carm.plugin.userprefix.util.ItemStackFactory;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
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 ? new ItemStackFactory(Material.ARROW)
|
||||||
|
.setDisplayName("&f上一页")
|
||||||
|
.addLore("&7&o右键可前往第一页哦")
|
||||||
|
.toItemStack() : previousPageUI) {
|
||||||
|
@Override
|
||||||
|
public void ClickAction(ClickType type, Player u) {
|
||||||
|
if (type == ClickType.RIGHT) {
|
||||||
|
goFirstPage();
|
||||||
|
} else {
|
||||||
|
goPreviousPage();
|
||||||
|
}
|
||||||
|
PrefixConfig.Sounds.GUI_CLICK.play(u);
|
||||||
|
openGUI(u);
|
||||||
|
// u.playSound(u.getLocation(), Sound.ENTITY_CHICKEN_EGG, 0.5f, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// setItem(previousPageSlot, new GUIItem(noPreviousPageUI == null ? new ItemStackFactory(Material.GRAY_STAINED_GLASS_PANE)
|
||||||
|
// .setDisplayName("已经是第一页啦")
|
||||||
|
// .toItemStack() : noPreviousPageUI));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (previousPageSlot >= 0)
|
||||||
|
if (hasNextPage()) {
|
||||||
|
setItem(nextPageSlot, new GUIItem(nextPageUI == null ? new ItemStackFactory(Material.ARROW)
|
||||||
|
.setDisplayName("下一页")
|
||||||
|
.addLore("&7&o右键可前往最后一页哦")
|
||||||
|
.toItemStack() : nextPageUI) {
|
||||||
|
@Override
|
||||||
|
public void ClickAction(ClickType type, Player u) {
|
||||||
|
if (type == ClickType.RIGHT) {
|
||||||
|
goLastPage();
|
||||||
|
} else {
|
||||||
|
goNextPage();
|
||||||
|
}
|
||||||
|
PrefixConfig.Sounds.GUI_CLICK.play(u);
|
||||||
|
openGUI(u);
|
||||||
|
// u.playSound(u.getLocation(), Sound.ENTITY_CHICKEN_EGG, 0.5f, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// setItem(nextPageSlot, new GUIItem(noNextPageUI == null ? new ItemStackFactory(Material.GRAY_STAINED_GLASS_PANE)
|
||||||
|
// .setDisplayName("已经是最后一页啦")
|
||||||
|
// .toItemStack() : noNextPageUI));
|
||||||
|
}
|
||||||
|
|
||||||
|
super.openGUI(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,170 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
378
src/main/java/cc/carm/plugin/userprefix/util/gui/GUI.java
Normal file
378
src/main/java/cc/carm/plugin/userprefix/util/gui/GUI.java
Normal file
@ -0,0 +1,378 @@
|
|||||||
|
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.event.inventory.InventoryType;
|
||||||
|
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.parseColor(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;
|
||||||
|
default:
|
||||||
|
case SIXBYNINE:
|
||||||
|
this.items = new GUIItem[54];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HOPPER:
|
||||||
|
this.items = new GUIItem[InventoryType.HOPPER.getDefaultSize()];
|
||||||
|
break;
|
||||||
|
case BEACON:
|
||||||
|
this.items = new GUIItem[InventoryType.BEACON.getDefaultSize()];
|
||||||
|
break;
|
||||||
|
case DISPENSER:
|
||||||
|
this.items = new GUIItem[InventoryType.DISPENSER.getDefaultSize()];
|
||||||
|
break;
|
||||||
|
case DROPPER:
|
||||||
|
this.items = new GUIItem[InventoryType.DROPPER.getDefaultSize()];
|
||||||
|
break;
|
||||||
|
case FURNACE:
|
||||||
|
this.items = new GUIItem[InventoryType.FURNACE.getDefaultSize()];
|
||||||
|
break;
|
||||||
|
case WORKBENCH:
|
||||||
|
this.items = new GUIItem[InventoryType.WORKBENCH.getDefaultSize()];
|
||||||
|
break;
|
||||||
|
case CRAFTING:
|
||||||
|
this.items = new GUIItem[InventoryType.CRAFTING.getDefaultSize()];
|
||||||
|
break;
|
||||||
|
case ENCHANTING:
|
||||||
|
this.items = new GUIItem[InventoryType.ENCHANTING.getDefaultSize()];
|
||||||
|
break;
|
||||||
|
case BREWING:
|
||||||
|
this.items = new GUIItem[InventoryType.BREWING.getDefaultSize()];
|
||||||
|
break;
|
||||||
|
case PLAYER:
|
||||||
|
this.items = new GUIItem[InventoryType.PLAYER.getDefaultSize()];
|
||||||
|
break;
|
||||||
|
case MERCHANT:
|
||||||
|
this.items = new GUIItem[InventoryType.MERCHANT.getDefaultSize()];
|
||||||
|
break;
|
||||||
|
case ENDER_CHEST:
|
||||||
|
this.items = new GUIItem[InventoryType.ENDER_CHEST.getDefaultSize()];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREATIVE:
|
||||||
|
this.items = new GUIItem[InventoryType.CREATIVE.getDefaultSize()];
|
||||||
|
break;
|
||||||
|
case CANCEL:
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
switch (type) {
|
||||||
|
default:
|
||||||
|
case ONEBYNINE:
|
||||||
|
case TWOBYNINE:
|
||||||
|
case THREEBYNINE:
|
||||||
|
case FOURBYNINE:
|
||||||
|
case FIVEBYNINE:
|
||||||
|
case SIXBYNINE:
|
||||||
|
inv = Bukkit.createInventory(null, this.items.length, this.name);
|
||||||
|
break;
|
||||||
|
case HOPPER:
|
||||||
|
inv = Bukkit.createInventory(null, InventoryType.HOPPER, this.name);
|
||||||
|
break;
|
||||||
|
case BEACON:
|
||||||
|
inv = Bukkit.createInventory(null, InventoryType.BEACON, this.name);
|
||||||
|
break;
|
||||||
|
case DISPENSER:
|
||||||
|
inv = Bukkit.createInventory(null, InventoryType.DISPENSER, this.name);
|
||||||
|
break;
|
||||||
|
case DROPPER:
|
||||||
|
inv = Bukkit.createInventory(null, InventoryType.DROPPER, this.name);
|
||||||
|
break;
|
||||||
|
case FURNACE:
|
||||||
|
inv = Bukkit.createInventory(null, InventoryType.FURNACE, this.name);
|
||||||
|
break;
|
||||||
|
case WORKBENCH:
|
||||||
|
inv = Bukkit.createInventory(null, InventoryType.WORKBENCH, this.name);
|
||||||
|
break;
|
||||||
|
case CRAFTING:
|
||||||
|
inv = Bukkit.createInventory(null, InventoryType.CRAFTING, this.name);
|
||||||
|
break;
|
||||||
|
case ENCHANTING:
|
||||||
|
inv = Bukkit.createInventory(null, InventoryType.ENCHANTING, this.name);
|
||||||
|
break;
|
||||||
|
case BREWING:
|
||||||
|
inv = Bukkit.createInventory(null, InventoryType.BREWING, this.name);
|
||||||
|
break;
|
||||||
|
case PLAYER:
|
||||||
|
inv = Bukkit.createInventory(null, InventoryType.PLAYER, this.name);
|
||||||
|
break;
|
||||||
|
case CREATIVE:
|
||||||
|
inv = Bukkit.createInventory(null, InventoryType.CREATIVE, this.name);
|
||||||
|
break;
|
||||||
|
case MERCHANT:
|
||||||
|
inv = Bukkit.createInventory(null, InventoryType.MERCHANT, this.name);
|
||||||
|
break;
|
||||||
|
case ENDER_CHEST:
|
||||||
|
inv = Bukkit.createInventory(null, InventoryType.ENDER_CHEST, this.name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
rawClickListener(event);
|
||||||
|
if (!(event.getWhoClicked() instanceof Player)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Player p = (Player) event.getWhoClicked();
|
||||||
|
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) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.err.print("err cause by GUI(" + GUI.this.toString() + "), name=" + name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (setCancelledIfClickOnOuter) event.setCancelled(true);
|
||||||
|
}
|
||||||
|
if (hasOpenedGUI(p) && /*player.openedGUI.inv.equals(event.getClickedInventory())*/ 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()].ClickAction(event.getClick(), player);
|
||||||
|
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())) {
|
||||||
|
if (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;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
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 点击的类型
|
||||||
|
* @param player 点击GUI的玩家
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void ClickAction(ClickType type, Player player) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 玩家点击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 customAction() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rawClickAction(InventoryClickEvent event) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void realRawClickAction(InventoryClickEvent event) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void customAction(Object obj) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 玩家点击GUI后执行的代码
|
||||||
|
*
|
||||||
|
* @param player 点击GUI的玩家
|
||||||
|
*/
|
||||||
|
public void customAction(Player player) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract static class GUIClickAction {
|
||||||
|
public abstract void run(ClickType type, Player player);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package cc.carm.plugin.userprefix.util.gui;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author LSeng
|
||||||
|
*/
|
||||||
|
public enum GUIType {
|
||||||
|
|
||||||
|
ONEBYNINE,
|
||||||
|
TWOBYNINE,
|
||||||
|
THREEBYNINE,
|
||||||
|
FOURBYNINE,
|
||||||
|
FIVEBYNINE,
|
||||||
|
SIXBYNINE,
|
||||||
|
DISPENSER,
|
||||||
|
DROPPER,
|
||||||
|
FURNACE,
|
||||||
|
WORKBENCH,
|
||||||
|
CRAFTING,
|
||||||
|
ENCHANTING,
|
||||||
|
BREWING,
|
||||||
|
PLAYER,
|
||||||
|
CREATIVE,
|
||||||
|
MERCHANT,
|
||||||
|
ENDER_CHEST,
|
||||||
|
BEACON,
|
||||||
|
HOPPER,
|
||||||
|
UNKNOWN,
|
||||||
|
CANCEL;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
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();
|
||||||
|
|
||||||
|
}
|
102
src/main/resources/config.yml
Normal file
102
src/main/resources/config.yml
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
version: ${project.version}
|
||||||
|
|
||||||
|
debug: false
|
||||||
|
|
||||||
|
functions:
|
||||||
|
OnNamePrefix: true # 是否给头顶上添加前缀,该方法用到了头顶的那个计分板,如有冲突请关掉哦~
|
||||||
|
autoUsePrefix: true # 自动前缀显示 当玩家没有自己选择一个前缀的时候,会自动使用所拥有的的前缀中权重最高的那一个
|
||||||
|
|
||||||
|
messages:
|
||||||
|
selected:
|
||||||
|
- "&7您选择了 &f%(name) &7作为当前显示的前缀。"
|
||||||
|
expired:
|
||||||
|
- "&7您先前使用的前缀 &f%(oldName) &7已到期。"
|
||||||
|
- "&7现在已为您重新调整为 &f%(newName) &7。"
|
||||||
|
help:
|
||||||
|
- "&7输入 &b/prefix &7打开前缀选择菜单。"
|
||||||
|
|
||||||
|
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✔ 您正在使用该前缀"
|
||||||
|
|
||||||
|
prefixes:
|
||||||
|
VIP:
|
||||||
|
name: "&b&lPro&b" # [必须] 名字(切换的时候左下角会弹提示 用的就是这个名字)
|
||||||
|
content: "§b§lPro §b" # [必须] 显示在名字前面的内容
|
||||||
|
weight: 1 # [必须] 权重,用于GUI里面的排序(越大显示在越后面)和自动前缀显示
|
||||||
|
permission: "yc.pro" # [非必须] 检测的权限,如果没有就是人人都能用,也代表不用配置“itemNoPermission”了(因为压根不可能显示没权限时候的物品)
|
||||||
|
itemHasPermission: # [必须] 当有权限的时候会显示这个Item
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: DIAMOND
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§b§lPro §b会员前缀"
|
||||||
|
lore:
|
||||||
|
- "§7Pro会员专属称号"
|
||||||
|
- ""
|
||||||
|
- "§f尊贵的Pro会员专属称号。"
|
||||||
|
- "§f您将获得多种特权与更好的游戏体验。"
|
||||||
|
- ""
|
||||||
|
- "§a➥ 点击切换到该前缀"
|
||||||
|
itemUsing: # [非必需] 当有权限的时候会显示这个Item,如果没有这个配置就自动显示“itemHasPermission”的。
|
||||||
|
==: 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✔ 您正在使用该前缀"
|
||||||
|
itemNoPermission: # [非必需] 如果没有权限就会显示这个item。如果不配置该物品,则玩家没有使用权限时不会显示在GUI里面。
|
||||||
|
==: 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+会员以使用该前缀!"
|
||||||
|
|
20
src/main/resources/plugin.yml
Normal file
20
src/main/resources/plugin.yml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
main: cc.carm.plugin.userprefix.Main
|
||||||
|
name: UserPrefix
|
||||||
|
version: ${project.version}
|
||||||
|
authors:
|
||||||
|
- Carm
|
||||||
|
depend:
|
||||||
|
- LuckPerms
|
||||||
|
softdepend:
|
||||||
|
- PlaceholderAPI
|
||||||
|
commands:
|
||||||
|
UserPrefix:
|
||||||
|
aliases:
|
||||||
|
- prefix
|
||||||
|
description: "用户前缀系统玩家指令,用于打开前缀GUI。"
|
||||||
|
UserPrefixAdmin:
|
||||||
|
aliases:
|
||||||
|
- upa
|
||||||
|
- prefixAdmin
|
||||||
|
permission: "UserPrefix.admin"
|
||||||
|
description: "用户前缀系统管理指令,可以查看前缀列表与重载配置文件。"
|
Loading…
Reference in New Issue
Block a user