Fixed problem when isRemoveNametags is true

Improved performance caching reflection fields
This commit is contained in:
AlexDev_ 2024-11-19 16:26:29 +01:00
parent 67931d8d41
commit 6c558fac3a
2 changed files with 35 additions and 7 deletions

View File

@ -152,7 +152,7 @@ public class ScoreboardManager {
return; return;
} }
final Set<RegisteredServer> siblings = tabPlayer.getGroup().registeredServers(plugin); final Set<RegisteredServer> siblings = tabPlayer.getGroup().registeredServers(plugin);
final boolean isNameTagEmpty = tabPlayer.getGroup().nametag().isEmpty(); final boolean isNameTagEmpty = tabPlayer.getGroup().nametag().isEmpty() && !plugin.getSettings().isRemoveNametags();
final Optional<Nametag> cachedTag = Optional.ofNullable(nametags.getOrDefault(teamName, null)); final Optional<Nametag> cachedTag = Optional.ofNullable(nametags.getOrDefault(teamName, null));
cachedTag.ifPresent(nametag -> siblings.forEach(server -> server.getPlayersConnected().stream().filter(p -> p != player) cachedTag.ifPresent(nametag -> siblings.forEach(server -> server.getPlayersConnected().stream().filter(p -> p != player)
@ -304,7 +304,7 @@ public class ScoreboardManager {
final UpdateTeamsPacket packet = UpdateTeamsPacket.create(plugin, tabPlayer, teamName, nametag, viewer, teamMembers); final UpdateTeamsPacket packet = UpdateTeamsPacket.create(plugin, tabPlayer, teamName, nametag, viewer, teamMembers);
trackedTeams.put(viewer.getPlayer().getUniqueId(), teamName); trackedTeams.put(viewer.getPlayer().getUniqueId(), teamName);
final boolean isNameTagEmpty = tabPlayer.getGroup().nametag().isEmpty(); final boolean isNameTagEmpty = tabPlayer.getGroup().nametag().isEmpty() && !plugin.getSettings().isRemoveNametags();
sendPacket(viewer.getPlayer(), packet, isNameTagEmpty); sendPacket(viewer.getPlayer(), packet, isNameTagEmpty);
} }
@ -314,7 +314,7 @@ public class ScoreboardManager {
if (!teams) { if (!teams) {
return; return;
} }
final boolean isNameTagEmpty = tabPlayer.getGroup().nametag().isEmpty(); final boolean isNameTagEmpty = tabPlayer.getGroup().nametag().isEmpty() && !plugin.getSettings().isRemoveNametags();
tabPlayer.getGroup().getTabPlayers(plugin, tabPlayer).forEach(viewer -> { tabPlayer.getGroup().getTabPlayers(plugin, tabPlayer).forEach(viewer -> {
if (viewer == tabPlayer || !viewer.getPlayer().isActive()) { if (viewer == tabPlayer || !viewer.getPlayer().isActive()) {
return; return;
@ -373,7 +373,7 @@ public class ScoreboardManager {
} }
final Set<Player> players = tabPlayer.getGroup().getPlayers(plugin); final Set<Player> players = tabPlayer.getGroup().getPlayers(plugin);
final boolean isNameTagEmpty = tabPlayer.getGroup().nametag().isEmpty(); final boolean isNameTagEmpty = tabPlayer.getGroup().nametag().isEmpty() && !plugin.getSettings().isRemoveNametags();
players.forEach(connected -> { players.forEach(connected -> {
try { try {
final boolean canSee = plugin.getVanishManager().canSee(connected.getUsername(), player.getUsername()); final boolean canSee = plugin.getVanishManager().canSee(connected.getUsername(), player.getUsername());
@ -459,7 +459,7 @@ public class ScoreboardManager {
} }
final UpdateTeamsPacket removeTeam = UpdateTeamsPacket.removeTeam(plugin, team); final UpdateTeamsPacket removeTeam = UpdateTeamsPacket.removeTeam(plugin, team);
final boolean isNameTagEmpty = tabPlayer.getGroup().nametag().isEmpty(); final boolean isNameTagEmpty = tabPlayer.getGroup().nametag().isEmpty() && !plugin.getSettings().isRemoveNametags();
sendPacket(player, removeTeam, isNameTagEmpty); sendPacket(player, removeTeam, isNameTagEmpty);
trackedTeams.remove(player.getUniqueId(), team); trackedTeams.remove(player.getUniqueId(), team);

View File

@ -28,6 +28,8 @@ import com.velocitypowered.api.proxy.player.TabListEntry;
import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.proxy.connection.client.ConnectedPlayer; import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
import com.velocitypowered.proxy.protocol.packet.UpsertPlayerInfoPacket; import com.velocitypowered.proxy.protocol.packet.UpsertPlayerInfoPacket;
import com.velocitypowered.proxy.tablist.KeyedVelocityTabList;
import com.velocitypowered.proxy.tablist.VelocityTabList;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -62,15 +64,38 @@ public class PlayerTabList {
@Getter(value = AccessLevel.PUBLIC) @Getter(value = AccessLevel.PUBLIC)
private final Map<UUID, TabPlayer> players; private final Map<UUID, TabPlayer> players;
private final TaskManager taskManager; private final TaskManager taskManager;
private final Map<Class<?>, Field> entriesFields;
public PlayerTabList(@NotNull Velocitab plugin) { public PlayerTabList(@NotNull Velocitab plugin) {
this.plugin = plugin; this.plugin = plugin;
this.vanishTabList = new VanishTabList(plugin, this); this.vanishTabList = new VanishTabList(plugin, this);
this.players = Maps.newConcurrentMap(); this.players = Maps.newConcurrentMap();
this.taskManager = new TaskManager(plugin); this.taskManager = new TaskManager(plugin);
this.entriesFields = Maps.newHashMap();
this.reloadUpdate(); this.reloadUpdate();
this.registerListener(); this.registerListener();
this.ensureDisplayNameTask(); this.ensureDisplayNameTask();
this.registerFields();
}
// VelocityTabListLegacy is not supported
private void registerFields() {
final Class<KeyedVelocityTabList> keyedVelocityTabListClass = KeyedVelocityTabList.class;
final Class<VelocityTabList> velocityTabListClass = VelocityTabList.class;
try {
final Field entriesField = keyedVelocityTabListClass.getDeclaredField("entries");
entriesField.setAccessible(true);
this.entriesFields.put(keyedVelocityTabListClass, entriesField);
} catch (NoSuchFieldException e) {
plugin.log(Level.ERROR, "Failed to register KeyedVelocityTabList field", e);
}
try {
final Field entriesField = velocityTabListClass.getDeclaredField("entries");
entriesField.setAccessible(true);
this.entriesFields.put(velocityTabListClass, entriesField);
} catch (NoSuchFieldException e) {
plugin.log(Level.ERROR, "Failed to register VelocityTabList field", e);
}
} }
private void registerListener() { private void registerListener() {
@ -275,8 +300,11 @@ public class PlayerTabList {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void fixDuplicateEntries(@NotNull Player target) { private void fixDuplicateEntries(@NotNull Player target) {
try { try {
final Field entriesField = target.getTabList().getClass().getDeclaredField("entries"); final Optional<Field> optionalField = Optional.ofNullable(this.entriesFields.get(target.getTabList().getClass()));
entriesField.setAccessible(true); if (optionalField.isEmpty()) {
return;
}
final Field entriesField = optionalField.get();
final Map<UUID, TabListEntry> entries = (Map<UUID, TabListEntry>) entriesField.get(target.getTabList()); final Map<UUID, TabListEntry> entries = (Map<UUID, TabListEntry>) entriesField.get(target.getTabList());
entries.entrySet().stream() entries.entrySet().stream()
.filter(entry -> entry.getValue().getProfile() != null) .filter(entry -> entry.getValue().getProfile() != null)