Fix village structure

This commit is contained in:
Mrbysco 2024-10-22 19:48:54 +02:00
parent d644baa4cc
commit 43a23883e3
4 changed files with 105 additions and 0 deletions

View file

@ -0,0 +1 @@
// 1.21.1 2024-10-22T19:46:05.5548254 Update structure files in /structure

View file

@ -1,5 +1,6 @@
package de.ellpeck.actuallyadditions.data; package de.ellpeck.actuallyadditions.data;
import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI;
import de.ellpeck.actuallyadditions.data.patchouli.PatchouliGenerator; import de.ellpeck.actuallyadditions.data.patchouli.PatchouliGenerator;
import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; import de.ellpeck.actuallyadditions.mod.ActuallyAdditions;
import de.ellpeck.actuallyadditions.mod.gen.ActuallyBiomeModifiers; import de.ellpeck.actuallyadditions.mod.gen.ActuallyBiomeModifiers;
@ -72,6 +73,7 @@ public class ActuallyAdditionsData {
generator.addProvider(event.includeServer(), new DatapackBuiltinEntriesProvider( generator.addProvider(event.includeServer(), new DatapackBuiltinEntriesProvider(
packOutput, patchedProvider, Set.of(ActuallyAdditions.MODID))); packOutput, patchedProvider, Set.of(ActuallyAdditions.MODID)));
generator.addProvider(true, new StructureUpdater("structure", ActuallyAdditionsAPI.MOD_ID, helper, packOutput));
generator.addProvider(true, new Curios(packOutput, helper, lookupProvider)); generator.addProvider(true, new Curios(packOutput, helper, lookupProvider));
} }

View file

@ -0,0 +1,102 @@
package de.ellpeck.actuallyadditions.data;
/*
* BluSunrize
* Copyright (c) 2021
*
* This code is licensed under "Blu's License of Common Sense".
* Class written by malte0811 and BluSunrize, and used with malte's permission.
*/
import com.google.common.hash.Hashing;
import com.mojang.datafixers.DataFixer;
import com.mojang.datafixers.DataFixerUpper;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.data.CachedOutput;
import net.minecraft.data.DataProvider;
import net.minecraft.data.PackOutput;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtAccounter;
import net.minecraft.nbt.NbtIo;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.MultiPackResourceManager;
import net.minecraft.server.packs.resources.Resource;
import net.minecraft.util.datafix.DataFixTypes;
import net.minecraft.util.datafix.DataFixers;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import net.neoforged.neoforge.common.data.ExistingFileHelper;
import javax.annotation.Nonnull;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.file.Path;
import java.util.concurrent.CompletableFuture;
public class StructureUpdater implements DataProvider {
private final String basePath;
private final String modid;
private final PackOutput output;
private final MultiPackResourceManager resources;
public StructureUpdater(
String basePath, String modid, ExistingFileHelper helper, PackOutput output
) {
this.basePath = basePath;
this.modid = modid;
this.output = output;
try {
Field serverData = ExistingFileHelper.class.getDeclaredField("serverData");
serverData.setAccessible(true);
resources = (MultiPackResourceManager) serverData.get(helper);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
@Override
public CompletableFuture<?> run(@Nonnull CachedOutput cache) {
try {
for (var entry : resources.listResources(basePath, $ -> true).entrySet())
if (entry.getKey().getNamespace().equals(modid))
process(entry.getKey(), entry.getValue(), cache);
return CompletableFuture.completedFuture(null);
} catch (IOException x) {
return CompletableFuture.failedFuture(x);
}
}
private void process(ResourceLocation loc, Resource resource, CachedOutput cache) throws IOException {
CompoundTag inputNBT = NbtIo.readCompressed(resource.open(), NbtAccounter.unlimitedHeap());
CompoundTag converted = updateNBT(inputNBT);
if (!converted.equals(inputNBT)) {
Class<? extends DataFixer> fixerClass = DataFixers.getDataFixer().getClass();
if (!fixerClass.equals(DataFixerUpper.class))
throw new RuntimeException("Structures are not up to date, but unknown data fixer is in use: " + fixerClass.getName());
writeNBTTo(loc, converted, cache);
}
}
private void writeNBTTo(ResourceLocation loc, CompoundTag data, CachedOutput cache) throws IOException {
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
NbtIo.writeCompressed(data, bytearrayoutputstream);
byte[] bytes = bytearrayoutputstream.toByteArray();
Path outputPath = output.getOutputFolder().resolve("data/" + loc.getNamespace() + "/" + loc.getPath());
cache.writeIfNeeded(outputPath, bytes, Hashing.sha1().hashBytes(bytes));
}
private static CompoundTag updateNBT(CompoundTag nbt) {
final CompoundTag updatedNBT = DataFixTypes.STRUCTURE.updateToCurrentVersion(
DataFixers.getDataFixer(), nbt, nbt.getInt("DataVersion")
);
StructureTemplate template = new StructureTemplate();
template.load(BuiltInRegistries.BLOCK.asLookup(), updatedNBT);
return template.save(new CompoundTag());
}
@Nonnull
@Override
public String getName() {
return "Update structure files in /" + basePath + "/";
}
}