Skip to content

Commit

Permalink
packet beehives part two
Browse files Browse the repository at this point in the history
  • Loading branch information
xGinko committed Mar 12, 2024
1 parent 8ba5398 commit 829d558
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 97 deletions.
Original file line number Diff line number Diff line change
@@ -1,66 +1,43 @@
package me.moomoo.anarchyexploitfixes.modules.patches;

import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTCompoundList;
import de.tr7zw.changeme.nbtapi.NBTItem;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.event.PacketListenerAbstract;
import com.github.retrooper.packetevents.event.PacketListenerPriority;
import com.github.retrooper.packetevents.event.PacketSendEvent;
import com.github.retrooper.packetevents.protocol.item.ItemStack;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTList;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetSlot;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerWindowItems;
import me.moomoo.anarchyexploitfixes.AnarchyExploitFixes;
import me.moomoo.anarchyexploitfixes.config.Config;
import me.moomoo.anarchyexploitfixes.modules.AEFModule;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.player.PlayerAttemptPickupItemEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.ItemStack;
import org.slf4j.event.Level;

import java.util.*;
import java.util.stream.Collectors;

import static me.moomoo.anarchyexploitfixes.utils.LogUtil.materialNotRecognized;
public class BeehiveCoordinates extends PacketListenerAbstract implements AEFModule {

public class BeehiveCoordinates implements AEFModule, Listener {

private final Set<String> entityDataTags;
private final Set<Material> beehiveTypes;
private final Set<String> entityDataTagsToRemove;

public BeehiveCoordinates() {
super(PacketListenerPriority.HIGHEST);
Config config = AnarchyExploitFixes.getConfiguration();
config.addComment("patches.remove-beehive-coordinates.enable", """
Patches an exploit that allows players to obtain another player's coordinates\s
by trading them for beehives or beenests.\s
If the traded item contains any bees, the stored bee's NBT data could then be read from the item.\s
This data includes, but is not limited to:\s
- UID of the world the bee was first spawned into existence\s
- XYZ coordinates of where the bee was first spawned into existence\s
- XYZ coordinates of where the bee last visited a flower\s
- XYZ coordinates of where the bee has its hive\s
- XYZ of the bee's last coordinates before entering it's hive.""");
this.entityDataTags = new HashSet<>(config.getList("patches.remove-beehive-coordinates.tags", Arrays.asList(
"Pos", "HivePos", "FlowerPos", "Paper.Origin", "Paper.OriginWorld", "WorldUUIDMost", "WorldUUIDLeast"),
config.addComment("patches.remove-beehive-coordinates.enable",
"Patches an exploit that allows players to obtain another player's coordinates\n" +
"by trading them for beehives or beenests.\n" +
"If the traded item contains any bees, the stored bee's NBT data could then be read from the item.\n" +
"This data includes, but is not limited to:\n" +
" - UID of the world the bee was first spawned into existence\n" +
" - XYZ coordinates of where the bee was first spawned into existence\n" +
" - XYZ coordinates of where the bee last visited a flower\n" +
" - XYZ coordinates of where the bee has its hive\n" +
" - XYZ of the bee's last coordinates before entering it's hive");
this.entityDataTagsToRemove = new HashSet<>(config.getList("patches.remove-beehive-coordinates.tags", Arrays.asList(
"Pos", "HivePos", "FlowerPos", "Paper.Origin", "Paper.OriginWorld", "WorldUUIDMost", "WorldUUIDLeast"),
"The NBT tags to filter from the item. These are the Keys that hold the position data.\n" +
"You may add more tags you want removed here."));
this.beehiveTypes = config.getList("patches.remove-beehive-coordinates.beehive-types-to-check",
List.of("BEEHIVE", "BEE_NEST"))
.stream()
.map(configuredType -> {
try {
return Material.valueOf(configuredType);
} catch (IllegalArgumentException e) {
materialNotRecognized(Level.WARN, name(), configuredType);
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toSet());
"You may add more tags you want removed here."));
}

@Override
Expand All @@ -75,8 +52,7 @@ public String category() {

@Override
public void enable() {
AnarchyExploitFixes plugin = AnarchyExploitFixes.getInstance();
plugin.getServer().getPluginManager().registerEvents(this, plugin);
PacketEvents.getAPI().getEventManager().registerListener(this);
}

@Override
Expand All @@ -86,64 +62,78 @@ public boolean shouldEnable() {

@Override
public void disable() {
HandlerList.unregisterAll(this);
PacketEvents.getAPI().getEventManager().unregisterListener(this);
}

private void handleBeehiveIfPresent(ItemStack item) {
if (item == null || !beehiveTypes.contains(item.getType())) return;

NBTItem nbtBeehive = new NBTItem(item);
if (!nbtBeehive.hasTag("BlockEntityTag")) return;
@Override
public void onPacketSend(PacketSendEvent event) {
if (event.getPacketType() == PacketType.Play.Server.SET_SLOT) {
WrapperPlayServerSetSlot packet = new WrapperPlayServerSetSlot(event);
packet.setItem(filterItemStack(packet.getItem()));
event.markForReEncode(true);
}

NBTCompound blockEntityCompound = nbtBeehive.getCompound("BlockEntityTag");
if (blockEntityCompound == null) return;
if (event.getPacketType() == PacketType.Play.Server.WINDOW_ITEMS) {
WrapperPlayServerWindowItems packet = new WrapperPlayServerWindowItems(event);
packet.getCarriedItem().ifPresent(itemStack -> packet.setCarriedItem(filterItemStack(itemStack)));
packet.setItems(packet.getItems().stream().map(this::filterItemStack).collect(Collectors.toList()));
event.markForReEncode(true);
}
}

NBTCompoundList beeList = blockEntityCompound.getCompoundList("Bees");
if (beeList == null) return;
private ItemStack filterItemStack(ItemStack itemStack) {
if (itemStack == null || itemStack.isEmpty()) return itemStack;

for (ReadWriteNBT nbtBee : beeList) {
ReadWriteNBT beeEntityData = nbtBee.getCompound("EntityData");
if (beeEntityData != null) {
entityDataTags.forEach(beeEntityData::removeKey);
}
}
final NBTCompound rootCompound = itemStack.getNBT();
if (rootCompound == null || !rootCompound.getTags().containsKey("BlockEntityTag")) return itemStack;

nbtBeehive.applyNBT(item);
}
final NBTCompound blockEntityTag = rootCompound.getCompoundTagOrNull("BlockEntityTag");
if (blockEntityTag == null || blockEntityTag.isEmpty()) return itemStack;

@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = false)
private void onPlayerJoinEvent(PlayerJoinEvent event) {
Player player = event.getPlayer();
player.getInventory().forEach(this::handleBeehiveIfPresent);
player.getEnderChest().forEach(this::handleBeehiveIfPresent);
rootCompound.setTag("BlockEntityTag", filterBlockEntityTag(blockEntityTag));
itemStack.setNBT(rootCompound);
return itemStack;
}

@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = false)
private void onPlayerInteractEvent(PlayerInteractEvent event) {
handleBeehiveIfPresent(event.getItem());
}
private NBTCompound filterBlockEntityTag(NBTCompound blockEntityTag) {
if (blockEntityTag.getTags().containsKey("Bees")) {
NBTList<NBTCompound> bees = blockEntityTag.getCompoundListTagOrNull("Bees");
if (bees == null || bees.isEmpty()) return blockEntityTag;

for (int i = 0; i < bees.size(); i++) {
NBTCompound beeEntity = bees.getTag(i);
NBTCompound beeEntityData = beeEntity.getCompoundTagOrNull("EntityData");
if (beeEntityData != null && !beeEntityData.isEmpty()) {
for (String toRemove : entityDataTagsToRemove) {
beeEntityData.removeTag(toRemove);
}
}
beeEntity.setTag("EntityData", beeEntityData);
bees.setTag(i, beeEntity);
}

@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
private void onPlayerDropItemEvent(PlayerDropItemEvent event) {
handleBeehiveIfPresent(event.getItemDrop().getItemStack());
}
blockEntityTag.setTag("Bees", bees);
}

@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
private void onPlayerPickupItem(PlayerAttemptPickupItemEvent event) {
handleBeehiveIfPresent(event.getItem().getItemStack());
}
if (blockEntityTag.getTags().containsKey("Items")) {
NBTList<NBTCompound> items = blockEntityTag.getCompoundListTagOrNull("Items");
if (items == null || items.isEmpty()) return blockEntityTag;

for (int i = 0; i < items.size(); i++) {
NBTCompound item = items.getTag(i);
NBTCompound itemRootCompound = item.getCompoundTagOrNull("tag");
if (itemRootCompound != null && itemRootCompound.getTags().containsKey("BlockEntityTag")) {
final NBTCompound nestedBlockEntityTag = itemRootCompound.getCompoundTagOrNull("BlockEntityTag");
if (nestedBlockEntityTag != null && !nestedBlockEntityTag.isEmpty()) {
itemRootCompound.setTag("BlockEntityTag", filterBlockEntityTag(nestedBlockEntityTag));
}
}
items.setTag(i, item);
}

// Inventory Events
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = false)
private void onInventoryOpenEvent(InventoryOpenEvent event) {
event.getInventory().forEach(this::handleBeehiveIfPresent);
}
blockEntityTag.setTag("Items", items);
}

@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = false)
private void onInventoryClick(InventoryClickEvent event) {
handleBeehiveIfPresent(event.getCursor());
handleBeehiveIfPresent(event.getCurrentItem());
event.getInventory().forEach(this::handleBeehiveIfPresent);
event.getWhoClicked().getInventory().forEach(this::handleBeehiveIfPresent);
return blockEntityTag;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,14 @@ public void onPacketSend(PacketSendEvent event) {
if (event.getPacketType() == PacketType.Play.Server.SET_SLOT) {
WrapperPlayServerSetSlot packet = new WrapperPlayServerSetSlot(event);
packet.setItem(filterItemStack(packet.getItem()));
event.markForReEncode(true);
}

if (event.getPacketType() == PacketType.Play.Server.WINDOW_ITEMS) {
WrapperPlayServerWindowItems packet = new WrapperPlayServerWindowItems(event);
packet.getCarriedItem().ifPresent(itemStack -> packet.setCarriedItem(filterItemStack(itemStack)));
packet.setItems(packet.getItems().stream().map(this::filterItemStack).collect(Collectors.toList()));
event.markForReEncode(true);
}
}

Expand Down

0 comments on commit 829d558

Please sign in to comment.