Skip to content

Commit 6e655bb

Browse files
tastybentoclaude
andcommitted
Address SonarCloud issues across main and test sources
Resolve the open issues reported on the new-code period: Main code: - BlockLimitsListener: replace Guava Optional copper fields with nullable Material (S4738); refactor fixMaterial to a lookup map and extract loadLimits helpers to cut cognitive complexity (S3776); lazy-supplier logging (S2629); drop unused handleBreak param (S1172). - EntityLimitListener: constants for duplicated literals (S1192); extract assignment from condition (S1121); remove always-false getHand() null check (S2583); single Optional resolve before get (S3655). - Stream.toList() over collect(toList()) (S6204) in Limits, RecountCalculator, OffsetCommand; rename shadowing locals (S1117); switch->if in CalcCommand/RecountCommand (S1301); CalcCommand island field -> local (S1450); drop unused OffsetCommand alias param (S1172); remove redundant lambda braces in JoinListener (S1602). Tests: - Drop redundant public modifier on 181 JUnit 5 methods (S5786). - Replace deprecated PlayerJoinEvent(String)/BlockMultiPlaceEvent ctors and PlayerInteractEvent.isCancelled() (S5738/S1874). - Parameterize the four invalid-perm-format tests (S5976); method reference (S1612); assertNotEquals (S5785); drop useless eq() matchers (S6068); remove unused imports/vars/throws/commented code and add a missing assertion (S1128/S1481/S1854/S1130/S125/S2699). All 243 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 2a535e7 commit 6e655bb

24 files changed

Lines changed: 345 additions & 378 deletions

src/main/java/world/bentobox/limits/Limits.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import java.util.List;
66
import java.util.Locale;
77
import java.util.Map;
8-
import java.util.stream.Collectors;
98

109
import org.bukkit.Material;
1110
import org.bukkit.NamespacedKey;
@@ -54,7 +53,7 @@ public void onEnable() {
5453
settings = new Settings(this);
5554
gameModes = getPlugin().getAddonsManager().getGameModeAddons().stream()
5655
.filter(gm -> settings.getGameModes().contains(gm.getDescription().getName()))
57-
.collect(Collectors.toList());
56+
.toList();
5857
gameModes.forEach(gm -> {
5958
gm.getAdminCommand().ifPresent(a -> new AdminCommand(this, a));
6059
gm.getPlayerCommand().ifPresent(a -> new PlayerCommand(this, a));

src/main/java/world/bentobox/limits/calculators/RecountCalculator.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import java.util.concurrent.ConcurrentLinkedQueue;
1212
import java.util.function.BooleanSupplier;
1313
import java.util.function.LongSupplier;
14-
import java.util.stream.Collectors;
1514

1615
import org.bukkit.Bukkit;
1716
import org.bukkit.Chunk;
@@ -120,12 +119,12 @@ public Results getResults() {
120119

121120
private CompletableFuture<List<Chunk>> getWorldChunk(Environment env, Queue<Pair<Integer, Integer>> pairList) {
122121
if (worlds.containsKey(env)) {
123-
World world = worlds.get(env);
124-
boolean isNether = world.getEnvironment().equals(Environment.NETHER);
122+
World envWorld = worlds.get(env);
123+
boolean isNether = envWorld.getEnvironment().equals(Environment.NETHER);
125124
List<CompletableFuture<Chunk>> futures = new ArrayList<>();
126125
while (!pairList.isEmpty()) {
127126
Pair<Integer, Integer> p = pairList.poll();
128-
futures.add(Util.getChunkAtAsync(world, p.x, p.z, isNether));
127+
futures.add(Util.getChunkAtAsync(envWorld, p.x, p.z, isNether));
129128
}
130129
if (futures.isEmpty()) {
131130
return CompletableFuture.completedFuture(Collections.emptyList());
@@ -134,7 +133,7 @@ private CompletableFuture<List<Chunk>> getWorldChunk(Environment env, Queue<Pair
134133
.thenApply(v -> futures.stream()
135134
.map(CompletableFuture::join)
136135
.filter(Objects::nonNull)
137-
.collect(Collectors.toList()));
136+
.toList());
138137
}
139138
return CompletableFuture.completedFuture(Collections.emptyList());
140139
}
@@ -242,7 +241,7 @@ public void tidyUp() {
242241
}
243242

244243
public void scanIsland(LongSupplier startTime, Runnable onRemove, BooleanSupplier isCancelled, Runnable recurse) {
245-
scanNextChunk().thenAccept(r -> {
244+
scanNextChunk().thenAccept(hasMoreChunks -> {
246245
if (!Bukkit.isPrimaryThread()) {
247246
addon.getPlugin().logError("scanChunk not on Primary Thread!");
248247
}
@@ -253,7 +252,7 @@ public void scanIsland(LongSupplier startTime, Runnable onRemove, BooleanSupplie
253252
+ getIsland());
254253
return;
255254
}
256-
if (Boolean.TRUE.equals(r) && !isCancelled.getAsBoolean()) {
255+
if (Boolean.TRUE.equals(hasMoreChunks) && !isCancelled.getAsBoolean()) {
257256
recurse.run();
258257
} else {
259258
onRemove.run();

src/main/java/world/bentobox/limits/commands/admin/CalcCommand.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
public class CalcCommand extends CompositeCommand {
2121

2222
private final Limits addon;
23-
private Island island;
2423

2524
/**
2625
* Admin command
@@ -54,7 +53,7 @@ public boolean execute(User user, String label, List<String> args) {
5453
user.sendMessage("general.errors.unknown-player", args.get(0));
5554
return true;
5655
}
57-
island = addon.getIslands().getIsland(getWorld(), playerUUID);
56+
Island island = addon.getIslands().getIsland(getWorld(), playerUUID);
5857
if (island == null) {
5958
user.sendMessage("general.errors.player-has-no-island");
6059
return false;
@@ -77,9 +76,10 @@ private void handlePipelineResult(User user, Results results) {
7776
if (results == null) {
7877
user.sendMessage("island.limits.recount.in-progress");
7978
} else {
80-
switch (results.getState()) {
81-
case TIMEOUT -> user.sendMessage("admin.limits.calc.timeout");
82-
default -> user.sendMessage("admin.limits.calc.finished");
79+
if (results.getState() == Results.Result.TIMEOUT) {
80+
user.sendMessage("admin.limits.calc.timeout");
81+
} else {
82+
user.sendMessage("admin.limits.calc.finished");
8383
}
8484
}
8585
}

src/main/java/world/bentobox/limits/commands/admin/OffsetCommand.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ public boolean execute(User user, String label, List<String> args)
188188
@Override
189189
public Optional<List<String>> tabComplete(User user, String alias, List<String> args)
190190
{
191-
return OffsetCommand.craftTabComplete(user, alias, args);
191+
return OffsetCommand.craftTabComplete(user, args);
192192
}
193193

194194

@@ -305,7 +305,7 @@ public boolean execute(User user, String label, List<String> args)
305305
@Override
306306
public Optional<List<String>> tabComplete(User user, String alias, List<String> args)
307307
{
308-
return OffsetCommand.craftTabComplete(user, alias, args);
308+
return OffsetCommand.craftTabComplete(user, args);
309309
}
310310

311311

@@ -422,7 +422,7 @@ public boolean execute(User user, String label, List<String> args)
422422
@Override
423423
public Optional<List<String>> tabComplete(User user, String alias, List<String> args)
424424
{
425-
return OffsetCommand.craftTabComplete(user, alias, args);
425+
return OffsetCommand.craftTabComplete(user, args);
426426
}
427427

428428

@@ -524,7 +524,7 @@ public boolean execute(User user, String label, List<String> args)
524524
@Override
525525
public Optional<List<String>> tabComplete(User user, String alias, List<String> args)
526526
{
527-
return OffsetCommand.craftTabComplete(user, alias, args);
527+
return OffsetCommand.craftTabComplete(user, args);
528528
}
529529

530530

@@ -624,7 +624,7 @@ public boolean execute(User user, String label, List<String> args)
624624
@Override
625625
public Optional<List<String>> tabComplete(User user, String alias, List<String> args)
626626
{
627-
return OffsetCommand.craftTabComplete(user, alias, args);
627+
return OffsetCommand.craftTabComplete(user, args);
628628
}
629629

630630

@@ -660,11 +660,10 @@ private static EntityType matchEntity(String name)
660660
/**
661661
* This method crafts tab complete for all subcommands
662662
* @param user User who runs command.
663-
* @param alias Command alias.
664663
* @param args List of args.
665664
* @return Optional list of strings.
666665
*/
667-
private static Optional<List<String>> craftTabComplete(User user, String alias, List<String> args)
666+
private static Optional<List<String>> craftTabComplete(User user, List<String> args)
668667
{
669668
String lastArg = !args.isEmpty() ? args.get(args.size() - 1) : "";
670669

@@ -686,7 +685,7 @@ else if (args.size() == 5)
686685

687686
options.addAll(Arrays.stream(EntityType.values()).
688687
map(Enum::name).
689-
collect(Collectors.toList()));
688+
toList());
690689

691690
return Optional.of(Util.tabLimit(options, lastArg));
692691
}

src/main/java/world/bentobox/limits/commands/player/RecountCommand.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import world.bentobox.bentobox.database.objects.Island;
1010
import world.bentobox.limits.Limits;
1111
import world.bentobox.limits.calculators.Pipeliner;
12+
import world.bentobox.limits.calculators.Results;
1213

1314
/**
1415
*
@@ -65,9 +66,10 @@ public boolean execute(User user, String label, List<String> args) {
6566
if (results == null) {
6667
user.sendMessage("island.limits.recount.in-progress");
6768
} else {
68-
switch (results.getState()) {
69-
case TIMEOUT -> user.sendMessage("admin.limits.calc.timeout");
70-
default -> user.sendMessage("admin.limits.calc.finished");
69+
if (results.getState() == Results.Result.TIMEOUT) {
70+
user.sendMessage("admin.limits.calc.timeout");
71+
} else {
72+
user.sendMessage("admin.limits.calc.finished");
7173
}
7274
}
7375
});

src/main/java/world/bentobox/limits/listeners/BlockLimitsListener.java

Lines changed: 71 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import org.bukkit.block.data.type.TechnicalPiston;
2222
import org.bukkit.configuration.ConfigurationSection;
2323
import org.bukkit.event.Cancellable;
24-
import org.bukkit.event.Event;
2524
import org.bukkit.event.EventHandler;
2625
import org.bukkit.event.EventPriority;
2726
import org.bukkit.event.Listener;
@@ -45,7 +44,6 @@
4544
import org.eclipse.jdt.annotation.Nullable;
4645

4746
import com.google.common.base.Enums;
48-
import com.google.common.base.Optional;
4947

5048
import world.bentobox.bentobox.api.events.island.IslandDeleteEvent;
5149
import world.bentobox.bentobox.api.localization.TextVariables;
@@ -73,15 +71,42 @@ public class BlockLimitsListener implements Listener {
7371
* addon links and runs on older servers (< 1.21.9) where these constants are
7472
* absent, instead of throwing NoSuchFieldError. Absent Optional == not on this server.
7573
*/
76-
private static final Optional<Material> COPPER_WALL_TORCH = Enums.getIfPresent(Material.class, "COPPER_WALL_TORCH");
77-
private static final Optional<Material> COPPER_TORCH = Enums.getIfPresent(Material.class, "COPPER_TORCH");
78-
private static final Optional<Material> COPPER_CHEST = Enums.getIfPresent(Material.class, "COPPER_CHEST");
74+
@Nullable
75+
private static final Material COPPER_WALL_TORCH = Enums.getIfPresent(Material.class, "COPPER_WALL_TORCH").orNull();
76+
@Nullable
77+
private static final Material COPPER_TORCH = Enums.getIfPresent(Material.class, "COPPER_TORCH").orNull();
78+
@Nullable
79+
private static final Material COPPER_CHEST = Enums.getIfPresent(Material.class, "COPPER_CHEST").orNull();
7980
/** All weathered/waxed copper chest variants that normalise to {@link #COPPER_CHEST}. */
8081
private static final List<Material> COPPER_CHEST_VARIANTS = List.of("EXPOSED_COPPER_CHEST", "WEATHERED_COPPER_CHEST",
8182
"OXIDIZED_COPPER_CHEST", "WAXED_COPPER_CHEST", "WAXED_EXPOSED_COPPER_CHEST", "WAXED_WEATHERED_COPPER_CHEST",
8283
"WAXED_OXIDIZED_COPPER_CHEST").stream().map(name -> Enums.getIfPresent(Material.class, name).orNull())
8384
.filter(Objects::nonNull).toList();
8485

86+
/**
87+
* Variant block materials mapped to the canonical material we count them as.
88+
* Pistons are handled separately because the canonical form depends on block data.
89+
*/
90+
private static final Map<Material, Material> VARIANT_MAP = new EnumMap<>(Material.class);
91+
static {
92+
VARIANT_MAP.put(Material.CHIPPED_ANVIL, Material.ANVIL);
93+
VARIANT_MAP.put(Material.DAMAGED_ANVIL, Material.ANVIL);
94+
VARIANT_MAP.put(Material.REDSTONE_WALL_TORCH, Material.REDSTONE_TORCH);
95+
VARIANT_MAP.put(Material.WALL_TORCH, Material.TORCH);
96+
VARIANT_MAP.put(Material.ZOMBIE_WALL_HEAD, Material.ZOMBIE_HEAD);
97+
VARIANT_MAP.put(Material.CREEPER_WALL_HEAD, Material.CREEPER_HEAD);
98+
VARIANT_MAP.put(Material.PLAYER_WALL_HEAD, Material.PLAYER_HEAD);
99+
VARIANT_MAP.put(Material.DRAGON_WALL_HEAD, Material.DRAGON_HEAD);
100+
VARIANT_MAP.put(Material.BAMBOO_SAPLING, Material.BAMBOO);
101+
// 1.21.9 materials: only mapped when present on this server
102+
if (COPPER_WALL_TORCH != null && COPPER_TORCH != null) {
103+
VARIANT_MAP.put(COPPER_WALL_TORCH, COPPER_TORCH);
104+
}
105+
if (COPPER_CHEST != null) {
106+
COPPER_CHEST_VARIANTS.forEach(variant -> VARIANT_MAP.put(variant, COPPER_CHEST));
107+
}
108+
}
109+
85110
/** Save every 10 blocks of change */
86111
private static final Integer CHANGE_LIMIT = 9;
87112
private final Limits addon;
@@ -159,41 +184,45 @@ private void loadEnvSection(String section, Environment env) {
159184
private Map<NamespacedKey, Integer> loadLimits(ConfigurationSection cs) {
160185
Map<NamespacedKey, Integer> limits = new HashMap<>();
161186
for (String key : cs.getKeys(false)) {
162-
int limit = cs.getInt(key);
163-
NamespacedKey nsKey;
164-
if (key.contains(":")) {
165-
nsKey = NamespacedKey.fromString(key.toLowerCase(Locale.ROOT));
166-
if (nsKey == null) {
167-
Bukkit.getLogger().warning("Invalid namespaced key in config, skipping: " + key);
168-
continue;
169-
}
170-
} else {
171-
nsKey = new NamespacedKey(NamespacedKey.MINECRAFT, key.toLowerCase(Locale.ROOT));
187+
NamespacedKey nsKey = parseConfigKey(key);
188+
if (nsKey != null) {
189+
registerLimit(limits, nsKey, key, cs.getInt(key));
172190
}
173-
boolean matched = false;
174-
Material mat = Registry.MATERIAL.get(nsKey);
175-
if (mat != null) {
176-
matched = true;
177-
if (!mat.isBlock()) {
178-
Bukkit.getLogger().warning("Non-block material in block limits config: " + key);
179-
} else if (DO_NOT_COUNT.contains(mat.getKey())) {
180-
Bukkit.getLogger().warning("Uncountable material in block limits config: " + key);
181-
} else {
182-
limits.put(mat.getKey(), limit);
183-
}
184-
}
185-
if (!matched) {
186-
Tag<Material> tag = Bukkit.getTag("blocks", nsKey, Material.class);
187-
if (tag != null) {
188-
limits.put(tag.getKey(), limit);
189-
matched = true;
190-
}
191+
}
192+
return limits;
193+
}
194+
195+
/** Parse a config key into a NamespacedKey, or null if it is an invalid namespaced key. */
196+
private NamespacedKey parseConfigKey(String key) {
197+
if (key.contains(":")) {
198+
NamespacedKey nsKey = NamespacedKey.fromString(key.toLowerCase(Locale.ROOT));
199+
if (nsKey == null) {
200+
Bukkit.getLogger().warning(() -> "Invalid namespaced key in config, skipping: " + key);
191201
}
192-
if (!matched) {
193-
Bukkit.getLogger().warning("Unknown material or tag in config: " + key);
202+
return nsKey;
203+
}
204+
return new NamespacedKey(NamespacedKey.MINECRAFT, key.toLowerCase(Locale.ROOT));
205+
}
206+
207+
/** Resolve a key to a material or block tag and store its limit, warning on any mismatch. */
208+
private void registerLimit(Map<NamespacedKey, Integer> limits, NamespacedKey nsKey, String key, int limit) {
209+
Material mat = Registry.MATERIAL.get(nsKey);
210+
if (mat != null) {
211+
if (!mat.isBlock()) {
212+
Bukkit.getLogger().warning(() -> "Non-block material in block limits config: " + key);
213+
} else if (DO_NOT_COUNT.contains(mat.getKey())) {
214+
Bukkit.getLogger().warning(() -> "Uncountable material in block limits config: " + key);
215+
} else {
216+
limits.put(mat.getKey(), limit);
194217
}
218+
return;
195219
}
196-
return limits;
220+
Tag<Material> tag = Bukkit.getTag("blocks", nsKey, Material.class);
221+
if (tag != null) {
222+
limits.put(tag.getKey(), limit);
223+
return;
224+
}
225+
Bukkit.getLogger().warning(() -> "Unknown material or tag in config: " + key);
197226
}
198227

199228
/** Save the count database completely */
@@ -223,18 +252,18 @@ public void onBlock(BlockBreakEvent e) {
223252
if (e.getBlock().hasMetadata("blockbreakevent-ignore")) {
224253
return;
225254
}
226-
handleBreak(e, e.getBlock());
255+
handleBreak(e.getBlock());
227256
}
228257

229258
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
230259
public void onTurtleEggBreak(PlayerInteractEvent e) {
231260
if (e.getAction().equals(Action.PHYSICAL) && e.getClickedBlock() != null
232261
&& e.getClickedBlock().getType().equals(Material.TURTLE_EGG)) {
233-
handleBreak(e, e.getClickedBlock());
262+
handleBreak(e.getClickedBlock());
234263
}
235264
}
236265

237-
private void handleBreak(Event e, Block b) {
266+
private void handleBreak(Block b) {
238267
if (!addon.inGameModeWorld(b.getWorld())) {
239268
return;
240269
}
@@ -380,35 +409,11 @@ public void onBlock(BlockFromToEvent e) {
380409
*/
381410
public NamespacedKey fixMaterial(BlockData b) {
382411
Material mat = b.getMaterial();
383-
if (mat.equals(Material.CHIPPED_ANVIL) || mat.equals(Material.DAMAGED_ANVIL)) {
384-
return Material.ANVIL.getKey();
385-
} else if (mat == Material.REDSTONE_WALL_TORCH) {
386-
return Material.REDSTONE_TORCH.getKey();
387-
} else if (mat == Material.WALL_TORCH) {
388-
return Material.TORCH.getKey();
389-
} else if (COPPER_WALL_TORCH.isPresent() && mat == COPPER_WALL_TORCH.get() && COPPER_TORCH.isPresent()) {
390-
return COPPER_TORCH.get().getKey();
391-
} else if (mat == Material.ZOMBIE_WALL_HEAD) {
392-
return Material.ZOMBIE_HEAD.getKey();
393-
} else if (mat == Material.CREEPER_WALL_HEAD) {
394-
return Material.CREEPER_HEAD.getKey();
395-
} else if (mat == Material.PLAYER_WALL_HEAD) {
396-
return Material.PLAYER_HEAD.getKey();
397-
} else if (mat == Material.DRAGON_WALL_HEAD) {
398-
return Material.DRAGON_HEAD.getKey();
399-
} else if (mat == Material.BAMBOO_SAPLING) {
400-
return Material.BAMBOO.getKey();
401-
} else if (mat == Material.PISTON_HEAD || mat == Material.MOVING_PISTON) {
412+
if (mat == Material.PISTON_HEAD || mat == Material.MOVING_PISTON) {
402413
TechnicalPiston tp = (TechnicalPiston) b;
403-
if (tp.getType() == TechnicalPiston.Type.NORMAL) {
404-
return Material.PISTON.getKey();
405-
} else {
406-
return Material.STICKY_PISTON.getKey();
407-
}
408-
} else if (COPPER_CHEST.isPresent() && COPPER_CHEST_VARIANTS.contains(mat)) {
409-
return COPPER_CHEST.get().getKey();
414+
return (tp.getType() == TechnicalPiston.Type.NORMAL ? Material.PISTON : Material.STICKY_PISTON).getKey();
410415
}
411-
return mat.getKey();
416+
return VARIANT_MAP.getOrDefault(mat, mat).getKey();
412417
}
413418

414419
private int process(Block b, boolean add) {

0 commit comments

Comments
 (0)