Instantiate shops in ShopFactory
This commit is contained in:
@@ -70,14 +70,16 @@ public class ItemId {
|
|||||||
// Throwing star
|
// Throwing star
|
||||||
public static final int SUBI_THROWING_STARS = 2070000;
|
public static final int SUBI_THROWING_STARS = 2070000;
|
||||||
public static final int HWABI_THROWING_STARS = 2070007;
|
public static final int HWABI_THROWING_STARS = 2070007;
|
||||||
|
private static final int ORANGE_THROWING_STARS = 2070013;
|
||||||
public static final int BALANCED_FURY = 2070018;
|
public static final int BALANCED_FURY = 2070018;
|
||||||
public static final int CRYSTAL_ILBI_THROWING_STARS = 2070016;
|
public static final int CRYSTAL_ILBI_THROWING_STARS = 2070016;
|
||||||
private static final int THROWING_STAR_MIN = SUBI_THROWING_STARS;
|
|
||||||
private static final int THROWING_STAR_MAX = 2070016;
|
|
||||||
public static final int DEVIL_RAIN_THROWING_STAR = 2070014;
|
|
||||||
|
|
||||||
public static int[] allThrowingStarIds() {
|
public static IntStream allThrowingStarIds() {
|
||||||
return IntStream.range(THROWING_STAR_MIN, THROWING_STAR_MAX + 1).toArray();
|
// excluding 2070015 - A Beginner Thief's Throwing Stars
|
||||||
|
return IntStream.concat(
|
||||||
|
IntStream.range(SUBI_THROWING_STARS, ORANGE_THROWING_STARS + 1),
|
||||||
|
IntStream.of(CRYSTAL_ILBI_THROWING_STARS, BALANCED_FURY)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bullet
|
// Bullet
|
||||||
@@ -87,8 +89,12 @@ public class ItemId {
|
|||||||
public static final int BLAZE_CAPSULE = 2331000;
|
public static final int BLAZE_CAPSULE = 2331000;
|
||||||
public static final int GLAZE_CAPSULE = 2332000;
|
public static final int GLAZE_CAPSULE = 2332000;
|
||||||
|
|
||||||
public static int[] allBulletIds() {
|
public static IntStream allBulletIds() {
|
||||||
return IntStream.range(BULLET_MIN, BULLET_MAX + 1).toArray();
|
return IntStream.range(BULLET_MIN, BULLET_MAX + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IntStream allBulletCapsuleIds() {
|
||||||
|
return IntStream.of(BLAZE_CAPSULE, GLAZE_CAPSULE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Starter
|
// Starter
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import database.maker.MakerDao;
|
|||||||
import database.maker.MakerInfoProvider;
|
import database.maker.MakerInfoProvider;
|
||||||
import database.migration.FlywayRunner;
|
import database.migration.FlywayRunner;
|
||||||
import database.note.NoteDao;
|
import database.note.NoteDao;
|
||||||
|
import database.shop.ShopDao;
|
||||||
import net.ChannelDependencies;
|
import net.ChannelDependencies;
|
||||||
import net.PacketProcessor;
|
import net.PacketProcessor;
|
||||||
import net.netty.LoginServer;
|
import net.netty.LoginServer;
|
||||||
@@ -978,7 +979,7 @@ public class Server {
|
|||||||
MakerProcessor makerProcessor = new MakerProcessor(new MakerInfoProvider(new MakerDao(connection)));
|
MakerProcessor makerProcessor = new MakerProcessor(new MakerInfoProvider(new MakerDao(connection)));
|
||||||
FredrickProcessor fredrickProcessor = new FredrickProcessor(noteService);
|
FredrickProcessor fredrickProcessor = new FredrickProcessor(noteService);
|
||||||
DropProvider dropProvider = new DropProvider(new DropDao(connection));
|
DropProvider dropProvider = new DropProvider(new DropDao(connection));
|
||||||
ShopFactory shopFactory = new ShopFactory();
|
ShopFactory shopFactory = new ShopFactory(new ShopDao(connection));
|
||||||
CommandContext commandContext = new CommandContext(dropProvider, shopFactory);
|
CommandContext commandContext = new CommandContext(dropProvider, shopFactory);
|
||||||
CommandsExecutor commandsExecutor = new CommandsExecutor(commandContext);
|
CommandsExecutor commandsExecutor = new CommandsExecutor(commandContext);
|
||||||
ChannelDependencies channelDependencies = new ChannelDependencies(noteService, fredrickProcessor,
|
ChannelDependencies channelDependencies = new ChannelDependencies(noteService, fredrickProcessor,
|
||||||
|
|||||||
@@ -106,11 +106,11 @@ public final class NPCTalkHandler extends AbstractPacketHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasShop(NPC npc) {
|
private boolean hasShop(NPC npc) {
|
||||||
return shopFactory.getShopForNPC(npc.getId()) != null;
|
return shopFactory.getShop(npc.getId()) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendShop(NPC npc, Client c) {
|
private void sendShop(NPC npc, Client c) {
|
||||||
Shop shop = shopFactory.getShopForNPC(npc.getId());
|
Shop shop = shopFactory.getShop(npc.getId());
|
||||||
if (shop == null) {
|
if (shop == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,25 +30,16 @@ import constants.id.ItemId;
|
|||||||
import constants.inventory.ItemConstants;
|
import constants.inventory.ItemConstants;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import tools.DatabaseConnection;
|
|
||||||
import tools.PacketCreator;
|
import tools.PacketCreator;
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Matze
|
* @author Matze
|
||||||
*/
|
*/
|
||||||
public class Shop {
|
public class Shop {
|
||||||
private static final Logger log = LoggerFactory.getLogger(Shop.class);
|
private static final Logger log = LoggerFactory.getLogger(Shop.class);
|
||||||
private static final Set<Integer> rechargeableItems = new LinkedHashSet<>();
|
|
||||||
private static final short MAX_QUANTITY_PER_PURCHASE = 1000; // Should really use max stack size for the given item
|
|
||||||
|
|
||||||
private final int id;
|
private final int id;
|
||||||
private final int npcId;
|
private final int npcId;
|
||||||
@@ -56,27 +47,10 @@ public class Shop {
|
|||||||
private final int tokenvalue = 1000000000;
|
private final int tokenvalue = 1000000000;
|
||||||
private final int token = ItemId.GOLDEN_MAPLE_LEAF;
|
private final int token = ItemId.GOLDEN_MAPLE_LEAF;
|
||||||
|
|
||||||
static {
|
public Shop(int id, int npcId, List<ShopItem> items) {
|
||||||
for (int throwingStarId : ItemId.allThrowingStarIds()) {
|
|
||||||
rechargeableItems.add(throwingStarId);
|
|
||||||
}
|
|
||||||
rechargeableItems.add(ItemId.BLAZE_CAPSULE);
|
|
||||||
rechargeableItems.add(ItemId.GLAZE_CAPSULE);
|
|
||||||
rechargeableItems.add(ItemId.BALANCED_FURY);
|
|
||||||
rechargeableItems.remove(ItemId.DEVIL_RAIN_THROWING_STAR); // doesn't exist
|
|
||||||
for (int bulletId : ItemId.allBulletIds()) {
|
|
||||||
rechargeableItems.add(bulletId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Shop(int id, int npcId) {
|
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.npcId = npcId;
|
this.npcId = npcId;
|
||||||
items = new ArrayList<>();
|
this.items = new ArrayList<>(items);
|
||||||
}
|
|
||||||
|
|
||||||
private void addItem(ShopItem item) {
|
|
||||||
items.add(item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendShop(Client c) {
|
public void sendShop(Client c) {
|
||||||
@@ -242,57 +216,6 @@ public class Shop {
|
|||||||
return items.get(slot);
|
return items.get(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Shop createFromDB(int id, boolean isShopId) {
|
|
||||||
Shop ret = null;
|
|
||||||
int shopId;
|
|
||||||
try (Connection con = DatabaseConnection.getConnection()) {
|
|
||||||
final String query;
|
|
||||||
if (isShopId) {
|
|
||||||
query = "SELECT * FROM shops WHERE shopid = ?";
|
|
||||||
} else {
|
|
||||||
query = "SELECT * FROM shops WHERE npcid = ?";
|
|
||||||
}
|
|
||||||
|
|
||||||
try (PreparedStatement ps = con.prepareStatement(query)) {
|
|
||||||
ps.setInt(1, id);
|
|
||||||
|
|
||||||
try (ResultSet rs = ps.executeQuery()) {
|
|
||||||
if (rs.next()) {
|
|
||||||
shopId = rs.getInt("shopid");
|
|
||||||
ret = new Shop(shopId, rs.getInt("npcid"));
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try (PreparedStatement ps = con.prepareStatement("SELECT itemid, price, pitch FROM shopitems WHERE shopid = ? ORDER BY position DESC")) {
|
|
||||||
ps.setInt(1, shopId);
|
|
||||||
|
|
||||||
try (ResultSet rs = ps.executeQuery()) {
|
|
||||||
List<Integer> recharges = new ArrayList<>(rechargeableItems);
|
|
||||||
while (rs.next()) {
|
|
||||||
if (ItemConstants.isRechargeable(rs.getInt("itemid"))) {
|
|
||||||
ShopItem starItem = new ShopItem((short) 1, rs.getInt("itemid"), rs.getInt("price"), rs.getInt("pitch"));
|
|
||||||
ret.addItem(starItem);
|
|
||||||
if (rechargeableItems.contains(starItem.getItemId())) {
|
|
||||||
recharges.remove(Integer.valueOf(starItem.getItemId()));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ret.addItem(new ShopItem(MAX_QUANTITY_PER_PURCHASE, rs.getInt("itemid"), rs.getInt("price"), rs.getInt("pitch")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (Integer recharge : recharges) {
|
|
||||||
ret.addItem(new ShopItem((short) 0, recharge, 0, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNpcId() {
|
public int getNpcId() {
|
||||||
return npcId;
|
return npcId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,45 +21,67 @@
|
|||||||
*/
|
*/
|
||||||
package server;
|
package server;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import com.github.benmanes.caffeine.cache.Cache;
|
||||||
import java.util.Map;
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
|
import constants.id.ItemId;
|
||||||
|
import constants.inventory.ItemConstants;
|
||||||
|
import database.shop.ShopDao;
|
||||||
|
import database.shop.ShopItem;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Matze
|
* @author Matze
|
||||||
*/
|
*/
|
||||||
public class ShopFactory {
|
public class ShopFactory {
|
||||||
private final Map<Integer, Shop> shops = new HashMap<>();
|
private static final short MAX_QUANTITY_PER_PURCHASE = 1000; // Should really use max stack size for the given item
|
||||||
private final Map<Integer, Shop> npcShops = new HashMap<>();
|
private static final Set<Integer> rechargeableItemIds = rechargeableItemIds();
|
||||||
|
private final Cache<Integer, Shop> shops = Caffeine.newBuilder().build();
|
||||||
|
private final ShopDao shopDao;
|
||||||
|
|
||||||
private Shop loadShop(int id, boolean isShopId) {
|
public ShopFactory(ShopDao shopDao) {
|
||||||
Shop ret = Shop.createFromDB(id, isShopId);
|
this.shopDao = shopDao;
|
||||||
if (ret != null) {
|
|
||||||
shops.put(ret.getId(), ret);
|
|
||||||
npcShops.put(ret.getNpcId(), ret);
|
|
||||||
} else if (isShopId) {
|
|
||||||
shops.put(id, null);
|
|
||||||
} else {
|
|
||||||
npcShops.put(id, null);
|
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
|
private static Set<Integer> rechargeableItemIds() {
|
||||||
|
IntStream stars = ItemId.allThrowingStarIds();
|
||||||
|
IntStream ammo = IntStream.concat(ItemId.allBulletIds(), ItemId.allBulletCapsuleIds());
|
||||||
|
return IntStream.concat(stars, ammo)
|
||||||
|
.boxed()
|
||||||
|
.collect(Collectors.toUnmodifiableSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Shop getShop(int shopId) {
|
public Shop getShop(int shopId) {
|
||||||
if (shops.containsKey(shopId)) {
|
return shops.get(shopId, this::loadShop);
|
||||||
return shops.get(shopId);
|
|
||||||
}
|
|
||||||
return loadShop(shopId, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Shop getShopForNPC(int npcId) {
|
private Shop loadShop(int shopId) {
|
||||||
if (npcShops.containsKey(npcId)) {
|
Optional<database.shop.Shop> dbShop = shopDao.getShop(shopId);
|
||||||
return npcShops.get(npcId);
|
if (dbShop.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("Shop with id %d does not exist".formatted(shopId));
|
||||||
}
|
}
|
||||||
return loadShop(npcId, false);
|
List<ShopItem> items = shopDao.getShopItems(shopId);
|
||||||
|
return new Shop(dbShop.get().id(), dbShop.get().npcId(), fromDbShopItems(items));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<server.ShopItem> fromDbShopItems(List<ShopItem> dbItems) {
|
||||||
|
Stream<server.ShopItem> purchaseableItems = dbItems.stream()
|
||||||
|
.map(dbItem -> {
|
||||||
|
short buyable = ItemConstants.isRechargeable(dbItem.itemId()) ? (short) 1 : MAX_QUANTITY_PER_PURCHASE;
|
||||||
|
int pitch = dbItem.pitch() == null ? 0 : dbItem.pitch();
|
||||||
|
return new server.ShopItem(buyable, dbItem.itemId(), dbItem.price(), pitch);
|
||||||
|
});
|
||||||
|
Stream<server.ShopItem> rechargeableItems = rechargeableItemIds.stream()
|
||||||
|
.map(rechItem -> new server.ShopItem((short) 0, rechItem, 0, 0));
|
||||||
|
return Stream.concat(purchaseableItems, rechargeableItems).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reloadShops() {
|
public void reloadShops() {
|
||||||
shops.clear();
|
shops.invalidateAll();
|
||||||
npcShops.clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user