1.21.6 dev
Co-authored-by: Bjarne Koll <git@lynxplay.dev> Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com> Co-authored-by: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Co-authored-by: Noah van der Aa <ndvdaa@gmail.com> Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
This commit is contained in:
committed by
Nassim Jahnke
parent
39203a65e0
commit
a24f9b204c
@ -15,7 +15,7 @@ plugins {
|
||||
val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/"
|
||||
|
||||
dependencies {
|
||||
mache("io.papermc:mache:1.21.5+build.2")
|
||||
mache("io.papermc:mache:1.21.6-rc1+build.1")
|
||||
paperclip("io.papermc:paperclip:3.0.3")
|
||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||
}
|
||||
@ -24,11 +24,8 @@ paperweight {
|
||||
minecraftVersion = providers.gradleProperty("mcVersion")
|
||||
gitFilePatches = false
|
||||
|
||||
//updatingMinecraft {
|
||||
// oldPaperCommit = "f4f275519f7c1fbe9db173b7144a4fe81440e365"
|
||||
//}
|
||||
|
||||
spigot {
|
||||
enabled = false
|
||||
buildDataRef = "702e1a0a5072b2c4082371d5228cb30525687efc"
|
||||
packageVersion = "v1_21_R4" // also needs to be updated in MappingEnvironment
|
||||
}
|
||||
@ -230,6 +227,11 @@ tasks.compileTestJava {
|
||||
options.compilerArgs.add("-parameters")
|
||||
}
|
||||
|
||||
// Bump compile tasks to 1GB memory to avoid OOMs
|
||||
tasks.withType<JavaCompile>().configureEach {
|
||||
options.forkOptions.memoryMaximumSize = "1G"
|
||||
}
|
||||
|
||||
val scanJarForBadCalls by tasks.registering(io.papermc.paperweight.tasks.ScanJarForBadCalls::class) {
|
||||
badAnnotations.add("Lio/papermc/paper/annotation/DoNotUse;")
|
||||
jarToScan.set(tasks.jar.flatMap { it.archiveFile })
|
||||
|
||||
@ -28,7 +28,7 @@ and then catch exceptions and close if they fire.
|
||||
Part of this commit was authored by: Spottedleaf, sandtechnology
|
||||
|
||||
diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java
|
||||
index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42eafb96fa1 100644
|
||||
index 2252c7c3e78c1d6dc9b56c0f6f01aec04699f072..235a076f982247552fef6d86d7e1b141eb8c72b5 100644
|
||||
--- a/net/minecraft/network/Connection.java
|
||||
+++ b/net/minecraft/network/Connection.java
|
||||
@@ -85,7 +85,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@ -51,10 +51,10 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e
|
||||
|
||||
public Connection(PacketFlow receiving) {
|
||||
this.receiving = receiving;
|
||||
@@ -423,11 +427,38 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -419,11 +423,38 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
}
|
||||
|
||||
public void send(Packet<?> packet, @Nullable PacketSendListener listener, boolean flush) {
|
||||
public void send(Packet<?> packet, @Nullable ChannelFutureListener channelFutureListener, boolean flag) {
|
||||
- if (this.isConnected()) {
|
||||
- this.flushQueue();
|
||||
+ // Paper start - Optimize network: Handle oversized packets better
|
||||
@ -67,14 +67,14 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e
|
||||
+ if (connected && (InnerUtil.canSendImmediate(this, packet)
|
||||
+ || (io.papermc.paper.util.MCUtil.isMainThread() && packet.isReady() && this.pendingActions.isEmpty()
|
||||
+ && (packet.getExtraPackets() == null || packet.getExtraPackets().isEmpty())))) {
|
||||
this.sendPacket(packet, listener, flush);
|
||||
this.sendPacket(packet, channelFutureListener, flag);
|
||||
} else {
|
||||
- this.pendingActions.add(connection -> connection.sendPacket(packet, listener, flush));
|
||||
- this.pendingActions.add(connection -> connection.sendPacket(packet, channelFutureListener, flag));
|
||||
+ // Write the packets to the queue, then flush - antixray hooks there already
|
||||
+ final java.util.List<Packet<?>> extraPackets = InnerUtil.buildExtraPackets(packet);
|
||||
+ final boolean hasExtraPackets = extraPackets != null && !extraPackets.isEmpty();
|
||||
+ if (!hasExtraPackets) {
|
||||
+ this.pendingActions.add(new PacketSendAction(packet, listener, flush));
|
||||
+ this.pendingActions.add(new PacketSendAction(packet, channelFutureListener, flag));
|
||||
+ } else {
|
||||
+ final java.util.List<PacketSendAction> actions = new java.util.ArrayList<>(1 + extraPackets.size());
|
||||
+ actions.add(new PacketSendAction(packet, null, false)); // Delay the future listener until the end of the extra packets
|
||||
@ -82,7 +82,7 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e
|
||||
+ for (int i = 0, len = extraPackets.size(); i < len;) {
|
||||
+ final Packet<?> extraPacket = extraPackets.get(i);
|
||||
+ final boolean end = ++i == len;
|
||||
+ actions.add(new PacketSendAction(extraPacket, end ? listener : null, end)); // Append listener to the end
|
||||
+ actions.add(new PacketSendAction(extraPacket, end ? channelFutureListener : null, end)); // Append listener to the end
|
||||
+ }
|
||||
+
|
||||
+ this.pendingActions.addAll(actions);
|
||||
@ -93,7 +93,7 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,7 +467,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -432,7 +463,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
this.flushQueue();
|
||||
action.accept(this);
|
||||
} else {
|
||||
@ -102,10 +102,10 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,6 +481,14 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -446,21 +477,41 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
}
|
||||
|
||||
private void doSendPacket(Packet<?> packet, @Nullable PacketSendListener sendListener, boolean flush) {
|
||||
private void doSendPacket(Packet<?> packet, @Nullable ChannelFutureListener channelFutureListener, boolean flag) {
|
||||
+ // Paper start - Optimize network
|
||||
+ final net.minecraft.server.level.ServerPlayer player = this.getPlayer();
|
||||
+ if (!this.isConnected()) {
|
||||
@ -113,24 +113,29 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e
|
||||
+ return;
|
||||
+ }
|
||||
+ try {
|
||||
+ final ChannelFuture channelFuture;
|
||||
+ // Paper end - Optimize network
|
||||
ChannelFuture channelFuture = flush ? this.channel.writeAndFlush(packet) : this.channel.write(packet);
|
||||
if (sendListener != null) {
|
||||
channelFuture.addListener(future -> {
|
||||
@@ -465,14 +504,24 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
});
|
||||
}
|
||||
|
||||
if (channelFutureListener != null) {
|
||||
- ChannelFuture channelFuture = flag ? this.channel.writeAndFlush(packet) : this.channel.write(packet);
|
||||
+ channelFuture = flag ? this.channel.writeAndFlush(packet) : this.channel.write(packet); // Paper - Optimize network
|
||||
channelFuture.addListener(channelFutureListener);
|
||||
} else if (flag) {
|
||||
- this.channel.writeAndFlush(packet, this.channel.voidPromise());
|
||||
+ channelFuture = this.channel.writeAndFlush(packet, this.channel.voidPromise()); // Paper - Optimize network
|
||||
} else {
|
||||
- this.channel.write(packet, this.channel.voidPromise());
|
||||
+ channelFuture = this.channel.write(packet, this.channel.voidPromise()); // Paper - Optimize network
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - Optimize network
|
||||
+ if (packet.hasFinishListener()) {
|
||||
+ channelFuture.addListener((ChannelFutureListener) future -> packet.onPacketDispatchFinish(player, future));
|
||||
+ }
|
||||
channelFuture.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
|
||||
+ } catch (final Exception e) {
|
||||
+ LOGGER.error("NetworkException: {}", player, e);
|
||||
+ this.disconnect(Component.translatable("disconnect.genericReason", "Internal Exception: " + e.getMessage()));
|
||||
+ packet.onPacketDispatchFinish(player, null);
|
||||
+ }
|
||||
}
|
||||
+ // Paper end - Optimize network
|
||||
}
|
||||
|
||||
@ -143,7 +148,7 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e
|
||||
}
|
||||
}
|
||||
|
||||
@@ -484,16 +533,57 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -472,16 +523,57 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,7 +211,7 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e
|
||||
|
||||
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
|
||||
@@ -563,6 +653,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -551,6 +643,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
|
||||
public void disconnect(DisconnectionDetails disconnectionDetails) {
|
||||
this.preparing = false; // Spigot
|
||||
@ -214,7 +219,7 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e
|
||||
if (this.channel == null) {
|
||||
this.delayedDisconnect = disconnectionDetails;
|
||||
}
|
||||
@@ -751,7 +842,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -739,7 +832,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
public void handleDisconnection() {
|
||||
if (this.channel != null && !this.channel.isOpen()) {
|
||||
if (this.disconnectionHandled) {
|
||||
@ -223,7 +228,7 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e
|
||||
} else {
|
||||
this.disconnectionHandled = true;
|
||||
PacketListener packetListener = this.getPacketListener();
|
||||
@@ -762,7 +853,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -750,7 +843,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
);
|
||||
packetListener1.onDisconnect(disconnectionDetails);
|
||||
}
|
||||
@ -232,7 +237,7 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e
|
||||
// Paper start - Add PlayerConnectionCloseEvent
|
||||
if (packetListener instanceof net.minecraft.server.network.ServerCommonPacketListenerImpl commonPacketListener) {
|
||||
/* Player was logged in, either game listener or configuration listener */
|
||||
@@ -797,4 +888,97 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -785,4 +878,97 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
public void setBandwidthLogger(LocalSampleLogger bandwithLogger) {
|
||||
this.bandwidthDebugMonitor = new BandwidthDebugMonitor(bandwithLogger);
|
||||
}
|
||||
@ -323,8 +328,8 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e
|
||||
+ private static final class PacketSendAction extends WrappedConsumer {
|
||||
+ private final Packet<?> packet;
|
||||
+
|
||||
+ private PacketSendAction(final Packet<?> packet, @Nullable final PacketSendListener packetSendListener, final boolean flush) {
|
||||
+ super(connection -> connection.sendPacket(packet, packetSendListener, flush));
|
||||
+ private PacketSendAction(final Packet<?> packet, @Nullable final ChannelFutureListener channelFutureListener, final boolean flush) {
|
||||
+ super(connection -> connection.sendPacket(packet, channelFutureListener, flush));
|
||||
+ this.packet = packet;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
@ -15,19 +15,20 @@ Adds villagers as separate config
|
||||
|
||||
diff --git a/io/papermc/paper/entity/activation/ActivationRange.java b/io/papermc/paper/entity/activation/ActivationRange.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..2ebee223085fe7926c7f3e555df19ae69f36157e
|
||||
index 0000000000000000000000000000000000000000..ae2bb9a73106febfe5f0d090abd4252bbb5fd27e
|
||||
--- /dev/null
|
||||
+++ b/io/papermc/paper/entity/activation/ActivationRange.java
|
||||
@@ -0,0 +1,318 @@
|
||||
@@ -0,0 +1,334 @@
|
||||
+package io.papermc.paper.entity.activation;
|
||||
+
|
||||
+import net.minecraft.core.BlockPos;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
+import net.minecraft.world.entity.Entity;
|
||||
+import net.minecraft.world.entity.EntityType;
|
||||
+import net.minecraft.world.entity.ExperienceOrb;
|
||||
+import net.minecraft.world.entity.FlyingMob;
|
||||
+import net.minecraft.world.entity.LightningBolt;
|
||||
+import net.minecraft.world.entity.LivingEntity;
|
||||
+import net.minecraft.world.entity.Marker;
|
||||
+import net.minecraft.world.entity.Mob;
|
||||
+import net.minecraft.world.entity.ai.Brain;
|
||||
+import net.minecraft.world.entity.animal.Animal;
|
||||
@ -38,6 +39,7 @@ index 0000000000000000000000000000000000000000..2ebee223085fe7926c7f3e555df19ae6
|
||||
+import net.minecraft.world.entity.boss.enderdragon.EndCrystal;
|
||||
+import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
|
||||
+import net.minecraft.world.entity.boss.wither.WitherBoss;
|
||||
+import net.minecraft.world.entity.item.FallingBlockEntity;
|
||||
+import net.minecraft.world.entity.item.ItemEntity;
|
||||
+import net.minecraft.world.entity.item.PrimedTnt;
|
||||
+import net.minecraft.world.entity.monster.Creeper;
|
||||
@ -51,9 +53,13 @@ index 0000000000000000000000000000000000000000..2ebee223085fe7926c7f3e555df19ae6
|
||||
+import net.minecraft.world.entity.projectile.ThrowableProjectile;
|
||||
+import net.minecraft.world.entity.projectile.ThrownTrident;
|
||||
+import net.minecraft.world.entity.schedule.Activity;
|
||||
+import net.minecraft.world.entity.vehicle.AbstractBoat;
|
||||
+import net.minecraft.world.entity.vehicle.AbstractMinecart;
|
||||
+import net.minecraft.world.level.Level;
|
||||
+import net.minecraft.world.phys.AABB;
|
||||
+import org.spigotmc.SpigotWorldConfig;
|
||||
+import java.util.List;
|
||||
+import java.util.Set;
|
||||
+
|
||||
+public final class ActivationRange {
|
||||
+
|
||||
@ -121,9 +127,9 @@ index 0000000000000000000000000000000000000000..2ebee223085fe7926c7f3e555df19ae6
|
||||
+ || entity instanceof AbstractHurtingProjectile
|
||||
+ || entity instanceof LightningBolt
|
||||
+ || entity instanceof PrimedTnt
|
||||
+ || entity instanceof net.minecraft.world.entity.item.FallingBlockEntity
|
||||
+ || entity instanceof net.minecraft.world.entity.vehicle.AbstractMinecart
|
||||
+ || entity instanceof net.minecraft.world.entity.vehicle.AbstractBoat
|
||||
+ || entity instanceof FallingBlockEntity
|
||||
+ || entity instanceof AbstractMinecart
|
||||
+ || entity instanceof AbstractBoat
|
||||
+ || entity instanceof EndCrystal
|
||||
+ || entity instanceof FireworkRocketEntity
|
||||
+ || entity instanceof ThrownTrident;
|
||||
@ -172,10 +178,10 @@ index 0000000000000000000000000000000000000000..2ebee223085fe7926c7f3e555df19ae6
|
||||
+ ActivationType.FLYING_MONSTER.boundingBox = player.getBoundingBox().inflate(flyingActivationRange, worldHeight, flyingActivationRange);
|
||||
+ ActivationType.VILLAGER.boundingBox = player.getBoundingBox().inflate(villagerActivationRange, worldHeight, villagerActivationRange);
|
||||
+
|
||||
+ final java.util.List<Entity> entities = world.getEntities((Entity) null, ActivationRange.maxBB, e -> true);
|
||||
+ final List<Entity> entities = world.getEntities((Entity) null, ActivationRange.maxBB, e -> true);
|
||||
+ final boolean tickMarkers = world.paperConfig().entities.markers.tick;
|
||||
+ for (final Entity entity : entities) {
|
||||
+ if (!tickMarkers && entity instanceof net.minecraft.world.entity.Marker) {
|
||||
+ if (!tickMarkers && entity instanceof Marker) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
@ -228,7 +234,7 @@ index 0000000000000000000000000000000000000000..2ebee223085fe7926c7f3e555df19ae6
|
||||
+ return 100;
|
||||
+ }
|
||||
+ if (!(entity instanceof final AbstractArrow arrow)) {
|
||||
+ if ((!entity.onGround() && !(entity instanceof FlyingMob))) {
|
||||
+ if ((!entity.onGround() && !isEntityThatFlies(entity))) {
|
||||
+ return 10;
|
||||
+ }
|
||||
+ } else if (!arrow.isInGround()) {
|
||||
@ -336,9 +342,19 @@ index 0000000000000000000000000000000000000000..2ebee223085fe7926c7f3e555df19ae6
|
||||
+ // removed the original's dumb tick skipping for active entities
|
||||
+ return isActive;
|
||||
+ }
|
||||
+
|
||||
+ private static Set<EntityType<?>> ENTITIES_THAT_FLY = Set.of(
|
||||
+ EntityType.GHAST,
|
||||
+ EntityType.HAPPY_GHAST,
|
||||
+ EntityType.PHANTOM
|
||||
+ );
|
||||
+
|
||||
+ private static boolean isEntityThatFlies(final Entity entity) {
|
||||
+ return ENTITIES_THAT_FLY.contains(entity.getType());
|
||||
+ }
|
||||
+}
|
||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||
index 88b81a5fbc88e6240f86c1e780d80eb4b601df8c..00a5ed09caa2689543bd47bcd93d5a6141d0af46 100644
|
||||
index 7b5ed00c9b2f22af5cbc44171192d674936dc7d7..5fe3c9a159908785e08fa874982bc1a82283bb1d 100644
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -4,7 +4,6 @@ import com.google.common.collect.ImmutableList;
|
||||
@ -358,10 +374,10 @@ index 88b81a5fbc88e6240f86c1e780d80eb4b601df8c..00a5ed09caa2689543bd47bcd93d5a61
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Path;
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 81c615d00323bdf86bdb76db17bb47288cf3feba..6b67cc939851745718f919488c997eb6719a16fc 100644
|
||||
index 18551bebb7e40c936de94c6d1b009db4752d3bba..e6f958b6128213fb9577406c6495148dccac40ca 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -544,6 +544,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -548,6 +548,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
profilerFiller.pop();
|
||||
}
|
||||
|
||||
@ -369,7 +385,7 @@ index 81c615d00323bdf86bdb76db17bb47288cf3feba..6b67cc939851745718f919488c997eb6
|
||||
this.entityTickList
|
||||
.forEach(
|
||||
entity -> {
|
||||
@@ -982,12 +983,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -990,12 +991,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
entity.totalEntityAge++; // Paper - age-like counter for all entities
|
||||
profilerFiller.push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString());
|
||||
profilerFiller.incrementCounter("tickNonPassenger");
|
||||
@ -386,7 +402,7 @@ index 81c615d00323bdf86bdb76db17bb47288cf3feba..6b67cc939851745718f919488c997eb6
|
||||
}
|
||||
// Paper start - log detailed entity tick information
|
||||
} finally {
|
||||
@@ -998,7 +1002,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -1006,7 +1010,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
// Paper end - log detailed entity tick information
|
||||
}
|
||||
|
||||
@ -395,7 +411,7 @@ index 81c615d00323bdf86bdb76db17bb47288cf3feba..6b67cc939851745718f919488c997eb6
|
||||
if (passengerEntity.isRemoved() || passengerEntity.getVehicle() != ridingEntity) {
|
||||
passengerEntity.stopRiding();
|
||||
} else if (passengerEntity instanceof Player || this.entityTickList.contains(passengerEntity)) {
|
||||
@@ -1008,12 +1012,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -1016,12 +1020,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
profilerFiller.push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(passengerEntity.getType()).toString());
|
||||
profilerFiller.incrementCounter("tickPassenger");
|
||||
@ -419,10 +435,10 @@ index 81c615d00323bdf86bdb76db17bb47288cf3feba..6b67cc939851745718f919488c997eb6
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/AgeableMob.java b/net/minecraft/world/entity/AgeableMob.java
|
||||
index f9cfa9dd17bd259cfbc0d96bf48a17556b365d8b..201c6d6e2f5799a7678b16f01c85508bc72e8af5 100644
|
||||
index 16c5ad1547eb383e40c9fbae9b1119afc418b3a4..04875840085541ebfc7014868beec49bb7ab9976 100644
|
||||
--- a/net/minecraft/world/entity/AgeableMob.java
|
||||
+++ b/net/minecraft/world/entity/AgeableMob.java
|
||||
@@ -129,6 +129,23 @@ public abstract class AgeableMob extends PathfinderMob {
|
||||
@@ -130,6 +130,23 @@ public abstract class AgeableMob extends PathfinderMob {
|
||||
super.onSyncedDataUpdated(key);
|
||||
}
|
||||
|
||||
@ -447,10 +463,10 @@ index f9cfa9dd17bd259cfbc0d96bf48a17556b365d8b..201c6d6e2f5799a7678b16f01c85508b
|
||||
public void aiStep() {
|
||||
super.aiStep();
|
||||
diff --git a/net/minecraft/world/entity/AreaEffectCloud.java b/net/minecraft/world/entity/AreaEffectCloud.java
|
||||
index bf44f6b9c8710e0c9a85d44f6217501abc98a7b1..bfd904e468bbf2cc1a5b3353d3a69ad5087c81ae 100644
|
||||
index c70a58f5f633fa8e255f74c42f5e87c96b7b013a..ec20a5a6d7c8f65abda528fec36bec7bc71117f6 100644
|
||||
--- a/net/minecraft/world/entity/AreaEffectCloud.java
|
||||
+++ b/net/minecraft/world/entity/AreaEffectCloud.java
|
||||
@@ -144,6 +144,16 @@ public class AreaEffectCloud extends Entity implements TraceableEntity {
|
||||
@@ -142,6 +142,16 @@ public class AreaEffectCloud extends Entity implements TraceableEntity {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
@ -468,10 +484,10 @@ index bf44f6b9c8710e0c9a85d44f6217501abc98a7b1..bfd904e468bbf2cc1a5b3353d3a69ad5
|
||||
public void tick() {
|
||||
super.tick();
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index a63873a0fe4335813cafe84cae2b2030c8f0e627..f0c72465a71dc5a51c22af5e614af744b0434e94 100644
|
||||
index f961540a00bfb5e1c8eb0e739f8ae535e9eee8f3..7453ddb09f349b7836f966573e4933646a75cba6 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -388,6 +388,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -409,6 +409,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
private final int despawnTime; // Paper - entity despawn time limit
|
||||
public int totalEntityAge; // Paper - age-like counter for all entities
|
||||
public final io.papermc.paper.entity.activation.ActivationType activationType = io.papermc.paper.entity.activation.ActivationType.activationTypeFor(this); // Paper - EAR 2/tracking ranges
|
||||
@ -487,7 +503,7 @@ index a63873a0fe4335813cafe84cae2b2030c8f0e627..f0c72465a71dc5a51c22af5e614af744
|
||||
// CraftBukkit end
|
||||
|
||||
// Paper start
|
||||
@@ -407,6 +416,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -424,6 +433,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
this.position = Vec3.ZERO;
|
||||
this.blockPosition = BlockPos.ZERO;
|
||||
this.chunkPosition = ChunkPos.ZERO;
|
||||
@ -501,7 +517,7 @@ index a63873a0fe4335813cafe84cae2b2030c8f0e627..f0c72465a71dc5a51c22af5e614af744
|
||||
SynchedEntityData.Builder builder = new SynchedEntityData.Builder(this);
|
||||
builder.define(DATA_SHARED_FLAGS_ID, (byte)0);
|
||||
builder.define(DATA_AIR_SUPPLY_ID, this.getMaxAirSupply());
|
||||
@@ -962,6 +978,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -984,6 +1000,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z);
|
||||
} else {
|
||||
if (type == MoverType.PISTON) {
|
||||
@ -512,7 +528,7 @@ index a63873a0fe4335813cafe84cae2b2030c8f0e627..f0c72465a71dc5a51c22af5e614af744
|
||||
movement = this.limitPistonMovement(movement);
|
||||
if (movement.equals(Vec3.ZERO)) {
|
||||
return;
|
||||
@@ -975,6 +995,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -997,6 +1017,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
this.stuckSpeedMultiplier = Vec3.ZERO;
|
||||
this.setDeltaMovement(Vec3.ZERO);
|
||||
}
|
||||
@ -527,10 +543,10 @@ index a63873a0fe4335813cafe84cae2b2030c8f0e627..f0c72465a71dc5a51c22af5e614af744
|
||||
movement = this.maybeBackOffFromEdge(movement, type);
|
||||
Vec3 vec3 = this.collide(movement);
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index 267544f50fafd914566df1c4b2327bc64d673165..3e8f4f3c3d43c6875108295187023c48eece2788 100644
|
||||
index 13cf40918ead3e2cb2699398ac659a3e1806294b..1ba342a1a60951f828034d3ed535b577b3990bf6 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3163,6 +3163,14 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
@@ -3215,6 +3215,14 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -546,10 +562,10 @@ index 267544f50fafd914566df1c4b2327bc64d673165..3e8f4f3c3d43c6875108295187023c48
|
||||
public void tick() {
|
||||
super.tick();
|
||||
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
|
||||
index 8f5c377540f83911c8d245fb00569f08dbc6a690..73ba442b9d39bc021cd5eb6c1c0f98aed94a5a02 100644
|
||||
index 3047763580fabd069db5e90a9a854396c6243763..0470c4bbf8be7e48ce8dfa4910c3b9f5ebb23360 100644
|
||||
--- a/net/minecraft/world/entity/Mob.java
|
||||
+++ b/net/minecraft/world/entity/Mob.java
|
||||
@@ -203,6 +203,19 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||
@@ -206,6 +206,19 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||
return this.lookControl;
|
||||
}
|
||||
|
||||
@ -570,7 +586,7 @@ index 8f5c377540f83911c8d245fb00569f08dbc6a690..73ba442b9d39bc021cd5eb6c1c0f98ae
|
||||
return this.getControlledVehicle() instanceof Mob mob ? mob.getMoveControl() : this.moveControl;
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/PathfinderMob.java b/net/minecraft/world/entity/PathfinderMob.java
|
||||
index 0caf50ec50f056b83a20bbc6a2fe0144593aef39..af59a700755654eb68d6bf57d0712c4a2ac6c09b 100644
|
||||
index 60cc5cf40967eee8988cda8a45ff098e66e8ddf2..741b5078ab9ee9b8463c61ab66ba9b5c9cda0974 100644
|
||||
--- a/net/minecraft/world/entity/PathfinderMob.java
|
||||
+++ b/net/minecraft/world/entity/PathfinderMob.java
|
||||
@@ -17,6 +17,8 @@ public abstract class PathfinderMob extends Mob {
|
||||
@ -583,10 +599,10 @@ index 0caf50ec50f056b83a20bbc6a2fe0144593aef39..af59a700755654eb68d6bf57d0712c4a
|
||||
return this.getWalkTargetValue(pos, this.level());
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/ai/goal/GoalSelector.java b/net/minecraft/world/entity/ai/goal/GoalSelector.java
|
||||
index 9338e63cc28413f5559bb0122ef5e04a84bd51d1..eeba224bd575451ba6023df65ef9d9b97f7f1c71 100644
|
||||
index d552e47aa38c61a8f78ed114a3433603c9658a24..674966c580220a4e0c83a628c763aaea8bfd0b1c 100644
|
||||
--- a/net/minecraft/world/entity/ai/goal/GoalSelector.java
|
||||
+++ b/net/minecraft/world/entity/ai/goal/GoalSelector.java
|
||||
@@ -25,6 +25,7 @@ public class GoalSelector {
|
||||
@@ -24,6 +24,7 @@ public class GoalSelector {
|
||||
private final Map<Goal.Flag, WrappedGoal> lockedFlags = new EnumMap<>(Goal.Flag.class);
|
||||
private final Set<WrappedGoal> availableGoals = new ObjectLinkedOpenHashSet<>();
|
||||
private final EnumSet<Goal.Flag> disabledFlags = EnumSet.noneOf(Goal.Flag.class);
|
||||
@ -594,7 +610,7 @@ index 9338e63cc28413f5559bb0122ef5e04a84bd51d1..eeba224bd575451ba6023df65ef9d9b9
|
||||
|
||||
public void addGoal(int priority, Goal goal) {
|
||||
this.availableGoals.add(new WrappedGoal(priority, goal));
|
||||
@@ -35,6 +36,22 @@ public class GoalSelector {
|
||||
@@ -33,6 +34,22 @@ public class GoalSelector {
|
||||
this.availableGoals.removeIf(wrappedGoal -> filter.test(wrappedGoal.getGoal()));
|
||||
}
|
||||
|
||||
@ -618,7 +634,7 @@ index 9338e63cc28413f5559bb0122ef5e04a84bd51d1..eeba224bd575451ba6023df65ef9d9b9
|
||||
for (WrappedGoal wrappedGoal : this.availableGoals) {
|
||||
if (wrappedGoal.getGoal() == goal && wrappedGoal.isRunning()) {
|
||||
diff --git a/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java b/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java
|
||||
index 789fea258d70e60d38271ebb31270562dc7eb3ab..d0ab3db7bbd2942db19f473474371b20ce822608 100644
|
||||
index 3f780276be6766ef253c50212e06fd93a96b0caa..7e70c7bee633c54497d1cd2854dd60f4fb5ff160 100644
|
||||
--- a/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java
|
||||
+++ b/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java
|
||||
@@ -23,6 +23,14 @@ public abstract class MoveToBlockGoal extends Goal {
|
||||
@ -638,17 +654,17 @@ index 789fea258d70e60d38271ebb31270562dc7eb3ab..d0ab3db7bbd2942db19f473474371b20
|
||||
this.mob = mob;
|
||||
@@ -113,6 +121,7 @@ public abstract class MoveToBlockGoal extends Goal {
|
||||
mutableBlockPos.setWithOffset(blockPos, i4, i2 - 1, i5);
|
||||
if (this.mob.isWithinRestriction(mutableBlockPos) && this.isValidTarget(this.mob.level(), mutableBlockPos)) {
|
||||
if (this.mob.isWithinHome(mutableBlockPos) && this.isValidTarget(this.mob.level(), mutableBlockPos)) {
|
||||
this.blockPos = mutableBlockPos;
|
||||
+ this.mob.movingTarget = mutableBlockPos == BlockPos.ZERO ? null : mutableBlockPos.immutable(); // Paper
|
||||
return true;
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java
|
||||
index ea3afc27600cde05a17197b071f14972d2c832e6..6c0ebfb2be4e8b884456a2aa3d5fdc87e45a0e3c 100644
|
||||
index 548d7c8dc517da6c4db86b11f579ae63e6db56cf..a29860af4c37b2b45df49f9ba18f7e38921dfb02 100644
|
||||
--- a/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -131,6 +131,29 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
||||
@@ -121,6 +121,29 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
||||
return 0.04;
|
||||
}
|
||||
|
||||
@ -679,10 +695,10 @@ index ea3afc27600cde05a17197b071f14972d2c832e6..6c0ebfb2be4e8b884456a2aa3d5fdc87
|
||||
public void tick() {
|
||||
if (this.getItem().isEmpty()) {
|
||||
diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java
|
||||
index 94032c60944f161519f0ddee69426cbfe3075170..e0e0d2ea7fc60e3142c675404d152eca60263240 100644
|
||||
index b0607f4a9b35570b319423c7876bb904d5154e8e..98c8653647dc52059d8becfe38a74d4e62edf08f 100644
|
||||
--- a/net/minecraft/world/entity/npc/Villager.java
|
||||
+++ b/net/minecraft/world/entity/npc/Villager.java
|
||||
@@ -268,11 +268,35 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
@@ -269,11 +269,35 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
return this.assignProfessionWhenSpawned;
|
||||
}
|
||||
|
||||
@ -719,7 +735,7 @@ index 94032c60944f161519f0ddee69426cbfe3075170..e0e0d2ea7fc60e3142c675404d152eca
|
||||
profilerFiller.pop();
|
||||
if (this.assignProfessionWhenSpawned) {
|
||||
this.assignProfessionWhenSpawned = false;
|
||||
@@ -296,7 +320,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
@@ -297,7 +321,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
this.lastTradedPlayer = null;
|
||||
}
|
||||
|
||||
@ -728,7 +744,7 @@ index 94032c60944f161519f0ddee69426cbfe3075170..e0e0d2ea7fc60e3142c675404d152eca
|
||||
Raid raidAt = level.getRaidAt(this.blockPosition());
|
||||
if (raidAt != null && raidAt.isActive() && !raidAt.isOver()) {
|
||||
level.broadcastEntityEvent(this, (byte)42);
|
||||
@@ -307,6 +331,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
@@ -308,6 +332,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
this.stopTrading();
|
||||
}
|
||||
|
||||
@ -758,10 +774,10 @@ index 1f22f44abb21d1ed9a4870f668779efb8fd9b295..91ead824718eeea2afba3bc0ef619b8a
|
||||
public void tick() {
|
||||
super.tick();
|
||||
diff --git a/net/minecraft/world/entity/projectile/FireworkRocketEntity.java b/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
|
||||
index dcb7714b2edeab8cfb0358929d07bd04cead26bf..e0e193078e550225e163149638bf9e053c0531f8 100644
|
||||
index 7d5c6eec8e7c2448a3502255135dd9154b6ed2d8..d8dc196ef92e97f831cf97cd1536a46f81f9d5d1 100644
|
||||
--- a/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
|
||||
+++ b/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
|
||||
@@ -109,6 +109,21 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier {
|
||||
@@ -107,6 +107,21 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier {
|
||||
return super.shouldRender(x, y, z) && !this.isAttachedToEntity();
|
||||
}
|
||||
|
||||
@ -784,10 +800,10 @@ index dcb7714b2edeab8cfb0358929d07bd04cead26bf..e0e193078e550225e163149638bf9e05
|
||||
public void tick() {
|
||||
super.tick();
|
||||
diff --git a/net/minecraft/world/entity/vehicle/MinecartHopper.java b/net/minecraft/world/entity/vehicle/MinecartHopper.java
|
||||
index 6162415095b030b4cc47364c56fa66236b3b0535..a56d9cdeb6589a053ffaaf2cd599a98ae0a0989a 100644
|
||||
index 52acc72841f0c6980f5f3f8ef21d0b29dd472ce3..41a6ec508a10a49a37539d2f10171d15c233b280 100644
|
||||
--- a/net/minecraft/world/entity/vehicle/MinecartHopper.java
|
||||
+++ b/net/minecraft/world/entity/vehicle/MinecartHopper.java
|
||||
@@ -48,6 +48,7 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper
|
||||
@@ -49,6 +49,7 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper
|
||||
if (flag != this.isEnabled()) {
|
||||
this.setEnabled(flag);
|
||||
}
|
||||
@ -795,7 +811,7 @@ index 6162415095b030b4cc47364c56fa66236b3b0535..a56d9cdeb6589a053ffaaf2cd599a98a
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
@@ -101,11 +102,13 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper
|
||||
@@ -102,11 +103,13 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper
|
||||
|
||||
public boolean suckInItems() {
|
||||
if (HopperBlockEntity.suckInItems(this.level(), this)) {
|
||||
@ -809,7 +825,7 @@ index 6162415095b030b4cc47364c56fa66236b3b0535..a56d9cdeb6589a053ffaaf2cd599a98a
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -140,4 +143,11 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper
|
||||
@@ -141,4 +144,11 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper
|
||||
public AbstractContainerMenu createMenu(int id, Inventory playerInventory) {
|
||||
return new HopperMenu(id, playerInventory, this);
|
||||
}
|
||||
@ -822,7 +838,7 @@ index 6162415095b030b4cc47364c56fa66236b3b0535..a56d9cdeb6589a053ffaaf2cd599a98a
|
||||
+
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index fff4914de57dff26f66259a145d662ff5c96d840..1bb40f18b671d63719d96a58ff283767c2cfe383 100644
|
||||
index d26e4d85d8fd8bd4f0c7de30b50a2ce370b37bf5..bab28e7afb7b1249d40631aabff16fc18cf95ea0 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -143,6 +143,12 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
|
||||
@ -839,10 +855,10 @@ index fff4914de57dff26f66259a145d662ff5c96d840..1bb40f18b671d63719d96a58ff283767
|
||||
public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot
|
||||
// Paper start - add paper world config
|
||||
diff --git a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
||||
index f8d10be7a0aa7f66f05126e75187025c040e3494..1669b76800756000a2f620610b3c8c8b6c48dd4a 100644
|
||||
index ba757b3accf0ee7e57f82507a6c04b90ae850d55..f1ce4cff1c03a0037ade2c8ef989cf327c973a7e 100644
|
||||
--- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
||||
@@ -153,6 +153,10 @@ public class PistonMovingBlockEntity extends BlockEntity {
|
||||
@@ -152,6 +152,10 @@ public class PistonMovingBlockEntity extends BlockEntity {
|
||||
}
|
||||
|
||||
entity.setDeltaMovement(d1, d2, d3);
|
||||
|
||||
@ -5,7 +5,7 @@ Subject: [PATCH] Anti-Xray
|
||||
|
||||
|
||||
diff --git a/io/papermc/paper/FeatureHooks.java b/io/papermc/paper/FeatureHooks.java
|
||||
index b9a838d638571bca1d00a620cedf169a3fa87e9d..329e9562e9c2b25228b04c21ff7353d2d8d6e5f6 100644
|
||||
index dce30842f6abab549f3abc25226604bb70ad0624..0a80ab83ca69b8b51fb1bb8c12ee6fcf439a3ac4 100644
|
||||
--- a/io/papermc/paper/FeatureHooks.java
|
||||
+++ b/io/papermc/paper/FeatureHooks.java
|
||||
@@ -37,20 +37,25 @@ public final class FeatureHooks {
|
||||
@ -39,7 +39,7 @@ index b9a838d638571bca1d00a620cedf169a3fa87e9d..329e9562e9c2b25228b04c21ff7353d2
|
||||
|
||||
public static Set<Long> getSentChunkKeys(final ServerPlayer player) {
|
||||
diff --git a/net/minecraft/network/protocol/game/ClientboundChunksBiomesPacket.java b/net/minecraft/network/protocol/game/ClientboundChunksBiomesPacket.java
|
||||
index d4872b7f4e9591b3b1c67406312905851303f521..cb41460e94161675e2ab43f4b1b5286ee38e2e13 100644
|
||||
index c9086bca5cbb780fd586f667e31a8fe1400ae58a..f828d07018d9a17aaa0142aac67ebed58dd84c3e 100644
|
||||
--- a/net/minecraft/network/protocol/game/ClientboundChunksBiomesPacket.java
|
||||
+++ b/net/minecraft/network/protocol/game/ClientboundChunksBiomesPacket.java
|
||||
@@ -70,8 +70,10 @@ public record ClientboundChunksBiomesPacket(List<ClientboundChunksBiomesPacket.C
|
||||
@ -52,10 +52,10 @@ index d4872b7f4e9591b3b1c67406312905851303f521..cb41460e94161675e2ab43f4b1b5286e
|
||||
+ levelChunkSection.getBiomes().write(buffer, null, chunkSectionIndex); // Paper - Anti-Xray
|
||||
+ chunkSectionIndex++; // Paper - Anti-Xray
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer.writerIndex() != buffer.capacity()) {
|
||||
diff --git a/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java b/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
index 89761bd368d75b8fb84f850fb3f8162fa280e236..272da41db7ce4619a8e459a2f0a2221e42f58a40 100644
|
||||
index de234f220ba09ad9b5e0c8215b49d20ca51d0ac7..83c4b454472714de6ebf99cd4e50867920d07509 100644
|
||||
--- a/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
+++ b/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
@@ -33,13 +33,23 @@ public class ClientboundLevelChunkPacketData {
|
||||
@ -100,8 +100,8 @@ index 89761bd368d75b8fb84f850fb3f8162fa280e236..272da41db7ce4619a8e459a2f0a2221e
|
||||
+ chunkSectionIndex++;
|
||||
+ // Paper end - Anti-Xray - Add chunk packet info
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer.writerIndex() != buffer.capacity()) {
|
||||
diff --git a/net/minecraft/network/protocol/game/ClientboundLevelChunkWithLightPacket.java b/net/minecraft/network/protocol/game/ClientboundLevelChunkWithLightPacket.java
|
||||
index 3a384175f8e7f204234bbaf3081bdc20c47a0d4b..5699bc15eba92e22433a20cb8326b59f2ebd3036 100644
|
||||
--- a/net/minecraft/network/protocol/game/ClientboundLevelChunkWithLightPacket.java
|
||||
@ -143,10 +143,10 @@ index 3a384175f8e7f204234bbaf3081bdc20c47a0d4b..5699bc15eba92e22433a20cb8326b59f
|
||||
|
||||
private ClientboundLevelChunkWithLightPacket(RegistryFriendlyByteBuf buffer) {
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 6b67cc939851745718f919488c997eb6719a16fc..085040aa98704f2874bcd95b751b0a81dcdb15ad 100644
|
||||
index e6f958b6128213fb9577406c6495148dccac40ca..49008b4cbaead8a66a93d2b0d4b50b335a6c3eed 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -343,7 +343,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -346,7 +346,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
org.bukkit.generator.BiomeProvider biomeProvider // CraftBukkit
|
||||
) {
|
||||
// CraftBukkit start
|
||||
@ -156,7 +156,7 @@ index 6b67cc939851745718f919488c997eb6719a16fc..085040aa98704f2874bcd95b751b0a81
|
||||
this.levelStorageAccess = levelStorageAccess;
|
||||
this.uuid = org.bukkit.craftbukkit.util.WorldUUID.getOrCreate(levelStorageAccess.levelDirectory.path().toFile());
|
||||
diff --git a/net/minecraft/server/level/ServerPlayerGameMode.java b/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
index b5378d6d73b6dab56bf664024f3f82496e9a9487..b604cba2490a747661d6819251bc3b9a1d35c7d4 100644
|
||||
index b29ecfcc07304c1ee3d77cd431db0889ebc7d6b1..6734756d7a51e635a50a47577f9e6b6f8111db51 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
@@ -296,6 +296,7 @@ public class ServerPlayerGameMode {
|
||||
@ -168,7 +168,7 @@ index b5378d6d73b6dab56bf664024f3f82496e9a9487..b604cba2490a747661d6819251bc3b9a
|
||||
|
||||
public void destroyAndAck(BlockPos pos, int sequence, String message) {
|
||||
diff --git a/net/minecraft/server/network/PlayerChunkSender.java b/net/minecraft/server/network/PlayerChunkSender.java
|
||||
index 342bc843c384761e883de861044f4f8930ae8763..14878690a88fd4de3e2c127086607e6c819c636c 100644
|
||||
index 8cd7363704d4532c926dbf4778eb4dfec5fdf8bc..0376a10ee0544b13e8fd629a7b13f78811e57a30 100644
|
||||
--- a/net/minecraft/server/network/PlayerChunkSender.java
|
||||
+++ b/net/minecraft/server/network/PlayerChunkSender.java
|
||||
@@ -78,8 +78,11 @@ public class PlayerChunkSender {
|
||||
@ -186,20 +186,20 @@ index 342bc843c384761e883de861044f4f8930ae8763..14878690a88fd4de3e2c127086607e6c
|
||||
if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
new io.papermc.paper.event.packet.PlayerChunkLoadEvent(new org.bukkit.craftbukkit.CraftChunk(chunk), packetListener.getPlayer().getBukkitEntity()).callEvent();
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index 9b2ee3e16e2c443e8ff03faec59dd55d729e9274..5ec9e3b37e575e9805bf9f0ce5cae5c1284461d8 100644
|
||||
index b595fc3bd844eaf2a56f70f166523ee6254386b6..891d3e13057c6034c59a78e594935c433921de04 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -407,7 +407,7 @@ public abstract class PlayerList {
|
||||
@@ -408,7 +408,7 @@ public abstract class PlayerList {
|
||||
.getOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS);
|
||||
player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket(
|
||||
player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket(
|
||||
new net.minecraft.world.level.chunk.EmptyLevelChunk(serverLevel, player.chunkPosition(), plains),
|
||||
- serverLevel.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null)
|
||||
+ serverLevel.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null, true) // Paper - Anti-Xray
|
||||
);
|
||||
}
|
||||
// Paper end - Send empty chunk
|
||||
);
|
||||
}
|
||||
// Paper end - Send empty chunk
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 1bb40f18b671d63719d96a58ff283767c2cfe383..ba50f21707a69bbf720345996d7c83d2064e5246 100644
|
||||
index 980eaba27ce2616c1573a4760cf4acc2dd251190..1eb8cb187d33510a4e99d229e721a2e7db4012ad 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -132,6 +132,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
|
||||
@ -237,10 +237,10 @@ index 1bb40f18b671d63719d96a58ff283767c2cfe383..ba50f21707a69bbf720345996d7c83d2
|
||||
if (blockState == null) {
|
||||
// CraftBukkit start - remove blockstate if failed (or the same)
|
||||
diff --git a/net/minecraft/world/level/chunk/ChunkAccess.java b/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
index c378f9e226df80ab0d4ebd06ae54ce556d0d94e7..97231db28146df56c727c9765f36277634d59a64 100644
|
||||
index f98ee299f5900b0a66c447d7970bd16a7ced1086..d1ae452f0aa96c36afe8b7ecddd3e06b06165878 100644
|
||||
--- a/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
+++ b/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
@@ -114,14 +114,14 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
|
||||
@@ -115,14 +115,14 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
|
||||
}
|
||||
}
|
||||
|
||||
@ -259,10 +259,10 @@ index c378f9e226df80ab0d4ebd06ae54ce556d0d94e7..97231db28146df56c727c9765f362776
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 8fa871512ad52c345f15b1f5fb1baf54bb2ec93b..08e2442f6965cc6eaab67bdf9340a5152c08db2a 100644
|
||||
index 1e60b295f8fa672ecee96a71fd1fea14339b7054..6f19586b4a39541c0fb895a18a0a4fd9b5da504c 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -110,7 +110,7 @@ public class LevelChunk extends ChunkAccess {
|
||||
@@ -112,7 +112,7 @@ public class LevelChunk extends ChunkAccess {
|
||||
@Nullable LevelChunk.PostLoadProcessor postLoad,
|
||||
@Nullable BlendingData blendingData
|
||||
) {
|
||||
@ -313,10 +313,10 @@ index 2399a0f8839c0925a9923bae87362c2c9a217197..1aa4e39431a93a7789b74a2e3476a3e4
|
||||
|
||||
public int getSerializedSize() {
|
||||
diff --git a/net/minecraft/world/level/chunk/PalettedContainer.java b/net/minecraft/world/level/chunk/PalettedContainer.java
|
||||
index 5a3ed1c2dd22434d96947580c4dff28a95eb8252..1491401ec94038450ea5eeb589fc33a336a3ae55 100644
|
||||
index cd2b1240f13acaaecbb8e6d0f7f8b326ab24b5b0..9b0f17841230640f532ac33bb86e6585e88b5a57 100644
|
||||
--- a/net/minecraft/world/level/chunk/PalettedContainer.java
|
||||
+++ b/net/minecraft/world/level/chunk/PalettedContainer.java
|
||||
@@ -28,6 +28,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
@@ -27,6 +27,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
private static final int MIN_PALETTE_BITS = 0;
|
||||
private final PaletteResize<T> dummyPaletteResize = (bits, objectAdded) -> 0;
|
||||
public final IdMap<T> registry;
|
||||
@ -324,7 +324,7 @@ index 5a3ed1c2dd22434d96947580c4dff28a95eb8252..1491401ec94038450ea5eeb589fc33a3
|
||||
private volatile PalettedContainer.Data<T> data;
|
||||
private final PalettedContainer.Strategy strategy;
|
||||
//private final ThreadingDetector threadingDetector = new ThreadingDetector("PalettedContainer"); // Paper - unused
|
||||
@@ -40,13 +41,21 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
@@ -39,13 +40,21 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
// this.threadingDetector.checkAndUnlock(); // Paper - disable this - use proper synchronization
|
||||
}
|
||||
|
||||
@ -348,7 +348,7 @@ index 5a3ed1c2dd22434d96947580c4dff28a95eb8252..1491401ec94038450ea5eeb589fc33a3
|
||||
.map(container -> (PalettedContainerRO<T>)container);
|
||||
return codec(registry, codec, strategy, value, unpacker);
|
||||
}
|
||||
@@ -66,27 +75,66 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
@@ -65,27 +74,66 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
);
|
||||
}
|
||||
|
||||
@ -418,7 +418,7 @@ index 5a3ed1c2dd22434d96947580c4dff28a95eb8252..1491401ec94038450ea5eeb589fc33a3
|
||||
this.strategy = strategy;
|
||||
this.registry = registry;
|
||||
this.data = this.createOrReuseData(null, 0);
|
||||
@@ -101,11 +149,30 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
@@ -100,11 +148,30 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
@Override
|
||||
public synchronized int onResize(int bits, T objectAdded) { // Paper - synchronize
|
||||
PalettedContainer.Data<T> data = this.data;
|
||||
@ -450,7 +450,7 @@ index 5a3ed1c2dd22434d96947580c4dff28a95eb8252..1491401ec94038450ea5eeb589fc33a3
|
||||
|
||||
public synchronized T getAndSet(int x, int y, int z, T state) { // Paper - synchronize
|
||||
this.acquire();
|
||||
@@ -172,24 +239,35 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
@@ -171,24 +238,35 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
data.palette.read(buffer);
|
||||
buffer.readFixedSizeLongArray(data.storage.getRaw());
|
||||
this.data = data;
|
||||
@ -489,7 +489,7 @@ index 5a3ed1c2dd22434d96947580c4dff28a95eb8252..1491401ec94038450ea5eeb589fc33a3
|
||||
) {
|
||||
List<T> list = packedData.paletteEntries();
|
||||
int size = strategy.size();
|
||||
@@ -222,7 +300,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
@@ -221,7 +299,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
}
|
||||
}
|
||||
|
||||
@ -498,7 +498,7 @@ index 5a3ed1c2dd22434d96947580c4dff28a95eb8252..1491401ec94038450ea5eeb589fc33a3
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -280,12 +358,12 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
@@ -279,12 +357,12 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
|
||||
@Override
|
||||
public PalettedContainer<T> copy() {
|
||||
@ -513,8 +513,8 @@ index 5a3ed1c2dd22434d96947580c4dff28a95eb8252..1491401ec94038450ea5eeb589fc33a3
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -324,9 +402,16 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
return 1 + this.palette.getSerializedSize() + VarInt.getByteSize(this.storage.getRaw().length) + this.storage.getRaw().length * 8;
|
||||
@@ -323,9 +401,16 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
return 1 + this.palette.getSerializedSize() + this.storage.getRaw().length * 8;
|
||||
}
|
||||
|
||||
- public void write(FriendlyByteBuf buffer) {
|
||||
@ -548,10 +548,10 @@ index bfbb1a2bb4abbb369a24f2f01439e9ea3e16794b..8d6ed8be4d93f7d4e6ea80c351020d88
|
||||
int getSerializedSize();
|
||||
|
||||
diff --git a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||
index 8efb5148a22b57ed090fb8fd20dd642223b3fb95..58bc96235f0149ea868da3bc3d20472f96d5f6ec 100644
|
||||
index e846bda9517f3325f0d343758d3235382bb8980d..15417fab103feec3c1f7d5bd5b332e89d3ace3f5 100644
|
||||
--- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||
+++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||
@@ -94,7 +94,7 @@ public record SerializableChunkData(
|
||||
@@ -96,7 +96,7 @@ public record SerializableChunkData(
|
||||
, @Nullable net.minecraft.nbt.Tag persistentDataContainer // CraftBukkit - persistentDataContainer
|
||||
) {
|
||||
public static final Codec<PalettedContainer<BlockState>> BLOCK_STATE_CODEC = PalettedContainer.codecRW(
|
||||
@ -560,7 +560,7 @@ index 8efb5148a22b57ed090fb8fd20dd642223b3fb95..58bc96235f0149ea868da3bc3d20472f
|
||||
);
|
||||
private static final Codec<List<SavedTick<Block>>> BLOCK_TICKS_CODEC = SavedTick.codec(BuiltInRegistries.BLOCK.byNameCodec()).listOf();
|
||||
private static final Codec<List<SavedTick<Fluid>>> FLUID_TICKS_CODEC = SavedTick.codec(BuiltInRegistries.FLUID.byNameCodec()).listOf();
|
||||
@@ -130,6 +130,7 @@ public record SerializableChunkData(
|
||||
@@ -132,6 +132,7 @@ public record SerializableChunkData(
|
||||
|
||||
@Nullable
|
||||
public static SerializableChunkData parse(LevelHeightAccessor levelHeightAccessor, RegistryAccess registries, CompoundTag tag) {
|
||||
@ -568,7 +568,7 @@ index 8efb5148a22b57ed090fb8fd20dd642223b3fb95..58bc96235f0149ea868da3bc3d20472f
|
||||
if (tag.getString("Status").isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -190,15 +191,17 @@ public record SerializableChunkData(
|
||||
@@ -192,15 +193,17 @@ public record SerializableChunkData(
|
||||
int byteOr = compoundTag.getByteOr("Y", (byte)0);
|
||||
LevelChunkSection levelChunkSection;
|
||||
if (byteOr >= levelHeightAccessor.getMinSectionY() && byteOr <= levelHeightAccessor.getMaxSectionY()) {
|
||||
@ -588,7 +588,7 @@ index 8efb5148a22b57ed090fb8fd20dd642223b3fb95..58bc96235f0149ea868da3bc3d20472f
|
||||
)
|
||||
);
|
||||
PalettedContainer<Holder<Biome>> palettedContainerRo = compoundTag.getCompound("biomes") // CraftBukkit - read/write
|
||||
@@ -209,7 +212,7 @@ public record SerializableChunkData(
|
||||
@@ -211,7 +214,7 @@ public record SerializableChunkData(
|
||||
)
|
||||
.orElseGet(
|
||||
() -> new PalettedContainer<>(
|
||||
@ -597,7 +597,7 @@ index 8efb5148a22b57ed090fb8fd20dd642223b3fb95..58bc96235f0149ea868da3bc3d20472f
|
||||
)
|
||||
);
|
||||
levelChunkSection = new LevelChunkSection(palettedContainer, palettedContainerRo);
|
||||
@@ -382,7 +385,7 @@ public record SerializableChunkData(
|
||||
@@ -384,7 +387,7 @@ public record SerializableChunkData(
|
||||
|
||||
// CraftBukkit start - read/write
|
||||
private static Codec<PalettedContainer<Holder<Biome>>> makeBiomeCodecRW(Registry<Biome> biomeRegistry) {
|
||||
|
||||
@ -269,10 +269,10 @@ index bc674b08a41d5529fe06c6d3f077051cf4138f73..ea8a894158c44c2e7943dea43ecd8e1f
|
||||
+ // Paper end - Use Velocity cipher
|
||||
}
|
||||
diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java
|
||||
index 2040b9555c430420a8a8697cc131d42eafb96fa1..4ed9611994c5c8da01fede690197527c5b3a5731 100644
|
||||
index 235a076f982247552fef6d86d7e1b141eb8c72b5..34524dc5a503bebcec99ada0d9560d6f4df48cdf 100644
|
||||
--- a/net/minecraft/network/Connection.java
|
||||
+++ b/net/minecraft/network/Connection.java
|
||||
@@ -772,11 +772,22 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -762,11 +762,22 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
return connection;
|
||||
}
|
||||
|
||||
@ -299,7 +299,7 @@ index 2040b9555c430420a8a8697cc131d42eafb96fa1..4ed9611994c5c8da01fede690197527c
|
||||
|
||||
public boolean isEncrypted() {
|
||||
return this.encrypted;
|
||||
@@ -815,16 +826,17 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -805,16 +816,17 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
// Paper end - add proper async disconnect
|
||||
public void setupCompression(int threshold, boolean validateDecompressed) {
|
||||
if (threshold >= 0) {
|
||||
|
||||
@ -14,10 +14,10 @@ movement will load only the chunk the player enters anyways and avoids loading
|
||||
massive amounts of surrounding chunks due to large AABB lookups.
|
||||
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index a8eaccde3ec9ed912cbc6df0b29e9f8136a46578..0f6ca6ef161ac2934ba761a1eca3215290c7262b 100644
|
||||
index 7453ddb09f349b7836f966573e4933646a75cba6..58eda0d6426f30cda604f4120f1ddb012316c108 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -223,6 +223,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -229,6 +229,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
// Paper end - Share random for entities to make them more random
|
||||
public @Nullable org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason
|
||||
|
||||
@ -76,7 +76,7 @@ index ed6e4f9fd0c7ad1219e66bc1cb4038191dd6edd8..45a20dbb935b12d429153463dba5d6fd
|
||||
&& (nextType != 2 || blockState.is(Blocks.MOVING_PISTON))) {
|
||||
VoxelShape collisionShape = this.context.getCollisionShape(blockState, this.collisionGetter, this.pos);
|
||||
diff --git a/net/minecraft/world/level/CollisionGetter.java b/net/minecraft/world/level/CollisionGetter.java
|
||||
index 79af1e4dd1f84580e509ac3e9a77bcd5531c8da6..a031d39854eb049a701f3de9e11c73419883d5ca 100644
|
||||
index 8956e5d66481d8ca874999df8f38eb28651362db..056005f0728ba14c9d0dd9dd16400a35a9656243 100644
|
||||
--- a/net/minecraft/world/level/CollisionGetter.java
|
||||
+++ b/net/minecraft/world/level/CollisionGetter.java
|
||||
@@ -50,11 +50,13 @@ public interface CollisionGetter extends BlockGetter {
|
||||
|
||||
@ -7,7 +7,7 @@ Optimise the stream.anyMatch statement to move to a bitset
|
||||
where we can replace the call with a single bitwise operation.
|
||||
|
||||
diff --git a/net/minecraft/world/entity/ai/goal/Goal.java b/net/minecraft/world/entity/ai/goal/Goal.java
|
||||
index d4f8387254a65b25fc808932a069298d0f8da091..5f5bf0e710ecff09a571091e5a923332be70cb74 100644
|
||||
index a66c86066ca2eda10f0ef62e5197a765a994f250..f54bbe2e65b18f214266769c7a64144baafa9a58 100644
|
||||
--- a/net/minecraft/world/entity/ai/goal/Goal.java
|
||||
+++ b/net/minecraft/world/entity/ai/goal/Goal.java
|
||||
@@ -7,7 +7,15 @@ import net.minecraft.world.entity.Entity;
|
||||
@ -69,10 +69,10 @@ index d4f8387254a65b25fc808932a069298d0f8da091..5f5bf0e710ecff09a571091e5a923332
|
||||
// Paper end - Mob Goal API
|
||||
|
||||
diff --git a/net/minecraft/world/entity/ai/goal/GoalSelector.java b/net/minecraft/world/entity/ai/goal/GoalSelector.java
|
||||
index eeba224bd575451ba6023df65ef9d9b97f7f1c71..a927c2790c8ab9ccaa7161b970e10b0b44817dd8 100644
|
||||
index 674966c580220a4e0c83a628c763aaea8bfd0b1c..859b859d29b637200cf7c9a0bd52d9f712413e3d 100644
|
||||
--- a/net/minecraft/world/entity/ai/goal/GoalSelector.java
|
||||
+++ b/net/minecraft/world/entity/ai/goal/GoalSelector.java
|
||||
@@ -24,7 +24,8 @@ public class GoalSelector {
|
||||
@@ -23,7 +23,8 @@ public class GoalSelector {
|
||||
};
|
||||
private final Map<Goal.Flag, WrappedGoal> lockedFlags = new EnumMap<>(Goal.Flag.class);
|
||||
private final Set<WrappedGoal> availableGoals = new ObjectLinkedOpenHashSet<>();
|
||||
@ -82,7 +82,7 @@ index eeba224bd575451ba6023df65ef9d9b97f7f1c71..a927c2790c8ab9ccaa7161b970e10b0b
|
||||
private int curRate; // Paper - EAR 2
|
||||
|
||||
public void addGoal(int priority, Goal goal) {
|
||||
@@ -62,18 +63,18 @@ public class GoalSelector {
|
||||
@@ -60,18 +61,18 @@ public class GoalSelector {
|
||||
this.availableGoals.removeIf(wrappedGoal1 -> wrappedGoal1.getGoal() == goal);
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ index eeba224bd575451ba6023df65ef9d9b97f7f1c71..a927c2790c8ab9ccaa7161b970e10b0b
|
||||
if (!flag.getOrDefault(flag1, NO_GOAL).canBeReplacedBy(goal)) {
|
||||
return false;
|
||||
}
|
||||
@@ -87,7 +88,7 @@ public class GoalSelector {
|
||||
@@ -85,7 +86,7 @@ public class GoalSelector {
|
||||
profilerFiller.push("goalCleanup");
|
||||
|
||||
for (WrappedGoal wrappedGoal : this.availableGoals) {
|
||||
@ -119,7 +119,7 @@ index eeba224bd575451ba6023df65ef9d9b97f7f1c71..a927c2790c8ab9ccaa7161b970e10b0b
|
||||
wrappedGoal.stop();
|
||||
}
|
||||
}
|
||||
@@ -97,11 +98,14 @@ public class GoalSelector {
|
||||
@@ -95,11 +96,14 @@ public class GoalSelector {
|
||||
profilerFiller.push("goalUpdate");
|
||||
|
||||
for (WrappedGoal wrappedGoalx : this.availableGoals) {
|
||||
@ -139,7 +139,7 @@ index eeba224bd575451ba6023df65ef9d9b97f7f1c71..a927c2790c8ab9ccaa7161b970e10b0b
|
||||
WrappedGoal wrappedGoal1 = this.lockedFlags.getOrDefault(flag, NO_GOAL);
|
||||
wrappedGoal1.stop();
|
||||
this.lockedFlags.put(flag, wrappedGoalx);
|
||||
@@ -133,11 +137,11 @@ public class GoalSelector {
|
||||
@@ -131,11 +135,11 @@ public class GoalSelector {
|
||||
}
|
||||
|
||||
public void disableControlFlag(Goal.Flag flag) {
|
||||
|
||||
@ -9,7 +9,7 @@ creating too large of a packet to sed.
|
||||
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
|
||||
diff --git a/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java b/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
index 272da41db7ce4619a8e459a2f0a2221e42f58a40..526c117e0d53ad527eb610c79cdc46ec16b18c0c 100644
|
||||
index 83c4b454472714de6ebf99cd4e50867920d07509..9f6d7c5dc0e591488a8a3763d8a1f1b3671d5299 100644
|
||||
--- a/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
+++ b/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
@@ -32,6 +32,14 @@ public class ClientboundLevelChunkPacketData {
|
||||
|
||||
@ -7,7 +7,7 @@ bypass the need to get a player chunk, then get the either,
|
||||
then unwrap it...
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
||||
index 006d8abe66b2d66740b984d8ff7f56a41b9929f7..52104bcd74107bb9a475109230ca85dd2eba5b06 100644
|
||||
index b805b9964ca5bf6b3d13dae615cb49177d43ded3..17ec8224bf5c2eebc7d6bcbe25e275be4bdb0a45 100644
|
||||
--- a/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -224,6 +224,12 @@ public class ServerChunkCache extends ChunkSource {
|
||||
|
||||
32538
paper-server/patches/features/0015-Rewrite-dataconverter-system.patch
Normal file
32538
paper-server/patches/features/0015-Rewrite-dataconverter-system.patch
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -48,7 +48,7 @@ index db31989ebe3d7021cfd2311439e9a00f819b0841..1373977b339405ef59bb3ea03d195285
|
||||
serverEntity.getLastSentYRot(),
|
||||
entity.getType(),
|
||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||
index 1463c31ba980ab0eb2174e3e891d1423a505e9dc..886340232b58afd59caa6df29e211589a7781070 100644
|
||||
index 61692c07dfb75ca0c19f603aafc96c0817861107..56a1d081a28e8b38384cfca732b103462693e322 100644
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1278,6 +1278,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@ -60,7 +60,7 @@ index 1463c31ba980ab0eb2174e3e891d1423a505e9dc..886340232b58afd59caa6df29e211589
|
||||
} else if (this.seenBy.remove(player.connection)) {
|
||||
this.serverEntity.removePairing(player);
|
||||
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
|
||||
index a1ae77b70f69852d9e4332bf1cb3409c33b21de0..b118e91f1e0b5a8b8c0b2a4a32faabc5a34a5954 100644
|
||||
index 3d5a8163a7dd78a195b77c4aaebdee2dc3dee64b..e96d4dee14c05f2fa329bfb1588ec795d4e3d730 100644
|
||||
--- a/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -103,6 +103,13 @@ public class ServerEntity {
|
||||
@ -90,12 +90,12 @@ index a1ae77b70f69852d9e4332bf1cb3409c33b21de0..b118e91f1e0b5a8b8c0b2a4a32faabc5
|
||||
long l1 = this.positionCodec.encodeY(vec3);
|
||||
long l2 = this.positionCodec.encodeZ(vec3);
|
||||
boolean flag5 = l < -32768L || l > 32767L || l1 < -32768L || l1 > 32767L || l2 < -32768L || l2 > 32767L;
|
||||
- if (flag5 || this.teleportDelay > 400 || this.wasRiding || this.wasOnGround != this.entity.onGround()) {
|
||||
+ if (this.forceStateResync || flag5 || this.teleportDelay > 400 || this.wasRiding || this.wasOnGround != this.entity.onGround()) { // Paper - fix desync when a player is added to the tracker
|
||||
this.wasOnGround = this.entity.onGround();
|
||||
this.teleportDelay = 0;
|
||||
packet = ClientboundEntityPositionSyncPacket.of(this.entity);
|
||||
@@ -241,6 +248,7 @@ public class ServerEntity {
|
||||
- if (this.entity.getRequiresPrecisePosition()
|
||||
+ if (this.forceStateResync || this.entity.getRequiresPrecisePosition() // Paper - fix desync when a player is added to the tracker
|
||||
|| flag5
|
||||
|| this.teleportDelay > 400
|
||||
|| this.wasRiding
|
||||
@@ -245,6 +252,7 @@ public class ServerEntity {
|
||||
}
|
||||
|
||||
this.entity.hasImpulse = false;
|
||||
@ -2326,10 +2326,10 @@ index 0000000000000000000000000000000000000000..298076a0db4e6ee6e4775ac43bf749d9
|
||||
+ }
|
||||
+}
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 8afe96bfdc37e57129f1bb4af5b6d5cc22c11aee..32db2b9e375c12cbf7abab69cc01e8ac2c7c3b6e 100644
|
||||
index f9c96bbdc54e68b9216b7f8662bfae03012d2866..34b7769663e235b93c6388ab0c92c00f0297e42f 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -210,6 +210,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -213,6 +213,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
public final java.util.UUID uuid;
|
||||
public boolean hasPhysicsEvent = true; // Paper - BlockPhysicsEvent
|
||||
public boolean hasEntityMoveEvent; // Paper - Add EntityMoveEvent
|
||||
@ -2337,7 +2337,7 @@ index 8afe96bfdc37e57129f1bb4af5b6d5cc22c11aee..32db2b9e375c12cbf7abab69cc01e8ac
|
||||
|
||||
@Override
|
||||
public @Nullable LevelChunk getChunkIfLoaded(int x, int z) {
|
||||
@@ -2552,6 +2553,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -2591,6 +2592,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
return this.chunkSource.getGenerator().getSeaLevel();
|
||||
}
|
||||
|
||||
@ -2352,10 +2352,10 @@ index 8afe96bfdc37e57129f1bb4af5b6d5cc22c11aee..32db2b9e375c12cbf7abab69cc01e8ac
|
||||
@Override
|
||||
public void onCreated(Entity entity) {
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index eb4d03cfdb34243901cfba832d35559d5be9e876..013ed7dbe2309f562f63e66203179a90566e8115 100644
|
||||
index f286dd9996590e5d448ca809c34b6f640203e274..c41df4b1fff1f65532256e835dc30fadbb4f8c8b 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -2096,6 +2096,17 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
|
||||
@@ -2093,6 +2093,17 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -204,10 +204,10 @@ index 6d3e3ec045d5b15a435f7217369968b33e082724..b7a3758af337270737041f84d10eb437
|
||||
int i = this.inventory.findSlotMatchingCraftingIngredient(item, item1);
|
||||
if (i == -1) {
|
||||
diff --git a/net/minecraft/world/entity/player/Inventory.java b/net/minecraft/world/entity/player/Inventory.java
|
||||
index e25e0bd410f8822cb9a1118b39a786f44aabef7b..d9cb4f0ed0c4f63362c837aeef3c4194911455c9 100644
|
||||
index 46408ccee787b45e7957c12bfe426cb391f6e173..a6bb436dc80daf6901dc027a6011ead4b3ed27e2 100644
|
||||
--- a/net/minecraft/world/entity/player/Inventory.java
|
||||
+++ b/net/minecraft/world/entity/player/Inventory.java
|
||||
@@ -234,12 +234,12 @@ public class Inventory implements Container, Nameable {
|
||||
@@ -251,12 +251,12 @@ public class Inventory implements Container, Nameable {
|
||||
return !stack.isDamaged() && !stack.isEnchanted() && !stack.has(DataComponents.CUSTOM_NAME);
|
||||
}
|
||||
|
||||
@ -1,81 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Wed, 18 Nov 2020 20:52:25 -0800
|
||||
Subject: [PATCH] Entity load/save limit per chunk
|
||||
|
||||
Adds a config option to limit the number of entities saved and loaded
|
||||
to a chunk. The default values of -1 disable the limit. Although
|
||||
defaults are only included for certain entites, this allows setting
|
||||
limits for any entity type.
|
||||
|
||||
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
|
||||
index 1c82dcd38f789707e15e8cbec72ef9cdc7efdf56..ba20e87d2105ce53cdaf4049de2388d05fcd1b56 100644
|
||||
--- a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
|
||||
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
|
||||
@@ -104,7 +104,18 @@ public final class ChunkEntitySlices {
|
||||
}
|
||||
|
||||
final ListTag entitiesTag = new ListTag();
|
||||
+ final java.util.Map<net.minecraft.world.entity.EntityType<?>, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk
|
||||
for (final Entity entity : PlatformHooks.get().modifySavedEntities(world, chunkPos.x, chunkPos.z, entities)) {
|
||||
+ // Paper start - Entity load/save limit per chunk
|
||||
+ final EntityType<?> entityType = entity.getType();
|
||||
+ final int saveLimit = world.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1);
|
||||
+ if (saveLimit > -1) {
|
||||
+ if (savedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ savedEntityCounts.merge(entityType, 1, Integer::sum);
|
||||
+ }
|
||||
+ // Paper end - Entity load/save limit per chunk
|
||||
CompoundTag compoundTag = new CompoundTag();
|
||||
if (entity.save(compoundTag)) {
|
||||
entitiesTag.add(compoundTag);
|
||||
diff --git a/net/minecraft/world/entity/EntityType.java b/net/minecraft/world/entity/EntityType.java
|
||||
index 4c57990c94721dd0973477669e1dadfab5f16404..8af02ed823da098a5592ef195c9fe8ed8f245b53 100644
|
||||
--- a/net/minecraft/world/entity/EntityType.java
|
||||
+++ b/net/minecraft/world/entity/EntityType.java
|
||||
@@ -1430,9 +1430,20 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
|
||||
}
|
||||
|
||||
public static Stream<Entity> loadEntitiesRecursive(List<? extends Tag> entityTags, Level level, EntitySpawnReason spawnReason) {
|
||||
+ final java.util.Map<EntityType<?>, Integer> loadedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk
|
||||
return entityTags.stream()
|
||||
.flatMap(tag -> tag.asCompound().stream())
|
||||
.mapMulti((compoundTag, consumer) -> loadEntityRecursive(compoundTag, level, spawnReason, entity -> {
|
||||
+ // Paper start - Entity load/save limit per chunk
|
||||
+ final EntityType<?> entityType = entity.getType();
|
||||
+ final int saveLimit = level.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1);
|
||||
+ if (saveLimit > -1) {
|
||||
+ if (loadedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ loadedEntityCounts.merge(entityType, 1, Integer::sum);
|
||||
+ }
|
||||
+ // Paper end - Entity load/save limit per chunk
|
||||
consumer.accept(entity);
|
||||
return entity;
|
||||
}));
|
||||
diff --git a/net/minecraft/world/level/chunk/storage/EntityStorage.java b/net/minecraft/world/level/chunk/storage/EntityStorage.java
|
||||
index bcc2a4081fac07c4579c3aabfe4353743f8cd876..f9fb1380be9cbe960127c208c65c19f770e50b6d 100644
|
||||
--- a/net/minecraft/world/level/chunk/storage/EntityStorage.java
|
||||
+++ b/net/minecraft/world/level/chunk/storage/EntityStorage.java
|
||||
@@ -87,7 +87,18 @@ public class EntityStorage implements EntityPersistentStorage<Entity> {
|
||||
}
|
||||
} else {
|
||||
ListTag listTag = new ListTag();
|
||||
+ final java.util.Map<net.minecraft.world.entity.EntityType<?>, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk
|
||||
entities.getEntities().forEach(entity -> {
|
||||
+ // Paper start - Entity load/save limit per chunk
|
||||
+ final EntityType<?> entityType = entity.getType();
|
||||
+ final int saveLimit = this.level.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1);
|
||||
+ if (saveLimit > -1) {
|
||||
+ if (savedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) {
|
||||
+ return;
|
||||
+ }
|
||||
+ savedEntityCounts.merge(entityType, 1, Integer::sum);
|
||||
+ }
|
||||
+ // Paper end - Entity load/save limit per chunk
|
||||
CompoundTag compoundTag1 = new CompoundTag();
|
||||
if (entity.save(compoundTag1)) {
|
||||
listTag.add(compoundTag1);
|
||||
@ -0,0 +1,80 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Wed, 18 Nov 2020 20:52:25 -0800
|
||||
Subject: [PATCH] Entity load/save limit per chunk
|
||||
|
||||
Adds a config option to limit the number of entities saved and loaded
|
||||
to a chunk. The default values of -1 disable the limit. Although
|
||||
defaults are only included for certain entites, this allows setting
|
||||
limits for any entity type.
|
||||
|
||||
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
|
||||
index c380487a97f626163e1f13d87231d64ce2ea4b24..b2bcfb3557a0326fd7ec1059f95d6da4568dfd80 100644
|
||||
--- a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
|
||||
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
|
||||
@@ -116,8 +116,19 @@ public final class ChunkEntitySlices {
|
||||
}
|
||||
|
||||
final ListTag entitiesTag = new ListTag();
|
||||
+ final java.util.Map<net.minecraft.world.entity.EntityType<?>, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk
|
||||
try (final ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(ChunkAccess.problemPath(chunkPos), LOGGER)) {
|
||||
for (final Entity entity : PlatformHooks.get().modifySavedEntities(world, chunkPos.x, chunkPos.z, entities)) {
|
||||
+ // Paper start - Entity load/save limit per chunk
|
||||
+ final EntityType<?> entityType = entity.getType();
|
||||
+ final int saveLimit = world.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1);
|
||||
+ if (saveLimit > -1) {
|
||||
+ if (savedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ savedEntityCounts.merge(entityType, 1, Integer::sum);
|
||||
+ }
|
||||
+ // Paper end - Entity load/save limit per chunk
|
||||
final TagValueOutput savedEntity = TagValueOutput.createWithContext(
|
||||
scopedCollector.forChild(entity.problemPath()), entity.registryAccess()
|
||||
);
|
||||
diff --git a/net/minecraft/world/entity/EntityType.java b/net/minecraft/world/entity/EntityType.java
|
||||
index 98586dfc562cf6909df0f4bfa1c19e35b3172abe..f92adee1c187561d3790a5a5c8c81f5e1543ed97 100644
|
||||
--- a/net/minecraft/world/entity/EntityType.java
|
||||
+++ b/net/minecraft/world/entity/EntityType.java
|
||||
@@ -1448,7 +1448,18 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
|
||||
}
|
||||
|
||||
public static Stream<Entity> loadEntitiesRecursive(ValueInput.ValueInputList input, Level level, EntitySpawnReason spawnReason) {
|
||||
+ final java.util.Map<EntityType<?>, Integer> loadedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk
|
||||
return input.stream().mapMulti((valueInput, consumer) -> loadEntityRecursive(valueInput, level, spawnReason, entity -> {
|
||||
+ // Paper start - Entity load/save limit per chunk
|
||||
+ final EntityType<?> entityType = entity.getType();
|
||||
+ final int saveLimit = level.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1);
|
||||
+ if (saveLimit > -1) {
|
||||
+ if (loadedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ loadedEntityCounts.merge(entityType, 1, Integer::sum);
|
||||
+ }
|
||||
+ // Paper end - Entity load/save limit per chunk
|
||||
consumer.accept(entity);
|
||||
return entity;
|
||||
}));
|
||||
diff --git a/net/minecraft/world/level/chunk/storage/EntityStorage.java b/net/minecraft/world/level/chunk/storage/EntityStorage.java
|
||||
index bf45cce4db77966d44d7a8d97673bb6631a6adaf..f1f8575a4b37114ced3cdb1d2ea33a36a2db44fd 100644
|
||||
--- a/net/minecraft/world/level/chunk/storage/EntityStorage.java
|
||||
+++ b/net/minecraft/world/level/chunk/storage/EntityStorage.java
|
||||
@@ -95,7 +95,18 @@ public class EntityStorage implements EntityPersistentStorage<Entity> {
|
||||
} else {
|
||||
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(ChunkAccess.problemPath(pos), LOGGER)) {
|
||||
ListTag listTag = new ListTag();
|
||||
+ final java.util.Map<net.minecraft.world.entity.EntityType<?>, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk
|
||||
entities.getEntities().forEach(entity -> {
|
||||
+ // Paper start - Entity load/save limit per chunk
|
||||
+ final EntityType<?> entityType = entity.getType();
|
||||
+ final int saveLimit = this.level.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1);
|
||||
+ if (saveLimit > -1) {
|
||||
+ if (savedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) {
|
||||
+ return;
|
||||
+ }
|
||||
+ savedEntityCounts.merge(entityType, 1, Integer::sum);
|
||||
+ }
|
||||
+ // Paper end - Entity load/save limit per chunk
|
||||
TagValueOutput tagValueOutput = TagValueOutput.createWithContext(scopedCollector.forChild(entity.problemPath()), entity.registryAccess());
|
||||
if (entity.save(tagValueOutput)) {
|
||||
CompoundTag compoundTag1 = tagValueOutput.buildResult();
|
||||
@ -778,10 +778,10 @@ index 1649119f45d970a9bf1683d676c47ecfc18ad047..cc544f3199cd6af29e50362923d06517
|
||||
public static final RegionFileVersion VERSION_GZIP = register(
|
||||
new RegionFileVersion(
|
||||
diff --git a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||
index 03d1527073cf827fc3e191915fe5f7f064e36c3b..749096358fccbd5d1d13801092255c51096eb001 100644
|
||||
index 2e6263d8b466e0f61bc72eb818044734b7d0ee6d..e04d3479383cd480cf35ed7ac3c82e7f6fb69e28 100644
|
||||
--- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||
+++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||
@@ -122,6 +122,18 @@ public record SerializableChunkData(
|
||||
@@ -124,6 +124,18 @@ public record SerializableChunkData(
|
||||
}
|
||||
}
|
||||
// Paper end - guard against serializing mismatching coordinates
|
||||
@ -799,8 +799,8 @@ index 03d1527073cf827fc3e191915fe5f7f064e36c3b..749096358fccbd5d1d13801092255c51
|
||||
+ // Paper end - Attempt to recalculate regionfile header if it is corrupt
|
||||
|
||||
// Paper start - Do not let the server load chunks from newer versions
|
||||
private static final int CURRENT_DATA_VERSION = net.minecraft.SharedConstants.getCurrentVersion().getDataVersion().getVersion();
|
||||
@@ -571,7 +583,7 @@ public record SerializableChunkData(
|
||||
private static final int CURRENT_DATA_VERSION = net.minecraft.SharedConstants.getCurrentVersion().dataVersion().version();
|
||||
@@ -573,7 +585,7 @@ public record SerializableChunkData(
|
||||
compoundTag.putInt("xPos", this.chunkPos.x);
|
||||
compoundTag.putInt("yPos", this.minSectionY);
|
||||
compoundTag.putInt("zPos", this.chunkPos.z);
|
||||
@ -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 094ef7f54ad71795a2d8c2a8d03a32bef6ff2164..79bc1b7d9f640d2322814177eb3e921da8671e87 100644
|
||||
index 80442494db670fec34df310390ea787fb963eef4..2dd512565ab901bf853f34b384155902b0fe8120 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -952,7 +952,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -954,7 +954,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
boolean var4;
|
||||
try {
|
||||
this.isSaving = true;
|
||||
@ -17,7 +17,7 @@ index 094ef7f54ad71795a2d8c2a8d03a32bef6ff2164..79bc1b7d9f640d2322814177eb3e921d
|
||||
var4 = this.saveAllChunks(suppressLog, flush, forced);
|
||||
} finally {
|
||||
this.isSaving = false;
|
||||
@@ -1531,9 +1531,29 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1533,9 +1533,29 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
this.ticksUntilAutosave--;
|
||||
@ -50,10 +50,10 @@ index 094ef7f54ad71795a2d8c2a8d03a32bef6ff2164..79bc1b7d9f640d2322814177eb3e921d
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
this.runAllTasks(); // Paper - move runAllTasks() into full server tick (previously for timings)
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 32c8d4675de341d5edad7dbd9c0bf4bce5037733..bfbfbaa9660d21071c420b60b10be0a02a1bc87e 100644
|
||||
index 34b7769663e235b93c6388ab0c92c00f0297e42f..dda8d38ef61672cc714d9e5a475f9b0412ed5ff9 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1317,6 +1317,28 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -1339,6 +1339,28 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
return !(entity instanceof Player player && (this.server.isUnderSpawnProtection(this, pos, player) || !this.getWorldBorder().isWithinBounds(pos)));
|
||||
}
|
||||
|
||||
@ -83,10 +83,10 @@ index 32c8d4675de341d5edad7dbd9c0bf4bce5037733..bfbfbaa9660d21071c420b60b10be0a0
|
||||
// Paper start - add close param
|
||||
this.save(progress, flush, skipSave, false);
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index 5a60f2598560571e156612bf256c1c340d92a922..57e7d0a8b5f2a5bc65b0f290fb655625b1481f31 100644
|
||||
index c0b74d408340101bc3aac4cb4b7232c5cc78b08a..b70929df38389d789dad46c0a6d94f6c08aa7eba 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -188,6 +188,7 @@ import org.slf4j.Logger;
|
||||
@@ -195,6 +195,7 @@ import org.slf4j.Logger;
|
||||
|
||||
public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer { // Paper - rewrite chunk system
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
@ -95,10 +95,10 @@ index 5a60f2598560571e156612bf256c1c340d92a922..57e7d0a8b5f2a5bc65b0f290fb655625
|
||||
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 a7a07ebe6ceed99fa768b6834e350fe2f51a6950..9ca3c55a3b5b1a532b86b08eb92460df4cb54f2a 100644
|
||||
index a3aa852b04e6deccccf995cfc57f95fa79860c04..b1524279c02cd3be82338a6bd0320cb125a134d5 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -486,6 +486,7 @@ public abstract class PlayerList {
|
||||
@@ -489,6 +489,7 @@ public abstract class PlayerList {
|
||||
|
||||
protected void save(ServerPlayer player) {
|
||||
if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit
|
||||
@ -106,7 +106,7 @@ index a7a07ebe6ceed99fa768b6834e350fe2f51a6950..9ca3c55a3b5b1a532b86b08eb92460df
|
||||
this.playerIo.save(player);
|
||||
ServerStatsCounter serverStatsCounter = player.getStats(); // CraftBukkit
|
||||
if (serverStatsCounter != null) {
|
||||
@@ -1079,9 +1080,23 @@ public abstract class PlayerList {
|
||||
@@ -1075,9 +1076,23 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public void saveAll() {
|
||||
@ -993,7 +993,7 @@ index c3bcb494afe464207e805f8c40b03c700059c64a..063fca9686a6a048ba279a49271f4144
|
||||
private boolean isValid;
|
||||
|
||||
diff --git a/net/minecraft/world/level/chunk/storage/SectionStorage.java b/net/minecraft/world/level/chunk/storage/SectionStorage.java
|
||||
index 778bd73a938c94ecb85ca0f8b686ff4e1baee040..79d4ce7712f16995b0de3be86477fb43ab3961d7 100644
|
||||
index 964dfe6c84ca947ec7165aff821588ad8513d467..5e8f4d4bd98ef8a9f962b969c95a784764b8def5 100644
|
||||
--- a/net/minecraft/world/level/chunk/storage/SectionStorage.java
|
||||
+++ b/net/minecraft/world/level/chunk/storage/SectionStorage.java
|
||||
@@ -131,11 +131,11 @@ public class SectionStorage<R, P> implements AutoCloseable, ca.spottedleaf.moonr
|
||||
@ -5,7 +5,7 @@ Subject: [PATCH] Optional per player mob spawns
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||
index 886340232b58afd59caa6df29e211589a7781070..4f4bcc4bbfcc9b191d12d667b8fc1e644a9d5957 100644
|
||||
index 86ba02916c4a1c1311eeca5b1fb10a46626ba9ab..b40b94c49dc0997654aca0a1a0dffe482cd14eac 100644
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -243,11 +243,29 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@ -43,7 +43,7 @@ index 886340232b58afd59caa6df29e211589a7781070..4f4bcc4bbfcc9b191d12d667b8fc1e64
|
||||
protected ChunkGenerator generator() {
|
||||
return this.worldGenContext.generator();
|
||||
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
||||
index 5d63bf024cbcbd2f627c64fee77553c9a512bd15..f863377a807b672f49f7140688f378eca2cf650b 100644
|
||||
index 8e9988130d9b912e5b858cd7792bdcefdeb66ada..25d74f866546362a17505b5d4abf85382c0df20c 100644
|
||||
--- a/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -541,9 +541,18 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||
@ -78,10 +78,10 @@ index 5d63bf024cbcbd2f627c64fee77553c9a512bd15..f863377a807b672f49f7140688f378ec
|
||||
profiler.popPush("tickSpawningChunks");
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index 4b2801749328f250ce5735fbe7f6941a6bede01a..af04fcdba1e57b4eac678235b56ad3e1c70169b7 100644
|
||||
index b70929df38389d789dad46c0a6d94f6c08aa7eba..e96bb37bb7a7340a7ee33046820652ecd4accc53 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -395,6 +395,10 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
@@ -406,6 +406,10 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
public boolean queueHealthUpdatePacket;
|
||||
public @Nullable net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket;
|
||||
// Paper end - cancellable death event
|
||||
@ -6,7 +6,7 @@ Subject: [PATCH] Improve cancelling PreCreatureSpawnEvent with per player mob
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||
index 4f4bcc4bbfcc9b191d12d667b8fc1e644a9d5957..0d8aefe8c886eaa4c33cbab53b0ad1c016f0531f 100644
|
||||
index b40b94c49dc0997654aca0a1a0dffe482cd14eac..b72000ce6bdcb97b787bfab79236f60bdb4aa2ee 100644
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -262,8 +262,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@ -37,7 +37,7 @@ index 4f4bcc4bbfcc9b191d12d667b8fc1e644a9d5957..0d8aefe8c886eaa4c33cbab53b0ad1c0
|
||||
// Paper end - Optional per player mob spawns
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
||||
index f863377a807b672f49f7140688f378eca2cf650b..59e8a5e1b35c81883c9b1ca00c6e55d77584d8cc 100644
|
||||
index 25d74f866546362a17505b5d4abf85382c0df20c..7d78d270b7a076f595301acd9b3c6275e804496e 100644
|
||||
--- a/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -546,7 +546,17 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||
@ -60,10 +60,10 @@ index f863377a807b672f49f7140688f378eca2cf650b..59e8a5e1b35c81883c9b1ca00c6e55d7
|
||||
spawnState = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, null, true);
|
||||
} else {
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index af04fcdba1e57b4eac678235b56ad3e1c70169b7..3781d9cc174b7aecacb9b9855d52c7b1ff05835c 100644
|
||||
index e96bb37bb7a7340a7ee33046820652ecd4accc53..53f038e1b5e7a13a08a0c925c8bd3f8a40868195 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -399,6 +399,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
@@ -410,6 +410,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
public static final int MOBCATEGORY_TOTAL_ENUMS = net.minecraft.world.entity.MobCategory.values().length;
|
||||
public final int[] mobCounts = new int[MOBCATEGORY_TOTAL_ENUMS];
|
||||
// Paper end - Optional per player mob spawns
|
||||
@ -48,10 +48,10 @@ index 0000000000000000000000000000000000000000..24a2090e068ad3c0d08705050944abdf
|
||||
+ }
|
||||
+}
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 79bc1b7d9f640d2322814177eb3e921da8671e87..f1373fd5fdebb9f4600ba7f32a5df6188de3a0e9 100644
|
||||
index 2dd512565ab901bf853f34b384155902b0fe8120..d6dcb6d146d89a8fb96e7c669e5deb802223abd6 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1706,6 +1706,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1708,6 +1708,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
serverLevel.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - BlockPhysicsEvent
|
||||
serverLevel.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent
|
||||
serverLevel.updateLagCompensationTick(); // Paper - lag compensation
|
||||
@ -60,10 +60,10 @@ index 79bc1b7d9f640d2322814177eb3e921da8671e87..f1373fd5fdebb9f4600ba7f32a5df618
|
||||
/* Drop global time updates
|
||||
if (this.tickCount % 20 == 0) {
|
||||
diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java
|
||||
index 72cd623a1a3ce4b7a570a853456b067cd93736b1..ad7852a19ff73368ec9e7e63dcb7a064f78eefa0 100644
|
||||
index fc91f7f5ca01f1afe6ceb21f12d1a6ec6f5b68f9..cf283389d9263ba29720bf296a778be9eaf308a7 100644
|
||||
--- a/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/net/minecraft/world/item/ItemStack.java
|
||||
@@ -831,10 +831,16 @@ public final class ItemStack implements DataComponentHolder {
|
||||
@@ -811,10 +811,16 @@ public final class ItemStack implements DataComponentHolder {
|
||||
}
|
||||
|
||||
public ItemStack copy() {
|
||||
@ -83,10 +83,10 @@ index 72cd623a1a3ce4b7a570a853456b067cd93736b1..ad7852a19ff73368ec9e7e63dcb7a064
|
||||
return itemStack;
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/block/entity/BlockEntity.java b/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
index 7783ff94e5183737d01c75c521b70b4fbd8c34a6..a1075c26d55cc01219acd94d0138f81aa9d34c48 100644
|
||||
index 275646a9f99f3c46bc81a23143c1960f2a6300b1..5986825d6a381eeb445dd424dd127864aa703163 100644
|
||||
--- a/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
@@ -33,6 +33,7 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||
@@ -35,6 +35,7 @@ import net.minecraft.world.level.storage.ValueOutput;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public abstract class BlockEntity {
|
||||
@ -94,7 +94,7 @@ index 7783ff94e5183737d01c75c521b70b4fbd8c34a6..a1075c26d55cc01219acd94d0138f81a
|
||||
// CraftBukkit start - data containers
|
||||
private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry();
|
||||
public final org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer persistentDataContainer;
|
||||
@@ -202,6 +203,7 @@ public abstract class BlockEntity {
|
||||
@@ -227,6 +228,7 @@ public abstract class BlockEntity {
|
||||
|
||||
public void setChanged() {
|
||||
if (this.level != null) {
|
||||
@ -103,7 +103,7 @@ index 7783ff94e5183737d01c75c521b70b4fbd8c34a6..a1075c26d55cc01219acd94d0138f81a
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
index 9a03934dd4d96184f37b9ff5661eb7bd76150464..15d4f60942c0cc612c1468b4c0fda886867a67cb 100644
|
||||
index 94d68fbb3d152b2fd43f989b728c5efabbf3c22c..800b7e78ae989868ed0b9e060c80dcd002759412 100644
|
||||
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
@@ -143,18 +143,56 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@ -669,7 +669,7 @@ index 9a03934dd4d96184f37b9ff5661eb7bd76150464..15d4f60942c0cc612c1468b4c0fda886
|
||||
|
||||
@Override
|
||||
diff --git a/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java b/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
|
||||
index 1c98d003907feb16de8f26377fceedf728afe7fb..eed5f8f912544b79c8ed54dcdc5eeacb6dcfaccd 100644
|
||||
index d2cd30ed072a3d75c32b49a72920a9c26ce29922..dc59465d63e36bd50a48a8ea4197424556736552 100644
|
||||
--- a/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
|
||||
@@ -54,7 +54,7 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc
|
||||
@ -14,7 +14,7 @@ timestamp so that fs watchers can detect when RegionFiles are
|
||||
modified.
|
||||
|
||||
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java
|
||||
index 1acea58838f057ab87efd103cbecb6f5aeaef393..98fbc5c8044bd945d64569f13412a6e7e49a4e7f 100644
|
||||
index 09320f243a54f855b29d3833089b096975ca0075..709df35246fb328cda21679b53d44d9f96206cb3 100644
|
||||
--- a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java
|
||||
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java
|
||||
@@ -1258,6 +1258,14 @@ public final class MoonriseRegionFileIO {
|
||||
@ -6,53 +6,43 @@ 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 0be741820fc7da2aac4f4aad85c4238ef49a0f57..337976c5c1ead87c36daa4e741b06e5a195b8302 100644
|
||||
index c9a0df5e5617e62703787942d067883ea537618b..aeb43902a09ef9c1b137964065780be3e87648f4 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -555,7 +555,7 @@ public class ServerGamePacketListenerImpl
|
||||
return;
|
||||
}
|
||||
|
||||
- boolean flag = serverLevel.noCollision(rootVehicle, rootVehicle.getBoundingBox().deflate(0.0625));
|
||||
+ final AABB oldBox = rootVehicle.getBoundingBox(); // Paper - copy from player movement packet
|
||||
d3 = d - this.vehicleLastGoodX; // Paper - diff on change, used for checking large move vectors above
|
||||
d4 = d1 - this.vehicleLastGoodY; // Paper - diff on change, used for checking large move vectors above
|
||||
d5 = d2 - this.vehicleLastGoodZ; // Paper - diff on change, used for checking large move vectors above
|
||||
@@ -565,6 +565,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -592,6 +592,7 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
|
||||
rootVehicle.move(MoverType.PLAYER, new Vec3(d3, d4, d5));
|
||||
+ final boolean didCollide = toX != rootVehicle.getX() || toY != rootVehicle.getY() || toZ != rootVehicle.getZ(); // Paper - needed here as the difference in Y can be reset - also note: this is only a guess at whether collisions took place, floating point errors can make this true when it shouldn't be...
|
||||
double verticalDelta = d4; // Paper - Decompile fix: lvt reassignment lost
|
||||
double verticalDelta = d4;
|
||||
d3 = d - rootVehicle.getX();
|
||||
d4 = d1 - rootVehicle.getY();
|
||||
@@ -576,14 +577,22 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -603,12 +604,21 @@ public class ServerGamePacketListenerImpl
|
||||
d7 = d3 * d3 + d4 * d4 + d5 * d5;
|
||||
boolean flag2 = false;
|
||||
boolean flag1 = false;
|
||||
if (d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot
|
||||
- flag2 = true;
|
||||
+ flag2 = true; // Paper - diff on change, this should be moved wrongly
|
||||
- flag1 = true;
|
||||
+ flag1 = true; // Paper - diff on change, this should be moved wrongly
|
||||
LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", rootVehicle.getName().getString(), this.player.getName().getString(), Math.sqrt(d7));
|
||||
}
|
||||
|
||||
rootVehicle.absSnapTo(d, d1, d2, f, f1);
|
||||
this.player.absSnapTo(d, d1, d2, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
|
||||
- boolean flag3 = serverLevel.noCollision(rootVehicle, rootVehicle.getBoundingBox().deflate(0.0625));
|
||||
- if (flag && (flag2 || !flag3)) {
|
||||
- if (flag1 && serverLevel.noCollision(rootVehicle, boundingBox)
|
||||
- || this.isEntityCollidingWithAnythingNew(serverLevel, rootVehicle, boundingBox, d, d1, d2)) {
|
||||
+ // Paper start - optimise out extra getCubes
|
||||
+ boolean teleportBack = flag2; // violating this is always a fail
|
||||
+ boolean teleportBack = flag1;
|
||||
+ if (!teleportBack) {
|
||||
+ // note: only call after setLocation, or else getBoundingBox is wrong
|
||||
+ final AABB newBox = rootVehicle.getBoundingBox();
|
||||
+ if (didCollide || !oldBox.equals(newBox)) {
|
||||
+ teleportBack = this.hasNewCollision(serverLevel, rootVehicle, oldBox, newBox);
|
||||
+ if (didCollide || !boundingBox.equals(newBox)) {
|
||||
+ teleportBack = this.hasNewCollision(serverLevel, rootVehicle, boundingBox, newBox);
|
||||
+ } // else: no collision at all detected, why do we care?
|
||||
+ }
|
||||
+ if (teleportBack) { // Paper end - optimise out extra getCubes
|
||||
+ if (teleportBack) {
|
||||
+ // Paper end - optimise out extra getCubes
|
||||
rootVehicle.absSnapTo(x, y, z, f, f1);
|
||||
this.player.absSnapTo(x, y, z, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
|
||||
this.send(ClientboundMoveVehiclePacket.fromEntity(rootVehicle));
|
||||
@@ -661,9 +670,32 @@ public class ServerGamePacketListenerImpl
|
||||
rootVehicle.removeLatestMovementRecording();
|
||||
@@ -687,9 +697,32 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
|
||||
private boolean noBlocksAround(Entity entity) {
|
||||
@ -88,7 +78,7 @@ index 0be741820fc7da2aac4f4aad85c4238ef49a0f57..337976c5c1ead87c36daa4e741b06e5a
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1432,7 +1464,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1465,7 +1498,7 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,7 +87,7 @@ index 0be741820fc7da2aac4f4aad85c4238ef49a0f57..337976c5c1ead87c36daa4e741b06e5a
|
||||
d3 = d - this.lastGoodX; // Paper - diff on change, used for checking large move vectors above
|
||||
d4 = d1 - this.lastGoodY; // Paper - diff on change, used for checking large move vectors above
|
||||
d5 = d2 - this.lastGoodZ; // Paper - diff on change, used for checking large move vectors above
|
||||
@@ -1471,6 +1503,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1504,6 +1537,7 @@ public class ServerGamePacketListenerImpl
|
||||
boolean flag1 = this.player.verticalCollisionBelow;
|
||||
this.player.move(MoverType.PLAYER, new Vec3(d3, d4, d5));
|
||||
this.player.onGround = packet.isOnGround(); // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move
|
||||
@ -105,26 +95,26 @@ index 0be741820fc7da2aac4f4aad85c4238ef49a0f57..337976c5c1ead87c36daa4e741b06e5a
|
||||
// Paper start - prevent position desync
|
||||
if (this.awaitingPositionFromClient != null) {
|
||||
return; // ... thanks Mojang for letting move calls teleport across dimensions.
|
||||
@@ -1503,7 +1536,17 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1536,7 +1570,17 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
|
||||
// Paper start - Add fail move event
|
||||
- boolean teleportBack = !this.player.noPhysics && !this.player.isSleeping() && (movedWrongly && serverLevel.noCollision(this.player, boundingBox) || this.isPlayerCollidingWithAnythingNew(serverLevel, boundingBox, d, d1, d2));
|
||||
- boolean allowMovement = this.player.noPhysics || this.player.isSleeping() || (!movedWrongly || !serverLevel.noCollision(this.player, boundingBox)) && !this.isEntityCollidingWithAnythingNew(serverLevel, this.player, boundingBox, d, d1, d2);
|
||||
+ // Paper start - optimise out extra getCubes
|
||||
+ boolean teleportBack = !this.player.noPhysics && !this.player.isSleeping() && movedWrongly;
|
||||
+ boolean allowMovement = this.player.noPhysics || this.player.isSleeping() || !movedWrongly;
|
||||
+ this.player.absSnapTo(d, d1, d2, f, f1); // prevent desync by tping to the set position, dropped for unknown reasons by mojang
|
||||
+ if (!this.player.noPhysics && !this.player.isSleeping() && !teleportBack) {
|
||||
+ if (!this.player.noPhysics && !this.player.isSleeping() && allowMovement) {
|
||||
+ final AABB newBox = this.player.getBoundingBox();
|
||||
+ if (didCollide || !boundingBox.equals(newBox)) {
|
||||
+ // note: only call after setLocation, or else getBoundingBox is wrong
|
||||
+ teleportBack = this.hasNewCollision(serverLevel, this.player, boundingBox, newBox);
|
||||
+ allowMovement = !this.hasNewCollision(serverLevel, this.player, boundingBox, newBox);
|
||||
+ } // else: no collision at all detected, why do we care?
|
||||
+ }
|
||||
+ // Paper end - optimise out extra getCubes
|
||||
if (teleportBack) {
|
||||
if (!allowMovement) {
|
||||
io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.CLIPPED_INTO_BLOCK,
|
||||
toX, toY, toZ, toYaw, toPitch, false);
|
||||
@@ -1640,7 +1683,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1672,7 +1716,7 @@ public class ServerGamePacketListenerImpl
|
||||
|
||||
private boolean updateAwaitingTeleport() {
|
||||
if (this.awaitingPositionFromClient != null) {
|
||||
@ -133,7 +123,7 @@ index 0be741820fc7da2aac4f4aad85c4238ef49a0f57..337976c5c1ead87c36daa4e741b06e5a
|
||||
this.awaitingTeleportTime = this.tickCount;
|
||||
this.teleport(
|
||||
this.awaitingPositionFromClient.x,
|
||||
@@ -1659,6 +1702,33 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1691,6 +1735,33 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,6 +154,6 @@ index 0be741820fc7da2aac4f4aad85c4238ef49a0f57..337976c5c1ead87c36daa4e741b06e5a
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end - optimise out extra getCubes
|
||||
private boolean isPlayerCollidingWithAnythingNew(LevelReader level, AABB box, double x, double y, double z) {
|
||||
AABB aabb = this.player.getBoundingBox().move(x - this.player.getX(), y - this.player.getY(), z - this.player.getZ());
|
||||
Iterable<VoxelShape> collisions = level.getCollisions(this.player, aabb.deflate(1.0E-5F));
|
||||
private boolean isEntityCollidingWithAnythingNew(LevelReader levelReader, Entity entity, AABB aabb, double d, double d1, double d2) {
|
||||
AABB aabb1 = entity.getBoundingBox().move(d - entity.getX(), d1 - entity.getY(), d2 - entity.getZ());
|
||||
Iterable<VoxelShape> preMoveCollisions = levelReader.getPreMoveCollisions(entity, aabb1.deflate(1.0E-5F), aabb.getBottomCenter());
|
||||
24
paper-server/patches/features/0031-DataConverter-Fixes.patch
Normal file
24
paper-server/patches/features/0031-DataConverter-Fixes.patch
Normal file
@ -0,0 +1,24 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sat, 7 Jun 2025 15:05:05 -0400
|
||||
Subject: [PATCH] DataConverter Fixes
|
||||
|
||||
|
||||
diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4307.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4307.java
|
||||
index d2877c20f389d0131e1dd208b464f590671e5d82..27bdc70d861ca39487ad16cb3afb89d604b462c8 100644
|
||||
--- a/ca/spottedleaf/dataconverter/minecraft/versions/V4307.java
|
||||
+++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4307.java
|
||||
@@ -87,10 +87,10 @@ public final class V4307 {
|
||||
|
||||
@Override
|
||||
public MapType convert(final MapType root, final long sourceVersion, final long toVersion) {
|
||||
- final Set<String> hiddenComponents = new LinkedHashSet<>();
|
||||
-
|
||||
- unwrapBlockPredicates(root, "minecraft:can_break", hiddenComponents);
|
||||
+ // Don't use a linked hash set, and ensure that it is added in the same (undefined) order as the vanilla datafixer
|
||||
+ final Set<String> hiddenComponents = new java.util.HashSet<>();
|
||||
unwrapBlockPredicates(root, "minecraft:can_place_on", hiddenComponents);
|
||||
+ unwrapBlockPredicates(root, "minecraft:can_break", hiddenComponents);
|
||||
|
||||
updateComponent(root, "minecraft:trim", hiddenComponents);
|
||||
updateComponent(root, "minecraft:unbreakable", hiddenComponents);
|
||||
@ -1,6 +1,6 @@
|
||||
--- /dev/null
|
||||
+++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java
|
||||
@@ -1,0 +_,241 @@
|
||||
@@ -1,0 +_,250 @@
|
||||
+package ca.spottedleaf.moonrise.paper;
|
||||
+
|
||||
+import ca.spottedleaf.moonrise.common.PlatformHooks;
|
||||
@ -33,6 +33,8 @@
|
||||
+
|
||||
+public final class PaperHooks extends BaseChunkSystemHooks implements PlatformHooks {
|
||||
+
|
||||
+ private static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger();
|
||||
+
|
||||
+ @Override
|
||||
+ public String getBrand() {
|
||||
+ return "Paper";
|
||||
@ -150,6 +152,11 @@
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public long[] getCounterTypesUncached(final net.minecraft.server.level.TicketType type) {
|
||||
+ return new long[0];
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean configFixMC224294() {
|
||||
+ return true;
|
||||
+ }
|
||||
@ -234,7 +241,9 @@
|
||||
+
|
||||
+ @Override
|
||||
+ public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk) {
|
||||
+ net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities());
|
||||
+ try (final net.minecraft.util.ProblemReporter.ScopedCollector scopedCollector = new net.minecraft.util.ProblemReporter.ScopedCollector(chunk.problemPath(), LOGGER)) {
|
||||
+ net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, net.minecraft.world.level.storage.TagValueInput.create(scopedCollector, world.registryAccess(), chunk.getEntities()));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
|
||||
@ -300,7 +300,7 @@
|
||||
+
|
||||
+ @Override
|
||||
+ public int getViewDistance(final ServerPlayer player) {
|
||||
+ final ServerLevel level = player.serverLevel();
|
||||
+ final ServerLevel level = player.level();
|
||||
+ if (level == null) {
|
||||
+ return Bukkit.getViewDistance();
|
||||
+ }
|
||||
@ -309,7 +309,7 @@
|
||||
+
|
||||
+ @Override
|
||||
+ public int getTickViewDistance(final ServerPlayer player) {
|
||||
+ final ServerLevel level = player.serverLevel();
|
||||
+ final ServerLevel level = player.level();
|
||||
+ if (level == null) {
|
||||
+ return Bukkit.getSimulationDistance();
|
||||
+ }
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
private final RedirectModifier<S> modifier;
|
||||
private final boolean forks;
|
||||
private Command<S> command;
|
||||
+ public CommandNode<net.minecraft.commands.CommandSourceStack> clientNode; // Paper - Brigadier API
|
||||
+ public CommandNode<S> clientNode; // Paper - Brigadier API
|
||||
+ public CommandNode<io.papermc.paper.command.brigadier.CommandSourceStack> unwrappedCached = null; // Paper - Brigadier Command API
|
||||
+ public CommandNode<io.papermc.paper.command.brigadier.CommandSourceStack> wrappedCached = null; // Paper - Brigadier Command API
|
||||
+ public io.papermc.paper.command.brigadier.APICommandMeta apiCommandMeta; // Paper - Brigadier Command API
|
||||
@ -24,25 +24,6 @@
|
||||
|
||||
protected CommandNode(final Command<S> command, final Predicate<S> requirement, final CommandNode<S> redirect, final RedirectModifier<S> modifier, final boolean forks) {
|
||||
this.command = command;
|
||||
@@ -61,7 +_,17 @@
|
||||
return modifier;
|
||||
}
|
||||
|
||||
- public boolean canUse(final S source) {
|
||||
+ // CraftBukkit start
|
||||
+ public synchronized boolean canUse(final S source) {
|
||||
+ if (source instanceof final net.minecraft.commands.CommandSourceStack css) {
|
||||
+ try {
|
||||
+ css.currentCommand.put(Thread.currentThread(), this); // Paper - Thread Safe Vanilla Command permission checking
|
||||
+ return this.requirement.test(source);
|
||||
+ } finally {
|
||||
+ css.currentCommand.remove(Thread.currentThread()); // Paper - Thread Safe Vanilla Command permission checking
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
return requirement.test(source);
|
||||
}
|
||||
|
||||
@@ -151,6 +_,12 @@
|
||||
protected abstract String getSortedKey();
|
||||
|
||||
|
||||
@ -64,7 +64,7 @@
|
||||
+
|
||||
+ public static Set<Chunk> getSentChunks(final ServerPlayer player) {
|
||||
+ final ObjectSet<Chunk> chunks = new ObjectOpenHashSet<>();
|
||||
+ final World world = player.serverLevel().getWorld();
|
||||
+ final World world = player.level().getWorld();
|
||||
+ player.getChunkTrackingView().forEach(pos -> {
|
||||
+ final org.bukkit.Chunk chunk = world.getChunkAt(pos.longKey);
|
||||
+ chunks.add(chunk);
|
||||
|
||||
@ -1,24 +1,23 @@
|
||||
--- a/net/minecraft/commands/CommandSourceStack.java
|
||||
+++ b/net/minecraft/commands/CommandSourceStack.java
|
||||
@@ -45,7 +_,7 @@
|
||||
@@ -47,7 +_,7 @@
|
||||
import net.minecraft.world.phys.Vec2;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
-public class CommandSourceStack implements ExecutionCommandSource<CommandSourceStack>, SharedSuggestionProvider {
|
||||
+public class CommandSourceStack implements ExecutionCommandSource<CommandSourceStack>, SharedSuggestionProvider, io.papermc.paper.command.brigadier.PaperCommandSourceStack { // Paper - Brigadier API
|
||||
-public class CommandSourceStack implements ExecutionCommandSource<CommandSourceStack>, PermissionSource, SharedSuggestionProvider {
|
||||
+public class CommandSourceStack implements ExecutionCommandSource<CommandSourceStack>, PermissionSource, SharedSuggestionProvider, io.papermc.paper.command.brigadier.PaperCommandSourceStack { // Paper - Brigadier API
|
||||
public static final SimpleCommandExceptionType ERROR_NOT_PLAYER = new SimpleCommandExceptionType(Component.translatable("permissions.requires.player"));
|
||||
public static final SimpleCommandExceptionType ERROR_NOT_ENTITY = new SimpleCommandExceptionType(Component.translatable("permissions.requires.entity"));
|
||||
public final CommandSource source;
|
||||
@@ -63,6 +_,8 @@
|
||||
@@ -65,6 +_,7 @@
|
||||
private final Vec2 rotation;
|
||||
private final CommandSigningContext signingContext;
|
||||
private final TaskChainer chatMessageChainer;
|
||||
+ public java.util.Map<Thread, com.mojang.brigadier.tree.CommandNode> currentCommand = new java.util.concurrent.ConcurrentHashMap<>(); // CraftBukkit // Paper - Thread Safe Vanilla Command permission checking
|
||||
+ public boolean bypassSelectorPermissions = false; // Paper - add bypass for selector permissions
|
||||
|
||||
public CommandSourceStack(
|
||||
CommandSource source,
|
||||
@@ -188,6 +_,30 @@
|
||||
@@ -190,6 +_,30 @@
|
||||
);
|
||||
}
|
||||
|
||||
@ -49,19 +48,7 @@
|
||||
public CommandSourceStack withRotation(Vec2 rotation) {
|
||||
return this.rotation.equals(rotation)
|
||||
? this
|
||||
@@ -391,9 +_,44 @@
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(int level) {
|
||||
+ // CraftBukkit start
|
||||
+ // Paper start - Thread Safe Vanilla Command permission checking
|
||||
+ com.mojang.brigadier.tree.CommandNode currentCommand = this.currentCommand.get(Thread.currentThread());
|
||||
+ if (currentCommand != null) {
|
||||
+ return this.hasPermission(level, org.bukkit.craftbukkit.command.VanillaCommandWrapper.getPermission(currentCommand));
|
||||
+ // Paper end - Thread Safe Vanilla Command permission checking
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
@@ -396,6 +_,32 @@
|
||||
return this.permissionLevel >= level;
|
||||
}
|
||||
|
||||
@ -94,7 +81,7 @@
|
||||
public Vec3 getPosition() {
|
||||
return this.worldPosition;
|
||||
}
|
||||
@@ -498,20 +_,25 @@
|
||||
@@ -500,20 +_,25 @@
|
||||
Component component = Component.translatable("chat.type.admin", this.getDisplayName(), message).withStyle(ChatFormatting.GRAY, ChatFormatting.ITALIC);
|
||||
if (this.server.getGameRules().getBoolean(GameRules.RULE_SENDCOMMANDFEEDBACK)) {
|
||||
for (ServerPlayer serverPlayer : this.server.getPlayerList().getPlayers()) {
|
||||
@ -123,7 +110,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,7 +_,7 @@
|
||||
@@ -524,7 +_,7 @@
|
||||
|
||||
@Override
|
||||
public Collection<String> getOnlinePlayerNames() {
|
||||
@ -132,7 +119,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -597,4 +_,16 @@
|
||||
@@ -604,4 +_,16 @@
|
||||
public boolean isSilent() {
|
||||
return this.silent;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/commands/Commands.java
|
||||
+++ b/net/minecraft/commands/Commands.java
|
||||
@@ -150,6 +_,11 @@
|
||||
@@ -176,6 +_,11 @@
|
||||
private final CommandDispatcher<CommandSourceStack> dispatcher = new CommandDispatcher<>();
|
||||
|
||||
public Commands(Commands.CommandSelection selection, CommandBuildContext context) {
|
||||
@ -12,7 +12,7 @@
|
||||
AdvancementCommands.register(this.dispatcher);
|
||||
AttributeCommand.register(this.dispatcher, context);
|
||||
ExecuteCommand.register(this.dispatcher, context);
|
||||
@@ -251,6 +_,40 @@
|
||||
@@ -280,6 +_,42 @@
|
||||
PublishCommand.register(this.dispatcher);
|
||||
}
|
||||
|
||||
@ -20,6 +20,8 @@
|
||||
+ for (final CommandNode<CommandSourceStack> node : this.dispatcher.getRoot().getChildren()) {
|
||||
+ if (node.getRequirement() == com.mojang.brigadier.builder.ArgumentBuilder.<CommandSourceStack>defaultRequirement()) {
|
||||
+ node.requirement = stack -> stack.source == CommandSource.NULL || stack.getBukkitSender().hasPermission(org.bukkit.craftbukkit.command.VanillaCommandWrapper.getPermission(node));
|
||||
+ } else if (node.getRequirement() instanceof net.minecraft.commands.PermissionSource.Check<CommandSourceStack> check) {
|
||||
+ check.vanillaNode().set(node);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Vanilla command permission fixes
|
||||
@ -53,7 +55,7 @@
|
||||
this.dispatcher.setConsumer(ExecutionCommandSource.resultConsumer());
|
||||
}
|
||||
|
||||
@@ -260,15 +_,58 @@
|
||||
@@ -289,9 +_,41 @@
|
||||
return new ParseResults<>(commandContextBuilder, parseResults.getReader(), parseResults.getExceptions());
|
||||
}
|
||||
|
||||
@ -89,12 +91,16 @@
|
||||
+ }
|
||||
+
|
||||
+ public void performPrefixedCommand(CommandSourceStack source, String command, String label) {
|
||||
command = command.startsWith("/") ? command.substring(1) : command;
|
||||
command = trimOptionalPrefix(command);
|
||||
- this.performCommand(this.dispatcher.parse(command, source), command);
|
||||
+ this.performCommand(this.dispatcher.parse(command, source), command, label);
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
public static String trimOptionalPrefix(String command) {
|
||||
@@ -299,9 +_,20 @@
|
||||
}
|
||||
|
||||
public void performCommand(ParseResults<CommandSourceStack> parseResults, String command) {
|
||||
+ // CraftBukkit start
|
||||
+ this.performCommand(parseResults, command, command);
|
||||
@ -114,7 +120,7 @@
|
||||
|
||||
try {
|
||||
if (contextChain != null) {
|
||||
@@ -280,9 +_,10 @@
|
||||
@@ -313,9 +_,10 @@
|
||||
);
|
||||
}
|
||||
} catch (Exception var12) {
|
||||
@ -127,7 +133,7 @@
|
||||
StackTraceElement[] stackTrace = var12.getStackTrace();
|
||||
|
||||
for (int i = 0; i < Math.min(stackTrace.length, 3); i++) {
|
||||
@@ -308,18 +_,22 @@
|
||||
@@ -341,18 +_,22 @@
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@ -153,7 +159,7 @@
|
||||
if (min > 10) {
|
||||
mutableComponent.append(CommonComponents.ELLIPSIS);
|
||||
}
|
||||
@@ -331,7 +_,17 @@
|
||||
@@ -364,7 +_,17 @@
|
||||
}
|
||||
|
||||
mutableComponent.append(Component.translatable("command.context.here").withStyle(ChatFormatting.RED, ChatFormatting.ITALIC));
|
||||
@ -172,13 +178,13 @@
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -359,26 +_,121 @@
|
||||
@@ -392,17 +_,110 @@
|
||||
}
|
||||
|
||||
public void sendCommands(ServerPlayer player) {
|
||||
+ // Paper start - Send empty commands if tab completion is disabled
|
||||
+ if (org.spigotmc.SpigotConfig.tabComplete < 0) {
|
||||
+ player.connection.send(new ClientboundCommandsPacket(new RootCommandNode<>()));
|
||||
+ player.connection.send(new ClientboundCommandsPacket(new RootCommandNode<>(), COMMAND_NODE_INSPECTOR));
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Send empty commands if tab completion is disabled
|
||||
@ -203,11 +209,11 @@
|
||||
+
|
||||
+ private void sendAsync(ServerPlayer player, java.util.Collection<CommandNode<CommandSourceStack>> dispatcherRootChildren) {
|
||||
+ // Paper end - Perf: Async command map building
|
||||
Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> map = Maps.newHashMap();
|
||||
RootCommandNode<SharedSuggestionProvider> rootCommandNode = new RootCommandNode<>();
|
||||
Map<CommandNode<CommandSourceStack>, CommandNode<CommandSourceStack>> map = new HashMap<>();
|
||||
RootCommandNode<CommandSourceStack> rootCommandNode = new RootCommandNode<>();
|
||||
map.put(this.dispatcher.getRoot(), rootCommandNode);
|
||||
- this.fillUsableCommands(this.dispatcher.getRoot(), rootCommandNode, player.createCommandSourceStack(), map);
|
||||
+ this.fillUsableCommands(dispatcherRootChildren, rootCommandNode, player.createCommandSourceStack(), map); // Paper - Perf: Async command map building; pass copy of children
|
||||
- fillUsableCommands(this.dispatcher.getRoot(), rootCommandNode, player.createCommandSourceStack(), map);
|
||||
+ fillUsableCommands(dispatcherRootChildren, rootCommandNode, player.createCommandSourceStack(), map); // Paper - Perf: Async command map building; pass copy of children
|
||||
+
|
||||
+ java.util.Collection<String> bukkit = new java.util.LinkedHashSet<>();
|
||||
+ for (CommandNode node : rootCommandNode.getChildren()) {
|
||||
@ -216,11 +222,11 @@
|
||||
+ // Paper start - Perf: Async command map building
|
||||
+ new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent<CommandSourceStack>(player.getBukkitEntity(), (RootCommandNode) rootCommandNode, false).callEvent(); // Paper - Brigadier API
|
||||
+ net.minecraft.server.MinecraftServer.getServer().execute(() -> {
|
||||
+ runSync(player, bukkit, rootCommandNode);
|
||||
+ runSync(player, bukkit, rootCommandNode);
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ private void runSync(ServerPlayer player, java.util.Collection<String> bukkit, RootCommandNode<SharedSuggestionProvider> rootCommandNode) {
|
||||
+ private void runSync(ServerPlayer player, java.util.Collection<String> bukkit, RootCommandNode<CommandSourceStack> rootCommandNode) {
|
||||
+ // Paper end - Perf: Async command map building
|
||||
+ new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent<CommandSourceStack>(player.getBukkitEntity(), (RootCommandNode) rootCommandNode, true).callEvent(); // Paper - Brigadier API
|
||||
+ org.bukkit.event.player.PlayerCommandSendEvent event = new org.bukkit.event.player.PlayerCommandSendEvent(player.getBukkitEntity(), new java.util.LinkedHashSet<>(bukkit));
|
||||
@ -233,28 +239,21 @@
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
player.connection.send(new ClientboundCommandsPacket(rootCommandNode));
|
||||
player.connection.send(new ClientboundCommandsPacket(rootCommandNode, COMMAND_NODE_INSPECTOR));
|
||||
}
|
||||
|
||||
private void fillUsableCommands(
|
||||
- CommandNode<CommandSourceStack> rootCommandSource,
|
||||
+ java.util.Collection<CommandNode<CommandSourceStack>> children, // Paper - Perf: Async command map building; pass copy of children
|
||||
CommandNode<SharedSuggestionProvider> rootSuggestion,
|
||||
CommandSourceStack source,
|
||||
Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> commandNodeToSuggestionNode
|
||||
) {
|
||||
- for (CommandNode<CommandSourceStack> commandNode : rootCommandSource.getChildren()) {
|
||||
+ for (CommandNode<CommandSourceStack> commandNode : children) { // Paper - Perf: Async command map building; pass copy of children
|
||||
- private static <S> void fillUsableCommands(CommandNode<S> root, CommandNode<S> current, S source, Map<CommandNode<S>, CommandNode<S>> output) {
|
||||
- for (CommandNode<S> commandNode : root.getChildren()) {
|
||||
+ private static <S> void fillUsableCommands(java.util.Collection<CommandNode<S>> children, CommandNode<S> current, S source, Map<CommandNode<S>, CommandNode<S>> output) { // Paper - Perf: Async command map building; pass copy of children
|
||||
+ for (CommandNode<S> commandNode : children) { // Paper - Perf: Async command map building; pass copy of children
|
||||
+ // Paper start - Brigadier API
|
||||
+ if (commandNode.clientNode != null) {
|
||||
+ commandNode = commandNode.clientNode;
|
||||
+ }
|
||||
+ // Paper end - Brigadier API
|
||||
+ if (!org.spigotmc.SpigotConfig.sendNamespaced && commandNode.getName().contains(":")) continue; // Spigot
|
||||
+ if (commandNode.wrappedCached != null && commandNode.wrappedCached.apiCommandMeta != null && commandNode.wrappedCached.apiCommandMeta.serverSideOnly()) continue; // Paper
|
||||
if (commandNode.canUse(source)) {
|
||||
ArgumentBuilder<SharedSuggestionProvider, ?> argumentBuilder = (ArgumentBuilder) commandNode.createBuilder();
|
||||
ArgumentBuilder<S, ?> argumentBuilder = commandNode.createBuilder();
|
||||
+ // Paper start
|
||||
+ /*
|
||||
+ Because of how commands can be yeeted right left and center due to bad bukkit practices
|
||||
@ -271,41 +270,34 @@
|
||||
+ - Do this :)
|
||||
+ */
|
||||
+ // Is there an invalid command redirect?
|
||||
+ if (argumentBuilder.getRedirect() != null && commandNodeToSuggestionNode.get(argumentBuilder.getRedirect()) == null) {
|
||||
+ if (argumentBuilder.getRedirect() != null && output.get(argumentBuilder.getRedirect()) == null) {
|
||||
+ // Create the argument builder with the same values as the specified node, but with a different literal and populated children
|
||||
+
|
||||
+ final CommandNode<SharedSuggestionProvider> redirect = argumentBuilder.getRedirect();
|
||||
+ final CommandNode<S> redirect = argumentBuilder.getRedirect();
|
||||
+ // Diff copied from LiteralCommand#createBuilder
|
||||
+ final com.mojang.brigadier.builder.LiteralArgumentBuilder<SharedSuggestionProvider> builder = com.mojang.brigadier.builder.LiteralArgumentBuilder.literal(commandNode.getName());
|
||||
+ final com.mojang.brigadier.builder.LiteralArgumentBuilder<S> builder = com.mojang.brigadier.builder.LiteralArgumentBuilder.literal(commandNode.getName());
|
||||
+ builder.requires(redirect.getRequirement());
|
||||
+ // builder.forward(redirect.getRedirect(), redirect.getRedirectModifier(), redirect.isFork()); We don't want to migrate the forward, since it's invalid.
|
||||
+ if (redirect.getCommand() != null) {
|
||||
+ builder.executes(redirect.getCommand());
|
||||
+ }
|
||||
+ // Diff copied from LiteralCommand#createBuilder
|
||||
+ for (final CommandNode<SharedSuggestionProvider> child : redirect.getChildren()) {
|
||||
+ for (final CommandNode<S> child : redirect.getChildren()) {
|
||||
+ builder.then(child);
|
||||
+ }
|
||||
+
|
||||
+ argumentBuilder = builder;
|
||||
+ }
|
||||
+ // Paper end
|
||||
argumentBuilder.requires(suggestions -> true);
|
||||
- if (argumentBuilder.getCommand() != null) {
|
||||
- argumentBuilder.executes(commandContext -> 0);
|
||||
- }
|
||||
+ // Paper - don't replace Command instance on suggestion node
|
||||
+ // we want the exact command instance to be used for equality checks
|
||||
+ // when assigning serialization ids to each command node
|
||||
|
||||
if (argumentBuilder instanceof RequiredArgumentBuilder requiredArgumentBuilder
|
||||
&& requiredArgumentBuilder.getSuggestionsProvider() != null) {
|
||||
@@ -393,7 +_,7 @@
|
||||
commandNodeToSuggestionNode.put(commandNode, commandNode1);
|
||||
rootSuggestion.addChild(commandNode1);
|
||||
if (argumentBuilder.getRedirect() != null) {
|
||||
argumentBuilder.redirect(output.get(argumentBuilder.getRedirect()));
|
||||
}
|
||||
@@ -411,7 +_,7 @@
|
||||
output.put(commandNode, commandNode1);
|
||||
current.addChild(commandNode1);
|
||||
if (!commandNode.getChildren().isEmpty()) {
|
||||
- this.fillUsableCommands(commandNode, commandNode1, source, commandNodeToSuggestionNode);
|
||||
+ this.fillUsableCommands(commandNode.getChildren(), commandNode1, source, commandNodeToSuggestionNode); // Paper - Perf: Async command map building; pass copy of children
|
||||
- fillUsableCommands(commandNode, commandNode1, source, output);
|
||||
+ fillUsableCommands(commandNode.getChildren(), commandNode1, source, output); // Paper - Perf: Async command map building; pass copy of children
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
--- a/net/minecraft/commands/PermissionSource.java
|
||||
+++ b/net/minecraft/commands/PermissionSource.java
|
||||
@@ -9,9 +_,20 @@
|
||||
return this.hasPermission(2);
|
||||
}
|
||||
|
||||
- public record Check<T extends PermissionSource>(@Override int requiredLevel) implements PermissionCheck<T> {
|
||||
+ public record Check<T extends PermissionSource>(@Override int requiredLevel, java.util.concurrent.atomic.AtomicReference<com.mojang.brigadier.tree.CommandNode<CommandSourceStack>> vanillaNode) implements PermissionCheck<T> { // Paper
|
||||
+ // Paper start - Vanilla Command permission checking
|
||||
+ public Check(int requiredLevel) {
|
||||
+ this(requiredLevel, new java.util.concurrent.atomic.AtomicReference<>());
|
||||
+ }
|
||||
+ // Paper end - Vanilla Command permission checking
|
||||
@Override
|
||||
public boolean test(T source) {
|
||||
+ // Paper start - Vanilla Command permission checking
|
||||
+ com.mojang.brigadier.tree.CommandNode<CommandSourceStack> currentCommand = vanillaNode.get();
|
||||
+ if (currentCommand != null && source instanceof CommandSourceStack commandSourceStack) {
|
||||
+ return commandSourceStack.hasPermission(this.requiredLevel, org.bukkit.craftbukkit.command.VanillaCommandWrapper.getPermission(currentCommand));
|
||||
+ }
|
||||
+ // Paper end - Vanilla Command permission checking
|
||||
return source.hasPermission(this.requiredLevel);
|
||||
}
|
||||
}
|
||||
@ -16,7 +16,7 @@
|
||||
if (entitySelector.getMaxResults() > 1 && this.single) {
|
||||
if (this.playersOnly) {
|
||||
reader.setCursor(0);
|
||||
@@ -129,7 +_,12 @@
|
||||
@@ -129,7 +_,13 @@
|
||||
if (context.getSource() instanceof SharedSuggestionProvider sharedSuggestionProvider) {
|
||||
StringReader stringReader = new StringReader(builder.getInput());
|
||||
stringReader.setCursor(builder.getStart());
|
||||
@ -24,7 +24,8 @@
|
||||
+ // Paper start - Fix EntityArgument permissions
|
||||
+ final boolean permission = sharedSuggestionProvider instanceof CommandSourceStack stack
|
||||
+ ? stack.bypassSelectorPermissions || stack.hasPermission(2, "minecraft.command.selector")
|
||||
+ : sharedSuggestionProvider.hasPermission(2);
|
||||
+ // Only CommandSourceStack implements SharedSuggestionProvider. If *somehow* anything else ends up here, try to query its permission level, otherwise yield false.
|
||||
+ : (sharedSuggestionProvider instanceof final net.minecraft.commands.PermissionSource permissionSource && permissionSource.hasPermission(2));
|
||||
+ EntitySelectorParser entitySelectorParser = new EntitySelectorParser(stringReader, permission);
|
||||
+ // Paper end - Fix EntityArgument permissions
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
}
|
||||
|
||||
private void checkPermissions(CommandSourceStack source) throws CommandSyntaxException {
|
||||
- if (this.usesSelector && !source.hasPermission(2)) {
|
||||
- if (this.usesSelector && !source.allowsSelectors()) {
|
||||
+ if (!source.bypassSelectorPermissions && (this.usesSelector && !source.hasPermission(2, "minecraft.command.selector"))) { // CraftBukkit // Paper - add bypass for selector perms
|
||||
throw EntityArgument.ERROR_SELECTORS_NOT_ALLOWED.create();
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
+ return stack.bypassSelectorPermissions || stack.hasPermission(2, "minecraft.command.selector");
|
||||
+ }
|
||||
+ // Paper end - Fix EntityArgument permissions
|
||||
return suggestionProvider instanceof SharedSuggestionProvider sharedSuggestionProvider && sharedSuggestionProvider.hasPermission(2);
|
||||
return suggestionProvider instanceof PermissionSource permissionSource && permissionSource.allowsSelectors();
|
||||
}
|
||||
|
||||
@@ -198,8 +_,10 @@
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
--- a/net/minecraft/core/HolderLookup.java
|
||||
+++ b/net/minecraft/core/HolderLookup.java
|
||||
@@ -68,6 +_,9 @@
|
||||
}
|
||||
|
||||
public interface RegistryLookup<T> extends HolderLookup<T>, HolderOwner<T> {
|
||||
+
|
||||
+ Optional<T> getValueForCopying(ResourceKey<T> resourceKey); // Paper - add method to get the value for pre-filling builders in the reg mod API
|
||||
+
|
||||
ResourceKey<? extends Registry<? extends T>> key();
|
||||
|
||||
Lifecycle registryLifecycle();
|
||||
@@ -80,6 +_,13 @@
|
||||
|
||||
default HolderLookup.RegistryLookup<T> filterElements(final Predicate<T> predicate) {
|
||||
return new HolderLookup.RegistryLookup.Delegate<T>() {
|
||||
+ // Paper start - add getValueForCopying
|
||||
+ @Override
|
||||
+ public Optional<T> getValueForCopying(final ResourceKey<T> resourceKey) {
|
||||
+ return this.parent().getValueForCopying(resourceKey).filter(predicate);
|
||||
+ }
|
||||
+ // Paper end - add getValueForCopying
|
||||
+
|
||||
@Override
|
||||
public HolderLookup.RegistryLookup<T> parent() {
|
||||
return RegistryLookup.this;
|
||||
@@ -99,6 +_,13 @@
|
||||
|
||||
public interface Delegate<T> extends HolderLookup.RegistryLookup<T> {
|
||||
HolderLookup.RegistryLookup<T> parent();
|
||||
+
|
||||
+ // Paper start - add getValueForCopying
|
||||
+ @Override
|
||||
+ default Optional<T> getValueForCopying(ResourceKey<T> resourceKey) {
|
||||
+ return this.parent().getValueForCopying(resourceKey);
|
||||
+ }
|
||||
+ // Paper end - add getValueForCopying
|
||||
|
||||
@Override
|
||||
default ResourceKey<? extends Registry<? extends T>> key() {
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/core/MappedRegistry.java
|
||||
+++ b/net/minecraft/core/MappedRegistry.java
|
||||
@@ -32,17 +_,18 @@
|
||||
@@ -32,17 +_,25 @@
|
||||
public class MappedRegistry<T> implements WritableRegistry<T> {
|
||||
private final ResourceKey<? extends Registry<T>> key;
|
||||
private final ObjectList<Holder.Reference<T>> byId = new ObjectArrayList<>(256);
|
||||
@ -20,7 +20,14 @@
|
||||
private boolean frozen;
|
||||
@Nullable
|
||||
private Map<T, Holder.Reference<T>> unregisteredIntrusiveHolders;
|
||||
+ public final Map<ResourceLocation, T> temporaryUnfrozenMap = new HashMap<>(); // Paper - support pre-filling in registry mod API
|
||||
+ // Paper start - support pre-filling in registry mod API
|
||||
+ private final Map<ResourceLocation, T> temporaryUnfrozenMap = new HashMap<>();
|
||||
+
|
||||
+ @Override
|
||||
+ public Optional<T> getValueForCopying(final ResourceKey<T> resourceKey) {
|
||||
+ return this.frozen ? this.getOptional(resourceKey) : Optional.ofNullable(this.temporaryUnfrozenMap.get(resourceKey.location()));
|
||||
+ }
|
||||
+ // Paper end - support pre-filling in registry mod API
|
||||
|
||||
@Override
|
||||
public Stream<HolderSet.Named<T>> listTags() {
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
--- a/net/minecraft/core/RegistrySetBuilder.java
|
||||
+++ b/net/minecraft/core/RegistrySetBuilder.java
|
||||
@@ -41,6 +_,13 @@
|
||||
final Map<ResourceKey<T>, Holder.Reference<T>> elements
|
||||
) {
|
||||
return new RegistrySetBuilder.EmptyTagRegistryLookup<T>(owner) {
|
||||
+ // Paper start - add getValueForCopying method
|
||||
+ @Override
|
||||
+ public Optional<T> getValueForCopying(final ResourceKey<T> resourceKey) {
|
||||
+ return this.get(resourceKey).map(Holder.Reference::value);
|
||||
+ }
|
||||
+ // Paper end - add getValueForCopying method
|
||||
+
|
||||
@Override
|
||||
public ResourceKey<? extends Registry<? extends T>> key() {
|
||||
return registryKey;
|
||||
@@ -121,6 +_,13 @@
|
||||
public <T> Optional<RegistryOps.RegistryInfo<T>> lookup(ResourceKey<? extends Registry<? extends T>> registryKey) {
|
||||
return getEntry(registryKey).map(Entry::opsInfo);
|
||||
}
|
||||
+
|
||||
+ // Paper start - add method to get the value for pre-filling builders in the reg mod API
|
||||
+ @Override
|
||||
+ public HolderLookup.Provider lookupForValueCopyViaBuilders() {
|
||||
+ throw new UnsupportedOperationException("Not implemented");
|
||||
+ }
|
||||
+ // Paper end - add method to get the value for pre-filling builders in the reg mod API
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -27,23 +27,27 @@
|
||||
+ // CraftBukkit end
|
||||
if (!serverLevel.isClientSide()) {
|
||||
BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING));
|
||||
- this.setSuccess(tryShearBeehive(serverLevel, blockPos) || tryShearLivingEntity(serverLevel, blockPos, item));
|
||||
+ this.setSuccess(tryShearBeehive(serverLevel, blockPos) || tryShearLivingEntity(serverLevel, blockPos, item, bukkitBlock, craftItem)); // CraftBukkit
|
||||
- this.setSuccess(tryShearBeehive(serverLevel, blockPos) || tryShearEntity(serverLevel, blockPos, item));
|
||||
+ this.setSuccess(tryShearBeehive(serverLevel, blockPos) || tryShearEntity(serverLevel, blockPos, item, bukkitBlock, craftItem)); // CraftBukkit
|
||||
if (this.isSuccess()) {
|
||||
item.hurtAndBreak(1, serverLevel, null, item1 -> {});
|
||||
}
|
||||
@@ -50,10 +_,18 @@
|
||||
@@ -50,14 +_,22 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
- private static boolean tryShearLivingEntity(ServerLevel level, BlockPos pos, ItemStack stack) {
|
||||
+ private static boolean tryShearLivingEntity(ServerLevel level, BlockPos pos, ItemStack stack, org.bukkit.block.Block bukkitBlock, org.bukkit.craftbukkit.inventory.CraftItemStack craftItem) { // CraftBukkit - add args
|
||||
for (LivingEntity livingEntity : level.getEntitiesOfClass(LivingEntity.class, new AABB(pos), EntitySelector.NO_SPECTATORS)) {
|
||||
if (livingEntity instanceof Shearable shearable && shearable.readyForShearing()) {
|
||||
- private static boolean tryShearEntity(ServerLevel level, BlockPos pos, ItemStack stack) {
|
||||
+ private static boolean tryShearEntity(ServerLevel level, BlockPos pos, ItemStack stack, org.bukkit.block.Block bukkitBlock, org.bukkit.craftbukkit.inventory.CraftItemStack craftItem) { // CraftBukkit - add args
|
||||
for (Entity entity : level.getEntitiesOfClass(Entity.class, new AABB(pos), EntitySelector.NO_SPECTATORS)) {
|
||||
if (entity.shearOffAllLeashConnections(null)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (entity instanceof Shearable shearable && shearable.readyForShearing()) {
|
||||
- shearable.shear(level, SoundSource.BLOCKS, stack);
|
||||
+ // CraftBukkit start
|
||||
+ // Paper start - Add drops to shear events
|
||||
+ org.bukkit.event.block.BlockShearEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockShearEntityEvent(livingEntity, bukkitBlock, craftItem, shearable.generateDefaultDrops(level, stack));
|
||||
+ org.bukkit.event.block.BlockShearEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockShearEntityEvent(entity, bukkitBlock, craftItem, shearable.generateDefaultDrops(level, stack));
|
||||
+ if (event.isCancelled()) {
|
||||
+ // Paper end - Add drops to shear events
|
||||
+ continue;
|
||||
|
||||
@ -1,32 +1,26 @@
|
||||
--- a/net/minecraft/core/registries/BuiltInRegistries.java
|
||||
+++ b/net/minecraft/core/registries/BuiltInRegistries.java
|
||||
@@ -311,6 +_,17 @@
|
||||
);
|
||||
@@ -325,6 +_,11 @@
|
||||
public static final Registry<MapCodec<? extends DialogBody>> DIALOG_BODY_TYPE = registerSimple(Registries.DIALOG_BODY_TYPE, DialogBodyTypes::bootstrap);
|
||||
public static final Registry<Consumer<GameTestHelper>> TEST_FUNCTION = registerSimple(Registries.TEST_FUNCTION, BuiltinTestFunctions::bootstrap);
|
||||
public static final Registry<? extends Registry<?>> REGISTRY = WRITABLE_REGISTRY;
|
||||
+ // Paper start - add built-in registry conversions
|
||||
+ public static final io.papermc.paper.registry.data.util.Conversions BUILT_IN_CONVERSIONS = new io.papermc.paper.registry.data.util.Conversions(new net.minecraft.resources.RegistryOps.RegistryInfoLookup() {
|
||||
+ @Override
|
||||
+ public <T> java.util.Optional<net.minecraft.resources.RegistryOps.RegistryInfo<T>> lookup(final ResourceKey<? extends Registry<? extends T>> registryRef) {
|
||||
+ final Registry<T> registry = net.minecraft.server.RegistryLayer.STATIC_ACCESS.lookupOrThrow(registryRef);
|
||||
+ return java.util.Optional.of(
|
||||
+ new net.minecraft.resources.RegistryOps.RegistryInfo<>(registry, registry, Lifecycle.experimental())
|
||||
+ );
|
||||
+ }
|
||||
+ });
|
||||
+ public static final io.papermc.paper.registry.data.util.Conversions STATIC_ACCESS_CONVERSIONS = new io.papermc.paper.registry.data.util.Conversions(
|
||||
+ new net.minecraft.resources.RegistryOps.HolderLookupAdapter(net.minecraft.server.RegistryLayer.STATIC_ACCESS)
|
||||
+ );
|
||||
+ // Paper end - add built-in registry conversions
|
||||
|
||||
private static <T> Registry<T> registerSimple(ResourceKey<? extends Registry<T>> key, BuiltInRegistries.RegistryBootstrap<T> bootstrap) {
|
||||
return internalRegister(key, new MappedRegistry<>(key, Lifecycle.stable(), false), bootstrap);
|
||||
@@ -336,6 +_,7 @@
|
||||
@@ -350,6 +_,7 @@
|
||||
ResourceKey<? extends Registry<T>> key, R registry, BuiltInRegistries.RegistryBootstrap<T> bootstrap
|
||||
) {
|
||||
Bootstrap.checkBootstrapCalled(() -> "registry " + key.location());
|
||||
+ io.papermc.paper.registry.PaperRegistryAccess.instance().registerRegistry(registry.key(), registry); // Paper - initialize API registry
|
||||
+ io.papermc.paper.registry.PaperRegistryAccess.instance().registerRegistry(registry); // Paper - initialize API registry
|
||||
ResourceLocation resourceLocation = key.location();
|
||||
LOADERS.put(resourceLocation, () -> bootstrap.run(registry));
|
||||
WRITABLE_REGISTRY.register((ResourceKey)key, registry, RegistrationInfo.BUILT_IN);
|
||||
@@ -343,16 +_,34 @@
|
||||
@@ -357,16 +_,34 @@
|
||||
}
|
||||
|
||||
public static void bootStrap() {
|
||||
@ -61,11 +55,11 @@
|
||||
});
|
||||
}
|
||||
|
||||
@@ -361,6 +_,7 @@
|
||||
@@ -375,6 +_,7 @@
|
||||
|
||||
for (Registry<?> registry : REGISTRY) {
|
||||
bindBootstrappedTagsToEmpty(registry);
|
||||
+ io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.runFreezeListeners(registry.key(), BUILT_IN_CONVERSIONS); // Paper
|
||||
+ io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.runFreezeListeners(registry.key(), STATIC_ACCESS_CONVERSIONS); // Paper
|
||||
registry.freeze();
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,4 +8,4 @@
|
||||
+ LevelStorageSource.LevelStorageAccess levelStorageAccess = LevelStorageSource.createDefault(Paths.get(string)).createAccess("gametestworld", net.minecraft.world.level.dimension.LevelStem.OVERWORLD); // Paper
|
||||
PackRepository packRepository = ServerPacksSource.createPackRepository(levelStorageAccess);
|
||||
MinecraftServer.spin(
|
||||
thread -> GameTestServer.create(thread, levelStorageAccess, packRepository, optionalFromOption(optionSet, tests), optionSet.has(verify))
|
||||
thread -> {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/gametest/framework/StructureUtils.java
|
||||
+++ b/net/minecraft/gametest/framework/StructureUtils.java
|
||||
@@ -86,7 +_,7 @@
|
||||
@@ -87,7 +_,7 @@
|
||||
level.clearBlockEvents(boundingBox1);
|
||||
AABB aabb = AABB.of(boundingBox1);
|
||||
List<Entity> entitiesOfClass = level.getEntitiesOfClass(Entity.class, aabb, entity -> !(entity instanceof Player));
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
@Override
|
||||
public CompoundTag copy() {
|
||||
- HashMap<String, Tag> map = new HashMap<>();
|
||||
- this.tags.forEach((string, tag) -> map.put(string, tag.copy()));
|
||||
- this.tags.forEach((key, value) -> map.put(key, value.copy()));
|
||||
- return new CompoundTag(map);
|
||||
+ // Paper start - Reduce memory footprint of CompoundTag
|
||||
+ it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<String, Tag> ret = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(this.tags.size(), 0.8f);
|
||||
|
||||
@ -192,7 +192,7 @@
|
||||
} catch (RejectedExecutionException var6) {
|
||||
this.disconnect(Component.translatable("multiplayer.disconnect.server_shutdown"));
|
||||
} catch (ClassCastException var7) {
|
||||
@@ -385,10 +_,30 @@
|
||||
@@ -373,10 +_,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,7 +223,7 @@
|
||||
}
|
||||
|
||||
if (!this.isConnected() && !this.disconnectionHandled) {
|
||||
@@ -396,7 +_,7 @@
|
||||
@@ -384,7 +_,7 @@
|
||||
}
|
||||
|
||||
if (this.channel != null) {
|
||||
@ -232,7 +232,7 @@
|
||||
}
|
||||
|
||||
if (this.tickCount++ % 20 == 0) {
|
||||
@@ -432,12 +_,13 @@
|
||||
@@ -420,12 +_,13 @@
|
||||
}
|
||||
|
||||
public void disconnect(DisconnectionDetails disconnectionDetails) {
|
||||
@ -247,7 +247,7 @@
|
||||
this.disconnectionDetails = disconnectionDetails;
|
||||
}
|
||||
}
|
||||
@@ -584,6 +_,13 @@
|
||||
@@ -572,6 +_,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,7 +261,7 @@
|
||||
public void setupCompression(int threshold, boolean validateDecompressed) {
|
||||
if (threshold >= 0) {
|
||||
if (this.channel.pipeline().get("decompress") instanceof CompressionDecoder compressionDecoder) {
|
||||
@@ -597,6 +_,7 @@
|
||||
@@ -585,6 +_,7 @@
|
||||
} else {
|
||||
this.channel.pipeline().addAfter("prepender", "compress", new CompressionEncoder(threshold));
|
||||
}
|
||||
@ -269,7 +269,7 @@
|
||||
} else {
|
||||
if (this.channel.pipeline().get("decompress") instanceof CompressionDecoder) {
|
||||
this.channel.pipeline().remove("decompress");
|
||||
@@ -605,6 +_,7 @@
|
||||
@@ -593,6 +_,7 @@
|
||||
if (this.channel.pipeline().get("compress") instanceof CompressionEncoder) {
|
||||
this.channel.pipeline().remove("compress");
|
||||
}
|
||||
@ -277,7 +277,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -622,6 +_,26 @@
|
||||
@@ -610,6 +_,26 @@
|
||||
);
|
||||
packetListener1.onDisconnect(disconnectionDetails);
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/network/FriendlyByteBuf.java
|
||||
+++ b/net/minecraft/network/FriendlyByteBuf.java
|
||||
@@ -70,14 +_,20 @@
|
||||
@@ -71,14 +_,20 @@
|
||||
public class FriendlyByteBuf extends ByteBuf {
|
||||
public static final int DEFAULT_NBT_QUOTA = 2097152;
|
||||
private final ByteBuf source;
|
||||
@ -21,7 +21,7 @@
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@@ -106,8 +_,13 @@
|
||||
@@ -107,8 +_,13 @@
|
||||
}
|
||||
|
||||
public <T> void writeJsonWithCodec(Codec<T> codec, T value) {
|
||||
@ -36,7 +36,7 @@
|
||||
}
|
||||
|
||||
public static <T> IntFunction<T> limitValue(IntFunction<T> function, int limit) {
|
||||
@@ -539,7 +_,7 @@
|
||||
@@ -556,7 +_,7 @@
|
||||
|
||||
try {
|
||||
NbtIo.writeAnyTag(nbt, new ByteBufOutputStream(buffer));
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/network/chat/Component.java
|
||||
+++ b/net/minecraft/network/chat/Component.java
|
||||
@@ -37,7 +_,19 @@
|
||||
@@ -23,7 +_,19 @@
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/network/codec/ByteBufCodecs.java
|
||||
+++ b/net/minecraft/network/codec/ByteBufCodecs.java
|
||||
@@ -389,6 +_,48 @@
|
||||
@@ -435,6 +_,48 @@
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
throw new RuntimeException("Chunk Packet trying to allocate too much memory on read.");
|
||||
} else {
|
||||
this.buffer = new byte[varInt];
|
||||
@@ -151,6 +_,7 @@
|
||||
@@ -155,6 +_,7 @@
|
||||
CompoundTag updateTag = blockEntity.getUpdateTag(blockEntity.getLevel().registryAccess());
|
||||
BlockPos blockPos = blockEntity.getBlockPos();
|
||||
int i = SectionPos.sectionRelative(blockPos.getX()) << 4 | SectionPos.sectionRelative(blockPos.getZ());
|
||||
|
||||
@ -1,21 +1,30 @@
|
||||
--- a/net/minecraft/network/protocol/login/ClientboundLoginDisconnectPacket.java
|
||||
+++ b/net/minecraft/network/protocol/login/ClientboundLoginDisconnectPacket.java
|
||||
@@ -18,11 +_,16 @@
|
||||
}
|
||||
@@ -14,8 +_,25 @@
|
||||
|
||||
private ClientboundLoginDisconnectPacket(FriendlyByteBuf buffer) {
|
||||
- this.reason = Component.Serializer.fromJsonLenient(buffer.readUtf(262144), RegistryAccess.EMPTY);
|
||||
+ this.reason = Component.Serializer.fromJsonLenient(buffer.readUtf(FriendlyByteBuf.MAX_COMPONENT_STRING_LENGTH), RegistryAccess.EMPTY); // Paper - diff on change
|
||||
}
|
||||
|
||||
private void write(FriendlyByteBuf buffer) {
|
||||
- buffer.writeUtf(Component.Serializer.toJson(this.reason, RegistryAccess.EMPTY));
|
||||
+ // Paper start - Adventure
|
||||
+ // buffer.writeUtf(Component.Serializer.toJson(this.reason, RegistryAccess.EMPTY));
|
||||
+ // In the login phase, buffer.adventure$locale field is most likely null, but plugins may use internals to set it via the channel attribute
|
||||
+ java.util.Locale bufLocale = buffer.adventure$locale;
|
||||
+ buffer.writeJsonWithCodec(net.minecraft.network.chat.ComponentSerialization.localizedCodec(bufLocale == null ? java.util.Locale.US : bufLocale), this.reason, FriendlyByteBuf.MAX_COMPONENT_STRING_LENGTH);
|
||||
+ // Paper end - Adventure
|
||||
}
|
||||
|
||||
@Override
|
||||
public record ClientboundLoginDisconnectPacket(Component reason) implements Packet<ClientLoginPacketListener> {
|
||||
private static final RegistryOps<JsonElement> OPS = RegistryAccess.EMPTY.createSerializationContext(JsonOps.INSTANCE);
|
||||
- public static final StreamCodec<ByteBuf, ClientboundLoginDisconnectPacket> STREAM_CODEC = StreamCodec.composite(
|
||||
- ByteBufCodecs.lenientJson(262144).apply(ByteBufCodecs.fromCodec(OPS, ComponentSerialization.CODEC)),
|
||||
+ // Paper start - localized codec
|
||||
+ // In the login phase, buffer.adventure$locale field is most likely null, but plugins may use internals to set it via the channel attribute
|
||||
+ public static final StreamCodec<net.minecraft.network.FriendlyByteBuf, ClientboundLoginDisconnectPacket> STREAM_CODEC = StreamCodec.composite(
|
||||
+ new StreamCodec<>() {
|
||||
+
|
||||
+ private static final net.minecraft.network.codec.StreamCodec<ByteBuf, JsonElement> LENIENT_JSON = ByteBufCodecs.lenientJson(net.minecraft.network.FriendlyByteBuf.MAX_COMPONENT_STRING_LENGTH);
|
||||
+ @Override
|
||||
+ public Component decode(final net.minecraft.network.FriendlyByteBuf buffer) {
|
||||
+ java.util.Locale bufLocale = buffer.adventure$locale;
|
||||
+ return LENIENT_JSON.apply(ByteBufCodecs.fromCodec(OPS, ComponentSerialization.localizedCodec(bufLocale == null ? java.util.Locale.US : bufLocale))).decode(buffer);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void encode(final net.minecraft.network.FriendlyByteBuf buffer, final Component value) {
|
||||
+ java.util.Locale bufLocale = buffer.adventure$locale;
|
||||
+ LENIENT_JSON.apply(ByteBufCodecs.fromCodec(OPS, ComponentSerialization.localizedCodec(bufLocale == null ? java.util.Locale.US : bufLocale))).encode(buffer, value);
|
||||
+ }
|
||||
+ },
|
||||
+ // Paper end - localized codec
|
||||
ClientboundLoginDisconnectPacket::reason,
|
||||
ClientboundLoginDisconnectPacket::new
|
||||
);
|
||||
|
||||
@ -1,6 +1,28 @@
|
||||
--- a/net/minecraft/resources/RegistryDataLoader.java
|
||||
+++ b/net/minecraft/resources/RegistryDataLoader.java
|
||||
@@ -271,13 +_,14 @@
|
||||
@@ -206,11 +_,21 @@
|
||||
final Map<ResourceKey<? extends Registry<?>>, RegistryOps.RegistryInfo<?>> map = new HashMap<>();
|
||||
registryLookups.forEach(registryLookup -> map.put(registryLookup.key(), createInfoForContextRegistry((HolderLookup.RegistryLookup<?>)registryLookup)));
|
||||
loaders.forEach(loader -> map.put(loader.registry.key(), createInfoForNewRegistry(loader.registry)));
|
||||
+ // this creates a HolderLookup.Provider to be used exclusively to obtain real instances of values to pre-populate builders
|
||||
+ // for the Registry Modification API. This concatenates the context registry lookups and the empty registries about to be filled.
|
||||
+ final HolderLookup.Provider providerForBuilders = HolderLookup.Provider.create(java.util.stream.Stream.concat(registryLookups.stream(), loaders.stream().map(Loader::registry))); // Paper - add method to get the value for pre-filling builders in the reg mod API
|
||||
return new RegistryOps.RegistryInfoLookup() {
|
||||
@Override
|
||||
public <T> Optional<RegistryOps.RegistryInfo<T>> lookup(ResourceKey<? extends Registry<? extends T>> registryKey) {
|
||||
return Optional.ofNullable((RegistryOps.RegistryInfo<T>)map.get(registryKey));
|
||||
}
|
||||
+
|
||||
+ // Paper start - add method to get the value for pre-filling builders in the reg mod API
|
||||
+ @Override
|
||||
+ public HolderLookup.Provider lookupForValueCopyViaBuilders() {
|
||||
+ return providerForBuilders;
|
||||
+ }
|
||||
+ // Paper end - add method to get the value for pre-filling builders in the reg mod API
|
||||
};
|
||||
}
|
||||
|
||||
@@ -274,13 +_,14 @@
|
||||
RegistryOps<JsonElement> ops,
|
||||
ResourceKey<E> resourceKey,
|
||||
Resource resource,
|
||||
@ -9,7 +31,7 @@
|
||||
+ io.papermc.paper.registry.data.util.Conversions conversions // Paper - pass conversions
|
||||
) throws IOException {
|
||||
try (Reader reader = resource.openAsReader()) {
|
||||
JsonElement jsonElement = JsonParser.parseReader(reader);
|
||||
JsonElement jsonElement = StrictJsonParser.parse(reader);
|
||||
DataResult<E> dataResult = codec.parse(ops, jsonElement);
|
||||
E orThrow = dataResult.getOrThrow();
|
||||
- registry.register(resourceKey, orThrow, registrationInfo);
|
||||
@ -17,7 +39,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,6 +_,7 @@
|
||||
@@ -294,6 +_,7 @@
|
||||
FileToIdConverter fileToIdConverter = FileToIdConverter.registry(registry.key());
|
||||
RegistryOps<JsonElement> registryOps = RegistryOps.create(JsonOps.INSTANCE, registryInfoLookup);
|
||||
|
||||
@ -25,7 +47,7 @@
|
||||
for (Entry<ResourceLocation, Resource> entry : fileToIdConverter.listMatchingResources(resourceManager).entrySet()) {
|
||||
ResourceLocation resourceLocation = entry.getKey();
|
||||
ResourceKey<E> resourceKey = ResourceKey.create(registry.key(), fileToIdConverter.fileToId(resourceLocation));
|
||||
@@ -298,7 +_,7 @@
|
||||
@@ -301,7 +_,7 @@
|
||||
RegistrationInfo registrationInfo = REGISTRATION_INFO_CACHE.apply(resource.knownPackInfo());
|
||||
|
||||
try {
|
||||
@ -34,7 +56,7 @@
|
||||
} catch (Exception var14) {
|
||||
loadingErrors.put(
|
||||
resourceKey,
|
||||
@@ -307,7 +_,9 @@
|
||||
@@ -310,7 +_,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,7 +67,7 @@
|
||||
}
|
||||
|
||||
static <E> void loadContentsFromNetwork(
|
||||
@@ -324,6 +_,7 @@
|
||||
@@ -327,6 +_,7 @@
|
||||
RegistryOps<JsonElement> registryOps1 = RegistryOps.create(JsonOps.INSTANCE, registryInfoLookup);
|
||||
FileToIdConverter fileToIdConverter = FileToIdConverter.registry(registry.key());
|
||||
|
||||
@ -53,7 +75,7 @@
|
||||
for (RegistrySynchronization.PackedRegistryEntry packedRegistryEntry : networkedRegistryData.elements) {
|
||||
ResourceKey<E> resourceKey = ResourceKey.create(registry.key(), packedRegistryEntry.id());
|
||||
Optional<Tag> optional = packedRegistryEntry.data();
|
||||
@@ -342,7 +_,7 @@
|
||||
@@ -345,7 +_,7 @@
|
||||
|
||||
try {
|
||||
Resource resourceOrThrow = resourceProvider.getResourceOrThrow(resourceLocation);
|
||||
@ -62,11 +84,11 @@
|
||||
} catch (Exception var17) {
|
||||
loadingErrors.put(resourceKey, new IllegalStateException("Failed to parse local data", var17));
|
||||
}
|
||||
@@ -384,6 +_,7 @@
|
||||
@@ -387,6 +_,7 @@
|
||||
|
||||
RegistryDataLoader.Loader<T> create(Lifecycle registryLifecycle, Map<ResourceKey<?>, Exception> loadingErrors) {
|
||||
WritableRegistry<T> writableRegistry = new MappedRegistry<>(this.key, registryLifecycle);
|
||||
+ io.papermc.paper.registry.PaperRegistryAccess.instance().registerRegistry(this.key, writableRegistry); // Paper - initialize API registry
|
||||
+ io.papermc.paper.registry.PaperRegistryAccess.instance().registerRegistry(writableRegistry); // Paper - initialize API registry
|
||||
return new RegistryDataLoader.Loader<>(this, writableRegistry, loadingErrors);
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
--- a/net/minecraft/resources/RegistryOps.java
|
||||
+++ b/net/minecraft/resources/RegistryOps.java
|
||||
@@ -117,6 +_,13 @@
|
||||
public int hashCode() {
|
||||
return this.lookupProvider.hashCode();
|
||||
}
|
||||
+
|
||||
+ // Paper start - add method to get the value for pre-filling builders in the reg mod API
|
||||
+ @Override
|
||||
+ public HolderLookup.Provider lookupForValueCopyViaBuilders() {
|
||||
+ return this.lookupProvider;
|
||||
+ }
|
||||
+ // Paper end - add method to get the value for pre-filling builders in the reg mod API
|
||||
}
|
||||
|
||||
public record RegistryInfo<T>(HolderOwner<T> owner, HolderGetter<T> getter, Lifecycle elementsLifecycle) {
|
||||
@@ -127,5 +_,7 @@
|
||||
|
||||
public interface RegistryInfoLookup {
|
||||
<T> Optional<RegistryOps.RegistryInfo<T>> lookup(ResourceKey<? extends Registry<? extends T>> registryKey);
|
||||
+
|
||||
+ HolderLookup.Provider lookupForValueCopyViaBuilders(); // Paper - add method to get the value for pre-filling builders in the reg mod API
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/Main.java
|
||||
+++ b/net/minecraft/server/Main.java
|
||||
@@ -67,8 +_,10 @@
|
||||
@@ -68,8 +_,10 @@
|
||||
reason = "System.out needed before bootstrap"
|
||||
)
|
||||
@DontObfuscate
|
||||
@ -12,7 +12,7 @@
|
||||
OptionParser optionParser = new OptionParser();
|
||||
OptionSpec<Void> optionSpec = optionParser.accepts("nogui");
|
||||
OptionSpec<Void> optionSpec1 = optionParser.accepts("initSettings", "Initializes 'server.properties' and 'eula.txt', then quits");
|
||||
@@ -93,41 +_,94 @@
|
||||
@@ -94,41 +_,94 @@
|
||||
optionParser.printHelpOn(System.err);
|
||||
return;
|
||||
}
|
||||
@ -116,7 +116,7 @@
|
||||
Dynamic<?> dataTag;
|
||||
if (levelStorageAccess.hasWorldData()) {
|
||||
LevelSummary summary;
|
||||
@@ -169,12 +_,33 @@
|
||||
@@ -170,12 +_,33 @@
|
||||
}
|
||||
|
||||
Dynamic<?> dynamic = dataTag;
|
||||
@ -141,7 +141,7 @@
|
||||
+ "pack_format": %d
|
||||
+ }
|
||||
+ }
|
||||
+ """.formatted(SharedConstants.getCurrentVersion().getPackVersion(net.minecraft.server.packs.PackType.SERVER_DATA))
|
||||
+ """.formatted(SharedConstants.getCurrentVersion().packVersion(net.minecraft.server.packs.PackType.SERVER_DATA))
|
||||
+ );
|
||||
+ } catch (java.io.IOException ex) {
|
||||
+ throw new RuntimeException("Could not initialize Bukkit datapack", ex);
|
||||
@ -151,7 +151,7 @@
|
||||
|
||||
WorldStem worldStem;
|
||||
try {
|
||||
@@ -183,6 +_,7 @@
|
||||
@@ -184,6 +_,7 @@
|
||||
executor -> WorldLoader.load(
|
||||
initConfig,
|
||||
context -> {
|
||||
@ -159,7 +159,7 @@
|
||||
Registry<LevelStem> registry = context.datapackDimensions().lookupOrThrow(Registries.LEVEL_STEM);
|
||||
if (dynamic != null) {
|
||||
LevelDataAndDimensions levelDataAndDimensions = LevelStorageSource.getLevelDataAndDimensions(
|
||||
@@ -196,7 +_,7 @@
|
||||
@@ -197,7 +_,7 @@
|
||||
LevelSettings levelSettings;
|
||||
WorldOptions worldOptions;
|
||||
WorldDimensions worldDimensions;
|
||||
@ -168,7 +168,7 @@
|
||||
levelSettings = MinecraftServer.DEMO_SETTINGS;
|
||||
worldOptions = WorldOptions.DEMO_OPTIONS;
|
||||
worldDimensions = WorldPresets.createNormalWorldDimensions(context.datapackWorldgen());
|
||||
@@ -211,7 +_,7 @@
|
||||
@@ -212,7 +_,7 @@
|
||||
new GameRules(context.dataConfiguration().enabledFeatures()),
|
||||
context.dataConfiguration()
|
||||
);
|
||||
@ -177,7 +177,7 @@
|
||||
worldDimensions = properties.createDimensions(context.datapackWorldgen());
|
||||
}
|
||||
|
||||
@@ -237,6 +_,7 @@
|
||||
@@ -238,6 +_,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
@ -185,7 +185,7 @@
|
||||
RegistryAccess.Frozen frozen = worldStem.registries().compositeAccess();
|
||||
WorldData worldData = worldStem.worldData();
|
||||
boolean hasOptionSpec1 = optionSet.has(optionSpec6);
|
||||
@@ -245,9 +_,13 @@
|
||||
@@ -246,9 +_,13 @@
|
||||
}
|
||||
|
||||
levelStorageAccess.saveDataTag(frozen, worldData);
|
||||
@ -199,7 +199,7 @@
|
||||
thread1,
|
||||
levelStorageAccess,
|
||||
packRepository,
|
||||
@@ -257,17 +_,34 @@
|
||||
@@ -258,18 +_,36 @@
|
||||
services,
|
||||
LoggerChunkProgressListener::createFromGameruleRadius
|
||||
);
|
||||
@ -221,14 +221,16 @@
|
||||
if (flag && !GraphicsEnvironment.isHeadless()) {
|
||||
dedicatedServer1.showGui();
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ if (optionSet.has("port")) {
|
||||
+ int port = (Integer) optionSet.valueOf("port");
|
||||
+ if (port > 0) {
|
||||
+ dedicatedServer1.setPort(port);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Paper end
|
||||
|
||||
GameTestTicker.SINGLETON.startTicking();
|
||||
return dedicatedServer1;
|
||||
}
|
||||
);
|
||||
@ -236,7 +238,7 @@
|
||||
Thread thread = new Thread("Server Shutdown Thread") {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -276,6 +_,7 @@
|
||||
@@ -278,6 +_,7 @@
|
||||
};
|
||||
thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER));
|
||||
Runtime.getRuntime().addShutdownHook(thread);
|
||||
@ -244,7 +246,7 @@
|
||||
} catch (Exception var42) {
|
||||
LOGGER.error(LogUtils.FATAL_MARKER, "Failed to start the minecraft server", (Throwable)var42);
|
||||
}
|
||||
@@ -317,7 +_,7 @@
|
||||
@@ -319,7 +_,7 @@
|
||||
RegistryAccess registryAccess,
|
||||
boolean recreateRegionFiles
|
||||
) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -173,11 +_,13 @@
|
||||
@@ -174,11 +_,13 @@
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTask> implements ServerInfo, ChunkIOErrorReporter, CommandSource {
|
||||
@ -15,7 +15,7 @@
|
||||
private static final int OVERLOADED_TICKS_THRESHOLD = 20;
|
||||
private static final long OVERLOADED_WARNING_INTERVAL_NANOS = 10L * TimeUtil.NANOSECONDS_PER_SECOND;
|
||||
private static final int OVERLOADED_TICKS_WARNING_INTERVAL = 100;
|
||||
@@ -217,6 +_,7 @@
|
||||
@@ -218,6 +_,7 @@
|
||||
private Map<ResourceKey<Level>, ServerLevel> levels = Maps.newLinkedHashMap();
|
||||
private PlayerList playerList;
|
||||
private volatile boolean running = true;
|
||||
@ -23,7 +23,7 @@
|
||||
private boolean stopped;
|
||||
private int tickCount;
|
||||
private int ticksUntilAutosave = 6000;
|
||||
@@ -225,11 +_,15 @@
|
||||
@@ -226,11 +_,15 @@
|
||||
private boolean preventProxyConnections;
|
||||
private boolean pvp;
|
||||
private boolean allowFlight;
|
||||
@ -41,7 +41,7 @@
|
||||
@Nullable
|
||||
private KeyPair keyPair;
|
||||
@Nullable
|
||||
@@ -270,10 +_,37 @@
|
||||
@@ -271,10 +_,37 @@
|
||||
private final SuppressedExceptionCollector suppressedExceptions = new SuppressedExceptionCollector();
|
||||
private final DiscontinuousFrame tickFrame;
|
||||
|
||||
@ -80,7 +80,7 @@
|
||||
if (Runtime.getRuntime().availableProcessors() > 4) {
|
||||
thread.setPriority(8);
|
||||
}
|
||||
@@ -285,6 +_,10 @@
|
||||
@@ -286,6 +_,10 @@
|
||||
}
|
||||
|
||||
public MinecraftServer(
|
||||
@ -91,7 +91,7 @@
|
||||
Thread serverThread,
|
||||
LevelStorageSource.LevelStorageAccess storageSource,
|
||||
PackRepository packRepository,
|
||||
@@ -295,9 +_,10 @@
|
||||
@@ -296,9 +_,10 @@
|
||||
ChunkProgressListenerFactory progressListenerFactory
|
||||
) {
|
||||
super("Server");
|
||||
@ -103,7 +103,7 @@
|
||||
throw new IllegalStateException("Missing Overworld dimension data");
|
||||
} else {
|
||||
this.proxy = proxy;
|
||||
@@ -308,7 +_,7 @@
|
||||
@@ -309,7 +_,7 @@
|
||||
services.profileCache().setExecutor(this);
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@
|
||||
this.tickRateManager = new ServerTickRateManager(this);
|
||||
this.progressListenerFactory = progressListenerFactory;
|
||||
this.storageSource = storageSource;
|
||||
@@ -327,6 +_,38 @@
|
||||
@@ -328,6 +_,38 @@
|
||||
this.fuelValues = FuelValues.vanillaBurnTimes(this.registries.compositeAccess(), this.worldData.enabledFeatures());
|
||||
this.tickFrame = TracyClient.createDiscontinuousFrame("Server Tick");
|
||||
}
|
||||
@ -151,7 +151,7 @@
|
||||
}
|
||||
|
||||
private void readScoreboard(DimensionDataStorage dataStorage) {
|
||||
@@ -335,18 +_,13 @@
|
||||
@@ -336,18 +_,13 @@
|
||||
|
||||
protected abstract boolean initServer() throws IOException;
|
||||
|
||||
@ -172,7 +172,7 @@
|
||||
if (profiledDuration != null) {
|
||||
profiledDuration.finish(true);
|
||||
}
|
||||
@@ -363,25 +_,265 @@
|
||||
@@ -364,25 +_,265 @@
|
||||
protected void forceDifficulty() {
|
||||
}
|
||||
|
||||
@ -457,7 +457,7 @@
|
||||
if (!serverLevelData.isInitialized()) {
|
||||
try {
|
||||
setInitialSpawn(serverLevel, serverLevelData, worldOptions.generateBonusChest(), isDebugWorld);
|
||||
@@ -402,47 +_,30 @@
|
||||
@@ -403,47 +_,30 @@
|
||||
|
||||
serverLevelData.setInitialized(true);
|
||||
}
|
||||
@ -522,7 +522,7 @@
|
||||
int spawnHeight = chunkSource.getGenerator().getSpawnHeight(level);
|
||||
if (spawnHeight < level.getMinY()) {
|
||||
BlockPos worldPosition = chunkPos.getWorldPosition();
|
||||
@@ -494,36 +_,48 @@
|
||||
@@ -495,36 +_,48 @@
|
||||
serverLevelData.setGameType(GameType.SPECTATOR);
|
||||
}
|
||||
|
||||
@ -582,7 +582,7 @@
|
||||
}
|
||||
|
||||
public GameType getDefaultGameType() {
|
||||
@@ -552,11 +_,14 @@
|
||||
@@ -553,11 +_,14 @@
|
||||
flag = true;
|
||||
}
|
||||
|
||||
@ -597,7 +597,7 @@
|
||||
if (flush) {
|
||||
for (ServerLevel serverLevel2 : this.getAllLevels()) {
|
||||
LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", serverLevel2.getChunkSource().chunkMap.getStorageName());
|
||||
@@ -586,18 +_,48 @@
|
||||
@@ -587,18 +_,48 @@
|
||||
this.stopServer();
|
||||
}
|
||||
|
||||
@ -647,7 +647,7 @@
|
||||
}
|
||||
|
||||
LOGGER.info("Saving worlds");
|
||||
@@ -639,6 +_,25 @@
|
||||
@@ -640,6 +_,25 @@
|
||||
} catch (IOException var4) {
|
||||
LOGGER.error("Failed to unlock level {}", this.storageSource.getLevelId(), var4);
|
||||
}
|
||||
@ -673,7 +673,7 @@
|
||||
}
|
||||
|
||||
public String getLocalIp() {
|
||||
@@ -654,6 +_,14 @@
|
||||
@@ -655,6 +_,14 @@
|
||||
}
|
||||
|
||||
public void halt(boolean waitForServer) {
|
||||
@ -688,7 +688,7 @@
|
||||
this.running = false;
|
||||
if (waitForServer) {
|
||||
try {
|
||||
@@ -664,6 +_,57 @@
|
||||
@@ -665,6 +_,57 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -746,7 +746,7 @@
|
||||
protected void runServer() {
|
||||
try {
|
||||
if (!this.initServer()) {
|
||||
@@ -674,6 +_,35 @@
|
||||
@@ -675,6 +_,35 @@
|
||||
this.statusIcon = this.loadStatusIcon().orElse(null);
|
||||
this.status = this.buildServerStatus();
|
||||
|
||||
@ -782,7 +782,7 @@
|
||||
while (this.running) {
|
||||
long l;
|
||||
if (!this.isPaused() && this.tickRateManager.isSprinting() && this.tickRateManager.checkShouldSprintThisTick()) {
|
||||
@@ -686,11 +_,30 @@
|
||||
@@ -687,11 +_,30 @@
|
||||
if (l1 > OVERLOADED_THRESHOLD_NANOS + 20L * l
|
||||
&& this.nextTickTimeNanos - this.lastOverloadWarningNanos >= OVERLOADED_WARNING_INTERVAL_NANOS + 100L * l) {
|
||||
long l2 = l1 / l;
|
||||
@ -813,7 +813,7 @@
|
||||
|
||||
boolean flag = l == 0L;
|
||||
if (this.debugCommandProfilerDelayStart) {
|
||||
@@ -698,6 +_,8 @@
|
||||
@@ -699,6 +_,8 @@
|
||||
this.debugCommandProfiler = new MinecraftServer.TimeProfiler(Util.getNanos(), this.tickCount);
|
||||
}
|
||||
|
||||
@ -822,7 +822,7 @@
|
||||
this.nextTickTimeNanos += l;
|
||||
|
||||
try (Profiler.Scope scope = Profiler.use(this.createProfiler())) {
|
||||
@@ -748,7 +_,7 @@
|
||||
@@ -749,7 +_,7 @@
|
||||
this.services.profileCache().clearExecutor();
|
||||
}
|
||||
|
||||
@ -831,7 +831,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -800,7 +_,14 @@
|
||||
@@ -801,7 +_,14 @@
|
||||
}
|
||||
|
||||
private boolean haveTime() {
|
||||
@ -847,7 +847,7 @@
|
||||
}
|
||||
|
||||
public static boolean throwIfFatalException() {
|
||||
@@ -845,6 +_,12 @@
|
||||
@@ -846,6 +_,12 @@
|
||||
|
||||
@Override
|
||||
public TickTask wrapRunnable(Runnable runnable) {
|
||||
@ -860,7 +860,7 @@
|
||||
return new TickTask(this.tickCount, runnable);
|
||||
}
|
||||
|
||||
@@ -864,15 +_,16 @@
|
||||
@@ -865,15 +_,16 @@
|
||||
if (super.pollTask()) {
|
||||
return true;
|
||||
} else {
|
||||
@ -879,7 +879,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -920,26 +_,44 @@
|
||||
@@ -921,26 +_,44 @@
|
||||
}
|
||||
|
||||
public void tickServer(BooleanSupplier hasTimeLeft) {
|
||||
@ -925,7 +925,7 @@
|
||||
this.tickCount++;
|
||||
this.tickRateManager.tick();
|
||||
this.tickChildren(hasTimeLeft);
|
||||
@@ -949,11 +_,19 @@
|
||||
@@ -950,11 +_,19 @@
|
||||
}
|
||||
|
||||
this.ticksUntilAutosave--;
|
||||
@ -946,7 +946,7 @@
|
||||
profilerFiller.push("tallying");
|
||||
long l = Util.getNanos() - nanos;
|
||||
int i1 = this.tickCount % 100;
|
||||
@@ -961,12 +_,17 @@
|
||||
@@ -962,12 +_,17 @@
|
||||
this.aggregatedTickTimesNanos += l;
|
||||
this.tickTimesNanos[i1] = l;
|
||||
this.smoothedTickTimeMillis = this.smoothedTickTimeMillis * 0.8F + (float)l / (float)TimeUtil.NANOSECONDS_PER_MILLISECOND * 0.19999999F;
|
||||
@ -965,7 +965,7 @@
|
||||
LOGGER.debug("Autosave started");
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
profilerFiller.push("save");
|
||||
@@ -1008,7 +_,7 @@
|
||||
@@ -1009,7 +_,7 @@
|
||||
private ServerStatus buildServerStatus() {
|
||||
ServerStatus.Players players = this.buildPlayerStatus();
|
||||
return new ServerStatus(
|
||||
@ -974,7 +974,7 @@
|
||||
Optional.of(players),
|
||||
Optional.of(ServerStatus.Version.current()),
|
||||
Optional.ofNullable(this.statusIcon),
|
||||
@@ -1022,7 +_,7 @@
|
||||
@@ -1023,7 +_,7 @@
|
||||
if (this.hidesOnlinePlayers()) {
|
||||
return new ServerStatus.Players(maxPlayers, players.size(), List.of());
|
||||
} else {
|
||||
@ -983,7 +983,7 @@
|
||||
ObjectArrayList<GameProfile> list = new ObjectArrayList<>(min);
|
||||
int randomInt = Mth.nextInt(this.random, 0, players.size() - min);
|
||||
|
||||
@@ -1039,17 +_,66 @@
|
||||
@@ -1040,17 +_,66 @@
|
||||
protected void tickChildren(BooleanSupplier hasTimeLeft) {
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
this.getPlayerList().getPlayers().forEach(serverPlayer1 -> serverPlayer1.connection.suspendFlushing());
|
||||
@ -1050,7 +1050,7 @@
|
||||
|
||||
profilerFiller.push("tick");
|
||||
|
||||
@@ -1063,7 +_,9 @@
|
||||
@@ -1064,7 +_,9 @@
|
||||
|
||||
profilerFiller.pop();
|
||||
profilerFiller.pop();
|
||||
@ -1060,7 +1060,7 @@
|
||||
|
||||
profilerFiller.popPush("connection");
|
||||
this.tickConnection();
|
||||
@@ -1141,6 +_,22 @@
|
||||
@@ -1142,6 +_,22 @@
|
||||
return this.levels.get(dimension);
|
||||
}
|
||||
|
||||
@ -1083,7 +1083,7 @@
|
||||
public Set<ResourceKey<Level>> levelKeys() {
|
||||
return this.levels.keySet();
|
||||
}
|
||||
@@ -1170,7 +_,7 @@
|
||||
@@ -1171,7 +_,7 @@
|
||||
|
||||
@DontObfuscate
|
||||
public String getServerModName() {
|
||||
@ -1092,7 +1092,7 @@
|
||||
}
|
||||
|
||||
public SystemReport fillSystemReport(SystemReport systemReport) {
|
||||
@@ -1205,7 +_,7 @@
|
||||
@@ -1206,7 +_,7 @@
|
||||
|
||||
@Override
|
||||
public void sendSystemMessage(Component component) {
|
||||
@ -1101,7 +1101,7 @@
|
||||
}
|
||||
|
||||
public KeyPair getKeyPair() {
|
||||
@@ -1243,11 +_,14 @@
|
||||
@@ -1244,11 +_,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -1121,7 +1121,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1257,7 +_,7 @@
|
||||
@@ -1258,7 +_,7 @@
|
||||
|
||||
private void updateMobSpawningFlags() {
|
||||
for (ServerLevel serverLevel : this.getAllLevels()) {
|
||||
@ -1130,7 +1130,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1333,10 +_,20 @@
|
||||
@@ -1334,10 +_,20 @@
|
||||
|
||||
@Override
|
||||
public String getMotd() {
|
||||
@ -1152,7 +1152,7 @@
|
||||
this.motd = motd;
|
||||
}
|
||||
|
||||
@@ -1359,7 +_,7 @@
|
||||
@@ -1360,7 +_,7 @@
|
||||
}
|
||||
|
||||
public ServerConnectionListener getConnection() {
|
||||
@ -1161,7 +1161,7 @@
|
||||
}
|
||||
|
||||
public boolean isReady() {
|
||||
@@ -1445,7 +_,7 @@
|
||||
@@ -1446,7 +_,7 @@
|
||||
@Override
|
||||
public void executeIfPossible(Runnable task) {
|
||||
if (this.isStopped()) {
|
||||
@ -1170,7 +1170,7 @@
|
||||
} else {
|
||||
super.executeIfPossible(task);
|
||||
}
|
||||
@@ -1484,7 +_,14 @@
|
||||
@@ -1485,7 +_,14 @@
|
||||
return this.functionManager;
|
||||
}
|
||||
|
||||
@ -1185,7 +1185,7 @@
|
||||
CompletableFuture<Void> completableFuture = CompletableFuture.<ImmutableList>supplyAsync(
|
||||
() -> selectedIds.stream().map(this.packRepository::getPack).filter(Objects::nonNull).map(Pack::open).collect(ImmutableList.toImmutableList()),
|
||||
this
|
||||
@@ -1492,7 +_,7 @@
|
||||
@@ -1493,7 +_,7 @@
|
||||
.thenCompose(
|
||||
list -> {
|
||||
CloseableResourceManager closeableResourceManager = new MultiPackResourceManager(PackType.SERVER_DATA, list);
|
||||
@ -1194,7 +1194,7 @@
|
||||
return ReloadableServerResources.loadResources(
|
||||
closeableResourceManager,
|
||||
this.registries,
|
||||
@@ -1513,20 +_,39 @@
|
||||
@@ -1514,20 +_,39 @@
|
||||
)
|
||||
.thenAcceptAsync(
|
||||
reloadableResources -> {
|
||||
@ -1236,7 +1236,7 @@
|
||||
},
|
||||
this
|
||||
);
|
||||
@@ -1543,7 +_,7 @@
|
||||
@@ -1544,7 +_,7 @@
|
||||
DataPackConfig dataPackConfig = initialDataConfig.dataPacks();
|
||||
FeatureFlagSet featureFlagSet = initMode ? FeatureFlagSet.of() : initialDataConfig.enabledFeatures();
|
||||
FeatureFlagSet featureFlagSet1 = initMode ? FeatureFlags.REGISTRY.allFlags() : initialDataConfig.enabledFeatures();
|
||||
@ -1245,7 +1245,7 @@
|
||||
if (safeMode) {
|
||||
return configureRepositoryWithSelection(packRepository, List.of("vanilla"), featureFlagSet, false);
|
||||
} else {
|
||||
@@ -1598,7 +_,7 @@
|
||||
@@ -1599,7 +_,7 @@
|
||||
private static WorldDataConfiguration configureRepositoryWithSelection(
|
||||
PackRepository packRepository, Collection<String> selectedPacks, FeatureFlagSet enabledFeatures, boolean safeMode
|
||||
) {
|
||||
@ -1254,7 +1254,7 @@
|
||||
enableForcedFeaturePacks(packRepository, enabledFeatures);
|
||||
DataPackConfig selectedPacks1 = getSelectedPacks(packRepository, safeMode);
|
||||
FeatureFlagSet featureFlagSet = packRepository.getRequestedFeatureFlags().join(enabledFeatures);
|
||||
@@ -1630,7 +_,7 @@
|
||||
@@ -1631,7 +_,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -1263,7 +1263,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1644,11 +_,12 @@
|
||||
@@ -1645,11 +_,12 @@
|
||||
public void kickUnlistedPlayers(CommandSourceStack commandSource) {
|
||||
if (this.isEnforceWhitelist()) {
|
||||
PlayerList playerList = commandSource.getServer().getPlayerList();
|
||||
@ -1278,7 +1278,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1852,6 +_,17 @@
|
||||
@@ -1853,6 +_,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -1296,7 +1296,7 @@
|
||||
private ProfilerFiller createProfiler() {
|
||||
if (this.willStartRecordingMetrics) {
|
||||
this.metricsRecorder = ActiveMetricsRecorder.createStarted(
|
||||
@@ -1973,16 +_,22 @@
|
||||
@@ -1974,16 +_,22 @@
|
||||
}
|
||||
|
||||
public void logChatMessage(Component content, ChatType.Bound boundChatType, @Nullable String header) {
|
||||
@ -1323,7 +1323,7 @@
|
||||
}
|
||||
|
||||
public boolean logIPs() {
|
||||
@@ -2115,4 +_,53 @@
|
||||
@@ -2120,4 +_,53 @@
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
public PlayerAdvancements(DataFixer dataFixer, PlayerList playerList, ServerAdvancementManager manager, Path playerSavePath, ServerPlayer player) {
|
||||
this.playerList = playerList;
|
||||
@@ -128,6 +_,7 @@
|
||||
@@ -127,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void save() {
|
||||
@ -25,7 +25,7 @@
|
||||
JsonElement jsonElement = this.codec.encodeStart(JsonOps.INSTANCE, this.asData()).getOrThrow();
|
||||
|
||||
try {
|
||||
@@ -145,6 +_,7 @@
|
||||
@@ -144,6 +_,7 @@
|
||||
data.forEach((path, progress) -> {
|
||||
AdvancementHolder advancementHolder = advancementManager.get(path);
|
||||
if (advancementHolder == null) {
|
||||
@ -33,7 +33,7 @@
|
||||
LOGGER.warn("Ignored advancement '{}' in progress file {} - it doesn't exist anymore?", path, this.playerSavePath);
|
||||
} else {
|
||||
this.startProgress(advancementHolder, progress);
|
||||
@@ -169,14 +_,31 @@
|
||||
@@ -168,14 +_,31 @@
|
||||
AdvancementProgress orStartProgress = this.getOrStartProgress(advancement);
|
||||
boolean isDone = orStartProgress.isDone();
|
||||
if (orStartProgress.grantProgress(criterionKey)) {
|
||||
@ -58,16 +58,16 @@
|
||||
+ // Paper end
|
||||
advancement.value().rewards().grant(this.player);
|
||||
advancement.value().display().ifPresent(displayInfo -> {
|
||||
- if (displayInfo.shouldAnnounceChat() && this.player.serverLevel().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) {
|
||||
- if (displayInfo.shouldAnnounceChat() && this.player.level().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) {
|
||||
- this.playerList.broadcastSystemMessage(displayInfo.getType().createAnnouncement(advancement, this.player), false);
|
||||
+ // Paper start - Add Adventure message to PlayerAdvancementDoneEvent
|
||||
+ if (event.message() != null && this.player.serverLevel().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) {
|
||||
+ if (event.message() != null && this.player.level().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) {
|
||||
+ this.playerList.broadcastSystemMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.message()), false);
|
||||
+ // Paper end
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -247,7 +_,7 @@
|
||||
@@ -246,7 +_,7 @@
|
||||
public void flushDirty(ServerPlayer player, boolean showAdvancements) {
|
||||
if (this.isFirstPacket || !this.rootsToUpdate.isEmpty() || !this.progressChanged.isEmpty()) {
|
||||
Map<ResourceLocation, AdvancementProgress> map = new HashMap<>();
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/ReloadableServerRegistries.java
|
||||
+++ b/net/minecraft/server/ReloadableServerRegistries.java
|
||||
@@ -48,8 +_,9 @@
|
||||
@@ -46,8 +_,9 @@
|
||||
List<HolderLookup.RegistryLookup<?>> list = TagLoader.buildUpdatedLookups(registryAccess.getAccessForLoading(RegistryLayer.RELOADABLE), postponedTags);
|
||||
HolderLookup.Provider provider = HolderLookup.Provider.create(list.stream());
|
||||
RegistryOps<JsonElement> registryOps = provider.createSerializationContext(JsonOps.INSTANCE);
|
||||
@ -11,7 +11,7 @@
|
||||
.toList();
|
||||
CompletableFuture<List<WritableRegistry<?>>> completableFuture = Util.sequence(list1);
|
||||
return completableFuture.thenApplyAsync(
|
||||
@@ -58,19 +_,20 @@
|
||||
@@ -56,19 +_,20 @@
|
||||
}
|
||||
|
||||
private static <T> CompletableFuture<WritableRegistry<?>> scheduleRegistryLoad(
|
||||
@ -21,7 +21,7 @@
|
||||
return CompletableFuture.supplyAsync(
|
||||
() -> {
|
||||
WritableRegistry<T> writableRegistry = new MappedRegistry<>(lootDataType.registryKey(), Lifecycle.experimental());
|
||||
+ io.papermc.paper.registry.PaperRegistryAccess.instance().registerReloadableRegistry(lootDataType.registryKey(), writableRegistry); // Paper - register reloadable registry
|
||||
+ io.papermc.paper.registry.PaperRegistryAccess.instance().registerReloadableRegistry(writableRegistry); // Paper - register reloadable registry
|
||||
Map<ResourceLocation, T> map = new HashMap<>();
|
||||
SimpleJsonResourceReloadListener.scanDirectory(resourceManager, lootDataType.registryKey(), ops, lootDataType.codec(), map);
|
||||
map.forEach(
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/ServerScoreboard.java
|
||||
+++ b/net/minecraft/server/ServerScoreboard.java
|
||||
@@ -43,9 +_,7 @@
|
||||
@@ -45,9 +_,7 @@
|
||||
protected void onScoreChanged(ScoreHolder scoreHolder, Objective objective, Score score) {
|
||||
super.onScoreChanged(scoreHolder, objective, score);
|
||||
if (this.trackedObjectives.contains(objective)) {
|
||||
@ -11,7 +11,7 @@
|
||||
new ClientboundSetScorePacket(
|
||||
scoreHolder.getScoreboardName(),
|
||||
objective.getName(),
|
||||
@@ -68,7 +_,7 @@
|
||||
@@ -70,7 +_,7 @@
|
||||
@Override
|
||||
public void onPlayerRemoved(ScoreHolder scoreHolder) {
|
||||
super.onPlayerRemoved(scoreHolder);
|
||||
@ -20,7 +20,7 @@
|
||||
this.setDirty();
|
||||
}
|
||||
|
||||
@@ -76,7 +_,7 @@
|
||||
@@ -78,7 +_,7 @@
|
||||
public void onPlayerScoreRemoved(ScoreHolder scoreHolder, Objective objective) {
|
||||
super.onPlayerScoreRemoved(scoreHolder, objective);
|
||||
if (this.trackedObjectives.contains(objective)) {
|
||||
@ -29,7 +29,7 @@
|
||||
}
|
||||
|
||||
this.setDirty();
|
||||
@@ -88,7 +_,7 @@
|
||||
@@ -90,7 +_,7 @@
|
||||
super.setDisplayObjective(slot, objective);
|
||||
if (displayObjective != objective && displayObjective != null) {
|
||||
if (this.getObjectiveDisplaySlotCount(displayObjective) > 0) {
|
||||
@ -38,7 +38,7 @@
|
||||
} else {
|
||||
this.stopTrackingObjective(displayObjective);
|
||||
}
|
||||
@@ -96,7 +_,7 @@
|
||||
@@ -98,7 +_,7 @@
|
||||
|
||||
if (objective != null) {
|
||||
if (this.trackedObjectives.contains(objective)) {
|
||||
@ -47,27 +47,21 @@
|
||||
} else {
|
||||
this.startTrackingObjective(objective);
|
||||
}
|
||||
@@ -108,24 +_,50 @@
|
||||
@@ -110,9 +_,7 @@
|
||||
@Override
|
||||
public boolean addPlayerToTeam(String playerName, PlayerTeam team) {
|
||||
if (super.addPlayerToTeam(playerName, team)) {
|
||||
- this.server
|
||||
- .getPlayerList()
|
||||
- .broadcastAll(ClientboundSetPlayerTeamPacket.createPlayerPacket(team, playerName, ClientboundSetPlayerTeamPacket.Action.ADD));
|
||||
- this.setDirty();
|
||||
- return true;
|
||||
- } else {
|
||||
- return false;
|
||||
- }
|
||||
- }
|
||||
+ this.broadcastAll(ClientboundSetPlayerTeamPacket.createPlayerPacket(team, playerName, ClientboundSetPlayerTeamPacket.Action.ADD)); // CraftBukkit
|
||||
+ this.setDirty();
|
||||
+ return true;
|
||||
+ } else {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
this.updatePlayerWaypoint(playerName);
|
||||
this.setDirty();
|
||||
return true;
|
||||
@@ -121,16 +_,44 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Multiple Entries with Scoreboards
|
||||
+ public boolean addPlayersToTeam(java.util.Collection<String> players, PlayerTeam team) {
|
||||
+ boolean anyAdded = false;
|
||||
@ -86,19 +80,18 @@
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Multiple Entries with Scoreboards
|
||||
|
||||
+
|
||||
@Override
|
||||
public void removePlayerFromTeam(String username, PlayerTeam playerTeam) {
|
||||
super.removePlayerFromTeam(username, playerTeam);
|
||||
- this.server
|
||||
- .getPlayerList()
|
||||
- .broadcastAll(ClientboundSetPlayerTeamPacket.createPlayerPacket(playerTeam, username, ClientboundSetPlayerTeamPacket.Action.REMOVE));
|
||||
- this.setDirty();
|
||||
- }
|
||||
+ this.broadcastAll(ClientboundSetPlayerTeamPacket.createPlayerPacket(playerTeam, username, ClientboundSetPlayerTeamPacket.Action.REMOVE)); // CraftBukkit
|
||||
+ this.setDirty();
|
||||
+ }
|
||||
+
|
||||
this.updatePlayerWaypoint(username);
|
||||
this.setDirty();
|
||||
}
|
||||
|
||||
+ // Paper start - Multiple Entries with Scoreboards
|
||||
+ public void removePlayersFromTeam(java.util.Collection<String> players, PlayerTeam team) {
|
||||
+ for (String playerName : players) {
|
||||
@ -109,10 +102,11 @@
|
||||
+ this.setDirty();
|
||||
+ }
|
||||
+ // Paper end - Multiple Entries with Scoreboards
|
||||
|
||||
+
|
||||
@Override
|
||||
public void onObjectiveAdded(Objective objective) {
|
||||
@@ -137,7 +_,7 @@
|
||||
super.onObjectiveAdded(objective);
|
||||
@@ -141,7 +_,7 @@
|
||||
public void onObjectiveChanged(Objective objective) {
|
||||
super.onObjectiveChanged(objective);
|
||||
if (this.trackedObjectives.contains(objective)) {
|
||||
@ -121,7 +115,7 @@
|
||||
}
|
||||
|
||||
this.setDirty();
|
||||
@@ -156,21 +_,21 @@
|
||||
@@ -160,14 +_,14 @@
|
||||
@Override
|
||||
public void onTeamAdded(PlayerTeam playerTeam) {
|
||||
super.onTeamAdded(playerTeam);
|
||||
@ -135,18 +129,19 @@
|
||||
super.onTeamChanged(playerTeam);
|
||||
- this.server.getPlayerList().broadcastAll(ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(playerTeam, false));
|
||||
+ this.broadcastAll(ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(playerTeam, false)); // CraftBukkit
|
||||
this.updateTeamWaypoints(playerTeam);
|
||||
this.setDirty();
|
||||
}
|
||||
|
||||
@@ -175,7 +_,7 @@
|
||||
@Override
|
||||
public void onTeamRemoved(PlayerTeam playerTeam) {
|
||||
super.onTeamRemoved(playerTeam);
|
||||
- this.server.getPlayerList().broadcastAll(ClientboundSetPlayerTeamPacket.createRemovePacket(playerTeam));
|
||||
+ this.broadcastAll(ClientboundSetPlayerTeamPacket.createRemovePacket(playerTeam)); // CraftBukkit
|
||||
this.updateTeamWaypoints(playerTeam);
|
||||
this.setDirty();
|
||||
}
|
||||
|
||||
@@ -213,6 +_,7 @@
|
||||
@@ -219,6 +_,7 @@
|
||||
List<Packet<?>> startTrackingPackets = this.getStartTrackingPackets(objective);
|
||||
|
||||
for (ServerPlayer serverPlayer : this.server.getPlayerList().getPlayers()) {
|
||||
@ -154,7 +149,7 @@
|
||||
for (Packet<?> packet : startTrackingPackets) {
|
||||
serverPlayer.connection.send(packet);
|
||||
}
|
||||
@@ -238,6 +_,7 @@
|
||||
@@ -244,6 +_,7 @@
|
||||
List<Packet<?>> stopTrackingPackets = this.getStopTrackingPackets(objective);
|
||||
|
||||
for (ServerPlayer serverPlayer : this.server.getPlayerList().getPlayers()) {
|
||||
@ -162,11 +157,10 @@
|
||||
for (Packet<?> packet : stopTrackingPackets) {
|
||||
serverPlayer.connection.send(packet);
|
||||
}
|
||||
@@ -269,6 +_,16 @@
|
||||
scoreboardSaveData.loadFrom(data);
|
||||
return scoreboardSaveData;
|
||||
@@ -295,4 +_,13 @@
|
||||
.forEach(serverPlayer -> serverLevel.getWaypointManager().remakeConnections(serverPlayer));
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // CraftBukkit start - Send to players
|
||||
+ private void broadcastAll(Packet<?> packet) {
|
||||
+ for (ServerPlayer serverPlayer : this.server.getPlayerList().players) {
|
||||
@ -176,6 +170,4 @@
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
|
||||
public static enum Method {
|
||||
CHANGE,
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/commands/BanPlayerCommands.java
|
||||
+++ b/net/minecraft/server/commands/BanPlayerCommands.java
|
||||
@@ -55,7 +_,7 @@
|
||||
@@ -57,7 +_,7 @@
|
||||
);
|
||||
ServerPlayer player = source.getServer().getPlayerList().getPlayer(gameProfile.getId());
|
||||
if (player != null) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/commands/DeOpCommands.java
|
||||
+++ b/net/minecraft/server/commands/DeOpCommands.java
|
||||
@@ -35,7 +_,7 @@
|
||||
@@ -39,7 +_,7 @@
|
||||
if (playerList.isOp(gameProfile)) {
|
||||
playerList.deop(gameProfile);
|
||||
i++;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/commands/EffectCommands.java
|
||||
+++ b/net/minecraft/server/commands/EffectCommands.java
|
||||
@@ -180,7 +_,7 @@
|
||||
@@ -182,7 +_,7 @@
|
||||
for (Entity entity : targets) {
|
||||
if (entity instanceof LivingEntity) {
|
||||
MobEffectInstance mobEffectInstance = new MobEffectInstance(effect, i1, amplifier, false, showParticles);
|
||||
@ -9,7 +9,7 @@
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@@ -210,7 +_,7 @@
|
||||
@@ -212,7 +_,7 @@
|
||||
int i = 0;
|
||||
|
||||
for (Entity entity : targets) {
|
||||
@ -18,7 +18,7 @@
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@@ -235,7 +_,7 @@
|
||||
@@ -237,7 +_,7 @@
|
||||
int i = 0;
|
||||
|
||||
for (Entity entity : targets) {
|
||||
|
||||
@ -1,18 +1,20 @@
|
||||
--- a/net/minecraft/server/commands/GameModeCommand.java
|
||||
+++ b/net/minecraft/server/commands/GameModeCommand.java
|
||||
@@ -54,9 +_,14 @@
|
||||
int i = 0;
|
||||
@@ -69,9 +_,16 @@
|
||||
}
|
||||
|
||||
for (ServerPlayer serverPlayer : players) {
|
||||
- if (serverPlayer.setGameMode(gameType)) {
|
||||
+ // Paper start - Expand PlayerGameModeChangeEvent
|
||||
+ org.bukkit.event.player.PlayerGameModeChangeEvent event = serverPlayer.setGameMode(gameType, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.COMMAND, net.kyori.adventure.text.Component.empty());
|
||||
+ if (event != null && !event.isCancelled()) {
|
||||
logGamemodeChange(source.getSource(), serverPlayer, gameType);
|
||||
i++;
|
||||
+ } else if (event != null && event.cancelMessage() != null) {
|
||||
+ source.getSource().sendSuccess(() -> io.papermc.paper.adventure.PaperAdventure.asVanilla(event.cancelMessage()), true);
|
||||
+ // Paper end - Expand PlayerGameModeChangeEvent
|
||||
}
|
||||
private static boolean setGameMode(CommandSourceStack source, ServerPlayer player, GameType gameMode) {
|
||||
- if (player.setGameMode(gameMode)) {
|
||||
+ // Paper start
|
||||
+ org.bukkit.event.player.PlayerGameModeChangeEvent event = player.setGameMode(gameMode, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.COMMAND, net.kyori.adventure.text.Component.empty());
|
||||
+ if (event != null && !event.isCancelled()) {
|
||||
+ // Paper end
|
||||
logGamemodeChange(source, player, gameMode);
|
||||
return true;
|
||||
+ } else if (event != null && event.cancelMessage() != null) {
|
||||
+ source.sendSuccess(() -> io.papermc.paper.adventure.PaperAdventure.asVanilla(event.cancelMessage()), true);
|
||||
+ return false;
|
||||
+ // Paper end - Expand PlayerGameModeChangeEvent
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/commands/GiveCommand.java
|
||||
+++ b/net/minecraft/server/commands/GiveCommand.java
|
||||
@@ -51,6 +_,7 @@
|
||||
@@ -54,6 +_,7 @@
|
||||
|
||||
private static int giveItem(CommandSourceStack source, ItemInput item, Collection<ServerPlayer> targets, int count) throws CommandSyntaxException {
|
||||
ItemStack itemStack = item.createItemStack(1, false);
|
||||
@ -8,25 +8,7 @@
|
||||
int maxStackSize = itemStack.getMaxStackSize();
|
||||
int i = maxStackSize * 100;
|
||||
if (count > i) {
|
||||
@@ -66,7 +_,7 @@
|
||||
ItemStack itemStack1 = item.createItemStack(min, false);
|
||||
boolean flag = serverPlayer.getInventory().add(itemStack1);
|
||||
if (flag && itemStack1.isEmpty()) {
|
||||
- ItemEntity itemEntity = serverPlayer.drop(itemStack, false);
|
||||
+ ItemEntity itemEntity = serverPlayer.drop(itemStack, false, false, false, null); // Paper - do not fire PlayerDropItemEvent for /give command
|
||||
if (itemEntity != null) {
|
||||
itemEntity.makeFakeItem();
|
||||
}
|
||||
@@ -84,7 +_,7 @@
|
||||
);
|
||||
serverPlayer.containerMenu.broadcastChanges();
|
||||
} else {
|
||||
- ItemEntity itemEntity = serverPlayer.drop(itemStack1, false);
|
||||
+ ItemEntity itemEntity = serverPlayer.drop(itemStack1, false, false, false, null); // Paper - do not fire PlayerDropItemEvent for /give command
|
||||
if (itemEntity != null) {
|
||||
itemEntity.setNoPickUpDelay();
|
||||
itemEntity.setTarget(serverPlayer.getUUID());
|
||||
@@ -95,11 +_,11 @@
|
||||
@@ -98,11 +_,11 @@
|
||||
|
||||
if (targets.size() == 1) {
|
||||
source.sendSuccess(
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/commands/KickCommand.java
|
||||
+++ b/net/minecraft/server/commands/KickCommand.java
|
||||
@@ -48,7 +_,7 @@
|
||||
@@ -50,7 +_,7 @@
|
||||
|
||||
for (ServerPlayer serverPlayer : players) {
|
||||
if (!source.getServer().isSingleplayerOwner(serverPlayer.getGameProfile())) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/commands/LocateCommand.java
|
||||
+++ b/net/minecraft/server/commands/LocateCommand.java
|
||||
@@ -202,6 +_,6 @@
|
||||
@@ -199,6 +_,6 @@
|
||||
private static float dist(int x1, int z1, int x2, int z2) {
|
||||
int i = x2 - x1;
|
||||
int i1 = z2 - z1;
|
||||
|
||||
@ -34,4 +34,4 @@
|
||||
+ // CraftBukkit end
|
||||
|
||||
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
|
||||
dispatcher.register(Commands.literal("reload").requires(source -> source.hasPermission(2)).executes(context -> {
|
||||
dispatcher.register(Commands.literal("reload").requires(Commands.hasPermission(2)).executes(commandContext -> {
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
--- a/net/minecraft/server/commands/RideCommand.java
|
||||
+++ b/net/minecraft/server/commands/RideCommand.java
|
||||
@@ -58,7 +_,7 @@
|
||||
@@ -60,7 +_,7 @@
|
||||
Entity vehicle1 = target.getVehicle();
|
||||
if (vehicle1 != null) {
|
||||
throw ERROR_ALREADY_RIDING.create(target.getDisplayName(), vehicle1.getDisplayName());
|
||||
- } else if (vehicle.getType() == EntityType.PLAYER) {
|
||||
+ } else if (vehicle.getType() == EntityType.PLAYER && !io.papermc.paper.configuration.GlobalConfiguration.get().commands.rideCommandAllowPlayerAsVehicle) { // Paper - allow player as vehicle
|
||||
throw ERROR_MOUNTING_PLAYER.create();
|
||||
} else if (target.getSelfAndPassengers().anyMatch(passenger -> passenger == vehicle)) {
|
||||
} else if (target.getSelfAndPassengers().anyMatch(entity -> entity == vehicle)) {
|
||||
throw ERROR_MOUNTING_LOOP.create();
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/commands/WorldBorderCommand.java
|
||||
+++ b/net/minecraft/server/commands/WorldBorderCommand.java
|
||||
@@ -135,7 +_,7 @@
|
||||
@@ -136,7 +_,7 @@
|
||||
}
|
||||
|
||||
private static int setDamageBuffer(CommandSourceStack source, float distance) throws CommandSyntaxException {
|
||||
@ -9,7 +9,7 @@
|
||||
if (worldBorder.getDamageSafeZone() == distance) {
|
||||
throw ERROR_SAME_DAMAGE_BUFFER.create();
|
||||
} else {
|
||||
@@ -146,7 +_,7 @@
|
||||
@@ -147,7 +_,7 @@
|
||||
}
|
||||
|
||||
private static int setDamageAmount(CommandSourceStack source, float damagePerBlock) throws CommandSyntaxException {
|
||||
@ -18,7 +18,7 @@
|
||||
if (worldBorder.getDamagePerBlock() == damagePerBlock) {
|
||||
throw ERROR_SAME_DAMAGE_AMOUNT.create();
|
||||
} else {
|
||||
@@ -159,7 +_,7 @@
|
||||
@@ -160,7 +_,7 @@
|
||||
}
|
||||
|
||||
private static int setWarningTime(CommandSourceStack source, int time) throws CommandSyntaxException {
|
||||
@ -27,7 +27,7 @@
|
||||
if (worldBorder.getWarningTime() == time) {
|
||||
throw ERROR_SAME_WARNING_TIME.create();
|
||||
} else {
|
||||
@@ -170,7 +_,7 @@
|
||||
@@ -171,7 +_,7 @@
|
||||
}
|
||||
|
||||
private static int setWarningDistance(CommandSourceStack source, int distance) throws CommandSyntaxException {
|
||||
@ -36,7 +36,7 @@
|
||||
if (worldBorder.getWarningBlocks() == distance) {
|
||||
throw ERROR_SAME_WARNING_DISTANCE.create();
|
||||
} else {
|
||||
@@ -181,13 +_,13 @@
|
||||
@@ -182,13 +_,13 @@
|
||||
}
|
||||
|
||||
private static int getSize(CommandSourceStack source) {
|
||||
@ -52,7 +52,7 @@
|
||||
if (worldBorder.getCenterX() == pos.x && worldBorder.getCenterZ() == pos.y) {
|
||||
throw ERROR_SAME_CENTER.create();
|
||||
} else if (!(Math.abs(pos.x) > 2.9999984E7) && !(Math.abs(pos.y) > 2.9999984E7)) {
|
||||
@@ -205,7 +_,7 @@
|
||||
@@ -206,7 +_,7 @@
|
||||
}
|
||||
|
||||
private static int setSize(CommandSourceStack source, double newSize, long time) throws CommandSyntaxException {
|
||||
|
||||
@ -70,7 +70,7 @@
|
||||
thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER));
|
||||
- thread.start();
|
||||
+ // thread.start(); // Paper - Enhance console tab completions for brigadier commands; moved down
|
||||
LOGGER.info("Starting minecraft server version {}", SharedConstants.getCurrentVersion().getName());
|
||||
LOGGER.info("Starting minecraft server version {}", SharedConstants.getCurrentVersion().name());
|
||||
if (Runtime.getRuntime().maxMemory() / 1024L / 1024L < 512L) {
|
||||
LOGGER.warn("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\"");
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
@@ -45,6 +_,7 @@
|
||||
@@ -47,6 +_,7 @@
|
||||
static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final Pattern SHA1 = Pattern.compile("^[a-fA-F0-9]{40}$");
|
||||
private static final Splitter COMMA_SPLITTER = Splitter.on(',').trimResults();
|
||||
@ -8,7 +8,7 @@
|
||||
public final boolean onlineMode = this.get("online-mode", true);
|
||||
public final boolean preventProxyConnections = this.get("prevent-proxy-connections", false);
|
||||
public final String serverIp = this.get("server-ip", "");
|
||||
@@ -85,7 +_,7 @@
|
||||
@@ -87,7 +_,7 @@
|
||||
public final boolean broadcastRconToOps = this.get("broadcast-rcon-to-ops", true);
|
||||
public final boolean broadcastConsoleToOps = this.get("broadcast-console-to-ops", true);
|
||||
public final int maxWorldSize = this.get("max-world-size", property -> Mth.clamp(property, 1, 29999984), 29999984);
|
||||
@ -17,7 +17,7 @@
|
||||
public final String regionFileComression = this.get("region-file-compression", "deflate");
|
||||
public final boolean enableJmxMonitoring = this.get("enable-jmx-monitoring", false);
|
||||
public final boolean enableStatus = this.get("enable-status", true);
|
||||
@@ -99,13 +_,16 @@
|
||||
@@ -101,13 +_,16 @@
|
||||
public final Settings<DedicatedServerProperties>.MutableValue<Boolean> whiteList = this.getMutable("white-list", false);
|
||||
public final boolean enforceSecureProfile = this.get("enforce-secure-profile", true);
|
||||
public final boolean logIPs = this.get("log-ips", true);
|
||||
@ -37,7 +37,7 @@
|
||||
String string = this.get("level-seed", "");
|
||||
boolean flag = this.get("generate-structures", true);
|
||||
long l = WorldOptions.parseSeed(string).orElse(WorldOptions.randomSeed());
|
||||
@@ -126,15 +_,21 @@
|
||||
@@ -128,15 +_,21 @@
|
||||
this.get("initial-enabled-packs", String.join(",", WorldDataConfiguration.DEFAULT.dataPacks().getEnabled())),
|
||||
this.get("initial-disabled-packs", String.join(",", WorldDataConfiguration.DEFAULT.dataPacks().getDisabled()))
|
||||
);
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
@VisibleForDebug
|
||||
private NaturalSpawner.SpawnState lastSpawnState;
|
||||
+ // Paper start
|
||||
+ private final ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable<net.minecraft.world.level.chunk.LevelChunk> fullChunks = new ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable<>();
|
||||
+ public final ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable<net.minecraft.world.level.chunk.LevelChunk> fullChunks = new ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable<>();
|
||||
+ public int getFullChunksCount() {
|
||||
+ return this.fullChunks.size();
|
||||
+ }
|
||||
@ -146,7 +146,7 @@
|
||||
+ ProfilerFiller gameprofilerfiller = Profiler.get();
|
||||
+
|
||||
+ gameprofilerfiller.push("purge");
|
||||
+ this.ticketStorage.purgeStaleTickets();
|
||||
+ this.ticketStorage.purgeStaleTickets(this.chunkMap);
|
||||
+ this.runDistanceManagerUpdates();
|
||||
+ gameprofilerfiller.popPush("unload");
|
||||
+ this.chunkMap.tick(() -> true);
|
||||
@ -161,7 +161,7 @@
|
||||
profilerFiller.push("purge");
|
||||
- if (this.level.tickRateManager().runsNormally() || !tickChunks) {
|
||||
+ if (this.level.tickRateManager().runsNormally() || !tickChunks || this.level.spigotConfig.unloadFrozenChunks) { // Spigot
|
||||
this.ticketStorage.purgeStaleTickets();
|
||||
this.ticketStorage.purgeStaleTickets(this.chunkMap);
|
||||
}
|
||||
|
||||
@@ -388,12 +_,20 @@
|
||||
@ -188,7 +188,7 @@
|
||||
} else {
|
||||
filteredSpawningCategories = List.of();
|
||||
}
|
||||
@@ -544,8 +_,13 @@
|
||||
@@ -547,8 +_,13 @@
|
||||
|
||||
@Override
|
||||
public void setSpawnSettings(boolean spawnSettings) {
|
||||
@ -203,7 +203,7 @@
|
||||
}
|
||||
|
||||
public String getChunkDebugData(ChunkPos chunkPos) {
|
||||
@@ -618,12 +_,18 @@
|
||||
@@ -621,12 +_,18 @@
|
||||
|
||||
@Override
|
||||
public boolean pollTask() {
|
||||
|
||||
@ -70,7 +70,7 @@
|
||||
Packet<?> packet = null;
|
||||
boolean flag2 = flag1 || this.tickCount % 60 == 0;
|
||||
boolean flag3 = false;
|
||||
@@ -223,6 +_,25 @@
|
||||
@@ -227,6 +_,25 @@
|
||||
|
||||
this.tickCount++;
|
||||
if (this.entity.hurtMarked) {
|
||||
@ -96,7 +96,7 @@
|
||||
this.entity.hurtMarked = false;
|
||||
this.broadcastAndSend(new ClientboundSetEntityMotionPacket(this.entity));
|
||||
}
|
||||
@@ -280,7 +_,10 @@
|
||||
@@ -284,7 +_,10 @@
|
||||
|
||||
public void sendPairingData(ServerPlayer player, Consumer<Packet<ClientGamePacketListener>> consumer) {
|
||||
if (this.entity.isRemoved()) {
|
||||
@ -108,11 +108,10 @@
|
||||
}
|
||||
|
||||
Packet<ClientGamePacketListener> addEntityPacket = this.entity.getAddEntityPacket(this);
|
||||
@@ -292,6 +_,12 @@
|
||||
boolean flag = this.trackDelta;
|
||||
if (this.entity instanceof LivingEntity) {
|
||||
Collection<AttributeInstance> syncableAttributes = ((LivingEntity)this.entity).getAttributes().getSyncableAttributes();
|
||||
+
|
||||
@@ -295,6 +_,11 @@
|
||||
|
||||
if (this.entity instanceof LivingEntity livingEntity) {
|
||||
Collection<AttributeInstance> syncableAttributes = livingEntity.getAttributes().getSyncableAttributes();
|
||||
+ // CraftBukkit start - If sending own attributes send scaled health instead of current maximum health
|
||||
+ if (this.entity.getId() == player.getId()) {
|
||||
+ ((ServerPlayer) this.entity).getBukkitEntity().injectScaledMaxHealth(syncableAttributes, false);
|
||||
@ -121,7 +120,7 @@
|
||||
if (!syncableAttributes.isEmpty()) {
|
||||
consumer.accept(new ClientboundUpdateAttributesPacket(this.entity.getId(), syncableAttributes));
|
||||
}
|
||||
@@ -316,8 +_,9 @@
|
||||
@@ -311,8 +_,9 @@
|
||||
}
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
@ -132,7 +131,7 @@
|
||||
}
|
||||
|
||||
if (!this.entity.getPassengers().isEmpty()) {
|
||||
@@ -364,6 +_,11 @@
|
||||
@@ -359,6 +_,11 @@
|
||||
if (this.entity instanceof LivingEntity) {
|
||||
Set<AttributeInstance> attributesToSync = ((LivingEntity)this.entity).getAttributes().getAttributesToSync();
|
||||
if (!attributesToSync.isEmpty()) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -178,7 +_,7 @@
|
||||
@@ -180,7 +_,7 @@
|
||||
final List<ServerPlayer> players = Lists.newArrayList();
|
||||
public final ServerChunkCache chunkSource;
|
||||
private final MinecraftServer server;
|
||||
@ -8,8 +8,8 @@
|
||||
+ public final net.minecraft.world.level.storage.PrimaryLevelData serverLevelData; // CraftBukkit - type
|
||||
private int lastSpawnChunkRadius;
|
||||
final EntityTickList entityTickList = new EntityTickList();
|
||||
public final PersistentEntitySectionManager<Entity> entityManager;
|
||||
@@ -205,11 +_,131 @@
|
||||
private final ServerWaypointManager waypointManager;
|
||||
@@ -208,11 +_,131 @@
|
||||
private final boolean tickTime;
|
||||
private final RandomSequences randomSequences;
|
||||
|
||||
@ -142,7 +142,7 @@
|
||||
ResourceKey<Level> dimension,
|
||||
LevelStem levelStem,
|
||||
ChunkProgressListener progressListener,
|
||||
@@ -217,14 +_,38 @@
|
||||
@@ -220,14 +_,38 @@
|
||||
long biomeZoomSeed,
|
||||
List<CustomSpawner> customSpawners,
|
||||
boolean tickTime,
|
||||
@ -183,7 +183,7 @@
|
||||
boolean flag = server.forceSynchronousWrites();
|
||||
DataFixer fixerUpper = server.getFixerUpper();
|
||||
EntityPersistentStorage<Entity> entityPersistentStorage = new EntityStorage(
|
||||
@@ -246,8 +_,8 @@
|
||||
@@ -249,8 +_,8 @@
|
||||
server.getStructureManager(),
|
||||
dispatcher,
|
||||
chunkGenerator,
|
||||
@ -194,7 +194,7 @@
|
||||
flag,
|
||||
progressListener,
|
||||
this.entityManager::updateChunkStatus,
|
||||
@@ -268,7 +_,7 @@
|
||||
@@ -271,7 +_,7 @@
|
||||
this.chunkSource.chunkScanner(),
|
||||
this.registryAccess(),
|
||||
server.getStructureManager(),
|
||||
@ -203,7 +203,7 @@
|
||||
chunkGenerator,
|
||||
this.chunkSource.randomState(),
|
||||
this,
|
||||
@@ -276,9 +_,9 @@
|
||||
@@ -279,9 +_,9 @@
|
||||
seed,
|
||||
fixerUpper
|
||||
);
|
||||
@ -216,10 +216,10 @@
|
||||
} else {
|
||||
this.dragonFight = null;
|
||||
}
|
||||
@@ -286,7 +_,15 @@
|
||||
this.sleepStatus = new SleepStatus();
|
||||
@@ -290,7 +_,15 @@
|
||||
this.gameEventDispatcher = new GameEventDispatcher(this);
|
||||
this.randomSequences = Objects.requireNonNullElseGet(randomSequences, () -> this.getDataStorage().computeIfAbsent(RandomSequences.TYPE));
|
||||
this.waypointManager = new ServerWaypointManager();
|
||||
- }
|
||||
+ this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
|
||||
+ }
|
||||
@ -233,7 +233,7 @@
|
||||
|
||||
@Deprecated
|
||||
@VisibleForTesting
|
||||
@@ -298,8 +_,8 @@
|
||||
@@ -302,8 +_,8 @@
|
||||
this.serverLevelData.setClearWeatherTime(clearTime);
|
||||
this.serverLevelData.setRainTime(weatherTime);
|
||||
this.serverLevelData.setThunderTime(weatherTime);
|
||||
@ -244,7 +244,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -326,12 +_,25 @@
|
||||
@@ -330,12 +_,25 @@
|
||||
|
||||
int _int = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE);
|
||||
if (this.sleepStatus.areEnoughSleeping(_int) && this.sleepStatus.areEnoughDeepSleeping(_int, this.players)) {
|
||||
@ -273,7 +273,7 @@
|
||||
if (this.getGameRules().getBoolean(GameRules.RULE_WEATHER_CYCLE) && this.isRaining()) {
|
||||
this.resetWeatherCycle();
|
||||
}
|
||||
@@ -346,9 +_,9 @@
|
||||
@@ -350,9 +_,9 @@
|
||||
if (!this.isDebug() && runsNormally) {
|
||||
long l = this.getGameTime();
|
||||
profilerFiller.push("blockTicks");
|
||||
@ -285,7 +285,7 @@
|
||||
profilerFiller.pop();
|
||||
}
|
||||
|
||||
@@ -366,7 +_,7 @@
|
||||
@@ -370,7 +_,7 @@
|
||||
|
||||
this.handlingTick = false;
|
||||
profilerFiller.pop();
|
||||
@ -294,7 +294,7 @@
|
||||
if (flag) {
|
||||
this.resetEmptyTime();
|
||||
}
|
||||
@@ -455,11 +_,13 @@
|
||||
@@ -459,11 +_,13 @@
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
profilerFiller.push("iceandsnow");
|
||||
|
||||
@ -308,7 +308,7 @@
|
||||
|
||||
profilerFiller.popPush("tickBlocks");
|
||||
if (randomTickSpeed > 0) {
|
||||
@@ -502,12 +_,12 @@
|
||||
@@ -506,12 +_,12 @@
|
||||
int minBlockZ = pos.getMinBlockZ();
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
profilerFiller.push("thunder");
|
||||
@ -323,7 +323,7 @@
|
||||
&& !this.getBlockState(blockPos.below()).is(Blocks.LIGHTNING_ROD);
|
||||
if (flag) {
|
||||
SkeletonHorse skeletonHorse = EntityType.SKELETON_HORSE.create(this, EntitySpawnReason.EVENT);
|
||||
@@ -515,7 +_,7 @@
|
||||
@@ -519,7 +_,7 @@
|
||||
skeletonHorse.setTrap(true);
|
||||
skeletonHorse.setAge(0);
|
||||
skeletonHorse.setPos(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
||||
@ -332,7 +332,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -523,7 +_,7 @@
|
||||
@@ -527,7 +_,7 @@
|
||||
if (lightningBolt != null) {
|
||||
lightningBolt.snapTo(Vec3.atBottomCenterOf(blockPos));
|
||||
lightningBolt.setVisualOnly(flag);
|
||||
@ -341,7 +341,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -537,7 +_,7 @@
|
||||
@@ -541,7 +_,7 @@
|
||||
BlockPos blockPos1 = heightmapPos.below();
|
||||
Biome biome = this.getBiome(heightmapPos).value();
|
||||
if (biome.shouldFreeze(this, blockPos1)) {
|
||||
@ -350,7 +350,7 @@
|
||||
}
|
||||
|
||||
if (this.isRaining()) {
|
||||
@@ -549,10 +_,10 @@
|
||||
@@ -553,10 +_,10 @@
|
||||
if (layersValue < Math.min(_int, 8)) {
|
||||
BlockState blockState1 = blockState.setValue(SnowLayerBlock.LAYERS, layersValue + 1);
|
||||
Block.pushEntitiesUp(blockState, blockState1, this, heightmapPos);
|
||||
@ -363,7 +363,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -577,6 +_,12 @@
|
||||
@@ -581,6 +_,12 @@
|
||||
}
|
||||
|
||||
protected BlockPos findLightningTargetAround(BlockPos pos) {
|
||||
@ -376,7 +376,7 @@
|
||||
BlockPos heightmapPos = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, pos);
|
||||
Optional<BlockPos> optional = this.findLightningRod(heightmapPos);
|
||||
if (optional.isPresent()) {
|
||||
@@ -584,11 +_,12 @@
|
||||
@@ -588,11 +_,12 @@
|
||||
} else {
|
||||
AABB aabb = AABB.encapsulatingFullBlocks(heightmapPos, heightmapPos.atY(this.getMaxY() + 1)).inflate(3.0);
|
||||
List<LivingEntity> entitiesOfClass = this.getEntitiesOfClass(
|
||||
@ -390,7 +390,7 @@
|
||||
if (heightmapPos.getY() == this.getMinY() - 1) {
|
||||
heightmapPos = heightmapPos.above(2);
|
||||
}
|
||||
@@ -675,8 +_,8 @@
|
||||
@@ -683,8 +_,8 @@
|
||||
this.serverLevelData.setThunderTime(thunderTime);
|
||||
this.serverLevelData.setRainTime(rainTime);
|
||||
this.serverLevelData.setClearWeatherTime(clearWeatherTime);
|
||||
@ -401,7 +401,7 @@
|
||||
}
|
||||
|
||||
this.oThunderLevel = this.thunderLevel;
|
||||
@@ -697,6 +_,7 @@
|
||||
@@ -705,6 +_,7 @@
|
||||
this.rainLevel = Mth.clamp(this.rainLevel, 0.0F, 1.0F);
|
||||
}
|
||||
|
||||
@ -409,7 +409,7 @@
|
||||
if (this.oRainLevel != this.rainLevel) {
|
||||
this.server
|
||||
.getPlayerList()
|
||||
@@ -719,14 +_,47 @@
|
||||
@@ -727,14 +_,47 @@
|
||||
this.server.getPlayerList().broadcastAll(new ClientboundGameEventPacket(ClientboundGameEventPacket.RAIN_LEVEL_CHANGE, this.rainLevel));
|
||||
this.server.getPlayerList().broadcastAll(new ClientboundGameEventPacket(ClientboundGameEventPacket.THUNDER_LEVEL_CHANGE, this.thunderLevel));
|
||||
}
|
||||
@ -461,7 +461,7 @@
|
||||
}
|
||||
|
||||
public void resetEmptyTime() {
|
||||
@@ -748,18 +_,46 @@
|
||||
@@ -756,18 +_,46 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -508,7 +508,7 @@
|
||||
}
|
||||
|
||||
private void tickPassenger(Entity ridingEntity, Entity passengerEntity) {
|
||||
@@ -768,10 +_,12 @@
|
||||
@@ -776,10 +_,12 @@
|
||||
} else if (passengerEntity instanceof Player || this.entityTickList.contains(passengerEntity)) {
|
||||
passengerEntity.setOldPosAndRot();
|
||||
passengerEntity.tickCount++;
|
||||
@ -521,7 +521,7 @@
|
||||
profilerFiller.pop();
|
||||
|
||||
for (Entity entity : passengerEntity.getPassengers()) {
|
||||
@@ -788,6 +_,7 @@
|
||||
@@ -810,6 +_,7 @@
|
||||
public void save(@Nullable ProgressListener progress, boolean flush, boolean skipSave) {
|
||||
ServerChunkCache chunkSource = this.getChunkSource();
|
||||
if (!skipSave) {
|
||||
@ -529,7 +529,7 @@
|
||||
if (progress != null) {
|
||||
progress.progressStartNoAbort(Component.translatable("menu.savingLevel"));
|
||||
}
|
||||
@@ -804,11 +_,19 @@
|
||||
@@ -826,11 +_,19 @@
|
||||
this.entityManager.autoSave();
|
||||
}
|
||||
}
|
||||
@ -550,7 +550,7 @@
|
||||
}
|
||||
|
||||
DimensionDataStorage dataStorage = this.getChunkSource().getDataStorage();
|
||||
@@ -873,18 +_,40 @@
|
||||
@@ -895,18 +_,40 @@
|
||||
|
||||
@Override
|
||||
public boolean addFreshEntity(Entity entity) {
|
||||
@ -594,7 +594,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -907,40 +_,119 @@
|
||||
@@ -929,40 +_,119 @@
|
||||
this.entityManager.addNewEntity(player);
|
||||
}
|
||||
|
||||
@ -719,7 +719,7 @@
|
||||
if (d * d + d1 * d1 + d2 * d2 < 1024.0) {
|
||||
serverPlayer.connection.send(new ClientboundBlockDestructionPacket(breakerId, pos, progress));
|
||||
}
|
||||
@@ -1015,7 +_,7 @@
|
||||
@@ -1037,7 +_,7 @@
|
||||
pos.getX(),
|
||||
pos.getY(),
|
||||
pos.getZ(),
|
||||
@ -728,7 +728,7 @@
|
||||
this.dimension(),
|
||||
new ClientboundLevelEventPacket(type, pos, data, false)
|
||||
);
|
||||
@@ -1027,6 +_,11 @@
|
||||
@@ -1049,6 +_,11 @@
|
||||
|
||||
@Override
|
||||
public void gameEvent(Holder<GameEvent> gameEvent, Vec3 pos, GameEvent.Context context) {
|
||||
@ -740,7 +740,7 @@
|
||||
this.gameEventDispatcher.post(gameEvent, pos, context);
|
||||
}
|
||||
|
||||
@@ -1039,17 +_,28 @@
|
||||
@@ -1061,17 +_,28 @@
|
||||
|
||||
this.getChunkSource().blockChanged(pos);
|
||||
this.pathTypesByPosCache.invalidate(pos);
|
||||
@ -769,7 +769,7 @@
|
||||
|
||||
try {
|
||||
this.isUpdatingNavigations = true;
|
||||
@@ -1061,15 +_,23 @@
|
||||
@@ -1083,15 +_,23 @@
|
||||
this.isUpdatingNavigations = false;
|
||||
}
|
||||
}
|
||||
@ -793,7 +793,7 @@
|
||||
this.neighborUpdater.updateNeighborsAtExceptFromFacing(pos, block, null, orientation);
|
||||
}
|
||||
|
||||
@@ -1118,6 +_,42 @@
|
||||
@@ -1140,6 +_,42 @@
|
||||
ParticleOptions largeExplosionParticles,
|
||||
Holder<SoundEvent> explosionSound
|
||||
) {
|
||||
@ -836,7 +836,7 @@
|
||||
Explosion.BlockInteraction blockInteraction = switch (explosionInteraction) {
|
||||
case NONE -> Explosion.BlockInteraction.KEEP;
|
||||
case BLOCK -> this.getDestroyType(GameRules.RULE_BLOCK_EXPLOSION_DROP_DECAY);
|
||||
@@ -1126,10 +_,17 @@
|
||||
@@ -1148,10 +_,17 @@
|
||||
: Explosion.BlockInteraction.KEEP;
|
||||
case TNT -> this.getDestroyType(GameRules.RULE_TNT_EXPLOSION_DROP_DECAY);
|
||||
case TRIGGER -> Explosion.BlockInteraction.TRIGGER_BLOCK;
|
||||
@ -854,7 +854,7 @@
|
||||
ParticleOptions particleOptions = serverExplosion.isSmall() ? smallExplosionParticles : largeExplosionParticles;
|
||||
|
||||
for (ServerPlayer serverPlayer : this.players) {
|
||||
@@ -1138,6 +_,8 @@
|
||||
@@ -1160,6 +_,8 @@
|
||||
serverPlayer.connection.send(new ClientboundExplodePacket(vec3, optional, particleOptions, explosionSound));
|
||||
}
|
||||
}
|
||||
@ -863,7 +863,7 @@
|
||||
}
|
||||
|
||||
private Explosion.BlockInteraction getDestroyType(GameRules.Key<GameRules.BooleanValue> decayGameRule) {
|
||||
@@ -1208,7 +_,7 @@
|
||||
@@ -1230,7 +_,7 @@
|
||||
public <T extends ParticleOptions> int sendParticles(
|
||||
T type, double posX, double posY, double posZ, int particleCount, double xOffset, double yOffset, double zOffset, double speed
|
||||
) {
|
||||
@ -872,7 +872,7 @@
|
||||
}
|
||||
|
||||
public <T extends ParticleOptions> int sendParticles(
|
||||
@@ -1224,13 +_,49 @@
|
||||
@@ -1246,13 +_,49 @@
|
||||
double zOffset,
|
||||
double speed
|
||||
) {
|
||||
@ -924,7 +924,7 @@
|
||||
if (this.sendParticles(serverPlayer, overrideLimiter, posX, posY, posZ, clientboundLevelParticlesPacket)) {
|
||||
i++;
|
||||
}
|
||||
@@ -1293,7 +_,7 @@
|
||||
@@ -1315,7 +_,7 @@
|
||||
|
||||
@Nullable
|
||||
public BlockPos findNearestMapStructure(TagKey<Structure> structureTag, BlockPos pos, int radius, boolean skipExistingChunks) {
|
||||
@ -933,7 +933,7 @@
|
||||
return null;
|
||||
} else {
|
||||
Optional<HolderSet.Named<Structure>> optional = this.registryAccess().lookupOrThrow(Registries.STRUCTURE).get(structureTag);
|
||||
@@ -1340,10 +_,36 @@
|
||||
@@ -1362,10 +_,36 @@
|
||||
@Nullable
|
||||
@Override
|
||||
public MapItemSavedData getMapData(MapId mapId) {
|
||||
@ -971,7 +971,7 @@
|
||||
this.getServer().overworld().getDataStorage().set(MapItemSavedData.type(mapId), data);
|
||||
}
|
||||
|
||||
@@ -1355,17 +_,27 @@
|
||||
@@ -1377,17 +_,27 @@
|
||||
BlockPos spawnPos = this.levelData.getSpawnPos();
|
||||
float spawnAngle = this.levelData.getSpawnAngle();
|
||||
if (!spawnPos.equals(pos) || spawnAngle != angle) {
|
||||
@ -1001,7 +1001,7 @@
|
||||
}
|
||||
|
||||
this.lastSpawnChunkRadius = i;
|
||||
@@ -1400,6 +_,11 @@
|
||||
@@ -1422,6 +_,11 @@
|
||||
DebugPackets.sendPoiRemovedPacket(this, blockPos);
|
||||
}));
|
||||
optional1.ifPresent(holder -> this.getServer().execute(() -> {
|
||||
@ -1013,7 +1013,7 @@
|
||||
this.getPoiManager().add(blockPos, (Holder<PoiType>)holder);
|
||||
DebugPackets.sendPoiAddedPacket(this, blockPos);
|
||||
}));
|
||||
@@ -1552,12 +_,12 @@
|
||||
@@ -1574,12 +_,12 @@
|
||||
}
|
||||
|
||||
public boolean isFlat() {
|
||||
@ -1028,7 +1028,7 @@
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -1608,6 +_,7 @@
|
||||
@@ -1630,6 +_,7 @@
|
||||
|
||||
@Override
|
||||
public LevelEntityGetter<Entity> getEntities() {
|
||||
@ -1036,7 +1036,7 @@
|
||||
return this.entityManager.getEntityGetter();
|
||||
}
|
||||
|
||||
@@ -1697,6 +_,28 @@
|
||||
@@ -1736,6 +_,28 @@
|
||||
return this.serverLevelData.getGameRules();
|
||||
}
|
||||
|
||||
@ -1065,15 +1065,15 @@
|
||||
@Override
|
||||
public CrashReportCategory fillReportDetails(CrashReport report) {
|
||||
CrashReportCategory crashReportCategory = super.fillReportDetails(report);
|
||||
@@ -1712,6 +_,7 @@
|
||||
final class EntityCallbacks implements LevelCallback<Entity> {
|
||||
@Override
|
||||
public void onCreated(Entity entity) {
|
||||
@@ -1754,6 +_,7 @@
|
||||
if (entity instanceof WaypointTransmitter waypointTransmitter && waypointTransmitter.isTransmittingWaypoint()) {
|
||||
ServerLevel.this.getWaypointManager().trackWaypoint(waypointTransmitter);
|
||||
}
|
||||
+ entity.setOldPosAndRot(); // Paper - update old pos / rot for new entities as it will default to Vec3.ZERO
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1721,24 +_,32 @@
|
||||
@@ -1767,17 +_,24 @@
|
||||
|
||||
@Override
|
||||
public void onTickingStart(Entity entity) {
|
||||
@ -1086,8 +1086,7 @@
|
||||
ServerLevel.this.entityTickList.remove(entity);
|
||||
+ // Paper start - Reset pearls when they stop being ticked
|
||||
+ if (ServerLevel.this.paperConfig().fixes.disableUnloadedChunkEnderpearlExploit && ServerLevel.this.paperConfig().misc.legacyEnderPearlBehavior && entity instanceof net.minecraft.world.entity.projectile.ThrownEnderpearl pearl) {
|
||||
+ pearl.cachedOwner = null;
|
||||
+ pearl.ownerUUID = null;
|
||||
+ pearl.setOwner(null);
|
||||
+ }
|
||||
+ // Paper end - Reset pearls when they stop being ticked
|
||||
}
|
||||
@ -1099,7 +1098,8 @@
|
||||
+ // ServerLevel.this.getChunkSource().addEntity(entity); // Paper - ignore and warn about illegal addEntity calls instead of crashing server; moved down below valid=true
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
ServerLevel.this.players.add(serverPlayer);
|
||||
ServerLevel.this.updateSleepingPlayerList();
|
||||
if (serverPlayer.isReceivingWaypoints()) {
|
||||
@@ -1792,7 +_,7 @@
|
||||
}
|
||||
|
||||
if (entity instanceof Mob mob) {
|
||||
@ -1108,7 +1108,7 @@
|
||||
String string = "onTrackingStart called during navigation iteration";
|
||||
Util.logAndPauseIfInIde(
|
||||
"onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration")
|
||||
@@ -1755,10 +_,52 @@
|
||||
@@ -1809,10 +_,52 @@
|
||||
}
|
||||
|
||||
entity.updateDynamicGameEventListener(DynamicGameEventListener::add);
|
||||
@ -1161,7 +1161,7 @@
|
||||
ServerLevel.this.getChunkSource().removeEntity(entity);
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
ServerLevel.this.players.remove(serverPlayer);
|
||||
@@ -1766,7 +_,7 @@
|
||||
@@ -1821,7 +_,7 @@
|
||||
}
|
||||
|
||||
if (entity instanceof Mob mob) {
|
||||
@ -1170,7 +1170,7 @@
|
||||
String string = "onTrackingStart called during navigation iteration";
|
||||
Util.logAndPauseIfInIde(
|
||||
"onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration")
|
||||
@@ -1783,6 +_,15 @@
|
||||
@@ -1838,6 +_,15 @@
|
||||
}
|
||||
|
||||
entity.updateDynamicGameEventListener(DynamicGameEventListener::remove);
|
||||
@ -1186,7 +1186,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1790,4 +_,24 @@
|
||||
@@ -1845,4 +_,24 @@
|
||||
entity.updateDynamicGameEventListener(DynamicGameEventListener::move);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,6 @@
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -65,7 +_,6 @@
|
||||
import net.minecraft.network.protocol.game.ClientboundHurtAnimationPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundMerchantOffersPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundOpenBookPacket;
|
||||
-import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundPlayerCombatEndPacket;
|
||||
@@ -235,7 +_,8 @@
|
||||
@@ -245,7 +_,8 @@
|
||||
private int levitationStartTime;
|
||||
private boolean disconnected;
|
||||
private int requestedViewDistance = 2;
|
||||
@ -18,7 +10,7 @@
|
||||
@Nullable
|
||||
private Vec3 startingToFallPosition;
|
||||
@Nullable
|
||||
@@ -281,6 +_,13 @@
|
||||
@@ -291,6 +_,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,7 +24,7 @@
|
||||
@Override
|
||||
public void sendSlotChange(AbstractContainerMenu container, int slot, ItemStack itemStack) {
|
||||
ServerPlayer.this.connection.send(new ClientboundContainerSetSlotPacket(container.containerId, container.incrementStateId(), slot, itemStack));
|
||||
@@ -316,6 +_,32 @@
|
||||
@@ -326,6 +_,32 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,7 +57,7 @@
|
||||
@Override
|
||||
public void dataChanged(AbstractContainerMenu containerMenu, int dataSlotIndex, int value) {
|
||||
}
|
||||
@@ -344,9 +_,43 @@
|
||||
@@ -354,9 +_,43 @@
|
||||
public void sendSystemMessage(Component component) {
|
||||
ServerPlayer.this.sendSystemMessage(component);
|
||||
}
|
||||
@ -108,22 +100,20 @@
|
||||
+ public @Nullable org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event
|
||||
|
||||
public ServerPlayer(MinecraftServer server, ServerLevel level, GameProfile gameProfile, ClientInformation clientInformation) {
|
||||
super(level, level.getSharedSpawnPos(), level.getSharedSpawnAngle(), gameProfile);
|
||||
@@ -356,16 +_,22 @@
|
||||
super(level, gameProfile);
|
||||
@@ -366,15 +_,21 @@
|
||||
this.server = server;
|
||||
this.stats = server.getPlayerList().getPlayerStats(this);
|
||||
this.advancements = server.getPlayerList().getPlayerAdvancements(this);
|
||||
- this.snapTo(this.adjustSpawnLocation(level, level.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F);
|
||||
- this.updateOptions(clientInformation);
|
||||
+ // this.snapTo(this.adjustSpawnLocation(level, level.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F); // Paper - Don't move existing players to world spawn
|
||||
+ this.updateOptionsNoEvents(clientInformation); // Paper - don't call options events on login
|
||||
this.object = null;
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
+ this.displayName = this.getScoreboardName();
|
||||
+ this.adventure$displayName = net.kyori.adventure.text.Component.text(this.getScoreboardName()); // Paper
|
||||
+ this.bukkitPickUpLoot = true;
|
||||
+ this.maxHealthCache = this.getMaxHealth();
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -135,22 +125,22 @@
|
||||
int max = Math.max(0, this.server.getSpawnRadius(level));
|
||||
int floor = Mth.floor(level.getWorldBorder().getDistanceToBorder(pos.getX(), pos.getZ()));
|
||||
if (floor < max) {
|
||||
@@ -436,6 +_,7 @@
|
||||
this.enteredNetherPosition = compound.read("entered_nether_pos", Vec3.CODEC).orElse(null);
|
||||
this.seenCredits = compound.getBooleanOr("seenCredits", false);
|
||||
this.recipeBook.fromNbt(compound.getCompoundOrEmpty("recipeBook"), key -> this.server.getRecipeManager().byKey(key).isPresent());
|
||||
+ this.getBukkitEntity().readExtraData(compound); // CraftBukkit
|
||||
@@ -446,6 +_,7 @@
|
||||
this.seenCredits = input.getBooleanOr("seenCredits", false);
|
||||
input.read("recipeBook", ServerRecipeBook.Packed.CODEC)
|
||||
.ifPresent(packed -> this.recipeBook.loadUntrusted(packed, key -> this.server.getRecipeManager().byKey(key).isPresent()));
|
||||
+ this.getBukkitEntity().readExtraData(input); // CraftBukkit
|
||||
if (this.isSleeping()) {
|
||||
this.stopSleeping();
|
||||
}
|
||||
@@ -459,12 +_,24 @@
|
||||
compound.putBoolean("spawn_extra_particles_on_fall", this.spawnExtraParticlesOnFall);
|
||||
compound.storeNullable("raid_omen_position", BlockPos.CODEC, this.raidOmenPosition);
|
||||
this.saveEnderPearls(compound);
|
||||
+ this.getBukkitEntity().setExtraData(compound); // CraftBukkit
|
||||
@@ -469,12 +_,24 @@
|
||||
output.putBoolean("spawn_extra_particles_on_fall", this.spawnExtraParticlesOnFall);
|
||||
output.storeNullable("raid_omen_position", BlockPos.CODEC, this.raidOmenPosition);
|
||||
this.saveEnderPearls(output);
|
||||
+ this.getBukkitEntity().setExtraData(output); // CraftBukkit
|
||||
}
|
||||
|
||||
private void saveParentVehicle(CompoundTag tag) {
|
||||
private void saveParentVehicle(ValueOutput output) {
|
||||
Entity rootVehicle = this.getRootVehicle();
|
||||
Entity vehicle = this.getVehicle();
|
||||
- if (vehicle != null && rootVehicle != this && rootVehicle.hasExactlyOnePlayerPassenger()) {
|
||||
@ -166,19 +156,19 @@
|
||||
+ }
|
||||
+ if (persistVehicle && vehicle != null && rootVehicle != this && rootVehicle.hasExactlyOnePlayerPassenger() && !rootVehicle.isRemoved()) { // Paper - Ensure valid vehicle status
|
||||
+ // CraftBukkit end
|
||||
CompoundTag compoundTag = new CompoundTag();
|
||||
CompoundTag compoundTag1 = new CompoundTag();
|
||||
rootVehicle.save(compoundTag1);
|
||||
@@ -479,7 +_,7 @@
|
||||
if (!compound.isEmpty()) {
|
||||
ServerLevel serverLevel = this.serverLevel();
|
||||
ValueOutput valueOutput = output.child("RootVehicle");
|
||||
valueOutput.store("Attach", UUIDUtil.CODEC, vehicle.getUUID());
|
||||
rootVehicle.save(valueOutput.child("Entity"));
|
||||
@@ -486,7 +_,7 @@
|
||||
if (!optional.isEmpty()) {
|
||||
ServerLevel serverLevel = this.level();
|
||||
Entity entity = EntityType.loadEntityRecursive(
|
||||
- compound.get().getCompoundOrEmpty("Entity"), serverLevel, EntitySpawnReason.LOAD, entity2 -> !serverLevel.addWithUUID(entity2) ? null : entity2
|
||||
+ compound.get().getCompoundOrEmpty("Entity"), serverLevel, EntitySpawnReason.LOAD, entity2 -> !serverLevel.addWithUUID(entity2, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT) ? null : entity2 // Paper - Entity#getEntitySpawnReason
|
||||
- optional.get().childOrEmpty("Entity"), serverLevel, EntitySpawnReason.LOAD, entity2 -> !serverLevel.addWithUUID(entity2) ? null : entity2
|
||||
+ optional.get().childOrEmpty("Entity"), serverLevel, EntitySpawnReason.LOAD, entity2 -> !serverLevel.addWithUUID(entity2, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT) ? null : entity2 // Paper - Entity#getEntitySpawnReason
|
||||
);
|
||||
if (entity != null) {
|
||||
UUID uuid = compound.get().read("Attach", UUIDUtil.CODEC).orElse(null);
|
||||
@@ -496,10 +_,10 @@
|
||||
UUID uuid = optional.get().read("Attach", UUIDUtil.CODEC).orElse(null);
|
||||
@@ -503,10 +_,10 @@
|
||||
|
||||
if (!this.isPassenger()) {
|
||||
LOGGER.warn("Couldn't reattach entity to player");
|
||||
@ -191,15 +181,15 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -511,6 +_,7 @@
|
||||
ListTag listTag = new ListTag();
|
||||
@@ -518,6 +_,7 @@
|
||||
ValueOutput.ValueOutputList valueOutputList = output.childrenList("ender_pearls");
|
||||
|
||||
for (ThrownEnderpearl thrownEnderpearl : this.enderPearls) {
|
||||
+ if (thrownEnderpearl.level().paperConfig().misc.legacyEnderPearlBehavior) continue; // Paper - Allow using old ender pearl behavior
|
||||
if (thrownEnderpearl.isRemoved()) {
|
||||
LOGGER.warn("Trying to save removed ender pearl, skipping");
|
||||
} else {
|
||||
@@ -546,6 +_,16 @@
|
||||
@@ -550,6 +_,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,7 +206,7 @@
|
||||
public void setExperiencePoints(int experiencePoints) {
|
||||
float f = this.getXpNeededForNextLevel();
|
||||
float f1 = (f - 1.0F) / f;
|
||||
@@ -603,6 +_,11 @@
|
||||
@@ -607,6 +_,11 @@
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
@ -228,7 +218,7 @@
|
||||
this.tickClientLoadTimeout();
|
||||
this.gameMode.tick();
|
||||
this.wardenSpawnTracker.tick();
|
||||
@@ -610,9 +_,14 @@
|
||||
@@ -614,9 +_,14 @@
|
||||
this.invulnerableTime--;
|
||||
}
|
||||
|
||||
@ -246,7 +236,7 @@
|
||||
this.containerMenu = this.inventoryMenu;
|
||||
}
|
||||
|
||||
@@ -662,7 +_,7 @@
|
||||
@@ -675,7 +_,7 @@
|
||||
|
||||
public void doTick() {
|
||||
try {
|
||||
@ -255,7 +245,7 @@
|
||||
super.tick();
|
||||
}
|
||||
|
||||
@@ -676,7 +_,7 @@
|
||||
@@ -689,7 +_,7 @@
|
||||
if (this.getHealth() != this.lastSentHealth
|
||||
|| this.lastSentFood != this.foodData.getFoodLevel()
|
||||
|| this.foodData.getSaturationLevel() == 0.0F != this.lastFoodSaturationZero) {
|
||||
@ -264,7 +254,7 @@
|
||||
this.lastSentHealth = this.getHealth();
|
||||
this.lastSentFood = this.foodData.getFoodLevel();
|
||||
this.lastFoodSaturationZero = this.foodData.getSaturationLevel() == 0.0F;
|
||||
@@ -707,6 +_,12 @@
|
||||
@@ -720,6 +_,12 @@
|
||||
this.updateScoreForCriteria(ObjectiveCriteria.EXPERIENCE, Mth.ceil((float)this.lastRecordedExperience));
|
||||
}
|
||||
|
||||
@ -277,7 +267,7 @@
|
||||
if (this.experienceLevel != this.lastRecordedLevel) {
|
||||
this.lastRecordedLevel = this.experienceLevel;
|
||||
this.updateScoreForCriteria(ObjectiveCriteria.LEVEL, Mth.ceil((float)this.lastRecordedLevel));
|
||||
@@ -720,6 +_,21 @@
|
||||
@@ -733,6 +_,21 @@
|
||||
if (this.tickCount % 20 == 0) {
|
||||
CriteriaTriggers.LOCATION.trigger(this);
|
||||
}
|
||||
@ -299,8 +289,8 @@
|
||||
} catch (Throwable var4) {
|
||||
CrashReport crashReport = CrashReport.forThrowable(var4, "Ticking player");
|
||||
CrashReportCategory crashReportCategory = crashReport.addCategory("Player being ticked");
|
||||
@@ -744,7 +_,7 @@
|
||||
if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.serverLevel().getGameRules().getBoolean(GameRules.RULE_NATURAL_REGENERATION)) {
|
||||
@@ -757,7 +_,7 @@
|
||||
if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.level().getGameRules().getBoolean(GameRules.RULE_NATURAL_REGENERATION)) {
|
||||
if (this.tickCount % 20 == 0) {
|
||||
if (this.getHealth() < this.getMaxHealth()) {
|
||||
- this.heal(1.0F);
|
||||
@ -308,7 +298,7 @@
|
||||
}
|
||||
|
||||
float saturationLevel = this.foodData.getSaturationLevel();
|
||||
@@ -793,15 +_,36 @@
|
||||
@@ -806,15 +_,36 @@
|
||||
}
|
||||
|
||||
private void updateScoreForCriteria(ObjectiveCriteria criteria, int points) {
|
||||
@ -318,7 +308,7 @@
|
||||
- @Override
|
||||
- public void die(DamageSource cause) {
|
||||
- this.gameEvent(GameEvent.ENTITY_DIE);
|
||||
- boolean _boolean = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES);
|
||||
- boolean _boolean = this.level().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES);
|
||||
- if (_boolean) {
|
||||
- Component deathMessage = this.getCombatTracker().getDeathMessage();
|
||||
+ this.level().getCraftServer().getScoreboardManager().forAllObjectives(criteria, this, score -> score.set(points)); // CraftBukkit - Use our scores instead
|
||||
@ -354,7 +344,7 @@
|
||||
this.connection
|
||||
.send(
|
||||
new ClientboundPlayerCombatKillPacket(this.getId(), deathMessage),
|
||||
@@ -818,6 +_,65 @@
|
||||
@@ -831,6 +_,65 @@
|
||||
}
|
||||
)
|
||||
);
|
||||
@ -366,13 +356,13 @@
|
||||
+ @Override
|
||||
+ public void die(DamageSource cause) {
|
||||
+ // this.gameEvent(GameEvent.ENTITY_DIE); // Paper - move below event cancellation check
|
||||
+ boolean _boolean = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); final boolean showDeathMessage = _boolean; // Paper - OBFHELPER
|
||||
+ boolean _boolean = this.level().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); final boolean showDeathMessage = _boolean; // Paper - OBFHELPER
|
||||
+ // CraftBukkit start - fire PlayerDeathEvent
|
||||
+ if (this.isRemoved()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ List<DefaultDrop> loot = new java.util.ArrayList<>(this.getInventory().getContainerSize()); // Paper - Restore vanilla drops behavior
|
||||
+ boolean keepInventory = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || this.isSpectator();
|
||||
+ boolean keepInventory = this.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || this.isSpectator();
|
||||
+ if (!keepInventory) {
|
||||
+ for (ItemStack item : this.getInventory().getContents()) {
|
||||
+ if (!item.isEmpty() && !EnchantmentHelper.has(item, net.minecraft.world.item.enchantment.EnchantmentEffectComponents.PREVENT_EQUIPMENT_DROP)) {
|
||||
@ -380,9 +370,9 @@
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (this.shouldDropLoot() && this.serverLevel().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - fix player loottables running when mob loot gamerule is false
|
||||
+ if (this.shouldDropLoot() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - fix player loottables running when mob loot gamerule is false
|
||||
+ // SPIGOT-5071: manually add player loot tables (SPIGOT-5195 - ignores keepInventory rule)
|
||||
+ this.dropFromLootTable(this.serverLevel(), cause, this.lastHurtByPlayerMemoryTime > 0);
|
||||
+ this.dropFromLootTable(this.level(), cause, this.lastHurtByPlayerMemoryTime > 0);
|
||||
+ // Paper - Restore vanilla drops behaviour; custom death loot is a noop on server player, remove.
|
||||
+ loot.addAll(this.drops);
|
||||
+ this.drops.clear(); // SPIGOT-5188: make sure to clear
|
||||
@ -420,7 +410,7 @@
|
||||
Team team = this.getTeam();
|
||||
if (team == null || team.getDeathMessageVisibility() == Team.Visibility.ALWAYS) {
|
||||
this.server.getPlayerList().broadcastSystemMessage(deathMessage, false);
|
||||
@@ -827,7 +_,7 @@
|
||||
@@ -840,7 +_,7 @@
|
||||
this.server.getPlayerList().broadcastSystemToAllExceptTeam(this, deathMessage);
|
||||
}
|
||||
} else {
|
||||
@ -429,14 +419,14 @@
|
||||
}
|
||||
|
||||
this.removeEntitiesOnShoulder();
|
||||
@@ -835,11 +_,35 @@
|
||||
@@ -848,11 +_,35 @@
|
||||
this.tellNeutralMobsThatIDied();
|
||||
}
|
||||
|
||||
- if (!this.isSpectator()) {
|
||||
- this.dropAllDeathLoot(this.serverLevel(), cause);
|
||||
- this.dropAllDeathLoot(this.level(), cause);
|
||||
+ // SPIGOT-5478 must be called manually now
|
||||
+ if (event.shouldDropExperience()) this.dropExperience(this.serverLevel(), cause.getEntity()); // Paper - tie to event
|
||||
+ if (event.shouldDropExperience()) this.dropExperience(this.level(), cause.getEntity()); // Paper - tie to event
|
||||
+ // we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory.
|
||||
+ if (!event.getKeepInventory()) {
|
||||
+ // Paper start - PlayerDeathEvent#getItemsToKeep
|
||||
@ -468,7 +458,7 @@
|
||||
LivingEntity killCredit = this.getKillCredit();
|
||||
if (killCredit != null) {
|
||||
this.awardStat(Stats.ENTITY_KILLED_BY.get(killCredit.getType()));
|
||||
@@ -872,10 +_,10 @@
|
||||
@@ -885,10 +_,10 @@
|
||||
public void awardKillScore(Entity entity, DamageSource damageSource) {
|
||||
if (entity != this) {
|
||||
super.awardKillScore(entity, damageSource);
|
||||
@ -481,7 +471,7 @@
|
||||
} else {
|
||||
this.awardStat(Stats.MOB_KILLS);
|
||||
}
|
||||
@@ -891,7 +_,7 @@
|
||||
@@ -904,7 +_,7 @@
|
||||
if (playersTeam != null) {
|
||||
int id = playersTeam.getColor().getId();
|
||||
if (id >= 0 && id < crtieria.length) {
|
||||
@ -490,7 +480,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -902,9 +_,20 @@
|
||||
@@ -915,9 +_,20 @@
|
||||
return false;
|
||||
} else {
|
||||
Entity entity = damageSource.getEntity();
|
||||
@ -513,7 +503,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -914,23 +_,77 @@
|
||||
@@ -927,23 +_,77 @@
|
||||
}
|
||||
|
||||
private boolean isPvpAllowed() {
|
||||
@ -596,8 +586,8 @@
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
public static Optional<ServerPlayer.RespawnPosAngle> findRespawnAndUseSpawnBlock(
|
||||
@@ -947,10 +_,10 @@
|
||||
public boolean isReceivingWaypoints() {
|
||||
@@ -978,10 +_,10 @@
|
||||
level.setBlock(blockPos, blockState.setValue(RespawnAnchorBlock.CHARGE, blockState.getValue(RespawnAnchorBlock.CHARGE) - 1), 3);
|
||||
}
|
||||
|
||||
@ -610,7 +600,7 @@
|
||||
} else if (!flag) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
@@ -958,7 +_,7 @@
|
||||
@@ -989,7 +_,7 @@
|
||||
BlockState blockState1 = level.getBlockState(blockPos.above());
|
||||
boolean isPossibleToRespawnInThis1 = blockState1.getBlock().isPossibleToRespawnInThis(blockState1);
|
||||
return isPossibleToRespawnInThis && isPossibleToRespawnInThis1
|
||||
@ -619,7 +609,7 @@
|
||||
: Optional.empty();
|
||||
}
|
||||
}
|
||||
@@ -976,6 +_,7 @@
|
||||
@@ -1007,6 +_,7 @@
|
||||
@Nullable
|
||||
@Override
|
||||
public ServerPlayer teleport(TeleportTransition teleportTransition) {
|
||||
@ -627,10 +617,10 @@
|
||||
if (this.isRemoved()) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -985,17 +_,52 @@
|
||||
@@ -1016,17 +_,52 @@
|
||||
|
||||
ServerLevel level = teleportTransition.newLevel();
|
||||
ServerLevel serverLevel = this.serverLevel();
|
||||
ServerLevel serverLevel = this.level();
|
||||
- ResourceKey<Level> resourceKey = serverLevel.dimension();
|
||||
+ // CraftBukkit start
|
||||
+ ResourceKey<net.minecraft.world.level.dimension.LevelStem> resourceKey = serverLevel.getTypeKey();
|
||||
@ -640,8 +630,8 @@
|
||||
+ org.bukkit.Location exit = org.bukkit.craftbukkit.util.CraftLocation.toBukkit(absolutePosition.position(), level.getWorld(), absolutePosition.yRot(), absolutePosition.xRot());
|
||||
+ org.bukkit.event.player.PlayerTeleportEvent tpEvent = new org.bukkit.event.player.PlayerTeleportEvent(this.getBukkitEntity(), enter, exit.clone(), teleportTransition.cause());
|
||||
+ // Paper start - gateway-specific teleport event
|
||||
+ if (this.portalProcess != null && this.portalProcess.isSamePortal(((net.minecraft.world.level.block.EndGatewayBlock) net.minecraft.world.level.block.Blocks.END_GATEWAY)) && this.serverLevel().getBlockEntity(this.portalProcess.getEntryPosition()) instanceof net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity theEndGatewayBlockEntity) {
|
||||
+ tpEvent = new com.destroystokyo.paper.event.player.PlayerTeleportEndGatewayEvent(this.getBukkitEntity(), enter, exit.clone(), new org.bukkit.craftbukkit.block.CraftEndGateway(this.serverLevel().getWorld(), theEndGatewayBlockEntity));
|
||||
+ if (this.portalProcess != null && this.portalProcess.isSamePortal(((net.minecraft.world.level.block.EndGatewayBlock) net.minecraft.world.level.block.Blocks.END_GATEWAY)) && this.level().getBlockEntity(this.portalProcess.getEntryPosition()) instanceof net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity theEndGatewayBlockEntity) {
|
||||
+ tpEvent = new com.destroystokyo.paper.event.player.PlayerTeleportEndGatewayEvent(this.getBukkitEntity(), enter, exit.clone(), new org.bukkit.craftbukkit.block.CraftEndGateway(this.level().getWorld(), theEndGatewayBlockEntity));
|
||||
+ }
|
||||
+ // Paper end - gateway-specific teleport event
|
||||
+ org.bukkit.Bukkit.getServer().getPluginManager().callEvent(tpEvent);
|
||||
@ -683,7 +673,7 @@
|
||||
this.isChangingDimension = true;
|
||||
LevelData levelData = level.getLevelData();
|
||||
this.connection.send(new ClientboundRespawnPacket(this.createCommonSpawnInfo(level), (byte)3));
|
||||
@@ -1004,16 +_,30 @@
|
||||
@@ -1035,16 +_,30 @@
|
||||
playerList.sendPlayerPermissionLevel(this);
|
||||
serverLevel.removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION);
|
||||
this.unsetRemoved();
|
||||
@ -716,12 +706,10 @@
|
||||
this.connection.resetPosition();
|
||||
level.addDuringTeleport(this);
|
||||
profilerFiller.pop();
|
||||
@@ -1027,10 +_,39 @@
|
||||
this.lastSentExp = -1;
|
||||
@@ -1059,10 +_,37 @@
|
||||
this.lastSentHealth = -1.0F;
|
||||
this.lastSentFood = -1;
|
||||
+
|
||||
+
|
||||
this.teleportSpectators(teleportTransition, serverLevel);
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.event.player.PlayerChangedWorldEvent changeEvent = new org.bukkit.event.player.PlayerChangedWorldEvent(this.getBukkitEntity(), serverLevel.getWorld());
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(changeEvent);
|
||||
@ -756,7 +744,7 @@
|
||||
|
||||
@Override
|
||||
public void forceSetRotation(float yRot, float xRot) {
|
||||
@@ -1040,12 +_,26 @@
|
||||
@@ -1072,12 +_,26 @@
|
||||
public void triggerDimensionChangeTriggers(ServerLevel level) {
|
||||
ResourceKey<Level> resourceKey = level.dimension();
|
||||
ResourceKey<Level> resourceKey1 = this.level().dimension();
|
||||
@ -786,7 +774,7 @@
|
||||
this.enteredNetherPosition = null;
|
||||
}
|
||||
}
|
||||
@@ -1061,19 +_,18 @@
|
||||
@@ -1093,19 +_,18 @@
|
||||
this.containerMenu.broadcastChanges();
|
||||
}
|
||||
|
||||
@ -810,7 +798,7 @@
|
||||
if (this.level().isBrightOutside()) {
|
||||
return Either.left(Player.BedSleepingProblem.NOT_POSSIBLE_NOW);
|
||||
} else {
|
||||
@@ -1092,7 +_,34 @@
|
||||
@@ -1124,7 +_,34 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -846,7 +834,7 @@
|
||||
this.awardStat(Stats.SLEEP_IN_BED);
|
||||
CriteriaTriggers.SLEPT_IN_BED.trigger(this);
|
||||
});
|
||||
@@ -1128,21 +_,29 @@
|
||||
@@ -1160,21 +_,29 @@
|
||||
|
||||
@Override
|
||||
public void stopSleepInBed(boolean wakeImmediately, boolean updateLevelForSleepingPlayers) {
|
||||
@ -859,7 +847,7 @@
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
if (this.isSleeping()) {
|
||||
this.serverLevel().getChunkSource().broadcastAndSend(this, new ClientboundAnimatePacket(this, 2));
|
||||
this.level().getChunkSource().broadcastAndSend(this, new ClientboundAnimatePacket(this, 2));
|
||||
}
|
||||
|
||||
super.stopSleepInBed(wakeImmediately, updateLevelForSleepingPlayers);
|
||||
@ -879,8 +867,8 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1185,8 +_,9 @@
|
||||
this.connection.send(new ClientboundOpenSignEditorPacket(signEntity.getBlockPos(), isFrontText));
|
||||
@@ -1222,8 +_,9 @@
|
||||
this.connection.send(new ClientboundShowDialogPacket(dialog));
|
||||
}
|
||||
|
||||
- public void nextContainerCounter() {
|
||||
@ -890,7 +878,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1194,12 +_,39 @@
|
||||
@@ -1231,12 +_,39 @@
|
||||
if (menu == null) {
|
||||
return OptionalInt.empty();
|
||||
} else {
|
||||
@ -931,7 +919,7 @@
|
||||
if (abstractContainerMenu == null) {
|
||||
if (this.isSpectator()) {
|
||||
this.displayClientMessage(Component.translatable("container.spectatorCantOpen").withStyle(ChatFormatting.RED), true);
|
||||
@@ -1207,10 +_,14 @@
|
||||
@@ -1244,10 +_,14 @@
|
||||
|
||||
return OptionalInt.empty();
|
||||
} else {
|
||||
@ -948,7 +936,7 @@
|
||||
return OptionalInt.of(this.containerCounter);
|
||||
}
|
||||
}
|
||||
@@ -1223,14 +_,25 @@
|
||||
@@ -1260,14 +_,25 @@
|
||||
|
||||
@Override
|
||||
public void openHorseInventory(AbstractHorse horse, Container inventory) {
|
||||
@ -977,7 +965,7 @@
|
||||
this.initMenu(this.containerMenu);
|
||||
}
|
||||
|
||||
@@ -1252,10 +_,30 @@
|
||||
@@ -1289,10 +_,30 @@
|
||||
|
||||
@Override
|
||||
public void closeContainer() {
|
||||
@ -1008,7 +996,7 @@
|
||||
@Override
|
||||
public void doCloseContainer() {
|
||||
this.containerMenu.removed(this);
|
||||
@@ -1278,19 +_,19 @@
|
||||
@@ -1315,19 +_,19 @@
|
||||
int rounded = Math.round((float)Math.sqrt(dx * dx + dy * dy + dz * dz) * 100.0F);
|
||||
if (rounded > 0) {
|
||||
this.awardStat(Stats.SWIM_ONE_CM, rounded);
|
||||
@ -1031,7 +1019,7 @@
|
||||
}
|
||||
} else if (this.onClimbable()) {
|
||||
if (dy > 0.0) {
|
||||
@@ -1301,13 +_,13 @@
|
||||
@@ -1338,13 +_,13 @@
|
||||
if (rounded > 0) {
|
||||
if (this.isSprinting()) {
|
||||
this.awardStat(Stats.SPRINT_ONE_CM, rounded);
|
||||
@ -1048,7 +1036,7 @@
|
||||
}
|
||||
}
|
||||
} else if (this.isFallFlying()) {
|
||||
@@ -1347,13 +_,13 @@
|
||||
@@ -1386,13 +_,13 @@
|
||||
@Override
|
||||
public void awardStat(Stat<?> stat, int amount) {
|
||||
this.stats.increment(this, stat, amount);
|
||||
@ -1064,7 +1052,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1384,9 +_,9 @@
|
||||
@@ -1423,9 +_,9 @@
|
||||
super.jumpFromGround();
|
||||
this.awardStat(Stats.JUMP);
|
||||
if (this.isSprinting()) {
|
||||
@ -1076,7 +1064,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1399,6 +_,13 @@
|
||||
@@ -1438,6 +_,13 @@
|
||||
public void disconnect() {
|
||||
this.disconnected = true;
|
||||
this.ejectPassengers();
|
||||
@ -1090,7 +1078,7 @@
|
||||
if (this.isSleeping()) {
|
||||
this.stopSleepInBed(true, false);
|
||||
}
|
||||
@@ -1410,6 +_,7 @@
|
||||
@@ -1449,6 +_,7 @@
|
||||
|
||||
public void resetSentInfo() {
|
||||
this.lastSentHealth = -1.0E8F;
|
||||
@ -1098,7 +1086,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1444,12 +_,12 @@
|
||||
@@ -1483,12 +_,12 @@
|
||||
this.onUpdateAbilities();
|
||||
if (keepEverything) {
|
||||
this.getAttributes().assignBaseValues(that.getAttributes());
|
||||
@ -1113,16 +1101,16 @@
|
||||
}
|
||||
|
||||
this.getInventory().replaceWith(that.getInventory());
|
||||
@@ -1460,7 +_,7 @@
|
||||
@@ -1499,7 +_,7 @@
|
||||
this.portalProcess = that.portalProcess;
|
||||
} else {
|
||||
this.getAttributes().assignBaseValues(that.getAttributes());
|
||||
- this.setHealth(this.getMaxHealth());
|
||||
+ // this.setHealth(this.getMaxHealth()); // CraftBukkit
|
||||
if (this.serverLevel().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || that.isSpectator()) {
|
||||
if (this.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || that.isSpectator()) {
|
||||
this.getInventory().replaceWith(that.getInventory());
|
||||
this.experienceLevel = that.experienceLevel;
|
||||
@@ -1476,7 +_,7 @@
|
||||
@@ -1515,7 +_,7 @@
|
||||
this.lastSentExp = -1;
|
||||
this.lastSentHealth = -1.0F;
|
||||
this.lastSentFood = -1;
|
||||
@ -1131,7 +1119,7 @@
|
||||
this.seenCredits = that.seenCredits;
|
||||
this.enteredNetherPosition = that.enteredNetherPosition;
|
||||
this.chunkTrackingView = that.chunkTrackingView;
|
||||
@@ -1529,7 +_,7 @@
|
||||
@@ -1568,7 +_,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1140,7 +1128,7 @@
|
||||
if (this.isSleeping()) {
|
||||
this.stopSleepInBed(true, true);
|
||||
}
|
||||
@@ -1538,7 +_,7 @@
|
||||
@@ -1577,7 +_,7 @@
|
||||
this.setCamera(this);
|
||||
}
|
||||
|
||||
@ -1149,7 +1137,7 @@
|
||||
if (flag) {
|
||||
this.setYHeadRot(relativeMovements.contains(Relative.Y_ROT) ? this.getYHeadRot() + yaw : yaw);
|
||||
}
|
||||
@@ -1575,9 +_,17 @@
|
||||
@@ -1615,9 +_,17 @@
|
||||
}
|
||||
|
||||
public boolean setGameMode(GameType gameMode) {
|
||||
@ -1169,7 +1157,7 @@
|
||||
} else {
|
||||
this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.CHANGE_GAME_MODE, gameMode.getId()));
|
||||
if (gameMode == GameType.SPECTATOR) {
|
||||
@@ -1593,7 +_,7 @@
|
||||
@@ -1633,7 +_,7 @@
|
||||
|
||||
this.onUpdateAbilities();
|
||||
this.updateEffectVisibility();
|
||||
@ -1178,7 +1166,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1649,8 +_,13 @@
|
||||
@@ -1689,8 +_,13 @@
|
||||
}
|
||||
|
||||
public void sendChatMessage(OutgoingChatMessage message, boolean filtered, ChatType.Bound boundType) {
|
||||
@ -1193,7 +1181,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1661,7 +_,42 @@
|
||||
@@ -1701,7 +_,42 @@
|
||||
}
|
||||
|
||||
public void updateOptions(ClientInformation clientInformation) {
|
||||
@ -1236,7 +1224,7 @@
|
||||
this.requestedViewDistance = clientInformation.viewDistance();
|
||||
this.chatVisibility = clientInformation.chatVisibility();
|
||||
this.canChatColor = clientInformation.chatColors();
|
||||
@@ -1747,8 +_,23 @@
|
||||
@@ -1787,8 +_,23 @@
|
||||
Entity camera = this.getCamera();
|
||||
this.camera = (Entity)(entityToSpectate == null ? this : entityToSpectate);
|
||||
if (camera != this.camera) {
|
||||
@ -1261,7 +1249,7 @@
|
||||
}
|
||||
|
||||
if (entityToSpectate != null) {
|
||||
@@ -1782,11 +_,11 @@
|
||||
@@ -1822,11 +_,11 @@
|
||||
|
||||
@Nullable
|
||||
public Component getTabListDisplayName() {
|
||||
@ -1275,7 +1263,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1817,11 +_,56 @@
|
||||
@@ -1857,11 +_,56 @@
|
||||
}
|
||||
|
||||
public void setRespawnPosition(@Nullable ServerPlayer.RespawnConfig respawnConfig, boolean displayInChat) {
|
||||
@ -1334,7 +1322,7 @@
|
||||
}
|
||||
|
||||
public SectionPos getLastSectionPos() {
|
||||
@@ -1851,16 +_,23 @@
|
||||
@@ -1891,16 +_,23 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1362,24 +1350,24 @@
|
||||
return itemEntity;
|
||||
}
|
||||
|
||||
@@ -1888,6 +_,16 @@
|
||||
@@ -1928,6 +_,16 @@
|
||||
}
|
||||
|
||||
public void loadGameTypes(@Nullable CompoundTag tag) {
|
||||
public void loadGameTypes(@Nullable ValueInput input) {
|
||||
+ // Paper start - Expand PlayerGameModeChangeEvent
|
||||
+ if (this.server.getForcedGameType() != null && this.server.getForcedGameType() != readPlayerMode(tag, "playerGameType")) {
|
||||
+ if (this.server.getForcedGameType() != null && this.server.getForcedGameType() != readPlayerMode(input, "playerGameType")) {
|
||||
+ if (new org.bukkit.event.player.PlayerGameModeChangeEvent(this.getBukkitEntity(), org.bukkit.GameMode.getByValue(this.server.getDefaultGameType().getId()), org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.DEFAULT_GAMEMODE, null).callEvent()) {
|
||||
+ this.gameMode.setGameModeForPlayer(this.server.getForcedGameType(), GameType.DEFAULT_MODE);
|
||||
+ } else {
|
||||
+ this.gameMode.setGameModeForPlayer(readPlayerMode(tag,"playerGameType"), readPlayerMode(tag, "previousPlayerGameType"));
|
||||
+ this.gameMode.setGameModeForPlayer(readPlayerMode(input, "playerGameType"), readPlayerMode(input, "previousPlayerGameType"));
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Expand PlayerGameModeChangeEvent
|
||||
this.gameMode
|
||||
.setGameModeForPlayer(this.calculateGameModeForNewPlayer(readPlayerMode(tag, "playerGameType")), readPlayerMode(tag, "previousPlayerGameType"));
|
||||
.setGameModeForPlayer(this.calculateGameModeForNewPlayer(readPlayerMode(input, "playerGameType")), readPlayerMode(input, "previousPlayerGameType"));
|
||||
}
|
||||
@@ -1989,8 +_,14 @@
|
||||
@@ -2029,8 +_,14 @@
|
||||
|
||||
@Override
|
||||
public void removeVehicle() {
|
||||
@ -1395,7 +1383,7 @@
|
||||
if (vehicle instanceof LivingEntity livingEntity) {
|
||||
for (MobEffectInstance mobEffectInstance : livingEntity.getActiveEffects()) {
|
||||
this.connection.send(new ClientboundRemoveMobEffectPacket(vehicle.getId(), mobEffectInstance.getEffect()));
|
||||
@@ -2089,7 +_,7 @@
|
||||
@@ -2129,7 +_,7 @@
|
||||
}
|
||||
|
||||
public static long placeEnderPearlTicket(ServerLevel level, ChunkPos pos) {
|
||||
@ -1404,7 +1392,7 @@
|
||||
return TicketType.ENDER_PEARL.timeout();
|
||||
}
|
||||
|
||||
@@ -2113,9 +_,11 @@
|
||||
@@ -2153,9 +_,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -1419,7 +1407,7 @@
|
||||
}
|
||||
|
||||
private static float calculateLookAtYaw(Vec3 position, BlockPos towardsPos) {
|
||||
@@ -2123,4 +_,143 @@
|
||||
@@ -2163,4 +_,143 @@
|
||||
return (float)Mth.wrapDegrees(Mth.atan2(vec3.z, vec3.x) * 180.0F / (float)Math.PI - 90.0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
public ServerPlayerGameMode(ServerPlayer player) {
|
||||
this.player = player;
|
||||
this.level = player.serverLevel();
|
||||
this.level = player.level();
|
||||
}
|
||||
|
||||
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper
|
||||
@ -40,8 +40,8 @@
|
||||
+ // CraftBukkit end
|
||||
+ this.setGameModeForPlayer(gameModeForPlayer, this.gameModeForPlayer); // Paper - Fix MC-259571
|
||||
this.player.onUpdateAbilities();
|
||||
this.player
|
||||
.server
|
||||
this.level
|
||||
.getServer()
|
||||
.getPlayerList()
|
||||
- .broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, this.player));
|
||||
+ .broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, this.player), this.player); // CraftBukkit
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
@@ -27,30 +_,67 @@
|
||||
@@ -29,30 +_,67 @@
|
||||
import net.minecraft.util.profiling.Profiler;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@ -73,7 +73,7 @@
|
||||
|
||||
private void close() {
|
||||
if (!this.closed) {
|
||||
@@ -61,6 +_,12 @@
|
||||
@@ -63,6 +_,12 @@
|
||||
|
||||
@Override
|
||||
public void onDisconnect(DisconnectionDetails details) {
|
||||
@ -86,7 +86,7 @@
|
||||
if (this.isSingleplayerOwner()) {
|
||||
LOGGER.info("Stopping singleplayer server as player logged out");
|
||||
this.server.halt(false);
|
||||
@@ -80,7 +_,7 @@
|
||||
@@ -82,7 +_,7 @@
|
||||
this.latency = (this.latency * 3 + i) / 4;
|
||||
this.keepAlivePending = false;
|
||||
} else if (!this.isSingleplayerOwner()) {
|
||||
@ -95,7 +95,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,30 +_,123 @@
|
||||
@@ -90,9 +_,73 @@
|
||||
public void handlePong(ServerboundPongPacket packet) {
|
||||
}
|
||||
|
||||
@ -114,7 +114,7 @@
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
+ PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
+
|
||||
+ final net.minecraft.resources.ResourceLocation identifier = packet.payload().type().id();
|
||||
+ final byte[] data = discardedPayload.data();
|
||||
@ -169,7 +169,8 @@
|
||||
+ // Paper end
|
||||
|
||||
@Override
|
||||
public void handleResourcePackResponse(ServerboundResourcePackPacket packet) {
|
||||
public void handleCustomClickAction(ServerboundCustomClickActionPacket packet) {
|
||||
@@ -105,21 +_,50 @@
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.server);
|
||||
if (packet.action() == ServerboundResourcePackPacket.Action.DECLINED && this.server.isResourcePackRequired()) {
|
||||
LOGGER.info("Disconnecting {} due to resource pack {} rejection", this.playerProfile().getName(), packet.id());
|
||||
@ -225,7 +226,7 @@
|
||||
} else if (this.checkIfClosed(millis)) {
|
||||
this.keepAlivePending = true;
|
||||
this.keepAliveTime = millis;
|
||||
@@ -126,7 +_,7 @@
|
||||
@@ -134,7 +_,7 @@
|
||||
private boolean checkIfClosed(long time) {
|
||||
if (this.closed) {
|
||||
if (time - this.closedListenerTime >= 15000L) {
|
||||
@ -234,10 +235,10 @@
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -149,6 +_,13 @@
|
||||
@@ -157,6 +_,13 @@
|
||||
}
|
||||
|
||||
public void send(Packet<?> packet, @Nullable PacketSendListener listener) {
|
||||
public void send(Packet<?> packet, @Nullable ChannelFutureListener channelFutureListener) {
|
||||
+ // CraftBukkit start
|
||||
+ if (packet == null || this.processedDisconnect) { // Spigot
|
||||
+ return;
|
||||
@ -248,7 +249,7 @@
|
||||
if (packet.isTerminal()) {
|
||||
this.close();
|
||||
}
|
||||
@@ -165,19 +_,115 @@
|
||||
@@ -173,19 +_,115 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -139,16 +_,21 @@
|
||||
@@ -139,16 +_,22 @@
|
||||
return;
|
||||
}
|
||||
|
||||
@ -57,9 +57,10 @@
|
||||
return;
|
||||
}
|
||||
|
||||
- ServerPlayer playerForLogin = playerList.getPlayerForLogin(this.gameProfile, this.clientInformation);
|
||||
+ ServerPlayer playerForLogin = playerList.getPlayerForLogin(this.gameProfile, this.clientInformation, this.player); // CraftBukkit
|
||||
playerList.placeNewPlayer(this.connection, playerForLogin, this.createCookie(this.clientInformation));
|
||||
- ServerPlayer serverPlayer = new ServerPlayer(this.server, this.server.overworld(), this.gameProfile, this.clientInformation);
|
||||
+ ServerPlayer serverPlayer = this.player; // Paper
|
||||
+ this.player.updateOptions(this.clientInformation); // Paper - Of course, we reuse the player
|
||||
playerList.placeNewPlayer(this.connection, serverPlayer, this.createCookie(this.clientInformation));
|
||||
} catch (Exception var5) {
|
||||
LOGGER.error("Couldn't place player in world", (Throwable)var5);
|
||||
+ // Paper start - Debugging
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -204,6 +_,39 @@
|
||||
@@ -208,6 +_,38 @@
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@ -33,14 +33,13 @@
|
||||
+import org.bukkit.event.player.PlayerSwapHandItemsEvent;
|
||||
+import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
+import org.bukkit.event.player.PlayerToggleFlightEvent;
|
||||
+import org.bukkit.event.player.PlayerToggleSneakEvent;
|
||||
+import org.bukkit.event.player.PlayerToggleSprintEvent;
|
||||
+// CraftBukkit end
|
||||
+
|
||||
public class ServerGamePacketListenerImpl
|
||||
extends ServerCommonPacketListenerImpl
|
||||
implements GameProtocols.Context,
|
||||
@@ -222,7 +_,9 @@
|
||||
@@ -226,7 +_,9 @@
|
||||
private int tickCount;
|
||||
private int ackBlockChangesUpTo = -1;
|
||||
private final TickThrottler chatSpamThrottler = new TickThrottler(20, 200);
|
||||
@ -50,7 +49,7 @@
|
||||
private double firstGoodX;
|
||||
private double firstGoodY;
|
||||
private double firstGoodZ;
|
||||
@@ -248,23 +_,42 @@
|
||||
@@ -252,23 +_,42 @@
|
||||
private int receivedMovePacketCount;
|
||||
private int knownMovePacketCount;
|
||||
private boolean receivedMovementThisTick;
|
||||
@ -95,7 +94,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -284,8 +_,8 @@
|
||||
@@ -288,8 +_,8 @@
|
||||
this.knownMovePacketCount = this.receivedMovePacketCount;
|
||||
if (this.clientIsFloating && !this.player.isSleeping() && !this.player.isPassenger() && !this.player.isDeadOrDying()) {
|
||||
if (++this.aboveGroundTickCount > this.getMaximumFlyingTicks(this.player)) {
|
||||
@ -106,7 +105,7 @@
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -303,8 +_,8 @@
|
||||
@@ -307,8 +_,8 @@
|
||||
this.vehicleLastGoodZ = this.lastVehicle.getZ();
|
||||
if (this.clientVehicleIsFloating && this.lastVehicle.getControllingPassenger() == this.player) {
|
||||
if (++this.aboveGroundVehicleTickCount > this.getMaximumFlyingTicks(this.lastVehicle)) {
|
||||
@ -117,7 +116,7 @@
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -320,11 +_,20 @@
|
||||
@@ -324,11 +_,20 @@
|
||||
this.keepConnectionAlive();
|
||||
this.chatSpamThrottler.tick();
|
||||
this.dropSpamThrottler.tick();
|
||||
@ -141,22 +140,49 @@
|
||||
}
|
||||
|
||||
private int getMaximumFlyingTicks(Entity entity) {
|
||||
@@ -384,6 +_,12 @@
|
||||
@@ -388,11 +_,37 @@
|
||||
@Override
|
||||
public void handlePlayerInput(ServerboundPlayerInputPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
+ // CraftBukkit start
|
||||
+ if (!packet.input().equals(this.player.getLastClientInput())) {
|
||||
+ PlayerInputEvent event = new PlayerInputEvent(this.player.getBukkitEntity(), new org.bukkit.craftbukkit.CraftInput(packet.input()));
|
||||
+ this.cserver.getPluginManager().callEvent(event);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper start - PlayerToggleSneakEvent
|
||||
+ net.minecraft.world.entity.player.Input lastInput = this.player.getLastClientInput();
|
||||
+ boolean shiftKeyDown = packet.input().shift();
|
||||
+ if (lastInput.shift() != packet.input().shift()) {
|
||||
+ // Has sneak changed
|
||||
+ org.bukkit.event.player.PlayerToggleSneakEvent event = new org.bukkit.event.player.PlayerToggleSneakEvent(this.getCraftPlayer(), packet.input().shift());
|
||||
+ this.cserver.getPluginManager().callEvent(event);
|
||||
+
|
||||
+ // Technically the player input and the flag is desynced, but this is previous behavior.. so should be fine?
|
||||
+ if (event.isCancelled()) {
|
||||
+ shiftKeyDown = this.player.isShiftKeyDown();
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - PlayerToggleSneakEvent
|
||||
this.player.setLastClientInput(packet.input());
|
||||
if (this.player.hasClientLoaded()) {
|
||||
this.player.resetLastActionTime();
|
||||
- this.player.setShiftKeyDown(packet.input().shift());
|
||||
- }
|
||||
+ this.player.setShiftKeyDown(shiftKeyDown); // Paper
|
||||
+ }
|
||||
+ // Paper start - Add option to make parrots stay
|
||||
+ if (packet.input().shift() && this.player.level().paperConfig().entities.behavior.parrotsAreUnaffectedByPlayerMovement) {
|
||||
+ this.player.removeEntitiesOnShoulder();
|
||||
+ }
|
||||
+ // Paper end - Add option to make parrots stay
|
||||
+
|
||||
}
|
||||
|
||||
@@ -403,17 +_,29 @@
|
||||
private static boolean containsInvalidValues(double x, double y, double z, float yRot, float xRot) {
|
||||
@@ -411,17 +_,29 @@
|
||||
public void handleMoveVehicle(ServerboundMoveVehiclePacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
if (containsInvalidValues(packet.position().x(), packet.position().y(), packet.position().z(), packet.yRot(), packet.xRot())) {
|
||||
- this.disconnect(Component.translatable("multiplayer.disconnect.invalid_vehicle_movement"));
|
||||
+ this.disconnect(Component.translatable("multiplayer.disconnect.invalid_vehicle_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_VEHICLE_MOVEMENT); // Paper - kick event cause
|
||||
@ -168,7 +194,7 @@
|
||||
+ }
|
||||
+ // Paper end - Don't allow vehicle movement from players while teleporting
|
||||
if (rootVehicle != this.player && rootVehicle.getControllingPassenger() == this.player && rootVehicle == this.lastVehicle) {
|
||||
ServerLevel serverLevel = this.player.serverLevel();
|
||||
ServerLevel serverLevel = this.player.level();
|
||||
+ // CraftBukkit - store current player position
|
||||
+ double prevX = this.player.getX();
|
||||
+ double prevY = this.player.getY();
|
||||
@ -188,7 +214,7 @@
|
||||
float f = Mth.wrapDegrees(packet.yRot());
|
||||
float f1 = Mth.wrapDegrees(packet.xRot());
|
||||
double d3 = d - this.vehicleFirstGoodX;
|
||||
@@ -421,7 +_,52 @@
|
||||
@@ -429,7 +_,52 @@
|
||||
double d5 = d2 - this.vehicleFirstGoodZ;
|
||||
double d6 = rootVehicle.getDeltaMovement().lengthSqr();
|
||||
double d7 = d3 * d3 + d4 * d4 + d5 * d5;
|
||||
@ -242,48 +268,34 @@
|
||||
LOGGER.warn(
|
||||
"{} (vehicle of {}) moved too quickly! {},{},{}", rootVehicle.getName().getString(), this.player.getName().getString(), d3, d4, d5
|
||||
);
|
||||
@@ -430,15 +_,16 @@
|
||||
@@ -438,9 +_,9 @@
|
||||
}
|
||||
|
||||
boolean flag = serverLevel.noCollision(rootVehicle, rootVehicle.getBoundingBox().deflate(0.0625));
|
||||
AABB boundingBox = rootVehicle.getBoundingBox();
|
||||
- d3 = d - this.vehicleLastGoodX;
|
||||
- d4 = d1 - this.vehicleLastGoodY;
|
||||
- d5 = d2 - this.vehicleLastGoodZ;
|
||||
+ d3 = d - this.vehicleLastGoodX; // Paper - diff on change, used for checking large move vectors above
|
||||
+ d4 = d1 - this.vehicleLastGoodY; // Paper - diff on change, used for checking large move vectors above
|
||||
+ d5 = d2 - this.vehicleLastGoodZ; // Paper - diff on change, used for checking large move vectors above
|
||||
boolean flag1 = rootVehicle.verticalCollisionBelow;
|
||||
boolean flag = rootVehicle.verticalCollisionBelow;
|
||||
if (rootVehicle instanceof LivingEntity livingEntity && livingEntity.onClimbable()) {
|
||||
livingEntity.resetFallDistance();
|
||||
}
|
||||
|
||||
rootVehicle.move(MoverType.PLAYER, new Vec3(d3, d4, d5));
|
||||
+ double verticalDelta = d4; // Paper - Decompile fix: lvt reassignment lost
|
||||
d3 = d - rootVehicle.getX();
|
||||
d4 = d1 - rootVehicle.getY();
|
||||
if (d4 > -0.5 || d4 < 0.5) {
|
||||
@@ -448,27 +_,80 @@
|
||||
@@ -457,7 +_,7 @@
|
||||
d5 = d2 - rootVehicle.getZ();
|
||||
d7 = d3 * d3 + d4 * d4 + d5 * d5;
|
||||
boolean flag2 = false;
|
||||
boolean flag1 = false;
|
||||
- if (d7 > 0.0625) {
|
||||
+ if (d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot
|
||||
flag2 = true;
|
||||
flag1 = true;
|
||||
LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", rootVehicle.getName().getString(), this.player.getName().getString(), Math.sqrt(d7));
|
||||
}
|
||||
@@ -471,6 +_,57 @@
|
||||
}
|
||||
|
||||
rootVehicle.absSnapTo(d, d1, d2, f, f1);
|
||||
+ this.player.absSnapTo(d, d1, d2, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
|
||||
boolean flag3 = serverLevel.noCollision(rootVehicle, rootVehicle.getBoundingBox().deflate(0.0625));
|
||||
if (flag && (flag2 || !flag3)) {
|
||||
rootVehicle.absSnapTo(x, y, z, f, f1);
|
||||
+ this.player.absSnapTo(x, y, z, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
|
||||
this.send(ClientboundMoveVehiclePacket.fromEntity(rootVehicle));
|
||||
rootVehicle.removeLatestMovementRecordingBatch();
|
||||
return;
|
||||
}
|
||||
|
||||
+ // CraftBukkit start - fire PlayerMoveEvent
|
||||
+ // CraftBukkit start - fire PlayerMoveEvent TODO: this should be removed.
|
||||
+ this.player.absSnapTo(x, y, z, this.player.getYRot(), this.player.getXRot()); // Paper - TODO: This breaks alot of stuff
|
||||
+ org.bukkit.entity.Player player = this.getCraftPlayer();
|
||||
+ if (!this.hasMoved) {
|
||||
+ this.lastPosX = prevX;
|
||||
@ -333,20 +345,11 @@
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
this.player.serverLevel().getChunkSource().move(this.player);
|
||||
this.player.level().getChunkSource().move(this.player);
|
||||
Vec3 vec3 = new Vec3(rootVehicle.getX() - x, rootVehicle.getY() - y, rootVehicle.getZ() - z);
|
||||
this.handlePlayerKnownMovement(vec3);
|
||||
rootVehicle.setOnGroundWithMovement(packet.onGround(), vec3);
|
||||
rootVehicle.doCheckFallDamage(vec3.x, vec3.y, vec3.z, packet.onGround());
|
||||
this.player.checkMovementStatistics(vec3.x, vec3.y, vec3.z);
|
||||
- this.clientVehicleIsFloating = d4 >= -0.03125
|
||||
+ this.clientVehicleIsFloating = verticalDelta >= -0.03125 // Paper - Decompile fix
|
||||
&& !flag1
|
||||
&& !this.server.isFlightAllowed()
|
||||
&& !rootVehicle.isNoGravity()
|
||||
@@ -491,12 +_,12 @@
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
@@ -501,12 +_,12 @@
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
if (packet.getId() == this.awaitingTeleport) {
|
||||
if (this.awaitingPositionFromClient == null) {
|
||||
- this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement"));
|
||||
@ -360,17 +363,17 @@
|
||||
this.awaitingPositionFromClient.x,
|
||||
this.awaitingPositionFromClient.y,
|
||||
this.awaitingPositionFromClient.z,
|
||||
@@ -508,12 +_,20 @@
|
||||
@@ -518,12 +_,20 @@
|
||||
this.lastGoodZ = this.awaitingPositionFromClient.z;
|
||||
this.player.hasChangedDimension();
|
||||
this.awaitingPositionFromClient = null;
|
||||
+ this.player.serverLevel().getChunkSource().move(this.player); // CraftBukkit
|
||||
+ this.player.level().getChunkSource().move(this.player); // CraftBukkit
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleAcceptPlayerLoad(ServerboundPlayerLoadedPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
+ // Paper start - PlayerLoadedWorldEvent
|
||||
+ if (this.player.hasClientLoaded()) {
|
||||
+ return;
|
||||
@ -381,15 +384,15 @@
|
||||
this.player.setClientLoaded(true);
|
||||
}
|
||||
|
||||
@@ -535,6 +_,7 @@
|
||||
@@ -545,6 +_,7 @@
|
||||
@Override
|
||||
public void handleRecipeBookChangeSettingsPacket(ServerboundRecipeBookChangeSettingsPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
+ CraftEventFactory.callRecipeBookSettingsEvent(this.player, packet.getBookType(), packet.isOpen(), packet.isFiltering()); // CraftBukkit
|
||||
this.player.getRecipeBook().setBookSetting(packet.getBookType(), packet.isOpen(), packet.isFiltering());
|
||||
}
|
||||
|
||||
@@ -550,25 +_,110 @@
|
||||
@@ -560,25 +_,110 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -400,8 +403,8 @@
|
||||
+
|
||||
@Override
|
||||
public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) {
|
||||
- PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
+ // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; run this async
|
||||
- PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
+ // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); // Paper - AsyncTabCompleteEvent; run this async
|
||||
+ // CraftBukkit start
|
||||
+ if (!this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - configurable tab spam limits
|
||||
+ this.disconnectAsync(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - Kick event cause // Paper - add proper async disconnect
|
||||
@ -505,8 +508,8 @@
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -578,7 +_,7 @@
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
@@ -588,7 +_,7 @@
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
if (!this.server.isCommandBlockEnabled()) {
|
||||
this.player.sendSystemMessage(Component.translatable("advMode.notEnabled"));
|
||||
- } else if (!this.player.canUseGameMasterBlocks()) {
|
||||
@ -514,8 +517,8 @@
|
||||
this.player.sendSystemMessage(Component.translatable("advMode.notAllowed"));
|
||||
} else {
|
||||
BaseCommandBlock baseCommandBlock = null;
|
||||
@@ -633,7 +_,7 @@
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
@@ -643,7 +_,7 @@
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
if (!this.server.isCommandBlockEnabled()) {
|
||||
this.player.sendSystemMessage(Component.translatable("advMode.notEnabled"));
|
||||
- } else if (!this.player.canUseGameMasterBlocks()) {
|
||||
@ -523,7 +526,7 @@
|
||||
this.player.sendSystemMessage(Component.translatable("advMode.notAllowed"));
|
||||
} else {
|
||||
BaseCommandBlock commandBlock = packet.getCommandBlock(this.player.level());
|
||||
@@ -661,11 +_,11 @@
|
||||
@@ -671,11 +_,11 @@
|
||||
boolean flag = this.player.hasInfiniteMaterials() && packet.includeData();
|
||||
ItemStack cloneItemStack = blockState.getCloneItemStack(serverLevel, blockPos, flag);
|
||||
if (!cloneItemStack.isEmpty()) {
|
||||
@ -537,7 +540,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -689,27 +_,40 @@
|
||||
@@ -702,27 +_,40 @@
|
||||
if (entityOrPart != null && this.player.canInteractWithEntity(entityOrPart, 3.0)) {
|
||||
ItemStack pickResult = entityOrPart.getPickResult();
|
||||
if (pickResult != null && !pickResult.isEmpty()) {
|
||||
@ -578,14 +581,14 @@
|
||||
+ inventory.addAndPickItem(stack, event.getTargetSlot()); // Paper - Add PlayerPickItemEvent
|
||||
}
|
||||
|
||||
this.player.connection.send(new ClientboundSetHeldSlotPacket(inventory.getSelectedSlot()));
|
||||
this.send(new ClientboundSetHeldSlotPacket(inventory.getSelectedSlot()));
|
||||
this.player.inventoryMenu.broadcastChanges();
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -887,6 +_,13 @@
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
@@ -900,6 +_,13 @@
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
int item = packet.getItem();
|
||||
if (this.player.containerMenu instanceof MerchantMenu merchantMenu) {
|
||||
+ // CraftBukkit start
|
||||
@ -598,7 +601,7 @@
|
||||
if (!merchantMenu.stillValid(this.player)) {
|
||||
LOGGER.debug("Player {} interacted with invalid menu {}", this.player, merchantMenu);
|
||||
return;
|
||||
@@ -899,6 +_,51 @@
|
||||
@@ -912,6 +_,51 @@
|
||||
|
||||
@Override
|
||||
public void handleEditBook(ServerboundEditBookPacket packet) {
|
||||
@ -650,7 +653,7 @@
|
||||
int slot = packet.slot();
|
||||
if (Inventory.isHotbarSlot(slot) || slot == 40) {
|
||||
List<String> list = Lists.newArrayList();
|
||||
@@ -913,10 +_,14 @@
|
||||
@@ -926,10 +_,14 @@
|
||||
}
|
||||
|
||||
private void updateBookContents(List<FilteredText> pages, int index) {
|
||||
@ -666,7 +669,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -930,7 +_,8 @@
|
||||
@@ -943,7 +_,8 @@
|
||||
DataComponents.WRITTEN_BOOK_CONTENT,
|
||||
new WrittenBookContent(this.filterableFromOutgoing(title), this.player.getName().getString(), 0, list, true)
|
||||
);
|
||||
@ -676,14 +679,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -974,27 +_,35 @@
|
||||
@@ -991,27 +_,35 @@
|
||||
public void handleMovePlayer(ServerboundMovePlayerPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
if (containsInvalidValues(packet.getX(0.0), packet.getY(0.0), packet.getZ(0.0), packet.getYRot(0.0F), packet.getXRot(0.0F))) {
|
||||
- this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement"));
|
||||
+ this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PLAYER_MOVEMENT); // Paper - kick event cause
|
||||
} else {
|
||||
ServerLevel serverLevel = this.player.serverLevel();
|
||||
ServerLevel serverLevel = this.player.level();
|
||||
- if (!this.player.wonGame) {
|
||||
+ if (!this.player.wonGame && !this.player.isImmobile()) { // CraftBukkit
|
||||
if (this.tickCount == 0) {
|
||||
@ -706,7 +709,7 @@
|
||||
+ double d2 = clampHorizontal(packet.getZ(this.player.getZ())); final double toZ = d2; // Paper - OBFHELPER
|
||||
if (this.player.isPassenger()) {
|
||||
this.player.absSnapTo(this.player.getX(), this.player.getY(), this.player.getZ(), f, f1);
|
||||
this.player.serverLevel().getChunkSource().move(this.player);
|
||||
this.player.level().getChunkSource().move(this.player);
|
||||
+ this.allowedPlayerTicks = 20; // CraftBukkit
|
||||
} else {
|
||||
+ // CraftBukkit - Make sure the move is valid but then reset it for plugins to modify
|
||||
@ -719,7 +722,7 @@
|
||||
double x = this.player.getX();
|
||||
double y = this.player.getY();
|
||||
double z = this.player.getZ();
|
||||
@@ -1003,6 +_,16 @@
|
||||
@@ -1020,6 +_,16 @@
|
||||
double d5 = d2 - this.firstGoodZ;
|
||||
double d6 = this.player.getDeltaMovement().lengthSqr();
|
||||
double d7 = d3 * d3 + d4 * d4 + d5 * d5;
|
||||
@ -736,7 +739,7 @@
|
||||
if (this.player.isSleeping()) {
|
||||
if (d7 > 1.0) {
|
||||
this.teleport(this.player.getX(), this.player.getY(), this.player.getZ(), f, f1);
|
||||
@@ -1012,36 +_,109 @@
|
||||
@@ -1029,36 +_,108 @@
|
||||
if (serverLevel.tickRateManager().runsNormally()) {
|
||||
this.receivedMovePacketCount++;
|
||||
int i = this.receivedMovePacketCount - this.knownMovePacketCount;
|
||||
@ -853,11 +856,10 @@
|
||||
+ return; // ... thanks Mojang for letting move calls teleport across dimensions.
|
||||
+ }
|
||||
+ // Paper end - prevent position desync
|
||||
+ double verticalDelta = d4; // Paper - Decompile fix: lvt reassignment lost
|
||||
double verticalDelta = d4;
|
||||
d3 = d - this.player.getX();
|
||||
d4 = d1 - this.player.getY();
|
||||
if (d4 > -0.5 || d4 < 0.5) {
|
||||
@@ -1050,23 +_,104 @@
|
||||
@@ -1068,20 +_,100 @@
|
||||
|
||||
d5 = d2 - this.player.getZ();
|
||||
d7 = d3 * d3 + d4 * d4 + d5 * d5;
|
||||
@ -883,20 +885,20 @@
|
||||
- if (this.player.noPhysics
|
||||
- || this.player.isSleeping()
|
||||
- || (!flag2 || !serverLevel.noCollision(this.player, boundingBox))
|
||||
- && !this.isPlayerCollidingWithAnythingNew(serverLevel, boundingBox, d, d1, d2)) {
|
||||
- && !this.isEntityCollidingWithAnythingNew(serverLevel, this.player, boundingBox, d, d1, d2)) {
|
||||
+ } // Paper
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - Add fail move event
|
||||
+ boolean teleportBack = !this.player.noPhysics && !this.player.isSleeping() && (movedWrongly && serverLevel.noCollision(this.player, boundingBox) || this.isPlayerCollidingWithAnythingNew(serverLevel, boundingBox, d, d1, d2));
|
||||
+ if (teleportBack) {
|
||||
+ boolean allowMovement = this.player.noPhysics || this.player.isSleeping() || (!movedWrongly || !serverLevel.noCollision(this.player, boundingBox)) && !this.isEntityCollidingWithAnythingNew(serverLevel, this.player, boundingBox, d, d1, d2);
|
||||
+ if (!allowMovement) {
|
||||
+ io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.CLIPPED_INTO_BLOCK,
|
||||
+ toX, toY, toZ, toYaw, toPitch, false);
|
||||
+ if (event.isAllowed()) {
|
||||
+ teleportBack = false;
|
||||
+ allowMovement = true;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!teleportBack) {
|
||||
+ if (allowMovement) {
|
||||
+ // Paper end - Add fail move event
|
||||
+ // CraftBukkit start - fire PlayerMoveEvent
|
||||
+ // Reset to old location first
|
||||
@ -911,7 +913,6 @@
|
||||
+ this.lastPitch = prevPitch;
|
||||
+ this.hasMoved = true;
|
||||
+ }
|
||||
+
|
||||
+ Location from = new Location(player.getWorld(), this.lastPosX, this.lastPosY, this.lastPosZ, this.lastYaw, this.lastPitch); // Get the Players previous Event location.
|
||||
+ Location to = player.getLocation().clone(); // Start off the To location as the Players current location.
|
||||
+
|
||||
@ -964,24 +965,20 @@
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper end
|
||||
this.player.absSnapTo(d, d1, d2, f, f1);
|
||||
boolean isAutoSpinAttack = this.player.isAutoSpinAttack();
|
||||
- this.clientIsFloating = d4 >= -0.03125
|
||||
+ this.clientIsFloating = verticalDelta >= -0.03125 // Paper - Decompile fix
|
||||
&& !flag1
|
||||
&& !this.player.isSpectator()
|
||||
&& !this.server.isFlightAllowed()
|
||||
@@ -1098,7 +_,7 @@
|
||||
this.clientIsFloating = verticalDelta >= -0.03125
|
||||
@@ -1116,7 +_,7 @@
|
||||
this.lastGoodY = this.player.getY();
|
||||
this.lastGoodZ = this.player.getZ();
|
||||
} else {
|
||||
- this.teleport(x, y, z, f, f1);
|
||||
+ this.internalTeleport(x, y, z, f, f1); // CraftBukkit - SPIGOT-1807: Don't call teleport event, when the client thinks the player is falling, because the chunks are not loaded on the client yet.
|
||||
this.player.doCheckFallDamage(this.player.getX() - x, this.player.getY() - y, this.player.getZ() - z, packet.isOnGround());
|
||||
this.player.removeLatestMovementRecordingBatch();
|
||||
this.player.removeLatestMovementRecording();
|
||||
}
|
||||
@@ -1134,6 +_,7 @@
|
||||
@@ -1152,6 +_,7 @@
|
||||
this.player.getXRot()
|
||||
);
|
||||
}
|
||||
@ -989,7 +986,7 @@
|
||||
|
||||
return true;
|
||||
} else {
|
||||
@@ -1157,10 +_,77 @@
|
||||
@@ -1175,10 +_,77 @@
|
||||
}
|
||||
|
||||
public void teleport(double x, double y, double z, float yaw, float pitch) {
|
||||
@ -1068,7 +1065,7 @@
|
||||
this.awaitingTeleportTime = this.tickCount;
|
||||
if (++this.awaitingTeleport == Integer.MAX_VALUE) {
|
||||
this.awaitingTeleport = 0;
|
||||
@@ -1168,12 +_,20 @@
|
||||
@@ -1186,12 +_,20 @@
|
||||
|
||||
this.player.teleportSetPosition(posMoveRotation, relatives);
|
||||
this.awaitingPositionFromClient = this.player.position();
|
||||
@ -1079,17 +1076,17 @@
|
||||
+ this.lastYaw = this.player.getYRot();
|
||||
+ this.lastPitch = this.player.getXRot();
|
||||
+ // CraftBukkit end
|
||||
this.player.connection.send(ClientboundPlayerPositionPacket.of(this.awaitingTeleport, posMoveRotation, relatives));
|
||||
this.send(ClientboundPlayerPositionPacket.of(this.awaitingTeleport, posMoveRotation, relatives));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePlayerAction(ServerboundPlayerActionPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
+ if (this.player.isImmobile()) return; // CraftBukkit
|
||||
if (this.player.hasClientLoaded()) {
|
||||
BlockPos pos = packet.getPos();
|
||||
this.player.resetLastActionTime();
|
||||
@@ -1182,32 +_,95 @@
|
||||
@@ -1200,32 +_,95 @@
|
||||
case SWAP_ITEM_WITH_OFFHAND:
|
||||
if (!this.player.isSpectator()) {
|
||||
ItemStack itemInHand = this.player.getItemInHand(InteractionHand.OFF_HAND);
|
||||
@ -1167,7 +1164,7 @@
|
||||
+ this.player.gameMode.captureSentBlockEntities = true;
|
||||
+ // Paper end - Send block entities after destroy prediction
|
||||
this.player.gameMode.handleBlockBreakAction(pos, action, packet.getDirection(), this.player.level().getMaxY(), packet.getSequence());
|
||||
this.player.connection.ackBlockChangesUpTo(packet.getSequence());
|
||||
this.ackBlockChangesUpTo(packet.getSequence());
|
||||
+ // Paper start - Send block entities after destroy prediction
|
||||
+ this.player.gameMode.captureSentBlockEntities = false;
|
||||
+ // If a block entity was modified speedup the block change ack to avoid the block entity
|
||||
@ -1188,7 +1185,7 @@
|
||||
return;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid player action");
|
||||
@@ -1224,9 +_,31 @@
|
||||
@@ -1242,9 +_,31 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -1214,13 +1211,13 @@
|
||||
+
|
||||
@Override
|
||||
public void handleUseItemOn(ServerboundUseItemOnPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
+ if (this.player.isImmobile()) return; // CraftBukkit
|
||||
+ if (!this.checkLimit(packet.timestamp)) return; // Spigot - check limit
|
||||
if (this.player.hasClientLoaded()) {
|
||||
this.player.connection.ackBlockChangesUpTo(packet.getSequence());
|
||||
ServerLevel serverLevel = this.player.serverLevel();
|
||||
@@ -1235,6 +_,11 @@
|
||||
this.ackBlockChangesUpTo(packet.getSequence());
|
||||
ServerLevel serverLevel = this.player.level();
|
||||
@@ -1253,6 +_,11 @@
|
||||
if (itemInHand.isItemEnabled(serverLevel.enabledFeatures())) {
|
||||
BlockHitResult hitResult = packet.getHitResult();
|
||||
Vec3 location = hitResult.getLocation();
|
||||
@ -1232,7 +1229,7 @@
|
||||
BlockPos blockPos = hitResult.getBlockPos();
|
||||
if (this.player.canInteractWithBlock(blockPos, 1.0)) {
|
||||
Vec3 vec3 = location.subtract(Vec3.atCenterOf(blockPos));
|
||||
@@ -1244,7 +_,8 @@
|
||||
@@ -1262,7 +_,8 @@
|
||||
this.player.resetLastActionTime();
|
||||
int maxY = this.player.level().getMaxY();
|
||||
if (blockPos.getY() <= maxY) {
|
||||
@ -1242,7 +1239,7 @@
|
||||
InteractionResult interactionResult = this.player.gameMode.useItemOn(this.player, serverLevel, itemInHand, hand, hitResult);
|
||||
if (interactionResult.consumesAction()) {
|
||||
CriteriaTriggers.ANY_BLOCK_USE.trigger(this.player, hitResult.getBlockPos(), itemInHand.copy());
|
||||
@@ -1257,10 +_,10 @@
|
||||
@@ -1275,10 +_,10 @@
|
||||
Component component = Component.translatable("build.tooHigh", maxY).withStyle(ChatFormatting.RED);
|
||||
this.player.sendSystemMessage(component, true);
|
||||
} else if (interactionResult instanceof InteractionResult.Success success
|
||||
@ -1255,10 +1252,10 @@
|
||||
} else {
|
||||
Component component1 = Component.translatable("build.tooHigh", maxY).withStyle(ChatFormatting.RED);
|
||||
this.player.sendSystemMessage(component1, true);
|
||||
@@ -1268,13 +_,7 @@
|
||||
@@ -1286,13 +_,8 @@
|
||||
|
||||
this.player.connection.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos));
|
||||
this.player.connection.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos.relative(direction)));
|
||||
this.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos));
|
||||
this.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos.relative(direction)));
|
||||
- } else {
|
||||
- LOGGER.warn(
|
||||
- "Rejecting UseItemOnPacket from {}: Location {} too far away from hit block {}.",
|
||||
@ -1267,19 +1264,20 @@
|
||||
- blockPos
|
||||
- );
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes.
|
||||
+ // Paper - Remove unused warning
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1284,6 +_,8 @@
|
||||
@@ -1302,6 +_,8 @@
|
||||
@Override
|
||||
public void handleUseItem(ServerboundUseItemPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
+ if (this.player.isImmobile()) return; // CraftBukkit
|
||||
+ if (!this.checkLimit(packet.timestamp)) return; // Spigot - check limit
|
||||
if (this.player.hasClientLoaded()) {
|
||||
this.ackBlockChangesUpTo(packet.getSequence());
|
||||
ServerLevel serverLevel = this.player.serverLevel();
|
||||
@@ -1297,6 +_,48 @@
|
||||
ServerLevel serverLevel = this.player.level();
|
||||
@@ -1315,6 +_,48 @@
|
||||
this.player.absSnapRotationTo(f, f1);
|
||||
}
|
||||
|
||||
@ -1328,7 +1326,7 @@
|
||||
if (this.player.gameMode.useItem(this.player, serverLevel, itemInHand, hand) instanceof InteractionResult.Success success
|
||||
&& success.swingSource() == InteractionResult.SwingSource.SERVER) {
|
||||
this.player.swing(hand, true);
|
||||
@@ -1312,7 +_,7 @@
|
||||
@@ -1330,7 +_,7 @@
|
||||
for (ServerLevel serverLevel : this.server.getAllLevels()) {
|
||||
Entity entity = packet.getEntity(serverLevel);
|
||||
if (entity != null) {
|
||||
@ -1337,7 +1335,7 @@
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1329,24 +_,54 @@
|
||||
@@ -1347,24 +_,54 @@
|
||||
|
||||
@Override
|
||||
public void onDisconnect(DisconnectionDetails details) {
|
||||
@ -1395,10 +1393,10 @@
|
||||
throw new IllegalArgumentException("Expected packet sequence nr >= 0");
|
||||
} else {
|
||||
this.ackBlockChangesUpTo = Math.max(sequence, this.ackBlockChangesUpTo);
|
||||
@@ -1356,20 +_,38 @@
|
||||
@@ -1374,20 +_,38 @@
|
||||
@Override
|
||||
public void handleSetCarriedItem(ServerboundSetCarriedItemPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
+ if (this.player.isImmobile()) return; // CraftBukkit
|
||||
if (packet.getSlot() >= 0 && packet.getSlot() < Inventory.getSelectionSize()) {
|
||||
+ if (packet.getSlot() == this.player.getInventory().getSelectedSlot()) { return; } // Paper - don't fire itemheldevent when there wasn't a slot change
|
||||
@ -1434,7 +1432,7 @@
|
||||
Optional<LastSeenMessages> optional = this.unpackAndApplyLastSeen(packet.lastSeenMessages());
|
||||
if (!optional.isEmpty()) {
|
||||
this.tryHandleChat(packet.message(), () -> {
|
||||
@@ -1381,25 +_,45 @@
|
||||
@@ -1399,25 +_,45 @@
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1487,7 +1485,7 @@
|
||||
ParseResults<CommandSourceStack> parseResults = this.parseCommand(command);
|
||||
if (this.server.enforceSecureProfile() && SignableCommand.hasSignableArguments(parseResults)) {
|
||||
LOGGER.error(
|
||||
@@ -1416,28 +_,57 @@
|
||||
@@ -1434,28 +_,57 @@
|
||||
Optional<LastSeenMessages> optional = this.unpackAndApplyLastSeen(packet.lastSeenMessages());
|
||||
if (!optional.isEmpty()) {
|
||||
this.tryHandleChat(packet.command(), () -> {
|
||||
@ -1548,7 +1546,7 @@
|
||||
}
|
||||
|
||||
private void handleMessageDecodeFailure(SignedMessageChain.DecodeException exception) {
|
||||
@@ -1501,14 +_,20 @@
|
||||
@@ -1519,14 +_,20 @@
|
||||
return dispatcher.parse(command, this.player.createCommandSourceStack());
|
||||
}
|
||||
|
||||
@ -1573,7 +1571,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1520,7 +_,7 @@
|
||||
@@ -1538,7 +_,7 @@
|
||||
var10000 = Optional.of(lastSeenMessages);
|
||||
} catch (LastSeenMessagesValidator.ValidationException var5) {
|
||||
LOGGER.error("Failed to validate message acknowledgements from {}: {}", this.player.getName().getString(), var5.getMessage());
|
||||
@ -1582,7 +1580,7 @@
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@@ -1538,22 +_,81 @@
|
||||
@@ -1556,22 +_,81 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1670,7 +1668,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1564,7 +_,7 @@
|
||||
@@ -1582,7 +_,7 @@
|
||||
this.lastSeenMessages.applyOffset(packet.offset());
|
||||
} catch (LastSeenMessagesValidator.ValidationException var5) {
|
||||
LOGGER.error("Failed to validate message acknowledgement offset from {}: {}", this.player.getName().getString(), var5.getMessage());
|
||||
@ -1679,10 +1677,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1572,7 +_,40 @@
|
||||
@@ -1590,7 +_,40 @@
|
||||
@Override
|
||||
public void handleAnimate(ServerboundSwingPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
+ if (this.player.isImmobile()) return; // CraftBukkit
|
||||
this.player.resetLastActionTime();
|
||||
+ // CraftBukkit start - Raytrace to look for 'rogue armswings'
|
||||
@ -1720,23 +1718,13 @@
|
||||
this.player.swing(packet.getHand());
|
||||
}
|
||||
|
||||
@@ -1580,10 +_,41 @@
|
||||
@@ -1598,6 +_,22 @@
|
||||
public void handlePlayerCommand(ServerboundPlayerCommandPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
if (this.player.hasClientLoaded()) {
|
||||
+ // CraftBukkit start
|
||||
+ if (this.player.isRemoved()) return;
|
||||
+ switch (packet.getAction()) {
|
||||
+ case PRESS_SHIFT_KEY:
|
||||
+ case RELEASE_SHIFT_KEY: {
|
||||
+ PlayerToggleSneakEvent event = new PlayerToggleSneakEvent(this.getCraftPlayer(), packet.getAction() == ServerboundPlayerCommandPacket.Action.PRESS_SHIFT_KEY);
|
||||
+ this.cserver.getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ case START_SPRINTING:
|
||||
+ case STOP_SPRINTING: {
|
||||
+ PlayerToggleSprintEvent event = new PlayerToggleSprintEvent(this.getCraftPlayer(), packet.getAction() == ServerboundPlayerCommandPacket.Action.START_SPRINTING);
|
||||
@ -1752,17 +1740,8 @@
|
||||
+
|
||||
this.player.resetLastActionTime();
|
||||
switch (packet.getAction()) {
|
||||
case PRESS_SHIFT_KEY:
|
||||
this.player.setShiftKeyDown(true);
|
||||
+ // Paper start - Add option to make parrots stay
|
||||
+ if (this.player.level().paperConfig().entities.behavior.parrotsAreUnaffectedByPlayerMovement) {
|
||||
+ this.player.removeEntitiesOnShoulder();
|
||||
+ }
|
||||
+ // Paper end - Add option to make parrots stay
|
||||
break;
|
||||
case RELEASE_SHIFT_KEY:
|
||||
this.player.setShiftKeyDown(false);
|
||||
@@ -1630,6 +_,14 @@
|
||||
case START_SPRINTING:
|
||||
@@ -1642,6 +_,14 @@
|
||||
}
|
||||
|
||||
public void sendPlayerChatMessage(PlayerChatMessage chatMessage, ChatType.Bound boundType) {
|
||||
@ -1777,7 +1756,7 @@
|
||||
this.send(
|
||||
new ClientboundPlayerChatPacket(
|
||||
this.nextChatIndex++,
|
||||
@@ -1652,9 +_,11 @@
|
||||
@@ -1664,9 +_,11 @@
|
||||
}
|
||||
|
||||
if (i > 4096) {
|
||||
@ -1790,7 +1769,7 @@
|
||||
}
|
||||
|
||||
public void sendDisguisedChatMessage(Component message, ChatType.Bound boundType) {
|
||||
@@ -1665,6 +_,17 @@
|
||||
@@ -1677,6 +_,17 @@
|
||||
return this.connection.getRemoteAddress();
|
||||
}
|
||||
|
||||
@ -1808,13 +1787,13 @@
|
||||
public void switchToConfig() {
|
||||
this.waitingForSwitchToConfig = true;
|
||||
this.removePlayerFromWorld();
|
||||
@@ -1680,9 +_,16 @@
|
||||
@@ -1692,9 +_,16 @@
|
||||
@Override
|
||||
public void handleInteract(ServerboundInteractPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
+ if (this.player.isImmobile()) return; // CraftBukkit
|
||||
if (this.player.hasClientLoaded()) {
|
||||
final ServerLevel serverLevel = this.player.serverLevel();
|
||||
final ServerLevel serverLevel = this.player.level();
|
||||
final Entity target = packet.getTarget(serverLevel);
|
||||
+ // Spigot start
|
||||
+ if (target == this.player && !this.player.isSpectator()) {
|
||||
@ -1825,7 +1804,7 @@
|
||||
this.player.resetLastActionTime();
|
||||
this.player.setShiftKeyDown(packet.isUsingSecondaryAction());
|
||||
if (target != null) {
|
||||
@@ -1691,16 +_,58 @@
|
||||
@@ -1703,16 +_,58 @@
|
||||
}
|
||||
|
||||
AABB boundingBox = target.getBoundingBox();
|
||||
@ -1889,7 +1868,7 @@
|
||||
ItemStack itemStack1 = success.wasItemInteraction() ? itemStack : ItemStack.EMPTY;
|
||||
CriteriaTriggers.PLAYER_INTERACTED_WITH_ENTITY.trigger(ServerGamePacketListenerImpl.this.player, itemStack1, target);
|
||||
if (success.swingSource() == InteractionResult.SwingSource.SERVER) {
|
||||
@@ -1712,13 +_,13 @@
|
||||
@@ -1724,13 +_,13 @@
|
||||
|
||||
@Override
|
||||
public void onInteraction(InteractionHand hand) {
|
||||
@ -1905,7 +1884,7 @@
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1726,14 +_,19 @@
|
||||
@@ -1738,14 +_,19 @@
|
||||
public void onAttack() {
|
||||
if (!(target instanceof ItemEntity)
|
||||
&& !(target instanceof ExperienceOrb)
|
||||
@ -1927,7 +1906,7 @@
|
||||
ServerGamePacketListenerImpl.LOGGER
|
||||
.warn("Player {} tried to attack an invalid entity", ServerGamePacketListenerImpl.this.player.getName().getString());
|
||||
}
|
||||
@@ -1742,6 +_,27 @@
|
||||
@@ -1754,6 +_,27 @@
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1955,7 +1934,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1754,7 +_,7 @@
|
||||
@@ -1766,7 +_,7 @@
|
||||
case PERFORM_RESPAWN:
|
||||
if (this.player.wonGame) {
|
||||
this.player.wonGame = false;
|
||||
@ -1964,7 +1943,7 @@
|
||||
this.resetPosition();
|
||||
CriteriaTriggers.CHANGED_DIMENSION.trigger(this.player, Level.END, Level.OVERWORLD);
|
||||
} else {
|
||||
@@ -1762,11 +_,11 @@
|
||||
@@ -1774,11 +_,11 @@
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1973,13 +1952,13 @@
|
||||
this.resetPosition();
|
||||
if (this.server.isHardcore()) {
|
||||
- this.player.setGameMode(GameType.SPECTATOR);
|
||||
- this.player.serverLevel().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS).set(false, this.server);
|
||||
- this.player.level().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS).set(false, this.server);
|
||||
+ this.player.setGameMode(GameType.SPECTATOR, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.HARDCORE_DEATH, null); // Paper - Expand PlayerGameModeChangeEvent
|
||||
+ this.player.serverLevel().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS).set(false, this.player.serverLevel()); // CraftBukkit - per-world
|
||||
+ this.player.level().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS).set(false, this.player.level()); // CraftBukkit - per-world
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1777,16 +_,28 @@
|
||||
@@ -1789,16 +_,27 @@
|
||||
|
||||
@Override
|
||||
public void handleContainerClose(ServerboundContainerClosePacket packet) {
|
||||
@ -1989,17 +1968,16 @@
|
||||
+
|
||||
+ public void handleContainerClose(ServerboundContainerClosePacket packet, org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
|
||||
+ // Paper end - Inventory close reason
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
+
|
||||
+ if (this.player.isImmobile()) return; // CraftBukkit
|
||||
+ CraftEventFactory.handleInventoryCloseEvent(this.player, reason); // CraftBukkit // Paper
|
||||
+
|
||||
this.player.doCloseContainer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleContainerClick(ServerboundContainerClickPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
+ if (this.player.isImmobile()) return; // CraftBukkit
|
||||
this.player.resetLastActionTime();
|
||||
- if (this.player.containerMenu.containerId == packet.containerId()) {
|
||||
@ -2010,7 +1988,7 @@
|
||||
this.player.containerMenu.sendAllDataToRemote();
|
||||
} else if (!this.player.containerMenu.stillValid(this.player)) {
|
||||
LOGGER.debug("Player {} interacted with invalid menu {}", this.player, this.player.containerMenu);
|
||||
@@ -1799,7 +_,340 @@
|
||||
@@ -1811,7 +_,340 @@
|
||||
} else {
|
||||
boolean flag = packet.stateId() != this.player.containerMenu.getStateId();
|
||||
this.player.containerMenu.suppressRemoteUpdates();
|
||||
@ -2352,7 +2330,7 @@
|
||||
|
||||
for (Entry<HashedStack> entry : Int2ObjectMaps.fastIterable(packet.changedSlots())) {
|
||||
this.player.containerMenu.setRemoteSlotUnsafe(entry.getIntKey(), entry.getValue());
|
||||
@@ -1812,6 +_,7 @@
|
||||
@@ -1824,6 +_,7 @@
|
||||
} else {
|
||||
this.player.containerMenu.broadcastChanges();
|
||||
}
|
||||
@ -2360,7 +2338,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1819,6 +_,14 @@
|
||||
@@ -1831,6 +_,14 @@
|
||||
|
||||
@Override
|
||||
public void handlePlaceRecipe(ServerboundPlaceRecipePacket packet) {
|
||||
@ -2372,10 +2350,10 @@
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - auto recipe limit
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
this.player.resetLastActionTime();
|
||||
if (!this.player.isSpectator() && this.player.containerMenu.containerId == packet.containerId()) {
|
||||
@@ -1835,9 +_,44 @@
|
||||
@@ -1847,9 +_,44 @@
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2414,22 +2392,22 @@
|
||||
+ }
|
||||
+
|
||||
RecipeBookMenu.PostPlaceAction postPlaceAction = recipeBookMenu.handlePlacement(
|
||||
- packet.useMaxItems(), this.player.isCreative(), recipeHolder, this.player.serverLevel(), this.player.getInventory()
|
||||
+ makeAll, this.player.isCreative(), recipeHolder, this.player.serverLevel(), this.player.getInventory()
|
||||
- packet.useMaxItems(), this.player.isCreative(), recipeHolder, this.player.level(), this.player.getInventory()
|
||||
+ makeAll, this.player.isCreative(), recipeHolder, this.player.level(), this.player.getInventory()
|
||||
);
|
||||
+ // CraftBukkit end
|
||||
if (postPlaceAction == RecipeBookMenu.PostPlaceAction.PLACE_GHOST_RECIPE) {
|
||||
this.player
|
||||
.connection
|
||||
@@ -1853,6 +_,7 @@
|
||||
this.send(new ClientboundPlaceGhostRecipePacket(this.player.containerMenu.containerId, recipeFromDisplay.display().display()));
|
||||
}
|
||||
@@ -1863,6 +_,7 @@
|
||||
@Override
|
||||
public void handleContainerButtonClick(ServerboundContainerButtonClickPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
+ if (this.player.isImmobile()) return; // CraftBukkit
|
||||
this.player.resetLastActionTime();
|
||||
if (this.player.containerMenu.containerId == packet.containerId() && !this.player.isSpectator()) {
|
||||
if (!this.player.containerMenu.stillValid(this.player)) {
|
||||
@@ -1862,6 +_,7 @@
|
||||
@@ -1872,6 +_,7 @@
|
||||
if (flag) {
|
||||
this.player.containerMenu.broadcastChanges();
|
||||
}
|
||||
@ -2437,7 +2415,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1878,10 +_,48 @@
|
||||
@@ -1888,10 +_,48 @@
|
||||
|
||||
boolean flag1 = packet.slotNum() >= 1 && packet.slotNum() <= 45;
|
||||
boolean flag2 = itemStack.isEmpty() || itemStack.getCount() <= itemStack.getMaxStackSize();
|
||||
@ -2486,7 +2464,7 @@
|
||||
} else if (flag && flag2) {
|
||||
if (this.dropSpamThrottler.isUnderThreshold()) {
|
||||
this.dropSpamThrottler.increment();
|
||||
@@ -1895,15 +_,38 @@
|
||||
@@ -1905,15 +_,38 @@
|
||||
|
||||
@Override
|
||||
public void handleSignUpdate(ServerboundSignUpdatePacket packet) {
|
||||
@ -2510,7 +2488,7 @@
|
||||
private void updateSignText(ServerboundSignUpdatePacket packet, List<FilteredText> filteredText) {
|
||||
+ if (this.player.isImmobile()) return; // CraftBukkit
|
||||
this.player.resetLastActionTime();
|
||||
ServerLevel serverLevel = this.player.serverLevel();
|
||||
ServerLevel serverLevel = this.player.level();
|
||||
BlockPos pos = packet.getPos();
|
||||
if (serverLevel.hasChunkAt(pos)) {
|
||||
+ // Paper start - Add API for client-side signs
|
||||
@ -2526,10 +2504,10 @@
|
||||
if (!(serverLevel.getBlockEntity(pos) instanceof SignBlockEntity signBlockEntity)) {
|
||||
return;
|
||||
}
|
||||
@@ -1915,14 +_,32 @@
|
||||
@@ -1925,14 +_,32 @@
|
||||
@Override
|
||||
public void handlePlayerAbilities(ServerboundPlayerAbilitiesPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
- this.player.getAbilities().flying = packet.isFlying() && this.player.getAbilities().mayfly;
|
||||
+ // CraftBukkit start
|
||||
+ if (this.player.getAbilities().mayfly && this.player.getAbilities().flying != packet.isFlying()) {
|
||||
@ -2546,7 +2524,7 @@
|
||||
|
||||
@Override
|
||||
public void handleClientInformation(ServerboundClientInformationPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
+ // Paper start - do not accept invalid information
|
||||
+ if (packet.information().viewDistance() < 0) {
|
||||
+ LOGGER.warn("Disconnecting {} for invalid view distance: {}", this.player.getScoreboardName(), packet.information().viewDistance());
|
||||
@ -2560,16 +2538,16 @@
|
||||
if (this.player.isModelPartShown(PlayerModelPart.HAT) != isModelPartShown) {
|
||||
this.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_HAT, this.player));
|
||||
}
|
||||
@@ -1932,7 +_,7 @@
|
||||
public void handleChangeDifficulty(ServerboundChangeDifficultyPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
if (this.player.hasPermissions(2) || this.isSingleplayerOwner()) {
|
||||
- this.server.setDifficulty(packet.getDifficulty(), false);
|
||||
+ // this.server.setDifficulty(packet.getDifficulty(), false); // Paper - per level difficulty; don't allow clients to change this
|
||||
@@ -1948,7 +_,7 @@
|
||||
packet.difficulty().getDisplayName()
|
||||
);
|
||||
} else {
|
||||
- this.server.setDifficulty(packet.difficulty(), false);
|
||||
+ // this.server.setDifficulty(packet.difficulty(), false); // Paper - per level difficulty; don't allow clients to change this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1952,7 +_,7 @@
|
||||
@@ -1982,7 +_,7 @@
|
||||
ProfilePublicKey.Data data2 = data.profilePublicKey();
|
||||
if (!Objects.equals(data1, data2)) {
|
||||
if (data1 != null && data2.expiresAt().isBefore(data1.expiresAt())) {
|
||||
@ -2578,7 +2556,7 @@
|
||||
} else {
|
||||
try {
|
||||
SignatureValidator profileKeySignatureValidator = this.server.getProfileKeySignatureValidator();
|
||||
@@ -1963,8 +_,8 @@
|
||||
@@ -1993,8 +_,8 @@
|
||||
|
||||
this.resetPlayerChatState(data.validate(this.player.getGameProfile(), profileKeySignatureValidator));
|
||||
} catch (ProfilePublicKey.ValidationException var6) {
|
||||
@ -2589,7 +2567,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1978,7 +_,7 @@
|
||||
@@ -2008,7 +_,7 @@
|
||||
this.connection
|
||||
.setupInboundProtocol(
|
||||
ConfigurationProtocols.SERVERBOUND,
|
||||
@ -2598,7 +2576,7 @@
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1997,27 +_,32 @@
|
||||
@@ -2027,27 +_,32 @@
|
||||
|
||||
private void resetPlayerChatState(RemoteChatSession chatSession) {
|
||||
this.chatSession = chatSession;
|
||||
@ -2627,12 +2605,12 @@
|
||||
|
||||
@Override
|
||||
public void handleClientTickEnd(ServerboundClientTickEndPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
+ this.tickEndEvent.callEvent(); // Paper - add client tick end event
|
||||
if (!this.receivedMovementThisTick) {
|
||||
this.player.setKnownMovement(Vec3.ZERO);
|
||||
}
|
||||
@@ -2048,4 +_,17 @@
|
||||
@@ -2078,4 +_,17 @@
|
||||
interface EntityInteraction {
|
||||
InteractionResult run(ServerPlayer player, Entity entity, InteractionHand hand);
|
||||
}
|
||||
|
||||
@ -73,16 +73,16 @@
|
||||
+ org.apache.logging.log4j.LogManager.getLogger().debug("Failed to check connection throttle", t);
|
||||
+ }
|
||||
+ // Paper end - Connection throttle
|
||||
if (packet.protocolVersion() != SharedConstants.getCurrentVersion().getProtocolVersion()) {
|
||||
if (packet.protocolVersion() != SharedConstants.getCurrentVersion().protocolVersion()) {
|
||||
- Component component;
|
||||
- if (packet.protocolVersion() < 754) {
|
||||
- component = Component.translatable("multiplayer.disconnect.outdated_client", SharedConstants.getCurrentVersion().getName());
|
||||
- component = Component.translatable("multiplayer.disconnect.outdated_client", SharedConstants.getCurrentVersion().name());
|
||||
+ net.kyori.adventure.text.Component adventureComponent; // Paper - Fix hex colors not working in some kick messages
|
||||
+ if (packet.protocolVersion() < SharedConstants.getCurrentVersion().getProtocolVersion()) { // Spigot - SPIGOT-7546: Handle version check correctly for outdated client message
|
||||
+ adventureComponent = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(java.text.MessageFormat.format(org.spigotmc.SpigotConfig.outdatedClientMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().getName())); // Spigot // Paper - Fix hex colors not working in some kick messages
|
||||
+ if (packet.protocolVersion() < SharedConstants.getCurrentVersion().protocolVersion()) { // Spigot - SPIGOT-7546: Handle version check correctly for outdated client message
|
||||
+ adventureComponent = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(java.text.MessageFormat.format(org.spigotmc.SpigotConfig.outdatedClientMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().name())); // Spigot // Paper - Fix hex colors not working in some kick messages
|
||||
} else {
|
||||
- component = Component.translatable("multiplayer.disconnect.incompatible", SharedConstants.getCurrentVersion().getName());
|
||||
+ adventureComponent = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(java.text.MessageFormat.format(org.spigotmc.SpigotConfig.outdatedServerMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().getName())); // Spigot // Paper - Fix hex colors not working in some kick messages
|
||||
- component = Component.translatable("multiplayer.disconnect.incompatible", SharedConstants.getCurrentVersion().name());
|
||||
+ adventureComponent = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(java.text.MessageFormat.format(org.spigotmc.SpigotConfig.outdatedServerMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().name())); // Spigot // Paper - Fix hex colors not working in some kick messages
|
||||
}
|
||||
+ Component component = io.papermc.paper.adventure.PaperAdventure.asVanilla(adventureComponent); // Paper - Fix hex colors not working in some kick messages
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/packs/PathPackResources.java
|
||||
+++ b/net/minecraft/server/packs/PathPackResources.java
|
||||
@@ -103,6 +_,12 @@
|
||||
@@ -112,6 +_,12 @@
|
||||
try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(path)) {
|
||||
for (Path path1 : directoryStream) {
|
||||
String string = path1.getFileName().toString();
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -112,14 +_,16 @@
|
||||
@@ -111,14 +_,16 @@
|
||||
private static final int SEND_PLAYER_INFO_INTERVAL = 600;
|
||||
private static final SimpleDateFormat BAN_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");
|
||||
private final MinecraftServer server;
|
||||
@ -20,7 +20,7 @@
|
||||
public final PlayerDataStorage playerIo;
|
||||
private boolean doWhiteList;
|
||||
private final LayeredRegistryAccess<RegistryLayer> registries;
|
||||
@@ -130,14 +_,26 @@
|
||||
@@ -129,14 +_,26 @@
|
||||
private static final boolean ALLOW_LOGOUTIVATOR = false;
|
||||
private int sendAllPlayerInfoIn;
|
||||
|
||||
@ -47,259 +47,262 @@
|
||||
GameProfile gameProfile = player.getGameProfile();
|
||||
GameProfileCache profileCache = this.server.getProfileCache();
|
||||
String string;
|
||||
@@ -150,30 +_,94 @@
|
||||
@@ -149,20 +_,66 @@
|
||||
}
|
||||
|
||||
Optional<CompoundTag> optional = this.load(player);
|
||||
- ResourceKey<Level> resourceKey = optional.<ResourceKey<Level>>flatMap(
|
||||
- compoundTag -> DimensionType.parseLegacy(new Dynamic<>(NbtOps.INSTANCE, compoundTag.get("Dimension"))).resultOrPartial(LOGGER::error)
|
||||
+ // CraftBukkit start - Better rename detection
|
||||
+ if (optional.isPresent()) {
|
||||
+ string = optional.flatMap(t -> t.getCompound("bukkit")).flatMap(t -> t.getString("lastKnownName")).orElse(string);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper start - move logic in Entity to here, to use bukkit supplied world UUID & reset to main world spawn if no valid world is found
|
||||
+ ResourceKey<Level> resourceKey = null; // Paper
|
||||
+ boolean[] invalidPlayerWorld = {false};
|
||||
+ bukkitData: if (optional.isPresent()) {
|
||||
+ // The main way for bukkit worlds to store the world is the world UUID despite mojang adding custom worlds
|
||||
+ final org.bukkit.World bWorld;
|
||||
+ final CompoundTag playerData = optional.get();
|
||||
+ // TODO maybe convert this to a codec and use compoundTag#read, we need silent variants of that method first.
|
||||
+ final Optional<Long> worldUUIDMost = playerData.getLong("WorldUUIDMost");
|
||||
+ final Optional<Long> worldUUIDLeast = playerData.getLong("WorldUUIDLeast");
|
||||
+ final java.util.Optional<String> worldName = playerData.getString("world");
|
||||
+ if (worldUUIDMost.isPresent() && worldUUIDLeast.isPresent()) {
|
||||
+ bWorld = org.bukkit.Bukkit.getServer().getWorld(new UUID(worldUUIDMost.get(), worldUUIDLeast.get()));
|
||||
+ } else if (worldName.isPresent()) { // Paper - legacy bukkit world name
|
||||
+ bWorld = org.bukkit.Bukkit.getServer().getWorld(worldName.get());
|
||||
+ } else {
|
||||
+ break bukkitData; // if neither of the bukkit data points exist, proceed to the vanilla migration section
|
||||
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(player.problemPath(), LOGGER)) {
|
||||
- Optional<ValueInput> optional1 = this.load(player, scopedCollector);
|
||||
- ResourceKey<Level> resourceKey = optional1.<ResourceKey<Level>>flatMap(valueInput -> valueInput.read("Dimension", Level.RESOURCE_KEY_CODEC))
|
||||
- .orElse(Level.OVERWORLD);
|
||||
+ Optional<ValueInput> optional1 = this.load(player, scopedCollector); final Optional<ValueInput> loadedPlayerData = optional1; // Paper - OBFHELPER
|
||||
+ // CraftBukkit start - Better rename detection
|
||||
+ if (loadedPlayerData.isPresent()) {
|
||||
+ string = loadedPlayerData.flatMap(t -> t.child("bukkit")).flatMap(t -> t.getString("lastKnownName")).orElse(string);
|
||||
+ }
|
||||
+ if (bWorld != null) {
|
||||
+ resourceKey = ((org.bukkit.craftbukkit.CraftWorld) bWorld).getHandle().dimension();
|
||||
+ } else {
|
||||
+ resourceKey = Level.OVERWORLD;
|
||||
+ invalidPlayerWorld[0] = true;
|
||||
+ }
|
||||
+ }
|
||||
+ if (resourceKey == null) { // only run the vanilla logic if we haven't found a world from the bukkit data
|
||||
+ // Below is the vanilla way of getting the dimension, this is for migration from vanilla servers
|
||||
+ resourceKey = optional.<ResourceKey<Level>>flatMap(
|
||||
+ compoundTag -> {
|
||||
+ com.mojang.serialization.DataResult<ResourceKey<Level>> dataResult = DimensionType.parseLegacy(new Dynamic<>(NbtOps.INSTANCE, compoundTag.get("Dimension")));
|
||||
+ final Optional<ResourceKey<Level>> result = dataResult.resultOrPartial(LOGGER::error);
|
||||
+ invalidPlayerWorld[0] = result.isEmpty(); // reset to main world spawn if no valid world is found
|
||||
+ return result;
|
||||
+ }
|
||||
)
|
||||
- .orElse(Level.OVERWORLD);
|
||||
+ .orElse(Level.OVERWORLD); // revert to vanilla default main world, this isn't an "invalid world" since no player data existed
|
||||
+ }
|
||||
+ // Paper end
|
||||
ServerLevel level = this.server.getLevel(resourceKey);
|
||||
ServerLevel serverLevel;
|
||||
if (level == null) {
|
||||
LOGGER.warn("Unknown respawn dimension {}, defaulting to overworld", resourceKey);
|
||||
serverLevel = this.server.overworld();
|
||||
+ invalidPlayerWorld[0] = true; // Paper - reset to main world if no world with parsed value is found
|
||||
} else {
|
||||
serverLevel = level;
|
||||
}
|
||||
|
||||
+ // Paper start - Entity#getEntitySpawnReason
|
||||
+ if (optional.isEmpty()) {
|
||||
+ player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login
|
||||
+ // Paper start - reset to main world spawn if first spawn or invalid world
|
||||
+ }
|
||||
+ if (optional.isEmpty() || invalidPlayerWorld[0]) {
|
||||
+ // Paper end - reset to main world spawn if first spawn or invalid world
|
||||
+ player.snapTo(player.adjustSpawnLocation(serverLevel, serverLevel.getSharedSpawnPos()).getBottomCenter(), serverLevel.getSharedSpawnAngle(), 0.0F); // Paper - MC-200092 - fix first spawn pos yaw being ignored
|
||||
+ }
|
||||
+ // Paper end - Entity#getEntitySpawnReason
|
||||
player.setServerLevel(serverLevel);
|
||||
String loggableAddress = connection.getLoggableAddress(this.server.logIPs());
|
||||
- LOGGER.info(
|
||||
- "{}[{}] logged in with entity id {} at ({}, {}, {})",
|
||||
- player.getName().getString(),
|
||||
- loggableAddress,
|
||||
- player.getId(),
|
||||
- player.getX(),
|
||||
- player.getY(),
|
||||
- player.getZ()
|
||||
- );
|
||||
+ // Spigot start - spawn location event
|
||||
+ org.bukkit.entity.Player spawnPlayer = player.getBukkitEntity();
|
||||
+ org.spigotmc.event.player.PlayerSpawnLocationEvent ev = new org.spigotmc.event.player.PlayerSpawnLocationEvent(spawnPlayer, spawnPlayer.getLocation());
|
||||
+ this.cserver.getPluginManager().callEvent(ev);
|
||||
+
|
||||
+ org.bukkit.Location loc = ev.getSpawnLocation();
|
||||
+ serverLevel = ((org.bukkit.craftbukkit.CraftWorld) loc.getWorld()).getHandle();
|
||||
+
|
||||
+ player.spawnIn(serverLevel);
|
||||
+ // Paper start - set raw so we aren't fully joined to the world (not added to chunk or world)
|
||||
+ player.setPosRaw(loc.getX(), loc.getY(), loc.getZ());
|
||||
+ player.setRot(loc.getYaw(), loc.getPitch());
|
||||
+ // Paper end - set raw so we aren't fully joined to the world
|
||||
+ // Spigot end
|
||||
+ // LOGGER.info( // CraftBukkit - Moved message to after join
|
||||
+ // "{}[{}] logged in with entity id {} at ({}, {}, {})",
|
||||
+ // player.getName().getString(),
|
||||
+ // loggableAddress,
|
||||
+ // player.getId(),
|
||||
+ // player.getX(),
|
||||
+ // player.getY(),
|
||||
+ // player.getZ()
|
||||
+ // );
|
||||
LevelData levelData = serverLevel.getLevelData();
|
||||
player.loadGameTypes(optional.orElse(null));
|
||||
ServerGamePacketListenerImpl serverGamePacketListenerImpl = new ServerGamePacketListenerImpl(this.server, connection, player, cookie);
|
||||
@@ -191,8 +_,8 @@
|
||||
levelData.isHardcore(),
|
||||
this.server.levelKeys(),
|
||||
this.getMaxPlayers(),
|
||||
- this.viewDistance,
|
||||
- this.simulationDistance,
|
||||
+ serverLevel.spigotConfig.viewDistance,// Spigot - view distance
|
||||
+ serverLevel.spigotConfig.simulationDistance,
|
||||
_boolean1,
|
||||
!_boolean,
|
||||
_boolean2,
|
||||
@@ -200,6 +_,7 @@
|
||||
this.server.enforceSecureProfile()
|
||||
)
|
||||
);
|
||||
+ player.getBukkitEntity().sendSupportedChannels(); // CraftBukkit
|
||||
serverGamePacketListenerImpl.send(new ClientboundChangeDifficultyPacket(levelData.getDifficulty(), levelData.isDifficultyLocked()));
|
||||
serverGamePacketListenerImpl.send(new ClientboundPlayerAbilitiesPacket(player.getAbilities()));
|
||||
serverGamePacketListenerImpl.send(new ClientboundSetHeldSlotPacket(player.getInventory().getSelectedSlot()));
|
||||
@@ -219,26 +_,119 @@
|
||||
mutableComponent = Component.translatable("multiplayer.player.joined.renamed", player.getDisplayName(), string);
|
||||
}
|
||||
|
||||
- this.broadcastSystemMessage(mutableComponent.withStyle(ChatFormatting.YELLOW), false);
|
||||
+ // CraftBukkit start
|
||||
+ mutableComponent.withStyle(ChatFormatting.YELLOW);
|
||||
+ Component joinMessage = mutableComponent; // Paper - Adventure
|
||||
serverGamePacketListenerImpl.teleport(player.getX(), player.getY(), player.getZ(), player.getYRot(), player.getXRot());
|
||||
ServerStatus status = this.server.getStatus();
|
||||
if (status != null && !cookie.transferred()) {
|
||||
player.sendServerStatus(status);
|
||||
}
|
||||
|
||||
- player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(this.players));
|
||||
+ // player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(this.players)); // CraftBukkit - replaced with loop below
|
||||
this.players.add(player);
|
||||
+ this.playersByName.put(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT), player); // Spigot
|
||||
this.playersByUUID.put(player.getUUID(), player);
|
||||
- this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player)));
|
||||
- this.sendLevelInfo(player, serverLevel);
|
||||
+ // this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player))); // CraftBukkit - replaced with loop below
|
||||
+ // Paper start - Fire PlayerJoinEvent when Player is actually ready; correctly register player BEFORE PlayerJoinEvent, so the entity is valid and doesn't require tick delay hacks
|
||||
+ player.supressTrackerForLogin = true;
|
||||
serverLevel.addNewPlayer(player);
|
||||
- this.server.getCustomBossEvents().onPlayerConnect(player);
|
||||
- this.sendActivePlayerEffects(player);
|
||||
+ this.server.getCustomBossEvents().onPlayerConnect(player); // see commented out section below serverLevel.addPlayerJoin(player);
|
||||
+ // Paper end - Fire PlayerJoinEvent when Player is actually ready
|
||||
optional.ifPresent(compoundTag -> {
|
||||
player.loadAndSpawnEnderPearls(compoundTag);
|
||||
player.loadAndSpawnParentVehicle(compoundTag);
|
||||
});
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.craftbukkit.entity.CraftPlayer bukkitPlayer = player.getBukkitEntity();
|
||||
+
|
||||
+ // Ensure that player inventory is populated with its viewer
|
||||
+ player.containerMenu.transferTo(player.containerMenu, bukkitPlayer);
|
||||
+
|
||||
+ org.bukkit.event.player.PlayerJoinEvent playerJoinEvent = new org.bukkit.event.player.PlayerJoinEvent(bukkitPlayer, io.papermc.paper.adventure.PaperAdventure.asAdventure(mutableComponent)); // Paper - Adventure
|
||||
+ this.cserver.getPluginManager().callEvent(playerJoinEvent);
|
||||
+
|
||||
+ if (!player.connection.isAcceptingMessages()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage();
|
||||
+
|
||||
+ if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure
|
||||
+ joinMessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(jm); // Paper - Adventure
|
||||
+ this.server.getPlayerList().broadcastSystemMessage(joinMessage, false); // Paper - Adventure
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ // CraftBukkit start - sendAll above replaced with this loop
|
||||
+ ClientboundPlayerInfoUpdatePacket packet = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player)); // Paper - Add Listing API for Player
|
||||
+
|
||||
+ final List<ServerPlayer> onlinePlayers = Lists.newArrayListWithExpectedSize(this.players.size() - 1); // Paper - Use single player info update packet on join
|
||||
+ for (int i = 0; i < this.players.size(); ++i) {
|
||||
+ ServerPlayer entityplayer1 = (ServerPlayer) this.players.get(i);
|
||||
+
|
||||
+ if (entityplayer1.getBukkitEntity().canSee(bukkitPlayer)) {
|
||||
+ // Paper start - Add Listing API for Player
|
||||
+ if (entityplayer1.getBukkitEntity().isListed(bukkitPlayer)) {
|
||||
+ // Paper end - Add Listing API for Player
|
||||
+ entityplayer1.connection.send(packet);
|
||||
+ // Paper start - Add Listing API for Player
|
||||
+ // CraftBukkit end
|
||||
+ // Paper start - move logic in Entity to here, to use bukkit supplied world UUID & reset to main world spawn if no valid world is found
|
||||
+ ResourceKey<Level> resourceKey = null; // Paper
|
||||
+ boolean[] invalidPlayerWorld = {false};
|
||||
+ bukkitData: if (loadedPlayerData.isPresent()) {
|
||||
+ // The main way for bukkit worlds to store the world is the world UUID despite mojang adding custom worlds
|
||||
+ final org.bukkit.World bWorld;
|
||||
+ final ValueInput playerData = loadedPlayerData.get();
|
||||
+ // TODO maybe convert this to a codec and use compoundTag#read, we need silent variants of that method first.
|
||||
+ final Optional<Long> worldUUIDMost = playerData.getLong("WorldUUIDMost");
|
||||
+ final Optional<Long> worldUUIDLeast = playerData.getLong("WorldUUIDLeast");
|
||||
+ final java.util.Optional<String> worldName = playerData.getString("world");
|
||||
+ if (worldUUIDMost.isPresent() && worldUUIDLeast.isPresent()) {
|
||||
+ bWorld = org.bukkit.Bukkit.getServer().getWorld(new UUID(worldUUIDMost.get(), worldUUIDLeast.get()));
|
||||
+ } else if (worldName.isPresent()) { // Paper - legacy bukkit world name
|
||||
+ bWorld = org.bukkit.Bukkit.getServer().getWorld(worldName.get());
|
||||
+ } else {
|
||||
+ entityplayer1.connection.send(ClientboundPlayerInfoUpdatePacket.createSinglePlayerInitializing(player, false));
|
||||
+ break bukkitData; // if neither of the bukkit data points exist, proceed to the vanilla migration section
|
||||
+ }
|
||||
+ // Paper end - Add Listing API for Player
|
||||
+ if (bWorld != null) {
|
||||
+ resourceKey = ((org.bukkit.craftbukkit.CraftWorld) bWorld).getHandle().dimension();
|
||||
+ } else {
|
||||
+ resourceKey = Level.OVERWORLD;
|
||||
+ invalidPlayerWorld[0] = true;
|
||||
+ }
|
||||
+ }
|
||||
+ if (resourceKey == null) { // only run the vanilla logic if we haven't found a world from the bukkit data
|
||||
+ // Below is the vanilla way of getting the dimension, this is for migration from vanilla servers
|
||||
+ resourceKey = loadedPlayerData.<ResourceKey<Level>>flatMap(
|
||||
+ compoundTag -> {
|
||||
+ Optional<ResourceKey<Level>> result = compoundTag.read("Dimension", Level.RESOURCE_KEY_CODEC);
|
||||
+ invalidPlayerWorld[0] = result.isEmpty(); // reset to main world spawn if no valid world is found
|
||||
+ return result;
|
||||
+ }
|
||||
+ )
|
||||
+ .orElse(Level.OVERWORLD); // revert to vanilla default main world, this isn't an "invalid world" since no player data existed
|
||||
+ }
|
||||
+ // Paper end
|
||||
ServerLevel level = this.server.getLevel(resourceKey);
|
||||
ServerLevel serverLevel;
|
||||
if (level == null) {
|
||||
LOGGER.warn("Unknown respawn dimension {}, defaulting to overworld", resourceKey);
|
||||
serverLevel = this.server.overworld();
|
||||
+ invalidPlayerWorld[0] = true; // Paper - reset to main world if no world with parsed value is found
|
||||
} else {
|
||||
serverLevel = level;
|
||||
}
|
||||
|
||||
+ // Paper start - Entity#getEntitySpawnReason
|
||||
+ if (loadedPlayerData.isEmpty()) {
|
||||
+ player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login
|
||||
+ }
|
||||
+ // Paper end - Entity#getEntitySpawnReason
|
||||
player.setServerLevel(serverLevel);
|
||||
- if (optional1.isEmpty()) {
|
||||
+ if (loadedPlayerData.isEmpty() || invalidPlayerWorld[0]) { // Paper - reset to main world spawn if first spawn or invalid world
|
||||
player.snapTo(
|
||||
player.adjustSpawnLocation(serverLevel, serverLevel.getSharedSpawnPos()).getBottomCenter(), serverLevel.getSharedSpawnAngle(), 0.0F
|
||||
);
|
||||
@@ -170,15 +_,29 @@
|
||||
|
||||
serverLevel.waitForChunkAndEntities(player.chunkPosition(), 1);
|
||||
String loggableAddress = connection.getLoggableAddress(this.server.logIPs());
|
||||
- LOGGER.info(
|
||||
- "{}[{}] logged in with entity id {} at ({}, {}, {})",
|
||||
- player.getName().getString(),
|
||||
- loggableAddress,
|
||||
- player.getId(),
|
||||
- player.getX(),
|
||||
- player.getY(),
|
||||
- player.getZ()
|
||||
- );
|
||||
+ // Spigot start - spawn location event
|
||||
+ org.bukkit.entity.Player spawnPlayer = player.getBukkitEntity();
|
||||
+ org.spigotmc.event.player.PlayerSpawnLocationEvent ev = new org.spigotmc.event.player.PlayerSpawnLocationEvent(spawnPlayer, spawnPlayer.getLocation());
|
||||
+ this.cserver.getPluginManager().callEvent(ev);
|
||||
+
|
||||
+ org.bukkit.Location loc = ev.getSpawnLocation();
|
||||
+ serverLevel = ((org.bukkit.craftbukkit.CraftWorld) loc.getWorld()).getHandle();
|
||||
+
|
||||
+ player.spawnIn(serverLevel);
|
||||
+ // Paper start - set raw so we aren't fully joined to the world (not added to chunk or world)
|
||||
+ player.setPosRaw(loc.getX(), loc.getY(), loc.getZ());
|
||||
+ player.setRot(loc.getYaw(), loc.getPitch());
|
||||
+ // Paper end - set raw so we aren't fully joined to the world
|
||||
+ // Spigot end
|
||||
+ // LOGGER.info( // CraftBukkit - Moved message to after join
|
||||
+ // "{}[{}] logged in with entity id {} at ({}, {}, {})",
|
||||
+ // player.getName().getString(),
|
||||
+ // loggableAddress,
|
||||
+ // player.getId(),
|
||||
+ // player.getX(),
|
||||
+ // player.getY(),
|
||||
+ // player.getZ()
|
||||
+ // );
|
||||
LevelData levelData = serverLevel.getLevelData();
|
||||
player.loadGameTypes(optional1.orElse(null));
|
||||
ServerGamePacketListenerImpl serverGamePacketListenerImpl = new ServerGamePacketListenerImpl(this.server, connection, player, cookie);
|
||||
@@ -196,8 +_,8 @@
|
||||
levelData.isHardcore(),
|
||||
this.server.levelKeys(),
|
||||
this.getMaxPlayers(),
|
||||
- this.viewDistance,
|
||||
- this.simulationDistance,
|
||||
+ serverLevel.spigotConfig.viewDistance, // Spigot - view distance
|
||||
+ serverLevel.spigotConfig.simulationDistance, // Spigot - simulation distance
|
||||
_boolean1,
|
||||
!_boolean,
|
||||
_boolean2,
|
||||
@@ -205,6 +_,7 @@
|
||||
this.server.enforceSecureProfile()
|
||||
)
|
||||
);
|
||||
+ player.getBukkitEntity().sendSupportedChannels(); // CraftBukkit
|
||||
serverGamePacketListenerImpl.send(new ClientboundChangeDifficultyPacket(levelData.getDifficulty(), levelData.isDifficultyLocked()));
|
||||
serverGamePacketListenerImpl.send(new ClientboundPlayerAbilitiesPacket(player.getAbilities()));
|
||||
serverGamePacketListenerImpl.send(new ClientboundSetHeldSlotPacket(player.getInventory().getSelectedSlot()));
|
||||
@@ -224,26 +_,119 @@
|
||||
mutableComponent = Component.translatable("multiplayer.player.joined.renamed", player.getDisplayName(), string);
|
||||
}
|
||||
|
||||
- this.broadcastSystemMessage(mutableComponent.withStyle(ChatFormatting.YELLOW), false);
|
||||
+ // CraftBukkit start
|
||||
+ mutableComponent.withStyle(ChatFormatting.YELLOW);
|
||||
+ Component joinMessage = mutableComponent; // Paper - Adventure
|
||||
serverGamePacketListenerImpl.teleport(player.getX(), player.getY(), player.getZ(), player.getYRot(), player.getXRot());
|
||||
ServerStatus status = this.server.getStatus();
|
||||
if (status != null && !cookie.transferred()) {
|
||||
player.sendServerStatus(status);
|
||||
}
|
||||
|
||||
- player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(this.players));
|
||||
+ // player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(this.players)); // CraftBukkit - replaced with loop below
|
||||
this.players.add(player);
|
||||
+ this.playersByName.put(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT), player); // Spigot
|
||||
this.playersByUUID.put(player.getUUID(), player);
|
||||
- this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player)));
|
||||
- this.sendLevelInfo(player, serverLevel);
|
||||
+ // this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player))); // CraftBukkit - replaced with loop below
|
||||
+ // Paper start - Fire PlayerJoinEvent when Player is actually ready; correctly register player BEFORE PlayerJoinEvent, so the entity is valid and doesn't require tick delay hacks
|
||||
+ player.supressTrackerForLogin = true;
|
||||
serverLevel.addNewPlayer(player);
|
||||
- this.server.getCustomBossEvents().onPlayerConnect(player);
|
||||
- this.sendActivePlayerEffects(player);
|
||||
+ this.server.getCustomBossEvents().onPlayerConnect(player); // see commented out section below serverLevel.addPlayerJoin(player);
|
||||
+ // Paper end - Fire PlayerJoinEvent when Player is actually ready
|
||||
optional1.ifPresent(valueInput -> {
|
||||
player.loadAndSpawnEnderPearls(valueInput);
|
||||
player.loadAndSpawnParentVehicle(valueInput);
|
||||
});
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.craftbukkit.entity.CraftPlayer bukkitPlayer = player.getBukkitEntity();
|
||||
+
|
||||
+ // Ensure that player inventory is populated with its viewer
|
||||
+ player.containerMenu.transferTo(player.containerMenu, bukkitPlayer);
|
||||
+
|
||||
+ org.bukkit.event.player.PlayerJoinEvent playerJoinEvent = new org.bukkit.event.player.PlayerJoinEvent(bukkitPlayer, io.papermc.paper.adventure.PaperAdventure.asAdventure(mutableComponent)); // Paper - Adventure
|
||||
+ this.cserver.getPluginManager().callEvent(playerJoinEvent);
|
||||
+
|
||||
+ if (!player.connection.isAcceptingMessages()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (entityplayer1 == player || !bukkitPlayer.canSee(entityplayer1.getBukkitEntity())) { // Paper - Use single player info update packet on join; Don't include joining player
|
||||
+ continue;
|
||||
+ final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage();
|
||||
+
|
||||
+ if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure
|
||||
+ joinMessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(jm); // Paper - Adventure
|
||||
+ this.server.getPlayerList().broadcastSystemMessage(joinMessage, false); // Paper - Adventure
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ // CraftBukkit start - sendAll above replaced with this loop
|
||||
+ ClientboundPlayerInfoUpdatePacket packet = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player)); // Paper - Add Listing API for Player
|
||||
+
|
||||
+ final List<ServerPlayer> onlinePlayers = Lists.newArrayListWithExpectedSize(this.players.size() - 1); // Paper - Use single player info update packet on join
|
||||
+ for (int i = 0; i < this.players.size(); ++i) {
|
||||
+ ServerPlayer entityplayer1 = (ServerPlayer) this.players.get(i);
|
||||
+
|
||||
+ if (entityplayer1.getBukkitEntity().canSee(bukkitPlayer)) {
|
||||
+ // Paper start - Add Listing API for Player
|
||||
+ if (entityplayer1.getBukkitEntity().isListed(bukkitPlayer)) {
|
||||
+ // Paper end - Add Listing API for Player
|
||||
+ entityplayer1.connection.send(packet);
|
||||
+ // Paper start - Add Listing API for Player
|
||||
+ } else {
|
||||
+ entityplayer1.connection.send(ClientboundPlayerInfoUpdatePacket.createSinglePlayerInitializing(player, false));
|
||||
+ }
|
||||
+ // Paper end - Add Listing API for Player
|
||||
+ }
|
||||
+
|
||||
+ if (entityplayer1 == player || !bukkitPlayer.canSee(entityplayer1.getBukkitEntity())) { // Paper - Use single player info update packet on join; Don't include joining player
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ onlinePlayers.add(entityplayer1); // Paper - Use single player info update packet on join
|
||||
+ }
|
||||
+ // Paper start - Use single player info update packet on join
|
||||
+ if (!onlinePlayers.isEmpty()) {
|
||||
+ player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(onlinePlayers, player)); // Paper - Add Listing API for Player
|
||||
+ }
|
||||
+ // Paper end - Use single player info update packet on join
|
||||
+ player.sentListPacket = true;
|
||||
+ player.supressTrackerForLogin = false; // Paper - Fire PlayerJoinEvent when Player is actually ready
|
||||
+ ((ServerLevel)player.level()).getChunkSource().chunkMap.addEntity(player); // Paper - Fire PlayerJoinEvent when Player is actually ready; track entity now
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ //player.refreshEntityData(player); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn // Paper - THIS IS NOT NEEDED ANYMORE
|
||||
+
|
||||
+ this.sendLevelInfo(player, serverLevel);
|
||||
+
|
||||
+ // CraftBukkit start - Only add if the player wasn't moved in the event
|
||||
+ if (player.level() == serverLevel && !serverLevel.players().contains(player)) {
|
||||
+ serverLevel.addNewPlayer(player);
|
||||
+ this.server.getCustomBossEvents().onPlayerConnect(player);
|
||||
+ }
|
||||
+
|
||||
+ onlinePlayers.add(entityplayer1); // Paper - Use single player info update packet on join
|
||||
+ }
|
||||
+ // Paper start - Use single player info update packet on join
|
||||
+ if (!onlinePlayers.isEmpty()) {
|
||||
+ player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(onlinePlayers, player)); // Paper - Add Listing API for Player
|
||||
+ }
|
||||
+ // Paper end - Use single player info update packet on join
|
||||
+ player.sentListPacket = true;
|
||||
+ player.supressTrackerForLogin = false; // Paper - Fire PlayerJoinEvent when Player is actually ready
|
||||
+ ((ServerLevel)player.level()).getChunkSource().chunkMap.addEntity(player); // Paper - Fire PlayerJoinEvent when Player is actually ready; track entity now
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ //player.refreshEntityData(player); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn // Paper - THIS IS NOT NEEDED ANYMORE
|
||||
+
|
||||
+ this.sendLevelInfo(player, serverLevel);
|
||||
+
|
||||
+ // CraftBukkit start - Only add if the player wasn't moved in the event
|
||||
+ if (player.level() == serverLevel && !serverLevel.players().contains(player)) {
|
||||
+ serverLevel.addNewPlayer(player);
|
||||
+ this.server.getCustomBossEvents().onPlayerConnect(player);
|
||||
+ }
|
||||
+
|
||||
+ serverLevel = player.serverLevel(); // CraftBukkit - Update in case join event changed it
|
||||
+ // CraftBukkit end
|
||||
+ this.sendActivePlayerEffects(player);
|
||||
+ // Paper - move loading pearls / parent vehicle up
|
||||
player.initInventoryMenu();
|
||||
+ // CraftBukkit - Moved from above, added world
|
||||
+ // Paper start - Configurable player collision; Add to collideRule team if needed
|
||||
+ final net.minecraft.world.scores.Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard();
|
||||
+ final PlayerTeam collideRuleTeam = scoreboard.getPlayerTeam(this.collideRuleTeamName);
|
||||
+ if (this.collideRuleTeamName != null && collideRuleTeam != null && player.getTeam() == null) {
|
||||
+ scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam);
|
||||
+ }
|
||||
+ // Paper end - Configurable player collision
|
||||
+ PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), loggableAddress, player.getId(), serverLevel.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ());
|
||||
+ // Paper start - Send empty chunk, so players aren't stuck in the world loading screen with our chunk system not sending chunks when dead
|
||||
+ if (player.isDeadOrDying()) {
|
||||
+ net.minecraft.core.Holder<net.minecraft.world.level.biome.Biome> plains = serverLevel.registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.BIOME)
|
||||
+ serverLevel = player.level(); // CraftBukkit - Update in case join event changed it
|
||||
+ // CraftBukkit end
|
||||
+ this.sendActivePlayerEffects(player);
|
||||
+ // Paper - move loading pearls / parent vehicle up
|
||||
player.initInventoryMenu();
|
||||
+ // CraftBukkit - Moved from above, added world
|
||||
+ // Paper start - Configurable player collision; Add to collideRule team if needed
|
||||
+ final net.minecraft.world.scores.Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard();
|
||||
+ final PlayerTeam collideRuleTeam = scoreboard.getPlayerTeam(this.collideRuleTeamName);
|
||||
+ if (this.collideRuleTeamName != null && collideRuleTeam != null && player.getTeam() == null) {
|
||||
+ scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam);
|
||||
+ }
|
||||
+ // Paper end - Configurable player collision
|
||||
+ PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), loggableAddress, player.getId(), serverLevel.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ());
|
||||
+ // Paper start - Send empty chunk, so players aren't stuck in the world loading screen with our chunk system not sending chunks when dead
|
||||
+ if (player.isDeadOrDying()) {
|
||||
+ net.minecraft.core.Holder<net.minecraft.world.level.biome.Biome> plains = serverLevel.registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.BIOME)
|
||||
+ .getOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS);
|
||||
+ player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket(
|
||||
+ player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket(
|
||||
+ new net.minecraft.world.level.chunk.EmptyLevelChunk(serverLevel, player.chunkPosition(), plains),
|
||||
+ serverLevel.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null)
|
||||
+ );
|
||||
+ }
|
||||
+ // Paper end - Send empty chunk
|
||||
+ );
|
||||
+ }
|
||||
+ // Paper end - Send empty chunk
|
||||
}
|
||||
}
|
||||
|
||||
public void updateEntireScoreboard(ServerScoreboard scoreboard, ServerPlayer player) {
|
||||
@@ -261,30 +_,31 @@
|
||||
@@ -267,30 +_,31 @@
|
||||
}
|
||||
|
||||
public void addWorldborderListener(ServerLevel level) {
|
||||
@ -336,7 +339,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -312,56 +_,156 @@
|
||||
@@ -319,56 +_,156 @@
|
||||
}
|
||||
|
||||
protected void save(ServerPlayer player) {
|
||||
@ -362,7 +365,7 @@
|
||||
+ }
|
||||
+ public @Nullable net.kyori.adventure.text.Component remove(ServerPlayer player, net.kyori.adventure.text.Component leaveMessage) {
|
||||
+ // Paper end - Fix kick event leave message not being sent
|
||||
ServerLevel serverLevel = player.serverLevel();
|
||||
ServerLevel serverLevel = player.level();
|
||||
player.awardStat(Stats.LEAVE_GAME);
|
||||
+ // CraftBukkit start - Quitting must be before we do final save of data, in case plugins need to modify it
|
||||
+ // See SPIGOT-5799, SPIGOT-6145
|
||||
@ -423,7 +426,7 @@
|
||||
+ if (!thrownEnderpearl.level().paperConfig().misc.legacyEnderPearlBehavior) {
|
||||
+ thrownEnderpearl.setRemoved(Entity.RemovalReason.UNLOADED_WITH_PLAYER, org.bukkit.event.entity.EntityRemoveEvent.Cause.PLAYER_QUIT); // CraftBukkit - add Bukkit remove cause
|
||||
+ } else {
|
||||
+ thrownEnderpearl.cachedOwner = null;
|
||||
+ thrownEnderpearl.setOwner(null);
|
||||
+ }
|
||||
+ // Paper end - Allow using old ender pearl behavior
|
||||
}
|
||||
@ -495,7 +498,7 @@
|
||||
+ // depending on the outcome.
|
||||
+ SocketAddress socketAddress = loginlistener.connection.getRemoteAddress();
|
||||
+
|
||||
+ ServerPlayer entity = new ServerPlayer(this.server, this.server.getLevel(Level.OVERWORLD), gameProfile, ClientInformation.createDefault());
|
||||
+ ServerPlayer entity = new ServerPlayer(this.server, this.server.getLevel(Level.OVERWORLD), gameProfile, net.minecraft.server.level.ClientInformation.createDefault());
|
||||
+ entity.transferCookieConnection = loginlistener;
|
||||
+ org.bukkit.entity.Player player = entity.getBukkitEntity();
|
||||
+ org.bukkit.event.player.PlayerLoginEvent event = new org.bukkit.event.player.PlayerLoginEvent(player, loginlistener.connection.hostname, ((java.net.InetSocketAddress) socketAddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.connection.channel.remoteAddress()).getAddress());
|
||||
@ -507,7 +510,7 @@
|
||||
MutableComponent mutableComponent = Component.translatable("multiplayer.disconnect.banned.reason", userBanListEntry.getReason());
|
||||
if (userBanListEntry.getExpires() != null) {
|
||||
mutableComponent.append(
|
||||
@@ -369,10 +_,12 @@
|
||||
@@ -376,10 +_,12 @@
|
||||
);
|
||||
}
|
||||
|
||||
@ -524,7 +527,7 @@
|
||||
IpBanListEntry ipBanListEntry = this.ipBans.get(socketAddress);
|
||||
MutableComponent mutableComponent = Component.translatable("multiplayer.disconnect.banned_ip.reason", ipBanListEntry.getReason());
|
||||
if (ipBanListEntry.getExpires() != null) {
|
||||
@@ -381,69 +_,131 @@
|
||||
@@ -388,65 +_,124 @@
|
||||
);
|
||||
}
|
||||
|
||||
@ -538,10 +541,6 @@
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- public ServerPlayer getPlayerForLogin(GameProfile gameProfile, ClientInformation clientInformation) {
|
||||
- return new ServerPlayer(this.server, this.server.overworld(), gameProfile, clientInformation);
|
||||
- }
|
||||
-
|
||||
- public boolean disconnectAllPlayersWithProfile(GameProfile gameProfile) {
|
||||
- UUID id = gameProfile.getId();
|
||||
- Set<ServerPlayer> set = Sets.newIdentityHashSet();
|
||||
@ -578,13 +577,6 @@
|
||||
+ return entity;
|
||||
+ }
|
||||
+
|
||||
+ // CraftBukkit start - added EntityPlayer
|
||||
+ public ServerPlayer getPlayerForLogin(GameProfile gameProfile, ClientInformation clientInformation, ServerPlayer player) {
|
||||
+ player.updateOptions(clientInformation);
|
||||
+ return player;
|
||||
+ // CraftBukkit end
|
||||
+ }
|
||||
+
|
||||
+ public boolean disconnectAllPlayersWithProfile(GameProfile gameProfile, ServerPlayer player) { // CraftBukkit - added ServerPlayer
|
||||
+ // CraftBukkit start - Moved up
|
||||
+ // UUID id = gameProfile.getId();
|
||||
@ -619,7 +611,7 @@
|
||||
+ player.stopRiding(); // CraftBukkit
|
||||
this.players.remove(player);
|
||||
+ this.playersByName.remove(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot
|
||||
player.serverLevel().removePlayerImmediately(player, reason);
|
||||
player.level().removePlayerImmediately(player, reason);
|
||||
- TeleportTransition teleportTransition = player.findRespawnPositionAndUseSpawnBlock(!keepInventory, TeleportTransition.DO_NOTHING);
|
||||
- ServerLevel level = teleportTransition.newLevel();
|
||||
- ServerPlayer serverPlayer = new ServerPlayer(this.server, level, player.getGameProfile(), player.clientInformation());
|
||||
@ -686,7 +678,7 @@
|
||||
}
|
||||
|
||||
byte b = (byte)(keepInventory ? 1 : 0);
|
||||
ServerLevel serverLevel = serverPlayer.serverLevel();
|
||||
ServerLevel serverLevel = serverPlayer.level();
|
||||
LevelData levelData = serverLevel.getLevelData();
|
||||
serverPlayer.connection.send(new ClientboundRespawnPacket(serverPlayer.createCommonSpawnInfo(serverLevel), b));
|
||||
- serverPlayer.connection.teleport(serverPlayer.getX(), serverPlayer.getY(), serverPlayer.getZ(), serverPlayer.getYRot(), serverPlayer.getXRot());
|
||||
@ -697,7 +689,7 @@
|
||||
serverPlayer.connection.send(new ClientboundSetDefaultSpawnPositionPacket(level.getSharedSpawnPos(), level.getSharedSpawnAngle()));
|
||||
serverPlayer.connection.send(new ClientboundChangeDifficultyPacket(levelData.getDifficulty(), levelData.isDifficultyLocked()));
|
||||
serverPlayer.connection
|
||||
@@ -451,10 +_,13 @@
|
||||
@@ -454,10 +_,13 @@
|
||||
this.sendActivePlayerEffects(serverPlayer);
|
||||
this.sendLevelInfo(serverPlayer, level);
|
||||
this.sendPlayerPermissionLevel(serverPlayer);
|
||||
@ -715,7 +707,7 @@
|
||||
serverPlayer.setHealth(serverPlayer.getHealth());
|
||||
ServerPlayer.RespawnConfig respawnConfig = serverPlayer.getRespawnConfig();
|
||||
if (!keepInventory && respawnConfig != null) {
|
||||
@@ -477,8 +_,52 @@
|
||||
@@ -480,8 +_,52 @@
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -768,7 +760,7 @@
|
||||
|
||||
return serverPlayer;
|
||||
}
|
||||
@@ -488,24 +_,59 @@
|
||||
@@ -491,24 +_,59 @@
|
||||
}
|
||||
|
||||
public void sendActiveEffects(LivingEntity entity, ServerGamePacketListenerImpl connection) {
|
||||
@ -831,7 +823,7 @@
|
||||
public void broadcastAll(Packet<?> packet) {
|
||||
for (ServerPlayer serverPlayer : this.players) {
|
||||
serverPlayer.connection.send(packet);
|
||||
@@ -581,6 +_,12 @@
|
||||
@@ -584,6 +_,12 @@
|
||||
}
|
||||
|
||||
private void sendPlayerPermissionLevel(ServerPlayer player, int permLevel) {
|
||||
@ -844,7 +836,7 @@
|
||||
if (player.connection != null) {
|
||||
byte b;
|
||||
if (permLevel <= 0) {
|
||||
@@ -594,11 +_,33 @@
|
||||
@@ -597,11 +_,33 @@
|
||||
player.connection.send(new ClientboundEntityEventPacket(player, b));
|
||||
}
|
||||
|
||||
@ -879,7 +871,7 @@
|
||||
}
|
||||
|
||||
public boolean isOp(GameProfile profile) {
|
||||
@@ -609,21 +_,17 @@
|
||||
@@ -612,21 +_,17 @@
|
||||
|
||||
@Nullable
|
||||
public ServerPlayer getPlayerByName(String username) {
|
||||
@ -907,7 +899,7 @@
|
||||
if (serverPlayer != except && serverPlayer.level().dimension() == dimension) {
|
||||
double d = x - serverPlayer.getX();
|
||||
double d1 = y - serverPlayer.getY();
|
||||
@@ -636,9 +_,11 @@
|
||||
@@ -639,9 +_,11 @@
|
||||
}
|
||||
|
||||
public void saveAll() {
|
||||
@ -919,7 +911,7 @@
|
||||
}
|
||||
|
||||
public UserWhiteList getWhiteList() {
|
||||
@@ -661,14 +_,18 @@
|
||||
@@ -664,14 +_,18 @@
|
||||
}
|
||||
|
||||
public void sendLevelInfo(ServerPlayer player, ServerLevel level) {
|
||||
@ -942,7 +934,7 @@
|
||||
}
|
||||
|
||||
player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LEVEL_CHUNKS_LOAD_START, 0.0F));
|
||||
@@ -677,8 +_,21 @@
|
||||
@@ -680,8 +_,21 @@
|
||||
|
||||
public void sendAllPlayerInfo(ServerPlayer player) {
|
||||
player.inventoryMenu.sendAllDataToRemote();
|
||||
@ -957,15 +949,15 @@
|
||||
+ player.refreshEntityData(player); // CraftBukkit - SPIGOT-7218: sync metadata
|
||||
player.connection.send(new ClientboundSetHeldSlotPacket(player.getInventory().getSelectedSlot()));
|
||||
+ // CraftBukkit start - from GameRules
|
||||
+ int i = player.serverLevel().getGameRules().getBoolean(GameRules.RULE_REDUCEDDEBUGINFO) ? 22 : 23;
|
||||
+ int i = player.level().getGameRules().getBoolean(GameRules.RULE_REDUCEDDEBUGINFO) ? 22 : 23;
|
||||
+ player.connection.send(new ClientboundEntityEventPacket(player, (byte) i));
|
||||
+ float immediateRespawn = player.serverLevel().getGameRules().getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN) ? 1.0F: 0.0F;
|
||||
+ float immediateRespawn = player.level().getGameRules().getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN) ? 1.0F: 0.0F;
|
||||
+ player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.IMMEDIATE_RESPAWN, immediateRespawn));
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
public int getPlayerCount() {
|
||||
@@ -694,6 +_,7 @@
|
||||
@@ -697,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void setUsingWhiteList(boolean whitelistEnabled) {
|
||||
@ -973,7 +965,7 @@
|
||||
this.doWhiteList = whitelistEnabled;
|
||||
}
|
||||
|
||||
@@ -731,10 +_,35 @@
|
||||
@@ -734,10 +_,35 @@
|
||||
}
|
||||
|
||||
public void removeAll() {
|
||||
@ -1013,7 +1005,7 @@
|
||||
|
||||
public void broadcastSystemMessage(Component message, boolean bypassHiddenChat) {
|
||||
this.broadcastSystemMessage(message, serverPlayer -> message, bypassHiddenChat);
|
||||
@@ -756,20 +_,39 @@
|
||||
@@ -759,20 +_,39 @@
|
||||
}
|
||||
|
||||
public void broadcastChatMessage(PlayerChatMessage message, ServerPlayer sender, ChatType.Bound boundChatType) {
|
||||
@ -1056,7 +1048,7 @@
|
||||
flag1 |= flag2 && message.isFullyFiltered();
|
||||
}
|
||||
|
||||
@@ -782,14 +_,21 @@
|
||||
@@ -785,14 +_,21 @@
|
||||
return message.hasSignature() && !message.hasExpiredServer(Instant.now());
|
||||
}
|
||||
|
||||
@ -1082,7 +1074,7 @@
|
||||
Path path = file2.toPath();
|
||||
if (FileUtil.isPathNormalized(path) && FileUtil.isPathPortable(path) && path.startsWith(file.getPath()) && file2.isFile()) {
|
||||
file2.renameTo(file1);
|
||||
@@ -797,7 +_,7 @@
|
||||
@@ -800,7 +_,7 @@
|
||||
}
|
||||
|
||||
serverStatsCounter = new ServerStatsCounter(this.server, file1);
|
||||
@ -1091,7 +1083,7 @@
|
||||
}
|
||||
|
||||
return serverStatsCounter;
|
||||
@@ -805,11 +_,11 @@
|
||||
@@ -808,11 +_,11 @@
|
||||
|
||||
public PlayerAdvancements getPlayerAdvancements(ServerPlayer player) {
|
||||
UUID uuid = player.getUUID();
|
||||
@ -1105,7 +1097,7 @@
|
||||
}
|
||||
|
||||
playerAdvancements.setPlayer(player);
|
||||
@@ -852,11 +_,34 @@
|
||||
@@ -855,11 +_,34 @@
|
||||
}
|
||||
|
||||
public void reloadResources() {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/stats/ServerRecipeBook.java
|
||||
+++ b/net/minecraft/stats/ServerRecipeBook.java
|
||||
@@ -66,7 +_,7 @@
|
||||
@@ -63,7 +_,7 @@
|
||||
|
||||
for (RecipeHolder<?> recipeHolder : recipes) {
|
||||
ResourceKey<Recipe<?>> resourceKey = recipeHolder.id();
|
||||
@ -9,7 +9,7 @@
|
||||
this.add(resourceKey);
|
||||
this.addHighlight(resourceKey);
|
||||
this.displayResolver
|
||||
@@ -77,7 +_,7 @@
|
||||
@@ -74,7 +_,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
player.connection.send(new ClientboundRecipeBookAddPacket(list, false));
|
||||
}
|
||||
|
||||
@@ -95,7 +_,7 @@
|
||||
@@ -92,7 +_,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/stats/ServerStatsCounter.java
|
||||
+++ b/net/minecraft/stats/ServerStatsCounter.java
|
||||
@@ -70,9 +_,21 @@
|
||||
@@ -68,9 +_,21 @@
|
||||
LOGGER.error("Couldn't parse statistics file {}", file, var5);
|
||||
}
|
||||
}
|
||||
@ -22,7 +22,7 @@
|
||||
try {
|
||||
FileUtils.writeStringToFile(this.file, this.toJson());
|
||||
} catch (IOException var2) {
|
||||
@@ -82,6 +_,8 @@
|
||||
@@ -80,6 +_,8 @@
|
||||
|
||||
@Override
|
||||
public void setValue(Player player, Stat<?> stat, int i) {
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
--- a/net/minecraft/util/PlaceholderLookupProvider.java
|
||||
+++ b/net/minecraft/util/PlaceholderLookupProvider.java
|
||||
@@ -52,6 +_,13 @@
|
||||
)
|
||||
);
|
||||
}
|
||||
+
|
||||
+ // Paper start add method to get the value for pre-filling builders in the reg mod API
|
||||
+ @Override
|
||||
+ public HolderLookup.Provider lookupForValueCopyViaBuilders() {
|
||||
+ return PlaceholderLookupProvider.this.context;
|
||||
+ }
|
||||
+ // Paper end - add method to get the value for pre-filling builders in the reg mod API
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/util/datafix/DataFixers.java
|
||||
+++ b/net/minecraft/util/datafix/DataFixers.java
|
||||
@@ -541,6 +_,24 @@
|
||||
@@ -515,6 +_,24 @@
|
||||
Schema schema44 = builder.addSchema(1456, SAME_NAMESPACED);
|
||||
builder.addFixer(new EntityItemFrameDirectionFix(schema44, false));
|
||||
Schema schema45 = builder.addSchema(1458, V1458::new);
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
--- a/net/minecraft/util/datafix/fixes/RaidRenamesDataFix.java
|
||||
+++ b/net/minecraft/util/datafix/fixes/RaidRenamesDataFix.java
|
||||
@@ -39,6 +_,6 @@
|
||||
.renameField("PostRaidTicks", "post_raid_ticks")
|
||||
.renameField("TotalHealth", "total_health")
|
||||
.renameField("NumGroups", "group_count")
|
||||
- .renameField("Status", "status");
|
||||
+ .renameField("Status", "status").renameField("HeroesOfTheVillage", "heroes_of_the_village"); // Paper - Add missing rename
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/RandomizableContainer.java
|
||||
+++ b/net/minecraft/world/RandomizableContainer.java
|
||||
@@ -26,7 +_,7 @@
|
||||
@@ -27,7 +_,7 @@
|
||||
|
||||
void setLootTable(@Nullable ResourceKey<LootTable> lootTable);
|
||||
|
||||
@ -9,25 +9,25 @@
|
||||
this.setLootTable(lootTable);
|
||||
this.setLootTableSeed(seed);
|
||||
}
|
||||
@@ -49,8 +_,9 @@
|
||||
default boolean tryLoadLootTable(CompoundTag tag) {
|
||||
ResourceKey<LootTable> resourceKey = tag.read("LootTable", LootTable.KEY_CODEC).orElse(null);
|
||||
@@ -50,8 +_,9 @@
|
||||
default boolean tryLoadLootTable(ValueInput input) {
|
||||
ResourceKey<LootTable> resourceKey = input.read("LootTable", LootTable.KEY_CODEC).orElse(null);
|
||||
this.setLootTable(resourceKey);
|
||||
+ if (this.lootableData() != null && resourceKey != null) this.lootableData().loadNbt(tag); // Paper - LootTable API
|
||||
this.setLootTableSeed(tag.getLongOr("LootTableSeed", 0L));
|
||||
+ if (this.lootableData() != null && resourceKey != null) this.lootableData().loadNbt(input); // Paper - LootTable API
|
||||
this.setLootTableSeed(input.getLongOr("LootTableSeed", 0L));
|
||||
- return resourceKey != null;
|
||||
+ return resourceKey != null && this.lootableData() == null; // Paper - only track the loot table if there is chance for replenish
|
||||
}
|
||||
|
||||
default boolean trySaveLootTable(CompoundTag tag) {
|
||||
@@ -59,26 +_,42 @@
|
||||
default boolean trySaveLootTable(ValueOutput output) {
|
||||
@@ -60,26 +_,42 @@
|
||||
return false;
|
||||
} else {
|
||||
tag.store("LootTable", LootTable.KEY_CODEC, lootTable);
|
||||
+ if (this.lootableData() != null) this.lootableData().saveNbt(tag); // Paper - LootTable API
|
||||
output.store("LootTable", LootTable.KEY_CODEC, lootTable);
|
||||
+ if (this.lootableData() != null) this.lootableData().saveNbt(output); // Paper - LootTable API
|
||||
long lootTableSeed = this.getLootTableSeed();
|
||||
if (lootTableSeed != 0L) {
|
||||
tag.putLong("LootTableSeed", lootTableSeed);
|
||||
output.putLong("LootTableSeed", lootTableSeed);
|
||||
}
|
||||
|
||||
- return true;
|
||||
@ -65,7 +65,7 @@
|
||||
LootParams.Builder builder = new LootParams.Builder((ServerLevel)level).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(blockPos));
|
||||
if (player != null) {
|
||||
builder.withLuck(player.getLuck()).withParameter(LootContextParams.THIS_ENTITY, player);
|
||||
@@ -87,4 +_,17 @@
|
||||
@@ -88,4 +_,17 @@
|
||||
lootTable1.fill(this, builder.create(LootContextParamSets.CHEST), this.getLootTableSeed());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/AgeableMob.java
|
||||
+++ b/net/minecraft/world/entity/AgeableMob.java
|
||||
@@ -22,6 +_,7 @@
|
||||
@@ -23,6 +_,7 @@
|
||||
protected int age = 0;
|
||||
protected int forcedAge = 0;
|
||||
protected int forcedAgeTimer;
|
||||
@ -8,40 +8,31 @@
|
||||
|
||||
protected AgeableMob(EntityType<? extends AgeableMob> entityType, Level level) {
|
||||
super(entityType, level);
|
||||
@@ -68,13 +_,15 @@
|
||||
@@ -69,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void ageUp(int amount, boolean forced) {
|
||||
+ if (this.ageLocked) return; // Paper - Honor ageLock
|
||||
int age = this.getAge();
|
||||
+ int previousAge = age; // Paper - Decompile fix: lvt reassignment lost
|
||||
int previousAge = age;
|
||||
age += amount * 20;
|
||||
if (age > 0) {
|
||||
age = 0;
|
||||
}
|
||||
|
||||
- int i1 = age - age;
|
||||
+ int i1 = age - previousAge; // Paper - Decompile fix
|
||||
this.setAge(age);
|
||||
if (forced) {
|
||||
this.forcedAge += i1;
|
||||
@@ -106,6 +_,7 @@
|
||||
super.addAdditionalSaveData(compound);
|
||||
compound.putInt("Age", this.getAge());
|
||||
compound.putInt("ForcedAge", this.forcedAge);
|
||||
+ compound.putBoolean("AgeLocked", this.ageLocked); // CraftBukkit
|
||||
@@ -108,6 +_,7 @@
|
||||
super.addAdditionalSaveData(output);
|
||||
output.putInt("Age", this.getAge());
|
||||
output.putInt("ForcedAge", this.forcedAge);
|
||||
+ output.putBoolean("AgeLocked", this.ageLocked); // CraftBukkit
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -113,6 +_,7 @@
|
||||
super.readAdditionalSaveData(compound);
|
||||
this.setAge(compound.getIntOr("Age", 0));
|
||||
this.forcedAge = compound.getIntOr("ForcedAge", 0);
|
||||
+ this.ageLocked = compound.getBooleanOr("AgeLocked", false); // CraftBukkit
|
||||
@@ -115,6 +_,7 @@
|
||||
super.readAdditionalSaveData(input);
|
||||
this.setAge(input.getIntOr("Age", 0));
|
||||
this.forcedAge = input.getIntOr("ForcedAge", 0);
|
||||
+ this.ageLocked = input.getBooleanOr("AgeLocked", false); // CraftBukkit
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -127,7 +_,7 @@
|
||||
@@ -129,7 +_,7 @@
|
||||
@Override
|
||||
public void aiStep() {
|
||||
super.aiStep();
|
||||
|
||||
@ -1,24 +1,15 @@
|
||||
--- a/net/minecraft/world/entity/AreaEffectCloud.java
|
||||
+++ b/net/minecraft/world/entity/AreaEffectCloud.java
|
||||
@@ -59,7 +_,7 @@
|
||||
public float radiusOnUse = 0.0F;
|
||||
public float radiusPerTick = 0.0F;
|
||||
@Nullable
|
||||
- private LivingEntity owner;
|
||||
+ private net.minecraft.world.entity.LivingEntity owner;
|
||||
@Nullable
|
||||
public UUID ownerUUID;
|
||||
|
||||
@@ -193,7 +_,7 @@
|
||||
@@ -191,7 +_,7 @@
|
||||
|
||||
private void serverTick(ServerLevel level) {
|
||||
if (this.duration != -1 && this.tickCount >= this.waitTime + this.duration) {
|
||||
if (this.duration != -1 && this.tickCount - this.waitTime >= this.duration) {
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
} else {
|
||||
boolean isWaiting = this.isWaiting();
|
||||
boolean flag = this.tickCount < this.waitTime;
|
||||
@@ -206,7 +_,7 @@
|
||||
@@ -204,7 +_,7 @@
|
||||
if (this.radiusPerTick != 0.0F) {
|
||||
radius += this.radiusPerTick;
|
||||
if (radius < 0.5F) {
|
||||
@ -27,7 +18,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -222,6 +_,7 @@
|
||||
@@ -220,6 +_,7 @@
|
||||
this.potionContents.forEachEffect(list::add, this.potionDurationScale);
|
||||
List<LivingEntity> entitiesOfClass = this.level().getEntitiesOfClass(LivingEntity.class, this.getBoundingBox());
|
||||
if (!entitiesOfClass.isEmpty()) {
|
||||
@ -35,7 +26,7 @@
|
||||
for (LivingEntity livingEntity : entitiesOfClass) {
|
||||
if (!this.victims.containsKey(livingEntity)
|
||||
&& livingEntity.isAffectedByPotions()
|
||||
@@ -230,6 +_,17 @@
|
||||
@@ -228,6 +_,17 @@
|
||||
double d1 = livingEntity.getZ() - this.getZ();
|
||||
double d2 = d * d + d1 * d1;
|
||||
if (d2 <= radius * radius) {
|
||||
@ -53,7 +44,7 @@
|
||||
this.victims.put(livingEntity, this.tickCount + this.reapplicationDelay);
|
||||
|
||||
for (MobEffectInstance mobEffectInstance : list) {
|
||||
@@ -238,14 +_,14 @@
|
||||
@@ -236,14 +_,14 @@
|
||||
.value()
|
||||
.applyInstantenousEffect(level, this, this.getOwner(), livingEntity, mobEffectInstance.getAmplifier(), 0.5);
|
||||
} else {
|
||||
@ -70,7 +61,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -255,7 +_,7 @@
|
||||
@@ -253,7 +_,7 @@
|
||||
if (this.durationOnUse != 0 && this.duration != -1) {
|
||||
this.duration = this.duration + this.durationOnUse;
|
||||
if (this.duration <= 0) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/ConversionType.java
|
||||
+++ b/net/minecraft/world/entity/ConversionType.java
|
||||
@@ -21,7 +_,7 @@
|
||||
@@ -24,7 +_,7 @@
|
||||
|
||||
for (Entity entity : newMob.getPassengers()) {
|
||||
entity.stopRiding();
|
||||
@ -9,7 +9,7 @@
|
||||
}
|
||||
|
||||
firstPassenger.startRiding(newMob);
|
||||
@@ -70,6 +_,7 @@
|
||||
@@ -73,6 +_,7 @@
|
||||
if (leashHolder != null) {
|
||||
oldMob.dropLeash();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
||||
+++ b/net/minecraft/world/entity/EntitySelector.java
|
||||
@@ -17,6 +_,22 @@
|
||||
public static final Predicate<Entity> NO_SPECTATORS = entity -> !entity.isSpectator();
|
||||
public static final Predicate<Entity> CAN_BE_COLLIDED_WITH = NO_SPECTATORS.and(Entity::canBeCollidedWith);
|
||||
public static final Predicate<Entity> CAN_BE_COLLIDED_WITH = NO_SPECTATORS.and(entity -> entity.canBeCollidedWith(null));
|
||||
public static final Predicate<Entity> CAN_BE_PICKED = NO_SPECTATORS.and(Entity::isPickable);
|
||||
+ // Paper start - Ability to control player's insomnia and phantoms
|
||||
+ public static Predicate<Player> IS_INSOMNIAC = (player) -> {
|
||||
@ -38,12 +38,13 @@
|
||||
return (Predicate<Entity>)(collisionRule == Team.CollisionRule.NEVER
|
||||
? Predicates.alwaysFalse()
|
||||
: NO_SPECTATORS.and(
|
||||
pushedEntity -> {
|
||||
- if (!pushedEntity.isPushable()) {
|
||||
- entity1 -> {
|
||||
- if (!entity1.isPushable()) {
|
||||
+ entity1 -> { final Entity pushedEntity = entity1; // Paper - OBFHELPER
|
||||
+ if (!pushedEntity.isCollidable(ignoreClimbing) || !pushedEntity.canCollideWithBukkit(entity) || !entity.canCollideWithBukkit(pushedEntity)) { // CraftBukkit - collidable API // Paper - Climbing should not bypass cramming gamerule
|
||||
return false;
|
||||
} else if (!entity.level().isClientSide || pushedEntity instanceof Player player && player.isLocalPlayer()) {
|
||||
Team team1 = pushedEntity.getTeam();
|
||||
} else if (!entity.level().isClientSide || entity1 instanceof Player player && player.isLocalPlayer()) {
|
||||
Team team1 = entity1.getTeam();
|
||||
Team.CollisionRule collisionRule1 = team1 == null ? Team.CollisionRule.ALWAYS : team1.getCollisionRule();
|
||||
- if (collisionRule1 == Team.CollisionRule.NEVER) {
|
||||
+ if (collisionRule1 == Team.CollisionRule.NEVER || (pushedEntity instanceof Player && !io.papermc.paper.configuration.GlobalConfiguration.get().collisions.enablePlayerCollisions)) { // Paper - Configurable player collision
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/EntityType.java
|
||||
+++ b/net/minecraft/world/entity/EntityType.java
|
||||
@@ -216,7 +_,7 @@
|
||||
@@ -217,7 +_,7 @@
|
||||
.fireImmune()
|
||||
.sized(6.0F, 0.5F)
|
||||
.clientTrackingRange(10)
|
||||
@ -9,7 +9,7 @@
|
||||
);
|
||||
public static final EntityType<Armadillo> ARMADILLO = register(
|
||||
"armadillo", EntityType.Builder.of(Armadillo::new, MobCategory.CREATURE).sized(0.7F, 0.65F).eyeHeight(0.26F).clientTrackingRange(10)
|
||||
@@ -1145,6 +_,22 @@
|
||||
@@ -1155,6 +_,22 @@
|
||||
boolean shouldOffsetY,
|
||||
boolean shouldOffsetYMore
|
||||
) {
|
||||
@ -32,7 +32,7 @@
|
||||
Consumer<T> consumer;
|
||||
if (spawnedFrom != null) {
|
||||
consumer = createDefaultStackConfig(level, spawnedFrom, owner);
|
||||
@@ -1152,7 +_,7 @@
|
||||
@@ -1162,7 +_,7 @@
|
||||
consumer = entity -> {};
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
}
|
||||
|
||||
public static <T extends Entity> Consumer<T> createDefaultStackConfig(Level level, ItemStack stack, @Nullable LivingEntity owner) {
|
||||
@@ -1169,19 +_,56 @@
|
||||
@@ -1179,19 +_,56 @@
|
||||
|
||||
public static <T extends Entity> Consumer<T> appendCustomEntityStackConfig(Consumer<T> consumer, Level level, ItemStack stack, @Nullable LivingEntity owner) {
|
||||
CustomData customData = stack.getOrDefault(DataComponents.ENTITY_DATA, CustomData.EMPTY);
|
||||
@ -101,7 +101,7 @@
|
||||
if (entity instanceof Mob mob) {
|
||||
mob.playAmbientSound();
|
||||
}
|
||||
@@ -1237,6 +_,15 @@
|
||||
@@ -1247,6 +_,15 @@
|
||||
if (level.isClientSide
|
||||
|| !entity.getType().onlyOpCanSetNbt()
|
||||
|| owner instanceof Player player && server.getPlayerList().isOp(player.getGameProfile())) {
|
||||
@ -117,25 +117,25 @@
|
||||
customData.loadInto(entity);
|
||||
}
|
||||
}
|
||||
@@ -1308,9 +_,20 @@
|
||||
@@ -1318,9 +_,20 @@
|
||||
}
|
||||
|
||||
public static Optional<Entity> create(CompoundTag tag, Level level, EntitySpawnReason spawnReason) {
|
||||
public static Optional<Entity> create(ValueInput input, Level level, EntitySpawnReason spawnReason) {
|
||||
+ // Paper start - Don't fire sync event during generation
|
||||
+ return create(tag, level, spawnReason, false);
|
||||
+ return create(input, level, spawnReason, false);
|
||||
+ }
|
||||
+
|
||||
+ public static Optional<Entity> create(CompoundTag tag, Level level, EntitySpawnReason spawnReason, boolean generation) {
|
||||
+ public static Optional<Entity> create(ValueInput input, Level level, EntitySpawnReason spawnReason, boolean generation) {
|
||||
+ // Paper end - Don't fire sync event during generation
|
||||
return Util.ifElse(
|
||||
by(tag).map(entityType -> entityType.create(level, spawnReason)),
|
||||
- entity -> entity.load(tag),
|
||||
+ // Paper start - Don't fire sync event during generation
|
||||
+ entity -> {
|
||||
+ if (generation) entity.generation = true; // Paper - Don't fire sync event during generation
|
||||
+ entity.load(tag);
|
||||
+ },
|
||||
+ // Paper end - Don't fire sync event during generation
|
||||
() -> LOGGER.warn("Skipping Entity with id {}", tag.getStringOr("id", "[invalid]"))
|
||||
by(input).map(entityType -> entityType.create(level, spawnReason)),
|
||||
- entity -> entity.load(input),
|
||||
+ // Paper start - Don't fire sync event during generation
|
||||
+ entity -> {
|
||||
+ if (generation) entity.generation = true; // Paper - Don't fire sync event during generation
|
||||
+ entity.load(input);
|
||||
+ },
|
||||
+ // Paper end - Don't fire sync event during generation
|
||||
() -> LOGGER.warn("Skipping Entity with id {}", input.getStringOr("id", "[invalid]"))
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,62 +1,67 @@
|
||||
--- a/net/minecraft/world/entity/ExperienceOrb.java
|
||||
+++ b/net/minecraft/world/entity/ExperienceOrb.java
|
||||
@@ -41,9 +_,54 @@
|
||||
@@ -44,13 +_,59 @@
|
||||
@Nullable
|
||||
private Player followingPlayer;
|
||||
private final InterpolationHandler interpolation = new InterpolationHandler(this);
|
||||
-
|
||||
+ // Paper start
|
||||
+ @Nullable
|
||||
+ public java.util.UUID sourceEntityId;
|
||||
+ @Nullable
|
||||
+ public java.util.UUID triggerEntityId;
|
||||
+ public org.bukkit.entity.ExperienceOrb.SpawnReason spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN;
|
||||
+
|
||||
+ private void loadPaperNBT(CompoundTag tag) {
|
||||
+ CompoundTag expData = tag.getCompoundOrEmpty("Paper.ExpData");
|
||||
+ if (expData.isEmpty()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ this.sourceEntityId = expData.read("source", net.minecraft.core.UUIDUtil.CODEC).orElse(null);
|
||||
+ this.triggerEntityId = expData.read("trigger", net.minecraft.core.UUIDUtil.CODEC).orElse(null);
|
||||
+ expData.getString("reason").ifPresent(reason -> {
|
||||
+ try {
|
||||
+ this.spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.valueOf(reason);
|
||||
+ } catch (Exception e) {
|
||||
+ this.level().getCraftServer().getLogger().warning("Invalid spawnReason set for experience orb: " + e.getMessage() + " - " + reason);
|
||||
+ }
|
||||
|
||||
+ private void loadPaperNBT(ValueInput input) {
|
||||
+ input.read("Paper.ExpData", net.minecraft.nbt.CompoundTag.CODEC).ifPresent(expData -> {
|
||||
+ this.sourceEntityId = expData.read("source", net.minecraft.core.UUIDUtil.CODEC).orElse(null);
|
||||
+ this.triggerEntityId = expData.read("trigger", net.minecraft.core.UUIDUtil.CODEC).orElse(null);
|
||||
+ expData.getString("reason").ifPresent(reason -> {
|
||||
+ try {
|
||||
+ this.spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.valueOf(reason);
|
||||
+ } catch (Exception e) {
|
||||
+ this.level().getCraftServer().getLogger().warning("Invalid spawnReason set for experience orb: " + e.getMessage() + " - " + reason);
|
||||
+ }
|
||||
+ });
|
||||
+ });
|
||||
+ }
|
||||
+ private void savePaperNBT(CompoundTag tag) {
|
||||
+ CompoundTag expData = new CompoundTag();
|
||||
+ private void savePaperNBT(ValueOutput output) {
|
||||
+ net.minecraft.nbt.CompoundTag expData = new net.minecraft.nbt.CompoundTag();
|
||||
+ expData.storeNullable("source", net.minecraft.core.UUIDUtil.CODEC, this.sourceEntityId);
|
||||
+ expData.storeNullable("trigger", net.minecraft.core.UUIDUtil.CODEC, this.triggerEntityId);
|
||||
+ if (this.spawnReason != org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN) {
|
||||
+ expData.putString("reason", this.spawnReason.name());
|
||||
+ }
|
||||
+ tag.put("Paper.ExpData", expData);
|
||||
+ output.store("Paper.ExpData", net.minecraft.nbt.CompoundTag.CODEC, expData);
|
||||
+ }
|
||||
+
|
||||
+ @Deprecated @io.papermc.paper.annotation.DoNotUse
|
||||
+ // Paper end
|
||||
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - overload ctor
|
||||
public ExperienceOrb(Level level, double x, double y, double z, int value) {
|
||||
+ this(level, x, y, z, value, null, null);
|
||||
- this(level, new Vec3(x, y, z), Vec3.ZERO, value);
|
||||
+ // Paper start - add reasons for orbs
|
||||
+ this(level, x, y, z, value, null, null, null);
|
||||
+ }
|
||||
+
|
||||
+ public ExperienceOrb(Level level, double x, double y, double z, int value, @Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @Nullable Entity triggerId) {
|
||||
+ this(level, x, y, z, value, reason, triggerId, null);
|
||||
+ }
|
||||
+
|
||||
+ public ExperienceOrb(Level level, double x, double y, double z, int value, @Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @Nullable Entity triggerId, @Nullable Entity sourceId) {
|
||||
+ this(level, new Vec3(x, y, z), Vec3.ZERO, value, reason, triggerId, sourceId);
|
||||
+ // Paper end - add reasons for orbs
|
||||
}
|
||||
|
||||
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - overload ctor
|
||||
public ExperienceOrb(Level level, Vec3 pos, Vec3 direction, int value) {
|
||||
+ // Paper start - add reasons for orbs
|
||||
+ this(level, pos, direction, value, null, null, null);
|
||||
+ }
|
||||
+ public ExperienceOrb(Level level, Vec3 pos, Vec3 direction, int value, @Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @Nullable Entity triggerId, @Nullable Entity sourceId) {
|
||||
+ // Paper end - add reasons for orbs
|
||||
this(EntityType.EXPERIENCE_ORB, level);
|
||||
+ // Paper start - add reasons for orbs
|
||||
+ this.sourceEntityId = sourceId != null ? sourceId.getUUID() : null;
|
||||
+ this.triggerEntityId = triggerId != null ? triggerId.getUUID() : null;
|
||||
+ this.spawnReason = reason != null ? reason : org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN;
|
||||
+ // Paper end
|
||||
this.setPos(x, y, z);
|
||||
if (!this.level().isClientSide) {
|
||||
this.setYRot((float)(this.random.nextDouble() * 360.0));
|
||||
@@ -119,12 +_,13 @@
|
||||
+ // Paper end - add reasons for orbs
|
||||
this.setPos(pos);
|
||||
if (!level.isClientSide) {
|
||||
this.setYRot(this.random.nextFloat() * 360.0F);
|
||||
@@ -147,12 +_,13 @@
|
||||
|
||||
this.age++;
|
||||
if (this.age >= 6000) {
|
||||
@ -71,7 +76,7 @@
|
||||
if (this.followingPlayer == null || this.followingPlayer.isSpectator() || this.followingPlayer.distanceToSqr(this) > 64.0) {
|
||||
Player nearestPlayer = this.level().getNearestPlayer(this, 8.0);
|
||||
if (nearestPlayer != null && !nearestPlayer.isSpectator() && !nearestPlayer.isDeadOrDying()) {
|
||||
@@ -134,7 +_,24 @@
|
||||
@@ -162,7 +_,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,26 +102,21 @@
|
||||
Vec3 vec3 = new Vec3(
|
||||
this.followingPlayer.getX() - this.getX(),
|
||||
this.followingPlayer.getY() + this.followingPlayer.getEyeHeight() / 2.0 - this.getY(),
|
||||
@@ -161,18 +_,29 @@
|
||||
@@ -193,18 +_,24 @@
|
||||
}
|
||||
|
||||
public static void award(ServerLevel level, Vec3 pos, int amount) {
|
||||
+ // Paper start - add reasons for orbs
|
||||
+ award(level, pos, amount, null, null, null);
|
||||
public static void awardWithDirection(ServerLevel level, Vec3 pos, Vec3 direction, int amount) {
|
||||
+ // Paper start - add reason to orbs
|
||||
+ awardWithDirection(level, pos, direction, amount, null, null, null);
|
||||
+ }
|
||||
+
|
||||
+ public static void award(ServerLevel level, Vec3 pos, int amount, @Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @Nullable Entity triggerId) {
|
||||
+ award(level, pos, amount, reason, triggerId, null);
|
||||
+ }
|
||||
+
|
||||
+ public static void award(ServerLevel level, Vec3 pos, int amount, @Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @Nullable Entity triggerId, @Nullable Entity sourceId) {
|
||||
+ // Paper end - add reasons for orbs
|
||||
+ public static void awardWithDirection(ServerLevel level, Vec3 pos, Vec3 direction, int amount, @Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @Nullable Entity triggerId, @Nullable Entity sourceId) {
|
||||
+ // Paper end - add reason to orbs
|
||||
while (amount > 0) {
|
||||
int experienceValue = getExperienceValue(amount);
|
||||
amount -= experienceValue;
|
||||
if (!tryMergeToExisting(level, pos, experienceValue)) {
|
||||
- level.addFreshEntity(new ExperienceOrb(level, pos.x(), pos.y(), pos.z(), experienceValue));
|
||||
+ level.addFreshEntity(new ExperienceOrb(level, pos.x(), pos.y(), pos.z(), experienceValue, reason, triggerId, sourceId)); // Paper - add reason
|
||||
- level.addFreshEntity(new ExperienceOrb(level, pos, direction, experienceValue));
|
||||
+ level.addFreshEntity(new ExperienceOrb(level, pos, direction, experienceValue, reason, triggerId, sourceId)); // Paper - add reason to orbs
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -126,10 +126,10 @@
|
||||
AABB aabb = AABB.ofSize(pos, 1.0, 1.0, 1.0);
|
||||
- int randomInt = level.getRandom().nextInt(40);
|
||||
+ int randomInt = level.getRandom().nextInt(io.papermc.paper.configuration.GlobalConfiguration.get().misc.xpOrbGroupsPerArea.or(ORB_GROUPS_PER_AREA)); // Paper - Configure how many orb groups per area
|
||||
List<ExperienceOrb> entities = level.getEntities(EntityTypeTest.forClass(ExperienceOrb.class), aabb, orb -> canMerge(orb, randomInt, amount));
|
||||
if (!entities.isEmpty()) {
|
||||
ExperienceOrb experienceOrb = entities.get(0);
|
||||
@@ -189,13 +_,18 @@
|
||||
List<ExperienceOrb> entities = level.getEntities(
|
||||
EntityTypeTest.forClass(ExperienceOrb.class), aabb, experienceOrb1 -> canMerge(experienceOrb1, randomInt, amount)
|
||||
);
|
||||
@@ -223,13 +_,18 @@
|
||||
}
|
||||
|
||||
private static boolean canMerge(ExperienceOrb orb, int amount, int other) {
|
||||
@ -150,7 +150,7 @@
|
||||
}
|
||||
|
||||
private void setUnderwaterMovement() {
|
||||
@@ -220,7 +_,7 @@
|
||||
@@ -254,7 +_,7 @@
|
||||
this.markHurt();
|
||||
this.health = (int)(this.health - amount);
|
||||
if (this.health <= 0) {
|
||||
@ -159,24 +159,24 @@
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -231,32 +_,34 @@
|
||||
public void addAdditionalSaveData(CompoundTag compound) {
|
||||
compound.putShort("Health", (short)this.health);
|
||||
compound.putShort("Age", (short)this.age);
|
||||
- compound.putShort("Value", (short)this.getValue());
|
||||
+ compound.putInt("Value", this.getValue()); // Paper - save as Integer
|
||||
compound.putInt("Count", this.count);
|
||||
+ this.savePaperNBT(compound); // Paper
|
||||
@@ -265,32 +_,34 @@
|
||||
protected void addAdditionalSaveData(ValueOutput output) {
|
||||
output.putShort("Health", (short)this.health);
|
||||
output.putShort("Age", (short)this.age);
|
||||
- output.putShort("Value", (short)this.getValue());
|
||||
+ output.putInt("Value", this.getValue()); // Paper - save as Integer
|
||||
output.putInt("Count", this.count);
|
||||
+ this.savePaperNBT(output); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readAdditionalSaveData(CompoundTag compound) {
|
||||
this.health = compound.getShortOr("Health", (short)5);
|
||||
this.age = compound.getShortOr("Age", (short)0);
|
||||
- this.setValue(compound.getShortOr("Value", (short)0));
|
||||
+ this.setValue(compound.getIntOr("Value", 0)); // Paper - load as Integer
|
||||
this.count = compound.read("Count", ExtraCodecs.POSITIVE_INT).orElse(1);
|
||||
+ this.loadPaperNBT(compound); // Paper
|
||||
protected void readAdditionalSaveData(ValueInput input) {
|
||||
this.health = input.getShortOr("Health", (short)5);
|
||||
this.age = input.getShortOr("Age", (short)0);
|
||||
- this.setValue(input.getShortOr("Value", (short)0));
|
||||
+ this.setValue(input.getIntOr("Value", 0)); // Paper - load as Integer
|
||||
this.count = input.read("Count", ExtraCodecs.POSITIVE_INT).orElse(1);
|
||||
+ this.loadPaperNBT(input); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -200,9 +200,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -270,9 +_,19 @@
|
||||
@@ -304,9 +_,19 @@
|
||||
ItemStack itemStack = randomItemWith.get().itemStack();
|
||||
int i = EnchantmentHelper.modifyDurabilityToRepairFromXp(player.serverLevel(), itemStack, value);
|
||||
int i = EnchantmentHelper.modifyDurabilityToRepairFromXp(player.level(), itemStack, value);
|
||||
int min = Math.min(i, itemStack.getDamageValue());
|
||||
+ // CraftBukkit start
|
||||
+ // Paper start - mending event
|
||||
@ -221,7 +221,7 @@
|
||||
if (i1 > 0) {
|
||||
return this.repairPlayerItems(player, i1);
|
||||
}
|
||||
@@ -318,6 +_,24 @@
|
||||
@@ -352,6 +_,24 @@
|
||||
}
|
||||
|
||||
public static int getExperienceValue(int expValue) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/Interaction.java
|
||||
+++ b/net/minecraft/world/entity/Interaction.java
|
||||
@@ -100,9 +_,16 @@
|
||||
@@ -101,9 +_,16 @@
|
||||
@Override
|
||||
public boolean skipAttackInteraction(Entity entity) {
|
||||
if (entity instanceof Player player) {
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
--- a/net/minecraft/world/entity/Leashable.java
|
||||
+++ b/net/minecraft/world/entity/Leashable.java
|
||||
@@ -56,6 +_,11 @@
|
||||
@@ -80,6 +_,11 @@
|
||||
}
|
||||
|
||||
default void writeLeashData(CompoundTag tag, @Nullable Leashable.LeashData leashData) {
|
||||
default void writeLeashData(ValueOutput output, @Nullable Leashable.LeashData leashData) {
|
||||
+ // CraftBukkit start - SPIGOT-7487: Don't save (and possible drop) leash, when the holder was removed by a plugin
|
||||
+ if (leashData != null && leashData.leashHolder != null && leashData.leashHolder.pluginRemoved) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
tag.storeNullable("leash", Leashable.LeashData.CODEC, leashData);
|
||||
output.storeNullable("leash", Leashable.LeashData.CODEC, leashData);
|
||||
}
|
||||
|
||||
@@ -75,7 +_,9 @@
|
||||
@@ -99,7 +_,9 @@
|
||||
}
|
||||
|
||||
if (entity.tickCount > 100) {
|
||||
@ -22,7 +22,7 @@
|
||||
entity.setLeashData(null);
|
||||
}
|
||||
}
|
||||
@@ -99,7 +_,9 @@
|
||||
@@ -123,7 +_,9 @@
|
||||
entity.onLeashRemoved();
|
||||
if (entity.level() instanceof ServerLevel serverLevel) {
|
||||
if (dropItem) {
|
||||
@ -32,7 +32,7 @@
|
||||
}
|
||||
|
||||
if (broadcastPacket) {
|
||||
@@ -117,7 +_,15 @@
|
||||
@@ -143,7 +_,15 @@
|
||||
|
||||
if (leashData != null && leashData.leashHolder != null) {
|
||||
if (!entity.isAlive() || !leashData.leashHolder.isAlive()) {
|
||||
@ -49,16 +49,29 @@
|
||||
entity.dropLeash();
|
||||
} else {
|
||||
entity.removeLeash();
|
||||
@@ -131,7 +_,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
- if (f > 10.0) {
|
||||
+ if (f > entity.level().paperConfig().misc.maxLeashDistance.or(LEASH_TOO_FAR_DIST)) { // Paper - Configurable max leash distance
|
||||
@@ -154,7 +_,7 @@
|
||||
if (leashHolder != null && leashHolder.level() == entity.level()) {
|
||||
double d = entity.leashDistanceTo(leashHolder);
|
||||
entity.whenLeashedTo(leashHolder);
|
||||
- if (d > entity.leashSnapDistance()) {
|
||||
+ if (d > entity.leashSnapDistanceOrConfig()) { // Paper - Configurable max leash distance
|
||||
level.playSound(null, leashHolder.getX(), leashHolder.getY(), leashHolder.getZ(), SoundEvents.LEAD_BREAK, SoundSource.NEUTRAL, 1.0F, 1.0F);
|
||||
entity.leashTooFarBehaviour();
|
||||
} else if (f > 6.0) {
|
||||
entity.elasticRangeLeashBehaviour(leashHolder, f);
|
||||
@@ -148,7 +_,21 @@
|
||||
} else if (d > entity.leashElasticDistance() - leashHolder.getBbWidth() - entity.getBbWidth()
|
||||
@@ -175,6 +_,12 @@
|
||||
entity.checkFallDistanceAccumulation();
|
||||
}
|
||||
|
||||
+ // Paper start - Configurable max leash distance
|
||||
+ default double leashSnapDistanceOrConfig() {
|
||||
+ if (!(this instanceof final Entity entity)) return leashSnapDistance();
|
||||
+ return entity.level().paperConfig().misc.maxLeashDistance.or(leashSnapDistance());
|
||||
+ }
|
||||
+ // Paper end - Configurable max leash distance
|
||||
default double leashSnapDistance() {
|
||||
return 12.0;
|
||||
}
|
||||
@@ -196,7 +_,21 @@
|
||||
}
|
||||
|
||||
default void leashTooFarBehaviour() {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/LightningBolt.java
|
||||
+++ b/net/minecraft/world/entity/LightningBolt.java
|
||||
@@ -39,6 +_,7 @@
|
||||
@@ -40,6 +_,7 @@
|
||||
private ServerPlayer cause;
|
||||
private final Set<Entity> hitEntities = Sets.newHashSet();
|
||||
private int blocksSetOnFire;
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
public LightningBolt(EntityType<? extends LightningBolt> entityType, Level level) {
|
||||
super(entityType, level);
|
||||
@@ -76,7 +_,7 @@
|
||||
@@ -77,7 +_,7 @@
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
@ -17,7 +17,7 @@
|
||||
if (this.level().isClientSide()) {
|
||||
this.level()
|
||||
.playLocalSound(
|
||||
@@ -107,7 +_,7 @@
|
||||
@@ -108,7 +_,7 @@
|
||||
}
|
||||
|
||||
this.powerLightningRod();
|
||||
@ -26,7 +26,7 @@
|
||||
this.gameEvent(GameEvent.LIGHTNING_STRIKE);
|
||||
}
|
||||
}
|
||||
@@ -130,7 +_,7 @@
|
||||
@@ -131,7 +_,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@
|
||||
} else if (this.life < -this.random.nextInt(10)) {
|
||||
this.flashes--;
|
||||
this.life = 1;
|
||||
@@ -139,10 +_,10 @@
|
||||
@@ -140,10 +_,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@
|
||||
List<Entity> entities = this.level()
|
||||
.getEntities(
|
||||
this,
|
||||
@@ -168,26 +_,34 @@
|
||||
@@ -169,26 +_,34 @@
|
||||
}
|
||||
|
||||
private void spawnFire(int extraIgnitions) {
|
||||
@ -89,7 +89,7 @@
|
||||
BlockState blockState = level.getBlockState(pos);
|
||||
BlockPos blockPos;
|
||||
BlockState blockState1;
|
||||
@@ -200,22 +_,27 @@
|
||||
@@ -201,22 +_,27 @@
|
||||
}
|
||||
|
||||
if (blockState1.getBlock() instanceof WeatheringCopper) {
|
||||
@ -121,7 +121,7 @@
|
||||
if (optional.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
@@ -224,11 +_,17 @@
|
||||
@@ -225,11 +_,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -135,6 +_,17 @@
|
||||
@@ -138,6 +_,17 @@
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@ -15,13 +15,13 @@
|
||||
+import org.bukkit.event.entity.EntityResurrectEvent;
|
||||
+// CraftBukkit end
|
||||
+
|
||||
public abstract class LivingEntity extends Entity implements Attackable {
|
||||
public abstract class LivingEntity extends Entity implements Attackable, WaypointTransmitter {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final String TAG_ACTIVE_EFFECTS = "active_effects";
|
||||
@@ -251,11 +_,25 @@
|
||||
EquipmentSlot.class
|
||||
@@ -264,11 +_,25 @@
|
||||
);
|
||||
protected final EntityEquipment equipment;
|
||||
private Waypoint.Icon locatorBarIcon = new Waypoint.Icon();
|
||||
+ // CraftBukkit start
|
||||
+ public int expToDrop;
|
||||
+ public List<DefaultDrop> drops = new java.util.ArrayList<>(); // Paper - Restore vanilla drops behavior
|
||||
@ -45,7 +45,7 @@
|
||||
this.equipment = this.createEquipment();
|
||||
this.blocksBuilding = true;
|
||||
this.reapplyPosition();
|
||||
@@ -350,7 +_,13 @@
|
||||
@@ -364,7 +_,13 @@
|
||||
|
||||
double d1 = Math.min(0.2F + d / 15.0, 2.5);
|
||||
int i = (int)(150.0 * d1);
|
||||
@ -60,7 +60,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -535,7 +_,7 @@
|
||||
@@ -549,7 +_,7 @@
|
||||
this.deathTime++;
|
||||
if (this.deathTime >= 20 && !this.level().isClientSide() && !this.isRemoved()) {
|
||||
this.level().broadcastEntityEvent(this, (byte)60);
|
||||
@ -69,7 +69,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -640,7 +_,7 @@
|
||||
@@ -654,7 +_,7 @@
|
||||
}
|
||||
|
||||
public boolean shouldDiscardFriction() {
|
||||
@ -78,7 +78,7 @@
|
||||
}
|
||||
|
||||
public void setDiscardFriction(boolean discardFriction) {
|
||||
@@ -652,10 +_,15 @@
|
||||
@@ -666,10 +_,15 @@
|
||||
}
|
||||
|
||||
public void onEquipItem(EquipmentSlot slot, ItemStack oldItem, ItemStack newItem) {
|
||||
@ -95,7 +95,7 @@
|
||||
this.level()
|
||||
.playSeededSound(
|
||||
null,
|
||||
@@ -682,12 +_,12 @@
|
||||
@@ -696,12 +_,12 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -110,7 +110,7 @@
|
||||
this.brain.clearMemories();
|
||||
}
|
||||
|
||||
@@ -696,11 +_,17 @@
|
||||
@@ -718,11 +_,17 @@
|
||||
mobEffectInstance.onMobRemoved(level, this, removalReason);
|
||||
}
|
||||
|
||||
@ -119,16 +119,16 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAdditionalSaveData(CompoundTag compound) {
|
||||
protected void addAdditionalSaveData(ValueOutput output) {
|
||||
+ // Paper start - Friction API
|
||||
+ if (this.frictionState != net.kyori.adventure.util.TriState.NOT_SET) {
|
||||
+ compound.putString("Paper.FrictionState", this.frictionState.toString());
|
||||
+ output.putString("Paper.FrictionState", this.frictionState.toString());
|
||||
+ }
|
||||
+ // Paper end - Friction API
|
||||
compound.putFloat("Health", this.getHealth());
|
||||
compound.putShort("HurtTime", (short)this.hurtTime);
|
||||
compound.putInt("HurtByTimestamp", this.lastHurtByMobTimestamp);
|
||||
@@ -731,8 +_,15 @@
|
||||
output.putFloat("Health", this.getHealth());
|
||||
output.putShort("HurtTime", (short)this.hurtTime);
|
||||
output.putInt("HurtByTimestamp", this.lastHurtByMobTimestamp);
|
||||
@@ -756,8 +_,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,7 +146,7 @@
|
||||
if (stack.isEmpty()) {
|
||||
return null;
|
||||
} else if (this.level().isClientSide) {
|
||||
@@ -741,6 +_,31 @@
|
||||
@@ -766,6 +_,31 @@
|
||||
} else {
|
||||
ItemEntity itemEntity = this.createItemStackToDrop(stack, randomizeMotion, includeThrower);
|
||||
if (itemEntity != null) {
|
||||
@ -178,20 +178,20 @@
|
||||
this.level().addFreshEntity(itemEntity);
|
||||
}
|
||||
|
||||
@@ -750,7 +_,22 @@
|
||||
@@ -775,7 +_,22 @@
|
||||
|
||||
@Override
|
||||
public void readAdditionalSaveData(CompoundTag compound) {
|
||||
- this.internalSetAbsorptionAmount(compound.getFloatOr("AbsorptionAmount", 0.0F));
|
||||
protected void readAdditionalSaveData(ValueInput input) {
|
||||
- this.internalSetAbsorptionAmount(input.getFloatOr("AbsorptionAmount", 0.0F));
|
||||
+ // Paper start - Check for NaN
|
||||
+ float absorptionAmount = compound.getFloatOr("AbsorptionAmount", 0.0F);
|
||||
+ float absorptionAmount = input.getFloatOr("AbsorptionAmount", 0.0F);
|
||||
+ if (Float.isNaN(absorptionAmount)) {
|
||||
+ absorptionAmount = 0;
|
||||
+ }
|
||||
+ this.internalSetAbsorptionAmount(absorptionAmount);
|
||||
+ // Paper end - Check for NaN
|
||||
+ // Paper start - Friction API
|
||||
+ compound.getString("Paper.FrictionState").ifPresent(frictionState -> {
|
||||
+ input.getString("Paper.FrictionState").ifPresent(frictionState -> {
|
||||
+ try {
|
||||
+ this.frictionState = net.kyori.adventure.util.TriState.valueOf(frictionState);
|
||||
+ } catch (Exception ignored) {
|
||||
@ -200,32 +200,32 @@
|
||||
+ });
|
||||
+ // Paper end - Friction API
|
||||
if (this.level() != null && !this.level().isClientSide) {
|
||||
compound.getList("attributes").ifPresent(this.getAttributes()::load);
|
||||
input.read("attributes", AttributeInstance.Packed.LIST_CODEC).ifPresent(this.getAttributes()::apply);
|
||||
}
|
||||
@@ -763,6 +_,11 @@
|
||||
@@ -787,6 +_,11 @@
|
||||
this.activeEffects.put(mobEffectInstance.getEffect(), mobEffectInstance);
|
||||
}
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ compound.getDouble("Bukkit.MaxHealth").ifPresent(maxHealth -> {
|
||||
+ input.read("Bukkit.MaxHealth", com.mojang.serialization.Codec.DOUBLE).ifPresent(maxHealth -> {
|
||||
+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(maxHealth);
|
||||
+ });
|
||||
+ // CraftBukkit end
|
||||
this.setHealth(compound.getFloatOr("Health", this.getMaxHealth()));
|
||||
this.hurtTime = compound.getShortOr("HurtTime", (short)0);
|
||||
this.deathTime = compound.getShortOr("DeathTime", (short)0);
|
||||
@@ -770,6 +_,7 @@
|
||||
compound.getString("Team").ifPresent(string -> {
|
||||
this.setHealth(input.getFloatOr("Health", this.getMaxHealth()));
|
||||
this.hurtTime = input.getShortOr("HurtTime", (short)0);
|
||||
this.deathTime = input.getShortOr("DeathTime", (short)0);
|
||||
@@ -794,6 +_,7 @@
|
||||
input.getString("Team").ifPresent(string -> {
|
||||
Scoreboard scoreboard = this.level().getScoreboard();
|
||||
PlayerTeam playerTeam = scoreboard.getPlayerTeam(string);
|
||||
+ if (!this.level().paperConfig().scoreboards.allowNonPlayerEntitiesOnScoreboards && !(this instanceof net.minecraft.world.entity.player.Player)) { playerTeam = null; } // Paper - Perf: Disable Scoreboards for non players by default
|
||||
boolean flag = playerTeam != null && scoreboard.addPlayerToTeam(this.getStringUUID(), playerTeam);
|
||||
if (!flag) {
|
||||
LOGGER.warn("Unable to add mob to team \"{}\" (that team probably doesn't exist)", string);
|
||||
@@ -777,11 +_,13 @@
|
||||
@@ -801,11 +_,13 @@
|
||||
});
|
||||
this.setSharedFlag(7, compound.getBooleanOr("FallFlying", false));
|
||||
compound.read("sleeping_pos", BlockPos.CODEC).ifPresentOrElse(blockPos -> {
|
||||
this.setSharedFlag(7, input.getBooleanOr("FallFlying", false));
|
||||
input.read("sleeping_pos", BlockPos.CODEC).ifPresentOrElse(blockPos -> {
|
||||
+ if (this.position().distanceToSqr(blockPos.getX(), blockPos.getY(), blockPos.getZ()) < Mth.square(16)) { // Paper - The sleeping pos will always also set the actual pos, so a desync suggests something is wrong
|
||||
this.setSleepingPos(blockPos);
|
||||
this.entityData.set(DATA_POSE, Pose.SLEEPING);
|
||||
@ -234,10 +234,10 @@
|
||||
}
|
||||
+ } // Paper - The sleeping pos will always also set the actual pos, so a desync suggests something is wrong
|
||||
}, this::clearSleepingPos);
|
||||
compound.getCompound("Brain").ifPresent(compoundTag -> this.brain = this.makeBrain(new Dynamic<>(NbtOps.INSTANCE, compoundTag)));
|
||||
this.lastHurtByPlayer = EntityReference.read(compound, "last_hurt_by_player");
|
||||
@@ -791,15 +_,44 @@
|
||||
this.equipment.setAll(compound.read("equipment", EntityEquipment.CODEC, registryOps).orElseGet(EntityEquipment::new));
|
||||
input.read("Brain", Codec.PASSTHROUGH).ifPresent(dynamic -> this.brain = this.makeBrain((Dynamic<?>)dynamic));
|
||||
this.lastHurtByPlayer = EntityReference.read(input, "last_hurt_by_player");
|
||||
@@ -816,15 +_,44 @@
|
||||
this.locatorBarIcon = input.read("locator_bar_icon", Waypoint.Icon.CODEC).orElseGet(Waypoint.Icon::new);
|
||||
}
|
||||
|
||||
+ // CraftBukkit start
|
||||
@ -281,7 +281,7 @@
|
||||
iterator.remove();
|
||||
this.onEffectsRemoved(List.of(mobEffectInstance));
|
||||
} else if (mobEffectInstance.getDuration() % 600 == 0) {
|
||||
@@ -809,6 +_,17 @@
|
||||
@@ -834,6 +_,17 @@
|
||||
} catch (ConcurrentModificationException var6) {
|
||||
}
|
||||
|
||||
@ -299,7 +299,7 @@
|
||||
if (this.effectsDirty) {
|
||||
this.updateInvisibilityStatus();
|
||||
this.updateGlowingStatus();
|
||||
@@ -916,15 +_,33 @@
|
||||
@@ -941,15 +_,33 @@
|
||||
}
|
||||
|
||||
public boolean removeAllEffects() {
|
||||
@ -337,7 +337,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -951,21 +_,57 @@
|
||||
@@ -976,21 +_,57 @@
|
||||
}
|
||||
|
||||
public final boolean addEffect(MobEffectInstance effectInstance) {
|
||||
@ -397,7 +397,7 @@
|
||||
this.onEffectUpdated(mobEffectInstance, true, entity);
|
||||
flag = true;
|
||||
}
|
||||
@@ -1004,11 +_,37 @@
|
||||
@@ -1029,11 +_,37 @@
|
||||
|
||||
@Nullable
|
||||
public final MobEffectInstance removeEffectNoUpdate(Holder<MobEffect> effect) {
|
||||
@ -436,7 +436,7 @@
|
||||
if (mobEffectInstance != null) {
|
||||
this.onEffectsRemoved(List.of(mobEffectInstance));
|
||||
return true;
|
||||
@@ -1092,17 +_,62 @@
|
||||
@@ -1124,17 +_,62 @@
|
||||
}
|
||||
|
||||
public void heal(float healAmount) {
|
||||
@ -500,7 +500,7 @@
|
||||
this.entityData.set(DATA_HEALTH_ID, Mth.clamp(health, 0.0F, this.getMaxHealth()));
|
||||
}
|
||||
|
||||
@@ -1114,7 +_,7 @@
|
||||
@@ -1146,7 +_,7 @@
|
||||
public boolean hurtServer(ServerLevel level, DamageSource damageSource, float amount) {
|
||||
if (this.isInvulnerableTo(level, damageSource)) {
|
||||
return false;
|
||||
@ -509,15 +509,14 @@
|
||||
return false;
|
||||
} else if (damageSource.is(DamageTypeTags.IS_FIRE) && this.hasEffect(MobEffects.FIRE_RESISTANCE)) {
|
||||
return false;
|
||||
@@ -1128,35 +_,59 @@
|
||||
amount = 0.0F;
|
||||
@@ -1161,35 +_,58 @@
|
||||
}
|
||||
|
||||
float originAmount = amount;
|
||||
- float f1 = this.applyItemBlocking(level, damageSource, amount);
|
||||
- amount -= f1;
|
||||
+ final float originalAmount = amount; // Paper - revert to vanilla #hurt - OBFHELPER
|
||||
+ float f1 = this.applyItemBlocking(level, damageSource, amount, true); // Paper
|
||||
+ // Paper end
|
||||
+ // amount -= f1; // CraftBukkit - Moved into handleEntityDamage(DamageSource, float) to allow modification
|
||||
boolean flag = f1 > 0.0F;
|
||||
- if (damageSource.is(DamageTypeTags.IS_FREEZING) && this.getType().is(EntityTypeTags.FREEZE_HURTS_EXTRA_TYPES)) {
|
||||
+ // CraftBukkit - Moved into handleEntityDamage(DamageSource, float) to get amount
|
||||
@ -554,7 +553,7 @@
|
||||
+ if (!this.actuallyHurt(level, damageSource, (float) event.getFinalDamage(), event)) { // Paper - fix invulnerability reduction in EntityDamageEvent - no longer subtract lastHurt, that is part of the damage event calc now
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (this instanceof ServerPlayer && event.getDamage() == 0 && originalAmount == 0) return false; // Paper - revert to vanilla damage - players are not affected by damage that is 0 - skip damage if the vanilla damage is 0 and was not modified by plugins in the event.
|
||||
+ if (this instanceof ServerPlayer && event.getDamage() == 0 && originAmount == 0) return false; // Paper - revert to vanilla damage - players are not affected by damage that is 0 - skip damage if the vanilla damage is 0 and was not modified by plugins in the event.
|
||||
+ // CraftBukkit end
|
||||
this.lastHurt = amount;
|
||||
flag1 = false;
|
||||
@ -567,7 +566,7 @@
|
||||
+ if (!this.actuallyHurt(level, damageSource, (float) event.getFinalDamage(), event)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (this instanceof ServerPlayer && event.getDamage() == 0 && originalAmount == 0) return false; // Paper - revert to vanilla damage - players are not affected by damage that is 0 - skip damage if the vanilla damage is 0 and was not modified by plugins in the event.
|
||||
+ if (this instanceof ServerPlayer && event.getDamage() == 0 && originAmount == 0) return false; // Paper - revert to vanilla damage - players are not affected by damage that is 0 - skip damage if the vanilla damage is 0 and was not modified by plugins in the event.
|
||||
this.lastHurt = amount;
|
||||
- this.invulnerableTime = 20;
|
||||
- this.actuallyHurt(level, damageSource, amount);
|
||||
@ -577,7 +576,7 @@
|
||||
this.hurtDuration = 10;
|
||||
this.hurtTime = this.hurtDuration;
|
||||
}
|
||||
@@ -1171,7 +_,7 @@
|
||||
@@ -1204,7 +_,7 @@
|
||||
level.broadcastDamageEvent(this, damageSource);
|
||||
}
|
||||
|
||||
@ -586,7 +585,7 @@
|
||||
this.markHurt();
|
||||
}
|
||||
|
||||
@@ -1186,8 +_,16 @@
|
||||
@@ -1219,8 +_,16 @@
|
||||
d = damageSource.getSourcePosition().x() - this.getX();
|
||||
d1 = damageSource.getSourcePosition().z() - this.getZ();
|
||||
}
|
||||
@ -604,7 +603,7 @@
|
||||
if (!flag) {
|
||||
this.indicateDamage(d, d1);
|
||||
}
|
||||
@@ -1196,19 +_,19 @@
|
||||
@@ -1229,19 +_,19 @@
|
||||
|
||||
if (this.isDeadOrDying()) {
|
||||
if (!this.checkTotemDeathProtection(damageSource)) {
|
||||
@ -629,7 +628,7 @@
|
||||
if (flag2) {
|
||||
this.lastDamageSource = damageSource;
|
||||
this.lastDamageStamp = this.level().getGameTime();
|
||||
@@ -1234,6 +_,12 @@
|
||||
@@ -1267,6 +_,12 @@
|
||||
}
|
||||
|
||||
public float applyItemBlocking(ServerLevel level, DamageSource damageSource, float damageAmount) {
|
||||
@ -642,7 +641,7 @@
|
||||
if (damageAmount <= 0.0F) {
|
||||
return 0.0F;
|
||||
} else {
|
||||
@@ -1258,10 +_,12 @@
|
||||
@@ -1291,10 +_,12 @@
|
||||
}
|
||||
|
||||
float f = blocksAttacks.resolveBlockedDamage(damageSource, damageAmount, acos);
|
||||
@ -656,7 +655,7 @@
|
||||
|
||||
return f;
|
||||
}
|
||||
@@ -1272,6 +_,59 @@
|
||||
@@ -1305,6 +_,59 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -716,7 +715,7 @@
|
||||
public void playSecondaryHurtSound(DamageSource damageSource) {
|
||||
if (damageSource.is(DamageTypes.THORNS)) {
|
||||
SoundSource soundSource = this instanceof Player ? SoundSource.PLAYERS : SoundSource.HOSTILE;
|
||||
@@ -1304,12 +_,24 @@
|
||||
@@ -1337,12 +_,24 @@
|
||||
return EntityReference.get(this.lastHurtByPlayer, this.level(), Player.class);
|
||||
}
|
||||
|
||||
@ -742,7 +741,7 @@
|
||||
}
|
||||
|
||||
private boolean checkTotemDeathProtection(DamageSource damageSource) {
|
||||
@@ -1319,18 +_,39 @@
|
||||
@@ -1352,18 +_,39 @@
|
||||
ItemStack itemStack = null;
|
||||
DeathProtection deathProtection = null;
|
||||
|
||||
@ -789,7 +788,7 @@
|
||||
serverPlayer.awardStat(Stats.ITEM_USED.get(itemStack.getItem()));
|
||||
CriteriaTriggers.USED_TOTEM.trigger(serverPlayer, itemStack);
|
||||
this.gameEvent(GameEvent.ITEM_INTERACT_FINISH);
|
||||
@@ -1389,6 +_,7 @@
|
||||
@@ -1422,6 +_,7 @@
|
||||
if (!this.isRemoved() && !this.dead) {
|
||||
Entity entity = damageSource.getEntity();
|
||||
LivingEntity killCredit = this.getKillCredit();
|
||||
@ -797,7 +796,7 @@
|
||||
if (killCredit != null) {
|
||||
killCredit.awardKillScore(this, damageSource);
|
||||
}
|
||||
@@ -1398,68 +_,141 @@
|
||||
@@ -1431,68 +_,141 @@
|
||||
}
|
||||
|
||||
if (!this.level().isClientSide && this.hasCustomName()) {
|
||||
@ -945,14 +944,14 @@
|
||||
+ protected void dropExperience(ServerLevel level, @Nullable Entity entity) {
|
||||
+ // CraftBukkit start - Update getExpReward() above if the removed if() changes!
|
||||
+ if (!(this instanceof net.minecraft.world.entity.boss.enderdragon.EnderDragon)) { // CraftBukkit - SPIGOT-2420: Special case ender dragon will drop the xp over time
|
||||
+ ExperienceOrb.award(level, this.position(), this.expToDrop, this instanceof ServerPlayer ? org.bukkit.entity.ExperienceOrb.SpawnReason.PLAYER_DEATH : org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, entity, this); // Paper
|
||||
+ ExperienceOrb.awardWithDirection(level, this.position(), net.minecraft.world.phys.Vec3.ZERO, this.expToDrop, this instanceof ServerPlayer ? org.bukkit.entity.ExperienceOrb.SpawnReason.PLAYER_DEATH : org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, entity, this); // Paper
|
||||
+ this.expToDrop = 0;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
protected void dropCustomDeathLoot(ServerLevel level, DamageSource damageSource, boolean recentlyHit) {
|
||||
@@ -1539,9 +_,14 @@
|
||||
@@ -1572,9 +_,14 @@
|
||||
}
|
||||
|
||||
public void knockback(double strength, double x, double z) {
|
||||
@ -969,7 +968,7 @@
|
||||
Vec3 deltaMovement = this.getDeltaMovement();
|
||||
|
||||
while (x * x + z * z < 1.0E-5F) {
|
||||
@@ -1550,11 +_,22 @@
|
||||
@@ -1583,11 +_,22 @@
|
||||
}
|
||||
|
||||
Vec3 vec3 = new Vec3(x, 0.0, z).normalize().scale(strength);
|
||||
@ -993,7 +992,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1639,7 +_,7 @@
|
||||
@@ -1672,7 +_,7 @@
|
||||
|
||||
@Override
|
||||
public boolean isAlive() {
|
||||
@ -1002,7 +1001,7 @@
|
||||
}
|
||||
|
||||
public boolean isLookingAtMe(LivingEntity entity, double tolerance, boolean scaleByDistance, boolean visual, double... yValues) {
|
||||
@@ -1673,9 +_,14 @@
|
||||
@@ -1706,9 +_,14 @@
|
||||
boolean flag = super.causeFallDamage(fallDistance, damageMultiplier, damageSource);
|
||||
int i = this.calculateFallDamage(fallDistance, damageMultiplier);
|
||||
if (i > 0) {
|
||||
@ -1018,7 +1017,7 @@
|
||||
return true;
|
||||
} else {
|
||||
return flag;
|
||||
@@ -1740,7 +_,7 @@
|
||||
@@ -1773,7 +_,7 @@
|
||||
|
||||
protected float getDamageAfterArmorAbsorb(DamageSource damageSource, float damageAmount) {
|
||||
if (!damageSource.is(DamageTypeTags.BYPASSES_ARMOR)) {
|
||||
@ -1027,7 +1026,7 @@
|
||||
damageAmount = CombatRules.getDamageAfterAbsorb(
|
||||
this, damageAmount, damageSource, this.getArmorValue(), (float)this.getAttributeValue(Attributes.ARMOR_TOUGHNESS)
|
||||
);
|
||||
@@ -1753,7 +_,8 @@
|
||||
@@ -1786,7 +_,8 @@
|
||||
if (damageSource.is(DamageTypeTags.BYPASSES_EFFECTS)) {
|
||||
return damageAmount;
|
||||
} else {
|
||||
@ -1037,7 +1036,7 @@
|
||||
int i = (this.getEffect(MobEffects.RESISTANCE).getAmplifier() + 1) * 5;
|
||||
int i1 = 25 - i;
|
||||
float f = damageAmount * i1;
|
||||
@@ -1790,24 +_,201 @@
|
||||
@@ -1823,24 +_,201 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -1249,7 +1248,7 @@
|
||||
}
|
||||
|
||||
public CombatTracker getCombatTracker() {
|
||||
@@ -1836,7 +_,17 @@
|
||||
@@ -1869,7 +_,17 @@
|
||||
}
|
||||
|
||||
public final void setArrowCount(int count) {
|
||||
@ -1268,7 +1267,7 @@
|
||||
}
|
||||
|
||||
public final int getStingerCount() {
|
||||
@@ -1991,7 +_,7 @@
|
||||
@@ -2024,7 +_,7 @@
|
||||
|
||||
@Override
|
||||
protected void onBelowWorld() {
|
||||
@ -1277,7 +1276,7 @@
|
||||
}
|
||||
|
||||
protected void updateSwingTime() {
|
||||
@@ -2087,8 +_,15 @@
|
||||
@@ -2120,8 +_,15 @@
|
||||
}
|
||||
|
||||
public void setItemSlot(EquipmentSlot slot, ItemStack stack) {
|
||||
@ -1295,7 +1294,7 @@
|
||||
|
||||
public float getArmorCoverPercentage() {
|
||||
int i = 0;
|
||||
@@ -2180,14 +_,27 @@
|
||||
@@ -2213,14 +_,27 @@
|
||||
return this.hasEffect(MobEffects.JUMP_BOOST) ? 0.1F * (this.getEffect(MobEffects.JUMP_BOOST).getAmplifier() + 1.0F) : 0.0F;
|
||||
}
|
||||
|
||||
@ -1323,7 +1322,7 @@
|
||||
this.addDeltaMovement(new Vec3(-Mth.sin(f) * 0.2, 0.0, Mth.cos(f) * 0.2));
|
||||
}
|
||||
|
||||
@@ -2327,8 +_,10 @@
|
||||
@@ -2380,8 +_,10 @@
|
||||
}
|
||||
|
||||
public void stopFallFlying() {
|
||||
@ -1334,7 +1333,7 @@
|
||||
}
|
||||
|
||||
private Vec3 updateFallFlyingMovement(Vec3 deltaMovement) {
|
||||
@@ -2454,7 +_,7 @@
|
||||
@@ -2507,7 +_,7 @@
|
||||
}
|
||||
|
||||
protected float getFlyingSpeed() {
|
||||
@ -1343,7 +1342,7 @@
|
||||
}
|
||||
|
||||
public float getSpeed() {
|
||||
@@ -2538,37 +_,15 @@
|
||||
@@ -2591,37 +_,15 @@
|
||||
profilerFiller.pop();
|
||||
profilerFiller.push("rangeChecks");
|
||||
|
||||
@ -1390,7 +1389,7 @@
|
||||
|
||||
profilerFiller.pop();
|
||||
if (this.isFallFlying()) {
|
||||
@@ -2598,16 +_,39 @@
|
||||
@@ -2651,16 +_,39 @@
|
||||
@Nullable
|
||||
private Map<EquipmentSlot, ItemStack> collectEquipmentChanges() {
|
||||
Map<EquipmentSlot, ItemStack> map = null;
|
||||
@ -1430,7 +1429,7 @@
|
||||
AttributeMap attributes = this.getAttributes();
|
||||
if (!itemStack.isEmpty()) {
|
||||
this.stopLocationBasedEffects(itemStack, equipmentSlot, attributes);
|
||||
@@ -2632,6 +_,8 @@
|
||||
@@ -2685,6 +_,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1439,7 +1438,7 @@
|
||||
}
|
||||
|
||||
return map;
|
||||
@@ -2663,7 +_,7 @@
|
||||
@@ -2716,7 +_,7 @@
|
||||
list.add(Pair.of(equipmentSlot, itemStack1));
|
||||
this.lastEquipmentItems.put(equipmentSlot, itemStack1);
|
||||
});
|
||||
@ -1448,7 +1447,7 @@
|
||||
}
|
||||
|
||||
protected void tickHeadTurn(float yBodyRot) {
|
||||
@@ -2749,8 +_,10 @@
|
||||
@@ -2802,8 +_,10 @@
|
||||
if (!flag || this.onGround() && !(fluidHeight > fluidJumpThreshold)) {
|
||||
if (!this.isInLava() || this.onGround() && !(fluidHeight > fluidJumpThreshold)) {
|
||||
if ((this.onGround() || flag && fluidHeight <= fluidJumpThreshold) && this.noJumpDelay == 0) {
|
||||
@ -1459,7 +1458,7 @@
|
||||
}
|
||||
} else {
|
||||
this.jumpInLiquid(FluidTags.LAVA);
|
||||
@@ -2791,7 +_,7 @@
|
||||
@@ -2844,7 +_,7 @@
|
||||
profilerFiller.pop();
|
||||
if (this.level() instanceof ServerLevel serverLevel) {
|
||||
profilerFiller.push("freezing");
|
||||
@ -1468,7 +1467,7 @@
|
||||
this.setTicksFrozen(Math.max(0, this.getTicksFrozen() - 2));
|
||||
}
|
||||
|
||||
@@ -2812,6 +_,20 @@
|
||||
@@ -2865,6 +_,20 @@
|
||||
|
||||
this.pushEntities();
|
||||
profilerFiller.pop();
|
||||
@ -1489,15 +1488,15 @@
|
||||
if (this.level() instanceof ServerLevel serverLevel && this.isSensitiveToWater() && this.isInWaterOrRain()) {
|
||||
this.hurtServer(serverLevel, this.damageSources().drown(), 1.0F);
|
||||
}
|
||||
@@ -2830,6 +_,7 @@
|
||||
this.checkSlowFallDistance();
|
||||
@@ -2887,6 +_,7 @@
|
||||
this.checkFallDistanceAccumulation();
|
||||
if (!this.level().isClientSide) {
|
||||
if (!this.canGlide()) {
|
||||
+ if (this.getSharedFlag(7) != false && !CraftEventFactory.callToggleGlideEvent(this, false).isCancelled()) // CraftBukkit
|
||||
this.setSharedFlag(7, false);
|
||||
return;
|
||||
}
|
||||
@@ -2869,10 +_,25 @@
|
||||
@@ -2926,10 +_,25 @@
|
||||
}
|
||||
|
||||
protected void pushEntities() {
|
||||
@ -1524,7 +1523,7 @@
|
||||
if (_int > 0 && pushableEntities.size() > _int - 1 && this.random.nextInt(4) == 0) {
|
||||
int i = 0;
|
||||
|
||||
@@ -2888,7 +_,16 @@
|
||||
@@ -2945,7 +_,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -1541,7 +1540,7 @@
|
||||
this.doPush(entity1);
|
||||
}
|
||||
}
|
||||
@@ -2930,9 +_,16 @@
|
||||
@@ -2987,9 +_,16 @@
|
||||
|
||||
@Override
|
||||
public void stopRiding() {
|
||||
@ -1560,16 +1559,16 @@
|
||||
this.dismountVehicle(vehicle);
|
||||
}
|
||||
}
|
||||
@@ -2959,7 +_,7 @@
|
||||
@@ -3016,7 +_,7 @@
|
||||
}
|
||||
|
||||
public void onItemPickup(ItemEntity itemEntity) {
|
||||
- Entity owner = itemEntity.getOwner();
|
||||
+ Entity owner = itemEntity.thrower != null ? this.level().getGlobalPlayerByUUID(itemEntity.thrower) : null; // Paper - check global player list where appropriate
|
||||
+ Entity owner = EntityReference.get(itemEntity.thrower, this.level()::getGlobalPlayerByUUID, Entity.class); // Paper - check global player list where appropriate
|
||||
if (owner instanceof ServerPlayer) {
|
||||
CriteriaTriggers.THROWN_ITEM_PICKED_UP_BY_ENTITY.trigger((ServerPlayer)owner, itemEntity.getItem(), this);
|
||||
}
|
||||
@@ -2969,7 +_,7 @@
|
||||
@@ -3026,7 +_,7 @@
|
||||
if (!entity.isRemoved()
|
||||
&& !this.level().isClientSide
|
||||
&& (entity instanceof ItemEntity || entity instanceof AbstractArrow || entity instanceof ExperienceOrb)) {
|
||||
@ -1578,7 +1577,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2983,7 +_,8 @@
|
||||
@@ -3040,7 +_,8 @@
|
||||
} else {
|
||||
Vec3 vec3 = new Vec3(this.getX(), this.getEyeY(), this.getZ());
|
||||
Vec3 vec31 = new Vec3(entity.getX(), y, entity.getZ());
|
||||
@ -1588,7 +1587,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3003,13 +_,27 @@
|
||||
@@ -3060,13 +_,27 @@
|
||||
|
||||
@Override
|
||||
public boolean isPickable() {
|
||||
@ -1619,7 +1618,7 @@
|
||||
|
||||
@Override
|
||||
public float getYHeadRot() {
|
||||
@@ -3040,7 +_,7 @@
|
||||
@@ -3097,7 +_,7 @@
|
||||
}
|
||||
|
||||
public final void setAbsorptionAmount(float absorptionAmount) {
|
||||
@ -1628,7 +1627,7 @@
|
||||
}
|
||||
|
||||
protected void internalSetAbsorptionAmount(float absorptionAmount) {
|
||||
@@ -3067,6 +_,15 @@
|
||||
@@ -3124,6 +_,15 @@
|
||||
return (this.entityData.get(DATA_LIVING_ENTITY_FLAGS) & 2) > 0 ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND;
|
||||
}
|
||||
|
||||
@ -1644,7 +1643,7 @@
|
||||
private void updatingUsingItem() {
|
||||
if (this.isUsingItem()) {
|
||||
if (ItemStack.isSameItem(this.getItemInHand(this.getUsedItemHand()), this.useItem)) {
|
||||
@@ -3084,6 +_,11 @@
|
||||
@@ -3141,6 +_,11 @@
|
||||
return null;
|
||||
} else {
|
||||
double d = this.getEyeY() - 0.3F;
|
||||
@ -1656,7 +1655,7 @@
|
||||
ItemEntity itemEntity = new ItemEntity(this.level(), this.getX(), d, this.getZ(), stack);
|
||||
itemEntity.setPickUpDelay(40);
|
||||
if (includeThrower) {
|
||||
@@ -3115,7 +_,12 @@
|
||||
@@ -3172,7 +_,12 @@
|
||||
|
||||
protected void updateUsingItem(ItemStack usingItem) {
|
||||
usingItem.onUseTick(this.level(), this, this.getUseItemRemainingTicks());
|
||||
@ -1670,7 +1669,7 @@
|
||||
this.completeUsingItem();
|
||||
}
|
||||
}
|
||||
@@ -3141,10 +_,19 @@
|
||||
@@ -3198,10 +_,19 @@
|
||||
}
|
||||
|
||||
public void startUsingItem(InteractionHand hand) {
|
||||
@ -1692,7 +1691,7 @@
|
||||
if (!this.level().isClientSide) {
|
||||
this.setLivingEntityFlag(1, true);
|
||||
this.setLivingEntityFlag(2, hand == InteractionHand.OFF_HAND);
|
||||
@@ -3168,7 +_,10 @@
|
||||
@@ -3225,7 +_,10 @@
|
||||
}
|
||||
} else if (!this.isUsingItem() && !this.useItem.isEmpty()) {
|
||||
this.useItem = ItemStack.EMPTY;
|
||||
@ -1704,7 +1703,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3207,12 +_,49 @@
|
||||
@@ -3264,12 +_,49 @@
|
||||
this.releaseUsingItem();
|
||||
} else {
|
||||
if (!this.useItem.isEmpty() && this.isUsingItem()) {
|
||||
@ -1755,7 +1754,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3237,6 +_,7 @@
|
||||
@@ -3294,6 +_,7 @@
|
||||
ItemStack itemInHand = this.getItemInHand(this.getUsedItemHand());
|
||||
if (!this.useItem.isEmpty() && ItemStack.isSameItem(itemInHand, this.useItem)) {
|
||||
this.useItem = itemInHand;
|
||||
@ -1763,7 +1762,7 @@
|
||||
this.useItem.releaseUsing(this.level(), this, this.getUseItemRemainingTicks());
|
||||
if (this.useItem.useOnRelease()) {
|
||||
this.updatingUsingItem();
|
||||
@@ -3256,7 +_,10 @@
|
||||
@@ -3313,7 +_,10 @@
|
||||
}
|
||||
|
||||
this.useItem = ItemStack.EMPTY;
|
||||
@ -1775,7 +1774,7 @@
|
||||
}
|
||||
|
||||
public boolean isBlocking() {
|
||||
@@ -3280,6 +_,60 @@
|
||||
@@ -3337,6 +_,60 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -1836,7 +1835,7 @@
|
||||
public boolean isSuppressingSlidingDownLadder() {
|
||||
return this.isShiftKeyDown();
|
||||
}
|
||||
@@ -3298,6 +_,12 @@
|
||||
@@ -3355,6 +_,12 @@
|
||||
}
|
||||
|
||||
public boolean randomTeleport(double x, double y, double z, boolean broadcastTeleport) {
|
||||
@ -1849,7 +1848,7 @@
|
||||
double x1 = this.getX();
|
||||
double y1 = this.getY();
|
||||
double z1 = this.getZ();
|
||||
@@ -3320,16 +_,39 @@
|
||||
@@ -3377,16 +_,39 @@
|
||||
}
|
||||
|
||||
if (flag1) {
|
||||
@ -1892,7 +1891,7 @@
|
||||
} else {
|
||||
if (broadcastTeleport) {
|
||||
level.broadcastEntityEvent(this, (byte)46);
|
||||
@@ -3339,7 +_,7 @@
|
||||
@@ -3396,7 +_,7 @@
|
||||
pathfinderMob.getNavigation().stop();
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
--- a/net/minecraft/world/entity/Mob.java
|
||||
+++ b/net/minecraft/world/entity/Mob.java
|
||||
@@ -83,6 +_,14 @@
|
||||
import net.minecraft.world.phys.AABB;
|
||||
@@ -82,6 +_,14 @@
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.ticks.ContainerSingleItem;
|
||||
|
||||
+// CraftBukkit start
|
||||
@ -15,7 +15,7 @@
|
||||
public abstract class Mob extends LivingEntity implements EquipmentUser, Leashable, Targeting {
|
||||
private static final EntityDataAccessor<Byte> DATA_MOB_FLAGS_ID = SynchedEntityData.defineId(Mob.class, EntityDataSerializers.BYTE);
|
||||
private static final int MOB_FLAG_NO_AI = 1;
|
||||
@@ -112,6 +_,7 @@
|
||||
@@ -115,6 +_,7 @@
|
||||
private final BodyRotationControl bodyRotationControl;
|
||||
protected PathNavigation navigation;
|
||||
public GoalSelector goalSelector;
|
||||
@ -23,15 +23,15 @@
|
||||
public GoalSelector targetSelector;
|
||||
@Nullable
|
||||
private LivingEntity target;
|
||||
@@ -126,6 +_,7 @@
|
||||
@@ -129,6 +_,7 @@
|
||||
private Leashable.LeashData leashData;
|
||||
private BlockPos restrictCenter = BlockPos.ZERO;
|
||||
private float restrictRadius = -1.0F;
|
||||
private BlockPos homePosition = BlockPos.ZERO;
|
||||
private int homeRadius = -1;
|
||||
+ public boolean aware = true; // CraftBukkit
|
||||
|
||||
protected Mob(EntityType<? extends Mob> entityType, Level level) {
|
||||
super(entityType, level);
|
||||
@@ -142,6 +_,12 @@
|
||||
@@ -145,6 +_,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@
|
||||
protected void registerGoals() {
|
||||
}
|
||||
|
||||
@@ -222,7 +_,39 @@
|
||||
@@ -225,7 +_,39 @@
|
||||
}
|
||||
|
||||
public void setTarget(@Nullable LivingEntity target) {
|
||||
@ -84,40 +84,40 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -358,13 +_,22 @@
|
||||
@@ -365,13 +_,22 @@
|
||||
if (this.isNoAi()) {
|
||||
compound.putBoolean("NoAI", this.isNoAi());
|
||||
output.putBoolean("NoAI", this.isNoAi());
|
||||
}
|
||||
+ compound.putBoolean("Bukkit.Aware", this.aware); // CraftBukkit
|
||||
+ output.putBoolean("Bukkit.Aware", this.aware); // CraftBukkit
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readAdditionalSaveData(CompoundTag compound) {
|
||||
super.readAdditionalSaveData(compound);
|
||||
- this.setCanPickUpLoot(compound.getBooleanOr("CanPickUpLoot", false));
|
||||
- this.persistenceRequired = compound.getBooleanOr("PersistenceRequired", false);
|
||||
protected void readAdditionalSaveData(ValueInput input) {
|
||||
super.readAdditionalSaveData(input);
|
||||
- this.setCanPickUpLoot(input.getBooleanOr("CanPickUpLoot", false));
|
||||
- this.persistenceRequired = input.getBooleanOr("PersistenceRequired", false);
|
||||
+ // CraftBukkit start - If looting or persistence is false only use it if it was set after we started using it
|
||||
+ boolean canPickUpLoot = compound.getBooleanOr("CanPickUpLoot", false);
|
||||
+ if (isLevelAtLeast(compound, 1) || canPickUpLoot) {
|
||||
+ boolean canPickUpLoot = input.getBooleanOr("CanPickUpLoot", false);
|
||||
+ if (isLevelAtLeast(input, 1) || canPickUpLoot) {
|
||||
+ this.setCanPickUpLoot(canPickUpLoot);
|
||||
+ }
|
||||
+ boolean persistenceRequired = compound.getBooleanOr("PersistenceRequired", false);
|
||||
+ if (isLevelAtLeast(compound, 1) || persistenceRequired) {
|
||||
+ boolean persistenceRequired = input.getBooleanOr("PersistenceRequired", false);
|
||||
+ if (isLevelAtLeast(input, 1) || persistenceRequired) {
|
||||
+ this.persistenceRequired = persistenceRequired;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
RegistryOps<Tag> registryOps = this.registryAccess().createSerializationContext(NbtOps.INSTANCE);
|
||||
this.dropChances = compound.read("drop_chances", DropChances.CODEC, registryOps).orElse(DropChances.DEFAULT);
|
||||
this.readLeashData(compound);
|
||||
@@ -372,6 +_,7 @@
|
||||
this.lootTable = compound.read("DeathLootTable", LootTable.KEY_CODEC);
|
||||
this.lootTableSeed = compound.getLongOr("DeathLootTableSeed", 0L);
|
||||
this.setNoAi(compound.getBooleanOr("NoAI", false));
|
||||
+ this.aware = compound.getBooleanOr("Bukkit.Aware", true); // CraftBukkit
|
||||
this.dropChances = input.read("drop_chances", DropChances.CODEC).orElse(DropChances.DEFAULT);
|
||||
this.readLeashData(input);
|
||||
this.homeRadius = input.getIntOr("home_radius", -1);
|
||||
@@ -383,6 +_,7 @@
|
||||
this.lootTable = input.read("DeathLootTable", LootTable.KEY_CODEC);
|
||||
this.lootTableSeed = input.getLongOr("DeathLootTableSeed", 0L);
|
||||
this.setNoAi(input.getBooleanOr("NoAI", false));
|
||||
+ this.aware = input.getBooleanOr("Bukkit.Aware", true); // CraftBukkit
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -433,6 +_,11 @@
|
||||
@@ -446,6 +_,11 @@
|
||||
&& !itemEntity.getItem().isEmpty()
|
||||
&& !itemEntity.hasPickUpDelay()
|
||||
&& this.wantsToPickUp(serverLevel, itemEntity.getItem())) {
|
||||
@ -129,7 +129,7 @@
|
||||
this.pickUpItem(serverLevel, itemEntity);
|
||||
}
|
||||
}
|
||||
@@ -447,18 +_,24 @@
|
||||
@@ -460,18 +_,24 @@
|
||||
|
||||
protected void pickUpItem(ServerLevel level, ItemEntity entity) {
|
||||
ItemStack item = entity.getItem();
|
||||
@ -156,7 +156,7 @@
|
||||
EquipmentSlot equipmentSlotForItem = this.getEquipmentSlotForItem(stack);
|
||||
if (!this.isEquippableInSlot(stack, equipmentSlotForItem)) {
|
||||
return ItemStack.EMPTY;
|
||||
@@ -471,10 +_,18 @@
|
||||
@@ -484,10 +_,18 @@
|
||||
canReplaceCurrentItem = itemBySlot.isEmpty();
|
||||
}
|
||||
|
||||
@ -176,7 +176,7 @@
|
||||
}
|
||||
|
||||
ItemStack itemStack = equipmentSlotForItem.limit(stack);
|
||||
@@ -591,22 +_,29 @@
|
||||
@@ -608,22 +_,29 @@
|
||||
@Override
|
||||
public void checkDespawn() {
|
||||
if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.shouldDespawnInPeaceful()) {
|
||||
@ -219,7 +219,7 @@
|
||||
this.noActionTime = 0;
|
||||
}
|
||||
}
|
||||
@@ -618,6 +_,15 @@
|
||||
@@ -635,6 +_,15 @@
|
||||
@Override
|
||||
protected final void serverAiStep() {
|
||||
this.noActionTime++;
|
||||
@ -235,7 +235,7 @@
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
profilerFiller.push("sensing");
|
||||
this.sensing.tick();
|
||||
@@ -793,14 +_,69 @@
|
||||
@@ -814,14 +_,69 @@
|
||||
public boolean stillValid(Player player) {
|
||||
return player.getVehicle() == Mob.this || player.canInteractWithEntity(Mob.this, 4.0);
|
||||
}
|
||||
@ -305,7 +305,7 @@
|
||||
ItemStack itemBySlot = this.getItemBySlot(equipmentSlot);
|
||||
float f = this.dropChances.byEquipment(equipmentSlot);
|
||||
if (f != 0.0F) {
|
||||
@@ -820,7 +_,13 @@
|
||||
@@ -841,7 +_,13 @@
|
||||
}
|
||||
|
||||
this.spawnAtLocation(level, itemBySlot);
|
||||
@ -319,7 +319,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -844,7 +_,9 @@
|
||||
@@ -865,7 +_,9 @@
|
||||
set.add(equipmentSlot);
|
||||
} else if (this.dropChances.isPreserved(equipmentSlot)) {
|
||||
this.setItemSlot(equipmentSlot, ItemStack.EMPTY);
|
||||
@ -329,7 +329,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1122,6 +_,21 @@
|
||||
@@ -1147,6 +_,21 @@
|
||||
public <T extends Mob> T convertTo(
|
||||
EntityType<T> entityType, ConversionParams conversionParams, EntitySpawnReason spawnReason, ConversionParams.AfterConversion<T> afterConversion
|
||||
) {
|
||||
@ -351,7 +351,7 @@
|
||||
if (this.isRemoved()) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -1130,13 +_,23 @@
|
||||
@@ -1155,13 +_,23 @@
|
||||
return null;
|
||||
} else {
|
||||
conversionParams.type().convert(this, mob, conversionParams);
|
||||
@ -378,7 +378,7 @@
|
||||
}
|
||||
|
||||
return mob;
|
||||
@@ -1146,7 +_,18 @@
|
||||
@@ -1171,7 +_,18 @@
|
||||
|
||||
@Nullable
|
||||
public <T extends Mob> T convertTo(EntityType<T> entityType, ConversionParams coversionParams, ConversionParams.AfterConversion<T> afterConversion) {
|
||||
@ -398,7 +398,7 @@
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -1182,7 +_,17 @@
|
||||
@@ -1213,7 +_,17 @@
|
||||
public boolean startRiding(Entity entity, boolean force) {
|
||||
boolean flag = super.startRiding(entity, force);
|
||||
if (flag && this.isLeashed()) {
|
||||
@ -417,7 +417,7 @@
|
||||
}
|
||||
|
||||
return flag;
|
||||
@@ -1270,7 +_,7 @@
|
||||
@@ -1296,7 +_,7 @@
|
||||
float knockback = this.getKnockback(source, damageSource);
|
||||
if (knockback > 0.0F && source instanceof LivingEntity livingEntity) {
|
||||
livingEntity.knockback(
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
--- a/net/minecraft/world/entity/NeutralMob.java
|
||||
+++ b/net/minecraft/world/entity/NeutralMob.java
|
||||
@@ -35,9 +_,11 @@
|
||||
@@ -36,9 +_,11 @@
|
||||
if (level instanceof ServerLevel serverLevel) {
|
||||
UUID uuid = tag.read("AngryAt", UUIDUtil.CODEC).orElse(null);
|
||||
UUID uuid = input.read("AngryAt", UUIDUtil.CODEC).orElse(null);
|
||||
this.setPersistentAngerTarget(uuid);
|
||||
- if ((uuid != null ? serverLevel.getEntity(uuid) : null) instanceof LivingEntity livingEntity) {
|
||||
- this.setTarget(livingEntity);
|
||||
@ -15,7 +15,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +_,7 @@
|
||||
@@ -91,7 +_,7 @@
|
||||
default void stopBeingAngry() {
|
||||
this.setLastHurtByMob(null);
|
||||
this.setPersistentAngerTarget(null);
|
||||
@ -24,7 +24,7 @@
|
||||
this.setRemainingPersistentAngerTime(0);
|
||||
}
|
||||
|
||||
@@ -101,8 +_,24 @@
|
||||
@@ -102,8 +_,24 @@
|
||||
|
||||
void setTarget(@Nullable LivingEntity livingEntity);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user