1
mirror of https://github.com/CarmJos/UltraDepository.git synced 2026-06-05 00:58:22 +08:00

Compare commits

...

26 Commits

Author SHA1 Message Date
carm a427db36e9 [v1.3.4] 版本更新
- [A] 添加版本更新检查。
2022-01-22 06:07:33 +08:00
carm afd62a493d [v1.3.3] 版本更新
- [A] 支持通过 PlugMan 等插件进行热重载。
2022-01-21 23:19:09 +08:00
carm c841a7b1b3 [v1.3.2] 版本更新
- [F] 修复Javadoc错误
2022-01-21 13:13:43 +08:00
carm dc57e822b5 [v1.3.1] 版本更新
- [F] 修复Javadoc错误
2022-01-21 13:09:45 +08:00
carm 54cc9c070b [v1.3.1] 版本更新
- [U] 修改预测仓库配置文件的位置,使其在初次启动时自动生成,避免用户完全不知道还有预设仓库这回事。
2022-01-21 13:03:43 +08:00
carm fa07564548 [v1.3.0] [A] 添加Java注释,修改debug消息位置。 2022-01-17 13:54:32 +08:00
carm 7138d20357 [v1.2.6] [R] 整合构建、部署(Javadoc)与版本发布。 2022-01-16 08:08:17 +08:00
carm 379068b440 [v1.2.5] 版本更新
- [A] 针对物品能否出售的状态提供额外的配置。
- [A] 添加ActionBar提示(如需关掉仅需将消息设为"")
- [A] 添加取回物品到背包的声音。
- [F] 修复SellGUI数量重调回0后(虽然不可能发生)物品仍然显示的问题
- [F] 修复SellGUI中可能存在的精度显示异常的问题。
2022-01-14 19:09:49 +08:00
carm 23e900cf3f 添加发布地址 2022-01-14 14:57:28 +08:00
carm 9b25c8574e [v1.2.4] 首次启动自动生成不同语言的示例文件 2022-01-14 14:08:37 +08:00
carm 23161a48bd [v1.2.4] 添加韩语 2022-01-14 13:26:52 +08:00
carm 7153661f86 [v1.2.4] 整合Javadoc网站与Maven一同部署 2022-01-14 12:57:59 +08:00
carm 19a26cb9b8 [v1.2.4] 简化配置文件类代码 2022-01-14 12:56:05 +08:00
carm c2eeddedcb [v1.2.4] 依赖更新
- [U] 采用EasyPlugin的EasyMessages实现消息配置文件
2022-01-09 13:16:08 +08:00
carm 8538aa2be8 修复构建 2022-01-08 01:49:43 +08:00
carm f001ac0010 [v1.2.3] 版本修复
- [A] 采用新版 EasyPlugin ,修改SQL语句使其更加优雅。
2022-01-08 01:05:59 +08:00
carm 988fe600ce [v1.2.2] 版本修复
- [F] 修复 getDateInt() 可能报错的问题。
2022-01-07 00:51:15 +08:00
carm 52df1863f4 [v1.2.1] 版本更新
- [U] 采用最新版本 EasyPlugin
- [U] 保留插件配置文件原本的注解
2022-01-06 16:21:48 +08:00
carm 4c46af55d0 [v1.2.1] 版本更新
- [U] 采用最新版本 EasyPlugin
- [U] 保留插件配置文件原本的注解
2022-01-06 16:21:29 +08:00
carm 123ae0b039 [v1.2.0] 版本更新
- `[U]` 采用最新版本 EasyPlugin
- `[U]` 令安静模式的权限默认不生效。
2022-01-06 14:22:42 +08:00
carm dd5793427a 指定只获取storageMethod的name 2022-01-06 00:15:00 +08:00
carm 6bf8e261d0 [v1.1.8] [F] 修复小数精度 2022-01-06 00:00:38 +08:00
carm fcdda893f1 [v1.1.8] [U] 添加安静模式下不收到提示。 2022-01-05 23:54:28 +08:00
carm 27ad14c7ab [v1.1.8] [U] 支持无限背包容量 2022-01-05 23:50:41 +08:00
carm b6a6502713 打包包含许可证 2022-01-05 23:05:24 +08:00
carm d8d589ba76 [v1.1.8] [F] 修复Debug模式失效的问题 2022-01-05 11:55:00 +08:00
46 changed files with 1683 additions and 950 deletions
+6 -6
View File
@@ -2,11 +2,11 @@
## 详细示例 ## 详细示例
您可以 [点击这里](full-example.yml) 查看一份详细的示例。 您可以 [点击这里](../../src/main/resources/depositories/.example-depository.yml) 查看一份详细的示例。
## 使用须知 ## 使用须知
预设配置基于 MineCraft 1.16 实现,更低版本可能无法使用。 预设配置基于 MineCraft 1.16 实现,理论上支持更高版本使用。
## 如何使用? ## 如何使用?
@@ -17,18 +17,18 @@
## 预设配置截图 ## 预设配置截图
### 渔夫仓库 ([fishman.yml](files/fishman.yml)) ### 渔夫仓库 ([fishman.yml](../../src/main/resources/depositories/fishman.yml))
![fishman](images/fishman.png) ![fishman](images/fishman.png)
### 矿工仓库 ([miner.yml](files/miner.yml)) ### 矿工仓库 ([miner.yml](../../src/main/resources/depositories/miner.yml))
![miner](images/miner.png) ![miner](images/miner.png)
### 农夫仓库 ([farmer.yml](files/farmer.yml)) ### 农夫仓库 ([farmer.yml](../../src/main/resources/depositories/farmer.yml))
![farmer](images/farmer.png) ![farmer](images/farmer.png)
### 猎人仓库 ([hunter.yml](files/hunter.yml)) ### 猎人仓库 ([hunter.yml](../../src/main/resources/depositories/hunter.yml))
![hunter](images/hunter.png) ![hunter](images/hunter.png)
+1 -1
View File
@@ -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:
+60 -3
View File
@@ -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
-77
View File
@@ -1,77 +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'
cache: maven
server-id: github
server-username: MAVEN_USERNAME
server-password: MAVEN_TOKEN
- name: Generate docs
run: mvn clean 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/UltraDepository
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/UltraDepository.git
git checkout -b gh-pages
git add -A
git commit -m "API Document generated."
- name: Push javadocs
run: |
cd docs
git push origin HEAD:gh-pages --force
+1 -1
View File
@@ -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: Project Build & Tests
on: on:
# 支持手动触发构建 # 支持手动触发构建
+1
View File
@@ -2,3 +2,4 @@
/target/ /target/
./*.iml ./*.iml
*.iml *.iml
asset/
+15 -11
View File
@@ -15,22 +15,24 @@
[![License](https://img.shields.io/github/license/CarmJos/UltraDepository)](https://opensource.org/licenses/GPL-3.0) [![License](https://img.shields.io/github/license/CarmJos/UltraDepository)](https://opensource.org/licenses/GPL-3.0)
[![workflow](https://github.com/CarmJos/UltraDepository/actions/workflows/maven.yml/badge.svg?branch=master)](https://github.com/CarmJos/UltraDepository/actions/workflows/maven.yml) [![workflow](https://github.com/CarmJos/UltraDepository/actions/workflows/maven.yml/badge.svg?branch=master)](https://github.com/CarmJos/UltraDepository/actions/workflows/maven.yml)
![CodeSize](https://img.shields.io/github/languages/code-size/CarmJos/UltraDepository) ![CodeSize](https://img.shields.io/github/languages/code-size/CarmJos/UltraDepository)
![Support](https://img.shields.io/badge/Minecraft-Java%201.13--Latest-green) ![Support](https://img.shields.io/badge/Minecraft-Java%201.16--Latest-green)
![](https://visitor-badge.glitch.me/badge?page_id=UltraDepository.readme) ![](https://visitor-badge.glitch.me/badge?page_id=UltraDepository.readme)
超级仓库插件,支持设定不同物品的存储仓库。 超级仓库插件,支持设定不同物品的存储仓库。
本插件基于Spigot实现,**理论上支持版本**。 本插件基于 Spigot(1.16.3) 实现,**理论上支持1.16后的全部版本**。
本插件由 [墨豆Mordo](https://www.mordo.cn)、[子墨Zimrs](https://www.zimrs.cn) 资助本人开发,经过授权后开源。 本插件由 [墨豆Mordo](https://www.mordo.cn)、[子墨Zimrs](https://www.zimrs.cn) 资助本人开发,经过授权后开源。
> 本插件已发布于 [MCBBS](https://www.mcbbs.net/forum.php?mod=viewthread&tid=1292631) 和 [SpigotMC]() 。
## 功能介绍 ## 功能介绍
本插件允许配置多个不同功能的仓库,玩家通过 击杀生物/挖掘方块/捡起收集 获得的原版物品可以自动被放入仓库中。 本插件允许配置多个不同功能的仓库,玩家通过 击杀生物/挖掘方块/捡起收集 获得的原版物品可以自动被放入仓库中。
进入仓库后的物品玩家可以选择拿出或直接按量出售,且每日的出售数量上限和每件物品的价格可以自定义。 进入仓库后的物品玩家可以选择拿出或直接按量出售,且每日的出售数量上限和每件物品的价格可以自定义。
插件支持针对不同的权限配置仓库的容量,由此可以制作付费享用的”农业仓库“、”战斗仓库“、”伐木仓库“... 插件支持针对不同的权限配置仓库的容量,由此可以制作付费享用的”作物仓库“、”药剂师仓库“、”伐木仓库“...
综上,该插件不但提供了一种功能特权,对其合理配置之后也将大大为玩家带来便利。 综上,该插件不但提供了一种功能特权,对其合理配置之后也将大大为玩家带来便利。
@@ -172,7 +174,6 @@
<summary>展开查看所有权限</summary> <summary>展开查看所有权限</summary>
```text ```text
# UltraDepository.use # UltraDepository.use
- 超级仓库的基本使用权限 (默认所有人都有) - 超级仓库的基本使用权限 (默认所有人都有)
@@ -191,9 +192,12 @@
- 若玩家缺失该权限或“UltraDepository.auto”权限,则自动收集物品功能不会启用。 - 若玩家缺失该权限或“UltraDepository.auto”权限,则自动收集物品功能不会启用。
- 您可以自己使用GUI创建一个按钮,后通过给玩家添加/删除该权限决定玩家是否开启自动收集。 - 您可以自己使用GUI创建一个按钮,后通过给玩家添加/删除该权限决定玩家是否开启自动收集。
# UltraDepository.silent
- 拥有该权限将不再接收到放入背包的提示。
- 您可以自己使用GUI创建一个按钮,后通过给玩家添加/删除该权限决定玩家是否开启收集提示。
# UltraDepository.admin # UltraDepository.admin
- "超级仓库的管理权限" - "超级仓库的管理权限"
``` ```
</details> </details>
@@ -204,19 +208,19 @@
详见源文件。 详见源文件。
### 消息配置文件 ([messages.yml](src/main/resources/messages.yml)) ### 消息配置文件 ([messages.yml](src/main/java/cc/carm/plugin/ultradepository/configuration/PluginMessages.java))
详见源文件 详见代码文件中默认值,相关文件将在首次运行时创建
### 仓库配置文件 ([depositories/<仓库ID>.yml](.examples/depositories/full-example.yml)) ### 仓库配置文件 ([depositories/<仓库ID>.yml](src/main/resources/depositories/.example-depository.yml))
所有仓库配置均为单独的配置文件,存放于 `插件配置目录/depositories` 下,便于管理。 所有仓库配置均为单独的配置文件,存放于 `插件配置目录/depositories` 下,便于管理。
文件名即仓库的ID,**强烈推荐使用纯英文**部分符号可能会影响正常读取,请避免使用。 文件名即仓库的ID,**强烈推荐使用纯英文**。以`.`开头的仓库配置不会被加载。部分符号可能会影响正常读取,请避免使用。
随本项目预设了几个常用的仓库类型,可以 [在这里](.examples/depositories) 找到您需要的仓库配置加以修改后使用。 随本项目预设了几个常用的仓库类型,可以 [在这里](.examples/depositories) 直接下载您需要的仓库配置加以修改后使用。
您也可以 [点击这里](.examples/depositories/full-example.yml) 查看一份*详细的仓库配置示例*,以制作您自己的仓库。 您也可以 [点击这里](src/main/resources/depositories/.example-depository.yml) 查看一份*详细的仓库配置示例*,以制作您自己的仓库。
## 开发 ## 开发
+45 -18
View File
@@ -9,13 +9,13 @@
<maven.compiler.target>11</maven.compiler.target> <maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding> <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<easyplugin.version>1.1.0</easyplugin.version> <easyplugin.version>1.3.5</easyplugin.version>
</properties> </properties>
<groupId>cc.carm.plugin</groupId> <groupId>cc.carm.plugin</groupId>
<artifactId>ultradepository</artifactId> <artifactId>ultradepository</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>1.1.7</version> <version>1.3.4</version>
<name>UltraDepository</name> <name>UltraDepository</name>
<description>超级仓库插件,支持设定不同物品的存储仓库。</description> <description>超级仓库插件,支持设定不同物品的存储仓库。</description>
@@ -85,52 +85,48 @@
<repository> <repository>
<id>github</id> <id>github</id>
<name>GitHub Packages</name> <name>GitHub Packages</name>
<url>https://maven.pkg.github.com/CarmJos/UltraDepository</url> <url>https://maven.pkg.github.com/CarmJos/*</url>
</repository> </repository>
</repositories> </repositories>
<dependencies> <dependencies>
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>2.2.1</version>
<scope>compile</scope>
</dependency>
<dependency> <dependency>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>easyplugin-main</artifactId> <artifactId>easyplugin-main</artifactId>
<version>${easyplugin.version}</version> <optional>true</optional>
<scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>easyplugin-configuration</artifactId> <artifactId>easyplugin-configuration</artifactId>
<version>${easyplugin.version}</version> <optional>true</optional>
<scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>easyplugin-gui</artifactId> <artifactId>easyplugin-gui</artifactId>
<version>${easyplugin.version}</version> <optional>true</optional>
<scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>cc.carm.lib</groupId> <groupId>cc.carm.lib</groupId>
<artifactId>easyplugin-database</artifactId> <artifactId>easyplugin-database</artifactId>
<version>${easyplugin.version}</version> <optional>true</optional>
</dependency>
<dependency>
<groupId>cc.carm.lib</groupId>
<artifactId>githubreleases4j</artifactId>
<version>1.2.0</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId> <artifactId>spigot-api</artifactId>
<version>1.17-R0.1-SNAPSHOT</version> <version>1.16.3-R0.1-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
@@ -141,6 +137,13 @@
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>2.2.1</version>
<scope>compile</scope>
</dependency>
<dependency> <dependency>
<groupId>com.github.MilkBowl</groupId> <groupId>com.github.MilkBowl</groupId>
<artifactId>VaultAPI</artifactId> <artifactId>VaultAPI</artifactId>
@@ -157,6 +160,20 @@
</dependencies> </dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>cc.carm.lib</groupId>
<artifactId>easyplugin-bom</artifactId>
<version>${easyplugin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
@@ -234,16 +251,26 @@
</executions> </executions>
<configuration> <configuration>
<finalName>${project.name}-${project.version}</finalName>
<outputDirectory>${project.basedir}/asset/</outputDirectory>
<createDependencyReducedPom>false</createDependencyReducedPom> <createDependencyReducedPom>false</createDependencyReducedPom>
<relocations> <relocations>
<relocation> <relocation>
<pattern>org.bstats</pattern> <pattern>org.bstats</pattern>
<shadedPattern>cc.carm.plugin.ultradepository.lib.bstats</shadedPattern> <shadedPattern>cc.carm.plugin.ultradepository.lib.bstats</shadedPattern>
</relocation> </relocation>
<relocation>
<pattern>org.json</pattern>
<shadedPattern>cc.carm.plugin.ultradepository.lib.json</shadedPattern>
</relocation>
<relocation> <relocation>
<pattern>cc.carm.lib.easyplugin</pattern> <pattern>cc.carm.lib.easyplugin</pattern>
<shadedPattern>cc.carm.plugin.ultradepository.lib.easyplugin</shadedPattern> <shadedPattern>cc.carm.plugin.ultradepository.lib.easyplugin</shadedPattern>
</relocation> </relocation>
<relocation>
<pattern>cc.carm.lib.githubreleases4j</pattern>
<shadedPattern>cc.carm.plugin.ultradepository.lib.github</shadedPattern>
</relocation>
</relocations> </relocations>
<filters> <filters>
<filter> <filter>
@@ -7,6 +7,7 @@ import cc.carm.lib.easyplugin.utils.MessageUtils;
import cc.carm.plugin.ultradepository.command.DepositoryCommand; import cc.carm.plugin.ultradepository.command.DepositoryCommand;
import cc.carm.plugin.ultradepository.configuration.PluginConfig; import cc.carm.plugin.ultradepository.configuration.PluginConfig;
import cc.carm.plugin.ultradepository.hooker.PAPIExpansion; import cc.carm.plugin.ultradepository.hooker.PAPIExpansion;
import cc.carm.plugin.ultradepository.hooker.UpdateChecker;
import cc.carm.plugin.ultradepository.listener.CollectListener; import cc.carm.plugin.ultradepository.listener.CollectListener;
import cc.carm.plugin.ultradepository.listener.UserListener; import cc.carm.plugin.ultradepository.listener.UserListener;
import cc.carm.plugin.ultradepository.manager.ConfigManager; import cc.carm.plugin.ultradepository.manager.ConfigManager;
@@ -36,36 +37,30 @@ public class UltraDepository extends EasyPlugin {
} }
@Override @Override
public void load() { protected void load() {
instance = this; instance = this;
log("加载配置文件...");
ConfigManager.initConfig();
GUI.initialize(this);
} }
@Override @Override
public boolean initialize() { protected boolean initialize() {
log("加载配置文件...");
if (!ConfigManager.initialize()) {
log("初始化配置文件失败,放弃加载。");
return false;
}
log("初始化存储方式..."); log("初始化存储方式...");
StorageMethod storageMethod = PluginConfig.STORAGE_METHOD.get(); StorageMethod storageMethod = PluginConfig.STORAGE_METHOD.getOptional().orElse(StorageMethod.YAML);
if (storageMethod == null) {
log("初始化存储方式失败,放弃加载");
return false;
}
storage = storageMethod.createStorage();
log(" 正在使用 " + storageMethod.name() + " 进行数据存储"); log(" 正在使用 " + storageMethod.name() + " 进行数据存储");
storage = storageMethod.createStorage();
if (!storage.initialize()) { if (!storage.initialize()) {
error("存储初始化失败,请检查配置文件。"); error("初始化存储失败,请检查配置文件。");
storage.shutdown();
return false; return false;
} }
log("加载用户系统...");
userManager = new UserManager();
log("加载经济系统..."); log("加载经济系统...");
if (Bukkit.getPluginManager().getPlugin("Vault") != null) { if (Bukkit.getPluginManager().getPlugin("Vault") != null) {
economyManager = new EconomyManager(); economyManager = new EconomyManager();
@@ -80,9 +75,14 @@ public class UltraDepository extends EasyPlugin {
depositoryManager = new DepositoryManager(); depositoryManager = new DepositoryManager();
getDepositoryManager().loadDepositories(); getDepositoryManager().loadDepositories();
log("加载用户系统...");
userManager = new UserManager();
log("注册监听器..."); log("注册监听器...");
regListener(new UserListener()); regListener(new UserListener());
regListener(new CollectListener()); regListener(new CollectListener());
GUI.initialize(this);
log("注册指令..."); log("注册指令...");
registerCommand("UltraDepository", new DepositoryCommand()); registerCommand("UltraDepository", new DepositoryCommand());
@@ -101,7 +101,7 @@ public class UltraDepository extends EasyPlugin {
"active_depositories", "active_depositories",
() -> getDepositoryManager().getDepositories().size()) () -> getDepositoryManager().getDepositories().size())
); );
metrics.addCustomChart(new SimplePie("storage_method", () -> getStorage().getClass().getSimpleName())); metrics.addCustomChart(new SimplePie("storage_method", storageMethod::name));
metrics.addCustomChart(new SimplePie("economy_enabled", () -> economyManager.isInitialized() ? "YES" : "NO")); metrics.addCustomChart(new SimplePie("economy_enabled", () -> economyManager.isInitialized() ? "YES" : "NO"));
metrics.addCustomChart(new SimplePie("papi_version", () -> { metrics.addCustomChart(new SimplePie("papi_version", () -> {
Plugin plugin = Bukkit.getPluginManager().getPlugin("PlaceholderAPI"); Plugin plugin = Bukkit.getPluginManager().getPlugin("PlaceholderAPI");
@@ -109,11 +109,21 @@ public class UltraDepository extends EasyPlugin {
else return plugin.getDescription().getVersion(); else return plugin.getDescription().getVersion();
})); }));
} }
if (PluginConfig.CHECK_UPDATE.get()) {
log("开始检查更新...");
UpdateChecker.checkUpdate(this);
} else {
log("已禁用检查更新,跳过。");
}
getUserManager().loadPlayersData();
return true; return true;
} }
@Override @Override
public void shutdown() { protected void shutdown() {
if (!isInitialized()) return; if (!isInitialized()) return;
log("保存现有用户数据..."); log("保存现有用户数据...");
@@ -125,6 +135,7 @@ public class UltraDepository extends EasyPlugin {
log("卸载监听器..."); log("卸载监听器...");
Bukkit.getServicesManager().unregisterAll(this); Bukkit.getServicesManager().unregisterAll(this);
} }
public static DataStorage getStorage() { public static DataStorage getStorage() {
@@ -147,6 +158,11 @@ public class UltraDepository extends EasyPlugin {
return depositoryManager; return depositoryManager;
} }
@Override
public boolean isDebugging() {
return PluginConfig.DEBUG.get();
}
@Override @Override
public void outputInfo() { public void outputInfo() {
log(" ", log(" ",
@@ -29,457 +29,457 @@ import java.util.stream.Collectors;
public class DepositoryCommand implements CommandExecutor, TabCompleter { public class DepositoryCommand implements CommandExecutor, TabCompleter {
private boolean helpConsole(CommandSender sender) { private boolean helpConsole(CommandSender sender) {
PluginMessages.HELP_CONSOLE.send(sender); PluginMessages.Usages.CONSOLE.send(sender);
return true; return true;
} }
private boolean helpPlayer(Player player) { private boolean helpPlayer(Player player) {
PluginMessages.HELP_PLAYER.send(player); PluginMessages.Usages.PLAYER.send(player);
return true; return true;
} }
@Override @Override
public boolean onCommand( public boolean onCommand(
@NotNull CommandSender sender, @NotNull Command command, @NotNull CommandSender sender, @NotNull Command command,
@NotNull String alias, @NotNull String[] args) { @NotNull String alias, @NotNull String[] args) {
if (sender instanceof Player) { if (sender instanceof Player) {
Player player = (Player) sender; Player player = (Player) sender;
if (args.length < 1) return helpPlayer(player); if (args.length < 1) return helpPlayer(player);
switch (args[0].toLowerCase()) { switch (args[0].toLowerCase()) {
case "open": { case "open": {
if (!player.hasPermission("UltraDepository.use")) { if (!player.hasPermission("UltraDepository.use")) {
return false; return false;
} }
if (args.length < 2) return helpPlayer(player); if (args.length < 2) return helpPlayer(player);
Depository depository = UltraDepository.getDepositoryManager().getDepository(args[1]); Depository depository = UltraDepository.getDepositoryManager().getDepository(args[1]);
if (depository == null) { if (depository == null) {
PluginMessages.NO_DEPOSITORY.send(player); PluginMessages.NO_DEPOSITORY.send(player);
return true; return true;
} }
DepositoryGUI.open((Player) sender, depository); DepositoryGUI.open((Player) sender, depository);
return true; return true;
} }
case "sell": { case "sell": {
if (!player.hasPermission("UltraDepository.Command.Sell")) { if (!player.hasPermission("UltraDepository.Command.Sell")) {
return false; return false;
} }
if (!UltraDepository.getEconomyManager().isInitialized()) { if (!UltraDepository.getEconomyManager().isInitialized()) {
PluginConfig.Sounds.SELL_FAIL.play(player); PluginConfig.Sounds.SELL_FAIL.play(player);
PluginMessages.NO_ECONOMY.send(player); PluginMessages.NO_ECONOMY.send(player);
return true; return true;
} }
if (args.length < 4) return helpPlayer(player); if (args.length < 4) return helpPlayer(player);
Depository depository = UltraDepository.getDepositoryManager().getDepository(args[1]); Depository depository = UltraDepository.getDepositoryManager().getDepository(args[1]);
if (depository == null) { if (depository == null) {
PluginConfig.Sounds.SELL_FAIL.play(player); PluginConfig.Sounds.SELL_FAIL.play(player);
PluginMessages.NO_DEPOSITORY.send(player); PluginMessages.NO_DEPOSITORY.send(player);
return true; return true;
} }
DepositoryItem item = depository.getItems().get(args[2]); DepositoryItem item = depository.getItems().get(args[2]);
if (item == null) { if (item == null) {
PluginConfig.Sounds.SELL_FAIL.play(player); PluginConfig.Sounds.SELL_FAIL.play(player);
PluginMessages.NO_ITEM.send(player); PluginMessages.NO_ITEM.send(player);
return true; return true;
} }
int amount = -1; int amount = -1;
try { try {
amount = Integer.parseInt(args[3]); amount = Integer.parseInt(args[3]);
} catch (Exception ignore) { } catch (Exception ignore) {
} }
if (amount <= 0) { if (amount <= 0) {
PluginConfig.Sounds.SELL_FAIL.play(player); PluginConfig.Sounds.SELL_FAIL.play(player);
PluginMessages.WRONG_NUMBER.send(player); PluginMessages.WRONG_NUMBER.send(player);
return true; return true;
} }
UserData userData = UltraDepository.getUserManager().getData(player); UserData userData = UltraDepository.getUserManager().getData(player);
DepositoryItemData itemData = userData.getItemData(item); DepositoryItemData itemData = userData.getItemData(item);
int limit = item.getLimit(); int limit = item.getLimit();
int sold = itemData.getSold(); int sold = itemData.getSold();
int currentAmount = itemData.getAmount(); int currentAmount = itemData.getAmount();
if (currentAmount < amount) { if (currentAmount < amount) {
PluginConfig.Sounds.SELL_FAIL.play(player); PluginConfig.Sounds.SELL_FAIL.play(player);
PluginMessages.NO_ENOUGH_ITEM.send(player); PluginMessages.NO_ENOUGH_ITEM.send(player);
return true; return true;
} }
if (amount > (limit - sold)) { if (amount > (limit - sold)) {
PluginConfig.Sounds.SELL_FAIL.play(player); PluginConfig.Sounds.SELL_FAIL.play(player);
PluginMessages.ITEM_SOLD_LIMIT.send(player, new Object[]{(limit - sold), limit}); PluginMessages.ITEM_SOLD_LIMIT.send(player, new Object[]{(limit - sold), limit});
return true; return true;
} }
UltraDepository.getEconomyManager().sellItem(player, userData, item, amount); UltraDepository.getEconomyManager().sellItem(player, userData, item, amount);
return true; return true;
} }
case "sellall": { case "sellall": {
if (!player.hasPermission("UltraDepository.Command.SellAll")) { if (!player.hasPermission("UltraDepository.Command.SellAll")) {
return false; return false;
} }
if (!UltraDepository.getEconomyManager().isInitialized()) { if (!UltraDepository.getEconomyManager().isInitialized()) {
PluginConfig.Sounds.SELL_FAIL.play(player); PluginConfig.Sounds.SELL_FAIL.play(player);
PluginMessages.NO_ECONOMY.send(player); PluginMessages.NO_ECONOMY.send(player);
return true; return true;
} }
UserData userData = UltraDepository.getUserManager().getData(player); UserData userData = UltraDepository.getUserManager().getData(player);
String depositoryID = args.length >= 2 ? args[1] : null; String depositoryID = args.length >= 2 ? args[1] : null;
String itemID = args.length >= 3 ? args[2] : null; String itemID = args.length >= 3 ? args[2] : null;
Depository depository = null; Depository depository = null;
if (depositoryID != null) { if (depositoryID != null) {
depository = UltraDepository.getDepositoryManager().getDepository(depositoryID); depository = UltraDepository.getDepositoryManager().getDepository(depositoryID);
if (depository == null) { if (depository == null) {
PluginConfig.Sounds.SELL_FAIL.play(player); PluginConfig.Sounds.SELL_FAIL.play(player);
PluginMessages.NO_DEPOSITORY.send(player); PluginMessages.NO_DEPOSITORY.send(player);
return true; return true;
} }
} }
if (depository == null) { if (depository == null) {
UltraDepository.getEconomyManager().sellAllItem(player, userData); UltraDepository.getEconomyManager().sellAllItem(player, userData);
sender.sendMessage("Success! " + player.getName() + "'s items had been sold."); sender.sendMessage("Success! " + player.getName() + "'s items had been sold.");
return true; return true;
} }
DepositoryItem item = null; DepositoryItem item = null;
if (itemID != null) { if (itemID != null) {
item = depository.getItems().get(itemID); item = depository.getItems().get(itemID);
if (item == null) { if (item == null) {
PluginConfig.Sounds.SELL_FAIL.play(player); PluginConfig.Sounds.SELL_FAIL.play(player);
PluginMessages.NO_ITEM.send(player); PluginMessages.NO_ITEM.send(player);
return true; return true;
} }
} }
if (item == null) { if (item == null) {
UltraDepository.getEconomyManager().sellAllItem(player, userData, depository); UltraDepository.getEconomyManager().sellAllItem(player, userData, depository);
return true; return true;
} }
UltraDepository.getEconomyManager().sellAllItem(player, userData, item); UltraDepository.getEconomyManager().sellAllItem(player, userData, item);
return true; return true;
} }
default: default:
return helpPlayer(player); return helpPlayer(player);
} }
} else { } else {
if (args.length < 1) return helpConsole(sender); if (args.length < 1) return helpConsole(sender);
switch (args[0].toLowerCase()) { switch (args[0].toLowerCase()) {
case "info": { case "info": {
if (args.length < 2) return helpConsole(sender); if (args.length < 2) return helpConsole(sender);
Player player = Bukkit.getPlayer(args[1]); Player player = Bukkit.getPlayer(args[1]);
if (player == null) { if (player == null) {
sender.sendMessage("Player does not exist."); sender.sendMessage("Player does not exist.");
return false; return false;
} }
UserData userData = UltraDepository.getUserManager().getData(player); UserData userData = UltraDepository.getUserManager().getData(player);
String depositoryID = args.length >= 3 ? args[2] : null; String depositoryID = args.length >= 3 ? args[2] : null;
String itemID = args.length >= 4 ? args[3] : null; String itemID = args.length >= 4 ? args[3] : null;
Depository depository = null; Depository depository = null;
if (depositoryID != null) { if (depositoryID != null) {
depository = UltraDepository.getDepositoryManager().getDepository(depositoryID); depository = UltraDepository.getDepositoryManager().getDepository(depositoryID);
if (depository == null) { if (depository == null) {
PluginMessages.NO_DEPOSITORY.send(player); PluginMessages.NO_DEPOSITORY.send(player);
return true; return true;
} }
} }
sender.sendMessage(ColorParser.parse("&fInfo &6" + player.getName() + " &f:")); sender.sendMessage(ColorParser.parse("&fInfo &6" + player.getName() + " &f:"));
if (depository == null) { if (depository == null) {
userData.getDepositories().values().forEach(depositoryData -> { userData.getDepositories().values().forEach(depositoryData -> {
MessageUtils.send(sender, "&8# &e" + depositoryData.getIdentifier()); MessageUtils.send(sender, "&8# &e" + depositoryData.getIdentifier());
depositoryData.getContents().values().forEach(itemData -> { depositoryData.getContents().values().forEach(itemData -> {
String typeID = itemData.getSource().getTypeID(); String typeID = itemData.getSource().getTypeID();
int amount = itemData.getAmount(); int amount = itemData.getAmount();
int sold = itemData.getSold(); int sold = itemData.getSold();
MessageUtils.send(sender, "&8- &f" + typeID + " &7[&f " + amount + "&8|&f " + sold + "&7]"); MessageUtils.send(sender, "&8- &f" + typeID + " &7[&f " + amount + "&8|&f " + sold + "&7]");
}); });
}); });
return true; return true;
} }
DepositoryItem item = null; DepositoryItem item = null;
if (itemID != null) { if (itemID != null) {
item = depository.getItems().get(itemID); item = depository.getItems().get(itemID);
if (item == null) { if (item == null) {
PluginMessages.NO_ITEM.send(player); PluginMessages.NO_ITEM.send(player);
return true; return true;
} }
} }
if (item == null) { if (item == null) {
DepositoryData depositoryData = userData.getDepositoryData(depository); DepositoryData depositoryData = userData.getDepositoryData(depository);
MessageUtils.send(sender, "&8# &e" + depositoryData.getIdentifier()); MessageUtils.send(sender, "&8# &e" + depositoryData.getIdentifier());
depositoryData.getContents().values().forEach(itemData -> { depositoryData.getContents().values().forEach(itemData -> {
String typeID = itemData.getSource().getTypeID(); String typeID = itemData.getSource().getTypeID();
int amount = itemData.getAmount(); int amount = itemData.getAmount();
int sold = itemData.getSold(); int sold = itemData.getSold();
MessageUtils.send(sender, "&8- &f" + typeID + " &7[&f " + amount + "&8|&f " + sold + "&7]"); MessageUtils.send(sender, "&8- &f" + typeID + " &7[&f " + amount + "&8|&f " + sold + "&7]");
}); });
return true; return true;
} }
DepositoryItemData itemData = userData.getItemData(item); DepositoryItemData itemData = userData.getItemData(item);
String typeID = itemData.getSource().getTypeID(); String typeID = itemData.getSource().getTypeID();
int amount = itemData.getAmount(); int amount = itemData.getAmount();
int sold = itemData.getSold(); int sold = itemData.getSold();
MessageUtils.send(sender, "&8# &e" + depository.getIdentifier()); MessageUtils.send(sender, "&8# &e" + depository.getIdentifier());
MessageUtils.send(sender, "&8- &f" + typeID + " &7[&f " + amount + "&8|&f " + sold + "&7]"); MessageUtils.send(sender, "&8- &f" + typeID + " &7[&f " + amount + "&8|&f " + sold + "&7]");
return true; return true;
} }
case "add": { case "add": {
if (args.length < 5) return true; if (args.length < 5) return true;
Player player = Bukkit.getPlayer(args[1]); Player player = Bukkit.getPlayer(args[1]);
if (player == null) { if (player == null) {
sender.sendMessage("Player does not exist."); sender.sendMessage("Player does not exist.");
return false; return false;
} }
Depository depository = UltraDepository.getDepositoryManager().getDepository(args[2]); Depository depository = UltraDepository.getDepositoryManager().getDepository(args[2]);
if (depository == null) { if (depository == null) {
PluginMessages.NO_DEPOSITORY.send(sender); PluginMessages.NO_DEPOSITORY.send(sender);
return true; return true;
} }
DepositoryItem item = depository.getItems().get(args[3]); DepositoryItem item = depository.getItems().get(args[3]);
if (item == null) { if (item == null) {
PluginMessages.NO_ITEM.send(sender); PluginMessages.NO_ITEM.send(sender);
return true; return true;
} }
int amount = -1; int amount = -1;
try { try {
amount = Integer.parseInt(args[4]); amount = Integer.parseInt(args[4]);
} catch (Exception ignore) { } catch (Exception ignore) {
} }
if (amount <= 0) { if (amount <= 0) {
PluginMessages.WRONG_NUMBER.send(sender); PluginMessages.WRONG_NUMBER.send(sender);
return true; return true;
} }
Integer after = UltraDepository.getUserManager().getData(player) Integer after = UltraDepository.getUserManager().getData(player)
.addItemAmount(depository.getIdentifier(), item.getTypeID(), amount); .addItemAmount(depository.getIdentifier(), item.getTypeID(), amount);
if (after != null) { if (after != null) {
sender.sendMessage("Success! Now " + player.getName() + "'s " + item.getTypeID() + " is " + after + " ."); sender.sendMessage("Success! Now " + player.getName() + "'s " + item.getTypeID() + " is " + after + " .");
} else { } else {
sender.sendMessage("Failed!"); sender.sendMessage("Failed!");
} }
return true; return true;
} }
case "remove": { case "remove": {
if (args.length < 4) return true; if (args.length < 4) return true;
Player player = Bukkit.getPlayer(args[1]); Player player = Bukkit.getPlayer(args[1]);
if (player == null) { if (player == null) {
sender.sendMessage("Player does not exist."); sender.sendMessage("Player does not exist.");
return false; return false;
} }
Depository depository = UltraDepository.getDepositoryManager().getDepository(args[2]); Depository depository = UltraDepository.getDepositoryManager().getDepository(args[2]);
if (depository == null) { if (depository == null) {
PluginMessages.NO_DEPOSITORY.send(sender); PluginMessages.NO_DEPOSITORY.send(sender);
return true; return true;
} }
DepositoryItem item = depository.getItems().get(args[3]); DepositoryItem item = depository.getItems().get(args[3]);
if (item == null) { if (item == null) {
PluginMessages.NO_ITEM.send(sender); PluginMessages.NO_ITEM.send(sender);
return true; return true;
} }
Integer amount = null; Integer amount = null;
try { try {
amount = Integer.parseInt(args[4]); amount = Integer.parseInt(args[4]);
} catch (Exception ignore) { } catch (Exception ignore) {
} }
if (amount != null && amount < 0) { if (amount != null && amount < 0) {
PluginMessages.WRONG_NUMBER.send(sender); PluginMessages.WRONG_NUMBER.send(sender);
return true; return true;
} }
UserData userData = UltraDepository.getUserManager().getData(player); UserData userData = UltraDepository.getUserManager().getData(player);
if (amount != null) { if (amount != null) {
Integer after = userData.removeItemAmount(depository.getIdentifier(), item.getTypeID(), amount); Integer after = userData.removeItemAmount(depository.getIdentifier(), item.getTypeID(), amount);
if (after != null) { if (after != null) {
sender.sendMessage("Success! Now " + player.getName() + "'s " + item.getTypeID() + " is " + after + " ."); sender.sendMessage("Success! Now " + player.getName() + "'s " + item.getTypeID() + " is " + after + " .");
} else { } else {
sender.sendMessage("Failed!"); sender.sendMessage("Failed!");
} }
} else { } else {
userData.setItemAmount(depository.getIdentifier(), item.getTypeID(), 0); userData.setItemAmount(depository.getIdentifier(), item.getTypeID(), 0);
sender.sendMessage("Success! Cleared " + player.getName() + "'s " + item.getTypeID() + " ."); sender.sendMessage("Success! Cleared " + player.getName() + "'s " + item.getTypeID() + " .");
} }
return true; return true;
} }
case "sell": { case "sell": {
if (args.length < 2) return true; if (args.length < 2) return true;
Player player = Bukkit.getPlayer(args[1]); Player player = Bukkit.getPlayer(args[1]);
if (player == null) { if (player == null) {
sender.sendMessage("Player does not exist."); sender.sendMessage("Player does not exist.");
return false; return false;
} }
String depositoryID = args.length >= 3 ? args[2] : null; String depositoryID = args.length >= 3 ? args[2] : null;
String itemID = args.length >= 4 ? args[3] : null; String itemID = args.length >= 4 ? args[3] : null;
Depository depository = null; Depository depository = null;
if (depositoryID != null) { if (depositoryID != null) {
depository = UltraDepository.getDepositoryManager().getDepository(depositoryID); depository = UltraDepository.getDepositoryManager().getDepository(depositoryID);
if (depository == null) { if (depository == null) {
PluginMessages.NO_DEPOSITORY.send(sender); PluginMessages.NO_DEPOSITORY.send(sender);
return true; return true;
} }
} }
UserData userData = UltraDepository.getUserManager().getData(player); UserData userData = UltraDepository.getUserManager().getData(player);
if (depository == null) { if (depository == null) {
UltraDepository.getEconomyManager().sellAllItem(player, userData); UltraDepository.getEconomyManager().sellAllItem(player, userData);
sender.sendMessage("Success! " + player.getName() + "'s items had been sold."); sender.sendMessage("Success! " + player.getName() + "'s items had been sold.");
return true; return true;
} }
DepositoryItem item = null; DepositoryItem item = null;
if (itemID != null) { if (itemID != null) {
item = depository.getItems().get(itemID); item = depository.getItems().get(itemID);
if (item == null) { if (item == null) {
PluginMessages.NO_ITEM.send(player); PluginMessages.NO_ITEM.send(player);
return true; return true;
} }
} }
if (item == null) { if (item == null) {
UltraDepository.getEconomyManager().sellAllItem(player, userData, depository); UltraDepository.getEconomyManager().sellAllItem(player, userData, depository);
sender.sendMessage("Success! " + player.getName() + "'s " + depository.getIdentifier() + " had been sold."); sender.sendMessage("Success! " + player.getName() + "'s " + depository.getIdentifier() + " had been sold.");
return true; return true;
} }
Integer amount = null; Integer amount = null;
if (args.length >= 5) { if (args.length >= 5) {
try { try {
amount = Integer.parseInt(args[4]); amount = Integer.parseInt(args[4]);
} catch (Exception ignore) { } catch (Exception ignore) {
} }
} }
if (amount != null && amount < 0) { if (amount != null && amount < 0) {
PluginMessages.WRONG_NUMBER.send(sender); PluginMessages.WRONG_NUMBER.send(sender);
return true; return true;
} }
if (amount == null) { if (amount == null) {
UltraDepository.getEconomyManager().sellAllItem(player, userData, item); UltraDepository.getEconomyManager().sellAllItem(player, userData, item);
sender.sendMessage("Success! " + player.getName() + "'s " + item.getTypeID() + " had been sold."); sender.sendMessage("Success! " + player.getName() + "'s " + item.getTypeID() + " had been sold.");
return true; return true;
} }
DepositoryItemData itemData = userData.getItemData(item); DepositoryItemData itemData = userData.getItemData(item);
int limit = item.getLimit(); int limit = item.getLimit();
int sold = itemData.getSold(); int sold = itemData.getSold();
int currentAmount = itemData.getAmount(); int currentAmount = itemData.getAmount();
if (currentAmount < amount) { if (currentAmount < amount) {
PluginMessages.NO_ENOUGH_ITEM.send(sender); PluginMessages.NO_ENOUGH_ITEM.send(sender);
return true; return true;
} }
if (currentAmount > (limit - sold)) { if (currentAmount > (limit - sold)) {
PluginMessages.ITEM_SOLD_LIMIT.send(sender, new Object[]{(limit - sold), limit}); PluginMessages.ITEM_SOLD_LIMIT.send(sender, new Object[]{(limit - sold), limit});
return true; return true;
} }
UltraDepository.getEconomyManager().sellItem(player, userData, item, amount); UltraDepository.getEconomyManager().sellItem(player, userData, item, amount);
sender.sendMessage("Success! " + player.getName() + "'s " + amount + " " + item.getTypeID() + " had been sold."); sender.sendMessage("Success! " + player.getName() + "'s " + amount + " " + item.getTypeID() + " had been sold.");
return true; return true;
} }
default: default:
return helpConsole(sender); return helpConsole(sender);
} }
} }
} }
@Nullable @Nullable
@Override @Override
public List<String> onTabComplete( public List<String> onTabComplete(
@NotNull CommandSender sender, @NotNull Command command, @NotNull CommandSender sender, @NotNull Command command,
@NotNull String alias, @NotNull String[] args) { @NotNull String alias, @NotNull String[] args) {
List<String> allCompletes = new ArrayList<>(); List<String> allCompletes = new ArrayList<>();
if (sender instanceof Player) { if (sender instanceof Player) {
// 玩家指令部分 // 玩家指令部分
Player player = (Player) sender; Player player = (Player) sender;
if (player.hasPermission("UltraDepository.use")) { if (player.hasPermission("UltraDepository.use")) {
switch (args.length) { switch (args.length) {
case 1: { case 1: {
allCompletes.add("open"); allCompletes.add("open");
if (player.hasPermission("UltraDepository.Command.Sell")) allCompletes.add("sell"); if (player.hasPermission("UltraDepository.Command.Sell")) allCompletes.add("sell");
if (player.hasPermission("UltraDepository.Command.SellAll")) allCompletes.add("sellAll"); if (player.hasPermission("UltraDepository.Command.SellAll")) allCompletes.add("sellAll");
break; break;
} }
case 2: { case 2: {
String aim = args[0]; String aim = args[0];
if (aim.equalsIgnoreCase("open") if (aim.equalsIgnoreCase("open")
|| (aim.equalsIgnoreCase("sell") || (aim.equalsIgnoreCase("sell")
&& player.hasPermission("UltraDepository.Command.Sell")) && player.hasPermission("UltraDepository.Command.Sell"))
|| (aim.equalsIgnoreCase("sellAll") || (aim.equalsIgnoreCase("sellAll")
&& player.hasPermission("UltraDepository.Command.SellAll"))) { && player.hasPermission("UltraDepository.Command.SellAll"))) {
allCompletes.addAll(UltraDepository.getDepositoryManager().getDepositories().keySet()); allCompletes.addAll(UltraDepository.getDepositoryManager().getDepositories().keySet());
} }
break; break;
} }
case 3: { case 3: {
String aim = args[0]; String aim = args[0];
String depositoryID = args[1]; String depositoryID = args[1];
if ((aim.equalsIgnoreCase("sell") if ((aim.equalsIgnoreCase("sell")
&& player.hasPermission("UltraDepository.Command.Sell")) && player.hasPermission("UltraDepository.Command.Sell"))
|| (aim.equalsIgnoreCase("sellAll") || (aim.equalsIgnoreCase("sellAll")
&& player.hasPermission("UltraDepository.Command.SellAll"))) { && player.hasPermission("UltraDepository.Command.SellAll"))) {
Depository depository = UltraDepository.getDepositoryManager().getDepository(depositoryID); Depository depository = UltraDepository.getDepositoryManager().getDepository(depositoryID);
if (depository != null) { if (depository != null) {
allCompletes.addAll(depository.getItems().keySet()); allCompletes.addAll(depository.getItems().keySet());
} }
} }
break; break;
} }
} }
} }
} else { } else {
//后台指令部分 //后台指令部分
switch (args.length) { switch (args.length) {
case 1: { case 1: {
allCompletes.add("info"); allCompletes.add("info");
allCompletes.add("add"); allCompletes.add("add");
allCompletes.add("remove"); allCompletes.add("remove");
allCompletes.add("sell"); allCompletes.add("sell");
break; break;
} }
case 2: { case 2: {
allCompletes = Bukkit.getOnlinePlayers().stream().map(HumanEntity::getName).collect(Collectors.toList()); allCompletes = Bukkit.getOnlinePlayers().stream().map(HumanEntity::getName).collect(Collectors.toList());
break; break;
} }
case 3: { case 3: {
allCompletes.addAll(UltraDepository.getDepositoryManager().getDepositories().keySet()); allCompletes.addAll(UltraDepository.getDepositoryManager().getDepositories().keySet());
break; break;
} }
case 4: { case 4: {
Depository depository = UltraDepository.getDepositoryManager().getDepository(args[2]); Depository depository = UltraDepository.getDepositoryManager().getDepository(args[2]);
if (depository != null) { if (depository != null) {
allCompletes.addAll(depository.getItems().keySet()); allCompletes.addAll(depository.getItems().keySet());
} }
break; break;
} }
} }
} }
return allCompletes.stream() return allCompletes.stream()
.filter(s -> StringUtil.startsWithIgnoreCase(s, args[args.length - 1])) .filter(s -> StringUtil.startsWithIgnoreCase(s, args[args.length - 1]))
.limit(10).collect(Collectors.toList()); .limit(10).collect(Collectors.toList());
} }
} }
@@ -1,13 +1,15 @@
package cc.carm.plugin.ultradepository.configuration; package cc.carm.plugin.ultradepository.configuration;
import cc.carm.lib.easyplugin.configuration.cast.ConfigStringCast;
import cc.carm.lib.easyplugin.configuration.impl.ConfigItem;
import cc.carm.lib.easyplugin.configuration.impl.ConfigSound; import cc.carm.lib.easyplugin.configuration.impl.ConfigSound;
import cc.carm.lib.easyplugin.configuration.impl.ConfigStringCast;
import cc.carm.lib.easyplugin.configuration.message.ConfigMessage; import cc.carm.lib.easyplugin.configuration.message.ConfigMessage;
import cc.carm.lib.easyplugin.configuration.message.ConfigMessageList; import cc.carm.lib.easyplugin.configuration.message.ConfigMessageList;
import cc.carm.lib.easyplugin.configuration.values.ConfigValue; import cc.carm.lib.easyplugin.configuration.values.ConfigValue;
import cc.carm.plugin.ultradepository.manager.ConfigManager; import cc.carm.plugin.ultradepository.manager.ConfigManager;
import cc.carm.plugin.ultradepository.storage.StorageMethod; import cc.carm.plugin.ultradepository.storage.StorageMethod;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Sound;
public class PluginConfig { public class PluginConfig {
@@ -19,6 +21,10 @@ public class PluginConfig {
"metrics", Boolean.class, true "metrics", Boolean.class, true
); );
public static final ConfigValue<Boolean> CHECK_UPDATE = new ConfigValue<>(
"check-update", Boolean.class, true
);
public static final ConfigStringCast<StorageMethod> STORAGE_METHOD = new ConfigStringCast<>( public static final ConfigStringCast<StorageMethod> STORAGE_METHOD = new ConfigStringCast<>(
"storage.method", StorageMethod::read, StorageMethod.YAML "storage.method", StorageMethod::read, StorageMethod.YAML
); );
@@ -44,7 +50,8 @@ public class PluginConfig {
public static class Sounds { public static class Sounds {
public static final ConfigSound COLLECT = new ConfigSound("sounds.collect"); public static final ConfigSound COLLECT = new ConfigSound("sounds.collect", Sound.ENTITY_VILLAGER_CELEBRATE);
public static final ConfigSound TAKEOUT = new ConfigSound("sounds.collect");
public static final ConfigSound SELL_SUCCESS = new ConfigSound("sounds.sell-success"); public static final ConfigSound SELL_SUCCESS = new ConfigSound("sounds.sell-success");
public static final ConfigSound SELL_FAIL = new ConfigSound("sounds.sell-fail"); public static final ConfigSound SELL_FAIL = new ConfigSound("sounds.sell-fail");
public static final ConfigSound GUI_CLICK = new ConfigSound("sounds.gui-click"); public static final ConfigSound GUI_CLICK = new ConfigSound("sounds.gui-click");
@@ -54,22 +61,53 @@ public class PluginConfig {
* 通用配置 * 通用配置
*/ */
public static class General { public static class General {
/** /**
* 针对每一件物品的额外介绍 * 针对每一件物品的额外介绍
* 将添加到背包界面内的物品上,避免重复配置 * 将添加到背包界面内的物品上,避免重复配置
*/ */
public static final ConfigMessageList ADDITIONAL_LORE = new ConfigMessageList( public static class AdditionalLore {
ConfigManager.getPluginConfig(), "general.additional-lore", new String[]{},
new String[]{ public static final ConfigMessageList AVAILABLE_FOR_SALE = new ConfigMessageList(
"%(item_name)", "%(amount)", "%(price)", "%(sold)", "%(remain)", "%(limit)" ConfigManager::getPluginConfig, "general.additional-lore.available-for-sale",
}); new String[]{},
new String[]{
"%(item_name)", "%(amount)", "%(price)", "%(sold)", "%(remain)", "%(limit)"
});
public static final ConfigMessageList NOT_FOR_SALE = new ConfigMessageList(
ConfigManager::getPluginConfig, "general.additional-lore.not-for-sale",
new String[]{}, new String[]{
"%(item_name)", "%(amount)"
});
}
/** /**
* 提示玩家点击行为的介绍 * 提示玩家点击行为的介绍
* 将添加到背包界面内的物品上,避免重复配置 * 将添加到背包界面内的物品上,避免重复配置
*/ */
public static class ClickLore {
public static final ConfigMessageList AVAILABLE_FOR_SALE = new ConfigMessageList(
ConfigManager::getPluginConfig,
"general.click-lore.available-for-sale",
new String[]{}, new String[]{
"%(item_name)", "%(amount)", "%(price)"
});
public static final ConfigMessageList NOT_FOR_SALE = new ConfigMessageList(
ConfigManager::getPluginConfig, "general.click-lore.not-for-sale",
new String[]{},
new String[]{
"%(item_name)", "%(amount)"
});
}
public static final ConfigMessageList CLICK_LORE = new ConfigMessageList( public static final ConfigMessageList CLICK_LORE = new ConfigMessageList(
ConfigManager.getPluginConfig(), "general.click-lore", new String[]{}, new String[]{ ConfigManager::getPluginConfig,
"general.click-lore",
new String[]{}, new String[]{
"%(item_name)", "%(amount)", "%(price)" "%(item_name)", "%(amount)", "%(price)"
}); });
@@ -80,7 +118,8 @@ public class PluginConfig {
public static final ConfigMessage TITLE = new ConfigMessage( public static final ConfigMessage TITLE = new ConfigMessage(
ConfigManager.getPluginConfig(), "general.sell-gui.title", ConfigManager::getPluginConfig,
"general.sell-gui.title",
"&a&l出售", new String[]{ "&a&l出售", new String[]{
"%(item_name)", "%(backpack_name)" "%(item_name)", "%(backpack_name)"
} }
@@ -88,124 +127,32 @@ public class PluginConfig {
public static class Items { public static class Items {
public static class Add { public static final ConfigItem ADD = new ConfigItem(
"general.sell-gui.items.add",
new String[]{"%(item_name)", "%(amount)"},
ConfigItem.create(Material.GREEN_STAINED_GLASS_PANE, "&a添加物品 %(amount) 个")
);
public static final ConfigStringCast<Material> TYPE = new ConfigStringCast<>( public static final ConfigItem REMOVE = new ConfigItem(
"general.sell-gui.items.add.type", "general.sell-gui.items.remove",
Material::matchMaterial, Material.STONE new String[]{"%(item_name)", "%(amount)"},
); ConfigItem.create(Material.RED_STAINED_GLASS_PANE, "&c減少物品 %(amount) 个")
);
public static final ConfigItem CONFIRM = new ConfigItem(
"general.sell-gui.items.confirm",
new String[]{"%(item_name)", "%(amount)", "%(money)"},
ConfigItem.create(Material.EMERALD, "&2确认售出")
);
public static final ConfigValue<Integer> DATA = new ConfigValue<>( public static final ConfigItem CANCEL = new ConfigItem(
"general.sell-gui.items.add.data", Integer.class, 0 "general.sell-gui.items.cancel",
); ConfigItem.create(Material.REDSTONE, "&4取消售出")
);
public static final ConfigMessage NAME = new ConfigMessage(
ConfigManager.getPluginConfig(), "general.sell-gui.items.add.name",
"&a添加物品 %(amount) 个", new String[]{
"%(item_name)", "%(amount)"
}
);
public static final ConfigMessageList LORE = new ConfigMessageList(
ConfigManager.getPluginConfig(), "general.sell-gui.items.add.lore",
new String[]{}, new String[]{
"%(item_name)", "%(amount)"
}
);
}
public static class Remove {
public static final ConfigStringCast<Material> TYPE = new ConfigStringCast<>(
"general.sell-gui.items.remove.type",
Material::matchMaterial, Material.STONE
);
public static final ConfigValue<Integer> DATA = new ConfigValue<>(
"general.sell-gui.items.remove.data", Integer.class, 0
);
public static final ConfigMessage NAME = new ConfigMessage(
ConfigManager.getPluginConfig(), "general.sell-gui.items.remove.name",
"&c減少物品 %(amount) 个", new String[]{
"%(item_name)", "%(amount)"
}
);
public static final ConfigMessageList LORE = new ConfigMessageList(
ConfigManager.getPluginConfig(), "general.sell-gui.items.remove.lore",
new String[]{}, new String[]{
"%(item_name)", "%(amount)"
}
);
}
public static class Confirm {
public static final ConfigStringCast<Material> TYPE = new ConfigStringCast<>(
"general.sell-gui.items.confirm.type",
Material::matchMaterial, Material.EMERALD
);
public static final ConfigValue<Integer> DATA = new ConfigValue<>(
"general.sell-gui.items.confirm.data", Integer.class, 0
);
public static final ConfigMessage NAME = new ConfigMessage(
ConfigManager.getPluginConfig(), "general.sell-gui.items.confirm.name",
"&2确认售出", new String[]{
"%(item_name)", "%(amount)", "%(money)"
}
);
public static final ConfigMessageList LORE = new ConfigMessageList(
ConfigManager.getPluginConfig(), "general.sell-gui.items.confirm.lore",
new String[]{}, new String[]{
"%(item_name)", "%(amount)", "%(money)"
}
);
}
public static class Cancel {
public static final ConfigStringCast<Material> TYPE = new ConfigStringCast<>(
"general.sell-gui.items.cancel.type",
Material::matchMaterial, Material.REDSTONE
);
public static final ConfigValue<Integer> DATA = new ConfigValue<>(
"general.sell-gui.items.cancel.data", Integer.class, 0
);
public static final ConfigMessage NAME = new ConfigMessage(
ConfigManager.getPluginConfig(), "general.sell-gui.items.cancel.name",
"&4取消售出", null
);
public static final ConfigMessageList LORE = new ConfigMessageList(
ConfigManager.getPluginConfig(), "general.sell-gui.items.cancel.lore", new String[0], new String[0]
);
}
} }
} }
} }
} }
@@ -1,46 +1,102 @@
package cc.carm.plugin.ultradepository.configuration; package cc.carm.plugin.ultradepository.configuration;
import cc.carm.lib.easyplugin.configuration.message.ConfigMessageList; import cc.carm.lib.easyplugin.configuration.language.EasyMessage;
import cc.carm.lib.easyplugin.configuration.language.EasyMessageList;
import cc.carm.lib.easyplugin.configuration.language.MessagesRoot;
import cc.carm.lib.easyplugin.configuration.language.MessagesSection;
public class PluginMessages { public class PluginMessages extends MessagesRoot {
public static final ConfigMessageList HELP_CONSOLE = new ConfigMessageList("help.console"); @MessagesSection("help")
public static class Usages {
public static final ConfigMessageList HELP_PLAYER = new ConfigMessageList("help.player"); public static final EasyMessageList CONSOLE = new EasyMessageList(
"&6&l超级仓库 &f后台指令帮助",
"&8#&f info &6<玩家> &e[仓库ID] &e[物品ID]",
"&8-&7 得到玩家的相关物品信息。",
"&8#&f add &6<玩家> &6<仓库ID> &6<物品ID> &6<数量>",
"&8-&7 为玩家添加对应仓库中对于物品的数量。",
"&8#&f remove &6<玩家> &6<仓库ID> &6<物品ID> &e[数量]",
"&8-&7 为玩家减少对应仓库中对于物品的数量。",
"&8-&7 若不填写数量,则清空对应仓库的对应物品。",
"&8#&f sell &6<玩家> &e[仓库ID] &e[物品ID] &e[数量]",
"&8-&7 为玩家售出相关物品。",
"&8-&7 若不填写数量,则售出所有对应仓库的对应物品。",
"&8-&7 若不填写物品,则售出对应仓库内所有物品。",
"&8-&7 若不填写仓库,则售出所有仓库内所有物品。",
"&8-&7 该指令受到玩家每日售出数量的限制。"
);
public static final EasyMessageList PLAYER = new EasyMessageList(
"&6&l超级仓库 &f玩家指令帮助",
"&8#&f open &e[仓库ID]",
"&8-&7 打开对应仓库的界面。",
"&8#&f sell &6<仓库ID> &6<物品ID> &6<数量>",
"&8-&7 售出对应数量的对应物品。",
"&8-&7 该指令受到玩家每日售出数量的限制。",
"&8#&f sellAll &e[仓库ID] &e[物品ID]",
"&8-&7 该指令受到玩家每日售出数量的限制。"
);
public static final ConfigMessageList SOLD = new ConfigMessageList( }
"item-sold", new String[0], new String[]{
"%(item)", "%(amount)", "%(money)"
});
public static final ConfigMessageList PICKUP = new ConfigMessageList( public static final EasyMessageList ITEM_SOLD = new EasyMessageList(
"item-pickup", new String[0], new String[]{ new String[]{"&f您出售了 &r%(item)&7x%(amount) &f,共赚取 &6%(money) &f元。"},
"%(item)", "%(amount)" new String[]{"%(item)", "%(amount)", "%(money)"}
}); );
public static final ConfigMessageList COLLECTED = new ConfigMessageList( public static final EasyMessageList ITEM_SOLD_LIMIT = new EasyMessageList(
"item-collected", new String[0], new String[]{ new String[]{"&f该物品今日剩余可出售额度为 &a%(amount)&8/%(limit) &f个。"},
"%(item)", "%(amount)", "%(depository)" new String[]{"%(amount)", "%(limit)"}
}); );
public static final EasyMessageList ITEM_PICKUP = new EasyMessageList(
new String[]{"&f您拾取了 &r%(item)&7x%(amount) &f,已自动放入到您的仓库中。"},
new String[]{"%(item)", "%(amount)"}
);
public static final ConfigMessageList NO_ECONOMY = new ConfigMessageList("no-economy"); public static final EasyMessageList ITEM_TAKEOUT = new EasyMessageList(
new String[]{"&f您从仓库中拿取了 &r%(item)&7x%(amount) &f放入到您的背包中。"},
new String[]{"%(item)", "%(amount)"}
);
public static final ConfigMessageList NO_SPACE = new ConfigMessageList("no-space"); public static final EasyMessageList ITEM_COLLECT = new EasyMessageList(
new String[]{"&f您收集了 &r%(item)&7x%(amount) &f,已自动放入到您的 &6%(depository) &f中。"},
new String[]{"%(item)", "%(amount)", "%(depository)"}
);
public static final ConfigMessageList NO_DEPOSITORY = new ConfigMessageList("no-depository"); public static final EasyMessage ITEM_COLLECT_ACTIONBAR = new EasyMessage(
"&r%(item)&7x%(amount) &f-> &6%(depository)",
new String[]{"%(item)", "%(amount)", "%(depository)"}
);
public static final ConfigMessageList NO_ITEM = new ConfigMessageList("no-item"); public static final EasyMessageList NO_SPACE = new EasyMessageList(
"&f您背包内没有足够的空间取出物品!"
);
public static final ConfigMessageList NO_ENOUGH_ITEM = new ConfigMessageList("no-enough-item"); public static final EasyMessageList NO_ECONOMY = new EasyMessageList(
"&f本服务器暂未启用出售功能。"
);
public static final EasyMessageList NO_DEPOSITORY = new EasyMessageList(
"&f不存在该仓库,请检查仓库ID是否正确。"
);
public static final ConfigMessageList ITEM_SOLD_LIMIT = new ConfigMessageList( public static final EasyMessageList NO_ITEM = new EasyMessageList(
"item-sold-limit", new String[0], new String[]{ "&f仓库中不存在该物品,请检查物品ID是否正确。"
"%(amount)", "%(limit)" );
});
public static final EasyMessageList NO_ENOUGH_ITEM = new EasyMessageList(
"&f仓库中不存在足够的物品。"
);
public static final EasyMessageList WRONG_NUMBER = new EasyMessageList(
"&f数目输入错误,请输入正确的数字!"
);
public static final EasyMessage LOAD_FAILED = new EasyMessage(
"&c您的背包数据未被正确加载,请重新进入!"
);
public static final ConfigMessageList WRONG_NUMBER = new ConfigMessageList("wrong-number");
} }
@@ -42,10 +42,21 @@ public class DepositoryCapacity {
} }
public int getPlayerCapacity(Player player) { public int getPlayerCapacity(Player player) {
return getPermissions().entrySet().stream() if (defaultCapacity == -1) return -1;
.filter(entry -> player.hasPermission(entry.getKey()))
.mapToInt(Map.Entry::getValue) int capacity = defaultCapacity;
.max().orElse(defaultCapacity); for (Map.Entry<String, Integer> entry : getPermissions().entrySet()) {
if (player.hasPermission(entry.getKey())) {
int value = entry.getValue();
if (value == -1) {
return -1;
} else if (value > capacity) {
capacity = value;
}
}
}
return capacity;
} }
} }
@@ -116,8 +116,8 @@ public class DepositoryItem {
return new DepositoryItem( return new DepositoryItem(
depository, material, data, depository, material, data,
section.getInt("slot", 0), section.getInt("slot", 0),
section.getDouble("price", 0), section.getDouble("price", -1),
section.getInt("limit", 0), section.getInt("limit", -1),
section.getString("name", material.name()), section.getString("name", material.name()),
section.getStringList("lore") section.getStringList("lore")
); );
@@ -117,7 +117,7 @@ public class UserData {
public Date getDate() { public Date getDate() {
return new Date(DateIntUtil.getDateMillis(getDateInt())); return DateIntUtil.getDate(getDateInt());
} }
public int getDateInt() { public int getDateInt() {
@@ -19,7 +19,7 @@ public class PAPIExpansion extends PlaceholderExpansion {
"%UltraDepository_amount_<BackpackID>_<ItemTypeID>%", "%UltraDepository_amount_<BackpackID>_<ItemTypeID>%",
"%UltraDepository_sold_<BackpackID>_<ItemTypeID>%", "%UltraDepository_sold_<BackpackID>_<ItemTypeID>%",
"%UltraDepository_price_<BackpackID>_<ItemTypeID>%", "%UltraDepository_price_<BackpackID>_<ItemTypeID>%",
"%UltraDepository_reUltraDepository_<BackpackID>_<ItemTypeID>%", "%UltraDepository_remain_<BackpackID>_<ItemTypeID>%",
"%UltraDepository_capacity_<BackpackID>%", "%UltraDepository_capacity_<BackpackID>%",
"%UltraDepository_used_<BackpackID>%", "%UltraDepository_used_<BackpackID>%",
"%UltraDepository_usable_<BackpackID>%" "%UltraDepository_usable_<BackpackID>%"
@@ -80,7 +80,7 @@ public class PAPIExpansion extends PlaceholderExpansion {
if (sold == null) return "Depository or Item not exists"; if (sold == null) return "Depository or Item not exists";
else return sold.toString(); else return sold.toString();
} }
case "reUltraDepository": { case "remain": {
if (args.length < 2) return "Error Params"; if (args.length < 2) return "Error Params";
Depository depository = UltraDepository.getDepositoryManager().getDepository(args[1]); Depository depository = UltraDepository.getDepositoryManager().getDepository(args[1]);
if (depository == null) return "Depository not exists"; if (depository == null) return "Depository not exists";
@@ -106,7 +106,8 @@ public class PAPIExpansion extends PlaceholderExpansion {
if (args.length < 2) return "Error Params"; if (args.length < 2) return "Error Params";
Depository depository = UltraDepository.getDepositoryManager().getDepository(args[1]); Depository depository = UltraDepository.getDepositoryManager().getDepository(args[1]);
if (depository == null) return "Depository not exists"; if (depository == null) return "Depository not exists";
return Integer.toString(depository.getCapacity().getPlayerCapacity(player)); int capacity = depository.getCapacity().getPlayerCapacity(player);
return capacity < 0 ? "" : Integer.toString(capacity);
} }
case "used": { case "used": {
if (args.length < 2) return "Error Params"; if (args.length < 2) return "Error Params";
@@ -118,8 +119,9 @@ public class PAPIExpansion extends PlaceholderExpansion {
if (args.length < 2) return "Error Params"; if (args.length < 2) return "Error Params";
Depository depository = UltraDepository.getDepositoryManager().getDepository(args[1]); Depository depository = UltraDepository.getDepositoryManager().getDepository(args[1]);
if (depository == null) return "Depository not exists"; if (depository == null) return "Depository not exists";
int max = depository.getCapacity().getPlayerCapacity(player);
int used = data.getDepositoryData(depository).getUsedCapacity(); int used = data.getDepositoryData(depository).getUsedCapacity();
return Integer.toString(depository.getCapacity().getPlayerCapacity(player) - used); return max < 0 ? "" : Integer.toString(max - used);
} }
case "version": { case "version": {
return getVersion(); return getVersion();
@@ -0,0 +1,46 @@
package cc.carm.plugin.ultradepository.hooker;
import cc.carm.lib.githubreleases4j.GithubRelease;
import cc.carm.lib.githubreleases4j.GithubReleases4J;
import cc.carm.plugin.ultradepository.UltraDepository;
import java.util.List;
public class UpdateChecker {
public static void checkUpdate(UltraDepository plugin) {
plugin.getScheduler().runAsync(() -> {
try {
List<GithubRelease> releases = GithubReleases4J.listReleases("CarmJos", "UltraDepository");
if (releases.isEmpty()) throw new NullPointerException(); // 无法获取更新
String currentVersion = plugin.getDescription().getVersion();
int i = 0;
for (GithubRelease release : releases) {
if (release.getTagName().equalsIgnoreCase(currentVersion)) {
break;
}
i++;
}
if (i > 0) {
GithubRelease latestRelease = releases.get(0);
plugin.log("检查更新完成,当前已落后 " + i + " 个版本,最新版本为 &6&l" + latestRelease.getTagName() + " &r。");
plugin.log("最新版本下载地址&e " + latestRelease.getHTMLUrl());
} else {
plugin.log("检查更新完成,当前已是最新版本。");
}
} catch (Exception exception) {
plugin.error("检查更新失败,请您定期查看插件是否更新,避免安全问题。");
plugin.error("插件下载地址&e https://github.com/CarmJos/UltraDepository/releases");
}
});
}
}
@@ -1,6 +1,7 @@
package cc.carm.plugin.ultradepository.listener; package cc.carm.plugin.ultradepository.listener;
import cc.carm.plugin.ultradepository.UltraDepository; import cc.carm.plugin.ultradepository.UltraDepository;
import cc.carm.plugin.ultradepository.configuration.PluginMessages;
import cc.carm.plugin.ultradepository.data.UserData; import cc.carm.plugin.ultradepository.data.UserData;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@@ -19,15 +20,13 @@ public class UserListener implements Listener {
if (event.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) { if (event.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
return; return;
} }
UUID uuid = event.getUniqueId(); UltraDepository.getUserManager().loadDataCache(event.getUniqueId());
UltraDepository.getInstance().debug("尝试加载玩家 " + event.getName() + " 的数据...");
UltraDepository.getUserManager().getDataCache().put(uuid, UltraDepository.getUserManager().loadData(uuid));
} }
@EventHandler(priority = EventPriority.MONITOR) @EventHandler(priority = EventPriority.MONITOR)
public void onPreLoginMonitor(AsyncPlayerPreLoginEvent event) { public void onPreLoginMonitor(AsyncPlayerPreLoginEvent event) {
if (event.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) { if (event.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
UltraDepository.getUserManager().getDataCache().remove(event.getUniqueId()); UltraDepository.getUserManager().removeDataCache(event.getUniqueId());
} }
} }
@@ -36,7 +35,7 @@ public class UserListener implements Listener {
UserData data = UltraDepository.getUserManager().getData(e.getPlayer().getUniqueId()); UserData data = UltraDepository.getUserManager().getData(e.getPlayer().getUniqueId());
if (data == null) { if (data == null) {
e.setResult(PlayerLoginEvent.Result.KICK_OTHER); e.setResult(PlayerLoginEvent.Result.KICK_OTHER);
e.setKickMessage(UltraDepository.getInstance().getName() + " 数据未被正确加载,请重新进入。"); e.setKickMessage(PluginMessages.LOAD_FAILED.get(e.getPlayer()));
} }
} }
@@ -44,7 +43,8 @@ public class UserListener implements Listener {
public void onQuit(PlayerQuitEvent event) { public void onQuit(PlayerQuitEvent event) {
Player player = event.getPlayer(); Player player = event.getPlayer();
UUID playerUUID = player.getUniqueId(); UUID playerUUID = player.getUniqueId();
UltraDepository.getInstance().getScheduler().runAsync(() -> UltraDepository.getUserManager().unloadData(playerUUID, true)); UltraDepository.getInstance().getScheduler()
.runAsync(() -> UltraDepository.getUserManager().unloadData(playerUUID, true));
} }
} }
@@ -2,37 +2,75 @@ package cc.carm.plugin.ultradepository.manager;
import cc.carm.lib.easyplugin.configuration.file.FileConfig; import cc.carm.lib.easyplugin.configuration.file.FileConfig;
import cc.carm.lib.easyplugin.configuration.language.MessagesConfig;
import cc.carm.lib.easyplugin.configuration.language.MessagesInitializer;
import cc.carm.plugin.ultradepository.UltraDepository; import cc.carm.plugin.ultradepository.UltraDepository;
import cc.carm.plugin.ultradepository.configuration.PluginMessages;
import cc.carm.plugin.ultradepository.util.JarUtil;
import java.io.File;
public class ConfigManager { public class ConfigManager {
private static FileConfig pluginConfiguration; private static FileConfig pluginConfiguration;
private static FileConfig messageConfiguration; private static MessagesConfig messageConfiguration;
public static void initConfig() { public static boolean initialize() {
pluginConfiguration = new FileConfig(UltraDepository.getInstance(), "config.yml"); UltraDepository udPlugin = UltraDepository.getInstance();
messageConfiguration = new FileConfig(UltraDepository.getInstance(), "messages.yml");
FileConfig.pluginConfiguration = () -> pluginConfiguration;
FileConfig.messageConfiguration = () -> messageConfiguration; try {
File configFile = new File(udPlugin.getDataFolder(), "config.yml");
if (!configFile.exists()) {
//没找到配置文件,可能是第一次加载此插件
//把一些英文版的东西复制出来,方便英文用户使用。
UltraDepository.getInstance().log(" 未找到配置文件,生成默认配置...");
JarUtil.copyFolderFromJar(
"i18n", udPlugin.getDataFolder(),
JarUtil.CopyOption.COPY_IF_NOT_EXIST
);
}
pluginConfiguration = new FileConfig(udPlugin, "config.yml");
messageConfiguration = new MessagesConfig(udPlugin, "messages.yml");
FileConfig.pluginConfiguration = () -> pluginConfiguration;
FileConfig.messageConfiguration = () -> messageConfiguration;
MessagesInitializer.initialize(messageConfiguration, PluginMessages.class);
return true;
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
} }
public static FileConfig getPluginConfig() { public static FileConfig getPluginConfig() {
return pluginConfiguration; return pluginConfiguration;
} }
public static FileConfig getMessageConfig() { public static MessagesConfig getMessageConfig() {
return messageConfiguration; return messageConfiguration;
} }
public static void reload() { public static void reload() {
getPluginConfig().reload(); try {
getMessageConfig().reload(); getPluginConfig().reload();
getMessageConfig().reload();
} catch (Exception ex) {
ex.printStackTrace();
}
} }
public static void saveConfig() { public static void saveConfig() {
getPluginConfig().save(); try {
getMessageConfig().save(); getPluginConfig().save();
getMessageConfig().save();
} catch (Exception ex) {
ex.printStackTrace();
}
} }
} }
@@ -6,6 +6,7 @@ import cc.carm.plugin.ultradepository.configuration.PluginMessages;
import cc.carm.plugin.ultradepository.configuration.depository.Depository; import cc.carm.plugin.ultradepository.configuration.depository.Depository;
import cc.carm.plugin.ultradepository.configuration.depository.DepositoryItem; import cc.carm.plugin.ultradepository.configuration.depository.DepositoryItem;
import cc.carm.plugin.ultradepository.event.DepositoryCollectItemEvent; import cc.carm.plugin.ultradepository.event.DepositoryCollectItemEvent;
import cc.carm.plugin.ultradepository.util.JarUtil;
import com.google.common.collect.HashMultimap; import com.google.common.collect.HashMultimap;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
@@ -18,6 +19,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -45,6 +47,15 @@ public class DepositoryManager {
File folder = new File(UltraDepository.getInstance().getDataFolder(), "depositories"); File folder = new File(UltraDepository.getInstance().getDataFolder(), "depositories");
if (!folder.exists()) { if (!folder.exists()) {
folder.mkdir(); folder.mkdir();
try {
JarUtil.copyFolderFromJar(
"depositories", UltraDepository.getInstance().getDataFolder(),
JarUtil.CopyOption.COPY_IF_NOT_EXIST
);
} catch (IOException ignore) {
}
} else if (folder.isDirectory()) { } else if (folder.isDirectory()) {
folder.delete(); folder.delete();
folder.mkdir(); folder.mkdir();
@@ -56,7 +67,8 @@ public class DepositoryManager {
HashMap<@NotNull String, @NotNull Depository> data = new HashMap<>(); HashMap<@NotNull String, @NotNull Depository> data = new HashMap<>();
for (File file : files) { for (File file : files) {
String fileName = file.getName(); String fileName = file.getName();
if (!file.isFile() || !fileName.toLowerCase().endsWith(".yml")) continue; if (!file.isFile() || fileName.startsWith(".")) continue;
if (!fileName.toLowerCase().endsWith(".yml")) continue;
String identifier = fileName.substring(0, fileName.lastIndexOf(".")); String identifier = fileName.substring(0, fileName.lastIndexOf("."));
FileConfiguration configuration = YamlConfiguration.loadConfiguration(file); FileConfiguration configuration = YamlConfiguration.loadConfiguration(file);
Depository depository = Depository.loadFrom(identifier, configuration); Depository depository = Depository.loadFrom(identifier, configuration);
@@ -101,6 +113,7 @@ public class DepositoryManager {
return getDepositories().get(depositoryID); return getDepositories().get(depositoryID);
} }
@SuppressWarnings("deprecation")
public Set<Depository> getItemDepositories(ItemStack itemStack) { public Set<Depository> getItemDepositories(ItemStack itemStack) {
return getItemDepositories(itemStack.getType(), itemStack.getDurability()); return getItemDepositories(itemStack.getType(), itemStack.getDurability());
} }
@@ -115,7 +128,7 @@ public class DepositoryManager {
return getItemDepositories(itemStack).stream().filter(configuration -> { return getItemDepositories(itemStack).stream().filter(configuration -> {
int used = UltraDepository.getUserManager().getData(player).getDepositoryData(configuration).getUsedCapacity(); int used = UltraDepository.getUserManager().getData(player).getDepositoryData(configuration).getUsedCapacity();
int max = configuration.getCapacity().getPlayerCapacity(player); int max = configuration.getCapacity().getPlayerCapacity(player);
return used + itemStack.getAmount() <= max; return max < 0 || used + itemStack.getAmount() <= max;
}).collect(Collectors.toSet()); }).collect(Collectors.toSet());
} }
@@ -124,6 +137,7 @@ public class DepositoryManager {
else return material.name() + ":" + data; else return material.name() + ":" + data;
} }
@SuppressWarnings("deprecation")
public @NotNull String getItemTypeID(ItemStack itemStack) { public @NotNull String getItemTypeID(ItemStack itemStack) {
return getItemTypeID(itemStack.getType(), itemStack.getDurability()); return getItemTypeID(itemStack.getType(), itemStack.getDurability());
} }
@@ -165,11 +179,19 @@ public class DepositoryManager {
int finalAmount = collectItemEvent.getItemAmount(); int finalAmount = collectItemEvent.getItemAmount();
collectItemEvent.getUserData().addItemAmount(depository.getIdentifier(), typeID, finalAmount); collectItemEvent.getUserData().addItemAmount(depository.getIdentifier(), typeID, finalAmount);
PluginMessages.COLLECTED.send(player, new Object[]{ if (!player.hasPermission("UltraDepository.silent")) {
depository.getItems().get(typeID).getName(), PluginMessages.ITEM_COLLECT.send(player, new Object[]{
finalAmount, depository.getName() depository.getItems().get(typeID).getName(),
}); finalAmount, depository.getName()
PluginConfig.Sounds.COLLECT.play(player); });
PluginConfig.Sounds.COLLECT.play(player);
PluginMessages.ITEM_COLLECT_ACTIONBAR.sendBar(player, new Object[]{
depository.getItems().get(typeID).getName(),
finalAmount, depository.getName()
}); // Support action bar
}
UltraDepository.getInstance().debug("Item collected successfully."); UltraDepository.getInstance().debug("Item collected successfully.");
return true; return true;
} }
@@ -12,6 +12,9 @@ import cc.carm.plugin.ultradepository.hooker.VaultHooker;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class EconomyManager { public class EconomyManager {
VaultHooker hooker; VaultHooker hooker;
@@ -35,9 +38,9 @@ public class EconomyManager {
public double sell(Player player, double price, int amount) { public double sell(Player player, double price, int amount) {
if (!isInitialized()) return 0D; if (!isInitialized()) return 0D;
double money = price * amount; BigDecimal money = BigDecimal.valueOf(price * amount).setScale(2, RoundingMode.DOWN);
getHooker().addMoney(player, money); getHooker().addMoney(player, money.doubleValue());
return money; return money.doubleValue();
} }
public void sellAllItem(Player player, UserData userData) { public void sellAllItem(Player player, UserData userData) {
@@ -86,7 +89,7 @@ public class EconomyManager {
player, depositoryItem, changes[0] + amount, changes[0], money player, depositoryItem, changes[0] + amount, changes[0], money
)); ));
PluginMessages.SOLD.send(player, new Object[]{depositoryItem.getName(), amount, money}); PluginMessages.ITEM_SOLD.send(player, new Object[]{depositoryItem.getName(), amount, money});
if (playSound) PluginConfig.Sounds.SELL_SUCCESS.play(player); if (playSound) PluginConfig.Sounds.SELL_SUCCESS.play(player);
} }
@@ -4,6 +4,7 @@ import cc.carm.plugin.ultradepository.UltraDepository;
import cc.carm.plugin.ultradepository.data.UserData; import cc.carm.plugin.ultradepository.data.UserData;
import cc.carm.plugin.ultradepository.storage.DataStorage; import cc.carm.plugin.ultradepository.storage.DataStorage;
import cc.carm.plugin.ultradepository.util.DateIntUtil; import cc.carm.plugin.ultradepository.util.DateIntUtil;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -20,6 +21,27 @@ public class UserManager {
return dataCache; return dataCache;
} }
public void loadPlayersData() {
if (Bukkit.getOnlinePlayers().size() < 1) return;
UltraDepository.getInstance().log("加载当前在线玩家数据...");
// 用于热加载时重载玩家数据。
Bukkit.getOnlinePlayers().forEach(player -> loadDataCache(player.getUniqueId()));
}
public @NotNull UserData loadDataCache(@NotNull UUID userUUID) {
UserData data = loadData(userUUID);
UltraDepository.getUserManager().getDataCache().put(userUUID, data);
return data;
}
public boolean removeDataCache(@NotNull UUID userUUID) {
boolean contains = getDataCache().containsKey(userUUID);
getDataCache().remove(userUUID);
return contains;
}
public @Nullable UserData getData(@NotNull UUID userUUID) { public @Nullable UserData getData(@NotNull UUID userUUID) {
return getDataCache().get(userUUID); return getDataCache().get(userUUID);
} }
@@ -32,7 +54,7 @@ public class UserManager {
try { try {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
DataStorage storage = UltraDepository.getStorage(); DataStorage storage = UltraDepository.getStorage();
UltraDepository.getInstance().debug("正通过 " + storage.getClass().getSimpleName() + " 加载 " + userUUID + " 的用户数据..."); UltraDepository.getInstance().debug("正通过 " + storage.getClass().getSimpleName() + " 加载 " + userUUID + " 的用户数据...(" + System.currentTimeMillis() + ")");
UserData data = UltraDepository.getStorage().loadData(userUUID); UserData data = UltraDepository.getStorage().loadData(userUUID);
if (data == null) { if (data == null) {
@@ -56,7 +78,7 @@ public class UserManager {
UserData data = getData(uuid); UserData data = getData(uuid);
if (data == null) return; if (data == null) return;
if (save) saveData(data); if (save) saveData(data);
dataCache.remove(uuid); removeDataCache(uuid);
} }
public void saveData(UserData data) { public void saveData(UserData data) {
@@ -64,7 +86,7 @@ public class UserManager {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
DataStorage storage = UltraDepository.getStorage(); DataStorage storage = UltraDepository.getStorage();
UltraDepository.getInstance().debug("正通过 " + storage.getClass().getSimpleName() + " 保存 " + data.getUserUUID() + " 的用户数据..."); UltraDepository.getInstance().debug("正通过 " + storage.getClass().getSimpleName() + " 保存 " + data.getUserUUID() + " 的用户数据...(" + System.currentTimeMillis() + ")");
storage.saveUserData(data); storage.saveUserData(data);
UltraDepository.getInstance().debug("通过 " + storage.getClass().getSimpleName() + " 保存 " + data.getUserUUID() + " 的用户数据完成," + UltraDepository.getInstance().debug("通过 " + storage.getClass().getSimpleName() + " 保存 " + data.getUserUUID() + " 的用户数据完成," +
@@ -1,6 +1,7 @@
package cc.carm.plugin.ultradepository.storage; package cc.carm.plugin.ultradepository.storage;
import cc.carm.plugin.ultradepository.data.UserData; import cc.carm.plugin.ultradepository.data.UserData;
import cc.carm.plugin.ultradepository.manager.UserManager;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -8,14 +9,38 @@ import java.util.UUID;
public interface DataStorage { public interface DataStorage {
/**
* 在插件加载存储源时执行。
*
* @return 是否初始化成功
*/
boolean initialize(); boolean initialize();
/**
* 在插件被卸载时执行。
*/
void shutdown(); void shutdown();
/**
* 用于加载用户数据的方法。<b>该方法将会被异步运行!</b>
* <br>该方法一般无需自行执行,见 {@link UserManager#loadData(UUID)}
* <br>
* <br>若不存在该用户的数据,请返回 null 。
* <br>若加载出现任何错误,请抛出异常。
*
* @param uuid 用户UUID
* @throws Exception 当出现任何错误时抛出
*/
@Nullable @Nullable
UserData loadData(@NotNull UUID uuid) throws Exception; UserData loadData(@NotNull UUID uuid) throws Exception;
/**
* 用于保存用户数据的方法。 <b>该方法将会被异步运行!</b>
* <br>该方法一般无需自行执行,见 {@link UserManager#saveData(UserData)}
*
* @param data 用户数据
* @throws Exception 当出现任何错误时抛出
*/
void saveUserData(@NotNull UserData data) throws Exception; void saveUserData(@NotNull UserData data) throws Exception;
/** /**
@@ -27,7 +52,7 @@ public interface DataStorage {
* @return 正确ID数据 * @return 正确ID数据
* @since v1.1.6 * @since v1.1.6
*/ */
default String getFixedTypeID(String typeID) { static String getFixedTypeID(String typeID) {
String trueID = typeID; String trueID = typeID;
if (typeID.contains(":")) { if (typeID.contains(":")) {
try { try {
@@ -30,8 +30,8 @@ public class JSONStorage implements DataStorage {
private File dataContainer; private File dataContainer;
public static final Gson GSON = new Gson(); protected static final Gson GSON = new Gson();
public static final JsonParser PARSER = new JsonParser(); protected static final JsonParser PARSER = new JsonParser();
@Override @Override
public boolean initialize() { public boolean initialize() {
@@ -66,18 +66,9 @@ public class JSONStorage implements DataStorage {
JsonObject dataObject = dataElement.getAsJsonObject(); JsonObject dataObject = dataElement.getAsJsonObject();
int dateInt = dataObject.get("date").getAsInt(); int dateInt = dataObject.get("date").getAsInt();
JsonObject repositoriesObject = dataObject.getAsJsonObject("depositories");
UserData userData = new UserData(uuid, new HashMap<>(), dateInt); UserData userData = new UserData(uuid, new HashMap<>(), dateInt);
for (Map.Entry<String, JsonElement> entry : repositoriesObject.entrySet()) { loadDepositoriesInto(userData, dataObject.getAsJsonObject("depositories"));
Depository depository = UltraDepository.getDepositoryManager().getDepository(entry.getKey());
if (depository == null) continue;
DepositoryData contentsData = parseContentsData(depository, userData, entry.getValue());
if (contentsData != null) userData.setDepository(contentsData);
}
return userData; return userData;
} }
@@ -86,7 +77,7 @@ public class JSONStorage implements DataStorage {
public void saveUserData(@NotNull UserData data) throws Exception { public void saveUserData(@NotNull UserData data) throws Exception {
JsonObject dataObject = new JsonObject(); JsonObject dataObject = new JsonObject();
dataObject.addProperty("date", data.getDateInt()); dataObject.addProperty("date", data.getDateInt());
dataObject.add("depositories", GSON.toJsonTree(data.serializeToMap())); dataObject.add("depositories", saveDepositoriesToJson(data));
FileWriter writer = new FileWriter(new File(getDataContainer(), data.getUserUUID() + ".json")); FileWriter writer = new FileWriter(new File(getDataContainer(), data.getUserUUID() + ".json"));
writer.write(GSON.toJson(dataObject)); writer.write(GSON.toJson(dataObject));
@@ -94,18 +85,36 @@ public class JSONStorage implements DataStorage {
writer.close(); writer.close();
} }
protected DepositoryData parseContentsData(@NotNull Depository source, public static JsonElement saveDepositoriesToJson(UserData data) {
@NotNull UserData owner, return GSON.toJsonTree(data.serializeToMap());
@NotNull JsonElement contentsElement) {
return contentsElement.isJsonObject() ? parseContentsData(source, owner, contentsElement.getAsJsonObject()) : null;
} }
protected DepositoryData parseContentsData(@NotNull Depository source, public static String serializeDepositories(UserData data) {
@NotNull UserData owner, return GSON.toJson(saveDepositoriesToJson(data));
@NotNull JsonObject contentsObject) { }
public static void loadDepositoriesInto(UserData data, JsonElement depositoriesElement) {
if (depositoriesElement == null || !depositoriesElement.isJsonObject()) return;
for (Map.Entry<String, JsonElement> entry : depositoriesElement.getAsJsonObject().entrySet()) {
Depository depository = UltraDepository.getDepositoryManager().getDepository(entry.getKey());
if (depository == null) continue;
DepositoryData contentsData = parseContentsData(depository, data, entry.getValue());
if (contentsData != null) data.setDepository(contentsData);
}
}
public static DepositoryData parseContentsData(@NotNull Depository source,
@NotNull UserData owner,
@NotNull JsonElement contentsElement) {
if (!contentsElement.isJsonObject()) return null;
JsonObject contentsObject = contentsElement.getAsJsonObject();
DepositoryData data = DepositoryData.emptyContents(source, owner); DepositoryData data = DepositoryData.emptyContents(source, owner);
for (Map.Entry<String, JsonElement> entry : contentsObject.entrySet()) { for (Map.Entry<String, JsonElement> entry : contentsObject.entrySet()) {
DepositoryItem item = source.getItems().get(getFixedTypeID(entry.getKey())); DepositoryItem item = source.getItems().get(DataStorage.getFixedTypeID(entry.getKey()));
if (item == null) continue; if (item == null) continue;
DepositoryItemData itemData = parseItemData(item, data, entry.getValue()); DepositoryItemData itemData = parseItemData(item, data, entry.getValue());
@@ -115,15 +124,13 @@ public class JSONStorage implements DataStorage {
return data; return data;
} }
protected DepositoryItemData parseItemData(@NotNull DepositoryItem source,
@NotNull DepositoryData owner,
@NotNull JsonElement itemElement) {
return itemElement.isJsonObject() ? parseItemData(source, owner, itemElement.getAsJsonObject()) : null;
}
protected DepositoryItemData parseItemData(@NotNull DepositoryItem source, public static DepositoryItemData parseItemData(@NotNull DepositoryItem source,
@NotNull DepositoryData owner, @NotNull DepositoryData owner,
@NotNull JsonObject itemObject) { @NotNull JsonElement itemElement) {
if (!itemElement.isJsonObject()) return null;
JsonObject itemObject = itemElement.getAsJsonObject();
int amount = itemObject.has("amount") ? itemObject.get("amount").getAsInt() : 0; int amount = itemObject.has("amount") ? itemObject.get("amount").getAsInt() : 0;
int sold = itemObject.has("sold") ? itemObject.get("sold").getAsInt() : 0; int sold = itemObject.has("sold") ? itemObject.get("sold").getAsInt() : 0;
if (amount == 0 && sold == 0) return null; if (amount == 0 && sold == 0) return null;
@@ -5,16 +5,9 @@ import cc.carm.lib.easyplugin.database.DatabaseTable;
import cc.carm.lib.easyplugin.database.EasySQL; import cc.carm.lib.easyplugin.database.EasySQL;
import cc.carm.lib.easyplugin.database.api.SQLManager; import cc.carm.lib.easyplugin.database.api.SQLManager;
import cc.carm.lib.easyplugin.database.api.action.query.PreparedQueryAction; import cc.carm.lib.easyplugin.database.api.action.query.PreparedQueryAction;
import cc.carm.lib.easyplugin.database.api.action.query.SQLQuery;
import cc.carm.plugin.ultradepository.UltraDepository; import cc.carm.plugin.ultradepository.UltraDepository;
import cc.carm.plugin.ultradepository.configuration.PluginConfig;
import cc.carm.plugin.ultradepository.configuration.depository.Depository;
import cc.carm.plugin.ultradepository.data.DepositoryData;
import cc.carm.plugin.ultradepository.data.UserData; import cc.carm.plugin.ultradepository.data.UserData;
import cc.carm.plugin.ultradepository.util.DateIntUtil; import cc.carm.plugin.ultradepository.util.DateIntUtil;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -22,39 +15,37 @@ import java.sql.Date;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
public class MySQLStorage extends JSONStorage { public class MySQLStorage extends JSONStorage {
private static final ConfigValue<String> DRIVER_NAME = new ConfigValue<>( private static final ConfigValue<String> DRIVER_NAME = new ConfigValue<>(
"storage.mysql.driver", String.class, "com.mysql.jdbc.Driver" "storage.mysql.driver", String.class,
"com.mysql.jdbc.Driver"
); );
private static final ConfigValue<String> URL = new ConfigValue<>( private static final ConfigValue<String> URL = new ConfigValue<>(
"storage.mysql.url", String.class, "jdbc:mysql://127.0.0.1:3306/minecraft" "storage.mysql.url", String.class,
"jdbc:mysql://127.0.0.1:3306/minecraft"
); );
private static final ConfigValue<String> USERNAME = new ConfigValue<>( private static final ConfigValue<String> USERNAME = new ConfigValue<>(
"storage.mysql.username", String.class, "username" "storage.mysql.username", String.class,
"root"
); );
private static final ConfigValue<String> PASSWORD = new ConfigValue<>( private static final ConfigValue<String> PASSWORD = new ConfigValue<>(
"storage.mysql.password", String.class, "password" "storage.mysql.password", String.class,
"password"
); );
private static final DatabaseTable USER_TABLE = new DatabaseTable( private static final ConfigValue<String> TABLE_NAME = new ConfigValue<>(
"ub_data", "storage.mysql.table", String.class,
new String[]{ "ud_data"
"`uuid` VARCHAR(36) NOT NULL PRIMARY KEY", // 用户的UUID );
"`data` MEDIUMTEXT NOT NULL",// 背包内具体物品
"`day` DATE NOT NULL", // 记录卖出数量的所在天
});
public static final Gson GSON = new Gson();
public static final JsonParser PARSER = new JsonParser();
SQLManager sqlManager; SQLManager sqlManager;
DatabaseTable userDataTable;
@Override @Override
public boolean initialize() { public boolean initialize() {
@@ -62,7 +53,7 @@ public class MySQLStorage extends JSONStorage {
try { try {
UltraDepository.getInstance().log(" 尝试连接到数据库..."); UltraDepository.getInstance().log(" 尝试连接到数据库...");
this.sqlManager = EasySQL.createManager(DRIVER_NAME.get(), URL.get(), USERNAME.get(), PASSWORD.get()); this.sqlManager = EasySQL.createManager(DRIVER_NAME.get(), URL.get(), USERNAME.get(), PASSWORD.get());
this.sqlManager.setDebugMode(PluginConfig.DEBUG.get()); this.sqlManager.setDebugMode(UltraDepository.getInstance().isDebugging());
} catch (Exception exception) { } catch (Exception exception) {
UltraDepository.getInstance().error("无法连接到数据库,请检查配置文件。"); UltraDepository.getInstance().error("无法连接到数据库,请检查配置文件。");
UltraDepository.getInstance().error("Could not connect to the database, please check the configuration."); UltraDepository.getInstance().error("Could not connect to the database, please check the configuration.");
@@ -72,7 +63,17 @@ public class MySQLStorage extends JSONStorage {
try { try {
UltraDepository.getInstance().log(" 创建插件所需表..."); UltraDepository.getInstance().log(" 创建插件所需表...");
USER_TABLE.createTable(sqlManager);
this.userDataTable = new DatabaseTable(
TABLE_NAME.getOptional().orElse("ud_data"),
new String[]{
"`uuid` VARCHAR(36) NOT NULL PRIMARY KEY", // 用户的UUID
"`data` MEDIUMTEXT NOT NULL",// 背包内具体物品
"`day` DATE NOT NULL", // 记录卖出数量的所在天
});
getUserDataTable().createTable(sqlManager);
} catch (SQLException exception) { } catch (SQLException exception) {
UltraDepository.getInstance().error("无法创建插件所需的表,请检查数据库权限。"); UltraDepository.getInstance().error("无法创建插件所需的表,请检查数据库权限。");
UltraDepository.getInstance().error("Could not create necessary tables, please check the database privileges."); UltraDepository.getInstance().error("Could not create necessary tables, please check the database privileges.");
@@ -91,38 +92,25 @@ public class MySQLStorage extends JSONStorage {
@Override @Override
public @Nullable UserData loadData(@NotNull UUID uuid) throws Exception { public @Nullable UserData loadData(@NotNull UUID uuid) throws Exception {
try (SQLQuery query = createAction(uuid).execute()) { return createAction(uuid).executeFunction((query) -> {
ResultSet resultSet = query.getResultSet(); ResultSet resultSet = query.getResultSet();
if (resultSet == null || !resultSet.next()) return null; if (resultSet == null || !resultSet.next()) return null;
String dataJSON = resultSet.getString("data");
Date date = resultSet.getDate("day"); Date date = resultSet.getDate("day");
UserData data = new UserData(uuid, new HashMap<>(), DateIntUtil.getDateInt(date)); UserData data = new UserData(uuid, new HashMap<>(), DateIntUtil.getDateInt(date));
JsonElement dataElement = PARSER.parse(dataJSON); loadDepositoriesInto(data, PARSER.parse(resultSet.getString("data")));
if (dataElement.isJsonObject()) {
for (Map.Entry<String, JsonElement> entry : dataElement.getAsJsonObject().entrySet()) {
Depository depository = UltraDepository.getDepositoryManager().getDepository(entry.getKey());
if (depository == null) continue;
DepositoryData contentsData = parseContentsData(depository, data, entry.getValue());
if (contentsData != null) data.setDepository(contentsData);
}
}
return data; return data;
});
} catch (Exception exception) {
throw new Exception(exception);
}
} }
@Override @Override
public void saveUserData(@NotNull UserData data) throws Exception { public void saveUserData(@NotNull UserData data) throws Exception {
getSQLManager().createReplace(USER_TABLE.getTableName()) getSQLManager().createReplace(getUserDataTable().getTableName())
.setColumnNames("uuid", "data", "day") .setColumnNames("uuid", "data", "day")
.setParams(data.getUserUUID(), GSON.toJson(data.serializeToMap()), data.getDate()) .setParams(data.getUserUUID(), serializeDepositories(data), data.getDate())
.execute(); .execute();
} }
@@ -130,8 +118,12 @@ public class MySQLStorage extends JSONStorage {
return sqlManager; return sqlManager;
} }
public DatabaseTable getUserDataTable() {
return userDataTable;
}
private PreparedQueryAction createAction(UUID uuid) { private PreparedQueryAction createAction(UUID uuid) {
return USER_TABLE.createQuery(sqlManager) return getUserDataTable().createQuery(getSQLManager())
.addCondition("uuid", uuid.toString()) .addCondition("uuid", uuid.toString())
.setLimit(1).build(); .setLimit(1).build();
} }
@@ -73,7 +73,7 @@ public class YAMLStorage implements DataStorage {
for (String itemTypeID : depositorySection.getKeys(false)) { for (String itemTypeID : depositorySection.getKeys(false)) {
DepositoryItem item = depository.getItems().get(getFixedTypeID(itemTypeID)); DepositoryItem item = depository.getItems().get(DataStorage.getFixedTypeID(itemTypeID));
if (item == null) continue; if (item == null) continue;
ConfigurationSection itemSection = depositorySection.getConfigurationSection(itemTypeID); ConfigurationSection itemSection = depositorySection.getConfigurationSection(itemTypeID);
@@ -13,8 +13,10 @@ import cc.carm.plugin.ultradepository.data.UserData;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.IntStream; import java.util.stream.IntStream;
@@ -24,7 +26,7 @@ public class DepositoryGUI extends GUI {
UserData userData; UserData userData;
Depository depository; Depository depository;
public DepositoryGUI(Player player, Depository depository) { private DepositoryGUI(Player player, Depository depository) {
super(depository.getGUIConfiguration().getGUIType(), depository.getGUIConfiguration().getTitle()); super(depository.getGUIConfiguration().getGUIType(), depository.getGUIConfiguration().getTitle());
this.player = player; this.player = player;
@@ -35,51 +37,53 @@ public class DepositoryGUI extends GUI {
} }
public void setupItems() { public void setupItems() {
loadConfigItems();
loadDepositoryItems();
}
public void loadConfigItems() {
depository.getGUIConfiguration().setupItems(player, this); depository.getGUIConfiguration().setupItems(player, this);
}
public void loadDepositoryItems() {
depository.getItems().values().forEach(depositoryItem -> setItem(depositoryItem.getSlot(), createGUIItem(depositoryItem))); depository.getItems().values().forEach(depositoryItem -> setItem(depositoryItem.getSlot(), createGUIItem(depositoryItem)));
} }
private GUIItem createGUIItem(DepositoryItem item) { private GUIItem createGUIItem(DepositoryItem item) {
DepositoryItemData itemData = userData.getItemData(item); return new GUIItem(getItemIcon(player, userData, item)) {
int remain = item.getLimit() - itemData.getSold();
ItemStackFactory factory = new ItemStackFactory(item.getDisplayItem());
List<String> additionalLore = PluginConfig.General.ADDITIONAL_LORE.get(player, new Object[]{
item.getName(), itemData.getAmount(), item.getPrice(),
itemData.getSold(), remain, item.getLimit()
});
additionalLore.forEach(factory::addLore);
List<String> clickLore = PluginConfig.General.CLICK_LORE.get(player, new Object[]{
item.getName(), itemData.getAmount(), item.getPrice()
});
clickLore.forEach(factory::addLore);
return new GUIItem(factory.toItemStack()) {
@Override @Override
public void onClick(ClickType type) { public void onClick(ClickType type) {
DepositoryItemData itemData = userData.getItemData(item);
if (itemData.getAmount() < 1) { if (itemData.getAmount() < 1) {
PluginConfig.Sounds.SELL_FAIL.play(player);
PluginMessages.NO_ENOUGH_ITEM.send(player); PluginMessages.NO_ENOUGH_ITEM.send(player);
return; return;
} }
if (type == ClickType.LEFT) { if (canSell(item) && type == ClickType.LEFT) {
if (remain >= 1) { int sellableAmount = item.getLimit() - itemData.getSold();
if (sellableAmount >= 1) {
SellItemGUI.open(player, userData, itemData, depository, item); SellItemGUI.open(player, userData, itemData, depository, item);
} else { } else {
PluginMessages.ITEM_SOLD_LIMIT.send(player, new Object[]{remain, item.getLimit()}); PluginConfig.Sounds.SELL_FAIL.play(player);
PluginMessages.ITEM_SOLD_LIMIT.send(player, new Object[]{sellableAmount, item.getLimit()});
player.closeInventory();
} }
} else if (type == ClickType.RIGHT) { } else if (type == ClickType.RIGHT) {
if (hasEmptySlot(player)) { if (hasEmptySlot(player)) {
int pickupAmount = Math.min(itemData.getAmount(), item.getMaterial().getMaxStackSize()); int takeoutAmount = Math.min(itemData.getAmount(), item.getMaterial().getMaxStackSize());
userData.removeItemAmount(item.getDepository().getIdentifier(), item.getTypeID(), pickupAmount); userData.removeItemAmount(
player.getInventory().addItem(item.getRawItem(pickupAmount)); item.getDepository().getIdentifier(), item.getTypeID(), takeoutAmount
PluginMessages.PICKUP.send(player, new Object[]{ );
item.getName(), pickupAmount player.getInventory().addItem(item.getRawItem(takeoutAmount));
PluginMessages.ITEM_TAKEOUT.send(player, new Object[]{
item.getName(), takeoutAmount
}); });
setupItems(); //刷新GUI PluginConfig.Sounds.TAKEOUT.play(player);
setDisplay(getItemIcon(player, userData, item)); // 刷新物品显示
loadConfigItems(); // 更新配置中的其他物品
updateView(); updateView();
} else { } else {
PluginMessages.NO_SPACE.send(player); PluginMessages.NO_SPACE.send(player);
@@ -90,12 +94,51 @@ public class DepositoryGUI extends GUI {
}; };
} }
private boolean hasEmptySlot(Player player) { public static boolean hasEmptySlot(Player player) {
return IntStream.range(0, 36) return IntStream.range(0, 36)
.mapToObj(i -> player.getInventory().getItem(i)) .mapToObj(i -> player.getInventory().getItem(i))
.anyMatch(i -> i == null || i.getType() == Material.AIR); .anyMatch(i -> i == null || i.getType() == Material.AIR);
} }
public static ItemStack getItemIcon(@NotNull Player player,
@NotNull UserData userData,
@NotNull DepositoryItem item) {
DepositoryItemData itemData = userData.getItemData(item);
ItemStackFactory factory = new ItemStackFactory(item.getDisplayItem());
getExtraLore(player, itemData).forEach(factory::addLore);
return factory.toItemStack();
}
public static List<String> getExtraLore(@NotNull Player player,
@NotNull DepositoryItemData itemData) {
DepositoryItem item = itemData.getSource();
int canSell = item.getLimit() - itemData.getSold();
List<String> lore = new ArrayList<>();
if (canSell(item)) {
lore.addAll(PluginConfig.General.AdditionalLore.AVAILABLE_FOR_SALE.get(player, new Object[]{
item.getName(), itemData.getAmount(), item.getPrice(),
itemData.getSold(), canSell, item.getLimit()
}));
lore.addAll(PluginConfig.General.ClickLore.AVAILABLE_FOR_SALE.get(player, new Object[]{
item.getName(), itemData.getAmount(), item.getPrice()
}));
} else {
lore.addAll(PluginConfig.General.AdditionalLore.NOT_FOR_SALE.get(player, new Object[]{
item.getName(), itemData.getAmount()
}));
lore.addAll(PluginConfig.General.ClickLore.NOT_FOR_SALE.get(player, new Object[]{
item.getName(), itemData.getAmount()
}));
}
return lore;
}
public static boolean canSell(DepositoryItem item) {
return UltraDepository.getEconomyManager().isInitialized()
&& item.getLimit() > 0 && item.getPrice() > 0;
}
public static void open(@NotNull Player player, @NotNull Depository depository) { public static void open(@NotNull Player player, @NotNull Depository depository) {
player.closeInventory(); player.closeInventory();
DepositoryGUI gui = new DepositoryGUI(player, depository); DepositoryGUI gui = new DepositoryGUI(player, depository);
@@ -15,6 +15,8 @@ import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List; import java.util.List;
import static cc.carm.plugin.ultradepository.configuration.PluginConfig.General.SellGUI.Items.*; import static cc.carm.plugin.ultradepository.configuration.PluginConfig.General.SellGUI.Items.*;
@@ -51,10 +53,11 @@ public class SellItemGUI extends GUI {
private void load(int amount) { private void load(int amount) {
this.currentAmount = Math.max(1, amount); // 不可小于1 this.currentAmount = Math.max(1, amount); // 不可小于1
ItemStackFactory factory = new ItemStackFactory(this.itemDisplay); ItemStackFactory factory = new ItemStackFactory(this.itemDisplay);
List<String> additionalLore = PluginConfig.General.ADDITIONAL_LORE.get(player, new Object[]{ List<String> additionalLore = PluginConfig.General.AdditionalLore.AVAILABLE_FOR_SALE
getItemName(), getReUltraDepositoryAmount(), getItemPrice(), .get(player, new Object[]{
getSoldAmount(), (getSellLimit() - getSoldAmount()), getSellLimit() getItemName(), getDepositoryAmount(), getItemPrice(),
}); getSoldAmount(), (getSellLimit() - getSoldAmount()), getSellLimit()
});
additionalLore.forEach(factory::addLore); additionalLore.forEach(factory::addLore);
setItem(9, getCurrentAmount() > 1000 ? getRemoveItem(1000) : null); setItem(9, getCurrentAmount() > 1000 ? getRemoveItem(1000) : null);
@@ -67,22 +70,15 @@ public class SellItemGUI extends GUI {
setItem(16, getAddableAmount() >= 100 ? getAddItem(100) : null); setItem(16, getAddableAmount() >= 100 ? getAddItem(100) : null);
setItem(17, getAddableAmount() >= 1000 ? getAddItem(1000) : null); setItem(17, getAddableAmount() >= 1000 ? getAddItem(1000) : null);
if (getCurrentAmount() >= 1) setItem(getConfirmItem(), 27, 28, 29, 30); setItem(getCurrentAmount() >= 1 ? getConfirmItem() : null, 27, 28, 29, 30);
setItem(getCancelItem(), 32, 33, 34, 35); setItem(getCancelItem(), 32, 33, 34, 35);
} }
private GUIItem getAddItem(int amount) { private GUIItem getAddItem(int amount) {
ItemStackFactory factory = new ItemStackFactory(Add.TYPE.get()); return new GUIItem(ADD.getItem(player, new Object[]{
factory.setDurability(Add.DATA.get());
factory.setDisplayName(Add.NAME.get(player, new Object[]{
getItemName(), amount getItemName(), amount
})); })) {
factory.setLore(Add.LORE.get(player, new Object[]{
getItemName(), amount
}));
return new GUIItem(factory.toItemStack()) {
@Override @Override
public void onClick(ClickType type) { public void onClick(ClickType type) {
PluginConfig.Sounds.GUI_CLICK.play(player); PluginConfig.Sounds.GUI_CLICK.play(player);
@@ -93,15 +89,9 @@ public class SellItemGUI extends GUI {
} }
private GUIItem getRemoveItem(int amount) { private GUIItem getRemoveItem(int amount) {
ItemStackFactory factory = new ItemStackFactory(Remove.TYPE.get()); return new GUIItem(REMOVE.getItem(player, new Object[]{
factory.setDurability(Remove.DATA.get());
factory.setDisplayName(Remove.NAME.get(player, new Object[]{
getItemName(), amount getItemName(), amount
})); })) {
factory.setLore(Remove.LORE.get(player, new Object[]{
getItemName(), amount
}));
return new GUIItem(factory.toItemStack()) {
@Override @Override
public void onClick(ClickType type) { public void onClick(ClickType type) {
PluginConfig.Sounds.GUI_CLICK.play(player); PluginConfig.Sounds.GUI_CLICK.play(player);
@@ -112,18 +102,12 @@ public class SellItemGUI extends GUI {
} }
private GUIItem getConfirmItem() { private GUIItem getConfirmItem() {
ItemStackFactory factory = new ItemStackFactory(Confirm.TYPE.get()); return new GUIItem(CONFIRM.getItem(player, new Object[]{
factory.setDurability(Confirm.DATA.get());
factory.setDisplayName(Confirm.NAME.get(player, new Object[]{
getItemName(), getCurrentAmount(), getTotalMoney() getItemName(), getCurrentAmount(), getTotalMoney()
})); })) {
factory.setLore(Confirm.LORE.get(player, new Object[]{
getItemName(), getCurrentAmount(), getTotalMoney()
}));
return new GUIItem(factory.toItemStack()) {
@Override @Override
public void onClick(ClickType type) { public void onClick(ClickType type) {
int amount = Math.min(getCurrentAmount(), Math.min(getReUltraDepositoryAmount(), getSellLimit() - getSoldAmount())); int amount = Math.min(getCurrentAmount(), Math.min(getDepositoryAmount(), getSellLimit() - getSoldAmount()));
if (amount > 0) UltraDepository.getEconomyManager().sellItem(player, userData, item, amount); if (amount > 0) UltraDepository.getEconomyManager().sellItem(player, userData, item, amount);
player.closeInventory(); player.closeInventory();
} }
@@ -131,11 +115,7 @@ public class SellItemGUI extends GUI {
} }
private GUIItem getCancelItem() { private GUIItem getCancelItem() {
ItemStackFactory factory = new ItemStackFactory(Cancel.TYPE.get()); return new GUIItem(CANCEL.getItem(player)) {
factory.setDurability(Cancel.DATA.get());
factory.setDisplayName(Cancel.NAME.get());
factory.setLore(Cancel.LORE.get());
return new GUIItem(factory.toItemStack()) {
@Override @Override
public void onClick(ClickType type) { public void onClick(ClickType type) {
PluginConfig.Sounds.SELL_FAIL.play(player); PluginConfig.Sounds.SELL_FAIL.play(player);
@@ -161,10 +141,11 @@ public class SellItemGUI extends GUI {
} }
private double getTotalMoney() { private double getTotalMoney() {
return getCurrentAmount() * getItemPrice(); BigDecimal money = BigDecimal.valueOf(getCurrentAmount() * getItemPrice()).setScale(2, RoundingMode.DOWN);
return money.doubleValue();
} }
private int getReUltraDepositoryAmount() { private int getDepositoryAmount() {
return userData.getItemData(this.item).getAmount(); return userData.getItemData(this.item).getAmount();
} }
@@ -173,7 +154,7 @@ public class SellItemGUI extends GUI {
} }
private int getAddableAmount() { private int getAddableAmount() {
return Math.min(getReUltraDepositoryAmount(), getSellLimit() - getSoldAmount()) - getCurrentAmount(); return Math.min(getDepositoryAmount(), getSellLimit() - getSoldAmount()) - getCurrentAmount();
} }
public static void open(Player player, UserData userData, DepositoryItemData itemData, public static void open(Player player, UserData userData, DepositoryItemData itemData,
@@ -22,10 +22,15 @@ public class DateIntUtil {
} }
public static long getDateMillis(int dateInt) { public static long getDateMillis(int dateInt) {
return getDate(dateInt).getTime();
}
public static Date getDate(int dateInt) {
try { try {
return getFormat().parse(Integer.toString(dateInt)).getTime(); long millis = getFormat().parse(Integer.toString(dateInt)).getTime();
} catch (ParseException e) { return new java.sql.Date(millis);
return System.currentTimeMillis(); } catch (ParseException | NumberFormatException e) {
return new Date(System.currentTimeMillis());
} }
} }
@@ -0,0 +1,90 @@
package cc.carm.plugin.ultradepository.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@SuppressWarnings("ResultOfMethodCallIgnored")
public class JarUtil {
public static final char JAR_SEPARATOR = '/';
public static void copyFolderFromJar(String folderName, File destFolder, CopyOption option)
throws IOException {
copyFolderFromJar(folderName, destFolder, option, null);
}
public static void copyFolderFromJar(String folderName, File destFolder,
CopyOption option, PathTrimmer trimmer) throws IOException {
if (!destFolder.exists())
destFolder.mkdirs();
byte[] buffer = new byte[1024];
File fullPath;
String path = JarUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath();
if (trimmer != null)
path = trimmer.trim(path);
try {
if (!path.startsWith("file"))
path = "file://" + path;
fullPath = new File(new URI(path));
} catch (URISyntaxException e) {
e.printStackTrace();
return;
}
ZipInputStream zis = new ZipInputStream(new FileInputStream(fullPath));
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
if (!entry.getName().startsWith(folderName + JAR_SEPARATOR))
continue;
String fileName = entry.getName();
if (fileName.charAt(fileName.length() - 1) == JAR_SEPARATOR) {
File file = new File(destFolder + File.separator + fileName);
if (file.isFile()) {
file.delete();
}
file.mkdirs();
continue;
}
File file = new File(destFolder + File.separator + fileName);
if (option == CopyOption.COPY_IF_NOT_EXIST && file.exists())
continue;
if (!file.getParentFile().exists())
file.getParentFile().mkdirs();
if (!file.exists())
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
}
zis.closeEntry();
zis.close();
}
public enum CopyOption {
COPY_IF_NOT_EXIST, REPLACE_IF_EXIST
}
@FunctionalInterface
public interface PathTrimmer {
String trim(String original);
}
}
+31 -12
View File
@@ -7,10 +7,15 @@ version: ${project.version}
debug: false debug: false
# 统计数据设定 # 统计数据设定
# 选项用于帮助开发者统计插件版本与使用情况,且绝不会影响性能与使用体验。 # 选项用于帮助开发者统计插件版本与使用情况,且绝不会影响性能与使用体验。
# 当然,您也可以选择在这里关闭,或在plugins/bStats下的配置文件中关闭。 # 当然,您也可以选择在这里关闭,或在plugins/bStats下的配置文件中关闭。
metrics: true metrics: true
# 检查更新设定
# 该选项用于插件判断是否要检查更新,若您不希望插件检查更新并提示您,可以选择关闭。
# 检查更新为异步操作,绝不会影响性能与使用体验。
check-update: true
# 存储相关配置 # 存储相关配置
# 注意:存储配置不会通过重载指令生效,如有修改请重新启动服务器。 # 注意:存储配置不会通过重载指令生效,如有修改请重新启动服务器。
storage: storage:
@@ -20,7 +25,7 @@ storage:
# 选择 yaml/json 存储方式时的存储路径 # 选择 yaml/json 存储方式时的存储路径
# 默认为相对路径,相对于插件生成的配置文件夹下的路径 # 默认为相对路径,相对于插件生成的配置文件夹下的路径
# 支持绝对路径,如 “/var/data/ub/"(linux) 或 "D:\data\ub\"(windows) # 支持绝对路径,如 “/var/data/ud/"(linux) 或 "D:\data\ud\"(windows)
# 使用绝对路径时请注意权限问题 # 使用绝对路径时请注意权限问题
file-path: data file-path: data
@@ -29,6 +34,7 @@ storage:
# 数据库驱动路径 # 数据库驱动路径
driver: "com.mysql.jdbc.Driver" driver: "com.mysql.jdbc.Driver"
url: "jdbc:mysql://127.0.0.1:3306/<db-name>" url: "jdbc:mysql://127.0.0.1:3306/<db-name>"
table: "ud_data" # 插件表名,允许自定义
username: "username" username: "username"
password: "password" password: "password"
@@ -43,6 +49,7 @@ collect:
sounds: sounds:
collect: "ENTITY_EXPERIENCE_ORB_PICKUP:0.5" collect: "ENTITY_EXPERIENCE_ORB_PICKUP:0.5"
takeout: "ENTITY_HORSE_ARMOR:0.5"
sell-success: "ENTITY_VILLAGER_CELEBRATE" sell-success: "ENTITY_VILLAGER_CELEBRATE"
sell-fail: "ENTITY_VILLAGER_NO" sell-fail: "ENTITY_VILLAGER_NO"
gui-click: "UI_BUTTON_CLICK" gui-click: "UI_BUTTON_CLICK"
@@ -50,20 +57,34 @@ sounds:
# 通用配置 # 通用配置
general: general:
# 针对每一件物品的额外介绍 # 针对可出售物品的额外介绍
# 将添加到背包界面内的物品上,避免重复配置 # 将添加到背包界面内的物品上,避免重复配置
additional-lore: additional-lore:
- " " available-for-sale:
- "&f仓库内数量 &a%(amount)" # 可出售物品的介绍
- "&f该物品单价 &a%(price)" - " "
- "&f今日可出售 &a%(remain)&8/%(limit)" - "&f仓库内数量 &a%(amount)"
- "&f该物品单价 &a%(price)"
- "&f今日可出售 &a%(remain)&8/%(limit)"
not-for-sale:
# 针对不可出售的物品的额外介绍
# (当 未安装经济插件 或 每日可售出数量<=0 或 单价<=0 时判断为不可出售)
- " "
- "&f仓库内数量 &a%(amount)"
# 提示玩家点击行为的介绍 # 提示玩家点击行为的介绍
# 将添加到背包界面内的物品上,避免重复配置 # 将添加到背包界面内的物品上,避免重复配置
click-lore: click-lore:
- " " available-for-sale:
- "&a&l左键点击 &8| &f按量售出该物品" - " "
- "&a&l键点击 &8| &f取出一组该物品" - "&a&l键点击 &8| &f按量售出该物品"
- "&a&l右键点击 &8| &f取出一组该物品"
not-for-sale:
# 针对不可出售的物品的额外介绍
# (当 未安装经济插件 或 每日可售出数量<=0 或 单价<=0 时判断为不可出售)
- " "
- "&a&l右键点击 &8| &f取出一组该物品"
# 售出界面的配置 # 售出界面的配置
sell-gui: sell-gui:
@@ -77,7 +98,6 @@ general:
name: "&c减少 %(amount) 个" name: "&c减少 %(amount) 个"
confirm: confirm:
type: EMERALD type: EMERALD
data: 0
name: "&a确认售出" name: "&a确认售出"
lore: lore:
- " " - " "
@@ -87,7 +107,6 @@ general:
- "&a&l点击确认售出" - "&a&l点击确认售出"
cancel: cancel:
type: REDSTONE type: REDSTONE
data: 0
name: "&c取消售出" name: "&c取消售出"
lore: lore:
- " " - " "
@@ -0,0 +1,47 @@
name: "&b&lExample Depository" # 仓库名,用于消息显示
capacity: # 容量配置
default: 500 # 若为0则默认不可以使用该仓库
permissions: # 特殊权限对应的仓库容量,格式为 "权限:容量
- "UltraDepository.vip:1000"
- "UltraDepository.mvp:1500"
gui: # GUI额外配置
title: "&b&l示例仓库 &7| 界面" #示例仓库的GUI标题
lines: 4 # GUI的行数,支持 1-6行。
items:
"TEST":
material: CHEST # 物品图标的类型
data: 0 # 物品图标的数据值
slot: 31 # 在GUI中显示的格子
name: "&9&l测试图标"
lore:
# 支持使用变量
- "你好 %player_name% !"
actions: # 物品点击操作
- "[CHAT] Hello!" #以玩家身份发送Hello,支持PlaceholderAPI变量
- "[CHAT] /help" #若内容以"/"开头,则会以玩家身份执行指令,支持PlaceholderAPI变量
- "[CONSOLE] say HELLO WORLD" #以后台身份执行指令,不需要加"/",支持PlaceholderAPI变量
- "[MESSAGE] &(#FFBBBBB)Test %player_name%" # 向玩家发送消息,支持PlaceholderAPI变量和RGB颜色
- "[SOUND] ENTITY_EXPERIENCE_ORB_PICKUP:0.5" # 向玩家发送声音,可以规定音量大小和音调,格式为 <声音>:[音量]:[音调]
- "[CLOSE]" # 为玩家关闭界面
- "[LEFT:CLOSE]" #限制只有 鼠标左键 才触发CLOSE
- "[SHIFT_LEFT:CLOSE]" #限制只有 按住Shift+鼠标左键 才触发CLOSE
- "[RIGHT:CLOSE]" #限制只有 鼠标右键 才触发CLOSE
- "[SHIFT_RIGHT:CLOSE]" #限制只有 按住Shift+鼠标右键 才触发CLOSE
- "[MIDDLE:CLOSE]" #限制只有 鼠标中键 才触发CLOSE
- "[DROP:CLOSE]" #限制只有 丢弃建 才触发CLOSE
- "[CONTROL_DROP:CLOSE]" #限制只有 按住Ctrl+丢弃键 才触发CLOSE
- "[DOUBLE_CLICK:CLOSE]" #限制只有 鼠标双击物品 才触发CLOSE
- "[NUMBER_KEY:CLOSE]" #限制只有 数字键切换 才触发CLOSE
items:
"INK_SAC": #物品ID,若需要限制数据ID则可以加“:”,如 "INK_SANK:4"
slot: 11 # 物品在GUI中显示的槽位
price: 0.1 # 物品单价
limit: 500 # 物品每日售出限制
name: "&8&l墨囊" # 物品显示的名字
lore: # 物品的lore
- " "
- "&f抓住墨鱼!"
+110
View File
@@ -0,0 +1,110 @@
# ${project.name} - ${project.description}
# Source url: ${project.url}
# Download URL: ${project.distributionManagement.downloadUrl}
version: ${project.version}
debug: false
# bStats Metrics
# This option is used to help developers analysis plugin stats,
# and will never affect performance and user experience.
# You can choose to turn it off here.
metrics: true
# Storage Configuration
storage:
# Storage method
# You can choose [ yaml | json | mysql ]
method: yaml
# The storage file path when choosing "yaml"/"json" method.
# Support absolute paths, e.g. “/var/data/ud/"(linux) or "D:\data\ud\"(windows)
# **Be aware of permission issues when using absolute paths!**
file-path: data
# The Database configuration when choosing "mysql" method.
mysql:
driver: "com.mysql.jdbc.Driver"
url: "jdbc:mysql://127.0.0.1:3306/<db-name>"
table: "ud_data" # Plugin data table name, allowing customization
username: "username"
password: "password"
# Player Collect Configuration
# Used to determine when put the player's item into the backpack automatically
collect:
pickup: true # Pickup Items
kill: true # Kill Entities (Animals/Monsters)
break: true # Break Blocks
sounds:
collect: "ENTITY_EXPERIENCE_ORB_PICKUP:0.5"
sell-success: "ENTITY_VILLAGER_CELEBRATE"
sell-fail: "ENTITY_VILLAGER_NO"
gui-click: "UI_BUTTON_CLICK"
# General Configuration
general:
# Hints lore for the item's information
# Will add to items in BackpackGUI and SellGUI.
additional-lore:
available-for-sale:
- " "
- "&fAmount &a%(amount)"
- "&fPrice &a%(price)"
- "&fSold &a%(remain)&8/%(limit)"
not-for-sale:
# Display when :
# 1. Vault not installed
# 2. No economy plugins
# 3. daily sell limit <= 0
# 4. item price <=0
- " "
- "&fAmount &a%(amount)"
# Hints lore for the player's click
# Will add to items in BackpackGUI.
click-lore:
available-for-sale:
- " "
- "&a&lLEFT-CLICK &8| &fSell items"
- "&a&lRIGHT-CLICK &8| &fTake one Stack"
not-for-sale:
# Display when :
# 1. Vault not installed
# 2. No economy plugins
# 3. daily sell limit <= 0
# 4. item price <=0
- " "
- "&a&lRIGHT-CLICK &8| &fTake one Stack"
# Configuration of the SellGUI
sell-gui:
title: "&8Selling %(item_name)"
items:
add:
type: GREEN_STAINED_GLASS_PANE
name: "&aAdd %(amount)"
remove:
type: RED_STAINED_GLASS_PANE
name: "&cReduce %(amount)"
confirm:
type: EMERALD
name: "&a&lConfirm"
lore:
- " "
- "&7You will sell &r%(item_name) &8x &f%(amount)"
- "&7and will get $&e%(money) &7."
- " "
- "&a&lClick to confirm"
cancel:
type: REDSTONE
name: "&c&lCancel"
lore:
- " "
- "&cClick to cancel"
@@ -0,0 +1,48 @@
help:
console:
- '&6&l超级仓库 &f后台指令帮助'
- '&8#&f info &6<玩家> &e[仓库ID] &e[物品ID]'
- '&8-&7 得到玩家的相关物品信息。'
- '&8#&f add &6<玩家> &6<仓库ID> &6<物品ID> &6<数量>'
- '&8-&7 为玩家添加对应仓库中对于物品的数量。'
- '&8#&f remove &6<玩家> &6<仓库ID> &6<物品ID> &e[数量]'
- '&8-&7 为玩家减少对应仓库中对于物品的数量。'
- '&8-&7 若不填写数量,则清空对应仓库的对应物品。'
- '&8#&f sell &6<玩家> &e[仓库ID] &e[物品ID] &e[数量]'
- '&8-&7 为玩家售出相关物品。'
- '&8-&7 若不填写数量,则售出所有对应仓库的对应物品。'
- '&8-&7 若不填写物品,则售出对应仓库内所有物品。'
- '&8-&7 若不填写仓库,则售出所有仓库内所有物品。'
- '&8-&7 该指令受到玩家每日售出数量的限制。'
player:
- '&6&l超级仓库 &f玩家指令帮助'
- '&8#&f open &e[仓库ID]'
- '&8-&7 打开对应仓库的界面。'
- '&8#&f sell &6<仓库ID> &6<物品ID> &6<数量>'
- '&8-&7 售出对应数量的对应物品。'
- '&8-&7 该指令受到玩家每日售出数量的限制。'
- '&8#&f sellAll &e[仓库ID] &e[物品ID]'
- '&8-&7 该指令受到玩家每日售出数量的限制。'
item-sold:
- '&f您出售了 &r%(item)&7x%(amount) &f,共赚取 &6%(money) &f元。'
item-sold-limit:
- '&f该物品今日剩余可出售额度为 &a%(amount)&8/%(limit) &f个。'
item-pickup:
- '&f您拾取了 &r%(item)&7x%(amount) &f,已自动放入到您的仓库中。'
item-takeout:
- '&f您从仓库中拿取了 &r%(item)&7x%(amount) &f放入到您的背包中。'
item-collect:
- '&f您收集了 &r%(item)&7x%(amount) &f,已自动放入到您的 &6%(depository) &f中。'
item-collect-actionbar: '&r%(item)&7x%(amount) &f-> &6%(depository)'
no-space:
- '&f您背包内没有足够的空间取出物品!'
no-economy:
- '&f本服务器暂未启用出售功能。'
no-depository:
- '&f不存在该仓库,请检查仓库ID是否正确。'
no-item:
- '&f仓库中不存在该物品,请检查物品ID是否正确。'
no-enough-item:
- '&f仓库中不存在足够的物品。'
wrong-number:
- '&f数目输入错误,请输入正确的数字!'
@@ -0,0 +1,48 @@
name: "&b&l示例仓库" # 仓库名,用于消息显示
capacity: # 容量配置
default: 500 # 若为0则默认不可以使用该仓库
permissions: # 特殊权限对应的仓库容量,格式为 "权限:容量
- "UltraDepository.vip:1000"
- "UltraDepository.mvp:1500"
gui: # GUI额外配置
title: "&b&l示例仓库 &7| 界面" #示例仓库的GUI标题
lines: 4 # GUI的行数,支持 1-6行。
items:
"TEST":
material: CHEST # 物品图标的类型
data: 0 # 物品图标的数据值
slot: 31 # 在GUI中显示的格子
name: "&9&l测试图标"
lore:
# 支持使用变量
- "你好 %player_name% !"
actions: # 物品点击操作
- "[CHAT] Hello!" #以玩家身份发送Hello,支持PlaceholderAPI变量
- "[CHAT] /help" #若内容以"/"开头,则会以玩家身份执行指令,支持PlaceholderAPI变量
- "[CONSOLE] say HELLO WORLD" #以后台身份执行指令,不需要加"/",支持PlaceholderAPI变量
- "[MESSAGE] &(#FFBBBBB)Test %player_name%" # 向玩家发送消息,支持PlaceholderAPI变量和RGB颜色
- "[SOUND] ENTITY_EXPERIENCE_ORB_PICKUP:0.5" # 向玩家发送声音,可以规定音量大小和音调,格式为 <声音>:[音量]:[音调]
- "[CLOSE]" # 为玩家关闭界面
- "[LEFT:CLOSE]" #限制只有 鼠标左键 才触发CLOSE
- "[SHIFT_LEFT:CLOSE]" #限制只有 按住Shift+鼠标左键 才触发CLOSE
- "[RIGHT:CLOSE]" #限制只有 鼠标右键 才触发CLOSE
- "[SHIFT_RIGHT:CLOSE]" #限制只有 按住Shift+鼠标右键 才触发CLOSE
- "[MIDDLE:CLOSE]" #限制只有 鼠标中键 才触发CLOSE
- "[DROP:CLOSE]" #限制只有 丢弃建 才触发CLOSE
- "[CONTROL_DROP:CLOSE]" #限制只有 按住Ctrl+丢弃键 才触发CLOSE
- "[DOUBLE_CLICK:CLOSE]" #限制只有 鼠标双击物品 才触发CLOSE
- "[NUMBER_KEY:CLOSE]" #限制只有 数字键切换 才触发CLOSE
items:
"INK_SAC": #物品ID,若需要限制数据ID则可以加“:”,如 "INK_SANK:4"
slot: 11 # 物品在GUI中显示的槽位
price: 0.1 # 物品单价
limit: 500 # 物品每日售出限制
name: "&8&l墨囊" # 物品显示的名字
lore: # 物品的lore
- " "
- "&f抓住墨鱼!"
+109
View File
@@ -0,0 +1,109 @@
# ${project.name} - ${project.description}
# Source url: ${project.url}
# Download URL: ${project.distributionManagement.downloadUrl}
version: ${project.version}
debug: false
# bStats Metrics
# This option is used to help developers analysis plugin stats,
# and will never affect performance and user experience.
# You can choose to turn it off here.
metrics: true
# Storage Configuration
storage:
# Storage method
# You can choose [ yaml | json | mysql ]
method: yaml
# The storage file path when choosing "yaml"/"json" method.
# Support absolute paths, e.g. “/var/data/ud/"(linux) or "D:\data\ud\"(windows)
# **Be aware of permission issues when using absolute paths!**
file-path: data
# The Database configuration when choosing "mysql" method.
mysql:
driver: "com.mysql.jdbc.Driver"
url: "jdbc:mysql://127.0.0.1:3306/<db-name>"
table: "ud_data" # Plugin data table name, allowing customization
username: "username"
password: "password"
# Player Collect Configuration
# Used to determine when put the player's item into the backpack automatically
collect:
pickup: true # Pickup Items
kill: true # Kill Entities (Animals/Monsters)
break: true # Break Blocks
sounds:
collect: "ENTITY_EXPERIENCE_ORB_PICKUP:0.5"
sell-success: "ENTITY_VILLAGER_CELEBRATE"
sell-fail: "ENTITY_VILLAGER_NO"
gui-click: "UI_BUTTON_CLICK"
# General Configuration
general:
# Hints lore for the item's information
# Will add to items in BackpackGUI and SellGUI.
additional-lore:
available-for-sale:
- " "
- "&fAmount &a%(amount)"
- "&fPrice &a%(price)"
- "&fSold &a%(remain)&8/%(limit)"
not-for-sale:
# Display when :
# 1. Vault not installed
# 2. No economy plugins
# 3. daily sell limit <= 0
# 4. item price <=0
- " "
- "&fAmount &a%(amount)"
# Hints lore for the player's click
# Will add to items in BackpackGUI.
click-lore:
available-for-sale:
- " "
- "&a&lLEFT-CLICK &8| &fSell items"
- "&a&lRIGHT-CLICK &8| &fTake one Stack"
not-for-sale:
# Display when :
# 1. Vault not installed
# 2. No economy plugins
# 3. daily sell limit <= 0
# 4. item price <=0
- " "
- "&a&lRIGHT-CLICK &8| &fTake one Stack"
# Configuration of the SellGUI
sell-gui:
title: "&8Selling %(item_name)"
items:
add:
type: GREEN_STAINED_GLASS_PANE
name: "&aAdd %(amount)"
remove:
type: RED_STAINED_GLASS_PANE
name: "&cReduce %(amount)"
confirm:
type: EMERALD
name: "&a&lConfirm"
lore:
- " "
- "&7You will sell &r%(item_name) &8x &f%(amount)"
- "&7and will get $&e%(money) &7."
- " "
- "&a&lClick to confirm"
cancel:
type: REDSTONE
name: "&c&lCancel"
lore:
- " "
- "&cClick to cancel"
@@ -0,0 +1,48 @@
help:
console:
- '&6&l超级仓库 &f后台指令帮助'
- '&8#&f info &6<玩家> &e[仓库ID] &e[物品ID]'
- '&8-&7 得到玩家的相关物品信息。'
- '&8#&f add &6<玩家> &6<仓库ID> &6<物品ID> &6<数量>'
- '&8-&7 为玩家添加对应仓库中对于物品的数量。'
- '&8#&f remove &6<玩家> &6<仓库ID> &6<物品ID> &e[数量]'
- '&8-&7 为玩家减少对应仓库中对于物品的数量。'
- '&8-&7 若不填写数量,则清空对应仓库的对应物品。'
- '&8#&f sell &6<玩家> &e[仓库ID] &e[物品ID] &e[数量]'
- '&8-&7 为玩家售出相关物品。'
- '&8-&7 若不填写数量,则售出所有对应仓库的对应物品。'
- '&8-&7 若不填写物品,则售出对应仓库内所有物品。'
- '&8-&7 若不填写仓库,则售出所有仓库内所有物品。'
- '&8-&7 该指令受到玩家每日售出数量的限制。'
player:
- '&6&l超级仓库 &f玩家指令帮助'
- '&8#&f open &e[仓库ID]'
- '&8-&7 打开对应仓库的界面。'
- '&8#&f sell &6<仓库ID> &6<物品ID> &6<数量>'
- '&8-&7 售出对应数量的对应物品。'
- '&8-&7 该指令受到玩家每日售出数量的限制。'
- '&8#&f sellAll &e[仓库ID] &e[物品ID]'
- '&8-&7 该指令受到玩家每日售出数量的限制。'
item-sold:
- '&f您出售了 &r%(item)&7x%(amount) &f,共赚取 &6%(money) &f元。'
item-sold-limit:
- '&f该物品今日剩余可出售额度为 &a%(amount)&8/%(limit) &f个。'
item-pickup:
- '&f您拾取了 &r%(item)&7x%(amount) &f,已自动放入到您的仓库中。'
item-takeout:
- '&f您从仓库中拿取了 &r%(item)&7x%(amount) &f放入到您的背包中。'
item-collect:
- '&f您收集了 &r%(item)&7x%(amount) &f,已自动放入到您的 &6%(depository) &f中。'
item-collect-actionbar: '&r%(item)&7x%(amount) &f-> &6%(depository)'
no-space:
- '&f您背包内没有足够的空间取出物品!'
no-economy:
- '&f本服务器暂未启用出售功能。'
no-depository:
- '&f不存在该仓库,请检查仓库ID是否正确。'
no-item:
- '&f仓库中不存在该物品,请检查物品ID是否正确。'
no-enough-item:
- '&f仓库中不存在足够的物品。'
wrong-number:
- '&f数目输入错误,请输入正确的数字!'
-58
View File
@@ -1,58 +0,0 @@
help:
player:
- "&6&l超级仓库 &f玩家指令帮助"
- "&8#&f open &e[仓库ID]"
- "&8-&7 打开对应仓库的界面。"
- "&8#&f sell &6<仓库ID> &6<物品ID> &6<数量>"
- "&8-&7 售出对应数量的对应物品。"
- "&8-&7 该指令受到玩家每日售出数量的限制。"
- "&8#&f sellAll &e[仓库ID] &e[物品ID]"
- "&8-&7 该指令受到玩家每日售出数量的限制。"
console:
- "&6&l超级仓库 &f后台指令帮助"
- "&8#&f info &6<玩家> &e[仓库ID] &e[物品ID]"
- "&8-&7 得到玩家的相关物品信息。"
- "&8#&f add &6<玩家> &6<仓库ID> &6<物品ID> &6<数量>"
- "&8-&7 为玩家添加对应仓库中对于物品的数量。"
- "&8#&f remove &6<玩家> &6<仓库ID> &6<物品ID> &e[数量]"
- "&8-&7 为玩家减少对应仓库中对于物品的数量。"
- "&8-&7 若不填写数量,则清空对应仓库的对应物品。"
- "&8#&f sell &6<玩家> &e[仓库ID] &e[物品ID] &e[数量]"
- "&8-&7 为玩家售出相关物品。"
- "&8-&7 若不填写数量,则售出所有对应仓库的对应物品。"
- "&8-&7 若不填写物品,则售出对应仓库内所有物品。"
- "&8-&7 若不填写仓库,则售出所有仓库内所有物品。"
- "&8-&7 该指令受到玩家每日售出数量的限制。"
item-collected:
- "&f您收集了 &r%(item)&7x%(amount) &f,已自动放入到您的 &6%(depository) &f中。"
item-pickup:
- "&f您取出了 &r%(item)&7x%(amount) &f,已自动放入到您的仓库中。"
item-sold:
- "&f您出售了 &r%(item)&7x%(amount) &f,共赚取 &6%(money) &f元。"
item-sold-limit:
- "&f该物品今日剩余可出售额度为 &a%(amount)&8/%(limit) &f个。"
no-economy:
- "&f本服务器暂未启用出售功能。"
no-space:
- "&f您仓库内没有足够的空间取出物品!"
no-depository:
- "&f不存在该仓库,请检查仓库ID是否正确。"
no-item:
- "&f仓库中不存在该物品,请检查物品ID是否正确。"
no-enough-item:
- "&f仓库中不存在足够的物品。"
wrong-number:
- "&f数目输入错误,请输入正确的数字!"
+5 -1
View File
@@ -9,7 +9,7 @@ authors:
- CarmJos - CarmJos
- Zimrs - Zimrs
api-version: 1.13 api-version: 1.16
softdepend: softdepend:
- PlaceholderAPI - PlaceholderAPI
@@ -30,6 +30,10 @@ permissions:
description: "超级仓库的基本使用权限" description: "超级仓库的基本使用权限"
default: true default: true
"UltraDepository.silent":
description: "超级仓库的安静模式权限,拥有该权限将不再接收到放入背包的提示。"
default: false
"UltraDepository.auto": "UltraDepository.auto":
description: "超级仓库的自动收集权限" description: "超级仓库的自动收集权限"
default: op default: op
+20
View File
@@ -0,0 +1,20 @@
import org.junit.Test;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class MoneyTest {
@Test
public void test() {
System.out.println(get(1.2, 100));
System.out.println(get(0.55, 10));
System.out.println(get(0.21, 5));
}
public double get(double price, int amount) {
BigDecimal money = BigDecimal.valueOf(price * amount).setScale(2, RoundingMode.DOWN);
return money.doubleValue();
}
}
+20
View File
@@ -0,0 +1,20 @@
import cc.carm.lib.githubreleases4j.GithubRelease;
import cc.carm.lib.githubreleases4j.GithubReleases4J;
import org.junit.Test;
import java.util.List;
public class ReleasesTest {
@Test
public void onTest() {
List<GithubRelease> releases = GithubReleases4J.listReleases("CarmJos", "UltraDepository");
for (GithubRelease release : releases) {
System.out.println("#" + release.getID() + " (:" + release.getTagName() + ")" + " " + release.getName());
System.out.println("- " + release.getHTMLUrl());
}
}
}