WorldOpenFlows.java
net.minecraft.client.gui.screens.worldselection.WorldOpenFlows
信息
- 全限定名:net.minecraft.client.gui.screens.worldselection.WorldOpenFlows
- 类型:public class
- 包:net.minecraft.client.gui.screens.worldselection
- 源码路径:src/main/java/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java
- 起始行号:L84
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L85 - 说明:
TODO
- 类型:
-
WORLD_PACK_ID- 类型:
UUID - 修饰符:
private static final - 源码定位:
L86 - 说明:
TODO
- 类型:
-
minecraft- 类型:
Minecraft - 修饰符:
private final - 源码定位:
L87 - 说明:
TODO
- 类型:
-
levelSource- 类型:
LevelStorageSource - 修饰符:
private final - 源码定位:
L88 - 说明:
TODO
- 类型:
内部类/嵌套类型
net.minecraft.client.gui.screens.worldselection.WorldOpenFlows.Data- 类型:
record - 修饰符:
package-private - 源码定位:
L194 - 说明:
TODO
- 类型:
构造器
public WorldOpenFlows(Minecraft minecraft, LevelStorageSource levelSource) @ L90
- 构造器名:WorldOpenFlows
- 源码定位:L90
- 修饰符:public
参数:
- minecraft: Minecraft
- levelSource: LevelStorageSource
说明:
TODO
方法
下面的方法块按源码顺序生成。
public void createFreshLevel(String levelId, LevelSettings levelSettings, WorldOptions options, Function<HolderLookup.Provider,WorldDimensions> dimensionsProvider, Screen parentScreen) @ L95
- 方法名:createFreshLevel
- 源码定位:L95
- 返回类型:void
- 修饰符:public
参数:
- levelId: String
- levelSettings: LevelSettings
- options: WorldOptions
- dimensionsProvider: Function<HolderLookup.Provider,WorldDimensions>
- parentScreen: Screen
说明:
TODO
private LevelStorageSource.LevelStorageAccess createWorldAccess(String levelId) @ L134
- 方法名:createWorldAccess
- 源码定位:L134
- 返回类型:LevelStorageSource.LevelStorageAccess
- 修饰符:private
参数:
- levelId: String
说明:
TODO
public void createLevelFromExistingSettings(LevelStorageSource.LevelStorageAccess levelSourceAccess, ReloadableServerResources serverResources, LayeredRegistryAccess<RegistryLayer> registryAccess, LevelDataAndDimensions.WorldDataAndGenSettings worldDataAndGenSettings, Optional<GameRules> gameRules) @ L149
- 方法名:createLevelFromExistingSettings
- 源码定位:L149
- 返回类型:void
- 修饰符:public
参数:
- levelSourceAccess: LevelStorageSource.LevelStorageAccess
- serverResources: ReloadableServerResources
- registryAccess: LayeredRegistryAccess
- worldDataAndGenSettings: LevelDataAndDimensions.WorldDataAndGenSettings
- gameRules: Optional
说明:
TODO
public WorldStem loadWorldStem(LevelStorageSource.LevelStorageAccess worldAccess, Dynamic<?> levelDataTag, boolean safeMode, PackRepository packRepository) @ L168
- 方法名:loadWorldStem
- 源码定位:L168
- 返回类型:WorldStem
- 修饰符:public
参数:
- worldAccess: LevelStorageSource.LevelStorageAccess
- levelDataTag: Dynamic<?>
- safeMode: boolean
- packRepository: PackRepository
说明:
TODO
public Pair<LevelSettings,WorldCreationContext> recreateWorldData(LevelStorageSource.LevelStorageAccess levelSourceAccess) @ L183
- 方法名:recreateWorldData
- 源码定位:L183
- 返回类型:Pair<LevelSettings,WorldCreationContext>
- 修饰符:public
参数:
- levelSourceAccess: LevelStorageSource.LevelStorageAccess
说明:
TODO
private <D,R> R loadWorldDataBlocking(WorldLoader.PackConfig packConfig, WorldLoader.WorldDataSupplier<D> worldDataGetter, WorldLoader.ResultFactory<D,R> worldDataSupplier) @ L238
- 方法名:loadWorldDataBlocking
- 源码定位:L238
- 返回类型:<D,R> R
- 修饰符:private
参数:
- packConfig: WorldLoader.PackConfig
- worldDataGetter: WorldLoader.WorldDataSupplier
- worldDataSupplier: WorldLoader.ResultFactory<D,R>
说明:
TODO
private void askForBackup(LevelStorageSource.LevelStorageAccess levelAccess, boolean oldCustomized, Runnable proceedCallback, Runnable cancelCallback) @ L250
- 方法名:askForBackup
- 源码定位:L250
- 返回类型:void
- 修饰符:private
参数:
- levelAccess: LevelStorageSource.LevelStorageAccess
- oldCustomized: boolean
- proceedCallback: Runnable
- cancelCallback: Runnable
说明:
TODO
public static void confirmWorldCreation(Minecraft minecraft, CreateWorldScreen parent, Lifecycle lifecycle, Runnable task, boolean skipWarning) @ L274
- 方法名:confirmWorldCreation
- 源码定位:L274
- 返回类型:void
- 修饰符:public static
参数:
- minecraft: Minecraft
- parent: CreateWorldScreen
- lifecycle: Lifecycle
- task: Runnable
- skipWarning: boolean
说明:
TODO
public void openWorld(String levelId, Runnable onCancel) @ L301
- 方法名:openWorld
- 源码定位:L301
- 返回类型:void
- 修饰符:public
参数:
- levelId: String
- onCancel: Runnable
说明:
TODO
private void openWorldLoadLevelData(LevelStorageSource.LevelStorageAccess worldAccess, Runnable onCancel) @ L309
- 方法名:openWorldLoadLevelData
- 源码定位:L309
- 返回类型:void
- 修饰符:private
参数:
- worldAccess: LevelStorageSource.LevelStorageAccess
- onCancel: Runnable
说明:
TODO
private void openWorldCheckVersionCompatibility(LevelStorageSource.LevelStorageAccess worldAccess, LevelSummary summary, Dynamic<?> levelDataTag, Runnable onCancel) @ L342
- 方法名:openWorldCheckVersionCompatibility
- 源码定位:L342
- 返回类型:void
- 修饰符:private
参数:
- worldAccess: LevelStorageSource.LevelStorageAccess
- summary: LevelSummary
- levelDataTag: Dynamic<?>
- onCancel: Runnable
说明:
TODO
private void createBackupAndOpenWorld(LevelStorageSource.LevelStorageAccess levelAccess, Dynamic<?> levelDataTag, Runnable onCancel, boolean backup) @ L376
- 方法名:createBackupAndOpenWorld
- 源码定位:L376
- 返回类型:void
- 修饰符:private
参数:
- levelAccess: LevelStorageSource.LevelStorageAccess
- levelDataTag: Dynamic<?>
- onCancel: Runnable
- backup: boolean
说明:
TODO
private void upgradeAndOpenWorld(LevelStorageSource.LevelStorageAccess worldAccess, Dynamic<?> levelDataTag, Runnable onCancel) @ L381
- 方法名:upgradeAndOpenWorld
- 源码定位:L381
- 返回类型:void
- 修饰符:private
参数:
- worldAccess: LevelStorageSource.LevelStorageAccess
- levelDataTag: Dynamic<?>
- onCancel: Runnable
说明:
TODO
private Dynamic<?> tryFileFixAndReportErrors(LevelStorageSource.LevelStorageAccess worldAccess, Dynamic<?> levelDataTag, UpgradeProgress upgradeProgress, Runnable cleanup) @ L415
- 方法名:tryFileFixAndReportErrors
- 源码定位:L415
- 返回类型:Dynamic<?>
- 修饰符:private
参数:
- worldAccess: LevelStorageSource.LevelStorageAccess
- levelDataTag: Dynamic<?>
- upgradeProgress: UpgradeProgress
- cleanup: Runnable
说明:
TODO
private void openWorldLoadLevelStem(LevelStorageSource.LevelStorageAccess worldAccess, Dynamic<?> levelDataTag, boolean safeMode, Runnable onCancel) @ L476
- 方法名:openWorldLoadLevelStem
- 源码定位:L476
- 返回类型:void
- 修饰符:private
参数:
- worldAccess: LevelStorageSource.LevelStorageAccess
- levelDataTag: Dynamic<?>
- safeMode: boolean
- onCancel: Runnable
说明:
TODO
private void openWorldCheckWorldStemCompatibility(LevelStorageSource.LevelStorageAccess worldAccess, WorldStem worldStem, PackRepository packRepository, Runnable onCancel) @ L514
- 方法名:openWorldCheckWorldStemCompatibility
- 源码定位:L514
- 返回类型:void
- 修饰符:private
参数:
- worldAccess: LevelStorageSource.LevelStorageAccess
- worldStem: WorldStem
- packRepository: PackRepository
- onCancel: Runnable
说明:
TODO
private void openWorldLoadBundledResourcePack(LevelStorageSource.LevelStorageAccess worldAccess, WorldStem worldStem, PackRepository packRepository, Runnable onCancel) @ L534
- 方法名:openWorldLoadBundledResourcePack
- 源码定位:L534
- 返回类型:void
- 修饰符:private
参数:
- worldAccess: LevelStorageSource.LevelStorageAccess
- worldStem: WorldStem
- packRepository: PackRepository
- onCancel: Runnable
说明:
TODO
private void openWorldCheckDiskSpace(LevelStorageSource.LevelStorageAccess worldAccess, WorldStem worldStem, DownloadedPackSource packSource, PackRepository packRepository, Runnable onCancel) @ L556
- 方法名:openWorldCheckDiskSpace
- 源码定位:L556
- 返回类型:void
- 修饰符:private
参数:
- worldAccess: LevelStorageSource.LevelStorageAccess
- worldStem: WorldStem
- packSource: DownloadedPackSource
- packRepository: PackRepository
- onCancel: Runnable
说明:
TODO
private void openWorldDoLoad(LevelStorageSource.LevelStorageAccess worldAccess, WorldStem worldStem, PackRepository packRepository) @ L588
- 方法名:openWorldDoLoad
- 源码定位:L588
- 返回类型:void
- 修饰符:private
参数:
- worldAccess: LevelStorageSource.LevelStorageAccess
- worldStem: WorldStem
- packRepository: PackRepository
说明:
TODO
private CompletableFuture<Void> loadBundledResourcePack(DownloadedPackSource packSource, LevelStorageSource.LevelStorageAccess levelSourceAccess) @ L592
- 方法名:loadBundledResourcePack
- 源码定位:L592
- 返回类型:CompletableFuture
- 修饰符:private
参数:
- packSource: DownloadedPackSource
- levelSourceAccess: LevelStorageSource.LevelStorageAccess
说明:
TODO
private CompletableFuture<Boolean> promptBundledPackLoadFailure() @ L604
- 方法名:promptBundledPackLoadFailure
- 源码定位:L604
- 返回类型:CompletableFuture
- 修饰符:private
参数:
- 无
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class WorldOpenFlows {
private static final Logger LOGGER = LogUtils.getLogger();
private static final UUID WORLD_PACK_ID = UUID.fromString("640a6a92-b6cb-48a0-b391-831586500359");
private final Minecraft minecraft;
private final LevelStorageSource levelSource;
public WorldOpenFlows(Minecraft minecraft, LevelStorageSource levelSource) {
this.minecraft = minecraft;
this.levelSource = levelSource;
}
public void createFreshLevel(
String levelId,
LevelSettings levelSettings,
WorldOptions options,
Function<HolderLookup.Provider, WorldDimensions> dimensionsProvider,
Screen parentScreen
) {
this.minecraft.setScreenAndShow(new GenericMessageScreen(Component.translatable("selectWorld.data_read")));
LevelStorageSource.LevelStorageAccess levelSourceAccess = this.createWorldAccess(levelId);
if (levelSourceAccess != null) {
PackRepository packRepository = ServerPacksSource.createPackRepository(levelSourceAccess);
WorldDataConfiguration dataConfiguration = levelSettings.dataConfiguration();
try {
WorldLoader.PackConfig packConfig = new WorldLoader.PackConfig(packRepository, dataConfiguration, false, false);
WorldStem worldStem = this.loadWorldDataBlocking(
packConfig,
context -> {
WorldDimensions dimensions = dimensionsProvider.apply(context.datapackWorldgen());
WorldDimensions.Complete completeDimensions = dimensions.bake(context.datapackDimensions().lookupOrThrow(Registries.LEVEL_STEM));
return new WorldLoader.DataLoadOutput<>(
new LevelDataAndDimensions.WorldDataAndGenSettings(
new PrimaryLevelData(levelSettings, completeDimensions.specialWorldProperty(), completeDimensions.lifecycle()),
new WorldGenSettings(options, dimensions)
),
completeDimensions.dimensionsRegistryAccess()
);
},
WorldStem::new
);
this.minecraft.doWorldLoad(levelSourceAccess, packRepository, worldStem, Optional.empty(), true);
} catch (Exception var11) {
LOGGER.warn("Failed to load datapacks, can't proceed with server load", (Throwable)var11);
levelSourceAccess.safeClose();
this.minecraft.setScreen(parentScreen);
}
}
}
private LevelStorageSource.@Nullable LevelStorageAccess createWorldAccess(String levelId) {
try {
return this.levelSource.validateAndCreateAccess(levelId);
} catch (IOException var3) {
LOGGER.warn("Failed to read level {} data", levelId, var3);
SystemToast.onWorldAccessFailure(this.minecraft, levelId);
this.minecraft.setScreen(null);
return null;
} catch (ContentValidationException var4) {
LOGGER.warn("{}", var4.getMessage());
this.minecraft.setScreen(NoticeWithLinkScreen.createWorldSymlinkWarningScreen(() -> this.minecraft.setScreen(null)));
return null;
}
}
public void createLevelFromExistingSettings(
LevelStorageSource.LevelStorageAccess levelSourceAccess,
ReloadableServerResources serverResources,
LayeredRegistryAccess<RegistryLayer> registryAccess,
LevelDataAndDimensions.WorldDataAndGenSettings worldDataAndGenSettings,
Optional<GameRules> gameRules
) {
PackRepository packRepository = ServerPacksSource.createPackRepository(levelSourceAccess);
CloseableResourceManager resourceManager = new WorldLoader.PackConfig(
packRepository, worldDataAndGenSettings.data().getDataConfiguration(), false, false
)
.createResourceManager()
.getSecond();
this.minecraft
.doWorldLoad(
levelSourceAccess, packRepository, new WorldStem(resourceManager, serverResources, registryAccess, worldDataAndGenSettings), gameRules, true
);
}
public WorldStem loadWorldStem(LevelStorageSource.LevelStorageAccess worldAccess, Dynamic<?> levelDataTag, boolean safeMode, PackRepository packRepository) throws Exception {
WorldLoader.PackConfig packConfig = LevelStorageSource.getPackConfig(levelDataTag, packRepository, safeMode);
return this.loadWorldDataBlocking(
packConfig,
context -> {
Registry<LevelStem> datapackDimensions = context.datapackDimensions().lookupOrThrow(Registries.LEVEL_STEM);
LevelDataAndDimensions data = LevelStorageSource.getLevelDataAndDimensions(
worldAccess, levelDataTag, context.dataConfiguration(), datapackDimensions, context.datapackWorldgen()
);
return new WorldLoader.DataLoadOutput<>(data.worldDataAndGenSettings(), data.dimensions().dimensionsRegistryAccess());
},
WorldStem::new
);
}
public Pair<LevelSettings, WorldCreationContext> recreateWorldData(LevelStorageSource.LevelStorageAccess levelSourceAccess) throws Exception {
PackRepository packRepository = ServerPacksSource.createPackRepository(levelSourceAccess);
Dynamic<?> unfixedDataTag = levelSourceAccess.getUnfixedDataTag(false);
int dataVersion = NbtUtils.getDataVersion(unfixedDataTag);
if (DataFixers.getFileFixer().requiresFileFixing(dataVersion)) {
throw new IllegalStateException("Can't recreate world before file fixing; shouldn't be able to get here");
} else {
Dynamic<?> levelDataTag = DataFixTypes.LEVEL.updateToCurrentVersion(DataFixers.getDataFixer(), unfixedDataTag, dataVersion);
WorldLoader.PackConfig packConfig = LevelStorageSource.getPackConfig(levelDataTag, packRepository, false);
@OnlyIn(Dist.CLIENT)
record Data(LevelSettings levelSettings, WorldOptions options, Registry<LevelStem> existingDimensions) {
}
return this.loadWorldDataBlocking(
packConfig,
context -> {
Registry<LevelStem> noDatapackDimensions = new MappedRegistry<>(Registries.LEVEL_STEM, Lifecycle.stable()).freeze();
LevelDataAndDimensions existingData = LevelStorageSource.getLevelDataAndDimensions(
levelSourceAccess, levelDataTag, context.dataConfiguration(), noDatapackDimensions, context.datapackWorldgen()
);
return new WorldLoader.DataLoadOutput<>(
new Data(
existingData.worldDataAndGenSettings().data().getLevelSettings(),
existingData.worldDataAndGenSettings().genSettings().options(),
existingData.dimensions().dimensions()
),
context.datapackDimensions()
);
},
(resources, managers, registries, loadedData) -> {
resources.close();
DataResult<GameRuleMap> existingGameRules = LevelStorageSource.readExistingSavedData(
levelSourceAccess, registries.compositeAccess(), GameRuleMap.TYPE
);
existingGameRules.ifError(e -> LOGGER.error("Failed to parse existing game rules: {}", e.message()));
InitialWorldCreationOptions initialWorldCreationOptions = new InitialWorldCreationOptions(
WorldCreationUiState.SelectedGameMode.SURVIVAL, existingGameRules.result().orElse(GameRuleMap.of()), null
);
return Pair.of(
loadedData.levelSettings,
new WorldCreationContext(
loadedData.options,
new WorldDimensions(loadedData.existingDimensions),
registries,
managers,
loadedData.levelSettings.dataConfiguration(),
initialWorldCreationOptions
)
);
}
);
}
}
private <D, R> R loadWorldDataBlocking(
WorldLoader.PackConfig packConfig, WorldLoader.WorldDataSupplier<D> worldDataGetter, WorldLoader.ResultFactory<D, R> worldDataSupplier
) throws Exception {
long start = Util.getMillis();
WorldLoader.InitConfig config = new WorldLoader.InitConfig(packConfig, Commands.CommandSelection.INTEGRATED, LevelBasedPermissionSet.GAMEMASTER);
CompletableFuture<R> resourceLoad = WorldLoader.load(config, worldDataGetter, worldDataSupplier, Util.backgroundExecutor(), this.minecraft);
this.minecraft.managedBlock(resourceLoad::isDone);
long end = Util.getMillis();
LOGGER.debug("World resource load blocked for {} ms", end - start);
return resourceLoad.get();
}
private void askForBackup(LevelStorageSource.LevelStorageAccess levelAccess, boolean oldCustomized, Runnable proceedCallback, Runnable cancelCallback) {
Component backupQuestion;
Component backupWarning;
if (oldCustomized) {
backupQuestion = Component.translatable("selectWorld.backupQuestion.customized");
backupWarning = Component.translatable("selectWorld.backupWarning.customized");
} else {
backupQuestion = Component.translatable("selectWorld.backupQuestion.experimental");
backupWarning = Component.translatable("selectWorld.backupWarning.experimental");
}
this.minecraft
.setScreen(
new BackupConfirmScreen(
cancelCallback,
(backup, eraseCache) -> EditWorldScreen.conditionallyMakeBackupAndShowToast(backup, levelAccess)
.thenAcceptAsync(var1x -> proceedCallback.run(), this.minecraft),
backupQuestion,
backupWarning,
false
)
);
}
public static void confirmWorldCreation(Minecraft minecraft, CreateWorldScreen parent, Lifecycle lifecycle, Runnable task, boolean skipWarning) {
BooleanConsumer callback = confirmed -> {
if (confirmed) {
task.run();
} else {
minecraft.setScreen(parent);
}
};
if (skipWarning || lifecycle == Lifecycle.stable()) {
task.run();
} else if (lifecycle == Lifecycle.experimental()) {
minecraft.setScreen(
new ConfirmScreen(
callback,
Component.translatable("selectWorld.warning.experimental.title"),
Component.translatable("selectWorld.warning.experimental.question")
)
);
} else {
minecraft.setScreen(
new ConfirmScreen(
callback, Component.translatable("selectWorld.warning.deprecated.title"), Component.translatable("selectWorld.warning.deprecated.question")
)
);
}
}
public void openWorld(String levelId, Runnable onCancel) {
this.minecraft.setScreenAndShow(new GenericMessageScreen(Component.translatable("selectWorld.data_read")));
LevelStorageSource.LevelStorageAccess worldAccess = this.createWorldAccess(levelId);
if (worldAccess != null) {
this.openWorldLoadLevelData(worldAccess, onCancel);
}
}
private void openWorldLoadLevelData(LevelStorageSource.LevelStorageAccess worldAccess, Runnable onCancel) {
this.minecraft.setScreenAndShow(new GenericMessageScreen(Component.translatable("selectWorld.data_read")));
Dynamic<?> levelDataTag;
LevelSummary summary;
try {
levelDataTag = worldAccess.getUnfixedDataTag(false);
summary = worldAccess.fixAndGetSummaryFromTag(levelDataTag);
} catch (NbtException | ReportedNbtException | IOException var10) {
this.minecraft.setScreen(new RecoverWorldDataScreen(this.minecraft, success -> {
if (success) {
this.openWorldLoadLevelData(worldAccess, onCancel);
} else {
worldAccess.safeClose();
onCancel.run();
}
}, worldAccess));
return;
} catch (OutOfMemoryError var11) {
MemoryReserve.release();
String detailedMessage = "Ran out of memory trying to read level data of world folder \"" + worldAccess.getLevelId() + "\"";
LOGGER.error(LogUtils.FATAL_MARKER, detailedMessage);
OutOfMemoryError detailedException = new OutOfMemoryError("Ran out of memory reading level data");
detailedException.initCause(var11);
CrashReport crashReport = CrashReport.forThrowable(detailedException, detailedMessage);
CrashReportCategory worldDetails = crashReport.addCategory("World details");
worldDetails.setDetail("World folder", worldAccess.getLevelId());
throw new ReportedException(crashReport);
}
this.openWorldCheckVersionCompatibility(worldAccess, summary, levelDataTag, onCancel);
}
private void openWorldCheckVersionCompatibility(
LevelStorageSource.LevelStorageAccess worldAccess, LevelSummary summary, Dynamic<?> levelDataTag, Runnable onCancel
) {
if (!summary.isCompatible()) {
worldAccess.safeClose();
this.minecraft
.setScreen(
new AlertScreen(
onCancel,
Component.translatable("selectWorld.incompatible.title").withColor(-65536),
Component.translatable("selectWorld.incompatible.description", summary.getWorldVersionName())
)
);
} else {
LevelSummary.BackupStatus backupStatus = summary.backupStatus();
if (backupStatus.shouldBackup()) {
String questionKey = "selectWorld.backupQuestion." + backupStatus.getTranslationKey();
String warningKey = "selectWorld.backupWarning." + backupStatus.getTranslationKey();
MutableComponent backupQuestion = Component.translatable(questionKey);
if (backupStatus.isSevere()) {
backupQuestion.withColor(-2142128);
}
Component backupWarning = Component.translatable(warningKey, summary.getWorldVersionName(), SharedConstants.getCurrentVersion().name());
this.minecraft.setScreen(new BackupConfirmScreen(() -> {
worldAccess.safeClose();
onCancel.run();
}, (backup, eraseCache) -> this.createBackupAndOpenWorld(worldAccess, levelDataTag, onCancel, backup), backupQuestion, backupWarning, false));
} else {
this.upgradeAndOpenWorld(worldAccess, levelDataTag, onCancel);
}
}
}
private void createBackupAndOpenWorld(LevelStorageSource.LevelStorageAccess levelAccess, Dynamic<?> levelDataTag, Runnable onCancel, boolean backup) {
EditWorldScreen.conditionallyMakeBackupAndShowToast(backup, levelAccess)
.thenAcceptAsync(var4 -> this.upgradeAndOpenWorld(levelAccess, levelDataTag, onCancel), this.minecraft);
}
private void upgradeAndOpenWorld(LevelStorageSource.LevelStorageAccess worldAccess, Dynamic<?> levelDataTag, Runnable onCancel) {
Runnable cleanup = () -> {
worldAccess.safeClose();
onCancel.run();
};
int dataVersion = NbtUtils.getDataVersion(levelDataTag);
boolean requiresFileFixing = DataFixers.getFileFixer().requiresFileFixing(dataVersion);
UpgradeProgress upgradeProgress = new UpgradeProgress();
if (requiresFileFixing) {
FileFixerProgressScreen progressScreen = new FileFixerProgressScreen(upgradeProgress);
this.minecraft.setScreenAndShow(progressScreen);
}
Util.backgroundExecutor().execute(() -> {
Dynamic<?> levelDataTagFixed = this.tryFileFixAndReportErrors(worldAccess, levelDataTag, upgradeProgress, cleanup);
if (levelDataTagFixed != null) {
this.minecraft.execute(() -> {
if (requiresFileFixing) {
ConfirmScreen loadConfirmScreen = new ConfirmScreen(result -> {
if (result) {
this.openWorldLoadLevelStem(worldAccess, levelDataTagFixed, false, onCancel);
} else {
cleanup.run();
}
}, Component.translatable("upgradeWorld.done"), Component.translatable("upgradeWorld.joinNow"));
this.minecraft.setScreenAndShow(loadConfirmScreen);
} else {
this.openWorldLoadLevelStem(worldAccess, levelDataTagFixed, false, onCancel);
}
});
}
});
}
private @Nullable Dynamic<?> tryFileFixAndReportErrors(
LevelStorageSource.LevelStorageAccess worldAccess, Dynamic<?> levelDataTag, UpgradeProgress upgradeProgress, Runnable cleanup
) {
try {
return DataFixers.getFileFixer().fix(worldAccess, levelDataTag, upgradeProgress);
} catch (CanceledFileFixException var8) {
this.minecraft
.execute(
() -> this.minecraft
.setScreenAndShow(
new AlertScreen(
cleanup,
Component.translatable("upgradeWorld.canceled.title"),
Component.translatable("upgradeWorld.canceled.message"),
CommonComponents.GUI_OK,
true
)
)
);
return null;
} catch (AbortedFileFixException var9) {
this.minecraft
.execute(
() -> {
if (var9.getCause() instanceof CowFSSymlinkException) {
this.minecraft
.setScreenAndShow(
new AlertScreen(
cleanup, Component.translatable("upgradeWorld.symlink.title"), Component.translatable("upgradeWorld.symlink.message")
)
);
} else {
this.minecraft.setScreenAndShow(new FileFixerAbortedScreen(cleanup, Component.translatable("upgradeWorld.aborted.message")));
}
}
);
return null;
} catch (FailedCleanupFileFixException var10) {
this.minecraft
.execute(
() -> this.minecraft
.setScreenAndShow(
new AlertScreen(
cleanup,
Component.translatable("upgradeWorld.failed_cleanup.title"),
Component.translatable("upgradeWorld.failed_cleanup.message", Component.literal(var10.newWorldFolderName()).withColor(-8355712))
)
)
);
return null;
} catch (FileFixException var11) {
this.minecraft.delayCrash(var11.makeReportedException().getReport());
return null;
} catch (Exception var12) {
LOGGER.error("Failed to upgrade the file structure of the world.", (Throwable)var12);
CrashReport report = CrashReport.forThrowable(var12, "Failed to update file structure");
this.minecraft.delayCrash(report);
return null;
}
}
private void openWorldLoadLevelStem(LevelStorageSource.LevelStorageAccess worldAccess, Dynamic<?> levelDataTag, boolean safeMode, Runnable onCancel) {
this.minecraft.setScreenAndShow(new GenericMessageScreen(Component.translatable("selectWorld.resource_load")));
PackRepository packRepository = ServerPacksSource.createPackRepository(worldAccess);
WorldStem worldStem;
try {
worldStem = this.loadWorldStem(worldAccess, levelDataTag, safeMode, packRepository);
for (LevelStem levelStem : worldStem.registries().compositeAccess().lookupOrThrow(Registries.LEVEL_STEM)) {
levelStem.generator().validate();
}
} catch (Exception var9) {
LOGGER.warn("Failed to load level data or datapacks, can't proceed with server load", (Throwable)var9);
if (!safeMode) {
this.minecraft.setScreen(new DatapackLoadFailureScreen(() -> {
worldAccess.safeClose();
onCancel.run();
}, () -> this.openWorldLoadLevelStem(worldAccess, levelDataTag, true, onCancel)));
} else {
worldAccess.safeClose();
this.minecraft
.setScreen(
new AlertScreen(
onCancel,
Component.translatable("datapackFailure.safeMode.failed.title"),
Component.translatable("datapackFailure.safeMode.failed.description"),
CommonComponents.GUI_BACK,
true
)
);
}
return;
}
this.openWorldCheckWorldStemCompatibility(worldAccess, worldStem, packRepository, onCancel);
}
private void openWorldCheckWorldStemCompatibility(
LevelStorageSource.LevelStorageAccess worldAccess, WorldStem worldStem, PackRepository packRepository, Runnable onCancel
) {
LevelDataAndDimensions.WorldDataAndGenSettings worldDataAndGenSettings = worldStem.worldDataAndGenSettings();
WorldData data = worldDataAndGenSettings.data();
boolean oldCustomized = worldDataAndGenSettings.genSettings().options().isOldCustomizedWorld();
boolean unstable = data.worldGenSettingsLifecycle() != Lifecycle.stable();
if (!oldCustomized && !unstable) {
this.openWorldLoadBundledResourcePack(worldAccess, worldStem, packRepository, onCancel);
} else {
this.askForBackup(
worldAccess, oldCustomized, () -> this.openWorldLoadBundledResourcePack(worldAccess, worldStem, packRepository, onCancel), () -> {
worldStem.close();
worldAccess.safeClose();
onCancel.run();
}
);
}
}
private void openWorldLoadBundledResourcePack(
LevelStorageSource.LevelStorageAccess worldAccess, WorldStem worldStem, PackRepository packRepository, Runnable onCancel
) {
DownloadedPackSource packSource = this.minecraft.getDownloadedPackSource();
this.loadBundledResourcePack(packSource, worldAccess).thenApply(unused -> true).exceptionallyComposeAsync(t -> {
LOGGER.warn("Failed to load pack: ", t);
return this.promptBundledPackLoadFailure();
}, this.minecraft).thenAcceptAsync(result -> {
if (result) {
this.openWorldCheckDiskSpace(worldAccess, worldStem, packSource, packRepository, onCancel);
} else {
packSource.popAll();
worldStem.close();
worldAccess.safeClose();
onCancel.run();
}
}, this.minecraft).exceptionally(e -> {
this.minecraft.delayCrash(CrashReport.forThrowable(e, "Load world"));
return null;
});
}
private void openWorldCheckDiskSpace(
LevelStorageSource.LevelStorageAccess worldAccess,
WorldStem worldStem,
DownloadedPackSource packSource,
PackRepository packRepository,
Runnable onCancel
) {
if (worldAccess.checkForLowDiskSpace()) {
this.minecraft
.setScreen(
new ConfirmScreen(
skip -> {
if (skip) {
this.openWorldDoLoad(worldAccess, worldStem, packRepository);
} else {
packSource.popAll();
worldStem.close();
worldAccess.safeClose();
onCancel.run();
}
},
Component.translatable("selectWorld.warning.lowDiskSpace.title").withStyle(ChatFormatting.RED),
Component.translatable("selectWorld.warning.lowDiskSpace.description"),
CommonComponents.GUI_CONTINUE,
CommonComponents.GUI_BACK
)
);
} else {
this.openWorldDoLoad(worldAccess, worldStem, packRepository);
}
}
private void openWorldDoLoad(LevelStorageSource.LevelStorageAccess worldAccess, WorldStem worldStem, PackRepository packRepository) {
this.minecraft.doWorldLoad(worldAccess, packRepository, worldStem, Optional.empty(), false);
}
private CompletableFuture<Void> loadBundledResourcePack(DownloadedPackSource packSource, LevelStorageSource.LevelStorageAccess levelSourceAccess) {
Path mapResourceFile = levelSourceAccess.getLevelPath(LevelResource.MAP_RESOURCE_FILE);
if (Files.exists(mapResourceFile) && !Files.isDirectory(mapResourceFile)) {
packSource.configureForLocalWorld();
CompletableFuture<Void> result = packSource.waitForPackFeedback(WORLD_PACK_ID);
packSource.pushLocalPack(WORLD_PACK_ID, mapResourceFile);
return result;
} else {
return CompletableFuture.completedFuture(null);
}
}
private CompletableFuture<Boolean> promptBundledPackLoadFailure() {
CompletableFuture<Boolean> result = new CompletableFuture<>();
this.minecraft
.setScreen(
new ConfirmScreen(
result::complete,
Component.translatable("multiplayer.texturePrompt.failure.line1"),
Component.translatable("multiplayer.texturePrompt.failure.line2"),
CommonComponents.GUI_PROCEED,
CommonComponents.GUI_CANCEL
)
);
return result;
}
}引用的其他类
-
- 引用位置:
方法调用 - 关联成员:
CrashReport.forThrowable()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
ReportedException()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
SharedConstants.getCurrentVersion()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
SystemToast.onWorldAccessFailure()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
AlertScreen()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
BackupConfirmScreen()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
ConfirmScreen()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
DatapackLoadFailureScreen()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
FileFixerAbortedScreen()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
GenericMessageScreen()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
NoticeWithLinkScreen.createWorldSymlinkWarningScreen()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
RecoverWorldDataScreen()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
EditWorldScreen.conditionallyMakeBackupAndShowToast()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
FileFixerProgressScreen()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
InitialWorldCreationOptions()
- 引用位置:
-
- 引用位置:
构造调用/返回值 - 关联成员:
WorldCreationContext()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
NbtUtils.getDataVersion()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Component.literal(), Component.translatable()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/方法调用/构造调用 - 关联成员:
InitConfig(), PackConfig(), WorldLoader.InitConfig(), WorldLoader.PackConfig(), WorldLoader.load()
- 引用位置:
-
- 引用位置:
参数/构造调用/返回值 - 关联成员:
WorldStem()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ServerPacksSource.createPackRepository()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
MemoryReserve.release()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Util.backgroundExecutor(), Util.getMillis()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
DataFixers.getDataFixer(), DataFixers.getFileFixer()
- 引用位置:
-
- 引用位置:
参数/构造调用 - 关联成员:
UpgradeProgress()
- 引用位置:
-
- 引用位置:
参数/返回值
- 引用位置:
-
- 引用位置:
参数/返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
GameRuleMap.of()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/构造调用 - 关联成员:
WorldDimensions()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
WorldGenSettings()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/方法调用/构造调用 - 关联成员:
LevelDataAndDimensions.WorldDataAndGenSettings(), WorldDataAndGenSettings()
- 引用位置:
-
- 引用位置:
参数/字段/方法调用/返回值 - 关联成员:
LevelStorageSource.getLevelDataAndDimensions(), LevelStorageSource.getPackConfig(), LevelStorageSource.readExistingSavedData()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
PrimaryLevelData()
- 引用位置: