From 131e3617d74a2ea026a320ae1e8f227c85a9a596 Mon Sep 17 00:00:00 2001 From: Gjum Date: Fri, 22 Apr 2022 17:15:58 +0200 Subject: [PATCH] roundPlayerListPing to same 6 levels vanilla displays --- .../hacks/basic/AttrHider.java | 43 ++++++++++++++++++- paper/src/main/resources/config.yml | 2 + 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/AttrHider.java b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/AttrHider.java index 38628093..6d7466b1 100644 --- a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/AttrHider.java +++ b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/AttrHider.java @@ -7,6 +7,7 @@ import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.wrappers.EnumWrappers; import com.comphenix.protocol.wrappers.Pair; +import com.comphenix.protocol.wrappers.PlayerInfoData; import com.comphenix.protocol.wrappers.WrappedWatchableObject; import com.destroystokyo.paper.MaterialTags; import com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks; @@ -26,6 +27,9 @@ import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.potion.PotionData; +import java.util.ArrayList; +import java.util.List; + public final class AttrHider extends BasicHack { public static final String BYPASS_PERMISSION = "attrhider.bypass"; @@ -41,6 +45,9 @@ public final class AttrHider extends BasicHack { @AutoLoad private boolean hideHealth; + @AutoLoad + private boolean roundPlayerListPing; + public AttrHider(final SimpleAdminHacks plugin, final BasicHackConfig config) { super(plugin, config); } @@ -152,6 +159,41 @@ public void onPacketSending(final PacketEvent event) { } }); } + if (this.roundPlayerListPing) { + this.packets.addAdapter(new PacketAdapter(this.plugin, PacketType.Play.Server.PLAYER_INFO) { + @Override + public void onPacketSending(final PacketEvent event) { + final PacketContainer packet = event.getPacket(); + final Player player = event.getPlayer(); + if (player.hasPermission(BYPASS_PERMISSION)) { + return; + } + final PacketContainer cloned = packet.deepClone(); + List newInfos = new ArrayList<>(); + List oldInfos = cloned.getPlayerInfoDataLists().read(0); + for (PlayerInfoData oldInfo : oldInfos) { + int latency = oldInfo.getLatency(); + // Limit player ping in the tablist to the same 6 values vanilla clients can discern visually + // this follows 1.16.5 PlayerTabOverlay#renderPingIcon() + if (latency < 0) latency = -1; + else if (latency < 150) latency = 75; // average of 0 and 150, arbitrary + else if (latency < 300) latency = 225; + else if (latency < 600) latency = 450; + else if (latency < 1000) latency = 800; + else latency = 1000; + newInfos.add(new PlayerInfoData( + oldInfo.getProfile(), + latency, + oldInfo.getGameMode(), + oldInfo.getDisplayName())); + } + cloned.getPlayerInfoDataLists().write(0, newInfos); + // The packet data is shared between events, but the event + // instance is exclusive to THIS sending of the packet + event.setPacket(cloned); + } + }); + } } @Override @@ -177,5 +219,4 @@ private static boolean shouldBeObfuscated(final Material material) { || material == Material.LINGERING_POTION || material == Material.SPLASH_POTION; } - } diff --git a/paper/src/main/resources/config.yml b/paper/src/main/resources/config.yml index 7ba4efb9..71301d28 100644 --- a/paper/src/main/resources/config.yml +++ b/paper/src/main/resources/config.yml @@ -62,6 +62,8 @@ hacks: hideEffects: true # Hide the health of entities hideHealth: true + # Limit player ping in the tablist to the same 6 values vanilla clients can discern visually + roundPlayerListPing: true AutoRespawn: enabled: true # Delay in MS