use of cn.nukkit.level.format.LevelProvider in project Nukkit by Nukkit.
the class LevelProviderConverter method perform.
LevelProvider perform() throws IOException {
new File(path).mkdir();
File dat = new File(provider.getPath(), "level.dat.old");
new File(provider.getPath(), "level.dat").renameTo(dat);
Utils.copyFile(dat, new File(path, "level.dat"));
LevelProvider result;
try {
if (provider instanceof LevelDB) {
try (FileInputStream stream = new FileInputStream(path + "level.dat")) {
stream.skip(8);
CompoundTag levelData = NBTIO.read(stream, ByteOrder.LITTLE_ENDIAN);
if (levelData != null) {
NBTIO.writeGZIPCompressed(new CompoundTag().putCompound("Data", levelData), new FileOutputStream(path + "level.dat"));
} else {
throw new IOException("LevelData can not be null");
}
} catch (IOException e) {
throw new LevelException("Invalid level.dat");
}
}
result = toClass.getConstructor(Level.class, String.class).newInstance(level, path);
} catch (Exception e) {
throw new RuntimeException(e);
}
if (toClass == Anvil.class) {
if (provider instanceof McRegion) {
new File(path, "region").mkdir();
for (File file : new File(provider.getPath() + "region/").listFiles()) {
Matcher m = Pattern.compile("-?\\d+").matcher(file.getName());
int regionX, regionZ;
try {
if (m.find()) {
regionX = Integer.parseInt(m.group());
} else
continue;
if (m.find()) {
regionZ = Integer.parseInt(m.group());
} else
continue;
} catch (NumberFormatException e) {
continue;
}
RegionLoader region = new RegionLoader(provider, regionX, regionZ);
for (Integer index : region.getLocationIndexes()) {
int chunkX = index & 0x1f;
int chunkZ = index >> 5;
BaseFullChunk old = region.readChunk(chunkX, chunkZ);
if (old == null)
continue;
int x = (regionX << 5) | chunkX;
int z = (regionZ << 5) | chunkZ;
FullChunk chunk = new ChunkConverter(result).from(old).to(Chunk.class).perform();
result.saveChunk(x, z, chunk);
}
region.close();
}
}
if (provider instanceof LevelDB) {
new File(path, "region").mkdir();
for (byte[] key : ((LevelDB) provider).getTerrainKeys()) {
int x = getChunkX(key);
int z = getChunkZ(key);
BaseFullChunk old = ((LevelDB) provider).readChunk(x, z);
FullChunk chunk = new ChunkConverter(result).from(old).to(Chunk.class).perform();
result.saveChunk(x, z, chunk);
}
}
result.doGarbageCollection();
}
return result;
}
use of cn.nukkit.level.format.LevelProvider in project Nukkit by Nukkit.
the class BaseFullChunk method unload.
@Override
public boolean unload(boolean save, boolean safe) {
LevelProvider level = this.getProvider();
if (level == null) {
return true;
}
if (save && this.changes != 0) {
level.saveChunk(this.getX(), this.getZ());
}
if (safe) {
for (Entity entity : this.getEntities().values()) {
if (entity instanceof Player) {
return false;
}
}
}
for (Entity entity : new ArrayList<>(this.getEntities().values())) {
if (entity instanceof Player) {
continue;
}
entity.close();
}
for (BlockEntity blockEntity : new ArrayList<>(this.getBlockEntities().values())) {
blockEntity.close();
}
this.provider = null;
return true;
}
use of cn.nukkit.level.format.LevelProvider in project Nukkit by Nukkit.
the class Chunk method toBinary.
public byte[] toBinary(boolean saveExtra) {
try {
LevelProvider provider = this.getProvider();
if (saveExtra && provider instanceof LevelDB) {
List<CompoundTag> entities = new ArrayList<>();
for (Entity entity : this.getEntities().values()) {
if (!(entity instanceof Player) && !entity.closed) {
entity.saveNBT();
entities.add(entity.namedTag);
}
}
EntitiesKey entitiesKey = EntitiesKey.create(this.getX(), this.getZ());
if (!entities.isEmpty()) {
((LevelDB) provider).getDatabase().put(entitiesKey.toArray(), NBTIO.write(entities));
} else {
((LevelDB) provider).getDatabase().delete(entitiesKey.toArray());
}
List<CompoundTag> tiles = new ArrayList<>();
for (BlockEntity blockEntity : this.getBlockEntities().values()) {
if (!blockEntity.closed) {
blockEntity.saveNBT();
entities.add(blockEntity.namedTag);
}
}
TilesKey tilesKey = TilesKey.create(this.getX(), this.getZ());
if (!tiles.isEmpty()) {
((LevelDB) provider).getDatabase().put(tilesKey.toArray(), NBTIO.write(tiles));
} else {
((LevelDB) provider).getDatabase().delete(tilesKey.toArray());
}
ExtraDataKey extraDataKey = ExtraDataKey.create(this.getX(), this.getZ());
if (!this.getBlockExtraDataArray().isEmpty()) {
BinaryStream extraData = new BinaryStream();
Map<Integer, Integer> extraDataArray = this.getBlockExtraDataArray();
extraData.putInt(extraDataArray.size());
for (Integer key : extraDataArray.keySet()) {
extraData.putInt(key);
extraData.putShort(extraDataArray.get(key));
}
((LevelDB) provider).getDatabase().put(extraDataKey.toArray(), extraData.getBuffer());
} else {
((LevelDB) provider).getDatabase().delete(extraDataKey.toArray());
}
}
byte[] heightMap = this.getHeightMapArray();
byte[] biomeColors = new byte[this.getBiomeColorArray().length * 4];
for (int i = 0; i < this.getBiomeColorArray().length; i++) {
byte[] bytes = Binary.writeInt(this.getBiomeColorArray()[i]);
biomeColors[i * 4] = bytes[0];
biomeColors[i * 4 + 1] = bytes[1];
biomeColors[i * 4 + 2] = bytes[2];
biomeColors[i * 4 + 3] = bytes[3];
}
return Binary.appendBytes(Binary.writeLInt(this.getX()), Binary.writeLInt(this.getZ()), this.getBlockIdArray(), this.getBlockDataArray(), this.getBlockSkyLightArray(), this.getBlockLightArray(), heightMap, biomeColors, new byte[] { (byte) (((this.isLightPopulated ? 0x04 : 0) | (this.isPopulated() ? 0x02 : 0) | (this.isGenerated() ? 0x01 : 0)) & 0xff) });
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Aggregations