/* * Copyright (C) 2004-2015 L2J Server * * This file is part of L2J Server. * * L2J Server is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * L2J Server is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.l2jserver.gameserver.data.xml.impl; import java.io.File; import java.io.FileFilter; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import com.l2jserver.Config; import com.l2jserver.L2DatabaseFactory; import com.l2jserver.gameserver.data.xml.IXmlReader; import com.l2jserver.gameserver.datatables.ItemTable; import com.l2jserver.gameserver.model.buylist.L2BuyList; import com.l2jserver.gameserver.model.buylist.Product; import com.l2jserver.gameserver.model.items.L2Item; import com.l2jserver.util.file.filter.NumericNameFilter; /** * Loads buy lists for NPCs. * @author NosBit */ public final class BuyListData implements IXmlReader { private final Map<Integer, L2BuyList> _buyLists = new HashMap<>(); private static final FileFilter NUMERIC_FILTER = new NumericNameFilter(); protected BuyListData() { load(); } @Override public synchronized void load() { _buyLists.clear(); parseDatapackDirectory("data/buylists", false); if (Config.CUSTOM_BUYLIST_LOAD) { parseDatapackDirectory("data/buylists/custom", false); } LOGGER.info(getClass().getSimpleName() + ": Loaded " + _buyLists.size() + " BuyLists."); try (Connection con = L2DatabaseFactory.getInstance().getConnection(); Statement statement = con.createStatement(); ResultSet rs = statement.executeQuery("SELECT * FROM `buylists`")) { while (rs.next()) { int buyListId = rs.getInt("buylist_id"); int itemId = rs.getInt("item_id"); long count = rs.getLong("count"); long nextRestockTime = rs.getLong("next_restock_time"); final L2BuyList buyList = getBuyList(buyListId); if (buyList == null) { LOGGER.warning("BuyList found in database but not loaded from xml! BuyListId: " + buyListId); continue; } final Product product = buyList.getProductByItemId(itemId); if (product == null) { LOGGER.warning("ItemId found in database but not loaded from xml! BuyListId: " + buyListId + " ItemId: " + itemId); continue; } if (count < product.getMaxCount()) { product.setCount(count); product.restartRestockTask(nextRestockTime); } } } catch (Exception e) { LOGGER.log(Level.WARNING, "Failed to load buyList data from database.", e); } } @Override public void parseDocument(Document doc, File f) { try { final int buyListId = Integer.parseInt(f.getName().replaceAll(".xml", "")); for (Node node = doc.getFirstChild(); node != null; node = node.getNextSibling()) { if ("list".equalsIgnoreCase(node.getNodeName())) { final L2BuyList buyList = new L2BuyList(buyListId); for (Node list_node = node.getFirstChild(); list_node != null; list_node = list_node.getNextSibling()) { if ("item".equalsIgnoreCase(list_node.getNodeName())) { int itemId = -1; long price = -1; long restockDelay = -1; long count = -1; NamedNodeMap attrs = list_node.getAttributes(); Node attr = attrs.getNamedItem("id"); itemId = Integer.parseInt(attr.getNodeValue()); attr = attrs.getNamedItem("price"); if (attr != null) { price = Long.parseLong(attr.getNodeValue()); } attr = attrs.getNamedItem("restock_delay"); if (attr != null) { restockDelay = Long.parseLong(attr.getNodeValue()); } attr = attrs.getNamedItem("count"); if (attr != null) { count = Long.parseLong(attr.getNodeValue()); } final L2Item item = ItemTable.getInstance().getTemplate(itemId); if (item != null) { buyList.addProduct(new Product(buyList.getListId(), item, price, restockDelay, count)); } else { LOGGER.warning("Item not found. BuyList:" + buyList.getListId() + " ItemID:" + itemId + " File:" + f.getName()); } } else if ("npcs".equalsIgnoreCase(list_node.getNodeName())) { for (Node npcs_node = list_node.getFirstChild(); npcs_node != null; npcs_node = npcs_node.getNextSibling()) { if ("npc".equalsIgnoreCase(npcs_node.getNodeName())) { int npcId = Integer.parseInt(npcs_node.getTextContent()); buyList.addAllowedNpc(npcId); } } } } _buyLists.put(buyList.getListId(), buyList); } } } catch (Exception e) { LOGGER.log(Level.WARNING, "Failed to load buyList data from xml File:" + f.getName(), e); } } @Override public FileFilter getCurrentFileFilter() { return NUMERIC_FILTER; } public L2BuyList getBuyList(int listId) { return _buyLists.get(listId); } public static BuyListData getInstance() { return SingletonHolder._instance; } private static class SingletonHolder { protected static final BuyListData _instance = new BuyListData(); } }