forked from Upstream/Velocitab
Fix for various problems (#119)
* Fixed logic problems with vanish + added tab recalculate system when luckperms fires UserDataRecalculateEvent * Fix for https://github.com/WiIIiam278/Velocitab/issues/120 . Fix for rgb nametags with legacy formatter. Fix for players with escape characters in their name. Fix for when a player is kicked from a server while staying online, tablist wasn't updated for that player. Fix for vanish, wrong variable used. Fix for negative values as input for tab sorting, min value is now 0.
This commit is contained in:
parent
e4df93ca3f
commit
2becf43845
@ -77,7 +77,12 @@ public enum Placeholder {
|
||||
}
|
||||
|
||||
return plugin.getPAPIProxyBridgeHook()
|
||||
.map(hook -> hook.formatPlaceholders(replaced, player.getPlayer()))
|
||||
.map(hook -> hook.formatPlaceholders(replaced, player.getPlayer())
|
||||
.exceptionally(e -> {
|
||||
plugin.log(Level.ERROR, "An error occurred whilst parsing placeholders: " + e.getMessage());
|
||||
return replaced;
|
||||
})
|
||||
)
|
||||
.orElse(CompletableFuture.completedFuture(replaced)).exceptionally(e -> {
|
||||
plugin.log(Level.ERROR, "An error occurred whilst parsing placeholders: " + e.getMessage());
|
||||
return replaced;
|
||||
|
@ -89,9 +89,17 @@ public class LuckPermsHook extends Hook {
|
||||
plugin.getServer().getPlayer(event.getUser().getUniqueId())
|
||||
.ifPresent(player -> plugin.getServer().getScheduler()
|
||||
.buildTask(plugin, () -> {
|
||||
final TabPlayer tabPlayer = tabList.getTabPlayer(player).orElseThrow();
|
||||
final Optional<TabPlayer> tabPlayerOptional = tabList.getTabPlayer(player);
|
||||
if (tabPlayerOptional.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final TabPlayer tabPlayer = tabPlayerOptional.get();
|
||||
final Role oldRole = tabPlayer.getRole();
|
||||
tabPlayer.setRole(getRoleFromMetadata(event.getData().getMetaData()));
|
||||
tabList.updatePlayerDisplayName(tabPlayer);
|
||||
tabList.recalculateVanishForPlayer(tabPlayer);
|
||||
checkRoleUpdate(tabPlayer, oldRole);
|
||||
})
|
||||
.delay(500, TimeUnit.MILLISECONDS)
|
||||
.schedule());
|
||||
@ -114,5 +122,12 @@ public class LuckPermsHook extends Hook {
|
||||
return api.getUserManager().getUser(uuid);
|
||||
}
|
||||
|
||||
private void checkRoleUpdate(@NotNull TabPlayer player, @NotNull Role oldRole) {
|
||||
if (oldRole.equals(player.getRole())) {
|
||||
return;
|
||||
}
|
||||
plugin.getTabList().updatePlayer(player);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ package net.william278.velocitab.packet;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.william278.velocitab.Velocitab;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -35,8 +36,8 @@ import java.util.Set;
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public class Protocol340Adapter extends TeamsPacketAdapter {
|
||||
|
||||
public Protocol340Adapter() {
|
||||
super(Set.of(ProtocolVersion.MINECRAFT_1_12_2));
|
||||
public Protocol340Adapter(@NotNull Velocitab plugin) {
|
||||
super(plugin, Set.of(ProtocolVersion.MINECRAFT_1_12_2));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -23,6 +23,11 @@ package net.william278.velocitab.packet;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import net.william278.velocitab.Velocitab;
|
||||
import net.william278.velocitab.config.Formatter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -35,8 +40,8 @@ import java.util.Set;
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public class Protocol403Adapter extends TeamsPacketAdapter {
|
||||
|
||||
public Protocol403Adapter() {
|
||||
super(Set.of(ProtocolVersion.MINECRAFT_1_13_2,
|
||||
public Protocol403Adapter(@NotNull Velocitab plugin) {
|
||||
super(plugin, Set.of(ProtocolVersion.MINECRAFT_1_13_2,
|
||||
ProtocolVersion.MINECRAFT_1_14,
|
||||
ProtocolVersion.MINECRAFT_1_14_1,
|
||||
ProtocolVersion.MINECRAFT_1_14_2,
|
||||
@ -79,8 +84,8 @@ public class Protocol403Adapter extends TeamsPacketAdapter {
|
||||
ProtocolUtils.writeString(byteBuf, packet.nameTagVisibility().id());
|
||||
ProtocolUtils.writeString(byteBuf, packet.collisionRule().id());
|
||||
byteBuf.writeByte(packet.color());
|
||||
ProtocolUtils.writeString(byteBuf, getChatString(packet.prefix()));
|
||||
ProtocolUtils.writeString(byteBuf, getChatString(packet.suffix()));
|
||||
ProtocolUtils.writeString(byteBuf, getRGBChat(packet.prefix()));
|
||||
ProtocolUtils.writeString(byteBuf, getRGBChat(packet.suffix()));
|
||||
}
|
||||
if (mode == UpdateTeamsPacket.UpdateMode.CREATE_TEAM || mode == UpdateTeamsPacket.UpdateMode.ADD_PLAYERS || mode == UpdateTeamsPacket.UpdateMode.REMOVE_PLAYERS) {
|
||||
List<String> entities = packet.entities();
|
||||
@ -90,4 +95,15 @@ public class Protocol403Adapter extends TeamsPacketAdapter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getRGBChat(@NotNull String input) {
|
||||
if (!getPlugin().getFormatter().equals(Formatter.LEGACY)) {
|
||||
return getChatString(input);
|
||||
}
|
||||
|
||||
final Component component = LegacyComponentSerializer.builder().hexColors().character('&').build().deserialize(input);
|
||||
|
||||
return GsonComponentSerializer.gson().serialize(component);
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ package net.william278.velocitab.packet;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.william278.velocitab.Velocitab;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -35,8 +36,8 @@ import java.util.Set;
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public class Protocol48Adapter extends TeamsPacketAdapter {
|
||||
|
||||
public Protocol48Adapter() {
|
||||
super(Set.of(ProtocolVersion.MINECRAFT_1_8));
|
||||
public Protocol48Adapter(@NotNull Velocitab plugin) {
|
||||
super(plugin, Set.of(ProtocolVersion.MINECRAFT_1_8));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -33,6 +33,7 @@ import org.slf4j.event.Level;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.*;
|
||||
|
||||
@ -43,20 +44,20 @@ public class ScoreboardManager {
|
||||
private final Velocitab plugin;
|
||||
private final Set<TeamsPacketAdapter> versions;
|
||||
private final Map<UUID, String> createdTeams;
|
||||
private final Map<String, String> nametags;
|
||||
private final Map<String, String> nameTags;
|
||||
|
||||
public ScoreboardManager(@NotNull Velocitab velocitab) {
|
||||
this.plugin = velocitab;
|
||||
this.createdTeams = new ConcurrentHashMap<>();
|
||||
this.nametags = new ConcurrentHashMap<>();
|
||||
this.nameTags = new ConcurrentHashMap<>();
|
||||
this.versions = new HashSet<>();
|
||||
this.registerVersions();
|
||||
}
|
||||
|
||||
private void registerVersions() {
|
||||
versions.add(new Protocol403Adapter());
|
||||
versions.add(new Protocol340Adapter());
|
||||
versions.add(new Protocol48Adapter());
|
||||
versions.add(new Protocol403Adapter(plugin));
|
||||
versions.add(new Protocol340Adapter(plugin));
|
||||
versions.add(new Protocol48Adapter(plugin));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -99,10 +100,9 @@ public class ScoreboardManager {
|
||||
final UpdateTeamsPacket packet = UpdateTeamsPacket.removeTeam(plugin, teamName);
|
||||
|
||||
siblings.forEach(server -> server.getPlayersConnected().forEach(connected -> {
|
||||
final boolean canSee = !plugin.getVanishManager().isVanished(connected.getUsername())
|
||||
|| plugin.getVanishManager().canSee(player.getUsername(), player.getUsername());
|
||||
final boolean canSee = plugin.getVanishManager().canSee(connected.getUsername(), player.getUsername());
|
||||
|
||||
if (!canSee) {
|
||||
if (canSee) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ public class ScoreboardManager {
|
||||
return;
|
||||
}
|
||||
|
||||
final String nametag = nametags.getOrDefault(teamName, "");
|
||||
final String nametag = nameTags.getOrDefault(teamName, "");
|
||||
if (nametag.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@ -138,7 +138,7 @@ public class ScoreboardManager {
|
||||
final String suffix = split.length > 1 ? split[1] : "";
|
||||
final UpdateTeamsPacket packet = UpdateTeamsPacket.create(plugin, createdTeams.get(player.getUniqueId()), "", prefix, suffix, player.getUsername());
|
||||
|
||||
siblings.forEach(server -> server.getPlayersConnected().forEach(connected -> dispatchPacket(packet, connected)));
|
||||
siblings.forEach(server -> server.getPlayersConnected().stream().filter(p -> p != player).forEach(connected -> dispatchPacket(packet, connected)));
|
||||
}
|
||||
|
||||
public void updateRole(@NotNull Player player, @NotNull String role) {
|
||||
@ -151,7 +151,7 @@ public class ScoreboardManager {
|
||||
final TabPlayer tabPlayer = plugin.getTabList().getTabPlayer(player).orElseThrow();
|
||||
|
||||
tabPlayer.getNametag(plugin).thenAccept(nametag -> {
|
||||
final String[] split = nametag.split(player.getUsername(), 2);
|
||||
final String[] split = nametag.split(Pattern.quote(player.getUsername()), 2);
|
||||
final String prefix = split[0];
|
||||
final String suffix = split.length > 1 ? split[1] : "";
|
||||
|
||||
@ -161,10 +161,10 @@ public class ScoreboardManager {
|
||||
}
|
||||
|
||||
createdTeams.put(player.getUniqueId(), role);
|
||||
this.nametags.put(role, prefix + NAMETAG_DELIMITER + suffix);
|
||||
this.nameTags.put(role, prefix + NAMETAG_DELIMITER + suffix);
|
||||
dispatchGroupPacket(UpdateTeamsPacket.create(plugin, role, "", prefix, suffix, name), player);
|
||||
} else if (!this.nametags.getOrDefault(role, "").equals(prefix + NAMETAG_DELIMITER + suffix)) {
|
||||
this.nametags.put(role, prefix + NAMETAG_DELIMITER + suffix);
|
||||
} else if (!this.nameTags.getOrDefault(role, "").equals(prefix + NAMETAG_DELIMITER + suffix)) {
|
||||
this.nameTags.put(role, prefix + NAMETAG_DELIMITER + suffix);
|
||||
dispatchGroupPacket(UpdateTeamsPacket.changeNameTag(plugin, role, prefix, suffix), player);
|
||||
}
|
||||
}).exceptionally(e -> {
|
||||
@ -198,8 +198,7 @@ public class ScoreboardManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.getVanishManager().isVanished(p.getUsername()) ||
|
||||
!plugin.getVanishManager().canSee(player.getUsername(), p.getUsername())) {
|
||||
if (!plugin.getVanishManager().canSee(player.getUsername(), p.getUsername())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -215,7 +214,7 @@ public class ScoreboardManager {
|
||||
|
||||
roles.add(role);
|
||||
|
||||
final String nametag = nametags.getOrDefault(role, "");
|
||||
final String nametag = nameTags.getOrDefault(role, "");
|
||||
if (nametag.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@ -251,8 +250,7 @@ public class ScoreboardManager {
|
||||
final List<RegisteredServer> siblings = plugin.getTabList().getGroupServers(serverInfo.getServerInfo().getName());
|
||||
siblings.forEach(server -> server.getPlayersConnected().forEach(connected -> {
|
||||
try {
|
||||
final boolean canSee = !plugin.getVanishManager().isVanished(connected.getUsername())
|
||||
|| plugin.getVanishManager().canSee(player.getUsername(), player.getUsername());
|
||||
final boolean canSee = plugin.getVanishManager().canSee(connected.getUsername(), player.getUsername());
|
||||
if (!canSee) {
|
||||
return;
|
||||
}
|
||||
@ -298,5 +296,39 @@ public class ScoreboardManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recalculates the vanish status for a specific player.
|
||||
* This method updates the player's scoreboard to reflect the vanish status of another player.
|
||||
*
|
||||
* @param tabPlayer The TabPlayer object representing the player whose scoreboard will be updated.
|
||||
* @param target The TabPlayer object representing the player whose vanish status will be reflected.
|
||||
* @param canSee A boolean indicating whether the player can see the target player.
|
||||
*/
|
||||
public void recalculateVanishForPlayer(TabPlayer tabPlayer, TabPlayer target, boolean canSee) {
|
||||
final Player player = tabPlayer.getPlayer();
|
||||
|
||||
final String team = createdTeams.get(target.getPlayer().getUniqueId());
|
||||
|
||||
if (team == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final UpdateTeamsPacket removeTeam = UpdateTeamsPacket.removeTeam(plugin, team);
|
||||
dispatchPacket(removeTeam, player);
|
||||
|
||||
if (canSee) {
|
||||
final String nametag = nameTags.getOrDefault(team, "");
|
||||
if (nametag.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String[] split = nametag.split(NAMETAG_DELIMITER, 2);
|
||||
final String prefix = split[0];
|
||||
final String suffix = split.length > 1 ? split[1] : "";
|
||||
final UpdateTeamsPacket addTeam = UpdateTeamsPacket.create(plugin, team, "", prefix, suffix, target.getPlayer().getUsername());
|
||||
dispatchPacket(addTeam, player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.william278.velocitab.Velocitab;
|
||||
import org.apache.commons.text.StringEscapeUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ -33,6 +34,7 @@ import java.util.Set;
|
||||
@RequiredArgsConstructor
|
||||
public abstract class TeamsPacketAdapter {
|
||||
|
||||
private final Velocitab plugin;
|
||||
private final Set<ProtocolVersion> protocolVersions;
|
||||
|
||||
public abstract void encode(@NotNull ByteBuf byteBuf, @NotNull UpdateTeamsPacket packet);
|
||||
|
@ -26,6 +26,8 @@ import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.*;
|
||||
import lombok.experimental.Accessors;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import net.william278.velocitab.Velocitab;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -127,7 +129,15 @@ public class UpdateTeamsPacket implements MinecraftPacket {
|
||||
if (text == null) {
|
||||
return 15;
|
||||
}
|
||||
int lastFormatIndex = text.lastIndexOf("§");
|
||||
|
||||
//add 1 random char at the end to make sure the last color is always found
|
||||
text = text + "z";
|
||||
|
||||
//serialize & deserialize to downsample rgb to legacy
|
||||
Component legacyComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(text);
|
||||
text = LegacyComponentSerializer.legacyAmpersand().serialize(legacyComponent);
|
||||
|
||||
int lastFormatIndex = text.lastIndexOf("&");
|
||||
if (lastFormatIndex == -1 || lastFormatIndex == text.length() - 1) {
|
||||
return 15;
|
||||
}
|
||||
@ -136,6 +146,7 @@ public class UpdateTeamsPacket implements MinecraftPacket {
|
||||
return TeamColor.getColorId(last.charAt(1));
|
||||
}
|
||||
|
||||
//Style-codes are handled as white
|
||||
public enum TeamColor {
|
||||
BLACK('0', 0),
|
||||
DARK_BLUE('1', 1),
|
||||
@ -154,10 +165,10 @@ public class UpdateTeamsPacket implements MinecraftPacket {
|
||||
YELLOW('e', 14),
|
||||
WHITE('f', 15),
|
||||
OBFUSCATED('k', 16),
|
||||
BOLD('l', 17),
|
||||
STRIKETHROUGH('m', 18),
|
||||
UNDERLINED('n', 19),
|
||||
ITALIC('o', 20),
|
||||
BOLD('f', 17),
|
||||
STRIKETHROUGH('f', 18),
|
||||
UNDERLINED('f', 19),
|
||||
ITALIC('f', 20),
|
||||
RESET('r', 21);
|
||||
|
||||
private final char colorChar;
|
||||
|
@ -26,6 +26,7 @@ import net.kyori.adventure.text.Component;
|
||||
import net.william278.velocitab.Velocitab;
|
||||
import net.william278.velocitab.config.Placeholder;
|
||||
import net.william278.velocitab.tab.PlayerTabList;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -45,6 +46,9 @@ public final class TabPlayer implements Comparable<TabPlayer> {
|
||||
private String teamName;
|
||||
@Nullable
|
||||
private String customName;
|
||||
@Nullable
|
||||
@Setter
|
||||
private String lastServer;
|
||||
|
||||
public TabPlayer(@NotNull Player player, @NotNull Role role) {
|
||||
this.player = player;
|
||||
@ -76,7 +80,7 @@ public final class TabPlayer implements Comparable<TabPlayer> {
|
||||
public String getServerName() {
|
||||
return player.getCurrentServer()
|
||||
.map(serverConnection -> serverConnection.getServerInfo().getName())
|
||||
.orElse("unknown");
|
||||
.orElse(ObjectUtils.firstNonNull(lastServer, "unknown"));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,9 +127,7 @@ public final class TabPlayer implements Comparable<TabPlayer> {
|
||||
@NotNull
|
||||
public CompletableFuture<String> getNametag(@NotNull Velocitab plugin) {
|
||||
final String serverGroup = plugin.getSettings().getServerGroup(getServerName());
|
||||
return Placeholder.replace(plugin.getSettings().getNametag(serverGroup), plugin, this)
|
||||
.thenApply(formatted -> plugin.getFormatter().formatLegacySymbols(formatted, this, plugin));
|
||||
|
||||
return Placeholder.replace(plugin.getSettings().getNametag(serverGroup), plugin, this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
@ -68,8 +68,9 @@ public class SortingManager {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (value.matches("[0-9]+")) {
|
||||
if (value.matches("^-?[0-9]\\d*(\\.\\d+)?$")) {
|
||||
double parsed = Double.parseDouble(value);
|
||||
parsed = Math.max(0, parsed);
|
||||
return compressNumber(Integer.MAX_VALUE / 4d - parsed);
|
||||
}
|
||||
|
||||
|
@ -19,8 +19,10 @@
|
||||
|
||||
package net.william278.velocitab.tab;
|
||||
|
||||
import com.velocitypowered.api.event.PostOrder;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
||||
import com.velocitypowered.api.event.player.KickedFromServerEvent;
|
||||
import com.velocitypowered.api.event.player.ServerPostConnectEvent;
|
||||
import com.velocitypowered.api.event.proxy.ProxyReloadEvent;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
@ -37,15 +39,13 @@ import net.william278.velocitab.config.Placeholder;
|
||||
import net.william278.velocitab.player.Role;
|
||||
import net.william278.velocitab.player.TabPlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.event.Level;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* The main class for tracking the server TAB list
|
||||
@ -54,12 +54,14 @@ public class PlayerTabList {
|
||||
private final Velocitab plugin;
|
||||
private final ConcurrentHashMap<UUID, TabPlayer> players;
|
||||
private final ConcurrentLinkedQueue<String> fallbackServers;
|
||||
private final List<UUID> justKicked;
|
||||
private ScheduledTask updateTask;
|
||||
|
||||
public PlayerTabList(@NotNull Velocitab plugin) {
|
||||
this.plugin = plugin;
|
||||
this.players = new ConcurrentHashMap<>();
|
||||
this.fallbackServers = new ConcurrentLinkedQueue<>();
|
||||
this.justKicked = new CopyOnWriteArrayList<>();
|
||||
|
||||
// If the update time is set to 0 do not schedule the updater
|
||||
if (plugin.getSettings().getUpdateRate() > 0) {
|
||||
@ -114,6 +116,13 @@ public class PlayerTabList {
|
||||
});
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onKick(KickedFromServerEvent event) {
|
||||
event.getPlayer().getTabList().clearAll();
|
||||
event.getPlayer().getTabList().clearHeaderAndFooter();
|
||||
justKicked.add(event.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
@Subscribe
|
||||
public void onPlayerJoin(@NotNull ServerPostConnectEvent event) {
|
||||
@ -146,6 +155,16 @@ public class PlayerTabList {
|
||||
final TabPlayer tabPlayer = getTabPlayer(joined).orElseGet(() -> createTabPlayer(joined));
|
||||
players.putIfAbsent(joined.getUniqueId(), tabPlayer);
|
||||
|
||||
int delay = 500;
|
||||
|
||||
if (justKicked.contains(joined.getUniqueId())) {
|
||||
delay = 1000;
|
||||
justKicked.remove(joined.getUniqueId());
|
||||
}
|
||||
|
||||
//store last server so it's possible to have the last server on disconnect
|
||||
tabPlayer.setLastServer(joined.getCurrentServer().map(ServerConnection::getServerInfo).map(ServerInfo::getName).orElse(""));
|
||||
|
||||
final boolean isVanished = plugin.getVanishManager().isVanished(joined.getUsername());
|
||||
// Update lists
|
||||
plugin.getServer().getScheduler()
|
||||
@ -164,12 +183,17 @@ public class PlayerTabList {
|
||||
player.getPlayer().getTabList().removeEntry(joined.getUniqueId());
|
||||
}
|
||||
// check if joined player can see current player
|
||||
if ((plugin.getVanishManager().isVanished(player.getPlayer().getUsername()) ||
|
||||
if ((plugin.getVanishManager().isVanished(player.getPlayer().getUsername()) &&
|
||||
!plugin.getVanishManager().canSee(joined.getUsername(), player.getPlayer().getUsername())) && player.getPlayer() != joined) {
|
||||
tabList.removeEntry(player.getPlayer().getUniqueId());
|
||||
} else {
|
||||
tabList.getEntry(player.getPlayer().getUniqueId()).ifPresentOrElse(
|
||||
entry -> player.getDisplayName(plugin).thenAccept(entry::setDisplayName),
|
||||
entry -> player.getDisplayName(plugin).thenAccept(entry::setDisplayName)
|
||||
.exceptionally(throwable -> {
|
||||
plugin.log(Level.ERROR, String.format("Failed to set display name for %s (UUID: %s)",
|
||||
player.getPlayer().getUsername(), player.getPlayer().getUniqueId()), throwable);
|
||||
return null;
|
||||
}),
|
||||
() -> createEntry(player, tabList).thenAccept(tabList::addEntry)
|
||||
);
|
||||
}
|
||||
@ -185,7 +209,7 @@ public class PlayerTabList {
|
||||
// Fire event without listening for result
|
||||
plugin.getServer().getEventManager().fireAndForget(new PlayerAddedToTabEvent(tabPlayer, tabPlayer.getServerGroup(plugin), serversInGroup));
|
||||
})
|
||||
.delay(500, TimeUnit.MILLISECONDS)
|
||||
.delay(delay, TimeUnit.MILLISECONDS)
|
||||
.schedule();
|
||||
}
|
||||
|
||||
@ -224,7 +248,7 @@ public class PlayerTabList {
|
||||
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@Subscribe(order = PostOrder.LAST)
|
||||
public void onPlayerQuit(@NotNull DisconnectEvent event) {
|
||||
if (event.getLoginStatus() != DisconnectEvent.LoginStatus.SUCCESSFUL_LOGIN) {
|
||||
return;
|
||||
@ -232,7 +256,8 @@ public class PlayerTabList {
|
||||
|
||||
// Remove the player from the tracking list, Print warning if player was not removed
|
||||
final UUID uuid = event.getPlayer().getUniqueId();
|
||||
if (players.remove(uuid) == null) {
|
||||
final TabPlayer tabPlayer = players.get(uuid);
|
||||
if (tabPlayer == null) {
|
||||
plugin.log(String.format("Failed to remove disconnecting player %s (UUID: %s)",
|
||||
event.getPlayer().getUsername(), uuid));
|
||||
}
|
||||
@ -250,7 +275,8 @@ public class PlayerTabList {
|
||||
.schedule();
|
||||
// Delete player team
|
||||
plugin.getScoreboardManager().ifPresent(manager -> manager.resetCache(event.getPlayer()));
|
||||
|
||||
//remove player from tab list cache
|
||||
players.remove(uuid);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -450,4 +476,53 @@ public class PlayerTabList {
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Recalculates the visibility of players in the tab list for the given player.
|
||||
* If tabPlayer can see the player, the player will be added to the tab list.
|
||||
*
|
||||
* @param tabPlayer The TabPlayer object representing the player for whom to recalculate the tab list visibility.
|
||||
*/
|
||||
public void recalculateVanishForPlayer(@NotNull TabPlayer tabPlayer) {
|
||||
final Player player = tabPlayer.getPlayer();
|
||||
final Optional<List<String>> serversInGroupOptional = getGroupNames(player.getCurrentServer()
|
||||
.map(ServerConnection::getServerInfo)
|
||||
.map(ServerInfo::getName)
|
||||
.orElse("?"));
|
||||
final List<String> serversInGroup = serversInGroupOptional.orElseGet(ArrayList::new);
|
||||
|
||||
plugin.getServer().getAllPlayers().forEach(p -> {
|
||||
if (p.equals(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Optional<TabPlayer> targetOptional = getTabPlayer(p);
|
||||
if (targetOptional.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final TabPlayer target = targetOptional.get();
|
||||
final String serverName = target.getServerName();
|
||||
|
||||
if (plugin.getSettings().isOnlyListPlayersInSameGroup()
|
||||
&& !serversInGroup.contains(serverName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean canSee = !plugin.getVanishManager().isVanished(p.getUsername()) ||
|
||||
plugin.getVanishManager().canSee(player.getUsername(), p.getUsername());
|
||||
|
||||
if (!canSee) {
|
||||
player.getTabList().removeEntry(p.getUniqueId());
|
||||
plugin.getScoreboardManager().ifPresent(s -> s.recalculateVanishForPlayer(tabPlayer, target, false));
|
||||
} else {
|
||||
if (!player.getTabList().containsEntry(p.getUniqueId())) {
|
||||
createEntry(target, player.getTabList()).thenAccept(e -> {
|
||||
player.getTabList().addEntry(e);
|
||||
plugin.getScoreboardManager().ifPresent(s -> s.recalculateVanishForPlayer(tabPlayer, target, true));
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user