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); } } } } }
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); } } }