diff --git a/config.yaml b/config.yaml index ff9c3a7a7c..bd71c9c6fe 100644 --- a/config.yaml +++ b/config.yaml @@ -242,6 +242,7 @@ server: USE_STARTING_AP_4: false #Use early-GMS 4/4/4/4 starting stats. To overcome AP shortage, this gives 4AP/5AP at 1st/2nd job advancements. USE_AUTOBAN: false #Commands the server to detect infractors automatically. USE_AUTOBAN_LOG: true #Log autoban related messages. Still logs even with USE_AUTOBAN disabled. + USE_EXP_GAIN_LOG: false #Logs characters exp gains; logs world rate & coupon exp, total gained exp, and current exp, level can be calculated from "ExpTable". USE_SERVER_AUTOASSIGNER: false #HeavenMS-builtin autoassigner, uses algorithm based on distributing AP accordingly with required secondary stat on equipments. USE_REFRESH_RANK_MOVE: true USE_ENFORCE_ADMIN_ACCOUNT: false #Forces accounts having GM characters to be treated as a "GM account" by the client (localhost). Some of the GM account perks is the ability to FLY, but unable to TRADE. diff --git a/database/sql/1-db_database.sql b/database/sql/1-db_database.sql index c24fc76912..639ca90b80 100644 --- a/database/sql/1-db_database.sql +++ b/database/sql/1-db_database.sql @@ -21484,6 +21484,17 @@ CREATE TABLE IF NOT EXISTS `worldtransfers` ( INDEX (characterid) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; +CREATE TABLE IF NOT EXISTS `characterexplogs` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `world_exp_rate` INT, + `exp_coupon` INT, + `gained_exp` BIGINT, + `current_exp` INT, + `exp_gain_time` DATETIME, + `charid` int(11) NOT NULL, + PRIMARY KEY (`id`), + FOREIGN KEY (`charid`) REFERENCES `characters`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; ALTER TABLE `dueyitems` ADD CONSTRAINT `dueyitems_ibfk_1` FOREIGN KEY (`PackageId`) REFERENCES `dueypackages` (`PackageId`) ON DELETE CASCADE; diff --git a/src/main/java/client/Character.java b/src/main/java/client/Character.java index b8369e2de4..f299e351e0 100644 --- a/src/main/java/client/Character.java +++ b/src/main/java/client/Character.java @@ -59,6 +59,7 @@ import scripting.AbstractPlayerInteraction; import scripting.event.EventInstanceManager; import scripting.item.ItemScriptManager; import server.*; +import server.ExpLogger.ExpLogRecord; import server.ItemInformationProvider.ScriptedItem; import server.events.Events; import server.events.RescueGaga; @@ -151,6 +152,7 @@ public class Character extends AbstractCharacterObject { private final AtomicInteger gachaexp = new AtomicInteger(); private final AtomicInteger meso = new AtomicInteger(); private final AtomicInteger chair = new AtomicInteger(-1); + private long totalExpGained = 0; private int merchantmeso; private BuddyList buddylist; private EventInstanceManager eventInstance = null; @@ -3094,6 +3096,7 @@ public class Character extends AbstractCharacterObject { leftover = nextExp - Integer.MAX_VALUE; } updateSingleStat(Stat.EXP, exp.addAndGet((int) total)); + totalExpGained += total; if (show) { announceExpGain(gain, equip, party, inChat, white); } @@ -3110,6 +3113,20 @@ public class Character extends AbstractCharacterObject { gainExpInternal(leftover, equip, party, false, inChat, white); } else { lastExpGainTime = System.currentTimeMillis(); + + if (YamlConfig.config.server.USE_EXP_GAIN_LOG) { + ExpLogRecord expLogRecord = new ExpLogger.ExpLogRecord( + getWorldServer().getExpRate(), + expCoupon, + totalExpGained, + exp.get(), + new Timestamp(lastExpGainTime), + id + ); + ExpLogger.putExpLogRecord(expLogRecord); + } + + totalExpGained = 0; } } } diff --git a/src/main/java/client/inventory/manipulator/KarmaManipulator.java b/src/main/java/client/inventory/manipulator/KarmaManipulator.java index 68cc77b5c5..660738ae25 100644 --- a/src/main/java/client/inventory/manipulator/KarmaManipulator.java +++ b/src/main/java/client/inventory/manipulator/KarmaManipulator.java @@ -43,7 +43,7 @@ public class KarmaManipulator { flag ^= karmaFlag; flag |= ItemConstants.UNTRADEABLE; - item.setFlag((byte) flag); + item.setFlag(flag); } } @@ -53,6 +53,6 @@ public class KarmaManipulator { flag |= karmaFlag; flag &= (0xFFFFFFFF ^ ItemConstants.UNTRADEABLE); - item.setFlag((byte) flag); + item.setFlag(flag); } } diff --git a/src/main/java/config/ServerConfig.java b/src/main/java/config/ServerConfig.java index 0a5d9a90f9..4dc650c4c6 100644 --- a/src/main/java/config/ServerConfig.java +++ b/src/main/java/config/ServerConfig.java @@ -91,6 +91,7 @@ public class ServerConfig { public boolean USE_STARTING_AP_4; public boolean USE_AUTOBAN; public boolean USE_AUTOBAN_LOG; + public boolean USE_EXP_GAIN_LOG; public boolean USE_SERVER_AUTOASSIGNER; public boolean USE_REFRESH_RANK_MOVE; public boolean USE_ENFORCE_ADMIN_ACCOUNT; diff --git a/src/main/java/net/server/Server.java b/src/main/java/net/server/Server.java index 92c31135f1..22fc2092f8 100644 --- a/src/main/java/net/server/Server.java +++ b/src/main/java/net/server/Server.java @@ -73,7 +73,7 @@ import server.SkillbookInformationProvider; import server.ThreadManager; import server.TimerManager; import server.expeditions.ExpeditionBossLog; -import server.life.PlayerNPCFactory; +import server.life.PlayerNPC; import server.quest.Quest; import server.shop.ShopFactory; import service.BanService; @@ -870,15 +870,15 @@ public class Server { final ExecutorService initExecutor = Executors.newFixedThreadPool(10); // Run slow operations asynchronously to make startup faster final List> futures = new ArrayList<>(); - futures.add(initExecutor.submit(() -> SkillFactory.loadAllSkills())); - futures.add(initExecutor.submit(() -> CashItemFactory.loadAllCashItems())); - futures.add(initExecutor.submit(() -> Quest.loadAllQuests())); - futures.add(initExecutor.submit(() -> SkillbookInformationProvider.loadAllSkillbookInformation())); - futures.add(initExecutor.submit(() -> PlayerNPCFactory.loadFactoryMetadata())); + futures.add(initExecutor.submit(SkillFactory::loadAllSkills)); + futures.add(initExecutor.submit(CashItemFactory::loadAllCashItems)); + futures.add(initExecutor.submit(Quest::loadAllQuests)); + futures.add(initExecutor.submit(SkillbookInformationProvider::loadAllSkillbookInformation)); initExecutor.shutdown(); TimeZone.setDefault(TimeZone.getTimeZone(YamlConfig.config.server.TIMEZONE)); + final int worldCount = Math.min(GameConstants.WORLD_NAMES.length, YamlConfig.config.server.WORLDS); try (Connection con = DatabaseConnection.getConnection()) { setAllLoggedOut(con); setAllMerchantsInactive(con); @@ -889,6 +889,7 @@ public class Server { CashIdGenerator.loadExistentCashIdsFromDb(con); applyAllNameChanges(con); // -- name changes can be missed by INSTANT_NAME_CHANGE -- applyAllWorldTransfers(con); + PlayerNPC.loadRunningRankData(con, worldCount); } catch (SQLException sqle) { log.error("Failed to run all startup-bound database tasks", sqle); throw new IllegalStateException(sqle); @@ -898,8 +899,6 @@ public class Server { initializeTimelyTasks(channelDependencies); // aggregated method for timely tasks thanks to lxconan try { - int worldCount = Math.min(GameConstants.WORLD_NAMES.length, YamlConfig.config.server.WORLDS); - for (int i = 0; i < worldCount; i++) { initWorld(); } diff --git a/src/main/java/net/server/channel/handlers/MTSHandler.java b/src/main/java/net/server/channel/handlers/MTSHandler.java index ca00cc842f..abffbe9ad1 100644 --- a/src/main/java/net/server/channel/handlers/MTSHandler.java +++ b/src/main/java/net/server/channel/handlers/MTSHandler.java @@ -45,6 +45,8 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Calendar; import java.util.List; @@ -122,40 +124,12 @@ public final class MTSHandler extends AbstractPacketHandler { return; } } - Calendar calendar = Calendar.getInstance(); - int year; - int month; - int day; - int oldmax = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); - int oldday = calendar.get(Calendar.DAY_OF_MONTH) + 7; - if (oldmax < oldday) { - if (calendar.get(Calendar.MONTH) + 2 > 12) { - year = calendar.get(Calendar.YEAR) + 1; - month = 1; - calendar.set(year, month, 1); - day = oldday - oldmax; - } else { - month = calendar.get(Calendar.MONTH) + 2; - year = calendar.get(Calendar.YEAR); - calendar.set(year, month, 1); - day = oldday - oldmax; - } - } else { - day = calendar.get(Calendar.DAY_OF_MONTH) + 7; - month = calendar.get(Calendar.MONTH); - year = calendar.get(Calendar.YEAR); - } - String date = year + "-"; - if (month < 10) { - date += "0" + month + "-"; - } else { - date += month + "-"; - } - if (day < 10) { - date += "0" + day; - } else { - date += day + ""; - } + + LocalDate now = LocalDate.now(); + LocalDate sellEnd = now.plusDays(7); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String date = sellEnd.format(formatter); + if (!i.getInventoryType().equals(InventoryType.EQUIP)) { Item item = i; try (PreparedStatement pse = con.prepareStatement("INSERT INTO mts_items (tab, type, itemid, quantity, expiration, giftFrom, seller, price, owner, sellername, sell_ends) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")) { @@ -761,7 +735,7 @@ public final class MTSHandler extends AbstractPacketHandler { } } } - try (PreparedStatement ps = con.prepareStatement("SELECT COUNT(*) FROM mts_items WHERE tab = ? " + (type != 0 ? "AND type = ?" : "") + "AND transfer = 0")) { + try (PreparedStatement ps = con.prepareStatement("SELECT COUNT(*) FROM mts_items WHERE tab = ? " + (type != 0 ? "AND type = ?" : "") + " AND transfer = 0")) { ps.setInt(1, tab); if (type != 0) { ps.setInt(2, type); diff --git a/src/main/java/scripting/AbstractPlayerInteraction.java b/src/main/java/scripting/AbstractPlayerInteraction.java index 46ba27f246..707d7f2c3f 100644 --- a/src/main/java/scripting/AbstractPlayerInteraction.java +++ b/src/main/java/scripting/AbstractPlayerInteraction.java @@ -298,7 +298,7 @@ public class AbstractPlayerInteraction { int size = Math.min(itemids.size(), quantity.size()); List>> invList = new ArrayList<>(6); - for (int i = InventoryType.UNDEFINED.getType(); i < InventoryType.CASH.getType(); i++) { + for (int i = InventoryType.UNDEFINED.getType(); i <= InventoryType.CASH.getType(); i++) { invList.add(new LinkedList<>()); } diff --git a/src/main/java/server/ExpLogger.java b/src/main/java/server/ExpLogger.java new file mode 100644 index 0000000000..c9016bdf69 --- /dev/null +++ b/src/main/java/server/ExpLogger.java @@ -0,0 +1,93 @@ +package server; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; +import java.sql.Timestamp; +import static java.util.concurrent.TimeUnit.*; + +import config.YamlConfig; +import tools.DatabaseConnection; + +public class ExpLogger { + private static final LinkedBlockingQueue expLoggerQueue = new LinkedBlockingQueue<>(); + private static final short EXP_LOGGER_THREAD_SLEEP_DURATION_SECONDS = 60; + private static final short EXP_LOGGER_THREAD_SHUTDOWN_WAIT_DURATION_MINUTES = 5; + + public record ExpLogRecord(int worldExpRate, int expCoupon, long gainedExp, int currentExp,Timestamp expGainTime, int charid) {} + + public static void putExpLogRecord(ExpLogRecord expLogRecord) { + try { + expLoggerQueue.put(expLogRecord); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + static private ScheduledExecutorService schdExctr = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(r); + t.setPriority(Thread.MIN_PRIORITY); + return t; + } + }); + + private static Runnable saveExpLoggerToDBRunnable = new Runnable() { + @Override + public void run() { + try (Connection con = DatabaseConnection.getConnection(); + PreparedStatement ps = con.prepareStatement("INSERT INTO characterexplogs (world_exp_rate, exp_coupon, gained_exp, current_exp, exp_gain_time, charid) VALUES (?, ?, ?, ?, ?, ?)")) { + + List drainedExpLogs = new ArrayList<>(); + expLoggerQueue.drainTo(drainedExpLogs); + for (ExpLogRecord expLogRecord : drainedExpLogs) { + ps.setInt(1, expLogRecord.worldExpRate); + ps.setInt(2, expLogRecord.expCoupon); + ps.setLong(3, expLogRecord.gainedExp); + ps.setInt(4, expLogRecord.currentExp); + ps.setTimestamp(5, expLogRecord.expGainTime); + ps.setInt(6, expLogRecord.charid); + ps.addBatch(); + } + ps.executeBatch(); + } catch (SQLException sqle) { + sqle.printStackTrace(); + } + } + }; + + + private static void startExpLogger() { + schdExctr.scheduleWithFixedDelay(saveExpLoggerToDBRunnable, EXP_LOGGER_THREAD_SLEEP_DURATION_SECONDS, EXP_LOGGER_THREAD_SLEEP_DURATION_SECONDS, SECONDS); + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + stopExpLogger(); + })); + } + + private static boolean stopExpLogger() { + schdExctr.shutdown(); + try { + schdExctr.awaitTermination(EXP_LOGGER_THREAD_SHUTDOWN_WAIT_DURATION_MINUTES, MINUTES); + Thread runThreadBeforeShutdown = new Thread(saveExpLoggerToDBRunnable); + runThreadBeforeShutdown.setPriority(Thread.MIN_PRIORITY); + runThreadBeforeShutdown.start(); + return true; + } catch (InterruptedException e) { + e.printStackTrace(); + return false; + } + } + + static { + if (YamlConfig.config.server.USE_EXP_GAIN_LOG) { + startExpLogger(); + } + } +} diff --git a/src/main/java/server/MTSItemInfo.java b/src/main/java/server/MTSItemInfo.java index 3779d69925..c091861167 100644 --- a/src/main/java/server/MTSItemInfo.java +++ b/src/main/java/server/MTSItemInfo.java @@ -23,6 +23,8 @@ package server; import client.inventory.Item; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; import java.util.Calendar; /** @@ -38,13 +40,16 @@ public class MTSItemInfo { private int day = 1; public MTSItemInfo(Item item, int price, int id, int cid, String seller, String date) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + LocalDate sellEnd = LocalDate.parse(date, formatter); + this.item = item; this.price = price; this.seller = seller; this.id = id; - this.year = Integer.parseInt(date.substring(0, 4)); - this.month = Integer.parseInt(date.substring(5, 7)); - this.day = Integer.parseInt(date.substring(8, 10)); + this.year = sellEnd.getYear(); + this.month = sellEnd.getMonthValue(); + this.day = sellEnd.getDayOfMonth(); } public Item getItem() { diff --git a/src/main/java/server/life/PlayerNPC.java b/src/main/java/server/life/PlayerNPC.java index c0487d0276..f5a592016d 100644 --- a/src/main/java/server/life/PlayerNPC.java +++ b/src/main/java/server/life/PlayerNPC.java @@ -53,6 +53,8 @@ import java.util.concurrent.atomic.AtomicInteger; * @author XoticStory * @author Ronan */ +// TODO: remove dependency on custom Npc.wz. All NPCs with id 9901910 and above are custom additions for player npcs. +// In summary: NPCs 9901910-9906599 and 9977777 are custom additions to HeavenMS that should be removed. public class PlayerNPC extends AbstractMapObject { private static final Logger log = LoggerFactory.getLogger(PlayerNPC.class); private static final Map> availablePlayerNpcScriptIds = new HashMap<>(); @@ -67,10 +69,6 @@ public class PlayerNPC extends AbstractMapObject { private int dir, FH, RX0, RX1, CY; private int worldRank, overallRank, worldJobRank, overallJobRank; - static { - getRunningMetadata(); - } - public PlayerNPC(String name, int scriptId, int face, int hair, int gender, byte skin, Map equips, int dir, int FH, int RX0, int RX1, int CX, int CY, int oid) { this.equips = equips; this.scriptId = scriptId; @@ -128,6 +126,12 @@ public class PlayerNPC extends AbstractMapObject { } } + public static void loadRunningRankData(Connection con, int worlds) throws SQLException { + getRunningOverallRanks(con); + getRunningWorldRanks(con, worlds); + getRunningWorldJobRanks(con); + } + public Map getEquips() { return equips; } @@ -213,16 +217,6 @@ public class PlayerNPC extends AbstractMapObject { client.sendPacket(PacketCreator.removePlayerNPC(this.getObjectId())); } - private static void getRunningMetadata() { - try (Connection con = DatabaseConnection.getConnection()) { - getRunningOverallRanks(con); - getRunningWorldRanks(con); - getRunningWorldJobRanks(con); - } catch (SQLException e) { - e.printStackTrace(); - } - } - private static void getRunningOverallRanks(Connection con) throws SQLException { try (PreparedStatement ps = con.prepareStatement("SELECT max(overallrank) FROM playernpcs"); ResultSet rs = ps.executeQuery()) { @@ -235,9 +229,8 @@ public class PlayerNPC extends AbstractMapObject { } } - private static void getRunningWorldRanks(Connection con) throws SQLException { - int numWorlds = Server.getInstance().getWorldsSize(); - for (int i = 0; i < numWorlds; i++) { + private static void getRunningWorldRanks(Connection con, int worlds) throws SQLException { + for (int i = 0; i < worlds; i++) { runningWorldRank.add(new AtomicInteger(1)); } @@ -246,7 +239,7 @@ public class PlayerNPC extends AbstractMapObject { while (rs.next()) { int wid = rs.getInt(1); - if (wid < numWorlds) { + if (wid < worlds) { runningWorldRank.get(wid).set(rs.getInt(2) + 1); } } @@ -649,4 +642,4 @@ public class PlayerNPC extends AbstractMapObject { e.printStackTrace(); } } -} \ No newline at end of file +} diff --git a/src/main/java/server/life/PlayerNPCFactory.java b/src/main/java/server/life/PlayerNPCFactory.java index a0a8de7f59..bacf994a1b 100644 --- a/src/main/java/server/life/PlayerNPCFactory.java +++ b/src/main/java/server/life/PlayerNPCFactory.java @@ -19,124 +19,17 @@ */ package server.life; -import constants.id.ItemId; -import constants.id.MapId; -import constants.id.NpcId; -import net.server.Server; -import provider.Data; import provider.DataProvider; import provider.DataProviderFactory; -import provider.DataTool; import provider.wz.WZFiles; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - /** * @author RonanLana */ public class PlayerNPCFactory { private static final DataProvider npcData = DataProviderFactory.getDataProvider(WZFiles.NPC); - private static final Map> dnpcMaps = new HashMap<>(); - private static Integer runningDeveloperOid = 2147483000; // 647 slots, long enough - public synchronized static boolean isExistentScriptid(int scriptid) { return npcData.getData(scriptid + ".img") != null; } - - private static void loadDeveloperRoomMetadata(DataProvider npc) { - Data thisData = npc.getData(NpcId.CUSTOM_DEV + ".img"); - if (thisData != null) { - DataProvider map = DataProviderFactory.getDataProvider(WZFiles.MAP); - - thisData = map.getData("Map/Map7/" + MapId.DEVELOPERS_HQ + ".img"); - if (thisData != null) { - DataProvider sound = DataProviderFactory.getDataProvider(WZFiles.SOUND); - - thisData = sound.getData("Field.img"); - if (thisData != null) { - Data md = thisData.getChildByPath("anthem/brazil"); - if (md != null) { - Server.getInstance().setAvailableDeveloperRoom(); - } - } - } - } - } - - public synchronized static void loadFactoryMetadata() { - DataProvider npc = npcData; - loadDeveloperRoomMetadata(npc); - - DataProvider etc = DataProviderFactory.getDataProvider(WZFiles.ETC); - Data dnpcData = etc.getData("DeveloperNpc.img"); - if (dnpcData != null) { - for (Data data : dnpcData.getChildren()) { - int scriptId = Integer.parseInt(data.getName()); - - String name = DataTool.getString("name", data, ""); - int face = DataTool.getIntConvert("face", data, 20000); - int hair = DataTool.getIntConvert("hair", data, 30000); - int gender = DataTool.getIntConvert("gender", data, 0); - byte skin = (byte) DataTool.getIntConvert("skin", data, 0); - int dir = DataTool.getIntConvert("dir", data, 0); - int mapid = DataTool.getIntConvert("map", data, 0); - int FH = DataTool.getIntConvert("fh", data, 0); - int RX0 = DataTool.getIntConvert("rx0", data, 0); - int RX1 = DataTool.getIntConvert("rx1", data, 0); - int CX = DataTool.getIntConvert("cx", data, 0); - int CY = DataTool.getIntConvert("cy", data, 0); - - Map equips = new HashMap<>(); - for (Data edata : data.getChildByPath("equips").getChildren()) { - short equippos = (short) DataTool.getIntConvert("pos", edata); - int equipid = DataTool.getIntConvert("itemid", edata); - - equips.put(equippos, equipid); - } - - List dnpcSet = dnpcMaps.get(mapid); - if (dnpcSet == null) { - dnpcSet = new LinkedList<>(); - dnpcMaps.put(mapid, dnpcSet); - } - - dnpcSet.add(new PlayerNPC(name, scriptId, face, hair, gender, skin, equips, dir, FH, RX0, RX1, CX, CY, runningDeveloperOid)); - runningDeveloperOid++; - } - } else { - Data thisData = npc.getData(NpcId.CUSTOM_DEV + ".img"); - - if (thisData != null) { - byte[] encData = {0x52, 0x6F, 0x6E, 0x61, 0x6E}; - String name = new String(encData); - int face = 20104, hair = 30215, gender = 0, skin = 0, dir = 0, mapid = MapId.DEVELOPERS_HQ; - int FH = 4, RX0 = -143, RX1 = -243, CX = -193, CY = 117, scriptId = NpcId.CUSTOM_DEV; - - Map equips = new HashMap<>(); - equips.put((short) -1, ItemId.GREEN_HEADBAND); - equips.put((short) -11, ItemId.TIMELESS_NIBLEHEIM); - equips.put((short) -8, ItemId.BLUE_KORBEN); - equips.put((short) -6, ItemId.MITHRIL_PLATINE_PANTS); - equips.put((short) -7, ItemId.BLUE_CARZEN_BOOTS); - equips.put((short) -5, ItemId.MITHRIL_PLATINE); - - List dnpcSet = dnpcMaps.get(mapid); - if (dnpcSet == null) { - dnpcSet = new LinkedList<>(); - dnpcMaps.put(mapid, dnpcSet); - } - - dnpcSet.add(new PlayerNPC(name, scriptId, face, hair, gender, (byte) skin, equips, dir, FH, RX0, RX1, CX, CY, runningDeveloperOid)); - runningDeveloperOid++; - } - } - } - - public synchronized static List getDeveloperNpcsFromMapid(int mapid) { - return dnpcMaps.get(mapid); - } } diff --git a/src/main/java/server/maps/MapFactory.java b/src/main/java/server/maps/MapFactory.java index 9d3f808fdd..7a8ecedcca 100644 --- a/src/main/java/server/maps/MapFactory.java +++ b/src/main/java/server/maps/MapFactory.java @@ -29,7 +29,10 @@ import provider.DataProviderFactory; import provider.DataTool; import provider.wz.WZFiles; import scripting.event.EventInstanceManager; -import server.life.*; +import server.life.AbstractLoadedLife; +import server.life.LifeFactory; +import server.life.Monster; +import server.life.PlayerNPC; import server.partyquest.GuardianSpawnPoint; import tools.DatabaseConnection; import tools.StringUtil; @@ -251,13 +254,6 @@ public class MapFactory { } catch (SQLException e) { e.printStackTrace(); } - - List dnpcs = PlayerNPCFactory.getDeveloperNpcsFromMapid(mapid); - if (dnpcs != null) { - for (PlayerNPC dnpc : dnpcs) { - map.addPlayerNPCMapObject(dnpc); - } - } } loadLifeFromWz(map, mapData);