mirror of
https://github.com/BentoBoxWorld/Level.git
synced 2024-12-24 01:58:21 +01:00
Release 2.7.2 (#233)
* Version 2.7.2 * Use Java 9's takeWhile * Added placeholder %Level_[gamemode]_rank_value Fixes https://github.com/BentoBoxWorld/Level/issues/228 * No save on disable (#231) * Release 2.6.4 * Remove saving to database on disable. https://github.com/BentoBoxWorld/Level/issues/229 First, the top ten tables are never actually used or loaded. They are created in memory by loading the island levels. So there is no reason to keep saving them. Second, the island level data is saved every time it is changed, so there is no need to save all of the cache on exit. * Fixes tests * Rosestacker (#232) * Add support for RoseStacker 1.3.0 * Made plugin a Pladdon.
This commit is contained in:
parent
389d06d0a2
commit
4a4794f771
39
pom.xml
39
pom.xml
@ -65,7 +65,7 @@
|
|||||||
<!-- Do not change unless you want different name for local builds. -->
|
<!-- Do not change unless you want different name for local builds. -->
|
||||||
<build.number>-LOCAL</build.number>
|
<build.number>-LOCAL</build.number>
|
||||||
<!-- This allows to change between versions. -->
|
<!-- This allows to change between versions. -->
|
||||||
<build.version>2.7.0</build.version>
|
<build.version>2.7.2</build.version>
|
||||||
<sonar.projectKey>BentoBoxWorld_Level</sonar.projectKey>
|
<sonar.projectKey>BentoBoxWorld_Level</sonar.projectKey>
|
||||||
<sonar.organization>bentobox-world</sonar.organization>
|
<sonar.organization>bentobox-world</sonar.organization>
|
||||||
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
|
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
|
||||||
@ -111,30 +111,6 @@
|
|||||||
<build.number></build.number>
|
<build.number></build.number>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
|
||||||
<id>sonar</id>
|
|
||||||
<properties>
|
|
||||||
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
|
|
||||||
<sonar.organization>bentobox-world</sonar.organization>
|
|
||||||
</properties>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.sonarsource.scanner.maven</groupId>
|
|
||||||
<artifactId>sonar-maven-plugin</artifactId>
|
|
||||||
<version>3.6.0.1398</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>verify</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>sonar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
@ -155,6 +131,11 @@
|
|||||||
<id>jitpack.io</id>
|
<id>jitpack.io</id>
|
||||||
<url>https://jitpack.io</url>
|
<url>https://jitpack.io</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
<!-- RoseStacker repo -->
|
||||||
|
<repository>
|
||||||
|
<id>rosewood-repo</id>
|
||||||
|
<url>https://repo.rosewooddev.io/repository/public/</url>
|
||||||
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -195,6 +176,7 @@
|
|||||||
<groupId>com.github.OmerBenGera</groupId>
|
<groupId>com.github.OmerBenGera</groupId>
|
||||||
<artifactId>WildStackerAPI</artifactId>
|
<artifactId>WildStackerAPI</artifactId>
|
||||||
<version>b18</version>
|
<version>b18</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- Static analysis -->
|
<!-- Static analysis -->
|
||||||
<!-- We are using Eclipse's annotations. If you're using IDEA, update
|
<!-- We are using Eclipse's annotations. If you're using IDEA, update
|
||||||
@ -209,6 +191,13 @@
|
|||||||
<groupId>com.github.DeadSilenceIV</groupId>
|
<groupId>com.github.DeadSilenceIV</groupId>
|
||||||
<artifactId>AdvancedChestsAPI</artifactId>
|
<artifactId>AdvancedChestsAPI</artifactId>
|
||||||
<version>1.8</version>
|
<version>1.8</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>dev.rosewood</groupId>
|
||||||
|
<artifactId>rosestacker</artifactId>
|
||||||
|
<version>1.3.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
package world.bentobox.level;
|
|
||||||
|
|
||||||
import java.util.Spliterator;
|
|
||||||
import java.util.Spliterators;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Java 8 version of Java 9's forWhile
|
|
||||||
* https://www.baeldung.com/java-break-stream-foreach
|
|
||||||
* @author tastybento
|
|
||||||
*
|
|
||||||
* @param <T>
|
|
||||||
*/
|
|
||||||
public class CustomSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
|
|
||||||
|
|
||||||
private Spliterator<T> splitr;
|
|
||||||
private Predicate<T> predicate;
|
|
||||||
private boolean isMatched = true;
|
|
||||||
|
|
||||||
public CustomSpliterator(Spliterator<T> splitr, Predicate<T> predicate) {
|
|
||||||
super(splitr.estimateSize(), 0);
|
|
||||||
this.splitr = splitr;
|
|
||||||
this.predicate = predicate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized boolean tryAdvance(Consumer<? super T> consumer) {
|
|
||||||
boolean hadNext = splitr.tryAdvance(elem -> {
|
|
||||||
if (predicate.test(elem) && isMatched) {
|
|
||||||
consumer.accept(elem);
|
|
||||||
} else {
|
|
||||||
isMatched = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return hadNext && isMatched;
|
|
||||||
}
|
|
||||||
}
|
|
@ -36,6 +36,7 @@ import world.bentobox.level.config.ConfigSettings;
|
|||||||
import world.bentobox.level.listeners.IslandActivitiesListeners;
|
import world.bentobox.level.listeners.IslandActivitiesListeners;
|
||||||
import world.bentobox.level.listeners.JoinLeaveListener;
|
import world.bentobox.level.listeners.JoinLeaveListener;
|
||||||
import world.bentobox.level.objects.LevelsData;
|
import world.bentobox.level.objects.LevelsData;
|
||||||
|
import world.bentobox.level.objects.TopTenData;
|
||||||
import world.bentobox.level.requests.LevelRequestHandler;
|
import world.bentobox.level.requests.LevelRequestHandler;
|
||||||
import world.bentobox.level.requests.TopTenRequestHandler;
|
import world.bentobox.level.requests.TopTenRequestHandler;
|
||||||
|
|
||||||
@ -56,6 +57,7 @@ public class Level extends Addon implements Listener {
|
|||||||
private LevelsManager manager;
|
private LevelsManager manager;
|
||||||
private boolean stackersEnabled;
|
private boolean stackersEnabled;
|
||||||
private boolean advChestEnabled;
|
private boolean advChestEnabled;
|
||||||
|
private boolean roseStackersEnabled;
|
||||||
private final List<GameModeAddon> registeredGameModes = new ArrayList<>();
|
private final List<GameModeAddon> registeredGameModes = new ArrayList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -105,7 +107,7 @@ public class Level extends Addon implements Listener {
|
|||||||
// Check if WildStackers is enabled on the server
|
// Check if WildStackers is enabled on the server
|
||||||
// I only added support for counting blocks into the island level
|
// I only added support for counting blocks into the island level
|
||||||
// Someone else can PR if they want spawners added to the Leveling system :)
|
// Someone else can PR if they want spawners added to the Leveling system :)
|
||||||
stackersEnabled = Bukkit.getPluginManager().getPlugin("WildStacker") != null;
|
stackersEnabled = Bukkit.getPluginManager().isPluginEnabled("WildStacker");
|
||||||
if (stackersEnabled) {
|
if (stackersEnabled) {
|
||||||
log("Hooked into WildStackers.");
|
log("Hooked into WildStackers.");
|
||||||
}
|
}
|
||||||
@ -121,6 +123,11 @@ public class Level extends Addon implements Listener {
|
|||||||
advChestEnabled = false;
|
advChestEnabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Check if RoseStackers is enabled
|
||||||
|
roseStackersEnabled = Bukkit.getPluginManager().isPluginEnabled("RoseStacker");
|
||||||
|
if (roseStackersEnabled) {
|
||||||
|
log("Hooked into RoseStackers.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -206,6 +213,9 @@ public class Level extends Addon implements Listener {
|
|||||||
gm.getDescription().getName().toLowerCase() + "_top_value_" + i, u -> getRankLevel(gm.getOverWorld(), rank));
|
gm.getDescription().getName().toLowerCase() + "_top_value_" + i, u -> getRankLevel(gm.getOverWorld(), rank));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Personal rank
|
||||||
|
getPlugin().getPlaceholdersManager().registerPlaceholder(this,
|
||||||
|
gm.getDescription().getName().toLowerCase() + "_rank_value", u -> getRankValue(gm.getOverWorld(), u));
|
||||||
}
|
}
|
||||||
|
|
||||||
String getRankName(World world, int rank) {
|
String getRankName(World world, int rank) {
|
||||||
@ -228,8 +238,23 @@ public class Level extends Addon implements Listener {
|
|||||||
.orElse(null));
|
.orElse(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the rank of the player in a world
|
||||||
|
* @param world world
|
||||||
|
* @param user player
|
||||||
|
* @return rank where 1 is the top rank.
|
||||||
|
*/
|
||||||
|
String getRankValue(World world, User user) {
|
||||||
|
if (user == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
// Get the island level for this user
|
||||||
|
long level = getManager().getIslandLevel(world, user.getUniqueId());
|
||||||
|
return String.valueOf(getManager().getTopTenLists().getOrDefault(world, new TopTenData(world)).getTopTen().values().stream().filter(l -> l > level).count() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
String getVisitedIslandLevel(GameModeAddon gm, User user) {
|
String getVisitedIslandLevel(GameModeAddon gm, User user) {
|
||||||
if (!gm.inWorld(user.getLocation())) return "";
|
if (user == null || !gm.inWorld(user.getLocation())) return "";
|
||||||
return getIslands().getIslandAt(user.getLocation())
|
return getIslands().getIslandAt(user.getLocation())
|
||||||
.map(island -> getManager().getIslandLevelString(gm.getOverWorld(), island.getOwner()))
|
.map(island -> getManager().getIslandLevelString(gm.getOverWorld(), island.getOwner()))
|
||||||
.orElse("0");
|
.orElse("0");
|
||||||
@ -256,11 +281,6 @@ public class Level extends Addon implements Listener {
|
|||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
// Stop the pipeline
|
// Stop the pipeline
|
||||||
this.getPipeliner().stop();
|
this.getPipeliner().stop();
|
||||||
// Save player data and the top tens
|
|
||||||
if (manager != null) {
|
|
||||||
manager.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadBlockSettings() {
|
private void loadBlockSettings() {
|
||||||
@ -431,4 +451,11 @@ public class Level extends Addon implements Listener {
|
|||||||
return registeredGameModes.stream().map(GameModeAddon::getOverWorld).anyMatch(w -> Util.sameWorld(world, w));
|
return registeredGameModes.stream().map(GameModeAddon::getOverWorld).anyMatch(w -> Util.sameWorld(world, w));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the roseStackersEnabled
|
||||||
|
*/
|
||||||
|
public boolean isRoseStackersEnabled() {
|
||||||
|
return roseStackersEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,8 @@ import java.util.TreeMap;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.function.Predicate;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import java.util.stream.StreamSupport;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
@ -64,8 +62,6 @@ public class LevelsManager {
|
|||||||
private final Database<IslandLevels> handler;
|
private final Database<IslandLevels> handler;
|
||||||
// A cache of island levels.
|
// A cache of island levels.
|
||||||
private final Map<String, IslandLevels> levelsCache;
|
private final Map<String, IslandLevels> levelsCache;
|
||||||
|
|
||||||
private final Database<TopTenData> topTenHandler;
|
|
||||||
// Top ten lists
|
// Top ten lists
|
||||||
private final Map<World,TopTenData> topTenLists;
|
private final Map<World,TopTenData> topTenLists;
|
||||||
// Background
|
// Background
|
||||||
@ -79,8 +75,6 @@ public class LevelsManager {
|
|||||||
// Set up the database handler to store and retrieve data
|
// Set up the database handler to store and retrieve data
|
||||||
// Note that these are saved by the BentoBox database
|
// Note that these are saved by the BentoBox database
|
||||||
handler = new Database<>(addon, IslandLevels.class);
|
handler = new Database<>(addon, IslandLevels.class);
|
||||||
// Top Ten handler
|
|
||||||
topTenHandler = new Database<>(addon, TopTenData.class);
|
|
||||||
// Initialize the cache
|
// Initialize the cache
|
||||||
levelsCache = new HashMap<>();
|
levelsCache = new HashMap<>();
|
||||||
// Initialize top ten lists
|
// Initialize top ten lists
|
||||||
@ -181,8 +175,6 @@ public class LevelsManager {
|
|||||||
}
|
}
|
||||||
// Save result
|
// Save result
|
||||||
setIslandResults(island.getWorld(), island.getOwner(), r);
|
setIslandResults(island.getWorld(), island.getOwner(), r);
|
||||||
// Save top ten
|
|
||||||
addon.getManager().saveTopTen(island.getWorld());
|
|
||||||
// Save the island scan details
|
// Save the island scan details
|
||||||
result.complete(r);
|
result.complete(r);
|
||||||
});
|
});
|
||||||
@ -444,18 +436,7 @@ public class LevelsManager {
|
|||||||
.filter(e -> addon.getIslands().isOwner(world, e.getKey()))
|
.filter(e -> addon.getIslands().isOwner(world, e.getKey()))
|
||||||
.filter(l -> l.getValue() > 0)
|
.filter(l -> l.getValue() > 0)
|
||||||
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()));
|
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()));
|
||||||
return takeWhile(stream, x -> !x.getKey().equals(uuid)).map(Map.Entry::getKey).collect(Collectors.toList()).size() + 1;
|
return stream.takeWhile(x -> !x.getKey().equals(uuid)).map(Map.Entry::getKey).collect(Collectors.toList()).size() + 1;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Java 8's version of Java 9's takeWhile
|
|
||||||
* @param stream
|
|
||||||
* @param predicate
|
|
||||||
* @return stream
|
|
||||||
*/
|
|
||||||
public static <T> Stream<T> takeWhile(Stream<T> stream, Predicate<T> predicate) {
|
|
||||||
CustomSpliterator<T> customSpliterator = new CustomSpliterator<>(stream.spliterator(), predicate);
|
|
||||||
return StreamSupport.stream(customSpliterator, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -475,15 +456,14 @@ public class LevelsManager {
|
|||||||
void loadTopTens() {
|
void loadTopTens() {
|
||||||
topTenLists.clear();
|
topTenLists.clear();
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(addon.getPlugin(), () -> {
|
Bukkit.getScheduler().runTaskAsynchronously(addon.getPlugin(), () -> {
|
||||||
addon.log("Generating Top Ten Tables");
|
addon.log("Generating rankings");
|
||||||
handler.loadObjects().forEach(il -> {
|
handler.loadObjects().forEach(il -> {
|
||||||
if (il.getLevel() > 0) {
|
if (il.getLevel() > 0) {
|
||||||
addon.getIslands().getIslandById(il.getUniqueId()).ifPresent(i -> this.addToTopTen(i, il.getLevel()));
|
addon.getIslands().getIslandById(il.getUniqueId()).ifPresent(i -> this.addToTopTen(i, il.getLevel()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
topTenLists.keySet().forEach(w -> {
|
topTenLists.keySet().forEach(w -> {
|
||||||
addon.log("Loaded top ten for " + w.getName());
|
addon.log("Generated rankings for " + w.getName());
|
||||||
this.saveTopTen(w);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -497,27 +477,10 @@ public class LevelsManager {
|
|||||||
public void removeEntry(World world, UUID uuid) {
|
public void removeEntry(World world, UUID uuid) {
|
||||||
if (topTenLists.containsKey(world)) {
|
if (topTenLists.containsKey(world)) {
|
||||||
topTenLists.get(world).getTopTen().remove(uuid);
|
topTenLists.get(world).getTopTen().remove(uuid);
|
||||||
topTenHandler.saveObjectAsync(topTenLists.get(world));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves all player data and the top ten
|
|
||||||
*/
|
|
||||||
public void save() {
|
|
||||||
levelsCache.values().forEach(handler::saveObjectAsync);
|
|
||||||
topTenLists.values().forEach(topTenHandler::saveObjectAsync);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save the top ten for world
|
|
||||||
* @param world - world
|
|
||||||
*/
|
|
||||||
public void saveTopTen(World world) {
|
|
||||||
topTenHandler.saveObjectAsync(topTenLists.get(world));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set an initial island level
|
* Set an initial island level
|
||||||
* @param island - the island to set. Must have a non-null world
|
* @param island - the island to set. Must have a non-null world
|
||||||
|
@ -2,9 +2,12 @@ package world.bentobox.level.calculators;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.EnumMap;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
@ -24,7 +27,6 @@ import org.bukkit.block.data.BlockData;
|
|||||||
import org.bukkit.block.data.type.Slab;
|
import org.bukkit.block.data.type.Slab;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
import org.eclipse.jdt.annotation.NonNull;
|
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
|
||||||
import com.bgsoftware.wildstacker.api.WildStackerAPI;
|
import com.bgsoftware.wildstacker.api.WildStackerAPI;
|
||||||
@ -33,6 +35,7 @@ import com.google.common.collect.Multiset;
|
|||||||
import com.google.common.collect.Multiset.Entry;
|
import com.google.common.collect.Multiset.Entry;
|
||||||
import com.google.common.collect.Multisets;
|
import com.google.common.collect.Multisets;
|
||||||
|
|
||||||
|
import dev.rosewood.rosestacker.api.RoseStackerAPI;
|
||||||
import us.lynuxcraft.deadsilenceiv.advancedchests.AdvancedChestsAPI;
|
import us.lynuxcraft.deadsilenceiv.advancedchests.AdvancedChestsAPI;
|
||||||
import us.lynuxcraft.deadsilenceiv.advancedchests.chest.AdvancedChest;
|
import us.lynuxcraft.deadsilenceiv.advancedchests.chest.AdvancedChest;
|
||||||
import us.lynuxcraft.deadsilenceiv.advancedchests.chest.gui.page.ChestPage;
|
import us.lynuxcraft.deadsilenceiv.advancedchests.chest.gui.page.ChestPage;
|
||||||
@ -151,6 +154,8 @@ public class IslandLevelCalculator {
|
|||||||
private final Results results;
|
private final Results results;
|
||||||
private long duration;
|
private long duration;
|
||||||
private final boolean zeroIsland;
|
private final boolean zeroIsland;
|
||||||
|
private final Map<Environment, World> worlds = new EnumMap<>(Environment.class);
|
||||||
|
private final int seaHeight;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor to get the level for an island
|
* Constructor to get the level for an island
|
||||||
@ -170,6 +175,24 @@ public class IslandLevelCalculator {
|
|||||||
this.limitCount = new HashMap<>(addon.getBlockConfig().getBlockLimits());
|
this.limitCount = new HashMap<>(addon.getBlockConfig().getBlockLimits());
|
||||||
// Get the initial island level
|
// Get the initial island level
|
||||||
results.initialLevel.set(addon.getInitialIslandLevel(island));
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -311,36 +334,33 @@ public class IslandLevelCalculator {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a chunk async
|
* Get a chunk async
|
||||||
* @param world - the world where the chunk is
|
|
||||||
* @param env - the environment
|
* @param env - the environment
|
||||||
* @param x - chunk x coordinate
|
* @param x - chunk x coordinate
|
||||||
* @param z - chunk z coordinate
|
* @param z - chunk z coordinate
|
||||||
* @return a future chunk or future null if there is no chunk to load, e.g., there is no island nether
|
* @return a future chunk or future null if there is no chunk to load, e.g., there is no island nether
|
||||||
*/
|
*/
|
||||||
private CompletableFuture<Chunk> getWorldChunk(@NonNull World world, Environment env, int x, int z) {
|
private CompletableFuture<Chunk> getWorldChunk(Environment env, int x, int z) {
|
||||||
switch (env) {
|
if (worlds.containsKey(env)) {
|
||||||
case NETHER:
|
CompletableFuture<Chunk> r2 = new CompletableFuture<>();
|
||||||
if (addon.getSettings().isNether()) {
|
// Get the chunk, and then coincidentally check the RoseStacker
|
||||||
World nether = addon.getPlugin().getIWM().getNetherWorld(island.getWorld());
|
Util.getChunkAtAsync(worlds.get(env), x, z, true).thenAccept(chunk -> roseStackerCheck(r2, chunk));
|
||||||
if (nether != null) {
|
return r2;
|
||||||
return Util.getChunkAtAsync(nether, x, z, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// There is no chunk to scan, so return a null chunk
|
|
||||||
return CompletableFuture.completedFuture(null);
|
|
||||||
case THE_END:
|
|
||||||
if (addon.getSettings().isEnd()) {
|
|
||||||
World end = addon.getPlugin().getIWM().getEndWorld(island.getWorld());
|
|
||||||
if (end != null) {
|
|
||||||
return Util.getChunkAtAsync(end, x, z, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// There is no chunk to scan, so return a null chunk
|
|
||||||
return CompletableFuture.completedFuture(null);
|
|
||||||
default:
|
|
||||||
return Util.getChunkAtAsync(world, x, z, true);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return CompletableFuture.completedFuture(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void roseStackerCheck(CompletableFuture<Chunk> r2, 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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
r2.complete(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -369,7 +389,6 @@ public class IslandLevelCalculator {
|
|||||||
* @param chunkSnapshot - the chunk to scan
|
* @param chunkSnapshot - the chunk to scan
|
||||||
*/
|
*/
|
||||||
private void scanAsync(CompletableFuture<Boolean> result, ChunkSnapshot chunkSnapshot, Chunk chunk) {
|
private void scanAsync(CompletableFuture<Boolean> result, ChunkSnapshot chunkSnapshot, Chunk chunk) {
|
||||||
int seaHeight = addon.getPlugin().getIWM().getSeaHeight(island.getWorld());
|
|
||||||
List<Vector> stackedBlocks = new ArrayList<>();
|
List<Vector> stackedBlocks = new ArrayList<>();
|
||||||
for (int x = 0; x< 16; x++) {
|
for (int x = 0; x< 16; x++) {
|
||||||
// Check if the block coordinate is inside the protection zone and if not, don't count it
|
// Check if the block coordinate is inside the protection zone and if not, don't count it
|
||||||
@ -486,11 +505,11 @@ public class IslandLevelCalculator {
|
|||||||
// Set up the result
|
// Set up the result
|
||||||
CompletableFuture<Boolean> result = new CompletableFuture<>();
|
CompletableFuture<Boolean> result = new CompletableFuture<>();
|
||||||
// Get chunks and scan
|
// Get chunks and scan
|
||||||
getWorldChunk(island.getWorld(), Environment.THE_END, p.x, p.z).thenAccept(endChunk ->
|
getWorldChunk(Environment.THE_END, p.x, p.z).thenAccept(endChunk ->
|
||||||
scanChunk(endChunk).thenAccept(b ->
|
scanChunk(endChunk).thenAccept(b ->
|
||||||
getWorldChunk(island.getWorld(), Environment.NETHER, p.x, p.z).thenAccept(netherChunk ->
|
getWorldChunk(Environment.NETHER, p.x, p.z).thenAccept(netherChunk ->
|
||||||
scanChunk(netherChunk).thenAccept(b2 ->
|
scanChunk(netherChunk).thenAccept(b2 ->
|
||||||
getWorldChunk(island.getWorld(), Environment.NORMAL, p.x, p.z).thenAccept(normalChunk ->
|
getWorldChunk(Environment.NORMAL, p.x, p.z).thenAccept(normalChunk ->
|
||||||
scanChunk(normalChunk).thenAccept(b3 ->
|
scanChunk(normalChunk).thenAccept(b3 ->
|
||||||
// Complete the result now that all chunks have been scanned
|
// Complete the result now that all chunks have been scanned
|
||||||
result.complete(!chunksToCheck.isEmpty()))))
|
result.complete(!chunksToCheck.isEmpty()))))
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
name: Level
|
name: Pladdon
|
||||||
main: world.bentobox.level.LevelPladdon
|
main: world.bentobox.level.LevelPladdon
|
||||||
version: ${version}
|
version: ${version}
|
||||||
api-version: "1.16"
|
api-version: "1.17"
|
||||||
description: Level Addon
|
description: Level Addon
|
||||||
author: tastybento
|
author: tastybento
|
||||||
depend:
|
depend:
|
||||||
|
@ -383,8 +383,8 @@ public class LevelsManagerTest {
|
|||||||
Bukkit.getScheduler();
|
Bukkit.getScheduler();
|
||||||
verify(scheduler).runTaskAsynchronously(eq(plugin), task.capture());
|
verify(scheduler).runTaskAsynchronously(eq(plugin), task.capture());
|
||||||
task.getValue().run();
|
task.getValue().run();
|
||||||
verify(addon).log(eq("Generating Top Ten Tables"));
|
verify(addon).log(eq("Generating rankings"));
|
||||||
verify(addon).log(eq("Loaded top ten for bskyblock-world"));
|
verify(addon).log(eq("Generated rankings for bskyblock-world"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,14 +401,6 @@ public class LevelsManagerTest {
|
|||||||
assertFalse(tt.containsKey(uuid));
|
assertFalse(tt.containsKey(uuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.level.LevelsManager#save()}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testSave() {
|
|
||||||
lm.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.level.LevelsManager#setInitialIslandLevel(world.bentobox.bentobox.database.objects.Island, long)}.
|
* Test method for {@link world.bentobox.level.LevelsManager#setInitialIslandLevel(world.bentobox.bentobox.database.objects.Island, long)}.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user