diff --git a/pom.xml b/pom.xml
index 4adb4dd..a24e216 100644
--- a/pom.xml
+++ b/pom.xml
@@ -59,7 +59,7 @@
2.0.9
1.20.4-R0.1-SNAPSHOT
- 2.0.0-SNAPSHOT
+ 2.4.0-SNAPSHOT
1.12.0
@@ -71,7 +71,7 @@
-LOCAL
- 2.13.0
+ 2.14.0
BentoBoxWorld_Level
bentobox-world
https://sonarcloud.io
diff --git a/src/main/java/world/bentobox/level/LevelsManager.java b/src/main/java/world/bentobox/level/LevelsManager.java
index f0680c5..46d47b3 100644
--- a/src/main/java/world/bentobox/level/LevelsManager.java
+++ b/src/main/java/world/bentobox/level/LevelsManager.java
@@ -39,12 +39,12 @@ public class LevelsManager {
private static final TreeMap LEVELS;
private static final BigInteger THOUSAND = BigInteger.valueOf(1000);
static {
- LEVELS = new TreeMap<>();
+ LEVELS = new TreeMap<>();
- LEVELS.put(THOUSAND, "k");
- LEVELS.put(THOUSAND.pow(2), "M");
- LEVELS.put(THOUSAND.pow(3), "G");
- LEVELS.put(THOUSAND.pow(4), "T");
+ LEVELS.put(THOUSAND, "k");
+ LEVELS.put(THOUSAND.pow(2), "M");
+ LEVELS.put(THOUSAND.pow(3), "G");
+ LEVELS.put(THOUSAND.pow(4), "T");
}
private final Level addon;
@@ -58,15 +58,15 @@ public class LevelsManager {
private Map cache = new HashMap<>();
public LevelsManager(Level addon) {
- this.addon = addon;
- // Get the BentoBox database
- // Set up the database handler to store and retrieve data
- // Note that these are saved by the BentoBox database
- handler = new Database<>(addon, IslandLevels.class);
- // Initialize the cache
- levelsCache = new HashMap<>();
- // Initialize top ten lists
- topTenLists = new ConcurrentHashMap<>();
+ this.addon = addon;
+ // Get the BentoBox database
+ // Set up the database handler to store and retrieve data
+ // Note that these are saved by the BentoBox database
+ handler = new Database<>(addon, IslandLevels.class);
+ // Initialize the cache
+ levelsCache = new HashMap<>();
+ // Initialize top ten lists
+ topTenLists = new ConcurrentHashMap<>();
}
public void migrate() {
@@ -208,7 +208,7 @@ public String formatLevel(@Nullable Long lvl) {
* @return initial level of island
*/
public long getInitialLevel(Island island) {
- return getLevelsData(island).getInitialLevel();
+ return getLevelsData(island).getInitialLevel();
}
/**
@@ -252,7 +252,7 @@ public long getIslandMaxLevel(@NonNull World world, @Nullable UUID targetPlayer)
* null
*/
public String getIslandLevelString(@NonNull World world, @Nullable UUID targetPlayer) {
- return formatLevel(getIslandLevel(world, targetPlayer));
+ return formatLevel(getIslandLevel(world, targetPlayer));
}
/**
@@ -263,24 +263,24 @@ public String getIslandLevelString(@NonNull World world, @Nullable UUID targetPl
*/
@NonNull
public IslandLevels getLevelsData(@NonNull Island island) {
- String id = island.getUniqueId();
- if (levelsCache.containsKey(id)) {
- return levelsCache.get(id);
- }
- // Get from database if not in cache
- if (handler.objectExists(id)) {
- IslandLevels ld = handler.loadObject(id);
- if (ld != null) {
- levelsCache.put(id, ld);
- } else {
- handler.deleteID(id);
- levelsCache.put(id, new IslandLevels(id));
- }
- } else {
- levelsCache.put(id, new IslandLevels(id));
- }
- // Return cached value
- return levelsCache.get(id);
+ String id = island.getUniqueId();
+ if (levelsCache.containsKey(id)) {
+ return levelsCache.get(id);
+ }
+ // Get from database if not in cache
+ if (handler.objectExists(id)) {
+ IslandLevels ld = handler.loadObject(id);
+ if (ld != null) {
+ levelsCache.put(id, ld);
+ } else {
+ handler.deleteID(id);
+ levelsCache.put(id, new IslandLevels(id));
+ }
+ } else {
+ levelsCache.put(id, new IslandLevels(id));
+ }
+ // Return cached value
+ return levelsCache.get(id);
}
/**
@@ -414,7 +414,8 @@ public void loadTopTens() {
addon.log("Generating rankings");
handler.loadObjects().forEach(il -> {
if (il.getLevel() > 0) {
- addon.getIslands().getIslandById(il.getUniqueId())
+ // Load islands, but don't cache them
+ addon.getIslands().getIslandById(il.getUniqueId(), false)
.ifPresent(i -> this.addToTopTen(i, il.getLevel()));
}
});
@@ -429,7 +430,7 @@ public void loadTopTens() {
* @param uuid - the island's uuid
*/
public void removeEntry(World world, String uuid) {
- if (topTenLists.containsKey(world)) {
+ if (topTenLists.containsKey(world)) {
topTenLists.get(world).getTopTen().remove(uuid);
// Invalidate the cache because of this deletion
cache.remove(world);
@@ -504,8 +505,8 @@ private void setIslandResults(Island island, Results r) {
* @param uniqueId - id of island
*/
public void deleteIsland(String uniqueId) {
- levelsCache.remove(uniqueId);
- handler.deleteID(uniqueId);
+ levelsCache.remove(uniqueId);
+ handler.deleteID(uniqueId);
}
}
diff --git a/src/main/java/world/bentobox/level/calculators/IslandLevelCalculator.java b/src/main/java/world/bentobox/level/calculators/IslandLevelCalculator.java
index 8904cdf..025381a 100644
--- a/src/main/java/world/bentobox/level/calculators/IslandLevelCalculator.java
+++ b/src/main/java/world/bentobox/level/calculators/IslandLevelCalculator.java
@@ -89,34 +89,34 @@ public class IslandLevelCalculator {
* @param zeroIsland - true if the calculation is due to an island zeroing
*/
public IslandLevelCalculator(Level addon, Island island, CompletableFuture r, boolean zeroIsland) {
- this.addon = addon;
- this.island = island;
- this.r = r;
- this.zeroIsland = zeroIsland;
- results = new Results();
- duration = System.currentTimeMillis();
- chunksToCheck = getChunksToScan(island);
- this.limitCount = new EnumMap<>(addon.getBlockConfig().getBlockLimits());
- // Get the initial island level
- results.initialLevel.set(addon.getInitialIslandLevel(island));
- // Set up the worlds
- worlds.put(Environment.NORMAL, Util.getWorld(island.getWorld()));
- // Nether
- if (addon.getSettings().isNether()) {
- World nether = addon.getPlugin().getIWM().getNetherWorld(island.getWorld());
- if (nether != null) {
- worlds.put(Environment.NETHER, nether);
- }
- }
- // End
- if (addon.getSettings().isEnd()) {
- World end = addon.getPlugin().getIWM().getEndWorld(island.getWorld());
- if (end != null) {
- worlds.put(Environment.THE_END, end);
- }
- }
- // Sea Height
- seaHeight = addon.getPlugin().getIWM().getSeaHeight(island.getWorld());
+ this.addon = addon;
+ this.island = island;
+ this.r = r;
+ this.zeroIsland = zeroIsland;
+ results = new Results();
+ duration = System.currentTimeMillis();
+ chunksToCheck = getChunksToScan(island);
+ this.limitCount = new EnumMap<>(addon.getBlockConfig().getBlockLimits());
+ // Get the initial island level
+ results.initialLevel.set(addon.getInitialIslandLevel(island));
+ // Set up the worlds
+ worlds.put(Environment.NORMAL, Util.getWorld(island.getWorld()));
+ // Nether
+ if (addon.getSettings().isNether()) {
+ World nether = addon.getPlugin().getIWM().getNetherWorld(island.getWorld());
+ if (nether != null) {
+ worlds.put(Environment.NETHER, nether);
+ }
+ }
+ // End
+ if (addon.getSettings().isEnd()) {
+ World end = addon.getPlugin().getIWM().getEndWorld(island.getWorld());
+ if (end != null) {
+ worlds.put(Environment.THE_END, end);
+ }
+ }
+ // Sea Height
+ seaHeight = addon.getPlugin().getIWM().getSeaHeight(island.getWorld());
}
/**
@@ -148,14 +148,14 @@ private long calculateLevel(long blockAndDeathPoints) {
* @param belowSeaLevel - true if below sea level
*/
private void checkBlock(Material mat, boolean belowSeaLevel) {
- int count = limitCount(mat);
- if (belowSeaLevel) {
- results.underWaterBlockCount.addAndGet(count);
- results.uwCount.add(mat);
- } else {
- results.rawBlockCount.addAndGet(count);
- results.mdCount.add(mat);
- }
+ int count = limitCount(mat);
+ if (belowSeaLevel) {
+ results.underWaterBlockCount.addAndGet(count);
+ results.uwCount.add(mat);
+ } else {
+ results.rawBlockCount.addAndGet(count);
+ results.mdCount.add(mat);
+ }
}
/**
@@ -180,7 +180,7 @@ private Queue> getChunksToScan(Island island) {
* @return the island
*/
public Island getIsland() {
- return island;
+ return island;
}
/**
@@ -189,7 +189,7 @@ public Island getIsland() {
* @return the r
*/
public CompletableFuture getR() {
- return r;
+ return r;
}
/**
@@ -258,7 +258,7 @@ private List getReport() {
* @return the results
*/
public Results getResults() {
- return results;
+ return results;
}
/**
@@ -268,13 +268,13 @@ public Results getResults() {
* @return value of a material
*/
private int getValue(Material md) {
- Integer value = addon.getBlockConfig().getValue(island.getWorld(), md);
- if (value == null) {
- // Not in config
- results.ncCount.add(md);
- return 0;
- }
- return value;
+ Integer value = addon.getBlockConfig().getValue(island.getWorld(), md);
+ if (value == null) {
+ // Not in config
+ results.ncCount.add(md);
+ return 0;
+ }
+ return value;
}
/**
@@ -286,44 +286,44 @@ private int getValue(Material md) {
* there is no island nether
*/
private CompletableFuture> getWorldChunk(Environment env, Queue> pairList) {
- if (worlds.containsKey(env)) {
- CompletableFuture> r2 = new CompletableFuture<>();
- List chunkList = new ArrayList<>();
- World world = worlds.get(env);
- // Get the chunk, and then coincidentally check the RoseStacker
- loadChunks(r2, world, pairList, chunkList);
- return r2;
- }
- return CompletableFuture.completedFuture(Collections.emptyList());
+ if (worlds.containsKey(env)) {
+ CompletableFuture> r2 = new CompletableFuture<>();
+ List chunkList = new ArrayList<>();
+ World world = worlds.get(env);
+ // Get the chunk, and then coincidentally check the RoseStacker
+ loadChunks(r2, world, pairList, chunkList);
+ return r2;
+ }
+ return CompletableFuture.completedFuture(Collections.emptyList());
}
private void loadChunks(CompletableFuture> r2, World world, Queue> pairList,
- List chunkList) {
- if (pairList.isEmpty()) {
- r2.complete(chunkList);
- return;
- }
- Pair p = pairList.poll();
- Util.getChunkAtAsync(world, p.x, p.z, world.getEnvironment().equals(Environment.NETHER)).thenAccept(chunk -> {
- if (chunk != null) {
- chunkList.add(chunk);
- roseStackerCheck(chunk);
- }
- loadChunks(r2, world, pairList, chunkList); // Iteration
- });
+ List chunkList) {
+ if (pairList.isEmpty()) {
+ r2.complete(chunkList);
+ return;
+ }
+ Pair p = pairList.poll();
+ Util.getChunkAtAsync(world, p.x, p.z, world.getEnvironment().equals(Environment.NETHER)).thenAccept(chunk -> {
+ if (chunk != null) {
+ chunkList.add(chunk);
+ roseStackerCheck(chunk);
+ }
+ loadChunks(r2, world, pairList, chunkList); // Iteration
+ });
}
private void roseStackerCheck(Chunk chunk) {
- if (addon.isRoseStackersEnabled()) {
- RoseStackerAPI.getInstance().getStackedBlocks(Collections.singletonList(chunk)).forEach(e -> {
- // Blocks below sea level can be scored differently
- boolean belowSeaLevel = seaHeight > 0 && e.getLocation().getY() <= seaHeight;
- // Check block once because the base block will be counted in the chunk snapshot
- for (int _x = 0; _x < e.getStackSize() - 1; _x++) {
- checkBlock(e.getBlock().getType(), belowSeaLevel);
- }
- });
- }
+ if (addon.isRoseStackersEnabled()) {
+ RoseStackerAPI.getInstance().getStackedBlocks(Collections.singletonList(chunk)).forEach(e -> {
+ // Blocks below sea level can be scored differently
+ boolean belowSeaLevel = seaHeight > 0 && e.getLocation().getY() <= seaHeight;
+ // Check block once because the base block will be counted in the chunk snapshot
+ for (int _x = 0; _x < e.getStackSize() - 1; _x++) {
+ checkBlock(e.getBlock().getType(), belowSeaLevel);
+ }
+ });
+ }
}
/**
@@ -334,17 +334,17 @@ private void roseStackerCheck(Chunk chunk) {
* @return value of the block if can be counted
*/
private int limitCount(Material md) {
- if (limitCount.containsKey(md)) {
- int count = limitCount.get(md);
- if (count > 0) {
- limitCount.put(md, --count);
- return getValue(md);
- } else {
- results.ofCount.add(md);
- return 0;
- }
- }
- return getValue(md);
+ if (limitCount.containsKey(md)) {
+ int count = limitCount.get(md);
+ if (count > 0) {
+ limitCount.put(md, --count);
+ return getValue(md);
+ } else {
+ results.ofCount.add(md);
+ return 0;
+ }
+ }
+ return getValue(md);
}
/**
@@ -579,7 +579,7 @@ public void tidyUp() {
* @return the zeroIsland
*/
boolean isNotZeroIsland() {
- return !zeroIsland;
+ return !zeroIsland;
}
public void scanIsland(Pipeliner pipeliner) {
@@ -608,57 +608,52 @@ public void scanIsland(Pipeliner pipeliner) {
// Done
pipeliner.getInProcessQueue().remove(this);
// Chunk finished
- // This was the last chunk
- handleStackedBlocks();
- handleChests();
- long checkTime = System.currentTimeMillis();
- finishTask = Bukkit.getScheduler().runTaskTimer(addon.getPlugin(), () -> {
- // Check every half second if all the chests and stacks have been cleared
- if ((chestBlocks.isEmpty() && stackedBlocks.isEmpty())
- || System.currentTimeMillis() - checkTime > MAX_AMOUNT) {
- this.tidyUp();
- this.getR().complete(getResults());
- finishTask.cancel();
- }
- }, 0, 10L);
-
+ // This was the last chunk. Handle stacked blocks, then chests and exit
+ handleStackedBlocks().thenCompose(v -> handleChests()).thenRun(() -> {
+ this.tidyUp();
+ this.getR().complete(getResults());
+ });
}
});
}
- private void handleChests() {
- Iterator it = chestBlocks.iterator();
- while (it.hasNext()) {
- Chunk v = it.next();
- Util.getChunkAtAsync(v.getWorld(), v.getX(), v.getZ()).thenAccept(c -> {
+ private CompletableFuture handleChests() {
+ List> futures = new ArrayList<>();
+ for (Chunk v : chestBlocks) {
+ CompletableFuture future = Util.getChunkAtAsync(v.getWorld(), v.getX(), v.getZ()).thenAccept(c -> {
scanChests(c);
- it.remove();
});
+ futures.add(future);
}
+ // Return a CompletableFuture that completes when all futures are done
+ return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
}
- private void handleStackedBlocks() {
- // Deal with any stacked blocks
- Iterator it = stackedBlocks.iterator();
- while (it.hasNext()) {
- Location v = it.next();
- Util.getChunkAtAsync(v).thenAccept(c -> {
- Block stackedBlock = v.getBlock();
- boolean belowSeaLevel = seaHeight > 0 && v.getBlockY() <= seaHeight;
- if (WildStackerAPI.getWildStacker().getSystemManager().isStackedBarrel(stackedBlock)) {
- StackedBarrel barrel = WildStackerAPI.getStackedBarrel(stackedBlock);
- int barrelAmt = WildStackerAPI.getBarrelAmount(stackedBlock);
- for (int _x = 0; _x < barrelAmt; _x++) {
- checkBlock(barrel.getType(), belowSeaLevel);
- }
- } else if (WildStackerAPI.getWildStacker().getSystemManager().isStackedSpawner(stackedBlock)) {
- int spawnerAmt = WildStackerAPI.getSpawnersAmount((CreatureSpawner) stackedBlock.getState());
- for (int _x = 0; _x < spawnerAmt; _x++) {
- checkBlock(stackedBlock.getType(), belowSeaLevel);
- }
- }
- it.remove();
- });
- }
+ private CompletableFuture handleStackedBlocks() {
+ // Deal with any stacked blocks
+ List> futures = new ArrayList<>();
+ for (Location v : stackedBlocks) {
+ CompletableFuture future = Util.getChunkAtAsync(v).thenAccept(c -> {
+ Block stackedBlock = v.getBlock();
+ boolean belowSeaLevel = seaHeight > 0 && v.getBlockY() <= seaHeight;
+ if (WildStackerAPI.getWildStacker().getSystemManager().isStackedBarrel(stackedBlock)) {
+ StackedBarrel barrel = WildStackerAPI.getStackedBarrel(stackedBlock);
+ int barrelAmt = WildStackerAPI.getBarrelAmount(stackedBlock);
+ for (int _x = 0; _x < barrelAmt; _x++) {
+ checkBlock(barrel.getType(), belowSeaLevel);
+ }
+ } else if (WildStackerAPI.getWildStacker().getSystemManager().isStackedSpawner(stackedBlock)) {
+ int spawnerAmt = WildStackerAPI.getSpawnersAmount((CreatureSpawner) stackedBlock.getState());
+ for (int _x = 0; _x < spawnerAmt; _x++) {
+ checkBlock(stackedBlock.getType(), belowSeaLevel);
+ }
+ }
+ });
+ futures.add(future);
+ }
+ // Return a CompletableFuture that completes when all futures are done
+ return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
+
}
+
}
diff --git a/src/main/resources/addon.yml b/src/main/resources/addon.yml
index d7e5b6d..9edbf7d 100755
--- a/src/main/resources/addon.yml
+++ b/src/main/resources/addon.yml
@@ -2,7 +2,7 @@ name: Level
main: world.bentobox.level.Level
version: ${version}${build.number}
icon: DIAMOND
-api-version: 1.16.5
+api-version: 2.4.0
authors: tastybento
diff --git a/src/main/resources/locales/zh-CN.yml b/src/main/resources/locales/zh-CN.yml
old mode 100755
new mode 100644
index d015525..e9283e0
--- a/src/main/resources/locales/zh-CN.yml
+++ b/src/main/resources/locales/zh-CN.yml
@@ -1,79 +1,93 @@
----
admin:
level:
- parameters: ""
+ parameters:
description: 计算指定玩家的岛屿等级
sethandicap:
- parameters: " "
- description: 设置偏差值,通常用于抵消初始岛屿等级,来保证岛屿等级从零开始。实际岛屿等级 - = 最终的岛屿等级
- changed: "&a 岛屿的偏差值从 [number] 更改为 [new_number]"
- invalid-level: "&c 偏差值无效,请使用整数"
+ parameters:
+ description: 设置偏差值, 通常用于抵消初始岛屿等级, 来保证岛屿等级从零开始. 实际岛屿等级 - = 最终的岛屿等级
+ changed: '&a岛屿的偏差值从[number]更改为[new_number]'
+ invalid-level: '&c偏差值无效, 请使用整数'
levelstatus:
description: 显示等级计算队列中的岛屿
- islands-in-queue: "&a 列队中的岛屿:[number]"
+ islands-in-queue: '&a列队中的岛屿: [number]'
top:
description: 显示前十名
- unknown-world: "&c 未知的世界!"
- display: "&f[rank]. &a[name] &7- &b[level]"
+ unknown-world: '&c未知的世界!'
+ display: '&f[rank]. &a[name] &7- &b[level]'
remove:
description: 将玩家移出前十名
- parameters: ""
+ parameters:
+ stats:
+ description: 显示该服务器上岛屿的统计数据
+ title: 服务器岛屿数据
+ world: '&a[name]'
+ no-data: '&c没有数据.'
+ average-level: '平均岛屿等级: [number]'
+ median-level: '中位数岛屿等级: [number]'
+ mode-level: '众数岛屿等级: [number]'
+ highest-level: '最高岛屿等级: [number]'
+ lowest-level: '最低岛屿等级: [number]'
+ distribution: '岛屿等级分布:'
+ islands: 个岛屿
island:
level:
- parameters: "[player]"
- description: 计算你或指定玩家 [player] 的岛屿等级
- calculating: "&a 等级计算中..."
- estimated-wait: "&a 预计等待时间:[number] 秒"
- in-queue: "&a 你处于队列中第 [number] 个"
- island-level-is: "&a 岛屿等级为 &b[level]"
- required-points-to-next-level: "&a 还需 [points] 点数才能到达下一级"
- deaths: "&c([number] 次死亡)"
- cooldown: "&c 还需等待 &b[time] &c秒才能再次使用该指令"
- in-progress: "&6 岛级等级正在计算中..."
- time-out: "&c 等级计算超时。请稍后再试"
+ parameters: '[player]'
+ description: 计算你或指定玩家[player]的岛屿等级
+ calculating: '&a等级计算中...'
+ estimated-wait: '&a预计等待时间: [number]秒'
+ in-queue: '&a你处于队列中第[number]个'
+ island-level-is: '&a岛屿等级为: &b[level]'
+ required-points-to-next-level: '&a还需[points]点数才能到达下一级'
+ deaths: '&c([number]次死亡)'
+ cooldown: '&c还需等待&b[time]&c秒才能再次使用该指令'
+ in-progress: '&6岛屿等级正在计算中...'
+ time-out: '&c等级计算超时, 请稍后再试'
+
top:
description: 显示前十名
- gui-title: "&a 前十"
- gui-heading: "&6[name]: &B[rank]"
- island-level: "&b 等级 [level]"
- warp-to: "&a 正在传送到 [name] 的岛屿"
+ gui-title: '&a前十'
+ gui-heading: '&6[name]: &B[rank]'
+ island-level: '&b等级: [level]'
+ warp-to: '&a正在传送到[name]的岛屿'
+
level-details:
above-sea-level-blocks: 海平面以上的方块
spawners: 刷怪笼
underwater-blocks: 水下的方块
all-blocks: 所有方块
- no-island: "&c 没有岛屿!"
- names-island: "[name] 的岛屿"
- syntax: "[name] x [number]"
- hint: "&c 运行level指令查看方块报告"
+ no-island: '&c没有岛屿!'
+ names-island: '[name]的岛屿'
+ syntax: '[name] x [number]'
+ hint: '&c运行level指令查看方块报告'
+
level:
commands:
value:
- parameters: "[hand|]"
- description: 显示方块的价值。在末尾添加 'hand' 可显示手中方块的价值
+ parameters: '[hand|]'
+ description: 显示方块的价值. 在末尾添加'hand'可显示手中方块的价值
gui:
titles:
- top: "&0&l 岛屿排行榜"
- detail-panel: "&0&l [name] 的岛屿"
- value-panel: "&0&l 方块价值"
+ top: '&0&l岛屿排行榜'
+ detail-panel: '&0&l[name]的岛屿'
+ value-panel: '&0&l方块价值'
buttons:
island:
- empty: "&f&l 第 [name] 名"
- name: "&f&l [name]"
+ empty: '&f&l第[name]名'
+ name: '&f&l[name]'
description: |-
[owner]
[members]
[place]
[level]
- owners-island: "[player] 的岛屿"
- owner: "&7&l 岛主:&r&b [player]"
- members-title: "&7&l 成员:"
- member: "&b - [player]"
+ owners-island: '[player]的岛屿'
+ owner: '&7&l岛主: &r&b[player]'
+ members-title: '&7&l成员: '
+ member: '&b- [player]'
unknown: 未知
- place: "&7第 &7&o[number] &r&7名"
- level: "&7 等级: &o [number]"
+ place: '&7第&7&o[number]&r&7名'
+ level: '&7等级: &o[number]'
material:
- name: "&f&l [number] x [material]"
+ name: '&f&l [number] x [material]'
description: |-
[description]
[count]
@@ -81,83 +95,79 @@ level:
[calculated]
[limit]
[id]
- id: "&7 方块ID:&e [id]"
- value: "&7 方块价值:&e [number]"
- limit: "&7 方块限制:&e [number]"
- count: "&7 方块数量:&e [number]"
- calculated: "&7 计算值:&e [number]"
+ id: '&7方块ID: &e[id]'
+ value: '&7方块价值: &e[number]'
+ limit: '&7方块限制: &e[number]'
+ count: '&7方块数量: &e[number]'
+ calculated: '&7计算值: &e[number]'
all_blocks:
- name: "&f&l 所有方块"
- description: "&7 显示岛屿上所有的方块"
+ name: '&f&l所有方块'
+ description: '&7显示岛屿上所有的方块'
above_sea_level:
- name: "&f&l 海平面以上的方块"
- description: |-
- &7 只显示所有
- &7 海平面以上的方块
+ name: '&f&l海平面以上的方块'
+ description: '&7只显示所有海平面以上的方块'
underwater:
- name: "&f&l 海平面以下的方块"
- description: |-
- &7 只显示所有
- &7 海平面以下的方块
+ name: '&f&l海平面以下的方块'
+ description: 只显示所有海平面以下的方块
spawner:
- name: "&f&l 刷怪笼"
- description: "&7 只显示刷怪笼"
+ name: '&f&l刷怪笼'
+ description: '&7只显示刷怪笼'
filters:
name:
- name: "&f&l 按名称排序"
- description: "&7 通过名称排序所有的方块"
+ name: '&f&l按名称排序'
+ description: '&7通过名称排序所有的方块'
value:
- name: "&f&l 按价值排序"
- description: "&7 通过价值排序所有的方块"
+ name: '&f&l按价值排序'
+ description: '&7通过价值排序所有的方块'
count:
- name: "&f&l 按数量排序"
- description: "&7 通过数量排序所有方块"
+ name: '&f&l按数量排序'
+ description: '&7通过数量排序所有方块'
value:
- name: "&f&l [material]"
+ name: '&f&l[material]'
description: |-
[description]
[value]
[underwater]
[limit]
[id]
- id: "&7 方块ID:&e [id]"
- value: "&7 方块价值:&e [number]"
- underwater: "&7 海平面以下方块的价值:&e [number]"
- limit: "&7 方块限制:&e [number]"
+ id: '&7方块ID: &e[id]'
+ value: '&7方块价值: &e[number]'
+ underwater: '&7海平面以下方块的价值: &e[number]'
+ limit: '&7方块限制: &e[number]'
previous:
- name: "&f&l 上一页"
- description: "&7 切换到第 [number] 页"
+ name: '&f&l上一页'
+ description: '&7切换到第[number]页'
next:
- name: "&f&l 下一页"
- description: "&7 切换到第 [number] 页"
+ name: '&f&l下一页'
+ description: '&7切换到第[number]页'
search:
- name: "&f&l 搜索"
- description: "&7 搜索特定的内容"
- search: "&b 搜索值:[value]"
+ name: '&f&l搜索'
+ description: '&7搜索特定的内容'
+ search: '&b搜索值: [value]'
tips:
- click-to-view: "&e 点击 &7 查看"
- click-to-previous: "&e 点击 &7 查看上一页"
- click-to-next: "&e 点击 &7 查看下一页"
- click-to-select: "&e 点击 &7 选择"
- left-click-to-cycle-up: "&e 左键点击 &7 向上循环"
- right-click-to-cycle-down: "&e 右键点击 &7 向下循环"
- left-click-to-change: "&e 左键点击 &7 编辑"
- right-click-to-clear: "&e 右键点击 &7 清除"
- click-to-asc: "&e 点击 &7 以升序排序"
- click-to-desc: "&e 点击 &7 以降序排序"
- click-to-warp: "&e 点击 &7 去岛屿传送点"
- click-to-visit: "&e 点击 &7 参观"
- right-click-to-visit: "&e 右键点击 &7 查看"
+ click-to-view: '&e点击 &7查看'
+ click-to-previous: '&e点击 &7查看上一页'
+ click-to-next: '&e点击 &7查看下一页'
+ click-to-select: '&e点击 &7选择'
+ left-click-to-cycle-up: '&e左键 &7向上循环'
+ right-click-to-cycle-down: '&e右键 &7向下循环'
+ left-click-to-change: '&e左键 &7编辑'
+ right-click-to-clear: '&e右键 &7清除'
+ click-to-asc: '&e点击 &7以升序排序'
+ click-to-desc: '&e点击 &7以降序排序'
+ click-to-warp: '&e点击 &7去岛屿传送点'
+ click-to-visit: '&e点击 &7参观'
+ right-click-to-visit: '&e右键 &7查看'
conversations:
- prefix: "&l&6 [BentoBox]: &r"
- no-data: "&c 运行level指令查看方块报告"
+ prefix: '&l&6[BentoBox]: &r'
+ no-data: '&c运行level指令查看方块报告'
cancel-string: cancel
exit-string: cancel, exit, quit
- write-search: "&e 请输入要搜索的值. (输入 'cancel' 退出)"
- search-updated: "&a 搜索值已更新"
- cancelled: "&c 对话已取消!"
- no-value: "&c 这件物品一文不值"
- unknown-item: "&c 物品 '[material]' 在游戏中不存在"
- value: "&7 物品 '[material]' 的价值:&e[value]"
- value-underwater: "&7 物品 '[material]' 在海平面以下的价值:&e[value]"
- empty-hand: "&c 你的手中没有拿着方块"
+ write-search: '&e请输入要搜索的值. (输入''cancel''退出)'
+ search-updated: '&a搜索值已更新'
+ cancelled: '&c对话已取消'
+ no-value: '&c这件物品一文不值'
+ unknown-item: '&c物品''[material]''在游戏中不存在'
+ value: '&7物品''[material]''的价值: &e[value]'
+ value-underwater: '&7物品''[material]''在海平面以下的价值: &e[value]'
+ empty-hand: '&c你的手中没有拿着方块'
diff --git a/src/test/java/world/bentobox/level/LevelTest.java b/src/test/java/world/bentobox/level/LevelTest.java
index 5f8074a..7da610f 100644
--- a/src/test/java/world/bentobox/level/LevelTest.java
+++ b/src/test/java/world/bentobox/level/LevelTest.java
@@ -61,6 +61,7 @@
import world.bentobox.bentobox.managers.IslandWorldManager;
import world.bentobox.bentobox.managers.IslandsManager;
import world.bentobox.bentobox.managers.PlaceholdersManager;
+import world.bentobox.bentobox.util.Util;
import world.bentobox.level.config.BlockConfig;
import world.bentobox.level.config.ConfigSettings;
import world.bentobox.level.listeners.IslandActivitiesListeners;
@@ -72,7 +73,7 @@
*/
@SuppressWarnings("deprecation")
@RunWith(PowerMockRunner.class)
-@PrepareForTest({ Bukkit.class, BentoBox.class, User.class })
+@PrepareForTest({ Bukkit.class, BentoBox.class, User.class, Util.class })
public class LevelTest {
private static File jFile;
@@ -144,7 +145,7 @@ public static void beforeClass() throws IOException {
/**
* @throws java.lang.Exception
*/
- @Before
+ @Before
public void setUp() throws Exception {
// Set up plugin
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
@@ -189,6 +190,11 @@ public void setUp() throws Exception {
when(Bukkit.getServer()).thenReturn(server);
when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger());
when(Bukkit.getPluginManager()).thenReturn(mock(PluginManager.class));
+ when(Bukkit.getBukkitVersion()).thenReturn("");
+
+ // Util
+ PowerMockito.mockStatic(Util.class, Mockito.RETURNS_MOCKS);
+ when(Util.inTest()).thenReturn(true);
// Addon
addon = new Level();
@@ -221,7 +227,6 @@ public void setUp() throws Exception {
when(fm.getFlags()).thenReturn(Collections.emptyList());
// Bukkit
- PowerMockito.mockStatic(Bukkit.class);
when(Bukkit.getScheduler()).thenReturn(scheduler);
ItemMeta meta = mock(ItemMeta.class);
ItemFactory itemFactory = mock(ItemFactory.class);
diff --git a/src/test/java/world/bentobox/level/LevelsManagerTest.java b/src/test/java/world/bentobox/level/LevelsManagerTest.java
index 551c573..c0be60c 100644
--- a/src/test/java/world/bentobox/level/LevelsManagerTest.java
+++ b/src/test/java/world/bentobox/level/LevelsManagerTest.java
@@ -4,6 +4,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -165,6 +166,7 @@ public void setUp() throws Exception {
when(im.hasIsland(eq(world), any(UUID.class))).thenReturn(true);
when(im.getIsland(world, uuid)).thenReturn(island);
when(im.getIslandById(anyString())).thenReturn(Optional.of(island));
+ when(im.getIslandById(anyString(), eq(false))).thenReturn(Optional.of(island));
// Player
when(player.getUniqueId()).thenReturn(uuid);
@@ -395,8 +397,8 @@ public void testLoadTopTens() {
lm.loadTopTens();
PowerMockito.verifyStatic(Bukkit.class); // 1
Bukkit.getScheduler();
- verify(scheduler).runTaskAsynchronously(eq(plugin), task.capture());
- task.getValue().run();
+ verify(scheduler).runTaskAsynchronously(eq(plugin), task.capture()); // Capture the task in the scheduler
+ task.getValue().run(); // run it
verify(addon).log("Generating rankings");
verify(addon).log("Generated rankings for bskyblock-world");
diff --git a/src/test/java/world/bentobox/level/PlaceholderManagerTest.java b/src/test/java/world/bentobox/level/PlaceholderManagerTest.java
index 56f0a1d..10bf0d0 100644
--- a/src/test/java/world/bentobox/level/PlaceholderManagerTest.java
+++ b/src/test/java/world/bentobox/level/PlaceholderManagerTest.java
@@ -9,9 +9,9 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
@@ -138,7 +138,7 @@ public void setUp() throws Exception {
when(im.getIsland(any(World.class), any(User.class))).thenReturn(island);
when(im.getIslandAt(any(Location.class))).thenReturn(Optional.of(island));
when(im.getIslandById(anyString())).thenAnswer((Answer>) invocation -> Optional.of(islands.get(invocation.getArgument(0, String.class))));
- when(im.getIslands(any(), any(UUID.class))).thenReturn(new HashSet<>(islands.values()));
+ when(im.getIslands(any(), any(UUID.class))).thenReturn(new ArrayList<>(islands.values()));
when(addon.getIslands()).thenReturn(im);
// Levels Manager
diff --git a/src/test/java/world/bentobox/level/commands/AdminTopRemoveCommandTest.java b/src/test/java/world/bentobox/level/commands/AdminTopRemoveCommandTest.java
index 9e82384..8a49c25 100644
--- a/src/test/java/world/bentobox/level/commands/AdminTopRemoveCommandTest.java
+++ b/src/test/java/world/bentobox/level/commands/AdminTopRemoveCommandTest.java
@@ -10,7 +10,7 @@
import static org.mockito.Mockito.when;
import java.util.Collections;
-import java.util.Set;
+import java.util.List;
import java.util.UUID;
import org.bukkit.Bukkit;
@@ -120,8 +120,8 @@ public void setUp() {
when(island.getOwner()).thenReturn(uuid);
// Island Manager
when(plugin.getIslands()).thenReturn(im);
- when(im.getIslands(any(), any(User.class))).thenReturn(Set.of(island));
- when(im.getIslands(any(), any(UUID.class))).thenReturn(Set.of(island));
+ when(im.getIslands(any(), any(User.class))).thenReturn(List.of(island));
+ when(im.getIslands(any(), any(UUID.class))).thenReturn(List.of(island));
// Bukkit
PowerMockito.mockStatic(Bukkit.class);