diff --git a/main.java b/main.java new file mode 100644 index 0000000..b998f1d --- /dev/null +++ b/main.java @@ -0,0 +1,59 @@ +import swg.APTFile; +import swg.LODFile; +import swg.SSAFile; + +import java.io.File; +import java.io.IOException; + +public class main { + private static String clientDataRoot = "E:/Games/SWG-Extracted/"; + public static void main(String[] args) + { + if(args != null){ + switch(args.length){ + case 0: + File f = new File(clientDataRoot + "/appearance"); + for(File file : f.listFiles()){ + if(!file.getName().contains(".apt")) continue; + APTFile aptFile = new APTFile(clientDataRoot + "appearance/" + file.getName()); + aptFile.read(); + if(aptFile.getFullName().contains(".lod")){ + try { + SSAFile ssaFile = new SSAFile(aptFile.getFullName()); + String ssaFileName = "appearance/" + file.getName().replace(".apt", ".ssa"); + + // first, see if we have an SSA file that we can use + File ssaFileCheck = new File(clientDataRoot + ssaFileName); + + // if it doesn't exist, try to create it from an LOD file. + if(!ssaFileCheck.exists()) { + // try to create the SSA file from the LOD file + LODFile lodFile = new LODFile(clientDataRoot + aptFile.getFullName()); + if (!lodFile.read()) { + System.out.println("Can't read file (" + aptFile.getFullName() + ")!!"); + continue; + } + ssaFile.setApprBytes(lodFile.getApprBytes()); + ssaFile.write(); + } + + // change the redirector in the APT + aptFile.setFullName("appearance/" + file.getName().replace(".apt", ".ssa")); + + // Create the SSA + aptFile.write(); + } + catch (IOException e){ + System.out.println("ERROR: " + e.getMessage()); + } + } + } + break; + case 1: + break; + default: + break; + } + } + } +} diff --git a/swg/APTFile.java b/swg/APTFile.java new file mode 100644 index 0000000..a65a093 --- /dev/null +++ b/swg/APTFile.java @@ -0,0 +1,116 @@ +package swg; + +import java.io.*; +import java.nio.ByteBuffer; + +public class APTFile { + private File inputFile; + private byte[] name; + private byte[] version = new byte[4]; + + private File outputFile; + + public APTFile(String fileName){ + inputFile = new File(fileName); + outputFile = new File("out/" + inputFile.getName()); + } + + public void read(){ + try{ + parse(); + } + catch(Exception e){ + e.printStackTrace(); + } + } + + public void write() throws IOException { + FileOutputStream fos = new FileOutputStream(outputFile.getName()); + try{ + int formLength = name.length + 24; + fos.write("FORM".getBytes()); + fos.write(ByteBuffer.allocate(4).putInt(formLength).array()); + fos.write("APT ".getBytes()); + fos.write("FORM".getBytes()); + fos.write(ByteBuffer.allocate(4).putInt(name.length + 12).array()); + fos.write(version); + fos.write("NAME".getBytes()); + fos.write(ByteBuffer.allocate(4).putInt(name.length).array()); + fos.write(name); + fos.write('\0'); + } + catch(Exception e){ + System.out.println("ERROR: " + e.getMessage()); + } + finally { + fos.close(); + } + } + + private void parse() throws IOException { + FileInputStream fis = null; + BufferedInputStream bi = null; + try { + byte[] FORM = new byte[4]; + byte[] APTFORM = new byte[8]; + + byte[] NAMETag = new byte[4]; + byte[] nameByteSize = new byte[4]; + + fis = new FileInputStream(inputFile); + bi = new BufferedInputStream(fis); + // work our way to the data. + bi.read(FORM); + bi.read(new byte[4]); // length of form + bi.read(APTFORM); + bi.read(new byte[4]); + bi.read(version); + bi.read(NAMETag); + bi.read(nameByteSize); + + // get the length of the path to the LOD or SSA + int nameLength = ByteBuffer.wrap(nameByteSize).getInt(); + + // make a buffer to hold the info + name = new byte[nameLength]; + + // read in the number of bytes that the path occupies + bi.read(name); + } + catch(Exception e){ + e.printStackTrace(); + } + finally{ + if(bi != null){ + bi.close(); + } + if(fis != null){ + fis.close(); + } + } + } + + public String getFullName() { + return new String(name); + } + + public void setFullName(String val) { + name = val.getBytes(); + } + + public int getVersion() { + return Integer.parseInt(new String(version)); + } + + public void setVersion(int val) { + version = ByteBuffer.allocate(4).putInt(val).array(); + } + + public String getFileName() { + return getFullName().substring(getFullName().lastIndexOf("/") + 1); + } + + public String getPathName() { + return getFullName().replace(getFileName(), ""); + } +} diff --git a/swg/LODFile.java b/swg/LODFile.java new file mode 100644 index 0000000..e7f2546 --- /dev/null +++ b/swg/LODFile.java @@ -0,0 +1,91 @@ +package swg; + +import java.io.*; +import java.nio.ByteBuffer; + +public class LODFile { + private File inputFile; + private File outputFile; + + private byte[] dtlaVersion; + private byte[] apprBytes; + + public LODFile(String iFile){ + inputFile = new File(iFile); + outputFile = new File("out/appearance/lod/" + inputFile.getName()); + } + + public boolean read() { + try{ + return parse(); + } + catch(Exception e){ + e.printStackTrace(); + } + return false; + } + + public void write() throws IOException { + /* + FileOutputStream fos = new FileOutputStream(outputFile.getName()); + try{ + // use as an example later. + + int formLength = name.length + 24; + fos.write("FORM".getBytes()); + fos.write(ByteBuffer.allocate(4).putInt(formLength).array()); + fos.write("APT ".getBytes()); + fos.write("FORM".getBytes()); + fos.write(ByteBuffer.allocate(4).putInt(name.length + 12).array()); + fos.write(version); + fos.write("NAME".getBytes()); + fos.write(ByteBuffer.allocate(4).putInt(name.length).array()); + fos.write(name); + } + catch(Exception e){ + System.out.println("ERROR: " + e.getMessage()); + } + finally { + fos.close(); + } + */ + } + + public boolean parse() throws IOException { + FileInputStream fis = null; + BufferedInputStream bi = null; + try { + byte[] MAINFORM = new byte[4]; + byte[] formSize = new byte[4]; + + byte[] DTLAFORM = new byte[8]; + byte[] dtlaFormSize = new byte[4]; + + fis = new FileInputStream(inputFile); + bi = new BufferedInputStream(fis); + // work our way to the data. + bi.read(MAINFORM); + bi.read(formSize); // length of form + bi.read(DTLAFORM); + bi.read(dtlaFormSize); + bi.read(dtlaVersion); + bi.read(apprBytes); + return true; + } + catch(Exception e){ + return false; + } + finally{ + if(bi != null){ + bi.close(); + } + if(fis != null){ + fis.close(); + } + } + } + + public byte[] getApprBytes() { + return apprBytes; + } +} diff --git a/swg/SSAFile.java b/swg/SSAFile.java new file mode 100644 index 0000000..241dba1 --- /dev/null +++ b/swg/SSAFile.java @@ -0,0 +1,87 @@ +package swg; + +import java.io.*; +import java.nio.ByteBuffer; + +public class SSAFile { + private File inputFile; + private File outputFile; + + private byte[] apprBytes; + + public SSAFile(String iFile){ + inputFile = new File(iFile); + outputFile = new File("out/appearance/" + inputFile.getName()); + } + + public void read() { + try{ + parse(); + } + catch(Exception e){ + e.printStackTrace(); + } + } + + public void write() throws IOException { + FileOutputStream fos = new FileOutputStream(outputFile.getName()); + try{ + fos.write(apprBytes); + } + catch(Exception e){ + System.out.println("ERROR: " + e.getMessage()); + } + finally { + fos.close(); + } + } + + public void parse() { + /* + FileInputStream fis = null; + BufferedInputStream bi = null; + try { + byte[] FORM = new byte[4]; + byte[] APTFORM = new byte[8]; + + byte[] NAMETag = new byte[4]; + byte[] nameByteSize = new byte[4]; + + fis = new FileInputStream(inputFile); + bi = new BufferedInputStream(fis); + // work our way to the data. + bi.read(FORM); + bi.read(new byte[4]); // length of form + bi.read(APTFORM); + bi.read(new byte[4]); + bi.read(version); + bi.read(NAMETag); + bi.read(nameByteSize); + + // get the length of the path to the LOD or SSA + int nameLength = ByteBuffer.wrap(nameByteSize).getInt(); + + // make a buffer to hold the info + name = new byte[nameLength]; + + // read in the number of bytes that the path occupies + bi.read(name); + } + catch(Exception e){ + e.printStackTrace(); + } + finally{ + if(bi != null){ + bi.close(); + } + if(fis != null){ + fis.close(); + } + } + */ + } + + public void setApprBytes(byte[] val){ + apprBytes = val; + } +}