update extras

This commit is contained in:
Chipmunk 2023-12-12 12:00:40 -05:00
commit 1334e758e2
18 changed files with 155 additions and 417 deletions

View file

@ -33,7 +33,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.2.0</version>
<version>3.3.0</version>
<executions>
<execution>
<id>checkstyle</id>

View file

@ -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(

View file

@ -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;
}

View file

@ -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(

View file

@ -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);
}
}
}

View file

@ -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<BlockFace> blockFaces = new HashSet<BlockFace>();
@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<BlockFace> getBlockFaces() {
return blockFaces;
}
private static void updateTPS() {
final double[] tpsValues = Bukkit.getTPS();

View file

@ -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();

View file

@ -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()));
}
}

View file

@ -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());

View file

@ -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());

View file

@ -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<UUID, Long> interactMillisList = new HashMap<UUID, Long>();
@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();

View file

@ -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()));
}
}

View file

@ -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("");
}

View file

@ -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
}
}

View file

@ -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<UUID, String> loginNameList = new HashMap<UUID, String>();
private static final HashMap<UUID, String> 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<String> getOpCompletions(final String argsFragment) {
ArrayList<String> deops = new ArrayList<String>();
final List<String> 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<String> getDeopCompletions(final String argsFragment) {
ArrayList<String> ops = new ArrayList<String>();
final List<String> ops = new ArrayList<>();
for (Player player : Bukkit.getOnlinePlayers()) {
if (player.isOp()) {
String loginName = loginNameList.get(player.getUniqueId());

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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: