Skip to content

Commit

Permalink
feat: added world extra data
Browse files Browse the repository at this point in the history
  • Loading branch information
RealBauHD committed Jan 14, 2024
1 parent 25f8a9c commit 25b39a5
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 28 deletions.
17 changes: 17 additions & 0 deletions api/src/main/java/io/github/sculkpowered/server/world/World.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import io.github.sculkpowered.server.world.chunk.ChunkGenerator;
import io.github.sculkpowered.server.world.chunk.VoidGenerator;
import io.github.sculkpowered.server.world.dimension.Dimension;
import net.kyori.adventure.nbt.CompoundBinaryTag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -137,6 +138,22 @@ default void block(@NotNull Position position, @NotNull BlockState block) {
*/
void spawnEntity(@NotNull Entity entity, @NotNull Position position);

/**
* Gets the extra world data.
* In the anvil folder it is the level dat file.
*
* @since 1.0.0
*/
@NotNull CompoundBinaryTag extraData();

/**
* Sets the extra data.
*
* @param data the data in a compound binary tag
* @since 1.0.0
*/
void extraData(@NotNull CompoundBinaryTag data);

/**
* Checks if the world is alive.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package io.github.sculkpowered.server.world;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -38,11 +41,19 @@ public boolean entities() {
}

public static @NotNull Slime slime(byte @NotNull [] bytes) {
return new Slime(bytes);
return slime(new ByteArrayInputStream(bytes));
}

public static @NotNull WorldLoader slime(@NotNull Path path) throws IOException {
return slime(Files.readAllBytes(path));
public static @NotNull Slime slime(@NotNull Path path) throws IOException {
return slime(Files.newInputStream(path));
}

public static @NotNull Slime slime(@NotNull InputStream inputStream) {
return slime(new DataInputStream(inputStream));
}

public static @NotNull Slime slime(@NotNull DataInputStream inputStream) {
return new Slime(inputStream);
}

public static final class Anvil extends WorldLoader {
Expand All @@ -60,14 +71,14 @@ public Path path() {

public static final class Slime extends WorldLoader {

private final byte[] bytes;
private final DataInputStream inputStream;

public Slime(byte[] bytes) {
this.bytes = bytes;
public Slime(DataInputStream inputStream) {
this.inputStream = inputStream;
}

public byte[] bytes() {
return this.bytes;
public DataInputStream inputStream() {
return this.inputStream;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.github.sculkpowered.server.world;

import java.io.DataOutputStream;
import java.io.OutputStream;
import java.nio.file.Path;
import org.jetbrains.annotations.NotNull;
Expand All @@ -14,6 +15,10 @@ private WorldSaver() {
}

public static @NotNull Slime slime(@NotNull OutputStream outputStream) {
return slime(new DataOutputStream(outputStream));
}

public static @NotNull Slime slime(@NotNull DataOutputStream outputStream) {
return new Slime(outputStream);
}

Expand All @@ -32,13 +37,13 @@ public Path path() {

public static final class Slime extends WorldSaver {

private final OutputStream outputStream;
private final DataOutputStream outputStream;

public Slime(OutputStream outputStream) {
public Slime(DataOutputStream outputStream) {
this.outputStream = outputStream;
}

public OutputStream outputStream() {
public DataOutputStream outputStream() {
return this.outputStream;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import net.kyori.adventure.nbt.BinaryTagIO;
import net.kyori.adventure.nbt.BinaryTagIO.Compression;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.apache.logging.log4j.LogManager;
Expand Down Expand Up @@ -304,6 +306,15 @@ public int playerCount() {
final var world = this.createWorld(builder, chunkLoader);
if (loader instanceof WorldLoader.Slime slime) {
SlimeFormat.load(this, (SculkWorld) world, slime);
} else if (loader instanceof WorldLoader.Anvil anvil) {
final var levelData = anvil.path().resolve("level.dat");
if (Files.exists(levelData)) {
try {
world.extraData(BinaryTagIO.reader().read(levelData, Compression.GZIP));
} catch (IOException e) {
LOGGER.warn("Error during level data loading: ", e);
}
}
}
return world;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import java.util.function.Consumer;
import net.kyori.adventure.nbt.CompoundBinaryTag;
import org.jetbrains.annotations.NotNull;

public final class SculkWorld implements World {
Expand All @@ -25,6 +26,7 @@ public final class SculkWorld implements World {
private final Position spawnPosition;
private final GameMode defaultGameMode;
private final Long2ObjectMap<SculkChunk> chunks;
private CompoundBinaryTag extraData = CompoundBinaryTag.empty();
private boolean alive;

public SculkWorld(
Expand Down Expand Up @@ -109,6 +111,16 @@ public void spawnEntity(@NotNull Entity entity, @NotNull Position position) {
}
}

@Override
public @NotNull CompoundBinaryTag extraData() {
return this.extraData;
}

@Override
public void extraData(@NotNull CompoundBinaryTag data) {
this.extraData = data;
}

@Override
public boolean isAlive() {
return this.alive;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
import net.kyori.adventure.nbt.BinaryTagIO;
import net.kyori.adventure.nbt.CompoundBinaryTag;
Expand All @@ -42,24 +41,22 @@ public static void load(
final SculkWorld world,
final WorldLoader.Slime loader
) {
try (final var inputStream = new DataInputStream(new ByteArrayInputStream(loader.bytes()))) {
try (final var inputStream = loader.inputStream()) {
if (inputStream.readShort() != HEADER) {
throw new AssertionError();
}
final var version = inputStream.readUnsignedByte();
if (version != VERSION_10 && version != VERSION_11) {
throw new UnsupportedOperationException(
"Currently only slime version 10 and 11 are supported!");
}
inputStream.readInt(); // world version

if (version == VERSION_10) {
readChunks10(server, world, readCompressed(inputStream));
readEntities(server, world, loader, inputStream);
} else {
readChunks11(server, world, loader, readCompressed(inputStream));
switch (version) {
case VERSION_10 -> {
readChunks10(server, world, readCompressed(inputStream));
readEntities(server, world, loader, inputStream);
}
case VERSION_11 -> readChunks11(server, world, loader, readCompressed(inputStream));
default -> throw new UnsupportedOperationException("Slime version " + version + " not supported!");
}
readCompressed(inputStream);

world.extraData(readCompound(readCompressed(inputStream)));
} catch (IOException e) {
LOGGER.error("Couldn't load slime world", e);
}
Expand Down Expand Up @@ -196,8 +193,8 @@ private static CompoundBinaryTag readCompound(final byte[] data) throws IOExcept
// SAVING

public static void save(final SculkServer server, final SculkWorld world,
final OutputStream outputStream) {
try (final var dataOutput = new DataOutputStream(outputStream)) {
final DataOutputStream outputStream) {
try (final var dataOutput = outputStream) {
dataOutput.writeShort(HEADER);
dataOutput.writeByte(VERSION_10);
dataOutput.writeInt(3465);
Expand Down Expand Up @@ -240,7 +237,7 @@ public static void save(final SculkServer server, final SculkWorld world,
CompoundBinaryTag.builder().put("tiles", tiles.build()).build());
writeCompoundCompressed(dataOutput,
CompoundBinaryTag.builder().put("entities", entities.build()).build());
writeCompoundCompressed(dataOutput, CompoundBinaryTag.empty());
writeCompoundCompressed(dataOutput, world.extraData());
} catch (IOException e) {
LOGGER.error("Error while saving world", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public AnvilLoader(final SculkServer server, final ChunkGenerator generator,
@Override
public @NotNull SculkChunk loadChunk(final SculkWorld world, final int x, final int z) {
final var fileName =
"r." + CoordinateUtil.regionCoordinate(x) + "." + CoordinateUtil.regionCoordinate(z)
"r." + CoordinateUtil.regionCoordinate(x) + '.' + CoordinateUtil.regionCoordinate(z)
+ ".mca";
try {
SculkChunk chunk;
Expand Down

0 comments on commit 25b39a5

Please sign in to comment.