Move MapleSkillMakerFetcher to main module

This commit is contained in:
P0nk
2021-07-11 14:38:43 +02:00
parent 91b2901f05
commit 93f067379c
37 changed files with 133 additions and 6028 deletions

View File

@@ -17,7 +17,7 @@
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 mapleskillmakerfetcher;
package tools.mapletools;
import java.util.List;
@@ -25,7 +25,7 @@ import java.util.List;
*
* @author RonanLana
*/
public class MapleMakerItemEntry {
public class MakerItemEntry {
public int id = -1;
public int itemid = -1;
public int reqLevel = -1;
@@ -43,7 +43,7 @@ public class MapleMakerItemEntry {
public List<int[]> recipeList = null;
public List<int[]> randomList = null;
public MapleMakerItemEntry(int id, int itemid, int reqLevel, int reqMakerLevel, int reqItem, int reqMeso, int reqEquip, int catalyst, int quantity, int tuc, int recipeCount, int recipeItem, List<int[]> recipeList, List<int[]> randomList) {
MakerItemEntry(int id, int itemid, int reqLevel, int reqMakerLevel, int reqItem, int reqMeso, int reqEquip, int catalyst, int quantity, int tuc, int recipeCount, int recipeItem, List<int[]> recipeList, List<int[]> randomList) {
this.id = id;
this.itemid = itemid;
this.reqLevel = reqLevel;

View File

@@ -1,78 +1,55 @@
/*
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.
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 mapleskillmakerfetcher;
import provider.wz.WZFiles;
import server.MapleItemInformationProvider;
import tools.DatabaseConnection;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.io.*;
/**
* @author RonanLana
*
* <p>
* The objective of this program is to uncover all maker data from the
* ItemMaker.wz.xml files and generate a SQL file with every data info
* for the Maker DB tables.
*
*/
public class MapleSkillMakerFetcher {
static String host = "jdbc:mysql://localhost:3306/cosmic";
static String driver = "com.mysql.jdbc.Driver";
static String username = "cosmic_server";
static String password = "snailshell";
public class SkillMakerFetcher {
private static final File INPUT_FILE = new File(WZFiles.ETC.getFile(), "ItemMake.img.xml");
private static final File OUTPUT_FILE = ToolConstants.getOutputFile("maker-data.sql");
private static final int INITIAL_STRING_LENGTH = 50;
static String fileName = "../../wz/Etc.wz/ItemMake.img.xml";
static String newFile = "lib/MakerData.sql";
private static PrintWriter printWriter = null;
private static BufferedReader bufferedReader = null;
private static byte status = 0;
private static byte state = 0;
static PrintWriter printWriter = null;
static InputStreamReader fileReader = null;
static BufferedReader bufferedReader = null;
static byte status = 0;
static byte state = 0;
static int initialStringLength = 50;
// maker data fields
static int id = -1;
static int itemid = -1;
static int reqLevel = -1;
static int reqMakerLevel = -1;
static int reqItem = -1;
static int reqMeso = -1;
static int reqEquip = -1;
static int catalyst = -1;
static int quantity = -1;
static int tuc = -1;
static int recipePos = -1;
static int recipeProb = -1;
static int recipeCount = -1;
static int recipeItem = -1;
private static int id = -1;
private static int itemid = -1;
private static int reqLevel = -1;
private static int reqMakerLevel = -1;
private static int reqItem = -1;
private static int reqMeso = -1;
private static int reqEquip = -1;
private static int catalyst = -1;
private static int quantity = -1;
private static int tuc = -1;
private static int recipePos = -1;
private static int recipeProb = -1;
private static int recipeCount = -1;
private static int recipeItem = -1;
static List<int[]> recipeList = null;
static List<int[]> randomList = null;
static List<MapleMakerItemEntry> makerList = new ArrayList<>(100);
static List<MakerItemEntry> makerList = new ArrayList<>(100);
private static void resetMakerDataFields() {
reqLevel = 0;
reqMakerLevel = 0;
@@ -82,16 +59,16 @@ public class MapleSkillMakerFetcher {
catalyst = 0;
quantity = 0;
tuc = 0;
recipePos = 0;
recipeProb = 0;
recipeCount = 0;
recipeItem = 0;
recipeList = null;
randomList = null;
}
private static String getName(String token) {
int i, j;
char[] dest;
@@ -101,16 +78,16 @@ public class MapleSkillMakerFetcher {
i = token.indexOf("\"", i) + 1; //lower bound of the string
j = token.indexOf("\"", i); //upper bound
dest = new char[initialStringLength];
dest = new char[INITIAL_STRING_LENGTH];
token.getChars(i, j, dest, 0);
d = new String(dest);
String s = d.trim();
s.replaceFirst("^0+(?!$)", "");
return(s);
return (s);
}
private static String getValue(String token) {
int i, j;
char[] dest;
@@ -120,157 +97,125 @@ public class MapleSkillMakerFetcher {
i = token.indexOf("\"", i) + 1; //lower bound of the string
j = token.indexOf("\"", i); //upper bound
dest = new char[initialStringLength];
dest = new char[INITIAL_STRING_LENGTH];
token.getChars(i, j, dest, 0);
d = new String(dest);
String s = d.trim();
s.replaceFirst("^0+(?!$)", "");
return(s);
return (s);
}
private static int[] generateRecipeItem() {
int pair[] = new int[2];
int[] pair = new int[2];
pair[0] = recipeItem;
pair[1] = recipeCount;
return pair;
}
private static int[] generateRandomItem() {
int tuple[] = new int[3];
int[] tuple = new int[3];
tuple[0] = recipeItem;
tuple[1] = recipeCount;
tuple[2] = recipeProb;
return tuple;
}
private static void simpleToken(String token) {
if(token.contains("/imgdir")) {
if (token.contains("/imgdir")) {
status -= 1;
}
else if(token.contains("imgdir")) {
} else if (token.contains("imgdir")) {
status += 1;
}
}
private static void forwardCursor(int st) {
String line = null;
try {
while(status >= st && (line = bufferedReader.readLine()) != null) {
while (status >= st && (line = bufferedReader.readLine()) != null) {
simpleToken(line);
}
}
catch(Exception e) {
} catch (Exception e) {
e.printStackTrace();
}
}
private static void translateToken(String token) {
String d;
if(token.contains("/imgdir")) {
if (token.contains("/imgdir")) {
status -= 1;
if(status == 2) { //close item maker data
if (status == 2) { //close item maker data
generateUpdatedItemFee(); // for equipments, this will try to update reqMeso to be conformant with the client.
makerList.add(new MapleMakerItemEntry(id, itemid, reqLevel, reqMakerLevel, reqItem, reqMeso, reqEquip, catalyst, quantity, tuc, recipeCount, recipeItem, recipeList, randomList));
makerList.add(new MakerItemEntry(id, itemid, reqLevel, reqMakerLevel, reqItem, reqMeso, reqEquip, catalyst, quantity, tuc, recipeCount, recipeItem, recipeList, randomList));
resetMakerDataFields();
} else if(status == 4) { //close recipe/random item
if(state == 0) recipeList.add(generateRecipeItem());
else if(state == 1) randomList.add(generateRandomItem());
} else if (status == 4) { //close recipe/random item
if (state == 0) {
recipeList.add(generateRecipeItem());
} else if (state == 1) {
randomList.add(generateRandomItem());
}
}
}
else if(token.contains("imgdir")) {
if(status == 1) { //getting id
} else if (token.contains("imgdir")) {
if (status == 1) { //getting id
d = getName(token);
id = Integer.parseInt(d);
System.out.println("Parsing maker id " + id);
}
else if(status == 2) { //getting target item id
} else if (status == 2) { //getting target item id
d = getName(token);
itemid = Integer.parseInt(d);
}
else if(status == 3) {
} else if (status == 3) {
d = getName(token);
switch(d) {
case "recipe":
switch (d) {
case "recipe" -> {
recipeList = new LinkedList<>();
state = 0;
break;
case "randomReward":
}
case "randomReward" -> {
randomList = new LinkedList<>();
state = 1;
break;
default:
forwardCursor(3); // unused content, read until end of block
break;
}
default -> forwardCursor(3); // unused content, read until end of block
}
}
else if(status == 4) { // inside recipe/random
} else if (status == 4) { // inside recipe/random
d = getName(token);
recipePos = Integer.parseInt(d);
}
status += 1;
} else {
if(status == 3) {
if (status == 3) {
d = getName(token);
switch(d) {
case "itemNum":
quantity = Integer.valueOf(getValue(token));
break;
case "meso":
reqMeso = Integer.valueOf(getValue(token));
break;
case "reqItem":
reqItem = Integer.valueOf(getValue(token));
break;
case "reqLevel":
reqLevel = Integer.valueOf(getValue(token));
break;
case "reqSkillLevel":
reqMakerLevel = Integer.valueOf(getValue(token));
break;
case "tuc":
tuc = Integer.valueOf(getValue(token));
break;
case "catalyst":
catalyst = Integer.valueOf(getValue(token));
break;
case "reqEquip":
reqEquip = Integer.valueOf(getValue(token));
break;
default:
switch (d) {
case "itemNum" -> quantity = Integer.parseInt(getValue(token));
case "meso" -> reqMeso = Integer.parseInt(getValue(token));
case "reqItem" -> reqItem = Integer.parseInt(getValue(token));
case "reqLevel" -> reqLevel = Integer.parseInt(getValue(token));
case "reqSkillLevel" -> reqMakerLevel = Integer.parseInt(getValue(token));
case "tuc" -> tuc = Integer.parseInt(getValue(token));
case "catalyst" -> catalyst = Integer.parseInt(getValue(token));
case "reqEquip" -> reqEquip = Integer.parseInt(getValue(token));
default -> {
System.out.println("Unhandled case: '" + d + "'");
state = 2;
break;
}
}
}
else if(status == 5) { // inside recipe/random item
} else if (status == 5) { // inside recipe/random item
d = getName(token);
if(d.equals("item")) {
if (d.equals("item")) {
recipeItem = Integer.parseInt(getValue(token));
} else {
if(state == 0) {
if (state == 0) {
recipeCount = Integer.parseInt(getValue(token));
} else {
if(d.equals("itemNum")) {
if (d.equals("itemNum")) {
recipeCount = Integer.parseInt(getValue(token));
} else {
recipeProb = Integer.parseInt(getValue(token));
@@ -280,17 +225,17 @@ public class MapleSkillMakerFetcher {
}
}
}
private static void generateUpdatedItemFee() {
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
float adjPrice = reqMeso;
if(itemid < 2000000) {
if (itemid < 2000000) {
Map<String, Integer> stats = ii.getEquipStats(itemid);
if(stats != null) {
if (stats != null) {
int val = itemid / 100000;
if(val == 13 || val == 14) { // is weapon-type
if (val == 13 || val == 14) { // is weapon-type
adjPrice /= 10;
adjPrice += reqMeso;
@@ -314,82 +259,78 @@ public class MapleSkillMakerFetcher {
reqMeso = 1000 * (int) Math.ceil(adjPrice);
}
}
private static void WriteMakerTableFile() {
printWriter.println(" # SQL File autogenerated from the MapleSkillMakerFetcher feature by Ronan Lana.");
printWriter.println(" # Generated data is conformant with the ItemMake.img.xml file used to compile this.");
printWriter.println();
StringBuilder sb_create = new StringBuilder("INSERT IGNORE INTO `makercreatedata` (`id`, `itemid`, `req_level`, `req_maker_level`, `req_meso`, `req_item`, `req_equip`, `catalyst`, `quantity`, `tuc`) VALUES\r\n");
StringBuilder sb_recipe = new StringBuilder("INSERT IGNORE INTO `makerrecipedata` (`itemid`, `req_item`, `count`) VALUES\r\n");
StringBuilder sb_reward = new StringBuilder("INSERT IGNORE INTO `makerrewarddata` (`itemid`, `rewardid`, `quantity`, `prob`) VALUES\r\n");
for(MapleMakerItemEntry it : makerList) {
for (MakerItemEntry it : makerList) {
sb_create.append(" (" + it.id + ", " + it.itemid + ", " + it.reqLevel + ", " + it.reqMakerLevel + ", " + it.reqMeso + ", " + it.reqItem + ", " + it.reqEquip + ", " + it.catalyst + ", " + it.quantity + ", " + it.tuc + "),\r\n");
if(it.recipeList != null) {
for(int[] rit : it.recipeList) {
sb_recipe.append(" (" + it.itemid + ", " + rit[0] + ", " + rit[1] + "),\r\n");
if (it.recipeList != null) {
for (int[] rit : it.recipeList) {
sb_recipe.append(" (" + it.itemid + ", " + rit[0] + ", " + rit[1] + "),\r\n");
}
}
if(it.randomList != null) {
for(int[] rit : it.randomList) {
if (it.randomList != null) {
for (int[] rit : it.randomList) {
sb_reward.append(" (" + it.itemid + ", " + rit[0] + ", " + rit[1] + ", " + rit[2] + "),\r\n");
}
}
}
sb_create.setLength(sb_create.length() - 3);
sb_create.append(";\r\n");
sb_recipe.setLength(sb_recipe.length() - 3);
sb_recipe.append(";\r\n");
sb_reward.setLength(sb_reward.length() - 3);
sb_reward.append(";");
printWriter.println(sb_create);
printWriter.println(sb_recipe);
printWriter.println(sb_reward);
}
private static void WriteMakerTableData() {
private static void writeMakerTableData() {
// This will reference one line at a time
String line = null;
try {
printWriter = new PrintWriter(newFile, "UTF-8");
fileReader = new InputStreamReader(new FileInputStream(fileName), "UTF-8");
printWriter = new PrintWriter(OUTPUT_FILE, StandardCharsets.UTF_8);
InputStreamReader fileReader = new InputStreamReader(new FileInputStream(INPUT_FILE), StandardCharsets.UTF_8);
bufferedReader = new BufferedReader(fileReader);
resetMakerDataFields();
while((line = bufferedReader.readLine()) != null) {
while ((line = bufferedReader.readLine()) != null) {
translateToken(line);
}
WriteMakerTableFile();
printWriter.close();
bufferedReader.close();
fileReader.close();
}
catch(FileNotFoundException ex) {
System.out.println("Unable to open file '" + fileName + "'");
}
catch(IOException ex) {
System.out.println("Error reading file '" + fileName + "'");
}
catch(Exception e) {
} catch (FileNotFoundException ex) {
System.out.println("Unable to open file '" + INPUT_FILE + "'");
} catch (IOException ex) {
System.out.println("Error reading file '" + INPUT_FILE + "'");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
WriteMakerTableData();
DatabaseConnection.initializeConnectionPool(); // Using MapleItemInformationProvider which loads som unrelated things from the db
writeMakerTableData();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,201 +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 mapleskillmakerfetcher;
import java.io.File;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import provider.MapleData;
import provider.MapleDataDirectoryEntry;
import provider.MapleDataFileEntry;
import provider.MapleDataProvider;
import provider.MapleDataProviderFactory;
import provider.MapleDataTool;
/**
*
* @author Ronan
*
*/
public class MapleItemInformationProvider {
private final static String wzPath = "../../wz";
private static MapleItemInformationProvider instance = null;
protected MapleDataProvider itemData;
protected MapleDataProvider equipData;
protected MapleDataProvider stringData;
protected MapleData eqpStringData;
protected Map<Integer, Map<String, Integer>> equipStatsCache = new HashMap<>();
protected Map<Integer, String> nameCache = new HashMap<>();
private MapleItemInformationProvider() {
itemData = MapleDataProviderFactory.getDataProvider(new File(wzPath + "/Item.wz"));
equipData = MapleDataProviderFactory.getDataProvider(new File(wzPath + "/Character.wz"));
stringData = MapleDataProviderFactory.getDataProvider(new File(wzPath + "/String.wz"));
eqpStringData = stringData.getData("Eqp.img");
}
public static MapleItemInformationProvider getInstance() {
if (instance == null) {
instance = new MapleItemInformationProvider();
}
return instance;
}
private MapleData getItemData(int itemId) {
MapleData ret = null;
String idStr = "0" + String.valueOf(itemId);
MapleDataDirectoryEntry root = itemData.getRoot();
for (MapleDataDirectoryEntry topDir : root.getSubdirectories()) {
for (MapleDataFileEntry iFile : topDir.getFiles()) {
if (iFile.getName().equals(idStr.substring(0, 4) + ".img")) {
ret = itemData.getData(topDir.getName() + "/" + iFile.getName());
if (ret == null) {
return null;
}
ret = ret.getChildByPath(idStr);
return ret;
} else if (iFile.getName().equals(idStr.substring(1) + ".img")) {
return itemData.getData(topDir.getName() + "/" + iFile.getName());
}
}
}
root = equipData.getRoot();
for (MapleDataDirectoryEntry topDir : root.getSubdirectories()) {
for (MapleDataFileEntry iFile : topDir.getFiles()) {
if (iFile.getName().equals(idStr + ".img")) {
return equipData.getData(topDir.getName() + "/" + iFile.getName());
}
}
}
return ret;
}
public Map<String, Integer> getEquipStats(int itemId) {
if (equipStatsCache.containsKey(itemId)) {
return equipStatsCache.get(itemId);
}
Map<String, Integer> ret = new LinkedHashMap<>();
MapleData item = getItemData(itemId);
if (item == null) {
return null;
}
MapleData info = item.getChildByPath("info");
if (info == null) {
return null;
}
for (MapleData data : info.getChildren()) {
if (data.getName().startsWith("inc")) {
ret.put(data.getName().substring(3), MapleDataTool.getIntConvert(data));
}
/*else if (data.getName().startsWith("req"))
ret.put(data.getName(), MapleDataTool.getInt(data.getName(), info, 0));*/
}
ret.put("reqJob", MapleDataTool.getInt("reqJob", info, 0));
ret.put("reqLevel", MapleDataTool.getInt("reqLevel", info, 0));
ret.put("reqDEX", MapleDataTool.getInt("reqDEX", info, 0));
ret.put("reqSTR", MapleDataTool.getInt("reqSTR", info, 0));
ret.put("reqINT", MapleDataTool.getInt("reqINT", info, 0));
ret.put("reqLUK", MapleDataTool.getInt("reqLUK", info, 0));
ret.put("reqPOP", MapleDataTool.getInt("reqPOP", info, 0));
ret.put("cash", MapleDataTool.getInt("cash", info, 0));
ret.put("tuc", MapleDataTool.getInt("tuc", info, 0));
ret.put("cursed", MapleDataTool.getInt("cursed", info, 0));
ret.put("success", MapleDataTool.getInt("success", info, 0));
ret.put("fs", MapleDataTool.getInt("fs", info, 0));
equipStatsCache.put(itemId, ret);
return ret;
}
private MapleData getStringData(int itemId) {
String cat = "null";
MapleData theData;
if ((itemId >= 1010000 && itemId < 1040000) || (itemId >= 1122000 && itemId < 1123000) || (itemId >= 1132000 && itemId < 1133000) || (itemId >= 1142000 && itemId < 1143000)) {
theData = eqpStringData;
cat = "Eqp/Accessory";
} else if (itemId >= 1000000 && itemId < 1010000) {
theData = eqpStringData;
cat = "Eqp/Cap";
} else if (itemId >= 1102000 && itemId < 1103000) {
theData = eqpStringData;
cat = "Eqp/Cape";
} else if (itemId >= 1040000 && itemId < 1050000) {
theData = eqpStringData;
cat = "Eqp/Coat";
} else if (itemId >= 20000 && itemId < 22000) {
theData = eqpStringData;
cat = "Eqp/Face";
} else if (itemId >= 1080000 && itemId < 1090000) {
theData = eqpStringData;
cat = "Eqp/Glove";
} else if (itemId >= 30000 && itemId < 35000) {
theData = eqpStringData;
cat = "Eqp/Hair";
} else if (itemId >= 1050000 && itemId < 1060000) {
theData = eqpStringData;
cat = "Eqp/Longcoat";
} else if (itemId >= 1060000 && itemId < 1070000) {
theData = eqpStringData;
cat = "Eqp/Pants";
} else if (itemId >= 1802000 && itemId < 1842000) {
theData = eqpStringData;
cat = "Eqp/PetEquip";
} else if (itemId >= 1112000 && itemId < 1120000) {
theData = eqpStringData;
cat = "Eqp/Ring";
} else if (itemId >= 1092000 && itemId < 1100000) {
theData = eqpStringData;
cat = "Eqp/Shield";
} else if (itemId >= 1070000 && itemId < 1080000) {
theData = eqpStringData;
cat = "Eqp/Shoes";
} else if (itemId >= 1900000 && itemId < 2000000) {
theData = eqpStringData;
cat = "Eqp/Taming";
} else if (itemId >= 1300000 && itemId < 1800000) {
theData = eqpStringData;
cat = "Eqp/Weapon";
} else {
return null;
}
if (cat.equalsIgnoreCase("null")) {
return theData.getChildByPath(String.valueOf(itemId));
} else {
return theData.getChildByPath(cat + "/" + itemId);
}
}
public String getName(int itemId) {
if (nameCache.containsKey(itemId)) {
return nameCache.get(itemId);
}
MapleData strings = getStringData(itemId);
if (strings == null) {
return null;
}
String ret = MapleDataTool.getString("name", strings, null);
nameCache.put(itemId, ret);
return ret;
}
}

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 = "../../wz";
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,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,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();
}