Skip to content

Commit 575630f

Browse files
committed
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 3d1da60 commit 575630f

3 files changed

Lines changed: 80 additions & 3 deletions

File tree

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);
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)