RegionStorageUpgrader.java
net.minecraft.util.worldupdate.RegionStorageUpgrader
信息
- 全限定名:net.minecraft.util.worldupdate.RegionStorageUpgrader
- 类型:public class
- 包:net.minecraft.util.worldupdate
- 源码路径:src/main/java/net/minecraft/util/worldupdate/RegionStorageUpgrader.java
- 起始行号:L36
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L37 - 说明:
TODO
- 类型:
-
NEW_DIRECTORY_PREFIX- 类型:
String - 修饰符:
private static final - 源码定位:
L38 - 说明:
TODO
- 类型:
-
REGEX- 类型:
Pattern - 修饰符:
private static final - 源码定位:
L39 - 说明:
TODO
- 类型:
-
dataFixer- 类型:
DataFixer - 修饰符:
private final - 源码定位:
L40 - 说明:
TODO
- 类型:
-
upgradeProgress- 类型:
UpgradeProgress - 修饰符:
private final - 源码定位:
L41 - 说明:
TODO
- 类型:
-
type- 类型:
String - 修饰符:
private final - 源码定位:
L42 - 说明:
TODO
- 类型:
-
folderName- 类型:
String - 修饰符:
private final - 源码定位:
L43 - 说明:
TODO
- 类型:
-
previousWriteFuture- 类型:
CompletableFuture<Void> - 修饰符:
protected - 源码定位:
L44 - 说明:
TODO
- 类型:
-
dataFixType- 类型:
DataFixTypes - 修饰符:
protected final - 源码定位:
L45 - 说明:
TODO
- 类型:
-
defaultVersion- 类型:
int - 修饰符:
protected final - 源码定位:
L46 - 说明:
TODO
- 类型:
-
recreateRegionFiles- 类型:
boolean - 修饰符:
private final - 源码定位:
L47 - 说明:
TODO
- 类型:
-
dimensionKey- 类型:
ResourceKey<Level> - 修饰符:
private - 源码定位:
L48 - 说明:
TODO
- 类型:
-
storage- 类型:
SimpleRegionStorage - 修饰符:
private - 源码定位:
L49 - 说明:
TODO
- 类型:
-
files- 类型:
List<FileToUpgrade> - 修饰符:
private - 源码定位:
L50 - 说明:
TODO
- 类型:
-
startIndex- 类型:
int - 修饰符:
private final - 源码定位:
L51 - 说明:
TODO
- 类型:
-
dataFixContextTag- 类型:
CompoundTag - 修饰符:
private final - 源码定位:
L52 - 说明:
TODO
- 类型:
-
tagModifiers- 类型:
Int2ObjectMap<RegionStorageUpgrader.TagModifier> - 修饰符:
private final - 源码定位:
L53 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.util.worldupdate.RegionStorageUpgrader.Builder- 类型:
class - 修饰符:
public static - 源码定位:
L281 - 说明:
TODO
- 类型:
-
net.minecraft.util.worldupdate.RegionStorageUpgrader.TagModifier- 类型:
interface - 修饰符:
public - 源码定位:
L378 - 说明:
TODO
- 类型:
构造器
protected RegionStorageUpgrader(DataFixer dataFixer, DataFixTypes dataFixType, String type, String folderName, int defaultVersion, boolean recreateRegionFiles, UpgradeProgress upgradeProgress, int startIndex, CompoundTag dataFixContextTag, Int2ObjectMap<RegionStorageUpgrader.TagModifier> tagModifiers) @ L55
- 构造器名:RegionStorageUpgrader
- 源码定位:L55
- 修饰符:protected
参数:
- dataFixer: DataFixer
- dataFixType: DataFixTypes
- type: String
- folderName: String
- defaultVersion: int
- recreateRegionFiles: boolean
- upgradeProgress: UpgradeProgress
- startIndex: int
- dataFixContextTag: CompoundTag
- tagModifiers: Int2ObjectMap<RegionStorageUpgrader.TagModifier>
说明:
TODO
方法
下面的方法块按源码顺序生成。
public void init(ResourceKey<Level> dimensionKey, LevelStorageSource.LevelStorageAccess levelStorage) @ L79
- 方法名:init
- 源码定位:L79
- 返回类型:void
- 修饰符:public
参数:
- dimensionKey: ResourceKey
- levelStorage: LevelStorageSource.LevelStorageAccess
说明:
TODO
public void upgrade() @ L87
- 方法名:upgrade
- 源码定位:L87
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
protected final SimpleRegionStorage createStorage(RegionStorageInfo info, Path regionFolder) @ L137
- 方法名:createStorage
- 源码定位:L137
- 返回类型:SimpleRegionStorage
- 修饰符:protected final
参数:
- info: RegionStorageInfo
- regionFolder: Path
说明:
TODO
private List<FileToUpgrade> getFilesToProcess(RegionStorageInfo info, Path regionFolder) @ L151
- 方法名:getFilesToProcess
- 源码定位:L151
- 返回类型:List
- 修饰符:private
参数:
- info: RegionStorageInfo
- regionFolder: Path
说明:
TODO
public int fileAmount() @ L158
- 方法名:fileAmount
- 源码定位:L158
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
private static List<FileToUpgrade> getAllChunkPositions(RegionStorageInfo info, Path regionFolder) @ L162
- 方法名:getAllChunkPositions
- 源码定位:L162
- 返回类型:List
- 修饰符:private static
参数:
- info: RegionStorageInfo
- regionFolder: Path
说明:
TODO
private boolean processOnePosition(SimpleRegionStorage storage, ChunkPos pos) @ L199
- 方法名:processOnePosition
- 源码定位:L199
- 返回类型:boolean
- 修饰符:private
参数:
- storage: SimpleRegionStorage
- pos: ChunkPos
说明:
TODO
protected boolean tryProcessOnePosition(SimpleRegionStorage storage, ChunkPos pos) @ L222
- 方法名:tryProcessOnePosition
- 源码定位:L222
- 返回类型:boolean
- 修饰符:protected
参数:
- storage: SimpleRegionStorage
- pos: ChunkPos
说明:
TODO
protected CompoundTag upgradeTag(SimpleRegionStorage storage, CompoundTag chunkTag, int targetVersion) @ L250
- 方法名:upgradeTag
- 源码定位:L250
- 返回类型:CompoundTag
- 修饰符:protected
参数:
- storage: SimpleRegionStorage
- chunkTag: CompoundTag
- targetVersion: int
说明:
TODO
private void onFileFinished(RegionFile regionFile) @ L254
- 方法名:onFileFinished
- 源码定位:L254
- 返回类型:void
- 修饰符:private
参数:
- regionFile: RegionFile
说明:
TODO
protected static Path resolveRecreateDirectory(Path directoryPath) @ L277
- 方法名:resolveRecreateDirectory
- 源码定位:L277
- 返回类型:Path
- 修饰符:protected static
参数:
- directoryPath: Path
说明:
TODO
代码
public class RegionStorageUpgrader {
private static final Logger LOGGER = LogUtils.getLogger();
private static final String NEW_DIRECTORY_PREFIX = "new_";
private static final Pattern REGEX = Pattern.compile("^r\\.(-?[0-9]+)\\.(-?[0-9]+)\\.mca$");
private final DataFixer dataFixer;
private final UpgradeProgress upgradeProgress;
private final String type;
private final String folderName;
protected @Nullable CompletableFuture<Void> previousWriteFuture;
protected final DataFixTypes dataFixType;
protected final int defaultVersion;
private final boolean recreateRegionFiles;
private @Nullable ResourceKey<Level> dimensionKey;
private @Nullable SimpleRegionStorage storage;
private @Nullable List<FileToUpgrade> files;
private final int startIndex;
private final @Nullable CompoundTag dataFixContextTag;
private final Int2ObjectMap<RegionStorageUpgrader.TagModifier> tagModifiers;
protected RegionStorageUpgrader(
DataFixer dataFixer,
DataFixTypes dataFixType,
String type,
String folderName,
int defaultVersion,
boolean recreateRegionFiles,
UpgradeProgress upgradeProgress,
int startIndex,
@Nullable CompoundTag dataFixContextTag,
Int2ObjectMap<RegionStorageUpgrader.TagModifier> tagModifiers
) {
this.dataFixer = dataFixer;
this.dataFixType = dataFixType;
this.type = type;
this.folderName = folderName;
this.recreateRegionFiles = recreateRegionFiles;
this.defaultVersion = defaultVersion;
this.upgradeProgress = upgradeProgress;
this.startIndex = startIndex;
this.dataFixContextTag = dataFixContextTag;
this.tagModifiers = tagModifiers;
}
public void init(ResourceKey<Level> dimensionKey, LevelStorageSource.LevelStorageAccess levelStorage) {
RegionStorageInfo info = new RegionStorageInfo(levelStorage.getLevelId(), dimensionKey, this.type);
Path regionFolder = levelStorage.getDimensionPath(dimensionKey).resolve(this.folderName);
this.dimensionKey = dimensionKey;
this.storage = this.createStorage(info, regionFolder);
this.files = this.getFilesToProcess(info, regionFolder);
}
public void upgrade() {
if (this.dimensionKey == null || this.storage == null || this.files == null) {
throw new IllegalStateException("RegionStorageUpgrader has not been initialized");
} else if (!this.files.isEmpty()) {
float totalSize = this.upgradeProgress.getTotalFileFixStats().totalOperations();
this.upgradeProgress.setStatus(UpgradeProgress.Status.UPGRADING);
ListIterator<FileToUpgrade> iterator = this.files.listIterator();
while (!this.upgradeProgress.isCanceled()) {
boolean worked = false;
float totalProgress = 0.0F;
if (iterator.hasNext()) {
FileToUpgrade fileToUpgrade = iterator.next();
boolean converted = true;
for (ChunkPos chunkPos : fileToUpgrade.chunksToUpgrade()) {
converted = converted && this.processOnePosition(this.storage, chunkPos);
worked = true;
}
if (this.recreateRegionFiles) {
if (converted) {
this.onFileFinished(fileToUpgrade.file());
} else {
LOGGER.error("Failed to convert region file {}", fileToUpgrade.file().getPath());
}
}
}
int nextIndex = iterator.nextIndex();
float currentDimensionProgress = nextIndex / totalSize;
float currentTotalProgress = (this.startIndex + nextIndex) / totalSize;
this.upgradeProgress.setDimensionProgress(this.dimensionKey, currentDimensionProgress);
totalProgress += currentTotalProgress;
this.upgradeProgress.setTotalProgress(totalProgress);
if (!worked) {
break;
}
}
this.upgradeProgress.setStatus(UpgradeProgress.Status.FINISHED);
try {
this.storage.close();
} catch (Exception var9) {
LOGGER.error("Error upgrading chunk", (Throwable)var9);
}
}
}
protected final SimpleRegionStorage createStorage(RegionStorageInfo info, Path regionFolder) {
return (SimpleRegionStorage)(this.recreateRegionFiles
? new RecreatingSimpleRegionStorage(
info.withTypeSuffix("source"),
regionFolder,
info.withTypeSuffix("target"),
resolveRecreateDirectory(regionFolder),
this.dataFixer,
true,
this.dataFixType
)
: new SimpleRegionStorage(info, regionFolder, this.dataFixer, true, this.dataFixType));
}
private List<FileToUpgrade> getFilesToProcess(RegionStorageInfo info, Path regionFolder) {
List<FileToUpgrade> filesToUpgrade = getAllChunkPositions(info, regionFolder);
this.upgradeProgress.addTotalFileFixOperations(filesToUpgrade.size());
this.upgradeProgress.addTotalChunks(filesToUpgrade.stream().mapToInt(fileToUpgrade -> fileToUpgrade.chunksToUpgrade().size()).sum());
return filesToUpgrade;
}
public int fileAmount() {
return this.files == null ? 0 : this.files.size();
}
private static List<FileToUpgrade> getAllChunkPositions(RegionStorageInfo info, Path regionFolder) {
File[] files = regionFolder.toFile().listFiles((dir, name) -> name.endsWith(".mca"));
if (files == null) {
return List.of();
} else {
List<FileToUpgrade> regionFileChunks = Lists.newArrayList();
for (File regionFile : files) {
Matcher regex = REGEX.matcher(regionFile.getName());
if (regex.matches()) {
int xOffset = Integer.parseInt(regex.group(1)) << 5;
int zOffset = Integer.parseInt(regex.group(2)) << 5;
List<ChunkPos> chunkPositions = Lists.newArrayList();
try (RegionFile regionSource = new RegionFile(info, regionFile.toPath(), regionFolder, true)) {
for (int x = 0; x < 32; x++) {
for (int z = 0; z < 32; z++) {
ChunkPos pos = new ChunkPos(x + xOffset, z + zOffset);
if (regionSource.doesChunkExist(pos)) {
chunkPositions.add(pos);
}
}
}
if (!chunkPositions.isEmpty()) {
regionFileChunks.add(new FileToUpgrade(regionSource, chunkPositions));
}
} catch (Throwable var18) {
LOGGER.error("Failed to read chunks from region file {}", regionFile.toPath(), var18);
}
}
}
return regionFileChunks;
}
}
private boolean processOnePosition(SimpleRegionStorage storage, ChunkPos pos) {
boolean converted = false;
try {
converted = this.tryProcessOnePosition(storage, pos);
} catch (CompletionException | ReportedException var6) {
Throwable cause = var6.getCause();
if (!(cause instanceof IOException)) {
throw var6;
}
LOGGER.error("Error upgrading chunk {}", pos, cause);
}
if (converted) {
this.upgradeProgress.incrementConverted();
} else {
this.upgradeProgress.incrementSkipped();
}
return converted;
}
protected boolean tryProcessOnePosition(SimpleRegionStorage storage, ChunkPos pos) {
CompoundTag chunkTag = storage.read(pos).join().orElse(null);
if (chunkTag != null) {
int version = NbtUtils.getDataVersion(chunkTag);
int latestVersion = SharedConstants.getCurrentVersion().dataVersion().version();
boolean changed = false;
for (Entry<RegionStorageUpgrader.TagModifier> tagFixer : this.tagModifiers.int2ObjectEntrySet()) {
int neededVersion = tagFixer.getIntKey();
chunkTag = this.upgradeTag(storage, chunkTag, neededVersion);
changed |= tagFixer.getValue().modifyTagAfterFix(pos, chunkTag);
}
CompoundTag upgradedTag = this.upgradeTag(storage, chunkTag, latestVersion);
changed |= version < latestVersion;
if (changed || this.recreateRegionFiles) {
if (this.previousWriteFuture != null) {
this.previousWriteFuture.join();
}
this.previousWriteFuture = storage.write(pos, upgradedTag);
return true;
}
}
return false;
}
protected CompoundTag upgradeTag(SimpleRegionStorage storage, CompoundTag chunkTag, int targetVersion) {
return storage.upgradeChunkTag(chunkTag, this.defaultVersion, this.dataFixContextTag, targetVersion);
}
private void onFileFinished(RegionFile regionFile) {
if (this.recreateRegionFiles) {
if (this.previousWriteFuture != null) {
this.previousWriteFuture.join();
}
Path filePath = regionFile.getPath();
Path directoryPath = filePath.getParent();
Path newFilePath = resolveRecreateDirectory(directoryPath).resolve(filePath.getFileName().toString());
try {
if (newFilePath.toFile().exists()) {
Files.delete(filePath);
Files.move(newFilePath, filePath);
} else {
LOGGER.error("Failed to replace an old region file. New file {} does not exist.", newFilePath);
}
} catch (IOException var6) {
LOGGER.error("Failed to replace an old region file", (Throwable)var6);
}
}
}
protected static Path resolveRecreateDirectory(Path directoryPath) {
return directoryPath.resolveSibling("new_" + directoryPath.getFileName().toString());
}
public static class Builder {
private final DataFixer dataFixer;
private @Nullable DataFixTypes dataFixType;
private @Nullable String type;
private @Nullable String folderName;
private int defaultVersion = -1;
private boolean recreateRegionFiles;
private UpgradeProgress upgradeProgress = new UpgradeProgress.Noop();
private @Nullable CompoundTag dataFixContextTag;
private Int2ObjectAVLTreeMap<RegionStorageUpgrader.TagModifier> tagModifiers = new Int2ObjectAVLTreeMap<>();
public Builder(DataFixer dataFixer) {
this.dataFixer = dataFixer;
}
public RegionStorageUpgrader.Builder setDataFixType(DataFixTypes dataFixType) {
this.dataFixType = dataFixType;
return this;
}
public RegionStorageUpgrader.Builder setTypeAndFolderName(String name) {
return this.setType(name).setFolderName(name);
}
public RegionStorageUpgrader.Builder setType(String type) {
this.type = type;
return this;
}
public RegionStorageUpgrader.Builder setFolderName(String folderName) {
this.folderName = folderName;
return this;
}
public RegionStorageUpgrader.Builder setDefaultVersion(int defaultVersion) {
this.defaultVersion = defaultVersion;
return this;
}
public RegionStorageUpgrader.Builder setRecreateRegionFiles(boolean recreateRegionFiles) {
this.recreateRegionFiles = recreateRegionFiles;
return this;
}
public RegionStorageUpgrader.Builder trackProgress(UpgradeProgress upgradeProgress) {
this.upgradeProgress = upgradeProgress;
return this;
}
public RegionStorageUpgrader.Builder setDataFixContextTag(@Nullable CompoundTag dataFixContextTag) {
this.dataFixContextTag = dataFixContextTag;
return this;
}
public RegionStorageUpgrader.Builder addTagModifier(int version, RegionStorageUpgrader.TagModifier tagModifier) {
if (this.tagModifiers.containsKey(version)) {
throw new IllegalStateException("Can't add two fixers for the same data version");
} else {
this.tagModifiers.put(version, tagModifier);
return this;
}
}
private RegionStorageUpgrader.Builder setTagModifiers(Int2ObjectAVLTreeMap<RegionStorageUpgrader.TagModifier> tagModifiers) {
this.tagModifiers = tagModifiers;
return this;
}
public RegionStorageUpgrader.Builder copy() {
return new RegionStorageUpgrader.Builder(this.dataFixer)
.setDataFixType(this.dataFixType)
.setType(this.type)
.setFolderName(this.folderName)
.setDefaultVersion(this.defaultVersion)
.setRecreateRegionFiles(this.recreateRegionFiles)
.trackProgress(this.upgradeProgress)
.setDataFixContextTag(this.dataFixContextTag)
.setTagModifiers(this.tagModifiers.clone());
}
public RegionStorageUpgrader build(int previousCopiesFileAmounts) {
return new RegionStorageUpgrader(
this.dataFixer,
Objects.requireNonNull(this.dataFixType),
Objects.requireNonNull(this.type),
Objects.requireNonNull(this.folderName),
this.defaultVersion,
this.recreateRegionFiles,
this.upgradeProgress,
previousCopiesFileAmounts,
this.dataFixContextTag,
this.tagModifiers
);
}
}
@FunctionalInterface
public interface TagModifier {
boolean modifyTagAfterFix(final ChunkPos pos, final CompoundTag upgradedTag);
}
}引用的其他类
-
- 引用位置:
方法调用 - 关联成员:
SharedConstants.getCurrentVersion()
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
NbtUtils.getDataVersion()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
FileToUpgrade()
- 引用位置:
-
- 引用位置:
参数/字段/方法调用/构造调用 - 关联成员:
Noop(), UpgradeProgress.Noop()
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
Pattern.compile()
- 引用位置:
-
- 引用位置:
参数/构造调用 - 关联成员:
ChunkPos()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
RecreatingSimpleRegionStorage()
- 引用位置:
-
- 引用位置:
参数/构造调用 - 关联成员:
RegionFile()
- 引用位置:
-
- 引用位置:
参数/构造调用 - 关联成员:
RegionStorageInfo()
- 引用位置:
-
- 引用位置:
参数/字段/构造调用/返回值 - 关联成员:
SimpleRegionStorage()
- 引用位置:
-
- 引用位置:
参数
- 引用位置: