From 7ce402e8b73f8a94fcbb63d7a4070edcde8d2fae Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Tue, 4 Apr 2006 20:34:07 +0000 Subject: [PATCH] Add support for having Getdown unpack bundles after it validates them. Eventually we should probably nix unpacking support in the resource manager and just have Getdown take care of it all as it's simpler. --- .../threerings/getdown/data/Application.java | 31 +++++++++++----- .../com/threerings/getdown/data/Resource.java | 35 ++++++++++++++++++- 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/java/com/threerings/getdown/data/Application.java b/src/java/com/threerings/getdown/data/Application.java index e421536..f56c3e0 100644 --- a/src/java/com/threerings/getdown/data/Application.java +++ b/src/java/com/threerings/getdown/data/Application.java @@ -121,7 +121,7 @@ public class Application public Resource getConfigResource () { try { - return createResource(CONFIG_FILE); + return createResource(CONFIG_FILE, false); } catch (Exception e) { throw new RuntimeException("Invalid appbase '" + _vappbase + "'."); } @@ -162,7 +162,7 @@ public class Application String pfile = "patch" + _version + ".dat"; try { URL remote = new URL(createVAppBase(_targetVersion), pfile); - return new Resource(pfile, remote, getLocalPath(pfile)); + return new Resource(pfile, remote, getLocalPath(pfile), false); } catch (Exception e) { Log.warning("Failed to create patch resource path [pfile=" + pfile + ", appbase=" + _appbase + ", tvers=" + _targetVersion + @@ -259,7 +259,7 @@ public class Application } for (int ii = 0; ii < codes.length; ii++) { try { - _codes.add(createResource(codes[ii])); + _codes.add(createResource(codes[ii], false)); } catch (Exception e) { Log.warning("Invalid code resource '" + codes[ii] + "'." + e); } @@ -269,8 +269,16 @@ public class Application String[] rsrcs = ConfigUtil.getMultiValue(cdata, "resource"); if (rsrcs != null) { for (int ii = 0; ii < rsrcs.length; ii++) { + String rsrc = rsrcs[ii]; try { - _resources.add(createResource(rsrcs[ii])); + boolean unpack = false; + int uidx; + if ((uidx = rsrc.indexOf("[u]")) != -1) { + unpack = true; + rsrc = rsrc.substring(0, uidx).trim() + + rsrc.substring(uidx+3).trim(); + } + _resources.add(createResource(rsrc, unpack)); } catch (Exception e) { Log.warning("Invalid resource '" + rsrcs[ii] + "'. " + e); } @@ -629,9 +637,13 @@ public class Application try { if (_digest.validateResource(rsrc, mpobs)) { - // make a note that this file is kosher - rsrc.markAsValid(); - continue; + // unpack this resource if appropriate + if (!rsrc.shouldUnpack() || rsrc.unpack()) { + // finally note that this resource is kosher + rsrc.markAsValid(); + continue; + } + Log.info("Failure unpacking resource [rsrc=" + rsrc + "]."); } } catch (Exception e) { @@ -737,10 +749,11 @@ public class Application } /** Helper function for creating {@link Resource} instances. */ - protected Resource createResource (String path) + protected Resource createResource (String path, boolean unpack) throws MalformedURLException { - return new Resource(path, getRemoteURL(path), getLocalPath(path)); + return new Resource( + path, getRemoteURL(path), getLocalPath(path), unpack); } /** Used to parse rectangle specifications from the config file. */ diff --git a/src/java/com/threerings/getdown/data/Resource.java b/src/java/com/threerings/getdown/data/Resource.java index 16bd663..536ff29 100644 --- a/src/java/com/threerings/getdown/data/Resource.java +++ b/src/java/com/threerings/getdown/data/Resource.java @@ -19,6 +19,7 @@ import java.util.jar.JarFile; import com.samskivert.io.StreamUtil; import com.samskivert.util.CollectionUtil; +import com.samskivert.util.FileUtil; import com.samskivert.util.SortableArrayList; import com.samskivert.util.StringUtil; @@ -33,12 +34,13 @@ public class Resource /** * Creates a resource with the supplied remote URL and local path. */ - public Resource (String path, URL remote, File local) + public Resource (String path, URL remote, File local, boolean unpack) { _path = path; _remote = remote; _local = local; _marker = new File(_local.getPath() + "v"); + _unpack = unpack; } /** @@ -65,6 +67,15 @@ public class Resource return _remote; } + /** + * Returns true if this resource should be unpacked as a part of the + * validation process. + */ + public boolean shouldUnpack () + { + return _unpack; + } + /** * Computes the MD5 hash of this resource's underlying file. * Note: This is both CPU and I/O intensive. @@ -113,6 +124,27 @@ public class Resource } } + /** + * Unpacks this resource file into the directory that contains it. Returns + * false if an error occurs while unpacking it. + */ + public boolean unpack () + { + // sanity check + if (!_local.getPath().endsWith(".jar")) { + Log.warning("Requested to unpack non-jar file '" + _local + "'."); + return false; + } + try { + return FileUtil.unpackJar( + new JarFile(_local), _local.getParentFile()); + } catch (IOException ioe) { + Log.warning("Failed to create JarFile from '" + + _local + "': " + ioe); + return false; + } + } + /** * Wipes this resource file along with any "validated" marker file * that may be associated with it. @@ -237,6 +269,7 @@ public class Resource protected String _path; protected URL _remote; protected File _local, _marker; + protected boolean _unpack; /** Used to sort the entries in a jar file. */ protected static final Comparator ENTRY_COMP = new Comparator() {