/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.pepsoft.worldpainter.biomeschemes; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import org.pepsoft.worldpainter.BiomeScheme; import org.pepsoft.worldpainter.ColourScheme; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; import java.util.*; import static org.pepsoft.minecraft.Constants.*; /** * An abstract base class for {@link BiomeScheme}s which provide the biomes as * used in Minecraft 1.7 and later. * * @author pepijn */ public abstract class AbstractMinecraft1_7BiomeScheme extends AbstractBiomeScheme implements Minecraft1_7Biomes { @Override public final int getBiomeCount() { return BIOME_NAMES.length; } @Override public final int getColour(int biome, ColourScheme colourScheme) { switch (biome) { case BIOME_OCEAN: case BIOME_RIVER: case BIOME_DEEP_OCEAN: return colourScheme.getColour(BLK_WATER); case BIOME_PLAINS: case BIOME_EXTREME_HILLS: case BIOME_EXTREME_HILLS_EDGE: case BIOME_EXTREME_HILLS_M: case BIOME_EXTREME_HILLS_PLUS: case BIOME_EXTREME_HILLS_PLUS_M: case BIOME_SUNFLOWER_PLAINS: return colourScheme.getColour(BLK_GRASS); case BIOME_DESERT: case BIOME_BEACH: case BIOME_DESERT_HILLS: case BIOME_DESERT_M: return colourScheme.getColour(BLK_SAND); case BIOME_FOREST: case BIOME_FOREST_HILLS: case BIOME_SWAMPLAND: case BIOME_ROOFED_FOREST: case BIOME_ROOFED_FOREST_M: case BIOME_FLOWER_FOREST: case BIOME_SWAMPLAND_M: return colourScheme.getColour(BLK_LEAVES, DATA_OAK); case BIOME_JUNGLE: case BIOME_JUNGLE_HILLS: case BIOME_JUNGLE_EDGE: case BIOME_JUNGLE_M: case BIOME_JUNGLE_EDGE_M: return colourScheme.getColour(BLK_LEAVES, DATA_JUNGLE); case BIOME_ICE_PLAINS: case BIOME_ICE_MOUNTAINS: case BIOME_COLD_TAIGA: case BIOME_COLD_TAIGA_HILLS: case BIOME_COLD_TAIGA_M: case BIOME_ICE_PLAINS_SPIKES: case BIOME_COLD_BEACH: return colourScheme.getColour(BLK_SNOW); case BIOME_HELL: return colourScheme.getColour(BLK_NETHERRACK); case BIOME_SKY: return colourScheme.getColour(BLK_END_STONE); case BIOME_FROZEN_OCEAN: case BIOME_FROZEN_RIVER: return colourScheme.getColour(BLK_ICE); case BIOME_MUSHROOM_ISLAND: case BIOME_MUSHROOM_ISLAND_SHORE: return colourScheme.getColour(BLK_MYCELIUM); case BIOME_STONE_BEACH: return colourScheme.getColour(BLK_STONE); case BIOME_BIRCH_FOREST: case BIOME_BIRCH_FOREST_HILLS: case BIOME_BIRCH_FOREST_HILLS_M: case BIOME_BIRCH_FOREST_M: return colourScheme.getColour(BLK_LEAVES, DATA_BIRCH); case BIOME_TAIGA: case BIOME_TAIGA_HILLS: case BIOME_MEGA_TAIGA: case BIOME_MEGA_TAIGA_HILLS: case BIOME_MEGA_SPRUCE_TAIGA: case BIOME_MEGA_SPRUCE_TAIGA_HILLS: case BIOME_TAIGA_M: return colourScheme.getColour(BLK_LEAVES, DATA_PINE); case BIOME_SAVANNA: case BIOME_SAVANNA_M: case BIOME_SAVANNA_PLATEAU: case BIOME_SAVANNA_PLATEAU_M: return colourScheme.getColour(BLK_LEAVES2, DATA_ACACIA); case BIOME_MESA: case BIOME_MESA_BRYCE: case BIOME_MESA_PLATEAU: case BIOME_MESA_PLATEAU_F: case BIOME_MESA_PLATEAU_F_M: case BIOME_MESA_PLATEAU_M: return colourScheme.getColour(BLK_HARDENED_CLAY); default: throw new IllegalArgumentException(Integer.toString(biome)); } } @Override public final boolean[][] getPattern(int biome) { return BIOME_PATTERNS[biome]; } @Override public boolean isBiomePresent(int biome) { return (biome <= HIGHEST_BIOME_ID) && (BIOME_NAMES[biome] != null); } @Override public String getBiomeName(int biome) { return BIOME_NAMES[biome]; } /** * Create a class loader for the specified Minecraft jar, including the jars * specified in its associated json descriptor file. * * @param minecraftJar The Minecraft jar for which to create a class loader. * @param libDir The directory from which to load the dependencies. * @return A class loader containing all (headless) dependencies for the * specified Minecraft jar. */ protected final ClassLoader getClassLoader(File minecraftJar, File libDir) { List<URL> classpath = new ArrayList<>(25); try { // Construct a classpath, starting with the Minecraft jar itself classpath.add(minecraftJar.toURI().toURL()); // Find and parse the json descriptor, adding the libraries to the // claspath File minecraftJarDir = minecraftJar.getParentFile(); String minecraftJarName = minecraftJar.getName(); String jsonFileName = minecraftJarName.substring(0, minecraftJarName.length() - 4) + ".json"; File jsonFile = new File(minecraftJarDir, jsonFileName); JSONParser jsonParser = new JSONParser(); try (FileReader in = new FileReader(jsonFile)) { Map<?, ?> rootNode = (Map<?, ?>) jsonParser.parse(in); List<Map<?, ?>> librariesNode = (List<Map<?, ?>>) rootNode.get("libraries"); for (Map<?, ?> libraryNode : librariesNode) { if (libraryNode.containsKey("rules")) { // For now we just skip any library that has rules, on // the assumption that it is a platform dependent // library that's only needed by the actual game client // and not by the Minecraft core continue; } String libraryDescriptor = (String) libraryNode.get("name"); String[] parts = libraryDescriptor.split(":"); String libraryGroup = parts[0]; String libraryName = parts[1]; if (IGNORED_LIBRARY_NAMES.contains(libraryName)) { continue; } String libraryVersion = parts[2]; File libraryDir = new File(libDir, libraryGroup.replace('.', '/') + '/' + libraryName + '/' + libraryVersion); File libraryFile = new File(libraryDir, libraryName + '-' + libraryVersion + ".jar"); if (logger.isTraceEnabled()) { logger.trace("Adding to biome scheme classpath: {}", libraryFile); } classpath.add(libraryFile.toURI().toURL()); } } } catch (IOException e) { throw new RuntimeException("I/O error while trying to load Minecraft jar descriptor json file", e); } catch (ParseException e) { throw new RuntimeException("Parsing error while trying to load Minecraft jar descriptor json file", e); } // Create the class loader and return it return new URLClassLoader(classpath.toArray(new URL[classpath.size()])); } private static final boolean[][][] BIOME_PATTERNS = new boolean[168][][]; // We want all logging to be redirected to the slf4j API private static final Set<String> IGNORED_LIBRARY_NAMES = new HashSet<>(Arrays.asList("log4j-api", "log4j-core", "commons-logging")); static { try { BufferedImage image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/swamp_pattern.png")); BIOME_PATTERNS[BIOME_SWAMPLAND] = createPattern(image); BIOME_PATTERNS[BIOME_SWAMPLAND_M] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/mountains_pattern.png")); BIOME_PATTERNS[BIOME_EXTREME_HILLS] = createPattern(image); BIOME_PATTERNS[BIOME_EXTREME_HILLS_M] = createPattern(image); BIOME_PATTERNS[BIOME_EXTREME_HILLS_PLUS] = createPattern(image); BIOME_PATTERNS[BIOME_EXTREME_HILLS_PLUS_M] = createPattern(image); BIOME_PATTERNS[BIOME_ICE_MOUNTAINS] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/deciduous_trees_pattern.png")); BIOME_PATTERNS[BIOME_FOREST] = createPattern(image); BIOME_PATTERNS[BIOME_FLOWER_FOREST] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/roofed_trees_pattern.png")); BIOME_PATTERNS[BIOME_ROOFED_FOREST] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/birch_trees_pattern.png")); BIOME_PATTERNS[BIOME_BIRCH_FOREST] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/spruce_trees_pattern.png")); BIOME_PATTERNS[BIOME_TAIGA] = createPattern(image); BIOME_PATTERNS[BIOME_COLD_TAIGA] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/pine_trees_pattern.png")); BIOME_PATTERNS[BIOME_MEGA_TAIGA] = createPattern(image); BIOME_PATTERNS[BIOME_MEGA_SPRUCE_TAIGA] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/hills_pattern.png")); BIOME_PATTERNS[BIOME_DESERT_HILLS] = createPattern(image); BIOME_PATTERNS[BIOME_EXTREME_HILLS_EDGE] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/deciduous_hills_pattern.png")); BIOME_PATTERNS[BIOME_FOREST_HILLS] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/roofed_hills_pattern.png")); BIOME_PATTERNS[BIOME_ROOFED_FOREST_M] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/birch_hills_pattern.png")); BIOME_PATTERNS[BIOME_BIRCH_FOREST_M] = createPattern(image); BIOME_PATTERNS[BIOME_BIRCH_FOREST_HILLS] = createPattern(image); BIOME_PATTERNS[BIOME_BIRCH_FOREST_HILLS_M] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/spruce_hills_pattern.png")); BIOME_PATTERNS[BIOME_TAIGA_M] = createPattern(image); BIOME_PATTERNS[BIOME_TAIGA_HILLS] = createPattern(image); BIOME_PATTERNS[BIOME_COLD_TAIGA_HILLS] = createPattern(image); BIOME_PATTERNS[BIOME_COLD_TAIGA_M] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/pine_hills_pattern.png")); BIOME_PATTERNS[BIOME_MEGA_TAIGA_HILLS] = createPattern(image); BIOME_PATTERNS[BIOME_MEGA_SPRUCE_TAIGA_HILLS] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/jungle_trees_pattern.png")); BIOME_PATTERNS[BIOME_JUNGLE] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/jungle_hills_pattern.png")); BIOME_PATTERNS[BIOME_JUNGLE_HILLS] = createPattern(image); BIOME_PATTERNS[BIOME_JUNGLE_M] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/savanna_pattern.png")); BIOME_PATTERNS[BIOME_SAVANNA] = createPattern(image); BIOME_PATTERNS[BIOME_SAVANNA_PLATEAU] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/savanna_hills_pattern.png")); BIOME_PATTERNS[BIOME_SAVANNA_M] = createPattern(image); BIOME_PATTERNS[BIOME_SAVANNA_PLATEAU_M] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/mesa_pattern.png")); BIOME_PATTERNS[BIOME_MESA] = createPattern(image); BIOME_PATTERNS[BIOME_MESA_PLATEAU] = createPattern(image); BIOME_PATTERNS[BIOME_MESA_PLATEAU_F] = createPattern(image); BIOME_PATTERNS[BIOME_MESA_PLATEAU_F_M] = createPattern(image); BIOME_PATTERNS[BIOME_MESA_PLATEAU_M] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/mesa_bryce_pattern.png")); BIOME_PATTERNS[BIOME_MESA_BRYCE] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/jungle_edge_pattern.png")); BIOME_PATTERNS[BIOME_JUNGLE_EDGE] = createPattern(image); image = ImageIO.read(ClassLoader.getSystemResourceAsStream("org/pepsoft/worldpainter/icons/jungle_edge_hills_pattern.png")); BIOME_PATTERNS[BIOME_JUNGLE_EDGE_M] = createPattern(image); } catch (IOException e) { throw new RuntimeException("I/O error loading image", e); } } private static boolean[][] createPattern(BufferedImage image) { boolean[][] pattern = new boolean[16][]; for (int x = 0; x < 16; x++) { pattern[x] = new boolean[16]; for (int y = 0; y < 16; y++) { pattern[x][y] = image.getRGB(x, y) != -1; } } return pattern; } private static final Logger logger = LoggerFactory.getLogger(AbstractMinecraft1_7BiomeScheme.class); }