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