64 lines
3.5 KiB
Diff
64 lines
3.5 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Aikar <aikar@aikar.co>
|
|
Date: Sat, 23 May 2020 17:03:41 -0400
|
|
Subject: [PATCH] Optimize sending packets to nearby locations (sounds/effects)
|
|
|
|
Instead of using the entire world or player list, use the distance
|
|
maps to only iterate players who are even seeing the chunk the packet
|
|
is originating from.
|
|
|
|
This will drastically cut down on packet sending cost for worlds with
|
|
lots of players in them.
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
|
index c2cc59f476a67224774503009439fec2ad1ec62d..54cbcea8e3eb4d2fdeced2ebc3c4819af429da9d 100644
|
|
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
|
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
|
@@ -1134,16 +1134,40 @@ public abstract class PlayerList {
|
|
}
|
|
|
|
public void broadcast(@Nullable net.minecraft.world.entity.player.Player player, double x, double y, double z, double distance, ResourceKey<Level> worldKey, Packet<?> packet) {
|
|
- for (int i = 0; i < this.players.size(); ++i) {
|
|
- ServerPlayer entityplayer = (ServerPlayer) this.players.get(i);
|
|
+ ServerLevel world = null;
|
|
+ if (player != null && player.level instanceof ServerLevel) {
|
|
+ world = (ServerLevel) player.level;
|
|
+ }
|
|
|
|
- // CraftBukkit start - Test if player receiving packet can see the source of the packet
|
|
- if (player != null && player instanceof ServerPlayer && !entityplayer.getBukkitEntity().canSee(((ServerPlayer) player).getBukkitEntity())) {
|
|
- continue;
|
|
+ // Paper start
|
|
+ if (world == null) {
|
|
+ world = server.getLevel(worldKey);
|
|
+ }
|
|
+ net.minecraft.server.level.ChunkMap chunkMap = world != null ? world.getChunkSource().chunkMap : null;
|
|
+ Object[] backingSet;
|
|
+ if (chunkMap == null) {
|
|
+ // Really shouldn't happen...
|
|
+ backingSet = world != null ? world.players.toArray() : players.toArray();
|
|
+ } else {
|
|
+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> nearbyPlayers = chunkMap.playerViewDistanceBroadcastMap.getObjectsInRange(MCUtil.fastFloor(x) >> 4, MCUtil.fastFloor(z) >> 4);
|
|
+ if (nearbyPlayers == null) {
|
|
+ return;
|
|
}
|
|
+ backingSet = nearbyPlayers.getBackingSet();
|
|
+ }
|
|
+
|
|
+ for (Object object : backingSet) {
|
|
+ if (!(object instanceof ServerPlayer)) continue;
|
|
+ ServerPlayer entityplayer = (ServerPlayer) object;
|
|
+ // Paper end
|
|
+
|
|
+ // CraftBukkit start - Test if player receiving packet can see the source of the packet
|
|
+ //if (entityhuman != null && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) { // Paper
|
|
+ //continue; // Paper
|
|
+ //} // Paper
|
|
// CraftBukkit end
|
|
|
|
- if (entityplayer != player && entityplayer.level.dimension() == worldKey) {
|
|
+ if (entityplayer != player && entityplayer.level.dimension() == worldKey && (!(player instanceof ServerPlayer) || entityplayer.getBukkitEntity().canSee(((ServerPlayer) player).getBukkitEntity()))) { // Paper
|
|
double d4 = x - entityplayer.getX();
|
|
double d5 = y - entityplayer.getY();
|
|
double d6 = z - entityplayer.getZ();
|