public override long WriteReplacer(AssetsFileWriter writer) { writer.Write((short)2); //replacer type writer.Write((byte)1); //file type (0 bundle, 1 assets) writer.Write((byte)1); //idk, always 1 writer.Write(0); //always 0 even when fileid is something else writer.Write(GetPathID()); writer.Write(GetClassID()); writer.Write(GetMonoScriptID()); writer.Write(preloadList.Count); for (int i = 0; i < preloadList.Count; i++) { writer.Write(preloadList[i].fileID); writer.Write(preloadList[i].pathID); } //flag1, unknown writer.Write((byte)0); //flag2 if (propertiesHash.data != null) { writer.Write((byte)1); writer.Write(propertiesHash.data); } else { writer.Write((byte)0); } //flag3 if (scriptIdHash.data != null) { writer.Write((byte)1); writer.Write(scriptIdHash.data); } else { writer.Write((byte)0); } //flag4 if (file != null) { writer.Write((byte)1); file.Write(writer); } else { writer.Write((byte)0); } writer.Write(GetSize()); Write(writer); return(writer.Position); }
public void Write(AssetsFileWriter writer, int optimizeStringTable = 1, int compress = 1) { long filePos = writer.BaseStream.Position; //lol don't do this if compress is 0 if ((compress & 0x80) == 0) { throw new NotImplementedException("Compression flag 0x80 must be used"); } //compress 1 for lz4 and 2 for lzma //this is backwards from assets files //build string table StringBuilder strTableBuilder = new StringBuilder(); Dictionary <string, uint> strTableMap; if (optimizeStringTable != 0) { strTableMap = new Dictionary <string, uint>(); } else { strTableMap = null; } foreach (ClassDatabaseFile cldb in files) { for (int i = 0; i < cldb.classes.Count; i++) { ClassDatabaseType type = cldb.classes[i]; AddStringTableEntry(cldb, strTableBuilder, strTableMap, ref type.name); if (header.fileVersion == 4 && (cldb.header.flags & 1) != 0) { AddStringTableEntry(cldb, strTableBuilder, strTableMap, ref type.assemblyFileName); } List <ClassDatabaseTypeField> fields = type.fields; for (int j = 0; j < fields.Count; j++) { ClassDatabaseTypeField field = fields[j]; AddStringTableEntry(cldb, strTableBuilder, strTableMap, ref field.fieldName); AddStringTableEntry(cldb, strTableBuilder, strTableMap, ref field.typeName); fields[j] = field; } } } header.fileCount = (uint)files.Count; header.Write(writer); using (MemoryStream cldbMs = new MemoryStream()) using (AssetsFileWriter cldbWriter = new AssetsFileWriter(cldbMs)) { //annoyingly, files and header.files are two different lists... for (int i = 0; i < files.Count; i++) { ClassDatabaseFile cldb = files[i]; long cldbStartFilePos = cldbWriter.BaseStream.Position; //does not support 0x80 self compression rn cldb.Write(cldbWriter, 0, 0, false); long cldbEndFilePos = cldbWriter.BaseStream.Position; string cldbName = header.files[i].name; header.files[i] = new ClassDatabaseFileRef() { offset = (uint)cldbStartFilePos, length = (uint)(cldbEndFilePos - cldbStartFilePos), name = cldbName }; } header.fileBlockSize = (uint)cldbMs.Length; cldbMs.Position = 0; if ((compress & 0x20) == 0) //compressed { if ((compress & 0x1f) == 1) //lz4 { byte[] compressedBlock = LZ4Codec.Encode32HC(cldbMs.ToArray(), 0, (int)cldbMs.Length); writer.Write(compressedBlock); } else if ((compress & 0x1f) == 2) //lzma { byte[] compressedBlock = SevenZipHelper.Compress(cldbMs.ToArray()); writer.Write(compressedBlock); } else { throw new ArgumentException("File marked as compressed but no valid compression option set!"); } } else //write normally { cldbMs.CopyToCompat(writer.BaseStream); } } header.stringTableOffset = (uint)writer.Position; byte[] stringTableBytes = Encoding.ASCII.GetBytes(strTableBuilder.ToString()); header.stringTableLenUncompressed = (uint)stringTableBytes.Length; if ((compress & 0x40) == 0) //string table is compressed { if ((compress & 0x1f) == 1) //lz4 { stringTableBytes = LZ4Codec.Encode32HC(stringTableBytes, 0, stringTableBytes.Length); } else if ((compress & 0x1f) == 2) //lzma { stringTableBytes = SevenZipHelper.Compress(stringTableBytes); } else { throw new ArgumentException("File marked as compressed but no valid compression option set!"); } } header.stringTableLenCompressed = (uint)stringTableBytes.Length; writer.Write(stringTableBytes); writer.Position = filePos; header.compressionType = (byte)compress; header.Write(writer); }