Development resources/Example Minecraft Classic Level Editing Class

To compile and use this class, have your classpath include the path to the LevelEditor.java file and the minecraft-server.jar file.
 javac -classpath .:minecraft-server.jar LevelEditor.java
 java -classpath .:minecraft-server.jar LevelEditor
or
 java -classpath .:minecraft-server.jar LevelEditor new_server_level.dat
 import java.io.*;
 import java.text.DateFormat;
 import java.util.zip.GZIPOutputStream;
 import java.util.zip.GZIPInputStream;
 
 public class LevelEditor {
 	private com.mojang.minecraft.level.Level level = null;
 
 	LevelEditor() {
 	}
 
 	// load from file called filename
 	public void load(String filename) {
 		FileInputStream fis = null;
 		GZIPInputStream gzis = null;
 		ObjectInputStream in = null;
 		DataInputStream inputstream = null;
 		try {
 			fis = new FileInputStream(filename);
 			gzis = new GZIPInputStream(fis);
 			inputstream = new DataInputStream(gzis);
 			if((inputstream.readInt()) != 0x271bb788) {
 				return;
 			}
 			if((inputstream.readByte()) > 2) {
 				System.out.println("Error: Level version > 2, this is unexpected!");
 				return;
 			}
 			in = new ObjectInputStream(gzis);
 			level = (com.mojang.minecraft.level.Level)in.readObject();
 			inputstream.close();
 			in.close();
 			System.out.println("Loading level "+filename+" successful");
 		} catch(IOException ex) {
 			ex.printStackTrace();
 		} catch(ClassNotFoundException ex) {
 			ex.printStackTrace();
 		}
 		level.initTransient();
 	}
 
 	// save in file called filename
 	public void save(String filename) {
 		FileOutputStream fos = null;
 		GZIPOutputStream gzos = null;
 		ObjectOutputStream out = null;
 		DataOutputStream outputstream = null;
 		try {
 			fos = new FileOutputStream(filename);
 			gzos = new GZIPOutputStream(fos);
 			outputstream = new DataOutputStream(gzos);
 			outputstream.writeInt(0x271bb788);
 			outputstream.writeByte(2);
 			out = new ObjectOutputStream(gzos);
 			out.writeObject(level);
 			outputstream.close();
 			out.close();
 			System.out.println("Saving level "+filename+" successful");
 		} catch(IOException ex) {
 			ex.printStackTrace();
 		}
 	}
 
 	// prints all there is to know about a level, except for the blocks data
 	public void printInfo() {
 		if (level == null) {
 			return;
 		}
 		System.out.println("Level info:");
 		System.out.println("name: "+level.name);
 		System.out.println("creator: "+level.creator);
 		System.out.println("createTime: "+(DateFormat.getDateTimeInstance(DateFormat.FULL,DateFormat.FULL).format(level.createTime)));
 		System.out.println("width: "+level.width);
 		System.out.println("height: "+level.height);
 		System.out.println("depth: "+level.depth);
 		System.out.println("spawnpoint: ["+level.xSpawn+","+level.ySpawn+","+level.zSpawn+"]");
 		System.out.println("spawn rotation: "+level.rotSpawn);
 	}
 
 	// safe to use method, return value let's you know if anything was changed
 	public boolean setTile(int x, int y, int z, int t) {
 		if (
 			x >=0 && x < level.width &&
 			y >=0 && y < level.depth &&
 			z >=0 && z < level.height &&
 			t >= 0 && t <= 37
 		) {
 			if (t == 8 || t == 10) {
 				level.setTile(x,y,z,t);
 			} else if (t >= 0 && t <= 18) {
 				level.setTileNoUpdate(x,y,z,t);
 			}
 			return true;
 		}
 		return false;
 	}
 
 	// gets you the level coordinates from the blocks array index
 	public int[] getCoords(int index) {
 		int x = index % level.width;
 		index = (index-x) / level.width;
 		int z = index % level.height;
 		int y = (index-z) / level.height;
 		return new int[] {x, y, z};
 	}
 
 	public void clearBlocks() {
 		for (int i=0; i<level.blocks.length; i++) {
 			level.blocks[i] = 0;
 		}
 	}
 
 	public void floor(int y, int type) {
 		for (int i=0; i<level.width; i++) {
 		for (int j=0; j<level.height; j++) {
 			setTile(i,y,j,type);
 		}
 		}
 	}
 
 	public void wallX(int x1, int x2, int z, int y, int height, int type) {
 		for (int i=x1; i<=x2; i++) {
 		for (int j=y; j<y+height; j++) {
 			if (!setTile(i,j,z,type)) {
 				System.out.println("Warning: a tile got ignored while building a wallX: ["+i+","+j+","+z+"]");
 			}
 		}
 		}
 	}
 
 	public void wallZ(int x, int z1, int z2, int y, int height, int type) {
 		for (int i=z1; i<=z2; i++) {
 		for (int j=y; j<y+height; j++) {
 			if (!setTile(x,j,i,type)) {
 				System.out.println("Warning: a tile got ignored while building a wallZ: ["+x+","+j+","+i+"]");
 			}
 		}
 		}
 	}
 
 	// substitute all of block type 'from' to 'to' :) returning the number of blocks altered
 	public int substitute(byte from, byte to) {
 		int count=0;
 		for (int i=0; i<level.blocks.length; i++) {
 			if (level.blocks[i] == from) {
 				level.blocks[i] = to;
 				count++;
 			}
 		}
 		return count;
 	}
 
 	public void setSize(int x, int y, int z) {
 		level.setData(x, y, z, new byte[x*y*z]);
 	}
 
 	public static void main(String [] args) {
 		LevelEditor le = new LevelEditor();
 		String filename = "server_level.dat";
 		if(args.length > 0) {
 			filename = args[0];
 			le.load(filename);
 			if (le.level == null) {
 				System.out.println("Loading level "+filename+" failed");
 				return;
 			}
 		} else {
 			le.level = new com.mojang.minecraft.level.Level();
 		}
 		// Do some fancy editing here
 
 		// set a custom size: 256 wide, 128 high, 512 length
 		le.setSize(256, 128, 512);
 
 		// first, let's clear out the field
 		le.clearBlocks();
 
 		// add a bunch of walls to fill the lower part of the level
 		for (int i=0; i<le.level.width; i++) {
 			le.wallX(0,le.level.height-1,i,0,(int)le.level.getWaterLevel()-1,3);
 		}
 		// lay the floor
 		le.floor((int)le.level.getWaterLevel()-1,2);
 
 		// let the level find a spawn location for us
 		le.level.findSpawn();
 
 		// Leave our fingerprint
 		le.level.creator = "Minecrafter";
 		le.level.name = "A Custom World";
 		le.level.createTime = System.currentTimeMillis();
 
 		le.save(filename);
 		le.printInfo();
 	}
 }
To help with getting the correct bytes for different block types, you can also use this class
 public class Blocks 
 {
 	public static final byte air 				= (byte)0;
 	public static final byte rock 				= (byte)1;
 	public static final byte grass 				= (byte)2;
 	public static final byte dirt 				= (byte)3;
 	public static final byte stone 				= (byte)4;
 	public static final byte wood 				= (byte)5;
 	public static final byte shrub 				= (byte)6;
 	public static final byte blackrock 			= (byte)7;
 	public static final byte water 				= (byte)8;
 	public static final byte waterstill 			= (byte)9;
 	public static final byte lava 				= (byte)10;
 	public static final byte lavastill 			= (byte)11;
 	public static final byte sand 				= (byte)12;
 	public static final byte gravel 			= (byte)13;
 	public static final byte goldrock 			= (byte)14;
 	public static final byte ironrock 			= (byte)15;
 	public static final byte coal 				= (byte)16;
 	public static final byte trunk 				= (byte)17;
 	public static final byte leaf 				= (byte)18;
 	public static final byte sponge 			= (byte)19;
 	public static final byte glass 				= (byte)20;
 	public static final byte red 				= (byte)21;
 	public static final byte orange 			= (byte)22;
 	public static final byte yellow 			= (byte)23;
 	public static final byte lightgreen 			= (byte)24;
 	public static final byte green 				= (byte)25;
 	public static final byte aquagreen 			= (byte)26;
 	public static final byte cyan 				= (byte)27;
 	public static final byte lightblue 			= (byte)28;
 	public static final byte blue 				= (byte)29;
 	public static final byte purple 			= (byte)30;
 	public static final byte lightpurple 			= (byte)31;
 	public static final byte pink 				= (byte)32;
 	public static final byte darkpink 			= (byte)33;
 	public static final byte darkgrey 			= (byte)34;
 	public static final byte lightgrey 			= (byte)35;
 	public static final byte white 				= (byte)36;
 	public static final byte yellowflower 			= (byte)37;
 	public static final byte redflower 			= (byte)38;
 	public static final byte mushroom 			= (byte)39;
 	public static final byte redmushroom 			= (byte)40;
 	public static final byte goldsolid 			= (byte)41;
 	public static final byte iron 				= (byte)42;
 	public static final byte staircasefull 			= (byte)43;
 	public static final byte staircasestep 			= (byte)44;
 	public static final byte brick 				= (byte)45;
 	public static final byte tnt 				= (byte)46;
 	public static final byte bookcase 			= (byte)47;
 	public static final byte stonevine 			= (byte)48;
 	public static final byte obsidian 			= (byte)49;
 }
Category:Development
fr:Classes Java d'édition de carte Classique
ru:Классы
zh:开发资源/Classic地图编辑类示例