diff --git a/tools/MapleCashDropFetcher/src/maplecashdropfetcher/MapleCashDropFetcher.java b/src/main/java/tools/mapletools/CashDropFetcher.java similarity index 56% rename from tools/MapleCashDropFetcher/src/maplecashdropfetcher/MapleCashDropFetcher.java rename to src/main/java/tools/mapletools/CashDropFetcher.java index cc610c9fcd..75176c4a81 100644 --- a/tools/MapleCashDropFetcher/src/maplecashdropfetcher/MapleCashDropFetcher.java +++ b/src/main/java/tools/mapletools/CashDropFetcher.java @@ -1,96 +1,59 @@ -/* - This file is part of the HeavenMS MapleStory Server - Copyleft (L) 2016 - 2019 RonanLana +package tools.mapletools; - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation version 3 as published by - the Free Software Foundation. You may not use, modify or distribute - this program under any other version of the GNU Affero General Public - License. +import provider.wz.WZFiles; +import tools.Pair; - 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ -package maplecashdropfetcher; - -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.InputStreamReader; -import java.io.PrintWriter; +import java.io.*; +import java.nio.charset.StandardCharsets; import java.sql.Connection; -import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.HashSet; -import java.util.Set; - -import java.io.File; - -import tools.Pair; +import java.util.*; /** - * * @author RonanLana - - This application gets info from the WZ.XML files regarding cash itemids then searches the drop data on the DB - after any NX (cash item) drops and reports them. - - Estimated parse time: 2 minutes + *

+ * This application gets info from the WZ.XML files regarding cash itemids then searches the drop data on the DB + * after any NX (cash item) drops and reports them. + *

+ * Estimated parse time: 2 minutes */ -public class MapleCashDropFetcher { - static String host = "jdbc:mysql://localhost:3306/cosmic"; - static String driver = "com.mysql.jdbc.Driver"; - static String username = "cosmic_server"; - static String password = "snailshell"; +public class CashDropFetcher { + private static final File OUTPUT_FILE = ToolConstants.getOutputFile("cash_drop_report.txt"); + private static final Connection con = SimpleDatabaseConnection.getConnection(); + private static final int INITIAL_STRING_LENGTH = 50; + private static final int ITEM_FILE_NAME_SIZE = 13; - static String wzPath = "../../wz"; - - static String directoryName = "../.."; - static String newFile = "lib/CashDropReport.txt"; + private static final Set nxItems = new HashSet<>(); + private static final Set nxDrops = new HashSet<>(); - static Connection con = null; - static PrintWriter printWriter = null; - static InputStreamReader fileReader = null; - static BufferedReader bufferedReader = null; - - static int initialLength = 200; - static int initialStringLength = 50; - static int itemFileNameSize = 13; - - static Set nxItems = new HashSet<>(); - static Set nxDrops = new HashSet<>(); - - static byte status = 0; - static int currentItemid = 0; + private static PrintWriter printWriter = null; + private static BufferedReader bufferedReader = null; + + private static byte status = 0; + private static int currentItemid = 0; private static String getName(String token) { int i, j; char[] dest; String d; - + i = token.lastIndexOf("name"); i = token.indexOf("\"", i) + 1; //lower bound of the string j = token.indexOf("\"", i); //upper bound - if(j < i) return "0"; //node value containing 'name' in it's scope, cheap fix since we don't deal with strings anyway - - dest = new char[initialStringLength]; + if (j < i) { + return "0"; //node value containing 'name' in it's scope, cheap fix since we don't deal with strings anyway + } + + dest = new char[INITIAL_STRING_LENGTH]; token.getChars(i, j, dest, 0); d = new String(dest); - return(d.trim()); + return (d.trim()); } - + private static String getValue(String token) { int i, j; char[] dest; @@ -100,115 +63,106 @@ public class MapleCashDropFetcher { i = token.indexOf("\"", i) + 1; //lower bound of the string j = token.indexOf("\"", i); //upper bound - dest = new char[initialStringLength]; + dest = new char[INITIAL_STRING_LENGTH]; token.getChars(i, j, dest, 0); d = new String(dest); - return(d.trim()); + return (d.trim()); } - + private static void forwardCursor(int st) { String line = null; try { - while(status >= st && (line = bufferedReader.readLine()) != null) { + while (status >= st && (line = bufferedReader.readLine()) != null) { simpleToken(line); } - } - catch(Exception e) { + } catch (Exception e) { e.printStackTrace(); } } - + private static void simpleToken(String token) { - if(token.contains("/imgdir")) { + if (token.contains("/imgdir")) { status -= 1; - } - else if(token.contains("imgdir")) { + } else if (token.contains("imgdir")) { status += 1; } } - - + + private static void inspectEquipWzEntry() { String line = null; try { - while((line = bufferedReader.readLine()) != null) { + while ((line = bufferedReader.readLine()) != null) { translateEquipToken(line); } - } - catch(Exception e) { + } catch (Exception e) { e.printStackTrace(); } } - + private static void translateEquipToken(String token) { - if(token.contains("/imgdir")) { + if (token.contains("/imgdir")) { status -= 1; - } - else if(token.contains("imgdir")) { - if(status == 1) { - if(!getName(token).equals("info")) { + } else if (token.contains("imgdir")) { + if (status == 1) { + if (!getName(token).equals("info")) { forwardCursor(status); } } - + status += 1; - } - else { - if(status == 2) { + } else { + if (status == 2) { String d = getName(token); - - if(d.equals("cash")) { - if(!getValue(token).equals("0")) { + + if (d.equals("cash")) { + if (!getValue(token).equals("0")) { nxItems.add(currentItemid); } - + forwardCursor(status); } } } } - + private static void inspectItemWzEntry() { String line = null; try { - while((line = bufferedReader.readLine()) != null) { + while ((line = bufferedReader.readLine()) != null) { translateItemToken(line); } - } - catch(Exception e) { + } catch (Exception e) { e.printStackTrace(); } } - + private static void translateItemToken(String token) { - if(token.contains("/imgdir")) { + if (token.contains("/imgdir")) { status -= 1; - } - else if(token.contains("imgdir")) { - if(status == 1) { - currentItemid = Integer.valueOf(getName(token)); - } - else if(status == 2) { - if(!getName(token).equals("info")) { + } else if (token.contains("imgdir")) { + if (status == 1) { + currentItemid = Integer.parseInt(getName(token)); + } else if (status == 2) { + if (!getName(token).equals("info")) { forwardCursor(status); } } - + status += 1; - } - else { - if(status == 3) { + } else { + if (status == 3) { String d = getName(token); - - if(d.equals("cash")) { - if(!getValue(token).equals("0")) { + + if (d.equals("cash")) { + if (!getValue(token).equals("0")) { nxItems.add(currentItemid); } - + forwardCursor(status); } } @@ -220,7 +174,7 @@ public class MapleCashDropFetcher { printWriter.println(" # Generated data takes into account several data info from the underlying DB and the server-side WZ.xmls."); printWriter.println(); } - + private static void listFiles(String directoryName, ArrayList files) { File directory = new File(directoryName); @@ -234,93 +188,92 @@ public class MapleCashDropFetcher { } } } - + private static int getItemIdFromFilename(String name) { try { - return Integer.valueOf(name.substring(0, name.indexOf('.'))); - } catch(Exception e) { + return Integer.parseInt(name.substring(0, name.indexOf('.'))); + } catch (Exception e) { return -1; } } - + private static String getDropTableName(boolean dropdata) { return (dropdata ? "drop_data" : "reactordrops"); } - + private static String getDropElementName(boolean dropdata) { return (dropdata ? "dropperid" : "reactorid"); } - + private static void filterNxDropsOnDB(boolean dropdata) throws SQLException { nxDrops.clear(); - + PreparedStatement ps = con.prepareStatement("SELECT DISTINCT itemid FROM " + getDropTableName(dropdata)); ResultSet rs = ps.executeQuery(); - - while(rs.next()) { + + while (rs.next()) { int itemid = rs.getInt("itemid"); - - if(nxItems.contains(itemid)) { + + if (nxItems.contains(itemid)) { nxDrops.add(itemid); } } - + rs.close(); ps.close(); } - + private static List> getNxDropsEntries(boolean dropdata) throws SQLException { List> entries = new ArrayList<>(); - + List sortedNxDrops = new ArrayList<>(nxDrops); Collections.sort(sortedNxDrops); - - for(Integer nx : sortedNxDrops) { + + for (Integer nx : sortedNxDrops) { PreparedStatement ps = con.prepareStatement("SELECT " + getDropElementName(dropdata) + " FROM " + getDropTableName(dropdata) + " WHERE itemid = ?"); ps.setInt(1, nx); - + ResultSet rs = ps.executeQuery(); - while(rs.next()) { + while (rs.next()) { entries.add(new Pair<>(nx, rs.getInt(getDropElementName(dropdata)))); } - + rs.close(); ps.close(); } - + return entries; } - + private static void reportNxDropResults(boolean dropdata) throws SQLException { filterNxDropsOnDB(dropdata); - - if(!nxDrops.isEmpty()) { + + if (!nxDrops.isEmpty()) { List> nxEntries = getNxDropsEntries(dropdata); printWriter.println("NX DROPS ON " + getDropTableName(dropdata)); - for(Pair nx : nxEntries) { + for (Pair nx : nxEntries) { printWriter.println(nx.left + " : " + nx.right); } printWriter.println("\n\n\n"); } } - - private static void ReportNxDropData() { + + private static void reportNxDropData() { try { - Class.forName(driver).newInstance(); - System.out.println("Reading Character.wz ..."); ArrayList files = new ArrayList<>(); - listFiles(wzPath + "/Character.wz", files); - - for(File f : files) { + listFiles(WZFiles.CHARACTER.getFilePath(), files); + + InputStreamReader fileReader = null; + for (File f : files) { //System.out.println("Parsing " + f.getAbsolutePath()); int itemid = getItemIdFromFilename(f.getName()); - if(itemid < 0) { + if (itemid < 0) { continue; } - - fileReader = new InputStreamReader(new FileInputStream(f), "UTF-8"); + + fileReader = new InputStreamReader(new FileInputStream(f), StandardCharsets.UTF_8); bufferedReader = new BufferedReader(fileReader); currentItemid = itemid; @@ -329,24 +282,24 @@ public class MapleCashDropFetcher { bufferedReader.close(); fileReader.close(); } - + System.out.println("Reading Item.wz ..."); files = new ArrayList<>(); - listFiles(wzPath + "/Item.wz", files); - - for(File f : files) { + listFiles(WZFiles.ITEM.getFilePath(), files); + + for (File f : files) { //System.out.println("Parsing " + f.getAbsolutePath()); - fileReader = new InputStreamReader(new FileInputStream(f), "UTF-8"); + fileReader = new InputStreamReader(new FileInputStream(f), StandardCharsets.UTF_8); bufferedReader = new BufferedReader(fileReader); - if(f.getName().length() <= itemFileNameSize) { + if (f.getName().length() <= ITEM_FILE_NAME_SIZE) { inspectItemWzEntry(); } else { // pet file structure is similar to equips, maybe there are other item-types following this behaviour? int itemid = getItemIdFromFilename(f.getName()); - if(itemid < 0) { + if (itemid < 0) { continue; } - + currentItemid = itemid; inspectEquipWzEntry(); } @@ -354,53 +307,35 @@ public class MapleCashDropFetcher { bufferedReader.close(); fileReader.close(); } - + System.out.println("Reporting results..."); - - // filter drop data on DB - con = DriverManager.getConnection(host, username, password); - + // report suspects of missing quest drop data, as well as those drop data that may have incorrect questids. - printWriter = new PrintWriter(newFile, "UTF-8"); + printWriter = new PrintWriter(OUTPUT_FILE, StandardCharsets.UTF_8); printReportFileHeader(); - + reportNxDropResults(true); reportNxDropResults(false); - + /* printWriter.println("NX LIST"); // list of all cash items found for(Integer nx : nxItems) { printWriter.println(nx); } */ - + con.close(); printWriter.close(); System.out.println("Done!"); - } - - catch(SQLException e) { + } catch (SQLException e) { System.out.println("Warning: Could not establish connection to database to report quest data."); System.out.println(e.getMessage()); - } - - catch(ClassNotFoundException e) { - System.out.println("Error: could not find class"); - System.out.println(e.getMessage()); - } - - catch(InstantiationException e) { - System.out.println("Error: instantiation failure"); - System.out.println(e.getMessage()); - } - - catch(Exception e) { + } catch (Exception e) { e.printStackTrace(); } } - + public static void main(String[] args) { - ReportNxDropData(); + reportNxDropData(); } - } diff --git a/tools/MapleCashDropFetcher/lib/CashDropReport.txt b/tools/MapleCashDropFetcher/lib/CashDropReport.txt deleted file mode 100644 index b60c817722..0000000000 --- a/tools/MapleCashDropFetcher/lib/CashDropReport.txt +++ /dev/null @@ -1,11 +0,0 @@ - # Report File autogenerated from the MapleCashDropFetcher feature by Ronan Lana. - # Generated data takes into account several data info from the underlying DB and the server-side WZ.xmls. - -NX DROPS ON drop_data -5240005 : 2100100 -5490000 : 9410066 -5490001 : 9410066 - - - - diff --git a/tools/MapleCashDropFetcher/src/tools/DatabaseConnection.java b/tools/MapleCashDropFetcher/src/tools/DatabaseConnection.java deleted file mode 100644 index b887280343..0000000000 --- a/tools/MapleCashDropFetcher/src/tools/DatabaseConnection.java +++ /dev/null @@ -1,51 +0,0 @@ -package tools; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; - -/** - * @author Frz (Big Daddy) - * @author The Real Spookster - some modifications to this beautiful code - */ -public class DatabaseConnection { - private static String DB_URL = "jdbc:mysql://localhost:3306/cosmic"; - private static String DB_USER = "cosmic_server"; - private static String DB_PASS = "snailshell"; - - public static final int RETURN_GENERATED_KEYS = 1; - - private static ThreadLocal con = new ThreadLocalConnection(); - - public static Connection getConnection() { - Connection c = con.get(); - try { - c.getMetaData(); - } catch (SQLException e) { // connection is dead, therefore discard old object 5ever - con.remove(); - c = con.get(); - } - return c; - } - - private static class ThreadLocalConnection extends ThreadLocal { - - @Override - protected Connection initialValue() { - try { - Class.forName("com.mysql.jdbc.Driver"); // touch the mysql driver - } catch (ClassNotFoundException e) { - System.out.println("[SEVERE] SQL Driver Not Found. Consider death by clams."); - e.printStackTrace(); - return null; - } - try { - return DriverManager.getConnection(DB_URL, DB_USER, DB_PASS); - } catch (SQLException e) { - System.out.println("[SEVERE] Unable to make database connection."); - e.printStackTrace(); - return null; - } - } - } -} \ No newline at end of file diff --git a/tools/MapleCashDropFetcher/src/tools/Pair.java b/tools/MapleCashDropFetcher/src/tools/Pair.java deleted file mode 100644 index b127e71110..0000000000 --- a/tools/MapleCashDropFetcher/src/tools/Pair.java +++ /dev/null @@ -1,121 +0,0 @@ -/* -This file is part of the OdinMS Maple Story Server -Copyright (C) 2008 ~ 2010 Patrick Huy -Matthias Butz -Jan Christian Meyer - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License version 3 -as published by the Free Software Foundation. You may not use, modify -or distribute this program under any other version of the -GNU Affero General Public License. - -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 Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . - */ -package tools; - -/** - * Represents a pair of values. - * - * @author Frz - * @since Revision 333 - * @version 1.0 - * - * @param The type of the left value. - * @param The type of the right value. - */ -public class Pair { - - public E left; - public F right; - - /** - * Class constructor - pairs two objects together. - * - * @param left The left object. - * @param right The right object. - */ - public Pair(E left, F right) { - this.left = left; - this.right = right; - } - - /** - * Gets the left value. - * - * @return The left value. - */ - public E getLeft() { - return left; - } - - /** - * Gets the right value. - * - * @return The right value. - */ - public F getRight() { - return right; - } - - /** - * Turns the pair into a string. - * - * @return Each value of the pair as a string joined with a colon. - */ - @Override - public String toString() { - return left.toString() + ":" + right.toString(); - } - - /** - * Gets the hash code of this pair. - */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((left == null) ? 0 : left.hashCode()); - result = prime * result + ((right == null) ? 0 : right.hashCode()); - return result; - } - - /** - * Checks to see if two pairs are equal. - */ - @SuppressWarnings("unchecked") - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final Pair other = (Pair) obj; - if (left == null) { - if (other.left != null) { - return false; - } - } else if (!left.equals(other.left)) { - return false; - } - if (right == null) { - if (other.right != null) { - return false; - } - } else if (!right.equals(other.right)) { - return false; - } - return true; - } -} \ No newline at end of file