MapleMapFactory.java
上传用户:gwt600
上传日期:2021-06-03
资源大小:704k
文件大小:17k
源码类别:

游戏

开发平台:

Java

  1. /*
  2. This file is part of the OdinMS Maple Story Server
  3. Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
  4. Matthias Butz <matze@odinms.de>
  5. Jan Christian Meyer <vimes@odinms.de>
  6. This program is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU Affero General Public License version 3
  8. as published by the Free Software Foundation. You may not use, modify
  9. or distribute this program under any other version of the
  10. GNU Affero General Public License.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU Affero General Public License for more details.
  15. You should have received a copy of the GNU Affero General Public License
  16. along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17.  */
  18. package net.sf.odinms.server.maps;
  19. import java.awt.Rectangle;
  20. import java.sql.SQLException;
  21. import java.util.HashMap;
  22. import java.util.LinkedList;
  23. import java.util.List;
  24. import java.util.Map;
  25. import java.awt.Point;
  26. import java.sql.Connection;
  27. import java.sql.PreparedStatement;
  28. import java.sql.ResultSet;
  29. import net.sf.odinms.client.MapleCharacter;
  30. import net.sf.odinms.client.MapleClient;
  31. import net.sf.odinms.database.DatabaseConnection;
  32. import net.sf.odinms.net.channel.ChannelServer;
  33. import net.sf.odinms.provider.MapleData;
  34. import net.sf.odinms.provider.MapleDataProvider;
  35. import net.sf.odinms.provider.MapleDataTool;
  36. import net.sf.odinms.server.MaplePortal;
  37. import net.sf.odinms.server.PortalFactory;
  38. import net.sf.odinms.server.life.AbstractLoadedMapleLife;
  39. import net.sf.odinms.server.life.MapleLifeFactory;
  40. import net.sf.odinms.server.life.MapleMonster;
  41. import net.sf.odinms.server.life.MapleNPC;
  42. import net.sf.odinms.tools.MockIOSession;
  43. import net.sf.odinms.tools.StringUtil;
  44. public class MapleMapFactory {
  45.     private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(MapleMapFactory.class);
  46.     private MapleDataProvider source;
  47.     private MapleData nameData;
  48.     private Map<Integer, MapleMap> maps = new HashMap<Integer, MapleMap>();
  49.     private int channel;
  50.     public MapleMapFactory(MapleDataProvider source, MapleDataProvider stringSource) {
  51.         this.source = source;
  52.         this.nameData = stringSource.getData("Map.img");
  53.     }
  54.     public MapleMap getMap(int mapid) {
  55.         return getMap(mapid, true, true, true);
  56.     }
  57.     //backwards-compatible
  58.     public MapleMap getMap(int mapid, boolean respawns, boolean npcs) {
  59.         return getMap(mapid, respawns, npcs, true);
  60.     }
  61.     public MapleMap getMap(int mapid, boolean respawns, boolean npcs, boolean reactors) {
  62.         Integer omapid = Integer.valueOf(mapid);
  63.         MapleMap map = maps.get(omapid);
  64.         if (map == null) {
  65.             synchronized (this) {
  66.                 // check if someone else who was also synchronized has loaded the map already
  67.                 map = maps.get(omapid);
  68.                 if (map != null) {
  69.                     return map;
  70.                 }
  71.                 String mapName = getMapName(mapid);
  72.                 MapleData mapData = source.getData(mapName);
  73.                 float monsterRate = 0;
  74.                 if (respawns) {
  75.                     MapleData mobRate = mapData.getChildByPath("info/mobRate");
  76.                     if (mobRate != null) {
  77.                         monsterRate = ((Float) mobRate.getData()).floatValue();
  78.                     }
  79.                 }
  80.                 map = new MapleMap(mapid, channel, MapleDataTool.getInt("info/returnMap", mapData), monsterRate);
  81.                 PortalFactory portalFactory = new PortalFactory();
  82.                 for (MapleData portal : mapData.getChildByPath("portal")) {
  83.                     int type = MapleDataTool.getInt(portal.getChildByPath("pt"));
  84.                     MaplePortal myPortal = portalFactory.makePortal(type, portal);
  85.                     map.addPortal(myPortal);
  86.                 }
  87.                 List<MapleFoothold> allFootholds = new LinkedList<MapleFoothold>();
  88.                 Point lBound = new Point();
  89.                 Point uBound = new Point();
  90.                 for (MapleData footRoot : mapData.getChildByPath("foothold")) {
  91.                     for (MapleData footCat : footRoot) {
  92.                         for (MapleData footHold : footCat) {
  93.                             int x1 = MapleDataTool.getInt(footHold.getChildByPath("x1"));
  94.                             int y1 = MapleDataTool.getInt(footHold.getChildByPath("y1"));
  95.                             int x2 = MapleDataTool.getInt(footHold.getChildByPath("x2"));
  96.                             int y2 = MapleDataTool.getInt(footHold.getChildByPath("y2"));
  97.                             MapleFoothold fh = new MapleFoothold(new Point(x1, y1), new Point(x2, y2), Integer.parseInt(footHold.getName()));
  98.                             fh.setPrev(MapleDataTool.getInt(footHold.getChildByPath("prev")));
  99.                             fh.setNext(MapleDataTool.getInt(footHold.getChildByPath("next")));
  100.                             if (fh.getX1() < lBound.x) {
  101.                                 lBound.x = fh.getX1();
  102.                             }
  103.                             if (fh.getX2() > uBound.x) {
  104.                                 uBound.x = fh.getX2();
  105.                             }
  106.                             if (fh.getY1() < lBound.y) {
  107.                                 lBound.y = fh.getY1();
  108.                             }
  109.                             if (fh.getY2() > uBound.y) {
  110.                                 uBound.y = fh.getY2();
  111.                             }
  112.                             allFootholds.add(fh);
  113.                         }
  114.                     }
  115.                 }
  116.                 MapleFootholdTree fTree = new MapleFootholdTree(lBound, uBound);
  117.                 for (MapleFoothold fh : allFootholds) {
  118.                     fTree.insert(fh);
  119.                 }
  120.                 map.setFootholds(fTree);
  121.                 // load areas (EG PQ platforms)
  122.                 if (mapData.getChildByPath("area") != null) {
  123.                     for (MapleData area : mapData.getChildByPath("area")) {
  124.                         int x1 = MapleDataTool.getInt(area.getChildByPath("x1"));
  125.                         int y1 = MapleDataTool.getInt(area.getChildByPath("y1"));
  126.                         int x2 = MapleDataTool.getInt(area.getChildByPath("x2"));
  127.                         int y2 = MapleDataTool.getInt(area.getChildByPath("y2"));
  128.                         Rectangle mapArea = new Rectangle(x1, y1, (x2 - x1), (y2 - y1));
  129.                         map.addMapleArea(mapArea);
  130.                     }
  131.                 }
  132.                 try {
  133.                     Connection con = DatabaseConnection.getConnection();
  134.                     PreparedStatement ps = con.prepareStatement("SELECT * FROM spawns WHERE mid = ?");
  135.                     ps.setInt(1, omapid);
  136.                     ResultSet rs = ps.executeQuery();
  137.                     while (rs.next()) {
  138.                         int id = rs.getInt("idd");
  139.                         int f = rs.getInt("f");
  140.                         boolean hide = false;
  141.                         String type = rs.getString("type");
  142.                         int fh = rs.getInt("fh");
  143.                         int cy = rs.getInt("cy");
  144.                         int rx0 = rs.getInt("rx0");
  145.                         int rx1 = rs.getInt("rx1");
  146.                         int x = rs.getInt("x");
  147.                         int y = rs.getInt("y");
  148.                         int mobTime = rs.getInt("mobtime");
  149.                         AbstractLoadedMapleLife myLife = loadLife(id, f, hide, fh, cy, rx0, rx1, x, y, type);
  150.                         if (type.equals("n")) {
  151.                             map.addMapObject(myLife);
  152.                         } else if (type.equals("m")) {
  153.                             MapleMonster monster = (MapleMonster) myLife;
  154.                             map.addMonsterSpawn(monster, mobTime);
  155.                         }
  156.                     }
  157.                     ps.close();
  158.                     rs.close();
  159.                     PreparedStatement ps2 = con.prepareStatement("SELECT * FROM playernpcs WHERE map = ?");
  160.                     ps2.setInt(1, omapid);
  161.                     ResultSet rs2 = ps2.executeQuery();
  162.                     while (rs2.next()) {
  163.                         map.addMapObject(new PlayerNPCs(rs2));
  164.                     }
  165.                     rs2.close();
  166.                     ps2.close();
  167.                 } catch (SQLException e) {
  168.                     e.printStackTrace();
  169.                 }
  170.                 // load life data (npc, monsters)
  171.                 for (MapleData life : mapData.getChildByPath("life")) {
  172.                     String id = MapleDataTool.getString(life.getChildByPath("id"));
  173.                     String type = MapleDataTool.getString(life.getChildByPath("type"));
  174.                     if (npcs || !type.equals("n")) {
  175.                         AbstractLoadedMapleLife myLife = loadLife(life, id, type);
  176.                         if (myLife instanceof MapleMonster) {
  177.                             // ((MapleMonster) myLife).calcFhBounds(allFootholds);
  178.                             MapleMonster monster = (MapleMonster) myLife;
  179.                             int mobTime = MapleDataTool.getInt("mobTime", life, 0);
  180.                             if (monster.isBoss()) {
  181.                                 mobTime += mobTime / 10 * (2.5 + 10 * Math.random());
  182.                             }
  183.                             if (mobTime == -1 && respawns) { //does not respawn, force spawn once
  184.                                 map.spawnMonster(monster);
  185.                             } else {
  186.                                 map.addMonsterSpawn(monster, mobTime);
  187.                             }
  188.                         } else if (myLife instanceof MapleNPC) {
  189.                             map.addMapObject(myLife);
  190.                         } else {
  191.                             map.addMapObject(myLife);
  192.                         }
  193.                     }
  194.                 }
  195.                 //load reactor data
  196.                 if (reactors && mapData.getChildByPath("reactor") != null) {
  197.                     for (MapleData reactor : mapData.getChildByPath("reactor")) {
  198.                         String id = MapleDataTool.getString(reactor.getChildByPath("id"));
  199.                         if (id != null) {
  200.                             MapleReactor newReactor = loadReactor(reactor, id);
  201.                             map.spawnReactor(newReactor);
  202.                         }
  203.                     }
  204.                 }
  205.                 try {
  206.                     map.setMapName(MapleDataTool.getString("mapName", nameData.getChildByPath(getMapStringName(omapid)), ""));
  207.                     map.setStreetName(MapleDataTool.getString("streetName", nameData.getChildByPath(getMapStringName(omapid)), ""));
  208.                 } catch (Exception e) {
  209.                     map.setMapName("");
  210.                     map.setStreetName("");
  211.                 }
  212.                 map.setClock(mapData.getChildByPath("clock") != null);
  213.                 map.setEverlast(mapData.getChildByPath("everlast") != null);
  214.                 map.setTown(mapData.getChildByPath("town") != null);
  215.                 map.setHPDec(MapleDataTool.getIntConvert("decHP", mapData, 0));
  216.                 map.setHPDecProtect(MapleDataTool.getIntConvert("protectItem", mapData, 0));
  217.                 map.setForcedReturnMap(MapleDataTool.getInt(mapData.getChildByPath("info/forcedReturn"), 999999999));
  218.                 if (mapData.getChildByPath("shipObj") != null) {
  219.                     map.setBoat(true);
  220.                 } else {
  221.                     map.setBoat(false);
  222.                 }
  223.                 map.setTimeLimit(MapleDataTool.getIntConvert("timeLimit", mapData.getChildByPath("info"), -1));
  224.                 maps.put(omapid, map);
  225.                 if (channel > 0 && Boolean.parseBoolean(ChannelServer.getInstance(channel).getProperty("net.sf.odinms.world.faekchar"))) {
  226.                     MapleClient faek = new MapleClient(null, null, new MockIOSession());
  227.                     try {
  228.                         MapleCharacter faekchar = MapleCharacter.loadCharFromDB(30000, faek, true);
  229.                         faek.setPlayer(faekchar);
  230.                         faekchar.setPosition(new Point(0, 0));
  231.                         faekchar.setMap(map);
  232.                         map.addPlayer(faekchar);
  233.                     } catch (SQLException e) {
  234.                         log.error("Loading FAEK failed", e);
  235.                     }
  236.                 }
  237.             }
  238.         }
  239.         return map;
  240.     }
  241.     public void disposeMap(int mapId) {
  242. synchronized (maps) {
  243. if (maps.containsKey(mapId)) {
  244. maps.remove(mapId);
  245. }
  246. }
  247. }
  248.     public int getLoadedMaps() {
  249.         return maps.size();
  250.     }
  251.     private AbstractLoadedMapleLife loadLife(int id, int f, boolean hide, int fh, int cy, int rx0, int rx1, int x, int y, String type) {
  252.         AbstractLoadedMapleLife myLife = MapleLifeFactory.getLife(id, type);
  253.         myLife.setCy(cy);
  254.         myLife.setF(f);
  255.         myLife.setFh(fh);
  256.         myLife.setRx0(rx0);
  257.         myLife.setRx1(rx1);
  258.         myLife.setPosition(new Point(x, y));
  259.         myLife.setHide(hide);
  260.         return myLife;
  261.     }
  262.     public boolean isMapLoaded(int mapId) {
  263.         return maps.containsKey(mapId);
  264.     }
  265.     private AbstractLoadedMapleLife loadLife(MapleData life, String id, String type) {
  266.         AbstractLoadedMapleLife myLife = MapleLifeFactory.getLife(Integer.parseInt(id), type);
  267.         myLife.setCy(MapleDataTool.getInt(life.getChildByPath("cy")));
  268.         MapleData dF = life.getChildByPath("f");
  269.         if (dF != null) {
  270.             myLife.setF(MapleDataTool.getInt(dF));
  271.         }
  272.         myLife.setFh(MapleDataTool.getInt(life.getChildByPath("fh")));
  273.         myLife.setRx0(MapleDataTool.getInt(life.getChildByPath("rx0")));
  274.         myLife.setRx1(MapleDataTool.getInt(life.getChildByPath("rx1")));
  275.         int x = MapleDataTool.getInt(life.getChildByPath("x"));
  276.         int y = MapleDataTool.getInt(life.getChildByPath("y"));
  277.         myLife.setPosition(new Point(x, y));
  278.         int hide = MapleDataTool.getInt("hide", life, 0);
  279.         if (hide == 1) {
  280.             myLife.setHide(true);
  281.         } else if (hide > 1) {
  282.             log.warn("Hide > 1 ({})", hide);
  283.         }
  284.         return myLife;
  285.     }
  286.     private MapleReactor loadReactor(MapleData reactor, String id) {
  287.         MapleReactor myReactor = new MapleReactor(MapleReactorFactory.getReactor(Integer.parseInt(id)), Integer.parseInt(id));
  288.         int x = MapleDataTool.getInt(reactor.getChildByPath("x"));
  289.         int y = MapleDataTool.getInt(reactor.getChildByPath("y"));
  290.         myReactor.setPosition(new Point(x, y));
  291.         myReactor.setDelay(MapleDataTool.getInt(reactor.getChildByPath("reactorTime")) * 1000);
  292.         myReactor.setState((byte) 0);
  293.         myReactor.setName(MapleDataTool.getString(reactor.getChildByPath("name"), ""));
  294.         return myReactor;
  295.     }
  296.     private String getMapName(int mapid) {
  297.         String mapName = StringUtil.getLeftPaddedStr(Integer.toString(mapid), '0', 9);
  298.         StringBuilder builder = new StringBuilder("Map/Map");
  299.         int area = mapid / 100000000;
  300.         builder.append(area);
  301.         builder.append("/");
  302.         builder.append(mapName);
  303.         builder.append(".img");
  304.         mapName = builder.toString();
  305.         return mapName;
  306.     }
  307.     private String getMapStringName(int mapid) {
  308.         StringBuilder builder = new StringBuilder();
  309.         if (mapid < 100000000) {
  310.             builder.append("maple");
  311.         } else if (mapid >= 100000000 && mapid < 200000000) {
  312.             builder.append("victoria");
  313.         } else if (mapid >= 200000000 && mapid < 300000000) {
  314.             builder.append("ossyria");
  315.         } else if (mapid >= 540000000 && mapid < 541010110) {
  316.             builder.append("singapore");
  317.         } else if (mapid >= 600000000 && mapid < 620000000) {
  318.             builder.append("MasteriaGL");
  319.         } else if (mapid >= 670000000 && mapid < 682000000) {
  320.             builder.append("weddingGL");
  321.         } else if (mapid >= 682000000 && mapid < 683000000) {
  322.             builder.append("HalloweenGL");
  323.         } else if (mapid >= 800000000 && mapid < 900000000) {
  324.             builder.append("jp");
  325.         } else {
  326.             builder.append("etc");
  327.         }
  328.         builder.append("/");
  329.         builder.append(mapid);
  330.         String mapName = builder.toString();
  331.         return mapName;
  332.     }
  333.     public void setChannel(int channel) {
  334.         this.channel = channel;
  335.     }
  336. }