Compare commits
116 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b601950a3 | |||
| d752461c74 | |||
| 548f1d366f | |||
| 686b28cf93 | |||
| 92e14e29fe | |||
| 78f9639092 | |||
| 096c23351f | |||
| b4f8404648 | |||
| 623356ce21 | |||
| 9164541e4f | |||
| 2453305420 | |||
| 1856de5e5d | |||
| c38adbeca6 | |||
| 0e90890c67 | |||
| 7e4ca870b5 | |||
| 42b71714aa | |||
| 0d6247b0f2 | |||
| 1b9f4f3e55 | |||
| b76081bb6b | |||
| b8d6862b17 | |||
| 46fb39d7bb | |||
| 523a4f872b | |||
| 5151f1f917 | |||
| 296339ca6f | |||
| 63b69defcc | |||
| 857ce5c27b | |||
| a5189ff314 | |||
| bacb0b1bed | |||
| 1826f08575 | |||
| 4df2a49c5b | |||
| cbb9928232 | |||
| 967984e0c3 | |||
| ad780a00bd | |||
| 43c2c14cb3 | |||
| 8521d87c46 | |||
| 378e518e72 | |||
| 84cbe0c61a | |||
| 90f7f7f2e5 | |||
| 48147aec16 | |||
| e7c8ce284c | |||
| e8b603debc | |||
| 72730fad1a | |||
| a87e97f744 | |||
| b2f7338ba6 | |||
| f91a2aa198 | |||
| 124ee0f9c3 | |||
| 9f738ff1ae | |||
| f23fa03f7a | |||
| cf749bf5c0 | |||
| 01e321686f | |||
| deba26c713 | |||
| 5b4d49f6ed | |||
| 2e5250dd36 | |||
| 88730c98f2 | |||
| e003a543f5 | |||
| 07edaeb401 | |||
| 2357699324 | |||
| c2fa1a1e95 | |||
| 3b03ec4616 | |||
| 1a2644210b | |||
| 83b9ced6f5 | |||
| dd96c6d6da | |||
| ba7d4b90c3 | |||
| ab984acc73 | |||
| 32df1de83d | |||
| dfe447393e | |||
| 26ce6d7e66 | |||
| 2e4d1122d9 | |||
| b5a2199e1e | |||
| 3678a201c7 | |||
| f08a5e84d3 | |||
| 7743bbb3ff | |||
| 1942c50078 | |||
| 2b701510bc | |||
| 0d17e7f1b6 | |||
| 3a41560972 | |||
| 313aa77d72 | |||
| dab774a389 | |||
| 5469c3101f | |||
| dbf826cec8 | |||
| 87c87127b9 | |||
| 50c35488ef | |||
| 29539ddb6f | |||
| cab2b60abf | |||
| 693ff4a4af | |||
| 7c90b8ff99 | |||
| e5ba217873 | |||
| 33e0e64b7d | |||
| 6eb60d83d8 | |||
| 875655bc60 | |||
| 9ca289e4ba | |||
| 41a9582d03 | |||
| e14901ac86 | |||
| 9a620d7324 | |||
| 9cff1c03dc | |||
| 3a457082b1 | |||
| 12218a2141 | |||
| 389e4d3904 | |||
| 6ac3cea7c0 | |||
| 3f14294e67 | |||
| 93521f6621 | |||
| 43a4fb08a6 | |||
| 3dd6398afa | |||
| 799bb4e52b | |||
| 7ea3934db9 | |||
| 0d20860166 | |||
| b0c6c793a8 | |||
| b6319eec78 | |||
| 8bf19a69f8 | |||
| 5d4b131a13 | |||
| 5c2b062839 | |||
| dbe4b187d3 | |||
| 419e440700 | |||
| 7052ea6ec4 | |||
| 264b69b115 | |||
| c16d12d718 |
@@ -0,0 +1,9 @@
|
|||||||
|
# UserPrefix Javadoc
|
||||||
|
|
||||||
|
基于 [Github Pages](https://pages.github.com/) 搭建,请访问 [JavaDoc](https://carmjos.github.io/UserPrefix) 。
|
||||||
|
|
||||||
|
## 如何实现?
|
||||||
|
|
||||||
|
若您也想通过 [Github Actions](https://docs.github.com/en/actions/learn-github-actions)
|
||||||
|
自动部署项目的Javadoc到 [Github Pages](https://pages.github.com/) ,
|
||||||
|
可以参考我的文章 [《自动部署Javadoc到Github Pages》](https://pages.carm.cc/doc/javadoc-in-github.html) 。
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
```text
|
||||||
|
_ _ _____ __ _
|
||||||
|
| | | | | __ \ / _|(_)
|
||||||
|
| | | | ___ ___ _ __ | |__) |_ __ ___ | |_ _ __ __
|
||||||
|
| | | |/ __| / _ \| '__|| ___/| '__|/ _ \| _|| |\ \/ /
|
||||||
|
| |__| |\__ \| __/| | | | | | | __/| | | | > <
|
||||||
|
\____/ |___/ \___||_| |_| |_| \___||_| |_|/_/\_\
|
||||||
|
```
|
||||||
|
|
||||||
|
# UserPrefix 帮助介绍文档
|
||||||
|
|
||||||
|
## 插件介绍目录
|
||||||
|
|
||||||
|
- 使用示例
|
||||||
|
- [前缀配置文件预设示例](../src/main/resources/prefixes/example-prefix.yml)
|
||||||
|
|
||||||
|
## [开发文档](JAVADOC-README.md)
|
||||||
|
|
||||||
|
基于 [Github Pages](https://pages.github.com/) 搭建,请访问 [JavaDoc](https://carmjos.github.io/UltraDepository) 。
|
||||||
|
|
||||||
|
## 依赖方式
|
||||||
|
|
||||||
|
### Maven 依赖
|
||||||
|
|
||||||
|
```xml
|
||||||
|
|
||||||
|
<project>
|
||||||
|
<repositories>
|
||||||
|
|
||||||
|
<repository>
|
||||||
|
<!--采用github依赖库,安全稳定,但需要配置 (推荐)-->
|
||||||
|
<id>UserPrefix</id>
|
||||||
|
<name>GitHub Packages</name>
|
||||||
|
<url>https://maven.pkg.github.com/CarmJos/UserPrefix</url>
|
||||||
|
</repository>
|
||||||
|
|
||||||
|
<repository>
|
||||||
|
<!--采用我的私人依赖库,简单方便,但可能因为变故而无法使用-->
|
||||||
|
<id>carm-repo</id>
|
||||||
|
<name>Carm's Repo</name>
|
||||||
|
<url>https://repo.carm.cc/repository/maven-public/</url>
|
||||||
|
</repository>
|
||||||
|
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cc.carm.plugin</groupId>
|
||||||
|
<artifactId>userprefix</artifactId>
|
||||||
|
<version>[LATEST RELEASE]</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Gradle 依赖
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
repositories {
|
||||||
|
// 采用github依赖库,安全稳定,但需要配置 (推荐)
|
||||||
|
maven { url 'https://maven.pkg.github.com/CarmJos/UserPrefix' }
|
||||||
|
|
||||||
|
// 采用我的私人依赖库,简单方便,但可能因为变故而无法使用
|
||||||
|
maven { url 'https://repo.carm.cc/repository/maven-public/' }
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly "cc.carm.plugin:userprefix:[LATEST RELEASE]"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Before Width: | Height: | Size: 723 KiB After Width: | Height: | Size: 723 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 212 KiB |
|
Before Width: | Height: | Size: 920 KiB After Width: | Height: | Size: 920 KiB |
|
After Width: | Height: | Size: 60 KiB |
@@ -0,0 +1,314 @@
|
|||||||
|
[align=center][attachimg]1905166[/attachimg]
|
||||||
|
[/align]
|
||||||
|
[align=left][b][size=6]用户前缀系统插件[/size][/b][/align][align=left][hr][/align][align=left][img]https://www.codefactor.io/repository/github/carmjos/userprefix/badge?s=b76fec1f64726b5f19989aace6adb5f85fdab840[/img] [img]https://github.com/CarmJos/UserPrefix/actions/workflows/maven.yml/badge.svg?branch=master[/img] [img]https://visitor-badge.glitch.me/badge?page_id=userprefix.readme[/img]
|
||||||
|
[/align]
|
||||||
|
[align=left]轻便、高效、实时的用户前缀系统。[/align]
|
||||||
|
[align=left]本插件基于Spigot实现,[b]理论上支持全版本[/b]。[/align]
|
||||||
|
[align=left][size=5][b]示例[/b][/size][/align][align=left][hr][/align]
|
||||||
|
[attachimg]1905175[/attachimg]
|
||||||
|
[align=left][size=5][b]依赖[/b][/size][/align][align=left][hr][/align]
|
||||||
|
[align=left][list]
|
||||||
|
[*][size=3][b][必须] [/b][/size]插件本体基于 [url=https://hub.spigotmc.org/stash/projects/SPIGOT][b]Spigot-API[/b][/url] 与 [b][url=http://bukkit.org/]BukkitAPI[/url] [/b]实现。
|
||||||
|
[*][size=3][b][必须] [/b][/size]数据部分基于 [url=https://www.spigotmc.org/resources/luckperms.28140/][b]LuckPerms[/b][/url] 实现。
|
||||||
|
[*][size=3][b][推荐][/b] [/size]变量部分基于 [url=https://www.spigotmc.org/resources/6245/][b]PlaceholderAPI[/b][/url] 实现。
|
||||||
|
[/list]
|
||||||
|
[/align]详细依赖列表可见 [url=https://github.com/CarmJos/UserPrefix/network/dependencies]软件依赖[/url] 。
|
||||||
|
|
||||||
|
[size=5][b]特性[/b][/size]
|
||||||
|
[hr]
|
||||||
|
[list]
|
||||||
|
[*]理论上[b]全版本支持[/b]!
|
||||||
|
[*]游戏内重载配置文件并实时更新到玩家!
|
||||||
|
[*]当玩家权限变更时会[b]实时监测前缀[/b],若权限不足则[b]自动更换[/b]前缀并提示!
|
||||||
|
[*]可配置的声音、消息!
|
||||||
|
[*]前缀图标可配置“选中”、“有权限”与“无权限”三种状态的物品
|
||||||
|
[*]物品的配置通过ItemStack原生配置,支持MC所有的设定!
|
||||||
|
[*]TabList自动按照前缀的权重排序 (如有冲突可关掉)
|
||||||
|
[*]玩家头顶前缀实时显示 (如有冲突可关掉)
|
||||||
|
[*][b]自动排序[/b],且[b]可翻页[/b]的GUI!
|
||||||
|
[*]支持PlaceholderAPI变量!(凡支持的都可以使用,如BungeeTabListPlus)
|
||||||
|
[*]支持Hex颜色!(1.16以上版本) 格式 [u]&(#颜色代码)[/u]
|
||||||
|
[/list][size=5][b]
|
||||||
|
注意事项[/b][/size]
|
||||||
|
[hr]
|
||||||
|
[size=4][b]1. 版本支持问题[/b][/size]
|
||||||
|
本插件理论全版本支持,如果出现图标不加载、声音无法播放等问题请检查配置文件中物品与声音的type在当前版本是否存在。
|
||||||
|
以声音举例,村民表示可以的声音在低版本中为 “[color=#000000][backcolor=silver]VILLAGER_YES[/backcolor][/color]”,而在高版本中则变为了“[backcolor=silver][color=#000000]ENTITY_VILLAGER_YES[/color][/backcolor]”。
|
||||||
|
|
||||||
|
[size=4][b]2. 计分板异常问题[/b][/size]
|
||||||
|
头顶上前缀的显示与TabList的排序均使用到了团队计分板API。
|
||||||
|
如有冲突导致其他插件的计分板无法显示,请关掉配置文件中 [u]functions.OnNamePrefix[/u]。
|
||||||
|
|
||||||
|
[size=4][b]3. 物品图标配置问题[/b][/size]
|
||||||
|
物品相关均通过Bukkit提供的ItemStack序列化方法读取,相关配置方式请参考[url=https://www.spigotmc.org/wiki/itemstack-serialization/]ItemStack Serialization(物品序列化)[/url]。
|
||||||
|
|
||||||
|
[size=5][b]指令[/b][/size]
|
||||||
|
[hr]
|
||||||
|
本插件指令部分较为简单,大多通过GUI实现。
|
||||||
|
[code]/UserPrefix 或 /prefix 打开前缀更换GUI
|
||||||
|
/UserPrefixAdmin 查看管理员指令帮助
|
||||||
|
/UserPrefixAdmin reload 重载配置文件
|
||||||
|
/UserPrefixAdmin list 查看已配置的前缀内容[/code]
|
||||||
|
[size=5][b]变量 (PlaceholderAPI)[/b][/size]
|
||||||
|
[hr]
|
||||||
|
安装 [url=https://github.com/PlaceholderAPI/PlaceholderAPI]PlaceholderAPI[/url]后,可以输入 [u]/papi info UserPrefix[/u] 查看相关变量。
|
||||||
|
变量内容如下
|
||||||
|
[code]# %UserPrefix_prefix%
|
||||||
|
- 得到当前正在使用的前缀
|
||||||
|
# %UserPrefix_weight%
|
||||||
|
- 得到当前正在使用的前缀权重
|
||||||
|
# %UserPrefix_identifier%
|
||||||
|
- 得到当前正在使用的前缀标识
|
||||||
|
# %UserPrefix_name%
|
||||||
|
- 得到当前正在使用的前缀名
|
||||||
|
# %UserPrefix_has_<Identifier>%
|
||||||
|
- 判断玩家是否拥有某个前缀(true/false)[/code][size=5][b]
|
||||||
|
配置文件示例[/b][/size]
|
||||||
|
[hr]
|
||||||
|
[size=4][b]基础配置文件 [/b][/size][color=#24292f][font=Tahoma][size=4](config.yml)[/size][/font][/color]
|
||||||
|
[spoiler]
|
||||||
|
[code]
|
||||||
|
version: ${project.version} #配置文件版本,若与插件版本不同请记得检查配置文件内容
|
||||||
|
|
||||||
|
debug: false
|
||||||
|
|
||||||
|
custom-storage:
|
||||||
|
# 自定义存储位置
|
||||||
|
# 默认存储位置为 “插件文件夹”/prefixes
|
||||||
|
# 可以规定到远程文件夹中去寻找前缀相关的设定
|
||||||
|
# 支持绝对文件路径,如 "/etc/minecraft/configurations/prefixes/"
|
||||||
|
enable: false # 是否启用
|
||||||
|
path: "prefixes/" # 一定要指向一个文件夹!
|
||||||
|
|
||||||
|
functions:
|
||||||
|
OnNamePrefix: true # 是否给头顶上添加前缀,该方法用到了头顶的那个计分板,如有冲突请关掉哦~
|
||||||
|
autoUsePrefix: true # 自动前缀显示 当玩家没有自己选择一个前缀的时候,会自动使用所拥有的的前缀中权重最高的那一个
|
||||||
|
chat:
|
||||||
|
# 聊天功能
|
||||||
|
# - 我不推荐使用本插件的聊天功能,而是建议使用其他的聊天插件。
|
||||||
|
# - 本插件仅仅提供了**最基本**的格式变量支持,不包含其他任何功能。
|
||||||
|
# - 注意聊天格式需要遵守Bukkit原格式,即不得缺失 “%1$s” 和 “%2$s” 。
|
||||||
|
# - 本插件的聊天功能不影响其他插件对聊天事件的操作。
|
||||||
|
enable: false # 是否启用
|
||||||
|
format: "<%UserPrefix_prefix%%1$s> %2$s" #聊天的格式,注意 “%1$s” 和 “%2$s” 不可缺少,分别代表 玩家名 与 消息内容 。
|
||||||
|
|
||||||
|
GUI:
|
||||||
|
title: "&f&l我的前缀 &8| 列表"
|
||||||
|
items:
|
||||||
|
# 【必须】 GUI中可能存在的其他物品
|
||||||
|
next-page: # 下一页物品,如果没有下一页则不显示
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: ARROW
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§f下一页"
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "§f右键可前往最后一页哦~"
|
||||||
|
previous-page: # 上一页物品,如果没有上一页则不显示
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: ARROW
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§f上一页"
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "§f右键可前往第一页哦~"
|
||||||
|
|
||||||
|
Sounds: #相关的声音,注释掉则不播放声音 格式为 【声音名:音量:音调】 或 【声音名:音量】 或 【声音名】
|
||||||
|
openGUI: "BLOCK_NOTE_BLOCK_PLING:1:1"
|
||||||
|
guiClick: "UI_BUTTON_CLICK"
|
||||||
|
prefixChange: "ENTITY_VILLAGER_YES"
|
||||||
|
prefixExpired: "ENTITY_VILLAGER_NO"
|
||||||
|
|
||||||
|
# 默认前缀的配置
|
||||||
|
# 默认前缀的权重为0哦
|
||||||
|
defaultPrefix:
|
||||||
|
name: "默认前缀"
|
||||||
|
content: "&b"
|
||||||
|
itemNotUsing:
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: NAME_TAG
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§f默认玩家前缀 §f(点击切换)"
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "§a➥ 点击切换到该前缀"
|
||||||
|
itemUsing:
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: NAME_TAG
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§f默认玩家前缀"
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "§a✔ 您正在使用该前缀"
|
||||||
|
[/code]
|
||||||
|
[/spoiler]
|
||||||
|
|
||||||
|
[b][size=4][backcolor=transparent]消息配置文件[/backcolor][/size] [/b][size=4](messages.yml)[/size]
|
||||||
|
[spoiler][code]selected:
|
||||||
|
- "&7您选择了 &f%(name) &7作为当前显示的前缀。"
|
||||||
|
expired:
|
||||||
|
- "&7您先前使用的前缀 &f%(oldName) &7已到期。"
|
||||||
|
- "&7现在已为您重新调整为 &f%(newName) &7。"
|
||||||
|
reload:
|
||||||
|
- "&a&l重载完成!&7共耗时 &f%(time)ms&7。"
|
||||||
|
help:
|
||||||
|
- "&3&l用户前缀系统 &f帮助"
|
||||||
|
- "&8#/upa&f list"
|
||||||
|
- "&8- &7查看当前前缀列表。"
|
||||||
|
- "&8#/upa&f reload"
|
||||||
|
- "&8- &7重载前缀配置。"
|
||||||
|
list-title:
|
||||||
|
- "&3&l用户前缀系统 &f前缀列表"
|
||||||
|
list-value:
|
||||||
|
- "&8#%(weight) &f%(identifier)"
|
||||||
|
- "&8- &7显示名 &r%(name) &7权限 &r%(permission)"
|
||||||
|
- "&8- &7内容示例&r %(content) %(sender_name)"[/code][/spoiler]
|
||||||
|
|
||||||
|
[size=4][backcolor=transparent][b]前缀配置文件[/b][/backcolor] (prefixes/*.yml) [自2.1.7可自定义目录][/size]
|
||||||
|
[align=left][font=-apple-system, BlinkMacSystemFont, "][size=3][color=#000000]所有前缀均为单独的配置文件,存放于 [u]插件配置目录/prefixes[/u] 下,便于管理。[/color][/size][/font][/align][align=left][font=-apple-system, BlinkMacSystemFont, "][size=3][color=#000000]文件名理论上可以随便取,推荐使用英文,部分符号可能会影响正常读取,请避免使用。[/color][/size][/font][/align][align=left][spoiler][/align][code]# 唯一标识 [必须]
|
||||||
|
# 将用于记录玩家所选的前缀,以及用于数据的缓存。
|
||||||
|
# 必须 必须 必须 保持唯一!
|
||||||
|
identifier: "pro"
|
||||||
|
|
||||||
|
# 名字 [必须]
|
||||||
|
# 切换的时候左下角会弹提示 用的就是这个名字
|
||||||
|
name: "&b&lPro&b"
|
||||||
|
|
||||||
|
# 内容 [必须]
|
||||||
|
# 显示在名字前面的内容
|
||||||
|
content: "§b§lPro §b"
|
||||||
|
|
||||||
|
# 权重 [必须]
|
||||||
|
# 用于GUI、TabList的排序和自动前缀显示
|
||||||
|
# 在GUI中,权重越高的会显示在越后面
|
||||||
|
# 在TabList中,权重越高的会显示在越上面
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
# 检测的权限 [非必须]
|
||||||
|
# 如果没有就是人人都能用,也代表不用配置“itemNoPermission”了(因为压根不可能显示没权限时候的物品)
|
||||||
|
permission: "yc.pro"
|
||||||
|
|
||||||
|
# 有权限时显示的物品 [必须]
|
||||||
|
# 当用户有权限且未选中时,会显示该物品
|
||||||
|
itemHasPermission: #
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: DIAMOND
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§b§lPro §b会员前缀"
|
||||||
|
lore:
|
||||||
|
- "§7Pro会员专属称号"
|
||||||
|
- ""
|
||||||
|
- "§f尊贵的Pro会员专属称号。"
|
||||||
|
- "§f您将获得多种特权与更好的游戏体验。"
|
||||||
|
- ""
|
||||||
|
- "§a➥ 点击切换到该前缀"
|
||||||
|
|
||||||
|
# 正在使用时显示的物品 [非必需]
|
||||||
|
# 当用户正在使用时会显示这个物品,不配置即自动加载“itemHasPermission”
|
||||||
|
itemUsing:
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: DIAMOND
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§b§lPro §b会员前缀"
|
||||||
|
enchants:
|
||||||
|
PROTECTION_ENVIRONMENTAL: 1 #加一个附魔这样看上去就像是选中了的
|
||||||
|
lore:
|
||||||
|
- "§7Pro会员专属称号"
|
||||||
|
- ""
|
||||||
|
- "§f尊贵的Pro会员专属称号。"
|
||||||
|
- "§f您将获得多种特权与更好的游戏体验。"
|
||||||
|
- ""
|
||||||
|
- "§a✔ 您正在使用该前缀"
|
||||||
|
|
||||||
|
# 没有权限时显示的物品 [非必需]
|
||||||
|
# 如果没有权限就会显示这个item。如果不配置该物品,则玩家没有使用权限时不会显示在GUI里面。
|
||||||
|
itemNoPermission:
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: INK_SACK
|
||||||
|
damage: 8
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§b§lPro+ §b会员前缀 §c(未拥有)"
|
||||||
|
lore:
|
||||||
|
- "§7Pro+会员专属称号"
|
||||||
|
- ""
|
||||||
|
- "§f尊贵的Pro会员专属称号。"
|
||||||
|
- "§f您将获得多种特权与更好的游戏体验。"
|
||||||
|
- "§f您可以输入 §b/vip §f指令查看详细特权!"
|
||||||
|
- ""
|
||||||
|
- "§e✯ 加入Pro+会员以使用该前缀!"[/code][align=left][/spoiler][/align]
|
||||||
|
|
||||||
|
[size=5][b]下载地址[/b][/size]
|
||||||
|
[hr]
|
||||||
|
[size=3][b]最新版本 [/b][/size][size=3][b]2.1.7 [/b][/size][attach]1919669[/attach][quote][b][size=3]更新内容[/size][/b]
|
||||||
|
1. 提供自定义配置文件存储位置的功能,便于多子服共享配置。(custome-storage)
|
||||||
|
2. 添加控制台打开玩家菜单时的反馈(来自 @Yuri南城 )。
|
||||||
|
3. 支持由控制台为其他玩家打开GUI。
|
||||||
|
4. 若出现新配置文件条目,将自动写入默认值,便于配置。[/quote][spoiler][size=3][b]2.1.2 [/b][/size][attach]1912028[/attach][quote][b][size=3]更新内容[/size][/b]
|
||||||
|
1. 修复不开启插件自带的头顶前缀功能时出现的报错。[/quote]
|
||||||
|
[size=3][b]2.1.0 [/b][/size][attach]1909962[/attach][quote][b][size=3]更新内容[/size][/b]
|
||||||
|
1. 添加聊天相关设定,支持聊天前缀。(但不推荐使用哦~)[/quote]
|
||||||
|
[size=3][b] 2.0.0 [/b][/size][attach]1905700[/attach]
|
||||||
|
[quote][b][size=3]更新内容[/size][/b]
|
||||||
|
1. 修复低版本可能无法读取物品的bug。
|
||||||
|
2. 分离配置文件,消息配置文件改为messages.yml,前缀配置文件改 prefixes/*.yml,便于配置和管理。
|
||||||
|
3. 允许配置GUI中上一页和下一页的物品。
|
||||||
|
4. 补全帮助文档,在插件首次加载将提供一份英文版的配置,以便使用。[/quote]
|
||||||
|
[size=3][b] 1.2.5 [/b][/size][attach]1905430[/attach][quote][size=3][b]更新内容[/b]
|
||||||
|
1. 支持指令的多语言配置。[/size][/quote]
|
||||||
|
[b][size=3]
|
||||||
|
1.2.4[/size][size=4] [/size][/b][attach]1905431[/attach]
|
||||||
|
[quote][size=3][b]更新内容:[/b]
|
||||||
|
1. 修复closeAll方法中,未移除玩家缓存的bug。
|
||||||
|
2. 当玩家权限更新时,将关闭玩家的GUI,令其自行打开刷新所有前缀。
|
||||||
|
3. 允许配置GUI的标题。[/size][/quote]
|
||||||
|
[size=3][b]1.2.3 [/b][/size][attach]1905406[/attach]
|
||||||
|
[quote][size=3][b]更新内容:[/b]
|
||||||
|
[/size][size=3]1. 支持Hex颜色!(1.16以上版本) 格式 [u]&(#颜色代码)[/u] ;[/size]
|
||||||
|
[size=3][backcolor=initial]- 如 “[/backcolor][/size][backcolor=initial][size=3]LightSlateBlue [u]&(#8470FF)[/u] ”、 “DarkSlateBlue [u]&(#483D8B)[/u]”。[/size][/backcolor]
|
||||||
|
[backcolor=initial][size=3]2. 修复未安装PlaceholderAPI的情况下可能导致的部分报错。[/size][/backcolor]
|
||||||
|
[backcolor=initial][size=3]
|
||||||
|
[/size][/backcolor]
|
||||||
|
[/quote]
|
||||||
|
[/spoiler]
|
||||||
|
|
||||||
|
更多版本请移步 [url=https://github.com/CarmJos/UserPrefix/releases]Releases · CarmJos/UserPrefix (github.com)[/url] 。
|
||||||
|
|
||||||
|
|
||||||
|
[size=5][b]开源地址[/b][/size]
|
||||||
|
[hr]
|
||||||
|
[size=3]本插件于 [/size][url=https://github.com/CarmJos/UserPrefix]Github[/url][size=3] 开源。[/size]
|
||||||
|
[size=3]
|
||||||
|
[/size]
|
||||||
|
[color=#24292f][font=-apple-system, BlinkMacSystemFont, "][size=16px]本项目源码采用 [/size][/font][/color][url=https://opensource.org/licenses/GPL-3.0]GNU General Public License v3.0[/url][color=#24292f][font=-apple-system, BlinkMacSystemFont, "][size=16px] 开源协议。[/size][/font][/color]
|
||||||
|
[font=-apple-system, BlinkMacSystemFont][color=#24292f][size=16px]
|
||||||
|
[/size][/color][/font][size=3]喜欢本插件的话,也可以去Github上给我点个小星星哦~
|
||||||
|
[/size]
|
||||||
|
|
||||||
|
[size=5][b]插件支持[/b][/size]
|
||||||
|
[hr]
|
||||||
|
[size=4]本项目由 [url=https://www.mcbbs.net/group-2077-1.html]YourCraft(你的世界)[/url] 团队提供长期支持与维护。
|
||||||
|
欢迎加入 [url=https://jq.qq.com/?_wv=1027&k=W634w2NT]YourCraft技术交流群[/url] 深入探讨开发问题。[/size]
|
||||||
|
[attachimg]1905173[/attachimg]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[hr]
|
||||||
|
[align=center][b][size=4][color=#ff0000]本插件所用所有代码均为原创,不存在借用/抄袭等行为[/color][/size][/b][/align]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,284 @@
|
|||||||
|
[URL='https://raw.githubusercontent.com/CarmJos/UserPrefix/master/img/banner.png'][IMG]https://raw.githubusercontent.com/CarmJos/UserPrefix/master/img/banner.png[/IMG][/URL]
|
||||||
|
|
||||||
|
[SIZE=6][B]UserPrefix Plugin[/B][/SIZE]
|
||||||
|
[URL='https://www.codefactor.io/repository/github/carmjos/userprefix'][IMG]https://camo.githubusercontent.com/6040f5c07ea04f9cb666459d6b6f08d19971fc29a26183cdc6595297b287234b/68747470733a2f2f7777772e636f6465666163746f722e696f2f7265706f7369746f72792f6769746875622f6361726d6a6f732f757365727072656669782f62616467653f733d62373666656331663634373236623566313939383961616365366164623566383566646162383430[/IMG][/URL] [URL='https://github.com/CarmJos/UserPrefix/actions/workflows/maven.yml'][IMG]https://github.com/CarmJos/UserPrefix/actions/workflows/maven.yml/badge.svg?branch=master[/IMG][/URL] [URL='https://opensource.org/licenses/GPL-3.0'][IMG]https://camo.githubusercontent.com/fd3e53788a319da1b7287d976c2f23fcb8e3d474249af0bf7f8e671f968faebd/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f4361726d4a6f732f55736572507265666978[/IMG][/URL] [URL='https://camo.githubusercontent.com/753f86cc8d2a514a026309afab251b090749751b35409f1e633c77cc0b3f5618/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d696e6563726166742d4a617661253230312e382d2d4c61746573742d79656c6c6f77'][IMG]https://camo.githubusercontent.com/753f86cc8d2a514a026309afab251b090749751b35409f1e633c77cc0b3f5618/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d696e6563726166742d4a617661253230312e382d2d4c61746573742d79656c6c6f77[/IMG][/URL] [URL='https://camo.githubusercontent.com/75543844e4f92947d837bd45ab75d5a268e63ff485cd7b354cf69f52e60be28d/68747470733a2f2f76697369746f722d62616467652e676c697463682e6d652f62616467653f706167655f69643d757365727072656669782e726561646d65'][IMG]https://camo.githubusercontent.com/75543844e4f92947d837bd45ab75d5a268e63ff485cd7b354cf69f52e60be28d/68747470733a2f2f76697369746f722d62616467652e676c697463682e6d652f62616467653f706167655f69643d757365727072656669782e726561646d65[/IMG][/URL]
|
||||||
|
|
||||||
|
Lightweight, efficient, and real-time user prefix system.
|
||||||
|
|
||||||
|
This plugin is implemented based on Spigot ,Theoretically support ALL MineCraft Versions.
|
||||||
|
|
||||||
|
The development of this plugin is based on Chinese, which purpose is to help Chinese developers learn Bukkit plugin development.
|
||||||
|
|
||||||
|
[QUOTE]
|
||||||
|
本插件已在 [URL='https://www.mcbbs.net/forum.php?mod=viewthread&tid=1261503']MCBBS[/URL] 上发布,欢迎中文用户来这里下载。
|
||||||
|
[/QUOTE]
|
||||||
|
|
||||||
|
[SIZE=5][B]Examples[/B][/SIZE]
|
||||||
|
[URL='https://raw.githubusercontent.com/CarmJos/UserPrefix/master/img/using-example.png'][IMG]https://raw.githubusercontent.com/CarmJos/UserPrefix/master/img/using-example.png[/IMG][/URL]
|
||||||
|
|
||||||
|
[SIZE=5][B]Dependencies[/B][/SIZE]
|
||||||
|
[LIST]
|
||||||
|
[*][B][Necessary][/B] Plugin developed based on [URL='https://hub.spigotmc.org/stash/projects/SPIGOT']Spigot-API[/URL] and [URL='http://bukkit.org/']BukkitAPI[/URL].
|
||||||
|
[*][B][Necessary][/B] Plugin data storage base on [URL='https://www.spigotmc.org/resources/luckperms.28140/']LuckPerms[/URL].
|
||||||
|
[*][Recommend] Placeholders based on [URL='https://www.spigotmc.org/resources/6245/']PlaceholderAPI[/URL] .
|
||||||
|
[/LIST]
|
||||||
|
For development dependencies, please see [URL='https://github.com/CarmJos/UserPrefix/network/dependencies']Dependencies[/URL] .
|
||||||
|
|
||||||
|
[SIZE=5][B]Features[/B][/SIZE]
|
||||||
|
[LIST]
|
||||||
|
[*]Theoretically support ALL MineCraft Versions.
|
||||||
|
[*]Reloading the configuration will automatically refresh the prefix of all players.
|
||||||
|
[*]Real-time judgment and feedback to the player when permissions are changed.
|
||||||
|
[*]Configurable sounds and messages.
|
||||||
|
[*]The prefix icon can be configured as "Selected", "Has Permission" and “No Permission”.
|
||||||
|
[LIST]
|
||||||
|
[*]Item configuration is natively configured through ItemStack, which supports all MC settings!
|
||||||
|
[/LIST]
|
||||||
|
[*]TabList is automatically sorted according to the weight of the prefix (if there is a conflict, it can be turned off)
|
||||||
|
[*]The prefix display on the player name (can be turned off if there is a conflict)
|
||||||
|
[*]GUI with automatic sorting and page turning!
|
||||||
|
[*]Support PlaceholderAPI variables!
|
||||||
|
[*]Support Hex color! (Version 1.16 and above) [U]&(#Color)[/U]
|
||||||
|
[LIST]
|
||||||
|
[*]Example: LightSlateBlue [U]&(#8470FF)[/U] 、 DarkSlateBlue [U]&(#483D8B)[/U]
|
||||||
|
[/LIST]
|
||||||
|
[/LIST]
|
||||||
|
[SIZE=5][B]Notice[/B][/SIZE]
|
||||||
|
[SIZE=4][B]1. Version support issues[/B][/SIZE]
|
||||||
|
This plugin theoretically supports all versions.
|
||||||
|
|
||||||
|
If the icon does not load, the sound cannot be played, etc., please check whether the type of the item and sound in the configuration file exists in the current version.
|
||||||
|
|
||||||
|
Take the SOUND as an example. The sound that the villager said "OK" is "[U]VILLAGER_YES[/U]" in the lower version, but it becomes "[U]ENTITY_VILLAGER_YES[/U]" in the higher version.
|
||||||
|
|
||||||
|
[SIZE=4][B]2. Scoreboard exception problem[/B][/SIZE]
|
||||||
|
The display of the prefix on the head and the sorting of the TabList both use the scoreboard API.
|
||||||
|
|
||||||
|
Please turn of the [U]functions.OnNamePrefix[/U] in the configuration if there is a conflict.
|
||||||
|
|
||||||
|
[SIZE=4][B]3. Item icon configuration problem[/B][/SIZE]
|
||||||
|
Items are read through the ItemStack serialization method provided by Bukkit. For related configuration methods, please refer to [URL='https://www.spigotmc.org/wiki/itemstack-serialization/']ItemStack Serialization[/URL].
|
||||||
|
|
||||||
|
[SIZE=5][B]Commands[/B]
|
||||||
|
[/SIZE]
|
||||||
|
[code]
|
||||||
|
/UserPrefix or /prefix #Open prefix GUI
|
||||||
|
/UserPrefixAdmin # View Admin Command Help
|
||||||
|
/UserPrefixAdmin reload # Reload Config
|
||||||
|
/UserPrefixAdmin list # List all configured prefixes.
|
||||||
|
[/code]
|
||||||
|
|
||||||
|
[SIZE=5][B]Placeholders (PlaceholderAPI)[/B][/SIZE]
|
||||||
|
After installed the [URL='https://github.com/PlaceholderAPI/PlaceholderAPI']PlaceholderAPI[/URL] , you can type /papi info UserPrefix to see all the placeholders.
|
||||||
|
|
||||||
|
[code]
|
||||||
|
# %UserPrefix_prefix%
|
||||||
|
- Get the content of the current prefix
|
||||||
|
# %UserPrefix_weight%
|
||||||
|
- Get the weight of the current prefix.
|
||||||
|
# %UserPrefix_identifier%
|
||||||
|
- Get the identifier of the current prefix.
|
||||||
|
# %UserPrefix_name%
|
||||||
|
- Get the name of the current prefix.
|
||||||
|
# %UserPrefix_has_<Identifier>%
|
||||||
|
- Determine whether the player has a certain prefix(true/false)
|
||||||
|
[/code]
|
||||||
|
|
||||||
|
[SIZE=5][B]Configuration Files[/B][/SIZE]
|
||||||
|
[B][SIZE=4][URL='https://github.com/CarmJos/UserPrefix/blob/master/src/main/resources/en_US/config.yml']Plugin Configuration[/URL] (config.yml)[/SIZE]
|
||||||
|
[/B]
|
||||||
|
Notice: The default configuration is based on Chinese. You can find the English Version [URL='https://github.com/CarmJos/UserPrefix/blob/master/src/main/resources/en_US/config.yml']here[/URL].
|
||||||
|
|
||||||
|
[code=YAML]
|
||||||
|
version: ${project.version}
|
||||||
|
|
||||||
|
debug: false #DEBUG OUT PUT
|
||||||
|
|
||||||
|
custom-storage:
|
||||||
|
# Custom storage location
|
||||||
|
# default location is "./prefixes"
|
||||||
|
# Support absolute file path , such as "/etc/minecraft/configurations/prefixes/"
|
||||||
|
enable: false
|
||||||
|
path: "prefixes/" # Must be a folder!
|
||||||
|
|
||||||
|
GUI:
|
||||||
|
title: "&f&lMy Prefixes List" # Title of the GUI
|
||||||
|
items:
|
||||||
|
next-page: # only show has next page
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: ARROW
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§fNext Page"
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "§fRight-Click to the last page"
|
||||||
|
previous-page: # only show has previous page
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: ARROW
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§fPrevious Page"
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "§fRight-Click to the first page"
|
||||||
|
|
||||||
|
functions:
|
||||||
|
# Whether to add a prefix to the top of the head,
|
||||||
|
# this method uses the scoreboard above the head,
|
||||||
|
# please turn it off if there is a conflict.
|
||||||
|
OnNamePrefix: true
|
||||||
|
# Automatic prefix select.
|
||||||
|
# When the player does not choose a prefix by himself,
|
||||||
|
# the prefix with the highest weight will be used automatically
|
||||||
|
autoUsePrefix: true
|
||||||
|
chat:
|
||||||
|
# Chat Function
|
||||||
|
# - I recommend using other chat plugins instead of using this plugin,
|
||||||
|
# - this plugin only provides very basic chat format placeholders.
|
||||||
|
# - Notice that: format must has “%1$s” and “%2$s” for PlayerName and Message (Bukkit Chat Event)
|
||||||
|
enable: false
|
||||||
|
format: "<%UserPrefix_prefix%%1$s> %2$s"
|
||||||
|
|
||||||
|
Sounds:
|
||||||
|
# Format is [SOUND_NAME:Volume:Pitch] or [SOUND_NAME:Volume] or [SOUND_NAME]
|
||||||
|
openGUI: "BLOCK_NOTE_BLOCK_PLING:1:1"
|
||||||
|
guiClick: "UI_BUTTON_CLICK"
|
||||||
|
prefixChange: "ENTITY_VILLAGER_YES"
|
||||||
|
prefixExpired: "ENTITY_VILLAGER_NO"
|
||||||
|
|
||||||
|
# The default prefix's weight is 0.
|
||||||
|
defaultPrefix:
|
||||||
|
name: "Default prefix"
|
||||||
|
content: "&b"
|
||||||
|
itemNotUsing:
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: NAME_TAG
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§fThe default prefix §f(Click to select)"
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "§a➥ Click to use"
|
||||||
|
itemUsing:
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: NAME_TAG
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§fThe default prefix"
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "§a✔ Selected"
|
||||||
|
[/code]
|
||||||
|
|
||||||
|
[B][SIZE=4][URL='https://github.com/CarmJos/UserPrefix/blob/master/src/main/resources/en_US/messages.yml']Messages Configuration[/URL] (messages.yml)[/SIZE][/B]
|
||||||
|
[code=YAML]
|
||||||
|
selected:
|
||||||
|
- "&7You have selected the &f%(name) &7as current prefix."
|
||||||
|
expired:
|
||||||
|
- "&7Your prefix &f%(oldName) &7has expired,"
|
||||||
|
- "&7Now the prefix is changed to &f%(newName) &7."
|
||||||
|
reload:
|
||||||
|
- "&a&lReload completed!&7costs &f%(time)ms&7."
|
||||||
|
help:
|
||||||
|
- "&3&lUserPrefixAdmin &fHelp"
|
||||||
|
- "&8#/upa&f list"
|
||||||
|
- "&8- &7Show configured prefixes."
|
||||||
|
- "&8#/upa&f reload"
|
||||||
|
- "&8- &7Reload configuration."
|
||||||
|
list-title:
|
||||||
|
- "&3&lUserPrefixAdmin &fList"
|
||||||
|
list-value:
|
||||||
|
- "&8#%(weight) &f%(identifier)"
|
||||||
|
- "&8- &7Name &r%(name) &7Perm &r%(permission)"
|
||||||
|
- "&8- &7Example&r %(content) %(sender_name)"
|
||||||
|
[/code]
|
||||||
|
|
||||||
|
[B][URL='https://github.com/CarmJos/UserPrefix/blob/master/src/main/resources/en_US/example-prefix.yml']Prefixes [/URL][B][URL='https://github.com/CarmJos/UserPrefix/blob/master/src/main/resources/en_US/example-prefix.yml']Configuration[/URL] [/B](/prefixes/*.yml)
|
||||||
|
[/B]
|
||||||
|
All prefixes are separate configuration files, stored in the [U]<Data Folder>/prefixes/[/U] for easy management.
|
||||||
|
|
||||||
|
Some symbols in file name may affect reading, please avoid using them.
|
||||||
|
|
||||||
|
[code]# identifier [Necessary]
|
||||||
|
# This will be used for data-storage.
|
||||||
|
identifier: "pro"
|
||||||
|
|
||||||
|
# Name [Necessary]
|
||||||
|
# Use in messages.
|
||||||
|
name: "&b&lPro&b"
|
||||||
|
|
||||||
|
# Content [Necessary]
|
||||||
|
# Use in Placeholders
|
||||||
|
content: "§b§lPro §b"
|
||||||
|
|
||||||
|
# Weight [Necessary]
|
||||||
|
# used for sorting in the GUI and TabList
|
||||||
|
# In GUI : the larger is displayed at the back
|
||||||
|
# At TabList : the larger is displayed at the top
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
# Permission [Unnecessary]
|
||||||
|
# If there is no permission for detection, everyone can use it,
|
||||||
|
# which means there is no need to configure "itemNoPermission"
|
||||||
|
# (because it is impossible to display items without permission at all)
|
||||||
|
permission: "yc.vip"
|
||||||
|
|
||||||
|
# itemHasPermission [Necessary]
|
||||||
|
# This Item will be displayed when player has permission
|
||||||
|
itemHasPermission:
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: DIAMOND
|
||||||
|
meta:
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: DIAMOND
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§b§lVIP Prefix"
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "§a➥ Click to use"
|
||||||
|
|
||||||
|
# itemUsing [Unnecessary]
|
||||||
|
# This Item will be displayed when the prefix is selected.
|
||||||
|
# If there is no such configuration, it will automatically display "itemHasPermission".
|
||||||
|
itemUsing:
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: DIAMOND
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§b§lVIP Prefix"
|
||||||
|
enchants:
|
||||||
|
PROTECTION_ENVIRONMENTAL: 1 #Add an enchantment so it looks like it’s selected
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "§a✔ Selected"
|
||||||
|
|
||||||
|
# itemNoPermission [Unnecessary]
|
||||||
|
# If player doesn't have the permission,this item will be displayed.
|
||||||
|
# If this item is not configured, it will not be displayed in the GUI when the player does not have permission to use it.
|
||||||
|
itemNoPermission:
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: INK_SACK
|
||||||
|
damage: 8
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§b§lVIP §c(Buy it!)"
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "§e✯ Buy the VIP to use it!"[/code]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[SIZE=5][B]Support and Donation[/B][/SIZE]
|
||||||
|
This project is support by the [URL='https://www.ycraft.cn/']YourCraft(你的世界)[/URL] . [URL='https://raw.githubusercontent.com/CarmJos/UserPrefix/master/img/team-logo.png'][IMG]https://raw.githubusercontent.com/CarmJos/UserPrefix/master/img/team-logo.png[/IMG][/URL]
|
||||||
|
|
||||||
|
[SIZE=5][B]Open source agreement[/B][/SIZE]
|
||||||
|
The source code of this project uses [URL='https://opensource.org/licenses/GPL-3.0']GNU General Public License v3.0[/URL] License.
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
name: 问题提交
|
||||||
|
about: 描述问题并提交,帮助我们对其进行检查与修复。
|
||||||
|
title: ''
|
||||||
|
labels: bug
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **问题简述**
|
||||||
|
用简短的话语描述一下大概问题。
|
||||||
|
|
||||||
|
### **问题来源**
|
||||||
|
描述一下通过哪些操作才发现的问题,如:
|
||||||
|
1. 打开 '...'
|
||||||
|
2. 点击了 '....'
|
||||||
|
3. 出现了报错 '....'
|
||||||
|
|
||||||
|
### **预期结果**(可选)
|
||||||
|
如果问题不发生,应该是什么情况
|
||||||
|
|
||||||
|
### **问题截图/问题报错**
|
||||||
|
如果有报错或输出,请提供截图。
|
||||||
|
|
||||||
|
### **操作环境**
|
||||||
|
请在后台输入 `version` 并复制相关输出。
|
||||||
|
|
||||||
|
|
||||||
|
### **其他补充**
|
||||||
|
如有其他补充,可以在这里描述。
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
name: 功能需求
|
||||||
|
about: 希望我们提供更多的功能。
|
||||||
|
title: ''
|
||||||
|
labels: enhancement
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **功能简述**
|
||||||
|
简单的描述一下你想要的功能
|
||||||
|
|
||||||
|
### **需求来源**
|
||||||
|
简单的描述一下为什么需要这个功能。
|
||||||
|
|
||||||
|
### **功能参考**(可选)
|
||||||
|
如果有相关功能的参考,如文本、截图,请提供给我们。
|
||||||
|
|
||||||
|
### **附加内容**
|
||||||
|
如果有什么小细节需要重点注意,请在这里告诉我们。
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
# For most projects, this workflow file will not need changing; you simply need
|
||||||
|
# to commit it to your repository.
|
||||||
|
#
|
||||||
|
# You may wish to alter this file to override the set of languages analyzed,
|
||||||
|
# or to provide custom queries or build logic.
|
||||||
|
#
|
||||||
|
# ******** NOTE ********
|
||||||
|
# We have attempted to detect the languages in your repository. Please check
|
||||||
|
# the `language` matrix defined below to confirm you have the correct set of
|
||||||
|
# supported CodeQL languages.
|
||||||
|
#
|
||||||
|
name: "CodeQL Analysis"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
pull_request:
|
||||||
|
# The branches below must be a subset of the branches above
|
||||||
|
branches: [ master ]
|
||||||
|
schedule:
|
||||||
|
- cron: '44 6 * * 4'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
language: [ 'java' ]
|
||||||
|
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||||
|
# Learn more about CodeQL language support at https://git.io/codeql-language-support
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
# Initializes the CodeQL tools for scanning.
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v1
|
||||||
|
with:
|
||||||
|
languages: ${{ matrix.language }}
|
||||||
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
|
# By default, queries listed here will override any specified in a config file.
|
||||||
|
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||||
|
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||||
|
|
||||||
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
|
- name: Autobuild
|
||||||
|
uses: github/codeql-action/autobuild@v1
|
||||||
|
|
||||||
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
|
# 📚 https://git.io/JvXDl
|
||||||
|
|
||||||
|
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||||
|
# and modify them (or add more) to build your code if your project
|
||||||
|
# uses a compiled language
|
||||||
|
|
||||||
|
#- run: |
|
||||||
|
# make bootstrap
|
||||||
|
# make release
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v1
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
|
||||||
|
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
|
||||||
|
|
||||||
|
name: Deploy & Upload
|
||||||
|
|
||||||
|
on:
|
||||||
|
# 支持手动触发构建
|
||||||
|
workflow_dispatch:
|
||||||
|
release:
|
||||||
|
# 创建release的时候触发
|
||||||
|
types: [ published ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: "Set up JDK"
|
||||||
|
uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
java-version: '11'
|
||||||
|
distribution: 'adopt'
|
||||||
|
cache: maven
|
||||||
|
server-id: github
|
||||||
|
server-username: MAVEN_USERNAME
|
||||||
|
server-password: MAVEN_TOKEN
|
||||||
|
|
||||||
|
- name: "Maven Deploy"
|
||||||
|
run: mvn -B deploy --file pom.xml -DskipTests
|
||||||
|
env:
|
||||||
|
MAVEN_USERNAME: ${{ github.repository_owner }}
|
||||||
|
MAVEN_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||||
|
|
||||||
|
- name: "Release Asset Upload"
|
||||||
|
id: upload-release-asset
|
||||||
|
uses: shogo82148/actions-upload-release-asset@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
upload_url: ${{ github.event.release.upload_url }}
|
||||||
|
asset_path: asset/*.jar
|
||||||
|
asset_content_type: application/java-archive
|
||||||
|
|
||||||
|
- name: "Javadoc Deploy Staging"
|
||||||
|
run: |
|
||||||
|
rm -rf docs
|
||||||
|
mkdir -vp docs
|
||||||
|
cp -vrf target/apidocs/* docs/
|
||||||
|
cp -vrf .documentation/JAVADOC-README.md docs/README.md
|
||||||
|
|
||||||
|
- name: "Generate the Javadoc sitemap"
|
||||||
|
id: sitemap
|
||||||
|
uses: cicirello/generate-sitemap@v1
|
||||||
|
with:
|
||||||
|
base-url-path: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}
|
||||||
|
path-to-root: docs
|
||||||
|
|
||||||
|
- name: "Output Javadoc stats"
|
||||||
|
run: |
|
||||||
|
echo "sitemap-path = ${{ steps.sitemap.outputs.sitemap-path }}"
|
||||||
|
echo "url-count = ${{ steps.sitemap.outputs.url-count }}"
|
||||||
|
echo "excluded-count = ${{ steps.sitemap.outputs.excluded-count }}"
|
||||||
|
|
||||||
|
- name: "Configure Git"
|
||||||
|
env:
|
||||||
|
DEPLOY_PRI: ${{secrets.DEPLOY_PRI}}
|
||||||
|
run: |
|
||||||
|
sudo timedatectl set-timezone "Asia/Shanghai"
|
||||||
|
mkdir -p ~/.ssh/
|
||||||
|
echo "$DEPLOY_PRI" > ~/.ssh/id_rsa
|
||||||
|
chmod 600 ~/.ssh/id_rsa
|
||||||
|
ssh-keyscan github.com >> ~/.ssh/known_hosts
|
||||||
|
git config --global user.name 'CarmJos'
|
||||||
|
git config --global user.email 'carm@carm.cc'
|
||||||
|
|
||||||
|
- name: "Commit Javadocs"
|
||||||
|
run: |
|
||||||
|
cd docs
|
||||||
|
git init
|
||||||
|
git remote add origin git@github.com:${{ github.repository }}.git
|
||||||
|
git checkout -b gh-pages
|
||||||
|
git add -A
|
||||||
|
git commit -m "API Document generated."
|
||||||
|
|
||||||
|
- name: "Push javadocs"
|
||||||
|
run: |
|
||||||
|
cd docs
|
||||||
|
git push origin HEAD:gh-pages --force
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
|
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
|
||||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
|
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
|
||||||
|
|
||||||
name: Java CI with Maven
|
name: Build & Tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
# 支持手动触发构建
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches: [ master ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -15,12 +14,26 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Set up JDK 11
|
- name: "Set up JDK"
|
||||||
uses: actions/setup-java@v2
|
uses: actions/setup-java@v2
|
||||||
with:
|
with:
|
||||||
java-version: '11'
|
java-version: '11'
|
||||||
distribution: 'adopt'
|
distribution: 'adopt'
|
||||||
cache: maven
|
cache: maven
|
||||||
- name: Build with Maven
|
server-id: github
|
||||||
run: mvn -B package --file pom.xml
|
server-username: MAVEN_USERNAME
|
||||||
|
server-password: MAVEN_TOKEN
|
||||||
|
- name: "Package"
|
||||||
|
run: mvn -B package --file pom.xml
|
||||||
|
env:
|
||||||
|
MAVEN_USERNAME: ${{ github.repository_owner }}
|
||||||
|
MAVEN_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||||
|
|
||||||
|
- name: "Target Staging"
|
||||||
|
run: mkdir staging && cp target/*.jar staging
|
||||||
|
- name: "Upload artifact"
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Artifact
|
||||||
|
path: staging
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
/.idea/
|
/.idea/
|
||||||
/target/
|
/target/
|
||||||
./*.iml
|
./*.iml
|
||||||
|
*.iml
|
||||||
|
asset/
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|

|
||||||
|
|
||||||
|
# UserPrefix Plugin
|
||||||
|
|
||||||
|
[](https://www.codefactor.io/repository/github/carmjos/userprefix)
|
||||||
|

|
||||||
|
[](https://opensource.org/licenses/GPL-3.0)
|
||||||
|
[](https://github.com/CarmJos/UserPrefix/actions/workflows/maven.yml)
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
Lightweight, efficient, and real-time user prefix system.
|
||||||
|
|
||||||
|
This plugin is implemented based on Spigot ,**Theoretically** support ALL MineCraft Versions.
|
||||||
|
|
||||||
|
The development of this plugin is based on Chinese which purpose is to help Chinese developers learn Bukkit plugin
|
||||||
|
development.
|
||||||
|
|
||||||
|
> This plugin has been published on [SpigotMC](https://www.spigotmc.org/resources/userprefix.96277/) .
|
||||||
|
|
||||||
|
> 本插件已在 [MCBBS](https://www.mcbbs.net/forum.php?mod=viewthread&tid=1261503) 上发布,欢迎中文用户来这里下载。
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- **[Necessary]** Plugin developed based on [Spigot-API](https://hub.spigotmc.org/stash/projects/SPIGOT)
|
||||||
|
and [BukkitAPI](http://bukkit.org/).
|
||||||
|
- **[Necessary]** Plugin data storage base on [LuckPerms](https://www.spigotmc.org/resources/luckperms.28140/).
|
||||||
|
- **[Recommend]** Placeholders based on [PlaceholderAPI](https://www.spigotmc.org/resources/6245/) .
|
||||||
|
|
||||||
|
For development dependencies, please see [Dependencies](https://github.com/CarmJos/UserPrefix/network/dependencies) .
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Theoretically** support ALL MineCraft Versions.
|
||||||
|
- Reloading the configuration will automatically refresh the prefix of all players.
|
||||||
|
- Real-time judgment and feedback to the player when permissions are changed.
|
||||||
|
- Configurable sounds and messages.
|
||||||
|
- The prefix icon can be configured as "Selected", "Has Permission" and “No Permission”.
|
||||||
|
- Item configuration is natively configured through ItemStack, which supports all MC settings!
|
||||||
|
- TabList is automatically sorted according to the weight of the prefix (if there is a conflict, it can be turned off)
|
||||||
|
- The prefix display on the player name (can be turned off if there has any conflict)
|
||||||
|
- Simple Chat Format Placeholder support. (Not Recommended)
|
||||||
|
- GUI with automatic sorting and page turning!
|
||||||
|
- Support PlaceholderAPI variables!
|
||||||
|
- Support [Hex Color](https://www.hexcolortool.com/)! (Version 1.16 and above) `&(#Color)`
|
||||||
|
- Example: LightSlateBlue `&(#8470FF)` 、 DarkSlateBlue `&(#483D8B)`
|
||||||
|
|
||||||
|
## Notice
|
||||||
|
|
||||||
|
### 1. Version support issues
|
||||||
|
|
||||||
|
This plugin theoretically supports all versions.
|
||||||
|
|
||||||
|
If the icon does not load, the sound cannot be played, etc., please check whether the type of the item and sound in the
|
||||||
|
configuration file exists in the current version.
|
||||||
|
|
||||||
|
Take the SOUND as an example. The sound that the villager said "OK" is "`VILLAGER_YES`" in the lower version, but it
|
||||||
|
becomes "`ENTITY_VILLAGER_YES`" in the higher version.
|
||||||
|
|
||||||
|
### 2. Scoreboard exception problem
|
||||||
|
|
||||||
|
The display of the prefix on the head and the sorting of the TabList both use the scoreboard API.
|
||||||
|
|
||||||
|
Please turn of the `functions.OnNamePrefix` in the configuration if there is a conflict.
|
||||||
|
|
||||||
|
### 3. Item icon configuration problem
|
||||||
|
|
||||||
|
Items are read through the ItemStack serialization method provided by Bukkit. For related configuration methods, please
|
||||||
|
refer to [ItemStack Serialization](https://www.spigotmc.org/wiki/itemstack-serialization/).
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
This plugin's Commands are based on Chinese!
|
||||||
|
**May support multi-language in the future.**
|
||||||
|
|
||||||
|
```text
|
||||||
|
/UserPrefix or /prefix #Open prefix GUI
|
||||||
|
/UserPrefixAdmin # View Admin Command Help
|
||||||
|
/UserPrefixAdmin reload # Reload Config
|
||||||
|
/UserPrefixAdmin list # List all configured prefixes.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Placeholders (PlaceholderAPI)
|
||||||
|
|
||||||
|
After installed the [PlaceholderAPI](https://github.com/PlaceholderAPI/PlaceholderAPI) , you can
|
||||||
|
type `/papi info UserPrefix` to see all the placeholders.
|
||||||
|
|
||||||
|
```text
|
||||||
|
# %UserPrefix_prefix%
|
||||||
|
- Get the content of the current prefix
|
||||||
|
# %UserPrefix_weight%
|
||||||
|
- Get the weight of the current prefix.
|
||||||
|
# %UserPrefix_identifier%
|
||||||
|
- Get the identifier of the current prefix.
|
||||||
|
# %UserPrefix_name%
|
||||||
|
- Get the name of the current prefix.
|
||||||
|
# %UserPrefix_has_<Identifier>%
|
||||||
|
- Determine whether the player has a certain prefix(true/false)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration files
|
||||||
|
|
||||||
|
### Plugin Configuration ([`config.yml`](src/main/resources/en_US/config.yml) .
|
||||||
|
|
||||||
|
Notice: The default configuration is based on Chinese. You can find
|
||||||
|
the [English Version here](src/main/resources/en_US/config.yml).
|
||||||
|
|
||||||
|
### Messages Configuration ([`messages.yml`](src/main/resources/en_US/messages.yml))
|
||||||
|
|
||||||
|
Please see the [Source File](src/main/resources/en_US/messages.yml) .
|
||||||
|
|
||||||
|
### Prefixes Configuration ([`prefixes/*.yml`](src/main/resources/en_US/example-prefix.yml))
|
||||||
|
|
||||||
|
All prefixes are separate configuration files, stored in the `<Data Folder>/prefixes/` for easy management.
|
||||||
|
|
||||||
|
Some symbols in file name may affect reading, please avoid using them.
|
||||||
|
|
||||||
|
## Support and Donation
|
||||||
|
|
||||||
|
This project is support by the [YourCraft(你的世界)](https://www.ycraft.cn) .
|
||||||
|

|
||||||
|
|
||||||
|
## Open source agreement
|
||||||
|
|
||||||
|
The source code of this project uses [GNU General Public License v3.0](https://opensource.org/licenses/GPL-3.0)
|
||||||
|
License.
|
||||||
|
|
||||||
@@ -1,17 +1,31 @@
|
|||||||

|

|
||||||
|
|
||||||
# 用户前缀系统插件
|
# 用户前缀系统插件
|
||||||
|
|
||||||
[](https://www.codefactor.io/repository/github/carmjos/userprefix)
|
[](https://www.codefactor.io/repository/github/carmjos/userprefix)
|
||||||
|

|
||||||
|
[](https://github.com/CarmJos/UserPrefix/releases)
|
||||||
[](https://github.com/CarmJos/UserPrefix/actions/workflows/maven.yml)
|
[](https://github.com/CarmJos/UserPrefix/actions/workflows/maven.yml)
|
||||||
|

|
||||||

|

|
||||||
|
|
||||||
轻便、高效、实时的用户前缀系统。
|
轻便、高效、实时的用户前缀系统。
|
||||||
|
|
||||||
本插件基于Spigot实现,**理论上支持全版本**。
|
本插件基于Spigot实现,**理论上支持全版本**。
|
||||||
|
|
||||||
|
The **English version** of the introduction is [here](README-en.md).
|
||||||
|
|
||||||
|
> 本插件已在 [MCBBS](https://www.mcbbs.net/forum.php?mod=viewthread&tid=1261503) 与 [SpigotMC](https://www.spigotmc.org/resources/userprefix-hex-color-support-all-version.96277/) 上发布。
|
||||||
|
|
||||||
|
## 示例
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## 依赖
|
## 依赖
|
||||||
|
|
||||||
- **[必须]** 插件本体基于 [Spigot-API](https://hub.spigotmc.org/stash/projects/SPIGOT)、[BukkitAPI](http://bukkit.org/) 实现。
|
- **[必须]** 插件本体基于 [Spigot-API](https://hub.spigotmc.org/stash/projects/SPIGOT)、[BukkitAPI](http://bukkit.org/) 实现。
|
||||||
- **[必须]** 数据部分基于 [LuckPerms](https://www.spigotmc.org/resources/luckperms.28140/) 实现。
|
- **[必须]** 数据部分基于 [LuckPerms](https://www.spigotmc.org/resources/luckperms.28140/) 实现。
|
||||||
- [选配] 变量部分基于 [PlaceholderAPI](https://www.spigotmc.org/resources/6245/) 实现。
|
- **[推荐]** 变量部分基于 [PlaceholderAPI](https://www.spigotmc.org/resources/6245/) 实现。
|
||||||
|
|
||||||
详细依赖列表可见 [Dependencies](https://github.com/CarmJos/UserPrefix/network/dependencies) 。
|
详细依赖列表可见 [Dependencies](https://github.com/CarmJos/UserPrefix/network/dependencies) 。
|
||||||
|
|
||||||
@@ -19,15 +33,19 @@
|
|||||||
|
|
||||||
- 理论上全版本支持!
|
- 理论上全版本支持!
|
||||||
- 游戏内重载配置文件并实时更新到玩家!
|
- 游戏内重载配置文件并实时更新到玩家!
|
||||||
- 当玩家权限变更时会实时监测前缀,若权限不足则自动更换前缀并提示!
|
- 当玩家权限变更时会实时监测前缀,若权限不足则自动更换前缀并提示
|
||||||
- 可配置的声音、消息!
|
- 可配置的声音、消息!
|
||||||
- 前缀图标可配置“选中”、“有权限”与“无权限”三种状态的物品
|
- 前缀图标可配置“选中”、“有权限”与“无权限”三种状态的物品
|
||||||
- 物品的配置通过ItemStack原生配置,支持MC所有的设定!
|
- 物品的配置通过ItemStack原生配置,支持MC所有的设定!
|
||||||
- 具体的设定请参考其他文档哦~
|
- 具体的设定请参考其他文档哦~
|
||||||
- TabList自动按照前缀的权重排序 (如有冲突可关掉)
|
- TabList自动按照前缀的权重排序 (如有冲突可关掉)
|
||||||
- 玩家头顶前缀显示 (如有冲突可关掉)
|
- 玩家头顶前缀显示 (如有冲突可关掉)
|
||||||
- 自动排序,且可翻页的GUI
|
- 简单的聊天变量修改功能!(不推荐使用) `[自 v2.1.0 版本起]`
|
||||||
- 支持PlaceholderAPI变量
|
- 自动排序,且可翻页的GUI!
|
||||||
|
- 支持PlaceholderAPI变量!(凡支持的都可以使用,如BungeeTabListPlus)
|
||||||
|
- 支持[Hex颜色](https://www.hexcolortool.com/)!(1.16以上版本) `[自 v1.2.3 版本起]`
|
||||||
|
- 格式: `&(#颜色代码)`
|
||||||
|
- 示例: LightSlateBlue `&(#8470FF)` 、 DarkSlateBlue `&(#483D8B)`
|
||||||
|
|
||||||
## 注意事项
|
## 注意事项
|
||||||
|
|
||||||
@@ -44,6 +62,7 @@
|
|||||||
如有冲突导致其他插件的计分板无法显示,请关掉配置文件中`functions.OnNamePrefix`。
|
如有冲突导致其他插件的计分板无法显示,请关掉配置文件中`functions.OnNamePrefix`。
|
||||||
|
|
||||||
### 3. 物品图标配置问题
|
### 3. 物品图标配置问题
|
||||||
|
|
||||||
物品相关均通过Bukkit提供的ItemStack序列化方法读取,相关配置方式请参考[ItemStack Serialization(物品序列化)](https://www.spigotmc.org/wiki/itemstack-serialization/)。
|
物品相关均通过Bukkit提供的ItemStack序列化方法读取,相关配置方式请参考[ItemStack Serialization(物品序列化)](https://www.spigotmc.org/wiki/itemstack-serialization/)。
|
||||||
|
|
||||||
## 指令
|
## 指令
|
||||||
@@ -78,122 +97,67 @@
|
|||||||
|
|
||||||
## 配置文件示例
|
## 配置文件示例
|
||||||
|
|
||||||
```yaml
|
### 基础配置文件 ([`config.yml`](src/main/resources/config.yml))
|
||||||
version: 1.0.0-SNAPSHOT # 配置文件版本,一般不会动。
|
|
||||||
|
|
||||||
debug: false #debug输出,开发者用的
|
详见 [源文件](src/main/resources/messages.yml) 。
|
||||||
|
|
||||||
functions:
|
### 消息配置文件 ([`messages.yml`](src/main/resources/messages.yml))
|
||||||
OnNamePrefix: true # 是否给头顶上添加前缀,该方法用到了头顶的那个计分板,如有冲突请关掉哦~
|
|
||||||
autoUsePrefix: true # 自动前缀显示 当玩家没有自己选择一个前缀的时候,会自动使用所拥有的的前缀中权重最高的那一个
|
|
||||||
|
|
||||||
messages:
|
详见 [源文件](src/main/resources/messages.yml) 。
|
||||||
selected:
|
|
||||||
- "&7您选择了 &f%(name) &7作为当前显示的前缀。"
|
|
||||||
expired:
|
|
||||||
- "&7您先前使用的前缀 &f%(oldName) &7已到期。"
|
|
||||||
- "&7现在已为您重新调整为 &f%(newName) &7。"
|
|
||||||
|
|
||||||
Sounds: #相关的声音,注释掉则不播放声音
|
### 前缀配置文件 ([`prefixes/*.yml`](src/main/resources/prefixes/example-prefix.yml))
|
||||||
# 格式为 【声音名:音量:音调】 或 【声音名:音量】 或 【声音名】
|
|
||||||
openGUI: "BLOCK_NOTE_BLOCK_PLING:1:1"
|
|
||||||
guiClick: "UI_BUTTON_CLICK"
|
|
||||||
prefixChange: "ENTITY_VILLAGER_YES"
|
|
||||||
prefixExpired: "ENTITY_VILLAGER_NO"
|
|
||||||
|
|
||||||
# 默认前缀的配置
|
所有前缀均为单独的配置文件,存放于 `插件配置目录/prefixes` 下,便于管理。
|
||||||
# 默认前缀的权重为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" # [必须] 名字(切换的时候左下角会弹提示 用的就是这个名字)
|
您可以 [点击这里](src/main/resources/prefixes/example-prefix.yml) 查看示例前缀配置文件。
|
||||||
content: "§b§lPro §b" # [必须] 显示在名字前面的内容
|
|
||||||
weight: 1 # [必须] 权重,用于GUI里面的排序(越大显示在越后面)和自动前缀显示
|
## 使用统计
|
||||||
permission: "yc.pro" # [非必须] 检测的权限,如果没有就是人人都能用,也代表不用配置“itemNoPermission”了(因为压根不可能显示没权限时候的物品)
|
|
||||||
itemHasPermission:
|
[](https://bstats.org/plugin/bukkit/UserPrefix/13776)
|
||||||
# [必须] 当有权限的时候会显示这个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+会员以使用该前缀!"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 支持与捐赠
|
## 支持与捐赠
|
||||||
|
|
||||||
本项目由 [YourCraft(你的世界)](https://www.ycraft.cn) 团队提供长期支持与维护。
|
本项目由 [YourCraft(你的世界)](https://www.ycraft.cn) 团队提供长期支持与维护。
|
||||||

|

|
||||||
|
|
||||||
若您觉得本插件做的不错,您可以捐赠支持我!
|
若您觉得本插件做的不错,您可以捐赠支持我!
|
||||||
|
|
||||||
感谢您成为开源项目的支持者!
|
感谢您成为开源项目的支持者!
|
||||||
|
|
||||||
<img height=25% width=25% src="https://raw.githubusercontent.com/CarmJos/UserPrefix/master/img/PAY.jpg" />
|
<img height=25% width=25% src="https://raw.githubusercontent.com/CarmJos/CarmJos/main/img/donate-code.jpg" alt=""/>
|
||||||
|
|
||||||
## 开源协议
|
## 开源协议
|
||||||
本项目源码采用 [GNU General Public License v3.0](https://opensource.org/licenses/gpl-3.0.php) 开源协议。
|
|
||||||
|
|
||||||
|
本项目源码采用 [GNU General Public License v3.0](https://opensource.org/licenses/GPL-3.0) 开源协议。
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>关于 GPL 协议</summary>
|
||||||
|
|
||||||
|
> GNU General Public Licence (GPL) 有可能是开源界最常用的许可模式。GPL 保证了所有开发者的权利,同时为使用者提供了足够的复制,分发,修改的权利:
|
||||||
|
>
|
||||||
|
> #### 可自由复制
|
||||||
|
> 你可以将软件复制到你的电脑,你客户的电脑,或者任何地方。复制份数没有任何限制。
|
||||||
|
> #### 可自由分发
|
||||||
|
> 在你的网站提供下载,拷贝到U盘送人,或者将源代码打印出来从窗户扔出去(环保起见,请别这样做)。
|
||||||
|
> #### 可以用来盈利
|
||||||
|
> 你可以在分发软件的时候收费,但你必须在收费前向你的客户提供该软件的 GNU GPL 许可协议,以便让他们知道,他们可以从别的渠道免费得到这份软件,以及你收费的理由。
|
||||||
|
> #### 可自由修改
|
||||||
|
> 如果你想添加或删除某个功能,没问题,如果你想在别的项目中使用部分代码,也没问题,唯一的要求是,使用了这段代码的项目也必须使用 GPL 协议。
|
||||||
|
>
|
||||||
|
> 需要注意的是,分发的时候,需要明确提供源代码和二进制文件,另外,用于某些程序的某些协议有一些问题和限制,你可以看一下 @PierreJoye 写的 Practical Guide to GPL Compliance 一文。使用 GPL 协议,你必须在源代码代码中包含相应信息,以及协议本身。
|
||||||
|
>
|
||||||
|
> *以上文字来自 [五种开源协议GPL,LGPL,BSD,MIT,Apache](https://www.oschina.net/question/54100_9455) 。*
|
||||||
|
</details>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```text
|
||||||
|
_ _ _____ __ _
|
||||||
|
| | | | | __ \ / _|(_)
|
||||||
|
| | | | ___ ___ _ __ | |__) |_ __ ___ | |_ _ __ __
|
||||||
|
| | | |/ __| / _ \| '__|| ___/| '__|/ _ \| _|| |\ \/ /
|
||||||
|
| |__| |\__ \| __/| | | | | | | __/| | | | > <
|
||||||
|
\____/ |___/ \___||_| |_| |_| \___||_| |_|/_/\_\
|
||||||
|
```
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 58 KiB |
@@ -4,23 +4,60 @@
|
|||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>cc.carm.plugin</groupId>
|
|
||||||
<artifactId>UserPrefix</artifactId>
|
|
||||||
<version>1.2.2-SNAPSHOT</version>
|
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>8</maven.compiler.source>
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
<maven.compiler.target>8</maven.compiler.target>
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
<maven.deploy.skip>true</maven.deploy.skip>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<groupId>cc.carm.plugin</groupId>
|
||||||
|
<artifactId>userprefix</artifactId>
|
||||||
|
<version>v2.3.2</version>
|
||||||
|
|
||||||
|
<name>UserPrefix</name>
|
||||||
|
<description>轻便、高效、实时的用户前缀系统。</description>
|
||||||
|
<url>https://github.com/CarmJos/UserPrefix</url>
|
||||||
|
|
||||||
|
<issueManagement>
|
||||||
|
<system>GitHub Issues</system>
|
||||||
|
<url>${project.url}/issues</url>
|
||||||
|
</issueManagement>
|
||||||
|
|
||||||
|
<ciManagement>
|
||||||
|
<system>GitHub Actions</system>
|
||||||
|
<url>${project.url}/actions/workflows/maven.yml</url>
|
||||||
|
</ciManagement>
|
||||||
|
|
||||||
|
<developers>
|
||||||
|
<developer>
|
||||||
|
<id>CarmJos</id>
|
||||||
|
<name>Carm Jos</name>
|
||||||
|
<email>carm@carm.cc</email>
|
||||||
|
<url>https://work.carm.cc</url>
|
||||||
|
<roles>
|
||||||
|
<role>Main Developer</role>
|
||||||
|
</roles>
|
||||||
|
</developer>
|
||||||
|
</developers>
|
||||||
|
|
||||||
|
<organization>
|
||||||
|
<name>YourCraft你的世界</name>
|
||||||
|
<url>https://www.ycraft.cn/</url>
|
||||||
|
</organization>
|
||||||
|
|
||||||
|
<licenses>
|
||||||
|
<license>
|
||||||
|
<name>GNU General Public License v3.0</name>
|
||||||
|
<url>https://opensource.org/licenses/GPL-3.0</url>
|
||||||
|
</license>
|
||||||
|
</licenses>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
|
|
||||||
<repository>
|
<repository>
|
||||||
<id>spigotmc-repo</id>
|
<id>spigot-repo</id>
|
||||||
<url>https://hub.spigotmc.org/nexus/content/repositories/public/</url>
|
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
|
||||||
<repository>
|
<repository>
|
||||||
@@ -28,11 +65,6 @@
|
|||||||
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
|
||||||
<repository>
|
|
||||||
<id>lss233-repo</id>
|
|
||||||
<url>https://lss233.littleservice.cn/repositories/minecraft</url>
|
|
||||||
</repository>
|
|
||||||
|
|
||||||
<repository>
|
<repository>
|
||||||
<id>oss-repo</id>
|
<id>oss-repo</id>
|
||||||
<url>https://oss.sonatype.org/content/groups/public/</url>
|
<url>https://oss.sonatype.org/content/groups/public/</url>
|
||||||
@@ -47,13 +79,29 @@
|
|||||||
<id>maven-central</id>
|
<id>maven-central</id>
|
||||||
<url>https://repo1.maven.org/maven2/</url>
|
<url>https://repo1.maven.org/maven2/</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
|
||||||
|
<repository>
|
||||||
|
<id>github</id>
|
||||||
|
<name>GitHub Packages</name>
|
||||||
|
<url>https://maven.pkg.github.com/CarmJos/${project.name}</url>
|
||||||
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
|
<distributionManagement>
|
||||||
|
<downloadUrl>${project.url}/releases</downloadUrl>
|
||||||
|
<repository>
|
||||||
|
<id>github</id>
|
||||||
|
<name>GitHub Packages</name>
|
||||||
|
<url>https://maven.pkg.github.com/CarmJos/${project.name}</url>
|
||||||
|
</repository>
|
||||||
|
</distributionManagement>
|
||||||
|
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.spigotmc</groupId>
|
<groupId>org.spigotmc</groupId>
|
||||||
<artifactId>spigot</artifactId>
|
<artifactId>spigot-api</artifactId>
|
||||||
<version>1.17-R0.1-SNAPSHOT</version>
|
<version>1.17-R0.1-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
@@ -72,16 +120,112 @@
|
|||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bstats</groupId>
|
||||||
|
<artifactId>bstats-bukkit</artifactId>
|
||||||
|
<version>2.2.1</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>4.13</version>
|
<version>4.13.2</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<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>
|
||||||
|
<charset>UTF-8</charset>
|
||||||
|
<docencoding>UTF-8</docencoding>
|
||||||
|
<locale>zh_CN</locale>
|
||||||
|
</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-source-plugin</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>jar-no-fork</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</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>
|
||||||
|
<finalName>${project.name}-${project.version}</finalName>
|
||||||
|
<outputDirectory>${project.basedir}/asset/</outputDirectory>
|
||||||
|
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<relocations>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.bstats</pattern>
|
||||||
|
<!-- Replace this with your package! -->
|
||||||
|
<shadedPattern>cc.carm.plugin.userprefix.bstats</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
</relocations>
|
||||||
|
<filters>
|
||||||
|
<filter>
|
||||||
|
<artifact>*:*</artifact>
|
||||||
|
<excludes>
|
||||||
|
<exclude>META-INF/MANIFEST.MF</exclude>
|
||||||
|
<exclude>META-INF/*.txt</exclude>
|
||||||
|
</excludes>
|
||||||
|
</filter>
|
||||||
|
</filters>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
@@ -91,82 +235,6 @@
|
|||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</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>
|
<resources>
|
||||||
<resource>
|
<resource>
|
||||||
<directory>src/main/resources</directory>
|
<directory>src/main/resources</directory>
|
||||||
|
|||||||
@@ -2,8 +2,9 @@ package cc.carm.plugin.userprefix;
|
|||||||
|
|
||||||
import cc.carm.plugin.userprefix.command.UserPrefixAdminCommand;
|
import cc.carm.plugin.userprefix.command.UserPrefixAdminCommand;
|
||||||
import cc.carm.plugin.userprefix.command.UserPrefixCommand;
|
import cc.carm.plugin.userprefix.command.UserPrefixCommand;
|
||||||
import cc.carm.plugin.userprefix.configuration.PrefixConfig;
|
import cc.carm.plugin.userprefix.configuration.PluginConfig;
|
||||||
import cc.carm.plugin.userprefix.hooker.UserPrefixExpansion;
|
import cc.carm.plugin.userprefix.hooker.UserPrefixExpansion;
|
||||||
|
import cc.carm.plugin.userprefix.listener.ChatListener;
|
||||||
import cc.carm.plugin.userprefix.listener.UserListener;
|
import cc.carm.plugin.userprefix.listener.UserListener;
|
||||||
import cc.carm.plugin.userprefix.listener.processor.UserNodeUpdateProcessor;
|
import cc.carm.plugin.userprefix.listener.processor.UserNodeUpdateProcessor;
|
||||||
import cc.carm.plugin.userprefix.manager.ConfigManager;
|
import cc.carm.plugin.userprefix.manager.ConfigManager;
|
||||||
@@ -11,93 +12,149 @@ import cc.carm.plugin.userprefix.manager.PrefixManager;
|
|||||||
import cc.carm.plugin.userprefix.manager.ServiceManager;
|
import cc.carm.plugin.userprefix.manager.ServiceManager;
|
||||||
import cc.carm.plugin.userprefix.manager.UserManager;
|
import cc.carm.plugin.userprefix.manager.UserManager;
|
||||||
import cc.carm.plugin.userprefix.util.ColorParser;
|
import cc.carm.plugin.userprefix.util.ColorParser;
|
||||||
|
import cc.carm.plugin.userprefix.util.MessageUtil;
|
||||||
import net.luckperms.api.event.user.UserDataRecalculateEvent;
|
import net.luckperms.api.event.user.UserDataRecalculateEvent;
|
||||||
|
import org.bstats.bukkit.Metrics;
|
||||||
|
import org.bstats.charts.SimplePie;
|
||||||
|
import org.bstats.charts.SingleLineChart;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.PluginCommand;
|
||||||
|
import org.bukkit.command.TabCompleter;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class Main extends JavaPlugin {
|
public class Main extends JavaPlugin {
|
||||||
|
|
||||||
private static Main instance;
|
private static Main instance;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
instance = this;
|
instance = this;
|
||||||
|
showPluginName();
|
||||||
|
log(getName() + " " + getDescription().getVersion() + " &7开始加载...");
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
log(getName() + " " + getDescription().getVersion() + " &7开始加载...");
|
log("加载配置文件...");
|
||||||
long startTime = System.currentTimeMillis();
|
ConfigManager.initConfig();
|
||||||
|
PrefixManager.init();
|
||||||
|
|
||||||
log("加载配置文件...");
|
log("注册指令...");
|
||||||
ConfigManager.initConfig();
|
registerCommand("UserPrefix", new UserPrefixCommand());
|
||||||
PrefixManager.init();
|
registerCommand("UserPrefixAdmin", new UserPrefixAdminCommand());
|
||||||
|
|
||||||
log("注册指令...");
|
log("注册监听器...");
|
||||||
Bukkit.getPluginCommand("UserPrefix").setExecutor(new UserPrefixCommand());
|
regListener(new UserListener());
|
||||||
Bukkit.getPluginCommand("UserPrefixAdmin").setExecutor(new UserPrefixAdminCommand());
|
regListener(new ChatListener());
|
||||||
|
ServiceManager.getService().getEventBus().subscribe(this, UserDataRecalculateEvent.class, UserNodeUpdateProcessor::process);
|
||||||
|
|
||||||
log("注册监听器...");
|
if (MessageUtil.hasPlaceholderAPI()) {
|
||||||
regListener(new UserListener());
|
log("注册变量...");
|
||||||
ServiceManager.getService().getEventBus().subscribe(this, UserDataRecalculateEvent.class, UserNodeUpdateProcessor::process);
|
new UserPrefixExpansion(getInstance()).register();
|
||||||
|
} else {
|
||||||
|
log("未安装 PlaceholderAPI 不进行变量注册...");
|
||||||
|
log("若您想使用变量进行前缀的显示,请安装PlaceholderAPI!");
|
||||||
|
}
|
||||||
|
|
||||||
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
|
if (PluginConfig.METRICS.get()) {
|
||||||
log("注册变量...");
|
log("启用统计数据...");
|
||||||
new UserPrefixExpansion(getInstance()).register();
|
Metrics metrics = new Metrics(this, 13776);
|
||||||
} else {
|
metrics.addCustomChart(new SingleLineChart("active_prefixes", () -> PrefixManager.getPrefixes().size()));
|
||||||
log("未安装 PlaceholderAPI 不进行变量注册...");
|
metrics.addCustomChart(new SimplePie("custom_storage", () -> PluginConfig.CustomStorage.ENABLE.get() ? "ENABLE" : "DISABLE"));
|
||||||
log("若您想使用变量进行前缀的显示,请安装PlaceholderAPI!");
|
metrics.addCustomChart(new SimplePie("lp_version", () -> ServiceManager.getService().getPluginMetadata().getVersion()));
|
||||||
}
|
metrics.addCustomChart(new SimplePie("papi_version", () -> {
|
||||||
|
Plugin plugin = Bukkit.getPluginManager().getPlugin("PlaceholderAPI");
|
||||||
|
if (plugin == null) return "Not installed";
|
||||||
|
else return plugin.getDescription().getVersion();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
log("加载完成 ,共耗时 " + (System.currentTimeMillis() - startTime) + " ms 。");
|
||||||
|
|
||||||
|
showAD();
|
||||||
|
|
||||||
|
if (Bukkit.getOnlinePlayers().size() > 0) {
|
||||||
|
Bukkit.getOnlinePlayers().forEach(UserManager::initPlayer); // 适配热重载
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
log("加载完成 ,共耗时 " + (System.currentTimeMillis() - startTime) + " ms 。");
|
}
|
||||||
|
|
||||||
showAD();
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
showPluginName();
|
||||||
|
log(getName() + " " + getDescription().getVersion() + " 开始卸载...");
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
if (Bukkit.getOnlinePlayers().size() > 0) {
|
log("卸载监听器...");
|
||||||
Bukkit.getOnlinePlayers().forEach(UserManager::initPlayer); // 适配热重载
|
Bukkit.getServicesManager().unregisterAll(this);
|
||||||
}
|
|
||||||
|
|
||||||
}
|
log("卸载完成 ,共耗时 " + (System.currentTimeMillis() - startTime) + " ms 。");
|
||||||
|
|
||||||
@Override
|
showAD();
|
||||||
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());
|
||||||
|
}
|
||||||
|
|
||||||
showAD();
|
public static void log(String message) {
|
||||||
|
Bukkit.getConsoleSender().sendMessage(ColorParser.parse("[" + getInstance().getName() + "] " + message));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
public static void debug(String message) {
|
||||||
|
if (PluginConfig.DEBUG.get()) {
|
||||||
|
log("[DEBUG] " + message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
public static void error(String message) {
|
||||||
* 注册监听器
|
log("&c[ERROR] &r" + message);
|
||||||
*
|
}
|
||||||
* @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) {
|
public static JavaPlugin getInstance() {
|
||||||
if (PrefixConfig.DEBUG.get()) {
|
return instance;
|
||||||
log("[DEBUG] " + ColorParser.parseColor(message));
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JavaPlugin getInstance() {
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showAD() {
|
public static void registerCommand(String commandName,
|
||||||
log("&7感谢您使用 &3&lUserPrefix " + getDescription().getVersion() + "&7!");
|
@NotNull CommandExecutor executor) {
|
||||||
log("&7本插件由 &b&lYourCraft &7提供长期支持与维护。");
|
registerCommand(commandName, executor, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void registerCommand(String commandName,
|
||||||
|
@NotNull CommandExecutor executor,
|
||||||
|
@Nullable TabCompleter tabCompleter) {
|
||||||
|
PluginCommand command = Bukkit.getPluginCommand(commandName);
|
||||||
|
if (command == null) return;
|
||||||
|
command.setExecutor(executor);
|
||||||
|
if (tabCompleter != null) command.setTabCompleter(tabCompleter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showPluginName() {
|
||||||
|
log("&b _ _ &f _____ __ _ ");
|
||||||
|
log("&b| | | | &f| __ \\ / _|(_) ");
|
||||||
|
log("&b| | | | ___ ___ _ __ &f| |__) |_ __ ___ | |_ _ __ __");
|
||||||
|
log("&b| | | |/ __| / _ \\| '__|&f| ___/| '__|/ _ \\| _|| |\\ \\/ /");
|
||||||
|
log("&b| |__| |\\__ \\| __/| | &f| | | | | __/| | | | > < ");
|
||||||
|
log("&b \\____/ |___/ \\___||_| &f|_| |_| \\___||_| |_|/_/\\_\\");
|
||||||
|
log("&8 ");
|
||||||
|
log("&8> &f" + getDescription().getWebsite());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showAD() {
|
||||||
|
log("&7感谢您使用 &3&lUserPrefix " + getDescription().getVersion() + "&7!");
|
||||||
|
log("&7本插件由 &b&lYourCraft &7提供长期支持与维护。");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
package cc.carm.plugin.userprefix.command;
|
package cc.carm.plugin.userprefix.command;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.configuration.PluginConfig;
|
||||||
import cc.carm.plugin.userprefix.manager.ConfigManager;
|
import cc.carm.plugin.userprefix.manager.ConfigManager;
|
||||||
import cc.carm.plugin.userprefix.manager.PrefixManager;
|
import cc.carm.plugin.userprefix.manager.PrefixManager;
|
||||||
import cc.carm.plugin.userprefix.manager.UserManager;
|
import cc.carm.plugin.userprefix.manager.UserManager;
|
||||||
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
|
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
|
||||||
import cc.carm.plugin.userprefix.ui.PrefixSelectGUI;
|
import cc.carm.plugin.userprefix.ui.PrefixSelectGUI;
|
||||||
import cc.carm.plugin.userprefix.util.ColorParser;
|
import cc.carm.plugin.userprefix.util.MessageUtil;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandExecutor;
|
import org.bukkit.command.CommandExecutor;
|
||||||
@@ -21,18 +22,28 @@ public class UserPrefixAdminCommand implements CommandExecutor {
|
|||||||
if (args.length == 1) {
|
if (args.length == 1) {
|
||||||
String aim = args[0];
|
String aim = args[0];
|
||||||
if (aim.equalsIgnoreCase("list")) {
|
if (aim.equalsIgnoreCase("list")) {
|
||||||
sender.sendMessage(ColorParser.parseColor("&3&l用户前缀系统 &f前缀列表"));
|
MessageUtil.sendWithPlaceholders(sender, PluginConfig.Messages.LIST_TITLE.get());
|
||||||
for (ConfiguredPrefix value : PrefixManager.getPrefixes().values()) {
|
for (ConfiguredPrefix value : PrefixManager.getPrefixes().values()) {
|
||||||
sender.sendMessage(ColorParser.parseColor("&8#" + value.getWeight() + " &f" + value.getIdentifier()));
|
MessageUtil.sendWithPlaceholders(
|
||||||
sender.sendMessage(ColorParser.parseColor("&8- &7显示名 &r" + value.getName() + " &7权限&r " + value.getPermission()));
|
sender, PluginConfig.Messages.LIST_VALUE.get(),
|
||||||
sender.sendMessage(ColorParser.parseColor("&8- &7内容示例&r " + value.getContent() + sender.getName()));
|
new String[]{
|
||||||
|
"%(weight)", "%(identifier)",
|
||||||
|
"%(name)", "%(permission)",
|
||||||
|
"%(content)", "%(sender_name)"
|
||||||
|
},
|
||||||
|
new Object[]{
|
||||||
|
value.getWeight(), value.getIdentifier(),
|
||||||
|
value.getName(), value.getPermission(),
|
||||||
|
value.getContent(), sender.getName()
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if (aim.equalsIgnoreCase("reload")) {
|
} else if (aim.equalsIgnoreCase("reload")) {
|
||||||
long s1 = System.currentTimeMillis();
|
long s1 = System.currentTimeMillis();
|
||||||
PrefixSelectGUI.closeAll(); // 关掉所有正在显示的前缀列表
|
PrefixSelectGUI.closeAll(); // 关掉所有正在显示的前缀列表
|
||||||
ConfigManager.reloadConfig(); // 重载配置文件
|
ConfigManager.reload(); // 重载配置文件
|
||||||
PrefixManager.loadConfiguredPrefixes(); //加载重载后了的配置文件
|
PrefixManager.loadPrefixes(); //加载重载后了的前缀配置
|
||||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
||||||
UserManager.checkPrefix(onlinePlayer, false);
|
UserManager.checkPrefix(onlinePlayer, false);
|
||||||
/*
|
/*
|
||||||
@@ -42,7 +53,10 @@ public class UserPrefixAdminCommand implements CommandExecutor {
|
|||||||
*/
|
*/
|
||||||
UserManager.updatePrefixView(onlinePlayer, false);
|
UserManager.updatePrefixView(onlinePlayer, false);
|
||||||
}
|
}
|
||||||
sender.sendMessage(ColorParser.parseColor("&a&l重载完成!&7共耗时 &f" + (System.currentTimeMillis() - s1) + " ms&7。"));
|
MessageUtil.sendWithPlaceholders(
|
||||||
|
sender, PluginConfig.Messages.RELOAD.get(),
|
||||||
|
new String[]{"%(time)"}, new Object[]{(System.currentTimeMillis() - s1)}
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return help(sender);
|
return help(sender);
|
||||||
@@ -51,11 +65,7 @@ public class UserPrefixAdminCommand implements CommandExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean help(CommandSender sender) {
|
public static boolean help(CommandSender sender) {
|
||||||
sender.sendMessage(ColorParser.parseColor("&3&l用户前缀系统 &f帮助"));
|
MessageUtil.send(sender, PluginConfig.Messages.HELP.get());
|
||||||
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package cc.carm.plugin.userprefix.command;
|
package cc.carm.plugin.userprefix.command;
|
||||||
|
|
||||||
import cc.carm.plugin.userprefix.ui.PrefixSelectGUI;
|
import cc.carm.plugin.userprefix.ui.PrefixSelectGUI;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandExecutor;
|
import org.bukkit.command.CommandExecutor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
@@ -14,6 +15,15 @@ public class UserPrefixCommand implements CommandExecutor {
|
|||||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) {
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) {
|
||||||
if (sender instanceof Player) {
|
if (sender instanceof Player) {
|
||||||
PrefixSelectGUI.open((Player) sender);
|
PrefixSelectGUI.open((Player) sender);
|
||||||
|
} else {
|
||||||
|
if (strings.length != 1) {
|
||||||
|
sender.sendMessage("输入 /prefix <ID> 为玩家打开前缀GUI。");
|
||||||
|
} else {
|
||||||
|
Player player = Bukkit.getPlayer(strings[0]);
|
||||||
|
if (player != null) {
|
||||||
|
PrefixSelectGUI.open(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package cc.carm.plugin.userprefix.configuration;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.configuration.message.ConfigMessageList;
|
||||||
|
import cc.carm.plugin.userprefix.configuration.values.ConfigSound;
|
||||||
|
import cc.carm.plugin.userprefix.configuration.values.ConfigValue;
|
||||||
|
import cc.carm.plugin.userprefix.util.ItemStackFactory;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
public class PluginConfig {
|
||||||
|
|
||||||
|
public static ConfigValue<Boolean> DEBUG = new ConfigValue<>("debug", Boolean.class, false);
|
||||||
|
|
||||||
|
public static ConfigValue<Boolean> METRICS = new ConfigValue<>("metrics", Boolean.class, true);
|
||||||
|
|
||||||
|
public static class CustomStorage {
|
||||||
|
|
||||||
|
public static ConfigValue<Boolean> ENABLE = new ConfigValue<>("custom-storage.enable", Boolean.class, false);
|
||||||
|
|
||||||
|
public static ConfigValue<String> PATH = new ConfigValue<>("custom-storage.path", String.class, "prefixes/");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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 Chat {
|
||||||
|
|
||||||
|
public static ConfigValue<Boolean> ENABLE = new ConfigValue<>("functions.chat.enable", Boolean.class, false);
|
||||||
|
public static ConfigValue<String> FORMAT = new ConfigValue<>("functions.chat.format", String.class, "<%1$s> %2$s");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class GUI {
|
||||||
|
|
||||||
|
public static ConfigValue<String> TITLE = new ConfigValue<>("GUI.title", String.class, "&f&l我的前缀 &8| 列表");
|
||||||
|
|
||||||
|
public static class Items {
|
||||||
|
|
||||||
|
public static ConfigValue<ItemStack> NEXT_PAGE = new ConfigValue<>("GUI.items.next-page", ItemStack.class,
|
||||||
|
new ItemStackFactory(Material.ARROW)
|
||||||
|
.setDisplayName("下一页")
|
||||||
|
.addLore("&7&o右键可前往最后一页哦")
|
||||||
|
.toItemStack()
|
||||||
|
);
|
||||||
|
public static ConfigValue<ItemStack> PREVIOUS_PAGE = new ConfigValue<>("GUI.items.previous-page", ItemStack.class,
|
||||||
|
new ItemStackFactory(Material.ARROW)
|
||||||
|
.setDisplayName("上一页")
|
||||||
|
.addLore("&7&o右键可前往第一页哦")
|
||||||
|
.toItemStack()
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Messages {
|
||||||
|
|
||||||
|
public static ConfigMessageList SELECTED = new ConfigMessageList("selected");
|
||||||
|
public static ConfigMessageList EXPIRED = new ConfigMessageList("expired");
|
||||||
|
public static ConfigMessageList REMOVED = new ConfigMessageList("removed");
|
||||||
|
|
||||||
|
public static ConfigMessageList RELOAD = new ConfigMessageList("reload");
|
||||||
|
public static ConfigMessageList HELP = new ConfigMessageList("help");
|
||||||
|
|
||||||
|
public static ConfigMessageList LIST_TITLE = new ConfigMessageList("list-title");
|
||||||
|
public static ConfigMessageList LIST_VALUE = new ConfigMessageList("list-value");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static 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");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
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 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,64 @@
|
|||||||
|
package cc.carm.plugin.userprefix.configuration.file;
|
||||||
|
|
||||||
|
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class FileConfig {
|
||||||
|
|
||||||
|
private final JavaPlugin plugin;
|
||||||
|
|
||||||
|
private final String fileName;
|
||||||
|
|
||||||
|
private File file;
|
||||||
|
private FileConfiguration config;
|
||||||
|
|
||||||
|
public FileConfig(final JavaPlugin plugin) {
|
||||||
|
this(plugin, "config.yml");
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileConfig(final JavaPlugin plugin, final String name) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.fileName = name;
|
||||||
|
initFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initFile() {
|
||||||
|
this.file = new File(plugin.getDataFolder(), fileName);
|
||||||
|
if (!this.file.exists()) {
|
||||||
|
if (!this.file.getParentFile().exists()) {
|
||||||
|
this.file.getParentFile().mkdirs();
|
||||||
|
}
|
||||||
|
plugin.saveResource(fileName, true);
|
||||||
|
}
|
||||||
|
this.config = YamlConfiguration.loadConfiguration(this.file);
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getFile() {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileConfiguration getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save() {
|
||||||
|
try {
|
||||||
|
getConfig().save(getFile());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reload() {
|
||||||
|
if (getFile().exists()) {
|
||||||
|
this.config = YamlConfiguration.loadConfiguration(getFile());
|
||||||
|
} else {
|
||||||
|
initFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package cc.carm.plugin.userprefix.configuration.message;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.configuration.values.ConfigValue;
|
||||||
|
import cc.carm.plugin.userprefix.manager.ConfigManager;
|
||||||
|
import cc.carm.plugin.userprefix.util.MessageUtil;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class ConfigMessage extends ConfigValue<String> {
|
||||||
|
|
||||||
|
public ConfigMessage(String configSection) {
|
||||||
|
this(configSection, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigMessage(String configSection, String defaultValue) {
|
||||||
|
super(ConfigManager.getMessageConfig(), configSection, String.class, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void send(CommandSender sender) {
|
||||||
|
MessageUtil.send(sender, get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendWithPlaceholders(CommandSender sender) {
|
||||||
|
MessageUtil.sendWithPlaceholders(sender, get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendWithPlaceholders(CommandSender sender, String[] params, Object[] values) {
|
||||||
|
MessageUtil.sendWithPlaceholders(sender, Arrays.asList(get()), params, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package cc.carm.plugin.userprefix.configuration.message;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.configuration.values.ConfigValueList;
|
||||||
|
import cc.carm.plugin.userprefix.manager.ConfigManager;
|
||||||
|
import cc.carm.plugin.userprefix.util.MessageUtil;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
public class ConfigMessageList extends ConfigValueList<String> {
|
||||||
|
|
||||||
|
public ConfigMessageList(String configSection) {
|
||||||
|
super(ConfigManager.getMessageConfig(), configSection, String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigMessageList(String configSection, String[] defaultValue) {
|
||||||
|
super(ConfigManager.getMessageConfig(), configSection, String.class, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void send(CommandSender sender) {
|
||||||
|
MessageUtil.send(sender, get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendWithPlaceholders(CommandSender sender) {
|
||||||
|
MessageUtil.sendWithPlaceholders(sender, get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendWithPlaceholders(CommandSender sender, String[] params, Object[] values) {
|
||||||
|
MessageUtil.sendWithPlaceholders(sender, get(), params, values);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,60 +1,73 @@
|
|||||||
package cc.carm.plugin.userprefix.configuration.values;
|
package cc.carm.plugin.userprefix.configuration.values;
|
||||||
|
|
||||||
import cc.carm.plugin.userprefix.Main;
|
import cc.carm.plugin.userprefix.Main;
|
||||||
|
import cc.carm.plugin.userprefix.configuration.file.FileConfig;
|
||||||
import cc.carm.plugin.userprefix.manager.ConfigManager;
|
import cc.carm.plugin.userprefix.manager.ConfigManager;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
public class ConfigSound {
|
public class ConfigSound {
|
||||||
FileConfiguration source;
|
|
||||||
String configSection;
|
|
||||||
|
|
||||||
Sound defaultValue;
|
|
||||||
|
|
||||||
public ConfigSound(String configSection) {
|
FileConfig source;
|
||||||
this(configSection, null);
|
String configSection;
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigSound(String configSection, Sound defaultValue) {
|
Sound defaultValue;
|
||||||
this.source = ConfigManager.getConfig();
|
|
||||||
this.configSection = configSection;
|
|
||||||
this.defaultValue = defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void set(Sound value, float volume) {
|
public ConfigSound(String configSection) {
|
||||||
this.source.set(this.configSection, value.name() + ":" + volume);
|
this(configSection, null);
|
||||||
this.save();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void set(Sound value, float volume, float pitch) {
|
public ConfigSound(String configSection, Sound defaultValue) {
|
||||||
this.source.set(this.configSection, value.name() + ":" + volume + ":" + pitch);
|
this(ConfigManager.getPluginConfig(), configSection, defaultValue);
|
||||||
this.save();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void play(Player player) {
|
public ConfigSound(FileConfig source, String configSection, Sound defaultValue) {
|
||||||
Sound finalSound = defaultValue;
|
this.source = source;
|
||||||
float pitch = 1;
|
this.configSection = configSection;
|
||||||
float volume = 1;
|
this.defaultValue = defaultValue;
|
||||||
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 FileConfiguration getConfiguration() {
|
||||||
|
return this.source.getConfig();
|
||||||
|
}
|
||||||
|
|
||||||
public void save() {
|
public void set(Sound value, float volume) {
|
||||||
ConfigManager.saveConfig();
|
getConfiguration().set(this.configSection, value.name() + ":" + volume);
|
||||||
}
|
this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(Sound value, float volume, float pitch) {
|
||||||
|
getConfiguration().set(this.configSection, value.name() + ":" + volume + ":" + pitch);
|
||||||
|
this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void play(Player player) {
|
||||||
|
Sound finalSound = defaultValue;
|
||||||
|
float pitch = 1;
|
||||||
|
float volume = 1;
|
||||||
|
String soundString = getConfiguration().getString(this.configSection);
|
||||||
|
if (soundString != null) {
|
||||||
|
String[] args = soundString.contains(":") ? soundString.split(":") : new String[]{soundString};
|
||||||
|
try {
|
||||||
|
if (args.length >= 1) finalSound = Sound.valueOf(args[0]);
|
||||||
|
if (args.length >= 2) volume = Float.parseFloat(args[1]);
|
||||||
|
if (args.length >= 3) volume = Float.parseFloat(args[2]);
|
||||||
|
} catch (Exception exception) {
|
||||||
|
Main.error("声音 " + this.configSection + " 配置错误,不存在 " + soundString + " ,请检查。");
|
||||||
|
Main.error("There's no sound matches in " + this.configSection + " , please check the configuration");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (finalSound != null) {
|
||||||
|
player.playSound(player.getLocation(), finalSound, volume, pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save() {
|
||||||
|
this.source.save();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
package cc.carm.plugin.userprefix.configuration.values;
|
package cc.carm.plugin.userprefix.configuration.values;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.configuration.file.FileConfig;
|
||||||
import cc.carm.plugin.userprefix.manager.ConfigManager;
|
import cc.carm.plugin.userprefix.manager.ConfigManager;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
|
||||||
public class ConfigValue<V> {
|
public class ConfigValue<V> {
|
||||||
FileConfiguration source;
|
|
||||||
|
FileConfig source;
|
||||||
|
|
||||||
String configSection;
|
String configSection;
|
||||||
Class<V> clazz;
|
Class<V> clazz;
|
||||||
V defaultValue;
|
V defaultValue;
|
||||||
@@ -14,24 +17,42 @@ public class ConfigValue<V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ConfigValue(String configSection, Class<V> clazz, V defaultValue) {
|
public ConfigValue(String configSection, Class<V> clazz, V defaultValue) {
|
||||||
this.source = ConfigManager.getConfig();
|
this(ConfigManager.getPluginConfig(), configSection, clazz, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigValue(FileConfig source, String configSection, Class<V> clazz, V defaultValue) {
|
||||||
|
this.source = source;
|
||||||
this.configSection = configSection;
|
this.configSection = configSection;
|
||||||
this.clazz = clazz;
|
this.clazz = clazz;
|
||||||
this.defaultValue = defaultValue;
|
this.defaultValue = defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FileConfiguration getConfiguration() {
|
||||||
|
return this.source.getConfig();
|
||||||
|
}
|
||||||
|
|
||||||
public V get() {
|
public V get() {
|
||||||
Object val = this.source.get(this.configSection, this.defaultValue);
|
if (getConfiguration().contains(this.configSection)) {
|
||||||
return this.clazz.isInstance(val) ? this.clazz.cast(val) : this.defaultValue;
|
Object val = getConfiguration().get(this.configSection, this.defaultValue);
|
||||||
|
return this.clazz.isInstance(val) ? this.clazz.cast(val) : this.defaultValue;
|
||||||
|
} else {
|
||||||
|
// 如果没有默认值,就把配置写进去,便于配置
|
||||||
|
return setDefault();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(V value) {
|
public void set(V value) {
|
||||||
this.source.set(this.configSection, value);
|
getConfiguration().set(this.configSection, value);
|
||||||
this.save();
|
this.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() {
|
public void save() {
|
||||||
ConfigManager.saveConfig();
|
this.source.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public V setDefault() {
|
||||||
|
set(this.defaultValue);
|
||||||
|
return this.defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,52 @@
|
|||||||
package cc.carm.plugin.userprefix.configuration.values;
|
package cc.carm.plugin.userprefix.configuration.values;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.configuration.file.FileConfig;
|
||||||
import cc.carm.plugin.userprefix.manager.ConfigManager;
|
import cc.carm.plugin.userprefix.manager.ConfigManager;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ConfigValueList<V> {
|
public class ConfigValueList<V> {
|
||||||
FileConfiguration source;
|
FileConfig source;
|
||||||
String configSection;
|
String configSection;
|
||||||
Class<V> clazz;
|
Class<V> clazz;
|
||||||
|
|
||||||
|
V[] defaultValue;
|
||||||
|
|
||||||
public ConfigValueList(String configSection, Class<V> clazz) {
|
public ConfigValueList(String configSection, Class<V> clazz) {
|
||||||
this.source = ConfigManager.getConfig();
|
this(ConfigManager.getPluginConfig(), configSection, clazz);
|
||||||
this.configSection = configSection;
|
|
||||||
this.clazz = clazz;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ConfigValueList(String configSection, Class<V> clazz, V[] defaultValue) {
|
||||||
|
this(ConfigManager.getPluginConfig(), configSection, clazz, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigValueList(FileConfig configuration, String configSection, Class<V> clazz) {
|
||||||
|
this(configuration, configSection, clazz, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigValueList(FileConfig configuration, String configSection, Class<V> clazz, V[] defaultValue) {
|
||||||
|
this.source = configuration;
|
||||||
|
this.configSection = configSection;
|
||||||
|
this.clazz = clazz;
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileConfiguration getConfiguration() {
|
||||||
|
return this.source.getConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public ArrayList<V> get() {
|
public ArrayList<V> get() {
|
||||||
List<?> list = this.source.getList(this.configSection);
|
List<?> list = getConfiguration().getList(this.configSection);
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
return new ArrayList(0);
|
if (defaultValue != null) {
|
||||||
|
return new ArrayList<>(Arrays.asList(defaultValue));
|
||||||
|
} else {
|
||||||
|
return new ArrayList(0);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ArrayList<V> result = new ArrayList();
|
ArrayList<V> result = new ArrayList();
|
||||||
|
|
||||||
@@ -29,17 +55,17 @@ public class ConfigValueList<V> {
|
|||||||
result.add(this.clazz.cast(object));
|
result.add(this.clazz.cast(object));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(ArrayList<V> value) {
|
public void set(ArrayList<V> value) {
|
||||||
this.source.set(this.configSection, value);
|
getConfiguration().set(this.configSection, value);
|
||||||
this.save();
|
this.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() {
|
public void save() {
|
||||||
ConfigManager.saveConfig();
|
this.source.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package cc.carm.plugin.userprefix.event;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class UserPrefixChangeEvent extends UserPrefixEvent implements Cancellable {
|
||||||
|
|
||||||
|
public static HandlerList handler = new HandlerList();
|
||||||
|
|
||||||
|
private boolean cancelled;
|
||||||
|
|
||||||
|
private final @Nullable ConfiguredPrefix before;
|
||||||
|
private @NotNull ConfiguredPrefix after;
|
||||||
|
|
||||||
|
public UserPrefixChangeEvent(@NotNull Player who,
|
||||||
|
@Nullable ConfiguredPrefix before,
|
||||||
|
@NotNull ConfiguredPrefix after) {
|
||||||
|
super(who);
|
||||||
|
this.before = before;
|
||||||
|
this.after = after;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable ConfiguredPrefix getBefore() {
|
||||||
|
return before;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull ConfiguredPrefix getAfter() {
|
||||||
|
return after;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAfter(@NotNull ConfiguredPrefix after) {
|
||||||
|
this.after = after;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
if (before == null) return false; //Could not be cancelled when prefix is null.
|
||||||
|
else return this.cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean cancel) {
|
||||||
|
this.cancelled = cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public HandlerList getHandlers() {
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package cc.carm.plugin.userprefix.event;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.player.PlayerEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public abstract class UserPrefixEvent extends PlayerEvent {
|
||||||
|
|
||||||
|
public UserPrefixEvent(@NotNull Player who) {
|
||||||
|
super(who);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package cc.carm.plugin.userprefix.event;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class UserPrefixExpireEvent extends UserPrefixEvent {
|
||||||
|
|
||||||
|
public static HandlerList handler = new HandlerList();
|
||||||
|
|
||||||
|
|
||||||
|
public final @NotNull ConfiguredPrefix expiredPrefix;
|
||||||
|
|
||||||
|
public UserPrefixExpireEvent(@NotNull Player who,
|
||||||
|
@NotNull ConfiguredPrefix expiredPrefix) {
|
||||||
|
super(who);
|
||||||
|
this.expiredPrefix = expiredPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull ConfiguredPrefix getExpiredPrefix() {
|
||||||
|
return expiredPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public HandlerList getHandlers() {
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package cc.carm.plugin.userprefix.listener;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.Main;
|
||||||
|
import cc.carm.plugin.userprefix.configuration.PluginConfig;
|
||||||
|
import cc.carm.plugin.userprefix.util.MessageUtil;
|
||||||
|
import me.clip.placeholderapi.PlaceholderAPI;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||||
|
|
||||||
|
public class ChatListener implements Listener {
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onChat(AsyncPlayerChatEvent event) {
|
||||||
|
if (!PluginConfig.Functions.Chat.ENABLE.get()) return;
|
||||||
|
String format = PluginConfig.Functions.Chat.FORMAT.get();
|
||||||
|
if (format == null || format.length() < 1) return;
|
||||||
|
|
||||||
|
if (!MessageUtil.hasPlaceholderAPI()) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
event.setFormat(PlaceholderAPI.setPlaceholders(event.getPlayer(), format));
|
||||||
|
} catch (Exception exception) {
|
||||||
|
Main.error("请检查配置文件中聊天相关是否配置正确。");
|
||||||
|
Main.error("Please check the chat configuration.");
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package cc.carm.plugin.userprefix.listener.processor;
|
package cc.carm.plugin.userprefix.listener.processor;
|
||||||
|
|
||||||
import cc.carm.plugin.userprefix.manager.UserManager;
|
import cc.carm.plugin.userprefix.manager.UserManager;
|
||||||
|
import cc.carm.plugin.userprefix.ui.PrefixSelectGUI;
|
||||||
import net.luckperms.api.event.user.UserDataRecalculateEvent;
|
import net.luckperms.api.event.user.UserDataRecalculateEvent;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -11,6 +12,11 @@ public class UserNodeUpdateProcessor {
|
|||||||
Player player = Bukkit.getPlayer(event.getUser().getUniqueId());
|
Player player = Bukkit.getPlayer(event.getUser().getUniqueId());
|
||||||
if (player == null) return;
|
if (player == null) return;
|
||||||
UserManager.checkPrefix(player, true);
|
UserManager.checkPrefix(player, true);
|
||||||
|
if (PrefixSelectGUI.openingUsers.contains(player)) {
|
||||||
|
// 玩家权限更新,关闭其GUI,以令其重新打开刷新自己的前缀。
|
||||||
|
player.closeInventory();
|
||||||
|
PrefixSelectGUI.removeOpening(player);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,47 @@
|
|||||||
package cc.carm.plugin.userprefix.manager;
|
package cc.carm.plugin.userprefix.manager;
|
||||||
|
|
||||||
import cc.carm.plugin.userprefix.Main;
|
import cc.carm.plugin.userprefix.Main;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import cc.carm.plugin.userprefix.configuration.file.FileConfig;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
public class ConfigManager {
|
public class ConfigManager {
|
||||||
|
|
||||||
private static FileConfiguration config;
|
private static FileConfig config;
|
||||||
|
private static FileConfig messageConfig;
|
||||||
|
|
||||||
|
|
||||||
public static void initConfig() {
|
public static void initConfig() {
|
||||||
Main.getInstance().saveDefaultConfig();
|
File configFile = new File(Main.getInstance().getDataFolder(), "config.yml");
|
||||||
Main.getInstance().reloadConfig();
|
if (!configFile.exists()) {
|
||||||
|
//没找到配置文件,可能是第一次加载此插件
|
||||||
|
//把一些英文版的东西复制出来,方便英文用户使用。
|
||||||
|
Main.getInstance().saveResource("prefixes/example-prefix.yml", false);
|
||||||
|
Main.getInstance().saveResource("en_US/config.yml", false);
|
||||||
|
Main.getInstance().saveResource("en_US/messages.yml", false);
|
||||||
|
Main.getInstance().saveResource("en_US/example-prefix.yml", false);
|
||||||
|
}
|
||||||
|
|
||||||
config = Main.getInstance().getConfig();
|
ConfigManager.config = new FileConfig(Main.getInstance(), "config.yml");
|
||||||
|
ConfigManager.messageConfig = new FileConfig(Main.getInstance(), "messages.yml");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FileConfiguration getConfig() {
|
public static FileConfig getPluginConfig() {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void reloadConfig() {
|
public static FileConfig getMessageConfig() {
|
||||||
Main.getInstance().reloadConfig();
|
return messageConfig;
|
||||||
config = Main.getInstance().getConfig();
|
}
|
||||||
|
|
||||||
|
public static void reload() {
|
||||||
|
getPluginConfig().reload();
|
||||||
|
getMessageConfig().reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void saveConfig() {
|
public static void saveConfig() {
|
||||||
Main.getInstance().saveConfig();
|
getPluginConfig().save();
|
||||||
|
getMessageConfig().save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package cc.carm.plugin.userprefix.manager;
|
package cc.carm.plugin.userprefix.manager;
|
||||||
|
|
||||||
import cc.carm.plugin.userprefix.Main;
|
import cc.carm.plugin.userprefix.Main;
|
||||||
|
import cc.carm.plugin.userprefix.configuration.PluginConfig;
|
||||||
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
|
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
|
||||||
import cc.carm.plugin.userprefix.util.ItemStackFactory;
|
import cc.carm.plugin.userprefix.util.ItemStackFactory;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@@ -11,6 +12,8 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -18,132 +21,151 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
public class PrefixManager {
|
public class PrefixManager {
|
||||||
|
|
||||||
public static ConfiguredPrefix defaultPrefix;
|
public static ConfiguredPrefix defaultPrefix;
|
||||||
public static HashMap<String, ConfiguredPrefix> prefixes = new HashMap<>();
|
public static HashMap<String, ConfiguredPrefix> prefixes = new HashMap<>();
|
||||||
|
|
||||||
|
private static final String FOLDER_NAME = "prefixes";
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
loadConfiguredPrefixes();
|
loadPrefixes();
|
||||||
Main.log("共加载了 " + prefixes.size() + " 个前缀。");
|
Main.log("共加载了 " + prefixes.size() + " 个前缀。");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadConfiguredPrefixes() {
|
public static void loadPrefixes() {
|
||||||
loadDefaultPrefix();
|
loadDefaultPrefix();
|
||||||
|
loadConfiguredPrefixes();
|
||||||
|
}
|
||||||
|
|
||||||
ConfigurationSection prefixesSection = ConfigManager.getConfig().getConfigurationSection("prefixes");
|
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||||
if (prefixesSection == null || prefixesSection.getKeys(false).isEmpty()) {
|
public static void loadConfiguredPrefixes() {
|
||||||
Main.log("配置文件中暂无任何前缀配置,请检查。");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMap<String, ConfiguredPrefix> dataPrefixes = new HashMap<>();
|
File prefixDataFolder = getStorageFolder();
|
||||||
|
if (!prefixDataFolder.isDirectory() || !prefixDataFolder.exists()) {
|
||||||
|
prefixDataFolder.mkdir();
|
||||||
|
}
|
||||||
|
|
||||||
for (String prefixIdentifier : prefixesSection.getKeys(false)) {
|
String[] filesList = prefixDataFolder.list();
|
||||||
ConfigurationSection configuredPrefixSection = prefixesSection.getConfigurationSection(prefixIdentifier);
|
if (filesList == null || filesList.length < 1) {
|
||||||
if (configuredPrefixSection == null) continue;
|
Main.error("配置文件夹中暂无任何前缀配置问,请检查。");
|
||||||
try {
|
Main.error("There's no configured prefix.");
|
||||||
String name = configuredPrefixSection.getString("name", "前缀名配置错误");
|
Main.error("Path: " + prefixDataFolder.getAbsolutePath());
|
||||||
String content = configuredPrefixSection.getString("content", "&r");
|
return;
|
||||||
String permission = configuredPrefixSection.getString("permission");
|
}
|
||||||
int weight = configuredPrefixSection.getInt("weight", 1);
|
|
||||||
|
|
||||||
ItemStack itemHasPermission = configuredPrefixSection.getItemStack("itemHasPermission",
|
List<File> files = Arrays.stream(filesList)
|
||||||
new ItemStackFactory(Material.STONE).setDisplayName(name).addLore(" ").addLore("§a➥ 点击切换到该前缀").toItemStack()
|
.map(s -> new File(prefixDataFolder, s))
|
||||||
);
|
.filter(File::isFile)
|
||||||
ItemStack itemNoPermission = configuredPrefixSection.getItemStack("itemNoPermission", itemHasPermission);
|
.collect(Collectors.toList());
|
||||||
ItemStack itemUsing = configuredPrefixSection.getItemStack("itemUsing", itemHasPermission);
|
|
||||||
|
|
||||||
|
HashMap<String, ConfiguredPrefix> dataPrefixes = new HashMap<>();
|
||||||
|
|
||||||
Main.log("完成前缀加载 " + prefixIdentifier + " : " + name);
|
if (files.size() > 0) {
|
||||||
|
for (File file : files) {
|
||||||
|
try {
|
||||||
|
ConfiguredPrefix prefix = new ConfiguredPrefix(file);
|
||||||
|
Main.log("完成前缀加载 " + prefix.getIdentifier() + " : " + prefix.getName());
|
||||||
|
Main.log("Successfully loaded " + prefix.getIdentifier() + " : " + prefix.getName());
|
||||||
|
dataPrefixes.put(prefix.getIdentifier(), prefix);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Main.error("在加载前缀 " + file.getAbsolutePath() + " 时出错,请检查配置!");
|
||||||
|
Main.error("Error occurred when loading prefix #" + file.getAbsolutePath() + " !");
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dataPrefixes.put(prefixIdentifier, new ConfiguredPrefix(prefixIdentifier, name, content, weight, permission, itemHasPermission, itemNoPermission, itemUsing));
|
PrefixManager.prefixes.clear();
|
||||||
} catch (Exception exception) {
|
PrefixManager.prefixes = dataPrefixes;
|
||||||
Main.log("在加载前缀 " + prefixIdentifier + " 时出错,请检查配置!");
|
}
|
||||||
exception.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PrefixManager.prefixes.clear();
|
public static void loadDefaultPrefix() {
|
||||||
PrefixManager.prefixes = dataPrefixes;
|
PrefixManager.defaultPrefix = null;
|
||||||
}
|
ConfigurationSection defaultPrefixSection = ConfigManager.getPluginConfig()
|
||||||
|
.getConfig().getConfigurationSection("defaultPrefix");
|
||||||
|
if (defaultPrefixSection != null) {
|
||||||
|
try {
|
||||||
|
String name = defaultPrefixSection.getString("name", "默认前缀");
|
||||||
|
String content = defaultPrefixSection.getString("content", "&r");
|
||||||
|
ItemStack itemNotUsing = defaultPrefixSection.getItemStack(
|
||||||
|
"itemNotUsing",
|
||||||
|
new ItemStackFactory(Material.NAME_TAG)
|
||||||
|
.setDisplayName("&f默认前缀")
|
||||||
|
.addLore(" ")
|
||||||
|
.addLore("§a➥ 点击切换到该前缀")
|
||||||
|
.toItemStack()
|
||||||
|
);
|
||||||
|
ItemStack itemUsing = defaultPrefixSection.getItemStack("itemUsing",
|
||||||
|
new ItemStackFactory(Material.NAME_TAG)
|
||||||
|
.setDisplayName("&f默认前缀")
|
||||||
|
.addLore(" ")
|
||||||
|
.addLore("§a✔ 您正在使用该前缀")
|
||||||
|
.addEnchant(Enchantment.DURABILITY, 1, false)
|
||||||
|
.addFlag(ItemFlag.HIDE_ENCHANTS)
|
||||||
|
.toItemStack()
|
||||||
|
);
|
||||||
|
PrefixManager.defaultPrefix = new ConfiguredPrefix("default", name, content, 0, null, itemNotUsing, null, itemUsing);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Main.error("在加载默认前缀时出错,请检查配置!");
|
||||||
|
Main.error("Error occurred when loading default prefix, please check the configuration.");
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PrefixManager.defaultPrefix = new ConfiguredPrefix("default", "默认前缀", "&r", 0, null,
|
||||||
|
new ItemStackFactory(Material.NAME_TAG)
|
||||||
|
.setDisplayName("&f默认前缀")
|
||||||
|
.addLore(" ")
|
||||||
|
.addLore("§a➥ 点击切换到该前缀")
|
||||||
|
.toItemStack(),
|
||||||
|
null,
|
||||||
|
new ItemStackFactory(Material.NAME_TAG)
|
||||||
|
.setDisplayName("&f默认前缀")
|
||||||
|
.addLore(" ")
|
||||||
|
.addLore("§a✔ 您正在使用该前缀")
|
||||||
|
.addEnchant(Enchantment.DURABILITY, 1, false)
|
||||||
|
.addFlag(ItemFlag.HIDE_ENCHANTS)
|
||||||
|
.toItemStack()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static void loadDefaultPrefix() {
|
Main.log("完成默认前缀加载 " + defaultPrefix.getName());
|
||||||
PrefixManager.defaultPrefix = null;
|
Main.log("Successfully loaded default prefix " + defaultPrefix.getName());
|
||||||
ConfigurationSection defaultPrefixSection = ConfigManager.getConfig().getConfigurationSection("defaultPrefix");
|
}
|
||||||
if (defaultPrefixSection != null) {
|
|
||||||
try {
|
|
||||||
String name = defaultPrefixSection.getString("name", "默认前缀");
|
|
||||||
String content = defaultPrefixSection.getString("content", "&r");
|
|
||||||
ItemStack itemNotUsing = defaultPrefixSection.getItemStack(
|
|
||||||
"itemNotUsing",
|
|
||||||
new ItemStackFactory(Material.NAME_TAG)
|
|
||||||
.setDisplayName("&f默认前缀")
|
|
||||||
.addLore(" ")
|
|
||||||
.addLore("§a➥ 点击切换到该前缀")
|
|
||||||
.toItemStack()
|
|
||||||
);
|
|
||||||
ItemStack itemUsing = defaultPrefixSection.getItemStack("itemUsing",
|
|
||||||
new ItemStackFactory(Material.NAME_TAG)
|
|
||||||
.setDisplayName("&f默认前缀")
|
|
||||||
.addLore(" ")
|
|
||||||
.addLore("§a✔ 您正在使用该前缀")
|
|
||||||
.addEnchant(Enchantment.DURABILITY, 1, false)
|
|
||||||
.addFlag(ItemFlag.HIDE_ENCHANTS)
|
|
||||||
.toItemStack()
|
|
||||||
);
|
|
||||||
PrefixManager.defaultPrefix = new ConfiguredPrefix("default", name, content, 0, null, itemNotUsing, null, itemUsing);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Main.log("在加载默认前缀时出错,请检查配置!");
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
PrefixManager.defaultPrefix = new ConfiguredPrefix("default", "默认前缀", "&r", 0, null,
|
|
||||||
new ItemStackFactory(Material.NAME_TAG)
|
|
||||||
.setDisplayName("&f默认前缀")
|
|
||||||
.addLore(" ")
|
|
||||||
.addLore("§a➥ 点击切换到该前缀")
|
|
||||||
.toItemStack(),
|
|
||||||
null,
|
|
||||||
new ItemStackFactory(Material.NAME_TAG)
|
|
||||||
.setDisplayName("&f默认前缀")
|
|
||||||
.addLore(" ")
|
|
||||||
.addLore("§a✔ 您正在使用该前缀")
|
|
||||||
.addEnchant(Enchantment.DURABILITY, 1, false)
|
|
||||||
.addFlag(ItemFlag.HIDE_ENCHANTS)
|
|
||||||
.toItemStack()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 List<ConfiguredPrefix> getVisiblePrefix() {
|
@NotNull
|
||||||
return PrefixManager.getPrefixes().values().stream()
|
public static ConfiguredPrefix getDefaultPrefix() {
|
||||||
.filter(ConfiguredPrefix::isVisibleNoPermission)
|
return defaultPrefix;
|
||||||
.sorted(Comparator.comparingInt(ConfiguredPrefix::getWeight))
|
}
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static ConfiguredPrefix getDefaultPrefix() {
|
public static HashMap<String, ConfiguredPrefix> getPrefixes() {
|
||||||
return defaultPrefix;
|
return prefixes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nullable
|
||||||
public static HashMap<String, ConfiguredPrefix> getPrefixes() {
|
public static ConfiguredPrefix getPrefix(String identifier) {
|
||||||
return prefixes;
|
if (identifier == null) {
|
||||||
}
|
return null;
|
||||||
|
} else if (identifier.equalsIgnoreCase("default")) {
|
||||||
|
return getDefaultPrefix();
|
||||||
|
} else {
|
||||||
|
return getPrefixes().get(identifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
private static File getStorageFolder() {
|
||||||
public static ConfiguredPrefix getPrefix(String identifier) {
|
if (PluginConfig.CustomStorage.ENABLE.get()) {
|
||||||
if (identifier == null) {
|
return new File(PluginConfig.CustomStorage.PATH.get());
|
||||||
return null;
|
} else {
|
||||||
} else if (identifier.equalsIgnoreCase("default")) {
|
return new File(Main.getInstance().getDataFolder() + File.separator + FOLDER_NAME);
|
||||||
return getDefaultPrefix();
|
}
|
||||||
} else {
|
}
|
||||||
return getPrefixes().get(identifier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
package cc.carm.plugin.userprefix.manager;
|
package cc.carm.plugin.userprefix.manager;
|
||||||
|
|
||||||
import cc.carm.plugin.userprefix.Main;
|
import cc.carm.plugin.userprefix.Main;
|
||||||
import cc.carm.plugin.userprefix.configuration.PrefixConfig;
|
import cc.carm.plugin.userprefix.configuration.PluginConfig;
|
||||||
|
import cc.carm.plugin.userprefix.event.UserPrefixChangeEvent;
|
||||||
|
import cc.carm.plugin.userprefix.event.UserPrefixExpireEvent;
|
||||||
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
|
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
|
||||||
import cc.carm.plugin.userprefix.nametag.UserNameTag;
|
import cc.carm.plugin.userprefix.nametag.UserNameTag;
|
||||||
import cc.carm.plugin.userprefix.ui.PrefixSelectGUI;
|
import cc.carm.plugin.userprefix.ui.PrefixSelectGUI;
|
||||||
import cc.carm.plugin.userprefix.util.MessageUtil;
|
|
||||||
import cc.carm.plugin.userprefix.util.gui.GUI;
|
import cc.carm.plugin.userprefix.util.gui.GUI;
|
||||||
import net.luckperms.api.model.user.User;
|
import net.luckperms.api.model.user.User;
|
||||||
import net.luckperms.api.node.NodeType;
|
import net.luckperms.api.node.NodeType;
|
||||||
@@ -20,235 +21,270 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
public class UserManager {
|
public class UserManager {
|
||||||
|
|
||||||
public static HashMap<UUID, UserNameTag> nameTags = new HashMap<>();
|
public static HashMap<UUID, UserNameTag> nameTags = new HashMap<>();
|
||||||
|
|
||||||
public static HashSet<UUID> checkingPlayers = new HashSet<>();
|
public static HashSet<UUID> checkingPlayers = new HashSet<>();
|
||||||
|
|
||||||
public static UserNameTag getNameTag(Player player) {
|
@Nullable
|
||||||
return nameTags.get(player.getUniqueId());
|
public static UserNameTag getNameTag(Player player) {
|
||||||
}
|
if (PluginConfig.Functions.NAME_PREFIX.get()) {
|
||||||
|
if (nameTags.containsKey(player.getUniqueId())) {
|
||||||
|
return nameTags.get(player.getUniqueId());
|
||||||
|
} else {
|
||||||
|
return createNameTag(player);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static UserNameTag createNameTag(Player player) {
|
@NotNull
|
||||||
UserNameTag nameTag = new UserNameTag(player);
|
public static UserNameTag createNameTag(Player player) {
|
||||||
nameTags.put(player.getUniqueId(), nameTag);
|
if (nameTags.containsKey(player.getUniqueId())) return nameTags.get(player.getUniqueId());
|
||||||
return nameTag;
|
UserNameTag nameTag = new UserNameTag(player);
|
||||||
}
|
nameTags.put(player.getUniqueId(), nameTag);
|
||||||
|
return nameTag;
|
||||||
|
}
|
||||||
|
|
||||||
public static void initPlayer(Player player) {
|
public static void initPlayer(Player player) {
|
||||||
UserManager.checkPrefix(player, false);
|
UserManager.checkPrefix(player, false);
|
||||||
if (PrefixConfig.Functions.NAME_PREFIX.get()) {
|
if (PluginConfig.Functions.NAME_PREFIX.get()) {
|
||||||
UserManager.createNameTag(player);
|
UserManager.createNameTag(player);
|
||||||
UserManager.updatePrefixView(player, true);
|
UserManager.updatePrefixView(player, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void unloadPlayer(Player player) {
|
public static void unloadPlayer(Player player) {
|
||||||
PrefixSelectGUI.removeOpening(player);
|
PrefixSelectGUI.removeOpening(player);
|
||||||
UserManager.unloadNameTag(player.getUniqueId());
|
UserManager.unloadNameTag(player.getUniqueId());
|
||||||
UserManager.checkingPlayers.remove(player.getUniqueId());
|
UserManager.checkingPlayers.remove(player.getUniqueId());
|
||||||
GUI.removeOpenedGUI(player); // 清空打开过的GUI缓存 (用于记录物品点击的
|
GUI.removeOpenedGUI(player); // 清空打开过的GUI缓存 (用于记录物品点击的
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新前缀显示效果
|
* 更新前缀显示效果
|
||||||
*
|
*
|
||||||
* @param player 玩家
|
* @param player 玩家
|
||||||
* @param loadOthers 是否为玩家更新其他人的前缀(一般用于加入游戏)
|
* @param loadOthers 是否为玩家更新其他人的前缀(一般用于加入游戏)
|
||||||
*/
|
*/
|
||||||
public static void updatePrefixView(Player player, boolean loadOthers) {
|
public static void updatePrefixView(Player player, boolean loadOthers) {
|
||||||
ConfiguredPrefix playerPrefix = UserManager.getPrefix(player);
|
if (!PluginConfig.Functions.NAME_PREFIX.get()) return; //未启用的情况下,不需要进行任何操作。
|
||||||
|
UserNameTag tag = getNameTag(player);
|
||||||
|
if (tag == null) return; //未启用的情况下,不需要进行任何操作。
|
||||||
|
|
||||||
UserNameTag tag = getNameTag(player);
|
ConfiguredPrefix playerPrefix = UserManager.getPrefix(player);
|
||||||
|
|
||||||
tag.setPrefix(playerPrefix.getContent());
|
tag.setPrefix(playerPrefix.getContent());
|
||||||
tag.setOrder(playerPrefix.getWeight());
|
tag.setOrder(playerPrefix.getWeight());
|
||||||
|
|
||||||
Main.debug("为玩家 " + player.getName() + " 设置了 " + player.getName() + "的前缀为 #" + playerPrefix.getWeight() + " " + playerPrefix.getName());
|
Main.debug("为玩家 " + player.getName() + " 设置了 " + player.getName() + "的前缀为 #" + playerPrefix.getWeight() + " " + playerPrefix.getName());
|
||||||
|
|
||||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
||||||
if (onlinePlayer.equals(player)) continue;
|
if (onlinePlayer.equals(player)) continue;
|
||||||
UserNameTag onlinePlayerTag = getNameTag(onlinePlayer);
|
UserNameTag onlinePlayerTag = getNameTag(onlinePlayer);
|
||||||
if (onlinePlayerTag != null) {
|
if (onlinePlayerTag != null) {
|
||||||
onlinePlayerTag.setPrefix(player, playerPrefix.getContent());
|
onlinePlayerTag.setPrefix(player, playerPrefix.getContent());
|
||||||
onlinePlayerTag.setOrder(player, playerPrefix.getWeight());
|
onlinePlayerTag.setOrder(player, playerPrefix.getWeight());
|
||||||
Main.debug("为玩家 " + onlinePlayer.getName() + " 设置了 " + player.getName() + "的前缀为 #" + playerPrefix.getWeight() + " " + playerPrefix.getName());
|
Main.debug("为玩家 " + onlinePlayer.getName() + " 设置了 " + player.getName() + "的前缀为 #" + playerPrefix.getWeight() + " " + playerPrefix.getName());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loadOthers) {
|
if (loadOthers) {
|
||||||
ConfiguredPrefix onlinePlayerPrefix = UserManager.getPrefix(onlinePlayer);
|
ConfiguredPrefix onlinePlayerPrefix = UserManager.getPrefix(onlinePlayer);
|
||||||
tag.setPrefix(onlinePlayer, onlinePlayerPrefix.getContent());
|
tag.setPrefix(onlinePlayer, onlinePlayerPrefix.getContent());
|
||||||
tag.setOrder(onlinePlayer, onlinePlayerPrefix.getWeight());
|
tag.setOrder(onlinePlayer, onlinePlayerPrefix.getWeight());
|
||||||
Main.debug("为玩家 " + player.getName() + " 设置了 " + onlinePlayer.getName() + "的前缀为 #" + onlinePlayerPrefix.getWeight() + " " + onlinePlayerPrefix.getName());
|
Main.debug("为玩家 " + player.getName() + " 设置了 " + onlinePlayer.getName() + "的前缀为 #" + onlinePlayerPrefix.getWeight() + " " + onlinePlayerPrefix.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查玩家的前缀的使用权
|
* 检查玩家的前缀的使用权
|
||||||
*
|
*
|
||||||
* @param player 玩家
|
* @param player 玩家
|
||||||
* @param updateView 是否更新头顶与TabList中的前缀
|
* @param updateView 是否更新头顶与TabList中的前缀
|
||||||
*/
|
*/
|
||||||
public static void checkPrefix(Player player, boolean updateView) {
|
public static void checkPrefix(Player player, boolean updateView) {
|
||||||
if (checkingPlayers.contains(player.getUniqueId())) {
|
if (checkingPlayers.contains(player.getUniqueId())) {
|
||||||
/*
|
/*
|
||||||
* 这里为了避免极短时间内的重复触发导致多次判断且结果相同误导玩家,
|
* 这里为了避免极短时间内的重复触发导致多次判断且结果相同误导玩家,
|
||||||
* 故没有采用同步锁,而是采用添加到一个临时Set中,对Set中玩家跳过判断。
|
* 故没有采用同步锁,而是采用添加到一个临时Set中,对Set中玩家跳过判断。
|
||||||
*/
|
*/
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
checkingPlayers.add(player.getUniqueId());
|
checkingPlayers.add(player.getUniqueId());
|
||||||
String currentPrefixIdentifier = UserManager.getPrefixData(player);
|
String currentPrefixData = 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) {
|
if (!UserManager.isPrefixUsable(player, currentPrefixData)) {
|
||||||
nameTags.remove(uuid);
|
ConfiguredPrefix currentPrefix = PrefixManager.getPrefix(currentPrefixData);
|
||||||
}
|
ConfiguredPrefix newPrefix = UserManager.getHighestPrefix(player);
|
||||||
|
|
||||||
/**
|
if (currentPrefix != null) {
|
||||||
* 得到玩家的前缀。
|
//当前前缀不为空,则代表属于前缀过期的情况
|
||||||
* 该方法会自动判断玩家当前的前缀是否可用,并返回最终可用的前缀。
|
Bukkit.getPluginManager().callEvent(new UserPrefixExpireEvent(player, currentPrefix));
|
||||||
*
|
|
||||||
* @param player 玩家
|
|
||||||
* @return 前缀配置
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
public static ConfiguredPrefix getPrefix(Player player) {
|
|
||||||
String identifier = getPrefixData(player);
|
|
||||||
if (identifier == null || !isPrefixUsable(player, identifier)) {
|
|
||||||
return getHighestPrefix(player);
|
|
||||||
} else {
|
|
||||||
ConfiguredPrefix prefix = PrefixManager.getPrefix(identifier);
|
|
||||||
return prefix == null ? PrefixManager.getDefaultPrefix() : prefix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// 发送消息
|
||||||
* 设定玩家前缀
|
PluginConfig.Messages.EXPIRED.sendWithPlaceholders(player,
|
||||||
*
|
new String[]{"%(newName)", "%(oldName)"},
|
||||||
* @param player 玩家
|
new Object[]{newPrefix.getName(), currentPrefix.getName()}
|
||||||
* @param prefix 前缀配置
|
);
|
||||||
* @param updateView 是否更新头顶上、TabList的前缀
|
|
||||||
*/
|
|
||||||
public static void setPrefix(Player player, ConfiguredPrefix prefix, boolean updateView) {
|
|
||||||
setPrefixData(player, prefix.getIdentifier());
|
|
||||||
if (updateView) updatePrefixView(player, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// 播放声音
|
||||||
* 得到玩家所有可用的前缀
|
PluginConfig.Sounds.PREFIX_EXPIRED.play(player);
|
||||||
*
|
} else {
|
||||||
* @param player 玩家
|
// 当前前缀为空,则代表是旧的前缀不存在了,
|
||||||
* @return 可用前缀列表
|
PluginConfig.Messages.REMOVED.sendWithPlaceholders(player,
|
||||||
*/
|
new String[]{"%(newName)", "%(oldName)"},
|
||||||
@NotNull
|
new Object[]{newPrefix.getName(), currentPrefixData}
|
||||||
public static List<ConfiguredPrefix> getUsablePrefixes(Player player) {
|
);
|
||||||
return PrefixManager.getPrefixes().values().stream()
|
}
|
||||||
.filter(configuredPrefix -> isPrefixUsable(player, configuredPrefix)) //过滤出玩家可用的前缀
|
|
||||||
.sorted(Comparator.comparingInt(ConfiguredPrefix::getWeight)) // 以前缀排序
|
UserPrefixChangeEvent event = new UserPrefixChangeEvent(player, currentPrefix, newPrefix);
|
||||||
.collect(Collectors.toList()); // 返回集合
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
}
|
|
||||||
|
if (!event.isCancelled()) {
|
||||||
|
// 更新前缀
|
||||||
|
UserManager.setPrefix(player, event.getAfter(), updateView);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
checkingPlayers.remove(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void unloadNameTag(UUID uuid) {
|
||||||
|
nameTags.remove(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 得到玩家的前缀。
|
||||||
|
* 该方法会自动判断玩家当前的前缀是否可用,并返回最终可用的前缀。
|
||||||
|
*
|
||||||
|
* @param player 玩家
|
||||||
|
* @return 前缀配置
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static ConfiguredPrefix getPrefix(Player player) {
|
||||||
|
String identifier = getPrefixData(player);
|
||||||
|
if (identifier == null || !isPrefixUsable(player, identifier)) {
|
||||||
|
return getHighestPrefix(player);
|
||||||
|
} else {
|
||||||
|
ConfiguredPrefix prefix = PrefixManager.getPrefix(identifier);
|
||||||
|
return prefix == null ? PrefixManager.getDefaultPrefix() : prefix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设定玩家前缀
|
||||||
|
*
|
||||||
|
* @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 可用前缀列表
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
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” ,则会返回默认前缀。
|
* 注意:若配置文件中关闭了 “autoUsePrefix” ,则会返回默认前缀。
|
||||||
*
|
*
|
||||||
* @param player 玩家
|
* @param player 玩家
|
||||||
* @return 权限内容
|
* @return 权限内容
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public static ConfiguredPrefix getHighestPrefix(Player player) {
|
public static ConfiguredPrefix getHighestPrefix(Player player) {
|
||||||
if (PrefixConfig.Functions.AUTO_USE.get()) {
|
if (PluginConfig.Functions.AUTO_USE.get()) {
|
||||||
// 关闭了自动选择,就直接给默认的前缀,让玩家自己去设置吧~
|
// 关闭了自动选择,就直接给默认的前缀,让玩家自己去设置吧~
|
||||||
return PrefixManager.getDefaultPrefix();
|
return PrefixManager.getDefaultPrefix();
|
||||||
}
|
}
|
||||||
return getUsablePrefixes(player).stream()
|
return getUsablePrefixes(player).stream()
|
||||||
.max(Comparator.comparingInt(ConfiguredPrefix::getWeight)) // 取权重最大
|
.max(Comparator.comparingInt(ConfiguredPrefix::getWeight)) // 取权重最大
|
||||||
.orElseGet(PrefixManager::getDefaultPrefix); // 啥都没有? 返回默认前缀。
|
.orElseGet(PrefixManager::getDefaultPrefix); // 啥都没有? 返回默认前缀。
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断一个前缀对某玩家是否可用
|
* 判断一个前缀对某玩家是否可用
|
||||||
*
|
*
|
||||||
* @param player 玩家
|
* @param player 玩家
|
||||||
* @param prefixIdentifier 前缀标识
|
* @param prefixIdentifier 前缀标识
|
||||||
* @return 若前缀标识不存在,则返回false;若前缀为默认前缀,或该前缀无权限,或玩家有该前缀的权限,则返回true。
|
* @return 若前缀标识不存在,则返回false;若前缀为默认前缀,或该前缀无权限,或玩家有该前缀的权限,则返回true。
|
||||||
*/
|
*/
|
||||||
public static boolean isPrefixUsable(Player player, String prefixIdentifier) {
|
public static boolean isPrefixUsable(Player player, String prefixIdentifier) {
|
||||||
if (prefixIdentifier == null || prefixIdentifier.equalsIgnoreCase("default")) return true;
|
if (prefixIdentifier == null || prefixIdentifier.equalsIgnoreCase("default")) return true;
|
||||||
ConfiguredPrefix prefix = PrefixManager.getPrefix(prefixIdentifier);
|
ConfiguredPrefix prefix = PrefixManager.getPrefix(prefixIdentifier);
|
||||||
if (prefix == null) return false;
|
if (prefix == null) return false;
|
||||||
return isPrefixUsable(player, prefix);
|
return isPrefixUsable(player, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断一个前缀对某玩家是否可用
|
* 判断一个前缀对某玩家是否可用
|
||||||
*
|
*
|
||||||
* @param player 玩家
|
* @param player 玩家
|
||||||
* @param configuredPrefix 前缀配置
|
* @param configuredPrefix 前缀配置
|
||||||
* @return 若前缀标识不存在,则返回false;若前缀为默认前缀,或该前缀无权限,或玩家有该前缀的权限,则返回true。
|
* @return 若前缀标识不存在,则返回false;若前缀为默认前缀,或该前缀无权限,或玩家有该前缀的权限,则返回true。
|
||||||
*/
|
*/
|
||||||
public static boolean isPrefixUsable(Player player, ConfiguredPrefix configuredPrefix) {
|
public static boolean isPrefixUsable(Player player, ConfiguredPrefix configuredPrefix) {
|
||||||
return configuredPrefix.getPermission() == null //为null的话说明无需权限了
|
return configuredPrefix.isPublic()
|
||||||
|| ServiceManager.hasPermission(ServiceManager.getUser(player), configuredPrefix.getPermission());
|
|| ServiceManager.hasPermission(ServiceManager.getUser(player), configuredPrefix.getPermission());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 得到用户当前正在使用的前缀Identifier。
|
* 得到用户当前正在使用的前缀Identifier。
|
||||||
* 该方法通过LuckPerms的MetaData实现,因此可以通过指令去操作。
|
* 该方法通过LuckPerms的MetaData实现,因此可以通过指令去操作。
|
||||||
*
|
*
|
||||||
* @param player 玩家
|
* @param player 玩家
|
||||||
* @return 正在使用的前缀Identifier(若不存在则返回null)
|
* @return 正在使用的前缀Identifier(若不存在则返回null, 代表未设置前缀)
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public static String getPrefixData(Player player) {
|
public static String getPrefixData(Player player) {
|
||||||
return ServiceManager.getAPI().getMetaData(player)
|
return ServiceManager.getAPI().getMetaData(player)
|
||||||
.getMetaValue("userprefix", String::valueOf)
|
.getMetaValue("userprefix", String::valueOf)
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设定用户所使用的的prefix。
|
* 设定用户所使用的的prefix。
|
||||||
* 该方法通过LuckPerms的MetaData实现,因此可以通过指令去操作。
|
* 该方法通过LuckPerms的MetaData实现,因此可以通过指令去操作。
|
||||||
*
|
*
|
||||||
* @param player 玩家
|
* @param player 玩家
|
||||||
* @param prefixIdentifier 前缀的标识
|
* @param prefixIdentifier 前缀的标识
|
||||||
*/
|
*/
|
||||||
public static void setPrefixData(Player player, String prefixIdentifier) {
|
public static void setPrefixData(Player player, String prefixIdentifier) {
|
||||||
User user = ServiceManager.getUser(player);
|
User user = ServiceManager.getUser(player);
|
||||||
clearPrefixData(player); // 清除掉旧的数据,LuckPerms不会去覆盖一个Meta,需要手动清除。
|
clearPrefixData(player); // 清除掉旧的数据,LuckPerms不会去覆盖一个Meta,需要手动清除。
|
||||||
if (prefixIdentifier != null) {
|
if (prefixIdentifier != null) {
|
||||||
user.data().add(MetaNode.builder("userprefix", prefixIdentifier).build());
|
user.data().add(MetaNode.builder("userprefix", prefixIdentifier).build());
|
||||||
ServiceManager.getService().getUserManager().saveUser(user); // 保存数据
|
ServiceManager.getService().getUserManager().saveUser(user); // 保存数据
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清除玩家所选择的前缀数据
|
* 清除玩家所选择的前缀数据
|
||||||
*
|
*
|
||||||
* @param player 玩家
|
* @param player 玩家
|
||||||
*/
|
*/
|
||||||
public static void clearPrefixData(Player player) {
|
public static void clearPrefixData(Player player) {
|
||||||
User user = ServiceManager.getUser(player);
|
User user = ServiceManager.getUser(player);
|
||||||
// LuckPerms竟然会把所有的metaKey全部转换为小写... 那我这里就直接写成小写吧~
|
// LuckPerms竟然会把所有的metaKey全部转换为小写... 那我这里就直接写成小写吧~
|
||||||
user.data().clear(NodeType.META.predicate(mn -> mn.getMetaKey().equals("userprefix")));
|
user.data().clear(NodeType.META.predicate(mn -> mn.getMetaKey().equals("userprefix")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,69 +1,159 @@
|
|||||||
package cc.carm.plugin.userprefix.model;
|
package cc.carm.plugin.userprefix.model;
|
||||||
|
|
||||||
import cc.carm.plugin.userprefix.util.ColorParser;
|
import cc.carm.plugin.userprefix.util.ColorParser;
|
||||||
|
import cc.carm.plugin.userprefix.util.ItemStackFactory;
|
||||||
|
import cc.carm.plugin.userprefix.util.MessageUtil;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class ConfiguredPrefix {
|
public class ConfiguredPrefix {
|
||||||
|
|
||||||
String identifier;
|
@Nullable
|
||||||
|
private File dataFile;
|
||||||
|
@Nullable
|
||||||
|
private FileConfiguration configuration;
|
||||||
|
|
||||||
String name;
|
String identifier;
|
||||||
String content;
|
|
||||||
|
|
||||||
int weight;
|
String name;
|
||||||
|
String content;
|
||||||
|
|
||||||
String permission;
|
int weight;
|
||||||
|
|
||||||
ItemStack itemHasPermission;
|
String permission;
|
||||||
ItemStack itemNoPermission;
|
|
||||||
ItemStack itemWhenUsing;
|
|
||||||
|
|
||||||
public ConfiguredPrefix(String identifier, String name, String content, int weight, String permission, ItemStack itemHasPermission, ItemStack itemNoPermission, ItemStack itemWhenUsing) {
|
ItemStack itemHasPermission;
|
||||||
this.identifier = identifier;
|
ItemStack itemNoPermission;
|
||||||
this.name = name;
|
ItemStack itemWhenUsing;
|
||||||
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 String getContent() {
|
|
||||||
return ColorParser.parseColor(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWeight() {
|
|
||||||
return weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPermission() {
|
|
||||||
return permission;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemStack getItemHasPermission() {
|
|
||||||
return itemHasPermission;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemStack getItemNoPermission() {
|
|
||||||
return itemNoPermission;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemStack getItemWhenUsing() {
|
|
||||||
return itemWhenUsing;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isVisibleNoPermission() {
|
|
||||||
return this.itemNoPermission != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
public ConfiguredPrefix(@NotNull File dataFile) {
|
||||||
|
this.dataFile = dataFile;
|
||||||
|
this.configuration = YamlConfiguration.loadConfiguration(dataFile);
|
||||||
|
if (getConfiguration() != null) {
|
||||||
|
this.identifier = getConfiguration().getString("identifier", "ERROR");
|
||||||
|
this.name = getConfiguration().getString("name", "ERROR");
|
||||||
|
this.content = getConfiguration().getString("content", "&r");
|
||||||
|
this.permission = getConfiguration().getString("permission");
|
||||||
|
this.weight = getConfiguration().getInt("weight", 1);
|
||||||
|
|
||||||
|
this.itemHasPermission = (ItemStack) getConfiguration().get("itemHasPermission",
|
||||||
|
new ItemStackFactory(Material.STONE).setDisplayName(name).addLore(" ").addLore("§a➥ 点击切换到该前缀").toItemStack()
|
||||||
|
);
|
||||||
|
this.itemNoPermission = (ItemStack) getConfiguration().get("itemNoPermission", itemHasPermission);
|
||||||
|
this.itemWhenUsing = (ItemStack) getConfiguration().get("itemUsing", itemHasPermission);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfiguredPrefix(@NotNull String identifier,
|
||||||
|
@NotNull String name,
|
||||||
|
@NotNull String content,
|
||||||
|
int weight, @Nullable String permission,
|
||||||
|
@NotNull ItemStack itemHasPermission,
|
||||||
|
@Nullable ItemStack itemNoPermission,
|
||||||
|
@Nullable ItemStack itemWhenUsing) {
|
||||||
|
this.identifier = identifier;
|
||||||
|
this.name = name;
|
||||||
|
this.content = content;
|
||||||
|
this.weight = weight;
|
||||||
|
this.permission = permission;
|
||||||
|
this.itemHasPermission = itemHasPermission;
|
||||||
|
this.itemNoPermission = itemNoPermission;
|
||||||
|
this.itemWhenUsing = itemWhenUsing;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public FileConfiguration getConfiguration() {
|
||||||
|
return configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String getIdentifier() {
|
||||||
|
return identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String getContent() {
|
||||||
|
return ColorParser.parse(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWeight() {
|
||||||
|
return weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getPermission() {
|
||||||
|
return permission;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public ItemStack getItemHasPermission(@Nullable Player player) {
|
||||||
|
return parseItemStackText(this.itemHasPermission, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public ItemStack getItemHasPermission() {
|
||||||
|
return getItemHasPermission(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public ItemStack getItemNoPermission(@Nullable Player player) {
|
||||||
|
return parseItemStackText(itemNoPermission, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public ItemStack getItemNoPermission() {
|
||||||
|
return getItemNoPermission(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public ItemStack getItemWhenUsing(@Nullable Player player) {
|
||||||
|
return parseItemStackText(itemWhenUsing, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public ItemStack getItemWhenUsing() {
|
||||||
|
return getItemWhenUsing(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPublic() {
|
||||||
|
return getPermission() == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isVisibleNoPermission() {
|
||||||
|
return this.itemNoPermission != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static ItemStack parseItemStackText(@NotNull ItemStack source, @Nullable Player player) {
|
||||||
|
if (player == null) return source;
|
||||||
|
ItemMeta meta = source.getItemMeta();
|
||||||
|
String displayName = null;
|
||||||
|
List<String> lore = null;
|
||||||
|
if (meta != null) {
|
||||||
|
if (meta.hasDisplayName()) displayName = meta.getDisplayName();
|
||||||
|
if (meta.hasLore()) lore = meta.getLore();
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStackFactory factory = new ItemStackFactory(source);
|
||||||
|
if (displayName != null) factory.setDisplayName(MessageUtil.setPlaceholders(player, displayName));
|
||||||
|
if (lore != null) factory.setLore(MessageUtil.setPlaceholders(player, lore));
|
||||||
|
|
||||||
|
return factory.toItemStack();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package cc.carm.plugin.userprefix.ui;
|
package cc.carm.plugin.userprefix.ui;
|
||||||
|
|
||||||
import cc.carm.plugin.userprefix.configuration.PrefixConfig;
|
import cc.carm.plugin.userprefix.configuration.PluginConfig;
|
||||||
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.PrefixManager;
|
||||||
import cc.carm.plugin.userprefix.manager.UserManager;
|
import cc.carm.plugin.userprefix.manager.UserManager;
|
||||||
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
|
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
|
||||||
|
import cc.carm.plugin.userprefix.util.MessageUtil;
|
||||||
import cc.carm.plugin.userprefix.util.gui.AutoPagedGUI;
|
import cc.carm.plugin.userprefix.util.gui.AutoPagedGUI;
|
||||||
import cc.carm.plugin.userprefix.util.gui.GUIItem;
|
import cc.carm.plugin.userprefix.util.gui.GUIItem;
|
||||||
|
import cc.carm.plugin.userprefix.util.gui.GUIType;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.inventory.ClickType;
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
|
||||||
@@ -17,78 +17,81 @@ import java.util.List;
|
|||||||
|
|
||||||
public class PrefixSelectGUI extends AutoPagedGUI {
|
public class PrefixSelectGUI extends AutoPagedGUI {
|
||||||
|
|
||||||
public static HashSet<Player> openingUsers = new HashSet<>();
|
public static HashSet<Player> openingUsers = new HashSet<>();
|
||||||
|
|
||||||
Player player;
|
Player player;
|
||||||
|
|
||||||
public PrefixSelectGUI(Player player) {
|
public PrefixSelectGUI(Player player) {
|
||||||
super(GUIType.SIXBYNINE, "&f&l我的前缀 &8| 列表", 10, 43);
|
super(GUIType.SIXBYNINE, PluginConfig.GUI.TITLE.get(), 10, 43);
|
||||||
this.player = player;
|
this.player = player;
|
||||||
|
|
||||||
setPreviousPageSlot(18);
|
setPreviousPageSlot(18);
|
||||||
setNextPageSlot(26);
|
setNextPageSlot(26);
|
||||||
|
|
||||||
loadItems();
|
loadItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player getPlayer() {
|
public Player getPlayer() {
|
||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadItems() {
|
public void loadItems() {
|
||||||
List<ConfiguredPrefix> prefixList = new ArrayList<>();
|
List<ConfiguredPrefix> prefixList = new ArrayList<>();
|
||||||
prefixList.add(PrefixManager.getDefaultPrefix());
|
prefixList.add(PrefixManager.getDefaultPrefix());
|
||||||
prefixList.addAll(PrefixManager.getVisiblePrefix());
|
prefixList.addAll(PrefixManager.getVisiblePrefix()); //只需要读取看得见的
|
||||||
|
|
||||||
ConfiguredPrefix usingPrefix = UserManager.getPrefix(getPlayer());
|
ConfiguredPrefix usingPrefix = UserManager.getPrefix(getPlayer());
|
||||||
|
|
||||||
for (ConfiguredPrefix prefix : prefixList) {
|
for (ConfiguredPrefix prefix : prefixList) {
|
||||||
if (prefix.getIdentifier().equals(usingPrefix.getIdentifier())) {
|
if (prefix.getIdentifier().equals(usingPrefix.getIdentifier())) {
|
||||||
addItem(new GUIItem(prefix.getItemWhenUsing() != null ? prefix.getItemWhenUsing() : prefix.getItemHasPermission()));
|
addItem(new GUIItem(prefix.getItemWhenUsing(player) != null ? prefix.getItemWhenUsing(player) : prefix.getItemHasPermission(player)));
|
||||||
} else if (UserManager.isPrefixUsable(player, prefix)) {
|
} else if (UserManager.isPrefixUsable(player, prefix)) {
|
||||||
addItem(new GUIItem(prefix.getItemHasPermission()) {
|
addItem(new GUIItem(prefix.getItemHasPermission(player)) {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(ClickType type) {
|
public void onClick(ClickType type) {
|
||||||
if (UserManager.isPrefixUsable(player, prefix)) { //再次检查,防止打开GUI后、选择前的时间段内权限消失
|
//再次检查,防止打开GUI后、选择前的时间段内权限消失
|
||||||
player.closeInventory();
|
if (UserManager.isPrefixUsable(player, prefix)) {
|
||||||
UserManager.setPrefix(player, prefix, true);
|
player.closeInventory();
|
||||||
|
UserManager.setPrefix(player, prefix, true);
|
||||||
|
|
||||||
PrefixConfig.Sounds.PREFIX_CHANGE.play(player);
|
PluginConfig.Sounds.PREFIX_CHANGE.play(player);
|
||||||
MessageUtil.sendWithPlaceholders(player, PrefixConfig.Messages.SELECTED.get(),
|
MessageUtil.sendWithPlaceholders(player, PluginConfig.Messages.SELECTED.get(),
|
||||||
new String[]{"%(name)"},
|
new String[]{"%(name)"},
|
||||||
new Object[]{prefix.getName()});
|
new Object[]{prefix.getName()});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
addItem(new GUIItem(prefix.getItemNoPermission()));
|
addItem(new GUIItem(prefix.getItemNoPermission(player)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClose() {
|
public void onClose() {
|
||||||
openingUsers.remove(player);
|
removeOpening(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeOpening(Player player) {
|
public static void removeOpening(Player player) {
|
||||||
openingUsers.remove(player);
|
openingUsers.remove(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void closeAll() {
|
public static void closeAll() {
|
||||||
for (Player player : new HashSet<>(openingUsers)) {
|
for (Player player : new HashSet<>(openingUsers)) {
|
||||||
player.closeInventory();
|
player.closeInventory();
|
||||||
}
|
}
|
||||||
}
|
openingUsers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
public static void open(Player player) {
|
public static void open(Player player) {
|
||||||
PrefixConfig.Sounds.GUI_OPEN.play(player);
|
player.closeInventory(); // 防止冲突
|
||||||
new PrefixSelectGUI(player).openGUI(player);
|
PluginConfig.Sounds.GUI_OPEN.play(player);
|
||||||
openingUsers.add(player);
|
new PrefixSelectGUI(player).openGUI(player);
|
||||||
}
|
openingUsers.add(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,33 @@
|
|||||||
|
|
||||||
package cc.carm.plugin.userprefix.util;
|
package cc.carm.plugin.userprefix.util;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class ColorParser {
|
public class ColorParser {
|
||||||
|
|
||||||
|
public static String parse(String text) {
|
||||||
|
text = parseHexColor(text);
|
||||||
|
return parseColor(text);
|
||||||
|
}
|
||||||
|
|
||||||
public static String parseColor(final String text) {
|
public static String parseColor(final String text) {
|
||||||
return text.replaceAll("&", "§").replace("§§", "&");
|
return text.replaceAll("&", "§").replace("§§", "&");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String parseHexColor(String text) {
|
||||||
|
Pattern pattern = Pattern.compile("&\\((&?#[0-9a-fA-F]{6})\\)");
|
||||||
|
Matcher matcher = pattern.matcher(text);
|
||||||
|
while (matcher.find()) {
|
||||||
|
String hexColor = text.substring(matcher.start() + 2, matcher.end() - 1);
|
||||||
|
hexColor = hexColor.replace("&", "");
|
||||||
|
StringBuilder bukkitColorCode = new StringBuilder('§' + "x");
|
||||||
|
for (int i = 1; i < hexColor.length(); i++) {
|
||||||
|
bukkitColorCode.append('§').append(hexColor.charAt(i));
|
||||||
|
}
|
||||||
|
text = text.replaceAll("&\\(" + hexColor + "\\)", bukkitColorCode.toString().toLowerCase());
|
||||||
|
matcher.reset(text);
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public class ItemStackFactory {
|
|||||||
public ItemStackFactory setDisplayName(@NotNull String name) {
|
public ItemStackFactory setDisplayName(@NotNull String name) {
|
||||||
ItemMeta im = this.item.getItemMeta();
|
ItemMeta im = this.item.getItemMeta();
|
||||||
if (im != null) {
|
if (im != null) {
|
||||||
im.setDisplayName(ColorParser.parseColor(name));
|
im.setDisplayName(ColorParser.parse(name));
|
||||||
this.item.setItemMeta(im);
|
this.item.setItemMeta(im);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
@@ -71,7 +71,7 @@ public class ItemStackFactory {
|
|||||||
if (im != null) {
|
if (im != null) {
|
||||||
im.setLore(
|
im.setLore(
|
||||||
loreList.stream()
|
loreList.stream()
|
||||||
.map(ColorParser::parseColor)
|
.map(ColorParser::parse)
|
||||||
.collect(Collectors.toList())
|
.collect(Collectors.toList())
|
||||||
);
|
);
|
||||||
this.item.setItemMeta(im);
|
this.item.setItemMeta(im);
|
||||||
@@ -83,7 +83,7 @@ public class ItemStackFactory {
|
|||||||
ItemMeta im = this.item.getItemMeta();
|
ItemMeta im = this.item.getItemMeta();
|
||||||
if (im != null) {
|
if (im != null) {
|
||||||
List<String> lore = im.getLore() != null ? im.getLore() : new ArrayList<>();
|
List<String> lore = im.getLore() != null ? im.getLore() : new ArrayList<>();
|
||||||
lore.add(ColorParser.parseColor(s));
|
lore.add(ColorParser.parse(s));
|
||||||
im.setLore(lore);
|
im.setLore(lore);
|
||||||
this.item.setItemMeta(im);
|
this.item.setItemMeta(im);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,63 +1,102 @@
|
|||||||
package cc.carm.plugin.userprefix.util;
|
package cc.carm.plugin.userprefix.util;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPI;
|
import me.clip.placeholderapi.PlaceholderAPI;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class MessageUtil {
|
public class MessageUtil {
|
||||||
|
|
||||||
public static void send(Player player, List<String> messages) {
|
public static boolean hasPlaceholderAPI() {
|
||||||
for (String s : messages) {
|
return Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null;
|
||||||
player.sendMessage(ColorParser.parseColor(s));
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void send(Player player, String... messages) {
|
public static void send(@Nullable CommandSender sender, List<String> messages) {
|
||||||
send(player, Arrays.asList(messages));
|
if (messages == null || messages.isEmpty() || sender == null) return;
|
||||||
}
|
for (String s : messages) {
|
||||||
|
sender.sendMessage(ColorParser.parse(s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void sendWithPlaceholders(Player player, String... messages) {
|
public static void send(@Nullable CommandSender sender, String... messages) {
|
||||||
sendWithPlaceholders(player, Arrays.asList(messages));
|
send(sender, Arrays.asList(messages));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendWithPlaceholders(Player player, List<String> messages) {
|
public static void sendWithPlaceholders(CommandSender sender, String... messages) {
|
||||||
send(player, PlaceholderAPI.setPlaceholders(player, messages));
|
sendWithPlaceholders(sender, Arrays.asList(messages));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendWithPlaceholders(Player player, List<String> messages, String param, Object value) {
|
public static void sendWithPlaceholders(@Nullable CommandSender sender, List<String> messages) {
|
||||||
sendWithPlaceholders(player, messages, new String[]{param}, new Object[]{value});
|
if (messages == null || messages.isEmpty() || sender == null) return;
|
||||||
}
|
send(sender, setPlaceholders(sender, messages));
|
||||||
|
}
|
||||||
|
|
||||||
public static void sendWithPlaceholders(Player player, List<String> messages, String[] params, Object[] values) {
|
public static void sendWithPlaceholders(@Nullable CommandSender sender, List<String> messages, String param, Object value) {
|
||||||
sendWithPlaceholders(player, setCustomParams(messages, params, values));
|
sendWithPlaceholders(sender, messages, new String[]{param}, new Object[]{value});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> setCustomParams(List<String> messages, String param, Object value) {
|
public static void sendWithPlaceholders(@Nullable CommandSender sender, List<String> messages, String[] params, Object[] values) {
|
||||||
return setCustomParams(messages, new String[]{param}, new Object[]{value});
|
sendWithPlaceholders(sender, setCustomParams(messages, params, values));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> setCustomParams(List<String> messages, String[] params, Object[] values) {
|
public static String setPlaceholders(@Nullable CommandSender sender, String message) {
|
||||||
if (params.length != values.length) return messages;
|
if (message == null) return null;
|
||||||
HashMap<String, Object> paramsMap = new HashMap<>();
|
|
||||||
for (int i = 0; i < params.length; i++) {
|
message = ColorParser.parse(message);
|
||||||
paramsMap.put(params[i], values[i]);
|
if (sender == null) return message;
|
||||||
}
|
|
||||||
return setCustomParams(messages, paramsMap);
|
if (hasPlaceholderAPI() && sender instanceof Player) {
|
||||||
}
|
return PlaceholderAPI.setPlaceholders((Player) sender, message);
|
||||||
|
} else {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> setPlaceholders(@Nullable CommandSender sender, List<String> messages) {
|
||||||
|
if (messages == null || messages.isEmpty()) return new ArrayList<>();
|
||||||
|
messages = messages.stream().map(ColorParser::parse).collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (sender == null) return messages;
|
||||||
|
if (hasPlaceholderAPI() && sender instanceof Player) {
|
||||||
|
return PlaceholderAPI.setPlaceholders((Player) sender, messages);
|
||||||
|
} else {
|
||||||
|
return messages;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> setPlaceholders(@Nullable CommandSender sender, List<String> messages, String[] params, Object[] values) {
|
||||||
|
return setPlaceholders(sender, setCustomParams(messages, params, values));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> setCustomParams(List<String> messages, String param, Object value) {
|
||||||
|
return setCustomParams(messages, new String[]{param}, new Object[]{value});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> setCustomParams(List<String> messages, String[] params, Object[] values) {
|
||||||
|
if (params.length != values.length) return messages;
|
||||||
|
HashMap<String, Object> paramsMap = new HashMap<>();
|
||||||
|
for (int i = 0; i < params.length; i++) {
|
||||||
|
paramsMap.put(params[i], values[i]);
|
||||||
|
}
|
||||||
|
return setCustomParams(messages, paramsMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static List<String> setCustomParams(List<String> messages, HashMap<String, Object> params) {
|
public static List<String> setCustomParams(List<String> messages, HashMap<String, Object> params) {
|
||||||
List<String> list = new ArrayList<>();
|
List<String> list = new ArrayList<>();
|
||||||
for (String message : messages) {
|
for (String message : messages) {
|
||||||
String afterMessage = message;
|
String afterMessage = message;
|
||||||
for (Map.Entry<String, Object> entry : params.entrySet()) {
|
for (Map.Entry<String, Object> entry : params.entrySet()) {
|
||||||
afterMessage = afterMessage.replace(entry.getKey(), entry.getValue().toString());
|
afterMessage = afterMessage.replace(entry.getKey(), entry.getValue().toString());
|
||||||
}
|
}
|
||||||
list.add(afterMessage);
|
list.add(afterMessage);
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,95 +1,93 @@
|
|||||||
package cc.carm.plugin.userprefix.util.gui;
|
package cc.carm.plugin.userprefix.util.gui;
|
||||||
|
|
||||||
import cc.carm.plugin.userprefix.configuration.PrefixConfig;
|
import cc.carm.plugin.userprefix.configuration.PluginConfig;
|
||||||
import cc.carm.plugin.userprefix.util.ItemStackFactory;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.inventory.ClickType;
|
import org.bukkit.event.inventory.ClickType;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
public class AutoPagedGUI extends CommonPagedGUI {
|
public class AutoPagedGUI extends CommonPagedGUI {
|
||||||
|
|
||||||
ItemStack previousPageUI;
|
ItemStack previousPageUI;
|
||||||
ItemStack nextPageUI;
|
ItemStack nextPageUI;
|
||||||
ItemStack noPreviousPageUI;
|
ItemStack noPreviousPageUI;
|
||||||
ItemStack noNextPageUI;
|
ItemStack noNextPageUI;
|
||||||
int previousPageSlot = -1;
|
int previousPageSlot = -1;
|
||||||
int nextPageSlot = -1;
|
int nextPageSlot = -1;
|
||||||
|
|
||||||
public AutoPagedGUI(GUIType type, String name, int[] range) {
|
public AutoPagedGUI(GUIType type, String name, int[] range) {
|
||||||
super(type, name, range);
|
super(type, name, range);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AutoPagedGUI(GUIType type, String name, int a, int b) {
|
public AutoPagedGUI(GUIType type, String name, int a, int b) {
|
||||||
super(type, name, a, b);
|
super(type, name, a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPreviousPageUI(ItemStack lastPageUI) {
|
public void setPreviousPageUI(ItemStack lastPageUI) {
|
||||||
this.previousPageUI = lastPageUI;
|
this.previousPageUI = lastPageUI;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNextPageUI(ItemStack nextPageUI) {
|
public void setNextPageUI(ItemStack nextPageUI) {
|
||||||
this.nextPageUI = nextPageUI;
|
this.nextPageUI = nextPageUI;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNoPreviousPageUI(ItemStack noPreviousPageUI) {
|
public void setNoPreviousPageUI(ItemStack noPreviousPageUI) {
|
||||||
this.noPreviousPageUI = noPreviousPageUI;
|
this.noPreviousPageUI = noPreviousPageUI;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNoNextPageUI(ItemStack noNextPageUI) {
|
public void setNoNextPageUI(ItemStack noNextPageUI) {
|
||||||
this.noNextPageUI = noNextPageUI;
|
this.noNextPageUI = noNextPageUI;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPreviousPageSlot(int slot) {
|
public void setPreviousPageSlot(int slot) {
|
||||||
this.previousPageSlot = slot;
|
this.previousPageSlot = slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNextPageSlot(int slot) {
|
public void setNextPageSlot(int slot) {
|
||||||
this.nextPageSlot = slot;
|
this.nextPageSlot = slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void openGUI(Player user) {
|
public void openGUI(Player user) {
|
||||||
if (previousPageSlot >= 0)
|
if (previousPageSlot >= 0) {
|
||||||
if (hasPreviousPage()) {
|
if (hasPreviousPage()) {
|
||||||
setItem(previousPageSlot, new GUIItem(previousPageUI == null ? new ItemStackFactory(Material.ARROW)
|
setItem(previousPageSlot, new GUIItem(previousPageUI == null ? PluginConfig.GUI.Items.PREVIOUS_PAGE.get() : previousPageUI) {
|
||||||
.setDisplayName("&f上一页")
|
@Override
|
||||||
.addLore("&7&o右键可前往第一页哦")
|
public void onClick(ClickType type) {
|
||||||
.toItemStack() : previousPageUI) {
|
if (type == ClickType.RIGHT) {
|
||||||
@Override
|
goFirstPage();
|
||||||
public void onClick(ClickType type) {
|
} else {
|
||||||
if (type == ClickType.RIGHT) {
|
goPreviousPage();
|
||||||
goFirstPage();
|
}
|
||||||
} else {
|
PluginConfig.Sounds.GUI_CLICK.play(user);
|
||||||
goPreviousPage();
|
openGUI(user);
|
||||||
}
|
}
|
||||||
PrefixConfig.Sounds.GUI_CLICK.play(user);
|
});
|
||||||
openGUI(user);
|
} else {
|
||||||
}
|
setItem(previousPageSlot, null);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (previousPageSlot >= 0)
|
if (nextPageSlot >= 0) {
|
||||||
if (hasNextPage()) {
|
if (hasNextPage()) {
|
||||||
setItem(nextPageSlot, new GUIItem(nextPageUI == null ? new ItemStackFactory(Material.ARROW)
|
setItem(nextPageSlot, new GUIItem(nextPageUI == null ? PluginConfig.GUI.Items.NEXT_PAGE.get() : nextPageUI) {
|
||||||
.setDisplayName("下一页")
|
@Override
|
||||||
.addLore("&7&o右键可前往最后一页哦")
|
public void onClick(ClickType type) {
|
||||||
.toItemStack() : nextPageUI) {
|
if (type == ClickType.RIGHT) {
|
||||||
@Override
|
goLastPage();
|
||||||
public void onClick(ClickType type) {
|
} else {
|
||||||
if (type == ClickType.RIGHT) {
|
goNextPage();
|
||||||
goLastPage();
|
}
|
||||||
} else {
|
PluginConfig.Sounds.GUI_CLICK.play(user);
|
||||||
goNextPage();
|
openGUI(user);
|
||||||
}
|
}
|
||||||
PrefixConfig.Sounds.GUI_CLICK.play(user);
|
});
|
||||||
openGUI(user);
|
} else {
|
||||||
}
|
setItem(nextPageSlot, null);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.openGUI(user);
|
super.openGUI(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class GUI {
|
|||||||
|
|
||||||
public GUI(GUIType type, String name) {
|
public GUI(GUIType type, String name) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.name = ColorParser.parseColor(name);
|
this.name = ColorParser.parse(name);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ONEBYNINE:
|
case ONEBYNINE:
|
||||||
this.items = new GUIItem[9];
|
this.items = new GUIItem[9];
|
||||||
|
|||||||
@@ -1,17 +1,56 @@
|
|||||||
version: ${project.version}
|
version: ${project.version} #配置文件版本,若与插件版本不同请记得检查配置文件内容
|
||||||
|
|
||||||
debug: false
|
debug: false
|
||||||
|
|
||||||
|
# 统计数据设定
|
||||||
|
# 改选项用于帮助开发者统计插件版本与使用情况,且绝不会影响性能与使用体验。
|
||||||
|
# 当然,您也可以选择在这里关闭,或在plugins/bStats下的配置文件中关闭。
|
||||||
|
metrics: true
|
||||||
|
|
||||||
|
custom-storage:
|
||||||
|
# 自定义存储位置
|
||||||
|
# 默认存储位置为 “插件文件夹”/prefixes
|
||||||
|
# 可以规定到远程文件夹中去寻找前缀相关的设定
|
||||||
|
# 支持绝对文件路径,如 "/etc/minecraft/configurations/prefixes/"
|
||||||
|
enable: false # 是否启用
|
||||||
|
path: "prefixes/" # 一定要指向一个文件夹!
|
||||||
|
|
||||||
functions:
|
functions:
|
||||||
OnNamePrefix: true # 是否给头顶上添加前缀,该方法用到了头顶的那个计分板,如有冲突请关掉哦~
|
OnNamePrefix: true # 是否给头顶上添加前缀,该方法用到了头顶的那个计分板,如有冲突请关掉哦~
|
||||||
autoUsePrefix: true # 自动前缀显示 当玩家没有自己选择一个前缀的时候,会自动使用所拥有的的前缀中权重最高的那一个
|
autoUsePrefix: true # 自动前缀显示 当玩家没有自己选择一个前缀的时候,会自动使用所拥有的的前缀中权重最高的那一个
|
||||||
|
chat:
|
||||||
|
# 聊天功能
|
||||||
|
# - 我不推荐使用本插件的聊天功能,而是建议使用其他的聊天插件。
|
||||||
|
# - 本插件仅仅提供了**最基本**的格式变量支持,不包含其他任何功能。
|
||||||
|
# - 注意聊天格式需要遵守Bukkit原格式,即不得缺失 “%1$s” 和 “%2$s” 。
|
||||||
|
# - 本插件的聊天功能不影响其他插件对聊天事件的操作。
|
||||||
|
enable: false # 是否启用
|
||||||
|
format: "<%UserPrefix_prefix%%1$s> %2$s" #聊天的格式,注意 “%1$s” 和 “%2$s” 不可缺少,分别代表 玩家名 与 消息内容 。
|
||||||
|
|
||||||
messages:
|
GUI:
|
||||||
selected:
|
title: "&f&l我的前缀 &8| 列表"
|
||||||
- "&7您选择了 &f%(name) &7作为当前显示的前缀。"
|
items:
|
||||||
expired:
|
# 【必须】 GUI中可能存在的其他物品
|
||||||
- "&7您先前使用的前缀 &f%(oldName) &7已到期。"
|
next-page: # 下一页物品,如果没有下一页则不显示
|
||||||
- "&7现在已为您重新调整为 &f%(newName) &7。"
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: ARROW
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "&f下一页"
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "&f右键可前往最后一页哦~"
|
||||||
|
previous-page: # 上一页物品,如果没有上一页则不显示
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: ARROW
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "&f上一页"
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "&f右键可前往第一页哦~"
|
||||||
|
|
||||||
Sounds: #相关的声音,注释掉则不播放声音 格式为 【声音名:音量:音调】 或 【声音名:音量】 或 【声音名】
|
Sounds: #相关的声音,注释掉则不播放声音 格式为 【声音名:音量:音调】 或 【声音名:音量】 或 【声音名】
|
||||||
openGUI: "BLOCK_NOTE_BLOCK_PLING:1:1"
|
openGUI: "BLOCK_NOTE_BLOCK_PLING:1:1"
|
||||||
@@ -30,71 +69,17 @@ defaultPrefix:
|
|||||||
meta:
|
meta:
|
||||||
==: ItemMeta
|
==: ItemMeta
|
||||||
meta-type: UNSPECIFIC
|
meta-type: UNSPECIFIC
|
||||||
display-name: "§f默认玩家前缀 §f(点击切换)"
|
display-name: "&f默认玩家前缀 &f(点击切换)"
|
||||||
lore:
|
lore:
|
||||||
- ""
|
- ""
|
||||||
- "§a➥ 点击切换到该前缀"
|
- "&a➥ 点击切换到该前缀"
|
||||||
itemUsing:
|
itemUsing:
|
||||||
==: org.bukkit.inventory.ItemStack
|
==: org.bukkit.inventory.ItemStack
|
||||||
type: NAME_TAG
|
type: NAME_TAG
|
||||||
meta:
|
meta:
|
||||||
==: ItemMeta
|
==: ItemMeta
|
||||||
meta-type: UNSPECIFIC
|
meta-type: UNSPECIFIC
|
||||||
display-name: "§f默认玩家前缀"
|
display-name: "&f默认玩家前缀"
|
||||||
lore:
|
lore:
|
||||||
- ""
|
- ""
|
||||||
- "§a✔ 您正在使用该前缀"
|
- "&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+会员以使用该前缀!"
|
|
||||||
|
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
version: ${project.version} # DO NOT EDIT IT
|
||||||
|
|
||||||
|
debug: false #DEBUG OUT PUT
|
||||||
|
|
||||||
|
metrics: true #Metrics stats (to help developer know the stats)
|
||||||
|
|
||||||
|
custom-storage:
|
||||||
|
# Custom storage location
|
||||||
|
# default location is "./prefixes"
|
||||||
|
# Support absolute file path , such as "/etc/minecraft/configurations/prefixes/"
|
||||||
|
enable: false
|
||||||
|
path: "prefixes/" # Must be a folder!
|
||||||
|
|
||||||
|
GUI:
|
||||||
|
title: "&f&lMy Prefixes List" # Title of the GUI
|
||||||
|
items:
|
||||||
|
next-page: # only show has next page
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: ARROW
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§fNext Page"
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "§fRight-Click to the last page"
|
||||||
|
previous-page: # only show has previous page
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: ARROW
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§fPrevious Page"
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "§fRight-Click to the first page"
|
||||||
|
|
||||||
|
functions:
|
||||||
|
# Whether to add a prefix to the top of the head,
|
||||||
|
# this method uses the scoreboard above the head,
|
||||||
|
# please turn it off if there is a conflict.
|
||||||
|
OnNamePrefix: true
|
||||||
|
# Automatic prefix select.
|
||||||
|
# When the player does not choose a prefix by himself,
|
||||||
|
# the prefix with the highest weight will be used automatically
|
||||||
|
autoUsePrefix: true
|
||||||
|
chat:
|
||||||
|
# Chat Function
|
||||||
|
# - I recommend using other chat plugins instead of using this plugin,
|
||||||
|
# - this plugin only provides very basic chat format placeholders.
|
||||||
|
# - Notice that: format must has “%1$s” and “%2$s” for PlayerName and Message (Bukkit Chat Event)
|
||||||
|
enable: false
|
||||||
|
format: "<%UserPrefix_prefix%%1$s> %2$s"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Sounds:
|
||||||
|
# Format is [SOUND_NAME:Volume:Pitch] or [SOUND_NAME:Volume] or [SOUND_NAME]
|
||||||
|
openGUI: "BLOCK_NOTE_BLOCK_PLING:1:1"
|
||||||
|
guiClick: "UI_BUTTON_CLICK"
|
||||||
|
prefixChange: "ENTITY_VILLAGER_YES"
|
||||||
|
prefixExpired: "ENTITY_VILLAGER_NO"
|
||||||
|
|
||||||
|
# The default prefix's weight is 0.
|
||||||
|
defaultPrefix:
|
||||||
|
name: "Default prefix"
|
||||||
|
content: "&b"
|
||||||
|
itemNotUsing:
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: NAME_TAG
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§fThe default prefix §f(Click to select)"
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "§a➥ Click to use"
|
||||||
|
itemUsing:
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: NAME_TAG
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "§fThe default prefix"
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "§a✔ Selected"
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
|
||||||
|
# identifier [Necessary]
|
||||||
|
# This will be used for data-storage.
|
||||||
|
identifier: "pro"
|
||||||
|
|
||||||
|
# Name [Necessary]
|
||||||
|
# Use in messages.
|
||||||
|
name: "&b&lPro&b"
|
||||||
|
|
||||||
|
# Content [Necessary]
|
||||||
|
# Use in Placeholders
|
||||||
|
content: "&b&lPro &b"
|
||||||
|
|
||||||
|
# Weight [Necessary]
|
||||||
|
# used for sorting in the GUI and TabList
|
||||||
|
# In GUI : the larger is displayed at the back
|
||||||
|
# At TabList : the larger is displayed at the top
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
# Permission [Unnecessary]
|
||||||
|
# If there is no permission for detection, everyone can use it,
|
||||||
|
# which means there is no need to configure "itemNoPermission"
|
||||||
|
# (because it is impossible to display items without permission at all)
|
||||||
|
permission: "yc.vip"
|
||||||
|
|
||||||
|
# itemHasPermission [Necessary]
|
||||||
|
# This Item will be displayed when player has permission
|
||||||
|
itemHasPermission:
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: DIAMOND
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "&b&lVIP Prefix"
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "&a➥ Click to use"
|
||||||
|
|
||||||
|
# itemUsing [Unnecessary]
|
||||||
|
# This Item will be displayed when the prefix is selected.
|
||||||
|
# If there is no such configuration, it will automatically display "itemHasPermission".
|
||||||
|
itemUsing:
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: DIAMOND
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "&b&lVIP Prefix"
|
||||||
|
enchants:
|
||||||
|
PROTECTION_ENVIRONMENTAL: 1 #Add an enchantment so it looks like it’s selected
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "&a✔ Selected"
|
||||||
|
|
||||||
|
# itemNoPermission [Unnecessary]
|
||||||
|
# If player doesn't have the permission,this item will be displayed.
|
||||||
|
# If this item is not configured, it will not be displayed in the GUI when the player does not have permission to use it.
|
||||||
|
itemNoPermission:
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: INK_SACK
|
||||||
|
damage: 8
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "&b&lVIP &c(Buy it!)"
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "&e✯ Buy the VIP to use it!"
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
selected:
|
||||||
|
- "&7You have selected the &f%(name) &7as current prefix."
|
||||||
|
expired:
|
||||||
|
- "&7Your prefix &f%(oldName) &7has expired,"
|
||||||
|
- "&7Now the prefix is changed to &f%(newName) &7."
|
||||||
|
removed:
|
||||||
|
- "&7Your using prefix has been removed, now the prefix is changed to &f%(newName) &7."
|
||||||
|
reload:
|
||||||
|
- "&a&lReload completed!&7costs &f%(time)ms&7."
|
||||||
|
help:
|
||||||
|
- "&3&lUserPrefixAdmin &fHelp"
|
||||||
|
- "&8#/upa&f list"
|
||||||
|
- "&8- &7Show configured prefixes."
|
||||||
|
- "&8#/upa&f reload"
|
||||||
|
- "&8- &7Reload configuration."
|
||||||
|
list-title:
|
||||||
|
- "&3&lUserPrefixAdmin &fList"
|
||||||
|
list-value:
|
||||||
|
- "&8#%(weight) &f%(identifier)"
|
||||||
|
- "&8- &7Name &r%(name) &7Perm &r%(permission)"
|
||||||
|
- "&8- &7Example&r %(content) %(sender_name)"
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
selected:
|
||||||
|
- "&7您选择了 &f%(name) &7作为当前显示的前缀。"
|
||||||
|
expired:
|
||||||
|
- "&7您先前使用的前缀 &f%(oldName) &7已到期。"
|
||||||
|
- "&7现在已为您重新调整为 &f%(newName) &7。"
|
||||||
|
removed:
|
||||||
|
- "&7您先前使用的前缀已被移除,现在已为您重新调整为 &f%(newName) &7。"
|
||||||
|
reload:
|
||||||
|
- "&a&l重载完成!&7共耗时 &f%(time)ms&7。"
|
||||||
|
help:
|
||||||
|
- "&3&l用户前缀系统 &f帮助"
|
||||||
|
- "&8#/upa&f list"
|
||||||
|
- "&8- &7查看当前前缀列表。"
|
||||||
|
- "&8#/upa&f reload"
|
||||||
|
- "&8- &7重载前缀配置。"
|
||||||
|
list-title:
|
||||||
|
- "&3&l用户前缀系统 &f前缀列表"
|
||||||
|
list-value:
|
||||||
|
- "&8#%(weight) &f%(identifier)"
|
||||||
|
- "&8- &7显示名 &r%(name) &7权限 &r%(permission)"
|
||||||
|
- "&8- &7内容示例&r %(content) %(sender_name)"
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
main: cc.carm.plugin.userprefix.Main
|
main: cc.carm.plugin.userprefix.Main
|
||||||
name: UserPrefix
|
name: ${project.name}
|
||||||
version: ${project.version}
|
version: ${project.version}
|
||||||
authors:
|
authors:
|
||||||
- Carm
|
- Carm
|
||||||
- YourCraft
|
- ${project.organization.name}
|
||||||
- SakuraGame
|
- SakuraGame
|
||||||
|
website: ${project.url}
|
||||||
|
description: ${project.description}
|
||||||
|
|
||||||
depend:
|
depend:
|
||||||
- LuckPerms
|
- LuckPerms
|
||||||
softdepend:
|
softdepend:
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
# 唯一标识 [必须]
|
||||||
|
# 将用于记录玩家所选的前缀,以及用于数据的缓存。
|
||||||
|
# 必须 必须 必须 保持唯一!
|
||||||
|
identifier: "pro"
|
||||||
|
|
||||||
|
# 名字 [必须]
|
||||||
|
# 切换的时候左下角会弹提示 用的就是这个名字
|
||||||
|
name: "&b&lPro&b"
|
||||||
|
|
||||||
|
# 内容 [必须]
|
||||||
|
# 显示在名字前面的内容
|
||||||
|
content: "&b&lPro &b"
|
||||||
|
|
||||||
|
# 权重 [必须]
|
||||||
|
# 用于GUI、TabList的排序和自动前缀显示
|
||||||
|
# 在GUI中,权重越高的会显示在越后面
|
||||||
|
# 在TabList中,权重越高的会显示在越上面
|
||||||
|
weight: 1
|
||||||
|
|
||||||
|
|
||||||
|
# 检测的权限 [非必须]
|
||||||
|
# 如果没有就是人人都能用,也代表不用配置“itemNoPermission”了(因为压根不可能显示没权限时候的物品)
|
||||||
|
permission: "yc.pro"
|
||||||
|
|
||||||
|
# 有权限时显示的物品 [必须]
|
||||||
|
# 当用户有权限且未选中时,会显示该物品
|
||||||
|
itemHasPermission: #
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: DIAMOND
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "&b&lPro &b会员前缀"
|
||||||
|
lore:
|
||||||
|
- "&7Pro会员专属称号"
|
||||||
|
- ""
|
||||||
|
- "&f尊贵的Pro会员专属称号。"
|
||||||
|
- "&f您将获得多种特权与更好的游戏体验。"
|
||||||
|
- ""
|
||||||
|
- "&a➥ 点击切换到该前缀"
|
||||||
|
|
||||||
|
# 正在使用时显示的物品 [非必需]
|
||||||
|
# 当用户正在使用时会显示这个物品,不配置即自动加载“itemHasPermission”
|
||||||
|
itemUsing:
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: DIAMOND
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "&b&lPro &b会员前缀"
|
||||||
|
enchants:
|
||||||
|
PROTECTION_ENVIRONMENTAL: 1 #加一个附魔这样看上去就像是选中了的
|
||||||
|
lore:
|
||||||
|
- "&7Pro会员专属称号"
|
||||||
|
- ""
|
||||||
|
- "&f尊贵的Pro会员专属称号。"
|
||||||
|
- "&f您将获得多种特权与更好的游戏体验。"
|
||||||
|
- ""
|
||||||
|
- "&a✔ 您正在使用该前缀"
|
||||||
|
|
||||||
|
# 没有权限时显示的物品 [非必需]
|
||||||
|
# 如果没有权限就会显示这个item。如果不配置该物品,则玩家没有使用权限时不会显示在GUI里面。
|
||||||
|
itemNoPermission:
|
||||||
|
==: org.bukkit.inventory.ItemStack
|
||||||
|
type: INK_SACK
|
||||||
|
damage: 8
|
||||||
|
meta:
|
||||||
|
==: ItemMeta
|
||||||
|
meta-type: UNSPECIFIC
|
||||||
|
display-name: "&b&lPro+ &b会员前缀 &c(未拥有)"
|
||||||
|
lore:
|
||||||
|
- "&7Pro+会员专属称号"
|
||||||
|
- ""
|
||||||
|
- "&f尊贵的Pro会员专属称号。"
|
||||||
|
- "&f您将获得多种特权与更好的游戏体验。"
|
||||||
|
- "&f您可以输入 &b/vip &f指令查看详细特权!"
|
||||||
|
- ""
|
||||||
|
- "&e✯ 加入Pro+会员以使用该前缀!"
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import cc.carm.plugin.userprefix.util.ColorParser;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class ColorParseTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onTest() {
|
||||||
|
String testString = "&f爱的人永远不爱我,为何付出得到的只有&(#aaaaaa)背叛。";
|
||||||
|
|
||||||
|
System.out.println(ColorParser.parseHexColor(testString));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||