more patches done

This commit is contained in:
Jake Potrebic
2021-11-24 15:26:29 -08:00
parent 2744031e64
commit 8df1b4ad21
26 changed files with 46 additions and 130 deletions

View File

@@ -1,81 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Fri, 19 Mar 2021 23:39:21 -0400
Subject: [PATCH] Add ElderGuardianAppearanceEvent
diff --git a/src/main/java/io/papermc/paper/event/entity/ElderGuardianAppearanceEvent.java b/src/main/java/io/papermc/paper/event/entity/ElderGuardianAppearanceEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/ElderGuardianAppearanceEvent.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.event.entity;
+
+import org.bukkit.entity.ElderGuardian;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Is called when an {@link org.bukkit.entity.ElderGuardian} appears in front of a {@link org.bukkit.entity.Player}.
+ */
+public class ElderGuardianAppearanceEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList handlers = new HandlerList();
+
+ private boolean cancelled;
+ private final Player affectedPlayer;
+
+ public ElderGuardianAppearanceEvent(@NotNull Entity what, @NotNull Player affectedPlayer) {
+ super(what);
+ this.affectedPlayer = affectedPlayer;
+ }
+
+ /**
+ * Get the player affected by the guardian appearance.
+ *
+ * @return Player affected by the appearance
+ */
+ @NotNull
+ public Player getAffectedPlayer() {
+ return affectedPlayer;
+ }
+
+ /**
+ * The elder guardian playing the effect.
+ *
+ * @return The elder guardian
+ */
+ @NotNull
+ public ElderGuardian getEntity() {
+ return (ElderGuardian) entity;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}

View File

@@ -1,157 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Professor Bloodstone <git@bloodstone.dev>
Date: Sun, 20 Jun 2021 01:48:31 +0200
Subject: [PATCH] Add Git information to version command/on startup
diff --git a/src/main/java/io/papermc/paper/util/JarManifests.java b/src/main/java/io/papermc/paper/util/JarManifests.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/io/papermc/paper/util/JarManifests.java
@@ -0,0 +0,0 @@
+/*
+Copyright (c) 2012-2017, jcabi.com
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met: 1) Redistributions of source code must retain the above
+copyright notice, this list of conditions and the following
+disclaimer. 2) Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following
+disclaimer in the documentation and/or other materials provided
+with the distribution. 3) Neither the name of the jcabi.com nor
+the names of its contributors may be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+package io.papermc.paper.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.*;
+import java.util.jar.Manifest;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Modified version of jcabi-manifests
+ *
+ */
+public final class JarManifests {
+
+ public static final JarManifests JAR_MANIFESTS = new JarManifests();
+ public static final Map<String, String> MANIFEST_MAP;
+
+ static {
+ try {
+ MANIFEST_MAP = Collections.unmodifiableMap(JAR_MANIFESTS.getManifestMap());
+ } catch (final IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ private JarManifests() {}
+
+ // Based on:
+ // https://github.com/jcabi/jcabi-manifests/blob/c4e1dd22bb6099769b8d279ebe3737e5b638b278/src/main/java/com/jcabi/manifests/ClasspathMfs.java#L49-L58
+
+ /**
+ * Get collection containing all META-INF/MANIFEST.MF streams
+ *
+ * @throws IOException if unable to get resources from classloader
+ */
+ public @NotNull Collection<@NotNull InputStream> getManifestStreams() throws IOException {
+ final Enumeration<URL> resources = getClass().getClassLoader().getResources("META-INF/MANIFEST.MF");
+ final Collection<InputStream> streams = new ArrayList<>(1);
+ while (resources.hasMoreElements()) {
+ streams.add(resources.nextElement().openStream());
+ }
+ return streams;
+ }
+
+ // Based on:
+ // https://github.com/jcabi/jcabi-manifests/blob/c4e1dd22bb6099769b8d279ebe3737e5b638b278/src/main/java/com/jcabi/manifests/Manifests.java#L209-L225
+ // https://github.com/jcabi/jcabi-manifests/blob/c4e1dd22bb6099769b8d279ebe3737e5b638b278/src/main/java/com/jcabi/manifests/Manifests.java#L381-L388
+
+ /**
+ * Get map containing entries from all manifests
+ *
+ * @throws IOException if unable to get manifest streams
+ */
+ public @NotNull Map<@NotNull String, @NotNull String> getManifestMap() throws IOException {
+ final HashMap<String, String> attribs = new HashMap<>();
+ for (final InputStream stream : getManifestStreams()) {
+ for (final Map.Entry<Object, Object> attr: new Manifest(stream).getMainAttributes().entrySet()) {
+ attribs.put(attr.getKey().toString(), attr.getValue().toString());
+ }
+ }
+ return attribs;
+ }
+}
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -0,0 +0,0 @@ import org.bukkit.util.CachedServerIcon;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import io.papermc.paper.util.JarManifests; // Paper
/**
* Represents the Bukkit core, for version and Server singleton handling
@@ -0,0 +0,0 @@ public final class Bukkit {
}
Bukkit.server = server;
- server.getLogger().info("This server is running " + getName() + " version " + getVersion() + " (Implementing API version " + getBukkitVersion() + ")");
+ // Paper start - add git information
+ server.getLogger().info(getVersionMessage());
+ }
+ /**
+ * Gets message describing the version server is running.
+ *
+ * @return message describing the version server is running
+ */
+ @NotNull
+ public static String getVersionMessage() {
+ Map<String, String> attributes = JarManifests.MANIFEST_MAP;
+ @NotNull String gitBranch = attributes.get("Git-Branch");
+ @NotNull String gitCommit = attributes.get("Git-Commit");
+ @NotNull String branchMsg = " on " + gitBranch;
+ if ("master".equals(gitBranch) || "main".equals(gitBranch)) {
+ branchMsg = ""; // Don't show branch on main/master
+ }
+ return "This server is running " + getName() + " version " + getVersion() + " (Implementing API version " + getBukkitVersion() + ") (Git: " + gitCommit + branchMsg + ")";
+ // Paper end
}
/**
diff --git a/src/main/java/org/bukkit/command/defaults/VersionCommand.java b/src/main/java/org/bukkit/command/defaults/VersionCommand.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/command/defaults/VersionCommand.java
+++ b/src/main/java/org/bukkit/command/defaults/VersionCommand.java
@@ -0,0 +0,0 @@ public class VersionCommand extends BukkitCommand {
private void setVersionMessage(final @NotNull Component msg) {
lastCheck = System.currentTimeMillis();
final Component message = net.kyori.adventure.text.TextComponent.ofChildren(
- Component.text("This server is running " + Bukkit.getName() + " version " + Bukkit.getVersion() + " (Implementing API version " + Bukkit.getBukkitVersion() + ")", net.kyori.adventure.text.format.NamedTextColor.WHITE),
+ Component.text(Bukkit.getVersionMessage(), net.kyori.adventure.text.format.NamedTextColor.WHITE),
Component.newline(),
msg
);

View File

@@ -1,46 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 9 Jul 2021 17:44:33 -0700
Subject: [PATCH] Add PlayerSignCommandPreprocessEvent
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerSignCommandPreprocessEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerSignCommandPreprocessEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerSignCommandPreprocessEvent.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.event.player;
+
+import org.bukkit.block.Sign;
+import org.bukkit.entity.Player;
+import org.bukkit.event.player.PlayerCommandPreprocessEvent;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+
+/**
+ * Called when a {@link Player} clicks a sign that causes a command to run.
+ * <p>
+ * This command is run with elevated permissions which allows players to access commands on signs they wouldn't
+ * normally be able to run.
+ */
+public class PlayerSignCommandPreprocessEvent extends PlayerCommandPreprocessEvent {
+
+ private final Sign sign;
+
+ public PlayerSignCommandPreprocessEvent(@NotNull Player player, @NotNull String message, @NotNull Set<Player> recipients, @NotNull Sign sign) {
+ super(player, message, recipients);
+ this.sign = sign;
+ }
+
+ /**
+ * Gets the sign that the command originated from.
+ *
+ * @return the sign
+ */
+ @NotNull
+ public Sign getSign() {
+ return sign;
+ }
+}

View File

@@ -1,511 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: dfsek <dfsek@protonmail.com>
Date: Sat, 19 Jun 2021 20:15:29 -0700
Subject: [PATCH] Add more LimitedRegion API
diff --git a/src/main/java/io/papermc/paper/world/generation/ProtoWorld.java b/src/main/java/io/papermc/paper/world/generation/ProtoWorld.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/io/papermc/paper/world/generation/ProtoWorld.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.world.generation;
+
+import org.bukkit.World;
+import org.bukkit.block.BlockState;
+import org.bukkit.block.data.BlockData;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.EntityType;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.bukkit.generator.LimitedRegion;
+import org.bukkit.generator.WorldInfo;
+import org.bukkit.util.Vector;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Random;
+import java.util.function.Consumer;
+
+/**
+ * Represents a small grid of chunks in a {@link World}
+ * with rudimentary block and entity access, for use during world generation.
+ * <p>
+ * A ProtoWorld is guaranteed read/write access to a 3x3 grid of chunks,
+ * but may have access to a grid as large as 17x17. It is safest to assume
+ * that there is only read/write access to 3x3 chunks. Some chunks outside
+ * of the 3x3 area may be readable but not writable.
+ * <p>
+ * ProtoWorlds should not be stored! After they are used during
+ * chunk generation they should be disposed of.
+ *
+ * @see org.bukkit.generator.BlockPopulator#populate(WorldInfo, Random, int, int, LimitedRegion)
+ * @deprecated see {@link org.bukkit.RegionAccessor} and {@link org.bukkit.generator.LimitedRegion}
+ */
+@Deprecated(forRemoval = true)
+public interface ProtoWorld {
+ /**
+ * Sets the block at (x, y, z) to the provided {@link BlockData}.
+ *
+ * @param x X coordinate in this ProtoWorld
+ * @param y Y coordinate in this ProtoWorld
+ * @param z Z coordinate in this ProtoWorld
+ * @param data {@link BlockData} to set the block at the provided coordinates to.
+ */
+ void setBlockData(int x, int y, int z, @NotNull BlockData data);
+
+ /**
+ * Sets the block at a vector location to the provided {@link BlockData}.
+ *
+ * @param vector {@link Vector} representing the position of the block to set.
+ * @param data {@link BlockData} to set the block at the provided coordinates to.
+ */
+ default void setBlockData(@NotNull Vector vector, @NotNull BlockData data) {
+ setBlockData(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ(), data);
+ }
+
+ /**
+ * Sets the {@link BlockState} at a location.
+ *
+ * @param x X coordinate.
+ * @param y Y coordinate.
+ * @param z Z coordinate.
+ * @param state The block state.
+ */
+ void setBlockState(int x, int y, int z, @NotNull BlockState state);
+
+ /**
+ * Sets the {@link BlockState} at a location.
+ *
+ * @param location Location to set block state.
+ * @param state The block state.
+ */
+ default void setBlockState(@NotNull Vector location, @NotNull BlockState state) {
+ setBlockState(location.getBlockX(), location.getBlockY(), location.getBlockZ(), state);
+ }
+
+ /**
+ * Gets the {@link BlockState} at a location.
+ *
+ * @param x X coordinate.
+ * @param y Y coordinate.
+ * @param z Z coordinate.
+ * @return The block state.
+ */
+ @NotNull
+ BlockState getBlockState(int x, int y, int z);
+
+ /**
+ * Gets the {@link BlockState} at a location.
+ *
+ * @param location Location to get block state from.
+ * @return The block state.
+ */
+ @NotNull
+ default BlockState getBlockState(@NotNull Vector location) {
+ return getBlockState(location.getBlockX(), location.getBlockY(), location.getBlockZ());
+ }
+
+ /**
+ * Schedule a block update at (x, y, z).
+ *
+ * @param x X coordinate in this ProtoWorld
+ * @param y Y coordinate in this ProtoWorld
+ * @param z Z coordinate in this ProtoWorld
+ */
+ void scheduleBlockUpdate(int x, int y, int z);
+
+ /**
+ * Schedule a block update at a vector location
+ *
+ * @param location {@link Vector} representing the position of the block to update.
+ */
+ default void scheduleBlockUpdate(@NotNull Vector location) {
+ scheduleBlockUpdate(location.getBlockX(), location.getBlockY(), location.getBlockZ());
+ }
+
+ /**
+ * Schedule a fluid update at (x, y, z).
+ *
+ * @param x X coordinate in this ProtoWorld
+ * @param y Y coordinate in this ProtoWorld
+ * @param z Z coordinate in this ProtoWorld
+ */
+ void scheduleFluidUpdate(int x, int y, int z);
+
+ /**
+ * Schedule a fluid update at a vector location
+ *
+ * @param location {@link Vector} representing the position of the block to update.
+ */
+ default void scheduleFluidUpdate(@NotNull Vector location) {
+ scheduleFluidUpdate(location.getBlockX(), location.getBlockY(), location.getBlockZ());
+ }
+
+ /**
+ * Get the {@link World} object this ProtoWorld represents.
+ * <p>
+ * Do <b>not</b> attempt to read from/write to this world! Doing so during generation <b>will cause a deadlock!</b>
+ *
+ * @return The {@link World} object that this ProtoWorld represents.
+ */
+ @NotNull
+ World getWorld();
+
+
+ /**
+ * Get the {@link BlockData} of the block at the provided coordinates.
+ *
+ * @param x X coordinate in this ProtoWorld
+ * @param y Y coordinate in this ProtoWorld
+ * @param z Z coordinate in this ProtoWorld
+ * @return {@link BlockData} at the coordinates
+ */
+ @NotNull
+ BlockData getBlockData(int x, int y, int z);
+
+ /**
+ * Get the {@link BlockData} of the block at the provided coordinates.
+ *
+ * @param vector {@link Vector} representing the position of the block to get.
+ * @return {@link BlockData} at the coordinates
+ */
+ @NotNull
+ default BlockData getBlockData(@NotNull Vector vector) {
+ return getBlockData(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
+ }
+
+ /**
+ * Get the X-coordinate of the chunk in the center of this ProtoWorld
+ *
+ * @return The center chunk's X coordinate.
+ */
+ int getCenterChunkX();
+
+ /**
+ * Get the X-coordinate of the block in the center of this {@link ProtoWorld}
+ *
+ * @return The center chunk's X coordinate.
+ */
+ default int getCenterBlockX() {
+ return getCenterChunkX() << 4;
+ }
+
+ /**
+ * Get the Z-coordinate of the chunk in the center of this {@link ProtoWorld}
+ *
+ * @return The center chunk's Z coordinate.
+ */
+ int getCenterChunkZ();
+
+ /**
+ * Get the Z-coordinate of the block in the center of this {@link ProtoWorld}
+ *
+ * @return The center chunk's Z coordinate.
+ */
+ default int getCenterBlockZ() {
+ return getCenterChunkZ() << 4;
+ }
+
+ /**
+ * Creates an entity at the location represented by the given {@link Vector}
+ *
+ * @param loc The {@link Vector} representing the location to spawn the entity
+ * @param type The entity to spawn
+ * @return Resulting Entity of this method
+ */
+ @NotNull
+ default Entity spawnEntity(@NotNull Vector loc, @NotNull EntityType type) {
+ return spawn(loc, type.getEntityClass(), CreatureSpawnEvent.SpawnReason.DEFAULT);
+ }
+
+ /**
+ * Spawn an entity of a specific class at location represented by the given {@link Vector}
+ *
+ * @param location The {@link Vector} representing the location to spawn the entity at
+ * @param clazz The class of the {@link Entity} to spawn
+ * @param <T> The class of the {@link Entity} to spawn
+ * @return An instance of the spawned {@link Entity}
+ * @throws IllegalArgumentException if either parameter is null or the
+ * {@link Entity} requested cannot be spawned
+ */
+ @NotNull
+ default <T extends Entity> T spawn(@NotNull Vector location, @NotNull Class<T> clazz) throws IllegalArgumentException {
+ return spawn(location, clazz, CreatureSpawnEvent.SpawnReason.DEFAULT, null);
+ }
+
+ /**
+ * Spawn an entity of a specific class at location represented by the given {@link Vector}
+ *
+ * @param location The {@link Vector} representing the location to spawn the entity at
+ * @param clazz The class of the {@link Entity} to spawn
+ * @param <T> The class of the {@link Entity} to spawn
+ * @param reason The reason for the entity's spawn.
+ * @return An instance of the spawned {@link Entity}
+ * @throws IllegalArgumentException if either parameter is null or the
+ * {@link Entity} requested cannot be spawned
+ */
+ @NotNull
+ default <T extends Entity> T spawn(@NotNull Vector location, @NotNull Class<T> clazz, @NotNull CreatureSpawnEvent.SpawnReason reason) throws IllegalArgumentException {
+ return spawn(location, clazz, reason, null);
+ }
+
+ /**
+ * Spawn an entity of a specific class at the location represented by the given {@link Vector}, with
+ * the supplied function run before the entity is added to the world.
+ * <br>
+ * Note that when the function is run, the entity will not be actually in
+ * the world. Any operation involving such as teleporting the entity is undefined
+ * until after this function returns.
+ *
+ * @param location The {@link Vector} representing the location to spawn the entity at
+ * @param clazz The class of the {@link Entity} to spawn
+ * @param function The function to be run before the entity is spawned.
+ * @param <T> The class of the {@link Entity} to spawn
+ * @return An instance of the spawned {@link Entity}
+ * @throws IllegalArgumentException if either parameter is null or the
+ * {@link Entity} requested cannot be spawned
+ */
+ @NotNull
+ default <T extends Entity> T spawn(@NotNull Vector location, @NotNull Class<T> clazz, @Nullable Consumer<T> function) throws IllegalArgumentException {
+ return spawn(location, clazz, CreatureSpawnEvent.SpawnReason.CUSTOM, function);
+ }
+
+ /**
+ * Spawn an entity of a specific class at the location represented by the given {@link Vector}, with
+ * the supplied function run before the entity is added to the world.
+ * <br>
+ * Note that when the function is run, the entity will not be actually in
+ * the world. Any operation involving such as teleporting the entity is undefined
+ * until after this function returns.
+ *
+ * @param location The {@link Vector} representing the location to spawn the entity at
+ * @param clazz The class of the {@link Entity} to spawn
+ * @param reason The reason for the entity's spawn.
+ * @param function The function to be run before the entity is spawned.
+ * @param <T> The class of the {@link Entity} to spawn
+ * @return An instance of the spawned {@link Entity}
+ * @throws IllegalArgumentException if either parameter is null or the
+ * {@link Entity} requested cannot be spawned
+ */
+ @NotNull
+ default <T extends Entity> T spawn(@NotNull Vector location, @NotNull Class<T> clazz, @NotNull CreatureSpawnEvent.SpawnReason reason, @Nullable Consumer<T> function) throws IllegalArgumentException {
+ return spawn(location, clazz, function, reason);
+ }
+
+ /**
+ * Creates an entity at the location represented by the given {@link Vector}
+ *
+ * @param loc The {@link Vector} representing the location to spawn the entity
+ * @param type The entity to spawn
+ * @param reason The reason for the entity's spawn.
+ * @return Resulting Entity of this method
+ */
+ @SuppressWarnings("unchecked")
+ @NotNull
+ default Entity spawnEntity(@NotNull Vector loc, @NotNull EntityType type, @NotNull CreatureSpawnEvent.SpawnReason reason) {
+ return spawn(loc, (Class<Entity>) type.getEntityClass(), reason, null);
+ }
+
+ /**
+ * Creates an entity at the location represented by the given {@link Vector}, with
+ * the supplied function run before the entity is added to the world.
+ * <br>
+ * Note that when the function is run, the entity will not be actually in
+ * the world. Any operation involving such as teleporting the entity is undefined
+ * until after this function returns.
+ *
+ * @param loc The {@link Vector} representing the location to spawn the entity
+ * @param type The entity to spawn
+ * @param reason The reason for the entity's spawn.
+ * @param function The function to be run before the entity is spawned.
+ * @return Resulting Entity of this method
+ */
+ @SuppressWarnings("unchecked")
+ @NotNull
+ default Entity spawnEntity(@NotNull Vector loc, @NotNull EntityType type, @NotNull CreatureSpawnEvent.SpawnReason reason, @Nullable Consumer<Entity> function) {
+ return spawn(loc, (Class<Entity>) type.getEntityClass(), reason, function);
+ }
+
+ @NotNull <T extends Entity> T spawn(@NotNull Vector location, @NotNull Class<T> clazz, @Nullable Consumer<T> function, @NotNull CreatureSpawnEvent.SpawnReason reason) throws IllegalArgumentException;
+}
diff --git a/src/main/java/org/bukkit/generator/ChunkGenerator.java b/src/main/java/org/bukkit/generator/ChunkGenerator.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/generator/ChunkGenerator.java
+++ b/src/main/java/org/bukkit/generator/ChunkGenerator.java
@@ -0,0 +0,0 @@ public abstract class ChunkGenerator {
return new ArrayList<BlockPopulator>();
}
+
+ // Paper start
+ /**
+ * Generate decorations in a chunk, with quick access to its neighbors.
+ *
+ * @param world ProtoWorld to generate decorations with.
+ * @deprecated use and override {@link BlockPopulator#populate(WorldInfo, Random, int, int, LimitedRegion)}
+ */
+ @Deprecated(forRemoval = true)
+ public void generateDecorations(@NotNull io.papermc.paper.world.generation.ProtoWorld world) {
+ // Do nothing by default to maintain compatibility with existing generators.
+ }
+ // Paper end
+
/**
* Gets a fixed spawn location to use for a given world.
* <p>
diff --git a/src/main/java/org/bukkit/generator/LimitedRegion.java b/src/main/java/org/bukkit/generator/LimitedRegion.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/generator/LimitedRegion.java
+++ b/src/main/java/org/bukkit/generator/LimitedRegion.java
@@ -0,0 +0,0 @@ import java.util.List;
import org.bukkit.Location;
import org.bukkit.RegionAccessor;
import org.bukkit.block.BlockState;
+// Paper start
+import org.bukkit.World;
+import org.bukkit.block.BlockState;
+import org.bukkit.block.data.BlockData;
+import org.bukkit.util.Vector;
+// Paper end
import org.jetbrains.annotations.NotNull;
/**
@@ -0,0 +0,0 @@ public interface LimitedRegion extends RegionAccessor {
*/
@NotNull
List<BlockState> getTileEntities();
+
+
+ // Paper start
+ /**
+ * Sets the block at a vector location to the provided {@link BlockData}.
+ *
+ * @param vector {@link Vector} representing the position of the block to set.
+ * @param data {@link BlockData} to set the block at the provided coordinates to.
+ */
+ default void setBlockData(@NotNull Vector vector, @NotNull BlockData data) {
+ setBlockData(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ(), data);
+ }
+
+ /**
+ * Sets the {@link BlockState} at a location.
+ *
+ * @param x X coordinate.
+ * @param y Y coordinate.
+ * @param z Z coordinate.
+ * @param state The block state.
+ */
+ void setBlockState(int x, int y, int z, @NotNull BlockState state);
+
+ /**
+ * Sets the {@link BlockState} at a location.
+ *
+ * @param location Location to set block state.
+ * @param state The block state.
+ */
+ default void setBlockState(@NotNull Vector location, @NotNull BlockState state) {
+ setBlockState(location.getBlockX(), location.getBlockY(), location.getBlockZ(), state);
+ }
+
+ /**
+ * Gets the {@link BlockState} at a location.
+ *
+ * @param location Location to get block state from.
+ * @return The block state.
+ */
+ @NotNull
+ default BlockState getBlockState(@NotNull Vector location) {
+ return getBlockState(location.getBlockX(), location.getBlockY(), location.getBlockZ());
+ }
+
+ /**
+ * Schedules a block update at (x, y, z).
+ *
+ * @param x X coordinate
+ * @param y Y coordinate
+ * @param z Z coordinate
+ */
+ void scheduleBlockUpdate(int x, int y, int z);
+
+ /**
+ * Schedules a block update at a vector location.
+ *
+ * @param location {@link Vector} representing the position of the block to update.
+ */
+ default void scheduleBlockUpdate(@NotNull Vector location) {
+ scheduleBlockUpdate(location.getBlockX(), location.getBlockY(), location.getBlockZ());
+ }
+
+ /**
+ * Schedules a fluid update at (x, y, z).
+ *
+ * @param x X coordinate
+ * @param y Y coordinate
+ * @param z Z coordinate
+ */
+ void scheduleFluidUpdate(int x, int y, int z);
+
+ /**
+ * Schedules a fluid update at a vector location.
+ *
+ * @param location {@link Vector} representing the position of the block to update.
+ */
+ default void scheduleFluidUpdate(@NotNull Vector location) {
+ scheduleFluidUpdate(location.getBlockX(), location.getBlockY(), location.getBlockZ());
+ }
+
+ /**
+ * Gets the {@link World} object this region represents.
+ * <p>
+ * Do <b>not</b> attempt to read from/write to this world! Doing so during generation <b>will cause a deadlock!</b>
+ *
+ * @return The {@link World} object that this region represents.
+ */
+ @NotNull
+ World getWorld();
+
+ /**
+ * Gets the {@link BlockData} of the block at the provided coordinates.
+ *
+ * @param vector {@link Vector} representing the position of the block to get.
+ * @return {@link BlockData} at the coordinates
+ */
+ @NotNull
+ default BlockData getBlockData(@NotNull Vector vector) {
+ return getBlockData(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
+ }
+
+ /**
+ * Gets the X-coordinate of the chunk in the center of the region.
+ *
+ * @return The center chunk's X coordinate.
+ */
+ int getCenterChunkX();
+
+ /**
+ * Gets the X-coordinate of the block in the center of the region.
+ *
+ * @return The center chunk's X coordinate.
+ */
+ default int getCenterBlockX() {
+ return getCenterChunkX() << 4;
+ }
+
+ /**
+ * Gets the Z-coordinate of the chunk in the center of the region.
+ *
+ * @return The center chunk's Z coordinate.
+ */
+ int getCenterChunkZ();
+
+ /**
+ * Gets the Z-coordinate of the block in the center of the region.
+ *
+ * @return The center chunk's Z coordinate.
+ */
+ default int getCenterBlockZ() {
+ return getCenterChunkZ() << 4;
+ }
+ // Paper end
}

View File

@@ -1,49 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: TwoLeggedCat <80929284+TwoLeggedCat@users.noreply.github.com>
Date: Sat, 29 May 2021 14:33:18 -0500
Subject: [PATCH] Add more line of sight methods
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/World.java
+++ b/src/main/java/org/bukkit/World.java
@@ -0,0 +0,0 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
*/
@NotNull
io.papermc.paper.world.MoonPhase getMoonPhase();
+
+ /**
+ * Tell whether a line of sight exists between the given locations
+ * @param from Location to start at
+ * @param to target Location
+ * @return whether a line of sight exists between {@code from} and {@code to}
+ */
+ public boolean lineOfSightExists(@NotNull Location from, @NotNull Location to);
// Paper end
/**
diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/entity/LivingEntity.java
+++ b/src/main/java/org/bukkit/entity/LivingEntity.java
@@ -0,0 +0,0 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource
*/
public boolean hasLineOfSight(@NotNull Entity other);
+ // Paper start
+ /**
+ * Checks whether the living entity has block line of sight to the given block.
+ * <p>
+ * This uses the same algorithm that hostile mobs use to find the closest
+ * player.
+ *
+ * @param location the location to determine line of sight to
+ * @return true if there is a line of sight, false if not
+ */
+ public boolean hasLineOfSight(@NotNull Location location);
+ // Paper end
+
/**
* Returns if the living entity despawns when away from players or not.
* <p>

View File

@@ -1,71 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 12 Mar 2021 19:20:03 -0800
Subject: [PATCH] Adds PlayerArmSwingEvent
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerArmSwingEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerArmSwingEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerArmSwingEvent.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.event.player;
+
+import org.bukkit.entity.Player;
+import org.bukkit.event.player.PlayerAnimationEvent;
+import org.bukkit.event.player.PlayerAnimationType;
+import org.bukkit.inventory.EquipmentSlot;
+import org.jetbrains.annotations.NotNull;
+
+public class PlayerArmSwingEvent extends PlayerAnimationEvent {
+
+ private final EquipmentSlot equipmentSlot;
+
+ public PlayerArmSwingEvent(@NotNull Player player, @NotNull EquipmentSlot equipmentSlot) {
+ super(player, PlayerAnimationType.ARM_SWING);
+ this.equipmentSlot = equipmentSlot;
+ }
+
+ /**
+ * Returns the hand of the arm swing.
+ *
+ * @return the hand
+ */
+ @NotNull
+ public EquipmentSlot getHand() {
+ return this.equipmentSlot;
+ }
+}
diff --git a/src/main/java/org/bukkit/event/player/PlayerAnimationEvent.java b/src/main/java/org/bukkit/event/player/PlayerAnimationEvent.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/event/player/PlayerAnimationEvent.java
+++ b/src/main/java/org/bukkit/event/player/PlayerAnimationEvent.java
@@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull;
/**
* Represents a player animation event
+ * <br>Use {@link io.papermc.paper.event.player.PlayerArmSwingEvent} for determining which arm was swung.
*/
public class PlayerAnimationEvent extends PlayerEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
@@ -0,0 +0,0 @@ public class PlayerAnimationEvent extends PlayerEvent implements Cancellable {
*
* @param player The player instance
*/
+ @Deprecated // Paper
public PlayerAnimationEvent(@NotNull final Player player) {
super(player);
// Only supported animation type for now:
animationType = PlayerAnimationType.ARM_SWING;
}
+ // Paper start
+ public PlayerAnimationEvent(@NotNull final Player player, @NotNull PlayerAnimationType animationType) {
+ super(player);
+ this.animationType = animationType;
+ }
+ // Paper end
/**
* Get the type of this animation event

View File

@@ -1,173 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Fri, 28 May 2021 21:06:59 -0400
Subject: [PATCH] Missing Entity Behavior API
diff --git a/src/main/java/org/bukkit/entity/AbstractHorse.java b/src/main/java/org/bukkit/entity/AbstractHorse.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/entity/AbstractHorse.java
+++ b/src/main/java/org/bukkit/entity/AbstractHorse.java
@@ -0,0 +0,0 @@ public interface AbstractHorse extends Vehicle, InventoryHolder, Tameable {
@NotNull
@Override
public AbstractHorseInventory getInventory();
+
+ // Paper start - Horse API
+ /**
+ * Gets if a horse is in their eating grass animation.
+ *
+ * @return eating grass animation is active
+ */
+ public boolean isEatingGrass();
+
+ /**
+ * Sets if a horse is in their eating grass animation.
+ *
+ * <p>When true, the horse will lower its neck.</p>
+ *
+ * @param eating eating grass animation is active
+ */
+ public void setEatingGrass(boolean eating);
+
+ /**
+ * Gets if a horse is in their rearing animation.
+ *
+ * @return rearing animation is active
+ */
+ public boolean isRearing();
+
+ /**
+ * Sets if a horse is in their rearing animation.
+ *
+ * <p>When true, the horse will stand on its hind legs.</p>
+ *
+ * @param rearing rearing animation is active
+ */
+ public void setRearing(boolean rearing);
+
+ /**
+ * Gets if a horse is in their eating animation.
+ *
+ * @return eating animation is active
+ */
+ public boolean isEating();
+
+ /**
+ * Sets if a horse is in their eating animation.
+ *
+ * <p>When true, the horse will bob its head.</p>
+ *
+ * @param eating eating animation is active
+ */
+ public void setEating(boolean eating);
+ // Paper end - Horse API
}
diff --git a/src/main/java/org/bukkit/entity/Cat.java b/src/main/java/org/bukkit/entity/Cat.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/entity/Cat.java
+++ b/src/main/java/org/bukkit/entity/Cat.java
@@ -0,0 +0,0 @@ public interface Cat extends Tameable, Sittable {
JELLIE,
ALL_BLACK;
}
+
+ // Paper Start - More cat api
+ /**
+ * Sets if the cat is lying down.
+ * This is visual and does not affect the behaviour of the cat.
+ *
+ * @param lyingDown whether the cat should lie down
+ */
+ public void setLyingDown(boolean lyingDown);
+
+ /**
+ * Gets if the cat is lying down.
+ *
+ * @return whether the cat is lying down
+ */
+ public boolean isLyingDown();
+
+ /**
+ * Sets if the cat has its head up.
+ * This is visual and does not affect the behaviour of the cat.
+ *
+ * @param headUp head is up
+ */
+ public void setHeadUp(boolean headUp);
+
+ /**
+ * Gets if the cat has its head up.
+ *
+ * @return head is up
+ */
+ public boolean isHeadUp();
+ // Paper End - More cat api
}
diff --git a/src/main/java/org/bukkit/entity/Fox.java b/src/main/java/org/bukkit/entity/Fox.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/entity/Fox.java
+++ b/src/main/java/org/bukkit/entity/Fox.java
@@ -0,0 +0,0 @@ public interface Fox extends Animals, Sittable {
RED,
SNOW;
}
+
+ // Paper start - Add more fox behavior API
+ /**
+ * Sets if the fox is interested.
+ *
+ * @param interested is interested
+ */
+ public void setInterested(boolean interested);
+
+ /**
+ * Gets if the fox is interested.
+ *
+ * @return fox is interested
+ */
+ public boolean isInterested();
+
+ /**
+ * Sets if the fox is leaping.
+ *
+ * @param leaping is leaping
+ */
+ public void setLeaping(boolean leaping);
+
+ /**
+ * Gets if the fox is leaping.
+ *
+ * @return fox is leaping
+ */
+ public boolean isLeaping();
+
+ /**
+ * Sets if the fox is defending.
+ *
+ * @param defending is defending
+ */
+ public void setDefending(boolean defending);
+
+ /**
+ * Gets if the fox is defending.
+ *
+ * @return fox is defending
+ */
+ public boolean isDefending();
+
+ /**
+ * Sets if the fox face planted.
+ *
+ * @param faceplanted face planted
+ */
+ public void setFaceplanted(boolean faceplanted);
+
+ /**
+ * Gets if the fox face planted.
+ *
+ * @return fox face planted
+ */
+ public boolean isFaceplanted();
+ // Paper end - Add more fox behavior API
}

View File

@@ -1,23 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Fri, 19 Mar 2021 23:39:09 -0400
Subject: [PATCH] Add ElderGuardianAppearanceEvent
diff --git a/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java b/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java
+++ b/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java
@@ -0,0 +0,0 @@ public class ElderGuardian extends Guardian {
while (iterator.hasNext()) {
ServerPlayer entityplayer = (ServerPlayer) iterator.next();
+ if (new io.papermc.paper.event.entity.ElderGuardianAppearanceEvent(getBukkitEntity(), entityplayer.getBukkitEntity()).callEvent()) { // Paper - Add Guardian Appearance Event
if (!entityplayer.hasEffect(mobeffectlist) || entityplayer.getEffect(mobeffectlist).getAmplifier() < 2 || entityplayer.getEffect(mobeffectlist).getDuration() < 1200) {
entityplayer.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.GUARDIAN_ELDER_EFFECT, this.isSilent() ? 0.0F : 1.0F));
entityplayer.addEffect(new MobEffectInstance(mobeffectlist, 6000, 2), this, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit
}
+ } // Paper - Add Guardian Appearance Event
}
}

View File

@@ -1,27 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Professor Bloodstone <git@bloodstone.dev>
Date: Sun, 20 Jun 2021 01:14:41 +0200
Subject: [PATCH] Add git branch and commit to manifest
diff --git a/build.gradle.kts b/build.gradle.kts
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -0,0 +0,0 @@ tasks.jar {
val gitHash = git("rev-parse", "--short=7", "HEAD").getText().trim()
val implementationVersion = System.getenv("BUILD_NUMBER") ?: "\"$gitHash\""
val date = git("show", "-s", "--format=%ci", gitHash).getText().trim() // Paper
+ val gitBranch = git("rev-parse", "--abbrev-ref", "HEAD").getText().trim() // Paper
attributes(
"Main-Class" to "org.bukkit.craftbukkit.Main",
"Implementation-Title" to "CraftBukkit",
@@ -0,0 +0,0 @@ tasks.jar {
"Specification-Version" to project.version,
"Specification-Vendor" to "Bukkit Team",
"Multi-Release" to "true", // Paper
+ "Git-Branch" to gitBranch, // Paper
+ "Git-Commit" to gitHash, // Paper
)
for (tld in setOf("net", "com", "org")) {
attributes("$tld/bukkit", "Sealed" to true)

View File

@@ -1,255 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: dfsek <dfsek@protonmail.com>
Date: Sat, 19 Jun 2021 20:15:59 -0700
Subject: [PATCH] Add more LimitedRegion API
diff --git a/src/main/java/io/papermc/paper/world/generation/CraftProtoWorld.java b/src/main/java/io/papermc/paper/world/generation/CraftProtoWorld.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/io/papermc/paper/world/generation/CraftProtoWorld.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.world.generation;
+
+import net.minecraft.core.BlockPos;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.server.level.WorldGenRegion;
+import net.minecraft.world.entity.Mob;
+import net.minecraft.world.entity.MobSpawnType;
+import net.minecraft.world.entity.SpawnGroupData;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import org.bukkit.World;
+import org.bukkit.block.BlockState;
+import org.bukkit.block.data.BlockData;
+import org.bukkit.craftbukkit.block.CraftBlockEntityState;
+import org.bukkit.craftbukkit.block.CraftBlockState;
+import org.bukkit.craftbukkit.block.data.CraftBlockData;
+import org.bukkit.craftbukkit.inventory.CraftMetaBlockState;
+import org.bukkit.entity.Entity;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.bukkit.util.Vector;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Objects;
+import java.util.function.Consumer;
+
+@Deprecated
+public class CraftProtoWorld implements ProtoWorld {
+ private WorldGenRegion region;
+
+ public CraftProtoWorld(WorldGenRegion region) {
+ this.region = region;
+ }
+
+ public void clearReference() {
+ region = null;
+ }
+
+ @Override
+ public void setBlockData(int x, int y, int z, @NotNull BlockData data) {
+ BlockPos position = new BlockPos(x, y, z);
+ getDelegate().setBlock(position, ((CraftBlockData) data).getState(), 3);
+ }
+
+ @Override
+ public void setBlockState(int x, int y, int z, @NotNull BlockState state) {
+ BlockPos pos = new BlockPos(x, y, z);
+ if(!state.getBlockData().matches(getDelegate().getBlockState(pos).createCraftBlockData())) {
+ throw new IllegalArgumentException("BlockData does not match! Expected " + state.getBlockData().getAsString(false) + ", got " + getDelegate().getBlockState(pos).createCraftBlockData().getAsString(false));
+ }
+ getDelegate().getBlockEntity(pos).load(((CraftBlockEntityState<?>) state).getSnapshotNBT());
+ }
+
+ @Override
+ public @NotNull BlockState getBlockState(int x, int y, int z) {
+ BlockEntity entity = getDelegate().getBlockEntity(new BlockPos(x, y, z));
+ return CraftMetaBlockState.createBlockState(entity.getBlockState().getBukkitMaterial(), entity.save(new CompoundTag()));
+ }
+
+ @Override
+ public void scheduleBlockUpdate(int x, int y, int z) {
+ BlockPos position = new BlockPos(x, y, z);
+ getDelegate().getBlockTicks().scheduleTick(position, getDelegate().getBlockIfLoaded(position), 0);
+ }
+
+ @Override
+ public void scheduleFluidUpdate(int x, int y, int z) {
+ BlockPos position = new BlockPos(x, y, z);
+ getDelegate().getLiquidTicks().scheduleTick(position, getDelegate().getFluidState(position).getType(), 0);
+ }
+
+ @Override
+ public @NotNull World getWorld() {
+ // reading/writing the returned Minecraft world causes a deadlock.
+ // By implementing this, and covering it in warnings, we're assuming people won't be stupid, and
+ // if they are stupid, they'll figure it out pretty fast.
+ return getDelegate().getMinecraftWorld().getWorld();
+ }
+
+ @Override
+ public @NotNull BlockData getBlockData(int x, int y, int z) {
+ return CraftBlockData.fromData(getDelegate().getBlockState(new BlockPos(x, y, z)));
+ }
+
+ @Override
+ public int getCenterChunkX() {
+ return getDelegate().getCenter().x;
+ }
+
+ @Override
+ public int getCenterChunkZ() {
+ return getDelegate().getCenter().z;
+ }
+
+ @SuppressWarnings({"unchecked", "deprecation"})
+ @Override
+ public <T extends Entity> @NotNull T spawn(@NotNull Vector location, @NotNull Class<T> clazz, @Nullable Consumer<T> function, CreatureSpawnEvent.@NotNull SpawnReason reason) throws IllegalArgumentException {
+ net.minecraft.world.entity.Entity entity = getDelegate().getMinecraftWorld().getWorld().createEntity(location.toLocation(getWorld()), clazz);
+ Objects.requireNonNull(entity, "Cannot spawn null entity");
+ if (entity instanceof Mob mob) {
+ mob.finalizeSpawn(getDelegate(), getDelegate().getCurrentDifficultyAt(entity.blockPosition()), MobSpawnType.COMMAND, (SpawnGroupData) null, null);
+ }
+
+ if (function != null) {
+ function.accept((T) entity.getBukkitEntity());
+ }
+
+ getDelegate().addEntity(entity, reason);
+ return (T) entity.getBukkitEntity();
+ }
+
+ @NotNull
+ private WorldGenRegion getDelegate() {
+ return Objects.requireNonNull(region, "Cannot access ProtoWorld after generation!");
+ }
+}
+
diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
+++ b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
@@ -0,0 +0,0 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe
@Override
public BlockState getBlockState(int x, int y, int z) {
Preconditions.checkArgument(this.isInRegion(x, y, z), "Coordinates %s, %s, %s are not in the region", x, y, z);
- return super.getBlockState(x, y, z);
+ // Paper start
+ net.minecraft.world.level.block.entity.BlockEntity entity = getHandle().getBlockEntity(new BlockPos(x, y, z));
+ return org.bukkit.craftbukkit.inventory.CraftMetaBlockState.createBlockState(entity.getBlockState().getBukkitMaterial(), entity.save(new CompoundTag()));
+ // Paper end
}
@Override
@@ -0,0 +0,0 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe
@Override
public void setBlockData(int x, int y, int z, BlockData blockData) {
Preconditions.checkArgument(this.isInRegion(x, y, z), "Coordinates %s, %s, %s are not in the region", x, y, z);
- super.setBlockData(x, y, z, blockData);
+ getHandle().setBlock(new BlockPos(x, y, z), ((org.bukkit.craftbukkit.block.data.CraftBlockData) blockData).getState(), 3); // Paper
}
@Override
@@ -0,0 +0,0 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe
public void addEntityToWorld(net.minecraft.world.entity.Entity entity, CreatureSpawnEvent.SpawnReason reason) {
this.entities.add(entity);
}
+
+ // Paper start
+ @Override
+ public void setBlockState(int x, int y, int z, BlockState state) {
+ BlockPos pos = new BlockPos(x, y, z);
+ 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).load(((org.bukkit.craftbukkit.block.CraftBlockEntityState<?>) state).getSnapshotNBT());
+ }
+
+ @Override
+ public void scheduleBlockUpdate(int x, int y, int z) {
+ BlockPos position = new BlockPos(x, y, z);
+ getHandle().getBlockTicks().scheduleTick(position, getHandle().getBlockIfLoaded(position), 0);
+ }
+
+ @Override
+ public void scheduleFluidUpdate(int x, int y, int z) {
+ BlockPos position = new BlockPos(x, y, z);
+ getHandle().getLiquidTicks().scheduleTick(position, getHandle().getFluidState(position).getType(), 0);
+ }
+
+ @Override
+ public World getWorld() {
+ // reading/writing the returned Minecraft world causes a deadlock.
+ // By implementing this, and covering it in warnings, we're assuming people won't be stupid, and
+ // if they are stupid, they'll figure it out pretty fast.
+ return getHandle().getMinecraftWorld().getWorld();
+ }
+
+ @Override
+ public int getCenterChunkX() {
+ return centerChunkX;
+ }
+
+ @Override
+ public int getCenterChunkZ() {
+ return centerChunkZ;
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java b/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java
+++ b/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java
@@ -0,0 +0,0 @@ public class CustomChunkGenerator extends InternalChunkGenerator {
for (BlockPos lightPosition : craftData.getLights()) {
((ProtoChunk) chunk).addLight(new BlockPos((x << 4) + lightPosition.getX(), lightPosition.getY(), (z << 4) + lightPosition.getZ())); // PAIL rename addLightBlock
}
+
+ // Paper start
+ io.papermc.paper.world.generation.CraftProtoWorld protoWorld = new io.papermc.paper.world.generation.CraftProtoWorld(region);
+ generator.generateDecorations(protoWorld);
+ protoWorld.clearReference(); // make sure people dont try to use the ProtoWorld after we're done with it.
+ // Paper end
}
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java
@@ -0,0 +0,0 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta
@Override
public BlockState getBlockState() {
- Material stateMaterial = (this.material != Material.SHIELD) ? this.material : CraftMetaBlockState.shieldToBannerHack(this.blockEntityTag); // Only actually used for jigsaws
- if (this.blockEntityTag != null) {
- switch (this.material) {
+ // Paper start
+ return createBlockState(this.material, this.blockEntityTag);
+ }
+ public static BlockState createBlockState(Material material, CompoundTag blockEntityTag) {
+ Material stateMaterial = (material != Material.SHIELD) ? material : CraftMetaBlockState.shieldToBannerHack(blockEntityTag); // Only actually used for jigsaws
+ if (blockEntityTag != null) {
+ switch (material) {
+ // Paper end
case SHIELD:
- this.blockEntityTag.putString("id", "banner");
+ blockEntityTag.putString("id", "banner"); // Paper
break;
case SHULKER_BOX:
case WHITE_SHULKER_BOX:
@@ -0,0 +0,0 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta
case GREEN_SHULKER_BOX:
case RED_SHULKER_BOX:
case BLACK_SHULKER_BOX:
- this.blockEntityTag.putString("id", "shulker_box");
+ blockEntityTag.putString("id", "shulker_box"); // Paper
break;
case BEE_NEST:
case BEEHIVE:
- this.blockEntityTag.putString("id", "beehive");
+ blockEntityTag.putString("id", "beehive"); // Paper
break;
}
}

View File

@@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 12 Mar 2021 19:22:21 -0800
Subject: [PATCH] Adds PlayerArmSwingEvent
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
}
// Arm swing animation
- PlayerAnimationEvent event = new PlayerAnimationEvent(this.getCraftPlayer());
+ io.papermc.paper.event.player.PlayerArmSwingEvent event = new io.papermc.paper.event.player.PlayerArmSwingEvent(this.getCraftPlayer(), packet.getHand() == InteractionHand.MAIN_HAND ? org.bukkit.inventory.EquipmentSlot.HAND : org.bukkit.inventory.EquipmentSlot.OFF_HAND); // Paper
this.cserver.getPluginManager().callEvent(event);
if (event.isCancelled()) return;

View File

@@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
Date: Tue, 22 Jun 2021 19:58:53 +0100
Subject: [PATCH] Ensure disconnect for book edit is called on main
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
// Paper end
// CraftBukkit start
if (this.lastBookTick + 20 > MinecraftServer.currentTick) {
- this.disconnect("Book edited too quickly!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause
+ server.scheduleOnMain(() -> this.disconnect("Book edited too quickly!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION)); // Paper - kick event cause // Paper - Also ensure this is called on main
return;
}
this.lastBookTick = MinecraftServer.currentTick;

View File

@@ -1,35 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sun, 20 Jun 2021 21:55:59 -0700
Subject: [PATCH] Fix PlayerDropItemEvent using wrong item
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
if (retainOwnership) {
if (!itemstack1.isEmpty()) {
- this.awardStat(Stats.ITEM_DROPPED.get(itemstack1.getItem()), stack.getCount());
+ this.awardStat(Stats.ITEM_DROPPED.get(itemstack1.getItem()), itemstack1.getCount()); // Paper
}
this.awardStat(Stats.DROP);
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
}
double d0 = this.getEyeY() - 0.30000001192092896D;
+ // Paper start
+ ItemStack tmp = stack.copy();
+ stack.setCount(0);
+ stack = tmp;
+ // Paper end
ItemEntity entityitem = new ItemEntity(this.level, this.getX(), d0, this.getZ(), stack);
entityitem.setPickUpDelay(40);

View File

@@ -1,52 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Thu, 20 May 2021 20:40:53 -0700
Subject: [PATCH] Fix PotionSplashEvent for water splash potions
Fixes SPIGOT-6221: https://hub.spigotmc.org/jira/projects/SPIGOT/issues/SPIGOT-6221
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
@@ -0,0 +0,0 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
private void applyWater() {
AABB axisalignedbb = this.getBoundingBox().inflate(4.0D, 2.0D, 4.0D);
List<net.minecraft.world.entity.LivingEntity> list = this.level.getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb, ThrownPotion.WATER_SENSITIVE);
+ Map<LivingEntity, Double> affected = new HashMap<>(); // Paper
if (!list.isEmpty()) {
Iterator iterator = list.iterator();
@@ -0,0 +0,0 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
double d0 = this.distanceToSqr(entityliving);
if (d0 < 16.0D && entityliving.isSensitiveToWater()) {
- entityliving.hurt(DamageSource.indirectMagic(entityliving, this.getOwner()), 1.0F);
+ // Paper start
+ double intensity = 1.0D - Math.sqrt(d0) / 4.0D;
+ affected.put(entityliving.getBukkitLivingEntity(), intensity);
+ // entityliving.damageEntity(DamageSource.c(entityliving, this.getShooter()), 1.0F); // Paper - moved down
}
}
}
+ org.bukkit.event.entity.PotionSplashEvent event = CraftEventFactory.callPotionSplashEvent(this, affected);
+ if (!event.isCancelled()) {
+ for (LivingEntity affectedEntity : event.getAffectedEntities()) {
+ net.minecraft.world.entity.LivingEntity entityliving = ((CraftLivingEntity) affectedEntity).getHandle();
+ entityliving.hurt(DamageSource.indirectMagic(entityliving, this.getOwner()), 1.0F);
+ }
+ }
+ // Paper end
+
List<Axolotl> list1 = this.level.getEntitiesOfClass(Axolotl.class, axisalignedbb);
Iterator iterator1 = list1.iterator();
@@ -0,0 +0,0 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
double d0 = this.distanceToSqr(entityliving);
if (d0 < 16.0D) {
+ // Paper - diff on change, used when calling the splash event for water splash potions
double d1 = 1.0D - Math.sqrt(d0) / 4.0D;
if (entityliving == entity) {

View File

@@ -1,141 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 9 Jul 2021 13:50:48 -0700
Subject: [PATCH] Fix commands from signs not firing command events
This patch changes sign command logic so that `run_command` click events:
- are logged to the console
- fire PlayerCommandPreprocessEvent
- work with double-slash commands like `//wand`
- sends failure messages to the player who clicked the sign
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
private void fixInvulnerableEndCrystalExploit() {
fixInvulnerableEndCrystalExploit = getBoolean("unsupported-settings.fix-invulnerable-end-crystal-exploit", fixInvulnerableEndCrystalExploit);
}
+
+ public boolean showSignClickCommandFailureMessagesToPlayer = false;
+ private void showSignClickCommandFailureMessagesToPlayer() {
+ showSignClickCommandFailureMessagesToPlayer = getBoolean("show-sign-click-command-failure-msgs-to-player", showSignClickCommandFailureMessagesToPlayer);
+ }
}
diff --git a/src/main/java/io/papermc/paper/commands/DelegatingCommandSource.java b/src/main/java/io/papermc/paper/commands/DelegatingCommandSource.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/io/papermc/paper/commands/DelegatingCommandSource.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.commands;
+
+import net.minecraft.commands.CommandSource;
+import net.minecraft.commands.CommandSourceStack;
+import net.minecraft.network.chat.Component;
+import org.bukkit.command.CommandSender;
+
+import java.util.UUID;
+
+public class DelegatingCommandSource implements CommandSource {
+
+ private final CommandSource delegate;
+
+ public DelegatingCommandSource(CommandSource delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void sendMessage(Component message, UUID sender) {
+ delegate.sendMessage(message, sender);
+ }
+
+ @Override
+ public boolean acceptsSuccess() {
+ return delegate.acceptsSuccess();
+ }
+
+ @Override
+ public boolean acceptsFailure() {
+ return delegate.acceptsFailure();
+ }
+
+ @Override
+ public boolean shouldInformAdmins() {
+ return delegate.shouldInformAdmins();
+ }
+
+ @Override
+ public CommandSender getBukkitSender(CommandSourceStack wrapper) {
+ return delegate.getBukkitSender(wrapper);
+ }
+}
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
@@ -0,0 +0,0 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
private boolean renderMessagedFiltered;
private DyeColor color;
private boolean hasGlowingText;
+ private static final org.apache.logging.log4j.Logger LOGGER = org.apache.logging.log4j.LogManager.getLogger();
public SignBlockEntity(BlockPos pos, BlockState state) {
super(BlockEntityType.SIGN, pos, state);
@@ -0,0 +0,0 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
ClickEvent chatclickable = chatmodifier.getClickEvent();
if (chatclickable != null && chatclickable.getAction() == ClickEvent.Action.RUN_COMMAND) {
- player.getServer().getCommands().performCommand(this.createCommandSourceStack(player), chatclickable.getValue());
+ // Paper start
+ String command = chatclickable.getValue().startsWith("/") ? chatclickable.getValue() : "/" + chatclickable.getValue();
+ if (org.spigotmc.SpigotConfig.logCommands) {
+ LOGGER.info("{} issued server command: {}", player.getScoreboardName(), command);
+ }
+ io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent event = new io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent(player.getBukkitEntity(), command, new org.bukkit.craftbukkit.util.LazyPlayerSet(player.getServer()), (org.bukkit.block.Sign) net.minecraft.server.MCUtil.toBukkitBlock(this.level, this.worldPosition).getState());
+ if (!event.callEvent()) {
+ return false;
+ }
+ player.getServer().getCommands().performCommand(this.createCommandSourceStack(((org.bukkit.craftbukkit.entity.CraftPlayer) event.getPlayer()).getHandle()), event.getMessage());
+ // Paper end
}
}
@@ -0,0 +0,0 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
String s = player == null ? "Sign" : player.getName().getString();
Object object = player == null ? new TextComponent("Sign") : player.getDisplayName();
+ // Paper start - send messages back to the player
+ CommandSource commandSource = this.level.paperConfig.showSignClickCommandFailureMessagesToPlayer ? new io.papermc.paper.commands.DelegatingCommandSource(this) {
+ @Override
+ public void sendMessage(net.minecraft.network.chat.Component message, java.util.UUID sender) {
+ player.sendMessage(message, sender);
+ }
+
+ @Override
+ public boolean acceptsFailure() {
+ return true;
+ }
+ } : this;
+ // Paper end
// CraftBukkit - this
- return new CommandSourceStack(this, Vec3.atCenterOf((Vec3i) this.worldPosition), Vec2.ZERO, (ServerLevel) this.level, 2, s, (Component) object, this.level.getServer(), player);
+ return new CommandSourceStack(commandSource, Vec3.atCenterOf((Vec3i) this.worldPosition), Vec2.ZERO, (ServerLevel) this.level, 2, s, (Component) object, this.level.getServer(), player); // Paper
}
public DyeColor getColor() {
diff --git a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
+++ b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
@@ -0,0 +0,0 @@ public class BukkitCommandWrapper implements com.mojang.brigadier.Command<Comman
@Override
public int run(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
- return this.server.dispatchCommand(context.getSource().getBukkitSender(), context.getInput()) ? 1 : 0;
+ return this.server.dispatchCommand(context.getSource().getBukkitSender(), context.getRange().get(context.getInput())) ? 1 : 0; // Paper - actually use the StringRange from context
}
@Override

View File

@@ -1,87 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <spottedleaf@users.noreply.github.com>
Date: Fri, 4 Jun 2021 17:06:52 -0400
Subject: [PATCH] Fix dangerous end portal logic
End portals could teleport entities during move calls. Stupid
logic given the caller will never expect that kind of thing,
and will result in all kinds of dupes.
Move the tick logic into the post tick, where portaling was
designed to happen in the first place.
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
}
// Paper end - optimise entity tracking
+ // Paper start - make end portalling safe
+ public BlockPos portalBlock;
+ public ServerLevel portalWorld;
+ public void tickEndPortal() {
+ BlockPos pos = this.portalBlock;
+ ServerLevel world = this.portalWorld;
+ this.portalBlock = null;
+ this.portalWorld = null;
+
+ if (pos == null || world == null || world != this.level) {
+ return;
+ }
+
+ if (this.isPassenger() || this.isVehicle() || !this.canChangeDimensions() || this.isRemoved() || !this.valid || !this.isAlive()) {
+ return;
+ }
+
+ ResourceKey<Level> resourcekey = world.getTypeKey() == DimensionType.END_LOCATION ? Level.OVERWORLD : Level.END; // CraftBukkit - SPIGOT-6152: send back to main overworld in custom ends
+ ServerLevel worldserver = world.getServer().getLevel(resourcekey);
+
+ org.bukkit.event.entity.EntityPortalEnterEvent event = new org.bukkit.event.entity.EntityPortalEnterEvent(this.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()));
+ event.callEvent();
+
+ if (this instanceof ServerPlayer) {
+ ((ServerPlayer)this).changeDimension(worldserver, PlayerTeleportEvent.TeleportCause.END_PORTAL);
+ return;
+ }
+ this.teleportTo(worldserver, null);
+ }
+ // Paper end - make end portalling safe
+
public Entity(EntityType<?> type, Level world) {
this.id = Entity.ENTITY_COUNTER.incrementAndGet();
this.passengers = ImmutableList.of();
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
}
this.processPortalCooldown();
+ this.tickEndPortal(); // Paper - make end portalling safe
}
}
diff --git a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
@@ -0,0 +0,0 @@ public class EndPortalBlock extends BaseEntityBlock {
// return; // CraftBukkit - always fire event in case plugins wish to change it
}
- // CraftBukkit start - Entity in portal
- EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()));
- world.getCraftServer().getPluginManager().callEvent(event);
-
- if (entity instanceof ServerPlayer) {
- ((ServerPlayer) entity).changeDimension(worldserver, PlayerTeleportEvent.TeleportCause.END_PORTAL);
- return;
- }
- // CraftBukkit end
- entity.changeDimension(worldserver);
+ // Paper start - move all of this logic into portal tick
+ entity.portalWorld = ((ServerLevel)world);
+ entity.portalBlock = pos.immutable();
+ // Paper end - move all of this logic into portal tick
}
}

View File

@@ -1,72 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 10 May 2021 15:46:57 -0700
Subject: [PATCH] Fix incorrect status dataconverter for pre 1.13 chunks
Vanilla was setting non-populated OR non-lit chunks to empty, but
really this is just completely wrong. It should be set to "carved"
at minmum, because pre 1.13 chunks went through 3 distinct stages
of generation: carving, population, and lighting - in this order.
There is no "empty" status, because a chunk was simply carved
or it didn't exist. So mapping any chunk data to empty is simply
invalid.
If the chunk is terrain populated, then obviously it must be at
minmum "decorated." If the chunk is lit and populated, then it is marked
"mobs_spawned" (which is what Vanilla is doing, and this is the last
stage before moving to full so it looks correct).
So now here is a table representing the new status conversion:
Chunk is lit Chunk is populated Vanilla
F F empty
T F empty
F T empty
T T mobs_spawned
Chunk is lit Chunk is populated Paper
F F carved
T F carved
F T decorated
T T mobs_spawned
This should fix some problems converting old data, as the
changes here are going to prevent the chunk from being regenerated
incorrectly.
diff --git a/src/main/java/net/minecraft/util/datafix/fixes/ChunkToProtochunkFix.java b/src/main/java/net/minecraft/util/datafix/fixes/ChunkToProtochunkFix.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/util/datafix/fixes/ChunkToProtochunkFix.java
+++ b/src/main/java/net/minecraft/util/datafix/fixes/ChunkToProtochunkFix.java
@@ -0,0 +0,0 @@ public class ChunkToProtochunkFix extends DataFix {
OpticFinder<?> opticFinder2 = DSL.fieldFinder("TileTicks", type5);
return TypeRewriteRule.seq(this.fixTypeEverywhereTyped("ChunkToProtoChunkFix", type, this.getOutputSchema().getType(References.CHUNK), (typed) -> {
return typed.updateTyped(opticFinder, type4, (typedx) -> {
- Optional<? extends Stream<? extends Dynamic<?>>> optional = typedx.getOptionalTyped(opticFinder2).flatMap((typed) -> {
- return typed.write().result();
+ Optional<? extends Stream<? extends Dynamic<?>>> optional = typedx.getOptionalTyped(opticFinder2).flatMap((it) -> { // Paper - remap fix
+ return it.write().result(); // Paper - remap fix
}).flatMap((dynamicx) -> {
return dynamicx.asStreamOpt().result();
});
Dynamic<?> dynamic = typedx.get(DSL.remainderFinder());
- boolean bl = dynamic.get("TerrainPopulated").asBoolean(false) && (!dynamic.get("LightPopulated").asNumber().result().isPresent() || dynamic.get("LightPopulated").asBoolean(false));
- dynamic = dynamic.set("Status", dynamic.createString(bl ? "mobs_spawned" : "empty"));
+ // Paper start - fix incorrect status conversion
+ // Vanilla is setting chunks to incorrect status here, they should be using at minimum carved.
+ // for populated chunks, it should be at minimum decorated
+ // and for lit and populated, mobs_spawned is correct (technically mobs_spawned should be for populated,
+ // but if it's not lit then it can't be set above lit)
+ final boolean terrainPopulated = dynamic.get("TerrainPopulated").asBoolean(false);
+ final boolean lightPopulated = dynamic.get("LightPopulated").asBoolean(false) || dynamic.get("LightPopulated").asNumber().result().isPresent();
+ final String newStatus = !terrainPopulated ? "carved" : (lightPopulated ? "mobs_spawned" : "decorated");
+
+ dynamic = dynamic.set("Status", dynamic.createString(newStatus));
+ // Paper end - fix incorrect status conversion
dynamic = dynamic.set("hasLegacyStructureData", dynamic.createBoolean(true));
Dynamic<?> dynamic3;
- if (bl) {
+ if (true) { // Paper - fix incorrect status conversion
Optional<ByteBuffer> optional2 = dynamic.get("Biomes").asByteBufferOpt().result();
if (optional2.isPresent()) {
ByteBuffer byteBuffer = optional2.get();

View File

@@ -1,80 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Max Lee <max@themoep.de>
Date: Thu, 27 May 2021 14:52:30 -0700
Subject: [PATCH] Fix invulnerable end crystals
MC-108513
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
private void fixItemsMergingThroughWalls() {
fixItemsMergingThroughWalls = getBoolean("fix-items-merging-through-walls", fixItemsMergingThroughWalls);
}
+
+ public boolean fixInvulnerableEndCrystalExploit = true;
+ private void fixInvulnerableEndCrystalExploit() {
+ fixInvulnerableEndCrystalExploit = getBoolean("unsupported-settings.fix-invulnerable-end-crystal-exploit", fixInvulnerableEndCrystalExploit);
+ }
}
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
@@ -0,0 +0,0 @@ public class EndCrystal extends Entity {
private static final EntityDataAccessor<Optional<BlockPos>> DATA_BEAM_TARGET = SynchedEntityData.defineId(EndCrystal.class, EntityDataSerializers.OPTIONAL_BLOCK_POS);
private static final EntityDataAccessor<Boolean> DATA_SHOW_BOTTOM = SynchedEntityData.defineId(EndCrystal.class, EntityDataSerializers.BOOLEAN);
public int time;
+ public boolean generatedByDragonFight = false; // Paper - Fix invulnerable end crystals
public EndCrystal(EntityType<? extends EndCrystal> type, Level world) {
super(type, world);
@@ -0,0 +0,0 @@ public class EndCrystal extends Entity {
}
// CraftBukkit end
}
+ // Paper start - Fix invulnerable end crystals
+ if (this.level.paperConfig.fixInvulnerableEndCrystalExploit && this.generatedByDragonFight && this.isInvulnerable()) {
+ if (!java.util.Objects.equals(((ServerLevel) this.level).uuid, this.getOriginWorld())
+ || ((ServerLevel) this.level).dragonFight() == null
+ || ((ServerLevel) this.level).dragonFight().respawnStage == null
+ || ((ServerLevel) this.level).dragonFight().respawnStage.ordinal() > net.minecraft.world.level.dimension.end.DragonRespawnAnimation.SUMMONING_DRAGON.ordinal()) {
+ this.setInvulnerable(false);
+ this.setBeamTarget(null);
+ }
+ }
+ // Paper end
}
}
@@ -0,0 +0,0 @@ public class EndCrystal extends Entity {
}
nbt.putBoolean("ShowBottom", this.showsBottom());
+ if (this.generatedByDragonFight) nbt.putBoolean("Paper.GeneratedByDragonFight", this.generatedByDragonFight); // Paper - Fix invulnerable end crystals
}
@Override
@@ -0,0 +0,0 @@ public class EndCrystal extends Entity {
if (nbt.contains("ShowBottom", 1)) {
this.setShowBottom(nbt.getBoolean("ShowBottom"));
}
+ if (nbt.contains("Paper.GeneratedByDragonFight", 1)) this.generatedByDragonFight = nbt.getBoolean("Paper.GeneratedByDragonFight"); // Paper - Fix invulnerable end crystals
}
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/SpikeFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/SpikeFeature.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/SpikeFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/SpikeFeature.java
@@ -0,0 +0,0 @@ public class SpikeFeature extends Feature<SpikeConfiguration> {
endCrystal.setBeamTarget(config.getCrystalBeamTarget());
endCrystal.setInvulnerable(config.isCrystalInvulnerable());
endCrystal.moveTo((double)spike.getCenterX() + 0.5D, (double)(spike.getHeight() + 1), (double)spike.getCenterZ() + 0.5D, random.nextFloat() * 360.0F, 0.0F);
+ endCrystal.generatedByDragonFight = true; // Paper
world.addFreshEntity(endCrystal);
this.setBlock(world, new BlockPos(spike.getCenterX(), spike.getHeight(), spike.getCenterZ()), Blocks.BEDROCK.defaultBlockState());
}

View File

@@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Mon, 28 Jun 2021 18:16:52 -0700
Subject: [PATCH] Fix return value of Block#applyBoneMeal always being false
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -0,0 +0,0 @@ public class CraftBlock implements Block {
Direction direction = CraftBlock.blockFaceToNotch(face);
UseOnContext context = new UseOnContext(this.getCraftWorld().getHandle(), null, InteractionHand.MAIN_HAND, Items.BONE_MEAL.getDefaultInstance(), new BlockHitResult(Vec3.ZERO, direction, this.getPosition(), false));
- return BoneMealItem.applyBonemeal(context) == InteractionResult.SUCCESS;
+ return BoneMealItem.applyBonemeal(context) == InteractionResult.CONSUME; // Paper - CONSUME is returned on success server-side (see BoneMealItem.applyBoneMeal and InteractionResult.sidedSuccess(boolean))
}
@Override

View File

@@ -1,76 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: TwoLeggedCat <80929284+TwoLeggedCat@users.noreply.github.com>
Date: Sat, 29 May 2021 14:33:25 -0500
Subject: [PATCH] Line Of Sight Changes
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
Vec3 vec3d = new Vec3(this.getX(), this.getEyeY(), this.getZ());
Vec3 vec3d1 = new Vec3(entity.getX(), entity.getEyeY(), entity.getZ());
- return vec3d1.distanceTo(vec3d) > 128.0D ? false : this.level.clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS;
+ // Paper - diff on change - used in CraftLivingEntity#hasLineOfSight(Location) and CraftWorld#lineOfSightExists
+ return vec3d1.distanceToSqr(vec3d) > 128D * 128D ? false : this.level.clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS; // Paper - use distanceToSqr
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
public io.papermc.paper.world.MoonPhase getMoonPhase() {
return io.papermc.paper.world.MoonPhase.getPhase(getFullTime() / 24000L);
}
+
+ @Override
+ public boolean lineOfSightExists(Location from, Location to) {
+ Validate.notNull(from, "from parameter in lineOfSightExists cannot be null");
+ Validate.notNull(to, "to parameter in lineOfSightExists cannot be null");
+ if (from.getWorld() != to.getWorld()) return false;
+ Vec3 vec3d = new Vec3(from.getX(), from.getY(), from.getZ());
+ Vec3 vec3d1 = new Vec3(to.getX(), to.getY(), to.getZ());
+ if (vec3d1.distanceToSqr(vec3d) > 128D * 128D) return false; //Return early if the distance is greater than 128 blocks
+
+ return this.getHandle().clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, null)).getType() == HitResult.Type.MISS;
+ }
// Paper end
private static final Random rand = new Random();
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -0,0 +0,0 @@ import net.minecraft.world.entity.projectile.ThrownEgg;
import net.minecraft.world.entity.projectile.ThrownEnderpearl;
import net.minecraft.world.entity.projectile.ThrownExperienceBottle;
import net.minecraft.world.entity.projectile.ThrownTrident;
+import net.minecraft.world.level.ClipContext;
+import net.minecraft.world.phys.HitResult;
+import net.minecraft.world.phys.Vec3;
import org.apache.commons.lang.Validate;
import org.bukkit.FluidCollisionMode;
import org.bukkit.Location;
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
return this.getHandle().hasLineOfSight(((CraftEntity) other).getHandle());
}
+ // Paper start
+ @Override
+ public boolean hasLineOfSight(Location loc) {
+ if (this.getHandle().level != ((CraftWorld) loc.getWorld()).getHandle()) return false;
+ Vec3 vec3d = new Vec3(this.getHandle().getX(), this.getHandle().getEyeY(), this.getHandle().getZ());
+ Vec3 vec3d1 = new Vec3(loc.getX(), loc.getY(), loc.getZ());
+ if (vec3d1.distanceToSqr(vec3d) > 128D * 128D) return false; //Return early if the distance is greater than 128 blocks
+
+ return this.getHandle().level.clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this.getHandle())).getType() == HitResult.Type.MISS;
+ }
+ // Paper end
+
@Override
public boolean getRemoveWhenFarAway() {
return this.getHandle() instanceof Mob && !((Mob) this.getHandle()).isPersistenceRequired();

View File

@@ -1,83 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 4 Jun 2021 12:12:35 -0700
Subject: [PATCH] Make item validations configurable
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -0,0 +0,0 @@ public class PaperConfig {
enableBrigadierConsoleHighlighting = getBoolean("settings.console.enable-brigadier-highlighting", enableBrigadierConsoleHighlighting);
enableBrigadierConsoleCompletions = getBoolean("settings.console.enable-brigadier-completions", enableBrigadierConsoleCompletions);
}
+
+ public static int itemValidationDisplayNameLength = 8192;
+ public static int itemValidationLocNameLength = 8192;
+ public static int itemValidationLoreLineLength = 8192;
+ public static int itemValidationBookTitleLength = 8192;
+ public static int itemValidationBookAuthorLength = 8192;
+ public static int itemValidationBookPageLength = 16384;
+ private static void itemValidationSettings() {
+ itemValidationDisplayNameLength = getInt("settings.item-validation.display-name", itemValidationDisplayNameLength);
+ itemValidationLocNameLength = getInt("settings.item-validation.loc-name", itemValidationLocNameLength);
+ itemValidationLoreLineLength = getInt("settings.item-validation.lore-line", itemValidationLoreLineLength);
+ itemValidationBookTitleLength = getInt("settings.item-validation.book.title", itemValidationBookTitleLength);
+ itemValidationBookAuthorLength = getInt("settings.item-validation.book.author", itemValidationBookAuthorLength);
+ itemValidationBookPageLength = getInt("settings.item-validation.book.page", itemValidationBookPageLength);
+ }
}
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java
@@ -0,0 +0,0 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta {
super(tag);
if (tag.contains(BOOK_TITLE.NBT)) {
- this.title = limit( tag.getString(BOOK_TITLE.NBT), 8192 ); // Spigot
+ this.title = limit( tag.getString(BOOK_TITLE.NBT), com.destroystokyo.paper.PaperConfig.itemValidationBookTitleLength); // Spigot // Paper - make configurable
}
if (tag.contains(BOOK_AUTHOR.NBT)) {
- this.author = limit( tag.getString(BOOK_AUTHOR.NBT), 8192 ); // Spigot
+ this.author = limit( tag.getString(BOOK_AUTHOR.NBT), com.destroystokyo.paper.PaperConfig.itemValidationBookAuthorLength ); // Spigot // Paper - make configurable
}
if (tag.contains(RESOLVED.NBT)) {
@@ -0,0 +0,0 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta {
} else {
page = this.validatePage(page);
}
- this.pages.add( limit( page, 16384 ) ); // Spigot
+ this.pages.add( limit( page, com.destroystokyo.paper.PaperConfig.itemValidationBookPageLength ) ); // Spigot // Paper - make configurable
}
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
CompoundTag display = tag.getCompound(DISPLAY.NBT);
if (display.contains(NAME.NBT)) {
- this.displayName = limit( display.getString(NAME.NBT), 8192 ); // Spigot
+ this.displayName = limit( display.getString(NAME.NBT), com.destroystokyo.paper.PaperConfig.itemValidationDisplayNameLength ); // Spigot // Paper - make configurable
}
if (display.contains(LOCNAME.NBT)) {
- this.locName = limit( display.getString(LOCNAME.NBT), 8192 ); // Spigot
+ this.locName = limit( display.getString(LOCNAME.NBT), com.destroystokyo.paper.PaperConfig.itemValidationLocNameLength ); // Spigot // Paper - make configurable
}
if (display.contains(LORE.NBT)) {
ListTag list = display.getList(LORE.NBT, CraftMagicNumbers.NBT.TAG_STRING);
this.lore = new ArrayList<String>(list.size());
for (int index = 0; index < list.size(); index++) {
- String line = limit( list.getString(index), 8192 ); // Spigot
+ String line = limit( list.getString(index), com.destroystokyo.paper.PaperConfig.itemValidationLoreLineLength ); // Spigot // Paper - make configurable
this.lore.add(line);
}
}

View File

@@ -1,158 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Mon, 21 Jun 2021 23:56:07 -0400
Subject: [PATCH] Missing Entity Behavior API
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
@@ -0,0 +0,0 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
}
+ // Paper Start - Horse API
+ public void setMouthOpen(boolean open) {
+ this.setFlag(FLAG_OPEN_MOUTH, open);
+ }
+ public boolean isMouthOpen() {
+ return this.getFlag(FLAG_OPEN_MOUTH);
+ }
+ // Paper End - Horse API
private void openMouth() {
if (!this.level.isClientSide) {
this.mouthCounter = 1;
@@ -0,0 +0,0 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
this.setFlag(16, eatingGrass);
}
+ // Paper Start - Horse API
+ public void setForceStanding(boolean standing) {
+ this.setFlag(FLAG_STANDING, standing);
+ }
+ // Paper End - Horse API
public void setStanding(boolean angry) {
if (angry) {
this.setEating(false);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
@@ -0,0 +0,0 @@ public abstract class CraftAbstractHorse extends CraftAnimals implements Abstrac
public AbstractHorseInventory getInventory() {
return new CraftSaddledInventory(getHandle().inventory);
}
+
+ // Paper start - Horse API
+ @Override
+ public boolean isEatingGrass() {
+ return this.getHandle().isEating();
+ }
+
+ @Override
+ public void setEatingGrass(boolean eating) {
+ this.getHandle().setEating(eating);
+ }
+
+ @Override
+ public boolean isRearing() {
+ return this.getHandle().isStanding();
+ }
+
+ @Override
+ public void setRearing(boolean rearing) {
+ this.getHandle().setForceStanding(rearing);
+ }
+
+ @Override
+ public boolean isEating() {
+ return this.getHandle().isMouthOpen();
+ }
+
+ @Override
+ public void setEating(boolean eating) {
+ this.getHandle().setMouthOpen(eating);
+ }
+ // Paper end - Horse API
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java
@@ -0,0 +0,0 @@ public class CraftCat extends CraftTameableAnimal implements Cat {
public void setCollarColor(DyeColor color) {
this.getHandle().setCollarColor(net.minecraft.world.item.DyeColor.byId(color.getWoolData()));
}
+ // Paper Start - More cat api
+ @Override
+ public void setLyingDown(boolean lyingDown) {
+ this.getHandle().setLying(lyingDown);
+ }
+
+ @Override
+ public boolean isLyingDown() {
+ return this.getHandle().isLying();
+ }
+
+ @Override
+ public void setHeadUp(boolean headUp) {
+ this.getHandle().setRelaxStateOne(headUp);
+ }
+
+ @Override
+ public boolean isHeadUp() {
+ return this.getHandle().isRelaxStateOne();
+ }
+ // Paper End - More cat api
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java
@@ -0,0 +0,0 @@ public class CraftFox extends CraftAnimals implements Fox {
this.getHandle().getEntityData().set(net.minecraft.world.entity.animal.Fox.DATA_TRUSTED_ID_1, player == null ? Optional.empty() : Optional.of(player.getUniqueId()));
}
+ // Paper start - Add more fox behavior API
+ @Override
+ public void setInterested(boolean interested) {
+ this.getHandle().setIsInterested(interested);
+ }
+
+ @Override
+ public boolean isInterested() {
+ return this.getHandle().isInterested();
+ }
+
+ @Override
+ public void setLeaping(boolean leaping) {
+ this.getHandle().setIsPouncing(leaping);
+ }
+
+ @Override
+ public boolean isLeaping() {
+ return this.getHandle().isPouncing();
+ }
+
+ @Override
+ public void setDefending(boolean defending) {
+ this.getHandle().setDefending(defending);
+ }
+
+ @Override
+ public boolean isDefending() {
+ return this.getHandle().isDefending();
+ }
+
+ @Override
+ public void setFaceplanted(boolean faceplanted) {
+ this.getHandle().setFaceplanted(faceplanted);
+ }
+
+ @Override
+ public boolean isFaceplanted() {
+ return this.getHandle().isFaceplanted();
+ }
+ // Paper end - Add more fox behavior API
}

View File

@@ -1,57 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Wed, 12 Sep 2018 21:47:01 -0400
Subject: [PATCH] Optimize Biome Mob Lookups for Mob Spawning
Uses an EnumMap as well as a Set paired List for O(1) contains calls.
diff --git a/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java b/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java
+++ b/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java
@@ -0,0 +0,0 @@ public class MobSpawnSettings {
}
public static class Builder {
- private final Map<MobCategory, List<MobSpawnSettings.SpawnerData>> spawners = Stream.of(MobCategory.values()).collect(ImmutableMap.toImmutableMap((mobCategory) -> {
+ // Paper start - keep track of data in a pair set to give O(1) contains calls - we have to hook removals incase plugins mess with it
+ public static class MobList extends java.util.ArrayList<MobSpawnSettings.SpawnerData> {
+ java.util.Set<MobSpawnSettings.SpawnerData> biomes = new java.util.HashSet<>();
+
+ @Override
+ public boolean contains(Object o) {
+ return biomes.contains(o);
+ }
+
+ @Override
+ public boolean add(MobSpawnSettings.SpawnerData BiomeSettingsMobs) {
+ biomes.add(BiomeSettingsMobs);
+ return super.add(BiomeSettingsMobs);
+ }
+
+ @Override
+ public MobSpawnSettings.SpawnerData remove(int index) {
+ MobSpawnSettings.SpawnerData removed = super.remove(index);
+ if (removed != null) {
+ biomes.remove(removed);
+ }
+ return removed;
+ }
+
+ @Override
+ public void clear() {
+ biomes.clear();
+ super.clear();
+ }
+ }
+ // use toImmutableEnumMap collector
+ private final Map<MobCategory, List<MobSpawnSettings.SpawnerData>> spawners = (Map) Stream.of(MobCategory.values()).collect(Maps.toImmutableEnumMap((mobCategory) -> {
return mobCategory;
}, (mobCategory) -> {
- return Lists.newArrayList();
+ return new MobList(); // Use MobList instead of ArrayList
}));
+ // Paper end
private final Map<EntityType<?>, MobSpawnSettings.MobSpawnCost> mobSpawnCosts = Maps.newLinkedHashMap();
private float creatureGenerationProbability = 0.1F;
private boolean playerCanSpawn;

View File

@@ -1,62 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 8 Jul 2019 00:13:36 -0700
Subject: [PATCH] Use getChunkIfLoadedImmediately in places
This prevents us from hitting chunk loads for chunks at or less-than
ticket level 33 (yes getChunkIfLoaded will actually perform a chunk
load in that case).
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
@Override public LevelChunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI
- return this.chunkSource.getChunk(x, z, false);
+ return this.chunkSource.getChunkAtIfLoadedImmediately(x, z); // Paper
}
// Paper start
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
speed = this.player.getAbilities().walkingSpeed * 10f;
}
// Paper start - Prevent moving into unloaded chunks
- if (player.level.paperConfig.preventMovingIntoUnloadedChunks && (this.player.getX() != toX || this.player.getZ() != toZ) && !worldserver.hasChunk((int) Math.floor(toX) >> 4, (int) Math.floor(toZ) >> 4)) {
+ if (player.level.paperConfig.preventMovingIntoUnloadedChunks && (this.player.getX() != toX || this.player.getZ() != toZ) && worldserver.getChunkIfLoadedImmediately((int) Math.floor(toX) >> 4, (int) Math.floor(toZ) >> 4) == null) { // Paper - use getIfLoadedImmediately
this.internalTeleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot(), Collections.emptySet(), true);
return;
}
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
return (CraftServer) Bukkit.getServer();
}
+ // Paper start
+ @Override
+ public boolean hasChunk(int chunkX, int chunkZ) {
+ return ((ServerLevel) this).getChunkIfLoaded(chunkX, chunkZ) != null;
+ }
+ // Paper end
+
public ResourceKey<DimensionType> getTypeKey() {
return this.typeKey;
}
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
for (int l1 = j; l1 <= l; ++l1) {
for (int i2 = k; i2 <= i1; ++i2) {
- LevelChunk chunk = this.getChunkSource().getChunkNow(l1, i2);
+ LevelChunk chunk = (LevelChunk) this.getChunkIfLoadedImmediately(l1, i2); // Paper
if (chunk != null) {
for (int j2 = j1; j2 <= k1; ++j2) {

View File

@@ -1,72 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: chase <chasewhip20@gmail.com>
Date: Wed, 2 Dec 2020 22:43:39 -0800
Subject: [PATCH] add per world spawn limits
Taken from #2982. Credit to Chasewhip8
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.Vindicator;
import net.minecraft.world.entity.monster.Zombie;
import com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray.EngineMode;
+import net.minecraft.world.level.NaturalSpawner;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.spigotmc.SpigotWorldConfig;
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
set("despawn-ranges.soft", null);
set("despawn-ranges.hard", null);
+
+ set("spawn-limits.monsters", null);
+ set("spawn-limits.animals", null);
+ set("spawn-limits.water-animals", null);
+ set("spawn-limits.water-ambient", null);
}
if (needsSave) {
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
zombieVillagerInfectionChance = getDouble("zombie-villager-infection-chance", zombieVillagerInfectionChance);
}
+ public Reference2IntMap<MobCategory> perWorldSpawnLimits = new Reference2IntOpenHashMap<>(NaturalSpawner.SPAWNING_CATEGORIES.length);
+ private void perWorldSpawnLimits() {
+ perWorldSpawnLimits.defaultReturnValue(-1);
+ if (PaperConfig.version < 24) {
+ // ambient category already had correct name
+ perWorldSpawnLimits.put(MobCategory.MONSTER, getInt("spawn-limits.monsters", -1, false));
+ perWorldSpawnLimits.put(MobCategory.CREATURE, getInt("spawn-limits.animals", -1, false));
+ perWorldSpawnLimits.put(MobCategory.WATER_CREATURE, getInt("spawn-limits.water-animals", -1, false));
+ perWorldSpawnLimits.put(MobCategory.WATER_AMBIENT, getInt("spawn-limits.water-ambient", -1, false));
+ }
+ for (MobCategory value : NaturalSpawner.SPAWNING_CATEGORIES) {
+ perWorldSpawnLimits.put(value, getInt("spawn-limits." + value.getName(), perWorldSpawnLimits.getInt(value)));
+ }
+ }
+
public int lightQueueSize = 20;
private void lightQueueSize() {
lightQueueSize = getInt("light-queue-size", lightQueueSize);
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
this.biomeProvider = biomeProvider;
this.environment = env;
+ // Paper start - per world spawn limits
+ this.monsterSpawn = this.world.paperConfig.perWorldSpawnLimits.getInt(net.minecraft.world.entity.MobCategory.MONSTER);
+ this.animalSpawn = this.world.paperConfig.perWorldSpawnLimits.getInt(net.minecraft.world.entity.MobCategory.CREATURE);
+ this.waterAnimalSpawn = this.world.paperConfig.perWorldSpawnLimits.getInt(net.minecraft.world.entity.MobCategory.WATER_CREATURE);
+ this.waterAmbientSpawn = this.world.paperConfig.perWorldSpawnLimits.getInt(net.minecraft.world.entity.MobCategory.WATER_AMBIENT);
+ this.ambientSpawn = this.world.paperConfig.perWorldSpawnLimits.getInt(net.minecraft.world.entity.MobCategory.AMBIENT);
+ this.waterUndergroundCreatureSpawn = this.world.paperConfig.perWorldSpawnLimits.getInt(net.minecraft.world.entity.MobCategory.UNDERGROUND_WATER_CREATURE);
+ // Paper end
}
@Override