public ulong Read(AssetsFileReader reader, ulong filePos) { reader.bigEndian = false; header = reader.ReadStringLength(4); if (header != "cldb") { return(reader.Position); } fileVersion = reader.ReadByte(); if (fileVersion != 3) { return(reader.Position); } compressionType = reader.ReadByte(); if (compressionType != 0) { return(reader.Position); } compressedSize = reader.ReadUInt32(); uncompressedSize = reader.ReadUInt32(); unityVersionCount = reader.ReadByte(); pUnityVersions = new string[unityVersionCount]; for (int i = 0; i < unityVersionCount; i++) { pUnityVersions[i] = reader.ReadCountString(); } stringTableLen = reader.ReadUInt32(); stringTablePos = reader.ReadUInt32(); return(reader.Position); }
public bool Read(AssetsFileReader reader, bool prefReplacersInMemory = false) { reader.bigEndian = false; magic = reader.ReadStringLength(4); if (magic != "EMIP") { return(false); } includesCldb = reader.ReadByte() != 0; modName = reader.ReadCountStringInt16(); modCreators = reader.ReadCountStringInt16(); modDescription = reader.ReadCountStringInt16(); if (includesCldb) { addedTypes = new ClassDatabaseFile(); addedTypes.Read(reader); //get past the string table since the reader goes back to the beginning reader.Position = addedTypes.header.stringTablePos + addedTypes.header.stringTableLen; } else { addedTypes = null; } int affectedFilesCount = reader.ReadInt32(); affectedFiles = new List <InstallerPackageAssetsDesc>(); for (int i = 0; i < affectedFilesCount; i++) { List <object> replacers = new List <object>(); InstallerPackageAssetsDesc desc = new InstallerPackageAssetsDesc() { isBundle = reader.ReadByte() != 0, path = reader.ReadCountStringInt16() }; int replacerCount = reader.ReadInt32(); for (int j = 0; j < replacerCount; j++) { object repObj = ParseReplacer(reader, prefReplacersInMemory); if (repObj is AssetsReplacer repAsset) { replacers.Add(repAsset); } else if (repObj is BundleReplacer repBundle) { replacers.Add(repBundle); } } desc.replacers = replacers; affectedFiles.Add(desc); } return(true); }
public ulong Read(AssetsFileReader reader, ulong filePos, int version) { typeName = new ClassDatabaseFileString(); typeName.Read(reader, reader.Position); fieldName = new ClassDatabaseFileString(); fieldName.Read(reader, reader.Position); depth = reader.ReadByte(); isArray = reader.ReadByte(); size = reader.ReadUInt32(); version = reader.ReadUInt16(); flags2 = reader.ReadUInt32(); return(reader.Position); }
public ulong Read(ulong absFilePos, AssetsFileReader reader) { metadataSize = reader.ReadUInt32(); fileSize = reader.ReadUInt32(); format = reader.ReadUInt32(); offs_firstFile = reader.ReadUInt32(); endianness = reader.ReadByte(); reader.bigEndian = endianness == 1 ? true : false; unknown = reader.ReadBytes(3); return(reader.Position); }
public uint flags; //0x14 public ulong Read(ulong absFilePos, AssetsFileReader reader, bool bigEndian) { version = reader.ReadUInt16(); depth = reader.ReadByte(); isArray = reader.ReadBoolean(); typeStringOffset = reader.ReadUInt32(); nameStringOffset = reader.ReadUInt32(); size = reader.ReadUInt32(); index = reader.ReadUInt32(); flags = reader.ReadUInt32(); return(reader.Position); }
public ulong Read(ulong absFilePos, AssetsFileReader reader, bool bigEndian) { guid = new GUID128(); guid.Read(reader.Position, reader); bufferedPath = new byte[] { reader.ReadByte() }; //todo: why type = reader.ReadInt32(); assetPath = reader.ReadNullTerminated(); if (assetPath.StartsWith("library/")) { assetPath = "Resources\\" + assetPath.Substring(8); } return(reader.Position); }
public void Read(AssetsFileReader reader, int version) { typeName = new ClassDatabaseFileString(); typeName.Read(reader); fieldName = new ClassDatabaseFileString(); fieldName.Read(reader); depth = reader.ReadByte(); isArray = reader.ReadByte(); size = reader.ReadInt32(); switch (version) { case 1: flags2 = reader.ReadUInt32(); break; case 3: case 4: this.version = reader.ReadUInt16(); flags2 = reader.ReadUInt32(); break; } }
private void addFileToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.DefaultExt = ""; if (ofd.ShowDialog() == DialogResult.OK) { string possibleBundleHeader; int possibleFormat; string emptyVersion; using (FileStream fs = File.OpenRead(ofd.FileName)) using (AssetsFileReader reader = new AssetsFileReader(fs)) { if (fs.Length < 0x20) { MessageBox.Show("File too small. Are you sure this is a unity file?", "Assets View"); return; } possibleBundleHeader = reader.ReadStringLength(7); reader.Position = 0x08; possibleFormat = reader.ReadInt32(); reader.Position = 0x14; string possibleVersion = ""; char curChar; while ((curChar = (char)reader.ReadByte()) != 0x00 && possibleVersion.Length < 100) { possibleVersion += curChar; } emptyVersion = Regex.Replace(possibleVersion, "[a-zA-Z0-9\\.]", ""); } if (possibleBundleHeader == "UnityFS") { LoadBundleFile(ofd.FileName); } else if (possibleFormat < 0xFF && emptyVersion == "") { LoadAssetsFile(ofd.FileName); } else { MessageBox.Show("Couldn't detect file type. Are you sure this is a unity file?", "Assets View"); } } }
public AssetsFileTable(AssetsFile pFile, bool readNames = true) { this.pFile = pFile; reader = new AssetsFileReader(pFile.readerPar); //todo, look back and see why I made a new reader here readerPar = pFile.readerPar; reader.bigEndian = pFile.header.endianness == 1 ? true : false; reader.BaseStream.Position = pFile.AssetTablePos; assetFileInfoCount = pFile.AssetCount; pAssetFileInfo = new AssetFileInfoEx[assetFileInfoCount]; for (int i = 0; i < assetFileInfoCount; i++) { AssetFileInfoEx assetFileInfoSet = new AssetFileInfoEx(); if (pFile.header.format >= 0x0E) { assetFileInfoSet.index = reader.ReadUInt64(); } else { assetFileInfoSet.index = reader.ReadUInt32(); } assetFileInfoSet.offs_curFile = reader.ReadUInt32(); assetFileInfoSet.curFileSize = reader.ReadUInt32(); assetFileInfoSet.curFileTypeOrIndex = reader.ReadUInt32(); if (pFile.header.format < 0x10) { assetFileInfoSet.inheritedUnityClass = reader.ReadUInt16(); } if (pFile.header.format <= 0x10) { assetFileInfoSet.scriptIndex = reader.ReadUInt16(); } if (0x0F <= pFile.header.format && pFile.header.format <= 0x10) { assetFileInfoSet.unknown1 = reader.ReadByte(); reader.ReadBytes(3); } assetFileInfoSet.absoluteFilePos = pFile.header.offs_firstFile + assetFileInfoSet.offs_curFile; assetFileInfoSet.curFileType = (uint)pFile.typeTree.pTypes_Unity5[assetFileInfoSet.curFileTypeOrIndex].classId; //todo: fix this variable (it can be from a different variable (index)) pAssetFileInfo[i] = assetFileInfoSet; } }
public static DetectedFileType DetectFileType(string filePath) { string possibleBundleHeader; int possibleFormat; string emptyVersion; using (FileStream fs = File.OpenRead(filePath)) using (AssetsFileReader r = new AssetsFileReader(fs)) { if (fs.Length < 0x20) { return(DetectedFileType.Unknown); } possibleBundleHeader = r.ReadStringLength(7); r.Position = 0x08; possibleFormat = r.ReadInt32(); r.Position = 0x14; string possibleVersion = ""; char curChar; while (r.Position < r.BaseStream.Length && (curChar = (char)r.ReadByte()) != 0x00) { possibleVersion += curChar; if (possibleVersion.Length < 0xFF) { break; } } emptyVersion = Regex.Replace(possibleVersion, "[a-zA-Z0-9\\.]", ""); } if (possibleBundleHeader == "UnityFS") { return(DetectedFileType.BundleFile); } else if (possibleFormat < 0xFF && emptyVersion == "") { return(DetectedFileType.AssetsFile); } return(DetectedFileType.Unknown); }
public ulong Read(bool hasTypeTree, ulong absFilePos, AssetsFileReader reader, uint version, uint typeVersion, bool bigEndian) { classId = reader.ReadInt32(); if (version >= 0x10) { unknown16_1 = reader.ReadByte(); } if (version >= 0x11) { scriptIndex = reader.ReadUInt16(); } if ((version < 0x11 && classId < 0) || (version >= 0x11 && scriptIndex != 0xFFFF)) { unknown1 = reader.ReadUInt32(); unknown2 = reader.ReadUInt32(); unknown3 = reader.ReadUInt32(); unknown4 = reader.ReadUInt32(); } unknown5 = reader.ReadUInt32(); unknown6 = reader.ReadUInt32(); unknown7 = reader.ReadUInt32(); unknown8 = reader.ReadUInt32(); if (hasTypeTree) { typeFieldsExCount = reader.ReadUInt32(); stringTableLen = reader.ReadUInt32(); pTypeFieldsEx = new TypeField_0D[typeFieldsExCount]; for (int i = 0; i < typeFieldsExCount; i++) { TypeField_0D typefield0d = new TypeField_0D(); typefield0d.Read(reader.Position, reader, bigEndian); pTypeFieldsEx[i] = typefield0d; } string rawStringTable = Encoding.UTF8.GetString(reader.ReadBytes((int)stringTableLen)); pStringTable = rawStringTable.Split('\0'); Array.Resize(ref pStringTable, pStringTable.Length - 1); } return(reader.Position); }
private static object ParseReplacer(AssetsFileReader reader, bool prefReplacersInMemory) { short replacerType = reader.ReadInt16(); byte fileType = reader.ReadByte(); if (fileType == 0) //BundleReplacer { string oldName = reader.ReadCountStringInt16(); string newName = reader.ReadCountStringInt16(); bool hasSerializedData = reader.ReadByte() != 0; //guess long replacerCount = reader.ReadInt64(); List <AssetsReplacer> replacers = new List <AssetsReplacer>(); for (int i = 0; i < replacerCount; i++) { AssetsReplacer assetReplacer = (AssetsReplacer)ParseReplacer(reader, prefReplacersInMemory); replacers.Add(assetReplacer); } if (replacerType == 4) //BundleReplacerFromAssets { //we have to null the assetsfile here and call init later BundleReplacer replacer = new BundleReplacerFromAssets(oldName, newName, null, replacers, 0); return(replacer); } } else if (fileType == 1) //AssetsReplacer { byte unknown01 = reader.ReadByte(); //always 1 int fileId = reader.ReadInt32(); long pathId = reader.ReadInt64(); int classId = reader.ReadInt32(); ushort monoScriptIndex = reader.ReadUInt16(); List <AssetPPtr> preloadDependencies = new List <AssetPPtr>(); int preloadDependencyCount = reader.ReadInt32(); for (int i = 0; i < preloadDependencyCount; i++) { AssetPPtr pptr = new AssetPPtr(reader.ReadInt32(), reader.ReadInt64()); preloadDependencies.Add(pptr); } if (replacerType == 0) //remover { AssetsReplacer replacer = new AssetsRemover(fileId, pathId, classId, monoScriptIndex); if (preloadDependencyCount != 0) { replacer.SetPreloadDependencies(preloadDependencies); } return(replacer); } else if (replacerType == 2) //adder/replacer? { Hash128? propertiesHash = null; Hash128? scriptHash = null; ClassDatabaseFile?classData = null; AssetsReplacer replacer; bool flag1 = reader.ReadByte() != 0; //no idea, couldn't get it to be 1 if (flag1) { throw new NotSupportedException("you just found a file with the mysterious flag1 set, send the file to nes"); } bool flag2 = reader.ReadByte() != 0; //has properties hash if (flag2) { propertiesHash = new Hash128(reader); } bool flag3 = reader.ReadByte() != 0; //has script hash if (flag3) { scriptHash = new Hash128(reader); } bool flag4 = reader.ReadByte() != 0; //has cldb if (flag4) { classData = new ClassDatabaseFile(); classData.Read(reader); } long bufLength = reader.ReadInt64(); if (prefReplacersInMemory) { byte[] buf = reader.ReadBytes((int)bufLength); replacer = new AssetsReplacerFromMemory(fileId, pathId, classId, monoScriptIndex, buf); } else { replacer = new AssetsReplacerFromStream(fileId, pathId, classId, monoScriptIndex, reader.BaseStream, reader.Position, bufLength); } if (propertiesHash != null) { replacer.SetPropertiesHash(propertiesHash.Value); } if (scriptHash != null) { replacer.SetScriptIDHash(scriptHash.Value); } if (scriptHash != null) { replacer.SetTypeInfo(classData, null, false); //idk what the last two are supposed to do } if (preloadDependencyCount != 0) { replacer.SetPreloadDependencies(preloadDependencies); } return(replacer); } } return(null); }
public AssetTypeValueField ReadType(AssetsFileReader reader, ulong filePos, AssetTypeValueField valueField, bool bigEndian) { if (valueField.templateField.isArray) { if (valueField.templateField.childrenCount == 2) { EnumValueTypes sizeType = valueField.templateField.children[0].valueType; if (sizeType == EnumValueTypes.ValueType_Int32 || sizeType == EnumValueTypes.ValueType_UInt32) { valueField.childrenCount = reader.ReadUInt32(); valueField.pChildren = new AssetTypeValueField[valueField.childrenCount]; for (int i = 0; i < valueField.childrenCount; i++) { valueField.pChildren[i] = new AssetTypeValueField(); valueField.pChildren[i].templateField = valueField.templateField.children[1]; valueField.pChildren[i] = ReadType(reader, reader.Position, valueField.pChildren[i], bigEndian); } if (valueField.templateField.align) { reader.Align(); } AssetTypeArray ata = new AssetTypeArray(); ata.size = valueField.childrenCount; valueField.value = new AssetTypeValue(EnumValueTypes.ValueType_Array, 0); valueField.value.Set(ata); } else { Debug.WriteLine("Invalid array value type! Found an unexpected " + sizeType.ToString() + " type instead!"); } } else { Debug.WriteLine("Invalid array!"); } } else { EnumValueTypes type = valueField.templateField.valueType; if (type != 0) { valueField.value = new AssetTypeValue(type, 0); } if (type == EnumValueTypes.ValueType_String) { valueField.value.Set(reader.ReadCountStringInt32()); reader.Align(); } else { valueField.childrenCount = valueField.templateField.childrenCount; if (valueField.childrenCount == 0) { valueField.pChildren = new AssetTypeValueField[0]; switch (valueField.templateField.valueType) { case EnumValueTypes.ValueType_Int8: valueField.value.Set(reader.ReadSByte()); if (valueField.templateField.align) { reader.Align(); } break; case EnumValueTypes.ValueType_UInt8: case EnumValueTypes.ValueType_Bool: valueField.value.Set(reader.ReadByte()); if (valueField.templateField.align) { reader.Align(); } break; case EnumValueTypes.ValueType_Int16: valueField.value.Set(reader.ReadInt16()); if (valueField.templateField.align) { reader.Align(); } break; case EnumValueTypes.ValueType_UInt16: valueField.value.Set(reader.ReadUInt16()); if (valueField.templateField.align) { reader.Align(); } break; case EnumValueTypes.ValueType_Int32: valueField.value.Set(reader.ReadInt32()); break; case EnumValueTypes.ValueType_UInt32: valueField.value.Set(reader.ReadUInt32()); break; case EnumValueTypes.ValueType_Int64: valueField.value.Set(reader.ReadInt64()); break; case EnumValueTypes.ValueType_UInt64: valueField.value.Set(reader.ReadUInt64()); break; case EnumValueTypes.ValueType_Float: valueField.value.Set(reader.ReadSingle()); break; case EnumValueTypes.ValueType_Double: valueField.value.Set(reader.ReadDouble()); break; } } else { valueField.pChildren = new AssetTypeValueField[valueField.childrenCount]; for (int i = 0; i < valueField.childrenCount; i++) { valueField.pChildren[i] = new AssetTypeValueField(); valueField.pChildren[i].templateField = valueField.templateField.children[i]; valueField.pChildren[i] = ReadType(reader, reader.Position, valueField.pChildren[i], bigEndian); } } } } return(valueField); }