use of org.pepsoft.minecraft.Level in project WorldPainter by Captain-Chaos.
the class JavaWorldExporter method export.
@Override
public Map<Integer, ChunkFactory.Stats> export(File baseDir, String name, File backupDir, ProgressReceiver progressReceiver) throws IOException, ProgressReceiver.OperationCancelled {
// Sanity checks
if ((selectedTiles == null) && (selectedDimensions != null)) {
throw new IllegalArgumentException("Exporting a subset of dimensions not supported");
}
// Backup existing level
File worldDir = new File(baseDir, FileUtils.sanitiseName(name));
logger.info("Exporting world " + world.getName() + " to map at " + worldDir);
if (worldDir.isDirectory()) {
if (backupDir != null) {
logger.info("Directory already exists; backing up to " + backupDir);
if (!worldDir.renameTo(backupDir)) {
throw new FileInUseException("Could not move " + worldDir + " to " + backupDir);
}
} else {
throw new IllegalStateException("Directory already exists and no backup directory specified");
}
}
// Record start of export
long start = System.currentTimeMillis();
// Export dimensions
Dimension dim0 = world.getDimension(0);
Level level = new Level(world.getMaxHeight(), world.getPlatform());
level.setSeed(dim0.getMinecraftSeed());
level.setName(name);
Point spawnPoint = world.getSpawnPoint();
level.setSpawnX(spawnPoint.x);
level.setSpawnY(Math.max(dim0.getIntHeightAt(spawnPoint), dim0.getWaterLevelAt(spawnPoint)));
level.setSpawnZ(spawnPoint.y);
if (world.getGameType() == GameType.HARDCORE) {
level.setGameType(GAME_TYPE_SURVIVAL);
level.setHardcore(true);
level.setDifficulty(DIFFICULTY_HARD);
level.setDifficultyLocked(true);
level.setAllowCommands(false);
} else {
level.setGameType(world.getGameType().ordinal());
level.setHardcore(false);
level.setDifficulty(world.getDifficulty());
level.setAllowCommands(world.isAllowCheats());
}
Dimension.Border dim0Border = dim0.getBorder();
boolean endlessBorder = (dim0Border != null) && dim0Border.isEndless();
if (endlessBorder) {
StringBuilder generatorOptions = new StringBuilder("3;");
switch(dim0Border) {
case ENDLESS_LAVA:
case ENDLESS_WATER:
boolean bottomless = dim0.isBottomless();
int borderLevel = dim0.getBorderLevel();
int oceanDepth = Math.min(borderLevel / 2, 20);
int dirtDepth = borderLevel - oceanDepth - (bottomless ? 1 : 0);
if (!bottomless) {
generatorOptions.append("1*minecraft:bedrock,");
}
generatorOptions.append(dirtDepth);
generatorOptions.append("*minecraft:dirt,");
generatorOptions.append(oceanDepth);
generatorOptions.append((dim0Border == Dimension.Border.ENDLESS_WATER) ? "*minecraft:water;0;" : "*minecraft:lava;1;");
break;
case ENDLESS_VOID:
generatorOptions.append("1*minecraft:air;1;");
break;
}
generatorOptions.append(DEFAULT_GENERATOR_OPTIONS);
level.setMapFeatures(false);
level.setGenerator(Generator.FLAT);
level.setGeneratorOptions(generatorOptions.toString());
} else {
level.setMapFeatures(world.isMapFeatures());
level.setGenerator(world.getGenerator());
}
if (world.getPlatform().equals(DefaultPlugin.JAVA_ANVIL)) {
if ((!endlessBorder) && (world.getGenerator() == Generator.FLAT) && (world.getGeneratorOptions() != null)) {
level.setGeneratorOptions(world.getGeneratorOptions());
}
World2.BorderSettings borderSettings = world.getBorderSettings();
level.setBorderCenterX(borderSettings.getCentreX());
level.setBorderCenterZ(borderSettings.getCentreY());
level.setBorderSize(borderSettings.getSize());
level.setBorderSafeZone(borderSettings.getSafeZone());
level.setBorderWarningBlocks(borderSettings.getWarningBlocks());
level.setBorderWarningTime(borderSettings.getWarningTime());
level.setBorderSizeLerpTarget(borderSettings.getSizeLerpTarget());
level.setBorderSizeLerpTime(borderSettings.getSizeLerpTime());
level.setBorderDamagePerBlock(borderSettings.getDamagePerBlock());
}
// Save the level.dat file. This will also create a session.lock file, hopefully kicking out any Minecraft
// instances which may have the map open:
level.save(worldDir);
Map<Integer, ChunkFactory.Stats> stats = new HashMap<>();
int selectedDimension;
if (selectedTiles == null) {
selectedDimension = -1;
boolean first = true;
for (Dimension dimension : world.getDimensions()) {
if (dimension.getDim() < 0) {
// dimension, so skip it
continue;
}
if (first) {
first = false;
} else if (progressReceiver != null) {
progressReceiver.reset();
}
stats.put(dimension.getDim(), exportDimension(worldDir, dimension, world.getPlatform(), progressReceiver));
}
} else {
selectedDimension = selectedDimensions.iterator().next();
stats.put(selectedDimension, exportDimension(worldDir, world.getDimension(selectedDimension), world.getPlatform(), progressReceiver));
}
// Update the session.lock file, hopefully kicking out any Minecraft instances which may have tried to open the
// map in the mean time:
File sessionLockFile = new File(worldDir, "session.lock");
try (DataOutputStream sessionOut = new DataOutputStream(new FileOutputStream(sessionLockFile))) {
sessionOut.writeLong(System.currentTimeMillis());
}
// Record the export in the world history
if (selectedTiles == null) {
world.addHistoryEntry(HistoryEntry.WORLD_EXPORTED_FULL, name, worldDir);
} else {
world.addHistoryEntry(HistoryEntry.WORLD_EXPORTED_PARTIAL, name, worldDir, world.getDimension(selectedDimension).getName());
}
// Log an event
Configuration config = Configuration.getInstance();
if (config != null) {
EventVO event = new EventVO(EVENT_KEY_ACTION_EXPORT_WORLD).duration(System.currentTimeMillis() - start);
event.setAttribute(EventVO.ATTRIBUTE_TIMESTAMP, new Date(start));
event.setAttribute(ATTRIBUTE_KEY_MAX_HEIGHT, world.getMaxHeight());
event.setAttribute(ATTRIBUTE_KEY_PLATFORM, world.getPlatform().displayName);
event.setAttribute(ATTRIBUTE_KEY_MAP_FEATURES, world.isMapFeatures());
event.setAttribute(ATTRIBUTE_KEY_GAME_TYPE_NAME, world.getGameType().name());
event.setAttribute(ATTRIBUTE_KEY_ALLOW_CHEATS, world.isAllowCheats());
event.setAttribute(ATTRIBUTE_KEY_GENERATOR, world.getGenerator().name());
if (world.getPlatform().equals(DefaultPlugin.JAVA_ANVIL) && (world.getGenerator() == Generator.FLAT)) {
event.setAttribute(ATTRIBUTE_KEY_GENERATOR_OPTIONS, world.getGeneratorOptions());
}
Dimension dimension = world.getDimension(0);
event.setAttribute(ATTRIBUTE_KEY_TILES, dimension.getTiles().size());
logLayers(dimension, event, "");
dimension = world.getDimension(1);
if (dimension != null) {
event.setAttribute(ATTRIBUTE_KEY_NETHER_TILES, dimension.getTiles().size());
logLayers(dimension, event, "nether.");
}
dimension = world.getDimension(2);
if (dimension != null) {
event.setAttribute(ATTRIBUTE_KEY_END_TILES, dimension.getTiles().size());
logLayers(dimension, event, "end.");
}
if (selectedDimension != -1) {
event.setAttribute(ATTRIBUTE_KEY_EXPORTED_DIMENSION, selectedDimension);
event.setAttribute(ATTRIBUTE_KEY_EXPORTED_DIMENSION_TILES, selectedTiles.size());
}
if (world.getImportedFrom() != null) {
event.setAttribute(ATTRIBUTE_KEY_IMPORTED_WORLD, true);
}
config.logEvent(event);
}
return stats;
}
use of org.pepsoft.minecraft.Level in project WorldPainter by Captain-Chaos.
the class DumpLighting method main.
public static void main(String[] args) throws IOException {
File levelDatFile = new File(args[0]);
int x = Integer.parseInt(args[1]);
int y = Integer.parseInt(args[2]);
int z = Integer.parseInt(args[3]);
Level level = Level.load(levelDatFile);
MinecraftWorld world = new JavaMinecraftWorld(levelDatFile.getParentFile(), 0, level.getMaxHeight(), level.getVersion() == SUPPORTED_VERSION_1 ? DefaultPlugin.JAVA_MCREGION : DefaultPlugin.JAVA_ANVIL, true, CACHE_SIZE);
for (int dy = 16; dy >= -62; dy--) {
for (int dx = -16; dx <= 16; dx++) {
int blockX = x + dx, blockZ = z;
int blockType = world.getBlockTypeAt(blockX, blockZ, y + dy);
System.out.print('[');
System.out.print(blockType != BLK_AIR ? BLOCK_TYPE_NAMES[blockType].substring(0, 3).toUpperCase() : " ");
System.out.print(';');
int skyLightLevel = world.getSkyLightLevel(blockX, blockZ, y + dy);
if (skyLightLevel < 15) {
if (skyLightLevel < 10) {
System.out.print('0');
}
System.out.print(skyLightLevel);
} else {
System.out.print(" ");
}
// int blockLightLevel = world.getBlockLightLevel(blockX, blockZ, y + dy);
// if (blockLightLevel > 0) {
// if (blockLightLevel < 10) {
// System.out.print('0');
// }
// System.out.print(blockLightLevel);
// } else {
// System.out.print(" ");
// }
System.out.print(']');
}
System.out.println();
}
}
use of org.pepsoft.minecraft.Level in project WorldPainter by Captain-Chaos.
the class Mapper method map.
private static void map(final File worldDir, final int dim, final ColourScheme colourScheme, File output) throws IOException, InterruptedException {
File levelDatFile = new File(worldDir, "level.dat");
Level level = Level.load(levelDatFile);
final Platform platform = level.getVersion() == SUPPORTED_VERSION_1 ? DefaultPlugin.JAVA_MCREGION : DefaultPlugin.JAVA_ANVIL;
maxHeight = level.getMaxHeight();
File dimensionDir;
switch(dim) {
case 0:
dimensionDir = worldDir;
break;
case 1:
dimensionDir = new File(worldDir, "DIM-1");
break;
case 2:
dimensionDir = new File(worldDir, "DIM1");
break;
default:
throw new IllegalArgumentException(Integer.toString(dim));
}
final File regionDir = new File(dimensionDir, "region");
if (!regionDir.exists()) {
error("Map does not have dimension " + dim);
}
System.out.println("Mapping " + worldDir);
System.out.println("Name: " + level.getName());
System.out.println("Seed: " + level.getSeed());
if (level.getGeneratorName() != null) {
System.out.println("Generator: " + level.getGeneratorName() + " (version " + level.getGeneratorVersion() + ")");
}
System.out.println("Map height: " + maxHeight);
System.out.println("Storage format: " + (platform.equals(DefaultPlugin.JAVA_MCREGION) ? "McRegion (Minecraft 1.1 or earlier)" : "Anvil (Minecraft 1.2 or later)"));
// Determine size
File[] regionFiles = regionDir.listFiles(platform.equals(DefaultPlugin.JAVA_MCREGION) ? (dir, name) -> name.toLowerCase().endsWith(".mcr") : (FilenameFilter) (dir, name) -> name.toLowerCase().endsWith(".mca"));
int tmpLowestRegionX = Integer.MAX_VALUE, tmpHighestRegionX = Integer.MIN_VALUE;
int tmpLowestRegionZ = Integer.MAX_VALUE, tmpHighestRegionZ = Integer.MIN_VALUE;
for (File regionFile : regionFiles) {
String[] parts = regionFile.getName().split("\\.");
int regionX = Integer.parseInt(parts[1]);
int regionZ = Integer.parseInt(parts[2]);
if (regionX < tmpLowestRegionX) {
tmpLowestRegionX = regionX;
}
if (regionX > tmpHighestRegionX) {
tmpHighestRegionX = regionX;
}
if (regionZ < tmpLowestRegionZ) {
tmpLowestRegionZ = regionZ;
}
if (regionZ > tmpHighestRegionZ) {
tmpHighestRegionZ = regionZ;
}
}
final int lowestRegionX = tmpLowestRegionX, highestRegionX = tmpHighestRegionX;
final int lowestRegionZ = tmpLowestRegionZ, highestRegionZ = tmpHighestRegionZ;
int tmpLowestChunkX = Integer.MAX_VALUE, tmpHighestChunkX = Integer.MIN_VALUE;
int tmpLowestChunkZ = Integer.MAX_VALUE, tmpHighestChunkZ = Integer.MIN_VALUE;
for (int regionX = lowestRegionX; regionX <= highestRegionX; regionX++) {
File file = new File(regionDir, "r." + regionX + "." + lowestRegionZ + (platform.equals(DefaultPlugin.JAVA_MCREGION) ? ".mcr" : ".mca"));
if (file.exists()) {
int regionChunkX = regionX << 5;
int regionChunkZ = lowestRegionZ << 5;
RegionFile region = new RegionFile(file);
try {
for (int chunkX = 0; chunkX < 32; chunkX++) {
for (int chunkZ = 0; chunkZ < 32; chunkZ++) {
if (region.containsChunk(chunkX, chunkZ)) {
int x = regionChunkX + chunkX;
int z = regionChunkZ + chunkZ;
if (x < tmpLowestChunkX) {
tmpLowestChunkX = x;
}
if (x > tmpHighestChunkX) {
tmpHighestChunkX = x;
}
if (z < tmpLowestChunkZ) {
tmpLowestChunkZ = z;
}
if (z > tmpHighestChunkZ) {
tmpHighestChunkZ = z;
}
}
}
}
} finally {
region.close();
}
}
file = new File(regionDir, "r." + regionX + "." + highestRegionZ + (platform.equals(DefaultPlugin.JAVA_MCREGION) ? ".mcr" : ".mca"));
if (file.exists()) {
int regionChunkX = regionX << 5;
int regionChunkZ = highestRegionZ << 5;
RegionFile region = new RegionFile(file);
try {
for (int chunkX = 0; chunkX < 32; chunkX++) {
for (int chunkZ = 0; chunkZ < 32; chunkZ++) {
if (region.containsChunk(chunkX, chunkZ)) {
int x = regionChunkX + chunkX;
int z = regionChunkZ + chunkZ;
if (x < tmpLowestChunkX) {
tmpLowestChunkX = x;
}
if (x > tmpHighestChunkX) {
tmpHighestChunkX = x;
}
if (z < tmpLowestChunkZ) {
tmpLowestChunkZ = z;
}
if (z > tmpHighestChunkZ) {
tmpHighestChunkZ = z;
}
}
}
}
} finally {
region.close();
}
}
}
for (int regionZ = lowestRegionZ + 1; regionZ <= highestRegionZ - 1; regionZ++) {
File file = new File(regionDir, "r." + lowestRegionX + "." + regionZ + (platform.equals(DefaultPlugin.JAVA_MCREGION) ? ".mcr" : ".mca"));
if (file.exists()) {
int regionChunkX = lowestRegionX << 5;
int regionChunkZ = regionZ << 5;
RegionFile region = new RegionFile(file);
try {
for (int chunkX = 0; chunkX < 32; chunkX++) {
for (int chunkZ = 0; chunkZ < 32; chunkZ++) {
if (region.containsChunk(chunkX, chunkZ)) {
int x = regionChunkX + chunkX;
int z = regionChunkZ + chunkZ;
if (x < tmpLowestChunkX) {
tmpLowestChunkX = x;
}
if (x > tmpHighestChunkX) {
tmpHighestChunkX = x;
}
if (z < tmpLowestChunkZ) {
tmpLowestChunkZ = z;
}
if (z > tmpHighestChunkZ) {
tmpHighestChunkZ = z;
}
}
}
}
} finally {
region.close();
}
}
file = new File(regionDir, "r." + highestRegionX + "." + regionZ + (platform.equals(DefaultPlugin.JAVA_MCREGION) ? ".mcr" : ".mca"));
if (file.exists()) {
int regionChunkX = highestRegionX << 5;
int regionChunkZ = regionZ << 5;
RegionFile region = new RegionFile(file);
try {
for (int chunkX = 0; chunkX < 32; chunkX++) {
for (int chunkZ = 0; chunkZ < 32; chunkZ++) {
if (region.containsChunk(chunkX, chunkZ)) {
int x = regionChunkX + chunkX;
int z = regionChunkZ + chunkZ;
if (x < tmpLowestChunkX) {
tmpLowestChunkX = x;
}
if (x > tmpHighestChunkX) {
tmpHighestChunkX = x;
}
if (z < tmpLowestChunkZ) {
tmpLowestChunkZ = z;
}
if (z > tmpHighestChunkZ) {
tmpHighestChunkZ = z;
}
}
}
}
} finally {
region.close();
}
}
}
final int lowestChunkX = tmpLowestChunkX;
final int lowestChunkZ = tmpLowestChunkZ;
int widthChunks = (tmpHighestChunkX - tmpLowestChunkX + 1);
int heightChunks = (tmpHighestChunkZ - tmpLowestChunkZ + 1);
System.out.println("Width: " + (widthChunks << 4));
System.out.println("Height: " + (heightChunks << 4));
final BufferedImage image = new BufferedImage(widthChunks << 4, heightChunks << 4, BufferedImage.TYPE_INT_ARGB);
final int imageOffsetX = lowestChunkX << 4;
final int imageOffsetY = lowestChunkZ << 4;
final int waterColour = colourScheme.getColour(Material.WATER);
final int lavaColour = colourScheme.getColour(Material.LAVA);
final int snowColour = colourScheme.getColour(Material.SNOW);
int threads = Runtime.getRuntime().availableProcessors();
System.out.print("Mapping");
ExecutorService executorService = Executors.newFixedThreadPool(threads);
for (File file : regionFiles) {
final File finalFile = file;
executorService.submit(() -> {
try {
String[] parts = finalFile.getName().split("\\.");
int regionX = Integer.parseInt(parts[1]);
int regionY = Integer.parseInt(parts[2]);
WorldRegion world = new WorldRegion(worldDir, dim, regionX, regionY, maxHeight, platform);
int[][] heightCache = new int[544][544];
for (int i = 0; i < 544; i++) {
Arrays.fill(heightCache[i], -1);
}
for (int chunkX = 0; chunkX < 32; chunkX++) {
for (int chunkY = 0; chunkY < 32; chunkY++) {
int worldChunkX = (regionX << 5) | chunkX;
int worldChunkY = (regionY << 5) | chunkY;
if (world.isChunkPresent(worldChunkX, worldChunkY)) {
for (int x = 0; x < 16; x++) {
for (int y = 0; y < 16; y++) {
int worldX = (worldChunkX << 4) | x;
int worldY = (worldChunkY << 4) | y;
boolean snow = false, water = false, lava = false;
int waterLevel = 0;
for (int height = maxHeight - 1; height >= 0; height--) {
int blockType = world.getBlockTypeAt(worldX, worldY, height);
if (blockType != BLK_AIR) {
if (blockType == BLK_SNOW) {
snow = true;
} else if ((blockType == BLK_STATIONARY_WATER) || (blockType == BLK_WATER) || (blockType == BLK_STATIONARY_LAVA) || (blockType == BLK_LAVA)) {
if ((world.getDataAt(worldX, worldY, height) == 0) && (waterLevel == 0)) {
waterLevel = height;
if ((blockType == BLK_LAVA) || (blockType == BLK_STATIONARY_LAVA)) {
lava = true;
} else {
water = true;
}
}
} else if (TERRAIN_BLOCKS.contains(blockType)) {
// Terrain found
int data = world.getDataAt(worldX, worldY, height);
int depth = waterLevel - height;
int fluidAlpha = 0xff >> Math.min(depth, 3);
int colour = colourScheme.getColour(blockType, data);
if (depth > 0) {
colour = ColourUtils.multiply(colour, getBrightenAmount(world, heightCache, ((chunkX + 1) << 4) | x, ((chunkY + 1) << 4) | y, regionX, regionY));
}
if (water) {
colour = ColourUtils.mix(colour, waterColour, fluidAlpha);
} else if (lava) {
colour = ColourUtils.mix(colour, lavaColour, fluidAlpha);
}
if (snow) {
colour = ColourUtils.mix(colour, snowColour, 64);
}
if (depth <= 0) {
colour = ColourUtils.multiply(colour, getBrightenAmount(world, heightCache, ((chunkX + 1) << 4) | x, ((chunkY + 1) << 4) | y, regionX, regionY));
}
image.setRGB(worldX - imageOffsetX, worldY - imageOffsetY, 0xff000000 | colour);
break;
} else {
// Non-terrain block found (not shaded)
int data = world.getDataAt(worldX, worldY, height);
int depth = waterLevel - height;
int fluidAlpha = 0xff >> Math.min(depth, 3);
int colour = colourScheme.getColour(blockType, data);
if (water) {
colour = ColourUtils.mix(colour, waterColour, fluidAlpha);
} else if (lava) {
colour = ColourUtils.mix(colour, lavaColour, fluidAlpha);
}
if (snow) {
colour = ColourUtils.mix(colour, snowColour);
}
image.setRGB(worldX - imageOffsetX, worldY - imageOffsetY, 0xff000000 | colour);
break;
}
}
}
}
}
}
}
}
System.out.print('.');
System.out.flush();
} catch (Throwable t) {
t.printStackTrace();
System.exit(1);
}
});
}
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.DAYS);
System.out.println();
// Save image
System.out.println("Saving image to " + output + "...");
ImageIO.write(image, "PNG", output);
System.out.println("Finished");
}
Aggregations