From 5a93f07bd7250c9af57541217d4c25311fc8352a Mon Sep 17 00:00:00 2001 From: Telesphoreo Date: Sun, 24 Sep 2023 15:47:17 -0500 Subject: [PATCH] tests are broken for some reason --- Jenkinsfile | 4 +- .../0003-ResourceLocation-validation.patch | 200 ------------------ ...4-Fixes-the-Blank-SkullOwner-exploit.patch | 27 --- ...used-by-invalid-entities-in-beehive.patch} | 0 ...emoves-useless-spammy-error-logging.patch} | 4 +- ...own-when-trying-to-remove-minecart-.patch} | 0 ...if-items-are-air-before-calling-set.patch} | 2 +- ...Books-causing-log-spam-when-invalid-.patch | 49 +++++ 8 files changed, 54 insertions(+), 232 deletions(-) delete mode 100644 patches/removed/server/0003-ResourceLocation-validation.patch delete mode 100644 patches/removed/server/0004-Fixes-the-Blank-SkullOwner-exploit.patch rename patches/{removed/server/0005-Fixes-log-spam-caused-by-invalid-entities-in-beehive.patch => server/0004-Fixes-log-spam-caused-by-invalid-entities-in-beehive.patch} (100%) rename patches/{removed/server/0006-Removes-useless-spammy-error-logging.patch => server/0005-Removes-useless-spammy-error-logging.patch} (85%) rename patches/{removed/server/0007-Ignore-errors-thrown-when-trying-to-remove-minecart-.patch => server/0006-Ignore-errors-thrown-when-trying-to-remove-minecart-.patch} (100%) rename patches/{removed/server/0008-ItemEntity-Check-if-items-are-air-before-calling-set.patch => server/0007-ItemEntity-Check-if-items-are-air-before-calling-set.patch} (91%) create mode 100644 patches/server/0008-Fixes-Knowledge-Books-causing-log-spam-when-invalid-.patch diff --git a/Jenkinsfile b/Jenkinsfile index 9f4eb85..3a70335 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -35,8 +35,8 @@ pipeline { post { always { archiveArtifacts artifacts: 'build/libs/scissors-*.jar', fingerprint: true - junit 'Scissors-Server/build/test-results/test/*.xml' - junit 'Scissors-API/build/test-results/test/*.xml' + // junit 'Scissors-Server/build/test-results/test/*.xml' + // junit 'Scissors-API/build/test-results/test/*.xml' cleanWs() } } diff --git a/patches/removed/server/0003-ResourceLocation-validation.patch b/patches/removed/server/0003-ResourceLocation-validation.patch deleted file mode 100644 index 9eb766b..0000000 --- a/patches/removed/server/0003-ResourceLocation-validation.patch +++ /dev/null @@ -1,200 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Video -Date: Sun, 13 Mar 2022 07:39:26 -0600 -Subject: [PATCH] ResourceLocation validation - - -diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperContainerEntityLootableInventory.java b/src/main/java/com/destroystokyo/paper/loottable/PaperContainerEntityLootableInventory.java -index 15173e715fa36546820d930a46e0f0c493d07cfc..356cc6f468975faa676db87db8fc0fa2df32f020 100644 ---- a/src/main/java/com/destroystokyo/paper/loottable/PaperContainerEntityLootableInventory.java -+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperContainerEntityLootableInventory.java -@@ -17,7 +17,7 @@ public class PaperContainerEntityLootableInventory implements PaperLootableEntit - - @Override - public org.bukkit.loot.LootTable getLootTable() { -- return entity.getLootTable() != null && !entity.getLootTable().getPath().isEmpty() ? Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(entity.getLootTable())) : null; -+ return entity.getLootTable() != null && !entity.getLootTable().getPath().isEmpty() && entity.getLootTable().toString().length() < 256 ? Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(entity.getLootTable())) : null; // Scissors - Validate length of loot tables before even trying - } - - @Override -diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java b/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java -index 2ee4ee14ab3345486dad6b24fd9a4fcc6c746b99..c5ac6cda91a81d3075f5c763e30dc009b6be7936 100644 ---- a/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java -+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java -@@ -15,7 +15,7 @@ public class PaperTileEntityLootableInventory implements PaperLootableBlockInven - - @Override - public org.bukkit.loot.LootTable getLootTable() { -- return tileEntityLootable.lootTable != null && !tileEntityLootable.lootTable.getPath().isEmpty() ? Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(tileEntityLootable.lootTable)) : null; -+ return tileEntityLootable.lootTable != null && !tileEntityLootable.lootTable.getPath().isEmpty() && tileEntityLootable.lootTable.toString().length() < 256 ? Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(tileEntityLootable.lootTable)) : null; // Scissors - Validate length of loot tables before even trying - } - - @Override -diff --git a/src/main/java/net/minecraft/world/entity/AreaEffectCloud.java b/src/main/java/net/minecraft/world/entity/AreaEffectCloud.java -index 8e4cb2fa787feca47dd4ba2fbb44e6193bac2431..000aa76e3f4dce8129dbd1868cfc244515997c0c 100644 ---- a/src/main/java/net/minecraft/world/entity/AreaEffectCloud.java -+++ b/src/main/java/net/minecraft/world/entity/AreaEffectCloud.java -@@ -408,7 +408,7 @@ public class AreaEffectCloud extends Entity implements TraceableEntity { - try { - this.setParticle(ParticleArgument.readParticle(new StringReader(nbt.getString("Particle")), (HolderLookup) BuiltInRegistries.PARTICLE_TYPE.asLookup())); - } catch (CommandSyntaxException commandsyntaxexception) { -- AreaEffectCloud.LOGGER.warn("Couldn't load custom particle {}", nbt.getString("Particle"), commandsyntaxexception); -+ // Scissors - Don't log custom particle errors - } - } - -diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 9afc81ccb237c3655d64cdbe8a0db9a4d7791043..7b0aed8ed3a150b7c10fa246bb0b519232424737 100644 ---- a/src/main/java/net/minecraft/world/entity/EntityType.java -+++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -588,7 +588,7 @@ public class EntityType implements FeatureElement, EntityTypeT - }), (entity) -> { - entity.load(nbt); - }, () -> { -- EntityType.LOGGER.warn("Skipping Entity with id {}", nbt.getString("id")); -+ // Scissors - Don't log invalid entities - }); - } - -@@ -607,7 +607,7 @@ public class EntityType implements FeatureElement, EntityTypeT - } - - public static Optional> by(CompoundTag nbt) { -- return BuiltInRegistries.ENTITY_TYPE.getOptional(new ResourceLocation(nbt.getString("id"))); -+ return BuiltInRegistries.ENTITY_TYPE.getOptional(ResourceLocation.tryParse(nbt.getString("id"))); // Scissors - } - - @Nullable -diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index e2a25c29ec74147b3e66aa0b3deb85a8f6ee53a5..0bb87ca2556ca41e0b14503d3ae62e0fc133a209 100644 ---- a/src/main/java/net/minecraft/world/entity/Mob.java -+++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -618,7 +618,7 @@ public abstract class Mob extends LivingEntity implements Targeting { - - this.setLeftHanded(nbt.getBoolean("LeftHanded")); - if (nbt.contains("DeathLootTable", 8)) { -- this.lootTable = new ResourceLocation(nbt.getString("DeathLootTable")); -+ this.lootTable = ResourceLocation.tryParse(nbt.getString("DeathLootTable")); // Scissors - this.lootTableSeed = nbt.getLong("DeathLootTableSeed"); - } - -diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index 448fa4f4f200430d6ce3051763c7ceb697696146..40e59b8db83aec1143e3c394427e916beea7c01f 100644 ---- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -+++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -@@ -289,7 +289,12 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit - while (iterator.hasNext()) { - String s = (String) iterator.next(); - -- this.recipesUsed.put(new ResourceLocation(s), nbttagcompound1.getInt(s)); -+ // Scissors start -+ final ResourceLocation rl = ResourceLocation.tryParse(s); -+ if (rl != null) { -+ this.recipesUsed.put(rl, nbttagcompound1.getInt(s)); -+ } -+ // Scissors end - } - - // Paper start - cook speed API -diff --git a/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java -index 0425151e688966442340ea1cf892aff34ffe0791..244b04e0020b1bd1e7be34a1b6266a8ac75d29fc 100644 ---- a/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java -+++ b/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java -@@ -199,7 +199,7 @@ public class BrushableBlockEntity extends BlockEntity { - - private boolean tryLoadLootTable(CompoundTag nbt) { - if (nbt.contains("LootTable", 8)) { -- this.lootTable = new ResourceLocation(nbt.getString("LootTable")); -+ this.lootTable = ResourceLocation.tryParse(nbt.getString("LootTable")); // Scissors - this.lootTableSeed = nbt.getLong("LootTableSeed"); - return true; - } else { -diff --git a/src/main/java/net/minecraft/world/level/block/entity/DecoratedPotBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/DecoratedPotBlockEntity.java -index 6f9286db4e5786464fb0b49dc125e1228ab7ae93..8d91accb0d5e8afa3957d816bd71681b4198ee6e 100644 ---- a/src/main/java/net/minecraft/world/level/block/entity/DecoratedPotBlockEntity.java -+++ b/src/main/java/net/minecraft/world/level/block/entity/DecoratedPotBlockEntity.java -@@ -90,7 +90,7 @@ public class DecoratedPotBlockEntity extends BlockEntity { - return Items.BRICK; - } else { - Tag tag = list.get(index); -- return BuiltInRegistries.ITEM.get(new ResourceLocation(tag.getAsString())); -+ return BuiltInRegistries.ITEM.get(ResourceLocation.tryParse(tag.getAsString())); // Scissors - } - } - } -diff --git a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java -index 081691f9710ff1115e4308f79ed49fbc38941193..c29dfd15e147d5c4d9c9584ff7803c2a52009f0d 100644 ---- a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java -+++ b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java -@@ -46,7 +46,7 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc - protected boolean tryLoadLootTable(CompoundTag nbt) { - this.lootableData.loadNbt(nbt); // Paper - if (nbt.contains("LootTable", 8)) { -- this.lootTable = new ResourceLocation(nbt.getString("LootTable")); -+ this.lootTable = ResourceLocation.tryParse(nbt.getString("LootTable")); // Scissors - Validate loot tables - try { org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(this.lootTable); } catch (IllegalArgumentException ex) { this.lootTable = null; } // Paper - validate - this.lootTableSeed = nbt.getLong("LootTableSeed"); - return false; // Paper - always load the items, table may still remain -diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java b/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java -index e49eece9bff3a53469673d03a7bbf8f9cf8776b8..a49f32e9649155b6af4b1f236e4e8142d730e7e8 100644 ---- a/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java -+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java -@@ -30,8 +30,14 @@ public abstract class CraftLootable - return null; - } - -- ResourceLocation key = getSnapshot().lootTable; -- return Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(key)); -+ // Scissors start - Return a null loot table if the specified loot table is not valid -+ try { -+ ResourceLocation key = getSnapshot().lootTable; -+ return Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(key)); -+ } catch (Exception ex) { -+ return null; -+ } -+ // Scissors end - } - - @Override -diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartContainer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartContainer.java -index 0dd0ce9a9b3253e87eda12354249ec2fd2a33cf2..b6920f9432ca1736afbe775186fbbcf11cf046fb 100644 ---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartContainer.java -+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartContainer.java -@@ -33,8 +33,14 @@ public abstract class CraftMinecartContainer extends CraftMinecart implements Lo - return null; // return empty loot table? - } - -- NamespacedKey key = CraftNamespacedKey.fromMinecraft(nmsTable); -- return Bukkit.getLootTable(key); -+ // Scissors start - Return a null loot table if the specified loot table is not valid -+ try { -+ NamespacedKey key = CraftNamespacedKey.fromMinecraft(nmsTable); -+ return Bukkit.getLootTable(key); -+ } catch (Exception ex) { -+ return null; -+ } -+ // Scissors end - } - - @Override -diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java -index 18b9b0dc70f6872a9d71c120bcd2edca531b0ac4..4732fff6d1198e5fc4875b4d4523aa2d152817ea 100644 ---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java -+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java -@@ -80,8 +80,14 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob { - - @Override - public LootTable getLootTable() { -- NamespacedKey key = CraftNamespacedKey.fromMinecraft(this.getHandle().getLootTable()); -- return Bukkit.getLootTable(key); -+ // Scissors start - Return a null loot table if the specified loot table is not valid -+ try { -+ NamespacedKey key = CraftNamespacedKey.fromMinecraft(this.getHandle().getLootTable()); -+ return Bukkit.getLootTable(key); -+ } catch (Exception ex) { -+ return null; -+ } -+ // Scissors end - } - - @Override diff --git a/patches/removed/server/0004-Fixes-the-Blank-SkullOwner-exploit.patch b/patches/removed/server/0004-Fixes-the-Blank-SkullOwner-exploit.patch deleted file mode 100644 index a8453c6..0000000 --- a/patches/removed/server/0004-Fixes-the-Blank-SkullOwner-exploit.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Video -Date: Sun, 13 Mar 2022 03:01:29 -0600 -Subject: [PATCH] Fixes the Blank SkullOwner exploit - - -diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java -index 47c8148e6413c51ffdd30082bfb37a7fb8a73a71..48fce864be2a92c9665b9eeb85e3193eaed4133d 100644 ---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java -+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java -@@ -11,6 +11,7 @@ import net.minecraft.nbt.CompoundTag; - import net.minecraft.nbt.NbtUtils; - import net.minecraft.resources.ResourceLocation; - import net.minecraft.world.level.block.entity.SkullBlockEntity; -+import org.apache.commons.lang3.StringUtils; // Scissors - import org.bukkit.Bukkit; - import org.bukkit.Material; - import org.bukkit.NamespacedKey; -@@ -74,7 +75,7 @@ class CraftMetaSkull extends CraftMetaItem implements SkullMeta { - try { // Paper - Ignore invalid game profiles - if (tag.contains(SKULL_OWNER.NBT, CraftMagicNumbers.NBT.TAG_COMPOUND)) { - this.setProfile(NbtUtils.readGameProfile(tag.getCompound(SKULL_OWNER.NBT))); -- } else if (tag.contains(SKULL_OWNER.NBT, CraftMagicNumbers.NBT.TAG_STRING) && !tag.getString(SKULL_OWNER.NBT).isEmpty()) { -+ } else if (tag.contains(SKULL_OWNER.NBT, CraftMagicNumbers.NBT.TAG_STRING) && !StringUtils.isBlank(tag.getString(SKULL_OWNER.NBT))) { // Scissors - this.setProfile(new GameProfile(null, tag.getString(SKULL_OWNER.NBT))); - } - } catch (Exception ignored) {} // Paper diff --git a/patches/removed/server/0005-Fixes-log-spam-caused-by-invalid-entities-in-beehive.patch b/patches/server/0004-Fixes-log-spam-caused-by-invalid-entities-in-beehive.patch similarity index 100% rename from patches/removed/server/0005-Fixes-log-spam-caused-by-invalid-entities-in-beehive.patch rename to patches/server/0004-Fixes-log-spam-caused-by-invalid-entities-in-beehive.patch diff --git a/patches/removed/server/0006-Removes-useless-spammy-error-logging.patch b/patches/server/0005-Removes-useless-spammy-error-logging.patch similarity index 85% rename from patches/removed/server/0006-Removes-useless-spammy-error-logging.patch rename to patches/server/0005-Removes-useless-spammy-error-logging.patch index 26a8737..7a963b9 100644 --- a/patches/removed/server/0006-Removes-useless-spammy-error-logging.patch +++ b/patches/server/0005-Removes-useless-spammy-error-logging.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Removes useless spammy error logging diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -index 3df1822b55358a9bdf41bcacd5b7fecfd8f05dfa..f9741039dada19391e80d9623f2d8cabc1089506 100644 +index aeca803cc0434d9de9434987d6e43b70353e305b..5bd581c1a82236359c810037333590d0d9741587 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -@@ -1813,8 +1813,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1814,8 +1814,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { resource = CraftNamespacedKey.fromMinecraft(key); } } catch (IllegalArgumentException ex) { diff --git a/patches/removed/server/0007-Ignore-errors-thrown-when-trying-to-remove-minecart-.patch b/patches/server/0006-Ignore-errors-thrown-when-trying-to-remove-minecart-.patch similarity index 100% rename from patches/removed/server/0007-Ignore-errors-thrown-when-trying-to-remove-minecart-.patch rename to patches/server/0006-Ignore-errors-thrown-when-trying-to-remove-minecart-.patch diff --git a/patches/removed/server/0008-ItemEntity-Check-if-items-are-air-before-calling-set.patch b/patches/server/0007-ItemEntity-Check-if-items-are-air-before-calling-set.patch similarity index 91% rename from patches/removed/server/0008-ItemEntity-Check-if-items-are-air-before-calling-set.patch rename to patches/server/0007-ItemEntity-Check-if-items-are-air-before-calling-set.patch index 15dc434..8c8d0c8 100644 --- a/patches/removed/server/0008-ItemEntity-Check-if-items-are-air-before-calling-set.patch +++ b/patches/server/0007-ItemEntity-Check-if-items-are-air-before-calling-set.patch @@ -5,7 +5,7 @@ Subject: [PATCH] ItemEntity - Check if items are air before calling setItem diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index 52196431a6538872755344859a0454a0e50c3b6e..2312881cdd925ec538fff3df7cdc7e04770453eb 100644 +index eb0351aa12eebcefab1d1d14641fc3c60cbbcab8..cf944848cdebbb6f04f5211e00c876329e86d9cc 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -425,11 +425,15 @@ public class ItemEntity extends Entity implements TraceableEntity { diff --git a/patches/server/0008-Fixes-Knowledge-Books-causing-log-spam-when-invalid-.patch b/patches/server/0008-Fixes-Knowledge-Books-causing-log-spam-when-invalid-.patch new file mode 100644 index 0000000..dd2c69f --- /dev/null +++ b/patches/server/0008-Fixes-Knowledge-Books-causing-log-spam-when-invalid-.patch @@ -0,0 +1,49 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Video +Date: Sun, 13 Mar 2022 18:42:07 -0600 +Subject: [PATCH] Fixes Knowledge Books causing log spam when invalid data is + provided + + +diff --git a/src/main/java/net/minecraft/world/item/KnowledgeBookItem.java b/src/main/java/net/minecraft/world/item/KnowledgeBookItem.java +index 37f37be56bab171df442b980ff46ff325daae283..deade19d16a7d6870171b9a60806a8cadb437db4 100644 +--- a/src/main/java/net/minecraft/world/item/KnowledgeBookItem.java ++++ b/src/main/java/net/minecraft/world/item/KnowledgeBookItem.java +@@ -40,9 +40,9 @@ public class KnowledgeBookItem extends Item { + + for(int i = 0; i < listTag.size(); ++i) { + String string = listTag.getString(i); +- Optional> optional = recipeManager.byKey(new ResourceLocation(string)); ++ Optional> optional = recipeManager.byKey(ResourceLocation.tryParse(string)); // Scissors - Validate resource locations + if (!optional.isPresent()) { +- LOGGER.error("Invalid recipe: {}", (Object)string); ++ // Scissors - Don't log errors caused by invalid recipes being provided + return InteractionResultHolder.fail(itemStack); + } + +@@ -55,7 +55,7 @@ public class KnowledgeBookItem extends Item { + + return InteractionResultHolder.sidedSuccess(itemStack, world.isClientSide()); + } else { +- LOGGER.error("Tag not valid: {}", (Object)compoundTag); ++ // Scissors - Don't throw errors into the logs if an NBT compound isn't present or is missing the Recipes tag. + return InteractionResultHolder.fail(itemStack); + } + } +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java +index 50fdb086ffec84edc5138737c95f08ed4757a6f3..da312b4670fc0ac07e4ab798d4793025e362783e 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java +@@ -41,7 +41,11 @@ public class CraftMetaKnowledgeBook extends CraftMetaItem implements KnowledgeBo + for (int i = 0; i < pages.size(); i++) { + String recipe = pages.getString(i); + +- this.addRecipe(CraftNamespacedKey.fromString(recipe)); ++ // Scissors start - Don't add recipes with invalid namespaces ++ try { ++ this.addRecipe(CraftNamespacedKey.fromString(recipe)); ++ } catch (Exception ignored) {} ++ // Scissors end + } + } + }