From cc88d382e69fd3ac3fd3dbae126397c6be0f86d4 Mon Sep 17 00:00:00 2001 From: P0nk Date: Thu, 16 Mar 2023 08:31:38 +0100 Subject: [PATCH] Monster drops are retrieved from DropProvider (postgres db) This commit emphasizes the need for events to be reworked. This is the chain of constructors the DropProvider has to pass through to reach MapleMap: Channel -> EventScriptManager -> EventManager -> EventInstanceManager -> MapManager -> MapleMap --- src/main/java/net/server/Server.java | 4 +-- src/main/java/net/server/channel/Channel.java | 15 ++++++---- .../scripting/event/EventInstanceManager.java | 5 ++-- .../java/scripting/event/EventManager.java | 14 ++++++---- .../scripting/event/EventScriptManager.java | 7 +++-- src/main/java/server/Marriage.java | 5 ++-- src/main/java/server/life/Monster.java | 7 +++-- .../life/MonsterInformationProvider.java | 28 ------------------- src/main/java/server/loot/LootManager.java | 6 ++-- src/main/java/server/maps/MapFactory.java | 6 ++-- src/main/java/server/maps/MapManager.java | 13 +++++---- src/main/java/server/maps/MapleMap.java | 8 ++++-- 12 files changed, 55 insertions(+), 63 deletions(-) diff --git a/src/main/java/net/server/Server.java b/src/main/java/net/server/Server.java index 17a70b985d..2feed8f403 100644 --- a/src/main/java/net/server/Server.java +++ b/src/main/java/net/server/Server.java @@ -361,7 +361,7 @@ public class Server { wldRLock.unlock(); } - Channel channel = new Channel(worldid, channelid, getCurrentTime()); + Channel channel = new Channel(worldid, channelid, getCurrentTime(), channelDependencies.dropProvider()); channel.setServerMessage(YamlConfig.config.worlds.get(worldid).why_am_i_recommended); if (world.addChannel(channel)) { @@ -434,7 +434,7 @@ public class Server { long bootTime = getCurrentTime(); for (int j = 1; j <= YamlConfig.config.worlds.get(i).channels; j++) { int channelid = j; - Channel channel = new Channel(i, channelid, bootTime); + Channel channel = new Channel(i, channelid, bootTime, channelDependencies.dropProvider()); world.addChannel(channel); channelInfo.put(channelid, channel.getIP()); diff --git a/src/main/java/net/server/channel/Channel.java b/src/main/java/net/server/channel/Channel.java index 98c3151953..2cb757f1d8 100644 --- a/src/main/java/net/server/channel/Channel.java +++ b/src/main/java/net/server/channel/Channel.java @@ -24,6 +24,7 @@ package net.server.channel; import client.Character; import config.YamlConfig; import constants.id.MapId; +import database.drop.DropProvider; import net.netty.ChannelServer; import net.packet.Packet; import net.server.PlayerStorage; @@ -73,6 +74,7 @@ public final class Channel { private MapManager mapManager; private EventScriptManager eventSM; private ServicesManager services; + private final DropProvider dropProvider; private final Map hiredMerchants = new HashMap<>(); private final Map storedVars = new HashMap<>(); private final Set playersAway = new HashSet<>(); @@ -107,12 +109,13 @@ public final class Channel { private final Lock merchRlock; private final Lock merchWlock; - public Channel(final int world, final int channel, long startTime) { + public Channel(final int world, final int channel, long startTime, DropProvider dropProvider) { this.world = world; this.channel = channel; + this.dropProvider = dropProvider; this.ongoingStartTime = startTime + 10000; // rude approach to a world's last channel boot time, placeholder for the 1st wedding reservation ever - this.mapManager = new MapManager(null, world, channel); + this.mapManager = new MapManager(null, world, channel, dropProvider); this.port = BASE_PORT + (this.channel - 1) + (world * 100); this.ip = YamlConfig.config.server.HOST + ":" + port; @@ -125,11 +128,11 @@ public final class Channel { expedType.addAll(Arrays.asList(ExpeditionType.values())); if (Server.getInstance().isOnline()) { // postpone event loading to improve boot time... thanks Riizade, daronhudson for noticing slow startup times - eventSM = new EventScriptManager(this, getEvents()); + eventSM = new EventScriptManager(this, getEvents(), dropProvider); eventSM.init(); } else { String[] ev = {"0_EXAMPLE"}; - eventSM = new EventScriptManager(this, ev); + eventSM = new EventScriptManager(this, ev, dropProvider); } dojoStage = new int[20]; @@ -162,7 +165,7 @@ public final class Channel { eventSM.cancel(); eventSM = null; - eventSM = new EventScriptManager(this, getEvents()); + eventSM = new EventScriptManager(this, getEvents(), dropProvider); } public synchronized void shutdown() { @@ -1035,4 +1038,4 @@ public final class Channel { log.debug("Guest list: {}", ongoingChapelGuests); log.debug("Starttime: {}", ongoingStartTime); } -} \ No newline at end of file +} diff --git a/src/main/java/scripting/event/EventInstanceManager.java b/src/main/java/scripting/event/EventInstanceManager.java index 9ee193cf7a..717c27f6b3 100644 --- a/src/main/java/scripting/event/EventInstanceManager.java +++ b/src/main/java/scripting/event/EventInstanceManager.java @@ -26,6 +26,7 @@ import client.Skill; import client.SkillFactory; import config.YamlConfig; import constants.inventory.ItemConstants; +import database.drop.DropProvider; import net.server.coordinator.world.EventRecallCoordinator; import net.server.world.Party; import net.server.world.PartyCharacter; @@ -110,11 +111,11 @@ public class EventInstanceManager { // forces deletion of items not supposed to be held outside of the event, dealt on a player's leaving moment. private final Set exclusiveItems = new HashSet<>(); - public EventInstanceManager(EventManager em, String name) { + public EventInstanceManager(EventManager em, String name, DropProvider dropProvider) { this.em = em; this.name = name; this.ess = new EventScriptScheduler(); - this.mapManager = new MapManager(this, em.getWorldServer().getId(), em.getChannelServer().getId()); + this.mapManager = new MapManager(this, em.getWorldServer().getId(), em.getChannelServer().getId(), dropProvider); ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true); this.readLock = readWriteLock.readLock(); diff --git a/src/main/java/scripting/event/EventManager.java b/src/main/java/scripting/event/EventManager.java index 8567b93330..00c925fd3f 100644 --- a/src/main/java/scripting/event/EventManager.java +++ b/src/main/java/scripting/event/EventManager.java @@ -24,6 +24,7 @@ package scripting.event; import client.Character; import config.YamlConfig; import constants.game.GameConstants; +import database.drop.DropProvider; import net.server.Server; import net.server.channel.Channel; import net.server.guild.Guild; @@ -51,7 +52,6 @@ import java.util.concurrent.locks.ReentrantLock; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.SECONDS; -//import jdk.nashorn.api.scripting.ScriptUtils; /** * @author Matze @@ -63,6 +63,7 @@ public class EventManager { private Channel cserv; private World wserv; private Server server; + private final DropProvider dropProvider; private final EventScriptScheduler ess = new EventScriptScheduler(); private final Map instances = new HashMap<>(); private final Map instanceLocks = new HashMap<>(); @@ -82,12 +83,13 @@ public class EventManager { private static final int maxLobbys = 8; // an event manager holds up to this amount of concurrent lobbys - public EventManager(Channel cserv, Invocable iv, String name) { + public EventManager(Channel cserv, Invocable iv, String name, DropProvider dropProvider) { this.server = Server.getInstance(); this.iv = iv; this.cserv = cserv; this.wserv = server.getWorld(cserv.getWorld()); this.name = name; + this.dropProvider = dropProvider; this.openedLobbys = new ArrayList<>(); for (int i = 0; i < maxLobbys; i++) { @@ -219,7 +221,7 @@ public class EventManager { EventInstanceManager ret = getReadyInstance(); if (ret == null) { - ret = new EventInstanceManager(this, name); + ret = new EventInstanceManager(this, name, dropProvider); } else { ret.setName(name); } @@ -235,7 +237,7 @@ public class EventManager { } public Marriage newMarriage(String name) throws EventInstanceInProgressException { - Marriage ret = new Marriage(this, name); + Marriage ret = new Marriage(this, name, dropProvider); synchronized (instances) { if (instances.containsKey(name)) { @@ -922,7 +924,7 @@ public class EventManager { queueLock.unlock(); } - EventInstanceManager eim = new EventInstanceManager(this, "sampleName" + nextEventId); + EventInstanceManager eim = new EventInstanceManager(this, "sampleName" + nextEventId, dropProvider); queueLock.lock(); try { if (this.isDisposed()) { // EM already disposed @@ -945,4 +947,4 @@ public class EventManager { instantiateQueuedInstance(); } } -} \ No newline at end of file +} diff --git a/src/main/java/scripting/event/EventScriptManager.java b/src/main/java/scripting/event/EventScriptManager.java index 2723aa23cb..65dd1ba65a 100644 --- a/src/main/java/scripting/event/EventScriptManager.java +++ b/src/main/java/scripting/event/EventScriptManager.java @@ -21,6 +21,7 @@ */ package scripting.event; +import database.drop.DropProvider; import net.server.channel.Channel; import org.slf4j.LoggerFactory; import scripting.AbstractScriptManager; @@ -42,6 +43,7 @@ public class EventScriptManager extends AbstractScriptManager { private static final String INJECTED_VARIABLE_NAME = "em"; private static EventEntry fallback; private final Map events = new ConcurrentHashMap<>(); + private final DropProvider dropProvider; private boolean active = false; private static class EventEntry { @@ -55,7 +57,8 @@ public class EventScriptManager extends AbstractScriptManager { public EventManager em; } - public EventScriptManager(final Channel channel, String[] scripts) { + public EventScriptManager(final Channel channel, String[] scripts, DropProvider dropProvider) { + this.dropProvider = dropProvider; for (String script : scripts) { if (!script.isEmpty()) { events.put(script, initializeEventEntry(script, channel)); @@ -106,7 +109,7 @@ public class EventScriptManager extends AbstractScriptManager { private EventEntry initializeEventEntry(String script, Channel channel) { ScriptEngine engine = getInvocableScriptEngine("event/" + script + ".js"); Invocable iv = SynchronizedInvocable.of((Invocable) engine); - EventManager eventManager = new EventManager(channel, iv, script); + EventManager eventManager = new EventManager(channel, iv, script, dropProvider); engine.put(INJECTED_VARIABLE_NAME, eventManager); return new EventEntry(iv, eventManager); } diff --git a/src/main/java/server/Marriage.java b/src/main/java/server/Marriage.java index e44a7a85f2..04bfe5e2a4 100644 --- a/src/main/java/server/Marriage.java +++ b/src/main/java/server/Marriage.java @@ -26,6 +26,7 @@ import client.inventory.InventoryType; import client.inventory.Item; import client.inventory.ItemFactory; import client.inventory.manipulator.InventoryManipulator; +import database.drop.DropProvider; import scripting.event.EventInstanceManager; import scripting.event.EventManager; import tools.DatabaseConnection; @@ -42,8 +43,8 @@ import java.util.List; * @author Ronan */ public class Marriage extends EventInstanceManager { - public Marriage(EventManager em, String name) { - super(em, name); + public Marriage(EventManager em, String name, DropProvider dropProvider) { + super(em, name, dropProvider); } public boolean giftItemToSpouse(int cid) { diff --git a/src/main/java/server/life/Monster.java b/src/main/java/server/life/Monster.java index 52f01017c8..f6ff920f5a 100644 --- a/src/main/java/server/life/Monster.java +++ b/src/main/java/server/life/Monster.java @@ -28,6 +28,7 @@ import client.status.MonsterStatusEffect; import config.YamlConfig; import constants.id.MobId; import constants.skills.*; +import database.drop.DropProvider; import net.packet.Packet; import net.server.channel.Channel; import net.server.coordinator.world.MonsterAggroCoordinator; @@ -738,9 +739,9 @@ public class Monster extends AbstractLoadedLife { } } - public List retrieveRelevantDrops() { + public List retrieveRelevantDrops(DropProvider dropProvider) { if (this.getStats().isFriendly()) { // thanks Conrad for noticing friendly mobs not spawning loots after a recent update - return MonsterInformationProvider.getInstance().retrieveEffectiveDrop(this.getId()); + return dropProvider.getMonsterDropEntries(this.getId()); } Map pchars = map.getMapAllPlayers(); @@ -753,7 +754,7 @@ public class Monster extends AbstractLoadedLife { } } - return LootManager.retrieveRelevantDrops(this.getId(), lootChars); + return LootManager.retrieveRelevantDrops(this.getId(), lootChars, dropProvider); } public Character killBy(final Character killer) { diff --git a/src/main/java/server/life/MonsterInformationProvider.java b/src/main/java/server/life/MonsterInformationProvider.java index 03ee8e02e5..a81876a01d 100644 --- a/src/main/java/server/life/MonsterInformationProvider.java +++ b/src/main/java/server/life/MonsterInformationProvider.java @@ -99,34 +99,6 @@ public class MonsterInformationProvider { } } - public List retrieveEffectiveDrop(final int monsterId) { - return retrieveDrop(monsterId); - } - - private List retrieveDrop(final int monsterId) { - if (drops.containsKey(monsterId)) { - return drops.get(monsterId); - } - final List ret = new LinkedList<>(); - - try (Connection con = DatabaseConnection.getConnection(); - PreparedStatement ps = con.prepareStatement("SELECT itemid, chance, minimum_quantity, maximum_quantity, questid FROM drop_data WHERE dropperid = ?")) { - ps.setInt(1, monsterId); - - try (ResultSet rs = ps.executeQuery()) { - while (rs.next()) { - ret.add(new MonsterDropEntry(rs.getInt("itemid"), rs.getInt("chance"), rs.getInt("minimum_quantity"), rs.getInt("maximum_quantity"), rs.getShort("questid"))); - } - } - } catch (SQLException e) { - e.printStackTrace(); - return ret; - } - - drops.put(monsterId, ret); - return ret; - } - public final void setMobAttackAnimationTime(int monsterId, int attackPos, int animationTime) { mobAttackAnimationTime.put(new Pair<>(monsterId, attackPos), animationTime); } diff --git a/src/main/java/server/loot/LootManager.java b/src/main/java/server/loot/LootManager.java index a747cc41d8..5df9aa1554 100644 --- a/src/main/java/server/loot/LootManager.java +++ b/src/main/java/server/loot/LootManager.java @@ -20,8 +20,8 @@ package server.loot; import client.Character; +import database.drop.DropProvider; import server.life.MonsterDropEntry; -import server.life.MonsterInformationProvider; import server.quest.Quest; import java.util.Collections; @@ -63,8 +63,8 @@ public class LootManager { return false; } - public static List retrieveRelevantDrops(int monsterId, List chrs) { - List drops = MonsterInformationProvider.getInstance().retrieveEffectiveDrop(monsterId); + public static List retrieveRelevantDrops(int monsterId, List chrs, DropProvider dropProvider) { + List drops = dropProvider.getMonsterDropEntries(monsterId); if (drops.isEmpty()) { return Collections.emptyList(); } diff --git a/src/main/java/server/maps/MapFactory.java b/src/main/java/server/maps/MapFactory.java index 1c7a85cd0c..9d3f808fdd 100644 --- a/src/main/java/server/maps/MapFactory.java +++ b/src/main/java/server/maps/MapFactory.java @@ -22,6 +22,7 @@ package server.maps; import constants.id.MapId; +import database.drop.DropProvider; import provider.Data; import provider.DataProvider; import provider.DataProviderFactory; @@ -127,7 +128,8 @@ public class MapFactory { } } - public static MapleMap loadMapFromWz(int mapid, int world, int channel, EventInstanceManager event) { + public static MapleMap loadMapFromWz(int mapid, int world, int channel, EventInstanceManager event, + DropProvider dropProvider) { MapleMap map; String mapName = getMapName(mapid); @@ -144,7 +146,7 @@ public class MapFactory { if (mobRate != null) { monsterRate = (Float) mobRate.getData(); } - map = new MapleMap(mapid, world, channel, DataTool.getInt("returnMap", infoData), monsterRate); + map = new MapleMap(mapid, world, channel, DataTool.getInt("returnMap", infoData), monsterRate, dropProvider); map.setEventInstance(event); String onFirstEnter = DataTool.getString(infoData.getChildByPath("onFirstUserEnter"), String.valueOf(mapid)); diff --git a/src/main/java/server/maps/MapManager.java b/src/main/java/server/maps/MapManager.java index 4b79038abf..32f43615e6 100644 --- a/src/main/java/server/maps/MapManager.java +++ b/src/main/java/server/maps/MapManager.java @@ -19,6 +19,7 @@ */ package server.maps; +import database.drop.DropProvider; import scripting.event.EventInstanceManager; import java.util.HashMap; @@ -30,17 +31,19 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; public class MapManager { private final int channel; private final int world; - private EventInstanceManager event; + private final DropProvider dropProvider; + private EventInstanceManager eventInstanceManager; private final Map maps = new HashMap<>(); private final Lock mapsRLock; private final Lock mapsWLock; - public MapManager(EventInstanceManager eim, int world, int channel) { + public MapManager(EventInstanceManager eim, int world, int channel, DropProvider dropProvider) { this.world = world; this.channel = channel; - this.event = eim; + this.eventInstanceManager = eim; + this.dropProvider = dropProvider; ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); this.mapsRLock = readWriteLock.readLock(); @@ -74,7 +77,7 @@ public class MapManager { } } - map = MapFactory.loadMapFromWz(mapid, world, channel, event); + map = MapFactory.loadMapFromWz(mapid, world, channel, eventInstanceManager, dropProvider); if (cache) { mapsWLock.lock(); @@ -135,7 +138,7 @@ public class MapManager { map.dispose(); } - this.event = null; + this.eventInstanceManager = null; } } diff --git a/src/main/java/server/maps/MapleMap.java b/src/main/java/server/maps/MapleMap.java index bf44ba733f..044651e58b 100644 --- a/src/main/java/server/maps/MapleMap.java +++ b/src/main/java/server/maps/MapleMap.java @@ -36,6 +36,7 @@ import constants.game.GameConstants; import constants.id.MapId; import constants.id.MobId; import constants.inventory.ItemConstants; +import database.drop.DropProvider; import net.packet.Packet; import net.server.Server; import net.server.channel.Channel; @@ -109,6 +110,7 @@ public class MapleMap { private final int world; private int seats; private byte monsterRate; + private final DropProvider dropProvider; private boolean clock; private boolean boat; private boolean docked = false; @@ -168,7 +170,7 @@ public class MapleMap { // due to the nature of loadMapFromWz (synchronized), sole function that calls 'generateMapDropRangeCache', this lock remains optional. private static final Lock bndLock = new ReentrantLock(true); - public MapleMap(int mapid, int world, int channel, int returnMapId, float monsterRate) { + public MapleMap(int mapid, int world, int channel, int returnMapId, float monsterRate, DropProvider dropProvider) { this.mapid = mapid; this.channel = channel; this.world = world; @@ -177,6 +179,7 @@ public class MapleMap { if (this.monsterRate == 0) { this.monsterRate = 1; } + this.dropProvider = dropProvider; final ReadWriteLock chrLock = new ReentrantReadWriteLock(true); chrRLock = chrLock.readLock(); @@ -733,7 +736,8 @@ public class MapleMap { final List visibleQuestEntry = new ArrayList<>(); final List otherQuestEntry = new ArrayList<>(); - List lootEntry = YamlConfig.config.server.USE_SPAWN_RELEVANT_LOOT ? mob.retrieveRelevantDrops() : mi.retrieveEffectiveDrop(mob.getId()); + List lootEntry = YamlConfig.config.server.USE_SPAWN_RELEVANT_LOOT ? + mob.retrieveRelevantDrops(dropProvider) : dropProvider.getMonsterDropEntries(mob.getId()); sortDropEntries(lootEntry, dropEntry, visibleQuestEntry, otherQuestEntry, chr); // thanks Articuno, Limit, Rohenn for noticing quest loots not showing up in only-quest item drops scenario if (lootEntry.isEmpty()) { // thanks resinate