1.21.6 dev

Co-authored-by: Bjarne Koll <git@lynxplay.dev>
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
Co-authored-by: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
Co-authored-by: Noah van der Aa <ndvdaa@gmail.com>
Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
This commit is contained in:
Bjarne Koll
2025-05-28 13:23:32 +02:00
committed by Nassim Jahnke
parent 39203a65e0
commit a24f9b204c
788 changed files with 41006 additions and 6324 deletions

View File

@@ -40,10 +40,7 @@ public final class CapturedBlockState extends CraftBlockState {
@Override
public boolean place(int flags) {
boolean result = super.place(flags);
if (result) {
this.addBees();
}
this.addBees();
return result;
}

View File

@@ -7,7 +7,6 @@ import org.bukkit.NamespacedKey;
import org.bukkit.block.Biome;
import org.bukkit.craftbukkit.CraftRegistry;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
import java.util.Objects;
@@ -61,17 +60,17 @@ public class CraftBiome extends OldEnumHolderable<Biome, net.minecraft.world.lev
}
@Override
public @NotNull NamespacedKey getKey() {
public NamespacedKey getKey() {
return LEGACY_CUSTOM_KEY;
}
@Override
public int compareTo(@NotNull final Biome other) {
public int compareTo(final Biome other) {
return this.ordinal - other.ordinal();
}
@Override
public @NotNull String name() {
public String name() {
return "CUSTOM";
}

View File

@@ -1,6 +1,7 @@
package org.bukkit.craftbukkit.block;
import java.util.Set;
import com.mojang.logging.LogUtils;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.component.DataComponentMap;
import net.minecraft.core.component.DataComponentPatch;
@@ -9,8 +10,11 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.storage.TagValueInput;
import net.minecraft.world.level.storage.TagValueOutput;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.TileState;
@@ -19,9 +23,12 @@ import org.bukkit.craftbukkit.util.CraftLocation;
import org.bukkit.persistence.PersistentDataContainer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
public abstract class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockState implements TileState { // Paper - revert upstream's revert of the block state changes
private static final Logger LOGGER = LogUtils.getLogger();
private final T blockEntity;
private final T snapshot;
public boolean snapshotDisabled; // Paper
@@ -67,10 +74,6 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
this.loadData(state.getSnapshotNBT());
}
public void refreshSnapshot() {
this.load(this.blockEntity);
}
private RegistryAccess getRegistryAccess() {
LevelAccessor worldHandle = this.getWorldHandle();
return (worldHandle != null) ? worldHandle.registryAccess() : CraftRegistry.getMinecraftRegistry();
@@ -97,14 +100,22 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
// Loads the specified data into the snapshot BlockEntity.
public void loadData(CompoundTag tag) {
this.snapshot.loadWithComponents(tag, this.getRegistryAccess());
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
() -> "CraftBlockEntityState@" + getPosition().toShortString(), LOGGER
)) {
this.snapshot.loadWithComponents(TagValueInput.create(problemReporter, this.getRegistryAccess(), tag));
}
this.load(this.snapshot);
}
// copies the BlockEntity-specific data, retains the position
private void copyData(T from, T to) {
CompoundTag tag = from.saveWithFullMetadata(this.getRegistryAccess());
to.loadWithComponents(tag, this.getRegistryAccess());
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
() -> "CraftBlockEntityState@" + getPosition().toShortString(), LOGGER
)) {
to.loadWithComponents(TagValueInput.create(problemReporter, this.getRegistryAccess(), tag));
}
}
// gets the wrapped BlockEntity
@@ -143,13 +154,21 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
// Paper start - properly save blockentity itemstacks
public CompoundTag getSnapshotCustomNbtOnly() {
this.applyTo(this.snapshot);
final CompoundTag nbt = this.snapshot.saveCustomOnly(this.getRegistryAccess());
this.snapshot.removeComponentsFromTag(nbt);
if (!nbt.isEmpty()) {
// have to include the "id" if it's going to have block entity data
this.snapshot.saveId(nbt);
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
() -> "CraftBlockEntityState@" + getPosition().toShortString(), LOGGER
)) {
final TagValueOutput output = TagValueOutput.createWrappingWithContext(
problemReporter,
this.getRegistryAccess(),
this.snapshot.saveCustomOnly(this.getRegistryAccess())
);
this.snapshot.removeComponentsFromTag(output);
if (!output.isEmpty()) {
// have to include the "id" if it's going to have block entity data
this.snapshot.saveId(output);
}
return output.buildResult();
}
return nbt;
}
// Paper end
@@ -183,15 +202,14 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
@Override
public boolean place(int flags) {
if (super.place(flags)) {
this.getWorldHandle().getBlockEntity(this.getPosition(), this.blockEntity.getType()).ifPresent(blockEntity -> {
this.applyTo((T) blockEntity);
blockEntity.setChanged();
});
return true;
}
boolean result = super.place(flags);
return false;
this.getWorldHandle().getBlockEntity(this.getPosition(), this.blockEntity.getType()).ifPresent(blockEntity -> {
this.applyTo((T) blockEntity);
blockEntity.setChanged();
});
return result;
}
@Override

View File

@@ -85,7 +85,7 @@ public final class CraftBlockStates {
static {
// Start generate - CraftBlockEntityStates
// @GeneratedFrom 1.21.5
// @GeneratedFrom 1.21.6-rc1
register(BlockEntityType.BANNER, CraftBanner.class, CraftBanner::new);
register(BlockEntityType.BARREL, CraftBarrel.class, CraftBarrel::new);
register(BlockEntityType.BEACON, CraftBeacon.class, CraftBeacon::new);

View File

@@ -2,7 +2,9 @@ package org.bukkit.craftbukkit.block;
import java.util.ArrayList;
import java.util.Collection;
import net.minecraft.Optionull;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.EntityReference;
import net.minecraft.world.level.block.entity.ConduitBlockEntity;
import net.minecraft.world.phys.AABB;
import org.bukkit.Location;
@@ -83,7 +85,7 @@ public class CraftConduit extends CraftBlockEntityState<ConduitBlockEntity> impl
return false;
}
net.minecraft.world.entity.LivingEntity currentTarget = conduit.destroyTarget;
EntityReference<net.minecraft.world.entity.LivingEntity> currentTarget = conduit.destroyTarget;
if (target == null) {
if (currentTarget == null) {
@@ -91,17 +93,22 @@ public class CraftConduit extends CraftBlockEntityState<ConduitBlockEntity> impl
}
conduit.destroyTarget = null;
conduit.destroyTargetUUID = null;
} else {
if (currentTarget != null && target.getUniqueId().equals(currentTarget.getUUID())) {
return false;
}
conduit.destroyTarget = ((CraftLivingEntity) target).getHandle();
conduit.destroyTargetUUID = target.getUniqueId();
conduit.destroyTarget = new EntityReference<>(((CraftLivingEntity) target).getHandle());
}
ConduitBlockEntity.updateDestroyTarget(conduit.getLevel(), this.getPosition(), this.data, conduit.effectBlocks, conduit, false);
ConduitBlockEntity.updateAndAttackTarget(
conduit.getLevel().getMinecraftWorld(),
this.getPosition(),
this.data,
conduit,
conduit.effectBlocks.size() >= ConduitBlockEntity.MIN_KILL_SIZE,
false
);
return true;
}
@@ -112,14 +119,17 @@ public class CraftConduit extends CraftBlockEntityState<ConduitBlockEntity> impl
return null;
}
net.minecraft.world.entity.LivingEntity nmsEntity = conduit.destroyTarget;
return (nmsEntity != null) ? (LivingEntity) nmsEntity.getBukkitEntity() : null;
final net.minecraft.world.entity.LivingEntity nmsEntity = EntityReference.get(conduit.destroyTarget, this.getWorldHandle().getMinecraftWorld(), net.minecraft.world.entity.LivingEntity.class);
return nmsEntity == null ? null : nmsEntity.getBukkitLivingEntity();
}
@Override
public boolean hasTarget() {
ConduitBlockEntity conduit = (ConduitBlockEntity) this.getBlockEntityFromWorld();
return conduit != null && conduit.destroyTarget != null && conduit.destroyTarget.isAlive();
if (conduit == null) return false;
final net.minecraft.world.entity.LivingEntity destroyTarget = EntityReference.get(conduit.destroyTarget, this.getWorldHandle().getMinecraftWorld(), net.minecraft.world.entity.LivingEntity.class);
return destroyTarget != null && destroyTarget.isAlive();
}
@Override

View File

@@ -8,8 +8,10 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import net.minecraft.core.RegistryAccess;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.InclusiveRange;
import net.minecraft.util.ProblemReporter;
import net.minecraft.util.RandomSource;
import net.minecraft.util.random.Weighted;
import net.minecraft.util.random.WeightedList;
@@ -17,6 +19,8 @@ import net.minecraft.world.entity.EquipmentTable;
import net.minecraft.world.level.BaseSpawner;
import net.minecraft.world.level.SpawnData;
import net.minecraft.world.level.block.entity.SpawnerBlockEntity;
import net.minecraft.world.level.storage.TagValueInput;
import net.minecraft.world.level.storage.ValueInput;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.CreatureSpawner;
@@ -46,8 +50,11 @@ public class CraftCreatureSpawner extends CraftBlockEntityState<SpawnerBlockEnti
return null;
}
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(spawnData.getEntityToSpawn());
return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(() -> "spawner@" + getLocation(), LOGGER)) {
ValueInput valueInput = TagValueInput.create(scopedCollector, this.getInternalWorld().registryAccess(), spawnData.entityToSpawn());
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(valueInput);
return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
}
}
@Override
@@ -175,9 +182,12 @@ public class CraftCreatureSpawner extends CraftBlockEntityState<SpawnerBlockEnti
if (spawnData == null) {
return null;
}
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(() -> "spawner@" + getLocation(), LOGGER)) {
ValueInput valueInput = TagValueInput.create(scopedCollector, this.getInternalWorld().registryAccess(), spawnData.getEntityToSpawn());
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(valueInput);
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(spawnData.getEntityToSpawn());
return type.map(CraftEntityType::minecraftToBukkit).map(CraftEntityType::bukkitToString).orElse(null);
return type.map(CraftEntityType::minecraftToBukkit).map(CraftEntityType::bukkitToString).orElse(null);
}
}
@Override

View File

@@ -46,8 +46,8 @@ public abstract class CraftFurnace<T extends AbstractFurnaceBlockEntity> extends
@Override
public void setBurnTime(short burnTime) {
this.getSnapshot().litTimeRemaining = burnTime;
// SPIGOT-844: Allow lighting and relighting using this API
this.data = this.data.setValue(AbstractFurnaceBlock.LIT, burnTime > 0);
this.data = this.data.trySetValue(AbstractFurnaceBlock.LIT, burnTime > 0);
// only try, block data might have changed to something different that would not allow this property
}
@Override

View File

@@ -7,7 +7,7 @@ import java.util.UUID;
import net.minecraft.core.Holder;
import net.minecraft.world.level.block.TrialSpawnerBlock;
import net.minecraft.world.level.block.entity.TrialSpawnerBlockEntity;
import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData;
import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerStateData;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
@@ -23,8 +23,8 @@ public class CraftTrialSpawner extends CraftBlockEntityState<TrialSpawnerBlockEn
public CraftTrialSpawner(World world, TrialSpawnerBlockEntity blockEntity) {
super(world, blockEntity);
this.normalConfig = new CraftTrialSpawnerConfiguration(blockEntity.getTrialSpawner().getNormalConfig(), this.getSnapshot());
this.ominousConfig = new CraftTrialSpawnerConfiguration(blockEntity.getTrialSpawner().getOminousConfig(), this.getSnapshot());
this.normalConfig = new CraftTrialSpawnerConfiguration(blockEntity.getTrialSpawner().normalConfig(), this.getSnapshot());
this.ominousConfig = new CraftTrialSpawnerConfiguration(blockEntity.getTrialSpawner().ominousConfig(), this.getSnapshot());
}
protected CraftTrialSpawner(CraftTrialSpawner state, Location location) {
@@ -35,22 +35,22 @@ public class CraftTrialSpawner extends CraftBlockEntityState<TrialSpawnerBlockEn
@Override
public long getCooldownEnd() {
return this.getSnapshot().trialSpawner.getData().cooldownEndsAt;
return this.getSnapshot().trialSpawner.getStateData().cooldownEndsAt;
}
@Override
public void setCooldownEnd(long ticks) {
this.getSnapshot().trialSpawner.getData().cooldownEndsAt = ticks;
this.getSnapshot().trialSpawner.getStateData().cooldownEndsAt = ticks;
}
@Override
public long getNextSpawnAttempt() {
return this.getSnapshot().trialSpawner.getData().nextMobSpawnsAt;
return this.getSnapshot().trialSpawner.getStateData().nextMobSpawnsAt;
}
@Override
public void setNextSpawnAttempt(long ticks) {
this.getSnapshot().trialSpawner.getData().nextMobSpawnsAt = ticks;
this.getSnapshot().trialSpawner.getStateData().nextMobSpawnsAt = ticks;
}
@Override
@@ -60,17 +60,17 @@ public class CraftTrialSpawner extends CraftBlockEntityState<TrialSpawnerBlockEn
@Override
public void setCooldownLength(int ticks) {
this.getSnapshot().trialSpawner.targetCooldownLength = ticks;
this.getSnapshot().trialSpawner.config = this.getSnapshot().trialSpawner.config.overrideTargetCooldownLength(ticks);
}
@Override
public int getRequiredPlayerRange() {
return this.getSnapshot().trialSpawner.getRequiredPlayerRange();
return this.getSnapshot().trialSpawner.getRequiredPlayerRange();
}
@Override
public void setRequiredPlayerRange(int requiredPlayerRange) {
this.getSnapshot().trialSpawner.requiredPlayerRange = requiredPlayerRange;
this.getSnapshot().trialSpawner.config = this.getSnapshot().trialSpawner.config.overrideRequiredPlayerRange(requiredPlayerRange);
}
@Override
@@ -160,24 +160,26 @@ public class CraftTrialSpawner extends CraftBlockEntityState<TrialSpawnerBlockEn
@Override
public TrialSpawnerConfiguration getNormalConfiguration() {
return this.normalConfig;
return this.normalConfig;
}
@Override
public TrialSpawnerConfiguration getOminousConfiguration() {
return this.ominousConfig;
return this.ominousConfig;
}
@Override
protected void applyTo(TrialSpawnerBlockEntity blockEntity) {
super.applyTo(blockEntity);
blockEntity.trialSpawner.normalConfig = Holder.direct(this.normalConfig.toMinecraft());
blockEntity.trialSpawner.ominousConfig = Holder.direct(this.ominousConfig.toMinecraft());
blockEntity.trialSpawner.config = blockEntity.trialSpawner.config.overrideConfigs(
Holder.direct(this.normalConfig.toMinecraft()),
Holder.direct(this.ominousConfig.toMinecraft())
);
}
private TrialSpawnerData getTrialData() {
return this.getSnapshot().getTrialSpawner().getData();
private TrialSpawnerStateData getTrialData() {
return this.getSnapshot().getTrialSpawner().getStateData();
}
@Override

View File

@@ -7,16 +7,20 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import com.mojang.logging.LogUtils;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceKey;
import net.minecraft.util.ProblemReporter;
import net.minecraft.util.random.Weighted;
import net.minecraft.util.random.WeightedList;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.SpawnData;
import net.minecraft.world.level.block.entity.TrialSpawnerBlockEntity;
import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerConfig;
import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData;
import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerStateData;
import net.minecraft.world.level.storage.TagValueInput;
import net.minecraft.world.level.storage.TagValueOutput;
import org.bukkit.block.spawner.SpawnRule;
import org.bukkit.block.spawner.SpawnerEntry;
import org.bukkit.craftbukkit.CraftLootTable;
@@ -26,8 +30,12 @@ import org.bukkit.entity.EntitySnapshot;
import org.bukkit.entity.EntityType;
import org.bukkit.loot.LootTable;
import org.bukkit.spawner.TrialSpawnerConfiguration;
import org.slf4j.Logger;
public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration {
private static final Logger LOGGER = LogUtils.getLogger();
private final TrialSpawnerBlockEntity snapshot;
private int spawnRange;
@@ -56,12 +64,21 @@ public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration
@Override
public EntityType getSpawnedType() {
if (this.spawnPotentialsDefinition.isEmpty()) {
return null;
}
if (this.spawnPotentialsDefinition.isEmpty()) {
return null;
}
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(this.spawnPotentialsDefinition.unwrap().get(0).value().getEntityToSpawn());
return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
() -> "TrialSpawnerConfiguration@" + snapshot.getBlockPos().toShortString(), LOGGER
)) {
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(
TagValueInput.createGlobal(
problemReporter,
this.spawnPotentialsDefinition.unwrap().getFirst().value().getEntityToSpawn()
)
);
return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
}
}
@Override
@@ -74,7 +91,7 @@ public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration
Preconditions.checkArgument(entityType != EntityType.UNKNOWN, "Can't spawn EntityType %s from mob spawners!", entityType);
SpawnData data = new SpawnData();
data.getEntityToSpawn().putString(Entity.ID_TAG, BuiltInRegistries.ENTITY_TYPE.getKey(CraftEntityType.bukkitToMinecraft(entityType)).toString());
data.getEntityToSpawn().putString(Entity.TAG_ID, BuiltInRegistries.ENTITY_TYPE.getKey(CraftEntityType.bukkitToMinecraft(entityType)).toString());
this.getTrialData().nextSpawnData = Optional.of(data);
this.spawnPotentialsDefinition = WeightedList.of(data);
}
@@ -121,7 +138,7 @@ public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration
@Override
public int getDelay() {
return this.ticksBetweenSpawn;
return this.ticksBetweenSpawn;
}
@Override
@@ -287,16 +304,16 @@ public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration
@Override
public int getRequiredPlayerRange() {
return this.snapshot.trialSpawner.getRequiredPlayerRange();
return this.snapshot.trialSpawner.getRequiredPlayerRange();
}
@Override
public void setRequiredPlayerRange(int requiredPlayerRange) {
this.snapshot.trialSpawner.requiredPlayerRange = requiredPlayerRange;
this.snapshot.trialSpawner.config = this.snapshot.trialSpawner.config.overrideRequiredPlayerRange(requiredPlayerRange);
}
private TrialSpawnerData getTrialData() {
return this.snapshot.getTrialSpawner().getData();
private TrialSpawnerStateData getTrialData() {
return this.snapshot.getTrialSpawner().getStateData();
}
protected TrialSpawnerConfig toMinecraft() {

View File

@@ -362,7 +362,7 @@ public class CraftBlockData implements BlockData {
static {
//<editor-fold desc="CraftBlockData Registration" defaultstate="collapsed">
// Start generate - CraftBlockData#MAP
// @GeneratedFrom 1.21.5
// @GeneratedFrom 1.21.6-rc1
register(net.minecraft.world.level.block.AmethystClusterBlock.class, org.bukkit.craftbukkit.block.impl.CraftAmethystCluster::new);
register(net.minecraft.world.level.block.AnvilBlock.class, org.bukkit.craftbukkit.block.impl.CraftAnvil::new);
register(net.minecraft.world.level.block.AttachedStemBlock.class, org.bukkit.craftbukkit.block.impl.CraftAttachedStem::new);
@@ -418,6 +418,7 @@ public class CraftBlockData implements BlockData {
register(net.minecraft.world.level.block.DispenserBlock.class, org.bukkit.craftbukkit.block.impl.CraftDispenser::new);
register(net.minecraft.world.level.block.DoorBlock.class, org.bukkit.craftbukkit.block.impl.CraftDoor::new);
register(net.minecraft.world.level.block.DoublePlantBlock.class, org.bukkit.craftbukkit.block.impl.CraftDoublePlant::new);
register(net.minecraft.world.level.block.DriedGhastBlock.class, org.bukkit.craftbukkit.block.impl.CraftDriedGhast::new);
register(net.minecraft.world.level.block.DropperBlock.class, org.bukkit.craftbukkit.block.impl.CraftDropper::new);
register(net.minecraft.world.level.block.EndPortalFrameBlock.class, org.bukkit.craftbukkit.block.impl.CraftEndPortalFrame::new);
register(net.minecraft.world.level.block.EndRodBlock.class, org.bukkit.craftbukkit.block.impl.CraftEndRod::new);