Compare commits
44
Commits
generators
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
026cc872ed
|
||
|
|
77b7b8a9a6
|
||
|
|
6ea42025a4 | ||
|
|
310f52293b | ||
|
|
c37b890c8b | ||
|
|
f0388e2f38 | ||
|
|
102c8bbc54 | ||
|
|
f4f275519f | ||
|
|
1a7288aa05 | ||
|
|
743346a5da | ||
|
|
e5d988df85 | ||
|
|
7afae7f465 | ||
|
|
3d13b11514 | ||
|
|
34c794dc51 | ||
|
|
2565497897 | ||
|
|
df96f8a0fa | ||
|
|
a2b0ff0644 | ||
|
|
43f37b1b5e | ||
|
|
20df25d3a5 | ||
|
|
2526fe063a | ||
|
|
8e69d981fa | ||
|
|
4519857817 | ||
|
|
ce30016218 | ||
|
|
a6ce734fd0 | ||
|
|
7a3d0c4e98 | ||
|
|
0a4eb8f3bb | ||
|
|
5538d24d72 | ||
|
|
a866e366b2 | ||
|
|
8de7e356fa | ||
|
|
1d5e5a57e9 | ||
|
|
b506626824 | ||
|
|
0a6e7435b3 | ||
|
|
9421f22372 | ||
|
|
f63dbeafde | ||
|
|
fc56c728c0 | ||
|
|
9b9f046f41 | ||
|
|
7f3d3591de | ||
|
|
a501c45918 | ||
|
|
ca2610904b | ||
|
|
b00875f86d | ||
|
|
5f2ee83ed4 | ||
|
|
1d9b399427 | ||
|
|
f12d33f04e | ||
|
|
9be4e07a3e |
No files matched your search
@@ -5,3 +5,4 @@ gradlew text eol=lf
|
||||
*.bat text eol=crlf
|
||||
|
||||
*.jar binary
|
||||
.gitea/CODEOWNERS linguist-detectable=false
|
||||
@@ -0,0 +1,3 @@
|
||||
# Pull requests request review from the eligible staff team(s).
|
||||
# One approval from either an Admin or Developer satisfies branch protection.
|
||||
* @trueog/Admins @trueog/Developers
|
||||
@@ -0,0 +1,29 @@
|
||||
package io.papermc.paper.event.packet;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
/**
|
||||
* Called when a {@code minecraft:client_tick_end} packet is received by the server.
|
||||
*/
|
||||
@NullMarked
|
||||
public class ClientTickEndEvent extends PlayerEvent {
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
@ApiStatus.Internal
|
||||
public ClientTickEndEvent(final Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
||||
@@ -2980,8 +2980,19 @@ public final class Bukkit {
|
||||
}
|
||||
// Paper end - Folia region threading API
|
||||
|
||||
/**
|
||||
* @deprecated All methods on this class have been deprecated, see the individual methods for replacements.
|
||||
*/
|
||||
@Deprecated(since = "1.21.4", forRemoval = true)
|
||||
@NotNull
|
||||
public static Server.Spigot spigot() {
|
||||
return server.spigot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restarts the server. If the server administrator has not configured restarting, the server will stop.
|
||||
*/
|
||||
public static void restart() {
|
||||
server.restart();
|
||||
}
|
||||
}
|
||||
@@ -83,14 +83,12 @@ public final class NamespacedKey implements net.kyori.adventure.key.Key, com.des
|
||||
* @see #NamespacedKey(Plugin, String)
|
||||
*/
|
||||
public NamespacedKey(@NotNull String namespace, @NotNull String key) {
|
||||
Preconditions.checkArgument(namespace != null && isValidNamespace(namespace), "Invalid namespace. Must be [a-z0-9._-]: %s", namespace);
|
||||
Preconditions.checkArgument(key != null && isValidKey(key), "Invalid key. Must be [a-z0-9/._-]: %s", key);
|
||||
|
||||
Preconditions.checkArgument(namespace != null, "Namespace cannot be null");
|
||||
Preconditions.checkArgument(key != null, "Key cannot be null");
|
||||
this.namespace = namespace;
|
||||
this.key = key;
|
||||
|
||||
String string = toString();
|
||||
Preconditions.checkArgument(string.length() <= Short.MAX_VALUE, "NamespacedKey must be less than 32768 characters", string); // Paper - Fix improper length validation
|
||||
this.validate();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,16 +106,17 @@ public final class NamespacedKey implements net.kyori.adventure.key.Key, com.des
|
||||
public NamespacedKey(@NotNull Plugin plugin, @NotNull String key) {
|
||||
Preconditions.checkArgument(plugin != null, "Plugin cannot be null");
|
||||
Preconditions.checkArgument(key != null, "Key cannot be null");
|
||||
|
||||
this.namespace = plugin.getName().toLowerCase(Locale.ROOT);
|
||||
this.key = key.toLowerCase(Locale.ROOT);
|
||||
|
||||
// Check validity after normalization
|
||||
this.validate();
|
||||
}
|
||||
|
||||
private void validate() {
|
||||
Preconditions.checkArgument(this.namespace.length() + 1 + this.key.length() <= Short.MAX_VALUE, "NamespacedKey must be less than 32768 characters");
|
||||
Preconditions.checkArgument(isValidNamespace(this.namespace), "Invalid namespace. Must be [a-z0-9._-]: %s", this.namespace);
|
||||
Preconditions.checkArgument(isValidKey(this.key), "Invalid key. Must be [a-z0-9/._-]: %s", this.key);
|
||||
|
||||
String string = toString();
|
||||
Preconditions.checkArgument(string.length() <= Short.MAX_VALUE, "NamespacedKey must be less than 32768 characters", string); // Paper - Fix improper length validation
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.bukkit;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import io.papermc.paper.datacomponent.DataComponentType;
|
||||
import io.papermc.paper.registry.RegistryAccess;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
@@ -63,7 +64,7 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(forRemoval = true, since = "1.21.4")
|
||||
private static <A extends Keyed> Registry<A> legacyRegistryFor(final Class<A> clazz) {
|
||||
return Objects.requireNonNull(RegistryAccess.registryAccess().getRegistry(clazz), "No registry present for " + clazz.getSimpleName() + ". This is a bug.");
|
||||
return Objects.requireNonNull(RegistryAccess.registryAccess().getRegistry(clazz), () -> "No registry present for " + clazz.getSimpleName() + ". This is a bug.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -297,6 +298,11 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
|
||||
return MemoryKey.values().iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return MemoryKey.values().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable MemoryKey get(final NamespacedKey key) {
|
||||
return MemoryKey.getByKey(key);
|
||||
@@ -536,6 +542,13 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
|
||||
return (namespacedKey != null) ? this.get(namespacedKey) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of the registry.
|
||||
*
|
||||
* @return the size of the registry
|
||||
*/
|
||||
int size();
|
||||
|
||||
@ApiStatus.Internal
|
||||
class SimpleRegistry<T extends Enum<T> & Keyed> extends NotARegistry<T> { // Paper - remove final
|
||||
|
||||
@@ -564,6 +577,11 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
|
||||
return this.map.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return this.map.values().iterator();
|
||||
@@ -584,6 +602,11 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
|
||||
return StreamSupport.stream(this.spliterator(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return Iterables.size(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamespacedKey getKey(final A value) {
|
||||
return value.getKey();
|
||||
|
||||
@@ -422,7 +422,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
* @param message MiniMessage content
|
||||
*/
|
||||
default void sendRichMessage(final @NotNull String message) {
|
||||
this.sendMessage(MiniMessage.miniMessage().deserialize(message));
|
||||
this.sendMessage(MiniMessage.miniMessage().deserialize(message, this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -435,7 +435,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
* @param resolvers resolvers to use
|
||||
*/
|
||||
default void sendRichMessage(final @NotNull String message, final @NotNull TagResolver... resolvers) {
|
||||
this.sendMessage(MiniMessage.miniMessage().deserialize(message, resolvers));
|
||||
this.sendMessage(MiniMessage.miniMessage().deserialize(message, this, resolvers));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2309,24 +2309,52 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
// Spigot start
|
||||
public class Spigot {
|
||||
|
||||
/**
|
||||
* @deprecated Server config options may be renamed or removed without notice. Prefer using existing API
|
||||
* wherever possible, rather than directly reading from a server config.
|
||||
*
|
||||
* @return The server's spigot config.
|
||||
*/
|
||||
@Deprecated(since = "1.21.4", forRemoval = true)
|
||||
@NotNull
|
||||
public org.bukkit.configuration.file.YamlConfiguration getConfig() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Server config options may be renamed or removed without notice. Prefer using existing API
|
||||
* wherever possible, rather than directly reading from a server config.
|
||||
*
|
||||
* @return The server's bukkit config.
|
||||
*/
|
||||
// Paper start
|
||||
@Deprecated(since = "1.21.4", forRemoval = true)
|
||||
@NotNull
|
||||
public org.bukkit.configuration.file.YamlConfiguration getBukkitConfig()
|
||||
{
|
||||
throw new UnsupportedOperationException( "Not supported yet." );
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Server config options may be renamed or removed without notice. Prefer using existing API
|
||||
* wherever possible, rather than directly reading from a server config.
|
||||
*
|
||||
* @return The server's spigot config.
|
||||
*/
|
||||
@Deprecated(since = "1.21.4", forRemoval = true)
|
||||
@NotNull
|
||||
public org.bukkit.configuration.file.YamlConfiguration getSpigotConfig()
|
||||
{
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Server config options may be renamed or removed without notice. Prefer using existing API
|
||||
* wherever possible, rather than directly reading from a server config.
|
||||
*
|
||||
* @return The server's paper config.
|
||||
*/
|
||||
@Deprecated(since = "1.21.4", forRemoval = true)
|
||||
@NotNull
|
||||
public org.bukkit.configuration.file.YamlConfiguration getPaperConfig()
|
||||
{
|
||||
@@ -2358,16 +2386,28 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
|
||||
/**
|
||||
* Restart the server. If the server administrator has not configured restarting, the server will stop.
|
||||
*
|
||||
* @deprecated Use {@link Server#restart()} instead.
|
||||
*/
|
||||
@Deprecated(since = "1.21.4", forRemoval = true)
|
||||
public void restart() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated All methods on this class have been deprecated, see the individual methods for replacements.
|
||||
*/
|
||||
@Deprecated(since = "1.21.4", forRemoval = true)
|
||||
@NotNull
|
||||
Spigot spigot();
|
||||
// Spigot end
|
||||
|
||||
/**
|
||||
* Restarts the server. If the server administrator has not configured restarting, the server will stop.
|
||||
*/
|
||||
void restart();
|
||||
|
||||
void reloadPermissions(); // Paper
|
||||
|
||||
boolean reloadCommandAliases(); // Paper
|
||||
|
||||
@@ -82,6 +82,8 @@ public interface Skull extends TileState {
|
||||
* may appear as the texture depending on skull type.
|
||||
*
|
||||
* @return the profile of the owning player
|
||||
*
|
||||
* @deprecated Use {@link #getPlayerProfile()} instead.
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated // Paper
|
||||
@@ -98,6 +100,8 @@ public interface Skull extends TileState {
|
||||
* @param profile the profile of the owning player
|
||||
* @throws IllegalArgumentException if the profile does not contain the
|
||||
* necessary information
|
||||
*
|
||||
* @deprecated Use {@link #setPlayerProfile(com.destroystokyo.paper.profile.PlayerProfile)} instead.
|
||||
*/
|
||||
@Deprecated // Paper
|
||||
void setOwnerProfile(@Nullable PlayerProfile profile);
|
||||
|
||||
@@ -147,7 +147,7 @@ public interface CommandSender extends net.kyori.adventure.audience.Audience, Pe
|
||||
* @param message MiniMessage content
|
||||
*/
|
||||
default void sendRichMessage(final @NotNull String message) {
|
||||
this.sendMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(message));
|
||||
this.sendMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(message, this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,7 +160,7 @@ public interface CommandSender extends net.kyori.adventure.audience.Audience, Pe
|
||||
* @param resolvers resolvers to use
|
||||
*/
|
||||
default void sendRichMessage(final @NotNull String message, final net.kyori.adventure.text.minimessage.tag.resolver.@NotNull TagResolver... resolvers) {
|
||||
this.sendMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(message, resolvers));
|
||||
this.sendMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(message, this, resolvers));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,43 @@
|
||||
package org.bukkit.entity;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a Creaking.
|
||||
*/
|
||||
@NullMarked
|
||||
public interface Creaking extends Monster {
|
||||
|
||||
/**
|
||||
* Gets the home location for this creaking (where its {@link org.bukkit.block.CreakingHeart} could be found).
|
||||
*
|
||||
* @return the location of the home if available, null otherwise
|
||||
*/
|
||||
@Nullable
|
||||
Location getHome();
|
||||
|
||||
/**
|
||||
* Activates this creaking to target and follow a player.
|
||||
*
|
||||
* @param player the target
|
||||
*/
|
||||
void activate(final Player player);
|
||||
|
||||
/**
|
||||
* Deactivates the creaking, clearing its current attack target and
|
||||
* marking it as inactive.
|
||||
*/
|
||||
void deactivate();
|
||||
|
||||
/**
|
||||
* Returns if this creaking is currently active and hunting.
|
||||
*
|
||||
* @see #activate(Player)
|
||||
*
|
||||
* @return true if active
|
||||
*/
|
||||
boolean isActive();
|
||||
|
||||
}
|
||||
@@ -3902,4 +3902,20 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @return the result of this method, holding leftovers and spawned items.
|
||||
*/
|
||||
PlayerGiveResult give(Collection<ItemStack> items, boolean dropIfFull);
|
||||
|
||||
/**
|
||||
* Get the score that shows in the death screen of the player.
|
||||
* <p>This amount is added to when the player gains experience.</p>
|
||||
*
|
||||
* @return Death screen score of player
|
||||
*/
|
||||
int getDeathScreenScore();
|
||||
|
||||
/**
|
||||
* Set the score that shows in the death screen of the player.
|
||||
* <p>This amount is added to when the player gains experience.</p>
|
||||
*
|
||||
* @param score New death screen score of player
|
||||
*/
|
||||
void setDeathScreenScore(int score);
|
||||
}
|
||||
@@ -33,11 +33,11 @@ public class BlockFadeEvent extends BlockEvent implements Cancellable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the state of the block that will be fading, melting or
|
||||
* disappearing.
|
||||
* Gets the state of the new block that will replace the block
|
||||
* fading, melting or disappearing.
|
||||
*
|
||||
* @return The block state of the block that will be fading, melting or
|
||||
* disappearing
|
||||
* @return The block state of the new block that replaces the block
|
||||
* fading, melting or disappearing
|
||||
*/
|
||||
@NotNull
|
||||
public BlockState getNewState() {
|
||||
|
||||
@@ -211,6 +211,10 @@ public class CreatureSpawnEvent extends EntitySpawnEvent {
|
||||
* When an entity spawns from an ominous item spawner
|
||||
*/
|
||||
OMINOUS_ITEM_SPAWNER,
|
||||
/**
|
||||
* When an entity spawns from a bucket
|
||||
*/
|
||||
BUCKET,
|
||||
// Paper end - Fixes and additions to the SpawnReason API
|
||||
/**
|
||||
* When a creature is spawned by a potion effect, for example:
|
||||
|
||||
@@ -327,7 +327,7 @@ public interface ItemFactory {
|
||||
*
|
||||
* <p>If the provided ItemStack is already enchanted, the existing enchants will be removed before enchanting.</p>
|
||||
*
|
||||
* <p>Levels must be in range {@code [1, 30]}.</p>
|
||||
* <p>Enchantment tables use levels in the range {@code [1, 30]}.</p>
|
||||
*
|
||||
* @param itemStack ItemStack to enchant
|
||||
* @param levels levels to use for enchanting
|
||||
@@ -336,7 +336,7 @@ public interface ItemFactory {
|
||||
* @return enchanted copy of the provided ItemStack
|
||||
* @throws IllegalArgumentException on bad arguments
|
||||
*/
|
||||
@NotNull ItemStack enchantWithLevels(@NotNull ItemStack itemStack, @org.jetbrains.annotations.Range(from = 1, to = 30) int levels, boolean allowTreasure, @NotNull java.util.Random random);
|
||||
@NotNull ItemStack enchantWithLevels(@NotNull ItemStack itemStack, int levels, boolean allowTreasure, @NotNull java.util.Random random);
|
||||
// Paper end - enchantWithLevels API
|
||||
// Paper start - enchantWithLevels with tag specification
|
||||
/**
|
||||
@@ -344,7 +344,7 @@ public interface ItemFactory {
|
||||
*
|
||||
* <p>If the provided ItemStack is already enchanted, the existing enchants will be removed before enchanting.</p>
|
||||
*
|
||||
* <p>Levels must be in range {@code [1, 30]}.</p>
|
||||
* <p>Enchantment tables use levels in the range {@code [1, 30]}.</p>
|
||||
*
|
||||
* @param itemStack ItemStack to enchant
|
||||
* @param levels levels to use for enchanting
|
||||
@@ -353,6 +353,6 @@ public interface ItemFactory {
|
||||
* @return enchanted copy of the provided ItemStack
|
||||
* @throws IllegalArgumentException on bad arguments
|
||||
*/
|
||||
@NotNull ItemStack enchantWithLevels(@NotNull ItemStack itemStack, @org.jetbrains.annotations.Range(from = 1, to = 30) int levels, @NotNull io.papermc.paper.registry.set.RegistryKeySet<@NotNull Enchantment> keySet, @NotNull java.util.Random random);
|
||||
@NotNull ItemStack enchantWithLevels(@NotNull ItemStack itemStack, int levels, @NotNull io.papermc.paper.registry.set.RegistryKeySet<@NotNull Enchantment> keySet, @NotNull java.util.Random random);
|
||||
// Paper end - enchantWithLevels with tag specification
|
||||
}
|
||||
@@ -57,7 +57,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
|
||||
*/
|
||||
@org.jetbrains.annotations.Contract(value = "_, _ -> new", pure = true)
|
||||
public static @NotNull ItemStack of(final @NotNull Material type, final int amount) {
|
||||
Preconditions.checkArgument(type.asItemType() != null, type + " isn't an item");
|
||||
Preconditions.checkArgument(type.asItemType() != null, "%s isn't an item", type);
|
||||
Preconditions.checkArgument(amount > 0, "amount must be greater than 0");
|
||||
return java.util.Objects.requireNonNull(type.asItemType(), type + " is not an item").createItemStack(amount); // Paper - delegate
|
||||
}
|
||||
@@ -683,7 +683,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
|
||||
*
|
||||
* <p>If this ItemStack is already enchanted, the existing enchants will be removed before enchanting.</p>
|
||||
*
|
||||
* <p>Levels must be in range {@code [1, 30]}.</p>
|
||||
* <p>Enchantment tables use levels in the range {@code [1, 30]}.</p>
|
||||
*
|
||||
* @param levels levels to use for enchanting
|
||||
* @param allowTreasure whether to allow enchantments where {@link org.bukkit.enchantments.Enchantment#isTreasure()} returns true
|
||||
@@ -692,7 +692,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
|
||||
* @throws IllegalArgumentException on bad arguments
|
||||
*/
|
||||
@NotNull
|
||||
public ItemStack enchantWithLevels(final @org.jetbrains.annotations.Range(from = 1, to = 30) int levels, final boolean allowTreasure, final @NotNull java.util.Random random) {
|
||||
public ItemStack enchantWithLevels(final int levels, final boolean allowTreasure, final @NotNull java.util.Random random) {
|
||||
return Bukkit.getServer().getItemFactory().enchantWithLevels(this, levels, allowTreasure, random);
|
||||
}
|
||||
|
||||
@@ -701,7 +701,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
|
||||
*
|
||||
* <p>If the provided ItemStack is already enchanted, the existing enchants will be removed before enchanting.</p>
|
||||
*
|
||||
* <p>Levels must be in range {@code [1, 30]}.</p>
|
||||
* <p>Enchantment tables use levels in the range {@code [1, 30]}.</p>
|
||||
*
|
||||
* @param levels levels to use for enchanting
|
||||
* @param keySet registry key set defining the set of possible enchantments, e.g. {@link io.papermc.paper.registry.keys.tags.EnchantmentTagKeys#IN_ENCHANTING_TABLE}.
|
||||
@@ -709,7 +709,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
|
||||
* @return enchanted copy of the provided ItemStack
|
||||
* @throws IllegalArgumentException on bad arguments
|
||||
*/
|
||||
public @NotNull ItemStack enchantWithLevels(final @org.jetbrains.annotations.Range(from = 1, to = 30) int levels, final @NotNull io.papermc.paper.registry.set.RegistryKeySet<@NotNull Enchantment> keySet, final @NotNull java.util.Random random) {
|
||||
public @NotNull ItemStack enchantWithLevels(final int levels, final @NotNull io.papermc.paper.registry.set.RegistryKeySet<@NotNull Enchantment> keySet, final @NotNull java.util.Random random) {
|
||||
return Bukkit.getItemFactory().enchantWithLevels(this, levels, keySet, random);
|
||||
}
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDepe
|
||||
*/
|
||||
MenuType.Typed<InventoryView, LocationInventoryViewBuilder<InventoryView>> SHULKER_BOX = get("shulker_box");
|
||||
/**
|
||||
* A MenuType which represents a stonecutter.
|
||||
* A MenuType which represents a smithing table.
|
||||
*/
|
||||
MenuType.Typed<InventoryView, LocationInventoryViewBuilder<InventoryView>> SMITHING = get("smithing");
|
||||
/**
|
||||
|
||||
@@ -143,7 +143,8 @@ dependencies {
|
||||
implementation("io.netty:netty-codec-haproxy:4.1.115.Final") // Add support for proxy protocol
|
||||
implementation("org.apache.logging.log4j:log4j-iostreams:2.24.1")
|
||||
implementation("org.ow2.asm:asm-commons:9.7.1")
|
||||
implementation("org.spongepowered:configurate-yaml:4.2.0-SNAPSHOT")
|
||||
implementation("org.spongepowered:configurate-yaml:4.2.0-20250225.064233-199")
|
||||
implementation("org.spongepowered:configurate-core:4.2.0-20250225.064233-204") // Pinned dependency of above pinned yaml snapshot.
|
||||
implementation("commons-lang:commons-lang:2.6")
|
||||
runtimeOnly("org.xerial:sqlite-jdbc:3.47.0.0")
|
||||
runtimeOnly("com.mysql:mysql-connector-j:9.1.0")
|
||||
@@ -173,7 +174,7 @@ dependencies {
|
||||
|
||||
// Spark
|
||||
implementation("me.lucko:spark-api:0.1-20240720.200737-2")
|
||||
implementation("me.lucko:spark-paper:1.10.119-SNAPSHOT")
|
||||
implementation("me.lucko:spark-paper:1.10.119-20241121.092015-1")
|
||||
}
|
||||
|
||||
tasks.jar {
|
||||
|
||||
+4
-3
@@ -28,7 +28,7 @@ and then catch exceptions and close if they fire.
|
||||
Part of this commit was authored by: Spottedleaf, sandtechnology
|
||||
|
||||
diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java
|
||||
index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..161ee86d67b9a23368a18481fde9768c022d913d 100644
|
||||
index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42eafb96fa1 100644
|
||||
--- a/net/minecraft/network/Connection.java
|
||||
+++ b/net/minecraft/network/Connection.java
|
||||
@@ -85,7 +85,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -232,7 +232,7 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..161ee86d67b9a23368a18481fde9768c
|
||||
// Paper start - Add PlayerConnectionCloseEvent
|
||||
if (packetListener instanceof net.minecraft.server.network.ServerCommonPacketListenerImpl commonPacketListener) {
|
||||
/* Player was logged in, either game listener or configuration listener */
|
||||
@@ -797,4 +888,96 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -797,4 +888,97 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
public void setBandwidthLogger(LocalSampleLogger bandwithLogger) {
|
||||
this.bandwidthDebugMonitor = new BandwidthDebugMonitor(bandwithLogger);
|
||||
}
|
||||
@@ -293,7 +293,8 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..161ee86d67b9a23368a18481fde9768c
|
||||
+ packet instanceof net.minecraft.network.protocol.game.ClientboundLevelParticlesPacket ||
|
||||
+ packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket ||
|
||||
+ packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket ||
|
||||
+ packet instanceof net.minecraft.network.protocol.game.ClientboundBossEventPacket;
|
||||
+ packet instanceof net.minecraft.network.protocol.game.ClientboundBossEventPacket ||
|
||||
+ packet instanceof net.minecraft.network.protocol.ping.ClientboundPongResponsePacket;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
|
||||
@@ -366,7 +366,7 @@ index d95413af04121fe91ca0f3b0c70025b9808acef9..ad665c7535c615d2b03a3e7864be435f
|
||||
import org.slf4j.Logger;
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 8204528c26456929fdec0d8ba7a5a52128409097..01bc2d1639be9f04afc63e5841c5c99730ea37d8 100644
|
||||
index cdb4d313eb33c049c8467fe5d31fb0d671737768..40b799fd90b0db13bdaa8834c021f5ca8f25ce10 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -551,6 +551,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -476,7 +476,7 @@ index 24735284fda151414d99faad401d25ba60995f9a..23b342cc31c7e72ade0e1ccad86a9ccf
|
||||
public void tick() {
|
||||
super.tick();
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index b15420ffa1432d49aec8e91e917598bde4e94337..054ece1d539d69a4b7eec57e681179343c7e75c3 100644
|
||||
index 54cf80831372d102e8d2966ac104678caebdf336..d89c3949e16ff6cb0374da29ec6731d854b5f105 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -381,6 +381,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -533,10 +533,10 @@ index b15420ffa1432d49aec8e91e917598bde4e94337..054ece1d539d69a4b7eec57e68117934
|
||||
movement = this.maybeBackOffFromEdge(movement, type);
|
||||
Vec3 vec3 = this.collide(movement);
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index ff513e8c87bf42be756e46f4dbfec8dda2b8cb60..239c443ddc9bacc08a39a8ef2ab17016a2480549 100644
|
||||
index bf5fd2a6c8630ea2bb06881d4d365dda9a4e90ea..4713c29cc2add476f568163a29cb297f5d1049df 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3096,6 +3096,14 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
@@ -3103,6 +3103,14 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -23751,7 +23751,7 @@ index 841a41485af62470d833aba578069b19a0bd1e8d..409c1134327bfcc338c3ac5e658a83cc
|
||||
// CraftBukkit start
|
||||
public boolean isDebugging() {
|
||||
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index f8c81d795b19e73d56d6e0196c75e441ab4c2bef..97a294d2f5c1ddf0af7ffec3e1425eb329c5751b 100644
|
||||
index ac7bc193f7ea63cbbba73df49f54a17ef7cdec40..d2db6e3a4af13984b0a790fb38e83c253914a973 100644
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -433,7 +433,33 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
@@ -26735,7 +26735,7 @@ index da793ad12565c36fffb26eb771ff68c76632caf7..db06f966077928419bfe469260f04d7d
|
||||
if (!passengers.equals(this.lastPassengers)) {
|
||||
this.broadcastAndSend(new ClientboundSetPassengersPacket(this.entity)); // CraftBukkit
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 400b56657414177cd76a7b94c426dc7c886aa957..a275b17d0852d9d9bc850614713244e580ae81f1 100644
|
||||
index d1f235ebd835f58cf0c703c3a64d29825d98e183..080091efc19bc768bb9a660f366c42e831225505 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -170,7 +170,7 @@ import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
@@ -27976,10 +27976,10 @@ index 4eb040006f5d41b47e5ac9df5d9f19c4315d6343..7fa41dea184b01891f45d8e404bc1cba
|
||||
this.generatingStep = generatingStep;
|
||||
this.cache = cache;
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index 5d88b2790710a885957ffcffc02fb99c917123c5..7d1d4abfb04829d8c4722e326c6c6b8fb2ab91f4 100644
|
||||
index 7eebb494e38b57e81b4f92f0a96d3a4c610d86df..065f4c810439dde464529b54ae300ecfcb1c2c31 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -1312,7 +1312,7 @@ public abstract class PlayerList {
|
||||
@@ -1317,7 +1317,7 @@ public abstract class PlayerList {
|
||||
|
||||
public void setViewDistance(int viewDistance) {
|
||||
this.viewDistance = viewDistance;
|
||||
@@ -27988,7 +27988,7 @@ index 5d88b2790710a885957ffcffc02fb99c917123c5..7d1d4abfb04829d8c4722e326c6c6b8f
|
||||
|
||||
for (ServerLevel serverLevel : this.server.getAllLevels()) {
|
||||
if (serverLevel != null) {
|
||||
@@ -1323,7 +1323,7 @@ public abstract class PlayerList {
|
||||
@@ -1328,7 +1328,7 @@ public abstract class PlayerList {
|
||||
|
||||
public void setSimulationDistance(int simulationDistance) {
|
||||
this.simulationDistance = simulationDistance;
|
||||
@@ -28372,7 +28372,7 @@ index 8cc5c0716392ba06501542ff5cbe71ee43979e5d..09fd99c9cbd23b5f3c899bfb00c9b896
|
||||
+ // Paper end - block counting
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 994791a83ca6712db3e74ca9aba4bfcd95a0ec6d..1b54cf07616a10d93e9336dbd299ba5f09678a28 100644
|
||||
index 9b3b770f6986dd132da78fdc3626d334166ec52a..b2b61203438bb1fad1ee807729781718d2467155 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -135,7 +135,7 @@ import net.minecraft.world.scores.ScoreHolder;
|
||||
|
||||
+10
-10
@@ -6,10 +6,10 @@ Subject: [PATCH] Optimise collision checking in player move packet handling
|
||||
Move collision logic to just the hasNewCollision call instead of getCubes + hasNewCollision
|
||||
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d149849983107c539b31 100644
|
||||
index 12c83cb084563a4e3f7f357d8b600941544ef2b0..90e582ca30851857add5e2d830e9876667fd1807 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -561,7 +561,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -563,7 +563,7 @@ public class ServerGamePacketListenerImpl
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
|
||||
d3 = d - this.vehicleLastGoodX; // Paper - diff on change, used for checking large move vectors above
|
||||
d4 = d1 - this.vehicleLastGoodY; // Paper - diff on change, used for checking large move vectors above
|
||||
d5 = d2 - this.vehicleLastGoodZ; // Paper - diff on change, used for checking large move vectors above
|
||||
@@ -571,6 +571,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -573,6 +573,7 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
|
||||
rootVehicle.move(MoverType.PLAYER, new Vec3(d3, d4, d5));
|
||||
@@ -26,7 +26,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
|
||||
double verticalDelta = d4; // Paper - Decompile fix, was named d11 previously, is now gone in the source
|
||||
d3 = d - rootVehicle.getX();
|
||||
d4 = d1 - rootVehicle.getY();
|
||||
@@ -582,14 +583,22 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -584,14 +585,22 @@ public class ServerGamePacketListenerImpl
|
||||
d7 = d3 * d3 + d4 * d4 + d5 * d5;
|
||||
boolean flag2 = false;
|
||||
if (d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot
|
||||
@@ -52,7 +52,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
|
||||
rootVehicle.absMoveTo(x, y, z, f, f1);
|
||||
this.player.absMoveTo(x, y, z, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
|
||||
this.send(ClientboundMoveVehiclePacket.fromEntity(rootVehicle));
|
||||
@@ -667,9 +676,32 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -669,9 +678,32 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
|
||||
private boolean noBlocksAround(Entity entity) {
|
||||
@@ -88,7 +88,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1368,7 +1400,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1371,7 +1403,7 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
|
||||
d3 = d - this.lastGoodX; // Paper - diff on change, used for checking large move vectors above
|
||||
d4 = d1 - this.lastGoodY; // Paper - diff on change, used for checking large move vectors above
|
||||
d5 = d2 - this.lastGoodZ; // Paper - diff on change, used for checking large move vectors above
|
||||
@@ -1407,6 +1439,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1410,6 +1442,7 @@ public class ServerGamePacketListenerImpl
|
||||
boolean flag1 = this.player.verticalCollisionBelow;
|
||||
this.player.move(MoverType.PLAYER, new Vec3(d3, d4, d5));
|
||||
this.player.onGround = packet.isOnGround(); // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move
|
||||
@@ -105,7 +105,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
|
||||
// Paper start - prevent position desync
|
||||
if (this.awaitingPositionFromClient != null) {
|
||||
return; // ... thanks Mojang for letting move calls teleport across dimensions.
|
||||
@@ -1439,7 +1472,17 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1442,7 +1475,17 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
|
||||
// Paper start - Add fail move event
|
||||
@@ -124,7 +124,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
|
||||
if (teleportBack) {
|
||||
io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.CLIPPED_INTO_BLOCK,
|
||||
toX, toY, toZ, toYaw, toPitch, false);
|
||||
@@ -1575,7 +1618,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1578,7 +1621,7 @@ public class ServerGamePacketListenerImpl
|
||||
|
||||
private boolean updateAwaitingTeleport() {
|
||||
if (this.awaitingPositionFromClient != null) {
|
||||
@@ -133,7 +133,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
|
||||
this.awaitingTeleportTime = this.tickCount;
|
||||
this.teleport(
|
||||
this.awaitingPositionFromClient.x,
|
||||
@@ -1594,6 +1637,33 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1597,6 +1640,33 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -11,10 +11,10 @@ a portal in spectator mode and then later switching to creative mode
|
||||
would portal the player.
|
||||
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 366c26b2ca539be189b67d75ae73a587c4102c14..4068132a33f87dd07d6df1033ed11ba16a57313b 100644
|
||||
index 90e582ca30851857add5e2d830e9876667fd1807..c569cdfa4cba4f65892ffd4045c611837049f440 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -657,7 +657,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -659,7 +659,7 @@ public class ServerGamePacketListenerImpl
|
||||
// CraftBukkit end
|
||||
|
||||
this.player.serverLevel().getChunkSource().move(this.player);
|
||||
@@ -23,7 +23,7 @@ index 366c26b2ca539be189b67d75ae73a587c4102c14..4068132a33f87dd07d6df1033ed11ba1
|
||||
Vec3 vec3 = new Vec3(rootVehicle.getX() - x, rootVehicle.getY() - y, rootVehicle.getZ() - z);
|
||||
this.handlePlayerKnownMovement(vec3);
|
||||
rootVehicle.setOnGroundWithMovement(packet.onGround(), vec3);
|
||||
@@ -1574,7 +1574,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1577,7 +1577,7 @@ public class ServerGamePacketListenerImpl
|
||||
Vec3 vec3 = new Vec3(this.player.getX() - x, this.player.getY() - y, this.player.getZ() - z);
|
||||
this.player.setOnGroundWithMovement(packet.isOnGround(), packet.horizontalCollision(), vec3);
|
||||
this.player.doCheckFallDamage(vec3.x, vec3.y, vec3.z, packet.isOnGround());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/network/FriendlyByteBuf.java
|
||||
+++ b/net/minecraft/network/FriendlyByteBuf.java
|
||||
@@ -70,6 +_,7 @@
|
||||
@@ -70,14 +_,20 @@
|
||||
public class FriendlyByteBuf extends ByteBuf {
|
||||
public static final int DEFAULT_NBT_QUOTA = 2097152;
|
||||
private final ByteBuf source;
|
||||
@@ -8,8 +8,13 @@
|
||||
public static final short MAX_STRING_LENGTH = 32767;
|
||||
public static final int MAX_COMPONENT_STRING_LENGTH = 262144;
|
||||
private static final int PUBLIC_KEY_SIZE = 256;
|
||||
@@ -78,6 +_,7 @@
|
||||
private static final int MAX_PUBLIC_KEY_HEADER_SIZE = 256;
|
||||
private static final int MAX_PUBLIC_KEY_LENGTH = 512;
|
||||
private static final Gson GSON = new Gson();
|
||||
+ // Paper start - Track codec depth
|
||||
+ public boolean trackCodecDepth;
|
||||
+ public byte codecDepth;
|
||||
+ // Paper end - Track codec depth
|
||||
|
||||
public FriendlyByteBuf(ByteBuf source) {
|
||||
+ this.adventure$locale = PacketEncoder.ADVENTURE_LOCALE.get(); // Paper - track player's locale for server-side translations
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
--- a/net/minecraft/network/codec/ByteBufCodecs.java
|
||||
+++ b/net/minecraft/network/codec/ByteBufCodecs.java
|
||||
@@ -378,6 +_,48 @@
|
||||
};
|
||||
}
|
||||
|
||||
+ // Paper start - Track codec depth
|
||||
+ static <B extends FriendlyByteBuf, V> StreamCodec<B, V> trackDepth(final StreamCodec<B, V> codec) {
|
||||
+ return new StreamCodec<>() {
|
||||
+ @Override
|
||||
+ public V decode(B buffer) {
|
||||
+ buffer.trackCodecDepth = true;
|
||||
+ try {
|
||||
+ return codec.decode(buffer);
|
||||
+ } finally {
|
||||
+ buffer.trackCodecDepth = false;
|
||||
+ buffer.codecDepth = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void encode(B buffer, V value) {
|
||||
+ codec.encode(buffer, value);
|
||||
+ }
|
||||
+ };
|
||||
+ }
|
||||
+
|
||||
+ static <B extends FriendlyByteBuf, V> StreamCodec<B, V> increaseDepth(final StreamCodec<B, V> codec) {
|
||||
+ return new StreamCodec<>() {
|
||||
+ @Override
|
||||
+ public V decode(B buffer) {
|
||||
+ if (!buffer.trackCodecDepth) {
|
||||
+ return codec.decode(buffer);
|
||||
+ }
|
||||
+ if (++buffer.codecDepth > 64) {
|
||||
+ throw new DecoderException("Too deep");
|
||||
+ }
|
||||
+ return codec.decode(buffer);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void encode(B buffer, V value) {
|
||||
+ codec.encode(buffer, value);
|
||||
+ }
|
||||
+ };
|
||||
+ }
|
||||
+ // Paper end - Track codec depth
|
||||
+
|
||||
static <B extends ByteBuf, V> StreamCodec<B, Optional<V>> optional(final StreamCodec<B, V> codec) {
|
||||
return new StreamCodec<B, Optional<V>>() {
|
||||
@Override
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
--- a/net/minecraft/network/protocol/game/ServerboundContainerClickPacket.java
|
||||
+++ b/net/minecraft/network/protocol/game/ServerboundContainerClickPacket.java
|
||||
@@ -17,7 +_,7 @@
|
||||
);
|
||||
private static final int MAX_SLOT_COUNT = 128;
|
||||
private static final StreamCodec<RegistryFriendlyByteBuf, Int2ObjectMap<ItemStack>> SLOTS_STREAM_CODEC = ByteBufCodecs.map(
|
||||
- Int2ObjectOpenHashMap::new, ByteBufCodecs.SHORT.map(Short::intValue, Integer::shortValue), ItemStack.OPTIONAL_STREAM_CODEC, 128
|
||||
+ Int2ObjectOpenHashMap::new, ByteBufCodecs.SHORT.map(Short::intValue, Integer::shortValue), ItemStack.OPTIONAL_STREAM_CODEC.apply(ByteBufCodecs::trackDepth), 128 // Paper - Track codec depth
|
||||
);
|
||||
private final int containerId;
|
||||
private final int stateId;
|
||||
@@ -46,7 +_,7 @@
|
||||
this.buttonNum = buffer.readByte();
|
||||
this.clickType = buffer.readEnum(ClickType.class);
|
||||
this.changedSlots = Int2ObjectMaps.unmodifiable(SLOTS_STREAM_CODEC.decode(buffer));
|
||||
- this.carriedItem = ItemStack.OPTIONAL_STREAM_CODEC.decode(buffer);
|
||||
+ this.carriedItem = ItemStack.OPTIONAL_STREAM_CODEC.apply(ByteBufCodecs::trackDepth).decode(buffer); // Paper - Track codec depth
|
||||
}
|
||||
|
||||
private void write(RegistryFriendlyByteBuf buffer) {
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
--- a/net/minecraft/network/protocol/game/ServerboundSetCreativeModeSlotPacket.java
|
||||
+++ b/net/minecraft/network/protocol/game/ServerboundSetCreativeModeSlotPacket.java
|
||||
@@ -11,7 +_,7 @@
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, ServerboundSetCreativeModeSlotPacket> STREAM_CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.SHORT,
|
||||
ServerboundSetCreativeModeSlotPacket::slotNum,
|
||||
- ItemStack.validatedStreamCodec(ItemStack.OPTIONAL_STREAM_CODEC),
|
||||
+ ItemStack.validatedStreamCodec(ItemStack.OPTIONAL_STREAM_CODEC).apply(ByteBufCodecs::trackDepth), // Paper - Track codec depth
|
||||
ServerboundSetCreativeModeSlotPacket::itemStack,
|
||||
ServerboundSetCreativeModeSlotPacket::new
|
||||
);
|
||||
@@ -0,0 +1,36 @@
|
||||
--- a/net/minecraft/server/ServerTickRateManager.java
|
||||
+++ b/net/minecraft/server/ServerTickRateManager.java
|
||||
@@ -14,6 +_,7 @@
|
||||
private long scheduledCurrentSprintTicks = 0L;
|
||||
private boolean previousIsFrozen = false;
|
||||
private final MinecraftServer server;
|
||||
+ private boolean silent; // Paper - silence feedback when API requests sprint
|
||||
|
||||
public ServerTickRateManager(MinecraftServer server) {
|
||||
this.server = server;
|
||||
@@ -67,6 +_,13 @@
|
||||
}
|
||||
|
||||
public boolean requestGameToSprint(int sprintTime) {
|
||||
+ // Paper start - silence feedback when API requests sprint
|
||||
+ return requestGameToSprint(sprintTime, false);
|
||||
+ }
|
||||
+
|
||||
+ public boolean requestGameToSprint(int sprintTime, boolean silent) {
|
||||
+ if (!isSprinting()) this.silent = silent;
|
||||
+ // Paper end - silence feedback when API requests sprint
|
||||
boolean flag = this.remainingSprintTicks > 0L;
|
||||
this.sprintTimeSpend = 0L;
|
||||
this.scheduledCurrentSprintTicks = sprintTime;
|
||||
@@ -83,7 +_,10 @@
|
||||
String string = String.format("%.2f", l == 0L ? this.millisecondsPerTick() : d / l);
|
||||
this.scheduledCurrentSprintTicks = 0L;
|
||||
this.sprintTimeSpend = 0L;
|
||||
- this.server.createCommandSourceStack().sendSuccess(() -> Component.translatable("commands.tick.sprint.report", i, string), true);
|
||||
+ // Paper start - silence feedback when API requests sprint
|
||||
+ if (!this.silent) this.server.createCommandSourceStack().sendSuccess(() -> Component.translatable("commands.tick.sprint.report", i, string), true);
|
||||
+ this.silent = false;
|
||||
+ // Paper end - silence feedback when API requests sprint
|
||||
this.remainingSprintTicks = 0L;
|
||||
this.setFrozen(this.previousIsFrozen);
|
||||
this.server.onTickRateChanged();
|
||||
+3
-1
@@ -361,7 +361,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -515,14 +_,52 @@
|
||||
@@ -515,14 +_,54 @@
|
||||
|
||||
@Override
|
||||
public String getPluginNames() {
|
||||
@@ -402,6 +402,8 @@
|
||||
+ }
|
||||
+
|
||||
+ public String runCommand(RconConsoleSource rconConsoleSource, String s) {
|
||||
+ if (s.isBlank()) return ""; // Paper - Do not process empty rcon commands
|
||||
+
|
||||
+ rconConsoleSource.prepareForCommand();
|
||||
+ this.executeBlocking(() -> {
|
||||
+ CommandSourceStack wrapper = rconConsoleSource.createCommandSourceStack();
|
||||
|
||||
@@ -1072,6 +1072,14 @@
|
||||
@Override
|
||||
public CrashReportCategory fillReportDetails(CrashReport report) {
|
||||
CrashReportCategory crashReportCategory = super.fillReportDetails(report);
|
||||
@@ -1714,6 +_,7 @@
|
||||
final class EntityCallbacks implements LevelCallback<Entity> {
|
||||
@Override
|
||||
public void onCreated(Entity entity) {
|
||||
+ entity.setOldPosAndRot(); // Paper - update old pos / rot for new entities as it will default to Vec3.ZERO
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1723,24 +_,32 @@
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
@Nullable
|
||||
private Vec3 startingToFallPosition;
|
||||
@Nullable
|
||||
@@ -258,6 +_,13 @@
|
||||
@@ -258,6 +_,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,13 @@
|
||||
+ ServerPlayer.this.connection.send(new ClientboundContainerSetSlotPacket(ServerPlayer.this.inventoryMenu.containerId, ServerPlayer.this.inventoryMenu.incrementStateId(), net.minecraft.world.inventory.InventoryMenu.SHIELD_SLOT, ServerPlayer.this.inventoryMenu.getSlot(net.minecraft.world.inventory.InventoryMenu.SHIELD_SLOT).getItem().copy()));
|
||||
+ }
|
||||
+ // Paper end - Sync offhand slot in menus
|
||||
+
|
||||
+ // Paper start - add flag to simplify remote matching logic
|
||||
+ @Override
|
||||
+ public ServerPlayer player() {
|
||||
+ return ServerPlayer.this;
|
||||
+ }
|
||||
+ // Paper end - add flag to simplify remote matching logic
|
||||
+
|
||||
@Override
|
||||
public void sendSlotChange(AbstractContainerMenu container, int slot, ItemStack itemStack) {
|
||||
|
||||
+63
-10
@@ -70,7 +70,7 @@
|
||||
private double firstGoodX;
|
||||
private double firstGoodY;
|
||||
private double firstGoodZ;
|
||||
@@ -236,22 +_,39 @@
|
||||
@@ -236,22 +_,41 @@
|
||||
private int receivedMovePacketCount;
|
||||
private int knownMovePacketCount;
|
||||
private boolean receivedMovementThisTick;
|
||||
@@ -98,6 +98,7 @@
|
||||
private final FutureChain chatMessageChain;
|
||||
private boolean waitingForSwitchToConfig;
|
||||
+ private static final int MAX_SIGN_LINE_LENGTH = Integer.getInteger("Paper.maxSignLength", 80); // Paper - Limit client sign length
|
||||
+ private final io.papermc.paper.event.packet.ClientTickEndEvent tickEndEvent; // Paper - add client tick end event
|
||||
|
||||
public ServerGamePacketListenerImpl(MinecraftServer server, Connection connection, ServerPlayer player, CommonListenerCookie cookie) {
|
||||
- super(server, connection, cookie);
|
||||
@@ -109,6 +110,7 @@
|
||||
this.signedMessageDecoder = SignedMessageChain.Decoder.unsigned(player.getUUID(), server::enforceSecureProfile);
|
||||
- this.chatMessageChain = new FutureChain(server);
|
||||
+ this.chatMessageChain = new FutureChain(server.chatExecutor); // CraftBukkit - async chat
|
||||
+ this.tickEndEvent = new io.papermc.paper.event.packet.ClientTickEndEvent(player.getBukkitEntity()); // Paper - add client tick end event
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -545,7 +547,7 @@
|
||||
addBlockDataToItem(blockState, serverLevel, blockPos, cloneItemStack);
|
||||
}
|
||||
|
||||
@@ -685,14 +_,24 @@
|
||||
@@ -685,18 +_,29 @@
|
||||
if (stack.isItemEnabled(this.player.level().enabledFeatures())) {
|
||||
Inventory inventory = this.player.getInventory();
|
||||
int i = inventory.findSlotMatchingItem(stack);
|
||||
@@ -574,6 +576,11 @@
|
||||
}
|
||||
|
||||
this.player.connection.send(new ClientboundSetHeldSlotPacket(inventory.selected));
|
||||
this.player.inventoryMenu.broadcastChanges();
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -814,6 +_,13 @@
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
int item = packet.getItem();
|
||||
@@ -1070,7 +1077,7 @@
|
||||
if (this.player.hasClientLoaded()) {
|
||||
BlockPos pos = packet.getPos();
|
||||
this.player.resetLastActionTime();
|
||||
@@ -1101,14 +_,46 @@
|
||||
@@ -1101,32 +_,95 @@
|
||||
case SWAP_ITEM_WITH_OFFHAND:
|
||||
if (!this.player.isSpectator()) {
|
||||
ItemStack itemInHand = this.player.getItemInHand(InteractionHand.OFF_HAND);
|
||||
@@ -1096,6 +1103,7 @@
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
this.player.stopUsingItem();
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes.
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -1117,20 +1125,27 @@
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
this.player.drop(false);
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes.
|
||||
}
|
||||
|
||||
@@ -1120,13 +_,39 @@
|
||||
return;
|
||||
case DROP_ALL_ITEMS:
|
||||
if (!this.player.isSpectator()) {
|
||||
this.player.drop(true);
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes.
|
||||
}
|
||||
|
||||
return;
|
||||
case RELEASE_USE_ITEM:
|
||||
- this.player.releaseUsingItem();
|
||||
+ if (this.player.getUseItem() == this.player.getItemInHand(this.player.getUsedItemHand())) this.player.releaseUsingItem(); // Paper - validate use item before processing release
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes.
|
||||
return;
|
||||
case START_DESTROY_BLOCK:
|
||||
case ABORT_DESTROY_BLOCK:
|
||||
case STOP_DESTROY_BLOCK:
|
||||
+ // Paper start - Don't allow digging into unloaded chunks
|
||||
+ if (this.player.level().getChunkIfLoadedImmediately(pos.getX() >> 4, pos.getZ() >> 4) == null) {
|
||||
+ if (this.player.level().getChunkIfLoadedImmediately(pos.getX() >> 4, pos.getZ() >> 4) == null || !this.player.canInteractWithBlock(pos, 1.0)) {
|
||||
+ this.player.connection.ackBlockChangesUpTo(packet.getSequence());
|
||||
+ return;
|
||||
+ }
|
||||
@@ -1157,6 +1172,7 @@
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Send block entities after destroy prediction
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes.
|
||||
return;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid player action");
|
||||
@@ -1227,6 +1243,14 @@
|
||||
} else {
|
||||
Component component1 = Component.translatable("build.tooHigh", maxY).withStyle(ChatFormatting.RED);
|
||||
this.player.sendSystemMessage(component1, true);
|
||||
@@ -1187,6 +_,7 @@
|
||||
|
||||
this.player.connection.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos));
|
||||
this.player.connection.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos.relative(direction)));
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes.
|
||||
} else {
|
||||
LOGGER.warn(
|
||||
"Rejecting UseItemOnPacket from {}: Location {} too far away from hit block {}.",
|
||||
@@ -1203,6 +_,8 @@
|
||||
@Override
|
||||
public void handleUseItem(ServerboundUseItemPacket packet) {
|
||||
@@ -1352,7 +1376,7 @@
|
||||
throw new IllegalArgumentException("Expected packet sequence nr >= 0");
|
||||
} else {
|
||||
this.ackBlockChangesUpTo = Math.max(sequence, this.ackBlockChangesUpTo);
|
||||
@@ -1275,7 +_,17 @@
|
||||
@@ -1275,20 +_,38 @@
|
||||
@Override
|
||||
public void handleSetCarriedItem(ServerboundSetCarriedItemPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
@@ -1370,8 +1394,10 @@
|
||||
if (this.player.getInventory().selected != packet.getSlot() && this.player.getUsedItemHand() == InteractionHand.MAIN_HAND) {
|
||||
this.player.stopUsingItem();
|
||||
}
|
||||
@@ -1284,11 +_,18 @@
|
||||
|
||||
this.player.getInventory().selected = packet.getSlot();
|
||||
this.player.resetLastActionTime();
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes.
|
||||
} else {
|
||||
LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString());
|
||||
+ this.disconnect(Component.literal("Invalid hotbar selection (Hacking?)"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // CraftBukkit // Paper - kick event cause
|
||||
@@ -1954,7 +1980,7 @@
|
||||
ServerGamePacketListenerImpl.LOGGER
|
||||
.warn("Player {} tried to attack an invalid entity", ServerGamePacketListenerImpl.this.player.getName().getString());
|
||||
}
|
||||
@@ -1656,6 +_,26 @@
|
||||
@@ -1656,6 +_,27 @@
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1978,6 +2004,7 @@
|
||||
+ });
|
||||
+ }
|
||||
+ // Paper end - PlayerUseUnknownEntityEvent
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2379,6 +2406,14 @@
|
||||
|
||||
for (Entry<ItemStack> entry : Int2ObjectMaps.fastIterable(packet.getChangedSlots())) {
|
||||
this.player.containerMenu.setRemoteSlotNoCopy(entry.getIntKey(), entry.getValue());
|
||||
@@ -1726,6 +_,7 @@
|
||||
} else {
|
||||
this.player.containerMenu.broadcastChanges();
|
||||
}
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1733,6 +_,14 @@
|
||||
|
||||
@Override
|
||||
@@ -2448,7 +2483,15 @@
|
||||
this.player.resetLastActionTime();
|
||||
if (this.player.containerMenu.containerId == packet.containerId() && !this.player.isSpectator()) {
|
||||
if (!this.player.containerMenu.stillValid(this.player)) {
|
||||
@@ -1792,6 +_,43 @@
|
||||
@@ -1776,6 +_,7 @@
|
||||
if (flag) {
|
||||
this.player.containerMenu.broadcastChanges();
|
||||
}
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1792,10 +_,48 @@
|
||||
|
||||
boolean flag1 = packet.slotNum() >= 1 && packet.slotNum() <= 45;
|
||||
boolean flag2 = itemStack.isEmpty() || itemStack.getCount() <= itemStack.getMaxStackSize();
|
||||
@@ -2492,6 +2535,11 @@
|
||||
if (flag1 && flag2) {
|
||||
this.player.inventoryMenu.getSlot(packet.slotNum()).setByPlayer(itemStack);
|
||||
this.player.inventoryMenu.setRemoteSlot(packet.slotNum(), itemStack);
|
||||
this.player.inventoryMenu.broadcastChanges();
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes.
|
||||
} else if (flag && flag2) {
|
||||
if (this.dropSpamThrottler.isUnderThreshold()) {
|
||||
this.dropSpamThrottler.increment();
|
||||
@@ -1809,11 +_,24 @@
|
||||
|
||||
@Override
|
||||
@@ -2598,7 +2646,7 @@
|
||||
this.signedMessageDecoder = chatSession.createMessageDecoder(this.player.getUUID());
|
||||
this.chatMessageChain
|
||||
.append(
|
||||
@@ -1919,15 +_,17 @@
|
||||
@@ -1919,19 +_,22 @@
|
||||
this.server
|
||||
.getPlayerList()
|
||||
.broadcastAll(
|
||||
@@ -2620,6 +2668,11 @@
|
||||
|
||||
@Override
|
||||
public void handleClientTickEnd(ServerboundClientTickEndPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
+ this.tickEndEvent.callEvent(); // Paper - add client tick end event
|
||||
if (!this.receivedMovementThisTick) {
|
||||
this.player.setKnownMovement(Vec3.ZERO);
|
||||
}
|
||||
@@ -1957,4 +_,17 @@
|
||||
interface EntityInteraction {
|
||||
InteractionResult run(ServerPlayer player, Entity entity, InteractionHand hand);
|
||||
|
||||
@@ -931,13 +931,18 @@
|
||||
}
|
||||
|
||||
player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LEVEL_CHUNKS_LOAD_START, 0.0F));
|
||||
@@ -671,8 +_,16 @@
|
||||
@@ -671,8 +_,21 @@
|
||||
|
||||
public void sendAllPlayerInfo(ServerPlayer player) {
|
||||
player.inventoryMenu.sendAllDataToRemote();
|
||||
- player.resetSentInfo();
|
||||
+ // entityplayer.resetSentInfo();
|
||||
+ player.getBukkitEntity().updateScaledHealth(); // CraftBukkit - Update scaled health on respawn and worldchange
|
||||
+ // Paper start - send all attributes
|
||||
+ // needs to be done because the ServerPlayer instance is being reused on respawn instead of getting replaced like on vanilla
|
||||
+ java.util.Collection<net.minecraft.world.entity.ai.attributes.AttributeInstance> syncableAttributes = player.getAttributes().getSyncableAttributes();
|
||||
+ player.getBukkitEntity().injectScaledMaxHealth(syncableAttributes, true);
|
||||
+ player.connection.send(new net.minecraft.network.protocol.game.ClientboundUpdateAttributesPacket(player.getId(), syncableAttributes));
|
||||
+ // Paper end - send all attributes
|
||||
+ player.refreshEntityData(player); // CraftBukkit - SPIGOT-7218: sync metadata
|
||||
player.connection.send(new ClientboundSetHeldSlotPacket(player.getInventory().selected));
|
||||
+ // CraftBukkit start - from GameRules
|
||||
|
||||
@@ -8,3 +8,21 @@
|
||||
&& !this.effect.value().applyEffectTick(serverLevel, entity, this.amplifier)) {
|
||||
entity.removeEffect(this.effect);
|
||||
}
|
||||
@@ -408,7 +_,7 @@
|
||||
.apply(instance, MobEffectInstance.Details::create)
|
||||
)
|
||||
);
|
||||
- public static final StreamCodec<ByteBuf, MobEffectInstance.Details> STREAM_CODEC = StreamCodec.recursive(
|
||||
+ public static final StreamCodec<net.minecraft.network.FriendlyByteBuf, MobEffectInstance.Details> STREAM_CODEC = StreamCodec.recursive( // Paper - Track codec depth
|
||||
codec -> StreamCodec.composite(
|
||||
ByteBufCodecs.VAR_INT,
|
||||
MobEffectInstance.Details::amplifier,
|
||||
@@ -420,7 +_,7 @@
|
||||
MobEffectInstance.Details::showParticles,
|
||||
ByteBufCodecs.BOOL,
|
||||
MobEffectInstance.Details::showIcon,
|
||||
- codec.apply(ByteBufCodecs::optional),
|
||||
+ codec.apply(ByteBufCodecs::increaseDepth).apply(ByteBufCodecs::optional), // Paper - Track codec depth
|
||||
MobEffectInstance.Details::hiddenEffect,
|
||||
MobEffectInstance.Details::new
|
||||
)
|
||||
@@ -192,7 +192,7 @@
|
||||
this.entityData = builder.build();
|
||||
this.setPos(0.0, 0.0, 0.0);
|
||||
this.eyeHeight = this.dimensions.eyeHeight();
|
||||
+ this.despawnTime = type == EntityType.PLAYER ? -1 : level.paperConfig().entities.spawning.despawnTime.getOrDefault(type, io.papermc.paper.configuration.type.number.IntOr.Disabled.DISABLED).or(-1); // Paper - entity despawn time limit
|
||||
+ this.despawnTime = level == null || type == EntityType.PLAYER ? -1 : level.paperConfig().entities.spawning.despawnTime.getOrDefault(type, io.papermc.paper.configuration.type.number.IntOr.Disabled.DISABLED).or(-1); // Paper - entity despawn time limit
|
||||
}
|
||||
|
||||
public boolean isColliding(BlockPos pos, BlockState state) {
|
||||
|
||||
@@ -971,7 +971,7 @@
|
||||
int i = (this.getEffect(MobEffects.DAMAGE_RESISTANCE).getAmplifier() + 1) * 5;
|
||||
int i1 = 25 - i;
|
||||
float f = damageAmount * i1;
|
||||
@@ -1768,24 +_,212 @@
|
||||
@@ -1768,24 +_,219 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -984,7 +984,11 @@
|
||||
+ if (invulnerabilityRelatedLastDamage == 0) return 0D; // no last damage, no reduction
|
||||
+ // last damage existed, this means the reduction *technically* is (new damage - last damage).
|
||||
+ // If the event damage was changed to something less than invul damage, hard lock it at 0.
|
||||
+ if (d < invulnerabilityRelatedLastDamage) return 0D;
|
||||
+ //
|
||||
+ // Cast the passed in double down to a float as double -> float -> double is lossy.
|
||||
+ // If last damage is a (float) 3.2D (since the events use doubles), we cannot compare
|
||||
+ // the new damage value of this damage instance by upcasting it again to a double as 3.2D != (double) (float) 3.2D.
|
||||
+ if (d.floatValue() < invulnerabilityRelatedLastDamage) return 0D;
|
||||
+ return (double) -invulnerabilityRelatedLastDamage;
|
||||
+ };
|
||||
+ final float originalInvulnerabilityReduction = invulnerabilityReductionEquation.apply((double) amount).floatValue();
|
||||
@@ -1118,7 +1122,10 @@
|
||||
+
|
||||
+ // Apply damage to armor
|
||||
+ if (!damageSource.is(DamageTypeTags.BYPASSES_ARMOR)) {
|
||||
+ float armorDamage = (float) (event.getDamage() + event.getDamage(DamageModifier.BLOCKING) + event.getDamage(DamageModifier.HARD_HAT));
|
||||
+ float armorDamage = (float) event.getDamage();
|
||||
+ armorDamage += (float) event.getDamage(DamageModifier.INVULNERABILITY_REDUCTION);
|
||||
+ armorDamage += (float) event.getDamage(DamageModifier.BLOCKING);
|
||||
+ armorDamage += (float) event.getDamage(DamageModifier.HARD_HAT);
|
||||
+ this.hurtArmor(damageSource, armorDamage);
|
||||
+ }
|
||||
+
|
||||
|
||||
@@ -326,6 +326,16 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -981,7 +_,9 @@
|
||||
double d = this.getEquipmentDropChance(equipmentSlot);
|
||||
if (d > 1.0) {
|
||||
this.setItemSlot(equipmentSlot, ItemStack.EMPTY);
|
||||
+ this.forceDrops = true; // Paper - Add missing forceDrop toggles
|
||||
this.spawnAtLocation(level, itemBySlot);
|
||||
+ this.forceDrops = false; // Paper - Add missing forceDrop toggles
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1269,6 +_,22 @@
|
||||
public <T extends Mob> T convertTo(
|
||||
EntityType<T> entityType, ConversionParams conversionParams, EntitySpawnReason spawnReason, ConversionParams.AfterConversion<T> afterConversion
|
||||
|
||||
-8
@@ -57,14 +57,6 @@
|
||||
EntityType.VILLAGER,
|
||||
ConversionParams.single(this, false, false),
|
||||
villager -> {
|
||||
@@ -223,6 +_,7 @@
|
||||
SlotAccess slot = villager.getSlot(equipmentSlot.getIndex() + 300);
|
||||
slot.set(this.getItemBySlot(equipmentSlot));
|
||||
}
|
||||
+ this.forceDrops = false; // CraftBukkit
|
||||
|
||||
villager.setVillagerData(this.getVillagerData());
|
||||
if (this.gossips != null) {
|
||||
@@ -237,19 +_,24 @@
|
||||
villager.finalizeSpawn(serverLevel, serverLevel.getCurrentDifficultyAt(villager.blockPosition()), EntitySpawnReason.CONVERSION, null);
|
||||
villager.refreshBrain(serverLevel);
|
||||
|
||||
+44
-88
@@ -1,14 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/projectile/ThrownPotion.java
|
||||
+++ b/net/minecraft/world/entity/projectile/ThrownPotion.java
|
||||
@@ -9,6 +_,7 @@
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.effect.MobEffect;
|
||||
@@ -82,51 +_,87 @@
|
||||
@@ -82,51 +_,86 @@
|
||||
@Override
|
||||
protected void onHit(HitResult result) {
|
||||
super.onHit(result);
|
||||
@@ -28,12 +20,12 @@
|
||||
+ } else if (true || potionContents.hasEffects()) { // CraftBukkit - Call event even if no effects to apply
|
||||
if (this.isLingering()) {
|
||||
- this.makeAreaOfEffectCloud(potionContents);
|
||||
+ showParticles = this.makeAreaOfEffectCloud(potionContents, result); // CraftBukkit - Pass MovingObjectPosition // Paper
|
||||
+ showParticles = this.makeAreaOfEffectCloud(potionContents, result); // CraftBukkit - Pass HitResult // Paper
|
||||
} else {
|
||||
- this.applySplash(
|
||||
- serverLevel, potionContents.getAllEffects(), result.getType() == HitResult.Type.ENTITY ? ((EntityHitResult)result).getEntity() : null
|
||||
+ showParticles = this.applySplash(
|
||||
+ serverLevel, potionContents.getAllEffects(), result != null && result.getType() == HitResult.Type.ENTITY ? ((EntityHitResult)result).getEntity() : null, result // CraftBukkit - Pass MovingObjectPosition // Paper - More projectile API
|
||||
+ showParticles = this.applySplash( // Paper - Fix potions splash events
|
||||
+ serverLevel, potionContents.getAllEffects(), result != null && result.getType() == HitResult.Type.ENTITY ? ((EntityHitResult)result).getEntity() : null, result // CraftBukkit - Pass HitResult // Paper - More projectile API
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -48,7 +40,7 @@
|
||||
}
|
||||
|
||||
- private void applyWater(ServerLevel level) {
|
||||
+ private static final Predicate<net.minecraft.world.entity.LivingEntity> APPLY_WATER_GET_ENTITIES_PREDICATE = ThrownPotion.WATER_SENSITIVE_OR_ON_FIRE.or(Axolotl.class::isInstance); // Paper - Fix potions splash events
|
||||
+ private static final Predicate<LivingEntity> APPLY_WATER_GET_ENTITIES_PREDICATE = ThrownPotion.WATER_SENSITIVE_OR_ON_FIRE.or(Axolotl.class::isInstance); // Paper - Fix potions splash events
|
||||
+
|
||||
+ private boolean applyWater(ServerLevel level, @Nullable HitResult result) { // Paper - Fix potions splash events
|
||||
AABB aabb = this.getBoundingBox().inflate(4.0, 2.0, 4.0);
|
||||
@@ -67,20 +59,19 @@
|
||||
if (d < 16.0) {
|
||||
if (livingEntity.isSensitiveToWater()) {
|
||||
- livingEntity.hurtServer(level, this.damageSources().indirectMagic(this, this.getOwner()), 1.0F);
|
||||
+ affected.put(livingEntity.getBukkitLivingEntity(), 1.0);
|
||||
+ // livingEntity.hurtServer(level, this.damageSources().indirectMagic(this, this.getOwner()), 1.0F);
|
||||
+ affected.put(livingEntity.getBukkitLivingEntity(), 1.0); // Paper - Fix potions splash events
|
||||
}
|
||||
|
||||
if (livingEntity.isOnFire() && livingEntity.isAlive()) {
|
||||
- livingEntity.extinguishFire();
|
||||
+ extinguish.add(livingEntity.getBukkitLivingEntity());
|
||||
+ // livingEntity.extinguishFire();
|
||||
+ extinguish.add(livingEntity.getBukkitLivingEntity()); // Paper - Fix potions splash events
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- for (Axolotl axolotl : this.level().getEntitiesOfClass(Axolotl.class, aabb)) {
|
||||
- axolotl.rehydrate();
|
||||
+ // Paper start - Fix potions splash events
|
||||
+ io.papermc.paper.event.entity.WaterBottleSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callWaterBottleSplashEvent(
|
||||
+ this, result, affected, rehydrate, extinguish
|
||||
+ );
|
||||
@@ -102,14 +93,14 @@
|
||||
}
|
||||
|
||||
- private void applySplash(ServerLevel level, Iterable<MobEffectInstance> effects, @Nullable Entity entity) {
|
||||
+ private boolean applySplash(ServerLevel level, Iterable<MobEffectInstance> effects, @Nullable Entity entity, @Nullable HitResult result) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events & More projectile API
|
||||
+ private boolean applySplash(ServerLevel level, Iterable<MobEffectInstance> effects, @Nullable Entity entity, @Nullable HitResult result) { // CraftBukkit - Pass HitResult // Paper - Fix potions splash events & More projectile API
|
||||
AABB aabb = this.getBoundingBox().inflate(4.0, 2.0, 4.0);
|
||||
List<LivingEntity> entitiesOfClass = level.getEntitiesOfClass(LivingEntity.class, aabb);
|
||||
+ java.util.Map<org.bukkit.entity.LivingEntity, Double> affected = new java.util.HashMap<>(); // CraftBukkit
|
||||
if (!entitiesOfClass.isEmpty()) {
|
||||
Entity effectSource = this.getEffectSource();
|
||||
|
||||
@@ -135,33 +_,57 @@
|
||||
@@ -135,12 +_,31 @@
|
||||
double d = this.distanceToSqr(livingEntity);
|
||||
if (d < 16.0) {
|
||||
double d1;
|
||||
@@ -120,69 +111,45 @@
|
||||
d1 = 1.0 - Math.sqrt(d) / 4.0;
|
||||
}
|
||||
|
||||
- for (MobEffectInstance mobEffectInstance : effects) {
|
||||
- Holder<MobEffect> effect = mobEffectInstance.getEffect();
|
||||
- if (effect.value().isInstantenous()) {
|
||||
- effect.value().applyInstantenousEffect(level, this, this.getOwner(), livingEntity, mobEffectInstance.getAmplifier(), d1);
|
||||
- } else {
|
||||
- int i = mobEffectInstance.mapDuration(i1 -> (int)(d1 * i1 + 0.5));
|
||||
- MobEffectInstance mobEffectInstance1 = new MobEffectInstance(
|
||||
- effect, i, mobEffectInstance.getAmplifier(), mobEffectInstance.isAmbient(), mobEffectInstance.isVisible()
|
||||
- );
|
||||
- if (!mobEffectInstance1.endsWithin(20)) {
|
||||
- livingEntity.addEffect(mobEffectInstance1, effectSource);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ affected.put(livingEntity.getBukkitLivingEntity(), d1);
|
||||
+ // CraftBukkit start
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ org.bukkit.event.entity.PotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPotionSplashEvent(this, result, affected);
|
||||
+ if (!event.isCancelled() && entitiesOfClass != null && !entitiesOfClass.isEmpty()) { // do not process effects if there are no effects to process
|
||||
+ if (!event.isCancelled() && !entitiesOfClass.isEmpty()) { // do not process effects if there are no effects to process
|
||||
+ Entity effectSource = this.getEffectSource();
|
||||
+ for (org.bukkit.entity.LivingEntity victim : event.getAffectedEntities()) {
|
||||
+ if (!(victim instanceof org.bukkit.craftbukkit.entity.CraftLivingEntity craftLivingEntity)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ net.minecraft.world.entity.LivingEntity livingEntity = craftLivingEntity.getHandle();
|
||||
+ LivingEntity livingEntity = craftLivingEntity.getHandle();
|
||||
+ double d1 = event.getIntensity(victim);
|
||||
+ // CraftBukkit end
|
||||
+ for (MobEffectInstance mobEffectInstance : effects) {
|
||||
+ Holder<MobEffect> effect = mobEffectInstance.getEffect();
|
||||
+ // CraftBukkit start - Abide by PVP settings - for players only!
|
||||
+ if (!this.level().pvpMode && this.getOwner() instanceof ServerPlayer && livingEntity instanceof ServerPlayer && livingEntity != this.getOwner()) {
|
||||
+ MobEffect mobEffect = effect.value();
|
||||
+ if (mobEffect == net.minecraft.world.effect.MobEffects.MOVEMENT_SLOWDOWN || mobEffect == net.minecraft.world.effect.MobEffects.DIG_SLOWDOWN || mobEffect == net.minecraft.world.effect.MobEffects.HARM || mobEffect == net.minecraft.world.effect.MobEffects.BLINDNESS
|
||||
+ || mobEffect == net.minecraft.world.effect.MobEffects.HUNGER || mobEffect == net.minecraft.world.effect.MobEffects.WEAKNESS || mobEffect == net.minecraft.world.effect.MobEffects.POISON) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+ {
|
||||
+ {
|
||||
+ // CraftBukkit end
|
||||
+ if (effect.value().isInstantenous()) {
|
||||
+ effect.value().applyInstantenousEffect(level, this, this.getOwner(), livingEntity, mobEffectInstance.getAmplifier(), d1);
|
||||
+ } else {
|
||||
+ int i = mobEffectInstance.mapDuration(i1 -> (int)(d1 * i1 + 0.5));
|
||||
+ MobEffectInstance mobEffectInstance1 = new MobEffectInstance(
|
||||
+ effect, i, mobEffectInstance.getAmplifier(), mobEffectInstance.isAmbient(), mobEffectInstance.isVisible()
|
||||
+ );
|
||||
+ if (!mobEffectInstance1.endsWithin(20)) {
|
||||
+ livingEntity.addEffect(mobEffectInstance1, effectSource, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.POTION_SPLASH); // CraftBukkit
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
for (MobEffectInstance mobEffectInstance : effects) {
|
||||
Holder<MobEffect> effect = mobEffectInstance.getEffect();
|
||||
if (effect.value().isInstantenous()) {
|
||||
@@ -151,7 +_,7 @@
|
||||
effect, i, mobEffectInstance.getAmplifier(), mobEffectInstance.isAmbient(), mobEffectInstance.isVisible()
|
||||
);
|
||||
if (!mobEffectInstance1.endsWithin(20)) {
|
||||
- livingEntity.addEffect(mobEffectInstance1, effectSource);
|
||||
+ livingEntity.addEffect(mobEffectInstance1, effectSource, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.POTION_SPLASH); // CraftBukkit
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,9 +_,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
+ return !event.isCancelled(); // Paper - Fix potions splash events
|
||||
}
|
||||
|
||||
- private void makeAreaOfEffectCloud(PotionContents potionContents) {
|
||||
+ private boolean makeAreaOfEffectCloud(PotionContents potionContents, @Nullable HitResult result) { // CraftBukkit - Pass MovingObjectPosition // Paper - More projectile API
|
||||
+ private boolean makeAreaOfEffectCloud(PotionContents potionContents, @Nullable HitResult result) { // CraftBukkit - Pass HitResult // Paper - More projectile API
|
||||
AreaEffectCloud areaEffectCloud = new AreaEffectCloud(this.level(), this.getX(), this.getY(), this.getZ());
|
||||
if (this.getOwner() instanceof LivingEntity livingEntity) {
|
||||
areaEffectCloud.setOwner(livingEntity);
|
||||
@@ -197,41 +164,30 @@
|
||||
+ if (!(event.isCancelled() || areaEffectCloud.isRemoved() || (!event.allowsEmptyCreation() && (noEffects && !areaEffectCloud.potionContents.hasEffects())))) { // Paper - don't spawn area effect cloud if the effects were empty and not changed during the event handling
|
||||
+ this.level().addFreshEntity(areaEffectCloud);
|
||||
+ } else {
|
||||
+ areaEffectCloud.discard(null); // CraftBukkit - add Bukkit remove cause
|
||||
+ areaEffectCloud.discard(null); // add Bukkit remove cause
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ return !event.isCancelled(); // Paper - Fix potions splash events
|
||||
}
|
||||
|
||||
public boolean isLingering() {
|
||||
@@ -182,13 +_,25 @@
|
||||
@@ -182,13 +_,19 @@
|
||||
private void dowseFire(BlockPos pos) {
|
||||
BlockState blockState = this.level().getBlockState(pos);
|
||||
if (blockState.is(BlockTags.FIRE)) {
|
||||
- this.level().destroyBlock(pos, false, this);
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
|
||||
+ this.level().destroyBlock(pos, false, this);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
this.level().destroyBlock(pos, false, this);
|
||||
+ } // CraftBukkit
|
||||
} else if (AbstractCandleBlock.isLit(blockState)) {
|
||||
- AbstractCandleBlock.extinguish(null, blockState, this.level(), pos);
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.setValue(AbstractCandleBlock.LIT, false))) {
|
||||
+ AbstractCandleBlock.extinguish(null, blockState, this.level(), pos);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.setValue(AbstractCandleBlock.LIT, Boolean.valueOf(false)))) { // CraftBukkit
|
||||
AbstractCandleBlock.extinguish(null, blockState, this.level(), pos);
|
||||
+ } // CraftBukkit
|
||||
} else if (CampfireBlock.isLitCampfire(blockState)) {
|
||||
- this.level().levelEvent(null, 1009, pos, 0);
|
||||
- CampfireBlock.dowse(this.getOwner(), this.level(), pos, blockState);
|
||||
- this.level().setBlockAndUpdate(pos, blockState.setValue(CampfireBlock.LIT, Boolean.valueOf(false)));
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.setValue(CampfireBlock.LIT, false))) {
|
||||
+ this.level().levelEvent(null, 1009, pos, 0);
|
||||
+ CampfireBlock.dowse(this.getOwner(), this.level(), pos, blockState);
|
||||
+ this.level().setBlockAndUpdate(pos, blockState.setValue(CampfireBlock.LIT, false));
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.setValue(CampfireBlock.LIT, Boolean.valueOf(false)))) { // CraftBukkit
|
||||
this.level().levelEvent(null, 1009, pos, 0);
|
||||
CampfireBlock.dowse(this.getOwner(), this.level(), pos, blockState);
|
||||
this.level().setBlockAndUpdate(pos, blockState.setValue(CampfireBlock.LIT, Boolean.valueOf(false)));
|
||||
+ } // CraftBukkit
|
||||
}
|
||||
}
|
||||
|
||||
+35
@@ -72,6 +72,41 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -243,7 +_,7 @@
|
||||
private void synchronizeSlotToRemote(int slotIndex, ItemStack stack, Supplier<ItemStack> supplier) {
|
||||
if (!this.suppressRemoteUpdates) {
|
||||
ItemStack itemStack = this.remoteSlots.get(slotIndex);
|
||||
- if (!ItemStack.matches(itemStack, stack)) {
|
||||
+ if (!this.matchesRemote(itemStack, stack)) { // Paper - add flag to simplify remote matching logic
|
||||
ItemStack itemStack1 = supplier.get();
|
||||
this.remoteSlots.set(slotIndex, itemStack1);
|
||||
if (this.synchronizer != null) {
|
||||
@@ -267,7 +_,7 @@
|
||||
|
||||
private void synchronizeCarriedToRemote() {
|
||||
if (!this.suppressRemoteUpdates) {
|
||||
- if (!ItemStack.matches(this.getCarried(), this.remoteCarried)) {
|
||||
+ if (!this.matchesRemote(this.getCarried(), this.remoteCarried)) { // Paper - add flag to simplify remote matching logic
|
||||
this.remoteCarried = this.getCarried().copy();
|
||||
if (this.synchronizer != null) {
|
||||
this.synchronizer.sendCarriedChange(this, this.remoteCarried);
|
||||
@@ -276,6 +_,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - add flag to simplify remote matching logic
|
||||
+ private boolean matchesRemote(final ItemStack stack, final ItemStack other) {
|
||||
+ if (this.synchronizer != null && this.synchronizer.player() != null && this.synchronizer.player().getBukkitEntity().simplifyContainerDesyncCheck()) {
|
||||
+ // Only check the item type and count
|
||||
+ return stack == other || (stack.getCount() == other.getCount() && ItemStack.isSameItem(stack, other));
|
||||
+ }
|
||||
+ return ItemStack.matches(stack, other);
|
||||
+ }
|
||||
+ // Paper end - add flag to simplify remote matching logic
|
||||
+
|
||||
public void setRemoteSlot(int slot, ItemStack stack) {
|
||||
this.remoteSlots.set(slot, stack.copy());
|
||||
}
|
||||
@@ -343,6 +_,7 @@
|
||||
this.resetQuickCraft();
|
||||
}
|
||||
|
||||
+7
-1
@@ -1,9 +1,15 @@
|
||||
--- a/net/minecraft/world/inventory/ContainerSynchronizer.java
|
||||
+++ b/net/minecraft/world/inventory/ContainerSynchronizer.java
|
||||
@@ -11,4 +_,6 @@
|
||||
@@ -11,4 +_,12 @@
|
||||
void sendCarriedChange(AbstractContainerMenu containerMenu, ItemStack stack);
|
||||
|
||||
void sendDataChange(AbstractContainerMenu container, int id, int value);
|
||||
+
|
||||
+ default void sendOffHandSlotChange() {} // Paper - Sync offhand slot in menus
|
||||
+
|
||||
+ // Paper start - add flag to simplify remote matching logic
|
||||
+ default net.minecraft.server.level.@org.jspecify.annotations.Nullable ServerPlayer player() {
|
||||
+ return null;
|
||||
+ }
|
||||
+ // Paper end - add flag to simplify remote matching logic
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/item/EnderpearlItem.java
|
||||
+++ b/net/minecraft/world/item/EnderpearlItem.java
|
||||
@@ -21,22 +_,38 @@
|
||||
@@ -21,22 +_,42 @@
|
||||
@Override
|
||||
public InteractionResult use(Level level, Player player, InteractionHand hand) {
|
||||
ItemStack itemInHand = player.getItemInHand(hand);
|
||||
@@ -39,7 +39,11 @@
|
||||
+ );
|
||||
+ player.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ } else {
|
||||
+ // Paper end - PlayerLaunchProjectileEvent
|
||||
+ if (player instanceof net.minecraft.server.level.ServerPlayer serverPlayer) {
|
||||
+ serverPlayer.deregisterEnderPearl(thrownEnderpearl.projectile());
|
||||
+ serverPlayer.connection.send(new net.minecraft.network.protocol.game.ClientboundCooldownPacket(player.getCooldowns().getCooldownGroup(itemInHand), 0)); // prevent visual desync of cooldown on the slot
|
||||
+ }
|
||||
+ // Paper end - PlayerLaunchProjectileEvent
|
||||
+ player.containerMenu.sendAllDataToRemote();
|
||||
+ return InteractionResult.FAIL;
|
||||
+ }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/item/HangingEntityItem.java
|
||||
+++ b/net/minecraft/world/item/HangingEntityItem.java
|
||||
@@ -66,6 +_,19 @@
|
||||
@@ -66,6 +_,20 @@
|
||||
|
||||
if (hangingEntity.survives()) {
|
||||
if (!level.isClientSide) {
|
||||
@@ -14,6 +14,7 @@
|
||||
+ level.getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ if (player != null) player.containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync
|
||||
+ return InteractionResult.FAIL;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
|
||||
@@ -15,3 +15,12 @@
|
||||
ServerLevel serverLevel = (ServerLevel)attacker.level();
|
||||
attacker.setDeltaMovement(attacker.getDeltaMovement().with(Direction.Axis.Y, 0.01F));
|
||||
if (attacker instanceof ServerPlayer serverPlayer) {
|
||||
@@ -139,7 +_,7 @@
|
||||
double knockbackPower = getKnockbackPower(attacker, livingEntity, vec3);
|
||||
Vec3 vec31 = vec3.normalize().scale(knockbackPower);
|
||||
if (knockbackPower > 0.0) {
|
||||
- livingEntity.push(vec31.x, 0.7F, vec31.z);
|
||||
+ livingEntity.push(vec31.x, 0.7F, vec31.z, attacker); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
|
||||
if (livingEntity instanceof ServerPlayer serverPlayer) {
|
||||
serverPlayer.connection.send(new ClientboundSetEntityMotionPacket(serverPlayer));
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
--- a/net/minecraft/world/item/MobBucketItem.java
|
||||
+++ b/net/minecraft/world/item/MobBucketItem.java
|
||||
@@ -58,7 +_,7 @@
|
||||
}
|
||||
|
||||
if (mob != null) {
|
||||
- serverLevel.addFreshEntityWithPassengers(mob);
|
||||
+ serverLevel.addFreshEntityWithPassengers(mob, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BUCKET); // Paper - Add SpawnReason
|
||||
mob.playAmbientSound();
|
||||
}
|
||||
}
|
||||
+8
@@ -1,5 +1,13 @@
|
||||
--- a/net/minecraft/world/item/component/BundleContents.java
|
||||
+++ b/net/minecraft/world/item/component/BundleContents.java
|
||||
@@ -25,6 +_,7 @@
|
||||
.flatXmap(BundleContents::checkAndCreate, bundleContents -> DataResult.success(bundleContents.items));
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, BundleContents> STREAM_CODEC = ItemStack.STREAM_CODEC
|
||||
.apply(ByteBufCodecs.list())
|
||||
+ .apply(ByteBufCodecs::increaseDepth) // Paper - Track codec depth
|
||||
.map(BundleContents::new, contents -> contents.items);
|
||||
private static final Fraction BUNDLE_IN_BUNDLE_WEIGHT = Fraction.getFraction(1, 16);
|
||||
private static final int NO_STACK_INDEX = -1;
|
||||
@@ -76,6 +_,12 @@
|
||||
return !stack.isEmpty() && stack.getItem().canFitInsideContainerItems();
|
||||
}
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
--- a/net/minecraft/world/item/component/ChargedProjectiles.java
|
||||
+++ b/net/minecraft/world/item/component/ChargedProjectiles.java
|
||||
@@ -16,6 +_,7 @@
|
||||
.xmap(ChargedProjectiles::new, chargedProjectiles -> chargedProjectiles.items);
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, ChargedProjectiles> STREAM_CODEC = ItemStack.STREAM_CODEC
|
||||
.apply(ByteBufCodecs.list())
|
||||
+ .apply(ByteBufCodecs::increaseDepth) // Paper - Track codec depth
|
||||
.map(ChargedProjectiles::new, chargedProjectiles -> chargedProjectiles.items);
|
||||
private final List<ItemStack> items;
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
--- a/net/minecraft/world/item/component/ItemContainerContents.java
|
||||
+++ b/net/minecraft/world/item/component/ItemContainerContents.java
|
||||
@@ -22,6 +_,7 @@
|
||||
.xmap(ItemContainerContents::fromSlots, ItemContainerContents::asSlots);
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, ItemContainerContents> STREAM_CODEC = ItemStack.OPTIONAL_STREAM_CODEC
|
||||
.apply(ByteBufCodecs.list(256))
|
||||
+ .apply(ByteBufCodecs::increaseDepth) // Paper - Track codec depth
|
||||
.map(ItemContainerContents::new, contents -> contents.items);
|
||||
public final NonNullList<ItemStack> items;
|
||||
private final int hashCode;
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
--- a/net/minecraft/world/item/component/UseRemainder.java
|
||||
+++ b/net/minecraft/world/item/component/UseRemainder.java
|
||||
@@ -8,7 +_,7 @@
|
||||
public record UseRemainder(ItemStack convertInto) {
|
||||
public static final Codec<UseRemainder> CODEC = ItemStack.CODEC.xmap(UseRemainder::new, UseRemainder::convertInto);
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, UseRemainder> STREAM_CODEC = StreamCodec.composite(
|
||||
- ItemStack.STREAM_CODEC, UseRemainder::convertInto, UseRemainder::new
|
||||
+ ItemStack.STREAM_CODEC.apply(net.minecraft.network.codec.ByteBufCodecs::increaseDepth), UseRemainder::convertInto, UseRemainder::new // Paper - Track codec depth
|
||||
);
|
||||
|
||||
public ItemStack convertIntoRemainder(ItemStack stack, int count, boolean hasInfiniteMaterials, UseRemainder.OnExtraCreatedRemainder onExtraCreated) {
|
||||
+5
-3
@@ -34,7 +34,7 @@
|
||||
f = Direction.WEST.toYRot();
|
||||
set = Relative.union(Relative.DELTA, Set.of(Relative.X_ROT));
|
||||
if (entity instanceof ServerPlayer) {
|
||||
@@ -88,15 +_,21 @@
|
||||
@@ -88,15 +_,23 @@
|
||||
f = 0.0F;
|
||||
set = Relative.union(Relative.DELTA, Relative.ROTATION);
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
@@ -49,13 +49,15 @@
|
||||
- level1, bottomCenter, Vec3.ZERO, f, 0.0F, set, TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET)
|
||||
- );
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.craftbukkit.event.CraftPortalEvent event = entity.callPortalEvent(entity, org.bukkit.craftbukkit.util.CraftLocation.toBukkit(bottomCenter, level1.getWorld(), f, entity.getXRot()), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL, 0, 0);
|
||||
+ set.removeAll(Relative.ROTATION); // remove relative rotation flags to simplify event mutation
|
||||
+ float absoluteYaw = flag ? f : entity.getYRot() + f;
|
||||
+ org.bukkit.craftbukkit.event.CraftPortalEvent event = entity.callPortalEvent(entity, org.bukkit.craftbukkit.util.CraftLocation.toBukkit(bottomCenter, level1.getWorld(), absoluteYaw, entity.getXRot()), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL, 0, 0);
|
||||
+ if (event == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ org.bukkit.Location to = event.getTo();
|
||||
+
|
||||
+ return new TeleportTransition(((org.bukkit.craftbukkit.CraftWorld) to.getWorld()).getHandle(), org.bukkit.craftbukkit.util.CraftLocation.toVec3D(to), entity.getDeltaMovement(), to.getYaw(), to.getPitch(), set, TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL);
|
||||
+ return new TeleportTransition(((org.bukkit.craftbukkit.CraftWorld) to.getWorld()).getHandle(), org.bukkit.craftbukkit.util.CraftLocation.toVec3D(to), Vec3.ZERO, to.getYaw(), to.getPitch(), set, TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL);
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -163,7 +163,7 @@
|
||||
iterator.remove();
|
||||
}
|
||||
+ // Paper start - Fix bees aging inside; use exitTickCounter to keep actual bee life
|
||||
+ else {
|
||||
+ else if (level.paperConfig().entities.behavior.cooldownFailedBeehiveReleases) {
|
||||
+ beeData.exitTickCounter = beeData.occupant.minTicksInHive / 2;
|
||||
+ }
|
||||
+ // Paper end - Fix bees aging inside; use exitTickCounter to keep actual bee life
|
||||
|
||||
@@ -30,6 +30,6 @@ public class CraftGameEventTag extends CraftTag<net.minecraft.world.level.gameev
|
||||
|
||||
@Override
|
||||
public @NotNull Set<GameEvent> getValues() {
|
||||
return getHandle().stream().map((nms) -> Objects.requireNonNull(GameEvent.getByKey(CraftNamespacedKey.fromMinecraft(BuiltInRegistries.GAME_EVENT.getKey(nms.value()))), nms + " is not a recognized game event")).collect(Collectors.toUnmodifiableSet());
|
||||
return getHandle().stream().map((nms) -> Objects.requireNonNull(GameEvent.getByKey(CraftNamespacedKey.fromMinecraft(BuiltInRegistries.GAME_EVENT.getKey(nms.value()))), () -> nms + " is not a recognized game event")).collect(Collectors.toUnmodifiableSet());
|
||||
}
|
||||
}
|
||||
+5
@@ -366,6 +366,11 @@ public class VanillaArgumentProviderImpl implements VanillaArgumentProvider {
|
||||
return this.converter.convert(this.nmsBase.parse(reader));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> P parse(final StringReader reader, final S source) throws CommandSyntaxException {
|
||||
return this.converter.convert(this.nmsBase.parse(reader, source));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> CompletableFuture<Suggestions> listSuggestions(final CommandContext<S> context, final SuggestionsBuilder builder) {
|
||||
return this.nmsBase.listSuggestions(context, builder);
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ public class WrappedArgumentCommandNode<NMS, API> extends ArgumentCommandNode<Co
|
||||
@Override
|
||||
public void parse(final StringReader reader, final CommandContextBuilder<CommandSourceStack> contextBuilder) throws CommandSyntaxException {
|
||||
final int start = reader.getCursor();
|
||||
final API result = this.pureArgumentType.parse(reader); // Use the api argument parser
|
||||
final API result = this.pureArgumentType.parse(reader, contextBuilder.getSource()); // Use the api argument parser
|
||||
final ParsedArgument<CommandSourceStack, API> parsed = new ParsedArgument<>(start, reader.getCursor(), result); // Return an API parsed argument instead.
|
||||
|
||||
contextBuilder.withArgument(this.getName(), parsed);
|
||||
|
||||
@@ -184,6 +184,10 @@ public class GlobalConfiguration extends ConfigurationPart {
|
||||
public boolean skipVanillaDamageTickWhenShieldBlocked = false;
|
||||
@Comment("This setting controls what compression format is used for region files.")
|
||||
public CompressionFormat compressionFormat = CompressionFormat.ZLIB;
|
||||
@Comment("This setting controls if equipment should be updated when handling certain player actions.")
|
||||
public boolean updateEquipmentOnPlayerActions = true;
|
||||
@Comment("Only checks an item's amount and type instead of its full data during inventory desync checks.")
|
||||
public boolean simplifyRemoteItemMatching = false;
|
||||
|
||||
public enum CompressionFormat {
|
||||
GZIP,
|
||||
|
||||
+2
-1
@@ -54,7 +54,8 @@ interface RemovedConfigurations {
|
||||
path("fixes", "fix-curing-zombie-villager-discount-exploit"),
|
||||
path("entities", "mob-effects", "undead-immune-to-certain-effects"),
|
||||
path("entities", "entities-target-with-follow-range"),
|
||||
path("environment", "disable-teleportation-suffocation-check")
|
||||
path("environment", "disable-teleportation-suffocation-check"),
|
||||
path("misc", "light-queue-size")
|
||||
};
|
||||
// spawn.keep-spawn-loaded and spawn.keep-spawn-loaded-range are no longer used, but kept
|
||||
// in the world default config for compatibility with old worlds being migrated to use the gamerule
|
||||
|
||||
@@ -327,6 +327,9 @@ public class WorldConfiguration extends ConfigurationPart {
|
||||
public int day = 5;
|
||||
}
|
||||
}
|
||||
|
||||
@Comment("Adds a cooldown to bees being released after a failed release, which can occur if the hive is blocked or it being night.")
|
||||
public boolean cooldownFailedBeehiveReleases = true;
|
||||
}
|
||||
|
||||
public TrackingRangeY trackingRangeY;
|
||||
@@ -555,7 +558,6 @@ public class WorldConfiguration extends ConfigurationPart {
|
||||
public Misc misc;
|
||||
|
||||
public class Misc extends ConfigurationPart {
|
||||
public int lightQueueSize = 20;
|
||||
public boolean updatePathfindingOnBlockUpdate = true;
|
||||
public boolean showSignClickCommandFailureMsgsToPlayer = false;
|
||||
public RedstoneImplementation redstoneImplementation = RedstoneImplementation.VANILLA;
|
||||
|
||||
@@ -15,10 +15,18 @@ public record DataComponentAdapter<NMS, API>(
|
||||
) {
|
||||
static final Function<Void, Unit> API_TO_UNIT_CONVERTER = $ -> Unit.INSTANCE;
|
||||
|
||||
static final Function API_TO_UNIMPLEMENTED_CONVERTER = $ -> {
|
||||
throw new UnsupportedOperationException("Cannot convert an API value to an unimplemented type");
|
||||
};
|
||||
|
||||
public boolean isValued() {
|
||||
return this.apiToVanilla != API_TO_UNIT_CONVERTER;
|
||||
}
|
||||
|
||||
public boolean isUnimplemented() {
|
||||
return this.apiToVanilla == API_TO_UNIMPLEMENTED_CONVERTER;
|
||||
}
|
||||
|
||||
public NMS toVanilla(final API value) {
|
||||
final NMS nms = this.apiToVanilla.apply(value);
|
||||
if (this.codecValidation) {
|
||||
|
||||
+9
-2
@@ -63,6 +63,10 @@ public final class DataComponentAdapters {
|
||||
throw new UnsupportedOperationException("Cannot convert the Unit type to an API value");
|
||||
};
|
||||
|
||||
static final Function UNIMPLEMENTED_TO_API_CONVERTER = $ -> {
|
||||
throw new UnsupportedOperationException("Cannot convert the an unimplemented type to an API value");
|
||||
};
|
||||
|
||||
static final Map<ResourceKey<DataComponentType<?>>, DataComponentAdapter<?, ?>> ADAPTERS = new HashMap<>();
|
||||
|
||||
public static void bootstrap() {
|
||||
@@ -136,10 +140,9 @@ public final class DataComponentAdapters {
|
||||
// register(DataComponents.LOCK, PaperLockCode::new);
|
||||
register(DataComponents.CONTAINER_LOOT, PaperSeededContainerLoot::new);
|
||||
|
||||
// TODO: REMOVE THIS... we want to build the PR... so lets just make things UNTYPED!
|
||||
for (final Map.Entry<ResourceKey<DataComponentType<?>>, DataComponentType<?>> componentType : BuiltInRegistries.DATA_COMPONENT_TYPE.entrySet()) {
|
||||
if (!ADAPTERS.containsKey(componentType.getKey())) {
|
||||
registerUntyped((DataComponentType<Unit>) componentType.getValue());
|
||||
registerUnimplemented(componentType.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,6 +155,10 @@ public final class DataComponentAdapters {
|
||||
registerInternal(type, Function.identity(), Function.identity(), true);
|
||||
}
|
||||
|
||||
public static <NMS> void registerUnimplemented(final DataComponentType<NMS> type) {
|
||||
registerInternal(type, UNIMPLEMENTED_TO_API_CONVERTER, DataComponentAdapter.API_TO_UNIMPLEMENTED_CONVERTER, false);
|
||||
}
|
||||
|
||||
private static <NMS, API extends Handleable<NMS>> void register(final DataComponentType<NMS> type, final Function<NMS, API> vanillaToApi) {
|
||||
registerInternal(type, vanillaToApi, Handleable::getHandle, false);
|
||||
}
|
||||
|
||||
+14
-1
@@ -77,7 +77,9 @@ public abstract class PaperDataComponentType<T, NMS> implements DataComponentTyp
|
||||
if (adapter == null) {
|
||||
throw new IllegalArgumentException("No adapter found for " + key);
|
||||
}
|
||||
if (adapter.isValued()) {
|
||||
if (adapter.isUnimplemented()) {
|
||||
return new Unimplemented<>(key, type, adapter);
|
||||
} else if (adapter.isValued()) {
|
||||
return new ValuedImpl<>(key, type, adapter);
|
||||
} else {
|
||||
return new NonValuedImpl<>(key, type, adapter);
|
||||
@@ -105,4 +107,15 @@ public abstract class PaperDataComponentType<T, NMS> implements DataComponentTyp
|
||||
super(key, type, adapter);
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Unimplemented<T, NMS> extends PaperDataComponentType<T, NMS> {
|
||||
|
||||
public Unimplemented(
|
||||
final NamespacedKey key,
|
||||
final net.minecraft.core.component.DataComponentType<NMS> type,
|
||||
final DataComponentAdapter<NMS, T> adapter
|
||||
) {
|
||||
super(key, type, adapter);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -40,7 +40,7 @@ public record PaperCustomModelData(
|
||||
|
||||
@Override
|
||||
public List<Color> colors() {
|
||||
return MCUtil.transformUnmodifiable(this.impl.colors(), Color::fromRGB);
|
||||
return MCUtil.transformUnmodifiable(this.impl.colors(), color -> Color.fromRGB(color & 0x00FFFFFF)); // skip alpha channel
|
||||
}
|
||||
|
||||
static final class BuilderImpl implements CustomModelData.Builder {
|
||||
|
||||
@@ -153,12 +153,12 @@ public final class PaperRegistries {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <M, T> RegistryKey<T> registryFromNms(final ResourceKey<? extends Registry<M>> registryResourceKey) {
|
||||
return (RegistryKey<T>) Objects.requireNonNull(BY_RESOURCE_KEY.get(registryResourceKey), registryResourceKey + " doesn't have an api RegistryKey").apiKey();
|
||||
return (RegistryKey<T>) Objects.requireNonNull(BY_RESOURCE_KEY.get(registryResourceKey), () -> registryResourceKey + " doesn't have an api RegistryKey").apiKey();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <M, T> ResourceKey<? extends Registry<M>> registryToNms(final RegistryKey<T> registryKey) {
|
||||
return (ResourceKey<? extends Registry<M>>) Objects.requireNonNull(BY_REGISTRY_KEY.get(registryKey), registryKey + " doesn't have an mc registry ResourceKey").mcKey();
|
||||
return (ResourceKey<? extends Registry<M>>) Objects.requireNonNull(BY_REGISTRY_KEY.get(registryKey), () -> registryKey + " doesn't have an mc registry ResourceKey").mcKey();
|
||||
}
|
||||
|
||||
public static <M, T> TypedKey<T> fromNms(final ResourceKey<M> resourceKey) {
|
||||
|
||||
@@ -60,7 +60,7 @@ public sealed interface RegistryEntryMeta<M, A extends Keyed> permits RegistryEn
|
||||
) implements ServerSide<M, A> { // TODO remove Keyed
|
||||
|
||||
public Craft {
|
||||
Preconditions.checkArgument(!classToPreload.getPackageName().startsWith("net.minecraft"), classToPreload + " should not be in the net.minecraft package as the class-to-preload");
|
||||
Preconditions.checkArgument(!classToPreload.getPackageName().startsWith("net.minecraft"), "%s should not be in the net.minecraft package as the class-to-preload", classToPreload);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ public final class RegistryEventMap {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T, E extends LifecycleEvent> LifecycleEventType<BootstrapContext, E, ?> getEventType(final RegistryKey<T> registryKey) {
|
||||
return (LifecycleEventType<BootstrapContext, E, ?>) Objects.requireNonNull(this.eventTypes.get(registryKey), "No hook for " + registryKey);
|
||||
return (LifecycleEventType<BootstrapContext, E, ?>) Objects.requireNonNull(this.eventTypes.get(registryKey), () -> "No hook for " + registryKey);
|
||||
}
|
||||
|
||||
public boolean hasHandlers(final RegistryKey<?> registryKey) {
|
||||
|
||||
@@ -49,6 +49,11 @@ public final class DelayedRegistry<T extends Keyed, R extends Registry<T>> imple
|
||||
return this.delegate().stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return this.delegate().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable NamespacedKey getKey(final T value) {
|
||||
return this.delegate().getKey(value);
|
||||
|
||||
+1
-1
@@ -181,7 +181,7 @@ public final class FoliaAsyncScheduler implements AsyncScheduler {
|
||||
|
||||
private void setDelay(final ScheduledFuture<?> delay) {
|
||||
this.delay = delay;
|
||||
this.state = STATE_SCHEDULED_EXECUTOR;
|
||||
this.state = delay == null ? STATE_SCHEDULED_EXECUTOR : STATE_ON_TIMER;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -233,6 +233,11 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
|
||||
return this.minecraftRegistry.keySet().stream().map(minecraftKey -> this.get(CraftNamespacedKey.fromMinecraft(minecraftKey)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return this.minecraftRegistry.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<B> iterator() {
|
||||
return this.stream().iterator();
|
||||
|
||||
@@ -1725,6 +1725,7 @@ public final class CraftServer implements Server {
|
||||
|
||||
if (recipe.isPresent()) {
|
||||
RecipeHolder<CraftingRecipe> recipeCrafting = recipe.get();
|
||||
inventoryCrafting.setCurrentRecipe(recipeCrafting);
|
||||
if (craftResult.setRecipeUsed(craftPlayer.getHandle(), recipeCrafting)) {
|
||||
itemstack = recipeCrafting.value().assemble(inventoryCrafting.asCraftInput(), craftWorld.getHandle().registryAccess());
|
||||
}
|
||||
@@ -3053,7 +3054,7 @@ public final class CraftServer implements Server {
|
||||
|
||||
@Override
|
||||
public void restart() {
|
||||
org.spigotmc.RestartCommand.restart();
|
||||
CraftServer.this.restart();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3077,6 +3078,11 @@ public final class CraftServer implements Server {
|
||||
}
|
||||
// Spigot end
|
||||
|
||||
@Override
|
||||
public void restart() {
|
||||
org.spigotmc.RestartCommand.restart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] getTPS() {
|
||||
return new double[] {
|
||||
|
||||
@@ -72,7 +72,7 @@ final class CraftServerTickManager implements ServerTickManager {
|
||||
|
||||
@Override
|
||||
public boolean requestGameToSprint(final int ticks) {
|
||||
return this.manager.requestGameToSprint(ticks);
|
||||
return this.manager.requestGameToSprint(ticks, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.minecraft.Optionull;
|
||||
import net.minecraft.world.entity.monster.creaking.Creaking;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.util.CraftLocation;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@NullMarked
|
||||
public class CraftCreaking extends CraftMonster implements org.bukkit.entity.Creaking {
|
||||
|
||||
public CraftCreaking(CraftServer server, Creaking entity) {
|
||||
public CraftCreaking(final CraftServer server, final Creaking entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
@@ -14,6 +22,28 @@ public class CraftCreaking extends CraftMonster implements org.bukkit.entity.Cre
|
||||
return (Creaking) this.entity;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Location getHome() {
|
||||
return Optionull.map(this.getHandle().getHomePos(), pos -> CraftLocation.toBukkit(pos, this.getHandle().level()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activate(final Player player) {
|
||||
Preconditions.checkArgument(player != null, "player cannot be null");
|
||||
this.getHandle().activate(((CraftPlayer) player).getHandle());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivate() {
|
||||
this.getHandle().deactivate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return this.getHandle().isActive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftCreaking";
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.papermc.paper.FeatureHooks;
|
||||
import io.papermc.paper.configuration.GlobalConfiguration;
|
||||
import io.papermc.paper.entity.LookAnchor;
|
||||
import io.papermc.paper.entity.PaperPlayerGiveResult;
|
||||
import io.papermc.paper.entity.PlayerGiveResult;
|
||||
@@ -225,6 +226,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
private BorderChangeListener clientWorldBorderListener = this.createWorldBorderListener();
|
||||
public org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus; // Paper - more resource pack API
|
||||
private static final boolean DISABLE_CHANNEL_LIMIT = System.getProperty("paper.disableChannelLimit") != null; // Paper - add a flag to disable the channel limit
|
||||
private boolean simplifyContainerDesyncCheck = GlobalConfiguration.get().unsupportedSettings.simplifyRemoteItemMatching;
|
||||
private long lastSaveTime; // Paper - getLastPlayed replacement API
|
||||
|
||||
public CraftPlayer(CraftServer server, ServerPlayer entity) {
|
||||
@@ -2827,14 +2829,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
|
||||
public void updateScaledHealth(boolean sendHealth) {
|
||||
AttributeMap attributemapserver = this.getHandle().getAttributes();
|
||||
Collection<AttributeInstance> set = attributemapserver.getSyncableAttributes();
|
||||
|
||||
this.injectScaledMaxHealth(set, true);
|
||||
|
||||
// SPIGOT-3813: Attributes before health
|
||||
if (this.getHandle().connection != null) {
|
||||
this.getHandle().connection.send(new ClientboundUpdateAttributesPacket(this.getHandle().getId(), set));
|
||||
this.getHandle().connection.send(new ClientboundUpdateAttributesPacket(this.getHandle().getId(), Set.of(this.getScaledMaxHealth())));
|
||||
if (sendHealth) {
|
||||
this.sendHealthUpdate();
|
||||
}
|
||||
@@ -2874,8 +2871,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
break;
|
||||
}
|
||||
}
|
||||
collection.add(getScaledMaxHealth());
|
||||
}
|
||||
|
||||
public AttributeInstance getScaledMaxHealth() {
|
||||
AttributeInstance dummy = new AttributeInstance(Attributes.MAX_HEALTH, (attribute) -> { });
|
||||
// Spigot start
|
||||
double healthMod = this.scaledHealth ? this.healthScale : this.getMaxHealth();
|
||||
if ( healthMod >= Float.MAX_VALUE || healthMod <= 0 )
|
||||
{
|
||||
@@ -2883,8 +2883,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
this.getServer().getLogger().warning( this.getName() + " tried to crash the server with a large health attribute" );
|
||||
}
|
||||
dummy.setBaseValue(healthMod);
|
||||
// Spigot end
|
||||
collection.add(dummy);
|
||||
return dummy;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3599,4 +3598,30 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
return forwardMovement == backwardMovement ? 0 : forwardMovement ? 1 : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeathScreenScore() {
|
||||
return getHandle().getScore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeathScreenScore(final int score) {
|
||||
getHandle().setScore(score);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether container desync checks should skip the full item comparison of remote carried and changed slots
|
||||
* and should instead only check their type and amount.
|
||||
* <p>
|
||||
* This is useful if the client is not able to produce the same item stack (or as of 1.21.5, its data hashes) as the server.
|
||||
*
|
||||
* @return whether to simplify container desync checks
|
||||
*/
|
||||
public boolean simplifyContainerDesyncCheck() {
|
||||
return simplifyContainerDesyncCheck;
|
||||
}
|
||||
|
||||
public void setSimplifyContainerDesyncCheck(final boolean simplifyContainerDesyncCheck) {
|
||||
this.simplifyContainerDesyncCheck = simplifyContainerDesyncCheck;
|
||||
}
|
||||
}
|
||||
@@ -349,7 +349,6 @@ public final class CraftItemFactory implements ItemFactory {
|
||||
) {
|
||||
Preconditions.checkArgument(itemStack != null, "Argument 'itemStack' must not be null");
|
||||
Preconditions.checkArgument(!itemStack.isEmpty(), "Argument 'itemStack' cannot be empty");
|
||||
Preconditions.checkArgument(levels > 0 && levels <= 30, "Argument 'levels' must be in range [1, 30] (attempted " + levels + ")");
|
||||
Preconditions.checkArgument(random != null, "Argument 'random' must not be null");
|
||||
final net.minecraft.world.item.ItemStack internalStack = CraftItemStack.asNMSCopy(itemStack);
|
||||
if (internalStack.isEnchanted()) {
|
||||
|
||||
+8
-12
@@ -1,6 +1,5 @@
|
||||
package org.bukkit.craftbukkit.inventory.components;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@@ -57,7 +56,7 @@ public final class CraftCustomModelDataComponent implements CustomModelDataCompo
|
||||
|
||||
@Override
|
||||
public void setFloats(List<Float> floats) {
|
||||
this.handle = new CustomModelData(new ArrayList<>(floats), this.handle.flags(), this.handle.strings(), this.handle.colors());
|
||||
this.handle = new CustomModelData(List.copyOf(floats), this.handle.flags(), this.handle.strings(), this.handle.colors());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,7 +66,7 @@ public final class CraftCustomModelDataComponent implements CustomModelDataCompo
|
||||
|
||||
@Override
|
||||
public void setFlags(List<Boolean> flags) {
|
||||
this.handle = new CustomModelData(this.handle.floats(), List.copyOf(flags), this.handle.strings(), this.handle.colors()); // Paper
|
||||
this.handle = new CustomModelData(this.handle.floats(), List.copyOf(flags), this.handle.strings(), this.handle.colors());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -77,17 +76,17 @@ public final class CraftCustomModelDataComponent implements CustomModelDataCompo
|
||||
|
||||
@Override
|
||||
public void setStrings(List<String> strings) {
|
||||
this.handle = new CustomModelData(this.handle.floats(), this.handle.flags(), List.copyOf(strings), this.handle.colors()); // Paper
|
||||
this.handle = new CustomModelData(this.handle.floats(), this.handle.flags(), List.copyOf(strings), this.handle.colors());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Color> getColors() {
|
||||
return this.getHandle().colors().stream().map(Color::fromRGB).toList();
|
||||
return this.getHandle().colors().stream().map(color -> Color.fromRGB(color & 0x00FFFFFF)).toList(); // skip alpha channel
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColors(List<Color> colors) {
|
||||
this.handle = new CustomModelData(this.handle.floats(), this.handle.flags(), this.handle.strings(), colors.stream().map(Color::asRGB).toList()); // Paper
|
||||
this.handle = new CustomModelData(this.handle.floats(), this.handle.flags(), this.handle.strings(), colors.stream().map(Color::asRGB).toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -95,14 +94,11 @@ public final class CraftCustomModelDataComponent implements CustomModelDataCompo
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (this.getClass() != obj.getClass()) {
|
||||
if (obj == null || this.getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final CraftCustomModelDataComponent other = (CraftCustomModelDataComponent) obj;
|
||||
return Objects.equals(this.handle, other.handle);
|
||||
return this.handle.equals(other.handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -114,6 +110,6 @@ public final class CraftCustomModelDataComponent implements CustomModelDataCompo
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftCustomModelDataComponent{" + "handle=" + this.handle + '}';
|
||||
return "CraftCustomModelDataComponent{component=" + this.handle + '}';
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user