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 MINOR = 3;
|
||||
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() {
|
||||
Region.loadMaps();
|
||||
|
||||
File file = new File("server.cdt");
|
||||
if(!file.exists())
|
||||
file = new File("server.cdt.tmp");
|
||||
|
@ -406,6 +404,7 @@ public final class Server implements IThreadListener, Executor {
|
|||
}
|
||||
|
||||
public void run(long time) {
|
||||
Region.loadMap();
|
||||
Converter.convert(this);
|
||||
long wtime = this.loadServerConfig();
|
||||
if(this.keyPair == null) {
|
||||
|
|
|
@ -17,7 +17,6 @@ import java.util.Map.Entry;
|
|||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
import common.Version;
|
||||
import common.biome.Biome;
|
||||
import common.block.Block;
|
||||
import common.block.BlockColored;
|
||||
|
@ -1092,6 +1091,7 @@ public abstract class Converter {
|
|||
|
||||
NbtTag[] sects = tag.getTagList("Sections");
|
||||
entities = Lists.newArrayList();
|
||||
char[] mapping = Region.getEncodeMap();
|
||||
for(NbtTag sect : sects) {
|
||||
TagObject nsect = new TagObject();
|
||||
nsect.setInt("Y", sect.getByte("Y"));
|
||||
|
@ -1105,39 +1105,25 @@ public abstract class Converter {
|
|||
int cz = c >> 4 & 15;
|
||||
int ca = adddata != null ? adddata.get(cx, cy, cz) : 0;
|
||||
char block = (char)((ca << 8) | (blocks[c] & 255));
|
||||
// if(block == 0)
|
||||
// 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);
|
||||
char cd = 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(adddata == null)
|
||||
adddata = new NibbleArray();
|
||||
adddata.set(cx, cy, cz, cd >> 12);
|
||||
}
|
||||
blocks[c] = (byte)(cd >> 4 & 255);
|
||||
data.set(cx, cy, cz, cd & 15);
|
||||
if(block == 0)
|
||||
continue;
|
||||
int dt = block == 111 ? RANDOM.zrange(4) : data.get(cx, cy, cz);
|
||||
char cd = mapping[block >= 256 ? BLOCK_MAP[1 << 4] : BLOCK_MAP[(block << 4) | dt]];
|
||||
if(cd >> 12 != 0) {
|
||||
if(adddata == null)
|
||||
adddata = new NibbleArray();
|
||||
adddata.set(cx, cy, cz, cd >> 12);
|
||||
}
|
||||
blocks[c] = (byte)(cd & 255);
|
||||
data.set(cx, cy, cz, cd >> 8 & 15);
|
||||
}
|
||||
nsect.setByteArray("Blocks", blocks);
|
||||
nsect.setByteArray("Data", data.getData());
|
||||
nsect.setByteArray("Dat0", blocks);
|
||||
nsect.setByteArray("Dat1", data.getData());
|
||||
if(adddata != null)
|
||||
nsect.setByteArray("Add", adddata.getData());
|
||||
nsect.setByteArray("Dat2", adddata.getData());
|
||||
entities.add(nsect);
|
||||
}
|
||||
ntag.setList("Sections", entities);
|
||||
|
||||
ntag.setInt("Version", Version.DATA);
|
||||
return ntag;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.util.Set;
|
|||
import java.util.zip.DeflaterOutputStream;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
import common.Version;
|
||||
import common.block.Block;
|
||||
import common.collect.Lists;
|
||||
import common.collect.Maps;
|
||||
|
@ -74,83 +73,97 @@ public class Region {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
private static TagObject makeMap() {
|
||||
TagObject tag = new TagObject();
|
||||
private static boolean makeMap(TagObject tag) {
|
||||
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++) {
|
||||
Block block = BlockRegistry.getBlockById(z);
|
||||
if(block != Blocks.air) {
|
||||
Set<IProperty> stored = getSavedProperties(block);
|
||||
for(int n = 0; n < 16; n++) {
|
||||
String id = filterProperties(block.getStateFromMeta(n), stored);
|
||||
MAPPING.put(id, (char)z);
|
||||
tag.setChar(id, (char)z);
|
||||
// Log.IO.info("Block-ID %d:%d [%d] = %s", z, n, z << 4 | n, id);
|
||||
State state = block.getStateFromMeta(n);
|
||||
String id = filterProperties(state, stored);
|
||||
List<Character> ids = current.get(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;
|
||||
}
|
||||
|
||||
private static void cacheMap(TagObject tag, int version) {
|
||||
char[] map = new char[65536];
|
||||
for(String key : tag.keySet()) {
|
||||
if(tag.hasChar(key))
|
||||
map[tag.getChar(key)] = MAPPING.getOrDefault(key, (char)0);
|
||||
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);
|
||||
}
|
||||
MAPS.put(version, map);
|
||||
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();
|
||||
}
|
||||
|
||||
public static void loadMaps() {
|
||||
TagObject map = makeMap();
|
||||
File mapFile = new File(new File("mapping"), "m." + Version.DATA + ".cdt");
|
||||
if(!mapFile.exists()) {
|
||||
mapFile.getParentFile().mkdirs();
|
||||
public static void loadMap() {
|
||||
File mapFile = new File("blocks.cdt");
|
||||
TagObject tag;
|
||||
if(mapFile.exists()) {
|
||||
try {
|
||||
TagObject.writeGZip(map, mapFile);
|
||||
tag = TagObject.readGZip(mapFile);
|
||||
}
|
||||
catch(Exception e) {
|
||||
Log.IO.error(e, "Fehler beim Schreiben von " + mapFile);
|
||||
tag = new TagObject();
|
||||
Log.IO.error(e, "Fehler beim Lesen von %s", 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;
|
||||
try {
|
||||
tag = TagObject.readGZip(file);
|
||||
}
|
||||
catch(Exception e) {
|
||||
Log.IO.error(e, "Fehler beim Lesen von " + file);
|
||||
continue;
|
||||
}
|
||||
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) {
|
||||
char[] map = MAPS.get(version);
|
||||
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;
|
||||
public static char[] getEncodeMap() {
|
||||
return ENCODE_MAP;
|
||||
}
|
||||
|
||||
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 List<WorldServer> QUEUE = Collections.<WorldServer>synchronizedList(Lists.<WorldServer>newArrayList());
|
||||
private static final Map<Integer, char[]> MAPS = Maps.newHashMap();
|
||||
private static final Map<String, Character> MAPPING = Maps.newHashMap();
|
||||
private static final char[] DECODE_MAP = new char[65536];
|
||||
private static final char[] ENCODE_MAP = new char[65536];
|
||||
|
||||
private static volatile long queued;
|
||||
private static volatile long saved;
|
||||
|
@ -502,9 +515,9 @@ public class Region {
|
|||
TagObject sect = sects.get(n);
|
||||
int y = sect.getInt("Y");
|
||||
BlockArray storage = new BlockArray(y << 4, light, null);
|
||||
byte[] blocks = sect.getByteArray("Blocks");
|
||||
NibbleArray data = new NibbleArray(sect.getByteArray("Data"));
|
||||
NibbleArray adddata = sect.hasByteArray("Add") ? new NibbleArray(sect.getByteArray("Add")) : null;
|
||||
byte[] blocks = sect.getByteArray("Dat0");
|
||||
NibbleArray data = new NibbleArray(sect.getByteArray("Dat1"));
|
||||
NibbleArray adddata = sect.hasByteArray("Dat2") ? new NibbleArray(sect.getByteArray("Dat2")) : null;
|
||||
char[] seg = new char[blocks.length];
|
||||
|
||||
for(int c = 0; c < seg.length; ++c) {
|
||||
|
@ -512,11 +525,8 @@ public class Region {
|
|||
int cy = c >> 8 & 15;
|
||||
int cz = c >> 4 & 15;
|
||||
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.setBlocklight(new NibbleArray(sect.getByteArray("BlockLight")));
|
||||
|
@ -602,7 +612,6 @@ public class Region {
|
|||
|
||||
public static TagObject writeChunk(WorldServer world, ChunkServer chunk) {
|
||||
TagObject tag = new TagObject();
|
||||
tag.setInt("Version", Version.DATA);
|
||||
tag.setLong("LastUpdate", world.getTime());
|
||||
tag.setIntArray("HeightMap", chunk.getHeights());
|
||||
tag.setBool("TerrainPopulated", chunk.isTerrainPopulated());
|
||||
|
@ -621,7 +630,7 @@ public class Region {
|
|||
NibbleArray adddata = null;
|
||||
|
||||
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 cy = c >> 8 & 15;
|
||||
int cz = c >> 4 & 15;
|
||||
|
@ -634,15 +643,15 @@ public class Region {
|
|||
adddata.set(cx, cy, cz, cd >> 12);
|
||||
}
|
||||
|
||||
blocks[c] = (byte)(cd >> 4 & 255);
|
||||
data.set(cx, cy, cz, cd & 15);
|
||||
blocks[c] = (byte)(cd & 255);
|
||||
data.set(cx, cy, cz, cd >> 8 & 15);
|
||||
}
|
||||
|
||||
sect.setByteArray("Blocks", blocks);
|
||||
sect.setByteArray("Data", data.getData());
|
||||
sect.setByteArray("Dat0", blocks);
|
||||
sect.setByteArray("Dat1", data.getData());
|
||||
|
||||
if(adddata != null) {
|
||||
sect.setByteArray("Add", adddata.getData());
|
||||
sect.setByteArray("Dat2", adddata.getData());
|
||||
}
|
||||
|
||||
sect.setByteArray("BlockLight", storage.getBlocklight().getData());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue