Compare commits
4 Commits
Author | SHA1 | Date |
---|---|---|
tastybento | 31c0cd58e6 | |
tastybento | b5eff6ab91 | |
tastybento | 6ddc0471cf | |
tastybento | 1321bcf9d6 |
39
pom.xml
39
pom.xml
|
@ -65,7 +65,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.6.3</build.version>
|
||||
<build.version>2.6.5</build.version>
|
||||
</properties>
|
||||
|
||||
<!-- Profiles will allow to automatically change build version. -->
|
||||
|
@ -108,30 +108,6 @@
|
|||
<build.number></build.number>
|
||||
</properties>
|
||||
</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>
|
||||
|
||||
<repositories>
|
||||
|
@ -152,6 +128,11 @@
|
|||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
<!-- RoseStacker repo -->
|
||||
<repository>
|
||||
<id>rosewood-repo</id>
|
||||
<url>https://repo.rosewooddev.io/repository/public/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
|
@ -192,6 +173,7 @@
|
|||
<groupId>com.github.OmerBenGera</groupId>
|
||||
<artifactId>WildStackerAPI</artifactId>
|
||||
<version>b18</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- Static analysis -->
|
||||
<!-- We are using Eclipse's annotations. If you're using IDEA, update
|
||||
|
@ -206,7 +188,14 @@
|
|||
<groupId>com.github.DeadSilenceIV</groupId>
|
||||
<artifactId>AdvancedChestsAPI</artifactId>
|
||||
<version>1.6</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.rosewood</groupId>
|
||||
<artifactId>rosestacker</artifactId>
|
||||
<version>1.3.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -50,6 +50,7 @@ public class Level extends Addon implements Listener {
|
|||
private LevelsManager manager;
|
||||
private boolean stackersEnabled;
|
||||
private boolean advChestEnabled;
|
||||
private boolean roseStackersEnabled;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
|
@ -112,6 +113,12 @@ public class Level extends Addon implements Listener {
|
|||
advChestEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if RoseStackers is enabled
|
||||
roseStackersEnabled = Bukkit.getPluginManager().isPluginEnabled("RoseStacker");
|
||||
if (roseStackersEnabled) {
|
||||
log("Hooked into RoseStackers.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -247,11 +254,6 @@ public class Level extends Addon implements Listener {
|
|||
public void onDisable() {
|
||||
// Stop the pipeline
|
||||
this.getPipeliner().stop();
|
||||
// Save player data and the top tens
|
||||
if (manager != null) {
|
||||
manager.save();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void loadBlockSettings() {
|
||||
|
@ -396,4 +398,11 @@ public class Level extends Addon implements Listener {
|
|||
});
|
||||
return ld;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the roseStackersEnabled
|
||||
*/
|
||||
public boolean isRoseStackersEnabled() {
|
||||
return roseStackersEnabled;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,8 +64,6 @@ public class LevelsManager {
|
|||
private final Database<IslandLevels> handler;
|
||||
// A cache of island levels.
|
||||
private final Map<String, IslandLevels> levelsCache;
|
||||
|
||||
private final Database<TopTenData> topTenHandler;
|
||||
// Top ten lists
|
||||
private final Map<World,TopTenData> topTenLists;
|
||||
// Background
|
||||
|
@ -79,8 +77,6 @@ public class LevelsManager {
|
|||
// 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);
|
||||
// Top Ten handler
|
||||
topTenHandler = new Database<>(addon, TopTenData.class);
|
||||
// Initialize the cache
|
||||
levelsCache = new HashMap<>();
|
||||
// Initialize top ten lists
|
||||
|
@ -181,8 +177,6 @@ public class LevelsManager {
|
|||
}
|
||||
// Save result
|
||||
setIslandResults(island.getWorld(), island.getOwner(), r);
|
||||
// Save top ten
|
||||
addon.getManager().saveTopTen(island.getWorld());
|
||||
// Save the island scan details
|
||||
result.complete(r);
|
||||
});
|
||||
|
@ -418,11 +412,11 @@ public class LevelsManager {
|
|||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)));
|
||||
}
|
||||
|
||||
|
||||
void createAndCleanRankings(@NonNull World world) {
|
||||
topTenLists.computeIfAbsent(world, TopTenData::new);
|
||||
// Remove player from top ten if they are online and do not have the perm
|
||||
topTenLists.get(world).getTopTen().keySet().removeIf(u -> !hasTopTenPerm(world, u));
|
||||
topTenLists.get(world).getTopTen().keySet().removeIf(u -> !hasTopTenPerm(world, u));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -441,12 +435,12 @@ public class LevelsManager {
|
|||
public int getRank(@NonNull World world, UUID uuid) {
|
||||
createAndCleanRankings(world);
|
||||
Stream<Entry<UUID, Long>> stream = topTenLists.get(world).getTopTen().entrySet().stream()
|
||||
.filter(e -> addon.getIslands().isOwner(world, e.getKey()))
|
||||
.filter(l -> l.getValue() > 0)
|
||||
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()));
|
||||
.filter(e -> addon.getIslands().isOwner(world, e.getKey()))
|
||||
.filter(l -> l.getValue() > 0)
|
||||
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()));
|
||||
return takeWhile(stream, 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
|
||||
|
@ -457,7 +451,7 @@ public class LevelsManager {
|
|||
CustomSpliterator<T> customSpliterator = new CustomSpliterator<>(stream.spliterator(), predicate);
|
||||
return StreamSupport.stream(customSpliterator, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if player has the correct top ten perm to have their level saved
|
||||
* @param world
|
||||
|
@ -475,15 +469,14 @@ public class LevelsManager {
|
|||
void loadTopTens() {
|
||||
topTenLists.clear();
|
||||
Bukkit.getScheduler().runTaskAsynchronously(addon.getPlugin(), () -> {
|
||||
addon.log("Generating Top Ten Tables");
|
||||
addon.log("Generating rankings");
|
||||
handler.loadObjects().forEach(il -> {
|
||||
if (il.getLevel() > 0) {
|
||||
addon.getIslands().getIslandById(il.getUniqueId()).ifPresent(i -> this.addToTopTen(i, il.getLevel()));
|
||||
}
|
||||
});
|
||||
topTenLists.keySet().forEach(w -> {
|
||||
addon.log("Loaded top ten for " + w.getName());
|
||||
this.saveTopTen(w);
|
||||
addon.log("Generated rankings for " + w.getName());
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -497,27 +490,10 @@ public class LevelsManager {
|
|||
public void removeEntry(World world, UUID uuid) {
|
||||
if (topTenLists.containsKey(world)) {
|
||||
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
|
||||
* @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.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.UUID;
|
||||
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.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
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.Multisets;
|
||||
|
||||
import dev.rosewood.rosestacker.api.RoseStackerAPI;
|
||||
import us.lynuxcraft.deadsilenceiv.advancedchests.AdvancedChestsAPI;
|
||||
import us.lynuxcraft.deadsilenceiv.advancedchests.chest.AdvancedChest;
|
||||
import us.lynuxcraft.deadsilenceiv.advancedchests.chest.gui.page.ChestPage;
|
||||
|
@ -45,6 +48,7 @@ import world.bentobox.level.Level;
|
|||
public class IslandLevelCalculator {
|
||||
private static final String LINE_BREAK = "==================================";
|
||||
public static final long MAX_AMOUNT = 10000;
|
||||
private final Map<Environment, World> worlds = new EnumMap<>(Environment.class);
|
||||
|
||||
/**
|
||||
* Method to evaluate a mathematical equation
|
||||
|
@ -151,6 +155,7 @@ public class IslandLevelCalculator {
|
|||
private final Results results;
|
||||
private long duration;
|
||||
private final boolean zeroIsland;
|
||||
private int seaHeight;
|
||||
|
||||
/**
|
||||
* Constructor to get the level for an island
|
||||
|
@ -170,6 +175,24 @@ public class IslandLevelCalculator {
|
|||
this.limitCount = new HashMap<>(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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -317,30 +340,28 @@ public class IslandLevelCalculator {
|
|||
* @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
|
||||
*/
|
||||
private CompletableFuture<Chunk> getWorldChunk(@NonNull World world, Environment env, int x, int z) {
|
||||
switch (env) {
|
||||
case NETHER:
|
||||
if (addon.getSettings().isNether()) {
|
||||
World nether = addon.getPlugin().getIWM().getNetherWorld(island.getWorld());
|
||||
if (nether != null) {
|
||||
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);
|
||||
|
||||
private CompletableFuture<Chunk> getWorldChunk(Environment env, int x, int z) {
|
||||
if (worlds.containsKey(env)) {
|
||||
CompletableFuture<Chunk> r2 = new CompletableFuture<>();
|
||||
// Get the chunk, and then coincidentally check the RoseStacker
|
||||
Util.getChunkAtAsync(worlds.get(env), x, z, true).thenAccept(chunk -> roseStackerCheck(r2, chunk));
|
||||
return r2;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -486,18 +507,17 @@ public class IslandLevelCalculator {
|
|||
// Set up the result
|
||||
CompletableFuture<Boolean> result = new CompletableFuture<>();
|
||||
// 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 ->
|
||||
getWorldChunk(island.getWorld(), Environment.NETHER, p.x, p.z).thenAccept(netherChunk ->
|
||||
getWorldChunk(Environment.NETHER, p.x, p.z).thenAccept(netherChunk ->
|
||||
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 ->
|
||||
// Complete the result now that all chunks have been scanned
|
||||
result.complete(!chunksToCheck.isEmpty()))))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -401,14 +401,6 @@ public class LevelsManagerTest {
|
|||
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)}.
|
||||
*/
|
||||
|
@ -443,7 +435,7 @@ public class LevelsManagerTest {
|
|||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.level.LevelsManager#getRank(World, UUID)}
|
||||
*/
|
||||
|
@ -453,7 +445,7 @@ public class LevelsManagerTest {
|
|||
Map<World, TopTenData> ttl = lm.getTopTenLists();
|
||||
Map<UUID, Long> tt = ttl.get(world).getTopTen();
|
||||
for (long i = 100; i < 150; i++) {
|
||||
tt.put(UUID.randomUUID(), i);
|
||||
tt.put(UUID.randomUUID(), i);
|
||||
}
|
||||
// Put player as lowest rank
|
||||
tt.put(uuid, 10L);
|
||||
|
|
Loading…
Reference in New Issue