ServerSelectionList.java
net.minecraft.client.gui.screens.multiplayer.ServerSelectionList
信息
- 全限定名:net.minecraft.client.gui.screens.multiplayer.ServerSelectionList
- 类型:public class
- 包:net.minecraft.client.gui.screens.multiplayer
- 源码路径:src/main/java/net/minecraft/client/gui/screens/multiplayer/ServerSelectionList.java
- 起始行号:L43
- 继承:ObjectSelectionList<ServerSelectionList.Entry>
- 职责:
TODO
字段/常量
-
INCOMPATIBLE_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L44 - 说明:
TODO
- 类型:
-
UNREACHABLE_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L45 - 说明:
TODO
- 类型:
-
PING_1_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L46 - 说明:
TODO
- 类型:
-
PING_2_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L47 - 说明:
TODO
- 类型:
-
PING_3_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L48 - 说明:
TODO
- 类型:
-
PING_4_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L49 - 说明:
TODO
- 类型:
-
PING_5_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L50 - 说明:
TODO
- 类型:
-
PINGING_1_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L51 - 说明:
TODO
- 类型:
-
PINGING_2_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L52 - 说明:
TODO
- 类型:
-
PINGING_3_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L53 - 说明:
TODO
- 类型:
-
PINGING_4_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L54 - 说明:
TODO
- 类型:
-
PINGING_5_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L55 - 说明:
TODO
- 类型:
-
JOIN_HIGHLIGHTED_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L56 - 说明:
TODO
- 类型:
-
JOIN_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L57 - 说明:
TODO
- 类型:
-
MOVE_UP_HIGHLIGHTED_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L58 - 说明:
TODO
- 类型:
-
MOVE_UP_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L59 - 说明:
TODO
- 类型:
-
MOVE_DOWN_HIGHLIGHTED_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L60 - 说明:
TODO
- 类型:
-
MOVE_DOWN_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L61 - 说明:
TODO
- 类型:
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L62 - 说明:
TODO
- 类型:
-
THREAD_POOL- 类型:
ThreadPoolExecutor - 修饰符:
private static final - 源码定位:
L63 - 说明:
TODO
- 类型:
-
SCANNING_LABEL- 类型:
Component - 修饰符:
private static final - 源码定位:
L71 - 说明:
TODO
- 类型:
-
CANT_RESOLVE_TEXT- 类型:
Component - 修饰符:
private static final - 源码定位:
L72 - 说明:
TODO
- 类型:
-
CANT_CONNECT_TEXT- 类型:
Component - 修饰符:
private static final - 源码定位:
L73 - 说明:
TODO
- 类型:
-
INCOMPATIBLE_STATUS- 类型:
Component - 修饰符:
private static final - 源码定位:
L74 - 说明:
TODO
- 类型:
-
NO_CONNECTION_STATUS- 类型:
Component - 修饰符:
private static final - 源码定位:
L75 - 说明:
TODO
- 类型:
-
PINGING_STATUS- 类型:
Component - 修饰符:
private static final - 源码定位:
L76 - 说明:
TODO
- 类型:
-
ONLINE_STATUS- 类型:
Component - 修饰符:
private static final - 源码定位:
L77 - 说明:
TODO
- 类型:
-
screen- 类型:
JoinMultiplayerScreen - 修饰符:
private final - 源码定位:
L78 - 说明:
TODO
- 类型:
-
onlineServers- 类型:
List<ServerSelectionList.OnlineServerEntry> - 修饰符:
private final - 源码定位:
L79 - 说明:
TODO
- 类型:
-
lanHeader- 类型:
ServerSelectionList.Entry - 修饰符:
private final - 源码定位:
L80 - 说明:
TODO
- 类型:
-
networkServers- 类型:
List<ServerSelectionList.NetworkServerEntry> - 修饰符:
private final - 源码定位:
L81 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.client.gui.screens.multiplayer.ServerSelectionList.Entry- 类型:
class - 修饰符:
public abstract static - 源码定位:
L149 - 说明:
TODO
- 类型:
-
net.minecraft.client.gui.screens.multiplayer.ServerSelectionList.LANHeader- 类型:
class - 修饰符:
public static - 源码定位:
L160 - 说明:
TODO
- 类型:
-
net.minecraft.client.gui.screens.multiplayer.ServerSelectionList.NetworkServerEntry- 类型:
class - 修饰符:
public static - 源码定位:
L187 - 说明:
TODO
- 类型:
-
net.minecraft.client.gui.screens.multiplayer.ServerSelectionList.OnlineServerEntry- 类型:
class - 修饰符:
public - 源码定位:
L252 - 说明:
TODO
- 类型:
构造器
public ServerSelectionList(JoinMultiplayerScreen screen, Minecraft minecraft, int width, int height, int y, int itemHeight) @ L83
- 构造器名:ServerSelectionList
- 源码定位:L83
- 修饰符:public
参数:
- screen: JoinMultiplayerScreen
- minecraft: Minecraft
- width: int
- height: int
- y: int
- itemHeight: int
说明:
TODO
方法
下面的方法块按源码顺序生成。
private void refreshEntries() @ L88
- 方法名:refreshEntries
- 源码定位:L88
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
public void setSelected(ServerSelectionList.Entry selected) @ L104
- 方法名:setSelected
- 源码定位:L104
- 返回类型:void
- 修饰符:public
参数:
- selected: ServerSelectionList.Entry
说明:
TODO
public void updateOnlineServers(ServerList servers) @ L109
- 方法名:updateOnlineServers
- 源码定位:L109
- 返回类型:void
- 修饰符:public
参数:
- servers: ServerList
说明:
TODO
public void updateNetworkServers(List<LanServer> servers) @ L119
- 方法名:updateNetworkServers
- 源码定位:L119
- 返回类型:void
- 修饰符:public
参数:
- servers: List
说明:
TODO
public int getRowWidth() @ L140
- 方法名:getRowWidth
- 源码定位:L140
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
public void removed() @ L145
- 方法名:removed
- 源码定位:L145
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class ServerSelectionList extends ObjectSelectionList<ServerSelectionList.Entry> {
private static final Identifier INCOMPATIBLE_SPRITE = Identifier.withDefaultNamespace("server_list/incompatible");
private static final Identifier UNREACHABLE_SPRITE = Identifier.withDefaultNamespace("server_list/unreachable");
private static final Identifier PING_1_SPRITE = Identifier.withDefaultNamespace("server_list/ping_1");
private static final Identifier PING_2_SPRITE = Identifier.withDefaultNamespace("server_list/ping_2");
private static final Identifier PING_3_SPRITE = Identifier.withDefaultNamespace("server_list/ping_3");
private static final Identifier PING_4_SPRITE = Identifier.withDefaultNamespace("server_list/ping_4");
private static final Identifier PING_5_SPRITE = Identifier.withDefaultNamespace("server_list/ping_5");
private static final Identifier PINGING_1_SPRITE = Identifier.withDefaultNamespace("server_list/pinging_1");
private static final Identifier PINGING_2_SPRITE = Identifier.withDefaultNamespace("server_list/pinging_2");
private static final Identifier PINGING_3_SPRITE = Identifier.withDefaultNamespace("server_list/pinging_3");
private static final Identifier PINGING_4_SPRITE = Identifier.withDefaultNamespace("server_list/pinging_4");
private static final Identifier PINGING_5_SPRITE = Identifier.withDefaultNamespace("server_list/pinging_5");
private static final Identifier JOIN_HIGHLIGHTED_SPRITE = Identifier.withDefaultNamespace("server_list/join_highlighted");
private static final Identifier JOIN_SPRITE = Identifier.withDefaultNamespace("server_list/join");
private static final Identifier MOVE_UP_HIGHLIGHTED_SPRITE = Identifier.withDefaultNamespace("server_list/move_up_highlighted");
private static final Identifier MOVE_UP_SPRITE = Identifier.withDefaultNamespace("server_list/move_up");
private static final Identifier MOVE_DOWN_HIGHLIGHTED_SPRITE = Identifier.withDefaultNamespace("server_list/move_down_highlighted");
private static final Identifier MOVE_DOWN_SPRITE = Identifier.withDefaultNamespace("server_list/move_down");
private static final Logger LOGGER = LogUtils.getLogger();
private static final ThreadPoolExecutor THREAD_POOL = new ScheduledThreadPoolExecutor(
5,
new ThreadFactoryBuilder()
.setNameFormat("Server Pinger #%d")
.setDaemon(true)
.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER))
.build()
);
private static final Component SCANNING_LABEL = Component.translatable("lanServer.scanning");
private static final Component CANT_RESOLVE_TEXT = Component.translatable("multiplayer.status.cannot_resolve").withColor(-65536);
private static final Component CANT_CONNECT_TEXT = Component.translatable("multiplayer.status.cannot_connect").withColor(-65536);
private static final Component INCOMPATIBLE_STATUS = Component.translatable("multiplayer.status.incompatible");
private static final Component NO_CONNECTION_STATUS = Component.translatable("multiplayer.status.no_connection");
private static final Component PINGING_STATUS = Component.translatable("multiplayer.status.pinging");
private static final Component ONLINE_STATUS = Component.translatable("multiplayer.status.online");
private final JoinMultiplayerScreen screen;
private final List<ServerSelectionList.OnlineServerEntry> onlineServers = Lists.newArrayList();
private final ServerSelectionList.Entry lanHeader = new ServerSelectionList.LANHeader();
private final List<ServerSelectionList.NetworkServerEntry> networkServers = Lists.newArrayList();
public ServerSelectionList(JoinMultiplayerScreen screen, Minecraft minecraft, int width, int height, int y, int itemHeight) {
super(minecraft, width, height, y, itemHeight);
this.screen = screen;
}
private void refreshEntries() {
ServerSelectionList.Entry previouslySelected = this.getSelected();
List<ServerSelectionList.Entry> entriesToAdd = new ArrayList<>(this.onlineServers);
entriesToAdd.add(this.lanHeader);
entriesToAdd.addAll(this.networkServers);
this.replaceEntries(entriesToAdd);
if (previouslySelected != null) {
for (ServerSelectionList.Entry entry : entriesToAdd) {
if (entry.matches(previouslySelected)) {
this.setSelected(entry);
break;
}
}
}
}
public void setSelected(ServerSelectionList.@Nullable Entry selected) {
super.setSelected(selected);
this.screen.onSelectedChange();
}
public void updateOnlineServers(ServerList servers) {
this.onlineServers.clear();
for (int i = 0; i < servers.size(); i++) {
this.onlineServers.add(new ServerSelectionList.OnlineServerEntry(this.screen, servers.get(i)));
}
this.refreshEntries();
}
public void updateNetworkServers(List<LanServer> servers) {
int newServerCount = servers.size() - this.networkServers.size();
this.networkServers.clear();
for (LanServer server : servers) {
this.networkServers.add(new ServerSelectionList.NetworkServerEntry(this.screen, server));
}
this.refreshEntries();
for (int i = this.networkServers.size() - newServerCount; i < this.networkServers.size(); i++) {
ServerSelectionList.NetworkServerEntry newServer = this.networkServers.get(i);
int entryIndex = i - this.networkServers.size() + this.children().size();
int rowTop = this.getRowTop(entryIndex);
int rowBottom = this.getRowBottom(entryIndex);
if (rowBottom >= this.getY() && rowTop <= this.getBottom()) {
this.minecraft.getNarrator().saySystemQueued(Component.translatable("multiplayer.lan.server_found", newServer.getServerNarration()));
}
}
}
@Override
public int getRowWidth() {
return 305;
}
public void removed() {
}
@OnlyIn(Dist.CLIENT)
public abstract static class Entry extends ObjectSelectionList.Entry<ServerSelectionList.Entry> implements AutoCloseable {
@Override
public void close() {
}
abstract boolean matches(final ServerSelectionList.Entry other);
public abstract void join();
}
@OnlyIn(Dist.CLIENT)
public static class LANHeader extends ServerSelectionList.Entry {
private final Minecraft minecraft = Minecraft.getInstance();
private final LoadingDotsWidget loadingDotsWidget = new LoadingDotsWidget(this.minecraft.font, ServerSelectionList.SCANNING_LABEL);
@Override
public void extractContent(GuiGraphicsExtractor graphics, int mouseX, int mouseY, boolean hovered, float a) {
this.loadingDotsWidget
.setPosition(this.getContentXMiddle() - this.minecraft.font.width(ServerSelectionList.SCANNING_LABEL) / 2, this.getContentY());
this.loadingDotsWidget.extractRenderState(graphics, mouseX, mouseY, a);
}
@Override
public Component getNarration() {
return ServerSelectionList.SCANNING_LABEL;
}
@Override
boolean matches(ServerSelectionList.Entry other) {
return other instanceof ServerSelectionList.LANHeader;
}
@Override
public void join() {
}
}
@OnlyIn(Dist.CLIENT)
public static class NetworkServerEntry extends ServerSelectionList.Entry {
private static final int ICON_WIDTH = 32;
private static final Component LAN_SERVER_HEADER = Component.translatable("lanServer.title");
private static final Component HIDDEN_ADDRESS_TEXT = Component.translatable("selectServer.hiddenAddress");
private final JoinMultiplayerScreen screen;
protected final Minecraft minecraft;
protected final LanServer serverData;
protected NetworkServerEntry(JoinMultiplayerScreen screen, LanServer serverData) {
this.screen = screen;
this.serverData = serverData;
this.minecraft = Minecraft.getInstance();
}
@Override
public void extractContent(GuiGraphicsExtractor graphics, int mouseX, int mouseY, boolean hovered, float a) {
graphics.text(this.minecraft.font, LAN_SERVER_HEADER, this.getContentX() + 32 + 3, this.getContentY() + 1, -1);
graphics.text(this.minecraft.font, this.serverData.getMotd(), this.getContentX() + 32 + 3, this.getContentY() + 12, -8355712);
if (this.minecraft.options.hideServerAddress) {
graphics.text(this.minecraft.font, HIDDEN_ADDRESS_TEXT, this.getContentX() + 32 + 3, this.getContentY() + 12 + 11, -8355712);
} else {
graphics.text(this.minecraft.font, this.serverData.getAddress(), this.getContentX() + 32 + 3, this.getContentY() + 12 + 11, -8355712);
}
}
@Override
public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) {
if (doubleClick) {
this.join();
}
return super.mouseClicked(event, doubleClick);
}
@Override
public boolean keyPressed(KeyEvent event) {
if (event.isSelection()) {
this.join();
return true;
} else {
return super.keyPressed(event);
}
}
@Override
public void join() {
this.screen.join(new ServerData(this.serverData.getMotd(), this.serverData.getAddress(), ServerData.Type.LAN));
}
@Override
public Component getNarration() {
return Component.translatable("narrator.select", this.getServerNarration());
}
public Component getServerNarration() {
return Component.empty().append(LAN_SERVER_HEADER).append(CommonComponents.SPACE).append(this.serverData.getMotd());
}
@Override
boolean matches(ServerSelectionList.Entry other) {
return other instanceof ServerSelectionList.NetworkServerEntry networkServerEntry && networkServerEntry.serverData == this.serverData;
}
}
@OnlyIn(Dist.CLIENT)
public class OnlineServerEntry extends ServerSelectionList.Entry implements SelectableEntry {
private static final int ICON_SIZE = 32;
private static final int SPACING = 5;
private static final int STATUS_ICON_WIDTH = 10;
private static final int STATUS_ICON_HEIGHT = 8;
private final JoinMultiplayerScreen screen;
private final Minecraft minecraft;
private final ServerData serverData;
private final FaviconTexture icon;
private byte @Nullable [] lastIconBytes;
private @Nullable List<Component> onlinePlayersTooltip;
private @Nullable Identifier statusIcon;
private @Nullable Component statusIconTooltip;
protected OnlineServerEntry(JoinMultiplayerScreen screen, ServerData serverData) {
Objects.requireNonNull(ServerSelectionList.this);
super();
this.screen = screen;
this.serverData = serverData;
this.minecraft = Minecraft.getInstance();
this.icon = FaviconTexture.forServer(this.minecraft.getTextureManager(), serverData.ip);
this.refreshStatus();
}
@Override
public void extractContent(GuiGraphicsExtractor graphics, int mouseX, int mouseY, boolean hovered, float a) {
if (this.serverData.state() == ServerData.State.INITIAL) {
this.serverData.setState(ServerData.State.PINGING);
this.serverData.motd = CommonComponents.EMPTY;
this.serverData.status = CommonComponents.EMPTY;
ServerSelectionList.THREAD_POOL
.submit(
() -> {
try {
this.screen
.getPinger()
.pingServer(
this.serverData,
() -> this.minecraft.execute(this::updateServerList),
() -> {
this.serverData
.setState(
this.serverData.protocol == SharedConstants.getCurrentVersion().protocolVersion()
? ServerData.State.SUCCESSFUL
: ServerData.State.INCOMPATIBLE
);
this.minecraft.execute(this::refreshStatus);
},
EventLoopGroupHolder.remote(this.minecraft.options.useNativeTransport())
);
} catch (UnknownHostException var2) {
this.serverData.setState(ServerData.State.UNREACHABLE);
this.serverData.motd = ServerSelectionList.CANT_RESOLVE_TEXT;
this.minecraft.execute(this::refreshStatus);
} catch (Exception var3) {
this.serverData.setState(ServerData.State.UNREACHABLE);
this.serverData.motd = ServerSelectionList.CANT_CONNECT_TEXT;
this.minecraft.execute(this::refreshStatus);
}
}
);
}
graphics.text(this.minecraft.font, this.serverData.name, this.getContentX() + 32 + 3, this.getContentY() + 1, -1);
List<FormattedCharSequence> lines = this.minecraft.font.split(this.serverData.motd, this.getContentWidth() - 32 - 2);
for (int i = 0; i < Math.min(lines.size(), 2); i++) {
graphics.text(this.minecraft.font, lines.get(i), this.getContentX() + 32 + 3, this.getContentY() + 12 + 9 * i, -8355712);
}
this.extractIcon(graphics, this.getContentX(), this.getContentY(), this.icon.textureLocation());
int index = ServerSelectionList.this.children().indexOf(this);
if (this.serverData.state() == ServerData.State.PINGING) {
int iconIndex = (int)(Util.getMillis() / 100L + index * 2 & 7L);
if (iconIndex > 4) {
iconIndex = 8 - iconIndex;
}
this.statusIcon = switch (iconIndex) {
case 1 -> ServerSelectionList.PINGING_2_SPRITE;
case 2 -> ServerSelectionList.PINGING_3_SPRITE;
case 3 -> ServerSelectionList.PINGING_4_SPRITE;
case 4 -> ServerSelectionList.PINGING_5_SPRITE;
default -> ServerSelectionList.PINGING_1_SPRITE;
};
}
int statusIconX = this.getContentRight() - 10 - 5;
if (this.statusIcon != null) {
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, this.statusIcon, statusIconX, this.getContentY(), 10, 8);
}
byte[] currentIconBytes = this.serverData.getIconBytes();
if (!Arrays.equals(currentIconBytes, this.lastIconBytes)) {
if (this.uploadServerIcon(currentIconBytes)) {
this.lastIconBytes = currentIconBytes;
} else {
this.serverData.setIconBytes(null);
this.updateServerList();
}
}
Component status = (Component)(this.serverData.state() == ServerData.State.INCOMPATIBLE
? this.serverData.version.copy().withStyle(ChatFormatting.RED)
: this.serverData.status);
int statusWidth = this.minecraft.font.width(status);
int statusX = statusIconX - statusWidth - 5;
graphics.text(this.minecraft.font, status, statusX, this.getContentY() + 1, -8355712);
if (this.statusIconTooltip != null
&& mouseX >= statusIconX
&& mouseX <= statusIconX + 10
&& mouseY >= this.getContentY()
&& mouseY <= this.getContentY() + 8) {
graphics.setTooltipForNextFrame(this.statusIconTooltip, mouseX, mouseY);
} else if (this.onlinePlayersTooltip != null
&& mouseX >= statusX
&& mouseX <= statusX + statusWidth
&& mouseY >= this.getContentY()
&& mouseY <= this.getContentY() - 1 + 9) {
graphics.setTooltipForNextFrame(Lists.transform(this.onlinePlayersTooltip, Component::getVisualOrderText), mouseX, mouseY);
}
if (this.minecraft.options.touchscreen().get() || hovered) {
graphics.fill(this.getContentX(), this.getContentY(), this.getContentX() + 32, this.getContentY() + 32, -1601138544);
int relX = mouseX - this.getContentX();
int relY = mouseY - this.getContentY();
if (this.mouseOverRightHalf(relX, relY, 32)) {
graphics.blitSprite(
RenderPipelines.GUI_TEXTURED, ServerSelectionList.JOIN_HIGHLIGHTED_SPRITE, this.getContentX(), this.getContentY(), 32, 32
);
ServerSelectionList.this.handleCursor(graphics);
} else {
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, ServerSelectionList.JOIN_SPRITE, this.getContentX(), this.getContentY(), 32, 32);
}
if (index > 0) {
if (this.mouseOverTopLeftQuarter(relX, relY, 32)) {
graphics.blitSprite(
RenderPipelines.GUI_TEXTURED, ServerSelectionList.MOVE_UP_HIGHLIGHTED_SPRITE, this.getContentX(), this.getContentY(), 32, 32
);
ServerSelectionList.this.handleCursor(graphics);
} else {
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, ServerSelectionList.MOVE_UP_SPRITE, this.getContentX(), this.getContentY(), 32, 32);
}
}
if (index < this.screen.getServers().size() - 1) {
if (this.mouseOverBottomLeftQuarter(relX, relY, 32)) {
graphics.blitSprite(
RenderPipelines.GUI_TEXTURED, ServerSelectionList.MOVE_DOWN_HIGHLIGHTED_SPRITE, this.getContentX(), this.getContentY(), 32, 32
);
ServerSelectionList.this.handleCursor(graphics);
} else {
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, ServerSelectionList.MOVE_DOWN_SPRITE, this.getContentX(), this.getContentY(), 32, 32);
}
}
}
}
private void refreshStatus() {
this.onlinePlayersTooltip = null;
switch (this.serverData.state()) {
case INITIAL:
case PINGING:
this.statusIcon = ServerSelectionList.PING_1_SPRITE;
this.statusIconTooltip = ServerSelectionList.PINGING_STATUS;
break;
case INCOMPATIBLE:
this.statusIcon = ServerSelectionList.INCOMPATIBLE_SPRITE;
this.statusIconTooltip = ServerSelectionList.INCOMPATIBLE_STATUS;
this.onlinePlayersTooltip = this.serverData.playerList;
break;
case UNREACHABLE:
this.statusIcon = ServerSelectionList.UNREACHABLE_SPRITE;
this.statusIconTooltip = ServerSelectionList.NO_CONNECTION_STATUS;
break;
case SUCCESSFUL:
if (this.serverData.ping < 150L) {
this.statusIcon = ServerSelectionList.PING_5_SPRITE;
} else if (this.serverData.ping < 300L) {
this.statusIcon = ServerSelectionList.PING_4_SPRITE;
} else if (this.serverData.ping < 600L) {
this.statusIcon = ServerSelectionList.PING_3_SPRITE;
} else if (this.serverData.ping < 1000L) {
this.statusIcon = ServerSelectionList.PING_2_SPRITE;
} else {
this.statusIcon = ServerSelectionList.PING_1_SPRITE;
}
this.statusIconTooltip = Component.translatable("multiplayer.status.ping", this.serverData.ping);
this.onlinePlayersTooltip = this.serverData.playerList;
}
}
public void updateServerList() {
this.screen.getServers().save();
}
protected void extractIcon(GuiGraphicsExtractor graphics, int rowLeft, int rowTop, Identifier location) {
graphics.blit(RenderPipelines.GUI_TEXTURED, location, rowLeft, rowTop, 0.0F, 0.0F, 32, 32, 32, 32);
}
private boolean uploadServerIcon(byte @Nullable [] serverIconBytes) {
if (serverIconBytes == null) {
this.icon.clear();
} else {
try {
this.icon.upload(NativeImage.read(serverIconBytes));
} catch (Throwable var3) {
ServerSelectionList.LOGGER.error("Invalid icon for server {} ({})", this.serverData.name, this.serverData.ip, var3);
return false;
}
}
return true;
}
@Override
public boolean keyPressed(KeyEvent event) {
if (event.isSelection()) {
this.join();
return true;
} else {
if (event.hasShiftDown()) {
ServerSelectionList list = this.screen.serverSelectionList;
int currentIndex = list.children().indexOf(this);
if (currentIndex == -1) {
return true;
}
if (event.isDown() && currentIndex < this.screen.getServers().size() - 1 || event.isUp() && currentIndex > 0) {
this.swap(currentIndex, event.isDown() ? currentIndex + 1 : currentIndex - 1);
return true;
}
}
return super.keyPressed(event);
}
}
@Override
public void join() {
this.screen.join(this.serverData);
}
private void swap(int currentIndex, int newIndex) {
this.screen.getServers().swap(currentIndex, newIndex);
this.screen.serverSelectionList.swap(currentIndex, newIndex);
}
@Override
public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) {
int relX = (int)event.x() - this.getContentX();
int relY = (int)event.y() - this.getContentY();
if (this.mouseOverRightHalf(relX, relY, 32)) {
this.join();
return true;
} else {
int currentIndex = this.screen.serverSelectionList.children().indexOf(this);
if (currentIndex > 0 && this.mouseOverTopLeftQuarter(relX, relY, 32)) {
this.swap(currentIndex, currentIndex - 1);
return true;
} else if (currentIndex < this.screen.getServers().size() - 1 && this.mouseOverBottomLeftQuarter(relX, relY, 32)) {
this.swap(currentIndex, currentIndex + 1);
return true;
} else {
if (doubleClick) {
this.join();
}
return super.mouseClicked(event, doubleClick);
}
}
}
public ServerData getServerData() {
return this.serverData;
}
@Override
public Component getNarration() {
MutableComponent narrationComponent = Component.empty();
narrationComponent.append(Component.translatable("narrator.select", this.serverData.name));
narrationComponent.append(CommonComponents.NARRATION_SEPARATOR);
switch (this.serverData.state()) {
case PINGING:
narrationComponent.append(ServerSelectionList.PINGING_STATUS);
break;
case INCOMPATIBLE:
narrationComponent.append(ServerSelectionList.INCOMPATIBLE_STATUS);
narrationComponent.append(CommonComponents.NARRATION_SEPARATOR);
narrationComponent.append(Component.translatable("multiplayer.status.version.narration", this.serverData.version));
narrationComponent.append(CommonComponents.NARRATION_SEPARATOR);
narrationComponent.append(Component.translatable("multiplayer.status.motd.narration", this.serverData.motd));
break;
case UNREACHABLE:
narrationComponent.append(ServerSelectionList.NO_CONNECTION_STATUS);
break;
default:
narrationComponent.append(ServerSelectionList.ONLINE_STATUS);
narrationComponent.append(CommonComponents.NARRATION_SEPARATOR);
narrationComponent.append(Component.translatable("multiplayer.status.ping.narration", this.serverData.ping));
narrationComponent.append(CommonComponents.NARRATION_SEPARATOR);
narrationComponent.append(Component.translatable("multiplayer.status.motd.narration", this.serverData.motd));
if (this.serverData.players != null) {
narrationComponent.append(CommonComponents.NARRATION_SEPARATOR);
narrationComponent.append(
Component.translatable("multiplayer.status.player_count.narration", this.serverData.players.online(), this.serverData.players.max())
);
narrationComponent.append(CommonComponents.NARRATION_SEPARATOR);
narrationComponent.append(ComponentUtils.formatList(this.serverData.playerList, Component.literal(", ")));
}
}
return narrationComponent;
}
@Override
public void close() {
this.icon.close();
}
@Override
boolean matches(ServerSelectionList.Entry other) {
return other instanceof ServerSelectionList.OnlineServerEntry onlineServerEntry && onlineServerEntry.serverData == this.serverData;
}
}
}引用的其他类
-
- 引用位置:
方法调用 - 关联成员:
NativeImage.read()
- 引用位置:
-
DefaultUncaughtExceptionHandler
- 引用位置:
构造调用 - 关联成员:
DefaultUncaughtExceptionHandler()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
SharedConstants.getCurrentVersion()
- 引用位置:
-
- 引用位置:
参数/方法调用 - 关联成员:
Minecraft.getInstance()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
LoadingDotsWidget()
- 引用位置:
-
- 引用位置:
继承
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
FaviconTexture.forServer()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
ServerData()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
Component.empty(), Component.literal(), Component.translatable()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ComponentUtils.formatList()
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
Identifier.withDefaultNamespace()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
EventLoopGroupHolder.remote()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Util.getMillis()
- 引用位置: