1
mirror of https://github.com/CarmJos/UserPrefix.git synced 2026-06-05 09:01:39 +08:00

Compare commits

..

55 Commits

Author SHA1 Message Date
carm 78f9639092 [v2.3.0] [U] 修改图片位置 2022-01-07 08:45:46 +08:00
carm 096c23351f Merge remote-tracking branch 'origin/master' 2022-01-07 08:37:36 +08:00
carm b4f8404648 [v2.3.0] 版本更新
- [A] 添加数个事件,方便其他插件调用使用。
- [A] 当原前缀已不存在的情况下的向玩家发送消息。
2022-01-07 08:37:25 +08:00
carm 623356ce21 Update README.md 2022-01-03 15:32:57 +08:00
carm 9164541e4f Merge remote-tracking branch 'origin/master' 2022-01-02 10:14:23 +08:00
carm 2453305420 添加更多统计数据 2022-01-02 10:14:11 +08:00
carm 1856de5e5d Update README.md 2022-01-02 09:33:03 +08:00
carm c38adbeca6 添加统计数据显示 2021-12-31 02:34:31 +08:00
carm 0e90890c67 [v2.2.1] [A] 添加统计数据获取与开关设定。 2021-12-31 02:00:53 +08:00
carm 7e4ca870b5 [v2.2.1] [U] 添加统计数据获取与开关设定。 2021-12-31 01:57:53 +08:00
carm 42b71714aa [v2.2.0] [U] 增添对原生ItemStack配置中 displayName 和 lore的RPG颜色代码支持与PlaceholderAPI变量支持。 2021-12-31 00:08:07 +08:00
carm 0d6247b0f2 [v2.2.0] [U] 增添对原生ItemStack配置中 displayName 和 lore的RPG颜色代码支持与PlaceholderAPI变量支持。 2021-12-30 22:56:33 +08:00
carm 1b9f4f3e55 添加折叠 2021-12-20 18:57:53 +08:00
carm b76081bb6b 添加折叠 2021-12-20 18:55:45 +08:00
carm b8d6862b17 添加折叠 2021-12-20 18:52:42 +08:00
carm 46fb39d7bb 修改路径 2021-11-23 04:37:51 +08:00
carm 523a4f872b 移除样式 2021-11-23 04:31:16 +08:00
carm 5151f1f917 不再整理 2021-11-23 04:27:22 +08:00
carm 296339ca6f 不再整理 2021-11-23 04:22:09 +08:00
carm 63b69defcc 改为中文界面 2021-11-23 04:20:37 +08:00
carm 857ce5c27b 改为中文界面 2021-11-23 04:19:38 +08:00
carm a5189ff314 改为中文界面 2021-11-23 04:16:59 +08:00
carm bacb0b1bed 添加字符集限定 2021-11-23 04:11:31 +08:00
carm 1826f08575 移除自定义css 2021-11-23 04:05:49 +08:00
carm 4df2a49c5b 移除自定义css 2021-11-23 04:03:47 +08:00
carm cbb9928232 自动部署 2021-11-23 03:58:49 +08:00
carm 967984e0c3 自动部署 2021-11-23 03:46:35 +08:00
carm ad780a00bd 自动部署 2021-11-23 03:45:31 +08:00
carm 43c2c14cb3 自动部署 2021-11-23 03:38:26 +08:00
carm 8521d87c46 优化javadoc 2021-11-23 03:36:30 +08:00
carm 378e518e72 Javadoc自动部署 2021-11-23 03:34:03 +08:00
carm 84cbe0c61a 优化javadoc 2021-11-23 03:24:35 +08:00
carm 90f7f7f2e5 优化javadoc 2021-11-23 03:23:39 +08:00
carm 48147aec16 优化javadoc 2021-11-23 03:21:12 +08:00
carm e7c8ce284c 优化javadoc 2021-11-23 03:19:44 +08:00
carm e8b603debc 优化javadoc 2021-11-23 03:17:49 +08:00
carm 72730fad1a 测试Javadoc部署 2021-11-23 03:06:39 +08:00
carm a87e97f744 测试Javadoc部署 2021-11-23 03:02:51 +08:00
carm b2f7338ba6 测试Javadoc部署 2021-11-23 02:58:03 +08:00
carm f91a2aa198 测试Javadoc部署 2021-11-23 02:56:11 +08:00
carm 124ee0f9c3 测试Javadoc部署 2021-11-23 02:46:51 +08:00
carm 9f738ff1ae 修改版本号 2021-11-21 20:01:49 +08:00
carm f23fa03f7a 添加ASCII文字与插件介绍 2021-11-21 19:53:12 +08:00
carm cf749bf5c0 添加下载地址 2021-11-02 11:47:13 +08:00
Carm 01e321686f Merge pull request #6 from CarmJos/dependabot/maven/junit-junit-4.13.1
Bump junit from 4.13 to 4.13.1
2021-10-30 17:59:07 +08:00
dependabot[bot] deba26c713 Bump junit from 4.13 to 4.13.1
Bumps [junit](https://github.com/junit-team/junit4) from 4.13 to 4.13.1.
- [Release notes](https://github.com/junit-team/junit4/releases)
- [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.13.1.md)
- [Commits](https://github.com/junit-team/junit4/compare/r4.13...r4.13.1)

---
updated-dependencies:
- dependency-name: junit:junit
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-30 09:56:26 +00:00
Carm 5b4d49f6ed Create codeql-analysis.yml 2021-10-30 17:54:55 +08:00
carm 2e5250dd36 更新帖子 2021-10-25 08:10:54 +08:00
carm 88730c98f2 更新帖子 2021-10-25 07:58:43 +08:00
carm e003a543f5 支持由控制台为其他玩家打开GUI 2021-10-24 21:22:08 +08:00
Carm 07edaeb401 Merge pull request #5 from Yurinann/master
添加控制台尝试打开称号菜单时的反馈
2021-10-24 21:17:10 +08:00
carm 2357699324 自动提交默认值 2021-10-24 21:14:29 +08:00
“Yurinan” c2fa1a1e95 添加控制台尝试打开称号菜单时的反馈 2021-10-24 14:29:57 +08:00
carm 3b03ec4616 修改readme 2021-10-24 07:22:23 +08:00
carm 1a2644210b 2.1.7 提供自定义配置文件存储位置的功能 2021-10-24 07:12:47 +08:00
42 changed files with 1557 additions and 833 deletions
+9
View File
@@ -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) 。
+73
View File
@@ -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

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before

Width:  |  Height:  |  Size: 212 KiB

After

Width:  |  Height:  |  Size: 212 KiB

Before

Width:  |  Height:  |  Size: 920 KiB

After

Width:  |  Height:  |  Size: 920 KiB

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

@@ -67,13 +67,89 @@
[hr]
[size=4][b]基础配置文件 [/b][/size][color=#24292f][font=Tahoma][size=4](config.yml)[/size][/font][/color]
[spoiler]
[code] version: 1.0.0-SNAPSHOT # 配置文件版本,一般不会动。
[code]
version: ${project.version} #配置文件版本,若与插件版本不同请记得检查配置文件内容
debug: false #debug输出,开发者用的
debug: false
custom-storage:
# 自定义存储位置
# 默认存储位置为 “插件文件夹”/prefixes
# 可以规定到远程文件夹中去寻找前缀相关的设定
# 支持绝对文件路径,如 "/etc/minecraft/configurations/prefixes/"
enable: false # 是否启用
path: "prefixes/" # 一定要指向一个文件夹!
functions:
OnNamePrefix: true # 是否给头顶上添加前缀,该方法用到了头顶的那个计分板,如有冲突请关掉哦~
autoUsePrefix: true # 自动前缀显示 当玩家没有自己选择一个前缀的时候,会自动使用所拥有的的前缀中权重最高的那一个[/code][/spoiler]
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:
@@ -96,7 +172,7 @@ list-value:
- "&8- &7显示名 &r%(name) &7权限 &r%(permission)"
- "&8- &7内容示例&r %(content) %(sender_name)"[/code][/spoiler]
[size=4][backcolor=transparent][b]前缀配置文件[/b][/backcolor] (prefixes/*.yml)[/size]
[size=4][backcolor=transparent][b]前缀配置文件[/b][/backcolor] (prefixes/*.yml) [自2.1.7可自定义目录][/size]
[align=left][font=-apple-system, BlinkMacSystemFont, &quot;][size=3][color=#000000]所有前缀均为单独的配置文件,存放于 [u]插件配置目录/prefixes[/u] 下,便于管理。[/color][/size][/font][/align][align=left][font=-apple-system, BlinkMacSystemFont, &quot;][size=3][color=#000000]文件名理论上可以随便取,推荐使用英文,部分符号可能会影响正常读取,请避免使用。[/color][/size][/font][/align][align=left][spoiler][/align][code]# 唯一标识 [必须]
# 将用于记录玩家所选的前缀,以及用于数据的缓存。
# 必须 必须 必须 保持唯一!
@@ -177,11 +253,14 @@ itemNoPermission:
[size=5][b]下载地址[/b][/size]
[hr]
[size=3][b]最新版本 2.1.0 [/b][/size][attach]1909962[/attach][quote][b][size=3]更新内容[/size][/b]
[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]
[spoiler]
[size=3][b] 2.0.0 [/b][/size][attach]1905700[/attach]
[quote][b][size=3]更新内容[/size][/b]
1. 修复低版本可能无法读取物品的bug。
@@ -233,8 +312,3 @@ itemNoPermission:
@@ -90,10 +90,17 @@ After installed the [URL='https://github.com/PlaceholderAPI/PlaceholderAPI']Plac
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} # DO NOT EDIT IT
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:
+7 -7
View File
@@ -1,30 +1,30 @@
---
name: 问题提交
about: 提交并描述问题,帮助我们对其进行检查与修复。
about: 描述问题并提交,帮助我们对其进行检查与修复。
title: ''
labels: bug
assignees: ''
---
**问题简述**
### **问题简述**
用简短的话语描述一下大概问题。
**问题来源**
### **问题来源**
描述一下通过哪些操作才发现的问题,如:
1. 打开 '...'
2. 点击了 '....'
3. 出现了报错 '....'
**预期结果**(可选)
### **预期结果**(可选)
如果问题不发生,应该是什么情况
**问题截图/问题报错**
### **问题截图/问题报错**
如果有报错或输出,请提供截图。
**操作环境**
### **操作环境**
请在后台输入 `version` 并复制相关输出。
**其他补充**
### **其他补充**
如有其他补充,可以在这里描述。
+4 -4
View File
@@ -7,14 +7,14 @@ assignees: ''
---
**功能简述**
### **功能简述**
简单的描述一下你想要的功能
**需求来源**
### **需求来源**
简单的描述一下为什么需要这个功能。
**功能参考**(可选)
### **功能参考**(可选)
如果有相关功能的参考,如文本、截图,请提供给我们。
**附加内容**
### **附加内容**
如果有什么小细节需要重点注意,请在这里告诉我们。
+70
View File
@@ -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"
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
+1 -1
View File
@@ -27,7 +27,7 @@ jobs:
server-username: MAVEN_USERNAME
server-password: MAVEN_TOKEN
- name: "Deploy"
run: mvn -B deploy --file pom.xml
run: mvn -B deploy --file pom.xml -DskipTests
env:
MAVEN_USERNAME: ${{ github.repository_owner }}
MAVEN_TOKEN: ${{secrets.GITHUB_TOKEN}}
+73
View File
@@ -0,0 +1,73 @@
# 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: Javadoc
on:
# 支持手动触发构建
workflow_dispatch:
release:
# 创建release的时候触发
types: [ published ]
jobs:
api-website:
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
uses: actions/checkout@v2
- name: Set up the Java JDK
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'adopt'
- name: Generate docs
run: mvn package -DskipTests
- name: Copy to Location
run: |
rm -rf docs
mkdir -vp docs
cp -vrf target/apidocs/* docs/
cp -vrf .documentation/JAVADOC-README.md docs/README.md
- name: Generate the sitemap
id: sitemap
uses: cicirello/generate-sitemap@v1
with:
base-url-path: https://carmjos.github.io/userprefix
path-to-root: docs
- name: Output 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 documentation changes
run: |
cd docs
git init
git remote add origin git@github.com:CarmJos/UserPrefix.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 -1
View File
@@ -34,5 +34,5 @@ jobs:
- name: "Upload artifact"
uses: actions/upload-artifact@v2
with:
name: artifact
name: Artifact
path: staging
+39 -9
View File
@@ -1,4 +1,4 @@
![BANNER](https://raw.githubusercontent.com/CarmJos/UserPrefix/master/img/banner.png)
![BANNER](.documentation/images/banner.png)
# UserPrefix Plugin
@@ -22,7 +22,7 @@ development.
## Examples
![example](https://raw.githubusercontent.com/CarmJos/UserPrefix/master/img/using-example.png)
![example](.documentation/images/using-example.png)
## Dependencies
@@ -37,16 +37,22 @@ For development dependencies, please see [Dependencies](https://github.com/Carm
- **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. [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/listener/processor/UserNodeUpdateProcessor.java)
- Real-time judgment and feedback to the player when permissions are
changed. [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/listener/processor/UserNodeUpdateProcessor.java)
- 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 is a conflict) [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/nametag/UserNameTag.java)
- Simple Chat Format Placeholder support. (Not Recommended) [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/listener/ChatListener.java)
- GUI with automatic sorting and page turning! [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/ui/PrefixSelectGUI.java)
- Support PlaceholderAPI variables! [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/hooker/UserPrefixExpansion.java)
- Support [Hex Color](https://www.hexcolortool.com/)! (Version 1.16 and above) `&(#Color)` [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/util/ColorParser.java)
- The prefix display on the player name (can be turned off if there is a
conflict) [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/nametag/UserNameTag.java)
- Simple Chat Format Placeholder support. (Not
Recommended) [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/listener/ChatListener.java)
- GUI with automatic sorting and page
turning! [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/ui/PrefixSelectGUI.java)
- Support PlaceholderAPI
variables! [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/hooker/UserPrefixExpansion.java)
- Support [Hex Color](https://www.hexcolortool.com/)! (Version 1.16 and
above) `&(#Color)` [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/util/ColorParser.java)
- Example: LightSlateBlue `&(#8470FF)` 、 DarkSlateBlue `&(#483D8B)`
## Notice
@@ -109,11 +115,21 @@ type `/papi info UserPrefix` to see all the placeholders.
Notice: The default configuration is based on Chinese. You can find
the [English Version here](https://github.com/CarmJos/UserPrefix/blob/master/src/main/resources/en_US/config.yml).
<details>
<summary>Click to see plugin configuration</summary>
```yaml
version: ${project.version} # DO NOT EDIT IT
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:
@@ -188,14 +204,21 @@ defaultPrefix:
- "§a✔ Selected"
```
</details>
### [Messages Configuration](https://github.com/CarmJos/UserPrefix/blob/master/src/main/resources/en_US/messages.yml) (messages.yml)
<details>
<summary>Click to see messages configuration</summary>
```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."
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:
@@ -213,12 +236,17 @@ list-value:
```
</details>
### [Prefixes Configuration](https://github.com/CarmJos/UserPrefix/blob/master/src/main/resources/en_US/example-prefix.yml) (/prefixes/*.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.
<details>
<summary>Example prefix configuration.</summary>
```yaml
# identifier [Necessary]
# This will be used for data-storage.
@@ -292,10 +320,12 @@ itemNoPermission:
- "§e✯ Buy the VIP to use it!"
```
</details>
## Support and Donation
This project is support by the [YourCraft(你的世界)](https://www.ycraft.cn) .
![TeamLogo](https://raw.githubusercontent.com/CarmJos/UserPrefix/master/img/team-logo.png)
![TeamLogo](.documentation/images/team-logo.png)
## Open source agreement
+66 -14
View File
@@ -1,12 +1,12 @@
![BANNER](https://raw.githubusercontent.com/CarmJos/UserPrefix/master/img/banner.png)
![BANNER](.documentation/images/banner.png)
# 用户前缀系统插件
[![CodeFactor](https://www.codefactor.io/repository/github/carmjos/userprefix/badge?s=b76fec1f64726b5f19989aace6adb5f85fdab840)](https://www.codefactor.io/repository/github/carmjos/userprefix)
![CodeSize](https://img.shields.io/github/languages/code-size/CarmJos/UserPrefix)
[![License](https://img.shields.io/github/license/CarmJos/UserPrefix)](https://opensource.org/licenses/GPL-3.0)
[![Download](https://img.shields.io/github/downloads/CarmJos/UserPrefix/total)](https://github.com/CarmJos/UserPrefix/releases)
[![Java CI with Maven](https://github.com/CarmJos/UserPrefix/actions/workflows/maven.yml/badge.svg?branch=master)](https://github.com/CarmJos/UserPrefix/actions/workflows/maven.yml)
![Support](https://img.shields.io/badge/Minecraft-Java%201.8--Latest-yellow)
![Support](https://img.shields.io/badge/Minecraft-Java%201.8--Latest-green)
![](https://visitor-badge.glitch.me/badge?page_id=userprefix.readme)
轻便、高效、实时的用户前缀系统。
@@ -19,7 +19,7 @@ The **English version** of the introduction is [here](https://github.com/CarmJos
## 示例
![example](https://raw.githubusercontent.com/CarmJos/UserPrefix/master/img/using-example.png)
![example](.documentation/images/using-example.png)
## 依赖
@@ -33,17 +33,23 @@ The **English version** of the introduction is [here](https://github.com/CarmJos
- 理论上全版本支持!
- 游戏内重载配置文件并实时更新到玩家!
- 当玩家权限变更时会实时监测前缀,若权限不足则自动更换前缀并提示![](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/listener/processor/UserNodeUpdateProcessor.java)
-
当玩家权限变更时会实时监测前缀,若权限不足则自动更换前缀并提示![](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/listener/processor/UserNodeUpdateProcessor.java)
- 可配置的声音、消息!
- 前缀图标可配置“选中”、“有权限”与“无权限”三种状态的物品
- 物品的配置通过ItemStack原生配置,支持MC所有的设定!
- 具体的设定请参考其他文档哦~
- TabList自动按照前缀的权重排序 (如有冲突可关掉)
- 玩家头顶前缀显示 (如有冲突可关掉) [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/nametag/UserNameTag.java)
- 简单的聊天变量修改功能!(不推荐使用) [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/listener/ChatListener.java)
- 自动排序,且可翻页的GUI[](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/ui/PrefixSelectGUI.java)
- 支持PlaceholderAPI变量!(凡支持的都可以使用,如BungeeTabListPlus) [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/hooker/UserPrefixExpansion.java)
- 支持[Hex颜色](https://www.hexcolortool.com/)(1.16以上版本) [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/util/ColorParser.java)
- 玩家头顶前缀显示 (
如有冲突可关掉) [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/nametag/UserNameTag.java)
- 简单的聊天变量修改功能!(
不推荐使用) [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/listener/ChatListener.java)
-
自动排序,且可翻页的GUI[](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/ui/PrefixSelectGUI.java)
- 支持PlaceholderAPI变量!(
凡支持的都可以使用,如BungeeTabListPlus) [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/hooker/UserPrefixExpansion.java)
-
支持[Hex颜色](https://www.hexcolortool.com/)(1.16以上版本) [](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/util/ColorParser.java)
- 格式: `&(#颜色代码)`
- 示例: LightSlateBlue `&(#8470FF)` 、 DarkSlateBlue `&(#483D8B)`
@@ -99,11 +105,22 @@ The **English version** of the introduction is [here](https://github.com/CarmJos
### [基础配置文件](https://github.com/CarmJos/UserPrefix/blob/master/src/main/resources/config.yml) (config.yml)
<details>
<summary>展开查看详细基础配置文件</summary>
```yaml
version: 1.0.0-SNAPSHOT # 配置文件版本,一般不会动。
version: 2.1.9 # 配置文件版本,一般不会动。
debug: false #debug输出,开发者用的
custom-storage:
# 自定义存储位置
# 默认存储位置为 “插件文件夹”/prefixes
# 可以规定到远程文件夹中去寻找前缀相关的设定
# 支持绝对文件路径,如 "/etc/minecraft/configurations/prefixes/"
enable: false # 是否启用
path: "prefixes/" # 一定要指向一个文件夹!
functions:
OnNamePrefix: true # 是否给头顶上添加前缀,该方法用到了头顶的那个计分板,如有冲突请关掉哦~
autoUsePrefix: true # 自动前缀显示 当玩家没有自己选择一个前缀的时候,会自动使用所拥有的的前缀中权重最高的那一个
@@ -175,13 +192,21 @@ defaultPrefix:
- "§a✔ 您正在使用该前缀"
```
</details>
### [消息配置文件](https://github.com/CarmJos/UserPrefix/blob/master/src/main/resources/messages.yml) (messages.yml)
<details>
<summary>展开查看详细消息配置文件</summary>
```yaml
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:
@@ -198,11 +223,18 @@ list-value:
- "&8- &7内容示例&r %(content) %(sender_name)"
```
</details>
### [前缀配置文件](https://github.com/CarmJos/UserPrefix/blob/master/src/main/resources/prefixes/example-prefix.yml) (prefixes/*.yml)
所有前缀均为单独的配置文件,存放于 `插件配置目录/prefixes` 下,便于管理。
文件名理论上可以随便取,推荐使用英文,部分符号可能会影响正常读取,请避免使用。
<details>
<summary>展开查看示例前缀配置文件</summary>
```yaml
# 唯一标识 [必须]
# 将用于记录玩家所选的前缀,以及用于数据的缓存。
@@ -283,22 +315,30 @@ itemNoPermission:
- "§e✯ 加入Pro+会员以使用该前缀!"
```
</details>
## 使用统计
[![bStats](https://bstats.org/signatures/bukkit/UserPrefix.svg)](https://bstats.org/plugin/bukkit/UserPrefix/13776)
## 支持与捐赠
本项目由 [YourCraft(你的世界)](https://www.ycraft.cn) 团队提供长期支持与维护。
![TeamLogo](https://raw.githubusercontent.com/CarmJos/UserPrefix/master/img/team-logo.png)
![TeamLogo](.documentation/images/team-logo.png)
若您觉得本插件做的不错,您可以捐赠支持我!
感谢您成为开源项目的支持者!
<img height=25% width=25% src="https://raw.githubusercontent.com/CarmJos/CarmJos/main/img/donate-code.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) 开源协议。
> ### 关于 GPL 协议
<details>
<summary>关于 GPL 协议</summary>
> GNU General Public Licence (GPL) 有可能是开源界最常用的许可模式。GPL 保证了所有开发者的权利,同时为使用者提供了足够的复制,分发,修改的权利:
>
> #### 可自由复制
@@ -313,3 +353,15 @@ itemNoPermission:
> 需要注意的是,分发的时候,需要明确提供源代码和二进制文件,另外,用于某些程序的某些协议有一些问题和限制,你可以看一下 @PierreJoye 写的 Practical Guide to GPL Compliance 一文。使用 GPL 协议,你必须在源代码代码中包含相应信息,以及协议本身。
>
> *以上文字来自 [五种开源协议GPL,LGPL,BSD,MIT,Apache](https://www.oschina.net/question/54100_9455) 。*
</details>
---
```text
_ _ _____ __ _
| | | | | __ \ / _|(_)
| | | | ___ ___ _ __ | |__) |_ __ ___ | |_ _ __ __
| | | |/ __| / _ \| '__|| ___/| '__|/ _ \| _|| |\ \/ /
| |__| |\__ \| __/| | | | | | | __/| | | | > <
\____/ |___/ \___||_| |_| |_| \___||_| |_|/_/\_\
```
+27 -9
View File
@@ -4,9 +4,16 @@
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>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<groupId>cc.carm.plugin</groupId>
<artifactId>userprefix</artifactId>
<version>2.1.6</version>
<version>2.3.0</version>
<name>UserPrefix</name>
<description>轻便、高效、实时的用户前缀系统。</description>
@@ -46,13 +53,6 @@
</license>
</licenses>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<repositories>
<repository>
@@ -88,6 +88,7 @@
</repositories>
<distributionManagement>
<downloadUrl>${project.url}/releases</downloadUrl>
<repository>
<id>github</id>
<name>GitHub Packages</name>
@@ -119,10 +120,17 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>2.2.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
@@ -140,6 +148,9 @@
</links>
<detectJavaApiLink>true</detectJavaApiLink>
<encoding>UTF-8</encoding>
<charset>UTF-8</charset>
<docencoding>UTF-8</docencoding>
<locale>zh_CN</locale>
</configuration>
<executions>
<execution>
@@ -195,6 +206,13 @@
</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>
@@ -2,7 +2,7 @@ package cc.carm.plugin.userprefix;
import cc.carm.plugin.userprefix.command.UserPrefixAdminCommand;
import cc.carm.plugin.userprefix.command.UserPrefixCommand;
import cc.carm.plugin.userprefix.configuration.PrefixConfig;
import cc.carm.plugin.userprefix.configuration.PluginConfig;
import cc.carm.plugin.userprefix.hooker.UserPrefixExpansion;
import cc.carm.plugin.userprefix.listener.ChatListener;
import cc.carm.plugin.userprefix.listener.UserListener;
@@ -14,9 +14,18 @@ import cc.carm.plugin.userprefix.manager.UserManager;
import cc.carm.plugin.userprefix.util.ColorParser;
import cc.carm.plugin.userprefix.util.MessageUtil;
import net.luckperms.api.event.user.UserDataRecalculateEvent;
import org.bstats.bukkit.Metrics;
import org.bstats.charts.SimplePie;
import org.bstats.charts.SingleLineChart;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.PluginCommand;
import org.bukkit.command.TabCompleter;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class Main extends JavaPlugin {
@@ -25,7 +34,7 @@ public class Main extends JavaPlugin {
@Override
public void onEnable() {
instance = this;
showPluginName();
log(getName() + " " + getDescription().getVersion() + " &7开始加载...");
long startTime = System.currentTimeMillis();
@@ -34,8 +43,8 @@ public class Main extends JavaPlugin {
PrefixManager.init();
log("注册指令...");
Bukkit.getPluginCommand("UserPrefix").setExecutor(new UserPrefixCommand());
Bukkit.getPluginCommand("UserPrefixAdmin").setExecutor(new UserPrefixAdminCommand());
registerCommand("UserPrefix", new UserPrefixCommand());
registerCommand("UserPrefixAdmin", new UserPrefixAdminCommand());
log("注册监听器...");
regListener(new UserListener());
@@ -50,6 +59,18 @@ public class Main extends JavaPlugin {
log("若您想使用变量进行前缀的显示,请安装PlaceholderAPI");
}
if (PluginConfig.METRICS.get()) {
log("启用统计数据...");
Metrics metrics = new Metrics(this, 13776);
metrics.addCustomChart(new SingleLineChart("active_prefixes", () -> PrefixManager.getPrefixes().size()));
metrics.addCustomChart(new SimplePie("custom_storage", () -> PluginConfig.CustomStorage.ENABLE.get() ? "ENABLE" : "DISABLE"));
metrics.addCustomChart(new 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 。");
@@ -59,10 +80,12 @@ public class Main extends JavaPlugin {
Bukkit.getOnlinePlayers().forEach(UserManager::initPlayer); // 适配热重载
}
}
@Override
public void onDisable() {
showPluginName();
log(getName() + " " + getDescription().getVersion() + " 开始卸载...");
long startTime = System.currentTimeMillis();
@@ -89,15 +112,46 @@ public class Main extends JavaPlugin {
}
public static void debug(String message) {
if (PrefixConfig.DEBUG.get()) {
if (PluginConfig.DEBUG.get()) {
log("[DEBUG] " + message);
}
}
public static void error(String message) {
log("&c[ERROR] &r" + message);
}
public static JavaPlugin getInstance() {
return instance;
}
public static void registerCommand(String commandName,
@NotNull CommandExecutor executor) {
registerCommand(commandName, executor, null);
}
public static void registerCommand(String commandName,
@NotNull CommandExecutor executor,
@Nullable TabCompleter tabCompleter) {
PluginCommand command = Bukkit.getPluginCommand(commandName);
if (command == null) return;
command.setExecutor(executor);
if (tabCompleter != null) command.setTabCompleter(tabCompleter);
}
private void showPluginName() {
log("&b _ _ &f _____ __ _ ");
log("&b| | | | &f| __ \\ / _|(_) ");
log("&b| | | | ___ ___ _ __ &f| |__) |_ __ ___ | |_ _ __ __");
log("&b| | | |/ __| / _ \\| '__|&f| ___/| '__|/ _ \\| _|| |\\ \\/ /");
log("&b| |__| |\\__ \\| __/| | &f| | | | | __/| | | | > < ");
log("&b \\____/ |___/ \\___||_| &f|_| |_| \\___||_| |_|/_/\\_\\");
log("&8 ");
log("&8> &f" + getDescription().getWebsite());
}
private void showAD() {
log("&7感谢您使用 &3&lUserPrefix " + getDescription().getVersion() + "&7!");
log("&7本插件由 &b&lYourCraft &7提供长期支持与维护。");
@@ -1,6 +1,6 @@
package cc.carm.plugin.userprefix.command;
import cc.carm.plugin.userprefix.configuration.PrefixConfig;
import cc.carm.plugin.userprefix.configuration.PluginConfig;
import cc.carm.plugin.userprefix.manager.ConfigManager;
import cc.carm.plugin.userprefix.manager.PrefixManager;
import cc.carm.plugin.userprefix.manager.UserManager;
@@ -22,10 +22,10 @@ public class UserPrefixAdminCommand implements CommandExecutor {
if (args.length == 1) {
String aim = args[0];
if (aim.equalsIgnoreCase("list")) {
MessageUtil.sendWithPlaceholders(sender, PrefixConfig.Messages.LIST_TITLE.get());
MessageUtil.sendWithPlaceholders(sender, PluginConfig.Messages.LIST_TITLE.get());
for (ConfiguredPrefix value : PrefixManager.getPrefixes().values()) {
MessageUtil.sendWithPlaceholders(
sender, PrefixConfig.Messages.LIST_VALUE.get(),
sender, PluginConfig.Messages.LIST_VALUE.get(),
new String[]{
"%(weight)", "%(identifier)",
"%(name)", "%(permission)",
@@ -54,7 +54,7 @@ public class UserPrefixAdminCommand implements CommandExecutor {
UserManager.updatePrefixView(onlinePlayer, false);
}
MessageUtil.sendWithPlaceholders(
sender, PrefixConfig.Messages.RELOAD.get(),
sender, PluginConfig.Messages.RELOAD.get(),
new String[]{"%(time)"}, new Object[]{(System.currentTimeMillis() - s1)}
);
return true;
@@ -65,7 +65,7 @@ public class UserPrefixAdminCommand implements CommandExecutor {
}
public static boolean help(CommandSender sender) {
MessageUtil.send(sender, PrefixConfig.Messages.HELP.get());
MessageUtil.send(sender, PluginConfig.Messages.HELP.get());
return true;
}
@@ -1,6 +1,7 @@
package cc.carm.plugin.userprefix.command;
import cc.carm.plugin.userprefix.ui.PrefixSelectGUI;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@@ -14,6 +15,15 @@ public class UserPrefixCommand implements CommandExecutor {
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) {
if (sender instanceof Player) {
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;
}
@@ -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,73 +0,0 @@
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 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 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 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");
}
}
@@ -55,7 +55,9 @@ public class ConfigSound {
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 + " ,请检查。");
Main.error("声音 " + this.configSection + " 配置错误,不存在 " + soundString + " ,请检查。");
Main.error("There's no sound matches in " + this.configSection + " , please check the configuration");
}
}
if (finalSound != null) {
@@ -32,8 +32,13 @@ public class ConfigValue<V> {
}
public V get() {
if (getConfiguration().contains(this.configSection)) {
Object val = getConfiguration().get(this.configSection, this.defaultValue);
return this.clazz.isInstance(val) ? this.clazz.cast(val) : this.defaultValue;
} else {
// 如果没有默认值,就把配置写进去,便于配置
return setDefault();
}
}
public void set(V value) {
@@ -45,4 +50,9 @@ public class ConfigValue<V> {
this.source.save();
}
public V setDefault() {
set(this.defaultValue);
return this.defaultValue;
}
}
@@ -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;
}
}
@@ -1,7 +1,7 @@
package cc.carm.plugin.userprefix.listener;
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.util.MessageUtil;
import me.clip.placeholderapi.PlaceholderAPI;
import org.bukkit.event.EventHandler;
@@ -12,8 +12,8 @@ public class ChatListener implements Listener {
@EventHandler
public void onChat(AsyncPlayerChatEvent event) {
if (!PrefixConfig.Functions.Chat.ENABLE.get()) return;
String format = PrefixConfig.Functions.Chat.FORMAT.get();
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;
@@ -21,8 +21,8 @@ public class ChatListener implements Listener {
try {
event.setFormat(PlaceholderAPI.setPlaceholders(event.getPlayer(), format));
} catch (Exception exception) {
Main.log("Please check the chat configuration.");
Main.log("请检查配置文件中聊天相关是否配置正确。");
Main.error("请检查配置文件中聊天相关是否配置正确。");
Main.error("Please check the chat configuration.");
exception.printStackTrace();
}
@@ -1,6 +1,7 @@
package cc.carm.plugin.userprefix.manager;
import cc.carm.plugin.userprefix.Main;
import cc.carm.plugin.userprefix.configuration.PluginConfig;
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
import cc.carm.plugin.userprefix.util.ItemStackFactory;
import org.bukkit.Material;
@@ -35,19 +36,22 @@ public class PrefixManager {
loadConfiguredPrefixes();
}
@SuppressWarnings("ResultOfMethodCallIgnored")
public static void loadConfiguredPrefixes() {
File prefixDataFolder = new File(Main.getInstance().getDataFolder() + File.separator + FOLDER_NAME);
File prefixDataFolder = getStorageFolder();
if (!prefixDataFolder.isDirectory() || !prefixDataFolder.exists()) {
prefixDataFolder.mkdir();
}
String[] filesList = prefixDataFolder.list();
if (filesList == null || filesList.length < 1) {
Main.log("配置文件中暂无任何前缀配置,请检查。");
Main.log("There's no configured prefix.");
Main.error("配置文件中暂无任何前缀配置,请检查。");
Main.error("There's no configured prefix.");
Main.error("Path: " + prefixDataFolder.getAbsolutePath());
return;
}
List<File> files = Arrays.stream(filesList)
.map(s -> new File(prefixDataFolder, s))
.filter(File::isFile)
@@ -60,9 +64,11 @@ public class PrefixManager {
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.log("Error occurred when loading prefix #" + file.getAbsolutePath() + " !");
Main.error("在加载前缀 " + file.getAbsolutePath() + " 时出错,请检查配置!");
Main.error("Error occurred when loading prefix #" + file.getAbsolutePath() + " !");
ex.printStackTrace();
}
}
@@ -74,7 +80,8 @@ public class PrefixManager {
public static void loadDefaultPrefix() {
PrefixManager.defaultPrefix = null;
ConfigurationSection defaultPrefixSection = ConfigManager.getPluginConfig().getConfig().getConfigurationSection("defaultPrefix");
ConfigurationSection defaultPrefixSection = ConfigManager.getPluginConfig()
.getConfig().getConfigurationSection("defaultPrefix");
if (defaultPrefixSection != null) {
try {
String name = defaultPrefixSection.getString("name", "默认前缀");
@@ -98,7 +105,8 @@ public class PrefixManager {
);
PrefixManager.defaultPrefix = new ConfiguredPrefix("default", name, content, 0, null, itemNotUsing, null, itemUsing);
} catch (Exception ex) {
Main.log("在加载默认前缀时出错,请检查配置!");
Main.error("在加载默认前缀时出错,请检查配置!");
Main.error("Error occurred when loading default prefix, please check the configuration.");
ex.printStackTrace();
}
} else {
@@ -120,6 +128,7 @@ public class PrefixManager {
}
Main.log("完成默认前缀加载 " + defaultPrefix.getName());
Main.log("Successfully loaded default prefix " + defaultPrefix.getName());
}
public static List<ConfiguredPrefix> getVisiblePrefix() {
@@ -150,5 +159,13 @@ public class PrefixManager {
}
}
private static File getStorageFolder() {
if (PluginConfig.CustomStorage.ENABLE.get()) {
return new File(PluginConfig.CustomStorage.PATH.get());
} else {
return new File(Main.getInstance().getDataFolder() + File.separator + FOLDER_NAME);
}
}
}
@@ -1,11 +1,12 @@
package cc.carm.plugin.userprefix.manager;
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.nametag.UserNameTag;
import cc.carm.plugin.userprefix.ui.PrefixSelectGUI;
import cc.carm.plugin.userprefix.util.MessageUtil;
import cc.carm.plugin.userprefix.util.gui.GUI;
import net.luckperms.api.model.user.User;
import net.luckperms.api.node.NodeType;
@@ -26,7 +27,7 @@ public class UserManager {
@Nullable
public static UserNameTag getNameTag(Player player) {
if (PrefixConfig.Functions.NAME_PREFIX.get()) {
if (PluginConfig.Functions.NAME_PREFIX.get()) {
if (nameTags.containsKey(player.getUniqueId())) {
return nameTags.get(player.getUniqueId());
} else {
@@ -47,7 +48,7 @@ public class UserManager {
public static void initPlayer(Player player) {
UserManager.checkPrefix(player, false);
if (PrefixConfig.Functions.NAME_PREFIX.get()) {
if (PluginConfig.Functions.NAME_PREFIX.get()) {
UserManager.createNameTag(player);
UserManager.updatePrefixView(player, true);
}
@@ -67,10 +68,11 @@ public class UserManager {
* @param loadOthers 是否为玩家更新其他人的前缀(一般用于加入游戏)
*/
public static void updatePrefixView(Player player, boolean loadOthers) {
if (!PrefixConfig.Functions.NAME_PREFIX.get()) return; //未启用的情况下,不需要进行任何操作。
ConfiguredPrefix playerPrefix = UserManager.getPrefix(player);
if (!PluginConfig.Functions.NAME_PREFIX.get()) return; //未启用的情况下,不需要进行任何操作。
UserNameTag tag = getNameTag(player);
if (tag == null) return; //未启用的情况下,不需要进行任何操作。
ConfiguredPrefix playerPrefix = UserManager.getPrefix(player);
tag.setPrefix(playerPrefix.getContent());
tag.setOrder(playerPrefix.getWeight());
@@ -111,20 +113,42 @@ public class UserManager {
return;
}
checkingPlayers.add(player.getUniqueId());
String currentPrefixIdentifier = UserManager.getPrefixData(player);
ConfiguredPrefix currentPrefix = PrefixManager.getPrefix(currentPrefixIdentifier);
if (!UserManager.isPrefixUsable(player, currentPrefixIdentifier)) {
String currentPrefixData = UserManager.getPrefixData(player);
if (!UserManager.isPrefixUsable(player, currentPrefixData)) {
ConfiguredPrefix currentPrefix = PrefixManager.getPrefix(currentPrefixData);
ConfiguredPrefix newPrefix = UserManager.getHighestPrefix(player);
// 更新前缀
UserManager.setPrefix(player, newPrefix, updateView);
if (currentPrefix != null) {
//当前前缀不为空,则代表属于前缀过期的情况
Bukkit.getPluginManager().callEvent(new UserPrefixExpireEvent(player, currentPrefix));
// 发送消息
MessageUtil.sendWithPlaceholders(player, PrefixConfig.Messages.EXPIRED.get(),
PluginConfig.Messages.EXPIRED.sendWithPlaceholders(player,
new String[]{"%(newName)", "%(oldName)"},
new Object[]{newPrefix.getName(), currentPrefix != null ? currentPrefix.getName() : currentPrefixIdentifier}
new Object[]{newPrefix.getName(), currentPrefix.getName()}
);
// 播放声音
PrefixConfig.Sounds.PREFIX_EXPIRED.play(player);
PluginConfig.Sounds.PREFIX_EXPIRED.play(player);
} else {
// 当前前缀为空,则代表是旧的前缀不存在了,
PluginConfig.Messages.REMOVED.sendWithPlaceholders(player,
new String[]{"%(newName)", "%(oldName)"},
new Object[]{newPrefix.getName(), currentPrefixData}
);
}
UserPrefixChangeEvent event = new UserPrefixChangeEvent(player, currentPrefix, newPrefix);
Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) {
// 更新前缀
UserManager.setPrefix(player, event.getAfter(), updateView);
}
}
checkingPlayers.remove(player.getUniqueId());
}
@@ -186,7 +210,7 @@ public class UserManager {
*/
@NotNull
public static ConfiguredPrefix getHighestPrefix(Player player) {
if (PrefixConfig.Functions.AUTO_USE.get()) {
if (PluginConfig.Functions.AUTO_USE.get()) {
// 关闭了自动选择,就直接给默认的前缀,让玩家自己去设置吧~
return PrefixManager.getDefaultPrefix();
}
@@ -226,7 +250,7 @@ public class UserManager {
* 该方法通过LuckPerms的MetaData实现,因此可以通过指令去操作。
*
* @param player 玩家
* @return 正在使用的前缀Identifier(若不存在则返回null)
* @return 正在使用的前缀Identifier(若不存在则返回null, 代表未设置前缀)
*/
@Nullable
public static String getPrefixData(Player player) {
@@ -2,14 +2,18 @@ package cc.carm.plugin.userprefix.model;
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.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.List;
public class ConfiguredPrefix {
@@ -96,19 +100,34 @@ public class ConfiguredPrefix {
return permission;
}
@NotNull
public ItemStack getItemHasPermission(@Nullable Player player) {
return parseItemStackText(this.itemHasPermission, player);
}
@NotNull
public ItemStack getItemHasPermission() {
return itemHasPermission;
return getItemHasPermission(null);
}
@Nullable
public ItemStack getItemNoPermission(@Nullable Player player) {
return parseItemStackText(itemNoPermission, player);
}
@Nullable
public ItemStack getItemNoPermission() {
return itemNoPermission;
return getItemNoPermission(null);
}
@Nullable
public ItemStack getItemWhenUsing(@Nullable Player player) {
return parseItemStackText(itemWhenUsing, player);
}
@Nullable
public ItemStack getItemWhenUsing() {
return itemWhenUsing;
return getItemWhenUsing(null);
}
public boolean isPublic() {
@@ -120,4 +139,21 @@ public class ConfiguredPrefix {
}
@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,6 +1,6 @@
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.manager.PrefixManager;
import cc.carm.plugin.userprefix.manager.UserManager;
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
@@ -22,7 +22,7 @@ public class PrefixSelectGUI extends AutoPagedGUI {
Player player;
public PrefixSelectGUI(Player player) {
super(GUIType.SIXBYNINE, PrefixConfig.GUI.TITLE.get(), 10, 43);
super(GUIType.SIXBYNINE, PluginConfig.GUI.TITLE.get(), 10, 43);
this.player = player;
setPreviousPageSlot(18);
@@ -44,9 +44,9 @@ public class PrefixSelectGUI extends AutoPagedGUI {
for (ConfiguredPrefix prefix : prefixList) {
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)) {
addItem(new GUIItem(prefix.getItemHasPermission()) {
addItem(new GUIItem(prefix.getItemHasPermission(player)) {
@Override
public void onClick(ClickType type) {
//再次检查,防止打开GUI后、选择前的时间段内权限消失
@@ -54,8 +54,8 @@ public class PrefixSelectGUI extends AutoPagedGUI {
player.closeInventory();
UserManager.setPrefix(player, prefix, true);
PrefixConfig.Sounds.PREFIX_CHANGE.play(player);
MessageUtil.sendWithPlaceholders(player, PrefixConfig.Messages.SELECTED.get(),
PluginConfig.Sounds.PREFIX_CHANGE.play(player);
MessageUtil.sendWithPlaceholders(player, PluginConfig.Messages.SELECTED.get(),
new String[]{"%(name)"},
new Object[]{prefix.getName()});
@@ -63,7 +63,7 @@ public class PrefixSelectGUI extends AutoPagedGUI {
}
});
} else {
addItem(new GUIItem(prefix.getItemNoPermission()));
addItem(new GUIItem(prefix.getItemNoPermission(player)));
}
}
@@ -87,7 +87,8 @@ public class PrefixSelectGUI extends AutoPagedGUI {
}
public static void open(Player player) {
PrefixConfig.Sounds.GUI_OPEN.play(player);
player.closeInventory(); // 防止冲突
PluginConfig.Sounds.GUI_OPEN.play(player);
new PrefixSelectGUI(player).openGUI(player);
openingUsers.add(player);
}
@@ -4,8 +4,10 @@ import me.clip.placeholderapi.PlaceholderAPI;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.stream.Collectors;
public class MessageUtil {
@@ -13,13 +15,14 @@ public class MessageUtil {
return Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null;
}
public static void send(CommandSender sender, List<String> messages) {
public static void send(@Nullable CommandSender sender, List<String> messages) {
if (messages == null || messages.isEmpty() || sender == null) return;
for (String s : messages) {
sender.sendMessage(ColorParser.parse(s));
}
}
public static void send(CommandSender sender, String... messages) {
public static void send(@Nullable CommandSender sender, String... messages) {
send(sender, Arrays.asList(messages));
}
@@ -27,23 +30,48 @@ public class MessageUtil {
sendWithPlaceholders(sender, Arrays.asList(messages));
}
public static void sendWithPlaceholders(CommandSender sender, List<String> messages) {
if (messages == null || messages.isEmpty()) return;
if (hasPlaceholderAPI() && sender instanceof Player) {
send(sender, PlaceholderAPI.setPlaceholders((Player) sender, messages));
} else {
send(sender, messages);
}
public static void sendWithPlaceholders(@Nullable CommandSender sender, List<String> messages) {
if (messages == null || messages.isEmpty() || sender == null) return;
send(sender, setPlaceholders(sender, messages));
}
public static void sendWithPlaceholders(CommandSender sender, List<String> messages, String param, Object value) {
public static void sendWithPlaceholders(@Nullable CommandSender sender, List<String> messages, String param, Object value) {
sendWithPlaceholders(sender, messages, new String[]{param}, new Object[]{value});
}
public static void sendWithPlaceholders(CommandSender sender, List<String> messages, String[] params, Object[] values) {
public static void sendWithPlaceholders(@Nullable CommandSender sender, List<String> messages, String[] params, Object[] values) {
sendWithPlaceholders(sender, setCustomParams(messages, params, values));
}
public static String setPlaceholders(@Nullable CommandSender sender, String message) {
if (message == null) return null;
message = ColorParser.parse(message);
if (sender == null) return message;
if (hasPlaceholderAPI() && sender instanceof Player) {
return PlaceholderAPI.setPlaceholders((Player) sender, message);
} else {
return message;
}
}
public static List<String> setPlaceholders(@Nullable CommandSender sender, List<String> messages) {
if (messages == null || messages.isEmpty()) return new ArrayList<>();
messages = messages.stream().map(ColorParser::parse).collect(Collectors.toList());
if (sender == null) return messages;
if (hasPlaceholderAPI() && sender instanceof Player) {
return PlaceholderAPI.setPlaceholders((Player) sender, messages);
} else {
return messages;
}
}
public static List<String> setPlaceholders(@Nullable CommandSender sender, List<String> messages, String[] params, Object[] values) {
return setPlaceholders(sender, setCustomParams(messages, params, values));
}
public static List<String> setCustomParams(List<String> messages, String param, Object value) {
return setCustomParams(messages, new String[]{param}, new Object[]{value});
}
@@ -1,6 +1,6 @@
package cc.carm.plugin.userprefix.util.gui;
import cc.carm.plugin.userprefix.configuration.PrefixConfig;
import cc.carm.plugin.userprefix.configuration.PluginConfig;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
@@ -51,7 +51,7 @@ public class AutoPagedGUI extends CommonPagedGUI {
public void openGUI(Player user) {
if (previousPageSlot >= 0)
if (hasPreviousPage()) {
setItem(previousPageSlot, new GUIItem(previousPageUI == null ? PrefixConfig.GUI.Items.PREVIOUS_PAGE.get() : previousPageUI) {
setItem(previousPageSlot, new GUIItem(previousPageUI == null ? PluginConfig.GUI.Items.PREVIOUS_PAGE.get() : previousPageUI) {
@Override
public void onClick(ClickType type) {
if (type == ClickType.RIGHT) {
@@ -59,7 +59,7 @@ public class AutoPagedGUI extends CommonPagedGUI {
} else {
goPreviousPage();
}
PrefixConfig.Sounds.GUI_CLICK.play(user);
PluginConfig.Sounds.GUI_CLICK.play(user);
openGUI(user);
}
});
@@ -67,7 +67,7 @@ public class AutoPagedGUI extends CommonPagedGUI {
if (nextPageSlot >= 0)
if (hasNextPage()) {
setItem(nextPageSlot, new GUIItem(nextPageUI == null ? PrefixConfig.GUI.Items.NEXT_PAGE.get() : nextPageUI) {
setItem(nextPageSlot, new GUIItem(nextPageUI == null ? PluginConfig.GUI.Items.NEXT_PAGE.get() : nextPageUI) {
@Override
public void onClick(ClickType type) {
if (type == ClickType.RIGHT) {
@@ -75,7 +75,7 @@ public class AutoPagedGUI extends CommonPagedGUI {
} else {
goNextPage();
}
PrefixConfig.Sounds.GUI_CLICK.play(user);
PluginConfig.Sounds.GUI_CLICK.play(user);
openGUI(user);
}
});
+22 -9
View File
@@ -1,7 +1,20 @@
version: ${project.version}
version: ${project.version} #配置文件版本,若与插件版本不同请记得检查配置文件内容
debug: false
# 统计数据设定
# 改选项用于帮助开发者统计插件版本与使用情况,且绝不会影响性能与使用体验。
# 当然,您也可以选择在这里关闭,或在plugins/bStats下的配置文件中关闭。
metrics: true
custom-storage:
# 自定义存储位置
# 默认存储位置为 “插件文件夹”/prefixes
# 可以规定到远程文件夹中去寻找前缀相关的设定
# 支持绝对文件路径,如 "/etc/minecraft/configurations/prefixes/"
enable: false # 是否启用
path: "prefixes/" # 一定要指向一个文件夹!
functions:
OnNamePrefix: true # 是否给头顶上添加前缀,该方法用到了头顶的那个计分板,如有冲突请关掉哦~
autoUsePrefix: true # 自动前缀显示 当玩家没有自己选择一个前缀的时候,会自动使用所拥有的的前缀中权重最高的那一个
@@ -24,20 +37,20 @@ GUI:
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "§f下一页"
display-name: "&f下一页"
lore:
- ""
- "§f右键可前往最后一页哦~"
- "&f右键可前往最后一页哦~"
previous-page: # 上一页物品,如果没有上一页则不显示
==: org.bukkit.inventory.ItemStack
type: ARROW
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "§f上一页"
display-name: "&f上一页"
lore:
- ""
- "§f右键可前往第一页哦~"
- "&f右键可前往第一页哦~"
Sounds: #相关的声音,注释掉则不播放声音 格式为 【声音名:音量:音调】 或 【声音名:音量】 或 【声音名】
openGUI: "BLOCK_NOTE_BLOCK_PLING:1:1"
@@ -56,17 +69,17 @@ defaultPrefix:
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "§f默认玩家前缀 §f(点击切换)"
display-name: "&f默认玩家前缀 &f(点击切换)"
lore:
- ""
- "§a➥ 点击切换到该前缀"
- "&a➥ 点击切换到该前缀"
itemUsing:
==: org.bukkit.inventory.ItemStack
type: NAME_TAG
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "§f默认玩家前缀"
display-name: "&f默认玩家前缀"
lore:
- ""
- "§a✔ 您正在使用该前缀"
- "&a✔ 您正在使用该前缀"
+9
View File
@@ -2,6 +2,15 @@ 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:
+7 -7
View File
@@ -9,7 +9,7 @@ name: "&b&lPro&b"
# Content [Necessary]
# Use in Placeholders
content: "§b§lPro §b"
content: "&b&lPro &b"
# Weight [Necessary]
# used for sorting in the GUI and TabList
@@ -31,10 +31,10 @@ itemHasPermission:
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "§b§lVIP Prefix"
display-name: "&b&lVIP Prefix"
lore:
- ""
- "§a➥ Click to use"
- "&a➥ Click to use"
# itemUsing [Unnecessary]
# This Item will be displayed when the prefix is selected.
@@ -45,12 +45,12 @@ itemUsing:
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "§b§lVIP Prefix"
display-name: "&b&lVIP Prefix"
enchants:
PROTECTION_ENVIRONMENTAL: 1 #Add an enchantment so it looks like its selected
lore:
- ""
- "§a✔ Selected"
- "&a✔ Selected"
# itemNoPermission [Unnecessary]
# If player doesn't have the permission,this item will be displayed.
@@ -62,7 +62,7 @@ itemNoPermission:
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "§b§lVIP §c(Buy it!)"
display-name: "&b&lVIP &c(Buy it!)"
lore:
- ""
- "§e✯ Buy the VIP to use it!"
- "&e✯ Buy the VIP to use it!"
+2
View File
@@ -3,6 +3,8 @@ selected:
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:
+2
View File
@@ -3,6 +3,8 @@ selected:
expired:
- "&7您先前使用的前缀 &f%(oldName) &7已到期。"
- "&7现在已为您重新调整为 &f%(newName) &7。"
removed:
- "&7您先前使用的前缀已被移除,现在已为您重新调整为 &f%(newName) &7。"
reload:
- "&a&l重载完成!&7共耗时 &f%(time)ms&7。"
help:
+17 -17
View File
@@ -9,7 +9,7 @@ name: "&b&lPro&b"
# 内容 [必须]
# 显示在名字前面的内容
content: "§b§lPro §b"
content: "&b&lPro &b"
# 权重 [必须]
# 用于GUI、TabList的排序和自动前缀显示
@@ -30,14 +30,14 @@ itemHasPermission: #
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "§b§lPro §b会员前缀"
display-name: "&b&lPro &b会员前缀"
lore:
- "§7Pro会员专属称号"
- "&7Pro会员专属称号"
- ""
- "§f尊贵的Pro会员专属称号。"
- "§f您将获得多种特权与更好的游戏体验。"
- "&f尊贵的Pro会员专属称号。"
- "&f您将获得多种特权与更好的游戏体验。"
- ""
- "§a➥ 点击切换到该前缀"
- "&a➥ 点击切换到该前缀"
# 正在使用时显示的物品 [非必需]
# 当用户正在使用时会显示这个物品,不配置即自动加载“itemHasPermission”
@@ -47,16 +47,16 @@ itemUsing:
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "§b§lPro §b会员前缀"
display-name: "&b&lPro &b会员前缀"
enchants:
PROTECTION_ENVIRONMENTAL: 1 #加一个附魔这样看上去就像是选中了的
lore:
- "§7Pro会员专属称号"
- "&7Pro会员专属称号"
- ""
- "§f尊贵的Pro会员专属称号。"
- "§f您将获得多种特权与更好的游戏体验。"
- "&f尊贵的Pro会员专属称号。"
- "&f您将获得多种特权与更好的游戏体验。"
- ""
- "§a✔ 您正在使用该前缀"
- "&a✔ 您正在使用该前缀"
# 没有权限时显示的物品 [非必需]
# 如果没有权限就会显示这个item。如果不配置该物品,则玩家没有使用权限时不会显示在GUI里面。
@@ -67,12 +67,12 @@ itemNoPermission:
meta:
==: ItemMeta
meta-type: UNSPECIFIC
display-name: "§b§lPro+ §b会员前缀 §c(未拥有)"
display-name: "&b&lPro+ &b会员前缀 &c(未拥有)"
lore:
- "§7Pro+会员专属称号"
- "&7Pro+会员专属称号"
- ""
- "§f尊贵的Pro会员专属称号。"
- "§f您将获得多种特权与更好的游戏体验。"
- "§f您可以输入 §b/vip §f指令查看详细特权!"
- "&f尊贵的Pro会员专属称号。"
- "&f您将获得多种特权与更好的游戏体验。"
- "&f您可以输入 &b/vip &f指令查看详细特权!"
- ""
- "§e✯ 加入Pro+会员以使用该前缀!"
- "&e✯ 加入Pro+会员以使用该前缀!"