Move MapleNoItemNameFetcher to main module

This commit is contained in:
P0nk
2021-07-10 23:10:22 +02:00
parent a088fd29b7
commit fdef9e37bb
44 changed files with 181 additions and 5081 deletions

View File

@@ -1,89 +1,51 @@
/*
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.*;
import provider.wz.WZFiles;
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 maplenoitemnamefetcher;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import provider.MapleData;
import provider.MapleDataDirectoryEntry;
import provider.MapleDataFileEntry;
import provider.MapleDataProvider;
import provider.MapleDataProviderFactory;
import provider.MapleDataTool;
import java.nio.charset.StandardCharsets;
import java.util.*;
/**
*
* @author RonanLana
*
* <p>
* This application finds itemids with inexistent name and description from
* within the server-side XMLs, then identify them on a report file along
* with a XML excerpt to be appended on the String.wz xml nodes. This program
* assumes all equipids are depicted using 8 digits and item using 7 digits.
*
* <p>
* Estimated parse time: 2 minutes
*/
public class MapleNoItemNameFetcher {
static String wzPath = "../../wz";
static String newFile = "lib/result.txt";
static String xmlFile = "lib/output.txt";
public class NoItemNameFetcher {
private static final File OUTPUT_FILE = ToolConstants.getOutputFile("no_item_name_result.txt");
private static final File OUTPUT_XML_FILE = ToolConstants.getOutputFile("no_item_name_xml.txt");
static PrintWriter printWriter = null;
static InputStreamReader fileReader = null;
static BufferedReader bufferedReader = null;
static Map<Integer, String> itemsWzPath = new HashMap<>();
static Map<Integer, ItemType> itemTypes = new HashMap<>();
static Map<Integer, EquipType> equipTypes = new HashMap<>();
static Map<Integer, ItemType> itemsWithNoNameProperty = new HashMap<>();
static Set<Integer> equipsWithNoCashProperty = new HashSet<>();
private static final Map<Integer, String> itemsWzPath = new HashMap<>();
private static final Map<Integer, EquipType> equipTypes = new HashMap<>();
private static final Map<Integer, ItemType> itemsWithNoNameProperty = new HashMap<>();
private static final Set<Integer> equipsWithNoCashProperty = new HashSet<>();
private static final Map<Integer, String> nameContentCache = new HashMap<>();
private static final Map<Integer, String> descContentCache = new HashMap<>();
private static PrintWriter printWriter = null;
private static ItemType curType = ItemType.UNDEF;
static Map<Integer, String> nameContentCache = new HashMap<>();
static Map<Integer, String> descContentCache = new HashMap<>();
static ItemType curType = ItemType.UNDEF;
private enum ItemType {
UNDEF, CASH, CONSUME, EQP, ETC, INS, PET
}
private enum EquipType {
UNDEF, ACCESSORY, CAP, CAPE, COAT, FACE, GLOVE, HAIR, LONGCOAT, PANTS, PETEQUIP, RING, SHIELD, SHOES, TAMING, WEAPON
}
private static void processStringSubdirectoryData(MapleData subdirData, String subdirPath) {
for(MapleData md : subdirData.getChildren()) {
for (MapleData md : subdirData.getChildren()) {
try {
MapleData nameData = md.getChildByPath("name");
MapleData descData = md.getChildByPath("desc");
int itemId = Integer.parseInt(md.getName());
if (nameData != null && descData != null) {
itemsWithNoNameProperty.remove(itemId);
@@ -93,7 +55,7 @@ public class MapleNoItemNameFetcher {
} else if (descData != null) {
descContentCache.put(itemId, MapleDataTool.getString("desc", md));
}
System.out.println("Found itemid on String.wz with no full property: " + subdirPath + subdirData.getName() + "/" + md.getName());
}
} catch (NumberFormatException nfe) {
@@ -101,9 +63,9 @@ public class MapleNoItemNameFetcher {
}
}
}
private static void readStringSubdirectoryData(MapleData subdirData, int depth, String subdirPath) {
if(depth > 0) {
if (depth > 0) {
for (MapleData mDir : subdirData.getChildren()) {
readStringSubdirectoryData(mDir, depth - 1, subdirPath + mDir.getName() + "/");
}
@@ -111,230 +73,162 @@ public class MapleNoItemNameFetcher {
processStringSubdirectoryData(subdirData, subdirPath);
}
}
private static void readStringSubdirectoryData(MapleData subdirData, int depth) {
readStringSubdirectoryData(subdirData, depth, "");
}
private static void readStringWZData() {
System.out.println("Parsing String.wz...");
MapleDataProvider stringData = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/String.wz"));
MapleDataProvider stringData = MapleDataProviderFactory.getDataProvider(WZFiles.STRING);
MapleData cashStringData = stringData.getData("Cash.img");
readStringSubdirectoryData(cashStringData, 0);
MapleData consumeStringData = stringData.getData("Consume.img");
readStringSubdirectoryData(consumeStringData, 0);
MapleData eqpStringData = stringData.getData("Eqp.img");
readStringSubdirectoryData(eqpStringData, 2);
MapleData etcStringData = stringData.getData("Etc.img");
readStringSubdirectoryData(etcStringData, 1);
MapleData insStringData = stringData.getData("Ins.img");
readStringSubdirectoryData(insStringData, 0);
MapleData petStringData = stringData.getData("Pet.img");
readStringSubdirectoryData(petStringData, 0);
}
private static boolean isTamingMob(int itemId) {
int itemType = itemId / 1000;
return itemType == 1902 || itemType == 1912;
}
private static boolean isAccessory(int itemId) {
return itemId >= 1110000 && itemId < 1140000;
}
private static ItemType getItemTypeFromDirectoryName(String dirName) {
switch(dirName) {
case "Cash":
return ItemType.CASH;
case "Consume":
return ItemType.CONSUME;
case "Etc":
return ItemType.ETC;
case "Install":
return ItemType.INS;
case "Pet":
return ItemType.PET;
default:
return ItemType.UNDEF;
}
return switch (dirName) {
case "Cash" -> ItemType.CASH;
case "Consume" -> ItemType.CONSUME;
case "Etc" -> ItemType.ETC;
case "Install" -> ItemType.INS;
case "Pet" -> ItemType.PET;
default -> ItemType.UNDEF;
};
}
private static EquipType getEquipTypeFromDirectoryName(String dirName) {
switch(dirName) {
case "Accessory":
return EquipType.ACCESSORY;
case "Cap":
return EquipType.CAP;
case "Cape":
return EquipType.CAPE;
case "Coat":
return EquipType.COAT;
case "Face":
return EquipType.FACE;
case "Glove":
return EquipType.GLOVE;
case "Hair":
return EquipType.HAIR;
case "Longcoat":
return EquipType.LONGCOAT;
case "Pants":
return EquipType.PANTS;
case "PetEquip":
return EquipType.PETEQUIP;
case "Ring":
return EquipType.RING;
case "Shield":
return EquipType.SHIELD;
case "Shoes":
return EquipType.SHOES;
case "TamingMob":
return EquipType.TAMING;
case "Weapon":
return EquipType.WEAPON;
default:
return EquipType.UNDEF;
}
return switch (dirName) {
case "Accessory" -> EquipType.ACCESSORY;
case "Cap" -> EquipType.CAP;
case "Cape" -> EquipType.CAPE;
case "Coat" -> EquipType.COAT;
case "Face" -> EquipType.FACE;
case "Glove" -> EquipType.GLOVE;
case "Hair" -> EquipType.HAIR;
case "Longcoat" -> EquipType.LONGCOAT;
case "Pants" -> EquipType.PANTS;
case "PetEquip" -> EquipType.PETEQUIP;
case "Ring" -> EquipType.RING;
case "Shield" -> EquipType.SHIELD;
case "Shoes" -> EquipType.SHOES;
case "TamingMob" -> EquipType.TAMING;
case "Weapon" -> EquipType.WEAPON;
default -> EquipType.UNDEF;
};
}
private static String getStringDirectoryNameFromEquipType(EquipType eType) {
switch(eType) {
case ACCESSORY:
return "Accessory";
case CAP:
return "Cap";
case CAPE:
return "Cape";
case COAT:
return "Coat";
case FACE:
return "Face";
case GLOVE:
return "Glove";
case HAIR:
return "Hair";
case LONGCOAT:
return "Longcoat";
case PANTS:
return "Pants";
case PETEQUIP:
return "PetEquip";
case RING:
return "Ring";
case SHIELD:
return "Shield";
case SHOES:
return "Shoes";
case TAMING:
return "Taming";
case WEAPON:
return "Weapon";
default:
return "Undefined";
}
return switch (eType) {
case ACCESSORY -> "Accessory";
case CAP -> "Cap";
case CAPE -> "Cape";
case COAT -> "Coat";
case FACE -> "Face";
case GLOVE -> "Glove";
case HAIR -> "Hair";
case LONGCOAT -> "Longcoat";
case PANTS -> "Pants";
case PETEQUIP -> "PetEquip";
case RING -> "Ring";
case SHIELD -> "Shield";
case SHOES -> "Shoes";
case TAMING -> "Taming";
case WEAPON -> "Weapon";
default -> "Undefined";
};
}
private static void readEquipNodeData(MapleDataProvider data, MapleDataDirectoryEntry mDir, String wzFileName, String dirName) {
EquipType eqType = getEquipTypeFromDirectoryName(dirName);
for(MapleDataFileEntry mFile : mDir.getFiles()) {
for (MapleDataFileEntry mFile : mDir.getFiles()) {
String fileName = mFile.getName();
try {
int itemId = Integer.parseInt(fileName.substring(0, 8));
int itemId = Integer.parseInt(fileName.substring(0, 8));
itemsWithNoNameProperty.put(itemId, curType);
equipTypes.put(itemId, eqType);
itemsWzPath.put(itemId, wzFileName + "/" + dirName + "/" + fileName);
if(!isAccessory(itemId) && !isTamingMob(itemId)) {
if (!isAccessory(itemId) && !isTamingMob(itemId)) {
try {
MapleData fileData = data.getData(dirName + "/" + fileName);
MapleData mdinfo = fileData.getChildByPath("info");
if( mdinfo.getChildByPath("cash") == null) {
if (mdinfo.getChildByPath("cash") == null) {
equipsWithNoCashProperty.add(itemId);
}
} catch(NullPointerException npe) {
} catch (NullPointerException npe) {
System.out.println("[SEVERE] " + mFile.getName() + " failed to load. Issue: " + npe.getMessage() + "\n\n");
}
}
} catch (Exception e) {}
} catch (Exception e) {
}
}
}
private static void readEquipWZData() {
String wzFileName = "Character.wz";
MapleDataProvider data = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Character.wz"));
MapleDataProvider data = MapleDataProviderFactory.getDataProvider(WZFiles.CHARACTER);
MapleDataDirectoryEntry root = data.getRoot();
System.out.println("Parsing " + wzFileName + "...");
for (MapleDataDirectoryEntry mDir : root.getSubdirectories()) {
String dirName = mDir.getName();
if(dirName.contentEquals("Dragon")) continue;
if (dirName.contentEquals("Dragon")) {
continue;
}
readEquipNodeData(data, mDir, wzFileName, dirName);
}
}
private static void readItemWZData() {
String wzFileName = "Item.wz";
MapleDataProvider data = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Item.wz"));
MapleDataProvider data = MapleDataProviderFactory.getDataProvider(WZFiles.ITEM);
MapleDataDirectoryEntry root = data.getRoot();
System.out.println("Parsing " + wzFileName + "...");
for (MapleDataDirectoryEntry mDir : root.getSubdirectories()) {
String dirName = mDir.getName();
if(dirName.contentEquals("Special")) continue;
if (dirName.contentEquals("Special")) {
continue;
}
curType = getItemTypeFromDirectoryName(dirName);
if(!dirName.contentEquals("Pet")) {
for(MapleDataFileEntry mFile : mDir.getFiles()) {
if (!dirName.contentEquals("Pet")) {
for (MapleDataFileEntry mFile : mDir.getFiles()) {
String fileName = mFile.getName();
MapleData fileData = data.getData(dirName + "/" + fileName);
for(MapleData mData : fileData.getChildren()) {
for (MapleData mData : fileData.getChildren()) {
try {
int itemId = Integer.parseInt(mData.getName());
itemsWithNoNameProperty.put(itemId, curType);
@@ -349,38 +243,38 @@ public class MapleNoItemNameFetcher {
}
}
}
private static void printReportFileHeader() {
printWriter.println(" # Report File autogenerated from the MapleInvalidItemWithNoNameFetcher 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() {
if(!itemsWithNoNameProperty.isEmpty()) {
if (!itemsWithNoNameProperty.isEmpty()) {
printWriter.println("Itemids with missing 'name' property: ");
List<Integer> itemids = new ArrayList<>(itemsWithNoNameProperty.keySet());
Collections.sort(itemids);
for(Integer itemid : itemids) {
for (Integer itemid : itemids) {
printWriter.println(" " + itemid + " " + itemsWzPath.get(itemid));
}
printWriter.println();
}
if(!equipsWithNoCashProperty.isEmpty()) {
if (!equipsWithNoCashProperty.isEmpty()) {
printWriter.println("Equipids with missing 'cash' property: ");
List<Integer> itemids = new ArrayList<>(equipsWithNoCashProperty);
Collections.sort(itemids);
for(Integer itemid : itemids) {
for (Integer itemid : itemids) {
printWriter.println(" " + itemid + " " + itemsWzPath.get(itemid));
}
}
}
private static Map<String, List<Integer>> filterMissingItemNames() {
List<Integer> cashList = new ArrayList<>(20);
List<Integer> consList = new ArrayList<>(20);
@@ -388,35 +282,18 @@ public class MapleNoItemNameFetcher {
List<Integer> etcList = new ArrayList<>(20);
List<Integer> insList = new ArrayList<>(20);
List<Integer> petList = new ArrayList<>(20);
for(Entry<Integer, ItemType> ids : itemsWithNoNameProperty.entrySet()) {
switch(ids.getValue()) {
case CASH:
cashList.add(ids.getKey());
break;
case CONSUME:
consList.add(ids.getKey());
break;
case EQP:
eqpList.add(ids.getKey());
break;
case ETC:
etcList.add(ids.getKey());
break;
case INS:
insList.add(ids.getKey());
break;
case PET:
petList.add(ids.getKey());
break;
for (Map.Entry<Integer, ItemType> ids : itemsWithNoNameProperty.entrySet()) {
switch (ids.getValue()) {
case CASH -> cashList.add(ids.getKey());
case CONSUME -> consList.add(ids.getKey());
case EQP -> eqpList.add(ids.getKey());
case ETC -> etcList.add(ids.getKey());
case INS -> insList.add(ids.getKey());
case PET -> petList.add(ids.getKey());
}
}
Map<String, List<Integer>> nameTags = new HashMap<>();
nameTags.put("Cash.img", cashList);
nameTags.put("Consume.img", consList);
@@ -424,94 +301,94 @@ public class MapleNoItemNameFetcher {
nameTags.put("Etc.img", etcList);
nameTags.put("Ins.img", insList);
nameTags.put("Pet.img", petList);
return nameTags;
}
private static void printOutputFileHeader() {
printWriter.println(" # XML File autogenerated from the MapleInvalidItemWithNoNameFetcher feature by Ronan Lana.");
printWriter.println(" # Generated data takes into account several data info from the server-side WZ.xmls.");
printWriter.println();
}
private static String getMissingEquipName(int itemid) {
String s = nameContentCache.get(itemid);
if (s == null) {
s = "MISSING NAME " + itemid;
}
return s;
}
private static String getMissingEquipDesc(int itemid) {
String s = descContentCache.get(itemid);
if (s == null && itemid >= 2000000) { // thanks Halcyon for noticing "missing info" on equips
s = "MISSING INFO " + itemid;
}
return s;
}
private static void writeMissingEquipInfo(Integer itemid) {
printWriter.println(" <imgdir name=\"" + itemid + "\">");
String s;
s = getMissingEquipName(itemid);
printWriter.println(" <string name=\"name\" value=\"" + s + "\"/>");
s = getMissingEquipDesc(itemid);
printWriter.println(" <string name=\"desc\" value=\"" + s + "\"/>");
printWriter.println(" </imgdir>");
}
private static void writeEquipSubdirectoryHeader(EquipType eType) {
printWriter.println(" <imgdir name=\"" + getStringDirectoryNameFromEquipType(eType) + "\">");
}
private static void writeEquipSubdirectoryFooter() {
printWriter.println(" </imgdir>");
}
private static void writeEquipXMLHeader() {
printWriter.println(" <imgdir name=\"Eqp\">");
}
private static void writeEquipXMLFooter() {
printWriter.println(" </imgdir>");
}
private static void writeMissingItemInfo(Integer itemid) {
printWriter.println(" <imgdir name=\"" + itemid + "\">");
printWriter.println(" <string name=\"name\" value=\"MISSING NAME\"/>");
printWriter.println(" <string name=\"desc\" value=\"MISSING INFO\"/>");
printWriter.println(" </imgdir>");
}
private static void writeXMLHeader(String fileName) {
printWriter.println("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
printWriter.println("<imgdir name=\"" + fileName + "\">");
}
private static void writeXMLFooter() {
printWriter.println("</imgdir>");
}
private static void writeMissingEquipWZNode(EquipType eType, List<Integer> missingNames) {
if(!missingNames.isEmpty()) {
if (!missingNames.isEmpty()) {
Collections.sort(missingNames);
writeEquipSubdirectoryHeader(eType);
for(Integer equipid : missingNames) {
for (Integer equipid : missingNames) {
writeMissingEquipInfo(equipid);
}
writeEquipSubdirectoryFooter();
}
}
private static void writeMissingStringWZNode(String nodePath, List<Integer> missingNames, boolean isEquip) {
if(!missingNames.isEmpty()) {
if(!isEquip) {
if (!missingNames.isEmpty()) {
if (!isEquip) {
Collections.sort(missingNames);
printWriter.println(nodePath + ":");
@@ -519,7 +396,7 @@ public class MapleNoItemNameFetcher {
writeXMLHeader(nodePath);
for(Integer i : missingNames) {
for (Integer i : missingNames) {
writeMissingItemInfo(i);
}
@@ -528,23 +405,23 @@ public class MapleNoItemNameFetcher {
printWriter.println();
} else {
int arraySize = EquipType.values().length;
List<Integer> equips[] = new List[arraySize];
for(int i = 0; i < arraySize; i++) {
List<Integer>[] equips = new List[arraySize];
for (int i = 0; i < arraySize; i++) {
equips[i] = new ArrayList<>(42);
}
for(Integer itemid : missingNames) {
for (Integer itemid : missingNames) {
equips[equipTypes.get(itemid).ordinal()].add(itemid);
}
printWriter.println(nodePath + ":");
printWriter.println();
writeXMLHeader(nodePath);
writeEquipXMLHeader();
for(EquipType eType : EquipType.values()) {
for (EquipType eType : EquipType.values()) {
writeMissingEquipWZNode(eType, equips[eType.ordinal()]);
}
@@ -555,43 +432,41 @@ public class MapleNoItemNameFetcher {
}
}
}
private static void writeMissingStringWZNames(Map<String, List<Integer>> missingNames) throws Exception {
System.out.println("Writing remaining 'String.wz' names...");
printWriter = new PrintWriter(xmlFile, "UTF-8");
printWriter = new PrintWriter(OUTPUT_XML_FILE, StandardCharsets.UTF_8);
printOutputFileHeader();
String nodePaths[] = {"Cash.img", "Consume.img", "Eqp.img", "Etc.img", "Ins.img", "Pet.img"};
for(int i = 0; i < nodePaths.length; i++) {
String[] nodePaths = {"Cash.img", "Consume.img", "Eqp.img", "Etc.img", "Ins.img", "Pet.img"};
for (int i = 0; i < nodePaths.length; i++) {
writeMissingStringWZNode(nodePaths[i], missingNames.get(nodePaths[i]), i == 2);
}
printWriter.close();
}
public static void main(String[] args) {
try {
System.setProperty("wzpath", wzPath);
curType = ItemType.EQP;
readEquipWZData();
curType = ItemType.UNDEF;
readItemWZData();
readStringWZData(); // calculates the diff and effectively holds all items with no name property on the WZ
System.out.println("Reporting results...");
printWriter = new PrintWriter(newFile, "UTF-8");
printWriter = new PrintWriter(OUTPUT_FILE, StandardCharsets.UTF_8);
printReportFileHeader();
printReportFileResults();
printWriter.close();
Map<String, List<Integer>> missingNames = filterMissingItemNames();
writeMissingStringWZNames(missingNames);
System.out.println("Done!");
} catch(Exception e) {
} catch (Exception e) {
e.printStackTrace();
}
}

View File

@@ -1,803 +0,0 @@
# XML File autogenerated from the MapleInvalidItemWithNoNameFetcher feature by Ronan Lana.
# Generated data takes into account several data info from the server-side WZ.xmls.
Cash.img:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<imgdir name="Cash.img">
<imgdir name="5120033">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="5121011">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="5121012">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="5121013">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="5121022">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="5152049">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="5152050">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="5190007">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="5190008">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="5280000">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="5500005">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="5500006">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="5530001">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="5530002">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="5530003">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="5530004">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="5530005">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="5530006">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="5530007">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="5530008">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
</imgdir>
Consume.img:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<imgdir name="Consume.img">
<imgdir name="2022303">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2100141">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2100142">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2100143">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2100144">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2100145">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2100146">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2100147">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2100148">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2100149">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2100150">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2100151">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2100166">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2100901">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2100902">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2100903">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2100904">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2101149">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2101150">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2280020">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2280021">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2280022">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2280023">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2280024">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="2280025">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
</imgdir>
Eqp.img:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<imgdir name="Eqp.img">
<imgdir name="Eqp">
<imgdir name="Accessory">
<imgdir name="1012133">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1142143">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1142144">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1142145">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1142149">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1142150">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1142151">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1142165">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
</imgdir>
<imgdir name="Glove">
<imgdir name="1082262">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
</imgdir>
<imgdir name="Hair">
<imgdir name="30105">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="30106">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="30107">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="30928">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="30929">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="31660">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="31661">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="31662">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="31663">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="31664">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="31665">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="31666">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="31667">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="33101">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
</imgdir>
<imgdir name="Longcoat">
<imgdir name="1050148">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1051130">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1051176">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1052186">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1052217">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1052224">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1052228">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
</imgdir>
<imgdir name="PetEquip">
<imgdir name="1802039">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1802056">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
</imgdir>
<imgdir name="Shield">
<imgdir name="1092067">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
</imgdir>
<imgdir name="Taming">
<imgdir name="1902040">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1902041">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1902042">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1912033">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1912034">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1912035">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1932000">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1932001">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1932002">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1932003">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1932004">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1932005">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1932010">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1932012">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
</imgdir>
<imgdir name="Weapon">
<imgdir name="1302048">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1302124">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1302125">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1302126">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1312035">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1312046">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1322074">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1332093">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1332094">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1332095">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1372026">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1372056">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1382074">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1382075">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1382076">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1392000">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1402043">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1402068">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1412043">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1412044">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1422035">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1422046">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1422047">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1432029">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1432058">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1432059">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1442059">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1442083">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1442084">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1452037">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1452058">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1452077">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1452078">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1452079">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1462069">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1462070">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1462071">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1472044">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1472093">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1472094">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1472095">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1482041">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1482042">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1482043">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1492042">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1492043">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="1492044">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
</imgdir>
</imgdir>
</imgdir>
Etc.img:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<imgdir name="Etc.img">
<imgdir name="4161049">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="4161050">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="4161051">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="4161999">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
</imgdir>
Ins.img:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<imgdir name="Ins.img">
<imgdir name="3010022">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3010023">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3010024">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3010026">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3010028">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994119">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994142">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994143">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994144">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994145">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994146">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994147">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994148">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994149">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994150">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994151">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994152">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994153">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994154">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994155">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994156">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994157">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994158">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994159">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994160">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994161">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994162">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994163">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994164">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994165">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994166">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994167">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994168">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994169">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994170">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994171">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994172">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994173">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994174">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994175">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994176">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994177">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994178">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994179">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
<imgdir name="3994180">
<string name="name" value="MISSING NAME"/>
<string name="desc" value="MISSING INFO"/>
</imgdir>
</imgdir>

View File

@@ -1,446 +0,0 @@
# Report File autogenerated from the MapleInvalidItemWithNoNameFetcher feature by Ronan Lana.
# Generated data takes into account several data info from the server-side WZ.xmls.
Itemids with missing 'name' property:
30105 Character.wz/Hair/00030105.img
30106 Character.wz/Hair/00030106.img
30107 Character.wz/Hair/00030107.img
30928 Character.wz/Hair/00030928.img
30929 Character.wz/Hair/00030929.img
31660 Character.wz/Hair/00031660.img
31661 Character.wz/Hair/00031661.img
31662 Character.wz/Hair/00031662.img
31663 Character.wz/Hair/00031663.img
31664 Character.wz/Hair/00031664.img
31665 Character.wz/Hair/00031665.img
31666 Character.wz/Hair/00031666.img
31667 Character.wz/Hair/00031667.img
33101 Character.wz/Hair/00033101.img
1012133 Character.wz/Accessory/01012133.img
1050148 Character.wz/Longcoat/01050148.img
1051130 Character.wz/Longcoat/01051130.img
1051176 Character.wz/Longcoat/01051176.img
1052186 Character.wz/Longcoat/01052186.img
1052217 Character.wz/Longcoat/01052217.img
1052224 Character.wz/Longcoat/01052224.img
1052228 Character.wz/Longcoat/01052228.img
1082262 Character.wz/Glove/01082262.img
1092067 Character.wz/Shield/01092067.img
1142143 Character.wz/Accessory/01142143.img
1142144 Character.wz/Accessory/01142144.img
1142145 Character.wz/Accessory/01142145.img
1142149 Character.wz/Accessory/01142149.img
1142150 Character.wz/Accessory/01142150.img
1142151 Character.wz/Accessory/01142151.img
1142165 Character.wz/Accessory/01142165.img
1302048 Character.wz/Weapon/01302048.img
1302124 Character.wz/Weapon/01302124.img
1302125 Character.wz/Weapon/01302125.img
1302126 Character.wz/Weapon/01302126.img
1312035 Character.wz/Weapon/01312035.img
1312046 Character.wz/Weapon/01312046.img
1322074 Character.wz/Weapon/01322074.img
1332093 Character.wz/Weapon/01332093.img
1332094 Character.wz/Weapon/01332094.img
1332095 Character.wz/Weapon/01332095.img
1372026 Character.wz/Weapon/01372026.img
1372056 Character.wz/Weapon/01372056.img
1382074 Character.wz/Weapon/01382074.img
1382075 Character.wz/Weapon/01382075.img
1382076 Character.wz/Weapon/01382076.img
1392000 Character.wz/Weapon/01392000.img
1402043 Character.wz/Weapon/01402043.img
1402068 Character.wz/Weapon/01402068.img
1412043 Character.wz/Weapon/01412043.img
1412044 Character.wz/Weapon/01412044.img
1422035 Character.wz/Weapon/01422035.img
1422046 Character.wz/Weapon/01422046.img
1422047 Character.wz/Weapon/01422047.img
1432029 Character.wz/Weapon/01432029.img
1432058 Character.wz/Weapon/01432058.img
1432059 Character.wz/Weapon/01432059.img
1442059 Character.wz/Weapon/01442059.img
1442083 Character.wz/Weapon/01442083.img
1442084 Character.wz/Weapon/01442084.img
1452037 Character.wz/Weapon/01452037.img
1452058 Character.wz/Weapon/01452058.img
1452077 Character.wz/Weapon/01452077.img
1452078 Character.wz/Weapon/01452078.img
1452079 Character.wz/Weapon/01452079.img
1462069 Character.wz/Weapon/01462069.img
1462070 Character.wz/Weapon/01462070.img
1462071 Character.wz/Weapon/01462071.img
1472044 Character.wz/Weapon/01472044.img
1472093 Character.wz/Weapon/01472093.img
1472094 Character.wz/Weapon/01472094.img
1472095 Character.wz/Weapon/01472095.img
1482041 Character.wz/Weapon/01482041.img
1482042 Character.wz/Weapon/01482042.img
1482043 Character.wz/Weapon/01482043.img
1492042 Character.wz/Weapon/01492042.img
1492043 Character.wz/Weapon/01492043.img
1492044 Character.wz/Weapon/01492044.img
1802039 Character.wz/PetEquip/01802039.img
1802056 Character.wz/PetEquip/01802056.img
1902040 Character.wz/TamingMob/01902040.img
1902041 Character.wz/TamingMob/01902041.img
1902042 Character.wz/TamingMob/01902042.img
1912033 Character.wz/TamingMob/01912033.img
1912034 Character.wz/TamingMob/01912034.img
1912035 Character.wz/TamingMob/01912035.img
1932000 Character.wz/TamingMob/01932000.img
1932001 Character.wz/TamingMob/01932001.img
1932002 Character.wz/TamingMob/01932002.img
1932003 Character.wz/TamingMob/01932003.img
1932004 Character.wz/TamingMob/01932004.img
1932005 Character.wz/TamingMob/01932005.img
1932010 Character.wz/TamingMob/01932010.img
1932012 Character.wz/TamingMob/01932012.img
2022303 Item.wz/Consume/0202.img
2100141 Item.wz/Consume/0210.img
2100142 Item.wz/Consume/0210.img
2100143 Item.wz/Consume/0210.img
2100144 Item.wz/Consume/0210.img
2100145 Item.wz/Consume/0210.img
2100146 Item.wz/Consume/0210.img
2100147 Item.wz/Consume/0210.img
2100148 Item.wz/Consume/0210.img
2100149 Item.wz/Consume/0210.img
2100150 Item.wz/Consume/0210.img
2100151 Item.wz/Consume/0210.img
2100166 Item.wz/Consume/0210.img
2100901 Item.wz/Consume/0210.img
2100902 Item.wz/Consume/0210.img
2100903 Item.wz/Consume/0210.img
2100904 Item.wz/Consume/0210.img
2101149 Item.wz/Consume/0210.img
2101150 Item.wz/Consume/0210.img
2280020 Item.wz/Consume/0228.img
2280021 Item.wz/Consume/0228.img
2280022 Item.wz/Consume/0228.img
2280023 Item.wz/Consume/0228.img
2280024 Item.wz/Consume/0228.img
2280025 Item.wz/Consume/0228.img
3010022 Item.wz/Install/0301.img
3010023 Item.wz/Install/0301.img
3010024 Item.wz/Install/0301.img
3010026 Item.wz/Install/0301.img
3010028 Item.wz/Install/0301.img
3994119 Item.wz/Install/0399.img
3994142 Item.wz/Install/0399.img
3994143 Item.wz/Install/0399.img
3994144 Item.wz/Install/0399.img
3994145 Item.wz/Install/0399.img
3994146 Item.wz/Install/0399.img
3994147 Item.wz/Install/0399.img
3994148 Item.wz/Install/0399.img
3994149 Item.wz/Install/0399.img
3994150 Item.wz/Install/0399.img
3994151 Item.wz/Install/0399.img
3994152 Item.wz/Install/0399.img
3994153 Item.wz/Install/0399.img
3994154 Item.wz/Install/0399.img
3994155 Item.wz/Install/0399.img
3994156 Item.wz/Install/0399.img
3994157 Item.wz/Install/0399.img
3994158 Item.wz/Install/0399.img
3994159 Item.wz/Install/0399.img
3994160 Item.wz/Install/0399.img
3994161 Item.wz/Install/0399.img
3994162 Item.wz/Install/0399.img
3994163 Item.wz/Install/0399.img
3994164 Item.wz/Install/0399.img
3994165 Item.wz/Install/0399.img
3994166 Item.wz/Install/0399.img
3994167 Item.wz/Install/0399.img
3994168 Item.wz/Install/0399.img
3994169 Item.wz/Install/0399.img
3994170 Item.wz/Install/0399.img
3994171 Item.wz/Install/0399.img
3994172 Item.wz/Install/0399.img
3994173 Item.wz/Install/0399.img
3994174 Item.wz/Install/0399.img
3994175 Item.wz/Install/0399.img
3994176 Item.wz/Install/0399.img
3994177 Item.wz/Install/0399.img
3994178 Item.wz/Install/0399.img
3994179 Item.wz/Install/0399.img
3994180 Item.wz/Install/0399.img
4161049 Item.wz/Etc/0416.img
4161050 Item.wz/Etc/0416.img
4161051 Item.wz/Etc/0416.img
4161999 Item.wz/Etc/0416.img
5120033 Item.wz/Cash/0512.img
5121011 Item.wz/Cash/0512.img
5121012 Item.wz/Cash/0512.img
5121013 Item.wz/Cash/0512.img
5121022 Item.wz/Cash/0512.img
5152049 Item.wz/Cash/0515.img
5152050 Item.wz/Cash/0515.img
5190007 Item.wz/Cash/0519.img
5190008 Item.wz/Cash/0519.img
5280000 Item.wz/Cash/0528.img
5500005 Item.wz/Cash/0550.img
5500006 Item.wz/Cash/0550.img
5530001 Item.wz/Cash/0553.img
5530002 Item.wz/Cash/0553.img
5530003 Item.wz/Cash/0553.img
5530004 Item.wz/Cash/0553.img
5530005 Item.wz/Cash/0553.img
5530006 Item.wz/Cash/0553.img
5530007 Item.wz/Cash/0553.img
5530008 Item.wz/Cash/0553.img
Equipids with missing 'cash' property:
30010 Character.wz/Hair/00030010.img
30020 Character.wz/Hair/00030020.img
30021 Character.wz/Hair/00030021.img
30022 Character.wz/Hair/00030022.img
30023 Character.wz/Hair/00030023.img
30024 Character.wz/Hair/00030024.img
30025 Character.wz/Hair/00030025.img
30026 Character.wz/Hair/00030026.img
30027 Character.wz/Hair/00030027.img
30030 Character.wz/Hair/00030030.img
30031 Character.wz/Hair/00030031.img
30032 Character.wz/Hair/00030032.img
30100 Character.wz/Hair/00030100.img
30101 Character.wz/Hair/00030101.img
30102 Character.wz/Hair/00030102.img
30103 Character.wz/Hair/00030103.img
30104 Character.wz/Hair/00030104.img
30105 Character.wz/Hair/00030105.img
30106 Character.wz/Hair/00030106.img
30107 Character.wz/Hair/00030107.img
30150 Character.wz/Hair/00030150.img
30151 Character.wz/Hair/00030151.img
30152 Character.wz/Hair/00030152.img
30153 Character.wz/Hair/00030153.img
30154 Character.wz/Hair/00030154.img
30155 Character.wz/Hair/00030155.img
30156 Character.wz/Hair/00030156.img
30157 Character.wz/Hair/00030157.img
30160 Character.wz/Hair/00030160.img
30161 Character.wz/Hair/00030161.img
30162 Character.wz/Hair/00030162.img
30163 Character.wz/Hair/00030163.img
30164 Character.wz/Hair/00030164.img
30165 Character.wz/Hair/00030165.img
30166 Character.wz/Hair/00030166.img
30167 Character.wz/Hair/00030167.img
30170 Character.wz/Hair/00030170.img
30171 Character.wz/Hair/00030171.img
30172 Character.wz/Hair/00030172.img
30173 Character.wz/Hair/00030173.img
30174 Character.wz/Hair/00030174.img
30175 Character.wz/Hair/00030175.img
30176 Character.wz/Hair/00030176.img
30177 Character.wz/Hair/00030177.img
30440 Character.wz/Hair/00030440.img
30441 Character.wz/Hair/00030441.img
30442 Character.wz/Hair/00030442.img
30443 Character.wz/Hair/00030443.img
30444 Character.wz/Hair/00030444.img
30445 Character.wz/Hair/00030445.img
30446 Character.wz/Hair/00030446.img
30447 Character.wz/Hair/00030447.img
30610 Character.wz/Hair/00030610.img
30611 Character.wz/Hair/00030611.img
30612 Character.wz/Hair/00030612.img
30613 Character.wz/Hair/00030613.img
30614 Character.wz/Hair/00030614.img
30615 Character.wz/Hair/00030615.img
30616 Character.wz/Hair/00030616.img
30617 Character.wz/Hair/00030617.img
30740 Character.wz/Hair/00030740.img
30741 Character.wz/Hair/00030741.img
30742 Character.wz/Hair/00030742.img
30743 Character.wz/Hair/00030743.img
30744 Character.wz/Hair/00030744.img
30745 Character.wz/Hair/00030745.img
30746 Character.wz/Hair/00030746.img
30747 Character.wz/Hair/00030747.img
30750 Character.wz/Hair/00030750.img
30751 Character.wz/Hair/00030751.img
30752 Character.wz/Hair/00030752.img
30753 Character.wz/Hair/00030753.img
30754 Character.wz/Hair/00030754.img
30755 Character.wz/Hair/00030755.img
30756 Character.wz/Hair/00030756.img
30757 Character.wz/Hair/00030757.img
30920 Character.wz/Hair/00030920.img
30921 Character.wz/Hair/00030921.img
30922 Character.wz/Hair/00030922.img
30923 Character.wz/Hair/00030923.img
30924 Character.wz/Hair/00030924.img
30925 Character.wz/Hair/00030925.img
30926 Character.wz/Hair/00030926.img
30927 Character.wz/Hair/00030927.img
31020 Character.wz/Hair/00031020.img
31021 Character.wz/Hair/00031021.img
31022 Character.wz/Hair/00031022.img
31023 Character.wz/Hair/00031023.img
31024 Character.wz/Hair/00031024.img
31025 Character.wz/Hair/00031025.img
31026 Character.wz/Hair/00031026.img
31027 Character.wz/Hair/00031027.img
31030 Character.wz/Hair/00031030.img
31031 Character.wz/Hair/00031031.img
31032 Character.wz/Hair/00031032.img
31033 Character.wz/Hair/00031033.img
31034 Character.wz/Hair/00031034.img
31035 Character.wz/Hair/00031035.img
31036 Character.wz/Hair/00031036.img
31037 Character.wz/Hair/00031037.img
31040 Character.wz/Hair/00031040.img
31041 Character.wz/Hair/00031041.img
31042 Character.wz/Hair/00031042.img
31043 Character.wz/Hair/00031043.img
31044 Character.wz/Hair/00031044.img
31045 Character.wz/Hair/00031045.img
31046 Character.wz/Hair/00031046.img
31047 Character.wz/Hair/00031047.img
31050 Character.wz/Hair/00031050.img
31051 Character.wz/Hair/00031051.img
31052 Character.wz/Hair/00031052.img
31053 Character.wz/Hair/00031053.img
31054 Character.wz/Hair/00031054.img
31055 Character.wz/Hair/00031055.img
31056 Character.wz/Hair/00031056.img
31057 Character.wz/Hair/00031057.img
31060 Character.wz/Hair/00031060.img
31061 Character.wz/Hair/00031061.img
31062 Character.wz/Hair/00031062.img
31063 Character.wz/Hair/00031063.img
31064 Character.wz/Hair/00031064.img
31065 Character.wz/Hair/00031065.img
31066 Character.wz/Hair/00031066.img
31067 Character.wz/Hair/00031067.img
31070 Character.wz/Hair/00031070.img
31071 Character.wz/Hair/00031071.img
31072 Character.wz/Hair/00031072.img
31073 Character.wz/Hair/00031073.img
31074 Character.wz/Hair/00031074.img
31075 Character.wz/Hair/00031075.img
31076 Character.wz/Hair/00031076.img
31077 Character.wz/Hair/00031077.img
31080 Character.wz/Hair/00031080.img
31081 Character.wz/Hair/00031081.img
31082 Character.wz/Hair/00031082.img
31083 Character.wz/Hair/00031083.img
31084 Character.wz/Hair/00031084.img
31085 Character.wz/Hair/00031085.img
31086 Character.wz/Hair/00031086.img
31087 Character.wz/Hair/00031087.img
31100 Character.wz/Hair/00031100.img
31101 Character.wz/Hair/00031101.img
31102 Character.wz/Hair/00031102.img
31103 Character.wz/Hair/00031103.img
31104 Character.wz/Hair/00031104.img
31105 Character.wz/Hair/00031105.img
31106 Character.wz/Hair/00031106.img
31107 Character.wz/Hair/00031107.img
31130 Character.wz/Hair/00031130.img
31131 Character.wz/Hair/00031131.img
31132 Character.wz/Hair/00031132.img
31133 Character.wz/Hair/00031133.img
31134 Character.wz/Hair/00031134.img
31135 Character.wz/Hair/00031135.img
31136 Character.wz/Hair/00031136.img
31137 Character.wz/Hair/00031137.img
31140 Character.wz/Hair/00031140.img
31141 Character.wz/Hair/00031141.img
31142 Character.wz/Hair/00031142.img
31143 Character.wz/Hair/00031143.img
31144 Character.wz/Hair/00031144.img
31145 Character.wz/Hair/00031145.img
31146 Character.wz/Hair/00031146.img
31147 Character.wz/Hair/00031147.img
31230 Character.wz/Hair/00031230.img
31231 Character.wz/Hair/00031231.img
31232 Character.wz/Hair/00031232.img
31233 Character.wz/Hair/00031233.img
31234 Character.wz/Hair/00031234.img
31235 Character.wz/Hair/00031235.img
31236 Character.wz/Hair/00031236.img
31237 Character.wz/Hair/00031237.img
31240 Character.wz/Hair/00031240.img
31241 Character.wz/Hair/00031241.img
31242 Character.wz/Hair/00031242.img
31243 Character.wz/Hair/00031243.img
31244 Character.wz/Hair/00031244.img
31245 Character.wz/Hair/00031245.img
31246 Character.wz/Hair/00031246.img
31247 Character.wz/Hair/00031247.img
31260 Character.wz/Hair/00031260.img
31261 Character.wz/Hair/00031261.img
31262 Character.wz/Hair/00031262.img
31263 Character.wz/Hair/00031263.img
31264 Character.wz/Hair/00031264.img
31265 Character.wz/Hair/00031265.img
31266 Character.wz/Hair/00031266.img
31267 Character.wz/Hair/00031267.img
31310 Character.wz/Hair/00031310.img
31311 Character.wz/Hair/00031311.img
31312 Character.wz/Hair/00031312.img
31313 Character.wz/Hair/00031313.img
31314 Character.wz/Hair/00031314.img
31315 Character.wz/Hair/00031315.img
31316 Character.wz/Hair/00031316.img
31317 Character.wz/Hair/00031317.img
31350 Character.wz/Hair/00031350.img
31351 Character.wz/Hair/00031351.img
31352 Character.wz/Hair/00031352.img
31353 Character.wz/Hair/00031353.img
31354 Character.wz/Hair/00031354.img
31355 Character.wz/Hair/00031355.img
31356 Character.wz/Hair/00031356.img
31357 Character.wz/Hair/00031357.img
31400 Character.wz/Hair/00031400.img
31401 Character.wz/Hair/00031401.img
31402 Character.wz/Hair/00031402.img
31403 Character.wz/Hair/00031403.img
31404 Character.wz/Hair/00031404.img
31405 Character.wz/Hair/00031405.img
31406 Character.wz/Hair/00031406.img
31407 Character.wz/Hair/00031407.img
31440 Character.wz/Hair/00031440.img
31441 Character.wz/Hair/00031441.img
31442 Character.wz/Hair/00031442.img
31443 Character.wz/Hair/00031443.img
31444 Character.wz/Hair/00031444.img
31445 Character.wz/Hair/00031445.img
31446 Character.wz/Hair/00031446.img
31447 Character.wz/Hair/00031447.img
31450 Character.wz/Hair/00031450.img
31451 Character.wz/Hair/00031451.img
31452 Character.wz/Hair/00031452.img
31453 Character.wz/Hair/00031453.img
31454 Character.wz/Hair/00031454.img
31455 Character.wz/Hair/00031455.img
31456 Character.wz/Hair/00031456.img
31457 Character.wz/Hair/00031457.img
31490 Character.wz/Hair/00031490.img
31491 Character.wz/Hair/00031491.img
31492 Character.wz/Hair/00031492.img
31493 Character.wz/Hair/00031493.img
31494 Character.wz/Hair/00031494.img
31495 Character.wz/Hair/00031495.img
31496 Character.wz/Hair/00031496.img
31497 Character.wz/Hair/00031497.img
31660 Character.wz/Hair/00031660.img
31661 Character.wz/Hair/00031661.img
31662 Character.wz/Hair/00031662.img
31663 Character.wz/Hair/00031663.img
31664 Character.wz/Hair/00031664.img
31665 Character.wz/Hair/00031665.img
31666 Character.wz/Hair/00031666.img
31667 Character.wz/Hair/00031667.img
1932000 Character.wz/TamingMob/01932000.img
1932001 Character.wz/TamingMob/01932001.img
1932002 Character.wz/TamingMob/01932002.img
1932003 Character.wz/TamingMob/01932003.img
1932004 Character.wz/TamingMob/01932004.img
1932005 Character.wz/TamingMob/01932005.img
1932010 Character.wz/TamingMob/01932010.img
1932012 Character.wz/TamingMob/01932012.img

View File

@@ -1,121 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 ~ 2010 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 maplenoitemnamefetcher;
/**
* 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;
}
}

View File

@@ -1,30 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider;
import java.awt.image.BufferedImage;
public interface MapleCanvas {
int getHeight();
int getWidth();
BufferedImage getImage();
}

View File

@@ -1,34 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider;
import java.util.List;
import provider.wz.MapleDataType;
public interface MapleData extends MapleDataEntity, Iterable<MapleData> {
@Override
public String getName();
public MapleDataType getType();
public List<MapleData> getChildren();
public MapleData getChildByPath(String path);
public Object getData();
}

View File

@@ -1,34 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider;
import java.util.List;
/**
*
* @author Matze
*/
public interface MapleDataDirectoryEntry extends MapleDataEntry {
public List<MapleDataDirectoryEntry> getSubdirectories();
public List<MapleDataFileEntry> getFiles();
public MapleDataEntry getEntry(String name);
}

View File

@@ -1,31 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider;
/**
*
* @author Matze
*/
public interface MapleDataEntity {
public String getName();
public MapleDataEntity getParent();
}

View File

@@ -1,33 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider;
/**
*
* @author Matze
*/
public interface MapleDataEntry extends MapleDataEntity {
public String getName();
public int getSize();
public int getChecksum();
public int getOffset();
}

View File

@@ -1,30 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider;
/**
*
* @author Matze
*/
public interface MapleDataFileEntry extends MapleDataEntry {
public void setOffset(int offset);
}

View File

@@ -1,27 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider;
public interface MapleDataProvider {
MapleData getData(String path);
MapleDataDirectoryEntry getRoot();
}

View File

@@ -1,55 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider;
import java.io.File;
import java.io.IOException;
import provider.wz.WZFile;
import provider.wz.XMLWZFile;
public class MapleDataProviderFactory {
private final static String wzPath = System.getProperty("wzpath");
private static MapleDataProvider getWZ(File in, boolean provideImages) {
if (in.getName().toLowerCase().endsWith("wz") && !in.isDirectory()) {
try {
return new WZFile(in, provideImages);
} catch (IOException e) {
throw new RuntimeException("Loading WZ File failed", e);
}
} else {
return new XMLWZFile(in);
}
}
public static MapleDataProvider getDataProvider(File in) {
return getWZ(in, false);
}
public static MapleDataProvider getImageProvidingDataProvider(File in) {
return getWZ(in, true);
}
public static File fileInWZPath(String filename) {
return new File(wzPath, filename);
}
}

View File

@@ -1,145 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider;
import java.awt.Point;
import java.awt.image.BufferedImage;
import provider.wz.MapleDataType;
public class MapleDataTool {
public static String getString(MapleData data) {
return ((String) data.getData());
}
public static String getString(MapleData data, String def) {
if (data == null || data.getData() == null) {
return def;
} else {
return ((String) data.getData());
}
}
public static String getString(String path, MapleData data) {
return getString(data.getChildByPath(path));
}
public static String getString(String path, MapleData data, String def) {
return getString(data.getChildByPath(path), def);
}
public static double getDouble(MapleData data) {
return ((Double) data.getData()).doubleValue();
}
public static float getFloat(MapleData data) {
return ((Float) data.getData()).floatValue();
}
public static int getInt(MapleData data) {
if (data == null || data.getData() == null) {
return 0;// DEF?
}
return ((Integer) data.getData()).intValue();
}
public static int getInt(String path, MapleData data) {
return getInt(data.getChildByPath(path));
}
public static int getIntConvert(MapleData data) {
if (data.getType() == MapleDataType.STRING) {
return Integer.parseInt(getString(data));
} else {
return getInt(data);
}
}
public static int getIntConvert(String path, MapleData data) {
MapleData d = data.getChildByPath(path);
if (d.getType() == MapleDataType.STRING) {
return Integer.parseInt(getString(d));
} else {
return getInt(d);
}
}
public static int getInt(MapleData data, int def) {
if (data == null || data.getData() == null) {
return def;
} else if (data.getType() == MapleDataType.STRING) {
return Integer.parseInt(getString(data));
} else {
return ((Integer) data.getData()).intValue();
}
}
public static int getInt(String path, MapleData data, int def) {
return getInt(data.getChildByPath(path), def);
}
public static int getIntConvert(String path, MapleData data, int def) {
MapleData d = data.getChildByPath(path);
if (d == null) {
return def;
}
if (d.getType() == MapleDataType.STRING) {
try {
return Integer.parseInt(getString(d));
} catch (NumberFormatException nfe) {
nfe.printStackTrace();
return def;
}
} else {
return getInt(d, def);
}
}
public static BufferedImage getImage(MapleData data) {
return ((MapleCanvas) data.getData()).getImage();
}
public static Point getPoint(MapleData data) {
return ((Point) data.getData());
}
public static Point getPoint(String path, MapleData data) {
return getPoint(data.getChildByPath(path));
}
public static Point getPoint(String path, MapleData data, Point def) {
final MapleData pointData = data.getChildByPath(path);
if (pointData == null) {
return def;
}
return getPoint(pointData);
}
public static String getFullDataPath(MapleData data) {
String path = "";
MapleDataEntity myData = data;
while (myData != null) {
path = myData.getName() + "/" + path;
myData = myData.getParent();
}
return path.substring(0, path.length() - 1);
}
}

View File

@@ -1,70 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider.wz;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import provider.MapleCanvas;
public class FileStoredPngMapleCanvas implements MapleCanvas {
private File file;
private int width;
private int height;
private BufferedImage image;
public FileStoredPngMapleCanvas(int width, int height, File fileIn) {
this.width = width;
this.height = height;
this.file = fileIn;
}
@Override
public int getHeight() {
return height;
}
@Override
public int getWidth() {
return width;
}
@Override
public BufferedImage getImage() {
loadImageIfNecessary();
return image;
}
private void loadImageIfNecessary() {
if (image == null) {
try {
image = ImageIO.read(file);
// replace the dimensions loaded from the wz by the REAL dimensions from the image - should be equal tho
width = image.getWidth();
height = image.getHeight();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}

View File

@@ -1,39 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider.wz;
public class ImgMapleSound {
private int dataLength, offset;
public ImgMapleSound(int dataLength, int offset) {
this.dataLength = dataLength;
this.offset = offset;
}
public int getDataLength() {
return dataLength;
}
public int getOffset() {
return offset;
}
}

View File

@@ -1,86 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider.wz;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import provider.MapleDataProviderFactory;
import tools.data.input.GenericLittleEndianAccessor;
import tools.data.input.InputStreamByteStream;
import tools.data.input.LittleEndianAccessor;
public class ListWZFile {
private LittleEndianAccessor lea;
private List<String> entries = new ArrayList<String>();
private static Collection<String> modernImgs = new HashSet<String>();
public static byte[] xorBytes(byte[] a, byte[] b) {
byte[] wusched = new byte[a.length];
for (int i = 0; i < a.length; i++) {
wusched[i] = (byte) (a[i] ^ b[i]);
}
return wusched;
}
public ListWZFile(File listwz) throws FileNotFoundException {
lea = new GenericLittleEndianAccessor(new InputStreamByteStream(new BufferedInputStream(new FileInputStream(listwz))));
while (lea.available() > 0) {
int l = lea.readInt() * 2;
byte[] chunk = new byte[l];
for (int i = 0; i < chunk.length; i++) {
chunk[i] = lea.readByte();
}
lea.readChar();
final String value = String.valueOf(WZTool.readListString(chunk));
entries.add(value);
}
entries = Collections.unmodifiableList(entries);
}
public List<String> getEntries() {
return entries;
}
public static void init() {
final String listWz = System.getProperty("listwz");
if (listWz != null) {
ListWZFile listwz;
try {
listwz = new ListWZFile(MapleDataProviderFactory.fileInWZPath("List.wz"));
modernImgs = new HashSet<String>(listwz.getEntries());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
public static boolean isModernImgFile(String path) {
return modernImgs.contains(path);
}
}

View File

@@ -1,26 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider.wz;
public enum MapleDataType {
NONE, IMG_0x00, SHORT, INT, FLOAT, DOUBLE, STRING, EXTENDED, PROPERTY, CANVAS, VECTOR, CONVEX, SOUND, UOL, UNKNOWN_TYPE, UNKNOWN_EXTENDED_TYPE;
}

View File

@@ -1,151 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider.wz;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.PixelInterleavedSampleModel;
import java.awt.image.Raster;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;
import provider.MapleCanvas;
public class PNGMapleCanvas implements MapleCanvas {
private static final int[] ZAHLEN = new int[]{2, 1, 0, 3};
private int height;
private int width;
private int dataLength;
private int format;
private byte[] data;
public PNGMapleCanvas(int width, int height, int dataLength, int format, byte[] data) {
super();
this.height = height;
this.width = width;
this.dataLength = dataLength;
this.format = format;
this.data = data;
}
public int getHeight() {
return height;
}
public int getWidth() {
return width;
}
public int getFormat() {
return format;
}
private byte[] getData() {
return data;
}
@Override
public BufferedImage getImage() {
int sizeUncompressed = 0;
int size8888 = 0;
int maxWriteBuf = 2;
int maxHeight = 3;
byte[] writeBuf = new byte[maxWriteBuf];
@SuppressWarnings ("unused")
byte[] rowPointers = new byte[maxHeight];
switch (getFormat()) {
case 1:
case 513:
sizeUncompressed = getHeight() * getWidth() * 4;
break;
case 2:
sizeUncompressed = getHeight() * getWidth() * 8;
break;
case 517:
sizeUncompressed = getHeight() * getWidth() / 128;
break;
}
size8888 = getHeight() * getWidth() * 8;
if (size8888 > maxWriteBuf) {
maxWriteBuf = size8888;
writeBuf = new byte[maxWriteBuf];
}
if (getHeight() > maxHeight) {
maxHeight = getHeight();
rowPointers = new byte[maxHeight];
}
Inflater dec = new Inflater();
dec.setInput(getData(), 0, dataLength);
int declen = 0;
byte[] uc = new byte[sizeUncompressed];
try {
declen = dec.inflate(uc);
} catch (DataFormatException ex) {
throw new RuntimeException("zlib fucks", ex);
}
dec.end();
if (getFormat() == 1) {
for (int i = 0; i < sizeUncompressed; i++) {
byte low = (byte) (uc[i] & 0x0F);
byte high = (byte) (uc[i] & 0xF0);
writeBuf[(i << 1)] = (byte) (((low << 4) | low) & 0xFF);
writeBuf[(i << 1) + 1] = (byte) (high | ((high >>> 4) & 0xF));
}
} else if (getFormat() == 2) {
writeBuf = uc;
} else if (getFormat() == 513) {
for (int i = 0; i < declen; i += 2) {
byte bBits = (byte) ((uc[i] & 0x1F) << 3);
byte gBits = (byte) (((uc[i + 1] & 0x07) << 5) | ((uc[i] & 0xE0) >> 3));
byte rBits = (byte) (uc[i + 1] & 0xF8);
writeBuf[(i << 1)] = (byte) (bBits | (bBits >> 5));
writeBuf[(i << 1) + 1] = (byte) (gBits | (gBits >> 6));
writeBuf[(i << 1) + 2] = (byte) (rBits | (rBits >> 5));
writeBuf[(i << 1) + 3] = (byte) 0xFF;
}
} else if (getFormat() == 517) {
byte b = 0x00;
int pixelIndex = 0;
for (int i = 0; i < declen; i++) {
for (int j = 0; j < 8; j++) {
b = (byte) (((uc[i] & (0x01 << (7 - j))) >> (7 - j)) * 255);
for (int k = 0; k < 16; k++) {
pixelIndex = (i << 9) + (j << 6) + k * 2;
writeBuf[pixelIndex] = b;
writeBuf[pixelIndex + 1] = b;
writeBuf[pixelIndex + 2] = b;
writeBuf[pixelIndex + 3] = (byte) 0xFF;
}
}
}
}
DataBufferByte imgData = new DataBufferByte(writeBuf, sizeUncompressed);
SampleModel sm = new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE, getWidth(), getHeight(), 4, getWidth() * 4, ZAHLEN);
WritableRaster imgRaster = Raster.createWritableRaster(sm, imgData, new Point(0, 0));
BufferedImage aa = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
aa.setData(imgRaster);
return aa;
}
}

View File

@@ -1,68 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider.wz;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import provider.MapleDataDirectoryEntry;
import provider.MapleDataEntity;
import provider.MapleDataEntry;
import provider.MapleDataFileEntry;
public class WZDirectoryEntry extends WZEntry implements MapleDataDirectoryEntry {
private List<MapleDataDirectoryEntry> subdirs = new ArrayList<MapleDataDirectoryEntry>();
private List<MapleDataFileEntry> files = new ArrayList<MapleDataFileEntry>();
private Map<String, MapleDataEntry> entries = new HashMap<String, MapleDataEntry>();
public WZDirectoryEntry(String name, int size, int checksum, MapleDataEntity parent) {
super(name, size, checksum, parent);
}
public WZDirectoryEntry() {
super(null, 0, 0, null);
}
public void addDirectory(MapleDataDirectoryEntry dir) {
subdirs.add(dir);
entries.put(dir.getName(), dir);
}
public void addFile(MapleDataFileEntry fileEntry) {
files.add(fileEntry);
entries.put(fileEntry.getName(), fileEntry);
}
public List<MapleDataDirectoryEntry> getSubdirectories() {
return Collections.unmodifiableList(subdirs);
}
public List<MapleDataFileEntry> getFiles() {
return Collections.unmodifiableList(files);
}
public MapleDataEntry getEntry(String name) {
return entries.get(name);
}
}

View File

@@ -1,61 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider.wz;
import provider.MapleDataEntity;
import provider.MapleDataEntry;
public class WZEntry implements MapleDataEntry {
private String name;
private int size;
private int checksum;
private int offset;
private MapleDataEntity parent;
public WZEntry(String name, int size, int checksum, MapleDataEntity parent) {
super();
this.name = name;
this.size = size;
this.checksum = checksum;
this.parent = parent;
}
public String getName() {
return name;
}
public int getSize() {
return size;
}
public int getChecksum() {
return checksum;
}
public int getOffset() {
return offset;
}
public MapleDataEntity getParent() {
return parent;
}
}

View File

@@ -1,154 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider.wz;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import provider.MapleData;
import provider.MapleDataDirectoryEntry;
import provider.MapleDataFileEntry;
import provider.MapleDataProvider;
import tools.data.input.GenericLittleEndianAccessor;
import tools.data.input.GenericSeekableLittleEndianAccessor;
import tools.data.input.InputStreamByteStream;
import tools.data.input.LittleEndianAccessor;
import tools.data.input.RandomAccessByteStream;
import tools.data.input.SeekableLittleEndianAccessor;
public class WZFile implements MapleDataProvider {
static {
ListWZFile.init();
}
private File wzfile;
private LittleEndianAccessor lea;
private SeekableLittleEndianAccessor slea;
private int headerSize;
private WZDirectoryEntry root;
private boolean provideImages;
private int cOffset;
public WZFile(File wzfile, boolean provideImages) throws IOException {
this.wzfile = wzfile;
lea = new GenericLittleEndianAccessor(new InputStreamByteStream(new BufferedInputStream(new FileInputStream(wzfile))));
RandomAccessFile raf = new RandomAccessFile(wzfile, "r");
slea = new GenericSeekableLittleEndianAccessor(new RandomAccessByteStream(raf));
root = new WZDirectoryEntry(wzfile.getName(), 0, 0, null);
this.provideImages = provideImages;
load();
}
private void load() throws IOException {
lea.readAsciiString(4);
lea.readInt();
lea.readInt();
headerSize = lea.readInt();
lea.readNullTerminatedAsciiString();
lea.readShort();
parseDirectory(root);
cOffset = (int) lea.getBytesRead();
getOffsets(root);
}
private void getOffsets(MapleDataDirectoryEntry dir) {
for (MapleDataFileEntry file : dir.getFiles()) {
file.setOffset(cOffset);
cOffset += file.getSize();
}
for (MapleDataDirectoryEntry sdir : dir.getSubdirectories()) {
getOffsets(sdir);
}
}
private void parseDirectory(WZDirectoryEntry dir) {
int entries = WZTool.readValue(lea);
for (int i = 0; i < entries; i++) {
byte marker = lea.readByte();
String name = null;
int size, checksum;
switch (marker) {
case 0x02:
name = WZTool.readDecodedStringAtOffsetAndReset(slea, lea.readInt() + this.headerSize + 1);
size = WZTool.readValue(lea);
checksum = WZTool.readValue(lea);
lea.readInt(); //dummy int
dir.addFile(new WZFileEntry(name, size, checksum, dir));
break;
case 0x03:
case 0x04:
name = WZTool.readDecodedString(lea);
size = WZTool.readValue(lea);
checksum = WZTool.readValue(lea);
lea.readInt(); //dummy int
if (marker == 3) {
dir.addDirectory(new WZDirectoryEntry(name, size, checksum, dir));
} else {
dir.addFile(new WZFileEntry(name, size, checksum, dir));
}
break;
default:
}
}
for (MapleDataDirectoryEntry idir : dir.getSubdirectories()) {
parseDirectory((WZDirectoryEntry) idir);
}
}
public WZIMGFile getImgFile(String path) throws IOException {
String segments[] = path.split("/");
WZDirectoryEntry dir = root;
for (int x = 0; x < segments.length - 1; x++) {
dir = (WZDirectoryEntry) dir.getEntry(segments[x]);
if (dir == null) {
return null;
}
}
WZFileEntry entry = (WZFileEntry) dir.getEntry(segments[segments.length - 1]);
if (entry == null) {
return null;
}
String fullPath = wzfile.getName().substring(0, wzfile.getName().length() - 3).toLowerCase() + "/" + path;
return new WZIMGFile(this.wzfile, entry, provideImages, ListWZFile.isModernImgFile(fullPath));
}
@Override
public synchronized MapleData getData(String path) {
try {
WZIMGFile imgFile = getImgFile(path);
if (imgFile == null) {
return null;
}
MapleData ret = imgFile.getRoot();
return ret;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
public MapleDataDirectoryEntry getRoot() {
return root;
}
}

View File

@@ -1,42 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider.wz;
import provider.MapleDataEntity;
import provider.MapleDataFileEntry;
public class WZFileEntry extends WZEntry implements MapleDataFileEntry {
private int offset;
public WZFileEntry(String name, int size, int checksum, MapleDataEntity parent) {
super(name, size, checksum, parent);
}
@Override
public int getOffset() {
return offset;
}
public void setOffset(int offset) {
this.offset = offset;
}
}

View File

@@ -1,118 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider.wz;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import provider.MapleData;
import provider.MapleDataEntity;
public class WZIMGEntry implements MapleData {
private String name;
private MapleDataType type;
private List<MapleData> children = new ArrayList<MapleData>(10);
private Object data;
private MapleDataEntity parent;
public WZIMGEntry(MapleDataEntity parent) {
this.parent = parent;
}
@Override
public String getName() {
return name;
}
@Override
public MapleDataType getType() {
return type;
}
@Override
public List<MapleData> getChildren() {
return Collections.unmodifiableList(children);
}
@Override
public MapleData getChildByPath(String path) {
String segments[] = path.split("/");
if (segments[0].equals("..")) {
return ((MapleData) getParent()).getChildByPath(path.substring(path.indexOf("/") + 1));
}
MapleData ret = this;
for (int x = 0; x < segments.length; x++) {
boolean foundChild = false;
for (MapleData child : ret.getChildren()) {
if (child.getName().equals(segments[x])) {
ret = child;
foundChild = true;
break;
}
}
if (!foundChild) {
return null;
}
}
return ret;
}
@Override
public Object getData() {
return data;
}
public void setName(String name) {
this.name = name;
}
public void setType(MapleDataType type) {
this.type = type;
}
public void setData(Object data) {
this.data = data;
}
public void addChild(WZIMGEntry entry) {
children.add(entry);
}
@Override
public Iterator<MapleData> iterator() {
return getChildren().iterator();
}
@Override
public String toString() {
return getName() + ":" + getData();
}
public MapleDataEntity getParent() {
return parent;
}
public void finish() {
((ArrayList<MapleData>) children).trimToSize();
}
}

View File

@@ -1,227 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider.wz;
import java.awt.Point;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import tools.data.input.GenericSeekableLittleEndianAccessor;
import tools.data.input.RandomAccessByteStream;
import tools.data.input.SeekableLittleEndianAccessor;
public class WZIMGFile {
private WZFileEntry file;
private WZIMGEntry root;
private boolean provideImages;
@SuppressWarnings ("unused")
private boolean modernImg;
public WZIMGFile(File wzfile, WZFileEntry file, boolean provideImages, boolean modernImg) throws IOException {
RandomAccessFile raf = new RandomAccessFile(wzfile, "r");
SeekableLittleEndianAccessor slea = new GenericSeekableLittleEndianAccessor(new RandomAccessByteStream(raf));
slea.seek(file.getOffset());
this.file = file;
this.provideImages = provideImages;
root = new WZIMGEntry(file.getParent());
root.setName(file.getName());
root.setType(MapleDataType.EXTENDED);
this.modernImg = modernImg;
parseExtended(root, slea, 0);
root.finish();
raf.close();
}
protected void dumpImg(OutputStream out, SeekableLittleEndianAccessor slea) throws IOException {
DataOutputStream os = new DataOutputStream(out);
long oldPos = slea.getPosition();
slea.seek(file.getOffset());
for (int x = 0; x < file.getSize(); x++) {
os.write(slea.readByte());
}
slea.seek(oldPos);
}
public WZIMGEntry getRoot() {
return root;
}
private void parse(WZIMGEntry entry, SeekableLittleEndianAccessor slea) {
byte marker = slea.readByte();
switch (marker) {
case 0: {
String name = WZTool.readDecodedString(slea);
entry.setName(name);
break;
}
case 1: {
String name = WZTool.readDecodedStringAtOffsetAndReset(slea, file.getOffset() + slea.readInt());
entry.setName(name);
break;
}
default:
System.out.println("Unknown Image identifier: " + marker + " at offset " + (slea.getPosition() - file.getOffset()));
}
marker = slea.readByte();
switch (marker) {
case 0:
entry.setType(MapleDataType.IMG_0x00);
break;
case 2:
case 11: //??? no idea, since 0.49
entry.setType(MapleDataType.SHORT);
entry.setData(Short.valueOf(slea.readShort()));
break;
case 3:
entry.setType(MapleDataType.INT);
entry.setData(Integer.valueOf(WZTool.readValue(slea)));
break;
case 4:
entry.setType(MapleDataType.FLOAT);
entry.setData(Float.valueOf(WZTool.readFloatValue(slea)));
break;
case 5:
entry.setType(MapleDataType.DOUBLE);
entry.setData(Double.valueOf(slea.readDouble()));
break;
case 8:
entry.setType(MapleDataType.STRING);
byte iMarker = slea.readByte();
if (iMarker == 0) {
entry.setData(WZTool.readDecodedString(slea));
} else if (iMarker == 1) {
entry.setData(WZTool.readDecodedStringAtOffsetAndReset(slea, slea.readInt() + file.getOffset()));
} else {
System.out.println("Unknown String type " + iMarker);
}
break;
case 9:
entry.setType(MapleDataType.EXTENDED);
long endOfExtendedBlock = slea.readInt();
endOfExtendedBlock += slea.getPosition();
parseExtended(entry, slea, endOfExtendedBlock);
break;
default:
System.out.println("Unknown Image type " + marker);
}
}
private void parseExtended(WZIMGEntry entry, SeekableLittleEndianAccessor slea, long endOfExtendedBlock) {
byte marker = slea.readByte();
String type;
switch (marker) {
case 0x73:
type = WZTool.readDecodedString(slea);
break;
case 0x1B:
type = WZTool.readDecodedStringAtOffsetAndReset(slea, file.getOffset() + slea.readInt());
break;
default:
throw new RuntimeException("Unknown extended image identifier: " + marker + " at offset " +
(slea.getPosition() - file.getOffset()));
}
if (type.equals("Property")) {
entry.setType(MapleDataType.PROPERTY);
slea.readByte();
slea.readByte();
int children = WZTool.readValue(slea);
for (int i = 0; i < children; i++) {
WZIMGEntry cEntry = new WZIMGEntry(entry);
parse(cEntry, slea);
cEntry.finish();
entry.addChild(cEntry);
}
} else if (type.equals("Canvas")) {
entry.setType(MapleDataType.CANVAS);
slea.readByte();
marker = slea.readByte();
if (marker == 0) {
// do nothing
} else if (marker == 1) {
slea.readByte();
slea.readByte();
int children = WZTool.readValue(slea);
for (int i = 0; i < children; i++) {
WZIMGEntry child = new WZIMGEntry(entry);
parse(child, slea);
child.finish();
entry.addChild(child);
}
} else {
System.out.println("Canvas marker != 1 (" + marker + ")");
}
int width = WZTool.readValue(slea);
int height = WZTool.readValue(slea);
int format = WZTool.readValue(slea);
int format2 = slea.readByte();
slea.readInt();
int dataLength = slea.readInt() - 1;
slea.readByte();
if (provideImages) {
byte[] pngdata = slea.read(dataLength);
entry.setData(new PNGMapleCanvas(width, height, dataLength, format + format2, pngdata));
} else {
entry.setData(new PNGMapleCanvas(width, height, dataLength, format + format2, null));
slea.skip(dataLength);
}
} else if (type.equals("Shape2D#Vector2D")) {
entry.setType(MapleDataType.VECTOR);
int x = WZTool.readValue(slea);
int y = WZTool.readValue(slea);
entry.setData(new Point(x, y));
} else if (type.equals("Shape2D#Convex2D")) {
int children = WZTool.readValue(slea);
for (int i = 0; i < children; i++) {
WZIMGEntry cEntry = new WZIMGEntry(entry);
parseExtended(cEntry, slea, 0);
cEntry.finish();
entry.addChild(cEntry);
}
} else if (type.equals("Sound_DX8")) {
entry.setType(MapleDataType.SOUND);
slea.readByte();
int dataLength = WZTool.readValue(slea);
WZTool.readValue(slea); // no clue what this is
int offset = (int) slea.getPosition();
entry.setData(new ImgMapleSound(dataLength, offset - file.getOffset()));
slea.seek(endOfExtendedBlock);
} else if (type.equals("UOL")) {
entry.setType(MapleDataType.UOL);
slea.readByte();
byte uolmarker = slea.readByte();
switch (uolmarker) {
case 0:
entry.setData(WZTool.readDecodedString(slea));
break;
case 1:
entry.setData(WZTool.readDecodedStringAtOffsetAndReset(slea, file.getOffset() + slea.readInt()));
break;
default:
System.out.println("Unknown UOL marker: " + uolmarker + " " + entry.getName());
}
} else {
throw new RuntimeException("Unhandled extended type: " + type);
}
}
}

View File

@@ -1,188 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider.wz;
import tools.data.input.LittleEndianAccessor;
import tools.data.input.SeekableLittleEndianAccessor;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
/*
* Ported Code, see WZFile.java for more info
*/
public class WZTool {
private static byte[] encKey;
static {
byte[] iv = new byte[]{(byte) 0x4d, (byte) 0x23, (byte) 0xc7, (byte) 0x2b,
(byte) 0x4d, (byte) 0x23, (byte) 0xc7, (byte) 0x2b,
(byte) 0x4d, (byte) 0x23, (byte) 0xc7, (byte) 0x2b,
(byte) 0x4d, (byte) 0x23, (byte) 0xc7, (byte) 0x2b,};
byte[] key = new byte[]{(byte) 0x13, 0x00, 0x00, 0x00,
(byte) 0x08, 0x00, 0x00, 0x00,
(byte) 0x06, 0x00, 0x00, 0x00,
(byte) 0xB4, 0x00, 0x00, 0x00,
(byte) 0x1B, 0x00, 0x00, 0x00,
(byte) 0x0F, 0x00, 0x00, 0x00,
(byte) 0x33, 0x00, 0x00, 0x00,
(byte) 0x52, 0x00, 0x00, 0x00
};
Cipher cipher = null;
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
try {
cipher = Cipher.getInstance("AES");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
try {
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
} catch (InvalidKeyException e) {
e.printStackTrace();
}
encKey = new byte[0xFFFF];
for (int i = 0; i < (0xFFFF / 16); i++) {
try {
iv = cipher.doFinal(iv);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
System.arraycopy(iv, 0, encKey, (i * 16), 16);
}
try {
iv = cipher.doFinal(iv);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
System.arraycopy(iv, 0, encKey, 65520, 15);
}
public static byte[] readListString(byte[] str) {
for (int i = 0; i < str.length; i++) {
str[i] = (byte) (str[i] ^ encKey[i]);
}
return str;
}
public static String readDecodedString(LittleEndianAccessor llea) {
int strLength;
byte b = llea.readByte();
if (b == 0x00) {
return "";
}
if (b >= 0) {
if (b == 0x7F) {
strLength = llea.readInt();
} else {
strLength = b;
}
if (strLength < 0) {
return "";
}
byte str[] = new byte[strLength * 2];
for (int i = 0; i < strLength * 2; i++) {
str[i] = llea.readByte();
}
return DecryptUnicodeStr(str);
} else {
if (b == -128) {
strLength = llea.readInt();
} else {
strLength = -b;
}
if (strLength < 0) {
return "";
}
byte str[] = new byte[strLength];
for (int i = 0; i < strLength; i++) {
str[i] = llea.readByte();
}
return DecryptAsciiStr(str);
}
}
public static String DecryptAsciiStr(byte[] str) {
byte xorByte = (byte) 0xAA;
for (int i = 0; i < str.length; i++) {
str[i] = (byte) (str[i] ^ xorByte ^ encKey[i]);
xorByte++;
}
return new String(str);
}
public static String DecryptUnicodeStr(byte[] str) {
int xorByte = 0xAAAA;
char[] charRet = new char[str.length / 2];
for (int i = 0; i < str.length; i++) {
str[i] = (byte) (str[i] ^ encKey[i]);
}
for (int i = 0; i < (str.length / 2); i++) {
char toXor = (char) ((str[i] << 8) | str[i + 1]);
charRet[i] = (char) (toXor ^ xorByte);
xorByte++;
}
return String.valueOf(charRet);
}
public static String readDecodedStringAtOffset(SeekableLittleEndianAccessor slea, int offset) {
slea.seek(offset);
return readDecodedString(slea);
}
public static String readDecodedStringAtOffsetAndReset(SeekableLittleEndianAccessor slea, int offset) {
long pos = 0;
pos = slea.getPosition();
slea.seek(offset);
String ret = readDecodedString(slea);
slea.seek(pos);
return ret;
}
public static int readValue(LittleEndianAccessor lea) {
byte b = lea.readByte();
if (b == -128) {
return lea.readInt();
} else {
return b;
}
}
public static float readFloatValue(LittleEndianAccessor lea) {
byte b = lea.readByte();
if (b == -128) {
return lea.readFloat();
} else {
return 0;
}
}
}

View File

@@ -1,219 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider.wz;
import java.awt.Point;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.text.NumberFormat;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import provider.MapleData;
import provider.MapleDataEntity;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class XMLDomMapleData implements MapleData {
private Node node;
private File imageDataDir;
private NumberFormat nf;
public XMLDomMapleData(FileInputStream fis, File imageDataDir) {
try {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(fis);
this.node = document.getFirstChild();
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
} catch (SAXException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
this.imageDataDir = imageDataDir;
this.nf = NumberFormat.getInstance(Locale.FRANCE);
}
private XMLDomMapleData(Node node) {
this.node = node;
this.nf = NumberFormat.getInstance(Locale.FRANCE);
}
@Override
public MapleData getChildByPath(String path) {
String segments[] = path.split("/");
if (segments[0].equals("..")) {
return ((MapleData) getParent()).getChildByPath(path.substring(path.indexOf("/") + 1));
}
Node myNode = node;
for (int x = 0; x < segments.length; x++) {
NodeList childNodes = myNode.getChildNodes();
boolean foundChild = false;
for (int i = 0; i < childNodes.getLength(); i++) {
Node childNode = childNodes.item(i);
if (childNode.getNodeType() == Node.ELEMENT_NODE && childNode.getAttributes().getNamedItem("name").getNodeValue().equals(segments[x])) {
myNode = childNode;
foundChild = true;
break;
}
}
if (!foundChild) {
return null;
}
}
XMLDomMapleData ret = new XMLDomMapleData(myNode);
ret.imageDataDir = new File(imageDataDir, getName() + "/" + path).getParentFile();
return ret;
}
@Override
public List<MapleData> getChildren() {
List<MapleData> ret = new ArrayList<MapleData>();
NodeList childNodes = node.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node childNode = childNodes.item(i);
if (childNode.getNodeType() == Node.ELEMENT_NODE) {
XMLDomMapleData child = new XMLDomMapleData(childNode);
child.imageDataDir = new File(imageDataDir, getName());
ret.add(child);
}
}
return ret;
}
@Override
public Object getData() {
NamedNodeMap attributes = node.getAttributes();
MapleDataType type = getType();
switch (type) {
case DOUBLE:
case FLOAT:
case INT:
case SHORT: {
String value = attributes.getNamedItem("value").getNodeValue();
Number nval;
try {
nval = nf.parse(value);
}
catch(java.text.ParseException pe) {
pe.printStackTrace();
nval = 0.0f;
}
switch (type) {
case DOUBLE:
return nval.doubleValue();
case FLOAT:
return nval.floatValue();
case INT:
return nval.intValue();
case SHORT:
return nval.shortValue();
default:
return null;
}
}
case STRING:
case UOL: {
String value = attributes.getNamedItem("value").getNodeValue();
return value;
}
case VECTOR: {
String x = attributes.getNamedItem("x").getNodeValue();
String y = attributes.getNamedItem("y").getNodeValue();
return new Point(Integer.parseInt(x), Integer.parseInt(y));
}
case CANVAS: {
String width = attributes.getNamedItem("width").getNodeValue();
String height = attributes.getNamedItem("height").getNodeValue();
return new FileStoredPngMapleCanvas(Integer.parseInt(width), Integer.parseInt(height), new File(
imageDataDir, getName() + ".png"));
}
default:
return null;
}
}
@Override
public MapleDataType getType() {
String nodeName = node.getNodeName();
if (nodeName.equals("imgdir")) {
return MapleDataType.PROPERTY;
} else if (nodeName.equals("canvas")) {
return MapleDataType.CANVAS;
} else if (nodeName.equals("convex")) {
return MapleDataType.CONVEX;
} else if (nodeName.equals("sound")) {
return MapleDataType.SOUND;
} else if (nodeName.equals("uol")) {
return MapleDataType.UOL;
} else if (nodeName.equals("double")) {
return MapleDataType.DOUBLE;
} else if (nodeName.equals("float")) {
return MapleDataType.FLOAT;
} else if (nodeName.equals("int")) {
return MapleDataType.INT;
} else if (nodeName.equals("short")) {
return MapleDataType.SHORT;
} else if (nodeName.equals("string")) {
return MapleDataType.STRING;
} else if (nodeName.equals("vector")) {
return MapleDataType.VECTOR;
} else if (nodeName.equals("null")) {
return MapleDataType.IMG_0x00;
}
return null;
}
@Override
public MapleDataEntity getParent() {
Node parentNode = node.getParentNode();
if (parentNode.getNodeType() == Node.DOCUMENT_NODE) {
return null;
}
XMLDomMapleData parentData = new XMLDomMapleData(parentNode);
parentData.imageDataDir = imageDataDir.getParentFile();
return parentData;
}
@Override
public String getName() {
return node.getAttributes().getNamedItem("name").getNodeValue();
}
@Override
public Iterator<MapleData> iterator() {
return getChildren().iterator();
}
}

View File

@@ -1,85 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package provider.wz;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import provider.MapleData;
import provider.MapleDataDirectoryEntry;
import provider.MapleDataProvider;
public class XMLWZFile implements MapleDataProvider {
private File root;
private WZDirectoryEntry rootForNavigation;
public XMLWZFile(File fileIn) {
root = fileIn;
rootForNavigation = new WZDirectoryEntry(fileIn.getName(), 0, 0, null);
fillMapleDataEntitys(root, rootForNavigation);
}
private void fillMapleDataEntitys(File lroot, WZDirectoryEntry wzdir) {
for (File file : lroot.listFiles()) {
String fileName = file.getName();
if (file.isDirectory() && !fileName.endsWith(".img")) {
WZDirectoryEntry newDir = new WZDirectoryEntry(fileName, 0, 0, wzdir);
wzdir.addDirectory(newDir);
fillMapleDataEntitys(file, newDir);
} else if (fileName.endsWith(".xml")) {
wzdir.addFile(new WZFileEntry(fileName.substring(0, fileName.length() - 4), 0, 0, wzdir));
}
}
}
@Override
public MapleData getData(String path) {
File dataFile = new File(root, path + ".xml");
File imageDataDir = new File(root, path);
if (!dataFile.exists()) {
return null;//bitches
}
FileInputStream fis;
try {
fis = new FileInputStream(dataFile);
} catch (FileNotFoundException e) {
throw new RuntimeException("Datafile " + path + " does not exist in " + root.getAbsolutePath());
}
final XMLDomMapleData domMapleData;
try {
domMapleData = new XMLDomMapleData(fis, imageDataDir.getParentFile());
} finally {
try {
fis.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return domMapleData;
}
@Override
public MapleDataDirectoryEntry getRoot() {
return rootForNavigation;
}
}

View File

@@ -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<Connection> 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<Connection> {
@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;
}
}
}
}

View File

@@ -1,79 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package tools;
import java.io.ByteArrayOutputStream;
public class HexTool {
private static final char[] HEX = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
private static String toString(byte byteValue) {
int tmp = byteValue << 8;
char[] retstr = new char[]{HEX[(tmp >> 12) & 0x0F], HEX[(tmp >> 8) & 0x0F]};
return String.valueOf(retstr);
}
public static String toString(byte[] bytes) {
StringBuilder hexed = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
hexed.append(toString(bytes[i]));
hexed.append(' ');
}
return hexed.substring(0, hexed.length() - 1);
}
public static byte[] getByteArrayFromHexString(String hex) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int nexti = 0;
int nextb = 0;
boolean highoc = true;
outer:
for (;;) {
int number = -1;
while (number == -1) {
if (nexti == hex.length()) {
break outer;
}
char chr = hex.charAt(nexti);
if (chr >= '0' && chr <= '9') {
number = chr - '0';
} else if (chr >= 'a' && chr <= 'f') {
number = chr - 'a' + 10;
} else if (chr >= 'A' && chr <= 'F') {
number = chr - 'A' + 10;
} else {
number = -1;
}
nexti++;
}
if (highoc) {
nextb = number << 4;
highoc = false;
} else {
nextb |= number;
highoc = true;
baos.write(nextb);
}
}
return baos.toByteArray();
}
}

View File

@@ -1,121 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 ~ 2010 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 tools;
/**
* 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;
}
}

View File

@@ -1,72 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package tools.data.input;
import java.io.IOException;
import tools.HexTool;
public class ByteArrayByteStream implements SeekableInputStreamBytestream {
private int pos = 0;
private long bytesRead = 0;
private byte[] arr;
public ByteArrayByteStream(byte[] arr) {
this.arr = arr;
}
@Override
public long getPosition() {
return pos;
}
@Override
public void seek(long offset) throws IOException {
pos = (int) offset;
}
@Override
public long getBytesRead() {
return bytesRead;
}
@Override
public int readByte() {
bytesRead++;
return ((int) arr[pos++]) & 0xFF;
}
@Override
public String toString() {
String nows = "kevintjuh93 pwns";//I lol'd
if (arr.length - pos > 0) {
byte[] now = new byte[arr.length - pos];
System.arraycopy(arr, pos, now, 0, arr.length - pos);
nows = HexTool.toString(now);
}
return "All: " + HexTool.toString(arr) + "\nNow: " + nows;
}
@Override
public long available() {
return arr.length - pos;
}
}

View File

@@ -1,35 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package tools.data.input;
/**
* Represents an abstract stream of bytes.
*
* @author Frz
* @version 1.0
* @since Revision 323
*/
public interface ByteInputStream {
int readByte();
long getBytesRead();
long available();
}

View File

@@ -1,239 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package tools.data.input;
import java.awt.Point;
import java.io.ByteArrayOutputStream;
/**
* Provides a generic interface to a Little Endian stream of bytes.
*
* @version 1.0
* @author Frz
* @since Revision 323
*/
public class GenericLittleEndianAccessor implements LittleEndianAccessor {
private ByteInputStream bs;
/**
* Class constructor - Wraps the accessor around a stream of bytes.
*
* @param bs The byte stream to wrap the accessor around.
*/
public GenericLittleEndianAccessor(ByteInputStream bs) {
this.bs = bs;
}
/**
* Read a single byte from the stream.
*
* @return The byte read.
* @see tools.data.input.ByteInputStream#readByte
*/
@Override
public byte readByte() {
return (byte) bs.readByte();
}
/**
* Reads an integer from the stream.
*
* @return The integer read.
*/
@Override
public int readInt() {
return bs.readByte() + (bs.readByte() << 8) + (bs.readByte() << 16) + (bs.readByte() << 24);
}
/**
* Reads a short integer from the stream.
*
* @return The short read.
*/
@Override
public short readShort() {
return (short) (bs.readByte() + (bs.readByte() << 8));
}
/**
* Reads a single character from the stream.
*
* @return The character read.
*/
@Override
public char readChar() {
return (char) readShort();
}
/**
* Reads a long integer from the stream.
*
* @return The long integer read.
*/
@Override
public long readLong() {
long byte1 = bs.readByte();
long byte2 = bs.readByte();
long byte3 = bs.readByte();
long byte4 = bs.readByte();
long byte5 = bs.readByte();
long byte6 = bs.readByte();
long byte7 = bs.readByte();
long byte8 = bs.readByte();
return (byte8 << 56) + (byte7 << 48) + (byte6 << 40) + (byte5 << 32) + (byte4 << 24) + (byte3 << 16) + (byte2 << 8) + byte1;
}
/**
* Reads a floating point integer from the stream.
*
* @return The float-type integer read.
*/
@Override
public float readFloat() {
return Float.intBitsToFloat(readInt());
}
/**
* Reads a double-precision integer from the stream.
*
* @return The double-type integer read.
*/
@Override
public double readDouble() {
return Double.longBitsToDouble(readLong());
}
/**
* Reads an ASCII string from the stream with length <code>n</code>.
*
* @param n Number of characters to read.
* @return The string read.
*/
public final String readAsciiString(int n) {
char ret[] = new char[n];
for (int x = 0; x < n; x++) {
ret[x] = (char) readByte();
}
return String.valueOf(ret);
}
/**
* Reads a null-terminated string from the stream.
*
* @return The string read.
*/
public final String readNullTerminatedAsciiString() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte b;
while (true) {
b = readByte();
if (b == 0) {
break;
}
baos.write(b);
}
byte[] buf = baos.toByteArray();
char[] chrBuf = new char[buf.length];
for (int x = 0; x < buf.length; x++) {
chrBuf[x] = (char) buf[x];
}
return String.valueOf(chrBuf);
}
/**
* Gets the number of bytes read from the stream so far.
*
* @return A long integer representing the number of bytes read.
* @see tools.data.input.ByteInputStream#getBytesRead()
*/
public long getBytesRead() {
return bs.getBytesRead();
}
/**
* Reads a MapleStory convention lengthed ASCII string.
* This consists of a short integer telling the length of the string,
* then the string itself.
*
* @return The string read.
*/
@Override
public String readMapleAsciiString() {
return readAsciiString(readShort());
}
/**
* Reads <code>num</code> bytes off the stream.
*
* @param num The number of bytes to read.
* @return An array of bytes with the length of <code>num</code>
*/
@Override
public byte[] read(int num) {
byte[] ret = new byte[num];
for (int x = 0; x < num; x++) {
ret[x] = readByte();
}
return ret;
}
/**
* Reads a MapleStory Position information.
* This consists of 2 short integer.
*
* @return The Position read.
*/
@Override
public final Point readPos() {
final int x = readShort();
final int y = readShort();
return new Point(x, y);
}
/**
* Skips the current position of the stream <code>num</code> bytes ahead.
*
* @param num Number of bytes to skip.
*/
@Override
public void skip(int num) {
for (int x = 0; x < num; x++) {
readByte();
}
}
/**
* @see tools.data.input.ByteInputStream#available
*/
@Override
public long available() {
return bs.available();
}
/**
* @see java.lang.Object#toString
*/
@Override
public String toString() {
return bs.toString();
}
}

View File

@@ -1,91 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package tools.data.input;
import java.io.IOException;
/**
* Provides an abstract accessor to a generic Little Endian byte stream. This
* accessor is seekable.
*
* @author Frz
* @version 1.0
* @since Revision 323
* @see tools.data.input.GenericLittleEndianAccessor
*/
public class GenericSeekableLittleEndianAccessor extends GenericLittleEndianAccessor implements SeekableLittleEndianAccessor {
private SeekableInputStreamBytestream bs;
/**
* Class constructor
* Provide a seekable input stream to wrap this object around.
*
* @param bs The byte stream to wrap this around.
*/
public GenericSeekableLittleEndianAccessor(SeekableInputStreamBytestream bs) {
super(bs);
this.bs = bs;
}
/**
* Seek the pointer to <code>offset</code>
*
* @param offset The offset to seek to.
* @see tools.data.input.SeekableInputStreamBytestream#seek
*/
@Override
public void seek(long offset) {
try {
bs.seek(offset);
} catch (IOException e) {
e.printStackTrace();
System.out.println("Seek failed " + e);
}
}
/**
* Get the current position of the pointer.
*
* @return The current position of the pointer as a long integer.
* @see tools.data.input.SeekableInputStreamBytestream#getPosition
*/
@Override
public long getPosition() {
try {
return bs.getPosition();
} catch (IOException e) {
e.printStackTrace();
System.out.println("getPosition failed" + e);
return -1;
}
}
/**
* Skip <code>num</code> number of bytes in the stream.
*
* @param num The number of bytes to skip.
*/
@Override
public void skip(int num) {
seek(getPosition() + num);
}
}

View File

@@ -1,93 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package tools.data.input;
import java.io.IOException;
import java.io.InputStream;
/**
* Provides an abstract wrapper to a stream of bytes.
*
* @author Frz
* @version 1.0
* @since Revision 323
*/
public class InputStreamByteStream implements ByteInputStream {
private InputStream is;
private long read = 0;
/**
* Class constructor.
* Provide an input stream to wrap this around.
*
* @param is The input stream to wrap this object around.
*/
public InputStreamByteStream(InputStream is) {
this.is = is;
}
/**
* Reads the next byte from the stream.
*
* @return Then next byte in the stream.
*/
@Override
public int readByte() {
int temp;
try {
temp = is.read();
if (temp == -1) {
throw new RuntimeException("EOF");
}
read++;
return temp;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* Gets the number of bytes read from the stream.
*
* @return The number of bytes read as a long integer.
*/
@Override
public long getBytesRead() {
return read;
}
/**
* Returns the number of bytes left in the stream.
*
* @return The number of bytes available for reading as a long integer.
*/
@Override
public long available() {
try {
return is.available();
} catch (IOException e) {
e.printStackTrace();
System.out.println("ERROR" + e);
return 0;
}
}
}

View File

@@ -1,45 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package tools.data.input;
import java.awt.Point;
/**
* @author Frz
*/
public interface LittleEndianAccessor {
byte readByte();
char readChar();
short readShort();
int readInt();
Point readPos();
long readLong();
void skip(int num);
byte[] read(int num);
float readFloat();
double readDouble();
String readAsciiString(int n);
String readNullTerminatedAsciiString();
String readMapleAsciiString();
long getBytesRead();
long available();
}

View File

@@ -1,84 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package tools.data.input;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* Provides an abstract layer to a byte stream. This layer can be accessed
* randomly.
*
* @author Frz
* @version 1.0
* @since Revision 323
*/
public class RandomAccessByteStream implements SeekableInputStreamBytestream {
private RandomAccessFile raf;
private long read = 0;
public RandomAccessByteStream(RandomAccessFile raf) {
super();
this.raf = raf;
}
@Override
public int readByte() {
int temp;
try {
temp = raf.read();
if (temp == -1) {
throw new RuntimeException("EOF");
}
read++;
return temp;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void seek(long offset) throws IOException {
raf.seek(offset);
}
@Override
public long getPosition() throws IOException {
return raf.getFilePointer();
}
@Override
public long getBytesRead() {
return read;
}
@Override
public long available() {
try {
return raf.length() - raf.getFilePointer();
} catch (IOException e) {
e.printStackTrace();
System.out.println("ERROR " + e);
return 0;
}
}
}

View File

@@ -1,51 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package tools.data.input;
import java.io.IOException;
/**
* Provides an abstract interface to a stream of bytes. This stream can be
* seeked.
*
* @author Frz
* @version 1.0
* @since 299
*/
public interface SeekableInputStreamBytestream extends ByteInputStream {
/**
* Seeks the stream by the specified offset.
*
* @param offset
* Number of bytes to seek.
* @throws IOException
*/
void seek(long offset) throws IOException;
/**
* Gets the current position of the stream.
*
* @return The stream position as a long integer.
* @throws IOException
*/
long getPosition() throws IOException;
}

View File

@@ -1,27 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package tools.data.input;
public interface SeekableLittleEndianAccessor extends LittleEndianAccessor {
void seek(long offset);
long getPosition();
}

View File

@@ -1,56 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package tools.data.output;
import java.io.ByteArrayOutputStream;
/**
* Uses a byte array to output a stream of bytes.
*
* @author Frz
* @version 1.0
* @since Revision 352
*/
class BAOSByteOutputStream implements ByteOutputStream {
private ByteArrayOutputStream baos;
/**
* Class constructor - Wraps the stream around a Java BAOS.
*
* @param baos <code>The ByteArrayOutputStream</code> to wrap this around.
*/
BAOSByteOutputStream(ByteArrayOutputStream baos) {
super();
this.baos = baos;
}
/**
* Writes a byte to the stream.
*
* @param b The byte to write to the stream.
* @see tools.data.output.ByteOutputStream#writeByte(byte)
*/
@Override
public void writeByte(byte b) {
baos.write(b);
}
}

View File

@@ -1,38 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package tools.data.output;
/**
* Provides an interface to an output stream of bytes.
*
* @author Frz
* @since Revision 323
* @version 1.0
*/
interface ByteOutputStream {
/**
* Writes a byte to the stream.
*
* @param b The byte to write.
*/
void writeByte(byte b);
}

View File

@@ -1,183 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package tools.data.output;
import java.awt.Point;
import java.nio.charset.Charset;
/**
* Provides a generic writer of a little-endian sequence of bytes.
*
* @author Frz
* @version 1.0
* @since Revision 323
*/
public class GenericLittleEndianWriter implements LittleEndianWriter {
private static Charset ASCII = Charset.forName("US-ASCII");
private ByteOutputStream bos;
/**
* Class constructor - Protected to prevent instantiation with no arguments.
*/
protected GenericLittleEndianWriter() {
// Blah!
}
/**
* Sets the byte-output stream for this instance of the object.
*
* @param bos The new output stream to set.
*/
void setByteOutputStream(ByteOutputStream bos) {
this.bos = bos;
}
/**
* Write an array of bytes to the stream.
*
* @param b The bytes to write.
*/
@Override
public void write(byte[] b) {
for (int x = 0; x < b.length; x++) {
bos.writeByte(b[x]);
}
}
/**
* Write a byte to the stream.
*
* @param b The byte to write.
*/
@Override
public void write(byte b) {
bos.writeByte(b);
}
/**
* Write a byte in integer form to the stream.
*
* @param b The byte as an <code>Integer</code> to write.
*/
@Override
public void write(int b) {
bos.writeByte((byte) b);
}
@Override
public void skip(int b) {
write(new byte[b]);
}
/**
* Write a short integer to the stream.
*
* @param i The short integer to write.
*/
@Override
public void writeShort(int i) {
bos.writeByte((byte) (i & 0xFF));
bos.writeByte((byte) ((i >>> 8) & 0xFF));
}
/**
* Writes an integer to the stream.
*
* @param i The integer to write.
*/
@Override
public void writeInt(int i) {
bos.writeByte((byte) (i & 0xFF));
bos.writeByte((byte) ((i >>> 8) & 0xFF));
bos.writeByte((byte) ((i >>> 16) & 0xFF));
bos.writeByte((byte) ((i >>> 24) & 0xFF));
}
/**
* Writes an ASCII string the the stream.
*
* @param s The ASCII string to write.
*/
@Override
public void writeAsciiString(String s) {
write(s.getBytes(ASCII));
}
/**
* Writes a maple-convention ASCII string to the stream.
*
* @param s The ASCII string to use maple-convention to write.
*/
@Override
public void writeMapleAsciiString(String s) {
writeShort((short) s.length());
writeAsciiString(s);
}
/**
* Writes a null-terminated ASCII string to the stream.
*
* @param s The ASCII string to write.
*/
@Override
public void writeNullTerminatedAsciiString(String s) {
writeAsciiString(s);
write(0);
}
/**
* Write a long integer to the stream.
* @param l The long integer to write.
*/
@Override
public void writeLong(long l) {
bos.writeByte((byte) (l & 0xFF));
bos.writeByte((byte) ((l >>> 8) & 0xFF));
bos.writeByte((byte) ((l >>> 16) & 0xFF));
bos.writeByte((byte) ((l >>> 24) & 0xFF));
bos.writeByte((byte) ((l >>> 32) & 0xFF));
bos.writeByte((byte) ((l >>> 40) & 0xFF));
bos.writeByte((byte) ((l >>> 48) & 0xFF));
bos.writeByte((byte) ((l >>> 56) & 0xFF));
}
/**
* Writes a 2D 4 byte position information
*
* @param s The Point position to write.
*/
@Override
public void writePos(Point s) {
writeShort(s.x);
writeShort(s.y);
}
/**
* Writes a boolean true ? 1 : 0
*
* @param b The boolean to write.
*/
@Override
public void writeBool(final boolean b) {
write(b ? 1 : 0);
}
}

View File

@@ -1,114 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package tools.data.output;
import java.awt.Point;
/**
* Provides an interface to a writer class that writes a little-endian sequence
* of bytes.
*
* @author Frz
* @version 1.0
* @since Revision 323
*/
public interface LittleEndianWriter {
/**
* Write an array of bytes to the sequence.
*
* @param b The bytes to write.
*/
public void write(byte b[]);
/**
* Write a byte to the sequence.
*
* @param b The byte to write.
*/
public void write(byte b);
/**
* Write a byte in integer form to the sequence.
*
* @param b The byte as an <code>Integer</code> to write.
*/
public void write(int b);
public void skip(int b);
/**
* Writes an integer to the sequence.
*
* @param i The integer to write.
*/
public void writeInt(int i);
/**
* Write a short integer to the sequence.
*
* @param s The short integer to write.
*/
public void writeShort(int s);
/**
* Write a long integer to the sequence.
*
* @param l The long integer to write.
*/
public void writeLong(long l);
/**
* Writes an ASCII string the the sequence.
*
* @param s The ASCII string to write.
*/
void writeAsciiString(String s);
/**
* Writes a null-terminated ASCII string to the sequence.
*
* @param s The ASCII string to write.
*/
void writeNullTerminatedAsciiString(String s);
/**
* Writes a maple-convention ASCII string to the sequence.
*
* @param s The ASCII string to use maple-convention to write.
*/
void writeMapleAsciiString(String s);
/**
* Writes a 2D 4 byte position information
*
* @param s The Point position to write.
*/
void writePos(Point s);
/**
* Writes a boolean true ? 1 : 0
*
* @param b The boolean to write.
*/
void writeBool(final boolean b);
}

View File

@@ -1,73 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
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 <http://www.gnu.org/licenses/>.
*/
package tools.data.output;
import java.io.ByteArrayOutputStream;
import tools.HexTool;
/**
* Writes a maplestory-packet little-endian stream of bytes.
*
* @author Frz
* @version 1.0
* @since Revision 352
*/
public class MaplePacketLittleEndianWriter extends GenericLittleEndianWriter {
private ByteArrayOutputStream baos;
/**
* Constructor - initializes this stream with a default size.
*/
public MaplePacketLittleEndianWriter() {
this(32);
}
/**
* Constructor - initializes this stream with size <code>size</code>.
*
* @param size The size of the underlying stream.
*/
public MaplePacketLittleEndianWriter(int size) {
this.baos = new ByteArrayOutputStream(size);
setByteOutputStream(new BAOSByteOutputStream(baos));
}
/**
* Gets a <code>MaplePacket</code> instance representing this
* sequence of bytes.
*
* @return A <code>MaplePacket</code> with the bytes in this stream.
*/
public byte[] getPacket() {
return baos.toByteArray();
}
/**
* Changes this packet into a human-readable hexadecimal stream of bytes.
*
* @return This packet as hex digits.
*/
@Override
public String toString() {
return HexTool.toString(baos.toByteArray());
}
}