1
mirror of https://github.com/CarmJos/EasyPlugin.git synced 2024-09-18 18:55:45 +00:00

项目初始化

This commit is contained in:
Carm Jos 2022-01-04 20:38:29 +08:00
commit d77b9f696d
43 changed files with 3407 additions and 0 deletions

View File

@ -0,0 +1,9 @@
# EasyPlugin Javadoc
基于 [Github Pages](https://pages.github.com/) 搭建,请访问 [JavaDoc](https://carmjos.github.io/EasyPlugin) 。
## 如何实现?
若您也想通过 [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) 。

3
.documentation/README.md Normal file
View File

@ -0,0 +1,3 @@
# 欢迎使用 EasyPlugin
这个项目刚刚创建详细的Javadoc与开发指南还在补充请给我一点时间~

38
.github/ISSUE_TEMPLATE/bugs_report.md vendored Normal file
View File

@ -0,0 +1,38 @@
---
name: 问题提交
about: 描述问题并提交,帮助我们对其进行检查与修复。
title: ''
labels: bug
assignees: ''
---
### **问题简述**
用简短的话语描述一下大概问题。
### **问题来源**
描述一下通过哪些操作才发现的问题,如:
1. 使用了 ...
2. 输入了 ...
3. 出现了报错 ...
### **预期结果**(可选)
如果问题不发生,应该是什么情况
### **问题截图/问题报错**
如果有报错或输出,请提供截图。
### **操作环境**
- 系统环境: `Windows 10` / `Ubuntu` / `...`
- Java版本: `JDK11` / `OPENJDK8` / `JRE8` / `...`
- 服务端版本: 请在后台输入 `version` 并复制相关输出。
### **其他补充**
如有其他补充,可以在这里描述。

View File

@ -0,0 +1,20 @@
---
name: 功能需求
about: 希望我们提供更多的功能。
title: ''
labels: enhancement
assignees: ''
---
### **功能简述**
简单的描述一下你想要的功能
### **需求来源**
简单的描述一下为什么需要这个功能。
### **功能参考**(可选)
如果有相关功能的参考,如文本、截图,请提供给我们。
### **附加内容**
如果有什么小细节需要重点注意,请在这里告诉我们。

70
.github/workflows/codeql-analysis.yml vendored Normal file
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: '45 12 * * 1'
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

33
.github/workflows/deploy.yml vendored Normal file
View File

@ -0,0 +1,33 @@
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
name: Deploy
on:
# 支持手动触发构建
workflow_dispatch:
release:
# 创建release的时候触发
types: [ published ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: "Set up JDK"
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'adopt'
cache: maven
server-id: github
server-username: MAVEN_USERNAME
server-password: MAVEN_TOKEN
- name: "Deploy"
run: mvn -B deploy --file pom.xml -DskipTests
env:
MAVEN_USERNAME: ${{ github.repository_owner }}
MAVEN_TOKEN: ${{secrets.GITHUB_TOKEN}}

73
.github/workflows/javadoc.yml vendored Normal file
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 clean package -DskipTests
- name: Copy to Location
run: |
rm -rf docs
mkdir -vp docs
cp -vrf EasyPlugin-api/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/EasyPlugin
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/EasyPlugin.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

31
.github/workflows/maven.yml vendored Normal file
View File

@ -0,0 +1,31 @@
# 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: Build
on:
# 支持手动触发构建
workflow_dispatch:
push:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: "Set up JDK"
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'adopt'
- name: "Package"
run: mvn -B package --file pom.xml -Dmaven.javadoc.skip=true
- name: "Target Stage"
run: mkdir staging && cp */target/*.jar staging
- name: "Upload artifact"
uses: actions/upload-artifact@v2
with:
name: Artifact
path: staging

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/.idea/
/target/
/*/target/
**.iml

132
README.md Normal file
View File

@ -0,0 +1,132 @@
```text
______ ____ __ _
/ ____/___ ________ __ / __ \/ /_ ______ _(_)___
/ __/ / __ `/ ___/ / / / / /_/ / / / / / __ `/ / __ \
/ /___/ /_/ (__ ) /_/ / / ____/ / /_/ / /_/ / / / / /
/_____/\__,_/____/\__, / /_/ /_/\__,_/\__, /_/_/ /_/
/____/ /____/
```
# EasyPlugin
[![version](https://img.shields.io/github/v/release/CarmJos/EasyPlugin)](https://github.com/CarmJos/EasyPlugin/releases)
[![License](https://img.shields.io/github/license/CarmJos/EasyPlugin)](https://opensource.org/licenses/GPL-3.0)
[![workflow](https://github.com/CarmJos/EasyPlugin/actions/workflows/maven.yml/badge.svg?branch=master)](https://github.com/CarmJos/EasyPlugin/actions/workflows/maven.yml)
[![CodeFactor](https://www.codefactor.io/repository/github/carmjos/EasyPlugin/badge)](https://www.codefactor.io/repository/github/carmjos/EasyPlugin)
![CodeSize](https://img.shields.io/github/languages/code-size/CarmJos/EasyPlugin)
![](https://visitor-badge.glitch.me/badge?page_id=EasyPlugin.readme)
轻松(做)插件旨在于方便快捷的使用Bukkit实现MC中的一些功能。
## 优势
- 轻便独立的功能模块,按需使用,避免大量打包!
- 详细的Javadoc与使用文档轻松上手方便使用
- 持续的更新与优化,需求不止,更新不止!
- 如需新功能支持,请 [点击这里](https://github.com/CarmJos/EasyPlugin/issues/new?assignees=&labels=enhancement&template=feature_issues.md&title=) 提交功能需求。
## 内容
### 集合部分
- All [`easyplugin-all`](easyplugin-all)
- Common [`easyplugin-common`](easyplugin-common)
### 主要部分
- Main [`easyplugin-main`](easyplugin-main)
- Command [`easyplugin-command`](easyplugin-command)
- Configuration [`easyplugin-configuration`](easyplugin-configuration)
- Database [`easyplugin-database`](easyplugin-database)
- GUI [`easyplugin-gui`](easyplugin-gui)
### 附属部分
- [PlaceholderAPI](https://www.spigotmc.org/resources/6245/) [`easyplugin-placeholderapi`](easyplugin-placeholderapi)
- [Vault](https://github.com/MilkBowl/VaultAPI) [`easyplugin-vault`](easyplugin-vault)
- [LuckPerms](https://www.spigotmc.org/resources/luckperms.28140/) [`easyplugin-lp`](easyplugin-lp)
## 开发
详细开发介绍请 [点击这里](.documentation/README.md) , JavaDoc(最新Release) 请 [点击这里](https://carmjos.github.io/EasyPlugin) 。
### 示例代码
您可以 [点击这里](https://github.com/CarmJos/UltraDepository) 查看实例项目演示,更多演示详见 [开发介绍](.documentation/README.md) 。
### 依赖方式
#### Maven 依赖
<details>
<summary>远程库配置</summary>
```xml
<project>
<repositories>
<repository>
<id>EasyPlugin</id>
<name>GitHub Packages</name>
<url>https://maven.pkg.github.com/CarmJos/EasyPlugin</url>
</repository>
</repositories>
</project>
```
</details>
<details>
<summary>原生依赖</summary>
```xml
<project>
<dependencies>
<!--大全集版本,包含项目内所有模块-->
<dependency>
<groupId>cc.carm.lib</groupId>
<artifactId>easyplugin-all</artifactId>
<version>[LATEST RELEASE]</version>
<scope>compile</scope>
</dependency>
<!--轻松插件主要接口集,包含方便的插件入口类与相关工具类。-->
<dependency>
<groupId>cc.carm.lib</groupId>
<artifactId>easyplugin-main</artifactId>
<version>[LATEST RELEASE]</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
```
</details>
## 支持与捐赠
若您觉得本插件做的不错,您可以通过捐赠支持我!
感谢您对开源项目的支持!
<img height=25% width=25% src="https://raw.githubusercontent.com/CarmJos/CarmJos/main/img/donate-code.jpg" alt=""/>
## 开源协议
本项目源码采用 [The MIT License](https://opensource.org/licenses/MIT) 开源协议。
<details>
<summary>关于 MIT 协议</summary>
> MIT 协议可能是几大开源协议中最宽松的一个,核心条款是:
>
> 该软件及其相关文档对所有人免费,可以任意处置,包括使用,复制,修改,合并,发表,分发,再授权,或者销售。唯一的限制是,软件中必须包含上述版 权和许可提示。
>
> 这意味着:
> - 你可以自由使用,复制,修改,可以用于自己的项目。
> - 可以免费分发或用来盈利。
> - 唯一的限制是必须包含许可声明。
>
> MIT 协议是所有开源许可中最宽松的一个,除了必须包含许可声明外,再无任何限制。
>
> *以上文字来自 [五种开源协议GPL,LGPL,BSD,MIT,Apache](https://www.oschina.net/question/54100_9455) 。*
</details>

106
easyplugin-all/pom.xml Normal file
View File

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<artifactId>easyplugin-all</artifactId>
<packaging>jar</packaging>
<name>EasyPlugin-All</name>
<description>轻松插件全集,将打包全部工具类与工具接口。</description>
<url>https://github.com/CarmJos/EasyPlugin</url>
<developers>
<developer>
<id>CarmJos</id>
<name>Carm Jos</name>
<email>carm@carm.cc</email>
<url>https://www.carm.cc</url>
</developer>
</developers>
<licenses>
<license>
<name>GNU General Public License v3.0</name>
<url>https://opensource.org/licenses/GPL-3.0</url>
</license>
</licenses>
<issueManagement>
<system>GitHub Issues</system>
<url>https://github.com/CarmJos/EasyPlugin/issues</url>
</issueManagement>
<ciManagement>
<system>GitHub Actions</system>
<url>https://github.com/CarmJos/EasyPlugin/actions/workflows/maven.yml</url>
</ciManagement>
<dependencies>
<dependency>
<groupId>${project.parent.groupId}</groupId>
<artifactId>easyplugin-common</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.parent.groupId}</groupId>
<artifactId>easyplugin-lp</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.parent.groupId}</groupId>
<artifactId>easyplugin-placeholderapi</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.parent.groupId}</groupId>
<artifactId>easyplugin-vault</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<artifactId>easyplugin-command</artifactId>
</project>

111
easyplugin-common/pom.xml Normal file
View File

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<artifactId>easyplugin-common</artifactId>
<packaging>jar</packaging>
<name>EasyPlugin-Main</name>
<description>轻松插件常用接口集,包含除附属模块外的所有模块。</description>
<url>https://github.com/CarmJos/EasyPlugin</url>
<developers>
<developer>
<id>CarmJos</id>
<name>Carm Jos</name>
<email>carm@carm.cc</email>
<url>https://www.carm.cc</url>
</developer>
</developers>
<licenses>
<license>
<name>GNU General Public License v3.0</name>
<url>https://opensource.org/licenses/GPL-3.0</url>
</license>
</licenses>
<issueManagement>
<system>GitHub Issues</system>
<url>https://github.com/CarmJos/EasyPlugin/issues</url>
</issueManagement>
<ciManagement>
<system>GitHub Actions</system>
<url>https://github.com/CarmJos/EasyPlugin/actions/workflows/maven.yml</url>
</ciManagement>
<dependencies>
<dependency>
<groupId>${project.parent.groupId}</groupId>
<artifactId>easyplugin-main</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.parent.groupId}</groupId>
<artifactId>easyplugin-command</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.parent.groupId}</groupId>
<artifactId>easyplugin-configuration</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.parent.groupId}</groupId>
<artifactId>easyplugin-gui</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.parent.groupId}</groupId>
<artifactId>easyplugin-database</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<artifactId>easyplugin-configuration</artifactId>
<packaging>jar</packaging>
<name>EasyPlugin-Configuration</name>
<description>轻松插件配置,可以方便快捷的将配置文件作为静态参数使用。</description>
<url>https://github.com/CarmJos/EasyPlugin</url>
<developers>
<developer>
<id>CarmJos</id>
<name>Carm Jos</name>
<email>carm@carm.cc</email>
<url>https://www.carm.cc</url>
</developer>
</developers>
<licenses>
<license>
<name>GNU General Public License v3.0</name>
<url>https://opensource.org/licenses/GPL-3.0</url>
</license>
</licenses>
<issueManagement>
<system>GitHub Issues</system>
<url>https://github.com/CarmJos/EasyPlugin/issues</url>
</issueManagement>
<ciManagement>
<system>GitHub Actions</system>
<url>https://github.com/CarmJos/EasyPlugin/actions/workflows/maven.yml</url>
</ciManagement>
<dependencies>
<dependency>
<groupId>${project.parent.groupId}</groupId>
<artifactId>easyplugin-main</artifactId>
<version>${project.parent.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,91 @@
package cc.carm.lib.easyplugin.configuration.file;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.function.Supplier;
public class FileConfig {
public static Supplier<FileConfig> pluginConfiguration = null;
public static Supplier<FileConfig> messageConfiguration = null;
@Nullable
public static FileConfig getPluginConfiguration() {
return pluginConfiguration == null ? null : pluginConfiguration.get();
}
@Nullable
public static FileConfig getMessageConfiguration() {
return messageConfiguration == null ? null : messageConfiguration.get();
}
private long updateTime;
private final JavaPlugin plugin;
private final String fileName;
private File file;
private FileConfiguration config;
public FileConfig(final JavaPlugin plugin) {
this(plugin, "config.yml");
}
public FileConfig(final JavaPlugin plugin, final String name) {
this.plugin = plugin;
this.fileName = name;
initFile();
}
private void initFile() {
this.updateTime = System.currentTimeMillis();
this.file = new File(plugin.getDataFolder(), fileName);
if (!this.file.exists()) {
if (!this.file.getParentFile().exists()) {
boolean success = this.file.getParentFile().mkdirs();
}
plugin.saveResource(fileName, true);
}
this.config = YamlConfiguration.loadConfiguration(this.file);
}
public File getFile() {
return file;
}
public FileConfiguration getConfig() {
return config;
}
public void save() {
try {
getConfig().save(getFile());
} catch (IOException e) {
e.printStackTrace();
}
}
public void reload() {
this.updateTime = System.currentTimeMillis();
if (getFile().exists()) {
this.config = YamlConfiguration.loadConfiguration(getFile());
} else {
initFile();
}
}
public long getUpdateTime() {
return updateTime;
}
public boolean isExpired(long time) {
return getUpdateTime() > time;
}
}

View File

@ -0,0 +1,73 @@
package cc.carm.lib.easyplugin.configuration.impl;
import cc.carm.lib.easyplugin.configuration.file.FileConfig;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Function;
public class ConfigSectionCast<V> {
@Nullable FileConfig source;
@NotNull String configSection;
@NotNull Function<ConfigurationSection, V> valueCast;
@Nullable V defaultValue;
V valueCache;
long updateTime;
public ConfigSectionCast(@NotNull String configSection, @NotNull Function<ConfigurationSection, V> valueCast) {
this(configSection, valueCast, null);
}
public ConfigSectionCast(@NotNull String configSection,
@NotNull Function<ConfigurationSection, V> valueCast,
@Nullable V defaultValue) {
this(null, configSection, valueCast, defaultValue);
}
public ConfigSectionCast(@Nullable FileConfig source, @NotNull String configSection,
@NotNull Function<ConfigurationSection, V> valueCast,
@Nullable V defaultValue) {
this.source = source;
this.configSection = configSection;
this.valueCast = valueCast;
this.defaultValue = defaultValue;
}
public @Nullable V get() {
FileConfig source = getSource();
if (source == null) return defaultValue;
if (valueCache != null && !source.isExpired(this.updateTime)) return valueCache;
if (!source.getConfig().contains(this.configSection)) return defaultValue;
try {
V finalValue = this.valueCast.apply(source.getConfig().getConfigurationSection(this.configSection));
if (finalValue != null) {
this.valueCache = finalValue;
this.updateTime = System.currentTimeMillis();
return finalValue;
} else {
return defaultValue;
}
} catch (Exception ignore) {
return defaultValue;
}
}
public void set(ConfigurationSection section) {
}
public void save() {
if (getSource() != null) getSource().save();
}
public @Nullable FileConfig getSource() {
return source == null ? FileConfig.getPluginConfiguration() : source;
}
}

View File

@ -0,0 +1,110 @@
package cc.carm.lib.easyplugin.configuration.impl;
import cc.carm.lib.easyplugin.configuration.file.FileConfig;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ConfigSound extends ConfigStringCast<ConfigSound.SoundData> {
public ConfigSound(@NotNull String configSection) {
this(configSection, null);
}
public ConfigSound(@NotNull String configSection,
@Nullable Sound defaultValue) {
this(null, configSection, defaultValue);
}
public ConfigSound(@Nullable FileConfig source, @NotNull String configSection, @Nullable Sound defaultValue) {
super(source, configSection, string -> {
Sound finalSound = defaultValue;
float volume = 1;
float pitch = 1;
if (string != null) {
String[] args = string.contains(":") ? string.split(":") : new String[]{string};
try {
if (args.length >= 1) finalSound = Sound.valueOf(args[0]);
if (args.length >= 2) volume = Float.parseFloat(args[1]);
if (args.length >= 3) pitch = Float.parseFloat(args[2]);
} catch (Exception exception) {
Bukkit.getLogger().severe("声音 " + configSection + " 配置错误,不存在 " + string + " ,请检查。");
Bukkit.getLogger().severe("In " + configSection + " (" + string + ") doesn't match any sound name.");
}
}
if (finalSound != null) {
return new SoundData(finalSound, volume, pitch);
} else {
return null;
}
}, defaultValue == null ? null : new SoundData(defaultValue));
}
public void set(@Nullable SoundData value) {
if (value == null) {
set((String) null);
} else if (value.pitch != 1) {
set(value.type, value.volume, value.pitch);
} else if (value.volume != 1) {
set(value.type, value.volume);
} else {
set(value.type);
}
}
public void set(Sound value) {
set(value.name());
}
public void set(Sound value, float volume) {
set(value.name() + (volume != 1 ? ":" + volume : ""));
}
public void set(Sound value, float volume, float pitch) {
set(value.name() + ":" + volume + (pitch != 1 ? ":" + pitch : ""));
}
public void play(Player player) {
SoundData data = get();
if (data != null) data.play(player);
}
public void save() {
if (getSource() != null) getSource().save();
}
public @Nullable FileConfig getSource() {
return source == null ? FileConfig.getPluginConfiguration() : source;
}
public static class SoundData {
Sound type;
float volume;
float pitch;
public SoundData(Sound type) {
this(type, 1, 1);
}
public SoundData(Sound type, float volume) {
this(type, volume, 1);
}
public SoundData(Sound type, float volume, float pitch) {
this.type = type;
this.volume = volume;
this.pitch = pitch;
}
public void play(Player player) {
player.playSound(player.getLocation(), type, volume, pitch);
}
}
}

View File

@ -0,0 +1,76 @@
package cc.carm.lib.easyplugin.configuration.impl;
import cc.carm.lib.easyplugin.configuration.file.FileConfig;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Function;
public class ConfigStringCast<V> {
@Nullable FileConfig source;
@NotNull String configSection;
@NotNull Function<String, V> valueCast;
@Nullable V defaultValue;
V valueCache;
long updateTime;
public ConfigStringCast(@NotNull String configSection, @NotNull Function<String, V> valueCast) {
this(configSection, valueCast, null);
}
public ConfigStringCast(@NotNull String configSection, @NotNull Function<String, V> valueCast, @Nullable V defaultValue) {
this(null, configSection, valueCast, defaultValue);
}
public ConfigStringCast(@Nullable FileConfig source, @NotNull String configSection,
@NotNull Function<String, V> valueCast, @Nullable V defaultValue) {
this.source = source;
this.configSection = configSection;
this.valueCast = valueCast;
this.defaultValue = defaultValue;
}
public @Nullable V get() {
FileConfig source = getSource();
if (source == null) return defaultValue;
if (valueCache != null && !source.isExpired(this.updateTime)) return valueCache;
if (!source.getConfig().contains(this.configSection)) return defaultValue;
try {
V finalValue = this.valueCast.apply(source.getConfig().getString(this.configSection));
if (finalValue != null) {
this.valueCache = finalValue;
this.updateTime = System.currentTimeMillis();
return finalValue;
} else {
return defaultValue;
}
} catch (Exception ignore) {
return defaultValue;
}
}
public void set(@Nullable String value) {
FileConfig source = getSource();
if (source != null) {
source.getConfig().set(this.configSection, value);
source.save();
}
}
public void save() {
if (getSource() != null) {
getSource().save();
}
}
public @Nullable FileConfig getSource() {
return source == null ? FileConfig.getPluginConfiguration() : source;
}
}

View File

@ -0,0 +1,72 @@
package cc.carm.lib.easyplugin.configuration.message;
import cc.carm.lib.easyplugin.configuration.file.FileConfig;
import cc.carm.lib.easyplugin.configuration.values.ConfigValue;
import cc.carm.lib.easyplugin.utils.MessageUtils;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
public class ConfigMessage extends ConfigValue<String> {
String[] messageParams;
public ConfigMessage(@NotNull String configSection) {
this(configSection, null);
}
public ConfigMessage(@NotNull String configSection, @Nullable String defaultValue) {
this(configSection, defaultValue, null);
}
public ConfigMessage(@NotNull String configSection, @Nullable String defaultValue, String[] messageParams) {
super(null, configSection, String.class, defaultValue);
this.messageParams = messageParams;
}
public ConfigMessage(@Nullable FileConfig config, @NotNull String configSection,
@Nullable String defaultValue, String[] messageParams) {
super(config, configSection, String.class, defaultValue);
this.messageParams = messageParams;
}
public @NotNull String get(CommandSender sender, Object[] values) {
if (messageParams != null) {
return get(sender, messageParams, values);
} else {
return get(sender, new String[0], new Object[0]);
}
}
public @NotNull String get(CommandSender sender, String[] params, Object[] values) {
List<String> messages = MessageUtils.setPlaceholders(sender, Collections.singletonList(get()), params, values);
return messages != null && !messages.isEmpty() ? messages.get(0) : "";
}
public void send(CommandSender sender) {
MessageUtils.sendWithPlaceholders(sender, get());
}
public void send(CommandSender sender, Object[] values) {
if (messageParams != null) {
send(sender, messageParams, values);
} else {
send(sender, new String[0], new Object[0]);
}
}
public void send(CommandSender sender, String[] params, Object[] values) {
MessageUtils.sendWithPlaceholders(sender, Collections.singletonList(get()), params, values);
}
public @Nullable FileConfig getSource() {
return source == null ? FileConfig.getMessageConfiguration() : source;
}
}

View File

@ -0,0 +1,73 @@
package cc.carm.lib.easyplugin.configuration.message;
import cc.carm.lib.easyplugin.configuration.file.FileConfig;
import cc.carm.lib.easyplugin.configuration.values.ConfigValueList;
import cc.carm.lib.easyplugin.utils.MessageUtils;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class ConfigMessageList extends ConfigValueList<String> {
@Nullable String[] messageParams;
public ConfigMessageList(String configSection) {
this(configSection, new String[0]);
}
public ConfigMessageList(@NotNull String configSection, @Nullable String[] defaultValue) {
this(configSection, defaultValue, null);
}
public ConfigMessageList(@NotNull String configSection, @Nullable String[] defaultValue, String[] messageParams) {
super(null, configSection, String.class, defaultValue);
this.messageParams = messageParams;
}
public ConfigMessageList(@Nullable FileConfig config, @NotNull String configSection,
@Nullable String[] defaultValue, String[] messageParams) {
super(config, configSection, String.class, defaultValue);
this.messageParams = messageParams;
}
public @NotNull List<String> get(@Nullable CommandSender sender) {
return MessageUtils.setPlaceholders(sender, get());
}
public @NotNull List<String> get(@Nullable CommandSender sender, Object[] values) {
if (messageParams != null) {
return get(sender, messageParams, values);
} else {
return get(sender);
}
}
public @NotNull List<String> get(@Nullable CommandSender sender, String[] params, Object[] values) {
return MessageUtils.setPlaceholders(sender, get(), params, values);
}
public void send(@Nullable CommandSender sender) {
MessageUtils.sendWithPlaceholders(sender, get());
}
public void send(@Nullable CommandSender sender, Object[] values) {
if (messageParams != null) {
send(sender, messageParams, values);
} else {
send(sender);
}
}
public void send(@Nullable CommandSender sender, String[] params, Object[] values) {
MessageUtils.sendWithPlaceholders(sender, get(), params, values);
}
@Override
public @Nullable FileConfig getSource() {
return source == null ? FileConfig.getMessageConfiguration() : source;
}
}

View File

@ -0,0 +1,64 @@
package cc.carm.lib.easyplugin.configuration.values;
import cc.carm.lib.easyplugin.configuration.file.FileConfig;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ConfigValue<V> {
protected @Nullable FileConfig source;
private final @NotNull String configSection;
private final @NotNull Class<V> clazz;
@Nullable V defaultValue;
public ConfigValue(@NotNull String configSection, @NotNull Class<V> clazz) {
this(configSection, clazz, null);
}
public ConfigValue(@NotNull String configSection, @NotNull Class<V> clazz, @Nullable V defaultValue) {
this(null, configSection, clazz, defaultValue);
}
public ConfigValue(@Nullable FileConfig source, @NotNull String configSection,
@NotNull Class<V> clazz, @Nullable V defaultValue) {
this.source = source;
this.configSection = configSection;
this.clazz = clazz;
this.defaultValue = defaultValue;
}
public V get() {
FileConfig source = getSource();
if (source == null) return this.defaultValue;
if (source.getConfig().contains(this.configSection)) {
Object val = source.getConfig().get(this.configSection, this.defaultValue);
return this.clazz.isInstance(val) ? this.clazz.cast(val) : this.defaultValue;
} else {
// 如果没有默认值就把配置写进去便于配置
return setDefault();
}
}
public void set(@Nullable V value) {
FileConfig source = getSource();
if (source == null) return;
source.getConfig().set(this.configSection, value);
source.save();
}
public void save() {
if (getSource() != null) getSource().save();
}
public V setDefault() {
set(this.defaultValue);
return this.defaultValue;
}
public @Nullable FileConfig getSource() {
return source == null ? FileConfig.getPluginConfiguration() : source;
}
}

View File

@ -0,0 +1,79 @@
package cc.carm.lib.easyplugin.configuration.values;
import cc.carm.lib.easyplugin.configuration.file.FileConfig;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ConfigValueList<V> {
protected @Nullable FileConfig source;
private final @NotNull String configSection;
private final @NotNull Class<V> clazz;
@Nullable V[] defaultValue;
public ConfigValueList(@NotNull String configSection, @NotNull Class<V> clazz) {
this(configSection, clazz, null);
}
public ConfigValueList(@NotNull String configSection, @NotNull Class<V> clazz, @Nullable V[] defaultValue) {
this(null, configSection, clazz, defaultValue);
}
public ConfigValueList(@Nullable FileConfig configuration, @NotNull String configSection, Class<V> clazz) {
this(configuration, configSection, clazz, null);
}
public ConfigValueList(@Nullable FileConfig configuration, @NotNull String configSection,
@NotNull Class<V> clazz, @Nullable V[] defaultValue) {
this.source = configuration;
this.configSection = configSection;
this.clazz = clazz;
this.defaultValue = defaultValue;
}
public @NotNull ArrayList<V> get() {
FileConfig source = getSource();
if (source == null) return new ArrayList<>();
List<?> list = source.getConfig().getList(this.configSection);
if (list == null) {
if (defaultValue != null) {
return new ArrayList<>(Arrays.asList(defaultValue));
} else {
return new ArrayList<>();
}
} else {
ArrayList<V> result = new ArrayList<>();
for (Object object : list) {
if (this.clazz.isInstance(object)) {
result.add(this.clazz.cast(object));
}
}
return result;
}
}
public void set(@Nullable ArrayList<V> value) {
FileConfig source = getSource();
if (source == null) return;
source.getConfig().set(this.configSection, value);
this.save();
}
public void save() {
if (getSource() != null) getSource().save();
}
public @Nullable FileConfig getSource() {
return this.source == null ? FileConfig.getPluginConfiguration() : this.source;
}
}

View File

@ -0,0 +1,88 @@
package cc.carm.lib.easyplugin.configuration.values;
import cc.carm.lib.easyplugin.configuration.file.FileConfig;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
public class ConfigValueMap<K, V> {
@Nullable FileConfig source;
@NotNull String configSection;
@NotNull Function<String, K> keyCast;
@NotNull Class<V> valueClazz;
@Nullable LinkedHashMap<K, V> valueCache;
long updateTime;
public ConfigValueMap(@NotNull String configSection, @NotNull Function<String, K> keyCast,
@NotNull Class<V> valueClazz) {
this(null, configSection, keyCast, valueClazz);
}
public ConfigValueMap(@Nullable FileConfig configuration, @NotNull String configSection,
@NotNull Function<String, K> keyCast, @NotNull Class<V> valueClazz) {
this.source = configuration;
this.configSection = configSection;
this.keyCast = keyCast;
this.valueClazz = valueClazz;
}
public void clearCache() {
this.valueCache = null;
}
@NotNull
public Map<K, V> get() {
FileConfig source = getSource();
if (source == null) return new HashMap<>();
if (valueCache != null && !getSource().isExpired(this.updateTime)) return valueCache;
ConfigurationSection section = source.getConfig().getConfigurationSection(this.configSection);
if (section == null) return new LinkedHashMap<>();
Set<String> keys = section.getKeys(false);
if (keys.isEmpty()) return new LinkedHashMap<>();
else {
LinkedHashMap<K, V> result = new LinkedHashMap<>();
for (String key : keys) {
K finalKey = keyCast.apply(key);
Object val = section.get(key);
V finalValue = this.valueClazz.isInstance(val) ? this.valueClazz.cast(val) : null;
if (finalKey != null && finalValue != null) {
result.put(finalKey, finalValue);
}
}
this.updateTime = System.currentTimeMillis();
this.valueCache = result;
return result;
}
}
public void set(@Nullable HashMap<K, V> valuesMap) {
FileConfig source = getSource();
if (source == null) return;
source.getConfig().createSection(this.configSection, valuesMap);
source.save();
}
public void save() {
if (getSource() != null) getSource().save();
}
public @Nullable FileConfig getSource() {
return source == null ? FileConfig.getPluginConfiguration() : source;
}
}

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<artifactId>easyplugin-database</artifactId>
<packaging>jar</packaging>
<repositories>
<repository>
<id>EasySQL</id>
<url>https://maven.pkg.github.com/CarmJos/EasySQL</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>cc.carm.lib</groupId>
<artifactId>easysql-beecp</artifactId>
<version>0.2.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

62
easyplugin-gui/pom.xml Normal file
View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<artifactId>easyplugin-gui</artifactId>
<packaging>jar</packaging>
<name>EasyPlugin-GUI</name>
<description>轻松插件界面相关接口方便快捷的创建箱子GUI界面。</description>
<url>https://github.com/CarmJos/EasyPlugin</url>
<developers>
<developer>
<id>CarmJos</id>
<name>Carm Jos</name>
<email>carm@carm.cc</email>
<url>https://www.carm.cc</url>
</developer>
</developers>
<licenses>
<license>
<name>GNU General Public License v3.0</name>
<url>https://opensource.org/licenses/GPL-3.0</url>
</license>
</licenses>
<issueManagement>
<system>GitHub Issues</system>
<url>https://github.com/CarmJos/EasyPlugin/issues</url>
</issueManagement>
<ciManagement>
<system>GitHub Actions</system>
<url>https://github.com/CarmJos/EasyPlugin/actions/workflows/maven.yml</url>
</ciManagement>
<dependencies>
<dependency>
<groupId>${project.parent.groupId}</groupId>
<artifactId>easyplugin-main</artifactId>
<version>${project.parent.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,206 @@
package cc.carm.lib.easyplugin.gui;
import cc.carm.lib.easyplugin.utils.ColorParser;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;
public class GUI {
private static JavaPlugin plugin;
private static final HashMap<Player, GUI> openedGUIs = new HashMap<>();
public static void initialize(JavaPlugin plugin) {
GUI.plugin = plugin;
}
public static JavaPlugin getPlugin() {
return plugin;
}
public static HashMap<Player, GUI> getOpenedGUIs() {
return openedGUIs;
}
GUIType type;
String name;
public HashMap<Integer, GUIItem> items;
public Inventory inv;
/**
* 当玩家点击目标GUI时是否取消
*/
boolean cancelOnTarget = true;
/**
* 当玩家点击自己背包时是否取消
*/
boolean cancelOnSelf = true;
/**
* 当玩家点击界面外时是否取消
*/
boolean cancelOnOuter = true;
Map<String, Object> flags;
GUIListener listener;
public GUI(GUIType type, String name) {
this.type = type;
this.name = ColorParser.parse(name);
this.items = new HashMap<>();
}
public HashMap<@NotNull Integer, @NotNull GUIItem> getItems() {
return new HashMap<>(items);
}
public final void setItem(int index, @Nullable GUIItem item) {
if (item == null) {
this.items.remove(index);
} else {
this.items.put(index, item);
}
}
public void setItem(GUIItem item, int... index) {
for (int i : index) {
setItem(i, item);
}
}
public GUIItem getItem(int index) {
return this.items.get(index);
}
/**
* 更新玩家箱子的视图
*/
public void updateView() {
if (this.inv != null) {
List<HumanEntity> viewers = this.inv.getViewers();
IntStream.range(0, this.inv.getSize()).forEach(index -> inv.setItem(index, new ItemStack(Material.AIR)));
getItems().forEach((index, item) -> inv.setItem(index, item.getDisplay()));
viewers.forEach(p -> ((Player) p).updateInventory());
}
}
/**
* 设置是否取消点击GUI内物品的事件
* 如果不取消玩家可以从GUI中拿取物品
*
* @param b 是否取消
*/
public void setCancelOnTarget(boolean b) {
this.cancelOnTarget = b;
}
/**
* 设置是否取消点击自己背包内物品的事件
* 如果不取消玩家可以从自己的背包中拿取物品
*
* @param b 是否取消
*/
public void setCancelOnSelf(boolean b) {
this.cancelOnSelf = b;
}
/**
* 设置是否取消点击GUI外的事件
* 如果不取消玩家可以把物品从GUI或背包中丢出去
*
* @param b 是否取消
*/
public void setCancelOnOuter(boolean b) {
this.cancelOnOuter = b;
}
public void addFlag(String flag, Object obj) {
if (this.flags == null) this.flags = new HashMap<>();
this.flags.put(flag, obj);
}
public Object getFlag(String flag) {
if (this.flags == null) return null;
else
return this.flags.get(flag);
}
public void setFlag(String flag, Object obj) {
if (this.flags == null) this.flags = new HashMap<>();
this.flags.replace(flag, obj);
}
public void removeFlag(String flag) {
if (this.flags == null) this.flags = new HashMap<>();
this.flags.remove(flag);
}
public void rawClickListener(InventoryClickEvent event) {
}
public void openGUI(Player player) {
if (this.type == GUIType.CANCEL) throw new NullPointerException("被取消或不存在的GUI");
Inventory inv = Bukkit.createInventory(null, this.type.getSize(), this.name);
IntStream.range(0, this.inv.getSize()).forEach(index -> inv.setItem(index, new ItemStack(Material.AIR)));
getItems().forEach((index, item) -> inv.setItem(index, item.getDisplay()));
setOpenedGUI(player, this);
this.inv = inv;
player.openInventory(inv);
if (listener == null) {
Bukkit.getPluginManager().registerEvents(listener = new GUIListener(this), getPlugin());
}
}
/**
* 拖动GUI内物品是执行的代码
*
* @param event InventoryDragEvent
*/
public void onDrag(InventoryDragEvent event) {
}
/**
* 关闭GUI时执行的代码
*/
public void onClose() {
}
public static void setOpenedGUI(Player player, GUI gui) {
getOpenedGUIs().put(player, gui);
}
public static boolean hasOpenedGUI(Player player) {
return getOpenedGUIs().containsKey(player);
}
public static GUI getOpenedGUI(Player player) {
return getOpenedGUIs().get(player);
}
public static void removeOpenedGUI(Player player) {
getOpenedGUIs().remove(player);
}
}

View File

@ -0,0 +1,73 @@
package cc.carm.lib.easyplugin.gui;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import java.util.HashSet;
import java.util.Set;
public class GUIItem {
ItemStack display;
boolean actionActive = true;
public Set<GUIClickAction> actions = new HashSet<>();
public Set<GUIClickAction> actionsIgnoreActive = new HashSet<>();
public GUIItem(ItemStack display) {
this.display = display;
}
public final ItemStack getDisplay() {
return this.display;
}
public final void setDisplay(ItemStack display) {
this.display = display;
}
public final boolean isActionActive() {
return this.actionActive;
}
public final void setActionActive(boolean b) {
actionActive = b;
}
/**
* 玩家点击GUI后执行的代码
*
* @param type 点击的类型
*/
public void onClick(ClickType type) {
}
public void addClickAction(GUIClickAction action) {
actions.add(action);
}
public void addActionIgnoreActive(GUIClickAction action) {
actionsIgnoreActive.add(action);
}
public void rawClickAction(InventoryClickEvent event) {
}
/**
* 玩家点击GUI后执行的代码
*
* @param player 点击GUI的玩家
*/
public void customAction(Player player) {
}
public abstract static class GUIClickAction {
public abstract void run(ClickType type, Player player);
}
}

View File

@ -0,0 +1,88 @@
package cc.carm.lib.easyplugin.gui;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.player.PlayerQuitEvent;
public class GUIListener implements Listener {
GUI currentGUI;
public GUIListener(GUI gui) {
this.currentGUI = gui;
}
public GUI getCurrentGUI() {
return currentGUI;
}
@EventHandler
public void onInventoryClickEvent(InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof Player)) return;
Player player = (Player) event.getWhoClicked();
if (!GUI.hasOpenedGUI(player)) return;
if (GUI.getOpenedGUI(player) != getCurrentGUI()) return;
getCurrentGUI().rawClickListener(event);
if (event.getSlot() == -999 && getCurrentGUI().cancelOnOuter) {
event.setCancelled(true);
return;
}
if (event.getClickedInventory() == null) return;
if (event.getClickedInventory().equals(getCurrentGUI().inv)) {
if (getCurrentGUI().cancelOnTarget) event.setCancelled(true);
if (event.getSlot() != -999) {
GUIItem clickedItem = getCurrentGUI().getItem(event.getSlot());
if (clickedItem != null) {
if (clickedItem.isActionActive()) {
clickedItem.onClick(event.getClick());
clickedItem.rawClickAction(event);
clickedItem.actions.forEach(action -> action.run(event.getClick(), player));
}
clickedItem.actionsIgnoreActive.forEach(action -> action.run(event.getClick(), player));
}
}
} else if (event.getClickedInventory().equals(player.getInventory()) && getCurrentGUI().cancelOnSelf) {
event.setCancelled(true);
}
}
@EventHandler
public void onDrag(InventoryDragEvent e) {
if (!(e.getWhoClicked() instanceof Player)) return;
if (e.getInventory().equals(getCurrentGUI().inv)
|| e.getInventory().equals(e.getWhoClicked().getInventory())) {
getCurrentGUI().onDrag(e);
}
}
@EventHandler
public void onInventoryCloseEvent(InventoryCloseEvent event) {
if (!(event.getPlayer() instanceof Player)) return;
if (!event.getInventory().equals(getCurrentGUI().inv)) return;
HandlerList.unregisterAll(this);
getCurrentGUI().listener = null;
GUI.removeOpenedGUI((Player) event.getPlayer());
getCurrentGUI().onClose();
}
@EventHandler
public void onPlayerLeave(PlayerQuitEvent event) {
GUI.removeOpenedGUI(event.getPlayer());
}
}

View File

@ -0,0 +1,49 @@
package cc.carm.lib.easyplugin.gui;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
public enum GUIType {
ONE_BY_NINE(1, 9),
TWO_BY_NINE(2, 18),
THREE_BY_NINE(3, 27),
FOUR_BY_NINE(4, 36),
FIVE_BY_NINE(5, 45),
SIX_BY_NINE(6, 54),
CANCEL(0, 0);
int lines;
int size;
GUIType(int lines, int size) {
this.lines = lines;
this.size = size;
}
public int getLines() {
return lines;
}
public int getSize() {
return size;
}
@NotNull
public static GUIType getBySize(int size) {
return Arrays.stream(values()).filter(type -> type.getSize() == size).findFirst().orElse(CANCEL);
}
@NotNull
public static GUIType getByLines(int lines) {
return Arrays.stream(values()).filter(type -> type.getLines() == lines).findFirst().orElse(CANCEL);
}
@NotNull
public static GUIType getByName(String name) {
return Arrays.stream(values()).filter(type -> type.name().equalsIgnoreCase(name)).findFirst().orElse(CANCEL);
}
}

View File

@ -0,0 +1,53 @@
package cc.carm.lib.easyplugin.gui.configuration;
import cc.carm.lib.easyplugin.gui.GUIItem;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class GUIActionConfiguration {
@Nullable ClickType clickType;
final @NotNull GUIActionType actionType;
final @Nullable String actionContent;
public GUIActionConfiguration(@Nullable ClickType clickType,
@NotNull GUIActionType actionType,
@Nullable String actionContent) {
this.clickType = clickType;
this.actionType = actionType;
this.actionContent = actionContent;
}
public @Nullable ClickType getClickType() {
return clickType;
}
public @NotNull GUIActionType getActionType() {
return actionType;
}
public @Nullable String getActionContent() {
return actionContent;
}
public void checkAction(Player player, ClickType type) {
if (getClickType() == null || getClickType() == type) executeAction(player);
}
public void executeAction(Player targetPlayer) {
getActionType().getExecutor().accept(targetPlayer, getActionContent());
}
public GUIItem.GUIClickAction toClickAction() {
return new GUIItem.GUIClickAction() {
@Override
public void run(ClickType type, Player player) {
checkAction(player, type);
}
};
}
}

View File

@ -0,0 +1,88 @@
package cc.carm.lib.easyplugin.gui.configuration;
import cc.carm.lib.easyplugin.utils.MessageUtils;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.BiConsumer;
public enum GUIActionType {
/**
* 以玩家聊天的形式执行
* 若内容以 /" 开头,则会以玩家身份执行命令。
*/
CHAT((player, string) -> {
if (string == null) return;
MessageUtils.setPlaceholders(player, Collections.singletonList(string)).forEach(player::chat);
}),
/**
* 以后台的形式执行指令
* 指令内容不需要以/开头
*/
CONSOLE((player, string) -> {
if (string == null) return;
MessageUtils.setPlaceholders(player, Collections.singletonList(string))
.forEach(message -> Bukkit.dispatchCommand(Bukkit.getConsoleSender(), message));
}),
/**
* 向玩家发送消息
*/
MESSAGE(MessageUtils::send),
/**
* 向玩家发送声音
* 允许配置音量与音调
* <ul>
* <li>SOUND_NAME</li>
* <li>SOUND_NAME:VOLUME</li>
* <li>SOUND_NAME:VOLUME:PITCH</li>
* </ul>
*/
SOUND((player, string) -> {
if (string == null) return;
try {
String[] args = string.contains(":") ? string.split(":") : new String[]{string};
Sound sound = Arrays.stream(Sound.values())
.filter(s -> s.name().equals(args[0]))
.findFirst().orElse(null);
if (sound == null) return;
float volume = args.length > 1 ? Float.parseFloat(args[1]) : 1F;
float pitch = args.length > 2 ? Float.parseFloat(args[2]) : 1F;
player.playSound(player.getLocation(), sound, volume, pitch);
} catch (Exception ignored) {
}
}),
/**
* 为玩家关闭GUI
*/
CLOSE((player, string) -> player.closeInventory());
BiConsumer<@NotNull Player, @Nullable String> executor;
GUIActionType(BiConsumer<@NotNull Player, @Nullable String> executor) {
this.executor = executor;
}
public BiConsumer<@NotNull Player, @Nullable String> getExecutor() {
return executor;
}
public static GUIActionType readActionType(String string) {
return Arrays.stream(GUIActionType.values())
.filter(action -> action.name().equalsIgnoreCase(string))
.findFirst().orElse(null);
}
}

View File

@ -0,0 +1,72 @@
package cc.carm.lib.easyplugin.gui.configuration;
import cc.carm.lib.easyplugin.gui.GUI;
import cc.carm.lib.easyplugin.gui.GUIType;
import cc.carm.lib.easyplugin.utils.ColorParser;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.stream.Collectors;
public class GUIConfiguration {
String title;
int lines;
List<GUIItemConfiguration> guiItems;
public GUIConfiguration(String title, int lines, List<GUIItemConfiguration> guiItems) {
this.title = title;
this.lines = lines;
this.guiItems = guiItems;
}
public String getTitle() {
return ColorParser.parse(title);
}
public int getLines() {
return lines;
}
public GUIType getGUIType() {
return Optional.of(GUIType.getByLines(lines))
.map(type -> type == GUIType.CANCEL ? GUIType.SIX_BY_NINE : type)
.get();
}
public List<GUIItemConfiguration> getGuiItems() {
return guiItems;
}
public void setupItems(Player player, GUI gui) {
getGuiItems().forEach(itemConfiguration -> itemConfiguration.setupItems(player, gui));
}
public static GUIConfiguration readConfiguration(@Nullable ConfigurationSection section) {
if (section == null) return new GUIConfiguration("name", 6, new ArrayList<>());
String title = section.getString("title", "");
int lines = section.getInt("lines", 6);
ConfigurationSection itemsSection = section.getConfigurationSection("items");
if (itemsSection == null) return new GUIConfiguration(title, lines, new ArrayList<>());
return new GUIConfiguration(
title, lines, itemsSection.getKeys(false).stream()
.map(key -> GUIItemConfiguration.readFrom(itemsSection.getConfigurationSection(key)))
.filter(Objects::nonNull)
.collect(Collectors.toList())
);
}
public static ClickType readClickType(String type) {
return Arrays.stream(ClickType.values())
.filter(click -> click.name().equalsIgnoreCase(type))
.findFirst().orElse(null);
}
}

View File

@ -0,0 +1,92 @@
package cc.carm.lib.easyplugin.gui.configuration;
import cc.carm.lib.easyplugin.gui.GUI;
import cc.carm.lib.easyplugin.gui.GUIItem;
import cc.carm.lib.easyplugin.utils.ItemStackFactory;
import cc.carm.lib.easyplugin.utils.MessageUtils;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
public class GUIItemConfiguration {
Material material;
int data;
String name;
@NotNull List<String> lore;
@NotNull List<Integer> slots;
@NotNull List<GUIActionConfiguration> actions;
public GUIItemConfiguration(Material material, int data,
String name, @NotNull List<String> lore,
@NotNull List<GUIActionConfiguration> actions,
@NotNull List<Integer> slots) {
this.material = material;
this.data = data;
this.name = name;
this.lore = lore;
this.slots = slots;
this.actions = actions;
}
public void setupItems(Player player, GUI gui) {
ItemStackFactory icon = new ItemStackFactory(this.material);
icon.setDurability(this.data);
if (this.name != null) icon.setDisplayName(this.name);
icon.setLore(MessageUtils.setPlaceholders(player, this.lore));
GUIItem item = new GUIItem(icon.toItemStack());
this.actions.stream().map(GUIActionConfiguration::toClickAction).forEach(item::addClickAction);
this.slots.forEach(slot -> gui.setItem(slot, item));
}
@Nullable
public static GUIItemConfiguration readFrom(@Nullable ConfigurationSection itemSection) {
if (itemSection == null) return null;
Material material = Optional.ofNullable(Material.matchMaterial(itemSection.getString("material", "STONE"))).orElse(Material.STONE);
int data = itemSection.getInt("data", 0);
String name = itemSection.getString("name");
List<String> lore = itemSection.getStringList("lore");
List<Integer> slots = itemSection.getIntegerList("slots");
int slot = itemSection.getInt("slot", 0);
List<String> actionsString = itemSection.getStringList("actions");
List<GUIActionConfiguration> actions = new ArrayList<>();
for (String actionString : actionsString) {
int prefixStart = actionString.indexOf("[");
int prefixEnd = actionString.indexOf("]");
if (prefixStart < 0 || prefixEnd < 0) continue;
String prefix = actionString.substring(prefixStart + 1, prefixEnd);
ClickType clickType = null;
GUIActionType actionType;
if (prefix.contains(":")) {
String[] args = prefix.split(":");
clickType = GUIConfiguration.readClickType(args[0]);
actionType = GUIActionType.readActionType(args[1]);
} else {
actionType = GUIActionType.readActionType(prefix);
}
if (actionType == null) continue;
actions.add(new GUIActionConfiguration(clickType, actionType, actionString.substring(prefixEnd + 1).trim()));
}
return new GUIItemConfiguration(
material, data, name, lore, actions,
slots.size() > 0 ? slots : Collections.singletonList(slot)
);
}
}

23
easyplugin-lp/pom.xml Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<artifactId>easyplugin-lp</artifactId>
<packaging>jar</packaging>
</project>

74
easyplugin-main/pom.xml Normal file
View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<artifactId>easyplugin-main</artifactId>
<packaging>jar</packaging>
<name>EasyPlugin-Main</name>
<description>轻松插件主要接口集,包含方便的插件入口类与相关工具类。</description>
<url>https://github.com/CarmJos/EasyPlugin</url>
<developers>
<developer>
<id>CarmJos</id>
<name>Carm Jos</name>
<email>carm@carm.cc</email>
<url>https://www.carm.cc</url>
</developer>
</developers>
<licenses>
<license>
<name>GNU General Public License v3.0</name>
<url>https://opensource.org/licenses/GPL-3.0</url>
</license>
</licenses>
<issueManagement>
<system>GitHub Issues</system>
<url>https://github.com/CarmJos/EasyPlugin/issues</url>
</issueManagement>
<ciManagement>
<system>GitHub Actions</system>
<url>https://github.com/CarmJos/EasyPlugin/actions/workflows/maven.yml</url>
</ciManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,135 @@
package cc.carm.lib.easyplugin;
import cc.carm.lib.easyplugin.utils.ColorParser;
import cc.carm.lib.easyplugin.utils.SchedulerUtils;
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.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public abstract class EasyPlugin extends JavaPlugin {
private SchedulerUtils scheduler;
private boolean initialized = false;
@Override
public void onLoad() {
scheduler = new SchedulerUtils(this);
if (!isOverride("load")) return;
log(getName() + " " + getDescription().getVersion() + " &7开始加载...");
long startTime = System.currentTimeMillis();
load();
log("加载完成 ,共耗时 " + (System.currentTimeMillis() - startTime) + " ms 。");
}
@Override
public void onEnable() {
log(getName() + " " + getDescription().getVersion() + " &7开始启动...");
long startTime = System.currentTimeMillis();
this.initialized = initialize();
if (!isInitialized()) {
setEnabled(false);
return;
}
log("启用完成 ,共耗时 " + (System.currentTimeMillis() - startTime) + " ms 。");
}
@Override
public void onDisable() {
if (!isOverride("shutdown")) return;
log(getName() + " " + getDescription().getVersion() + " 开始卸载...");
long startTime = System.currentTimeMillis();
shutdown();
log("卸载完成 ,共耗时 " + (System.currentTimeMillis() - startTime) + " ms 。");
}
public void load() {
}
public abstract boolean initialize();
public void shutdown() {
}
public boolean isInitialized() {
return initialized;
}
public boolean isDebugging() {
return false;
}
public SchedulerUtils getScheduler() {
return scheduler;
}
public void regListener(@NotNull Listener... listeners) {
Arrays.stream(listeners).forEach(listener -> Bukkit.getPluginManager().registerEvents(listener, this));
}
public void registerCommand(String commandName,
@NotNull CommandExecutor executor) {
registerCommand(commandName, executor, executor instanceof TabCompleter ? (TabCompleter) executor : null);
}
public 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);
}
public void log(@Nullable String... messages) {
print(null, messages);
}
public void print(@Nullable String prefix, @Nullable String... messages) {
Arrays.stream(messages)
.map(message -> "[" + getName() + "] " + (prefix == null ? "" : prefix) + message)
.map(ColorParser::parse)
.forEach(message -> Bukkit.getConsoleSender().sendMessage(message));
}
public void error(String... messages) {
print("&c[ERROR] &r", messages);
}
public void debug(@Nullable String... messages) {
if (isDebugging()) print("&7[DEBUG] &r", messages);
}
private boolean isOverride(String methodName) {
Map<Method, Method> methodMap = new HashMap<>();
Arrays.stream(EasyPlugin.class.getDeclaredMethods())
.filter(method -> method.getName().equals(methodName))
.forEach(method -> Arrays.stream(getClass().getDeclaredMethods())
.filter(extend -> extend.getName().equals(methodName))
.filter(extend -> extend.getReturnType().equals(method.getReturnType()))
.filter(extend -> extend.getParameterTypes().length == method.getParameterTypes().length)
.findFirst().ifPresent(extendMethod -> methodMap.put(method, extendMethod))
);
return !methodMap.isEmpty();
}
}

View File

@ -0,0 +1,33 @@
package cc.carm.lib.easyplugin.utils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ColorParser {
public static String parse(String text) {
text = parseHexColor(text);
return parseColor(text);
}
public static String parseColor(final String text) {
return text.replaceAll("&", "§").replace("§§", "&");
}
public static String parseHexColor(String text) {
Pattern pattern = Pattern.compile("&\\((&?#[0-9a-fA-F]{6})\\)");
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
String hexColor = text.substring(matcher.start() + 2, matcher.end() - 1);
hexColor = hexColor.replace("&", "");
StringBuilder bukkitColorCode = new StringBuilder('§' + "x");
for (int i = 1; i < hexColor.length(); i++) {
bukkitColorCode.append('§').append(hexColor.charAt(i));
}
text = text.replaceAll("&\\(" + hexColor + "\\)", bukkitColorCode.toString().toLowerCase());
matcher.reset(text);
}
return text;
}
}

View File

@ -0,0 +1,144 @@
package cc.carm.lib.easyplugin.utils;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class ItemStackFactory {
ItemStack item;
private ItemStackFactory() {
}
public ItemStackFactory(ItemStack is) {
this.item = is.clone();
}
public ItemStackFactory(Material type) {
this(type, 1);
}
public ItemStackFactory(Material type, int amount) {
this(type, amount, (short) 0);
}
public ItemStackFactory(Material type, int amount, short data) {
this.item = new ItemStack(type, amount, data);
}
public ItemStackFactory(Material type, int amount, int data) {
this(type, amount, (short) data);
}
public ItemStack toItemStack() {
return this.item;
}
public ItemStackFactory setType(Material type) {
this.item.setType(type);
return this;
}
public ItemStackFactory setDurability(int i) {
ItemMeta im = this.item.getItemMeta();
if (im instanceof Damageable) {
((Damageable) im).setDamage(i);
this.item.setItemMeta(im);
}
return this;
}
public ItemStackFactory setAmount(int a) {
this.item.setAmount(a);
return this;
}
public ItemStackFactory setDisplayName(@NotNull String name) {
ItemMeta im = this.item.getItemMeta();
if (im != null) {
im.setDisplayName(ColorParser.parse(name));
this.item.setItemMeta(im);
}
return this;
}
public ItemStackFactory setLore(@NotNull List<String> loreList) {
ItemMeta im = this.item.getItemMeta();
if (im != null) {
im.setLore(
loreList.stream()
.map(ColorParser::parse)
.collect(Collectors.toList())
);
this.item.setItemMeta(im);
}
return this;
}
public ItemStackFactory addLore(@NotNull String s) {
ItemMeta im = this.item.getItemMeta();
if (im != null) {
List<String> lore = im.getLore() != null ? im.getLore() : new ArrayList<>();
lore.add(ColorParser.parse(s));
im.setLore(lore);
this.item.setItemMeta(im);
}
return this;
}
public ItemStackFactory addEnchant(@NotNull Enchantment enchant, int level, boolean ignoreLevelRestriction) {
ItemMeta im = this.item.getItemMeta();
if (im != null) {
im.addEnchant(enchant, level, ignoreLevelRestriction);
this.item.setItemMeta(im);
}
return this;
}
public ItemStackFactory removeEnchant(@NotNull Enchantment enchant) {
ItemMeta im = this.item.getItemMeta();
if (im != null) {
im.removeEnchant(enchant);
this.item.setItemMeta(im);
}
return this;
}
public ItemStackFactory addFlag(@NotNull ItemFlag flag) {
ItemMeta im = this.item.getItemMeta();
if (im != null) {
im.addItemFlags(flag);
this.item.setItemMeta(im);
}
return this;
}
public ItemStackFactory removeFlag(@NotNull ItemFlag flag) {
ItemMeta im = this.item.getItemMeta();
if (im != null) {
im.removeItemFlags(flag);
this.item.setItemMeta(im);
}
return this;
}
public ItemStackFactory setUnbreakable(boolean unbreakable) {
ItemMeta im = this.item.getItemMeta();
if (im != null) {
im.setUnbreakable(unbreakable);
this.item.setItemMeta(im);
}
return this;
}
}

View File

@ -0,0 +1,85 @@
package cc.carm.lib.easyplugin.utils;
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.*;
public class MessageUtils {
public static boolean hasPlaceholderAPI() {
return Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null;
}
public static void send(@Nullable CommandSender sender, List<String> messages) {
if (messages == null || messages.isEmpty() || sender == null) return;
for (String s : messages) {
sender.sendMessage(ColorParser.parse(s));
}
}
public static void send(@Nullable CommandSender sender, String... messages) {
send(sender, Arrays.asList(messages));
}
public static void sendWithPlaceholders(CommandSender sender, String... messages) {
sendWithPlaceholders(sender, Arrays.asList(messages));
}
public static void sendWithPlaceholders(@Nullable CommandSender sender, List<String> messages) {
if (messages == null || messages.isEmpty() || sender == null) return;
send(sender, setPlaceholders(sender, messages));
}
public static void sendWithPlaceholders(@Nullable CommandSender sender, List<String> messages, String param, Object value) {
sendWithPlaceholders(sender, messages, new String[]{param}, new Object[]{value});
}
public static void sendWithPlaceholders(@Nullable CommandSender sender, List<String> messages, String[] params, Object[] values) {
sendWithPlaceholders(sender, setCustomParams(messages, params, values));
}
public static List<String> setPlaceholders(@Nullable CommandSender sender, List<String> messages) {
if (messages == null || messages.isEmpty() || sender == null) return messages;
if (hasPlaceholderAPI() && sender instanceof Player) {
return PlaceholderAPI.setPlaceholders((Player) sender, messages);
} else {
return messages;
}
}
public static List<String> setPlaceholders(@Nullable CommandSender sender, List<String> messages, String[] params, Object[] values) {
return setPlaceholders(sender, setCustomParams(messages, params, values));
}
public static List<String> setCustomParams(List<String> messages, String param, Object value) {
return setCustomParams(messages, new String[]{param}, new Object[]{value});
}
public static List<String> setCustomParams(List<String> messages, String[] params, Object[] values) {
if (params.length != values.length) return messages;
HashMap<String, Object> paramsMap = new HashMap<>();
for (int i = 0; i < params.length; i++) {
paramsMap.put(params[i], values[i]);
}
return setCustomParams(messages, paramsMap);
}
public static List<String> setCustomParams(List<String> messages, HashMap<String, Object> params) {
List<String> list = new ArrayList<>();
for (String message : messages) {
String afterMessage = message;
for (Map.Entry<String, Object> entry : params.entrySet()) {
afterMessage = afterMessage.replace(entry.getKey(), entry.getValue().toString());
}
list.add(afterMessage);
}
return list;
}
}

View File

@ -0,0 +1,352 @@
package cc.carm.lib.easyplugin.utils;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.Callable;
@SuppressWarnings("DuplicatedCode")
public class SchedulerUtils {
private final JavaPlugin plugin;
public SchedulerUtils(JavaPlugin plugin) {
this.plugin = plugin;
}
private JavaPlugin getPlugin() {
return plugin;
}
/**
* 在主线程延时执行一个任务
*
* @param delay 延迟的ticks
* @param runnable 需要执行的任务
*/
public void runLater(long delay, Runnable runnable) {
Bukkit.getScheduler().runTaskLater(getPlugin(), runnable, delay);
}
/**
* 异步延时执行一个任务
*
* @param delay 延迟的ticks
* @param runnable 需要执行的任务
*/
public void runLaterAsync(long delay, Runnable runnable) {
Bukkit.getScheduler().runTaskLaterAsynchronously(getPlugin(), runnable, delay);
}
/**
* 异步执行一个任务
*
* @param runnable 需要执行的任务
*/
public void runAsync(Runnable runnable) {
Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), runnable);
}
/**
* 在服务端主线程中执行一个任务
*
* @param runnable 需要执行的任务
*/
public void run(Runnable runnable) {
Bukkit.getScheduler().runTask(getPlugin(), runnable);
}
/**
* 间隔一段时间按顺序异步执行列表中的任务
*
* @param interval 间隔时间
* @param tasks 任务列表
*/
public void runAtIntervalAsync(long interval, Runnable... tasks) {
runAtIntervalAsync(0L, interval, tasks);
}
/**
* 间隔一段时间按顺序执行列表中的任务
*
* @param interval 间隔时间
* @param tasks 任务列表
*/
public void runAtInterval(long interval, Runnable... tasks) {
runAtInterval(0L, interval, tasks);
}
/**
* 间隔一段时间按顺序异步执行列表中的任务
*
* @param delay 延迟时间
* @param interval 间隔时间
* @param tasks 任务列表
*/
public void runAtIntervalAsync(long delay, long interval, Runnable... tasks) {
new BukkitRunnable() {
private int index;
@Override
public void run() {
if (this.index >= tasks.length) {
this.cancel();
return;
}
tasks[index].run();
index++;
}
}.runTaskTimerAsynchronously(getPlugin(), delay, interval);
}
/**
* 间隔一段时间按顺序执行列表中的任务
*
* @param delay 延迟时间
* @param interval 间隔时间
* @param tasks 任务列表
*/
public void runAtInterval(long delay, long interval, Runnable... tasks) {
new BukkitRunnable() {
private int index;
@Override
public void run() {
if (this.index >= tasks.length) {
this.cancel();
return;
}
tasks[index].run();
index++;
}
}.runTaskTimer(getPlugin(), delay, interval);
}
/**
* 重复执行一个任务
*
* @param repetitions 重复次数
* @param interval 间隔时间
* @param task 任务
* @param onComplete 结束时执行的任务
*/
public void repeat(int repetitions, long interval, Runnable task, Runnable onComplete) {
new BukkitRunnable() {
private int index;
@Override
public void run() {
index++;
if (this.index >= repetitions) {
this.cancel();
if (onComplete == null) {
return;
}
onComplete.run();
return;
}
task.run();
}
}.runTaskTimer(getPlugin(), 0L, interval);
}
/**
* 重复执行一个任务
*
* @param repetitions 重复次数
* @param interval 间隔时间
* @param task 任务
* @param onComplete 结束时执行的任务
*/
public void repeatAsync(int repetitions, long interval, Runnable task, Runnable onComplete) {
new BukkitRunnable() {
private int index;
@Override
public void run() {
index++;
if (this.index >= repetitions) {
this.cancel();
if (onComplete == null) {
return;
}
onComplete.run();
return;
}
task.run();
}
}.runTaskTimerAsynchronously(getPlugin(), 0L, interval);
}
/**
* 在满足某个条件时重复执行一个任务
*
* @param interval 重复间隔时间
* @param predicate 条件
* @param task 任务
* @param onComplete 结束时执行的任务
*/
public void repeatWhile(long interval, Callable<Boolean> predicate, Runnable task, Runnable onComplete) {
new BukkitRunnable() {
@Override
public void run() {
try {
if (!predicate.call()) {
this.cancel();
if (onComplete == null) {
return;
}
onComplete.run();
return;
}
task.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}.runTaskTimer(getPlugin(), 0L, interval);
}
/**
* 在满足某个条件时重复执行一个任务
*
* @param interval 重复间隔时间
* @param predicate 条件
* @param task 任务
* @param onComplete 结束时执行的任务
*/
public void repeatWhileAsync(long interval, Callable<Boolean> predicate, Runnable task, Runnable onComplete) {
new BukkitRunnable() {
@Override
public void run() {
try {
if (!predicate.call()) {
this.cancel();
if (onComplete == null) {
return;
}
onComplete.run();
return;
}
task.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}.runTaskTimerAsynchronously(getPlugin(), 0L, interval);
}
public interface Task {
void start(Runnable onComplete);
}
public class TaskBuilder {
private final Queue<Task> taskList;
public TaskBuilder() {
this.taskList = new LinkedList<>();
}
public TaskBuilder append(TaskBuilder builder) {
this.taskList.addAll(builder.taskList);
return this;
}
public TaskBuilder appendDelay(long delay) {
this.taskList.add(onComplete -> SchedulerUtils.this.runLater(delay, onComplete));
return this;
}
public TaskBuilder appendTask(Runnable task) {
this.taskList.add(onComplete ->
{
task.run();
onComplete.run();
});
return this;
}
public TaskBuilder appendTask(Task task) {
this.taskList.add(task);
return this;
}
public TaskBuilder appendDelayedTask(long delay, Runnable task) {
this.taskList.add(onComplete -> SchedulerUtils.this.runLater(delay, () ->
{
task.run();
onComplete.run();
}));
return this;
}
public TaskBuilder appendTasks(long delay, long interval, Runnable... tasks) {
this.taskList.add(onComplete ->
{
Runnable[] runnables = Arrays.copyOf(tasks, tasks.length + 1);
runnables[runnables.length - 1] = onComplete;
SchedulerUtils.this.runAtInterval(delay, interval, runnables);
});
return this;
}
public TaskBuilder appendRepeatingTask(int repetitions, long interval, Runnable task) {
this.taskList.add(onComplete -> SchedulerUtils.this.repeat(repetitions, interval, task, onComplete));
return this;
}
public TaskBuilder appendConditionalRepeatingTask(long interval, Callable<Boolean> predicate, Runnable task) {
this.taskList.add(onComplete -> SchedulerUtils.this.repeatWhile(interval, predicate, task, onComplete));
return this;
}
public TaskBuilder waitFor(Callable<Boolean> predicate) {
this.taskList.add(onComplete -> new BukkitRunnable() {
@Override
public void run() {
try {
if (!predicate.call()) {
return;
}
this.cancel();
onComplete.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}.runTaskTimer(getPlugin(), 0L, 1L));
return this;
}
public void runTasks() {
this.startNext();
}
private void startNext() {
Task task = this.taskList.poll();
if (task == null) {
return;
}
task.start(this::startNext);
}
}
}

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<artifactId>easyplugin-placeholderapi</artifactId>
</project>

33
easyplugin-vault/pom.xml Normal file
View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>easyplugin-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<artifactId>easyplugin-vault</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.github.MilkBowl</groupId>
<artifactId>VaultAPI</artifactId>
<version>1.7</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

242
pom.xml Normal file
View File

@ -0,0 +1,242 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<groupId>cc.carm.lib</groupId>
<artifactId>easyplugin-parent</artifactId>
<packaging>pom</packaging>
<version>1.0.0-SNAPSHOT</version>
<modules>
<module>easyplugin-main</module>
<module>easyplugin-database</module>
<module>easyplugin-gui</module>
<module>easyplugin-configuration</module>
<module>easyplugin-command</module>
<module>easyplugin-vault</module>
<module>easyplugin-placeholderapi</module>
<module>easyplugin-all</module>
<module>easyplugin-common</module>
<module>easyplugin-lp</module>
</modules>
<name>EasyPlugin</name>
<description>轻松插件类库简单快捷的通用Spigot插件基础类库。</description>
<url>https://github.com/CarmJos/EasyPlugin</url>
<developers>
<developer>
<id>CarmJos</id>
<name>Carm Jos</name>
<email>carm@carm.cc</email>
<url>https://www.carm.cc</url>
</developer>
</developers>
<licenses>
<license>
<name>GNU General Public License v3.0</name>
<url>https://opensource.org/licenses/GPL-3.0</url>
</license>
</licenses>
<issueManagement>
<system>GitHub Issues</system>
<url>https://github.com/CarmJos/EasyPlugin/issues</url>
</issueManagement>
<ciManagement>
<system>GitHub Actions</system>
<url>https://github.com/CarmJos/EasyPlugin/actions/workflows/maven.yml</url>
</ciManagement>
<distributionManagement>
<downloadUrl>https://github.com/CarmJos/EasyPlugin/releases</downloadUrl>
<repository>
<id>github</id>
<name>GitHub Packages</name>
<url>https://maven.pkg.github.com/CarmJos/EasyPlugin</url>
</repository>
</distributionManagement>
<repositories>
<repository>
<id>github</id>
<name>GitHub Packages</name>
<url>https://maven.pkg.github.com/CarmJos/EasyPlugin</url>
</repository>
<repository>
<id>central</id>
<url>https://repo1.maven.org/maven2/</url>
</repository>
<repository>
<id>carm-repo</id>
<name>Carm's Repo</name>
<url>https://repo.carm.cc/repository/maven-public/</url>
</repository>
<repository>
<id>nexus</id>
<url>https://mvn.lumine.io/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.13-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>1.13-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.10.9</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>22.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<classifier>javadoc</classifier>
<links>
<link>https://javadoc.io/doc/org.jetbrains/annotations/</link>
</links>
<detectJavaApiLink>false</detectJavaApiLink>
<encoding>UTF-8</encoding>
<charset>UTF-8</charset>
<docencoding>UTF-8</docencoding>
<locale>zh_CN</locale>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<compilerArgument>-parameters</compilerArgument>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/MANIFEST.MF</exclude>
<exclude>META-INF/*.txt</exclude>
</excludes>
</filter>
</filters>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>