public object Parse(TypeNode typeNode, ArchiveBinaryReader reader) { object result = null; switch (typeNode.TypeFlag) { case "bool": result = reader.ReadBoolean(); break; case "SInt8": result = reader.ReadSByte(); break; case "char": case "UInt8": result = reader.ReadByte(); break; case "short": case "SInt16": result = reader.ReadInt16(); break; case "unsigned short": case "UInt16": result = reader.ReadUInt16(); break; case "int": case "SInt32": result = reader.ReadInt32(); break; case "unsigned int": case "UInt32": case "Type*": result = reader.ReadUInt32(); break; case "long long": case "SInt64": result = reader.ReadInt64(); break; case "unsigned long long": case "UInt64": result = reader.ReadUInt64(); break; case "float": result = reader.ReadSingle(); break; case "double": result = reader.ReadDouble(); break; case "Quaternionf": { result = reader.ReadQuaternion(); break; } case "float4": case "Vector4f": { result = reader.ReadVector4(); break; } case "float3": case "Vector3f": { result = reader.ReadVector3(); break; } case "float2": case "Vector2f": { result = reader.ReadVector2(); break; } case "ColorRGBA": { if (typeNode.Version == 2) { result = reader.ReadColor32(); } else { result = reader.ReadColor(); } break; } case "Matrix4x4f": { result = reader.ReadMatrix4x4(); break; } case "Hash128": { result = reader.ReadHash128(); break; } case "string": { result = reader.ReadString(); break; } case "vector": case "staticvector": case "set": { var valueTypeNode = typeNode.Children[0]; result = this.Parse(valueTypeNode, reader); break; } case "map": { var pairTypeNode = typeNode.Children[0].Children[1]; var keyTypeNode = pairTypeNode.Children[0]; var valueTypeNode = pairTypeNode.Children[1]; var size = reader.ReadInt32(); Map map = new Map(typeNode); for (int i = 0; i < size; i++) { var key = this.Parse(keyTypeNode, reader); var value = this.Parse(valueTypeNode, reader); map.Add(key, value); } result = map; break; } case "Array": { var valueTypeNode = typeNode.Children[1]; var size = reader.ReadInt32(); result = this.ParseArray(valueTypeNode, size, reader); break; } case "PPtr": { var fileID = reader.ReadInt32(); var pathID = reader.ReadInt64(); result = new PPtr(fileID, pathID, typeNode.TypeName); break; } case "TypelessData": { var size = reader.ReadInt32(); result = new TypelessData(reader.ReadBytes(size)); break; } case "StreamedResource": { var source = reader.ReadString(); var offset = reader.ReadUInt64(); var size = reader.ReadUInt64(); var streamedResource = new StreamedResource(source, offset, size); result = streamedResource; break; } case "AssetBundle": { AssetBundle bundle = new AssetBundle(((TypeTree)typeNode).Archive); bundle.FullName = reader.ReadString(); var size = reader.ReadInt32(); List <PPtr> preloadTable = new List <PPtr>(size); for (int i = 0; i < size; i++) { PPtr pptr = new PPtr(reader.ReadInt32(), reader.ReadInt64(), "PPtr<Object>"); preloadTable.Add(pptr); } bundle.Preloads.AddRange(preloadTable); size = reader.ReadInt32(); List <AssetPair> container = new List <AssetPair>(size); for (int i = 0; i < size; i++) { var first = reader.ReadString(); var preloadIndex = reader.ReadInt32(); var preloadSize = reader.ReadInt32(); var pptr = new PPtr(reader.ReadInt32(), reader.ReadInt64(), "PPtr<Object>"); var pair = new AssetPair(first, new Objects.AssetInfo(preloadIndex, preloadSize, pptr)); container.Add(pair); } bundle.Container.AddRange(container); bundle.MainAsset = new Objects.AssetInfo(reader.ReadInt32(), reader.ReadInt32(), new PPtr(reader.ReadInt32(), reader.ReadInt64(), "PPtr<Object>")); bundle.RuntimeCompatibility = reader.ReadUInt32(); bundle.Name = reader.ReadString(); size = reader.ReadInt32(); List <string> dependencies = new List <string>(size); for (int i = 0; i < size; i++) { dependencies.Add(reader.ReadString()); } bundle.Dependencies.AddRange(dependencies); bundle.IsStreamed = reader.ReadBoolean(); result = bundle; break; } case "PreloadData": { PreloadData preloadData = new PreloadData(((TypeTree)typeNode).Archive); preloadData.Name = reader.ReadString(); var size = reader.ReadInt32(); List <PPtr> preloadTable = new List <PPtr>(size); for (int i = 0; i < size; i++) { PPtr pptr = new PPtr(reader.ReadInt32(), reader.ReadInt64(), "PPtr<Object>"); preloadTable.Add(pptr); } preloadData.Preloads.AddRange(preloadTable); size = reader.ReadInt32(); List <string> dependencies = new List <string>(size); for (int i = 0; i < size; i++) { dependencies.Add(reader.ReadString()); } preloadData.Dependencies.AddRange(dependencies); result = preloadData; break; } case "AssetBundleManifest": { Objects.AssetBundleManifest obj = new Objects.AssetBundleManifest((TypeTree)typeNode); foreach (TypeNode childNode in typeNode.Children) { var key = childNode.FieldName; var childValue = this.Parse(childNode, reader); obj[key] = childValue; } result = obj; break; } default: { DynamicObject obj = typeNode is TypeTree ? new UnityDynamicObject((TypeTree)typeNode) : new DynamicObject(typeNode); foreach (TypeNode childNode in typeNode.Children) { var key = childNode.FieldName; var childValue = this.Parse(childNode, reader); obj[key] = childValue; } result = obj; break; } } if (typeNode.IsAlign) { reader.Align(4); } return(result); }
public static IProgressResult <float> Load(this ArchiveContainer container, DirectoryInfo dir, IStreamDecryptor decryptor) { try { List <FileInfo> files = new List <FileInfo>(); foreach (FileInfo file in dir.GetFiles("*", SearchOption.TopDirectoryOnly)) { if (file.Name.EndsWith(BundleSetting.ManifestFilename)) { files.Add(file); continue; } if (file.Name.EndsWith(dir.Name)) { files.Add(file); continue; } } if (files.Count <= 0) { throw new Exception("Please select the root directory of the AssetBundle"); } files.Sort((x, y) => y.LastWriteTime.CompareTo(x.LastWriteTime)); if (files[0].Name.Equals(BundleSetting.ManifestFilename)) { BundleManifest manifest = BundleManifest.Parse(File.ReadAllText(files[0].FullName, Encoding.UTF8)); return(container.LoadAssetBundle(dir.FullName, decryptor, manifest.GetAll())); } else if (files[0].Name.Equals(dir.Name)) { List <string> filenames = new List <string>(); string[] bundleNames = new string[0]; var bundle = AssetBundleArchive.Load(files[0].FullName); foreach (var archive in bundle.AssetArchives) { ObjectArchive oa = archive as ObjectArchive; if (oa == null) { continue; } foreach (var summary in oa.GetAllObjectInfo()) { if (summary.TypeID == TypeID.AssetBundleManifest) { Objects.AssetBundleManifest assetBundleManifest = summary.GetObject <Objects.AssetBundleManifest>(); bundleNames = assetBundleManifest.GetAllAssetBundles(); } } } foreach (string bundleName in bundleNames) { var fullName = System.IO.Path.Combine(dir.FullName, bundleName.Replace("/", @"\")); filenames.Add(fullName); } bundle.Dispose(); //UnityEngine.AssetBundle bundle = UnityEngine.AssetBundle.LoadFromFile(files[0].FullName); //AssetBundleManifest manifest = bundle.LoadAsset<AssetBundleManifest>("assetbundlemanifest"); //bundle.Unload(false); //files = new List<FileInfo>(); //foreach (string bundleName in manifest.GetAllAssetBundles()) //{ // var fullName = System.IO.Path.Combine(dir.FullName, bundleName.Replace("/", @"\")); // filenames.Add(fullName); //} return(container.LoadAssetBundle(filenames.ToArray())); } else { List <string> filenames = new List <string>(); foreach (FileInfo file in dir.GetFiles("*", SearchOption.AllDirectories)) { if (file.FullName.EndsWith(BundleSetting.ManifestFilename) || file.FullName.EndsWith(".manifest")) { continue; } filenames.Add(file.FullName); } return(container.LoadAssetBundle(filenames.ToArray())); } } catch (Exception e) { return(new ImmutableProgressResult <float>(e, 0f)); } }