Update to Minecraft 1.21

By: md_5 <git@md-5.net>
This commit is contained in:
CraftBukkit/Spigot
2024-06-14 01:05:00 +10:00
parent 7c6204e1a9
commit eed041d629
255 changed files with 3585 additions and 3261 deletions

View File

@@ -194,7 +194,7 @@ public class CraftChunk implements Chunk {
@Override
public boolean isGenerated() {
IChunkAccess chunk = getHandle(ChunkStatus.EMPTY);
return chunk.getStatus().isOrAfter(ChunkStatus.FULL);
return chunk.getPersistedStatus().isOrAfter(ChunkStatus.FULL);
}
@Override

View File

@@ -0,0 +1,65 @@
package org.bukkit.craftbukkit;
import com.google.common.base.Preconditions;
import net.minecraft.core.Holder;
import net.minecraft.core.IRegistry;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.contents.TranslatableContents;
import org.bukkit.JukeboxSong;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.craftbukkit.util.Handleable;
import org.jetbrains.annotations.NotNull;
public class CraftJukeboxSong implements JukeboxSong, Handleable<net.minecraft.world.item.JukeboxSong> {
public static JukeboxSong minecraftToBukkit(net.minecraft.world.item.JukeboxSong minecraft) {
return CraftRegistry.minecraftToBukkit(minecraft, Registries.JUKEBOX_SONG, Registry.JUKEBOX_SONG);
}
public static JukeboxSong minecraftHolderToBukkit(Holder<net.minecraft.world.item.JukeboxSong> minecraft) {
return minecraftToBukkit(minecraft.value());
}
public static net.minecraft.world.item.JukeboxSong bukkitToMinecraft(JukeboxSong bukkit) {
return CraftRegistry.bukkitToMinecraft(bukkit);
}
public static Holder<net.minecraft.world.item.JukeboxSong> bukkitToMinecraftHolder(JukeboxSong bukkit) {
Preconditions.checkArgument(bukkit != null);
IRegistry<net.minecraft.world.item.JukeboxSong> registry = CraftRegistry.getMinecraftRegistry(Registries.JUKEBOX_SONG);
if (registry.wrapAsHolder(bukkitToMinecraft(bukkit)) instanceof Holder.c<net.minecraft.world.item.JukeboxSong> holder) {
return holder;
}
throw new IllegalArgumentException("No Reference holder found for " + bukkit
+ ", this can happen if a plugin creates its own trim pattern without properly registering it.");
}
private final NamespacedKey key;
private final net.minecraft.world.item.JukeboxSong handle;
public CraftJukeboxSong(NamespacedKey key, net.minecraft.world.item.JukeboxSong handle) {
this.key = key;
this.handle = handle;
}
@Override
public net.minecraft.world.item.JukeboxSong getHandle() {
return handle;
}
@Override
@NotNull
public NamespacedKey getKey() {
return key;
}
@NotNull
@Override
public String getTranslationKey() {
return ((TranslatableContents) handle.description().getContents()).getKey();
}
}

View File

@@ -123,17 +123,12 @@ public class CraftLootTable implements org.bukkit.loot.LootTable {
if (context.getKiller() != null) {
EntityHuman nmsKiller = ((CraftHumanEntity) context.getKiller()).getHandle();
setMaybe(builder, LootContextParameters.KILLER_ENTITY, nmsKiller);
setMaybe(builder, LootContextParameters.ATTACKING_ENTITY, nmsKiller);
// If there is a player killer, damage source should reflect that in case loot tables use that information
setMaybe(builder, LootContextParameters.DAMAGE_SOURCE, handle.damageSources().playerAttack(nmsKiller));
setMaybe(builder, LootContextParameters.LAST_DAMAGE_PLAYER, nmsKiller); // SPIGOT-5603 - Set minecraft:killed_by_player
setMaybe(builder, LootContextParameters.TOOL, nmsKiller.getUseItem()); // SPIGOT-6925 - Set minecraft:match_tool
}
// SPIGOT-5603 - Use LootContext#lootingModifier
if (context.getLootingModifier() != LootContext.DEFAULT_LOOT_MODIFIER) {
setMaybe(builder, LootContextParameters.LOOTING_MOD, context.getLootingModifier());
}
}
// SPIGOT-5603 - Avoid IllegalArgumentException in LootTableInfo#build()
@@ -146,7 +141,6 @@ public class CraftLootTable implements org.bukkit.loot.LootTable {
nmsBuilder.optional(param);
}
}
nmsBuilder.optional(LootContextParameters.LOOTING_MOD);
return builder.create(getHandle().getParamSet());
}
@@ -165,8 +159,8 @@ public class CraftLootTable implements org.bukkit.loot.LootTable {
Location location = CraftLocation.toBukkit(position, info.getLevel().getWorld());
LootContext.Builder contextBuilder = new LootContext.Builder(location);
if (info.hasParam(LootContextParameters.KILLER_ENTITY)) {
CraftEntity killer = info.getParamOrNull(LootContextParameters.KILLER_ENTITY).getBukkitEntity();
if (info.hasParam(LootContextParameters.ATTACKING_ENTITY)) {
CraftEntity killer = info.getParamOrNull(LootContextParameters.ATTACKING_ENTITY).getBukkitEntity();
if (killer instanceof CraftHumanEntity) {
contextBuilder.killer((CraftHumanEntity) killer);
}
@@ -176,10 +170,6 @@ public class CraftLootTable implements org.bukkit.loot.LootTable {
contextBuilder.lootedEntity(info.getParamOrNull(LootContextParameters.THIS_ENTITY).getBukkitEntity());
}
if (info.hasParam(LootContextParameters.LOOTING_MOD)) {
contextBuilder.lootingModifier(info.getParamOrNull(LootContextParameters.LOOTING_MOD));
}
contextBuilder.luck(info.getLuck());
return contextBuilder.build();
}

View File

@@ -24,6 +24,7 @@ import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.IBlockData;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.feature.WorldGenFeatureConfigured;
import net.minecraft.world.level.portal.DimensionTransition;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.RegionAccessor;
@@ -418,7 +419,7 @@ public abstract class CraftRegionAccessor implements RegionAccessor {
Preconditions.checkArgument(!entity.isInWorld(), "Entity has already been added to a world");
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
if (nmsEntity.level() != getHandle().getLevel()) {
nmsEntity = nmsEntity.changeDimension(getHandle().getLevel());
nmsEntity = nmsEntity.changeDimension(new DimensionTransition(getHandle().getLevel(), nmsEntity, DimensionTransition.DO_NOTHING));
}
addEntityWithPassengers(nmsEntity, CreatureSpawnEvent.SpawnReason.CUSTOM);

View File

@@ -13,6 +13,7 @@ import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import org.bukkit.GameEvent;
import org.bukkit.JukeboxSong;
import org.bukkit.Keyed;
import org.bukkit.MusicInstrument;
import org.bukkit.NamespacedKey;
@@ -146,6 +147,9 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
if (bukkitClass == DamageType.class) {
return new CraftRegistry<>(DamageType.class, registryHolder.registryOrThrow(Registries.DAMAGE_TYPE), CraftDamageType::new, FieldRename.NONE);
}
if (bukkitClass == JukeboxSong.class) {
return new CraftRegistry<>(JukeboxSong.class, registryHolder.registryOrThrow(Registries.JUKEBOX_SONG), CraftJukeboxSong::new, FieldRename.NONE);
}
if (bukkitClass == Wolf.Variant.class) {
return new CraftRegistry<>(Wolf.Variant.class, registryHolder.registryOrThrow(Registries.WOLF_VARIANT), CraftWolf.CraftVariant::new, FieldRename.NONE);
}

View File

@@ -127,6 +127,7 @@ import org.bukkit.NamespacedKey;
import org.bukkit.OfflinePlayer;
import org.bukkit.Registry;
import org.bukkit.Server;
import org.bukkit.ServerLinks;
import org.bukkit.ServerTickManager;
import org.bukkit.StructureType;
import org.bukkit.UnsafeValues;
@@ -296,6 +297,7 @@ public final class CraftServer implements Server {
public CraftScoreboardManager scoreboardManager;
public CraftDataPackManager dataPackManager;
private CraftServerTickManager serverTickManager;
private CraftServerLinks serverLinks;
public boolean playerCommandState;
private boolean printSaveWarning;
private CraftIconCache icon;
@@ -325,6 +327,7 @@ public final class CraftServer implements Server {
this.structureManager = new CraftStructureManager(console.getStructureManager(), console.registryAccess());
this.dataPackManager = new CraftDataPackManager(this.getServer().getPackRepository());
this.serverTickManager = new CraftServerTickManager(console.tickRateManager());
this.serverLinks = new CraftServerLinks(console);
Bukkit.setServer(this);
@@ -706,7 +709,7 @@ public final class CraftServer implements Server {
@Override
public boolean getAllowNether() {
return this.getServer().isNetherEnabled();
return this.getProperties().allowNether;
}
@Override
@@ -1203,7 +1206,7 @@ public final class CraftServer implements Server {
} else if (name.equals(levelName + "_the_end")) {
worldKey = net.minecraft.world.level.World.END;
} else {
worldKey = ResourceKey.create(Registries.DIMENSION, new MinecraftKey(name.toLowerCase(Locale.ROOT)));
worldKey = ResourceKey.create(Registries.DIMENSION, MinecraftKey.withDefaultNamespace(name.toLowerCase(Locale.ROOT)));
}
// If set to not keep spawn in memory (changed from default) then adjust rule accordingly
@@ -1452,7 +1455,7 @@ public final class CraftServer implements Server {
if (recipe.isPresent()) {
RecipeHolder<RecipeCrafting> recipeCrafting = recipe.get();
if (craftResult.setRecipeUsed(craftWorld.getHandle(), craftPlayer.getHandle(), recipeCrafting)) {
itemstack = recipeCrafting.value().assemble(inventoryCrafting, craftWorld.getHandle().registryAccess());
itemstack = recipeCrafting.value().assemble(inventoryCrafting.asCraftInput(), craftWorld.getHandle().registryAccess());
}
}
@@ -1482,7 +1485,7 @@ public final class CraftServer implements Server {
net.minecraft.world.item.ItemStack itemStack = net.minecraft.world.item.ItemStack.EMPTY;
if (recipe.isPresent()) {
itemStack = recipe.get().value().assemble(inventoryCrafting, craftWorld.getHandle().registryAccess());
itemStack = recipe.get().value().assemble(inventoryCrafting.asCraftInput(), craftWorld.getHandle().registryAccess());
}
return createItemCraftResult(CraftItemStack.asBukkitCopy(itemStack), inventoryCrafting, craftWorld.getHandle());
@@ -1490,7 +1493,7 @@ public final class CraftServer implements Server {
private CraftItemCraftResult createItemCraftResult(ItemStack itemStack, InventoryCrafting inventoryCrafting, WorldServer worldServer) {
CraftItemCraftResult craftItemResult = new CraftItemCraftResult(itemStack);
NonNullList<net.minecraft.world.item.ItemStack> remainingItems = getServer().getRecipeManager().getRemainingItemsFor(Recipes.CRAFTING, inventoryCrafting, worldServer);
NonNullList<net.minecraft.world.item.ItemStack> remainingItems = getServer().getRecipeManager().getRemainingItemsFor(Recipes.CRAFTING, inventoryCrafting.asCraftInput(), worldServer);
// Set the resulting matrix items and overflow items
for (int i = 0; i < remainingItems.size(); ++i) {
@@ -1530,7 +1533,7 @@ public final class CraftServer implements Server {
inventoryCrafting.setItem(i, CraftItemStack.asNMSCopy(craftingMatrix[i]));
}
return getServer().getRecipeManager().getRecipeFor(Recipes.CRAFTING, inventoryCrafting, world.getHandle());
return getServer().getRecipeManager().getRecipeFor(Recipes.CRAFTING, inventoryCrafting.asCraftInput(), world.getHandle());
}
@Override
@@ -2133,6 +2136,11 @@ public final class CraftServer implements Server {
console.setMotd(motd);
}
@Override
public ServerLinks getServerLinks() {
return this.serverLinks;
}
@Override
public WarningState getWarningState() {
return warningState;

View File

@@ -0,0 +1,142 @@
package org.bukkit.craftbukkit;
import com.google.common.base.Preconditions;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.server.dedicated.DedicatedServer;
import org.bukkit.ServerLinks;
import org.bukkit.craftbukkit.util.CraftChatMessage;
public class CraftServerLinks implements ServerLinks {
private final DedicatedServer server;
private net.minecraft.server.ServerLinks serverLinks;
public CraftServerLinks(DedicatedServer server) {
this(server, null);
}
public CraftServerLinks(net.minecraft.server.ServerLinks serverLinks) {
this(null, serverLinks);
}
private CraftServerLinks(DedicatedServer server, net.minecraft.server.ServerLinks serverLinks) {
this.server = server;
this.serverLinks = serverLinks;
}
@Override
public ServerLink getLink(Type type) {
Preconditions.checkArgument(type != null, "type cannot be null");
return getServerLinks().findKnownType(fromBukkit(type)).map(CraftServerLink::new).orElse(null);
}
@Override
public List<ServerLink> getLinks() {
return getServerLinks().entries().stream().map(nms -> (ServerLink) new CraftServerLink(nms)).toList();
}
@Override
public ServerLink setLink(Type type, URI url) {
Preconditions.checkArgument(type != null, "type cannot be null");
Preconditions.checkArgument(url != null, "url cannot be null");
ServerLink existing = getLink(type);
if (existing != null) {
removeLink(existing);
}
return addLink(type, url);
}
@Override
public ServerLink addLink(Type type, URI url) {
Preconditions.checkArgument(type != null, "type cannot be null");
Preconditions.checkArgument(url != null, "url cannot be null");
CraftServerLink link = new CraftServerLink(net.minecraft.server.ServerLinks.Entry.knownType(fromBukkit(type), url));
addLink(link);
return link;
}
@Override
public ServerLink addLink(String displayName, URI url) {
Preconditions.checkArgument(displayName != null, "displayName cannot be null");
Preconditions.checkArgument(url != null, "url cannot be null");
CraftServerLink link = new CraftServerLink(net.minecraft.server.ServerLinks.Entry.custom(CraftChatMessage.fromStringOrNull(displayName), url));
addLink(link);
return link;
}
private void addLink(CraftServerLink link) {
List<net.minecraft.server.ServerLinks.Entry> lst = new ArrayList<>(getServerLinks().entries());
lst.add(link.handle);
setLinks(new net.minecraft.server.ServerLinks(lst));
}
@Override
public boolean removeLink(ServerLink link) {
Preconditions.checkArgument(link != null, "link cannot be null");
List<net.minecraft.server.ServerLinks.Entry> lst = new ArrayList<>(getServerLinks().entries());
boolean result = lst.remove(((CraftServerLink) link).handle);
setLinks(new net.minecraft.server.ServerLinks(lst));
return result;
}
@Override
public ServerLinks copy() {
return new CraftServerLinks(getServerLinks());
}
public net.minecraft.server.ServerLinks getServerLinks() {
return (server != null) ? server.serverLinks() : serverLinks;
}
private void setLinks(net.minecraft.server.ServerLinks links) {
if (server != null) {
server.serverLinks = links;
} else {
this.serverLinks = links;
}
}
private static net.minecraft.server.ServerLinks.KnownLinkType fromBukkit(Type type) {
return net.minecraft.server.ServerLinks.KnownLinkType.values()[type.ordinal()];
}
private static ServerLinks.Type fromNMS(net.minecraft.server.ServerLinks.KnownLinkType nms) {
return ServerLinks.Type.values()[nms.ordinal()];
}
public static class CraftServerLink implements ServerLink {
private final net.minecraft.server.ServerLinks.Entry handle;
public CraftServerLink(net.minecraft.server.ServerLinks.Entry handle) {
this.handle = handle;
}
@Override
public Type getType() {
return handle.type().left().map(CraftServerLinks::fromNMS).orElse(null);
}
@Override
public String getDisplayName() {
return CraftChatMessage.fromComponent(handle.displayName());
}
@Override
public URI getUrl() {
return handle.link();
}
}
}

View File

@@ -31,8 +31,8 @@ public enum CraftStatistic {
LEAVE_GAME(StatisticList.LEAVE_GAME),
JUMP(StatisticList.JUMP),
DROP_COUNT(StatisticList.DROP),
DROP(new MinecraftKey("dropped")),
PICKUP(new MinecraftKey("picked_up")),
DROP(MinecraftKey.withDefaultNamespace("dropped")),
PICKUP(MinecraftKey.withDefaultNamespace("picked_up")),
PLAY_ONE_MINUTE(StatisticList.PLAY_TIME),
TOTAL_WORLD_TIME(StatisticList.TOTAL_WORLD_TIME),
WALK_ONE_CM(StatisticList.WALK_ONE_CM),
@@ -49,12 +49,12 @@ public enum CraftStatistic {
SPRINT_ONE_CM(StatisticList.SPRINT_ONE_CM),
CROUCH_ONE_CM(StatisticList.CROUCH_ONE_CM),
AVIATE_ONE_CM(StatisticList.AVIATE_ONE_CM),
MINE_BLOCK(new MinecraftKey("mined")),
USE_ITEM(new MinecraftKey("used")),
BREAK_ITEM(new MinecraftKey("broken")),
CRAFT_ITEM(new MinecraftKey("crafted")),
KILL_ENTITY(new MinecraftKey("killed")),
ENTITY_KILLED_BY(new MinecraftKey("killed_by")),
MINE_BLOCK(MinecraftKey.withDefaultNamespace("mined")),
USE_ITEM(MinecraftKey.withDefaultNamespace("used")),
BREAK_ITEM(MinecraftKey.withDefaultNamespace("broken")),
CRAFT_ITEM(MinecraftKey.withDefaultNamespace("crafted")),
KILL_ENTITY(MinecraftKey.withDefaultNamespace("killed")),
ENTITY_KILLED_BY(MinecraftKey.withDefaultNamespace("killed_by")),
TIME_SINCE_DEATH(StatisticList.TIME_SINCE_DEATH),
TALKED_TO_VILLAGER(StatisticList.TALKED_TO_VILLAGER),
TRADED_WITH_VILLAGER(StatisticList.TRADED_WITH_VILLAGER),

View File

@@ -1663,7 +1663,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
double y = loc.getY();
double z = loc.getZ();
PacketPlayOutNamedSoundEffect packet = new PacketPlayOutNamedSoundEffect(Holder.direct(SoundEffect.createVariableRangeEvent(new MinecraftKey(sound))), SoundCategory.valueOf(category.name()), x, y, z, volume, pitch, seed);
PacketPlayOutNamedSoundEffect packet = new PacketPlayOutNamedSoundEffect(Holder.direct(SoundEffect.createVariableRangeEvent(MinecraftKey.parse(sound))), SoundCategory.valueOf(category.name()), x, y, z, volume, pitch, seed);
world.getServer().getPlayerList().broadcast(null, x, y, z, volume > 1.0F ? 16.0F * volume : 16.0D, this.world.dimension(), packet);
}
@@ -1702,7 +1702,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
public void playSound(Entity entity, String sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) {
if (!(entity instanceof CraftEntity craftEntity) || entity.getWorld() != this || sound == null || category == null) return;
PacketPlayOutEntitySound packet = new PacketPlayOutEntitySound(Holder.direct(SoundEffect.createVariableRangeEvent(new MinecraftKey(sound))), net.minecraft.sounds.SoundCategory.valueOf(category.name()), craftEntity.getHandle(), volume, pitch, seed);
PacketPlayOutEntitySound packet = new PacketPlayOutEntitySound(Holder.direct(SoundEffect.createVariableRangeEvent(MinecraftKey.parse(sound))), net.minecraft.sounds.SoundCategory.valueOf(category.name()), craftEntity.getHandle(), volume, pitch, seed);
PlayerChunkMap.EntityTracker entityTracker = getHandle().getChunkSource().chunkMap.entityMap.get(entity.getEntityId());
if (entityTracker != null) {
entityTracker.broadcastAndSend(packet);

View File

@@ -201,11 +201,11 @@ public class Main {
useConsole = false;
}
if (false && Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) {
if (Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) {
Date buildDate = new Date(Integer.parseInt(Main.class.getPackage().getImplementationVendor()) * 1000L);
Calendar deadline = Calendar.getInstance();
deadline.add(Calendar.DAY_OF_YEAR, -21);
deadline.add(Calendar.DAY_OF_YEAR, -3);
if (buildDate.before(deadline.getTime())) {
System.err.println("*** Error, this build is outdated ***");
System.err.println("*** Please download a new build as per instructions from https://www.spigotmc.org/go/outdated-spigot ***");

View File

@@ -7,6 +7,7 @@ import java.util.List;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeInstance;
import org.bukkit.attribute.AttributeModifier;
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
import org.bukkit.inventory.EquipmentSlot;
public class CraftAttributeInstance implements AttributeInstance {
@@ -67,14 +68,14 @@ public class CraftAttributeInstance implements AttributeInstance {
}
public static net.minecraft.world.entity.ai.attributes.AttributeModifier convert(AttributeModifier bukkit) {
return new net.minecraft.world.entity.ai.attributes.AttributeModifier(bukkit.getUniqueId(), bukkit.getName(), bukkit.getAmount(), net.minecraft.world.entity.ai.attributes.AttributeModifier.Operation.values()[bukkit.getOperation().ordinal()]);
return new net.minecraft.world.entity.ai.attributes.AttributeModifier(CraftNamespacedKey.toMinecraft(bukkit.getKey()), bukkit.getAmount(), net.minecraft.world.entity.ai.attributes.AttributeModifier.Operation.values()[bukkit.getOperation().ordinal()]);
}
public static AttributeModifier convert(net.minecraft.world.entity.ai.attributes.AttributeModifier nms) {
return new AttributeModifier(nms.id(), nms.name, nms.amount(), AttributeModifier.Operation.values()[nms.operation().ordinal()]);
return new AttributeModifier(CraftNamespacedKey.fromMinecraft(nms.id()), nms.amount(), AttributeModifier.Operation.values()[nms.operation().ordinal()], org.bukkit.inventory.EquipmentSlotGroup.ANY);
}
public static AttributeModifier convert(net.minecraft.world.entity.ai.attributes.AttributeModifier nms, EquipmentSlot slot) {
return new AttributeModifier(nms.id(), nms.name, nms.amount(), AttributeModifier.Operation.values()[nms.operation().ordinal()], slot);
return new AttributeModifier(CraftNamespacedKey.fromMinecraft(nms.id()), nms.amount(), AttributeModifier.Operation.values()[nms.operation().ordinal()], slot.getGroup());
}
}

View File

@@ -4,12 +4,10 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.BlockJukeBox;
import net.minecraft.world.level.block.entity.TileEntity;
import net.minecraft.world.level.block.entity.TileEntityJukeBox;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Jukebox;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.inventory.CraftInventoryJukebox;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.inventory.CraftItemType;
@@ -44,18 +42,11 @@ public class CraftJukebox extends CraftBlockEntityState<TileEntityJukeBox> imple
boolean result = super.update(force, applyPhysics);
if (result && this.isPlaced() && this.getType() == Material.JUKEBOX) {
Material record = this.getPlaying();
getWorldHandle().setBlock(this.getPosition(), data, 3);
TileEntity tileEntity = this.getTileEntityFromWorld();
if (tileEntity instanceof TileEntityJukeBox jukebox) {
CraftWorld world = (CraftWorld) this.getWorld();
if (record.isAir()) {
jukebox.setRecordWithoutPlaying(ItemStack.EMPTY);
world.playEffect(this.getLocation(), Effect.IRON_DOOR_CLOSE, 0); // TODO: Fix this enum constant. This stops jukeboxes
} else {
world.playEffect(this.getLocation(), Effect.RECORD_PLAY, record);
}
jukebox.setTheItem(jukebox.getTheItem());
}
}
@@ -92,9 +83,7 @@ public class CraftJukebox extends CraftBlockEntityState<TileEntityJukeBox> imple
ItemStack nms = CraftItemStack.asNMSCopy(record);
TileEntityJukeBox snapshot = this.getSnapshot();
snapshot.setRecordWithoutPlaying(nms);
snapshot.recordStartedTick = snapshot.tickCount;
snapshot.isPlaying = !nms.isEmpty();
snapshot.setSongItemWithoutPlaying(nms, snapshot.getSongPlayer().getTicksSinceSongStarted());
this.data = this.data.setValue(BlockJukeBox.HAS_RECORD, !nms.isEmpty());
}
@@ -104,7 +93,7 @@ public class CraftJukebox extends CraftBlockEntityState<TileEntityJukeBox> imple
requirePlaced();
TileEntity tileEntity = this.getTileEntityFromWorld();
return tileEntity instanceof TileEntityJukeBox jukebox && jukebox.isRecordPlaying();
return tileEntity instanceof TileEntityJukeBox jukebox && jukebox.getSongPlayer().isPlaying();
}
@Override
@@ -121,9 +110,7 @@ public class CraftJukebox extends CraftBlockEntityState<TileEntityJukeBox> imple
return false;
}
jukebox.isPlaying = true;
jukebox.recordStartedTick = jukebox.tickCount;
getWorld().playEffect(getLocation(), Effect.RECORD_PLAY, CraftItemType.minecraftToBukkit(record.getItem()));
jukebox.tryForcePlaySong();
return true;
}
@@ -136,8 +123,7 @@ public class CraftJukebox extends CraftBlockEntityState<TileEntityJukeBox> imple
return;
}
jukebox.isPlaying = false;
getWorld().playEffect(getLocation(), Effect.IRON_DOOR_CLOSE, 0); // TODO: Fix this enum constant. This stops jukeboxes
jukebox.getSongPlayer().stop(tileEntity.getLevel(), tileEntity.getBlockState());
}
@Override
@@ -149,7 +135,7 @@ public class CraftJukebox extends CraftBlockEntityState<TileEntityJukeBox> imple
TileEntityJukeBox jukebox = (TileEntityJukeBox) tileEntity;
boolean result = !jukebox.getTheItem().isEmpty();
jukebox.popOutRecord();
jukebox.popOutTheItem();
return result;
}

View File

@@ -2,11 +2,10 @@ package org.bukkit.craftbukkit.enchantments;
import com.google.common.base.Preconditions;
import java.util.Locale;
import net.minecraft.SystemUtils;
import net.minecraft.core.Holder;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.item.enchantment.EnchantmentBinding;
import net.minecraft.world.item.enchantment.EnchantmentVanishing;
import net.minecraft.tags.EnchantmentTags;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.craftbukkit.CraftRegistry;
@@ -33,6 +32,10 @@ public class CraftEnchantment extends Enchantment implements Handleable<net.mine
return CraftRegistry.bukkitToMinecraft(bukkit);
}
public static Holder<net.minecraft.world.item.enchantment.Enchantment> bukkitToMinecraftHolder(Enchantment bukkit) {
return CraftRegistry.bukkitToMinecraftHolder(bukkit, Registries.ENCHANTMENT);
}
public static String bukkitToString(Enchantment bukkit) {
Preconditions.checkArgument(bukkit != null);
@@ -53,18 +56,18 @@ public class CraftEnchantment extends Enchantment implements Handleable<net.mine
}
private final NamespacedKey key;
private final net.minecraft.world.item.enchantment.Enchantment handle;
private final Holder<net.minecraft.world.item.enchantment.Enchantment> handle;
private final int id;
public CraftEnchantment(NamespacedKey key, net.minecraft.world.item.enchantment.Enchantment handle) {
this.key = key;
this.handle = handle;
this.id = BuiltInRegistries.ENCHANTMENT.getId(handle);
this.handle = CraftRegistry.getMinecraftRegistry(Registries.ENCHANTMENT).wrapAsHolder(handle);
this.id = CraftRegistry.getMinecraftRegistry(Registries.ENCHANTMENT).getId(handle);
}
@Override
public net.minecraft.world.item.enchantment.Enchantment getHandle() {
return handle;
return handle.value();
}
@Override
@@ -74,12 +77,12 @@ public class CraftEnchantment extends Enchantment implements Handleable<net.mine
@Override
public int getMaxLevel() {
return handle.getMaxLevel();
return getHandle().getMaxLevel();
}
@Override
public int getStartLevel() {
return handle.getMinLevel();
return getHandle().getMinLevel();
}
@Override
@@ -89,17 +92,17 @@ public class CraftEnchantment extends Enchantment implements Handleable<net.mine
@Override
public boolean isTreasure() {
return handle.isTreasureOnly();
return !handle.is(EnchantmentTags.IN_ENCHANTING_TABLE);
}
@Override
public boolean isCursed() {
return handle instanceof EnchantmentBinding || handle instanceof EnchantmentVanishing;
return handle.is(EnchantmentTags.CURSE);
}
@Override
public boolean canEnchantItem(ItemStack item) {
return handle.canEnchant(CraftItemStack.asNMSCopy(item));
return getHandle().canEnchant(CraftItemStack.asNMSCopy(item));
}
@Override
@@ -161,12 +164,12 @@ public class CraftEnchantment extends Enchantment implements Handleable<net.mine
return false;
}
CraftEnchantment ench = (CraftEnchantment) other;
return !handle.isCompatibleWith(ench.getHandle());
return !net.minecraft.world.item.enchantment.Enchantment.areCompatible(handle, ench.handle);
}
@Override
public String getTranslationKey() {
return handle.getDescriptionId();
return SystemUtils.makeDescriptionId("enchantment", handle.unwrapKey().get().location());
}
@Override

View File

@@ -19,13 +19,11 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr
@Override
public void setKnockbackStrength(int knockbackStrength) {
Preconditions.checkArgument(knockbackStrength >= 0, "Knockback value (%s) cannot be negative", knockbackStrength);
getHandle().setKnockback(knockbackStrength);
}
@Override
public int getKnockbackStrength() {
return getHandle().knockback;
return 0;
}
@Override
@@ -117,7 +115,6 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr
@Override
public void setShotFromCrossbow(boolean shotFromCrossbow) {
getHandle().setShotFromCrossbow(shotFromCrossbow);
}
@Override
@@ -132,6 +129,18 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr
getHandle().pickupItemStack = CraftItemStack.asNMSCopy(item);
}
@Override
public ItemStack getWeapon() {
return CraftItemStack.asBukkitCopy(getHandle().getWeaponItem());
}
@Override
public void setWeapon(ItemStack item) {
Preconditions.checkArgument(item != null, "ItemStack cannot be null");
getHandle().firedFromWeapon = CraftItemStack.asNMSCopy(item);
}
@Override
public EntityArrow getHandle() {
return (EntityArrow) entity;

View File

@@ -11,7 +11,7 @@ public abstract class CraftAbstractWindCharge extends CraftFireball implements A
@Override
public void explode() {
this.getHandle().explode();
this.getHandle().explode(this.getHandle().position());
this.getHandle().discard(EntityRemoveEvent.Cause.EXPLODE); // SPIGOT-7577 - explode doesn't discard the entity, this happens only in tick and onHitBlock
}

View File

@@ -0,0 +1,20 @@
package org.bukkit.craftbukkit.entity;
import net.minecraft.world.entity.decoration.BlockAttachedEntity;
import org.bukkit.craftbukkit.CraftServer;
public class CraftBlockAttachedEntity extends CraftEntity {
public CraftBlockAttachedEntity(CraftServer server, BlockAttachedEntity entity) {
super(server, entity);
}
@Override
public BlockAttachedEntity getHandle() {
return (BlockAttachedEntity) entity;
}
@Override
public String toString() {
return "CraftBlockAttachedEntity";
}
}

View File

@@ -21,7 +21,9 @@ import net.minecraft.world.entity.boss.EntityComplexPart;
import net.minecraft.world.entity.boss.enderdragon.EntityEnderDragon;
import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.entity.projectile.EntityArrow;
import net.minecraft.world.level.portal.DimensionTransition;
import net.minecraft.world.phys.AxisAlignedBB;
import net.minecraft.world.phys.Vec3D;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.Server;
@@ -202,7 +204,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
if (location.getWorld() != null && !location.getWorld().equals(getWorld())) {
// Prevent teleportation to an other world during world generation
Preconditions.checkState(!entity.generation, "Cannot teleport entity to an other world during world generation");
entity.teleportTo(((CraftWorld) location.getWorld()).getHandle(), CraftLocation.toVec3D(location));
entity.changeDimension(new DimensionTransition(((CraftWorld) location.getWorld()).getHandle(), CraftLocation.toVec3D(location), Vec3D.ZERO, location.getPitch(), location.getYaw(), DimensionTransition.DO_NOTHING, TeleportCause.PLUGIN));
return true;
}
@@ -856,7 +858,22 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
return;
}
entityTracker.broadcast(getHandle().getAddEntityPacket());
entityTracker.broadcast(getHandle().getAddEntityPacket(entityTracker.serverEntity));
}
public void update(EntityPlayer player) {
if (!getHandle().isAlive()) {
return;
}
WorldServer world = ((CraftWorld) getWorld()).getHandle();
PlayerChunkMap.EntityTracker entityTracker = world.getChunkSource().chunkMap.entityMap.get(getEntityId());
if (entityTracker == null) {
return;
}
player.connection.send(getHandle().getAddEntityPacket(entityTracker.serverEntity));
}
private static PermissibleBase getPermissibleBase() {

View File

@@ -41,6 +41,7 @@ import net.minecraft.world.level.World;
import net.minecraft.world.level.block.BlockDiodeAbstract;
import net.minecraft.world.level.block.state.IBlockData;
import net.minecraft.world.phys.AxisAlignedBB;
import net.minecraft.world.phys.Vec3D;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -226,8 +227,8 @@ public final class CraftEntityTypes {
private static final BiConsumer<SpawnData, net.minecraft.world.entity.Entity> MOVE = (spawnData, entity) -> entity.moveTo(spawnData.x(), spawnData.y(), spawnData.z(), spawnData.yaw(), spawnData.pitch());
private static final BiConsumer<SpawnData, net.minecraft.world.entity.Entity> MOVE_EMPTY_ROT = (spawnData, entity) -> entity.moveTo(spawnData.x(), spawnData.y(), spawnData.z(), 0, 0);
private static final BiConsumer<SpawnData, EntityFireball> DIRECTION = (spawnData, entity) -> {
Vector direction = spawnData.location().getDirection().multiply(10);
entity.assignPower(direction.getX(), direction.getY(), direction.getZ());
Vector direction = spawnData.location().getDirection();
entity.assignDirectionalMovement(new Vec3D(direction.getX(), direction.getY(), direction.getZ()), 1.0);
};
private static final Map<Class<?>, EntityTypeData<?, ?>> CLASS_TYPE_DATA = new HashMap<>();
private static final Map<EntityType, EntityTypeData<?, ?>> ENTITY_TYPE_DATA = new HashMap<>();
@@ -472,8 +473,8 @@ public final class CraftEntityTypes {
if (nmsBlock.isSolid() || BlockDiodeAbstract.isDiode(nmsBlock)) {
boolean taken = false;
AxisAlignedBB bb = (ItemFrame.class.isAssignableFrom(clazz))
? EntityItemFrame.calculateBoundingBox(null, pos, CraftBlock.blockFaceToNotch(dir).getOpposite(), width, height)
: EntityHanging.calculateBoundingBox(null, pos, CraftBlock.blockFaceToNotch(dir).getOpposite(), width, height);
? EntityItemFrame.calculateBoundingBoxStatic(pos, CraftBlock.blockFaceToNotch(dir).getOpposite())
: EntityPainting.calculateBoundingBoxStatic(pos, CraftBlock.blockFaceToNotch(dir).getOpposite(), width, height);
List<net.minecraft.world.entity.Entity> list = spawnData.world().getEntities(null, bb);
for (Iterator<net.minecraft.world.entity.Entity> it = list.iterator(); !taken && it.hasNext(); ) {
net.minecraft.world.entity.Entity e = it.next();

View File

@@ -2,6 +2,7 @@ package org.bukkit.craftbukkit.entity;
import com.google.common.base.Preconditions;
import net.minecraft.world.entity.projectile.EntityFireball;
import net.minecraft.world.phys.Vec3D;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.entity.Fireball;
import org.bukkit.projectiles.ProjectileSource;
@@ -72,16 +73,15 @@ public class CraftFireball extends AbstractProjectile implements Fireball {
Preconditions.checkArgument(acceleration != null, "Vector acceleration cannot be null");
// SPIGOT-6993: EntityFireball#assignPower will normalize the given values
// Note: Because of MC-80142 the fireball will stutter on the client when setting the power to something other than 0 or the normalized vector * 0.1
getHandle().xPower = acceleration.getX();
getHandle().yPower = acceleration.getY();
getHandle().zPower = acceleration.getZ();
getHandle().assignDirectionalMovement(new Vec3D(acceleration.getX(), acceleration.getY(), acceleration.getZ()), acceleration.length());
update(); // SPIGOT-6579
}
@NotNull
@Override
public Vector getAcceleration() {
return new Vector(getHandle().xPower, getHandle().yPower, getHandle().zPower);
Vec3D delta = getHandle().getDeltaMovement();
return new Vector(delta.x, delta.y, delta.z);
}
@Override

View File

@@ -7,7 +7,7 @@ import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.block.CraftBlock;
import org.bukkit.entity.Hanging;
public class CraftHanging extends CraftEntity implements Hanging {
public class CraftHanging extends CraftBlockAttachedEntity implements Hanging {
public CraftHanging(CraftServer server, EntityHanging entity) {
super(server, entity);
}

View File

@@ -46,7 +46,7 @@ public class CraftItemFrame extends CraftHanging implements ItemFrame {
// update redstone
if (!getHandle().generation) {
getHandle().level().updateNeighbourForOutputSignal(getHandle().pos, Blocks.AIR);
getHandle().level().updateNeighbourForOutputSignal(getHandle().getPos(), Blocks.AIR);
}
}

View File

@@ -6,7 +6,7 @@ import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.entity.LeashHitch;
public class CraftLeash extends CraftHanging implements LeashHitch {
public class CraftLeash extends CraftBlockAttachedEntity implements LeashHitch {
public CraftLeash(CraftServer server, EntityLeash entity) {
super(server, entity);
}
@@ -24,6 +24,17 @@ public class CraftLeash extends CraftHanging implements LeashHitch {
return BlockFace.SELF;
}
@Override
public BlockFace getAttachedFace() {
// Leash hitch has no facing direction, so we return self
return BlockFace.SELF;
}
@Override
public void setFacingDirection(BlockFace face) {
// Leash hitch has no facing direction
}
@Override
public EntityLeash getHandle() {
return (EntityLeash) entity;

View File

@@ -40,6 +40,7 @@ import net.minecraft.world.entity.projectile.EntityThrownExpBottle;
import net.minecraft.world.entity.projectile.EntityThrownTrident;
import net.minecraft.world.entity.projectile.EntityTippedArrow;
import net.minecraft.world.entity.projectile.EntityWitherSkull;
import net.minecraft.world.phys.Vec3D;
import org.bukkit.FluidCollisionMode;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -462,14 +463,14 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
((EntityProjectile) launch).shootFromRotation(getHandle(), getHandle().getXRot(), getHandle().getYRot(), 0.0F, 1.5F, 1.0F); // ItemEnderPearl
} else if (AbstractArrow.class.isAssignableFrom(projectile)) {
if (TippedArrow.class.isAssignableFrom(projectile)) {
launch = new EntityTippedArrow(world, getHandle(), new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.ARROW));
launch = new EntityTippedArrow(world, getHandle(), new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.ARROW), null);
((Arrow) launch.getBukkitEntity()).setBasePotionType(PotionType.WATER);
} else if (SpectralArrow.class.isAssignableFrom(projectile)) {
launch = new EntitySpectralArrow(world, getHandle(), new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.SPECTRAL_ARROW));
launch = new EntitySpectralArrow(world, getHandle(), new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.SPECTRAL_ARROW), null);
} else if (Trident.class.isAssignableFrom(projectile)) {
launch = new EntityThrownTrident(world, getHandle(), new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.TRIDENT));
} else {
launch = new EntityTippedArrow(world, getHandle(), new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.ARROW));
launch = new EntityTippedArrow(world, getHandle(), new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.ARROW), null);
}
((EntityArrow) launch).shootFromRotation(getHandle(), getHandle().getXRot(), getHandle().getYRot(), 0.0F, 3.0F, 1.0F); // ItemBow
} else if (ThrownPotion.class.isAssignableFrom(projectile)) {
@@ -489,19 +490,20 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
} else if (Fireball.class.isAssignableFrom(projectile)) {
Location location = getEyeLocation();
Vector direction = location.getDirection().multiply(10);
Vec3D vec = new Vec3D(direction.getX(), direction.getY(), direction.getZ());
if (SmallFireball.class.isAssignableFrom(projectile)) {
launch = new EntitySmallFireball(world, getHandle(), direction.getX(), direction.getY(), direction.getZ());
launch = new EntitySmallFireball(world, getHandle(), vec);
} else if (WitherSkull.class.isAssignableFrom(projectile)) {
launch = new EntityWitherSkull(world, getHandle(), direction.getX(), direction.getY(), direction.getZ());
launch = new EntityWitherSkull(world, getHandle(), vec);
} else if (DragonFireball.class.isAssignableFrom(projectile)) {
launch = new EntityDragonFireball(world, getHandle(), direction.getX(), direction.getY(), direction.getZ());
launch = new EntityDragonFireball(world, getHandle(), vec);
} else if (WindCharge.class.isAssignableFrom(projectile)) {
launch = EntityTypes.WIND_CHARGE.create(world);
((net.minecraft.world.entity.projectile.windcharge.WindCharge) launch).setOwner(getHandle());
((net.minecraft.world.entity.projectile.windcharge.WindCharge) launch).assignPower(direction.getX(), direction.getY(), direction.getZ());
((net.minecraft.world.entity.projectile.windcharge.WindCharge) launch).assignDirectionalMovement(vec, 0.1D);
} else {
launch = new EntityLargeFireball(world, getHandle(), direction.getX(), direction.getY(), direction.getZ(), 1);
launch = new EntityLargeFireball(world, getHandle(), vec, 1);
}
((EntityFireball) launch).projectileSource = this;

View File

@@ -47,6 +47,7 @@ import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket;
import net.minecraft.network.protocol.common.ClientboundResourcePackPopPacket;
import net.minecraft.network.protocol.common.ClientboundResourcePackPushPacket;
import net.minecraft.network.protocol.common.ClientboundServerLinksPacket;
import net.minecraft.network.protocol.common.ClientboundStoreCookiePacket;
import net.minecraft.network.protocol.common.ClientboundTransferPacket;
import net.minecraft.network.protocol.common.custom.DiscardedPayload;
@@ -98,7 +99,6 @@ import net.minecraft.world.entity.EnumItemSlot;
import net.minecraft.world.entity.ai.attributes.AttributeMapBase;
import net.minecraft.world.entity.ai.attributes.AttributeModifiable;
import net.minecraft.world.entity.ai.attributes.GenericAttributes;
import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.food.FoodMetaData;
import net.minecraft.world.inventory.Container;
import net.minecraft.world.item.EnumColor;
@@ -111,7 +111,6 @@ import net.minecraft.world.level.border.IWorldBorderListener;
import net.minecraft.world.level.saveddata.maps.MapIcon;
import net.minecraft.world.level.saveddata.maps.MapId;
import net.minecraft.world.level.saveddata.maps.WorldMap;
import net.minecraft.world.phys.Vec3D;
import org.bukkit.BanEntry;
import org.bukkit.BanList;
import org.bukkit.Bukkit;
@@ -125,6 +124,7 @@ import org.bukkit.NamespacedKey;
import org.bukkit.Note;
import org.bukkit.OfflinePlayer;
import org.bukkit.Particle;
import org.bukkit.ServerLinks;
import org.bukkit.Sound;
import org.bukkit.Statistic;
import org.bukkit.WeatherType;
@@ -146,6 +146,7 @@ import org.bukkit.craftbukkit.CraftEquipmentSlot;
import org.bukkit.craftbukkit.CraftOfflinePlayer;
import org.bukkit.craftbukkit.CraftParticle;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.CraftServerLinks;
import org.bukkit.craftbukkit.CraftSound;
import org.bukkit.craftbukkit.CraftStatistic;
import org.bukkit.craftbukkit.CraftWorld;
@@ -478,7 +479,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
public void kickPlayer(String message) {
if (getHandle().connection == null) return;
getHandle().connection.disconnect(message == null ? "" : message);
getHandle().connection.disconnect(CraftChatMessage.fromStringOrEmpty(message));
}
@Override
@@ -562,7 +563,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
public void playSound(Location loc, String sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) {
if (loc == null || sound == null || category == null || getHandle().connection == null) return;
playSound0(loc, Holder.direct(SoundEffect.createVariableRangeEvent(new MinecraftKey(sound))), net.minecraft.sounds.SoundCategory.valueOf(category.name()), volume, pitch, seed);
playSound0(loc, Holder.direct(SoundEffect.createVariableRangeEvent(MinecraftKey.parse(sound))), net.minecraft.sounds.SoundCategory.valueOf(category.name()), volume, pitch, seed);
}
private void playSound0(Location loc, Holder<SoundEffect> soundEffectHolder, net.minecraft.sounds.SoundCategory categoryNMS, float volume, float pitch, long seed) {
@@ -605,7 +606,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
public void playSound(org.bukkit.entity.Entity entity, String sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) {
if (!(entity instanceof CraftEntity craftEntity) || sound == null || category == null || getHandle().connection == null) return;
playSound0(entity, Holder.direct(SoundEffect.createVariableRangeEvent(new MinecraftKey(sound))), net.minecraft.sounds.SoundCategory.valueOf(category.name()), volume, pitch, seed);
playSound0(entity, Holder.direct(SoundEffect.createVariableRangeEvent(MinecraftKey.parse(sound))), net.minecraft.sounds.SoundCategory.valueOf(category.name()), volume, pitch, seed);
}
private void playSound0(org.bukkit.entity.Entity entity, Holder<SoundEffect> soundEffectHolder, net.minecraft.sounds.SoundCategory categoryNMS, float volume, float pitch, long seed) {
@@ -639,7 +640,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
public void stopSound(String sound, org.bukkit.SoundCategory category) {
if (getHandle().connection == null) return;
getHandle().connection.send(new PacketPlayOutStopSound(new MinecraftKey(sound), category == null ? net.minecraft.sounds.SoundCategory.MASTER : net.minecraft.sounds.SoundCategory.valueOf(category.name())));
getHandle().connection.send(new PacketPlayOutStopSound(MinecraftKey.parse(sound), category == null ? net.minecraft.sounds.SoundCategory.MASTER : net.minecraft.sounds.SoundCategory.valueOf(category.name())));
}
@Override
@@ -978,6 +979,17 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
getHandle().connection.send(new ClientboundHurtAnimationPacket(getEntityId(), actualYaw));
}
@Override
public void sendLinks(ServerLinks links) {
if (getHandle().connection == null) {
return;
}
Preconditions.checkArgument(links != null, "links cannot be null");
net.minecraft.server.ServerLinks nms = ((CraftServerLinks) links).getServerLinks();
getHandle().connection.send(new ClientboundServerLinksPacket(nms.untrust()));
}
@Override
public void addCustomChatCompletions(Collection<String> completions) {
this.sendCustomChatCompletionPacket(completions, ClientboundCustomChatCompletionsPacket.Action.ADD);
@@ -1064,7 +1076,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
entity.connection.teleport(to);
} else {
// The respawn reason should never be used if the passed location is non null.
server.getHandle().respawn(entity, toWorld, true, to, true, null);
server.getHandle().respawn(entity, true, Entity.RemovalReason.CHANGED_DIMENSION, null, to);
}
return true;
}
@@ -1127,10 +1139,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
BlockPosition bed = getHandle().getRespawnPosition();
if (world != null && bed != null) {
Optional<Vec3D> spawnLoc = EntityHuman.findRespawnPositionAndUseSpawnBlock(world, bed, getHandle().getRespawnAngle(), getHandle().isRespawnForced(), true);
Optional<EntityPlayer.RespawnPosAngle> spawnLoc = EntityPlayer.findRespawnAndUseSpawnBlock(world, bed, getHandle().getRespawnAngle(), getHandle().isRespawnForced(), true);
if (spawnLoc.isPresent()) {
Vec3D vec = spawnLoc.get();
return CraftLocation.toBukkit(vec, world.getWorld(), getHandle().getRespawnAngle(), 0);
EntityPlayer.RespawnPosAngle vec = spawnLoc.get();
return CraftLocation.toBukkit(vec.position(), world.getWorld(), vec.yaw(), 0);
}
}
return null;
@@ -1787,7 +1799,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
if (getHandle().connection == null) return;
if (channels.contains(channel)) {
MinecraftKey id = new MinecraftKey(StandardMessenger.validateAndCorrectChannel(channel));
MinecraftKey id = MinecraftKey.parse(StandardMessenger.validateAndCorrectChannel(channel));
sendCustomPayload(id, message);
}
}
@@ -1914,7 +1926,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
}
}
sendCustomPayload(new MinecraftKey("register"), stream.toByteArray());
sendCustomPayload(MinecraftKey.withDefaultNamespace("register"), stream.toByteArray());
}
}

View File

@@ -56,6 +56,7 @@ import net.minecraft.world.entity.raid.EntityRaider;
import net.minecraft.world.entity.raid.Raid;
import net.minecraft.world.inventory.Container;
import net.minecraft.world.inventory.ContainerMerchant;
import net.minecraft.world.inventory.InventoryCrafting;
import net.minecraft.world.inventory.RecipeBookType;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
@@ -887,7 +888,7 @@ public class CraftEventFactory {
public static EntityDeathEvent callEntityDeathEvent(EntityLiving victim, DamageSource damageSource, List<org.bukkit.inventory.ItemStack> drops) {
CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward());
EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(damageSource.getEntity()));
CraftWorld world = (CraftWorld) entity.getWorld();
Bukkit.getServer().getPluginManager().callEvent(event);
@@ -905,7 +906,7 @@ public class CraftEventFactory {
public static PlayerDeathEvent callPlayerDeathEvent(EntityPlayer victim, DamageSource damageSource, List<org.bukkit.inventory.ItemStack> drops, String deathMessage, boolean keepInventory) {
CraftPlayer entity = victim.getBukkitEntity();
CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(), 0, deathMessage);
PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(damageSource.getEntity()), 0, deathMessage);
event.setKeepInventory(keepInventory);
event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel
org.bukkit.World world = entity.getWorld();
@@ -1257,7 +1258,7 @@ public class CraftEventFactory {
return container;
}
public static ItemStack callPreCraftEvent(IInventory matrix, IInventory resultInventory, ItemStack result, InventoryView lastCraftView, boolean isRepair) {
public static ItemStack callPreCraftEvent(InventoryCrafting matrix, IInventory resultInventory, ItemStack result, InventoryView lastCraftView, boolean isRepair) {
CraftInventoryCrafting inventory = new CraftInventoryCrafting(matrix, resultInventory);
inventory.setResult(CraftItemStack.asCraftMirror(result));
@@ -1438,13 +1439,13 @@ public class CraftEventFactory {
Bukkit.getPluginManager().callEvent(new PlayerRecipeBookSettingsChangeEvent(player.getBukkitEntity(), bukkitType, open, filter));
}
public static PlayerUnleashEntityEvent callPlayerUnleashEntityEvent(EntityInsentient entity, EntityHuman player, EnumHand enumhand) {
public static PlayerUnleashEntityEvent callPlayerUnleashEntityEvent(Entity entity, EntityHuman player, EnumHand enumhand) {
PlayerUnleashEntityEvent event = new PlayerUnleashEntityEvent(entity.getBukkitEntity(), (Player) player.getBukkitEntity(), CraftEquipmentSlot.getHand(enumhand));
entity.level().getCraftServer().getPluginManager().callEvent(event);
return event;
}
public static PlayerLeashEntityEvent callPlayerLeashEntityEvent(EntityInsentient entity, Entity leashHolder, EntityHuman player, EnumHand enumhand) {
public static PlayerLeashEntityEvent callPlayerLeashEntityEvent(Entity entity, Entity leashHolder, EntityHuman player, EnumHand enumhand) {
PlayerLeashEntityEvent event = new PlayerLeashEntityEvent(entity.getBukkitEntity(), leashHolder.getBukkitEntity(), (Player) player.getBukkitEntity(), CraftEquipmentSlot.getHand(enumhand));
entity.level().getCraftServer().getPluginManager().callEvent(event);
return event;
@@ -1794,6 +1795,11 @@ public class CraftEventFactory {
public static EntityTeleportEvent callEntityTeleportEvent(Entity nmsEntity, double x, double y, double z) {
CraftEntity entity = nmsEntity.getBukkitEntity();
Location to = new Location(entity.getWorld(), x, y, z, nmsEntity.getYRot(), nmsEntity.getXRot());
return callEntityTeleportEvent(nmsEntity, to);
}
public static EntityTeleportEvent callEntityTeleportEvent(Entity nmsEntity, Location to) {
CraftEntity entity = nmsEntity.getBukkitEntity();
EntityTeleportEvent event = new org.bukkit.event.entity.EntityTeleportEvent(entity, entity.getLocation(), to);
Bukkit.getPluginManager().callEvent(event);

View File

@@ -5,7 +5,6 @@ import com.mojang.serialization.MapCodec;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import net.minecraft.core.BlockPosition;
import net.minecraft.core.Holder;
import net.minecraft.core.IRegistryCustom;
@@ -245,7 +244,7 @@ public class CustomChunkGenerator extends InternalChunkGenerator {
}
@Override
public CompletableFuture<IChunkAccess> fillFromNoise(Executor executor, Blender blender, RandomState randomstate, StructureManager structuremanager, IChunkAccess ichunkaccess) {
public CompletableFuture<IChunkAccess> fillFromNoise(Blender blender, RandomState randomstate, StructureManager structuremanager, IChunkAccess ichunkaccess) {
CompletableFuture<IChunkAccess> future = null;
SeededRandom random = getSeededRandom();
int x = ichunkaccess.getPos().x;
@@ -253,7 +252,7 @@ public class CustomChunkGenerator extends InternalChunkGenerator {
random.setSeed(MathHelper.getSeed(x, "should-noise".hashCode(), z) ^ this.world.getSeed());
if (generator.shouldGenerateNoise(this.world.getWorld(), new RandomSourceWrapper.RandomWrapper(random), x, z)) {
future = delegate.fillFromNoise(executor, blender, randomstate, structuremanager, ichunkaccess);
future = delegate.fillFromNoise(blender, randomstate, structuremanager, ichunkaccess);
}
java.util.function.Function<IChunkAccess, IChunkAccess> function = (ichunkaccess1) -> {

View File

@@ -4,6 +4,7 @@ import com.google.common.base.Preconditions;
import java.util.Arrays;
import java.util.List;
import net.minecraft.world.IInventory;
import net.minecraft.world.inventory.InventoryCrafting;
import net.minecraft.world.item.crafting.RecipeHolder;
import org.bukkit.inventory.CraftingInventory;
import org.bukkit.inventory.ItemStack;
@@ -12,7 +13,7 @@ import org.bukkit.inventory.Recipe;
public class CraftInventoryCrafting extends CraftInventory implements CraftingInventory {
private final IInventory resultInventory;
public CraftInventoryCrafting(IInventory inventory, IInventory resultInventory) {
public CraftInventoryCrafting(InventoryCrafting inventory, IInventory resultInventory) {
super(inventory);
this.resultInventory = resultInventory;
}
@@ -21,8 +22,8 @@ public class CraftInventoryCrafting extends CraftInventory implements CraftingIn
return resultInventory;
}
public IInventory getMatrixInventory() {
return inventory;
public InventoryCrafting getMatrixInventory() {
return (InventoryCrafting) inventory;
}
@Override
@@ -115,7 +116,7 @@ public class CraftInventoryCrafting extends CraftInventory implements CraftingIn
@Override
public Recipe getRecipe() {
RecipeHolder<?> recipe = getInventory().getCurrentRecipe();
RecipeHolder<?> recipe = getMatrixInventory().getCurrentRecipe();
return recipe == null ? null : recipe.toBukkitRecipe();
}
}

View File

@@ -3,22 +3,30 @@ package org.bukkit.craftbukkit.inventory;
import com.google.common.base.Preconditions;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import java.util.Optional;
import net.minecraft.commands.arguments.item.ArgumentParserItemStack;
import net.minecraft.core.component.DataComponentMap;
import net.minecraft.core.HolderSet;
import net.minecraft.core.IRegistryCustom;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.registries.Registries;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tags.EnchantmentTags;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.EntityTypes;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemMonsterEgg;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentManager;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.configuration.serialization.ConfigurationSerialization;
import org.bukkit.craftbukkit.CraftRegistry;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.entity.CraftEntity;
import org.bukkit.craftbukkit.entity.CraftEntityType;
import org.bukkit.craftbukkit.inventory.components.CraftFoodComponent;
import org.bukkit.craftbukkit.inventory.components.CraftJukeboxComponent;
import org.bukkit.craftbukkit.inventory.components.CraftToolComponent;
import org.bukkit.craftbukkit.util.CraftLegacy;
import org.bukkit.entity.Entity;
@@ -39,6 +47,7 @@ public final class CraftItemFactory implements ItemFactory {
ConfigurationSerialization.registerClass(CraftFoodComponent.CraftFoodEffect.class);
ConfigurationSerialization.registerClass(CraftToolComponent.class);
ConfigurationSerialization.registerClass(CraftToolComponent.CraftToolRule.class);
ConfigurationSerialization.registerClass(CraftJukeboxComponent.class);
}
private CraftItemFactory() {
@@ -448,7 +457,7 @@ public final class CraftItemFactory implements ItemFactory {
Item item = arg.item().value();
net.minecraft.world.item.ItemStack nmsItemStack = new net.minecraft.world.item.ItemStack(item);
DataComponentMap nbt = arg.components();
DataComponentPatch nbt = arg.components();
if (nbt != null) {
nmsItemStack.applyComponents(nbt);
}
@@ -498,6 +507,8 @@ public final class CraftItemFactory implements ItemFactory {
Preconditions.checkArgument(!itemStack.getType().isAir(), "ItemStack must not be air");
itemStack = CraftItemStack.asCraftCopy(itemStack);
CraftItemStack craft = (CraftItemStack) itemStack;
return CraftItemStack.asCraftMirror(EnchantmentManager.enchantItem(MinecraftServer.getServer().getWorldData().enabledFeatures(), source, craft.handle, level, allowTreasures));
IRegistryCustom registry = CraftRegistry.getMinecraftRegistry();
Optional<HolderSet.Named<Enchantment>> optional = (allowTreasures) ? Optional.empty() : registry.registryOrThrow(Registries.ENCHANTMENT).getTag(EnchantmentTags.IN_ENCHANTING_TABLE);
return CraftItemStack.asCraftMirror(EnchantmentManager.enchantItem(source, craft.handle, level, registry, optional));
}
}

View File

@@ -185,7 +185,7 @@ public final class CraftItemStack extends ItemStack {
list = ItemEnchantments.EMPTY;
}
ItemEnchantments.a listCopy = new ItemEnchantments.a(list);
listCopy.set(CraftEnchantment.bukkitToMinecraft(ench), level);
listCopy.set(CraftEnchantment.bukkitToMinecraftHolder(ench), level);
handle.set(DataComponents.ENCHANTMENTS, listCopy.toImmutable());
}
@@ -208,7 +208,7 @@ public final class CraftItemStack extends ItemStack {
if (handle == null) {
return 0;
}
return EnchantmentManager.getItemEnchantmentLevel(CraftEnchantment.bukkitToMinecraft(ench), handle);
return EnchantmentManager.getItemEnchantmentLevel(CraftEnchantment.bukkitToMinecraftHolder(ench), handle);
}
@Override
@@ -231,7 +231,7 @@ public final class CraftItemStack extends ItemStack {
}
ItemEnchantments.a listCopy = new ItemEnchantments.a(list);
listCopy.set(CraftEnchantment.bukkitToMinecraft(ench), -1); // Negative to remove
listCopy.set(CraftEnchantment.bukkitToMinecraftHolder(ench), -1); // Negative to remove
handle.set(DataComponents.ENCHANTMENTS, listCopy.toImmutable());
return level;

View File

@@ -8,7 +8,6 @@ import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemBlock;
import net.minecraft.world.item.ItemRecord;
import net.minecraft.world.item.component.ItemAttributeModifiers;
import net.minecraft.world.level.block.BlockComposter;
import net.minecraft.world.level.block.entity.TileEntityFurnace;
@@ -169,7 +168,7 @@ public class CraftItemType<M extends ItemMeta> implements ItemType.Typed<M>, Han
@Override
public boolean isRecord() {
return item instanceof ItemRecord;
return item.components().has(DataComponents.JUKEBOX_PLAYABLE);
}
@Override

View File

@@ -61,7 +61,10 @@ import net.minecraft.world.entity.EnumItemSlot;
import net.minecraft.world.entity.EquipmentSlotGroup;
import net.minecraft.world.entity.ai.attributes.AttributeBase;
import net.minecraft.world.food.FoodInfo;
import net.minecraft.world.item.EitherHolder;
import net.minecraft.world.item.EnumItemRarity;
import net.minecraft.world.item.JukeboxPlayable;
import net.minecraft.world.item.JukeboxSongs;
import net.minecraft.world.item.component.BlockItemStateProperties;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.item.component.CustomModelData;
@@ -86,6 +89,7 @@ import org.bukkit.craftbukkit.block.data.CraftBlockData;
import org.bukkit.craftbukkit.enchantments.CraftEnchantment;
import org.bukkit.craftbukkit.inventory.CraftMetaItem.ItemMetaKey.Specific;
import org.bukkit.craftbukkit.inventory.components.CraftFoodComponent;
import org.bukkit.craftbukkit.inventory.components.CraftJukeboxComponent;
import org.bukkit.craftbukkit.inventory.components.CraftToolComponent;
import org.bukkit.craftbukkit.inventory.tags.DeprecatedCustomTagContainer;
import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer;
@@ -102,6 +106,7 @@ import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.Repairable;
import org.bukkit.inventory.meta.components.FoodComponent;
import org.bukkit.inventory.meta.components.JukeboxPlayableComponent;
import org.bukkit.inventory.meta.components.ToolComponent;
import org.bukkit.inventory.meta.tags.CustomItemTagContainer;
import org.bukkit.persistence.PersistentDataContainer;
@@ -226,6 +231,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
@Specific(Specific.To.NBT)
static final ItemMetaKeyType<Tool> TOOL = new ItemMetaKeyType<>(DataComponents.TOOL, "tool");
@Specific(Specific.To.NBT)
static final ItemMetaKeyType<JukeboxPlayable> JUKEBOX_PLAYABLE = new ItemMetaKeyType<>(DataComponents.JUKEBOX_PLAYABLE, "jukebox-playable");
@Specific(Specific.To.NBT)
static final ItemMetaKeyType<Integer> DAMAGE = new ItemMetaKeyType<>(DataComponents.DAMAGE, "Damage");
@Specific(Specific.To.NBT)
static final ItemMetaKeyType<Integer> MAX_DAMAGE = new ItemMetaKeyType<>(DataComponents.MAX_DAMAGE, "max-damage");
@@ -255,6 +262,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
private ItemRarity rarity;
private CraftFoodComponent food;
private CraftToolComponent tool;
private CraftJukeboxComponent jukebox;
private int damage;
private Integer maxDamage;
@@ -304,6 +312,9 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
if (meta.hasTool()) {
this.tool = new CraftToolComponent(meta.tool);
}
if (meta.hasJukeboxPlayable()) {
this.jukebox = new CraftJukeboxComponent(meta.jukebox);
}
this.damage = meta.damage;
this.maxDamage = meta.maxDamage;
this.unhandledTags = meta.unhandledTags;
@@ -385,6 +396,9 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
getOrEmpty(tag, TOOL).ifPresent((toolInfo) -> {
tool = new CraftToolComponent(toolInfo);
});
getOrEmpty(tag, JUKEBOX_PLAYABLE).ifPresent((jukeboxPlayable) -> {
jukebox = new CraftJukeboxComponent(jukeboxPlayable);
});
getOrEmpty(tag, DAMAGE).ifPresent((i) -> {
damage = i;
});
@@ -474,7 +488,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
continue;
}
attribMod = new AttributeModifier(attribMod.getUniqueId(), attribMod.getName(), attribMod.getAmount(), attribMod.getOperation(), slot);
attribMod = new AttributeModifier(attribMod.getKey(), attribMod.getAmount(), attribMod.getOperation(), slot);
}
modifiers.put(attribute, attribMod);
}
@@ -568,6 +582,11 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
setTool(tool);
}
CraftJukeboxComponent jukeboxPlayable = SerializableMeta.getObject(CraftJukeboxComponent.class, map, JUKEBOX_PLAYABLE.BUKKIT, true);
if (jukeboxPlayable != null) {
setJukeboxPlayable(jukeboxPlayable);
}
Integer damage = SerializableMeta.getObject(Integer.class, map, DAMAGE.BUKKIT, true);
if (damage != null) {
setDamage(damage);
@@ -673,7 +692,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
continue;
}
attribMod = new AttributeModifier(attribMod.getUniqueId(), attribMod.getName(), attribMod.getAmount(), attribMod.getOperation(), slot);
attribMod = new AttributeModifier(attribMod.getKey(), attribMod.getAmount(), attribMod.getOperation(), slot.getGroup());
}
modifiers.put(attribute, attribMod);
}
@@ -800,6 +819,10 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
itemTag.put(TOOL, tool.getHandle());
}
if (hasJukeboxPlayable()) {
itemTag.put(JUKEBOX_PLAYABLE, jukebox.getHandle());
}
if (hasDamage()) {
itemTag.put(DAMAGE, damage);
}
@@ -842,7 +865,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
ItemEnchantments.a list = new ItemEnchantments.a(ItemEnchantments.EMPTY);
for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
list.set(CraftEnchantment.bukkitToMinecraft(entry.getKey()), entry.getValue());
list.set(CraftEnchantment.bukkitToMinecraftHolder(entry.getKey()), entry.getValue());
}
list.showInTooltip = !hasItemFlag(itemFlag);
@@ -1187,7 +1210,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
@Override
public FoodComponent getFood() {
return (this.hasFood()) ? new CraftFoodComponent(this.food) : new CraftFoodComponent(new FoodInfo(0, 0, false, 0, Collections.emptyList()));
return (this.hasFood()) ? new CraftFoodComponent(this.food) : new CraftFoodComponent(new FoodInfo(0, 0, false, 0, Optional.empty(), Collections.emptyList()));
}
@Override
@@ -1210,6 +1233,21 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
this.tool = (tool == null) ? null : new CraftToolComponent((CraftToolComponent) tool);
}
@Override
public boolean hasJukeboxPlayable() {
return this.jukebox != null;
}
@Override
public JukeboxPlayableComponent getJukeboxPlayable() {
return (this.hasJukeboxPlayable()) ? new CraftJukeboxComponent(this.jukebox) : new CraftJukeboxComponent(new JukeboxPlayable(new EitherHolder<>(JukeboxSongs.THIRTEEN), true));
}
@Override
public void setJukeboxPlayable(JukeboxPlayableComponent jukeboxPlayable) {
this.jukebox = (jukeboxPlayable == null) ? null : new CraftJukeboxComponent((CraftJukeboxComponent) jukeboxPlayable);
}
@Override
public boolean hasAttributeModifiers() {
return attributeModifiers != null && !attributeModifiers.isEmpty();
@@ -1250,7 +1288,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
Preconditions.checkNotNull(modifier, "AttributeModifier cannot be null");
checkAttributeList();
for (Map.Entry<Attribute, AttributeModifier> entry : attributeModifiers.entries()) {
Preconditions.checkArgument(!entry.getValue().getUniqueId().equals(modifier.getUniqueId()), "Cannot register AttributeModifier. Modifier is already applied! %s", modifier);
Preconditions.checkArgument(!entry.getValue().getKey().equals(modifier.getKey()), "Cannot register AttributeModifier. Modifier is already applied! %s", modifier);
}
return attributeModifiers.put(attribute, modifier);
}
@@ -1318,7 +1356,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
continue; // remove all null values while we are here
}
if (entry.getKey() == attribute && entry.getValue().getUniqueId().equals(modifier.getUniqueId())) {
if (entry.getKey() == attribute && entry.getValue().getKey().equals(modifier.getKey())) {
iter.remove();
++removed;
}
@@ -1356,7 +1394,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
String componentValueAsNBTString = new SnbtPrinterTagVisitor("", 0, new ArrayList<>()).visit(componentValueAsNBT);
componentString.add(componentKey + "=" + componentValueAsNBTString);
} else {
// TODO: 1.21, remove component (!) format
componentString.add("!" + componentKey);
}
}
@@ -1462,6 +1500,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
&& (this.rarity == that.rarity)
&& (this.hasFood() ? that.hasFood() && this.food.equals(that.food) : !that.hasFood())
&& (this.hasTool() ? that.hasTool() && this.tool.equals(that.tool) : !that.hasTool())
&& (this.hasJukeboxPlayable() ? that.hasJukeboxPlayable() && this.jukebox.equals(that.jukebox) : !that.hasJukeboxPlayable())
&& (this.hasDamage() ? that.hasDamage() && this.damage == that.damage : !that.hasDamage())
&& (this.hasMaxDamage() ? that.hasMaxDamage() && this.maxDamage.equals(that.maxDamage) : !that.hasMaxDamage())
&& (this.version == that.version);
@@ -1504,6 +1543,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
hash = 61 * hash + (hasRarity() ? this.rarity.hashCode() : 0);
hash = 61 * hash + (hasFood() ? this.food.hashCode() : 0);
hash = 61 * hash + (hasTool() ? this.tool.hashCode() : 0);
hash = 61 * hash + (hasJukeboxPlayable() ? this.jukebox.hashCode() : 0);
hash = 61 * hash + (hasDamage() ? this.damage : 0);
hash = 61 * hash + (hasMaxDamage() ? 1231 : 1237);
hash = 61 * hash + (hasAttributeModifiers() ? this.attributeModifiers.hashCode() : 0);
@@ -1544,6 +1584,9 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
if (this.hasTool()) {
clone.tool = new CraftToolComponent(tool);
}
if (this.hasJukeboxPlayable()) {
clone.jukebox = new CraftJukeboxComponent(jukebox);
}
clone.damage = this.damage;
clone.maxDamage = this.maxDamage;
clone.version = this.version;
@@ -1636,6 +1679,10 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
builder.put(TOOL.BUKKIT, tool);
}
if (hasJukeboxPlayable()) {
builder.put(JUKEBOX_PLAYABLE.BUKKIT, jukebox);
}
if (hasDamage()) {
builder.put(DAMAGE.BUKKIT, damage);
}
@@ -1799,6 +1846,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
RARITY.TYPE,
FOOD.TYPE,
TOOL.TYPE,
JUKEBOX_PLAYABLE.TYPE,
DAMAGE.TYPE,
MAX_DAMAGE.TYPE,
CUSTOM_DATA.TYPE,

View File

@@ -7,11 +7,14 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import net.minecraft.world.food.FoodInfo;
import org.bukkit.configuration.serialization.SerializableAs;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.inventory.SerializableMeta;
import org.bukkit.craftbukkit.potion.CraftPotionUtil;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.components.FoodComponent;
import org.bukkit.potion.PotionEffect;
@@ -38,6 +41,8 @@ public final class CraftFoodComponent implements FoodComponent {
eatSeconds = 1.6f;
}
ItemStack usingConvertsTo = SerializableMeta.getObject(ItemStack.class, map, "using-converts-to", true);
ImmutableList.Builder<FoodEffect> effects = ImmutableList.builder();
Iterable<?> rawEffectList = SerializableMeta.getObject(Iterable.class, map, "effects", true);
if (rawEffectList != null) {
@@ -47,7 +52,7 @@ public final class CraftFoodComponent implements FoodComponent {
}
}
this.handle = new FoodInfo(nutrition, saturationModifier, canAlwaysEat, eatSeconds, effects.build().stream().map(CraftFoodEffect::new).map(CraftFoodEffect::getHandle).toList());
this.handle = new FoodInfo(nutrition, saturationModifier, canAlwaysEat, eatSeconds, Optional.ofNullable(usingConvertsTo).map(CraftItemStack::asNMSCopy), effects.build().stream().map(CraftFoodEffect::new).map(CraftFoodEffect::getHandle).toList());
}
@Override
@@ -57,6 +62,7 @@ public final class CraftFoodComponent implements FoodComponent {
result.put("saturation", getSaturation());
result.put("can-always-eat", canAlwaysEat());
result.put("eat-seconds", getEatSeconds());
result.put("using-converts-to", getUsingConvertsTo());
result.put("effects", getEffects());
return result;
}
@@ -73,7 +79,7 @@ public final class CraftFoodComponent implements FoodComponent {
@Override
public void setNutrition(int nutrition) {
Preconditions.checkArgument(nutrition >= 0, "Nutrition cannot be negative");
handle = new FoodInfo(nutrition, handle.saturation(), handle.canAlwaysEat(), handle.eatSeconds(), handle.effects());
handle = new FoodInfo(nutrition, handle.saturation(), handle.canAlwaysEat(), handle.eatSeconds(), handle.usingConvertsTo(), handle.effects());
}
@Override
@@ -83,7 +89,7 @@ public final class CraftFoodComponent implements FoodComponent {
@Override
public void setSaturation(float saturation) {
handle = new FoodInfo(handle.nutrition(), saturation, handle.canAlwaysEat(), handle.eatSeconds(), handle.effects());
handle = new FoodInfo(handle.nutrition(), saturation, handle.canAlwaysEat(), handle.eatSeconds(), handle.usingConvertsTo(), handle.effects());
}
@Override
@@ -93,7 +99,7 @@ public final class CraftFoodComponent implements FoodComponent {
@Override
public void setCanAlwaysEat(boolean canAlwaysEat) {
handle = new FoodInfo(handle.nutrition(), handle.saturation(), canAlwaysEat, handle.eatSeconds(), handle.effects());
handle = new FoodInfo(handle.nutrition(), handle.saturation(), canAlwaysEat, handle.eatSeconds(), handle.usingConvertsTo(), handle.effects());
}
@Override
@@ -103,7 +109,17 @@ public final class CraftFoodComponent implements FoodComponent {
@Override
public void setEatSeconds(float eatSeconds) {
handle = new FoodInfo(handle.nutrition(), handle.saturation(), handle.canAlwaysEat(), eatSeconds, handle.effects());
handle = new FoodInfo(handle.nutrition(), handle.saturation(), handle.canAlwaysEat(), eatSeconds, handle.usingConvertsTo(), handle.effects());
}
@Override
public ItemStack getUsingConvertsTo() {
return handle.usingConvertsTo().map(CraftItemStack::asBukkitCopy).orElse(null);
}
@Override
public void setUsingConvertsTo(ItemStack item) {
handle = new FoodInfo(handle.nutrition(), handle.saturation(), handle.canAlwaysEat(), handle.eatSeconds(), Optional.ofNullable(item).map(CraftItemStack::asNMSCopy), handle.effects());
}
@Override
@@ -113,7 +129,7 @@ public final class CraftFoodComponent implements FoodComponent {
@Override
public void setEffects(List<FoodEffect> effects) {
handle = new FoodInfo(handle.nutrition(), handle.saturation(), handle.canAlwaysEat(), handle.eatSeconds(), effects.stream().map(CraftFoodEffect::new).map(CraftFoodEffect::getHandle).toList());
handle = new FoodInfo(handle.nutrition(), handle.saturation(), handle.canAlwaysEat(), handle.eatSeconds(), handle.usingConvertsTo(), effects.stream().map(CraftFoodEffect::new).map(CraftFoodEffect::getHandle).toList());
}
@Override
@@ -123,7 +139,7 @@ public final class CraftFoodComponent implements FoodComponent {
FoodInfo.b newEffect = new net.minecraft.world.food.FoodInfo.b(CraftPotionUtil.fromBukkit(effect), probability);
effects.add(newEffect);
handle = new FoodInfo(handle.nutrition(), handle.saturation(), handle.canAlwaysEat(), handle.eatSeconds(), effects);
handle = new FoodInfo(handle.nutrition(), handle.saturation(), handle.canAlwaysEat(), handle.eatSeconds(), handle.usingConvertsTo(), effects);
return new CraftFoodEffect(newEffect);
}

View File

@@ -0,0 +1,116 @@
package org.bukkit.craftbukkit.inventory.components;
import com.google.common.base.Preconditions;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import net.minecraft.core.Holder;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.MinecraftKey;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.item.EitherHolder;
import net.minecraft.world.item.JukeboxPlayable;
import org.bukkit.JukeboxSong;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.serialization.SerializableAs;
import org.bukkit.craftbukkit.CraftJukeboxSong;
import org.bukkit.craftbukkit.CraftRegistry;
import org.bukkit.craftbukkit.inventory.SerializableMeta;
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
import org.bukkit.inventory.meta.components.JukeboxPlayableComponent;
@SerializableAs("JukeboxPlayable")
public final class CraftJukeboxComponent implements JukeboxPlayableComponent {
private JukeboxPlayable handle;
public CraftJukeboxComponent(JukeboxPlayable jukebox) {
this.handle = jukebox;
}
public CraftJukeboxComponent(CraftJukeboxComponent jukebox) {
this.handle = jukebox.handle;
}
public CraftJukeboxComponent(Map<String, Object> map) {
String song = SerializableMeta.getObject(String.class, map, "song", false);
Boolean showTooltip = SerializableMeta.getObject(boolean.class, map, "show-in-tooltip", true);
this.handle = new JukeboxPlayable(new EitherHolder<>(ResourceKey.create(Registries.JUKEBOX_SONG, MinecraftKey.parse(song))), (showTooltip != null) ? showTooltip : true);
}
@Override
public Map<String, Object> serialize() {
Map<String, Object> result = new LinkedHashMap<>();
result.put("song", getSongKey().toString());
result.put("show-in-tooltip", isShowInTooltip());
return result;
}
public JukeboxPlayable getHandle() {
return handle;
}
@Override
public JukeboxSong getSong() {
Optional<Holder<net.minecraft.world.item.JukeboxSong>> song = handle.song().unwrap(CraftRegistry.getMinecraftRegistry());
return (song.isPresent()) ? CraftJukeboxSong.minecraftHolderToBukkit(song.get()) : null;
}
@Override
public NamespacedKey getSongKey() {
return CraftNamespacedKey.fromMinecraft(handle.song().key().location());
}
@Override
public void setSong(JukeboxSong song) {
Preconditions.checkArgument(song != null, "song cannot be null");
handle = new JukeboxPlayable(new EitherHolder<>(CraftJukeboxSong.bukkitToMinecraftHolder(song)), handle.showInTooltip());
}
@Override
public void setSongKey(NamespacedKey song) {
Preconditions.checkArgument(song != null, "song cannot be null");
handle = new JukeboxPlayable(new EitherHolder<>(ResourceKey.create(Registries.JUKEBOX_SONG, CraftNamespacedKey.toMinecraft(song))), handle.showInTooltip());
}
@Override
public boolean isShowInTooltip() {
return handle.showInTooltip();
}
@Override
public void setShowInTooltip(boolean show) {
handle = new JukeboxPlayable(handle.song(), show);
}
@Override
public int hashCode() {
int hash = 7;
hash = 73 * hash + Objects.hashCode(this.handle);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final CraftJukeboxComponent other = (CraftJukeboxComponent) obj;
return Objects.equals(this.handle, other.handle);
}
@Override
public String toString() {
return "CraftJukeboxComponent{" + "handle=" + handle + '}';
}
}

View File

@@ -342,7 +342,7 @@ public final class CraftLegacy {
}
String name = blockTag.get("Name").asString("");
Block block = BuiltInRegistries.BLOCK.get(new MinecraftKey(name));
Block block = BuiltInRegistries.BLOCK.get(MinecraftKey.parse(name));
if (block == null) {
continue;
}
@@ -416,7 +416,7 @@ public final class CraftLegacy {
}
// Preconditions.checkState(newId.contains("minecraft:"), "Unknown new material for " + matData);
Item newMaterial = BuiltInRegistries.ITEM.get(new MinecraftKey(newId));
Item newMaterial = BuiltInRegistries.ITEM.get(MinecraftKey.parse(newId));
if (newMaterial == Items.AIR) {
continue;

View File

@@ -0,0 +1,12 @@
package org.bukkit.craftbukkit.legacy;
import org.bukkit.craftbukkit.legacy.reroute.NotInBukkit;
import org.bukkit.event.entity.EntityCombustEvent;
public class MethodRerouting {
@NotInBukkit
public static int getDuration(EntityCombustEvent event) {
return (int) event.getDuration();
}
}

View File

@@ -21,6 +21,7 @@ import net.minecraft.world.entity.projectile.EntityTippedArrow;
import net.minecraft.world.entity.projectile.IProjectile;
import net.minecraft.world.level.block.BlockDispenser;
import net.minecraft.world.level.block.entity.TileEntityDispenser;
import net.minecraft.world.phys.Vec3D;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
@@ -90,12 +91,12 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
}
} else if (AbstractArrow.class.isAssignableFrom(projectile)) {
if (TippedArrow.class.isAssignableFrom(projectile)) {
launch = new EntityTippedArrow(world, iposition.x(), iposition.y(), iposition.z(), new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.ARROW));
launch = new EntityTippedArrow(world, iposition.x(), iposition.y(), iposition.z(), new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.ARROW), null);
((Arrow) launch.getBukkitEntity()).setBasePotionType(PotionType.WATER);
} else if (SpectralArrow.class.isAssignableFrom(projectile)) {
launch = new EntitySpectralArrow(world, iposition.x(), iposition.y(), iposition.z(), new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.SPECTRAL_ARROW));
launch = new EntitySpectralArrow(world, iposition.x(), iposition.y(), iposition.z(), new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.SPECTRAL_ARROW), null);
} else {
launch = new EntityTippedArrow(world, iposition.x(), iposition.y(), iposition.z(), new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.ARROW));
launch = new EntityTippedArrow(world, iposition.x(), iposition.y(), iposition.z(), new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.ARROW), null);
}
((EntityArrow) launch).pickup = EntityArrow.PickupStatus.ALLOWED;
((EntityArrow) launch).projectileSource = this;
@@ -109,23 +110,17 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
double d5 = random.nextGaussian() * 0.05D + (double) enumdirection.getStepZ();
if (SmallFireball.class.isAssignableFrom(projectile)) {
launch = new EntitySmallFireball(world, null, d0, d1, d2);
launch = new EntitySmallFireball(world, null, new Vec3D(d0, d1, d2));
} else if (WitherSkull.class.isAssignableFrom(projectile)) {
launch = EntityTypes.WITHER_SKULL.create(world);
launch.setPos(d0, d1, d2);
double d6 = Math.sqrt(d3 * d3 + d4 * d4 + d5 * d5);
((EntityFireball) launch).xPower = d3 / d6 * 0.1D;
((EntityFireball) launch).yPower = d4 / d6 * 0.1D;
((EntityFireball) launch).zPower = d5 / d6 * 0.1D;
((EntityFireball) launch).assignDirectionalMovement(new Vec3D(d3, d4, d5), 0.1D);
} else {
launch = EntityTypes.FIREBALL.create(world);
launch.setPos(d0, d1, d2);
double d6 = Math.sqrt(d3 * d3 + d4 * d4 + d5 * d5);
((EntityFireball) launch).xPower = d3 / d6 * 0.1D;
((EntityFireball) launch).yPower = d4 / d6 * 0.1D;
((EntityFireball) launch).zPower = d5 / d6 * 0.1D;
((EntityFireball) launch).assignDirectionalMovement(new Vec3D(d3, d4, d5), 0.1D);
}
((EntityFireball) launch).projectileSource = this;

View File

@@ -124,14 +124,14 @@ public class CraftStructureManager implements StructureManager {
if (unregister) {
structureManager.structureRepository.remove(key);
}
Path path = structureManager.getPathToGeneratedStructure(key, ".nbt");
Path path = structureManager.createAndValidatePathToGeneratedStructure(key, ".nbt");
Files.deleteIfExists(path);
}
@Override
public File getStructureFile(NamespacedKey structureKey) {
MinecraftKey minecraftKey = createAndValidateMinecraftStructureKey(structureKey);
return structureManager.getPathToGeneratedStructure(minecraftKey, ".nbt").toFile();
return structureManager.createAndValidatePathToGeneratedStructure(minecraftKey, ".nbt").toFile();
}
@Override

View File

@@ -15,7 +15,7 @@ public final class ApiVersion implements Comparable<ApiVersion> {
static {
versions = new HashMap<>();
CURRENT = getOrCreateVersion("1.20.6");
CURRENT = getOrCreateVersion("1.21");
FLATTENING = getOrCreateVersion("1.13");
FIELD_NAME_PARITY = getOrCreateVersion("1.20.5");
NONE = getOrCreateVersion("none");

View File

@@ -23,6 +23,7 @@ import joptsimple.OptionSpec;
import org.bukkit.Material;
import org.bukkit.craftbukkit.legacy.FieldRename;
import org.bukkit.craftbukkit.legacy.MaterialRerouting;
import org.bukkit.craftbukkit.legacy.MethodRerouting;
import org.bukkit.craftbukkit.legacy.reroute.RerouteArgument;
import org.bukkit.craftbukkit.legacy.reroute.RerouteBuilder;
import org.bukkit.craftbukkit.legacy.reroute.RerouteMethodData;
@@ -76,6 +77,7 @@ public class Commodore {
public static final List<Map<String, RerouteMethodData>> REROUTES = new ArrayList<>(); // Only used for testing
private static final Map<String, RerouteMethodData> FIELD_RENAME_METHOD_REROUTE = createReroutes(FieldRename.class);
private static final Map<String, RerouteMethodData> MATERIAL_METHOD_REROUTE = createReroutes(MaterialRerouting.class);
private static final Map<String, RerouteMethodData> METHOD_REROUTE = createReroutes(MethodRerouting.class);
public static void main(String[] args) {
OptionParser parser = new OptionParser();
@@ -282,6 +284,9 @@ public class Commodore {
if (checkReroute(visitor, FIELD_RENAME_METHOD_REROUTE, opcode, owner, name, desc, samMethodType, instantiatedMethodType)) {
return;
}
if (checkReroute(visitor, METHOD_REROUTE, opcode, owner, name, desc, samMethodType, instantiatedMethodType)) {
return;
}
// SPIGOT-4496
if (owner.equals("org/bukkit/map/MapView") && name.equals("getId") && desc.equals("()S")) {

View File

@@ -230,7 +230,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
* @return string
*/
public String getMappingsVersion() {
return "ee13f98a43b9c5abffdcc0bb24154460";
return "229d7afc75b70a6c388337687ac4da1f";
}
@Override

View File

@@ -17,7 +17,7 @@ public final class CraftNamespacedKey {
}
public static NamespacedKey fromString(String string) {
return fromMinecraft(new MinecraftKey(string));
return fromMinecraft(MinecraftKey.parse(string));
}
public static NamespacedKey fromMinecraft(MinecraftKey minecraft) {
@@ -25,6 +25,6 @@ public final class CraftNamespacedKey {
}
public static MinecraftKey toMinecraft(NamespacedKey key) {
return new MinecraftKey(key.getNamespace(), key.getKey());
return MinecraftKey.fromNamespaceAndPath(key.getNamespace(), key.getKey());
}
}

View File

@@ -10,25 +10,25 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.minecraft.core.Holder;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.entity.decoration.PaintingVariant;
import org.bukkit.craftbukkit.CraftArt;
import org.bukkit.craftbukkit.CraftRegistry;
import org.bukkit.support.AbstractTestingBase;
import org.junit.jupiter.api.Test;
public class ArtTest extends AbstractTestingBase {
private static final int UNIT_MULTIPLIER = 16;
@Test
public void verifyMapping() {
List<Art> arts = Lists.newArrayList(Art.values());
for (ResourceKey<PaintingVariant> key : BuiltInRegistries.PAINTING_VARIANT.registryKeySet()) {
Holder<PaintingVariant> enumArt = BuiltInRegistries.PAINTING_VARIANT.getHolderOrThrow(key);
for (ResourceKey<PaintingVariant> key : CraftRegistry.getMinecraftRegistry(Registries.PAINTING_VARIANT).registryKeySet()) {
Holder<PaintingVariant> enumArt = CraftRegistry.getMinecraftRegistry(Registries.PAINTING_VARIANT).getHolderOrThrow(key);
String name = key.location().getPath();
int width = enumArt.value().getWidth() / UNIT_MULTIPLIER;
int height = enumArt.value().getHeight() / UNIT_MULTIPLIER;
int width = enumArt.value().width();
int height = enumArt.value().height();
Art subject = CraftArt.minecraftHolderToBukkit(enumArt);
@@ -58,7 +58,7 @@ public class ArtTest extends AbstractTestingBase {
@Test
public void testCraftArtToBukkit() {
Map<Art, Holder<PaintingVariant>> cache = new EnumMap(Art.class);
for (Holder<PaintingVariant> enumArt : BuiltInRegistries.PAINTING_VARIANT.asHolderIdMap()) {
for (Holder<PaintingVariant> enumArt : CraftRegistry.getMinecraftRegistry(Registries.PAINTING_VARIANT).asHolderIdMap()) {
Art art = CraftArt.minecraftHolderToBukkit(enumArt);
assertNotNull(art, "Could not CraftArt.NotchToBukkit " + enumArt);
assertThat(cache.put(art, enumArt), is(nullValue()), "Duplicate artwork " + enumArt);

View File

@@ -13,8 +13,8 @@ public class DyeColorsTest extends AbstractTestingBase {
@EnumSource(DyeColor.class)
public void checkColor(DyeColor dye) {
Color color = dye.getColor();
float[] nmsColorArray = EnumColor.byId(dye.getWoolData()).getTextureDiffuseColors();
Color nmsColor = Color.fromRGB((int) (nmsColorArray[0] * 255), (int) (nmsColorArray[1] * 255), (int) (nmsColorArray[2] * 255));
int nmsColorArray = EnumColor.byId(dye.getWoolData()).getTextureDiffuseColor();
Color nmsColor = Color.fromARGB(nmsColorArray);
assertThat(color, is(nmsColor));
}

View File

@@ -1,8 +1,9 @@
package org.bukkit;
import static org.junit.jupiter.api.Assertions.*;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.MinecraftKey;
import org.bukkit.craftbukkit.CraftRegistry;
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.support.AbstractTestingBase;
@@ -12,8 +13,8 @@ public class EnchantmentTest extends AbstractTestingBase {
@Test
public void verifyMapping() {
for (MinecraftKey key : BuiltInRegistries.ENCHANTMENT.keySet()) {
net.minecraft.world.item.enchantment.Enchantment nms = BuiltInRegistries.ENCHANTMENT.get(key);
for (MinecraftKey key : CraftRegistry.getMinecraftRegistry(Registries.ENCHANTMENT).keySet()) {
net.minecraft.world.item.enchantment.Enchantment nms = CraftRegistry.getMinecraftRegistry(Registries.ENCHANTMENT).get(key);
Enchantment bukkitById = Enchantment.getByKey(CraftNamespacedKey.fromMinecraft(key));

View File

@@ -7,10 +7,10 @@ import java.util.Map;
import net.minecraft.core.BlockPosition;
import net.minecraft.core.component.DataComponents;
import net.minecraft.world.EnumHand;
import net.minecraft.world.entity.EntityInsentient;
import net.minecraft.world.entity.EnumItemSlot;
import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.item.Equipable;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemRecord;
import net.minecraft.world.level.BlockAccessAir;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.BlockFalling;
@@ -74,7 +74,11 @@ public class PerMaterialTest extends AbstractTestingBase {
@ParameterizedTest
@EnumSource(value = Material.class, names = "LEGACY_.*", mode = EnumSource.Mode.MATCH_NONE)
public void isRecord(Material material) {
assertThat(material.isRecord(), is(CraftMagicNumbers.getItem(material) instanceof ItemRecord));
if (material.isBlock()) {
assertFalse(material.isRecord());
} else {
assertThat(material.isRecord(), is(CraftMagicNumbers.getItem(material).components().has(DataComponents.JUKEBOX_PLAYABLE)));
}
}
@ParameterizedTest
@@ -304,7 +308,8 @@ public class PerMaterialTest extends AbstractTestingBase {
@EnumSource(value = Material.class, names = "LEGACY_.*", mode = EnumSource.Mode.MATCH_NONE)
public void testEquipmentSlot(Material material) {
if (material.isItem()) {
EquipmentSlot expected = CraftEquipmentSlot.getSlot(EntityInsentient.getEquipmentSlotForItem(CraftItemStack.asNMSCopy(new ItemStack(material))));
Equipable equipable = Equipable.get(CraftItemStack.asNMSCopy(new ItemStack(material)));
EquipmentSlot expected = CraftEquipmentSlot.getSlot(equipable != null ? equipable.getEquipmentSlot() : EnumItemSlot.MAINHAND);
assertThat(material.getEquipmentSlot(), is(expected));
}
}

View File

@@ -2,7 +2,8 @@ package org.bukkit.craftbukkit.inventory;
import static org.bukkit.support.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
import net.minecraft.world.item.enchantment.Enchantments;
import org.bukkit.craftbukkit.enchantments.CraftEnchantment;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.support.AbstractTestingBase;
import org.junit.jupiter.api.Test;
@@ -12,7 +13,7 @@ public class NMSCraftItemStackTest extends AbstractTestingBase {
@Test
public void testCloneEnchantedItem() throws Exception {
net.minecraft.world.item.ItemStack nmsItemStack = new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.POTION);
nmsItemStack.enchant(Enchantments.SHARPNESS, 1);
nmsItemStack.enchant(CraftEnchantment.bukkitToMinecraftHolder(Enchantment.SHARPNESS), 1);
ItemStack itemStack = CraftItemStack.asCraftMirror(nmsItemStack);
ItemStack clone = itemStack.clone();
assertThat(clone.getType(), is(itemStack.getType()));

View File

@@ -123,6 +123,8 @@ public class LegacyTest extends AbstractTestingBase {
// 1.20.5
Material.ARMADILLO_SCUTE, Material.ARMADILLO_SPAWN_EGG, Material.BOGGED_SPAWN_EGG, Material.WIND_CHARGE, Material.WOLF_ARMOR, Material.VAULT, Material.HEAVY_CORE, Material.MACE, Material.FLOW_BANNER_PATTERN, Material.GUSTER_BANNER_PATTERN,
Material.FLOW_ARMOR_TRIM_SMITHING_TEMPLATE, Material.BOLT_ARMOR_TRIM_SMITHING_TEMPLATE, Material.FLOW_POTTERY_SHERD, Material.GUSTER_POTTERY_SHERD, Material.SCRAPE_POTTERY_SHERD, Material.BREEZE_ROD, Material.OMINOUS_TRIAL_KEY, Material.OMINOUS_BOTTLE,
// 1.21
Material.MUSIC_DISC_CREATOR, Material.MUSIC_DISC_CREATOR_MUSIC_BOX, Material.MUSIC_DISC_PRECIPICE,
//
Material.LEGACY_AIR, Material.LEGACY_DEAD_BUSH, Material.LEGACY_BURNING_FURNACE, Material.LEGACY_WALL_SIGN, Material.LEGACY_REDSTONE_TORCH_OFF, Material.LEGACY_SKULL, Material.LEGACY_REDSTONE_COMPARATOR_ON, Material.LEGACY_WALL_BANNER, Material.LEGACY_MONSTER_EGG));

View File

@@ -66,7 +66,14 @@ public class ApiVersionTest extends AbstractTestingBase {
@Test
public void testCurrentVersionUpdated() {
ApiVersion apiVersionOne = ApiVersion.getOrCreateVersion(SharedConstants.getCurrentVersion().getName());
ApiVersion apiVersionOne = null;
try {
apiVersionOne = ApiVersion.getOrCreateVersion(SharedConstants.getCurrentVersion().getName());
} catch (IllegalArgumentException ex) {
if (!SharedConstants.getCurrentVersion().isStable()) {
return;
}
}
ApiVersion apiVersionTwo = ApiVersion.CURRENT;
assertEquals(apiVersionOne, apiVersionTwo, "The current version in ApiVersion not match current minecraft version");

View File

@@ -9,9 +9,11 @@ import net.minecraft.world.effect.MobEffectList;
import net.minecraft.world.entity.animal.WolfVariant;
import net.minecraft.world.item.Instrument;
import org.bukkit.GameEvent;
import org.bukkit.JukeboxSong;
import org.bukkit.MusicInstrument;
import org.bukkit.block.BlockType;
import org.bukkit.craftbukkit.CraftGameEvent;
import org.bukkit.craftbukkit.CraftJukeboxSong;
import org.bukkit.craftbukkit.CraftMusicInstrument;
import org.bukkit.craftbukkit.block.CraftBlockType;
import org.bukkit.craftbukkit.damage.CraftDamageType;
@@ -51,6 +53,7 @@ public class RegistriesArgumentProvider implements ArgumentsProvider {
register(TrimMaterial.class, Registries.TRIM_MATERIAL, CraftTrimMaterial.class, net.minecraft.world.item.armortrim.TrimMaterial.class);
register(TrimPattern.class, Registries.TRIM_PATTERN, CraftTrimPattern.class, net.minecraft.world.item.armortrim.TrimPattern.class);
register(DamageType.class, Registries.DAMAGE_TYPE, CraftDamageType.class, net.minecraft.world.damagesource.DamageType.class);
register(JukeboxSong.class, Registries.JUKEBOX_SONG, CraftJukeboxSong.class, net.minecraft.world.item.JukeboxSong.class);
register(Wolf.Variant.class, Registries.WOLF_VARIANT, CraftWolf.CraftVariant.class, WolfVariant.class);
register(ItemType.class, Registries.ITEM, CraftItemType.class, net.minecraft.world.item.Item.class, true);
register(BlockType.class, Registries.BLOCK, CraftBlockType.class, net.minecraft.world.level.block.Block.class, true);