diff --git a/pom.xml b/pom.xml index e98f3b3..3adeaf6 100644 --- a/pom.xml +++ b/pom.xml @@ -33,7 +33,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.2.0 + 3.3.0 checkstyle diff --git a/src/main/java/pw/kaboom/extras/Main.java b/src/main/java/pw/kaboom/extras/Main.java index e97f0a0..08aaf37 100644 --- a/src/main/java/pw/kaboom/extras/Main.java +++ b/src/main/java/pw/kaboom/extras/Main.java @@ -12,12 +12,10 @@ import pw.kaboom.extras.modules.block.BlockPhysics; import pw.kaboom.extras.modules.entity.EntityExplosion; import pw.kaboom.extras.modules.entity.EntityKnockback; import pw.kaboom.extras.modules.entity.EntitySpawn; -import pw.kaboom.extras.modules.entity.EntityTeleport; import pw.kaboom.extras.modules.player.*; import pw.kaboom.extras.modules.server.ServerCommand; import pw.kaboom.extras.modules.server.ServerGameRule; import pw.kaboom.extras.modules.server.ServerTabComplete; -import pw.kaboom.extras.modules.server.ServerTick; import java.io.File; import java.util.Collections; @@ -28,16 +26,6 @@ public final class Main extends JavaPlugin { @Override public void onLoad() { - /* Fill lists */ - Collections.addAll( - BlockPhysics.getBlockFaces(), - BlockFace.NORTH, - BlockFace.SOUTH, - BlockFace.WEST, - BlockFace.EAST, - BlockFace.UP - ); - /* Load missing config.yml defaults */ getConfig().options().copyDefaults(true); saveConfig(); @@ -81,7 +69,6 @@ public final class Main extends JavaPlugin { this.getServer().getPluginManager().registerEvents(new EntityExplosion(), this); this.getServer().getPluginManager().registerEvents(new EntityKnockback(), this); this.getServer().getPluginManager().registerEvents(new EntitySpawn(), this); - this.getServer().getPluginManager().registerEvents(new EntityTeleport(), this); /* Player-related modules */ this.getServer().getPluginManager().registerEvents(new PlayerChat(), this); @@ -94,10 +81,11 @@ public final class Main extends JavaPlugin { this.getServer().getPluginManager().registerEvents(new PlayerPrefix(), this); /* Server-related modules */ + ServerGameRule.init(this); + this.getServer().getPluginManager().registerEvents(new ServerCommand(), this); this.getServer().getPluginManager().registerEvents(new ServerGameRule(), this); this.getServer().getPluginManager().registerEvents(new ServerTabComplete(), this); - this.getServer().getPluginManager().registerEvents(new ServerTick(), this); /* Custom worlds */ this.getServer().createWorld( diff --git a/src/main/java/pw/kaboom/extras/commands/CommandConsole.java b/src/main/java/pw/kaboom/extras/commands/CommandConsole.java index b487d73..aaeaead 100644 --- a/src/main/java/pw/kaboom/extras/commands/CommandConsole.java +++ b/src/main/java/pw/kaboom/extras/commands/CommandConsole.java @@ -3,10 +3,10 @@ package pw.kaboom.extras.commands; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; +import pw.kaboom.extras.util.Utility; import javax.annotation.Nonnull; @@ -24,8 +24,7 @@ public final class CommandConsole implements CommandExecutor { Bukkit.dispatchCommand( Bukkit.getConsoleSender(), - "minecraft:say " + ChatColor.translateAlternateColorCodes( - '&', String.join(" ", args)) + "minecraft:say " + Utility.translateLegacyColors(String.join(" ", args)) ); return true; } diff --git a/src/main/java/pw/kaboom/extras/commands/CommandUsername.java b/src/main/java/pw/kaboom/extras/commands/CommandUsername.java index f42804a..f0274b5 100644 --- a/src/main/java/pw/kaboom/extras/commands/CommandUsername.java +++ b/src/main/java/pw/kaboom/extras/commands/CommandUsername.java @@ -4,11 +4,11 @@ import com.destroystokyo.paper.profile.PlayerProfile; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import pw.kaboom.extras.util.Utility; import javax.annotation.Nonnull; import java.util.HashMap; @@ -28,8 +28,7 @@ public final class CommandUsername implements CommandExecutor { return true; } - final String nameColor = ChatColor.translateAlternateColorCodes( - '&', String.join(" ", args)); + final String nameColor = Utility.translateLegacyColors(String.join(" ", args)); final String name = nameColor.substring(0, Math.min(16, nameColor.length())); final long millis = lastUsedMillis.getOrDefault(player, 0L); final long millisDifference = System.currentTimeMillis() - millis; @@ -61,10 +60,11 @@ public final class CommandUsername implements CommandExecutor { return true; } - final PlayerProfile profile = player.getPlayerProfile(); + // Preserve UUIDs, as changing them breaks clients + final PlayerProfile newProfile = Bukkit.createProfileExact(player.getUniqueId(), name); + newProfile.setProperties(player.getPlayerProfile().getProperties()); - profile.setName(name); // FIXME: Marked for removal - player.setPlayerProfile(profile); + player.setPlayerProfile(newProfile); lastUsedMillis.put(player, System.currentTimeMillis()); player.sendMessage( diff --git a/src/main/java/pw/kaboom/extras/modules/block/BlockCheck.java b/src/main/java/pw/kaboom/extras/modules/block/BlockCheck.java index 78f9204..ff3def4 100644 --- a/src/main/java/pw/kaboom/extras/modules/block/BlockCheck.java +++ b/src/main/java/pw/kaboom/extras/modules/block/BlockCheck.java @@ -3,39 +3,13 @@ package pw.kaboom.extras.modules.block; import org.bukkit.Chunk; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.world.ChunkUnloadEvent; public final class BlockCheck implements Listener { - @EventHandler - void onBlockPlace(final BlockPlaceEvent event) { - try { - final int maxItemStringLength = 3019; - - if (event.getItemInHand().toString().length() > maxItemStringLength) { - event.setCancelled(true); - } - - event.getBlockPlaced().getState(); - } catch (Exception exception) { - event.setCancelled(true); - } - } - @EventHandler void onChunkUnload(final ChunkUnloadEvent event) { for (Chunk chunk : event.getChunk().getWorld().getForceLoadedChunks()) { chunk.setForceLoaded(false); } } - - @EventHandler - void onSignChange(final SignChangeEvent event) { - try { - event.getLines(); - } catch (Exception exception) { - event.setCancelled(true); - } - } } diff --git a/src/main/java/pw/kaboom/extras/modules/block/BlockPhysics.java b/src/main/java/pw/kaboom/extras/modules/block/BlockPhysics.java index bb9adb9..f6f5405 100644 --- a/src/main/java/pw/kaboom/extras/modules/block/BlockPhysics.java +++ b/src/main/java/pw/kaboom/extras/modules/block/BlockPhysics.java @@ -1,132 +1,27 @@ package pw.kaboom.extras.modules.block; -import java.util.HashSet; - import org.bukkit.Bukkit; import org.bukkit.Material; -import org.bukkit.block.BlockFace; import org.bukkit.entity.EntityType; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockFadeEvent; import org.bukkit.event.block.BlockFormEvent; -import org.bukkit.event.block.BlockFromToEvent; import org.bukkit.event.block.BlockPhysicsEvent; import org.bukkit.event.block.BlockRedstoneEvent; import org.bukkit.event.entity.EntityChangeBlockEvent; - -import com.destroystokyo.paper.event.block.BlockDestroyEvent; import org.bukkit.scheduler.BukkitScheduler; import pw.kaboom.extras.Main; public final class BlockPhysics implements Listener { - + private static final double MINIMUM_TPS = 10; // This class contains code to prevent large areas of non-solid blocks // from crashing the server private static double tps = 20; - private static HashSet blockFaces = new HashSet(); - - @EventHandler - void onBlockDestroy(final BlockDestroyEvent event) { - try { - if (!event.getBlock().getType().isSolid()) { - for (BlockFace face : getBlockFaces()) { - if (event.getBlock().getRelative(face).getType() - != event.getBlock().getType()) { - return; - } - if (!event.getBlock().getType().equals(Material.AIR)) { - event.getBlock().setType(Material.AIR, false); - } - if (!event.isCancelled()) { - event.setCancelled(true); - } - } - } - } catch (Exception | StackOverflowError e) { - event.setCancelled(true); - } - } - - @EventHandler - void onBlockFade(final BlockFadeEvent event) { - try { - if (event.getBlock().getType() == Material.FIRE) { - event.getBlock().setType(Material.AIR, false); - event.setCancelled(true); - } - } catch (Exception | StackOverflowError e) { - event.setCancelled(true); - } - } - - @EventHandler - void onBlockForm(final BlockFormEvent event) { - try { - if (event.getBlock().getType() == Material.LAVA - || event.getBlock().getType() == Material.WATER) { - for (BlockFace face : getBlockFaces()) { - if (event.getBlock().getRelative(face).getType() != Material.LAVA - && event.getBlock().getRelative(face).getType() != Material.WATER) { - return; - } - event.setCancelled(true); - } - } - } catch (Exception | StackOverflowError e) { - event.setCancelled(true); - } - } - - @EventHandler - void onBlockFromTo(final BlockFromToEvent event) { - try { - if (event.getBlock().getType() == Material.LAVA - || event.getBlock().getType() == Material.WATER) { - boolean lavaFound = false; - boolean waterFound = false; - - for (BlockFace face : getBlockFaces()) { - if (event.getBlock().getRelative(face).getType() == Material.LAVA - && !lavaFound) { - lavaFound = true; - } else if (event.getBlock().getRelative(face).getType() == Material.WATER - && !waterFound) { - waterFound = true; - } - - if (lavaFound && waterFound) { - event.setCancelled(true); - return; - } - } - } - } catch (Exception | StackOverflowError e) { - event.setCancelled(true); - } - } @EventHandler void onBlockPhysics(final BlockPhysicsEvent event) { try { switch (event.getChangedType()) { - case ACTIVATOR_RAIL: - case DETECTOR_RAIL: - case POWERED_RAIL: - case RAIL: - case COMPARATOR: - case REDSTONE_TORCH: - case REDSTONE_WIRE: - case REPEATER: - case TRIPWIRE: - if (!event.getBlock().getRelative(BlockFace.DOWN).getType().isSolid() - && !Material.AIR.equals(event.getBlock().getRelative(BlockFace.DOWN) - .getType()) - && !Material.CAVE_AIR.equals(event.getBlock() - .getRelative(BlockFace.DOWN).getType())) { - event.setCancelled(true); - } - return; case COMMAND_BLOCK: case CHAIN_COMMAND_BLOCK: case REPEATING_COMMAND_BLOCK: @@ -143,15 +38,20 @@ public final class BlockPhysics implements Listener { @EventHandler void onBlockRedstone(final BlockRedstoneEvent event) { - final int maxTps = 10; - - if (tps < maxTps) { + if (tps < MINIMUM_TPS) { event.setNewCurrent(0); } } private int fallingBlockCount; + @EventHandler + void onBlockForm(final BlockFormEvent event) { + if (tps < MINIMUM_TPS) { + event.setCancelled(true); + } + } + @EventHandler void onEntityChangeBlock(final EntityChangeBlockEvent event) { if (event.getEntityType() == EntityType.FALLING_BLOCK @@ -167,10 +67,6 @@ public final class BlockPhysics implements Listener { } } - public static HashSet getBlockFaces() { - return blockFaces; - } - private static void updateTPS() { final double[] tpsValues = Bukkit.getTPS(); diff --git a/src/main/java/pw/kaboom/extras/modules/entity/EntitySpawn.java b/src/main/java/pw/kaboom/extras/modules/entity/EntitySpawn.java index 6e85fe0..43cb8b9 100644 --- a/src/main/java/pw/kaboom/extras/modules/entity/EntitySpawn.java +++ b/src/main/java/pw/kaboom/extras/modules/entity/EntitySpawn.java @@ -19,6 +19,7 @@ import org.bukkit.entity.Vehicle; import org.bukkit.entity.minecart.ExplosiveMinecart; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.bukkit.event.block.TNTPrimeEvent; import org.bukkit.event.entity.AreaEffectCloudApplyEvent; import org.bukkit.event.entity.EntitySpawnEvent; import org.bukkit.event.entity.ExplosionPrimeEvent; @@ -27,7 +28,6 @@ import org.bukkit.event.entity.SpawnerSpawnEvent; import org.bukkit.event.vehicle.VehicleCreateEvent; import org.bukkit.event.weather.LightningStrikeEvent; -import com.destroystokyo.paper.event.block.TNTPrimeEvent; import com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent; import com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent; import org.bukkit.plugin.java.JavaPlugin; @@ -107,21 +107,6 @@ public final class EntitySpawn implements Listener { return false; } - private boolean isOutsideBoundaries(final double x, final double y, final double z) { - final int maxValue = 30000000; - final int minValue = -30000000; - - if (x > maxValue - || x < minValue - || y > maxValue - || y < minValue - || z > maxValue - || z < minValue) { - return true; - } - return false; - } - private void limitAreaEffectCloudRadius(final AreaEffectCloud cloud) { if (cloud.getRadius() > 40) { cloud.setRadius(40); @@ -183,15 +168,6 @@ public final class EntitySpawn implements Listener { @EventHandler void onEntitySpawn(final EntitySpawnEvent event) { - final double x = event.getLocation().getX(); - final double y = event.getLocation().getY(); - final double z = event.getLocation().getZ(); - - if (isOutsideBoundaries(x, y, z)) { - event.setCancelled(true); - return; - } - final EntityType entityType = event.getEntityType(); final Chunk chunk = event.getLocation().getChunk(); final World world = event.getLocation().getWorld(); @@ -221,15 +197,6 @@ public final class EntitySpawn implements Listener { @EventHandler void onLightningStrike(final LightningStrikeEvent event) { final LightningStrike lightning = event.getLightning(); - final double x = lightning.getLocation().getX(); - final double y = lightning.getLocation().getY(); - final double z = lightning.getLocation().getZ(); - - if (isOutsideBoundaries(x, y, z)) { - event.setCancelled(true); - return; - } - final EntityType entityType = EntityType.LIGHTNING; final Chunk chunk = lightning.getChunk(); final World world = event.getWorld(); @@ -273,31 +240,16 @@ public final class EntitySpawn implements Listener { @EventHandler void onTNTPrime(final TNTPrimeEvent event) { - switch (event.getReason()) { - case EXPLOSION: - case FIRE: - case REDSTONE: - if (ThreadLocalRandom.current().nextBoolean()) { - event.setCancelled(true); - } - return; - default: - break; + if (event.getBlock() + .getWorld().getEntitiesByClass(TNTPrimed.class).size() >= MAX_TNTS_PER_WORLD + && ThreadLocalRandom.current().nextBoolean()) { + event.setCancelled(true); } } @EventHandler void onVehicleCreate(final VehicleCreateEvent event) { final Vehicle vehicle = event.getVehicle(); - final double x = vehicle.getLocation().getX(); - final double y = vehicle.getLocation().getY(); - final double z = vehicle.getLocation().getZ(); - - if (isOutsideBoundaries(x, y, z)) { - event.setCancelled(true); - return; - } - final EntityType entityType = vehicle.getType(); final Chunk chunk = vehicle.getChunk(); final World world = vehicle.getWorld(); diff --git a/src/main/java/pw/kaboom/extras/modules/entity/EntityTeleport.java b/src/main/java/pw/kaboom/extras/modules/entity/EntityTeleport.java deleted file mode 100644 index 8858c54..0000000 --- a/src/main/java/pw/kaboom/extras/modules/entity/EntityTeleport.java +++ /dev/null @@ -1,43 +0,0 @@ -package pw.kaboom.extras.modules.entity; - -import org.bukkit.Location; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityTeleportEvent; - -public final class EntityTeleport implements Listener { - public static Location limitLocation(final Location location) { - double x = location.getX(); - double y = location.getY(); - double z = location.getZ(); - - final int maxValue = 30000000; - final int minValue = -30000000; - - if (x > maxValue) { - location.setX(maxValue); - } - if (x < minValue) { - location.setX(minValue); - } - if (y > maxValue) { - location.setY(maxValue); - } - if (y < minValue) { - location.setY(minValue); - } - if (z > maxValue) { - location.setZ(maxValue); - } - if (z < minValue) { - location.setZ(minValue); - } - - return location; - } - - @EventHandler - void onEntityTeleport(final EntityTeleportEvent event) { - event.setTo(limitLocation(event.getTo())); - } -} diff --git a/src/main/java/pw/kaboom/extras/modules/player/PlayerConnection.java b/src/main/java/pw/kaboom/extras/modules/player/PlayerConnection.java index be42ea9..6f1ee1d 100644 --- a/src/main/java/pw/kaboom/extras/modules/player/PlayerConnection.java +++ b/src/main/java/pw/kaboom/extras/modules/player/PlayerConnection.java @@ -3,6 +3,8 @@ package pw.kaboom.extras.modules.player; import com.destroystokyo.paper.event.profile.PreLookupProfileEvent; import com.destroystokyo.paper.profile.ProfileProperty; import com.google.common.base.Charsets; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.title.Title; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Server; @@ -20,6 +22,7 @@ import pw.kaboom.extras.modules.server.ServerTabComplete; import pw.kaboom.extras.modules.player.skin.SkinManager; import pw.kaboom.extras.util.Utility; +import java.time.Duration; import java.util.HashSet; import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; @@ -28,9 +31,9 @@ public final class PlayerConnection implements Listener { private static final FileConfiguration CONFIG = JavaPlugin.getPlugin(Main.class).getConfig(); private static final String TITLE = CONFIG.getString("playerJoinTitle"); private static final String SUBTITLE = CONFIG.getString("playerJoinSubtitle"); - private static final int FADE_IN = 10; - private static final int STAY = 160; - private static final int FADE_OUT = 5; + private static final Duration FADE_IN = Duration.ofMillis(50); + private static final Duration STAY = Duration.ofMillis(8000); + private static final Duration FADE_OUT = Duration.ofMillis(250); private static final boolean ENABLE_KICK = CONFIG.getBoolean("enableKick"); private static final boolean ENABLE_JOIN_RESTRICTIONS = CONFIG.getBoolean( @@ -46,7 +49,7 @@ public final class PlayerConnection implements Listener { if (player != null) { event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, - "A player with that username is already logged in"); + Component.text("A player with that username is already logged in")); } /*try { @@ -67,15 +70,12 @@ public final class PlayerConnection implements Listener { void onPlayerJoin(final PlayerJoinEvent event) { final Player player = event.getPlayer(); - if (TITLE != null - || SUBTITLE != null) { - player.sendTitle( - TITLE, - SUBTITLE, - FADE_IN, - STAY, - FADE_OUT - ); + if (TITLE != null || SUBTITLE != null) { + player.showTitle(Title.title( + Component.text(TITLE), + Component.text(SUBTITLE), + Title.Times.times(FADE_IN, STAY, FADE_OUT) + )); } ServerTabComplete.getLoginNameList().put(player.getUniqueId(), player.getName()); diff --git a/src/main/java/pw/kaboom/extras/modules/player/PlayerDamage.java b/src/main/java/pw/kaboom/extras/modules/player/PlayerDamage.java index 6257d42..cf95d3f 100644 --- a/src/main/java/pw/kaboom/extras/modules/player/PlayerDamage.java +++ b/src/main/java/pw/kaboom/extras/modules/player/PlayerDamage.java @@ -2,6 +2,8 @@ package pw.kaboom.extras.modules.player; import org.bukkit.Bukkit; import org.bukkit.World; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeInstance; import org.bukkit.entity.EntityType; import org.bukkit.entity.ExperienceOrb; import org.bukkit.entity.HumanEntity; @@ -15,6 +17,7 @@ import org.bukkit.event.entity.FoodLevelChangeEvent; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; +import pw.kaboom.extras.util.Utility; public final class PlayerDamage implements Listener { @EventHandler @@ -34,19 +37,17 @@ public final class PlayerDamage implements Listener { } } - @SuppressWarnings("deprecation") @EventHandler void onFoodLevelChange(final FoodLevelChangeEvent event) { final HumanEntity player = event.getEntity(); - - if (player.getMaxHealth() <= 0) { - player.setMaxHealth(Double.POSITIVE_INFINITY); + final AttributeInstance attribute = player.getAttribute(Attribute.GENERIC_MAX_HEALTH); + if (attribute == null) return; + if (attribute.getValue() <= 0) { + Utility.resetAttribute(attribute); player.setHealth(20); - player.setMaxHealth(20); } } - @SuppressWarnings("deprecation") @EventHandler void onPlayerDeath(final PlayerDeathEvent event) { final Player player = event.getEntity(); @@ -70,7 +71,11 @@ public final class PlayerDamage implements Listener { xp.setExperience(event.getDroppedExp()); } - player.setMaxHealth(20); + final AttributeInstance attribute = player.getAttribute(Attribute.GENERIC_MAX_HEALTH); + if (attribute != null) { + Utility.resetAttribute(attribute); + } + player.setHealth(20); if (player.getBedSpawnLocation() != null) { @@ -80,9 +85,11 @@ public final class PlayerDamage implements Listener { player.teleportAsync(world.getSpawnLocation()); } } catch (Exception exception) { - player.setMaxHealth(Double.POSITIVE_INFINITY); + final AttributeInstance attribute = player.getAttribute(Attribute.GENERIC_MAX_HEALTH); + if (attribute != null) { + Utility.resetAttribute(attribute); + } player.setHealth(20); - player.setMaxHealth(20); } player.setExp(event.getNewExp()); diff --git a/src/main/java/pw/kaboom/extras/modules/player/PlayerInteract.java b/src/main/java/pw/kaboom/extras/modules/player/PlayerInteract.java index 34d5c54..b578604 100644 --- a/src/main/java/pw/kaboom/extras/modules/player/PlayerInteract.java +++ b/src/main/java/pw/kaboom/extras/modules/player/PlayerInteract.java @@ -1,28 +1,15 @@ package pw.kaboom.extras.modules.player; import org.bukkit.Material; -import org.bukkit.block.BlockState; -import org.bukkit.block.Sign; import org.bukkit.enchantments.Enchantment; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; -import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; public final class PlayerInteract implements Listener { //static HashMap interactMillisList = new HashMap(); - @EventHandler - void onInventoryClick(final InventoryClickEvent event) { - try { - event.getSlot(); - } catch (Exception exception) { - event.setCancelled(true); - } - } - @EventHandler void onPlayerInteract(final PlayerInteractEvent event) { /*final UUID playerUuid = event.getPlayer().getUniqueId(); diff --git a/src/main/java/pw/kaboom/extras/modules/player/PlayerTeleport.java b/src/main/java/pw/kaboom/extras/modules/player/PlayerTeleport.java index c481801..bc58b07 100644 --- a/src/main/java/pw/kaboom/extras/modules/player/PlayerTeleport.java +++ b/src/main/java/pw/kaboom/extras/modules/player/PlayerTeleport.java @@ -1,27 +1,23 @@ package pw.kaboom.extras.modules.player; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeInstance; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerChangedWorldEvent; -import org.bukkit.event.player.PlayerTeleportEvent; - -import pw.kaboom.extras.modules.entity.EntityTeleport; +import pw.kaboom.extras.util.Utility; public final class PlayerTeleport implements Listener { @EventHandler void onPlayerChangedWorld(final PlayerChangedWorldEvent event) { final Player player = event.getPlayer(); - if (player.getMaxHealth() <= 0) { - player.setMaxHealth(Double.POSITIVE_INFINITY); + final AttributeInstance attribute = player.getAttribute(Attribute.GENERIC_MAX_HEALTH); + if (attribute == null) return; + if (attribute.getValue() <= 0) { + Utility.resetAttribute(attribute); player.setHealth(20); - player.setMaxHealth(20); } } - - @EventHandler - void onPlayerTeleport(final PlayerTeleportEvent event) { - event.setTo(EntityTeleport.limitLocation(event.getTo())); - } } diff --git a/src/main/java/pw/kaboom/extras/modules/server/ServerCommand.java b/src/main/java/pw/kaboom/extras/modules/server/ServerCommand.java index a164b9e..99f2d0a 100644 --- a/src/main/java/pw/kaboom/extras/modules/server/ServerCommand.java +++ b/src/main/java/pw/kaboom/extras/modules/server/ServerCommand.java @@ -11,6 +11,7 @@ import org.bukkit.plugin.java.JavaPlugin; import pw.kaboom.extras.Main; import java.util.Arrays; +import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; @@ -22,33 +23,18 @@ public final class ServerCommand implements Listener { private static final Pattern SELECTOR_PATTERN = Pattern.compile("(?>\\s)*@[aepsr](?>\\s)*"); private static final Logger LOGGER = JavaPlugin.getPlugin(Main.class).getLogger(); + private static final String[] COMMANDS = { "execute", "clone", "fill", "forceload", "kick", + "locate", "locatebiome", /* "me", "msg", */ "reload", "save-all", /* "say", */ "spreadplayers", + "stop", /* "summon", "teammsg", "teleport", "tell", "tellraw", "tm", "tp", "w", */ "place", + "fillbiome", "ride" }; + public static boolean checkExecuteCommand(final String cmd) { - return ("execute".equalsIgnoreCase(cmd) - || "clone".equalsIgnoreCase(cmd) - || "fill".equalsIgnoreCase(cmd) - || "forceload".equalsIgnoreCase(cmd) - || "kick".equalsIgnoreCase(cmd) - || "locate".equalsIgnoreCase(cmd) - || "locatebiome".equalsIgnoreCase(cmd) - // || "me".equalsIgnoreCase(cmd) - // || "msg".equalsIgnoreCase(cmd) - || "reload".equalsIgnoreCase(cmd) - || "save-all".equalsIgnoreCase(cmd) - // || "say".equalsIgnoreCase(cmd) - || "spreadplayers".equalsIgnoreCase(cmd) - || "stop".equalsIgnoreCase(cmd) - // || "summon".equalsIgnoreCase(cmd) - // || "teammsg".equalsIgnoreCase(cmd) - // || "teleport".equalsIgnoreCase(cmd) - // || "tell".equalsIgnoreCase(cmd) - // || "tellraw".equalsIgnoreCase(cmd) - // || "tm".equalsIgnoreCase(cmd) - // || "tp".equalsIgnoreCase(cmd) - // || "w".equalsIgnoreCase(cmd) - || "place".equalsIgnoreCase(cmd) - || "fillbiome".equalsIgnoreCase(cmd) - || "ride".equalsIgnoreCase(cmd) - ); + for (String command : COMMANDS) { + if (command.equalsIgnoreCase(cmd)) { + return true; + } + } + return false; } private static String checkSelectors(final String[] arr) { @@ -87,8 +73,7 @@ public final class ServerCommand implements Listener { try { switch (commandName) { - case "/minecraft:execute": - case "/execute": + case "/minecraft:execute", "/execute" -> { if (arr.length >= 2) { int asAtCount = 0; Matcher asAtMatcher = AS_AT_PATTERN.matcher(command.toLowerCase()); @@ -113,41 +98,36 @@ public final class ServerCommand implements Listener { return "cancel"; } final String[] executeCommand = Arrays.copyOfRange( - arr, i + 1, arr.length); + arr, i + 1, arr.length); final String result = checkCommand(sender, - String.join(" ", executeCommand), true, depth + 1); + String.join(" ", executeCommand), true, depth + 1); if (result == null) { continue; } else if (result.equals("cancel")) { return "cancel"; } final String pureExecute = String.join( - " ", Arrays.copyOfRange(arr, 0, i + 1)); + " ", Arrays.copyOfRange(arr, 0, i + 1)); final String finalResult = checkCommand(sender, - pureExecute + " " + result, isConsoleCommand, depth + 1); - if (finalResult == null) { - return pureExecute + " " + result; - } - return finalResult; + pureExecute + " " + result, isConsoleCommand, depth + 1); + return Objects.requireNonNullElseGet(finalResult, + () -> pureExecute + " " + result); } } - break; - case "/minecraft:fill": - case "/fill": + } + case "/minecraft:fill", "/fill" -> { if (command.contains("auto")) { return command.replace("auto", "[auto]"); } - break; - case "/minecraft:give": - case "/give": + } + case "/minecraft:give", "/give" -> { if (Double.parseDouble(arr[arr.length - 1]) > 64) { // Limit item count arr[arr.length - 1] = "64"; return String.join(" ", arr); } - break; - case "/minecraft:particle": - case "/particle": + } + case "/minecraft:particle", "/particle" -> { int[] numArgs = {14, 10}; for (int i : numArgs) { if (arr.length < i || arr.length > i + 2) { @@ -159,22 +139,13 @@ public final class ServerCommand implements Listener { return String.join(" ", arr); } } - break; - case "/minecraft:ban": - case "/ban": - case "/minecraft:kick": - case "/kick": - case "/minecraft:tell": - case "/tell": - case "/minecraft:msg": - case "/msg": - case "/minecraft:w": - case "/w": - case "/minecraft:say": - case "/say": + } + case "/minecraft:ban", "/ban", "/minecraft:kick", "/kick", + "/minecraft:tell", "/tell", "/minecraft:msg", "/msg", + "/minecraft:w", "/w", "/minecraft:say", "/say" -> { return checkSelectors(arr); - case "/minecraft:spreadplayers": - case "/spreadplayers": + } + case "/minecraft:spreadplayers", "/spreadplayers" -> { if (arr.length == 7 && (arr[6].contains("@e") || arr[6].contains("@a"))) { return "cancel"; } else if (arr.length >= 5) { @@ -189,34 +160,28 @@ public final class ServerCommand implements Listener { } return String.join(" ", arr); } - break; - case "/viaversion:viaver": - case "/viaversion:viaversion": - case "/viaversion:vvbukkit": - case "/viaver": - case "/viaversion": - case "/vvbukkit": + } + case "/viaversion:viaver", "/viaversion:viaversion", "/viaversion:vvbukkit", + "/viaver", "/viaversion", "/vvbukkit" -> { if (arr.length >= 2 && "debug".equalsIgnoreCase(arr[1])) { return "cancel"; } - break; - case "/scissors:scissors": - case "/scissors": - if(arr.length >= 2 - && "reload".equalsIgnoreCase(arr[1])) { + } + case "/scissors:scissors", "/scissors" -> { + if (arr.length >= 2 + && "reload".equalsIgnoreCase(arr[1])) { return "cancel"; } - break; - case "/geyser-spigot:geyser": - case "/geyser": + } + case "/geyser-spigot:geyser", "/geyser" -> { if (arr.length >= 2 && "dump".equalsIgnoreCase(arr[1])) { return "cancel"; } - break; - default: - break; + } + default -> { + } } } catch (NumberFormatException exception) { // Do nothing @@ -229,15 +194,12 @@ public final class ServerCommand implements Listener { void onServerCommand(final ServerCommandEvent event) { final CommandSender sender = event.getSender(); - if (sender instanceof BlockCommandSender) { - final CommandBlock commandBlock = (CommandBlock) ((BlockCommandSender) sender) - .getBlock().getState(); + if (sender instanceof BlockCommandSender blockCommandSender) { + final var commandBlock = (CommandBlock) blockCommandSender.getBlock().getState(); commandBlock.setCommand(""); commandBlock.update(); - } else if (sender instanceof CommandMinecart) { - final CommandMinecart commandMinecart = (CommandMinecart) sender; - + } else if (sender instanceof CommandMinecart commandMinecart) { commandMinecart.setCommand(""); } diff --git a/src/main/java/pw/kaboom/extras/modules/server/ServerGameRule.java b/src/main/java/pw/kaboom/extras/modules/server/ServerGameRule.java index 22c7e8d..f891c69 100644 --- a/src/main/java/pw/kaboom/extras/modules/server/ServerGameRule.java +++ b/src/main/java/pw/kaboom/extras/modules/server/ServerGameRule.java @@ -1,9 +1,13 @@ package pw.kaboom.extras.modules.server; import io.papermc.paper.event.world.WorldGameRuleChangeEvent; +import org.bukkit.Bukkit; import org.bukkit.GameRule; +import org.bukkit.World; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.bukkit.scheduler.BukkitScheduler; +import pw.kaboom.extras.Main; public final class ServerGameRule implements Listener { @EventHandler @@ -19,4 +23,16 @@ public final class ServerGameRule implements Listener { event.setCancelled(true); } } + + private static void enableAutoSave() { + for (final World world: Bukkit.getWorlds()) { + world.setAutoSave(true); + } + } + + public static void init(final Main main) { + final BukkitScheduler scheduler = Bukkit.getScheduler(); + + scheduler.runTaskTimer(main, ServerGameRule::enableAutoSave, 0L, 600L); // 30 seconds + } } diff --git a/src/main/java/pw/kaboom/extras/modules/server/ServerTabComplete.java b/src/main/java/pw/kaboom/extras/modules/server/ServerTabComplete.java index 4ecb541..8b21b54 100644 --- a/src/main/java/pw/kaboom/extras/modules/server/ServerTabComplete.java +++ b/src/main/java/pw/kaboom/extras/modules/server/ServerTabComplete.java @@ -13,7 +13,7 @@ import org.bukkit.event.Listener; import com.destroystokyo.paper.event.server.AsyncTabCompleteEvent; public final class ServerTabComplete implements Listener { - private static HashMap loginNameList = new HashMap(); + private static final HashMap loginNameList = new HashMap<>(); @EventHandler void onAsyncTabComplete(final AsyncTabCompleteEvent event) { @@ -39,13 +39,13 @@ public final class ServerTabComplete implements Listener { return; } - if (event.getCompletions().size() == 0) { + if (event.getCompletions().isEmpty()) { event.setCancelled(true); } } static List getOpCompletions(final String argsFragment) { - ArrayList deops = new ArrayList(); + final List deops = new ArrayList<>(); for (Player player : Bukkit.getOnlinePlayers()) { if (!player.isOp()) { String loginName = loginNameList.get(player.getUniqueId()); @@ -58,7 +58,7 @@ public final class ServerTabComplete implements Listener { } static List getDeopCompletions(final String argsFragment) { - ArrayList ops = new ArrayList(); + final List ops = new ArrayList<>(); for (Player player : Bukkit.getOnlinePlayers()) { if (player.isOp()) { String loginName = loginNameList.get(player.getUniqueId()); diff --git a/src/main/java/pw/kaboom/extras/modules/server/ServerTick.java b/src/main/java/pw/kaboom/extras/modules/server/ServerTick.java deleted file mode 100644 index f5b38b6..0000000 --- a/src/main/java/pw/kaboom/extras/modules/server/ServerTick.java +++ /dev/null @@ -1,19 +0,0 @@ -package pw.kaboom.extras.modules.server; - -import org.bukkit.World; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerStatisticIncrementEvent; - -public final class ServerTick implements Listener { - @EventHandler - void onPlayerStatisticIncrement(final PlayerStatisticIncrementEvent event) { - final World world = event.getPlayer().getWorld(); - - if (!world.isAutoSave()) { - world.setAutoSave(true); - } - - event.setCancelled(true); - } -} diff --git a/src/main/java/pw/kaboom/extras/util/Utility.java b/src/main/java/pw/kaboom/extras/util/Utility.java index e10c9bb..ec56487 100644 --- a/src/main/java/pw/kaboom/extras/util/Utility.java +++ b/src/main/java/pw/kaboom/extras/util/Utility.java @@ -1,8 +1,11 @@ package pw.kaboom.extras.util; import org.bukkit.Bukkit; +import org.bukkit.attribute.AttributeInstance; +import org.bukkit.attribute.AttributeModifier; import org.bukkit.entity.Player; +import javax.annotation.Nonnull; import javax.annotation.Nullable; public final class Utility { @@ -13,4 +16,24 @@ public final class Utility { .findFirst() .orElse(null); } + + public static void resetAttribute(final AttributeInstance attribute) { + for (final AttributeModifier modifier: attribute.getModifiers()) { + attribute.removeModifier(modifier); + } + + attribute.setBaseValue(attribute.getDefaultValue()); + } + + // TODO: Support hex color codes, too (they aren't supported in Spigot either) + public static String translateLegacyColors(@Nonnull String text) { + char[] b = text.toCharArray(); + for (int i = 0; i < b.length - 1; i++) { + if (b[i] == '&' && "0123456789AaBbCcDdEeFfKkLlMmNnOoRrXx".indexOf(b[i + 1]) > -1) { + b[i] = '\u00a7'; + b[i + 1] = Character.toLowerCase(b[i + 1]); + } + } + return new String(b); + } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 066f47e..af498ea 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: Extras main: pw.kaboom.extras.Main description: Plugin that adds extra functionality to the server. -api-version: 1.13 +api-version: '1.19' version: master commands: @@ -22,14 +22,14 @@ commands: description: Broadcasts text in vanilla style permission: extras.broadcastvanilla clearchat: - aliases: cc + aliases: [ cc ] description: Clears messages from the chat permission: extras.clearchat console: description: Broadcasts a message as the console permission: extras.console destroyentities: - aliases: de + aliases: [ de ] description: Destroys all entities in every world permission: extras.destroyentities enchantall: @@ -44,7 +44,7 @@ commands: description: Gets the JSON of a deserialized MiniMessage component permission: extras.getjsonmm jumpscare: - aliases: scare + aliases: [ scare ] description: Scares a player permission: extras.jumpscare kaboom: @@ -62,7 +62,7 @@ commands: description: Places a pumpkin on a player's head permission: extras.pumpkin serverinfo: - aliases: specs + aliases: [ specs ] description: Shows detailed server information permission: extras.serverinfo skin: