Skip to content

Commit 7e34fba

Browse files
Owen1212055kennytv
authored andcommitted
feat: Optimize ServerWaypointManager when locator bar is disabled
The waypoint system iterates over each player for running waypoint calculations. This, most notably, is done on setPosRaw which is executed twice for each player (one for non players). This results in every time a player moves, it iterates over each player twice. So instead, we cache the game rule and instead use this to prevent iterating over all the players and avoid the redundant connection logic checks. This performance issue is most noticeable with many players on the same level.
1 parent 9d2db14 commit 7e34fba

4 files changed

Lines changed: 83 additions & 6 deletions

File tree

paper-server/patches/features/0001-Moonrise-optimisation-patches.patch

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23838,7 +23838,7 @@ index 3c1490ac7c259da04031db2f170e0c0a5f512191..470d7c770ae9d045b97e2df145cfe3cf
2383823838
}
2383923839
}
2384023840
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
23841-
index 54dc5f5898df9895c82bbc318d63d2f485bf9574..1b064f00c33712c3d2d85ed8520f1eda02abfbf9 100644
23841+
index 9566334f019ff3c9469f06c784d122b5d35f3e24..e11862c7e0617acfb36212cfe349bdade3a5164b 100644
2384223842
--- a/net/minecraft/server/MinecraftServer.java
2384323843
+++ b/net/minecraft/server/MinecraftServer.java
2384423844
@@ -191,7 +191,7 @@ import net.minecraft.world.scores.ScoreboardSaveData;
@@ -27004,7 +27004,7 @@ index de75dda2e6f17f0ae6e7f6a5620fd3eac9d389e5..6774d12d04fa848624fb8bf7a3c2b8bc
2700427004
List<Entity> passengers = this.entity.getPassengers();
2700527005
if (!passengers.equals(this.lastPassengers)) {
2700627006
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
27007-
index 71446ef19c560f67d22697941973326e2b81bb60..8c954add1949777b4f5658064eb7cd381d542140 100644
27007+
index d0742abe193dfd8eeeea69a53f78d809d26efabe..96e45eab1e8cf857f5068e911070259866d8bdcb 100644
2700827008
--- a/net/minecraft/server/level/ServerLevel.java
2700927009
+++ b/net/minecraft/server/level/ServerLevel.java
2701027010
@@ -182,7 +182,7 @@ import net.minecraft.world.waypoints.WaypointTransmitter;
@@ -27400,7 +27400,7 @@ index 71446ef19c560f67d22697941973326e2b81bb60..8c954add1949777b4f5658064eb7cd38
2740027400
, savedDataStorage // Paper - initialize SavedDataStorage earlier
2740127401
);
2740227402
@@ -471,6 +715,20 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
27403-
this.waypointManager = new ServerWaypointManager();
27403+
this.waypointManager = new ServerWaypointManager(this); // Paper - optimize ServerWaypointManager with locator bar disabled
2740427404
this.environmentAttributes = EnvironmentAttributeSystem.builder().addDefaultLayers(this).build();
2740527405
this.updateSkyBrightness();
2740627406
+ // Paper start - rewrite chunk system

paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1533,7 +1533,7 @@
15331533
player.connection.send(new ClientboundEntityEventPacket(player, event));
15341534
}
15351535
} else if (rule == GameRules.LIMITED_CRAFTING || rule == GameRules.IMMEDIATE_RESPAWN) {
1536-
@@ -2131,19 +_,20 @@
1536+
@@ -2131,19 +_,21 @@
15371537
? ClientboundGameEventPacket.LIMITED_CRAFTING
15381538
: ClientboundGameEventPacket.IMMEDIATE_RESPAWN;
15391539
ClientboundGameEventPacket packet = new ClientboundGameEventPacket(eventType, (Boolean)value ? 1.0F : 0.0F);
@@ -1543,6 +1543,7 @@
15431543
- this.getAllLevels().forEach(level -> {
15441544
+ // this.getAllLevels().forEach(level -> { // Paper - per-world game rules
15451545
ServerWaypointManager waypointManager = level.getWaypointManager();
1546+
+ waypointManager.locatorBarEnabled = (Boolean) value; // Paper - optimize ServerWaypointManager with locator bar disabled
15461547
if ((Boolean)value) {
15471548
level.players().forEach(waypointManager::updatePlayer);
15481549
} else {

paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,12 @@
241241
generator,
242242
this.chunkSource.randomState(),
243243
this,
244-
@@ -303,7 +_,15 @@
245-
this.waypointManager = new ServerWaypointManager();
244+
@@ -300,10 +_,18 @@
245+
246+
this.sleepStatus = new SleepStatus();
247+
this.gameEventDispatcher = new GameEventDispatcher(this);
248+
- this.waypointManager = new ServerWaypointManager();
249+
+ this.waypointManager = new ServerWaypointManager(this); // Paper - optimize ServerWaypointManager with locator bar disabled
246250
this.environmentAttributes = EnvironmentAttributeSystem.builder().addDefaultLayers(this).build();
247251
this.updateSkyBrightness();
248252
- }
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
--- a/net/minecraft/server/waypoints/ServerWaypointManager.java
2+
+++ b/net/minecraft/server/waypoints/ServerWaypointManager.java
3+
@@ -19,11 +_,19 @@
4+
private final Set<WaypointTransmitter> waypoints = new HashSet<>();
5+
private final Set<ServerPlayer> players = new HashSet<>();
6+
private final Table<ServerPlayer, WaypointTransmitter, WaypointTransmitter.Connection> connections = HashBasedTable.create();
7+
+ // Paper start - optimize ServerWaypointManager with locator bar disabled
8+
+ public boolean locatorBarEnabled; // Avoid a gamerule lookup for each player
9+
+
10+
+ public ServerWaypointManager(net.minecraft.server.level.ServerLevel serverLevel) {
11+
+ this.locatorBarEnabled = serverLevel.getGameRules().get(GameRules.LOCATOR_BAR);
12+
+ }
13+
+ // Paper end - optimize ServerWaypointManager with locator bar disabled
14+
15+
@Override
16+
public void trackWaypoint(final WaypointTransmitter waypoint) {
17+
this.waypoints.add(waypoint);
18+
19+
+ if (!this.locatorBarEnabled) return; // Paper - optimize ServerWaypointManager with locator bar disabled
20+
for (ServerPlayer player : this.players) {
21+
this.createConnection(player, waypoint);
22+
}
23+
@@ -31,6 +_,7 @@
24+
25+
@Override
26+
public void updateWaypoint(final WaypointTransmitter waypoint) {
27+
+ if (!this.locatorBarEnabled) return; // Paper - optimize ServerWaypointManager with locator bar disabled
28+
if (this.waypoints.contains(waypoint)) {
29+
Map<ServerPlayer, WaypointTransmitter.Connection> playerConnection = Tables.transpose(this.connections).row(waypoint);
30+
SetView<ServerPlayer> potentialPlayers = Sets.difference(this.players, playerConnection.keySet());
31+
@@ -55,9 +_,11 @@
32+
public void addPlayer(final ServerPlayer player) {
33+
this.players.add(player);
34+
35+
+ if (this.locatorBarEnabled) { // Paper - optimize ServerWaypointManager with locator bar disabled
36+
for (WaypointTransmitter waypoint : this.waypoints) {
37+
this.createConnection(player, waypoint);
38+
}
39+
+ } // Paper - optimize ServerWaypointManager with locator bar disabled
40+
41+
if (player.isTransmittingWaypoint()) {
42+
this.trackWaypoint((WaypointTransmitter)player);
43+
@@ -65,6 +_,7 @@
44+
}
45+
46+
public void updatePlayer(final ServerPlayer player) {
47+
+ if (!this.locatorBarEnabled) return; // Paper - optimize ServerWaypointManager with locator bar disabled
48+
Map<WaypointTransmitter, WaypointTransmitter.Connection> waypointConnections = this.connections.row(player);
49+
SetView<WaypointTransmitter> potentialWaypoints = Sets.difference(this.waypoints, waypointConnections.keySet());
50+
51+
@@ -92,6 +_,7 @@
52+
}
53+
54+
public void remakeConnections(final WaypointTransmitter waypoint) {
55+
+ if (!this.locatorBarEnabled) return; // Paper - optimize ServerWaypointManager with locator bar disabled
56+
for (ServerPlayer player : this.players) {
57+
this.createConnection(player, waypoint);
58+
}
59+
@@ -101,8 +_,11 @@
60+
return this.waypoints;
61+
}
62+
63+
- private static boolean isLocatorBarEnabledFor(final ServerPlayer player) {
64+
- return player.level().getGameRules().get(GameRules.LOCATOR_BAR);
65+
+ // Paper start - optimize ServerWaypointManager with locator bar disabled
66+
+ // Avoid a gamerule lookup for each player
67+
+ private boolean isLocatorBarEnabledFor(final ServerPlayer player) {
68+
+ return locatorBarEnabled;
69+
+ // Paper end - optimize ServerWaypointManager with locator bar disabled
70+
}
71+
72+
private void createConnection(final ServerPlayer player, final WaypointTransmitter waypoint) {

0 commit comments

Comments
 (0)