minecraft-src/net/minecraft/client/gui/screens/social/SocialInteractionsPlayerList.java
2025-07-04 03:15:13 +03:00

188 lines
6.2 KiB
Java

package net.minecraft.client.gui.screens.social;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.mojang.authlib.GameProfile;
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.multiplayer.PlayerInfo;
import net.minecraft.client.multiplayer.chat.ChatLog;
import net.minecraft.client.multiplayer.chat.LoggedChatMessage.Player;
import org.jetbrains.annotations.Nullable;
@Environment(EnvType.CLIENT)
public class SocialInteractionsPlayerList extends ContainerObjectSelectionList<PlayerEntry> {
private final SocialInteractionsScreen socialInteractionsScreen;
private final List<PlayerEntry> players = Lists.<PlayerEntry>newArrayList();
@Nullable
private String filter;
public SocialInteractionsPlayerList(SocialInteractionsScreen socialInteractionsScreen, Minecraft minecraft, int width, int height, int y, int itemHeight) {
super(minecraft, width, height, y, itemHeight);
this.socialInteractionsScreen = socialInteractionsScreen;
}
@Override
protected void renderListBackground(GuiGraphics guiGraphics) {
}
@Override
protected void renderListSeparators(GuiGraphics guiGraphics) {
}
@Override
protected void enableScissor(GuiGraphics guiGraphics) {
guiGraphics.enableScissor(this.getX(), this.getY() + 4, this.getRight(), this.getBottom());
}
public void updatePlayerList(Collection<UUID> ids, double scrollAmount, boolean addChatLogPlayers) {
Map<UUID, PlayerEntry> map = new HashMap();
this.addOnlinePlayers(ids, map);
this.updatePlayersFromChatLog(map, addChatLogPlayers);
this.updateFiltersAndScroll(map.values(), scrollAmount);
}
private void addOnlinePlayers(Collection<UUID> ids, Map<UUID, PlayerEntry> playerMap) {
ClientPacketListener clientPacketListener = this.minecraft.player.connection;
for (UUID uUID : ids) {
PlayerInfo playerInfo = clientPacketListener.getPlayerInfo(uUID);
if (playerInfo != null) {
boolean bl = playerInfo.hasVerifiableChat();
playerMap.put(uUID, new PlayerEntry(this.minecraft, this.socialInteractionsScreen, uUID, playerInfo.getProfile().getName(), playerInfo::getSkin, bl));
}
}
}
private void updatePlayersFromChatLog(Map<UUID, PlayerEntry> playerMap, boolean addPlayers) {
for (GameProfile gameProfile : collectProfilesFromChatLog(this.minecraft.getReportingContext().chatLog())) {
PlayerEntry playerEntry;
if (addPlayers) {
playerEntry = (PlayerEntry)playerMap.computeIfAbsent(
gameProfile.getId(),
uUID -> {
PlayerEntry playerEntryx = new PlayerEntry(
this.minecraft,
this.socialInteractionsScreen,
gameProfile.getId(),
gameProfile.getName(),
this.minecraft.getSkinManager().lookupInsecure(gameProfile),
true
);
playerEntryx.setRemoved(true);
return playerEntryx;
}
);
} else {
playerEntry = (PlayerEntry)playerMap.get(gameProfile.getId());
if (playerEntry == null) {
continue;
}
}
playerEntry.setHasRecentMessages(true);
}
}
private static Collection<GameProfile> collectProfilesFromChatLog(ChatLog chatLog) {
Set<GameProfile> set = new ObjectLinkedOpenHashSet<>();
for (int i = chatLog.end(); i >= chatLog.start(); i--) {
if (chatLog.lookup(i) instanceof Player player && player.message().hasSignature()) {
set.add(player.profile());
}
}
return set;
}
private void sortPlayerEntries() {
this.players.sort(Comparator.comparing(playerEntry -> {
if (this.minecraft.isLocalPlayer(playerEntry.getPlayerId())) {
return 0;
} else if (this.minecraft.getReportingContext().hasDraftReportFor(playerEntry.getPlayerId())) {
return 1;
} else if (playerEntry.getPlayerId().version() == 2) {
return 4;
} else {
return playerEntry.hasRecentMessages() ? 2 : 3;
}
}).thenComparing(playerEntry -> {
if (!playerEntry.getPlayerName().isBlank()) {
int i = playerEntry.getPlayerName().codePointAt(0);
if (i == 95 || i >= 97 && i <= 122 || i >= 65 && i <= 90 || i >= 48 && i <= 57) {
return 0;
}
}
return 1;
}).thenComparing(PlayerEntry::getPlayerName, String::compareToIgnoreCase));
}
private void updateFiltersAndScroll(Collection<PlayerEntry> players, double scrollAmount) {
this.players.clear();
this.players.addAll(players);
this.sortPlayerEntries();
this.updateFilteredPlayers();
this.replaceEntries(this.players);
this.setScrollAmount(scrollAmount);
}
private void updateFilteredPlayers() {
if (this.filter != null) {
this.players.removeIf(playerEntry -> !playerEntry.getPlayerName().toLowerCase(Locale.ROOT).contains(this.filter));
this.replaceEntries(this.players);
}
}
public void setFilter(String filter) {
this.filter = filter;
}
public boolean isEmpty() {
return this.players.isEmpty();
}
public void addPlayer(PlayerInfo playerInfo, SocialInteractionsScreen.Page page) {
UUID uUID = playerInfo.getProfile().getId();
for (PlayerEntry playerEntry : this.players) {
if (playerEntry.getPlayerId().equals(uUID)) {
playerEntry.setRemoved(false);
return;
}
}
if ((page == SocialInteractionsScreen.Page.ALL || this.minecraft.getPlayerSocialManager().shouldHideMessageFrom(uUID))
&& (Strings.isNullOrEmpty(this.filter) || playerInfo.getProfile().getName().toLowerCase(Locale.ROOT).contains(this.filter))) {
boolean bl = playerInfo.hasVerifiableChat();
PlayerEntry playerEntryx = new PlayerEntry(
this.minecraft, this.socialInteractionsScreen, playerInfo.getProfile().getId(), playerInfo.getProfile().getName(), playerInfo::getSkin, bl
);
this.addEntry(playerEntryx);
this.players.add(playerEntryx);
}
}
public void removePlayer(UUID id) {
for (PlayerEntry playerEntry : this.players) {
if (playerEntry.getPlayerId().equals(id)) {
playerEntry.setRemoved(true);
return;
}
}
}
}