Fix BlockBadItemsFromCreativeTab

This commit is contained in:
NotAlexNoyle authored and GWServer committed 2026-07-22 12:21:06 +00:00
1 parent ffd216406e
commit 0b8e6b1bfd
5 files changed
+143 -16

No files matched your search

+9 -1
View File
@@ -21,7 +21,7 @@ kotlin { jvmToolchain(17) }
/* ----------------------------- Metadata ------------------------------ */
version = "2.9.13" // Declare plugin version (will be in .jar).
version = "2.9.15-SNAPSHOT" // Declare plugin version (will be in .jar).
group = "net.trueog.illegalstack-og" // Declare bundle identifier.
@@ -67,8 +67,16 @@ dependencies {
compileOnly("com.gmail.nossr50.mcMMO:mcMMO:2.1.217") { isTransitive = false } // Import mcMMO API.
compileOnly("fr.minuskube.inv:smart-invs:1.2.7") // Import SmartInvs API.
compileOnly("com.github.brcdev-minecraft:shopgui-api:3.0.0") // Import ShopGUI API.
testImplementation("dev.folia:folia-api:1.19.4-R0.1-SNAPSHOT")
testImplementation(platform("org.junit:junit-bom:5.13.3"))
testImplementation("org.junit.jupiter:junit-jupiter")
testImplementation("org.mockito:mockito-core:5.14.2")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
tasks.test { useJUnitPlatform() }
/* ---------------------- Reproducible jars ---------------------------- */
tasks.withType<AbstractArchiveTask>().configureEach { // Ensure reproducible .jars
isPreserveFileTimestamps = false
@@ -1058,6 +1058,9 @@ public class IllegalStack extends JavaPlugin {
private void loadConfig() {
this.saveDefaultConfig();
// saveDefaultConfig() does not refresh Bukkit's cached configuration on /istack
// reload.
this.reloadConfig();
Protections.update();
@@ -1499,4 +1502,4 @@ public class IllegalStack extends JavaPlugin {
}
}
}
@@ -0,0 +1,33 @@
package main.java.me.dniym.checks;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
/**
* Classifies payloads received through the creative-slot packet.
*
* <p>
* Vanilla metadata is not itself evidence of an unsafe payload. Other
* configured protections remain responsible for overstacked items, illegal
* enchantments, banned types, and name or lore rules.
* </p>
*/
public final class CreativeItemCheck {
private CreativeItemCheck() {
}
public static boolean hasUnsafePayload(ItemStack stack) {
if (stack == null || stack.getType() == Material.AIR) {
return false;
}
return BadAttributeCheck.hasNonDefaultAttributeModifiers(stack);
}
}
@@ -7,7 +7,7 @@ import com.comphenix.protocol.events.PacketEvent;
import java.util.HashMap;
import java.util.UUID;
import main.java.me.dniym.IllegalStack;
import main.java.me.dniym.checks.BadAttributeCheck;
import main.java.me.dniym.checks.CreativeItemCheck;
import main.java.me.dniym.enums.Msg;
import main.java.me.dniym.enums.Protections;
import main.java.me.dniym.timers.fTimer;
@@ -20,7 +20,6 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.Horse;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.plugin.Plugin;
public class pLisbListener {
@@ -53,14 +52,18 @@ public class pLisbListener {
try {
ItemStack stack = event.getPacket().getItemModifier().readSafely(0);
if (stack != null && stack.hasItemMeta() && !isVanillaLeatherArmor(stack)) {
final ItemStack stack = event.getPacket().getItemModifier().readSafely(0);
if (CreativeItemCheck.hasUnsafePayload(stack)) {
stack = new ItemStack(Material.AIR);
final Player player = event.getPlayer();
Scheduler.runTaskLater(plugin, player::updateInventory, 5L, player);
Scheduler.runTaskLater(plugin, () -> {
player.updateInventory();
fListener.getLog().append(Msg.StaffMsgCreativeBlock.getValue(player.getName()),
Protections.BlockBadItemsFromCreativeTab);
}, 5L, player);
event.setCancelled(true);
Msg.StaffMsgCreativeBlock.getValue(event.getPlayer().getName());
}
@@ -165,13 +168,6 @@ public class pLisbListener {
}
private static boolean isVanillaLeatherArmor(ItemStack stack) {
return stack.getItemMeta() instanceof LeatherArmorMeta
&& !BadAttributeCheck.hasNonDefaultAttributeModifiers(stack);
}
private void exploitMessage(Player p, Entity ent) {
if (!messageDelay.containsKey(p.getUniqueId())) {
@@ -0,0 +1,87 @@
package main.java.me.dniym.checks;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
class CreativeItemCheckTest {
@Test
void allowsAnvilDisplayNameWhenNoUnsafeSignalExists() {
final ItemStack stack = mock(ItemStack.class);
final ItemMeta meta = mock(ItemMeta.class);
when(stack.getType()).thenReturn(Material.DIAMOND_SWORD);
when(stack.hasItemMeta()).thenReturn(true);
when(stack.getItemMeta()).thenReturn(meta);
when(meta.hasDisplayName()).thenReturn(true);
try (MockedStatic<BadAttributeCheck> attributes = mockStatic(BadAttributeCheck.class)) {
attributes.when(() -> BadAttributeCheck.hasNonDefaultAttributeModifiers(stack)).thenReturn(false);
assertFalse(CreativeItemCheck.hasUnsafePayload(stack));
attributes.verify(() -> BadAttributeCheck.hasNonDefaultAttributeModifiers(stack));
}
}
@Test
void allowsOtherVanillaMetadataWhenNoUnsafeSignalExists() {
final ItemStack stack = mock(ItemStack.class);
final LeatherArmorMeta meta = mock(LeatherArmorMeta.class);
when(stack.getType()).thenReturn(Material.LEATHER_CHESTPLATE);
when(stack.hasItemMeta()).thenReturn(true);
when(stack.getItemMeta()).thenReturn(meta);
try (MockedStatic<BadAttributeCheck> attributes = mockStatic(BadAttributeCheck.class)) {
attributes.when(() -> BadAttributeCheck.hasNonDefaultAttributeModifiers(stack)).thenReturn(false);
assertFalse(CreativeItemCheck.hasUnsafePayload(stack));
}
}
@Test
void blocksNonDefaultAttributePayload() {
final ItemStack stack = mock(ItemStack.class);
when(stack.getType()).thenReturn(Material.STICK);
try (MockedStatic<BadAttributeCheck> attributes = mockStatic(BadAttributeCheck.class)) {
attributes.when(() -> BadAttributeCheck.hasNonDefaultAttributeModifiers(stack)).thenReturn(true);
assertTrue(CreativeItemCheck.hasUnsafePayload(stack));
}
}
@Test
void ignoresNullAndAirWithoutInspectingAttributes() {
final ItemStack air = mock(ItemStack.class);
when(air.getType()).thenReturn(Material.AIR);
try (MockedStatic<BadAttributeCheck> attributes = mockStatic(BadAttributeCheck.class)) {
assertFalse(CreativeItemCheck.hasUnsafePayload(null));
assertFalse(CreativeItemCheck.hasUnsafePayload(air));
attributes.verifyNoInteractions();
}
}
}