public GeoDriverArray() { // load region files _blocks = new byte[GeoStructure.GEO_BLOCKS_X][GeoStructure.GEO_BLOCKS_Y][]; // prepare null block _nullBlock = new byte[] {GeoStructure.NULL}; // default null and flat block NSWE _nswe = Config.GEODATA_FORMAT != GeoFormat.L2D ? 0x0F : (byte) 0xFF; // load geo files according to geoengine config setup final ExProperties props = Config.load(Config.GEOENGINE_FILE); int loaded = 0; for (int rx = L2World.TILE_X_MIN; rx <= L2World.TILE_X_MAX; rx++) { for (int ry = L2World.TILE_Y_MIN; ry <= L2World.TILE_Y_MAX; ry++) { if (props.containsKey(String.valueOf(rx) + "_" + String.valueOf(ry))) { // region file is load-able, try to load it if (loadGeoBlocks(rx, ry)) loaded++; } else { // region file is not load-able, load null blocks loadNullBlocks(rx, ry); } } } _log.info( "GeoDriverArray: Loaded " + loaded + " " + Config.GEODATA_FORMAT.toString() + " region files."); // release the bytebuffer for loading of multilayer blocks _list = null; }
/** * Loads geodata from a file. When diagonal strategy is enabled, precalculates diagonal flags for * whole file. When file does not exist, is corrupted or not consistent, loads none geodata. * * @param regionX : Geodata file region X coordinate. * @param regionY : Geodata file region Y coordinate. * @return boolean : True, when geodata file was loaded without problem. */ private final boolean loadGeoBlocks(int regionX, int regionY) { final String filename = String.format(Config.GEODATA_FORMAT.getFilename(), regionX, regionY); // standard load try (RandomAccessFile raf = new RandomAccessFile(Config.GEODATA_PATH + filename, "r"); FileChannel fc = raf.getChannel()) { // initialize file buffer MappedByteBuffer buffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()).load(); buffer.order(ByteOrder.LITTLE_ENDIAN); // load 18B header for L2off geodata (1st and 2nd byte...region X and Y) if (Config.GEODATA_FORMAT == GeoFormat.L2OFF) { for (int i = 0; i < 18; i++) buffer.get(); } // get block indexes final int blockX = (regionX - L2World.TILE_X_MIN) * GeoStructure.REGION_BLOCKS_X; final int blockY = (regionY - L2World.TILE_Y_MIN) * GeoStructure.REGION_BLOCKS_Y; // loop over region blocks for (int ix = 0; ix < GeoStructure.REGION_BLOCKS_X; ix++) { for (int iy = 0; iy < GeoStructure.REGION_BLOCKS_Y; iy++) { if (Config.GEODATA_FORMAT != GeoFormat.L2OFF) { // get block type final byte type = buffer.get(); // load block according to block type switch (type) { case GeoStructure.TYPE_FLAT_L2J_L2OFF: case GeoStructure.TYPE_FLAT_L2D: _blocks[blockX + ix][blockY + iy] = loadFlatBlock(buffer); break; case GeoStructure.TYPE_COMPLEX_L2J: case GeoStructure.TYPE_COMPLEX_L2D: _blocks[blockX + ix][blockY + iy] = loadComplexBlock(buffer); break; case GeoStructure.TYPE_MULTILAYER_L2J: case GeoStructure.TYPE_MULTILAYER_L2D: _blocks[blockX + ix][blockY + iy] = loadMultilayerBlock(buffer); break; default: throw new IllegalArgumentException("Unknown block type: " + type); } } else { // get block type final short type = buffer.getShort(); // load block according to block type switch (type) { case GeoStructure.TYPE_FLAT_L2J_L2OFF: _blocks[blockX + ix][blockY + iy] = loadFlatBlock(buffer); break; case GeoStructure.TYPE_COMPLEX_L2OFF: _blocks[blockX + ix][blockY + iy] = loadComplexBlock(buffer); break; default: _blocks[blockX + ix][blockY + iy] = loadMultilayerBlock(buffer); break; } } } } // check data consistency if (buffer.remaining() > 0) _log.warning( "GeoDriverArray: Region file " + filename + " can be corrupted, remaining " + buffer.remaining() + " bytes to read."); // loading was successful return true; } catch (Exception e) { // an error occured while loading, load null blocks _log.warning("GeoDriverArray: Error while loading " + filename + " region file."); _log.warning(e.getMessage()); // replace whole region file with null blocks loadNullBlocks(regionX, regionY); // loading was not successful return false; } }