Last active
December 22, 2015 13:59
-
-
Save aristotle9/6482660 to your computer and use it in GitHub Desktop.
unpacker for MA pack file, and it's easy to generate pack file, possible to customize MA assets.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.BufferedInputStream; | |
import java.io.File; | |
import java.io.FileInputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
/** | |
* unpacker for MA pack file | |
*/ | |
public final class Unpacker { | |
public static void main(String[] args) { | |
if(args.length >= 1) { | |
File f = new File(args[0]); | |
unpack(f); | |
} | |
} | |
private static int readInt(InputStream input) throws IOException { | |
int ret = 0; | |
int i = 3; | |
while (i >= 0) { | |
int k = input.read(); | |
ret |= k << i * 8; | |
i--; | |
} | |
return ret; | |
} | |
private static byte[] readBytes(InputStream input, int offset, int length) | |
throws IOException { | |
byte[] bytes = new byte[length]; | |
input.read(bytes, 0, length); | |
return bytes; | |
} | |
public static boolean unpack(File file) { | |
log("start unpack: %s", file.getAbsolutePath()); | |
if(!file.exists()) { | |
error("file dose not exist: %s", file.getAbsolutePath()); | |
return false; | |
} | |
BufferedInputStream bi = null; | |
int offset = 0; | |
try { | |
bi = new BufferedInputStream(new FileInputStream(file)); | |
int ch = bi.read(); | |
if(ch != 0x52) { | |
error("invalid header: %d", ch); | |
return false; | |
} | |
ch = bi.read(); | |
if(ch != 0x4a) { | |
error("invalid header: %d", ch); | |
return false; | |
} | |
int total = readInt(bi); | |
int pCount = readInt(bi); | |
int nth = readInt(bi); | |
if(nth == 0) { | |
log("totalFileSize: %d", total); | |
log("packFileCount: %d", pCount); | |
log("nthPackFile: %d", nth); | |
} | |
int num = readInt(bi); | |
offset = 18;//header length | |
String[] lStr = new String[num]; | |
int[] lInt = new int[num]; | |
for(int i = 0; i < num; i++) { | |
int strLength = readInt(bi); | |
offset += 4; | |
byte[] strBytes = readBytes(bi, offset, strLength); | |
offset += strLength; | |
int bytesLength = readInt(bi); | |
offset += 4; | |
lStr[i] = new String(strBytes); | |
lInt[i] = bytesLength; | |
} | |
for(int i = 0; i < num; i ++) { | |
bi.read();//forward 1byte | |
int bytesLength = lInt[i]; | |
byte[] bytes = readBytes(bi, offset, bytesLength); | |
offset += bytes.length; | |
String name = lStr[i]; | |
//TODO do something with name and bytes (bytes is encrypted!) | |
log(name); | |
} | |
return true; | |
} catch (Exception e) { | |
error("error at offset: %d", offset); | |
e.printStackTrace(); | |
return false; | |
} finally { | |
if(bi != null) { | |
try { | |
bi.close(); | |
} | |
catch (Exception e2) { | |
e2.printStackTrace(); | |
} | |
} | |
} | |
} | |
private static void log(String format, Object... params) { | |
System.out.printf(format, params); | |
System.out.println(); | |
} | |
private static void error(String format, Object... params) { | |
System.err.printf(format, params); | |
System.err.println(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment