188 lines
6.2 KiB
Java
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;
|
|
}
|
|
}
|
|
}
|
|
}
|