Skip to content

Commit

Permalink
Merge pull request #120 from mircokroon/entities
Browse files Browse the repository at this point in the history
Entities
  • Loading branch information
mircokroon authored Feb 20, 2021
2 parents f312a57 + 9379c5c commit 02f81aa
Show file tree
Hide file tree
Showing 51 changed files with 1,621 additions and 431 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Latest Windows release (GUI): [world-downloader.exe](https://github.com/mircokro

Cross-platform jar (GUI & commandline): [world-downloader.jar](https://github.com/mircokroon/minecraft-world-downloader/releases/latest/download/world-downloader.jar)

### Features
### [Features](https://github.com/mircokroon/minecraft-world-downloader/wiki/Features)
- Requires no client modifications and as such works with every game client, vanilla or not
- Automatically merge into previous downloads or existing worlds
- Save chests and other inventories by opening them
Expand Down
16 changes: 14 additions & 2 deletions src/main/java/config/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ public class Config {
private transient boolean guiOnlyMode = true;

private transient boolean debugWriteChunkNbt;
private transient VersionReporter versionReporter;

public Config() {
this.versionReporter = new VersionReporter(0);
}

public static void setInstance(Config config) {
instance = config;
Expand Down Expand Up @@ -101,6 +106,7 @@ public static ConnectionDetails getConnectionDetails() {

public static void setProtocolVersion(int protocolVersion) {
instance.protocolVersion = protocolVersion;
instance.versionReporter = new VersionReporter(protocolVersion);
}

public static boolean inGuiMode() {
Expand Down Expand Up @@ -235,6 +241,7 @@ public static Protocol getGameProtocol() {
Protocol p = instance.versionHandler.getProtocolByProtocolVersion(instance.protocolVersion);
instance.dataVersion = p.getDataVersion();
instance.gameVersion = p.getVersion();
instance.versionReporter = new VersionReporter(instance.protocolVersion);

new Thread(() -> loadVersionRegistries(p)).start();

Expand All @@ -251,7 +258,6 @@ private static void loadVersionRegistries(Protocol p) {
WorldManager.getInstance().setItemRegistry(loader.generateItemRegistry());

WorldManager.getInstance().startSaveService();
ChunkFactory.startChunkParserService();

loader.clean();
} catch (Exception e) {
Expand Down Expand Up @@ -411,10 +417,16 @@ public static String getGameVersion() {
return instance.gameVersion;
}

public static int getProtocolVersion() {
private static int getProtocolVersion() {
return instance.protocolVersion;
}

public static VersionReporter versionReporter() {
return instance.versionReporter;
}



public static AuthDetails getAuthDetails() {
return AuthDetails.fromUsername(instance.username, instance.accessToken);
}
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/config/Option.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package config;

import java.util.function.Supplier;

public class Option {
Version v;
Supplier<Object> obj;

public Option(Version v, Supplier<Object> obj) {
this.v = v;
this.obj = obj;
}

public static Option of(Version v, Supplier<Object> obj) {
return new Option(v, obj);
}
}
34 changes: 34 additions & 0 deletions src/main/java/config/Version.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package config;

public enum Version {
V1_12,
V1_13,
V1_14,
V1_15,
V1_16,
ANY;

boolean isVersion(VersionReporter versionReporter) {
switch (this) {
case V1_12: return versionReporter.isAtLeast1_12();
case V1_13: return versionReporter.isAtLeast1_13();
case V1_14: return versionReporter.isAtLeast1_14();
case V1_15: return versionReporter.isAtLeast1_15();
case V1_16: return versionReporter.isAtLeast1_16();
case ANY: return true;
default: return false;
}
}

public boolean isDataVersion(int dataVersion) {
switch (this) {
case V1_12: return VersionReporter.isAtLeast1_12(dataVersion);
case V1_13: return VersionReporter.isAtLeast1_13(dataVersion);
case V1_14: return VersionReporter.isAtLeast1_14(dataVersion);
case V1_15: return VersionReporter.isAtLeast1_15(dataVersion);
case V1_16: return VersionReporter.isAtLeast1_16(dataVersion);
case ANY: return true;
default: return false;
}
}
}
101 changes: 101 additions & 0 deletions src/main/java/config/VersionReporter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package config;

import game.protocol.Protocol;
import game.protocol.ProtocolVersionHandler;

public class VersionReporter {
private final static int DATA_VERSION_1_12 = 1022;
private final static int DATA_VERSION_1_13 = 1444;
private final static int DATA_VERSION_1_14 = 1901;
private final static int DATA_VERSION_1_15 = 2200;
private final static int DATA_VERSION_1_16 = 2504;

private final static int VERSION_1_12 = 317;
private final static int VERSION_1_13 = 341;
private final static int VERSION_1_14 = 440;
private final static int VERSION_1_15 = 550;
private final static int VERSION_1_16 = 701;

private final int protocolVersion;
public VersionReporter(int version) {
this.protocolVersion = version;
}

public Protocol getProtocol() {
return ProtocolVersionHandler.getInstance().getProtocolByProtocolVersion(protocolVersion);
}

public static <T> T select(int dataVersion, Class<T> type, Option... opts) {
for (Option opt : opts) {
if (is(dataVersion, opt.v)) {
return type.cast(opt.obj.get());
}
}
return null;
}

public <T> T select(Class<T> type, Option... opts) {
for (Option opt : opts) {
if (is(opt.v)) {
return type.cast(opt.obj.get());
}
}
return null;
}

public static boolean is(int dataVersion, Version v) {
return v.isDataVersion(dataVersion);
}

public boolean is(Version v) {
return v.isVersion(this);
}

public boolean isAtLeast1_12() {
return protocolVersion >= VERSION_1_12;
}
public boolean isAtLeast1_13() {
return protocolVersion >= VERSION_1_13;
}
public boolean isAtLeast1_14() {
return protocolVersion >= VERSION_1_14;
}
public boolean isAtLeast1_15() {
return protocolVersion >= VERSION_1_15;
}
public boolean isAtLeast1_16() {
return protocolVersion >= VERSION_1_16;
}

public static boolean isAtLeast1_12(int dataVersion) {
return dataVersion >= DATA_VERSION_1_12;
}
public static boolean isAtLeast1_13(int dataVersion) {
return dataVersion >= DATA_VERSION_1_13;
}
public static boolean isAtLeast1_14(int dataVersion) {
return dataVersion >= DATA_VERSION_1_14;
}
public static boolean isAtLeast1_15(int dataVersion) {
return dataVersion >= DATA_VERSION_1_15;
}
public static boolean isAtLeast1_16(int dataVersion) {
return dataVersion >= DATA_VERSION_1_16;
}

public boolean is1_12() {
return protocolVersion >= VERSION_1_12 && protocolVersion < VERSION_1_13;
}
public boolean is1_13() {
return protocolVersion >= VERSION_1_13 && protocolVersion < VERSION_1_14;
}
public boolean is1_14() {
return protocolVersion >= VERSION_1_14 && protocolVersion < VERSION_1_15;
}
public boolean is1_15() {
return protocolVersion >= VERSION_1_15 && protocolVersion < VERSION_1_16;
}
public boolean is1_16() {
return protocolVersion >= VERSION_1_16;
}
}
66 changes: 53 additions & 13 deletions src/main/java/game/data/LevelData.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
package game.data;

import config.Config;
import game.data.WorldManager;
import game.data.coordinates.Coordinate3D;
import game.data.coordinates.CoordinateDim2D;
import game.data.coordinates.CoordinateDim3D;
import game.data.coordinates.CoordinateDouble3D;
import game.data.dimension.Dimension;
import game.data.dimension.DimensionCodec;
import org.apache.commons.io.IOUtils;
import proxy.CompressionManager;
import se.llbit.nbt.*;
import util.NbtUtil;
import util.PathUtils;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class LevelData {
WorldManager worldManager;
Expand Down Expand Up @@ -67,13 +73,9 @@ private void load(boolean forceInternal) throws IOException {
fileInput = new FileInputStream(file);
}

byte[] fileContent = IOUtils.toByteArray(fileInput);

try {
// get default level.dat
this.root = NamedTag.read(
new DataInputStream(new ByteArrayInputStream(CompressionManager.gzipDecompress(fileContent)))
);
this.root = NbtUtil.read(fileInput);
} catch (Exception ex) {
ex.printStackTrace();
if (!forceInternal) {
Expand All @@ -84,7 +86,6 @@ private void load(boolean forceInternal) throws IOException {
this.data = (CompoundTag) root.unpack().get("Data");
}


/**
* Save the level.dat file so the world can be easily opened. If one doesn't exist, use the default one from
* the resource folder.
Expand Down Expand Up @@ -126,29 +127,68 @@ public void save() throws IOException {
versionTag.add("Snapshot", new ByteTag((byte) 0));

data.add("Version", versionTag);
data.add("DataVersion", new IntTag(Config.getDataVersion()));
}

if (!Config.isWorldGenEnabled()) {
disableWorldGeneration(data);
} else {
enableWorldGeneration(data);
}

// write the file
ByteArrayOutputStream output = new ByteArrayOutputStream();
root.write(new DataOutputStream(output));
NbtUtil.write(root, file.toPath());
}

byte[] compressed = CompressionManager.gzipCompress(output.toByteArray());
Files.write(file.toPath(), compressed);
private void enableWorldGeneration(CompoundTag data) {
if (Config.getDataVersion() < 2504) {
data.add("generatorVersion", new IntTag(1));
data.add("generatorName", new StringTag("default"));
// this is the 1.12.2 superflat format, but it still works in later versions.
data.add("generatorOptions", new StringTag(""));
}
}


/**
* Set world type to a superflat void world.
*/
private void disableWorldGeneration(CompoundTag data) {
data.add("generatorName", new StringTag("flat"));
if (Config.getDataVersion() < 2504) {
data.add("generatorVersion", new IntTag(1));
data.add("generatorName", new StringTag("flat"));
// this is the 1.12.2 superflat format, but it still works in later versions.
data.add("generatorOptions", new StringTag("3;minecraft:air;127"));
} else {
CompoundTag generator = new CompoundTag();
generator.add("type", new StringTag("minecraft:flat"));
generator.add("settings", new CompoundTag(Arrays.asList(
new NamedTag("layers", new ListTag(Tag.TAG_COMPOUND, Collections.singletonList(
new CompoundTag(Arrays.asList(
new NamedTag("block", new StringTag("minecraft:air")),
new NamedTag("height", new IntTag(1))
))
))),
new NamedTag("structures", new CompoundTag(Arrays.asList(new NamedTag("structures", new CompoundTag())))),
new NamedTag("biome", new StringTag("minecraft:the_void"))
)));

CompoundTag dimensions = new CompoundTag(worldManager.getDimensionCodec().getDimensions().stream().map(dimension -> {
CompoundTag dim = new CompoundTag();
dim.add("type", new StringTag(dimension.getType()));
dim.add("generator", generator);

return new NamedTag(dimension.getName(), dim);
}).collect(Collectors.toList()));

// this is the 1.12.2 superflat format, but it still works in later versions.
data.add("generatorOptions", new StringTag("3;minecraft:air;127"));

data.add("WorldGenSettings", new CompoundTag(Arrays.asList(
new NamedTag("bonus_chest", new ByteTag(0)),
new NamedTag("generate_features", new ByteTag(0)),
new NamedTag("seed", new LongTag(Config.getLevelSeed())),
new NamedTag("dimensions", dimensions)
)));
}
}

}
Loading

0 comments on commit 02f81aa

Please sign in to comment.