A bunch of patches

This commit is contained in:
Shane Freeder
2024-10-23 20:43:06 +01:00
parent c9e7a34e4b
commit 615e1d5a6a
20 changed files with 94 additions and 58 deletions

View File

@@ -1,24 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: booky10 <boooky10@gmail.com>
Date: Fri, 5 Nov 2021 21:01:36 +0100
Subject: [PATCH] Add API for resetting a single score
It was only possible to reset all scores for a specific entry, instead of resetting only specific scores.
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java
@@ -0,0 +0,0 @@ final class CraftScore implements Score {
public CraftScoreboard getScoreboard() {
return this.objective.getScoreboard();
}
+
+ // Paper start
+ @Override
+ public void resetScore() {
+ Scoreboard board = this.objective.checkState().board;
+ board.resetSinglePlayerScore(entry, this.objective.getHandle());
+ }
+ // Paper end
}

View File

@@ -1,87 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sun, 3 Jan 2021 17:58:11 -0800
Subject: [PATCH] Add BlockBreakBlockEvent
diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/Block.java
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
@@ -0,0 +0,0 @@ public class Block extends BlockBehaviour implements ItemLike {
}
+ // Paper start - Add BlockBreakBlockEvent
+ public static boolean dropResources(BlockState state, LevelAccessor levelAccessor, BlockPos pos, @Nullable BlockEntity blockEntity, BlockPos source) {
+ if (levelAccessor instanceof ServerLevel serverLevel) {
+ List<org.bukkit.inventory.ItemStack> items = new java.util.ArrayList<>();
+ for (ItemStack drop : Block.getDrops(state, serverLevel, pos, blockEntity)) {
+ items.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(drop));
+ }
+ io.papermc.paper.event.block.BlockBreakBlockEvent event = new io.papermc.paper.event.block.BlockBreakBlockEvent(org.bukkit.craftbukkit.block.CraftBlock.at(levelAccessor, pos), org.bukkit.craftbukkit.block.CraftBlock.at(levelAccessor, source), items);
+ event.callEvent();
+ for (org.bukkit.inventory.ItemStack drop : event.getDrops()) {
+ popResource(serverLevel, pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(drop));
+ }
+ state.spawnAfterBreak(serverLevel, pos, ItemStack.EMPTY, true);
+ }
+ return true;
+ }
+ // Paper end - Add BlockBreakBlockEvent
+
public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) {
if (world instanceof ServerLevel) {
Block.getDrops(state, (ServerLevel) world, pos, blockEntity, entity, tool).forEach((itemstack1) -> {
diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
@@ -0,0 +0,0 @@ public class PistonBaseBlock extends DirectionalBlock {
iblockdata1 = world.getBlockState(blockposition3);
BlockEntity tileentity = iblockdata1.hasBlockEntity() ? world.getBlockEntity(blockposition3) : null;
- dropResources(iblockdata1, world, blockposition3, tileentity);
+ dropResources(iblockdata1, world, blockposition3, tileentity, pos); // Paper - Add BlockBreakBlockEvent
world.setBlock(blockposition3, Blocks.AIR.defaultBlockState(), 18);
world.gameEvent((Holder) GameEvent.BLOCK_DESTROY, blockposition3, GameEvent.Context.of(iblockdata1));
if (!iblockdata1.is(BlockTags.FIRE)) {
diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
+++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
@@ -0,0 +0,0 @@ public abstract class FlowingFluid extends Fluid {
((LiquidBlockContainer) state.getBlock()).placeLiquid(world, pos, state, fluidState);
} else {
if (!state.isAir()) {
- this.beforeDestroyingBlock(world, pos, state);
+ this.beforeDestroyingBlock(world, pos, state, pos.relative(direction.getOpposite())); // Paper - Add BlockBreakBlockEvent
}
world.setBlock(pos, fluidState.createLegacyBlock(), 3);
@@ -0,0 +0,0 @@ public abstract class FlowingFluid extends Fluid {
}
+ protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) { beforeDestroyingBlock(world, pos, state); } // Paper - Add BlockBreakBlockEvent
protected abstract void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state);
private static short getCacheKey(BlockPos from, BlockPos to) {
diff --git a/src/main/java/net/minecraft/world/level/material/WaterFluid.java b/src/main/java/net/minecraft/world/level/material/WaterFluid.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/material/WaterFluid.java
+++ b/src/main/java/net/minecraft/world/level/material/WaterFluid.java
@@ -0,0 +0,0 @@ public abstract class WaterFluid extends FlowingFluid {
return world.getGameRules().getBoolean(GameRules.RULE_WATER_SOURCE_CONVERSION);
}
+ // Paper start - Add BlockBreakBlockEvent
+ @Override
+ protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) {
+ BlockEntity tileentity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null;
+ Block.dropResources(state, world, pos, tileentity, source);
+ }
+ // Paper end - Add BlockBreakBlockEvent
@Override
protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state) {
BlockEntity blockEntity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null;

View File

@@ -1,58 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 14 Oct 2021 12:09:39 -0500
Subject: [PATCH] Add ItemFactory#getSpawnEgg API
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
@@ -0,0 +0,0 @@ import net.minecraft.core.HolderSet;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.registries.Registries;
+import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tags.EnchantmentTags;
import net.minecraft.util.RandomSource;
@@ -0,0 +0,0 @@ public final class CraftItemFactory implements ItemFactory {
new net.md_5.bungee.api.chat.TextComponent(customName));
}
// Paper end - bungee hover events
+
+ // Paper start - old getSpawnEgg API
+ // @Override // used to override, upstream added conflicting method, is called via Commodore now
+ @Deprecated
+ public ItemStack getSpawnEgg0(org.bukkit.entity.EntityType type) {
+ if (type == null) {
+ return null;
+ }
+ String typeId = type.getKey().toString();
+ net.minecraft.resources.ResourceLocation typeKey = ResourceLocation.parse(typeId);
+ net.minecraft.world.entity.EntityType<?> nmsType = net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.get(typeKey);
+ net.minecraft.world.item.SpawnEggItem eggItem = net.minecraft.world.item.SpawnEggItem.byId(nmsType);
+ return eggItem == null ? null : new net.minecraft.world.item.ItemStack(eggItem).asBukkitMirror();
+ }
+ // Paper end - old getSpawnEgg API
}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
@@ -0,0 +0,0 @@ public class Commodore {
}
// Paper end
+ // Paper start - ItemFactory#getSpawnEgg (paper had original method that returned ItemStack, upstream added identical but returned Material)
+ if (owner.equals("org/bukkit/inventory/ItemFactory") && name.equals("getSpawnEgg") && desc.equals("(Lorg/bukkit/entity/EntityType;)Lorg/bukkit/inventory/ItemStack;")) {
+ super.visitInsn(Opcodes.SWAP); // has 1 param, this moves the owner instance to the top for the checkcast
+ super.visitTypeInsn(Opcodes.CHECKCAST, runtimeCbPkgPrefix() + "inventory/CraftItemFactory");
+ super.visitInsn(Opcodes.SWAP); // moves param back to the the top of stack
+ super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, runtimeCbPkgPrefix() + "inventory/CraftItemFactory", "getSpawnEgg0", desc, false);
+ return;
+ }
+ // Paper end - ItemFactory#getSpawnEgg
if (modern) {
if (owner.equals("org/bukkit/Material") || (instantiatedMethodType != null && instantiatedMethodType.getDescriptor().startsWith("(Lorg/bukkit/Material;)"))) {
switch (name) {

View File

@@ -1,90 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Sun, 24 Oct 2021 16:20:31 -0400
Subject: [PATCH] Add Raw Byte Entity Serialization
== AT ==
public net.minecraft.world.entity.Entity setLevel(Lnet/minecraft/world/level/Level;)V
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
}
+ // Paper start - Entity serialization api
+ public boolean serializeEntity(CompoundTag compound) {
+ List<Entity> pass = new java.util.ArrayList<>(this.getPassengers());
+ this.passengers = ImmutableList.of();
+ boolean result = save(compound);
+ this.passengers = ImmutableList.copyOf(pass);
+ return result;
+ }
+ // Paper end - Entity serialization api
public boolean save(CompoundTag nbt) {
return this.isPassenger() ? false : this.saveAsPassenger(nbt);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -0,0 +0,0 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
}
// Paper end - tracked players API
+ // Paper start - raw entity serialization API
+ @Override
+ public boolean spawnAt(Location location, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) {
+ Preconditions.checkNotNull(location, "location cannot be null");
+ Preconditions.checkNotNull(reason, "reason cannot be null");
+ this.entity.setLevel(((CraftWorld) location.getWorld()).getHandle());
+ this.entity.setPos(location.getX(), location.getY(), location.getZ());
+ this.entity.setRot(location.getYaw(), location.getPitch());
+ return !this.entity.valid && this.entity.level().addFreshEntity(this.entity, reason);
+ }
+ // Paper end - raw entity serialization API
+
// Paper start - missing entity api
@Override
public boolean isInvisible() { // Paper - moved up from LivingEntity
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -0,0 +0,0 @@ public final class CraftMagicNumbers implements UnsafeValues {
return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.parse(MinecraftServer.getServer().registryAccess(), compound).orElseThrow());
}
- private byte[] serializeNbtToBytes(CompoundTag compound) {
+ @Override
+ public byte[] serializeEntity(org.bukkit.entity.Entity entity) {
+ Preconditions.checkNotNull(entity, "null cannot be serialized");
+ Preconditions.checkArgument(entity instanceof org.bukkit.craftbukkit.entity.CraftEntity, "only CraftEntities can be serialized");
+
+ net.minecraft.nbt.CompoundTag compound = new net.minecraft.nbt.CompoundTag();
+ ((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().serializeEntity(compound);
+ return serializeNbtToBytes(compound);
+ }
+
+ @Override
+ public org.bukkit.entity.Entity deserializeEntity(byte[] data, org.bukkit.World world, boolean preserveUUID) {
+ Preconditions.checkNotNull(data, "null cannot be deserialized");
+ Preconditions.checkArgument(data.length > 0, "cannot deserialize nothing");
+
+ net.minecraft.nbt.CompoundTag compound = deserializeNbtFromBytes(data);
+ int dataVersion = compound.getInt("DataVersion");
+ compound = (net.minecraft.nbt.CompoundTag) MinecraftServer.getServer().fixerUpper.update(References.ENTITY, new Dynamic<>(NbtOps.INSTANCE, compound), dataVersion, this.getDataVersion()).getValue();
+ if (!preserveUUID) {
+ // Generate a new UUID so we don't have to worry about deserializing the same entity twice
+ compound.remove("UUID");
+ }
+ return net.minecraft.world.entity.EntityType.create(compound, ((org.bukkit.craftbukkit.CraftWorld) world).getHandle())
+ .orElseThrow(() -> new IllegalArgumentException("An ID was not found for the data. Did you downgrade?")).getBukkitEntity();
+ }
+
+ private byte[] serializeNbtToBytes(net.minecraft.nbt.CompoundTag compound) {
compound.putInt("DataVersion", getDataVersion());
java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream();
try {

View File

@@ -1,48 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sun, 16 May 2021 09:39:46 -0700
Subject: [PATCH] Add back EntityPortalExitEvent
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
if (world instanceof ServerLevel worldserver) {
if (!this.isRemoved()) {
// CraftBukkit start
- Location to = new Location(teleportTarget.newLevel().getWorld(), teleportTarget.pos().x, teleportTarget.pos().y, teleportTarget.pos().z, teleportTarget.yRot(), teleportTarget.xRot());
+ Location to = new Location(teleportTarget.newLevel().getWorld(), teleportTarget.pos().x, teleportTarget.pos().y, teleportTarget.pos().z, teleportTarget.yRot(), this.getXRot()); // Paper - use getXRot (doesn't respect DimensionTransition pitch)
// Paper start - gateway-specific teleport event
final EntityTeleportEvent teleEvent;
if (this.portalProcess != null && this.portalProcess.isSamePortal(((net.minecraft.world.level.block.EndGatewayBlock) net.minecraft.world.level.block.Blocks.END_GATEWAY)) && this.level.getBlockEntity(this.portalProcess.getEntryPosition()) instanceof net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity theEndGatewayBlockEntity) {
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return null;
}
to = teleEvent.getTo();
- teleportTarget = new DimensionTransition(((CraftWorld) to.getWorld()).getHandle(), CraftLocation.toVec3D(to), teleportTarget.speed(), to.getYaw(), to.getPitch(), teleportTarget.missingRespawnBlock(), teleportTarget.postDimensionTransition(), teleportTarget.cause());
+ // Paper start - Call EntityPortalExitEvent
+ if (this.portalProcess != null) { // if in a portal
+ CraftEntity bukkitEntity = this.getBukkitEntity();
+ Vec3 velocity = teleportTarget.speed();
+ org.bukkit.event.entity.EntityPortalExitEvent event = new org.bukkit.event.entity.EntityPortalExitEvent(
+ bukkitEntity,
+ bukkitEntity.getLocation(), to.clone(),
+ bukkitEntity.getVelocity(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(velocity)
+ );
+ event.callEvent();
+
+ if (!event.isCancelled() && event.getTo() != null) {
+ to = event.getTo().clone();
+ velocity = org.bukkit.craftbukkit.util.CraftVector.toNMS(event.getAfter());
+ }
+ teleportTarget = new DimensionTransition(((CraftWorld) to.getWorld()).getHandle(), CraftLocation.toVec3D(to), velocity, to.getYaw(), to.getPitch(), teleportTarget.missingRespawnBlock(), teleportTarget.postDimensionTransition(), teleportTarget.cause());
+ }
+ if (this.isRemoved()) {
+ return null;
+ }
+ // Paper end - Call EntityPortalExitEvent
// CraftBukkit end
ServerLevel worldserver1 = teleportTarget.newLevel();
List<Entity> list = this.getPassengers();

View File

@@ -1,101 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: dodison <kacpik@mapik.eu>
Date: Mon, 26 Jul 2021 17:32:36 +0200
Subject: [PATCH] Add critical damage API
diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSource.java b/src/main/java/net/minecraft/world/damagesource/DamageSource.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/damagesource/DamageSource.java
+++ b/src/main/java/net/minecraft/world/damagesource/DamageSource.java
@@ -0,0 +0,0 @@ public class DamageSource {
public Holder<DamageType> typeHolder() {
return this.type;
}
+
+ // Paper start - add critical damage API
+ private boolean critical;
+ public boolean isCritical() {
+ return this.critical;
+ }
+ public DamageSource critical() {
+ return this.critical(true);
+ }
+ public DamageSource critical(boolean critical) {
+ this.critical = critical;
+ return this;
+ }
+ // Paper end - add critical damage API
}
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper - Toggleable player crits
if (flag2) {
+ damagesource = damagesource.critical(true); // Paper start - critical damage API
f *= 1.5F;
}
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
float f7 = this.getEnchantedDamage(entityliving2, f6, damagesource) * f2;
// CraftBukkit start - Only apply knockback if the damage hits
- if (!entityliving2.hurt(this.damageSources().playerAttack(this).sweep(), f7)) {
+ if (!entityliving2.hurt(this.damageSources().playerAttack(this).sweep().critical(flag2), f7)) { // Paper - add critical damage API
continue;
}
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
@@ -0,0 +0,0 @@ public abstract class AbstractArrow extends Projectile {
entityliving.setLastHurtMob(entity);
}
+ if (this.isCritArrow()) damagesource = damagesource.critical(); // Paper - add critical damage API
boolean flag = entity.getType() == EntityType.ENDERMAN;
int k = entity.getRemainingFireTicks();
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -0,0 +0,0 @@ public class CraftEventFactory {
return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
}
DamageCause damageCause = (damager.getBukkitEntity() instanceof org.bukkit.entity.TNTPrimed) ? DamageCause.BLOCK_EXPLOSION : DamageCause.ENTITY_EXPLOSION;
- return CraftEventFactory.callEntityDamageEvent(damager, entity, damageCause, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
+ return CraftEventFactory.callEntityDamageEvent(damager, entity, damageCause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.isCritical()); // Paper - add critical damage API
} else if (damager != null || source.getDirectEntity() != null) {
DamageCause cause = (source.isSweep()) ? DamageCause.ENTITY_SWEEP_ATTACK : DamageCause.ENTITY_ATTACK;
@@ -0,0 +0,0 @@ public class CraftEventFactory {
cause = DamageCause.MAGIC;
}
- return CraftEventFactory.callEntityDamageEvent(damager, entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
+ return CraftEventFactory.callEntityDamageEvent(damager, entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.isCritical()); // Paper - add critical damage API
} else if (source.is(DamageTypes.FELL_OUT_OF_WORLD)) {
return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, DamageCause.VOID, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
} else if (source.is(DamageTypes.LAVA)) {
@@ -0,0 +0,0 @@ public class CraftEventFactory {
cause = DamageCause.CUSTOM;
}
- return CraftEventFactory.callEntityDamageEvent((Entity) null, entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
+ return CraftEventFactory.callEntityDamageEvent((Entity) null, entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.isCritical()); // Paper - add critical damage API
}
- private static EntityDamageEvent callEntityDamageEvent(Entity damager, Entity damagee, DamageCause cause, org.bukkit.damage.DamageSource bukkitDamageSource, Map<DamageModifier, Double> modifiers, Map<DamageModifier, Function<? super Double, Double>> modifierFunctions, boolean cancelled) {
+ private static EntityDamageEvent callEntityDamageEvent(Entity damager, Entity damagee, DamageCause cause, org.bukkit.damage.DamageSource bukkitDamageSource, Map<DamageModifier, Double> modifiers, Map<DamageModifier, Function<? super Double, Double>> modifierFunctions, boolean cancelled, boolean critical) { // Paper - add critical damage API
EntityDamageEvent event;
if (damager != null) {
- event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions);
+ event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions, critical);
} else {
event = new EntityDamageEvent(damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions);
}

View File

@@ -1,56 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Thu, 4 Nov 2021 11:50:40 -0700
Subject: [PATCH] Add hasCollision methods to various places
== AT ==
public net.minecraft.world.level.block.state.BlockBehaviour hasCollision
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -0,0 +0,0 @@ public class CraftBlock implements Block {
public boolean isSolid() {
return this.getNMS().blocksMotion();
}
+
+ @Override
+ public boolean isCollidable() {
+ return getNMS().getBlock().hasCollision;
+ }
// Paper end
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
@@ -0,0 +0,0 @@ public class CraftBlockState implements BlockState {
public BlockState copy(Location location) {
return new CraftBlockState(this, location);
}
+
+ // Paper start
+ @Override
+ public boolean isCollidable() {
+ return this.data.getBlock().hasCollision;
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockType.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockType.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockType.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockType.java
@@ -0,0 +0,0 @@ public class CraftBlockType<B extends BlockData> implements BlockType.Typed<B>,
return this.block.getDescriptionId();
}
// Paper end - add Translatable
+
+ // Paper start - hasCollision API
+ @Override
+ public boolean hasCollision() {
+ return this.block.hasCollision;
+ }
+ // Paper end - hasCollision API
}

View File

@@ -1,60 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jakub Zacek <dawon@dawon.eu>
Date: Mon, 4 Oct 2021 10:16:44 +0200
Subject: [PATCH] Add methods to find targets for lightning strikes
== AT ==
public net.minecraft.server.level.ServerLevel findLightningRod(Lnet/minecraft/core/BlockPos;)Ljava/util/Optional;
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
protected BlockPos findLightningTargetAround(BlockPos pos) {
+ // Paper start - Add methods to find targets for lightning strikes
+ return this.findLightningTargetAround(pos, false);
+ }
+ public BlockPos findLightningTargetAround(BlockPos pos, boolean returnNullWhenNoTarget) {
+ // Paper end - Add methods to find targets for lightning strikes
BlockPos blockposition1 = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, pos);
Optional<BlockPos> optional = this.findLightningRod(blockposition1);
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
if (!list.isEmpty()) {
return ((LivingEntity) list.get(this.random.nextInt(list.size()))).blockPosition();
} else {
+ if (returnNullWhenNoTarget) return null; // Paper - Add methods to find targets for lightning strikes
if (blockposition1.getY() == this.getMinBuildHeight() - 1) {
blockposition1 = blockposition1.above(2);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
return (LightningStrike) lightning.getBukkitEntity();
}
+ // Paper start - Add methods to find targets for lightning strikes
+ @Override
+ public Location findLightningRod(Location location) {
+ return this.world.findLightningRod(io.papermc.paper.util.MCUtil.toBlockPosition(location))
+ .map(blockPos -> io.papermc.paper.util.MCUtil.toLocation(this.world, blockPos)
+ // get the actual rod pos
+ .subtract(0, 1, 0))
+ .orElse(null);
+ }
+
+ @Override
+ public Location findLightningTarget(Location location) {
+ final BlockPos pos = this.world.findLightningTargetAround(io.papermc.paper.util.MCUtil.toBlockPosition(location), true);
+ return pos == null ? null : io.papermc.paper.util.MCUtil.toLocation(this.world, pos);
+ }
+ // Paper end - Add methods to find targets for lightning strikes
+
@Override
public boolean generateTree(Location loc, TreeType type) {
return this.generateTree(loc, CraftWorld.rand, type);

View File

@@ -1,114 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 1 Oct 2021 08:04:39 -0700
Subject: [PATCH] Add missing team sidebar display slots
== AT ==
public org.bukkit.craftbukkit.scoreboard.CraftScoreboardTranslations
public org.bukkit.craftbukkit.scoreboard.CraftScoreboardTranslations toBukkitSlot(Lnet/minecraft/world/scores/DisplaySlot;)Lorg/bukkit/scoreboard/DisplaySlot;
public org.bukkit.craftbukkit.scoreboard.CraftScoreboardTranslations fromBukkitSlot(Lorg/bukkit/scoreboard/DisplaySlot;)Lnet/minecraft/world/scores/DisplaySlot;
diff --git a/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java b/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java
+++ b/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java
@@ -0,0 +0,0 @@ public class FieldRename {
}
return switch (owner) {
+ case "org/bukkit/scoreboard/DisplaySlot" -> FieldRename.convertDisplaySlot(from); // Paper - DisplaySlot
case "org/bukkit/block/banner/PatternType" -> FieldRename.convertPatternTypeName(apiVersion, from);
case "org/bukkit/enchantments/Enchantment" -> FieldRename.convertEnchantmentName(apiVersion, from);
case "org/bukkit/block/Biome" -> FieldRename.convertBiomeName(apiVersion, from);
@@ -0,0 +0,0 @@ public class FieldRename {
//}
// Paper end
+ // Paper start - DisplaySlot
+ @DoNotReroute
+ public static String convertDisplaySlot(final String from) {
+ if (from.startsWith("SIDEBAR_") && !from.startsWith("SIDEBAR_TEAM_")) {
+ return from.replace("SIDEBAR_", "SIDEBAR_TEAM_");
+ }
+ return from;
+ }
+ // Paper end - DisplaySlot
+
// PatternType
private static final FieldRenameData PATTERN_TYPE_DATA = FieldRenameData.Builder.newBuilder()
.forVersionsBefore(ApiVersion.FIELD_NAME_PARITY)
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java
@@ -0,0 +0,0 @@ import org.bukkit.scoreboard.RenderType;
public final class CraftScoreboardTranslations {
static final int MAX_DISPLAY_SLOT = 19;
+ @Deprecated // Paper
static final ImmutableBiMap<DisplaySlot, String> SLOTS = ImmutableBiMap.<DisplaySlot, String>builder()
.put(DisplaySlot.BELOW_NAME, "below_name")
.put(DisplaySlot.PLAYER_LIST, "list")
.put(DisplaySlot.SIDEBAR, "sidebar")
- .put(DisplaySlot.SIDEBAR_BLACK, "sidebar.team.black")
- .put(DisplaySlot.SIDEBAR_DARK_BLUE, "sidebar.team.dark_blue")
- .put(DisplaySlot.SIDEBAR_DARK_GREEN, "sidebar.team.dark_green")
- .put(DisplaySlot.SIDEBAR_DARK_AQUA, "sidebar.team.dark_aqua")
- .put(DisplaySlot.SIDEBAR_DARK_RED, "sidebar.team.dark_red")
- .put(DisplaySlot.SIDEBAR_DARK_PURPLE, "sidebar.team.dark_purple")
- .put(DisplaySlot.SIDEBAR_GOLD, "sidebar.team.gold")
- .put(DisplaySlot.SIDEBAR_GRAY, "sidebar.team.gray")
- .put(DisplaySlot.SIDEBAR_DARK_GRAY, "sidebar.team.dark_gray")
- .put(DisplaySlot.SIDEBAR_BLUE, "sidebar.team.blue")
- .put(DisplaySlot.SIDEBAR_GREEN, "sidebar.team.green")
- .put(DisplaySlot.SIDEBAR_AQUA, "sidebar.team.aqua")
- .put(DisplaySlot.SIDEBAR_RED, "sidebar.team.red")
- .put(DisplaySlot.SIDEBAR_LIGHT_PURPLE, "sidebar.team.light_purple")
- .put(DisplaySlot.SIDEBAR_YELLOW, "sidebar.team.yellow")
- .put(DisplaySlot.SIDEBAR_WHITE, "sidebar.team.white")
.buildOrThrow();
private CraftScoreboardTranslations() {}
public static DisplaySlot toBukkitSlot(net.minecraft.world.scores.DisplaySlot minecraft) {
+ if (true) return DisplaySlot.NAMES.value(minecraft.getSerializedName()); // Paper
return CraftScoreboardTranslations.SLOTS.inverse().get(minecraft.getSerializedName());
}
public static net.minecraft.world.scores.DisplaySlot fromBukkitSlot(DisplaySlot slot) {
+ if (true) return net.minecraft.world.scores.DisplaySlot.CODEC.byName(slot.getId()); // Paper
return net.minecraft.world.scores.DisplaySlot.CODEC.byName(CraftScoreboardTranslations.SLOTS.get(slot));
}
diff --git a/src/test/java/io/papermc/paper/scoreboard/DisplaySlotTest.java b/src/test/java/io/papermc/paper/scoreboard/DisplaySlotTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/test/java/io/papermc/paper/scoreboard/DisplaySlotTest.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.scoreboard;
+
+import org.bukkit.craftbukkit.scoreboard.CraftScoreboardTranslations;
+import org.bukkit.scoreboard.DisplaySlot;
+import org.bukkit.support.environment.Normal;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+@Normal
+public class DisplaySlotTest {
+
+ @Test
+ public void testBukkitToMinecraftDisplaySlots() {
+ for (DisplaySlot bukkitSlot : DisplaySlot.values()) {
+ assertNotNull(CraftScoreboardTranslations.fromBukkitSlot(bukkitSlot));
+ }
+ }
+
+ @Test
+ public void testMinecraftToBukkitDisplaySlots() {
+ for (net.minecraft.world.scores.DisplaySlot nmsSlot : net.minecraft.world.scores.DisplaySlot.values()) {
+ assertNotNull(CraftScoreboardTranslations.toBukkitSlot(nmsSlot));
+ }
+ }
+}

View File

@@ -1,213 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: syldium <syldium@mailo.com>
Date: Fri, 9 Jul 2021 18:50:40 +0200
Subject: [PATCH] Add more advancement API
== AT ==
public net.minecraft.advancements.Advancement decorateName(Lnet/minecraft/advancements/DisplayInfo;)Lnet/minecraft/network/chat/Component;
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
diff --git a/src/main/java/io/papermc/paper/advancement/PaperAdvancementDisplay.java b/src/main/java/io/papermc/paper/advancement/PaperAdvancementDisplay.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/io/papermc/paper/advancement/PaperAdvancementDisplay.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.advancement;
+
+import io.papermc.paper.adventure.PaperAdventure;
+import net.kyori.adventure.text.Component;
+import net.minecraft.advancements.Advancement;
+import net.minecraft.advancements.AdvancementType;
+import net.minecraft.advancements.DisplayInfo;
+import org.bukkit.NamespacedKey;
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
+import org.bukkit.craftbukkit.util.CraftNamespacedKey;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public record PaperAdvancementDisplay(DisplayInfo handle) implements AdvancementDisplay {
+
+ @Override
+ public @NotNull Frame frame() {
+ return asPaperFrame(this.handle.getType());
+ }
+
+ @Override
+ public @NotNull Component title() {
+ return PaperAdventure.asAdventure(this.handle.getTitle());
+ }
+
+ @Override
+ public @NotNull Component description() {
+ return PaperAdventure.asAdventure(this.handle.getDescription());
+ }
+
+ @Override
+ public @NotNull ItemStack icon() {
+ return CraftItemStack.asBukkitCopy(this.handle.getIcon());
+ }
+
+ @Override
+ public boolean doesShowToast() {
+ return this.handle.shouldShowToast();
+ }
+
+ @Override
+ public boolean doesAnnounceToChat() {
+ return this.handle.shouldAnnounceChat();
+ }
+
+ @Override
+ public boolean isHidden() {
+ return this.handle.isHidden();
+ }
+
+ @Override
+ public @Nullable NamespacedKey backgroundPath() {
+ return this.handle.getBackground().map(CraftNamespacedKey::fromMinecraft).orElse(null);
+ }
+
+ @Override
+ public @NotNull Component displayName() {
+ return PaperAdventure.asAdventure(Advancement.decorateName(java.util.Objects.requireNonNull(this.handle, "cannot build display name for null handle, invalid state")));
+ }
+
+ public static @NotNull Frame asPaperFrame(final @NotNull AdvancementType frameType) {
+ return switch (frameType) {
+ case TASK -> Frame.TASK;
+ case CHALLENGE -> Frame.CHALLENGE;
+ case GOAL -> Frame.GOAL;
+ };
+ }
+}
diff --git a/src/main/java/net/minecraft/advancements/DisplayInfo.java b/src/main/java/net/minecraft/advancements/DisplayInfo.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/advancements/DisplayInfo.java
+++ b/src/main/java/net/minecraft/advancements/DisplayInfo.java
@@ -0,0 +0,0 @@ public class DisplayInfo {
private final boolean hidden;
private float x;
private float y;
+ public final io.papermc.paper.advancement.AdvancementDisplay paper = new io.papermc.paper.advancement.PaperAdvancementDisplay(this); // Paper - Add more advancement API
public DisplayInfo(
ItemStack icon,
diff --git a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java
+++ b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java
@@ -0,0 +0,0 @@ public class CraftAdvancement implements org.bukkit.advancement.Advancement {
return Collections.unmodifiableCollection(this.handle.value().criteria().keySet());
}
+ // Paper start - Add more advancement API
@Override
- public AdvancementDisplay getDisplay() {
- if (this.handle.value().display().isEmpty()) {
- return null;
+ public io.papermc.paper.advancement.AdvancementDisplay getDisplay() {
+ return this.handle.value().display().map(d -> d.paper).orElse(null);
+ }
+
+ @Deprecated
+ @io.papermc.paper.annotation.DoNotUse
+ public AdvancementDisplay getDisplay0() { // May be called by plugins via Commodore
+ return this.handle.value().display().map(CraftAdvancementDisplay::new).orElse(null);
+ }
+
+ @Override
+ public net.kyori.adventure.text.Component displayName() {
+ return io.papermc.paper.adventure.PaperAdventure.asAdventure(net.minecraft.advancements.Advancement.name(this.handle));
+ }
+
+ @Override
+ public org.bukkit.advancement.Advancement getParent() {
+ return this.handle.value().parent()
+ .map(net.minecraft.server.MinecraftServer.getServer().getAdvancements()::get)
+ .map(AdvancementHolder::toBukkit)
+ .orElse(null);
+ }
+
+ @Override
+ public Collection<org.bukkit.advancement.Advancement> getChildren() {
+ final com.google.common.collect.ImmutableList.Builder<org.bukkit.advancement.Advancement> children = com.google.common.collect.ImmutableList.<org.bukkit.advancement.Advancement>builder();
+ final net.minecraft.advancements.AdvancementNode advancementNode = net.minecraft.server.MinecraftServer.getServer().getAdvancements().tree().get(this.handle);
+ if (advancementNode != null) {
+ for (final net.minecraft.advancements.AdvancementNode child : advancementNode.children()) {
+ children.add(child.holder().toBukkit());
+ }
}
+ return children.build();
+ }
- return new CraftAdvancementDisplay(this.handle.value().display().get());
+ @Override
+ public org.bukkit.advancement.Advancement getRoot() {
+ final net.minecraft.advancements.AdvancementNode advancementNode = net.minecraft.server.MinecraftServer.getServer().getAdvancements().tree().get(this.handle);
+ return java.util.Objects.requireNonNull(advancementNode, "could not find internal advancement node for advancement " + this.handle.id()).root().holder().toBukkit();
}
+ // Paper end - Add more advancement API
}
diff --git a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java
+++ b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java
@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.util.CraftChatMessage;
import org.bukkit.inventory.ItemStack;
+@Deprecated // Paper
public class CraftAdvancementDisplay implements org.bukkit.advancement.AdvancementDisplay {
private final DisplayInfo handle;
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
@@ -0,0 +0,0 @@ public class Commodore {
super.visitMethodInsn(opcode, owner, name, "()Lcom/destroystokyo/paper/profile/PlayerProfile;", itf);
return;
}
+ if (owner.equals("org/bukkit/advancement/Advancement") && name.equals("getDisplay") && desc.endsWith(")Lorg/bukkit/advancement/AdvancementDisplay;")) {
+ super.visitTypeInsn(Opcodes.CHECKCAST, runtimeCbPkgPrefix() + "advancement/CraftAdvancement");
+ super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, runtimeCbPkgPrefix() + "advancement/CraftAdvancement", "getDisplay0", desc, false);
+ return;
+ }
// Paper end
if (modern) {
diff --git a/src/test/java/io/papermc/paper/advancement/AdvancementFrameTest.java b/src/test/java/io/papermc/paper/advancement/AdvancementFrameTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/test/java/io/papermc/paper/advancement/AdvancementFrameTest.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.advancement;
+
+import io.papermc.paper.adventure.PaperAdventure;
+import net.kyori.adventure.text.format.TextColor;
+import net.minecraft.advancements.AdvancementType;
+import net.minecraft.network.chat.contents.TranslatableContents;
+import org.bukkit.support.environment.Normal;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@Normal
+public class AdvancementFrameTest {
+
+ @Test
+ public void test() {
+ for (final AdvancementType advancementType : AdvancementType.values()) {
+ final TextColor expectedColor = PaperAdventure.asAdventure(advancementType.getChatColor());
+ final String expectedTranslationKey = ((TranslatableContents) advancementType.getDisplayName().getContents()).getKey();
+ final var frame = PaperAdvancementDisplay.asPaperFrame(advancementType);
+ assertEquals(expectedTranslationKey, frame.translationKey(), "The translation keys should be the same");
+ assertEquals(expectedColor, frame.color(), "The frame colors should be the same");
+ assertEquals(advancementType.getSerializedName(), AdvancementDisplay.Frame.NAMES.key(frame));
+ }
+ }
+}

View File

@@ -1,68 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Thu, 11 Mar 2021 03:03:32 -0800
Subject: [PATCH] Do not run close logic for inventories on chunk unload
Still call the event and change the active container though. We
want to avoid close logic because it's possible to load the
chunk through it. This should also be OK from a leak prevention/
state desync POV because the TE is getting unloaded anyways.
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
// Spigot Start
for (net.minecraft.world.level.block.entity.BlockEntity tileentity : chunk.getBlockEntities().values()) {
if (tileentity instanceof net.minecraft.world.Container) {
+ // Paper start - this area looks like it can load chunks, change the behavior
+ // chests for example can apply physics to the world
+ // so instead we just change the active container and call the event
for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((net.minecraft.world.Container) tileentity).getViewers())) {
- h.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper - Inventory close reason
+ ((org.bukkit.craftbukkit.entity.CraftHumanEntity) h).getHandle().closeUnloadedInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper - Inventory close reason
}
+ // Paper end - this area looks like it can load chunks, change the behavior
}
}
// Spigot End
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId));
this.doCloseContainer();
}
+ // Paper start - special close for unloaded inventory
+ @Override
+ public void closeUnloadedInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
+ // copied from above
+ CraftEventFactory.handleInventoryCloseEvent(this, reason); // CraftBukkit
+ // Paper end
+ // copied from below
+ this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId));
+ this.containerMenu = this.inventoryMenu;
+ // do not run close logic
+ }
+ // Paper end - special close for unloaded inventory
@Override
public void doCloseContainer() {
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
this.containerMenu = this.inventoryMenu;
}
// Paper end - Inventory close reason
+ // Paper start - special close for unloaded inventory
+ public void closeUnloadedInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
+ this.containerMenu = this.inventoryMenu;
+ }
+ // Paper end - special close for unloaded inventory
public void closeContainer() {
this.containerMenu = this.inventoryMenu;

View File

@@ -1,126 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sat, 11 Jul 2020 05:09:28 -0700
Subject: [PATCH] Fix GameProfileCache concurrency
Separate lookup and state access locks prevent lookups
from stalling simple state access/write calls
diff --git a/src/main/java/net/minecraft/server/players/GameProfileCache.java b/src/main/java/net/minecraft/server/players/GameProfileCache.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/players/GameProfileCache.java
+++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java
@@ -0,0 +0,0 @@ public class GameProfileCache {
@Nullable
private Executor executor;
+ // Paper start - Fix GameProfileCache concurrency
+ protected final java.util.concurrent.locks.ReentrantLock stateLock = new java.util.concurrent.locks.ReentrantLock();
+ protected final java.util.concurrent.locks.ReentrantLock lookupLock = new java.util.concurrent.locks.ReentrantLock();
+ // Paper end - Fix GameProfileCache concurrency
+
public GameProfileCache(GameProfileRepository profileRepository, File cacheFile) {
this.profileRepository = profileRepository;
this.file = cacheFile;
@@ -0,0 +0,0 @@ public class GameProfileCache {
}
private void safeAdd(GameProfileCache.GameProfileInfo entry) {
+ try { this.stateLock.lock(); // Paper - Fix GameProfileCache concurrency
GameProfile gameprofile = entry.getProfile();
entry.setLastAccess(this.getNextOperation());
this.profilesByName.put(gameprofile.getName().toLowerCase(Locale.ROOT), entry);
this.profilesByUUID.put(gameprofile.getId(), entry);
+ } finally { this.stateLock.unlock(); } // Paper - Fix GameProfileCache concurrency
}
private static Optional<GameProfile> lookupGameProfile(GameProfileRepository repository, String name) {
@@ -0,0 +0,0 @@ public class GameProfileCache {
// Paper start
public @Nullable GameProfile getProfileIfCached(String name) {
+ try { this.stateLock.lock(); // Paper - Fix GameProfileCache concurrency
GameProfileCache.GameProfileInfo entry = this.profilesByName.get(name.toLowerCase(Locale.ROOT));
if (entry == null) {
return null;
}
entry.setLastAccess(this.getNextOperation());
return entry.getProfile();
+ } finally { this.stateLock.unlock(); } // Paper - Fix GameProfileCache concurrency
}
// Paper end
public Optional<GameProfile> get(String name) {
String s1 = name.toLowerCase(Locale.ROOT);
+ boolean stateLocked = true; try { this.stateLock.lock(); // Paper - Fix GameProfileCache concurrency
GameProfileCache.GameProfileInfo usercache_usercacheentry = (GameProfileCache.GameProfileInfo) this.profilesByName.get(s1);
boolean flag = false;
@@ -0,0 +0,0 @@ public class GameProfileCache {
if (usercache_usercacheentry != null) {
usercache_usercacheentry.setLastAccess(this.getNextOperation());
optional = Optional.of(usercache_usercacheentry.getProfile());
+ stateLocked = false; this.stateLock.unlock(); // Paper - Fix GameProfileCache concurrency
} else {
+ stateLocked = false; this.stateLock.unlock(); // Paper - Fix GameProfileCache concurrency
+ try { this.lookupLock.lock(); // Paper - Fix GameProfileCache concurrency
optional = GameProfileCache.lookupGameProfile(this.profileRepository, name); // CraftBukkit - use correct case for offline players
+ } finally { this.lookupLock.unlock(); } // Paper - Fix GameProfileCache concurrency
if (optional.isPresent()) {
this.add((GameProfile) optional.get());
flag = false;
@@ -0,0 +0,0 @@ public class GameProfileCache {
}
return optional;
+ } finally { if (stateLocked) { this.stateLock.unlock(); } } // Paper - Fix GameProfileCache concurrency
}
public CompletableFuture<Optional<GameProfile>> getAsync(String username) {
@@ -0,0 +0,0 @@ public class GameProfileCache {
}
public Optional<GameProfile> get(UUID uuid) {
+ try { this.stateLock.lock(); // Paper - Fix GameProfileCache concurrency
GameProfileCache.GameProfileInfo usercache_usercacheentry = (GameProfileCache.GameProfileInfo) this.profilesByUUID.get(uuid);
if (usercache_usercacheentry == null) {
@@ -0,0 +0,0 @@ public class GameProfileCache {
usercache_usercacheentry.setLastAccess(this.getNextOperation());
return Optional.of(usercache_usercacheentry.getProfile());
}
+ } finally { this.stateLock.unlock(); } // Paper - Fix GameProfileCache concurrency
}
public void setExecutor(Executor executor) {
@@ -0,0 +0,0 @@ public class GameProfileCache {
JsonArray jsonarray = new JsonArray();
DateFormat dateformat = GameProfileCache.createDateFormat();
- this.getTopMRUProfiles(org.spigotmc.SpigotConfig.userCacheCap).forEach((usercache_usercacheentry) -> { // Spigot
+ this.listTopMRUProfiles(org.spigotmc.SpigotConfig.userCacheCap).forEach((usercache_usercacheentry) -> { // Spigot // Paper - Fix GameProfileCache concurrency
jsonarray.add(GameProfileCache.writeGameProfile(usercache_usercacheentry, dateformat));
});
String s = this.gson.toJson(jsonarray);
@@ -0,0 +0,0 @@ public class GameProfileCache {
}
private Stream<GameProfileCache.GameProfileInfo> getTopMRUProfiles(int limit) {
- return ImmutableList.copyOf(this.profilesByUUID.values()).stream().sorted(Comparator.comparing(GameProfileCache.GameProfileInfo::getLastAccess).reversed()).limit((long) limit);
+ // Paper start - Fix GameProfileCache concurrency
+ return this.listTopMRUProfiles(limit).stream();
+ }
+
+ private List<GameProfileCache.GameProfileInfo> listTopMRUProfiles(int limit) {
+ try {
+ this.stateLock.lock();
+ return this.profilesByUUID.values().stream().sorted(Comparator.comparing(GameProfileCache.GameProfileInfo::getLastAccess).reversed()).limit(limit).toList();
+ } finally {
+ this.stateLock.unlock();
+ }
}
+ // Paper end - Fix GameProfileCache concurrency
private static JsonElement writeGameProfile(GameProfileCache.GameProfileInfo entry, DateFormat dateFormat) {
JsonObject jsonobject = new JsonObject();

View File

@@ -1,59 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sun, 24 Oct 2021 20:29:45 -0700
Subject: [PATCH] Fix issues with mob conversion
diff --git a/src/main/java/net/minecraft/world/entity/monster/Skeleton.java b/src/main/java/net/minecraft/world/entity/monster/Skeleton.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Skeleton.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Skeleton.java
@@ -0,0 +0,0 @@ public class Skeleton extends AbstractSkeleton {
}
protected void doFreezeConversion() {
- this.convertTo(EntityType.STRAY, true, org.bukkit.event.entity.EntityTransformEvent.TransformReason.FROZEN, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.FROZEN); // CraftBukkit - add spawn and transform reasons
+ Stray stray = this.convertTo(EntityType.STRAY, true, org.bukkit.event.entity.EntityTransformEvent.TransformReason.FROZEN, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.FROZEN); // CraftBukkit - add spawn and transform reasons // Paper - Fix issues with mob conversion
if (!this.isSilent()) {
this.level().levelEvent((Player) null, 1048, this.blockPosition(), 0);
}
+ // Paper start - Fix issues with mob conversion; reset conversion time to prevent event spam
+ if (stray == null) {
+ this.conversionTime = 300;
+ }
+ // Paper end - Fix issues with mob conversion
}
diff --git a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java
+++ b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java
@@ -0,0 +0,0 @@ public class Hoglin extends Animal implements Enemy, HoglinBase {
if (zoglin != null) {
zoglin.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 200, 0));
}
+ // Paper start - Fix issues with mob conversion; reset to prevent event spam
+ else {
+ this.timeInOverworld = 0;
+ }
+ // Paper end - Fix issues with mob conversion
}
@Override
diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java
+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java
@@ -0,0 +0,0 @@ public abstract class AbstractPiglin extends Monster {
if (entitypigzombie != null) {
entitypigzombie.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 200, 0));
}
+ // Paper start - Fix issues with mob conversion; reset to prevent event spam
+ else {
+ this.timeInOverworld = 0;
+ }
+ // Paper end - Fix issues with mob conversion
}

View File

@@ -1,151 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 20 Aug 2021 13:03:21 -0700
Subject: [PATCH] Get entity default attributes
== AT ==
public net.minecraft.world.entity.ai.attributes.AttributeSupplier getAttributeInstance(Lnet/minecraft/core/Holder;)Lnet/minecraft/world/entity/ai/attributes/AttributeInstance;
diff --git a/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java b/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.attribute;
+
+import net.minecraft.world.entity.ai.attributes.AttributeInstance;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.attribute.AttributeModifier;
+import org.bukkit.craftbukkit.attribute.CraftAttributeInstance;
+
+import java.util.Collection;
+
+public class UnmodifiableAttributeInstance extends CraftAttributeInstance {
+
+ public UnmodifiableAttributeInstance(AttributeInstance handle, Attribute attribute) {
+ super(handle, attribute);
+ }
+
+ @Override
+ public void setBaseValue(double d) {
+ throw new UnsupportedOperationException("Cannot modify default attributes");
+ }
+
+ @Override
+ public void addModifier(AttributeModifier modifier) {
+ throw new UnsupportedOperationException("Cannot modify default attributes");
+ }
+
+ @Override
+ public void removeModifier(AttributeModifier modifier) {
+ throw new UnsupportedOperationException("Cannot modify default attributes");
+ }
+}
diff --git a/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeMap.java b/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeMap.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeMap.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.attribute;
+
+import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
+import org.bukkit.attribute.Attributable;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.attribute.AttributeInstance;
+import org.bukkit.craftbukkit.attribute.CraftAttribute;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class UnmodifiableAttributeMap implements Attributable {
+
+ private final AttributeSupplier handle;
+
+ public UnmodifiableAttributeMap(@NotNull AttributeSupplier handle) {
+ this.handle = handle;
+ }
+
+ @Override
+ public @Nullable AttributeInstance getAttribute(@NotNull Attribute attribute) {
+ net.minecraft.core.Holder<net.minecraft.world.entity.ai.attributes.Attribute> nmsAttribute = CraftAttribute.bukkitToMinecraftHolder(attribute);
+ if (!this.handle.hasAttribute(nmsAttribute)) {
+ return null;
+ }
+ return new UnmodifiableAttributeInstance(this.handle.getAttributeInstance(nmsAttribute), attribute);
+ }
+
+ @Override
+ public void registerAttribute(@NotNull Attribute attribute) {
+ throw new UnsupportedOperationException("Cannot register new attributes here");
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -0,0 +0,0 @@ public final class CraftMagicNumbers implements UnsafeValues {
}
return CraftMagicNumbers.getItem(itemToBeRepaired.getType()).isValidRepairItem(CraftItemStack.asNMSCopy(itemToBeRepaired), CraftItemStack.asNMSCopy(repairMaterial));
}
+
+ @Override
+ public boolean hasDefaultEntityAttributes(NamespacedKey bukkitEntityKey) {
+ return net.minecraft.world.entity.ai.attributes.DefaultAttributes.hasSupplier(net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.get(CraftNamespacedKey.toMinecraft(bukkitEntityKey)));
+ }
+
+ @Override
+ public org.bukkit.attribute.Attributable getDefaultEntityAttributes(NamespacedKey bukkitEntityKey) {
+ Preconditions.checkArgument(hasDefaultEntityAttributes(bukkitEntityKey), bukkitEntityKey + " doesn't have default attributes");
+ var supplier = net.minecraft.world.entity.ai.attributes.DefaultAttributes.getSupplier((net.minecraft.world.entity.EntityType<? extends net.minecraft.world.entity.LivingEntity>) net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.get(CraftNamespacedKey.toMinecraft(bukkitEntityKey)));
+ return new io.papermc.paper.attribute.UnmodifiableAttributeMap(supplier);
+ }
// Paper end
@Override
diff --git a/src/test/java/io/papermc/paper/attribute/EntityTypeAttributesTest.java b/src/test/java/io/papermc/paper/attribute/EntityTypeAttributesTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/test/java/io/papermc/paper/attribute/EntityTypeAttributesTest.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.attribute;
+
+import org.bukkit.attribute.Attributable;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.attribute.AttributeInstance;
+import org.bukkit.attribute.AttributeModifier;
+import org.bukkit.entity.EntityType;
+import org.bukkit.support.environment.AllFeatures;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@AllFeatures
+public class EntityTypeAttributesTest {
+
+ @Test
+ public void testIllegalEntity() {
+ assertFalse(EntityType.EGG.hasDefaultAttributes());
+ assertThrows(IllegalArgumentException.class, EntityType.EGG::getDefaultAttributes);
+ }
+
+ @Test
+ public void testLegalEntity() {
+ assertTrue(EntityType.ZOMBIE.hasDefaultAttributes());
+ EntityType.ZOMBIE.getDefaultAttributes();
+ }
+
+ @Test
+ public void testUnmodifiabilityOfAttributable() {
+ Attributable attributable = EntityType.ZOMBIE.getDefaultAttributes();
+ assertThrows(UnsupportedOperationException.class, () -> attributable.registerAttribute(Attribute.GENERIC_ATTACK_DAMAGE));
+ AttributeInstance instance = attributable.getAttribute(Attribute.GENERIC_FOLLOW_RANGE);
+ assertNotNull(instance);
+ assertThrows(UnsupportedOperationException.class, () -> instance.addModifier(new AttributeModifier("test", 3, AttributeModifier.Operation.ADD_NUMBER)));
+ assertThrows(UnsupportedOperationException.class, () -> instance.setBaseValue(3.2));
+ }
+}

View File

@@ -1,42 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Seggan <segganew@gmail.com>
Date: Thu, 5 Aug 2021 13:10:27 -0400
Subject: [PATCH] Goat ram API
diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
+++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
@@ -0,0 +0,0 @@ public class Goat extends Animal {
public static boolean checkGoatSpawnRules(EntityType<? extends Animal> entityType, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, RandomSource random) {
return world.getBlockState(pos.below()).is(BlockTags.GOATS_SPAWNABLE_ON) && isBrightEnoughToSpawn(world, pos);
}
+
+ // Paper start - Goat ram API
+ public void ram(net.minecraft.world.entity.LivingEntity entity) {
+ Brain<Goat> brain = this.getBrain();
+ brain.setMemory(MemoryModuleType.RAM_TARGET, entity.position());
+ brain.eraseMemory(MemoryModuleType.RAM_COOLDOWN_TICKS);
+ brain.eraseMemory(MemoryModuleType.BREED_TARGET);
+ brain.eraseMemory(MemoryModuleType.TEMPTING_PLAYER);
+ brain.setActiveActivityIfPossible(net.minecraft.world.entity.schedule.Activity.RAM);
+ }
+ // Paper end - Goat ram API
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftGoat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftGoat.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftGoat.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftGoat.java
@@ -0,0 +0,0 @@ public class CraftGoat extends CraftAnimals implements Goat {
public void setScreaming(boolean screaming) {
this.getHandle().setScreamingGoat(screaming);
}
+
+ // Paper start - Goat ram API
+ @Override
+ public void ram(@org.jetbrains.annotations.NotNull org.bukkit.entity.LivingEntity entity) {
+ this.getHandle().ram(((CraftLivingEntity) entity).getHandle());
+ }
+ // Paper end
}

View File

@@ -1,227 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Wed, 25 Aug 2021 20:17:12 -0700
Subject: [PATCH] Improve and expand AsyncCatcher
Log when the async catcher is tripped
The chunk system can swallow the exception given it's all
built with completablefuture, so ensure it is at least printed.
Add/move several async catchers
Async catch modifications to critical entity state
These used to be here from Spigot, but were dropped with 1.17.
Now in 1.17, this state is _even more_ critical than it was before,
so these must exist to catch stupid plugins.
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
public void internalTeleport(double d0, double d1, double d2, float f, float f1, Set<RelativeMovement> set) { // Paper
+ org.spigotmc.AsyncCatcher.catchOp("teleport"); // Paper
// Paper start - Prevent teleporting dead entities
if (player.isRemoved()) {
LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName());
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
public boolean addEffect(MobEffectInstance mobeffect, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause) {
- org.spigotmc.AsyncCatcher.catchOp("effect add"); // Spigot
+ // org.spigotmc.AsyncCatcher.catchOp("effect add"); // Spigot // Paper - move to API
if (this.isTickingEffects) {
this.effectsToProcess.add(new ProcessableEffect(mobeffect, cause));
return true;
diff --git a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
+++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
@@ -0,0 +0,0 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
private boolean addEntityUuid(T entity) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity add by UUID"); // Paper
if (!this.knownUuids.add(entity.getUUID())) {
PersistentEntitySectionManager.LOGGER.warn("UUID of added entity already exists: {}", entity);
return false;
@@ -0,0 +0,0 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
private boolean addEntity(T entity, boolean existing) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity add"); // Paper
// Paper start - chunk system hooks
if (existing) {
// I don't want to know why this is a generic type.
@@ -0,0 +0,0 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
void startTicking(T entity) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity start ticking"); // Paper
this.callbacks.onTickingStart(entity);
}
void stopTicking(T entity) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity stop ticking"); // Paper
this.callbacks.onTickingEnd(entity);
}
void startTracking(T entity) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity start tracking"); // Paper
this.visibleEntityStorage.add(entity);
this.callbacks.onTrackingStart(entity);
}
void stopTracking(T entity) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity stop tracking"); // Paper
this.callbacks.onTrackingEnd(entity);
this.visibleEntityStorage.remove(entity);
}
@@ -0,0 +0,0 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
public void updateChunkStatus(ChunkPos chunkPos, Visibility trackingStatus) {
+ org.spigotmc.AsyncCatcher.catchOp("Update chunk status"); // Paper
long i = chunkPos.toLong();
if (trackingStatus == Visibility.HIDDEN) {
@@ -0,0 +0,0 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
public void ensureChunkQueuedForLoad(long chunkPos) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity chunk save"); // Paper
PersistentEntitySectionManager.ChunkLoadStatus persistententitysectionmanager_b = (PersistentEntitySectionManager.ChunkLoadStatus) this.chunkLoadStatuses.get(chunkPos);
if (persistententitysectionmanager_b == PersistentEntitySectionManager.ChunkLoadStatus.FRESH) {
@@ -0,0 +0,0 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
private void requestChunkLoad(long chunkPos) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity chunk load request"); // Paper
this.chunkLoadStatuses.put(chunkPos, PersistentEntitySectionManager.ChunkLoadStatus.PENDING);
ChunkPos chunkcoordintpair = new ChunkPos(chunkPos);
CompletableFuture completablefuture = this.permanentStorage.loadEntities(chunkcoordintpair);
@@ -0,0 +0,0 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
private boolean processChunkUnload(long chunkPos) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity chunk unload process"); // Paper
boolean flag = this.storeChunkSections(chunkPos, (entityaccess) -> {
entityaccess.getPassengersAndSelf().forEach(this::unloadEntity);
}, true); // CraftBukkit - add boolean for event call
@@ -0,0 +0,0 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
private void processPendingLoads() {
+ org.spigotmc.AsyncCatcher.catchOp("Entity chunk process pending loads"); // Paper
ChunkEntities<T> chunkentities; // CraftBukkit - decompile error
while ((chunkentities = (ChunkEntities) this.loadingInbox.poll()) != null) {
@@ -0,0 +0,0 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
public void tick() {
+ org.spigotmc.AsyncCatcher.catchOp("Entity manager tick"); // Paper
this.processPendingLoads();
this.processUnloads();
}
@@ -0,0 +0,0 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
public void autoSave() {
+ org.spigotmc.AsyncCatcher.catchOp("Entity manager autosave"); // Paper
this.getAllChunksToSave().forEach((java.util.function.LongConsumer) (i) -> { // CraftBukkit - decompile error
boolean flag = this.chunkVisibility.get(i) == Visibility.HIDDEN;
@@ -0,0 +0,0 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
public void saveAll() {
+ org.spigotmc.AsyncCatcher.catchOp("Entity manager save"); // Paper
LongSet longset = this.getAllChunksToSave();
while (!longset.isEmpty()) {
@@ -0,0 +0,0 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
long i = SectionPos.asLong(blockposition);
if (i != this.currentSectionKey) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity move"); // Paper
Visibility visibility = this.currentSection.getStatus();
if (!this.currentSection.remove(this.entity)) {
@@ -0,0 +0,0 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
@Override
public void onRemove(Entity.RemovalReason reason) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity remove"); // Paper
if (!this.currentSection.remove(this.entity)) {
PersistentEntitySectionManager.LOGGER.warn("Entity {} wasn't found in section {} (destroying due to {})", new Object[]{this.entity, SectionPos.of(this.currentSectionKey), reason});
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public void playSound(Location loc, Sound sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) {
+ org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper
if (loc == null || sound == null || category == null) return;
double x = loc.getX();
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public void playSound(Location loc, String sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) {
+ org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper
if (loc == null || sound == null || category == null) return;
double x = loc.getX();
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public void playSound(Entity entity, Sound sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) {
+ org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper
if (!(entity instanceof CraftEntity craftEntity) || entity.getWorld() != this || sound == null || category == null) return;
ClientboundSoundEntityPacket packet = new ClientboundSoundEntityPacket(CraftSound.bukkitToMinecraftHolder(sound), net.minecraft.sounds.SoundSource.valueOf(category.name()), craftEntity.getHandle(), volume, pitch, seed);
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public void playSound(Entity entity, String sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) {
+ org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper
if (!(entity instanceof CraftEntity craftEntity) || entity.getWorld() != this || sound == null || category == null) return;
ClientboundSoundEntityPacket packet = new ClientboundSoundEntityPacket(Holder.direct(SoundEvent.createVariableRangeEvent(ResourceLocation.parse(sound))), net.minecraft.sounds.SoundSource.valueOf(category.name()), craftEntity.getHandle(), volume, pitch, seed);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
@Override
public boolean addPotionEffect(PotionEffect effect, boolean force) {
+ org.spigotmc.AsyncCatcher.catchOp("effect add"); // Paper
this.getHandle().addEffect(org.bukkit.craftbukkit.potion.CraftPotionUtil.fromBukkit(effect), EntityPotionEffectEvent.Cause.PLUGIN); // Paper - Don't ignore icon
return true;
}
diff --git a/src/main/java/org/spigotmc/AsyncCatcher.java b/src/main/java/org/spigotmc/AsyncCatcher.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/spigotmc/AsyncCatcher.java
+++ b/src/main/java/org/spigotmc/AsyncCatcher.java
@@ -0,0 +0,0 @@ public class AsyncCatcher
{
if ( AsyncCatcher.enabled && Thread.currentThread() != MinecraftServer.getServer().serverThread )
{
+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); // Paper
throw new IllegalStateException( "Asynchronous " + reason + "!" );
}
}

View File

@@ -1,27 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 14 Oct 2021 12:36:58 -0500
Subject: [PATCH] Left handed API
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
@@ -0,0 +0,0 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob {
public int getMaxHeadPitch() {
return getHandle().getMaxHeadXRot();
}
+
+ @Override
+ public boolean isLeftHanded() {
+ return getHandle().isLeftHanded();
+ }
+
+ @Override
+ public void setLeftHanded(boolean leftHanded) {
+ getHandle().setLeftHanded(leftHanded);
+ }
// Paper end
// Paper start

View File

@@ -1,101 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Thu, 23 Sep 2021 10:40:09 -0700
Subject: [PATCH] More CommandBlock API
diff --git a/src/main/java/io/papermc/paper/commands/PaperCommandBlockHolder.java b/src/main/java/io/papermc/paper/commands/PaperCommandBlockHolder.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/io/papermc/paper/commands/PaperCommandBlockHolder.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.commands;
+
+import io.papermc.paper.adventure.PaperAdventure;
+import io.papermc.paper.command.CommandBlockHolder;
+import net.kyori.adventure.text.Component;
+import net.minecraft.world.level.BaseCommandBlock;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
+
+@NullMarked
+public interface PaperCommandBlockHolder extends CommandBlockHolder {
+
+ BaseCommandBlock getCommandBlockHandle();
+
+ @Override
+ default Component lastOutput() {
+ return PaperAdventure.asAdventure(this.getCommandBlockHandle().getLastOutput());
+ }
+
+ @Override
+ default void lastOutput(final @Nullable Component lastOutput) {
+ this.getCommandBlockHandle().setLastOutput(PaperAdventure.asVanilla(lastOutput));
+ }
+
+ @Override
+ default int getSuccessCount() {
+ return this.getCommandBlockHandle().getSuccessCount();
+ }
+
+ @Override
+ default void setSuccessCount(final int successCount) {
+ this.getCommandBlockHandle().setSuccessCount(successCount);
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java
@@ -0,0 +0,0 @@ import org.bukkit.World;
import org.bukkit.block.CommandBlock;
import org.bukkit.craftbukkit.util.CraftChatMessage;
-public class CraftCommandBlock extends CraftBlockEntityState<CommandBlockEntity> implements CommandBlock {
+public class CraftCommandBlock extends CraftBlockEntityState<CommandBlockEntity> implements CommandBlock, io.papermc.paper.commands.PaperCommandBlockHolder {
public CraftCommandBlock(World world, CommandBlockEntity tileEntity) {
super(world, tileEntity);
@@ -0,0 +0,0 @@ public class CraftCommandBlock extends CraftBlockEntityState<CommandBlockEntity>
public void name(net.kyori.adventure.text.Component name) {
getSnapshot().getCommandBlock().setCustomName(name == null ? net.minecraft.network.chat.Component.literal("@") : io.papermc.paper.adventure.PaperAdventure.asVanilla(name));
}
+
+ @Override
+ public net.minecraft.world.level.BaseCommandBlock getCommandBlockHandle() {
+ return getSnapshot().getCommandBlock();
+ }
// Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java
@@ -0,0 +0,0 @@ import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.plugin.Plugin;
-public class CraftMinecartCommand extends CraftMinecart implements CommandMinecart {
+public class CraftMinecartCommand extends CraftMinecart implements CommandMinecart, io.papermc.paper.commands.PaperCommandBlockHolder {
private final PermissibleBase perm = new PermissibleBase(this);
public CraftMinecartCommand(CraftServer server, MinecartCommandBlock entity) {
@@ -0,0 +0,0 @@ public class CraftMinecartCommand extends CraftMinecart implements CommandMineca
public net.kyori.adventure.text.@org.jetbrains.annotations.NotNull Component name() {
return io.papermc.paper.adventure.PaperAdventure.asAdventure(this.getHandle().getCommandBlock().getName());
}
+
+ @Override
+ public net.minecraft.world.level.BaseCommandBlock getCommandBlockHandle() {
+ return getHandle().getCommandBlock();
+ }
+
+ @Override
+ public void lastOutput(net.kyori.adventure.text.Component lastOutput) {
+ io.papermc.paper.commands.PaperCommandBlockHolder.super.lastOutput(lastOutput);
+ getCommandBlockHandle().onUpdated();
+ }
// Paper end
@Override

View File

@@ -1,143 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sun, 26 Sep 2021 12:57:28 -0700
Subject: [PATCH] Option to prevent data components copy in smithing recipes
diff --git a/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java b/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java
+++ b/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java
@@ -0,0 +0,0 @@ public class SmithingTransformRecipe implements SmithingRecipe {
final Ingredient base;
final Ingredient addition;
final ItemStack result;
+ final boolean copyDataComponents; // Paper - Option to prevent data components copy
public SmithingTransformRecipe(Ingredient template, Ingredient base, Ingredient addition, ItemStack result) {
+ // Paper start - Option to prevent data components copy
+ this(template, base, addition, result, true);
+ }
+ public SmithingTransformRecipe(Ingredient template, Ingredient base, Ingredient addition, ItemStack result, boolean copyDataComponents) {
+ this.copyDataComponents = copyDataComponents;
+ // Paper end - Option to prevent data components copy
this.template = template;
this.base = base;
this.addition = addition;
@@ -0,0 +0,0 @@ public class SmithingTransformRecipe implements SmithingRecipe {
public ItemStack assemble(SmithingRecipeInput input, HolderLookup.Provider lookup) {
ItemStack itemstack = input.base().transmuteCopy(this.result.getItem(), this.result.getCount());
+ if (this.copyDataComponents) { // Paper - Option to prevent data components copy
itemstack.applyComponents(this.result.getComponentsPatch());
+ } // Paper - Option to prevent data components copy
return itemstack;
}
@@ -0,0 +0,0 @@ public class SmithingTransformRecipe implements SmithingRecipe {
public Recipe toBukkitRecipe(NamespacedKey id) {
CraftItemStack result = CraftItemStack.asCraftMirror(this.result);
- CraftSmithingTransformRecipe recipe = new CraftSmithingTransformRecipe(id, result, CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition));
+ CraftSmithingTransformRecipe recipe = new CraftSmithingTransformRecipe(id, result, CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition), this.copyDataComponents); // Paper - Option to prevent data components copy
return recipe;
}
diff --git a/src/main/java/net/minecraft/world/item/crafting/SmithingTrimRecipe.java b/src/main/java/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
+++ b/src/main/java/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
@@ -0,0 +0,0 @@ public class SmithingTrimRecipe implements SmithingRecipe {
final Ingredient template;
final Ingredient base;
final Ingredient addition;
+ final boolean copyDataComponents; // Paper - Option to prevent data components copy
public SmithingTrimRecipe(Ingredient template, Ingredient base, Ingredient addition) {
+ // Paper start - Option to prevent data components copy
+ this(template, base, addition, true);
+ }
+ public SmithingTrimRecipe(Ingredient template, Ingredient base, Ingredient addition, boolean copyDataComponents) {
+ this.copyDataComponents = copyDataComponents;
+ // Paper end - Option to prevent data components copy
this.template = template;
this.base = base;
this.addition = addition;
@@ -0,0 +0,0 @@ public class SmithingTrimRecipe implements SmithingRecipe {
return ItemStack.EMPTY;
}
- ItemStack itemstack1 = itemstack.copyWithCount(1);
+ ItemStack itemstack1 = this.copyDataComponents ? itemstack.copyWithCount(1) : new ItemStack(itemstack.getItem(), 1); // Paper - Option to prevent data components copy
itemstack1.set(DataComponents.TRIM, new ArmorTrim((Holder) optional.get(), (Holder) optional1.get()));
return itemstack1;
@@ -0,0 +0,0 @@ public class SmithingTrimRecipe implements SmithingRecipe {
// CraftBukkit start
@Override
public Recipe toBukkitRecipe(NamespacedKey id) {
- return new CraftSmithingTrimRecipe(id, CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition));
+ return new CraftSmithingTrimRecipe(id, CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition), this.copyDataComponents); // Paper - Option to prevent data components copy
}
// CraftBukkit end
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java
@@ -0,0 +0,0 @@ public class CraftSmithingTransformRecipe extends SmithingTransformRecipe implem
public CraftSmithingTransformRecipe(NamespacedKey key, ItemStack result, RecipeChoice template, RecipeChoice base, RecipeChoice addition) {
super(key, result, template, base, addition);
}
+ // Paper start - Option to prevent data components copy
+ public CraftSmithingTransformRecipe(NamespacedKey key, ItemStack result, RecipeChoice template, RecipeChoice base, RecipeChoice addition, boolean copyDataComponents) {
+ super(key, result, template, base, addition, copyDataComponents);
+ }
+ // Paper end - Option to prevent data components copy
public static CraftSmithingTransformRecipe fromBukkitRecipe(SmithingTransformRecipe recipe) {
if (recipe instanceof CraftSmithingTransformRecipe) {
return (CraftSmithingTransformRecipe) recipe;
}
- CraftSmithingTransformRecipe ret = new CraftSmithingTransformRecipe(recipe.getKey(), recipe.getResult(), recipe.getTemplate(), recipe.getBase(), recipe.getAddition());
+ CraftSmithingTransformRecipe ret = new CraftSmithingTransformRecipe(recipe.getKey(), recipe.getResult(), recipe.getTemplate(), recipe.getBase(), recipe.getAddition(), recipe.willCopyDataComponents()); // Paper - Option to prevent data components copy
return ret;
}
@@ -0,0 +0,0 @@ public class CraftSmithingTransformRecipe extends SmithingTransformRecipe implem
public void addToCraftingManager() {
ItemStack result = this.getResult();
- MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTransformRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), CraftItemStack.asNMSCopy(result))));
+ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTransformRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), CraftItemStack.asNMSCopy(result), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java
@@ -0,0 +0,0 @@ public class CraftSmithingTrimRecipe extends SmithingTrimRecipe implements Craft
public CraftSmithingTrimRecipe(NamespacedKey key, RecipeChoice template, RecipeChoice base, RecipeChoice addition) {
super(key, template, base, addition);
}
+ // Paper start - Option to prevent data components copy
+ public CraftSmithingTrimRecipe(NamespacedKey key, RecipeChoice template, RecipeChoice base, RecipeChoice addition, boolean copyDataComponents) {
+ super(key, template, base, addition, copyDataComponents);
+ }
+ // Paper end - Option to prevent data components copy
public static CraftSmithingTrimRecipe fromBukkitRecipe(SmithingTrimRecipe recipe) {
if (recipe instanceof CraftSmithingTrimRecipe) {
return (CraftSmithingTrimRecipe) recipe;
}
- CraftSmithingTrimRecipe ret = new CraftSmithingTrimRecipe(recipe.getKey(), recipe.getTemplate(), recipe.getBase(), recipe.getAddition());
+ CraftSmithingTrimRecipe ret = new CraftSmithingTrimRecipe(recipe.getKey(), recipe.getTemplate(), recipe.getBase(), recipe.getAddition(), recipe.willCopyDataComponents()); // Paper - Option to prevent data components copy
return ret;
}
@Override
public void addToCraftingManager() {
- MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTrimRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false))));
+ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTrimRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy
}
}

View File

@@ -1,79 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Wed, 25 Aug 2021 13:19:53 -0700
Subject: [PATCH] Vanilla command permission fixes
Fixes permission checks for vanilla commands which don't have a
requirement, as well as for namespaced vanilla commands.
== AT ==
public-f com.mojang.brigadier.tree.CommandNode requirement
diff --git a/src/main/java/com/mojang/brigadier/builder/ArgumentBuilder.java b/src/main/java/com/mojang/brigadier/builder/ArgumentBuilder.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/com/mojang/brigadier/builder/ArgumentBuilder.java
+++ b/src/main/java/com/mojang/brigadier/builder/ArgumentBuilder.java
@@ -0,0 +0,0 @@ import java.util.Collections;
import java.util.function.Predicate;
public abstract class ArgumentBuilder<S, T extends ArgumentBuilder<S, T>> {
+ // Paper start - Vanilla command permission fixes
+ private static final Predicate<Object> DEFAULT_REQUIREMENT = s -> true;
+
+ @SuppressWarnings("unchecked")
+ public static <S> Predicate<S> defaultRequirement() {
+ return (Predicate<S>) DEFAULT_REQUIREMENT;
+ }
+ // Paper end - Vanilla command permission fixes
private final RootCommandNode<S> arguments = new RootCommandNode<>();
private Command<S> command;
- private Predicate<S> requirement = s -> true;
+ private Predicate<S> requirement = defaultRequirement(); // Paper - Vanilla command permission fixes
private CommandNode<S> target;
private RedirectModifier<S> modifier = null;
private boolean forks;
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -0,0 +0,0 @@ public class Commands {
PublishCommand.register(this.dispatcher);
}
+ // Paper start - Vanilla command permission fixes
+ for (final CommandNode<CommandSourceStack> node : this.dispatcher.getRoot().getChildren()) {
+ if (node.getRequirement() == com.mojang.brigadier.builder.ArgumentBuilder.<CommandSourceStack>defaultRequirement()) {
+ node.requirement = stack -> stack.source == CommandSource.NULL || stack.getBukkitSender().hasPermission(org.bukkit.craftbukkit.command.VanillaCommandWrapper.getPermission(node));
+ }
+ }
+ // Paper end - Vanilla command permission fixes
// CraftBukkit start
}
diff --git a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
+++ b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
@@ -0,0 +0,0 @@ public final class VanillaCommandWrapper extends BukkitCommand {
}
public static String getPermission(CommandNode<CommandSourceStack> vanillaCommand) {
- return "minecraft.command." + ((vanillaCommand.getRedirect() == null) ? vanillaCommand.getName() : vanillaCommand.getRedirect().getName());
+ // Paper start - Vanilla command permission fixes
+ while (vanillaCommand.getRedirect() != null) {
+ vanillaCommand = vanillaCommand.getRedirect();
+ }
+ final String commandName = vanillaCommand.getName();
+ return "minecraft.command." + stripDefaultNamespace(commandName);
+ }
+
+ private static String stripDefaultNamespace(final String maybeNamespaced) {
+ final String prefix = "minecraft:";
+ if (maybeNamespaced.startsWith(prefix)) {
+ return maybeNamespaced.substring(prefix.length());
+ }
+ return maybeNamespaced;
+ // Paper end - Vanilla command permission fixes
}
private String toDispatcher(String[] args, String name) {