RealmsClient.java

com.mojang.realmsclient.client.RealmsClient

信息

  • 全限定名:com.mojang.realmsclient.client.RealmsClient
  • 类型:public class
  • 包:com.mojang.realmsclient.client
  • 源码路径:src/main/java/com/mojang/realmsclient/client/RealmsClient.java
  • 起始行号:L60
  • 职责:

    TODO

字段/常量

  • ENVIRONMENT

    • 类型: RealmsClient.Environment
    • 修饰符: public static final
    • 源码定位: L61
    • 说明:

      TODO

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L65
    • 说明:

      TODO

  • realmsClientInstance

    • 类型: RealmsClient
    • 修饰符: private static volatile
    • 源码定位: L66
    • 说明:

      TODO

  • featureFlags

    • 类型: CompletableFuture<Set<String>>
    • 修饰符: private final
    • 源码定位: L67
    • 说明:

      TODO

  • sessionId

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

      TODO

  • username

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

      TODO

  • minecraft

    • 类型: Minecraft
    • 修饰符: private final
    • 源码定位: L70
    • 说明:

      TODO

  • WORLDS_RESOURCE_PATH

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L71
    • 说明:

      TODO

  • INVITES_RESOURCE_PATH

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L72
    • 说明:

      TODO

  • MCO_RESOURCE_PATH

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L73
    • 说明:

      TODO

  • SUBSCRIPTION_RESOURCE

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L74
    • 说明:

      TODO

  • ACTIVITIES_RESOURCE

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L75
    • 说明:

      TODO

  • OPS_RESOURCE

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L76
    • 说明:

      TODO

  • REGIONS_RESOURCE

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L77
    • 说明:

      TODO

  • PREFERRED_REGION_RESOURCE

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L78
    • 说明:

      TODO

  • TRIALS_RESOURCE

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L79
    • 说明:

      TODO

  • NOTIFICATIONS_RESOURCE

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L80
    • 说明:

      TODO

  • FEATURE_FLAGS_RESOURCE

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L81
    • 说明:

      TODO

  • PATH_LIST_ALL_REALMS

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L82
    • 说明:

      TODO

  • PATH_CREATE_SNAPSHOT_REALM

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L83
    • 说明:

      TODO

  • PATH_SNAPSHOT_ELIGIBLE_REALMS

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L84
    • 说明:

      TODO

  • PATH_INITIALIZE

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L85
    • 说明:

      TODO

  • PATH_GET_LIVESTATS

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L86
    • 说明:

      TODO

  • PATH_GET_SUBSCRIPTION

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L87
    • 说明:

      TODO

  • PATH_OP

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L88
    • 说明:

      TODO

  • PATH_PUT_INTO_MINIGAMES_MODE

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L89
    • 说明:

      TODO

  • PATH_AVAILABLE

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L90
    • 说明:

      TODO

  • PATH_TEMPLATES

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L91
    • 说明:

      TODO

  • PATH_WORLD_JOIN

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L92
    • 说明:

      TODO

  • PATH_WORLD_GET

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L93
    • 说明:

      TODO

  • PATH_WORLD_INVITES

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L94
    • 说明:

      TODO

  • PATH_WORLD_UNINVITE

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L95
    • 说明:

      TODO

  • PATH_PENDING_INVITES

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L96
    • 说明:

      TODO

  • PATH_ACCEPT_INVITE

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L97
    • 说明:

      TODO

  • PATH_REJECT_INVITE

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L98
    • 说明:

      TODO

  • PATH_UNINVITE_MYSELF

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L99
    • 说明:

      TODO

  • PATH_WORLD_CONFIGURE

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L100
    • 说明:

      TODO

  • PATH_SLOT

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L101
    • 说明:

      TODO

  • PATH_WORLD_OPEN

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L102
    • 说明:

      TODO

  • PATH_WORLD_CLOSE

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L103
    • 说明:

      TODO

  • PATH_WORLD_RESET

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L104
    • 说明:

      TODO

  • PATH_DELETE_WORLD

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L105
    • 说明:

      TODO

  • PATH_WORLD_BACKUPS

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L106
    • 说明:

      TODO

  • PATH_WORLD_DOWNLOAD

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L107
    • 说明:

      TODO

  • PATH_WORLD_UPLOAD

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L108
    • 说明:

      TODO

  • PATH_CLIENT_COMPATIBLE

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L109
    • 说明:

      TODO

  • PATH_TOS_AGREED

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L110
    • 说明:

      TODO

  • PATH_NEWS

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L111
    • 说明:

      TODO

  • PATH_MARK_NOTIFICATIONS_SEEN

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L112
    • 说明:

      TODO

  • PATH_DISMISS_NOTIFICATIONS

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L113
    • 说明:

      TODO

  • GSON

    • 类型: GuardedSerializer
    • 修饰符: private static final
    • 源码定位: L114
    • 说明:

      TODO

内部类/嵌套类型

  • com.mojang.realmsclient.client.RealmsClient.CompatibleVersionResponse

    • 类型: enum
    • 修饰符: public static
    • 源码定位: L533
    • 说明:

      TODO

  • com.mojang.realmsclient.client.RealmsClient.Environment

    • 类型: enum
    • 修饰符: public static
    • 源码定位: L540
    • 说明:

      TODO

构造器

private RealmsClient(String sessionId, String username, Minecraft minecraft) @ L141

  • 构造器名:RealmsClient
  • 源码定位:L141
  • 修饰符:private

参数:

  • sessionId: String
  • username: String
  • minecraft: Minecraft

说明:

TODO

方法

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

public static RealmsClient getOrCreate() @ L116

  • 方法名:getOrCreate
  • 源码定位:L116
  • 返回类型:RealmsClient
  • 修饰符:public static

参数:

说明:

TODO

public static RealmsClient getOrCreate(Minecraft minecraft) @ L121

  • 方法名:getOrCreate
  • 源码定位:L121
  • 返回类型:RealmsClient
  • 修饰符:public static

参数:

  • minecraft: Minecraft

说明:

TODO

public Set<String> getFeatureFlags() @ L149

  • 方法名:getFeatureFlags
  • 源码定位:L149
  • 返回类型:Set
  • 修饰符:public

参数:

说明:

TODO

private Set<String> fetchFeatureFlags() @ L153

  • 方法名:fetchFeatureFlags
  • 源码定位:L153
  • 返回类型:Set
  • 修饰符:private

参数:

说明:

TODO

public RealmsServerList listRealms() @ L175

  • 方法名:listRealms
  • 源码定位:L175
  • 返回类型:RealmsServerList
  • 修饰符:public

参数:

说明:

TODO

public List<RealmsServer> listSnapshotEligibleRealms() @ L185

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

参数:

说明:

TODO

public RealmsServer createSnapshotRealm(Long parentId) @ L191

  • 方法名:createSnapshotRealm
  • 源码定位:L191
  • 返回类型:RealmsServer
  • 修饰符:public

参数:

  • parentId: Long

说明:

TODO

public List<RealmsNotification> getNotifications() @ L197

  • 方法名:getNotifications
  • 源码定位:L197
  • 返回类型:List
  • 修饰符:public

参数:

说明:

TODO

private static JsonArray uuidListToJsonArray(List<UUID> uuids) @ L203

  • 方法名:uuidListToJsonArray
  • 源码定位:L203
  • 返回类型:JsonArray
  • 修饰符:private static

参数:

  • uuids: List

说明:

TODO

public void notificationsSeen(List<UUID> notificationUuids) @ L215

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

参数:

  • notificationUuids: List

说明:

TODO

public void notificationsDismiss(List<UUID> notificationUuids) @ L220

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

参数:

  • notificationUuids: List

说明:

TODO

public RealmsServer getOwnRealm(long realmId) @ L225

  • 方法名:getOwnRealm
  • 源码定位:L225
  • 返回类型:RealmsServer
  • 修饰符:public

参数:

  • realmId: long

说明:

TODO

public PreferredRegionsDto getPreferredRegionSelections() @ L231

  • 方法名:getPreferredRegionSelections
  • 源码定位:L231
  • 返回类型:PreferredRegionsDto
  • 修饰符:public

参数:

说明:

TODO

public RealmsServerPlayerLists getLiveStats() @ L256

  • 方法名:getLiveStats
  • 源码定位:L256
  • 返回类型:RealmsServerPlayerLists
  • 修饰符:public

参数:

说明:

TODO

public RealmsJoinInformation join(long realmId) @ L262

  • 方法名:join
  • 源码定位:L262
  • 返回类型:RealmsJoinInformation
  • 修饰符:public

参数:

  • realmId: long

说明:

TODO

public void initializeRealm(long realmId, String name, String motd) @ L268

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

参数:

  • realmId: long
  • name: String
  • motd: String

说明:

TODO

public boolean hasParentalConsent() @ L275

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

参数:

说明:

TODO

public RealmsClient.CompatibleVersionResponse clientCompatible() @ L281

  • 方法名:clientCompatible
  • 源码定位:L281
  • 返回类型:RealmsClient.CompatibleVersionResponse
  • 修饰符:public

参数:

说明:

TODO

public void uninvite(long realmId, UUID profileId) @ L292

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

参数:

  • realmId: long
  • profileId: UUID

说明:

TODO

public void uninviteMyselfFrom(long realmId) @ L299

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

参数:

  • realmId: long

说明:

TODO

public List<PlayerInfo> invite(long realmId, String profileName) @ L304

  • 方法名:invite
  • 源码定位:L304
  • 返回类型:List
  • 修饰符:public

参数:

  • realmId: long
  • profileName: String

说明:

TODO

public BackupList backupsFor(long realmId) @ L312

  • 方法名:backupsFor
  • 源码定位:L312
  • 返回类型:BackupList
  • 修饰符:public

参数:

  • realmId: long

说明:

TODO

public void updateConfiguration(long realmId, String name, String description, RegionSelectionPreferenceDto regionSelectionPreference, int slotId, RealmsWorldOptions options, List<RealmsSetting> settings) @ L318

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

参数:

  • realmId: long
  • name: String
  • description: String
  • regionSelectionPreference: RegionSelectionPreferenceDto
  • slotId: int
  • options: RealmsWorldOptions
  • settings: List

说明:

TODO

public void updateSlot(long realmId, int slotId, RealmsWorldOptions options, List<RealmsSetting> settings) @ L337

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

参数:

  • realmId: long
  • slotId: int
  • options: RealmsWorldOptions
  • settings: List

说明:

TODO

public boolean switchSlot(long realmId, int slot) @ L345

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

参数:

  • realmId: long
  • slot: int

说明:

TODO

public void restoreWorld(long realmId, String backupId) @ L353

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

参数:

  • realmId: long
  • backupId: String

说明:

TODO

public WorldTemplatePaginatedList fetchWorldTemplates(int page, int pageSize, RealmsServer.WorldType type) @ L358

  • 方法名:fetchWorldTemplates
  • 源码定位:L358
  • 返回类型:WorldTemplatePaginatedList
  • 修饰符:public

参数:

  • page: int
  • pageSize: int
  • type: RealmsServer.WorldType

说明:

TODO

public Boolean putIntoMinigameMode(long realmId, String minigameId) @ L366

  • 方法名:putIntoMinigameMode
  • 源码定位:L366
  • 返回类型:Boolean
  • 修饰符:public

参数:

  • realmId: long
  • minigameId: String

说明:

TODO

public Ops op(long realmId, UUID profileId) @ L372

  • 方法名:op
  • 源码定位:L372
  • 返回类型:Ops
  • 修饰符:public

参数:

  • realmId: long
  • profileId: UUID

说明:

TODO

public Ops deop(long realmId, UUID profileId) @ L378

  • 方法名:deop
  • 源码定位:L378
  • 返回类型:Ops
  • 修饰符:public

参数:

  • realmId: long
  • profileId: UUID

说明:

TODO

public Boolean open(long realmId) @ L384

  • 方法名:open
  • 源码定位:L384
  • 返回类型:Boolean
  • 修饰符:public

参数:

  • realmId: long

说明:

TODO

public Boolean close(long realmId) @ L390

  • 方法名:close
  • 源码定位:L390
  • 返回类型:Boolean
  • 修饰符:public

参数:

  • realmId: long

说明:

TODO

public Boolean resetWorldWithTemplate(long realmId, String worldTemplateId) @ L396

  • 方法名:resetWorldWithTemplate
  • 源码定位:L396
  • 返回类型:Boolean
  • 修饰符:public

参数:

  • realmId: long
  • worldTemplateId: String

说明:

TODO

public Subscription subscriptionFor(long realmId) @ L403

  • 方法名:subscriptionFor
  • 源码定位:L403
  • 返回类型:Subscription
  • 修饰符:public

参数:

  • realmId: long

说明:

TODO

public int pendingInvitesCount() @ L409

  • 方法名:pendingInvitesCount
  • 源码定位:L409
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public PendingInvitesList pendingInvites() @ L413

  • 方法名:pendingInvites
  • 源码定位:L413
  • 返回类型:PendingInvitesList
  • 修饰符:public

参数:

说明:

TODO

private boolean isBlocked(PendingInvite invite) @ L421

  • 方法名:isBlocked
  • 源码定位:L421
  • 返回类型:boolean
  • 修饰符:private

参数:

  • invite: PendingInvite

说明:

TODO

public void acceptInvitation(String invitationId) @ L425

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

参数:

  • invitationId: String

说明:

TODO

public WorldDownload requestDownloadInfo(long realmId, int slotId) @ L430

  • 方法名:requestDownloadInfo
  • 源码定位:L430
  • 返回类型:WorldDownload
  • 修饰符:public

参数:

  • realmId: long
  • slotId: int

说明:

TODO

public UploadInfo requestUploadInfo(long realmId) @ L438

  • 方法名:requestUploadInfo
  • 源码定位:L438
  • 返回类型:UploadInfo
  • 修饰符:public

参数:

  • realmId: long

说明:

TODO

public void rejectInvitation(String invitationId) @ L449

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

参数:

  • invitationId: String

说明:

TODO

public void agreeToTos() @ L454

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

参数:

说明:

TODO

public RealmsNews getNews() @ L459

  • 方法名:getNews
  • 源码定位:L459
  • 返回类型:RealmsNews
  • 修饰符:public

参数:

说明:

TODO

public void sendPingResults(PingResult pingResult) @ L465

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

参数:

  • pingResult: PingResult

说明:

TODO

public Boolean trialAvailable() @ L470

  • 方法名:trialAvailable
  • 源码定位:L470
  • 返回类型:Boolean
  • 修饰符:public

参数:

说明:

TODO

public void deleteRealm(long realmId) @ L476

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

参数:

  • realmId: long

说明:

TODO

private String url(String path) @ L481

  • 方法名:url
  • 源码定位:L481
  • 返回类型:String
  • 修饰符:private

参数:

  • path: String

说明:

TODO

private String url(String path, String queryString) @ L485

  • 方法名:url
  • 源码定位:L485
  • 返回类型:String
  • 修饰符:private

参数:

  • path: String
  • queryString: String

说明:

TODO

private static String url(String path, String queryString, boolean useAlternativeURL) @ L489

  • 方法名:url
  • 源码定位:L489
  • 返回类型:String
  • 修饰符:private static

参数:

  • path: String
  • queryString: String
  • useAlternativeURL: boolean

说明:

TODO

private String execute(Request<?> request) @ L498

  • 方法名:execute
  • 源码定位:L498
  • 返回类型:String
  • 修饰符:private

参数:

  • request: Request<?>

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class RealmsClient {
    public static final RealmsClient.Environment ENVIRONMENT = Optional.ofNullable(System.getenv("realms.environment"))
        .or(() -> Optional.ofNullable(System.getProperty("realms.environment")))
        .flatMap(RealmsClient.Environment::byName)
        .orElse(RealmsClient.Environment.PRODUCTION);
    private static final Logger LOGGER = LogUtils.getLogger();
    private static volatile @Nullable RealmsClient realmsClientInstance = null;
    private final CompletableFuture<Set<String>> featureFlags;
    private final String sessionId;
    private final String username;
    private final Minecraft minecraft;
    private static final String WORLDS_RESOURCE_PATH = "worlds";
    private static final String INVITES_RESOURCE_PATH = "invites";
    private static final String MCO_RESOURCE_PATH = "mco";
    private static final String SUBSCRIPTION_RESOURCE = "subscriptions";
    private static final String ACTIVITIES_RESOURCE = "activities";
    private static final String OPS_RESOURCE = "ops";
    private static final String REGIONS_RESOURCE = "regions/ping/stat";
    private static final String PREFERRED_REGION_RESOURCE = "regions/preferredRegions";
    private static final String TRIALS_RESOURCE = "trial";
    private static final String NOTIFICATIONS_RESOURCE = "notifications";
    private static final String FEATURE_FLAGS_RESOURCE = "feature/v1";
    private static final String PATH_LIST_ALL_REALMS = "/listUserWorldsOfType/any";
    private static final String PATH_CREATE_SNAPSHOT_REALM = "/$PARENT_WORLD_ID/createPrereleaseRealm";
    private static final String PATH_SNAPSHOT_ELIGIBLE_REALMS = "/listPrereleaseEligibleWorlds";
    private static final String PATH_INITIALIZE = "/$WORLD_ID/initialize";
    private static final String PATH_GET_LIVESTATS = "/liveplayerlist";
    private static final String PATH_GET_SUBSCRIPTION = "/$WORLD_ID";
    private static final String PATH_OP = "/$WORLD_ID/$PROFILE_UUID";
    private static final String PATH_PUT_INTO_MINIGAMES_MODE = "/minigames/$MINIGAME_ID/$WORLD_ID";
    private static final String PATH_AVAILABLE = "/available";
    private static final String PATH_TEMPLATES = "/templates/$WORLD_TYPE";
    private static final String PATH_WORLD_JOIN = "/v1/$ID/join/pc";
    private static final String PATH_WORLD_GET = "/$ID";
    private static final String PATH_WORLD_INVITES = "/$WORLD_ID";
    private static final String PATH_WORLD_UNINVITE = "/$WORLD_ID/invite/$UUID";
    private static final String PATH_PENDING_INVITES = "/pending";
    private static final String PATH_ACCEPT_INVITE = "/accept/$INVITATION_ID";
    private static final String PATH_REJECT_INVITE = "/reject/$INVITATION_ID";
    private static final String PATH_UNINVITE_MYSELF = "/$WORLD_ID";
    private static final String PATH_WORLD_CONFIGURE = "/$WORLD_ID/configuration";
    private static final String PATH_SLOT = "/$WORLD_ID/slot/$SLOT_ID";
    private static final String PATH_WORLD_OPEN = "/$WORLD_ID/open";
    private static final String PATH_WORLD_CLOSE = "/$WORLD_ID/close";
    private static final String PATH_WORLD_RESET = "/$WORLD_ID/reset";
    private static final String PATH_DELETE_WORLD = "/$WORLD_ID";
    private static final String PATH_WORLD_BACKUPS = "/$WORLD_ID/backups";
    private static final String PATH_WORLD_DOWNLOAD = "/$WORLD_ID/slot/$SLOT_ID/download";
    private static final String PATH_WORLD_UPLOAD = "/$WORLD_ID/backups/upload";
    private static final String PATH_CLIENT_COMPATIBLE = "/client/compatible";
    private static final String PATH_TOS_AGREED = "/tos/agreed";
    private static final String PATH_NEWS = "/v1/news";
    private static final String PATH_MARK_NOTIFICATIONS_SEEN = "/seen";
    private static final String PATH_DISMISS_NOTIFICATIONS = "/dismiss";
    private static final GuardedSerializer GSON = new GuardedSerializer();
 
    public static RealmsClient getOrCreate() {
        Minecraft minecraft = Minecraft.getInstance();
        return getOrCreate(minecraft);
    }
 
    public static RealmsClient getOrCreate(Minecraft minecraft) {
        String username = minecraft.getUser().getName();
        String sessionId = minecraft.getUser().getSessionId();
        RealmsClient realmsClient = realmsClientInstance;
        if (realmsClient != null) {
            return realmsClient;
        } else {
            synchronized (RealmsClient.class) {
                RealmsClient rc = realmsClientInstance;
                if (rc != null) {
                    return rc;
                } else {
                    rc = new RealmsClient(sessionId, username, minecraft);
                    realmsClientInstance = rc;
                    return rc;
                }
            }
        }
    }
 
    private RealmsClient(String sessionId, String username, Minecraft minecraft) {
        this.sessionId = sessionId;
        this.username = username;
        this.minecraft = minecraft;
        RealmsClientConfig.setProxy(minecraft.getProxy());
        this.featureFlags = CompletableFuture.supplyAsync(this::fetchFeatureFlags, Util.nonCriticalIoPool());
    }
 
    public Set<String> getFeatureFlags() {
        return this.featureFlags.join();
    }
 
    private Set<String> fetchFeatureFlags() {
        if (Minecraft.getInstance().isOfflineDeveloperMode()) {
            return Set.of();
        } else {
            String asciiUrl = url("feature/v1", null, false);
 
            try {
                String returnJson = this.execute(Request.get(asciiUrl, 5000, 10000));
                JsonArray object = LenientJsonParser.parse(returnJson).getAsJsonArray();
                Set<String> featureFlags = object.asList().stream().map(JsonElement::getAsString).collect(Collectors.toSet());
                LOGGER.debug("Fetched Realms feature flags: {}", featureFlags);
                return featureFlags;
            } catch (RealmsServiceException var5) {
                LOGGER.error("Failed to fetch Realms feature flags", (Throwable)var5);
            } catch (Exception var6) {
                LOGGER.error("Could not parse Realms feature flags", (Throwable)var6);
            }
 
            return Set.of();
        }
    }
 
    public RealmsServerList listRealms() throws RealmsServiceException {
        String asciiUrl = this.url("worlds");
        if (RealmsMainScreen.isSnapshot()) {
            asciiUrl = asciiUrl + "/listUserWorldsOfType/any";
        }
 
        String json = this.execute(Request.get(asciiUrl));
        return RealmsServerList.parse(GSON, json);
    }
 
    public List<RealmsServer> listSnapshotEligibleRealms() throws RealmsServiceException {
        String asciiUrl = this.url("worlds/listPrereleaseEligibleWorlds");
        String json = this.execute(Request.get(asciiUrl));
        return RealmsServerList.parse(GSON, json).servers();
    }
 
    public RealmsServer createSnapshotRealm(Long parentId) throws RealmsServiceException {
        String parentIdString = String.valueOf(parentId);
        String url = this.url("worlds" + "/$PARENT_WORLD_ID/createPrereleaseRealm".replace("$PARENT_WORLD_ID", parentIdString));
        return RealmsServer.parse(GSON, this.execute(Request.post(url, parentIdString)));
    }
 
    public List<RealmsNotification> getNotifications() throws RealmsServiceException {
        String endpoint = this.url("notifications");
        String responseJson = this.execute(Request.get(endpoint));
        return RealmsNotification.parseList(responseJson);
    }
 
    private static JsonArray uuidListToJsonArray(List<UUID> uuids) {
        JsonArray array = new JsonArray();
 
        for (UUID uuid : uuids) {
            if (uuid != null) {
                array.add(uuid.toString());
            }
        }
 
        return array;
    }
 
    public void notificationsSeen(List<UUID> notificationUuids) throws RealmsServiceException {
        String endpoint = this.url("notifications/seen");
        this.execute(Request.post(endpoint, GSON.toJson(uuidListToJsonArray(notificationUuids))));
    }
 
    public void notificationsDismiss(List<UUID> notificationUuids) throws RealmsServiceException {
        String endpoint = this.url("notifications/dismiss");
        this.execute(Request.post(endpoint, GSON.toJson(uuidListToJsonArray(notificationUuids))));
    }
 
    public RealmsServer getOwnRealm(long realmId) throws RealmsServiceException {
        String asciiUrl = this.url("worlds" + "/$ID".replace("$ID", String.valueOf(realmId)));
        String json = this.execute(Request.get(asciiUrl));
        return RealmsServer.parse(GSON, json);
    }
 
    public PreferredRegionsDto getPreferredRegionSelections() throws RealmsServiceException {
        String asciiUrl = this.url("regions/preferredRegions");
        String json = this.execute(Request.get(asciiUrl));
 
        try {
            PreferredRegionsDto preferredRegionsDto = GSON.fromJson(json, PreferredRegionsDto.class);
            if (preferredRegionsDto == null) {
                return PreferredRegionsDto.empty();
            } else {
                Set<RealmsRegion> regionsInResponse = preferredRegionsDto.regionData().stream().map(RegionDataDto::region).collect(Collectors.toSet());
 
                for (RealmsRegion region : RealmsRegion.values()) {
                    if (region != RealmsRegion.INVALID_REGION && !regionsInResponse.contains(region)) {
                        LOGGER.debug("No realms region matching {} in server response", region);
                    }
                }
 
                return preferredRegionsDto;
            }
        } catch (Exception var9) {
            LOGGER.error("Could not parse PreferredRegionSelections", (Throwable)var9);
            return PreferredRegionsDto.empty();
        }
    }
 
    public RealmsServerPlayerLists getLiveStats() throws RealmsServiceException {
        String asciiUrl = this.url("activities/liveplayerlist");
        String json = this.execute(Request.get(asciiUrl));
        return RealmsServerPlayerLists.parse(json);
    }
 
    public RealmsJoinInformation join(long realmId) throws RealmsServiceException {
        String asciiUrl = this.url("worlds" + "/v1/$ID/join/pc".replace("$ID", realmId + ""));
        String json = this.execute(Request.get(asciiUrl, 5000, 30000));
        return RealmsJoinInformation.parse(GSON, json);
    }
 
    public void initializeRealm(long realmId, String name, String motd) throws RealmsServiceException {
        RealmsDescriptionDto realmsDescription = new RealmsDescriptionDto(name, motd);
        String asciiUrl = this.url("worlds" + "/$WORLD_ID/initialize".replace("$WORLD_ID", String.valueOf(realmId)));
        String json = GSON.toJson(realmsDescription);
        this.execute(Request.post(asciiUrl, json, 5000, 10000));
    }
 
    public boolean hasParentalConsent() throws RealmsServiceException {
        String asciiUrl = this.url("mco/available");
        String json = this.execute(Request.get(asciiUrl));
        return Boolean.parseBoolean(json);
    }
 
    public RealmsClient.CompatibleVersionResponse clientCompatible() throws RealmsServiceException {
        String asciiUrl = this.url("mco/client/compatible");
        String response = this.execute(Request.get(asciiUrl));
 
        try {
            return RealmsClient.CompatibleVersionResponse.valueOf(response);
        } catch (IllegalArgumentException var5) {
            throw new RealmsServiceException(RealmsError.CustomError.unknownCompatibilityResponse(response));
        }
    }
 
    public void uninvite(long realmId, UUID profileId) throws RealmsServiceException {
        String asciiUrl = this.url(
            "invites" + "/$WORLD_ID/invite/$UUID".replace("$WORLD_ID", String.valueOf(realmId)).replace("$UUID", UndashedUuid.toString(profileId))
        );
        this.execute(Request.delete(asciiUrl));
    }
 
    public void uninviteMyselfFrom(long realmId) throws RealmsServiceException {
        String asciiUrl = this.url("invites" + "/$WORLD_ID".replace("$WORLD_ID", String.valueOf(realmId)));
        this.execute(Request.delete(asciiUrl));
    }
 
    public List<PlayerInfo> invite(long realmId, String profileName) throws RealmsServiceException {
        OutboundPlayer playerInfo = new OutboundPlayer();
        playerInfo.name = profileName;
        String asciiUrl = this.url("invites" + "/$WORLD_ID".replace("$WORLD_ID", String.valueOf(realmId)));
        String json = this.execute(Request.post(asciiUrl, GSON.toJson(playerInfo)));
        return RealmsServer.parse(GSON, json).players;
    }
 
    public BackupList backupsFor(long realmId) throws RealmsServiceException {
        String asciiUrl = this.url("worlds" + "/$WORLD_ID/backups".replace("$WORLD_ID", String.valueOf(realmId)));
        String json = this.execute(Request.get(asciiUrl));
        return BackupList.parse(json);
    }
 
    public void updateConfiguration(
        long realmId,
        String name,
        String description,
        @Nullable RegionSelectionPreferenceDto regionSelectionPreference,
        int slotId,
        RealmsWorldOptions options,
        List<RealmsSetting> settings
    ) throws RealmsServiceException {
        RegionSelectionPreferenceDto preferenceDto = regionSelectionPreference != null
            ? regionSelectionPreference
            : new RegionSelectionPreferenceDto(RegionSelectionPreference.DEFAULT_SELECTION, null);
        RealmsDescriptionDto realmsDescription = new RealmsDescriptionDto(name, description);
        RealmsSlotUpdateDto slotUpdateDto = new RealmsSlotUpdateDto(slotId, options, RealmsSetting.isHardcore(settings));
        RealmsConfigurationDto realmsConfiguration = new RealmsConfigurationDto(slotUpdateDto, settings, preferenceDto, realmsDescription);
        String asciiUrl = this.url("worlds" + "/$WORLD_ID/configuration".replace("$WORLD_ID", String.valueOf(realmId)));
        this.execute(Request.post(asciiUrl, GSON.toJson(realmsConfiguration)));
    }
 
    public void updateSlot(long realmId, int slotId, RealmsWorldOptions options, List<RealmsSetting> settings) throws RealmsServiceException {
        String asciiUrl = this.url(
            "worlds" + "/$WORLD_ID/slot/$SLOT_ID".replace("$WORLD_ID", String.valueOf(realmId)).replace("$SLOT_ID", String.valueOf(slotId))
        );
        String json = GSON.toJson(new RealmsSlotUpdateDto(slotId, options, RealmsSetting.isHardcore(settings)));
        this.execute(Request.post(asciiUrl, json));
    }
 
    public boolean switchSlot(long realmId, int slot) throws RealmsServiceException {
        String asciiUrl = this.url(
            "worlds" + "/$WORLD_ID/slot/$SLOT_ID".replace("$WORLD_ID", String.valueOf(realmId)).replace("$SLOT_ID", String.valueOf(slot))
        );
        String json = this.execute(Request.put(asciiUrl, ""));
        return Boolean.valueOf(json);
    }
 
    public void restoreWorld(long realmId, String backupId) throws RealmsServiceException {
        String asciiUrl = this.url("worlds" + "/$WORLD_ID/backups".replace("$WORLD_ID", String.valueOf(realmId)), "backupId=" + backupId);
        this.execute(Request.put(asciiUrl, "", 40000, 600000));
    }
 
    public WorldTemplatePaginatedList fetchWorldTemplates(int page, int pageSize, RealmsServer.WorldType type) throws RealmsServiceException {
        String asciiUrl = this.url(
            "worlds" + "/templates/$WORLD_TYPE".replace("$WORLD_TYPE", type.toString()), String.format(Locale.ROOT, "page=%d&pageSize=%d", page, pageSize)
        );
        String json = this.execute(Request.get(asciiUrl));
        return WorldTemplatePaginatedList.parse(json);
    }
 
    public Boolean putIntoMinigameMode(long realmId, String minigameId) throws RealmsServiceException {
        String path = "/minigames/$MINIGAME_ID/$WORLD_ID".replace("$MINIGAME_ID", minigameId).replace("$WORLD_ID", String.valueOf(realmId));
        String asciiUrl = this.url("worlds" + path);
        return Boolean.valueOf(this.execute(Request.put(asciiUrl, "")));
    }
 
    public Ops op(long realmId, UUID profileId) throws RealmsServiceException {
        String path = "/$WORLD_ID/$PROFILE_UUID".replace("$WORLD_ID", String.valueOf(realmId)).replace("$PROFILE_UUID", UndashedUuid.toString(profileId));
        String asciiUrl = this.url("ops" + path);
        return Ops.parse(this.execute(Request.post(asciiUrl, "")));
    }
 
    public Ops deop(long realmId, UUID profileId) throws RealmsServiceException {
        String path = "/$WORLD_ID/$PROFILE_UUID".replace("$WORLD_ID", String.valueOf(realmId)).replace("$PROFILE_UUID", UndashedUuid.toString(profileId));
        String asciiUrl = this.url("ops" + path);
        return Ops.parse(this.execute(Request.delete(asciiUrl)));
    }
 
    public Boolean open(long realmId) throws RealmsServiceException {
        String asciiUrl = this.url("worlds" + "/$WORLD_ID/open".replace("$WORLD_ID", String.valueOf(realmId)));
        String json = this.execute(Request.put(asciiUrl, ""));
        return Boolean.valueOf(json);
    }
 
    public Boolean close(long realmId) throws RealmsServiceException {
        String asciiUrl = this.url("worlds" + "/$WORLD_ID/close".replace("$WORLD_ID", String.valueOf(realmId)));
        String json = this.execute(Request.put(asciiUrl, ""));
        return Boolean.valueOf(json);
    }
 
    public Boolean resetWorldWithTemplate(long realmId, String worldTemplateId) throws RealmsServiceException {
        RealmsWorldResetDto worldReset = new RealmsWorldResetDto(null, Long.valueOf(worldTemplateId), -1, false, Set.of());
        String asciiUrl = this.url("worlds" + "/$WORLD_ID/reset".replace("$WORLD_ID", String.valueOf(realmId)));
        String json = this.execute(Request.post(asciiUrl, GSON.toJson(worldReset), 30000, 80000));
        return Boolean.valueOf(json);
    }
 
    public Subscription subscriptionFor(long realmId) throws RealmsServiceException {
        String asciiUrl = this.url("subscriptions" + "/$WORLD_ID".replace("$WORLD_ID", String.valueOf(realmId)));
        String json = this.execute(Request.get(asciiUrl));
        return Subscription.parse(json);
    }
 
    public int pendingInvitesCount() throws RealmsServiceException {
        return this.pendingInvites().pendingInvites().size();
    }
 
    public PendingInvitesList pendingInvites() throws RealmsServiceException {
        String asciiUrl = this.url("invites/pending");
        String json = this.execute(Request.get(asciiUrl));
        PendingInvitesList list = PendingInvitesList.parse(json);
        list.pendingInvites().removeIf(this::isBlocked);
        return list;
    }
 
    private boolean isBlocked(PendingInvite invite) {
        return this.minecraft.getPlayerSocialManager().isBlocked(invite.realmOwnerUuid());
    }
 
    public void acceptInvitation(String invitationId) throws RealmsServiceException {
        String asciiUrl = this.url("invites" + "/accept/$INVITATION_ID".replace("$INVITATION_ID", invitationId));
        this.execute(Request.put(asciiUrl, ""));
    }
 
    public WorldDownload requestDownloadInfo(long realmId, int slotId) throws RealmsServiceException {
        String asciiUrl = this.url(
            "worlds" + "/$WORLD_ID/slot/$SLOT_ID/download".replace("$WORLD_ID", String.valueOf(realmId)).replace("$SLOT_ID", String.valueOf(slotId))
        );
        String json = this.execute(Request.get(asciiUrl));
        return WorldDownload.parse(json);
    }
 
    public @Nullable UploadInfo requestUploadInfo(long realmId) throws RealmsServiceException {
        String asciiUrl = this.url("worlds" + "/$WORLD_ID/backups/upload".replace("$WORLD_ID", String.valueOf(realmId)));
        String uploadToken = UploadTokenCache.get(realmId);
        UploadInfo uploadInfo = UploadInfo.parse(this.execute(Request.put(asciiUrl, UploadInfo.createRequest(uploadToken))));
        if (uploadInfo != null) {
            UploadTokenCache.put(realmId, uploadInfo.token());
        }
 
        return uploadInfo;
    }
 
    public void rejectInvitation(String invitationId) throws RealmsServiceException {
        String asciiUrl = this.url("invites" + "/reject/$INVITATION_ID".replace("$INVITATION_ID", invitationId));
        this.execute(Request.put(asciiUrl, ""));
    }
 
    public void agreeToTos() throws RealmsServiceException {
        String asciiUrl = this.url("mco/tos/agreed");
        this.execute(Request.post(asciiUrl, ""));
    }
 
    public RealmsNews getNews() throws RealmsServiceException {
        String asciiUrl = this.url("mco/v1/news");
        String returnJson = this.execute(Request.get(asciiUrl, 5000, 10000));
        return RealmsNews.parse(returnJson);
    }
 
    public void sendPingResults(PingResult pingResult) throws RealmsServiceException {
        String asciiUrl = this.url("regions/ping/stat");
        this.execute(Request.post(asciiUrl, GSON.toJson(pingResult)));
    }
 
    public Boolean trialAvailable() throws RealmsServiceException {
        String asciiUrl = this.url("trial");
        String json = this.execute(Request.get(asciiUrl));
        return Boolean.valueOf(json);
    }
 
    public void deleteRealm(long realmId) throws RealmsServiceException {
        String asciiUrl = this.url("worlds" + "/$WORLD_ID".replace("$WORLD_ID", String.valueOf(realmId)));
        this.execute(Request.delete(asciiUrl));
    }
 
    private String url(String path) throws RealmsServiceException {
        return this.url(path, null);
    }
 
    private String url(String path, @Nullable String queryString) {
        return url(path, queryString, this.getFeatureFlags().contains("realms_in_aks"));
    }
 
    private static String url(String path, @Nullable String queryString, boolean useAlternativeURL) {
        try {
            return new URI(ENVIRONMENT.protocol, useAlternativeURL ? ENVIRONMENT.alternativeUrl : ENVIRONMENT.baseUrl, "/" + path, queryString, null)
                .toASCIIString();
        } catch (URISyntaxException var4) {
            throw new IllegalArgumentException(path, var4);
        }
    }
 
    private String execute(Request<?> request) throws RealmsServiceException {
        request.cookie("sid", this.sessionId);
        request.cookie("user", this.username);
        request.cookie("version", SharedConstants.getCurrentVersion().name());
        request.addSnapshotHeader(RealmsMainScreen.isSnapshot());
 
        try {
            int responseCode = request.responseCode();
            if (responseCode != 503 && responseCode != 277) {
                String responseText = request.text();
                if (responseCode >= 200 && responseCode < 300) {
                    return responseText;
                } else if (responseCode == 401) {
                    String authenticationHeader = request.getHeader("WWW-Authenticate");
                    LOGGER.info("Could not authorize you against Realms server: {}", authenticationHeader);
                    throw new RealmsServiceException(new RealmsError.AuthenticationError(authenticationHeader));
                } else {
                    String contentType = request.connection.getContentType();
                    if (contentType != null && contentType.startsWith("text/html")) {
                        throw new RealmsServiceException(RealmsError.CustomError.htmlPayload(responseCode, responseText));
                    } else {
                        RealmsError error = RealmsError.parse(responseCode, responseText);
                        throw new RealmsServiceException(error);
                    }
                }
            } else {
                int pauseTime = request.getRetryAfterHeader();
                throw new RetryCallException(pauseTime, responseCode);
            }
        } catch (RealmsHttpException var6) {
            throw new RealmsServiceException(RealmsError.CustomError.connectivityError(var6));
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    public static enum CompatibleVersionResponse {
        COMPATIBLE,
        OUTDATED,
        OTHER;
    }
 
    @OnlyIn(Dist.CLIENT)
    public static enum Environment {
        PRODUCTION("pc.realms.minecraft.net", "java.frontendlegacy.realms.minecraft-services.net", "https"),
        STAGE("pc-stage.realms.minecraft.net", "java.frontendlegacy.stage-c2a40e62.realms.minecraft-services.net", "https"),
        LOCAL("localhost:8080", "localhost:8080", "http");
 
        public final String baseUrl;
        public final String alternativeUrl;
        public final String protocol;
 
        private Environment(String baseUrl, String alternativeUrl, String protocol) {
            this.baseUrl = baseUrl;
            this.alternativeUrl = alternativeUrl;
            this.protocol = protocol;
        }
 
        public static Optional<RealmsClient.Environment> byName(String name) {
            String var1 = name.toLowerCase(Locale.ROOT);
 
            return switch (var1) {
                case "production" -> Optional.of(PRODUCTION);
                case "local" -> Optional.of(LOCAL);
                case "stage", "staging" -> Optional.of(STAGE);
                default -> Optional.empty();
            };
        }
    }
}

引用的其他类

  • RealmsMainScreen

    • 引用位置: 方法调用
    • 关联成员: RealmsMainScreen.isSnapshot()
  • RealmsClientConfig

    • 引用位置: 方法调用
    • 关联成员: RealmsClientConfig.setProxy()
  • RealmsError

    • 引用位置: 方法调用/构造调用
    • 关联成员: AuthenticationError(), RealmsError.AuthenticationError(), RealmsError.CustomError.connectivityError(), RealmsError.CustomError.htmlPayload(), RealmsError.CustomError.unknownCompatibilityResponse(), RealmsError.parse()
  • Request

    • 引用位置: 参数/方法调用
    • 关联成员: Request.delete(), Request.get(), Request.post(), Request.put()
  • BackupList

    • 引用位置: 方法调用/返回值
    • 关联成员: BackupList.parse()
  • GuardedSerializer

    • 引用位置: 字段/构造调用
    • 关联成员: GuardedSerializer()
  • Ops

    • 引用位置: 方法调用/返回值
    • 关联成员: Ops.parse()
  • OutboundPlayer

    • 引用位置: 构造调用
    • 关联成员: OutboundPlayer()
  • PendingInvite

    • 引用位置: 参数
  • PendingInvitesList

    • 引用位置: 方法调用/返回值
    • 关联成员: PendingInvitesList.parse()
  • PingResult

    • 引用位置: 参数
  • PlayerInfo

    • 引用位置: 返回值
  • PreferredRegionsDto

    • 引用位置: 方法调用/返回值
    • 关联成员: PreferredRegionsDto.empty()
  • RealmsConfigurationDto

    • 引用位置: 构造调用
    • 关联成员: RealmsConfigurationDto()
  • RealmsDescriptionDto

    • 引用位置: 构造调用
    • 关联成员: RealmsDescriptionDto()
  • RealmsJoinInformation

    • 引用位置: 方法调用/返回值
    • 关联成员: RealmsJoinInformation.parse()
  • RealmsNews

    • 引用位置: 方法调用/返回值
    • 关联成员: RealmsNews.parse()
  • RealmsNotification

    • 引用位置: 方法调用/返回值
    • 关联成员: RealmsNotification.parseList()
  • RealmsRegion

    • 引用位置: 方法调用
    • 关联成员: RealmsRegion.values()
  • RealmsServer

    • 引用位置: 参数/方法调用/返回值
    • 关联成员: RealmsServer.parse()
  • RealmsServerList

    • 引用位置: 方法调用/返回值
    • 关联成员: RealmsServerList.parse()
  • RealmsServerPlayerLists

    • 引用位置: 方法调用/返回值
    • 关联成员: RealmsServerPlayerLists.parse()
  • RealmsSetting

    • 引用位置: 参数/方法调用
    • 关联成员: RealmsSetting.isHardcore()
  • RealmsSlotUpdateDto

    • 引用位置: 构造调用
    • 关联成员: RealmsSlotUpdateDto()
  • RealmsWorldOptions

    • 引用位置: 参数
  • RealmsWorldResetDto

    • 引用位置: 构造调用
    • 关联成员: RealmsWorldResetDto()
  • RegionSelectionPreferenceDto

    • 引用位置: 参数/构造调用
    • 关联成员: RegionSelectionPreferenceDto()
  • Subscription

    • 引用位置: 方法调用/返回值
    • 关联成员: Subscription.parse()
  • UploadInfo

    • 引用位置: 方法调用/返回值
    • 关联成员: UploadInfo.createRequest(), UploadInfo.parse()
  • WorldDownload

    • 引用位置: 方法调用/返回值
    • 关联成员: WorldDownload.parse()
  • WorldTemplatePaginatedList

    • 引用位置: 方法调用/返回值
    • 关联成员: WorldTemplatePaginatedList.parse()
  • RealmsServiceException

    • 引用位置: 构造调用
    • 关联成员: RealmsServiceException()
  • RetryCallException

    • 引用位置: 构造调用
    • 关联成员: RetryCallException()
  • UploadTokenCache

    • 引用位置: 方法调用
    • 关联成员: UploadTokenCache.get(), UploadTokenCache.put()
  • SharedConstants

    • 引用位置: 方法调用
    • 关联成员: SharedConstants.getCurrentVersion()
  • Minecraft

    • 引用位置: 参数/字段/方法调用
    • 关联成员: Minecraft.getInstance()
  • LoggedChatMessage

    • 引用位置: 方法调用
    • 关联成员: System.getProperty(), System.getenv()
  • LenientJsonParser

    • 引用位置: 方法调用
    • 关联成员: LenientJsonParser.parse()
  • Util

    • 引用位置: 方法调用
    • 关联成员: Util.nonCriticalIoPool()