RealmsMainScreen.java
com.mojang.realmsclient.RealmsMainScreen
信息
- 全限定名:com.mojang.realmsclient.RealmsMainScreen
- 类型:public class
- 包:com.mojang.realmsclient
- 源码路径:src/main/java/com/mojang/realmsclient/RealmsMainScreen.java
- 起始行号:L90
- 继承:RealmsScreen
- 职责:
TODO
字段/常量
-
INFO_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L91 - 说明:
TODO
- 类型:
-
NEW_REALM_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L92 - 说明:
TODO
- 类型:
-
EXPIRED_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L93 - 说明:
TODO
- 类型:
-
EXPIRES_SOON_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L94 - 说明:
TODO
- 类型:
-
OPEN_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L95 - 说明:
TODO
- 类型:
-
CLOSED_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L96 - 说明:
TODO
- 类型:
-
INVITE_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L97 - 说明:
TODO
- 类型:
-
NEWS_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L98 - 说明:
TODO
- 类型:
-
HARDCORE_MODE_SPRITE- 类型:
Identifier - 修饰符:
public static final - 源码定位:
L99 - 说明:
TODO
- 类型:
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L100 - 说明:
TODO
- 类型:
-
NO_REALMS_LOCATION- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L101 - 说明:
TODO
- 类型:
-
TITLE- 类型:
Component - 修饰符:
private static final - 源码定位:
L102 - 说明:
TODO
- 类型:
-
LOADING_TEXT- 类型:
Component - 修饰符:
private static final - 源码定位:
L103 - 说明:
TODO
- 类型:
-
SERVER_UNITIALIZED_TEXT- 类型:
Component - 修饰符:
private static final - 源码定位:
L104 - 说明:
TODO
- 类型:
-
SUBSCRIPTION_EXPIRED_TEXT- 类型:
Component - 修饰符:
private static final - 源码定位:
L105 - 说明:
TODO
- 类型:
-
SUBSCRIPTION_RENEW_TEXT- 类型:
Component - 修饰符:
private static final - 源码定位:
L106 - 说明:
TODO
- 类型:
-
TRIAL_EXPIRED_TEXT- 类型:
Component - 修饰符:
private static final - 源码定位:
L107 - 说明:
TODO
- 类型:
-
PLAY_TEXT- 类型:
Component - 修饰符:
private static final - 源码定位:
L108 - 说明:
TODO
- 类型:
-
LEAVE_SERVER_TEXT- 类型:
Component - 修饰符:
private static final - 源码定位:
L109 - 说明:
TODO
- 类型:
-
CONFIGURE_SERVER_TEXT- 类型:
Component - 修饰符:
private static final - 源码定位:
L110 - 说明:
TODO
- 类型:
-
SERVER_EXPIRED_TOOLTIP- 类型:
Component - 修饰符:
private static final - 源码定位:
L111 - 说明:
TODO
- 类型:
-
SERVER_EXPIRES_SOON_TOOLTIP- 类型:
Component - 修饰符:
private static final - 源码定位:
L112 - 说明:
TODO
- 类型:
-
SERVER_EXPIRES_IN_DAY_TOOLTIP- 类型:
Component - 修饰符:
private static final - 源码定位:
L113 - 说明:
TODO
- 类型:
-
SERVER_OPEN_TOOLTIP- 类型:
Component - 修饰符:
private static final - 源码定位:
L114 - 说明:
TODO
- 类型:
-
SERVER_CLOSED_TOOLTIP- 类型:
Component - 修饰符:
private static final - 源码定位:
L115 - 说明:
TODO
- 类型:
-
UNITIALIZED_WORLD_NARRATION- 类型:
Component - 修饰符:
private static final - 源码定位:
L116 - 说明:
TODO
- 类型:
-
NO_REALMS_TEXT- 类型:
Component - 修饰符:
private static final - 源码定位:
L117 - 说明:
TODO
- 类型:
-
NO_PENDING_INVITES- 类型:
Component - 修饰符:
private static final - 源码定位:
L118 - 说明:
TODO
- 类型:
-
PENDING_INVITES- 类型:
Component - 修饰符:
private static final - 源码定位:
L119 - 说明:
TODO
- 类型:
-
INCOMPATIBLE_POPUP_TITLE- 类型:
Component - 修饰符:
private static final - 源码定位:
L120 - 说明:
TODO
- 类型:
-
INCOMPATIBLE_RELEASE_TYPE_POPUP_MESSAGE- 类型:
Component - 修饰符:
private static final - 源码定位:
L121 - 说明:
TODO
- 类型:
-
BUTTON_WIDTH- 类型:
int - 修饰符:
private static final - 源码定位:
L122 - 说明:
TODO
- 类型:
-
BUTTON_COLUMNS- 类型:
int - 修饰符:
private static final - 源码定位:
L123 - 说明:
TODO
- 类型:
-
BUTTON_SPACING- 类型:
int - 修饰符:
private static final - 源码定位:
L124 - 说明:
TODO
- 类型:
-
CONTENT_WIDTH- 类型:
int - 修饰符:
private static final - 源码定位:
L125 - 说明:
TODO
- 类型:
-
LOGO_PADDING- 类型:
int - 修饰符:
private static final - 源码定位:
L126 - 说明:
TODO
- 类型:
-
HEADER_HEIGHT- 类型:
int - 修饰符:
private static final - 源码定位:
L127 - 说明:
TODO
- 类型:
-
FOOTER_PADDING- 类型:
int - 修饰符:
private static final - 源码定位:
L128 - 说明:
TODO
- 类型:
-
NEW_REALM_SPRITE_WIDTH- 类型:
int - 修饰符:
private static final - 源码定位:
L129 - 说明:
TODO
- 类型:
-
NEW_REALM_SPRITE_HEIGHT- 类型:
int - 修饰符:
private static final - 源码定位:
L130 - 说明:
TODO
- 类型:
-
SNAPSHOT- 类型:
boolean - 修饰符:
private static final - 源码定位:
L131 - 说明:
TODO
- 类型:
-
snapshotToggle- 类型:
boolean - 修饰符:
private static - 源码定位:
L132 - 说明:
TODO
- 类型:
-
availability- 类型:
CompletableFuture<RealmsAvailability.Result> - 修饰符:
private final - 源码定位:
L133 - 说明:
TODO
- 类型:
-
dataSubscription- 类型:
DataFetcher.Subscription - 修饰符:
private - 源码定位:
L134 - 说明:
TODO
- 类型:
-
handledSeenNotifications- 类型:
Set<UUID> - 修饰符:
private final - 源码定位:
L135 - 说明:
TODO
- 类型:
-
regionsPinged- 类型:
boolean - 修饰符:
private static - 源码定位:
L136 - 说明:
TODO
- 类型:
-
inviteNarrationLimiter- 类型:
RateLimiter - 修饰符:
private final - 源码定位:
L137 - 说明:
TODO
- 类型:
-
lastScreen- 类型:
Screen - 修饰符:
private final - 源码定位:
L138 - 说明:
TODO
- 类型:
-
playButton- 类型:
Button - 修饰符:
private - 源码定位:
L139 - 说明:
TODO
- 类型:
-
backButton- 类型:
Button - 修饰符:
private - 源码定位:
L140 - 说明:
TODO
- 类型:
-
renewButton- 类型:
Button - 修饰符:
private - 源码定位:
L141 - 说明:
TODO
- 类型:
-
configureButton- 类型:
Button - 修饰符:
private - 源码定位:
L142 - 说明:
TODO
- 类型:
-
leaveButton- 类型:
Button - 修饰符:
private - 源码定位:
L143 - 说明:
TODO
- 类型:
-
realmSelectionList- 类型:
RealmsMainScreen.RealmSelectionList - 修饰符:
private - 源码定位:
L144 - 说明:
TODO
- 类型:
-
serverList- 类型:
RealmsServerList - 修饰符:
private - 源码定位:
L145 - 说明:
TODO
- 类型:
-
availableSnapshotServers- 类型:
List<RealmsServer> - 修饰符:
private - 源码定位:
L146 - 说明:
TODO
- 类型:
-
onlinePlayersPerRealm- 类型:
RealmsServerPlayerLists - 修饰符:
private - 源码定位:
L147 - 说明:
TODO
- 类型:
-
trialsAvailable- 类型:
boolean - 修饰符:
private volatile - 源码定位:
L148 - 说明:
TODO
- 类型:
-
newsLink- 类型:
String - 修饰符:
private volatile - 源码定位:
L149 - 说明:
TODO
- 类型:
-
notifications- 类型:
List<RealmsNotification> - 修饰符:
private final - 源码定位:
L150 - 说明:
TODO
- 类型:
-
addRealmButton- 类型:
Button - 修饰符:
private - 源码定位:
L151 - 说明:
TODO
- 类型:
-
pendingInvitesButton- 类型:
RealmsMainScreen.NotificationButton - 修饰符:
private - 源码定位:
L152 - 说明:
TODO
- 类型:
-
newsButton- 类型:
RealmsMainScreen.NotificationButton - 修饰符:
private - 源码定位:
L153 - 说明:
TODO
- 类型:
-
activeLayoutState- 类型:
RealmsMainScreen.LayoutState - 修饰符:
private - 源码定位:
L154 - 说明:
TODO
- 类型:
-
layout- 类型:
HeaderAndFooterLayout - 修饰符:
private - 源码定位:
L155 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
com.mojang.realmsclient.RealmsMainScreen.AvailableSnapshotEntry- 类型:
class - 修饰符:
private - 源码定位:
L700 - 说明:
TODO
- 类型:
-
com.mojang.realmsclient.RealmsMainScreen.CrossButton- 类型:
class - 修饰符:
private static - 源码定位:
L780 - 说明:
TODO
- 类型:
-
com.mojang.realmsclient.RealmsMainScreen.Entry- 类型:
class - 修饰符:
private abstract - 源码定位:
L792 - 说明:
TODO
- 类型:
-
com.mojang.realmsclient.RealmsMainScreen.LayoutState- 类型:
enum - 修饰符:
private static - 源码定位:
L944 - 说明:
TODO
- 类型:
-
com.mojang.realmsclient.RealmsMainScreen.NotificationButton- 类型:
class - 修饰符:
private static - 源码定位:
L951 - 说明:
TODO
- 类型:
-
com.mojang.realmsclient.RealmsMainScreen.NotificationMessageEntry- 类型:
class - 修饰符:
private - 源码定位:
L998 - 说明:
TODO
- 类型:
-
com.mojang.realmsclient.RealmsMainScreen.ParentEntry- 类型:
class - 修饰符:
private - 源码定位:
L1102 - 说明:
TODO
- 类型:
-
com.mojang.realmsclient.RealmsMainScreen.RealmSelectionList- 类型:
class - 修饰符:
private - 源码定位:
L1141 - 说明:
TODO
- 类型:
-
com.mojang.realmsclient.RealmsMainScreen.RealmsCall- 类型:
interface - 修饰符:
private - 源码定位:
L1213 - 说明:
TODO
- 类型:
-
com.mojang.realmsclient.RealmsMainScreen.ServerEntry- 类型:
class - 修饰符:
private - 源码定位:
L1218 - 说明:
TODO
- 类型:
构造器
public RealmsMainScreen(Screen lastScreen) @ L157
- 构造器名:RealmsMainScreen
- 源码定位:L157
- 修饰符:public
参数:
- lastScreen: Screen
说明:
TODO
方法
下面的方法块按源码顺序生成。
public void init() @ L163
- 方法名:init
- 源码定位:L163
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public static boolean isSnapshot() @ L215
- 方法名:isSnapshot
- 源码定位:L215
- 返回类型:boolean
- 修饰符:public static
参数:
- 无
说明:
TODO
protected void repositionElements() @ L219
- 方法名:repositionElements
- 源码定位:L219
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
public void onClose() @ L227
- 方法名:onClose
- 源码定位:L227
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
private void updateLayout() @ L232
- 方法名:updateLayout
- 源码定位:L232
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
private void updateLayout(RealmsMainScreen.LayoutState state) @ L240
- 方法名:updateLayout
- 源码定位:L240
- 返回类型:void
- 修饰符:private
参数:
- state: RealmsMainScreen.LayoutState
说明:
TODO
private HeaderAndFooterLayout createLayout(RealmsMainScreen.LayoutState state) @ L253
- 方法名:createLayout
- 源码定位:L253
- 返回类型:HeaderAndFooterLayout
- 修饰符:private
参数:
- state: RealmsMainScreen.LayoutState
说明:
TODO
private Layout createHeader() @ L275
- 方法名:createHeader
- 源码定位:L275
- 返回类型:Layout
- 修饰符:private
参数:
- 无
说明:
TODO
private Layout createFooter(RealmsMainScreen.LayoutState state) @ L289
- 方法名:createFooter
- 源码定位:L289
- 返回类型:Layout
- 修饰符:private
参数:
- state: RealmsMainScreen.LayoutState
说明:
TODO
private LinearLayout createNoRealmsContent() @ L304
- 方法名:createNoRealmsContent
- 源码定位:L304
- 返回类型:LinearLayout
- 修饰符:private
参数:
- 无
说明:
TODO
private void updateButtonStates() @ L318
- 方法名:updateButtonStates
- 源码定位:L318
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
private boolean shouldRenewButtonBeActive(RealmsServer server) @ L332
- 方法名:shouldRenewButtonBeActive
- 源码定位:L332
- 返回类型:boolean
- 修饰符:private
参数:
- server: RealmsServer
说明:
TODO
private boolean shouldConfigureButtonBeActive(RealmsServer server) @ L336
- 方法名:shouldConfigureButtonBeActive
- 源码定位:L336
- 返回类型:boolean
- 修饰符:private
参数:
- server: RealmsServer
说明:
TODO
private boolean shouldLeaveButtonBeActive(RealmsServer server) @ L340
- 方法名:shouldLeaveButtonBeActive
- 源码定位:L340
- 返回类型:boolean
- 修饰符:private
参数:
- server: RealmsServer
说明:
TODO
public void tick() @ L344
- 方法名:tick
- 源码定位:L344
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public static void refreshPendingInvites() @ L352
- 方法名:refreshPendingInvites
- 源码定位:L352
- 返回类型:void
- 修饰符:public static
参数:
- 无
说明:
TODO
public static void refreshServerList() @ L356
- 方法名:refreshServerList
- 源码定位:L356
- 返回类型:void
- 修饰符:public static
参数:
- 无
说明:
TODO
private void debugRefreshDataFetchers() @ L360
- 方法名:debugRefreshDataFetchers
- 源码定位:L360
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
private DataFetcher.Subscription initDataFetcher(RealmsDataFetcher dataSource) @ L366
- 方法名:initDataFetcher
- 源码定位:L366
- 返回类型:DataFetcher.Subscription
- 修饰符:private
参数:
- dataSource: RealmsDataFetcher
说明:
TODO
private void markNotificationsAsSeen(Collection<RealmsNotification> notifications) @ L421
- 方法名:markNotificationsAsSeen
- 源码定位:L421
- 返回类型:void
- 修饰符:private
参数:
- notifications: Collection
说明:
TODO
private static <T> void callRealmsClient(RealmsMainScreen.RealmsCall<T> supplier, Consumer<T> callback) @ L438
- 方法名:callRealmsClient
- 源码定位:L438
- 返回类型:
void - 修饰符:private static
参数:
- supplier: RealmsMainScreen.RealmsCall
- callback: Consumer
说明:
TODO
private void refreshListAndLayout() @ L452
- 方法名:refreshListAndLayout
- 源码定位:L452
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
private void pingRegions() @ L458
- 方法名:pingRegions
- 源码定位:L458
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
private List<Long> getOwnedNonExpiredRealmIds() @ L472
- 方法名:getOwnedNonExpiredRealmIds
- 源码定位:L472
- 返回类型:List
- 修饰符:private
参数:
- 无
说明:
TODO
private void onRenew(RealmsServer server) @ L484
- 方法名:onRenew
- 源码定位:L484
- 返回类型:void
- 修饰符:private
参数:
- server: RealmsServer
说明:
TODO
private void configureClicked(RealmsServer selectedServer) @ L497
- 方法名:configureClicked
- 源码定位:L497
- 返回类型:void
- 修饰符:private
参数:
- selectedServer: RealmsServer
说明:
TODO
private void leaveClicked(RealmsServer selectedServer) @ L503
- 方法名:leaveClicked
- 源码定位:L503
- 返回类型:void
- 修饰符:private
参数:
- selectedServer: RealmsServer
说明:
TODO
private RealmsServer getSelectedServer() @ L510
- 方法名:getSelectedServer
- 源码定位:L510
- 返回类型:RealmsServer
- 修饰符:private
参数:
- 无
说明:
TODO
private void leaveServer(RealmsServer server) @ L514
- 方法名:leaveServer
- 源码定位:L514
- 返回类型:void
- 修饰符:private
参数:
- server: RealmsServer
说明:
TODO
private void dismissNotification(UUID uuid) @ L537
- 方法名:dismissNotification
- 源码定位:L537
- 返回类型:void
- 修饰符:private
参数:
- uuid: UUID
说明:
TODO
public void resetScreen() @ L547
- 方法名:resetScreen
- 源码定位:L547
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public Component getNarrationMessage() @ L552
- 方法名:getNarrationMessage
- 源码定位:L552
- 返回类型:Component
- 修饰符:public
参数:
- 无
说明:
TODO
public void extractRenderState(GuiGraphicsExtractor graphics, int xm, int ym, float a) @ L561
- 方法名:extractRenderState
- 源码定位:L561
- 返回类型:void
- 修饰符:public
参数:
- graphics: GuiGraphicsExtractor
- xm: int
- ym: int
- a: float
说明:
TODO
private void openTrialAvailablePopup() @ L581
- 方法名:openTrialAvailablePopup
- 源码定位:L581
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
public static void play(RealmsServer server, Screen cancelScreen) @ L585
- 方法名:play
- 源码定位:L585
- 返回类型:void
- 修饰符:public static
参数:
- server: RealmsServer
- cancelScreen: Screen
说明:
TODO
public static void play(RealmsServer server, Screen cancelScreen, boolean skipCompatibility) @ L589
- 方法名:play
- 源码定位:L589
- 返回类型:void
- 修饰符:public static
参数:
- server: RealmsServer
- cancelScreen: Screen
- skipCompatibility: boolean
说明:
TODO
private static void confirmToPlay(RealmsServer server, Screen lastScreen, Component title, Component message, Component confirmButton) @ L652
- 方法名:confirmToPlay
- 源码定位:L652
- 返回类型:void
- 修饰符:private static
参数:
- server: RealmsServer
- lastScreen: Screen
- title: Component
- message: Component
- confirmButton: Component
说明:
TODO
private static void upgradeRealmAndPlay(RealmsServer server, Screen cancelScreen) @ L659
- 方法名:upgradeRealmAndPlay
- 源码定位:L659
- 返回类型:void
- 修饰符:private static
参数:
- server: RealmsServer
- cancelScreen: Screen
说明:
TODO
public static Component getVersionComponent(String version, boolean isCompatible) @ L670
- 方法名:getVersionComponent
- 源码定位:L670
- 返回类型:Component
- 修饰符:public static
参数:
- version: String
- isCompatible: boolean
说明:
TODO
public static Component getVersionComponent(String version, int color) @ L674
- 方法名:getVersionComponent
- 源码定位:L674
- 返回类型:Component
- 修饰符:public static
参数:
- version: String
- color: int
说明:
TODO
public static Component getGameModeComponent(int gameMode, boolean hardcore) @ L678
- 方法名:getGameModeComponent
- 源码定位:L678
- 返回类型:Component
- 修饰符:public static
参数:
- gameMode: int
- hardcore: boolean
说明:
TODO
private static boolean isSelfOwnedServer(RealmsServer serverData) @ L682
- 方法名:isSelfOwnedServer
- 源码定位:L682
- 返回类型:boolean
- 修饰符:private static
参数:
- serverData: RealmsServer
说明:
TODO
private boolean isSelfOwnedNonExpiredServer(RealmsServer serverData) @ L686
- 方法名:isSelfOwnedNonExpiredServer
- 源码定位:L686
- 返回类型:boolean
- 修饰符:private
参数:
- serverData: RealmsServer
说明:
TODO
private void extractEnvironment(GuiGraphicsExtractor graphics, String text, int color) @ L690
- 方法名:extractEnvironment
- 源码定位:L690
- 返回类型:void
- 修饰符:private
参数:
- graphics: GuiGraphicsExtractor
- text: String
- color: int
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class RealmsMainScreen extends RealmsScreen {
private static final Identifier INFO_SPRITE = Identifier.withDefaultNamespace("icon/info");
private static final Identifier NEW_REALM_SPRITE = Identifier.withDefaultNamespace("icon/new_realm");
private static final Identifier EXPIRED_SPRITE = Identifier.withDefaultNamespace("realm_status/expired");
private static final Identifier EXPIRES_SOON_SPRITE = Identifier.withDefaultNamespace("realm_status/expires_soon");
private static final Identifier OPEN_SPRITE = Identifier.withDefaultNamespace("realm_status/open");
private static final Identifier CLOSED_SPRITE = Identifier.withDefaultNamespace("realm_status/closed");
private static final Identifier INVITE_SPRITE = Identifier.withDefaultNamespace("icon/invite");
private static final Identifier NEWS_SPRITE = Identifier.withDefaultNamespace("icon/news");
public static final Identifier HARDCORE_MODE_SPRITE = Identifier.withDefaultNamespace("hud/heart/hardcore_full");
private static final Logger LOGGER = LogUtils.getLogger();
private static final Identifier NO_REALMS_LOCATION = Identifier.withDefaultNamespace("textures/gui/realms/no_realms.png");
private static final Component TITLE = Component.translatable("menu.online");
private static final Component LOADING_TEXT = Component.translatable("mco.selectServer.loading");
private static final Component SERVER_UNITIALIZED_TEXT = Component.translatable("mco.selectServer.uninitialized");
private static final Component SUBSCRIPTION_EXPIRED_TEXT = Component.translatable("mco.selectServer.expiredList");
private static final Component SUBSCRIPTION_RENEW_TEXT = Component.translatable("mco.selectServer.expiredRenew");
private static final Component TRIAL_EXPIRED_TEXT = Component.translatable("mco.selectServer.expiredTrial");
private static final Component PLAY_TEXT = Component.translatable("mco.selectServer.play");
private static final Component LEAVE_SERVER_TEXT = Component.translatable("mco.selectServer.leave");
private static final Component CONFIGURE_SERVER_TEXT = Component.translatable("mco.selectServer.configure");
private static final Component SERVER_EXPIRED_TOOLTIP = Component.translatable("mco.selectServer.expired");
private static final Component SERVER_EXPIRES_SOON_TOOLTIP = Component.translatable("mco.selectServer.expires.soon");
private static final Component SERVER_EXPIRES_IN_DAY_TOOLTIP = Component.translatable("mco.selectServer.expires.day");
private static final Component SERVER_OPEN_TOOLTIP = Component.translatable("mco.selectServer.open");
private static final Component SERVER_CLOSED_TOOLTIP = Component.translatable("mco.selectServer.closed");
private static final Component UNITIALIZED_WORLD_NARRATION = Component.translatable("gui.narrate.button", SERVER_UNITIALIZED_TEXT);
private static final Component NO_REALMS_TEXT = Component.translatable("mco.selectServer.noRealms");
private static final Component NO_PENDING_INVITES = Component.translatable("mco.invites.nopending");
private static final Component PENDING_INVITES = Component.translatable("mco.invites.pending");
private static final Component INCOMPATIBLE_POPUP_TITLE = Component.translatable("mco.compatibility.incompatible.popup.title");
private static final Component INCOMPATIBLE_RELEASE_TYPE_POPUP_MESSAGE = Component.translatable("mco.compatibility.incompatible.releaseType.popup.message");
private static final int BUTTON_WIDTH = 100;
private static final int BUTTON_COLUMNS = 3;
private static final int BUTTON_SPACING = 4;
private static final int CONTENT_WIDTH = 308;
private static final int LOGO_PADDING = 5;
private static final int HEADER_HEIGHT = 44;
private static final int FOOTER_PADDING = 11;
private static final int NEW_REALM_SPRITE_WIDTH = 40;
private static final int NEW_REALM_SPRITE_HEIGHT = 20;
private static final boolean SNAPSHOT = !SharedConstants.getCurrentVersion().stable();
private static boolean snapshotToggle = SNAPSHOT;
private final CompletableFuture<RealmsAvailability.Result> availability = RealmsAvailability.get();
private DataFetcher.@Nullable Subscription dataSubscription;
private final Set<UUID> handledSeenNotifications = new HashSet<>();
private static boolean regionsPinged;
private final RateLimiter inviteNarrationLimiter;
private final Screen lastScreen;
private Button playButton;
private Button backButton;
private Button renewButton;
private Button configureButton;
private Button leaveButton;
private RealmsMainScreen.RealmSelectionList realmSelectionList;
private RealmsServerList serverList;
private List<RealmsServer> availableSnapshotServers = List.of();
private RealmsServerPlayerLists onlinePlayersPerRealm = new RealmsServerPlayerLists(Map.of());
private volatile boolean trialsAvailable;
private volatile @Nullable String newsLink;
private final List<RealmsNotification> notifications = new ArrayList<>();
private Button addRealmButton;
private RealmsMainScreen.NotificationButton pendingInvitesButton;
private RealmsMainScreen.NotificationButton newsButton;
private RealmsMainScreen.LayoutState activeLayoutState;
private @Nullable HeaderAndFooterLayout layout;
public RealmsMainScreen(Screen lastScreen) {
super(TITLE);
this.lastScreen = lastScreen;
this.inviteNarrationLimiter = RateLimiter.create(0.016666668F);
}
@Override
public void init() {
this.serverList = new RealmsServerList(this.minecraft);
this.realmSelectionList = new RealmsMainScreen.RealmSelectionList();
Component invitesTitle = Component.translatable("mco.invites.title");
this.pendingInvitesButton = new RealmsMainScreen.NotificationButton(
invitesTitle, INVITE_SPRITE, b -> this.minecraft.setScreen(new RealmsPendingInvitesScreen(this, invitesTitle)), null
);
Component newsTitle = Component.translatable("mco.news");
this.newsButton = new RealmsMainScreen.NotificationButton(newsTitle, NEWS_SPRITE, b -> {
String newsLink = this.newsLink;
if (newsLink != null) {
ConfirmLinkScreen.confirmLinkNow(this, newsLink);
if (this.newsButton.notificationCount() != 0) {
RealmsPersistence.RealmsPersistenceData data = RealmsPersistence.readFile();
data.hasUnreadNews = false;
RealmsPersistence.writeFile(data);
this.newsButton.setNotificationCount(0);
}
}
}, newsTitle);
this.playButton = Button.builder(PLAY_TEXT, button -> play(this.getSelectedServer(), this)).width(100).build();
this.configureButton = Button.builder(CONFIGURE_SERVER_TEXT, button -> this.configureClicked(this.getSelectedServer())).width(100).build();
this.renewButton = Button.builder(SUBSCRIPTION_RENEW_TEXT, button -> this.onRenew(this.getSelectedServer())).width(100).build();
this.leaveButton = Button.builder(LEAVE_SERVER_TEXT, button -> this.leaveClicked(this.getSelectedServer())).width(100).build();
this.addRealmButton = Button.builder(Component.translatable("mco.selectServer.purchase"), button -> this.openTrialAvailablePopup())
.size(100, 20)
.build();
this.backButton = Button.builder(CommonComponents.GUI_BACK, button -> this.onClose()).width(100).build();
if (RealmsClient.ENVIRONMENT == RealmsClient.Environment.STAGE) {
this.addRenderableWidget(
CycleButton.booleanBuilder(Component.literal("Snapshot"), Component.literal("Release"), snapshotToggle)
.create(5, 5, 100, 20, Component.literal("Realm"), (button, value) -> {
snapshotToggle = value;
this.availableSnapshotServers = List.of();
this.debugRefreshDataFetchers();
})
);
}
this.updateLayout(RealmsMainScreen.LayoutState.LOADING);
this.updateButtonStates();
this.availability.thenAcceptAsync(result -> {
Screen errorScreen = result.createErrorScreen(this.lastScreen);
if (errorScreen == null) {
this.dataSubscription = this.initDataFetcher(this.minecraft.realmsDataFetcher());
} else {
this.minecraft.setScreen(errorScreen);
}
}, this.screenExecutor);
}
public static boolean isSnapshot() {
return SNAPSHOT && snapshotToggle;
}
@Override
protected void repositionElements() {
if (this.layout != null) {
this.realmSelectionList.updateSize(this.width, this.layout);
this.layout.arrangeElements();
}
}
@Override
public void onClose() {
this.minecraft.setScreen(this.lastScreen);
}
private void updateLayout() {
if (this.serverList.isEmpty() && this.availableSnapshotServers.isEmpty() && this.notifications.isEmpty()) {
this.updateLayout(RealmsMainScreen.LayoutState.NO_REALMS);
} else {
this.updateLayout(RealmsMainScreen.LayoutState.LIST);
}
}
private void updateLayout(RealmsMainScreen.LayoutState state) {
if (this.activeLayoutState != state) {
if (this.layout != null) {
this.layout.visitWidgets(x$0 -> this.removeWidget(x$0));
}
this.layout = this.createLayout(state);
this.activeLayoutState = state;
this.layout.visitWidgets(x$0 -> this.addRenderableWidget(x$0));
this.repositionElements();
}
}
private HeaderAndFooterLayout createLayout(RealmsMainScreen.LayoutState state) {
HeaderAndFooterLayout layout = new HeaderAndFooterLayout(this);
layout.setHeaderHeight(44);
layout.addToHeader(this.createHeader());
Layout footer = this.createFooter(state);
footer.arrangeElements();
layout.setFooterHeight(footer.getHeight() + 22);
layout.addToFooter(footer);
switch (state) {
case LOADING:
layout.addToContents(new LoadingDotsWidget(this.font, LOADING_TEXT));
break;
case NO_REALMS:
layout.addToContents(this.createNoRealmsContent());
break;
case LIST:
layout.addToContents(this.realmSelectionList);
}
return layout;
}
private Layout createHeader() {
int sideCellWidth = 90;
LinearLayout buttons = LinearLayout.horizontal().spacing(4);
buttons.defaultCellSetting().alignVerticallyMiddle();
buttons.addChild(this.pendingInvitesButton);
buttons.addChild(this.newsButton);
LinearLayout header = LinearLayout.horizontal();
header.defaultCellSetting().alignVerticallyMiddle();
header.addChild(SpacerElement.width(90));
header.addChild(realmsLogo(), LayoutSettings::alignHorizontallyCenter);
header.addChild(new FrameLayout(90, 44)).addChild(buttons, LayoutSettings::alignHorizontallyRight);
return header;
}
private Layout createFooter(RealmsMainScreen.LayoutState state) {
GridLayout footer = new GridLayout().spacing(4);
GridLayout.RowHelper helper = footer.createRowHelper(3);
if (state == RealmsMainScreen.LayoutState.LIST) {
helper.addChild(this.playButton);
helper.addChild(this.configureButton);
helper.addChild(this.renewButton);
helper.addChild(this.leaveButton);
}
helper.addChild(this.addRealmButton);
helper.addChild(this.backButton);
return footer;
}
private LinearLayout createNoRealmsContent() {
LinearLayout content = LinearLayout.vertical().spacing(8);
content.defaultCellSetting().alignHorizontallyCenter();
content.addChild(ImageWidget.texture(130, 64, NO_REALMS_LOCATION, 130, 64));
content.addChild(
FocusableTextWidget.builder(NO_REALMS_TEXT, this.font)
.maxWidth(308)
.alwaysShowBorder(false)
.backgroundFill(FocusableTextWidget.BackgroundFill.ON_FOCUS)
.build()
);
return content;
}
private void updateButtonStates() {
RealmsServer server = this.getSelectedServer();
boolean serverSelected = server != null;
this.addRealmButton.active = this.activeLayoutState != RealmsMainScreen.LayoutState.LOADING;
this.playButton.active = serverSelected && server.shouldPlayButtonBeActive();
if (!this.playButton.active && serverSelected && server.state == RealmsServer.State.CLOSED) {
this.playButton.setTooltip(Tooltip.create(RealmsServer.WORLD_CLOSED_COMPONENT));
}
this.renewButton.active = serverSelected && this.shouldRenewButtonBeActive(server);
this.leaveButton.active = serverSelected && this.shouldLeaveButtonBeActive(server);
this.configureButton.active = serverSelected && this.shouldConfigureButtonBeActive(server);
}
private boolean shouldRenewButtonBeActive(RealmsServer server) {
return server.expired && isSelfOwnedServer(server);
}
private boolean shouldConfigureButtonBeActive(RealmsServer server) {
return isSelfOwnedServer(server) && server.state != RealmsServer.State.UNINITIALIZED;
}
private boolean shouldLeaveButtonBeActive(RealmsServer server) {
return !isSelfOwnedServer(server);
}
@Override
public void tick() {
super.tick();
if (this.dataSubscription != null) {
this.dataSubscription.tick();
}
}
public static void refreshPendingInvites() {
Minecraft.getInstance().realmsDataFetcher().pendingInvitesTask.reset();
}
public static void refreshServerList() {
Minecraft.getInstance().realmsDataFetcher().serverListUpdateTask.reset();
}
private void debugRefreshDataFetchers() {
for (DataFetcher.Task<?> task : this.minecraft.realmsDataFetcher().getTasks()) {
task.reset();
}
}
private DataFetcher.Subscription initDataFetcher(RealmsDataFetcher dataSource) {
DataFetcher.Subscription result = dataSource.dataFetcher.createSubscription();
result.subscribe(dataSource.serverListUpdateTask, updatedServers -> {
this.serverList.updateServersList(updatedServers.serverList());
this.availableSnapshotServers = updatedServers.availableSnapshotServers();
this.refreshListAndLayout();
boolean ownsNonExpiredRealmServer = false;
for (RealmsServer retrievedServer : this.serverList) {
if (this.isSelfOwnedNonExpiredServer(retrievedServer)) {
ownsNonExpiredRealmServer = true;
}
}
if (!regionsPinged && ownsNonExpiredRealmServer) {
regionsPinged = true;
this.pingRegions();
}
});
callRealmsClient(RealmsClient::getNotifications, retrievedNotifications -> {
this.notifications.clear();
this.notifications.addAll(retrievedNotifications);
for (RealmsNotification notification : retrievedNotifications) {
if (notification instanceof RealmsNotification.InfoPopup popup) {
PopupScreen popupScreen = popup.buildScreen(this, this::dismissNotification);
if (popupScreen != null) {
this.minecraft.setScreen(popupScreen);
this.markNotificationsAsSeen(List.of(notification));
break;
}
}
}
if (!this.notifications.isEmpty() && this.activeLayoutState != RealmsMainScreen.LayoutState.LOADING) {
this.refreshListAndLayout();
}
});
result.subscribe(dataSource.pendingInvitesTask, numberOfPendingInvites -> {
this.pendingInvitesButton.setNotificationCount(numberOfPendingInvites);
this.pendingInvitesButton.setTooltip(numberOfPendingInvites == 0 ? Tooltip.create(NO_PENDING_INVITES) : Tooltip.create(PENDING_INVITES));
if (numberOfPendingInvites > 0 && this.inviteNarrationLimiter.tryAcquire(1)) {
this.minecraft.getNarrator().saySystemNow(Component.translatable("mco.configure.world.invite.narration", numberOfPendingInvites));
}
});
result.subscribe(dataSource.trialAvailabilityTask, newStatus -> this.trialsAvailable = newStatus);
result.subscribe(dataSource.onlinePlayersTask, playerList -> this.onlinePlayersPerRealm = playerList);
result.subscribe(dataSource.newsTask, news -> {
dataSource.newsManager.updateUnreadNews(news);
this.newsLink = dataSource.newsManager.newsLink();
this.newsButton.setNotificationCount(dataSource.newsManager.hasUnreadNews() ? Integer.MAX_VALUE : 0);
});
return result;
}
private void markNotificationsAsSeen(Collection<RealmsNotification> notifications) {
List<UUID> seenNotifications = new ArrayList<>(notifications.size());
for (RealmsNotification notification : notifications) {
if (!notification.seen() && !this.handledSeenNotifications.contains(notification.uuid())) {
seenNotifications.add(notification.uuid());
}
}
if (!seenNotifications.isEmpty()) {
callRealmsClient(realmsClient -> {
realmsClient.notificationsSeen(seenNotifications);
return null;
}, ignored -> this.handledSeenNotifications.addAll(seenNotifications));
}
}
private static <T> void callRealmsClient(RealmsMainScreen.RealmsCall<T> supplier, Consumer<T> callback) {
Minecraft minecraft = Minecraft.getInstance();
CompletableFuture.<T>supplyAsync(() -> {
try {
return supplier.request(RealmsClient.getOrCreate(minecraft));
} catch (RealmsServiceException var3) {
throw new RuntimeException(var3);
}
}).thenAcceptAsync(callback, minecraft).exceptionally(e -> {
LOGGER.error("Failed to execute call to Realms Service", e);
return null;
});
}
private void refreshListAndLayout() {
this.realmSelectionList.refreshEntries(this);
this.updateLayout();
this.updateButtonStates();
}
private void pingRegions() {
new Thread(() -> {
List<RegionPingResult> regionPingResultList = Ping.pingAllRegions();
RealmsClient client = RealmsClient.getOrCreate();
PingResult pingResult = new PingResult(regionPingResultList, this.getOwnedNonExpiredRealmIds());
try {
client.sendPingResults(pingResult);
} catch (Throwable var5) {
LOGGER.warn("Could not send ping result to Realms: ", var5);
}
}).start();
}
private List<Long> getOwnedNonExpiredRealmIds() {
List<Long> ids = Lists.newArrayList();
for (RealmsServer server : this.serverList) {
if (this.isSelfOwnedNonExpiredServer(server)) {
ids.add(server.id);
}
}
return ids;
}
private void onRenew(@Nullable RealmsServer server) {
if (server != null) {
String extensionUrl = CommonLinks.extendRealms(server.remoteSubscriptionId, this.minecraft.getUser().getProfileId(), server.expiredTrial);
this.minecraft.setScreen(new ConfirmLinkScreen(result -> {
if (result) {
Util.getPlatform().openUri(extensionUrl);
} else {
this.minecraft.setScreen(this);
}
}, extensionUrl, true));
}
}
private void configureClicked(@Nullable RealmsServer selectedServer) {
if (selectedServer != null && this.minecraft.isLocalPlayer(selectedServer.ownerUUID)) {
this.minecraft.setScreen(new RealmsConfigureWorldScreen(this, selectedServer.id));
}
}
private void leaveClicked(@Nullable RealmsServer selectedServer) {
if (selectedServer != null && !this.minecraft.isLocalPlayer(selectedServer.ownerUUID)) {
Component popupMessage = Component.translatable("mco.configure.world.leave.question.line1");
this.minecraft.setScreen(RealmsPopups.infoPopupScreen(this, popupMessage, popup -> this.leaveServer(selectedServer)));
}
}
private @Nullable RealmsServer getSelectedServer() {
return this.realmSelectionList.getSelected() instanceof RealmsMainScreen.ServerEntry entry ? entry.getServer() : null;
}
private void leaveServer(RealmsServer server) {
(new Thread("Realms-leave-server") {
{
Objects.requireNonNull(RealmsMainScreen.this);
}
@Override
public void run() {
try {
RealmsClient client = RealmsClient.getOrCreate();
client.uninviteMyselfFrom(server.id);
RealmsMainScreen.this.minecraft.execute(RealmsMainScreen::refreshServerList);
} catch (RealmsServiceException var2) {
RealmsMainScreen.LOGGER.error("Couldn't configure world", (Throwable)var2);
RealmsMainScreen.this.minecraft
.execute(() -> RealmsMainScreen.this.minecraft.setScreen(new RealmsGenericErrorScreen(var2, RealmsMainScreen.this)));
}
}
})
.start();
this.minecraft.setScreen(this);
}
private void dismissNotification(UUID uuid) {
callRealmsClient(realmsClient -> {
realmsClient.notificationsDismiss(List.of(uuid));
return null;
}, ignored -> {
this.notifications.removeIf(notification -> notification.dismissable() && uuid.equals(notification.uuid()));
this.refreshListAndLayout();
});
}
public void resetScreen() {
this.realmSelectionList.setSelected(null);
refreshServerList();
}
@Override
public Component getNarrationMessage() {
return (Component)(switch (this.activeLayoutState) {
case LOADING -> CommonComponents.joinForNarration(super.getNarrationMessage(), LOADING_TEXT);
case NO_REALMS -> CommonComponents.joinForNarration(super.getNarrationMessage(), NO_REALMS_TEXT);
case LIST -> super.getNarrationMessage();
});
}
@Override
public void extractRenderState(GuiGraphicsExtractor graphics, int xm, int ym, float a) {
super.extractRenderState(graphics, xm, ym, a);
if (isSnapshot()) {
graphics.text(this.font, "Minecraft " + SharedConstants.getCurrentVersion().name(), 2, this.height - 10, -1);
}
if (this.trialsAvailable && this.addRealmButton.active) {
AddRealmPopupScreen.extractDiamond(graphics, this.addRealmButton);
}
switch (RealmsClient.ENVIRONMENT) {
case STAGE:
this.extractEnvironment(graphics, "STAGE!", -256);
break;
case LOCAL:
this.extractEnvironment(graphics, "LOCAL!", -8388737);
}
}
private void openTrialAvailablePopup() {
this.minecraft.setScreen(new AddRealmPopupScreen(this, this.trialsAvailable));
}
public static void play(@Nullable RealmsServer server, Screen cancelScreen) {
play(server, cancelScreen, false);
}
public static void play(@Nullable RealmsServer server, Screen cancelScreen, boolean skipCompatibility) {
if (server != null) {
if (!isSnapshot() || skipCompatibility || server.isMinigameActive()) {
Minecraft.getInstance().setScreen(new RealmsLongRunningMcoTaskScreen(cancelScreen, new GetServerDetailsTask(cancelScreen, server)));
return;
}
switch (server.compatibility) {
case COMPATIBLE:
Minecraft.getInstance().setScreen(new RealmsLongRunningMcoTaskScreen(cancelScreen, new GetServerDetailsTask(cancelScreen, server)));
break;
case UNVERIFIABLE:
confirmToPlay(
server,
cancelScreen,
Component.translatable("mco.compatibility.unverifiable.title").withColor(-171),
Component.translatable("mco.compatibility.unverifiable.message"),
CommonComponents.GUI_CONTINUE
);
break;
case NEEDS_DOWNGRADE:
confirmToPlay(
server,
cancelScreen,
Component.translatable("selectWorld.backupQuestion.downgrade").withColor(-2142128),
Component.translatable(
"mco.compatibility.downgrade.description",
Component.literal(server.activeVersion).withColor(-171),
Component.literal(SharedConstants.getCurrentVersion().name()).withColor(-171)
),
Component.translatable("mco.compatibility.downgrade")
);
break;
case NEEDS_UPGRADE:
upgradeRealmAndPlay(server, cancelScreen);
break;
case INCOMPATIBLE:
Minecraft.getInstance()
.setScreen(
new PopupScreen.Builder(cancelScreen, INCOMPATIBLE_POPUP_TITLE)
.addMessage(
Component.translatable(
"mco.compatibility.incompatible.series.popup.message",
Component.literal(server.activeVersion).withColor(-171),
Component.literal(SharedConstants.getCurrentVersion().name()).withColor(-171)
)
)
.addButton(CommonComponents.GUI_BACK, PopupScreen::onClose)
.build()
);
break;
case RELEASE_TYPE_INCOMPATIBLE:
Minecraft.getInstance()
.setScreen(
new PopupScreen.Builder(cancelScreen, INCOMPATIBLE_POPUP_TITLE)
.addMessage(INCOMPATIBLE_RELEASE_TYPE_POPUP_MESSAGE)
.addButton(CommonComponents.GUI_BACK, PopupScreen::onClose)
.build()
);
}
}
}
private static void confirmToPlay(RealmsServer server, Screen lastScreen, Component title, Component message, Component confirmButton) {
Minecraft.getInstance().setScreen(new PopupScreen.Builder(lastScreen, title).addMessage(message).addButton(confirmButton, popupScreen -> {
Minecraft.getInstance().setScreen(new RealmsLongRunningMcoTaskScreen(lastScreen, new GetServerDetailsTask(lastScreen, server)));
refreshServerList();
}).addButton(CommonComponents.GUI_CANCEL, PopupScreen::onClose).build());
}
private static void upgradeRealmAndPlay(RealmsServer server, Screen cancelScreen) {
Component title = Component.translatable("mco.compatibility.upgrade.title").withColor(-171);
Component confirmButton = Component.translatable("mco.compatibility.upgrade");
Component serverVersion = Component.literal(server.activeVersion).withColor(-171);
Component clientVersion = Component.literal(SharedConstants.getCurrentVersion().name()).withColor(-171);
Component message = isSelfOwnedServer(server)
? Component.translatable("mco.compatibility.upgrade.description", serverVersion, clientVersion)
: Component.translatable("mco.compatibility.upgrade.friend.description", serverVersion, clientVersion);
confirmToPlay(server, cancelScreen, title, message, confirmButton);
}
public static Component getVersionComponent(String version, boolean isCompatible) {
return getVersionComponent(version, isCompatible ? -8355712 : -2142128);
}
public static Component getVersionComponent(String version, int color) {
return (Component)(StringUtils.isBlank(version) ? CommonComponents.EMPTY : Component.literal(version).withColor(color));
}
public static Component getGameModeComponent(int gameMode, boolean hardcore) {
return (Component)(hardcore ? Component.translatable("gameMode.hardcore").withColor(-65536) : GameType.byId(gameMode).getLongDisplayName());
}
private static boolean isSelfOwnedServer(RealmsServer serverData) {
return Minecraft.getInstance().isLocalPlayer(serverData.ownerUUID);
}
private boolean isSelfOwnedNonExpiredServer(RealmsServer serverData) {
return isSelfOwnedServer(serverData) && !serverData.expired;
}
private void extractEnvironment(GuiGraphicsExtractor graphics, String text, int color) {
graphics.pose().pushMatrix();
graphics.pose().translate(this.width / 2 - 25, 20.0F);
graphics.pose().rotate((float) (-Math.PI / 9));
graphics.pose().scale(1.5F, 1.5F);
graphics.text(this.font, text, 0, 0, color);
graphics.pose().popMatrix();
}
@OnlyIn(Dist.CLIENT)
private class AvailableSnapshotEntry extends RealmsMainScreen.Entry {
private static final Component START_SNAPSHOT_REALM = Component.translatable("mco.snapshot.start");
private static final int TEXT_PADDING = 5;
private final WidgetTooltipHolder tooltip;
private final RealmsServer parent;
public AvailableSnapshotEntry(RealmsServer parent) {
Objects.requireNonNull(RealmsMainScreen.this);
super();
this.tooltip = new WidgetTooltipHolder();
this.parent = parent;
this.tooltip.set(Tooltip.create(Component.translatable("mco.snapshot.tooltip")));
}
@Override
public void extractContent(GuiGraphicsExtractor graphics, int mouseX, int mouseY, boolean hovered, float a) {
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, RealmsMainScreen.NEW_REALM_SPRITE, this.getContentX() - 5, this.getContentYMiddle() - 10, 40, 20);
int textYPos = this.getContentYMiddle() - 9 / 2;
graphics.text(RealmsMainScreen.this.font, START_SNAPSHOT_REALM, this.getContentX() + 40 - 2, textYPos - 5, -8388737);
graphics.text(
RealmsMainScreen.this.font,
Component.translatable("mco.snapshot.description", Objects.requireNonNullElse(this.parent.name, "unknown server")),
this.getContentX() + 40 - 2,
textYPos + 5,
-8355712
);
this.tooltip
.refreshTooltipForNextRenderPass(
graphics,
mouseX,
mouseY,
hovered,
this.isFocused(),
new ScreenRectangle(this.getContentX(), this.getContentY(), this.getContentWidth(), this.getContentHeight())
);
}
@Override
public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) {
this.addSnapshotRealm();
return true;
}
@Override
public boolean keyPressed(KeyEvent event) {
if (event.isSelection()) {
this.addSnapshotRealm();
return false;
} else {
return super.keyPressed(event);
}
}
private void addSnapshotRealm() {
RealmsMainScreen.this.minecraft.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
RealmsMainScreen.this.minecraft
.setScreen(
new PopupScreen.Builder(RealmsMainScreen.this, Component.translatable("mco.snapshot.createSnapshotPopup.title"))
.addMessage(Component.translatable("mco.snapshot.createSnapshotPopup.text"))
.addButton(
Component.translatable("mco.selectServer.create"),
popup -> RealmsMainScreen.this.minecraft.setScreen(new RealmsCreateRealmScreen(RealmsMainScreen.this, this.parent, true))
)
.addButton(CommonComponents.GUI_CANCEL, PopupScreen::onClose)
.build()
);
}
@Override
public Component getNarration() {
return Component.translatable(
"gui.narrate.button",
CommonComponents.joinForNarration(
START_SNAPSHOT_REALM, Component.translatable("mco.snapshot.description", Objects.requireNonNullElse(this.parent.name, "unknown server"))
)
);
}
}
@OnlyIn(Dist.CLIENT)
private static class CrossButton extends ImageButton {
private static final WidgetSprites SPRITES = new WidgetSprites(
Identifier.withDefaultNamespace("widget/cross_button"), Identifier.withDefaultNamespace("widget/cross_button_highlighted")
);
protected CrossButton(Button.OnPress onPress, Component tooltip) {
super(0, 0, 14, 14, SPRITES, onPress);
this.setTooltip(Tooltip.create(tooltip));
}
}
@OnlyIn(Dist.CLIENT)
private abstract class Entry extends ObjectSelectionList.Entry<RealmsMainScreen.Entry> {
protected static final int STATUS_LIGHT_WIDTH = 10;
private static final int STATUS_LIGHT_HEIGHT = 28;
protected static final int PADDING_X = 7;
protected static final int PADDING_Y = 2;
private Entry() {
Objects.requireNonNull(RealmsMainScreen.this);
super();
}
protected void extractStatusLights(RealmsServer serverData, GuiGraphicsExtractor graphics, int rowRight, int rowTop, int mouseX, int mouseY) {
int x = rowRight - 10 - 7;
int y = rowTop + 2;
if (serverData.expired) {
this.extractRealmStatus(graphics, x, y, mouseX, mouseY, RealmsMainScreen.EXPIRED_SPRITE, () -> RealmsMainScreen.SERVER_EXPIRED_TOOLTIP);
} else if (serverData.state == RealmsServer.State.CLOSED) {
this.extractRealmStatus(graphics, x, y, mouseX, mouseY, RealmsMainScreen.CLOSED_SPRITE, () -> RealmsMainScreen.SERVER_CLOSED_TOOLTIP);
} else if (RealmsMainScreen.isSelfOwnedServer(serverData) && serverData.daysLeft < 7) {
this.extractRealmStatus(
graphics,
x,
y,
mouseX,
mouseY,
RealmsMainScreen.EXPIRES_SOON_SPRITE,
() -> {
if (serverData.daysLeft <= 0) {
return RealmsMainScreen.SERVER_EXPIRES_SOON_TOOLTIP;
} else {
return (Component)(serverData.daysLeft == 1
? RealmsMainScreen.SERVER_EXPIRES_IN_DAY_TOOLTIP
: Component.translatable("mco.selectServer.expires.days", serverData.daysLeft));
}
}
);
} else if (serverData.state == RealmsServer.State.OPEN) {
this.extractRealmStatus(graphics, x, y, mouseX, mouseY, RealmsMainScreen.OPEN_SPRITE, () -> RealmsMainScreen.SERVER_OPEN_TOOLTIP);
}
}
private void extractRealmStatus(GuiGraphicsExtractor graphics, int x, int y, int xm, int ym, Identifier sprite, Supplier<Component> tooltip) {
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, sprite, x, y, 10, 28);
if (RealmsMainScreen.this.realmSelectionList.isMouseOver(xm, ym) && xm >= x && xm <= x + 10 && ym >= y && ym <= y + 28) {
graphics.setTooltipForNextFrame(tooltip.get(), xm, ym);
}
}
protected void extractFirstLine(GuiGraphicsExtractor graphics, int rowTop, int rowLeft, int rowWidth, int serverNameColor, RealmsServer serverData) {
int textX = this.textX(rowLeft);
int firstLineY = this.firstLineY(rowTop);
Component versionComponent = RealmsMainScreen.getVersionComponent(serverData.activeVersion, serverData.isCompatible());
int versionTextX = this.versionTextX(rowLeft, rowWidth, versionComponent);
this.extractClampedString(graphics, serverData.getName(), textX, firstLineY, versionTextX, serverNameColor);
if (versionComponent != CommonComponents.EMPTY && !serverData.isMinigameActive()) {
graphics.text(RealmsMainScreen.this.font, versionComponent, versionTextX, firstLineY, -8355712);
}
}
protected void extractSecondLine(GuiGraphicsExtractor graphics, int rowTop, int rowLeft, int rowWidth, RealmsServer serverData) {
int textX = this.textX(rowLeft);
int firstLineY = this.firstLineY(rowTop);
int secondLineY = this.secondLineY(firstLineY);
String minigameName = serverData.getMinigameName();
boolean minigameActive = serverData.isMinigameActive();
if (minigameActive && minigameName != null) {
Component minigameNameComponent = Component.literal(minigameName).withStyle(ChatFormatting.GRAY);
graphics.text(
RealmsMainScreen.this.font,
Component.translatable("mco.selectServer.minigameName", minigameNameComponent).withColor(-171),
textX,
secondLineY,
-1
);
} else {
int maxX = this.extractGameMode(serverData, graphics, rowLeft, rowWidth, firstLineY);
this.extractClampedString(graphics, serverData.getDescription(), textX, this.secondLineY(firstLineY), maxX, -8355712);
}
}
protected void extractThirdLine(GuiGraphicsExtractor graphics, int rowTop, int rowLeft, RealmsServer server) {
int textX = this.textX(rowLeft);
int firstLineY = this.firstLineY(rowTop);
int thirdLineY = this.thirdLineY(firstLineY);
if (!RealmsMainScreen.isSelfOwnedServer(server)) {
graphics.text(RealmsMainScreen.this.font, server.owner, textX, this.thirdLineY(firstLineY), -8355712);
} else if (server.expired) {
Component expirationText = server.expiredTrial ? RealmsMainScreen.TRIAL_EXPIRED_TEXT : RealmsMainScreen.SUBSCRIPTION_EXPIRED_TEXT;
graphics.text(RealmsMainScreen.this.font, expirationText, textX, thirdLineY, -2142128);
}
}
protected void extractClampedString(GuiGraphicsExtractor graphics, @Nullable String string, int x, int y, int maxX, int color) {
if (string != null) {
int availableSpace = maxX - x;
if (RealmsMainScreen.this.font.width(string) > availableSpace) {
String clampedName = RealmsMainScreen.this.font.plainSubstrByWidth(string, availableSpace - RealmsMainScreen.this.font.width("... "));
graphics.text(RealmsMainScreen.this.font, clampedName + "...", x, y, color);
} else {
graphics.text(RealmsMainScreen.this.font, string, x, y, color);
}
}
}
protected int versionTextX(int rowLeft, int rowWidth, Component versionComponent) {
return rowLeft + rowWidth - RealmsMainScreen.this.font.width(versionComponent) - 20;
}
protected int gameModeTextX(int rowLeft, int rowWidth, Component versionComponent) {
return rowLeft + rowWidth - RealmsMainScreen.this.font.width(versionComponent) - 20;
}
protected int extractGameMode(RealmsServer server, GuiGraphicsExtractor graphics, int rowLeft, int rowWidth, int firstLineY) {
boolean hardcore = server.isHardcore;
int gameMode = server.gameMode;
int x = rowLeft;
if (GameType.isValidId(gameMode)) {
Component gameModeComponent = RealmsMainScreen.getGameModeComponent(gameMode, hardcore);
x = this.gameModeTextX(rowLeft, rowWidth, gameModeComponent);
graphics.text(RealmsMainScreen.this.font, gameModeComponent, x, this.secondLineY(firstLineY), -8355712);
}
if (hardcore) {
x -= 10;
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, RealmsMainScreen.HARDCORE_MODE_SPRITE, x, this.secondLineY(firstLineY), 8, 8);
}
return x;
}
protected int firstLineY(int rowTop) {
return rowTop + 1;
}
protected int lineHeight() {
return 2 + 9;
}
protected int textX(int rowLeft) {
return rowLeft + 36 + 2;
}
protected int secondLineY(int firstLineY) {
return firstLineY + this.lineHeight();
}
protected int thirdLineY(int firstLineY) {
return firstLineY + this.lineHeight() * 2;
}
}
@OnlyIn(Dist.CLIENT)
private static enum LayoutState {
LOADING,
NO_REALMS,
LIST;
}
@OnlyIn(Dist.CLIENT)
private static class NotificationButton extends SpriteIconButton.CenteredIcon {
private static final Identifier[] NOTIFICATION_ICONS = new Identifier[]{
Identifier.withDefaultNamespace("notification/1"),
Identifier.withDefaultNamespace("notification/2"),
Identifier.withDefaultNamespace("notification/3"),
Identifier.withDefaultNamespace("notification/4"),
Identifier.withDefaultNamespace("notification/5"),
Identifier.withDefaultNamespace("notification/more")
};
private static final int UNKNOWN_COUNT = Integer.MAX_VALUE;
private static final int SIZE = 20;
private static final int SPRITE_SIZE = 14;
private int notificationCount;
public NotificationButton(Component title, Identifier texture, Button.OnPress onPress, @Nullable Component tooltip) {
super(20, 20, title, 14, 14, new WidgetSprites(texture), onPress, tooltip, null);
}
private int notificationCount() {
return this.notificationCount;
}
public void setNotificationCount(int notificationCount) {
this.notificationCount = notificationCount;
}
@Override
public void extractContents(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) {
super.extractContents(graphics, mouseX, mouseY, a);
if (this.active && this.notificationCount != 0) {
this.extractNotificationCounter(graphics);
}
}
private void extractNotificationCounter(GuiGraphicsExtractor graphics) {
graphics.blitSprite(
RenderPipelines.GUI_TEXTURED,
NOTIFICATION_ICONS[Math.min(this.notificationCount, 6) - 1],
this.getX() + this.getWidth() - 5,
this.getY() - 3,
8,
8
);
}
}
@OnlyIn(Dist.CLIENT)
private class NotificationMessageEntry extends RealmsMainScreen.Entry {
private static final int SIDE_MARGINS = 40;
public static final int PADDING = 7;
public static final int HEIGHT_WITHOUT_TEXT = 38;
private final Component text;
private final List<AbstractWidget> children;
private final RealmsMainScreen.@Nullable CrossButton dismissButton;
private final MultiLineTextWidget textWidget;
private final GridLayout gridLayout;
private final FrameLayout textFrame;
private final Button button;
private int lastEntryWidth;
public NotificationMessageEntry(RealmsMainScreen realmsMainScreen, int messageHeight, Component text, RealmsNotification.VisitUrl notification) {
Objects.requireNonNull(RealmsMainScreen.this);
super();
this.children = new ArrayList<>();
this.lastEntryWidth = -1;
this.text = text;
this.gridLayout = new GridLayout();
this.gridLayout.addChild(ImageWidget.sprite(20, 20, RealmsMainScreen.INFO_SPRITE), 0, 0, this.gridLayout.newCellSettings().padding(7, 7, 0, 0));
this.gridLayout.addChild(SpacerElement.width(40), 0, 0);
this.textFrame = this.gridLayout.addChild(new FrameLayout(0, messageHeight), 0, 1, this.gridLayout.newCellSettings().paddingTop(7));
this.textWidget = this.textFrame
.addChild(
new MultiLineTextWidget(text, RealmsMainScreen.this.font).setCentered(true),
this.textFrame.newChildLayoutSettings().alignHorizontallyCenter().alignVerticallyTop()
);
this.gridLayout.addChild(SpacerElement.width(40), 0, 2);
if (notification.dismissable()) {
this.dismissButton = this.gridLayout
.addChild(
new RealmsMainScreen.CrossButton(
b -> RealmsMainScreen.this.dismissNotification(notification.uuid()), Component.translatable("mco.notification.dismiss")
),
0,
2,
this.gridLayout.newCellSettings().alignHorizontallyRight().padding(0, 7, 7, 0)
);
} else {
this.dismissButton = null;
}
this.button = this.gridLayout
.addChild(notification.buildOpenLinkButton(realmsMainScreen), 1, 1, this.gridLayout.newCellSettings().alignHorizontallyCenter().padding(4));
this.button.setOverrideRenderHighlightedSprite(() -> this.isFocused());
this.gridLayout.visitWidgets(this.children::add);
}
@Override
public boolean keyPressed(KeyEvent event) {
if (this.button.keyPressed(event)) {
return true;
} else {
return this.dismissButton != null && this.dismissButton.keyPressed(event) ? true : super.keyPressed(event);
}
}
private void updateEntryWidth() {
int entryWidth = this.getWidth();
if (this.lastEntryWidth != entryWidth) {
this.refreshLayout(entryWidth);
this.lastEntryWidth = entryWidth;
}
}
private void refreshLayout(int entryWidth) {
int width = textWidth(entryWidth);
this.textFrame.setMinWidth(width);
this.textWidget.setMaxWidth(width);
this.gridLayout.arrangeElements();
}
public static int textWidth(int rowWidth) {
return rowWidth - 80;
}
@Override
public void extractContent(GuiGraphicsExtractor graphics, int mouseX, int mouseY, boolean hovered, float a) {
this.gridLayout.setPosition(this.getContentX(), this.getContentY());
this.updateEntryWidth();
this.children.forEach(child -> child.extractRenderState(graphics, mouseX, mouseY, a));
}
@Override
public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) {
if (this.dismissButton != null && this.dismissButton.mouseClicked(event, doubleClick)) {
return true;
} else {
return this.button.mouseClicked(event, doubleClick) ? true : super.mouseClicked(event, doubleClick);
}
}
public Component getText() {
return this.text;
}
@Override
public Component getNarration() {
return this.getText();
}
}
@OnlyIn(Dist.CLIENT)
private class ParentEntry extends RealmsMainScreen.Entry {
private final RealmsServer server;
private final WidgetTooltipHolder tooltip;
public ParentEntry(RealmsServer server) {
Objects.requireNonNull(RealmsMainScreen.this);
super();
this.tooltip = new WidgetTooltipHolder();
this.server = server;
if (!server.expired) {
this.tooltip.set(Tooltip.create(Component.translatable("mco.snapshot.parent.tooltip")));
}
}
@Override
public void extractContent(GuiGraphicsExtractor graphics, int mouseX, int mouseY, boolean hovered, float a) {
this.extractStatusLights(this.server, graphics, this.getContentRight(), this.getContentY(), mouseX, mouseY);
RealmsUtil.extractPlayerFace(graphics, this.getContentX(), this.getContentY(), 32, this.server.ownerUUID);
this.extractFirstLine(graphics, this.getContentY(), this.getContentX(), this.getContentWidth(), -8355712, this.server);
this.extractSecondLine(graphics, this.getContentY(), this.getContentX(), this.getContentWidth(), this.server);
this.extractThirdLine(graphics, this.getContentY(), this.getContentX(), this.server);
this.tooltip
.refreshTooltipForNextRenderPass(
graphics,
mouseX,
mouseY,
hovered,
this.isFocused(),
new ScreenRectangle(this.getContentX(), this.getContentY(), this.getContentWidth(), this.getContentHeight())
);
}
@Override
public Component getNarration() {
return Component.literal(Objects.requireNonNullElse(this.server.name, "unknown server"));
}
}
@OnlyIn(Dist.CLIENT)
private class RealmSelectionList extends ObjectSelectionList<RealmsMainScreen.Entry> {
public RealmSelectionList() {
Objects.requireNonNull(RealmsMainScreen.this);
super(Minecraft.getInstance(), RealmsMainScreen.this.width, RealmsMainScreen.this.height, 0, 36);
}
public void setSelected(RealmsMainScreen.@Nullable Entry selected) {
super.setSelected(selected);
RealmsMainScreen.this.updateButtonStates();
}
@Override
public int getRowWidth() {
return 300;
}
private void refreshEntries(RealmsMainScreen realmsMainScreen) {
RealmsMainScreen.Entry previouslySelected = this.getSelected();
this.clearEntries();
for (RealmsNotification notification : RealmsMainScreen.this.notifications) {
if (notification instanceof RealmsNotification.VisitUrl visitUrl) {
this.addEntriesForNotification(visitUrl, realmsMainScreen, previouslySelected);
RealmsMainScreen.this.markNotificationsAsSeen(List.of(notification));
break;
}
}
this.refreshServerEntries(previouslySelected);
}
private void addEntriesForNotification(
RealmsNotification.VisitUrl visitUrl, RealmsMainScreen realmsMainScreen, RealmsMainScreen.@Nullable Entry previouslySelected
) {
Component message = visitUrl.getMessage();
int messageHeight = RealmsMainScreen.this.font.wordWrapHeight(message, RealmsMainScreen.NotificationMessageEntry.textWidth(this.getRowWidth()));
RealmsMainScreen.NotificationMessageEntry entry = RealmsMainScreen.this.new NotificationMessageEntry(
realmsMainScreen, messageHeight, message, visitUrl
);
this.addEntry(entry, 38 + messageHeight);
if (previouslySelected instanceof RealmsMainScreen.NotificationMessageEntry notificationMessageEntry
&& notificationMessageEntry.getText().equals(message)) {
this.setSelected((RealmsMainScreen.Entry)entry);
}
}
private void refreshServerEntries(RealmsMainScreen.@Nullable Entry previouslySelected) {
for (RealmsServer eligibleForSnapshotServer : RealmsMainScreen.this.availableSnapshotServers) {
this.addEntry(RealmsMainScreen.this.new AvailableSnapshotEntry(eligibleForSnapshotServer));
}
for (RealmsServer server : RealmsMainScreen.this.serverList) {
RealmsMainScreen.Entry entry;
if (RealmsMainScreen.isSnapshot() && !server.isSnapshotRealm()) {
if (server.state == RealmsServer.State.UNINITIALIZED) {
continue;
}
entry = RealmsMainScreen.this.new ParentEntry(server);
} else {
entry = RealmsMainScreen.this.new ServerEntry(server);
}
this.addEntry(entry);
if (previouslySelected instanceof RealmsMainScreen.ServerEntry serverEntry && serverEntry.serverData.id == server.id) {
this.setSelected(entry);
}
}
}
}
@OnlyIn(Dist.CLIENT)
private interface RealmsCall<T> {
T request(RealmsClient realmsClient) throws RealmsServiceException;
}
@OnlyIn(Dist.CLIENT)
private class ServerEntry extends RealmsMainScreen.Entry {
private static final Component ONLINE_PLAYERS_TOOLTIP_HEADER = Component.translatable("mco.onlinePlayers");
private static final int PLAYERS_ONLINE_SPRITE_SIZE = 9;
private static final int PLAYERS_ONLINE_SPRITE_SEPARATION = 3;
private static final int SKIN_HEAD_LARGE_WIDTH = 36;
private final RealmsServer serverData;
private final WidgetTooltipHolder tooltip;
public ServerEntry(RealmsServer serverData) {
Objects.requireNonNull(RealmsMainScreen.this);
super();
this.tooltip = new WidgetTooltipHolder();
this.serverData = serverData;
boolean selfOwnedServer = RealmsMainScreen.isSelfOwnedServer(serverData);
if (RealmsMainScreen.isSnapshot() && selfOwnedServer && serverData.isSnapshotRealm()) {
this.tooltip.set(Tooltip.create(Component.translatable("mco.snapshot.paired", serverData.parentWorldName)));
} else if (!selfOwnedServer && serverData.needsDowngrade()) {
this.tooltip.set(Tooltip.create(Component.translatable("mco.snapshot.friendsRealm.downgrade", serverData.activeVersion)));
}
}
@Override
public void extractContent(GuiGraphicsExtractor graphics, int mouseX, int mouseY, boolean hovered, float a) {
if (this.serverData.state == RealmsServer.State.UNINITIALIZED) {
graphics.blitSprite(
RenderPipelines.GUI_TEXTURED, RealmsMainScreen.NEW_REALM_SPRITE, this.getContentX() - 5, this.getContentYMiddle() - 10, 40, 20
);
int textYPos = this.getContentYMiddle() - 9 / 2;
graphics.text(RealmsMainScreen.this.font, RealmsMainScreen.SERVER_UNITIALIZED_TEXT, this.getContentX() + 40 - 2, textYPos, -8388737);
} else {
RealmsUtil.extractPlayerFace(graphics, this.getContentX(), this.getContentY(), 32, this.serverData.ownerUUID);
this.extractFirstLine(graphics, this.getContentY(), this.getContentX(), this.getContentWidth(), -1, this.serverData);
this.extractSecondLine(graphics, this.getContentY(), this.getContentX(), this.getContentWidth(), this.serverData);
this.extractThirdLine(graphics, this.getContentY(), this.getContentX(), this.serverData);
this.extractStatusLights(this.serverData, graphics, this.getContentRight(), this.getContentY(), mouseX, mouseY);
boolean hasTooltip = this.extractOnlinePlayers(
graphics, this.getContentY(), this.getContentX(), this.getContentWidth(), this.getContentHeight(), mouseX, mouseY, a
);
if (!hasTooltip) {
this.tooltip
.refreshTooltipForNextRenderPass(
graphics,
mouseX,
mouseY,
hovered,
this.isFocused(),
new ScreenRectangle(this.getContentX(), this.getContentY(), this.getContentWidth(), this.getContentHeight())
);
}
}
}
private boolean extractOnlinePlayers(
GuiGraphicsExtractor graphics, int rowTop, int rowLeft, int rowWidth, int rowHeight, int mouseX, int mouseY, float a
) {
List<ResolvableProfile> profileResults = RealmsMainScreen.this.onlinePlayersPerRealm.getProfileResultsFor(this.serverData.id);
int playerCount = profileResults.size();
if (playerCount > 0) {
int playersOnlineXEnd = rowLeft + rowWidth - 21;
int playersOnlineY = rowTop + rowHeight - 9 - 2;
int playerOnlineWidth = 9 * playerCount + 3 * (playerCount - 1);
int playersOnlineXStart = playersOnlineXEnd - playerOnlineWidth;
List<PlayerSkinRenderCache.RenderInfo> tooltipEntries;
if (mouseX >= playersOnlineXStart && mouseX <= playersOnlineXEnd && mouseY >= playersOnlineY && mouseY <= playersOnlineY + 9) {
tooltipEntries = new ArrayList<>(playerCount);
} else {
tooltipEntries = null;
}
PlayerSkinRenderCache skinCache = RealmsMainScreen.this.minecraft.playerSkinRenderCache();
for (int i = 0; i < profileResults.size(); i++) {
ResolvableProfile profile = profileResults.get(i);
PlayerSkinRenderCache.RenderInfo profileRenderInfo = skinCache.getOrDefault(profile);
int xPos = playersOnlineXStart + 12 * i;
PlayerFaceExtractor.extractRenderState(graphics, profileRenderInfo.playerSkin(), xPos, playersOnlineY, 9);
if (tooltipEntries != null) {
tooltipEntries.add(profileRenderInfo);
}
}
if (tooltipEntries != null) {
graphics.setTooltipForNextFrame(
RealmsMainScreen.this.font,
List.of(ONLINE_PLAYERS_TOOLTIP_HEADER),
Optional.of(new ClientActivePlayersTooltip.ActivePlayersTooltip(tooltipEntries)),
mouseX,
mouseY
);
return true;
}
}
return false;
}
private void playRealm() {
RealmsMainScreen.this.minecraft.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
RealmsMainScreen.play(this.serverData, RealmsMainScreen.this);
}
private void createUnitializedRealm() {
RealmsMainScreen.this.minecraft.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
RealmsCreateRealmScreen createScreen = new RealmsCreateRealmScreen(RealmsMainScreen.this, this.serverData, this.serverData.isSnapshotRealm());
RealmsMainScreen.this.minecraft.setScreen(createScreen);
}
@Override
public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) {
if (this.serverData.state == RealmsServer.State.UNINITIALIZED) {
this.createUnitializedRealm();
} else if (this.serverData.shouldPlayButtonBeActive() && doubleClick && this.isFocused()) {
this.playRealm();
}
return true;
}
@Override
public boolean keyPressed(KeyEvent event) {
if (event.isSelection()) {
if (this.serverData.state == RealmsServer.State.UNINITIALIZED) {
this.createUnitializedRealm();
return true;
}
if (this.serverData.shouldPlayButtonBeActive()) {
this.playRealm();
return true;
}
}
return super.keyPressed(event);
}
@Override
public Component getNarration() {
return (Component)(this.serverData.state == RealmsServer.State.UNINITIALIZED
? RealmsMainScreen.UNITIALIZED_WORLD_NARRATION
: Component.translatable("narrator.select", Objects.requireNonNullElse(this.serverData.name, "unknown server")));
}
public RealmsServer getServer() {
return this.serverData;
}
}
}引用的其他类
-
- 引用位置:
字段/方法调用 - 关联成员:
RealmsAvailability.get()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Ping.pingAllRegions()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
RealmsClient.getOrCreate()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
PingResult()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
RealmsServerPlayerLists()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
RealmsServerList()
- 引用位置:
-
- 引用位置:
方法调用/构造调用 - 关联成员:
AddRealmPopupScreen(), AddRealmPopupScreen.extractDiamond()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
RealmsCreateRealmScreen()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
RealmsGenericErrorScreen()
- 引用位置:
-
RealmsLongRunningMcoTaskScreen
- 引用位置:
构造调用 - 关联成员:
RealmsLongRunningMcoTaskScreen()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
RealmsPendingInvitesScreen()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
RealmsPopups.infoPopupScreen()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
RealmsConfigureWorldScreen()
- 引用位置:
-
- 引用位置:
字段/返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
RealmsPersistence.readFile(), RealmsPersistence.writeFile()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
RealmsUtil.extractPlayerFace()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
GetServerDetailsTask()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
SharedConstants.getCurrentVersion()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Minecraft.getInstance()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
Button.builder()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
CycleButton.booleanBuilder()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
FocusableTextWidget.builder()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ImageWidget.sprite(), ImageWidget.texture()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
LoadingDotsWidget()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
MultiLineTextWidget()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
PlayerFaceExtractor.extractRenderState()
- 引用位置:
-
- 引用位置:
方法调用/构造调用 - 关联成员:
Builder(), PopupScreen.Builder()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Tooltip.create()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
WidgetSprites()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
WidgetTooltipHolder()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
FrameLayout()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
GridLayout()
- 引用位置:
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
HeaderAndFooterLayout()
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
方法调用/返回值 - 关联成员:
LinearLayout.horizontal(), LinearLayout.vertical()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
SpacerElement.width()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
ScreenRectangle()
- 引用位置:
-
- 引用位置:
方法调用/构造调用 - 关联成员:
ConfirmLinkScreen(), ConfirmLinkScreen.confirmLinkNow()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
方法调用/构造调用 - 关联成员:
ActivePlayersTooltip(), ClientActivePlayersTooltip.ActivePlayersTooltip()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
SimpleSoundInstance.forUI()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
CommonComponents.joinForNarration()
- 引用位置:
-
- 引用位置:
参数/字段/方法调用/返回值 - 关联成员:
Component.literal(), Component.translatable()
- 引用位置:
-
- 引用位置:
继承
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
Identifier.withDefaultNamespace()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
CommonLinks.extendRealms()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Util.getPlatform()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
GameType.byId(), GameType.isValidId()
- 引用位置: