Package com.l2jfrozen.gameserver.managers

Source Code of com.l2jfrozen.gameserver.managers.GrandBossManager

/*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jfrozen.gameserver.managers;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.l2jfrozen.Config;
import com.l2jfrozen.gameserver.datatables.sql.NpcTable;
import com.l2jfrozen.gameserver.model.L2Character;
import com.l2jfrozen.gameserver.model.L2Object;
import com.l2jfrozen.gameserver.model.actor.instance.L2GrandBossInstance;
import com.l2jfrozen.gameserver.model.zone.type.L2BossZone;
import com.l2jfrozen.gameserver.templates.L2NpcTemplate;
import com.l2jfrozen.gameserver.templates.StatsSet;
import com.l2jfrozen.util.CloseUtil;
import com.l2jfrozen.util.database.L2DatabaseFactory;

/**
* This class handles all Grand Bosses:
* <ul>
* <li>22215-22217  Tyrannosaurus</li>
* <li>25333-25338  Anakazel</li>
* <li>29001        Queen Ant</li>
* <li>29006        Core</li>
* <li>29014        Orfen</li>
* <li>29019        Antharas</li>
* <li>29020        Baium</li>
* <li>29022        Zaken</li>
* <li>29028        Valakas</li>
* <li>29045        Frintezza</li>
* <li>29046-29047  Scarlet van Halisha</li>
* </ul>
*
* It handles the saving of hp, mp, location, and status of all Grand Bosses. It also manages the zones associated with the Grand Bosses.
* NOTE: The current version does NOT spawn the Grand Bosses, it just stores and retrieves the values on reboot/startup, for AI scripts to utilize as needed.
* @author DaRkRaGe Revised by Emperorc
*/
public class GrandBossManager
{
  protected static final Logger _log = Logger.getLogger(GrandBossManager.class.getName());
 
  private static final String DELETE_GRAND_BOSS_LIST = "DELETE FROM grandboss_list";
  private static final String INSERT_GRAND_BOSS_LIST = "INSERT INTO grandboss_list (player_id,zone) VALUES (?,?)";
  private static final String UPDATE_GRAND_BOSS_DATA = "UPDATE grandboss_data set loc_x = ?, loc_y = ?, loc_z = ?, heading = ?, respawn_time = ?, currentHP = ?, currentMP = ?, status = ? where boss_id = ?";
  private static final String UPDATE_GRAND_BOSS_DATA2 = "UPDATE grandboss_data set status = ? where boss_id = ?";
 
  private static GrandBossManager _instance;

  protected static Map<Integer, L2GrandBossInstance> _bosses;

  protected static Map<Integer, StatsSet> _storedInfo;

  private Map<Integer, Integer> _bossStatus;

  private List<L2BossZone> _zones;

  public static GrandBossManager getInstance()
  {
    if(_instance == null)
    {
      _log.info("Initializing GrandBossManager");
      _instance = new GrandBossManager();
    }
    return _instance;
  }

  public GrandBossManager()
  {
    init();
  }

  private void init()
  {
    _zones = new CopyOnWriteArrayList<L2BossZone>();
    _bosses = new ConcurrentHashMap<Integer, L2GrandBossInstance>();
    _storedInfo = new ConcurrentHashMap<Integer, StatsSet>();
    _bossStatus = new ConcurrentHashMap<Integer, Integer>();
    Connection con = null;
    try
    {
      con = L2DatabaseFactory.getInstance().getConnection(false);

      PreparedStatement statement = con.prepareStatement("SELECT * from grandboss_data ORDER BY boss_id");
      ResultSet rset = statement.executeQuery();
      while(rset.next())
      {
        //Read all info from DB, and store it for AI to read and decide what to do
        //faster than accessing DB in real time
        StatsSet info = new StatsSet();
        int bossId = rset.getInt("boss_id");
        info.set("loc_x", rset.getInt("loc_x"));
        info.set("loc_y", rset.getInt("loc_y"));
        info.set("loc_z", rset.getInt("loc_z"));
        info.set("heading", rset.getInt("heading"));
        info.set("respawn_time", rset.getLong("respawn_time"));
        double HP = rset.getDouble("currentHP"); //jython doesn't recognize doubles
        int true_HP = (int) HP; //so use java's ability to type cast
        info.set("currentHP", true_HP); //to convert double to int
        double MP = rset.getDouble("currentMP");
        int true_MP = (int) MP;
        info.set("currentMP", true_MP);
        _bossStatus.put(bossId, rset.getInt("status"));

        _storedInfo.put(bossId, info);
        info = null;
      }

      _log.info("GrandBossManager: Loaded " + _storedInfo.size() + " Instances");

      rset.close();
      statement.close();
    }
    catch(SQLException e)
    {
      if(Config.ENABLE_ALL_EXCEPTIONS)
        e.printStackTrace();
     
      _log.warning("GrandBossManager: Could not load grandboss_data table");
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      CloseUtil.close(con);
    }
  }
 
  public void initZones()
  {
    if(_zones == null)
    {
      _log.warning("GrandBossManager: Could not read Grand Boss zone data");
      return;
    }

    Map<Integer, List<Integer>> zones = new ConcurrentHashMap<Integer, List<Integer>>();
    for(L2BossZone zone : _zones)
    {
      if(zone == null)
      {
        continue;
      }
      zones.put(zone.getId(), new CopyOnWriteArrayList<Integer>());
    }
   
    Connection con = null;
    try
    {
      con = L2DatabaseFactory.getInstance().getConnection(false);
      PreparedStatement statement = con.prepareStatement("SELECT * from grandboss_list ORDER BY player_id");
      ResultSet rset = statement.executeQuery();
      while(rset.next())
      {
        zones.get(rset.getInt("zone")).add(rset.getInt("player_id"));
      }
      rset.close();
      statement.close();
      _log.info("GrandBossManager: Initialized " + _zones.size() + " Grand Boss Zones");
    }
    catch(SQLException e)
    {
      _log.warning("GrandBossManager: Could not load grandboss_list table");
      if(Config.ENABLE_ALL_EXCEPTIONS)
        e.printStackTrace();
     
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      CloseUtil.close(con);
    }

    for(L2BossZone zone : _zones)
    {
      if(zone == null)
      {
        continue;
      }
      zone.setAllowedPlayers(zones.get(zone.getId()));
    }
    zones.clear();
  }

  public void addZone(L2BossZone zone)
  {
    if(_zones != null)
    {
      _zones.add(zone);
    }
  }

  public final L2BossZone getZone(L2Character character)
  {
    if(_zones != null)
    {
      for(L2BossZone temp : _zones)
      {
        if(temp.isCharacterInZone(character))
          return temp;
      }
    }
    return null;
  }

  public final L2BossZone getZone(int x, int y, int z)
  {
    if(_zones != null)
    {
      for(L2BossZone temp : _zones)
      {
        if(temp.isInsideZone(x, y, z))
          return temp;
      }
    }
    return null;
  }

  public boolean checkIfInZone(String zoneType, L2Object obj)
  {
    L2BossZone temp = getZone(obj.getX(), obj.getY(), obj.getZ());
    if(temp == null)
      return false;
    return temp.getZoneName().equalsIgnoreCase(zoneType);
  }

  /*
   * The rest
   */

  public Integer getBossStatus(int bossId)
  {
    return _bossStatus.get(bossId);
  }

  /*
  public void setBossStatus(int bossId, int status)
  {
    _bossStatus.remove(bossId);
    _bossStatus.put(bossId, status);
  }
  */
  public void setBossStatus(int bossId, int status)
  {
    _bossStatus.put(bossId, status);
    _log.info(getClass().getSimpleName()+": Updated "+NpcTable.getInstance().getTemplate(bossId).getName()+"(" +bossId+ ") status to " +status);
    updateDb(bossId, true);
  }
 
  public void addBoss(L2GrandBossInstance boss)
  {
    if(boss != null)
    {
      _bosses.put(boss.getNpcId(), boss);
    }
  }

  public L2GrandBossInstance getBoss(int bossId)
  {
    return _bosses.get(bossId);
  }
 
  public L2GrandBossInstance deleteBoss(int bossId)
  {
    return _bosses.remove(bossId);
  }

  public StatsSet getStatsSet(int bossId)
  {
    return _storedInfo.get(bossId);
  }

  public void setStatsSet(int bossId, StatsSet info)
  {
    if(_storedInfo.containsKey(bossId))
    {
      _storedInfo.remove(bossId);
    }
    _storedInfo.put(bossId, info);
    //Update immediately status in Database.
    fastStoreToDb();
  }

  private void fastStoreToDb()
  {
    Connection con = null;
    try
    {
      con = L2DatabaseFactory.getInstance().getConnection(false);
      for(Integer bossId : _storedInfo.keySet())
      {
        L2GrandBossInstance boss = _bosses.get(bossId);
        StatsSet info = _storedInfo.get(bossId);
        if(boss == null || info == null)
        {
          PreparedStatement update2 = con.prepareStatement(UPDATE_GRAND_BOSS_DATA2);
          update2.setInt(1, _bossStatus.get(bossId));
          update2.setInt(2, bossId);
          update2.executeUpdate();
          update2.close();
        }
        else
        {
          PreparedStatement update1 = con.prepareStatement(UPDATE_GRAND_BOSS_DATA);
          update1.setInt(1, boss.getX());
          update1.setInt(2, boss.getY());
          update1.setInt(3, boss.getZ());
          update1.setInt(4, boss.getHeading());
          update1.setLong(5, info.getLong("respawn_time"));
          double hp = boss.getCurrentHp();
          double mp = boss.getCurrentMp();
          if(boss.isDead())
          {
            hp = boss.getMaxHp();
            mp = boss.getMaxMp();
          }
          update1.setDouble(6, hp);
          update1.setDouble(7, mp);
          update1.setInt(8, _bossStatus.get(bossId));
          update1.setInt(9, bossId);
          update1.executeUpdate();
          update1.close();
        }
      }
    }
    catch(SQLException e)
    {
      if(Config.ENABLE_ALL_EXCEPTIONS)
        e.printStackTrace();
      _log.warning("GrandBossManager[fastStoreToDb]: Couldn't store grandbosses to database:" + e);
    }
    finally
    {
      CloseUtil.close(con);
    }
  }

  private void storeToDb()
  {
    Connection con = null;
    try
    {
      con = L2DatabaseFactory.getInstance().getConnection(false);

      PreparedStatement delete = con.prepareStatement(DELETE_GRAND_BOSS_LIST);
      delete.executeUpdate();
      delete.close();

      for(L2BossZone zone : _zones)
      {
        if(zone == null)
        {
          continue;
        }
        Integer id = zone.getId();
        List<Integer> list = zone.getAllowedPlayers();
        if(list == null || list.isEmpty())
        {
          continue;
        }
        for(Integer player : list)
        {
          PreparedStatement insert = con.prepareStatement(INSERT_GRAND_BOSS_LIST);
          insert.setInt(1, player);
          insert.setInt(2, id);
          insert.executeUpdate();
          insert.close();
        }
      }

      for(Integer bossId : _storedInfo.keySet())
      {
        L2GrandBossInstance boss = _bosses.get(bossId);
        StatsSet info = _storedInfo.get(bossId);
        if(boss == null || info == null)
        {
          PreparedStatement update2 = con.prepareStatement(UPDATE_GRAND_BOSS_DATA2);
          update2.setInt(1, _bossStatus.get(bossId));
          update2.setInt(2, bossId);
          update2.executeUpdate();
          update2.close();
        }
        else
        {
          PreparedStatement update1 = con.prepareStatement(UPDATE_GRAND_BOSS_DATA);
          update1.setInt(1, boss.getX());
          update1.setInt(2, boss.getY());
          update1.setInt(3, boss.getZ());
          update1.setInt(4, boss.getHeading());
          update1.setLong(5, info.getLong("respawn_time"));
          double hp = boss.getCurrentHp();
          double mp = boss.getCurrentMp();
          if(boss.isDead())
          {
            hp = boss.getMaxHp();
            mp = boss.getMaxMp();
          }
          update1.setDouble(6, hp);
          update1.setDouble(7, mp);
          update1.setInt(8, _bossStatus.get(bossId));
          update1.setInt(9, bossId);
          update1.executeUpdate();
          update1.close();
        }
      }
    }
    catch(SQLException e)
    {
      if(Config.ENABLE_ALL_EXCEPTIONS)
        e.printStackTrace();
     
      _log.warning("GrandBossManager: Couldn't store grandbosses to database:" + e);
    }
    finally
    {
      CloseUtil.close(con);
    }
  }
 
  private void updateDb(int bossId, boolean statusOnly)
  {
    Connection con = null;
    PreparedStatement statement = null;
    try
    {
      con = L2DatabaseFactory.getInstance().getConnection();
      L2GrandBossInstance boss = _bosses.get(bossId);
      StatsSet info = _storedInfo.get(bossId);
     
      if (statusOnly || boss == null || info == null)
      {
        statement = con.prepareStatement(UPDATE_GRAND_BOSS_DATA2);
        statement.setInt(1, _bossStatus.get(bossId));
        statement.setInt(2, bossId);
      }
      else
      {
        statement = con.prepareStatement(UPDATE_GRAND_BOSS_DATA);
        statement.setInt(1, boss.getX());
        statement.setInt(2, boss.getY());
        statement.setInt(3, boss.getZ());
        statement.setInt(4, boss.getHeading());
        statement.setLong(5, info.getLong("respawn_time"));
        double hp = boss.getCurrentHp();
        double mp = boss.getCurrentMp();
        if (boss.isDead())
        {
          hp = boss.getMaxHp();
          mp = boss.getMaxMp();
        }
        statement.setDouble(6, hp);
        statement.setDouble(7, mp);
        statement.setInt(8, _bossStatus.get(bossId));
        statement.setInt(9, bossId);
      }
      statement.executeUpdate();
      statement.close();
    }
    catch (SQLException e)
    {
      _log.log(Level.WARNING, "GrandBossManager: Couldn't update grandbosses to database:" + e.getMessage(), e);
    }
    finally
    {
      L2DatabaseFactory.close(con);
    }
  }
 

  /**
   * Saves all Grand Boss info and then clears all info from memory, including all schedules.
   */
  public void cleanUp()
  {
    storeToDb();

    _bosses.clear();
    _storedInfo.clear();
    _bossStatus.clear();
    _zones.clear();
  }
 
  public L2NpcTemplate getValidTemplate(int bossId)
  {
    L2NpcTemplate template = NpcTable.getInstance().getTemplate(bossId);
    if(template == null)
      return null;

    if(!template.type.equalsIgnoreCase("L2GrandBoss"))
      return null;

    return template;
  }
 
  public boolean isDefined(int bossId) //into database
  {
    return _bossStatus.get(bossId)!=null;
  }
}
TOP

Related Classes of com.l2jfrozen.gameserver.managers.GrandBossManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.