Показать сообщение отдельно
Непрочитано 31.08.2010, 22:23   #1
Пользователь

Автор темы (Топик Стартер) MySQL raidboss_spawnlist respawn_time

Проблема состоит в том, что когда РБ жив в базе l2jdb raidboss_spawnlist в колонке respawn_time стоит значение 0, когда РБ убивают, значение меняется на время респауна РБ у меня такое 1283179635482. Но вот когда РБ возрождается, значение respawn_time не обнуляется, а остается тем же самым, помогите пожалуйста разобраться. Сборка L2JServer.

Я так думаю, проблема в ядре, вот только не знаю что именно изменить.

Код:
package com.l2jserver.gameserver.instancemanager;

/**
@author godson
**/

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
import java.util.logging.Logger;

import com.l2jserver.Config;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.GmListTable;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.datatables.NpcTable;
import com.l2jserver.gameserver.datatables.SpawnTable;
import com.l2jserver.gameserver.model.L2Spawn;
import com.l2jserver.gameserver.model.actor.instance.L2RaidBossInstance;
import com.l2jserver.gameserver.templates.StatsSet;
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
import com.l2jserver.util.Rnd;

import javolution.util.FastMap;

public class RaidBossSpawnManager
{
        private static Logger _log = Logger.getLogger(RaidBossSpawnManager.class.getName());

        protected static Map<Integer, L2RaidBossInstance> _bosses;
        protected static Map<Integer, L2Spawn> _spawns;
        protected static Map<Integer, StatsSet> _storedInfo;
        protected static Map<Integer, ScheduledFuture<?>> _schedules;

        public static enum StatusEnum
        {
                ALIVE,
                DEAD,
                UNDEFINED
        }

        private RaidBossSpawnManager()
        {
                init();
        }

        public static RaidBossSpawnManager getInstance()
        {
                return SingletonHolder._instance;
        }

        private void init()
        {
                _bosses = new FastMap<Integer, L2RaidBossInstance>();
                _schedules = new FastMap<Integer, ScheduledFuture<?>>();
                _storedInfo = new FastMap<Integer, StatsSet>();
                _spawns = new FastMap<Integer, L2Spawn>();

                Connection con = null;
                PreparedStatement statement = null;

                try
                {
                        con = L2DatabaseFactory.getInstance().getConnection();

                        statement = con.prepareStatement("SELECT * FROM raidboss_spawnlist ORDER BY boss_id");
                        ResultSet rset = statement.executeQuery();

                        L2Spawn spawnDat;
                        L2NpcTemplate template;
                        long respawnTime;
                        while (rset.next())
                        {
                                template = getValidTemplate(rset.getInt("boss_id"));
                                if (template != null)
                                {
                                        spawnDat = new L2Spawn(template);
                                        spawnDat.setLocx(rset.getInt("loc_x"));
                                        spawnDat.setLocy(rset.getInt("loc_y"));
                                        spawnDat.setLocz(rset.getInt("loc_z"));
                                        spawnDat.setAmount(rset.getInt("amount"));
                                        spawnDat.setHeading(rset.getInt("heading"));
                                        spawnDat.setRespawnMinDelay(rset.getInt("respawn_min_delay"));
                                        spawnDat.setRespawnMaxDelay(rset.getInt("respawn_max_delay"));
                                        respawnTime = rset.getLong("respawn_time");

                                        addNewSpawn(spawnDat, respawnTime, rset.getDouble("currentHP"), rset.getDouble("currentMP"), false);
                                }
                                else
                                {
                                        _log.warning("RaidBossSpawnManager: Could not load raidboss #" + rset.getInt("boss_id") + " from DB");
                                }
                        }

                        _log.info("RaidBossSpawnManager: Loaded " + _bosses.size() + " Instances");
                        _log.info("RaidBossSpawnManager: Scheduled " + _schedules.size() + " Instances");

                        rset.close();
                }
                catch (SQLException e)
                {
                        _log.warning("RaidBossSpawnManager: Couldnt load raidboss_spawnlist table");
                }
                catch (Exception e)
                {
                        e.printStackTrace();
                }
                finally
                {
                        try
                        {
                                statement.close();
                        }
                        catch (Exception e)
                        {
                        }
                        try
                        {
                                con.close();
                        }
                        catch (Exception e)
                        {
                        }
                }
        }

        private class spawnSchedule implements Runnable
        {
                private final int bossId;

                public spawnSchedule(int npcId)
                {
                        bossId = npcId;
                }

                public void run()
                {
                        L2RaidBossInstance raidboss = null;

                        if (bossId == 25328)
                                raidboss = DayNightSpawnManager.getInstance().handleBoss(_spawns.get(bossId));
                        else
                                raidboss = (L2RaidBossInstance) _spawns.get(bossId).doSpawn();

                        if (raidboss != null)
                        {
                                raidboss.setRaidStatus(StatusEnum.ALIVE);

                                StatsSet info = new StatsSet();
                                info.set("currentHP", raidboss.getCurrentHp());
                                info.set("currentMP", raidboss.getCurrentMp());
                                info.set("respawnTime", 0L);

                                _storedInfo.put(bossId, info);

                                GmListTable.broadcastMessageToGMs("Spawning Raid Boss " + raidboss.getName());

                                _bosses.put(bossId, raidboss);
                        }

                        _schedules.remove(bossId);
                }
        }

        public void updateStatus(L2RaidBossInstance boss, boolean isBossDead)
        {
                if (!_storedInfo.containsKey(boss.getNpcId()))
                        return;

                StatsSet info = _storedInfo.get(boss.getNpcId());

                if (isBossDead)
                {
                        boss.setRaidStatus(StatusEnum.DEAD);

                        long respawnTime;
                        int RespawnMinDelay = boss.getSpawn().getRespawnMinDelay();
                        int RespawnMaxDelay = boss.getSpawn().getRespawnMaxDelay();
                        long respawn_delay = Rnd.get((int) (RespawnMinDelay * 1000 * Config.RAID_MIN_RESPAWN_MULTIPLIER), (int) (RespawnMaxDelay * 1000 * Config.RAID_MAX_RESPAWN_MULTIPLIER));
                        respawnTime = Calendar.getInstance().getTimeInMillis() + respawn_delay;

                        info.set("currentHP", boss.getMaxHp());
                        info.set("currentMP", boss.getMaxMp());
                        info.set("respawnTime", respawnTime);

                        Calendar time = Calendar.getInstance();
                        time.setTimeInMillis(respawnTime);
                        _log.info("RaidBossSpawnManager: Updated " + boss.getName() + " respawn time to " + time.getTime());

                        if (!_schedules.containsKey(boss.getNpcId()))
                        {
                                ScheduledFuture<?> futureSpawn;
                                futureSpawn = ThreadPoolManager.getInstance().scheduleGeneral(new spawnSchedule(boss.getNpcId()), respawn_delay);

                                _schedules.put(boss.getNpcId(), futureSpawn);
                                //To update immediately Database uncomment on the following line, to post the hour of respawn raid boss on your site for example or to envisage a crash landing of the waiter.
                                updateDb();
                        }
                }
                else
                {
                        boss.setRaidStatus(StatusEnum.ALIVE);

                        info.set("currentHP", boss.getCurrentHp());
                        info.set("currentMP", boss.getCurrentMp());
                        info.set("respawnTime", 0L);
                }

                _storedInfo.remove(boss.getNpcId());
                _storedInfo.put(boss.getNpcId(), info);
        }

        public void addNewSpawn(L2Spawn spawnDat, long respawnTime, double currentHP, double currentMP, boolean storeInDb)
        {
                if (spawnDat == null)
                        return;
                if (_spawns.containsKey(spawnDat.getNpcid()))
                        return;

                int bossId = spawnDat.getNpcid();
                long time = Calendar.getInstance().getTimeInMillis();

                SpawnTable.getInstance().addNewSpawn(spawnDat, false);

                if (respawnTime == 0L || (time > respawnTime))
                {
                        L2RaidBossInstance raidboss = null;

                        if (bossId == 25328)
                                raidboss = DayNightSpawnManager.getInstance().handleBoss(spawnDat);
                        else
                                raidboss = (L2RaidBossInstance) spawnDat.doSpawn();

                        if (raidboss != null)
                        {
                                raidboss.setCurrentHp(currentHP);
                                raidboss.setCurrentMp(currentMP);
                                raidboss.setRaidStatus(StatusEnum.ALIVE);

                                _bosses.put(bossId, raidboss);

                                StatsSet info = new StatsSet();
                                info.set("currentHP", currentHP);
                                info.set("currentMP", currentMP);
                                info.set("respawnTime", 0L);

                                _storedInfo.put(bossId, info);
                        }
                }
                else
                {
                        ScheduledFuture<?> futureSpawn;
                        long spawnTime = respawnTime - Calendar.getInstance().getTimeInMillis();

                        futureSpawn = ThreadPoolManager.getInstance().scheduleGeneral(new spawnSchedule(bossId), spawnTime);

                        _schedules.put(bossId, futureSpawn);
                }

                _spawns.put(bossId, spawnDat);

                if (storeInDb)
                {
                        Connection con = null;
                        PreparedStatement statement = null;

                        try
                        {
                                con = L2DatabaseFactory.getInstance().getConnection();
                                statement = con.prepareStatement("INSERT INTO raidboss_spawnlist (boss_id,amount,loc_x,loc_y,loc_z,heading,respawn_time,currentHp,currentMp) VALUES(?,?,?,?,?,?,?,?,?)");
                                statement.setInt(1, spawnDat.getNpcid());
                                statement.setInt(2, spawnDat.getAmount());
                                statement.setInt(3, spawnDat.getLocx());
                                statement.setInt(4, spawnDat.getLocy());
                                statement.setInt(5, spawnDat.getLocz());
                                statement.setInt(6, spawnDat.getHeading());
                                statement.setLong(7, respawnTime);
                                statement.setDouble(8, currentHP);
                                statement.setDouble(9, currentMP);
                                statement.execute();
                        }
                        catch (Exception e)
                        {
                                // problem with storing spawn
                                _log.warning("RaidBossSpawnManager: Could not store raidboss #" + bossId + " in the DB:" + e);
                        }
                        finally
                        {
                                try
                                {
                                        statement.close();
                                }
                                catch (Exception e)
                                {
                                }
                                try
                                {
                                        con.close();
                                }
                                catch (Exception e)
                                {
                                }
                        }
                }
        }

        public void deleteSpawn(L2Spawn spawnDat, boolean updateDb)
        {
                if (spawnDat == null)
                        return;
                if (!_spawns.containsKey(spawnDat.getNpcid()))
                        return;

                int bossId = spawnDat.getNpcid();

                SpawnTable.getInstance().deleteSpawn(spawnDat, false);
                _spawns.remove(bossId);

                if (_bosses.containsKey(bossId))
                        _bosses.remove(bossId);

                if (_schedules.containsKey(bossId))
                {
                        ScheduledFuture<?> f = _schedules.get(bossId);
                        f.cancel(true);
                        _schedules.remove(bossId);
                }

                if (_storedInfo.containsKey(bossId))
                        _storedInfo.remove(bossId);

                if (updateDb)
                {
                        Connection con = null;
                        PreparedStatement statement = null;

                        try
                        {
                                con = L2DatabaseFactory.getInstance().getConnection();
                                statement = con.prepareStatement("DELETE FROM raidboss_spawnlist WHERE boss_id=?");
                                statement.setInt(1, bossId);
                                statement.execute();
                        }
                        catch (Exception e)
                        {
                                // problem with deleting spawn
                                _log.warning("RaidBossSpawnManager: Could not remove raidboss #" + bossId + " from DB: " + e);
                        }
                        finally
                        {
                                try
                                {
                                        statement.close();
                                }
                                catch (Exception e)
                                {
                                }
                                try
                                {
                                        con.close();
                                }
                                catch (Exception e)
                                {
                                }
                        }
                }
        }

        private void updateDb()
        {
                for (Integer bossId : _storedInfo.keySet())
                {
                        Connection con = null;
                        PreparedStatement statement = null;

                        try
                        {
                                con = L2DatabaseFactory.getInstance().getConnection();

                                L2RaidBossInstance boss = _bosses.get(bossId);

                                if (boss == null)
                                        continue;

                                if (boss.getRaidStatus().equals(StatusEnum.ALIVE))
                                        updateStatus(boss, false);

                                StatsSet info = _storedInfo.get(bossId);

                                if (info == null)
                                        continue;

                                statement = con.prepareStatement("UPDATE raidboss_spawnlist SET respawn_time = ?, currentHP = ?, currentMP = ? WHERE boss_id = ?");
                                statement.setLong(1, info.getLong("respawnTime"));
                                statement.setDouble(2, info.getDouble("currentHP"));
                                statement.setDouble(3, info.getDouble("currentMP"));
                                statement.setInt(4, bossId);
                                statement.execute();
                        }
                        catch (SQLException e)
                        {
                                _log.warning("RaidBossSpawnManager: Couldnt update raidboss_spawnlist table " + e);
                        }
                        finally
                        {
                                try
                                {
                                        statement.close();
                                }
                                catch (Exception e)
                                {
                                }
                                try
                                {
                                        con.close();
                                }
                                catch (Exception e)
                                {
                                }
                        }
                }
        }

        public String[] getAllRaidBossStatus()
        {
                String[] msg = new String[_bosses == null ? 0 : _bosses.size()];

                if (_bosses == null)
                {
                        msg[0] = "None";
                        return msg;
                }

                int index = 0;

                for (int i : _bosses.keySet())
                {
                        L2RaidBossInstance boss = _bosses.get(i);

                        msg[index++] = boss.getName() + ": " + boss.getRaidStatus().name();
                }

                return msg;
        }

        public String getRaidBossStatus(int bossId)
        {
                String msg = "RaidBoss Status....\n";

                if (_bosses == null)
                {
                        msg += "None";
                        return msg;
                }

                if (_bosses.containsKey(bossId))
                {
                        L2RaidBossInstance boss = _bosses.get(bossId);

                        msg += boss.getName() + ": " + boss.getRaidStatus().name();
                }

                return msg;
        }

        public StatusEnum getRaidBossStatusId(int bossId)
        {
                if (_bosses.containsKey(bossId))
                        return _bosses.get(bossId).getRaidStatus();
                else if (_schedules.containsKey(bossId))
                        return StatusEnum.DEAD;
                else
                        return StatusEnum.UNDEFINED;
        }

        public L2NpcTemplate getValidTemplate(int bossId)
        {
                L2NpcTemplate template = NpcTable.getInstance().getTemplate(bossId);
                if (template == null)
                        return null;
                if (!template.type.equalsIgnoreCase("L2RaidBoss"))
                        return null;
                return template;
        }

        public void notifySpawnNightBoss(L2RaidBossInstance raidboss)
        {
                StatsSet info = new StatsSet();
                info.set("currentHP", raidboss.getCurrentHp());
                info.set("currentMP", raidboss.getCurrentMp());
                info.set("respawnTime", 0L);

                raidboss.setRaidStatus(StatusEnum.ALIVE);

                _storedInfo.put(raidboss.getNpcId(), info);

                GmListTable.broadcastMessageToGMs("Spawning Raid Boss " + raidboss.getName());

                _bosses.put(raidboss.getNpcId(), raidboss);
        }

        public boolean isDefined(int bossId)
        {
                return _spawns.containsKey(bossId);
        }

        public Map<Integer, L2RaidBossInstance> getBosses()
        {
                return _bosses;
        }

        public Map<Integer, L2Spawn> getSpawns()
        {
                return _spawns;
        }

        public void reloadBosses()
        {
                init();
        }

        /**
         * Saves all raidboss status and then clears all info from memory,
         * including all schedules.
         */
        public void cleanUp()
        {
                updateDb();

                _bosses.clear();

                if (_schedules != null)
                {
                        for (Integer bossId : _schedules.keySet())
                        {
                                ScheduledFuture<?> f = _schedules.get(bossId);
                                f.cancel(true);
                        }
                }

                _schedules.clear();
                _storedInfo.clear();
                _spawns.clear();
        }

        @SuppressWarnings("synthetic-access")
        private static class SingletonHolder
        {
                protected static final RaidBossSpawnManager _instance = new RaidBossSpawnManager();
        }
}

Последний раз редактировалось Perfecto; 09.09.2010 в 11:18. Причина: Для кода нужно использовать тег [CODE], а не [QUOTE]
Randomazer вне форума Ответить с цитированием