home *** CD-ROM | disk | FTP | other *** search
Java Source | 1998-01-14 | 11.2 KB | 456 lines |
-
- /*
- * Unpack -- a completely non-object oriented utility...
- *
- */
-
- // TODO:
- //
- // Unpack files that are selected in the list
- //
- // MODIFICATIONS
- // AUHTOR: RD Bettens - richmal@ozemail.com.au
- // DATE: Jan 1998
- //
- // PURPOSE: to provide a GUI for Quake 2 Unpack utility
- //
- // Problems:
- // Whatever you do.....DON'T PRESS THE CANCEL BUTTONS
- // ........ bad things happen
- // This file is pretty crude. It only has minimal exception handling. This will be looked at
- // for the next release
- //
-
- import java.awt.*;
- import java.io.*;
-
- class Unpack extends Panel {
-
- // globals
- int ident;
- int dirofs;
- int dirlen;
- int numLumps;
- byte[] name = new byte[56];
- String nameString;
- int filepos;
- int filelen;
- RandomAccessFile readLump;
- DataInputStream directory;
- String pakName;
- String pattern;
-
- // awt components
- FileDialog pakFileDialog;
- FileDialog outputFileDialog;
-
- TextField patternText;
- List pakList;
- String[] pakListSelections;
- Button unpackButton;
- Button listButton;
- boolean finished;
-
-
- public boolean isFinished()
- {
- return finished;
- }
-
- public boolean action(Event e, Object o)
- {
- if (e.target instanceof Button)
- {
- System.out.println("Object is: "+o.toString());
- if (o.toString().equals("List") ) {
- pattern = GetPattern();
- System.out.println("The pattern is: "+pattern);
- UnpackFile( pattern );
- finished = false;
- } else if (o.toString().equals("Unpack") ) {
- try {
- pakListSelections = pakList.getSelectedItems();
- WriteFiles(); // write selected files to output directory
- finished = true;
- } catch (Exception exc) {
- exc.printStackTrace();
- return false;
- }
- }
- return true;
- }
- return false;
- }
-
- protected boolean Selected(String item)
- // returns true if item is a seleced item
- {
- for (int i=0; i < pakListSelections.length; i++) {
- if (pakListSelections[i].equals(item) ) {
- return true;
- }
- }
- return false;
- }
-
- protected void SetOutputDirectory()
- {
- outputFileDialog.show();
- System.out.println("The output directory is: "+outputFileDialog.getDirectory());
- }
-
- protected String GetPattern()
- {
- return patternText.getText().trim();
- }
-
-
- protected void ReadPakFile()
- {
- try {
- // one stream to read the directory
- directory = new DataInputStream(new FileInputStream(pakName));
-
- // another to read lumps
- readLump = new RandomAccessFile(pakName, "r");
-
- // read the header
- ident = intSwap(directory.readInt()); // 4 bytes
- dirofs = intSwap(directory.readInt());// 4 bytes
- dirlen = intSwap(directory.readInt());// 4 bytes
-
- if (ident != IDPAKHEADER) {
- System.out.println ( pakName + " is not a pakfile.");
- System.exit (1);
- }
-
- // read the directory
- directory.skipBytes (dirofs - 12);
- numLumps = dirlen / 64;
-
- // beginning of lumps
- // int lumpStart = 4 + 4 + 4 + (dirofs - 12);
-
- // define the pak file selections list
- pakListSelections = new String[numLumps];
- System.out.println (numLumps + " lumps in " + pakName);
- } catch
- (IOException e) {
- System.out.println("Invalid IO operation");
- e.printStackTrace();
- }
- }
-
- protected void UnpackFile(String pattern)
- {
- try {
- directory = new DataInputStream(new FileInputStream(pakName));
- directory.skipBytes(4 + 4 + 4 + (dirofs - 12));
- // this should be the start of the lumps
-
- pakList.clear(); // clear list box
-
- for (int i=0; i< numLumps; i++) {
- // read file name
- directory.readFully(name);
- // get file position
- filepos = intSwap(directory.readInt());
- // get file length
- filelen = intSwap(directory.readInt());
-
- // get the name of the file
- nameString = new String (name, 0);
- // chop to the first 0 byte
- nameString = nameString.substring (0, nameString.indexOf(0));
-
- if (patternMatch (pattern, nameString) ) {
- // listing mode
- pakList.addItem(nameString); // add file name to list box
- }
- }
-
- } catch (IOException e) {
- System.err.println("Unexpected Exception");
- e.printStackTrace();
- }
- }
-
- public void WriteFiles()
- // extract and write file from pak file
- {
- try {
- RandomAccessFile log;
- String logName;
-
- directory = new DataInputStream(new FileInputStream(pakName));
- directory.skipBytes(4 + 4 + 4 + (dirofs - 12));
- // this should be the start of the lumps
-
- if (outputFileDialog.getFile() == null) {
- logName = outputFileDialog.getDirectory()+"output.log";
- } else {
- logName = outputFileDialog.getDirectory() + outputFileDialog.getFile();
- }
- log = new RandomAccessFile(logName,"rw");
- log.writeBytes("FILES CREATED:\r\n");
-
-
- for (int i = 0 ; i < numLumps ; i++) {
- directory.readFully(name);
- filepos = intSwap(directory.readInt());
- filelen = intSwap(directory.readInt());
-
- nameString = new String (name, 0);
- // chop to the first 0 byte
- nameString = nameString.substring (0, nameString.indexOf(0));
-
- //if (patternMatch (pattern, nameString) ) {
- if ( Selected(nameString) ) { // if selected item
- File writeFile;
- DataOutputStream writeLump;
- byte[] buffer = new byte[filelen];
- StringBuffer fixedString;
- String finalName;
- int index;
-
- // set log file
-
- log.writeBytes(nameString+"\r\n");
-
- System.out.println ("Unpaking " + nameString + " " + filelen
- + " bytes");
-
- // load the lump
- readLump.seek(filepos);
- readLump.readFully(buffer);
-
- // quake uses forward slashes, but java requires
- // they only by the host's seperator, which
- // varies from win to unix
- fixedString =
- new StringBuffer (outputFileDialog.getDirectory() + nameString);
- for (index = 0 ; index < fixedString.length() ; index++) {
- if (fixedString.charAt(index) == '/') {
- fixedString.setCharAt(index, File.separatorChar);
- }
- }
- finalName = fixedString.toString ();
-
- index = finalName.lastIndexOf(File.separatorChar);
- if (index != -1) {
- String finalPath;
- File writePath;
-
- finalPath = finalName.substring(0, index);
- writePath = new File (finalPath);
- writePath.mkdirs();
- }
-
- writeFile = new File (finalName);
- writeLump = new DataOutputStream ( new FileOutputStream(writeFile) );
- writeLump.write(buffer);
- writeLump.close();
- }
- }
- log.close();
- } catch (IOException e) {
- System.out.println ( e.toString() );
- }
- }
-
- protected void CleanUp()
- {
- pakFileDialog.dispose();
- outputFileDialog.dispose();
- try {
- directory.close();
- readLump.close();
- } catch (IOException e) { e.printStackTrace(); }
- }
-
-
-
- static final protected int IDPAKHEADER = (('K'<<24)+('C'<<16)+('A'<<8)+'P');
-
- protected int intSwap(int i) {
- int a, b, c, d;
-
- a = i & 255;
- b = (i >> 8) & 255;
- c = (i >> 16) & 255;
- d = (i >> 24) & 255;
-
- return (a << 24) + (b << 16) + (c << 8) + d;
- }
-
- protected boolean patternMatch (String pattern, String s) {
- int index;
- int remaining;
-
- if (pattern.equals(s)) {
- return true;
- }
-
- // fairly lame single wildcard matching
- index = pattern.indexOf('*');
- if (index == -1) {
- return false;
- }
- if (!pattern.regionMatches(0, s, 0, index)) {
- return false;
- }
-
- index += 1; // skip the *
- remaining = pattern.length() - index;
- if (s.length() < remaining) {
- return false;
- }
-
- if (!pattern.regionMatches(index, s, s.length()-remaining, remaining)) {
- return false;
- }
-
- return true;
- }
-
- static void usage() {
- System.out.println ("Usage: unpack <packfile> <match> <basedir>");
- System.out.println (" or: unpack -list <packfile>");
- System.out.println ("<match> may contain a single * wildcard");
- System.exit (1);
- }
-
- public void GetPakFile()
- {
- pakFileDialog.show();
- // need to check if a valid Quake2 pak file
- pakName = pakFileDialog.getDirectory()+pakFileDialog.getFile();
- // System.out.println("Pak File is "+pakName);
- ReadPakFile();
- }
-
- public Unpack(Frame parent)
- {
- super();
-
- finished = false;
-
- resize(200,200);
-
- // get pak filename
- pakFileDialog = new FileDialog(parent,"Pak File");
- pakFileDialog.setFile("*.pak");
-
- outputFileDialog = new FileDialog(parent, "Output File");
- outputFileDialog.setFile("output.log");
-
- patternText = new TextField("*",20);
-
- this.setLayout(new FlowLayout());
-
-
- // list component to display the list of files
- // can also select multiple files for unpacking
- pakList = new List(10,true);
-
- this.add(pakList);
- this.add(new Label("Pattern:"));
- this.add(patternText);
-
- listButton = new Button("Unpack");
- unpackButton = new Button("List");
-
- this.add(unpackButton);
- this.add(listButton);
-
- /*
- try {
- // one stream to read the directory
- directory = new DataInputStream(new FileInputStream(pakName));
-
- // another to read lumps
- readLump = new RandomAccessFile(pakName, "r");
-
- // read the header
- ident = intSwap(directory.readInt());
- dirofs = intSwap(directory.readInt());
- dirlen = intSwap(directory.readInt());
-
- if (ident != IDPAKHEADER) {
- System.out.println ( pakName + " is not a pakfile.");
- System.exit (1);
- }
-
- // read the directory
- directory.skipBytes (dirofs - 12);
- numLumps = dirlen / 64;
-
- System.out.println (numLumps + " lumps in " + pakName);
-
- for (int i = 0 ; i < numLumps ; i++) {
- directory.readFully(name);
- filepos = intSwap(directory.readInt());
- filelen = intSwap(directory.readInt());
-
- nameString = new String (name, 0);
- // chop to the first 0 byte
- nameString = nameString.substring (0, nameString.indexOf(0));
-
- if (pattern == null) {
- // listing mode
- System.out.println (nameString + " : " + filelen + "bytes");
- } else if (patternMatch (pattern, nameString) ) {
- File writeFile;
- DataOutputStream writeLump;
- byte[] buffer = new byte[filelen];
- StringBuffer fixedString;
- String finalName;
- int index;
-
- System.out.println ("Unpaking " + nameString + " " + filelen
- + " bytes");
-
- // load the lump
- readLump.seek(filepos);
- readLump.readFully(buffer);
-
- // quake uses forward slashes, but java requires
- // they only by the host's seperator, which
- // varies from win to unix
- fixedString = new StringBuffer (args[2] + File.separator + nameString);
- for (index = 0 ; index < fixedString.length() ; index++) {
- if (fixedString.charAt(index) == '/') {
- fixedString.setCharAt(index, File.separatorChar);
- }
- }
- finalName = fixedString.toString ();
-
- index = finalName.lastIndexOf(File.separatorChar);
- if (index != -1) {
- String finalPath;
- File writePath;
-
- finalPath = finalName.substring(0, index);
- writePath = new File (finalPath);
- writePath.mkdirs();
- }
-
- writeFile = new File (finalName);
- writeLump = new DataOutputStream ( new FileOutputStream(writeFile) );
- writeLump.write(buffer);
- writeLump.close();
-
- }
- }
-
- readLump.close();
- directory.close();
-
- } catch (IOException e) {
- System.out.println ( e.toString() );
- }
- */
- }
-
- }
-