source
Source for my MapleSolaxiaV2 (v83 MapleStory).
This commit is contained in:
149
src/tools/ArrayMap.java
Normal file
149
src/tools/ArrayMap.java
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
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.util.AbstractMap;
|
||||
import java.util.AbstractSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class ArrayMap<K, V> extends AbstractMap<K, V> {
|
||||
|
||||
static class Entry<K, V> implements Map.Entry<K, V> {
|
||||
protected K key;
|
||||
protected V value;
|
||||
|
||||
public Entry(K key, V value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public K getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V setValue(V newValue) {
|
||||
V oldValue = value;
|
||||
value = newValue;
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof Map.Entry<?, ?>)) {
|
||||
return false;
|
||||
}
|
||||
Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
|
||||
return (key == null ? e.getKey() == null : key.equals(e.getKey())) && (value == null ? e.getValue() == null : value.equals(e.getValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int keyHash = (key == null ? 0 : key.hashCode());
|
||||
int valueHash = (value == null ? 0 : value.hashCode());
|
||||
return keyHash ^ valueHash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return key + "=" + value;
|
||||
}
|
||||
}
|
||||
private Set<? extends java.util.Map.Entry<K, V>> entries = null;
|
||||
private ArrayList<Entry<K, V>> list;
|
||||
|
||||
public ArrayMap() {
|
||||
list = new ArrayList<>();
|
||||
}
|
||||
|
||||
public ArrayMap(Map<K, V> map) {
|
||||
list = new ArrayList<>();
|
||||
putAll(map);
|
||||
}
|
||||
|
||||
public ArrayMap(int initialCapacity) {
|
||||
list = new ArrayList<>(initialCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings ("unchecked")
|
||||
public Set<java.util.Map.Entry<K, V>> entrySet() {
|
||||
if (entries == null) {
|
||||
entries = new AbstractSet<Entry<K, V>>() {
|
||||
@Override
|
||||
public void clear() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Entry<K, V>> iterator() {
|
||||
return list.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return list.size();
|
||||
}
|
||||
};
|
||||
}
|
||||
return (Set<java.util.Map.Entry<K, V>>) entries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V put(K key, V value) {
|
||||
int size = list.size();
|
||||
Entry<K, V> entry = null;
|
||||
int i;
|
||||
if (key == null) {
|
||||
for (i = 0; i < size; i++) {
|
||||
entry = (list.get(i));
|
||||
if (entry.getKey() == null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < size; i++) {
|
||||
entry = (list.get(i));
|
||||
if (key.equals(entry.getKey())) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
V oldValue = null;
|
||||
if (i < size) {
|
||||
oldValue = entry.getValue();
|
||||
entry.setValue(value);
|
||||
} else {
|
||||
list.add(new Entry<>(key, value));
|
||||
}
|
||||
return oldValue;
|
||||
}
|
||||
}
|
||||
50
src/tools/DatabaseConnection.java
Normal file
50
src/tools/DatabaseConnection.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package tools;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import constants.ServerConstants;
|
||||
|
||||
/**
|
||||
* @author Frz (Big Daddy)
|
||||
* @author The Real Spookster (some modifications to this beautiful code)
|
||||
*/
|
||||
public class DatabaseConnection {
|
||||
|
||||
public static final int RETURN_GENERATED_KEYS = 1;
|
||||
|
||||
private static ThreadLocal<Connection> con = new ThreadLocalConnection();
|
||||
|
||||
public static Connection getConnection() {
|
||||
Connection c = con.get();
|
||||
try {
|
||||
c.getMetaData();
|
||||
} catch (SQLException e) { // connection is dead, therefore discard old object 5ever
|
||||
con.remove();
|
||||
c = con.get();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
private static class ThreadLocalConnection extends ThreadLocal<Connection> {
|
||||
|
||||
@Override
|
||||
protected Connection initialValue() {
|
||||
try {
|
||||
Class.forName("com.mysql.jdbc.Driver"); // touch the mysql driver
|
||||
} catch (ClassNotFoundException e) {
|
||||
System.out.println("[SEVERE] SQL Driver Not Found. Consider death by clams.");
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return DriverManager.getConnection(ServerConstants.DB_URL, ServerConstants.DB_USER, ServerConstants.DB_PASS);
|
||||
} catch (SQLException e) {
|
||||
System.out.println("[SEVERE] Unable to make database connection.");
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
175
src/tools/FilePrinter.java
Normal file
175
src/tools/FilePrinter.java
Normal file
@@ -0,0 +1,175 @@
|
||||
package tools;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
|
||||
public class FilePrinter {
|
||||
|
||||
public static final String
|
||||
ACCOUNT_STUCK = "accountStuck.txt",
|
||||
EXCEPTION_CAUGHT = "exceptionCaught.txt",
|
||||
CLIENT_START = "clientStartError.txt",
|
||||
ADD_PLAYER = "addPlayer.txt",
|
||||
MAPLE_MAP = "mapleMap.txt",
|
||||
ERROR38 = "error38.txt",
|
||||
PACKET_LOG = "log.txt",
|
||||
EXCEPTION = "exceptions.txt",
|
||||
PACKET_HANDLER = "PacketHandler/",
|
||||
PORTAL = "portals/",
|
||||
NPC = "npcs/",
|
||||
INVOCABLE = "invocable/",
|
||||
REACTOR = "reactors/",
|
||||
QUEST = "quests/",
|
||||
ITEM = "items/",
|
||||
MOB_MOVEMENT = "mobmovement.txt",
|
||||
MAP_SCRIPT = "mapscript/",
|
||||
DIRECTION = "directions/",
|
||||
SAVE_CHAR = "saveToDB.txt",
|
||||
INSERT_CHAR = "insertCharacter.txt",
|
||||
LOAD_CHAR = "loadCharFromDB.txt",
|
||||
UNHANDLED_EVENT = "doesNotExist.txt",
|
||||
SESSION = "sessions.txt",
|
||||
EXPLOITS = "exploits/",
|
||||
STORAGE = "storage/",
|
||||
PACKET_LOGS = "packetlogs/",
|
||||
DELETED_CHARACTERS = "deletedchars/",
|
||||
FREDRICK = "fredrick/",
|
||||
NPC_UNCODED = "uncodedNPCs.txt",
|
||||
QUEST_UNCODED = "uncodedQuests.txt",
|
||||
SAVING_CHARACTER = "saveChar.txt";//more to come (maps)
|
||||
private static final SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
|
||||
private static final String FILE_PATH = "logs/" + sdf.format(Calendar.getInstance().getTime()) + "/";// + sdf.format(Calendar.getInstance().getTime()) + "/"
|
||||
private static final String ERROR = "error/";
|
||||
|
||||
public static void printError(final String name, final Throwable t) {
|
||||
System.out.println("Error thrown: " + name);
|
||||
System.out.println(getString(t));
|
||||
FileOutputStream out = null;
|
||||
final String file = FILE_PATH + ERROR + name;
|
||||
try {
|
||||
File outputFile = new File(file);
|
||||
if (outputFile.getParentFile() != null) {
|
||||
outputFile.getParentFile().mkdirs();
|
||||
}
|
||||
out = new FileOutputStream(file, true);
|
||||
out.write(getString(t).getBytes());
|
||||
out.write("\n---------------------------------\r\n".getBytes());
|
||||
} catch (IOException ess) {
|
||||
} finally {
|
||||
try {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void printError(final String name, final Throwable t, final String info) {
|
||||
System.out.println("Error thrown: " + name);
|
||||
System.out.println(getString(t));
|
||||
FileOutputStream out = null;
|
||||
final String file = FILE_PATH + ERROR + name;
|
||||
try {
|
||||
File outputFile = new File(file);
|
||||
if (outputFile.getParentFile() != null) {
|
||||
outputFile.getParentFile().mkdirs();
|
||||
}
|
||||
out = new FileOutputStream(file, true);
|
||||
out.write((info + "\r\n").getBytes());
|
||||
out.write(getString(t).getBytes());
|
||||
out.write("\n---------------------------------\r\n".getBytes());
|
||||
} catch (IOException ess) {
|
||||
} finally {
|
||||
try {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void printError(final String name, final String s) {
|
||||
System.out.println("Error thrown: " + name);
|
||||
System.out.println(s);
|
||||
FileOutputStream out = null;
|
||||
final String file = FILE_PATH + ERROR + name;
|
||||
try {
|
||||
File outputFile = new File(file);
|
||||
if (outputFile.getParentFile() != null) {
|
||||
outputFile.getParentFile().mkdirs();
|
||||
}
|
||||
out = new FileOutputStream(file, true);
|
||||
out.write(s.getBytes());
|
||||
//out.write("\n---------------------------------\n".getBytes());
|
||||
} catch (IOException ess) {
|
||||
} finally {
|
||||
try {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void print(final String name, final String s) {
|
||||
print(name, s, true);
|
||||
}
|
||||
|
||||
public static void print(final String name, final String s, boolean line) {
|
||||
System.out.println("Error thrown: " + name);
|
||||
System.out.println(s);
|
||||
FileOutputStream out = null;
|
||||
String file = FILE_PATH + name;
|
||||
try {
|
||||
File outputFile = new File(file);
|
||||
if (outputFile.getParentFile() != null) {
|
||||
outputFile.getParentFile().mkdirs();
|
||||
}
|
||||
out = new FileOutputStream(file, true);
|
||||
out.write(s.getBytes());
|
||||
out.write("\r\n".getBytes());
|
||||
if (line) {
|
||||
out.write("---------------------------------\r\n".getBytes());
|
||||
}
|
||||
} catch (IOException ess) {
|
||||
} finally {
|
||||
try {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getString(final Throwable e) {
|
||||
String retValue = null;
|
||||
StringWriter sw = null;
|
||||
PrintWriter pw = null;
|
||||
try {
|
||||
sw = new StringWriter();
|
||||
pw = new PrintWriter(sw);
|
||||
e.printStackTrace(pw);
|
||||
retValue = sw.toString();
|
||||
} finally {
|
||||
try {
|
||||
if (pw != null) {
|
||||
pw.close();
|
||||
}
|
||||
if (sw != null) {
|
||||
sw.close();
|
||||
}
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
}
|
||||
79
src/tools/HexTool.java
Normal file
79
src/tools/HexTool.java
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
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();
|
||||
}
|
||||
}
|
||||
74
src/tools/LogHelper.java
Normal file
74
src/tools/LogHelper.java
Normal file
@@ -0,0 +1,74 @@
|
||||
package tools;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import net.server.Server;
|
||||
import net.server.channel.Channel;
|
||||
import net.server.world.MapleParty;
|
||||
import net.server.world.MaplePartyCharacter;
|
||||
import server.MapleItemInformationProvider;
|
||||
import server.MapleTrade;
|
||||
import server.expeditions.MapleExpedition;
|
||||
import client.MapleCharacter;
|
||||
import client.inventory.Item;
|
||||
|
||||
public class LogHelper {
|
||||
|
||||
public static void logTrade(MapleTrade trade1, MapleTrade trade2) {
|
||||
String name1 = trade1.getChr().getName();
|
||||
String name2 = trade2.getChr().getName();
|
||||
String log = "TRADE BETWEEN " + name1 + " AND " + name2 + "\r\n";
|
||||
//Trade 1 to trade 2
|
||||
log += trade1.getExchangeMesos() + " mesos from " + name1 + " to " + name2 + " \r\n";
|
||||
for (Item item : trade1.getItems()){
|
||||
String itemName = MapleItemInformationProvider.getInstance().getName(item.getItemId()) + "(" + item.getItemId() + ")";
|
||||
log += item.getQuantity() + " " + itemName + " from " + name1 + " to " + name2 + " \r\n";;
|
||||
}
|
||||
//Trade 2 to trade 1
|
||||
log += trade2.getExchangeMesos() + " mesos from " + name2 + " to " + name1 + " \r\n";
|
||||
for (Item item : trade2.getItems()){
|
||||
String itemName = MapleItemInformationProvider.getInstance().getName(item.getItemId()) + "(" + item.getItemId() + ")";
|
||||
log += item.getQuantity() + " " + itemName + " from " + name2 + " to " + name1 + " \r\n";;
|
||||
}
|
||||
log += "\r\n\r\n";
|
||||
FilePrinter.printError("trades.txt", log);
|
||||
}
|
||||
|
||||
public static void logExpedition(MapleExpedition expedition) {
|
||||
Server.getInstance().broadcastGMMessage(MaplePacketCreator.serverNotice(6, expedition.getType().toString() + " Expedition with leader " + expedition.getLeader().getName() + " finished after " + getTimeString(expedition.getStartTime())));
|
||||
|
||||
String log = expedition.getType().toString() + " EXPEDITION\r\n";
|
||||
log += getTimeString(expedition.getStartTime()) + "\r\n";
|
||||
|
||||
for (MapleCharacter member : expedition.getMembers()){
|
||||
log += ">>" + member.getName() + "\r\n";
|
||||
}
|
||||
log += "BOSS KILLS\r\n";
|
||||
for (String message: expedition.getBossLogs()){
|
||||
log += message;
|
||||
}
|
||||
log += "\r\n\r\n";
|
||||
FilePrinter.printError("expeditions.txt", log);
|
||||
}
|
||||
|
||||
public static String getTimeString(long then){
|
||||
long duration = System.currentTimeMillis() - then;
|
||||
int seconds = (int) (duration / 1000) % 60 ;
|
||||
int minutes = (int) ((duration / (1000*60)) % 60);
|
||||
return minutes + " Minutes and " + seconds + " Seconds";
|
||||
}
|
||||
|
||||
public static void logLeaf(MapleCharacter player, boolean gotPrize, String operation) {
|
||||
String timeStamp = new SimpleDateFormat("dd-M-yyyy hh:mm:ss").format(new Date());
|
||||
String log = player.getName() + (gotPrize ? " used a maple leaf to buy " + operation : " redeemed " + operation + " VP for a leaf") + " - " + timeStamp + "\r\n";
|
||||
FilePrinter.printError("mapleleaves.txt", log);
|
||||
}
|
||||
|
||||
public static void logGacha(MapleCharacter player, int itemid, String map) {
|
||||
String itemName = MapleItemInformationProvider.getInstance().getName(itemid);
|
||||
String timeStamp = new SimpleDateFormat("dd-M-yyyy hh:mm:ss").format(new Date());
|
||||
String log = player.getName() + " got a " + itemName + "(" + itemid + ") from the " + map + " gachapon. - " + timeStamp + "\r\n";
|
||||
FilePrinter.printError("gachapon.txt", log);
|
||||
}
|
||||
}
|
||||
194
src/tools/MapleAESOFB.java
Normal file
194
src/tools/MapleAESOFB.java
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
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.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;
|
||||
|
||||
public class MapleAESOFB {
|
||||
private byte iv[];
|
||||
private Cipher cipher;
|
||||
private short mapleVersion;
|
||||
private static final byte[] funnyBytes = new byte[]{(byte) 0xEC, (byte) 0x3F, (byte) 0x77, (byte) 0xA4, (byte) 0x45, (byte) 0xD0, (byte) 0x71, (byte) 0xBF, (byte) 0xB7, (byte) 0x98, (byte) 0x20, (byte) 0xFC,
|
||||
(byte) 0x4B, (byte) 0xE9, (byte) 0xB3, (byte) 0xE1, (byte) 0x5C, (byte) 0x22, (byte) 0xF7, (byte) 0x0C, (byte) 0x44, (byte) 0x1B, (byte) 0x81, (byte) 0xBD, (byte) 0x63, (byte) 0x8D, (byte) 0xD4, (byte) 0xC3,
|
||||
(byte) 0xF2, (byte) 0x10, (byte) 0x19, (byte) 0xE0, (byte) 0xFB, (byte) 0xA1, (byte) 0x6E, (byte) 0x66, (byte) 0xEA, (byte) 0xAE, (byte) 0xD6, (byte) 0xCE, (byte) 0x06, (byte) 0x18, (byte) 0x4E, (byte) 0xEB,
|
||||
(byte) 0x78, (byte) 0x95, (byte) 0xDB, (byte) 0xBA, (byte) 0xB6, (byte) 0x42, (byte) 0x7A, (byte) 0x2A, (byte) 0x83, (byte) 0x0B, (byte) 0x54, (byte) 0x67, (byte) 0x6D, (byte) 0xE8, (byte) 0x65, (byte) 0xE7,
|
||||
(byte) 0x2F, (byte) 0x07, (byte) 0xF3, (byte) 0xAA, (byte) 0x27, (byte) 0x7B, (byte) 0x85, (byte) 0xB0, (byte) 0x26, (byte) 0xFD, (byte) 0x8B, (byte) 0xA9, (byte) 0xFA, (byte) 0xBE, (byte) 0xA8, (byte) 0xD7,
|
||||
(byte) 0xCB, (byte) 0xCC, (byte) 0x92, (byte) 0xDA, (byte) 0xF9, (byte) 0x93, (byte) 0x60, (byte) 0x2D, (byte) 0xDD, (byte) 0xD2, (byte) 0xA2, (byte) 0x9B, (byte) 0x39, (byte) 0x5F, (byte) 0x82, (byte) 0x21,
|
||||
(byte) 0x4C, (byte) 0x69, (byte) 0xF8, (byte) 0x31, (byte) 0x87, (byte) 0xEE, (byte) 0x8E, (byte) 0xAD, (byte) 0x8C, (byte) 0x6A, (byte) 0xBC, (byte) 0xB5, (byte) 0x6B, (byte) 0x59, (byte) 0x13, (byte) 0xF1,
|
||||
(byte) 0x04, (byte) 0x00, (byte) 0xF6, (byte) 0x5A, (byte) 0x35, (byte) 0x79, (byte) 0x48, (byte) 0x8F, (byte) 0x15, (byte) 0xCD, (byte) 0x97, (byte) 0x57, (byte) 0x12, (byte) 0x3E, (byte) 0x37, (byte) 0xFF,
|
||||
(byte) 0x9D, (byte) 0x4F, (byte) 0x51, (byte) 0xF5, (byte) 0xA3, (byte) 0x70, (byte) 0xBB, (byte) 0x14, (byte) 0x75, (byte) 0xC2, (byte) 0xB8, (byte) 0x72, (byte) 0xC0, (byte) 0xED, (byte) 0x7D, (byte) 0x68,
|
||||
(byte) 0xC9, (byte) 0x2E, (byte) 0x0D, (byte) 0x62, (byte) 0x46, (byte) 0x17, (byte) 0x11, (byte) 0x4D, (byte) 0x6C, (byte) 0xC4, (byte) 0x7E, (byte) 0x53, (byte) 0xC1, (byte) 0x25, (byte) 0xC7, (byte) 0x9A,
|
||||
(byte) 0x1C, (byte) 0x88, (byte) 0x58, (byte) 0x2C, (byte) 0x89, (byte) 0xDC, (byte) 0x02, (byte) 0x64, (byte) 0x40, (byte) 0x01, (byte) 0x5D, (byte) 0x38, (byte) 0xA5, (byte) 0xE2, (byte) 0xAF, (byte) 0x55,
|
||||
(byte) 0xD5, (byte) 0xEF, (byte) 0x1A, (byte) 0x7C, (byte) 0xA7, (byte) 0x5B, (byte) 0xA6, (byte) 0x6F, (byte) 0x86, (byte) 0x9F, (byte) 0x73, (byte) 0xE6, (byte) 0x0A, (byte) 0xDE, (byte) 0x2B, (byte) 0x99,
|
||||
(byte) 0x4A, (byte) 0x47, (byte) 0x9C, (byte) 0xDF, (byte) 0x09, (byte) 0x76, (byte) 0x9E, (byte) 0x30, (byte) 0x0E, (byte) 0xE4, (byte) 0xB2, (byte) 0x94, (byte) 0xA0, (byte) 0x3B, (byte) 0x34, (byte) 0x1D,
|
||||
(byte) 0x28, (byte) 0x0F, (byte) 0x36, (byte) 0xE3, (byte) 0x23, (byte) 0xB4, (byte) 0x03, (byte) 0xD8, (byte) 0x90, (byte) 0xC8, (byte) 0x3C, (byte) 0xFE, (byte) 0x5E, (byte) 0x32, (byte) 0x24, (byte) 0x50,
|
||||
(byte) 0x1F, (byte) 0x3A, (byte) 0x43, (byte) 0x8A, (byte) 0x96, (byte) 0x41, (byte) 0x74, (byte) 0xAC, (byte) 0x52, (byte) 0x33, (byte) 0xF0, (byte) 0xD9, (byte) 0x29, (byte) 0x80, (byte) 0xB1, (byte) 0x16,
|
||||
(byte) 0xD3, (byte) 0xAB, (byte) 0x91, (byte) 0xB9, (byte) 0x84, (byte) 0x7F, (byte) 0x61, (byte) 0x1E, (byte) 0xCF, (byte) 0xC5, (byte) 0xD1, (byte) 0x56, (byte) 0x3D, (byte) 0xCA, (byte) 0xF4, (byte) 0x05,
|
||||
(byte) 0xC6, (byte) 0xE5, (byte) 0x08, (byte) 0x49};
|
||||
|
||||
public MapleAESOFB(byte key[], byte iv[], short mapleVersion) {
|
||||
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
|
||||
try {
|
||||
cipher = Cipher.getInstance("AES");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
System.out.println("ERROR " + e);
|
||||
} catch (NoSuchPaddingException e) {
|
||||
System.out.println("ERROR " + e);
|
||||
}
|
||||
try {
|
||||
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
|
||||
} catch (InvalidKeyException e) {
|
||||
}
|
||||
this.setIv(iv);
|
||||
this.mapleVersion = (short) (((mapleVersion >> 8) & 0xFF) | ((mapleVersion << 8) & 0xFF00));
|
||||
}
|
||||
|
||||
private void setIv(byte[] iv) {
|
||||
this.iv = iv;
|
||||
}
|
||||
|
||||
private static byte[] multiplyBytes(byte[] in, int count, int mul) {
|
||||
byte[] ret = new byte[count * mul];
|
||||
for (int x = 0; x < count * mul; x++) {
|
||||
ret[x] = in[x % count];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public synchronized byte[] crypt(byte[] data) {
|
||||
int remaining = data.length;
|
||||
int llength = 0x5B0;
|
||||
int start = 0;
|
||||
while (remaining > 0) {
|
||||
byte[] myIv = multiplyBytes(this.iv, 4, 4);
|
||||
if (remaining < llength) {
|
||||
llength = remaining;
|
||||
}
|
||||
for (int x = start; x < (start + llength); x++) {
|
||||
if ((x - start) % myIv.length == 0) {
|
||||
try {
|
||||
byte[] newIv = cipher.doFinal(myIv);
|
||||
for (int j = 0; j < myIv.length; j++) {
|
||||
myIv[j] = newIv[j];
|
||||
}
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
} catch (BadPaddingException e) {
|
||||
}
|
||||
}
|
||||
data[x] ^= myIv[(x - start) % myIv.length];
|
||||
}
|
||||
start += llength;
|
||||
remaining -= llength;
|
||||
llength = 0x5B4;
|
||||
}
|
||||
updateIv();
|
||||
return data;
|
||||
}
|
||||
|
||||
private synchronized void updateIv() {
|
||||
this.iv = getNewIv(this.iv);
|
||||
}
|
||||
|
||||
public byte[] getPacketHeader(int length) {
|
||||
int iiv = (iv[3]) & 0xFF;
|
||||
iiv |= (iv[2] << 8) & 0xFF00;
|
||||
iiv ^= mapleVersion;
|
||||
int mlength = ((length << 8) & 0xFF00) | (length >>> 8);
|
||||
int xoredIv = iiv ^ mlength;
|
||||
byte[] ret = new byte[4];
|
||||
ret[0] = (byte) ((iiv >>> 8) & 0xFF);
|
||||
ret[1] = (byte) (iiv & 0xFF);
|
||||
ret[2] = (byte) ((xoredIv >>> 8) & 0xFF);
|
||||
ret[3] = (byte) (xoredIv & 0xFF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static int getPacketLength(int packetHeader) {
|
||||
int packetLength = ((packetHeader >>> 16) ^ (packetHeader & 0xFFFF));
|
||||
packetLength = ((packetLength << 8) & 0xFF00) | ((packetLength >>> 8) & 0xFF);
|
||||
return packetLength;
|
||||
}
|
||||
|
||||
public boolean checkPacket(byte[] packet) {
|
||||
return ((((packet[0] ^ iv[2]) & 0xFF) == ((mapleVersion >> 8) & 0xFF)) && (((packet[1] ^ iv[3]) & 0xFF) == (mapleVersion & 0xFF)));
|
||||
}
|
||||
|
||||
public boolean checkPacket(int packetHeader) {
|
||||
byte packetHeaderBuf[] = new byte[2];
|
||||
packetHeaderBuf[0] = (byte) ((packetHeader >> 24) & 0xFF);
|
||||
packetHeaderBuf[1] = (byte) ((packetHeader >> 16) & 0xFF);
|
||||
return checkPacket(packetHeaderBuf);
|
||||
}
|
||||
|
||||
public static byte[] getNewIv(byte oldIv[]) {
|
||||
byte[] in = {(byte) 0xf2, 0x53, (byte) 0x50, (byte) 0xc6};
|
||||
for (int x = 0; x < 4; x++) {
|
||||
funnyShit(oldIv[x], in);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IV: " + HexTool.toString(this.iv);
|
||||
}
|
||||
|
||||
private static byte[] funnyShit(byte inputByte, byte[] in) {
|
||||
byte elina = in[1];
|
||||
byte anna = inputByte;
|
||||
byte moritz = funnyBytes[(int) elina & 0xFF];
|
||||
moritz -= inputByte;
|
||||
in[0] += moritz;
|
||||
moritz = in[2];
|
||||
moritz ^= funnyBytes[(int) anna & 0xFF];
|
||||
elina -= (int) moritz & 0xFF;
|
||||
in[1] = elina;
|
||||
elina = in[3];
|
||||
moritz = elina;
|
||||
elina -= (int) in[0] & 0xFF;
|
||||
moritz = funnyBytes[(int) moritz & 0xFF];
|
||||
moritz += inputByte;
|
||||
moritz ^= in[2];
|
||||
in[2] = moritz;
|
||||
elina += (int) funnyBytes[(int) anna & 0xFF] & 0xFF;
|
||||
in[3] = elina;
|
||||
int merry = ((int) in[0]) & 0xFF;
|
||||
merry |= (in[1] << 8) & 0xFF00;
|
||||
merry |= (in[2] << 16) & 0xFF0000;
|
||||
merry |= (in[3] << 24) & 0xFF000000;
|
||||
int ret_value = merry;
|
||||
ret_value = ret_value >>> 0x1d;
|
||||
merry = merry << 3;
|
||||
ret_value = ret_value | merry;
|
||||
in[0] = (byte) (ret_value & 0xFF);
|
||||
in[1] = (byte) ((ret_value >> 8) & 0xFF);
|
||||
in[2] = (byte) ((ret_value >> 16) & 0xFF);
|
||||
in[3] = (byte) ((ret_value >> 24) & 0xFF);
|
||||
return in;
|
||||
}
|
||||
}
|
||||
78
src/tools/MapleLogger.java
Normal file
78
src/tools/MapleLogger.java
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 ~ 2010 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation. You may not use, modify
|
||||
or distribute this program under any other version of the
|
||||
GNU Affero General Public License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package tools;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.RecvOpcode;
|
||||
import client.MapleClient;
|
||||
|
||||
/**
|
||||
* Logs packets to console and file.
|
||||
*
|
||||
* @author SharpAceX (Alan)
|
||||
*/
|
||||
|
||||
public class MapleLogger {
|
||||
|
||||
public static List<String> monitored = new ArrayList<>();
|
||||
public static List<String> ignored = new ArrayList<>();
|
||||
|
||||
public static void logRecv(MapleClient c, short packetId, Object message) {
|
||||
if (c.getPlayer() == null){
|
||||
return;
|
||||
}
|
||||
if (!monitored.contains(c.getPlayer().getName())){
|
||||
return;
|
||||
}
|
||||
RecvOpcode op = getOpcodeFromValue(packetId);
|
||||
if (isRecvBlocked(op)){
|
||||
return;
|
||||
}
|
||||
String packet = op.toString() + "\r\n" + HexTool.toString((byte[]) message);
|
||||
FilePrinter.printError(FilePrinter.PACKET_LOGS + c.getAccountName() + "-" + c.getPlayer().getName() + ".txt", packet + "\r\n\r\n");
|
||||
}
|
||||
|
||||
private static final boolean isRecvBlocked(RecvOpcode op){
|
||||
switch(op){
|
||||
case MOVE_PLAYER:
|
||||
case GENERAL_CHAT:
|
||||
case TAKE_DAMAGE:
|
||||
case MOVE_PET:
|
||||
case MOVE_LIFE:
|
||||
case NPC_ACTION:
|
||||
case FACE_EXPRESSION:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static final RecvOpcode getOpcodeFromValue(int value){
|
||||
for (RecvOpcode op : RecvOpcode.values()){
|
||||
if (op.getValue() == value){
|
||||
return op;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
6986
src/tools/MaplePacketCreator.java
Normal file
6986
src/tools/MaplePacketCreator.java
Normal file
File diff suppressed because it is too large
Load Diff
121
src/tools/Pair.java
Normal file
121
src/tools/Pair.java
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 ~ 2010 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation. You may not use, modify
|
||||
or distribute this program under any other version of the
|
||||
GNU Affero General Public License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package tools;
|
||||
|
||||
/**
|
||||
* Represents a pair of values.
|
||||
*
|
||||
* @author Frz
|
||||
* @since Revision 333
|
||||
* @version 1.0
|
||||
*
|
||||
* @param <E> The type of the left value.
|
||||
* @param <F> The type of the right value.
|
||||
*/
|
||||
public class Pair<E, F> {
|
||||
|
||||
public E left;
|
||||
public F right;
|
||||
|
||||
/**
|
||||
* Class constructor - pairs two objects together.
|
||||
*
|
||||
* @param left The left object.
|
||||
* @param right The right object.
|
||||
*/
|
||||
public Pair(E left, F right) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the left value.
|
||||
*
|
||||
* @return The left value.
|
||||
*/
|
||||
public E getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the right value.
|
||||
*
|
||||
* @return The right value.
|
||||
*/
|
||||
public F getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns the pair into a string.
|
||||
*
|
||||
* @return Each value of the pair as a string joined by a colon.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return left.toString() + ":" + right.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hash code of this pair.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((left == null) ? 0 : left.hashCode());
|
||||
result = prime * result + ((right == null) ? 0 : right.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if two pairs are equal.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final Pair other = (Pair) obj;
|
||||
if (left == null) {
|
||||
if (other.left != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!left.equals(other.left)) {
|
||||
return false;
|
||||
}
|
||||
if (right == null) {
|
||||
if (other.right != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!right.equals(other.right)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
40
src/tools/Randomizer.java
Normal file
40
src/tools/Randomizer.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package tools;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class Randomizer {
|
||||
|
||||
private final static Random rand = new Random();
|
||||
|
||||
public static int nextInt() {
|
||||
return rand.nextInt();
|
||||
}
|
||||
|
||||
public static int nextInt(final int arg0) {
|
||||
return rand.nextInt(arg0);
|
||||
}
|
||||
|
||||
public static void nextBytes(final byte[] bytes) {
|
||||
rand.nextBytes(bytes);
|
||||
}
|
||||
|
||||
public static boolean nextBoolean() {
|
||||
return rand.nextBoolean();
|
||||
}
|
||||
|
||||
public static double nextDouble() {
|
||||
return rand.nextDouble();
|
||||
}
|
||||
|
||||
public static float nextFloat() {
|
||||
return rand.nextFloat();
|
||||
}
|
||||
|
||||
public static long nextLong() {
|
||||
return rand.nextLong();
|
||||
}
|
||||
|
||||
public static int rand(final int lbound, final int ubound) {
|
||||
return (int) ((rand.nextDouble() * (ubound - lbound + 1)) + lbound);
|
||||
}
|
||||
}
|
||||
128
src/tools/StringUtil.java
Normal file
128
src/tools/StringUtil.java
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
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;
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
* Gets a string padded from the left to <code>length</code> by
|
||||
* <code>padchar</code>.
|
||||
*
|
||||
* @param in The input string to be padded.
|
||||
* @param padchar The character to pad with.
|
||||
* @param length The length to pad to.
|
||||
* @return The padded string.
|
||||
*/
|
||||
public static String getLeftPaddedStr(String in, char padchar, int length) {
|
||||
StringBuilder builder = new StringBuilder(length);
|
||||
for (int x = in.length(); x < length; x++) {
|
||||
builder.append(padchar);
|
||||
}
|
||||
builder.append(in);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string padded from the right to <code>length</code> by
|
||||
* <code>padchar</code>.
|
||||
*
|
||||
* @param in The input string to be padded.
|
||||
* @param padchar The character to pad with.
|
||||
* @param length The length to pad to.
|
||||
* @return The padded string.
|
||||
*/
|
||||
public static String getRightPaddedStr(String in, char padchar, int length) {
|
||||
StringBuilder builder = new StringBuilder(in);
|
||||
for (int x = in.length(); x < length; x++) {
|
||||
builder.append(padchar);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins an array of strings starting from string <code>start</code> with
|
||||
* a space.
|
||||
*
|
||||
* @param arr The array of strings to join.
|
||||
* @param start Starting from which string.
|
||||
* @return The joined strings.
|
||||
*/
|
||||
public static String joinStringFrom(String arr[], int start) {
|
||||
return joinStringFrom(arr, start, " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins an array of strings starting from string <code>start</code> with
|
||||
* <code>sep</code> as a seperator.
|
||||
*
|
||||
* @param arr The array of strings to join.
|
||||
* @param start Starting from which string.
|
||||
* @return The joined strings.
|
||||
*/
|
||||
public static String joinStringFrom(String arr[], int start, String sep) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = start; i < arr.length; i++) {
|
||||
builder.append(arr[i]);
|
||||
if (i != arr.length - 1) {
|
||||
builder.append(sep);
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes an enum name human readable (fixes spaces, capitalization, etc)
|
||||
*
|
||||
* @param enumName The name of the enum to neaten up.
|
||||
* @return The human-readable enum name.
|
||||
*/
|
||||
public static String makeEnumHumanReadable(String enumName) {
|
||||
StringBuilder builder = new StringBuilder(enumName.length() + 1);
|
||||
String[] words = enumName.split("_");
|
||||
for (String word : words) {
|
||||
if (word.length() <= 2) {
|
||||
builder.append(word); // assume that it's an abbrevation
|
||||
} else {
|
||||
builder.append(word.charAt(0));
|
||||
builder.append(word.substring(1).toLowerCase());
|
||||
}
|
||||
builder.append(' ');
|
||||
}
|
||||
return builder.substring(0, enumName.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of <code>chr</code>'s in <code>str</code>.
|
||||
*
|
||||
* @param str The string to check for instances of <code>chr</code>.
|
||||
* @param chr The character to check for.
|
||||
* @return The number of times <code>chr</code> occurs in <code>str</code>.
|
||||
*/
|
||||
public static int countCharacters(String str, char chr) {
|
||||
int ret = 0;
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
if (str.charAt(i) == chr) {
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
72
src/tools/data/input/ByteArrayByteStream.java
Normal file
72
src/tools/data/input/ByteArrayByteStream.java
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
}
|
||||
35
src/tools/data/input/ByteInputStream.java
Normal file
35
src/tools/data/input/ByteInputStream.java
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
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();
|
||||
}
|
||||
239
src/tools/data/input/GenericLittleEndianAccessor.java
Normal file
239
src/tools/data/input/GenericLittleEndianAccessor.java
Normal file
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
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) {
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
92
src/tools/data/input/InputStreamByteStream.java
Normal file
92
src/tools/data/input/InputStreamByteStream.java
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
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) {
|
||||
System.out.println("ERROR" + e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
45
src/tools/data/input/LittleEndianAccessor.java
Normal file
45
src/tools/data/input/LittleEndianAccessor.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
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();
|
||||
}
|
||||
83
src/tools/data/input/RandomAccessByteStream.java
Normal file
83
src/tools/data/input/RandomAccessByteStream.java
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
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) {
|
||||
System.out.println("ERROR " + e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
51
src/tools/data/input/SeekableInputStreamBytestream.java
Normal file
51
src/tools/data/input/SeekableInputStreamBytestream.java
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
27
src/tools/data/input/SeekableLittleEndianAccessor.java
Normal file
27
src/tools/data/input/SeekableLittleEndianAccessor.java
Normal file
@@ -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 tools.data.input;
|
||||
|
||||
public interface SeekableLittleEndianAccessor extends LittleEndianAccessor {
|
||||
void seek(long offset);
|
||||
long getPosition();
|
||||
}
|
||||
56
src/tools/data/output/BAOSByteOutputStream.java
Normal file
56
src/tools/data/output/BAOSByteOutputStream.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package tools.data.output;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
/**
|
||||
* Uses a byte array to output a stream of bytes.
|
||||
*
|
||||
* @author Frz
|
||||
* @version 1.0
|
||||
* @since Revision 352
|
||||
*/
|
||||
class BAOSByteOutputStream implements ByteOutputStream {
|
||||
private ByteArrayOutputStream baos;
|
||||
|
||||
/**
|
||||
* Class constructor - Wraps the stream around a Java BAOS.
|
||||
*
|
||||
* @param baos <code>The ByteArrayOutputStream</code> to wrap this around.
|
||||
*/
|
||||
BAOSByteOutputStream(ByteArrayOutputStream baos) {
|
||||
super();
|
||||
this.baos = baos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a byte to the stream.
|
||||
*
|
||||
* @param b The byte to write to the stream.
|
||||
* @see tools.data.output.ByteOutputStream#writeByte(byte)
|
||||
*/
|
||||
@Override
|
||||
public void writeByte(byte b) {
|
||||
baos.write(b);
|
||||
}
|
||||
}
|
||||
38
src/tools/data/output/ByteOutputStream.java
Normal file
38
src/tools/data/output/ByteOutputStream.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package tools.data.output;
|
||||
|
||||
/**
|
||||
* Provides an interface to an output stream of bytes.
|
||||
*
|
||||
* @author Frz
|
||||
* @since Revision 323
|
||||
* @version 1.0
|
||||
*/
|
||||
interface ByteOutputStream {
|
||||
/**
|
||||
* Writes a byte to the stream.
|
||||
*
|
||||
* @param b The byte to write.
|
||||
*/
|
||||
void writeByte(byte b);
|
||||
}
|
||||
183
src/tools/data/output/GenericLittleEndianWriter.java
Normal file
183
src/tools/data/output/GenericLittleEndianWriter.java
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package tools.data.output;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* Provides a generic writer of a little-endian sequence of bytes.
|
||||
*
|
||||
* @author Frz
|
||||
* @version 1.0
|
||||
* @since Revision 323
|
||||
*/
|
||||
public class GenericLittleEndianWriter implements LittleEndianWriter {
|
||||
private static Charset ASCII = Charset.forName("US-ASCII");
|
||||
private ByteOutputStream bos;
|
||||
|
||||
/**
|
||||
* Class constructor - Protected to prevent instantiation with no arguments.
|
||||
*/
|
||||
protected GenericLittleEndianWriter() {
|
||||
// Blah!
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the byte-output stream for this instance of the object.
|
||||
*
|
||||
* @param bos The new output stream to set.
|
||||
*/
|
||||
void setByteOutputStream(ByteOutputStream bos) {
|
||||
this.bos = bos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an array of bytes to the stream.
|
||||
*
|
||||
* @param b The bytes to write.
|
||||
*/
|
||||
@Override
|
||||
public void write(byte[] b) {
|
||||
for (int x = 0; x < b.length; x++) {
|
||||
bos.writeByte(b[x]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a byte to the stream.
|
||||
*
|
||||
* @param b The byte to write.
|
||||
*/
|
||||
@Override
|
||||
public void write(byte b) {
|
||||
bos.writeByte(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a byte in integer form to the stream.
|
||||
*
|
||||
* @param b The byte as an <code>Integer</code> to write.
|
||||
*/
|
||||
@Override
|
||||
public void write(int b) {
|
||||
bos.writeByte((byte) b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skip(int b) {
|
||||
write(new byte[b]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a short integer to the stream.
|
||||
*
|
||||
* @param i The short integer to write.
|
||||
*/
|
||||
@Override
|
||||
public void writeShort(int i) {
|
||||
bos.writeByte((byte) (i & 0xFF));
|
||||
bos.writeByte((byte) ((i >>> 8) & 0xFF));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an integer to the stream.
|
||||
*
|
||||
* @param i The integer to write.
|
||||
*/
|
||||
@Override
|
||||
public void writeInt(int i) {
|
||||
bos.writeByte((byte) (i & 0xFF));
|
||||
bos.writeByte((byte) ((i >>> 8) & 0xFF));
|
||||
bos.writeByte((byte) ((i >>> 16) & 0xFF));
|
||||
bos.writeByte((byte) ((i >>> 24) & 0xFF));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an ASCII string the the stream.
|
||||
*
|
||||
* @param s The ASCII string to write.
|
||||
*/
|
||||
@Override
|
||||
public void writeAsciiString(String s) {
|
||||
write(s.getBytes(ASCII));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a maple-convention ASCII string to the stream.
|
||||
*
|
||||
* @param s The ASCII string to use maple-convention to write.
|
||||
*/
|
||||
@Override
|
||||
public void writeMapleAsciiString(String s) {
|
||||
writeShort((short) s.length());
|
||||
writeAsciiString(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a null-terminated ASCII string to the stream.
|
||||
*
|
||||
* @param s The ASCII string to write.
|
||||
*/
|
||||
@Override
|
||||
public void writeNullTerminatedAsciiString(String s) {
|
||||
writeAsciiString(s);
|
||||
write(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a long integer to the stream.
|
||||
* @param l The long integer to write.
|
||||
*/
|
||||
@Override
|
||||
public void writeLong(long l) {
|
||||
bos.writeByte((byte) (l & 0xFF));
|
||||
bos.writeByte((byte) ((l >>> 8) & 0xFF));
|
||||
bos.writeByte((byte) ((l >>> 16) & 0xFF));
|
||||
bos.writeByte((byte) ((l >>> 24) & 0xFF));
|
||||
bos.writeByte((byte) ((l >>> 32) & 0xFF));
|
||||
bos.writeByte((byte) ((l >>> 40) & 0xFF));
|
||||
bos.writeByte((byte) ((l >>> 48) & 0xFF));
|
||||
bos.writeByte((byte) ((l >>> 56) & 0xFF));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a 2D 4 byte position information
|
||||
*
|
||||
* @param s The Point position to write.
|
||||
*/
|
||||
@Override
|
||||
public void writePos(Point s) {
|
||||
writeShort(s.x);
|
||||
writeShort(s.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a boolean true ? 1 : 0
|
||||
*
|
||||
* @param b The boolean to write.
|
||||
*/
|
||||
@Override
|
||||
public void writeBool(final boolean b) {
|
||||
write(b ? 1 : 0);
|
||||
}
|
||||
}
|
||||
114
src/tools/data/output/LittleEndianWriter.java
Normal file
114
src/tools/data/output/LittleEndianWriter.java
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package tools.data.output;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
/**
|
||||
* Provides an interface to a writer class that writes a little-endian sequence
|
||||
* of bytes.
|
||||
*
|
||||
* @author Frz
|
||||
* @version 1.0
|
||||
* @since Revision 323
|
||||
*/
|
||||
public interface LittleEndianWriter {
|
||||
|
||||
/**
|
||||
* Write an array of bytes to the sequence.
|
||||
*
|
||||
* @param b The bytes to write.
|
||||
*/
|
||||
public void write(byte b[]);
|
||||
|
||||
/**
|
||||
* Write a byte to the sequence.
|
||||
*
|
||||
* @param b The byte to write.
|
||||
*/
|
||||
public void write(byte b);
|
||||
|
||||
/**
|
||||
* Write a byte in integer form to the sequence.
|
||||
*
|
||||
* @param b The byte as an <code>Integer</code> to write.
|
||||
*/
|
||||
public void write(int b);
|
||||
|
||||
public void skip(int b);
|
||||
|
||||
/**
|
||||
* Writes an integer to the sequence.
|
||||
*
|
||||
* @param i The integer to write.
|
||||
*/
|
||||
public void writeInt(int i);
|
||||
|
||||
/**
|
||||
* Write a short integer to the sequence.
|
||||
*
|
||||
* @param s The short integer to write.
|
||||
*/
|
||||
public void writeShort(int s);
|
||||
|
||||
/**
|
||||
* Write a long integer to the sequence.
|
||||
*
|
||||
* @param l The long integer to write.
|
||||
*/
|
||||
public void writeLong(long l);
|
||||
|
||||
/**
|
||||
* Writes an ASCII string the the sequence.
|
||||
*
|
||||
* @param s The ASCII string to write.
|
||||
*/
|
||||
void writeAsciiString(String s);
|
||||
|
||||
/**
|
||||
* Writes a null-terminated ASCII string to the sequence.
|
||||
*
|
||||
* @param s The ASCII string to write.
|
||||
*/
|
||||
void writeNullTerminatedAsciiString(String s);
|
||||
|
||||
/**
|
||||
* Writes a maple-convention ASCII string to the sequence.
|
||||
*
|
||||
* @param s The ASCII string to use maple-convention to write.
|
||||
*/
|
||||
void writeMapleAsciiString(String s);
|
||||
|
||||
/**
|
||||
* Writes a 2D 4 byte position information
|
||||
*
|
||||
* @param s The Point position to write.
|
||||
*/
|
||||
void writePos(Point s);
|
||||
|
||||
/**
|
||||
* Writes a boolean true ? 1 : 0
|
||||
*
|
||||
* @param b The boolean to write.
|
||||
*/
|
||||
void writeBool(final boolean b);
|
||||
}
|
||||
73
src/tools/data/output/MaplePacketLittleEndianWriter.java
Normal file
73
src/tools/data/output/MaplePacketLittleEndianWriter.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package tools.data.output;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import tools.HexTool;
|
||||
|
||||
/**
|
||||
* Writes a maplestory-packet little-endian stream of bytes.
|
||||
*
|
||||
* @author Frz
|
||||
* @version 1.0
|
||||
* @since Revision 352
|
||||
*/
|
||||
public class MaplePacketLittleEndianWriter extends GenericLittleEndianWriter {
|
||||
private ByteArrayOutputStream baos;
|
||||
|
||||
/**
|
||||
* Constructor - initializes this stream with a default size.
|
||||
*/
|
||||
public MaplePacketLittleEndianWriter() {
|
||||
this(32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor - initializes this stream with size <code>size</code>.
|
||||
*
|
||||
* @param size The size of the underlying stream.
|
||||
*/
|
||||
public MaplePacketLittleEndianWriter(int size) {
|
||||
this.baos = new ByteArrayOutputStream(size);
|
||||
setByteOutputStream(new BAOSByteOutputStream(baos));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a <code>MaplePacket</code> instance representing this
|
||||
* sequence of bytes.
|
||||
*
|
||||
* @return A <code>MaplePacket</code> with the bytes in this stream.
|
||||
*/
|
||||
public byte[] getPacket() {
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes this packet into a human-readable hexadecimal stream of bytes.
|
||||
*
|
||||
* @return This packet as hex digits.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return HexTool.toString(baos.toByteArray());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user