Share

Share

Development resources/Example Minecraft Classic Level Editing Class

From Minecraft Wiki
< Development resources(Redirected from Classes)
Jump to: navigation, search
This article is an orphan, as few or no other articles link to it. Please introduce links to this page from related articles
You can help us by linking to it or categorizing it.

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 % width;
                index = (index-x) / width;
                int z = index % height;
                int y = (index-z) / 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;
   }