From cc7d70191310062d7555d2ec341d8e5d554f351e Mon Sep 17 00:00:00 2001 From: Loving11ish Date: Tue, 9 Jul 2024 16:39:14 +0100 Subject: [PATCH] Added ShadowJar plugin to Gradle. Added PacketEvents library. Added new CreativeInvPacketListeners class. Added new UseEntityPacketListener class. Made plugin properly unregister listeners on shutdown. Deprecated ProtocolLib classes and methods. Marked ProtocolLib classes and methods for removal. Changed EntityMountEvent to BukkitAPI import. Changed version to `2.10.0-SNAPSHOT-01`. --- build.gradle.kts | 22 +++- .../java/main/java/me/dniym/IllegalStack.java | 56 +++++--- .../main/java/me/dniym/enums/Protections.java | 3 +- .../listeners/CreativeInvPacketListeners.java | 73 +++++++++++ .../listeners/UseEntityPacketListener.java | 124 ++++++++++++++++++ .../java/me/dniym/listeners/fListener.java | 4 +- .../me/dniym/listeners/pLisbListener.java | 3 + .../me/dniym/utils/BookCrashExploitCheck.java | 3 + .../java/me/dniym/utils/PacketAttack.java | 3 + .../java/me/dniym/utils/SpigotMethods.java | 1 + src/main/resources/plugin.yml | 18 ++- 11 files changed, 283 insertions(+), 27 deletions(-) create mode 100644 src/main/java/main/java/me/dniym/listeners/CreativeInvPacketListeners.java create mode 100644 src/main/java/main/java/me/dniym/listeners/UseEntityPacketListener.java diff --git a/build.gradle.kts b/build.gradle.kts index b77fa28..b91ec5a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,6 +4,8 @@ plugins { idea eclipse + + id("com.github.johnrengelman.shadow") version "7.1.0" } repositories { @@ -20,6 +22,10 @@ repositories { name = "PaperMC" url = uri("https://repo.papermc.io/repository/maven-public/") } + maven { + name = "PacketEvents" + url = uri("https://repo.codemc.io/repository/maven-releases/") + } maven { name = "ProtocolLib" url = uri("https://repo.dmulloy2.net/nexus/repository/public/") @@ -52,6 +58,7 @@ dependencies { compileOnly("fr.minuskube.inv:smart-invs:1.2.7") //compileOnly("com.github.CraftingStore.MinecraftPlugin:core:master-e366d322f8-1") compileOnly("com.github.brcdev-minecraft:shopgui-api:3.0.0") + implementation("com.github.retrooper:packetevents-spigot:2.4.0") } the().toolchain { @@ -66,10 +73,23 @@ tasks.compileJava.configure { options.release.set(8) } -version = "2.9.12-SNAPSHOT-01" +version = "2.10.0-SNAPSHOT-01" tasks.named("processResources") { filesMatching("plugin.yml") { expand("version" to project.version) } } + +// ShadowJar configuration +tasks.shadowJar { + // Optionally, relocate the PacketEvents package to avoid conflicts + relocate("com.github.retrooper.packetevents", "me.dniym.packetevents.api") + relocate("io.github.retrooper.packetevents", "me.dniym.packetevents.impl") + minimize() +} + +// Build the ShadowJar +tasks.build { + dependsOn(tasks.shadowJar) +} diff --git a/src/main/java/main/java/me/dniym/IllegalStack.java b/src/main/java/main/java/me/dniym/IllegalStack.java index 1d51ddf..16802a4 100644 --- a/src/main/java/main/java/me/dniym/IllegalStack.java +++ b/src/main/java/main/java/me/dniym/IllegalStack.java @@ -1,16 +1,20 @@ package main.java.me.dniym; +import com.github.retrooper.packetevents.PacketEvents; +import com.github.retrooper.packetevents.PacketEventsAPI; +import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder; import main.java.me.dniym.commands.IllegalStackCommand; import main.java.me.dniym.enums.Msg; import main.java.me.dniym.enums.Protections; import main.java.me.dniym.enums.ServerVersion; +import main.java.me.dniym.listeners.CreativeInvPacketListeners; import main.java.me.dniym.listeners.Listener113; import main.java.me.dniym.listeners.Listener114; import main.java.me.dniym.listeners.Listener116; import main.java.me.dniym.listeners.ProtectionListener; +import main.java.me.dniym.listeners.UseEntityPacketListener; import main.java.me.dniym.listeners.fListener; import main.java.me.dniym.listeners.mcMMOListener; -import main.java.me.dniym.listeners.pLisbListener; import main.java.me.dniym.timers.fTimer; import main.java.me.dniym.timers.sTimer; import main.java.me.dniym.timers.syncTimer; @@ -23,6 +27,7 @@ import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.event.HandlerList; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; @@ -112,6 +117,16 @@ public static void setCMI(boolean cMI) { CMI = cMI; } + @Override + public void onLoad() { + // Load PacketEventsAPI + PacketEvents.setAPI(SpigotPacketEventsBuilder.build(this)); + PacketEvents.getAPI().getSettings() + .checkForUpdates(false) + .debug(false); + PacketEvents.getAPI().load(); + } + public static void ReloadConfig(Boolean wasCommand) { if (!wasCommand) { IllegalStack.getPlugin().writeConfig(); @@ -432,6 +447,13 @@ public static boolean hasStorage() { @Override public void onEnable() { + // Register PacketEvents listeners + LOGGER.info("Registering PacketEvents listeners..."); + PacketEvents.getAPI().getEventManager().registerListeners(new CreativeInvPacketListeners(this)); + PacketEvents.getAPI().getEventManager().registerListeners(new UseEntityPacketListener(this)); + PacketEventsAPI packetEventsAPI = PacketEvents.getAPI(); + packetEventsAPI.init(); + LOGGER.info("PacketEvents API {} has been initialized!", PacketEvents.getAPI().getVersion()); // new EntityRegistry(this); this.setPlugin(this); @@ -542,25 +564,6 @@ public void onEnable() { } } - if (this - .getServer() - .getPluginManager() - .getPlugin("ProtocolLib") != null && Protections.BlockBadItemsFromCreativeTab.isEnabled()) { - LOGGER.info( - "ProtocolLib was detected, creative inventory exploit detection enabled. NOTE* This protection ONLY needs to be turned on if you have regular (non op) players with access to /gmc"); - new pLisbListener(this); - } - - if (this.getServer().getPluginManager().getPlugin("ProtocolLib") == null && Protections.DisableChestsOnMobs.isEnabled()) { - - LOGGER.warn( - "ProtocolLib NOT FOUND!!!! and DisableChestsOnMobs protection is turned on.. It may still be possible for players to dupe using horses/donkeys on your server using a hacked client. It is highly recommended that you install ProtocolLib for optimal protection!"); - - } else if (Protections.DisableChestsOnMobs.isEnabled()) { - new pLisbListener(this); - setHasProtocolLib(true); - } - this.getServer().getPluginManager().registerEvents(new fListener(this), this); if (!fListener.is18()) { @@ -1033,13 +1036,26 @@ public static boolean isDisable() { @Override public void onDisable() { + // Signal plugin is now disabled disable = true; + + // Terminate PacketEvents + PacketEvents.getAPI().getEventManager().unregisterAllListeners(); + PacketEvents.getAPI().terminate(); + LOGGER.info("PacketEvents has been terminated successfully!"); + + // Unregister listeners + HandlerList.unregisterAll(this); + LOGGER.info("Listeners have unregistered successfully!"); + + // Cancel all tasks if (hasAsyncScheduler) { getServer().getAsyncScheduler().cancelTasks(this); } else if (!isFoliaServer()){ Bukkit.getScheduler().cancelTasks(this); } + // Save configuration writeConfig(); } diff --git a/src/main/java/main/java/me/dniym/enums/Protections.java b/src/main/java/main/java/me/dniym/enums/Protections.java index 1efdf4c..336c86a 100644 --- a/src/main/java/main/java/me/dniym/enums/Protections.java +++ b/src/main/java/main/java/me/dniym/enums/Protections.java @@ -1676,8 +1676,7 @@ World getWorldFromObj(Object obj) { public boolean isDisabledInWorld(World wld) { return Protections.DisableInWorlds.isWhitelisted(wld.getName()); } - - @Deprecated + public boolean isEnabled() { if (this.getVersion().isEmpty()) //child node return this.enabled; diff --git a/src/main/java/main/java/me/dniym/listeners/CreativeInvPacketListeners.java b/src/main/java/main/java/me/dniym/listeners/CreativeInvPacketListeners.java new file mode 100644 index 0000000..5ae3de2 --- /dev/null +++ b/src/main/java/main/java/me/dniym/listeners/CreativeInvPacketListeners.java @@ -0,0 +1,73 @@ +package main.java.me.dniym.listeners; + +import com.github.retrooper.packetevents.event.PacketListenerAbstract; +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.protocol.player.User; +import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientCreativeInventoryAction; +import io.github.retrooper.packetevents.util.SpigotConversionUtil; +import main.java.me.dniym.IllegalStack; +import main.java.me.dniym.enums.Msg; +import main.java.me.dniym.enums.Protections; +import main.java.me.dniym.utils.Scheduler; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.UUID; + +public class CreativeInvPacketListeners extends PacketListenerAbstract { + + private final IllegalStack plugin; + + private static final Logger LOGGER = LogManager.getLogger("IllegalStack/" + CreativeInvPacketListeners.class.getSimpleName()); + + public CreativeInvPacketListeners(IllegalStack plugin) { + super(PacketListenerPriority.LOW); + this.plugin = plugin; + } + + @Override + public void onPacketReceive(PacketReceiveEvent event) { + + if (event.getPacketType() != PacketType.Play.Client.CREATIVE_INVENTORY_ACTION) { + return; + } + + if (!Protections.BlockBadItemsFromCreativeTab.isEnabled()) { + return; + } + + User user = event.getUser(); + UUID uuid = user.getUUID(); + Player player = plugin.getServer().getPlayer(uuid); + + if (player == null) { + return; + } + + if (player.isOp() || player.hasPermission("illegalstack.admin")) { + return; + } + + WrapperPlayClientCreativeInventoryAction packetWrapper = new WrapperPlayClientCreativeInventoryAction(event); + + try { + com.github.retrooper.packetevents.protocol.item.ItemStack wrapperItemStack = packetWrapper.getItemStack(); + ItemStack stack = SpigotConversionUtil.toBukkitItemStack(wrapperItemStack); + if (stack != null && stack.hasItemMeta()) { + stack = new ItemStack(Material.AIR); + Scheduler.runTaskLater(plugin, player::updateInventory, 5L, player); + event.setCancelled(true); + Msg.StaffMsgCreativeBlock.getValue(player.getName()); + } + } catch (IndexOutOfBoundsException ex) { + LOGGER.error( + "An error receiving a CREATIVE_INVENTORY_ACTION packet has occurred, you are probably using paper and have BlockBadItemsFromCreativeTab turned on. This setting is needed very rarely, and ONLY if you have regular non-op players with access to /gmc."); + } + } + +} diff --git a/src/main/java/main/java/me/dniym/listeners/UseEntityPacketListener.java b/src/main/java/main/java/me/dniym/listeners/UseEntityPacketListener.java new file mode 100644 index 0000000..f4bb98a --- /dev/null +++ b/src/main/java/main/java/me/dniym/listeners/UseEntityPacketListener.java @@ -0,0 +1,124 @@ +package main.java.me.dniym.listeners; + +import com.github.retrooper.packetevents.event.PacketListenerAbstract; +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.protocol.player.User; +import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity; +import main.java.me.dniym.IllegalStack; +import main.java.me.dniym.enums.Msg; +import main.java.me.dniym.enums.Protections; +import main.java.me.dniym.timers.fTimer; +import main.java.me.dniym.utils.Scheduler; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.entity.ChestedHorse; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Horse; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; +import java.util.UUID; + +public class UseEntityPacketListener extends PacketListenerAbstract { + + private final IllegalStack plugin; + private final HashMap messageDelay = new HashMap<>(); + + public UseEntityPacketListener(IllegalStack plugin) { + super(PacketListenerPriority.LOW); + this.plugin = plugin; + } + + @Override + public void onPacketReceive(PacketReceiveEvent event) { + + if (event.getPacketType() != PacketType.Play.Client.INTERACT_ENTITY) { + return; + } + + if (!IllegalStack.hasChestedAnimals()) { + return; + } + + if (!Protections.DisableChestsOnMobs.isEnabled()) { + return; + } + + User user = event.getUser(); + UUID uuid = user.getUUID(); + Player player = plugin.getServer().getPlayer(uuid); + + if (player == null) { + return; + } + + if (player.isOp() || player.hasPermission("illegalstack.admin")) { + return; + } + + WrapperPlayClientInteractEntity packetWrapper = new WrapperPlayClientInteractEntity(event); + + World world = player.getWorld(); + int entityId = packetWrapper.getEntityId(); + + if (entityId <= 0) { + return; + } + + Scheduler.runTask(plugin, () -> { + + Entity entity = world.getEntities().stream().filter(e -> e.getEntityId() == entityId).findFirst().orElse(null); + + Scheduler.runTaskLater(plugin, () -> { + + if (entity instanceof Horse && ((Horse) entity).isTamed()) { + ItemStack is = player.getInventory().getItemInMainHand(); + if (!fListener.is18() && (is == null || is.getType() != Material.CHEST)) { + is = player.getInventory().getItemInOffHand(); + } + if (is == null || is.getType() != Material.CHEST) { + return; + } + exploitMessage(player, entity); + event.setCancelled(true); + fTimer.getPunish().put(player, entity); + return; + } + + if (entity instanceof ChestedHorse && ((ChestedHorse) entity).isTamed()) { + ItemStack is = player.getInventory().getItemInMainHand(); + if (is == null || is.getType() != Material.CHEST) { + is = player.getInventory().getItemInOffHand(); + } + if (is == null || is.getType() != Material.CHEST) { + return; + } + exploitMessage(player, entity); + event.setCancelled(true); + + ((ChestedHorse) entity).setCarryingChest(true); + ((ChestedHorse) entity).setCarryingChest(false); + fTimer.getPunish().put(player, entity); + } + + }, 1, entity); + + }, player.getLocation()); + } + + private void exploitMessage(Player p, Entity ent) { + if (!messageDelay.containsKey(p.getUniqueId())) { + messageDelay.put(p.getUniqueId(), 0L); + } + + if (System.currentTimeMillis() > messageDelay.get(p.getUniqueId())) { + p.sendMessage(Msg.PlayerDisabledHorseChestMsg.getValue()); + fListener.getLog().append2(Msg.ChestPrevented.getValue(p, ent)); + messageDelay.put(p.getUniqueId(), System.currentTimeMillis() + 2000L); + } + } + +} diff --git a/src/main/java/main/java/me/dniym/listeners/fListener.java b/src/main/java/main/java/me/dniym/listeners/fListener.java index 9ad7706..adbef32 100644 --- a/src/main/java/main/java/me/dniym/listeners/fListener.java +++ b/src/main/java/main/java/me/dniym/listeners/fListener.java @@ -64,7 +64,6 @@ import org.bukkit.entity.TNTPrimed; import org.bukkit.entity.Tameable; import org.bukkit.entity.TraderLlama; -import org.bukkit.entity.Vehicle; import org.bukkit.entity.Vex; import org.bukkit.entity.Zombie; import org.bukkit.entity.minecart.HopperMinecart; @@ -85,6 +84,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.EntityMountEvent; import org.bukkit.event.entity.EntityPortalEvent; import org.bukkit.event.entity.EntitySpawnEvent; import org.bukkit.event.entity.EntityTargetEvent; @@ -94,7 +94,6 @@ import org.bukkit.event.inventory.InventoryDragEvent; import org.bukkit.event.inventory.InventoryMoveItemEvent; import org.bukkit.event.inventory.InventoryOpenEvent; -import org.bukkit.event.inventory.InventoryPickupItemEvent; import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.inventory.PrepareItemCraftEvent; import org.bukkit.event.player.PlayerBucketEmptyEvent; @@ -120,7 +119,6 @@ import org.bukkit.inventory.meta.BookMeta; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.util.Vector; -import org.spigotmc.event.entity.EntityMountEvent; import java.nio.charset.Charset; import java.util.ArrayList; diff --git a/src/main/java/main/java/me/dniym/listeners/pLisbListener.java b/src/main/java/main/java/me/dniym/listeners/pLisbListener.java index 635a650..fe0e8c6 100644 --- a/src/main/java/main/java/me/dniym/listeners/pLisbListener.java +++ b/src/main/java/main/java/me/dniym/listeners/pLisbListener.java @@ -18,10 +18,13 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.ApiStatus; import java.util.HashMap; import java.util.UUID; +@Deprecated +@ApiStatus.ScheduledForRemoval public class pLisbListener { private static final Logger LOGGER = LogManager.getLogger("IllegalStack/" + pLisbListener.class.getSimpleName()); diff --git a/src/main/java/main/java/me/dniym/utils/BookCrashExploitCheck.java b/src/main/java/main/java/me/dniym/utils/BookCrashExploitCheck.java index 87f07d3..a3e0f57 100644 --- a/src/main/java/main/java/me/dniym/utils/BookCrashExploitCheck.java +++ b/src/main/java/main/java/me/dniym/utils/BookCrashExploitCheck.java @@ -7,7 +7,10 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.InventoryView; import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.ApiStatus; +@Deprecated +@ApiStatus.ScheduledForRemoval public class BookCrashExploitCheck extends PacketAdapter { public BookCrashExploitCheck(final Plugin plugin) { diff --git a/src/main/java/main/java/me/dniym/utils/PacketAttack.java b/src/main/java/main/java/me/dniym/utils/PacketAttack.java index bd26281..429f1c7 100644 --- a/src/main/java/main/java/me/dniym/utils/PacketAttack.java +++ b/src/main/java/main/java/me/dniym/utils/PacketAttack.java @@ -8,11 +8,14 @@ import main.java.me.dniym.listeners.fListener; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.ApiStatus; import java.util.HashMap; import java.util.HashSet; import java.util.UUID; +@Deprecated +@ApiStatus.ScheduledForRemoval public class PacketAttack { private static final Logger LOGGER = LogManager.getLogger("IllegalStack/" + PacketAttack.class.getSimpleName()); diff --git a/src/main/java/main/java/me/dniym/utils/SpigotMethods.java b/src/main/java/main/java/me/dniym/utils/SpigotMethods.java index 9f35fac..85ab6ee 100644 --- a/src/main/java/main/java/me/dniym/utils/SpigotMethods.java +++ b/src/main/java/main/java/me/dniym/utils/SpigotMethods.java @@ -11,6 +11,7 @@ import org.bukkit.entity.LivingEntity; +@SuppressWarnings("deprecation") public class SpigotMethods { public static BaseComponent makeParentText(Protections protections, String status, boolean children, int catId) { diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index aa74972..785a7ec 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -5,7 +5,23 @@ api-version: 1.13 folia-supported: true description: Closes some dupe bugs still present in vanilla minecraft. authors: [ dNiym, Loving11ish ] -softdepend: [Magic, Factions, NBTAPI, ProtocolLib, Slimefun, CraftingStore, DynamicShop, ClueScrolls, mcMMO, JetsMinions, SmartInvs, FactionsX] +softdepend: + - MagicFactions + - NBTAPI + - ProtocolLib + - ProtocolSupport + - ViaVersion + - ViaBackwards + - ViaRewind + - Geyser-Spigot + - Slimefun + - CraftingStore + - DynamicShop + - ClueScrolls + - mcMMO + - JetsMinions + - SmartInvs + - FactionsX loadbefore: [MythicDrops] website: https://www.spigotmc.org/resources/44411/ commands: