package NET.worlds.core; import NET.worlds.console.Console; import NET.worlds.console.PolledDialog; import NET.worlds.network.ProgressBar; import NET.worlds.network.URL; import NET.worlds.scape.FileList; import NET.worlds.scape.Pilot; import NET.worlds.scape.World; import java.awt.Button; import java.awt.Event; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.Label; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.text.MessageFormat; import java.util.Enumeration; import java.util.Vector; import java.util.zip.CRC32; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; public class ArchiveMaker extends PolledDialog { private static final long serialVersionUID = -7620030251122522576L; private static final String extensions = "cmp;mov"; private URL sourceURL; private String path; private Label status = new Label("", 0); private Button goButton; private Button closeButton = new Button(Console.message("Close")); private ProgressBar progress = new ProgressBar(1); private boolean start; private boolean stop; private boolean finished; private boolean condense; public ArchiveMaker(boolean condense) { super(Console.getFrame(), null, condense ? Console.message("Condense-Files") : Console.message("Expand-Files"), true); this.condense = condense; this.ready(); } @Override protected void build() { String errStatus = null; Pilot pilot = Pilot.getActive(); if (pilot != null) { World world = pilot.getWorld(); if (world != null) { this.sourceURL = world.getSourceURL(); this.path = this.sourceURL.unalias(); this.path = this.path.substring(0, this.path.lastIndexOf(47)); String home = URL.getHome().unalias(); if (this.path.startsWith(home)) { File f = new File(URL.make(this.sourceURL, "content.zip").unalias()); if (this.condense) { if (f.exists()) { errStatus = Console.message("Must-expand"); } } else if (!f.exists()) { errStatus = Console.message("Must-condense"); } } else { errStatus = Console.message("Not-a-home"); } } else { errStatus = Console.message("Cant-access-world"); } } else { errStatus = Console.message("Cant-access-pilot"); } GridBagLayout gbag = new GridBagLayout(); this.setLayout(gbag); GridBagConstraints c = new GridBagConstraints(); c.weightx = 0.0; c.gridwidth = 1; this.add(gbag, new Label(Console.message("Status"), 2), c); c.weightx = 1.0; c.gridwidth = 0; c.fill = 2; this.add(gbag, this.status, c); c.fill = 0; c.weightx = 0.0; c.gridwidth = 0; this.goButton = new Button(this.condense ? Console.message("Condense") : Console.message("Expand")); this.add(gbag, this.goButton, c); c.weightx = 1.0; c.fill = 2; Insets tmp = c.insets; c.insets = new Insets(5, 5, 5, 5); this.add(gbag, this.progress, c); c.insets = tmp; c.fill = 0; c.weightx = 0.0; this.add(gbag, this.closeButton, c); if (errStatus != null) { this.status.setText(errStatus); this.goButton.setEnabled(false); } else { String name = this.sourceURL.getAbsolute(); name = name.substring(0, name.lastIndexOf(47)); Object[] arguments = new Object[]{new String(name)}; if (this.condense) { this.status.setText(MessageFormat.format(Console.message("condense-name"), arguments)); } else { this.status.setText(MessageFormat.format(Console.message("expand-name"), arguments)); } } } @Override public boolean action(Event event, Object what) { Object target = event.target; if (target == this.goButton) { if (!this.start) { this.start = true; } else { this.stop = true; } } else { if (target != this.closeButton) { return false; } if (!this.start || this.finished) { this.done(true); } } return true; } @Override protected void activeCallback() { if (this.start && !this.finished) { this.goButton.setLabel(Console.message("Stop")); if (this.condense) { this.doCondense(); } else { this.doExpand(); } } } private void doCondense() { this.status.setText(Console.message("Scanning-dir")); Vector dirs = new Vector(); getDirectories(dirs, this.path); if (this.stop) { this.cancelled(); } else { String d = ""; int count = dirs.size(); for (int i = 0; i < count; i++) { if (d.length() != 0) { d = d + ";"; } d = d + dirs.elementAt(i); } Vector files = new FileList(d, "cmp;mov").keepPathInfo().dontSort().getList(); count = files.size(); String[] list = new String[count]; int start = this.path.length() + 1; for (int i = 0; i < count; i++) { list[i] = files.elementAt(i).substring(start).replace('\\', '/').toLowerCase(); } this.status.setText(Console.message("Sorting-files")); Sort.sort(list); if (this.stop) { this.cancelled(); } else { this.status.setText(Console.message("Building-archive")); String zipFileName = this.path + "/" + "content.zip"; boolean deleteOnError = true; try { FileOutputStream fos = new FileOutputStream(zipFileName); ZipOutputStream zs = new ZipOutputStream(fos); zs.setMethod(0); double dlen = list.length; for (int i = 0; i < list.length && !this.stop; i++) { Object[] arguments = new Object[]{new String(list[i])}; this.status.setText(MessageFormat.format(Console.message("Reading-list"), arguments)); File f = new File(this.path + "/" + list[i]); int length = (int)f.length(); byte[] data = new byte[length]; FileInputStream fis = new FileInputStream(f); fis.read(data); fis.close(); CRC32 crc = new CRC32(); crc.update(data); this.status.setText(MessageFormat.format(Console.message("Writing-list"), arguments)); ZipEntry ze = new ZipEntry(list[i]); ze.setSize(length); ze.setTime(f.lastModified()); ze.setCrc(crc.getValue()); zs.putNextEntry(ze); zs.write(data, 0, length); zs.closeEntry(); this.progress.setProgress((i + 1) / dlen); } zs.finish(); zs.close(); if (!this.stop) { deleteOnError = false; this.goButton.setEnabled(false); Archive.flushAll(); for (int i = 0; i < list.length; i++) { Object[] arguments = new Object[]{new String(list[i])}; this.status.setText(MessageFormat.format(Console.message("Deleting-list"), arguments)); File f = new File(this.path + "/" + list[i]); f.delete(); this.progress.setProgress((i + 1) / dlen); } this.status.setText(Console.message("Removing-empty")); count = dirs.size(); for (int i = 0; i < count; i++) { File f = new File(dirs.elementAt(i)); if (f.list().length == 0) { f.delete(); } } this.status.setText(Console.message("Done")); this.finished = true; return; } } catch (IOException var21) { Object[] arguments = new Object[]{new String(this.status.getText())}; this.status.setText(MessageFormat.format(Console.message("IO-Error"), arguments)); } if (deleteOnError) { File f = new File(zipFileName); f.delete(); } this.finished = true; if (this.stop) { this.cancelled(); } } } } private void doExpand() { this.status.setText(Console.message("Scanning-archive")); boolean deleteOnError = true; Vector written = new Vector(); try { String zipFileName = this.path + "/" + "content.zip"; ZipFile zip = new ZipFile(zipFileName); Enumeration ents = zip.entries(); int count = 0; while (ents.hasMoreElements() && !this.stop) { count++; ents.nextElement(); } String lastDir = ""; ents = zip.entries(); int i = 0; double dlen = count; while (ents.hasMoreElements() && !this.stop) { ZipEntry ent = ents.nextElement(); String name = ent.getName(); Object[] arguments = new Object[]{new String(name)}; this.status.setText(MessageFormat.format(Console.message("Checking-name"), arguments)); String filePath = this.path + "/" + name; File f = new File(filePath); if (f.exists()) { this.stop = true; this.finished = true; this.status.setText(MessageFormat.format(Console.message("File-exists"), arguments)); break; } int index = filePath.lastIndexOf(47); if (index != -1) { String dir = filePath.substring(0, index); if (!dir.equals(lastDir)) { this.status.setText(Console.message("Creating-dir")); File dirs = new File(dir); dirs.mkdirs(); lastDir = dir; } } this.status.setText(MessageFormat.format(Console.message("Reading-list"), arguments)); byte[] data = Archive.load(zip, ent); this.status.setText(MessageFormat.format(Console.message("Writing-list"), arguments)); FileOutputStream fos = new FileOutputStream(f); written.addElement(f); fos.write(data); fos.close(); i++; this.progress.setProgress(i / dlen); } zip.close(); if (!this.stop) { this.goButton.setEnabled(false); deleteOnError = false; synchronized (Archive.getMutex()) { Archive.flushAll(); new File(zipFileName).delete(); } this.status.setText(Console.message("Done")); this.finished = true; return; } } catch (IOException var20) { Object[] argumentsx = new Object[]{new String(this.status.getText())}; this.status.setText(MessageFormat.format(Console.message("IO-Error"), argumentsx)); } if (deleteOnError) { Enumeration e = written.elements(); while (e.hasMoreElements()) { e.nextElement().delete(); } } if (!this.finished) { this.finished = true; if (this.stop) { this.cancelled(); } } } private void cancelled() { this.finished = true; this.status.setText(Console.message("Cancelled")); } @Override protected boolean done(boolean confirmed) { return this.start && !this.finished ? true : super.done(confirmed); } private static void getDirectories(Vector dirs, String path) { dirs.addElement(path); File dir = new File(path); String[] files = dir.list(); for (int i = 0; i < files.length; i++) { String name = path + '/' + files[i]; File f = new File(name); if (f.isDirectory()) { getDirectories(dirs, name); } } } }