fix: duplicate entity ID issues with offline accounts (#190)

This commit is contained in:
AlexDev_ 2024-05-07 12:13:42 +02:00 committed by GitHub
parent b4dd2f4d8b
commit 4770567a98
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 5 deletions

View File

@ -56,6 +56,13 @@ public class PlayerChannelHandler extends ChannelDuplexHandler {
forceGameMode(minecraftPacket.getEntries()); forceGameMode(minecraftPacket.getEntries());
} }
//fix for duplicate entries
if (minecraftPacket.containsAction(UpsertPlayerInfoPacket.Action.ADD_PLAYER)) {
minecraftPacket.getEntries().stream()
.filter(entry -> entry.getProfile() != null && !entry.getProfile().getId().equals(entry.getProfileId()))
.forEach(entry -> entry.setListed(false));
}
if (!minecraftPacket.containsAction(UpsertPlayerInfoPacket.Action.ADD_PLAYER) && !minecraftPacket.containsAction(UpsertPlayerInfoPacket.Action.UPDATE_LISTED)) { if (!minecraftPacket.containsAction(UpsertPlayerInfoPacket.Action.ADD_PLAYER) && !minecraftPacket.containsAction(UpsertPlayerInfoPacket.Action.UPDATE_LISTED)) {
super.write(ctx, msg, promise); super.write(ctx, msg, promise);
return; return;

View File

@ -39,6 +39,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.slf4j.event.Level; import org.slf4j.event.Level;
import java.lang.reflect.Field;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -212,6 +213,8 @@ public class PlayerTabList {
tabPlayer.getTeamName(plugin).thenAccept(t -> s.updateRole(tabPlayer, t, false)); tabPlayer.getTeamName(plugin).thenAccept(t -> s.updateRole(tabPlayer, t, false));
}); });
fixDuplicateEntries(joined);
// Fire event without listening for result // Fire event without listening for result
plugin.getServer().getEventManager().fireAndForget(new PlayerAddedToTabEvent(tabPlayer, group)); plugin.getServer().getEventManager().fireAndForget(new PlayerAddedToTabEvent(tabPlayer, group));
}) })
@ -231,6 +234,22 @@ public class PlayerTabList {
.orElse(""); .orElse("");
} }
@SuppressWarnings("unchecked")
private void fixDuplicateEntries(@NotNull Player target) {
try {
final Field entriesField = target.getTabList().getClass().getDeclaredField("entries");
entriesField.setAccessible(true);
final Map<UUID, TabListEntry> entries = (Map<UUID, TabListEntry>) entriesField.get(target.getTabList());
entries.entrySet().stream()
.filter(entry -> entry.getValue().getProfile() != null)
.filter(entry -> entry.getValue().getProfile().getId().equals(target.getUniqueId()))
.filter(entry -> !entry.getKey().equals(target.getUniqueId()))
.forEach(entry -> target.getTabList().removeEntry(entry.getKey()));
} catch (Throwable error) {
plugin.log(Level.ERROR, "Failed to fix duplicate entries", error);
}
}
protected void removePlayer(@NotNull Player target) { protected void removePlayer(@NotNull Player target) {
removePlayer(target, null); removePlayer(target, null);
} }
@ -409,11 +428,9 @@ public class PlayerTabList {
.forEach(player -> { .forEach(player -> {
final int latency = (int) player.getPlayer().getPing(); final int latency = (int) player.getPlayer().getPing();
final Set<TabPlayer> players = group.getTabPlayers(plugin, player); final Set<TabPlayer> players = group.getTabPlayers(plugin, player);
players.forEach(p -> { players.forEach(p -> p.getPlayer().getTabList().getEntries().stream()
p.getPlayer().getTabList().getEntries().stream() .filter(e -> e.getProfile().getId().equals(player.getPlayer().getUniqueId())).findFirst()
.filter(e -> e.getProfile().getId().equals(player.getPlayer().getUniqueId())).findFirst() .ifPresent(entry -> entry.setLatency(Math.max(latency, 0))));
.ifPresent(entry -> entry.setLatency(Math.max(latency, 0)));
});
}); });
} }