mirror of
https://github.com/CarmJos/UltraDepository.git
synced 2026-06-04 16:48:21 +08:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f98a7ce025 | |||
| c5230c0fbd | |||
| 56aba62ffc | |||
| affe047789 | |||
| 6662ae35fb | |||
| e95ca412f8 | |||
| 539d0d08dc | |||
| 92b9c45911 | |||
| bfbf55c9fc | |||
| 564ca28f4a | |||
| 4b533e44b3 |
@@ -14,5 +14,3 @@
|
||||
## [开发文档](JAVADOC-README.md)
|
||||
|
||||
基于 [Github Pages](https://pages.github.com/) 搭建,请访问 [JavaDoc](https://carmjos.github.io/UltraDepository) 。
|
||||
|
||||
## 文档目录
|
||||
@@ -1,8 +1,12 @@
|
||||
# UltraDepository 示例仓库配置
|
||||
# UltraDepository 预设仓库配置
|
||||
|
||||
## 详细示例
|
||||
|
||||
您可以 [点击这里](full-example.yml) 查看一份详细的示例。
|
||||
|
||||
## 使用须知
|
||||
|
||||
示例配置基于 MineCraft 1.16 实现,更低版本可能无法使用。
|
||||
预设配置基于 MineCraft 1.16 实现,更低版本可能无法使用。
|
||||
|
||||
## 如何使用?
|
||||
|
||||
@@ -11,8 +15,7 @@
|
||||
3. 下载你想要的示例仓库配置文件,并放入 `插件配置目录/depositories` 下。
|
||||
4. 重启服务器,即可令对应的配置文件生效!
|
||||
|
||||
|
||||
## 示例图片
|
||||
## 预设配置截图
|
||||
|
||||
### 渔夫仓库 ([fishman.yml](files/fishman.yml))
|
||||
|
||||
|
||||
@@ -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抓住墨鱼!"
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"farmer": {},
|
||||
"hunter": {
|
||||
"CHICKEN:0": {
|
||||
"amount": 3
|
||||
},
|
||||
"FEATHER:0": {
|
||||
"amount": 2
|
||||
}
|
||||
},
|
||||
"miner": {
|
||||
"COAL:0": {
|
||||
"amount": 9,
|
||||
"sold": 10
|
||||
},
|
||||
"LAPIS_LAZULI:0": {
|
||||
"amount": 9
|
||||
},
|
||||
"REDSTONE:0": {
|
||||
"sold": 129
|
||||
},
|
||||
"COBBLESTONE:0": {
|
||||
"amount": 12
|
||||
},
|
||||
"CLAY_BALL:0": {
|
||||
"amount": 112
|
||||
},
|
||||
"DIAMOND:0": {
|
||||
"amount": 975,
|
||||
"sold": 1500
|
||||
}
|
||||
},
|
||||
"fishman": {
|
||||
"COD:0": {
|
||||
"amount": 3
|
||||
},
|
||||
"PUFFERFISH:0": {
|
||||
"amount": 64
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,21 +24,37 @@
|
||||
|
||||
本插件由 [墨豆Mordo](https://www.zimrs.cn) 赞助本人开发,经过授权后开源。
|
||||
|
||||
## 功能介绍
|
||||
|
||||
本插件允许配置多个不同功能的仓库,玩家通过 击杀生物/挖掘方块/捡起收集 获得的原版物品可以自动被放入仓库中。
|
||||
|
||||
进入仓库后的物品玩家可以选择拿出或直接按量出售,且每日的出售数量上限和每件物品的价格可以自定义。
|
||||
|
||||
插件支持针对不同的权限配置仓库的容量,由此可以制作付费享用的”农业仓库“、”战斗仓库“、”伐木仓库“...
|
||||
|
||||
## 效果预览
|
||||
|
||||
### 收集物品
|
||||
<details>
|
||||
<summary>收集物品</summary>
|
||||
|
||||

|
||||
|
||||
### 仓库界面 (可自定义配置)
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>仓库界面 (可自定义配置)</summary>
|
||||
|
||||

|
||||
|
||||
### 出售界面
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>出售界面</summary>
|
||||
|
||||

|
||||
|
||||

|
||||
</details>
|
||||
|
||||
## 插件依赖
|
||||
|
||||
@@ -168,6 +184,8 @@
|
||||
|
||||
# UltraDepository.auto.enable
|
||||
- 用于判断是否启用了自动收集功能
|
||||
- 若玩家有"UltraDepository.auto"权限,且玩家有该权限,则会开始为玩家自动收集物品。
|
||||
- 若玩家缺失该权限或“UltraDepository.auto”权限,则自动收集物品功能不会启用。
|
||||
- 您可以自己使用GUI创建一个按钮,后通过给玩家添加/删除该权限决定玩家是否开启自动收集。
|
||||
|
||||
# UltraDepository.admin
|
||||
@@ -179,79 +197,27 @@
|
||||
|
||||
## 配置文件
|
||||
|
||||
### [插件配置文件](src/main/resources/config.yml) (config.yml)
|
||||
### 插件配置文件 ([config.yml](src/main/resources/config.yml))
|
||||
|
||||
详见源文件。
|
||||
|
||||
### [消息配置文件](src/main/resources/messages.yml) (messages.yml)
|
||||
### 消息配置文件 ([messages.yml](src/main/resources/messages.yml))
|
||||
|
||||
详见源文件。
|
||||
|
||||
### 仓库配置文件 (depositories/<ID>.yml)
|
||||
### 仓库配置文件 ([depositories/<仓库ID>.yml](.examples/depositories/full-example.yml))
|
||||
|
||||
所有仓库配置均为单独的配置文件,存放于 `插件配置目录/depositories` 下,便于管理。
|
||||
|
||||
文件名即仓库的ID,理论上可以随便取,但**强烈推荐**使用纯英文,部分符号可能会影响正常读取,请避免使用。
|
||||
文件名即仓库的ID,**强烈推荐使用纯英文**,部分符号可能会影响正常读取,请避免使用。
|
||||
|
||||
这里准备了几个常用的仓库类型,可以 [在这里](.examples/depositories) 找到您需要的直接使用或加以修改后使用。
|
||||
随本项目预设了几个常用的仓库类型,可以 [在这里](.examples/depositories) 找到您需要的直接使用或加以修改后使用。
|
||||
|
||||
您也可以查看下方的示例,看到所有相关的配置,以制作您自己的仓库。
|
||||
<details>
|
||||
<summary>展开查看示例仓库配置</summary>
|
||||
您也可以 [点击这里](.examples/depositories/full-example.yml) 查看一份*详细的仓库配置示例*,以制作您自己的仓库。
|
||||
|
||||
```yaml
|
||||
## 使用统计
|
||||
|
||||
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抓住墨鱼!"
|
||||
|
||||
```
|
||||
|
||||
</details>
|
||||

|
||||
|
||||
## 支持与捐赠
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<groupId>cc.carm.plugin</groupId>
|
||||
<artifactId>ultradepository</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.1.0</version>
|
||||
<version>1.1.5</version>
|
||||
|
||||
<name>UltraDepository</name>
|
||||
<description>超级仓库插件,支持设定不同物品的存储仓库。</description>
|
||||
@@ -91,6 +91,13 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-bukkit</artifactId>
|
||||
<version>2.2.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>easysql-beecp</artifactId>
|
||||
@@ -207,6 +214,20 @@
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>org.bstats</pattern>
|
||||
<shadedPattern>cc.carm.plugin.ultradepository.lib.bstats</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>cc.carm.lib.easysql</pattern>
|
||||
<shadedPattern>cc.carm.plugin.ultradepository.lib.easysql</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>cn.beecp</pattern>
|
||||
<shadedPattern>cc.carm.plugin.ultradepository.lib.beecp</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
|
||||
@@ -15,6 +15,8 @@ import cc.carm.plugin.ultradepository.storage.MySQLStorage;
|
||||
import cc.carm.plugin.ultradepository.util.ColorParser;
|
||||
import cc.carm.plugin.ultradepository.util.MessageUtil;
|
||||
import cc.carm.plugin.ultradepository.util.SchedulerUtils;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bstats.charts.SingleLineChart;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
@@ -27,6 +29,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
public class Main extends JavaPlugin {
|
||||
|
||||
private static Main instance;
|
||||
private static Metrics metrics;
|
||||
private static SchedulerUtils scheduler;
|
||||
|
||||
private static DataStorage storage;
|
||||
@@ -94,6 +97,15 @@ public class Main extends JavaPlugin {
|
||||
log("检测到未安装PlaceholderAPI,跳过变量注册。");
|
||||
}
|
||||
|
||||
if (PluginConfig.METRICS.get()) {
|
||||
log("启用统计数据...");
|
||||
metrics = new Metrics(this, 13777);
|
||||
metrics.addCustomChart(new SingleLineChart(
|
||||
"active_depositories",
|
||||
() -> getDepositoryManager().getDepositories().size())
|
||||
);
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
log("加载完成 ,共耗时 " + (System.currentTimeMillis() - startTime) + " ms 。");
|
||||
|
||||
|
||||
@@ -11,9 +11,14 @@ import org.bukkit.Material;
|
||||
public class PluginConfig {
|
||||
|
||||
public static final ConfigValue<Boolean> DEBUG = new ConfigValue<>(
|
||||
"debug", Boolean.class
|
||||
"debug", Boolean.class, false
|
||||
);
|
||||
|
||||
public static final ConfigValue<Boolean> METRICS = new ConfigValue<>(
|
||||
"metrics", Boolean.class, true
|
||||
);
|
||||
|
||||
|
||||
public static final ConfigValue<String> STORAGE_METHOD = new ConfigValue<>(
|
||||
"storage.method", String.class
|
||||
);
|
||||
|
||||
+2
-4
@@ -3,7 +3,6 @@ package cc.carm.plugin.ultradepository.configuration.depository;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -45,9 +44,8 @@ public class DepositoryCapacity {
|
||||
public int getPlayerCapacity(Player player) {
|
||||
return getPermissions().entrySet().stream()
|
||||
.filter(entry -> player.hasPermission(entry.getKey()))
|
||||
.map(Map.Entry::getValue)
|
||||
.min(Comparator.comparingInt(Integer::intValue))
|
||||
.orElse(defaultCapacity);
|
||||
.mapToInt(Map.Entry::getValue)
|
||||
.max().orElse(defaultCapacity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.sql.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -148,4 +150,21 @@ public class UserData {
|
||||
this.storage.saveUserData(this);
|
||||
}
|
||||
|
||||
public Map<String, Map<String, Map<String, Integer>>> serializeToMap() {
|
||||
Map<String, Map<String, Map<String, Integer>>> values = new LinkedHashMap<>();
|
||||
|
||||
getDepositories().forEach((depositoryID, depositoryData) -> {
|
||||
Map<String, Map<String, Integer>> depositoryDataMap = new LinkedHashMap<>();
|
||||
depositoryData.getContents().forEach((itemType, itemData) -> {
|
||||
Map<String, Integer> itemDataMap = new HashMap<>();
|
||||
if (itemData.getAmount() > 0) itemDataMap.put("amount", itemData.getAmount());
|
||||
if (itemData.getSold() > 0) itemDataMap.put("sold", itemData.getSold());
|
||||
if (!itemDataMap.isEmpty()) depositoryDataMap.put(itemType, itemDataMap);
|
||||
});
|
||||
if (!depositoryDataMap.isEmpty()) values.put(depositoryID, depositoryDataMap);
|
||||
});
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@ package cc.carm.plugin.ultradepository.listener;
|
||||
|
||||
import cc.carm.plugin.ultradepository.Main;
|
||||
import cc.carm.plugin.ultradepository.configuration.PluginConfig;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@@ -26,9 +24,7 @@ public class CollectListener implements Listener {
|
||||
|
||||
Player player = event.getPlayer();
|
||||
if (!Main.getUserManager().isCollectEnabled(player)) return;
|
||||
if (event.getBlock().getType() == Material.CHEST || event.getBlock().getType() == Material.TRAPPED_CHEST) {
|
||||
return;
|
||||
}
|
||||
if (event.getBlock().getType().isOccluding()) return;
|
||||
|
||||
List<Item> droppedItems = event.getItems();
|
||||
if (droppedItems.isEmpty()) return;
|
||||
|
||||
@@ -7,7 +7,6 @@ import cc.carm.plugin.ultradepository.configuration.depository.Depository;
|
||||
import cc.carm.plugin.ultradepository.configuration.depository.DepositoryItem;
|
||||
import cc.carm.plugin.ultradepository.data.UserData;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
@@ -112,12 +111,10 @@ public class DepositoryManager {
|
||||
}
|
||||
|
||||
public Set<Depository> getPlayerUsableDepository(Player player, ItemStack itemStack) {
|
||||
String typeID = getItemTypeID(itemStack);
|
||||
return getItemDepositories(itemStack).stream().filter(configuration -> {
|
||||
int currentAmount = Optional.ofNullable(Main.getUserManager().getData(player)
|
||||
.getItemAmount(configuration.getIdentifier(), typeID)).orElse(0);
|
||||
int depositoryCapacity = configuration.getCapacity().getPlayerCapacity(player);
|
||||
return currentAmount + itemStack.getAmount() <= depositoryCapacity;
|
||||
int used = Main.getUserManager().getData(player).getDepositoryData(configuration).getUsedCapacity();
|
||||
int max = configuration.getCapacity().getPlayerCapacity(player);
|
||||
return used + itemStack.getAmount() <= max;
|
||||
}).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class FileStorage implements DataStorage {
|
||||
@@ -104,21 +102,8 @@ public class FileStorage implements DataStorage {
|
||||
YamlConfiguration userDataConfig = new YamlConfiguration();
|
||||
userDataConfig.set("date", data.getDateInt());
|
||||
|
||||
Map<String, Map<String, Map<String, Integer>>> values = new LinkedHashMap<>();
|
||||
|
||||
data.getDepositories().forEach((depositoryID, depositoryData) -> {
|
||||
Map<String, Map<String, Integer>> depositoryDataMap = new LinkedHashMap<>();
|
||||
depositoryData.getContents().forEach((itemType, itemData) -> {
|
||||
Map<String, Integer> itemDataMap = new HashMap<>();
|
||||
if (itemData.getAmount() > 0) itemDataMap.put("amount", itemData.getAmount());
|
||||
if (itemData.getSold() > 0) itemDataMap.put("sold", itemData.getSold());
|
||||
if (!itemDataMap.isEmpty()) depositoryDataMap.put(itemType, itemDataMap);
|
||||
});
|
||||
if (!depositoryDataMap.isEmpty()) values.put(depositoryID, depositoryDataMap);
|
||||
});
|
||||
|
||||
try {
|
||||
userDataConfig.createSection("depositories", values);
|
||||
userDataConfig.createSection("depositories", data.serializeToMap());
|
||||
userDataConfig.save(new File(getDataContainer(), data.getUserUUID() + ".yml"));
|
||||
} catch (IOException ioException) {
|
||||
Main.error("在保存玩家 #" + data.getUserUUID() + " 的数据时出现异常。");
|
||||
|
||||
@@ -18,7 +18,6 @@ import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.sql.Date;
|
||||
import java.sql.ResultSet;
|
||||
@@ -133,12 +132,16 @@ public class MySQLStorage implements DataStorage {
|
||||
for (Map.Entry<String, JsonElement> entry : dataElement.getAsJsonObject().entrySet()) {
|
||||
Depository depository = Main.getDepositoryManager().getDepository(entry.getKey());
|
||||
if (depository == null) continue;
|
||||
|
||||
DepositoryData contentsData = parseContentsData(depository, data, entry.getValue());
|
||||
if (contentsData != null) data.setDepository(contentsData);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Main.debug("通过 MySQLStorage 加载 " + uuid + " 的用户数据完成,"
|
||||
+ "耗时 " + (System.currentTimeMillis() - start) + "ms。");
|
||||
|
||||
return data;
|
||||
}
|
||||
Main.debug("当前库内不存在玩家 " + uuid + " 的数据,视作新档。");
|
||||
@@ -153,15 +156,13 @@ public class MySQLStorage implements DataStorage {
|
||||
long start = System.currentTimeMillis();
|
||||
Main.debug("正通过 MySQLStorage 保存 " + data.getUserUUID() + " 的用户数据...");
|
||||
|
||||
JsonObject dataObject = new JsonObject();
|
||||
|
||||
data.getDepositories().forEach((id, contents) -> dataObject.add(id, serializeContentsData(contents)));
|
||||
|
||||
try {
|
||||
|
||||
getSQLManager().createReplace(SQLTables.USER_DATA.getName())
|
||||
.setColumnNames("uuid", "data", "day")
|
||||
.setParams(data.getUserUUID(), GSON.toJson(dataObject), data.getDate())
|
||||
.setParams(data.getUserUUID(), GSON.toJson(data.serializeToMap()), data.getDate())
|
||||
.execute();
|
||||
|
||||
} catch (SQLException exception) {
|
||||
Main.error("在保存玩家 #" + data.getUserUUID() + " 的数据时出现异常。");
|
||||
Main.error("Error occurred when saving #" + data.getUserUUID() + " data.");
|
||||
@@ -191,10 +192,13 @@ public class MySQLStorage implements DataStorage {
|
||||
private DepositoryData parseContentsData(Depository source, UserData owner, JsonObject contentsObject) {
|
||||
DepositoryData data = DepositoryData.emptyContents(source, owner);
|
||||
for (Map.Entry<String, JsonElement> entry : contentsObject.entrySet()) {
|
||||
|
||||
DepositoryItem item = source.getItems().get(entry.getKey());
|
||||
if (item == null) continue;
|
||||
|
||||
DepositoryItemData itemData = parseItemData(item, data, entry.getValue());
|
||||
if (itemData != null) data.getContents().put(item.getTypeID(), itemData);
|
||||
|
||||
}
|
||||
return data;
|
||||
}
|
||||
@@ -207,26 +211,8 @@ public class MySQLStorage implements DataStorage {
|
||||
int amount = itemObject.has("amount") ? itemObject.get("amount").getAsInt() : 0;
|
||||
int sold = itemObject.has("sold") ? itemObject.get("sold").getAsInt() : 0;
|
||||
if (amount == 0 && sold == 0) return null;
|
||||
else return new DepositoryItemData(source, owner, amount, sold);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JsonObject serializeContentsData(@Nullable DepositoryData contentsData) {
|
||||
if (contentsData == null) return null;
|
||||
JsonObject contentsObject = new JsonObject();
|
||||
contentsData.getContents().entrySet().stream()
|
||||
// 只存取有数值的部分,减少数据量
|
||||
.filter(entry -> entry.getValue().getSold() > 0 || entry.getValue().getAmount() > 0)
|
||||
.forEach(entry -> contentsObject.add(entry.getKey(), serializeItemData(entry.getValue())));
|
||||
return contentsObject;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsonObject serializeItemData(@NotNull DepositoryItemData itemData) {
|
||||
JsonObject itemObject = new JsonObject();
|
||||
if (itemData.getAmount() > 0) itemObject.addProperty("amount", itemData.getAmount());
|
||||
if (itemData.getSold() > 0) itemObject.addProperty("sold", itemData.getSold());
|
||||
return itemObject;
|
||||
return new DepositoryItemData(source, owner, amount, sold);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -59,21 +59,19 @@ public class DepositoryGUI extends GUI {
|
||||
return new GUIItem(factory.toItemStack()) {
|
||||
@Override
|
||||
public void onClick(ClickType type) {
|
||||
if (itemData.getAmount() < 1) return;
|
||||
if (itemData.getAmount() < 1) {
|
||||
PluginMessages.NO_ENOUGH_ITEM.send(player);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == ClickType.LEFT) {
|
||||
player.closeInventory();
|
||||
if (itemData.getAmount() >= 1) {
|
||||
if (remain >= 1) {
|
||||
SellItemGUI.open(player, userData, itemData, depository, item);
|
||||
} else {
|
||||
PluginMessages.ITEM_SOLD_LIMIT.send(player, new Object[]{remain, item.getLimit()});
|
||||
}
|
||||
} else {
|
||||
PluginMessages.NO_ENOUGH_ITEM.send(player);
|
||||
}
|
||||
|
||||
} else if (type == ClickType.RIGHT) {
|
||||
player.closeInventory();
|
||||
|
||||
if (hasEmptySlot(player)) {
|
||||
int pickupAmount = Math.min(itemData.getAmount(), item.getMaterial().getMaxStackSize());
|
||||
userData.removeItemAmount(item.getDepository().getIdentifier(), item.getTypeID(), pickupAmount);
|
||||
@@ -81,10 +79,12 @@ public class DepositoryGUI extends GUI {
|
||||
PluginMessages.PICKUP.send(player, new Object[]{
|
||||
item.getName(), pickupAmount
|
||||
});
|
||||
setupItems(); //刷新GUI
|
||||
updateView();
|
||||
} else {
|
||||
PluginMessages.NO_SPACE.send(player);
|
||||
player.closeInventory();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -97,6 +97,7 @@ public class DepositoryGUI extends GUI {
|
||||
}
|
||||
|
||||
public static void open(@NotNull Player player, @NotNull Depository depository) {
|
||||
player.closeInventory();
|
||||
DepositoryGUI gui = new DepositoryGUI(player, depository);
|
||||
gui.openGUI(player);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package cc.carm.plugin.ultradepository.ui;
|
||||
|
||||
import cc.carm.plugin.ultradepository.Main;
|
||||
import cc.carm.plugin.ultradepository.configuration.PluginConfig;
|
||||
import cc.carm.plugin.ultradepository.configuration.PluginMessages;
|
||||
import cc.carm.plugin.ultradepository.configuration.depository.Depository;
|
||||
import cc.carm.plugin.ultradepository.configuration.depository.DepositoryItem;
|
||||
import cc.carm.plugin.ultradepository.data.DepositoryItemData;
|
||||
@@ -177,7 +178,12 @@ public class SellItemGUI extends GUI {
|
||||
|
||||
public static void open(Player player, UserData userData, DepositoryItemData itemData,
|
||||
Depository configuration, DepositoryItem item) {
|
||||
if (!Main.getEconomyManager().isInitialized()) return;
|
||||
player.closeInventory();
|
||||
if (!Main.getEconomyManager().isInitialized()) {
|
||||
PluginMessages.NO_ECONOMY.send(player);
|
||||
return;
|
||||
}
|
||||
|
||||
SellItemGUI gui = new SellItemGUI(player, userData, itemData, configuration, item);
|
||||
gui.openGUI(player);
|
||||
}
|
||||
|
||||
@@ -6,16 +6,18 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class GUI {
|
||||
|
||||
@@ -26,13 +28,13 @@ public class GUI {
|
||||
public GUIItem[] items;
|
||||
public Inventory inv;
|
||||
|
||||
boolean cancelOnTarget = true;
|
||||
boolean cancelOnSelf = true;
|
||||
boolean cancelOnOuter = true;
|
||||
boolean setCancelledIfClickOnTarget = true;
|
||||
boolean setCancelledIfClickOnSelf = true;
|
||||
boolean setCancelledIfClickOnOuter = true;
|
||||
|
||||
Map<String, Object> flags;
|
||||
|
||||
public GUIListener listener;
|
||||
public Listener listener;
|
||||
|
||||
public GUI(GUIType type, String name) {
|
||||
this.type = type;
|
||||
@@ -71,18 +73,10 @@ public class GUI {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加GUI Item
|
||||
*
|
||||
* @param item 物品
|
||||
* @param index 对应格
|
||||
*/
|
||||
public void setItem(GUIItem item, int... index) {
|
||||
Arrays.stream(index).forEach(i -> setItem(i, item));
|
||||
for (int i : index) {
|
||||
setItem(i, item);
|
||||
}
|
||||
|
||||
public void setItem(GUIItem item, int start, int end) {
|
||||
IntStream.rangeClosed(start, end).forEach(i -> setItem(i, item));
|
||||
}
|
||||
|
||||
public GUIItem getItem(int index) {
|
||||
@@ -95,18 +89,14 @@ public class GUI {
|
||||
public void updateView() {
|
||||
if (this.inv != null) {
|
||||
List<HumanEntity> viewers = this.inv.getViewers();
|
||||
IntStream.range(0, this.items.length).forEach(index -> {
|
||||
GUIItem item = items[index];
|
||||
if (item == null) {
|
||||
for (int index = 0; index < this.items.length; index++) {
|
||||
if (items[index] == null) {
|
||||
inv.setItem(index, new ItemStack(Material.AIR));
|
||||
} else {
|
||||
inv.setItem(index, items[index].display);
|
||||
}
|
||||
});
|
||||
|
||||
for (HumanEntity p : viewers) {
|
||||
((Player) p).updateInventory();
|
||||
}
|
||||
viewers.forEach(p -> ((Player) p).updateInventory());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +107,7 @@ public class GUI {
|
||||
* @param b 是否取消
|
||||
*/
|
||||
public void setCancelledIfClickOnTarget(boolean b) {
|
||||
this.cancelOnTarget = b;
|
||||
this.setCancelledIfClickOnTarget = b;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,7 +117,7 @@ public class GUI {
|
||||
* @param b 是否取消
|
||||
*/
|
||||
public void setCancelledIfClickOnSelf(boolean b) {
|
||||
this.cancelOnSelf = b;
|
||||
this.setCancelledIfClickOnSelf = b;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,7 +127,7 @@ public class GUI {
|
||||
* @param b 是否取消
|
||||
*/
|
||||
public void setCancelledIfClickOnOuter(boolean b) {
|
||||
this.cancelOnOuter = b;
|
||||
this.setCancelledIfClickOnOuter = b;
|
||||
}
|
||||
|
||||
public void addFlag(String flag, Object obj) {
|
||||
@@ -182,14 +172,78 @@ public class GUI {
|
||||
this.inv = inv;
|
||||
player.openInventory(inv);
|
||||
|
||||
if (listener == null) {
|
||||
Main.regListener(listener = new GUIListener(this, player));
|
||||
if (listener == null)
|
||||
Bukkit.getPluginManager().registerEvents(listener = new Listener() {
|
||||
@EventHandler
|
||||
public void onInventoryClickEvent(InventoryClickEvent event) {
|
||||
if (!(event.getWhoClicked() instanceof Player)) return;
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
if (!hasOpenedGUI(player)) return;
|
||||
|
||||
rawClickListener(event);
|
||||
if (event.getSlot() != -999) {
|
||||
try {
|
||||
if (getOpenedGUI(player) == GUI.this
|
||||
&& event.getClickedInventory() != null
|
||||
&& event.getClickedInventory().equals(GUI.this.inv)
|
||||
&& GUI.this.items[event.getSlot()] != null) {
|
||||
GUI.this.items[event.getSlot()].realRawClickAction(event);
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
System.err.print("err cause by GUI(" + GUI.this + "), name=" + name);
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
} else if (setCancelledIfClickOnOuter) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
if (getOpenedGUI(player) == GUI.this
|
||||
&& event.getClickedInventory() != null) {
|
||||
if (event.getClickedInventory().equals(GUI.this.inv)) {
|
||||
if (setCancelledIfClickOnTarget) event.setCancelled(true);
|
||||
|
||||
if (event.getSlot() != -999 && GUI.this.items[event.getSlot()] != null) {
|
||||
GUIItem clickedItem = GUI.this.items[event.getSlot()];
|
||||
if (clickedItem.isActionActive()) {
|
||||
clickedItem.onClick(event.getClick());
|
||||
clickedItem.rawClickAction(event);
|
||||
clickedItem.actions.forEach(action -> action.run(event.getClick(), player));
|
||||
}
|
||||
clickedItem.actionsIgnoreActive.forEach(action -> action.run(event.getClick(), player));
|
||||
}
|
||||
} else if (event.getClickedInventory().equals(player.getInventory()) && setCancelledIfClickOnSelf) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDrag(InventoryDragEvent e) {
|
||||
if (!(e.getWhoClicked() instanceof Player)) return;
|
||||
if (e.getInventory().equals(inv)
|
||||
|| e.getInventory().equals(e.getWhoClicked().getInventory())) {
|
||||
GUI.this.onDrag(e);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryCloseEvent(InventoryCloseEvent event) {
|
||||
if (!(event.getPlayer() instanceof Player)) return;
|
||||
if (!event.getInventory().equals(inv)) return;
|
||||
|
||||
HandlerList.unregisterAll(this);
|
||||
listener = null;
|
||||
removeOpenedGUI((Player) event.getPlayer());
|
||||
onClose();
|
||||
|
||||
}
|
||||
}, Main.getInstance());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 拖动GUI内物品时执行的代码
|
||||
* 拖动GUI内物品是执行的代码
|
||||
*
|
||||
* @param event InventoryDragEvent
|
||||
*/
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
package cc.carm.plugin.ultradepository.util.gui;
|
||||
|
||||
import cc.carm.plugin.ultradepository.Main;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||
import org.bukkit.event.inventory.InventoryOpenEvent;
|
||||
|
||||
public class GUIListener implements Listener {
|
||||
|
||||
final GUI currentGUI;
|
||||
final Player player;
|
||||
|
||||
public GUIListener(GUI gui, Player player) {
|
||||
this.currentGUI = gui;
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public GUI getCurrentGUI() {
|
||||
return currentGUI;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClickEvent(InventoryClickEvent event) {
|
||||
if (!(event.getWhoClicked() instanceof Player)) return;
|
||||
getCurrentGUI().rawClickListener(event);
|
||||
|
||||
Player p = (Player) event.getWhoClicked();
|
||||
if (event.getSlot() != -999) {
|
||||
try {
|
||||
if (GUI.getOpenedGUI(p) == getCurrentGUI()
|
||||
&& event.getClickedInventory() != null
|
||||
&& event.getClickedInventory().equals(getCurrentGUI().inv)
|
||||
&& getCurrentGUI().items[event.getSlot()] != null) {
|
||||
getCurrentGUI().items[event.getSlot()].realRawClickAction(event);
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
Main.error("error cause by GUI(" + getCurrentGUI() + "), name=" + getCurrentGUI().name);
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
} else if (getCurrentGUI().cancelOnOuter) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
if (GUI.hasOpenedGUI(p)
|
||||
&& GUI.getOpenedGUI(p) == getCurrentGUI()
|
||||
&& event.getClickedInventory() != null) {
|
||||
|
||||
if (event.getClickedInventory().equals(getCurrentGUI().inv)) {
|
||||
if (getCurrentGUI().cancelOnTarget) event.setCancelled(true);
|
||||
|
||||
if (event.getSlot() != -999 && getCurrentGUI().items[event.getSlot()] != null) {
|
||||
|
||||
GUIItem item = getCurrentGUI().items[event.getSlot()];
|
||||
|
||||
if (item.isActionActive()) {
|
||||
item.onClick(event.getClick());
|
||||
item.rawClickAction(event);
|
||||
item.actions.forEach(action -> action.run(event.getClick(), player));
|
||||
}
|
||||
|
||||
item.actionsIgnoreActive.forEach(action -> action.run(event.getClick(), player));
|
||||
|
||||
}
|
||||
} else if (event.getClickedInventory().equals(p.getInventory()) && getCurrentGUI().cancelOnSelf) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDrag(InventoryDragEvent e) {
|
||||
if (!(e.getWhoClicked() instanceof Player)) return;
|
||||
Player p = (Player) e.getWhoClicked();
|
||||
if (e.getInventory().equals(getCurrentGUI().inv) || e.getInventory().equals(p.getInventory())) {
|
||||
getCurrentGUI().onDrag(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryCloseEvent(InventoryCloseEvent event) {
|
||||
Player p = (Player) event.getPlayer();
|
||||
if (event.getInventory().equals(getCurrentGUI().inv)) {
|
||||
HandlerList.unregisterAll(this);
|
||||
getCurrentGUI().listener = null;
|
||||
getCurrentGUI().onClose();
|
||||
GUI.removeOpenedGUI(p);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onOpen(InventoryOpenEvent event) {
|
||||
Player p = (Player) event.getPlayer();
|
||||
//开启新界面后 结束旧界面
|
||||
if (!event.getInventory().equals(getCurrentGUI().inv)) {
|
||||
HandlerList.unregisterAll(this);
|
||||
getCurrentGUI().listener = null;
|
||||
getCurrentGUI().onClose();
|
||||
GUI.removeOpenedGUI(p);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,12 +6,17 @@ version: ${project.version}
|
||||
|
||||
debug: false
|
||||
|
||||
# 统计数据设定
|
||||
# 改选项用于帮助开发者统计插件版本与使用情况,且绝不会影响性能与使用体验。
|
||||
# 当然,您也可以选择在这里关闭,或在plugins/bStats下的配置文件中关闭。
|
||||
metrics: true
|
||||
|
||||
# 存储相关配置
|
||||
# 注意:存储配置不会通过重载指令生效,如有修改请重新启动服务器。
|
||||
storage:
|
||||
|
||||
# 存储方式,可选 [ file | mysql ]
|
||||
method: mysql
|
||||
method: file
|
||||
|
||||
# 选择 file 存储方式时的存储路径
|
||||
# 默认为相对路径,相对于插件生成的配置文件夹下的路径
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import com.google.gson.Gson;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class GsonMapTest {
|
||||
|
||||
private static final Gson GSON = new Gson();
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
Map<String, Map<String, Map<String, Integer>>> values = new LinkedHashMap<>();
|
||||
|
||||
|
||||
for (int u = 0; u < 3; u++) {
|
||||
Map<String, Map<String, Integer>> depositoryDataMap = new LinkedHashMap<>();
|
||||
for (int i = 0; i < 5; i++) {
|
||||
Map<String, Integer> itemDataMap = new HashMap<>();
|
||||
int amount = Math.max(0, new Random().nextInt(15));
|
||||
int sold = Math.max(0, new Random().nextInt(15));
|
||||
if (amount > 0) itemDataMap.put("amount", amount);
|
||||
if (sold > 0) itemDataMap.put("sold", sold);
|
||||
if (!itemDataMap.isEmpty()) {
|
||||
depositoryDataMap.put(UUID.randomUUID().toString().substring(0, 4), itemDataMap);
|
||||
}
|
||||
}
|
||||
if (!depositoryDataMap.isEmpty()) {
|
||||
values.put(UUID.randomUUID().toString().substring(0, 8), depositoryDataMap);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println(values.size());
|
||||
|
||||
|
||||
String jsonValues = GSON.toJson(values);
|
||||
System.out.println(jsonValues);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user