From a49c1703ae1f43b72a3093ffee8a769402d80e5d Mon Sep 17 00:00:00 2001 From: P0nk Date: Mon, 18 Sep 2023 23:26:37 +0200 Subject: [PATCH 1/2] Remove developer player npc --- .../java/server/life/PlayerNPCFactory.java | 107 ------------------ src/main/java/server/maps/MapFactory.java | 12 +- 2 files changed, 4 insertions(+), 115 deletions(-) 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 1c7a85cd0c..a1c3f14c21 100644 --- a/src/main/java/server/maps/MapFactory.java +++ b/src/main/java/server/maps/MapFactory.java @@ -28,7 +28,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; @@ -249,13 +252,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); From 0aee9d7c3f360bb48a6d399462b4f1ed3ca1ffb4 Mon Sep 17 00:00:00 2001 From: P0nk Date: Mon, 18 Sep 2023 23:45:56 +0200 Subject: [PATCH 2/2] Fix unable to create playernpc The initialization of the running world counters depended on worlds already having been initialized, so I made that dependency more explicit. --- src/main/java/net/server/Server.java | 15 ++++++------ src/main/java/server/life/PlayerNPC.java | 31 +++++++++--------------- 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/src/main/java/net/server/Server.java b/src/main/java/net/server/Server.java index 5b854bebcd..679d136643 100644 --- a/src/main/java/net/server/Server.java +++ b/src/main/java/net/server/Server.java @@ -57,7 +57,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 service.NoteService; import tools.DatabaseConnection; @@ -849,15 +849,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); @@ -868,6 +868,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); @@ -877,8 +878,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/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 +}