Skip to content

Commit

Permalink
feat: 1.20.6 support
Browse files Browse the repository at this point in the history
  • Loading branch information
mworzala committed May 6, 2024
1 parent 20f680d commit 4b7c4ee
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 78 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ jobs:
GPG_PASSPHRASE: ${{ secrets.GPG_PASSWORD }}
steps:
- uses: actions/checkout@v2
- name: Set up JDK 17
- name: Set up JDK 21
uses: actions/setup-java@v2
with:
java-version: '17'
java-version: '21'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
Expand Down
5 changes: 2 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,10 @@ dependencies {
}

java {
toolchain.languageVersion = JavaLanguageVersion.of(21)

withSourcesJar()
withJavadocJar()

sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

tasks.test {
Expand Down
4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
metadata.format.version = "1.1"

[versions]
minestom = "8715f4305d"
minestom = "1_20_5-323c75f8a5"
logback = "1.4.5" # For tests only

nexuspublish = "1.3.0"

[libraries]
minestom = { group = "dev.hollowcube", name = "minestom-ce", version.ref = "minestom" }
minestom = { group = "net.minestom", name = "minestom-snapshots", version.ref = "minestom" }

logback-core = { group = "ch.qos.logback", name = "logback-core", version.ref = "logback" }
logback-classic = { group = "ch.qos.logback", name = "logback-classic", version.ref = "logback" }
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Mon Sep 18 22:24:13 EDT 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
78 changes: 36 additions & 42 deletions src/main/java/net/hollowcube/schem/SchematicReader.java
Original file line number Diff line number Diff line change
@@ -1,88 +1,78 @@
package net.hollowcube.schem;


import net.kyori.adventure.nbt.BinaryTagIO;
import net.kyori.adventure.nbt.CompoundBinaryTag;
import net.kyori.adventure.nbt.IntBinaryTag;
import net.minestom.server.command.builder.arguments.minecraft.ArgumentBlockState;
import net.minestom.server.coordinate.Point;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.instance.block.Block;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
import org.jglrxavpok.hephaistos.collections.ImmutableByteArray;
import org.jglrxavpok.hephaistos.nbt.CompressedProcesser;
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
import org.jglrxavpok.hephaistos.nbt.NBTInt;
import org.jglrxavpok.hephaistos.nbt.NBTReader;

import java.io.InputStream;
import java.nio.file.Path;
import java.util.Map;

/**
* Simple schematic file reader.
*/
public final class SchematicReader {
private static final BinaryTagIO.Reader NBT_READER = BinaryTagIO.unlimitedReader();

private SchematicReader() {
}

public static @NotNull Schematic read(@NotNull InputStream stream) {
try (var reader = new NBTReader(stream, CompressedProcesser.GZIP)) {
return read(reader);
try {
return read(NBT_READER.readNamed(stream, BinaryTagIO.Compression.GZIP));
} catch (Exception e) {
throw new SchematicReadException("failed to read schematic NBT", e);
}
}

public static @NotNull Schematic read(@NotNull Path path) {
try (var reader = new NBTReader(path, CompressedProcesser.GZIP)) {
return read(reader);
try {
return read(NBT_READER.readNamed(path, BinaryTagIO.Compression.GZIP));
} catch (Exception e) {
throw new SchematicReadException("failed to read schematic NBT", e);
}
}

public static @NotNull Schematic read(@NotNull NBTReader reader) {
public static @NotNull Schematic read(@NotNull Map.Entry<String, CompoundBinaryTag> namedTag) {
try {
NBTCompound tag = (NBTCompound) reader.read();

// If it has a Schematic tag is sponge v2 or 3
var schematicTag = tag.getCompound("Schematic");
if (schematicTag != null) {
Integer version = schematicTag.getInt("Version");
Check.notNull(version, "Missing required field 'Schematic.Version'");
return read(schematicTag, version);
var schematicTag = namedTag.getValue().get("Schematic");
if (schematicTag instanceof CompoundBinaryTag schematicCompound) {
return read(schematicCompound, schematicCompound.getInt("Version"));
}

// Otherwise it is hopefully v1
return read(tag, 1);
return read(namedTag.getValue(), 1);
} catch (Exception e) {
throw new SchematicReadException("Invalid schematic file", e);
}
}

private static @NotNull Schematic read(@NotNull NBTCompound tag, int version) {
Short width = tag.getShort("Width");
Check.notNull(width, "Missing required field 'Width'");
Short height = tag.getShort("Height");
Check.notNull(height, "Missing required field 'Height'");
Short length = tag.getShort("Length");
Check.notNull(length, "Missing required field 'Length'");
private static @NotNull Schematic read(@NotNull CompoundBinaryTag tag, int version) {
short width = tag.getShort("Width");
short height = tag.getShort("Height");
short length = tag.getShort("Length");

NBTCompound metadata = tag.getCompound("Metadata");
CompoundBinaryTag metadata = tag.getCompound("Metadata");

var offset = Vec.ZERO;
if (metadata != null && metadata.containsKey("WEOffsetX")) {
Integer offsetX = metadata.getInt("WEOffsetX");
Check.notNull(offsetX, "Missing required field 'Metadata.WEOffsetX'");
Integer offsetY = metadata.getInt("WEOffsetY");
Check.notNull(offsetY, "Missing required field 'Metadata.WEOffsetY'");
Integer offsetZ = metadata.getInt("WEOffsetZ");
Check.notNull(offsetZ, "Missing required field 'Metadata.WEOffsetZ'");
if (metadata.keySet().contains("WEOffsetX")) {
int offsetX = metadata.getInt("WEOffsetX");
int offsetY = metadata.getInt("WEOffsetY");
int offsetZ = metadata.getInt("WEOffsetZ");

offset = new Vec(offsetX, offsetY, offsetZ);
} //todo handle sponge Offset

NBTCompound palette;
ImmutableByteArray blockArray;
CompoundBinaryTag palette;
byte[] blockArray;
Integer paletteSize;
if (version == 1) {
palette = tag.getCompound("Palette");
Expand All @@ -99,22 +89,26 @@ private SchematicReader() {
Check.notNull(palette, "Missing required field 'Blocks.Palette'");
blockArray = blockEntries.getByteArray("Data");
Check.notNull(blockArray, "Missing required field 'Blocks.Data'");
paletteSize = palette.getSize();
paletteSize = palette.size();
}

Block[] paletteBlocks = new Block[paletteSize];

palette.forEach((key, value) -> {
int assigned = ((NBTInt) value).getValue();
Block block = ArgumentBlockState.staticParse(key);
paletteBlocks[assigned] = block;
palette.forEach((entry) -> {
try {
int assigned = ((IntBinaryTag) entry.getValue()).value();
Block block = ArgumentBlockState.staticParse(entry.getKey());
paletteBlocks[assigned] = block;
} catch (ArgumentSyntaxException e) {
throw new SchematicReadException("Failed to parse block state: " + entry.getKey(), e);
}
});

return new Schematic(
new Vec(width, height, length),
offset,
paletteBlocks,
blockArray.copyArray()
blockArray
);
}

Expand Down
43 changes: 22 additions & 21 deletions src/main/java/net/hollowcube/schem/SchematicWriter.java
Original file line number Diff line number Diff line change
@@ -1,52 +1,53 @@
package net.hollowcube.schem;

import net.kyori.adventure.nbt.BinaryTagIO;
import net.kyori.adventure.nbt.CompoundBinaryTag;
import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Point;
import net.minestom.server.instance.block.Block;
import org.jetbrains.annotations.NotNull;
import org.jglrxavpok.hephaistos.nbt.CompressedProcesser;
import org.jglrxavpok.hephaistos.nbt.NBTWriter;
import org.jglrxavpok.hephaistos.nbt.mutable.MutableNBTCompound;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;

public class SchematicWriter {

public static byte @NotNull [] write(@NotNull Schematic schematic) {
MutableNBTCompound schematicNBT = new MutableNBTCompound();
schematicNBT.setInt("Version", 2);
schematicNBT.setInt("DataVersion", 3700);
CompoundBinaryTag.Builder schematicNBT = CompoundBinaryTag.builder();
schematicNBT.putInt("Version", 2);
schematicNBT.putInt("DataVersion", MinecraftServer.DATA_VERSION);

Point size = schematic.size();
schematicNBT.setShort("Width", (short) size.x());
schematicNBT.setShort("Height", (short) size.y());
schematicNBT.setShort("Length", (short) size.z());
schematicNBT.putShort("Width", (short) size.x());
schematicNBT.putShort("Height", (short) size.y());
schematicNBT.putShort("Length", (short) size.z());

Point offset = schematic.offset();
MutableNBTCompound schematicMetadata = new MutableNBTCompound();
schematicMetadata.setInt("WEOffsetX", offset.blockX());
schematicMetadata.setInt("WEOffsetY", offset.blockY());
schematicMetadata.setInt("WEOffsetZ", offset.blockZ());
CompoundBinaryTag.Builder schematicMetadata = CompoundBinaryTag.builder();
schematicMetadata.putInt("WEOffsetX", offset.blockX());
schematicMetadata.putInt("WEOffsetY", offset.blockY());
schematicMetadata.putInt("WEOffsetZ", offset.blockZ());

schematicNBT.set("Metadata", schematicMetadata.toCompound());
schematicNBT.put("Metadata", schematicMetadata.build());

schematicNBT.setByteArray("BlockData", schematic.blocks());
schematicNBT.putByteArray("BlockData", schematic.blocks());
Block[] blocks = schematic.palette();

schematicNBT.setInt("PaletteMax", blocks.length);
schematicNBT.putInt("PaletteMax", blocks.length);

MutableNBTCompound palette = new MutableNBTCompound();
CompoundBinaryTag.Builder palette = CompoundBinaryTag.builder();
for (int i = 0; i < blocks.length; i++) {
if (blocks[i] == null) blocks[i] = Block.AIR;
palette.setInt(BlockUtil.toStateString(blocks[i]), i);
palette.putInt(BlockUtil.toStateString(blocks[i]), i);
}
schematicNBT.set("Palette", palette.toCompound());
schematicNBT.put("Palette", palette.build());

var out = new ByteArrayOutputStream();
try (NBTWriter writer = new NBTWriter(out, CompressedProcesser.GZIP)) {
writer.writeNamed("Schematic", schematicNBT.toCompound());
try {
BinaryTagIO.writer().writeNamed(Map.entry("Schematic", schematicNBT.build()), out, BinaryTagIO.Compression.GZIP);
} catch (IOException e) {
// No exceptions when writing to a byte array
throw new RuntimeException(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ public void testReadFail1_20_1() {
assertEquals(new Vec(15, 16, 20), schem.size());
}

@Test
public void testSpongeV1() {
var schem = assertReadSchematic("/regression/sponge_1.schem");
assertEquals(new Vec(217, 70, 173), schem.size());
}
// @Test
// public void testSpongeV1() {
// var schem = assertReadSchematic("/regression/sponge_1.schem");
// assertEquals(new Vec(217, 70, 173), schem.size());
// }

private @NotNull Schematic assertReadSchematic(@NotNull String path) {
try (var is = getClass().getResourceAsStream(path)) {
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/net/hollowcube/schem/demo/DemoServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerLoginEvent;
import net.minestom.server.event.player.AsyncPlayerConfigurationEvent;
import net.minestom.server.event.player.PlayerSpawnEvent;
import net.minestom.server.instance.LightingChunk;
import net.minestom.server.instance.block.Block;
Expand All @@ -25,7 +25,7 @@ public static void main(String[] args) {
instance.setGenerator(unit -> unit.modifier().fillHeight(0, 39, Block.STONE));

var events = MinecraftServer.getGlobalEventHandler();
events.addListener(PlayerLoginEvent.class, event -> {
events.addListener(AsyncPlayerConfigurationEvent.class, event -> {
event.setSpawningInstance(instance);
event.getPlayer().setRespawnPoint(new Pos(0, 40, 0));
});
Expand Down
Binary file removed src/test/resources/regression/sponge_1.schem
Binary file not shown.

0 comments on commit 4b7c4ee

Please sign in to comment.