forked from Upstream/Velocitab
Reduce number of packets being sent, adjust logic
This commit is contained in:
parent
de747bf3eb
commit
0a39899705
@ -48,7 +48,7 @@ public class LuckPermsHook {
|
||||
|
||||
public void onLuckPermsGroupUpdate(@NotNull UserDataRecalculateEvent event) {
|
||||
plugin.getServer().getPlayer(event.getUser().getUniqueId())
|
||||
.ifPresent(player -> plugin.getTabList().updatePlayer(new TabPlayer(
|
||||
.ifPresent(player -> plugin.getTabList().onPlayerRoleUpdate(new TabPlayer(
|
||||
player,
|
||||
getRoleFromMetadata(event.getData().getMetaData()),
|
||||
getHighestWeight()
|
||||
@ -80,5 +80,4 @@ public class LuckPermsHook {
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -5,21 +5,54 @@ import dev.simplix.protocolize.api.PacketDirection;
|
||||
import dev.simplix.protocolize.api.Protocol;
|
||||
import dev.simplix.protocolize.api.Protocolize;
|
||||
import net.william278.velocitab.Velocitab;
|
||||
import net.william278.velocitab.player.TabPlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ScoreboardManager {
|
||||
|
||||
private final Velocitab plugin;
|
||||
|
||||
private final ConcurrentHashMap<UUID, String> fauxTeams;
|
||||
private final Map<UUID, List<String>> createdTeams;
|
||||
private final Map<UUID, Map<String, String>> roleMappings;
|
||||
|
||||
public ScoreboardManager(@NotNull Velocitab velocitab) {
|
||||
this.plugin = velocitab;
|
||||
this.fauxTeams = new ConcurrentHashMap<>();
|
||||
this.createdTeams = new HashMap<>();
|
||||
this.roleMappings = new HashMap<>();
|
||||
}
|
||||
|
||||
public void resetCache(@NotNull Player player) {
|
||||
createdTeams.remove(player.getUniqueId());
|
||||
roleMappings.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
public void sendTeamPackets(@NotNull Player player, @NotNull Map<Player, String> playerRoles) {
|
||||
playerRoles.entrySet().stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
Map.Entry::getValue,
|
||||
Collectors.mapping(entry -> entry.getKey().getUsername(), Collectors.toList())
|
||||
))
|
||||
.forEach((role, players) -> updateRoles(player, role, players.toArray(new String[0])));
|
||||
}
|
||||
|
||||
public void updateRoles(@NotNull Player player, @NotNull String role, @NotNull String... playerNames) {
|
||||
if (!createdTeams.getOrDefault(player.getUniqueId(), List.of()).contains(role)) {
|
||||
dispatchPacket(UpdateTeamsPacket.create(role, playerNames), player);
|
||||
createdTeams.computeIfAbsent(player.getUniqueId(), k -> new ArrayList<>()).add(role);
|
||||
} else {
|
||||
roleMappings.getOrDefault(player.getUniqueId(), Map.of())
|
||||
.entrySet().stream()
|
||||
.filter((entry) -> List.of(playerNames).contains(entry.getKey()))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))
|
||||
.forEach((playerName, oldRole) -> dispatchPacket(UpdateTeamsPacket.removeFromTeam(oldRole, playerName), player));
|
||||
dispatchPacket(UpdateTeamsPacket.addToTeam(role, playerNames), player);
|
||||
roleMappings.computeIfAbsent(player.getUniqueId(), k -> new HashMap<>()).put(player.getUsername(), role);
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchPacket(@NotNull UpdateTeamsPacket packet, @NotNull Player player) {
|
||||
Protocolize.playerProvider().player(player.getUniqueId()).sendPacket(packet);
|
||||
}
|
||||
|
||||
public void registerPacket() {
|
||||
@ -35,40 +68,5 @@ public class ScoreboardManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void setPlayerTeam(@NotNull TabPlayer player) {
|
||||
removeTeam(player.getPlayer());
|
||||
createTeam(player.getTeamName(), player.getPlayer());
|
||||
}
|
||||
|
||||
private void createTeam(@NotNull String teamName, @NotNull Player member) {
|
||||
final UUID uuid = member.getUniqueId();
|
||||
try {
|
||||
final UpdateTeamsPacket createTeamPacket = UpdateTeamsPacket.create(teamName, member.getUsername());
|
||||
fauxTeams.put(uuid, teamName);
|
||||
plugin.getServer().getAllPlayers().stream()
|
||||
.map(Player::getUniqueId)
|
||||
.map(Protocolize.playerProvider()::player)
|
||||
.forEach(protocolPlayer -> protocolPlayer.sendPacket(createTeamPacket));
|
||||
} catch (Exception e) {
|
||||
plugin.log("Skipped setting team for " + member.getUsername());
|
||||
}
|
||||
}
|
||||
|
||||
public void removeTeam(@NotNull Player member) {
|
||||
final UUID uuid = member.getUniqueId();
|
||||
try {
|
||||
final String teamName = fauxTeams.getOrDefault(uuid, null);
|
||||
if (teamName != null) {
|
||||
final UpdateTeamsPacket removeTeamPacket = UpdateTeamsPacket.remove(teamName);
|
||||
plugin.getServer().getAllPlayers().stream()
|
||||
.map(Player::getUniqueId)
|
||||
.map(Protocolize.playerProvider()::player)
|
||||
.forEach(protocolPlayer -> protocolPlayer.sendPacket(removeTeamPacket));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
plugin.log("Skipped removing team for " + member.getUsername());
|
||||
}
|
||||
fauxTeams.remove(uuid);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ public class UpdateTeamsPacket extends AbstractPacket {
|
||||
private List<String> entities;
|
||||
|
||||
@NotNull
|
||||
public static UpdateTeamsPacket create(@NotNull String teamName, @NotNull String member) {
|
||||
public static UpdateTeamsPacket create(@NotNull String teamName, @NotNull String... teamMembers) {
|
||||
return new UpdateTeamsPacket()
|
||||
.teamName(teamName.length() > 16 ? teamName.substring(0, 16) : teamName)
|
||||
.mode(UpdateMode.CREATE_TEAM)
|
||||
@ -56,14 +56,23 @@ public class UpdateTeamsPacket extends AbstractPacket {
|
||||
.color(15)
|
||||
.prefix(getChatString(""))
|
||||
.suffix(getChatString(""))
|
||||
.entities(List.of(member));
|
||||
.entities(Arrays.asList(teamMembers));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static UpdateTeamsPacket remove(@NotNull String teamName) {
|
||||
public static UpdateTeamsPacket addToTeam(@NotNull String teamName, @NotNull String... teamMembers) {
|
||||
return new UpdateTeamsPacket()
|
||||
.teamName(teamName.length() > 16 ? teamName.substring(0, 16) : teamName)
|
||||
.mode(UpdateMode.REMOVE_TEAM);
|
||||
.mode(UpdateMode.ADD_PLAYERS)
|
||||
.entities(Arrays.asList(teamMembers));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static UpdateTeamsPacket removeFromTeam(@NotNull String teamName, @NotNull String... teamMembers) {
|
||||
return new UpdateTeamsPacket()
|
||||
.teamName(teamName.length() > 16 ? teamName.substring(0, 16) : teamName)
|
||||
.mode(UpdateMode.REMOVE_PLAYERS)
|
||||
.entities(Arrays.asList(teamMembers));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -41,7 +41,7 @@ public class Role implements Comparable<Role> {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getStringComparableWeight(int highestWeight) {
|
||||
protected String getWeightString(int highestWeight) {
|
||||
return String.format("%0" + (highestWeight + "").length() + "d", highestWeight - weight);
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ public final class TabPlayer implements Comparable<TabPlayer> {
|
||||
|
||||
@NotNull
|
||||
public String getTeamName() {
|
||||
return role.getStringComparableWeight(highestWeight) + "-" + getServerName() + "-" + player.getUsername();
|
||||
return role.getWeightString(highestWeight) + role.getName().map(name -> "-" + name).orElse("");
|
||||
}
|
||||
|
||||
public void sendHeaderAndFooter(@NotNull PlayerTabList tabList) {
|
||||
|
@ -1,11 +1,11 @@
|
||||
package net.william278.velocitab.tab;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
||||
import com.velocitypowered.api.event.player.ServerPostConnectEvent;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.api.proxy.ServerConnection;
|
||||
import com.velocitypowered.api.proxy.player.TabList;
|
||||
import com.velocitypowered.api.proxy.player.TabListEntry;
|
||||
import com.velocitypowered.api.proxy.server.ServerInfo;
|
||||
import de.themoep.minedown.adventure.MineDown;
|
||||
@ -15,7 +15,8 @@ import net.william278.velocitab.config.Placeholder;
|
||||
import net.william278.velocitab.player.TabPlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -32,6 +33,8 @@ public class PlayerTabList {
|
||||
@Subscribe
|
||||
public void onPlayerJoin(@NotNull ServerPostConnectEvent event) {
|
||||
final Player joined = event.getPlayer();
|
||||
plugin.getScoreboardManager().resetCache(joined);
|
||||
|
||||
// Remove the player from the tracking list if they are switching servers
|
||||
if (event.getPreviousServer() == null) {
|
||||
players.removeIf(player -> player.getPlayer().getUniqueId().equals(joined.getUniqueId()));
|
||||
@ -46,14 +49,61 @@ public class PlayerTabList {
|
||||
}
|
||||
|
||||
// Add the player to the tracking list
|
||||
players.add(plugin.getTabPlayer(joined));
|
||||
final TabPlayer tabPlayer = plugin.getTabPlayer(joined);
|
||||
players.add(tabPlayer);
|
||||
|
||||
// Update the tab list of all players
|
||||
plugin.getServer().getScheduler().buildTask(plugin, this::updateList)
|
||||
// Update lists
|
||||
plugin.getServer().getScheduler()
|
||||
.buildTask(plugin, () -> {
|
||||
final TabList tabList = joined.getTabList();
|
||||
final Map<Player, String> playerRoles = new HashMap<>();
|
||||
players.forEach(player -> {
|
||||
playerRoles.put(player.getPlayer(), tabPlayer.getTeamName());
|
||||
tabList.getEntries().stream()
|
||||
.filter(e -> e.getProfile().getId().equals(player.getPlayer().getUniqueId())).findFirst()
|
||||
.ifPresentOrElse(
|
||||
entry -> entry.setDisplayName(player.getDisplayName(plugin)),
|
||||
() -> tabList.addEntry(createEntry(player, tabList))
|
||||
);
|
||||
addPlayerToTabList(player, tabPlayer);
|
||||
player.sendHeaderAndFooter(this);
|
||||
});
|
||||
plugin.getScoreboardManager().sendTeamPackets(joined, playerRoles);
|
||||
})
|
||||
.delay(500, TimeUnit.MILLISECONDS)
|
||||
.schedule();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private TabListEntry createEntry(@NotNull TabPlayer player, @NotNull TabList tabList) {
|
||||
return TabListEntry.builder()
|
||||
.profile(player.getPlayer().getGameProfile())
|
||||
.displayName(player.getDisplayName(plugin))
|
||||
.latency(0)
|
||||
.tabList(tabList)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void addPlayerToTabList(@NotNull TabPlayer player, @NotNull TabPlayer newPlayer) {
|
||||
if (newPlayer.getPlayer().getUniqueId().equals(player.getPlayer().getUniqueId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
player.getPlayer()
|
||||
.getTabList().getEntries().stream()
|
||||
.filter(e -> e.getProfile().getId().equals(newPlayer.getPlayer().getUniqueId())).findFirst()
|
||||
.ifPresentOrElse(
|
||||
entry -> entry.setDisplayName(newPlayer.getDisplayName(plugin)),
|
||||
() -> player.getPlayer().getTabList()
|
||||
.addEntry(createEntry(newPlayer, player.getPlayer().getTabList()))
|
||||
);
|
||||
plugin.getScoreboardManager().updateRoles(
|
||||
player.getPlayer(),
|
||||
newPlayer.getTeamName(),
|
||||
newPlayer.getPlayer().getUsername()
|
||||
);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onPlayerQuit(@NotNull DisconnectEvent event) {
|
||||
// Remove the player from the tracking list
|
||||
@ -63,56 +113,26 @@ public class PlayerTabList {
|
||||
plugin.getServer().getAllPlayers().forEach(player -> player.getTabList().removeEntry(event.getPlayer().getUniqueId()));
|
||||
|
||||
// Update the tab list of all players
|
||||
plugin.getServer().getScheduler().buildTask(plugin, () -> {
|
||||
plugin.getScoreboardManager().removeTeam(event.getPlayer());
|
||||
updateList();
|
||||
})
|
||||
.delay(500, TimeUnit.MILLISECONDS)
|
||||
.schedule();
|
||||
}
|
||||
|
||||
public void updatePlayer(@NotNull TabPlayer tabPlayer) {
|
||||
plugin.getServer().getScheduler()
|
||||
.buildTask(plugin, () -> {
|
||||
// Update the player's team sorting
|
||||
players.remove(tabPlayer);
|
||||
players.add(tabPlayer);
|
||||
|
||||
plugin.getScoreboardManager().setPlayerTeam(tabPlayer);
|
||||
|
||||
updateList();
|
||||
})
|
||||
.buildTask(plugin, () -> players.forEach(player -> {
|
||||
player.getPlayer().getTabList().removeEntry(event.getPlayer().getUniqueId());
|
||||
player.sendHeaderAndFooter(this);
|
||||
}))
|
||||
.delay(500, TimeUnit.MILLISECONDS)
|
||||
.schedule();
|
||||
}
|
||||
|
||||
private void updateList() {
|
||||
final ImmutableList<TabPlayer> players = ImmutableList.copyOf(this.players);
|
||||
players.forEach(player -> {
|
||||
player.sendHeaderAndFooter(this);
|
||||
|
||||
// Fill the tab list with the players
|
||||
players.forEach(listedPlayer -> {
|
||||
final Optional<TabListEntry> current = player.getPlayer().getTabList().getEntries().stream()
|
||||
.filter(entry -> entry.getProfile().getId().equals(listedPlayer.getPlayer().getUniqueId()))
|
||||
.findFirst();
|
||||
current.ifPresentOrElse(
|
||||
entry -> entry.setDisplayName(listedPlayer.getDisplayName(plugin)),
|
||||
() -> player.getPlayer().getTabList().addEntry(TabListEntry.builder()
|
||||
.profile(listedPlayer.getPlayer().getGameProfile())
|
||||
.displayName(listedPlayer.getDisplayName(plugin))
|
||||
.latency(0)
|
||||
.tabList(player.getPlayer().getTabList())
|
||||
.build()));
|
||||
plugin.getScoreboardManager().setPlayerTeam(listedPlayer);
|
||||
});
|
||||
|
||||
// Remove players in the tab list that are not in the players list
|
||||
player.getPlayer().getTabList().getEntries().stream()
|
||||
.filter(entry -> players.stream()
|
||||
.noneMatch(listedPlayer -> listedPlayer.getPlayer().getUniqueId().equals(entry.getProfile().getId())))
|
||||
.forEach(entry -> player.getPlayer().getTabList().removeEntry(entry.getProfile().getId()));
|
||||
});
|
||||
public void onPlayerRoleUpdate(@NotNull TabPlayer tabPlayer) {
|
||||
plugin.getServer().getScheduler()
|
||||
.buildTask(plugin, () -> players.forEach(player -> {
|
||||
player.getPlayer().getTabList().getEntries().stream()
|
||||
.filter(e -> e.getProfile().getId().equals(tabPlayer.getPlayer().getUniqueId())).findFirst()
|
||||
.ifPresent(entry -> entry.setDisplayName(tabPlayer.getDisplayName(plugin)));
|
||||
plugin.getScoreboardManager().updateRoles(player.getPlayer(),
|
||||
tabPlayer.getTeamName(), tabPlayer.getPlayer().getUsername());
|
||||
}))
|
||||
.delay(500, TimeUnit.MILLISECONDS)
|
||||
.schedule();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
Loading…
Reference in New Issue
Block a user