package net.minecraft.util.datafix.fixes;
import com.mojang.datafixers.DSL;
import com.mojang.datafixers.DataFix;
import com.mojang.datafixers.OpticFinder;
import com.mojang.datafixers.TypeRewriteRule;
import com.mojang.datafixers.Typed;
import com.mojang.datafixers.schemas.Schema;
import com.mojang.datafixers.types.Type;
import com.mojang.datafixers.util.Either;
import com.mojang.datafixers.util.Pair;
import com.mojang.datafixers.util.Unit;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.Dynamic;
import com.mojang.serialization.DynamicOps;
import java.util.function.Function;
public class ChunkRenamesFix extends DataFix {
public ChunkRenamesFix(final Schema outputSchema) {
super(outputSchema, true);
}
@Override
protected TypeRewriteRule makeRule() {
Type> chunkType = this.getInputSchema().getType(References.CHUNK);
OpticFinder> levelFinder = chunkType.findField("Level");
OpticFinder> structureFinder = levelFinder.type().findField("Structures");
Type> newChunkType = this.getOutputSchema().getType(References.CHUNK);
Type> newStructuresType = newChunkType.findFieldType("structures");
return this.fixTypeEverywhereTyped("Chunk Renames; purge Level-tag", chunkType, newChunkType, chunk -> {
Typed> level = chunk.getTyped(levelFinder);
Typed> chunkTyped = appendChunkName(level);
chunkTyped = chunkTyped.set(DSL.remainderFinder(), mergeRemainders(chunk, level.get(DSL.remainderFinder())));
chunkTyped = renameField(chunkTyped, "TileEntities", "block_entities");
chunkTyped = renameField(chunkTyped, "TileTicks", "block_ticks");
chunkTyped = renameField(chunkTyped, "Entities", "entities");
chunkTyped = renameField(chunkTyped, "Sections", "sections");
chunkTyped = chunkTyped.updateTyped(structureFinder, newStructuresType, structure -> renameField(structure, "Starts", "starts"));
chunkTyped = renameField(chunkTyped, "Structures", "structures");
return chunkTyped.update(DSL.remainderFinder(), remainder -> remainder.remove("Level"));
});
}
private static Typed> renameField(final Typed> input, final String oldName, final String newName) {
return renameFieldHelper(input, oldName, newName, input.getType().findFieldType(oldName)).update(DSL.remainderFinder(), tag -> tag.remove(oldName));
}
private static Typed> renameFieldHelper(final Typed> input, final String oldName, final String newName, final Type fieldType) {
Type> oldType = DSL.optional(DSL.field(oldName, fieldType));
Type> newType = DSL.optional(DSL.field(newName, fieldType));
return input.update(oldType.finder(), newType, Function.identity());
}
private static Typed> appendChunkName(final Typed input) {
return new Typed<>(DSL.named("chunk", input.getType()), input.getOps(), Pair.of("chunk", input.getValue()));
}
private static Dynamic mergeRemainders(final Typed> chunk, final Dynamic levelRemainder) {
DynamicOps ops = levelRemainder.getOps();
Dynamic chunkRemainder = chunk.get(DSL.remainderFinder()).convert(ops);
DataResult toMap = ops.getMap(levelRemainder.getValue()).flatMap(map -> ops.mergeToMap(chunkRemainder.getValue(), map));
return (Dynamic)toMap.result().map(v -> new Dynamic<>(ops, (T)v)).orElse(levelRemainder);
}
}