/* * This file is part of OrionAlpha, a MapleStory Emulator Project. * Copyright (C) 2018 Eric Smith <[email protected]> * * This program 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. * * This program 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 shop; import game.user.item.ItemInfo; import java.io.FileNotFoundException; import java.io.FileReader; import java.net.InetSocketAddress; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import javax.json.Json; import javax.json.JsonObject; import javax.json.JsonReader; import network.ShopAcceptor; import network.database.CommonDB; import network.database.Database; import util.Logger; import util.wz.WzFileSystem; import util.wz.WzPackage; import util.wz.WzProperty; import util.wz.WzUtil; /** * * @author Eric */ public class ShopApp { private static final ShopApp instance = new ShopApp(); private String addr; private short port; private byte worldID; private int connectionLimit; private int waitingFirstPacket; private ShopAcceptor acceptor; private CenterSocket socket; private final long serverStartTime; private final AtomicLong itemInitSN; private final AtomicLong cashItemInitSN; private final Lock lockItemSN; private final Lock lockCashItemSN; private final Map<Long, Commodity> commodity; public ShopApp() { this.worldID = -2;//ShopSvr this.waitingFirstPacket = 1000 * 15; this.connectionLimit = 1000; this.serverStartTime = System.currentTimeMillis(); this.itemInitSN = new AtomicLong(0); this.cashItemInitSN = new AtomicLong(0); this.lockItemSN = new ReentrantLock(); this.lockCashItemSN = new ReentrantLock(); this.commodity = new HashMap<>(); } public static final ShopApp getInstance() { return instance; } public static void main(String[] args) { ShopApp.getInstance().start(); } private void connectCenter() { try (JsonReader reader = Json.createReader(new FileReader("Shop.img"))) { JsonObject shopData = reader.readObject(); Integer world = shopData.getInt("gameWorldId", getWorldID()); if (world != getWorldID()) { //this.worldID = world.byteValue(); } this.addr = shopData.getString("PublicIP", "127.0.0.1"); this.port = (short) shopData.getInt("port", 8787); JsonObject loginData = shopData.getJsonObject("login"); if (loginData != null) { this.socket = new CenterSocket(); this.socket.init(loginData); this.socket.connect(); } } catch (FileNotFoundException ex) { ex.printStackTrace(System.err); } } private void createAcceptor() { this.acceptor = new ShopAcceptor(new InetSocketAddress(addr, port)); this.acceptor.start(); Logger.logReport("Socket acceptor started"); } public final ShopAcceptor getAcceptor() { return acceptor; } public final CenterSocket getCenter() { return socket; } public Map<Long, Commodity> getCommodity() { return this.commodity; } public Commodity findCommodity(long commoditySN) { if (commodity.containsKey(commoditySN)) { return commodity.get(commoditySN); } return null; } public int getConnectionLimit() { return connectionLimit; } public String getAddr() { return addr; } public final long getNextCashSN() { lockCashItemSN.lock(); try { final long cashItemSN = cashItemInitSN.decrementAndGet(); return cashItemSN; } finally { lockCashItemSN.unlock(); } } public final long getNextSN() { lockItemSN.lock(); try { return itemInitSN.get(); } finally { lockItemSN.unlock(); } } public short getPort() { return port; } public long getServerStartTime() { return serverStartTime; } public int getWaitingFirstPacket() { return waitingFirstPacket; } public byte getWorldID() { return worldID; } private void initializeCommodity() { long time; time = System.currentTimeMillis(); ItemInfo.load(); Logger.logReport("Loaded Item Info in " + ((System.currentTimeMillis() - time) / 1000.0) + " seconds."); WzPackage etcDir = new WzFileSystem().init("Etc").getPackage(); if (etcDir != null) { WzProperty img = etcDir.getItem("Commodity.img"); time = System.currentTimeMillis(); for (WzProperty imgDir : img.getChildNodes()) { Commodity comm = new Commodity(); comm.setSN(WzUtil.getInt32(imgDir.getNode("SN"), 0)); comm.setItemID(WzUtil.getInt32(imgDir.getNode("ItemId"), 0)); comm.setCount(WzUtil.getShort(imgDir.getNode("Count"), 0)); comm.setPrice(WzUtil.getInt32(imgDir.getNode("Price"), 0)); comm.setPeriod(WzUtil.getByte(imgDir.getNode("Period"), 0)); comm.setPriority(WzUtil.getByte(imgDir.getNode("Priority"), 0)); commodity.put(comm.getSN(), comm); } etcDir.release(); Logger.logReport("Loaded Commodity in " + ((System.currentTimeMillis() - time) / 1000.0) + " seconds."); } etcDir = null; } private void initializeDB() { try (JsonReader reader = Json.createReader(new FileReader("Database.img"))) { JsonObject dbData = reader.readObject(); int dbPort = dbData.getInt("dbPort", 3306); String dbName = dbData.getString("dbGameWorld", "orionalpha"); String dbSource = dbData.getString("dbGameWorldSource", "127.0.0.1"); String[] dbInfo = dbData.getString("dbGameWorldInfo", "root,").split(","); // Construct the instance of the Database Database.createInstance(dbName, dbSource, dbInfo[0], dbInfo.length == 1 ? "" : dbInfo[1], dbPort); // Load the initial instance of the Database Database.getDB().load(); Logger.logReport("DB configuration parsed successfully"); } catch (FileNotFoundException ex) { ex.printStackTrace(System.err); } } private void initializeItemSN() { CommonDB.rawLoadItemInitSN(this.worldID, this.itemInitSN, this.cashItemInitSN); } public void start() { connectCenter(); initializeDB(); initializeItemSN(); initializeCommodity(); createAcceptor(); Logger.logReport("The Shop Server has been initialized in " + ((System.currentTimeMillis() - serverStartTime) / 1000.0) + " seconds."); } public void updateItemInitSN() { CommonDB.rawUpdateItemInitSN(this.worldID, this.itemInitSN, this.cashItemInitSN); } }