From fd8eccb3d4ca53e0cb1728ab094b4d6236f133de Mon Sep 17 00:00:00 2001 From: FlorianMichael Date: Sun, 5 Jan 2025 23:56:17 +0100 Subject: [PATCH 1/5] Fixup luck and random implementation in CB loot-tables Looking at the git history this is broken since 1.14 (No idea what upstream did here). This fixes the CB loot table API to properly support the luck and random setters / to actually do something with them. --- .../level/storage/loot/LootTable.java.patch | 11 ++++++----- .../org/bukkit/craftbukkit/CraftLootTable.java | 16 +++++++--------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch b/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch index 21a8108d1a9f..f345c0c27d50 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch @@ -20,19 +20,20 @@ output.accept(itemStack); } else { int count = itemStack.getCount(); -@@ -141,9 +_,22 @@ +@@ -141,9 +_,21 @@ } public void fill(Container container, LootParams params, long seed) { +- LootContext lootContext = new LootContext.Builder(params).withOptionalRandomSeed(seed).create(this.randomSequence); + // CraftBukkit start -+ this.fillInventory(container, params, seed, false); ++ this.fillInventory(container, params, RandomSource.create(seed), false); + } + -+ public void fillInventory(Container container, LootParams params, long seed, boolean plugin) { ++ public void fillInventory(Container container, LootParams params, RandomSource random, boolean plugin) { + // CraftBukkit end - LootContext lootContext = new LootContext.Builder(params).withOptionalRandomSeed(seed).create(this.randomSequence); ++ LootContext lootContext = new LootContext.Builder(params).withOptionalRandomSource(random).create(this.randomSequence); ObjectArrayList randomItems = this.getRandomItems(lootContext); - RandomSource random = lootContext.getRandom(); +- RandomSource random = lootContext.getRandom(); + // CraftBukkit start + org.bukkit.event.world.LootGenerateEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callLootGenerateEvent(container, this, lootContext, randomItems, plugin); + if (event.isCancelled()) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java index 5fd22a80e9d0..9cac7774309c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java @@ -27,6 +27,7 @@ import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.util.CraftLocation; import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.craftbukkit.util.RandomSourceWrapper; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.loot.LootContext; @@ -68,8 +69,8 @@ public LootTable getHandle() { @Override public Collection populateLoot(Random random, LootContext context) { Preconditions.checkArgument(context != null, "LootContext cannot be null"); - LootParams nmsContext = this.convertContext(context, random); - List nmsItems = this.handle.getRandomItems(nmsContext); + LootParams nmsContext = this.convertContext(context); + List nmsItems = this.handle.getRandomItems(nmsContext, new RandomSourceWrapper(random)); Collection bukkit = new ArrayList<>(nmsItems.size()); for (net.minecraft.world.item.ItemStack item : nmsItems) { @@ -86,12 +87,12 @@ public Collection populateLoot(Random random, LootContext context) { public void fillInventory(Inventory inventory, Random random, LootContext context) { Preconditions.checkArgument(inventory != null, "Inventory cannot be null"); Preconditions.checkArgument(context != null, "LootContext cannot be null"); - LootParams nmsContext = this.convertContext(context, random); + LootParams nmsContext = this.convertContext(context); CraftInventory craftInventory = (CraftInventory) inventory; Container handle = craftInventory.getInventory(); // TODO: When events are added, call event here w/ custom reason? - this.getHandle().fillInventory(handle, nmsContext, random.nextLong(), true); + this.getHandle().fillInventory(handle, nmsContext, new RandomSourceWrapper(random), true); } @Override @@ -99,19 +100,16 @@ public NamespacedKey getKey() { return this.key; } - private LootParams convertContext(LootContext context, Random random) { + private LootParams convertContext(LootContext context) { Preconditions.checkArgument(context != null, "LootContext cannot be null"); Location loc = context.getLocation(); Preconditions.checkArgument(loc.getWorld() != null, "LootContext.getLocation#getWorld cannot be null"); ServerLevel handle = ((CraftWorld) loc.getWorld()).getHandle(); LootParams.Builder builder = new LootParams.Builder(handle); - if (random != null) { - // builder = builder.withRandom(new RandomSourceWrapper(random)); - } this.setMaybe(builder, LootContextParams.ORIGIN, CraftLocation.toVec3D(loc)); if (this.getHandle() != LootTable.EMPTY) { - // builder.luck(context.getLuck()); + builder.withLuck(context.getLuck()); if (context.getLootedEntity() != null) { Entity nmsLootedEntity = ((CraftEntity) context.getLootedEntity()).getHandle(); From b513eca1de88bcc1dbba2c9ddef964af0da98a46 Mon Sep 17 00:00:00 2001 From: FlorianMichael Date: Tue, 28 Jan 2025 14:56:30 +0100 Subject: [PATCH 2/5] Restore previous behaviour --- .../world/level/storage/loot/LootTable.java.patch | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch b/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch index f345c0c27d50..fb1c5ff4f27f 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch @@ -20,20 +20,20 @@ output.accept(itemStack); } else { int count = itemStack.getCount(); -@@ -141,9 +_,21 @@ +@@ -141,9 +_,22 @@ } public void fill(Container container, LootParams params, long seed) { - LootContext lootContext = new LootContext.Builder(params).withOptionalRandomSeed(seed).create(this.randomSequence); + // CraftBukkit start -+ this.fillInventory(container, params, RandomSource.create(seed), false); ++ this.fillInventory(container, params, seed == 0L ? null : RandomSource.create(seed), false); + } + -+ public void fillInventory(Container container, LootParams params, RandomSource random, boolean plugin) { ++ public void fillInventory(Container container, LootParams params, RandomSource randomSource, boolean plugin) { + // CraftBukkit end -+ LootContext lootContext = new LootContext.Builder(params).withOptionalRandomSource(random).create(this.randomSequence); ++ LootContext lootContext = new LootContext.Builder(params).withOptionalRandomSource(randomSource).create(this.randomSequence); ObjectArrayList randomItems = this.getRandomItems(lootContext); -- RandomSource random = lootContext.getRandom(); + RandomSource random = lootContext.getRandom(); + // CraftBukkit start + org.bukkit.event.world.LootGenerateEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callLootGenerateEvent(container, this, lootContext, randomItems, plugin); + if (event.isCancelled()) { From 1897457d103bb6575eacfcf0b843cee75d0ab479 Mon Sep 17 00:00:00 2001 From: FlorianMichael Date: Fri, 31 Jan 2025 20:17:53 +0100 Subject: [PATCH 3/5] Rename overload --- .../net/minecraft/world/RandomizableContainer.java.patch | 8 +++++--- .../world/entity/vehicle/ContainerEntity.java.patch | 9 ++++++++- .../world/level/storage/loot/LootTable.java.patch | 6 ++++-- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/RandomizableContainer.java.patch b/paper-server/patches/sources/net/minecraft/world/RandomizableContainer.java.patch index 8467c86645c6..6c82705a615b 100644 --- a/paper-server/patches/sources/net/minecraft/world/RandomizableContainer.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/RandomizableContainer.java.patch @@ -27,7 +27,7 @@ } else { return false; } -@@ -69,26 +_,42 @@ +@@ -69,32 +_,61 @@ return false; } else { tag.putString("LootTable", lootTable.location().toString()); @@ -72,8 +72,10 @@ LootParams.Builder builder = new LootParams.Builder((ServerLevel)level).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(blockPos)); if (player != null) { builder.withLuck(player.getLuck()).withParameter(LootContextParams.THIS_ENTITY, player); -@@ -97,4 +_,17 @@ - lootTable1.fill(this, builder.create(LootContextParamSets.CHEST), this.getLootTableSeed()); + } + +- lootTable1.fill(this, builder.create(LootContextParamSets.CHEST), this.getLootTableSeed()); ++ lootTable1.fillInventory(this, builder.create(LootContextParamSets.CHEST), this.getLootTableSeed()); } } + diff --git a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch index fea198069caa..148a23eccb88 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch @@ -32,7 +32,7 @@ } default void chestVehicleDestroyed(DamageSource damageSource, ServerLevel level, Entity entity) { -@@ -91,19 +_,27 @@ +@@ -91,25 +_,33 @@ } default InteractionResult interactWithContainerVehicle(Player player) { @@ -63,6 +63,13 @@ LootParams.Builder builder = new LootParams.Builder((ServerLevel)this.level()).withParameter(LootContextParams.ORIGIN, this.position()); if (player != null) { builder.withLuck(player.getLuck()).withParameter(LootContextParams.THIS_ENTITY, player); + } + +- lootTable.fill(this, builder.create(LootContextParamSets.CHEST), this.getContainerLootTableSeed()); ++ lootTable.fillInventory(this, builder.create(LootContextParamSets.CHEST), this.getContainerLootTableSeed()); + } + } + @@ -173,4 +_,14 @@ default boolean isChestVehicleStillValid(Player player) { return !this.isRemoved() && player.canInteractWithEntity(this.getBoundingBox(), 4.0); diff --git a/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch b/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch index fb1c5ff4f27f..3c1ffaf2c332 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch @@ -20,11 +20,13 @@ output.accept(itemStack); } else { int count = itemStack.getCount(); -@@ -141,9 +_,22 @@ +@@ -140,10 +_,23 @@ + } } - public void fill(Container container, LootParams params, long seed) { +- public void fill(Container container, LootParams params, long seed) { - LootContext lootContext = new LootContext.Builder(params).withOptionalRandomSeed(seed).create(this.randomSequence); ++ public void fillInventory(Container container, LootParams params, long seed) { + // CraftBukkit start + this.fillInventory(container, params, seed == 0L ? null : RandomSource.create(seed), false); + } From d29ffc2af1c4555de4ff53453eeb79bfd8216e3c Mon Sep 17 00:00:00 2001 From: FlorianMichael Date: Fri, 31 Jan 2025 21:52:01 +0100 Subject: [PATCH 4/5] Fixup --- .../minecraft/world/RandomizableContainer.java.patch | 8 +++----- .../world/entity/vehicle/ContainerEntity.java.patch | 9 +-------- .../world/level/storage/loot/LootTable.java.patch | 10 ++++------ .../java/org/bukkit/craftbukkit/CraftLootTable.java | 2 +- 4 files changed, 9 insertions(+), 20 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/RandomizableContainer.java.patch b/paper-server/patches/sources/net/minecraft/world/RandomizableContainer.java.patch index 6c82705a615b..8467c86645c6 100644 --- a/paper-server/patches/sources/net/minecraft/world/RandomizableContainer.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/RandomizableContainer.java.patch @@ -27,7 +27,7 @@ } else { return false; } -@@ -69,32 +_,61 @@ +@@ -69,26 +_,42 @@ return false; } else { tag.putString("LootTable", lootTable.location().toString()); @@ -72,10 +72,8 @@ LootParams.Builder builder = new LootParams.Builder((ServerLevel)level).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(blockPos)); if (player != null) { builder.withLuck(player.getLuck()).withParameter(LootContextParams.THIS_ENTITY, player); - } - -- lootTable1.fill(this, builder.create(LootContextParamSets.CHEST), this.getLootTableSeed()); -+ lootTable1.fillInventory(this, builder.create(LootContextParamSets.CHEST), this.getLootTableSeed()); +@@ -97,4 +_,17 @@ + lootTable1.fill(this, builder.create(LootContextParamSets.CHEST), this.getLootTableSeed()); } } + diff --git a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch index 148a23eccb88..fea198069caa 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch @@ -32,7 +32,7 @@ } default void chestVehicleDestroyed(DamageSource damageSource, ServerLevel level, Entity entity) { -@@ -91,25 +_,33 @@ +@@ -91,19 +_,27 @@ } default InteractionResult interactWithContainerVehicle(Player player) { @@ -63,13 +63,6 @@ LootParams.Builder builder = new LootParams.Builder((ServerLevel)this.level()).withParameter(LootContextParams.ORIGIN, this.position()); if (player != null) { builder.withLuck(player.getLuck()).withParameter(LootContextParams.THIS_ENTITY, player); - } - -- lootTable.fill(this, builder.create(LootContextParamSets.CHEST), this.getContainerLootTableSeed()); -+ lootTable.fillInventory(this, builder.create(LootContextParamSets.CHEST), this.getContainerLootTableSeed()); - } - } - @@ -173,4 +_,14 @@ default boolean isChestVehicleStillValid(Player player) { return !this.isRemoved() && player.canInteractWithEntity(this.getBoundingBox(), 4.0); diff --git a/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch b/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch index 3c1ffaf2c332..53f28e336307 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch @@ -20,18 +20,16 @@ output.accept(itemStack); } else { int count = itemStack.getCount(); -@@ -140,10 +_,23 @@ - } +@@ -141,9 +_,22 @@ } -- public void fill(Container container, LootParams params, long seed) { + public void fill(Container container, LootParams params, long seed) { - LootContext lootContext = new LootContext.Builder(params).withOptionalRandomSeed(seed).create(this.randomSequence); -+ public void fillInventory(Container container, LootParams params, long seed) { + // CraftBukkit start -+ this.fillInventory(container, params, seed == 0L ? null : RandomSource.create(seed), false); ++ this.fill(container, params, seed == 0L ? null : RandomSource.create(seed), false); + } + -+ public void fillInventory(Container container, LootParams params, RandomSource randomSource, boolean plugin) { ++ public void fill(Container container, LootParams params, RandomSource randomSource, boolean plugin) { + // CraftBukkit end + LootContext lootContext = new LootContext.Builder(params).withOptionalRandomSource(randomSource).create(this.randomSequence); ObjectArrayList randomItems = this.getRandomItems(lootContext); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java index 9cac7774309c..99e9067f7381 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java @@ -92,7 +92,7 @@ public void fillInventory(Inventory inventory, Random random, LootContext contex Container handle = craftInventory.getInventory(); // TODO: When events are added, call event here w/ custom reason? - this.getHandle().fillInventory(handle, nmsContext, new RandomSourceWrapper(random), true); + this.getHandle().fill(handle, nmsContext, new RandomSourceWrapper(random), true); } @Override From 9f13e318354562cad874197f497aede16af3baa0 Mon Sep 17 00:00:00 2001 From: FlorianMichael Date: Fri, 31 Jan 2025 22:53:11 +0100 Subject: [PATCH 5/5] Fixup API even more lol --- .../src/main/java/org/bukkit/craftbukkit/CraftLootTable.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java index 99e9067f7381..4f29e9af057f 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java @@ -70,7 +70,7 @@ public LootTable getHandle() { public Collection populateLoot(Random random, LootContext context) { Preconditions.checkArgument(context != null, "LootContext cannot be null"); LootParams nmsContext = this.convertContext(context); - List nmsItems = this.handle.getRandomItems(nmsContext, new RandomSourceWrapper(random)); + List nmsItems = this.handle.getRandomItems(nmsContext, random == null ? null : new RandomSourceWrapper(random)); Collection bukkit = new ArrayList<>(nmsItems.size()); for (net.minecraft.world.item.ItemStack item : nmsItems) { @@ -92,7 +92,7 @@ public void fillInventory(Inventory inventory, Random random, LootContext contex Container handle = craftInventory.getInventory(); // TODO: When events are added, call event here w/ custom reason? - this.getHandle().fill(handle, nmsContext, new RandomSourceWrapper(random), true); + this.getHandle().fill(handle, nmsContext, random == null ? null : new RandomSourceWrapper(random), true); } @Override