Some initial adoption of ValueInput/Output

This commit is contained in:
Bjarne Koll
2025-06-01 16:34:59 +02:00
parent 5933bd5bf3
commit 20136f71ca
19 changed files with 137 additions and 60 deletions

View File

@@ -439,6 +439,7 @@ public net.minecraft.world.entity.projectile.Arrow updateColor()V
public net.minecraft.world.entity.projectile.EvokerFangs warmupDelayTicks public net.minecraft.world.entity.projectile.EvokerFangs warmupDelayTicks
public net.minecraft.world.entity.projectile.EyeOfEnder life public net.minecraft.world.entity.projectile.EyeOfEnder life
public net.minecraft.world.entity.projectile.EyeOfEnder surviveAfterDeath public net.minecraft.world.entity.projectile.EyeOfEnder surviveAfterDeath
public net.minecraft.world.entity.projectile.EyeOfEnder target
public net.minecraft.world.entity.projectile.FireworkRocketEntity DATA_ATTACHED_TO_TARGET public net.minecraft.world.entity.projectile.FireworkRocketEntity DATA_ATTACHED_TO_TARGET
public net.minecraft.world.entity.projectile.FireworkRocketEntity DATA_ID_FIREWORKS_ITEM public net.minecraft.world.entity.projectile.FireworkRocketEntity DATA_ID_FIREWORKS_ITEM
public net.minecraft.world.entity.projectile.FireworkRocketEntity DATA_SHOT_AT_ANGLE public net.minecraft.world.entity.projectile.FireworkRocketEntity DATA_SHOT_AT_ANGLE
@@ -601,6 +602,7 @@ public net.minecraft.world.level.block.entity.BedBlockEntity color
public net.minecraft.world.level.block.entity.BeehiveBlockEntity savedFlowerPos public net.minecraft.world.level.block.entity.BeehiveBlockEntity savedFlowerPos
public net.minecraft.world.level.block.entity.BellBlockEntity resonating public net.minecraft.world.level.block.entity.BellBlockEntity resonating
public net.minecraft.world.level.block.entity.BellBlockEntity resonationTicks public net.minecraft.world.level.block.entity.BellBlockEntity resonationTicks
public net.minecraft.world.level.block.entity.BlockEntity saveId(Lnet/minecraft/world/level/storage/ValueOutput;)V
public net.minecraft.world.level.block.entity.BlockEntityType validBlocks public net.minecraft.world.level.block.entity.BlockEntityType validBlocks
public net.minecraft.world.level.block.entity.BrewingStandBlockEntity brewTime public net.minecraft.world.level.block.entity.BrewingStandBlockEntity brewTime
public net.minecraft.world.level.block.entity.BrewingStandBlockEntity fuel public net.minecraft.world.level.block.entity.BrewingStandBlockEntity fuel
@@ -612,9 +614,11 @@ public net.minecraft.world.level.block.entity.CampfireBlockEntity cookingTime
public net.minecraft.world.level.block.entity.ChestBlockEntity openersCounter public net.minecraft.world.level.block.entity.ChestBlockEntity openersCounter
public net.minecraft.world.level.block.entity.ChestBlockEntity playSound(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/sounds/SoundEvent;)V public net.minecraft.world.level.block.entity.ChestBlockEntity playSound(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/sounds/SoundEvent;)V
public net.minecraft.world.level.block.entity.ChiseledBookShelfBlockEntity lastInteractedSlot public net.minecraft.world.level.block.entity.ChiseledBookShelfBlockEntity lastInteractedSlot
public net.minecraft.world.level.block.entity.ConduitBlockEntity MIN_KILL_SIZE
public net.minecraft.world.level.block.entity.ConduitBlockEntity destroyTarget public net.minecraft.world.level.block.entity.ConduitBlockEntity destroyTarget
public net.minecraft.world.level.block.entity.ConduitBlockEntity effectBlocks public net.minecraft.world.level.block.entity.ConduitBlockEntity effectBlocks
public net.minecraft.world.level.block.entity.ConduitBlockEntity getDestroyRangeAABB(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/phys/AABB; public net.minecraft.world.level.block.entity.ConduitBlockEntity getDestroyRangeAABB(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/phys/AABB;
public net.minecraft.world.level.block.entity.ConduitBlockEntity updateDestroyTarget(Lnet/minecraft/world/entity/EntityReference;Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;Z)Lnet/minecraft/world/entity/EntityReference;
public net.minecraft.world.level.block.entity.CrafterBlockEntity craftingTicksRemaining public net.minecraft.world.level.block.entity.CrafterBlockEntity craftingTicksRemaining
public net.minecraft.world.level.block.entity.DecoratedPotBlockEntity decorations public net.minecraft.world.level.block.entity.DecoratedPotBlockEntity decorations
public net.minecraft.world.level.block.entity.EnderChestBlockEntity openersCounter public net.minecraft.world.level.block.entity.EnderChestBlockEntity openersCounter

View File

@@ -46,7 +46,6 @@ public final class MobGoalNames { // todo sync with MobGoalHelper ideally this s
bukkitMap.put(net.minecraft.world.entity.monster.Evoker.class, Evoker.class); bukkitMap.put(net.minecraft.world.entity.monster.Evoker.class, Evoker.class);
bukkitMap.put(net.minecraft.world.entity.animal.AbstractFish.class, Fish.class); bukkitMap.put(net.minecraft.world.entity.animal.AbstractFish.class, Fish.class);
bukkitMap.put(net.minecraft.world.entity.animal.AbstractSchoolingFish.class, SchoolableFish.class); bukkitMap.put(net.minecraft.world.entity.animal.AbstractSchoolingFish.class, SchoolableFish.class);
bukkitMap.put(net.minecraft.world.entity.FlyingMob.class, Flying.class);
bukkitMap.put(net.minecraft.world.entity.animal.Fox.class, Fox.class); bukkitMap.put(net.minecraft.world.entity.animal.Fox.class, Fox.class);
bukkitMap.put(net.minecraft.world.entity.monster.Ghast.class, Ghast.class); bukkitMap.put(net.minecraft.world.entity.monster.Ghast.class, Ghast.class);
bukkitMap.put(net.minecraft.world.entity.monster.Giant.class, Giant.class); bukkitMap.put(net.minecraft.world.entity.monster.Giant.class, Giant.class);

View File

@@ -721,7 +721,7 @@
public void saveWithoutId(ValueOutput output) { public void saveWithoutId(ValueOutput output) {
+ // CraftBukkit start - allow excluding certain data when saving + // CraftBukkit start - allow excluding certain data when saving
+ // Paper start - Raw entity serialization API + // Paper start - Raw entity serialization API
+ return this.saveWithoutId(output, true, false, false); + this.saveWithoutId(output, true, false, false);
+ } + }
+ +
+ public void saveWithoutId(ValueOutput output, boolean includeAll, boolean includeNonSaveable, boolean forceSerialization) { + public void saveWithoutId(ValueOutput output, boolean includeAll, boolean includeNonSaveable, boolean forceSerialization) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/ExperienceOrb.java --- a/net/minecraft/world/entity/ExperienceOrb.java
+++ b/net/minecraft/world/entity/ExperienceOrb.java +++ b/net/minecraft/world/entity/ExperienceOrb.java
@@ -44,13 +_,54 @@ @@ -44,13 +_,59 @@
@Nullable @Nullable
private Player followingPlayer; private Player followingPlayer;
private final InterpolationHandler interpolation = new InterpolationHandler(this); private final InterpolationHandler interpolation = new InterpolationHandler(this);
@@ -36,7 +36,13 @@
+ // Paper end + // Paper end
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - overload ctor + @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - overload ctor
public ExperienceOrb(Level level, double x, double y, double z, int value) { public ExperienceOrb(Level level, double x, double y, double z, int value) {
this(level, new Vec3(x, y, z), Vec3.ZERO, value); - this(level, new Vec3(x, y, z), Vec3.ZERO, value);
+ // Paper start - add reasons for orbs
+ this(level, x, y, z, value, null, null, null);
+ }
+ public ExperienceOrb(Level level, double x, double y, double z, int value, @Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @Nullable Entity triggerId, @Nullable Entity sourceId) {
+ this(level, new Vec3(x, y, z), Vec3.ZERO, value, reason, triggerId, sourceId);
+ // Paper end - add reasons for orbs
} }
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - overload ctor + @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - overload ctor

View File

@@ -71,7 +71,7 @@
+ // Paper end + // Paper end
} }
private void saveId(ValueOutput output) { public void saveId(ValueOutput output) {
@@ -287,6 +_,12 @@ @@ -287,6 +_,12 @@
} }

View File

@@ -36,7 +36,7 @@
+ // CraftBukkit start - add "damageTarget" boolean + // CraftBukkit start - add "damageTarget" boolean
+ updateAndAttackTarget(level, pos, state, blockEntity, canDestroy, true); + updateAndAttackTarget(level, pos, state, blockEntity, canDestroy, true);
+ } + }
+ private static void updateAndAttackTarget(ServerLevel level, BlockPos pos, BlockState state, ConduitBlockEntity blockEntity, boolean canDestroy, boolean damageTarget) { + public static void updateAndAttackTarget(ServerLevel level, BlockPos pos, BlockState state, ConduitBlockEntity blockEntity, boolean canDestroy, boolean damageTarget) {
+ // CraftBukkit end - add "damageTarget" boolean + // CraftBukkit end - add "damageTarget" boolean
EntityReference<LivingEntity> entityReference = updateDestroyTarget(blockEntity.destroyTarget, level, pos, canDestroy); EntityReference<LivingEntity> entityReference = updateDestroyTarget(blockEntity.destroyTarget, level, pos, canDestroy);
LivingEntity livingEntity = EntityReference.get(entityReference, level, LivingEntity.class); LivingEntity livingEntity = EntityReference.get(entityReference, level, LivingEntity.class);

View File

@@ -26,7 +26,7 @@
+ // Paper end - guard against serializing mismatching coordinates + // Paper end - guard against serializing mismatching coordinates
+ +
+ // Paper start - Do not let the server load chunks from newer versions + // Paper start - Do not let the server load chunks from newer versions
+ private static final int CURRENT_DATA_VERSION = net.minecraft.SharedConstants.getCurrentVersion().dataVersion().getVersion(); + private static final int CURRENT_DATA_VERSION = net.minecraft.SharedConstants.getCurrentVersion().dataVersion().version();
+ private static final boolean JUST_CORRUPT_IT = Boolean.getBoolean("Paper.ignoreWorldDataVersion"); + private static final boolean JUST_CORRUPT_IT = Boolean.getBoolean("Paper.ignoreWorldDataVersion");
+ // Paper end - Do not let the server load chunks from newer versions + // Paper end - Do not let the server load chunks from newer versions
+ +

View File

@@ -25,7 +25,7 @@
+ boolean result = levelAccessor.setBlock(pos, craftBlockEntityState.getHandle(), flags); + boolean result = levelAccessor.setBlock(pos, craftBlockEntityState.getHandle(), flags);
+ BlockEntity blockEntity = levelAccessor.getBlockEntity(pos); + BlockEntity blockEntity = levelAccessor.getBlockEntity(pos);
+ if (blockEntity != null) { + if (blockEntity != null) {
+ blockEntity.loadWithComponents(craftBlockEntityState.getSnapshotNBT(), levelAccessor.registryAccess()); + blockEntity.loadWithComponents(net.minecraft.world.level.storage.TagValueInput.createDiscarding(levelAccessor.registryAccess(), craftBlockEntityState.getSnapshotNBT()));
+ } + }
+ return result; + return result;
+ } + }

View File

@@ -0,0 +1,27 @@
--- a/net/minecraft/world/level/storage/TagValueOutput.java
+++ b/net/minecraft/world/level/storage/TagValueOutput.java
@@ -24,6 +_,24 @@
this.output = tag;
}
+ // Paper start - utility methods
+ public static TagValueOutput createDiscarding() {
+ return createWithoutContext(ProblemReporter.DISCARDING);
+ }
+
+ public static TagValueOutput createDiscardingWithContext(final HolderLookup.Provider lookup) {
+ return createWithContext(ProblemReporter.DISCARDING, lookup);
+ }
+
+ public static TagValueOutput createDiscarding(final CompoundTag wrapping) {
+ return new TagValueOutput(ProblemReporter.DISCARDING, NbtOps.INSTANCE, wrapping);
+ }
+
+ public static TagValueOutput createDiscardingWithContext(final CompoundTag wrapping, final HolderLookup.Provider lookup) {
+ return new TagValueOutput(ProblemReporter.DISCARDING, lookup.createSerializationContext(NbtOps.INSTANCE), wrapping);
+ }
+ // Paper end - utility methods
+
public static TagValueOutput createWithContext(ProblemReporter problemReporter, HolderLookup.Provider lookup) {
return new TagValueOutput(problemReporter, lookup.createSerializationContext(NbtOps.INSTANCE), new CompoundTag());
}

View File

@@ -11,6 +11,8 @@ import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.entity.BlockEntity; 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.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.TileState; import org.bukkit.block.TileState;
@@ -97,14 +99,14 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
// Loads the specified data into the snapshot BlockEntity. // Loads the specified data into the snapshot BlockEntity.
public void loadData(CompoundTag tag) { public void loadData(CompoundTag tag) {
this.snapshot.loadWithComponents(tag, this.getRegistryAccess()); this.snapshot.loadWithComponents(TagValueInput.createDiscarding(this.getRegistryAccess(), tag));
this.load(this.snapshot); this.load(this.snapshot);
} }
// copies the BlockEntity-specific data, retains the position // copies the BlockEntity-specific data, retains the position
private void copyData(T from, T to) { private void copyData(T from, T to) {
CompoundTag tag = from.saveWithFullMetadata(this.getRegistryAccess()); CompoundTag tag = from.saveWithFullMetadata(this.getRegistryAccess());
to.loadWithComponents(tag, this.getRegistryAccess()); to.loadWithComponents(TagValueInput.createDiscarding(this.getRegistryAccess(), tag));
} }
// gets the wrapped BlockEntity // gets the wrapped BlockEntity
@@ -143,13 +145,13 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
// Paper start - properly save blockentity itemstacks // Paper start - properly save blockentity itemstacks
public CompoundTag getSnapshotCustomNbtOnly() { public CompoundTag getSnapshotCustomNbtOnly() {
this.applyTo(this.snapshot); this.applyTo(this.snapshot);
final CompoundTag nbt = this.snapshot.saveCustomOnly(this.getRegistryAccess()); final TagValueOutput output = TagValueOutput.createDiscardingWithContext(this.snapshot.saveCustomOnly(this.getRegistryAccess()), this.getRegistryAccess());
this.snapshot.removeComponentsFromTag(nbt); this.snapshot.removeComponentsFromTag(output);
if (!nbt.isEmpty()) { if (!output.isEmpty()) {
// have to include the "id" if it's going to have block entity data // have to include the "id" if it's going to have block entity data
this.snapshot.saveId(nbt); this.snapshot.saveId(output);
} }
return nbt; return output.buildResult();
} }
// Paper end // Paper end

View File

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

View File

@@ -22,7 +22,7 @@ public class CraftEnderSignal extends CraftEntity implements EnderSignal {
@Override @Override
public Location getTargetLocation() { public Location getTargetLocation() {
return new Location(this.getWorld(), this.getHandle().tx, this.getHandle().ty, this.getHandle().tz, this.getHandle().getYRot(), this.getHandle().getXRot()); return CraftLocation.toBukkit(this.getHandle().target, this.getWorld(), this.getHandle().getYRot(), this.getHandle().getXRot());
} }
@Override @Override
@@ -35,7 +35,7 @@ public class CraftEnderSignal extends CraftEntity implements EnderSignal {
public void setTargetLocation(Location location, boolean update) { public void setTargetLocation(Location location, boolean update) {
// Paper end - Change EnderEye target without changing other things // Paper end - Change EnderEye target without changing other things
Preconditions.checkArgument(this.getWorld().equals(location.getWorld()), "Cannot target EnderSignal across worlds"); Preconditions.checkArgument(this.getWorld().equals(location.getWorld()), "Cannot target EnderSignal across worlds");
this.getHandle().signalTo(CraftLocation.toBlockPosition(location), update); // Paper - Change EnderEye target without changing other things this.getHandle().signalTo(CraftLocation.toVec3(location), update); // Paper - Change EnderEye target without changing other things
} }
@Override @Override

View File

@@ -30,6 +30,9 @@ import net.minecraft.world.entity.boss.EnderDragonPart;
import net.minecraft.world.entity.boss.enderdragon.EnderDragon; import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
import net.minecraft.world.entity.projectile.AbstractArrow; import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.level.portal.TeleportTransition; import net.minecraft.world.level.portal.TeleportTransition;
import net.minecraft.world.level.storage.TagValueOutput;
import net.minecraft.world.level.storage.ValueInput;
import net.minecraft.world.level.storage.ValueOutput;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import org.bukkit.EntityEffect; import org.bukkit.EntityEffect;
@@ -979,12 +982,12 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
@Override @Override
public String getAsString() { public String getAsString() {
CompoundTag tag = new CompoundTag(); final TagValueOutput output = TagValueOutput.createDiscardingWithContext(this.getHandle().registryAccess());
if (!this.getHandle().saveAsPassenger(tag, false, true, true)) { if (!this.getHandle().saveAsPassenger(output, false, true, true)) {
return null; return null;
} }
return tag.toString(); return output.buildResult().toString();
} }
@Override @Override
@@ -1012,32 +1015,29 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
} }
private Entity copy(net.minecraft.world.level.Level level) { private Entity copy(net.minecraft.world.level.Level level) {
CompoundTag compoundTag = new CompoundTag(); final TagValueOutput output = TagValueOutput.createDiscardingWithContext(level.registryAccess());
this.getHandle().saveAsPassenger(compoundTag, false, true, true); this.getHandle().saveAsPassenger(output, false, true, true);
return net.minecraft.world.entity.EntityType.loadEntityRecursive(compoundTag, level, EntitySpawnReason.LOAD, java.util.function.Function.identity()); return net.minecraft.world.entity.EntityType.loadEntityRecursive(output.buildResult(), level, EntitySpawnReason.LOAD, java.util.function.Function.identity());
} }
public void storeBukkitValues(CompoundTag c) { public void storeBukkitValues(ValueOutput c) {
if (!this.persistentDataContainer.isEmpty()) { if (!this.persistentDataContainer.isEmpty()) {
c.put("BukkitValues", this.persistentDataContainer.toTagCompound()); c.store("BukkitValues", CompoundTag.CODEC, this.persistentDataContainer.toTagCompound());
} }
} }
public void readBukkitValues(CompoundTag c) { public void readBukkitValues(ValueInput c) {
Tag base = c.get("BukkitValues"); c.read("BukkitValues", CompoundTag.CODEC).ifPresent(this.persistentDataContainer::putAll);
if (base instanceof CompoundTag) {
this.persistentDataContainer.putAll((CompoundTag) base);
}
} }
protected CompoundTag save() { protected CompoundTag save() {
CompoundTag tag = new CompoundTag(); final TagValueOutput tagValueOutput = TagValueOutput.createDiscardingWithContext(this.getHandle().registryAccess());
tag.putString(Entity.ID_TAG, this.getHandle().getEncodeId()); // todo NPE? tagValueOutput.putString(Entity.TAG_ID, this.getHandle().getEncodeId()); // todo NPE?
this.getHandle().saveWithoutId(tag); this.getHandle().saveWithoutId(tagValueOutput);
return tag; return tagValueOutput.buildResult();
} }
// re-sends the spawn entity packet to updated values which cannot be updated otherwise // re-sends the spawn entity packet to updated values which cannot be updated otherwise

View File

@@ -5,6 +5,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.TagParser; import net.minecraft.nbt.TagParser;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.storage.TagValueInput;
import org.bukkit.entity.EntityFactory; import org.bukkit.entity.EntityFactory;
import org.bukkit.entity.EntitySnapshot; import org.bukkit.entity.EntitySnapshot;
@@ -30,7 +31,7 @@ public class CraftEntityFactory implements EntityFactory {
throw new IllegalArgumentException("Could not parse Entity: " + input, e); throw new IllegalArgumentException("Could not parse Entity: " + input, e);
} }
EntityType<?> type = EntityType.by(tag).orElse(null); EntityType<?> type = EntityType.by(TagValueInput.createGlobalDiscarding(tag)).orElse(null);
if (type == null) { if (type == null) {
throw new IllegalArgumentException("Could not parse Entity: " + input); throw new IllegalArgumentException("Could not parse Entity: " + input);
} }

View File

@@ -106,6 +106,7 @@ import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerGamePacketListenerImpl; import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.server.players.UserWhiteListEntry; import net.minecraft.server.players.UserWhiteListEntry;
import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvent;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.ai.attributes.AttributeInstance; import net.minecraft.world.entity.ai.attributes.AttributeInstance;
import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.ai.attributes.Attributes;
@@ -1532,7 +1533,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override @Override
public void loadData() { public void loadData() {
this.server.getHandle().playerIo.load(this.getHandle()); this.server.getHandle().playerIo.load(this.getHandle(), ProblemReporter.DISCARDING);
} }
@Override @Override

View File

@@ -17,6 +17,7 @@ import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ProtoChunk; import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.chunk.status.ChunkStatus; import net.minecraft.world.level.chunk.status.ChunkStatus;
import net.minecraft.world.level.storage.TagValueInput;
import org.bukkit.HeightMap; import org.bukkit.HeightMap;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@@ -271,7 +272,9 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe
if (!state.getBlockData().matches(getHandle().getBlockState(pos).createCraftBlockData())) { if (!state.getBlockData().matches(getHandle().getBlockState(pos).createCraftBlockData())) {
throw new IllegalArgumentException("BlockData does not match! Expected " + state.getBlockData().getAsString(false) + ", got " + getHandle().getBlockState(pos).createCraftBlockData().getAsString(false)); throw new IllegalArgumentException("BlockData does not match! Expected " + state.getBlockData().getAsString(false) + ", got " + getHandle().getBlockState(pos).createCraftBlockData().getAsString(false));
} }
getHandle().getBlockEntity(pos).loadWithComponents(((org.bukkit.craftbukkit.block.CraftBlockEntityState<?>) state).getSnapshotNBT(), this.getHandle().registryAccess()); getHandle().getBlockEntity(pos).loadWithComponents(TagValueInput.createDiscarding(
this.getHandle().registryAccess(), ((org.bukkit.craftbukkit.block.CraftBlockEntityState<?>) state).getSnapshotNBT()
));
} }
@Override @Override

View File

@@ -17,8 +17,10 @@ import net.minecraft.core.component.TypedDataComponent;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.item.component.CustomData; import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.storage.TagValueOutput;
import org.bukkit.DyeColor; import org.bukkit.DyeColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
@@ -144,12 +146,13 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta
final BlockVector legacyPosition = SerializableMeta.getObject(BlockVector.class, map, "blockPosition", true); final BlockVector legacyPosition = SerializableMeta.getObject(BlockVector.class, map, "blockPosition", true);
if (legacyPosition != null) { if (legacyPosition != null) {
this.blockEntityTag = this.blockEntityTag.update(blockEntityTag -> { this.blockEntityTag = this.blockEntityTag.update(blockEntityTag -> {
final TagValueOutput output = TagValueOutput.createDiscardingWithContext(blockEntityTag, CraftRegistry.getMinecraftRegistry());
if (blockEntityTag.isEmpty()) { if (blockEntityTag.isEmpty()) {
BlockEntity.addEntityType(blockEntityTag, java.util.Objects.requireNonNull(CraftBlockStates.getBlockEntityType(this.materialForBlockEntityType()))); BlockEntity.addEntityType(output, java.util.Objects.requireNonNull(CraftBlockStates.getBlockEntityType(this.materialForBlockEntityType())));
} }
blockEntityTag.putInt("x", legacyPosition.getBlockX()); output.putInt("x", legacyPosition.getBlockX());
blockEntityTag.putInt("y", legacyPosition.getBlockY()); output.putInt("y", legacyPosition.getBlockY());
blockEntityTag.putInt("z", legacyPosition.getBlockZ()); output.putInt("z", legacyPosition.getBlockZ());
}); });
} }
// Paper end - general item meta fixes - parse spigot legacy position and merge into block entity tag // Paper end - general item meta fixes - parse spigot legacy position and merge into block entity tag
@@ -164,7 +167,7 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta
final CompoundTag nbt = this.blockEntityTag.copyTag(); final CompoundTag nbt = this.blockEntityTag.copyTag();
if (!nbt.isEmpty()) { if (!nbt.isEmpty()) {
if (nbt.getString("id").isEmpty()) { if (nbt.getString("id").isEmpty()) {
BlockEntity.addEntityType(nbt, java.util.Objects.requireNonNull(CraftBlockStates.getBlockEntityType(this.materialForBlockEntityType()))); BlockEntity.addEntityType(TagValueOutput.createDiscardingWithContext(nbt, CraftRegistry.getMinecraftRegistry()), java.util.Objects.requireNonNull(CraftBlockStates.getBlockEntityType(this.materialForBlockEntityType())));
} }
tag.put(CraftMetaBlockState.BLOCK_ENTITY_TAG, CustomData.of(nbt)); tag.put(CraftMetaBlockState.BLOCK_ENTITY_TAG, CustomData.of(nbt));
} }

View File

@@ -50,6 +50,7 @@ import net.minecraft.world.item.alchemy.Potion;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.storage.LevelResource; import net.minecraft.world.level.storage.LevelResource;
import net.minecraft.world.level.storage.TagValueOutput;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Keyed; import org.bukkit.Keyed;
import org.bukkit.Material; import org.bukkit.Material;
@@ -280,7 +281,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
@Override @Override
public int getDataVersion() { public int getDataVersion() {
return SharedConstants.getCurrentVersion().getDataVersion().getVersion(); return SharedConstants.getCurrentVersion().dataVersion().getVersion();
} }
@Override @Override
@@ -492,8 +493,14 @@ public final class CraftMagicNumbers implements UnsafeValues {
public byte[] serializeItem(ItemStack item) { public byte[] serializeItem(ItemStack item) {
Preconditions.checkNotNull(item, "null cannot be serialized"); Preconditions.checkNotNull(item, "null cannot be serialized");
Preconditions.checkArgument(item.getType() != Material.AIR, "air cannot be serialized"); Preconditions.checkArgument(item.getType() != Material.AIR, "air cannot be serialized");
Preconditions.checkArgument(!item.isEmpty(), "Empty itemstack cannot be serialised");
return serializeNbtToBytes((CompoundTag) (item instanceof CraftItemStack ? ((CraftItemStack) item).handle : CraftItemStack.asNMSCopy(item)).save(MinecraftServer.getServer().registryAccess())); return serializeNbtToBytes(
(CompoundTag) net.minecraft.world.item.ItemStack.CODEC.encodeStart(
MinecraftServer.getServer().registryAccess().createSerializationContext(NbtOps.INSTANCE),
CraftItemStack.unwrap(item)
).getOrThrow()
);
} }
@Override @Override
@@ -511,7 +518,9 @@ public final class CraftMagicNumbers implements UnsafeValues {
if (compound.getStringOr("id", "minecraft:air").equals("minecraft:air")) { if (compound.getStringOr("id", "minecraft:air").equals("minecraft:air")) {
return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.EMPTY); return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.EMPTY);
} }
return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.parse(CraftRegistry.getMinecraftRegistry(), compound).orElseThrow()); return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.CODEC.parse(
MinecraftServer.getServer().registryAccess().createSerializationContext(NbtOps.INSTANCE), compound
).getOrThrow());
} }
@Override @Override
@@ -519,7 +528,10 @@ public final class CraftMagicNumbers implements UnsafeValues {
if (itemStack.isEmpty()) { if (itemStack.isEmpty()) {
return Map.of("id", "minecraft:air", SharedConstants.DATA_VERSION_TAG, this.getDataVersion(), "schema_version", 1); return Map.of("id", "minecraft:air", SharedConstants.DATA_VERSION_TAG, this.getDataVersion(), "schema_version", 1);
} }
final CompoundTag tag = CraftItemStack.asNMSCopy(itemStack).save(CraftRegistry.getMinecraftRegistry()).asCompound().orElseThrow(); final CompoundTag tag = (CompoundTag) net.minecraft.world.item.ItemStack.CODEC.encodeStart(
CraftRegistry.getMinecraftRegistry().createSerializationContext(NbtOps.INSTANCE),
CraftItemStack.asNMSCopy(itemStack)
).getOrThrow();
NbtUtils.addCurrentDataVersion(tag); NbtUtils.addCurrentDataVersion(tag);
final Map<String, Object> ret = new LinkedHashMap<>(); final Map<String, Object> ret = new LinkedHashMap<>();
@@ -677,21 +689,21 @@ public final class CraftMagicNumbers implements UnsafeValues {
} }
}); });
CompoundTag compound = new CompoundTag(); final TagValueOutput output = TagValueOutput.createDiscardingWithContext(nmsEntity.registryAccess());
if (serializePassangers) { if (serializePassangers) {
if (!nmsEntity.saveAsPassenger(compound, true, includeNonSaveable, forceSerialization)) { if (!nmsEntity.saveAsPassenger(output, true, includeNonSaveable, forceSerialization)) {
throw new IllegalArgumentException("Couldn't serialize entity"); throw new IllegalArgumentException("Couldn't serialize entity");
} }
} else { } else {
List<net.minecraft.world.entity.Entity> pass = new ArrayList<>(nmsEntity.getPassengers()); List<net.minecraft.world.entity.Entity> pass = new ArrayList<>(nmsEntity.getPassengers());
nmsEntity.passengers = com.google.common.collect.ImmutableList.of(); nmsEntity.passengers = com.google.common.collect.ImmutableList.of();
boolean serialized = nmsEntity.saveAsPassenger(compound, true, includeNonSaveable, forceSerialization); boolean serialized = nmsEntity.saveAsPassenger(output, true, includeNonSaveable, forceSerialization);
nmsEntity.passengers = com.google.common.collect.ImmutableList.copyOf(pass); nmsEntity.passengers = com.google.common.collect.ImmutableList.copyOf(pass);
if (!serialized) { if (!serialized) {
throw new IllegalArgumentException("Couldn't serialize entity"); throw new IllegalArgumentException("Couldn't serialize entity");
} }
} }
return serializeNbtToBytes(compound); return serializeNbtToBytes(output.buildResult());
} }
@Override @Override
@@ -768,7 +780,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
@Override @Override
public int getProtocolVersion() { public int getProtocolVersion() {
return net.minecraft.SharedConstants.getCurrentVersion().getProtocolVersion(); return net.minecraft.SharedConstants.getCurrentVersion().protocolVersion();
} }
@Override @Override

View File

@@ -7,6 +7,7 @@ import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.structure.StructurePiece; import net.minecraft.world.level.levelgen.structure.StructurePiece;
import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.storage.TagValueInput;
import org.bukkit.craftbukkit.block.CraftBlockEntityState; import org.bukkit.craftbukkit.block.CraftBlockEntityState;
import org.bukkit.craftbukkit.block.CraftBlockState; import org.bukkit.craftbukkit.block.CraftBlockState;
import org.bukkit.craftbukkit.block.CraftBlockStates; import org.bukkit.craftbukkit.block.CraftBlockStates;
@@ -60,7 +61,9 @@ public class TransformerGeneratorAccess extends DelegatedGeneratorAccess {
} }
BlockEntity blockEntity = this.getBlockEntity(position); BlockEntity blockEntity = this.getBlockEntity(position);
if (blockEntity != null && craftBlockState instanceof CraftBlockEntityState<?> craftEntityState) { if (blockEntity != null && craftBlockState instanceof CraftBlockEntityState<?> craftEntityState) {
blockEntity.loadWithComponents(craftEntityState.getSnapshotNBT(), this.registryAccess()); blockEntity.loadWithComponents(TagValueInput.createDiscarding(
this.registryAccess(), craftEntityState.getSnapshotNBT()
));
} }
return result; return result;
} }