add block map (will reimplement this)

This commit is contained in:
Sen 2025-06-19 16:21:15 +02:00
parent 9930d1bb6d
commit 64cff6a171
Signed by: sen
GPG key ID: 3AC50A6F47D1B722
4 changed files with 133 additions and 1 deletions

View file

@ -8,4 +8,6 @@ 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;
}

View file

@ -215,6 +215,8 @@ 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");

View file

@ -17,6 +17,7 @@ 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;
@ -1135,6 +1136,8 @@ public abstract class Converter {
entities.add(nsect);
}
ntag.setList("Sections", entities);
ntag.setInt("Version", Version.DATA);
return ntag;
}

View file

@ -14,26 +14,145 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
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;
import common.collect.Sets;
import common.entity.Entity;
import common.init.BlockRegistry;
import common.init.Blocks;
import common.init.EntityRegistry;
import common.log.Log;
import common.properties.IProperty;
import common.tags.TagObject;
import common.tileentity.TileEntity;
import common.util.BlockPos;
import common.util.NibbleArray;
import common.util.Util;
import common.world.BlockArray;
import common.world.State;
public class Region {
private static Set<IProperty> getSavedProperties(Block block) {
Set<IProperty> stored = Sets.newHashSet();
Map<IProperty, Comparable> map = Maps.newHashMap();
for(int z = 0; z < 16; z++) {
State sub = block.getStateFromMeta(z);
for(Entry<IProperty, Comparable> entry : sub.getProperties().entrySet()) {
if(map.containsKey(entry.getKey())) {
if(!map.get(entry.getKey()).equals(entry.getValue()))
stored.add(entry.getKey());
}
else {
map.put(entry.getKey(), entry.getValue());
}
}
}
for(int z = 0; z < 16; z++) {
State sub = block.getStateFromMeta(z);
Map<IProperty, Comparable> smap = sub.getProperties();
for(IProperty prop : map.keySet()) {
if(!smap.containsKey(prop))
stored.add(prop);
}
}
return stored;
}
private static String filterProperties(State state, Set<IProperty> stored) {
StringBuilder sb = new StringBuilder(BlockRegistry.getNameFromBlock(state.getBlock()));
for(Entry<IProperty, Comparable> entry : state.getProperties().entrySet()) {
if(stored.contains(entry.getKey()))
sb.append(',').append(entry.getKey().getName()).append('=').append(entry.getKey().getName(entry.getValue()));
}
return sb.toString();
}
private static TagObject makeMap() {
TagObject tag = new TagObject();
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);
}
}
}
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);
}
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;
try {
tag = TagObject.readGZip(file);
}
catch(Exception e) {
Log.IO.error(e, "Fehler beim Lesen von " + file);
continue;
}
cacheMap(tag, version);
}
}
}
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;
}
private static class ChunkBuffer extends ByteArrayOutputStream {
public ChunkBuffer() {
super(8096);
@ -58,6 +177,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 volatile long queued;
private static volatile long saved;
@ -367,6 +488,7 @@ public class Region {
Log.IO.warn("Chunk-Datei bei " + x + "," + z + " hat keine Block-Daten, überspringe");
return null;
}
int version = tag.getInt("Version");
ChunkServer chunk = new ChunkServer(world, x, z);
chunk.setHeights(tag.getIntArray("HeightMap"));
chunk.setTerrainPopulated(tag.getBool("TerrainPopulated"));
@ -392,6 +514,9 @@ public class Region {
int ca = adddata != null ? adddata.get(cx, cy, cz) : 0;
seg[c] = (char)(ca << 12 | (blocks[c] & 255) << 4 | data.get(cx, cy, cz));
}
// if(version != Version.DATA)
// remap(seg, version, x, z);
storage.setData(seg);
storage.setBlocklight(new NibbleArray(sect.getByteArray("BlockLight")));
@ -477,7 +602,7 @@ public class Region {
public static TagObject writeChunk(WorldServer world, ChunkServer chunk) {
TagObject tag = new TagObject();
// tag.setShort("V", (short)Config.PROTOCOL);
tag.setInt("Version", Version.DATA);
tag.setLong("LastUpdate", world.getTime());
tag.setIntArray("HeightMap", chunk.getHeights());
tag.setBool("TerrainPopulated", chunk.isTerrainPopulated());