/* This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * * http://www.gnu.org/copyleft/gpl.html */ package net.sf.l2j.gameserver; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FilenameFilter; import java.io.IOException; import java.io.ObjectInputStream; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.StringTokenizer; import java.util.TreeSet; import java.util.logging.Logger; import java.util.zip.GZIPInputStream; import javax.imageio.ImageIO; import net.sf.l2j.Config; import net.sf.l2j.gameserver.model.L2CharPosition; public class Universe implements java.io.Serializable { /** * Comment for <code>serialVersionUID</code> */ private static final long serialVersionUID = -2040223695811104704L; public static final int MIN_X = -127900; public static final int MAX_X = 194327; public static final int MIN_Y = -30000; public static final int MAX_Y = 259536; public static final int MIN_Z = -17000; public static final int MAX_Z = 17000; public static final int MIN_X_GRID = 60; public static final int MIN_Y_GRID = 60; public static final int MIN_Z_GRID = 60; public static final int MIN_GRID = 360; private static Universe _instance; protected static final Logger _log = Logger.getLogger(Universe.class.getName()); protected List<Coord> _coordList; private HashSet<Integer> _logPlayers; private boolean _logAll = true; public static void main(String[] args) { Universe u = new Universe(); u.load(); //u.removeDoubles(); u.implode(false); } private class Position implements Comparable<Position>, java.io.Serializable { /** * Comment for <code>serialVersionUID</code> */ private static final long serialVersionUID = -8798746764450022287L; protected int _x; protected int _flag; protected int _y; protected int _z; public Position(int x, int y, int z, int flag) { _x = x; _y = y; _z = z; _flag = flag; } public Position(L2CharPosition pos) { _x = pos.x; _y = pos.y; _z = pos.z; _flag = 0; } @Deprecated public L2CharPosition l2CP() { return new L2CharPosition(_x, _y, _z, 0); } public int compareTo(Position obj) { int res = Integer.valueOf(_x).compareTo(obj._x); if (res != 0) return res; res = Integer.valueOf(_y).compareTo(obj._y); if (res != 0) return res; res = Integer.valueOf(_z).compareTo(obj._z); return res; } @Override public String toString() { return String.valueOf(_x) + " " + _y + " " + _z + " " + _flag; } } private class Coord implements Comparable<Position>, java.io.Serializable { /** * Comment for <code>serialVersionUID</code> */ private static final long serialVersionUID = -558060332886829552L; protected int _x; protected int _y; protected int _z; public Coord(int x, int y, int z) { _x = x; _y = y; _z = z; } public Coord(L2CharPosition pos) { _x = pos.x; _y = pos.y; _z = pos.z; } public int compareTo(Position obj) { int res = Integer.valueOf(_x).compareTo(obj._x); if (res != 0) return res; res = Integer.valueOf(_y).compareTo(obj._y); if (res != 0) return res; res = Integer.valueOf(_z).compareTo(obj._z); return res; } @Override public String toString() { return String.valueOf(_x) + " " + _y + " " + _z; } } public static Universe getInstance() { if (_instance == null && Config.ACTIVATE_POSITION_RECORDER) { _instance = new Universe(); } return _instance; } private Universe() { _coordList = new LinkedList<Coord>(); _logPlayers = new HashSet<Integer>(); ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new UniverseDump(), 30000, 30000); } public void registerHeight(int x, int y, int z) { // don't overwrite obstacle entries //Position p = new Position(x, y, z, 0); //_map.add(p); _coordList.add(new Coord(x, y, z)); //if (Config.USE_3D_MAP) insertInto3DMap(p); } public void registerObstacle(int x, int y, int z) { //Position p = new Position(x, y, z, -1); //_map.add(p); _coordList.add(new Coord(x, y, z)); //if (Config.USE_3D_MAP) insertInto3DMap(p); } public boolean shouldLog(Integer id) { return (_logPlayers.contains(id) || _logAll); } public void setLogAll(boolean flag) { _logAll = flag; } public void addLogPlayer(Integer id) { _logPlayers.add(id); _logAll = false; } public void removeLogPlayer(Integer id) { _logPlayers.remove(id); } public void loadAscii() { int initialSize = _coordList.size(); try { BufferedReader r = new BufferedReader(new FileReader("data/universe.txt")); String line; while ((line = r.readLine()) != null) { StringTokenizer st = new StringTokenizer(line); String x1 = st.nextToken(); String y1 = st.nextToken(); String z1 = st.nextToken(); // String f1 = st.nextToken(); int x = Integer.parseInt(x1); int y = Integer.parseInt(y1); int z = Integer.parseInt(z1); // int f = Integer.parseInt(f1); _coordList.add(new Coord(x, y, z)); } r.close(); _log.info((_coordList.size() - initialSize) + " additional nodes loaded from text file."); } catch (Exception e) { _log.info("could not read text file universe.txt"); } } public void createMap() { int zoom = 100; int w = (MAX_X - MIN_X) / zoom; int h = (MAX_Y - MIN_Y) / zoom; BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_USHORT_GRAY); Graphics2D gr = bi.createGraphics(); int min_z = 0, max_z = 0; for (Coord pos : _coordList) { if (pos == null) continue; if (pos._z < min_z) min_z = pos._z; if (pos._z > max_z) max_z = pos._z; } for (Coord pos : _coordList) { if (pos == null) continue; int x = (pos._x - MIN_X) / zoom; int y = (pos._y - MIN_Y) / zoom; int color = (int) (((long) pos._z - MIN_Z) * 0xFFFFFF / (MAX_Z - MIN_Z)); gr.setColor(new Color(color)); gr.drawLine(x, y, x, y); } try { ImageIO.write(bi, "png", new File("universe.png")); } catch (Exception e) { _log.warning("cannot create universe.png: " + e); } } public class UniverseFilter implements FilenameFilter { String _ext = ""; public UniverseFilter(String pExt) { _ext = pExt; } /* (non-Javadoc) * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String) */ public boolean accept(@SuppressWarnings("unused") File arg0, String name) { return name.startsWith("universe") && name.endsWith("." + _ext); } } public void load() { int total = 0; if (_coordList == null) { _coordList = new LinkedList<Coord>(); } try { loadBinFiles(); loadHexFiles(); loadFinFiles(); _log.info(_coordList.size() + " map vertices loaded in total."); } catch (Exception e) { e.printStackTrace(); } System.out.println("Total: " + total); } /** * @throws FileNotFoundException * @throws IOException */ private void loadFinFiles() throws FileNotFoundException, IOException { FilenameFilter filter = new UniverseFilter("fin"); File directory = new File("data"); File[] files = directory.listFiles(filter); for (File file : files) { FileInputStream fos = new FileInputStream(file); // Save to file DataInputStream data = new DataInputStream(fos); int count = data.readInt(); List<Coord> newMap = new LinkedList<Coord>(); for (int i = 0; i < count; i++) { newMap.add(new Coord(data.readInt(), data.readInt(), data.readInt())); } data.close(); // Close the stream. _log.info(newMap.size() + " map vertices loaded from file " + file.getName()); _coordList.addAll(newMap); } } /** * @throws FileNotFoundException * @throws IOException */ private void loadHexFiles() throws FileNotFoundException, IOException { FilenameFilter filter = new UniverseFilter("hex"); File directory = new File("data"); File[] files = directory.listFiles(filter); for (File file : files) { FileInputStream fos = new FileInputStream(file); // Save to file GZIPInputStream gzos = new GZIPInputStream(fos); DataInputStream data = new DataInputStream(gzos); int count = data.readInt(); List<Coord> newMap = new LinkedList<Coord>(); for (int i = 0; i < count; i++) { newMap.add(new Coord(data.readInt(), data.readInt(), data.readInt())); data.readInt(); } data.close(); // Close the stream. _log.info(newMap.size() + " map vertices loaded from file " + file.getName()); _coordList.addAll(newMap); } } /** * @throws FileNotFoundException * @throws IOException * @throws ClassNotFoundException */ @SuppressWarnings(value = {"unchecked"}) private void loadBinFiles() throws FileNotFoundException, IOException, ClassNotFoundException { FilenameFilter filter = new UniverseFilter("bin"); File directory = new File("data"); File[] files = directory.listFiles(filter); for (File file : files) { //Create necessary input streams FileInputStream fis = new FileInputStream(file); // Read from file GZIPInputStream gzis = new GZIPInputStream(fis); // Uncompress ObjectInputStream in = new ObjectInputStream(gzis); // Read objects // Read in an object. It should be a vector of scribbles TreeSet<Position> temp = (TreeSet<Position>) in.readObject(); _log.info(temp.size() + " map vertices loaded from file " + file.getName()); in.close(); // Close the stream. for (Position p : temp) { _coordList.add(new Coord(p._x, p._y, p._z)); } } } public class UniverseDump implements Runnable { /* (non-Javadoc) * @see java.lang.Runnable#run() */ public void run() { int size = _coordList.size(); //System.out.println("Univere Map has " + _map.size() + " nodes."); if (size > 100000) { flush(); } } } public void flush() { //System.out.println("Size of dump: "+coordList.size()); List<Coord> oldMap = _coordList; _coordList = new LinkedList<Coord>(); int size = oldMap.size(); dump(oldMap, true); _log.info("Universe Map : Dumped " + size + " vertices."); } public int size() { int size = 0; if (_coordList != null) size = _coordList.size(); return size; } public void dump(List<Coord> _map, boolean b) { try { String pad = ""; if (b) pad = "" + System.currentTimeMillis(); FileOutputStream fos = new FileOutputStream("data/universe" + pad + ".fin"); // Save to file DataOutputStream data = new DataOutputStream(fos); int count = _map.size(); //System.out.println("Size of dump: "+count); data.writeInt(count); if (_map != null) { for (Coord p : _map) { if (p != null) { data.writeInt(p._x); data.writeInt(p._y); data.writeInt(p._z); } } } data.flush(); data.close(); _log.info("Universe Map saved to: " + "data/universe" + pad + ".fin"); } catch (Exception e) { e.printStackTrace(); } } // prepare for shutdown public void implode(boolean b) { createMap(); dump(_coordList, b); } }