use of org.jnbt.NBTOutputStream in project WorldPainter by Captain-Chaos.
the class RespawnPlayer method respawnPlayer.
public static void respawnPlayer(File levelDatFile) throws IOException {
CompoundTag outerTag;
try (NBTInputStream in = new NBTInputStream(new GZIPInputStream(new FileInputStream(levelDatFile)))) {
outerTag = (CompoundTag) in.readTag();
}
CompoundTag dataTag = (CompoundTag) outerTag.getTag(TAG_DATA);
int spawnX = ((IntTag) dataTag.getTag(TAG_SPAWN_X)).getValue();
int spawnY = ((IntTag) dataTag.getTag(TAG_SPAWN_Y)).getValue();
int spawnZ = ((IntTag) dataTag.getTag(TAG_SPAWN_Z)).getValue();
CompoundTag playerTag = (CompoundTag) dataTag.getTag(TAG_PLAYER);
playerTag.setTag(TAG_DEATH_TIME, new ShortTag(TAG_DEATH_TIME, (short) 0));
playerTag.setTag(TAG_HEALTH, new ShortTag(TAG_HEALTH, (short) 20));
List<Tag> motionList = new ArrayList<>(3);
motionList.add(new DoubleTag(null, 0));
motionList.add(new DoubleTag(null, 0));
motionList.add(new DoubleTag(null, 0));
playerTag.setTag(TAG_MOTION, new ListTag(TAG_MOTION, DoubleTag.class, motionList));
List<Tag> posList = new ArrayList<>(3);
posList.add(new DoubleTag(null, spawnX + 0.5));
posList.add(new DoubleTag(null, spawnY + 3));
posList.add(new DoubleTag(null, spawnZ + 0.5));
playerTag.setTag(TAG_POS, new ListTag(TAG_POS, DoubleTag.class, posList));
try (NBTOutputStream out = new NBTOutputStream(new GZIPOutputStream(new FileOutputStream(levelDatFile)))) {
out.writeTag(outerTag);
}
}
use of org.jnbt.NBTOutputStream in project WorldPainter by Captain-Chaos.
the class JavaWorldMerger method mergeBiomes.
/**
* Merge only the biomes, leave everything else the same.
*/
public void mergeBiomes(File backupDir, ProgressReceiver progressReceiver) throws IOException, ProgressReceiver.OperationCancelled {
// Read existing level.dat file and perform sanity checks
Level level = performSanityChecks(true);
// Backup existing level
File worldDir = levelDatFile.getParentFile();
if (!worldDir.renameTo(backupDir)) {
throw new FileInUseException("Could not move " + worldDir + " to " + backupDir);
}
if (!worldDir.mkdirs()) {
throw new IOException("Could not create " + worldDir);
}
// Copy everything that we are not going to generate (this includes the
// Nether and End dimensions)
File[] files = backupDir.listFiles();
// noinspection ConstantConditions // Cannot happen because we previously loaded level.dat from it
for (File file : files) {
if ((!file.getName().equalsIgnoreCase("session.lock")) && (!file.getName().equalsIgnoreCase("region"))) {
if (file.isFile()) {
FileUtils.copyFileToDir(file, worldDir);
} else if (file.isDirectory()) {
FileUtils.copyDir(file, new File(worldDir, file.getName()));
} else {
logger.warn("Not copying " + file + "; not a regular file or directory");
}
}
}
// Write session.lock file
File sessionLockFile = new File(worldDir, "session.lock");
try (DataOutputStream sessionOut = new DataOutputStream(new FileOutputStream(sessionLockFile))) {
sessionOut.writeLong(System.currentTimeMillis());
}
// Process all chunks and copy just the biomes
if (progressReceiver != null) {
progressReceiver.setMessage("Merging biomes");
}
// Find all the region files of the existing level
File oldRegionDir = new File(backupDir, "region");
final Pattern regionFilePattern = Pattern.compile("r\\.-?\\d+\\.-?\\d+\\.mca");
File[] oldRegionFiles = oldRegionDir.listFiles((dir, name) -> regionFilePattern.matcher(name).matches());
// Process each region file, copying every chunk unmodified, except
// for the biomes
// Can only happen for corrupted maps
@SuppressWarnings("ConstantConditions") int totalChunkCount = oldRegionFiles.length * 32 * 32, chunkCount = 0;
File newRegionDir = new File(worldDir, "region");
newRegionDir.mkdirs();
Dimension dimension = world.getDimension(DIM_NORMAL);
for (File file : oldRegionFiles) {
try (RegionFile oldRegion = new RegionFile(file)) {
String[] parts = file.getName().split("\\.");
int regionX = Integer.parseInt(parts[1]);
int regionZ = Integer.parseInt(parts[2]);
File newRegionFile = new File(newRegionDir, "r." + regionX + "." + regionZ + ".mca");
try (RegionFile newRegion = new RegionFile(newRegionFile)) {
for (int x = 0; x < 32; x++) {
for (int z = 0; z < 32; z++) {
if (oldRegion.containsChunk(x, z)) {
ChunkImpl2 chunk;
try (NBTInputStream in = new NBTInputStream(oldRegion.getChunkDataInputStream(x, z))) {
CompoundTag tag = (CompoundTag) in.readTag();
chunk = new ChunkImpl2(tag, level.getMaxHeight());
}
int chunkX = chunk.getxPos(), chunkZ = chunk.getzPos();
for (int xx = 0; xx < 16; xx++) {
for (int zz = 0; zz < 16; zz++) {
chunk.setBiome(xx, zz, dimension.getLayerValueAt(Biome.INSTANCE, (chunkX << 4) | xx, (chunkZ << 4) | zz));
}
}
try (NBTOutputStream out = new NBTOutputStream(newRegion.getChunkDataOutputStream(x, z))) {
out.writeTag(chunk.toNBT());
}
}
chunkCount++;
if (progressReceiver != null) {
progressReceiver.setProgress((float) chunkCount / totalChunkCount);
}
}
}
}
}
}
// Rewrite session.lock file
try (DataOutputStream sessionOut = new DataOutputStream(new FileOutputStream(sessionLockFile))) {
sessionOut.writeLong(System.currentTimeMillis());
}
}
use of org.jnbt.NBTOutputStream in project WorldPainter by Captain-Chaos.
the class JavaChunkStore method saveChunk.
@Override
public void saveChunk(Chunk chunk) {
// actually there
for (Iterator<TileEntity> i = chunk.getTileEntities().iterator(); i.hasNext(); ) {
final TileEntity tileEntity = i.next();
final Set<Integer> blockIds = Constants.TILE_ENTITY_MAP.get(tileEntity.getId());
if (blockIds == null) {
logger.warn("Unknown tile entity ID \"" + tileEntity.getId() + "\" encountered @ " + tileEntity.getX() + "," + tileEntity.getZ() + "," + tileEntity.getY() + "; can't check whether the corresponding block is there!");
} else {
final int existingBlockId = chunk.getBlockType(tileEntity.getX() & 0xf, tileEntity.getY(), tileEntity.getZ() & 0xf);
if (!blockIds.contains(existingBlockId)) {
// The block at the specified location
// is not a tile entity, or a different
// tile entity. Remove the data
i.remove();
if (logger.isDebugEnabled()) {
logger.debug("Removing tile entity " + tileEntity.getId() + " @ " + tileEntity.getX() + "," + tileEntity.getZ() + "," + tileEntity.getY() + " because the block at that location is a " + BLOCK_TYPE_NAMES[existingBlockId]);
}
}
}
}
// Check that there aren't multiple tile entities (of the same type,
// otherwise they would have been removed above) in the same location
Set<Point3i> occupiedCoords = new HashSet<>();
for (Iterator<TileEntity> i = chunk.getTileEntities().iterator(); i.hasNext(); ) {
TileEntity tileEntity = i.next();
Point3i coords = new Point3i(tileEntity.getX(), tileEntity.getZ(), tileEntity.getY());
if (occupiedCoords.contains(coords)) {
// There is already tile data for that location in the chunk;
// remove this copy
i.remove();
logger.warn("Removing tile entity " + tileEntity.getId() + " @ " + tileEntity.getX() + "," + tileEntity.getZ() + "," + tileEntity.getY() + " because there is already a tile entity of the same type at that location");
} else {
occupiedCoords.add(coords);
}
}
try {
int x = chunk.getxPos(), z = chunk.getzPos();
RegionFile regionFile = getOrCreateRegionFile(new Point(x >> 5, z >> 5));
try (NBTOutputStream out = new NBTOutputStream(regionFile.getChunkDataOutputStream(x & 31, z & 31))) {
out.writeTag(((NBTItem) chunk).toNBT());
}
} catch (IOException e) {
throw new RuntimeException("I/O error saving chunk", e);
}
// timeSpentSaving += System.currentTimeMillis() - start;
}
Aggregations