Compare commits

..

5 commits

Author SHA1 Message Date
94d1fde563
Merge remote-tracking branch 'upstream' 2025-01-25 00:29:02 -03:00
9e26b370dd
fix: whoops 2024-11-01 11:29:00 -03:00
85fe8525d8
fix: tweak spawner restrictions 2024-11-01 11:28:04 -03:00
70f7134de9
fix: restrict spawners, a lot
LOL! Whoops!
2024-09-29 18:19:03 -03:00
a58ef649cf
fix: highly experimental (and hacky!) patch for kick exploit 2024-09-29 12:46:02 -03:00
7 changed files with 35 additions and 185 deletions
.github/workflows
pom.xml
src/main/java/pw/kaboom/extras

View file

@ -11,14 +11,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: 21
java-version: 17
- name: Cache maven packages to speed up build
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
@ -27,7 +27,7 @@ jobs:
- name: Build with Maven
run: mvn -B package --file pom.xml
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v3
with:
name: Extras
path: target/Extras.jar

22
pom.xml
View file

@ -18,14 +18,6 @@
<version>1.20.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>6.4.5</version>
<!-- This is a vanilla dependency, as of 1.20.4 -->
<scope>provided</scope>
</dependency>
</dependencies>
<repositories>
@ -37,19 +29,7 @@
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<archive>
<manifestEntries>
<paperweight-mappings-namespace>mojang</paperweight-mappings-namespace>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>

View file

@ -1,61 +1,16 @@
package pw.kaboom.extras.commands;
import it.unimi.dsi.fastutil.Pair;
import it.unimi.dsi.fastutil.objects.ObjectObjectImmutablePair;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.Nullable;
import oshi.SystemInfo;
import oshi.hardware.GraphicsCard;
import pw.kaboom.extras.util.Utility;
import javax.annotation.Nonnull;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
public final class CommandServerInfo implements CommandExecutor {
private static final @Nullable String[] GPU_DEVICES;
private static final @Nullable String PROCESSOR_NAME;
static {
// No need to store this in a static variable as it would
// just waste memory & won't be accessed outside construction
// anyway.
final SystemInfo systemInfo = new SystemInfo();
// Unfortunately, we need to do something like this
// because calls to getHardware may fail if the
// server is running on an unrecognized platform,
// and we're unable to use guard clauses due to
// returns not being supported in static blocks.
final @Nullable Pair<String[], String> hardwareInfo = Utility.composeCallable(
systemInfo::getHardware,
hardware ->
new ObjectObjectImmutablePair<>(
hardware.getGraphicsCards()
.stream()
.map(GraphicsCard::getName)
.toArray(String[]::new),
hardware.getProcessor()
.getProcessorIdentifier()
.getName()
)
);
if (hardwareInfo == null) {
GPU_DEVICES = null;
PROCESSOR_NAME = null;
} else {
GPU_DEVICES = hardwareInfo.first();
PROCESSOR_NAME = hardwareInfo.second();
}
}
private void sendInfoMessage(final CommandSender target, final String description,
final String value) {
target.sendMessage(
@ -95,8 +50,6 @@ public final class CommandServerInfo implements CommandExecutor {
+ ManagementFactory.getRuntimeMXBean().getVmVersion()
);
sendInfoMessage(sender, "CPU model", PROCESSOR_NAME);
sendInfoMessage(sender, "CPU cores",
String.valueOf(Runtime.getRuntime().availableProcessors())
);
@ -104,14 +57,6 @@ public final class CommandServerInfo implements CommandExecutor {
String.valueOf(ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage())
);
for (int i = 0; i < GPU_DEVICES.length; i++) {
sendInfoMessage(
sender,
"GPU device (" + i + ")",
GPU_DEVICES[i]
);
}
final long heapUsage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed();
final long nonHeapUsage = ManagementFactory.getMemoryMXBean()
.getNonHeapMemoryUsage().getUsed();

View file

@ -3,7 +3,6 @@ package pw.kaboom.extras.commands;
import net.kyori.adventure.text.Component;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@ -38,11 +37,10 @@ public final class CommandSpidey implements CommandExecutor {
distance
);
while (blockIterator.hasNext()) {
final Block block = blockIterator.next();
if (block.getType() != Material.COBWEB && !block.getType().isAir()) break;
block.setType(Material.COBWEB);
while (blockIterator.hasNext()
&& (Material.AIR.equals(blockIterator.next().getType())
|| Material.CAVE_AIR.equals(blockIterator.next().getType()))) {
blockIterator.next().setType(Material.COBWEB);
}
return true;
}

View file

@ -3,15 +3,12 @@ package pw.kaboom.extras.modules.entity;
import java.util.concurrent.ThreadLocalRandom;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.AreaEffectCloud;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.LightningStrike;
import org.bukkit.entity.Slime;
import org.bukkit.entity.TNTPrimed;
@ -23,13 +20,10 @@ import org.bukkit.event.block.TNTPrimeEvent;
import org.bukkit.event.entity.AreaEffectCloudApplyEvent;
import org.bukkit.event.entity.EntitySpawnEvent;
import org.bukkit.event.entity.ExplosionPrimeEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.entity.SpawnerSpawnEvent;
import org.bukkit.event.vehicle.VehicleCreateEvent;
import org.bukkit.event.weather.LightningStrikeEvent;
import com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent;
import com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent;
import org.bukkit.plugin.java.JavaPlugin;
import pw.kaboom.extras.Main;
@ -130,48 +124,6 @@ public final class EntitySpawn implements Listener {
}
}
private boolean limitSpawner(final CreatureSpawner spawner) {
final EntityType spawnedType = spawner.getSpawnedType();
boolean didChange = false;
if (!spawnedType.isAlive() || spawnedType.equals(EntityType.ARMOR_STAND)) {
spawner.setSpawnedType(EntityType.PIG);
didChange = true;
}
if (spawner.getMaxSpawnDelay() < 2000) {
spawner.setMaxSpawnDelay(2000);
didChange = true;
}
if (spawner.getMinSpawnDelay() < 1000) {
spawner.setMinSpawnDelay(1000);
didChange = true;
}
if (spawner.getDelay() < 2000) {
spawner.setDelay(2000);
didChange = true;
}
if (spawner.getSpawnCount() > 10) {
spawner.setSpawnCount(10);
didChange = true;
}
if (spawner.getSpawnRange() > 64) {
spawner.setSpawnRange(64);
didChange = true;
}
if (didChange) {
spawner.update();
return true;
}
return false;
}
@EventHandler
void onAreaEffectCloudApply(final AreaEffectCloudApplyEvent event) {
limitAreaEffectCloudRadius(event.getEntity());
@ -228,28 +180,6 @@ public final class EntitySpawn implements Listener {
}
}
@EventHandler
void onPreSpawnerSpawn(final PreSpawnerSpawnEvent event) {
final CreatureSpawner spawner = (CreatureSpawner)event.getSpawnerLocation().getBlock()
.getState();
if (limitSpawner(spawner)) {
event.setCancelled(true);
}
}
@EventHandler
void onSpawnerSpawn(final SpawnerSpawnEvent event) {
if (EntityType.FALLING_BLOCK.equals(event.getEntityType())) {
final FallingBlock block = (FallingBlock) event.getEntity();
if (block.getBlockData().getMaterial().equals(Material.SPAWNER)) {
event.setCancelled(true);
event.getSpawner().setSpawnedType(EntityType.FALLING_BLOCK);
}
}
}
@EventHandler
void onTNTPrime(final TNTPrimeEvent event) {
if (event.getBlock()

View file

@ -1,6 +1,5 @@
package pw.kaboom.extras.modules.server;
import com.google.common.collect.ImmutableSet;
import org.bukkit.block.CommandBlock;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
@ -13,20 +12,29 @@ import pw.kaboom.extras.Main;
import java.util.Arrays;
import java.util.Objects;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class ServerCommand implements Listener {
private static final Pattern SELECTOR_PATTERN = Pattern.compile("(?>\\s)*@[aenprs](?>\\s)*");
private static final Pattern SELECTOR_PATTERN = Pattern.compile("(?>\\s)*@[aepsr](?>\\s)*");
private static final Logger LOGGER = JavaPlugin.getPlugin(Main.class).getLogger();
private static final Set<String> BLOCKED_EXECUTE_COMMANDS = ImmutableSet.of(
"clone", "fill", "give", "kick", "locate", "me", "msg", "save-all", "say",
"spawnpoint", "spreadplayers", "summon", "teammsg", "teleport", "tell", "tellraw",
"tm", "tp", "w", "fillbiome", "ride");
private static final String[] COMMANDS = {"clone", "datapack", "fill", "forceload",
"give", "kick", "locate", "locatebiome", "me", "msg", "reload", "save-all",
"say", "spawnpoint", "spreadplayers", "stop", "summon", "teammsg",
"teleport", "tell", "tellraw", "tm", "tp", "w", "place", "fillbiome", "ride",
"tick", "jfr"};
public static boolean checkExecuteCommand(final String cmd) {
for (String command : COMMANDS) {
if (command.equalsIgnoreCase(cmd)) {
return true;
}
}
return false;
}
public static boolean checkValidUTF8(final String component) {
int len = component.length();
@ -41,8 +49,8 @@ public final class ServerCommand implements Listener {
return len <= 65535;
}
private static String checkSelectors(final String[] arr, final int offset) {
final String[] args = Arrays.copyOfRange(arr, offset, arr.length);
private static String checkSelectors(final String[] arr) {
final String[] args = Arrays.copyOfRange(arr, 1, arr.length);
final String str = String.join(" ", args);
final Matcher matcher = SELECTOR_PATTERN.matcher(str);
final long count = matcher.results().count();
@ -86,10 +94,6 @@ public final class ServerCommand implements Listener {
switch (commandName) {
case "/minecraft:execute", "/execute" -> {
if (arr.length >= 2) {
if (arr.length >= 3 && checkSelectors(arr, 2) != null) {
return "cancel";
}
for (int i = 1; i < arr.length; i++) {
if ("summon".equalsIgnoreCase(arr[i])) {
return "cancel";
@ -100,7 +104,7 @@ public final class ServerCommand implements Listener {
if (i + 1 == arr.length) {
break;
}
if (BLOCKED_EXECUTE_COMMANDS.contains(arr[i + 1])) {
if (checkExecuteCommand(arr[i + 1])) {
return "cancel";
}
final String[] executeCommand = Arrays.copyOfRange(
@ -149,7 +153,7 @@ public final class ServerCommand implements Listener {
case "/minecraft:ban", "/ban", "/minecraft:kick", "/kick",
"/minecraft:tell", "/tell", "/minecraft:msg", "/msg",
"/minecraft:w", "/w", "/minecraft:say", "/say" -> {
return checkSelectors(arr, 1);
return checkSelectors(arr);
}
case "/minecraft:spreadplayers", "/spreadplayers" -> {
if (arr.length == 7 && (arr[6].contains("@e") || arr[6].contains("@a"))) {
@ -174,6 +178,12 @@ public final class ServerCommand implements Listener {
return "cancel";
}
}
case "/scissors:scissors", "/scissors" -> {
if (arr.length >= 2
&& "reload".equalsIgnoreCase(arr[1])) {
return "cancel";
}
}
case "/geyser-spigot:geyser", "/geyser" -> {
if (arr.length >= 2
&& "dump".equalsIgnoreCase(arr[1])) {

View file

@ -7,8 +7,6 @@ import org.bukkit.entity.Player;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.concurrent.Callable;
import java.util.function.Function;
public final class Utility {
public static @Nullable Player getPlayerExactIgnoreCase(final String username) {
@ -38,15 +36,4 @@ public final class Utility {
}
return new String(b);
}
public static <T, R> @Nullable R composeCallable(
Callable<T> callable,
Function<T, R> composer
) {
try {
return composer.apply(callable.call());
} catch (Exception e) {
return null;
}
}
}