1.21.6 dev
Co-authored-by: Bjarne Koll <git@lynxplay.dev> Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com> Co-authored-by: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Co-authored-by: Noah van der Aa <ndvdaa@gmail.com> Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
This commit is contained in:
committed by
Nassim Jahnke
parent
39203a65e0
commit
a24f9b204c
@@ -10,11 +10,14 @@ import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.core.GlobalPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.protocol.game.ClientboundTagQueryPacket;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.players.UserWhiteListEntry;
|
||||
import net.minecraft.stats.ServerStatsCounter;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.level.storage.PlayerDataStorage;
|
||||
import net.minecraft.world.level.storage.TagValueOutput;
|
||||
import net.minecraft.world.phys.Vec2;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.BanEntry;
|
||||
@@ -196,7 +199,8 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa
|
||||
}
|
||||
|
||||
private CompoundTag getData() {
|
||||
return this.storage.load(this.profile.getName(), this.profile.getId().toString()).orElse(null);
|
||||
// This method does not use the problem reporter
|
||||
return this.storage.load(this.profile.getName(), this.profile.getId().toString(), ProblemReporter.DISCARDING).orElse(null);
|
||||
}
|
||||
|
||||
private CompoundTag getBukkitData() {
|
||||
|
||||
@@ -198,7 +198,6 @@ public abstract class CraftRegionAccessor implements RegionAccessor {
|
||||
BlockPos pos = CraftLocation.toBlockPosition(location);
|
||||
BlockStateListPopulator populator = new BlockStateListPopulator(this.getHandle());
|
||||
boolean result = this.generateTree(populator, this.getHandle().getMinecraftWorld().getChunkSource().getGenerator(), pos, new RandomSourceWrapper(random), treeType);
|
||||
populator.refreshTiles();
|
||||
populator.placeSomeBlocks(predicate == null ? ($ -> true) : predicate);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -205,7 +205,8 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
|
||||
return cached;
|
||||
}
|
||||
|
||||
final Optional<Holder.Reference<M>> holderOptional = this.minecraftRegistry.get(CraftNamespacedKey.toMinecraft(namespacedKey));
|
||||
// Important to use the ResourceKey<?> "get" method below because it will work before registry is frozen
|
||||
final Optional<Holder.Reference<M>> holderOptional = this.minecraftRegistry.get(MCUtil.toResourceKey(this.minecraftRegistry.key(), namespacedKey));
|
||||
final Holder.Reference<M> holder;
|
||||
if (holderOptional.isPresent()) {
|
||||
holder = holderOptional.get();
|
||||
@@ -215,12 +216,9 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
|
||||
// to create something to fill the API constant fields, so we create a dummy reference holder.
|
||||
holder = Holder.Reference.createStandAlone(this.invalidHolderOwner, MCUtil.toResourceKey(this.minecraftRegistry.key(), namespacedKey));
|
||||
} else {
|
||||
holder = null;
|
||||
}
|
||||
final B bukkit = this.createBukkit(holder);
|
||||
if (bukkit == null) {
|
||||
return null;
|
||||
}
|
||||
final B bukkit = this.createBukkit(holder);
|
||||
|
||||
this.cache.put(namespacedKey, bukkit);
|
||||
|
||||
@@ -250,10 +248,6 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
|
||||
}
|
||||
|
||||
public B createBukkit(Holder<M> minecraft) {
|
||||
if (minecraft == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.minecraftToBukkit.createBukkit(minecraft);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.bukkit.entity.EntityType;
|
||||
|
||||
public enum CraftStatistic {
|
||||
// Start generate - CraftStatisticCustom
|
||||
// @GeneratedFrom 1.21.5
|
||||
// @GeneratedFrom 1.21.6-rc1
|
||||
ANIMALS_BRED(Stats.ANIMALS_BRED),
|
||||
AVIATE_ONE_CM(Stats.AVIATE_ONE_CM),
|
||||
BELL_RING(Stats.BELL_RING),
|
||||
@@ -46,6 +46,7 @@ public enum CraftStatistic {
|
||||
CAULDRON_FILLED(Stats.FILL_CAULDRON),
|
||||
FISH_CAUGHT(Stats.FISH_CAUGHT),
|
||||
FLY_ONE_CM(Stats.FLY_ONE_CM),
|
||||
HAPPY_GHAST_ONE_CM(Stats.HAPPY_GHAST_ONE_CM),
|
||||
HORSE_ONE_CM(Stats.HORSE_ONE_CM),
|
||||
DISPENSER_INSPECTED(Stats.INSPECT_DISPENSER),
|
||||
DROPPER_INSPECTED(Stats.INSPECT_DROPPER),
|
||||
@@ -99,7 +100,7 @@ public enum CraftStatistic {
|
||||
WALK_UNDER_WATER_ONE_CM(Stats.WALK_UNDER_WATER_ONE_CM),
|
||||
// End generate - CraftStatisticCustom
|
||||
// Start generate - CraftStatisticType
|
||||
// @GeneratedFrom 1.21.5
|
||||
// @GeneratedFrom 1.21.6-rc1
|
||||
BREAK_ITEM(ResourceLocation.withDefaultNamespace("broken")),
|
||||
CRAFT_ITEM(ResourceLocation.withDefaultNamespace("crafted")),
|
||||
DROP(ResourceLocation.withDefaultNamespace("dropped")),
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import ca.spottedleaf.moonrise.common.list.ReferenceList;
|
||||
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
@@ -12,6 +14,7 @@ import io.papermc.paper.raytracing.PositionedRayTraceConfigurationBuilderImpl;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -19,6 +22,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.PrimitiveIterator;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
@@ -40,6 +44,7 @@ import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.DistanceManager;
|
||||
import net.minecraft.server.level.ServerChunkCache;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.level.TicketType;
|
||||
@@ -243,7 +248,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public BiomeProvider vanillaBiomeProvider() {
|
||||
net.minecraft.server.level.ServerChunkCache serverCache = this.getHandle().chunkSource;
|
||||
ServerChunkCache serverCache = this.getHandle().chunkSource;
|
||||
|
||||
final net.minecraft.world.level.chunk.ChunkGenerator gen = serverCache.getGenerator();
|
||||
net.minecraft.world.level.biome.BiomeSource biomeSource;
|
||||
@@ -421,8 +426,21 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public Chunk[] getLoadedChunks() {
|
||||
List<ChunkHolder> chunks = ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.world); // Paper
|
||||
return chunks.stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull).map(CraftChunk::new).toArray(Chunk[]::new);
|
||||
ServerChunkCache serverChunkCache = this.getHandle().chunkSource;
|
||||
ReferenceList<Chunk> chunks = new ReferenceList<>(new Chunk[serverChunkCache.fullChunks.size()]);
|
||||
|
||||
for (PrimitiveIterator.OfLong iterator = serverChunkCache.fullChunks.keyIterator(); iterator.hasNext();) {
|
||||
long chunk = iterator.nextLong();
|
||||
chunks.add(new CraftChunk(this.world, CoordinateUtils.getChunkX(chunk), CoordinateUtils.getChunkZ(chunk)));
|
||||
}
|
||||
|
||||
Chunk[] raw = chunks.getRawDataUnchecked();
|
||||
int size = chunks.size();
|
||||
if (raw.length == size) {
|
||||
// always true when on main
|
||||
return raw;
|
||||
}
|
||||
return Arrays.copyOf(raw, size);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -631,7 +649,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
Set<Chunk> chunks = new HashSet<>();
|
||||
|
||||
for (long coord : this.getHandle().getForceLoadedChunks()) {
|
||||
chunks.add(this.getChunkAt(ChunkPos.getX(coord), ChunkPos.getZ(coord)));
|
||||
chunks.add(new CraftChunk(this.getHandle(), ChunkPos.getX(coord), ChunkPos.getZ(coord)));
|
||||
}
|
||||
|
||||
return Collections.unmodifiableCollection(chunks);
|
||||
@@ -828,7 +846,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
CraftPlayer cp = (CraftPlayer) p;
|
||||
if (cp.getHandle().connection == null) continue;
|
||||
|
||||
cp.getHandle().connection.send(new ClientboundSetTimePacket(cp.getHandle().level().getGameTime(), cp.getHandle().getPlayerTime(), cp.getHandle().relativeTime && cp.getHandle().serverLevel().getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)));
|
||||
cp.getHandle().connection.send(new ClientboundSetTimePacket(cp.getHandle().level().getGameTime(), cp.getHandle().getPlayerTime(), cp.getHandle().relativeTime && cp.getHandle().level().getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,16 +3,16 @@ package org.bukkit.craftbukkit;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import joptsimple.OptionParser;
|
||||
import joptsimple.OptionSet;
|
||||
import joptsimple.util.PathConverter;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
public class Main {
|
||||
public static final java.time.Instant BOOT_TIME = java.time.Instant.now(); // Paper - track initial start time
|
||||
public static boolean useJline = true;
|
||||
@@ -25,41 +25,40 @@ public class Main {
|
||||
// Paper end - Reset loggers after shutdown
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Todo: Installation script
|
||||
if (System.getProperty("jdk.nio.maxCachedBufferSize") == null) System.setProperty("jdk.nio.maxCachedBufferSize", "262144"); // Paper - cap per-thread NIO cache size; https://www.evanjones.ca/java-bytebuffer-leak.html
|
||||
OptionParser parser = new OptionParser() {
|
||||
{
|
||||
this.acceptsAll(Main.asList("?", "help"), "Show the help");
|
||||
this.acceptsAll(asList("?", "help"), "Show the help");
|
||||
|
||||
this.acceptsAll(Main.asList("c", "config"), "Properties file to use")
|
||||
this.acceptsAll(asList("c", "config"), "Properties file to use")
|
||||
.withRequiredArg()
|
||||
.ofType(File.class)
|
||||
.defaultsTo(new File("server.properties"))
|
||||
.describedAs("Properties file");
|
||||
|
||||
this.acceptsAll(Main.asList("P", "plugins"), "Plugin directory to use")
|
||||
this.acceptsAll(asList("P", "plugins"), "Plugin directory to use")
|
||||
.withRequiredArg()
|
||||
.ofType(File.class)
|
||||
.defaultsTo(new File("plugins"))
|
||||
.describedAs("Plugin directory");
|
||||
|
||||
this.acceptsAll(Main.asList("h", "host", "server-ip"), "Host to listen on")
|
||||
this.acceptsAll(asList("h", "host", "server-ip"), "Host to listen on")
|
||||
.withRequiredArg()
|
||||
.ofType(String.class)
|
||||
.describedAs("Hostname or IP");
|
||||
|
||||
this.acceptsAll(Main.asList("W", "world-dir", "universe", "world-container"), "World container")
|
||||
this.acceptsAll(asList("W", "world-dir", "universe", "world-container"), "World container")
|
||||
.withRequiredArg()
|
||||
.ofType(File.class)
|
||||
.defaultsTo(new File("."))
|
||||
.describedAs("Directory containing worlds");
|
||||
|
||||
this.acceptsAll(Main.asList("w", "world", "level-name"), "World name")
|
||||
this.acceptsAll(asList("w", "world", "level-name"), "World name")
|
||||
.withRequiredArg()
|
||||
.ofType(String.class)
|
||||
.describedAs("World name");
|
||||
|
||||
this.acceptsAll(Main.asList("p", "port", "server-port"), "Port to listen on")
|
||||
this.acceptsAll(asList("p", "port", "server-port"), "Port to listen on")
|
||||
.withRequiredArg()
|
||||
.ofType(Integer.class)
|
||||
.describedAs("Port");
|
||||
@@ -73,99 +72,99 @@ public class Main {
|
||||
.withRequiredArg()
|
||||
.withValuesConvertedBy(new PathConverter());
|
||||
|
||||
this.acceptsAll(Main.asList("o", "online-mode"), "Whether to use online authentication")
|
||||
this.acceptsAll(asList("o", "online-mode"), "Whether to use online authentication")
|
||||
.withRequiredArg()
|
||||
.ofType(Boolean.class)
|
||||
.describedAs("Authentication");
|
||||
|
||||
this.acceptsAll(Main.asList("s", "size", "max-players"), "Maximum amount of players")
|
||||
this.acceptsAll(asList("s", "size", "max-players"), "Maximum amount of players")
|
||||
.withRequiredArg()
|
||||
.ofType(Integer.class)
|
||||
.describedAs("Server size");
|
||||
|
||||
this.acceptsAll(Main.asList("d", "date-format"), "Format of the date to display in the console (for log entries)")
|
||||
this.acceptsAll(asList("d", "date-format"), "Format of the date to display in the console (for log entries)")
|
||||
.withRequiredArg()
|
||||
.ofType(SimpleDateFormat.class)
|
||||
.describedAs("Log date format");
|
||||
|
||||
this.acceptsAll(Main.asList("log-pattern"), "Specfies the log filename pattern")
|
||||
this.accepts("log-pattern", "Specfies the log filename pattern")
|
||||
.withRequiredArg()
|
||||
.ofType(String.class)
|
||||
.defaultsTo("server.log")
|
||||
.describedAs("Log filename");
|
||||
|
||||
this.acceptsAll(Main.asList("log-limit"), "Limits the maximum size of the log file (0 = unlimited)")
|
||||
this.accepts("log-limit", "Limits the maximum size of the log file (0 = unlimited)")
|
||||
.withRequiredArg()
|
||||
.ofType(Integer.class)
|
||||
.defaultsTo(0)
|
||||
.describedAs("Max log size");
|
||||
|
||||
this.acceptsAll(Main.asList("log-count"), "Specified how many log files to cycle through")
|
||||
this.accepts("log-count", "Specified how many log files to cycle through")
|
||||
.withRequiredArg()
|
||||
.ofType(Integer.class)
|
||||
.defaultsTo(1)
|
||||
.describedAs("Log count");
|
||||
|
||||
this.acceptsAll(Main.asList("log-append"), "Whether to append to the log file")
|
||||
this.accepts("log-append", "Whether to append to the log file")
|
||||
.withRequiredArg()
|
||||
.ofType(Boolean.class)
|
||||
.defaultsTo(true)
|
||||
.describedAs("Log append");
|
||||
|
||||
this.acceptsAll(Main.asList("log-strip-color"), "Strips color codes from log file");
|
||||
this.accepts("log-strip-color", "Strips color codes from log file");
|
||||
|
||||
this.acceptsAll(Main.asList("b", "bukkit-settings"), "File for bukkit settings")
|
||||
this.acceptsAll(asList("b", "bukkit-settings"), "File for bukkit settings")
|
||||
.withRequiredArg()
|
||||
.ofType(File.class)
|
||||
.defaultsTo(new File("bukkit.yml"))
|
||||
.describedAs("Yml file");
|
||||
|
||||
this.acceptsAll(Main.asList("C", "commands-settings"), "File for command settings")
|
||||
this.acceptsAll(asList("C", "commands-settings"), "File for command settings")
|
||||
.withRequiredArg()
|
||||
.ofType(File.class)
|
||||
.defaultsTo(new File("commands.yml"))
|
||||
.describedAs("Yml file");
|
||||
|
||||
this.acceptsAll(Main.asList("forceUpgrade"), "Whether to force a world upgrade");
|
||||
this.acceptsAll(Main.asList("eraseCache"), "Whether to force cache erase during world upgrade");
|
||||
this.acceptsAll(Main.asList("recreateRegionFiles"), "Whether to recreate region files during world upgrade");
|
||||
this.accepts("forceUpgrade", "Whether to force a world upgrade");
|
||||
this.accepts("eraseCache", "Whether to force cache erase during world upgrade");
|
||||
this.accepts("recreateRegionFiles", "Whether to recreate region files during world upgrade");
|
||||
this.accepts("safeMode", "Loads level with vanilla datapack only"); // Paper
|
||||
this.acceptsAll(Main.asList("nogui"), "Disables the graphical console");
|
||||
this.accepts("nogui", "Disables the graphical console");
|
||||
|
||||
this.acceptsAll(Main.asList("nojline"), "Disables jline and emulates the vanilla console");
|
||||
this.accepts("nojline", "Disables jline and emulates the vanilla console");
|
||||
|
||||
this.acceptsAll(Main.asList("noconsole"), "Disables the console");
|
||||
this.accepts("noconsole", "Disables the console");
|
||||
|
||||
this.acceptsAll(Main.asList("v", "version"), "Show the CraftBukkit Version");
|
||||
this.acceptsAll(asList("v", "version"), "Show the CraftBukkit Version");
|
||||
|
||||
this.acceptsAll(Main.asList("demo"), "Demo mode");
|
||||
this.accepts("demo", "Demo mode");
|
||||
|
||||
this.acceptsAll(Main.asList("initSettings"), "Only create configuration files and then exit"); // SPIGOT-5761: Add initSettings option
|
||||
this.accepts("initSettings", "Only create configuration files and then exit"); // SPIGOT-5761: Add initSettings option
|
||||
|
||||
this.acceptsAll(Main.asList("S", "spigot-settings"), "File for spigot settings")
|
||||
this.acceptsAll(asList("S", "spigot-settings"), "File for spigot settings")
|
||||
.withRequiredArg()
|
||||
.ofType(File.class)
|
||||
.defaultsTo(new File("spigot.yml"))
|
||||
.describedAs("Yml file");
|
||||
|
||||
acceptsAll(asList("paper-dir", "paper-settings-directory"), "Directory for Paper settings")
|
||||
this.acceptsAll(asList("paper-dir", "paper-settings-directory"), "Directory for Paper settings")
|
||||
.withRequiredArg()
|
||||
.ofType(File.class)
|
||||
.defaultsTo(new File(io.papermc.paper.configuration.PaperConfigurations.CONFIG_DIR))
|
||||
.describedAs("Config directory");
|
||||
acceptsAll(asList("paper", "paper-settings"), "File for Paper settings")
|
||||
this.acceptsAll(asList("paper", "paper-settings"), "File for Paper settings")
|
||||
.withRequiredArg()
|
||||
.ofType(File.class)
|
||||
.defaultsTo(new File("paper.yml"))
|
||||
.describedAs("Yml file");
|
||||
|
||||
acceptsAll(asList("add-plugin", "add-extra-plugin-jar"), "Specify paths to extra plugin jars to be loaded in addition to those in the plugins folder. This argument can be specified multiple times, once for each extra plugin jar path.")
|
||||
this.acceptsAll(asList("add-plugin", "add-extra-plugin-jar"), "Specify paths to extra plugin jars to be loaded in addition to those in the plugins folder. This argument can be specified multiple times, once for each extra plugin jar path.")
|
||||
.withRequiredArg()
|
||||
.ofType(File.class)
|
||||
.defaultsTo(new File[] {})
|
||||
.describedAs("Jar file");
|
||||
|
||||
acceptsAll(asList("server-name"), "Name of the server")
|
||||
this.accepts("server-name", "Name of the server")
|
||||
.withRequiredArg()
|
||||
.ofType(String.class)
|
||||
.defaultsTo("Unknown Server")
|
||||
@@ -246,8 +245,4 @@ public class Main {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> asList(String... params) {
|
||||
return Arrays.asList(params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,10 +40,7 @@ public final class CapturedBlockState extends CraftBlockState {
|
||||
@Override
|
||||
public boolean place(int flags) {
|
||||
boolean result = super.place(flags);
|
||||
|
||||
if (result) {
|
||||
this.addBees();
|
||||
}
|
||||
this.addBees();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import java.util.Objects;
|
||||
@@ -61,17 +60,17 @@ public class CraftBiome extends OldEnumHolderable<Biome, net.minecraft.world.lev
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull NamespacedKey getKey() {
|
||||
public NamespacedKey getKey() {
|
||||
return LEGACY_CUSTOM_KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull final Biome other) {
|
||||
public int compareTo(final Biome other) {
|
||||
return this.ordinal - other.ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String name() {
|
||||
public String name() {
|
||||
return "CUSTOM";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.bukkit.craftbukkit.block;
|
||||
|
||||
import java.util.Set;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.component.DataComponentMap;
|
||||
import net.minecraft.core.component.DataComponentPatch;
|
||||
@@ -9,8 +10,11 @@ import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import net.minecraft.world.level.storage.TagValueOutput;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.TileState;
|
||||
@@ -19,9 +23,12 @@ import org.bukkit.craftbukkit.util.CraftLocation;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public abstract class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockState implements TileState { // Paper - revert upstream's revert of the block state changes
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private final T blockEntity;
|
||||
private final T snapshot;
|
||||
public boolean snapshotDisabled; // Paper
|
||||
@@ -67,10 +74,6 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
|
||||
this.loadData(state.getSnapshotNBT());
|
||||
}
|
||||
|
||||
public void refreshSnapshot() {
|
||||
this.load(this.blockEntity);
|
||||
}
|
||||
|
||||
private RegistryAccess getRegistryAccess() {
|
||||
LevelAccessor worldHandle = this.getWorldHandle();
|
||||
return (worldHandle != null) ? worldHandle.registryAccess() : CraftRegistry.getMinecraftRegistry();
|
||||
@@ -97,14 +100,22 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
|
||||
|
||||
// Loads the specified data into the snapshot BlockEntity.
|
||||
public void loadData(CompoundTag tag) {
|
||||
this.snapshot.loadWithComponents(tag, this.getRegistryAccess());
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "CraftBlockEntityState@" + getPosition().toShortString(), LOGGER
|
||||
)) {
|
||||
this.snapshot.loadWithComponents(TagValueInput.create(problemReporter, this.getRegistryAccess(), tag));
|
||||
}
|
||||
this.load(this.snapshot);
|
||||
}
|
||||
|
||||
// copies the BlockEntity-specific data, retains the position
|
||||
private void copyData(T from, T to) {
|
||||
CompoundTag tag = from.saveWithFullMetadata(this.getRegistryAccess());
|
||||
to.loadWithComponents(tag, this.getRegistryAccess());
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "CraftBlockEntityState@" + getPosition().toShortString(), LOGGER
|
||||
)) {
|
||||
to.loadWithComponents(TagValueInput.create(problemReporter, this.getRegistryAccess(), tag));
|
||||
}
|
||||
}
|
||||
|
||||
// gets the wrapped BlockEntity
|
||||
@@ -143,13 +154,21 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
|
||||
// Paper start - properly save blockentity itemstacks
|
||||
public CompoundTag getSnapshotCustomNbtOnly() {
|
||||
this.applyTo(this.snapshot);
|
||||
final CompoundTag nbt = this.snapshot.saveCustomOnly(this.getRegistryAccess());
|
||||
this.snapshot.removeComponentsFromTag(nbt);
|
||||
if (!nbt.isEmpty()) {
|
||||
// have to include the "id" if it's going to have block entity data
|
||||
this.snapshot.saveId(nbt);
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "CraftBlockEntityState@" + getPosition().toShortString(), LOGGER
|
||||
)) {
|
||||
final TagValueOutput output = TagValueOutput.createWrappingWithContext(
|
||||
problemReporter,
|
||||
this.getRegistryAccess(),
|
||||
this.snapshot.saveCustomOnly(this.getRegistryAccess())
|
||||
);
|
||||
this.snapshot.removeComponentsFromTag(output);
|
||||
if (!output.isEmpty()) {
|
||||
// have to include the "id" if it's going to have block entity data
|
||||
this.snapshot.saveId(output);
|
||||
}
|
||||
return output.buildResult();
|
||||
}
|
||||
return nbt;
|
||||
}
|
||||
// Paper end
|
||||
|
||||
@@ -183,15 +202,14 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
|
||||
|
||||
@Override
|
||||
public boolean place(int flags) {
|
||||
if (super.place(flags)) {
|
||||
this.getWorldHandle().getBlockEntity(this.getPosition(), this.blockEntity.getType()).ifPresent(blockEntity -> {
|
||||
this.applyTo((T) blockEntity);
|
||||
blockEntity.setChanged();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
boolean result = super.place(flags);
|
||||
|
||||
return false;
|
||||
this.getWorldHandle().getBlockEntity(this.getPosition(), this.blockEntity.getType()).ifPresent(blockEntity -> {
|
||||
this.applyTo((T) blockEntity);
|
||||
blockEntity.setChanged();
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -85,7 +85,7 @@ public final class CraftBlockStates {
|
||||
|
||||
static {
|
||||
// Start generate - CraftBlockEntityStates
|
||||
// @GeneratedFrom 1.21.5
|
||||
// @GeneratedFrom 1.21.6-rc1
|
||||
register(BlockEntityType.BANNER, CraftBanner.class, CraftBanner::new);
|
||||
register(BlockEntityType.BARREL, CraftBarrel.class, CraftBarrel::new);
|
||||
register(BlockEntityType.BEACON, CraftBeacon.class, CraftBeacon::new);
|
||||
|
||||
@@ -2,7 +2,9 @@ package org.bukkit.craftbukkit.block;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import net.minecraft.Optionull;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.entity.EntityReference;
|
||||
import net.minecraft.world.level.block.entity.ConduitBlockEntity;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import org.bukkit.Location;
|
||||
@@ -83,7 +85,7 @@ public class CraftConduit extends CraftBlockEntityState<ConduitBlockEntity> impl
|
||||
return false;
|
||||
}
|
||||
|
||||
net.minecraft.world.entity.LivingEntity currentTarget = conduit.destroyTarget;
|
||||
EntityReference<net.minecraft.world.entity.LivingEntity> currentTarget = conduit.destroyTarget;
|
||||
|
||||
if (target == null) {
|
||||
if (currentTarget == null) {
|
||||
@@ -91,17 +93,22 @@ public class CraftConduit extends CraftBlockEntityState<ConduitBlockEntity> impl
|
||||
}
|
||||
|
||||
conduit.destroyTarget = null;
|
||||
conduit.destroyTargetUUID = null;
|
||||
} else {
|
||||
if (currentTarget != null && target.getUniqueId().equals(currentTarget.getUUID())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
conduit.destroyTarget = ((CraftLivingEntity) target).getHandle();
|
||||
conduit.destroyTargetUUID = target.getUniqueId();
|
||||
conduit.destroyTarget = new EntityReference<>(((CraftLivingEntity) target).getHandle());
|
||||
}
|
||||
|
||||
ConduitBlockEntity.updateDestroyTarget(conduit.getLevel(), this.getPosition(), this.data, conduit.effectBlocks, conduit, false);
|
||||
ConduitBlockEntity.updateAndAttackTarget(
|
||||
conduit.getLevel().getMinecraftWorld(),
|
||||
this.getPosition(),
|
||||
this.data,
|
||||
conduit,
|
||||
conduit.effectBlocks.size() >= ConduitBlockEntity.MIN_KILL_SIZE,
|
||||
false
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -112,14 +119,17 @@ public class CraftConduit extends CraftBlockEntityState<ConduitBlockEntity> impl
|
||||
return null;
|
||||
}
|
||||
|
||||
net.minecraft.world.entity.LivingEntity nmsEntity = conduit.destroyTarget;
|
||||
return (nmsEntity != null) ? (LivingEntity) nmsEntity.getBukkitEntity() : null;
|
||||
final net.minecraft.world.entity.LivingEntity nmsEntity = EntityReference.get(conduit.destroyTarget, this.getWorldHandle().getMinecraftWorld(), net.minecraft.world.entity.LivingEntity.class);
|
||||
return nmsEntity == null ? null : nmsEntity.getBukkitLivingEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTarget() {
|
||||
ConduitBlockEntity conduit = (ConduitBlockEntity) this.getBlockEntityFromWorld();
|
||||
return conduit != null && conduit.destroyTarget != null && conduit.destroyTarget.isAlive();
|
||||
if (conduit == null) return false;
|
||||
|
||||
final net.minecraft.world.entity.LivingEntity destroyTarget = EntityReference.get(conduit.destroyTarget, this.getWorldHandle().getMinecraftWorld(), net.minecraft.world.entity.LivingEntity.class);
|
||||
return destroyTarget != null && destroyTarget.isAlive();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -8,8 +8,10 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.InclusiveRange;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.util.random.Weighted;
|
||||
import net.minecraft.util.random.WeightedList;
|
||||
@@ -17,6 +19,8 @@ import net.minecraft.world.entity.EquipmentTable;
|
||||
import net.minecraft.world.level.BaseSpawner;
|
||||
import net.minecraft.world.level.SpawnData;
|
||||
import net.minecraft.world.level.block.entity.SpawnerBlockEntity;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import net.minecraft.world.level.storage.ValueInput;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.CreatureSpawner;
|
||||
@@ -46,8 +50,11 @@ public class CraftCreatureSpawner extends CraftBlockEntityState<SpawnerBlockEnti
|
||||
return null;
|
||||
}
|
||||
|
||||
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(spawnData.getEntityToSpawn());
|
||||
return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
|
||||
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(() -> "spawner@" + getLocation(), LOGGER)) {
|
||||
ValueInput valueInput = TagValueInput.create(scopedCollector, this.getInternalWorld().registryAccess(), spawnData.entityToSpawn());
|
||||
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(valueInput);
|
||||
return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -175,9 +182,12 @@ public class CraftCreatureSpawner extends CraftBlockEntityState<SpawnerBlockEnti
|
||||
if (spawnData == null) {
|
||||
return null;
|
||||
}
|
||||
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(() -> "spawner@" + getLocation(), LOGGER)) {
|
||||
ValueInput valueInput = TagValueInput.create(scopedCollector, this.getInternalWorld().registryAccess(), spawnData.getEntityToSpawn());
|
||||
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(valueInput);
|
||||
|
||||
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(spawnData.getEntityToSpawn());
|
||||
return type.map(CraftEntityType::minecraftToBukkit).map(CraftEntityType::bukkitToString).orElse(null);
|
||||
return type.map(CraftEntityType::minecraftToBukkit).map(CraftEntityType::bukkitToString).orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -46,8 +46,8 @@ public abstract class CraftFurnace<T extends AbstractFurnaceBlockEntity> extends
|
||||
@Override
|
||||
public void setBurnTime(short burnTime) {
|
||||
this.getSnapshot().litTimeRemaining = burnTime;
|
||||
// SPIGOT-844: Allow lighting and relighting using this API
|
||||
this.data = this.data.setValue(AbstractFurnaceBlock.LIT, burnTime > 0);
|
||||
this.data = this.data.trySetValue(AbstractFurnaceBlock.LIT, burnTime > 0);
|
||||
// only try, block data might have changed to something different that would not allow this property
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.util.UUID;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.world.level.block.TrialSpawnerBlock;
|
||||
import net.minecraft.world.level.block.entity.TrialSpawnerBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData;
|
||||
import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerStateData;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
@@ -23,8 +23,8 @@ public class CraftTrialSpawner extends CraftBlockEntityState<TrialSpawnerBlockEn
|
||||
|
||||
public CraftTrialSpawner(World world, TrialSpawnerBlockEntity blockEntity) {
|
||||
super(world, blockEntity);
|
||||
this.normalConfig = new CraftTrialSpawnerConfiguration(blockEntity.getTrialSpawner().getNormalConfig(), this.getSnapshot());
|
||||
this.ominousConfig = new CraftTrialSpawnerConfiguration(blockEntity.getTrialSpawner().getOminousConfig(), this.getSnapshot());
|
||||
this.normalConfig = new CraftTrialSpawnerConfiguration(blockEntity.getTrialSpawner().normalConfig(), this.getSnapshot());
|
||||
this.ominousConfig = new CraftTrialSpawnerConfiguration(blockEntity.getTrialSpawner().ominousConfig(), this.getSnapshot());
|
||||
}
|
||||
|
||||
protected CraftTrialSpawner(CraftTrialSpawner state, Location location) {
|
||||
@@ -35,22 +35,22 @@ public class CraftTrialSpawner extends CraftBlockEntityState<TrialSpawnerBlockEn
|
||||
|
||||
@Override
|
||||
public long getCooldownEnd() {
|
||||
return this.getSnapshot().trialSpawner.getData().cooldownEndsAt;
|
||||
return this.getSnapshot().trialSpawner.getStateData().cooldownEndsAt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCooldownEnd(long ticks) {
|
||||
this.getSnapshot().trialSpawner.getData().cooldownEndsAt = ticks;
|
||||
this.getSnapshot().trialSpawner.getStateData().cooldownEndsAt = ticks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNextSpawnAttempt() {
|
||||
return this.getSnapshot().trialSpawner.getData().nextMobSpawnsAt;
|
||||
return this.getSnapshot().trialSpawner.getStateData().nextMobSpawnsAt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNextSpawnAttempt(long ticks) {
|
||||
this.getSnapshot().trialSpawner.getData().nextMobSpawnsAt = ticks;
|
||||
this.getSnapshot().trialSpawner.getStateData().nextMobSpawnsAt = ticks;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -60,17 +60,17 @@ public class CraftTrialSpawner extends CraftBlockEntityState<TrialSpawnerBlockEn
|
||||
|
||||
@Override
|
||||
public void setCooldownLength(int ticks) {
|
||||
this.getSnapshot().trialSpawner.targetCooldownLength = ticks;
|
||||
this.getSnapshot().trialSpawner.config = this.getSnapshot().trialSpawner.config.overrideTargetCooldownLength(ticks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRequiredPlayerRange() {
|
||||
return this.getSnapshot().trialSpawner.getRequiredPlayerRange();
|
||||
return this.getSnapshot().trialSpawner.getRequiredPlayerRange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequiredPlayerRange(int requiredPlayerRange) {
|
||||
this.getSnapshot().trialSpawner.requiredPlayerRange = requiredPlayerRange;
|
||||
this.getSnapshot().trialSpawner.config = this.getSnapshot().trialSpawner.config.overrideRequiredPlayerRange(requiredPlayerRange);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -160,24 +160,26 @@ public class CraftTrialSpawner extends CraftBlockEntityState<TrialSpawnerBlockEn
|
||||
|
||||
@Override
|
||||
public TrialSpawnerConfiguration getNormalConfiguration() {
|
||||
return this.normalConfig;
|
||||
return this.normalConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrialSpawnerConfiguration getOminousConfiguration() {
|
||||
return this.ominousConfig;
|
||||
return this.ominousConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyTo(TrialSpawnerBlockEntity blockEntity) {
|
||||
super.applyTo(blockEntity);
|
||||
|
||||
blockEntity.trialSpawner.normalConfig = Holder.direct(this.normalConfig.toMinecraft());
|
||||
blockEntity.trialSpawner.ominousConfig = Holder.direct(this.ominousConfig.toMinecraft());
|
||||
blockEntity.trialSpawner.config = blockEntity.trialSpawner.config.overrideConfigs(
|
||||
Holder.direct(this.normalConfig.toMinecraft()),
|
||||
Holder.direct(this.ominousConfig.toMinecraft())
|
||||
);
|
||||
}
|
||||
|
||||
private TrialSpawnerData getTrialData() {
|
||||
return this.getSnapshot().getTrialSpawner().getData();
|
||||
private TrialSpawnerStateData getTrialData() {
|
||||
return this.getSnapshot().getTrialSpawner().getStateData();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7,16 +7,20 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.util.random.Weighted;
|
||||
import net.minecraft.util.random.WeightedList;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.SpawnData;
|
||||
import net.minecraft.world.level.block.entity.TrialSpawnerBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerConfig;
|
||||
import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData;
|
||||
import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerStateData;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import net.minecraft.world.level.storage.TagValueOutput;
|
||||
import org.bukkit.block.spawner.SpawnRule;
|
||||
import org.bukkit.block.spawner.SpawnerEntry;
|
||||
import org.bukkit.craftbukkit.CraftLootTable;
|
||||
@@ -26,8 +30,12 @@ import org.bukkit.entity.EntitySnapshot;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.loot.LootTable;
|
||||
import org.bukkit.spawner.TrialSpawnerConfiguration;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private final TrialSpawnerBlockEntity snapshot;
|
||||
|
||||
private int spawnRange;
|
||||
@@ -56,12 +64,21 @@ public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration
|
||||
|
||||
@Override
|
||||
public EntityType getSpawnedType() {
|
||||
if (this.spawnPotentialsDefinition.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (this.spawnPotentialsDefinition.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(this.spawnPotentialsDefinition.unwrap().get(0).value().getEntityToSpawn());
|
||||
return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "TrialSpawnerConfiguration@" + snapshot.getBlockPos().toShortString(), LOGGER
|
||||
)) {
|
||||
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(
|
||||
TagValueInput.createGlobal(
|
||||
problemReporter,
|
||||
this.spawnPotentialsDefinition.unwrap().getFirst().value().getEntityToSpawn()
|
||||
)
|
||||
);
|
||||
return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -74,7 +91,7 @@ public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration
|
||||
Preconditions.checkArgument(entityType != EntityType.UNKNOWN, "Can't spawn EntityType %s from mob spawners!", entityType);
|
||||
|
||||
SpawnData data = new SpawnData();
|
||||
data.getEntityToSpawn().putString(Entity.ID_TAG, BuiltInRegistries.ENTITY_TYPE.getKey(CraftEntityType.bukkitToMinecraft(entityType)).toString());
|
||||
data.getEntityToSpawn().putString(Entity.TAG_ID, BuiltInRegistries.ENTITY_TYPE.getKey(CraftEntityType.bukkitToMinecraft(entityType)).toString());
|
||||
this.getTrialData().nextSpawnData = Optional.of(data);
|
||||
this.spawnPotentialsDefinition = WeightedList.of(data);
|
||||
}
|
||||
@@ -121,7 +138,7 @@ public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration
|
||||
|
||||
@Override
|
||||
public int getDelay() {
|
||||
return this.ticksBetweenSpawn;
|
||||
return this.ticksBetweenSpawn;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -287,16 +304,16 @@ public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration
|
||||
|
||||
@Override
|
||||
public int getRequiredPlayerRange() {
|
||||
return this.snapshot.trialSpawner.getRequiredPlayerRange();
|
||||
return this.snapshot.trialSpawner.getRequiredPlayerRange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequiredPlayerRange(int requiredPlayerRange) {
|
||||
this.snapshot.trialSpawner.requiredPlayerRange = requiredPlayerRange;
|
||||
this.snapshot.trialSpawner.config = this.snapshot.trialSpawner.config.overrideRequiredPlayerRange(requiredPlayerRange);
|
||||
}
|
||||
|
||||
private TrialSpawnerData getTrialData() {
|
||||
return this.snapshot.getTrialSpawner().getData();
|
||||
private TrialSpawnerStateData getTrialData() {
|
||||
return this.snapshot.getTrialSpawner().getStateData();
|
||||
}
|
||||
|
||||
protected TrialSpawnerConfig toMinecraft() {
|
||||
|
||||
@@ -362,7 +362,7 @@ public class CraftBlockData implements BlockData {
|
||||
static {
|
||||
//<editor-fold desc="CraftBlockData Registration" defaultstate="collapsed">
|
||||
// Start generate - CraftBlockData#MAP
|
||||
// @GeneratedFrom 1.21.5
|
||||
// @GeneratedFrom 1.21.6-rc1
|
||||
register(net.minecraft.world.level.block.AmethystClusterBlock.class, org.bukkit.craftbukkit.block.impl.CraftAmethystCluster::new);
|
||||
register(net.minecraft.world.level.block.AnvilBlock.class, org.bukkit.craftbukkit.block.impl.CraftAnvil::new);
|
||||
register(net.minecraft.world.level.block.AttachedStemBlock.class, org.bukkit.craftbukkit.block.impl.CraftAttachedStem::new);
|
||||
@@ -418,6 +418,7 @@ public class CraftBlockData implements BlockData {
|
||||
register(net.minecraft.world.level.block.DispenserBlock.class, org.bukkit.craftbukkit.block.impl.CraftDispenser::new);
|
||||
register(net.minecraft.world.level.block.DoorBlock.class, org.bukkit.craftbukkit.block.impl.CraftDoor::new);
|
||||
register(net.minecraft.world.level.block.DoublePlantBlock.class, org.bukkit.craftbukkit.block.impl.CraftDoublePlant::new);
|
||||
register(net.minecraft.world.level.block.DriedGhastBlock.class, org.bukkit.craftbukkit.block.impl.CraftDriedGhast::new);
|
||||
register(net.minecraft.world.level.block.DropperBlock.class, org.bukkit.craftbukkit.block.impl.CraftDropper::new);
|
||||
register(net.minecraft.world.level.block.EndPortalFrameBlock.class, org.bukkit.craftbukkit.block.impl.CraftEndPortalFrame::new);
|
||||
register(net.minecraft.world.level.block.EndRodBlock.class, org.bukkit.craftbukkit.block.impl.CraftEndRod::new);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.Optionull;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityReference;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Projectile;
|
||||
|
||||
@@ -76,7 +79,7 @@ public abstract class AbstractProjectile extends CraftEntity implements Projecti
|
||||
|
||||
@Override
|
||||
public java.util.UUID getOwnerUniqueId() {
|
||||
return this.getHandle().ownerUUID;
|
||||
return Optionull.map(this.getHandle().owner, EntityReference::getUUID);
|
||||
}
|
||||
// Paper end - More projectile API
|
||||
}
|
||||
|
||||
@@ -139,7 +139,11 @@ public abstract class CraftAbstractHorse extends CraftAnimals implements Abstrac
|
||||
|
||||
@Override
|
||||
public void setRearing(boolean rearing) {
|
||||
this.getHandle().setForceStanding(rearing);
|
||||
if (rearing) {
|
||||
this.getHandle().setStanding(Integer.MAX_VALUE);
|
||||
} else {
|
||||
this.getHandle().clearStanding();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,6 +2,8 @@ package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.Optionull;
|
||||
import net.minecraft.world.entity.EntityReference;
|
||||
import net.minecraft.world.entity.animal.Animal;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
@@ -22,12 +24,12 @@ public class CraftAnimals extends CraftAgeable implements Animals {
|
||||
|
||||
@Override
|
||||
public UUID getBreedCause() {
|
||||
return this.getHandle().loveCause;
|
||||
return Optionull.map(this.getHandle().loveCause, EntityReference::getUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBreedCause(UUID uuid) {
|
||||
this.getHandle().loveCause = uuid;
|
||||
this.getHandle().loveCause = uuid == null ? null : new EntityReference<>(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,9 +3,11 @@ package org.bukkit.craftbukkit.entity;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.Optionull;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.world.effect.MobEffect;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.entity.EntityReference;
|
||||
import net.minecraft.world.item.alchemy.PotionContents;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Particle;
|
||||
@@ -115,7 +117,7 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud
|
||||
|
||||
@Override
|
||||
public <T> void setParticle(Particle particle, T data) {
|
||||
this.getHandle().setParticle(CraftParticle.createParticleParam(particle, data));
|
||||
this.getHandle().setCustomParticle(CraftParticle.createParticleParam(particle, data));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -226,13 +228,12 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud
|
||||
// Paper start - owner API
|
||||
@Override
|
||||
public java.util.UUID getOwnerUniqueId() {
|
||||
return this.getHandle().ownerUUID;
|
||||
return Optionull.map(this.getHandle().owner, EntityReference::getUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOwnerUniqueId(final java.util.UUID ownerUuid) {
|
||||
this.getHandle().setOwner(null);
|
||||
this.getHandle().ownerUUID = ownerUuid;
|
||||
this.getHandle().owner = ownerUuid == null ? null : new EntityReference<>(ownerUuid);
|
||||
}
|
||||
// Paper end
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ public class CraftArmadillo extends CraftAnimals implements Armadillo {
|
||||
|
||||
@Override
|
||||
public State getState() {
|
||||
return CraftArmadillo.stateToBukkit(this.getHandle().getState());
|
||||
return State.valueOf(this.getHandle().getState().name());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -37,22 +37,4 @@ public class CraftArmadillo extends CraftAnimals implements Armadillo {
|
||||
this.getHandle().lastHurtByMob = null; // Clear this memory to not have the sensor trigger rollUp instantly for damaged armadillo
|
||||
this.getHandle().getBrain().setMemoryWithExpiry(MemoryModuleType.DANGER_DETECTED_RECENTLY, true, ArmadilloState.UNROLLING.animationDuration());
|
||||
}
|
||||
|
||||
public static State stateToBukkit(ArmadilloState state) {
|
||||
return switch (state) {
|
||||
case IDLE -> State.IDLE;
|
||||
case ROLLING -> State.ROLLING;
|
||||
case SCARED -> State.SCARED;
|
||||
case UNROLLING -> State.UNROLLING;
|
||||
};
|
||||
}
|
||||
|
||||
public static ArmadilloState stateToNMS(State state) {
|
||||
return switch (state) {
|
||||
case State.IDLE -> ArmadilloState.IDLE;
|
||||
case State.ROLLING -> ArmadilloState.ROLLING;
|
||||
case State.SCARED -> ArmadilloState.SCARED;
|
||||
case State.UNROLLING -> ArmadilloState.UNROLLING;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public EulerAngle getBodyPose() {
|
||||
return CraftArmorStand.fromNMS(this.getHandle().bodyPose);
|
||||
return CraftArmorStand.fromNMS(this.getHandle().getBodyPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,7 +82,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public EulerAngle getLeftArmPose() {
|
||||
return CraftArmorStand.fromNMS(this.getHandle().leftArmPose);
|
||||
return CraftArmorStand.fromNMS(this.getHandle().getLeftArmPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -92,7 +92,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public EulerAngle getRightArmPose() {
|
||||
return CraftArmorStand.fromNMS(this.getHandle().rightArmPose);
|
||||
return CraftArmorStand.fromNMS(this.getHandle().getRightArmPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,7 +102,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public EulerAngle getLeftLegPose() {
|
||||
return CraftArmorStand.fromNMS(this.getHandle().leftLegPose);
|
||||
return CraftArmorStand.fromNMS(this.getHandle().getLeftLegPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -112,7 +112,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public EulerAngle getRightLegPose() {
|
||||
return CraftArmorStand.fromNMS(this.getHandle().rightLegPose);
|
||||
return CraftArmorStand.fromNMS(this.getHandle().getRightLegPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,7 +122,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public EulerAngle getHeadPose() {
|
||||
return CraftArmorStand.fromNMS(this.getHandle().headPose);
|
||||
return CraftArmorStand.fromNMS(this.getHandle().getHeadPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -293,7 +293,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public io.papermc.paper.math.Rotations getBodyRotations() {
|
||||
return fromNMSRotations(this.getHandle().bodyPose);
|
||||
return fromNMSRotations(this.getHandle().getBodyPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -303,7 +303,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public io.papermc.paper.math.Rotations getLeftArmRotations() {
|
||||
return fromNMSRotations(this.getHandle().leftArmPose);
|
||||
return fromNMSRotations(this.getHandle().getLeftArmPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -313,7 +313,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public io.papermc.paper.math.Rotations getRightArmRotations() {
|
||||
return fromNMSRotations(this.getHandle().rightArmPose);
|
||||
return fromNMSRotations(this.getHandle().getRightArmPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -323,7 +323,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public io.papermc.paper.math.Rotations getLeftLegRotations() {
|
||||
return fromNMSRotations(this.getHandle().leftLegPose);
|
||||
return fromNMSRotations(this.getHandle().getLeftLegPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -333,7 +333,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public io.papermc.paper.math.Rotations getRightLegRotations() {
|
||||
return fromNMSRotations(this.getHandle().rightLegPose);
|
||||
return fromNMSRotations(this.getHandle().getRightLegPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -343,7 +343,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public io.papermc.paper.math.Rotations getHeadRotations() {
|
||||
return fromNMSRotations(this.getHandle().headPose);
|
||||
return fromNMSRotations(this.getHandle().getHeadPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.minecraft.Optionull;
|
||||
import net.minecraft.world.entity.projectile.EyeOfEnder;
|
||||
import net.minecraft.world.item.Items;
|
||||
import org.bukkit.Location;
|
||||
@@ -22,7 +23,7 @@ public class CraftEnderSignal extends CraftEntity implements EnderSignal {
|
||||
|
||||
@Override
|
||||
public Location getTargetLocation() {
|
||||
return new Location(this.getWorld(), this.getHandle().tx, this.getHandle().ty, this.getHandle().tz, this.getHandle().getYRot(), this.getHandle().getXRot());
|
||||
return Optionull.map(this.getHandle().target, target -> CraftLocation.toBukkit(target, this.getWorld(), this.getHandle().getYRot(), this.getHandle().getXRot()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -35,7 +36,7 @@ public class CraftEnderSignal extends CraftEntity implements EnderSignal {
|
||||
public void setTargetLocation(Location location, boolean update) {
|
||||
// Paper end - Change EnderEye target without changing other things
|
||||
Preconditions.checkArgument(this.getWorld().equals(location.getWorld()), "Cannot target EnderSignal across worlds");
|
||||
this.getHandle().signalTo(CraftLocation.toBlockPosition(location), update); // Paper - Change EnderEye target without changing other things
|
||||
this.getHandle().signalTo(CraftLocation.toVec3(location), update); // Paper - Change EnderEye target without changing other things
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import io.papermc.paper.datacomponent.DataComponentType;
|
||||
import io.papermc.paper.entity.TeleportFlag;
|
||||
import java.util.HashSet;
|
||||
@@ -15,7 +16,6 @@ import io.papermc.paper.entity.LookAnchor;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import net.kyori.adventure.util.TriState;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
@@ -24,12 +24,16 @@ import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.level.TicketType;
|
||||
import net.minecraft.server.network.ServerPlayerConnection;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntitySpawnReason;
|
||||
import net.minecraft.world.entity.boss.EnderDragonPart;
|
||||
import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
|
||||
import net.minecraft.world.entity.projectile.AbstractArrow;
|
||||
import net.minecraft.world.level.portal.TeleportTransition;
|
||||
import net.minecraft.world.level.storage.TagValueOutput;
|
||||
import net.minecraft.world.level.storage.ValueInput;
|
||||
import net.minecraft.world.level.storage.ValueOutput;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.EntityEffect;
|
||||
@@ -73,8 +77,12 @@ import org.bukkit.util.Vector;
|
||||
import net.md_5.bungee.api.chat.BaseComponent; // Spigot
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private static PermissibleBase perm;
|
||||
private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry();
|
||||
|
||||
@@ -979,12 +987,19 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
|
||||
@Override
|
||||
public String getAsString() {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
if (!this.getHandle().saveAsPassenger(tag, false, true, true)) {
|
||||
return null;
|
||||
}
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "Entity#toString", LOGGER
|
||||
)) {
|
||||
final TagValueOutput output = TagValueOutput.createWithContext(
|
||||
problemReporter,
|
||||
this.getHandle().registryAccess()
|
||||
);
|
||||
if (!this.getHandle().saveAsPassenger(output, false, true, true)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return tag.toString();
|
||||
return output.buildResult().toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1012,32 +1027,40 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
}
|
||||
|
||||
private Entity copy(net.minecraft.world.level.Level level) {
|
||||
CompoundTag compoundTag = new CompoundTag();
|
||||
this.getHandle().saveAsPassenger(compoundTag, false, true, true);
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "Entity#copy", LOGGER
|
||||
)) {
|
||||
final TagValueOutput output = TagValueOutput.createWithContext(problemReporter, level.registryAccess());
|
||||
this.getHandle().saveAsPassenger(output, false, true, true);
|
||||
|
||||
return net.minecraft.world.entity.EntityType.loadEntityRecursive(compoundTag, level, EntitySpawnReason.LOAD, java.util.function.Function.identity());
|
||||
return net.minecraft.world.entity.EntityType.loadEntityRecursive(output.buildResult(), level, EntitySpawnReason.LOAD, java.util.function.Function.identity());
|
||||
}
|
||||
}
|
||||
|
||||
public void storeBukkitValues(CompoundTag c) {
|
||||
public void storeBukkitValues(ValueOutput output) {
|
||||
if (!this.persistentDataContainer.isEmpty()) {
|
||||
c.put("BukkitValues", this.persistentDataContainer.toTagCompound());
|
||||
output.store("BukkitValues", CompoundTag.CODEC, this.persistentDataContainer.toTagCompound());
|
||||
}
|
||||
}
|
||||
|
||||
public void readBukkitValues(CompoundTag c) {
|
||||
Tag base = c.get("BukkitValues");
|
||||
if (base instanceof CompoundTag) {
|
||||
this.persistentDataContainer.putAll((CompoundTag) base);
|
||||
}
|
||||
public void readBukkitValues(ValueInput input) {
|
||||
input.read("BukkitValues", CompoundTag.CODEC).ifPresent(this.persistentDataContainer::putAll);
|
||||
}
|
||||
|
||||
protected CompoundTag save() {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "Entity#save", LOGGER
|
||||
)) {
|
||||
final TagValueOutput tagValueOutput = TagValueOutput.createWithContext(
|
||||
problemReporter,
|
||||
this.getHandle().registryAccess()
|
||||
);
|
||||
|
||||
tag.putString(Entity.ID_TAG, this.getHandle().getEncodeId()); // todo NPE?
|
||||
this.getHandle().saveWithoutId(tag);
|
||||
tagValueOutput.putString(Entity.TAG_ID, this.getHandle().getEncodeId(true));
|
||||
this.getHandle().saveWithoutId(tagValueOutput);
|
||||
|
||||
return tag;
|
||||
return tagValueOutput.buildResult();
|
||||
}
|
||||
}
|
||||
|
||||
// re-sends the spawn entity packet to updated values which cannot be updated otherwise
|
||||
|
||||
@@ -2,14 +2,19 @@ package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.TagParser;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import org.bukkit.entity.EntityFactory;
|
||||
import org.bukkit.entity.EntitySnapshot;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class CraftEntityFactory implements EntityFactory {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final CraftEntityFactory instance;
|
||||
|
||||
static {
|
||||
@@ -30,7 +35,12 @@ public class CraftEntityFactory implements EntityFactory {
|
||||
throw new IllegalArgumentException("Could not parse Entity: " + input, e);
|
||||
}
|
||||
|
||||
EntityType<?> type = EntityType.by(tag).orElse(null);
|
||||
final EntityType<?> type;
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "createEntitySnapshot", LOGGER
|
||||
)) {
|
||||
type = EntityType.by(TagValueInput.createGlobal(problemReporter, tag)).orElse(null);
|
||||
}
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("Could not parse Entity: " + input);
|
||||
}
|
||||
|
||||
@@ -2,16 +2,25 @@ package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.util.function.Function;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.entity.EntitySpawnReason;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import net.minecraft.world.level.storage.TagValueOutput;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntitySnapshot;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class CraftEntitySnapshot implements EntitySnapshot {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private final CompoundTag data;
|
||||
private final EntityType type;
|
||||
|
||||
@@ -55,7 +64,11 @@ public class CraftEntitySnapshot implements EntitySnapshot {
|
||||
}
|
||||
|
||||
Preconditions.checkArgument(internal != null, "Error creating new entity."); // This should only fail if the stored CompoundTag is malformed.
|
||||
internal.load(this.data);
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "EntitySnapshot#createEntity", LOGGER
|
||||
)) {
|
||||
internal.load(TagValueInput.createGlobal(problemReporter, this.data));
|
||||
}
|
||||
|
||||
return internal;
|
||||
}
|
||||
@@ -65,12 +78,19 @@ public class CraftEntitySnapshot implements EntitySnapshot {
|
||||
}
|
||||
|
||||
public static CraftEntitySnapshot create(CraftEntity entity) {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
if (!entity.getHandle().saveAsPassenger(tag, false, false, false)) {
|
||||
return null;
|
||||
}
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "create@" + entity.getUniqueId(), LOGGER
|
||||
)) {
|
||||
final TagValueOutput output = TagValueOutput.createWithContext(
|
||||
problemReporter,
|
||||
CraftRegistry.getMinecraftRegistry()
|
||||
);
|
||||
if (!entity.getHandle().saveAsPassenger(output, false, false, false)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new CraftEntitySnapshot(tag, entity.getType());
|
||||
return new CraftEntitySnapshot(output.buildResult(), entity.getType());
|
||||
}
|
||||
}
|
||||
|
||||
public static CraftEntitySnapshot create(CompoundTag tag, EntityType type) {
|
||||
@@ -82,7 +102,13 @@ public class CraftEntitySnapshot implements EntitySnapshot {
|
||||
}
|
||||
|
||||
public static CraftEntitySnapshot create(CompoundTag tag) {
|
||||
EntityType type = net.minecraft.world.entity.EntityType.by(tag).map(CraftEntityType::minecraftToBukkit).orElse(null);
|
||||
return CraftEntitySnapshot.create(tag, type);
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "create", LOGGER
|
||||
)) {
|
||||
EntityType type = net.minecraft.world.entity.EntityType.by(
|
||||
TagValueInput.createGlobal(problemReporter, tag)
|
||||
).map(CraftEntityType::minecraftToBukkit).orElse(null);
|
||||
return CraftEntitySnapshot.create(tag, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@ import org.bukkit.entity.GlowSquid;
|
||||
import org.bukkit.entity.Goat;
|
||||
import org.bukkit.entity.Guardian;
|
||||
import org.bukkit.entity.Hanging;
|
||||
import org.bukkit.entity.HappyGhast;
|
||||
import org.bukkit.entity.Hoglin;
|
||||
import org.bukkit.entity.Horse;
|
||||
import org.bukkit.entity.Husk;
|
||||
@@ -352,6 +353,7 @@ public final class CraftEntityTypes {
|
||||
register(new EntityTypeData<>(EntityType.BREEZE, Breeze.class, CraftBreeze::new, createLiving(net.minecraft.world.entity.EntityType.BREEZE)));
|
||||
register(new EntityTypeData<>(EntityType.ARMADILLO, Armadillo.class, CraftArmadillo::new, createLiving(net.minecraft.world.entity.EntityType.ARMADILLO)));
|
||||
register(new EntityTypeData<>(EntityType.CREAKING, Creaking.class, CraftCreaking::new, createLiving(net.minecraft.world.entity.EntityType.CREAKING)));
|
||||
register(new EntityTypeData<>(EntityType.HAPPY_GHAST, HappyGhast.class, CraftHappyGhast::new, createLiving(net.minecraft.world.entity.EntityType.HAPPY_GHAST)));
|
||||
|
||||
Function<SpawnData, net.minecraft.world.entity.boss.enderdragon.EnderDragon> dragonFunction = createLiving(net.minecraft.world.entity.EntityType.ENDER_DRAGON);
|
||||
register(new EntityTypeData<>(EntityType.ENDER_DRAGON, EnderDragon.class, CraftEnderDragon::new, spawnData -> {
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.world.entity.FlyingMob;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Flying;
|
||||
|
||||
public class CraftFlying extends CraftMob implements Flying {
|
||||
|
||||
public CraftFlying(CraftServer server, FlyingMob entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlyingMob getHandle() {
|
||||
return (FlyingMob) this.entity;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package org.bukkit.craftbukkit.entity;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Ghast;
|
||||
|
||||
public class CraftGhast extends CraftFlying implements Ghast, CraftEnemy {
|
||||
public class CraftGhast extends CraftMob implements Ghast, CraftEnemy {
|
||||
|
||||
public CraftGhast(CraftServer server, net.minecraft.world.entity.monster.Ghast entity) {
|
||||
super(server, entity);
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.HappyGhast;
|
||||
|
||||
public class CraftHappyGhast extends CraftAnimals implements HappyGhast {
|
||||
public CraftHappyGhast(final CraftServer server, final net.minecraft.world.entity.animal.HappyGhast entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -18,11 +19,13 @@ import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket;
|
||||
import net.minecraft.network.protocol.game.ServerboundContainerClosePacket;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntitySpawnReason;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.HumanoidArm;
|
||||
import net.minecraft.world.entity.TamableAnimal;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.projectile.FireworkRocketEntity;
|
||||
@@ -38,6 +41,7 @@ import net.minecraft.world.level.block.BedBlock;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@@ -78,9 +82,11 @@ import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private CraftInventoryPlayer inventory;
|
||||
private final CraftInventory enderChest;
|
||||
protected final PermissibleBase perm = new PermissibleBase(this);
|
||||
@@ -175,7 +181,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
return null;
|
||||
}
|
||||
|
||||
net.minecraft.server.level.ServerLevel level = ((ServerPlayer) this.getHandle()).server.getLevel(respawnConfig.dimension());
|
||||
net.minecraft.server.level.ServerLevel level = ((ServerPlayer) this.getHandle()).getServer().getLevel(respawnConfig.dimension());
|
||||
if (level == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -769,8 +775,13 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity getShoulderEntityLeft() {
|
||||
if (!this.getHandle().getShoulderEntityLeft().isEmpty()) {
|
||||
Optional<Entity> shoulder = EntityType.create(this.getHandle().getShoulderEntityLeft(), this.getHandle().level(), EntitySpawnReason.LOAD);
|
||||
return shoulder.map(Entity::getBukkitEntity).orElse(null);
|
||||
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(this.getHandle().problemPath(), LOGGER)) {
|
||||
return EntityType.create(
|
||||
TagValueInput.create(scopedCollector.forChild(() -> ".shoulder"), this.getHandle().registryAccess(), this.getHandle().getShoulderEntityLeft()),
|
||||
this.getHandle().level(),
|
||||
EntitySpawnReason.LOAD
|
||||
).map(Entity::getBukkitEntity).orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -778,6 +789,9 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
|
||||
@Override
|
||||
public void setShoulderEntityLeft(org.bukkit.entity.Entity entity) {
|
||||
if (entity != null) {
|
||||
Preconditions.checkArgument(((CraftEntity) entity).getHandle().getType().canSerialize(), "Cannot set entity of type %s as a shoulder entity", entity.getType().getKey());
|
||||
}
|
||||
this.getHandle().setShoulderEntityLeft(entity == null ? new CompoundTag() : ((CraftEntity) entity).save());
|
||||
if (entity != null) {
|
||||
entity.remove();
|
||||
@@ -787,8 +801,13 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity getShoulderEntityRight() {
|
||||
if (!this.getHandle().getShoulderEntityRight().isEmpty()) {
|
||||
Optional<Entity> shoulder = EntityType.create(this.getHandle().getShoulderEntityRight(), this.getHandle().level(), EntitySpawnReason.LOAD);
|
||||
return shoulder.map(Entity::getBukkitEntity).orElse(null);
|
||||
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(this.getHandle().problemPath(), LOGGER)) {
|
||||
return EntityType.create(
|
||||
TagValueInput.create(scopedCollector.forChild(() -> ".shoulder"), this.getHandle().registryAccess(), this.getHandle().getShoulderEntityRight()),
|
||||
this.getHandle().level(),
|
||||
EntitySpawnReason.LOAD
|
||||
).map(Entity::getBukkitEntity).orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -796,6 +815,9 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
|
||||
@Override
|
||||
public void setShoulderEntityRight(org.bukkit.entity.Entity entity) {
|
||||
if (entity != null) {
|
||||
Preconditions.checkArgument(((CraftEntity) entity).getHandle().getType().canSerialize(), "Cannot set entity of type %s as a shoulder entity", entity.getType().getKey());
|
||||
}
|
||||
this.getHandle().setShoulderEntityRight(entity == null ? new CompoundTag() : ((CraftEntity) entity).save());
|
||||
if (entity != null) {
|
||||
entity.remove();
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import java.util.UUID;
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.Optionull;
|
||||
import net.minecraft.world.entity.EntityReference;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
@@ -136,11 +138,11 @@ public class CraftItem extends CraftEntity implements Item {
|
||||
|
||||
@Override
|
||||
public void setThrower(UUID uuid) {
|
||||
this.getHandle().thrower = uuid;
|
||||
this.getHandle().thrower = uuid == null ? null : new EntityReference<>(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getThrower() {
|
||||
return this.getHandle().thrower;
|
||||
return Optionull.map(this.getHandle().thrower, EntityReference::getUUID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,12 @@ import com.google.common.base.Preconditions;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.util.random.WeightedList;
|
||||
import net.minecraft.world.entity.vehicle.MinecartSpawner;
|
||||
import net.minecraft.world.level.SpawnData;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import org.bukkit.block.spawner.SpawnRule;
|
||||
import org.bukkit.block.spawner.SpawnerEntry;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
@@ -34,8 +36,14 @@ public class CraftMinecartMobSpawner extends CraftMinecart implements SpawnerMin
|
||||
return null;
|
||||
}
|
||||
|
||||
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(spawnData.getEntityToSpawn());
|
||||
return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "getSpawnedType@" + this.getUniqueId(), LOGGER
|
||||
)) {
|
||||
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(
|
||||
TagValueInput.create(problemReporter, getHandle().registryAccess(), spawnData.getEntityToSpawn())
|
||||
);
|
||||
return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7,7 +7,7 @@ import org.bukkit.craftbukkit.util.CraftLocation;
|
||||
import org.bukkit.entity.Phantom;
|
||||
import java.util.UUID;
|
||||
|
||||
public class CraftPhantom extends CraftFlying implements Phantom, CraftEnemy {
|
||||
public class CraftPhantom extends CraftMob implements Phantom, CraftEnemy {
|
||||
|
||||
public CraftPhantom(CraftServer server, net.minecraft.world.entity.monster.Phantom entity) {
|
||||
super(server, entity);
|
||||
@@ -50,7 +50,6 @@ public class CraftPhantom extends CraftFlying implements Phantom, CraftEnemy {
|
||||
|
||||
@Override
|
||||
public void setAnchorLocation(Location location) {
|
||||
com.google.common.base.Preconditions.checkArgument(location != null, "location cannot be null");
|
||||
this.getHandle().anchorPoint = location == null ? null : CraftLocation.toBlockPosition(location);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@ import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import net.minecraft.server.players.UserWhiteListEntry;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
@@ -120,6 +121,8 @@ import net.minecraft.world.level.border.BorderChangeListener;
|
||||
import net.minecraft.world.level.saveddata.maps.MapDecoration;
|
||||
import net.minecraft.world.level.saveddata.maps.MapId;
|
||||
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
|
||||
import net.minecraft.world.level.storage.ValueInput;
|
||||
import net.minecraft.world.level.storage.ValueOutput;
|
||||
import org.bukkit.BanEntry;
|
||||
import org.bukkit.BanList;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -1530,7 +1533,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
@Override
|
||||
public void loadData() {
|
||||
this.server.getHandle().playerIo.load(this.getHandle());
|
||||
this.server.getHandle().playerIo.load(this.getHandle(), ProblemReporter.DISCARDING);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1560,7 +1563,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
final ServerPlayer.RespawnConfig respawnConfig = this.getHandle().getRespawnConfig();
|
||||
if (respawnConfig == null) return null;
|
||||
|
||||
final ServerLevel world = this.getHandle().server.getLevel(respawnConfig.dimension());
|
||||
final ServerLevel world = this.getHandle().getServer().getLevel(respawnConfig.dimension());
|
||||
if (world == null) return null;
|
||||
|
||||
if (!loadLocationAndValidate) {
|
||||
@@ -1885,7 +1888,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
orb.setPosRaw(handle.getX(), handle.getY(), handle.getZ());
|
||||
|
||||
final int possibleDurabilityFromXp = net.minecraft.world.item.enchantment.EnchantmentHelper.modifyDurabilityToRepairFromXp(
|
||||
handle.serverLevel(), itemstack, amount
|
||||
handle.level(), itemstack, amount
|
||||
);
|
||||
int i = Math.min(possibleDurabilityFromXp, itemstack.getDamageValue());
|
||||
final int consumedExperience = i > 0 ? i * amount / possibleDurabilityFromXp : possibleDurabilityFromXp; // Paper - taken from ExperienceOrb#repairPlayerItems + prevent division by 0
|
||||
@@ -2234,11 +2237,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
ServerGamePacketListenerImpl connection = handle.connection;
|
||||
|
||||
// Respawn the player then update their position and selected slot
|
||||
ServerLevel level = handle.serverLevel();
|
||||
ServerLevel level = handle.level();
|
||||
connection.send(new net.minecraft.network.protocol.game.ClientboundRespawnPacket(handle.createCommonSpawnInfo(level), net.minecraft.network.protocol.game.ClientboundRespawnPacket.KEEP_ALL_DATA));
|
||||
handle.onUpdateAbilities();
|
||||
connection.internalTeleport(net.minecraft.world.entity.PositionMoveRotation.of(this.getHandle()), java.util.Collections.emptySet());
|
||||
net.minecraft.server.players.PlayerList playerList = handle.server.getPlayerList();
|
||||
net.minecraft.server.players.PlayerList playerList = handle.getServer().getPlayerList();
|
||||
playerList.sendPlayerPermissionLevel(handle, false);
|
||||
playerList.sendLevelInfo(handle, level);
|
||||
playerList.sendAllPlayerInfo(handle);
|
||||
@@ -2351,9 +2354,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
// Paper end - getLastPlayed replacement API
|
||||
|
||||
public void readExtraData(CompoundTag tag) {
|
||||
public void readExtraData(ValueInput input) {
|
||||
this.hasPlayedBefore = true;
|
||||
tag.getCompound("bukkit").ifPresent(data -> {
|
||||
input.child("bukkit").ifPresent(data -> {
|
||||
this.firstPlayed = data.getLongOr("firstPlayed", 0);
|
||||
this.lastPlayed = data.getLongOr("lastPlayed", 0);
|
||||
|
||||
@@ -2366,14 +2369,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
});
|
||||
}
|
||||
|
||||
public void setExtraData(CompoundTag tag) {
|
||||
public void setExtraData(ValueOutput output) {
|
||||
this.lastSaveTime = System.currentTimeMillis(); // Paper
|
||||
|
||||
if (!tag.contains("bukkit")) {
|
||||
tag.put("bukkit", new CompoundTag());
|
||||
}
|
||||
|
||||
CompoundTag data = tag.getCompoundOrEmpty("bukkit");
|
||||
ValueOutput data = output.child("bukkit");
|
||||
ServerPlayer handle = this.getHandle();
|
||||
data.putInt("newExp", handle.newExp);
|
||||
data.putInt("newTotalExp", handle.newTotalExp);
|
||||
@@ -2385,11 +2384,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
data.putString("lastKnownName", handle.getScoreboardName());
|
||||
|
||||
// Paper start - persist for use in offline save data
|
||||
if (!tag.contains("Paper")) {
|
||||
tag.put("Paper", new CompoundTag());
|
||||
}
|
||||
|
||||
CompoundTag paper = tag.getCompoundOrEmpty("Paper");
|
||||
ValueOutput paper = output.child("Paper");
|
||||
paper.putLong("LastLogin", handle.loginTime);
|
||||
paper.putLong("LastSeen", System.currentTimeMillis());
|
||||
// Paper end
|
||||
@@ -3016,7 +3011,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
public void updateCommands() {
|
||||
if (this.getHandle().connection == null) return;
|
||||
|
||||
this.getHandle().server.getCommands().sendCommands(this.getHandle());
|
||||
this.getHandle().getServer().getCommands().sendCommands(this.getHandle());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.world.entity.EntityReference;
|
||||
import net.minecraft.world.entity.item.PrimedTnt;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Entity;
|
||||
@@ -57,7 +58,7 @@ public class CraftTNTPrimed extends CraftEntity implements TNTPrimed {
|
||||
@Override
|
||||
public void setSource(Entity source) {
|
||||
if (source instanceof LivingEntity) {
|
||||
this.getHandle().owner = ((CraftLivingEntity) source).getHandle();
|
||||
this.getHandle().owner = new EntityReference<>(((CraftLivingEntity) source).getHandle());
|
||||
} else {
|
||||
this.getHandle().owner = null;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.entity.EntityReference;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.util.CraftLocation;
|
||||
@@ -20,13 +21,13 @@ public class CraftVex extends CraftMonster implements Vex {
|
||||
|
||||
@Override
|
||||
public org.bukkit.entity.Mob getSummoner() {
|
||||
net.minecraft.world.entity.Mob owner = getHandle().getOwner();
|
||||
net.minecraft.world.entity.Mob owner = this.getHandle().getOwner();
|
||||
return owner != null ? (org.bukkit.entity.Mob) owner.getBukkitEntity() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSummoner(org.bukkit.entity.Mob summoner) {
|
||||
getHandle().setOwner(summoner == null ? null : ((CraftMob) summoner).getHandle());
|
||||
this.getHandle().owner = summoner == null ? null : new EntityReference<>(((CraftMob) summoner).getHandle());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,6 +27,7 @@ import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.damagesource.DamageTypes;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.Leashable;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.animal.AbstractFish;
|
||||
import net.minecraft.world.entity.animal.AbstractGolem;
|
||||
@@ -881,7 +882,7 @@ public class CraftEventFactory {
|
||||
public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, DamageSource damageSource, List<Entity.DefaultDrop> drops, net.kyori.adventure.text.Component deathMessage, boolean showDeathMessages, boolean keepInventory) {
|
||||
CraftPlayer entity = victim.getBukkitEntity();
|
||||
CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
|
||||
PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(victim.serverLevel(), damageSource.getEntity()), 0, deathMessage, showDeathMessages);
|
||||
PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(victim.level(), damageSource.getEntity()), 0, deathMessage, showDeathMessages);
|
||||
event.setKeepInventory(keepInventory);
|
||||
event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel
|
||||
populateFields(victim, event); // Paper - make cancellable
|
||||
@@ -1490,10 +1491,56 @@ public class CraftEventFactory {
|
||||
Bukkit.getPluginManager().callEvent(new PlayerRecipeBookSettingsChangeEvent(player.getBukkitEntity(), bukkitType, open, filter));
|
||||
}
|
||||
|
||||
public static PlayerUnleashEntityEvent callPlayerUnleashEntityEvent(Entity entity, net.minecraft.world.entity.player.Player player, InteractionHand hand, boolean dropLeash) {
|
||||
public static boolean handlePlayerUnleashEntityEvent(
|
||||
final Leashable leashable,
|
||||
final net.minecraft.world.entity.player.@Nullable Player player,
|
||||
final @Nullable InteractionHand hand,
|
||||
final boolean dropLeash,
|
||||
final boolean resendState
|
||||
) {
|
||||
if (!(leashable instanceof final Entity entity)) return true;
|
||||
return handlePlayerUnleashEntityEvent(entity, player, hand, dropLeash, resendState);
|
||||
}
|
||||
|
||||
public static boolean handlePlayerUnleashEntityEvent(
|
||||
final Entity entity,
|
||||
final net.minecraft.world.entity.player.@Nullable Player player,
|
||||
final @Nullable InteractionHand hand,
|
||||
final boolean dropLeash,
|
||||
final boolean resendState
|
||||
) {
|
||||
if (player == null || hand == null) {
|
||||
if (entity instanceof final Leashable leashable) {
|
||||
if (dropLeash) leashable.dropLeash();
|
||||
else leashable.removeLeash();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
PlayerUnleashEntityEvent event = new PlayerUnleashEntityEvent(entity.getBukkitEntity(), (Player) player.getBukkitEntity(), CraftEquipmentSlot.getHand(hand), dropLeash);
|
||||
entity.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
return event;
|
||||
if (event.isCancelled()) {
|
||||
if (resendState && entity instanceof final Leashable leashable) {
|
||||
((ServerPlayer) player).connection.send(new net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket(entity, leashable.getLeashHolder()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entity instanceof final Leashable leashable) {
|
||||
if (event.isDropLeash()) leashable.dropLeash();
|
||||
else leashable.removeLeash();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean handlePlayerLeashEntityEvent(Leashable leashed, Entity leashHolder, net.minecraft.world.entity.player.Player player, InteractionHand hand) {
|
||||
if (!(leashed instanceof final Entity leashedEntity)) return false;
|
||||
return callPlayerLeashEntityEvent(leashedEntity, leashHolder, player, hand).callEvent();
|
||||
}
|
||||
|
||||
public static @Nullable PlayerLeashEntityEvent callPlayerLeashEntityEvent(Leashable leashed, Entity leashHolder, net.minecraft.world.entity.player.Player player, InteractionHand hand) {
|
||||
if (!(leashed instanceof final Entity leashedEntity)) return null;
|
||||
return callPlayerLeashEntityEvent(leashedEntity, leashHolder, player, hand);
|
||||
}
|
||||
|
||||
public static PlayerLeashEntityEvent callPlayerLeashEntityEvent(Entity entity, Entity leashHolder, net.minecraft.world.entity.player.Player player, InteractionHand hand) {
|
||||
|
||||
@@ -7,9 +7,11 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Consumer;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.entity.EntitySpawnReason;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
@@ -17,6 +19,7 @@ import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import org.bukkit.HeightMap;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@@ -30,9 +33,12 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.generator.LimitedRegion;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRegion {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private final WeakReference<WorldGenLevel> weakAccess;
|
||||
private final int centerChunkX;
|
||||
private final int centerChunkZ;
|
||||
@@ -271,7 +277,16 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe
|
||||
if (!state.getBlockData().matches(getHandle().getBlockState(pos).createCraftBlockData())) {
|
||||
throw new IllegalArgumentException("BlockData does not match! Expected " + state.getBlockData().getAsString(false) + ", got " + getHandle().getBlockState(pos).createCraftBlockData().getAsString(false));
|
||||
}
|
||||
getHandle().getBlockEntity(pos).loadWithComponents(((org.bukkit.craftbukkit.block.CraftBlockEntityState<?>) state).getSnapshotNBT(), this.getHandle().registryAccess());
|
||||
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "CraftLimitedRegion@" + pos.toShortString(), LOGGER
|
||||
)) {
|
||||
getHandle().getBlockEntity(pos).loadWithComponents(TagValueInput.create(
|
||||
problemReporter,
|
||||
this.getHandle().registryAccess(),
|
||||
((org.bukkit.craftbukkit.block.CraftBlockEntityState<?>) state).getSnapshotNBT()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,12 +20,12 @@ public class CraftInventoryAbstractHorse extends CraftInventory implements Abstr
|
||||
|
||||
@Override
|
||||
public ItemStack getSaddle() {
|
||||
return this.getItem(HorseInventoryMenu.SLOT_SADDLE); // Paper
|
||||
return this.getItem(HorseInventoryMenu.SLOT_SADDLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSaddle(ItemStack stack) {
|
||||
this.setItem(HorseInventoryMenu.SLOT_SADDLE, stack); // Paper
|
||||
this.setItem(HorseInventoryMenu.SLOT_SADDLE, stack);
|
||||
}
|
||||
|
||||
public Container getMainInventory() {
|
||||
@@ -88,14 +88,17 @@ public class CraftInventoryAbstractHorse extends CraftInventory implements Abstr
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(final int index) {
|
||||
if (index == HorseInventoryMenu.SLOT_BODY_ARMOR) {
|
||||
final net.minecraft.world.item.ItemStack item = this.getArmorInventory().getItem(0);
|
||||
return item.isEmpty() ? null : CraftItemStack.asCraftMirror(item);
|
||||
} else if (index == HorseInventoryMenu.SLOT_SADDLE) {
|
||||
if (index == HorseInventoryMenu.SLOT_SADDLE) {
|
||||
final net.minecraft.world.item.ItemStack item = this.getSaddleInventory().getItem(0);
|
||||
return item.isEmpty() ? null : CraftItemStack.asCraftMirror(item);
|
||||
} else if (index == HorseInventoryMenu.SLOT_BODY_ARMOR) {
|
||||
final net.minecraft.world.item.ItemStack item = this.getArmorInventory().getItem(0);
|
||||
return item.isEmpty() ? null : CraftItemStack.asCraftMirror(item);
|
||||
} else {
|
||||
int shiftedIndex = index;
|
||||
if (index > HorseInventoryMenu.SLOT_SADDLE) {
|
||||
shiftedIndex--;
|
||||
}
|
||||
if (index > HorseInventoryMenu.SLOT_BODY_ARMOR) {
|
||||
shiftedIndex--;
|
||||
}
|
||||
@@ -107,16 +110,16 @@ public class CraftInventoryAbstractHorse extends CraftInventory implements Abstr
|
||||
|
||||
@Override
|
||||
public void setItem(final int index, final ItemStack item) {
|
||||
if (index == HorseInventoryMenu.SLOT_BODY_ARMOR) {
|
||||
this.getArmorInventory().setItem(0, CraftItemStack.asNMSCopy(item));
|
||||
} else if (index == HorseInventoryMenu.SLOT_SADDLE) {
|
||||
if (index == HorseInventoryMenu.SLOT_SADDLE) {
|
||||
this.getSaddleInventory().setItem(0, CraftItemStack.asNMSCopy(item));
|
||||
} else if (index == HorseInventoryMenu.SLOT_BODY_ARMOR) {
|
||||
this.getArmorInventory().setItem(0, CraftItemStack.asNMSCopy(item));
|
||||
} else {
|
||||
int shiftedIndex = index;
|
||||
if (index > HorseInventoryMenu.SLOT_BODY_ARMOR) {
|
||||
if (index > HorseInventoryMenu.SLOT_SADDLE) {
|
||||
shiftedIndex--;
|
||||
}
|
||||
if (index > HorseInventoryMenu.SLOT_SADDLE) {
|
||||
if (index > HorseInventoryMenu.SLOT_BODY_ARMOR) {
|
||||
shiftedIndex--;
|
||||
}
|
||||
this.getMainInventory().setItem(shiftedIndex, CraftItemStack.asNMSCopy(item));
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.google.common.base.Preconditions;
|
||||
import java.util.List;
|
||||
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetHeldSlotPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetPlayerInventoryPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
||||
@@ -71,14 +72,25 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i
|
||||
@Override
|
||||
public void setItem(int index, ItemStack item) {
|
||||
// Paper start - Validate setItem index
|
||||
if (index < 0 || index > 40) {
|
||||
throw new ArrayIndexOutOfBoundsException("Index must be between 0 and 40");
|
||||
if (index < 0 || index > 42) {
|
||||
throw new ArrayIndexOutOfBoundsException("Index must be between 0 and 42");
|
||||
}
|
||||
// Paper end - Validate setItem index
|
||||
super.setItem(index, item);
|
||||
if (this.getHolder() == null) return;
|
||||
|
||||
ServerPlayer player = ((CraftPlayer) this.getHolder()).getHandle();
|
||||
if (player.connection == null) return;
|
||||
// Of course, these are not part of the player inventory "menu" because these slots are not accessible.
|
||||
// However they are technically part of the player inventory.
|
||||
// This is a poor representation by this API, but basically instead send a player inventory update packet.
|
||||
// This will allow updates to the player inventory rather than through the menu.
|
||||
// TODO: This could be something worth cleaning up in the future.
|
||||
if (index > 40) {
|
||||
player.connection.send(new ClientboundSetPlayerInventoryPacket(index, CraftItemStack.asNMSCopy(item)));
|
||||
return;
|
||||
}
|
||||
|
||||
// PacketPlayOutSetSlot places the items differently than setItem()
|
||||
//
|
||||
// Between, and including, index 9 (the first index outside of the hotbar) and index 35 (the last index before
|
||||
@@ -123,11 +135,8 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i
|
||||
|
||||
switch (slot) {
|
||||
case HAND -> this.setItemInMainHand(item);
|
||||
case OFF_HAND, FEET, LEGS, CHEST, HEAD ->
|
||||
case OFF_HAND, FEET, LEGS, CHEST, HEAD, BODY, SADDLE ->
|
||||
this.getInventory().equipment.set(CraftEquipmentSlot.getNMS(slot), CraftItemStack.asNMSCopy(item));
|
||||
case BODY -> throw new IllegalArgumentException("BODY is not valid for players!"); // Paper end
|
||||
default ->
|
||||
throw new IllegalArgumentException("Could not set slot " + slot + " - not a valid slot for PlayerInventory");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,10 +151,7 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i
|
||||
|
||||
return switch (slot) {
|
||||
case HAND -> this.getItemInMainHand();
|
||||
case OFF_HAND, FEET, LEGS, CHEST, HEAD -> CraftItemStack.asCraftMirror(this.getInventory().equipment.get(CraftEquipmentSlot.getNMS(slot)));
|
||||
case BODY -> throw new IllegalArgumentException("BODY is not valid for players!");
|
||||
default ->
|
||||
throw new IllegalArgumentException("Could not get slot " + slot + " - not a valid slot for PlayerInventory");
|
||||
case OFF_HAND, FEET, LEGS, CHEST, HEAD, BODY, SADDLE -> CraftItemStack.asCraftMirror(this.getInventory().equipment.get(CraftEquipmentSlot.getNMS(slot)));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -253,12 +259,12 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i
|
||||
|
||||
@Override
|
||||
public ItemStack[] getExtraContents() {
|
||||
return this.asCraftMirror(List.of(this.getInventory().equipment.get(net.minecraft.world.entity.EquipmentSlot.OFFHAND)));
|
||||
return this.asCraftMirror(this.getInventory().getExtraContent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExtraContents(ItemStack[] items) {
|
||||
this.setSlots(items, this.getInventory().getNonEquipmentItems().size() + this.getInventory().getArmorContents().size(), 1);
|
||||
this.setSlots(items, this.getInventory().getNonEquipmentItems().size() + this.getInventory().getArmorContents().size(), 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.google.common.base.Preconditions;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import java.util.Optional;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import net.minecraft.commands.arguments.item.ItemParser;
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
@@ -332,7 +333,7 @@ public final class CraftItemFactory implements ItemFactory {
|
||||
Optional.of(
|
||||
io.papermc.paper.registry.set.PaperRegistrySets.convertToNms(
|
||||
Registries.ENCHANTMENT,
|
||||
net.minecraft.server.MinecraftServer.getServer().registryAccess().createSerializationContext(net.minecraft.nbt.NbtOps.INSTANCE).lookupProvider,
|
||||
Conversions.global().lookup(),
|
||||
keySet
|
||||
)
|
||||
),
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.bukkit.craftbukkit.inventory;
|
||||
import com.destroystokyo.paper.inventory.meta.ArmorStandMeta;
|
||||
import java.util.function.BiFunction;
|
||||
import net.minecraft.world.item.BannerItem;
|
||||
import net.minecraft.world.item.BedItem;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.BundleItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
@@ -247,7 +248,8 @@ public final class CraftItemMetas {
|
||||
|| itemType == ItemType.SUSPICIOUS_GRAVEL || itemType == ItemType.CRAFTER
|
||||
|| itemType == ItemType.TRIAL_SPAWNER || itemType == ItemType.VAULT
|
||||
|| itemType == ItemType.CREAKING_HEART || itemType == ItemType.TEST_BLOCK
|
||||
|| itemType == ItemType.TEST_INSTANCE_BLOCK) {
|
||||
|| itemType == ItemType.TEST_INSTANCE_BLOCK || itemHandle instanceof BedItem
|
||||
|| itemType == ItemType.CONDUIT) {
|
||||
return CraftItemMetas.asType(CraftItemMetas.BLOCK_STATE_META_DATA);
|
||||
}
|
||||
if (itemType == ItemType.SHIELD) {
|
||||
|
||||
@@ -17,8 +17,10 @@ import net.minecraft.core.component.TypedDataComponent;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtOps;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.item.component.CustomData;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.storage.TagValueOutput;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockState;
|
||||
@@ -144,12 +146,17 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta
|
||||
final BlockVector legacyPosition = SerializableMeta.getObject(BlockVector.class, map, "blockPosition", true);
|
||||
if (legacyPosition != null) {
|
||||
this.blockEntityTag = this.blockEntityTag.update(blockEntityTag -> {
|
||||
if (blockEntityTag.isEmpty()) {
|
||||
BlockEntity.addEntityType(blockEntityTag, java.util.Objects.requireNonNull(CraftBlockStates.getBlockEntityType(this.materialForBlockEntityType())));
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "blockEntityTag", LOGGER
|
||||
)) {
|
||||
final TagValueOutput output = TagValueOutput.createWrappingWithContext(problemReporter, CraftRegistry.getMinecraftRegistry(), blockEntityTag);
|
||||
if (blockEntityTag.isEmpty()) {
|
||||
BlockEntity.addEntityType(output, java.util.Objects.requireNonNull(CraftBlockStates.getBlockEntityType(this.materialForBlockEntityType())));
|
||||
}
|
||||
output.putInt("x", legacyPosition.getBlockX());
|
||||
output.putInt("y", legacyPosition.getBlockY());
|
||||
output.putInt("z", legacyPosition.getBlockZ());
|
||||
}
|
||||
blockEntityTag.putInt("x", legacyPosition.getBlockX());
|
||||
blockEntityTag.putInt("y", legacyPosition.getBlockY());
|
||||
blockEntityTag.putInt("z", legacyPosition.getBlockZ());
|
||||
});
|
||||
}
|
||||
// Paper end - general item meta fixes - parse spigot legacy position and merge into block entity tag
|
||||
@@ -164,7 +171,14 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta
|
||||
final CompoundTag nbt = this.blockEntityTag.copyTag();
|
||||
if (!nbt.isEmpty()) {
|
||||
if (nbt.getString("id").isEmpty()) {
|
||||
BlockEntity.addEntityType(nbt, java.util.Objects.requireNonNull(CraftBlockStates.getBlockEntityType(this.materialForBlockEntityType())));
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "CraftMetaBlockState#apply", LOGGER
|
||||
)) {
|
||||
BlockEntity.addEntityType(
|
||||
TagValueOutput.createWrappingWithContext(problemReporter, CraftRegistry.getMinecraftRegistry(), nbt),
|
||||
java.util.Objects.requireNonNull(CraftBlockStates.getBlockEntityType(this.materialForBlockEntityType()))
|
||||
);
|
||||
}
|
||||
}
|
||||
tag.put(CraftMetaBlockState.BLOCK_ENTITY_TAG, CustomData.of(nbt));
|
||||
}
|
||||
|
||||
@@ -274,7 +274,6 @@ public class CraftMetaBookSigned extends CraftMetaItem implements BookMeta {
|
||||
return page > 0 && page <= this.getPageCount();
|
||||
}
|
||||
|
||||
// TODO Expose this attribute in Bukkit?
|
||||
public boolean isResolved() {
|
||||
return this.resolved;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.serialization.DynamicOps;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -37,8 +38,6 @@ import java.util.Optional;
|
||||
import java.util.SequencedSet;
|
||||
import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
@@ -131,6 +130,7 @@ import org.bukkit.inventory.meta.components.UseCooldownComponent;
|
||||
import org.bukkit.inventory.meta.tags.CustomItemTagContainer;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.tag.DamageTypeTags;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
/**
|
||||
* Children must include the following:
|
||||
@@ -158,6 +158,8 @@ import org.bukkit.tag.DamageTypeTags;
|
||||
// Important: ItemMeta needs to be the first interface see #applicableTo(Material)
|
||||
class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
|
||||
static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
static class ItemMetaKey {
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@@ -750,7 +752,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
CompoundTag internalTag = NbtIo.readCompressed(buf, NbtAccounter.unlimitedHeap());
|
||||
this.deserializeInternal(internalTag, map);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex);
|
||||
LOGGER.error("Failed to read internal tag from object", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -779,7 +781,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex);
|
||||
LOGGER.error("Failed to read unhandled tag for item", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -809,7 +811,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
try {
|
||||
this.customTag = NbtIo.readCompressed(buf, NbtAccounter.unlimitedHeap());
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex);
|
||||
LOGGER.error("Failed to read custom tag for item", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2238,7 +2240,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
NbtIo.writeCompressed(internal, buf);
|
||||
builder.put("internal", Base64.getEncoder().encodeToString(buf.toByteArray()));
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex);
|
||||
LOGGER.error("Failed to write internal tag for item", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2258,7 +2260,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
NbtIo.writeCompressed((CompoundTag) unhandled, buf);
|
||||
builder.put("unhandled", Base64.getEncoder().encodeToString(buf.toByteArray()));
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex);
|
||||
LOGGER.error("Failed to write unhandled tag for item", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2293,7 +2295,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
NbtIo.writeCompressed(this.customTag, buf);
|
||||
builder.put("custom", Base64.getEncoder().encodeToString(buf.toByteArray()));
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex);
|
||||
LOGGER.error("Failed to write custom tag for item", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -323,11 +323,11 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta {
|
||||
@Override
|
||||
@NotNull
|
||||
public Color computeEffectiveColor() {
|
||||
if (hasColor()) return getColor();
|
||||
if (this.hasColor()) return this.getColor();
|
||||
|
||||
return Color.fromRGB(
|
||||
PotionContents.getColorOptional(Collections2.transform(getAllEffects(), CraftPotionUtil::fromBukkit))
|
||||
.orElse(PotionContents.BASE_POTION_COLOR) & 0xFFFFFF
|
||||
.orElse(PotionContents.BASE_POTION_COLOR) & 0x00FFFFFF
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
@@ -74,7 +75,8 @@ public final class CraftEquippableComponent implements EquippableComponent {
|
||||
(dispensable != null) ? dispensable : true,
|
||||
(swappable != null) ? swappable : true,
|
||||
(damageOnHurt != null) ? damageOnHurt : true,
|
||||
(equipOnInteract != null) ? equipOnInteract : false
|
||||
(equipOnInteract != null) ? equipOnInteract : false,
|
||||
false, BuiltInRegistries.SOUND_EVENT.wrapAsHolder(SoundEvents.SHEARS_SNIP) // TODO - 1.21.6
|
||||
);
|
||||
}
|
||||
|
||||
@@ -115,7 +117,7 @@ public final class CraftEquippableComponent implements EquippableComponent {
|
||||
|
||||
@Override
|
||||
public void setSlot(EquipmentSlot slot) {
|
||||
this.handle = new Equippable(CraftEquipmentSlot.getNMS(slot), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract());
|
||||
this.handle = new Equippable(CraftEquipmentSlot.getNMS(slot), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -125,7 +127,7 @@ public final class CraftEquippableComponent implements EquippableComponent {
|
||||
|
||||
@Override
|
||||
public void setEquipSound(Sound sound) {
|
||||
this.handle = new Equippable(this.handle.slot(), (sound != null) ? CraftSound.bukkitToMinecraftHolder(sound) : SoundEvents.ARMOR_EQUIP_GENERIC, this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract());
|
||||
this.handle = new Equippable(this.handle.slot(), (sound != null) ? CraftSound.bukkitToMinecraftHolder(sound) : SoundEvents.ARMOR_EQUIP_GENERIC, this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -135,7 +137,7 @@ public final class CraftEquippableComponent implements EquippableComponent {
|
||||
|
||||
@Override
|
||||
public void setModel(NamespacedKey key) {
|
||||
this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), Optional.ofNullable(key).map(CraftNamespacedKey::toMinecraft).map((k) -> ResourceKey.create(EquipmentAssets.ROOT_ID, k)), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract());
|
||||
this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), Optional.ofNullable(key).map(CraftNamespacedKey::toMinecraft).map((k) -> ResourceKey.create(EquipmentAssets.ROOT_ID, k)), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -145,7 +147,7 @@ public final class CraftEquippableComponent implements EquippableComponent {
|
||||
|
||||
@Override
|
||||
public void setCameraOverlay(NamespacedKey key) {
|
||||
this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), Optional.ofNullable(key).map(CraftNamespacedKey::toMinecraft), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract());
|
||||
this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), Optional.ofNullable(key).map(CraftNamespacedKey::toMinecraft), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -157,7 +159,7 @@ public final class CraftEquippableComponent implements EquippableComponent {
|
||||
public void setAllowedEntities(EntityType entities) {
|
||||
this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(),
|
||||
(entities != null) ? Optional.of(HolderSet.direct(CraftEntityType.bukkitToMinecraftHolder(entities))) : Optional.empty(),
|
||||
this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract()
|
||||
this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -165,7 +167,7 @@ public final class CraftEquippableComponent implements EquippableComponent {
|
||||
public void setAllowedEntities(Collection<EntityType> entities) {
|
||||
this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(),
|
||||
(entities != null) ? Optional.of(HolderSet.direct(entities.stream().map(CraftEntityType::bukkitToMinecraftHolder).collect(Collectors.toList()))) : Optional.empty(),
|
||||
this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract()
|
||||
this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -175,7 +177,7 @@ public final class CraftEquippableComponent implements EquippableComponent {
|
||||
|
||||
this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(),
|
||||
(tag != null) ? Optional.of(((CraftEntityTag) tag).getHandle()) : Optional.empty(),
|
||||
this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract()
|
||||
this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -186,7 +188,7 @@ public final class CraftEquippableComponent implements EquippableComponent {
|
||||
|
||||
@Override
|
||||
public void setDispensable(boolean dispensable) {
|
||||
this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), dispensable, this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract());
|
||||
this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), dispensable, this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -196,7 +198,7 @@ public final class CraftEquippableComponent implements EquippableComponent {
|
||||
|
||||
@Override
|
||||
public void setSwappable(boolean swappable) {
|
||||
this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), swappable, this.handle.damageOnHurt(), this.handle.equipOnInteract());
|
||||
this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), swappable, this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -206,7 +208,7 @@ public final class CraftEquippableComponent implements EquippableComponent {
|
||||
|
||||
@Override
|
||||
public void setDamageOnHurt(boolean damage) {
|
||||
this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), damage, this.handle.equipOnInteract());
|
||||
this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), damage, this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -216,7 +218,7 @@ public final class CraftEquippableComponent implements EquippableComponent {
|
||||
|
||||
@Override
|
||||
public void setEquipOnInteract(final boolean equip) {
|
||||
this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), equip);
|
||||
this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), equip, this.handle.canBeSheared(), this.handle.shearingSound());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,7 +15,7 @@ public class CraftPotionUtil {
|
||||
|
||||
private static final BiMap<PotionType, PotionType> upgradeable = ImmutableBiMap.<PotionType, PotionType>builder()
|
||||
// Start generate - CraftPotionUtil#upgradeable
|
||||
// @GeneratedFrom 1.21.5
|
||||
// @GeneratedFrom 1.21.6-rc1
|
||||
.put(PotionType.HARMING, PotionType.STRONG_HARMING)
|
||||
.put(PotionType.HEALING, PotionType.STRONG_HEALING)
|
||||
.put(PotionType.LEAPING, PotionType.STRONG_LEAPING)
|
||||
@@ -29,7 +29,7 @@ public class CraftPotionUtil {
|
||||
.build();
|
||||
private static final BiMap<PotionType, PotionType> extendable = ImmutableBiMap.<PotionType, PotionType>builder()
|
||||
// Start generate - CraftPotionUtil#extendable
|
||||
// @GeneratedFrom 1.21.5
|
||||
// @GeneratedFrom 1.21.6-rc1
|
||||
.put(PotionType.FIRE_RESISTANCE, PotionType.LONG_FIRE_RESISTANCE)
|
||||
.put(PotionType.INVISIBILITY, PotionType.LONG_INVISIBILITY)
|
||||
.put(PotionType.LEAPING, PotionType.LONG_LEAPING)
|
||||
|
||||
@@ -2,29 +2,39 @@ package org.bukkit.craftbukkit.spawner;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.util.Optional;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.level.BaseSpawner;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.SpawnData;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.storage.TagValueOutput;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.spawner.Spawner;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
/**
|
||||
* A common parent interface for both the {@link org.bukkit.craftbukkit.block.CraftCreatureSpawner} and minecart mob spawner.
|
||||
*/
|
||||
public interface PaperSharedSpawnerLogic extends Spawner {
|
||||
|
||||
static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
BaseSpawner getSpawner();
|
||||
|
||||
Level getInternalWorld();
|
||||
|
||||
BlockPos getInternalPosition();
|
||||
|
||||
default boolean isActivated() {
|
||||
return this.getSpawner().isNearPlayer(this.getInternalWorld(), this.getInternalPosition());
|
||||
}
|
||||
@@ -41,16 +51,20 @@ public interface PaperSharedSpawnerLogic extends Spawner {
|
||||
Preconditions.checkArgument(itemStack != null && !itemStack.getType().isAir(), "spawners cannot spawn air");
|
||||
|
||||
final net.minecraft.world.item.ItemStack item = CraftItemStack.asNMSCopy(itemStack);
|
||||
final CompoundTag entity = new CompoundTag();
|
||||
entity.putString(Entity.ID_TAG, BuiltInRegistries.ENTITY_TYPE.getKey(EntityType.ITEM).toString());
|
||||
entity.put("Item", item.save(this.getInternalWorld().registryAccess()));
|
||||
|
||||
this.setNextSpawnData(
|
||||
new net.minecraft.world.level.SpawnData(
|
||||
entity,
|
||||
java.util.Optional.empty(),
|
||||
Optional.ofNullable(this.getSpawner().nextSpawnData).flatMap(SpawnData::equipment)
|
||||
)
|
||||
);
|
||||
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(() -> getSpawner().toString(), LOGGER)) {
|
||||
TagValueOutput tagValueOutput = TagValueOutput.createWithContext(scopedCollector, this.getInternalWorld().registryAccess());
|
||||
tagValueOutput.putString(Entity.TAG_ID, BuiltInRegistries.ENTITY_TYPE.getKey(EntityType.ITEM).toString());
|
||||
tagValueOutput.store("Item", net.minecraft.world.item.ItemStack.CODEC, item);
|
||||
|
||||
this.setNextSpawnData(
|
||||
new net.minecraft.world.level.SpawnData(
|
||||
tagValueOutput.buildResult(),
|
||||
java.util.Optional.empty(),
|
||||
Optional.ofNullable(this.getSpawner().nextSpawnData).flatMap(SpawnData::equipment)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,10 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.stream.Collectors;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.entity.EntitySpawnReason;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
@@ -19,6 +21,7 @@ import net.minecraft.world.level.block.Rotation;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.BlockRotProcessor;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.RegionAccessor;
|
||||
@@ -39,9 +42,12 @@ import org.bukkit.structure.Structure;
|
||||
import org.bukkit.util.BlockTransformer;
|
||||
import org.bukkit.util.BlockVector;
|
||||
import org.bukkit.util.EntityTransformer;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class CraftStructure implements Structure {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private final StructureTemplate structure;
|
||||
private final RegistryAccess registry;
|
||||
|
||||
@@ -121,7 +127,7 @@ public class CraftStructure implements Structure {
|
||||
Preconditions.checkArgument(size != null, "BlockVector size cannot be null");
|
||||
Preconditions.checkArgument(size.getBlockX() >= 1 && size.getBlockY() >= 1 && size.getBlockZ() >= 1, "Size must be at least 1x1x1 but was %sx%sx%s", size.getBlockX(), size.getBlockY(), size.getBlockZ());
|
||||
|
||||
this.structure.fillFromWorld(((CraftWorld) world).getHandle(), CraftLocation.toBlockPosition(origin), CraftBlockVector.toBlockPosition(size), includeEntities, Blocks.STRUCTURE_VOID);
|
||||
this.structure.fillFromWorld(((CraftWorld) world).getHandle(), CraftLocation.toBlockPosition(origin), CraftBlockVector.toBlockPosition(size), includeEntities, List.of(Blocks.STRUCTURE_VOID));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,10 +139,18 @@ public class CraftStructure implements Structure {
|
||||
public List<Entity> getEntities() {
|
||||
List<Entity> entities = new ArrayList<>();
|
||||
for (StructureTemplate.StructureEntityInfo entity : this.structure.entityInfoList) {
|
||||
EntityType.create(entity.nbt, ((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle(), EntitySpawnReason.STRUCTURE).ifPresent(dummyEntity -> {
|
||||
dummyEntity.setPos(entity.pos.x, entity.pos.y, entity.pos.z);
|
||||
entities.add(dummyEntity.getBukkitEntity());
|
||||
});
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "entity@" + entity.pos, LOGGER
|
||||
)) {
|
||||
EntityType.create(
|
||||
TagValueInput.createGlobal(problemReporter, entity.nbt),
|
||||
((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle(),
|
||||
EntitySpawnReason.STRUCTURE
|
||||
).ifPresent(dummyEntity -> {
|
||||
dummyEntity.setPos(entity.pos.x, entity.pos.y, entity.pos.z);
|
||||
entities.add(dummyEntity.getBukkitEntity());
|
||||
});
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableList(entities);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ public final class ApiVersion implements Comparable<ApiVersion>, Serializable {
|
||||
|
||||
static {
|
||||
versions = new HashMap<>();
|
||||
CURRENT = getOrCreateVersion("1.21.5");
|
||||
CURRENT = getOrCreateVersion("1.21.6");
|
||||
FLATTENING = getOrCreateVersion("1.13");
|
||||
FIELD_NAME_PARITY = getOrCreateVersion("1.20.5");
|
||||
ABSTRACT_COW = getOrCreateVersion("1.21.5");
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.bukkit.craftbukkit.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -11,6 +10,7 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.block.EntityBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
@@ -18,84 +18,86 @@ import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.storage.LevelData;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.craftbukkit.block.CraftBlock;
|
||||
import org.bukkit.craftbukkit.block.CraftBlockEntityState;
|
||||
import org.bukkit.craftbukkit.block.CraftBlockState;
|
||||
import org.bukkit.craftbukkit.block.CraftBlockStates;
|
||||
|
||||
public class BlockStateListPopulator extends DummyGeneratorAccess {
|
||||
private final LevelAccessor world;
|
||||
private final Map<BlockPos, net.minecraft.world.level.block.state.BlockState> dataMap = new HashMap<>();
|
||||
private final Map<BlockPos, BlockEntity> entityMap = new HashMap<>();
|
||||
private final LinkedHashMap<BlockPos, CraftBlockState> blocks;
|
||||
|
||||
public BlockStateListPopulator(LevelAccessor world) {
|
||||
this(world, new LinkedHashMap<>());
|
||||
}
|
||||
private final LevelAccessor level;
|
||||
private final Map<BlockPos, CapturedBlock> blocks = new LinkedHashMap<>();
|
||||
|
||||
private BlockStateListPopulator(LevelAccessor world, LinkedHashMap<BlockPos, CraftBlockState> blocks) {
|
||||
this.world = world;
|
||||
this.blocks = blocks;
|
||||
private List<CraftBlockState> snapshots;
|
||||
|
||||
public BlockStateListPopulator(LevelAccessor level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.world.level.block.state.BlockState getBlockState(BlockPos pos) {
|
||||
net.minecraft.world.level.block.state.BlockState state = this.dataMap.get(pos);
|
||||
return (state != null) ? state : this.world.getBlockState(pos);
|
||||
CapturedBlock block = this.blocks.get(pos);
|
||||
return block != null ? block.state() : this.level.getBlockState(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidState getFluidState(BlockPos pos) {
|
||||
net.minecraft.world.level.block.state.BlockState state = this.dataMap.get(pos);
|
||||
return (state != null) ? state.getFluidState() : this.world.getFluidState(pos);
|
||||
CapturedBlock block = this.blocks.get(pos);
|
||||
return block != null ? block.state().getFluidState() : this.level.getFluidState(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity getBlockEntity(BlockPos pos) {
|
||||
// The contains is important to check for null values
|
||||
if (this.entityMap.containsKey(pos)) {
|
||||
return this.entityMap.get(pos);
|
||||
}
|
||||
|
||||
return this.world.getBlockEntity(pos);
|
||||
CapturedBlock block = this.blocks.get(pos);
|
||||
return block != null ? block.blockEntity() : this.level.getBlockEntity(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(BlockPos pos, net.minecraft.world.level.block.state.BlockState state, int flags, int recursionLeft) {
|
||||
pos = pos.immutable();
|
||||
// remove first to keep insertion order
|
||||
// remove first to keep last updated order
|
||||
this.blocks.remove(pos);
|
||||
|
||||
this.dataMap.put(pos, state);
|
||||
if (state.hasBlockEntity()) {
|
||||
this.entityMap.put(pos, ((EntityBlock) state.getBlock()).newBlockEntity(pos, state));
|
||||
final BlockEntity newBlockEntity;
|
||||
if (state.getBlock() instanceof EntityBlock entityBlock) {
|
||||
// based on LevelChunk#setBlockState
|
||||
BlockEntity currentBlockEntity = this.getBlockEntity(pos);
|
||||
if (currentBlockEntity != null && currentBlockEntity.isValidBlockState(state)) {
|
||||
newBlockEntity = currentBlockEntity; // previous block entity is still valid for this block state
|
||||
currentBlockEntity.setBlockState(state);
|
||||
} else {
|
||||
newBlockEntity = entityBlock.newBlockEntity(pos, state); // create a new one when the block change
|
||||
}
|
||||
} else {
|
||||
this.entityMap.put(pos, null);
|
||||
newBlockEntity = null;
|
||||
}
|
||||
|
||||
// use 'this' to ensure that the block state is the correct TileState
|
||||
CraftBlockState snapshot = (CraftBlockState) CraftBlock.at(this, pos).getState();
|
||||
snapshot.setFlags(flags);
|
||||
// set world handle to ensure that updated calls are done to the world and not to this populator
|
||||
snapshot.setWorldHandle(this.world);
|
||||
this.blocks.put(pos, snapshot);
|
||||
this.blocks.put(pos, new CapturedBlock(state, flags, newBlockEntity));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean destroyBlock(BlockPos pos, boolean dropBlock, Entity entity, int recursionLeft) {
|
||||
net.minecraft.world.level.block.state.BlockState blockState = this.getBlockState(pos);
|
||||
if (blockState.isAir()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.setBlock(pos, blockState.getFluidState().createLegacyBlock(), 3, recursionLeft); // capture block without the event
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerLevel getMinecraftWorld() {
|
||||
return this.world.getMinecraftWorld();
|
||||
return this.level.getMinecraftWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerLevel getLevel() {
|
||||
return this.getMinecraftWorld();
|
||||
}
|
||||
|
||||
public void refreshTiles() {
|
||||
for (CraftBlockState snapshot : this.blocks.values()) {
|
||||
if (snapshot instanceof CraftBlockEntityState) {
|
||||
((CraftBlockEntityState<?>) snapshot).refreshSnapshot();
|
||||
}
|
||||
private void iterateSnapshots(Consumer<CraftBlockState> callback) {
|
||||
for (Map.Entry<BlockPos, CapturedBlock> entry : this.blocks.entrySet()) {
|
||||
CapturedBlock block = entry.getValue();
|
||||
CraftBlockState snapshot = CraftBlockStates.getBlockState(
|
||||
this.getMinecraftWorld().getWorld(), entry.getKey(), block.state(), block.blockEntity()
|
||||
);
|
||||
snapshot.setFlags(block.flags());
|
||||
callback.accept(snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,27 +114,38 @@ public class BlockStateListPopulator extends DummyGeneratorAccess {
|
||||
}
|
||||
|
||||
public void placeSomeBlocks(Consumer<? super CraftBlockState> beforeRun, Predicate<? super BlockState> filter) {
|
||||
for (CraftBlockState state : this.blocks.values()) {
|
||||
if (filter.test(state)) {
|
||||
beforeRun.accept(state);
|
||||
state.place(state.getFlags());
|
||||
for (CraftBlockState snapshot : this.getSnapshotBlocks()) {
|
||||
if (filter.test(snapshot)) {
|
||||
beforeRun.accept(snapshot);
|
||||
snapshot.place(snapshot.getFlags());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<CraftBlockState> getSnapshotBlocks() {
|
||||
return new ArrayList<>(this.blocks.values());
|
||||
if (this.snapshots == null) {
|
||||
List<CraftBlockState> snapshots = new ArrayList<>();
|
||||
this.iterateSnapshots(snapshots::add);
|
||||
this.snapshots = snapshots;
|
||||
}
|
||||
return snapshots;
|
||||
}
|
||||
|
||||
// For tree generation
|
||||
|
||||
@Override
|
||||
public ServerLevel getLevel() {
|
||||
return this.getMinecraftWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinY() {
|
||||
return this.world.getMinY();
|
||||
return this.level.getMinY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return this.world.getHeight();
|
||||
return this.level.getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -147,29 +160,29 @@ public class BlockStateListPopulator extends DummyGeneratorAccess {
|
||||
|
||||
@Override
|
||||
public DimensionType dimensionType() {
|
||||
return this.world.dimensionType();
|
||||
return this.level.dimensionType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegistryAccess registryAccess() {
|
||||
return this.world.registryAccess();
|
||||
return this.level.registryAccess();
|
||||
}
|
||||
|
||||
// Needed when a tree generates in water
|
||||
@Override
|
||||
public LevelData getLevelData() {
|
||||
return this.world.getLevelData();
|
||||
return this.level.getLevelData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long nextSubTickCount() {
|
||||
return this.world.nextSubTickCount();
|
||||
return this.level.nextSubTickCount();
|
||||
}
|
||||
|
||||
// SPIGOT-7966: Needed for some tree generations
|
||||
@Override
|
||||
public RandomSource getRandom() {
|
||||
return this.world.getRandom();
|
||||
return this.level.getRandom();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -179,22 +192,22 @@ public class BlockStateListPopulator extends DummyGeneratorAccess {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getHeightmapPos(net.minecraft.world.level.levelgen.Heightmap.Types heightmap, BlockPos pos) {
|
||||
return this.world.getHeightmapPos(heightmap, pos);
|
||||
public BlockPos getHeightmapPos(net.minecraft.world.level.levelgen.Heightmap.Types heightmapType, BlockPos pos) {
|
||||
return this.level.getHeightmapPos(heightmapType, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight(net.minecraft.world.level.levelgen.Heightmap.Types heightmap, int x, int z) {
|
||||
return this.world.getHeight(heightmap, x, z);
|
||||
public int getHeight(net.minecraft.world.level.levelgen.Heightmap.Types heightmapType, int x, int z) {
|
||||
return this.level.getHeight(heightmapType, x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRawBrightness(BlockPos pos, int amount) {
|
||||
return this.world.getRawBrightness(pos, amount);
|
||||
return this.level.getRawBrightness(pos, amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBrightness(net.minecraft.world.level.LightLayer lightLayer, BlockPos pos) {
|
||||
return this.world.getBrightness(lightLayer, pos);
|
||||
public int getBrightness(net.minecraft.world.level.LightLayer lightType, BlockPos pos) {
|
||||
return this.level.getBrightness(lightType, pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.bukkit.craftbukkit.util;
|
||||
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@NullMarked
|
||||
public record CapturedBlock(BlockState state, int flags, @Nullable BlockEntity blockEntity) {
|
||||
}
|
||||
@@ -2,6 +2,9 @@ package org.bukkit.craftbukkit.util;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMap.Builder;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
@@ -11,6 +14,7 @@ import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.chat.ChatVersion;
|
||||
import net.md_5.bungee.chat.VersionedComponentSerializer;
|
||||
@@ -18,6 +22,7 @@ import com.mojang.serialization.JavaOps;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.network.chat.ClickEvent;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.ComponentSerialization;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.network.chat.TextColor;
|
||||
@@ -28,6 +33,7 @@ import org.bukkit.craftbukkit.CraftRegistry;
|
||||
|
||||
public final class CraftChatMessage {
|
||||
|
||||
private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().create();
|
||||
private static final Map<Character, ChatFormatting> formatMap;
|
||||
|
||||
static {
|
||||
@@ -223,7 +229,11 @@ public final class CraftChatMessage {
|
||||
}
|
||||
|
||||
public static String toJSON(Component component) {
|
||||
return Component.Serializer.toJson(component, CraftRegistry.getMinecraftRegistry());
|
||||
return GSON.toJson(
|
||||
ComponentSerialization.CODEC
|
||||
.encodeStart(CraftRegistry.getMinecraftRegistry().createSerializationContext(JsonOps.INSTANCE), component)
|
||||
.getOrThrow(JsonParseException::new)
|
||||
);
|
||||
}
|
||||
|
||||
public static String toJSONOrNull(Component component) {
|
||||
@@ -234,7 +244,10 @@ public final class CraftChatMessage {
|
||||
public static Component fromJSON(String jsonMessage) throws JsonParseException {
|
||||
// Note: This also parses plain Strings to text components.
|
||||
// Note: An empty message (empty, or only consisting of whitespace) results in null rather than a parse exception.
|
||||
return Component.Serializer.fromJson(jsonMessage, CraftRegistry.getMinecraftRegistry());
|
||||
final JsonElement jsonElement = GSON.fromJson(jsonMessage, JsonElement.class);
|
||||
return jsonElement == null ? null : ComponentSerialization.CODEC.parse(
|
||||
CraftRegistry.getMinecraftRegistry().createSerializationContext(JsonOps.INSTANCE), jsonElement
|
||||
).getOrThrow(JsonParseException::new);
|
||||
}
|
||||
|
||||
public static Component fromJSONOrNull(String jsonMessage) {
|
||||
|
||||
@@ -4,12 +4,12 @@ import ca.spottedleaf.moonrise.common.PlatformHooks;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.serialization.Dynamic;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
@@ -41,7 +41,7 @@ import net.minecraft.nbt.TagParser;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.ExtraCodecs;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.util.datafix.DataFixers;
|
||||
import net.minecraft.util.datafix.fixes.References;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
@@ -50,6 +50,8 @@ import net.minecraft.world.item.alchemy.Potion;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.storage.LevelResource;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import net.minecraft.world.level.storage.TagValueOutput;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.Material;
|
||||
@@ -82,9 +84,13 @@ import org.bukkit.material.MaterialData;
|
||||
import org.bukkit.plugin.InvalidPluginException;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.potion.PotionType;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public final class CraftMagicNumbers implements UnsafeValues {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
public static final CraftMagicNumbers INSTANCE = new CraftMagicNumbers();
|
||||
public static final boolean DISABLE_OLD_API_SUPPORT = Boolean.getBoolean("paper.disableOldApiSupport"); // Paper
|
||||
|
||||
@@ -260,27 +266,17 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
}
|
||||
|
||||
/**
|
||||
* This string should be changed if the NMS mappings do.
|
||||
*
|
||||
* It has no meaning and should only be used as an equality check. Plugins
|
||||
* which are sensitive to the NMS mappings may read it and refuse to load if
|
||||
* it cannot be found or is different to the expected value.
|
||||
*
|
||||
* Remember: NMS is not supported API and may break at any time for any
|
||||
* reason irrespective of this. There is often supported API to do the same
|
||||
* thing as many common NMS usages. If not, you are encouraged to open a
|
||||
* feature and/or pull request for consideration, or use a well abstracted
|
||||
* third-party API such as ProtocolLib.
|
||||
*
|
||||
* @return string
|
||||
* @deprecated in favor of {@link io.papermc.paper.ServerBuildInfo#minecraftVersionId()}
|
||||
* Paper has used Mojang mappings since 1.20.5, and this method no longer returns a useful value.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.21.6")
|
||||
public String getMappingsVersion() {
|
||||
return "7ecad754373a5fbc43d381d7450c53a5";
|
||||
throw new UnsupportedOperationException("Use ServerBuildInfo#minecraftVersionId instead.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDataVersion() {
|
||||
return SharedConstants.getCurrentVersion().getDataVersion().getVersion();
|
||||
return SharedConstants.getCurrentVersion().dataVersion().version();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -491,9 +487,14 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
@Override
|
||||
public byte[] serializeItem(ItemStack item) {
|
||||
Preconditions.checkNotNull(item, "null cannot be serialized");
|
||||
Preconditions.checkArgument(item.getType() != Material.AIR, "air cannot be serialized");
|
||||
Preconditions.checkArgument(!item.isEmpty(), "Empty itemstack cannot be serialized");
|
||||
|
||||
return serializeNbtToBytes((CompoundTag) (item instanceof CraftItemStack ? ((CraftItemStack) item).handle : CraftItemStack.asNMSCopy(item)).save(MinecraftServer.getServer().registryAccess()));
|
||||
return serializeNbtToBytes(
|
||||
(CompoundTag) net.minecraft.world.item.ItemStack.CODEC.encodeStart(
|
||||
MinecraftServer.getServer().registryAccess().createSerializationContext(NbtOps.INSTANCE),
|
||||
CraftItemStack.unwrap(item)
|
||||
).getOrThrow()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -511,7 +512,9 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
if (compound.getStringOr("id", "minecraft:air").equals("minecraft:air")) {
|
||||
return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.EMPTY);
|
||||
}
|
||||
return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.parse(CraftRegistry.getMinecraftRegistry(), compound).orElseThrow());
|
||||
return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.CODEC.parse(
|
||||
CraftRegistry.getMinecraftRegistry().createSerializationContext(NbtOps.INSTANCE), compound
|
||||
).getOrThrow());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -519,7 +522,10 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
if (itemStack.isEmpty()) {
|
||||
return Map.of("id", "minecraft:air", SharedConstants.DATA_VERSION_TAG, this.getDataVersion(), "schema_version", 1);
|
||||
}
|
||||
final CompoundTag tag = CraftItemStack.asNMSCopy(itemStack).save(CraftRegistry.getMinecraftRegistry()).asCompound().orElseThrow();
|
||||
final CompoundTag tag = (CompoundTag) net.minecraft.world.item.ItemStack.CODEC.encodeStart(
|
||||
CraftRegistry.getMinecraftRegistry().createSerializationContext(NbtOps.INSTANCE),
|
||||
CraftItemStack.asNMSCopy(itemStack)
|
||||
).getOrThrow();
|
||||
NbtUtils.addCurrentDataVersion(tag);
|
||||
|
||||
final Map<String, Object> ret = new LinkedHashMap<>();
|
||||
@@ -677,21 +683,25 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
}
|
||||
});
|
||||
|
||||
CompoundTag compound = new CompoundTag();
|
||||
if (serializePassangers) {
|
||||
if (!nmsEntity.saveAsPassenger(compound, true, includeNonSaveable, forceSerialization)) {
|
||||
throw new IllegalArgumentException("Couldn't serialize entity");
|
||||
}
|
||||
} else {
|
||||
List<net.minecraft.world.entity.Entity> pass = new ArrayList<>(nmsEntity.getPassengers());
|
||||
nmsEntity.passengers = com.google.common.collect.ImmutableList.of();
|
||||
boolean serialized = nmsEntity.saveAsPassenger(compound, true, includeNonSaveable, forceSerialization);
|
||||
nmsEntity.passengers = com.google.common.collect.ImmutableList.copyOf(pass);
|
||||
if (!serialized) {
|
||||
throw new IllegalArgumentException("Couldn't serialize entity");
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "serialiseEntity@" + entity.getUniqueId(), LOGGER
|
||||
)) {
|
||||
final TagValueOutput output = TagValueOutput.createWithContext(problemReporter, nmsEntity.registryAccess());
|
||||
if (serializePassangers) {
|
||||
if (!nmsEntity.saveAsPassenger(output, true, includeNonSaveable, forceSerialization)) {
|
||||
throw new IllegalArgumentException("Couldn't serialize entity");
|
||||
}
|
||||
} else {
|
||||
List<net.minecraft.world.entity.Entity> pass = new ArrayList<>(nmsEntity.getPassengers());
|
||||
nmsEntity.passengers = com.google.common.collect.ImmutableList.of();
|
||||
boolean serialized = nmsEntity.saveAsPassenger(output, true, includeNonSaveable, forceSerialization);
|
||||
nmsEntity.passengers = com.google.common.collect.ImmutableList.copyOf(pass);
|
||||
if (!serialized) {
|
||||
throw new IllegalArgumentException("Couldn't serialize entity");
|
||||
}
|
||||
}
|
||||
return serializeNbtToBytes(output.buildResult());
|
||||
}
|
||||
return serializeNbtToBytes(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -714,8 +724,18 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
// Generate a new UUID, so we don't have to worry about deserializing the same entity twice
|
||||
compound.remove("UUID");
|
||||
}
|
||||
net.minecraft.world.entity.Entity nmsEntity = net.minecraft.world.entity.EntityType.create(compound, world, net.minecraft.world.entity.EntitySpawnReason.LOAD)
|
||||
.orElseThrow(() -> new IllegalArgumentException("An ID was not found for the data. Did you downgrade?"));
|
||||
|
||||
final net.minecraft.world.entity.Entity nmsEntity;
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "deserialiseEntity", LOGGER
|
||||
)) {
|
||||
nmsEntity = net.minecraft.world.entity.EntityType.create(
|
||||
TagValueInput.create(problemReporter, world.registryAccess(), compound),
|
||||
world,
|
||||
net.minecraft.world.entity.EntitySpawnReason.LOAD
|
||||
).orElseThrow(() -> new IllegalArgumentException("An ID was not found for the data. Did you downgrade?"));
|
||||
}
|
||||
|
||||
compound.getList("Passengers").ifPresent(passengers -> {
|
||||
for (final Tag tag : passengers) {
|
||||
if (!(tag instanceof final CompoundTag serializedPassenger)) {
|
||||
@@ -768,7 +788,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
|
||||
@Override
|
||||
public int getProtocolVersion() {
|
||||
return net.minecraft.SharedConstants.getCurrentVersion().getProtocolVersion();
|
||||
return net.minecraft.SharedConstants.getCurrentVersion().protocolVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
package org.bukkit.craftbukkit.util;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.structure.StructurePiece;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import org.bukkit.craftbukkit.block.CraftBlockEntityState;
|
||||
import org.bukkit.craftbukkit.block.CraftBlockState;
|
||||
import org.bukkit.craftbukkit.block.CraftBlockStates;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class TransformerGeneratorAccess extends DelegatedGeneratorAccess {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private CraftStructureTransformer structureTransformer;
|
||||
|
||||
public void setStructureTransformer(CraftStructureTransformer structureTransformer) {
|
||||
@@ -60,7 +66,13 @@ public class TransformerGeneratorAccess extends DelegatedGeneratorAccess {
|
||||
}
|
||||
BlockEntity blockEntity = this.getBlockEntity(position);
|
||||
if (blockEntity != null && craftBlockState instanceof CraftBlockEntityState<?> craftEntityState) {
|
||||
blockEntity.loadWithComponents(craftEntityState.getSnapshotNBT(), this.registryAccess());
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "TransformerGeneratorAccess@" + position.toShortString(), LOGGER
|
||||
)) {
|
||||
blockEntity.loadWithComponents(TagValueInput.create(
|
||||
problemReporter, this.registryAccess(), craftEntityState.getSnapshotNBT()
|
||||
));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ public final class CommandPermissions {
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "selector", "Allows the use of selectors", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "trigger", "Allows the use of the trigger command", PermissionDefault.TRUE, commands);
|
||||
// Paper start
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "attribute", "Allows the user to query, add, remove or set an entity attribute", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "advancement", "Allows the user to give, remove, or check player advancements", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "attribute", "Allows the user to query, add, remove or set an entity attribute", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "ban", "Allows the user to add players to the ban list", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "ban-ip", "Allows the user to add ip address to the ban list", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "banlist", "Allows the user to display the ban list", PermissionDefault.OP, commands);
|
||||
@@ -44,6 +44,7 @@ public final class CommandPermissions {
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "datapack", "Allows the user to control loaded data packs", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "debug", "Allows the user to start or stop a debugging session", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "deop", "Allows the user to revoke operator status from a player", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "dialog", "Allows the user to show dialogs", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "difficulty", "Allows the user to set the difficulty level", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "enchant", "Allows the user to enchant a player item", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "execute", "Allows the user to execute another command", PermissionDefault.OP, commands);
|
||||
@@ -52,6 +53,7 @@ public final class CommandPermissions {
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "forceload", "Allows the user to force chunks to be constantly loaded or not", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "function", "Allows the user to run a function", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "gamerule", "Allows a user to set or query a game rule value", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "item", "Allows the user to replace items in inventories", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "jfr", "Allows a user to use the vanilla Java FlightRecorder profiling system", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "locate", "Allows the user to locate the closest structure", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "loot", "Allows the user to drop items from an inventory slot onto the ground", PermissionDefault.OP, commands);
|
||||
@@ -60,11 +62,14 @@ public final class CommandPermissions {
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "pardon-ip", "Allows the user to remove entries from the ip address ban list", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "particle", "Allows the user to create particles", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "perf", "Allows the user to start/stop the vanilla performance metrics capture", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "place", "Allows the user to place features and structures", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "playsound", "Allows the user to play a sound", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "ride", "Allows the user to use the /ride command to control passengers", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "random", "Allows the user to generate a random number", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "recipe", "Allows the user to give or take recipes", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "reload", "Allows the user to reload loot tables, advancements, and functions from disk", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "item", "Allows the user to replace items in inventories", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "return", "Allows the user to use the /return command", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "ride", "Allows the user to use the /ride command to control passengers", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "rotate", "Allows the user to change the rotation of entities", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "save-all", "Allows the user to save the server to disk", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "save-off", "Allows the user disable automatic server saves", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "save-on", "Allows the user enable automatic server saves", PermissionDefault.OP, commands);
|
||||
@@ -83,17 +88,15 @@ public final class CommandPermissions {
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "teammsg", "Allows the user to specify the message to send to team", PermissionDefault.TRUE, commands); // defaults to all players
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "tellraw", "Allows the user to display a JSON message to players", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "test", "Allows the user to manage and execute GameTests", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "time", "Allows the user to change or query the world's game time", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "tick", "Allows the user to control the tick rate of the server", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "time", "Allows the user to change or query the world's game time", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "title", "Allows the user to manage screen titles", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "transfer", "Allows the user to transfer to another server", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "version", "Shows info related to the server version", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "waypoint", "Allows the managment of a waypoints on the server/locator bar", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "weather", "Allows the user to set the weather", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "whitelist", "Allows the user to manage the server whitelist", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "worldborder", "Allows the user to manage the world border", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "place", "Allows the user to place features and structures", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "return", "Allows the user to use the /return command", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "random", "Allows the user to generate a random number", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "rotate", "Allows the user to change the rotation of entities", PermissionDefault.OP, commands);
|
||||
// Paper end
|
||||
|
||||
DefaultPermissions.registerPermission("minecraft.admin.command_feedback", "Receive command broadcasts when sendCommandFeedback is true", PermissionDefault.OP, commands);
|
||||
|
||||
Reference in New Issue
Block a user