Move MapleCashCosmeticsChecker to main module
This commit is contained in:
1 parent
fdd2ef7b3a
commit
da66e7614d
27 files changed
+94
-439
No files matched your search
@@ -21,15 +21,15 @@ public enum WZFiles {
|
|||||||
|
|
||||||
private final String fileName;
|
private final String fileName;
|
||||||
|
|
||||||
WZFiles(String fileName) {
|
WZFiles(String name) {
|
||||||
this.fileName = fileName;
|
this.fileName = name + ".wz";
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getFile() {
|
public File getFile() {
|
||||||
return new File(getFilePath());
|
return new File(DIRECTORY, fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFilePath() {
|
public String getFilePath() {
|
||||||
return String.format("%s/%s.wz", DIRECTORY, fileName);
|
return getFile().getPath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+84
-101
@@ -1,76 +1,50 @@
|
|||||||
/*
|
package tools.mapletools;
|
||||||
This file is part of the HeavenMS MapleStory Server
|
|
||||||
Copyleft (L) 2016 - 2019 RonanLana
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
import provider.wz.WZFiles;
|
||||||
it under the terms of the GNU Affero General Public License as
|
import tools.Pair;
|
||||||
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.
|
|
||||||
|
|
||||||
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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package maplecashcosmeticschecker;
|
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author RonanLana
|
* @author RonanLana
|
||||||
|
* <p>
|
||||||
This application parses the cosmetic recipes defined within "lib/care" folder, loads
|
* This application parses the cosmetic recipes defined within "lib/care" folder, loads
|
||||||
every present cosmetic itemid from the XML data, then checks the scripts for missed
|
* every present cosmetic itemid from the XML data, then checks the scripts for missed
|
||||||
cosmetics within the stylist/surgeon. Results from the search are reported in a report
|
* cosmetics within the stylist/surgeon. Results from the search are reported in a report
|
||||||
file.
|
* file.
|
||||||
|
* <p>
|
||||||
Note: to best make use of this feature, set ignoreCurrentScriptCosmetics = true. This
|
* Note: to best make use of this feature, set IGNORE_CURRENT_SCRIPT_COSMETICS = true. This
|
||||||
way, every available cosmetic present on the recipes will be listed on the report.
|
* way, every available cosmetic present on the recipes will be listed on the report.
|
||||||
|
* <p>
|
||||||
Estimated parse time: 1 minute
|
* Estimated parse time: 1 minute
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public class MapleCashCosmeticsChecker {
|
public class CashCosmeticsChecker {
|
||||||
static String libPath = "lib";
|
private static final String HANDBOOK_PATH = "handbook";
|
||||||
static String handbookPath = "../../handbook";
|
private static final String SCRIPTS_PATH = "scripts";
|
||||||
static String wzPath = "../../wz";
|
private static final String INPUT_DIRECTORY_PATH = ToolConstants.getInputFile("care").getPath();
|
||||||
static String scriptPath = "../../scripts";
|
private static final File OUTPUT_FILE = ToolConstants.getOutputFile("cash_cosmetics_result.txt");
|
||||||
|
private static final boolean IGNORE_CURRENT_SCRIPT_COSMETICS = false; // Toggle to preference
|
||||||
|
private static final int INITIAL_STRING_LENGTH = 50;
|
||||||
|
|
||||||
static PrintWriter printWriter = null;
|
private static final Map<Integer, Set<Integer>> scriptCosmetics = new HashMap<>();
|
||||||
static InputStreamReader fileReader = null;
|
private static final Map<Integer, String> scriptEntries = new HashMap<>(500);
|
||||||
static BufferedReader bufferedReader = null;
|
private static final Set<Integer> allCosmetics = new HashSet<>();
|
||||||
|
private static final Set<Integer> unusedCosmetics = new HashSet<>();
|
||||||
|
private static final Map<Integer, List<Integer>> usedCosmetics = new HashMap<>();
|
||||||
|
private static final Map<Integer, String> couponNames = new HashMap<>();
|
||||||
|
private static final Map<Integer, Integer> cosmeticNpcs = new HashMap<>(); // expected only 1 NPC per cosmetic coupon (town care/salon)
|
||||||
|
private static final Map<List<String>, Integer> cosmeticNpcids = new HashMap<>();
|
||||||
|
private static final Set<String> missingCosmeticNames = new HashSet<>();
|
||||||
|
private static final Map<String, Integer> cosmeticNameIds = new HashMap<>();
|
||||||
|
private static final Map<Integer, String> cosmeticIdNames = new HashMap<>();
|
||||||
|
private static final Map<Pair<Integer, String>, Set<Integer>> missingCosmeticsNpcTypes = new HashMap<>();
|
||||||
|
|
||||||
static boolean ignoreCurrentScriptCosmetics = false;
|
private static PrintWriter printWriter = null;
|
||||||
|
private static InputStreamReader fileReader = null;
|
||||||
static int initialStringLength = 50;
|
private static BufferedReader bufferedReader = null;
|
||||||
|
private static byte status = 0;
|
||||||
static byte status = 0;
|
|
||||||
|
|
||||||
static Map<Integer, Set<Integer>> scriptCosmetics = new HashMap<>();
|
|
||||||
static Map<Integer, String> scriptEntries = new HashMap<>(500);
|
|
||||||
|
|
||||||
static Set<Integer> allCosmetics = new HashSet<>();
|
|
||||||
|
|
||||||
static Set<Integer> unusedCosmetics = new HashSet<>();
|
|
||||||
static Map<Integer, List<Integer>> usedCosmetics = new HashMap<>();
|
|
||||||
|
|
||||||
static Map<Integer, String> couponNames = new HashMap<>();
|
|
||||||
static Map<Integer, Integer> cosmeticNpcs = new HashMap<>(); // expected only 1 NPC per cosmetic coupon (town care/salon)
|
|
||||||
static Map<List<String>, Integer> cosmeticNpcids = new HashMap<>();
|
|
||||||
|
|
||||||
static Set<String> missingCosmeticNames = new HashSet<>();
|
|
||||||
static Map<String, Integer> cosmeticNameIds = new HashMap<>();
|
|
||||||
static Map<Integer, String> cosmeticIdNames = new HashMap<>();
|
|
||||||
|
|
||||||
static Map<Pair<Integer, String>, Set<Integer>> missingCosmeticsNpcTypes = new HashMap<>();
|
|
||||||
|
|
||||||
private static String getName(String token) {
|
private static String getName(String token) {
|
||||||
int i, j;
|
int i, j;
|
||||||
@@ -81,7 +55,7 @@ public class MapleCashCosmeticsChecker {
|
|||||||
i = token.indexOf("\"", i) + 1; //lower bound of the string
|
i = token.indexOf("\"", i) + 1; //lower bound of the string
|
||||||
j = token.indexOf("\"", i); //upper bound
|
j = token.indexOf("\"", i); //upper bound
|
||||||
|
|
||||||
dest = new char[initialStringLength];
|
dest = new char[INITIAL_STRING_LENGTH];
|
||||||
token.getChars(i, j, dest, 0);
|
token.getChars(i, j, dest, 0);
|
||||||
|
|
||||||
d = new String(dest);
|
d = new String(dest);
|
||||||
@@ -97,7 +71,7 @@ public class MapleCashCosmeticsChecker {
|
|||||||
i = token.indexOf("\"", i) + 1; //lower bound of the string
|
i = token.indexOf("\"", i) + 1; //lower bound of the string
|
||||||
j = token.indexOf("\"", i); //upper bound
|
j = token.indexOf("\"", i); //upper bound
|
||||||
|
|
||||||
dest = new char[initialStringLength];
|
dest = new char[INITIAL_STRING_LENGTH];
|
||||||
token.getChars(i, j, dest, 0);
|
token.getChars(i, j, dest, 0);
|
||||||
|
|
||||||
d = new String(dest);
|
d = new String(dest);
|
||||||
@@ -111,8 +85,7 @@ public class MapleCashCosmeticsChecker {
|
|||||||
while (status >= st && (line = bufferedReader.readLine()) != null) {
|
while (status >= st && (line = bufferedReader.readLine()) != null) {
|
||||||
simpleToken(line);
|
simpleToken(line);
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch(Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,8 +93,7 @@ public class MapleCashCosmeticsChecker {
|
|||||||
private static void simpleToken(String token) {
|
private static void simpleToken(String token) {
|
||||||
if (token.contains("/imgdir")) {
|
if (token.contains("/imgdir")) {
|
||||||
status -= 1;
|
status -= 1;
|
||||||
}
|
} else if (token.contains("imgdir")) {
|
||||||
else if(token.contains("imgdir")) {
|
|
||||||
status += 1;
|
status += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,8 +101,7 @@ public class MapleCashCosmeticsChecker {
|
|||||||
private static void translateToken(String token) {
|
private static void translateToken(String token) {
|
||||||
if (token.contains("/imgdir")) {
|
if (token.contains("/imgdir")) {
|
||||||
status -= 1;
|
status -= 1;
|
||||||
}
|
} else if (token.contains("imgdir")) {
|
||||||
else if(token.contains("imgdir")) {
|
|
||||||
status += 1;
|
status += 1;
|
||||||
|
|
||||||
if (status == 3) {
|
if (status == 3) {
|
||||||
@@ -141,7 +112,7 @@ public class MapleCashCosmeticsChecker {
|
|||||||
}
|
}
|
||||||
} else if (status == 4) {
|
} else if (status == 4) {
|
||||||
String d = getName(token);
|
String d = getName(token);
|
||||||
int itemid = Integer.valueOf(d);
|
int itemid = Integer.parseInt(d);
|
||||||
|
|
||||||
int cosmeticid;
|
int cosmeticid;
|
||||||
if (itemid >= 30000) {
|
if (itemid >= 30000) {
|
||||||
@@ -159,7 +130,7 @@ public class MapleCashCosmeticsChecker {
|
|||||||
private static void readEqpStringData(String eqpStringDirectory) throws IOException {
|
private static void readEqpStringData(String eqpStringDirectory) throws IOException {
|
||||||
String line;
|
String line;
|
||||||
|
|
||||||
fileReader = new InputStreamReader(new FileInputStream(eqpStringDirectory), "UTF-8");
|
fileReader = new InputStreamReader(new FileInputStream(eqpStringDirectory), StandardCharsets.UTF_8);
|
||||||
bufferedReader = new BufferedReader(fileReader);
|
bufferedReader = new BufferedReader(fileReader);
|
||||||
|
|
||||||
while ((line = bufferedReader.readLine()) != null) {
|
while ((line = bufferedReader.readLine()) != null) {
|
||||||
@@ -172,7 +143,7 @@ public class MapleCashCosmeticsChecker {
|
|||||||
|
|
||||||
private static void loadCosmeticWzData() throws IOException {
|
private static void loadCosmeticWzData() throws IOException {
|
||||||
System.out.println("Reading String.wz ...");
|
System.out.println("Reading String.wz ...");
|
||||||
readEqpStringData(wzPath + "/String.wz/Eqp.img.xml");
|
readEqpStringData(WZFiles.STRING.getFilePath() + "/Eqp.img.xml");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setCosmeticUsage(List<Integer> usedByNpcids, int cosmeticid) {
|
private static void setCosmeticUsage(List<Integer> usedByNpcids, int cosmeticid) {
|
||||||
@@ -199,7 +170,7 @@ public class MapleCashCosmeticsChecker {
|
|||||||
|
|
||||||
private static int getNpcIdFromFilename(String name) {
|
private static int getNpcIdFromFilename(String name) {
|
||||||
try {
|
try {
|
||||||
return Integer.valueOf(name.substring(0, name.indexOf('.')));
|
return Integer.parseInt(name.substring(0, name.indexOf('.')));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -207,7 +178,7 @@ public class MapleCashCosmeticsChecker {
|
|||||||
|
|
||||||
private static List<Integer> findCosmeticDataNpcids(int itemid) {
|
private static List<Integer> findCosmeticDataNpcids(int itemid) {
|
||||||
List<Integer> npcids = new LinkedList<>();
|
List<Integer> npcids = new LinkedList<>();
|
||||||
for (Entry<Integer, Set<Integer>> sc : scriptCosmetics.entrySet()) {
|
for (Map.Entry<Integer, Set<Integer>> sc : scriptCosmetics.entrySet()) {
|
||||||
if (sc.getValue().contains(itemid)) {
|
if (sc.getValue().contains(itemid)) {
|
||||||
npcids.add(itemid);
|
npcids.add(itemid);
|
||||||
}
|
}
|
||||||
@@ -218,13 +189,13 @@ public class MapleCashCosmeticsChecker {
|
|||||||
|
|
||||||
private static void loadScripts() throws IOException {
|
private static void loadScripts() throws IOException {
|
||||||
ArrayList<File> files = new ArrayList<>();
|
ArrayList<File> files = new ArrayList<>();
|
||||||
listFiles(scriptPath + "/npc", files);
|
listFiles(SCRIPTS_PATH + "/npc", files);
|
||||||
|
|
||||||
for (File f : files) {
|
for (File f : files) {
|
||||||
Integer npcid = getNpcIdFromFilename(f.getName());
|
Integer npcid = getNpcIdFromFilename(f.getName());
|
||||||
|
|
||||||
//System.out.println("Parsing " + f.getAbsolutePath());
|
//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);
|
bufferedReader = new BufferedReader(fileReader);
|
||||||
|
|
||||||
String line;
|
String line;
|
||||||
@@ -243,7 +214,7 @@ public class MapleCashCosmeticsChecker {
|
|||||||
|
|
||||||
for (String st : s) {
|
for (String st : s) {
|
||||||
if (!st.isEmpty()) {
|
if (!st.isEmpty()) {
|
||||||
int itemid = Integer.valueOf(st);
|
int itemid = Integer.parseInt(st);
|
||||||
cosmeticids.add(itemid);
|
cosmeticids.add(itemid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -257,7 +228,7 @@ public class MapleCashCosmeticsChecker {
|
|||||||
|
|
||||||
for (String st : s) {
|
for (String st : s) {
|
||||||
if (!st.isEmpty()) {
|
if (!st.isEmpty()) {
|
||||||
int itemid = Integer.valueOf(st);
|
int itemid = Integer.parseInt(st);
|
||||||
cosmeticids.add(itemid);
|
cosmeticids.add(itemid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -282,7 +253,7 @@ public class MapleCashCosmeticsChecker {
|
|||||||
System.out.println("Reading script files ...");
|
System.out.println("Reading script files ...");
|
||||||
loadScripts();
|
loadScripts();
|
||||||
|
|
||||||
if (ignoreCurrentScriptCosmetics) {
|
if (IGNORE_CURRENT_SCRIPT_COSMETICS) {
|
||||||
for (Set<Integer> npcCosmetics : scriptCosmetics.values()) {
|
for (Set<Integer> npcCosmetics : scriptCosmetics.values()) {
|
||||||
npcCosmetics.clear();
|
npcCosmetics.clear();
|
||||||
}
|
}
|
||||||
@@ -297,15 +268,17 @@ public class MapleCashCosmeticsChecker {
|
|||||||
private static List<Integer> loadCosmeticCouponids() throws IOException {
|
private static List<Integer> loadCosmeticCouponids() throws IOException {
|
||||||
List<Integer> couponItemids = new LinkedList<>();
|
List<Integer> couponItemids = new LinkedList<>();
|
||||||
|
|
||||||
fileReader = new InputStreamReader(new FileInputStream(handbookPath + "/Cash.txt"), "UTF-8");
|
fileReader = new InputStreamReader(new FileInputStream(getHandbookFileName("/Cash.txt")), StandardCharsets.UTF_8);
|
||||||
bufferedReader = new BufferedReader(fileReader);
|
bufferedReader = new BufferedReader(fileReader);
|
||||||
|
|
||||||
String line;
|
String line;
|
||||||
while ((line = bufferedReader.readLine()) != null) {
|
while ((line = bufferedReader.readLine()) != null) {
|
||||||
if (line.isEmpty()) continue;
|
if (line.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
String[] s = line.split(" - ", 3);
|
String[] s = line.split(" - ", 3);
|
||||||
|
|
||||||
int itemid = Integer.valueOf(s[0]);
|
int itemid = Integer.parseInt(s[0]);
|
||||||
if (itemid >= 5150000 && itemid < 5160000) {
|
if (itemid >= 5150000 && itemid < 5160000) {
|
||||||
couponItemids.add(itemid);
|
couponItemids.add(itemid);
|
||||||
couponNames.put(itemid, s[1]);
|
couponNames.put(itemid, s[1]);
|
||||||
@@ -322,7 +295,7 @@ public class MapleCashCosmeticsChecker {
|
|||||||
List<Integer> files = new LinkedList<>();
|
List<Integer> files = new LinkedList<>();
|
||||||
String t = String.valueOf(itemid);
|
String t = String.valueOf(itemid);
|
||||||
|
|
||||||
for (Entry<Integer, String> text : scriptEntries.entrySet()) {
|
for (Map.Entry<Integer, String> text : scriptEntries.entrySet()) {
|
||||||
if (text.getValue().contains(t)) {
|
if (text.getValue().contains(t)) {
|
||||||
files.add(text.getKey());
|
files.add(text.getKey());
|
||||||
}
|
}
|
||||||
@@ -401,7 +374,9 @@ public class MapleCashCosmeticsChecker {
|
|||||||
|
|
||||||
String[] tokens = s[0].split(" ");
|
String[] tokens = s[0].split(" ");
|
||||||
Pair<Integer, CosmeticType> cosmeticData = parseCosmeticCoupon(tokens);
|
Pair<Integer, CosmeticType> cosmeticData = parseCosmeticCoupon(tokens);
|
||||||
if (cosmeticData == null) return null;
|
if (cosmeticData == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
town = "";
|
town = "";
|
||||||
for (int i = 0; i < cosmeticData.left; i++) {
|
for (int i = 0; i < cosmeticData.left; i++) {
|
||||||
@@ -426,14 +401,18 @@ public class MapleCashCosmeticsChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void generateCosmeticPlaceNpcs() {
|
private static void generateCosmeticPlaceNpcs() {
|
||||||
for (Entry<Integer, String> e : couponNames.entrySet()) {
|
for (Map.Entry<Integer, String> e : couponNames.entrySet()) {
|
||||||
Integer npcid = cosmeticNpcs.get(e.getKey());
|
Integer npcid = cosmeticNpcs.get(e.getKey());
|
||||||
if (npcid == null) continue;
|
if (npcid == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
String couponName = e.getValue();
|
String couponName = e.getValue();
|
||||||
List<String> couponData = parseCosmeticCoupon(couponName);
|
List<String> couponData = parseCosmeticCoupon(couponName);
|
||||||
|
|
||||||
if (couponData == null) continue;
|
if (couponData == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
cosmeticNpcids.put(couponData, npcid);
|
cosmeticNpcids.put(couponData, npcid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -443,18 +422,18 @@ public class MapleCashCosmeticsChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static String getCosmeticName(String name, boolean gender) {
|
private static String getCosmeticName(String name, boolean gender) {
|
||||||
String ret = name + " (" + (gender ? "F" : "M") + ")";
|
final String genderString = gender ? "F" : "M";
|
||||||
return ret;
|
return String.format("%s (%s)", name, genderString);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadCosmeticNames(String cosmeticPath) throws IOException {
|
private static void loadCosmeticNames(String cosmeticPath) throws IOException {
|
||||||
fileReader = new InputStreamReader(new FileInputStream(cosmeticPath), "UTF-8");
|
fileReader = new InputStreamReader(new FileInputStream(cosmeticPath), StandardCharsets.UTF_8);
|
||||||
bufferedReader = new BufferedReader(fileReader);
|
bufferedReader = new BufferedReader(fileReader);
|
||||||
|
|
||||||
String line;
|
String line;
|
||||||
while ((line = bufferedReader.readLine()) != null) {
|
while ((line = bufferedReader.readLine()) != null) {
|
||||||
String[] s = line.split(" - ", 3);
|
String[] s = line.split(" - ", 3);
|
||||||
int itemid = Integer.valueOf(s[0]);
|
int itemid = Integer.parseInt(s[0]);
|
||||||
|
|
||||||
String name;
|
String name;
|
||||||
if (itemid < 30000) {
|
if (itemid < 30000) {
|
||||||
@@ -498,8 +477,12 @@ public class MapleCashCosmeticsChecker {
|
|||||||
private static void loadCosmeticNames() throws IOException {
|
private static void loadCosmeticNames() throws IOException {
|
||||||
System.out.println("Reading cosmetics from handbook ...");
|
System.out.println("Reading cosmetics from handbook ...");
|
||||||
|
|
||||||
loadCosmeticNames(handbookPath + "/Equip/Face.txt");
|
loadCosmeticNames(getHandbookFileName("/Equip/Face.txt"));
|
||||||
loadCosmeticNames(handbookPath + "/Equip/Hair.txt");
|
loadCosmeticNames(getHandbookFileName("/Equip/Hair.txt"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getHandbookFileName(String fileName) {
|
||||||
|
return HANDBOOK_PATH + fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Integer> fetchExpectedCosmetics(String[] cosmeticList, boolean gender) {
|
private static List<Integer> fetchExpectedCosmetics(String[] cosmeticList, boolean gender) {
|
||||||
@@ -522,7 +505,7 @@ public class MapleCashCosmeticsChecker {
|
|||||||
String townName = f.getParent().substring(f.getParent().lastIndexOf("\\") + 1);
|
String townName = f.getParent().substring(f.getParent().lastIndexOf("\\") + 1);
|
||||||
String typeCosmetic = f.getName().substring(0, f.getName().indexOf("."));
|
String typeCosmetic = f.getName().substring(0, f.getName().indexOf("."));
|
||||||
|
|
||||||
fileReader = new InputStreamReader(new FileInputStream(f), "UTF-8");
|
fileReader = new InputStreamReader(new FileInputStream(f), StandardCharsets.UTF_8);
|
||||||
bufferedReader = new BufferedReader(fileReader);
|
bufferedReader = new BufferedReader(fileReader);
|
||||||
|
|
||||||
String line;
|
String line;
|
||||||
@@ -567,7 +550,7 @@ public class MapleCashCosmeticsChecker {
|
|||||||
System.out.println("Analyzing cosmetic NPC scripts ...");
|
System.out.println("Analyzing cosmetic NPC scripts ...");
|
||||||
|
|
||||||
ArrayList<File> cosmeticRecipes = new ArrayList<>();
|
ArrayList<File> cosmeticRecipes = new ArrayList<>();
|
||||||
listFiles(libPath + "/care", cosmeticRecipes);
|
listFiles(INPUT_DIRECTORY_PATH, cosmeticRecipes);
|
||||||
|
|
||||||
for (File f : cosmeticRecipes) {
|
for (File f : cosmeticRecipes) {
|
||||||
verifyCosmeticExpectedFile(f);
|
verifyCosmeticExpectedFile(f);
|
||||||
@@ -576,16 +559,16 @@ public class MapleCashCosmeticsChecker {
|
|||||||
|
|
||||||
private static List<Pair<Pair<Integer, String>, List<Integer>>> getSortedMapEntries(Map<Pair<Integer, String>, Set<Integer>> map) {
|
private static List<Pair<Pair<Integer, String>, List<Integer>>> getSortedMapEntries(Map<Pair<Integer, String>, Set<Integer>> map) {
|
||||||
List<Pair<Pair<Integer, String>, List<Integer>>> list = new ArrayList<>(map.size());
|
List<Pair<Pair<Integer, String>, List<Integer>>> list = new ArrayList<>(map.size());
|
||||||
for(Entry<Pair<Integer, String>, Set<Integer>> e : map.entrySet()) {
|
for (Map.Entry<Pair<Integer, String>, Set<Integer>> e : map.entrySet()) {
|
||||||
List<Integer> il = new ArrayList<>(2);
|
List<Integer> il = new ArrayList<>(2);
|
||||||
il.addAll(e.getValue());
|
il.addAll(e.getValue());
|
||||||
|
|
||||||
Collections.sort(il, (o1, o2) -> o1 - o2);
|
il.sort((o1, o2) -> o1 - o2);
|
||||||
|
|
||||||
list.add(new Pair<>(e.getKey(), il));
|
list.add(new Pair<>(e.getKey(), il));
|
||||||
}
|
}
|
||||||
|
|
||||||
Collections.sort(list, (o1, o2) -> {
|
list.sort((o1, o2) -> {
|
||||||
int cmp = o1.getLeft().getLeft() - o2.getLeft().getLeft();
|
int cmp = o1.getLeft().getLeft() - o2.getLeft().getLeft();
|
||||||
if (cmp == 0) {
|
if (cmp == 0) {
|
||||||
return o1.getLeft().getRight().compareTo(o2.getLeft().getRight());
|
return o1.getLeft().getRight().compareTo(o2.getLeft().getRight());
|
||||||
@@ -633,7 +616,7 @@ public class MapleCashCosmeticsChecker {
|
|||||||
private static void reportCosmeticResults() throws IOException {
|
private static void reportCosmeticResults() throws IOException {
|
||||||
System.out.println("Reporting results ...");
|
System.out.println("Reporting results ...");
|
||||||
|
|
||||||
printWriter = new PrintWriter("lib/result.txt", "UTF-8");
|
printWriter = new PrintWriter(OUTPUT_FILE, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
printReportFileHeader();
|
printReportFileHeader();
|
||||||
|
|
||||||
@@ -6,6 +6,10 @@ public class ToolConstants {
|
|||||||
public static final File INPUT_DIRECTORY = new File("tools/input");
|
public static final File INPUT_DIRECTORY = new File("tools/input");
|
||||||
public static final File OUTPUT_DIRECTORY = new File("tools/output");
|
public static final File OUTPUT_DIRECTORY = new File("tools/output");
|
||||||
|
|
||||||
|
public static File getInputFile(String fileName) {
|
||||||
|
return new File(INPUT_DIRECTORY, fileName);
|
||||||
|
}
|
||||||
|
|
||||||
public static File getOutputFile(String fileName) {
|
public static File getOutputFile(String fileName) {
|
||||||
return new File(OUTPUT_DIRECTORY, fileName);
|
return new File(OUTPUT_DIRECTORY, fileName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,213 +0,0 @@
|
|||||||
# Report File autogenerated from the MapleCashCosmeticsChecker feature by Ronan Lana.
|
|
||||||
# Generated data takes into account several data info from the server source files and the server-side WZ.xmls.
|
|
||||||
|
|
||||||
Found 42 entries with missing cosmetic entries.
|
|
||||||
NPC 1012103:VIP
|
|
||||||
30060, 30140, 30200, 30210, 30310, 33040, 33100
|
|
||||||
31150, 31300, 31350, 31700, 31740, 34050, 34110
|
|
||||||
|
|
||||||
NPC 1012104:EXP
|
|
||||||
30030, 30140, 30200, 30210, 30310, 30610, 33040, 33100
|
|
||||||
31070, 31150, 31300, 31350, 31430, 31700, 34050, 34110
|
|
||||||
|
|
||||||
NPC 1012104:REG
|
|
||||||
30060, 30140, 30200, 30210, 30310, 30610, 33040, 33100
|
|
||||||
31070, 31080, 31150, 31300, 31350, 31700, 34050, 34110
|
|
||||||
|
|
||||||
NPC 1052004:VIP
|
|
||||||
20000, 20001, 20003, 20004, 20005, 20006, 20007, 20008, 20012, 20014, 20015, 20022, 20028, 20031
|
|
||||||
21000, 21001, 21002, 21003, 21004, 21005, 21006, 21007, 21008, 21012, 21013, 21014, 21023, 21026
|
|
||||||
|
|
||||||
NPC 1052005:REG
|
|
||||||
20000, 20005, 20008, 20012, 20016, 20022, 20032
|
|
||||||
21000, 21002, 21008, 21014, 21020, 21024, 21029
|
|
||||||
|
|
||||||
NPC 1052100:VIP
|
|
||||||
30040, 30130, 30780, 30850, 30860, 30920, 33040
|
|
||||||
31090, 31140, 31330, 31440, 31760, 31880, 34050
|
|
||||||
|
|
||||||
NPC 1052101:EXP
|
|
||||||
30130, 30430, 30520, 30770, 30780, 30850, 30920, 33040
|
|
||||||
31060, 31140, 31330, 31520, 31760, 31880, 34010, 34050
|
|
||||||
|
|
||||||
NPC 1052101:REG
|
|
||||||
30040, 30130, 30520, 30770, 30780, 30850, 30920, 33040
|
|
||||||
31060, 31140, 31330, 31440, 31520, 31750, 31760, 31880, 34050
|
|
||||||
|
|
||||||
NPC 2010001:VIP
|
|
||||||
30230, 30260, 30280, 30340, 30490
|
|
||||||
31110, 31220, 31230, 31630, 31790
|
|
||||||
|
|
||||||
NPC 2010002:VIP
|
|
||||||
20000, 20001, 20003, 20004, 20005, 20006, 20007, 20008, 20012, 20014, 20022, 20028, 20031
|
|
||||||
21000, 21001, 21002, 21003, 21004, 21005, 21006, 21007, 21008, 21012, 21014, 21023, 21026
|
|
||||||
|
|
||||||
NPC 2012007:EXP
|
|
||||||
30230, 30280, 30340, 30490, 30530, 30740
|
|
||||||
31110, 31220, 31230, 31710, 31790, 31890, 31930
|
|
||||||
|
|
||||||
NPC 2012007:REG
|
|
||||||
30230, 30260, 30280, 30340, 30490, 30530, 30630, 30740
|
|
||||||
31110, 31220, 31230, 31630, 31650, 31710, 31790, 31890, 31930
|
|
||||||
|
|
||||||
NPC 2012009:REG
|
|
||||||
20003, 20011, 20021, 20022, 20023, 20027, 20031
|
|
||||||
21004, 21007, 21010, 21012, 21020, 21021, 21030
|
|
||||||
|
|
||||||
NPC 2040019:REG
|
|
||||||
20001, 20003, 20007, 20013, 20021, 20023, 20025
|
|
||||||
21002, 21004, 21006, 21008, 21022, 21027, 21029
|
|
||||||
|
|
||||||
NPC 2041007:VIP
|
|
||||||
30160, 30190, 30250, 30640, 30660, 30840, 30870, 30990
|
|
||||||
31270, 31290, 31550, 31680, 31810, 31830, 31840, 31870
|
|
||||||
|
|
||||||
NPC 2041009:EXP
|
|
||||||
30030, 30190, 30220, 30250, 30540, 30610, 30620, 30640, 30650, 30660, 30840, 30990
|
|
||||||
31170, 31270, 31430, 31510, 31540, 31550, 31600, 31680, 31810, 31830, 31840, 31870
|
|
||||||
|
|
||||||
NPC 2041009:REG
|
|
||||||
30190, 30220, 30250, 30540, 30610, 30620, 30640, 30650, 30660, 30840, 30870, 30940, 30990
|
|
||||||
31170, 31270, 31290, 31510, 31540, 31550, 31600, 31640, 31680, 31810, 31830, 31840, 31870
|
|
||||||
|
|
||||||
NPC 2041010:VIP
|
|
||||||
20000, 20001, 20003, 20004, 20005, 20006, 20007, 20008, 20011, 20012, 20014, 20031
|
|
||||||
21000, 21001, 21002, 21003, 21004, 21005, 21006, 21007, 21008, 21010, 21012, 21014
|
|
||||||
|
|
||||||
NPC 2090100:VIP
|
|
||||||
30150, 30240, 30370, 30420, 30640, 30710, 30750, 30810
|
|
||||||
31140, 31160, 31180, 31300, 31460, 31470, 31660, 31910
|
|
||||||
|
|
||||||
NPC 2090101:EXP
|
|
||||||
30030, 30150, 30240, 30370, 30420, 30550, 30600, 30640, 30700, 30710, 30720, 30750, 30810, 30830
|
|
||||||
31140, 31160, 31180, 31210, 31300, 31430, 31460, 31470, 31660, 31690, 31800, 31890, 31910, 31940
|
|
||||||
|
|
||||||
NPC 2090104:REG
|
|
||||||
20002, 20005, 20007, 20011, 20014, 20017, 20029
|
|
||||||
21001, 21010, 21013, 21018, 21020, 21021, 21030
|
|
||||||
|
|
||||||
NPC 2090104:VIP
|
|
||||||
20000, 20001, 20004, 20005, 20006, 20007, 20009, 20012, 20022, 20028, 20031
|
|
||||||
21000, 21003, 21005, 21006, 21008, 21009, 21011, 21012, 21023, 21024, 21026
|
|
||||||
|
|
||||||
NPC 2100005:REG
|
|
||||||
30150, 30170, 30180, 30320, 30330, 30410, 30460, 30680, 30800, 30820, 30900
|
|
||||||
31090, 31190, 31330, 31340, 31400, 31420, 31520, 31620, 31650, 31660, 34000
|
|
||||||
|
|
||||||
NPC 2100006:VIP
|
|
||||||
30150, 30170, 30180, 30320, 30330, 30410, 30460, 30820, 30900
|
|
||||||
31040, 31090, 31190, 31330, 31340, 31400, 31420, 31620, 31660
|
|
||||||
|
|
||||||
NPC 2100008:VIP
|
|
||||||
20000, 20004, 20005, 20012, 20013, 20031
|
|
||||||
21000, 21003, 21006, 21009, 21012, 21024
|
|
||||||
|
|
||||||
NPC 2100009:REG
|
|
||||||
20001, 20003, 20009, 20010, 20025, 20031
|
|
||||||
21002, 21009, 21011, 21013, 21016, 21029, 21030
|
|
||||||
|
|
||||||
NPC 9120100:VIP
|
|
||||||
30260, 30280, 30340, 30710, 30780, 30800, 30810, 30820, 30920
|
|
||||||
31000, 31030, 31100, 31350, 31460, 31550, 31770, 31790, 31850
|
|
||||||
|
|
||||||
NPC 9120101:REG
|
|
||||||
30260, 30280, 30340, 30360, 30710, 30780, 30790, 30800, 30810, 30820, 30920
|
|
||||||
31350, 31410, 31460, 31540, 31550, 31710, 31720, 31770, 31790, 31800, 31850, 34000
|
|
||||||
|
|
||||||
NPC 9120102:VIP
|
|
||||||
20000, 20004, 20005, 20012, 20020, 20031
|
|
||||||
21000, 21003, 21006, 21012, 21021, 21024
|
|
||||||
|
|
||||||
NPC 9120103:REG
|
|
||||||
20000, 20016, 20019, 20020, 20021, 20024, 20026
|
|
||||||
21000, 21002, 21009, 21016, 21022, 21025, 21027
|
|
||||||
|
|
||||||
NPC 9201015:VIP
|
|
||||||
30050, 30300, 30410, 30450, 30510, 30570, 30580, 30590, 30660, 30910
|
|
||||||
31150, 31220, 31260, 31310, 31420, 31480, 31490, 31580, 31590, 31610, 31630
|
|
||||||
|
|
||||||
NPC 9201016:EXP
|
|
||||||
30000, 30020, 30110, 30130, 30160, 30190, 30240, 30270, 30430
|
|
||||||
31000, 31030, 31050, 31070, 31090, 31150, 31310, 31910, 34010
|
|
||||||
|
|
||||||
NPC 9201018:VIP
|
|
||||||
20000, 20001, 20003, 20004, 20005, 20006, 20007, 20008, 20018, 20019
|
|
||||||
21001, 21002, 21003, 21004, 21005, 21006, 21007, 21012, 21018, 21019
|
|
||||||
|
|
||||||
NPC 9201019:REG
|
|
||||||
20002, 20005, 20007, 20011, 20014, 20027, 20029
|
|
||||||
21001, 21005, 21007, 21017, 21018, 21020, 21022
|
|
||||||
|
|
||||||
NPC 9201063:EXP
|
|
||||||
30250, 30400, 30430, 30440, 30490, 30730, 30830, 30870, 30880, 33100
|
|
||||||
31320, 31450, 31560, 31570, 31690, 31720, 31730, 31830, 34010
|
|
||||||
|
|
||||||
NPC 9201064:VIP
|
|
||||||
30250, 30490, 30730, 30870, 30880, 33100
|
|
||||||
31320, 31450, 31560, 31730, 31830
|
|
||||||
|
|
||||||
NPC 9201069:VIP
|
|
||||||
20000, 20001, 20003, 20004, 20005, 20006, 20008, 20012, 20031
|
|
||||||
21001, 21002, 21003, 21004, 21005, 21006, 21008, 21012, 21016
|
|
||||||
|
|
||||||
NPC 9201070:REG
|
|
||||||
20001, 20008, 20011, 20013, 20024, 20029, 20032
|
|
||||||
21000, 21007, 21011, 21012, 21017, 21020, 21022
|
|
||||||
|
|
||||||
NPC 9270023:REG
|
|
||||||
20002, 20005, 20006, 20013, 20017, 20021, 20024
|
|
||||||
21002, 21003, 21014, 21016, 21017, 21021, 21027
|
|
||||||
|
|
||||||
NPC 9270024:VIP
|
|
||||||
20005, 20012, 20013, 20020, 20021, 20026
|
|
||||||
21006, 21009, 21011, 21012, 21021, 21025
|
|
||||||
|
|
||||||
NPC 9270036:VIP
|
|
||||||
30000, 30020, 30110, 30120, 30270, 30290, 30310, 30670, 30840
|
|
||||||
31010, 31050, 31110, 31120, 31240, 31250, 31280, 31670, 31810
|
|
||||||
|
|
||||||
NPC 9270037:REG
|
|
||||||
30110, 30180, 30260, 30290, 30300, 30350, 30470, 30720, 30840
|
|
||||||
31110, 31200, 31250, 31280, 31600, 31640, 31670, 31810, 34020
|
|
||||||
|
|
||||||
Unused cosmetics: 22
|
|
||||||
30010 Zeta
|
|
||||||
30070 Back
|
|
||||||
30080 Buzzcut
|
|
||||||
30090 Mohawk
|
|
||||||
30100 Fantasy
|
|
||||||
30480 Babby Cut
|
|
||||||
30560 Grand Lionman
|
|
||||||
30690 Metro Man
|
|
||||||
30760 Bowling Ball
|
|
||||||
30890 Eastern Mystery
|
|
||||||
30930 Boy Band Cut
|
|
||||||
30950 Volume Cut
|
|
||||||
31020 Francesca
|
|
||||||
31130 Jolie
|
|
||||||
31530 Zessica
|
|
||||||
31780 ???? ??
|
|
||||||
31820 Grace
|
|
||||||
31860 Laguna Beach
|
|
||||||
31920 CL Hair
|
|
||||||
31950 Vintage Flip
|
|
||||||
33000 Prince Cut
|
|
||||||
34030 Designer Hair
|
|
||||||
|
|
||||||
Missing cosmetic itemids: 15
|
|
||||||
Bohemian Hair
|
|
||||||
Bow Hair
|
|
||||||
Clean-Cut Short Hair
|
|
||||||
Dual Blade Hair
|
|
||||||
Evan Hair (F)
|
|
||||||
Evan Hair (M)
|
|
||||||
Explosion
|
|
||||||
Lilin Hair
|
|
||||||
Low Cut Bob
|
|
||||||
Messy Pigtails
|
|
||||||
Oh So Windy
|
|
||||||
Spiky Shag
|
|
||||||
Top Tied Hair
|
|
||||||
Updo
|
|
||||||
Windy Hair
|
|
||||||
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is part of the OdinMS Maple Story Server
|
|
||||||
Copyright (C) 2008 ~ 2010 Patrick Huy <[email protected]>
|
|
||||||
Matthias Butz <[email protected]>
|
|
||||||
Jan Christian Meyer <[email protected]>
|
|
||||||
|
|
||||||
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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package maplecashcosmeticschecker;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a pair of values.
|
|
||||||
*
|
|
||||||
* @author Frz
|
|
||||||
* @since Revision 333
|
|
||||||
* @version 1.0
|
|
||||||
*
|
|
||||||
* @param <E> The type of the left value.
|
|
||||||
* @param <F> The type of the right value.
|
|
||||||
*/
|
|
||||||
public class Pair<E, F> {
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +1,4 @@
|
|||||||
*
|
*
|
||||||
|
!*/
|
||||||
|
!/cosmetics/**
|
||||||
!.gitignore
|
!.gitignore
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Reference in new issue
Block a user