Added schematic parser

Basically just v2 without biomes

 Changes to be committed:
	new file:   src/main/java/org/dimdev/dimcore/schematic/v2/Schematic.java
	new file:   src/main/java/org/dimdev/dimcore/schematic/v2/SchematicBlockPallete.java
	new file:   src/main/java/org/dimdev/dimcore/schematic/v2/SchematicMetadata.java
This commit is contained in:
SD 2020-09-10 11:24:05 +05:30
parent 73b02c278c
commit b0d79adc66
No known key found for this signature in database
GPG key ID: E36B57EE08544BC5
3 changed files with 232 additions and 0 deletions

View file

@ -0,0 +1,110 @@
package org.dimdev.dimcore.schematic.v2;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.math.Vec3i;
@SuppressWarnings("CodeBlock2Expr")
public class Schematic {
public static final Codec<Schematic> CODEC = RecordCodecBuilder.create((instance) -> {
return instance.group(
Codec.INT.fieldOf("Version").forGetter(Schematic::getVersion),
Codec.INT.fieldOf("Data Version").forGetter(Schematic::getDataVersion),
SchematicMetadata.CODEC.optionalFieldOf("Metadata", SchematicMetadata.EMPTY).forGetter(Schematic::getMetadata),
Codec.SHORT.fieldOf("Width").forGetter(Schematic::getWidth),
Codec.SHORT.fieldOf("Height").forGetter(Schematic::getHeight),
Codec.SHORT.fieldOf("Length").forGetter(Schematic::getLength),
Vec3i.field_25123.optionalFieldOf("Offset", Vec3i.ZERO).forGetter(Schematic::getOffset),
Codec.INT.fieldOf("PalleteMax").forGetter(Schematic::getPalleteMax),
SchematicBlockPallete.CODEC.optionalFieldOf("Palette", ImmutableMap.of()).forGetter(Schematic::getBlockPallete),
Codec.INT_STREAM.fieldOf("BlockData").forGetter(Schematic::getBlockData),
Codec.list(CompoundTag.field_25128).optionalFieldOf("BlockEntities", ImmutableList.of()).forGetter(Schematic::getBlockEntities),
Codec.list(CompoundTag.field_25128).optionalFieldOf("Entities", ImmutableList.of()).forGetter(Schematic::getEntities)
).apply(instance, Schematic::new);
});
private final int version;
private final int dataVersion;
private final SchematicMetadata metadata;
private final short width;
private final short height;
private final short length;
private final Vec3i offset;
private final int palleteMax;
private final Map<BlockState, Integer> blockPallete;
private final IntStream blockData;
private final List<CompoundTag> blockEntities;
private final List<CompoundTag> entities;
public Schematic(int version, int dataVersion, SchematicMetadata metadata, short width, short height, short length, Vec3i offset, int palleteMax, Map<BlockState, Integer> blockPallete, IntStream blockData, List<CompoundTag> blockEntities, List<CompoundTag> entities) {
this.version = version;
this.dataVersion = dataVersion;
this.metadata = metadata;
this.width = width;
this.height = height;
this.length = length;
this.offset = offset;
this.palleteMax = palleteMax;
this.blockPallete = blockPallete;
this.blockData = blockData;
this.blockEntities = blockEntities;
this.entities = entities;
}
public int getVersion() {
return this.version;
}
public int getDataVersion() {
return this.dataVersion;
}
public SchematicMetadata getMetadata() {
return this.metadata;
}
public short getWidth() {
return this.width;
}
public short getHeight() {
return this.height;
}
public short getLength() {
return this.length;
}
public Vec3i getOffset() {
return this.offset;
}
public int getPalleteMax() {
return this.palleteMax;
}
public Map<BlockState, Integer> getBlockPallete() {
return this.blockPallete;
}
public IntStream getBlockData() {
return this.blockData;
}
public List<CompoundTag> getBlockEntities() {
return this.blockEntities;
}
public List<CompoundTag> getEntities() {
return this.entities;
}
}

View file

@ -0,0 +1,75 @@
package org.dimdev.dimcore.schematic.v2;
import java.util.Iterator;
import java.util.Objects;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.codecs.UnboundedMapCodec;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.state.property.Property;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public class SchematicBlockPallete {
public static final UnboundedMapCodec<BlockState, Integer> CODEC = Codec.unboundedMap(Entry.CODEC, Codec.INT);
private static <T extends Comparable<T>> void process(Property<T> property, String value, BlockState state) {
state.with(property, property.parse(value).orElseThrow(NullPointerException::new));
}
public interface Entry {
Codec<BlockState> CODEC = Codec.STRING.comapFlatMap(Entry::to, Entry::from);
static <T extends Comparable<T>> DataResult<BlockState> to(String string) {
if (!string.contains("[") && !string.contains("]")) {
BlockState state = Registry.BLOCK.get(new Identifier(string)).getDefaultState();
return DataResult.success(state);
} else {
Block block = Objects.requireNonNull(Registry.BLOCK.get(new Identifier(string.substring(0, string.indexOf("[")))));
BlockState state = block.getDefaultState();
String[] stateArray = string.substring(string.indexOf("[") + 1, string.length() - 1).split(",");
for (String stateString : stateArray) {
Property<?> property = Objects.requireNonNull(block.getStateManager().getProperty(stateString.split("=")[0]));
process(property,stateString.split("=")[1], state);
}
return DataResult.success(state);
}
}
static String from(BlockState state) {
StringBuilder builder = new StringBuilder();
builder.append(Objects.requireNonNull(Registry.BLOCK.getId(state.getBlock())));
// Ensures that [ and ] are only added when properties are present
boolean flag = true;
Iterator<Property<?>> iterator = state.getProperties().iterator();
while(iterator.hasNext()) {
if (flag) {
builder.append("[");
flag = false;
}
Property<?> property = iterator.next();
builder.append(property.getName());
builder.append("=");
if (state.get(property) instanceof Enum<?>) {
// Enum might have override toString
builder.append(((Enum<?>) state.get(property)).name());
} else {
builder.append(state.get(property).toString());
}
if (iterator.hasNext()) {
builder.append(",");
}
}
if (!flag) {
builder.append("]");
}
return builder.toString();
}
}
}

View file

@ -0,0 +1,47 @@
package org.dimdev.dimcore.schematic.v2;
import java.util.List;
import com.google.common.collect.ImmutableList;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
@SuppressWarnings("CodeBlock2Expr")
public class SchematicMetadata {
public static final SchematicMetadata EMPTY = new SchematicMetadata("", "", 0L, ImmutableList.of());
public static final Codec<SchematicMetadata> CODEC = RecordCodecBuilder.create((instance) -> {
return instance.group(
Codec.STRING.fieldOf("Name").forGetter(SchematicMetadata::getName),
Codec.STRING.fieldOf("Author").forGetter(SchematicMetadata::getAuthor),
Codec.LONG.fieldOf("Date").forGetter(SchematicMetadata::getDate),
Codec.list(Codec.STRING).fieldOf("RequiredMods").forGetter(SchematicMetadata::getRequiredMods)
).apply(instance, SchematicMetadata::new);
});
private final String name;
private final String author;
private final long date;
private final List<String> requiredMods;
private SchematicMetadata(String name, String author, long date, List<String> requiredMods) {
this.name = name;
this.author = author;
this.date = date;
this.requiredMods = requiredMods;
}
public String getName() {
return this.name;
}
public String getAuthor() {
return this.author;
}
public long getDate() {
return this.date;
}
public List<String> getRequiredMods() {
return this.requiredMods;
}
}