Merge pull request #193 from P0nk/fix-192/playernpc #patch

Fix #192 - Unable to create PlayerNPC
This commit is contained in:
Ponk
2023-09-19 17:15:00 +02:00
committed by GitHub
4 changed files with 23 additions and 142 deletions

View File

@@ -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<Future<?>> 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();
}

View File

@@ -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<Byte, List<Integer>> 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<Short, Integer> 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<Short, Integer> 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();
}
}
}
}

View File

@@ -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<Integer, List<PlayerNPC>> 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<Short, Integer> 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<PlayerNPC> 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<Short, Integer> 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<PlayerNPC> 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<PlayerNPC> getDeveloperNpcsFromMapid(int mapid) {
return dnpcMaps.get(mapid);
}
}

View File

@@ -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<PlayerNPC> dnpcs = PlayerNPCFactory.getDeveloperNpcsFromMapid(mapid);
if (dnpcs != null) {
for (PlayerNPC dnpc : dnpcs) {
map.addPlayerNPCMapObject(dnpc);
}
}
}
loadLifeFromWz(map, mapData);