ZoneData.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. /*
  2. * This program is free software: you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation, either version 3 of the License, or (at your option) any later
  5. * version.
  6. *
  7. * This program is distributed in the hope that it will be useful, but WITHOUT
  8. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  9. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  10. * details.
  11. *
  12. * You should have received a copy of the GNU General Public License along with
  13. * this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. package net.sf.l2j.gameserver.datatables;
  16. import java.io.File;
  17. import java.sql.PreparedStatement;
  18. import java.sql.ResultSet;
  19. import java.util.logging.Level;
  20. import java.util.logging.Logger;
  21. import javax.xml.parsers.DocumentBuilderFactory;
  22. import javolution.util.FastList;
  23. import net.sf.l2j.Config;
  24. import net.sf.l2j.L2DatabaseFactory;
  25. import net.sf.l2j.gameserver.instancemanager.ArenaManager;
  26. import net.sf.l2j.gameserver.instancemanager.FishingZoneManager;
  27. import net.sf.l2j.gameserver.instancemanager.GrandBossManager;
  28. import net.sf.l2j.gameserver.instancemanager.OlympiadStadiaManager;
  29. import net.sf.l2j.gameserver.instancemanager.TownManager;
  30. import net.sf.l2j.gameserver.model.L2World;
  31. import net.sf.l2j.gameserver.model.L2WorldRegion;
  32. import net.sf.l2j.gameserver.model.zone.L2ZoneType;
  33. import net.sf.l2j.gameserver.model.zone.form.ZoneCuboid;
  34. import net.sf.l2j.gameserver.model.zone.form.ZoneNPoly;
  35. import net.sf.l2j.gameserver.model.zone.type.L2ArenaZone;
  36. import net.sf.l2j.gameserver.model.zone.type.L2BigheadZone;
  37. import net.sf.l2j.gameserver.model.zone.type.L2BossZone;
  38. import net.sf.l2j.gameserver.model.zone.type.L2CastleTeleportZone;
  39. import net.sf.l2j.gameserver.model.zone.type.L2CastleZone;
  40. import net.sf.l2j.gameserver.model.zone.type.L2ClanHallZone;
  41. import net.sf.l2j.gameserver.model.zone.type.L2DamageZone;
  42. import net.sf.l2j.gameserver.model.zone.type.L2DerbyTrackZone;
  43. import net.sf.l2j.gameserver.model.zone.type.L2FishingZone;
  44. import net.sf.l2j.gameserver.model.zone.type.L2FortZone;
  45. import net.sf.l2j.gameserver.model.zone.type.L2JailZone;
  46. import net.sf.l2j.gameserver.model.zone.type.L2MotherTreeZone;
  47. import net.sf.l2j.gameserver.model.zone.type.L2NoLandingZone;
  48. import net.sf.l2j.gameserver.model.zone.type.L2OlympiadStadiumZone;
  49. import net.sf.l2j.gameserver.model.zone.type.L2TownZone;
  50. import net.sf.l2j.gameserver.model.zone.type.L2WaterZone;
  51. import org.w3c.dom.Document;
  52. import org.w3c.dom.NamedNodeMap;
  53. import org.w3c.dom.Node;
  54. /**
  55. * This class manages the augmentation data and can also create new augmentations.
  56. *
  57. * @author durgus
  58. */
  59. public class ZoneData
  60. {
  61. private static final Logger _log = Logger.getLogger(ZoneData.class.getName());
  62. // =========================================================
  63. private static ZoneData _instance;
  64. public static final ZoneData getInstance()
  65. {
  66. if (_instance == null)
  67. {
  68. _instance = new ZoneData();
  69. }
  70. return _instance;
  71. }
  72. // =========================================================
  73. // Data Field
  74. // =========================================================
  75. // Constructor
  76. public ZoneData()
  77. {
  78. _log.info("Loading zones...");
  79. load();
  80. }
  81. // =========================================================
  82. // Method - Private
  83. private final void load()
  84. {
  85. java.sql.Connection con = null;
  86. int zoneCount = 0;
  87. // Get the world regions
  88. L2WorldRegion[][] worldRegions = L2World.getInstance().getAllWorldRegions();
  89. // Load the zone xml
  90. try
  91. {
  92. // Get a sql connection here
  93. con = L2DatabaseFactory.getInstance().getConnection();
  94. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  95. factory.setValidating(false);
  96. factory.setIgnoringComments(true);
  97. File file = new File(Config.DATAPACK_ROOT+"/data/zones/zone.xml");
  98. if (!file.exists())
  99. {
  100. if (Config.DEBUG)
  101. _log.info("The zone.xml file is missing.");
  102. return;
  103. }
  104. Document doc = factory.newDocumentBuilder().parse(file);
  105. for (Node n=doc.getFirstChild(); n != null; n = n.getNextSibling())
  106. {
  107. if ("list".equalsIgnoreCase(n.getNodeName()))
  108. {
  109. for (Node d=n.getFirstChild(); d != null; d = d.getNextSibling())
  110. {
  111. if ("zone".equalsIgnoreCase(d.getNodeName()))
  112. {
  113. NamedNodeMap attrs = d.getAttributes();
  114. int zoneId = Integer.parseInt(attrs.getNamedItem("id").getNodeValue());
  115. int minZ = Integer.parseInt(attrs.getNamedItem("minZ").getNodeValue());
  116. int maxZ = Integer.parseInt(attrs.getNamedItem("maxZ").getNodeValue());
  117. String zoneType = attrs.getNamedItem("type").getNodeValue();
  118. String zoneShape = attrs.getNamedItem("shape").getNodeValue();
  119. // Create the zone
  120. L2ZoneType temp = null;
  121. if (zoneType.equals("FishingZone"))
  122. temp = new L2FishingZone(zoneId);
  123. else if (zoneType.equals("ClanHallZone"))
  124. temp = new L2ClanHallZone(zoneId);
  125. else if (zoneType.equals("Town"))
  126. temp = new L2TownZone(zoneId);
  127. else if (zoneType.equals("OlympiadStadium"))
  128. temp = new L2OlympiadStadiumZone(zoneId);
  129. else if (zoneType.equals("CastleZone"))
  130. temp = new L2CastleZone(zoneId);
  131. else if (zoneType.equals("CastleTeleportZone"))
  132. temp = new L2CastleTeleportZone(zoneId);
  133. else if (zoneType.equals("FortZone"))
  134. temp = new L2FortZone(zoneId);
  135. else if (zoneType.equals("DamageZone"))
  136. temp = new L2DamageZone(zoneId);
  137. else if (zoneType.equals("Arena"))
  138. temp = new L2ArenaZone(zoneId);
  139. else if (zoneType.equals("MotherTree"))
  140. temp = new L2MotherTreeZone(zoneId);
  141. else if (zoneType.equals("BigheadZone"))
  142. temp = new L2BigheadZone(zoneId);
  143. else if (zoneType.equals("NoLandingZone"))
  144. temp = new L2NoLandingZone(zoneId);
  145. else if (zoneType.equals("JailZone"))
  146. temp = new L2JailZone(zoneId);
  147. else if (zoneType.equals("DerbyTrackZone"))
  148. temp = new L2DerbyTrackZone(zoneId);
  149. else if (zoneType.equals("BossZone"))
  150. temp = new L2BossZone(zoneId);
  151. else if (zoneType.equals("WaterZone"))
  152. temp = new L2WaterZone(zoneId);
  153. // Check for unknown type
  154. if (temp == null)
  155. {
  156. _log.warning("ZoneData: No such zone type: "+zoneType);
  157. continue;
  158. }
  159. // Get the zone shape from sql
  160. try
  161. {
  162. PreparedStatement statement = null;
  163. // Set the correct query
  164. statement = con.prepareStatement("SELECT x,y FROM zone_vertices WHERE id=? ORDER BY 'order' ASC ");
  165. statement.setInt(1, zoneId);
  166. ResultSet rset = statement.executeQuery();
  167. // Create this zone. Parsing for cuboids is a bit different than for other polygons
  168. // cuboids need exactly 2 points to be defined. Other polygons need at least 3 (one per vertex)
  169. if (zoneShape.equals("Cuboid"))
  170. {
  171. int[] x = {0,0};
  172. int[] y = {0,0};
  173. boolean successfulLoad = true;
  174. for (int i=0;i<2; i++)
  175. {
  176. if ( rset.next() )
  177. {
  178. x[i] = rset.getInt("x");
  179. y[i] = rset.getInt("y");
  180. }
  181. else
  182. {
  183. _log.warning("ZoneData: Missing cuboid vertex in sql data for zone: "+zoneId);
  184. rset.close();
  185. statement.close();
  186. successfulLoad = false;
  187. break;
  188. }
  189. }
  190. if (successfulLoad)
  191. temp.setZone(new ZoneCuboid(x[0],x[1], y[0],y[1],minZ,maxZ));
  192. else
  193. continue;
  194. }
  195. else if (zoneShape.equals("NPoly"))
  196. {
  197. FastList<Integer> fl_x = new FastList<Integer>(), fl_y = new FastList<Integer>();
  198. // Load the rest
  199. while (rset.next())
  200. {
  201. fl_x.add(rset.getInt("x"));
  202. fl_y.add(rset.getInt("y"));
  203. }
  204. // An nPoly needs to have at least 3 vertices
  205. if ((fl_x.size() == fl_y.size()) && (fl_x.size() > 2))
  206. {
  207. // Create arrays
  208. int[] aX = new int[fl_x.size()];
  209. int[] aY = new int[fl_y.size()];
  210. // This runs only at server startup so dont complain :>
  211. for (int i=0; i < fl_x.size(); i++) { aX[i] = fl_x.get(i); aY[i] = fl_y.get(i); }
  212. // Create the zone
  213. temp.setZone(new ZoneNPoly(aX, aY, minZ, maxZ));
  214. }
  215. else
  216. {
  217. _log.warning("ZoneData: Bad sql data for zone: "+zoneId);
  218. rset.close();
  219. statement.close();
  220. continue;
  221. }
  222. }
  223. else
  224. {
  225. _log.warning("ZoneData: Unknown shape: "+zoneShape);
  226. rset.close();
  227. statement.close();
  228. continue;
  229. }
  230. rset.close();
  231. statement.close();
  232. }
  233. catch (Exception e)
  234. {
  235. _log.warning("ZoneData: Failed to load zone coordinates: " + e);
  236. }
  237. // Check for aditional parameters
  238. for (Node cd=d.getFirstChild(); cd != null; cd = cd.getNextSibling())
  239. {
  240. if ("stat".equalsIgnoreCase(cd.getNodeName()))
  241. {
  242. attrs = cd.getAttributes();
  243. String name = attrs.getNamedItem("name").getNodeValue();
  244. String val = attrs.getNamedItem("val").getNodeValue();
  245. temp.setParameter(name, val);
  246. }
  247. }
  248. // Skip checks for fishing zones & add to fishing zone manager
  249. if (temp instanceof L2FishingZone)
  250. {
  251. FishingZoneManager.getInstance().addFishingZone((L2FishingZone)temp);
  252. continue;
  253. }
  254. // Register the zone into any world region it intersects with...
  255. // currently 11136 test for each zone :>
  256. int ax,ay,bx,by;
  257. for (int x=0; x < worldRegions.length; x++)
  258. {
  259. for (int y=0; y < worldRegions[x].length; y++)
  260. {
  261. ax = (x-L2World.OFFSET_X) << L2World.SHIFT_BY;
  262. bx = ((x+1)-L2World.OFFSET_X) << L2World.SHIFT_BY;
  263. ay = (y-L2World.OFFSET_Y) << L2World.SHIFT_BY;
  264. by = ((y+1)-L2World.OFFSET_Y) << L2World.SHIFT_BY;
  265. if (temp.getZone().intersectsRectangle(ax, bx, ay, by))
  266. {
  267. if (Config.DEBUG)
  268. {
  269. _log.info("Zone ("+zoneId+") added to: "+x+" "+y);
  270. }
  271. worldRegions[x][y].addZone(temp);
  272. }
  273. }
  274. }
  275. // Special managers for arenas, towns...
  276. if (temp instanceof L2ArenaZone)
  277. ArenaManager.getInstance().addArena((L2ArenaZone)temp);
  278. else if (temp instanceof L2TownZone)
  279. TownManager.getInstance().addTown((L2TownZone)temp);
  280. else if (temp instanceof L2OlympiadStadiumZone)
  281. OlympiadStadiaManager.getInstance().addStadium((L2OlympiadStadiumZone)temp);
  282. else if (temp instanceof L2BossZone)
  283. GrandBossManager.getInstance().addZone((L2BossZone) temp);
  284. // Increase the counter
  285. zoneCount++;
  286. }
  287. }
  288. }
  289. }
  290. }
  291. catch (Exception e)
  292. {
  293. _log.log(Level.SEVERE, "Error while loading zones.", e);
  294. return ;
  295. }
  296. finally
  297. {
  298. try
  299. {
  300. con.close();
  301. }
  302. catch (Exception e)
  303. {
  304. }
  305. }
  306. GrandBossManager.getInstance().initZones();
  307. _log.info("Done: loaded "+zoneCount+" zones.");
  308. }
  309. }