Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into dev
Browse files Browse the repository at this point in the history
# Conflicts:
#	AnarchyExploitFixesFolia/src/main/java/me/xginko/aef/modules/chunklimits/DroppedItemLimit.java
#	AnarchyExploitFixesFolia/src/main/java/me/xginko/aef/modules/lagpreventions/agelimits/CustomAgeLimits.java
#	AnarchyExploitFixesFolia/src/main/java/me/xginko/aef/modules/preventions/withers/RemoveSkullsOnChunkload.java
#	AnarchyExploitFixesLegacy/src/main/java/me/xginko/aef/modules/preventions/withers/RemoveSkullsOnChunkload.java
#	shared/src/main/java/me/xginko/aef/utils/ChunkUtil.java
  • Loading branch information
xGinko committed Nov 5, 2024
2 parents fe4b563 + 8b1b943 commit a3b10af
Show file tree
Hide file tree
Showing 13 changed files with 193 additions and 345 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.EntitiesLoadEvent;

import java.time.Duration;
import java.util.EnumSet;
Expand All @@ -36,7 +36,7 @@ public class DroppedItemLimit extends AEFModule implements Consumer<ScheduledTas
private final Set<Material> whitelistedTypes;
private final long checkPeriod, cleanupDelay;
private final int maxDroppedItemsPerChunk;
private final boolean logIsEnabled, usingWhitelist, onChunkLoad;
private final boolean logIsEnabled, usingWhitelist, onEntitiesLoad;

public DroppedItemLimit() {
super("chunk-limits.entity-limits.dropped-item-limit");
Expand All @@ -57,8 +57,8 @@ public DroppedItemLimit() {
checked. Keep in mind: A lower number provides more accuracy but is\s
also worse for performance.""");
this.scheduledChecks = Caffeine.newBuilder().expireAfterWrite(Duration.ofMillis(cleanupDelay * 50L)).build();
this.onChunkLoad = config.getBoolean(configPath + ".check-on-chunk-load", true, """
Runs item check when a chunk is loaded.""");
this.onEntitiesLoad = config.getBoolean(configPath + ".check-on-entities-load", true, """
Runs item check when a chunk's entities are loaded.""");
this.usingWhitelist = config.getBoolean(configPath + ".whitelist-specific-item-types", false);
this.whitelistedTypes = config.getList(configPath + ".whitelisted-types",
MaterialTags.SHULKER_BOXES.getValues().stream().map(Enum::name).sorted().toList(), """
Expand Down Expand Up @@ -124,13 +124,12 @@ private void onItemDrop(ItemSpawnEvent event) {
}

@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
private void onChunkLoad(ChunkLoadEvent event) {
if (!onChunkLoad || event.isNewChunk()) return;
if (ChunkUtil.isRetrievalUnsafe(event.getChunk())) return;
private void onEntitiesLoad(EntitiesLoadEvent event) {
if (!onEntitiesLoad) return;

int droppedItemCount = 0;

for (Entity entity : event.getChunk().getEntities()) {
for (Entity entity : event.getEntities()) {
if (entity.getType() != XEntityType.ITEM.get()) continue;

droppedItemCount++;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package me.xginko.aef.modules.dupepreventions;

import com.github.retrooper.packetevents.event.PacketListenerPriority;
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientEditBook;
import me.xginko.aef.modules.packets.PacketModule;
import me.xginko.aef.utils.PlatformUtil;

public class BookTitleDupe extends PacketModule {

private final int maxTitleChars;

public BookTitleDupe() {
super("dupe-preventions.book-title-dupe", PacketListenerPriority.HIGHEST);
config.addComment(configPath + ".enable", """
Relevant for 1.20.6 - 1.21:
Will prevent players from sending book packets with a too large title,
to get disconnected and their inventories restored.""");
this.maxTitleChars = config.getInt(configPath + ".max-title-charlength", 20, """
Normal ascii like charlimit in vanilla is 15, you could need a bit more
if you want to support languages with special characters.""");
}

@Override
public boolean shouldEnable() {
return config.getBoolean(configPath + ".enable", PlatformUtil.getMinecraftPatchVersion() > 19);
}

@Override
public void onPacketReceive(PacketReceiveEvent event) {
if (event.getPacketType() != PacketType.Play.Client.EDIT_BOOK) return;

WrapperPlayClientEditBook packet = new WrapperPlayClientEditBook(event);
if (packet.getTitle() == null) return;

if (packet.getTitle().length() > maxTitleChars) {
event.setCancelled(true);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class KeepStashLoaded extends AEFModule implements Consumer<ScheduledTask
private final Map<ChunkUID, Long> forceLoadedChunks;
private final Map<String, Double> worldsAndTheirRadiuses = new HashMap<>();
private final Set<Material> storageTypes;
private final long minInhabitedTime, keepLoadedMillis;
private final long minInhabitedTime, keepLoadedMillis, checkDelayTicks;
private final int stashCount;
private final boolean logIsEnabled, onlyTileEntities;

Expand All @@ -50,6 +50,9 @@ public KeepStashLoaded() {
this.stashCount = config.getInt(configPath + ".container-block-threshold", 50, """
How many container blocks have to be in a chunk for it to be seen\s
as a stash chunk to keep force loaded.""");
this.checkDelayTicks = config.getInt(configPath + ".check-delay-ticks", 200, """
Ticks to wait after a chunk is loaded before it will be checked.\s
Reduces lag by fast travelling players.""");
this.minInhabitedTime = config.getInt(configPath + ".min-chunk-inhabited-time-ticks", 1000, """
The minimum time in ticks a chunk has to have been inhabited to be checked.""");
this.keepLoadedMillis = TimeUnit.MINUTES.toMillis(config.getInt(configPath + ".keep-loaded-minutes", 120, """
Expand Down Expand Up @@ -141,6 +144,7 @@ public void accept(ScheduledTask task) {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
private void onChunkLoad(ChunkLoadEvent event) {
if (event.isNewChunk()) return;

final String world = event.getWorld().getName();
if (!worldsAndTheirRadiuses.containsKey(world)) return;

Expand All @@ -149,31 +153,28 @@ private void onChunkLoad(ChunkLoadEvent event) {
if (chunk.getInhabitedTime() < minInhabitedTime) return;
if (NumberConversions.square(chunk.getX()) + NumberConversions.square(chunk.getZ()) < worldsAndTheirRadiuses.get(world)) return;

if (isStashChunk(chunk)) {
forceLoadedChunks.computeIfAbsent(ChunkUID.of(chunk), chunkUID -> {
plugin.getServer().getGlobalRegionScheduler().execute(plugin, () -> {
chunk.setForceLoaded(true);
if (logIsEnabled)
info("Set chunk " + chunkUID + " to force loaded.");
});
return System.currentTimeMillis() + keepLoadedMillis;
});
}
}

private boolean isStashChunk(Chunk chunk) {
int count = 0;

if (onlyTileEntities) {
for (BlockState tileEntity : chunk.getTileEntities()) {
if (storageTypes.contains(tileEntity.getType())) {
count++;
if (count > stashCount) {
return true;
plugin.getServer().getRegionScheduler().runDelayed(plugin, chunk.getWorld(), chunk.getX(), chunk.getZ(), delayedCheck -> {
if (!chunk.isLoaded()) return;

int count = 0;

if (onlyTileEntities) {
for (BlockState tileEntity : chunk.getTileEntities()) {
if (storageTypes.contains(tileEntity.getType())) {
count++;
if (count > stashCount) {
chunk.setForceLoaded(true);
forceLoadedChunks.computeIfAbsent(ChunkUID.of(chunk), chunkUID -> {
if (logIsEnabled) info("Set chunk " + chunkUID + " to force loaded.");
return System.currentTimeMillis() + keepLoadedMillis;
});
return;
}
}
}
return;
}
} else {

final int minY = chunk.getWorld().getMinHeight();
final int maxY = chunk.getWorld().getMaxHeight();

Expand All @@ -183,14 +184,17 @@ private boolean isStashChunk(Chunk chunk) {
if (storageTypes.contains(chunk.getBlock(x, y, z).getType())) {
count++;
if (count > stashCount) {
return true;
chunk.setForceLoaded(true);
forceLoadedChunks.computeIfAbsent(ChunkUID.of(chunk), chunkUID -> {
if (logIsEnabled) info("Set chunk " + chunkUID + " to force loaded.");
return System.currentTimeMillis() + keepLoadedMillis;
});
return;
}
}
}
}
}
}

return false;
}, checkDelayTicks);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.EntitiesLoadEvent;

import java.util.EnumMap;
import java.util.Map;
Expand Down Expand Up @@ -115,13 +115,10 @@ public void accept(ScheduledTask task) {
}

@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
private void onChunkLoad(ChunkLoadEvent event) {
if (event.isNewChunk()) return;
if (ChunkUtil.isRetrievalUnsafe(event.getChunk())) return;

for (Entity entity : event.getChunk().getEntities()) {
private void onEntitiesLoad(EntitiesLoadEvent event) {
for (Entity entity : event.getEntities()) {
if (entityLimits.containsKey(entity.getType()) && entity.getTicksLived() >= entityLimits.get(entity.getType())) {
entity.remove();
entity.getScheduler().execute(plugin, entity::remove, null, 1L);
if (logIsEnabled)
info("Removed " + entity.getType().name() + " due to old age.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,18 @@
import java.time.Duration;
import java.util.UUID;

public class BookBan extends AEFModule implements Listener {
public class ItemDataBan extends AEFModule implements Listener {

private final Cache<UUID, Integer> cachedItemSizes, cachedInventorySizes;
private final int maxBookSize, maxItemSize, maxInventorySize, maxAuthorChars, maxTitleChars, maxPages;
private final boolean useUTF16, kickOnBigBook;

public BookBan() {
super("patches.anti-book-ban");
public ItemDataBan() {
super("patches.anti-item-ban");
this.config.addComment(configPath+".enable", """
More commonly known as book-ban:\s
Prevents player's getting banned from items with big nbt/compound data.\s
This check applies to all item data, not just books.""");
this.useUTF16 = config.getBoolean(configPath + ".use-UTF-16", false, """
If set to false, will use UTF-8.\s
Charset to use to encode the result of NBTCompound#toString into\s
Expand All @@ -41,8 +45,8 @@ public BookBan() {
this.maxBookSize = config.getInt(configPath + ".max-book-size", 56000);
this.kickOnBigBook = config.getBoolean(configPath + ".kick-on-too-large-book-edit", true,
"Kicks players when they try to create a book bigger than the limit.");
this.maxAuthorChars = config.getInt(configPath + ".max-author-chars", 32);
this.maxTitleChars = config.getInt(configPath + ".max-title-chars", 32);
this.maxAuthorChars = config.getInt(configPath + ".max-author-chars", 30);
this.maxTitleChars = config.getInt(configPath + ".max-title-chars", 30);
this.maxPages = config.getInt(configPath + ".max-pages", 100);
this.maxItemSize = config.getInt(configPath + ".max-item-size", 56000);
this.maxInventorySize = config.getInt(configPath + ".max-inventory-size", 2050000);
Expand Down

This file was deleted.

Loading

0 comments on commit a3b10af

Please sign in to comment.