WorldUpgrader.java

net.minecraft.util.worldupdate.WorldUpgrader

信息

  • 全限定名:net.minecraft.util.worldupdate.WorldUpgrader
  • 类型:public class
  • 包:net.minecraft.util.worldupdate
  • 源码路径:src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
  • 起始行号:L32
  • 实现:AutoCloseable
  • 职责:

    TODO

字段/常量

  • LOGGER

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

      TODO

  • THREAD_FACTORY

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

      TODO

  • statusTranslator

    • 类型: UpgradeStatusTranslator
    • 修饰符: private final
    • 源码定位: L35
    • 说明:

      TODO

  • dimensions

    • 类型: Registry<LevelStem>
    • 修饰符: private final
    • 源码定位: L36
    • 说明:

      TODO

  • levels

    • 类型: Set<ResourceKey<Level>>
    • 修饰符: private final
    • 源码定位: L37
    • 说明:

      TODO

  • eraseCache

    • 类型: boolean
    • 修饰符: private final
    • 源码定位: L38
    • 说明:

      TODO

  • recreateRegionFiles

    • 类型: boolean
    • 修饰符: private final
    • 源码定位: L39
    • 说明:

      TODO

  • levelStorage

    • 类型: LevelStorageSource.LevelStorageAccess
    • 修饰符: private final
    • 源码定位: L40
    • 说明:

      TODO

  • thread

    • 类型: Thread
    • 修饰符: private final
    • 源码定位: L41
    • 说明:

      TODO

  • dataFixer

    • 类型: DataFixer
    • 修饰符: private final
    • 源码定位: L42
    • 说明:

      TODO

  • upgradeProgress

    • 类型: UpgradeProgress
    • 修饰符: private final
    • 源码定位: L43
    • 说明:

      TODO

  • overworldSavedDataStorage

    • 类型: SavedDataStorage
    • 修饰符: private final
    • 源码定位: L44
    • 说明:

      TODO

内部类/嵌套类型

构造器

public WorldUpgrader(LevelStorageSource.LevelStorageAccess levelSource, DataFixer dataFixer, RegistryAccess registryAccess, boolean eraseCache, boolean recreateRegionFiles) @ L46

  • 构造器名:WorldUpgrader
  • 源码定位:L46
  • 修饰符:public

参数:

  • levelSource: LevelStorageSource.LevelStorageAccess
  • dataFixer: DataFixer
  • registryAccess: RegistryAccess
  • eraseCache: boolean
  • recreateRegionFiles: boolean

说明:

TODO

方法

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

public static CompoundTag getDataFixContextTag(Registry<LevelStem> dimensions, ResourceKey<Level> dimension) @ L65

  • 方法名:getDataFixContextTag
  • 源码定位:L65
  • 返回类型:CompoundTag
  • 修饰符:public static

参数:

  • dimensions: Registry
  • dimension: ResourceKey

说明:

TODO

public static boolean verifyChunkPosAndEraseCache(ChunkPos pos, CompoundTag upgradedTag) @ L70

  • 方法名:verifyChunkPosAndEraseCache
  • 源码定位:L70
  • 返回类型:boolean
  • 修饰符:public static

参数:

  • pos: ChunkPos
  • upgradedTag: CompoundTag

说明:

TODO

public static boolean verifyChunkPos(ChunkPos pos, CompoundTag upgradedTag) @ L92

  • 方法名:verifyChunkPos
  • 源码定位:L92
  • 返回类型:boolean
  • 修饰符:public static

参数:

  • pos: ChunkPos
  • upgradedTag: CompoundTag

说明:

TODO

public void cancel() @ L101

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

参数:

说明:

TODO

private void work() @ L110

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

参数:

说明:

TODO

private void upgradeLevels(DataFixTypes dataFixType, RegionStorageUpgrader.Builder builder) @ L147

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

参数:

  • dataFixType: DataFixTypes
  • builder: RegionStorageUpgrader.Builder

说明:

TODO

private void upgradeLevels(DataFixTypes dataFixType, RegionStorageUpgrader.Builder builder, BiFunction<RegionStorageUpgrader.Builder,ResourceKey<Level>,RegionStorageUpgrader.Builder> levelSpecificBuilder) @ L151

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

参数:

  • dataFixType: DataFixTypes
  • builder: RegionStorageUpgrader.Builder
  • levelSpecificBuilder: BiFunction<RegionStorageUpgrader.Builder,ResourceKey,RegionStorageUpgrader.Builder>

说明:

TODO

public boolean isFinished() @ L172

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

参数:

说明:

TODO

public Set<ResourceKey<Level>> levels() @ L176

  • 方法名:levels
  • 源码定位:L176
  • 返回类型:Set<ResourceKey>
  • 修饰符:public

参数:

说明:

TODO

public float dimensionProgress(ResourceKey<Level> dimension) @ L180

  • 方法名:dimensionProgress
  • 源码定位:L180
  • 返回类型:float
  • 修饰符:public

参数:

  • dimension: ResourceKey

说明:

TODO

public float getTotalProgress() @ L184

  • 方法名:getTotalProgress
  • 源码定位:L184
  • 返回类型:float
  • 修饰符:public

参数:

说明:

TODO

public int getTotalChunks() @ L188

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

参数:

说明:

TODO

public int getConverted() @ L192

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

参数:

说明:

TODO

public int getSkipped() @ L196

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

参数:

说明:

TODO

public Component getStatus() @ L200

  • 方法名:getStatus
  • 源码定位:L200
  • 返回类型:Component
  • 修饰符:public

参数:

说明:

TODO

public void close() @ L204

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

参数:

说明:

TODO

代码

public class WorldUpgrader implements AutoCloseable {
    private static final Logger LOGGER = LogUtils.getLogger();
    private static final ThreadFactory THREAD_FACTORY = new ThreadFactoryBuilder().setDaemon(true).build();
    private final UpgradeStatusTranslator statusTranslator = new UpgradeStatusTranslator();
    private final Registry<LevelStem> dimensions;
    private final Set<ResourceKey<Level>> levels;
    private final boolean eraseCache;
    private final boolean recreateRegionFiles;
    private final LevelStorageSource.LevelStorageAccess levelStorage;
    private final Thread thread;
    private final DataFixer dataFixer;
    private final UpgradeProgress upgradeProgress = new UpgradeProgress();
    private final SavedDataStorage overworldSavedDataStorage;
 
    public WorldUpgrader(
        LevelStorageSource.LevelStorageAccess levelSource, DataFixer dataFixer, RegistryAccess registryAccess, boolean eraseCache, boolean recreateRegionFiles
    ) {
        this.dimensions = registryAccess.lookupOrThrow(Registries.LEVEL_STEM);
        this.levels = this.dimensions.registryKeySet().stream().map(Registries::levelStemToLevel).collect(Collectors.toUnmodifiableSet());
        this.eraseCache = eraseCache;
        this.dataFixer = dataFixer;
        this.levelStorage = levelSource;
        this.overworldSavedDataStorage = new SavedDataStorage(this.levelStorage.getDimensionPath(Level.OVERWORLD).resolve("data"), dataFixer, registryAccess);
        this.recreateRegionFiles = recreateRegionFiles;
        this.thread = THREAD_FACTORY.newThread(this::work);
        this.thread.setUncaughtExceptionHandler((t, e) -> {
            LOGGER.error("Error upgrading world", e);
            this.upgradeProgress.setStatus(UpgradeProgress.Status.FAILED);
            this.upgradeProgress.setFinished(true);
        });
        this.thread.start();
    }
 
    public static CompoundTag getDataFixContextTag(Registry<LevelStem> dimensions, ResourceKey<Level> dimension) {
        ChunkGenerator generator = dimensions.getValueOrThrow(Registries.levelToLevelStem(dimension)).generator();
        return ChunkMap.getChunkDataFixContextTag(dimension, generator.getTypeNameForDataFixer());
    }
 
    public static boolean verifyChunkPosAndEraseCache(ChunkPos pos, CompoundTag upgradedTag) {
        verifyChunkPos(pos, upgradedTag);
        boolean changed = upgradedTag.contains("Heightmaps");
        upgradedTag.remove("Heightmaps");
        changed = changed || upgradedTag.contains("isLightOn");
        upgradedTag.remove("isLightOn");
        ListTag sections = upgradedTag.getListOrEmpty("sections");
 
        for (int i = 0; i < sections.size(); i++) {
            Optional<CompoundTag> maybeSection = sections.getCompound(i);
            if (!maybeSection.isEmpty()) {
                CompoundTag section = maybeSection.get();
                changed = changed || section.contains("BlockLight");
                section.remove("BlockLight");
                changed = changed || section.contains("SkyLight");
                section.remove("SkyLight");
            }
        }
 
        return changed;
    }
 
    public static boolean verifyChunkPos(ChunkPos pos, CompoundTag upgradedTag) {
        ChunkPos storedPos = new ChunkPos(upgradedTag.getIntOr("xPos", 0), upgradedTag.getIntOr("zPos", 0));
        if (!storedPos.equals(pos)) {
            LOGGER.warn("Chunk {} has invalid position {}", pos, storedPos);
        }
 
        return false;
    }
 
    public void cancel() {
        this.upgradeProgress.setCanceled();
 
        try {
            this.thread.join();
        } catch (InterruptedException var2) {
        }
    }
 
    private void work() {
        long conversionTime = Util.getMillis();
        int currentVersion = SharedConstants.getCurrentVersion().dataVersion().version();
        LOGGER.info("Upgrading entities");
        this.upgradeLevels(
            DataFixTypes.ENTITY_CHUNK,
            new RegionStorageUpgrader.Builder(this.dataFixer)
                .setTypeAndFolderName("entities")
                .setRecreateRegionFiles(this.recreateRegionFiles)
                .trackProgress(this.upgradeProgress)
        );
        LOGGER.info("Upgrading POIs");
        this.upgradeLevels(
            DataFixTypes.POI_CHUNK,
            new RegionStorageUpgrader.Builder(this.dataFixer)
                .setTypeAndFolderName("poi")
                .setDefaultVersion(1945)
                .setRecreateRegionFiles(this.recreateRegionFiles)
                .trackProgress(this.upgradeProgress)
        );
        LOGGER.info("Upgrading blocks");
        this.upgradeLevels(
            DataFixTypes.CHUNK,
            new RegionStorageUpgrader.Builder(this.dataFixer)
                .setType("chunk")
                .setFolderName("region")
                .setRecreateRegionFiles(this.recreateRegionFiles)
                .trackProgress(this.upgradeProgress),
            (levelSpecificBuilder, level) -> levelSpecificBuilder.setDataFixContextTag(getDataFixContextTag(this.dimensions, level))
                .addTagModifier(currentVersion, this.eraseCache ? WorldUpgrader::verifyChunkPosAndEraseCache : WorldUpgrader::verifyChunkPos)
        );
        this.overworldSavedDataStorage.saveAndJoin();
        conversionTime = Util.getMillis() - conversionTime;
        LOGGER.info("World optimization finished after {} seconds", conversionTime / 1000L);
        this.upgradeProgress.setFinished(true);
    }
 
    private void upgradeLevels(DataFixTypes dataFixType, RegionStorageUpgrader.Builder builder) {
        this.upgradeLevels(dataFixType, builder, (levelSpecificBuilder, level) -> levelSpecificBuilder);
    }
 
    private void upgradeLevels(
        DataFixTypes dataFixType,
        RegionStorageUpgrader.Builder builder,
        BiFunction<RegionStorageUpgrader.Builder, ResourceKey<Level>, RegionStorageUpgrader.Builder> levelSpecificBuilder
    ) {
        List<RegionStorageUpgrader> upgraders = new ArrayList<>();
        this.upgradeProgress.reset(dataFixType);
        this.upgradeProgress.setType(UpgradeProgress.Type.REGIONS);
        builder.setDataFixType(dataFixType);
        int previousCopiesFileAmounts = 0;
 
        for (ResourceKey<Level> level : this.levels) {
            RegionStorageUpgrader upgrader = levelSpecificBuilder.apply(builder.copy(), level).build(previousCopiesFileAmounts);
            upgrader.init(level, this.levelStorage);
            previousCopiesFileAmounts += upgrader.fileAmount();
            upgraders.add(upgrader);
        }
 
        upgraders.forEach(RegionStorageUpgrader::upgrade);
    }
 
    public boolean isFinished() {
        return this.upgradeProgress.isFinished();
    }
 
    public Set<ResourceKey<Level>> levels() {
        return this.levels;
    }
 
    public float dimensionProgress(ResourceKey<Level> dimension) {
        return this.upgradeProgress.getDimensionProgress(dimension);
    }
 
    public float getTotalProgress() {
        return this.upgradeProgress.getTotalProgress();
    }
 
    public int getTotalChunks() {
        return this.upgradeProgress.getTotalChunks();
    }
 
    public int getConverted() {
        return this.upgradeProgress.getConverted();
    }
 
    public int getSkipped() {
        return this.upgradeProgress.getSkipped();
    }
 
    public Component getStatus() {
        return this.statusTranslator.translate(this.upgradeProgress);
    }
 
    @Override
    public void close() {
        this.overworldSavedDataStorage.close();
    }
}

引用的其他类

  • SharedConstants

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

    • 引用位置: 参数/字段
  • RegistryAccess

    • 引用位置: 参数
  • Registries

    • 引用位置: 方法调用
    • 关联成员: Registries.levelToLevelStem()
  • CompoundTag

    • 引用位置: 参数/返回值
  • Component

    • 引用位置: 返回值
  • ResourceKey

    • 引用位置: 参数/字段/返回值
  • ChunkMap

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

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

    • 引用位置: 参数
  • RegionStorageUpgrader

    • 引用位置: 参数/方法调用/构造调用
    • 关联成员: Builder(), RegionStorageUpgrader.Builder()
  • UpgradeProgress

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

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

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

    • 引用位置: 参数/字段/返回值
  • LevelStem

    • 引用位置: 参数/字段
  • LevelStorageSource

    • 引用位置: 参数/字段
  • SavedDataStorage

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