Move last pieces of monster drops to DropProvider

This commit is contained in:
P0nk
2023-03-16 18:27:14 +01:00
parent 5a35b55d7a
commit f2f3abdb32
6 changed files with 44 additions and 57 deletions

View File

@@ -27,7 +27,6 @@ import client.Character;
import client.Client;
import client.command.Command;
import client.command.CommandContext;
import server.life.MonsterInformationProvider;
public class ReloadDropsCommand extends Command {
{
@@ -37,7 +36,7 @@ public class ReloadDropsCommand extends Command {
@Override
public void execute(Client c, String[] params, CommandContext ctx) {
Character player = c.getPlayer();
MonsterInformationProvider.getInstance().clearDrops();
ctx.dropProvider().clearCaches();
player.dropMessage(5, "Reloaded Drops");
}
}

View File

@@ -103,4 +103,10 @@ public class DropProvider {
ItemInformationProvider ii = ItemInformationProvider.getInstance();
return !ii.isQuestItem(drop.itemId()) && !ii.isPartyQuestItem(drop.itemId());
}
public void clearCaches() {
this.monsterDropCache.invalidateAll();
this.globalContinentDropCache.invalidateAll();
this.globalMonsterDrops = null;
}
}

View File

@@ -23,7 +23,7 @@ package server.life;
/**
* @author LightPepsi
*/
// TODO: replace this with MonsterDrop everywhere, which is immutable and therefore threadsafe
public class MonsterDropEntry {
public MonsterDropEntry(int itemId, int chance, int Minimum, int Maximum, short questid) {
this.itemId = itemId;
@@ -35,4 +35,4 @@ public class MonsterDropEntry {
public short questid;
public int itemId, chance, Minimum, Maximum;
}
}

View File

@@ -23,6 +23,7 @@ package server.life;
/**
* @author LightPepsi
*/
// TODO: replace this with MonsterGlobalDrop, which is immutable and therefore threadsafe
public class MonsterGlobalDropEntry {
public MonsterGlobalDropEntry(int itemId, int chance, int continent, int Minimum, int Maximum, short questid) {
this.itemId = itemId;

View File

@@ -27,13 +27,8 @@ import provider.DataProvider;
import provider.DataProviderFactory;
import provider.DataTool;
import provider.wz.WZFiles;
import tools.DatabaseConnection;
import tools.Pair;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
public class MonsterInformationProvider {
@@ -46,9 +41,6 @@ public class MonsterInformationProvider {
return instance;
}
private final List<MonsterGlobalDropEntry> globaldrops = new ArrayList<>();
private final Map<Integer, List<MonsterGlobalDropEntry>> continentdrops = new HashMap<>();
private final Map<Pair<Integer, Integer>, Integer> mobAttackAnimationTime = new HashMap<>();
private final Map<MobSkill, Integer> mobSkillAnimationTime = new HashMap<>();
@@ -57,45 +49,7 @@ public class MonsterInformationProvider {
private final Map<Integer, Boolean> mobBossCache = new HashMap<>();
private final Map<Integer, String> mobNameCache = new HashMap<>();
protected MonsterInformationProvider() {
retrieveGlobal();
}
public final List<MonsterGlobalDropEntry> getRelevantGlobalDrops(int mapid) {
int continentid = mapid / 100000000;
List<MonsterGlobalDropEntry> contiItems = continentdrops.get(continentid);
if (contiItems == null) { // continent separated global drops found thanks to marcuswoon
contiItems = new ArrayList<>();
for (MonsterGlobalDropEntry e : globaldrops) {
if (e.continentid < 0 || e.continentid == continentid) {
contiItems.add(e);
}
}
continentdrops.put(continentid, contiItems);
}
return contiItems;
}
private void retrieveGlobal() {
try (Connection con = DatabaseConnection.getConnection();
PreparedStatement ps = con.prepareStatement("SELECT * FROM drop_data_global WHERE chance > 0");
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
globaldrops.add(new MonsterGlobalDropEntry(
rs.getInt("itemid"),
rs.getInt("chance"),
rs.getByte("continent"),
rs.getInt("minimum_quantity"),
rs.getInt("maximum_quantity"),
rs.getShort("questid")));
}
} catch (SQLException e) {
log.error("Error retrieving global drops", e);
}
private MonsterInformationProvider() {
}
public final void setMobAttackAnimationTime(int monsterId, int attackPos, int animationTime) {
@@ -176,10 +130,4 @@ public class MonsterInformationProvider {
return mobName;
}
public final void clearDrops() {
globaldrops.clear();
continentdrops.clear();
retrieveGlobal();
}
}

View File

@@ -127,6 +127,39 @@ class DropProviderTest {
assertTrue(dropEntries.isEmpty());
}
@Test
void clearCaches_shouldClearMonsterDrops() {
MonsterDrop drop = snailShellDrop();
when(dropDao.getMonsterDrops(anyInt())).thenReturn(List.of(drop));
int monsterId = 100100;
List<MonsterDropEntry> drops1 = dropProvider.getMonsterDropEntries(monsterId);
dropProvider.clearCaches();
List<MonsterDropEntry> drops2 = dropProvider.getMonsterDropEntries(monsterId);
verify(dropDao, times(2)).getMonsterDrops(anyInt());
assertEquals(1, drops1.size());
assertEquals(1, drops2.size());
}
@Test
void clearCaches_shouldClearGlobalDrops() {
when(dropDao.getGlobalMonsterDrops()).thenReturn(List.of(globalDrop()));
int mapId = 100_000_123;
List<MonsterGlobalDropEntry> drops1 = dropProvider.getRelevantGlobalDrops(mapId);
dropProvider.clearCaches();
List<MonsterGlobalDropEntry> drops2 = dropProvider.getRelevantGlobalDrops(mapId);
verify(dropDao, times(2)).getGlobalMonsterDrops();
assertEquals(1, drops1.size());
assertEquals(1, drops2.size());
}
private GlobalMonsterDrop globalDrop() {
return new GlobalMonsterDrop(2049100, -1, 1, 1, null, 150);
}
// TODO: add tests for getRandomStealDrop() once ItemInformationProvider is able to be mocked.
// Currently, it does database calls (and a bunch of other stuff) in the constructor, which is problematic.
}