mirror of
https://github.com/PaperMC/Paper.git
synced 2026-11-12 20:32:00 -05:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4b128ed5c | ||
|
|
99237906b9 | ||
|
|
10cb0e367f |
No files matched your search
@@ -185,6 +185,10 @@ tasks.jar {
|
||||
from(generateApiVersioningFile.flatMap { it.outputFile })
|
||||
}
|
||||
|
||||
tasks.compileJava {
|
||||
options.compilerArgs.addAll(listOf("--add-reads", "org.bukkit=ALL-UNNAMED"))
|
||||
}
|
||||
|
||||
abstract class Services {
|
||||
@get:Inject
|
||||
abstract val fileSystemOperations: FileSystemOperations
|
||||
@@ -210,6 +214,9 @@ tasks.withType<Javadoc>().configureEach {
|
||||
)
|
||||
options.tags(projectCustomJavadocTags.map { it.toOptionString() })
|
||||
|
||||
modularity.inferModulePath = false
|
||||
exclude("module-info.java")
|
||||
|
||||
inputs.files(javadocSourcepath).ignoreEmptyDirectories().withPropertyName(javadocSourcepath.name + "-configuration")
|
||||
val javadocSourcepathElements = javadocSourcepath.elements
|
||||
doFirst {
|
||||
|
||||
@@ -10,7 +10,7 @@ public enum GoalType {
|
||||
JUMP,
|
||||
TARGET,
|
||||
/**
|
||||
* Used to map vanilla goals, that are a behavior goal but don't have a type set.
|
||||
* Used to map vanilla goals, that are a behavior goal but don't have a type set...
|
||||
*/
|
||||
UNKNOWN_BEHAVIOR,
|
||||
|
||||
|
||||
+1
-4
@@ -71,10 +71,7 @@ public class PlayerChangeBeaconEffectEvent extends PlayerEvent implements Cancel
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the block at the location associated with the beacon menu.
|
||||
* This block may not be a beacon, for example when the menu is virtual.
|
||||
*
|
||||
* @return the block at the menu's location
|
||||
* @return the beacon block associated with this event
|
||||
*/
|
||||
public Block getBeacon() {
|
||||
return this.beacon;
|
||||
|
||||
+4
-18
@@ -6,18 +6,15 @@ import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.LecternInventory;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@NullMarked
|
||||
public class PlayerLecternPageChangeEvent extends PlayerEvent implements Cancellable {
|
||||
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
private final LecternInventory inventory;
|
||||
private final @Nullable Lectern lectern;
|
||||
private final Lectern lectern;
|
||||
private final ItemStack book;
|
||||
private final PageChangeDirection pageChangeDirection;
|
||||
private final int oldPage;
|
||||
@@ -26,9 +23,8 @@ public class PlayerLecternPageChangeEvent extends PlayerEvent implements Cancell
|
||||
private boolean cancelled;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public PlayerLecternPageChangeEvent(final Player player, final LecternInventory inventory, final @Nullable Lectern lectern, final ItemStack book, final PageChangeDirection pageChangeDirection, final int oldPage, final int newPage) {
|
||||
public PlayerLecternPageChangeEvent(final Player player, final Lectern lectern, final ItemStack book, final PageChangeDirection pageChangeDirection, final int oldPage, final int newPage) {
|
||||
super(player);
|
||||
this.inventory = inventory;
|
||||
this.lectern = lectern;
|
||||
this.book = book;
|
||||
this.pageChangeDirection = pageChangeDirection;
|
||||
@@ -36,22 +32,12 @@ public class PlayerLecternPageChangeEvent extends PlayerEvent implements Cancell
|
||||
this.newPage = newPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the inventory of the lectern.
|
||||
*
|
||||
* @return the Inventory of the Lectern
|
||||
*/
|
||||
public LecternInventory getInventory() {
|
||||
return this.inventory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the lectern involved.
|
||||
*
|
||||
* @return the lectern, or {@code null} if the inventory has no lectern
|
||||
* holder, such as a virtual lectern menu
|
||||
* @return the Lectern
|
||||
*/
|
||||
public @Nullable Lectern getLectern() {
|
||||
public Lectern getLectern() {
|
||||
return this.lectern;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
/**
|
||||
* The Paper API.
|
||||
*/
|
||||
@SuppressWarnings({"requires-transitive-automatic", "deprecation"})
|
||||
module org.bukkit {
|
||||
exports co.aikar.timings;
|
||||
exports co.aikar.util;
|
||||
exports com.destroystokyo.paper.block;
|
||||
exports com.destroystokyo.paper.brigadier;
|
||||
exports com.destroystokyo.paper.entity.ai;
|
||||
exports com.destroystokyo.paper.entity.villager;
|
||||
exports com.destroystokyo.paper.entity;
|
||||
exports com.destroystokyo.paper.event.block;
|
||||
exports com.destroystokyo.paper.event.brigadier;
|
||||
exports com.destroystokyo.paper.event.entity;
|
||||
exports com.destroystokyo.paper.event.inventory;
|
||||
exports com.destroystokyo.paper.event.player;
|
||||
exports com.destroystokyo.paper.event.profile;
|
||||
exports com.destroystokyo.paper.event.server;
|
||||
exports com.destroystokyo.paper.exception;
|
||||
exports com.destroystokyo.paper.inventory.meta;
|
||||
exports com.destroystokyo.paper.loottable;
|
||||
exports com.destroystokyo.paper.network;
|
||||
exports com.destroystokyo.paper.profile;
|
||||
exports com.destroystokyo.paper.util;
|
||||
exports com.destroystokyo.paper.utils;
|
||||
exports com.destroystokyo.paper;
|
||||
exports io.papermc.paper.advancement;
|
||||
exports io.papermc.paper.annotation;
|
||||
exports io.papermc.paper.ban;
|
||||
exports io.papermc.paper.block.bed;
|
||||
exports io.papermc.paper.block.fluid.type;
|
||||
exports io.papermc.paper.block.fluid;
|
||||
exports io.papermc.paper.block.pot;
|
||||
exports io.papermc.paper.block;
|
||||
exports io.papermc.paper.brigadier;
|
||||
exports io.papermc.paper.chat;
|
||||
exports io.papermc.paper.command.brigadier.argument.position;
|
||||
exports io.papermc.paper.command.brigadier.argument.predicate;
|
||||
exports io.papermc.paper.command.brigadier.argument.range;
|
||||
exports io.papermc.paper.command.brigadier.argument.resolvers.selector;
|
||||
exports io.papermc.paper.command.brigadier.argument.resolvers;
|
||||
exports io.papermc.paper.command.brigadier.argument;
|
||||
exports io.papermc.paper.command.brigadier;
|
||||
exports io.papermc.paper.command;
|
||||
exports io.papermc.paper.configuration;
|
||||
exports io.papermc.paper.connection;
|
||||
exports io.papermc.paper.datacomponent.item.attribute;
|
||||
exports io.papermc.paper.datacomponent.item.blocksattacks;
|
||||
exports io.papermc.paper.datacomponent.item.consumable;
|
||||
exports io.papermc.paper.datacomponent.item;
|
||||
exports io.papermc.paper.datacomponent;
|
||||
exports io.papermc.paper.datapack;
|
||||
exports io.papermc.paper.dialog;
|
||||
exports io.papermc.paper.enchantments;
|
||||
exports io.papermc.paper.entity.poi;
|
||||
exports io.papermc.paper.entity;
|
||||
exports io.papermc.paper.event.block;
|
||||
exports io.papermc.paper.event.connection.configuration;
|
||||
exports io.papermc.paper.event.connection;
|
||||
exports io.papermc.paper.event.entity;
|
||||
exports io.papermc.paper.event.executor;
|
||||
exports io.papermc.paper.event.inventory;
|
||||
exports io.papermc.paper.event.packet;
|
||||
exports io.papermc.paper.event.player;
|
||||
exports io.papermc.paper.event.server;
|
||||
exports io.papermc.paper.event.world.border;
|
||||
exports io.papermc.paper.event.world;
|
||||
exports io.papermc.paper.inventory.tooltip;
|
||||
exports io.papermc.paper.inventory;
|
||||
exports io.papermc.paper.item;
|
||||
exports io.papermc.paper.math;
|
||||
exports io.papermc.paper.persistence;
|
||||
exports io.papermc.paper.plugin.bootstrap;
|
||||
exports io.papermc.paper.plugin.configuration;
|
||||
exports io.papermc.paper.plugin.lifecycle.event.handler.configuration;
|
||||
exports io.papermc.paper.plugin.lifecycle.event.handler;
|
||||
exports io.papermc.paper.plugin.lifecycle.event.registrar;
|
||||
exports io.papermc.paper.plugin.lifecycle.event.types;
|
||||
exports io.papermc.paper.plugin.lifecycle.event;
|
||||
exports io.papermc.paper.plugin.loader.library.impl;
|
||||
exports io.papermc.paper.plugin.loader.library;
|
||||
exports io.papermc.paper.plugin.loader;
|
||||
exports io.papermc.paper.plugin.provider.classloader;
|
||||
exports io.papermc.paper.plugin.provider.entrypoint;
|
||||
exports io.papermc.paper.plugin.provider.util;
|
||||
exports io.papermc.paper.plugin;
|
||||
exports io.papermc.paper.potion;
|
||||
exports io.papermc.paper.raytracing;
|
||||
exports io.papermc.paper.registry.data.client;
|
||||
exports io.papermc.paper.registry.data.dialog.action;
|
||||
exports io.papermc.paper.registry.data.dialog.body;
|
||||
exports io.papermc.paper.registry.data.dialog.input;
|
||||
exports io.papermc.paper.registry.data.dialog.type;
|
||||
exports io.papermc.paper.registry.data.dialog;
|
||||
exports io.papermc.paper.registry.data;
|
||||
exports io.papermc.paper.registry.event.type;
|
||||
exports io.papermc.paper.registry.event;
|
||||
exports io.papermc.paper.registry.holder;
|
||||
exports io.papermc.paper.registry.keys.tags;
|
||||
exports io.papermc.paper.registry.keys;
|
||||
exports io.papermc.paper.registry.set;
|
||||
exports io.papermc.paper.registry.tag;
|
||||
exports io.papermc.paper.registry;
|
||||
exports io.papermc.paper.scoreboard.numbers;
|
||||
exports io.papermc.paper.tag;
|
||||
exports io.papermc.paper.text;
|
||||
exports io.papermc.paper.threadedregions.scheduler;
|
||||
exports io.papermc.paper.threadedregions;
|
||||
exports io.papermc.paper.util;
|
||||
exports io.papermc.paper.world.chunk;
|
||||
exports io.papermc.paper.world.damagesource;
|
||||
exports io.papermc.paper.world.flag;
|
||||
exports io.papermc.paper.world;
|
||||
exports io.papermc.paper;
|
||||
exports org.bukkit.advancement;
|
||||
exports org.bukkit.attribute;
|
||||
exports org.bukkit.ban;
|
||||
exports org.bukkit.block.banner;
|
||||
exports org.bukkit.block.data.type;
|
||||
exports org.bukkit.block.data;
|
||||
exports org.bukkit.block.sign;
|
||||
exports org.bukkit.block.spawner;
|
||||
exports org.bukkit.block.structure;
|
||||
exports org.bukkit.block;
|
||||
exports org.bukkit.boss;
|
||||
exports org.bukkit.command.defaults;
|
||||
exports org.bukkit.command;
|
||||
exports org.bukkit.configuration.file;
|
||||
exports org.bukkit.configuration.serialization;
|
||||
exports org.bukkit.configuration;
|
||||
exports org.bukkit.conversations;
|
||||
exports org.bukkit.damage;
|
||||
exports org.bukkit.enchantments;
|
||||
exports org.bukkit.entity.boat;
|
||||
exports org.bukkit.entity.memory;
|
||||
exports org.bukkit.entity.minecart;
|
||||
exports org.bukkit.entity;
|
||||
exports org.bukkit.event.block;
|
||||
exports org.bukkit.event.command;
|
||||
exports org.bukkit.event.enchantment;
|
||||
exports org.bukkit.event.entity;
|
||||
exports org.bukkit.event.hanging;
|
||||
exports org.bukkit.event.inventory;
|
||||
exports org.bukkit.event.player;
|
||||
exports org.bukkit.event.raid;
|
||||
exports org.bukkit.event.server;
|
||||
exports org.bukkit.event.vehicle;
|
||||
exports org.bukkit.event.weather;
|
||||
exports org.bukkit.event.world;
|
||||
exports org.bukkit.event;
|
||||
exports org.bukkit.generator.structure;
|
||||
exports org.bukkit.generator;
|
||||
exports org.bukkit.help;
|
||||
exports org.bukkit.inventory.meta.components;
|
||||
exports org.bukkit.inventory.meta.tags;
|
||||
exports org.bukkit.inventory.meta.trim;
|
||||
exports org.bukkit.inventory.meta;
|
||||
exports org.bukkit.inventory.recipe;
|
||||
exports org.bukkit.inventory.view.builder;
|
||||
exports org.bukkit.inventory.view;
|
||||
exports org.bukkit.inventory;
|
||||
exports org.bukkit.loot;
|
||||
exports org.bukkit.map;
|
||||
exports org.bukkit.material.types;
|
||||
exports org.bukkit.material;
|
||||
exports org.bukkit.metadata;
|
||||
exports org.bukkit.packs;
|
||||
exports org.bukkit.permissions;
|
||||
exports org.bukkit.persistence;
|
||||
exports org.bukkit.plugin.java;
|
||||
exports org.bukkit.plugin.messaging;
|
||||
exports org.bukkit.plugin;
|
||||
exports org.bukkit.potion;
|
||||
exports org.bukkit.profile;
|
||||
exports org.bukkit.projectiles;
|
||||
exports org.bukkit.scheduler;
|
||||
exports org.bukkit.scoreboard;
|
||||
exports org.bukkit.spawner;
|
||||
exports org.bukkit.structure;
|
||||
exports org.bukkit.tag;
|
||||
exports org.bukkit.util.io;
|
||||
exports org.bukkit.util.noise;
|
||||
exports org.bukkit.util.permissions;
|
||||
exports org.bukkit.util;
|
||||
exports org.bukkit;
|
||||
exports org.spigotmc.event.player;
|
||||
exports org.spigotmc;
|
||||
|
||||
requires transitive java.desktop;
|
||||
requires transitive java.logging;
|
||||
|
||||
requires transitive com.google.common;
|
||||
requires transitive com.google.gson;
|
||||
requires transitive it.unimi.dsi.fastutil;
|
||||
requires transitive net.kyori.adventure.api;
|
||||
requires transitive net.kyori.adventure.key;
|
||||
requires transitive net.kyori.adventure.text.logger.slf4j;
|
||||
requires transitive net.kyori.adventure.text.minimessage;
|
||||
requires transitive net.kyori.adventure.text.serializer.gson;
|
||||
requires transitive net.kyori.adventure.text.serializer.legacy;
|
||||
requires transitive net.kyori.adventure.text.serializer.plain;
|
||||
requires transitive org.apache.logging.log4j;
|
||||
requires transitive org.apache.maven.resolver;
|
||||
requires transitive org.joml;
|
||||
requires transitive org.jspecify;
|
||||
requires transitive org.slf4j;
|
||||
requires transitive org.yaml.snakeyaml;
|
||||
|
||||
requires org.apache.commons.lang3;
|
||||
requires org.apache.maven.resolver.connector.basic;
|
||||
requires org.apache.maven.resolver.transport.http;
|
||||
requires org.apache.maven.resolver.impl;
|
||||
requires org.apache.maven.resolver.spi;
|
||||
|
||||
requires static transitive org.checkerframework.checker.qual;
|
||||
requires static org.jetbrains.annotations;
|
||||
|
||||
uses io.papermc.paper.InternalAPIBridge;
|
||||
uses io.papermc.paper.ServerBuildInfo;
|
||||
uses io.papermc.paper.command.brigadier.MessageComponentSerializer;
|
||||
uses io.papermc.paper.registry.RegistryAccess;
|
||||
uses io.papermc.paper.registry.data.InlinedRegistryBuilderProvider;
|
||||
uses io.papermc.paper.registry.data.dialog.DialogInstancesProvider;
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.bukkit.inventory.BlockInventoryHolder;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Represents a captured state of a lectern.
|
||||
*/
|
||||
@NullMarked
|
||||
public interface Lectern extends io.papermc.paper.block.TileStateInventoryHolder {
|
||||
public interface Lectern extends io.papermc.paper.block.TileStateInventoryHolder { // Paper - TileStateInventoryHolder
|
||||
|
||||
/**
|
||||
* Get the current lectern page.
|
||||
@@ -17,11 +18,13 @@ public interface Lectern extends io.papermc.paper.block.TileStateInventoryHolder
|
||||
|
||||
/**
|
||||
* Set the current lectern page.
|
||||
* <br>
|
||||
*
|
||||
* If the page is greater than the number of pages of the book currently in
|
||||
* the inventory, then behavior is undefined.
|
||||
*
|
||||
* @param page new page
|
||||
*/
|
||||
void setPage(int page);
|
||||
|
||||
// Paper - moved to TileStateInventoryHolder
|
||||
}
|
||||
@@ -40,7 +40,6 @@ import org.bukkit.util.BoundingBox;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.checkerframework.checker.index.qual.NonNegative;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.UnmodifiableView;
|
||||
@@ -889,32 +888,10 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
|
||||
void setInvulnerable(boolean flag);
|
||||
|
||||
/**
|
||||
* Gets the remaining duration of this entity's temporary invulnerability.
|
||||
* <p>
|
||||
* This is separate from permanent invulnerability and the damage cooldown
|
||||
* exposed by {@link LivingEntity#getNoDamageTicks()}.
|
||||
*
|
||||
* @return the remaining temporary invulnerability duration, in ticks
|
||||
*/
|
||||
int getInvulnerableTime();
|
||||
|
||||
/**
|
||||
* Sets the remaining duration of this entity's temporary invulnerability.
|
||||
* <p>
|
||||
* Setting this to {@code 0} removes temporary invulnerability.
|
||||
* This does not change the entity's permanent invulnerability state.
|
||||
*
|
||||
* @param ticks the temporary invulnerability duration, in ticks
|
||||
* @throws IllegalArgumentException if ticks is negative
|
||||
*/
|
||||
void setInvulnerableTime(@NonNegative int ticks);
|
||||
|
||||
/**
|
||||
* Gets the entity's current invulnerability state, including permanent and temporary invulnerability.
|
||||
* Gets the current invulnerability state of the entity set by {@link #setInvulnerable(boolean)}.
|
||||
*
|
||||
* @return whether the entity is invulnerable
|
||||
* @see #isInvulnerableTo(DamageSource)
|
||||
* @see #getInvulnerableTime()
|
||||
*/
|
||||
boolean isMarkedInvulnerable();
|
||||
|
||||
|
||||
@@ -4,49 +4,35 @@ import org.bukkit.block.Lectern;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.LecternInventory;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* This event is called when a player clicks the button to take a book of a
|
||||
* Lectern. If this event is cancelled the book remains on the lectern.
|
||||
*/
|
||||
@NullMarked
|
||||
public class PlayerTakeLecternBookEvent extends PlayerEvent implements Cancellable {
|
||||
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
private final LecternInventory inventory;
|
||||
private final @Nullable Lectern lectern;
|
||||
private final Lectern lectern;
|
||||
private boolean cancelled;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public PlayerTakeLecternBookEvent(final Player player, final LecternInventory inventory, final @Nullable Lectern lectern) {
|
||||
public PlayerTakeLecternBookEvent(@NotNull Player player, @NotNull Lectern lectern) {
|
||||
super(player);
|
||||
this.inventory = inventory;
|
||||
this.lectern = lectern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the inventory of the lectern.
|
||||
*
|
||||
* @return the Inventory of the Lectern
|
||||
*/
|
||||
public LecternInventory getInventory() {
|
||||
return this.inventory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the lectern involved.
|
||||
*
|
||||
* @return the lectern, or {@code null} if the inventory has no lectern
|
||||
* holder, such as a virtual lectern menu
|
||||
* @return the Lectern
|
||||
*/
|
||||
public @Nullable Lectern getLectern() {
|
||||
@NotNull
|
||||
public Lectern getLectern() {
|
||||
return this.lectern;
|
||||
}
|
||||
|
||||
@@ -55,8 +41,9 @@ public class PlayerTakeLecternBookEvent extends PlayerEvent implements Cancellab
|
||||
*
|
||||
* @return the ItemStack on the Lectern
|
||||
*/
|
||||
public @Nullable ItemStack getBook() {
|
||||
return this.getInventory().getItem(0);
|
||||
@Nullable
|
||||
public ItemStack getBook() {
|
||||
return this.lectern.getInventory().getItem(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,15 +52,17 @@ public class PlayerTakeLecternBookEvent extends PlayerEvent implements Cancellab
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(final boolean cancel) {
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancelled = cancel;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
package org.bukkit.inventory;
|
||||
|
||||
import org.bukkit.block.Lectern;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Interface to the inventory of a Lectern.
|
||||
*/
|
||||
@NullMarked
|
||||
public interface LecternInventory extends Inventory {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@Nullable Lectern getHolder();
|
||||
public Lectern getHolder();
|
||||
|
||||
// Paper start
|
||||
/**
|
||||
* Gets the lectern's held book.
|
||||
*
|
||||
* @return book set in the lectern
|
||||
*/
|
||||
default @Nullable ItemStack getBook() {
|
||||
@Nullable
|
||||
default ItemStack getBook() {
|
||||
return getItem(0);
|
||||
}
|
||||
|
||||
@@ -27,7 +28,8 @@ public interface LecternInventory extends Inventory {
|
||||
*
|
||||
* @param book the new book
|
||||
*/
|
||||
default void setBook(final @Nullable ItemStack book) {
|
||||
this.setItem(0, book);
|
||||
default void setBook(@Nullable ItemStack book) {
|
||||
setItem(0, book);
|
||||
}
|
||||
// Paper end
|
||||
}
|
||||
@@ -31,7 +31,7 @@ index a47b79c188f459e8b8f8cf0872a610b461ebde59..5ddfc7c9df08e9abedcb0fbaa0f614a8
|
||||
protected void onOpen(final Level level, final BlockPos pos, final BlockState state) {
|
||||
BarrelBlockEntity.this.playSound(state, SoundEvents.BARREL_OPEN);
|
||||
diff --git a/net/minecraft/world/level/block/entity/ChestBlockEntity.java b/net/minecraft/world/level/block/entity/ChestBlockEntity.java
|
||||
index 58e532e913f360280f5bee461d1e86a63f4f76ed..13ba29eaaea8bdc8d8dff14a9504b7918006d9fc 100644
|
||||
index 06878204e0df42fc35cfa380413986a045ee229d..c1cdced85052cbc600cf8f9d81e38ab37817a14a 100644
|
||||
--- a/net/minecraft/world/level/block/entity/ChestBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/ChestBlockEntity.java
|
||||
@@ -30,6 +30,13 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement
|
||||
|
||||
+15
-4
@@ -7,19 +7,27 @@ Optimise the stream.anyMatch statement to move to a bitset
|
||||
where we can replace the call with a single bitwise operation.
|
||||
|
||||
diff --git a/net/minecraft/world/entity/ai/goal/Goal.java b/net/minecraft/world/entity/ai/goal/Goal.java
|
||||
index 94e48cd6a91eea44d656f4b55376b1762f7a7210..8c30d5d59f8ea6c405db0758e629e7793f88e8cc 100644
|
||||
index aa5f0e00daf26650b943a24676638581e494a112..60e0d618c603caef5e3516c9fdfc63ff45a7cdff 100644
|
||||
--- a/net/minecraft/world/entity/ai/goal/Goal.java
|
||||
+++ b/net/minecraft/world/entity/ai/goal/Goal.java
|
||||
@@ -7,7 +7,7 @@ import net.minecraft.world.entity.Entity;
|
||||
@@ -7,7 +7,15 @@ import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
public abstract class Goal {
|
||||
- private final EnumSet<Goal.Flag> flags = EnumSet.noneOf(Goal.Flag.class);
|
||||
+ private final ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet<net.minecraft.world.entity.ai.goal.Goal.Flag> goalTypes = new ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from GoalSelector
|
||||
+
|
||||
+ // Paper start - remove streams from GoalSelector; make sure types are not empty
|
||||
+ protected Goal() {
|
||||
+ if (this.goalTypes.size() == 0) {
|
||||
+ this.goalTypes.addUnchecked(Flag.UNKNOWN_BEHAVIOR);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - remove streams from GoalSelector
|
||||
|
||||
public abstract boolean canUse();
|
||||
|
||||
@@ -33,8 +33,10 @@ public abstract class Goal {
|
||||
@@ -33,8 +41,13 @@ public abstract class Goal {
|
||||
}
|
||||
|
||||
public void setFlags(final EnumSet<Goal.Flag> requiredControlFlags) {
|
||||
@@ -28,11 +36,14 @@ index 94e48cd6a91eea44d656f4b55376b1762f7a7210..8c30d5d59f8ea6c405db0758e629e779
|
||||
+ // Paper start - remove streams from GoalSelector
|
||||
+ this.goalTypes.clear();
|
||||
+ this.goalTypes.addAllUnchecked(requiredControlFlags);
|
||||
+ if (this.goalTypes.size() == 0) {
|
||||
+ this.goalTypes.addUnchecked(Flag.UNKNOWN_BEHAVIOR);
|
||||
+ }
|
||||
+ // Paper end - remove streams from GoalSelector
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -42,18 +44,20 @@ public abstract class Goal {
|
||||
@@ -42,18 +55,20 @@ public abstract class Goal {
|
||||
return this.getClass().getSimpleName();
|
||||
}
|
||||
|
||||
|
||||
@@ -33,10 +33,10 @@ index 01873fc32799c3429771ef6da77d370b83b630e8..5b7ed8e5067683143c99473a126e17ba
|
||||
scopedCollector.forChild(entity.problemPath()), entity.registryAccess()
|
||||
);
|
||||
diff --git a/net/minecraft/world/entity/EntityType.java b/net/minecraft/world/entity/EntityType.java
|
||||
index abbe947c09a6be08a233710b680646b38173ca3d..bffb559a49de9bd8f25ed25ecc49ffd47e1401fe 100644
|
||||
index b94e06a2982ff6815338eca3f323a00453a88162..04b9138882054b8d5160463987821d9ad205c628 100644
|
||||
--- a/net/minecraft/world/entity/EntityType.java
|
||||
+++ b/net/minecraft/world/entity/EntityType.java
|
||||
@@ -506,7 +506,18 @@ public class EntityType<T extends Entity> implements EntityTypeTest<Entity, T>,
|
||||
@@ -499,7 +499,18 @@ public class EntityType<T extends Entity> implements EntityTypeTest<Entity, T>,
|
||||
}
|
||||
|
||||
public static Stream<Entity> loadEntitiesRecursive(final ValueInput.ValueInputList entities, final Level level, final EntitySpawnReason reason) {
|
||||
|
||||
@@ -95,10 +95,10 @@ index d3f17088d8f0592ef1231cf3f8bb3ca83170de0b..ddda24a55201de2136fc6dd2cb863d60
|
||||
// CraftBukkit start - data containers
|
||||
private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry();
|
||||
public final org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer persistentDataContainer;
|
||||
@@ -210,6 +211,7 @@ public abstract class BlockEntity implements DebugValueSource, TypedInstance<Blo
|
||||
@@ -209,6 +210,7 @@ public abstract class BlockEntity implements DebugValueSource, TypedInstance<Blo
|
||||
|
||||
public void setChanged() {
|
||||
if (this.level != null && this.real) { // Paper - don't broadcast for fake block entities
|
||||
if (this.level != null) {
|
||||
+ if (ignoreBlockEntityUpdates) return; // Paper - Perf: Optimize Hoppers
|
||||
setChanged(this.level, this.worldPosition, this.blockState);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final Holder.Reference<EntityType<?>> builtInRegistryHolder = BuiltInRegistries.ENTITY_TYPE.createIntrusiveHolder(this);
|
||||
public static final Codec<EntityType<?>> CODEC = BuiltInRegistries.ENTITY_TYPE.byNameCodec();
|
||||
@@ -124,14 +_,37 @@
|
||||
@@ -124,6 +_,22 @@
|
||||
final boolean tryMoveDown,
|
||||
final boolean movedUp
|
||||
) {
|
||||
@@ -30,16 +30,8 @@
|
||||
+ // CraftBukkit end
|
||||
PostSpawnProcessor<T> postSpawnConfig;
|
||||
if (itemStack != null) {
|
||||
- postSpawnConfig = createDefaultStackConfig(level, itemStack, user);
|
||||
+ // Paper start - Override spawnReason with createSpawnReason if not Paper.SpawnReason it's used to avoid bad fallback reason behavior
|
||||
+ TypedEntityData<EntityType<?>> typedEntityData = itemStack.get(DataComponents.ENTITY_DATA);
|
||||
+ if (typedEntityData != null && !typedEntityData.contains("Paper.SpawnReason")) {
|
||||
+ postSpawnConfig = appendCustomEntityStackConfig(appendComponentsConfig(entity -> entity.spawnReason = createSpawnReason, itemStack), level, itemStack, user);
|
||||
+ } else {
|
||||
+ postSpawnConfig = createDefaultStackConfig(level, itemStack, user);
|
||||
+ }
|
||||
+ // Paper end - Override spawnReason with createSpawnReason if not Paper.SpawnReason it's used to avoid bad fallback reason behavior
|
||||
} else {
|
||||
postSpawnConfig = createDefaultStackConfig(level, itemStack, user);
|
||||
@@ -131,7 +_,7 @@
|
||||
postSpawnConfig = PostSpawnProcessor.nop();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,11 +18,10 @@
|
||||
protected int adjustedTickDelay(final int ticks) {
|
||||
return this.requiresUpdateEveryTick() ? ticks : reducedTickDelay(ticks);
|
||||
}
|
||||
@@ -61,6 +_,17 @@
|
||||
protected static ServerLevel getServerLevel(final Level level) {
|
||||
@@ -62,7 +_,19 @@
|
||||
return (ServerLevel)level;
|
||||
}
|
||||
+
|
||||
|
||||
+ // Paper start - Mob goal api
|
||||
+ private com.destroystokyo.paper.entity.ai.PaperGoal<?> paperGoal;
|
||||
+ public <T extends org.bukkit.entity.Mob> com.destroystokyo.paper.entity.ai.Goal<T> asPaperGoal() {
|
||||
@@ -33,6 +32,9 @@
|
||||
+ return (com.destroystokyo.paper.entity.ai.Goal<T>) this.paperGoal;
|
||||
+ }
|
||||
+ // Paper end - Mob goal api
|
||||
|
||||
+
|
||||
public enum Flag {
|
||||
+ UNKNOWN_BEHAVIOR, // Paper - add UNKNOWN_BEHAVIOR
|
||||
MOVE,
|
||||
LOOK,
|
||||
JUMP,
|
||||
@@ -56,7 +56,7 @@
|
||||
- this.setData(0, currentPage - 1);
|
||||
+ // Paper start - Add PlayerLecternPageChangeEvent
|
||||
+ bukkitView = (org.bukkit.craftbukkit.inventory.CraftInventoryLectern) getBukkitView().getTopInventory();
|
||||
+ playerLecternPageChangeEvent = new io.papermc.paper.event.player.PlayerLecternPageChangeEvent((org.bukkit.entity.Player) player.getBukkitEntity(), bukkitView, bukkitView.getHolder(), bukkitView.getBook(), io.papermc.paper.event.player.PlayerLecternPageChangeEvent.PageChangeDirection.LEFT, currentPage, currentPage - 1);
|
||||
+ playerLecternPageChangeEvent = new io.papermc.paper.event.player.PlayerLecternPageChangeEvent((org.bukkit.entity.Player) player.getBukkitEntity(), bukkitView.getHolder(), bukkitView.getBook(), io.papermc.paper.event.player.PlayerLecternPageChangeEvent.PageChangeDirection.LEFT, currentPage, currentPage - 1);
|
||||
+ if (!playerLecternPageChangeEvent.callEvent()) {
|
||||
+ return false;
|
||||
+ }
|
||||
@@ -69,7 +69,7 @@
|
||||
- this.setData(0, currentPage + 1);
|
||||
+ // Paper start - Add PlayerLecternPageChangeEvent
|
||||
+ bukkitView = (org.bukkit.craftbukkit.inventory.CraftInventoryLectern) getBukkitView().getTopInventory();
|
||||
+ playerLecternPageChangeEvent = new io.papermc.paper.event.player.PlayerLecternPageChangeEvent((org.bukkit.entity.Player) player.getBukkitEntity(), bukkitView, bukkitView.getHolder(), bukkitView.getBook(), io.papermc.paper.event.player.PlayerLecternPageChangeEvent.PageChangeDirection.RIGHT, currentPage, currentPage + 1);
|
||||
+ playerLecternPageChangeEvent = new io.papermc.paper.event.player.PlayerLecternPageChangeEvent((org.bukkit.entity.Player) player.getBukkitEntity(), bukkitView.getHolder(), bukkitView.getBook(), io.papermc.paper.event.player.PlayerLecternPageChangeEvent.PageChangeDirection.RIGHT, currentPage, currentPage + 1);
|
||||
+ if (!playerLecternPageChangeEvent.callEvent()) {
|
||||
+ return false;
|
||||
+ }
|
||||
@@ -83,7 +83,7 @@
|
||||
}
|
||||
|
||||
+ // CraftBukkit start - Event for taking the book
|
||||
+ org.bukkit.event.player.PlayerTakeLecternBookEvent event = new org.bukkit.event.player.PlayerTakeLecternBookEvent(this.player, this.getBukkitView().getTopInventory(), this.getBukkitView().getTopInventory().getHolder());
|
||||
+ org.bukkit.event.player.PlayerTakeLecternBookEvent event = new org.bukkit.event.player.PlayerTakeLecternBookEvent(this.player, this.getBukkitView().getTopInventory().getHolder());
|
||||
+ if (!event.callEvent()) {
|
||||
+ return false;
|
||||
+ }
|
||||
|
||||
+2
-18
@@ -11,14 +11,7 @@
|
||||
private static final Codec<BlockEntityType<?>> TYPE_CODEC = BuiltInRegistries.BLOCK_ENTITY_TYPE.byNameCodec();
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final BlockEntityType<?> type;
|
||||
@@ -47,12 +_,14 @@
|
||||
protected boolean remove;
|
||||
private BlockState blockState;
|
||||
private DataComponentMap components = DataComponentMap.EMPTY;
|
||||
+ public boolean real = true; // Paper - mark block entities that aren't actually in the level
|
||||
|
||||
public BlockEntity(final BlockEntityType<?> type, final BlockPos worldPosition, final BlockState blockState) {
|
||||
this.type = type;
|
||||
@@ -53,6 +_,7 @@
|
||||
this.worldPosition = worldPosition.immutable();
|
||||
this.validateBlockState(blockState);
|
||||
this.blockState = blockState;
|
||||
@@ -72,15 +65,6 @@
|
||||
}
|
||||
|
||||
public final CompoundTag saveWithFullMetadata(final HolderLookup.Provider registries) {
|
||||
@@ -190,7 +_,7 @@
|
||||
}
|
||||
|
||||
public void setChanged() {
|
||||
- if (this.level != null) {
|
||||
+ if (this.level != null && this.real) { // Paper - don't broadcast for fake block entities
|
||||
setChanged(this.level, this.worldPosition, this.blockState);
|
||||
}
|
||||
}
|
||||
@@ -278,6 +_,12 @@
|
||||
}
|
||||
|
||||
@@ -116,7 +100,7 @@
|
||||
+ }
|
||||
+
|
||||
+ public org.bukkit.inventory.@Nullable InventoryHolder getOwner(boolean useSnapshot) {
|
||||
+ if (this.level == null || !this.real) return null; // Paper - fake block entities have no owner
|
||||
+ if (this.level == null) return null;
|
||||
+ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(this.level, this.worldPosition);
|
||||
+ org.bukkit.block.BlockState state = block.getState(useSnapshot); // Paper
|
||||
+ return state instanceof final org.bukkit.inventory.InventoryHolder inventoryHolder ? inventoryHolder : null;
|
||||
|
||||
-16
@@ -41,19 +41,3 @@
|
||||
protected ChestBlockEntity(final BlockEntityType<?> type, final BlockPos worldPosition, final BlockState blockState) {
|
||||
super(type, worldPosition, blockState);
|
||||
}
|
||||
@@ -129,6 +_,7 @@
|
||||
|
||||
@Override
|
||||
public void startOpen(final ContainerUser containerUser) {
|
||||
+ if (!this.real) return; // Paper - don't broadcast for fake block entities
|
||||
if (!this.remove && !containerUser.getLivingEntity().isSpectator()) {
|
||||
this.openersCounter
|
||||
.incrementOpeners(
|
||||
@@ -139,6 +_,7 @@
|
||||
|
||||
@Override
|
||||
public void stopOpen(final ContainerUser containerUser) {
|
||||
+ if (!this.real) return; // Paper - don't broadcast for fake block entities
|
||||
if (!this.remove && !containerUser.getLivingEntity().isSpectator()) {
|
||||
this.openersCounter.decrementOpeners(containerUser.getLivingEntity(), this.getLevel(), this.getBlockPos(), this.getBlockState());
|
||||
}
|
||||
+2
-11
@@ -61,7 +61,7 @@
|
||||
+ // CraftBukkit start
|
||||
+ if (slot == 0) {
|
||||
+ LecternBlockEntity.this.setBook(itemStack);
|
||||
+ if (LecternBlockEntity.this.getLevel() != null && LecternBlockEntity.this.real) { // Paper - don't update the block for fake block entities
|
||||
+ if (LecternBlockEntity.this.getLevel() != null) {
|
||||
+ LecternBlock.resetBookState(null, LecternBlockEntity.this.getLevel(), LecternBlockEntity.this.getBlockPos(), LecternBlockEntity.this.getBlockState(), LecternBlockEntity.this.hasBook());
|
||||
+ }
|
||||
+ }
|
||||
@@ -75,21 +75,12 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -146,7 +_,7 @@
|
||||
private void onBookItemRemove() {
|
||||
this.page = 0;
|
||||
this.pageCount = 0;
|
||||
- LecternBlock.resetBookState(null, this.getLevel(), this.getBlockPos(), this.getBlockState(), false);
|
||||
+ if (this.level != null && this.real) LecternBlock.resetBookState(null, this.getLevel(), this.getBlockPos(), this.getBlockState(), false); // Paper - don't update the block for fake block entities
|
||||
}
|
||||
|
||||
public void setBook(final ItemStack book, final @Nullable Player resolutionContext) {
|
||||
@@ -161,7 +_,7 @@
|
||||
if (newPage != this.page) {
|
||||
this.page = newPage;
|
||||
this.setChanged();
|
||||
- LecternBlock.signalPageChange(this.getLevel(), this.getBlockPos(), this.getBlockState());
|
||||
+ if (this.level != null && this.real) LecternBlock.signalPageChange(this.getLevel(), this.getBlockPos(), this.getBlockState()); // CraftBukkit // Paper - don't update the block for fake block entities
|
||||
+ if (this.level != null) LecternBlock.signalPageChange(this.getLevel(), this.getBlockPos(), this.getBlockState()); // CraftBukkit
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -47,7 +47,7 @@
|
||||
}
|
||||
|
||||
this.openCount++;
|
||||
+ if (this.opened || !this.real) return; // CraftBukkit - only animate if the ShulkerBox hasn't been forced open already by an API call // Paper - don't animate fake block entities
|
||||
+ if (this.opened) return; // CraftBukkit - only animate if the ShulkerBox hasn't been forced open already by an API call
|
||||
this.level.blockEvent(this.worldPosition, this.getBlockState().getBlock(), EVENT_SET_OPEN_COUNT, this.openCount);
|
||||
if (this.openCount == 1) {
|
||||
this.level.gameEvent(containerUser.getLivingEntity(), GameEvent.CONTAINER_OPEN, this.worldPosition);
|
||||
@@ -55,7 +55,7 @@
|
||||
public void stopOpen(final ContainerUser containerUser) {
|
||||
if (!this.remove && !containerUser.getLivingEntity().isSpectator()) {
|
||||
this.openCount--;
|
||||
+ if (this.opened || !this.real) return; // CraftBukkit - only animate if the ShulkerBox hasn't been forced open already by an API call. // Paper - don't animate fake block entities
|
||||
+ if (this.opened) return; // CraftBukkit - only animate if the ShulkerBox hasn't been forced open already by an API call.
|
||||
this.level.blockEvent(this.worldPosition, this.getBlockState().getBlock(), EVENT_SET_OPEN_COUNT, this.openCount);
|
||||
if (this.openCount <= 0) {
|
||||
this.level.gameEvent(containerUser.getLivingEntity(), GameEvent.CONTAINER_CLOSE, this.worldPosition);
|
||||
-4
@@ -45,10 +45,6 @@ public final class OptimizedSmallEnumSet<E extends Enum<E>> {
|
||||
return Long.bitCount(this.backingSet);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
public void addAllUnchecked(final Collection<E> enums) {
|
||||
for (final E element : enums) {
|
||||
if (element == null) {
|
||||
|
||||
@@ -212,15 +212,10 @@ public class MobGoalHelper {
|
||||
public static EnumSet<GoalType> vanillaToPaper(Goal goal) {
|
||||
EnumSet<GoalType> goals = EnumSet.noneOf(GoalType.class);
|
||||
for (GoalType type : GoalType.values()) {
|
||||
if (type != GoalType.UNKNOWN_BEHAVIOR && goal.hasFlag(paperToVanilla(type))) {
|
||||
if (goal.hasFlag(paperToVanilla(type))) {
|
||||
goals.add(type);
|
||||
}
|
||||
}
|
||||
|
||||
if (goals.isEmpty()) {
|
||||
goals.add(GoalType.UNKNOWN_BEHAVIOR);
|
||||
}
|
||||
|
||||
return goals;
|
||||
}
|
||||
|
||||
@@ -229,6 +224,7 @@ public class MobGoalHelper {
|
||||
case MOVE -> GoalType.MOVE;
|
||||
case LOOK -> GoalType.LOOK;
|
||||
case JUMP -> GoalType.JUMP;
|
||||
case UNKNOWN_BEHAVIOR -> GoalType.UNKNOWN_BEHAVIOR;
|
||||
case TARGET -> GoalType.TARGET;
|
||||
};
|
||||
}
|
||||
@@ -236,9 +232,7 @@ public class MobGoalHelper {
|
||||
public static EnumSet<Goal.Flag> paperToVanilla(EnumSet<GoalType> types) {
|
||||
EnumSet<Goal.Flag> goals = EnumSet.noneOf(Goal.Flag.class);
|
||||
for (GoalType type : types) {
|
||||
if (type != GoalType.UNKNOWN_BEHAVIOR) {
|
||||
goals.add(paperToVanilla(type));
|
||||
}
|
||||
goals.add(paperToVanilla(type));
|
||||
}
|
||||
return goals;
|
||||
}
|
||||
@@ -248,8 +242,8 @@ public class MobGoalHelper {
|
||||
case MOVE -> Goal.Flag.MOVE;
|
||||
case LOOK -> Goal.Flag.LOOK;
|
||||
case JUMP -> Goal.Flag.JUMP;
|
||||
case UNKNOWN_BEHAVIOR -> Goal.Flag.UNKNOWN_BEHAVIOR;
|
||||
case TARGET -> Goal.Flag.TARGET;
|
||||
default -> throw new IllegalArgumentException(type + " does not have a vanilla representation!");
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,9 @@ public class PaperCustomGoal<T extends Mob> extends net.minecraft.world.entity.a
|
||||
this.handle = handle;
|
||||
|
||||
this.setFlags(MobGoalHelper.paperToVanilla(handle.getTypes()));
|
||||
if (this.getFlags().size() == 0) {
|
||||
this.addFlag(Flag.UNKNOWN_BEHAVIOR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -11,7 +11,6 @@ import net.minecraft.world.entity.ai.goal.WrappedGoal;
|
||||
import org.bukkit.craftbukkit.entity.CraftMob;
|
||||
import org.bukkit.entity.Mob;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@NullMarked
|
||||
public class PaperMobGoals implements MobGoals {
|
||||
@@ -86,7 +85,7 @@ public class PaperMobGoals implements MobGoals {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Mob> @Nullable Goal<T> getGoal(T mob, GoalKey<T> key) {
|
||||
public <T extends Mob> Goal<T> getGoal(T mob, GoalKey<T> key) {
|
||||
for (Goal<T> g : getAllGoals(mob)) {
|
||||
if (g.getKey().equals(key)) {
|
||||
return g;
|
||||
@@ -120,16 +119,15 @@ public class PaperMobGoals implements MobGoals {
|
||||
CraftMob craftMob = (CraftMob) mob;
|
||||
Set<Goal<T>> goals = new HashSet<>();
|
||||
for (WrappedGoal item : getHandle(craftMob, type).getAvailableGoals()) {
|
||||
final net.minecraft.world.entity.ai.goal.Goal goal = item.getGoal();
|
||||
if (type == GoalType.UNKNOWN_BEHAVIOR ? !goal.getFlags().isEmpty() : !goal.hasFlag(MobGoalHelper.paperToVanilla(type))) {
|
||||
if (!item.getGoal().hasFlag(MobGoalHelper.paperToVanilla(type))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (goal instanceof PaperCustomGoal) {
|
||||
if (item.getGoal() instanceof PaperCustomGoal) {
|
||||
//noinspection unchecked
|
||||
goals.add(((PaperCustomGoal<T>) goal).getHandle());
|
||||
goals.add(((PaperCustomGoal<T>) item.getGoal()).getHandle());
|
||||
} else {
|
||||
goals.add(goal.asPaperGoal());
|
||||
goals.add(item.getGoal().asPaperGoal());
|
||||
}
|
||||
}
|
||||
return goals;
|
||||
@@ -144,16 +142,15 @@ public class PaperMobGoals implements MobGoals {
|
||||
continue;
|
||||
}
|
||||
for (WrappedGoal item : getHandle(craftMob, internalType).getAvailableGoals()) {
|
||||
final net.minecraft.world.entity.ai.goal.Goal goal = item.getGoal();
|
||||
if (type == GoalType.UNKNOWN_BEHAVIOR ? goal.getFlags().isEmpty() : goal.hasFlag(MobGoalHelper.paperToVanilla(type))) {
|
||||
if (item.getGoal().hasFlag(MobGoalHelper.paperToVanilla(type))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (goal instanceof PaperCustomGoal) {
|
||||
if (item.getGoal() instanceof PaperCustomGoal) {
|
||||
//noinspection unchecked
|
||||
goals.add(((PaperCustomGoal<T>) goal).getHandle());
|
||||
goals.add(((PaperCustomGoal<T>) item.getGoal()).getHandle());
|
||||
} else {
|
||||
goals.add(goal.asPaperGoal());
|
||||
goals.add(item.getGoal().asPaperGoal());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,14 +172,13 @@ public class PaperMobGoals implements MobGoals {
|
||||
Set<Goal<T>> goals = new HashSet<>();
|
||||
getHandle(craftMob, type).getAvailableGoals()
|
||||
.stream().filter(WrappedGoal::isRunning)
|
||||
.map(WrappedGoal::getGoal)
|
||||
.filter(goal -> type == GoalType.UNKNOWN_BEHAVIOR ? goal.getFlags().isEmpty() : goal.hasFlag(MobGoalHelper.paperToVanilla(type)))
|
||||
.forEach(goal -> {
|
||||
if (goal instanceof PaperCustomGoal) {
|
||||
.filter(item -> item.getGoal().hasFlag(MobGoalHelper.paperToVanilla(type)))
|
||||
.forEach(item -> {
|
||||
if (item.getGoal() instanceof PaperCustomGoal) {
|
||||
//noinspection unchecked
|
||||
goals.add(((PaperCustomGoal<T>) goal).getHandle());
|
||||
goals.add(((PaperCustomGoal<T>) item.getGoal()).getHandle());
|
||||
} else {
|
||||
goals.add(goal.asPaperGoal());
|
||||
goals.add(item.getGoal().asPaperGoal());
|
||||
}
|
||||
});
|
||||
return goals;
|
||||
@@ -199,14 +195,13 @@ public class PaperMobGoals implements MobGoals {
|
||||
getHandle(craftMob, internalType).getAvailableGoals()
|
||||
.stream()
|
||||
.filter(WrappedGoal::isRunning)
|
||||
.map(WrappedGoal::getGoal)
|
||||
.filter(goal -> type == GoalType.UNKNOWN_BEHAVIOR ? !goal.getFlags().isEmpty() : !goal.hasFlag(MobGoalHelper.paperToVanilla(type)))
|
||||
.forEach(goal -> {
|
||||
if (goal instanceof PaperCustomGoal) {
|
||||
.filter(item -> !item.getGoal().hasFlag(MobGoalHelper.paperToVanilla(type)))
|
||||
.forEach(item -> {
|
||||
if (item.getGoal() instanceof PaperCustomGoal) {
|
||||
//noinspection unchecked
|
||||
goals.add(((PaperCustomGoal<T>) goal).getHandle());
|
||||
goals.add(((PaperCustomGoal<T>) item.getGoal()).getHandle());
|
||||
} else {
|
||||
goals.add(goal.asPaperGoal());
|
||||
goals.add(item.getGoal().asPaperGoal());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package io.papermc.paper.datacomponent;
|
||||
|
||||
import java.util.function.Function;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.component.DataComponentType;
|
||||
import net.minecraft.util.NullOps;
|
||||
import net.minecraft.util.Unit;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
|
||||
public record DataComponentAdapter<NMS, API>(
|
||||
Function<API, NMS> apiToVanilla,
|
||||
Function<NMS, API> vanillaToApi,
|
||||
boolean codecValidation
|
||||
) {
|
||||
static final Function<Void, Unit> API_TO_UNIT_CONVERTER = _ -> Unit.INSTANCE;
|
||||
|
||||
static final Function API_TO_UNIMPLEMENTED_CONVERTER = _ -> {
|
||||
throw new UnsupportedOperationException("Cannot convert an API value to an unimplemented type");
|
||||
};
|
||||
|
||||
public boolean isValued() {
|
||||
return this.apiToVanilla != API_TO_UNIT_CONVERTER;
|
||||
}
|
||||
|
||||
public boolean isUnimplemented() {
|
||||
return this.apiToVanilla == API_TO_UNIMPLEMENTED_CONVERTER;
|
||||
}
|
||||
|
||||
public NMS toVanilla(final API value, final Holder<? extends DataComponentType<NMS>> type) {
|
||||
final NMS nms = this.apiToVanilla.apply(value);
|
||||
if (this.codecValidation && !type.value().isTransient()) {
|
||||
type.value().codecOrThrow().encodeStart(CraftRegistry.getMinecraftRegistry().createSerializationContext(NullOps.INSTANCE), nms).ifError(error -> {
|
||||
throw new IllegalArgumentException("Failed to encode data component %s (%s)".formatted(type.unwrapKey().orElseThrow(), error.message()));
|
||||
});
|
||||
}
|
||||
|
||||
return nms;
|
||||
}
|
||||
|
||||
public API fromVanilla(final NMS value) {
|
||||
return this.vanillaToApi.apply(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
package io.papermc.paper.datacomponent;
|
||||
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import io.papermc.paper.block.pot.PaperPotPatternType;
|
||||
import io.papermc.paper.datacomponent.item.PaperAttackRange;
|
||||
import io.papermc.paper.datacomponent.item.PaperBannerPatternLayers;
|
||||
import io.papermc.paper.datacomponent.item.PaperBlockItemDataProperties;
|
||||
import io.papermc.paper.datacomponent.item.PaperBlocksAttacks;
|
||||
import io.papermc.paper.datacomponent.item.PaperBundleContents;
|
||||
import io.papermc.paper.datacomponent.item.PaperChargedProjectiles;
|
||||
import io.papermc.paper.datacomponent.item.PaperConsumable;
|
||||
import io.papermc.paper.datacomponent.item.PaperCustomModelData;
|
||||
import io.papermc.paper.datacomponent.item.PaperDamageResistant;
|
||||
import io.papermc.paper.datacomponent.item.PaperDeathProtection;
|
||||
import io.papermc.paper.datacomponent.item.PaperDyedItemColor;
|
||||
import io.papermc.paper.datacomponent.item.PaperEnchantable;
|
||||
import io.papermc.paper.datacomponent.item.PaperEquippable;
|
||||
import io.papermc.paper.datacomponent.item.PaperFireworks;
|
||||
import io.papermc.paper.datacomponent.item.PaperFoodProperties;
|
||||
import io.papermc.paper.datacomponent.item.PaperItemAdventurePredicate;
|
||||
import io.papermc.paper.datacomponent.item.PaperItemArmorTrim;
|
||||
import io.papermc.paper.datacomponent.item.PaperItemAttributeModifiers;
|
||||
import io.papermc.paper.datacomponent.item.PaperItemContainerContents;
|
||||
import io.papermc.paper.datacomponent.item.PaperItemEnchantments;
|
||||
import io.papermc.paper.datacomponent.item.PaperItemLore;
|
||||
import io.papermc.paper.datacomponent.item.PaperItemTool;
|
||||
import io.papermc.paper.datacomponent.item.PaperJukeboxPlayable;
|
||||
import io.papermc.paper.datacomponent.item.PaperKineticWeapon;
|
||||
import io.papermc.paper.datacomponent.item.PaperLodestoneTracker;
|
||||
import io.papermc.paper.datacomponent.item.PaperMapDecorations;
|
||||
import io.papermc.paper.datacomponent.item.PaperMapId;
|
||||
import io.papermc.paper.datacomponent.item.PaperMobVisibility;
|
||||
import io.papermc.paper.datacomponent.item.PaperOminousBottleAmplifier;
|
||||
import io.papermc.paper.datacomponent.item.PaperPiercingWeapon;
|
||||
import io.papermc.paper.datacomponent.item.PaperPotDecorations;
|
||||
import io.papermc.paper.datacomponent.item.PaperPotionContents;
|
||||
import io.papermc.paper.datacomponent.item.PaperRepairable;
|
||||
import io.papermc.paper.datacomponent.item.PaperResolvableProfile;
|
||||
import io.papermc.paper.datacomponent.item.PaperSeededContainerLoot;
|
||||
import io.papermc.paper.datacomponent.item.PaperSignText;
|
||||
import io.papermc.paper.datacomponent.item.PaperSulfurCubeContent;
|
||||
import io.papermc.paper.datacomponent.item.PaperSuspiciousStewEffects;
|
||||
import io.papermc.paper.datacomponent.item.PaperSwingAnimation;
|
||||
import io.papermc.paper.datacomponent.item.PaperTooltipDisplay;
|
||||
import io.papermc.paper.datacomponent.item.PaperUseCooldown;
|
||||
import io.papermc.paper.datacomponent.item.PaperUseEffects;
|
||||
import io.papermc.paper.datacomponent.item.PaperUseRemainder;
|
||||
import io.papermc.paper.datacomponent.item.PaperVillagerFood;
|
||||
import io.papermc.paper.datacomponent.item.PaperWeapon;
|
||||
import io.papermc.paper.datacomponent.item.PaperWritableBookContent;
|
||||
import io.papermc.paper.datacomponent.item.PaperWrittenBookContent;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.set.PaperRegistrySets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import net.minecraft.core.component.DataComponentType;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.world.item.Rarity;
|
||||
import net.minecraft.world.item.component.InstrumentComponent;
|
||||
import net.minecraft.world.item.component.MapPostProcessing;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.craftbukkit.CraftArt;
|
||||
import org.bukkit.craftbukkit.CraftMusicInstrument;
|
||||
import org.bukkit.craftbukkit.damage.CraftDamageType;
|
||||
import org.bukkit.craftbukkit.entity.CraftCat;
|
||||
import org.bukkit.craftbukkit.entity.CraftChicken;
|
||||
import org.bukkit.craftbukkit.entity.CraftCow;
|
||||
import org.bukkit.craftbukkit.entity.CraftFrog;
|
||||
import org.bukkit.craftbukkit.entity.CraftPig;
|
||||
import org.bukkit.craftbukkit.entity.CraftVillager;
|
||||
import org.bukkit.craftbukkit.entity.CraftWolf;
|
||||
import org.bukkit.craftbukkit.entity.CraftZombieNautilus;
|
||||
import org.bukkit.craftbukkit.inventory.CraftMetaFirework;
|
||||
import org.bukkit.craftbukkit.inventory.trim.CraftTrimMaterial;
|
||||
import org.bukkit.craftbukkit.util.Handleable;
|
||||
import org.bukkit.entity.Axolotl;
|
||||
import org.bukkit.entity.Horse;
|
||||
import org.bukkit.entity.Llama;
|
||||
import org.bukkit.entity.MushroomCow;
|
||||
import org.bukkit.entity.Parrot;
|
||||
import org.bukkit.entity.Rabbit;
|
||||
import org.bukkit.entity.Salmon;
|
||||
import org.bukkit.entity.TropicalFish;
|
||||
import org.bukkit.inventory.ItemRarity;
|
||||
|
||||
import static io.papermc.paper.util.MCUtil.transformUnmodifiable;
|
||||
|
||||
public final class DataComponentAdapters {
|
||||
|
||||
static final Function<Unit, Void> UNIT_TO_API_CONVERTER = _ -> {
|
||||
throw new UnsupportedOperationException("Cannot convert the Unit type to an API value");
|
||||
};
|
||||
|
||||
static final Function UNIMPLEMENTED_TO_API_CONVERTER = _ -> {
|
||||
throw new UnsupportedOperationException("Cannot convert the an unimplemented type to an API value");
|
||||
};
|
||||
|
||||
static final Map<ResourceKey<DataComponentType<?>>, DataComponentAdapter<?, ?>> ADAPTERS = new HashMap<>();
|
||||
|
||||
public static void bootstrap() {
|
||||
registerIdentity(DataComponents.MAX_STACK_SIZE);
|
||||
registerIdentity(DataComponents.MAX_DAMAGE);
|
||||
registerIdentity(DataComponents.DAMAGE);
|
||||
registerUntyped(DataComponents.UNBREAKABLE);
|
||||
register(DataComponents.USE_EFFECTS, PaperUseEffects::new);
|
||||
register(DataComponents.CUSTOM_NAME, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
|
||||
registerIdentity(DataComponents.MINIMUM_ATTACK_CHARGE);
|
||||
register(DataComponents.DAMAGE_TYPE, CraftDamageType::minecraftHolderToBukkit, CraftDamageType::bukkitToMinecraftHolder);
|
||||
register(DataComponents.ITEM_NAME, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
|
||||
register(DataComponents.ITEM_MODEL, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
|
||||
register(DataComponents.LORE, PaperItemLore::new);
|
||||
register(DataComponents.RARITY, nms -> ItemRarity.valueOf(nms.name()), api -> Rarity.valueOf(api.name()));
|
||||
register(DataComponents.ENCHANTMENTS, PaperItemEnchantments::new);
|
||||
register(DataComponents.CAN_PLACE_ON, PaperItemAdventurePredicate::new);
|
||||
register(DataComponents.CAN_BREAK, PaperItemAdventurePredicate::new);
|
||||
register(DataComponents.ATTRIBUTE_MODIFIERS, PaperItemAttributeModifiers::new);
|
||||
register(DataComponents.CUSTOM_MODEL_DATA, PaperCustomModelData::new);
|
||||
register(DataComponents.TOOLTIP_DISPLAY, PaperTooltipDisplay::new);
|
||||
registerIdentity(DataComponents.REPAIR_COST);
|
||||
// registerUntyped(DataComponents.CREATIVE_SLOT_LOCK);
|
||||
registerIdentity(DataComponents.ENCHANTMENT_GLINT_OVERRIDE);
|
||||
registerUntyped(DataComponents.INTANGIBLE_PROJECTILE);
|
||||
register(DataComponents.FOOD, PaperFoodProperties::new);
|
||||
register(DataComponents.CONSUMABLE, PaperConsumable::new);
|
||||
register(DataComponents.USE_REMAINDER, PaperUseRemainder::new);
|
||||
register(DataComponents.USE_COOLDOWN, PaperUseCooldown::new);
|
||||
register(DataComponents.DAMAGE_RESISTANT, PaperDamageResistant::new);
|
||||
register(DataComponents.TOOL, PaperItemTool::new);
|
||||
register(DataComponents.WEAPON, PaperWeapon::new);
|
||||
register(DataComponents.ATTACK_RANGE, PaperAttackRange::new);
|
||||
register(DataComponents.ENCHANTABLE, PaperEnchantable::new);
|
||||
register(DataComponents.EQUIPPABLE, PaperEquippable::new);
|
||||
register(DataComponents.REPAIRABLE, PaperRepairable::new);
|
||||
registerUntyped(DataComponents.GLIDER);
|
||||
register(DataComponents.TOOLTIP_STYLE, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
|
||||
register(DataComponents.DEATH_PROTECTION, PaperDeathProtection::new);
|
||||
register(DataComponents.STORED_ENCHANTMENTS, PaperItemEnchantments::new);
|
||||
register(DataComponents.DYE, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
|
||||
register(DataComponents.DYED_COLOR, PaperDyedItemColor::new);
|
||||
register(DataComponents.MAP_ID, PaperMapId::new);
|
||||
register(DataComponents.MAP_DECORATIONS, PaperMapDecorations::new);
|
||||
register(DataComponents.MAP_POST_PROCESSING, nms -> io.papermc.paper.item.MapPostProcessing.valueOf(nms.name()), api -> MapPostProcessing.valueOf(api.name()));
|
||||
register(DataComponents.CHARGED_PROJECTILES, PaperChargedProjectiles::new);
|
||||
register(DataComponents.BUNDLE_CONTENTS, PaperBundleContents::new);
|
||||
register(DataComponents.POTION_CONTENTS, PaperPotionContents::new);
|
||||
registerIdentity(DataComponents.POTION_DURATION_SCALE);
|
||||
register(DataComponents.SUSPICIOUS_STEW_EFFECTS, PaperSuspiciousStewEffects::new);
|
||||
register(DataComponents.WRITTEN_BOOK_CONTENT, PaperWrittenBookContent::new);
|
||||
register(DataComponents.WRITABLE_BOOK_CONTENT, PaperWritableBookContent::new);
|
||||
register(DataComponents.TRIM, PaperItemArmorTrim::new);
|
||||
// debug stick state
|
||||
// entity data
|
||||
// bucket entity data
|
||||
// block entity data
|
||||
register(DataComponents.INSTRUMENT, nms -> CraftMusicInstrument.minecraftHolderToBukkit(nms.instrument()), api -> new InstrumentComponent(CraftMusicInstrument.bukkitToMinecraftHolder(api)));
|
||||
register(DataComponents.PROVIDES_TRIM_MATERIAL, CraftTrimMaterial::minecraftHolderToBukkit, CraftTrimMaterial::bukkitToMinecraftHolder);
|
||||
register(DataComponents.OMINOUS_BOTTLE_AMPLIFIER, PaperOminousBottleAmplifier::new);
|
||||
register(DataComponents.JUKEBOX_PLAYABLE, PaperJukeboxPlayable::new);
|
||||
register(DataComponents.PROVIDES_BANNER_PATTERNS, set -> PaperRegistrySets.convertToApi(RegistryKey.BANNER_PATTERN, set), set -> PaperRegistrySets.convertToNms(Registries.BANNER_PATTERN, Conversions.global().lookup(), set));
|
||||
register(
|
||||
DataComponents.RECIPES,
|
||||
nms -> transformUnmodifiable(nms, PaperAdventure::asAdventureKey),
|
||||
api -> transformUnmodifiable(api, key -> PaperAdventure.asVanilla(Registries.RECIPE, key))
|
||||
);
|
||||
register(DataComponents.LODESTONE_TRACKER, PaperLodestoneTracker::new);
|
||||
register(DataComponents.FIREWORK_EXPLOSION, CraftMetaFirework::getEffect, CraftMetaFirework::getExplosion);
|
||||
register(DataComponents.FIREWORKS, PaperFireworks::new);
|
||||
register(DataComponents.PROFILE, PaperResolvableProfile::new);
|
||||
register(DataComponents.NOTE_BLOCK_SOUND, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
|
||||
register(DataComponents.BANNER_PATTERNS, PaperBannerPatternLayers::new);
|
||||
register(DataComponents.BASE_COLOR, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
|
||||
register(DataComponents.POT_DECORATIONS, PaperPotDecorations::new);
|
||||
register(DataComponents.CONTAINER, PaperItemContainerContents::new);
|
||||
register(DataComponents.BLOCK_STATE, PaperBlockItemDataProperties::new);
|
||||
// bees
|
||||
register(DataComponents.SULFUR_CUBE_CONTENT, PaperSulfurCubeContent::new);
|
||||
// register(DataComponents.LOCK, PaperLockCode::new);
|
||||
register(DataComponents.CONTAINER_LOOT, PaperSeededContainerLoot::new);
|
||||
register(DataComponents.BREAK_SOUND, nms -> PaperAdventure.asAdventure(nms.value().location()), PaperAdventure::resolveSound);
|
||||
register(DataComponents.BLOCKS_ATTACKS, PaperBlocksAttacks::new);
|
||||
register(DataComponents.PIERCING_WEAPON, PaperPiercingWeapon::new);
|
||||
register(DataComponents.KINETIC_WEAPON, PaperKineticWeapon::new);
|
||||
register(DataComponents.ATTACK_ANIMATION, PaperSwingAnimation::new);
|
||||
register(DataComponents.INTERACT_ANIMATION, PaperSwingAnimation::new);
|
||||
// registerIdentity(DataComponents.ADDITIONAL_TRADE_COST);
|
||||
// block transformer
|
||||
register(DataComponents.VILLAGER_FOOD, PaperVillagerFood::new);
|
||||
register(DataComponents.MOB_VISIBILITY, PaperMobVisibility::new);
|
||||
register(DataComponents.VILLAGER_VARIANT, CraftVillager.CraftType::minecraftHolderToBukkit, CraftVillager.CraftType::bukkitToMinecraftHolder);
|
||||
register(DataComponents.WOLF_VARIANT, CraftWolf.CraftVariant::minecraftHolderToBukkit, CraftWolf.CraftVariant::bukkitToMinecraftHolder);
|
||||
register(DataComponents.WOLF_COLLAR, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
|
||||
register(DataComponents.WOLF_SOUND_VARIANT, CraftWolf.CraftSoundVariant::minecraftHolderToBukkit, CraftWolf.CraftSoundVariant::bukkitToMinecraftHolder);
|
||||
register(DataComponents.FOX_VARIANT, nms -> org.bukkit.entity.Fox.Type.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.fox.Fox.Variant.byId(api.ordinal()));
|
||||
register(DataComponents.SALMON_SIZE, nms -> Salmon.Variant.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.fish.Salmon.Variant.values()[api.ordinal()]);
|
||||
register(DataComponents.PARROT_VARIANT, nms -> Parrot.Variant.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.parrot.Parrot.Variant.byId(api.ordinal()));
|
||||
register(DataComponents.TROPICAL_FISH_PATTERN, nms -> TropicalFish.Pattern.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.fish.TropicalFish.Pattern.values()[api.ordinal()]);
|
||||
register(DataComponents.TROPICAL_FISH_BASE_COLOR, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
|
||||
register(DataComponents.TROPICAL_FISH_PATTERN_COLOR, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
|
||||
register(DataComponents.MOOSHROOM_VARIANT, nms -> MushroomCow.Variant.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.cow.MushroomCow.Variant.values()[api.ordinal()]);
|
||||
register(DataComponents.RABBIT_VARIANT, nms -> Rabbit.Type.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.rabbit.Rabbit.Variant.values()[api.ordinal()]);
|
||||
register(DataComponents.PIG_VARIANT, CraftPig.CraftVariant::minecraftHolderToBukkit, CraftPig.CraftVariant::bukkitToMinecraftHolder);
|
||||
register(DataComponents.PIG_SOUND_VARIANT, CraftPig.CraftSoundVariant::minecraftHolderToBukkit, CraftPig.CraftSoundVariant::bukkitToMinecraftHolder);
|
||||
register(DataComponents.COW_VARIANT, CraftCow.CraftVariant::minecraftHolderToBukkit, CraftCow.CraftVariant::bukkitToMinecraftHolder);
|
||||
register(DataComponents.COW_SOUND_VARIANT, CraftCow.CraftSoundVariant::minecraftHolderToBukkit, CraftCow.CraftSoundVariant::bukkitToMinecraftHolder);
|
||||
register(DataComponents.CHICKEN_VARIANT, CraftChicken.CraftVariant::minecraftHolderToBukkit, CraftChicken.CraftVariant::bukkitToMinecraftHolder);
|
||||
register(DataComponents.CHICKEN_SOUND_VARIANT, CraftChicken.CraftSoundVariant::minecraftHolderToBukkit, CraftChicken.CraftSoundVariant::bukkitToMinecraftHolder);
|
||||
register(DataComponents.FROG_VARIANT, CraftFrog.CraftVariant::minecraftHolderToBukkit, CraftFrog.CraftVariant::bukkitToMinecraftHolder);
|
||||
register(DataComponents.ZOMBIE_NAUTILUS_VARIANT, CraftZombieNautilus.CraftVariant::minecraftHolderToBukkit, CraftZombieNautilus.CraftVariant::bukkitToMinecraftHolder);
|
||||
register(DataComponents.HORSE_VARIANT, nms -> Horse.Color.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.equine.Variant.byId(api.ordinal()));
|
||||
register(DataComponents.PAINTING_VARIANT, CraftArt::minecraftHolderToBukkit, CraftArt::bukkitToMinecraftHolder);
|
||||
register(DataComponents.LLAMA_VARIANT, nms -> Llama.Color.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.equine.Llama.Variant.byId(api.ordinal()));
|
||||
register(DataComponents.AXOLOTL_VARIANT, nms -> Axolotl.Variant.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.axolotl.Axolotl.Variant.byId(api.ordinal()));
|
||||
register(DataComponents.CAT_VARIANT, CraftCat.CraftType::minecraftHolderToBukkit, CraftCat.CraftType::bukkitToMinecraftHolder);
|
||||
register(DataComponents.CAT_SOUND_VARIANT, CraftCat.CraftSoundVariant::minecraftHolderToBukkit, CraftCat.CraftSoundVariant::bukkitToMinecraftHolder);
|
||||
register(DataComponents.CAT_COLLAR, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
|
||||
register(DataComponents.SHEEP_COLOR, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
|
||||
register(DataComponents.SHULKER_COLOR, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
|
||||
register(DataComponents.PROVIDES_POTTERY_PATTERN, PaperPotPatternType::minecraftHolderToBukkit, PaperPotPatternType::bukkitToMinecraftHolder);
|
||||
register(DataComponents.SIGN_TEXT_FRONT, PaperSignText::new);
|
||||
register(DataComponents.SIGN_TEXT_BACK, PaperSignText::new);
|
||||
registerUntyped(DataComponents.WAXED);
|
||||
register(DataComponents.CUSHION_COLOR, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
|
||||
|
||||
for (final ResourceKey<DataComponentType<?>> key : BuiltInRegistries.DATA_COMPONENT_TYPE.registryKeySet()) {
|
||||
if (!ADAPTERS.containsKey(key)) {
|
||||
registerUnimplemented(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static <NMS> ResourceKey<DataComponentType<?>> getKey(final DataComponentType<NMS> type) {
|
||||
return BuiltInRegistries.DATA_COMPONENT_TYPE.getResourceKey(type).orElseThrow();
|
||||
}
|
||||
|
||||
public static void registerUntyped(final DataComponentType<Unit> type) {
|
||||
registerInternal(getKey(type), UNIT_TO_API_CONVERTER, DataComponentAdapter.API_TO_UNIT_CONVERTER, false);
|
||||
}
|
||||
|
||||
private static <COMMON> void registerIdentity(final DataComponentType<COMMON> type) {
|
||||
registerInternal(getKey(type), Function.identity(), Function.identity(), true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void registerUnimplemented(final ResourceKey<DataComponentType<?>> key) {
|
||||
registerInternal(key, UNIMPLEMENTED_TO_API_CONVERTER, DataComponentAdapter.API_TO_UNIMPLEMENTED_CONVERTER, false);
|
||||
}
|
||||
|
||||
private static <NMS, API extends Handleable<NMS>> void register(final DataComponentType<NMS> type, final Function<NMS, API> vanillaToApi) {
|
||||
registerInternal(getKey(type), vanillaToApi, Handleable::getHandle, false);
|
||||
}
|
||||
|
||||
private static <NMS, API> void register(final DataComponentType<NMS> type, final Function<NMS, API> vanillaToApi, final Function<API, NMS> apiToVanilla) {
|
||||
registerInternal(getKey(type), vanillaToApi, apiToVanilla, false);
|
||||
}
|
||||
|
||||
private static <NMS, API> void registerInternal(final ResourceKey<DataComponentType<?>> key, final Function<NMS, API> vanillaToApi, final Function<API, NMS> apiToVanilla, final boolean codecValidation) {
|
||||
if (ADAPTERS.containsKey(key)) {
|
||||
throw new IllegalStateException("Duplicate adapter registration for " + key);
|
||||
}
|
||||
ADAPTERS.put(key, new DataComponentAdapter<>(apiToVanilla, vanillaToApi, codecValidation));
|
||||
}
|
||||
}
|
||||
+40
-252
@@ -1,237 +1,22 @@
|
||||
package io.papermc.paper.datacomponent;
|
||||
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import io.papermc.paper.datacomponent.item.PaperAttackRange;
|
||||
import io.papermc.paper.datacomponent.item.PaperBannerPatternLayers;
|
||||
import io.papermc.paper.datacomponent.item.PaperBlockItemDataProperties;
|
||||
import io.papermc.paper.datacomponent.item.PaperBlocksAttacks;
|
||||
import io.papermc.paper.datacomponent.item.PaperBundleContents;
|
||||
import io.papermc.paper.datacomponent.item.PaperChargedProjectiles;
|
||||
import io.papermc.paper.datacomponent.item.PaperConsumable;
|
||||
import io.papermc.paper.datacomponent.item.PaperCustomModelData;
|
||||
import io.papermc.paper.datacomponent.item.PaperDamageResistant;
|
||||
import io.papermc.paper.datacomponent.item.PaperDeathProtection;
|
||||
import io.papermc.paper.datacomponent.item.PaperDyedItemColor;
|
||||
import io.papermc.paper.datacomponent.item.PaperEnchantable;
|
||||
import io.papermc.paper.datacomponent.item.PaperEquippable;
|
||||
import io.papermc.paper.datacomponent.item.PaperFireworks;
|
||||
import io.papermc.paper.datacomponent.item.PaperFoodProperties;
|
||||
import io.papermc.paper.datacomponent.item.PaperItemAdventurePredicate;
|
||||
import io.papermc.paper.datacomponent.item.PaperItemArmorTrim;
|
||||
import io.papermc.paper.datacomponent.item.PaperItemAttributeModifiers;
|
||||
import io.papermc.paper.datacomponent.item.PaperItemContainerContents;
|
||||
import io.papermc.paper.datacomponent.item.PaperItemEnchantments;
|
||||
import io.papermc.paper.datacomponent.item.PaperItemLore;
|
||||
import io.papermc.paper.datacomponent.item.PaperItemTool;
|
||||
import io.papermc.paper.datacomponent.item.PaperJukeboxPlayable;
|
||||
import io.papermc.paper.datacomponent.item.PaperKineticWeapon;
|
||||
import io.papermc.paper.datacomponent.item.PaperLodestoneTracker;
|
||||
import io.papermc.paper.datacomponent.item.PaperMapDecorations;
|
||||
import io.papermc.paper.datacomponent.item.PaperMapId;
|
||||
import io.papermc.paper.datacomponent.item.PaperMobVisibility;
|
||||
import io.papermc.paper.datacomponent.item.PaperOminousBottleAmplifier;
|
||||
import io.papermc.paper.datacomponent.item.PaperPiercingWeapon;
|
||||
import io.papermc.paper.datacomponent.item.PaperPotDecorations;
|
||||
import io.papermc.paper.datacomponent.item.PaperPotionContents;
|
||||
import io.papermc.paper.datacomponent.item.PaperRepairable;
|
||||
import io.papermc.paper.datacomponent.item.PaperResolvableProfile;
|
||||
import io.papermc.paper.datacomponent.item.PaperSeededContainerLoot;
|
||||
import io.papermc.paper.datacomponent.item.PaperSignText;
|
||||
import io.papermc.paper.datacomponent.item.PaperSulfurCubeContent;
|
||||
import io.papermc.paper.datacomponent.item.PaperSuspiciousStewEffects;
|
||||
import io.papermc.paper.datacomponent.item.PaperSwingAnimation;
|
||||
import io.papermc.paper.datacomponent.item.PaperTooltipDisplay;
|
||||
import io.papermc.paper.datacomponent.item.PaperUseCooldown;
|
||||
import io.papermc.paper.datacomponent.item.PaperUseEffects;
|
||||
import io.papermc.paper.datacomponent.item.PaperUseRemainder;
|
||||
import io.papermc.paper.datacomponent.item.PaperVillagerFood;
|
||||
import io.papermc.paper.datacomponent.item.PaperWeapon;
|
||||
import io.papermc.paper.datacomponent.item.PaperWritableBookContent;
|
||||
import io.papermc.paper.datacomponent.item.PaperWrittenBookContent;
|
||||
import io.papermc.paper.item.MapPostProcessing;
|
||||
import io.papermc.paper.registry.HolderableBase;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.set.PaperRegistrySets;
|
||||
import io.papermc.paper.registry.typed.PaperTypedDataAdapters;
|
||||
import io.papermc.paper.registry.typed.PaperTypedDataCollector;
|
||||
import io.papermc.paper.util.converter.Converter;
|
||||
import io.papermc.paper.util.converter.Converters;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.component.DataComponentGetter;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.component.DataComponentMap;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.world.item.Rarity;
|
||||
import net.minecraft.world.item.component.InstrumentComponent;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.craftbukkit.CraftMusicInstrument;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.bukkit.craftbukkit.inventory.CraftMetaFirework;
|
||||
import org.bukkit.entity.Axolotl;
|
||||
import org.bukkit.entity.Horse;
|
||||
import org.bukkit.entity.Llama;
|
||||
import org.bukkit.entity.MushroomCow;
|
||||
import org.bukkit.entity.Parrot;
|
||||
import org.bukkit.entity.Rabbit;
|
||||
import org.bukkit.entity.Salmon;
|
||||
import org.bukkit.entity.TropicalFish;
|
||||
import org.bukkit.inventory.ItemRarity;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import static io.papermc.paper.util.converter.Converter.direct;
|
||||
import static io.papermc.paper.util.converter.Converters.listOf;
|
||||
import static io.papermc.paper.util.converter.Converters.registryElement;
|
||||
import static io.papermc.paper.util.converter.Converters.sameName;
|
||||
import static io.papermc.paper.util.converter.Converters.sameOrder;
|
||||
import static io.papermc.paper.util.converter.Converters.wrapper;
|
||||
public abstract class PaperDataComponentType<T, NMS> extends HolderableBase<net.minecraft.core.component.DataComponentType<NMS>> implements DataComponentType {
|
||||
|
||||
public abstract class PaperDataComponentType<A, M> extends HolderableBase<net.minecraft.core.component.DataComponentType<M>> implements DataComponentType {
|
||||
|
||||
// this is a hack around generics limitations to prevent
|
||||
// having to define generics on each register call as seen below, making collectors easier to read:
|
||||
// collector.<T, A>register(...)
|
||||
private static <M, A> void register(final PaperTypedDataCollector<net.minecraft.core.component.DataComponentType<?>> collector, final net.minecraft.core.component.DataComponentType<M> dataComponentType, final Function<M, A> vanillaToApi, final Function<A, M> apiToVanilla) {
|
||||
collector.register(dataComponentType, vanillaToApi, apiToVanilla);
|
||||
static {
|
||||
DataComponentAdapters.bootstrap();
|
||||
}
|
||||
|
||||
@SuppressWarnings("RedundantTypeArguments")
|
||||
private static final PaperTypedDataAdapters<net.minecraft.core.component.DataComponentType<?>> ADAPTERS = PaperTypedDataAdapters.<net.minecraft.core.component.DataComponentType<?>, PaperTypedDataCollector<net.minecraft.core.component.DataComponentType<?>>>create(
|
||||
BuiltInRegistries.DATA_COMPONENT_TYPE,
|
||||
PaperTypedDataCollector::new,
|
||||
collector -> {
|
||||
final Converter<net.minecraft.world.item.DyeColor, DyeColor> dyeColor = direct(
|
||||
color -> DyeColor.getByWoolData((byte) color.getId()), color -> net.minecraft.world.item.DyeColor.byId(color.getWoolData())
|
||||
);
|
||||
collector.dispatch(_ -> Converters.unvalued()).add(
|
||||
DataComponents.UNBREAKABLE,
|
||||
DataComponents.INTANGIBLE_PROJECTILE,
|
||||
DataComponents.GLIDER,
|
||||
DataComponents.WAXED
|
||||
// DataComponents.CREATIVE_SLOT_LOCK
|
||||
);
|
||||
collector.dispatch(type -> Converter.identity(type.codec())).add(
|
||||
DataComponents.MAX_STACK_SIZE,
|
||||
DataComponents.MAX_DAMAGE,
|
||||
DataComponents.DAMAGE,
|
||||
DataComponents.POTION_DURATION_SCALE,
|
||||
DataComponents.MINIMUM_ATTACK_CHARGE,
|
||||
DataComponents.REPAIR_COST,
|
||||
DataComponents.ENCHANTMENT_GLINT_OVERRIDE
|
||||
// DataComponents.ADDITIONAL_TRADE_COST
|
||||
);
|
||||
collector.register(DataComponents.USE_EFFECTS, wrapper(PaperUseEffects::new));
|
||||
register(collector, DataComponents.CUSTOM_NAME, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
|
||||
collector.register(DataComponents.DAMAGE_TYPE, registryElement(Registries.DAMAGE_TYPE));
|
||||
register(collector, DataComponents.ITEM_NAME, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
|
||||
register(collector, DataComponents.ITEM_MODEL, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
|
||||
collector.register(DataComponents.LORE, wrapper(PaperItemLore::new));
|
||||
collector.register(DataComponents.RARITY, sameName(ItemRarity.class, Rarity.class));
|
||||
collector.register(DataComponents.ENCHANTMENTS, wrapper(PaperItemEnchantments::of));
|
||||
collector.register(DataComponents.CAN_PLACE_ON, wrapper(PaperItemAdventurePredicate::new));
|
||||
collector.register(DataComponents.CAN_BREAK, wrapper(PaperItemAdventurePredicate::new));
|
||||
collector.register(DataComponents.ATTRIBUTE_MODIFIERS, wrapper(PaperItemAttributeModifiers::new));
|
||||
collector.register(DataComponents.CUSTOM_MODEL_DATA, wrapper(PaperCustomModelData::new));
|
||||
collector.register(DataComponents.TOOLTIP_DISPLAY, wrapper(PaperTooltipDisplay::new));
|
||||
collector.register(DataComponents.FOOD, wrapper(PaperFoodProperties::new));
|
||||
collector.register(DataComponents.CONSUMABLE, wrapper(PaperConsumable::new));
|
||||
collector.register(DataComponents.USE_REMAINDER, wrapper(PaperUseRemainder::new));
|
||||
collector.register(DataComponents.USE_COOLDOWN, wrapper(PaperUseCooldown::new));
|
||||
collector.register(DataComponents.DAMAGE_RESISTANT, wrapper(PaperDamageResistant::new));
|
||||
collector.register(DataComponents.TOOL, wrapper(PaperItemTool::new));
|
||||
collector.register(DataComponents.WEAPON, wrapper(PaperWeapon::new));
|
||||
collector.register(DataComponents.ATTACK_RANGE, wrapper(PaperAttackRange::new));
|
||||
collector.register(DataComponents.ENCHANTABLE, wrapper(PaperEnchantable::new));
|
||||
collector.register(DataComponents.EQUIPPABLE, wrapper(PaperEquippable::new));
|
||||
collector.register(DataComponents.REPAIRABLE, wrapper(PaperRepairable::new));
|
||||
register(collector, DataComponents.TOOLTIP_STYLE, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
|
||||
collector.register(DataComponents.DEATH_PROTECTION, wrapper(PaperDeathProtection::new));
|
||||
collector.register(DataComponents.STORED_ENCHANTMENTS, wrapper(PaperItemEnchantments::of));
|
||||
collector.register(DataComponents.DYE, dyeColor);
|
||||
collector.register(DataComponents.DYED_COLOR, wrapper(PaperDyedItemColor::new));
|
||||
collector.register(DataComponents.MAP_ID, wrapper(PaperMapId::new));
|
||||
collector.register(DataComponents.MAP_DECORATIONS, wrapper(PaperMapDecorations::new));
|
||||
collector.register(DataComponents.MAP_POST_PROCESSING, sameName(MapPostProcessing.class, net.minecraft.world.item.component.MapPostProcessing.class));
|
||||
collector.register(DataComponents.CHARGED_PROJECTILES, wrapper(PaperChargedProjectiles::new));
|
||||
collector.register(DataComponents.BUNDLE_CONTENTS, wrapper(PaperBundleContents::new));
|
||||
collector.register(DataComponents.POTION_CONTENTS, wrapper(PaperPotionContents::new));
|
||||
collector.register(DataComponents.SUSPICIOUS_STEW_EFFECTS, wrapper(PaperSuspiciousStewEffects::new));
|
||||
collector.register(DataComponents.WRITTEN_BOOK_CONTENT, wrapper(PaperWrittenBookContent::new));
|
||||
collector.register(DataComponents.WRITABLE_BOOK_CONTENT, wrapper(PaperWritableBookContent::new));
|
||||
collector.register(DataComponents.TRIM, wrapper(PaperItemArmorTrim::new));
|
||||
// debug stick state
|
||||
// entity data
|
||||
// bucket entity data
|
||||
// block entity data
|
||||
register(collector, DataComponents.INSTRUMENT, component -> CraftMusicInstrument.minecraftHolderToBukkit(component.instrument()), api -> new InstrumentComponent(CraftMusicInstrument.bukkitToMinecraftHolder(api)));
|
||||
collector.register(DataComponents.PROVIDES_TRIM_MATERIAL, registryElement(Registries.TRIM_MATERIAL));
|
||||
collector.register(DataComponents.OMINOUS_BOTTLE_AMPLIFIER, wrapper(PaperOminousBottleAmplifier::new));
|
||||
collector.register(DataComponents.JUKEBOX_PLAYABLE, wrapper(PaperJukeboxPlayable::new));
|
||||
register(collector, DataComponents.PROVIDES_BANNER_PATTERNS, set -> PaperRegistrySets.convertToApi(RegistryKey.BANNER_PATTERN, set), set -> PaperRegistrySets.convertToNms(Registries.BANNER_PATTERN, Conversions.global().lookup(), set));
|
||||
collector.register(DataComponents.RECIPES, listOf(PaperAdventure::asAdventureKey, key -> PaperAdventure.asVanilla(Registries.RECIPE, key)));
|
||||
collector.register(DataComponents.LODESTONE_TRACKER, wrapper(PaperLodestoneTracker::new));
|
||||
collector.register(DataComponents.FIREWORK_EXPLOSION, CraftMetaFirework::getEffect, CraftMetaFirework::getExplosion);
|
||||
collector.register(DataComponents.FIREWORKS, wrapper(PaperFireworks::new));
|
||||
collector.register(DataComponents.PROFILE, wrapper(PaperResolvableProfile::new));
|
||||
register(collector, DataComponents.NOTE_BLOCK_SOUND, PaperAdventure::asAdventure, PaperAdventure::asVanilla);
|
||||
collector.register(DataComponents.BANNER_PATTERNS, wrapper(PaperBannerPatternLayers::new));
|
||||
collector.register(DataComponents.BASE_COLOR, dyeColor);
|
||||
collector.register(DataComponents.POT_DECORATIONS, wrapper(PaperPotDecorations::new));
|
||||
collector.register(DataComponents.CONTAINER, wrapper(PaperItemContainerContents::new));
|
||||
collector.register(DataComponents.BLOCK_STATE, wrapper(PaperBlockItemDataProperties::new));
|
||||
// bees
|
||||
collector.register(DataComponents.SULFUR_CUBE_CONTENT, wrapper(PaperSulfurCubeContent::new));
|
||||
// register(DataComponents.LOCK, wrapper(PaperLockCode::new));
|
||||
collector.register(DataComponents.CONTAINER_LOOT, wrapper(PaperSeededContainerLoot::new));
|
||||
collector.register(DataComponents.BREAK_SOUND, sound -> PaperAdventure.asAdventure(sound.value().location()), PaperAdventure::resolveSound);
|
||||
collector.register(DataComponents.BLOCKS_ATTACKS, wrapper(PaperBlocksAttacks::new));
|
||||
collector.register(DataComponents.PIERCING_WEAPON, wrapper(PaperPiercingWeapon::new));
|
||||
collector.register(DataComponents.KINETIC_WEAPON, wrapper(PaperKineticWeapon::new));
|
||||
collector.register(DataComponents.ATTACK_ANIMATION, wrapper(PaperSwingAnimation::new));
|
||||
collector.register(DataComponents.INTERACT_ANIMATION, wrapper(PaperSwingAnimation::new));
|
||||
// block transformer
|
||||
collector.register(DataComponents.VILLAGER_FOOD, wrapper(PaperVillagerFood::new));
|
||||
collector.register(DataComponents.MOB_VISIBILITY, wrapper(PaperMobVisibility::new));
|
||||
collector.register(DataComponents.VILLAGER_VARIANT, registryElement(Registries.VILLAGER_TYPE));
|
||||
collector.register(DataComponents.WOLF_VARIANT, registryElement(Registries.WOLF_VARIANT));
|
||||
collector.register(DataComponents.WOLF_COLLAR, dyeColor);
|
||||
collector.register(DataComponents.WOLF_SOUND_VARIANT, registryElement(Registries.WOLF_SOUND_VARIANT));
|
||||
collector.register(DataComponents.FOX_VARIANT, sameOrder(org.bukkit.entity.Fox.Type.class, net.minecraft.world.entity.animal.fox.Fox.Variant.class));
|
||||
collector.register(DataComponents.SALMON_SIZE, sameOrder(Salmon.Variant.class, net.minecraft.world.entity.animal.fish.Salmon.Variant.class));
|
||||
collector.register(DataComponents.PARROT_VARIANT, sameOrder(Parrot.Variant.class, net.minecraft.world.entity.animal.parrot.Parrot.Variant.class));
|
||||
collector.register(DataComponents.TROPICAL_FISH_PATTERN, sameOrder(TropicalFish.Pattern.class, net.minecraft.world.entity.animal.fish.TropicalFish.Pattern.class));
|
||||
collector.register(DataComponents.TROPICAL_FISH_BASE_COLOR, dyeColor);
|
||||
collector.register(DataComponents.TROPICAL_FISH_PATTERN_COLOR, dyeColor);
|
||||
collector.register(DataComponents.MOOSHROOM_VARIANT, sameOrder(MushroomCow.Variant.class, net.minecraft.world.entity.animal.cow.MushroomCow.Variant.class));
|
||||
collector.register(DataComponents.RABBIT_VARIANT, sameOrder(Rabbit.Type.class, net.minecraft.world.entity.animal.rabbit.Rabbit.Variant.class));
|
||||
collector.register(DataComponents.PIG_VARIANT, registryElement(Registries.PIG_VARIANT));
|
||||
collector.register(DataComponents.PIG_SOUND_VARIANT, registryElement(Registries.PIG_SOUND_VARIANT));
|
||||
collector.register(DataComponents.COW_VARIANT, registryElement(Registries.COW_VARIANT));
|
||||
collector.register(DataComponents.COW_SOUND_VARIANT, registryElement(Registries.COW_SOUND_VARIANT));
|
||||
collector.register(DataComponents.CHICKEN_VARIANT, registryElement(Registries.CHICKEN_VARIANT));
|
||||
collector.register(DataComponents.CHICKEN_SOUND_VARIANT, registryElement(Registries.CHICKEN_SOUND_VARIANT));
|
||||
collector.register(DataComponents.FROG_VARIANT, registryElement(Registries.FROG_VARIANT));
|
||||
collector.register(DataComponents.ZOMBIE_NAUTILUS_VARIANT, registryElement(Registries.ZOMBIE_NAUTILUS_VARIANT));
|
||||
collector.register(DataComponents.HORSE_VARIANT, sameOrder(Horse.Color.class, net.minecraft.world.entity.animal.equine.Variant.class));
|
||||
collector.register(DataComponents.PAINTING_VARIANT, registryElement(Registries.PAINTING_VARIANT));
|
||||
collector.register(DataComponents.LLAMA_VARIANT, sameOrder(Llama.Color.class, net.minecraft.world.entity.animal.equine.Llama.Variant.class));
|
||||
collector.register(DataComponents.AXOLOTL_VARIANT, sameOrder(Axolotl.Variant.class, net.minecraft.world.entity.animal.axolotl.Axolotl.Variant.class));
|
||||
collector.register(DataComponents.CAT_VARIANT, registryElement(Registries.CAT_VARIANT));
|
||||
collector.register(DataComponents.CAT_SOUND_VARIANT, registryElement(Registries.CAT_SOUND_VARIANT));
|
||||
collector.register(DataComponents.CAT_COLLAR, dyeColor);
|
||||
collector.register(DataComponents.SHEEP_COLOR, dyeColor);
|
||||
collector.register(DataComponents.SHULKER_COLOR, dyeColor);
|
||||
collector.register(DataComponents.PROVIDES_POTTERY_PATTERN, registryElement(Registries.DECORATED_POT_PATTERN));
|
||||
collector.register(DataComponents.SIGN_TEXT_FRONT, wrapper(PaperSignText::new));
|
||||
collector.register(DataComponents.SIGN_TEXT_BACK, wrapper(PaperSignText::new));
|
||||
collector.register(DataComponents.CUSHION_COLOR, dyeColor);
|
||||
}
|
||||
);
|
||||
|
||||
public static <T> net.minecraft.core.component.DataComponentType<T> bukkitToMinecraft(final DataComponentType type) {
|
||||
return CraftRegistry.bukkitToMinecraft(type);
|
||||
}
|
||||
@@ -240,27 +25,28 @@ public abstract class PaperDataComponentType<A, M> extends HolderableBase<net.mi
|
||||
return CraftRegistry.minecraftToBukkit(type, Registries.DATA_COMPONENT_TYPE);
|
||||
}
|
||||
|
||||
public static Set<DataComponentType> minecraftToBukkit(final Set<net.minecraft.core.component.DataComponentType<?>> types) {
|
||||
final Set<DataComponentType> result = new HashSet<>(types.size());
|
||||
for (final net.minecraft.core.component.DataComponentType<?> type : types) {
|
||||
result.add(PaperDataComponentType.minecraftToBukkit(type));
|
||||
public static Set<DataComponentType> minecraftToBukkit(final Set<net.minecraft.core.component.DataComponentType<?>> nmsTypes) {
|
||||
final Set<DataComponentType> types = new HashSet<>(nmsTypes.size());
|
||||
for (final net.minecraft.core.component.DataComponentType<?> nmsType : nmsTypes) {
|
||||
types.add(PaperDataComponentType.minecraftToBukkit(nmsType));
|
||||
}
|
||||
return Collections.unmodifiableSet(result);
|
||||
return Collections.unmodifiableSet(types);
|
||||
}
|
||||
|
||||
public static <B, M> @Nullable B convertDataComponentValue(final DataComponentGetter getter, final PaperDataComponentType.ValuedImpl<B, M> type) {
|
||||
final M value = getter.get(bukkitToMinecraft(type));
|
||||
if (value == null) {
|
||||
final net.minecraft.core.component.DataComponentType<M> nms = bukkitToMinecraft(type);
|
||||
final M nmsValue = getter.get(nms);
|
||||
if (nmsValue == null) {
|
||||
return null;
|
||||
}
|
||||
return type.getConverter().fromVanilla(value);
|
||||
return type.getAdapter().fromVanilla(nmsValue);
|
||||
}
|
||||
|
||||
private final Converter<M, A> converter;
|
||||
private final DataComponentAdapter<NMS, T> adapter;
|
||||
|
||||
private PaperDataComponentType(final Holder<net.minecraft.core.component.DataComponentType<M>> holder, final Converter<M, A> converter) {
|
||||
private PaperDataComponentType(final Holder<net.minecraft.core.component.DataComponentType<NMS>> holder, final DataComponentAdapter<NMS, T> adapter) {
|
||||
super(holder);
|
||||
this.converter = converter;
|
||||
this.adapter = adapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -268,50 +54,52 @@ public abstract class PaperDataComponentType<A, M> extends HolderableBase<net.mi
|
||||
return !this.getHandle().isTransient();
|
||||
}
|
||||
|
||||
public Converter<M, A> getConverter() {
|
||||
return this.converter;
|
||||
public DataComponentAdapter<NMS, T> getAdapter() {
|
||||
return this.adapter;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <M> DataComponentType of(final Holder<?> holder) {
|
||||
final Holder.Reference<net.minecraft.core.component.DataComponentType<M>> reference = (Holder.Reference<net.minecraft.core.component.DataComponentType<M>>) holder;
|
||||
final Converter<M, ?> converter = PaperDataComponentType.ADAPTERS.get(reference.key());
|
||||
if (converter == Converters.unimplemented()) {
|
||||
return new Unimplemented<>(reference, converter);
|
||||
} else if (converter == Converters.unvalued()) {
|
||||
return new NonValuedImpl<>(reference, converter);
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public static <NMS> DataComponentType of(final Holder<?> holder) {
|
||||
final DataComponentAdapter<NMS, ?> adapter = (DataComponentAdapter<NMS, ?>) DataComponentAdapters.ADAPTERS.get(holder.unwrapKey().orElseThrow());
|
||||
if (adapter == null) {
|
||||
throw new IllegalArgumentException("No adapter found for " + holder);
|
||||
}
|
||||
if (adapter.isUnimplemented()) {
|
||||
return new Unimplemented<>((Holder<net.minecraft.core.component.DataComponentType<NMS>>) holder, adapter);
|
||||
} else if (adapter.isValued()) {
|
||||
return new ValuedImpl<>((Holder<net.minecraft.core.component.DataComponentType<NMS>>) holder, adapter);
|
||||
} else {
|
||||
return new ValuedImpl<>(reference, converter);
|
||||
return new NonValuedImpl<>((Holder<net.minecraft.core.component.DataComponentType<NMS>>) holder, adapter);
|
||||
}
|
||||
}
|
||||
|
||||
public static final class NonValuedImpl<A, M> extends PaperDataComponentType<A, M> implements NonValued {
|
||||
public static final class NonValuedImpl<T, NMS> extends PaperDataComponentType<T, NMS> implements NonValued {
|
||||
|
||||
NonValuedImpl(
|
||||
final Holder<net.minecraft.core.component.DataComponentType<M>> holder,
|
||||
final Converter<M, A> adapter
|
||||
final Holder<net.minecraft.core.component.DataComponentType<NMS>> holder,
|
||||
final DataComponentAdapter<NMS, T> adapter
|
||||
) {
|
||||
super(holder, adapter);
|
||||
}
|
||||
}
|
||||
|
||||
public static final class ValuedImpl<A, M> extends PaperDataComponentType<A, M> implements Valued<A> {
|
||||
public static final class ValuedImpl<T, NMS> extends PaperDataComponentType<T, NMS> implements Valued<T> {
|
||||
|
||||
ValuedImpl(
|
||||
final Holder<net.minecraft.core.component.DataComponentType<M>> holder,
|
||||
final Converter<M, A> converter
|
||||
final Holder<net.minecraft.core.component.DataComponentType<NMS>> holder,
|
||||
final DataComponentAdapter<NMS, T> adapter
|
||||
) {
|
||||
super(holder, converter);
|
||||
super(holder, adapter);
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Unimplemented<A, M> extends PaperDataComponentType<A, M> {
|
||||
public static final class Unimplemented<T, NMS> extends PaperDataComponentType<T, NMS> {
|
||||
|
||||
public Unimplemented(
|
||||
final Holder<net.minecraft.core.component.DataComponentType<M>> holder,
|
||||
final Converter<M, A> converter
|
||||
final Holder<net.minecraft.core.component.DataComponentType<NMS>> holder,
|
||||
final DataComponentAdapter<NMS, T> adapter
|
||||
) {
|
||||
super(holder, converter);
|
||||
super(holder, adapter);
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -17,8 +17,8 @@ public record PaperItemEnchantments(
|
||||
Map<Enchantment, Integer> enchantments // API values are stored externally as the concept of a lazy key transformer map does not make much sense
|
||||
) implements ItemEnchantments, Handleable<net.minecraft.world.item.enchantment.ItemEnchantments> {
|
||||
|
||||
public static PaperItemEnchantments of(final net.minecraft.world.item.enchantment.ItemEnchantments itemEnchantments) {
|
||||
return new PaperItemEnchantments(itemEnchantments, convert(itemEnchantments));
|
||||
public PaperItemEnchantments(final net.minecraft.world.item.enchantment.ItemEnchantments itemEnchantments) {
|
||||
this(itemEnchantments, convert(itemEnchantments));
|
||||
}
|
||||
|
||||
private static Map<Enchantment, Integer> convert(final net.minecraft.world.item.enchantment.ItemEnchantments itemEnchantments) {
|
||||
@@ -57,14 +57,14 @@ public record PaperItemEnchantments(
|
||||
public ItemEnchantments build() {
|
||||
final net.minecraft.world.item.enchantment.ItemEnchantments initialEnchantments = net.minecraft.world.item.enchantment.ItemEnchantments.EMPTY;
|
||||
if (this.enchantments.isEmpty()) {
|
||||
return PaperItemEnchantments.of(initialEnchantments);
|
||||
return new PaperItemEnchantments(initialEnchantments);
|
||||
}
|
||||
|
||||
final net.minecraft.world.item.enchantment.ItemEnchantments.Mutable mutable = new net.minecraft.world.item.enchantment.ItemEnchantments.Mutable(initialEnchantments);
|
||||
this.enchantments.forEach((enchantment, level) ->
|
||||
mutable.set(CraftEnchantment.bukkitToMinecraftHolder(enchantment), level)
|
||||
);
|
||||
return PaperItemEnchantments.of(mutable.toImmutable());
|
||||
return new PaperItemEnchantments(mutable.toImmutable());
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -33,7 +33,7 @@ import net.minecraft.server.dialog.body.PlainMessage;
|
||||
import net.minecraft.server.dialog.input.TextInput;
|
||||
import net.minecraft.util.ExtraCodecs;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.world.item.ItemStackTemplate;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
|
||||
import static io.papermc.paper.util.PaperCodecs.registryFileDecoderFor;
|
||||
@@ -85,7 +85,7 @@ public final class PaperDialogCodecs {
|
||||
);
|
||||
private static final Codec<PlainMessageDialogBody> SIMPLE_PLAIN_MESSAGE_BODY_CODEC = Codec.withAlternative(PLAIN_MESSAGE_BODY_CODEC.codec(), AdventureCodecs.COMPONENT_CODEC, component -> DialogBody.plainMessage(component, PlainMessage.DEFAULT_WIDTH));
|
||||
private static final MapCodec<ItemDialogBody> ITEM_BODY_CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
|
||||
ItemStackTemplate.CODEC.xmap(CraftItemStack::asBukkitCopy, CraftItemStack::asTemplate).fieldOf("item").forGetter(ItemDialogBody::item),
|
||||
ItemStack.CODEC.xmap(CraftItemStack::asBukkitCopy, CraftItemStack::asNMSCopy).fieldOf("item").forGetter(ItemDialogBody::item),
|
||||
SIMPLE_PLAIN_MESSAGE_BODY_CODEC.optionalFieldOf("description").forGetter(body -> Optional.ofNullable(body.description())),
|
||||
Codec.BOOL.optionalFieldOf("show_decorations", true).forGetter(ItemDialogBody::showDecorations),
|
||||
Codec.BOOL.optionalFieldOf("show_tooltip", true).forGetter(ItemDialogBody::showTooltip),
|
||||
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
package io.papermc.paper.registry.typed;
|
||||
|
||||
import io.papermc.paper.util.converter.Converter;
|
||||
import io.papermc.paper.util.converter.Converters;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
|
||||
public final class PaperTypedDataAdapters<T> {
|
||||
|
||||
private final Map<ResourceKey<T>, Converter<?, ?>> converters;
|
||||
|
||||
private PaperTypedDataAdapters(final Map<ResourceKey<T>, Converter<?, ?>> converters) {
|
||||
this.converters = converters;
|
||||
}
|
||||
|
||||
public static <T, C extends TypedDataCollector<T>> PaperTypedDataAdapters<T> create(
|
||||
final Registry<T> registry,
|
||||
final TypedDataCollector.Factory<T, C> collectorFactory,
|
||||
final Consumer<C> consumer
|
||||
) {
|
||||
final Map<ResourceKey<T>, Converter<?, ?>> converters = new IdentityHashMap<>();
|
||||
final C collector = collectorFactory.create(registry, converters);
|
||||
|
||||
consumer.accept(collector);
|
||||
|
||||
return new PaperTypedDataAdapters<>(converters);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <A extends Converter<?, ?>> A get(final ResourceKey<? extends T> key) {
|
||||
return (A) this.converters.getOrDefault(key, Converters.unimplemented());
|
||||
}
|
||||
}
|
||||
-120
@@ -1,120 +0,0 @@
|
||||
package io.papermc.paper.registry.typed;
|
||||
|
||||
import io.papermc.paper.util.converter.Converter;
|
||||
import io.papermc.paper.util.converter.Converters;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
|
||||
public class PaperTypedDataCollector<T> implements TypedDataCollector<T> {
|
||||
|
||||
private final Registry<T> registry;
|
||||
private final Map<ResourceKey<T>, Converter<?, ?>> converters;
|
||||
|
||||
public PaperTypedDataCollector(
|
||||
final Registry<T> registry,
|
||||
final Map<ResourceKey<T>, Converter<?, ?>> converters
|
||||
) {
|
||||
this.registry = registry;
|
||||
this.converters = converters;
|
||||
}
|
||||
|
||||
protected ResourceKey<T> getKey(final T type) {
|
||||
return this.registry.getResourceKey(type).orElseThrow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <M, A> void register(final T type, final Function<M, A> vanillaToApi, final Function<A, M> apiToVanilla) {
|
||||
this.register(this.getKey(type), vanillaToApi, apiToVanilla);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <M, A> void register(final ResourceKey<T> type, final Function<M, A> vanillaToApi, final Function<A, M> apiToVanilla) {
|
||||
this.registerInternal(type, vanillaToApi, apiToVanilla);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <M, A> void register(final T type, final Converter<M, A> converter) {
|
||||
this.register(this.getKey(type), converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <M, A> void register(final ResourceKey<T> type, final Converter<M, A> converter) {
|
||||
this.registerInternal(type, converter);
|
||||
}
|
||||
|
||||
private <M, A> void maybeRegister(final Supplier<ResourceKey<T>> type, final Converter<M, A> converter) {
|
||||
if (converter == Converters.unimplemented()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.register(type.get(), converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dispatcher<T> dispatch(final Function<T, Converter<?, ?>> converter) {
|
||||
return new Dispatcher<>() {
|
||||
@Override
|
||||
public void add(final Iterable<T> types) {
|
||||
types.forEach(type -> {
|
||||
PaperTypedDataCollector.this.register(PaperTypedDataCollector.this.getKey(type), converter.apply(type));
|
||||
});
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
@Override
|
||||
public final void add(final T type, final T... types) {
|
||||
PaperTypedDataCollector.this.register(PaperTypedDataCollector.this.getKey(type), converter.apply(type));
|
||||
for (final T t : types) {
|
||||
PaperTypedDataCollector.this.register(PaperTypedDataCollector.this.getKey(t), converter.apply(t));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassDispatcher<T> dispatchClass(final Function<Type, Converter<?, ?>> converter) {
|
||||
return (from, toType, toValueType) -> {
|
||||
for (final Field field : from.getDeclaredFields()) {
|
||||
final int mod = field.getModifiers();
|
||||
if (!Modifier.isStatic(mod) || !Modifier.isPublic(mod)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final T value;
|
||||
try {
|
||||
value = toType.apply(field);
|
||||
} catch (final ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
final Type valueType = toValueType.apply(value, field);
|
||||
if (valueType == null) {
|
||||
continue;
|
||||
}
|
||||
PaperTypedDataCollector.this.maybeRegister(() -> PaperTypedDataCollector.this.getKey(value), converter.apply(valueType));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected <M, A> void registerInternal(
|
||||
final ResourceKey<T> key,
|
||||
final Function<M, A> vanillaToApi,
|
||||
final Function<A, M> apiToVanilla
|
||||
) {
|
||||
this.registerInternal(key, Converter.direct(vanillaToApi, apiToVanilla));
|
||||
}
|
||||
|
||||
protected <M, A> void registerInternal(
|
||||
final ResourceKey<T> key,
|
||||
final Converter<M, A> converter
|
||||
) {
|
||||
if (this.converters.put(key, converter) != null) {
|
||||
throw new IllegalStateException("Duplicate converter registration for " + key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package io.papermc.paper.registry.typed;
|
||||
|
||||
import io.papermc.paper.util.converter.Converter;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public interface TypedDataCollector<T> {
|
||||
|
||||
<M, A> void register(T type, Function<M, A> vanillaToApi, Function<A, M> apiToVanilla);
|
||||
|
||||
default <M, A> void register(final Holder.Reference<T> type, final Function<M, A> vanillaToApi, final Function<A, M> apiToVanilla) {
|
||||
this.register(type.key(), vanillaToApi, apiToVanilla);
|
||||
}
|
||||
|
||||
<M, A> void register(ResourceKey<T> type, Function<M, A> vanillaToApi, Function<A, M> apiToVanilla);
|
||||
|
||||
<M, A> void register(T type, Converter<M, A> converter);
|
||||
|
||||
default <M, A> void register(final Holder.Reference<T> type, final Converter<M, A> converter) {
|
||||
this.register(type.key(), converter);
|
||||
}
|
||||
|
||||
<M, A> void register(ResourceKey<T> type, Converter<M, A> converter);
|
||||
|
||||
Dispatcher<T> dispatch(Function<T, Converter<?, ?>> converter);
|
||||
|
||||
ClassDispatcher<T> dispatchClass(Function<Type, Converter<?, ?>> converter);
|
||||
|
||||
interface Factory<T, C extends TypedDataCollector<T>> {
|
||||
|
||||
C create(Registry<T> registry, Map<ResourceKey<T>, Converter<?, ?>> adapters);
|
||||
}
|
||||
|
||||
interface Dispatcher<T> {
|
||||
|
||||
void add(Iterable<T> types);
|
||||
|
||||
void add(T type, T... types);
|
||||
}
|
||||
|
||||
interface ClassDispatcher<T> {
|
||||
|
||||
void scanConstants(Class<?> from, ReflectiveFunction<T> toType, BiFunction<T, Field, @Nullable Type> toValueType);
|
||||
|
||||
interface ReflectiveFunction<T> {
|
||||
T apply(Field field) throws ReflectiveOperationException;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
@NullMarked
|
||||
package io.papermc.paper.registry.typed;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
@@ -1,33 +0,0 @@
|
||||
package io.papermc.paper.util.converter;
|
||||
|
||||
import com.mojang.serialization.DataResult;
|
||||
import com.mojang.serialization.DynamicOps;
|
||||
import com.mojang.serialization.Encoder;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.util.NullOps;
|
||||
import net.minecraft.util.Unit;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
|
||||
public record CodecConverter<M, A>(
|
||||
Converter<M, A> converter,
|
||||
Encoder<M> serializer
|
||||
) implements Converter<M, A> {
|
||||
|
||||
@Override
|
||||
public M toVanilla(final A value) {
|
||||
return this.converter.toVanilla(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public A fromVanilla(final M value) {
|
||||
return this.converter.fromVanilla(value);
|
||||
}
|
||||
|
||||
public Optional<String> validate(final M value, final boolean requireRegistryAccess) {
|
||||
DynamicOps<Unit> ops = NullOps.INSTANCE;
|
||||
if (requireRegistryAccess) {
|
||||
ops = CraftRegistry.getMinecraftRegistry().createSerializationContext(ops);
|
||||
}
|
||||
return this.serializer.encodeStart(ops, value).error().map(DataResult.Error::message);
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
package io.papermc.paper.util.converter;
|
||||
|
||||
import com.mojang.serialization.Encoder;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import static io.papermc.paper.util.MCUtil.transformUnmodifiable;
|
||||
|
||||
public interface Converter<M, A> {
|
||||
|
||||
static <M, A> Converter<M, A> direct(final Function<M, A> vanillaToApi, final Function<A, M> apiToVanilla) {
|
||||
return new Converter<>() {
|
||||
@Override
|
||||
public M toVanilla(final A value) {
|
||||
return apiToVanilla.apply(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public A fromVanilla(final M value) {
|
||||
return vanillaToApi.apply(value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static <I> Converter<I, I> identity() {
|
||||
final class Holder {
|
||||
private static final Converter<?, ?> NO_OP = direct(Function.identity(), Function.identity());
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
return (Converter<I, I>) Holder.NO_OP;
|
||||
}
|
||||
|
||||
static <I> Converter<I, I> identity(final @Nullable Encoder<I> serializer) {
|
||||
final Converter<I, I> i = identity();
|
||||
if (serializer == null) {
|
||||
return i;
|
||||
}
|
||||
return i.serializable(serializer);
|
||||
}
|
||||
|
||||
default Converter<M, A> serializable(final Encoder<M> serializer) {
|
||||
return new CodecConverter<>(this, serializer);
|
||||
}
|
||||
|
||||
default Converter<Collection<M>, Collection<A>> collectionOf() {
|
||||
return Converter.direct(
|
||||
collection -> transformUnmodifiable(collection, this::fromVanilla),
|
||||
collection -> transformUnmodifiable(collection, this::toVanilla)
|
||||
);
|
||||
}
|
||||
|
||||
default Converter<List<M>, List<A>> listOf() {
|
||||
return Converter.direct(
|
||||
list -> transformUnmodifiable(list, this::fromVanilla),
|
||||
list -> transformUnmodifiable(list, this::toVanilla)
|
||||
);
|
||||
}
|
||||
|
||||
default Converter<Set<M>, Set<A>> setOf() {
|
||||
return Converter.direct(
|
||||
set -> set.stream().map(this::fromVanilla).collect(Collectors.toUnmodifiableSet()),
|
||||
set -> set.stream().map(this::toVanilla).collect(Collectors.toUnmodifiableSet())
|
||||
);
|
||||
}
|
||||
|
||||
M toVanilla(A value);
|
||||
|
||||
A fromVanilla(M value);
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
package io.papermc.paper.util.converter;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.bukkit.craftbukkit.entity.CraftEntity;
|
||||
import org.bukkit.craftbukkit.util.Handleable;
|
||||
|
||||
import static io.papermc.paper.util.MCUtil.transformUnmodifiable;
|
||||
|
||||
public final class Converters {
|
||||
|
||||
private static final Converter<?, ?> UNIMPLEMENTED = Converter.direct(
|
||||
_ -> {
|
||||
throw new UnsupportedOperationException("Cannot convert an unimplemented type to an API value");
|
||||
}, _ -> {
|
||||
throw new UnsupportedOperationException("Cannot convert an API value to an unimplemented type");
|
||||
}
|
||||
);
|
||||
private static final Converter<Unit, ?> UNVALUED = Converter.direct(
|
||||
_ -> {
|
||||
throw new UnsupportedOperationException("Cannot convert the Unit type to an API value");
|
||||
}, _ -> Unit.INSTANCE
|
||||
);
|
||||
|
||||
private Converters() {
|
||||
}
|
||||
|
||||
public static <M extends Enum<M>, A extends Enum<A>> Converter<M, A> sameName(final Class<A> apiEnum, final Class<M> internalEnum) {
|
||||
return Converter.direct(
|
||||
value -> Enum.valueOf(apiEnum, value.name()),
|
||||
value -> Enum.valueOf(internalEnum, value.name())
|
||||
);
|
||||
}
|
||||
|
||||
public static <M extends Enum<M>, A extends Enum<A>> Converter<M, A> sameOrder(final Class<A> apiEnum, final Class<M> internalEnum) {
|
||||
final A[] apiValues = apiEnum.getEnumConstants();
|
||||
final M[] internalValues = internalEnum.getEnumConstants();
|
||||
return Converter.direct(
|
||||
value -> apiValues[value.ordinal()],
|
||||
value -> internalValues[value.ordinal()]
|
||||
);
|
||||
}
|
||||
|
||||
public static <M, A> Converter<Collection<M>, Collection<A>> collectionOf(final Function<M, A> vanillaToApi, final Function<A, M> apiToVanilla) {
|
||||
return Converter.direct(
|
||||
collection -> transformUnmodifiable(collection, vanillaToApi),
|
||||
collection -> transformUnmodifiable(collection, apiToVanilla)
|
||||
);
|
||||
}
|
||||
|
||||
public static <M, A> Converter<List<M>, List<A>> listOf(final Function<M, A> vanillaToApi, final Function<A, M> apiToVanilla) {
|
||||
return Converter.direct(
|
||||
list -> transformUnmodifiable(list, vanillaToApi),
|
||||
list -> transformUnmodifiable(list, apiToVanilla)
|
||||
);
|
||||
}
|
||||
|
||||
public static <M, A> Converter<Set<M>, Set<A>> setOf(final Function<M, A> vanillaToApi, final Function<A, M> apiToVanilla) {
|
||||
return Converter.direct(
|
||||
set -> set.stream().map(vanillaToApi).collect(Collectors.toUnmodifiableSet()),
|
||||
set -> set.stream().map(apiToVanilla).collect(Collectors.toUnmodifiableSet())
|
||||
);
|
||||
}
|
||||
|
||||
// make sure that no custom logic run in the specialized methods under implementation
|
||||
public static <M, A extends Keyed> Converter<Holder<M>, A> registryElement(final ResourceKey<? extends Registry<M>> registryKey) { // todo remove Keyed
|
||||
return Converter.direct(
|
||||
holder -> CraftRegistry.minecraftHolderToBukkit(holder, registryKey),
|
||||
CraftRegistry::bukkitToMinecraftHolder
|
||||
);
|
||||
}
|
||||
|
||||
public static <M, A extends Handleable<M>> Converter<M, A> wrapper(final Function<M, A> vanillaToApi) {
|
||||
return Converter.direct(vanillaToApi, Handleable::getHandle);
|
||||
}
|
||||
|
||||
public static <M extends Entity, A extends CraftEntity> Converter<M, A> entity(final Class<M> vanillaEntity, final Class<A> apiEntity) {
|
||||
return Converter.direct(
|
||||
entity -> apiEntity.cast(entity.getBukkitEntity()),
|
||||
entity -> vanillaEntity.cast(entity.getHandle())
|
||||
);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <A, M> Converter<A, M> unimplemented() {
|
||||
return (Converter<A, M>) UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <A, M> Converter<A, M> unvalued() {
|
||||
return (Converter<A, M>) UNVALUED;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
@NullMarked
|
||||
package io.papermc.paper.util.converter;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
@@ -95,8 +95,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import static io.papermc.paper.util.BoundChecker.requireNonNegative;
|
||||
|
||||
public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
@@ -920,20 +918,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInvulnerable(final boolean flag) {
|
||||
public void setInvulnerable(boolean flag) {
|
||||
this.getHandle().setPermanentlyInvulnerable(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInvulnerableTime() {
|
||||
return this.getHandle().getInvulnerableTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInvulnerableTime(final int ticks) {
|
||||
this.getHandle().setInvulnerableTime(requireNonNegative(ticks, "ticks"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMarkedInvulnerable() {
|
||||
return this.getHandle().isInvulnerable();
|
||||
|
||||
@@ -8,7 +8,6 @@ import io.papermc.paper.inventory.tooltip.TooltipContext;
|
||||
import io.papermc.paper.persistence.PaperPersistentDataContainerView;
|
||||
import io.papermc.paper.persistence.PersistentDataContainerView;
|
||||
import io.papermc.paper.util.MCUtil;
|
||||
import io.papermc.paper.util.converter.CodecConverter;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.util.ArrayList;
|
||||
@@ -670,13 +669,7 @@ public final class CraftItemStack extends ItemStack {
|
||||
}
|
||||
|
||||
private <A, V> void setDataInternal(final PaperDataComponentType<A, V> type, final A value) {
|
||||
final V v = type.getConverter().toVanilla(value);
|
||||
if (type.getConverter() instanceof final CodecConverter<V, A> codecConverter) {
|
||||
codecConverter.validate(v, true).ifPresent(message -> {
|
||||
throw new IllegalArgumentException("Failed to encode data component %s (%s)".formatted(type.getKey().asString(), message));
|
||||
});
|
||||
}
|
||||
this.handle.set(type.getHandle(), v);
|
||||
this.handle.set(type.getHandle(), type.getAdapter().toVanilla(value, type.getHolder()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -82,7 +82,7 @@ public final class CraftMenus {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftDoubleChestInventoryViewBuilder<>(handle)));
|
||||
}
|
||||
if (menuType == MenuType.GENERIC_9X3) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.CHEST, ChestBlockEntity::new)));
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.CHEST, ChestBlockEntity::new, false)));
|
||||
}
|
||||
// this isn't ideal as both dispenser and dropper are 3x3, InventoryType can't currently handle generic 3x3s with size 9
|
||||
// this needs to be removed when inventory creation is overhauled
|
||||
|
||||
+16
-3
@@ -16,14 +16,25 @@ import org.jspecify.annotations.Nullable;
|
||||
public class CraftBlockEntityInventoryViewBuilder<V extends InventoryView> extends CraftAbstractLocationInventoryViewBuilder<V> {
|
||||
|
||||
private final Block block;
|
||||
private final boolean useFakeBlockEntity;
|
||||
private final @Nullable CraftBlockInventoryBuilder builder;
|
||||
|
||||
public CraftBlockEntityInventoryViewBuilder(
|
||||
final MenuType<?> handle,
|
||||
final Block block,
|
||||
final @Nullable CraftBlockInventoryBuilder builder
|
||||
) {
|
||||
this(handle, block, builder, true);
|
||||
}
|
||||
|
||||
public CraftBlockEntityInventoryViewBuilder(
|
||||
final MenuType<?> handle,
|
||||
final Block block,
|
||||
final @Nullable CraftBlockInventoryBuilder builder,
|
||||
final boolean useFakeBlockEntity
|
||||
) {
|
||||
super(handle);
|
||||
this.useFakeBlockEntity = useFakeBlockEntity;
|
||||
this.block = block;
|
||||
this.builder = builder;
|
||||
}
|
||||
@@ -61,17 +72,19 @@ public class CraftBlockEntityInventoryViewBuilder<V extends InventoryView> exten
|
||||
final MenuProvider inventory = this.builder.build(this.position, this.block.defaultBlockState());
|
||||
if (inventory instanceof final BlockEntity blockEntity) {
|
||||
blockEntity.setLevel(this.world);
|
||||
// marks this as "not in world" for gating general level broadcasts
|
||||
blockEntity.real = false;
|
||||
super.defaultTitle = inventory.getDisplayName();
|
||||
}
|
||||
|
||||
if (!this.useFakeBlockEntity) { // gets around open noise for chest
|
||||
return handle.create(player.nextContainerCounter(), player.getInventory());
|
||||
}
|
||||
|
||||
return inventory.createMenu(player.nextContainerCounter(), player.getInventory(), player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocationInventoryViewBuilder<V> copy() {
|
||||
final CraftBlockEntityInventoryViewBuilder<V> copy = new CraftBlockEntityInventoryViewBuilder<>(super.handle, this.block, this.builder);
|
||||
final CraftBlockEntityInventoryViewBuilder<V> copy = new CraftBlockEntityInventoryViewBuilder<>(super.handle, this.block, this.builder, this.useFakeBlockEntity);
|
||||
copy.world = this.world;
|
||||
copy.position = this.position;
|
||||
copy.checkReachable = super.checkReachable;
|
||||
|
||||
Reference in new issue
Block a user