diff --git a/tools/MapleCodeCouponGenerator/src/maplecodecoupongenerator/MapleCodeCouponGenerator.java b/src/main/java/tools/mapletools/CodeCouponGenerator.java
similarity index 64%
rename from tools/MapleCodeCouponGenerator/src/maplecodecoupongenerator/MapleCodeCouponGenerator.java
rename to src/main/java/tools/mapletools/CodeCouponGenerator.java
index 45e2abab35..0539cf4d17 100644
--- a/tools/MapleCodeCouponGenerator/src/maplecodecoupongenerator/MapleCodeCouponGenerator.java
+++ b/src/main/java/tools/mapletools/CodeCouponGenerator.java
@@ -1,79 +1,46 @@
-/*
- 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 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 maplecodecoupongenerator;
-
-import java.io.BufferedReader;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.sql.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
/**
- *
* @author RonanLana
-
- This application parses the coupon descriptor XML file and automatically generates
- code entries on the DB reflecting the descriptions found. Parse time relies on the
- sum of coupon codes created and amount of current codes on DB.
-
- Estimated parse time: 2 minutes (for 100 code entries)
+ *
+ * This application parses the coupon descriptor XML file and automatically generates
+ * code entries on the DB reflecting the descriptions found. Parse time relies on the
+ * sum of coupon codes created and amount of current codes on DB.
+ *
+ * Estimated parse time: 2 minutes (for 100 code entries)
*/
-public class MapleCodeCouponGenerator {
- static String host = "jdbc:mysql://localhost:3306/cosmic";
- static String driver = "com.mysql.jdbc.Driver";
- static String username = "cosmic_server";
- static String password = "snailshell";
-
- static Connection con = null;
- static InputStreamReader fileReader = null;
- static BufferedReader bufferedReader = null;
-
- static String fileName = "lib/CouponCodes.img.xml";
- static long currentTime;
-
- static int initialStringLength = 250;
-
- static String name;
- static boolean active;
- static int quantity, duration;
- static int maplePoint, nxCredit, nxPrepaid;
-
- static List> itemList = new ArrayList<>();
- static Pair item;
-
-
- static List activeCoupons = new ArrayList<>();
- static List generatedKeys;
- static Set usedCodes = new HashSet<>();
-
- static byte status;
-
+public class CodeCouponGenerator {
+ private static final File INPUT_FILE = ToolConstants.getInputFile("CouponCodes.img.xml");
+ private static final int INITIAL_STRING_LENGTH = 250;
+ private static final Connection con = SimpleDatabaseConnection.getConnection();
+
+ private static final List activeCoupons = new ArrayList<>();
+ private static final Set usedCodes = new HashSet<>();
+ private static final List> itemList = new ArrayList<>();
+
+ private static BufferedReader bufferedReader = null;
+ private static long currentTime;
+ private static String name;
+ private static boolean active;
+ private static int quantity;
+ private static int duration;
+ private static int maplePoint;
+ private static int nxCredit;
+ private static int nxPrepaid;
+ private static Pair item;
+ private static List generatedKeys;
+ private static byte status;
+
private static void resetCouponPackage() {
name = null;
active = false;
@@ -84,17 +51,17 @@ public class MapleCodeCouponGenerator {
nxPrepaid = 0;
itemList.clear();
}
-
+
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
- dest = new char[initialStringLength];
+ dest = new char[INITIAL_STRING_LENGTH];
try {
token.getChars(i, j, dest, 0);
} catch (StringIndexOutOfBoundsException e) {
@@ -105,14 +72,13 @@ public class MapleCodeCouponGenerator {
e.printStackTrace();
try {
Thread.sleep(100000000);
- } catch (Exception ex) {}
+ } catch (Exception ex) {
+ }
}
-
- d = new String(dest);
- return(d.trim());
+ return new String(dest).trim();
}
-
+
private static String getValue(String token) {
int i, j;
char[] dest;
@@ -122,68 +88,64 @@ public class MapleCodeCouponGenerator {
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 translateToken(String token) {
- if(token.contains("/imgdir")) {
+ if (token.contains("/imgdir")) {
status -= 1;
-
+
if (status == 1) {
if (active) {
activeCoupons.add(new CodeCouponDescriptor(name, quantity, duration, maplePoint, nxCredit, nxPrepaid, itemList));
}
-
+
resetCouponPackage();
} else if (status == 3) {
itemList.add(item);
}
- }
- else if(token.contains("imgdir")) {
+ } else if (token.contains("imgdir")) {
status += 1;
-
+
if (status == 4) {
item = new Pair<>(-1, -1);
} else if (status == 2) {
String d = getName(token);
-
+
System.out.println(" Reading coupon '" + d + "'");
name = d;
}
- }
- else {
+ } else {
String d = getName(token);
-
+
if (status == 2) {
switch (d) {
case "active":
- if (Integer.valueOf(getValue(token)) == 0) {
+ if (Integer.parseInt(getValue(token)) == 0) {
forwardCursor(status);
resetCouponPackage();
} else {
@@ -192,19 +154,19 @@ public class MapleCodeCouponGenerator {
break;
case "quantity":
- quantity = Integer.valueOf(getValue(token));
+ quantity = Integer.parseInt(getValue(token));
break;
case "duration":
- duration = Integer.valueOf(getValue(token));
+ duration = Integer.parseInt(getValue(token));
break;
case "maplePoint":
- maplePoint = Integer.valueOf(getValue(token));
+ maplePoint = Integer.parseInt(getValue(token));
break;
case "nxCredit":
- nxCredit = Integer.valueOf(getValue(token));
+ nxCredit = Integer.parseInt(getValue(token));
break;
case "nxPrepaid":
- nxPrepaid = Integer.valueOf(getValue(token));
+ nxPrepaid = Integer.parseInt(getValue(token));
break;
}
} else if (status == 4) {
@@ -219,13 +181,13 @@ public class MapleCodeCouponGenerator {
}
}
}
-
+
private static class CodeCouponDescriptor {
protected String name;
protected int quantity, duration;
protected int nxCredit, maplePoint, nxPrepaid;
protected List> itemList;
-
+
protected CodeCouponDescriptor(String name, int quantity, int duration, int maplePoint, int nxCredit, int nxPrepaid, List> itemList) {
this.name = name;
this.quantity = quantity;
@@ -233,109 +195,111 @@ public class MapleCodeCouponGenerator {
this.maplePoint = maplePoint;
this.nxCredit = nxCredit;
this.nxPrepaid = nxPrepaid;
-
+
this.itemList = new ArrayList<>(itemList);
}
}
-
+
private static String randomizeCouponCode() {
return Long.toHexString(Double.doubleToLongBits(Math.random())).substring(0, 15);
}
-
+
private static String generateCouponCode() {
String newCode;
do {
newCode = randomizeCouponCode();
} while (usedCodes.contains(newCode));
-
+
usedCodes.add(newCode);
return newCode;
}
-
+
private static List getGeneratedKeys(PreparedStatement ps) throws SQLException {
if (generatedKeys == null) {
generatedKeys = new ArrayList<>();
-
+
ResultSet rs = ps.getGeneratedKeys();
while (rs.next()) {
generatedKeys.add(rs.getInt(1));
}
rs.close();
}
-
+
return generatedKeys;
}
-
+
private static void commitCodeCouponDescription(CodeCouponDescriptor recipe) throws SQLException {
- if (recipe.quantity < 1) return;
-
+ if (recipe.quantity < 1) {
+ return;
+ }
+
System.out.println(" Generating coupon '" + recipe.name + "'");
generatedKeys = null;
-
+
PreparedStatement ps = con.prepareStatement("INSERT IGNORE INTO `nxcode` (`code`, `expiration`) VALUES (?, ?)", Statement.RETURN_GENERATED_KEYS);
ps.setLong(2, currentTime + ((long) recipe.duration * 60 * 60 * 1000));
-
- for(int i = 0; i < recipe.quantity; i++) {
+
+ for (int i = 0; i < recipe.quantity; i++) {
ps.setString(1, generateCouponCode());
ps.addBatch();
}
ps.executeBatch();
-
+
PreparedStatement ps2 = con.prepareStatement("INSERT IGNORE INTO `nxcode_items` (`codeid`, `type`, `item`, `quantity`) VALUES (?, ?, ?, ?)");
if (!recipe.itemList.isEmpty()) {
ps2.setInt(2, 5);
List keys = getGeneratedKeys(ps);
-
+
for (Pair p : recipe.itemList) {
ps2.setInt(3, p.getLeft());
ps2.setInt(4, p.getRight());
-
+
for (Integer codeid : keys) {
ps2.setInt(1, codeid);
ps2.addBatch();
}
}
}
-
+
ps2.setInt(3, 0);
if (recipe.nxCredit > 0) {
ps2.setInt(2, 0);
ps2.setInt(4, recipe.nxCredit);
List keys = getGeneratedKeys(ps);
-
- for(Integer codeid : keys) {
+
+ for (Integer codeid : keys) {
ps2.setInt(1, codeid);
ps2.addBatch();
}
}
-
+
if (recipe.maplePoint > 0) {
ps2.setInt(2, 1);
ps2.setInt(4, recipe.maplePoint);
List keys = getGeneratedKeys(ps);
-
- for(Integer codeid : keys) {
+
+ for (Integer codeid : keys) {
ps2.setInt(1, codeid);
ps2.addBatch();
}
}
-
+
if (recipe.nxPrepaid > 0) {
ps2.setInt(2, 2);
ps2.setInt(4, recipe.nxPrepaid);
List keys = getGeneratedKeys(ps);
-
- for(Integer codeid : keys) {
+
+ for (Integer codeid : keys) {
ps2.setInt(1, codeid);
ps2.addBatch();
}
}
-
+
ps2.executeBatch();
ps2.close();
ps.close();
}
-
+
private static void loadUsedCouponCodes() throws SQLException {
PreparedStatement ps = con.prepareStatement("SELECT code FROM nxcode", Statement.RETURN_GENERATED_KEYS);
ResultSet rs = ps.executeQuery();
@@ -345,51 +309,48 @@ public class MapleCodeCouponGenerator {
rs.close();
ps.close();
}
-
- private static void generateCodeCoupons(String fileName) throws IOException {
- fileReader = new InputStreamReader(new FileInputStream(fileName), "UTF-8");
+
+ private static void generateCodeCoupons(File file) throws IOException {
+ InputStreamReader fileReader = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8);
bufferedReader = new BufferedReader(fileReader);
-
+
resetCouponPackage();
status = 0;
-
+
System.out.println("Reading XML coupon information...");
String line;
- while((line = bufferedReader.readLine()) != null) {
+ while ((line = bufferedReader.readLine()) != null) {
translateToken(line);
}
bufferedReader.close();
fileReader.close();
System.out.println();
-
+
try {
- Class.forName(driver).newInstance();
- con = DriverManager.getConnection(host, username, password);
-
System.out.println("Loading DB coupon codes...");
loadUsedCouponCodes();
System.out.println();
-
+
System.out.println("Saving generated coupons...");
currentTime = System.currentTimeMillis();
for (CodeCouponDescriptor ccd : activeCoupons) {
commitCodeCouponDescription(ccd);
}
System.out.println();
-
+
con.close();
System.out.println("Done.");
- } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | SQLException e) {
+ } catch (SQLException e) {
e.printStackTrace();
}
}
-
+
public static void main(String[] args) {
try {
- generateCodeCoupons(fileName);
- } catch(IOException ex) {
- System.out.println("Error reading file '" + fileName + "'");
+ generateCodeCoupons(INPUT_FILE);
+ } catch (IOException ex) {
+ System.out.println("Error reading file '" + INPUT_FILE.getAbsolutePath() + "'");
}
}
}
diff --git a/tools/MapleCodeCouponGenerator/src/maplecodecoupongenerator/Pair.java b/tools/MapleCodeCouponGenerator/src/maplecodecoupongenerator/Pair.java
deleted file mode 100644
index b0bcdf2411..0000000000
--- a/tools/MapleCodeCouponGenerator/src/maplecodecoupongenerator/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 maplecodecoupongenerator;
-
-/**
- * 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
diff --git a/tools/input/.gitignore b/tools/input/.gitignore
index 9e88c6e0f0..ff456c3654 100644
--- a/tools/input/.gitignore
+++ b/tools/input/.gitignore
@@ -1,4 +1,5 @@
*
!*/
!/cosmetics/**
-!.gitignore
\ No newline at end of file
+!.gitignore
+!CouponCodes.img.xml
\ No newline at end of file
diff --git a/tools/MapleCodeCouponGenerator/lib/CouponCodes.img.xml b/tools/input/CouponCodes.img.xml
similarity index 53%
rename from tools/MapleCodeCouponGenerator/lib/CouponCodes.img.xml
rename to tools/input/CouponCodes.img.xml
index 9fccae135f..8ce30f6212 100644
--- a/tools/MapleCodeCouponGenerator/lib/CouponCodes.img.xml
+++ b/tools/input/CouponCodes.img.xml
@@ -4,17 +4,17 @@
-
-
-
+
+
+
-
-
+
+
-
-
+
+
@@ -22,17 +22,17 @@
-
-
-
+
+
+
-
-
+
+
-
-
+
+