add some commands, fix exception spam, split converter nbt implementation

This commit is contained in:
Sen 2025-05-27 14:29:40 +02:00
parent 2cee1d6632
commit ad4949af16
Signed by: sen
GPG key ID: 3AC50A6F47D1B722
9 changed files with 465 additions and 90 deletions

View file

@ -1,5 +1,6 @@
package common.network;
import java.io.IOException;
import java.net.SocketAddress;
import java.nio.channels.ClosedChannelException;
import java.util.Queue;
@ -69,7 +70,7 @@ public class NetConnection extends SimpleChannelInboundHandler<Packet> {
}
else {
comp = "Interner Fehler: " + throwable;
if(!(throwable instanceof ClosedChannelException))
if(!(throwable instanceof ClosedChannelException || throwable instanceof IOException))
Log.NETWORK.error(throwable, "Fehler in der Verbindung mit %s", this.getCutAddress());
}

View file

@ -7,10 +7,12 @@ import java.util.Map;
import common.collect.Lists;
import common.collect.Maps;
import common.util.BlockPos;
import common.util.CharValidator;
import common.util.Vec3;
import common.world.World;
import server.command.DoubleParser.DefType;
import server.command.IntParser.CoordType;
public abstract class Command implements Executable {
private final String name;
@ -78,6 +80,25 @@ public abstract class Command implements Executable {
new DoubleParser("z", defaulted ? DefType.Z : null, (double)(-World.MAX_SIZE), (double)World.MAX_SIZE, centered));
}
protected Command addBlockPos(String name, boolean defaulted) {
return this.addParameter(name, new ArgCombiner<Integer>() {
public BlockPos combine(Integer[] values) {
return new BlockPos(values[0], values[1], values[2]);
}
public Class<?> getTypeClass() {
return BlockPos.class;
}
public Class<Integer> getInputClass() {
return Integer.class;
}
},
new IntParser("x", defaulted ? CoordType.X : null, -World.MAX_SIZE, World.MAX_SIZE),
new IntParser("y", defaulted ? CoordType.Y : null, -World.MAX_SIZE_Y, World.MAX_SIZE_Y),
new IntParser("z", defaulted ? CoordType.Z : null, -World.MAX_SIZE, World.MAX_SIZE));
}
protected Command addWorld(String name, boolean defaulted) {
return this.addParameter(new WorldParser(name, false, defaulted));
}

View file

@ -14,6 +14,8 @@ import common.color.TextColor;
import common.log.Log;
import server.Server;
import server.command.commands.CommandAdmin;
import server.command.commands.CommandBlock;
import server.command.commands.CommandFind;
import server.command.commands.CommandHelp;
import server.command.commands.CommandKick;
import server.command.commands.CommandMessage;
@ -26,6 +28,7 @@ import server.command.commands.CommandRegister;
import server.command.commands.CommandRemove;
import server.command.commands.CommandRevoke;
import server.command.commands.CommandSave;
import server.command.commands.CommandSeed;
import server.command.commands.CommandShutdown;
import server.command.commands.CommandSpawn;
import server.command.commands.CommandTele;
@ -279,6 +282,9 @@ public class CommandEnvironment {
this.registerExecutable(new CommandPlayers());
this.registerExecutable(new CommandSave());
this.registerExecutable(new CommandRegister());
this.registerExecutable(new CommandFind());
this.registerExecutable(new CommandBlock());
this.registerExecutable(new CommandSeed());
this.registerExecutable(new CommandHelp(this));
}

View file

@ -36,14 +36,21 @@ public class DoubleParser extends DefaultingParser {
Double pre = this.defType != null && input.startsWith("~") ? this.getDefault(env) : null;
input = pre != null ? input.substring(1) : input;
double value;
try {
value = Double.parseDouble(input);
if(pre != null && input.isEmpty()) {
value = pre;
}
catch(NumberFormatException e) {
throw new RunException("Ungültige Gleitkommazahl '%s'", input);
else {
try {
value = Double.parseDouble(input);
}
catch(NumberFormatException e) {
throw new RunException("Ungültige Gleitkommazahl '%s'", input);
}
if(this.center && pre == null && input.indexOf('.') < 0)
value += 0.5;
else if(pre != null)
value = pre + value;
}
if(this.center && pre == null && input.indexOf('.') < 0)
value += 0.5;
if(this.min != null && value < this.min)
if(this.max != null)
throw new RunException("Die Zahl muss im Bereich %f .. %f liegen, habe %f", this.min, this.max, value);

View file

@ -1,24 +1,54 @@
package server.command;
import java.util.Collection;
import common.collect.Lists;
import common.util.BlockPos;
import common.util.ExtMath;
import common.util.Position;
public class IntParser extends DefaultingParser {
public static enum CoordType {
X, Y, Z;
}
private final CoordType defType;
private final Integer min;
private final Integer max;
private final boolean hex;
public IntParser(String name, boolean hex, Integer def, Integer min, Integer max, Object ... completions) {
super(name, def, completions);
this.defType = null;
this.min = min;
this.max = max;
this.hex = hex;
}
public IntParser(String name, CoordType type, Integer min, Integer max) {
super(name, null);
this.defType = type;
this.min = min;
this.max = max;
this.hex = false;
}
public Integer parse(CommandEnvironment env, String input) {
Integer pre = this.defType != null && input.startsWith("~") ? this.getDefault(env) : null;
input = pre != null ? input.substring(1) : input;
int value;
try {
value = Integer.parseInt(input, this.hex ? 16 : 10);
if(pre != null && input.isEmpty()) {
value = pre;
}
catch(NumberFormatException e) {
throw new RunException("Ungültige " + (this.hex ? "Hexadezimalzahl" : "Ganzzahl") + " '%s'", input);
else {
try {
value = Integer.parseInt(input, this.hex ? 16 : 10);
}
catch(NumberFormatException e) {
throw new RunException("Ungültige " + (this.hex ? "Hexadezimalzahl" : "Ganzzahl") + " '%s'", input);
}
if(pre != null)
value = pre + value;
}
if(this.min != null && value < this.min)
if(this.max != null)
@ -33,7 +63,35 @@ public class IntParser extends DefaultingParser {
return value;
}
public Integer getDefault(CommandEnvironment env) {
Position pos = this.defType == null ? null : env.getExecutor().getExecPos();
if(this.defType != null)
switch(this.defType) {
case X:
return pos == null ? null : ExtMath.floord(pos.x);
case Y:
return pos == null ? null : ExtMath.floord(pos.y);
case Z:
return pos == null ? null : ExtMath.floord(pos.z);
}
return (Integer)super.getDefault(env);
}
public Class<?> getTypeClass(boolean required) {
return this.hasDefault() || required ? int.class : Integer.class;
}
public Collection<String> getCompletions(CommandEnvironment env) {
BlockPos pos = this.defType == null ? null : env.getExecutor().getPointedPosition();
if(this.defType != null)
switch(this.defType) {
case X:
return pos == null ? null : Lists.newArrayList("" + pos.getX());
case Y:
return pos == null ? null : Lists.newArrayList("" + pos.getY());
case Z:
return pos == null ? null : Lists.newArrayList("" + pos.getZ());
}
return super.getCompletions(env);
}
}

View file

@ -0,0 +1,60 @@
package server.command.commands;
import java.util.Collection;
import common.init.BlockRegistry;
import common.nbt.NBTTagCompound;
import common.tileentity.TileEntity;
import common.util.BlockPos;
import common.world.State;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
import server.command.RunException;
import server.command.StringCompleter;
import server.world.WorldServer;
public class CommandBlock extends Command {
public CommandBlock() {
super("block");
this.addString("block", false, new StringCompleter() {
public Collection<String> complete(CommandEnvironment env) {
return BlockRegistry.REGISTRY.getKeys();
}
});
this.addBlockPos("position", true);
this.addWorld("dim", true);
this.addTag("tag", 't');
}
public Object exec(CommandEnvironment env, Executor exec, String block, BlockPos position, WorldServer world, NBTTagCompound tag) {
State state = BlockRegistry.getFromIdName(block, null);
if(state == null)
throw new RunException("Block '%s' existiert nicht", block);
boolean success = world.setState(position, state);
if(tag != null) {
TileEntity tile = world.getTileEntity(position);
if(tile != null) {
NBTTagCompound te = new NBTTagCompound();
tile.writeToNBT(te);
tag.setString("id", te.getString("id"));
tag.setInteger("x", position.getX());
tag.setInteger("y", position.getY());
tag.setInteger("z", position.getZ());
te.merge(tag);
TileEntity newTile = TileEntity.createAndLoadEntity(te);
if(newTile != null) {
world.removeTileEntity(position);
world.setTileEntity(position, newTile);
success = true;
}
}
}
if(success)
exec.logConsole("%s bei %d, %d, %d in %s gesetzt", state.getBlock().getDisplay(), position.getX(), position.getY(), position.getZ(), world.dimension.getFormattedName(false));
else
exec.logConsole("Block wurde nicht verändert");
return success;
}
}

View file

@ -0,0 +1,31 @@
package server.command.commands;
import java.util.List;
import common.entity.Entity;
import common.util.BlockPos;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
public class CommandFind extends Command {
public CommandFind() {
super("find");
this.addEntityList("entities", false);
}
public Object exec(CommandEnvironment env, Executor exec, List<Entity> entities) {
int done = 0;
for(Entity entity : entities) {
if(entity.isEntityAlive()) {
BlockPos pos = entity.getPosition();
exec.logConsole("%s bei %d, %d, %d in %s gefunden", entity.getCommandName(), pos.getX(), pos.getY(), pos.getZ(), entity.worldObj.dimension.getFormattedName(false));
done++;
}
}
if(done > 1)
exec.logConsole("%d Objekte gefunden", done);
return done;
}
}

View file

@ -0,0 +1,19 @@
package server.command.commands;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
import server.world.WorldServer;
public class CommandSeed extends Command {
public CommandSeed() {
super("seed");
this.addWorld("dim", true);
}
public Object exec(CommandEnvironment env, Executor exec, WorldServer world) {
exec.logConsole("Startwert von %s: %d", world.dimension.getFormattedName(false), world.dimension.getSeed());
return world.dimension.getSeed();
}
}

View file

@ -2,14 +2,16 @@ package server.world;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.zip.GZIPInputStream;
@ -41,6 +43,7 @@ import common.block.natural.BlockSandStone;
import common.block.tech.BlockPistonBase;
import common.block.tech.BlockPistonHead;
import common.block.tech.BlockTNT;
import common.collect.Lists;
import common.collect.Maps;
import common.color.DyeColor;
import common.entity.Entity;
@ -66,6 +69,8 @@ import common.init.UniverseRegistry;
import common.log.Log;
import common.nbt.NBTLoader;
import common.nbt.NBTTagCompound;
import common.nbt.NBTTagDouble;
import common.nbt.NBTTagFloat;
import common.nbt.NBTTagList;
import common.rng.Random;
import common.tileentity.TileEntity;
@ -81,7 +86,6 @@ import common.tileentity.TileEntityFurnace;
import common.tileentity.TileEntityHopper;
import common.tileentity.TileEntityMobSpawner;
import common.tileentity.TileEntityNote;
import common.tileentity.TileEntityPiston;
import common.tileentity.TileEntitySign;
import common.tileentity.TileEntitySkull;
import common.util.Facing;
@ -92,6 +96,74 @@ import common.world.World;
import server.Server;
public abstract class Converter {
private static class OldNbtTag {
private final Map<String, Object> map = Maps.newHashMap();
private boolean has(String key, Class<?> type) {
Object tag = this.map.get(key);
return tag != null && tag.getClass() == type;
}
private List<?> getList(String key, Class<?> type) {
Object tag = this.map.get(key);
if(!(tag instanceof List))
return Lists.newArrayList();
List<?> list = (List<?>)tag;
return !list.isEmpty() && list.get(0).getClass() != type ? Lists.newArrayList() : list;
}
public byte getByte(String key) {
return !this.has(key, Byte.class) ? 0 : (Byte)this.map.get(key);
}
public int getInt(String key) {
return this.has(key, Integer.class) ? (Integer)this.map.get(key) : (this.has(key, Short.class) ? (Short)this.map.get(key) : this.getByte(key));
}
public String getString(String key) {
return !this.has(key, String.class) ? "" : (String)this.map.get(key);
}
public byte[] getByteArray(String key) {
return !this.has(key, byte[].class) ? new byte[0] : (byte[])this.map.get(key);
}
public int[] getIntArray(String key) {
return !this.has(key, int[].class) ? new int[0] : (int[])this.map.get(key);
}
public OldNbtTag getTag(String key) {
return !this.has(key, OldNbtTag.class) ? new OldNbtTag() : (OldNbtTag)this.map.get(key);
}
public float[] getFloatList(String key) {
List<?> list = this.getList(key, Float.class);
float[] values = new float[list.size()];
for(int z = 0; z < values.length; z++) {
values[z] = (Float)list.get(z);
}
return values;
}
public double[] getDoubleList(String key) {
List<?> list = this.getList(key, Double.class);
double[] values = new double[list.size()];
for(int z = 0; z < values.length; z++) {
values[z] = (Double)list.get(z);
}
return values;
}
public OldNbtTag[] getTagList(String key) {
List<?> list = this.getList(key, OldNbtTag.class);
OldNbtTag[] values = new OldNbtTag[list.size()];
for(int z = 0; z < values.length; z++) {
values[z] = (OldNbtTag)list.get(z);
}
return values;
}
}
private static enum SaveVersion {
ALPHA_1_0("Alpha 1.0 - Beta 1.2"),
BETA_1_3("Beta 1.3 - Release 1.8.9"),
@ -282,7 +354,7 @@ public abstract class Converter {
mapTile(TileEntitySign.class, "Sign", "sign");
mapTile(TileEntityMobSpawner.class, "MobSpawner", "mob_spawner");
mapTile(TileEntityNote.class, "Music", "noteblock");
mapTile(TileEntityPiston.class, "Piston", "piston");
// mapTile(TileEntityPiston.class, "Piston", "piston");
mapTile(TileEntityEnchantmentTable.class, "EnchantTable", "enchanting_table");
mapTile(TileEntityBeacon.class, "Beacon", "beacon");
mapTile(TileEntitySkull.class, "Skull", "skull");
@ -427,7 +499,7 @@ public abstract class Converter {
return Blocks.wool.getState().withProperty(BlockColored.COLOR, DyeColor.byMetadata(data));
}
}, 35);
mapBlockData(Blocks.piston_extension, 36);
mapBlock(Blocks.stone, 36); // mapBlockData(Blocks.piston_extension, 36);
mapBlock(Blocks.flower.getState().withProperty(Blocks.flower.getTypeProperty(), BlockFlower.EnumFlowerType.DANDELION), 37);
mapBlock(Blocks.flower.getState().withProperty(Blocks.flower.getTypeProperty(), BlockFlower.EnumFlowerType.POPPY),
38);
@ -802,10 +874,73 @@ public abstract class Converter {
mapBlock(Blocks.obsidian, 255);
}
private static void convertTile(NBTTagCompound ent) {
if("Sign".equals(ent.getString("id"))) {
// Log.debug("Konvertiere Schild bei "
// + ent.getInteger("x") + "," + ent.getInteger("y") + "," + ent.getInteger("z") + " ...");
private static Object read(DataInput input, byte id) throws IOException {
switch(id) {
case 0:
return null;
case 1:
return input.readByte();
case 2:
return input.readShort();
case 3:
return input.readInt();
case 4:
return input.readLong();
case 5:
return input.readFloat();
case 6:
return input.readDouble();
case 7: {
int len = input.readInt();
byte[] data = new byte[len];
input.readFully(data);
return data;
}
case 8:
return input.readUTF();
case 9: {
byte type = input.readByte();
int len = input.readInt();
if(type == 0 && len > 0)
throw new RuntimeException("Liste hat keinen Typ");
List<Object> list = new ArrayList<Object>(len);
for(int z = 0; z < len; z++) {
list.add(read(input, type));
}
return list;
}
case 10: {
OldNbtTag tag = new OldNbtTag();
byte type;
while((type = input.readByte()) != 0) {
String key = input.readUTF();
tag.map.put(key, read(input, type));
}
return tag;
}
case 11: {
int len = input.readInt();
int[] data = new int[len];
for(int z = 0; z < len; z++) {
data[z] = input.readInt();
}
return data;
}
default:
return null;
}
}
private static OldNbtTag readTag(DataInputStream in) throws IOException {
if(in.readByte() != 10)
throw new IOException("Tag hat den falschen Typ");
in.readUTF();
return (OldNbtTag)read(in, (byte)10);
}
private static NBTTagCompound convertTile(OldNbtTag ent, String id) {
NBTTagCompound nent = new NBTTagCompound();
if("Sign".equals(id)) {
String[] signText = new String[4];
for(int i = 0; i < 4; ++i) {
signText[i] = ent.getString("Text" + (i + 1));
@ -815,15 +950,12 @@ public abstract class Converter {
String[] old = new String[4];
for(int i = 0; i < 4; ++i) {
old[i] = signText[i];
// if(ChatFormat.hasLegacy(this.signText[i])) {
signText[i] = signText[i].indexOf('\u00A7') != -1 ? /* TextColor.replaceCodes( */
signText[i].replaceAll("\u00A7[0-9a-fA-Fk-oK-O]", "") /* .replace("\u00A7", "$$")) */ :
signText[i] = signText[i].indexOf('\u00A7') != -1 ?
signText[i].replaceAll("\u00A7[0-9a-fA-Fk-oK-O]", "") :
signText[i];
// }
if(signText[i].startsWith("{") && signText[i].endsWith("}")) {
try {
// TextComponent comp = TextSerializer.toComponent(signText[i]);
signText[i] = "<JSON>"; // comp.getFormattedText();
signText[i] = "<JSON>";
newComp++;
}
catch(Throwable e) {
@ -838,14 +970,21 @@ public abstract class Converter {
if(newComp == 4 && (quotes & (1 << i)) != 0) {
signText[i] = signText[i].substring(1, signText[i].length() - 1);
}
// if(old[i] != signText[i]) {
// Log.debug("Zeile " + (i + 1) + ": '" + TextColor.stripCodes(signText[i]) + "'");
// }
}
for(int i = 0; i < 4; ++i) {
ent.setString("Text" + (i + 1), signText[i]);
nent.setString("Text" + (i + 1), signText[i]);
}
}
else if("Comparator".equals(id)) {
nent.setInteger("OutputSignal", ent.getInt("OutputSignal"));
}
else if("Music".equals(id)) {
nent.setByte("note", ent.getByte("note"));
}
else if("Skull".equals(id)) {
nent.setByte("Rot", ent.getByte("Rot"));
}
return nent;
}
private static int getNibble(byte[] data, int x, int y, int z) {
@ -858,17 +997,32 @@ public abstract class Converter {
return idx >= 0 ? name.substring(idx + 1) : name; // save compat
}
private static NBTTagCompound convertChunkData(NBTTagCompound tag, boolean legacy) {
tag = tag.getCompoundTag("Level");
private static NBTTagList getList(float[] values) {
NBTTagList nlist = new NBTTagList();
for(int z = 0; z < values.length; z++) {
nlist.appendTag(new NBTTagFloat(values[z]));
}
return nlist;
}
private static NBTTagList getList(double[] values) {
NBTTagList nlist = new NBTTagList();
for(int z = 0; z < values.length; z++) {
nlist.appendTag(new NBTTagDouble(values[z]));
}
return nlist;
}
private static NBTTagCompound convertChunkData(OldNbtTag tag, boolean legacy) {
NBTTagCompound ntag = new NBTTagCompound();
tag = tag.getTag("Level");
if(legacy) {
if(tag.hasKey("LastUpdate", 3))
tag.setLong("LastUpdate", (long)tag.getInteger("LastUpdate"));
byte[] oldheight = tag.getByteArray("HeightMap");
int[] height = new int[oldheight.length];
for(int i = 0; i < oldheight.length; ++i) {
height[i] = oldheight[i];
}
tag.setIntArray("HeightMap", height);
ntag.setIntArray("HeightMap", height);
byte[] oldblks = tag.getByteArray("Blocks");
byte[] olddata = tag.getByteArray("Data");
byte[] oldsky = tag.getByteArray("SkyLight");
@ -914,54 +1068,65 @@ public abstract class Converter {
sections.appendTag(section);
}
}
tag.setTag("Sections", sections);
ntag.setTag("Sections", sections);
byte[] biomes = new byte[256];
Arrays.fill(biomes, (byte)(Biome.DEF_BIOME.id & 255));
tag.setByteArray("Biomes", biomes);
ntag.setByteArray("Biomes", biomes);
}
NBTTagList ents = tag.getTagList("Entities", 10);
else {
ntag.setIntArray("HeightMap", tag.getIntArray("HeightMap"));
}
ntag.setBoolean("TerrainPopulated", true);
ntag.setBoolean("LightPopulated", tag.getByte("LightPopulated") != 0);
OldNbtTag[] ents = tag.getTagList("Entities");
NBTTagList entities = new NBTTagList();
for(int z = 0; z < ents.tagCount(); z++) {
NBTTagCompound ent = ents.getCompoundTagAt(z);
for(OldNbtTag ent : ents) {
NBTTagCompound nent = new NBTTagCompound();
String mapped = ENTITY_MAP.get(trimColon(ent.getString("id")));
if(mapped != null) {
NBTTagList pos = ent.getTagList("Pos", 6);
NBTTagList motion = ent.getTagList("Motion", 6);
NBTTagList rotation = ent.getTagList("Rotation", 5);
boolean ground = ent.getBoolean("OnGround");
ent.getKeySet().clear();
ent.setTag("Pos", pos);
ent.setTag("Motion", motion);
ent.setTag("Rotation", rotation);
ent.setBoolean("OnGround", ground);
ent.setInteger("Dimension", 1);
ent.setString("id", mapped);
entities.appendTag(ent);
double[] pos = ent.getDoubleList("Pos");
double[] motion = ent.getDoubleList("Motion");
float[] rotation = ent.getFloatList("Rotation");
if(pos.length != 3 || motion.length != 3 || rotation.length != 2)
continue;
boolean ground = ent.getByte("OnGround") != 0;
nent.setTag("Pos", getList(pos));
nent.setTag("Motion", getList(motion));
nent.setTag("Rotation", getList(rotation));
nent.setBoolean("OnGround", ground);
nent.setInteger("Dimension", 1);
nent.setString("id", mapped);
entities.appendTag(nent);
}
}
tag.setTag("Entities", entities);
ntag.setTag("Entities", entities);
ents = tag.getTagList("TileEntities", 10);
ents = tag.getTagList("TileEntities");
entities = new NBTTagList();
for(int z = 0; z < ents.tagCount(); z++) {
NBTTagCompound ent = ents.getCompoundTagAt(z);
for(OldNbtTag ent : ents) {
NBTTagCompound nent = new NBTTagCompound();
String mapped = TILE_MAP.get(trimColon(ent.getString("id")));
if(mapped != null) {
ent.setString("id", mapped);
convertTile(ent);
entities.appendTag(ent);
nent = convertTile(ent, mapped);
nent.setString("id", mapped);
nent.setInteger("x", ent.getInt("x"));
nent.setInteger("y", ent.getInt("y"));
nent.setInteger("z", ent.getInt("z"));
entities.appendTag(nent);
}
}
tag.setTag("TileEntities", entities);
ntag.setTag("TileEntities", entities);
tag.removeTag("TileTicks");
NBTTagList sects = tag.getTagList("Sections", 10);
for(int n = 0; n < sects.tagCount(); ++n) {
NBTTagCompound sect = sects.getCompoundTagAt(n);
OldNbtTag[] sects = tag.getTagList("Sections");
entities = new NBTTagList();
for(OldNbtTag sect : sects) {
NBTTagCompound nsect = new NBTTagCompound();
byte[] blocks = sect.getByteArray("Blocks");
NibbleArray data = new NibbleArray(sect.getByteArray("Data"));
NibbleArray adddata = sect.hasKey("Add", 7) ? new NibbleArray(sect.getByteArray("Add")) : null;
byte[] add = sect.getByteArray("Add");
NibbleArray adddata = add.length > 0 ? new NibbleArray(add) : null;
for(int c = 0; c < blocks.length; ++c) {
int cx = c & 15;
int cy = c >> 8 & 15;
@ -992,12 +1157,14 @@ public abstract class Converter {
data.set(cx, cy, cz, cd & 15);
}
}
sect.setByteArray("Blocks", blocks);
sect.setByteArray("Data", data.getData());
nsect.setByteArray("Blocks", blocks);
nsect.setByteArray("Data", data.getData());
if(adddata != null)
sect.setByteArray("Add", adddata.getData());
nsect.setByteArray("Add", adddata.getData());
entities.appendTag(nsect);
}
return tag;
ntag.setTag("Sections", entities);
return ntag;
}
private static long convertChunks(File dir, File file, long start, int progress, int total) {
@ -1043,13 +1210,13 @@ public abstract class Converter {
Log.IO.warn("Konnte " + file.getPath() + "@" + x + "," + z + " nicht lesen");
continue;
}
NBTTagCompound tag = NBTLoader.read(in);
OldNbtTag tag = readTag(in);
in.close();
tag = convertChunkData(tag, legacy);
NBTTagCompound ntag = convertChunkData(tag, legacy);
// DataOutputStream out = newreg.getOutputStream(nx, nz);
// CompressedStreamTools.write(tag, out);
// out.close();
newreg.writeTag(nx, nz, tag);
newreg.writeTag(nx, nz, ntag);
}
}
}
@ -1081,27 +1248,34 @@ public abstract class Converter {
if(!ldat.exists())
return false;
Log.IO.info("Welt wird konvertiert");
NBTTagCompound nbt;
OldNbtTag nbt;
DataInputStream in = null;
try {
nbt = NBTLoader.readGZip(ldat);
in = new DataInputStream(new BufferedInputStream(new GZIPInputStream(new FileInputStream(ldat))));
nbt = readTag(in);
}
catch(Exception e) {
Log.IO.error(e, "Fehler beim Lesen von level.dat");
return false;
}
nbt = nbt.getCompoundTag("Data");
int version = nbt.getInteger("version");
int data = nbt.getInteger("DataVersion");
finally {
try {
if(in != null)
in.close();
}
catch(IOException e) {
}
}
nbt = nbt.getTag("Data");
int version = nbt.getInt("version");
int data = nbt.getInt("DataVersion");
// nbt.setBoolean("incompatible", data >= 1400);
SaveVersion ver = data >= 1400 ? SaveVersion.RELEASE_1_13 : (data >= 100 ? SaveVersion.RELEASE_1_9 : (version == 19132 || version == 19133 ? SaveVersion.BETA_1_3 : (version == 0 ? SaveVersion.ALPHA_1_0 : null)));
if(ver == null) {
Log.IO.error("Version %d ist unbekannt", version);
return false;
}
long wtime = nbt.getLong(nbt.hasKey("DayTime", 99) ? "DayTime" : "Time") + World.START_TIME;
Log.IO.info("Version: %s", ver);
Log.IO.info("Weltzeit: %d Ticks / %d Sekunden", wtime, wtime / 20L);
Log.IO.info("Zuletzt geladen: %s", new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(new Date(nbt.getLong("LastPlayed"))));
if(ver != SaveVersion.RELEASE_1_13) {
Log.IO.info("Konvertiere Chunk-Daten von region/*.mca,*.mcr");
File regionDir = new File("region");
@ -1143,16 +1317,14 @@ public abstract class Converter {
Log.IO.info("Konvertiere Daten von level.dat");
Config.clear();
UniverseRegistry.clear();
if(nbt.hasKey("GameRules", 10)) {
NBTTagCompound rules = nbt.getCompoundTag("GameRules");
for(Entry<String, String> rule : OLD_GAMERULES.entrySet()) {
if(rules.hasKey(rule.getKey(), 8))
Config.set(rule.getValue(), rules.getString(rule.getKey()), false);
}
OldNbtTag rules = nbt.getTag("GameRules");
for(Entry<String, String> rule : OLD_GAMERULES.entrySet()) {
if(!rules.getString(rule.getKey()).isEmpty())
Config.set(rule.getValue(), rules.getString(rule.getKey()), false);
}
Log.IO.info("Speichere neue server.nbt ...");
Server.saveServerConfig(wtime);
Weather weather = nbt.getBoolean("thundering") ? Weather.THUNDER : (nbt.getBoolean("raining") ? Weather.RAIN : Weather.CLEAR);
Server.saveServerConfig(World.START_TIME);
Weather weather = nbt.getByte("thundering") != 0 ? Weather.THUNDER : (nbt.getByte("raining") != 0 ? Weather.RAIN : Weather.CLEAR);
if(weather != Weather.CLEAR) {
NBTTagCompound dataTag = new NBTTagCompound();
dataTag.setString("Weather", weather.getName());