mirror of
https://github.com/PaperMC/Paper.git
synced 2026-11-04 17:00:09 -05:00
Compare commits
24
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
592f013c5c | ||
|
|
b4682bfef6 | ||
|
|
b685281d74 | ||
|
|
b8b4a1c7cd | ||
|
|
11dbf11014 | ||
|
|
39bd1bac06 | ||
|
|
afea65c2d2 | ||
|
|
1835b0468f | ||
|
|
b80b604636 | ||
|
|
6048c2d97c | ||
|
|
2e7bb166b1 | ||
|
|
39a1aa5c7f | ||
|
|
174eab0192 | ||
|
|
5d62ec0ed9 | ||
|
|
17524d0ee0 | ||
|
|
7799bf28ae | ||
|
|
55be6c0ef5 | ||
|
|
5dc4afc1dd | ||
|
|
f4e769a74d | ||
|
|
651d8481b7 | ||
|
|
acfe105b9d | ||
|
|
a64ea13e8e | ||
|
|
1f8197327f | ||
|
|
8021488ef4 |
No files matched your search
+12
-3
@@ -420,13 +420,19 @@ int maxPlayers = GlobalConfiguration.get().misc.maxNumOfPlayers;
|
||||
Generally for global config values you will use the fully qualified class name,
|
||||
`io.papermc.paper.configuration.GlobalConfiguration` since it's not imported in
|
||||
most places.
|
||||
---
|
||||
|
||||
If you are adding a new world config value, you must have access to an instance
|
||||
of the `net.minecraft.world.level.Level` which you can then access the config by doing
|
||||
```java
|
||||
int maxPlayers = level.paperConfig().misc.maxNumOfPlayers;
|
||||
```
|
||||
|
||||
#### Documentation
|
||||
When adding or removing a config option, you should open a pull request in our [documentation repository](https://github.com/PaperMC/docs)
|
||||
to keep it in sync and accurate. If you're unsure whether your original change will be accepted, then it's fine to wait with making the documentation
|
||||
pull request until a maintainer has reviewed your changes. Once everything is done, the documentation pull request will be merged at the same time
|
||||
that your original pull request is.
|
||||
|
||||
## Testing API changes
|
||||
|
||||
### Using the Paper Test Plugin
|
||||
@@ -470,10 +476,13 @@ If you use Maven to build your plugin:
|
||||
|
||||
### My commit doesn't need a build, what do I do?
|
||||
|
||||
Quite simple: You add `[ci skip]` to the start of your commit subject.
|
||||
Quite simple: You add `[ci skip]` to the start of your pull request title.
|
||||
|
||||
This case most often applies to changes to files like `README.md`, this very
|
||||
file (`CONTRIBUTING.md`), the `LICENSE.md` file, and so forth.
|
||||
file (`CONTRIBUTING.md`), the `LICENSE.md` file, and also small updates to Javadocs or other documentation.
|
||||
|
||||
Do *not* add [ci skip] to the start of your individual commit subjects, as your
|
||||
pull request will not be mergeable until a new commit is added due to status check requirements.
|
||||
|
||||
### Patching and building is *really* slow, what can I do?
|
||||
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ mcVersion=26.1.2
|
||||
# This is the current API version for use in (paper-)plugin.yml files
|
||||
# During snapshot cycles this should be the anticipated version of the release target
|
||||
apiVersion=26.1.2
|
||||
channel=ALPHA
|
||||
channel=STABLE
|
||||
|
||||
# Set to true while updating Minecraft version
|
||||
updatingMinecraft=false
|
||||
|
||||
@@ -134,7 +134,7 @@ public class TimingHistory {
|
||||
}
|
||||
}
|
||||
return pair(
|
||||
worldMap.get(world.getKey().toString()),
|
||||
worldMap.get(world.key().asString()),
|
||||
toArrayMapper(regions.values(),new Function<RegionData, Object>() {
|
||||
@NotNull
|
||||
@Override
|
||||
|
||||
@@ -125,10 +125,11 @@ public class MaterialTags {
|
||||
|
||||
/**
|
||||
* Covers all dyes.
|
||||
*
|
||||
* @deprecated in favour of {@link Tag#ITEMS_DYES}
|
||||
*/
|
||||
public static final MaterialSetTag DYES = new MaterialSetTag(keyFor("dyes"))
|
||||
.endsWith("_DYE")
|
||||
.ensureSize("DYES", 16).lock();
|
||||
@Deprecated(since = "26.1")
|
||||
public static final MaterialSetTag DYES = replacedBy(Tag.ITEMS_DYES);
|
||||
|
||||
/**
|
||||
* Covers all variants of gates.
|
||||
|
||||
+8
-1
@@ -9,9 +9,16 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
/**
|
||||
* Called when processing a player's attack on an entity when the player's attack strength cooldown is reset
|
||||
* Called when processing a player's attack on an entity when the player's attack strength cooldown is reset.
|
||||
*
|
||||
* @deprecated In modern Minecraft, this does not properly represent spear attacks and additionally does not
|
||||
* cover the wide range of ways that the cooldown may be reset.
|
||||
* <p>
|
||||
* Additionally, the cancellation of event is misleading as the client will reset the cooldown manually.
|
||||
* So there is no way for the server to control this.
|
||||
*/
|
||||
@NullMarked
|
||||
@Deprecated(since = "26.1", forRemoval = true)
|
||||
public class PlayerAttackEntityCooldownResetEvent extends PlayerEvent implements Cancellable {
|
||||
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.papermc.paper.datacomponent.item;
|
||||
|
||||
import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.checkerframework.checker.index.qual.Positive;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
@@ -23,7 +24,7 @@ public interface UseCooldown {
|
||||
* @return builder
|
||||
*/
|
||||
@Contract(value = "_ -> new", pure = true)
|
||||
static UseCooldown.Builder useCooldown(final float seconds) {
|
||||
static UseCooldown.Builder useCooldown(final @Positive float seconds) {
|
||||
return ItemComponentTypesBridge.bridge().useCooldown(seconds);
|
||||
}
|
||||
|
||||
@@ -33,7 +34,7 @@ public interface UseCooldown {
|
||||
* @return cooldown seconds
|
||||
*/
|
||||
@Contract(pure = true)
|
||||
float seconds();
|
||||
@Positive float seconds();
|
||||
|
||||
/**
|
||||
* The unique resource location to identify this cooldown group.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.papermc.paper.datacomponent.item;
|
||||
|
||||
import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||||
import org.checkerframework.checker.index.qual.NonNegative;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
@@ -23,7 +24,7 @@ public interface Weapon {
|
||||
*
|
||||
* @return durability
|
||||
*/
|
||||
int itemDamagePerAttack();
|
||||
@NonNegative int itemDamagePerAttack();
|
||||
|
||||
/**
|
||||
* The number of seconds that blocking is disabled.
|
||||
@@ -46,7 +47,7 @@ public interface Weapon {
|
||||
* @return the builder for chaining
|
||||
* @see #itemDamagePerAttack()
|
||||
*/
|
||||
Builder itemDamagePerAttack(int damage);
|
||||
Builder itemDamagePerAttack(@NonNegative int damage);
|
||||
|
||||
/**
|
||||
* Sets the disable blocking duration (in seconds).
|
||||
|
||||
+2
-3
@@ -27,8 +27,7 @@ public interface ItemDamageFunction {
|
||||
*
|
||||
* @return the threshold
|
||||
*/
|
||||
@NonNegative
|
||||
float threshold();
|
||||
@NonNegative float threshold();
|
||||
|
||||
/**
|
||||
* Get the constant amount of damage applied to the item, if threshold is passed.
|
||||
@@ -60,7 +59,7 @@ public interface ItemDamageFunction {
|
||||
interface Builder extends DataComponentBuilder<ItemDamageFunction> {
|
||||
|
||||
@Contract(value = "_ -> this", mutates = "this")
|
||||
ItemDamageFunction.Builder threshold(@NonNegative final float threshold);
|
||||
ItemDamageFunction.Builder threshold(final @NonNegative float threshold);
|
||||
|
||||
@Contract(value = "_ -> this", mutates = "this")
|
||||
ItemDamageFunction.Builder base(final float base);
|
||||
|
||||
+4
-1
@@ -1,5 +1,6 @@
|
||||
package io.papermc.paper.event.player;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.papermc.paper.connection.PlayerConfigurationConnection;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
@@ -52,7 +53,7 @@ public class AsyncPlayerSpawnLocationEvent extends Event {
|
||||
* @return the spawn location
|
||||
*/
|
||||
public Location getSpawnLocation() {
|
||||
return this.spawnLocation;
|
||||
return this.spawnLocation.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,6 +62,8 @@ public class AsyncPlayerSpawnLocationEvent extends Event {
|
||||
* @param location the spawn location
|
||||
*/
|
||||
public void setSpawnLocation(final Location location) {
|
||||
Preconditions.checkArgument(location != null, "Location cannot be null");
|
||||
Preconditions.checkArgument(location.getWorld() != null, "World cannot be null");
|
||||
this.spawnLocation = location.clone();
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -12,6 +12,7 @@ import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.EquipmentSlotGroup;
|
||||
import org.bukkit.inventory.ItemType;
|
||||
import org.checkerframework.checker.index.qual.NonNegative;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.Range;
|
||||
@@ -99,7 +100,7 @@ public interface EnchantmentRegistryEntry {
|
||||
*
|
||||
* @return the anvil cost of this enchantment
|
||||
*/
|
||||
@Range(from = 0, to = Integer.MAX_VALUE) int anvilCost();
|
||||
@NonNegative int anvilCost();
|
||||
|
||||
/**
|
||||
* Provides a list of slot groups this enchantment may be active in.
|
||||
@@ -245,7 +246,7 @@ public interface EnchantmentRegistryEntry {
|
||||
* @see Enchantment#getAnvilCost()
|
||||
*/
|
||||
@Contract(value = "_ -> this", mutates = "this")
|
||||
Builder anvilCost(@Range(from = 0, to = Integer.MAX_VALUE) int anvilCost);
|
||||
Builder anvilCost(@NonNegative int anvilCost);
|
||||
|
||||
/**
|
||||
* Configures the list of slot groups this enchantment may be active in.
|
||||
|
||||
@@ -2,9 +2,9 @@ package io.papermc.paper.registry.data;
|
||||
|
||||
import io.papermc.paper.registry.RegistryBuilder;
|
||||
import org.bukkit.GameEvent;
|
||||
import org.checkerframework.checker.index.qual.NonNegative;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.Range;
|
||||
|
||||
/**
|
||||
* A data-centric version-specific registry entry for the {@link GameEvent} type.
|
||||
@@ -19,7 +19,7 @@ public interface GameEventRegistryEntry {
|
||||
* @return the range of blocks, represented as an int.
|
||||
* @see GameEvent#getRange()
|
||||
*/
|
||||
@Range(from = 0, to = Integer.MAX_VALUE) int range();
|
||||
@NonNegative int range();
|
||||
|
||||
/**
|
||||
* A mutable builder for the {@link GameEventRegistryEntry} plugins may change in applicable registry events.
|
||||
@@ -42,6 +42,6 @@ public interface GameEventRegistryEntry {
|
||||
* @see GameEvent#getRange()
|
||||
*/
|
||||
@Contract(value = "_ -> this", mutates = "this")
|
||||
Builder range(@Range(from = 0, to = Integer.MAX_VALUE) int range);
|
||||
Builder range(@NonNegative int range);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import io.papermc.paper.registry.tag.Tag;
|
||||
import io.papermc.paper.registry.tag.TagKey;
|
||||
import org.bukkit.Keyed;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
|
||||
/**
|
||||
* Event object for {@link RegistryEventProvider#compose()}. This
|
||||
@@ -32,6 +33,19 @@ public interface RegistryComposeEvent<T, B extends RegistryBuilder<T>> extends R
|
||||
* @param tagKey the tag key
|
||||
* @return the tag
|
||||
* @param <V> the tag value type
|
||||
* @deprecated use {@link #retriever()}
|
||||
*/
|
||||
<V extends Keyed> Tag<V> getOrCreateTag(TagKey<V> tagKey); // TODO remove Keyed
|
||||
@Deprecated(forRemoval = true)
|
||||
default <V extends Keyed> Tag<V> getOrCreateTag(TagKey<V> tagKey) { // TODO remove Keyed
|
||||
return this.retriever().getOrCreateTag(tagKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the registry retriever, which can be used to retrieve or create
|
||||
* entries in the registry.
|
||||
*
|
||||
* @return the registry retriever
|
||||
*/
|
||||
@Contract(pure = true)
|
||||
RegistryRetriever retriever();
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import io.papermc.paper.registry.tag.Tag;
|
||||
import io.papermc.paper.registry.tag.TagKey;
|
||||
import org.bukkit.Keyed;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
|
||||
/**
|
||||
* Event object for {@link RegistryEventProvider#entryAdd()}. This
|
||||
@@ -40,6 +41,19 @@ public interface RegistryEntryAddEvent<T, B extends RegistryBuilder<T>> extends
|
||||
* @param tagKey the tag key
|
||||
* @return the tag
|
||||
* @param <V> the tag value type
|
||||
* @deprecated use {@link #retriever()}
|
||||
*/
|
||||
<V extends Keyed> Tag<V> getOrCreateTag(TagKey<V> tagKey);
|
||||
@Deprecated(forRemoval = true)
|
||||
default <V extends Keyed> Tag<V> getOrCreateTag(final TagKey<V> tagKey) { // TODO remove Keyed
|
||||
return this.retriever().getOrCreateTag(tagKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the registry retriever, which can be used to retrieve or create
|
||||
* entries in the registry.
|
||||
*
|
||||
* @return the registry retriever
|
||||
*/
|
||||
@Contract(pure = true)
|
||||
RegistryRetriever retriever();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package io.papermc.paper.registry.event;
|
||||
|
||||
import io.papermc.paper.registry.TypedKey;
|
||||
import io.papermc.paper.registry.tag.Tag;
|
||||
import io.papermc.paper.registry.tag.TagKey;
|
||||
import org.bukkit.Keyed;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
public interface RegistryRetriever {
|
||||
|
||||
/**
|
||||
* Gets or creates a tag for the given tag key. This tag
|
||||
* is then required to be filled either from the built-in or
|
||||
* custom datapack.
|
||||
*
|
||||
* @param tagKey the tag key
|
||||
* @param <V> the tag value type
|
||||
* @return the tag
|
||||
*/
|
||||
<V extends Keyed> Tag<V> getOrCreateTag(TagKey<V> tagKey); // TODO remove Keyed
|
||||
|
||||
/**
|
||||
* Gets or creates an empty instance of the given {@link TypedKey}.
|
||||
* <br>
|
||||
* Can only create instances if the applicable registry still supports adding
|
||||
* new references. If the registry doesn't, this method will throw an exception.
|
||||
*
|
||||
* @param key the key to get or create an instance for
|
||||
* @param <V> the type of the value associated with the key
|
||||
* @return an instance of the given key, or a new instance if it does not exist
|
||||
* @throws IllegalStateException if this registry does not support adding new references and the key does not exist
|
||||
*/
|
||||
<V extends Keyed> V getOrCreate(TypedKey<V> key); // TODO remove Keyed
|
||||
}
|
||||
@@ -857,13 +857,13 @@ public final class Bukkit {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the world with the given name.
|
||||
* Gets the world with the given legacy Bukkit name.
|
||||
*
|
||||
* <p>This method is considered obsolete and is a candidate for future deprecation.
|
||||
* Prefer using {@link #getWorld(NamespacedKey)}.</p>
|
||||
*
|
||||
* @param name the name of the world to retrieve
|
||||
* @return a world with the given name, or null if none exists
|
||||
* @param name the legacy Bukkit name of the world to retrieve
|
||||
* @return a world with the given legacy Bukkit name, or null if none exists
|
||||
*/
|
||||
@ApiStatus.Obsolete
|
||||
@Nullable
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package org.bukkit;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.papermc.paper.math.FinePosition;
|
||||
import io.papermc.paper.math.Rotation;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
import io.papermc.paper.math.FinePosition;
|
||||
import io.papermc.paper.math.Rotation;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.entity.Entity;
|
||||
@@ -574,7 +574,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
|
||||
} else if (o.getWorld() == null || getWorld() == null) {
|
||||
throw new IllegalArgumentException("Cannot measure distance to a null world");
|
||||
} else if (o.getWorld() != getWorld()) {
|
||||
throw new IllegalArgumentException("Cannot measure distance between " + getWorld().getKey() + " and " + o.getWorld().getKey());
|
||||
throw new IllegalArgumentException("Cannot measure distance between " + getWorld().key().asString() + " and " + o.getWorld().key().asString());
|
||||
}
|
||||
|
||||
return NumberConversions.square(x - o.x) + NumberConversions.square(y - o.y) + NumberConversions.square(z - o.z);
|
||||
@@ -1186,10 +1186,11 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
|
||||
@Utility
|
||||
@NotNull
|
||||
public Map<String, Object> serialize() {
|
||||
Map<String, Object> data = new HashMap<String, Object>();
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
|
||||
if (this.world != null) {
|
||||
data.put("world_key", getWorld().getKey().toString());
|
||||
World world = this.getWorld();
|
||||
if (world != null) {
|
||||
data.put("world_key", world.key().asString());
|
||||
}
|
||||
|
||||
data.put("x", this.x);
|
||||
@@ -1219,7 +1220,8 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
|
||||
requiresWorld = true;
|
||||
}
|
||||
if (args.containsKey("world_key")) {
|
||||
world = Bukkit.getWorld(NamespacedKey.fromString((String) args.get("world_key")));
|
||||
NamespacedKey key = NamespacedKey.fromString((String) args.get("world_key"));
|
||||
world = key == null ? null : Bukkit.getWorld(key);
|
||||
requiresWorld = true;
|
||||
}
|
||||
|
||||
@@ -1227,7 +1229,6 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
|
||||
throw new IllegalArgumentException("unknown world");
|
||||
}
|
||||
|
||||
|
||||
return new Location(world, NumberConversions.toDouble(args.get("x")), NumberConversions.toDouble(args.get("y")), NumberConversions.toDouble(args.get("z")), NumberConversions.toFloat(args.get("yaw")), NumberConversions.toFloat(args.get("pitch")));
|
||||
}
|
||||
|
||||
|
||||
@@ -2094,10 +2094,8 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
*
|
||||
* @param time The new absolute time to set this world to
|
||||
* @see #setTime(long) Sets the relative time of this world
|
||||
* @deprecated all overworlds share the same world clock by default now
|
||||
* @throws IllegalArgumentException if this world does not have a world clock (e.g. the nether)
|
||||
*/
|
||||
@Deprecated // TODO world clock API with links to it
|
||||
public void setFullTime(long time);
|
||||
|
||||
// Paper start
|
||||
|
||||
@@ -3349,8 +3349,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
/**
|
||||
* Get the player's current client side view distance.
|
||||
* <br>
|
||||
* Will default to the server view distance if the client has not yet
|
||||
* communicated this information,
|
||||
* Will default to 2 if the client has not yet communicated this information.
|
||||
*
|
||||
* @return client view distance as above
|
||||
*/
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
package org.bukkit.event.block;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.checkerframework.common.value.qual.IntRange;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
/**
|
||||
* Called when a redstone current changes
|
||||
* Called when a redstone current changes.
|
||||
* <p>
|
||||
* It includes the relevant mutation of the {@code powered} and {@code power}
|
||||
* properties even if the block is not able to produce a redstone signal.
|
||||
* For the {@code powered} property, a high state will be considered as
|
||||
* a current of 15 and a low state as 0. Setting the new current to a different
|
||||
* value will prevent most action in this case.
|
||||
*/
|
||||
@NullMarked
|
||||
public class BlockRedstoneEvent extends BlockEvent {
|
||||
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
@@ -16,46 +25,45 @@ public class BlockRedstoneEvent extends BlockEvent {
|
||||
private int newCurrent;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public BlockRedstoneEvent(@NotNull final Block block, final int oldCurrent, final int newCurrent) {
|
||||
public BlockRedstoneEvent(final Block block, final int oldCurrent, final int newCurrent) {
|
||||
super(block);
|
||||
this.oldCurrent = oldCurrent;
|
||||
this.newCurrent = newCurrent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the old current of this block
|
||||
* Gets the old current of this block.
|
||||
*
|
||||
* @return The previous current
|
||||
* @return the previous current
|
||||
*/
|
||||
public int getOldCurrent() {
|
||||
public @IntRange(from = 0, to = 15) int getOldCurrent() {
|
||||
return this.oldCurrent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the new current of this block
|
||||
* Gets the new current of this block.
|
||||
*
|
||||
* @return The new current
|
||||
* @return the new current
|
||||
*/
|
||||
public int getNewCurrent() {
|
||||
public @IntRange(from = 0, to = 15) int getNewCurrent() {
|
||||
return this.newCurrent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the new current of this block
|
||||
* Sets the new current of this block.
|
||||
*
|
||||
* @param newCurrent The new current to set
|
||||
* @param newCurrent the new current to set
|
||||
*/
|
||||
public void setNewCurrent(int newCurrent) {
|
||||
public void setNewCurrent(@IntRange(from = 0, to = 15) int newCurrent) {
|
||||
Preconditions.checkArgument(newCurrent >= 0 && newCurrent <= 15, "New current must be a redstone signal between 0 and 15 (was %s)", newCurrent);
|
||||
this.newCurrent = newCurrent;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
@@ -102,6 +102,10 @@ public class EntityUnleashEvent extends EntityEvent implements Cancellable {
|
||||
* When the entity's leashholder is more than 10 blocks away
|
||||
*/
|
||||
DISTANCE,
|
||||
/**
|
||||
* When the leashed entity is removed from the game
|
||||
*/
|
||||
LEASHED_GONE,
|
||||
UNKNOWN;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package org.bukkit.event.world;
|
||||
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
/**
|
||||
* Called when the time skips for a world clock.
|
||||
* <p>
|
||||
* If the event is cancelled the time will not change.
|
||||
*/
|
||||
// TODO - snapshot - 26.1 clock
|
||||
@ApiStatus.Experimental
|
||||
@NullMarked
|
||||
public class ClockTimeSkipEvent extends Event implements Cancellable {
|
||||
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
private final SkipReason skipReason;
|
||||
private long skipAmount;
|
||||
|
||||
private boolean cancelled;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public ClockTimeSkipEvent(final SkipReason skipReason, final long skipAmount) {
|
||||
this.skipReason = skipReason;
|
||||
this.skipAmount = skipAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the reason why the time has skipped.
|
||||
*
|
||||
* @return a SkipReason value detailing why the time has skipped
|
||||
*/
|
||||
public SkipReason getSkipReason() {
|
||||
return this.skipReason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of time that was skipped.
|
||||
*
|
||||
* @return Amount of time skipped
|
||||
*/
|
||||
public long getSkipAmount() {
|
||||
return this.skipAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount of time to skip.
|
||||
*
|
||||
* @param skipAmount Amount of time to skip
|
||||
*/
|
||||
public void setSkipAmount(long skipAmount) {
|
||||
this.skipAmount = skipAmount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancelled = cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
/**
|
||||
* An enum specifying the reason the time skipped.
|
||||
*/
|
||||
public enum SkipReason {
|
||||
|
||||
/**
|
||||
* When time is changed using the vanilla /time command.
|
||||
*/
|
||||
COMMAND,
|
||||
/**
|
||||
* When time is changed by a plugin.
|
||||
*/
|
||||
CUSTOM,
|
||||
/**
|
||||
* When time is changed by all players sleeping in their beds and the
|
||||
* night skips.
|
||||
*/
|
||||
NIGHT_SKIP
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.bukkit.event.world;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -10,60 +9,29 @@ import org.jetbrains.annotations.NotNull;
|
||||
* Called when the time skips in a world.
|
||||
* <p>
|
||||
* If the event is cancelled the time will not change.
|
||||
*
|
||||
* @see ClockTimeSkipEvent for changing of clocks that affect all worlds
|
||||
*/
|
||||
// TODO - snapshot - 26.1 API needed for clock!
|
||||
public class TimeSkipEvent extends WorldEvent implements Cancellable {
|
||||
public class TimeSkipEvent extends ClockTimeSkipEvent {
|
||||
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
private final SkipReason skipReason;
|
||||
private long skipAmount;
|
||||
|
||||
private boolean cancelled;
|
||||
private final World world;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public TimeSkipEvent(@NotNull World world, @NotNull SkipReason skipReason, long skipAmount) {
|
||||
super(world);
|
||||
this.skipReason = skipReason;
|
||||
this.skipAmount = skipAmount;
|
||||
super(skipReason, skipAmount);
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the reason why the time has skipped.
|
||||
* Returns the world that time is skipped in.
|
||||
*
|
||||
* @return a SkipReason value detailing why the time has skipped
|
||||
* @return world that time is skipped in
|
||||
*/
|
||||
@NotNull
|
||||
public SkipReason getSkipReason() {
|
||||
return this.skipReason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of time that was skipped.
|
||||
*
|
||||
* @return Amount of time skipped
|
||||
*/
|
||||
public long getSkipAmount() {
|
||||
return this.skipAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount of time to skip.
|
||||
*
|
||||
* @param skipAmount Amount of time to skip
|
||||
*/
|
||||
public void setSkipAmount(long skipAmount) {
|
||||
this.skipAmount = skipAmount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancelled = cancel;
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -76,24 +44,4 @@ public class TimeSkipEvent extends WorldEvent implements Cancellable {
|
||||
public static HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
/**
|
||||
* An enum specifying the reason the time skipped.
|
||||
*/
|
||||
public enum SkipReason {
|
||||
|
||||
/**
|
||||
* When time is changed using the vanilla /time command.
|
||||
*/
|
||||
COMMAND,
|
||||
/**
|
||||
* When time is changed by a plugin.
|
||||
*/
|
||||
CUSTOM,
|
||||
/**
|
||||
* When time is changed by all players sleeping in their beds and the
|
||||
* night skips.
|
||||
*/
|
||||
NIGHT_SKIP
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.bukkit.inventory.meta.components;
|
||||
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.checkerframework.checker.index.qual.NonNegative;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
/**
|
||||
@@ -14,14 +15,14 @@ public interface FoodComponent extends ConfigurationSerializable {
|
||||
*
|
||||
* @return nutrition value
|
||||
*/
|
||||
int getNutrition();
|
||||
@NonNegative int getNutrition();
|
||||
|
||||
/**
|
||||
* Sets the food restored by this item when eaten.
|
||||
*
|
||||
* @param nutrition new nutrition value, must be non-negative
|
||||
*/
|
||||
void setNutrition(int nutrition);
|
||||
void setNutrition(@NonNegative int nutrition);
|
||||
|
||||
/**
|
||||
* Gets the saturation restored by this item when eaten.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.spigotmc.event.player;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.Warning;
|
||||
@@ -49,6 +50,8 @@ public class PlayerSpawnLocationEvent extends PlayerEvent {
|
||||
* @param location the spawn location
|
||||
*/
|
||||
public void setSpawnLocation(@NotNull Location location) {
|
||||
Preconditions.checkArgument(location != null, "Location cannot be null");
|
||||
Preconditions.checkArgument(location.getWorld() != null, "World cannot be null");
|
||||
this.spawnLocation = location.clone();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/"
|
||||
|
||||
dependencies {
|
||||
mache("io.papermc:mache:26.1.2+build.1")
|
||||
paperclip("io.papermc:paperclip:3.0.3")
|
||||
paperclip("io.papermc:paperclip:3.0.4")
|
||||
}
|
||||
|
||||
paperweight {
|
||||
|
||||
@@ -23277,10 +23277,10 @@ index 1cd5901c8e4eb4114ab347a393fc37095c8642d2..fadce1c051e6c7bc0c3d041c0cc8ecd7
|
||||
+}
|
||||
diff --git a/io/papermc/paper/command/subcommands/ChunkDebugCommand.java b/io/papermc/paper/command/subcommands/ChunkDebugCommand.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..09f1a74740f898559edc8892ae59aca9b89a6fb3
|
||||
index 0000000000000000000000000000000000000000..d86bd11e0155f767c3bf66ac05fa4acf6d2bfccb
|
||||
--- /dev/null
|
||||
+++ b/io/papermc/paper/command/subcommands/ChunkDebugCommand.java
|
||||
@@ -0,0 +1,277 @@
|
||||
@@ -0,0 +1,269 @@
|
||||
+package io.papermc.paper.command.subcommands;
|
||||
+
|
||||
+import ca.spottedleaf.moonrise.common.util.JsonUtil;
|
||||
@@ -23301,6 +23301,8 @@ index 0000000000000000000000000000000000000000..09f1a74740f898559edc8892ae59aca9
|
||||
+import net.minecraft.world.level.chunk.LevelChunk;
|
||||
+import net.minecraft.world.level.chunk.ProtoChunk;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.NamespacedKey;
|
||||
+import org.bukkit.World;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+import org.bukkit.craftbukkit.CraftWorld;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
@@ -23327,44 +23329,33 @@ index 0000000000000000000000000000000000000000..09f1a74740f898559edc8892ae59aca9
|
||||
+
|
||||
+ @Override
|
||||
+ public List<String> tabComplete(final CommandSender sender, final String subCommand, final String[] args) {
|
||||
+ switch (subCommand) {
|
||||
+ case "debug" -> {
|
||||
+ return switch (subCommand) {
|
||||
+ case "debug":
|
||||
+ if (args.length == 1) {
|
||||
+ return CommandUtil.getListMatchingLast(sender, args, "help", "chunks");
|
||||
+ yield CommandUtil.getListMatchingLast(sender, args, "help", "chunks");
|
||||
+ }
|
||||
+ }
|
||||
+ case "holderinfo" -> {
|
||||
+ List<String> worldNames = new ArrayList<>();
|
||||
+ worldNames.add("*");
|
||||
+ for (org.bukkit.World world : Bukkit.getWorlds()) {
|
||||
+ worldNames.add(world.getKey().toString());
|
||||
+ case "chunkinfo", "holderinfo":
|
||||
+ if (args.length >= 1 && (args.length == 1 || !args[0].equals("*"))) {
|
||||
+ yield CommandUtil.getListMatchingLast(
|
||||
+ sender,
|
||||
+ args,
|
||||
+ CommandUtil.getWorldSuggestions(sender.getServer(), args.length == 1)
|
||||
+ );
|
||||
+ }
|
||||
+ if (args.length == 1) {
|
||||
+ return CommandUtil.getListMatchingLast(sender, args, worldNames);
|
||||
+ }
|
||||
+ }
|
||||
+ case "chunkinfo" -> {
|
||||
+ List<String> worldNames = new ArrayList<>();
|
||||
+ worldNames.add("*");
|
||||
+ for (org.bukkit.World world : Bukkit.getWorlds()) {
|
||||
+ worldNames.add(world.getKey().toString());
|
||||
+ }
|
||||
+ if (args.length == 1) {
|
||||
+ return CommandUtil.getListMatchingLast(sender, args, worldNames);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return Collections.emptyList();
|
||||
+ default:
|
||||
+ yield Collections.emptyList();
|
||||
+ };
|
||||
+ }
|
||||
+
|
||||
+ private void doChunkInfo(final CommandSender sender, final String[] args) {
|
||||
+ List<org.bukkit.World> worlds;
|
||||
+ List<World> worlds;
|
||||
+ if (args.length < 1 || args[0].equals("*")) {
|
||||
+ worlds = Bukkit.getWorlds();
|
||||
+ worlds = Bukkit.getServer().getWorlds();
|
||||
+ } else {
|
||||
+ worlds = new ArrayList<>(args.length);
|
||||
+ for (final String arg : args) {
|
||||
+ org.bukkit.@Nullable World world = Bukkit.getWorld(arg);
|
||||
+ @Nullable NamespacedKey key = NamespacedKey.fromString(arg);
|
||||
+ @Nullable World world = key == null ? null : sender.getServer().getWorld(key);
|
||||
+ if (world == null) {
|
||||
+ sender.sendMessage(text("World '" + arg + "' is invalid", RED));
|
||||
+ return;
|
||||
@@ -23379,7 +23370,7 @@ index 0000000000000000000000000000000000000000..09f1a74740f898559edc8892ae59aca9
|
||||
+ int accumulatedTicking = 0;
|
||||
+ int accumulatedEntityTicking = 0;
|
||||
+
|
||||
+ for (final org.bukkit.World bukkitWorld : worlds) {
|
||||
+ for (final World bukkitWorld : worlds) {
|
||||
+ final ServerLevel world = ((CraftWorld) bukkitWorld).getHandle();
|
||||
+
|
||||
+ int total = 0;
|
||||
@@ -23390,7 +23381,7 @@ index 0000000000000000000000000000000000000000..09f1a74740f898559edc8892ae59aca9
|
||||
+
|
||||
+ for (final NewChunkHolder holder : ((ChunkSystemServerLevel)world).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolders()) {
|
||||
+ final NewChunkHolder.ChunkCompletion completion = holder.getLastChunkCompletion();
|
||||
+ final ChunkAccess chunk = completion == null ? null : completion.chunk();
|
||||
+ final @Nullable ChunkAccess chunk = completion == null ? null : completion.chunk();
|
||||
+
|
||||
+ if (!(chunk instanceof LevelChunk fullChunk)) {
|
||||
+ continue;
|
||||
@@ -23424,7 +23415,7 @@ index 0000000000000000000000000000000000000000..09f1a74740f898559edc8892ae59aca9
|
||||
+ accumulatedTicking += blockTicking;
|
||||
+ accumulatedEntityTicking += entityTicking;
|
||||
+
|
||||
+ sender.sendMessage(text().append(text("Chunks in ", BLUE), text(bukkitWorld.key().toString(), GREEN), text(":")));
|
||||
+ sender.sendMessage(text().append(text("Chunks in ", BLUE), text(bukkitWorld.key().asString(), GREEN), text(":")));
|
||||
+ sender.sendMessage(text().color(DARK_AQUA).append(
|
||||
+ text("Total: ", BLUE), text(total),
|
||||
+ text(" Inactive: ", BLUE), text(inactive),
|
||||
@@ -23446,13 +23437,14 @@ index 0000000000000000000000000000000000000000..09f1a74740f898559edc8892ae59aca9
|
||||
+ }
|
||||
+
|
||||
+ private void doHolderInfo(final CommandSender sender, final String[] args) {
|
||||
+ List<org.bukkit.World> worlds;
|
||||
+ List<World> worlds;
|
||||
+ if (args.length < 1 || args[0].equals("*")) {
|
||||
+ worlds = Bukkit.getWorlds();
|
||||
+ worlds = Bukkit.getServer().getWorlds();
|
||||
+ } else {
|
||||
+ worlds = new ArrayList<>(args.length);
|
||||
+ for (final String arg : args) {
|
||||
+ org.bukkit.@Nullable World world = Bukkit.getWorld(arg);
|
||||
+ @Nullable NamespacedKey key = NamespacedKey.fromString(arg);
|
||||
+ @Nullable World world = key == null ? null : sender.getServer().getWorld(key);
|
||||
+ if (world == null) {
|
||||
+ sender.sendMessage(text("World '" + arg + "' is invalid", RED));
|
||||
+ return;
|
||||
@@ -23468,7 +23460,7 @@ index 0000000000000000000000000000000000000000..09f1a74740f898559edc8892ae59aca9
|
||||
+ int accumulatedProtoChunk = 0;
|
||||
+ int accumulatedFullChunk = 0;
|
||||
+
|
||||
+ for (final org.bukkit.World bukkitWorld : worlds) {
|
||||
+ for (final World bukkitWorld : worlds) {
|
||||
+ final ServerLevel world = ((CraftWorld) bukkitWorld).getHandle();
|
||||
+
|
||||
+ int total = 0;
|
||||
@@ -23480,7 +23472,7 @@ index 0000000000000000000000000000000000000000..09f1a74740f898559edc8892ae59aca9
|
||||
+
|
||||
+ for (final NewChunkHolder holder : ((ChunkSystemServerLevel)world).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolders()) {
|
||||
+ final NewChunkHolder.ChunkCompletion completion = holder.getLastChunkCompletion();
|
||||
+ final ChunkAccess chunk = completion == null ? null : completion.chunk();
|
||||
+ final @Nullable ChunkAccess chunk = completion == null ? null : completion.chunk();
|
||||
+
|
||||
+ ++total;
|
||||
+
|
||||
@@ -23506,7 +23498,7 @@ index 0000000000000000000000000000000000000000..09f1a74740f898559edc8892ae59aca9
|
||||
+ accumulatedProtoChunk += protoChunk;
|
||||
+ accumulatedFullChunk += fullChunk;
|
||||
+
|
||||
+ sender.sendMessage(text().append(text("Chunks in ", BLUE), text(bukkitWorld.getKey().toString(), GREEN), text(":")));
|
||||
+ sender.sendMessage(text().append(text("Chunks in ", BLUE), text(bukkitWorld.key().asString(), GREEN), text(":")));
|
||||
+ sender.sendMessage(text().color(DARK_AQUA).append(
|
||||
+ text("Total: ", BLUE), text(total),
|
||||
+ text(" Unloadable: ", BLUE), text(canUnload),
|
||||
@@ -23838,7 +23830,7 @@ index 3c1490ac7c259da04031db2f170e0c0a5f512191..470d7c770ae9d045b97e2df145cfe3cf
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896c81fc2ef 100644
|
||||
index d22f55c63eb950e1b979280612eb9f155e986406..93690b360e5eb1b8d2f8ab2198aa087c9be7ffe2 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -191,7 +191,7 @@ import net.minecraft.world.scores.ScoreboardSaveData;
|
||||
@@ -23943,7 +23935,7 @@ index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896
|
||||
|
||||
public MinecraftServer(
|
||||
// CraftBukkit start
|
||||
@@ -843,7 +929,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -853,7 +939,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
level.setSpawnSettings(level.isSpawningMonsters()); // Paper - per level difficulty (from setDifficulty(ServerLevel, Difficulty, boolean))
|
||||
this.updateEffectiveRespawnData();
|
||||
this.forceTicks = false; // CraftBukkit
|
||||
@@ -23952,7 +23944,7 @@ index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896
|
||||
new org.bukkit.event.world.WorldLoadEvent(level.getWorld()).callEvent(); // Paper - call WorldLoadEvent
|
||||
}
|
||||
|
||||
@@ -866,6 +952,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -876,6 +962,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
public abstract boolean shouldRconBroadcast();
|
||||
|
||||
public boolean saveAllChunks(final boolean silent, final boolean flush, final boolean force) {
|
||||
@@ -23964,7 +23956,7 @@ index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896
|
||||
this.scoreboard.storeToSaveDataIfDirty(this.getDataStorage().computeIfAbsent(ScoreboardSaveData.TYPE));
|
||||
boolean result = false;
|
||||
|
||||
@@ -874,7 +965,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -884,7 +975,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
LOGGER.info("Saving chunks for level '{}'/{}", level, level.dimension().identifier());
|
||||
}
|
||||
|
||||
@@ -23973,7 +23965,7 @@ index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896
|
||||
result = true;
|
||||
}
|
||||
|
||||
@@ -971,7 +1062,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -981,7 +1072,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23982,7 +23974,7 @@ index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896
|
||||
this.nextTickTimeNanos = Util.getNanos() + TimeUtil.NANOSECONDS_PER_MILLISECOND;
|
||||
|
||||
for (ServerLevel levelx : this.getAllLevels()) {
|
||||
@@ -982,17 +1073,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -992,17 +1083,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.waitUntilNextTick();
|
||||
}
|
||||
|
||||
@@ -24007,7 +23999,7 @@ index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896
|
||||
|
||||
this.isSaving = false;
|
||||
this.savedDataStorage.close();
|
||||
@@ -1013,6 +1101,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1023,6 +1111,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.services().nameToIdCache().save(false); // Paper - Perf: Async GameProfileCache saving
|
||||
}
|
||||
// Spigot end
|
||||
@@ -24022,7 +24014,7 @@ index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896
|
||||
// Paper start - Improved watchdog support - move final shutdown items here
|
||||
Util.shutdownExecutors();
|
||||
this.onServerExit();
|
||||
@@ -1107,16 +1203,31 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1117,16 +1213,31 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
// execute small amounts of other tasks just in case the number of tasks we are
|
||||
// draining is large - chunk system and packet processing may be latency sensitive
|
||||
|
||||
@@ -24057,7 +24049,7 @@ index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896
|
||||
profiler.pop(); // moonrise:run_all_chunk
|
||||
profiler.pop(); // moonrise:run_all_tasks
|
||||
|
||||
@@ -1417,6 +1528,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1427,6 +1538,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
private boolean pollTaskInternal() {
|
||||
if (super.pollTask()) {
|
||||
@@ -24065,7 +24057,7 @@ index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896
|
||||
return true;
|
||||
} else {
|
||||
boolean ret = false; // Paper - force execution of all worlds, do not just bias the first
|
||||
@@ -1558,6 +1670,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1568,6 +1680,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
// Paper - improve tick loop - moved into runAllTasksAtTickStart
|
||||
this.runAllTasksAtTickStart(); // Paper - improve tick loop
|
||||
this.tickServer(sprinting ? () -> false : this::haveTime);
|
||||
@@ -24079,7 +24071,7 @@ index e5925d778c28bd19ee4cb911fb115edc6351c26b..b4d7ccc2fd9e6c928445b09dbc6ac896
|
||||
this.tickFrame.end();
|
||||
this.recordEndOfTick(); // Paper - improve tick loop
|
||||
profiler.pop();
|
||||
@@ -2600,6 +2719,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -2618,6 +2737,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26479,7 +26471,7 @@ index 045d4b0ab26622e2763d1583e1e8fcb83ba44427..ddffd36d8213a40dc3f6cbb0ef0f33a0
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
||||
index 319335341617051c5b78578465f2224f78c3ea3d..fcb23814c2539f4e31ed5191e03cc28f4e7f9c2d 100644
|
||||
index bf8496c8cadb29db9c46015e202e7d59e2ed2f5e..f4e033fb5e5b116245dd4a381366c4e749a73f93 100644
|
||||
--- a/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -54,7 +54,7 @@ import net.minecraft.world.level.storage.SavedDataStorage;
|
||||
@@ -27004,7 +26996,7 @@ index de75dda2e6f17f0ae6e7f6a5620fd3eac9d389e5..6774d12d04fa848624fb8bf7a3c2b8bc
|
||||
List<Entity> passengers = this.entity.getPassengers();
|
||||
if (!passengers.equals(this.lastPassengers)) {
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3bb953056 100644
|
||||
index f39d48821d728232472ebc5bd6868e6a0d644721..91d27b90a9c9c348d3f93624ff8dbff8a70f522c 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -182,7 +182,7 @@ import net.minecraft.world.waypoints.WaypointTransmitter;
|
||||
@@ -27025,7 +27017,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
private final GameEventDispatcher gameEventDispatcher;
|
||||
public boolean noSave;
|
||||
private final SleepStatus sleepStatus;
|
||||
@@ -275,12 +275,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -276,12 +276,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
|
||||
public final void loadChunksForMoveAsync(AABB box, ca.spottedleaf.concurrentutil.util.Priority priority,
|
||||
java.util.function.Consumer<List<net.minecraft.world.level.chunk.ChunkAccess>> onLoad) {
|
||||
@@ -27039,7 +27031,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
int minBlockX = Mth.floor(box.minX - 1.0E-7) - 3;
|
||||
int minBlockZ = Mth.floor(box.minZ - 1.0E-7) - 3;
|
||||
|
||||
@@ -299,30 +294,171 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -300,30 +295,171 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
public final void loadChunks(int minChunkX, int minChunkZ, int maxChunkX, int maxChunkZ,
|
||||
ca.spottedleaf.concurrentutil.util.Priority priority,
|
||||
java.util.function.Consumer<List<net.minecraft.world.level.chunk.ChunkAccess>> onLoad) {
|
||||
@@ -27227,7 +27219,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -336,16 +472,135 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -337,16 +473,135 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27370,7 +27362,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
|
||||
public ServerLevel(
|
||||
final MinecraftServer server,
|
||||
@@ -409,18 +664,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -416,18 +671,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
// CraftBukkit end
|
||||
boolean syncWrites = server.forceSynchronousWrites();
|
||||
DataFixer fixerUpper = server.getFixerUpper();
|
||||
@@ -27390,7 +27382,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
this.chunkSource = new ServerChunkCache(
|
||||
this,
|
||||
levelStorage,
|
||||
@@ -431,7 +675,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -438,7 +682,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
this.spigotConfig.viewDistance, // Spigot
|
||||
this.spigotConfig.simulationDistance, // Spigot
|
||||
syncWrites,
|
||||
@@ -27399,7 +27391,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
() -> server.overworld().getDataStorage()
|
||||
, savedDataStorage // Paper - initialize SavedDataStorage earlier
|
||||
);
|
||||
@@ -471,6 +715,20 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -478,6 +722,20 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
this.waypointManager = new ServerWaypointManager(this); // Paper - optimize ServerWaypointManager with locator bar disabled
|
||||
this.environmentAttributes = EnvironmentAttributeSystem.builder().addDefaultLayers(this).build();
|
||||
this.updateSkyBrightness();
|
||||
@@ -27420,7 +27412,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
|
||||
}
|
||||
|
||||
@@ -607,8 +865,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -614,8 +872,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
profiler.push("checkDespawn");
|
||||
entity.checkDespawn();
|
||||
profiler.pop();
|
||||
@@ -27430,7 +27422,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
Entity vehicle = entity.getVehicle();
|
||||
if (vehicle != null) {
|
||||
if (!vehicle.isRemoved() && vehicle.hasPassenger(entity)) {
|
||||
@@ -632,7 +889,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -642,7 +899,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
}
|
||||
|
||||
profiler.push("entityManagement");
|
||||
@@ -27439,7 +27431,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
profiler.pop();
|
||||
profiler.push("debugSynchronizers");
|
||||
if (this.debugSynchronizers.hasAnySubscriberFor(DebugSubscriptions.NEIGHBOR_UPDATES)) {
|
||||
@@ -649,7 +906,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -659,7 +916,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
|
||||
@Override
|
||||
public boolean shouldTickBlocksAt(final long chunkPos) {
|
||||
@@ -27451,7 +27443,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
}
|
||||
|
||||
protected void tickTime() {
|
||||
@@ -673,7 +933,60 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -683,7 +943,60 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
this.players.stream().filter(LivingEntity::isSleeping).collect(Collectors.toList()).forEach(player -> player.stopSleepInBed(false, false));
|
||||
}
|
||||
|
||||
@@ -27512,7 +27504,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
ChunkPos chunkPos = chunk.getPos();
|
||||
int minX = chunkPos.getMinBlockX();
|
||||
int minZ = chunkPos.getMinBlockZ();
|
||||
@@ -682,7 +995,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -692,7 +1005,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
|
||||
if (!this.paperConfig().environment.disableIceAndSnow) { // Paper - Option to disable ice and snow
|
||||
for (int i = 0; i < tickSpeed; i++) {
|
||||
@@ -27521,7 +27513,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
this.tickPrecipitation(this.getBlockRandomPos(minX, 0, minZ, 15));
|
||||
}
|
||||
}
|
||||
@@ -690,31 +1003,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -700,31 +1013,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
|
||||
profiler.popPush("tickBlocks");
|
||||
if (tickSpeed > 0) {
|
||||
@@ -27554,7 +27546,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
}
|
||||
|
||||
profiler.pop();
|
||||
@@ -1037,6 +1326,12 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1047,6 +1336,12 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
if (fluidState.is(type)) {
|
||||
fluidState.tick(this, pos, blockState);
|
||||
}
|
||||
@@ -27567,7 +27559,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
}
|
||||
|
||||
private void tickBlock(final BlockPos pos, final Block type) {
|
||||
@@ -1044,6 +1339,12 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1054,6 +1349,12 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
if (state.is(type)) {
|
||||
state.tick(this, pos, this.random);
|
||||
}
|
||||
@@ -27580,7 +27572,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
}
|
||||
|
||||
// Paper start - log detailed entity tick information
|
||||
@@ -1128,6 +1429,11 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1138,6 +1439,11 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
}
|
||||
|
||||
public void save(final @Nullable ProgressListener progressListener, final boolean flush, final boolean noSave) {
|
||||
@@ -27592,7 +27584,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
ServerChunkCache chunkSource = this.getChunkSource();
|
||||
if (!noSave) {
|
||||
new org.bukkit.event.world.WorldSaveEvent(this.getWorld()).callEvent(); // CraftBukkit
|
||||
@@ -1140,13 +1446,18 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1150,13 +1456,18 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
progressListener.progressStage(Component.translatable("menu.savingChunks"));
|
||||
}
|
||||
|
||||
@@ -27616,7 +27608,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
}
|
||||
|
||||
private void saveLevelData(final boolean sync) {
|
||||
@@ -1267,7 +1578,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1277,7 +1588,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
this.removePlayerImmediately((ServerPlayer)existing, Entity.RemovalReason.DISCARDED);
|
||||
}
|
||||
|
||||
@@ -27625,7 +27617,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
}
|
||||
|
||||
// CraftBukkit start
|
||||
@@ -1298,7 +1609,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1308,7 +1619,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
@@ -27634,7 +27626,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1309,7 +1620,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1319,7 +1630,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
|
||||
public boolean tryAddFreshEntityWithPassengers(final Entity entity, final org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) {
|
||||
// CraftBukkit end
|
||||
@@ -27643,7 +27635,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
return false;
|
||||
} else {
|
||||
this.addFreshEntityWithPassengers(entity, reason); // CraftBukkit
|
||||
@@ -2102,7 +2413,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -2112,7 +2423,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27652,7 +27644,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
output.write(String.format(Locale.ROOT, "block_entity_tickers: %d\n", this.blockEntityTickers.size()));
|
||||
output.write(String.format(Locale.ROOT, "block_ticks: %d\n", this.getBlockTicks().count()));
|
||||
output.write(String.format(Locale.ROOT, "fluid_ticks: %d\n", this.getFluidTicks().count()));
|
||||
@@ -2120,13 +2431,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -2130,13 +2441,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
Path chunks = rootDir.resolve("chunks.csv");
|
||||
|
||||
try (Writer output = Files.newBufferedWriter(chunks)) {
|
||||
@@ -27668,7 +27660,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
}
|
||||
|
||||
Path entities = rootDir.resolve("entities.csv");
|
||||
@@ -2221,8 +2532,8 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -2231,8 +2542,8 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
Locale.ROOT,
|
||||
"players: %s, entities: %s [%s], block_entities: %d [%s], block_ticks: %d, fluid_ticks: %d, chunk_source: %s",
|
||||
this.players.size(),
|
||||
@@ -27679,7 +27671,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
this.blockEntityTickers.size(),
|
||||
getTypeCount(this.blockEntityTickers, TickingBlockEntity::getType),
|
||||
this.getBlockTicks().count(),
|
||||
@@ -2255,15 +2566,25 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -2265,15 +2576,25 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@Override
|
||||
public LevelEntityGetter<Entity> getEntities() {
|
||||
org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot
|
||||
@@ -27708,7 +27700,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
}
|
||||
|
||||
public void startTickingChunk(final LevelChunk levelChunk) {
|
||||
@@ -2280,8 +2601,8 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -2290,8 +2611,8 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
|
||||
public void waitForEntities(final ChunkPos centerChunk, final int radius) {
|
||||
List<ChunkPos> chunks = ChunkPos.rangeClosed(centerChunk, radius).toList();
|
||||
@@ -27719,7 +27711,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
|
||||
for (ChunkPos chunk : chunks) {
|
||||
if (!this.areEntitiesLoaded(chunk.pack())) {
|
||||
@@ -2302,28 +2623,38 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -2312,28 +2633,38 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
@@ -27764,7 +27756,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
}
|
||||
|
||||
public boolean anyPlayerCloseEnoughForSpawning(final BlockPos pos) {
|
||||
@@ -2340,7 +2671,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -2350,7 +2681,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
}
|
||||
|
||||
public boolean canSpawnEntitiesInChunk(final ChunkPos pos) {
|
||||
@@ -27776,7 +27768,7 @@ index 5dc8f5d3738bb3b97e0a0d98fcec4fda44d741a3..0b7fb9e17a43d2eddd96a55e422626c3
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2388,7 +2722,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -2398,7 +2732,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
public CrashReportCategory fillReportDetails(final CrashReport report) {
|
||||
CrashReportCategory category = super.fillReportDetails(report);
|
||||
WeatherData weatherData = this.getWeatherData();
|
||||
@@ -28487,11 +28479,11 @@ index 83af9ee3ba150da85b9b694cd76a5fabb5b2d8ef..1fb40837bd02672850ec9adc2797190d
|
||||
PrepareSpawnTask.this.loadListener.updateFocus(this.spawnLevel.dimension(), spawnChunk);
|
||||
}
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index 0c4de29676732f5e84d7584e1f89d508addc1cc4..0613b053f4a75c0884280011ee092d9d108b3857 100644
|
||||
index eff42b94fd182abace988d9649952e04dc35b268..02605ebe6ef10727badadbf7fc4cec52583df965 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -983,8 +983,8 @@ public abstract class PlayerList {
|
||||
player.connection.send(this.server.clockManager().createFullSyncPacket());
|
||||
@@ -982,8 +982,8 @@ public abstract class PlayerList {
|
||||
player.connection.send(level.clockManager().createFullSyncPacket(player)); // Paper - per-world time; per-player time
|
||||
player.connection.send(new ClientboundSetDefaultSpawnPositionPacket(level.getRespawnData()));
|
||||
// Paper start - view distances
|
||||
- player.connection.send(new ClientboundSetChunkCacheRadiusPacket(io.papermc.paper.FeatureHooks.getViewDistance(level)));
|
||||
@@ -28501,7 +28493,7 @@ index 0c4de29676732f5e84d7584e1f89d508addc1cc4..0613b053f4a75c0884280011ee092d9d
|
||||
// Paper end - view distances
|
||||
if (level.isRaining()) {
|
||||
// CraftBukkit start - handle player weather
|
||||
@@ -1201,7 +1201,7 @@ public abstract class PlayerList {
|
||||
@@ -1200,7 +1200,7 @@ public abstract class PlayerList {
|
||||
|
||||
public void setViewDistance(final int viewDistance) {
|
||||
this.viewDistance = viewDistance;
|
||||
@@ -28510,7 +28502,7 @@ index 0c4de29676732f5e84d7584e1f89d508addc1cc4..0613b053f4a75c0884280011ee092d9d
|
||||
|
||||
for (ServerLevel level : this.server.getAllLevels()) {
|
||||
level.getChunkSource().setViewDistance(viewDistance);
|
||||
@@ -1210,7 +1210,7 @@ public abstract class PlayerList {
|
||||
@@ -1209,7 +1209,7 @@ public abstract class PlayerList {
|
||||
|
||||
public void setSimulationDistance(final int simulationDistance) {
|
||||
this.simulationDistance = simulationDistance;
|
||||
@@ -30053,7 +30045,7 @@ index e07a7bda45146686a6ac2d20507df9fc8630514f..f84e651e2a34e76a0a71993332e4be1b
|
||||
|
||||
// Paper start - Affects Spawning API
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 81c3f9f04040b6cfa014ce55e517bd9b374ec252..0958fe0438c3e934b885acf78a0f8003ef8bb694 100644
|
||||
index 838bad640b7f8e42fc8972918cfc7c1d9807e2b3..c0f901c4ac61a0aa2b480f102feb3669b111f4c0 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -87,6 +87,7 @@ import net.minecraft.world.level.storage.LevelData;
|
||||
@@ -30725,10 +30717,10 @@ index 81c3f9f04040b6cfa014ce55e517bd9b374ec252..0958fe0438c3e934b885acf78a0f8003
|
||||
+ this.maxSectionY = this.maxY >> 4;
|
||||
+ this.sectionsCount = this.maxSectionY - this.minSectionY + 1;
|
||||
+ // Paper end - getblock optimisations - cache world height/sections
|
||||
this.spigotConfig = new org.spigotmc.SpigotWorldConfig(bukkitName, CraftNamespacedKey.fromMinecraft(dimension.identifier())); // Spigot
|
||||
final org.bukkit.NamespacedKey worldKey = CraftNamespacedKey.fromMinecraft(dimension.identifier()); // Paper
|
||||
this.spigotConfig = new org.spigotmc.SpigotWorldConfig(bukkitName, worldKey); // Spigot
|
||||
this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config
|
||||
this.generator = generator;
|
||||
@@ -230,6 +863,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
@@ -231,6 +864,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
this.registryAccess = registryAccess;
|
||||
this.palettedContainerFactory = PalettedContainerFactory.create(registryAccess);
|
||||
this.damageSources = new DamageSources(registryAccess);
|
||||
@@ -30736,7 +30728,7 @@ index 81c3f9f04040b6cfa014ce55e517bd9b374ec252..0958fe0438c3e934b885acf78a0f8003
|
||||
}
|
||||
|
||||
// Paper start - Cancel hit for vanished players
|
||||
@@ -511,7 +1145,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
@@ -512,7 +1146,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
this.setBlocksDirty(pos, blockState, blockState1);
|
||||
}
|
||||
|
||||
@@ -30745,7 +30737,7 @@ index 81c3f9f04040b6cfa014ce55e517bd9b374ec252..0958fe0438c3e934b885acf78a0f8003
|
||||
this.sendBlockUpdated(pos, blockState, state, flags);
|
||||
}
|
||||
|
||||
@@ -844,6 +1478,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
@@ -846,6 +1480,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
// Paper - Fix MC-117075 use removeAll - remove iterator in favour of indexed for loop, ensuring compile error if something uses iter incorrectly
|
||||
boolean tickBlockEntities = this.tickRateManager().runsNormally();
|
||||
|
||||
@@ -30753,7 +30745,7 @@ index 81c3f9f04040b6cfa014ce55e517bd9b374ec252..0958fe0438c3e934b885acf78a0f8003
|
||||
// Paper start - Fix MC-117075 use removeAll
|
||||
final it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<@Nullable TickingBlockEntity> toRemove = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>();
|
||||
toRemove.add(null);
|
||||
@@ -854,6 +1489,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
@@ -856,6 +1491,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
toRemove.add(ticker); // Paper - Fix MC-117075 use removeAll
|
||||
} else if (tickBlockEntities && this.shouldTickBlocksAt(ticker.getPos())) {
|
||||
ticker.tick();
|
||||
@@ -30765,7 +30757,7 @@ index 81c3f9f04040b6cfa014ce55e517bd9b374ec252..0958fe0438c3e934b885acf78a0f8003
|
||||
}
|
||||
}
|
||||
|
||||
@@ -873,6 +1513,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
@@ -874,6 +1514,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD);
|
||||
// Paper end - Prevent block entity and entity crashes
|
||||
}
|
||||
@@ -30773,7 +30765,7 @@ index 81c3f9f04040b6cfa014ce55e517bd9b374ec252..0958fe0438c3e934b885acf78a0f8003
|
||||
}
|
||||
|
||||
// Paper start - Option to prevent armor stands from doing entity lookups
|
||||
@@ -880,7 +1521,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
@@ -881,7 +1522,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
public boolean noCollision(@Nullable Entity entity, AABB box) {
|
||||
if (entity instanceof net.minecraft.world.entity.decoration.ArmorStand && !entity.level().paperConfig().entities.armorStands.doCollisionEntityLookups)
|
||||
return false;
|
||||
@@ -30789,7 +30781,7 @@ index 81c3f9f04040b6cfa014ce55e517bd9b374ec252..0958fe0438c3e934b885acf78a0f8003
|
||||
}
|
||||
// Paper end - Option to prevent armor stands from doing entity lookups
|
||||
|
||||
@@ -1025,7 +1673,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
@@ -1026,7 +1674,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
if (!this.isInValidBounds(pos)) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -30798,7 +30790,7 @@ index 81c3f9f04040b6cfa014ce55e517bd9b374ec252..0958fe0438c3e934b885acf78a0f8003
|
||||
? null
|
||||
: this.getChunkAt(pos).getBlockEntity(pos, LevelChunk.EntityCreationType.IMMEDIATE);
|
||||
}
|
||||
@@ -1105,20 +1753,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
@@ -1106,20 +1754,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
@Override
|
||||
public List<Entity> getEntities(final @Nullable Entity except, final AABB bb, final Predicate<? super Entity> selector) {
|
||||
Profiler.get().incrementCounter("getEntities");
|
||||
@@ -30826,7 +30818,7 @@ index 81c3f9f04040b6cfa014ce55e517bd9b374ec252..0958fe0438c3e934b885acf78a0f8003
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1134,33 +1777,94 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
@@ -1135,33 +1778,94 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
this.getEntities(type, bb, selector, output, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
@@ -30941,7 +30933,7 @@ index 81c3f9f04040b6cfa014ce55e517bd9b374ec252..0958fe0438c3e934b885acf78a0f8003
|
||||
|
||||
public <T extends Entity> boolean hasEntities(final EntityTypeTest<Entity, T> type, final AABB bb, final Predicate<? super T> selector) {
|
||||
Profiler.get().incrementCounter("hasEntities");
|
||||
@@ -1465,13 +2169,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
@@ -1466,13 +2170,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
|
||||
// Paper start - allow patching this logic
|
||||
public final int getEntityCount() {
|
||||
@@ -32693,7 +32685,7 @@ index 54d57f80b1cca351cac2aa59477a0e57334816e7..94652b00e18ffcbe02f1ad0578d671e2
|
||||
public @Nullable BlockEntity getBlockEntity(final BlockPos pos) {
|
||||
return this.wrapped.getBlockEntity(pos);
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 1bbb8ca0c4a5087cf35c8af8362d867ef868cbd3..b5b514b292f9fdbe410aba5facec1638682c9075 100644
|
||||
index d747e7058f78ac1fd02f3dc8e06670ed484cd42b..c0c212fd50cf97ae311035b370e8b4d40d82229e 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -64,7 +64,7 @@ import net.minecraft.world.ticks.TickContainerAccess;
|
||||
|
||||
+13
-12
@@ -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 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6b33beff8 100644
|
||||
index 1511cbd2e6123a00d22694353ee4989d539fe0f0..104976b3eb04d80e5be5bd020cf16c647b1cde27 100644
|
||||
--- a/net/minecraft/network/Connection.java
|
||||
+++ b/net/minecraft/network/Connection.java
|
||||
@@ -65,7 +65,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -40,7 +40,7 @@ index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6
|
||||
public Channel channel;
|
||||
public SocketAddress address;
|
||||
// Spigot start
|
||||
@@ -123,6 +123,10 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -124,6 +124,10 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
public boolean handledLegacyLoginEvent; // Paper - playerloginevent
|
||||
public net.minecraft.server.level.@Nullable ServerPlayer savedPlayerForLegacyEvents; // Paper - playerloginevent & PlayerSpawnLocationEvent
|
||||
public org.bukkit.event.player.PlayerResourcePackStatusEvent.@Nullable Status resourcePackStatus; // Paper
|
||||
@@ -51,7 +51,7 @@ index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6
|
||||
|
||||
public Connection(final PacketFlow receiving) {
|
||||
this.receiving = receiving;
|
||||
@@ -393,11 +397,38 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -394,11 +398,38 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
}
|
||||
|
||||
public void send(final Packet<?> packet, final @Nullable ChannelFutureListener listener, final boolean flush) {
|
||||
@@ -93,7 +93,7 @@ index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,7 +437,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -407,7 +438,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
this.flushQueue();
|
||||
action.accept(this);
|
||||
} else {
|
||||
@@ -102,7 +102,7 @@ index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,21 +451,41 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -421,21 +452,42 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
}
|
||||
|
||||
private void doSendPacket(final Packet<?> packet, final @Nullable ChannelFutureListener listener, final boolean flush) {
|
||||
@@ -133,7 +133,8 @@ index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6
|
||||
+ }
|
||||
+ } catch (final Exception e) {
|
||||
+ LOGGER.error("NetworkException: {}", player, e);
|
||||
+ this.disconnect(Component.translatable("disconnect.genericReason", "Internal Exception: " + e.getMessage()));
|
||||
+ Component reason = Component.translatable("disconnect.genericReason", "Internal Exception: " + e.getMessage());
|
||||
+ this.send(new ClientboundDisconnectPacket(reason), PacketSendListener.thenRun(() -> this.disconnect(reason)));
|
||||
+ packet.onPacketDispatchFinish(player, null);
|
||||
}
|
||||
+ // Paper end - Optimize network
|
||||
@@ -148,7 +149,7 @@ index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,16 +497,57 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -447,16 +499,57 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,7 +212,7 @@ index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6
|
||||
|
||||
private static final int MAX_PER_TICK = io.papermc.paper.configuration.GlobalConfiguration.get().misc.maxJoinsPerTick; // Paper - Buffer joins to world
|
||||
private static int joinAttemptsThisTick; // Paper - Buffer joins to world
|
||||
@@ -525,6 +617,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -526,6 +619,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
|
||||
public void disconnect(final DisconnectionDetails details) {
|
||||
this.preparing = false; // Spigot
|
||||
@@ -219,7 +220,7 @@ index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6
|
||||
if (this.channel == null) {
|
||||
this.delayedDisconnect = details;
|
||||
}
|
||||
@@ -714,7 +807,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -715,7 +809,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
public void handleDisconnection() {
|
||||
if (this.channel != null && !this.channel.isOpen()) {
|
||||
if (this.disconnectionHandled) {
|
||||
@@ -228,7 +229,7 @@ index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6
|
||||
} else {
|
||||
this.disconnectionHandled = true;
|
||||
PacketListener packetListener = this.getPacketListener();
|
||||
@@ -725,7 +818,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -726,7 +820,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
);
|
||||
disconnectListener.onDisconnect(details);
|
||||
}
|
||||
@@ -237,7 +238,7 @@ index 0bc6ab5e498f82c5b3cbdf8dddfed6c8406ad511..9cd6ec17981da310be1d35054af080d6
|
||||
// Paper start - Add PlayerConnectionCloseEvent
|
||||
if (packetListener instanceof net.minecraft.server.network.ServerCommonPacketListenerImpl commonPacketListener) {
|
||||
/* Player was logged in, either game listener or configuration listener */
|
||||
@@ -760,4 +853,96 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -761,4 +855,96 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
public void setBandwidthLogger(final LocalSampleLogger bandwidthLogger) {
|
||||
this.bandwidthDebugMonitor = new BandwidthDebugMonitor(bandwidthLogger);
|
||||
}
|
||||
@@ -371,7 +372,7 @@ index 1480d0db90f5797e3dee19503e52d1e783493ac3..bd76e55ea56dd7c1e232806d1d13a747
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/net/minecraft/server/network/ServerConnectionListener.java b/net/minecraft/server/network/ServerConnectionListener.java
|
||||
index b0445b4ad9adb6d2dec08537559d2ed243ca69bb..b266e4f7b437578356568d86910e3b428ee66523 100644
|
||||
index 387ac8a4e67ef07df73ce98d0add0937314ee497..9ae7c79e5088d9e1e3fb7e0dca00bb15fee118b6 100644
|
||||
--- a/net/minecraft/server/network/ServerConnectionListener.java
|
||||
+++ b/net/minecraft/server/network/ServerConnectionListener.java
|
||||
@@ -52,11 +52,13 @@ public class ServerConnectionListener {
|
||||
|
||||
@@ -354,10 +354,10 @@ index 0000000000000000000000000000000000000000..ce6b57eeeeb1bd652f4bb53c19dcfbc0
|
||||
+ }
|
||||
+}
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 3cd2fcc38f3989bb5124ba5bc2f4597103e7a111..6d847ff3646b27fe9bc75e792d813a7f611ab3e5 100644
|
||||
index 91d27b90a9c9c348d3f93624ff8dbff8a70f522c..f4bbccee849ee3711a3b838884e4bcf4e24da039 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -857,6 +857,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -864,6 +864,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
profiler.pop();
|
||||
}
|
||||
|
||||
@@ -365,7 +365,7 @@ index 3cd2fcc38f3989bb5124ba5bc2f4597103e7a111..6d847ff3646b27fe9bc75e792d813a7f
|
||||
this.entityTickList
|
||||
.forEach(
|
||||
entity -> {
|
||||
@@ -1373,12 +1374,15 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1383,12 +1384,15 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
entity.totalEntityAge++; // Paper - age-like counter for all entities
|
||||
profiler.push(entity.typeHolder()::getRegisteredName);
|
||||
profiler.incrementCounter("tickNonPassenger");
|
||||
@@ -382,7 +382,7 @@ index 3cd2fcc38f3989bb5124ba5bc2f4597103e7a111..6d847ff3646b27fe9bc75e792d813a7f
|
||||
}
|
||||
// Paper start - log detailed entity tick information
|
||||
} finally {
|
||||
@@ -1389,7 +1393,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1399,7 +1403,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
// Paper end - log detailed entity tick information
|
||||
}
|
||||
|
||||
@@ -391,7 +391,7 @@ index 3cd2fcc38f3989bb5124ba5bc2f4597103e7a111..6d847ff3646b27fe9bc75e792d813a7f
|
||||
if (entity.isRemoved() || entity.getVehicle() != vehicle) {
|
||||
entity.stopRiding();
|
||||
} else if (entity instanceof Player || this.entityTickList.contains(entity)) {
|
||||
@@ -1399,12 +1403,21 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1409,12 +1413,21 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
ProfilerFiller profiler = Profiler.get();
|
||||
profiler.push(entity.typeHolder()::getRegisteredName);
|
||||
profiler.incrementCounter("tickPassenger");
|
||||
@@ -521,10 +521,10 @@ index e087d5596979044fe7fbcf7f2cccdae4e81a3d3a..fea6c3b48c4eb162fbdc099fa775bc31
|
||||
delta = this.maybeBackOffFromEdge(delta, moverType);
|
||||
Vec3 movement = this.collide(delta);
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index c4da41f3b5ba6d8492d3776654b1ce62a5015895..6a0ebbdfcc0bc07915574c1cf87463e82213ca7e 100644
|
||||
index 8b0abe9c7a3907419f6e4d55ea22fb9bc749f28b..36c0081e3e8f8776293ae619156cd0828fe5b21d 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3385,6 +3385,14 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
@@ -3372,6 +3372,14 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
protected void playAttackSound() {
|
||||
}
|
||||
|
||||
@@ -817,7 +817,7 @@ index 3a590d4dc980a2912e9cc043d8c8db4cf9d60803..06ab7c48b18c03af494ab10fc2b584ce
|
||||
+
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 0958fe0438c3e934b885acf78a0f8003ef8bb694..31c7223d2d01573c24d4ad83737fa2c2752db028 100644
|
||||
index c0f901c4ac61a0aa2b480f102feb3669b111f4c0..07c301ba02c7f2c032a29a0ae3bdf95fc522c03b 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -155,6 +155,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
|
||||
+6
-6
@@ -266,10 +266,10 @@ index 319325e741cc314b84844bb49ea569aaf014f319..20b5cfe1ce36d74cd6b2f95566a1bc34
|
||||
+ // Paper end - Use Velocity cipher
|
||||
}
|
||||
diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java
|
||||
index 9cd6ec17981da310be1d35054af080d6b33beff8..d7ed1621709c491525daaf7adc8e9f0d781c93e1 100644
|
||||
index 104976b3eb04d80e5be5bd020cf16c647b1cde27..5a23f95aff982ecc58d2e2bc994f4e495285069c 100644
|
||||
--- a/net/minecraft/network/Connection.java
|
||||
+++ b/net/minecraft/network/Connection.java
|
||||
@@ -738,11 +738,22 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -740,11 +740,22 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
return connection;
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ index 9cd6ec17981da310be1d35054af080d6b33beff8..d7ed1621709c491525daaf7adc8e9f0d
|
||||
|
||||
public boolean isEncrypted() {
|
||||
return this.encrypted;
|
||||
@@ -780,16 +791,17 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -782,16 +793,17 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
|
||||
public void setupCompression(final int threshold, final boolean validateDecompressed) {
|
||||
if (threshold >= 0) {
|
||||
@@ -318,7 +318,7 @@ index 9cd6ec17981da310be1d35054af080d6b33beff8..d7ed1621709c491525daaf7adc8e9f0d
|
||||
this.channel.pipeline().fireUserEventTriggered(io.papermc.paper.network.ConnectionEvent.COMPRESSION_THRESHOLD_SET); // Paper - Add Channel initialization listeners
|
||||
} else {
|
||||
diff --git a/net/minecraft/server/network/ServerConnectionListener.java b/net/minecraft/server/network/ServerConnectionListener.java
|
||||
index b266e4f7b437578356568d86910e3b428ee66523..0b57e3bcd0319e4e9571fddbcb85db5a3105b8b2 100644
|
||||
index 391435cf3d279c8f5a889702b50f57626864c7bb..19a77c8269c3f1998985d533d9099c7e6cf76af4 100644
|
||||
--- a/net/minecraft/server/network/ServerConnectionListener.java
|
||||
+++ b/net/minecraft/server/network/ServerConnectionListener.java
|
||||
@@ -77,6 +77,10 @@ public class ServerConnectionListener {
|
||||
@@ -333,10 +333,10 @@ index b266e4f7b437578356568d86910e3b428ee66523..0b57e3bcd0319e4e9571fddbcb85db5a
|
||||
.add(
|
||||
new ServerBootstrap()
|
||||
diff --git a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
index 8203765d5570644b4c8f6790f361bca2c7066b25..718f00ad9c587a4b0c12f351c10d462113f16ac3 100644
|
||||
index c1edad046cbdd1627edba58bc06aef5c058e79eb..3a0d47a716ce5c5345640ed67ac306101791892b 100644
|
||||
--- a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -245,11 +245,9 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
@@ -251,11 +251,9 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
}
|
||||
|
||||
SecretKey secretKey = packet.getSecretKey(serverPrivateKey);
|
||||
|
||||
@@ -19,12 +19,14 @@ Co-authored-by: egg82 <eggys82@gmail.com>
|
||||
|
||||
diff --git a/io/papermc/paper/redstone/RedstoneWireTurbo.java b/io/papermc/paper/redstone/RedstoneWireTurbo.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ff747a1ecdf3c888bca0d69de4f85dcd810b6139
|
||||
index 0000000000000000000000000000000000000000..8e03419df1469c6fecfaa82fcb319a58635b39f3
|
||||
--- /dev/null
|
||||
+++ b/io/papermc/paper/redstone/RedstoneWireTurbo.java
|
||||
@@ -0,0 +1,954 @@
|
||||
@@ -0,0 +1,949 @@
|
||||
+package io.papermc.paper.redstone;
|
||||
+
|
||||
+import com.google.common.collect.Lists;
|
||||
+import com.google.common.collect.Maps;
|
||||
+import java.util.List;
|
||||
+import java.util.Map;
|
||||
+import java.util.concurrent.ThreadLocalRandom;
|
||||
@@ -36,11 +38,7 @@ index 0000000000000000000000000000000000000000..ff747a1ecdf3c888bca0d69de4f85dcd
|
||||
+import net.minecraft.world.level.block.Block;
|
||||
+import net.minecraft.world.level.block.RedStoneWireBlock;
|
||||
+import net.minecraft.world.level.block.state.BlockState;
|
||||
+import org.bukkit.craftbukkit.block.CraftBlock;
|
||||
+import org.bukkit.event.block.BlockRedstoneEvent;
|
||||
+
|
||||
+import com.google.common.collect.Lists;
|
||||
+import com.google.common.collect.Maps;
|
||||
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||
+
|
||||
+public final class RedstoneWireTurbo {
|
||||
+ /*
|
||||
@@ -914,12 +912,9 @@ index 0000000000000000000000000000000000000000..ff747a1ecdf3c888bca0d69de4f85dcd
|
||||
+ // always be in the range of 0 to 15, the following if will correct that.
|
||||
+ if (k > j) j = k;
|
||||
+
|
||||
+ // egg82's amendment
|
||||
+ // Adding Bukkit's BlockRedstoneEvent - er.. event.
|
||||
+ // [egg82] Adding Bukkit's BlockRedstoneEvent.
|
||||
+ if (i != j) {
|
||||
+ BlockRedstoneEvent event = new BlockRedstoneEvent(CraftBlock.at(worldIn, upd.self), i, j);
|
||||
+ worldIn.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ j = event.getNewCurrent();
|
||||
+ j = CraftEventFactory.callRedstoneChange(worldIn, upd.self, i, j).getNewCurrent();
|
||||
+ }
|
||||
+
|
||||
+ if (i != j) {
|
||||
@@ -978,10 +973,10 @@ index 0000000000000000000000000000000000000000..ff747a1ecdf3c888bca0d69de4f85dcd
|
||||
+ }
|
||||
+}
|
||||
diff --git a/net/minecraft/world/level/block/RedStoneWireBlock.java b/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
index 0ee7bc3a10896a4f59fa94df158bce741aea0464..a677c3bfddfa0b7947394a3975ec43794be07d7e 100644
|
||||
index 0ee7bc3a10896a4f59fa94df158bce741aea0464..a00002774755eb90a0b772fe742b30a5e09452cf 100644
|
||||
--- a/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
+++ b/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
@@ -269,6 +269,60 @@ public class RedStoneWireBlock extends Block {
|
||||
@@ -269,6 +269,56 @@ public class RedStoneWireBlock extends Block {
|
||||
return relativeState.isFaceSturdy(level, relativePos, Direction.UP) || relativeState.is(Blocks.HOPPER);
|
||||
}
|
||||
|
||||
@@ -1021,12 +1016,8 @@ index 0ee7bc3a10896a4f59fa94df158bce741aea0464..a677c3bfddfa0b7947394a3975ec4379
|
||||
+ int oldPower = state.getValue(POWER);
|
||||
+ int newPower = ((DefaultRedstoneWireEvaluator) evaluator).calculateTargetStrength(level, pos);
|
||||
+ if (oldPower != newPower) {
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent event = new org.bukkit.event.block.BlockRedstoneEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), oldPower, newPower);
|
||||
+ level.getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ newPower = event.getNewCurrent();
|
||||
+
|
||||
+ if (level.getBlockState(pos) == state) {
|
||||
+ newPower = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, oldPower, newPower).getNewCurrent();
|
||||
+ state = state.setValue(POWER, newPower);
|
||||
+ // [Space Walker] suppress shape updates and emit those manually to
|
||||
+ // bypass the new neighbor update stack.
|
||||
@@ -1042,7 +1033,7 @@ index 0ee7bc3a10896a4f59fa94df158bce741aea0464..a677c3bfddfa0b7947394a3975ec4379
|
||||
private void updatePowerStrength(
|
||||
final Level level,
|
||||
final BlockPos pos,
|
||||
@@ -303,7 +357,7 @@ public class RedStoneWireBlock extends Block {
|
||||
@@ -303,7 +353,7 @@ public class RedStoneWireBlock extends Block {
|
||||
@Override
|
||||
protected void onPlace(final BlockState state, final Level level, final BlockPos pos, final BlockState oldState, final boolean movedByPiston) {
|
||||
if (!oldState.is(state.getBlock()) && !level.isClientSide()) {
|
||||
@@ -1051,7 +1042,7 @@ index 0ee7bc3a10896a4f59fa94df158bce741aea0464..a677c3bfddfa0b7947394a3975ec4379
|
||||
|
||||
for (Direction direction : Direction.Plane.VERTICAL) {
|
||||
level.updateNeighborsAt(pos.relative(direction), this);
|
||||
@@ -320,7 +374,7 @@ public class RedStoneWireBlock extends Block {
|
||||
@@ -320,7 +370,7 @@ public class RedStoneWireBlock extends Block {
|
||||
level.updateNeighborsAt(pos.relative(direction), this);
|
||||
}
|
||||
|
||||
@@ -1060,7 +1051,7 @@ index 0ee7bc3a10896a4f59fa94df158bce741aea0464..a677c3bfddfa0b7947394a3975ec4379
|
||||
this.updateNeighborsOfNeighboringWires(level, pos);
|
||||
}
|
||||
}
|
||||
@@ -347,7 +401,7 @@ public class RedStoneWireBlock extends Block {
|
||||
@@ -347,7 +397,7 @@ public class RedStoneWireBlock extends Block {
|
||||
if (!level.isClientSide()) {
|
||||
if (block != this || !useExperimentalEvaluator(level)) {
|
||||
if (state.canSurvive(level, pos)) {
|
||||
@@ -1070,10 +1061,10 @@ index 0ee7bc3a10896a4f59fa94df158bce741aea0464..a677c3bfddfa0b7947394a3975ec4379
|
||||
dropResources(state, level, pos);
|
||||
level.removeBlock(pos, false);
|
||||
diff --git a/net/minecraft/world/level/redstone/DefaultRedstoneWireEvaluator.java b/net/minecraft/world/level/redstone/DefaultRedstoneWireEvaluator.java
|
||||
index fe52dd304bc03b172654b89acb382c7f410d7946..afdcbb9e5a4c859d82bfb33a1d253514c17eed39 100644
|
||||
index 45c3586a653f4ec22b9fb859b2869503d0b6c5b3..81b7b625dbfe69f2a9d74dac000a0e60a75db839 100644
|
||||
--- a/net/minecraft/world/level/redstone/DefaultRedstoneWireEvaluator.java
|
||||
+++ b/net/minecraft/world/level/redstone/DefaultRedstoneWireEvaluator.java
|
||||
@@ -47,7 +47,7 @@ public class DefaultRedstoneWireEvaluator extends RedstoneWireEvaluator {
|
||||
@@ -44,7 +44,7 @@ public class DefaultRedstoneWireEvaluator extends RedstoneWireEvaluator {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-20
@@ -22,30 +22,25 @@ Alternate Current's wire handler.
|
||||
|
||||
diff --git a/alternate/current/wire/LevelHelper.java b/alternate/current/wire/LevelHelper.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ff663d3089627e75221aa128aff4bf5cc459addb
|
||||
index 0000000000000000000000000000000000000000..dd533953f33aacfc91a8acad6c9a9d601df0bd86
|
||||
--- /dev/null
|
||||
+++ b/alternate/current/wire/LevelHelper.java
|
||||
@@ -0,0 +1,66 @@
|
||||
@@ -0,0 +1,61 @@
|
||||
+package alternate.current.wire;
|
||||
+
|
||||
+import org.bukkit.craftbukkit.block.CraftBlock;
|
||||
+import org.bukkit.event.block.BlockRedstoneEvent;
|
||||
+
|
||||
+import net.minecraft.core.BlockPos;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.world.level.block.Block;
|
||||
+import net.minecraft.world.level.block.state.BlockState;
|
||||
+import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
+import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||
+import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
+import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||
+
|
||||
+class LevelHelper {
|
||||
+
|
||||
+ static int doRedstoneEvent(ServerLevel level, BlockPos pos, int prevPower, int newPower) {
|
||||
+ BlockRedstoneEvent event = new BlockRedstoneEvent(CraftBlock.at(level, pos), prevPower, newPower);
|
||||
+ level.getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ return event.getNewCurrent();
|
||||
+ return CraftEventFactory.callRedstoneChange(level, pos, prevPower, newPower).getNewCurrent();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
@@ -2326,18 +2321,18 @@ index 0000000000000000000000000000000000000000..298076a0db4e6ee6e4775ac43bf749d9
|
||||
+ }
|
||||
+}
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 26c05173e7fb2bf055afda1717af0dd2e997118d..ffe3ae41dd3d8c4141f81edf0b92001db957ebac 100644
|
||||
index f4bbccee849ee3711a3b838884e4bcf4e24da039..0b9fbf0ae658f0b3e9c6106a42fb70948b6fb9be 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -232,6 +232,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
public final WorldGenSettings worldGenSettings;
|
||||
@@ -233,6 +233,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
private @Nullable ServerClockManager clockManager;
|
||||
public boolean hasPhysicsEvent = true; // Paper - BlockPhysicsEvent
|
||||
public boolean hasEntityMoveEvent; // Paper - Add EntityMoveEvent
|
||||
+ private final alternate.current.wire.WireHandler wireHandler = new alternate.current.wire.WireHandler(this); // Paper - optimize redstone (Alternate Current)
|
||||
|
||||
@Override
|
||||
public @Nullable LevelChunk getChunkIfLoaded(int x, int z) {
|
||||
@@ -2765,6 +2766,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -2775,6 +2776,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
return this.debugSynchronizers;
|
||||
}
|
||||
|
||||
@@ -2352,10 +2347,10 @@ index 26c05173e7fb2bf055afda1717af0dd2e997118d..ffe3ae41dd3d8c4141f81edf0b92001d
|
||||
return toLevel.dimension() != Level.NETHER || this.getGameRules().get(GameRules.ALLOW_ENTERING_NETHER_USING_PORTALS);
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 31c7223d2d01573c24d4ad83737fa2c2752db028..8df070a7135411806d42ea692b566c4d8389a47b 100644
|
||||
index 07c301ba02c7f2c032a29a0ae3bdf95fc522c03b..7e4cf8a13e0ff2198cb7b6d80fb3fa343339943b 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -2152,6 +2152,17 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
@@ -2153,6 +2153,17 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
return this.palettedContainerFactory;
|
||||
}
|
||||
|
||||
@@ -2374,7 +2369,7 @@ index 31c7223d2d01573c24d4ad83737fa2c2752db028..8df070a7135411806d42ea692b566c4d
|
||||
NONE("none"),
|
||||
BLOCK("block"),
|
||||
diff --git a/net/minecraft/world/level/block/RedStoneWireBlock.java b/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
index a677c3bfddfa0b7947394a3975ec43794be07d7e..ed471efa3ab705de62aec81c3940c1b9c5acdbc5 100644
|
||||
index a00002774755eb90a0b772fe742b30a5e09452cf..1e863e97bd1dc99ed6e2c0602f78f457ac618965 100644
|
||||
--- a/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
+++ b/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
@@ -269,7 +269,7 @@ public class RedStoneWireBlock extends Block {
|
||||
@@ -2386,7 +2381,7 @@ index a677c3bfddfa0b7947394a3975ec43794be07d7e..ed471efa3ab705de62aec81c3940c1b9
|
||||
// The bulk of the new functionality is found in RedstoneWireTurbo.java
|
||||
io.papermc.paper.redstone.RedstoneWireTurbo turbo = new io.papermc.paper.redstone.RedstoneWireTurbo(this);
|
||||
|
||||
@@ -357,7 +357,13 @@ public class RedStoneWireBlock extends Block {
|
||||
@@ -353,7 +353,13 @@ public class RedStoneWireBlock extends Block {
|
||||
@Override
|
||||
protected void onPlace(final BlockState state, final Level level, final BlockPos pos, final BlockState oldState, final boolean movedByPiston) {
|
||||
if (!oldState.is(state.getBlock()) && !level.isClientSide()) {
|
||||
@@ -2401,7 +2396,7 @@ index a677c3bfddfa0b7947394a3975ec43794be07d7e..ed471efa3ab705de62aec81c3940c1b9
|
||||
|
||||
for (Direction direction : Direction.Plane.VERTICAL) {
|
||||
level.updateNeighborsAt(pos.relative(direction), this);
|
||||
@@ -374,7 +380,13 @@ public class RedStoneWireBlock extends Block {
|
||||
@@ -370,7 +376,13 @@ public class RedStoneWireBlock extends Block {
|
||||
level.updateNeighborsAt(pos.relative(direction), this);
|
||||
}
|
||||
|
||||
@@ -2416,7 +2411,7 @@ index a677c3bfddfa0b7947394a3975ec43794be07d7e..ed471efa3ab705de62aec81c3940c1b9
|
||||
this.updateNeighborsOfNeighboringWires(level, pos);
|
||||
}
|
||||
}
|
||||
@@ -399,9 +411,15 @@ public class RedStoneWireBlock extends Block {
|
||||
@@ -395,9 +407,15 @@ public class RedStoneWireBlock extends Block {
|
||||
final BlockState state, final Level level, final BlockPos pos, final Block block, final @Nullable Orientation orientation, final boolean movedByPiston
|
||||
) {
|
||||
if (!level.isClientSide()) {
|
||||
|
||||
@@ -5,10 +5,10 @@ Subject: [PATCH] Incremental chunk and player saving
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 40a500011e7fcb6f5b07ff289f737ed9d3550296..da8c04aa02032c4c582709727f8f7f0b66b697b1 100644
|
||||
index 248a01f06ec822737a741873166aa4e502a7ba07..c4eb56fc227afd7e9631624537dd8e67ae3a8bea 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -958,7 +958,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -968,7 +968,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
public boolean saveAllChunks(final boolean silent, final boolean flush, final boolean force, final boolean close) {
|
||||
// Paper end - add close param
|
||||
@@ -17,7 +17,7 @@ index 40a500011e7fcb6f5b07ff289f737ed9d3550296..da8c04aa02032c4c582709727f8f7f0b
|
||||
boolean result = false;
|
||||
|
||||
for (ServerLevel level : this.getAllLevels()) {
|
||||
@@ -970,13 +970,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -980,13 +980,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
result = true;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ index 40a500011e7fcb6f5b07ff289f737ed9d3550296..da8c04aa02032c4c582709727f8f7f0b
|
||||
|
||||
if (flush) {
|
||||
for (ServerLevel level : this.getAllLevels()) {
|
||||
@@ -990,11 +984,25 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1000,11 +994,25 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ index 40a500011e7fcb6f5b07ff289f737ed9d3550296..da8c04aa02032c4c582709727f8f7f0b
|
||||
boolean result = this.saveAllChunks(silent, flush, force);
|
||||
this.warnOnLowDiskSpace();
|
||||
var5 = result;
|
||||
@@ -1641,9 +1649,31 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1651,9 +1659,31 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
this.ticksUntilAutosave--;
|
||||
@@ -94,10 +94,10 @@ index 40a500011e7fcb6f5b07ff289f737ed9d3550296..da8c04aa02032c4c582709727f8f7f0b
|
||||
ProfilerFiller profiler = Profiler.get();
|
||||
this.server.spark.executeMainThreadTasks(); // Paper - spark
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index ffe3ae41dd3d8c4141f81edf0b92001db957ebac..98461e8468a7eeaef2544ee907ff64de1fd42a49 100644
|
||||
index 0b9fbf0ae658f0b3e9c6106a42fb70948b6fb9be..bbeb0f673f2b23d1748e33364dc12ac16528d4c4 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1441,6 +1441,15 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1451,6 +1451,15 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
public boolean mayInteract(final Entity entity, final BlockPos pos) {
|
||||
return !(entity instanceof Player player && (this.server.isUnderSpawnProtection(this, pos, player) || !this.getWorldBorder().isWithinBounds(pos)));
|
||||
}
|
||||
@@ -126,7 +126,7 @@ index 41816ca8d4ef3d959d2b88cd4b2eedaaa541e612..82e87270d1ad89ad7aa56e028ced6b99
|
||||
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10;
|
||||
private static final int FLY_STAT_RECORDING_SPEED = 25;
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index 0613b053f4a75c0884280011ee092d9d108b3857..b69bcaa1e27a4fbe9a9568f3c9e1843167abe1f5 100644
|
||||
index 02605ebe6ef10727badadbf7fc4cec52583df965..3d62e4d275f32c8604a1bdaefb6b9b1d4ea6e21f 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -418,6 +418,7 @@ public abstract class PlayerList {
|
||||
@@ -137,7 +137,7 @@ index 0613b053f4a75c0884280011ee092d9d108b3857..b69bcaa1e27a4fbe9a9568f3c9e18431
|
||||
this.playerIo.save(player);
|
||||
ServerStatsCounter stats = player.getStats(); // CraftBukkit
|
||||
if (stats != null) {
|
||||
@@ -951,10 +952,24 @@ public abstract class PlayerList {
|
||||
@@ -950,10 +951,24 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public void saveAll() {
|
||||
|
||||
+9
-9
@@ -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 0b86c393b041607278c1b712a62ec9ae3640f4de..80162ffef5d54d00663dcb58a087884ec8a3eaaa 100644
|
||||
index fad017de5d9fc31988aa4edf97fb3f9bcbee56c8..06132bde0aed9dd9088c884ee31056b9176b6f90 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -634,6 +634,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -633,6 +633,7 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
|
||||
vehicle.move(MoverType.PLAYER, new Vec3(xDist, yDist, zDist));
|
||||
@@ -17,7 +17,7 @@ index 0b86c393b041607278c1b712a62ec9ae3640f4de..80162ffef5d54d00663dcb58a087884e
|
||||
double oyDist = yDist;
|
||||
xDist = targetX - vehicle.getX();
|
||||
yDist = targetY - vehicle.getY();
|
||||
@@ -649,7 +650,17 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -648,7 +649,17 @@ public class ServerGamePacketListenerImpl
|
||||
LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", vehicle.getPlainTextName(), this.player.getPlainTextName(), Math.sqrt(movedDist));
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ index 0b86c393b041607278c1b712a62ec9ae3640f4de..80162ffef5d54d00663dcb58a087884e
|
||||
vehicle.absSnapTo(oldX, oldY, oldZ, targetYRot, targetXRot);
|
||||
this.send(ClientboundMoveVehiclePacket.fromEntity(vehicle));
|
||||
vehicle.removeLatestMovementRecording();
|
||||
@@ -728,9 +739,32 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -727,9 +738,32 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
|
||||
private boolean noBlocksAround(final Entity entity) {
|
||||
@@ -72,7 +72,7 @@ index 0b86c393b041607278c1b712a62ec9ae3640f4de..80162ffef5d54d00663dcb58a087884e
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1542,7 +1576,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1541,7 +1575,7 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ index 0b86c393b041607278c1b712a62ec9ae3640f4de..80162ffef5d54d00663dcb58a087884e
|
||||
xDist = targetX - this.lastGoodX; // Paper - diff on change, used for checking large move vectors above
|
||||
yDist = targetY - this.lastGoodY; // Paper - diff on change, used for checking large move vectors above
|
||||
zDist = targetZ - this.lastGoodZ; // Paper - diff on change, used for checking large move vectors above
|
||||
@@ -1581,6 +1615,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1580,6 +1614,7 @@ public class ServerGamePacketListenerImpl
|
||||
boolean playerStandsOnSomething = this.player.verticalCollisionBelow;
|
||||
this.player.move(MoverType.PLAYER, new Vec3(xDist, yDist, zDist));
|
||||
this.player.onGround = packet.isOnGround(); // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move
|
||||
@@ -89,7 +89,7 @@ index 0b86c393b041607278c1b712a62ec9ae3640f4de..80162ffef5d54d00663dcb58a087884e
|
||||
// Paper start - prevent position desync
|
||||
if (this.awaitingPositionFromClient != null) {
|
||||
return; // ... thanks Mojang for letting move calls teleport across dimensions.
|
||||
@@ -1614,7 +1649,17 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1613,7 +1648,17 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
|
||||
// Paper start - Add fail move event
|
||||
@@ -108,7 +108,7 @@ index 0b86c393b041607278c1b712a62ec9ae3640f4de..80162ffef5d54d00663dcb58a087884e
|
||||
if (!allowMovement) {
|
||||
io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.CLIPPED_INTO_BLOCK,
|
||||
targetX, targetY, targetZ, targetYRot, targetXRot, false);
|
||||
@@ -1752,7 +1797,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1751,7 +1796,7 @@ public class ServerGamePacketListenerImpl
|
||||
|
||||
private boolean updateAwaitingTeleport() {
|
||||
if (this.awaitingPositionFromClient != null) {
|
||||
@@ -117,7 +117,7 @@ index 0b86c393b041607278c1b712a62ec9ae3640f4de..80162ffef5d54d00663dcb58a087884e
|
||||
this.awaitingTeleportTime = this.tickCount;
|
||||
this.teleport(
|
||||
this.awaitingPositionFromClient.x,
|
||||
@@ -1771,6 +1816,34 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1770,6 +1815,34 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ index d87a00ee3cd04ce25dbe46ae6b386b7f0799102c..ace440c2b82a6368aa27a85ff433ba2c
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
index 079ab378920c0e52ef4e42ef20b37bd389f40870..dc9020f210c21a626c948d013cc6c972cbc093f3 100644
|
||||
index abeca4714053fd0a4fa489d496e2e0b844de40a8..7ed50fc00c58c7781c958df1d828a67adf696f3e 100644
|
||||
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
@@ -39,12 +39,13 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
@@ -138,7 +138,7 @@ index 079ab378920c0e52ef4e42ef20b37bd389f40870..dc9020f210c21a626c948d013cc6c972
|
||||
private volatile boolean suspendFlushingOnServerThread = false;
|
||||
// CraftBukkit start
|
||||
public final org.bukkit.craftbukkit.CraftServer cserver;
|
||||
@@ -61,13 +62,14 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
@@ -60,13 +61,14 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
public ServerCommonPacketListenerImpl(final MinecraftServer server, final Connection connection, final CommonListenerCookie cookie) {
|
||||
this.server = server;
|
||||
this.connection = connection;
|
||||
@@ -154,7 +154,7 @@ index 079ab378920c0e52ef4e42ef20b37bd389f40870..dc9020f210c21a626c948d013cc6c972
|
||||
// Paper end
|
||||
}
|
||||
|
||||
@@ -100,13 +102,41 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
@@ -99,13 +101,35 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
|
||||
@Override
|
||||
public void handleKeepAlive(final ServerboundKeepAlivePacket packet) {
|
||||
@@ -184,25 +184,19 @@ index 079ab378920c0e52ef4e42ef20b37bd389f40870..dc9020f210c21a626c948d013cc6c972
|
||||
+ if (ka.challengeId() == packet.getId()) {
|
||||
+ itr.remove();
|
||||
+
|
||||
+ if (!this.processedDisconnect) {
|
||||
+ LOGGER.info("Disconnecting {} for sending keepalive response ({}) out-of-order!", this.playerProfile().name(), packet.getId());
|
||||
+ this.disconnectAsync(TIMEOUT_DISCONNECTION_MESSAGE, io.papermc.paper.connection.DisconnectionReason.TIMEOUT);
|
||||
+ return;
|
||||
+ }
|
||||
+ break;
|
||||
+ LOGGER.info("Disconnecting {} for sending keepalive response ({}) out-of-order!", this.playerProfile().name(), packet.getId());
|
||||
+ this.disconnectAsync(TIMEOUT_DISCONNECTION_MESSAGE, io.papermc.paper.connection.DisconnectionReason.TIMEOUT);
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ if (!this.processedDisconnect) {
|
||||
+ LOGGER.info("Disconnecting {} for sending keepalive response ({}) without matching challenge!", this.playerProfile().name(), packet.getId());
|
||||
+ this.disconnectAsync(TIMEOUT_DISCONNECTION_MESSAGE, io.papermc.paper.connection.DisconnectionReason.TIMEOUT);
|
||||
+ return;
|
||||
+ }
|
||||
+ LOGGER.info("Disconnecting {} for sending keepalive response ({}) without matching challenge!", this.playerProfile().name(), packet.getId());
|
||||
+ this.disconnectAsync(TIMEOUT_DISCONNECTION_MESSAGE, io.papermc.paper.connection.DisconnectionReason.TIMEOUT);
|
||||
+ // Paper end - improve keepalives
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -233,20 +263,23 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
@@ -232,20 +256,23 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
protected void keepConnectionAlive() {
|
||||
Profiler.get().push("keepAlive");
|
||||
long now = Util.getMillis();
|
||||
@@ -221,7 +215,7 @@ index 079ab378920c0e52ef4e42ef20b37bd389f40870..dc9020f210c21a626c948d013cc6c972
|
||||
- this.keepAliveChallenge = now;
|
||||
- this.send(new ClientboundKeepAlivePacket(this.keepAliveChallenge));
|
||||
+ // Paper start - improve keepalives
|
||||
+ if (this.checkIfClosed(now) && !this.processedDisconnect) {
|
||||
+ if (this.checkIfClosed(now)) {
|
||||
+ long currTime = System.nanoTime();
|
||||
+
|
||||
+ if ((currTime - this.keepAlive.lastKeepAliveTx) >= java.util.concurrent.TimeUnit.SECONDS.toNanos(1L)) {
|
||||
@@ -240,11 +234,12 @@ index 079ab378920c0e52ef4e42ef20b37bd389f40870..dc9020f210c21a626c948d013cc6c972
|
||||
}
|
||||
}
|
||||
|
||||
@@ -424,6 +457,14 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
@@ -420,6 +447,16 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
}
|
||||
|
||||
protected CommonListenerCookie createCookie(final ClientInformation clientInformation) {
|
||||
- return new CommonListenerCookie(this.playerProfile(), this.latency, clientInformation, this.transferred, this.playerBrand, this.pluginMessagerChannels); // Paper
|
||||
+ // Paper start - listener handoff should reset pending keepalive expectations
|
||||
+ return new CommonListenerCookie(
|
||||
+ this.playerProfile(),
|
||||
+ this.latency,
|
||||
@@ -253,6 +248,7 @@ index 079ab378920c0e52ef4e42ef20b37bd389f40870..dc9020f210c21a626c948d013cc6c972
|
||||
+ this.playerBrand,
|
||||
+ this.pluginMessagerChannels,
|
||||
+ this.keepAlive.copyForListenerHandoff()
|
||||
+ ); // Paper - listener handoff should reset pending keepalive expectations
|
||||
+ );
|
||||
+ // Paper end - listener handoff should reset pending keepalive expectations
|
||||
}
|
||||
}
|
||||
@@ -20,10 +20,10 @@ index 2bc436cdf5180a7943c45fabb9fbbedae6f7db56..f312a7f5b1b2a777ab36b94ce7cbf387
|
||||
|
||||
@Override
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index da8c04aa02032c4c582709727f8f7f0b66b697b1..3923f21c67165e2ecd2c9cecd5266758435a6806 100644
|
||||
index 8c4b40362f77cdea6e57315a6639006ac7ab27c7..a5217deb236ee922d020a7a6a03141a5f67acd77 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1784,32 +1784,22 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1794,32 +1794,22 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,10 +42,10 @@ index d2877c20f389d0131e1dd208b464f590671e5d82..27bdc70d861ca39487ad16cb3afb89d6
|
||||
updateComponent(root, "minecraft:trim", hiddenComponents);
|
||||
updateComponent(root, "minecraft:unbreakable", hiddenComponents);
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index ae140a514e1e3200f52c5933f886cc9e820b818a..4a1146cc54bd9272466ffc9bb64f600c40f0c0f4 100644
|
||||
index 06132bde0aed9dd9088c884ee31056b9176b6f90..08374da2d9b84e8ff13c670d7f45867fb0bdd897 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -1820,9 +1820,14 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1819,9 +1819,14 @@ public class ServerGamePacketListenerImpl
|
||||
private boolean hasNewCollision(final ServerLevel level, final Entity entity, final AABB oldBox, final AABB newBox) {
|
||||
final List<AABB> collisionsBB = new java.util.ArrayList<>();
|
||||
final List<VoxelShape> collisionsVoxel = new java.util.ArrayList<>();
|
||||
@@ -62,10 +62,10 @@ index ae140a514e1e3200f52c5933f886cc9e820b818a..4a1146cc54bd9272466ffc9bb64f600c
|
||||
);
|
||||
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 8df070a7135411806d42ea692b566c4d8389a47b..06451a21c4bfbcd95063f96246013d63f65af8a3 100644
|
||||
index fa3809be5c0488c5a1d2639579d68619b0a55de9..c332d48f5cac2f3be93201c66f4f7cdba916cbac 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -1528,7 +1528,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
@@ -1529,7 +1529,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
if (entity instanceof net.minecraft.world.entity.decoration.ArmorStand && !entity.level().paperConfig().entities.armorStands.doCollisionEntityLookups)
|
||||
return false;
|
||||
// Paper start - optimise collisions
|
||||
|
||||
@@ -48,10 +48,10 @@ index 0000000000000000000000000000000000000000..24a2090e068ad3c0d08705050944abdf
|
||||
+ }
|
||||
+}
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 3923f21c67165e2ecd2c9cecd5266758435a6806..92acd256fdf815dfb8dd743cf8ecd0eb377d996e 100644
|
||||
index af1f5e83bd24e671399af2a9aadc8e11959ec5f4..b9efed1df74651c894a416f1d3db320d4ab20401 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1836,6 +1836,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1850,6 +1850,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
level.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - BlockPhysicsEvent
|
||||
level.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent
|
||||
level.updateLagCompensationTick(); // Paper - lag compensation
|
||||
|
||||
@@ -155,10 +155,10 @@ index a94e6ca1d396b6b0781de5d550c4a804274ee003..a1018e9ca9dfb978d6e6633577abd7d5
|
||||
|
||||
private ClientboundLevelChunkWithLightPacket(final RegistryFriendlyByteBuf input) {
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 78021db10860396fef4eb2e01926fbad123916fa..3f02da2014ed8e4169f4bb819b4d9e61154b7b06 100644
|
||||
index 4ac7ef5a1ed1fac04a9fd246212f59919deb498c..e562aec4366d7724f915e3dd5ae440a77e0947c5 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -630,7 +630,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -631,7 +631,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
savedDataStorage.set(io.papermc.paper.world.saveddata.PaperWorldPDC.TYPE, loadedWorldData.pdc() == null ? io.papermc.paper.world.saveddata.PaperWorldPDC.TYPE.constructor().get() : loadedWorldData.pdc());
|
||||
final GameRules gameRules = new GameRules(server.getWorldData().enabledFeatures(), savedDataStorage.computeIfAbsent(net.minecraft.world.level.gamerules.GameRuleMap.TYPE));
|
||||
this.gameRules = gameRules;
|
||||
@@ -196,7 +196,7 @@ index ec40f02032f965f548b0c0a29aa9d9bbad6f439b..373da9d604cfb1614a0618d856aefd2b
|
||||
if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
new io.papermc.paper.event.packet.PlayerChunkLoadEvent(new org.bukkit.craftbukkit.CraftChunk(chunk), connection.getPlayer().getBukkitEntity()).callEvent();
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index b69bcaa1e27a4fbe9a9568f3c9e1843167abe1f5..9218322801c41657c00928ef90b0de99df1670f6 100644
|
||||
index 5e11abcfd681d86b1c0e282cf901108822766ce2..3020a3208b14bb483b08cf59a796fb83c2403d1c 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -331,7 +331,7 @@ public abstract class PlayerList {
|
||||
@@ -209,7 +209,7 @@ index b69bcaa1e27a4fbe9a9568f3c9e1843167abe1f5..9218322801c41657c00928ef90b0de99
|
||||
}
|
||||
// Paper end - Send empty chunk
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 06451a21c4bfbcd95063f96246013d63f65af8a3..e34e901dce06c6bc6060418593010dcfb38e9396 100644
|
||||
index 829bb616e5d72b955248bbc150254c239176ce64..4b228b5c563e40b6f301df22b5c8a7f7988cb072 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -145,6 +145,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
@@ -230,7 +230,7 @@ index 06451a21c4bfbcd95063f96246013d63f65af8a3..e34e901dce06c6bc6060418593010dcf
|
||||
) {
|
||||
// Paper start - getblock optimisations - cache world height/sections
|
||||
final DimensionType dimType = dimensionTypeRegistration.value();
|
||||
@@ -870,6 +872,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
@@ -871,6 +873,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
this.palettedContainerFactory = PalettedContainerFactory.create(registryAccess);
|
||||
this.damageSources = new DamageSources(registryAccess);
|
||||
this.entityLookup = new ca.spottedleaf.moonrise.patches.chunk_system.level.entity.dfl.DefaultEntityLookup(this); // Paper - rewrite chunk system
|
||||
@@ -238,7 +238,7 @@ index 06451a21c4bfbcd95063f96246013d63f65af8a3..e34e901dce06c6bc6060418593010dcf
|
||||
}
|
||||
|
||||
// Paper start - Cancel hit for vanished players
|
||||
@@ -1084,6 +1087,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
@@ -1085,6 +1088,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
}
|
||||
// CraftBukkit end - capture blockstates
|
||||
BlockState oldState = chunk.setBlockState(pos, blockState, updateFlags);
|
||||
|
||||
@@ -46,7 +46,7 @@ index 81a293cc13653a9a0336cb25d75273969fee4d16..8ebcce4c4971a11d367fb39e9c7fd280
|
||||
protected void onOpen(final Level level, final BlockPos pos, final BlockState blockState) {
|
||||
if (blockState.getBlock() instanceof ChestBlock chestBlock) {
|
||||
diff --git a/net/minecraft/world/level/block/entity/ContainerOpenersCounter.java b/net/minecraft/world/level/block/entity/ContainerOpenersCounter.java
|
||||
index 9af046cbe2c5024040057118a0e9ecd539815781..aa8b384b05738139fa3492b3c09084cda09448ce 100644
|
||||
index baa8b5aba0500981a191626553d66650c7304b88..52737172ccfa0c7c977e4f2fe1db242e0bb92d25 100644
|
||||
--- a/net/minecraft/world/level/block/entity/ContainerOpenersCounter.java
|
||||
+++ b/net/minecraft/world/level/block/entity/ContainerOpenersCounter.java
|
||||
@@ -37,11 +37,23 @@ public abstract class ContainerOpenersCounter {
|
||||
@@ -70,9 +70,9 @@ index 9af046cbe2c5024040057118a0e9ecd539815781..aa8b384b05738139fa3492b3c09084cd
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - delay open/close callbacks
|
||||
int oldPower = Math.max(0, Math.min(15, this.openCount)); // CraftBukkit - Get power before new viewer is added
|
||||
int previous = this.openCount++;
|
||||
|
||||
// Paper start - Call BlockRedstoneEvent
|
||||
@@ -66,6 +78,12 @@ public abstract class ContainerOpenersCounter {
|
||||
}
|
||||
|
||||
@@ -83,9 +83,9 @@ index 9af046cbe2c5024040057118a0e9ecd539815781..aa8b384b05738139fa3492b3c09084cd
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - delay open/close callbacks
|
||||
int oldPower = Math.max(0, Math.min(15, this.openCount)); // CraftBukkit - Get power before new viewer is added
|
||||
if (this.openCount == 0) return; // Paper - Prevent ContainerOpenersCounter openCount from going negative
|
||||
int previous = this.openCount--;
|
||||
|
||||
@@ -151,6 +169,11 @@ public abstract class ContainerOpenersCounter {
|
||||
}
|
||||
|
||||
|
||||
+138
-133
@@ -8,13 +8,14 @@ and shapeless recipes.
|
||||
|
||||
diff --git a/io/papermc/paper/inventory/recipe/ItemOrExact.java b/io/papermc/paper/inventory/recipe/ItemOrExact.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ce745e49cd54fe3ae187785563a1bd311d14b5b2
|
||||
index 0000000000000000000000000000000000000000..9e621873454cc2edc2e59e6c7554d8116cd32bc1
|
||||
--- /dev/null
|
||||
+++ b/io/papermc/paper/inventory/recipe/ItemOrExact.java
|
||||
@@ -0,0 +1,63 @@
|
||||
@@ -0,0 +1,64 @@
|
||||
+package io.papermc.paper.inventory.recipe;
|
||||
+
|
||||
+import net.minecraft.core.Holder;
|
||||
+import net.minecraft.core.component.DataComponents;
|
||||
+import net.minecraft.world.item.ItemStack;
|
||||
+
|
||||
+public sealed interface ItemOrExact permits ItemOrExact.Item, ItemOrExact.Exact {
|
||||
@@ -26,12 +27,12 @@ index 0000000000000000000000000000000000000000..ce745e49cd54fe3ae187785563a1bd31
|
||||
+ record Item(Holder<net.minecraft.world.item.Item> item) implements ItemOrExact {
|
||||
+
|
||||
+ public Item(final ItemStack stack) {
|
||||
+ this(stack.getItemHolder());
|
||||
+ this(stack.typeHolder());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getMaxStackSize() {
|
||||
+ return this.item.value().getDefaultMaxStackSize();
|
||||
+ return this.item.components().getOrDefault(DataComponents.MAX_STACK_SIZE, 1);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
@@ -150,119 +151,119 @@ index 0000000000000000000000000000000000000000..f47c12e9dd6cfa857ca07a764edc22de
|
||||
+ }
|
||||
+}
|
||||
diff --git a/net/minecraft/recipebook/ServerPlaceRecipe.java b/net/minecraft/recipebook/ServerPlaceRecipe.java
|
||||
index 6d3e3ec045d5b15a435f7217369968b33e082724..b7a3758af337270737041f84d10eb43784e42279 100644
|
||||
index 31f8aa58b48aeb64e57480490a449b6c46913880..b7ee9fe694ea37eeb58b5dded7967e7d0f338d0d 100644
|
||||
--- a/net/minecraft/recipebook/ServerPlaceRecipe.java
|
||||
+++ b/net/minecraft/recipebook/ServerPlaceRecipe.java
|
||||
@@ -40,6 +40,7 @@ public class ServerPlaceRecipe<R extends Recipe<?>> {
|
||||
@@ -41,6 +41,7 @@ public class ServerPlaceRecipe<R extends Recipe<?>> {
|
||||
return RecipeBookMenu.PostPlaceAction.NOTHING;
|
||||
} else {
|
||||
StackedItemContents stackedItemContents = new StackedItemContents();
|
||||
+ stackedItemContents.initializeExtras(recipe.value(), null); // Paper - Improve exact choice recipe ingredients
|
||||
inventory.fillStackedContents(stackedItemContents);
|
||||
menu.fillCraftSlotsStackedContents(stackedItemContents);
|
||||
return serverPlaceRecipe.tryPlaceRecipe(recipe, stackedItemContents);
|
||||
@@ -99,7 +100,7 @@ public class ServerPlaceRecipe<R extends Recipe<?>> {
|
||||
StackedItemContents availableItems = new StackedItemContents();
|
||||
+ availableItems.initializeExtras(recipe.value(), null); // Paper - Improve exact choice recipe ingredients
|
||||
inventory.fillStackedContents(availableItems);
|
||||
menu.fillCraftSlotsStackedContents(availableItems);
|
||||
return placer.tryPlaceRecipe(recipe, availableItems);
|
||||
@@ -100,7 +101,7 @@ public class ServerPlaceRecipe<R extends Recipe<?>> {
|
||||
}
|
||||
|
||||
int i = this.calculateAmountToCraft(biggestCraftableStack, flag);
|
||||
- List<Holder<Item>> list = new ArrayList<>();
|
||||
+ List<io.papermc.paper.inventory.recipe.ItemOrExact> list = new ArrayList<>(); // Paper - Improve exact choice recipe ingredients
|
||||
if (stackedItemContents.canCraft(recipe.value(), i, list::add)) {
|
||||
int i1 = clampToMaxStackSize(i, list);
|
||||
if (i1 != i) {
|
||||
@@ -114,7 +115,7 @@ public class ServerPlaceRecipe<R extends Recipe<?>> {
|
||||
this.gridWidth, this.gridHeight, recipe.value(), recipe.value().placementInfo().slotsToIngredientIndex(), (item1, slot1, x, y) -> {
|
||||
if (item1 != -1) {
|
||||
Slot slot2 = this.inputGridSlots.get(slot1);
|
||||
- Holder<Item> holder = list.get(item1);
|
||||
+ io.papermc.paper.inventory.recipe.ItemOrExact holder = list.get(item1); // Paper - Improve exact choice recipe ingredients
|
||||
int i2 = i1;
|
||||
int amountToCraft = this.calculateAmountToCraft(biggestCraftableStack, recipeMatchesPlaced);
|
||||
- List<Holder<Item>> itemsUsedPerIngredient = new ArrayList<>();
|
||||
+ List<io.papermc.paper.inventory.recipe.ItemOrExact> itemsUsedPerIngredient = new ArrayList<>(); // Paper - Improve exact choice recipe ingredients
|
||||
if (availableItems.canCraft(recipe.value(), amountToCraft, itemsUsedPerIngredient::add)) {
|
||||
int adjustedAmountToCraft = clampToMaxStackSize(amountToCraft, itemsUsedPerIngredient);
|
||||
if (adjustedAmountToCraft != amountToCraft) {
|
||||
@@ -119,7 +120,7 @@ public class ServerPlaceRecipe<R extends Recipe<?>> {
|
||||
(ingredientIndex, gridIndex, gridXPos, gridYPos) -> {
|
||||
if (ingredientIndex != -1) {
|
||||
Slot targetGridSlot = this.inputGridSlots.get(gridIndex);
|
||||
- Holder<Item> itemUsed = itemsUsedPerIngredient.get(ingredientIndex);
|
||||
+ io.papermc.paper.inventory.recipe.ItemOrExact itemUsed = itemsUsedPerIngredient.get(ingredientIndex); // Paper - Improve exact choice recipe ingredients
|
||||
int remainingCount = adjustedAmountToCraft;
|
||||
|
||||
while (i2 > 0) {
|
||||
@@ -129,9 +130,11 @@ public class ServerPlaceRecipe<R extends Recipe<?>> {
|
||||
while (remainingCount > 0) {
|
||||
@@ -134,9 +135,11 @@ public class ServerPlaceRecipe<R extends Recipe<?>> {
|
||||
}
|
||||
}
|
||||
|
||||
- private static int clampToMaxStackSize(int amount, List<Holder<Item>> items) {
|
||||
- for (Holder<Item> holder : items) {
|
||||
- amount = Math.min(amount, holder.value().getDefaultMaxStackSize());
|
||||
- private static int clampToMaxStackSize(int value, final List<Holder<Item>> items) {
|
||||
- for (Holder<Item> item : items) {
|
||||
- value = Math.min(value, item.components().getOrDefault(DataComponents.MAX_STACK_SIZE, 1));
|
||||
+ // Paper start - Improve exact choice recipe ingredients
|
||||
+ private static int clampToMaxStackSize(int amount, List<io.papermc.paper.inventory.recipe.ItemOrExact> items) {
|
||||
+ for (io.papermc.paper.inventory.recipe.ItemOrExact holder : items) {
|
||||
+ amount = Math.min(amount, holder.getMaxStackSize());
|
||||
+ private static int clampToMaxStackSize(int value, final List<io.papermc.paper.inventory.recipe.ItemOrExact> items) {
|
||||
+ for (io.papermc.paper.inventory.recipe.ItemOrExact item : items) {
|
||||
+ value = Math.min(value, item.getMaxStackSize());
|
||||
+ // Paper end - Improve exact choice recipe ingredients
|
||||
}
|
||||
|
||||
return amount;
|
||||
@@ -160,7 +163,7 @@ public class ServerPlaceRecipe<R extends Recipe<?>> {
|
||||
return value;
|
||||
@@ -165,7 +168,7 @@ public class ServerPlaceRecipe<R extends Recipe<?>> {
|
||||
}
|
||||
}
|
||||
|
||||
- private int moveItemToGrid(Slot slot, Holder<Item> item, int count) {
|
||||
+ private int moveItemToGrid(Slot slot, io.papermc.paper.inventory.recipe.ItemOrExact item, int count) { // Paper - Improve exact choice recipe ingredients
|
||||
ItemStack item1 = slot.getItem();
|
||||
int i = this.inventory.findSlotMatchingCraftingIngredient(item, item1);
|
||||
if (i == -1) {
|
||||
- private int moveItemToGrid(final Slot targetSlot, final Holder<Item> itemInInventory, final int count) {
|
||||
+ private int moveItemToGrid(final Slot targetSlot, final io.papermc.paper.inventory.recipe.ItemOrExact itemInInventory, final int count) { // Paper - Improve exact choice recipe ingredients
|
||||
ItemStack itemInTargetSlot = targetSlot.getItem();
|
||||
int inventorySlotId = this.inventory.findSlotMatchingCraftingIngredient(itemInInventory, itemInTargetSlot);
|
||||
if (inventorySlotId == Inventory.NOT_FOUND_INDEX) {
|
||||
diff --git a/net/minecraft/world/entity/player/Inventory.java b/net/minecraft/world/entity/player/Inventory.java
|
||||
index 76eda3bd8c513c7e42ceedf1aa605fb6df8b7019..41e59f3739945ca7f6ab710c993b5c0f15fcd529 100644
|
||||
index da8bab81e135a9b240fbeac0e9e1d2aa12c6212d..f004911c438e6f89d6e079437e3f4104d6cbacbd 100644
|
||||
--- a/net/minecraft/world/entity/player/Inventory.java
|
||||
+++ b/net/minecraft/world/entity/player/Inventory.java
|
||||
@@ -252,12 +252,12 @@ public class Inventory implements Container, Nameable {
|
||||
return !stack.isDamaged() && !stack.isEnchanted() && !stack.has(DataComponents.CUSTOM_NAME);
|
||||
return !item.isDamaged() && !item.isEnchanted() && !item.has(DataComponents.CUSTOM_NAME);
|
||||
}
|
||||
|
||||
- public int findSlotMatchingCraftingIngredient(Holder<Item> item, ItemStack stack) {
|
||||
+ public int findSlotMatchingCraftingIngredient(io.papermc.paper.inventory.recipe.ItemOrExact item, ItemStack stack) { // Paper - Improve exact choice recipe ingredients
|
||||
- public int findSlotMatchingCraftingIngredient(final Holder<Item> item, final ItemStack existingItem) {
|
||||
+ public int findSlotMatchingCraftingIngredient(final io.papermc.paper.inventory.recipe.ItemOrExact item, final ItemStack existingItem) { // Paper - Improve exact choice recipe ingredients
|
||||
for (int i = 0; i < this.items.size(); i++) {
|
||||
ItemStack itemStack = this.items.get(i);
|
||||
if (!itemStack.isEmpty()
|
||||
- && itemStack.is(item)
|
||||
- && isUsableForCrafting(itemStack)
|
||||
+ && item.matches(itemStack) // Paper - Improve exact choice recipe ingredients
|
||||
+ && (!(item instanceof io.papermc.paper.inventory.recipe.ItemOrExact.Item) || Inventory.isUsableForCrafting(itemStack)) // Paper - Improve exact choice recipe ingredients
|
||||
&& (stack.isEmpty() || ItemStack.isSameItemSameComponents(stack, itemStack))) {
|
||||
ItemStack inventoryItemStack = this.items.get(i);
|
||||
if (!inventoryItemStack.isEmpty()
|
||||
- && inventoryItemStack.is(item)
|
||||
- && isUsableForCrafting(inventoryItemStack)
|
||||
+ && item.matches(inventoryItemStack) // Paper - Improve exact choice recipe ingredients
|
||||
+ && (!(item instanceof io.papermc.paper.inventory.recipe.ItemOrExact.Item) || Inventory.isUsableForCrafting(inventoryItemStack)) // Paper - Improve exact choice recipe ingredients
|
||||
&& (existingItem.isEmpty() || ItemStack.isSameItemSameComponents(existingItem, inventoryItemStack))) {
|
||||
return i;
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/player/StackedContents.java b/net/minecraft/world/entity/player/StackedContents.java
|
||||
index bc4f7d16365dffc87b1eef8aa5791a5cb595ee78..cbb37480c19b210cf83999247c1d670c9df2d150 100644
|
||||
index 889b8e6c3762203deccf657b505f6f29cc893526..6710653d033a48c4b3fc267496f93a2548b5c966 100644
|
||||
--- a/net/minecraft/world/entity/player/StackedContents.java
|
||||
+++ b/net/minecraft/world/entity/player/StackedContents.java
|
||||
@@ -13,7 +13,7 @@ import java.util.List;
|
||||
@@ -14,7 +14,7 @@ import java.util.Objects;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class StackedContents<T> {
|
||||
- public final Reference2IntOpenHashMap<T> amounts = new Reference2IntOpenHashMap<>();
|
||||
+ public final it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap<T> amounts = new it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap<>(); // Paper - Improve exact choice recipe ingredients (don't use "reference" map)
|
||||
|
||||
boolean hasAtLeast(T item, int amount) {
|
||||
return this.amounts.getInt(item) >= amount;
|
||||
@@ -49,7 +49,7 @@ public class StackedContents<T> {
|
||||
List<T> getUniqueAvailableIngredientItems(Iterable<? extends StackedContents.IngredientInfo<T>> ingredients) {
|
||||
List<T> list = new ArrayList<>();
|
||||
private boolean hasAtLeast(final T item, final int count) {
|
||||
return this.amounts.getInt(item) >= count;
|
||||
@@ -54,7 +54,7 @@ public class StackedContents<T> {
|
||||
private List<T> getUniqueAvailableIngredientItems(final Iterable<? extends StackedContents.IngredientInfo<T>> ingredients) {
|
||||
List<T> result = new ArrayList<>();
|
||||
|
||||
- for (Entry<T> entry : Reference2IntMaps.fastIterable(this.amounts)) {
|
||||
+ for (it.unimi.dsi.fastutil.objects.Object2IntMap.Entry<T> entry : it.unimi.dsi.fastutil.objects.Object2IntMaps.fastIterable(this.amounts)) { // Paper - Improve exact choice recipe ingredients (don't use "reference" map)
|
||||
if (entry.getIntValue() > 0 && anyIngredientMatches(ingredients, entry.getKey())) {
|
||||
list.add(entry.getKey());
|
||||
- for (Entry<T> availableItem : Reference2IntMaps.fastIterable(this.amounts)) {
|
||||
+ for (it.unimi.dsi.fastutil.objects.Object2IntMap.Entry<T> availableItem : it.unimi.dsi.fastutil.objects.Object2IntMaps.fastIterable(this.amounts)) { // Paper - Improve exact choice recipe ingredients (don't use "reference" map)
|
||||
if (availableItem.getIntValue() > 0 && anyIngredientMatches(ingredients, availableItem.getKey())) {
|
||||
result.add(availableItem.getKey());
|
||||
}
|
||||
@@ -71,13 +71,13 @@ public class StackedContents<T> {
|
||||
@@ -76,13 +76,13 @@ public class StackedContents<T> {
|
||||
@VisibleForTesting
|
||||
public int getResultUpperBound(List<? extends StackedContents.IngredientInfo<T>> ingredients) {
|
||||
int i = Integer.MAX_VALUE;
|
||||
- ObjectIterable<Entry<T>> objectIterable = Reference2IntMaps.fastIterable(this.amounts);
|
||||
+ ObjectIterable<it.unimi.dsi.fastutil.objects.Object2IntMap.Entry<T>> objectIterable = it.unimi.dsi.fastutil.objects.Object2IntMaps.fastIterable(this.amounts); // Paper - Improve exact choice recipe ingredients (don't use "reference" map)
|
||||
public int getResultUpperBound(final List<? extends StackedContents.IngredientInfo<T>> ingredients) {
|
||||
int min = Integer.MAX_VALUE;
|
||||
- ObjectIterable<Entry<T>> availableItems = Reference2IntMaps.fastIterable(this.amounts);
|
||||
+ ObjectIterable<it.unimi.dsi.fastutil.objects.Object2IntMap.Entry<T>> availableItems = it.unimi.dsi.fastutil.objects.Object2IntMaps.fastIterable(this.amounts); // Paper - Improve exact choice recipe ingredients (don't use "reference" map)
|
||||
|
||||
label31:
|
||||
for (StackedContents.IngredientInfo<T> ingredientInfo : ingredients) {
|
||||
int i1 = 0;
|
||||
for (StackedContents.IngredientInfo<T> ingredient : ingredients) {
|
||||
int max = 0;
|
||||
|
||||
- for (Entry<T> entry : objectIterable) {
|
||||
+ for (it.unimi.dsi.fastutil.objects.Object2IntMap.Entry<T> entry : objectIterable) { // Paper - Improve exact choice recipe ingredients (don't use "reference" map)
|
||||
int intValue = entry.getIntValue();
|
||||
if (intValue > i1) {
|
||||
if (ingredientInfo.acceptsItem(entry.getKey())) {
|
||||
- for (Entry<T> entry : availableItems) {
|
||||
+ for (it.unimi.dsi.fastutil.objects.Object2IntMap.Entry<T> entry : availableItems) { // Paper - Improve exact choice recipe ingredients (don't use "reference" map)
|
||||
int itemCount = entry.getIntValue();
|
||||
if (itemCount > max) {
|
||||
if (ingredient.acceptsItem(entry.getKey())) {
|
||||
diff --git a/net/minecraft/world/entity/player/StackedItemContents.java b/net/minecraft/world/entity/player/StackedItemContents.java
|
||||
index e0121e9c8439e32b7ef064c06942ccd5dd74987d..00dbc0d125b2c8c208ffa46f9084c6317efaba90 100644
|
||||
index ffaa8e450a11a01060b6847d1b66a76323f9d8ba..1ace17d8fc7e7b8b4722a1889d49233c0ec55e20 100644
|
||||
--- a/net/minecraft/world/entity/player/StackedItemContents.java
|
||||
+++ b/net/minecraft/world/entity/player/StackedItemContents.java
|
||||
@@ -9,9 +9,27 @@ import net.minecraft.world.item.crafting.Recipe;
|
||||
@@ -289,115 +290,119 @@ index e0121e9c8439e32b7ef064c06942ccd5dd74987d..00dbc0d125b2c8c208ffa46f9084c631
|
||||
+ }
|
||||
+ // Paper end - Improve exact choice recipe ingredients
|
||||
|
||||
public void accountSimpleStack(ItemStack stack) {
|
||||
+ if (this.extrasMap != null && this.extrasMap.accountStack(stack, Math.min(64, stack.getCount()))) return; // Paper - Improve exact choice recipe ingredients; max of 64 due to accountStack method below
|
||||
if (Inventory.isUsableForCrafting(stack)) {
|
||||
this.accountStack(stack);
|
||||
public void accountSimpleStack(final ItemStack itemStack) {
|
||||
+ if (this.extrasMap != null && this.extrasMap.accountStack(itemStack, Math.min(itemStack.getMaxStackSize(), itemStack.getCount()))) return; // Paper - Improve exact choice recipe ingredients; Referenced from the accountStack method below
|
||||
if (Inventory.isUsableForCrafting(itemStack)) {
|
||||
this.accountStack(itemStack);
|
||||
}
|
||||
@@ -24,34 +42,35 @@ public class StackedItemContents {
|
||||
public void accountStack(ItemStack stack, int maxStackSize) {
|
||||
if (!stack.isEmpty()) {
|
||||
int min = Math.min(maxStackSize, stack.getCount());
|
||||
- this.raw.account(stack.getItemHolder(), min);
|
||||
+ if (this.extrasMap != null && !stack.getComponentsPatch().isEmpty() && this.extrasMap.accountStack(stack, min)) return; // Paper - Improve exact choice recipe ingredients; if an exact ingredient, don't include it
|
||||
+ this.raw.account(new io.papermc.paper.inventory.recipe.ItemOrExact.Item(stack.getItemHolder()), min);
|
||||
@@ -24,38 +42,39 @@ public class StackedItemContents {
|
||||
public void accountStack(final ItemStack itemStack, final int maxCount) {
|
||||
if (!itemStack.isEmpty()) {
|
||||
int count = Math.min(maxCount, itemStack.getCount());
|
||||
- this.raw.account(itemStack.typeHolder(), count);
|
||||
+ if (this.extrasMap != null && !itemStack.getComponentsPatch().isEmpty() && this.extrasMap.accountStack(itemStack, count)) return; // Paper - Improve exact choice recipe ingredients; if an exact ingredient, don't include it
|
||||
+ this.raw.account(new io.papermc.paper.inventory.recipe.ItemOrExact.Item(itemStack.typeHolder()), count);
|
||||
}
|
||||
}
|
||||
|
||||
- public boolean canCraft(Recipe<?> recipe, StackedContents.@Nullable Output<Holder<Item>> output) {
|
||||
+ public boolean canCraft(Recipe<?> recipe, StackedContents.@Nullable Output<io.papermc.paper.inventory.recipe.ItemOrExact> output) { // Paper - Improve exact choice recipe ingredients
|
||||
- public boolean canCraft(final Recipe<?> recipe, final StackedContents.@Nullable Output<Holder<Item>> output) {
|
||||
+ public boolean canCraft(final Recipe<?> recipe, final StackedContents.@Nullable Output<io.papermc.paper.inventory.recipe.ItemOrExact> output) { // Paper - Improve exact choice recipe ingredients
|
||||
return this.canCraft(recipe, 1, output);
|
||||
}
|
||||
|
||||
- public boolean canCraft(Recipe<?> recipe, int maxCount, StackedContents.@Nullable Output<Holder<Item>> output) {
|
||||
+ public boolean canCraft(Recipe<?> recipe, int maxCount, StackedContents.@Nullable Output<io.papermc.paper.inventory.recipe.ItemOrExact> output) { // Paper - Improve exact choice recipe ingredients
|
||||
- public boolean canCraft(final Recipe<?> recipe, final int amount, final StackedContents.@Nullable Output<Holder<Item>> output) {
|
||||
+ public boolean canCraft(final Recipe<?> recipe, final int amount, final StackedContents.@Nullable Output<io.papermc.paper.inventory.recipe.ItemOrExact> output) { // Paper - Improve exact choice recipe ingredients
|
||||
PlacementInfo placementInfo = recipe.placementInfo();
|
||||
return !placementInfo.isImpossibleToPlace() && this.canCraft(placementInfo.ingredients(), maxCount, output);
|
||||
return !placementInfo.isImpossibleToPlace() && this.canCraft(placementInfo.ingredients(), amount, output);
|
||||
}
|
||||
|
||||
- public boolean canCraft(List<? extends StackedContents.IngredientInfo<Holder<Item>>> ingredients, StackedContents.@Nullable Output<Holder<Item>> output) {
|
||||
+ public boolean canCraft(List<? extends StackedContents.IngredientInfo<io.papermc.paper.inventory.recipe.ItemOrExact>> ingredients, StackedContents.@Nullable Output<io.papermc.paper.inventory.recipe.ItemOrExact> output) { // Paper - Improve exact choice recipe ingredients
|
||||
return this.canCraft(ingredients, 1, output);
|
||||
public boolean canCraft(
|
||||
- final List<? extends StackedContents.IngredientInfo<Holder<Item>>> contents, final StackedContents.@Nullable Output<Holder<Item>> output
|
||||
+ final List<? extends StackedContents.IngredientInfo<io.papermc.paper.inventory.recipe.ItemOrExact>> contents, final StackedContents.@Nullable Output<io.papermc.paper.inventory.recipe.ItemOrExact> output // Paper - Improve exact choice recipe ingredients
|
||||
) {
|
||||
return this.canCraft(contents, 1, output);
|
||||
}
|
||||
|
||||
private boolean canCraft(
|
||||
- List<? extends StackedContents.IngredientInfo<Holder<Item>>> ingredients, int maxCount, StackedContents.@Nullable Output<Holder<Item>> output
|
||||
+ List<? extends StackedContents.IngredientInfo<io.papermc.paper.inventory.recipe.ItemOrExact>> ingredients, int maxCount, StackedContents.@Nullable Output<io.papermc.paper.inventory.recipe.ItemOrExact> output // Paper - Improve exact choice recipe ingredients
|
||||
- final List<? extends StackedContents.IngredientInfo<Holder<Item>>> contents,
|
||||
+ final List<? extends StackedContents.IngredientInfo<io.papermc.paper.inventory.recipe.ItemOrExact>> contents, // Paper - Improve exact choice recipe ingredients
|
||||
final int amount,
|
||||
- final StackedContents.@Nullable Output<Holder<Item>> output
|
||||
+ final StackedContents.@Nullable Output<io.papermc.paper.inventory.recipe.ItemOrExact> output // Paper - Improve exact choice recipe ingredients
|
||||
) {
|
||||
return this.raw.tryPick(ingredients, maxCount, output);
|
||||
return this.raw.tryPick(contents, amount, output);
|
||||
}
|
||||
|
||||
- public int getBiggestCraftableStack(Recipe<?> recipe, StackedContents.@Nullable Output<Holder<Item>> output) {
|
||||
+ public int getBiggestCraftableStack(Recipe<?> recipe, StackedContents.@Nullable Output<io.papermc.paper.inventory.recipe.ItemOrExact> output) { // Paper - Improve exact choice recipe ingredients
|
||||
- public int getBiggestCraftableStack(final Recipe<?> recipe, final StackedContents.@Nullable Output<Holder<Item>> output) {
|
||||
+ public int getBiggestCraftableStack(final Recipe<?> recipe, final StackedContents.@Nullable Output<io.papermc.paper.inventory.recipe.ItemOrExact> output) { // Paper - Improve exact choice recipe ingredients
|
||||
return this.getBiggestCraftableStack(recipe, Integer.MAX_VALUE, output);
|
||||
}
|
||||
|
||||
- public int getBiggestCraftableStack(Recipe<?> recipe, int maxCount, StackedContents.@Nullable Output<Holder<Item>> output) {
|
||||
+ public int getBiggestCraftableStack(Recipe<?> recipe, int maxCount, StackedContents.@Nullable Output<io.papermc.paper.inventory.recipe.ItemOrExact> output) { // Paper - Improve exact choice recipe ingredients
|
||||
return this.raw.tryPickAll(recipe.placementInfo().ingredients(), maxCount, output);
|
||||
- public int getBiggestCraftableStack(final Recipe<?> recipe, final int maxSize, final StackedContents.@Nullable Output<Holder<Item>> output) {
|
||||
+ public int getBiggestCraftableStack(final Recipe<?> recipe, final int maxSize, final StackedContents.@Nullable Output<io.papermc.paper.inventory.recipe.ItemOrExact> output) { // Paper - Improve exact choice recipe ingredients
|
||||
return this.raw.tryPickAll(recipe.placementInfo().ingredients(), maxSize, output);
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/world/item/crafting/Ingredient.java b/net/minecraft/world/item/crafting/Ingredient.java
|
||||
index ac4520afe510df9b1dd256d13dcb0768c83edb70..da95f40503f3696c8daa8fd0e947508fe43060ba 100644
|
||||
index 3a8a07712a15167dabd12d4bfd258de11706ce93..1deeb3fd148c5d59250346147681b7e8f2147574 100644
|
||||
--- a/net/minecraft/world/item/crafting/Ingredient.java
|
||||
+++ b/net/minecraft/world/item/crafting/Ingredient.java
|
||||
@@ -21,7 +21,7 @@ import net.minecraft.world.item.Items;
|
||||
@@ -22,7 +22,7 @@ import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.crafting.display.SlotDisplay;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
|
||||
-public final class Ingredient implements StackedContents.IngredientInfo<Holder<Item>>, Predicate<ItemStack> {
|
||||
+public final class Ingredient implements StackedContents.IngredientInfo<io.papermc.paper.inventory.recipe.ItemOrExact>, Predicate<ItemStack> { // Paper - Improve exact choice recipe ingredients
|
||||
-public final class Ingredient implements Predicate<ItemStack>, StackedContents.IngredientInfo<Holder<Item>> {
|
||||
+public final class Ingredient implements Predicate<ItemStack>, StackedContents.IngredientInfo<io.papermc.paper.inventory.recipe.ItemOrExact> { // Paper - Improve exact choice recipe ingredients
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, Ingredient> CONTENTS_STREAM_CODEC = ByteBufCodecs.holderSet(Registries.ITEM)
|
||||
.map(Ingredient::new, ingredient -> ingredient.values);
|
||||
.map(Ingredient::new, i -> i.values);
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, Optional<Ingredient>> OPTIONAL_CONTENTS_STREAM_CODEC = ByteBufCodecs.holderSet(Registries.ITEM)
|
||||
@@ -35,20 +35,24 @@ public final class Ingredient implements StackedContents.IngredientInfo<Holder<I
|
||||
@@ -34,19 +34,23 @@ public final class Ingredient implements Predicate<ItemStack>, StackedContents.I
|
||||
public static final Codec<Ingredient> CODEC = ExtraCodecs.nonEmptyHolderSet(NON_AIR_HOLDER_SET_CODEC).xmap(Ingredient::new, i -> i.values);
|
||||
public final HolderSet<Item> values;
|
||||
// CraftBukkit start
|
||||
@javax.annotation.Nullable
|
||||
- private java.util.List<ItemStack> itemStacks;
|
||||
+ private java.util.Set<ItemStack> itemStacks; // Paper - Improve exact choice recipe ingredients
|
||||
- private java.util.@org.jspecify.annotations.Nullable List<ItemStack> itemStacks;
|
||||
+ private java.util.@org.jspecify.annotations.Nullable Set<ItemStack> itemStacks; // Paper - Improve exact choice recipe ingredients
|
||||
|
||||
public boolean isExact() {
|
||||
return this.itemStacks != null;
|
||||
}
|
||||
|
||||
@javax.annotation.Nullable
|
||||
- public java.util.List<ItemStack> itemStacks() {
|
||||
+ public java.util.Set<ItemStack> itemStacks() { // Paper - Improve exact choice recipe ingredients
|
||||
- public java.util.@org.jspecify.annotations.Nullable List<ItemStack> itemStacks() {
|
||||
+ public java.util.@org.jspecify.annotations.Nullable Set<ItemStack> itemStacks() { // Paper - Improve exact choice recipe ingredients
|
||||
return this.itemStacks;
|
||||
}
|
||||
|
||||
public static Ingredient ofStacks(java.util.List<ItemStack> stacks) {
|
||||
Ingredient recipe = Ingredient.of(stacks.stream().map(ItemStack::getItem));
|
||||
- recipe.itemStacks = stacks;
|
||||
Ingredient ingredient = Ingredient.of(stacks.stream().map(ItemStack::getItem));
|
||||
- ingredient.itemStacks = stacks;
|
||||
+ // Paper start - Improve exact choice recipe ingredients
|
||||
+ recipe.itemStacks = net.minecraft.world.item.ItemStackLinkedSet.createTypeAndComponentsSet();
|
||||
+ recipe.itemStacks.addAll(stacks);
|
||||
+ recipe.itemStacks = java.util.Collections.unmodifiableSet(recipe.itemStacks);
|
||||
+ ingredient.itemStacks = net.minecraft.world.item.ItemStackLinkedSet.createTypeAndComponentsSet();
|
||||
+ ingredient.itemStacks.addAll(stacks);
|
||||
+ ingredient.itemStacks = java.util.Collections.unmodifiableSet(ingredient.itemStacks);
|
||||
+ // Paper end - Improve exact choice recipe ingredients
|
||||
return recipe;
|
||||
return ingredient;
|
||||
}
|
||||
// CraftBukkit end
|
||||
@@ -81,21 +85,22 @@ public final class Ingredient implements StackedContents.IngredientInfo<Holder<I
|
||||
public boolean test(ItemStack stack) {
|
||||
@@ -79,21 +83,22 @@ public final class Ingredient implements Predicate<ItemStack>, StackedContents.I
|
||||
public boolean test(final ItemStack input) {
|
||||
// CraftBukkit start
|
||||
if (this.isExact()) {
|
||||
- for (ItemStack itemstack1 : this.itemStacks()) {
|
||||
- if (itemstack1.getItem() == stack.getItem() && ItemStack.isSameItemSameComponents(stack, itemstack1)) {
|
||||
- for (ItemStack item : this.itemStacks()) {
|
||||
- if (item.getItem() == input.getItem() && ItemStack.isSameItemSameComponents(input, item)) {
|
||||
- return true;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return false;
|
||||
+ return this.itemStacks.contains(stack); // Paper - Improve exact choice recipe ingredients (hashing FTW!)
|
||||
+ return this.itemStacks.contains(input); // Paper - Improve exact choice recipe ingredients (hashing FTW!)
|
||||
}
|
||||
// CraftBukkit end
|
||||
return stack.is(this.values);
|
||||
return input.is(this.values);
|
||||
}
|
||||
|
||||
+ // Paper start - Improve exact choice recipe ingredients
|
||||
@Override
|
||||
- public boolean acceptsItem(Holder<Item> item) {
|
||||
- public boolean acceptsItem(final Holder<Item> item) {
|
||||
- return this.values.contains(item);
|
||||
+ public boolean acceptsItem(final io.papermc.paper.inventory.recipe.ItemOrExact itemOrExact) {
|
||||
+ return switch (itemOrExact) {
|
||||
@@ -410,26 +415,26 @@ index ac4520afe510df9b1dd256d13dcb0768c83edb70..da95f40503f3696c8daa8fd0e947508f
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -120,6 +125,11 @@ public final class Ingredient implements StackedContents.IngredientInfo<Holder<I
|
||||
@@ -118,6 +123,11 @@ public final class Ingredient implements Predicate<ItemStack>, StackedContents.I
|
||||
}
|
||||
|
||||
public SlotDisplay display() {
|
||||
+ // Paper start - show exact ingredients in recipe book
|
||||
+ if (this.isExact()) {
|
||||
+ return new SlotDisplay.Composite(this.itemStacks().stream().<SlotDisplay>map(SlotDisplay.ItemStackSlotDisplay::new).toList());
|
||||
+ return new SlotDisplay.Composite(this.itemStacks().stream().map(ItemStackTemplate::fromNonEmptyStack).<SlotDisplay>map(SlotDisplay.ItemStackSlotDisplay::new).toList());
|
||||
+ }
|
||||
+ // Paper end - show exact ingredients in recipe book
|
||||
return (SlotDisplay)this.values
|
||||
.unwrap()
|
||||
.map(SlotDisplay.TagSlotDisplay::new, list -> new SlotDisplay.Composite(list.stream().map(Ingredient::displayForSingleItem).toList()));
|
||||
.map(SlotDisplay.TagSlotDisplay::new, l -> new SlotDisplay.Composite(l.stream().map(Ingredient::displayForSingleItem).toList()));
|
||||
diff --git a/net/minecraft/world/item/crafting/ShapelessRecipe.java b/net/minecraft/world/item/crafting/ShapelessRecipe.java
|
||||
index 43c8b7a027c519196852602d136a31f8c392b786..28d085fce206634ee88c492e06fdbf63a618ee12 100644
|
||||
index d4d4fad66be0f0c0225993026602dc61e10c6bce..53a818f14709d1978dbbc4aa7367be733a8ee47f 100644
|
||||
--- a/net/minecraft/world/item/crafting/ShapelessRecipe.java
|
||||
+++ b/net/minecraft/world/item/crafting/ShapelessRecipe.java
|
||||
@@ -71,13 +71,18 @@ public class ShapelessRecipe implements CraftingRecipe {
|
||||
@@ -74,13 +74,18 @@ public class ShapelessRecipe extends NormalCraftingRecipe {
|
||||
|
||||
@Override
|
||||
public boolean matches(CraftingInput input, Level level) {
|
||||
public boolean matches(final CraftingInput input, final Level level) {
|
||||
+ // Paper start - Improve exact choice recipe ingredients & unwrap ternary
|
||||
if (input.ingredientCount() != this.ingredients.size()) {
|
||||
return false;
|
||||
@@ -12,11 +12,12 @@
|
||||
private volatile @Nullable PacketListener disconnectListener;
|
||||
private volatile @Nullable PacketListener packetListener;
|
||||
private @Nullable DisconnectionDetails disconnectionDetails;
|
||||
@@ -81,6 +_,43 @@
|
||||
@@ -81,6 +_,44 @@
|
||||
private boolean handlingFault;
|
||||
private volatile @Nullable DisconnectionDetails delayedDisconnect;
|
||||
private @Nullable BandwidthDebugMonitor bandwidthDebugMonitor;
|
||||
+ public String hostname = ""; // CraftBukkit - add field
|
||||
+ public boolean handleConnectionDisconnectOnNextTick = false; // Paper - Force kill connection ticking
|
||||
+ // Paper start - NetworkClient implementation
|
||||
+ public int protocolVersion;
|
||||
+ public java.net.InetSocketAddress virtualHost;
|
||||
@@ -220,7 +221,7 @@
|
||||
}
|
||||
|
||||
if (this.tickCount++ % 20 == 0) {
|
||||
@@ -391,12 +_,13 @@
|
||||
@@ -391,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void disconnect(final DisconnectionDetails details) {
|
||||
@@ -228,13 +229,6 @@
|
||||
if (this.channel == null) {
|
||||
this.delayedDisconnect = details;
|
||||
}
|
||||
|
||||
if (this.isConnected()) {
|
||||
- this.channel.close().awaitUninterruptibly();
|
||||
+ this.channel.close(); // We can't wait as this may be called from an event loop.
|
||||
this.disconnectionDetails = details;
|
||||
}
|
||||
}
|
||||
@@ -543,6 +_,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +_,29 @@
|
||||
@@ -44,8 +_,28 @@
|
||||
this.closed = true;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,6 @@
|
||||
public void handle() {
|
||||
+ packetProcessing.push(this.listener); // Paper - detailed watchdog information
|
||||
+ try { // Paper - detailed watchdog information
|
||||
+ if (this.listener instanceof net.minecraft.server.network.ServerCommonPacketListenerImpl serverCommonPacketListener && serverCommonPacketListener.processedDisconnect) return; // Paper - Don't handle sync packets for kicked players
|
||||
if (this.listener.shouldHandleMessage(this.packet)) {
|
||||
try {
|
||||
this.packet.handle(this.listener);
|
||||
|
||||
@@ -501,9 +501,9 @@
|
||||
+ java.util.Random rand = new java.util.Random(level.getSeed());
|
||||
+ org.bukkit.Location spawn = level.generator.getFixedSpawnLocation(level.getWorld(), rand);
|
||||
+
|
||||
+ if (spawn != null) {
|
||||
+ if (spawn != null && spawn.getWorld() != null) {
|
||||
+ if (spawn.getWorld() != level.getWorld()) {
|
||||
+ throw new IllegalStateException("Cannot set spawn point for " + levelData.getLevelName() + " to be in another world (" + (spawn.getWorld() != null ? spawn.getWorld().key() : null) + ")");
|
||||
+ throw new IllegalStateException("Cannot set spawn point for " + levelData.getLevelName() + " to be in another world (" + spawn.getWorld().key().asString() + ")");
|
||||
+ } else {
|
||||
+ levelData.setSpawn(
|
||||
+ net.minecraft.world.level.storage.LevelData.RespawnData.of(
|
||||
@@ -1096,7 +1096,7 @@
|
||||
ObjectArrayList<NameAndId> sample = new ObjectArrayList<>(sampleSize);
|
||||
int offset = Mth.nextInt(this.random, 0, players.size() - sampleSize);
|
||||
|
||||
@@ -1104,6 +_,32 @@
|
||||
@@ -1104,12 +_,46 @@
|
||||
protected void tickChildren(final BooleanSupplier haveTime) {
|
||||
ProfilerFiller profiler = Profiler.get();
|
||||
this.getPlayerList().getPlayers().forEach(playerx -> playerx.connection.suspendFlushing());
|
||||
@@ -1129,25 +1129,31 @@
|
||||
profiler.push("commandFunctions");
|
||||
this.getFunctions().tick();
|
||||
profiler.pop();
|
||||
@@ -1115,14 +_,28 @@
|
||||
|
||||
if (this.tickCount % 20 == 0) {
|
||||
profiler.push("timeSync");
|
||||
- this.forceGameTimeSynchronization();
|
||||
+ // Paper start - per-world game time
|
||||
+ for (final ServerLevel level : this.getAllLevels()) {
|
||||
+ this.playerList.broadcastAll(new ClientboundSetTimePacket(level.getGameTime(), Map.of()), level);
|
||||
if (this.tickRateManager.runsNormally()) {
|
||||
profiler.push("clocks");
|
||||
- this.clockManager.tick();
|
||||
+ // Paper start - per-world time
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().time.affectsAllWorlds) {
|
||||
+ this.clockManager.tick();
|
||||
+ } else {
|
||||
+ for (ServerLevel level : this.getAllLevels()) {
|
||||
+ level.clockManager().tick();
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - per-world game time
|
||||
+ // Paper end - per-world time
|
||||
profiler.pop();
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
@@ -1119,10 +_,20 @@
|
||||
profiler.pop();
|
||||
}
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ // Run tasks that are waiting on processing
|
||||
+ while (!this.processQueue.isEmpty()) {
|
||||
+ this.processQueue.remove().run();
|
||||
}
|
||||
|
||||
+ }
|
||||
+
|
||||
profiler.push("levels");
|
||||
this.updateEffectiveRespawnData();
|
||||
|
||||
@@ -1184,6 +1190,19 @@
|
||||
this.effectiveRespawnData = respawnLevel.getWorldBorderAdjustedRespawnData(respawnData);
|
||||
}
|
||||
|
||||
@@ -1179,7 +_,11 @@
|
||||
public void forceGameTimeSynchronization() {
|
||||
ProfilerFiller profiler = Profiler.get();
|
||||
profiler.push("timeSync");
|
||||
- this.playerList.broadcastAll(new ClientboundSetTimePacket(this.overworld().getGameTime(), Map.of()));
|
||||
+ // Paper start - per-world time
|
||||
+ for (ServerLevel level : this.getAllLevels()) {
|
||||
+ this.playerList.broadcastAll(new ClientboundSetTimePacket(level.getGameTime(), Map.of()), level);
|
||||
+ }
|
||||
+ // Paper end - per-world time
|
||||
profiler.pop();
|
||||
}
|
||||
|
||||
@@ -1207,6 +_,22 @@
|
||||
return this.levels.get(dimension);
|
||||
}
|
||||
@@ -1544,7 +1563,7 @@
|
||||
player.connection.send(new ClientboundEntityEventPacket(player, event));
|
||||
}
|
||||
} else if (rule == GameRules.LIMITED_CRAFTING || rule == GameRules.IMMEDIATE_RESPAWN) {
|
||||
@@ -2131,19 +_,21 @@
|
||||
@@ -2131,20 +_,21 @@
|
||||
? ClientboundGameEventPacket.LIMITED_CRAFTING
|
||||
: ClientboundGameEventPacket.IMMEDIATE_RESPAWN;
|
||||
ClientboundGameEventPacket packet = new ClientboundGameEventPacket(eventType, (Boolean)value ? 1.0F : 0.0F);
|
||||
@@ -1566,10 +1585,11 @@
|
||||
- this.updateMobSpawningFlags();
|
||||
+ level.setSpawnSettings(level.isSpawningMonsters()); // Paper - per-world game rules
|
||||
} else if (rule == GameRules.ADVANCE_TIME) {
|
||||
+ // TODO - snapshot - time handling
|
||||
this.getPlayerList().broadcastAll(this.clockManager().createFullSyncPacket());
|
||||
- this.getPlayerList().broadcastAll(this.clockManager().createFullSyncPacket());
|
||||
+ level.players().forEach(player -> player.connection.send(level.clockManager().createFullSyncPacket(player))); // Paper - per-world time; per-player time
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2157,12 +_,14 @@
|
||||
return this.savedDataStorage;
|
||||
}
|
||||
|
||||
@@ -1,67 +1,108 @@
|
||||
--- a/net/minecraft/server/commands/TimeCommand.java
|
||||
+++ b/net/minecraft/server/commands/TimeCommand.java
|
||||
@@ -170,23 +_,61 @@
|
||||
@@ -119,7 +_,7 @@
|
||||
final CommandSourceStack source, final SuggestionsBuilder builder, final Holder<WorldClock> clock
|
||||
) {
|
||||
return SharedSuggestionProvider.suggestResource(
|
||||
- source.getServer().clockManager().commandTimeMarkersForClock(clock).map(ResourceKey::identifier), builder
|
||||
+ source.getLevel().clockManager().commandTimeMarkersForClock(clock).map(ResourceKey::identifier), builder // Paper - per-world time
|
||||
);
|
||||
}
|
||||
|
||||
@@ -141,7 +_,7 @@
|
||||
}
|
||||
|
||||
private static int queryTime(final CommandSourceStack source, final Holder<WorldClock> clock) {
|
||||
- ServerClockManager clockManager = source.getServer().clockManager();
|
||||
+ ServerClockManager clockManager = source.getLevel().clockManager(); // Paper - per-world time
|
||||
long totalTicks = clockManager.getTotalTicks(clock);
|
||||
source.sendSuccess(() -> Component.translatable("commands.time.query.absolute", clock.getRegisteredName(), totalTicks), false);
|
||||
return wrapTime(totalTicks);
|
||||
@@ -151,7 +_,7 @@
|
||||
if (!clock.equals(timeline.value().clock())) {
|
||||
throw ERROR_WRONG_TIMELINE_FOR_CLOCK.create(clock.getRegisteredName(), timeline.getRegisteredName());
|
||||
} else {
|
||||
- ServerClockManager clockManager = source.getServer().clockManager();
|
||||
+ ServerClockManager clockManager = source.getLevel().clockManager(); // Paper - per-world time
|
||||
long currentTicks = timeline.value().getCurrentTicks(clockManager);
|
||||
source.sendSuccess(() -> Component.translatable("commands.time.query.timeline", timeline.getRegisteredName(), currentTicks), false);
|
||||
return wrapTime(currentTicks);
|
||||
@@ -162,33 +_,53 @@
|
||||
if (!clock.equals(timeline.value().clock())) {
|
||||
throw ERROR_WRONG_TIMELINE_FOR_CLOCK.create(clock.getRegisteredName(), timeline.getRegisteredName());
|
||||
} else {
|
||||
- ServerClockManager clockManager = source.getServer().clockManager();
|
||||
+ ServerClockManager clockManager = source.getLevel().clockManager(); // Paper - per-world time
|
||||
long repetitions = timeline.value().getPeriodCount(clockManager);
|
||||
source.sendSuccess(() -> Component.translatable("commands.time.query.timeline.repetitions", timeline.getRegisteredName(), repetitions), false);
|
||||
return wrapTime(repetitions);
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - per-world time
|
||||
private static int setTotalTicks(final CommandSourceStack source, final Holder<WorldClock> clock, final int totalTicks) {
|
||||
+ // Paper start
|
||||
+ // TODO - snapshot - 26.1
|
||||
+ for (net.minecraft.server.level.ServerLevel level : io.papermc.paper.configuration.GlobalConfiguration.get().commands.timeCommandAffectsAllWorlds ? source.getServer().getAllLevels() : java.util.List.of(source.getLevel())) {
|
||||
+ long currentTime = level.clockManager().getTotalTicks(clock);
|
||||
+ org.bukkit.event.world.TimeSkipEvent event = new org.bukkit.event.world.TimeSkipEvent(level.getWorld(), org.bukkit.event.world.TimeSkipEvent.SkipReason.COMMAND, totalTicks - currentTime);
|
||||
+ if (event.callEvent()) {
|
||||
+ level.clockManager().setTotalTicks(clock, currentTime + event.getSkipAmount());
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
ServerClockManager clockManager = source.getServer().clockManager();
|
||||
- ServerClockManager clockManager = source.getServer().clockManager();
|
||||
- clockManager.setTotalTicks(clock, totalTicks);
|
||||
+ // clockManager.setTotalTicks(clock, totalTicks);
|
||||
source.sendSuccess(() -> Component.translatable("commands.time.set.absolute", clock.getRegisteredName(), totalTicks), true);
|
||||
return totalTicks;
|
||||
- source.sendSuccess(() -> Component.translatable("commands.time.set.absolute", clock.getRegisteredName(), totalTicks), true);
|
||||
- return totalTicks;
|
||||
+ ServerClockManager clockManager = source.getLevel().clockManager();
|
||||
+ long currentTotalTicks = clockManager.getTotalTicks(clock);
|
||||
+ org.bukkit.event.world.ClockTimeSkipEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.createTimeSkipEvent(source, totalTicks - currentTotalTicks);
|
||||
+ final long newTotalTicks;
|
||||
+ if (event.callEvent()) {
|
||||
+ newTotalTicks = currentTotalTicks + event.getSkipAmount();
|
||||
+ clockManager.setTotalTicks(clock, newTotalTicks);
|
||||
+ } else {
|
||||
+ newTotalTicks = totalTicks; // just pass it through
|
||||
+ }
|
||||
+ source.sendSuccess(() -> Component.translatable("commands.time.set.absolute", clock.getRegisteredName(), newTotalTicks), true);
|
||||
+ return wrapTime(newTotalTicks);
|
||||
}
|
||||
|
||||
private static int addTime(final CommandSourceStack source, final Holder<WorldClock> clock, final int time) {
|
||||
+ // Paper start
|
||||
+ // TODO - snapshot - 26.1
|
||||
+ for (net.minecraft.server.level.ServerLevel level : io.papermc.paper.configuration.GlobalConfiguration.get().commands.timeCommandAffectsAllWorlds ? source.getServer().getAllLevels() : java.util.List.of(source.getLevel())) {
|
||||
+ org.bukkit.event.world.TimeSkipEvent event = new org.bukkit.event.world.TimeSkipEvent(level.getWorld(), org.bukkit.event.world.TimeSkipEvent.SkipReason.COMMAND, time);;
|
||||
+ if (event.callEvent()) {
|
||||
+ level.clockManager().addTicks(clock, event.getSkipAmount());
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
ServerClockManager clockManager = source.getServer().clockManager();
|
||||
- ServerClockManager clockManager = source.getServer().clockManager();
|
||||
- clockManager.addTicks(clock, time);
|
||||
+ // Paper - move up
|
||||
+ ServerClockManager clockManager = source.getLevel().clockManager();
|
||||
+ org.bukkit.event.world.ClockTimeSkipEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.createTimeSkipEvent(source, time);
|
||||
+ if (event.callEvent()) {
|
||||
+ clockManager.addTicks(clock, event.getSkipAmount());
|
||||
+ }
|
||||
long totalTicks = clockManager.getTotalTicks(clock);
|
||||
source.sendSuccess(() -> Component.translatable("commands.time.set.absolute", clock.getRegisteredName(), totalTicks), true);
|
||||
return wrapTime(totalTicks);
|
||||
}
|
||||
|
||||
private static int setTimeToTimeMarker(final CommandSourceStack source, final Holder<WorldClock> clock, final ResourceKey<ClockTimeMarker> timeMarkerId) throws CommandSyntaxException {
|
||||
+ // Paper start
|
||||
+ // TODO - snapshot - 26.1
|
||||
+ boolean foundMarker = false;
|
||||
+ for (net.minecraft.server.level.ServerLevel level : io.papermc.paper.configuration.GlobalConfiguration.get().commands.timeCommandAffectsAllWorlds ? source.getServer().getAllLevels() : java.util.List.of(source.getLevel())) {
|
||||
+ java.util.OptionalLong targetTime = level.clockManager().getTotalTicksToTimeMarker(clock, timeMarkerId);
|
||||
+ if (targetTime.isEmpty()) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ foundMarker = true;
|
||||
+ long currentTime = level.clockManager().getTotalTicks(clock);
|
||||
+ long delta = targetTime.getAsLong() - currentTime;
|
||||
+ org.bukkit.event.world.TimeSkipEvent event = new org.bukkit.event.world.TimeSkipEvent(level.getWorld(), org.bukkit.event.world.TimeSkipEvent.SkipReason.COMMAND, delta);
|
||||
+ if (event.callEvent()) {
|
||||
+ level.clockManager().setTotalTicks(clock, currentTime + event.getSkipAmount());
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
ServerClockManager clockManager = source.getServer().clockManager();
|
||||
- ServerClockManager clockManager = source.getServer().clockManager();
|
||||
- if (!clockManager.moveToTimeMarker(clock, timeMarkerId)) {
|
||||
+ if (!foundMarker) { // Paper
|
||||
+ // Paper start - per-world time
|
||||
+ ServerClockManager clockManager = source.getLevel().clockManager();
|
||||
+ java.util.OptionalLong targetTime = clockManager.getTotalTicksToTimeMarker(clock, timeMarkerId);
|
||||
+ if (targetTime.isEmpty()) {
|
||||
throw ERROR_NO_TIME_MARKER_FOUND.create(clock.getRegisteredName(), timeMarkerId);
|
||||
} else {
|
||||
+ final long currentTime = clockManager.getTotalTicks(clock);
|
||||
+ final org.bukkit.event.world.ClockTimeSkipEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.createTimeSkipEvent(source, targetTime.getAsLong() - currentTime);
|
||||
+ if (event.callEvent()) {
|
||||
+ clockManager.setTotalTicks(clock, currentTime + event.getSkipAmount());
|
||||
+ }
|
||||
+ // Paper end - per-world time
|
||||
source.sendSuccess(
|
||||
() -> Component.translatable("commands.time.set.time_marker", clock.getRegisteredName(), timeMarkerId.identifier().toString()), true
|
||||
);
|
||||
@@ -197,13 +_,13 @@
|
||||
}
|
||||
|
||||
private static int setPaused(final CommandSourceStack source, final Holder<WorldClock> clock, final boolean paused) {
|
||||
- source.getServer().clockManager().setPaused(clock, paused);
|
||||
+ source.getLevel().clockManager().setPaused(clock, paused); // Paper - per-world time
|
||||
source.sendSuccess(() -> Component.translatable(paused ? "commands.time.pause" : "commands.time.resume", clock.getRegisteredName()), true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int setRate(final CommandSourceStack source, final Holder<WorldClock> clock, final float rate) {
|
||||
- source.getServer().clockManager().setRate(clock, rate);
|
||||
+ source.getLevel().clockManager().setRate(clock, rate); // Paper - per-world time
|
||||
source.sendSuccess(() -> Component.translatable("commands.time.rate", clock.getRegisteredName(), rate), true);
|
||||
return 1;
|
||||
}
|
||||
@@ -189,6 +189,15 @@
|
||||
this.ticketStorage.purgeStaleTickets(this.chunkMap);
|
||||
}
|
||||
|
||||
@@ -344,7 +_,7 @@
|
||||
if (!this.level.isDebug()) {
|
||||
ProfilerFiller profiler = Profiler.get();
|
||||
profiler.push("pollingChunks");
|
||||
- if (this.level.tickRateManager().runsNormally()) {
|
||||
+ if (this.level.tickRateManager().runsNormally() && this.level.paperConfig().unsupportedSettings.ticking.chunks) { // Paper - option to disable ticking
|
||||
profiler.push("tickingChunks");
|
||||
this.tickChunks(profiler, timeDiff);
|
||||
profiler.pop();
|
||||
@@ -376,12 +_,20 @@
|
||||
chunkCount, this.level.getAllEntities(), this::getFullChunk, new LocalMobCapCalculator(this.chunkMap)
|
||||
);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
private final EntityTickList entityTickList = new EntityTickList();
|
||||
private final ServerWaypointManager waypointManager;
|
||||
private EnvironmentAttributeSystem environmentAttributes;
|
||||
@@ -221,24 +_,192 @@
|
||||
@@ -221,24 +_,199 @@
|
||||
private final boolean tickTime;
|
||||
private final LevelDebugSynchronizers debugSynchronizers = new LevelDebugSynchronizers(this);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
+ private final WeatherData weatherData;
|
||||
+ public final net.minecraft.world.level.timers.TimerQueue<net.minecraft.server.MinecraftServer> scheduledEvents;
|
||||
+ public final WorldGenSettings worldGenSettings;
|
||||
+ private @Nullable ServerClockManager clockManager;
|
||||
+ public boolean hasPhysicsEvent = true; // Paper - BlockPhysicsEvent
|
||||
+ public boolean hasEntityMoveEvent; // Paper - Add EntityMoveEvent
|
||||
+
|
||||
@@ -184,6 +185,12 @@
|
||||
this.serverLevelData = levelData;
|
||||
ChunkGenerator generator = levelStem.generator();
|
||||
+ // CraftBukkit start
|
||||
+ // Paper start - per-world time
|
||||
+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().time.affectsAllWorlds) {
|
||||
+ this.clockManager = savedDataStorage.computeIfAbsent(net.minecraft.world.clock.ServerClockManager.TYPE); // Paper - per-world time
|
||||
+ this.clockManager.init(server, this); // Paper - per-world time
|
||||
+ }
|
||||
+ // Paper end - per-world time
|
||||
+ if (loadedWorldData.pdc() != null) {
|
||||
+ this.getWorld().readBukkitValues(loadedWorldData.pdc().persistentData().toTagCompound());
|
||||
+ }
|
||||
@@ -262,30 +269,39 @@
|
||||
|
||||
@Deprecated
|
||||
@VisibleForTesting
|
||||
@@ -322,7 +_,7 @@
|
||||
|
||||
@Override
|
||||
public ServerClockManager clockManager() {
|
||||
- return this.server.clockManager();
|
||||
+ return io.papermc.paper.configuration.GlobalConfiguration.get().time.affectsAllWorlds ? this.server.clockManager() : this.clockManager; // Paper - per-world time
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -354,11 +_,24 @@
|
||||
int percentage = this.getGameRules().get(GameRules.PLAYERS_SLEEPING_PERCENTAGE);
|
||||
if (this.sleepStatus.areEnoughSleeping(percentage) && this.sleepStatus.areEnoughDeepSleeping(percentage, this.players)) {
|
||||
Optional<Holder<WorldClock>> defaultClock = this.dimensionType().defaultClock();
|
||||
+ org.bukkit.event.world.TimeSkipEvent event = null; // Paper - time skip event
|
||||
+ org.bukkit.event.world.ClockTimeSkipEvent event = null; // Paper - per-world time
|
||||
if (this.getGameRules().get(GameRules.ADVANCE_TIME) && defaultClock.isPresent()) {
|
||||
- this.server.clockManager().moveToTimeMarker(defaultClock.get(), ClockTimeMarkers.WAKE_UP_FROM_SLEEP);
|
||||
+ // Paper start - time skip event
|
||||
+ long currentTime = this.server.clockManager().getTotalTicks(defaultClock.get());
|
||||
+ long delta = this.server.clockManager().getTotalTicksToTimeMarker(defaultClock.get(), ClockTimeMarkers.WAKE_UP_FROM_SLEEP).orElse(0L) - currentTime;
|
||||
+ // Paper start - per-world time
|
||||
+ long currentTime = this.clockManager().getTotalTicks(defaultClock.get());
|
||||
+ long delta = this.clockManager().getTotalTicksToTimeMarker(defaultClock.get(), ClockTimeMarkers.WAKE_UP_FROM_SLEEP).orElse(0L) - currentTime;
|
||||
+ event = new org.bukkit.event.world.TimeSkipEvent(
|
||||
+ this.getWorld(),
|
||||
+ org.bukkit.event.world.TimeSkipEvent.SkipReason.NIGHT_SKIP,
|
||||
+ org.bukkit.event.world.ClockTimeSkipEvent.SkipReason.NIGHT_SKIP,
|
||||
+ delta
|
||||
+ );
|
||||
+
|
||||
+ if (event.callEvent()) {
|
||||
+ this.server.clockManager().setTotalTicks(defaultClock.get(), currentTime + event.getSkipAmount()); // TODO - snapshot - per world time
|
||||
+ this.clockManager().setTotalTicks(defaultClock.get(), currentTime + event.getSkipAmount());
|
||||
+ }
|
||||
+ // Paper end - time skip event
|
||||
+ // Paper end - per-world time
|
||||
}
|
||||
|
||||
- this.wakeUpAllPlayers();
|
||||
+ if (event == null || !event.isCancelled()) this.wakeUpAllPlayers(); // Paper - time skip event - only wake up players if time skip event is not cancelled
|
||||
+ if (event == null || !event.isCancelled()) this.wakeUpAllPlayers(); // Paper - per-world time - only wake up players if time skip event is not cancelled
|
||||
if (this.getGameRules().get(GameRules.ADVANCE_WEATHER) && this.isRaining()) {
|
||||
this.resetWeatherCycle();
|
||||
}
|
||||
@@ -310,6 +326,19 @@
|
||||
if (isActive) {
|
||||
this.resetEmptyTime();
|
||||
}
|
||||
@@ -437,9 +_,12 @@
|
||||
}
|
||||
}
|
||||
);
|
||||
+ if (this.paperConfig().unsupportedSettings.ticking.blockEntities) { // Paper - option to disable ticking
|
||||
profiler.popPush("blockEntities");
|
||||
this.tickBlockEntities();
|
||||
profiler.pop();
|
||||
+ } // Paper - option to disable ticking
|
||||
+ this.spigotConfig.currentPrimedTnt = 0; // Spigot
|
||||
}
|
||||
|
||||
profiler.push("entityManagement");
|
||||
@@ -468,7 +_,7 @@
|
||||
long time = this.levelData.getGameTime() + 1L;
|
||||
this.serverLevelData.setGameTime(time);
|
||||
|
||||
+5
-9
@@ -9,13 +9,12 @@
|
||||
private final boolean transferred;
|
||||
private long keepAliveTime;
|
||||
private boolean keepAlivePending;
|
||||
@@ -46,6 +_,17 @@
|
||||
@@ -46,6 +_,16 @@
|
||||
private boolean closed = false;
|
||||
private int latency;
|
||||
private volatile boolean suspendFlushingOnServerThread = false;
|
||||
+ // CraftBukkit start
|
||||
+ public final org.bukkit.craftbukkit.CraftServer cserver;
|
||||
+ public boolean processedDisconnect;
|
||||
+ // CraftBukkit end
|
||||
+ public final java.util.Map<java.util.UUID, net.kyori.adventure.resource.ResourcePackCallback> packCallbacks = new java.util.concurrent.ConcurrentHashMap<>(); // Paper - adventure resource pack callbacks
|
||||
+ private static final long KEEPALIVE_LIMIT = Long.getLong("paper.playerconnection.keepalive", 30) * 1000; // Paper - provide property to set keepalive limit
|
||||
@@ -210,7 +209,7 @@
|
||||
|
||||
public void send(final Packet<?> packet, final @Nullable ChannelFutureListener listener) {
|
||||
+ // CraftBukkit start
|
||||
+ if (packet == null || this.processedDisconnect) { // Spigot
|
||||
+ if (packet == null) {
|
||||
+ return;
|
||||
+ } else if (packet instanceof net.minecraft.network.protocol.game.ClientboundSetDefaultSpawnPositionPacket defaultSpawnPositionPacket && this instanceof ServerGamePacketListenerImpl serverGamePacketListener) {
|
||||
+ serverGamePacketListener.player.compassTarget = org.bukkit.craftbukkit.util.CraftLocation.toBukkit(defaultSpawnPositionPacket.respawnData().pos(), serverGamePacketListener.getPlayer().level());
|
||||
@@ -219,7 +218,7 @@
|
||||
if (packet.isTerminal()) {
|
||||
this.close();
|
||||
}
|
||||
@@ -174,15 +_,111 @@
|
||||
@@ -174,15 +_,108 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,7 +236,7 @@
|
||||
|
||||
public void disconnect(final DisconnectionDetails details) {
|
||||
+ // CraftBukkit start - fire PlayerKickEvent
|
||||
+ if (this.processedDisconnect) {
|
||||
+ if (!this.connection.isConnected()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (!this.cserver.isPrimaryThread()) {
|
||||
@@ -303,14 +302,11 @@
|
||||
+ }
|
||||
+
|
||||
+ private void disconnect0(final DisconnectionDetails details) {
|
||||
+ // CraftBukkit end
|
||||
this.connection.send(new ClientboundDisconnectPacket(details.reason()), PacketSendListener.thenRun(() -> this.connection.disconnect(details)));
|
||||
+ this.onDisconnect(details); // CraftBukkit - fire quit instantly
|
||||
this.connection.setReadOnly();
|
||||
- this.server.executeBlocking(this.connection::handleDisconnection);
|
||||
- }
|
||||
+ // CraftBukkit - Don't wait
|
||||
+ this.server.scheduleOnMain(this.connection::handleDisconnection); // Paper
|
||||
+ this.connection.handleConnectionDisconnectOnNextTick = true; // Paper - Force kill connection ticking. Let this close the connection
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - add proper async disconnect
|
||||
|
||||
+14
-1
@@ -100,7 +100,7 @@
|
||||
public SocketAddress startMemoryChannel() {
|
||||
ChannelFuture newChannel;
|
||||
synchronized (this.channels) {
|
||||
@@ -151,6 +_,13 @@
|
||||
@@ -151,12 +_,26 @@
|
||||
|
||||
public void tick() {
|
||||
synchronized (this.connections) {
|
||||
@@ -114,6 +114,19 @@
|
||||
Iterator<Connection> iterator = this.connections.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Connection connection = iterator.next();
|
||||
if (!connection.isConnecting()) {
|
||||
if (connection.isConnected()) {
|
||||
+ // Paper start - Force kill connection ticking
|
||||
+ // also call this multiple times, doesnt matter
|
||||
+ // See MC-307764
|
||||
+ if (connection.handleConnectionDisconnectOnNextTick) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Paper end - Force kill connection ticking
|
||||
try {
|
||||
connection.tick();
|
||||
} catch (Exception var7) {
|
||||
@@ -170,6 +_,7 @@
|
||||
connection.setReadOnly();
|
||||
}
|
||||
|
||||
+12
-17
@@ -83,7 +83,7 @@
|
||||
|
||||
public ServerGamePacketListenerImpl(final MinecraftServer server, final Connection connection, final ServerPlayer player, final CommonListenerCookie cookie) {
|
||||
super(server, connection, cookie);
|
||||
@@ -284,11 +_,26 @@
|
||||
@@ -284,8 +_,22 @@
|
||||
player.connection = this;
|
||||
player.getTextFilter().join();
|
||||
this.signedMessageDecoder = SignedMessageChain.Decoder.unsigned(player.getUUID(), server::enforceSecureProfile);
|
||||
@@ -108,10 +108,6 @@
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
+ if (this.isDisconnected()) return; // Paper
|
||||
if (this.ackBlockChangesUpTo > -1) {
|
||||
this.send(new ClientboundBlockChangedAckPacket(this.ackBlockChangesUpTo));
|
||||
this.ackBlockChangesUpTo = -1;
|
||||
@@ -298,11 +_,13 @@
|
||||
this.keepConnectionAlive();
|
||||
this.chatSpamThrottler.tick();
|
||||
@@ -1356,17 +1352,9 @@
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1453,24 +_,50 @@
|
||||
|
||||
@@ -1454,23 +_,42 @@
|
||||
@Override
|
||||
public void onDisconnect(final DisconnectionDetails details) {
|
||||
+ // CraftBukkit start - Rarely it would send a disconnect line twice
|
||||
+ if (this.processedDisconnect) {
|
||||
+ return;
|
||||
+ } else {
|
||||
+ this.processedDisconnect = true;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
LOGGER.info("{} lost connection: {}", this.player.getPlainTextName(), details.reason().getString());
|
||||
- this.removePlayerFromWorld();
|
||||
+ // Paper start - Fix kick event leave message not being sent
|
||||
@@ -2510,7 +2498,7 @@
|
||||
if (this.player.isModelPartShown(PlayerModelPart.HAT) != wasHatShown) {
|
||||
this.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_HAT, this.player));
|
||||
}
|
||||
@@ -2082,7 +_,7 @@
|
||||
@@ -2082,21 +_,21 @@
|
||||
packet.difficulty().getDisplayName()
|
||||
);
|
||||
} else {
|
||||
@@ -2519,7 +2507,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2096,7 +_,7 @@
|
||||
@Override
|
||||
public void handleChangeGameMode(final ServerboundChangeGameModePacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
- if (!GameModeCommand.PERMISSION_CHECK.check(this.player.permissions())) {
|
||||
+ if (!GameModeCommand.PERMISSION_CHECK.check(this.player.permissions()) && !this.player.getBukkitEntity().hasPermission("minecraft.command.gamemode")) { // Paper - add permission check
|
||||
LOGGER.warn(
|
||||
"Player {} tried to change game mode to {} without required permissions",
|
||||
this.player.getGameProfile().name(),
|
||||
packet.mode().getShortDisplayName().getString()
|
||||
);
|
||||
} else {
|
||||
@@ -2664,7 +2659,7 @@
|
||||
+ }
|
||||
+
|
||||
+ public final boolean isDisconnected() {
|
||||
+ return (!this.player.joining && !this.connection.isConnected()) || this.processedDisconnect; // Paper - Fix duplication bugs
|
||||
+ return (!this.player.joining && !this.connection.isConnected());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
|
||||
+33
-25
@@ -13,11 +13,11 @@
|
||||
public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, TickablePacketListener {
|
||||
private static final AtomicInteger UNIQUE_THREAD_ID = new AtomicInteger(0);
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
+ private static final java.util.concurrent.ExecutorService authenticatorPool = java.util.concurrent.Executors.newCachedThreadPool(new com.google.common.util.concurrent.ThreadFactoryBuilder().setNameFormat("User Authenticator #%d").setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER)).build()); // Paper - Cache authenticator threads
|
||||
+ private static final java.util.concurrent.ExecutorService authenticatorPool = java.util.concurrent.Executors.newThreadPerTaskExecutor(Thread.ofVirtual().name("User Authenticator #", 0).uncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER)).factory()); // Paper - Virtual authenticator threads
|
||||
private static final int MAX_TICKS_BEFORE_LOGIN = 600;
|
||||
private final byte[] challenge;
|
||||
private final MinecraftServer server;
|
||||
@@ -56,10 +_,15 @@
|
||||
@@ -56,10 +_,14 @@
|
||||
private final ServerActivityMonitor serverActivityMonitor;
|
||||
public volatile ServerLoginPacketListenerImpl.State state = ServerLoginPacketListenerImpl.State.HELLO;
|
||||
private int tick;
|
||||
@@ -31,11 +31,10 @@
|
||||
+ private int velocityLoginMessageId = -1; // Paper - Add Velocity IP Forwarding Support
|
||||
+ public java.util.@Nullable UUID requestedUuid; // Paper
|
||||
+ private final io.papermc.paper.connection.PaperPlayerLoginConnection paperLoginConnection; // Paper - Config API
|
||||
+ private volatile boolean disconnecting = false; // Paper - Fix disconnect still ticking login
|
||||
|
||||
public ServerLoginPacketListenerImpl(final MinecraftServer minecraftserver, final Connection connection, final boolean transferred) {
|
||||
this.server = minecraftserver;
|
||||
@@ -67,10 +_,20 @@
|
||||
@@ -67,10 +_,19 @@
|
||||
this.serverActivityMonitor = this.server.getServerActivityMonitor();
|
||||
this.challenge = Ints.toByteArray(RandomSource.create().nextInt());
|
||||
this.transferred = transferred;
|
||||
@@ -44,7 +43,6 @@
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
+ if (this.disconnecting) return; // Paper - Fix disconnect being called multiple times due to not awaiting for disconnect
|
||||
+ // Paper start - login cookie API
|
||||
+ // Don't block the connection
|
||||
+ if (this.paperLoginConnection.isAwaitingCookies()) {
|
||||
@@ -56,7 +54,7 @@
|
||||
if (this.state == ServerLoginPacketListenerImpl.State.VERIFYING) {
|
||||
this.verifyLoginAndFinishConnectionSetup(Objects.requireNonNull(this.authenticatedProfile));
|
||||
}
|
||||
@@ -80,11 +_,23 @@
|
||||
@@ -80,16 +_,39 @@
|
||||
this.finishLoginAndWaitForClient(this.authenticatedProfile);
|
||||
}
|
||||
|
||||
@@ -66,28 +64,37 @@
|
||||
+ public void tickTimeout() {
|
||||
+ // Paper end - login cookie API
|
||||
if (this.tick++ == 600) {
|
||||
this.disconnect(Component.translatable("multiplayer.disconnect.slow_login"));
|
||||
- this.disconnect(Component.translatable("multiplayer.disconnect.slow_login"));
|
||||
+ this.disconnectAsync(Component.translatable("multiplayer.disconnect.slow_login")); // Paper
|
||||
}
|
||||
}
|
||||
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
+ @Deprecated
|
||||
+ public void disconnect(String reason) {
|
||||
+ this.disconnect(io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(reason))); // Paper - Fix hex colors not working in some kick messages
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
|
||||
@Override
|
||||
public boolean isAcceptingMessages() {
|
||||
return this.connection.isConnected();
|
||||
@@ -95,6 +_,7 @@
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public void disconnectAsync(Component reason) {
|
||||
+ try {
|
||||
+ LOGGER.info("Disconnecting {}: {}", this.getUserName(), reason.getString());
|
||||
+ this.connection.send(new ClientboundLoginDisconnectPacket(reason), PacketSendListener.thenRun(() -> this.connection.disconnect(reason)));
|
||||
+ this.connection.handleConnectionDisconnectOnNextTick = true;
|
||||
+ } catch (Exception var3) {
|
||||
+ LOGGER.error("Error whilst disconnecting player", (Throwable)var3);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
public void disconnect(final Component component) {
|
||||
try {
|
||||
LOGGER.info("Disconnecting {}: {}", this.getUserName(), component.getString());
|
||||
this.connection.send(new ClientboundLoginDisconnectPacket(component));
|
||||
this.connection.disconnect(component);
|
||||
+ this.disconnecting = true; // Paper - Fix disconnect still ticking login
|
||||
} catch (Exception var3) {
|
||||
LOGGER.error("Error whilst disconnecting player", (Throwable)var3);
|
||||
}
|
||||
@@ -117,7 +_,14 @@
|
||||
@Override
|
||||
public void handleHello(final ServerboundHelloPacket packet) {
|
||||
@@ -104,7 +111,7 @@
|
||||
this.requestedUsername = packet.name();
|
||||
GameProfile singleplayerProfile = this.server.getSingleplayerProfile();
|
||||
if (singleplayerProfile != null && this.requestedUsername.equalsIgnoreCase(singleplayerProfile.name())) {
|
||||
@@ -127,7 +_,32 @@
|
||||
@@ -127,7 +_,30 @@
|
||||
this.state = ServerLoginPacketListenerImpl.State.KEY;
|
||||
this.connection.send(new ClientboundHelloPacket("", this.server.getKeyPair().getPublic().getEncoded(), this.challenge, true));
|
||||
} else {
|
||||
@@ -119,8 +126,7 @@
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Add Velocity IP Forwarding Support
|
||||
+ // CraftBukkit start
|
||||
+ // Paper start - Cache authenticator threads
|
||||
+ // Paper start - Virtual authenticator threads
|
||||
+ authenticatorPool.execute(() -> {
|
||||
+ try {
|
||||
+ GameProfile gameprofile = ServerLoginPacketListenerImpl.this.createOfflineProfile(ServerLoginPacketListenerImpl.this.requestedUsername); // Spigot
|
||||
@@ -133,20 +139,22 @@
|
||||
+ ServerLoginPacketListenerImpl.this.server.server.getLogger().log(java.util.logging.Level.WARNING, "Exception verifying " + ServerLoginPacketListenerImpl.this.requestedUsername, ex);
|
||||
+ }
|
||||
+ });
|
||||
+ // Paper end - Cache authenticator threads
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Virtual authenticator threads
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,7 +_,7 @@
|
||||
@@ -139,9 +_,9 @@
|
||||
|
||||
private void verifyLoginAndFinishConnectionSetup(final GameProfile profile) {
|
||||
PlayerList playerList = this.server.getPlayerList();
|
||||
- Component error = playerList.canPlayerLogin(this.connection.getRemoteAddress(), new NameAndId(profile));
|
||||
+ Component error = org.bukkit.craftbukkit.event.CraftEventFactory.handleLoginResult(playerList.canPlayerLogin(this.connection.getRemoteAddress(), new NameAndId(profile)), this.paperLoginConnection, this.connection, profile, this.server, true); // Paper
|
||||
if (error != null) {
|
||||
this.disconnect(error);
|
||||
- this.disconnect(error);
|
||||
+ this.disconnectAsync(error); // Paper
|
||||
} else {
|
||||
if (this.server.getCompressionThreshold() >= 0 && !this.connection.isMemoryConnection()) {
|
||||
this.connection
|
||||
@@ -151,7 +_,7 @@
|
||||
);
|
||||
}
|
||||
@@ -169,7 +177,7 @@
|
||||
}
|
||||
|
||||
- Thread thread = new Thread("User Authenticator #" + UNIQUE_THREAD_ID.incrementAndGet()) {
|
||||
+ // Paper start - Cache authenticator threads
|
||||
+ // Paper start - Virtual authenticator threads
|
||||
+ authenticatorPool.execute(new Runnable() {
|
||||
{
|
||||
Objects.requireNonNull(ServerLoginPacketListenerImpl.this);
|
||||
@@ -222,7 +230,7 @@
|
||||
- thread.start();
|
||||
- }
|
||||
+ });
|
||||
+ // Paper end - Cache authenticator threads
|
||||
+ // Paper end - Virtual authenticator threads
|
||||
+ }
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
|
||||
+1
-1
@@ -125,7 +125,7 @@
|
||||
+ );
|
||||
+ ev.callEvent();
|
||||
+ spawnPosition = io.papermc.paper.util.MCUtil.toVec3(ev.getSpawnLocation());
|
||||
+ this.spawnLevel = ((org.bukkit.craftbukkit.CraftWorld) ev.getSpawnLocation().getWorld()).getHandle();
|
||||
+ if (ev.getSpawnLocation().getWorld() != null) this.spawnLevel = ((org.bukkit.craftbukkit.CraftWorld) ev.getSpawnLocation().getWorld()).getHandle();
|
||||
+ this.spawnPosition = CompletableFuture.completedFuture(spawnPosition);
|
||||
+ this.spawnAngle = new Vec2(ev.getSpawnLocation().getYaw(), ev.getSpawnLocation().getPitch());
|
||||
+ }
|
||||
|
||||
@@ -272,7 +272,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -296,64 +_,148 @@
|
||||
@@ -296,64 +_,147 @@
|
||||
}
|
||||
|
||||
protected void save(final ServerPlayer player) {
|
||||
@@ -310,7 +310,6 @@
|
||||
+ this.cserver.getPluginManager().callEvent(playerQuitEvent);
|
||||
+ player.getBukkitEntity().disconnect();
|
||||
+
|
||||
+ if (this.server.isSameThread()) player.doTick(); // SPIGOT-924 // Paper - Improved watchdog support; don't tick during emergency shutdowns
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ // Paper start - Configurable player collision; Remove from collideRule team if needed
|
||||
@@ -741,9 +740,12 @@
|
||||
}
|
||||
|
||||
public UserWhiteList getWhiteList() {
|
||||
@@ -654,10 +_,18 @@
|
||||
@@ -652,12 +_,20 @@
|
||||
public void sendLevelInfo(final ServerPlayer player, final ServerLevel level) {
|
||||
WorldBorder worldBorder = level.getWorldBorder();
|
||||
player.connection.send(new ClientboundInitializeBorderPacket(worldBorder));
|
||||
player.connection.send(this.server.clockManager().createFullSyncPacket());
|
||||
- player.connection.send(this.server.clockManager().createFullSyncPacket());
|
||||
+ player.connection.send(level.clockManager().createFullSyncPacket(player)); // Paper - per-world time; per-player time
|
||||
player.connection.send(new ClientboundSetDefaultSpawnPositionPacket(level.getRespawnData()));
|
||||
+ // Paper start - view distances
|
||||
+ player.connection.send(new ClientboundSetChunkCacheRadiusPacket(io.papermc.paper.FeatureHooks.getViewDistance(level)));
|
||||
|
||||
+102
-22
@@ -1,5 +1,35 @@
|
||||
--- a/net/minecraft/world/clock/ServerClockManager.java
|
||||
+++ b/net/minecraft/world/clock/ServerClockManager.java
|
||||
@@ -30,6 +_,7 @@
|
||||
);
|
||||
private final PackedClockStates packedClockStates;
|
||||
private MinecraftServer server;
|
||||
+ private @org.jspecify.annotations.Nullable ServerLevel level; // Paper - per-world time
|
||||
private final Map<Holder<WorldClock>, ServerClockManager.ClockInstance> clocks = new HashMap<>();
|
||||
|
||||
private ServerClockManager(final PackedClockStates packedClockStates) {
|
||||
@@ -37,6 +_,12 @@
|
||||
}
|
||||
|
||||
public void init(final MinecraftServer server) {
|
||||
+ // Paper start - per-world time
|
||||
+ this.init(server, null);
|
||||
+ }
|
||||
+ public void init(final MinecraftServer server, @org.jspecify.annotations.Nullable final ServerLevel level) {
|
||||
+ this.level = level;
|
||||
+ // Paper end - per-world time
|
||||
this.server = server;
|
||||
server.registryAccess()
|
||||
.lookupOrThrow(Registries.WORLD_CLOCK)
|
||||
@@ -61,7 +_,7 @@
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
- boolean advanceTime = this.server.getGlobalGameRules().get(GameRules.ADVANCE_TIME);
|
||||
+ boolean advanceTime = this.advanceTime(); // Paper - per-world time
|
||||
if (advanceTime) {
|
||||
this.clocks.values().forEach(ServerClockManager.ClockInstance::tick);
|
||||
this.setDirty();
|
||||
@@ -97,7 +_,16 @@
|
||||
return set.booleanValue();
|
||||
}
|
||||
@@ -18,36 +48,86 @@
|
||||
this.modifyClock(clock, instance -> instance.totalTicks = Math.max(instance.totalTicks + ticks, 0L));
|
||||
}
|
||||
|
||||
@@ -113,7 +_,7 @@
|
||||
@@ -112,13 +_,18 @@
|
||||
private void modifyClock(final Holder<WorldClock> clock, final Consumer<? super ServerClockManager.ClockInstance> action) {
|
||||
ServerClockManager.ClockInstance instance = this.getInstance(clock);
|
||||
action.accept(instance);
|
||||
Map<Holder<WorldClock>, ClockNetworkState> updates = Map.of(clock, instance.packNetworkState(this.server));
|
||||
- Map<Holder<WorldClock>, ClockNetworkState> updates = Map.of(clock, instance.packNetworkState(this.server));
|
||||
- this.server.getPlayerList().broadcastAll(new ClientboundSetTimePacket(this.getGameTime(), updates));
|
||||
+ this.server.getPlayerList().broadcastAll(new ClientboundSetTimePacket(this.getGameTime(), updates)); // TODO 26.1 per-player time
|
||||
+ // Paper start - per-world time
|
||||
+ this.broadcastUpdates(clock, instance);
|
||||
this.setDirty();
|
||||
|
||||
+ if (this.level != null) {
|
||||
+ this.level.environmentAttributes().invalidateTickCache();
|
||||
+ } else {
|
||||
for (ServerLevel level : this.server.getAllLevels()) {
|
||||
@@ -126,7 +_,23 @@
|
||||
return this.getInstance(definition).totalTicks;
|
||||
level.environmentAttributes().invalidateTickCache();
|
||||
}
|
||||
+ }
|
||||
+ // Paper end - per-world time
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -127,12 +_,48 @@
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ // TODO - snapshot: just make the inner class, fields and getter public
|
||||
+ public boolean isPaused(final Holder<WorldClock> definition) {
|
||||
+ return this.getInstance(definition).paused;
|
||||
+ }
|
||||
+
|
||||
+ public float partialTick(final Holder<WorldClock> definition) {
|
||||
+ return this.getInstance(definition).partialTick;
|
||||
+ }
|
||||
+
|
||||
+ public float rate(final Holder<WorldClock> definition) {
|
||||
+ return this.getInstance(definition).rate;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public ClientboundSetTimePacket createFullSyncPacket() {
|
||||
+ // TODO - snapshot: 26.1 per-player time
|
||||
return new ClientboundSetTimePacket(this.getGameTime(), Util.mapValues(this.clocks, clock -> clock.packNetworkState(this.server)));
|
||||
- return new ClientboundSetTimePacket(this.getGameTime(), Util.mapValues(this.clocks, clock -> clock.packNetworkState(this.server)));
|
||||
+ // Paper start - per-player time
|
||||
+ return this.createFullSyncPacket(null);
|
||||
+ }
|
||||
+
|
||||
+ public ClientboundSetTimePacket createFullSyncPacket(final net.minecraft.server.level.ServerPlayer player) {
|
||||
+ final Map<Holder<WorldClock>, ClockNetworkState> updates = new HashMap<>(this.clocks.size());
|
||||
+ this.clocks.forEach((clock, instance) -> updates.put(clock, this.packNetworkState(clock, instance, player)));
|
||||
+ return new ClientboundSetTimePacket(this.getGameTime(), updates);
|
||||
+ // Paper end - per-player time
|
||||
}
|
||||
|
||||
private long getGameTime() {
|
||||
- return this.server.overworld().getGameTime();
|
||||
- }
|
||||
+ return this.level != null ? this.level.getGameTime() : this.server.overworld().getGameTime(); // Paper - per-world time
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - per-world time; per-player time
|
||||
+ private void broadcastUpdates(final Holder<WorldClock> clock, final ServerClockManager.ClockInstance instance) {
|
||||
+ for (final net.minecraft.server.level.ServerPlayer player : this.level != null ? this.level.players() : this.server.getPlayerList().getPlayers()) {
|
||||
+ final var packet = new net.minecraft.network.protocol.game.ClientboundSetTimePacket(
|
||||
+ this.getGameTime(),
|
||||
+ java.util.Map.of(clock, this.packNetworkState(clock, instance, player))
|
||||
+ );
|
||||
+ player.connection.send(packet);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private ClockNetworkState packNetworkState(
|
||||
+ final Holder<WorldClock> clock,
|
||||
+ final ServerClockManager.ClockInstance instance,
|
||||
+ final net.minecraft.server.level.ServerPlayer player
|
||||
+ ) {
|
||||
+ if (player != null && player.level().dimensionType().defaultClock().filter(clock::equals).isPresent()) {
|
||||
+ final boolean paused = !player.relativeTime || instance.paused || !this.advanceTime();
|
||||
+ return new ClockNetworkState(player.getPlayerTime(), instance.partialTick, paused ? 0.0F : instance.rate);
|
||||
+ }
|
||||
+ return instance.packNetworkState(this.advanceTime());
|
||||
+ }
|
||||
+
|
||||
+ private boolean advanceTime() {
|
||||
+ return this.level != null ? this.level.getGameRules().get(GameRules.ADVANCE_TIME) : this.server.getGlobalGameRules().get(GameRules.ADVANCE_TIME);
|
||||
+ }
|
||||
+ // Paper end - per-world time; per-player time
|
||||
|
||||
public boolean isAtTimeMarker(final Holder<WorldClock> clock, final ResourceKey<ClockTimeMarker> timeMarkerId) {
|
||||
ServerClockManager.ClockInstance clockInstance = this.getInstance(clock);
|
||||
@@ -171,8 +_,7 @@
|
||||
return new ClockState(this.totalTicks, this.partialTick, this.rate, this.paused);
|
||||
}
|
||||
|
||||
- public ClockNetworkState packNetworkState(final MinecraftServer server) {
|
||||
- boolean advanceTime = server.getGlobalGameRules().get(GameRules.ADVANCE_TIME);
|
||||
+ public ClockNetworkState packNetworkState(final boolean advanceTime) { // Paper - per-world time
|
||||
boolean paused = this.paused || !advanceTime;
|
||||
return new ClockNetworkState(this.totalTicks, this.partialTick, paused ? 0.0F : this.rate);
|
||||
}
|
||||
@@ -40,7 +40,7 @@
|
||||
+ // Paper start - Expand EntityUnleashEvent
|
||||
+ final org.bukkit.event.entity.EntityUnleashEvent event = new org.bukkit.event.entity.EntityUnleashEvent(
|
||||
+ entity.getBukkitEntity(),
|
||||
+ !entity.isAlive() ? org.bukkit.event.entity.EntityUnleashEvent.UnleashReason.PLAYER_UNLEASH : org.bukkit.event.entity.EntityUnleashEvent.UnleashReason.HOLDER_GONE,
|
||||
+ !entity.isAlive() ? org.bukkit.event.entity.EntityUnleashEvent.UnleashReason.LEASHED_GONE : org.bukkit.event.entity.EntityUnleashEvent.UnleashReason.HOLDER_GONE,
|
||||
+ level.getGameRules().get(GameRules.ENTITY_DROPS) && !entity.pluginRemoved
|
||||
+ );
|
||||
+ event.callEvent();
|
||||
|
||||
@@ -1053,7 +1053,7 @@
|
||||
int absorbValue = (this.getEffect(MobEffects.RESISTANCE).getAmplifier() + 1) * 5;
|
||||
int absorb = 25 - absorbValue;
|
||||
float v = damage * absorb;
|
||||
@@ -1915,24 +_,194 @@
|
||||
@@ -1915,24 +_,181 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1147,19 +1147,6 @@
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (source.getEntity() instanceof net.minecraft.world.entity.player.Player) {
|
||||
+ // Paper start - PlayerAttackEntityCooldownResetEvent
|
||||
+ //((net.minecraft.world.entity.player.Player) damagesource.getEntity()).resetOnlyAttackStrengthTicker(); // Moved from Player in order to make the cooldown reset get called after the damage event is fired
|
||||
+ if (source.getEntity() instanceof ServerPlayer player) {
|
||||
+ if (new com.destroystokyo.paper.event.player.PlayerAttackEntityCooldownResetEvent(player.getBukkitEntity(), this.getBukkitEntity(), player.getAttackStrengthScale(0F)).callEvent()) {
|
||||
+ player.resetOnlyAttackStrengthTicker();
|
||||
+ }
|
||||
+ } else {
|
||||
+ ((net.minecraft.world.entity.player.Player)source.getEntity()).resetOnlyAttackStrengthTicker();
|
||||
+ }
|
||||
+ // Paper end - PlayerAttackEntityCooldownResetEvent
|
||||
+ }
|
||||
+
|
||||
+ // Resistance
|
||||
+ if (event.getDamage(DamageModifier.RESISTANCE) < 0) {
|
||||
+ float damageResisted = (float)-event.getDamage(DamageModifier.RESISTANCE);
|
||||
@@ -1405,6 +1392,18 @@
|
||||
|
||||
profiler.pop();
|
||||
if (this.isFallFlying()) {
|
||||
@@ -2865,6 +_,11 @@
|
||||
}
|
||||
|
||||
public void onAttack() {
|
||||
+ // Paper start
|
||||
+ onAttack(null);
|
||||
+ }
|
||||
+ public void onAttack(Entity entity) {
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public void detectEquipmentUpdates() {
|
||||
@@ -2879,16 +_,39 @@
|
||||
|
||||
private @Nullable Map<EquipmentSlot, ItemStack> collectEquipmentChanges() {
|
||||
|
||||
@@ -240,8 +240,9 @@
|
||||
float attackStrengthScale = this.getAttackStrengthScale(0.5F);
|
||||
float magicBoost = attackStrengthScale * (this.getEnchantedDamage(entity, baseDamage, damageSource) - baseDamage);
|
||||
baseDamage *= this.baseDamageScaleFactor();
|
||||
this.onAttack();
|
||||
- this.onAttack();
|
||||
- if (!this.deflectProjectile(entity)) {
|
||||
+ this.onAttack(entity); // Paper
|
||||
+ final float dmgFinal = magicBoost; // Paper - damage events
|
||||
+ if (!this.deflectProjectile(entity, () -> !org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(entity, dmgSourceFinal, dmgFinal, false))) {
|
||||
if (baseDamage > 0.0F || magicBoost > 0.0F) {
|
||||
@@ -480,15 +481,27 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1808,10 +_,31 @@
|
||||
|
||||
@Override
|
||||
public void onAttack() {
|
||||
- this.resetOnlyAttackStrengthTicker();
|
||||
+ // this.resetOnlyAttackStrengthTicker(); // CraftBukkit - Moved to EntityLiving to reset the cooldown after the damage is dealt
|
||||
super.onAttack();
|
||||
@@ -1807,10 +_,39 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void onAttack() {
|
||||
- this.resetOnlyAttackStrengthTicker();
|
||||
- super.onAttack();
|
||||
- }
|
||||
+ // Paper start
|
||||
+ public void onAttack(@Nullable Entity entity) {
|
||||
+ if (entity != null) {
|
||||
+ if (new com.destroystokyo.paper.event.player.PlayerAttackEntityCooldownResetEvent((org.bukkit.entity.Player) this.getBukkitEntity(), entity.getBukkitEntity(), this.getAttackStrengthScale(0F)).callEvent()) {
|
||||
+ this.resetOnlyAttackStrengthTicker();
|
||||
+ }
|
||||
+ } else {
|
||||
+ this.resetOnlyAttackStrengthTicker();
|
||||
+ }
|
||||
+ super.onAttack(entity);
|
||||
+ // Paper end
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - Force update attributes.
|
||||
+ @Override
|
||||
+ public void detectEquipmentUpdates() {
|
||||
@@ -509,10 +522,9 @@
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Force update attributes.
|
||||
+
|
||||
|
||||
public void resetOnlyAttackStrengthTicker() {
|
||||
this.attackStrengthTicker = 0;
|
||||
}
|
||||
@@ -1843,17 +_,32 @@
|
||||
return ImmutableList.of(Pose.STANDING, Pose.CROUCHING, Pose.SWIMMING);
|
||||
}
|
||||
|
||||
+11
-2
@@ -84,14 +84,23 @@
|
||||
this.setDeltaMovement(this.getDeltaMovement().multiply(1.0, 0.0, 1.0));
|
||||
this.lastYd = 0.0;
|
||||
}
|
||||
@@ -704,12 +_,12 @@
|
||||
@@ -704,12 +_,20 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void remove(final Entity.RemovalReason reason) {
|
||||
+ public void remove(final Entity.RemovalReason reason, org.bukkit.event.entity.EntityRemoveEvent.@Nullable Cause eventCause) { // CraftBukkit - add Bukkit remove cause
|
||||
if (!this.level().isClientSide() && reason.shouldDestroy() && this.isLeashed()) {
|
||||
this.dropLeash();
|
||||
- this.dropLeash();
|
||||
+ // Paper start - Fire EntityUnleashEvent on boat destruction
|
||||
+ final org.bukkit.event.entity.EntityUnleashEvent event = new org.bukkit.event.entity.EntityUnleashEvent(this.getBukkitEntity(), org.bukkit.event.entity.EntityUnleashEvent.UnleashReason.LEASHED_GONE, true);
|
||||
+ event.callEvent();
|
||||
+ if (event.isDropLeash()) {
|
||||
+ this.dropLeash();
|
||||
+ } else {
|
||||
+ this.removeLeash();
|
||||
+ }
|
||||
+ // Paper end - Fire EntityUnleashEvent on boat destruction
|
||||
}
|
||||
|
||||
- super.remove(reason);
|
||||
|
||||
+8
-1
@@ -201,7 +201,7 @@
|
||||
player.handleCreativeModeItemDrop(itemStack);
|
||||
}
|
||||
}
|
||||
@@ -595,8 +_,9 @@
|
||||
@@ -595,14 +_,15 @@
|
||||
if (player instanceof ServerPlayer) {
|
||||
ItemStack carried = this.getCarried();
|
||||
if (!carried.isEmpty()) {
|
||||
@@ -212,6 +212,13 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void dropOrPlaceInInventory(final Player player, final ItemStack carried) {
|
||||
- boolean playerRemovedNotChangingDimension = player.isRemoved() && player.getRemovalReason() != Entity.RemovalReason.CHANGED_DIMENSION;
|
||||
+ boolean playerRemovedNotChangingDimension = !player.isAlive() && player.getRemovalReason() != Entity.RemovalReason.CHANGED_DIMENSION; // Paper - Make sure player is dead (https://github.com/PaperMC/Paper/pull/13002)
|
||||
boolean serverPlayerHasDisconnected = player instanceof ServerPlayer serverPlayer && serverPlayer.hasDisconnected();
|
||||
if (playerRemovedNotChangingDimension || serverPlayerHasDisconnected) {
|
||||
player.drop(carried, false);
|
||||
@@ -642,6 +_,14 @@
|
||||
public abstract boolean stillValid(Player player);
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
+ com.destroystokyo.paper.event.player.PlayerElytraBoostEvent event = new com.destroystokyo.paper.event.player.PlayerElytraBoostEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) delayed.projectile().getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand));
|
||||
+ if (event.callEvent() && delayed.attemptSpawn()) {
|
||||
+ player.awardStat(Stats.ITEM_USED.get(this)); // Moved up from below
|
||||
+ if (player.dropAllLeashConnections(null)) {
|
||||
+ if (player.dropAllLeashConnections(player, hand)) { // Paper - PlayerUnleashEntityEvent
|
||||
+ level.playSound(null, player, SoundEvents.LEAD_BREAK, SoundSource.NEUTRAL, 1.0F, 1.0F);
|
||||
+ }
|
||||
+ if (event.shouldConsume() && !player.hasInfiniteMaterials()) {
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
protected Level(
|
||||
final WritableLevelData levelData,
|
||||
final ResourceKey<Level> dimension,
|
||||
@@ -141,7 +_,24 @@
|
||||
@@ -141,7 +_,25 @@
|
||||
final boolean isDebug,
|
||||
final long biomeZoomSeed,
|
||||
final int maxChainedNeighborUpdates
|
||||
@@ -87,10 +87,11 @@
|
||||
+ java.util.function.Function<org.spigotmc.SpigotWorldConfig, // Spigot - create per world config
|
||||
+ io.papermc.paper.configuration.WorldConfiguration> paperWorldConfigCreator // Paper - create paper world config
|
||||
) {
|
||||
+ this.spigotConfig = new org.spigotmc.SpigotWorldConfig(bukkitName, CraftNamespacedKey.fromMinecraft(dimension.identifier())); // Spigot
|
||||
+ final org.bukkit.NamespacedKey worldKey = CraftNamespacedKey.fromMinecraft(dimension.identifier()); // Paper
|
||||
+ this.spigotConfig = new org.spigotmc.SpigotWorldConfig(bukkitName, worldKey); // Spigot
|
||||
+ this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config
|
||||
+ this.generator = generator;
|
||||
+ this.world = new CraftWorld((ServerLevel) this, dimension.identifier(), biomeProvider, environment);
|
||||
+ this.world = new CraftWorld((ServerLevel) this, worldKey, biomeProvider, environment);
|
||||
+
|
||||
+ for (SpawnCategory spawnCategory : SpawnCategory.values()) {
|
||||
+ if (org.bukkit.craftbukkit.util.CraftSpawnCategory.isValidForLimits(spawnCategory)) {
|
||||
@@ -445,7 +446,15 @@
|
||||
return chunk.getBlockState(pos);
|
||||
}
|
||||
}
|
||||
@@ -533,31 +_,48 @@
|
||||
@@ -523,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void addBlockEntityTicker(final TickingBlockEntity ticker) {
|
||||
+ if (!this.paperConfig().unsupportedSettings.ticking.blockEntities) return; // Paper - option to disable ticking
|
||||
(this.tickingBlockEntities ? this.pendingBlockEntityTickers : this.blockEntityTickers).add(ticker);
|
||||
}
|
||||
|
||||
@@ -533,18 +_,23 @@
|
||||
this.pendingBlockEntityTickers.clear();
|
||||
}
|
||||
|
||||
@@ -471,10 +480,9 @@
|
||||
|
||||
+ this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075 use removeAll
|
||||
this.tickingBlockEntities = false;
|
||||
+ this.spigotConfig.currentPrimedTnt = 0; // Spigot
|
||||
}
|
||||
|
||||
public <T extends Entity> void guardEntityTick(final Consumer<T> tick, final T entity) {
|
||||
@@ -552,12 +_,23 @@
|
||||
try {
|
||||
tick.accept(entity);
|
||||
} catch (Throwable var6) {
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
--- a/net/minecraft/world/level/block/AbstractSkullBlock.java
|
||||
+++ b/net/minecraft/world/level/block/AbstractSkullBlock.java
|
||||
@@ -76,6 +_,11 @@
|
||||
if (!level.isClientSide()) {
|
||||
boolean signal = level.hasNeighborSignal(pos);
|
||||
if (signal != state.getValue(POWERED)) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, signal)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(POWERED, signal), Block.UPDATE_CLIENTS);
|
||||
}
|
||||
}
|
||||
+7
-7
@@ -13,15 +13,15 @@
|
||||
boolean wasPressed = oldSignal > 0;
|
||||
boolean isPressed = signal > 0;
|
||||
+
|
||||
+ // CraftBukkit start - Interact Pressure Plate
|
||||
+ if (wasPressed != isPressed) {
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), oldSignal, signal);
|
||||
+ eventRedstone.callEvent();
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (oldSignal != signal) {
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, oldSignal, signal);
|
||||
+
|
||||
+ isPressed = eventRedstone.getNewCurrent() > 0;
|
||||
+ signal = eventRedstone.getNewCurrent();
|
||||
+ signal = event.getNewCurrent();
|
||||
+ isPressed = signal > 0;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
+
|
||||
if (oldSignal != signal) {
|
||||
BlockState newState = this.setSignalForState(state, signal);
|
||||
level.setBlock(pos, newState, Block.UPDATE_CLIENTS);
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
--- a/net/minecraft/world/level/block/BellBlock.java
|
||||
+++ b/net/minecraft/world/level/block/BellBlock.java
|
||||
@@ -73,6 +_,11 @@
|
||||
) {
|
||||
boolean signal = level.hasNeighborSignal(pos);
|
||||
if (signal != state.getValue(POWERED)) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, signal)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
if (signal) {
|
||||
this.attemptToRing(level, pos, null);
|
||||
}
|
||||
@@ -143,6 +_,11 @@
|
||||
direction = level.getBlockState(pos).getValue(FACING);
|
||||
}
|
||||
|
||||
+19
-27
@@ -1,25 +1,27 @@
|
||||
--- a/net/minecraft/world/level/block/ButtonBlock.java
|
||||
+++ b/net/minecraft/world/level/block/ButtonBlock.java
|
||||
@@ -92,6 +_,19 @@
|
||||
@@ -92,6 +_,11 @@
|
||||
if (state.getValue(POWERED)) {
|
||||
return InteractionResult.CONSUME;
|
||||
} else {
|
||||
+ // CraftBukkit start
|
||||
+ boolean powered = state.getValue(ButtonBlock.POWERED);
|
||||
+ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
|
||||
+ int old = (powered) ? 15 : 0;
|
||||
+ int current = (!powered) ? 15 : 0;
|
||||
+
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(block, old, current);
|
||||
+ level.getCraftServer().getPluginManager().callEvent(eventRedstone);
|
||||
+
|
||||
+ if ((eventRedstone.getNewCurrent() > 0) != (!powered)) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, true)) {
|
||||
+ return InteractionResult.SUCCESS;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
this.press(state, level, pos, player);
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
@@ -102,7 +_,9 @@
|
||||
final BlockState state, final ServerLevel level, final BlockPos pos, final Explosion explosion, final BiConsumer<ItemStack, BlockPos> onHit
|
||||
) {
|
||||
if (explosion.canTriggerBlocks() && !state.getValue(POWERED)) {
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, true)) { // Paper - Call BlockRedstoneEvent
|
||||
this.press(state, level, pos, null);
|
||||
+ } // Paper - Call BlockRedstoneEvent
|
||||
}
|
||||
|
||||
super.onExplosionHit(state, level, pos, explosion, onHit);
|
||||
@@ -162,6 +_,7 @@
|
||||
final InsideBlockEffectApplier effectApplier,
|
||||
final boolean isPrecise
|
||||
@@ -28,7 +30,7 @@
|
||||
if (!level.isClientSide() && this.type.canButtonBeActivatedByArrows() && !state.getValue(POWERED)) {
|
||||
this.checkPressed(state, level, pos);
|
||||
}
|
||||
@@ -173,7 +_,31 @@
|
||||
@@ -173,7 +_,21 @@
|
||||
: null;
|
||||
boolean shouldBePressed = firstArrow != null;
|
||||
boolean wasPressed = state.getValue(POWERED);
|
||||
@@ -36,27 +38,17 @@
|
||||
+ if (wasPressed != shouldBePressed && shouldBePressed) {
|
||||
+ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
|
||||
+ org.bukkit.event.entity.EntityInteractEvent event = new org.bukkit.event.entity.EntityInteractEvent(firstArrow.getBukkitEntity(), block);
|
||||
+ level.getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ if (!event.callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
if (shouldBePressed != wasPressed) {
|
||||
+ // CraftBukkit start
|
||||
+ boolean powered = wasPressed;
|
||||
+ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
|
||||
+ int old = (powered) ? 15 : 0;
|
||||
+ int current = (!powered) ? 15 : 0;
|
||||
+
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(block, old, current);
|
||||
+ level.getCraftServer().getPluginManager().callEvent(eventRedstone);
|
||||
+
|
||||
+ if ((shouldBePressed && eventRedstone.getNewCurrent() <= 0) || (!shouldBePressed && eventRedstone.getNewCurrent() > 0)) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, shouldBePressed)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(POWERED, shouldBePressed), Block.UPDATE_ALL);
|
||||
this.updateNeighbours(state, level, pos);
|
||||
this.playSound(null, level, pos, shouldBePressed);
|
||||
+7
-10
@@ -1,24 +1,21 @@
|
||||
--- a/net/minecraft/world/level/block/CommandBlock.java
|
||||
+++ b/net/minecraft/world/level/block/CommandBlock.java
|
||||
@@ -69,8 +_,17 @@
|
||||
@@ -69,9 +_,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
- private void setPoweredAndUpdate(final Level level, final BlockPos pos, final CommandBlockEntity commandBlock, final boolean isPowered) {
|
||||
+ private void setPoweredAndUpdate(final Level level, final BlockPos pos, final CommandBlockEntity commandBlock, boolean isPowered) { // Paper - remove final from isPowered
|
||||
boolean wasPowered = commandBlock.isPowered();
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
|
||||
+ int old = wasPowered ? 15 : 0;
|
||||
+ int current = isPowered ? 15 : 0;
|
||||
+
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(bukkitBlock, old, current);
|
||||
+ level.getCraftServer().getPluginManager().callEvent(eventRedstone);
|
||||
+ isPowered = eventRedstone.getNewCurrent() > 0;
|
||||
+ // CraftBukkit end
|
||||
if (isPowered != wasPowered) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, isPowered)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
commandBlock.setPowered(isPowered);
|
||||
if (isPowered) {
|
||||
if (commandBlock.isAutomatic() || commandBlock.getMode() == CommandBlockEntity.Mode.SEQUENCE) {
|
||||
@@ -129,7 +_,7 @@
|
||||
final BlockState state, final Level level, final BlockPos pos, final Player player, final BlockHitResult hitResult
|
||||
) {
|
||||
|
||||
+6
-6
@@ -13,18 +13,18 @@
|
||||
boolean sourceOn = this.shouldTurnOn(level, pos, state);
|
||||
boolean isOn = state.getValue(POWERED);
|
||||
if (isOn && !sourceOn) {
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 15, 0).getNewCurrent() != 0) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, false)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(POWERED, false), Block.UPDATE_CLIENTS);
|
||||
} else if (!isOn && sourceOn) {
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 0, 15).getNewCurrent() != 15) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, true)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(POWERED, true), Block.UPDATE_CLIENTS);
|
||||
}
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
--- a/net/minecraft/world/level/block/CopperBulbBlock.java
|
||||
+++ b/net/minecraft/world/level/block/CopperBulbBlock.java
|
||||
@@ -49,6 +_,11 @@
|
||||
public void checkAndFlip(final BlockState state, final ServerLevel level, final BlockPos pos) {
|
||||
boolean signal = level.hasNeighborSignal(pos);
|
||||
if (signal != state.getValue(POWERED)) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, signal)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
BlockState newState = state;
|
||||
if (!state.getValue(POWERED)) {
|
||||
newState = state.cycle(LIT);
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
target = Mth.clamp(target, 0, 15);
|
||||
if (state.getValue(POWER) != target) {
|
||||
+ target = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, state.getValue(DaylightDetectorBlock.POWER), target).getNewCurrent(); // CraftBukkit - Call BlockRedstoneEvent
|
||||
+ target = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, state.getValue(POWER), target).getNewCurrent(); // Paper - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(POWER, target), Block.UPDATE_ALL);
|
||||
}
|
||||
}
|
||||
+9
-12
@@ -8,7 +8,7 @@
|
||||
if (!level.isClientSide()) {
|
||||
if (!state.getValue(POWERED)) {
|
||||
this.checkPressed(level, pos, state);
|
||||
@@ -87,6 +_,7 @@
|
||||
@@ -87,12 +_,21 @@
|
||||
|
||||
private void checkPressed(final Level level, final BlockPos pos, final BlockState state) {
|
||||
if (this.canSurvive(state, level, pos)) {
|
||||
@@ -16,20 +16,17 @@
|
||||
boolean wasPressed = state.getValue(POWERED);
|
||||
boolean shouldBePressed = false;
|
||||
List<AbstractMinecart> entities = this.getInteractingMinecartOfType(level, pos, AbstractMinecart.class, e -> true);
|
||||
@@ -94,6 +_,16 @@
|
||||
if (!entities.isEmpty()) {
|
||||
shouldBePressed = true;
|
||||
}
|
||||
|
||||
+ // CraftBukkit start
|
||||
+
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (wasPressed != shouldBePressed) {
|
||||
+ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
|
||||
+
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(block, shouldBePressed ? 15 : 0, shouldBePressed ? 15 : 0);
|
||||
+ level.getCraftServer().getPluginManager().callEvent(eventRedstone);
|
||||
+
|
||||
+ shouldBePressed = eventRedstone.getNewCurrent() > 0;
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, shouldBePressed)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
|
||||
if (shouldBePressed && !wasPressed) {
|
||||
BlockState newState = state.setValue(POWERED, true);
|
||||
level.setBlock(pos, newState, Block.UPDATE_ALL);
|
||||
@@ -4,18 +4,18 @@
|
||||
boolean on = state.getValue(POWERED);
|
||||
boolean shouldTurnOn = this.shouldTurnOn(level, pos, state);
|
||||
if (on && !shouldTurnOn) {
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 15, 0).getNewCurrent() != 0) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, false)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(POWERED, false), Block.UPDATE_CLIENTS);
|
||||
} else if (!on) {
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 0, 15).getNewCurrent() != 15) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, true)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(POWERED, true), Block.UPDATE_CLIENTS);
|
||||
if (!shouldTurnOn) {
|
||||
level.scheduleTick(pos, this, this.getDelay(state), TickPriority.VERY_HIGH);
|
||||
|
||||
@@ -1,28 +1,14 @@
|
||||
--- a/net/minecraft/world/level/block/DoorBlock.java
|
||||
+++ b/net/minecraft/world/level/block/DoorBlock.java
|
||||
@@ -225,9 +_,22 @@
|
||||
protected void neighborChanged(
|
||||
final BlockState state, final Level level, final BlockPos pos, final Block block, final @Nullable Orientation orientation, final boolean movedByPiston
|
||||
) {
|
||||
- boolean signal = level.hasNeighborSignal(pos)
|
||||
- || level.hasNeighborSignal(pos.relative(state.getValue(HALF) == DoubleBlockHalf.LOWER ? Direction.UP : Direction.DOWN));
|
||||
- if (!this.defaultBlockState().is(block) && signal != state.getValue(POWERED)) {
|
||||
+ // CraftBukkit start
|
||||
+ BlockPos otherHalf = pos.relative(state.getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER ? Direction.UP : Direction.DOWN);
|
||||
+ org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
|
||||
+ org.bukkit.block.Block blockTop = org.bukkit.craftbukkit.block.CraftBlock.at(level, otherHalf);
|
||||
+
|
||||
+ int power = bukkitBlock.getBlockPower();
|
||||
+ int powerTop = blockTop.getBlockPower();
|
||||
+ if (powerTop > power) power = powerTop;
|
||||
+ int oldPower = state.getValue(DoorBlock.POWERED) ? net.minecraft.world.level.redstone.Redstone.SIGNAL_MAX : net.minecraft.world.level.redstone.Redstone.SIGNAL_MIN;
|
||||
+
|
||||
+ if (oldPower == 0 ^ power == 0) {
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent event = new org.bukkit.event.block.BlockRedstoneEvent(bukkitBlock, oldPower, power);
|
||||
+ event.callEvent();
|
||||
+
|
||||
+ boolean signal = event.getNewCurrent() > 0;
|
||||
+ // CraftBukkit end
|
||||
@@ -228,6 +_,11 @@
|
||||
boolean signal = level.hasNeighborSignal(pos)
|
||||
|| level.hasNeighborSignal(pos.relative(state.getValue(HALF) == DoubleBlockHalf.LOWER ? Direction.UP : Direction.DOWN));
|
||||
if (!this.defaultBlockState().is(block) && signal != state.getValue(POWERED)) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, signal)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
if (signal != state.getValue(OPEN)) {
|
||||
this.playSound(null, level, pos, signal);
|
||||
level.gameEvent(null, signal ? GameEvent.BLOCK_OPEN : GameEvent.BLOCK_CLOSE, pos);
|
||||
+7
-13
@@ -1,20 +1,14 @@
|
||||
--- a/net/minecraft/world/level/block/FenceGateBlock.java
|
||||
+++ b/net/minecraft/world/level/block/FenceGateBlock.java
|
||||
@@ -188,6 +_,17 @@
|
||||
) {
|
||||
@@ -189,6 +_,11 @@
|
||||
if (!level.isClientSide()) {
|
||||
boolean hasPower = level.hasNeighborSignal(pos);
|
||||
+ // CraftBukkit start
|
||||
+ boolean oldPowered = state.getValue(FenceGateBlock.POWERED);
|
||||
+ if (oldPowered != hasPower) {
|
||||
+ int newPower = hasPower ? 15 : 0;
|
||||
+ int oldPower = oldPowered ? 15 : 0;
|
||||
+ org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(bukkitBlock, oldPower, newPower);
|
||||
+ level.getCraftServer().getPluginManager().callEvent(eventRedstone);
|
||||
+ hasPower = eventRedstone.getNewCurrent() > 0;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
if (state.getValue(POWERED) != hasPower) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, hasPower)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(POWERED, hasPower).setValue(OPEN, hasPower), Block.UPDATE_CLIENTS);
|
||||
if (state.getValue(OPEN) != hasPower) {
|
||||
level.playSound(
|
||||
+5
-8
@@ -26,20 +26,17 @@
|
||||
resetBookState(sourceEntity, level, pos, state, true);
|
||||
level.playSound(null, pos, SoundEvents.BOOK_PUT, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
}
|
||||
@@ -162,6 +_,16 @@
|
||||
@@ -162,6 +_,13 @@
|
||||
}
|
||||
|
||||
private static void changePowered(final Level level, final BlockPos pos, final BlockState state, final boolean isPowered) {
|
||||
+ // Paper start - Call BlockRedstoneEvent properly
|
||||
+ final int currentRedstoneLevel = state.getValue(LecternBlock.POWERED) ? 15 : 0, targetRedstoneLevel = isPowered ? 15 : 0;
|
||||
+ if (currentRedstoneLevel != targetRedstoneLevel) {
|
||||
+ final org.bukkit.event.block.BlockRedstoneEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, currentRedstoneLevel, targetRedstoneLevel);
|
||||
+
|
||||
+ if (event.getNewCurrent() != targetRedstoneLevel) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (state.getValue(POWERED) != isPowered) {
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, isPowered)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Call BlockRedstoneEvent properly
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(POWERED, isPowered), Block.UPDATE_ALL);
|
||||
updateBelow(level, pos, state);
|
||||
}
|
||||
|
||||
+18
-12
@@ -1,22 +1,28 @@
|
||||
--- a/net/minecraft/world/level/block/LeverBlock.java
|
||||
+++ b/net/minecraft/world/level/block/LeverBlock.java
|
||||
@@ -70,6 +_,19 @@
|
||||
@@ -70,6 +_,12 @@
|
||||
makeParticle(stateAfter, level, pos, 1.0F);
|
||||
}
|
||||
} else {
|
||||
+ // CraftBukkit start - Interact Lever
|
||||
+ boolean powered = stateBefore.getValue(LeverBlock.POWERED); // Old powered state
|
||||
+ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
|
||||
+ int old = (powered) ? 15 : 0;
|
||||
+ int current = (!powered) ? 15 : 0;
|
||||
+
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(block, old, current);
|
||||
+ level.getCraftServer().getPluginManager().callEvent(eventRedstone);
|
||||
+
|
||||
+ if ((eventRedstone.getNewCurrent() > 0) != (!powered)) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ boolean wasPowered = stateBefore.getValue(POWERED);
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, !wasPowered)) {
|
||||
+ return InteractionResult.SUCCESS;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
this.pull(stateBefore, level, pos, null);
|
||||
}
|
||||
|
||||
@@ -81,7 +_,12 @@
|
||||
final BlockState state, final ServerLevel level, final BlockPos pos, final Explosion explosion, final BiConsumer<ItemStack, BlockPos> onHit
|
||||
) {
|
||||
if (explosion.canTriggerBlocks()) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ boolean wasPowered = state.getValue(POWERED);
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, !wasPowered)) {
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
this.pull(state, level, pos, null);
|
||||
+ } // Paper - Call BlockRedstoneEvent
|
||||
}
|
||||
|
||||
super.onExplosionHit(state, level, pos, explosion, onHit);
|
||||
+21
-12
@@ -1,21 +1,30 @@
|
||||
--- a/net/minecraft/world/level/block/LightningRodBlock.java
|
||||
+++ b/net/minecraft/world/level/block/LightningRodBlock.java
|
||||
@@ -83,6 +_,18 @@
|
||||
@@ -83,6 +_,13 @@
|
||||
}
|
||||
|
||||
public void onLightningStrike(final BlockState state, final Level level, final BlockPos pos) {
|
||||
+ // CraftBukkit start
|
||||
+ boolean powered = state.getValue(LightningRodBlock.POWERED);
|
||||
+ int old = (powered) ? 15 : 0;
|
||||
+ int current = (!powered) ? 15 : 0;
|
||||
+
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), old, current);
|
||||
+ level.getCraftServer().getPluginManager().callEvent(eventRedstone);
|
||||
+
|
||||
+ if (eventRedstone.getNewCurrent() <= 0) {
|
||||
+ return;
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!state.getValue(POWERED)) {
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, true)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(POWERED, true), Block.UPDATE_ALL);
|
||||
this.updateNeighbours(state, level, pos);
|
||||
level.scheduleTick(pos, this, 8);
|
||||
@@ -96,6 +_,13 @@
|
||||
|
||||
@Override
|
||||
protected void tick(final BlockState state, final ServerLevel level, final BlockPos pos, final RandomSource random) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (state.getValue(POWERED)) {
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, false)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(POWERED, false), Block.UPDATE_ALL);
|
||||
this.updateNeighbours(state, level, pos);
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
boolean neighborDirectionSetsInstrument = directionToNeighbour.getAxis() == Direction.Axis.Y;
|
||||
return neighborDirectionSetsInstrument
|
||||
? this.setInstrument(level, pos, state)
|
||||
@@ -86,12 +_,14 @@
|
||||
@@ -86,12 +_,19 @@
|
||||
|
||||
@Override
|
||||
protected void neighborChanged(
|
||||
@@ -26,6 +26,11 @@
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return; // Paper - prevent noteblock powered-state from updating
|
||||
boolean signal = level.hasNeighborSignal(pos);
|
||||
if (signal != state.getValue(POWERED)) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, signal)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
if (signal) {
|
||||
this.playNote(null, state, level, pos);
|
||||
+ state = level.getBlockState(pos); // CraftBukkit - SPIGOT-5617: update in case changed in event
|
||||
|
||||
+6
-6
@@ -4,18 +4,18 @@
|
||||
@Override
|
||||
protected void tick(final BlockState state, final ServerLevel level, final BlockPos pos, final RandomSource random) {
|
||||
if (state.getValue(POWERED)) {
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 15, 0).getNewCurrent() != 0) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, false)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(POWERED, false), Block.UPDATE_CLIENTS);
|
||||
} else {
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 0, 15).getNewCurrent() != 15) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, true)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(POWERED, true), Block.UPDATE_CLIENTS);
|
||||
level.scheduleTick(pos, this, 2);
|
||||
}
|
||||
+4
-6
@@ -1,16 +1,14 @@
|
||||
--- a/net/minecraft/world/level/block/PoweredRailBlock.java
|
||||
+++ b/net/minecraft/world/level/block/PoweredRailBlock.java
|
||||
@@ -127,6 +_,13 @@
|
||||
@@ -127,6 +_,11 @@
|
||||
|| this.findPoweredRailSignal(level, pos, state, true, 0)
|
||||
|| this.findPoweredRailSignal(level, pos, state, false, 0);
|
||||
if (shouldPower != isPowered) {
|
||||
+ // CraftBukkit start
|
||||
+ int power = shouldPower ? 15 : 0;
|
||||
+ int newPower = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, power, 15 - power).getNewCurrent();
|
||||
+ if (newPower == power) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, shouldPower)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(POWERED, shouldPower), Block.UPDATE_ALL);
|
||||
level.updateNeighborsAt(pos.below(), this);
|
||||
if (state.getValue(SHAPE).isSlope()) {
|
||||
+6
-6
@@ -4,11 +4,11 @@
|
||||
if (isLit) {
|
||||
level.scheduleTick(pos, this, 4);
|
||||
} else {
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 0, 15).getNewCurrent() != 15) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, true)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.cycle(LIT), Block.UPDATE_CLIENTS);
|
||||
}
|
||||
}
|
||||
@@ -16,11 +16,11 @@
|
||||
@Override
|
||||
protected void tick(final BlockState state, final ServerLevel level, final BlockPos pos, final RandomSource random) {
|
||||
if (state.getValue(LIT) && !level.hasNeighborSignal(pos)) {
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 15, 0).getNewCurrent() != 0) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, false)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.cycle(LIT), Block.UPDATE_CLIENTS);
|
||||
}
|
||||
}
|
||||
+10
-23
@@ -9,7 +9,7 @@
|
||||
public static final int RECENT_TOGGLE_TIMER = 60;
|
||||
public static final int MAX_RECENT_TOGGLES = 8;
|
||||
public static final int RESTART_DELAY = 160;
|
||||
@@ -73,14 +_,32 @@
|
||||
@@ -73,14 +_,23 @@
|
||||
@Override
|
||||
protected void tick(final BlockState state, final ServerLevel level, final BlockPos pos, final RandomSource random) {
|
||||
boolean neighborSignal = this.hasNeighborSignal(level, pos, state);
|
||||
@@ -26,39 +26,26 @@
|
||||
+ }
|
||||
}
|
||||
+ // Paper end - Faster redstone torch rapid clock removal
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
|
||||
+ int oldCurrent = state.getValue(LIT) ? 15 : 0;
|
||||
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent event = new org.bukkit.event.block.BlockRedstoneEvent(block, oldCurrent, oldCurrent);
|
||||
+ // CraftBukkit end
|
||||
if (state.getValue(LIT)) {
|
||||
if (neighborSignal) {
|
||||
+ // CraftBukkit start
|
||||
+ if (oldCurrent != 0) {
|
||||
+ event.setNewCurrent(0);
|
||||
+ event.callEvent();
|
||||
+ if (event.getNewCurrent() != 0) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, false)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(LIT, false), Block.UPDATE_ALL);
|
||||
if (isToggledTooFrequently(level, pos, true)) {
|
||||
level.levelEvent(LevelEvent.REDSTONE_TORCH_BURNOUT, pos, 0);
|
||||
@@ -88,6 +_,15 @@
|
||||
@@ -88,6 +_,11 @@
|
||||
}
|
||||
}
|
||||
} else if (!neighborSignal && !isToggledTooFrequently(level, pos, false)) {
|
||||
+ // CraftBukkit start
|
||||
+ if (oldCurrent != 15) {
|
||||
+ event.setNewCurrent(15);
|
||||
+ event.callEvent();
|
||||
+ if (event.getNewCurrent() != 15) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, true)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(LIT, true), Block.UPDATE_ALL);
|
||||
}
|
||||
}
|
||||
|
||||
+12
-17
@@ -19,7 +19,7 @@
|
||||
sculkSensor.getListener().forceScheduleVibration(serverLevel, GameEvent.STEP, GameEvent.Context.of(entity), entity.position());
|
||||
}
|
||||
|
||||
@@ -189,10 +_,19 @@
|
||||
@@ -189,10 +_,17 @@
|
||||
}
|
||||
|
||||
public static boolean canActivate(final BlockState state) {
|
||||
@@ -28,35 +28,30 @@
|
||||
}
|
||||
|
||||
public static void deactivate(final Level level, final BlockPos pos, final BlockState state) {
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), state.getValue(SculkSensorBlock.POWER), 0);
|
||||
+ level.getCraftServer().getPluginManager().callEvent(eventRedstone);
|
||||
+
|
||||
+ if (eventRedstone.getNewCurrent() > 0) {
|
||||
+ level.setBlock(pos, state.setValue(SculkSensorBlock.POWER, eventRedstone.getNewCurrent()), Block.UPDATE_ALL);
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ int newCurrent = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, state.getValue(POWER), 0).getNewCurrent();
|
||||
+ if (newCurrent > 0) {
|
||||
+ level.setBlock(pos, state.setValue(POWER, newCurrent), Block.UPDATE_ALL);
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(PHASE, SculkSensorPhase.COOLDOWN).setValue(POWER, 0), Block.UPDATE_ALL);
|
||||
level.scheduleTick(pos, state.getBlock(), 10);
|
||||
updateNeighbours(level, pos, state);
|
||||
@@ -208,9 +_,18 @@
|
||||
@@ -208,9 +_,15 @@
|
||||
final Level level,
|
||||
final BlockPos pos,
|
||||
final BlockState state,
|
||||
- final int calculatedPower,
|
||||
+ int calculatedPower, // CraftBukkit
|
||||
+ int calculatedPower, // Paper - remove final
|
||||
final int vibrationFrequency
|
||||
) {
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), state.getValue(SculkSensorBlock.POWER), calculatedPower);
|
||||
+ level.getCraftServer().getPluginManager().callEvent(eventRedstone);
|
||||
+
|
||||
+ if (eventRedstone.getNewCurrent() <= 0) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ calculatedPower = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, state.getValue(POWER), calculatedPower).getNewCurrent();
|
||||
+ if (calculatedPower == 0) {
|
||||
+ return;
|
||||
+ }
|
||||
+ calculatedPower = eventRedstone.getNewCurrent();
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(PHASE, SculkSensorPhase.ACTIVE).setValue(POWER, calculatedPower), Block.UPDATE_ALL);
|
||||
level.scheduleTick(pos, state.getBlock(), this.getActiveTicks());
|
||||
updateNeighbours(level, pos, state);
|
||||
|
||||
+30
-3
@@ -11,7 +11,7 @@
|
||||
if (projectile.getOwner() instanceof ServerPlayer playerOwner) {
|
||||
playerOwner.awardStat(Stats.TARGET_HIT);
|
||||
CriteriaTriggers.TARGET_BLOCK_HIT.trigger(playerOwner, projectile, hitResult.getLocation(), outputStrength);
|
||||
@@ -51,9 +_,29 @@
|
||||
@@ -51,10 +_,29 @@
|
||||
private static int updateRedstoneOutput(final LevelAccessor level, final BlockState state, final BlockHitResult hitResult, final Entity entity) {
|
||||
int redstoneStrength = getRedstoneStrength(hitResult, hitResult.getLocation());
|
||||
int duration = entity instanceof AbstractArrow ? 20 : 8;
|
||||
@@ -32,12 +32,39 @@
|
||||
if (!level.getBlockTicks().hasScheduledTick(hitResult.getBlockPos(), state.getBlock())) {
|
||||
setOutputPower(level, state, redstoneStrength, hitResult.getBlockPos(), duration);
|
||||
}
|
||||
+
|
||||
|
||||
+ // Paper start - Award Hit Criteria after Block Update
|
||||
+ if (shouldAward) {
|
||||
+ awardTargetHitCriteria((Projectile) entity, hitResult, redstoneStrength);
|
||||
+ }
|
||||
+ // Paper end - Award Hit Criteria after Block Update
|
||||
|
||||
return redstoneStrength;
|
||||
}
|
||||
|
||||
@@ -76,7 +_,12 @@
|
||||
return Math.max(1, Mth.ceil(15.0 * Mth.clamp((0.5 - distance) / 0.5, 0.0, 1.0)));
|
||||
}
|
||||
|
||||
- private static void setOutputPower(final LevelAccessor level, final BlockState state, final int outputStrength, final BlockPos pos, final int duration) {
|
||||
+ private static void setOutputPower(final LevelAccessor level, final BlockState state, int outputStrength, final BlockPos pos, final int duration) { // Paper - remove final
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (state.getValue(OUTPUT_POWER) != outputStrength) {
|
||||
+ outputStrength = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, state.getValue(OUTPUT_POWER), outputStrength).getNewCurrent();
|
||||
+ }
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(OUTPUT_POWER, outputStrength), Block.UPDATE_ALL);
|
||||
level.scheduleTick(pos, state.getBlock(), duration);
|
||||
}
|
||||
@@ -84,6 +_,12 @@
|
||||
@Override
|
||||
protected void tick(final BlockState state, final ServerLevel level, final BlockPos pos, final RandomSource random) {
|
||||
if (state.getValue(OUTPUT_POWER) != 0) {
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, state.getValue(OUTPUT_POWER), 0);
|
||||
+ if (event.getNewCurrent() > 0) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
level.setBlock(pos, state.setValue(OUTPUT_POWER, 0), Block.UPDATE_ALL);
|
||||
}
|
||||
}
|
||||
+6
-12
@@ -1,21 +1,15 @@
|
||||
--- a/net/minecraft/world/level/block/TrapDoorBlock.java
|
||||
+++ b/net/minecraft/world/level/block/TrapDoorBlock.java
|
||||
@@ -133,7 +_,37 @@
|
||||
@@ -133,7 +_,31 @@
|
||||
if (!level.isClientSide()) {
|
||||
boolean signal = level.hasNeighborSignal(pos);
|
||||
if (signal != state.getValue(POWERED)) {
|
||||
- if (state.getValue(OPEN) != signal) {
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.block.Block bblock = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
|
||||
+ int power = bblock.getBlockPower();
|
||||
+ int oldPower = state.getValue(TrapDoorBlock.OPEN) ? 15 : 0;
|
||||
+
|
||||
+ if (oldPower == 0 ^ power == 0 || block.defaultBlockState().isSignalSource()) {
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(bblock, oldPower, power);
|
||||
+ level.getCraftServer().getPluginManager().callEvent(eventRedstone);
|
||||
+ signal = eventRedstone.getNewCurrent() > 0;
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, signal)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
+ // Paper start - break redstone on trapdoors early
|
||||
+ boolean open = state.getValue(TrapDoorBlock.OPEN) != signal;
|
||||
+ // note: this must run before any state for this block/its neighbours are written to the world
|
||||
@@ -26,7 +20,7 @@
|
||||
+ BlockState above = level.getBlockState(abovePos);
|
||||
+ if (above.getBlock() instanceof RedStoneWireBlock) {
|
||||
+ level.setBlock(abovePos, Blocks.AIR.defaultBlockState(), Block.UPDATE_CLIENTS | Block.UPDATE_NEIGHBORS);
|
||||
+ Block.popResource(level, abovePos, new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.REDSTONE));
|
||||
+ Block.popResource(level, abovePos, new ItemStack(net.minecraft.world.item.Items.REDSTONE));
|
||||
+ // now check that this didn't change our state
|
||||
+ if (level.getBlockState(pos) != state) {
|
||||
+ // our state was changed, so we cannot propagate this update
|
||||
|
||||
+4
-14
@@ -13,7 +13,7 @@
|
||||
int receiverPos = 0;
|
||||
BlockState[] wireStates = new BlockState[42];
|
||||
|
||||
@@ -158,8 +_,20 @@
|
||||
@@ -158,8 +_,15 @@
|
||||
attached &= receiverPos > 1;
|
||||
powered &= attached;
|
||||
BlockState newState = block.defaultBlockState().trySetValue(ATTACHED, attached).trySetValue(POWERED, powered);
|
||||
@@ -22,19 +22,14 @@
|
||||
BlockPos testPosx = pos.relative(direction, receiverPos);
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (wasPowered != powered) {
|
||||
+ int newCurrent = powered ? 15 : 0;
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent event = new org.bukkit.event.block.BlockRedstoneEvent(
|
||||
+ org.bukkit.craftbukkit.block.CraftBlock.at(level, testPosx), wasPowered ? 15 : 0, newCurrent
|
||||
+ );
|
||||
+ event.callEvent();
|
||||
+ cancelledReceiverHook = event.getNewCurrent() != newCurrent;
|
||||
+ cancelledReceiverHook = !org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, testPosx, powered);
|
||||
+ }
|
||||
+ if (!cancelledReceiverHook) { // always trigger two events even when the first hook current change is cancelled
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
Direction opposite = direction.getOpposite();
|
||||
level.setBlock(testPosx, newState.setValue(FACING, opposite), Block.UPDATE_ALL);
|
||||
notifyNeighbors(block, level, testPosx, opposite);
|
||||
@@ -169,15 +_,29 @@
|
||||
@@ -169,15 +_,24 @@
|
||||
}
|
||||
|
||||
emitState(level, testPosx, attached, powered, wasAttached, wasPowered);
|
||||
@@ -43,12 +38,7 @@
|
||||
+ }
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (wasPowered != powered) {
|
||||
+ int newCurrent = powered ? 15 : 0;
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent event = new org.bukkit.event.block.BlockRedstoneEvent(
|
||||
+ org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), wasPowered ? 15 : 0, newCurrent
|
||||
+ );
|
||||
+ event.callEvent();
|
||||
+ cancelledEmitterHook = event.getNewCurrent() != newCurrent;
|
||||
+ cancelledEmitterHook = !org.bukkit.craftbukkit.event.CraftEventFactory.callBinaryRedstoneChange(level, pos, powered);
|
||||
+ }
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
|
||||
|
||||
+22
-23
@@ -21,22 +21,21 @@
|
||||
|
||||
protected abstract void onOpen(final Level level, final BlockPos pos, final BlockState blockState);
|
||||
|
||||
@@ -28,7 +_,19 @@
|
||||
public void incrementOpeners(
|
||||
@@ -29,6 +_,18 @@
|
||||
final LivingEntity entity, final Level level, final BlockPos pos, final BlockState blockState, final double maxInteractionRange
|
||||
) {
|
||||
+ int oldPower = Math.max(0, Math.min(15, this.openCount)); // CraftBukkit - Get power before new viewer is added
|
||||
int previous = this.openCount++;
|
||||
+
|
||||
+ // CraftBukkit start - Call redstone event
|
||||
+ if (level.getBlockState(pos).is(net.minecraft.world.level.block.Blocks.TRAPPED_CHEST)) {
|
||||
+ int newPower = Math.max(0, Math.min(15, this.openCount));
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (blockState.is(net.minecraft.world.level.block.Blocks.TRAPPED_CHEST)) {
|
||||
+ int oldCurrent = Math.clamp(previous, 0, 15);
|
||||
+ int newCurrent = Math.clamp(this.openCount, 0, 15);
|
||||
+
|
||||
+ if (oldPower != newPower) {
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, oldPower, newPower);
|
||||
+ if (oldCurrent != newCurrent) {
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, oldCurrent, newCurrent);
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
+
|
||||
if (previous == 0) {
|
||||
this.onOpen(level, pos, blockState);
|
||||
@@ -45,19 +44,19 @@
|
||||
}
|
||||
|
||||
public void decrementOpeners(final LivingEntity entity, final Level level, final BlockPos pos, final BlockState blockState) {
|
||||
+ int oldPower = Math.max(0, Math.min(15, this.openCount)); // CraftBukkit - Get power before new viewer is added
|
||||
+ if (this.openCount == 0) return; // Paper - Prevent ContainerOpenersCounter openCount from going negative
|
||||
int previous = this.openCount--;
|
||||
+
|
||||
+ // CraftBukkit start - Call redstone event
|
||||
+ if (level.getBlockState(pos).is(net.minecraft.world.level.block.Blocks.TRAPPED_CHEST)) {
|
||||
+ int newPower = Math.max(0, Math.min(15, this.openCount));
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (blockState.is(net.minecraft.world.level.block.Blocks.TRAPPED_CHEST)) {
|
||||
+ int oldCurrent = Math.clamp(previous, 0, 15);
|
||||
+ int newCurrent = Math.clamp(this.openCount, 0, 15);
|
||||
+
|
||||
+ if (oldPower != newPower) {
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, oldPower, newPower);
|
||||
+ if (oldCurrent != newCurrent) {
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, oldCurrent, newCurrent);
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
+
|
||||
if (this.openCount == 0) {
|
||||
this.onClose(level, pos, blockState);
|
||||
@@ -69,16 +68,16 @@
|
||||
+ if (this.opened) openCount++; // CraftBukkit - add dummy count from API
|
||||
int prevCount = this.openCount;
|
||||
if (prevCount != openCount) {
|
||||
+ // CraftBukkit start - Call redstone event
|
||||
+ if (level.getBlockState(pos).is(net.minecraft.world.level.block.Blocks.TRAPPED_CHEST)) {
|
||||
+ int oldPower = net.minecraft.util.Mth.clamp(prevCount, 0, 15);
|
||||
+ int newPower = net.minecraft.util.Mth.clamp(openCount, 0, 15);
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (blockState.is(net.minecraft.world.level.block.Blocks.TRAPPED_CHEST)) {
|
||||
+ int oldCurrent = Math.clamp(prevCount, 0, 15);
|
||||
+ int newCurrent = Math.clamp(openCount, 0, 15);
|
||||
+
|
||||
+ if (oldPower != newPower) {
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, oldPower, newPower);
|
||||
+ if (oldCurrent != newCurrent) {
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, oldCurrent, newCurrent);
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
+
|
||||
boolean isOpen = openCount != 0;
|
||||
boolean wasOpen = prevCount != 0;
|
||||
|
||||
@@ -246,6 +246,14 @@
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
@@ -703,6 +_,7 @@
|
||||
}
|
||||
|
||||
private <T extends BlockEntity> void updateBlockEntityTicker(final T blockEntity) {
|
||||
+ if (!this.level.paperConfig().unsupportedSettings.ticking.blockEntities) return; // Paper - option to disable ticking
|
||||
BlockState state = blockEntity.getBlockState();
|
||||
BlockEntityTicker<T> ticker = state.getTicker(this.level, (BlockEntityType<T>)blockEntity.getType());
|
||||
if (ticker == null) {
|
||||
@@ -752,23 +_,24 @@
|
||||
if (this.blockEntity.getType().isValid(blockState)) {
|
||||
this.ticker.tick(LevelChunk.this.level, this.blockEntity.getBlockPos(), blockState, this.blockEntity);
|
||||
|
||||
+7
-10
@@ -1,20 +1,17 @@
|
||||
--- a/net/minecraft/world/level/redstone/DefaultRedstoneWireEvaluator.java
|
||||
+++ b/net/minecraft/world/level/redstone/DefaultRedstoneWireEvaluator.java
|
||||
@@ -20,7 +_,16 @@
|
||||
@@ -20,7 +_,13 @@
|
||||
final Level level, final BlockPos pos, final BlockState state, final @Nullable Orientation orientation, final boolean skipShapeUpdates
|
||||
) {
|
||||
int targetStrength = this.calculateTargetStrength(level, pos);
|
||||
- if (state.getValue(RedStoneWireBlock.POWER) != targetStrength) {
|
||||
+ // CraftBukkit start
|
||||
+ int oldPower = state.getValue(RedStoneWireBlock.POWER);
|
||||
+ if (oldPower != targetStrength) {
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent event = new org.bukkit.event.block.BlockRedstoneEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), oldPower, targetStrength);
|
||||
+ level.getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ targetStrength = event.getNewCurrent();
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ int previousStrength = state.getValue(RedStoneWireBlock.POWER);
|
||||
+ if (previousStrength != targetStrength && level.getBlockState(pos) == state) {
|
||||
+ targetStrength = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, previousStrength, targetStrength).getNewCurrent();
|
||||
+ }
|
||||
+ if (oldPower != targetStrength) {
|
||||
+ // CraftBukkit end
|
||||
+ if (previousStrength != targetStrength) {
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
if (level.getBlockState(pos) == state) {
|
||||
level.setBlock(pos, state.setValue(RedStoneWireBlock.POWER, targetStrength), Block.UPDATE_CLIENTS);
|
||||
}
|
||||
+6
-12
@@ -1,20 +1,14 @@
|
||||
--- a/net/minecraft/world/level/redstone/ExperimentalRedstoneWireEvaluator.java
|
||||
+++ b/net/minecraft/world/level/redstone/ExperimentalRedstoneWireEvaluator.java
|
||||
@@ -45,7 +_,16 @@
|
||||
@@ -45,6 +_,11 @@
|
||||
int packed = next.getIntValue();
|
||||
int newLevel = unpackPower(packed);
|
||||
BlockState state = level.getBlockState(pos);
|
||||
- if (state.is(this.wireBlock) && !state.getValue(RedStoneWireBlock.POWER).equals(newLevel)) {
|
||||
+ // CraftBukkit start
|
||||
+ int oldPower = state.getValue(RedStoneWireBlock.POWER); // Paper - Call BlockRedstoneEvent properly; get the previous power from the right state
|
||||
+ if (oldPower != newLevel) {
|
||||
+ org.bukkit.event.block.BlockRedstoneEvent event = new org.bukkit.event.block.BlockRedstoneEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), oldPower, newLevel);
|
||||
+ level.getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ newLevel = event.getNewCurrent();
|
||||
+ // Paper start - Call BlockRedstoneEvent
|
||||
+ if (state.is(this.wireBlock) && !state.getValue(RedStoneWireBlock.POWER).equals(newLevel)) {
|
||||
+ newLevel = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, state.getValue(RedStoneWireBlock.POWER), newLevel).getNewCurrent();
|
||||
+ }
|
||||
+ if (state.is(this.wireBlock) && oldPower != newLevel) {
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end - Call BlockRedstoneEvent
|
||||
if (state.is(this.wireBlock) && !state.getValue(RedStoneWireBlock.POWER).equals(newLevel)) {
|
||||
int updateFlags = Block.UPDATE_CLIENTS;
|
||||
if (!shapeUpdateWiresAroundInitialPosition || !initialWire) {
|
||||
updateFlags |= Block.UPDATE_SKIP_SHAPE_UPDATE_ON_WIRE;
|
||||
@@ -71,7 +71,7 @@ public class SyncLoadFinder {
|
||||
|
||||
final JsonObject worldData = new JsonObject();
|
||||
|
||||
worldData.addProperty("name", world.getWorld().getKey().toString());
|
||||
worldData.addProperty("key", world.getWorld().key().asString());
|
||||
|
||||
final List<Pair<ThrowableWithEquals, SyncLoadInformation>> data = new ArrayList<>();
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
@@ -18,6 +20,18 @@ public final class CommandUtil {
|
||||
private CommandUtil() {
|
||||
}
|
||||
|
||||
public static List<String> getWorldSuggestions(Server server, boolean withWildcard) {
|
||||
List<World> worlds = server.getWorlds();
|
||||
List<String> worldKeys = new ArrayList<>(worlds.size() + (withWildcard ? 1 : 0));
|
||||
if (withWildcard) {
|
||||
worldKeys.add("*");
|
||||
}
|
||||
for (World world : worlds) {
|
||||
worldKeys.add(world.key().asString());
|
||||
}
|
||||
return worldKeys;
|
||||
}
|
||||
|
||||
// Code from Mojang - copyright them
|
||||
public static List<String> getListMatchingLast(
|
||||
final CommandSender sender,
|
||||
|
||||
+33
-31
@@ -4,7 +4,9 @@ import com.google.common.collect.Maps;
|
||||
import io.papermc.paper.FeatureHooks;
|
||||
import io.papermc.paper.command.CommandUtil;
|
||||
import io.papermc.paper.command.PaperSubcommand;
|
||||
import io.papermc.paper.util.MCUtil;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -21,7 +23,6 @@ import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.HeightMap;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.World;
|
||||
@@ -48,8 +49,12 @@ public final class EntityCommand implements PaperSubcommand {
|
||||
public List<String> tabComplete(final CommandSender sender, final String subCommand, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return CommandUtil.getListMatchingLast(sender, args, "help", "list");
|
||||
} else if (args.length == 2) {
|
||||
return CommandUtil.getListMatchingLast(sender, args, BuiltInRegistries.ENTITY_TYPE.keySet());
|
||||
} else if (args.length > 1 && args[0].toLowerCase(Locale.ROOT).equals("list")) {
|
||||
if (args.length == 2) {
|
||||
return CommandUtil.getListMatchingLast(sender, args, BuiltInRegistries.ENTITY_TYPE.keySet());
|
||||
} else if (args.length == 3) {
|
||||
return CommandUtil.getListMatchingLast(sender, args, CommandUtil.getWorldSuggestions(sender.getServer(), false));
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -60,58 +65,55 @@ public final class EntityCommand implements PaperSubcommand {
|
||||
private void listEntities(final CommandSender sender, final String[] args) {
|
||||
// help
|
||||
if (args.length < 1 || !args[0].toLowerCase(Locale.ROOT).equals("list")) {
|
||||
sender.sendMessage(text("Use /paper entity [list] help for more information on a specific command", RED));
|
||||
sender.sendMessage(text("Use /paper entity list [filter] [world] to get entity info that matches the optional filter.", RED));
|
||||
return;
|
||||
}
|
||||
|
||||
if ("list".equals(args[0].toLowerCase(Locale.ROOT))) {
|
||||
String filter = "*";
|
||||
if (args.length > 1) {
|
||||
if (args[1].toLowerCase(Locale.ROOT).equals("help")) {
|
||||
sender.sendMessage(text("Use /paper entity list [filter] [worldName] to get entity info that matches the optional filter.", RED));
|
||||
return;
|
||||
}
|
||||
filter = args[1];
|
||||
}
|
||||
final String cleanfilter = filter.replace("?", ".?").replace("*", ".*?");
|
||||
final String cleanFilter = filter.replace("?", ".?").replace("*", ".*?");
|
||||
Set<Identifier> names = BuiltInRegistries.ENTITY_TYPE.keySet().stream()
|
||||
.filter(n -> n.toString().matches(cleanfilter))
|
||||
.filter(n -> n.toString().matches(cleanFilter))
|
||||
.collect(Collectors.toSet());
|
||||
if (names.isEmpty()) {
|
||||
sender.sendMessage(text("Invalid filter, does not match any entities. Use /paper entity list for a proper list", RED));
|
||||
sender.sendMessage(text("Usage: /paper entity list [filter] [worldName]", RED));
|
||||
sender.sendMessage(text("Usage: /paper entity list [filter] [world]", RED));
|
||||
return;
|
||||
}
|
||||
String worldName;
|
||||
|
||||
final @Nullable World world;
|
||||
if (args.length > 2) {
|
||||
worldName = args[2];
|
||||
} else if (sender instanceof Player) {
|
||||
worldName = ((Player) sender).getWorld().getKey().toString();
|
||||
@Nullable NamespacedKey key = NamespacedKey.fromString(args[2]);
|
||||
world = key == null ? null : sender.getServer().getWorld(key);
|
||||
if (world == null) {
|
||||
sender.sendMessage(text("Could not load world for " + args[2] + ". Please select a valid world.", RED));
|
||||
sender.sendMessage(text("Usage: /paper entity list [filter] [world]", RED));
|
||||
return;
|
||||
}
|
||||
} else if (sender instanceof Player player) {
|
||||
world = player.getWorld();
|
||||
} else {
|
||||
sender.sendMessage(text("Please specify the name of a world", RED));
|
||||
sender.sendMessage(text("Please specify the key of a world", RED));
|
||||
sender.sendMessage(text("To do so without a filter, specify '*' as the filter", RED));
|
||||
sender.sendMessage(text("Usage: /paper entity list [filter] [worldKey]", RED));
|
||||
sender.sendMessage(text("Usage: /paper entity list [filter] [world]", RED));
|
||||
return;
|
||||
}
|
||||
Map<Identifier, MutablePair<Integer, Map<ChunkPos, Integer>>> list = Maps.newHashMap();
|
||||
@Nullable NamespacedKey worldKey = NamespacedKey.fromString(worldName);
|
||||
@Nullable World bukkitWorld;
|
||||
if (worldKey == null || (bukkitWorld = Bukkit.getWorld(worldKey)) == null) {
|
||||
sender.sendMessage(text("Could not load world for " + worldName + ". Please select a valid world.", RED));
|
||||
sender.sendMessage(text("Usage: /paper entity list [filter] [worldKey]", RED));
|
||||
return;
|
||||
}
|
||||
ServerLevel world = ((CraftWorld) bukkitWorld).getHandle();
|
||||
Map<Identifier, Integer> nonEntityTicking = Maps.newHashMap();
|
||||
ServerChunkCache chunkProviderServer = world.getChunkSource();
|
||||
FeatureHooks.getAllEntities(world).forEach(e -> {
|
||||
|
||||
Map<Identifier, MutablePair<Integer, Map<ChunkPos, Integer>>> list = new HashMap<>();
|
||||
ServerLevel level = ((CraftWorld) world).getHandle();
|
||||
Map<Identifier, Integer> nonEntityTicking = new HashMap<>();
|
||||
ServerChunkCache chunkProviderServer = level.getChunkSource();
|
||||
FeatureHooks.getAllEntities(level).forEach(e -> {
|
||||
Identifier key = EntityType.getKey(e.getType());
|
||||
|
||||
MutablePair<Integer, Map<ChunkPos, Integer>> info = list.computeIfAbsent(key, k -> MutablePair.of(0, Maps.newHashMap()));
|
||||
ChunkPos chunk = e.chunkPosition();
|
||||
info.left++;
|
||||
info.right.put(chunk, info.right.getOrDefault(chunk, 0) + 1);
|
||||
if (!world.isPositionEntityTicking(e.blockPosition()) || (e instanceof net.minecraft.world.entity.Marker && !world.paperConfig().entities.markers.tick)) { // Paper - Configurable marker ticking
|
||||
if (!level.isPositionEntityTicking(e.blockPosition()) || (e instanceof net.minecraft.world.entity.Marker && !level.paperConfig().entities.markers.tick)) { // Paper - Configurable marker ticking
|
||||
nonEntityTicking.merge(key, 1, Integer::sum);
|
||||
}
|
||||
});
|
||||
@@ -131,7 +133,7 @@ public final class EntityCommand implements PaperSubcommand {
|
||||
final int z = (e.getKey().z() << 4) + 8;
|
||||
final Component message = text(" " + e.getValue() + ": " + e.getKey().x() + ", " + e.getKey().z() + (chunkProviderServer.isPositionTicking(e.getKey().pack()) ? " (Ticking)" : " (Non-Ticking)"))
|
||||
.hoverEvent(HoverEvent.showText(text("Click to teleport to chunk", GREEN)))
|
||||
.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND, "/minecraft:execute as @s in " + world.getWorld().getKey() + " run tp " + x + " " + (world.getWorld().getHighestBlockYAt(x, z, HeightMap.MOTION_BLOCKING) + 1) + " " + z));
|
||||
.clickEvent(ClickEvent.runCommand("/minecraft:execute as @s in " + MCUtil.getLevelName(level) + " run tp " + x + " " + (level.getWorld().getHighestBlockYAt(x, z, HeightMap.MOTION_BLOCKING) + 1) + " " + z));
|
||||
sender.sendMessage(message);
|
||||
});
|
||||
} else {
|
||||
|
||||
+9
-12
@@ -8,7 +8,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.ToIntFunction;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.ComponentLike;
|
||||
import net.kyori.adventure.text.JoinConfiguration;
|
||||
@@ -56,17 +55,15 @@ public final class MobcapsCommand implements PaperSubcommand {
|
||||
@Override
|
||||
public List<String> tabComplete(final CommandSender sender, final String subCommand, final String[] args) {
|
||||
return switch (subCommand) {
|
||||
case "mobcaps" -> CommandUtil.getListMatchingLast(sender, args, this.suggestMobcaps(args));
|
||||
case "mobcaps" -> CommandUtil.getListMatchingLast(sender, args, this.suggestMobcaps(sender, args));
|
||||
case "playermobcaps" -> CommandUtil.getListMatchingLast(sender, args, this.suggestPlayerMobcaps(sender, args));
|
||||
default -> throw new IllegalArgumentException();
|
||||
};
|
||||
}
|
||||
|
||||
private List<String> suggestMobcaps(final String[] args) {
|
||||
private List<String> suggestMobcaps(final CommandSender sender, String[] args) {
|
||||
if (args.length == 1) {
|
||||
final List<String> worlds = new ArrayList<>(Bukkit.getWorlds().stream().map(World::getKey).map(NamespacedKey::toString).toList());
|
||||
worlds.add("*");
|
||||
return worlds;
|
||||
return CommandUtil.getWorldSuggestions(sender.getServer(), true);
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
@@ -92,17 +89,17 @@ public final class MobcapsCommand implements PaperSubcommand {
|
||||
if (sender instanceof Player player) {
|
||||
worlds = List.of(player.getWorld());
|
||||
} else {
|
||||
sender.sendMessage(Component.text("Must specify a world! ex: '/paper mobcaps overworld'", NamedTextColor.RED));
|
||||
sender.sendMessage(Component.text("Must specify a world! ex: '/paper mobcaps minecraft:overworld'", NamedTextColor.RED));
|
||||
return;
|
||||
}
|
||||
} else if (args.length == 1) {
|
||||
final String input = args[0];
|
||||
if (input.equals("*")) {
|
||||
worlds = Bukkit.getWorlds();
|
||||
worlds = Bukkit.getServer().getWorlds();
|
||||
} else {
|
||||
final @Nullable Key worldKey = NamespacedKey.fromString(input);
|
||||
final @Nullable World world;
|
||||
if (worldKey == null || (world = Bukkit.getWorld(worldKey)) == null) {
|
||||
final @Nullable NamespacedKey worldKey = NamespacedKey.fromString(input);
|
||||
final @Nullable World world = worldKey == null ? null : sender.getServer().getWorld(worldKey);
|
||||
if (world == null) {
|
||||
sender.sendMessage(Component.text("'" + input + "' is not a valid world!", NamedTextColor.RED));
|
||||
return;
|
||||
} else {
|
||||
@@ -126,7 +123,7 @@ public final class MobcapsCommand implements PaperSubcommand {
|
||||
}
|
||||
sender.sendMessage(Component.join(JoinConfiguration.noSeparators(),
|
||||
Component.text("Mobcaps for world: "),
|
||||
Component.text(world.getKey().toString(), NamedTextColor.AQUA),
|
||||
Component.text(world.key().asString(), NamedTextColor.AQUA),
|
||||
Component.text(" (" + chunks + " spawnable chunks)")
|
||||
));
|
||||
|
||||
|
||||
+7
-3
@@ -13,8 +13,9 @@ import java.io.StringWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import java.util.Locale;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import net.kyori.adventure.text.event.HoverEvent;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
@@ -38,7 +39,10 @@ public final class SyncLoadInfoCommand implements PaperSubcommand {
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(final CommandSender sender, final String subCommand, final String[] args) {
|
||||
return CommandUtil.getListMatchingLast(sender, args, "clear");
|
||||
if (args.length == 1) {
|
||||
return CommandUtil.getListMatchingLast(sender, args, "clear");
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss");
|
||||
@@ -53,7 +57,7 @@ public final class SyncLoadInfoCommand implements PaperSubcommand {
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length > 0 && args[0].equals("clear")) {
|
||||
if (args.length > 0 && args[0].toLowerCase(Locale.ROOT).equals("clear")) {
|
||||
SyncLoadFinder.clear();
|
||||
sender.sendMessage(text("Sync load data cleared.", GRAY));
|
||||
return;
|
||||
|
||||
@@ -192,11 +192,16 @@ public class GlobalConfiguration extends ConfigurationPart {
|
||||
|
||||
public class Commands extends ConfigurationPart {
|
||||
public boolean suggestPlayerNamesWhenNullTabCompletions = true;
|
||||
public boolean timeCommandAffectsAllWorlds = false;
|
||||
@Comment("Allow mounting entities to a player in the Vanilla '/ride' command.")
|
||||
public boolean rideCommandAllowPlayerAsVehicle = false;
|
||||
}
|
||||
|
||||
public Time time;
|
||||
|
||||
public class Time extends ConfigurationPart {
|
||||
public boolean affectsAllWorlds = false;
|
||||
}
|
||||
|
||||
public Scoreboards scoreboards;
|
||||
|
||||
public class Scoreboards extends ConfigurationPart {
|
||||
|
||||
@@ -11,9 +11,9 @@ import io.papermc.paper.configuration.mapping.InnerClassFieldDiscoverer;
|
||||
import io.papermc.paper.configuration.mapping.MergeMap;
|
||||
import io.papermc.paper.configuration.serializer.ComponentSerializer;
|
||||
import io.papermc.paper.configuration.serializer.EnumValueSerializer;
|
||||
import io.papermc.paper.configuration.serializer.IdentifierSerializer;
|
||||
import io.papermc.paper.configuration.serializer.NbtPathSerializer;
|
||||
import io.papermc.paper.configuration.serializer.ServerboundPacketClassSerializer;
|
||||
import io.papermc.paper.configuration.serializer.IdentifierSerializer;
|
||||
import io.papermc.paper.configuration.serializer.StringRepresentableSerializer;
|
||||
import io.papermc.paper.configuration.serializer.collection.TableSerializer;
|
||||
import io.papermc.paper.configuration.serializer.collection.map.FastutilMapSerializer;
|
||||
@@ -54,7 +54,6 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.component.DataComponentType;
|
||||
@@ -64,8 +63,8 @@ import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.gamerules.GameRules;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.gamerules.GameRules;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
@@ -87,6 +87,7 @@ interface RemovedConfigurations {
|
||||
path("chunk-system", "gen-parallelism"),
|
||||
path("logging"), // server is no longer obfuscated since 26.1
|
||||
path("unsupported-settings", "compression-format"),
|
||||
path("commands", "time-command-affects-all-worlds") // replaced with time.affects-all-worlds
|
||||
};
|
||||
|
||||
}
|
||||
@@ -477,6 +477,12 @@ public class WorldConfiguration extends ConfigurationPart {
|
||||
public class UnsupportedSettings extends ConfigurationPart {
|
||||
public boolean fixInvulnerableEndCrystalExploit = true;
|
||||
public boolean disableWorldTickingWhenEmpty = false;
|
||||
public Ticking ticking;
|
||||
|
||||
public class Ticking extends ConfigurationPart {
|
||||
public boolean chunks = true;
|
||||
public boolean blockEntities = true;
|
||||
}
|
||||
}
|
||||
|
||||
public Hopper hopper;
|
||||
|
||||
-1
@@ -128,7 +128,6 @@ public final class LegacyPaperConfig {
|
||||
moveFromRoot(builder, "track-plugin-scoreboards", "scoreboards");
|
||||
|
||||
moveFromRoot(builder, "suggest-player-names-when-null-tab-completions", "commands");
|
||||
moveFromRoot(builder, "time-command-affects-all-worlds", "commands");
|
||||
moveFromRoot(builder, "fix-target-selector-tag-completion", "commands");
|
||||
|
||||
moveFromRoot(builder, "log-player-ip-addresses", "loggers");
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.papermc.paper.connection;
|
||||
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import io.papermc.paper.event.connection.configuration.AsyncPlayerConnectionConfigureEvent;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@@ -15,8 +14,9 @@ import org.slf4j.Logger;
|
||||
public class PaperConfigurationTask implements ConfigurationTask {
|
||||
private static final Logger LOGGER = LogUtils.getClassLogger();
|
||||
|
||||
public static final ExecutorService CONFIGURATION_POOL = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("Configuration Thread #%d")
|
||||
.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER)).build());
|
||||
public static final ExecutorService CONFIGURATION_POOL = Executors.newThreadPerTaskExecutor(
|
||||
Thread.ofVirtual().name("Configuration Thread #", 0).uncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER)).factory()
|
||||
);
|
||||
|
||||
public static final ConfigurationTask.Type TYPE = new ConfigurationTask.Type("paper_event_handling");
|
||||
|
||||
|
||||
+7
-8
@@ -21,6 +21,10 @@ import org.bukkit.inventory.meta.trim.ArmorTrim;
|
||||
import org.bukkit.map.MapCursor;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import static io.papermc.paper.util.BoundChecker.requireNonNegative;
|
||||
import static io.papermc.paper.util.BoundChecker.requirePositive;
|
||||
import static io.papermc.paper.util.BoundChecker.requireRange;
|
||||
|
||||
public final class ItemComponentTypesBridgesImpl implements ItemComponentTypesBridge {
|
||||
|
||||
@Override
|
||||
@@ -194,8 +198,7 @@ public final class ItemComponentTypesBridgesImpl implements ItemComponentTypesBr
|
||||
|
||||
@Override
|
||||
public UseCooldown.Builder useCooldown(final float seconds) {
|
||||
Preconditions.checkArgument(seconds > 0, "seconds must be positive, was %s", seconds);
|
||||
return new PaperUseCooldown.BuilderImpl(seconds);
|
||||
return new PaperUseCooldown.BuilderImpl(requirePositive(seconds, "seconds"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -232,11 +235,8 @@ public final class ItemComponentTypesBridgesImpl implements ItemComponentTypesBr
|
||||
|
||||
@Override
|
||||
public PaperOminousBottleAmplifier ominousBottleAmplifier(final int amplifier) {
|
||||
Preconditions.checkArgument(OminousBottleAmplifier.MIN_AMPLIFIER <= amplifier && amplifier <= OminousBottleAmplifier.MAX_AMPLIFIER,
|
||||
"amplifier must be between %s-%s, was %s", OminousBottleAmplifier.MIN_AMPLIFIER, OminousBottleAmplifier.MAX_AMPLIFIER, amplifier
|
||||
);
|
||||
return new PaperOminousBottleAmplifier(
|
||||
new OminousBottleAmplifier(amplifier)
|
||||
new OminousBottleAmplifier(requireRange(amplifier, "amplifier", OminousBottleAmplifier.MIN_AMPLIFIER, OminousBottleAmplifier.MAX_AMPLIFIER))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -282,9 +282,8 @@ public final class ItemComponentTypesBridgesImpl implements ItemComponentTypesBr
|
||||
|
||||
@Override
|
||||
public KineticWeapon.Condition kineticWeaponCondition(int maxDurationTicks, float minSpeed, float minRelativeSpeed) {
|
||||
Preconditions.checkArgument(maxDurationTicks >= 0, "maxDurationTicks must be non-negative");
|
||||
return new PaperKineticWeapon.PaperKineticWeaponCondition(new net.minecraft.world.item.component.KineticWeapon.Condition(
|
||||
maxDurationTicks, minSpeed, minRelativeSpeed
|
||||
maxDurationTicks, minSpeed, requireNonNegative(minRelativeSpeed, "minRelativeSpeed")
|
||||
));
|
||||
}
|
||||
}
|
||||
Loaded 100 of 156 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user