add block map properly
This commit is contained in:
parent
64cff6a171
commit
dd3ac39530
4 changed files with 98 additions and 106 deletions
|
@ -8,6 +8,4 @@ public abstract class Version {
|
||||||
public static final int MAJOR = 2;
|
public static final int MAJOR = 2;
|
||||||
public static final int MINOR = 3;
|
public static final int MINOR = 3;
|
||||||
public static final int PATCH = 0;
|
public static final int PATCH = 0;
|
||||||
|
|
||||||
public static final int DATA = 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,8 +215,6 @@ public final class Server implements IThreadListener, Executor {
|
||||||
}
|
}
|
||||||
|
|
||||||
private long loadServerConfig() {
|
private long loadServerConfig() {
|
||||||
Region.loadMaps();
|
|
||||||
|
|
||||||
File file = new File("server.cdt");
|
File file = new File("server.cdt");
|
||||||
if(!file.exists())
|
if(!file.exists())
|
||||||
file = new File("server.cdt.tmp");
|
file = new File("server.cdt.tmp");
|
||||||
|
@ -406,6 +404,7 @@ public final class Server implements IThreadListener, Executor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run(long time) {
|
public void run(long time) {
|
||||||
|
Region.loadMap();
|
||||||
Converter.convert(this);
|
Converter.convert(this);
|
||||||
long wtime = this.loadServerConfig();
|
long wtime = this.loadServerConfig();
|
||||||
if(this.keyPair == null) {
|
if(this.keyPair == null) {
|
||||||
|
|
|
@ -17,7 +17,6 @@ import java.util.Map.Entry;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
import java.util.zip.InflaterInputStream;
|
import java.util.zip.InflaterInputStream;
|
||||||
|
|
||||||
import common.Version;
|
|
||||||
import common.biome.Biome;
|
import common.biome.Biome;
|
||||||
import common.block.Block;
|
import common.block.Block;
|
||||||
import common.block.BlockColored;
|
import common.block.BlockColored;
|
||||||
|
@ -1092,6 +1091,7 @@ public abstract class Converter {
|
||||||
|
|
||||||
NbtTag[] sects = tag.getTagList("Sections");
|
NbtTag[] sects = tag.getTagList("Sections");
|
||||||
entities = Lists.newArrayList();
|
entities = Lists.newArrayList();
|
||||||
|
char[] mapping = Region.getEncodeMap();
|
||||||
for(NbtTag sect : sects) {
|
for(NbtTag sect : sects) {
|
||||||
TagObject nsect = new TagObject();
|
TagObject nsect = new TagObject();
|
||||||
nsect.setInt("Y", sect.getByte("Y"));
|
nsect.setInt("Y", sect.getByte("Y"));
|
||||||
|
@ -1105,39 +1105,25 @@ public abstract class Converter {
|
||||||
int cz = c >> 4 & 15;
|
int cz = c >> 4 & 15;
|
||||||
int ca = adddata != null ? adddata.get(cx, cy, cz) : 0;
|
int ca = adddata != null ? adddata.get(cx, cy, cz) : 0;
|
||||||
char block = (char)((ca << 8) | (blocks[c] & 255));
|
char block = (char)((ca << 8) | (blocks[c] & 255));
|
||||||
// if(block == 0)
|
if(block == 0)
|
||||||
// continue;
|
continue;
|
||||||
//// else if(block <= 197) {
|
|
||||||
//// if((blocks[c] = BLOCK_MAP[block]) != (byte)block)
|
|
||||||
//// data.set(cx, cy, cz, DATA_MAP[block]);
|
|
||||||
//// }
|
|
||||||
if(block >= 256) {
|
|
||||||
blocks[c] = (byte)1;
|
|
||||||
data.set(cx, cy, cz, 0);
|
|
||||||
}
|
|
||||||
else if(block > 0) {
|
|
||||||
int dt = block == 111 ? RANDOM.zrange(4) : data.get(cx, cy, cz);
|
int dt = block == 111 ? RANDOM.zrange(4) : data.get(cx, cy, cz);
|
||||||
char cd = BLOCK_MAP[(block << 4) | dt];
|
char cd = mapping[block >= 256 ? BLOCK_MAP[1 << 4] : BLOCK_MAP[(block << 4) | dt]];
|
||||||
// if(cd == (char)0x000f)
|
|
||||||
// cd = (char)BlockRegistry.STATEMAP.get(BLOCK_FUNCS.get((char)((block << 4) | dt)).getState(block, dt));
|
|
||||||
if(cd >> 12 != 0) {
|
if(cd >> 12 != 0) {
|
||||||
if(adddata == null)
|
if(adddata == null)
|
||||||
adddata = new NibbleArray();
|
adddata = new NibbleArray();
|
||||||
adddata.set(cx, cy, cz, cd >> 12);
|
adddata.set(cx, cy, cz, cd >> 12);
|
||||||
}
|
}
|
||||||
blocks[c] = (byte)(cd >> 4 & 255);
|
blocks[c] = (byte)(cd & 255);
|
||||||
data.set(cx, cy, cz, cd & 15);
|
data.set(cx, cy, cz, cd >> 8 & 15);
|
||||||
}
|
}
|
||||||
}
|
nsect.setByteArray("Dat0", blocks);
|
||||||
nsect.setByteArray("Blocks", blocks);
|
nsect.setByteArray("Dat1", data.getData());
|
||||||
nsect.setByteArray("Data", data.getData());
|
|
||||||
if(adddata != null)
|
if(adddata != null)
|
||||||
nsect.setByteArray("Add", adddata.getData());
|
nsect.setByteArray("Dat2", adddata.getData());
|
||||||
entities.add(nsect);
|
entities.add(nsect);
|
||||||
}
|
}
|
||||||
ntag.setList("Sections", entities);
|
ntag.setList("Sections", entities);
|
||||||
|
|
||||||
ntag.setInt("Version", Version.DATA);
|
|
||||||
return ntag;
|
return ntag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ import java.util.Set;
|
||||||
import java.util.zip.DeflaterOutputStream;
|
import java.util.zip.DeflaterOutputStream;
|
||||||
import java.util.zip.InflaterInputStream;
|
import java.util.zip.InflaterInputStream;
|
||||||
|
|
||||||
import common.Version;
|
|
||||||
import common.block.Block;
|
import common.block.Block;
|
||||||
import common.collect.Lists;
|
import common.collect.Lists;
|
||||||
import common.collect.Maps;
|
import common.collect.Maps;
|
||||||
|
@ -74,83 +73,97 @@ public class Region {
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TagObject makeMap() {
|
private static boolean makeMap(TagObject tag) {
|
||||||
TagObject tag = new TagObject();
|
Map<String, Character> mapping = Maps.newHashMap();
|
||||||
|
Map<String, List<Character>> current = Maps.newHashMap();
|
||||||
|
Set<Character> taken = Sets.newHashSet();
|
||||||
|
List<String> missing = Lists.newArrayList();
|
||||||
for(int z = 0; z < 4096; z++) {
|
for(int z = 0; z < 4096; z++) {
|
||||||
Block block = BlockRegistry.getBlockById(z);
|
Block block = BlockRegistry.getBlockById(z);
|
||||||
if(block != Blocks.air) {
|
if(block != Blocks.air) {
|
||||||
Set<IProperty> stored = getSavedProperties(block);
|
Set<IProperty> stored = getSavedProperties(block);
|
||||||
for(int n = 0; n < 16; n++) {
|
for(int n = 0; n < 16; n++) {
|
||||||
String id = filterProperties(block.getStateFromMeta(n), stored);
|
State state = block.getStateFromMeta(n);
|
||||||
MAPPING.put(id, (char)z);
|
String id = filterProperties(state, stored);
|
||||||
tag.setChar(id, (char)z);
|
List<Character> ids = current.get(id);
|
||||||
// Log.IO.info("Block-ID %d:%d [%d] = %s", z, n, z << 4 | n, id);
|
char mid = (char)BlockRegistry.STATEMAP.get(state);
|
||||||
|
if(ids == null) {
|
||||||
|
current.put(id, Lists.newArrayList(mid));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ids.add(mid);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(tag.hasChar(id)) {
|
||||||
|
char bid = tag.getChar(id);
|
||||||
|
if(bid == 0) {
|
||||||
|
missing.add(id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
mapping.put(id, bid);
|
||||||
|
taken.add(bid);
|
||||||
|
tag.remove(id);
|
||||||
|
Log.IO.debug("Bestehende Block-ID %d = %s", (int)bid, id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
missing.add(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tag;
|
}
|
||||||
|
char bid = 1;
|
||||||
|
for(String id : missing) {
|
||||||
|
while(taken.contains(bid)) {
|
||||||
|
++bid;
|
||||||
|
}
|
||||||
|
mapping.put(id, bid);
|
||||||
|
tag.setChar(id, bid);
|
||||||
|
taken.add(bid);
|
||||||
|
Log.IO.debug("Neue Block-ID %d = %s", (int)bid, id);
|
||||||
|
}
|
||||||
|
for(Entry<String, Character> entry : mapping.entrySet()) {
|
||||||
|
bid = entry.getValue();
|
||||||
|
List<Character> ids = current.get(entry.getKey());
|
||||||
|
DECODE_MAP[bid] = ids.get(0);
|
||||||
|
for(char id : ids) {
|
||||||
|
ENCODE_MAP[id] = bid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(String id : tag.keySet()) {
|
||||||
|
if(tag.hasChar(id))
|
||||||
|
Log.IO.debug("Entfernte Block-ID %d = %s", (int)tag.getChar(id), id);
|
||||||
|
}
|
||||||
|
return !missing.isEmpty() || !tag.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void cacheMap(TagObject tag, int version) {
|
public static void loadMap() {
|
||||||
char[] map = new char[65536];
|
File mapFile = new File("blocks.cdt");
|
||||||
for(String key : tag.keySet()) {
|
|
||||||
if(tag.hasChar(key))
|
|
||||||
map[tag.getChar(key)] = MAPPING.getOrDefault(key, (char)0);
|
|
||||||
}
|
|
||||||
MAPS.put(version, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void loadMaps() {
|
|
||||||
TagObject map = makeMap();
|
|
||||||
File mapFile = new File(new File("mapping"), "m." + Version.DATA + ".cdt");
|
|
||||||
if(!mapFile.exists()) {
|
|
||||||
mapFile.getParentFile().mkdirs();
|
|
||||||
try {
|
|
||||||
TagObject.writeGZip(map, mapFile);
|
|
||||||
}
|
|
||||||
catch(Exception e) {
|
|
||||||
Log.IO.error(e, "Fehler beim Schreiben von " + mapFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File[] maps = new File("mapping").listFiles(file -> file.isFile() && file.getName().startsWith("m.") && file.getName().endsWith(".cdt"));
|
|
||||||
if(maps != null) {
|
|
||||||
for(File file : maps) {
|
|
||||||
String str = file.getName().substring(2, file.getName().length() - 4);
|
|
||||||
if(str.isEmpty())
|
|
||||||
continue;
|
|
||||||
int version;
|
|
||||||
try {
|
|
||||||
version = Integer.parseUnsignedInt(str);
|
|
||||||
}
|
|
||||||
catch(NumberFormatException e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(version == Version.DATA)
|
|
||||||
continue;
|
|
||||||
TagObject tag;
|
TagObject tag;
|
||||||
|
if(mapFile.exists()) {
|
||||||
try {
|
try {
|
||||||
tag = TagObject.readGZip(file);
|
tag = TagObject.readGZip(mapFile);
|
||||||
}
|
}
|
||||||
catch(Exception e) {
|
catch(Exception e) {
|
||||||
Log.IO.error(e, "Fehler beim Lesen von " + file);
|
tag = new TagObject();
|
||||||
continue;
|
Log.IO.error(e, "Fehler beim Lesen von %s", mapFile);
|
||||||
}
|
}
|
||||||
cacheMap(tag, version);
|
}
|
||||||
|
else {
|
||||||
|
tag = new TagObject();
|
||||||
|
}
|
||||||
|
if(makeMap(tag)) {
|
||||||
|
Log.IO.info("Block-IDs haben sich geändert, schreibe %s", mapFile);
|
||||||
|
try {
|
||||||
|
TagObject.writeGZip(tag, mapFile);
|
||||||
|
}
|
||||||
|
catch(Exception e) {
|
||||||
|
Log.IO.error(e, "Fehler beim Schreiben von %s", mapFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean remap(char[] data, int version, int x, int z) {
|
public static char[] getEncodeMap() {
|
||||||
char[] map = MAPS.get(version);
|
return ENCODE_MAP;
|
||||||
if(map == null) {
|
|
||||||
Log.IO.error("Chunk %d, %d: Konnte keine Block-Datenbank für Version #%d finden", x, z, version);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Log.IO.info("Chunk %d, %d: Konvertiere Block-IDs von Version #%d zu #%d", x, z, version, Version.DATA);
|
|
||||||
for(int n = 0; n < data.length; n++) {
|
|
||||||
data[n] = map[data[n]];
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ChunkBuffer extends ByteArrayOutputStream {
|
private static class ChunkBuffer extends ByteArrayOutputStream {
|
||||||
|
@ -177,8 +190,8 @@ public class Region {
|
||||||
|
|
||||||
private static final Map<String, Region> CACHE = Maps.<String, Region>newHashMap();
|
private static final Map<String, Region> CACHE = Maps.<String, Region>newHashMap();
|
||||||
private static final List<WorldServer> QUEUE = Collections.<WorldServer>synchronizedList(Lists.<WorldServer>newArrayList());
|
private static final List<WorldServer> QUEUE = Collections.<WorldServer>synchronizedList(Lists.<WorldServer>newArrayList());
|
||||||
private static final Map<Integer, char[]> MAPS = Maps.newHashMap();
|
private static final char[] DECODE_MAP = new char[65536];
|
||||||
private static final Map<String, Character> MAPPING = Maps.newHashMap();
|
private static final char[] ENCODE_MAP = new char[65536];
|
||||||
|
|
||||||
private static volatile long queued;
|
private static volatile long queued;
|
||||||
private static volatile long saved;
|
private static volatile long saved;
|
||||||
|
@ -502,9 +515,9 @@ public class Region {
|
||||||
TagObject sect = sects.get(n);
|
TagObject sect = sects.get(n);
|
||||||
int y = sect.getInt("Y");
|
int y = sect.getInt("Y");
|
||||||
BlockArray storage = new BlockArray(y << 4, light, null);
|
BlockArray storage = new BlockArray(y << 4, light, null);
|
||||||
byte[] blocks = sect.getByteArray("Blocks");
|
byte[] blocks = sect.getByteArray("Dat0");
|
||||||
NibbleArray data = new NibbleArray(sect.getByteArray("Data"));
|
NibbleArray data = new NibbleArray(sect.getByteArray("Dat1"));
|
||||||
NibbleArray adddata = sect.hasByteArray("Add") ? new NibbleArray(sect.getByteArray("Add")) : null;
|
NibbleArray adddata = sect.hasByteArray("Dat2") ? new NibbleArray(sect.getByteArray("Dat2")) : null;
|
||||||
char[] seg = new char[blocks.length];
|
char[] seg = new char[blocks.length];
|
||||||
|
|
||||||
for(int c = 0; c < seg.length; ++c) {
|
for(int c = 0; c < seg.length; ++c) {
|
||||||
|
@ -512,12 +525,9 @@ public class Region {
|
||||||
int cy = c >> 8 & 15;
|
int cy = c >> 8 & 15;
|
||||||
int cz = c >> 4 & 15;
|
int cz = c >> 4 & 15;
|
||||||
int ca = adddata != null ? adddata.get(cx, cy, cz) : 0;
|
int ca = adddata != null ? adddata.get(cx, cy, cz) : 0;
|
||||||
seg[c] = (char)(ca << 12 | (blocks[c] & 255) << 4 | data.get(cx, cy, cz));
|
seg[c] = DECODE_MAP[ca << 12 | data.get(cx, cy, cz) << 8 | (blocks[c] & 255)];
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(version != Version.DATA)
|
|
||||||
// remap(seg, version, x, z);
|
|
||||||
|
|
||||||
storage.setData(seg);
|
storage.setData(seg);
|
||||||
storage.setBlocklight(new NibbleArray(sect.getByteArray("BlockLight")));
|
storage.setBlocklight(new NibbleArray(sect.getByteArray("BlockLight")));
|
||||||
|
|
||||||
|
@ -602,7 +612,6 @@ public class Region {
|
||||||
|
|
||||||
public static TagObject writeChunk(WorldServer world, ChunkServer chunk) {
|
public static TagObject writeChunk(WorldServer world, ChunkServer chunk) {
|
||||||
TagObject tag = new TagObject();
|
TagObject tag = new TagObject();
|
||||||
tag.setInt("Version", Version.DATA);
|
|
||||||
tag.setLong("LastUpdate", world.getTime());
|
tag.setLong("LastUpdate", world.getTime());
|
||||||
tag.setIntArray("HeightMap", chunk.getHeights());
|
tag.setIntArray("HeightMap", chunk.getHeights());
|
||||||
tag.setBool("TerrainPopulated", chunk.isTerrainPopulated());
|
tag.setBool("TerrainPopulated", chunk.isTerrainPopulated());
|
||||||
|
@ -621,7 +630,7 @@ public class Region {
|
||||||
NibbleArray adddata = null;
|
NibbleArray adddata = null;
|
||||||
|
|
||||||
for(int c = 0; c < storage.getData().length; ++c) {
|
for(int c = 0; c < storage.getData().length; ++c) {
|
||||||
char cd = storage.getData()[c];
|
char cd = ENCODE_MAP[storage.getData()[c]];
|
||||||
int cx = c & 15;
|
int cx = c & 15;
|
||||||
int cy = c >> 8 & 15;
|
int cy = c >> 8 & 15;
|
||||||
int cz = c >> 4 & 15;
|
int cz = c >> 4 & 15;
|
||||||
|
@ -634,15 +643,15 @@ public class Region {
|
||||||
adddata.set(cx, cy, cz, cd >> 12);
|
adddata.set(cx, cy, cz, cd >> 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
blocks[c] = (byte)(cd >> 4 & 255);
|
blocks[c] = (byte)(cd & 255);
|
||||||
data.set(cx, cy, cz, cd & 15);
|
data.set(cx, cy, cz, cd >> 8 & 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
sect.setByteArray("Blocks", blocks);
|
sect.setByteArray("Dat0", blocks);
|
||||||
sect.setByteArray("Data", data.getData());
|
sect.setByteArray("Dat1", data.getData());
|
||||||
|
|
||||||
if(adddata != null) {
|
if(adddata != null) {
|
||||||
sect.setByteArray("Add", adddata.getData());
|
sect.setByteArray("Dat2", adddata.getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
sect.setByteArray("BlockLight", storage.getBlocklight().getData());
|
sect.setByteArray("BlockLight", storage.getBlocklight().getData());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue