mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2026-01-04 15:41:40 +00:00
fix bundle packet too large (#419)
restore to vanilla behavior bundle delimiter packet used to ensure handle multiply packet in same tick (client side) handle all packets together is unnecessarily
This commit is contained in:
@@ -604,7 +604,7 @@ index f106373ef3ac4a8685c2939c9e8361688a285913..7df467924d029d6e42b1d0b039cb9272
|
||||
if (!this.players.isEmpty()) {
|
||||
for (ServerPlayer serverPlayer : Lists.newArrayList(this.players)) {
|
||||
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
|
||||
index add696ec1835eb161d6fc94509a2a77febd23d69..ca948c0f4f48b567b66e4b992eef99d3a9210d45 100644
|
||||
index add696ec1835eb161d6fc94509a2a77febd23d69..23a449cec699c0a32d6fffc0f88e84895b162856 100644
|
||||
--- a/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -57,11 +57,13 @@ public class ServerEntity {
|
||||
@@ -629,7 +629,7 @@ index add696ec1835eb161d6fc94509a2a77febd23d69..ca948c0f4f48b567b66e4b992eef99d3
|
||||
this.positionCodec.setBase(entity.trackingPosition());
|
||||
this.lastSentMovement = entity.getDeltaMovement();
|
||||
this.lastSentYRot = Mth.packDegrees(entity.getYRot());
|
||||
@@ -105,204 +108,413 @@ public class ServerEntity {
|
||||
@@ -105,204 +108,415 @@ public class ServerEntity {
|
||||
|
||||
// Paper start - fix desync when a player is added to the tracker
|
||||
private boolean forceStateResync;
|
||||
@@ -992,8 +992,10 @@ index add696ec1835eb161d6fc94509a2a77febd23d69..ca948c0f4f48b567b66e4b992eef99d3
|
||||
+ if (d > 1.0E-7 || d > 0.0 && deltaMovement.lengthSqr() == 0.0) {
|
||||
+ this.lastSentMovement = deltaMovement;
|
||||
+ if (this.entity instanceof AbstractHurtingProjectile abstractHurtingProjectile) {
|
||||
+ trackedEntity.leafBroadcast(ctx, new ClientboundSetEntityMotionPacket(this.entity.getId(), this.lastSentMovement));
|
||||
+ trackedEntity.leafBroadcast(ctx, new ClientboundProjectilePowerPacket(abstractHurtingProjectile.getId(), abstractHurtingProjectile.accelerationPower));
|
||||
+ trackedEntity.leafBroadcast(ctx, new ClientboundBundlePacket(List.of(
|
||||
+ new ClientboundSetEntityMotionPacket(this.entity.getId(), this.lastSentMovement),
|
||||
+ new ClientboundProjectilePowerPacket(abstractHurtingProjectile.getId(), abstractHurtingProjectile.accelerationPower)
|
||||
+ )));
|
||||
+ } else {
|
||||
+ trackedEntity.leafBroadcast(ctx, new ClientboundSetEntityMotionPacket(this.entity.getId(), this.lastSentMovement));
|
||||
+ }
|
||||
@@ -1043,7 +1045,7 @@ index add696ec1835eb161d6fc94509a2a77febd23d69..ca948c0f4f48b567b66e4b992eef99d3
|
||||
private Stream<Entity> mountedOrDismounted(List<Entity> entities) {
|
||||
return Streams.concat(
|
||||
this.lastPassengers.stream().filter(entity -> !entities.contains(entity)),
|
||||
@@ -356,6 +568,39 @@ public class ServerEntity {
|
||||
@@ -356,6 +570,39 @@ public class ServerEntity {
|
||||
this.positionCodec.setBase(this.entity.position());
|
||||
}
|
||||
|
||||
@@ -1083,14 +1085,16 @@ index add696ec1835eb161d6fc94509a2a77febd23d69..ca948c0f4f48b567b66e4b992eef99d3
|
||||
public void removePairing(ServerPlayer player) {
|
||||
this.entity.stopSeenByPlayer(player);
|
||||
player.connection.send(new ClientboundRemoveEntitiesPacket(this.entity.getId()));
|
||||
@@ -368,8 +613,21 @@ public class ServerEntity {
|
||||
@@ -368,8 +615,23 @@ public class ServerEntity {
|
||||
this.entity.startSeenByPlayer(player);
|
||||
}
|
||||
|
||||
+ // Leaf start - Multithreaded tracker
|
||||
+ public void leafAddPairing(org.dreeam.leaf.async.tracker.TrackerCtx ctx, ServerPlayer player) {
|
||||
+ final net.minecraft.server.network.ServerGamePacketListenerImpl connection = player.connection;
|
||||
+ this.sendPairingData0(player, p -> ctx.send(connection, p), true);
|
||||
+ List<Packet<? super ClientGamePacketListener>> list = new ArrayList<>();
|
||||
+ this.sendPairingData0(player, list::add, true);
|
||||
+ ctx.send(connection, new ClientboundBundlePacket(list));
|
||||
+ ctx.startSeenByPlayer(connection, this.entity);
|
||||
+ }
|
||||
+
|
||||
@@ -1105,7 +1109,7 @@ index add696ec1835eb161d6fc94509a2a77febd23d69..ca948c0f4f48b567b66e4b992eef99d3
|
||||
// CraftBukkit start - Remove useless error spam, just return
|
||||
// LOGGER.warn("Fetching packet for removed entity {}", this.entity);
|
||||
return;
|
||||
@@ -407,7 +665,7 @@ public class ServerEntity {
|
||||
@@ -407,7 +669,7 @@ public class ServerEntity {
|
||||
if (!list.isEmpty()) {
|
||||
consumer.accept(new ClientboundSetEquipmentPacket(this.entity.getId(), list, true)); // Paper - data sanitization
|
||||
}
|
||||
@@ -1114,7 +1118,7 @@ index add696ec1835eb161d6fc94509a2a77febd23d69..ca948c0f4f48b567b66e4b992eef99d3
|
||||
}
|
||||
|
||||
if (!this.entity.getPassengers().isEmpty()) {
|
||||
@@ -443,6 +701,7 @@ public class ServerEntity {
|
||||
@@ -443,6 +705,7 @@ public class ServerEntity {
|
||||
return Mth.unpackDegrees(this.lastSentYHeadRot);
|
||||
}
|
||||
|
||||
@@ -1122,7 +1126,7 @@ index add696ec1835eb161d6fc94509a2a77febd23d69..ca948c0f4f48b567b66e4b992eef99d3
|
||||
public void sendDirtyEntityData() {
|
||||
SynchedEntityData entityData = this.entity.getEntityData();
|
||||
List<SynchedEntityData.DataValue<?>> list = entityData.packDirty();
|
||||
@@ -450,10 +709,12 @@ public class ServerEntity {
|
||||
@@ -450,10 +713,12 @@ public class ServerEntity {
|
||||
this.trackedDataValues = entityData.getNonDefaultValues();
|
||||
this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), list));
|
||||
}
|
||||
@@ -1135,7 +1139,7 @@ index add696ec1835eb161d6fc94509a2a77febd23d69..ca948c0f4f48b567b66e4b992eef99d3
|
||||
// CraftBukkit start - Send scaled max health
|
||||
if (this.entity instanceof ServerPlayer serverPlayer) {
|
||||
serverPlayer.getBukkitEntity().injectScaledMaxHealth(attributesToSync, false);
|
||||
@@ -462,11 +723,38 @@ public class ServerEntity {
|
||||
@@ -462,11 +727,38 @@ public class ServerEntity {
|
||||
this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), attributesToSync));
|
||||
}
|
||||
|
||||
@@ -1214,7 +1218,7 @@ index 08d12a1acc3a672a77daa15f82392cd603c30283..b0ac6de9e0f15d234781fc43dd6fd1d5
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index f98617c5d55876ac91377f3014d6f0438305d7b3..25871b2db4888d8729f2dd64fdac16dc6eecc5e9 100644
|
||||
index 070fc3b4ec0558c597eb411db5b22edc447fe976..512d9b22e79c2bff18defa2f101475d315098176 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -1928,7 +1928,7 @@ public class ServerGamePacketListenerImpl
|
||||
|
||||
@@ -62,26 +62,26 @@ public final class AsyncTracker {
|
||||
return;
|
||||
}
|
||||
}
|
||||
handle(world, task);
|
||||
handle(world, task, false);
|
||||
}
|
||||
|
||||
public static void onTickEnd(MinecraftServer server) {
|
||||
for (ServerLevel world : server.getAllLevels()) {
|
||||
Future<TrackerCtx>[] task = world.trackerTask;
|
||||
if (task != null) {
|
||||
handle(world, task);
|
||||
handle(world, task, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void handle(ServerLevel world, Future<TrackerCtx>[] futures) {
|
||||
private static void handle(ServerLevel world, Future<TrackerCtx>[] futures, boolean flush) {
|
||||
try {
|
||||
TrackerCtx ctx = futures[0].get();
|
||||
for (int i = 1; i < futures.length; i++) {
|
||||
ctx.join(futures[i].get());
|
||||
}
|
||||
world.trackerTask = null;
|
||||
ctx.handle();
|
||||
ctx.handle(flush);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (ExecutionException e) {
|
||||
|
||||
@@ -5,9 +5,9 @@ import io.papermc.paper.event.player.PlayerTrackEntityEvent;
|
||||
import io.papermc.paper.event.player.PlayerUntrackEntityEvent;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.network.protocol.game.ClientboundBundlePacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
@@ -25,12 +25,8 @@ import net.minecraft.world.level.saveddata.maps.MapId;
|
||||
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
|
||||
import org.bukkit.event.player.PlayerVelocityEvent;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class TrackerCtx {
|
||||
private static final int SIZE_LIMIT_PER_BUNDLE = 4096;
|
||||
|
||||
private final Reference2ReferenceOpenHashMap<ServerPlayerConnection, ObjectArrayList<Packet<? super ClientGamePacketListener>>> packets;
|
||||
private final Reference2ReferenceOpenHashMap<ServerPlayerConnection, ReferenceArrayList<Packet<? super ClientGamePacketListener>>> packets;
|
||||
private final ServerLevel world;
|
||||
private final ObjectArrayList<ServerPlayer> bukkitVelocityEvent = new ObjectArrayList<>();
|
||||
private final ObjectArrayList<ItemFrame> bukkitItemFrames = new ObjectArrayList<>();
|
||||
@@ -108,7 +104,7 @@ public final class TrackerCtx {
|
||||
}
|
||||
|
||||
public void send(ServerPlayerConnection connection, Packet<? super ClientGamePacketListener> packet) {
|
||||
packets.computeIfAbsent(connection, x -> new ObjectArrayList<>()).add(packet);
|
||||
packets.computeIfAbsent(connection, x -> ReferenceArrayList.wrap(new Packet[16])).add(packet);
|
||||
}
|
||||
|
||||
void join(TrackerCtx other) {
|
||||
@@ -123,12 +119,12 @@ public final class TrackerCtx {
|
||||
var iterator = other.packets.reference2ReferenceEntrySet().fastIterator();
|
||||
while (iterator.hasNext()) {
|
||||
var entry = iterator.next();
|
||||
packets.computeIfAbsent(entry.getKey(), x -> new ObjectArrayList<>()).addAll(entry.getValue());
|
||||
packets.computeIfAbsent(entry.getKey(), x -> ReferenceArrayList.wrap(new Packet[0])).addAll(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
void handle() {
|
||||
handlePackets(world, packets);
|
||||
void handle(boolean flush) {
|
||||
handlePackets(world, packets, flush);
|
||||
|
||||
if (!pluginEntity.isEmpty()) {
|
||||
for (final Entity entity : pluginEntity) {
|
||||
@@ -237,10 +233,10 @@ public final class TrackerCtx {
|
||||
paperStopSeen.clear();
|
||||
}
|
||||
|
||||
handlePackets(world, packets);
|
||||
handlePackets(world, packets, flush);
|
||||
}
|
||||
|
||||
private static void handlePackets(ServerLevel world, Reference2ReferenceOpenHashMap<ServerPlayerConnection, ObjectArrayList<Packet<? super ClientGamePacketListener>>> packets) {
|
||||
private static void handlePackets(ServerLevel world, Reference2ReferenceOpenHashMap<ServerPlayerConnection, ReferenceArrayList<Packet<? super ClientGamePacketListener>>> packets, boolean flush) {
|
||||
if (packets.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -248,25 +244,16 @@ public final class TrackerCtx {
|
||||
while (iter.hasNext()) {
|
||||
var entry = iter.next();
|
||||
ServerPlayerConnection connection = entry.getKey();
|
||||
ObjectArrayList<Packet<? super ClientGamePacketListener>> list = entry.getValue();
|
||||
ReferenceArrayList<Packet<? super ClientGamePacketListener>> list = entry.getValue();
|
||||
if (!world.equals(connection.getPlayer().level())) {
|
||||
continue;
|
||||
}
|
||||
int size = list.size();
|
||||
if (size > SIZE_LIMIT_PER_BUNDLE) {
|
||||
int from = 0;
|
||||
while (from < size) {
|
||||
int chunkLen = Math.min(SIZE_LIMIT_PER_BUNDLE, size - from);
|
||||
Packet<? super ClientGamePacketListener>[] chunk = new Packet[chunkLen];
|
||||
list.getElements(from, chunk, 0, chunkLen);
|
||||
connection.send(new ClientboundBundlePacket(Arrays.asList(chunk)));
|
||||
from += chunkLen;
|
||||
}
|
||||
} else {
|
||||
connection.send(new ClientboundBundlePacket(list));
|
||||
Packet[] packetsRaw = list.elements();
|
||||
for (int i = 0, size = list.size(); i < size; i++) {
|
||||
connection.send(packetsRaw[i]);
|
||||
}
|
||||
if (connection instanceof ServerGamePacketListenerImpl conn) {
|
||||
conn.connection.flushChannel();
|
||||
if (flush && connection instanceof ServerGamePacketListenerImpl playerConnection) {
|
||||
playerConnection.connection.flushChannel();
|
||||
}
|
||||
}
|
||||
packets.clear();
|
||||
|
||||
Reference in New Issue
Block a user