diff --git a/purpur-server/minecraft-patches/features/0001-Ridables.patch b/purpur-server/minecraft-patches/features/0001-Ridables.patch index 4703d4bed..110d08b7a 100644 --- a/purpur-server/minecraft-patches/features/0001-Ridables.patch +++ b/purpur-server/minecraft-patches/features/0001-Ridables.patch @@ -42,7 +42,7 @@ index e4c88e1f99e684fadec47eeceb82420c879897cf..44a8629ec03c01597c7167c26d801c01 @Override public @Nullable LevelChunk getChunkIfLoaded(int x, int z) { diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index 14a7b040e9f5609a0e08783b60a767618a192de7..0c489a6d3357ed0d3dc9341440b87623d007da3f 100644 +index 565f54a7e37b9303cb23db09881751b364cdf5c4..38f92b36533c5f9694ca689a88f3f42a977d003a 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java @@ -761,6 +761,15 @@ public class ServerPlayer extends Player { @@ -62,7 +62,7 @@ index 14a7b040e9f5609a0e08783b60a767618a192de7..0c489a6d3357ed0d3dc9341440b87623 private void updatePlayerAttributes() { diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 7cdb4d46bb0ebdece3cdbe0dc2c156fe211da0d0..58be234e80a0c55642ba66a5001bac784c420a95 100644 +index 55e74b04ed0576923b8acfdf833e6c999d5a7b6c..900d59620d309258b3b883ccd8cb086f26db0c11 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -2773,6 +2773,8 @@ public class ServerGamePacketListenerImpl @@ -75,10 +75,10 @@ index 7cdb4d46bb0ebdece3cdbe0dc2c156fe211da0d0..58be234e80a0c55642ba66a5001bac78 if ((target instanceof net.minecraft.world.entity.animal.Bucketable && target instanceof LivingEntity && origItem != null && origItem == Items.WATER_BUCKET) && (event.isCancelled() || ServerGamePacketListenerImpl.this.player.getInventory().getSelectedItem().isEmpty() || !ServerGamePacketListenerImpl.this.player.getInventory().getSelectedItem().is(origItem))) { target.resendPossiblyDesyncedEntityData(ServerGamePacketListenerImpl.this.player); // Paper - The entire mob gets deleted, so resend it diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index fe1b49288dabc8aecfcae151b40fa76d633fc8c2..bce2b06cd7c0b9928a6538ddcd370f2c4d84a9ae 100644 +index efeee8849237270ad7c8cd0577dcefed34b82299..7e9e0e9cd0a12af66d937859885da5c0f619af22 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -3069,6 +3069,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3065,6 +3065,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.passengers = ImmutableList.copyOf(list); } @@ -92,7 +92,7 @@ index fe1b49288dabc8aecfcae151b40fa76d633fc8c2..bce2b06cd7c0b9928a6538ddcd370f2c this.gameEvent(GameEvent.ENTITY_MOUNT, passenger); } } -@@ -3110,6 +3117,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3106,6 +3113,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return false; } // CraftBukkit end @@ -107,7 +107,7 @@ index fe1b49288dabc8aecfcae151b40fa76d633fc8c2..bce2b06cd7c0b9928a6538ddcd370f2c if (this.passengers.size() == 1 && this.passengers.get(0) == passenger) { this.passengers = ImmutableList.of(); } else { -@@ -5079,4 +5094,44 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -5075,4 +5090,44 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return ((ServerLevel) this.level()).isPositionEntityTicking(this.blockPosition()); } // Paper end - Expose entity id counter @@ -177,7 +177,7 @@ index f0c452ddc4b299a930de261722cc41a89aa78eeb..8e8ddab59de508c84c4182e105a11554 protected ParticleOptions getInkParticle() { return ParticleTypes.GLOW_SQUID_INK; diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index 65cb0a0cfa3d75e4d1083b7e6b22ca1b2682dc49..e78d30d8fdfcb1a530bf3380251fabd0c9a18f46 100644 +index 96e47e6145a4cce8c154a05f9b155c1ba74bfa6a..d272f5e789cb6c03ede0bece14fc3fe976a02ff3 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java @@ -238,9 +238,9 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin @@ -3483,10 +3483,10 @@ index 7efa39ab1fb34da41a04cd6816f2571c6eba98f5..10142de6bdf9474958ca939c956a4282 this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true).setUnseenMemoryTicks(300)); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false).setUnseenMemoryTicks(300)); diff --git a/net/minecraft/world/entity/monster/Ghast.java b/net/minecraft/world/entity/monster/Ghast.java -index bbdff8b4043f27045684a2aa5687e2b7ca7afbb5..c7ac650f9618fd124035f9cf01fffada7efc97e1 100644 +index bbdff8b4043f27045684a2aa5687e2b7ca7afbb5..e09004313c7c8333eba38bbfab09b20bdb646034 100644 --- a/net/minecraft/world/entity/monster/Ghast.java +++ b/net/minecraft/world/entity/monster/Ghast.java -@@ -52,11 +52,47 @@ public class Ghast extends Mob implements Enemy { +@@ -52,11 +52,35 @@ public class Ghast extends Mob implements Enemy { this.moveControl = new Ghast.GhastMoveControl(this, false, () -> false); } @@ -3510,18 +3510,6 @@ index bbdff8b4043f27045684a2aa5687e2b7ca7afbb5..c7ac650f9618fd124035f9cf01fffada + public double getMaxY() { + return level().purpurConfig.ghastMaxY; + } -+ -+ @Override -+ public void travel(Vec3 vec3) { -+ super.travel(vec3); -+ if (getRider() != null && this.isControllable() && !onGround) { -+ float speed = (float) getAttributeValue(Attributes.FLYING_SPEED); -+ setSpeed(speed); -+ Vec3 mot = getDeltaMovement(); -+ move(net.minecraft.world.entity.MoverType.SELF, mot.multiply(speed, 1.0, speed)); -+ setDeltaMovement(mot.scale(0.9D)); -+ } -+ } + // Purpur end - Ridables + @Override @@ -3534,7 +3522,23 @@ index bbdff8b4043f27045684a2aa5687e2b7ca7afbb5..c7ac650f9618fd124035f9cf01fffada this.targetSelector .addGoal(1, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (entity, level) -> Math.abs(entity.getY() - this.getY()) <= 4.0)); } -@@ -236,7 +272,7 @@ public class Ghast extends Mob implements Enemy { +@@ -106,6 +130,15 @@ public class Ghast extends Mob implements Enemy { + @Override + public void travel(Vec3 travelVector) { + this.travelFlying(travelVector, 0.02F); ++ // Purpur start - Ridables ++ if (getRider() != null && this.isControllable() && !onGround) { ++ float speed = (float) getAttributeValue(Attributes.FLYING_SPEED); ++ setSpeed(speed); ++ Vec3 mot = getDeltaMovement(); ++ move(net.minecraft.world.entity.MoverType.SELF, mot.multiply(speed, 1.0, speed)); ++ setDeltaMovement(mot.scale(0.9D)); ++ } ++ // Purpur end - Ridables + } + + @Override +@@ -236,7 +269,7 @@ public class Ghast extends Mob implements Enemy { } } @@ -3543,7 +3547,7 @@ index bbdff8b4043f27045684a2aa5687e2b7ca7afbb5..c7ac650f9618fd124035f9cf01fffada private final Mob ghast; private int floatDuration; private final boolean careful; -@@ -250,7 +286,7 @@ public class Ghast extends Mob implements Enemy { +@@ -250,7 +283,7 @@ public class Ghast extends Mob implements Enemy { } @Override @@ -3791,10 +3795,10 @@ index 889c31cc9257fbbd5df8325ccee9ce39b026ec4b..4a1299d6cee2807522de0c2d0d4745c5 @Override diff --git a/net/minecraft/world/entity/monster/Phantom.java b/net/minecraft/world/entity/monster/Phantom.java -index 2abb55d84507fd29817760cb0068dd083f7f1c37..99194cf1fa89d3112719ead9f7de260ca5b9b676 100644 +index 2abb55d84507fd29817760cb0068dd083f7f1c37..855ec37a7e4110e37823ecf62f67f5cb3714f4bf 100644 --- a/net/minecraft/world/entity/monster/Phantom.java +++ b/net/minecraft/world/entity/monster/Phantom.java -@@ -62,6 +62,64 @@ public class Phantom extends Mob implements Enemy { +@@ -62,6 +62,52 @@ public class Phantom extends Mob implements Enemy { this.lookControl = new Phantom.PhantomLookControl(this); } @@ -3819,18 +3823,6 @@ index 2abb55d84507fd29817760cb0068dd083f7f1c37..99194cf1fa89d3112719ead9f7de260c + return level().purpurConfig.phantomMaxY; + } + -+ @Override -+ public void travel(Vec3 vec3) { -+ super.travel(vec3); -+ if (getRider() != null && this.isControllable() && !onGround) { -+ float speed = (float) getAttributeValue(Attributes.FLYING_SPEED); -+ setSpeed(speed); -+ Vec3 mot = getDeltaMovement(); -+ move(net.minecraft.world.entity.MoverType.SELF, mot.multiply(speed, speed, speed)); -+ setDeltaMovement(mot.scale(0.9D)); -+ } -+ } -+ + public static net.minecraft.world.entity.ai.attributes.AttributeSupplier.Builder createAttributes() { + return Monster.createMonsterAttributes().add(Attributes.FLYING_SPEED, 3.0D); + } @@ -3859,7 +3851,7 @@ index 2abb55d84507fd29817760cb0068dd083f7f1c37..99194cf1fa89d3112719ead9f7de260c @Override public boolean isFlapping() { return (this.getUniqueFlapTickOffset() + this.tickCount) % TICKS_PER_FLAP == 0; -@@ -74,9 +132,11 @@ public class Phantom extends Mob implements Enemy { +@@ -74,9 +120,11 @@ public class Phantom extends Mob implements Enemy { @Override protected void registerGoals() { @@ -3871,7 +3863,7 @@ index 2abb55d84507fd29817760cb0068dd083f7f1c37..99194cf1fa89d3112719ead9f7de260c this.targetSelector.addGoal(1, new Phantom.PhantomAttackPlayerTargetGoal()); } -@@ -92,6 +152,7 @@ public class Phantom extends Mob implements Enemy { +@@ -92,6 +140,7 @@ public class Phantom extends Mob implements Enemy { private void updatePhantomSizeInfo() { this.refreshDimensions(); @@ -3879,7 +3871,7 @@ index 2abb55d84507fd29817760cb0068dd083f7f1c37..99194cf1fa89d3112719ead9f7de260c this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(6 + this.getPhantomSize()); } -@@ -149,6 +210,7 @@ public class Phantom extends Mob implements Enemy { +@@ -149,6 +198,7 @@ public class Phantom extends Mob implements Enemy { @Override public void aiStep() { if (this.isAlive() && this.shouldBurnInDay && this.isSunBurnTick()) { // Paper - shouldBurnInDay API @@ -3887,7 +3879,23 @@ index 2abb55d84507fd29817760cb0068dd083f7f1c37..99194cf1fa89d3112719ead9f7de260c this.igniteForSeconds(8.0F); } -@@ -419,25 +481,42 @@ public class Phantom extends Mob implements Enemy { +@@ -167,6 +217,15 @@ public class Phantom extends Mob implements Enemy { + @Override + public void travel(Vec3 travelVector) { + this.travelFlying(travelVector, 0.2F); ++ // Purpur start - Ridables ++ if (this.getRider() != null && this.isControllable() && !this.onGround) { ++ float speed = (float) this.getAttributeValue(Attributes.FLYING_SPEED); ++ this.setSpeed(speed); ++ Vec3 mot = this.getDeltaMovement(); ++ this.move(net.minecraft.world.entity.MoverType.SELF, mot.multiply(speed, speed, speed)); ++ this.setDeltaMovement(mot.scale(0.9D)); ++ } ++ // Purpur end - Ridables + } + + @Override +@@ -419,25 +478,42 @@ public class Phantom extends Mob implements Enemy { } } @@ -4029,7 +4037,7 @@ index 2b9a72b8742bf13c69df5ce0c905d47a92b9d8bc..b67ac487ce4a7fd8b2f62452ab0b87f4 this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.0); } else { diff --git a/net/minecraft/world/entity/monster/Shulker.java b/net/minecraft/world/entity/monster/Shulker.java -index aaa95836e7d767ab6d162ff227f8a82a41255304..e0c70493e771b50885b0263ff07e8ee594c2dfdc 100644 +index b45145051f936bb08941be1b3cd2790f73102352..7b04bf19ee575b9199cb65f0eb3f412a05acac08 100644 --- a/net/minecraft/world/entity/monster/Shulker.java +++ b/net/minecraft/world/entity/monster/Shulker.java @@ -110,12 +110,31 @@ public class Shulker extends AbstractGolem implements Enemy { @@ -5046,7 +5054,7 @@ index 93ed977260f369677028bbd8396862f344dfeaa3..e5d6d8bd30876832e6219969849e8260 if (this.level().purpurConfig.wanderingTraderAllowTrading) { // Purpur - Add config for villager trading this.setTradingPlayer(player); diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java -index aba0104c4953ef514118ee8af76d029100081fc4..c421cc7dc6c401a19eaf193abd970f21e910f927 100644 +index cc29c094f81f16e6b4d74877e31fabd4a0e62435..65d981d26c729d63aa9bad1bbe90cef35207e832 100644 --- a/net/minecraft/world/entity/player/Player.java +++ b/net/minecraft/world/entity/player/Player.java @@ -239,6 +239,19 @@ public abstract class Player extends LivingEntity { diff --git a/purpur-server/minecraft-patches/features/0002-Configurable-entity-base-attributes.patch b/purpur-server/minecraft-patches/features/0002-Configurable-entity-base-attributes.patch index c732be65e..9292fb8a4 100644 --- a/purpur-server/minecraft-patches/features/0002-Configurable-entity-base-attributes.patch +++ b/purpur-server/minecraft-patches/features/0002-Configurable-entity-base-attributes.patch @@ -23,7 +23,7 @@ index 8e8ddab59de508c84c4182e105a11554387dcce0..1896f91e10a5e17332836d5354813a18 protected ParticleOptions getInkParticle() { return ParticleTypes.GLOW_SQUID_INK; diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index e78d30d8fdfcb1a530bf3380251fabd0c9a18f46..ae0c2f41c522656bde37d4f31699ee6172b5a79d 100644 +index d272f5e789cb6c03ede0bece14fc3fe976a02ff3..41b6b18130d89b3c3c31bbb2d184fa735a8cd99c 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java @@ -291,6 +291,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin @@ -1107,10 +1107,10 @@ index 10142de6bdf9474958ca939c956a428218ee48db..e8aac93cffa3a9d4105c03c1aeb4d571 protected void registerGoals() { super.registerGoals(); diff --git a/net/minecraft/world/entity/monster/Ghast.java b/net/minecraft/world/entity/monster/Ghast.java -index c7ac650f9618fd124035f9cf01fffada7efc97e1..5e2ae3ada994b5fa7758a61cdf1c0e9f26c23a79 100644 +index e09004313c7c8333eba38bbfab09b20bdb646034..06333fe18ea71464d35584592f487c6ac572f0cd 100644 --- a/net/minecraft/world/entity/monster/Ghast.java +++ b/net/minecraft/world/entity/monster/Ghast.java -@@ -86,6 +86,14 @@ public class Ghast extends Mob implements Enemy { +@@ -74,6 +74,14 @@ public class Ghast extends Mob implements Enemy { } // Purpur end - Ridables @@ -1243,10 +1243,10 @@ index 4a1299d6cee2807522de0c2d0d4745c5810e4121..bb1364c4a220cc93f7ac01cbaa617561 return Monster.createMonsterAttributes().add(Attributes.MOVEMENT_SPEED, 0.2F); } diff --git a/net/minecraft/world/entity/monster/Phantom.java b/net/minecraft/world/entity/monster/Phantom.java -index 99194cf1fa89d3112719ead9f7de260ca5b9b676..96ef89704122485948a526bcc323379474ac9343 100644 +index 855ec37a7e4110e37823ecf62f67f5cb3714f4bf..e35d1e91c1300d8f7d14a5cfa54c404c9f21184d 100644 --- a/net/minecraft/world/entity/monster/Phantom.java +++ b/net/minecraft/world/entity/monster/Phantom.java -@@ -153,7 +153,10 @@ public class Phantom extends Mob implements Enemy { +@@ -141,7 +141,10 @@ public class Phantom extends Mob implements Enemy { private void updatePhantomSizeInfo() { this.refreshDimensions(); if (level().purpurConfig.phantomFlamesOnSwoop && attackPhase == AttackPhase.SWOOP) shoot(); // Purpur - Ridables - Phantom flames on swoop @@ -1258,7 +1258,7 @@ index 99194cf1fa89d3112719ead9f7de260ca5b9b676..96ef89704122485948a526bcc3233794 } public int getPhantomSize() { -@@ -178,6 +181,23 @@ public class Phantom extends Mob implements Enemy { +@@ -166,6 +169,23 @@ public class Phantom extends Mob implements Enemy { return true; } @@ -1321,7 +1321,7 @@ index b67ac487ce4a7fd8b2f62452ab0b87f4a55006f2..9e7b07f353fb8f0650b8805014c37136 protected void registerGoals() { super.registerGoals(); diff --git a/net/minecraft/world/entity/monster/Shulker.java b/net/minecraft/world/entity/monster/Shulker.java -index e0c70493e771b50885b0263ff07e8ee594c2dfdc..069dacf455e597a4cb2efae03553479cac2a5fec 100644 +index 7b04bf19ee575b9199cb65f0eb3f412a05acac08..66f26ecce4f9d74c1b008b09c0eaf4b6ef4a177a 100644 --- a/net/minecraft/world/entity/monster/Shulker.java +++ b/net/minecraft/world/entity/monster/Shulker.java @@ -127,6 +127,14 @@ public class Shulker extends AbstractGolem implements Enemy { diff --git a/purpur-server/minecraft-patches/features/0010-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch b/purpur-server/minecraft-patches/features/0010-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch index 0045fa085..33e025049 100644 --- a/purpur-server/minecraft-patches/features/0010-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch +++ b/purpur-server/minecraft-patches/features/0010-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch @@ -72,7 +72,7 @@ index 5bff703ae4f95091620dec5347246d7c0cbe5d5e..220a828717e1933a44c5282b56713ba0 @Override diff --git a/net/minecraft/world/entity/monster/Phantom.java b/net/minecraft/world/entity/monster/Phantom.java -index 96ef89704122485948a526bcc323379474ac9343..f9f6199f5b64733be69e9e8dbdb3cd26700d822b 100644 +index e35d1e91c1300d8f7d14a5cfa54c404c9f21184d..1d7432bcce99c893a1f6e4a02d0cad65c0d6d3a4 100644 --- a/net/minecraft/world/entity/monster/Phantom.java +++ b/net/minecraft/world/entity/monster/Phantom.java @@ -49,6 +49,7 @@ public class Phantom extends Mob implements Enemy { @@ -83,7 +83,7 @@ index 96ef89704122485948a526bcc323379474ac9343..f9f6199f5b64733be69e9e8dbdb3cd26 // Paper start @Nullable public java.util.UUID spawningEntity; -@@ -120,6 +121,25 @@ public class Phantom extends Mob implements Enemy { +@@ -108,6 +109,25 @@ public class Phantom extends Mob implements Enemy { } // Purpur end - Ridables @@ -109,7 +109,7 @@ index 96ef89704122485948a526bcc323379474ac9343..f9f6199f5b64733be69e9e8dbdb3cd26 @Override public boolean isFlapping() { return (this.getUniqueFlapTickOffset() + this.tickCount) % TICKS_PER_FLAP == 0; -@@ -133,9 +153,15 @@ public class Phantom extends Mob implements Enemy { +@@ -121,9 +141,15 @@ public class Phantom extends Mob implements Enemy { @Override protected void registerGoals() { this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables @@ -128,7 +128,7 @@ index 96ef89704122485948a526bcc323379474ac9343..f9f6199f5b64733be69e9e8dbdb3cd26 this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.targetSelector.addGoal(1, new Phantom.PhantomAttackPlayerTargetGoal()); } -@@ -517,6 +543,124 @@ public class Phantom extends Mob implements Enemy { +@@ -514,6 +540,124 @@ public class Phantom extends Mob implements Enemy { } } diff --git a/purpur-server/minecraft-patches/features/0011-Phantoms-burn-in-light.patch b/purpur-server/minecraft-patches/features/0011-Phantoms-burn-in-light.patch index 79cdba713..aa5a25007 100644 --- a/purpur-server/minecraft-patches/features/0011-Phantoms-burn-in-light.patch +++ b/purpur-server/minecraft-patches/features/0011-Phantoms-burn-in-light.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Phantoms burn in light diff --git a/net/minecraft/world/entity/monster/Phantom.java b/net/minecraft/world/entity/monster/Phantom.java -index f9f6199f5b64733be69e9e8dbdb3cd26700d822b..f0351975340dec2b2bd51670f193baf44a62ae16 100644 +index 1d7432bcce99c893a1f6e4a02d0cad65c0d6d3a4..5b2018019f6ec9e91357d46dd66865e2f232507a 100644 --- a/net/minecraft/world/entity/monster/Phantom.java +++ b/net/minecraft/world/entity/monster/Phantom.java @@ -55,6 +55,7 @@ public class Phantom extends Mob implements Enemy { @@ -16,7 +16,7 @@ index f9f6199f5b64733be69e9e8dbdb3cd26700d822b..f0351975340dec2b2bd51670f193baf4 public Phantom(EntityType entityType, Level level) { super(entityType, level); -@@ -255,7 +256,11 @@ public class Phantom extends Mob implements Enemy { +@@ -243,7 +244,11 @@ public class Phantom extends Mob implements Enemy { @Override public void aiStep() { @@ -29,7 +29,7 @@ index f9f6199f5b64733be69e9e8dbdb3cd26700d822b..f0351975340dec2b2bd51670f193baf4 if (getRider() == null || !this.isControllable()) // Purpur - Ridables this.igniteForSeconds(8.0F); } -@@ -378,6 +383,7 @@ public class Phantom extends Mob implements Enemy { +@@ -375,6 +380,7 @@ public class Phantom extends Mob implements Enemy { List nearbyPlayers = serverLevel.getNearbyPlayers( this.attackTargeting, Phantom.this, Phantom.this.getBoundingBox().inflate(16.0, 64.0, 16.0) ); @@ -37,7 +37,7 @@ index f9f6199f5b64733be69e9e8dbdb3cd26700d822b..f0351975340dec2b2bd51670f193baf4 if (!nearbyPlayers.isEmpty()) { nearbyPlayers.sort(Comparator.comparing(Entity::getY).reversed()); -@@ -747,6 +753,12 @@ public class Phantom extends Mob implements Enemy { +@@ -744,6 +750,12 @@ public class Phantom extends Mob implements Enemy { return false; } else if (!target.isAlive()) { return false; diff --git a/purpur-server/minecraft-patches/features/0012-Make-entity-breeding-times-configurable.patch b/purpur-server/minecraft-patches/features/0012-Make-entity-breeding-times-configurable.patch index 136aa01b4..134cb2219 100644 --- a/purpur-server/minecraft-patches/features/0012-Make-entity-breeding-times-configurable.patch +++ b/purpur-server/minecraft-patches/features/0012-Make-entity-breeding-times-configurable.patch @@ -149,6 +149,24 @@ index 869a0154c81593db8933f9daa6a7d3a9d02facc5..37b6bfa8dc1fd4ed0006f6531d2056bc this.animal.resetLove(); this.partner.resetLove(); serverLevel.addFreshEntityWithPassengers(fox, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason +diff --git a/net/minecraft/world/entity/animal/HappyGhast.java b/net/minecraft/world/entity/animal/HappyGhast.java +index 8e998a2b35e38dbc74edbaa007f66e98e5486647..74bca6719c0bb1a4cabe058eeff6f8dc73632628 100644 +--- a/net/minecraft/world/entity/animal/HappyGhast.java ++++ b/net/minecraft/world/entity/animal/HappyGhast.java +@@ -120,6 +120,13 @@ public class HappyGhast extends Animal { + this.removeAllGoals(goal -> true); + } + ++ // Purpur start - Make entity breeding times configurable ++ @Override ++ public int getPurpurBreedTime() { ++ return 6000; ++ } ++ // Purpur end - Make entity breeding times configurable ++ + @Override + protected void ageBoundaryReached() { + if (this.isBaby()) { diff --git a/net/minecraft/world/entity/animal/MushroomCow.java b/net/minecraft/world/entity/animal/MushroomCow.java index 8cfbe37df24647c3f0a2d64bcc3451de1402c86f..3e4cb7680e6082ebab95e2b8307eedb0d3fcfbcd 100644 --- a/net/minecraft/world/entity/animal/MushroomCow.java diff --git a/purpur-server/minecraft-patches/features/0017-Toggle-for-water-sensitive-mob-damage.patch b/purpur-server/minecraft-patches/features/0017-Toggle-for-water-sensitive-mob-damage.patch index 3b1ee9b98..043ba8941 100644 --- a/purpur-server/minecraft-patches/features/0017-Toggle-for-water-sensitive-mob-damage.patch +++ b/purpur-server/minecraft-patches/features/0017-Toggle-for-water-sensitive-mob-damage.patch @@ -809,10 +809,10 @@ index 4d1d746e39d136243dc620c89b29daf80dc62230..d77e3b0f36ec4a262ff375d9e2da9125 protected void registerGoals() { super.registerGoals(); diff --git a/net/minecraft/world/entity/monster/Ghast.java b/net/minecraft/world/entity/monster/Ghast.java -index 5e2ae3ada994b5fa7758a61cdf1c0e9f26c23a79..92a9ce3d7db83a631281a6ac11ccc4441e04efdc 100644 +index 06333fe18ea71464d35584592f487c6ac572f0cd..07ea4f44d9fd32d5be5aae6c36b30806acc9db64 100644 --- a/net/minecraft/world/entity/monster/Ghast.java +++ b/net/minecraft/world/entity/monster/Ghast.java -@@ -94,6 +94,13 @@ public class Ghast extends Mob implements Enemy { +@@ -82,6 +82,13 @@ public class Ghast extends Mob implements Enemy { } // Purpur end - Configurable entity base attributes @@ -917,10 +917,10 @@ index bb1364c4a220cc93f7ac01cbaa617561de4cd2e3..da90b7dc79aa6d01e88c1250fff662ba return Monster.createMonsterAttributes().add(Attributes.MOVEMENT_SPEED, 0.2F); } diff --git a/net/minecraft/world/entity/monster/Phantom.java b/net/minecraft/world/entity/monster/Phantom.java -index f0351975340dec2b2bd51670f193baf44a62ae16..3e66363e0677d98b5c406fbaac2d4eaa533c6eb2 100644 +index 5b2018019f6ec9e91357d46dd66865e2f232507a..67dc738faef3ab414bf791692090aaea3dbe7385 100644 --- a/net/minecraft/world/entity/monster/Phantom.java +++ b/net/minecraft/world/entity/monster/Phantom.java -@@ -141,6 +141,13 @@ public class Phantom extends Mob implements Enemy { +@@ -129,6 +129,13 @@ public class Phantom extends Mob implements Enemy { } // Purpur end - Phantoms attracted to crystals and crystals shoot phantoms @@ -971,7 +971,7 @@ index 23b6d3c9746e1ee641d8b19ec50805cb271a9cc9..d75df6de50f9830efeea826d0ebdac17 protected void registerGoals() { super.registerGoals(); diff --git a/net/minecraft/world/entity/monster/Shulker.java b/net/minecraft/world/entity/monster/Shulker.java -index 069dacf455e597a4cb2efae03553479cac2a5fec..d38c6025833079a435971c66cfbb90486721ca14 100644 +index 66f26ecce4f9d74c1b008b09c0eaf4b6ef4a177a..decadd1844e197400e4130c2d4f8ef8622cfd7f6 100644 --- a/net/minecraft/world/entity/monster/Shulker.java +++ b/net/minecraft/world/entity/monster/Shulker.java @@ -135,6 +135,13 @@ public class Shulker extends AbstractGolem implements Enemy { diff --git a/purpur-server/minecraft-patches/features/0018-API-for-any-mob-to-burn-daylight.patch b/purpur-server/minecraft-patches/features/0018-API-for-any-mob-to-burn-daylight.patch index 452e113f5..37cd11243 100644 --- a/purpur-server/minecraft-patches/features/0018-API-for-any-mob-to-burn-daylight.patch +++ b/purpur-server/minecraft-patches/features/0018-API-for-any-mob-to-burn-daylight.patch @@ -6,7 +6,7 @@ Subject: [PATCH] API for any mob to burn daylight Co-authored by: Encode42 diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index bce2b06cd7c0b9928a6538ddcd370f2c4d84a9ae..5a6db2d02204cf98de02c30b63666692ed03c000 100644 +index 7e9e0e9cd0a12af66d937859885da5c0f619af22..0fb1267063476bb510ff236800132b535c29a50c 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -435,6 +435,24 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -35,7 +35,7 @@ index bce2b06cd7c0b9928a6538ddcd370f2c4d84a9ae..5a6db2d02204cf98de02c30b63666692 this.type = entityType; this.level = level; diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index a70fddd19b24bb25edde63e4fda4685ee6997eba..eabee40979ab8a1611b2d4eff04414f303b672f1 100644 +index 70808e9f092953a3edf7001b318c91228844f73c..98096df5f83196a6fee8d26637a1816807952f3f 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java @@ -286,6 +286,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin @@ -207,7 +207,7 @@ index 9baec22561093d64157d93449e84c23b3f238b39..3f331215ef49c52fa3a53bcf744159d2 @Override diff --git a/net/minecraft/world/entity/monster/Phantom.java b/net/minecraft/world/entity/monster/Phantom.java -index 3e66363e0677d98b5c406fbaac2d4eaa533c6eb2..bfd4d7eef537c0d3688159d6db99236d6ed2f810 100644 +index 67dc738faef3ab414bf791692090aaea3dbe7385..2c7f11e165ea9f59dca6de559c7bcba39977cb19 100644 --- a/net/minecraft/world/entity/monster/Phantom.java +++ b/net/minecraft/world/entity/monster/Phantom.java @@ -62,6 +62,7 @@ public class Phantom extends Mob implements Enemy { @@ -218,7 +218,7 @@ index 3e66363e0677d98b5c406fbaac2d4eaa533c6eb2..bfd4d7eef537c0d3688159d6db99236d } // Purpur start - Ridables -@@ -148,6 +149,16 @@ public class Phantom extends Mob implements Enemy { +@@ -136,6 +137,16 @@ public class Phantom extends Mob implements Enemy { } // Purpur end - Toggle for water sensitive mob damage @@ -235,7 +235,7 @@ index 3e66363e0677d98b5c406fbaac2d4eaa533c6eb2..bfd4d7eef537c0d3688159d6db99236d @Override public boolean isFlapping() { return (this.getUniqueFlapTickOffset() + this.tickCount) % TICKS_PER_FLAP == 0; -@@ -263,15 +274,7 @@ public class Phantom extends Mob implements Enemy { +@@ -251,15 +262,7 @@ public class Phantom extends Mob implements Enemy { @Override public void aiStep() { @@ -252,7 +252,7 @@ index 3e66363e0677d98b5c406fbaac2d4eaa533c6eb2..bfd4d7eef537c0d3688159d6db99236d super.aiStep(); } -@@ -309,7 +312,7 @@ public class Phantom extends Mob implements Enemy { +@@ -306,7 +309,7 @@ public class Phantom extends Mob implements Enemy { this.setPhantomSize(input.getIntOr("size", 0)); // Paper start this.spawningEntity = input.read("Paper.SpawningEntity", net.minecraft.core.UUIDUtil.CODEC).orElse(null); @@ -261,7 +261,7 @@ index 3e66363e0677d98b5c406fbaac2d4eaa533c6eb2..bfd4d7eef537c0d3688159d6db99236d // Paper end } -@@ -320,7 +323,7 @@ public class Phantom extends Mob implements Enemy { +@@ -317,7 +320,7 @@ public class Phantom extends Mob implements Enemy { output.putInt("size", this.getPhantomSize()); // Paper start output.storeNullable("Paper.SpawningEntity", net.minecraft.core.UUIDUtil.CODEC, this.spawningEntity); diff --git a/purpur-server/minecraft-patches/features/0020-Mobs-always-drop-experience.patch b/purpur-server/minecraft-patches/features/0020-Mobs-always-drop-experience.patch index 59641be0f..732676310 100644 --- a/purpur-server/minecraft-patches/features/0020-Mobs-always-drop-experience.patch +++ b/purpur-server/minecraft-patches/features/0020-Mobs-always-drop-experience.patch @@ -779,10 +779,10 @@ index d77e3b0f36ec4a262ff375d9e2da912553a344f8..5c1992a7fd5d7c5fe23ebfad35a82826 protected void registerGoals() { super.registerGoals(); diff --git a/net/minecraft/world/entity/monster/Ghast.java b/net/minecraft/world/entity/monster/Ghast.java -index 92a9ce3d7db83a631281a6ac11ccc4441e04efdc..f11b9f5ff3087ee2b53c1614b63f29ef33072f73 100644 +index 07ea4f44d9fd32d5be5aae6c36b30806acc9db64..6f312f0b8ab60c839129ea671f2d9c128fa58e58 100644 --- a/net/minecraft/world/entity/monster/Ghast.java +++ b/net/minecraft/world/entity/monster/Ghast.java -@@ -101,6 +101,13 @@ public class Ghast extends Mob implements Enemy { +@@ -89,6 +89,13 @@ public class Ghast extends Mob implements Enemy { } // Purpur end - Toggle for water sensitive mob damage @@ -887,10 +887,10 @@ index da90b7dc79aa6d01e88c1250fff662ba1b001dc3..7ef0f84d4c449a8991683ca66d7b16ca return Monster.createMonsterAttributes().add(Attributes.MOVEMENT_SPEED, 0.2F); } diff --git a/net/minecraft/world/entity/monster/Phantom.java b/net/minecraft/world/entity/monster/Phantom.java -index bfd4d7eef537c0d3688159d6db99236d6ed2f810..82fe0c14f22e8492766553a93b24cb506b09afd9 100644 +index 2c7f11e165ea9f59dca6de559c7bcba39977cb19..3b812e0860e37d30d5d12f97410ed5fd2babadf6 100644 --- a/net/minecraft/world/entity/monster/Phantom.java +++ b/net/minecraft/world/entity/monster/Phantom.java -@@ -159,6 +159,13 @@ public class Phantom extends Mob implements Enemy { +@@ -147,6 +147,13 @@ public class Phantom extends Mob implements Enemy { public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; } // Purpur end - API for any mob to burn daylight @@ -941,7 +941,7 @@ index d75df6de50f9830efeea826d0ebdac17f56d4c4b..2b85cedf235e673d6030c2a649abf60b protected void registerGoals() { super.registerGoals(); diff --git a/net/minecraft/world/entity/monster/Shulker.java b/net/minecraft/world/entity/monster/Shulker.java -index d38c6025833079a435971c66cfbb90486721ca14..768da16864cbb925e4988f3bcfb7dc86a9b1846d 100644 +index decadd1844e197400e4130c2d4f8ef8622cfd7f6..2ace8aebd050e43582524c4a659132fef0e05be4 100644 --- a/net/minecraft/world/entity/monster/Shulker.java +++ b/net/minecraft/world/entity/monster/Shulker.java @@ -142,6 +142,13 @@ public class Shulker extends AbstractGolem implements Enemy { diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerPlayer.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerPlayer.java.patch index 1b2a563b5..b100b40ed 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerPlayer.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerPlayer.java.patch @@ -210,8 +210,8 @@ + } + + @Override -+ public boolean canBeCollidedWith() { -+ return !this.isAfk() && super.canBeCollidedWith(); ++ public boolean canBeCollidedWith(Entity entity) { ++ return !this.isAfk() && super.canBeCollidedWith(entity); + } + // Purpur end - AFK API diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index 841cc134f..4e3a6149c 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -179,8 +179,8 @@ } + // Purpur start - Dont run with scissors! -+ if (this.player.serverLevel().purpurConfig.dontRunWithScissors && this.player.isSprinting() && !(this.player.serverLevel().purpurConfig.ignoreScissorsInWater && this.player.isInWater()) && !(this.player.serverLevel().purpurConfig.ignoreScissorsInLava && this.player.isInLava()) && (isScissors(this.player.getItemInHand(InteractionHand.MAIN_HAND)) || isScissors(this.player.getItemInHand(InteractionHand.OFF_HAND))) && (int) (Math.random() * 10) == 0) { -+ this.player.hurtServer(this.player.serverLevel(), this.player.damageSources().scissors(), (float) this.player.serverLevel().purpurConfig.scissorsRunningDamage); ++ if (this.player.level().purpurConfig.dontRunWithScissors && this.player.isSprinting() && !(this.player.level().purpurConfig.ignoreScissorsInWater && this.player.isInWater()) && !(this.player.level().purpurConfig.ignoreScissorsInLava && this.player.isInLava()) && (isScissors(this.player.getItemInHand(InteractionHand.MAIN_HAND)) || isScissors(this.player.getItemInHand(InteractionHand.OFF_HAND))) && (int) (Math.random() * 10) == 0) { ++ this.player.hurtServer(this.player.level(), this.player.damageSources().scissors(), (float) this.player.level().purpurConfig.scissorsRunningDamage); + if (!org.purpurmc.purpur.PurpurConfig.dontRunWithScissors.isBlank()) this.player.sendActionBarMessage(org.purpurmc.purpur.PurpurConfig.dontRunWithScissors); + } + // Purpur end - Dont run with scissors! @@ -197,7 +197,7 @@ + if (!stack.is(Items.SHEARS)) return false; + + ResourceLocation itemModelReference = stack.get(net.minecraft.core.component.DataComponents.ITEM_MODEL); -+ if (itemModelReference != null && itemModelReference.equals(this.player.serverLevel().purpurConfig.dontRunWithScissorsItemModelReference)) return true; ++ if (itemModelReference != null && itemModelReference.equals(this.player.level().purpurConfig.dontRunWithScissorsItemModelReference)) return true; + + return stack.getOrDefault(DataComponents.CUSTOM_MODEL_DATA, net.minecraft.world.item.component.CustomModelData.EMPTY).equals(net.minecraft.world.item.component.CustomModelData.EMPTY); + } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/Entity.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/Entity.java.patch index c474ef13e..1927d54c1 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/Entity.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/Entity.java.patch @@ -81,7 +81,7 @@ return this.isInWater() || flag; } -- void updateInWaterStateAndDoWaterCurrentPushing() { +- public void updateInWaterStateAndDoWaterCurrentPushing() { + public void updateInWaterStateAndDoWaterCurrentPushing() { // Purpur - Movement options for armor stands - package-private -> public - TODO: use AT file if (this.getVehicle() instanceof AbstractBoat abstractBoat && !abstractBoat.isUnderWater()) { this.wasTouchingWater = false; @@ -98,16 +98,12 @@ } catch (Throwable var7) { CrashReport crashReport = CrashReport.forThrowable(var7, "Saving entity NBT"); CrashReportCategory crashReportCategory = crashReport.addCategory("Entity being saved"); -@@ -2557,6 +_,13 @@ +@@ -2557,6 +_,9 @@ } freezeLocked = input.getBooleanOr("Paper.FreezeLock", false); // Paper end + -+ // Purpur start - Fire immune API -+ if (input.contains("Purpur.FireImmune")) { -+ immuneToFire = input.getBoolean("Purpur.FireImmune").orElse(null); -+ } -+ // Purpur end - Fire immune API ++ immuneToFire = input.read("Purpur.FireImmune", com.mojang.serialization.Codec.BOOL).orElse(null); // Purpur - Fire immune API + } catch (Throwable var7) { CrashReport crashReport = CrashReport.forThrowable(var7, "Loading entity NBT"); diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/SpawnerBlock.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/SpawnerBlock.java.patch index 9c1015ed7..0b505b086 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/SpawnerBlock.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/SpawnerBlock.java.patch @@ -1,6 +1,14 @@ --- a/net/minecraft/world/level/block/SpawnerBlock.java +++ b/net/minecraft/world/level/block/SpawnerBlock.java -@@ -38,6 +_,59 @@ +@@ -14,6 +_,7 @@ + import net.minecraft.world.level.block.state.BlockState; + + public class SpawnerBlock extends BaseEntityBlock { ++ private static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger(); + public static final MapCodec CODEC = simpleCodec(SpawnerBlock::new); + + @Override +@@ -38,6 +_,62 @@ ); } @@ -13,7 +21,10 @@ + net.minecraft.world.level.SpawnData nextSpawnData = blockEntity instanceof SpawnerBlockEntity spawnerBlock ? spawnerBlock.getSpawner().nextSpawnData : null; + java.util.Optional> type = java.util.Optional.empty(); + if (nextSpawnData != null) { -+ type = net.minecraft.world.entity.EntityType.by(nextSpawnData.getEntityToSpawn()); ++ try (net.minecraft.util.ProblemReporter.ScopedCollector scopedCollector = new net.minecraft.util.ProblemReporter.ScopedCollector(blockEntity.problemPath(), LOGGER)) { ++ net.minecraft.world.level.storage.ValueInput valueInput = net.minecraft.world.level.storage.TagValueInput.create(scopedCollector, player.level().registryAccess(), nextSpawnData.entityToSpawn()); ++ type = net.minecraft.world.entity.EntityType.by(valueInput); ++ } + net.minecraft.nbt.CompoundTag spawnDataTag = new net.minecraft.nbt.CompoundTag(); + spawnDataTag.storeNullable("SpawnData", net.minecraft.world.level.SpawnData.CODEC, nextSpawnData); + item.set(net.minecraft.core.component.DataComponents.CUSTOM_DATA, net.minecraft.world.item.component.CustomData.EMPTY.update(compoundTag -> compoundTag.put("Purpur.SpawnData", spawnDataTag))); diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/BlockEntity.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/BlockEntity.java.patch index e06155335..d33824d55 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/BlockEntity.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/BlockEntity.java.patch @@ -6,7 +6,7 @@ // Paper end - read persistent data container + + -+ this.persistentLore = tag.read("Purpur.persistentLore", net.minecraft.world.item.component.ItemLore.CODEC).orElse(null); // Purpur - Persistent BlockEntity Lore and DisplayName ++ this.persistentLore = input.read("Purpur.persistentLore", net.minecraft.world.item.component.ItemLore.CODEC).orElse(null); // Purpur - Persistent BlockEntity Lore and DisplayName + } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch index 940a560fc..427ad45ec 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch @@ -35,26 +35,29 @@ ); } } -@@ -306,6 +_,24 @@ +@@ -306,6 +_,27 @@ // CraftBukkit - this return new CommandSourceStack(commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, level, 2, string, component, level.getServer(), player); // Paper - Fix commands from signs not firing command events } + + // Purpur start - Signs allow color codes + public ClientboundBlockEntityDataPacket getTranslatedUpdatePacket(boolean filtered, boolean front) { -+ final CompoundTag nbt = new CompoundTag(); -+ this.saveAdditional(nbt, this.getLevel().registryAccess()); -+ final Component[] lines = front ? frontText.getMessages(filtered) : backText.getMessages(filtered); -+ final String side = front ? "front_text" : "back_text"; -+ for (int i = 0; i < 4; i++) { -+ final var component = io.papermc.paper.adventure.PaperAdventure.asAdventure(lines[i]); -+ final String line = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacyAmpersand().serialize(component); -+ final CompoundTag sideNbt = nbt.getCompoundOrEmpty(side); -+ final net.minecraft.nbt.ListTag messagesNbt = sideNbt.getListOrEmpty("messages"); -+ messagesNbt.set(i, net.minecraft.nbt.StringTag.valueOf(line)); ++ try (net.minecraft.util.ProblemReporter.ScopedCollector scopedCollector = new net.minecraft.util.ProblemReporter.ScopedCollector(this.problemPath(), LOGGER)) { ++ net.minecraft.world.level.storage.TagValueOutput tagValueOutput = net.minecraft.world.level.storage.TagValueOutput.createWithContext(scopedCollector, this.getLevel().registryAccess()); ++ this.saveAdditional(tagValueOutput); ++ ++ final Component[] lines = front ? frontText.getMessages(filtered) : backText.getMessages(filtered); ++ final String side = front ? "front_text" : "back_text"; ++ for (int i = 0; i < 4; i++) { ++ final net.kyori.adventure.text.Component component = io.papermc.paper.adventure.PaperAdventure.asAdventure(lines[i]); ++ final String line = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacyAmpersand().serialize(component); ++ net.minecraft.world.level.storage.ValueOutput sideNbt = tagValueOutput.child(side); ++ net.minecraft.world.level.storage.ValueOutput.TypedOutputList messagesNbt = sideNbt.list("messages", com.mojang.serialization.Codec.STRING); ++ messagesNbt.add(line); ++ } ++ tagValueOutput.putString("PurpurEditor", "true"); ++ return ClientboundBlockEntityDataPacket.create(this, (blockEntity, registryAccess) -> tagValueOutput.buildResult()); + } -+ nbt.putString("PurpurEditor", "true"); -+ return ClientboundBlockEntityDataPacket.create(this, (blockEntity, registryAccess) -> nbt); + } + // Purpur end - Signs allow color codes diff --git a/purpur-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java.patch b/purpur-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java.patch index e8bb09a96..b2fe7e396 100644 --- a/purpur-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java.patch +++ b/purpur-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java.patch @@ -10,7 +10,7 @@ super(world, blockEntity); + // Purpur start - load bees to be able to modify them individually - Stored Bee API + for(BeehiveBlockEntity.BeeData data : blockEntity.getStored()) { -+ storage.add(new org.purpurmc.purpur.entity.PurpurStoredBee(data, this)); ++ storage.add(new org.purpurmc.purpur.entity.PurpurStoredBee(data, this, blockEntity)); + } + // Purpur end - Stored Bee API } @@ -65,7 +65,7 @@ + // Purpur start - check if new bee was added, and if yes, add to stored bees - Stored Bee API + List storedBeeData = this.getSnapshot().getStored(); + if(length < storedBeeData.size()) { -+ storage.add(new org.purpurmc.purpur.entity.PurpurStoredBee(storedBeeData.getLast(), this)); ++ storage.add(new org.purpurmc.purpur.entity.PurpurStoredBee(storedBeeData.getLast(), this, this.getBlockEntity())); + } + // Purpur end - Stored Bee API } diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/entity/PurpurStoredBee.java b/purpur-server/src/main/java/org/purpurmc/purpur/entity/PurpurStoredBee.java index 1cd79edbe..cdaa50276 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/entity/PurpurStoredBee.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/entity/PurpurStoredBee.java @@ -1,23 +1,29 @@ package org.purpurmc.purpur.entity; +import com.mojang.logging.LogUtils; import io.papermc.paper.adventure.PaperAdventure; import net.kyori.adventure.text.Component; import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.ProblemReporter; import net.minecraft.world.level.block.entity.BeehiveBlockEntity; import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.storage.TagValueInput; +import net.minecraft.world.level.storage.ValueInput; import org.bukkit.block.EntityBlockStorage; -import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer; import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry; +import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.entity.Bee; import org.bukkit.entity.EntityType; import org.bukkit.persistence.PersistentDataContainer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; - +import org.slf4j.Logger; import java.util.Locale; public class PurpurStoredBee implements StoredEntity { + static final Logger LOGGER = LogUtils.getLogger(); + private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry(); private final EntityBlockStorage blockStorage; @@ -26,16 +32,21 @@ public class PurpurStoredBee implements StoredEntity { private Component customName; - public PurpurStoredBee(BeehiveBlockEntity.BeeData data, EntityBlockStorage blockStorage) { + public PurpurStoredBee(BeehiveBlockEntity.BeeData data, EntityBlockStorage blockStorage, final BeehiveBlockEntity blockEntity) { this.handle = data; this.blockStorage = blockStorage; CompoundTag customData = handle.occupant.entityData().copyTag(); - net.minecraft.network.chat.Component customNameMinecraft = BlockEntity.parseCustomNameSafe(customData.get("CustomName"), ((CraftWorld) blockStorage.getWorld()).getHandle().registryAccess()); - this.customName = customNameMinecraft == null ? null : PaperAdventure.asAdventure(customNameMinecraft); - if (customData.get("BukkitValues") instanceof CompoundTag compoundTag) { - this.persistentDataContainer.putAll(compoundTag); + try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(blockEntity.problemPath(), LOGGER)) { + ValueInput valueInput = TagValueInput.create(scopedCollector, blockEntity.getLevel().registryAccess(), customData); + + net.minecraft.network.chat.Component customNameMinecraft = BlockEntity.parseCustomNameSafe(valueInput, "CustomName"); + this.customName = customNameMinecraft == null ? null : PaperAdventure.asAdventure(customNameMinecraft); + + if (customData.get("BukkitValues") instanceof CompoundTag compoundTag) { + this.persistentDataContainer.putAll(compoundTag); + } } } @@ -98,7 +109,7 @@ public class PurpurStoredBee implements StoredEntity { if(customName == null) { handle.occupant.entityData().copyTag().remove("CustomName"); } else { - handle.occupant.entityData().copyTag().putString("CustomName", net.minecraft.network.chat.Component.Serializer.toJson(PaperAdventure.asVanilla(customName), ((CraftWorld) blockStorage.getWorld()).getHandle().registryAccess())); + handle.occupant.entityData().copyTag().putString("CustomName", CraftChatMessage.toJSON(PaperAdventure.asVanilla(customName))); } } }