SocialInteractionsPlayerList.java

net.minecraft.client.gui.screens.social.SocialInteractionsPlayerList

信息

  • 全限定名:net.minecraft.client.gui.screens.social.SocialInteractionsPlayerList
  • 类型:public class
  • 包:net.minecraft.client.gui.screens.social
  • 源码路径:src/main/java/net/minecraft/client/gui/screens/social/SocialInteractionsPlayerList.java
  • 起始行号:L27
  • 继承:ContainerObjectSelectionList
  • 职责:

    TODO

字段/常量

  • socialInteractionsScreen

    • 类型: SocialInteractionsScreen
    • 修饰符: private final
    • 源码定位: L28
    • 说明:

      TODO

  • players

    • 类型: List<PlayerEntry>
    • 修饰符: private final
    • 源码定位: L29
    • 说明:

      TODO

  • filter

    • 类型: String
    • 修饰符: private
    • 源码定位: L30
    • 说明:

      TODO

内部类/嵌套类型

构造器

public SocialInteractionsPlayerList(SocialInteractionsScreen socialInteractionsScreen, Minecraft minecraft, int width, int height, int y, int itemHeight) @ L32

  • 构造器名:SocialInteractionsPlayerList
  • 源码定位:L32
  • 修饰符:public

参数:

  • socialInteractionsScreen: SocialInteractionsScreen
  • minecraft: Minecraft
  • width: int
  • height: int
  • y: int
  • itemHeight: int

说明:

TODO

方法

下面的方法块按源码顺序生成。

protected void extractListBackground(GuiGraphicsExtractor graphics) @ L37

  • 方法名:extractListBackground
  • 源码定位:L37
  • 返回类型:void
  • 修饰符:protected

参数:

  • graphics: GuiGraphicsExtractor

说明:

TODO

protected void extractListSeparators(GuiGraphicsExtractor graphics) @ L41

  • 方法名:extractListSeparators
  • 源码定位:L41
  • 返回类型:void
  • 修饰符:protected

参数:

  • graphics: GuiGraphicsExtractor

说明:

TODO

protected void enableScissor(GuiGraphicsExtractor graphics) @ L45

  • 方法名:enableScissor
  • 源码定位:L45
  • 返回类型:void
  • 修饰符:protected

参数:

  • graphics: GuiGraphicsExtractor

说明:

TODO

public void updatePlayerList(Collection<UUID> playersToAdd, double scrollAmount, boolean addOfflineEntries) @ L50

  • 方法名:updatePlayerList
  • 源码定位:L50
  • 返回类型:void
  • 修饰符:public

参数:

  • playersToAdd: Collection
  • scrollAmount: double
  • addOfflineEntries: boolean

说明:

TODO

private void addOnlinePlayers(Collection<UUID> playersToAdd, Map<UUID,PlayerEntry> output) @ L61

  • 方法名:addOnlinePlayers
  • 源码定位:L61
  • 返回类型:void
  • 修饰符:private

参数:

  • playersToAdd: Collection
  • output: Map<UUID,PlayerEntry>

说明:

TODO

private void addSeenPlayers(Map<UUID,PlayerEntry> newEntries) @ L73

  • 方法名:addSeenPlayers
  • 源码定位:L73
  • 返回类型:void
  • 修饰符:private

参数:

  • newEntries: Map<UUID,PlayerEntry>

说明:

TODO

private PlayerEntry makePlayerEntry(UUID id, PlayerInfo playerInfo) @ L85

  • 方法名:makePlayerEntry
  • 源码定位:L85
  • 返回类型:PlayerEntry
  • 修饰符:private

参数:

  • id: UUID
  • playerInfo: PlayerInfo

说明:

TODO

private void updatePlayersFromChatLog(Map<UUID,PlayerEntry> entries, boolean addOfflineEntries) @ L91

  • 方法名:updatePlayersFromChatLog
  • 源码定位:L91
  • 返回类型:void
  • 修饰符:private

参数:

  • entries: Map<UUID,PlayerEntry>
  • addOfflineEntries: boolean

说明:

TODO

private static Map<UUID,GameProfile> collectProfilesFromChatLog(ChatLog chatLog) @ L124

  • 方法名:collectProfilesFromChatLog
  • 源码定位:L124
  • 返回类型:Map<UUID,GameProfile>
  • 修饰符:private static

参数:

  • chatLog: ChatLog

说明:

TODO

private void sortPlayerEntries() @ L136

  • 方法名:sortPlayerEntries
  • 源码定位:L136
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

private void updateFiltersAndScroll(Collection<PlayerEntry> newEntries, double scrollAmount) @ L169

  • 方法名:updateFiltersAndScroll
  • 源码定位:L169
  • 返回类型:void
  • 修饰符:private

参数:

  • newEntries: Collection
  • scrollAmount: double

说明:

TODO

private void updateFilteredPlayers() @ L178

  • 方法名:updateFilteredPlayers
  • 源码定位:L178
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

public void setFilter(String filter) @ L185

  • 方法名:setFilter
  • 源码定位:L185
  • 返回类型:void
  • 修饰符:public

参数:

  • filter: String

说明:

TODO

public boolean isEmpty() @ L189

  • 方法名:isEmpty
  • 源码定位:L189
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public void addPlayer(PlayerInfo player, SocialInteractionsScreen.Page page) @ L193

  • 方法名:addPlayer
  • 源码定位:L193
  • 返回类型:void
  • 修饰符:public

参数:

  • player: PlayerInfo
  • page: SocialInteractionsScreen.Page

说明:

TODO

public void removePlayer(UUID id) @ L214

  • 方法名:removePlayer
  • 源码定位:L214
  • 返回类型:void
  • 修饰符:public

参数:

  • id: UUID

说明:

TODO

public void refreshHasDraftReport() @ L223

  • 方法名:refreshHasDraftReport
  • 源码定位:L223
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class SocialInteractionsPlayerList extends ContainerObjectSelectionList<PlayerEntry> {
    private final SocialInteractionsScreen socialInteractionsScreen;
    private final List<PlayerEntry> players = Lists.newArrayList();
    private @Nullable 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 extractListBackground(GuiGraphicsExtractor graphics) {
    }
 
    @Override
    protected void extractListSeparators(GuiGraphicsExtractor graphics) {
    }
 
    @Override
    protected void enableScissor(GuiGraphicsExtractor graphics) {
        graphics.enableScissor(this.getX(), this.getY() + 4, this.getRight(), this.getBottom());
    }
 
    public void updatePlayerList(Collection<UUID> playersToAdd, double scrollAmount, boolean addOfflineEntries) {
        Map<UUID, PlayerEntry> newEntries = new HashMap<>();
        this.addOnlinePlayers(playersToAdd, newEntries);
        if (addOfflineEntries) {
            this.addSeenPlayers(newEntries);
        }
 
        this.updatePlayersFromChatLog(newEntries, addOfflineEntries);
        this.updateFiltersAndScroll(newEntries.values(), scrollAmount);
    }
 
    private void addOnlinePlayers(Collection<UUID> playersToAdd, Map<UUID, PlayerEntry> output) {
        ClientPacketListener connection = this.minecraft.player.connection;
 
        for (UUID id : playersToAdd) {
            PlayerInfo playerInfo = connection.getPlayerInfo(id);
            if (playerInfo != null) {
                PlayerEntry player = this.makePlayerEntry(id, playerInfo);
                output.put(id, player);
            }
        }
    }
 
    private void addSeenPlayers(Map<UUID, PlayerEntry> newEntries) {
        Map<UUID, PlayerInfo> seenPlayers = this.minecraft.player.connection.getSeenPlayers();
 
        for (Map.Entry<UUID, PlayerInfo> entry : seenPlayers.entrySet()) {
            newEntries.computeIfAbsent(entry.getKey(), uuid -> {
                PlayerEntry player = this.makePlayerEntry(uuid, entry.getValue());
                player.setRemoved(true);
                return player;
            });
        }
    }
 
    private PlayerEntry makePlayerEntry(UUID id, PlayerInfo playerInfo) {
        return new PlayerEntry(
            this.minecraft, this.socialInteractionsScreen, id, playerInfo.getProfile().name(), playerInfo::getSkin, playerInfo.hasVerifiableChat()
        );
    }
 
    private void updatePlayersFromChatLog(Map<UUID, PlayerEntry> entries, boolean addOfflineEntries) {
        Map<UUID, GameProfile> gameProfiles = collectProfilesFromChatLog(this.minecraft.getReportingContext().chatLog());
        gameProfiles.forEach(
            (id, gameProfile) -> {
                PlayerEntry entry;
                if (addOfflineEntries) {
                    entry = entries.computeIfAbsent(
                        id,
                        uuid -> {
                            PlayerEntry player = new PlayerEntry(
                                this.minecraft,
                                this.socialInteractionsScreen,
                                gameProfile.id(),
                                gameProfile.name(),
                                this.minecraft.getSkinManager().createLookup(gameProfile, true),
                                true
                            );
                            player.setRemoved(true);
                            return player;
                        }
                    );
                } else {
                    entry = entries.get(id);
                    if (entry == null) {
                        return;
                    }
                }
 
                entry.setHasRecentMessages(true);
            }
        );
    }
 
    private static Map<UUID, GameProfile> collectProfilesFromChatLog(ChatLog chatLog) {
        Map<UUID, GameProfile> gameProfiles = new Object2ObjectLinkedOpenHashMap<>();
 
        for (int id = chatLog.end(); id >= chatLog.start(); id--) {
            if (chatLog.lookup(id) instanceof LoggedChatMessage.Player message && message.message().hasSignature()) {
                gameProfiles.put(message.profileId(), message.profile());
            }
        }
 
        return gameProfiles;
    }
 
    private void sortPlayerEntries() {
        this.players
            .sort(
                Comparator.<PlayerEntry, Integer>comparing(e -> {
                        if (this.minecraft.isLocalPlayer(e.getPlayerId())) {
                            return 0;
                        } else if (this.minecraft.getReportingContext().hasDraftReportFor(e.getPlayerId())) {
                            return 1;
                        } else if (e.getPlayerId().version() == 2) {
                            return 4;
                        } else {
                            return e.hasRecentMessages() ? 2 : 3;
                        }
                    })
                    .thenComparing(
                        e -> {
                            if (!e.getPlayerName().isBlank()) {
                                int firstCodepoint = e.getPlayerName().codePointAt(0);
                                if (firstCodepoint == 95
                                    || firstCodepoint >= 97 && firstCodepoint <= 122
                                    || firstCodepoint >= 65 && firstCodepoint <= 90
                                    || firstCodepoint >= 48 && firstCodepoint <= 57) {
                                    return 0;
                                }
                            }
 
                            return 1;
                        }
                    )
                    .thenComparing(PlayerEntry::getPlayerName, String::compareToIgnoreCase)
            );
    }
 
    private void updateFiltersAndScroll(Collection<PlayerEntry> newEntries, double scrollAmount) {
        this.players.clear();
        this.players.addAll(newEntries);
        this.sortPlayerEntries();
        this.updateFilteredPlayers();
        this.replaceEntries(this.players);
        this.setScrollAmount(scrollAmount);
    }
 
    private void updateFilteredPlayers() {
        if (this.filter != null) {
            this.players.removeIf(p -> !p.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 player, SocialInteractionsScreen.Page page) {
        UUID playerId = player.getProfile().id();
 
        for (PlayerEntry playerEntry : this.players) {
            if (playerEntry.getPlayerId().equals(playerId)) {
                playerEntry.setRemoved(false);
                return;
            }
        }
 
        if ((page == SocialInteractionsScreen.Page.ALL || this.minecraft.getPlayerSocialManager().shouldHideMessageFrom(playerId))
            && (Strings.isNullOrEmpty(this.filter) || player.getProfile().name().toLowerCase(Locale.ROOT).contains(this.filter))) {
            boolean chatReportable = player.hasVerifiableChat();
            PlayerEntry playerEntryx = new PlayerEntry(
                this.minecraft, this.socialInteractionsScreen, player.getProfile().id(), player.getProfile().name(), player::getSkin, chatReportable
            );
            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;
            }
        }
    }
 
    public void refreshHasDraftReport() {
        this.players.forEach(playerEntry -> playerEntry.refreshHasDraftReport(this.minecraft.getReportingContext()));
    }
}

引用的其他类