mirror of
https://github.com/CarmJos/UserPrefix.git
synced 2026-06-14 03:41:10 +08:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 774e9b764e | |||
| a31da83531 | |||
| 61857d6305 | |||
| dd96188b22 | |||
| eb4ecaada9 | |||
| acc9ea7e7c | |||
| 83b3c45d57 | |||
| 3ec39b9ca3 | |||
| 821b42cc03 | |||
| 81e0c0960f | |||
| 99c577c361 | |||
| 5df6e1fe34 | |||
| 7c887822ba | |||
| 6b601950a3 | |||
| d752461c74 | |||
| 548f1d366f | |||
| 686b28cf93 | |||
| 92e14e29fe |
@@ -9,7 +9,7 @@
|
|||||||
# the `language` matrix defined below to confirm you have the correct set of
|
# the `language` matrix defined below to confirm you have the correct set of
|
||||||
# supported CodeQL languages.
|
# supported CodeQL languages.
|
||||||
#
|
#
|
||||||
name: "CodeQL"
|
name: "CodeQL Analysis"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# 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: Deploy
|
name: Deploy & Upload
|
||||||
|
|
||||||
on:
|
on:
|
||||||
# 支持手动触发构建
|
# 支持手动触发构建
|
||||||
@@ -26,8 +26,65 @@ jobs:
|
|||||||
server-id: github
|
server-id: github
|
||||||
server-username: MAVEN_USERNAME
|
server-username: MAVEN_USERNAME
|
||||||
server-password: MAVEN_TOKEN
|
server-password: MAVEN_TOKEN
|
||||||
- name: "Deploy"
|
|
||||||
|
- name: "Maven Deploy"
|
||||||
run: mvn -B deploy --file pom.xml -DskipTests
|
run: mvn -B deploy --file pom.xml -DskipTests
|
||||||
env:
|
env:
|
||||||
MAVEN_USERNAME: ${{ github.repository_owner }}
|
MAVEN_USERNAME: ${{ github.repository_owner }}
|
||||||
MAVEN_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
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,73 +0,0 @@
|
|||||||
# 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,7 +1,7 @@
|
|||||||
# 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: Build
|
name: Build & Tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
# 支持手动触发构建
|
# 支持手动触发构建
|
||||||
@@ -29,10 +29,15 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
MAVEN_USERNAME: ${{ github.repository_owner }}
|
MAVEN_USERNAME: ${{ github.repository_owner }}
|
||||||
MAVEN_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
MAVEN_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||||
- name: "Target Stage"
|
|
||||||
run: mkdir staging && cp target/*.jar staging
|
- name: "Target Staging"
|
||||||
|
run: |
|
||||||
|
mkdir artifacts
|
||||||
|
cp -vrf target/ artifacts/target/
|
||||||
|
cp -vrf asset/*.jar artifacts
|
||||||
|
|
||||||
- name: "Upload artifact"
|
- name: "Upload artifact"
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: Artifact
|
name: Artifact
|
||||||
path: staging
|
path: artifacts
|
||||||
@@ -2,3 +2,4 @@
|
|||||||
/target/
|
/target/
|
||||||
./*.iml
|
./*.iml
|
||||||
*.iml
|
*.iml
|
||||||
|
asset/
|
||||||
+14
-215
@@ -1,5 +1,7 @@
|
|||||||

|

|
||||||
|
|
||||||
|
README LANGUAGES [ [中文](README.md) | [**English**](README-en.md) ]
|
||||||
|
|
||||||
# UserPrefix Plugin
|
# UserPrefix Plugin
|
||||||
|
|
||||||
[](https://www.codefactor.io/repository/github/carmjos/userprefix)
|
[](https://www.codefactor.io/repository/github/carmjos/userprefix)
|
||||||
@@ -37,22 +39,16 @@ For development dependencies, please see [Dependencies](https://github.com/Carm
|
|||||||
|
|
||||||
- **Theoretically** support ALL MineCraft Versions.
|
- **Theoretically** support ALL MineCraft Versions.
|
||||||
- Reloading the configuration will automatically refresh the prefix of all players.
|
- Reloading the configuration will automatically refresh the prefix of all players.
|
||||||
- Real-time judgment and feedback to the player when permissions are
|
- Real-time judgment and feedback to the player when permissions are changed.
|
||||||
changed. [✈](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/listener/processor/UserNodeUpdateProcessor.java)
|
|
||||||
- Configurable sounds and messages.
|
- Configurable sounds and messages.
|
||||||
- The prefix icon can be configured as "Selected", "Has Permission" and “No Permission”.
|
- 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!
|
- 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)
|
- 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
|
- The prefix display on the player name (can be turned off if there has any conflict)
|
||||||
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)
|
||||||
- Simple Chat Format Placeholder support. (Not
|
- GUI with automatic sorting and page turning!
|
||||||
Recommended) [✈](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/listener/ChatListener.java)
|
- Support PlaceholderAPI variables!
|
||||||
- GUI with automatic sorting and page
|
- Support [Hex Color](https://www.hexcolortool.com/)! (Version 1.16 and above) `&(#Color)`
|
||||||
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)`
|
- Example: LightSlateBlue `&(#8470FF)` 、 DarkSlateBlue `&(#483D8B)`
|
||||||
|
|
||||||
## Notice
|
## Notice
|
||||||
@@ -87,7 +83,7 @@ This plugin's Commands are based on Chinese!
|
|||||||
/UserPrefix or /prefix #Open prefix GUI
|
/UserPrefix or /prefix #Open prefix GUI
|
||||||
/UserPrefixAdmin # View Admin Command Help
|
/UserPrefixAdmin # View Admin Command Help
|
||||||
/UserPrefixAdmin reload # Reload Config
|
/UserPrefixAdmin reload # Reload Config
|
||||||
/UserPrefixAdmin list # List all configured prefixes.~~~~
|
/UserPrefixAdmin list # List all configured prefixes.
|
||||||
```
|
```
|
||||||
|
|
||||||
## Placeholders (PlaceholderAPI)
|
## Placeholders (PlaceholderAPI)
|
||||||
@@ -110,218 +106,21 @@ type `/papi info UserPrefix` to see all the placeholders.
|
|||||||
|
|
||||||
## Configuration files
|
## Configuration files
|
||||||
|
|
||||||
### [Plugin Configuration](https://github.com/CarmJos/UserPrefix/blob/master/src/main/resources/en_US/config.yml) (config.yml)
|
### Plugin Configuration ([`config.yml`](src/main/resources/en_US/config.yml) .
|
||||||
|
|
||||||
Notice: The default configuration is based on Chinese. You can find
|
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).
|
the [English Version here](src/main/resources/en_US/config.yml).
|
||||||
|
|
||||||
<details>
|
### Messages Configuration ([`messages.yml`](src/main/resources/en_US/messages.yml))
|
||||||
<summary>Click to see plugin configuration</summary>
|
|
||||||
|
|
||||||
```yaml
|
Please see the [Source File](src/main/resources/en_US/messages.yml) .
|
||||||
version: ${project.version} # DO NOT EDIT IT
|
|
||||||
|
|
||||||
debug: false #DEBUG OUT PUT
|
### Prefixes Configuration ([`prefixes/*.yml`](src/main/resources/en_US/example-prefix.yml))
|
||||||
|
|
||||||
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"
|
|
||||||
```
|
|
||||||
|
|
||||||
</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:
|
|
||||||
- "&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)"
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
</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.
|
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.
|
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.
|
|
||||||
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!"
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
## Support and Donation
|
## Support and Donation
|
||||||
|
|
||||||
This project is support by the [YourCraft(你的世界)](https://www.ycraft.cn) .
|
This project is support by the [YourCraft(你的世界)](https://www.ycraft.cn) .
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||

|

|
||||||
|
|
||||||
|
README LANGUAGES [ [**中文**](README.md) | [English](README-en.md) ]
|
||||||
|
|
||||||
# 用户前缀系统插件
|
# 用户前缀系统插件
|
||||||
|
|
||||||
[](https://www.codefactor.io/repository/github/carmjos/userprefix)
|
[](https://www.codefactor.io/repository/github/carmjos/userprefix)
|
||||||
@@ -13,8 +15,6 @@
|
|||||||
|
|
||||||
本插件基于Spigot实现,**理论上支持全版本**。
|
本插件基于Spigot实现,**理论上支持全版本**。
|
||||||
|
|
||||||
The **English version** of the introduction is [here](https://github.com/CarmJos/UserPrefix/blob/master/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/) 上发布。
|
> 本插件已在 [MCBBS](https://www.mcbbs.net/forum.php?mod=viewthread&tid=1261503) 与 [SpigotMC](https://www.spigotmc.org/resources/userprefix-hex-color-support-all-version.96277/) 上发布。
|
||||||
|
|
||||||
## 示例
|
## 示例
|
||||||
@@ -33,23 +33,17 @@ The **English version** of the introduction is [here](https://github.com/CarmJos
|
|||||||
|
|
||||||
- 理论上全版本支持!
|
- 理论上全版本支持!
|
||||||
- 游戏内重载配置文件并实时更新到玩家!
|
- 游戏内重载配置文件并实时更新到玩家!
|
||||||
-
|
- 当玩家权限变更时会实时监测前缀,若权限不足则自动更换前缀并提示
|
||||||
当玩家权限变更时会实时监测前缀,若权限不足则自动更换前缀并提示
|
|
||||||
- 可配置的声音、消息!
|
- 可配置的声音、消息!
|
||||||
- 前缀图标可配置“选中”、“有权限”与“无权限”三种状态的物品
|
- 前缀图标可配置“选中”、“有权限”与“无权限”三种状态的物品
|
||||||
- 物品的配置通过ItemStack原生配置,支持MC所有的设定!
|
- 物品的配置通过ItemStack原生配置,支持MC所有的设定!
|
||||||
- 具体的设定请参考其他文档哦~
|
- 具体的设定请参考其他文档哦~
|
||||||
- TabList自动按照前缀的权重排序 (如有冲突可关掉)
|
- TabList自动按照前缀的权重排序 (如有冲突可关掉)
|
||||||
- 玩家头顶前缀显示 (
|
- 玩家头顶前缀显示 (如有冲突可关掉)
|
||||||
如有冲突可关掉) [✈](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/nametag/UserNameTag.java)
|
- 简单的聊天变量修改功能!(不推荐使用) `[自 v2.1.0 版本起]`
|
||||||
- 简单的聊天变量修改功能!(
|
- 自动排序,且可翻页的GUI!
|
||||||
不推荐使用) [✈](https://github.com/CarmJos/UserPrefix/blob/master/src/main/java/cc/carm/plugin/userprefix/listener/ChatListener.java)
|
- 支持PlaceholderAPI变量!(凡支持的都可以使用,如BungeeTabListPlus)
|
||||||
-
|
- 支持[Hex颜色](https://www.hexcolortool.com/)!(1.16以上版本) `[自 v1.2.3 版本起]`
|
||||||
自动排序,且可翻页的GUI
|
|
||||||
- 支持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)`
|
- 示例: LightSlateBlue `&(#8470FF)` 、 DarkSlateBlue `&(#483D8B)`
|
||||||
|
|
||||||
@@ -103,219 +97,21 @@ 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)
|
### 基础配置文件 ([`config.yml`](src/main/resources/config.yml))
|
||||||
|
|
||||||
<details>
|
详见 [源文件](src/main/resources/messages.yml) 。
|
||||||
<summary>展开查看详细基础配置文件</summary>
|
|
||||||
|
|
||||||
```yaml
|
### 消息配置文件 ([`messages.yml`](src/main/resources/messages.yml))
|
||||||
version: 2.1.9 # 配置文件版本,一般不会动。
|
|
||||||
|
|
||||||
debug: false #debug输出,开发者用的
|
详见 [源文件](src/main/resources/messages.yml) 。
|
||||||
|
|
||||||
custom-storage:
|
### 前缀配置文件 ([`prefixes/*.yml`](src/main/resources/prefixes/example-prefix.yml))
|
||||||
# 自定义存储位置
|
|
||||||
# 默认存储位置为 “插件文件夹”/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✔ 您正在使用该前缀"
|
|
||||||
```
|
|
||||||
|
|
||||||
</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:
|
|
||||||
- "&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)"
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
### [前缀配置文件](https://github.com/CarmJos/UserPrefix/blob/master/src/main/resources/prefixes/example-prefix.yml) (prefixes/*.yml)
|
|
||||||
|
|
||||||
所有前缀均为单独的配置文件,存放于 `插件配置目录/prefixes` 下,便于管理。
|
所有前缀均为单独的配置文件,存放于 `插件配置目录/prefixes` 下,便于管理。
|
||||||
|
|
||||||
文件名理论上可以随便取,推荐使用英文,部分符号可能会影响正常读取,请避免使用。
|
文件名理论上可以随便取,推荐使用英文,部分符号可能会影响正常读取,请避免使用。
|
||||||
|
|
||||||
|
您可以 [点击这里](src/main/resources/prefixes/example-prefix.yml) 查看示例前缀配置文件。
|
||||||
<details>
|
|
||||||
<summary>展开查看示例前缀配置文件</summary>
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# 唯一标识 [必须]
|
|
||||||
# 将用于记录玩家所选的前缀,以及用于数据的缓存。
|
|
||||||
# 必须 必须 必须 保持唯一!
|
|
||||||
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+会员以使用该前缀!"
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
## 使用统计
|
## 使用统计
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
<groupId>cc.carm.plugin</groupId>
|
<groupId>cc.carm.plugin</groupId>
|
||||||
<artifactId>userprefix</artifactId>
|
<artifactId>userprefix</artifactId>
|
||||||
<version>2.3.0</version>
|
<version>2.4.2</version>
|
||||||
|
|
||||||
<name>UserPrefix</name>
|
<name>UserPrefix</name>
|
||||||
<description>轻便、高效、实时的用户前缀系统。</description>
|
<description>轻便、高效、实时的用户前缀系统。</description>
|
||||||
@@ -80,6 +80,11 @@
|
|||||||
<url>https://repo1.maven.org/maven2/</url>
|
<url>https://repo1.maven.org/maven2/</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
|
||||||
|
<repository>
|
||||||
|
<id>sonatype-repo</id>
|
||||||
|
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
||||||
|
</repository>
|
||||||
|
|
||||||
<repository>
|
<repository>
|
||||||
<id>github</id>
|
<id>github</id>
|
||||||
<name>GitHub Packages</name>
|
<name>GitHub Packages</name>
|
||||||
@@ -123,7 +128,14 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.bstats</groupId>
|
<groupId>org.bstats</groupId>
|
||||||
<artifactId>bstats-bukkit</artifactId>
|
<artifactId>bstats-bukkit</artifactId>
|
||||||
<version>2.2.1</version>
|
<version>3.0.0</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cc.carm.lib</groupId>
|
||||||
|
<artifactId>githubreleases4j</artifactId>
|
||||||
|
<version>1.3.1</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -200,18 +212,25 @@
|
|||||||
<goals>
|
<goals>
|
||||||
<goal>shade</goal>
|
<goal>shade</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
|
||||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<finalName>${project.name}-${project.version}</finalName>
|
||||||
|
<outputDirectory>${project.basedir}/asset/</outputDirectory>
|
||||||
|
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||||
<relocations>
|
<relocations>
|
||||||
<relocation>
|
<relocation>
|
||||||
<pattern>org.bstats</pattern>
|
<pattern>org.bstats</pattern>
|
||||||
<!-- Replace this with your package! -->
|
|
||||||
<shadedPattern>cc.carm.plugin.userprefix.bstats</shadedPattern>
|
<shadedPattern>cc.carm.plugin.userprefix.bstats</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>cc.carm.lib.githubreleases4j</pattern>
|
||||||
|
<shadedPattern>cc.carm.plugin.userprefix.lib.github</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.json</pattern>
|
||||||
|
<shadedPattern>cc.carm.plugin.userprefix.lib.json</shadedPattern>
|
||||||
|
</relocation>
|
||||||
</relocations>
|
</relocations>
|
||||||
<filters>
|
<filters>
|
||||||
<filter>
|
<filter>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ 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.PluginConfig;
|
import cc.carm.plugin.userprefix.configuration.PluginConfig;
|
||||||
|
import cc.carm.plugin.userprefix.hooker.UpdateChecker;
|
||||||
import cc.carm.plugin.userprefix.hooker.UserPrefixExpansion;
|
import cc.carm.plugin.userprefix.hooker.UserPrefixExpansion;
|
||||||
import cc.carm.plugin.userprefix.listener.ChatListener;
|
import cc.carm.plugin.userprefix.listener.ChatListener;
|
||||||
import cc.carm.plugin.userprefix.listener.UserListener;
|
import cc.carm.plugin.userprefix.listener.UserListener;
|
||||||
@@ -13,6 +14,7 @@ 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 cc.carm.plugin.userprefix.util.MessageUtil;
|
||||||
|
import cc.carm.plugin.userprefix.wrapper.ItemStackWrapper;
|
||||||
import net.luckperms.api.event.user.UserDataRecalculateEvent;
|
import net.luckperms.api.event.user.UserDataRecalculateEvent;
|
||||||
import org.bstats.bukkit.Metrics;
|
import org.bstats.bukkit.Metrics;
|
||||||
import org.bstats.charts.SimplePie;
|
import org.bstats.charts.SimplePie;
|
||||||
@@ -21,6 +23,7 @@ import org.bukkit.Bukkit;
|
|||||||
import org.bukkit.command.CommandExecutor;
|
import org.bukkit.command.CommandExecutor;
|
||||||
import org.bukkit.command.PluginCommand;
|
import org.bukkit.command.PluginCommand;
|
||||||
import org.bukkit.command.TabCompleter;
|
import org.bukkit.command.TabCompleter;
|
||||||
|
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
@@ -38,6 +41,9 @@ public class Main extends JavaPlugin {
|
|||||||
log(getName() + " " + getDescription().getVersion() + " &7开始加载...");
|
log(getName() + " " + getDescription().getVersion() + " &7开始加载...");
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
log("注入序列化处理工具...");
|
||||||
|
ConfigurationSerialization.registerClass(ItemStackWrapper.class);
|
||||||
|
|
||||||
log("加载配置文件...");
|
log("加载配置文件...");
|
||||||
ConfigManager.initConfig();
|
ConfigManager.initConfig();
|
||||||
PrefixManager.init();
|
PrefixManager.init();
|
||||||
@@ -72,6 +78,13 @@ public class Main extends JavaPlugin {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PluginConfig.CHECK_UPDATE.get()) {
|
||||||
|
log("开始检查更新...");
|
||||||
|
UpdateChecker.checkUpdate(getDescription().getVersion());
|
||||||
|
} else {
|
||||||
|
log("已禁用检查更新,跳过。");
|
||||||
|
}
|
||||||
|
|
||||||
log("加载完成 ,共耗时 " + (System.currentTimeMillis() - startTime) + " ms 。");
|
log("加载完成 ,共耗时 " + (System.currentTimeMillis() - startTime) + " ms 。");
|
||||||
|
|
||||||
showAD();
|
showAD();
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ public class PluginConfig {
|
|||||||
|
|
||||||
public static ConfigValue<Boolean> METRICS = new ConfigValue<>("metrics", Boolean.class, true);
|
public static ConfigValue<Boolean> METRICS = new ConfigValue<>("metrics", Boolean.class, true);
|
||||||
|
|
||||||
|
public static final ConfigValue<Boolean> CHECK_UPDATE = new ConfigValue<>("check-update", Boolean.class, true);
|
||||||
|
|
||||||
public static class CustomStorage {
|
public static class CustomStorage {
|
||||||
|
|
||||||
public static ConfigValue<Boolean> ENABLE = new ConfigValue<>("custom-storage.enable", Boolean.class, false);
|
public static ConfigValue<Boolean> ENABLE = new ConfigValue<>("custom-storage.enable", Boolean.class, false);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package cc.carm.plugin.userprefix.configuration.file;
|
package cc.carm.plugin.userprefix.configuration.file;
|
||||||
|
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.util.ConfigurationUtil;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -35,7 +35,7 @@ public class FileConfig {
|
|||||||
}
|
}
|
||||||
plugin.saveResource(fileName, true);
|
plugin.saveResource(fileName, true);
|
||||||
}
|
}
|
||||||
this.config = YamlConfiguration.loadConfiguration(this.file);
|
this.config = ConfigurationUtil.bang(this.file);
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getFile() {
|
public File getFile() {
|
||||||
@@ -56,7 +56,7 @@ public class FileConfig {
|
|||||||
|
|
||||||
public void reload() {
|
public void reload() {
|
||||||
if (getFile().exists()) {
|
if (getFile().exists()) {
|
||||||
this.config = YamlConfiguration.loadConfiguration(getFile());
|
this.config = ConfigurationUtil.bang(getFile());
|
||||||
} else {
|
} else {
|
||||||
initFile();
|
initFile();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
package cc.carm.plugin.userprefix.event;
|
package cc.carm.plugin.userprefix.event;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.Main;
|
||||||
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
|
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.Cancellable;
|
import org.bukkit.event.Cancellable;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class UserPrefixChangeEvent extends UserPrefixEvent implements Cancellable {
|
public class UserPrefixChangeEvent extends UserPrefixEvent implements Cancellable {
|
||||||
|
|
||||||
public static HandlerList handler = new HandlerList();
|
public static HandlerList handler = new HandlerList();
|
||||||
@@ -52,4 +57,19 @@ public class UserPrefixChangeEvent extends UserPrefixEvent implements Cancellabl
|
|||||||
public HandlerList getHandlers() {
|
public HandlerList getHandlers() {
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void call(@NotNull Player who,
|
||||||
|
@Nullable ConfiguredPrefix before,
|
||||||
|
@NotNull ConfiguredPrefix after,
|
||||||
|
@Nullable Consumer<@Nullable ConfiguredPrefix> finish) {
|
||||||
|
new BukkitRunnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
UserPrefixChangeEvent event = new UserPrefixChangeEvent(who, before, after);
|
||||||
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
|
if (finish != null) finish.accept(event.isCancelled() ? null : event.getAfter());
|
||||||
|
}
|
||||||
|
}.runTask(Main.getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package cc.carm.plugin.userprefix.event;
|
package cc.carm.plugin.userprefix.event;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.Main;
|
||||||
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
|
import cc.carm.plugin.userprefix.model.ConfiguredPrefix;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class UserPrefixExpireEvent extends UserPrefixEvent {
|
public class UserPrefixExpireEvent extends UserPrefixEvent {
|
||||||
@@ -27,4 +30,14 @@ public class UserPrefixExpireEvent extends UserPrefixEvent {
|
|||||||
public HandlerList getHandlers() {
|
public HandlerList getHandlers() {
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void call(@NotNull Player player, @NotNull ConfiguredPrefix currentPrefix) {
|
||||||
|
new BukkitRunnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Bukkit.getPluginManager().callEvent(new UserPrefixExpireEvent(player, currentPrefix));
|
||||||
|
}
|
||||||
|
}.runTask(Main.getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package cc.carm.plugin.userprefix.hooker;
|
||||||
|
|
||||||
|
import cc.carm.lib.githubreleases4j.GithubReleases4J;
|
||||||
|
import cc.carm.plugin.userprefix.Main;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
|
public class UpdateChecker {
|
||||||
|
|
||||||
|
public static void checkUpdate(String currentVersion) {
|
||||||
|
new BukkitRunnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
String downloadURL = GithubReleases4J.getReleasesURL("CarmJos", "UserPrefix");
|
||||||
|
Integer behindVersions = GithubReleases4J.getVersionBehind(
|
||||||
|
"CarmJos", "UserPrefix", currentVersion
|
||||||
|
);
|
||||||
|
|
||||||
|
if (behindVersions == null) {
|
||||||
|
Main.error("检查更新失败,请您定期查看插件是否更新,避免安全问题。");
|
||||||
|
Main.error("下载地址 " + downloadURL);
|
||||||
|
} else if (behindVersions == 0) {
|
||||||
|
Main.log("检查完成,当前已是最新版本。");
|
||||||
|
} else if (behindVersions > 0) {
|
||||||
|
Main.log("发现新版本! 目前已落后 " + behindVersions + " 个版本。");
|
||||||
|
Main.log("最新版下载地址 " + downloadURL);
|
||||||
|
} else {
|
||||||
|
Main.error("检查更新失败! 当前版本未知,请您使用原生版本以避免安全问题。");
|
||||||
|
Main.error("最新版下载地址 " + downloadURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.runTaskAsynchronously(Main.getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -121,7 +121,7 @@ public class UserManager {
|
|||||||
|
|
||||||
if (currentPrefix != null) {
|
if (currentPrefix != null) {
|
||||||
//当前前缀不为空,则代表属于前缀过期的情况
|
//当前前缀不为空,则代表属于前缀过期的情况
|
||||||
Bukkit.getPluginManager().callEvent(new UserPrefixExpireEvent(player, currentPrefix));
|
UserPrefixExpireEvent.call(player, currentPrefix);
|
||||||
|
|
||||||
// 发送消息
|
// 发送消息
|
||||||
PluginConfig.Messages.EXPIRED.sendWithPlaceholders(player,
|
PluginConfig.Messages.EXPIRED.sendWithPlaceholders(player,
|
||||||
@@ -139,17 +139,16 @@ public class UserManager {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
UserPrefixChangeEvent event = new UserPrefixChangeEvent(player, currentPrefix, newPrefix);
|
UserPrefixChangeEvent.call(player, currentPrefix, newPrefix, (after) -> {
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
if (after != null) {
|
||||||
|
UserManager.setPrefix(player, after, updateView);
|
||||||
if (!event.isCancelled()) {
|
|
||||||
// 更新前缀
|
|
||||||
UserManager.setPrefix(player, event.getAfter(), updateView);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
checkingPlayers.remove(player.getUniqueId());
|
checkingPlayers.remove(player.getUniqueId());
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
checkingPlayers.remove(player.getUniqueId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void unloadNameTag(UUID uuid) {
|
public static void unloadNameTag(UUID uuid) {
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
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.ConfigurationUtil;
|
||||||
import cc.carm.plugin.userprefix.util.ItemStackFactory;
|
import cc.carm.plugin.userprefix.util.ItemStackFactory;
|
||||||
import cc.carm.plugin.userprefix.util.MessageUtil;
|
import cc.carm.plugin.userprefix.util.MessageUtil;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
@@ -38,7 +38,11 @@ public class ConfiguredPrefix {
|
|||||||
|
|
||||||
public ConfiguredPrefix(@NotNull File dataFile) {
|
public ConfiguredPrefix(@NotNull File dataFile) {
|
||||||
this.dataFile = dataFile;
|
this.dataFile = dataFile;
|
||||||
this.configuration = YamlConfiguration.loadConfiguration(dataFile);
|
try {
|
||||||
|
this.configuration = ConfigurationUtil.bang(dataFile);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
if (getConfiguration() != null) {
|
if (getConfiguration() != null) {
|
||||||
this.identifier = getConfiguration().getString("identifier", "ERROR");
|
this.identifier = getConfiguration().getString("identifier", "ERROR");
|
||||||
this.name = getConfiguration().getString("name", "ERROR");
|
this.name = getConfiguration().getString("name", "ERROR");
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package cc.carm.plugin.userprefix.util;
|
||||||
|
|
||||||
|
import cc.carm.plugin.userprefix.wrapper.ItemStackWrapper;
|
||||||
|
import com.google.common.io.Files;
|
||||||
|
import org.bukkit.configuration.InvalidConfigurationException;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
|
public class ConfigurationUtil {
|
||||||
|
public static FileConfiguration bang(File file) {
|
||||||
|
YamlConfiguration conf = new YamlConfiguration();
|
||||||
|
StringJoiner builder = new StringJoiner("\n");
|
||||||
|
try {
|
||||||
|
//noinspection UnstableApiUsage
|
||||||
|
Files.readLines(file, StandardCharsets.UTF_8).forEach(builder::add);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return conf;
|
||||||
|
}
|
||||||
|
String tmpConf = builder.toString().replace("==: "+ ItemStack.class.getName(), "==: "+ ItemStackWrapper.class.getName());
|
||||||
|
try {
|
||||||
|
conf.loadFromString(tmpConf);
|
||||||
|
} catch (InvalidConfigurationException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String dong(FileConfiguration conf) {
|
||||||
|
return conf.saveToString().replace("==: "+ ItemStackWrapper.class.getName(),"==: "+ ItemStack.class.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -49,7 +49,7 @@ public class AutoPagedGUI extends CommonPagedGUI {
|
|||||||
|
|
||||||
@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 ? PluginConfig.GUI.Items.PREVIOUS_PAGE.get() : previousPageUI) {
|
setItem(previousPageSlot, new GUIItem(previousPageUI == null ? PluginConfig.GUI.Items.PREVIOUS_PAGE.get() : previousPageUI) {
|
||||||
@Override
|
@Override
|
||||||
@@ -63,9 +63,12 @@ public class AutoPagedGUI extends CommonPagedGUI {
|
|||||||
openGUI(user);
|
openGUI(user);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
setItem(previousPageSlot, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextPageSlot >= 0)
|
if (nextPageSlot >= 0) {
|
||||||
if (hasNextPage()) {
|
if (hasNextPage()) {
|
||||||
setItem(nextPageSlot, new GUIItem(nextPageUI == null ? PluginConfig.GUI.Items.NEXT_PAGE.get() : nextPageUI) {
|
setItem(nextPageSlot, new GUIItem(nextPageUI == null ? PluginConfig.GUI.Items.NEXT_PAGE.get() : nextPageUI) {
|
||||||
@Override
|
@Override
|
||||||
@@ -79,6 +82,9 @@ public class AutoPagedGUI extends CommonPagedGUI {
|
|||||||
openGUI(user);
|
openGUI(user);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
setItem(nextPageSlot, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.openGUI(user);
|
super.openGUI(user);
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package cc.carm.plugin.userprefix.wrapper;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ItemStackWrapper implements ConfigurationSerializable {
|
||||||
|
private static boolean unsafeAvailable;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
Class.forName("org.bukkit.UnsafeValues");
|
||||||
|
unsafeAvailable = true;
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
unsafeAvailable = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> serialize() {
|
||||||
|
throw new UnsupportedOperationException("Use ConfigurationUtil#dong to save configuration");
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static ItemStack deserialize(@NotNull Map<String, Object> args) {
|
||||||
|
// static define will cause problem, lazy load it
|
||||||
|
if (unsafeAvailable) {
|
||||||
|
if (!args.containsKey("v")) {
|
||||||
|
Material material = Material.matchMaterial(args.get("type").toString());
|
||||||
|
if (material == null) {
|
||||||
|
throw new IllegalArgumentException("物品 "+args.get("type")+" 不存在");
|
||||||
|
}
|
||||||
|
args.put("v", Bukkit.getServer().getUnsafe().getDataVersion());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ItemStack.deserialize(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,11 @@ debug: false
|
|||||||
# 当然,您也可以选择在这里关闭,或在plugins/bStats下的配置文件中关闭。
|
# 当然,您也可以选择在这里关闭,或在plugins/bStats下的配置文件中关闭。
|
||||||
metrics: true
|
metrics: true
|
||||||
|
|
||||||
|
# 检查更新设定
|
||||||
|
# 该选项用于插件判断是否要检查更新,若您不希望插件检查更新并提示您,可以选择关闭。
|
||||||
|
# 检查更新为异步操作,绝不会影响性能与使用体验。
|
||||||
|
check-update: true
|
||||||
|
|
||||||
custom-storage:
|
custom-storage:
|
||||||
# 自定义存储位置
|
# 自定义存储位置
|
||||||
# 默认存储位置为 “插件文件夹”/prefixes
|
# 默认存储位置为 “插件文件夹”/prefixes
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ debug: false #DEBUG OUT PUT
|
|||||||
|
|
||||||
metrics: true #Metrics stats (to help developer know the stats)
|
metrics: true #Metrics stats (to help developer know the stats)
|
||||||
|
|
||||||
|
# Auto check the updates.
|
||||||
|
check-update: true
|
||||||
|
|
||||||
custom-storage:
|
custom-storage:
|
||||||
# Custom storage location
|
# Custom storage location
|
||||||
# default location is "./prefixes"
|
# default location is "./prefixes"
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ authors:
|
|||||||
- SakuraGame
|
- SakuraGame
|
||||||
website: ${project.url}
|
website: ${project.url}
|
||||||
description: ${project.description}
|
description: ${project.description}
|
||||||
|
api-version: 1.13
|
||||||
|
|
||||||
depend:
|
depend:
|
||||||
- LuckPerms
|
- LuckPerms
|
||||||
|
|||||||
Reference in New Issue
Block a user