1 Commits

Author SHA1 Message Date
pragent test 07e5bb6018 chore: retrigger pragent review (post format-overhaul) 2026-08-20 17:17:44 +00:00
8 changed files with 27 additions and 154 deletions
+1
View File
@@ -611,3 +611,4 @@ Statistic constants get renamed between Minecraft releases, so resolve them via
`Stats.resolve("NEW_NAME", "OLD_NAME")` — a rename then degrades one curiosity `Stats.resolve("NEW_NAME", "OLD_NAME")` — a rename then degrades one curiosity
instead of breaking the whole announcement. instead of breaking the whole announcement.
@@ -868,8 +868,6 @@ public final class Canalhandia extends JavaPlugin implements Listener {
int x = safeLoc.getBlockX(); int x = safeLoc.getBlockX();
int y = safeLoc.getBlockY(); int y = safeLoc.getBlockY();
int z = safeLoc.getBlockZ(); int z = safeLoc.getBlockZ();
pendingDeathCoords.put(player.getUniqueId(), new DeathCoords(
x + " " + y + " " + z + " (" + safeLoc.getWorld().getName() + " - Baú do Vácuo)", false));
getServer().getScheduler().runTaskLater(this, () -> { getServer().getScheduler().runTaskLater(this, () -> {
if (player.isOnline()) { if (player.isOnline()) {
player.sendMessage(Component.text("[Canalhandia] ", NamedTextColor.GOLD) player.sendMessage(Component.text("[Canalhandia] ", NamedTextColor.GOLD)
@@ -886,9 +884,6 @@ public final class Canalhandia extends JavaPlugin implements Listener {
event.setKeepLevel(true); event.setKeepLevel(true);
event.setDroppedExp(0); event.setDroppedExp(0);
} }
pendingDeathCoords.put(player.getUniqueId(), new DeathCoords(
player.getLocation().getBlockX() + " " + player.getLocation().getBlockY() + " " + player.getLocation().getBlockZ()
+ " (" + player.getWorld().getName() + ")", true));
getServer().getScheduler().runTaskLater(this, () -> { getServer().getScheduler().runTaskLater(this, () -> {
if (player.isOnline()) { if (player.isOnline()) {
player.sendMessage(Component.text("[Canalhandia] ", NamedTextColor.GOLD) player.sendMessage(Component.text("[Canalhandia] ", NamedTextColor.GOLD)
@@ -910,7 +905,7 @@ public final class Canalhandia extends JavaPlugin implements Listener {
* {@code [F]} mourning row and never touches {@code deathMessage}, so both * {@code [F]} mourning row and never touches {@code deathMessage}, so both
* fire on the same event without conflict. * fire on the same event without conflict.
*/ */
@EventHandler(priority = EventPriority.MONITOR) @EventHandler
public void onDeathComic(PlayerDeathEvent event) { public void onDeathComic(PlayerDeathEvent event) {
if (!settings.moduleEnabled(Module.MORTES)) { if (!settings.moduleEnabled(Module.MORTES)) {
return; return;
@@ -1999,7 +1999,7 @@ final class CanalhandiaCommand implements CommandExecutor, TabCompleter {
try { try {
double hours = Double.parseDouble(args[1]); double hours = Double.parseDouble(args[1]);
if (hours <= 0 && isAdmin) { if (hours <= 0 && isAdmin) {
plugin.chunkLoaders().setExpiresAt(loader.id(), 0L); // permanent plugin.chunkLoaders().addTime(loader.id(), -loader.expiresAt()); // permanent
Msg.ok(sender, "Âncora " + loader.displayName() + " definida como PERMANENTE."); Msg.ok(sender, "Âncora " + loader.displayName() + " definida como PERMANENTE.");
} else { } else {
long millis = (long) (hours * 3600_000L); long millis = (long) (hours * 3600_000L);
@@ -2202,7 +2202,7 @@ final class CanalhandiaCommand implements CommandExecutor, TabCompleter {
} }
try { try {
int newLimit = Math.max(0, Integer.parseInt(args[1])); int newLimit = Math.max(0, Integer.parseInt(args[1]));
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "lp user " + target.getUniqueId() + " permission set canalhandia.chunkloader.limite." + newLimit); Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "lp user " + target.getName() + " permission set canalhandia.chunkloader.limite." + newLimit);
Msg.ok(sender, "Limite de " + target.getName() + " definido para " + newLimit + " âncoras."); Msg.ok(sender, "Limite de " + target.getName() + " definido para " + newLimit + " âncoras.");
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
Msg.error(sender, "Quantidade inválida: " + args[1]); Msg.error(sender, "Quantidade inválida: " + args[1]);
@@ -300,17 +300,13 @@ final class ChunkLoaderListener implements Listener {
if (!plugin.settings().moduleEnabled(Module.CHUNKLOADER)) { if (!plugin.settings().moduleEnabled(Module.CHUNKLOADER)) {
return; return;
} }
CreatureSpawnEvent.SpawnReason reason = event.getSpawnReason();
if (reason != CreatureSpawnEvent.SpawnReason.SPAWNER && reason != CreatureSpawnEvent.SpawnReason.CUSTOM) {
return;
}
Location loc = event.getLocation(); Location loc = event.getLocation();
World w = loc.getWorld(); World w = loc.getWorld();
if (w == null) { if (w == null) {
return; return;
} }
ChunkLoader loader = plugin.chunkLoaders().byChunk(w.getName(), loc.getBlockX() >> 4, loc.getBlockZ() >> 4); ChunkLoader loader = plugin.chunkLoaders().byChunk(w.getName(), loc.getBlockX() >> 4, loc.getBlockZ() >> 4);
if (loader != null && loader.enabled() && event.getEntity() instanceof Mob mob) { if (loader != null && event.getEntity() instanceof Mob mob) {
mob.setRemoveWhenFarAway(false); mob.setRemoveWhenFarAway(false);
} }
} }
@@ -144,29 +144,6 @@ final class ChunkLoaders {
return false; return false;
} }
/**
* Sets a specific expiration timestamp (or 0 for permanent) for a chunk loader.
*/
boolean setExpiresAt(long id, long expiresAt) {
ChunkLoader updated = null;
synchronized (loaders) {
for (int i = 0; i < loaders.size(); i++) {
ChunkLoader curr = loaders.get(i);
if (curr.id() == id) {
updated = curr.withExpiresAt(expiresAt).withEnabled(true);
loaders.set(i, updated);
break;
}
}
}
if (updated != null) {
addTicket(updated);
save();
return true;
}
return false;
}
/** /**
* Renames an existing chunk loader. * Renames an existing chunk loader.
*/ */
@@ -470,21 +447,15 @@ final class ChunkLoaders {
} }
static EntityType pickEntityType(World w, Block space, int light) { static EntityType pickEntityType(World w, Block space, int light) {
boolean isSlime = false; World.Environment env = w.getEnvironment();
try { ThreadLocalRandom rnd = ThreadLocalRandom.current();
isSlime = space.getChunk().isSlimeChunk();
} catch (Exception ignored) {
}
return pickEntityType(w.getEnvironment(), isSlime, space.getY(), light, ThreadLocalRandom.current().nextInt(100));
}
static EntityType pickEntityType(World.Environment env, boolean isSlimeChunk, int y, int light, int roll) {
if (env == World.Environment.NETHER) { if (env == World.Environment.NETHER) {
if (light > 11) return null; if (light > 11) return null;
int r = Math.floorMod(roll, 100); int roll = rnd.nextInt(100);
if (r < 45) return EntityType.ZOMBIFIED_PIGLIN; if (roll < 45) return EntityType.ZOMBIFIED_PIGLIN;
if (r < 65) return EntityType.WITHER_SKELETON; if (roll < 65) return EntityType.WITHER_SKELETON;
if (r < 85) return EntityType.BLAZE; if (roll < 85) return EntityType.BLAZE;
return EntityType.MAGMA_CUBE; return EntityType.MAGMA_CUBE;
} }
@@ -492,7 +463,8 @@ final class ChunkLoaders {
return EntityType.ENDERMAN; return EntityType.ENDERMAN;
} }
if (isSlimeChunk && y < 40 && light <= 7 && roll % 3 == 0) { boolean isSlimeChunk = space.getChunk().isSlimeChunk() && space.getY() < 40;
if (isSlimeChunk && light <= 7 && rnd.nextInt(3) == 0) {
return EntityType.SLIME; return EntityType.SLIME;
} }
@@ -500,11 +472,11 @@ final class ChunkLoaders {
return null; return null;
} }
int r = Math.floorMod(roll, 100); int roll = rnd.nextInt(100);
if (r < 35) return EntityType.ZOMBIE; if (roll < 35) return EntityType.ZOMBIE;
if (r < 65) return EntityType.SKELETON; if (roll < 65) return EntityType.SKELETON;
if (r < 85) return EntityType.CREEPER; if (roll < 85) return EntityType.CREEPER;
if (r < 95) return EntityType.SPIDER; if (roll < 95) return EntityType.SPIDER;
return EntityType.WITCH; return EntityType.WITCH;
} }
@@ -108,35 +108,24 @@ public final class VoidProtection {
} }
static boolean isSafeGround(Block block) { static boolean isSafeGround(Block block) {
return block != null && isSafeGroundMaterial(block.getType()); if (block == null) {
}
public static boolean isSafeGroundMaterial(Material mat) {
if (mat == null || mat == Material.AIR || mat == Material.CAVE_AIR || mat == Material.VOID_AIR) {
return false; return false;
} }
if (mat == Material.LAVA || mat == Material.WATER || mat == Material.FIRE || mat == Material.SOUL_FIRE Material mat = block.getType();
|| mat == Material.CACTUS || mat == Material.MAGMA_BLOCK || mat == Material.SWEET_BERRY_BUSH if (mat.isAir() || !mat.isSolid()) {
|| mat == Material.WITHER_ROSE || mat == Material.POWDER_SNOW) {
return false; return false;
} }
try { return mat != Material.LAVA && mat != Material.FIRE && mat != Material.SOUL_FIRE
return mat.isSolid(); && mat != Material.CACTUS && mat != Material.MAGMA_BLOCK && mat != Material.SWEET_BERRY_BUSH
} catch (Exception | LinkageError e) { && mat != Material.WITHER_ROSE && mat != Material.POWDER_SNOW;
return true;
}
} }
static boolean isReplaceable(Block block) { static boolean isReplaceable(Block block) {
return block != null && isReplaceableMaterial(block.getType()); if (block == null) {
}
public static boolean isReplaceableMaterial(Material mat) {
if (mat == null) {
return false; return false;
} }
return mat == Material.AIR || mat == Material.CAVE_AIR || mat == Material.VOID_AIR Material mat = block.getType();
|| mat == Material.SHORT_GRASS || mat == Material.TALL_GRASS return mat.isAir() || mat == Material.SHORT_GRASS || mat == Material.TALL_GRASS
|| mat == Material.SNOW || mat == Material.FERN || mat == Material.LARGE_FERN; || mat == Material.SNOW || mat == Material.FERN || mat == Material.LARGE_FERN;
} }
@@ -151,50 +151,6 @@ class ChunkLoaderTest {
ChunkLoader expired = timed.withExpiresAt(System.currentTimeMillis() - 1000L); ChunkLoader expired = timed.withExpiresAt(System.currentTimeMillis() - 1000L);
assertTrue(expired.isExpired()); assertTrue(expired.isExpired());
assertEquals("Expirado", expired.timeLeft()); assertEquals("Expirado", expired.timeLeft());
assertTrue(loaders.setExpiresAt(loader.id(), 0L));
ChunkLoader permanent = loaders.byId(loader.id());
assertNotNull(permanent);
assertEquals(0L, permanent.expiresAt());
assertEquals("Permanente", permanent.timeLeft());
assertFalse(permanent.isExpired());
}
@Test
void pickEntityTypeReturnsExpectedEntitiesByEnvironment() {
// Nether
assertEquals(org.bukkit.entity.EntityType.ZOMBIFIED_PIGLIN,
ChunkLoaders.pickEntityType(org.bukkit.World.Environment.NETHER, false, 64, 0, 10));
assertEquals(org.bukkit.entity.EntityType.WITHER_SKELETON,
ChunkLoaders.pickEntityType(org.bukkit.World.Environment.NETHER, false, 64, 0, 50));
assertEquals(org.bukkit.entity.EntityType.BLAZE,
ChunkLoaders.pickEntityType(org.bukkit.World.Environment.NETHER, false, 64, 0, 75));
assertEquals(org.bukkit.entity.EntityType.MAGMA_CUBE,
ChunkLoaders.pickEntityType(org.bukkit.World.Environment.NETHER, false, 64, 0, 90));
assertNull(ChunkLoaders.pickEntityType(org.bukkit.World.Environment.NETHER, false, 64, 12, 10));
// End
assertEquals(org.bukkit.entity.EntityType.ENDERMAN,
ChunkLoaders.pickEntityType(org.bukkit.World.Environment.THE_END, false, 64, 15, 50));
// Overworld Slime Chunk
assertEquals(org.bukkit.entity.EntityType.SLIME,
ChunkLoaders.pickEntityType(org.bukkit.World.Environment.NORMAL, true, 30, 5, 0));
// Overworld Normal Darkness
assertEquals(org.bukkit.entity.EntityType.ZOMBIE,
ChunkLoaders.pickEntityType(org.bukkit.World.Environment.NORMAL, false, 64, 0, 10));
assertEquals(org.bukkit.entity.EntityType.SKELETON,
ChunkLoaders.pickEntityType(org.bukkit.World.Environment.NORMAL, false, 64, 0, 45));
assertEquals(org.bukkit.entity.EntityType.CREEPER,
ChunkLoaders.pickEntityType(org.bukkit.World.Environment.NORMAL, false, 64, 0, 75));
assertEquals(org.bukkit.entity.EntityType.SPIDER,
ChunkLoaders.pickEntityType(org.bukkit.World.Environment.NORMAL, false, 64, 0, 90));
assertEquals(org.bukkit.entity.EntityType.WITCH,
ChunkLoaders.pickEntityType(org.bukkit.World.Environment.NORMAL, false, 64, 0, 99));
// Overworld in Light -> Null
assertNull(ChunkLoaders.pickEntityType(org.bukkit.World.Environment.NORMAL, false, 64, 5, 10));
} }
@Test @Test
@@ -32,42 +32,6 @@ class VoidProtectionTest {
assertFalse(VoidProtection.rescueToChest(List.of(), null)); assertFalse(VoidProtection.rescueToChest(List.of(), null));
} }
@Test
void validatesSafeGroundMaterials() {
assertTrue(VoidProtection.isSafeGroundMaterial(org.bukkit.Material.STONE));
assertTrue(VoidProtection.isSafeGroundMaterial(org.bukkit.Material.GRASS_BLOCK));
assertTrue(VoidProtection.isSafeGroundMaterial(org.bukkit.Material.DIRT));
assertTrue(VoidProtection.isSafeGroundMaterial(org.bukkit.Material.OBSIDIAN));
assertFalse(VoidProtection.isSafeGroundMaterial(null));
assertFalse(VoidProtection.isSafeGroundMaterial(org.bukkit.Material.AIR));
assertFalse(VoidProtection.isSafeGroundMaterial(org.bukkit.Material.LAVA));
assertFalse(VoidProtection.isSafeGroundMaterial(org.bukkit.Material.FIRE));
assertFalse(VoidProtection.isSafeGroundMaterial(org.bukkit.Material.SOUL_FIRE));
assertFalse(VoidProtection.isSafeGroundMaterial(org.bukkit.Material.CACTUS));
assertFalse(VoidProtection.isSafeGroundMaterial(org.bukkit.Material.MAGMA_BLOCK));
assertFalse(VoidProtection.isSafeGroundMaterial(org.bukkit.Material.SWEET_BERRY_BUSH));
assertFalse(VoidProtection.isSafeGroundMaterial(org.bukkit.Material.WITHER_ROSE));
assertFalse(VoidProtection.isSafeGroundMaterial(org.bukkit.Material.POWDER_SNOW));
}
@Test
void validatesReplaceableMaterials() {
assertTrue(VoidProtection.isReplaceableMaterial(org.bukkit.Material.AIR));
assertTrue(VoidProtection.isReplaceableMaterial(org.bukkit.Material.CAVE_AIR));
assertTrue(VoidProtection.isReplaceableMaterial(org.bukkit.Material.VOID_AIR));
assertTrue(VoidProtection.isReplaceableMaterial(org.bukkit.Material.SHORT_GRASS));
assertTrue(VoidProtection.isReplaceableMaterial(org.bukkit.Material.TALL_GRASS));
assertTrue(VoidProtection.isReplaceableMaterial(org.bukkit.Material.SNOW));
assertTrue(VoidProtection.isReplaceableMaterial(org.bukkit.Material.FERN));
assertTrue(VoidProtection.isReplaceableMaterial(org.bukkit.Material.LARGE_FERN));
assertFalse(VoidProtection.isReplaceableMaterial(null));
assertFalse(VoidProtection.isReplaceableMaterial(org.bukkit.Material.STONE));
assertFalse(VoidProtection.isReplaceableMaterial(org.bukkit.Material.CHEST));
assertFalse(VoidProtection.isReplaceableMaterial(org.bukkit.Material.OBSIDIAN));
}
@Test @Test
void nullBlocksAreNeitherSafeNorReplaceable() { void nullBlocksAreNeitherSafeNorReplaceable() {
assertFalse(VoidProtection.isSafeGround(null)); assertFalse(VoidProtection.isSafeGround(null));