LegacyStructureFileFix.java
net.minecraft.util.filefix.fixes.LegacyStructureFileFix
信息
- 全限定名:net.minecraft.util.filefix.fixes.LegacyStructureFileFix
- 类型:public class
- 包:net.minecraft.util.filefix.fixes
- 源码路径:src/main/java/net/minecraft/util/filefix/fixes/LegacyStructureFileFix.java
- 起始行号:L44
- 继承:FileFix
- 职责:
TODO
字段/常量
-
STRUCTURE_RANGE- 类型:
int - 修饰符:
public static final - 源码定位:
L45 - 说明:
TODO
- 类型:
-
OVERWORLD_LEGACY_STRUCTURES- 类型:
List<String> - 修饰符:
public static final - 源码定位:
L46 - 说明:
TODO
- 类型:
-
LEGACY_TO_CURRENT_MAP- 类型:
Map<String,String> - 修饰符:
public static final - 源码定位:
L47 - 说明:
TODO
- 类型:
-
NETHER_LEGACY_STRUCTURES- 类型:
List<String> - 修饰符:
public static final - 源码定位:
L53 - 说明:
TODO
- 类型:
-
END_LEGACY_STRUCTURES- 类型:
List<String> - 修饰符:
public static final - 源码定位:
L54 - 说明:
TODO
- 类型:
-
OVERWORLD_KEY- 类型:
ResourceKey<Level> - 修饰符:
private static final - 源码定位:
L55 - 说明:
TODO
- 类型:
-
NETHER_KEY- 类型:
ResourceKey<Level> - 修饰符:
private static final - 源码定位:
L56 - 说明:
TODO
- 类型:
-
END_KEY- 类型:
ResourceKey<Level> - 修饰符:
private static final - 源码定位:
L57 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.util.filefix.fixes.LegacyStructureFileFix.DimensionFixEntry- 类型:
record - 修饰符:
private - 源码定位:
L229 - 说明:
TODO
- 类型:
-
net.minecraft.util.filefix.fixes.LegacyStructureFileFix.LegacyStructureData- 类型:
record - 修饰符:
public - 源码定位:
L237 - 说明:
TODO
- 类型:
构造器
public LegacyStructureFileFix(Schema schema) @ L59
- 构造器名:LegacyStructureFileFix
- 源码定位:L59
- 修饰符:public
参数:
- schema: Schema
说明:
TODO
方法
下面的方法块按源码顺序生成。
public void makeFixer() @ L63
- 方法名:makeFixer
- 源码定位:L63
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
private static void extractAndStoreLegacyStructureData(Dynamic<Tag> levelData, List<LegacyStructureFileFix.DimensionFixEntry> dimensionFixEntries, UpgradeProgress upgradeProgress) @ L110
- 方法名:extractAndStoreLegacyStructureData
- 源码定位:L110
- 返回类型:void
- 修饰符:private static
参数:
- levelData: Dynamic
- dimensionFixEntries: List<LegacyStructureFileFix.DimensionFixEntry>
- upgradeProgress: UpgradeProgress
说明:
TODO
private static FileAccess<SavedDataNbt> getLegacyStructureData(FileAccessProvider files, String structureId) @ L153
- 方法名:getLegacyStructureData
- 源码定位:L153
- 返回类型:FileAccess
- 修饰符:private static
参数:
- files: FileAccessProvider
- structureId: String
说明:
TODO
private static void extractLegacyStructureData(Dynamic<Tag> structureData, Long2ObjectMap<LegacyStructureFileFix.LegacyStructureData> extractedDataContainer) @ L160
- 方法名:extractLegacyStructureData
- 源码定位:L160
- 返回类型:void
- 修饰符:private static
参数:
- structureData: Dynamic
- extractedDataContainer: Long2ObjectMap<LegacyStructureFileFix.LegacyStructureData>
说明:
TODO
private static void storeLegacyStructureDataToChunks(Long2ObjectMap<LegacyStructureFileFix.LegacyStructureData> structures, ChunkNbt chunksAccess, CompoundTag dataFixContext, UpgradeProgress upgradeProgress) @ L196
- 方法名:storeLegacyStructureDataToChunks
- 源码定位:L196
- 返回类型:void
- 修饰符:private static
参数:
- structures: Long2ObjectMap<LegacyStructureFileFix.LegacyStructureData>
- chunksAccess: ChunkNbt
- dataFixContext: CompoundTag
- upgradeProgress: UpgradeProgress
说明:
TODO
代码
public class LegacyStructureFileFix extends FileFix {
public static final int STRUCTURE_RANGE = 8;
public static final List<String> OVERWORLD_LEGACY_STRUCTURES = List.of("Monument", "Stronghold", "Mineshaft", "Temple", "Mansion");
public static final Map<String, String> LEGACY_TO_CURRENT_MAP = Util.make(Maps.newHashMap(), map -> {
map.put("Iglu", "Igloo");
map.put("TeDP", "Desert_Pyramid");
map.put("TeJP", "Jungle_Pyramid");
map.put("TeSH", "Swamp_Hut");
});
public static final List<String> NETHER_LEGACY_STRUCTURES = List.of("Fortress");
public static final List<String> END_LEGACY_STRUCTURES = List.of("EndCity");
private static final ResourceKey<Level> OVERWORLD_KEY = ResourceKey.create(Registries.DIMENSION, Identifier.withDefaultNamespace("overworld"));
private static final ResourceKey<Level> NETHER_KEY = ResourceKey.create(Registries.DIMENSION, Identifier.withDefaultNamespace("the_nether"));
private static final ResourceKey<Level> END_KEY = ResourceKey.create(Registries.DIMENSION, Identifier.withDefaultNamespace("the_end"));
public LegacyStructureFileFix(Schema schema) {
super(schema);
}
@Override
public void makeFixer() {
this.addFileContentFix(
files -> {
List<FileAccess<SavedDataNbt>> overworldStructureData = OVERWORLD_LEGACY_STRUCTURES.stream()
.map(structureId -> getLegacyStructureData(files, structureId))
.toList();
RegionStorageInfo overworldInfo = new RegionStorageInfo("overworld", OVERWORLD_KEY, "chunk");
List<FileAccess<SavedDataNbt>> netherStructureData = NETHER_LEGACY_STRUCTURES.stream()
.map(structureId -> getLegacyStructureData(files, structureId))
.toList();
RegionStorageInfo netherInfo = new RegionStorageInfo("the_nether", NETHER_KEY, "chunk");
List<FileAccess<SavedDataNbt>> endStructureData = END_LEGACY_STRUCTURES.stream()
.map(structureId -> getLegacyStructureData(files, structureId))
.toList();
RegionStorageInfo endInfo = new RegionStorageInfo("the_end", END_KEY, "chunk");
FileAccess<LevelDat> levelDat = files.getFileAccess(FileResourceTypes.LEVEL_DAT, FileRelation.ORIGIN.forFile("level.dat"));
FileAccess<ChunkNbt> overworldChunks = files.getFileAccess(
FileResourceTypes.chunk(DataFixTypes.CHUNK, overworldInfo), FileRelation.OLD_OVERWORLD.resolve(FileRelation.REGION)
);
FileAccess<ChunkNbt> netherChunks = files.getFileAccess(
FileResourceTypes.chunk(DataFixTypes.CHUNK, netherInfo), FileRelation.OLD_NETHER.resolve(FileRelation.REGION)
);
FileAccess<ChunkNbt> endChunks = files.getFileAccess(
FileResourceTypes.chunk(DataFixTypes.CHUNK, endInfo), FileRelation.OLD_END.resolve(FileRelation.REGION)
);
return upgradeProgress -> {
Optional<Dynamic<Tag>> levelData = levelDat.getOnlyFile().read();
if (!levelData.isEmpty()) {
upgradeProgress.setType(UpgradeProgress.Type.LEGACY_STRUCTURES);
extractAndStoreLegacyStructureData(
levelData.get(),
List.of(
new LegacyStructureFileFix.DimensionFixEntry(
OVERWORLD_KEY, overworldStructureData, overworldChunks, new Long2ObjectOpenHashMap<>()
),
new LegacyStructureFileFix.DimensionFixEntry(NETHER_KEY, netherStructureData, netherChunks, new Long2ObjectOpenHashMap<>()),
new LegacyStructureFileFix.DimensionFixEntry(END_KEY, endStructureData, endChunks, new Long2ObjectOpenHashMap<>())
),
upgradeProgress
);
}
};
}
);
}
private static void extractAndStoreLegacyStructureData(
Dynamic<Tag> levelData, List<LegacyStructureFileFix.DimensionFixEntry> dimensionFixEntries, UpgradeProgress upgradeProgress
) throws IOException {
upgradeProgress.setStatus(UpgradeProgress.Status.COUNTING);
for (LegacyStructureFileFix.DimensionFixEntry dimensionFixEntry : dimensionFixEntries) {
Long2ObjectOpenHashMap<LegacyStructureFileFix.LegacyStructureData> structures = dimensionFixEntry.structures;
for (FileAccess<SavedDataNbt> structureDataFileAccess : dimensionFixEntry.structureFileAccess) {
SavedDataNbt targetFile = structureDataFileAccess.getOnlyFile();
Optional<Dynamic<Tag>> structureData = targetFile.read();
if (!structureData.isEmpty()) {
extractLegacyStructureData(structureData.get(), structures);
}
}
upgradeProgress.addTotalFileFixOperations(structures.size());
}
upgradeProgress.setStatus(UpgradeProgress.Status.UPGRADING);
for (LegacyStructureFileFix.DimensionFixEntry dimensionFixEntry : dimensionFixEntries) {
ResourceKey<Level> dimensionKey = dimensionFixEntry.dimensionKey;
ChunkNbt chunkNbt = dimensionFixEntry.chunkFileAccess.getOnlyFile();
String chunkGeneratorType;
if (dimensionKey == OVERWORLD_KEY) {
String generatorName = levelData.get("generatorName").asString("buffet");
chunkGeneratorType = switch (generatorName) {
case "flat" -> "minecraft:flat";
case "debug_all_block_states" -> "minecraft:debug";
default -> "minecraft:noise";
};
} else {
chunkGeneratorType = "minecraft:noise";
}
Optional<Identifier> generatorIdentifier = Optional.ofNullable(Identifier.tryParse(chunkGeneratorType));
CompoundTag dataFixContext = ChunkMap.getChunkDataFixContextTag(dimensionKey, generatorIdentifier);
storeLegacyStructureDataToChunks(dimensionFixEntry.structures, chunkNbt, dataFixContext, upgradeProgress);
}
}
private static FileAccess<SavedDataNbt> getLegacyStructureData(FileAccessProvider files, String structureId) {
return files.getFileAccess(
FileResourceTypes.savedData(References.SAVED_DATA_STRUCTURE_FEATURE_INDICES, CompressedNbt.MissingSeverity.MINOR),
FileRelation.DATA.forFile(structureId + ".dat")
);
}
private static void extractLegacyStructureData(
Dynamic<Tag> structureData, Long2ObjectMap<LegacyStructureFileFix.LegacyStructureData> extractedDataContainer
) {
OptionalDynamic<Tag> features = structureData.get("Features");
Map<Dynamic<Tag>, Dynamic<Tag>> map = features.asMap(Function.identity(), Function.identity());
for (Dynamic<Tag> value : map.values()) {
long pos = ChunkPos.pack(value.get("ChunkX").asInt(0), value.get("ChunkZ").asInt(0));
List<Dynamic<Tag>> childList = value.get("Children").asList(Function.identity());
if (!childList.isEmpty()) {
Optional<String> id = childList.getFirst().get("id").asString().result().map(LEGACY_TO_CURRENT_MAP::get);
if (id.isPresent()) {
value = value.set("id", value.createString(id.get()));
}
}
Dynamic<Tag> finalValue = value;
value.get("id")
.asString()
.ifSuccess(
id -> {
extractedDataContainer.computeIfAbsent(pos, l -> new LegacyStructureFileFix.LegacyStructureData()).addStart(id, finalValue);
for (int neighborX = ChunkPos.getX(pos) - 8; neighborX <= ChunkPos.getX(pos) + 8; neighborX++) {
for (int neighborZ = ChunkPos.getZ(pos) - 8; neighborZ <= ChunkPos.getZ(pos) + 8; neighborZ++) {
extractedDataContainer.computeIfAbsent(
ChunkPos.pack(neighborX, neighborZ), l -> new LegacyStructureFileFix.LegacyStructureData()
)
.addIndex(id, pos);
}
}
}
);
}
}
private static void storeLegacyStructureDataToChunks(
Long2ObjectMap<LegacyStructureFileFix.LegacyStructureData> structures,
ChunkNbt chunksAccess,
CompoundTag dataFixContext,
UpgradeProgress upgradeProgress
) {
for (Entry<LegacyStructureFileFix.LegacyStructureData> entry : structures.long2ObjectEntrySet()
.stream()
.sorted(Comparator.comparingLong(entryx -> ChunkPos.pack(ChunkPos.getRegionX(entryx.getLongKey()), ChunkPos.getRegionZ(entryx.getLongKey()))))
.toList()) {
if (upgradeProgress.isCanceled()) {
throw new CanceledFileFixException();
}
long pos = entry.getLongKey();
LegacyStructureFileFix.LegacyStructureData legacyData = entry.getValue();
chunksAccess.updateChunk(ChunkPos.unpack(pos), dataFixContext, tag -> {
CompoundTag levelTag = tag.getCompoundOrEmpty("Level");
CompoundTag structureTag = levelTag.getCompoundOrEmpty("Structures");
CompoundTag startTag = structureTag.getCompoundOrEmpty("Starts");
CompoundTag referencesTag = structureTag.getCompoundOrEmpty("References");
legacyData.starts().forEach((id, value) -> startTag.put(id, value.convert(NbtOps.INSTANCE).getValue()));
legacyData.indexes().forEach((id, indexes) -> referencesTag.putLongArray(id, indexes.toLongArray()));
structureTag.put("Starts", startTag);
structureTag.put("References", referencesTag);
levelTag.put("Structures", structureTag);
tag.put("Level", levelTag);
return tag;
});
upgradeProgress.incrementFinishedOperationsBy(1);
}
}
private record DimensionFixEntry(
ResourceKey<Level> dimensionKey,
List<FileAccess<SavedDataNbt>> structureFileAccess,
FileAccess<ChunkNbt> chunkFileAccess,
Long2ObjectOpenHashMap<LegacyStructureFileFix.LegacyStructureData> structures
) {
}
public record LegacyStructureData(Map<String, Dynamic<?>> starts, Map<String, LongList> indexes) {
public LegacyStructureData() {
this(new HashMap<>(), new HashMap<>());
}
public void addStart(String id, Dynamic<Tag> data) {
this.starts.put(id, data);
}
public void addIndex(String id, long sourcePos) {
this.indexes.computeIfAbsent(id, l -> new LongArrayList()).add(sourcePos);
}
}
}引用的其他类
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Identifier.tryParse(), Identifier.withDefaultNamespace()
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
ResourceKey.create()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ChunkMap.getChunkDataFixContextTag()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Util.make()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
CanceledFileFixException()
- 引用位置:
-
- 引用位置:
继承
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
FileResourceTypes.chunk(), FileResourceTypes.savedData()
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ChunkPos.getRegionX(), ChunkPos.getRegionZ(), ChunkPos.getX(), ChunkPos.getZ(), ChunkPos.pack(), ChunkPos.unpack()
- 引用位置:
-
- 引用位置:
字段
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
RegionStorageInfo()
- 引用位置: