Merge pull request #318 from BentoBoxWorld/develop

Release 2.14.0
This commit is contained in:
tastybento 2024-06-30 14:58:10 -07:00 committed by GitHub
commit 45cfe39a76
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 298 additions and 285 deletions

View File

@ -59,7 +59,7 @@
<powermock.version>2.0.9</powermock.version>
<!-- More visible way how to change dependency versions -->
<spigot.version>1.20.4-R0.1-SNAPSHOT</spigot.version>
<bentobox.version>2.0.0-SNAPSHOT</bentobox.version>
<bentobox.version>2.4.0-SNAPSHOT</bentobox.version>
<!-- Warps addon version -->
<warps.version>1.12.0</warps.version>
<!-- Visit addon version -->
@ -71,7 +71,7 @@
<!-- Do not change unless you want different name for local builds. -->
<build.number>-LOCAL</build.number>
<!-- This allows to change between versions. -->
<build.version>2.13.0</build.version>
<build.version>2.14.0</build.version>
<sonar.projectKey>BentoBoxWorld_Level</sonar.projectKey>
<sonar.organization>bentobox-world</sonar.organization>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>

View File

@ -39,12 +39,12 @@ public class LevelsManager {
private static final TreeMap<BigInteger, String> 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<World, CachedData> 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 class LevelsManager {
* @return initial level of island
*/
public long getInitialLevel(Island island) {
return getLevelsData(island).getInitialLevel();
return getLevelsData(island).getInitialLevel();
}
/**
@ -252,7 +252,7 @@ public class LevelsManager {
* 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 class LevelsManager {
*/
@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 class LevelsManager {
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 class LevelsManager {
* @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 @@ public class LevelsManager {
* @param uniqueId - id of island
*/
public void deleteIsland(String uniqueId) {
levelsCache.remove(uniqueId);
handler.deleteID(uniqueId);
levelsCache.remove(uniqueId);
handler.deleteID(uniqueId);
}
}

View File

@ -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<Results> 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 @@ public class IslandLevelCalculator {
* @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 @@ public class IslandLevelCalculator {
* @return the island
*/
public Island getIsland() {
return island;
return island;
}
/**
@ -189,7 +189,7 @@ public class IslandLevelCalculator {
* @return the r
*/
public CompletableFuture<Results> getR() {
return r;
return r;
}
/**
@ -258,7 +258,7 @@ public class IslandLevelCalculator {
* @return the results
*/
public Results getResults() {
return results;
return results;
}
/**
@ -268,13 +268,13 @@ public class IslandLevelCalculator {
* @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 @@ public class IslandLevelCalculator {
* there is no island nether
*/
private CompletableFuture<List<Chunk>> getWorldChunk(Environment env, Queue<Pair<Integer, Integer>> pairList) {
if (worlds.containsKey(env)) {
CompletableFuture<List<Chunk>> r2 = new CompletableFuture<>();
List<Chunk> 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<List<Chunk>> r2 = new CompletableFuture<>();
List<Chunk> 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<List<Chunk>> r2, World world, Queue<Pair<Integer, Integer>> pairList,
List<Chunk> chunkList) {
if (pairList.isEmpty()) {
r2.complete(chunkList);
return;
}
Pair<Integer, Integer> 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<Chunk> chunkList) {
if (pairList.isEmpty()) {
r2.complete(chunkList);
return;
}
Pair<Integer, Integer> 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 @@ public class IslandLevelCalculator {
* @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 class IslandLevelCalculator {
* @return the zeroIsland
*/
boolean isNotZeroIsland() {
return !zeroIsland;
return !zeroIsland;
}
public void scanIsland(Pipeliner pipeliner) {
@ -608,57 +608,52 @@ public class IslandLevelCalculator {
// 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<Chunk> it = chestBlocks.iterator();
while (it.hasNext()) {
Chunk v = it.next();
Util.getChunkAtAsync(v.getWorld(), v.getX(), v.getZ()).thenAccept(c -> {
private CompletableFuture<Void> handleChests() {
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (Chunk v : chestBlocks) {
CompletableFuture<Void> 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<Location> 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<Void> handleStackedBlocks() {
// Deal with any stacked blocks
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (Location v : stackedBlocks) {
CompletableFuture<Void> 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]));
}
}

View File

@ -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

212
src/main/resources/locales/zh-CN.yml Executable file → Normal file
View File

@ -1,79 +1,93 @@
---
admin:
level:
parameters: "<player>"
parameters: <player>
description: 计算指定玩家的岛屿等级
sethandicap:
parameters: "<player> <handicap>"
description: 设置偏差值,通常用于抵消初始岛屿等级,来保证岛屿等级从零开始。实际岛屿等级 - <handicap> = 最终的岛屿等级
changed: "&a 岛屿的偏差值从 [number] 更改为 [new_number]"
invalid-level: "&c 偏差值无效,请使用整数"
parameters: <player> <handicap>
description: 设置偏差值, 通常用于抵消初始岛屿等级, 来保证岛屿等级从零开始. 实际岛屿等级 - <handicap> = 最终的岛屿等级
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: "<player>"
parameters: <player>
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|<material>]"
description: 显示方块的价值。在末尾添加 'hand' 可显示手中方块的价值
parameters: '[hand|<material>]'
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你的手中没有拿着方块'

View File

@ -61,6 +61,7 @@ import world.bentobox.bentobox.managers.FlagsManager;
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 @@ import world.bentobox.level.listeners.JoinLeaveListener;
*/
@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 class LevelTest {
/**
* @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 class LevelTest {
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 class LevelTest {
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);

View File

@ -4,6 +4,7 @@ import static org.junit.Assert.assertEquals;
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 class LevelsManagerTest {
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 class LevelsManagerTest {
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");

View File

@ -9,9 +9,9 @@ import static org.mockito.Mockito.mock;
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 class PlaceholderManagerTest {
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<Optional<Island>>) 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

View File

@ -10,7 +10,7 @@ import static org.mockito.Mockito.verify;
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 class AdminTopRemoveCommandTest {
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);