Skip to content

Commit 399bec9

Browse files
committed
Implement support for different spawner types
1 parent 0089cbf commit 399bec9

File tree

9 files changed

+315
-272
lines changed

9 files changed

+315
-272
lines changed

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@
5050
<properties>
5151
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
5252
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
53-
<java.version>17</java.version>
53+
<java.version>21</java.version>
5454
<!-- Non-minecraft related dependencies -->
5555
<powermock.version>2.0.9</powermock.version>
5656
<!-- More visible way how to change dependency versions -->
5757
<spigot.version>1.21.3-R0.1-SNAPSHOT</spigot.version>
58-
<bentobox.version>2.7.1-SNAPSHOT</bentobox.version>
58+
<bentobox.version>3.2.4-SNAPSHOT</bentobox.version>
5959
<!-- Warps addon version -->
6060
<warps.version>1.12.0</warps.version>
6161
<!-- Visit addon version -->

src/main/java/world/bentobox/level/LevelsManager.java

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import world.bentobox.level.events.IslandLevelCalculatedEvent;
3131
import world.bentobox.level.events.IslandPreLevelEvent;
3232
import world.bentobox.level.objects.IslandLevels;
33-
import world.bentobox.level.objects.LevelsData;
3433
import world.bentobox.level.objects.TopTenData;
3534
import world.bentobox.level.util.CachedData;
3635

@@ -67,38 +66,6 @@ public LevelsManager(Level addon) {
6766

6867
}
6968

70-
public void migrate() {
71-
Database<LevelsData> oldDb = new Database<>(addon, LevelsData.class);
72-
oldDb.loadObjects().forEach(ld -> {
73-
try {
74-
UUID owner = UUID.fromString(ld.getUniqueId());
75-
// Step through each world
76-
ld.getLevels().keySet().stream()
77-
// World
78-
.map(Bukkit::getWorld).filter(Objects::nonNull)
79-
// Island
80-
.map(w -> addon.getIslands().getIsland(w, owner)).filter(Objects::nonNull).forEach(i -> {
81-
// Make new database entry
82-
World w = i.getWorld();
83-
IslandLevels il = new IslandLevels(i.getUniqueId());
84-
il.setInitialLevel(ld.getInitialLevel(w));
85-
il.setLevel(ld.getLevel(w));
86-
il.setMdCount(ld.getMdCount(w));
87-
il.setPointsToNextLevel(ld.getPointsToNextLevel(w));
88-
il.setUwCount(ld.getUwCount(w));
89-
// Save it
90-
handler.saveObjectAsync(il);
91-
});
92-
// Now delete the old database entry
93-
oldDb.deleteID(ld.getUniqueId());
94-
} catch (Exception e) {
95-
addon.logError("Could not migrate level data database! " + e.getMessage());
96-
e.printStackTrace();
97-
return;
98-
}
99-
});
100-
}
101-
10269
/**
10370
* Add an island to a top ten
10471
*

src/main/java/world/bentobox/level/calculators/IslandLevelCalculator.java

Lines changed: 82 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
import java.text.ParseException;
44
import java.util.ArrayList;
5-
import java.util.Arrays;
65
import java.util.Collection;
76
import java.util.Collections;
87
import java.util.EnumMap;
8+
import java.util.HashMap;
99
import java.util.HashSet;
1010
import java.util.Iterator;
1111
import java.util.List;
1212
import java.util.Map;
13+
import java.util.Objects;
1314
import java.util.Queue;
1415
import java.util.Set;
1516
import java.util.UUID;
@@ -31,9 +32,9 @@
3132
import org.bukkit.block.ShulkerBox;
3233
import org.bukkit.block.data.BlockData;
3334
import org.bukkit.block.data.type.Slab;
35+
import org.bukkit.entity.EntityType;
3436
import org.bukkit.inventory.ItemStack;
3537
import org.bukkit.inventory.meta.BlockStateMeta;
36-
import org.bukkit.scheduler.BukkitTask;
3738

3839
import com.bgsoftware.wildstacker.api.WildStackerAPI;
3940
import com.bgsoftware.wildstacker.api.objects.StackedBarrel;
@@ -55,19 +56,6 @@
5556
public class IslandLevelCalculator {
5657
private static final String LINE_BREAK = "==================================";
5758
public static final long MAX_AMOUNT = 10000000;
58-
private static final List<Material> CHESTS = Arrays.asList(Material.CHEST, Material.CHEST_MINECART,
59-
Material.TRAPPED_CHEST, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX,
60-
Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX,
61-
Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX,
62-
Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX,
63-
Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.RED_SHULKER_BOX,
64-
Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX, Material.COMPOSTER, Material.BARREL,
65-
Material.DISPENSER, Material.DROPPER, Material.SMOKER, Material.BLAST_FURNACE, Material.BUNDLE,
66-
Material.RED_BUNDLE, Material.BLACK_BUNDLE, Material.BLUE_BUNDLE, Material.BROWN_BUNDLE,
67-
Material.CYAN_BUNDLE, Material.GRAY_BUNDLE, Material.GREEN_BUNDLE, Material.LIGHT_BLUE_BUNDLE,
68-
Material.LIGHT_GRAY_BUNDLE, Material.LIME_BUNDLE, Material.MAGENTA_BUNDLE, Material.ORANGE_BUNDLE,
69-
Material.PINK_BUNDLE, Material.PURPLE_BUNDLE, Material.RED_BUNDLE, Material.WHITE_BUNDLE,
70-
Material.YELLOW_BUNDLE);
7159
private static final int CHUNKS_TO_SCAN = 100;
7260
private final Level addon;
7361
private final Queue<Pair<Integer, Integer>> chunksToCheck;
@@ -82,7 +70,7 @@ public class IslandLevelCalculator {
8270
private final int seaHeight;
8371
private final List<Location> stackedBlocks = new ArrayList<>();
8472
private final Set<Chunk> chestBlocks = new HashSet<>();
85-
private BukkitTask finishTask;
73+
private final Map<Location, Boolean> spawners = new HashMap<>();
8674

8775
/**
8876
* Constructor to get the level for an island
@@ -163,6 +151,29 @@ private void checkBlock(Material mat, boolean belowSeaLevel) {
163151
}
164152
}
165153

154+
/**
155+
* Adds value to the results based on the material and whether the block is
156+
* below sea level or not
157+
*
158+
* @param mat - material of the block
159+
* @param belowSeaLevel - true if below sea level
160+
*/
161+
private void checkSpawner(EntityType et, boolean belowSeaLevel) {
162+
if (limitCount(Material.SPAWNER) == 0) {
163+
return;
164+
}
165+
Integer count = addon.getBlockConfig().getValue(island.getWorld(), et);
166+
if (count != null) {
167+
if (belowSeaLevel) {
168+
results.underWaterBlockCount.addAndGet(count);
169+
results.uwCount.add(et);
170+
} else {
171+
results.rawBlockCount.addAndGet(count);
172+
results.mdCount.add(et);
173+
}
174+
}
175+
}
176+
166177
/**
167178
* Get a set of all the chunks in island
168179
*
@@ -231,31 +242,22 @@ private List<String> getReport() {
231242

232243
reportLines.add(
233244
"Blocks not counted because they exceeded limits: " + String.format("%,d", results.ofCount.size()));
234-
Iterable<Multiset.Entry<Material>> entriesSortedByCount = results.ofCount.entrySet();
235-
Iterator<Entry<Material>> it = entriesSortedByCount.iterator();
245+
Iterable<Multiset.Entry<Object>> entriesSortedByCount = results.ofCount.entrySet();
246+
Iterator<Entry<Object>> it = entriesSortedByCount.iterator();
236247
while (it.hasNext()) {
237-
Entry<Material> type = it.next();
238-
Integer limit = addon.getBlockConfig().getBlockLimits().get(type.getElement());
248+
249+
Entry<Object> type = it.next();
250+
Material m = type.getElement() instanceof Material mat ? mat : Material.SPAWNER;
251+
Integer limit = addon.getBlockConfig().getBlockLimits().get(m);
239252
String explain = ")";
240253
if (limit == null) {
241-
Material generic = type.getElement();
242-
limit = addon.getBlockConfig().getBlockLimits().get(generic);
254+
limit = addon.getBlockConfig().getBlockLimits().get(m);
243255
explain = " - All types)";
244256
}
245-
reportLines.add(type.getElement().toString() + ": " + String.format("%,d", type.getCount())
257+
reportLines.add(Util.prettifyText(m.name()) + ": " + String.format("%,d", type.getCount())
246258
+ " blocks (max " + limit + explain);
247259
}
248260
reportLines.add(LINE_BREAK);
249-
reportLines.add("Blocks on island that are not in config.yml");
250-
reportLines.add("Total number = " + String.format("%,d", results.ncCount.size()));
251-
entriesSortedByCount = results.ncCount.entrySet();
252-
it = entriesSortedByCount.iterator();
253-
while (it.hasNext()) {
254-
Entry<Material> type = it.next();
255-
reportLines.add(type.getElement().toString() + ": " + String.format("%,d", type.getCount()) + " blocks");
256-
}
257-
reportLines.add(LINE_BREAK);
258-
259261
return reportLines;
260262
}
261263

@@ -454,6 +456,8 @@ private void scanAsync(ChunkPair cp) {
454456
BlockData blockData = cp.chunkSnapshot.getBlockData(x, y, z);
455457
Material m = blockData.getMaterial();
456458
boolean belowSeaLevel = seaHeight > 0 && y <= seaHeight;
459+
Location loc = new Location(cp.world, (double) x + cp.chunkSnapshot.getX() * 16, y,
460+
(double) z + cp.chunkSnapshot.getZ() * 16);
457461
// Slabs can be doubled, so check them twice
458462
if (Tag.SLABS.isTagged(m)) {
459463
Slab slab = (Slab) blockData;
@@ -464,22 +468,26 @@ private void scanAsync(ChunkPair cp) {
464468
// Hook for Wild Stackers (Blocks and Spawners Only) - this has to use the real
465469
// chunk
466470
if (addon.isStackersEnabled() && (m.equals(Material.CAULDRON) || m.equals(Material.SPAWNER))) {
467-
stackedBlocks.add(new Location(cp.world, (double) x + cp.chunkSnapshot.getX() * 16, y,
468-
(double) z + cp.chunkSnapshot.getZ() * 16));
471+
stackedBlocks.add(loc);
469472
}
470473

471474
if (addon.isUltimateStackerEnabled() && !m.isAir()) {
472-
Location l = new Location(cp.chunk.getWorld(), x, y, z);
473-
UltimateStackerCalc.addStackers(m, l, results, belowSeaLevel, limitCount(m));
475+
UltimateStackerCalc.addStackers(m, loc, results, belowSeaLevel, limitCount(m));
474476
}
475477

476478
// Scan chests
477-
if (addon.getSettings().isIncludeChests() && CHESTS.contains(m)) {
478-
479+
if (addon.getSettings().isIncludeChests() && blockData instanceof Container) {
479480
chestBlocks.add(cp.chunk);
480481
}
481-
// Add the value of the block's material
482-
checkBlock(m, belowSeaLevel);
482+
483+
// Spawners
484+
if (m == Material.SPAWNER) {
485+
// Stash the spawner because the type cannot be obtained from the chunk snapshot
486+
this.spawners.put(loc, belowSeaLevel);
487+
} else {
488+
// Add the value of the block's material
489+
checkBlock(m, belowSeaLevel);
490+
}
483491
}
484492
}
485493
}
@@ -520,16 +528,23 @@ public CompletableFuture<Boolean> scanNextChunk() {
520528
return result;
521529
}
522530

523-
private Collection<String> sortedReport(int total, Multiset<Material> materialCount) {
531+
private Collection<String> sortedReport(int total, Multiset<Object> uwCount) {
524532
Collection<String> result = new ArrayList<>();
525-
Iterable<Multiset.Entry<Material>> entriesSortedByCount = Multisets.copyHighestCountFirst(materialCount)
533+
Iterable<Multiset.Entry<Object>> entriesSortedByCount = Multisets.copyHighestCountFirst(uwCount)
526534
.entrySet();
527-
for (Entry<Material> en : entriesSortedByCount) {
528-
Material type = en.getElement();
529-
530-
int value = getValue(type);
535+
for (Entry<Object> en : entriesSortedByCount) {
536+
537+
int value = 0;
538+
String name = "";
539+
if (en.getElement() instanceof Material md) {
540+
value = Objects.requireNonNullElse(addon.getBlockConfig().getValue(island.getWorld(), md), 0);
541+
name = Util.prettifyText(md.name());
542+
} else if (en.getElement() instanceof EntityType et) {
543+
name = Util.prettifyText(et.name());
544+
value = Objects.requireNonNullElse(addon.getBlockConfig().getValue(island.getWorld(), et), 0);
545+
}
531546

532-
result.add(type.toString() + ":" + String.format("%,d", en.getCount()) + " blocks x " + value + " = "
547+
result.add(name + " :" + String.format("%,d", en.getCount()) + " blocks x " + value + " = "
533548
+ (value * en.getCount()));
534549
total += (value * en.getCount());
535550

@@ -616,15 +631,32 @@ public void scanIsland(Pipeliner pipeliner) {
616631
pipeliner.getInProcessQueue().remove(this);
617632
BentoBox.getInstance().log("Completed Level scan.");
618633
// Chunk finished
619-
// This was the last chunk. Handle stacked blocks, then chests and exit
620-
handleStackedBlocks().thenCompose(v -> handleChests()).thenRun(() -> {
634+
// This was the last chunk. Handle stacked blocks, spawners, chests and exit
635+
handleStackedBlocks().thenCompose(v -> handleSpawners()).thenCompose(v -> handleChests())
636+
.thenRun(() -> {
621637
this.tidyUp();
622638
this.getR().complete(getResults());
623639
});
624640
}
625641
});
626642
}
627643

644+
private CompletableFuture<Void> handleSpawners() {
645+
List<CompletableFuture<Void>> futures = new ArrayList<>();
646+
for (Map.Entry<Location, Boolean> en : this.spawners.entrySet()) {
647+
CompletableFuture<Void> future = Util.getChunkAtAsync(en.getKey()).thenAccept(c -> {
648+
if (en.getKey().getBlock().getType() == Material.SPAWNER) {
649+
CreatureSpawner cs = (CreatureSpawner) en.getKey().getBlock().getState();
650+
checkSpawner(cs.getSpawnedType(), en.getValue());
651+
}
652+
});
653+
futures.add(future);
654+
}
655+
// Return a CompletableFuture that completes when all futures are done
656+
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
657+
658+
}
659+
628660
private CompletableFuture<Void> handleChests() {
629661
List<CompletableFuture<Void>> futures = new ArrayList<>();
630662
for (Chunk v : chestBlocks) {

src/main/java/world/bentobox/level/calculators/Results.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ public enum Result {
2525
TIMEOUT
2626
}
2727
List<String> report;
28-
final Multiset<Material> mdCount = HashMultiset.create();
29-
final Multiset<Material> uwCount = HashMultiset.create();
30-
final Multiset<Material> ncCount = HashMultiset.create();
31-
final Multiset<Material> ofCount = HashMultiset.create();
28+
final Multiset<Object> mdCount = HashMultiset.create();
29+
final Multiset<Object> uwCount = HashMultiset.create();
30+
final Multiset<Object> ncCount = HashMultiset.create();
31+
final Multiset<Object> ofCount = HashMultiset.create();
3232
// AtomicLong and AtomicInteger must be used because they are changed by multiple concurrent threads
3333
AtomicLong rawBlockCount = new AtomicLong(0);
3434
AtomicLong underWaterBlockCount = new AtomicLong(0);
@@ -130,13 +130,13 @@ public String toString() {
130130
/**
131131
* @return the mdCount
132132
*/
133-
public Multiset<Material> getMdCount() {
133+
public Multiset<Object> getMdCount() {
134134
return mdCount;
135135
}
136136
/**
137137
* @return the uwCount
138138
*/
139-
public Multiset<Material> getUwCount() {
139+
public Multiset<Object> getUwCount() {
140140
return uwCount;
141141
}
142142
/**

0 commit comments

Comments
 (0)