mirror of
https://github.com/BentoBoxWorld/Level.git
synced 2024-11-28 21:55:14 +01:00
commit
45cfe39a76
4
pom.xml
4
pom.xml
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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]));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
212
src/main/resources/locales/zh-CN.yml
Executable file → Normal 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你的手中没有拿着方块'
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user