Mob banish on touch + GMS-like cosmetics + Clear missing names
Fixed erroneous clean slate scroll block on equipments having certain properties. Implemented a log for bought cash items from Cash Shop. Implemented mob's player banish by touch (e. g. used by mobs from the Hypnotize quest). Thoroughly revised stylist/surgeon NPCs, adding several missing GMS-like cosmetic contents. Thoroughly revised String.wz names having missing item content throughout the WZ files. Revised missing name info for several faces throughout the WZ files. Solved a possible deadlock case related with a player vision's spawn object method. Fixed an issue with "Movement allowed only within account" items being given as "Untradeable" by NPCs. Happy Holidays and Great New Year everyone!!!
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
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();
|
||||
}
|
||||
34
tools/MapleCashCosmeticsFetcher/src/provider/MapleData.java
Normal file
34
tools/MapleCashCosmeticsFetcher/src/provider/MapleData.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
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();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
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();
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
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();
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
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();
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package provider;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import provider.wz.WZFile;
|
||||
import provider.wz.XMLWZFile;
|
||||
|
||||
public class MapleDataProviderFactory {
|
||||
private final static String wzPath = System.getProperty("wzpath");
|
||||
|
||||
private static MapleDataProvider getWZ(File in, boolean provideImages) {
|
||||
if (in.getName().toLowerCase().endsWith("wz") && !in.isDirectory()) {
|
||||
try {
|
||||
return new WZFile(in, provideImages);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Loading WZ File failed", e);
|
||||
}
|
||||
} else {
|
||||
return new XMLWZFile(in);
|
||||
}
|
||||
}
|
||||
|
||||
public static MapleDataProvider getDataProvider(File in) {
|
||||
return getWZ(in, false);
|
||||
}
|
||||
|
||||
public static MapleDataProvider getImageProvidingDataProvider(File in) {
|
||||
return getWZ(in, true);
|
||||
}
|
||||
|
||||
public static File fileInWZPath(String filename) {
|
||||
return new File(wzPath, filename);
|
||||
}
|
||||
}
|
||||
145
tools/MapleCashCosmeticsFetcher/src/provider/MapleDataTool.java
Normal file
145
tools/MapleCashCosmeticsFetcher/src/provider/MapleDataTool.java
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
}
|
||||
61
tools/MapleCashCosmeticsFetcher/src/provider/wz/WZEntry.java
Normal file
61
tools/MapleCashCosmeticsFetcher/src/provider/wz/WZEntry.java
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
}
|
||||
154
tools/MapleCashCosmeticsFetcher/src/provider/wz/WZFile.java
Normal file
154
tools/MapleCashCosmeticsFetcher/src/provider/wz/WZFile.java
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
}
|
||||
118
tools/MapleCashCosmeticsFetcher/src/provider/wz/WZIMGEntry.java
Normal file
118
tools/MapleCashCosmeticsFetcher/src/provider/wz/WZIMGEntry.java
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
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();
|
||||
}
|
||||
}
|
||||
227
tools/MapleCashCosmeticsFetcher/src/provider/wz/WZIMGFile.java
Normal file
227
tools/MapleCashCosmeticsFetcher/src/provider/wz/WZIMGFile.java
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
187
tools/MapleCashCosmeticsFetcher/src/provider/wz/WZTool.java
Normal file
187
tools/MapleCashCosmeticsFetcher/src/provider/wz/WZTool.java
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
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.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import tools.data.input.LittleEndianAccessor;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
/*
|
||||
* 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 = (int) 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 ((int) b);
|
||||
}
|
||||
}
|
||||
|
||||
public static float readFloatValue(LittleEndianAccessor lea) {
|
||||
byte b = lea.readByte();
|
||||
if (b == -128) {
|
||||
return lea.readFloat();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user