From 97770cd1a68d9f3cdb35bd4ff19b1ffabd96b42d Mon Sep 17 00:00:00 2001 From: JOO200 Date: Fri, 9 Dec 2022 19:40:30 +0100 Subject: [PATCH] Reduce Spam from the TabList by not sending every package multiple times (#902) * Reduce Spam from the TabList by not sending every package multiple times VelocityTabList#processUpsert called entry.setX which will create a package and send it to the client. BackendPlaySessionHandler doesn't return true for those packages, therefore the package for tab list updates will be send two times. * Cleanup TabList#buildEntry, added listed status to Entry builder --- .../api/proxy/player/TabList.java | 32 ++++++++++++++++--- .../api/proxy/player/TabListEntry.java | 15 ++++++++- .../proxy/tablist/KeyedVelocityTabList.java | 7 +--- .../proxy/tablist/VelocityTabList.java | 25 ++++----------- .../proxy/tablist/VelocityTabListEntry.java | 16 ++++++++++ 5 files changed, 65 insertions(+), 30 deletions(-) diff --git a/api/src/main/java/com/velocitypowered/api/proxy/player/TabList.java b/api/src/main/java/com/velocitypowered/api/proxy/player/TabList.java index 02e16c77e..cd9430212 100644 --- a/api/src/main/java/com/velocitypowered/api/proxy/player/TabList.java +++ b/api/src/main/java/com/velocitypowered/api/proxy/player/TabList.java @@ -84,8 +84,10 @@ public interface TabList { * @deprecated Internal usage. Use {@link TabListEntry.Builder} instead. */ @Deprecated - TabListEntry buildEntry(GameProfile profile, @Nullable Component displayName, int latency, - int gameMode); + default TabListEntry buildEntry(GameProfile profile, @Nullable Component displayName, int latency, + int gameMode) { + return buildEntry(profile, displayName, latency, gameMode, null, true); + } /** * Builds a tab list entry. @@ -99,8 +101,10 @@ public interface TabList { * @deprecated Internal usage. Use {@link TabListEntry.Builder} instead. */ @Deprecated - TabListEntry buildEntry(GameProfile profile, @Nullable Component displayName, int latency, - int gameMode, @Nullable IdentifiedKey key); + default TabListEntry buildEntry(GameProfile profile, @Nullable Component displayName, int latency, + int gameMode, @Nullable IdentifiedKey key) { + return buildEntry(profile, displayName, latency, gameMode, null, true); + } /** @@ -115,6 +119,24 @@ public interface TabList { * @deprecated Internal usage. Use {@link TabListEntry.Builder} instead. */ @Deprecated + default TabListEntry buildEntry(GameProfile profile, @Nullable Component displayName, int latency, + int gameMode, @Nullable ChatSession chatSession) { + return buildEntry(profile, displayName, latency, gameMode, chatSession, true); + } + + /** + * Represents an entry in a {@link Player}'s tab list. + * + * @param profile the profile + * @param displayName the display name + * @param latency the latency + * @param gameMode the game mode + * @param chatSession the chat session + * @param listed the visible status of entry + * @return the entry + * @deprecated Internal usage. Use {@link TabListEntry.Builder} instead. + */ + @Deprecated TabListEntry buildEntry(GameProfile profile, @Nullable Component displayName, int latency, - int gameMode, @Nullable ChatSession chatSession); + int gameMode, @Nullable ChatSession chatSession, boolean listed); } diff --git a/api/src/main/java/com/velocitypowered/api/proxy/player/TabListEntry.java b/api/src/main/java/com/velocitypowered/api/proxy/player/TabListEntry.java index 5714a2054..a3f3bd61a 100644 --- a/api/src/main/java/com/velocitypowered/api/proxy/player/TabListEntry.java +++ b/api/src/main/java/com/velocitypowered/api/proxy/player/TabListEntry.java @@ -160,6 +160,7 @@ public interface TabListEntry extends KeyIdentifiable { private @Nullable Component displayName; private int latency = 0; private int gameMode = 0; + private boolean listed = true; private @Nullable ChatSession chatSession; @@ -241,6 +242,18 @@ public interface TabListEntry extends KeyIdentifiable { return this; } + /** + * Sets wether this entry should be visible. + * + * @param listed to set + * @return ${code this}, for chaining + * @see TabListEntry#isListed() + */ + public Builder listed(boolean listed) { + this.listed = listed; + return this; + } + /** * Constructs the {@link TabListEntry} specified by {@code this} {@link Builder}. * @@ -253,7 +266,7 @@ public interface TabListEntry extends KeyIdentifiable { if (profile == null) { throw new IllegalStateException("The GameProfile must be set when building a TabListEntry"); } - return tabList.buildEntry(profile, displayName, latency, gameMode, chatSession); + return tabList.buildEntry(profile, displayName, latency, gameMode, chatSession, listed); } } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/tablist/KeyedVelocityTabList.java b/proxy/src/main/java/com/velocitypowered/proxy/tablist/KeyedVelocityTabList.java index 5744e6c32..a32aee8de 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/tablist/KeyedVelocityTabList.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/tablist/KeyedVelocityTabList.java @@ -131,11 +131,6 @@ public class KeyedVelocityTabList implements InternalTabList { return Collections.unmodifiableCollection(this.entries.values()); } - @Override - public TabListEntry buildEntry(GameProfile profile, @Nullable Component displayName, int latency, int gameMode) { - return buildEntry(profile, displayName, latency, gameMode, (ChatSession) null); - } - @Override public TabListEntry buildEntry(GameProfile profile, net.kyori.adventure.text.@Nullable Component displayName, @@ -145,7 +140,7 @@ public class KeyedVelocityTabList implements InternalTabList { @Override public TabListEntry buildEntry(GameProfile profile, @Nullable Component displayName, int latency, int gameMode, - @Nullable ChatSession chatSession) { + @Nullable ChatSession chatSession, boolean listed) { return new KeyedVelocityTabListEntry(this, profile, displayName, latency, gameMode, chatSession == null ? null : chatSession.getIdentifiedKey()); } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/tablist/VelocityTabList.java b/proxy/src/main/java/com/velocitypowered/proxy/tablist/VelocityTabList.java index 1c509e2dd..ddc524641 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/tablist/VelocityTabList.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/tablist/VelocityTabList.java @@ -162,21 +162,10 @@ public class VelocityTabList implements InternalTabList { this.entries.clear(); } - @Override - public TabListEntry buildEntry(GameProfile profile, @Nullable Component displayName, int latency, int gameMode) { - return new VelocityTabListEntry(this, profile, displayName, latency, gameMode, null, true); - } - @Override public TabListEntry buildEntry(GameProfile profile, @Nullable Component displayName, int latency, int gameMode, - @Nullable IdentifiedKey key) { - return new VelocityTabListEntry(this, profile, displayName, latency, gameMode, null, true); - } - - @Override - public TabListEntry buildEntry(GameProfile profile, @Nullable Component displayName, int latency, int gameMode, - @Nullable ChatSession chatSession) { - return new VelocityTabListEntry(this, profile, displayName, latency, gameMode, chatSession, true); + @Nullable ChatSession chatSession, boolean listed) { + return new VelocityTabListEntry(this, profile, displayName, latency, gameMode, chatSession, listed); } @Override @@ -211,7 +200,7 @@ public class VelocityTabList implements InternalTabList { 0, -1, null, - true + false ) ); } else { @@ -223,19 +212,19 @@ public class VelocityTabList implements InternalTabList { return; } if (actions.contains(UpsertPlayerInfo.Action.UPDATE_GAME_MODE)) { - currentEntry.setGameMode(entry.getGameMode()); + currentEntry.setGameModeWithoutUpdate(entry.getGameMode()); } if (actions.contains(UpsertPlayerInfo.Action.UPDATE_LATENCY)) { - currentEntry.setLatency(entry.getLatency()); + currentEntry.setLatencyWithoutUpdate(entry.getLatency()); } if (actions.contains(UpsertPlayerInfo.Action.UPDATE_DISPLAY_NAME)) { - currentEntry.setDisplayName(entry.getDisplayName()); + currentEntry.setDisplayNameWithoutUpdate(entry.getDisplayName()); } if (actions.contains(UpsertPlayerInfo.Action.INITIALIZE_CHAT)) { currentEntry.setChatSession(entry.getChatSession()); } if (actions.contains(UpsertPlayerInfo.Action.UPDATE_LISTED)) { - currentEntry.setListed(entry.isListed()); + currentEntry.setListedWithoutUpdate(entry.isListed()); } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/tablist/VelocityTabListEntry.java b/proxy/src/main/java/com/velocitypowered/proxy/tablist/VelocityTabListEntry.java index d913c25b0..6c9bca80a 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/tablist/VelocityTabListEntry.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/tablist/VelocityTabListEntry.java @@ -76,6 +76,10 @@ public class VelocityTabListEntry implements TabListEntry { return this; } + void setDisplayNameWithoutUpdate(@Nullable Component displayName) { + this.displayName = displayName; + } + @Override public int getLatency() { return this.latency; @@ -90,6 +94,10 @@ public class VelocityTabListEntry implements TabListEntry { return this; } + void setLatencyWithoutUpdate(int latency) { + this.latency = latency; + } + @Override public int getGameMode() { return this.gameMode; @@ -104,6 +112,10 @@ public class VelocityTabListEntry implements TabListEntry { return this; } + void setGameModeWithoutUpdate(int gameMode) { + this.gameMode = gameMode; + } + protected void setChatSession(@Nullable ChatSession session) { this.session = session; } @@ -121,4 +133,8 @@ public class VelocityTabListEntry implements TabListEntry { this.tabList.emitActionRaw(UpsertPlayerInfo.Action.UPDATE_LISTED, upsertEntry); return this; } + + void setListedWithoutUpdate(boolean listed) { + this.listed = listed; + } }