From fc7e97a355a6145347676f8777dfb262ef39cec4 Mon Sep 17 00:00:00 2001 From: P0nk Date: Sat, 10 Jul 2021 23:18:20 +0200 Subject: [PATCH] Move MapleQuestItemCountFetcher to main module --- .../mapletools/QuestItemCountFetcher.java | 268 +++++++++++++++ .../lib/QuestReport.txt | 22 -- .../MapleQuestItemCountFetcher.java | 323 ------------------ .../src/maplequestitemcountfetcher/Pair.java | 121 ------- 4 files changed, 268 insertions(+), 466 deletions(-) create mode 100644 src/main/java/tools/mapletools/QuestItemCountFetcher.java delete mode 100644 tools/MapleQuestItemCountFetcher/lib/QuestReport.txt delete mode 100644 tools/MapleQuestItemCountFetcher/src/maplequestitemcountfetcher/MapleQuestItemCountFetcher.java delete mode 100644 tools/MapleQuestItemCountFetcher/src/maplequestitemcountfetcher/Pair.java diff --git a/src/main/java/tools/mapletools/QuestItemCountFetcher.java b/src/main/java/tools/mapletools/QuestItemCountFetcher.java new file mode 100644 index 0000000000..fb0a453a92 --- /dev/null +++ b/src/main/java/tools/mapletools/QuestItemCountFetcher.java @@ -0,0 +1,268 @@ +package tools.mapletools; + +import provider.wz.WZFiles; +import tools.Pair; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.*; + +/** + * @author RonanLana + *

+ * This application parses the Quest.wz file inputted and generates a report showing + * all cases where a quest requires an item, but doesn't take them, which may happen + * because the node representing the item doesn't have a "count" clause. + *

+ * Running it should generate a report file under "output" folder with the search results. + */ +public class QuestItemCountFetcher { + private static final File OUTPUT_FILE = ToolConstants.getOutputFile("quest_item_count_report.txt"); + private static final String ACT_NAME = WZFiles.QUEST.getFilePath() + "/Act.img.xml"; + private static final String CHECK_NAME = WZFiles.QUEST.getFilePath() + "/Check.img.xml"; + private static final int INITIAL_STRING_LENGTH = 50; + + private static final Map> checkItems = new HashMap<>(); + private static final Map> actItems = new HashMap<>(); + + private static PrintWriter printWriter = null; + private static BufferedReader bufferedReader = null; + private static byte status = 0; + private static int questId = -1; + private static int isCompleteState = 0; + private static int curItemId; + private static int curItemCount; + + 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[INITIAL_STRING_LENGTH]; + token.getChars(i, j, dest, 0); + + d = new String(dest); + return (d.trim()); + } + + private static String getValue(String token) { + int i, j; + char[] dest; + String d; + + i = token.lastIndexOf("value"); + i = token.indexOf("\"", i) + 1; //lower bound of the string + j = token.indexOf("\"", i); //upper bound + + dest = new char[INITIAL_STRING_LENGTH]; + token.getChars(i, j, dest, 0); + + d = new String(dest); + return (d.trim()); + } + + private static void forwardCursor(int st) { + String line = null; + + try { + while (status >= st && (line = bufferedReader.readLine()) != null) { + simpleToken(line); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static void simpleToken(String token) { + if (token.contains("/imgdir")) { + status -= 1; + } else if (token.contains("imgdir")) { + status += 1; + } + } + + private static void readItemLabel(String token) { + String name = getName(token); + String value = getValue(token); + + switch (name) { + case "id" -> curItemId = Integer.parseInt(value); + case "count" -> curItemCount = Integer.parseInt(value); + } + } + + private static void commitQuestItemPair(Map> map) { + Map list = map.get(questId); + if (list == null) { + list = new LinkedHashMap<>(); + map.put(questId, list); + } + + list.put(curItemId, curItemCount); + } + + private static void translateTokenAct(String token) { + String d; + + if (token.contains("/imgdir")) { + status -= 1; + + if (status == 4) { + if (curItemCount == Integer.MAX_VALUE && isCompleteState == 1) { + commitQuestItemPair(actItems); + } + } + } else if (token.contains("imgdir")) { + if (status == 1) { //getting QuestId + d = getName(token); + questId = Integer.parseInt(d); + } else if (status == 2) { //start/complete + d = getName(token); + isCompleteState = Integer.parseInt(d); + } else if (status == 3) { + if (!token.contains("item")) { + forwardCursor(status); + } + } else if (status == 4) { + curItemId = Integer.MAX_VALUE; + curItemCount = Integer.MAX_VALUE; + } + + status += 1; + } else { + if (status == 5) { + readItemLabel(token); + } + } + } + + private static void translateTokenCheck(String token) { + String d; + + if (token.contains("/imgdir")) { + status -= 1; + + if (status == 4) { + Map missedItems = actItems.get(questId); + + if (missedItems != null && missedItems.containsKey(curItemId) && isCompleteState == 1) { + commitQuestItemPair(checkItems); + } + } + } else if (token.contains("imgdir")) { + if (status == 1) { //getting QuestId + d = getName(token); + questId = Integer.parseInt(d); + } else if (status == 2) { //start/complete + d = getName(token); + isCompleteState = Integer.parseInt(d); + } else if (status == 3) { + if (!token.contains("item")) { + forwardCursor(status); + } + } else if (status == 4) { + curItemId = Integer.MAX_VALUE; + curItemCount = Integer.MAX_VALUE; + } + + status += 1; + } else { + if (status == 5) { + readItemLabel(token); + } + } + } + + private static void readQuestItemCountData() throws IOException { + String line; + + InputStreamReader fileReader = new InputStreamReader(new FileInputStream(ACT_NAME), StandardCharsets.UTF_8); + bufferedReader = new BufferedReader(fileReader); + + while ((line = bufferedReader.readLine()) != null) { + translateTokenAct(line); + } + + bufferedReader.close(); + fileReader.close(); + + fileReader = new InputStreamReader(new FileInputStream(CHECK_NAME), StandardCharsets.UTF_8); + bufferedReader = new BufferedReader(fileReader); + + while ((line = bufferedReader.readLine()) != null) { + translateTokenCheck(line); + } + + bufferedReader.close(); + fileReader.close(); + } + + private static void printReportFileHeader() { + printWriter.println(" # Report File autogenerated from the MapleQuestItemCountFetcher feature by Ronan Lana."); + printWriter.println(" # Generated data takes into account several data info from the server-side WZ.xmls."); + printWriter.println(); + } + + private static void printReportFileResults() { + List>> reports = new ArrayList<>(); + List> notChecked = new ArrayList<>(); + + for (Map.Entry> actItem : actItems.entrySet()) { + int questid = actItem.getKey(); + + for (Map.Entry actData : actItem.getValue().entrySet()) { + int itemid = actData.getKey(); + + Map checkData = checkItems.get(questid); + if (checkData != null) { + Integer count = checkData.get(itemid); + if (count != null) { + reports.add(new Pair<>(questid, new Pair<>(itemid, -count))); + } + } else { + notChecked.add(new Pair<>(questid, itemid)); + } + } + } + + for (Pair> r : reports) { + printWriter.println("Questid " + r.left + " : Itemid " + r.right.left + " should have qty " + r.right.right); + } + + for (Pair r : notChecked) { + printWriter.println("Questid " + r.left + " : Itemid " + r.right + " is unchecked"); + } + } + + private static void reportQuestItemCountData() { + // This will reference one line at a time + + try { + System.out.println("Reading WZs..."); + readQuestItemCountData(); + + System.out.println("Reporting results..."); + printWriter = new PrintWriter(OUTPUT_FILE, StandardCharsets.UTF_8); + + printReportFileHeader(); + printReportFileResults(); + + printWriter.close(); + System.out.println("Done!"); + } catch (FileNotFoundException ex) { + System.out.println("Unable to open quest file."); + } catch (IOException ex) { + System.out.println("Error reading quest file."); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { + reportQuestItemCountData(); + } +} diff --git a/tools/MapleQuestItemCountFetcher/lib/QuestReport.txt b/tools/MapleQuestItemCountFetcher/lib/QuestReport.txt deleted file mode 100644 index 2ac6bb6388..0000000000 --- a/tools/MapleQuestItemCountFetcher/lib/QuestReport.txt +++ /dev/null @@ -1,22 +0,0 @@ - # Report File autogenerated from the MapleQuestItemCountFetcher feature by Ronan Lana. - # Generated data takes into account several data info from the server-side WZ.xmls. - -Questid 2167 : Itemid 4031841 should have qty -1 -Questid 1018 : Itemid 4000142 should have qty -1 -Questid 6361 : Itemid 4031870 should have qty -1 -Questid 6360 : Itemid 4031869 should have qty -1 -Questid 10430 : Itemid 4220152 should have qty -1 -Questid 6390 : Itemid 4031874 should have qty -50 -Questid 2173 : Itemid 4031846 should have qty -1 -Questid 2169 : Itemid 4031843 should have qty -1 -Questid 2168 : Itemid 4031842 should have qty -1 -Questid 2185 : Itemid 4031852 should have qty -1 -Questid 6380 : Itemid 4031873 should have qty -50 -Questid 6350 : Itemid 4031871 should have qty -50 -Questid 2052 : Itemid 4031025 should have qty -10 -Questid 2053 : Itemid 4031026 should have qty -20 -Questid 2054 : Itemid 4031028 should have qty -30 -Questid 6340 : Itemid 4031872 should have qty -50 -Questid 28120 : Itemid 4032306 should have qty -4 -Questid 2180 : Itemid 4031850 should have qty -1 -Questid 2183 : Itemid 4031851 should have qty -1 diff --git a/tools/MapleQuestItemCountFetcher/src/maplequestitemcountfetcher/MapleQuestItemCountFetcher.java b/tools/MapleQuestItemCountFetcher/src/maplequestitemcountfetcher/MapleQuestItemCountFetcher.java deleted file mode 100644 index f06cd1f2f3..0000000000 --- a/tools/MapleQuestItemCountFetcher/src/maplequestitemcountfetcher/MapleQuestItemCountFetcher.java +++ /dev/null @@ -1,323 +0,0 @@ -/* - 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 - 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. - - 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 maplequestitemcountfetcher; - -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.List; -import java.util.LinkedHashMap; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -/** - * - * @author RonanLana - - This application parses the Quest.wz file inputted and generates a report showing - all cases where a quest requires an item, but doesn't take them, which may happen - because the node representing the item doesn't have a "count" clause. - - Running it should generate a report file under "lib" folder with the search results. - - */ -public class MapleQuestItemCountFetcher { - static String actName = "../../wz/Quest.wz/Act.img.xml"; - static String checkName = "../../wz/Quest.wz/Check.img.xml"; - static String newFile = "lib/QuestReport.txt"; - - static PrintWriter printWriter = null; - static InputStreamReader fileReader = null; - static BufferedReader bufferedReader = null; - - static int initialLength = 200; - static int initialStringLength = 50; - - static byte status = 0; - static int questId = -1; - static int isCompleteState = 0; - - static int curItemId; - static int curItemCount; - - static Map> checkItems = new HashMap<>(); - static Map> actItems = new HashMap<>(); - - 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]; - token.getChars(i, j, dest, 0); - - d = new String(dest); - return(d.trim()); - } - - private static String getValue(String token) { - int i, j; - char[] dest; - String d; - - i = token.lastIndexOf("value"); - i = token.indexOf("\"", i) + 1; //lower bound of the string - j = token.indexOf("\"", i); //upper bound - - dest = new char[initialStringLength]; - token.getChars(i, j, dest, 0); - - d = new String(dest); - return(d.trim()); - } - - private static void forwardCursor(int st) { - String line = null; - - try { - while(status >= st && (line = bufferedReader.readLine()) != null) { - simpleToken(line); - } - } - catch(Exception e) { - e.printStackTrace(); - } - } - - private static void simpleToken(String token) { - if(token.contains("/imgdir")) { - status -= 1; - } - else if(token.contains("imgdir")) { - status += 1; - } - } - - private static void readItemLabel(String token) { - String name = getName(token); - String value = getValue(token); - - switch(name) { - case "id": - curItemId = Integer.parseInt(value); - break; - - case "count": - curItemCount = Integer.parseInt(value); - break; - } - } - - private static void commitQuestItemPair(Map> map) { - Map list = map.get(questId); - if(list == null) { - list = new LinkedHashMap<>(); - map.put(questId, list); - } - - list.put(curItemId, curItemCount); - } - - private static void translateTokenAct(String token) { - String d; - - if(token.contains("/imgdir")) { - status -= 1; - - if(status == 4) { - if(curItemCount == Integer.MAX_VALUE && isCompleteState == 1) { - commitQuestItemPair(actItems); - } - } - } - else if(token.contains("imgdir")) { - if(status == 1) { //getting QuestId - d = getName(token); - questId = Integer.parseInt(d); - } - else if(status == 2) { //start/complete - d = getName(token); - isCompleteState = Integer.parseInt(d); - } - else if(status == 3) { - if(!token.contains("item")) { - forwardCursor(status); - } - } - else if(status == 4) { - curItemId = Integer.MAX_VALUE; - curItemCount = Integer.MAX_VALUE; - } - - status += 1; - } - else { - if(status == 5) { - readItemLabel(token); - } - } - } - - private static void translateTokenCheck(String token) { - String d; - - if(token.contains("/imgdir")) { - status -= 1; - - if(status == 4) { - Map missedItems = actItems.get(questId); - - if(missedItems != null && missedItems.containsKey(curItemId) && isCompleteState == 1) { - commitQuestItemPair(checkItems); - } - } - } - else if(token.contains("imgdir")) { - if(status == 1) { //getting QuestId - d = getName(token); - questId = Integer.parseInt(d); - } - else if(status == 2) { //start/complete - d = getName(token); - isCompleteState = Integer.parseInt(d); - } - else if(status == 3) { - if(!token.contains("item")) { - forwardCursor(status); - } - } - else if(status == 4) { - curItemId = Integer.MAX_VALUE; - curItemCount = Integer.MAX_VALUE; - } - - status += 1; - } - else { - if(status == 5) { - readItemLabel(token); - } - } - } - - private static void readQuestItemCountData() throws IOException { - String line; - - fileReader = new InputStreamReader(new FileInputStream(actName), "UTF-8"); - bufferedReader = new BufferedReader(fileReader); - - while((line = bufferedReader.readLine()) != null) { - translateTokenAct(line); - } - - bufferedReader.close(); - fileReader.close(); - - fileReader = new InputStreamReader(new FileInputStream(checkName), "UTF-8"); - bufferedReader = new BufferedReader(fileReader); - - while((line = bufferedReader.readLine()) != null) { - translateTokenCheck(line); - } - - bufferedReader.close(); - fileReader.close(); - } - - private static void printReportFileHeader() { - printWriter.println(" # Report File autogenerated from the MapleQuestItemCountFetcher feature by Ronan Lana."); - printWriter.println(" # Generated data takes into account several data info from the server-side WZ.xmls."); - printWriter.println(); - } - - private static void printReportFileResults() { - List>> reports = new ArrayList<>(); - List> notChecked = new ArrayList<>(); - - for(Entry> actItem : actItems.entrySet()) { - int questid = actItem.getKey(); - - for(Entry actData : actItem.getValue().entrySet()) { - int itemid = actData.getKey(); - - Map checkData = checkItems.get(questid); - if(checkData != null) { - Integer count = checkData.get(itemid); - if(count != null) { - reports.add(new Pair<>(questid, new Pair<>(itemid, -count))); - } - } else { - notChecked.add(new Pair<>(questid, itemid)); - } - } - } - - for(Pair> r : reports) { - printWriter.println("Questid " + r.left + " : Itemid " + r.right.left + " should have qty " + r.right.right); - } - - for(Pair r : notChecked) { - printWriter.println("Questid " + r.left + " : Itemid " + r.right + " is unchecked"); - } - } - - private static void ReportQuestItemCountData() { - // This will reference one line at a time - - try { - System.out.println("Reading WZs..."); - readQuestItemCountData(); - - System.out.println("Reporting results..."); - printWriter = new PrintWriter(newFile, "UTF-8"); - - printReportFileHeader(); - printReportFileResults(); - - printWriter.close(); - System.out.println("Done!"); - } - - catch(FileNotFoundException ex) { - System.out.println("Unable to open quest file."); - } - catch(IOException ex) { - System.out.println("Error reading quest file."); - } - - catch(Exception e) { - e.printStackTrace(); - } - } - - public static void main(String[] args) { - ReportQuestItemCountData(); - } - -} diff --git a/tools/MapleQuestItemCountFetcher/src/maplequestitemcountfetcher/Pair.java b/tools/MapleQuestItemCountFetcher/src/maplequestitemcountfetcher/Pair.java deleted file mode 100644 index 97ce258574..0000000000 --- a/tools/MapleQuestItemCountFetcher/src/maplequestitemcountfetcher/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 maplequestitemcountfetcher; - -/** - * 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