From f5e08987d695f9bc6dc343e36ec8d2d994f2bf67 Mon Sep 17 00:00:00 2001 From: codestation Date: Sun, 12 Dec 2010 17:41:57 +0000 Subject: [PATCH] Forgot to code formatting before the first commit -_-# --- src/base/Decoder.java | 119 +++++++------- src/base/Encoder.java | 186 ++++++++++----------- src/base/Mhtrans.java | 293 ++++++++++++++++----------------- src/crypt/DecryptTable.java | 233 +++++++++++++------------- src/crypt/Decrypter.java | 268 +++++++++++++++--------------- src/crypt/Encrypter.java | 72 ++++---- src/dec/ExtractPluginA.java | 178 ++++++++++---------- src/dec/ExtractPluginB.java | 218 ++++++++++++------------ src/dec/ExtractPluginC.java | 166 ++++++++++--------- src/enc/RebuildPluginA.java | 318 +++++++++++++++++++----------------- src/enc/RebuildPluginB.java | 263 +++++++++++++++-------------- src/enc/RebuildPluginC.java | 279 ++++++++++++++++--------------- 12 files changed, 1325 insertions(+), 1268 deletions(-) diff --git a/src/base/Decoder.java b/src/base/Decoder.java index 8163d89..be06fff 100644 --- a/src/base/Decoder.java +++ b/src/base/Decoder.java @@ -23,66 +23,67 @@ import java.io.RandomAccessFile; public abstract class Decoder { - public abstract void extract(String filename); + public abstract void extract(String filename); - /** - * The "readInt" function of java reads in BigEndian mode but we need - * LittleEndian so i made a custom function for that - * - * @param file - * @return 8 byte integer in LittleEndian mode - * @throws IOException - * if any error occur while reading - */ - protected int readInt(RandomAccessFile file) throws IOException, EOFException { - int ch1 = file.read(); - int ch2 = file.read(); - int ch3 = file.read(); - int ch4 = file.read(); - if ((ch1 | ch2 | ch3 | ch4) < 0) { - throw new EOFException(); - } - return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0); - } + /** + * The "readInt" function of java reads in BigEndian mode but we need + * LittleEndian so i made a custom function for that + * + * @param file + * @return 8 byte integer in LittleEndian mode + * @throws IOException + * if any error occur while reading + */ + protected int readInt(RandomAccessFile file) throws IOException, + EOFException { + int ch1 = file.read(); + int ch2 = file.read(); + int ch3 = file.read(); + int ch4 = file.read(); + if ((ch1 | ch2 | ch3 | ch4) < 0) { + throw new EOFException(); + } + return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0); + } - /** - * Some hex-edited files have some extra zeros at the end of the strings so - * its better to skip them - * - * @param file - * @throws IOException - * if any error occur while reading - */ - protected void advanceNext(RandomAccessFile file) throws IOException { - while (file.readByte() == 0) { - ; - } - file.seek(file.getFilePointer() - 1); - } + /** + * Some hex-edited files have some extra zeros at the end of the strings + * so its better to skip them + * + * @param file + * @throws IOException + * if any error occur while reading + */ + protected void advanceNext(RandomAccessFile file) throws IOException { + while (file.readByte() == 0) { + ; + } + file.seek(file.getFilePointer() - 1); + } - /** - * The "readUTF8" function of java expects a different format of the string - * so i have to make a custom one - * - * @param file - * @return string extracted from file - * @throws IOException - * if any error occur while reading - */ - protected String readString(RandomAccessFile file) throws IOException { - byte[] buffer = new byte[1024]; - byte data = 0; - int counter = 0; - try { - do { - data = file.readByte(); - buffer[counter++] = data; - } while (data != 0); - // checks if the string is a edited one - advanceNext(file); - } catch (EOFException e) { - return null; - } - return new String(buffer, 0, counter, "UTF-8"); - } + /** + * The "readUTF8" function of java expects a different format of the + * string so i have to make a custom one + * + * @param file + * @return string extracted from file + * @throws IOException + * if any error occur while reading + */ + protected String readString(RandomAccessFile file) throws IOException { + byte[] buffer = new byte[1024]; + byte data = 0; + int counter = 0; + try { + do { + data = file.readByte(); + buffer[counter++] = data; + } while (data != 0); + // checks if the string is a edited one + advanceNext(file); + } catch (EOFException e) { + return null; + } + return new String(buffer, 0, counter, "UTF-8"); + } } diff --git a/src/base/Encoder.java b/src/base/Encoder.java index 7a32bb9..492d610 100644 --- a/src/base/Encoder.java +++ b/src/base/Encoder.java @@ -23,100 +23,102 @@ import java.io.RandomAccessFile; public abstract class Encoder { - public abstract void compile(String filelist); + public abstract void compile(String filelist); - /** - * The "readUTF8" function of java expects a different format of the string - * so i have to make a custom one. - * - * @param file - * @return string extracted from file - * @throws IOException - * if any error occur while reading - */ - protected String readString(RandomAccessFile file) throws IOException { - byte[] buffer = new byte[1024]; - byte data = 0; - boolean eol = false; - int counter = 0; - try { - while (!eol) { - switch (data = file.readByte()) { - case '\n': - eol = true; - break; - case '\r': - eol = true; - long cur = file.getFilePointer(); - if (file.readByte() != '\n') { - file.seek(cur); - eol = false; - } - break; - default: - buffer[counter++] = data; - break; - } - } - } catch (EOFException e) { - return null; - } - return new String(buffer, 0, counter, "UTF-8"); - } + /** + * The "readUTF8" function of java expects a different format of + * the string so i have to make a custom one. + * + * @param file + * @return string extracted from file + * @throws IOException + * if any error occur while reading + */ + protected String readString(RandomAccessFile file) throws IOException { + byte[] buffer = new byte[1024]; + byte data = 0; + boolean eol = false; + int counter = 0; + try { + while (!eol) { + switch (data = file.readByte()) { + case '\n': + eol = true; + break; + case '\r': + eol = true; + long cur = file.getFilePointer(); + if (file.readByte() != '\n') { + file.seek(cur); + eol = false; + } + break; + default: + buffer[counter++] = data; + break; + } + } + } catch (EOFException e) { + return null; + } + return new String(buffer, 0, counter, "UTF-8"); + } - /** - * Checks if the file have the unicode BOM mark and skip it (thanks notepad - * grr..) - * - * @param file - * @throws IOException - * if any error occur while reading - */ - protected void checkUnicodeBOM(RandomAccessFile file) throws IOException { - int a = file.readByte(); - int b = file.readByte(); - int c = file.readByte(); - if (a != -17 || b != -69 || c != -65) { - file.seek(0); - } - } + /** + * Checks if the file have the unicode BOM mark and skip it + * (thanks notepad grr..) + * + * @param file + * @throws IOException + * if any error occur while reading + */ + protected void checkUnicodeBOM(RandomAccessFile file) throws IOException { + int a = file.readByte(); + int b = file.readByte(); + int c = file.readByte(); + if (a != -17 || b != -69 || c != -65) { + file.seek(0); + } + } - /** - * The "writeInt" function of java writes in BigEndian mode but we need - * LittleEndian so i made a custom function for that - * - * @param file - * @throws IOException - * if any error occur while writing - */ - protected void writeInt(RandomAccessFile file, int value) throws IOException { - int ch1 = (byte) (value >>> 24); - int ch2 = (byte) (value >>> 16); - int ch3 = (byte) (value >>> 8); - int ch4 = (byte) value; - file.write(ch4); - file.write(ch3); - file.write(ch2); - file.write(ch1); - } + /** + * The "writeInt" function of java writes in BigEndian mode but we need + * LittleEndian so i made a custom function for that + * + * @param file + * @throws IOException + * if any error occur while writing + */ + protected void writeInt(RandomAccessFile file, int value) + throws IOException { + int ch1 = (byte) (value >>> 24); + int ch2 = (byte) (value >>> 16); + int ch3 = (byte) (value >>> 8); + int ch4 = (byte) value; + file.write(ch4); + file.write(ch3); + file.write(ch2); + file.write(ch1); + } - /** - * The "readInt" function of java reads in BigEndian mode but we need - * LittleEndian so i made a custom function for that - * - * @param file - * @return 8 byte integer in LittleEndian mode - * @throws IOException - * if any error occur while reading - */ - protected int readInt(RandomAccessFile file) throws IOException, EOFException { - int ch1 = file.read(); - int ch2 = file.read(); - int ch3 = file.read(); - int ch4 = file.read(); - if ((ch1 | ch2 | ch3 | ch4) < 0) { - throw new EOFException(); - } - return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0); - } + /** + * The "readInt" function of java reads in BigEndian mode but we need + * LittleEndian so i made a custom function for that + * + * @param file + * @return 8 byte integer in LittleEndian mode + * @throws IOException + * if any error occur while reading + */ + protected int readInt(RandomAccessFile file) throws IOException, + EOFException { + int ch1 = file.read(); + int ch2 = file.read(); + int ch3 = file.read(); + int ch4 = file.read(); + if ((ch1 | ch2 | ch3 | ch4) < 0) { + throw new EOFException(); + } + return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0); + } } diff --git a/src/base/Mhtrans.java b/src/base/Mhtrans.java index 92ca38d..a0c6e74 100644 --- a/src/base/Mhtrans.java +++ b/src/base/Mhtrans.java @@ -33,152 +33,153 @@ import enc.RebuildPluginB; import enc.RebuildPluginC; public class Mhtrans { - - public static void extract(String filename, String decoder) { - // (00[1-2][0-9]|47[0-9][0-9])\\..* decoder A - // 53[0-9][0-9]\\..* decoder B - // 54[0-9][0-9]\\..* decoder C - - Decoder dec = null; - int type = Integer.parseInt(decoder); - switch(type) { - case 1: - dec = new ExtractPluginA(); - break; - case 2: - dec = new ExtractPluginB(false); - break; - case 4: - dec = new ExtractPluginB(true); - break; - case 3: - dec = new ExtractPluginC(); - break; - default: - System.err.println("Unknown decoder: " + decoder); - System.exit(1); - } - dec.extract(filename); - } - - public static void rebuild(String filename, String encoder) { - String str = checkFile(filename + "/filelist.txt"); - Encoder enc = null; - if (str == null) - System.exit(1); - int type = Integer.parseInt(encoder); - switch(type) { - case 1: - enc = new RebuildPluginA(); - break; - case 2: - enc = new RebuildPluginB(0); - break; - case 4: - enc = new RebuildPluginB(type); - break; - case 3: - enc = new RebuildPluginC(); - break; - default: - System.err.println("Unknown encoder: " + encoder); - System.exit(1); - } - enc.compile(filename); - } - public static void main(String[] args) { - System.out.println("mhtrans v2.0 - MHP2G/MHFU/MHP3 xxxx.bin language table extractor/rebuilder"); - System.out.println(); - if (args.length < 2) { - System.err.println("Usage: java -jar mhtrans.jar --extract "); - System.err.println(" java -jar mhtrans.jar --rebuild "); - System.err.println(" java -jar mhtrans.jar --decrypt "); - System.err.println(" java -jar mhtrans.jar --encrypt "); - System.err.println(" java -jar mhtrans.jar --dec-ext "); - System.err.println(" java -jar mhtrans.jar --reb-enc "); - System.err.println(" java -jar mhtrans.jar --gen-index "); - System.err.println(" java -jar mhtrans.jar --dec-all "); - //System.err.println(" java MHP2GTRANS --dec-single "); - //System.err.println(" java MHP2GTRANS --insert "); - System.exit(1); - } else { - if (args[0].equals("--extract")) { - if(args.length < 3) { - System.err.println("Decoder number missing. Aborting"); - System.exit(1); - } - extract(args[1], args[2]); - } else if (args[0].equals("--rebuild")) { - if(args.length < 3) { - System.err.println("Decoder number missing. Aborting"); - System.exit(1); - } - rebuild(args[1], args[2]); - } else if (args[0].equals("--decrypt")) { - new Decrypter().decrypt(args[1], args[1] + ".dec"); - } else if (args[0].equals("--encrypt")) { - String filename = new File(args[1]).getName(); - new Encrypter().encrypt(args[1], filename + ".enc"); - } else if (args[0].equals("--dec-ext")) { - if(args.length < 3) { - System.err.println("Decoder number missing. Aborting"); - System.exit(1); - } - new Decrypter().decrypt(args[1], args[1] + ".dec"); - new File(args[1]).renameTo(new File(args[1] + ".tmp")); - new File(args[1] + ".dec").renameTo(new File(args[1])); - extract(args[1], args[2]); - new File(args[1]).delete(); - new File(args[1] + ".tmp").renameTo(new File(args[1])); - } else if (args[0].equals("--reb-enc")) { - if(args.length < 3) { - System.err.println("Decoder number missing. Aborting"); - System.exit(1); - } - rebuild(args[1], args[2]); - String filename = new File(args[1]).getName(); - new Encrypter().encrypt(filename + ".bin.out", filename + ".bin.enc"); - System.out.println("Moving to " + filename + ".bin.enc"); - new File(filename + ".bin.out").delete(); - } else if(args[0].equals("--gen-index")) { - new Decrypter().decrypt_index(args[1], null); - } else if(args[0].equals("--dec-all")) { - if(args.length < 3) { - System.err.println("Output folder missing. Aborting"); - System.exit(1); - } - new Decrypter().decrypt_whole(args[1], args[2]); -// } else if(args[0].equals("--dec-single")) { -// if(args.length < 3) { -// System.err.println("Output xxxx.bin missing. Aborting"); -// System.exit(1); -// } -// -// } else if(args[0].equals("--insert")) { -// if(args.length < 3) { -// System.err.println("Path of data.bin missing. Aborting"); -// System.exit(1); -// } - } else { - System.err.println("Unknown parameter: " + args[0]); - System.exit(1); - } - } - } + public static void extract(String filename, String decoder) { + // (00[1-2][0-9]|47[0-9][0-9])\\..* decoder A + // 53[0-9][0-9]\\..* decoder B + // 54[0-9][0-9]\\..* decoder C - public static String checkFile(String filename) { - try { - BufferedReader file = new BufferedReader(new FileReader(filename)); - String name = file.readLine().split(" ")[0]; - file.close(); - return name; - } catch (FileNotFoundException e) { - System.err.println(e.toString()); - return null; - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } + Decoder dec = null; + int type = Integer.parseInt(decoder); + switch (type) { + case 1: + dec = new ExtractPluginA(); + break; + case 2: + dec = new ExtractPluginB(false); + break; + case 4: + dec = new ExtractPluginB(true); + break; + case 3: + dec = new ExtractPluginC(); + break; + default: + System.err.println("Unknown decoder: " + decoder); + System.exit(1); + } + dec.extract(filename); + } + + public static void rebuild(String filename, String encoder) { + String str = checkFile(filename + "/filelist.txt"); + Encoder enc = null; + if (str == null) + System.exit(1); + int type = Integer.parseInt(encoder); + switch (type) { + case 1: + enc = new RebuildPluginA(); + break; + case 2: + enc = new RebuildPluginB(0); + break; + case 4: + enc = new RebuildPluginB(type); + break; + case 3: + enc = new RebuildPluginC(); + break; + default: + System.err.println("Unknown encoder: " + encoder); + System.exit(1); + } + enc.compile(filename); + } + + public static void main(String[] args) { + System.out.println("mhtrans v2.0 - MHP2G/MHFU/MHP3 xxxx.bin language table extractor/rebuilder"); + System.out.println(); + if (args.length < 2) { + System.err.println("Usage: java -jar mhtrans.jar --extract "); + System.err.println(" java -jar mhtrans.jar --rebuild "); + System.err.println(" java -jar mhtrans.jar --decrypt "); + System.err.println(" java -jar mhtrans.jar --encrypt "); + System.err.println(" java -jar mhtrans.jar --dec-ext "); + System.err.println(" java -jar mhtrans.jar --reb-enc "); + System.err.println(" java -jar mhtrans.jar --gen-index "); + System.err.println(" java -jar mhtrans.jar --dec-all "); + // System.err.println(" java MHP2GTRANS --dec-single "); + // System.err.println(" java MHP2GTRANS --insert "); + System.exit(1); + } else { + if (args[0].equals("--extract")) { + if (args.length < 3) { + System.err.println("Decoder number missing. Aborting"); + System.exit(1); + } + extract(args[1], args[2]); + } else if (args[0].equals("--rebuild")) { + if (args.length < 3) { + System.err.println("Decoder number missing. Aborting"); + System.exit(1); + } + rebuild(args[1], args[2]); + } else if (args[0].equals("--decrypt")) { + new Decrypter().decrypt(args[1], args[1] + ".dec"); + } else if (args[0].equals("--encrypt")) { + String filename = new File(args[1]).getName(); + new Encrypter().encrypt(args[1], filename + ".enc"); + } else if (args[0].equals("--dec-ext")) { + if (args.length < 3) { + System.err.println("Decoder number missing. Aborting"); + System.exit(1); + } + new Decrypter().decrypt(args[1], args[1] + ".dec"); + new File(args[1]).renameTo(new File(args[1] + ".tmp")); + new File(args[1] + ".dec").renameTo(new File(args[1])); + extract(args[1], args[2]); + new File(args[1]).delete(); + new File(args[1] + ".tmp").renameTo(new File(args[1])); + } else if (args[0].equals("--reb-enc")) { + if (args.length < 3) { + System.err.println("Decoder number missing. Aborting"); + System.exit(1); + } + rebuild(args[1], args[2]); + String filename = new File(args[1]).getName(); + new Encrypter().encrypt(filename + ".bin.out", filename + + ".bin.enc"); + System.out.println("Moving to " + filename + ".bin.enc"); + new File(filename + ".bin.out").delete(); + } else if (args[0].equals("--gen-index")) { + new Decrypter().decrypt_index(args[1], null); + } else if (args[0].equals("--dec-all")) { + if (args.length < 3) { + System.err.println("Output folder missing. Aborting"); + System.exit(1); + } + new Decrypter().decrypt_whole(args[1], args[2]); + // } else if(args[0].equals("--dec-single")) { + // if(args.length < 3) { + // System.err.println("Output xxxx.bin missing. Aborting"); + // System.exit(1); + // } + // + // } else if(args[0].equals("--insert")) { + // if(args.length < 3) { + // System.err.println("Path of data.bin missing. Aborting"); + // System.exit(1); + // } + } else { + System.err.println("Unknown parameter: " + args[0]); + System.exit(1); + } + } + } + + public static String checkFile(String filename) { + try { + BufferedReader file = new BufferedReader(new FileReader(filename)); + String name = file.readLine().split(" ")[0]; + file.close(); + return name; + } catch (FileNotFoundException e) { + System.err.println(e.toString()); + return null; + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } } diff --git a/src/crypt/DecryptTable.java b/src/crypt/DecryptTable.java index 1a825e8..061a053 100644 --- a/src/crypt/DecryptTable.java +++ b/src/crypt/DecryptTable.java @@ -25,122 +25,123 @@ import java.io.RandomAccessFile; public abstract class DecryptTable { - protected final byte decrypt_table[] = { (byte) 0xCB, (byte) 0x96, - (byte) 0x85, (byte) 0xA6, (byte) 0x5F, (byte) 0x3E, (byte) 0xAB, - (byte) 0x03, (byte) 0x50, (byte) 0xB7, (byte) 0x9C, (byte) 0x5C, - (byte) 0xB2, (byte) 0x40, (byte) 0xEF, (byte) 0xF6, (byte) 0xFF, - (byte) 0x61, (byte) 0x15, (byte) 0x29, (byte) 0xA2, (byte) 0xF1, - (byte) 0xEC, (byte) 0x52, (byte) 0x35, (byte) 0x28, (byte) 0xD9, - (byte) 0x68, (byte) 0x24, (byte) 0x36, (byte) 0xC4, (byte) 0x74, - (byte) 0x26, (byte) 0xE2, (byte) 0xD5, (byte) 0x8C, (byte) 0x47, - (byte) 0x4D, (byte) 0x2C, (byte) 0xFA, (byte) 0x86, (byte) 0x66, - (byte) 0xC1, (byte) 0x4F, (byte) 0x0B, (byte) 0x81, (byte) 0x5B, - (byte) 0x1B, (byte) 0xC0, (byte) 0x0A, (byte) 0xFD, (byte) 0x17, - (byte) 0xA4, (byte) 0xA9, (byte) 0x6D, (byte) 0x63, (byte) 0xAD, - (byte) 0xF3, (byte) 0xF4, (byte) 0x6E, (byte) 0x8D, (byte) 0x89, - (byte) 0x14, (byte) 0xDD, (byte) 0x59, (byte) 0x87, (byte) 0x4A, - (byte) 0x30, (byte) 0xCE, (byte) 0xFE, (byte) 0x3F, (byte) 0x7E, - (byte) 0x06, (byte) 0x49, (byte) 0xA5, (byte) 0x04, (byte) 0x5E, - (byte) 0xD0, (byte) 0xDE, (byte) 0xE8, (byte) 0x0F, (byte) 0xD4, - (byte) 0x13, (byte) 0x1F, (byte) 0xBA, (byte) 0xB9, (byte) 0x69, - (byte) 0x71, (byte) 0x3D, (byte) 0xE4, (byte) 0xDC, (byte) 0x58, - (byte) 0x90, (byte) 0x34, (byte) 0x3A, (byte) 0x3C, (byte) 0xCA, - (byte) 0x10, (byte) 0x76, (byte) 0xC7, (byte) 0xC8, (byte) 0x45, - (byte) 0x33, (byte) 0xC3, (byte) 0x92, (byte) 0x1D, (byte) 0x2B, - (byte) 0x1C, (byte) 0x8F, (byte) 0x6F, (byte) 0x05, (byte) 0x07, - (byte) 0x38, (byte) 0x57, (byte) 0x51, (byte) 0xD6, (byte) 0xDA, - (byte) 0x2D, (byte) 0xB3, (byte) 0xC6, (byte) 0x2E, (byte) 0x64, - (byte) 0x32, (byte) 0x1E, (byte) 0x43, (byte) 0xB1, (byte) 0x5D, - (byte) 0xE1, (byte) 0xBB, (byte) 0x8E, (byte) 0x9D, (byte) 0x72, - (byte) 0x77, (byte) 0xF2, (byte) 0x27, (byte) 0xC9, (byte) 0x7F, - (byte) 0x9E, (byte) 0xAA, (byte) 0x6A, (byte) 0x2F, (byte) 0x6C, - (byte) 0xF9, (byte) 0x48, (byte) 0xE7, (byte) 0xA0, (byte) 0x09, - (byte) 0x56, (byte) 0xB8, (byte) 0xBD, (byte) 0x20, (byte) 0x41, - (byte) 0xCD, (byte) 0x95, (byte) 0x80, (byte) 0xD7, (byte) 0x23, - (byte) 0x0C, (byte) 0x42, (byte) 0xE5, (byte) 0xAE, (byte) 0x8B, - (byte) 0x7D, (byte) 0xBC, (byte) 0x54, (byte) 0x39, (byte) 0xBF, - (byte) 0x65, (byte) 0x01, (byte) 0x88, (byte) 0xE0, (byte) 0x7B, - (byte) 0xB6, (byte) 0x16, (byte) 0x18, (byte) 0x4B, (byte) 0xCC, - (byte) 0x22, (byte) 0x5A, (byte) 0xB5, (byte) 0xEB, (byte) 0xFC, - (byte) 0xF8, (byte) 0x9B, (byte) 0x4E, (byte) 0xE6, (byte) 0xA8, - (byte) 0xBE, (byte) 0x67, (byte) 0x73, (byte) 0x97, (byte) 0x94, - (byte) 0x00, (byte) 0x62, (byte) 0xB4, (byte) 0xD2, (byte) 0x21, - (byte) 0x25, (byte) 0x11, (byte) 0x82, (byte) 0xDB, (byte) 0x93, - (byte) 0x02, (byte) 0x84, (byte) 0x7C, (byte) 0xD3, (byte) 0xB0, - (byte) 0xA3, (byte) 0x91, (byte) 0xA7, (byte) 0xF7, (byte) 0x55, - (byte) 0x70, (byte) 0x7A, (byte) 0x08, (byte) 0x75, (byte) 0x8A, - (byte) 0x53, (byte) 0x79, (byte) 0xFB, (byte) 0x9F, (byte) 0x46, - (byte) 0xF5, (byte) 0x83, (byte) 0xD8, (byte) 0x0E, (byte) 0xE9, - (byte) 0xED, (byte) 0x12, (byte) 0xD1, (byte) 0xDF, (byte) 0xF0, - (byte) 0x37, (byte) 0x2A, (byte) 0x44, (byte) 0x19, (byte) 0x9A, - (byte) 0x31, (byte) 0xCF, (byte) 0xA1, (byte) 0xAF, (byte) 0xE3, - (byte) 0x3B, (byte) 0x1A, (byte) 0x4C, (byte) 0x78, (byte) 0xC2, - (byte) 0x60, (byte) 0xEE, (byte) 0x98, (byte) 0x6B, (byte) 0x0D, - (byte) 0x99, (byte) 0xEA, (byte) 0xC5, (byte) 0xAC }; - - private long lower_offset; - private long upper_offset; - - protected void initSeed(long seed) { - lower_offset = seed & 0xFFFF; - upper_offset = seed >> 0x10 & 0xFFFF; - if (lower_offset == 0) { - lower_offset = 0x7F8D; - } - if (upper_offset == 0) { - upper_offset = 0x2345; - } - } - - protected long getBeta() { - lower_offset = (lower_offset * 0x7F8D) % 0xFFF1; - upper_offset = (upper_offset * 0x2345) % 0xFFD9; - return lower_offset + (upper_offset << 0x10); - } - - protected void set_table_value(byte table[], int pos, long value) { - table[pos] = (byte) value; - table[pos+1] = (byte) (value >> 8); - table[pos+2] = (byte) (value >> 16); - table[pos+3] = (byte) (value >> 24); - } - - protected long get_table_value(byte table[], int pos) { - return (table[pos] & 0xFF) - + ((long) (table[pos+1] & 0xFF) << 8) - + ((long) (table[pos+2] & 0xFF) << 16) - + ((long) (table[pos+3] & 0xFF) << 24); - } + protected final byte decrypt_table[] = { (byte) 0xCB, (byte) 0x96, + (byte) 0x85, (byte) 0xA6, (byte) 0x5F, (byte) 0x3E, (byte) 0xAB, + (byte) 0x03, (byte) 0x50, (byte) 0xB7, (byte) 0x9C, (byte) 0x5C, + (byte) 0xB2, (byte) 0x40, (byte) 0xEF, (byte) 0xF6, (byte) 0xFF, + (byte) 0x61, (byte) 0x15, (byte) 0x29, (byte) 0xA2, (byte) 0xF1, + (byte) 0xEC, (byte) 0x52, (byte) 0x35, (byte) 0x28, (byte) 0xD9, + (byte) 0x68, (byte) 0x24, (byte) 0x36, (byte) 0xC4, (byte) 0x74, + (byte) 0x26, (byte) 0xE2, (byte) 0xD5, (byte) 0x8C, (byte) 0x47, + (byte) 0x4D, (byte) 0x2C, (byte) 0xFA, (byte) 0x86, (byte) 0x66, + (byte) 0xC1, (byte) 0x4F, (byte) 0x0B, (byte) 0x81, (byte) 0x5B, + (byte) 0x1B, (byte) 0xC0, (byte) 0x0A, (byte) 0xFD, (byte) 0x17, + (byte) 0xA4, (byte) 0xA9, (byte) 0x6D, (byte) 0x63, (byte) 0xAD, + (byte) 0xF3, (byte) 0xF4, (byte) 0x6E, (byte) 0x8D, (byte) 0x89, + (byte) 0x14, (byte) 0xDD, (byte) 0x59, (byte) 0x87, (byte) 0x4A, + (byte) 0x30, (byte) 0xCE, (byte) 0xFE, (byte) 0x3F, (byte) 0x7E, + (byte) 0x06, (byte) 0x49, (byte) 0xA5, (byte) 0x04, (byte) 0x5E, + (byte) 0xD0, (byte) 0xDE, (byte) 0xE8, (byte) 0x0F, (byte) 0xD4, + (byte) 0x13, (byte) 0x1F, (byte) 0xBA, (byte) 0xB9, (byte) 0x69, + (byte) 0x71, (byte) 0x3D, (byte) 0xE4, (byte) 0xDC, (byte) 0x58, + (byte) 0x90, (byte) 0x34, (byte) 0x3A, (byte) 0x3C, (byte) 0xCA, + (byte) 0x10, (byte) 0x76, (byte) 0xC7, (byte) 0xC8, (byte) 0x45, + (byte) 0x33, (byte) 0xC3, (byte) 0x92, (byte) 0x1D, (byte) 0x2B, + (byte) 0x1C, (byte) 0x8F, (byte) 0x6F, (byte) 0x05, (byte) 0x07, + (byte) 0x38, (byte) 0x57, (byte) 0x51, (byte) 0xD6, (byte) 0xDA, + (byte) 0x2D, (byte) 0xB3, (byte) 0xC6, (byte) 0x2E, (byte) 0x64, + (byte) 0x32, (byte) 0x1E, (byte) 0x43, (byte) 0xB1, (byte) 0x5D, + (byte) 0xE1, (byte) 0xBB, (byte) 0x8E, (byte) 0x9D, (byte) 0x72, + (byte) 0x77, (byte) 0xF2, (byte) 0x27, (byte) 0xC9, (byte) 0x7F, + (byte) 0x9E, (byte) 0xAA, (byte) 0x6A, (byte) 0x2F, (byte) 0x6C, + (byte) 0xF9, (byte) 0x48, (byte) 0xE7, (byte) 0xA0, (byte) 0x09, + (byte) 0x56, (byte) 0xB8, (byte) 0xBD, (byte) 0x20, (byte) 0x41, + (byte) 0xCD, (byte) 0x95, (byte) 0x80, (byte) 0xD7, (byte) 0x23, + (byte) 0x0C, (byte) 0x42, (byte) 0xE5, (byte) 0xAE, (byte) 0x8B, + (byte) 0x7D, (byte) 0xBC, (byte) 0x54, (byte) 0x39, (byte) 0xBF, + (byte) 0x65, (byte) 0x01, (byte) 0x88, (byte) 0xE0, (byte) 0x7B, + (byte) 0xB6, (byte) 0x16, (byte) 0x18, (byte) 0x4B, (byte) 0xCC, + (byte) 0x22, (byte) 0x5A, (byte) 0xB5, (byte) 0xEB, (byte) 0xFC, + (byte) 0xF8, (byte) 0x9B, (byte) 0x4E, (byte) 0xE6, (byte) 0xA8, + (byte) 0xBE, (byte) 0x67, (byte) 0x73, (byte) 0x97, (byte) 0x94, + (byte) 0x00, (byte) 0x62, (byte) 0xB4, (byte) 0xD2, (byte) 0x21, + (byte) 0x25, (byte) 0x11, (byte) 0x82, (byte) 0xDB, (byte) 0x93, + (byte) 0x02, (byte) 0x84, (byte) 0x7C, (byte) 0xD3, (byte) 0xB0, + (byte) 0xA3, (byte) 0x91, (byte) 0xA7, (byte) 0xF7, (byte) 0x55, + (byte) 0x70, (byte) 0x7A, (byte) 0x08, (byte) 0x75, (byte) 0x8A, + (byte) 0x53, (byte) 0x79, (byte) 0xFB, (byte) 0x9F, (byte) 0x46, + (byte) 0xF5, (byte) 0x83, (byte) 0xD8, (byte) 0x0E, (byte) 0xE9, + (byte) 0xED, (byte) 0x12, (byte) 0xD1, (byte) 0xDF, (byte) 0xF0, + (byte) 0x37, (byte) 0x2A, (byte) 0x44, (byte) 0x19, (byte) 0x9A, + (byte) 0x31, (byte) 0xCF, (byte) 0xA1, (byte) 0xAF, (byte) 0xE3, + (byte) 0x3B, (byte) 0x1A, (byte) 0x4C, (byte) 0x78, (byte) 0xC2, + (byte) 0x60, (byte) 0xEE, (byte) 0x98, (byte) 0x6B, (byte) 0x0D, + (byte) 0x99, (byte) 0xEA, (byte) 0xC5, (byte) 0xAC }; - /* - * Can't use the RandomAccessFile readInt func as we need the bytes - * in reverse order - */ - private int readInt(RandomAccessFile file) throws IOException, EOFException { - int ch1 = file.read(); - int ch2 = file.read(); - int ch3 = file.read(); - int ch4 = file.read(); - if ((ch1 | ch2 | ch3 | ch4) < 0) { - throw new EOFException(); - } - return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0); - } + private long lower_offset; + private long upper_offset; - protected int getOffset(int value) throws EOFException, FileNotFoundException, IOException { - int res = -1; - if (value == 0) { - res = 0; - } else { - RandomAccessFile table = new RandomAccessFile("index.bin", "r"); - table.seek(value * 4 - 4); - res = readInt(table); - table.close(); - } - return res; - } - - protected int extractNumber(String filename) { - return Integer.parseInt(filename.substring(filename.indexOf(".") - 4, filename.indexOf("."))); - } + protected void initSeed(long seed) { + lower_offset = seed & 0xFFFF; + upper_offset = seed >> 0x10 & 0xFFFF; + if (lower_offset == 0) { + lower_offset = 0x7F8D; + } + if (upper_offset == 0) { + upper_offset = 0x2345; + } + } + + protected long getBeta() { + lower_offset = (lower_offset * 0x7F8D) % 0xFFF1; + upper_offset = (upper_offset * 0x2345) % 0xFFD9; + return lower_offset + (upper_offset << 0x10); + } + + protected void set_table_value(byte table[], int pos, long value) { + table[pos] = (byte) value; + table[pos + 1] = (byte) (value >> 8); + table[pos + 2] = (byte) (value >> 16); + table[pos + 3] = (byte) (value >> 24); + } + + protected long get_table_value(byte table[], int pos) { + return (table[pos] & 0xFF) + ((long) (table[pos + 1] & 0xFF) << 8) + + ((long) (table[pos + 2] & 0xFF) << 16) + + ((long) (table[pos + 3] & 0xFF) << 24); + } + + /* + * Can't use the RandomAccessFile readInt func as we need the bytes in + * reverse order + */ + private int readInt(RandomAccessFile file) throws IOException, EOFException { + int ch1 = file.read(); + int ch2 = file.read(); + int ch3 = file.read(); + int ch4 = file.read(); + if ((ch1 | ch2 | ch3 | ch4) < 0) { + throw new EOFException(); + } + return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0); + } + + protected int getOffset(int value) throws EOFException, + FileNotFoundException, IOException { + int res = -1; + if (value == 0) { + res = 0; + } else { + RandomAccessFile table = new RandomAccessFile("index.bin", "r"); + table.seek(value * 4 - 4); + res = readInt(table); + table.close(); + } + return res; + } + + protected int extractNumber(String filename) { + return Integer.parseInt(filename.substring(filename.indexOf(".") - 4, + filename.indexOf("."))); + } } diff --git a/src/crypt/Decrypter.java b/src/crypt/Decrypter.java index 161b164..23999c5 100644 --- a/src/crypt/Decrypter.java +++ b/src/crypt/Decrypter.java @@ -24,137 +24,141 @@ import java.io.IOException; import java.io.RandomAccessFile; public class Decrypter extends DecryptTable { - - public void decrypt_index(String in, ByteArrayOutputStream index_buffer) { - try { - RandomAccessFile filein = new RandomAccessFile(in, "r"); - RandomAccessFile fileout = new RandomAccessFile("index.bin", "rw"); - fileout.setLength(0); - byte[] buffer = new byte[4]; - System.out.println("Decrypting index..."); - initSeed(0); - boolean table_end = false; - boolean end_flag = false; - int i = 0; - while(!table_end) { - filein.read(buffer); - buffer[0] = decrypt_table[buffer[0] & 0xFF]; - buffer[1] = decrypt_table[buffer[1] & 0xFF]; - buffer[2] = decrypt_table[buffer[2] & 0xFF]; - buffer[3] = decrypt_table[buffer[3] & 0xFF]; - long beta = getBeta(); - long alpha = get_table_value(buffer, 0); - long gamma = alpha ^ beta; - - if(gamma > 0xFF) { - end_flag = true; - } else if(end_flag) { - table_end = true; - continue; - } - set_table_value(buffer, 0, gamma); - fileout.write(buffer); - if(index_buffer != null) - index_buffer.write(buffer); - i += 4; - } - fileout.close(); - System.out.println("Index size: " + i + " bytes"); - System.out.println("File count: " + i / 4); - }catch(FileNotFoundException e) { - e.printStackTrace(); - }catch(IOException e) { - e.printStackTrace(); - } - } - - public void decrypt_whole(String in, String out) { - ByteArrayOutputStream index_buffer = new ByteArrayOutputStream(); - decrypt_index(in, index_buffer); - RandomAccessFile filein; - try { - filein = new RandomAccessFile(in, "r"); - byte index_table[] = index_buffer.toByteArray(); - int files_count = index_table.length / 4; - new File(out).mkdir(); - boolean create_subdirectory = true; - int last_subdirectory = 0; - long last_offset = 0; - for(int i = 0; i < files_count; i++) { - if(create_subdirectory) { - last_subdirectory = i / 1000; - new File(out + "/0" + Integer.toString(last_subdirectory)).mkdir(); - create_subdirectory = false; - } else { - if(last_subdirectory < i / 1000) { - create_subdirectory = true; - } - } - long offset = last_offset; - last_offset = get_table_value(index_table, i * 4); - long file_length = (get_table_value(index_table, i * 4) - offset) << 11; - String fileout = out + - "/0" + Integer.toString(last_subdirectory) + - "/" + String.format("%04d.bin", i); - System.out.print("Decrypting " + fileout + "(" + file_length + " bytes/offset: " + (offset << 11) + ") ... "); - decrypt_internal(filein, offset, file_length, fileout, false); - - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - } - - private void decrypt_internal(RandomAccessFile filein, long pos, long size, String out, boolean single) { - try { - if(!single) - filein.seek(pos << 11); - RandomAccessFile fileout = new RandomAccessFile(out, "rw"); - byte buffer[] = new byte[1024]; - fileout.setLength(0); - initSeed(pos); - while (size > 0) { - int read = filein.read(buffer); - size -= read; - for(int i = 0; i < read; i += 4) { - buffer[i] = decrypt_table[buffer[i] & 0xFF]; - buffer[i+1] = decrypt_table[buffer[i+1] & 0xFF]; - buffer[i+2] = decrypt_table[buffer[i+2] & 0xFF]; - buffer[i+3] = decrypt_table[buffer[i+3] & 0xFF]; - long alpha = get_table_value(buffer, i); - long beta = getBeta(); - long gamma = alpha ^ beta; - set_table_value(buffer, i, gamma); - } - fileout.write(buffer); - } - fileout.close(); - System.out.println("Finished!"); - }catch(FileNotFoundException e) { - e.printStackTrace(); - }catch(IOException e) { - e.printStackTrace(); - } - } - public void decrypt(String in, String out) { - RandomAccessFile filein = null; - try { - filein = new RandomAccessFile(in, "r"); - System.out.print("Decrypting " + out + " ... "); - decrypt_internal(filein, getOffset(extractNumber(in)), filein.length(), out, true); - - }catch(FileNotFoundException e) { - e.printStackTrace(); - }catch(IOException e) { - e.printStackTrace(); - } finally { - if(filein != null) - try { - filein.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } + public void decrypt_index(String in, ByteArrayOutputStream index_buffer) { + try { + RandomAccessFile filein = new RandomAccessFile(in, "r"); + RandomAccessFile fileout = new RandomAccessFile("index.bin", "rw"); + fileout.setLength(0); + byte[] buffer = new byte[4]; + System.out.println("Decrypting index..."); + initSeed(0); + boolean table_end = false; + boolean end_flag = false; + int i = 0; + while (!table_end) { + filein.read(buffer); + buffer[0] = decrypt_table[buffer[0] & 0xFF]; + buffer[1] = decrypt_table[buffer[1] & 0xFF]; + buffer[2] = decrypt_table[buffer[2] & 0xFF]; + buffer[3] = decrypt_table[buffer[3] & 0xFF]; + long beta = getBeta(); + long alpha = get_table_value(buffer, 0); + long gamma = alpha ^ beta; + + if (gamma > 0xFF) { + end_flag = true; + } else if (end_flag) { + table_end = true; + continue; + } + set_table_value(buffer, 0, gamma); + fileout.write(buffer); + if (index_buffer != null) + index_buffer.write(buffer); + i += 4; + } + fileout.close(); + System.out.println("Index size: " + i + " bytes"); + System.out.println("File count: " + i / 4); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void decrypt_whole(String in, String out) { + ByteArrayOutputStream index_buffer = new ByteArrayOutputStream(); + decrypt_index(in, index_buffer); + RandomAccessFile filein; + try { + filein = new RandomAccessFile(in, "r"); + byte index_table[] = index_buffer.toByteArray(); + int files_count = index_table.length / 4; + new File(out).mkdir(); + boolean create_subdirectory = true; + int last_subdirectory = 0; + long last_offset = 0; + for (int i = 0; i < files_count; i++) { + if (create_subdirectory) { + last_subdirectory = i / 1000; + new File(out + "/0" + Integer.toString(last_subdirectory)) + .mkdir(); + create_subdirectory = false; + } else { + if (last_subdirectory < i / 1000) { + create_subdirectory = true; + } + } + long offset = last_offset; + last_offset = get_table_value(index_table, i * 4); + long file_length = (get_table_value(index_table, i * 4) - offset) << 11; + String fileout = out + "/0" + + Integer.toString(last_subdirectory) + "/" + + String.format("%04d.bin", i); + System.out.print("Decrypting " + fileout + "(" + file_length + + " bytes/offset: " + (offset << 11) + ") ... "); + decrypt_internal(filein, offset, file_length, fileout, false); + + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + + private void decrypt_internal(RandomAccessFile filein, long pos, long size, + String out, boolean single) { + try { + if (!single) + filein.seek(pos << 11); + RandomAccessFile fileout = new RandomAccessFile(out, "rw"); + byte buffer[] = new byte[1024]; + fileout.setLength(0); + initSeed(pos); + while (size > 0) { + int read = filein.read(buffer); + size -= read; + for (int i = 0; i < read; i += 4) { + buffer[i] = decrypt_table[buffer[i] & 0xFF]; + buffer[i + 1] = decrypt_table[buffer[i + 1] & 0xFF]; + buffer[i + 2] = decrypt_table[buffer[i + 2] & 0xFF]; + buffer[i + 3] = decrypt_table[buffer[i + 3] & 0xFF]; + long alpha = get_table_value(buffer, i); + long beta = getBeta(); + long gamma = alpha ^ beta; + set_table_value(buffer, i, gamma); + } + fileout.write(buffer); + } + fileout.close(); + System.out.println("Finished!"); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void decrypt(String in, String out) { + RandomAccessFile filein = null; + try { + filein = new RandomAccessFile(in, "r"); + System.out.print("Decrypting " + out + " ... "); + decrypt_internal(filein, getOffset(extractNumber(in)), + filein.length(), out, true); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (filein != null) + try { + filein.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } } diff --git a/src/crypt/Encrypter.java b/src/crypt/Encrypter.java index 299c99e..72c535b 100644 --- a/src/crypt/Encrypter.java +++ b/src/crypt/Encrypter.java @@ -22,41 +22,41 @@ import java.io.IOException; import java.io.RandomAccessFile; public class Encrypter extends DecryptTable { - - private byte []encrypt_table; - - public Encrypter() { - encrypt_table = new byte[256]; - for(int i = 0;i < 256; i++) { - encrypt_table[decrypt_table[i] & 0xFF] = (byte)i; - } - } - public void encrypt(String in, String out) { - try { - RandomAccessFile filein = new RandomAccessFile(in, "r"); - RandomAccessFile fileout = new RandomAccessFile(out, "rw"); - initSeed(getOffset(extractNumber(in))); - byte[] buffer = new byte[4]; - System.out.println("Encrypting " + in); - while (filein.read(buffer) >= 0) { - long gamma = get_table_value(buffer, 0); - long beta = getBeta(); - long alpha = beta ^ gamma; - set_table_value(buffer, 0, alpha); - buffer[0] = encrypt_table[buffer[0] & 0xFF]; - buffer[1] = encrypt_table[buffer[1] & 0xFF]; - buffer[2] = encrypt_table[buffer[2] & 0xFF]; - buffer[3] = encrypt_table[buffer[3] & 0xFF]; - fileout.write(buffer); - } - filein.close(); - fileout.close(); - System.out.println("Finished!"); - }catch(FileNotFoundException e) { - e.printStackTrace(); - }catch(IOException e) { - e.printStackTrace(); - } - } + private byte[] encrypt_table; + + public Encrypter() { + encrypt_table = new byte[256]; + for (int i = 0; i < 256; i++) { + encrypt_table[decrypt_table[i] & 0xFF] = (byte) i; + } + } + + public void encrypt(String in, String out) { + try { + RandomAccessFile filein = new RandomAccessFile(in, "r"); + RandomAccessFile fileout = new RandomAccessFile(out, "rw"); + initSeed(getOffset(extractNumber(in))); + byte[] buffer = new byte[4]; + System.out.println("Encrypting " + in); + while (filein.read(buffer) >= 0) { + long gamma = get_table_value(buffer, 0); + long beta = getBeta(); + long alpha = beta ^ gamma; + set_table_value(buffer, 0, alpha); + buffer[0] = encrypt_table[buffer[0] & 0xFF]; + buffer[1] = encrypt_table[buffer[1] & 0xFF]; + buffer[2] = encrypt_table[buffer[2] & 0xFF]; + buffer[3] = encrypt_table[buffer[3] & 0xFF]; + fileout.write(buffer); + } + filein.close(); + fileout.close(); + System.out.println("Finished!"); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } } diff --git a/src/dec/ExtractPluginA.java b/src/dec/ExtractPluginA.java index 60c0f41..9791fc5 100644 --- a/src/dec/ExtractPluginA.java +++ b/src/dec/ExtractPluginA.java @@ -32,89 +32,97 @@ import base.Decoder; */ public class ExtractPluginA extends Decoder { - @Override - public void extract(String filename) { - int tables_count; - byte[] paddingData; - int[] table_offset; - int offset; - try { - RandomAccessFile file = new RandomAccessFile(filename, "r"); - // reading of number of main tables - tables_count = readInt(file); - // skipping 4 bytes of unknown data - file.skipBytes(4); - table_offset = new int[tables_count]; - // read the location of each table - for (int i = 0; i < tables_count; i++) { - table_offset[i] = readInt(file); - } - String directory = filename.split("\\.")[0]; - new File(directory).mkdir(); - // create the list of string tables used in the rebuild - PrintStream filelist = new PrintStream(new FileOutputStream(new File(directory + "/filelist.txt")), true, "UTF-8"); - // save the name and size of the file - filelist.println(filename + " " + file.length()); - for (int j = 0; j < tables_count; j++) { - if(table_offset[j] == -1) { - //System.out.println("Creating " + directory + "/string_table_" + j + ".txt (empty)"); - System.out.println("Can't create " + directory + "/string_table_" + j + ".txt (null table), skipping."); - File f = new File(directory + "/string_table_" + j + ".txt"); - f.delete(); - //f.createNewFile(); - filelist.println("string_table_" + j + ".txt"); - continue; - } - file.seek(table_offset[j]); - System.out.println("Creating " + directory + "/string_table_" + j + ".txt"); - PrintStream stringout = new PrintStream(new FileOutputStream(new File(directory + "/string_table_" + j + ".txt")), true, "UTF-8"); - filelist.println("string_table_" + j + ".txt"); - int offsetCounter = 0; - // just skip the offset section (not needed) - while (true) { - offset = readInt(file); - if (offset == -1) { - break; - } - offsetCounter++; - } - int stringCounter = 0; - while (stringCounter < offsetCounter) { - String str = readString(file); - if (str.length() == 1 && str.charAt(0) == 0) { - // some offsets points to empty strings, so i put this - // string to make - // sure that it will created at the moment of repack - stringout.println(""); - } else { - str = str.substring(0, str.length() - 1); - // need one string per line, so better replace the - // newlines - stringout.println(str.replaceAll("\n", "")); - } - stringCounter++; - } - // skip the end-byte mark - file.skipBytes(1); - stringout.close(); - } - file.seek(file.getFilePointer() - 1); - // calculate the size of the ending padding data and make a file of - // it - int size = (int) (file.length() - file.getFilePointer()); - paddingData = new byte[size]; - file.read(paddingData, 0, size); - System.out.println("Creating " + directory + "/enddata.bin"); - RandomAccessFile end = new RandomAccessFile(directory + "/enddata.bin", "rw"); - filelist.println("enddata.bin"); - end.write(paddingData, 0, size); - end.setLength(end.getFilePointer()); - end.close(); - file.close(); - filelist.close(); - System.out.println("Finished!"); - } catch (IOException e) { - e.printStackTrace(); - } - } + @Override + public void extract(String filename) { + int tables_count; + byte[] paddingData; + int[] table_offset; + int offset; + try { + RandomAccessFile file = new RandomAccessFile(filename, "r"); + // reading of number of main tables + tables_count = readInt(file); + // skipping 4 bytes of unknown data + file.skipBytes(4); + table_offset = new int[tables_count]; + // read the location of each table + for (int i = 0; i < tables_count; i++) { + table_offset[i] = readInt(file); + } + String directory = filename.split("\\.")[0]; + new File(directory).mkdir(); + // create the list of string tables used in the rebuild + PrintStream filelist = new PrintStream(new FileOutputStream( + new File(directory + "/filelist.txt")), true, "UTF-8"); + // save the name and size of the file + filelist.println(filename + " " + file.length()); + for (int j = 0; j < tables_count; j++) { + if (table_offset[j] == -1) { + // System.out.println("Creating " + directory + + // "/string_table_" + j + ".txt (empty)"); + System.out.println("Can't create " + directory + + "/string_table_" + j + + ".txt (null table), skipping."); + File f = new File(directory + "/string_table_" + j + ".txt"); + f.delete(); + // f.createNewFile(); + filelist.println("string_table_" + j + ".txt"); + continue; + } + file.seek(table_offset[j]); + System.out.println("Creating " + directory + "/string_table_" + + j + ".txt"); + PrintStream stringout = new PrintStream(new FileOutputStream( + new File(directory + "/string_table_" + j + ".txt")), + true, "UTF-8"); + filelist.println("string_table_" + j + ".txt"); + int offsetCounter = 0; + // just skip the offset section (not needed) + while (true) { + offset = readInt(file); + if (offset == -1) { + break; + } + offsetCounter++; + } + int stringCounter = 0; + while (stringCounter < offsetCounter) { + String str = readString(file); + if (str.length() == 1 && str.charAt(0) == 0) { + // some offsets points to empty strings, so i put this + // string to make + // sure that it will created at the moment of repack + stringout.println(""); + } else { + str = str.substring(0, str.length() - 1); + // need one string per line, so better replace the + // newlines + stringout.println(str.replaceAll("\n", "")); + } + stringCounter++; + } + // skip the end-byte mark + file.skipBytes(1); + stringout.close(); + } + file.seek(file.getFilePointer() - 1); + // calculate the size of the ending padding data and make + // a file of it + int size = (int) (file.length() - file.getFilePointer()); + paddingData = new byte[size]; + file.read(paddingData, 0, size); + System.out.println("Creating " + directory + "/enddata.bin"); + RandomAccessFile end = new RandomAccessFile(directory + + "/enddata.bin", "rw"); + filelist.println("enddata.bin"); + end.write(paddingData, 0, size); + end.setLength(end.getFilePointer()); + end.close(); + file.close(); + filelist.close(); + System.out.println("Finished!"); + } catch (IOException e) { + e.printStackTrace(); + } + } } diff --git a/src/dec/ExtractPluginB.java b/src/dec/ExtractPluginB.java index fbcaceb..1e5e0b7 100644 --- a/src/dec/ExtractPluginB.java +++ b/src/dec/ExtractPluginB.java @@ -37,111 +37,119 @@ import base.Decoder; */ public class ExtractPluginB extends Decoder { - private int mhp3_skip_bytes; - public ExtractPluginB(boolean newdec) { - mhp3_skip_bytes = newdec ? 4 : 0; - } + private int mhp3_skip_bytes; - @Override - public void extract(String filename) { - byte[] unknownData; - Vector table_offset; - try { - RandomAccessFile file = new RandomAccessFile(filename, "r"); - table_offset = new Vector(); - int pointer; - while (true) { - pointer = readInt(file); - if (pointer == 0) { - break; - } - table_offset.add(pointer); - } - String directory = filename.split("\\.")[0]; - new File(directory).mkdir(); - PrintStream filelist = new PrintStream(new FileOutputStream(new File(directory + "/filelist.txt")), true, "UTF-8"); - filelist.println(filename + " " + file.length()); - for (int j = 0; j < table_offset.size(); j++) { - file.seek(table_offset.get(j)); - System.out.println("Creating " + directory + "/string_table_" + j + ".txt"); - PrintStream stringout = new PrintStream(new FileOutputStream(new File(directory + "/string_table_" + j + ".txt")), true, "UTF-8"); - filelist.println("string_table_" + j + ".txt"); - // int unknown0 = readInt(file); - // int payment = readInt(file); - // int reward = readInt(file); - // int decrease = readInt(file); - // int unknown_fixed = readInt(file); - file.skipBytes(20 + mhp3_skip_bytes); - int offset_table_pointer = readInt(file); - // int unknown1 = readInt(file); - // int unknown2 = readInt(file); - // int unknown3 = readInt(file); - // int unknown4 = readInt(file); - // int unknown5 = readInt(file); - // int unknown6 = readInt(file); - // int unknown7 = readInt(file); - file.seek(offset_table_pointer); - int string_table_pointers = readInt(file); - for (long i = string_table_pointers; i < offset_table_pointer; i += 4) { - file.seek(i); - int current_string = readInt(file); - file.seek(current_string); - String str = readString(file); - if (str.length() == 1 && str.charAt(0) == 0) { - // some offsets points to empty strings, so i put this - // string to make - // sure that it will created at the moment of re-pack - stringout.println(""); - } else { - str = str.substring(0, str.length() - 1); - // need one string per line, so better replace the - // newlines - stringout.println(str.replaceAll("\n", "")); - } - } - stringout.close(); - file.seek(offset_table_pointer + 7 * 4); - } - // calculate the size of the ending unknown data and make a file of - // it - int size = (int) (file.length() - file.getFilePointer()); - unknownData = new byte[size]; - file.read(unknownData, 0, size); - System.out.println("Creating " + directory + "/enddata.bin"); - RandomAccessFile end = new RandomAccessFile(directory + "/enddata.bin", "rw"); - filelist.println("enddata.bin"); - end.write(unknownData, 0, size); - end.setLength(end.getFilePointer()); - end.close(); - file.close(); - filelist.close(); - System.out.println("Copying " + filename + " to " + directory + "/" + filename + " (needed for rebuild)"); - copyfile(filename, directory + "/" + filename); - System.out.println("Finished!"); - } catch (IOException e) { - e.printStackTrace(); - } - } - - private void copyfile(String srFile, String dtFile) { - try { - File f1 = new File(srFile); - File f2 = new File(dtFile); - InputStream in = new FileInputStream(f1); - OutputStream out = new FileOutputStream(f2); + public ExtractPluginB(boolean newdec) { + mhp3_skip_bytes = newdec ? 4 : 0; + } - byte[] buf = new byte[1024]; - int len; - while ((len = in.read(buf)) > 0) { - out.write(buf, 0, len); - } - in.close(); - out.close(); - } catch (FileNotFoundException ex) { - System.out.println(ex.getMessage() + " in the specified directory."); - System.exit(0); - } catch (IOException e) { - System.out.println(e.getMessage()); - } - } + @Override + public void extract(String filename) { + byte[] unknownData; + Vector table_offset; + try { + RandomAccessFile file = new RandomAccessFile(filename, "r"); + table_offset = new Vector(); + int pointer; + while (true) { + pointer = readInt(file); + if (pointer == 0) { + break; + } + table_offset.add(pointer); + } + String directory = filename.split("\\.")[0]; + new File(directory).mkdir(); + PrintStream filelist = new PrintStream(new FileOutputStream( + new File(directory + "/filelist.txt")), true, "UTF-8"); + filelist.println(filename + " " + file.length()); + for (int j = 0; j < table_offset.size(); j++) { + file.seek(table_offset.get(j)); + System.out.println("Creating " + directory + "/string_table_" + + j + ".txt"); + PrintStream stringout = new PrintStream(new FileOutputStream( + new File(directory + "/string_table_" + j + ".txt")), + true, "UTF-8"); + filelist.println("string_table_" + j + ".txt"); + // int unknown0 = readInt(file); + // int payment = readInt(file); + // int reward = readInt(file); + // int decrease = readInt(file); + // int unknown_fixed = readInt(file); + file.skipBytes(20 + mhp3_skip_bytes); + int offset_table_pointer = readInt(file); + // int unknown1 = readInt(file); + // int unknown2 = readInt(file); + // int unknown3 = readInt(file); + // int unknown4 = readInt(file); + // int unknown5 = readInt(file); + // int unknown6 = readInt(file); + // int unknown7 = readInt(file); + file.seek(offset_table_pointer); + int string_table_pointers = readInt(file); + for (long i = string_table_pointers; i < offset_table_pointer; i += 4) { + file.seek(i); + int current_string = readInt(file); + file.seek(current_string); + String str = readString(file); + if (str.length() == 1 && str.charAt(0) == 0) { + // some offsets points to empty strings, so i put this + // string to make + // sure that it will created at the moment of re-pack + stringout.println(""); + } else { + str = str.substring(0, str.length() - 1); + // need one string per line, so better replace the + // newlines + stringout.println(str.replaceAll("\n", "")); + } + } + stringout.close(); + file.seek(offset_table_pointer + 7 * 4); + } + // calculate the size of the ending unknown data and + // make a file of it + int size = (int) (file.length() - file.getFilePointer()); + unknownData = new byte[size]; + file.read(unknownData, 0, size); + System.out.println("Creating " + directory + "/enddata.bin"); + RandomAccessFile end = new RandomAccessFile(directory + + "/enddata.bin", "rw"); + filelist.println("enddata.bin"); + end.write(unknownData, 0, size); + end.setLength(end.getFilePointer()); + end.close(); + file.close(); + filelist.close(); + System.out.println("Copying " + filename + " to " + directory + "/" + + filename + " (needed for rebuild)"); + copyfile(filename, directory + "/" + filename); + System.out.println("Finished!"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void copyfile(String srFile, String dtFile) { + try { + File f1 = new File(srFile); + File f2 = new File(dtFile); + InputStream in = new FileInputStream(f1); + OutputStream out = new FileOutputStream(f2); + + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + in.close(); + out.close(); + } catch (FileNotFoundException ex) { + System.out + .println(ex.getMessage() + " in the specified directory."); + System.exit(0); + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } } diff --git a/src/dec/ExtractPluginC.java b/src/dec/ExtractPluginC.java index ecf3317..9616df7 100644 --- a/src/dec/ExtractPluginC.java +++ b/src/dec/ExtractPluginC.java @@ -33,85 +33,91 @@ import base.Decoder; */ public class ExtractPluginC extends Decoder { - @Override - public void extract(String filename) { - Vector offset_tables = new Vector(); - Vector unknown_values = new Vector(); - try { - RandomAccessFile file = new RandomAccessFile(filename, "r"); - while (true) { - int unknown = readInt(file); - int offset = readInt(file); - if (unknown == -1 && offset == -1) { - break; - } - unknown_values.add(unknown); - offset_tables.add(offset); + @Override + public void extract(String filename) { + Vector offset_tables = new Vector(); + Vector unknown_values = new Vector(); + try { + RandomAccessFile file = new RandomAccessFile(filename, "r"); + while (true) { + int unknown = readInt(file); + int offset = readInt(file); + if (unknown == -1 && offset == -1) { + break; + } + unknown_values.add(unknown); + offset_tables.add(offset); - } - String directory = filename.split("\\.")[0]; - new File(directory).mkdir(); - // create the list of string tables used in the rebuild - PrintStream filelist = new PrintStream(new FileOutputStream(new File(directory + "/filelist.txt")), true, "UTF-8"); - // save the name and size of the file - filelist.println(filename + " " + file.length()); - int string_table_end = 0; - ; - for (int j = 0; j < offset_tables.size(); j++) { - file.seek(offset_tables.get(j)); - System.out.println("Creating " + directory + "/string_table_" + j + ".txt"); - PrintStream stringout = new PrintStream(new FileOutputStream(new File(directory + "/string_table_" + j + ".txt")), true, "UTF-8"); - filelist.println(unknown_values.get(j) + ",string_table_" + j + ".txt"); - int offset_table_start = (int) file.getFilePointer(); - int string_table_start = 0; - boolean first = false; - while (true) { - int unknown = readInt(file); - int offset = readInt(file); - if (!first) { - first = true; - string_table_start = offset + offset_table_start; - } - int actual_offset = (int) file.getFilePointer(); - file.seek(offset + offset_table_start); - String str = readString(file); - string_table_end = (int) file.getFilePointer(); - file.seek(actual_offset); - if (str.length() == 1 && str.charAt(0) == 0) { - // some offsets points to empty strings, so i put this - // string to make - // sure that it will created at the moment of re-pack - stringout.println(unknown + ","); - } else { - str = str.substring(0, str.length() - 1); - // need one string per line, so better replace the - // newlines - stringout.println(unknown + "," - + str.replaceAll("\n", "")); - } - if (file.getFilePointer() >= string_table_start) { - break; - } - } - stringout.close(); - } - file.seek(string_table_end); - // calculate the size of the ending unknown data and make a file of - // it - int size = (int) (file.length() - file.getFilePointer()); - byte[] unknownData = new byte[size]; - file.read(unknownData, 0, size); - file.close(); - System.out.println("Creating " + directory + "/enddata.bin"); - RandomAccessFile end = new RandomAccessFile(directory + "/enddata.bin", "rw"); - filelist.println("enddata.bin"); - filelist.close(); - end.write(unknownData, 0, size); - end.setLength(end.getFilePointer()); - end.close(); - System.out.println("Finished!"); - } catch (IOException e) { - e.printStackTrace(); - } - } + } + String directory = filename.split("\\.")[0]; + new File(directory).mkdir(); + // create the list of string tables used in the rebuild + PrintStream filelist = new PrintStream(new FileOutputStream( + new File(directory + "/filelist.txt")), true, "UTF-8"); + // save the name and size of the file + filelist.println(filename + " " + file.length()); + int string_table_end = 0; + ; + for (int j = 0; j < offset_tables.size(); j++) { + file.seek(offset_tables.get(j)); + System.out.println("Creating " + directory + "/string_table_" + + j + ".txt"); + PrintStream stringout = new PrintStream(new FileOutputStream( + new File(directory + "/string_table_" + j + ".txt")), + true, "UTF-8"); + filelist.println(unknown_values.get(j) + ",string_table_" + j + + ".txt"); + int offset_table_start = (int) file.getFilePointer(); + int string_table_start = 0; + boolean first = false; + while (true) { + int unknown = readInt(file); + int offset = readInt(file); + if (!first) { + first = true; + string_table_start = offset + offset_table_start; + } + int actual_offset = (int) file.getFilePointer(); + file.seek(offset + offset_table_start); + String str = readString(file); + string_table_end = (int) file.getFilePointer(); + file.seek(actual_offset); + if (str.length() == 1 && str.charAt(0) == 0) { + // some offsets points to empty strings, so i put this + // string to make + // sure that it will created at the moment of re-pack + stringout.println(unknown + ","); + } else { + str = str.substring(0, str.length() - 1); + // need one string per line, so better replace the + // newlines + stringout.println(unknown + "," + + str.replaceAll("\n", "")); + } + if (file.getFilePointer() >= string_table_start) { + break; + } + } + stringout.close(); + } + file.seek(string_table_end); + // calculate the size of the ending unknown data and + // make a file of it + int size = (int) (file.length() - file.getFilePointer()); + byte[] unknownData = new byte[size]; + file.read(unknownData, 0, size); + file.close(); + System.out.println("Creating " + directory + "/enddata.bin"); + RandomAccessFile end = new RandomAccessFile(directory + + "/enddata.bin", "rw"); + filelist.println("enddata.bin"); + filelist.close(); + end.write(unknownData, 0, size); + end.setLength(end.getFilePointer()); + end.close(); + System.out.println("Finished!"); + } catch (IOException e) { + e.printStackTrace(); + } + } } diff --git a/src/enc/RebuildPluginA.java b/src/enc/RebuildPluginA.java index d4892c2..1f7e66a 100644 --- a/src/enc/RebuildPluginA.java +++ b/src/enc/RebuildPluginA.java @@ -34,161 +34,171 @@ import base.Encoder; */ public class RebuildPluginA extends Encoder { - @Override - public void compile(String filepath) { - try { - BufferedReader files = new BufferedReader(new FileReader(filepath + "/filelist.txt")); - String file = files.readLine(); - // retrieve the filename and size - String filename = file.split(" ")[0]; - long size = Integer.parseInt(file.split(" ")[1]); - // now make a list with the string tables files - Vector filenames = new Vector(); - while ((file = files.readLine()) != null) { - filenames.add(file); - } - files.close(); - RandomAccessFile out = new RandomAccessFile(filename + ".out", "rw"); - out.setLength(0); - // write the first value (number of tables) - writeInt(out, filenames.size() - 1); - int offset = 0; - offset += 8; - // write the second value (unknown...or maybe offset to tables - // offsets?) - writeInt(out, offset); - offset += (filenames.size() - 1) * 4; - // write the first table offset (fixed value) - writeInt(out, offset); - long table_offset = out.getFilePointer(); - // first write empty offset values (we don't know the values...yet) - for (int i = 1; i < filenames.size() - 1; i++) { - writeInt(out, 0); - } - for (int i = 0; i < filenames.size() - 1; i++) { - // now start to create each offset table / string table - try { - createStringTable(filepath, filenames.get(i), out); - // write the end-table mark - out.writeByte(0); - if (i < filenames.size() - 2) { - long current = out.getFilePointer(); - out.seek(table_offset); - // now we know the value of the next table, so write above - // in the main offset table - writeInt(out, (int) current); - out.seek(current); - table_offset += 4; - } - }catch(FileNotFoundException e) { - // New in MHP3: null tables - System.out.println(filenames.get(i) + " not found, assuming null table pointer."); - if (i < filenames.size() - 2) { - long current = out.getFilePointer(); - out.seek(table_offset - 4); - int last_offset = readInt(out); - out.seek(table_offset - 4); - writeInt(out, -1); - out.seek(table_offset); - writeInt(out, last_offset); - out.seek(current); - table_offset += 4; - } - } - } - // we need to know the size of the enddata, so open it now - System.out.println("Reading " + filenames.lastElement()); - RandomAccessFile enddata = new RandomAccessFile(filepath + "/" + filenames.lastElement(), "rw"); + @Override + public void compile(String filepath) { + try { + BufferedReader files = new BufferedReader(new FileReader(filepath + + "/filelist.txt")); + String file = files.readLine(); + // retrieve the filename and size + String filename = file.split(" ")[0]; + long size = Integer.parseInt(file.split(" ")[1]); + // now make a list with the string tables files + Vector filenames = new Vector(); + while ((file = files.readLine()) != null) { + filenames.add(file); + } + files.close(); + RandomAccessFile out = new RandomAccessFile(filename + ".out", "rw"); + out.setLength(0); + // write the first value (number of tables) + writeInt(out, filenames.size() - 1); + int offset = 0; + offset += 8; + // write the second value (unknown...or maybe offset to tables + // offsets?) + writeInt(out, offset); + offset += (filenames.size() - 1) * 4; + // write the first table offset (fixed value) + writeInt(out, offset); + long table_offset = out.getFilePointer(); + // first write empty offset values (we don't know the values...yet) + for (int i = 1; i < filenames.size() - 1; i++) { + writeInt(out, 0); + } + for (int i = 0; i < filenames.size() - 1; i++) { + // now start to create each offset table / string table + try { + createStringTable(filepath, filenames.get(i), out); + // write the end-table mark + out.writeByte(0); + if (i < filenames.size() - 2) { + long current = out.getFilePointer(); + out.seek(table_offset); + // now we know the value of the next table, so write + // above + // in the main offset table + writeInt(out, (int) current); + out.seek(current); + table_offset += 4; + } + } catch (FileNotFoundException e) { + // New in MHP3: null tables + System.out.println(filenames.get(i) + + " not found, assuming null table pointer."); + if (i < filenames.size() - 2) { + long current = out.getFilePointer(); + out.seek(table_offset - 4); + int last_offset = readInt(out); + out.seek(table_offset - 4); + writeInt(out, -1); + out.seek(table_offset); + writeInt(out, last_offset); + out.seek(current); + table_offset += 4; + } + } + } + // we need to know the size of the enddata, so open it now + System.out.println("Reading " + filenames.lastElement()); + RandomAccessFile enddata = new RandomAccessFile(filepath + "/" + + filenames.lastElement(), "rw"); - long enddataSize = enddata.length(); + long enddataSize = enddata.length(); - // some checks to make sure that the file size of xxxx.bin is - // correct - if (out.getFilePointer() > size - enddataSize) { - System.out.println("File too big (by " + (out.getFilePointer() - (size - enddataSize))+ " bytes), please reduce some strings :("); - } else if (out.getFilePointer() < size - enddataSize) { - System.out.println("File too small (by " + ((size - enddataSize) - out.getFilePointer())+ " bytes), filling with 0x00 (this is OK) :D"); - while (out.getFilePointer() < size - enddataSize) { - out.writeByte(0); - } - } else { - System.out.println("Perfect size of file :O"); - } - // now append the padding data at the end of file - int data; - while ((data = enddata.read()) != -1) { - out.write((byte) data); - } - enddata.close(); - out.setLength(out.getFilePointer()); - out.close(); - System.out.println("Finished!"); - } catch (FileNotFoundException e) { - System.out.println(e.toString()); - } catch (IOException e) { - e.printStackTrace(); - } - } + // some checks to make sure that the file size of xxxx.bin is + // correct + if (out.getFilePointer() > size - enddataSize) { + System.out.println("File too big (by " + + (out.getFilePointer() - (size - enddataSize)) + + " bytes), please reduce some strings :("); + } else if (out.getFilePointer() < size - enddataSize) { + System.out.println("File too small (by " + + ((size - enddataSize) - out.getFilePointer()) + + " bytes), filling with 0x00 (this is OK) :D"); + while (out.getFilePointer() < size - enddataSize) { + out.writeByte(0); + } + } else { + System.out.println("Perfect size of file :O"); + } + // now append the padding data at the end of file + int data; + while ((data = enddata.read()) != -1) { + out.write((byte) data); + } + enddata.close(); + out.setLength(out.getFilePointer()); + out.close(); + System.out.println("Finished!"); + } catch (FileNotFoundException e) { + System.out.println(e.toString()); + } catch (IOException e) { + e.printStackTrace(); + } + } - /** - * - * @param in - * filename of text file - * @param out - * file to write the table - * @throws FileNotFoundException - * if the file is not found - * @throws IOException - * if any error occur while reading/writing - */ - public void createStringTable(String directory, String in, RandomAccessFile out) throws FileNotFoundException, IOException { - System.out.println("Reading " + directory + "/" + in); - RandomAccessFile file = new RandomAccessFile(directory + "/" + in, "r"); - if(file.length() == 0) { - // new in MHP3: empty tables - writeInt(out, -1); - file.close(); - return; - } - checkUnicodeBOM(file); // thanks notepad :/ (who the hell uses notepad?) - Vector stringTable = new Vector(); - try { - while (true) { - // read all strings of file - String str = readString(file); - if (str == null) { - break; - } - // remove the labels and put the original data - str = str.replaceAll("", "\n"); - str = str.replaceAll("", "\0"); - stringTable.add(str); - } - } catch (EOFException e) { - file.close(); - } - int offset = stringTable.size() * 4; - offset += 4; - // now calculate the offsets using the length in bytes of the strings - for (int i = 0; i < stringTable.size(); i++) { - writeInt(out, offset); - if (stringTable.elementAt(i).getBytes("UTF-8").length == 1 && stringTable.elementAt(i).charAt(0) == '\0') { - offset++; - } else { - offset += stringTable.elementAt(i).getBytes("UTF-8").length + 1; - } - } - // end of offset table mark - writeInt(out, -1); - // now write the zero terminated string in the file - for (int i = 0; i < stringTable.size(); i++) { - String str = stringTable.elementAt(i); - if (str.equals("\0")) { - out.writeByte(0); - } else { - out.write(str.getBytes("UTF-8")); - out.writeByte(0); - } - } - } + /** + * + * @param in + * filename of text file + * @param out + * file to write the table + * @throws FileNotFoundException + * if the file is not found + * @throws IOException + * if any error occur while reading/writing + */ + public void createStringTable(String directory, String in, + RandomAccessFile out) throws FileNotFoundException, IOException { + System.out.println("Reading " + directory + "/" + in); + RandomAccessFile file = new RandomAccessFile(directory + "/" + in, "r"); + if (file.length() == 0) { + // new in MHP3: empty tables + writeInt(out, -1); + file.close(); + return; + } + checkUnicodeBOM(file); // thanks notepad :/ (who the hell uses notepad?) + Vector stringTable = new Vector(); + try { + while (true) { + // read all strings of file + String str = readString(file); + if (str == null) { + break; + } + // remove the labels and put the original data + str = str.replaceAll("", "\n"); + str = str.replaceAll("", "\0"); + stringTable.add(str); + } + } catch (EOFException e) { + file.close(); + } + int offset = stringTable.size() * 4; + offset += 4; + // now calculate the offsets using the length in bytes of the strings + for (int i = 0; i < stringTable.size(); i++) { + writeInt(out, offset); + if (stringTable.elementAt(i).getBytes("UTF-8").length == 1 + && stringTable.elementAt(i).charAt(0) == '\0') { + offset++; + } else { + offset += stringTable.elementAt(i).getBytes("UTF-8").length + 1; + } + } + // end of offset table mark + writeInt(out, -1); + // now write the zero terminated string in the file + for (int i = 0; i < stringTable.size(); i++) { + String str = stringTable.elementAt(i); + if (str.equals("\0")) { + out.writeByte(0); + } else { + out.write(str.getBytes("UTF-8")); + out.writeByte(0); + } + } + } } diff --git a/src/enc/RebuildPluginB.java b/src/enc/RebuildPluginB.java index 6603b75..258852e 100644 --- a/src/enc/RebuildPluginB.java +++ b/src/enc/RebuildPluginB.java @@ -40,137 +40,146 @@ import base.Encoder; */ public class RebuildPluginB extends Encoder { - private int encoder = 0; - public RebuildPluginB(int type) { - encoder = type; - } + private int encoder = 0; - @Override - public void compile(String filepath) { - try { - BufferedReader files = new BufferedReader(new FileReader(filepath + "/filelist.txt")); - String file = files.readLine(); - // retrieve the filename and size - String filename = file.split(" ")[0]; - // long size = Integer.parseInt(file.split(" ")[1]); - // now make a list with the string tables files - Vector filenames = new Vector(); - while ((file = files.readLine()) != null) { - filenames.add(file); - } - files.close(); - copyfile(filepath + "/" + filename, filename + ".out"); - RandomAccessFile out = new RandomAccessFile(filename + ".out", "rw"); - Vector table_offset = new Vector(); - int pointer; - while (true) { - pointer = readInt(out); - if (pointer == 0) { - break; - } - table_offset.add(pointer); - } - for (int i = 0; i < table_offset.size(); i++) { - patchStringTable(filepath, filenames.get(i), out, table_offset.get(i)); - } - out.close(); - System.out.println("Finished!"); - } catch (FileNotFoundException e) { - System.out.println(e.toString()); - } catch (IOException e) { - e.printStackTrace(); - } - } + public RebuildPluginB(int type) { + encoder = type; + } - private void patchStringTable(String directory, String in, RandomAccessFile out, int starting_offset) throws FileNotFoundException, IOException { - System.out.println("Reading " + directory + "/" + in); - RandomAccessFile file = new RandomAccessFile(directory + "/" + in, "r"); - checkUnicodeBOM(file); // thanks notepad :/ (die notepad, die) - Vector stringTable = new Vector(); - try { - while (true) { - // read all strings of file - String str = readString(file); - if (str == null) { - break; - } - // remove the labels and put the original data - str = str.replaceAll("", "\n"); - str = str.replaceAll("", "\0"); - stringTable.add(str); - } - } catch (EOFException e) { - } - file.close(); - out.seek(starting_offset); - out.skipBytes(20 + encoder); - int offset_table_pointer = readInt(out); - int string_start = (int) out.getFilePointer() + 28; - out.seek(offset_table_pointer); - int string_table_pointers = readInt(out); - int diff = string_table_pointers - string_start - calculateTotalSize(stringTable); - if (diff < 0) { - System.err.println(in + " is too big, please remove at least " + -diff + " bytes. Skipped"); - return; - } - out.seek(string_table_pointers); - int starting_string = readInt(out); - out.seek(starting_string); - long orig_table_pointer = string_table_pointers; - for (String str : stringTable) { - out.write(str.getBytes("UTF-8")); - out.writeByte(0); - out.writeByte(0); - while (out.getFilePointer() % 4 != 0) { - out.writeByte(0); - } - int tmp = (int) out.getFilePointer(); - out.seek(string_table_pointers); - writeInt(out, starting_string); - string_table_pointers += 4; - starting_string = tmp; - out.seek(tmp); - } - long current_offset = out.getFilePointer(); - while (current_offset < orig_table_pointer) { - out.writeByte(0); - current_offset++; - } - } + @Override + public void compile(String filepath) { + try { + BufferedReader files = new BufferedReader(new FileReader(filepath + + "/filelist.txt")); + String file = files.readLine(); + // retrieve the filename and size + String filename = file.split(" ")[0]; + // long size = Integer.parseInt(file.split(" ")[1]); + // now make a list with the string tables files + Vector filenames = new Vector(); + while ((file = files.readLine()) != null) { + filenames.add(file); + } + files.close(); + copyfile(filepath + "/" + filename, filename + ".out"); + RandomAccessFile out = new RandomAccessFile(filename + ".out", "rw"); + Vector table_offset = new Vector(); + int pointer; + while (true) { + pointer = readInt(out); + if (pointer == 0) { + break; + } + table_offset.add(pointer); + } + for (int i = 0; i < table_offset.size(); i++) { + patchStringTable(filepath, filenames.get(i), out, + table_offset.get(i)); + } + out.close(); + System.out.println("Finished!"); + } catch (FileNotFoundException e) { + System.out.println(e.toString()); + } catch (IOException e) { + e.printStackTrace(); + } + } - private int calculateTotalSize(Vector st) throws UnsupportedEncodingException { - int total = 0; - for (String str : st) { - int len = str.getBytes("UTF-8").length; + private void patchStringTable(String directory, String in, + RandomAccessFile out, int starting_offset) + throws FileNotFoundException, IOException { + System.out.println("Reading " + directory + "/" + in); + RandomAccessFile file = new RandomAccessFile(directory + "/" + in, "r"); + checkUnicodeBOM(file); // thanks notepad :/ (die notepad, die) + Vector stringTable = new Vector(); + try { + while (true) { + // read all strings of file + String str = readString(file); + if (str == null) { + break; + } + // remove the labels and put the original data + str = str.replaceAll("", "\n"); + str = str.replaceAll("", "\0"); + stringTable.add(str); + } + } catch (EOFException e) { + } + file.close(); + out.seek(starting_offset); + out.skipBytes(20 + encoder); + int offset_table_pointer = readInt(out); + int string_start = (int) out.getFilePointer() + 28; + out.seek(offset_table_pointer); + int string_table_pointers = readInt(out); + int diff = string_table_pointers - string_start + - calculateTotalSize(stringTable); + if (diff < 0) { + System.err.println(in + " is too big, please remove at least " + + -diff + " bytes. Skipped"); + return; + } + out.seek(string_table_pointers); + int starting_string = readInt(out); + out.seek(starting_string); + long orig_table_pointer = string_table_pointers; + for (String str : stringTable) { + out.write(str.getBytes("UTF-8")); + out.writeByte(0); + out.writeByte(0); + while (out.getFilePointer() % 4 != 0) { + out.writeByte(0); + } + int tmp = (int) out.getFilePointer(); + out.seek(string_table_pointers); + writeInt(out, starting_string); + string_table_pointers += 4; + starting_string = tmp; + out.seek(tmp); + } + long current_offset = out.getFilePointer(); + while (current_offset < orig_table_pointer) { + out.writeByte(0); + current_offset++; + } + } - if (len == 1 && str.charAt(0) == 0) { - total++; - } else { - total += len + 1; - } - } - return total; - } + private int calculateTotalSize(Vector st) + throws UnsupportedEncodingException { + int total = 0; + for (String str : st) { + int len = str.getBytes("UTF-8").length; - private void copyfile(String srFile, String dtFile) { - try { - File f1 = new File(srFile); - File f2 = new File(dtFile); - InputStream in = new FileInputStream(f1); - OutputStream out = new FileOutputStream(f2); + if (len == 1 && str.charAt(0) == 0) { + total++; + } else { + total += len + 1; + } + } + return total; + } - byte[] buf = new byte[1024]; - int len; - while ((len = in.read(buf)) > 0) { - out.write(buf, 0, len); - } - in.close(); - out.close(); - } catch (FileNotFoundException ex) { - System.out.println(ex.getMessage() + " in the specified directory."); - System.exit(0); - } catch (IOException e) { - System.out.println(e.getMessage()); - } - } + private void copyfile(String srFile, String dtFile) { + try { + File f1 = new File(srFile); + File f2 = new File(dtFile); + InputStream in = new FileInputStream(f1); + OutputStream out = new FileOutputStream(f2); + + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + in.close(); + out.close(); + } catch (FileNotFoundException ex) { + System.out + .println(ex.getMessage() + " in the specified directory."); + System.exit(0); + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } } diff --git a/src/enc/RebuildPluginC.java b/src/enc/RebuildPluginC.java index 10c360d..0434c66 100644 --- a/src/enc/RebuildPluginC.java +++ b/src/enc/RebuildPluginC.java @@ -34,143 +34,150 @@ import base.Encoder; */ public class RebuildPluginC extends Encoder { - @Override - public void compile(String filepath) { - try { - BufferedReader files = new BufferedReader(new FileReader(filepath + "/filelist.txt")); - String string_file = files.readLine(); - // retrieve the filename and size - String filename = string_file.split(" ")[0]; - long size = Integer.parseInt(string_file.split(" ")[1]); - // now make a list with the string tables files - Vector filenames = new Vector(); - Vector unknown = new Vector(); - while ((string_file = files.readLine()) != null) { - if (string_file.equals("enddata.bin")) { - filenames.add(string_file); - } else { - filenames.add(string_file.split(",")[1]); - unknown.add(Integer.parseInt(string_file.split(",")[0])); - } - } - files.close(); - RandomAccessFile out = new RandomAccessFile(filename + ".out", "rw"); - writeInt(out, unknown.get(0)); - writeInt(out, (unknown.size() + 1) * 8); - for (int i = 1; i < unknown.size(); i++) { - writeInt(out, unknown.get(i)); - writeInt(out, 0); - } - writeInt(out, -1); - writeInt(out, -1); - int table_offset = 12; - for (int i = 0; i < filenames.size() - 1; i++) { - // now start to create each offset table / string table - createStringTable(filepath, filenames.get(i), out); - // write the end-table mark - out.writeByte(0); - if (i < filenames.size() - 2) { - long current = out.getFilePointer(); - out.seek(table_offset); - // now we know the value of the next table, so write above - // in the main - // offset table - writeInt(out, (int) current); - out.seek(current); - table_offset += 8; - out.seek(current); - } - } - out.writeByte(0); - // we need to know the size of the enddata, so open it now - System.out.println("Reading " + filenames.lastElement()); - RandomAccessFile enddata = new RandomAccessFile(filepath + "/" + filenames.lastElement(), "rw"); + @Override + public void compile(String filepath) { + try { + BufferedReader files = new BufferedReader(new FileReader(filepath + + "/filelist.txt")); + String string_file = files.readLine(); + // retrieve the filename and size + String filename = string_file.split(" ")[0]; + long size = Integer.parseInt(string_file.split(" ")[1]); + // now make a list with the string tables files + Vector filenames = new Vector(); + Vector unknown = new Vector(); + while ((string_file = files.readLine()) != null) { + if (string_file.equals("enddata.bin")) { + filenames.add(string_file); + } else { + filenames.add(string_file.split(",")[1]); + unknown.add(Integer.parseInt(string_file.split(",")[0])); + } + } + files.close(); + RandomAccessFile out = new RandomAccessFile(filename + ".out", "rw"); + writeInt(out, unknown.get(0)); + writeInt(out, (unknown.size() + 1) * 8); + for (int i = 1; i < unknown.size(); i++) { + writeInt(out, unknown.get(i)); + writeInt(out, 0); + } + writeInt(out, -1); + writeInt(out, -1); + int table_offset = 12; + for (int i = 0; i < filenames.size() - 1; i++) { + // now start to create each offset table / string table + createStringTable(filepath, filenames.get(i), out); + // write the end-table mark + out.writeByte(0); + if (i < filenames.size() - 2) { + long current = out.getFilePointer(); + out.seek(table_offset); + // now we know the value of the next table, so write above + // in the main + // offset table + writeInt(out, (int) current); + out.seek(current); + table_offset += 8; + out.seek(current); + } + } + out.writeByte(0); + // we need to know the size of the enddata, so open it now + System.out.println("Reading " + filenames.lastElement()); + RandomAccessFile enddata = new RandomAccessFile(filepath + "/" + + filenames.lastElement(), "rw"); - long enddataSize = enddata.length(); + long enddataSize = enddata.length(); - // some checks to make sure that the file size of xxxx.bin is - // correct - if (out.getFilePointer() > size - enddataSize) { - System.out.println("File too big (by " + (out.getFilePointer() - (size - enddataSize))+ " bytes), please reduce some strings :("); - } else if (out.getFilePointer() < size - enddataSize) { - System.out.println("File too small (by " + ((size - enddataSize) - out.getFilePointer())+ " bytes), filling with 0x00 (this is OK) :D"); - while (out.getFilePointer() < size - enddataSize) { - out.writeByte(0); - } - } else { - System.out.println("Perfect size of file :O"); - } - // now append the unknown data at the end of file - int data; - while ((data = enddata.read()) != -1) { - out.write((byte) data); - } - enddata.close(); - out.setLength(out.getFilePointer()); - out.close(); - System.out.println("Finished!"); - } catch (FileNotFoundException e) { - System.out.println(e.toString()); - } catch (IOException e) { - e.printStackTrace(); - } - } + // some checks to make sure that the file size of xxxx.bin is + // correct + if (out.getFilePointer() > size - enddataSize) { + System.out.println("File too big (by " + + (out.getFilePointer() - (size - enddataSize)) + + " bytes), please reduce some strings :("); + } else if (out.getFilePointer() < size - enddataSize) { + System.out.println("File too small (by " + + ((size - enddataSize) - out.getFilePointer()) + + " bytes), filling with 0x00 (this is OK) :D"); + while (out.getFilePointer() < size - enddataSize) { + out.writeByte(0); + } + } else { + System.out.println("Perfect size of file :O"); + } + // now append the unknown data at the end of file + int data; + while ((data = enddata.read()) != -1) { + out.write((byte) data); + } + enddata.close(); + out.setLength(out.getFilePointer()); + out.close(); + System.out.println("Finished!"); + } catch (FileNotFoundException e) { + System.out.println(e.toString()); + } catch (IOException e) { + e.printStackTrace(); + } + } - /** - * - * @param in - * filename of text file - * @param out - * file to write the table - * @throws FileNotFoundException - * if the file is not found - * @throws IOException - * if any error occur while reading/writing - */ - private void createStringTable(String directory, String in, RandomAccessFile out) throws FileNotFoundException, IOException { - System.out.println("Reading " + directory + "/" + in); - RandomAccessFile file = new RandomAccessFile(directory + "/" + in, "r"); - checkUnicodeBOM(file); // thanks notepad :/ (*sigh*) - Vector stringTable = new Vector(); - Vector unknownTable = new Vector(); - try { - while (true) { - // read all strings of file - String str = readString(file); - if (str == null) { - break; - } - // remove the labels and put the original data - unknownTable.add(Integer.parseInt(str.split(",")[0])); - str = str.substring(str.indexOf(",") + 1); - str = str.replaceAll("", "\n"); - str = str.replaceAll("", "\0"); - stringTable.add(str); - } - } catch (EOFException e) { - } - file.close(); - int offset = stringTable.size() * 8; - // now calculate the offsets using the length in bytes of the strings - for (int i = 0; i < stringTable.size(); i++) { - writeInt(out, unknownTable.get(i)); - writeInt(out, offset); - if (stringTable.elementAt(i).getBytes("UTF-8").length == 1 - && stringTable.elementAt(i).charAt(0) == '\0') { - offset++; - } else { - offset += stringTable.elementAt(i).getBytes("UTF-8").length + 1; - } - } - // now write the zero terminated string in the file - for (int i = 0; i < stringTable.size(); i++) { - String str = stringTable.elementAt(i); - if (str.equals("\0")) { - out.writeByte(0); - } else { - out.write(str.getBytes("UTF-8")); - out.writeByte(0); - } - } - } + /** + * + * @param in + * filename of text file + * @param out + * file to write the table + * @throws FileNotFoundException + * if the file is not found + * @throws IOException + * if any error occur while reading/writing + */ + private void createStringTable(String directory, String in, + RandomAccessFile out) throws FileNotFoundException, IOException { + System.out.println("Reading " + directory + "/" + in); + RandomAccessFile file = new RandomAccessFile(directory + "/" + in, "r"); + checkUnicodeBOM(file); // thanks notepad :/ (*sigh*) + Vector stringTable = new Vector(); + Vector unknownTable = new Vector(); + try { + while (true) { + // read all strings of file + String str = readString(file); + if (str == null) { + break; + } + // remove the labels and put the original data + unknownTable.add(Integer.parseInt(str.split(",")[0])); + str = str.substring(str.indexOf(",") + 1); + str = str.replaceAll("", "\n"); + str = str.replaceAll("", "\0"); + stringTable.add(str); + } + } catch (EOFException e) { + } + file.close(); + int offset = stringTable.size() * 8; + // now calculate the offsets using the length in bytes of the strings + for (int i = 0; i < stringTable.size(); i++) { + writeInt(out, unknownTable.get(i)); + writeInt(out, offset); + if (stringTable.elementAt(i).getBytes("UTF-8").length == 1 + && stringTable.elementAt(i).charAt(0) == '\0') { + offset++; + } else { + offset += stringTable.elementAt(i).getBytes("UTF-8").length + 1; + } + } + // now write the zero terminated string in the file + for (int i = 0; i < stringTable.size(); i++) { + String str = stringTable.elementAt(i); + if (str.equals("\0")) { + out.writeByte(0); + } else { + out.write(str.getBytes("UTF-8")); + out.writeByte(0); + } + } + } }