Example #1
0
  public void split() throws IOException {
    List<ObjectPath> pathTable = asset.getPaths();
    TypeTree typeTree = asset.getTypeTree();

    // assets with just one object can't be split any further
    if (pathTable.size() == 1) {
      L.warning("Asset doesn't contain sub-assets!");
      return;
    }

    for (ObjectPath path : pathTable) {
      // skip filtered classes
      if (cf != null && !cf.accept(path)) {
        continue;
      }

      String className = ClassID.getNameForID(path.getClassID(), true);

      AssetFile subAsset = new AssetFile();
      subAsset.getHeader().setFormat(asset.getHeader().getFormat());

      ObjectPath subFieldPath = new ObjectPath();
      subFieldPath.setClassID1(path.getClassID1());
      subFieldPath.setClassID2(path.getClassID2());
      subFieldPath.setLength(path.getLength());
      subFieldPath.setOffset(0);
      subFieldPath.setPathID(1);
      subAsset.getPaths().add(subFieldPath);

      TypeTree subTypeTree = subAsset.getTypeTree();
      subTypeTree.setEngineVersion(typeTree.getEngineVersion());
      subTypeTree.setVersion(-2);
      subTypeTree.setFormat(typeTree.getFormat());
      subTypeTree.getFields().put(path.getClassID(), typeTree.getFields().get(path.getClassID()));

      subAsset.setDataBuffer(asset.getPathBuffer(path));

      Path subAssetDir = outputDir.resolve(className);
      if (Files.notExists(subAssetDir)) {
        Files.createDirectories(subAssetDir);
      }

      // probe asset name
      String subAssetName = getObjectName(asset, path);
      if (subAssetName != null) {
        // remove any chars that could cause troubles on various file systems
        subAssetName = FilenameSanitizer.sanitizeName(subAssetName);
      } else {
        // use numeric names
        subAssetName = String.format("%06d", path.getPathID());
      }
      subAssetName += ".asset";

      Path subAssetFile = subAssetDir.resolve(subAssetName);
      if (Files.notExists(subAssetFile)) {
        L.log(Level.INFO, "Writing {0}", subAssetFile);
        subAsset.save(subAssetFile);
      }
    }
  }
Example #2
0
  public void extract(boolean raw) throws IOException {
    List<ObjectPath> paths = asset.getPaths();
    Deserializer deser = new Deserializer(asset);

    for (AssetExtractHandler extractHandler : extractHandlerMap.values()) {
      extractHandler.setAssetFile(asset);
      extractHandler.setOutputDir(outputDir);
    }

    for (ObjectPath path : paths) {
      // skip filtered classes
      if (cf != null && !cf.accept(path)) {
        continue;
      }

      String className = ClassID.getNameForID(path.getClassID(), true);

      // write just the serialized object data or parsed and extracted content?
      if (raw) {
        String assetFileName = String.format("%06d.bin", path.getPathID());
        Path classDir = outputDir.resolve(className);
        if (Files.notExists(classDir)) {
          Files.createDirectories(classDir);
        }

        Path assetFile = classDir.resolve(assetFileName);

        L.log(Level.INFO, "Writing {0} {1}", new Object[] {className, assetFileName});

        ByteBuffer bbAsset = asset.getPathBuffer(path);

        try {
          ByteBufferUtils.save(assetFile, bbAsset);
        } catch (Exception ex) {
          L.log(Level.WARNING, "Can't write " + path + " to " + assetFile, ex);
        }
      } else {
        AssetExtractHandler handler = getHandler(className);

        if (handler != null) {
          UnityObject obj;

          try {
            obj = deser.deserialize(path);
          } catch (Exception ex) {
            L.log(Level.WARNING, "Can't deserialize " + path, ex);
            continue;
          }

          try {
            handler.setObjectPath(path);
            handler.extract(obj);
          } catch (Exception ex) {
            L.log(Level.WARNING, "Can't extract " + path, ex);
          }
        }
      }
    }
  }