minecraft-src/net/minecraft/server/waypoints/ServerWaypointManager.java
2025-09-18 12:27:44 +00:00

138 lines
4.7 KiB
Java

package net.minecraft.server.waypoints;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.collect.Table;
import com.google.common.collect.Tables;
import com.google.common.collect.Sets.SetView;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.waypoints.WaypointManager;
import net.minecraft.world.waypoints.WaypointTransmitter;
public class ServerWaypointManager implements WaypointManager<WaypointTransmitter> {
private final Set<WaypointTransmitter> waypoints = new HashSet();
private final Set<ServerPlayer> players = new HashSet();
private final Table<ServerPlayer, WaypointTransmitter, WaypointTransmitter.Connection> connections = HashBasedTable.create();
public void trackWaypoint(WaypointTransmitter waypoint) {
this.waypoints.add(waypoint);
for (ServerPlayer serverPlayer : this.players) {
this.createConnection(serverPlayer, waypoint);
}
}
public void updateWaypoint(WaypointTransmitter waypoint) {
if (this.waypoints.contains(waypoint)) {
Map<ServerPlayer, WaypointTransmitter.Connection> map = Tables.transpose(this.connections).row(waypoint);
SetView<ServerPlayer> setView = Sets.difference(this.players, map.keySet());
for (Entry<ServerPlayer, WaypointTransmitter.Connection> entry : ImmutableSet.copyOf(map.entrySet())) {
this.updateConnection((ServerPlayer)entry.getKey(), waypoint, (WaypointTransmitter.Connection)entry.getValue());
}
for (ServerPlayer serverPlayer : setView) {
this.createConnection(serverPlayer, waypoint);
}
}
}
public void untrackWaypoint(WaypointTransmitter waypoint) {
this.connections.column(waypoint).forEach((serverPlayer, connection) -> connection.disconnect());
Tables.transpose(this.connections).row(waypoint).clear();
this.waypoints.remove(waypoint);
}
public void addPlayer(ServerPlayer player) {
this.players.add(player);
for (WaypointTransmitter waypointTransmitter : this.waypoints) {
this.createConnection(player, waypointTransmitter);
}
if (player.isTransmittingWaypoint()) {
this.trackWaypoint((WaypointTransmitter)player);
}
}
public void updatePlayer(ServerPlayer player) {
Map<WaypointTransmitter, WaypointTransmitter.Connection> map = this.connections.row(player);
SetView<WaypointTransmitter> setView = Sets.difference(this.waypoints, map.keySet());
for (Entry<WaypointTransmitter, WaypointTransmitter.Connection> entry : ImmutableSet.copyOf(map.entrySet())) {
this.updateConnection(player, (WaypointTransmitter)entry.getKey(), (WaypointTransmitter.Connection)entry.getValue());
}
for (WaypointTransmitter waypointTransmitter : setView) {
this.createConnection(player, waypointTransmitter);
}
}
public void removePlayer(ServerPlayer player) {
this.connections.row(player).values().removeIf(connection -> {
connection.disconnect();
return true;
});
this.untrackWaypoint((WaypointTransmitter)player);
this.players.remove(player);
}
public void breakAllConnections() {
this.connections.values().forEach(WaypointTransmitter.Connection::disconnect);
this.connections.clear();
}
public void remakeConnections(WaypointTransmitter waypoint) {
for (ServerPlayer serverPlayer : this.players) {
this.createConnection(serverPlayer, waypoint);
}
}
public Set<WaypointTransmitter> transmitters() {
return this.waypoints;
}
private static boolean isLocatorBarEnabledFor(ServerPlayer player) {
return player.level().getServer().getGameRules().getBoolean(GameRules.RULE_LOCATOR_BAR);
}
private void createConnection(ServerPlayer player, WaypointTransmitter waypoint) {
if (player != waypoint) {
if (isLocatorBarEnabledFor(player)) {
waypoint.makeWaypointConnectionWith(player).ifPresentOrElse(connection -> {
this.connections.put(player, waypoint, connection);
connection.connect();
}, () -> {
WaypointTransmitter.Connection connection = this.connections.remove(player, waypoint);
if (connection != null) {
connection.disconnect();
}
});
}
}
}
private void updateConnection(ServerPlayer player, WaypointTransmitter waypoint, WaypointTransmitter.Connection connection) {
if (player != waypoint) {
if (isLocatorBarEnabledFor(player)) {
if (!connection.isBroken()) {
connection.update();
} else {
waypoint.makeWaypointConnectionWith(player).ifPresentOrElse(connectionx -> {
connectionx.connect();
this.connections.put(player, waypoint, connectionx);
}, () -> {
connection.disconnect();
this.connections.remove(player, waypoint);
});
}
}
}
}
}