Skip to content

Commit fd4c6f1

Browse files
committed
Break MushroomCow parent
MushroomCows no longer are direct child types of Cows, as Cows have their own variant. The commit for now breaks the API by introducing a new parent type, similar to the vanilla implementation. The commit does not include potential bytecode rewriting or other compatibility measures.
1 parent 4db9475 commit fd4c6f1

File tree

14 files changed

+65
-24
lines changed

14 files changed

+65
-24
lines changed

build-data/paper.at

+1
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ public net.minecraft.world.entity.animal.Fox setDefending(Z)V
281281
public net.minecraft.world.entity.animal.Fox setFaceplanted(Z)V
282282
public net.minecraft.world.entity.animal.Fox setSleeping(Z)V
283283
public net.minecraft.world.entity.animal.Fox setVariant(Lnet/minecraft/world/entity/animal/Fox$Variant;)V
284+
public net.minecraft.world.entity.animal.MushroomCow setVariant(Lnet/minecraft/world/entity/animal/MushroomCow$Variant;)V
284285
public net.minecraft.world.entity.animal.MushroomCow stewEffects
285286
public net.minecraft.world.entity.animal.Ocelot isTrusting()Z
286287
public net.minecraft.world.entity.animal.Ocelot setTrusting(Z)V
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.bukkit.entity;
2+
3+
import io.papermc.paper.registry.RegistryAccess;
4+
import io.papermc.paper.registry.RegistryKey;
5+
import org.bukkit.Keyed;
6+
import org.bukkit.NamespacedKey;
7+
import org.jspecify.annotations.NullMarked;
8+
9+
/**
10+
* This interface defines or represents the abstract concept of cow-like
11+
* entities on the server. The interface is hence not a direct representation
12+
* of an entity but rather serves as a parent to interfaces/entity types like
13+
* {@link Cow} or {@link MushroomCow}.
14+
*/
15+
@NullMarked
16+
public interface AbstractCow extends Animals {
17+
18+
}

paper-api/src/main/java/org/bukkit/entity/MushroomCow.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
/**
99
* Represents a mushroom {@link Cow}
1010
*/
11-
public interface MushroomCow extends Cow, io.papermc.paper.entity.Shearable { // Paper
11+
public interface MushroomCow extends AbstractCow, io.papermc.paper.entity.Shearable { // Paper
1212

1313
/**
1414
* Checks for the presence of custom potion effects to be applied to the

paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch

+1-1
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@
173173
+ net.minecraft.world.level.block.state.BlockState blockData = serverLevel.getBlockState(position);
174174
+
175175
+ if (blockData.getBlock() instanceof net.minecraft.world.level.block.BedBlock) {
176-
+ serverLevel.blockUpdated(position, net.minecraft.world.level.block.Blocks.AIR);
176+
+ serverLevel.updateNeighborsAt(position, net.minecraft.world.level.block.Blocks.AIR);
177177
+ blockData.updateNeighbourShapes(serverLevel, position, 3);
178178
+ }
179179
+ }

paper-server/patches/sources/net/minecraft/world/level/Level.java.patch

+1-1
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@
455455
+
456456
+ // CraftBukkit start - SPIGOT-5710
457457
+ if (!this.preventPoiUpdated) {
458-
+ this.onBlockStateChange(blockposition, iblockdata1, iblockdata2);
458+
+ this.updatePOIOnBlockStateChange(blockposition, iblockdata1, iblockdata2);
459459
+ }
460460
+ // CraftBukkit end
461461
+ }

paper-server/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ private static int fetchDistanceFromGitHub(final String repo, final String branc
112112
final HttpURLConnection connection = (HttpURLConnection) URI.create("https://api.github.com/repos/%s/compare/%s...%s".formatted(repo, branch, hash)).toURL().openConnection();
113113
connection.connect();
114114
if (connection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) return DISTANCE_UNKNOWN; // Unknown commit
115-
try (final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), Charsets.UTF_8))) {
115+
try (final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
116116
final JsonObject obj = new Gson().fromJson(reader, JsonObject.class);
117117
final String status = obj.get("status").getAsString();
118118
return switch (status) {

paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
import java.util.Collection;
55
import java.util.Collections;
66
import java.util.Optional;
7+
import net.minecraft.advancements.critereon.DataComponentMatchers;
78
import net.minecraft.advancements.critereon.ItemPredicate;
89
import net.minecraft.advancements.critereon.MinMaxBounds;
9-
import net.minecraft.core.component.DataComponentPredicate;
10+
import net.minecraft.core.component.DataComponentExactPredicate;
1011
import net.minecraft.core.component.DataComponents;
1112
import net.minecraft.network.chat.Component;
1213
import net.minecraft.world.LockCode;
@@ -112,7 +113,7 @@ public boolean isLocked() {
112113

113114
@Override
114115
public String getLock() {
115-
Optional<? extends Component> customName = this.getSnapshot().lockKey.predicate().components().asPatch().get(DataComponents.CUSTOM_NAME);
116+
Optional<? extends Component> customName = this.getSnapshot().lockKey.predicate().components().exact().asPatch().get(DataComponents.CUSTOM_NAME);
116117

117118
return (customName != null) ? customName.map(CraftChatMessage::fromComponent).orElse("") : "";
118119
}
@@ -122,8 +123,8 @@ public void setLock(String key) {
122123
if (key == null) {
123124
this.getSnapshot().lockKey = LockCode.NO_LOCK;
124125
} else {
125-
DataComponentPredicate predicate = DataComponentPredicate.builder().expect(DataComponents.CUSTOM_NAME, CraftChatMessage.fromStringOrNull(key)).build();
126-
this.getSnapshot().lockKey = new LockCode(new ItemPredicate(Optional.empty(), MinMaxBounds.Ints.ANY, predicate, Collections.emptyMap()));
126+
DataComponentExactPredicate predicate = DataComponentExactPredicate.builder().expect(DataComponents.CUSTOM_NAME, CraftChatMessage.fromStringOrNull(key)).build();
127+
this.getSnapshot().lockKey = new LockCode(new ItemPredicate(Optional.empty(), MinMaxBounds.Ints.ANY, new DataComponentMatchers(predicate, Collections.emptyMap())));
127128
}
128129
}
129130

paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftContainer.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
import java.util.Collections;
44
import java.util.Optional;
5+
import net.minecraft.advancements.critereon.DataComponentMatchers;
56
import net.minecraft.advancements.critereon.ItemPredicate;
67
import net.minecraft.advancements.critereon.MinMaxBounds;
7-
import net.minecraft.core.component.DataComponentPredicate;
8+
import net.minecraft.core.component.DataComponentExactPredicate;
89
import net.minecraft.core.component.DataComponents;
910
import net.minecraft.network.chat.Component;
1011
import net.minecraft.world.LockCode;
@@ -33,7 +34,7 @@ public boolean isLocked() {
3334

3435
@Override
3536
public String getLock() {
36-
Optional<? extends Component> customName = this.getSnapshot().lockKey.predicate().components().asPatch().get(DataComponents.CUSTOM_NAME);
37+
Optional<? extends Component> customName = this.getSnapshot().lockKey.predicate().components().exact().asPatch().get(DataComponents.CUSTOM_NAME);
3738

3839
return (customName != null) ? customName.map(CraftChatMessage::fromComponent).orElse("") : "";
3940
}
@@ -43,8 +44,8 @@ public void setLock(String key) {
4344
if (key == null) {
4445
this.getSnapshot().lockKey = LockCode.NO_LOCK;
4546
} else {
46-
DataComponentPredicate predicate = DataComponentPredicate.builder().expect(DataComponents.CUSTOM_NAME, CraftChatMessage.fromStringOrNull(key)).build();
47-
this.getSnapshot().lockKey = new LockCode(new ItemPredicate(Optional.empty(), MinMaxBounds.Ints.ANY, predicate, Collections.emptyMap()));
47+
DataComponentExactPredicate predicate = DataComponentExactPredicate.builder().expect(DataComponents.CUSTOM_NAME, CraftChatMessage.fromStringOrNull(key)).build();
48+
this.getSnapshot().lockKey = new LockCode(new ItemPredicate(Optional.empty(), MinMaxBounds.Ints.ANY, new DataComponentMatchers(predicate, Collections.emptyMap())));
4849
}
4950
}
5051

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.bukkit.craftbukkit.entity;
2+
3+
import org.bukkit.craftbukkit.CraftServer;
4+
import org.bukkit.entity.AbstractCow;
5+
import org.jspecify.annotations.NullMarked;
6+
7+
@NullMarked
8+
public class CraftAbstractCow extends CraftAnimals implements AbstractCow {
9+
10+
public CraftAbstractCow(CraftServer server, net.minecraft.world.entity.animal.AbstractCow entity) {
11+
super(server, entity);
12+
}
13+
14+
@Override
15+
public net.minecraft.world.entity.animal.AbstractCow getHandle() {
16+
return (net.minecraft.world.entity.animal.AbstractCow) this.entity;
17+
}
18+
19+
}

paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import org.bukkit.potion.PotionEffect;
1515
import org.bukkit.potion.PotionEffectType;
1616

17-
public class CraftMushroomCow extends CraftCow implements MushroomCow, io.papermc.paper.entity.PaperShearable { // Paper
17+
public class CraftMushroomCow extends CraftAbstractCow implements MushroomCow, io.papermc.paper.entity.PaperShearable { // Paper
1818
public CraftMushroomCow(CraftServer server, net.minecraft.world.entity.animal.MushroomCow entity) {
1919
super(server, entity);
2020
}

paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import org.bukkit.potion.PotionEffect;
1616

1717
public class CraftThrownPotion extends CraftThrowableProjectile implements ThrownPotion, org.bukkit.entity.SplashPotion, org.bukkit.entity.LingeringPotion { // Paper - implement other classes to avoid violating spawn method generic contracts
18-
public CraftThrownPotion(CraftServer server, net.minecraft.world.entity.projectile.ThrownPotion entity) {
18+
public CraftThrownPotion(CraftServer server, net.minecraft.world.entity.projectile.AbstractThrownPotion entity) {
1919
super(server, entity);
2020
}
2121

@@ -62,7 +62,7 @@ public void splash() {
6262
}
6363
// Paper end
6464
@Override
65-
public net.minecraft.world.entity.projectile.ThrownPotion getHandle() {
66-
return (net.minecraft.world.entity.projectile.ThrownPotion) this.entity;
65+
public net.minecraft.world.entity.projectile.AbstractThrownPotion getHandle() {
66+
return (net.minecraft.world.entity.projectile.AbstractThrownPotion) this.entity;
6767
}
6868
}

paper-server/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import net.minecraft.server.level.ServerLevel;
1313
import net.minecraft.server.level.WorldGenRegion;
1414
import net.minecraft.util.Mth;
15-
import net.minecraft.util.random.WeightedRandomList;
15+
import net.minecraft.util.random.WeightedList;
1616
import net.minecraft.world.entity.MobCategory;
1717
import net.minecraft.world.level.Level;
1818
import net.minecraft.world.level.LevelHeightAccessor;
@@ -286,7 +286,7 @@ public int getBaseHeight(int x, int z, Heightmap.Types heightmap, LevelHeightAcc
286286
}
287287

288288
@Override
289-
public WeightedRandomList<MobSpawnSettings.SpawnerData> getMobsAt(Holder<net.minecraft.world.level.biome.Biome> biome, StructureManager accessor, MobCategory group, BlockPos pos) {
289+
public WeightedList<MobSpawnSettings.SpawnerData> getMobsAt(Holder<net.minecraft.world.level.biome.Biome> biome, StructureManager accessor, MobCategory group, BlockPos pos) {
290290
return this.delegate.getMobsAt(biome, accessor, group, pos);
291291
}
292292

paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88
import java.util.Optional;
99
import java.util.function.Consumer;
1010
import net.kyori.adventure.text.Component;
11+
import net.minecraft.advancements.critereon.DataComponentMatchers;
1112
import net.minecraft.advancements.critereon.ItemPredicate;
1213
import net.minecraft.advancements.critereon.MinMaxBounds;
1314
import net.minecraft.core.Holder;
1415
import net.minecraft.core.HolderSet;
16+
import net.minecraft.core.component.DataComponentExactPredicate;
1517
import net.minecraft.core.component.DataComponentMap;
1618
import net.minecraft.core.component.DataComponentPatch;
17-
import net.minecraft.core.component.DataComponentPredicate;
1819
import net.minecraft.core.component.DataComponents;
1920
import net.minecraft.core.component.PatchedDataComponentMap;
2021
import net.minecraft.nbt.CompoundTag;
@@ -158,9 +159,9 @@ public static CraftItemStack asNewCraftStack(Item item, int amount) {
158159

159160
public static ItemPredicate asCriterionConditionItem(ItemStack original) {
160161
net.minecraft.world.item.ItemStack nms = CraftItemStack.asNMSCopy(original);
161-
DataComponentPredicate predicate = DataComponentPredicate.allOf(PatchedDataComponentMap.fromPatch(DataComponentMap.EMPTY, nms.getComponentsPatch()));
162+
DataComponentExactPredicate predicate = DataComponentExactPredicate.allOf(PatchedDataComponentMap.fromPatch(DataComponentMap.EMPTY, nms.getComponentsPatch()));
162163

163-
return new ItemPredicate(Optional.of(HolderSet.direct(nms.getItemHolder())), MinMaxBounds.Ints.ANY, predicate, Collections.emptyMap());
164+
return new ItemPredicate(Optional.of(HolderSet.direct(nms.getItemHolder())), MinMaxBounds.Ints.ANY, new DataComponentMatchers(predicate, Collections.emptyMap()));
164165
}
165166

166167
public net.minecraft.world.item.ItemStack handle;

paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantRecipe.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import com.google.common.base.Preconditions;
44
import java.util.List;
55
import java.util.Optional;
6+
import net.minecraft.core.component.DataComponentExactPredicate;
67
import net.minecraft.core.component.DataComponentMap;
7-
import net.minecraft.core.component.DataComponentPredicate;
88
import net.minecraft.core.component.PatchedDataComponentMap;
99
import net.minecraft.world.item.Items;
1010
import net.minecraft.world.item.trading.ItemCost;
@@ -139,11 +139,11 @@ public net.minecraft.world.item.trading.MerchantOffer toMinecraft() {
139139
List<ItemStack> ingredients = this.getIngredients();
140140
Preconditions.checkState(!ingredients.isEmpty(), "No offered ingredients");
141141
net.minecraft.world.item.ItemStack baseCostA = CraftItemStack.asNMSCopy(ingredients.get(0));
142-
DataComponentPredicate baseCostAPredicate = DataComponentPredicate.allOf(PatchedDataComponentMap.fromPatch(DataComponentMap.EMPTY, baseCostA.getComponentsPatch()));
142+
DataComponentExactPredicate baseCostAPredicate = DataComponentExactPredicate.allOf(PatchedDataComponentMap.fromPatch(DataComponentMap.EMPTY, baseCostA.getComponentsPatch()));
143143
this.handle.baseCostA = new ItemCost(baseCostA.getItemHolder(), baseCostA.getCount(), baseCostAPredicate, baseCostA);
144144
if (ingredients.size() > 1) {
145145
net.minecraft.world.item.ItemStack costB = CraftItemStack.asNMSCopy(ingredients.get(1));
146-
DataComponentPredicate costBPredicate = DataComponentPredicate.allOf(PatchedDataComponentMap.fromPatch(DataComponentMap.EMPTY, costB.getComponentsPatch()));
146+
DataComponentExactPredicate costBPredicate = DataComponentExactPredicate.allOf(PatchedDataComponentMap.fromPatch(DataComponentMap.EMPTY, costB.getComponentsPatch()));
147147
this.handle.costB = Optional.of(new ItemCost(costB.getItemHolder(), costB.getCount(), costBPredicate, costB));
148148
} else {
149149
this.handle.costB = Optional.empty();

0 commit comments

Comments
 (0)