Data Fixer (WIP)

This commit is contained in:
paulevsGitch 2021-03-13 05:08:17 +03:00
parent a3a6b54eba
commit a2605ef3f9
8 changed files with 174 additions and 0 deletions

View file

@ -32,6 +32,7 @@ import ru.betterend.registry.EndSounds;
import ru.betterend.registry.EndStructures; import ru.betterend.registry.EndStructures;
import ru.betterend.registry.EndTags; import ru.betterend.registry.EndTags;
import ru.betterend.util.BonemealUtil; import ru.betterend.util.BonemealUtil;
import ru.betterend.util.DataFixerUtil;
import ru.betterend.util.Logger; import ru.betterend.util.Logger;
import ru.betterend.world.generator.BetterEndBiomeSource; import ru.betterend.world.generator.BetterEndBiomeSource;
import ru.betterend.world.generator.GeneratorOptions; import ru.betterend.world.generator.GeneratorOptions;
@ -65,6 +66,7 @@ public class BetterEnd implements ModInitializer {
Integrations.register(); Integrations.register();
BonemealUtil.init(); BonemealUtil.init();
GeneratorOptions.init(); GeneratorOptions.init();
DataFixerUtil.init();
if (hasGuideBook()) { if (hasGuideBook()) {
GuideBookItem.register(); GuideBookItem.register();

View file

@ -0,0 +1,69 @@
package ru.betterend.mixin.common;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.Executor;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.metadata.ModMetadata;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtIo;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.WorldGenerationProgressListener;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.World;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.gen.Spawner;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.level.ServerWorldProperties;
import net.minecraft.world.level.storage.LevelStorage;
import ru.betterend.BetterEnd;
import ru.betterend.util.DataFixerUtil;
@Mixin(ServerWorld.class)
public class ServerWorldMixin {
@Inject(method = "<init>*", at = @At("TAIL"))
private void be_onServerWorldInit(MinecraftServer server, Executor workerExecutor, LevelStorage.Session session, ServerWorldProperties properties, RegistryKey<World> registryKey, DimensionType dimensionType, WorldGenerationProgressListener worldGenerationProgressListener, ChunkGenerator chunkGenerator, boolean debugWorld, long l, List<Spawner> list, boolean bl, CallbackInfo info) {
File beData = new File(FabricLoader.getInstance().getGameDir().getParent().toString(), "saves/" + properties.getLevelName() + "/betterend_data.nbt");
ModMetadata meta = FabricLoader.getInstance().getModContainer(BetterEnd.MOD_ID).get().getMetadata();
String version = meta.getVersion().toString();
boolean fix = false;
if (version.equals("${version}")) {
version = "development";
}
if (beData.exists()) {
CompoundTag root;
try {
root = NbtIo.read(beData);
}
catch (IOException e) {
BetterEnd.LOGGER.error("World data loading failed", e);
return;
}
String dataVersion = root.getString("version");
fix = !dataVersion.equals(version);
}
else {
CompoundTag root = new CompoundTag();
root.putString("version", version);
try {
NbtIo.write(root, beData);
}
catch (IOException e) {
BetterEnd.LOGGER.error("World data saving failed", e);
}
fix = true;
}
if (fix) {
DataFixerUtil.fixData(beData.getParentFile());
}
}
}

View file

@ -0,0 +1,90 @@
package ru.betterend.util;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.util.List;
import java.util.Map;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtIo;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.storage.RegionFile;
public class DataFixerUtil {
private static final Map<String, String> REPLACEMENT = Maps.newHashMap();
public static void init() {
addFix("minecraft:stone", "minecraft:glowstone");
}
public static void fixData(File dir) {
List<File> regions = getAllRegions(dir, null);
regions.forEach((file) -> {
try {
System.out.println("Fixing " + file);
boolean[] changed = new boolean[1];
RegionFile region = new RegionFile(file, file.getParentFile(), true);
for (int x = 0; x < 32; x++) {
for (int z = 0; z < 32; z++) {
ChunkPos pos = new ChunkPos(x, z);
changed[0] = false;
if (region.hasChunk(pos)) {
DataInputStream input = region.getChunkInputStream(pos);
CompoundTag root = NbtIo.read(input);
input.close();
ListTag sections = root.getCompound("Level").getList("Sections", 10);
sections.forEach((tag) -> {
ListTag palette = ((CompoundTag) tag).getList("Palette", 10);
palette.forEach((blockTag) -> {
CompoundTag blockTagCompound = ((CompoundTag) blockTag);
String name = blockTagCompound.getString("Name");
String replace = REPLACEMENT.get(name);
if (replace != null) {
blockTagCompound.putString("Name", replace);
changed[0] = true;
}
});
});
if (changed[0]) {
System.out.println("Write!");
DataOutputStream output = region.getChunkOutputStream(pos);
NbtIo.write(root, output);
output.close();
}
}
}
}
region.close();
}
catch (Exception e) {
e.printStackTrace();
}
});
}
private static void addFix(String result, String... names) {
for (String name: names) {
REPLACEMENT.put(name, result);
}
}
private static List<File> getAllRegions(File dir, List<File> list) {
if (list == null) {
list = Lists.newArrayList();
}
for (File file: dir.listFiles()) {
if (file.isDirectory()) {
getAllRegions(file, list);
}
else if (file.isFile() && file.getName().endsWith(".mca")) {
list.add(file);
}
}
return list;
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "betterend:item/end_stone_stalactite"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "betterend:item/end_stone_stalactite_cavemoss"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -29,6 +29,7 @@
"LivingEntityMixin", "LivingEntityMixin",
"BoneMealItemMixin", "BoneMealItemMixin",
"PlayerEntityMixin", "PlayerEntityMixin",
"ServerWorldMixin",
"SlimeEntityMixin", "SlimeEntityMixin",
"AnvilBlockMixin", "AnvilBlockMixin",
"BrewingAccessor", "BrewingAccessor",