public override void WriteTo(BinaryWriter w, Apk.Version v) { material.WriteTo(w); color.WriteTo(w, v); w.Write(raycastTarget); w.AlignStream(); cullState.WriteTo(w); w.WriteAlignedString(text); w.Write(rightToLeft); w.AlignStream(); fontAsset.WriteTo(w); w.Write(remainingData); }
public override void WriteTo(BinaryWriter w) { w.WriteAlignedString(name); w.Write(forcedFallbackFormat); w.Write(downscaleFallback); w.Write(width); w.Write(height); w.Write(completeImageSize); w.Write(textureFormat); w.Write(mipCount); w.Write(isReadable); w.Write(streamingMips); w.AlignStream(); w.Write(streamingMipsPriority); w.Write(imageCount); w.Write(textureDimension); w.Write(filterMode); w.Write(anisotropic); w.Write(mipBias); w.Write(wrapU); w.Write(wrapV); w.Write(wrapW); w.Write(lightmapFormat); w.Write(colorSpace); w.WritePrefixedBytes(imageData); w.Write(offset); w.Write(size); w.WriteAlignedString(path); }
public override void WriteTo(BinaryWriter w) { text.WriteTo(w); w.Write(maintainTextAlignment); w.AlignStream(); w.WriteAlignedString(key); }
public static void WriteAlignedString(this BinaryWriter write, string toWrite, int overrideAlignment = -1) { var result = Encoding.UTF8.GetBytes(toWrite); write.Write(result.Length); write.Write(result); write.AlignStream(overrideAlignment > 0 ? overrideAlignment : 4); }
public static void WriteAlignedString(this BinaryWriter writer, string str) { var bytes = Encoding.UTF8.GetBytes(str); writer.Write(bytes.Length); writer.Write(bytes); writer.AlignStream(4); }
public override void WriteTo(BinaryWriter w) { w.WriteAlignedString(packID); w.WriteAlignedString(packName); coverImage.WriteTo(w); w.Write(isPackAlwaysOwned); w.AlignStream(); beatmapLevelCollection.WriteTo(w); }
public void WriteTo(BinaryWriter w) { w.WriteAlignedString(docsID); w.WriteAlignedString(sheetID); w.Write(format); textAsset.WriteTo(w); w.Write(downloadOnStart); w.AlignStream(); }
// returns the location to patch the offsets public long WriteTo(BinaryWriter w) { w.AlignStream(); w.Write(pathID); long patchPos = w.BaseStream.Position; w.Write(offset); w.Write(size); w.Write(typeID); return(patchPos); }
public override void WriteTo(BinaryWriter w, Apk.Version v) { w.WriteAlignedString(packID); w.WriteAlignedString(packName); coverImage.WriteTo(w); if (v < Apk.Version.V1_1_0) { w.Write(isPackAlwaysOwned); w.AlignStream(); } beatmapLevelCollection.WriteTo(w); }
public override void WriteTo(BinaryWriter w, Apk.Version v) { w.WriteAlignedString(name); w.Write(loadType); w.Write(channels); w.Write(frequency); w.Write(bitsPerSample); w.Write(length); w.Write(isTracker); w.AlignStream(); w.Write(subsoundIndex); w.Write(preloadAudio); w.Write(backgroundLoad); w.Write(legacy3D); w.AlignStream(); w.WriteAlignedString(source); w.Write(offset); w.Write(size); w.Write(compressionFormat); }
public override void WriteTo(BinaryWriter w, Apk.Version v) { w.WriteAlignedString(name); foreach (float f in floats) { w.Write(f); } w.Write(extrude); w.Write(isPolygon); w.AlignStream(); w.Write(guid); w.Write(second); w.WritePrefixedList(atlasTags, a => a.WriteTo(w)); spriteAtlas.WriteTo(w); texture.WriteTo(w); w.Write(bytesAfterTexture); }
public void WriteTo(Stream outStream) { List <long> patchLocs = new List <long>(objects.Count); byte[] buf; int length; int dataOffset; int metadataSize; using (MemoryStream stream = new MemoryStream()) { BinaryWriter w = new BinaryWriter(stream); // ===== Header w.Write((int)0); // patch w.Write((int)0); // patch w.WriteInt32BE(parsedGeneration); w.Write((int)0); // patch w.WriteInt32BE(0); // not big endian // ===== Metadata w.WriteCString(version); w.Write(targetPlatform); w.Write(enableTypeTree); w.WritePrefixedList(types, x => x.WriteTo(w)); w.WritePrefixedList(objects, x => patchLocs.Add(x.WriteTo(w))); w.WritePrefixedList(scripts, x => x.WriteTo(w)); w.WritePrefixedList(externals, x => x.WriteTo(w)); w.Write((byte)0); metadataSize = (int)w.BaseStream.Position - headerLen; w.WriteZeros(paddingLen); w.AlignStream(); // ===== Data dataOffset = (int)w.BaseStream.Position; foreach (AssetObject obj in objects) { obj.offset = (int)w.BaseStream.Position - dataOffset; obj.data.WriteTo(w, apkVersion); obj.size = ((int)w.BaseStream.Position - dataOffset) - obj.offset; w.WriteZeros(obj.paddingLen); // TODO do objects need to be aligned? // All objects I can find are. If nothing is modified this shouldn't do anything. // But if we change the size of an object it's probably more important to preserve // alignment than the exact amount of padding. w.AlignStream(); } length = (int)stream.Length; stream.Close(); buf = stream.GetBuffer(); } // Patch header PatchInt(buf, 0 * 4, metadataSize, true); PatchInt(buf, 1 * 4, length, true); PatchInt(buf, 3 * 4, dataOffset, true); // Patch objects for (int i = 0; i < patchLocs.Count; i++) { PatchInt(buf, patchLocs[i] + 0 * 4, objects[i].offset, false); PatchInt(buf, patchLocs[i] + 1 * 4, objects[i].size, false); } outStream.Write(buf, 0, length); }
public static void write(string fileName, ref yarnDictionary rootz) { yarnFile f; if (!rootz.yarnFiles.TryGetValue(fileName, out f)) { //yarn file not found Form1.Log("ERROR yarn file not found: " + fileName, true); return; } string assetFileName = Path.GetFileName(f.assetsFilePath); Form1.Log("Writing " + f.yarnFileName + " to " + assetFileName + "..."); if (File.Exists(f.assetsFilePath)) { if (IsFileLocked(f.assetsFilePath)) { MessageBox.Show("The file " + assetFileName + " is locked." + Environment.NewLine + Environment.NewLine + "Try closing any programs that could use it and if that fails try restarting your computer.", "File Locked", MessageBoxButtons.OK, MessageBoxIcon.Warning); Form1.Log("Failed to write " + assetFileName + " (locked)", true); return; } //calculate new yarn object length string yarnFilePath = AppDomain.CurrentDomain.BaseDirectory + @"\yarn files\" + f.yarnFileName + ".txt"; if (IsFileLocked(yarnFilePath)) { MessageBox.Show("The file " + f.yarnFileName + " is locked." + Environment.NewLine + Environment.NewLine + "Sublime is known to cause this problem, try editing with another text editor. Also close any programs that could use " + f.yarnFileName + " and if that fails try restarting your computer.", "File Locked", MessageBoxButtons.OK, MessageBoxIcon.Warning); Form1.Log("Failed to write " + assetFileName + " (" + f.yarnFileName + " locked)", true); return; } string newContent = File.ReadAllText(yarnFilePath); byte[] newContentBytes = Encoding.UTF8.GetBytes(newContent); byte[] pathBytes = Encoding.UTF8.GetBytes(f.yarnPath); uint newLength = 0; uint newLength_name = 0; uint newLength_namePadding = 0; uint newLength_content = 0; uint newLength_contentPadding = 0; uint newLength_path = 0; uint newLength_pathPadding = 0; newLength_name = 4 + (uint)f.yarnFileName.Length; if (newLength_name % 4 > 0) { newLength_namePadding = 4 - (newLength_name % 4); } newLength_content = 4 + (uint)newContentBytes.Length; if (newLength_content % 4 > 0) { newLength_contentPadding = 4 - (newLength_content % 4); } newLength_path = 4 + (uint)f.yarnPath.Length; if (newLength_path % 4 > 0) { newLength_pathPadding = 4 - (newLength_path % 4); } newLength = newLength_name + newLength_namePadding; newLength += newLength_content + newLength_contentPadding; newLength += newLength_path + newLength_pathPadding; //calculate offset delta int offsetDelta = (int)newLength - (int)f.length; //change file length long nextObjectOriginalPosition = f.objectDataOffset + f.offset + f.length; long nextObjectNewPosition = nextObjectOriginalPosition + offsetDelta; long assetfileSize = new FileInfo(f.assetsFilePath).Length; long followingObjectsSize = assetfileSize - nextObjectOriginalPosition; long newAssetFileSize = assetfileSize + offsetDelta; if (offsetDelta < 0) { //yarn object is smaller now -> transpose yarn object following bytes and truncate file FileOps.FileHelper.Transpose(f.assetsFilePath, nextObjectOriginalPosition, nextObjectNewPosition, followingObjectsSize); FileOps.FileHelper.SetFileLen(f.assetsFilePath, newAssetFileSize); } else if (offsetDelta > 0) { //yarn object is bigger now -> transpose yarn object following bytes FileOps.FileHelper.Transpose(f.assetsFilePath, nextObjectOriginalPosition, nextObjectNewPosition, followingObjectsSize); } //update object table with new length and new offsets for following objects List <uint> offsets = new List <uint>(); // SB: Dodgy to leave this hardcoded but at least it's a constant by one name rather than magic numbers, right? // Use my newly added "f.objectEntrySize" for the size of the entry object as a whole... const int offsetToIndex = 0; // SB: 8 bytes long (in file versions >= 14) Won't work for file version < 14 (where this is Int32), but that doesn't apply to NITW const int offsetToOffset = offsetToIndex + 8; // SB: 4 bytes long const int offsetToLength = offsetToOffset + 4; // SB: 4 bytes long uint m_Version; //put all object offsets in a list using (BinaryReader reader = new BinaryReader(File.Open(f.assetsFilePath, FileMode.Open))) { reader.ReadUInt32BE(); reader.ReadUInt32BE(); m_Version = reader.ReadUInt32BE(); reader.BaseStream.Seek(f.objectInfoPosition, SeekOrigin.Begin); for (int i = 0; i < f.objectInfoCount; i++) { if (m_Version >= 14) { reader.AlignStream(); } //skip uint64 index reader.BaseStream.Seek(offsetToOffset, SeekOrigin.Current); //save offsets for later uint offset = reader.ReadUInt32(); offsets.Add(offset); //skip rest of entry var remainingBytes = f.objectEntrySize - offsetToLength; // SB: still a little dodgy reader.BaseStream.Seek(remainingBytes, SeekOrigin.Current); } } //write new length and new offsets and new file size using (BinaryWriter writer = new BinaryWriter(File.Open(f.assetsFilePath, FileMode.Open))) { //update filesize writer.BaseStream.Seek(4, SeekOrigin.Begin); byte[] newAssetFileSizeBytes = BitConverter.GetBytes((uint)newAssetFileSize); Array.Reverse(newAssetFileSizeBytes); writer.Write(newAssetFileSizeBytes); long indexPosition = (f.index - 1) * f.objectEntrySize; // SB: removed hardcoded value writer.BaseStream.Seek(f.objectInfoPosition + indexPosition, SeekOrigin.Begin); if (m_Version >= 14) { writer.AlignStream(); } //update yarn length { writer.BaseStream.Seek(offsetToLength, SeekOrigin.Current); writer.Write(newLength); var remainingBytes = f.objectEntrySize - offsetToLength - 4; // SB: still a little dodgy, additional -4 since we just wrote the length so we're passed the length writer.BaseStream.Seek(remainingBytes, SeekOrigin.Current); } //update all offsets behind f.index for (int i = (int)(f.index); i < f.objectInfoCount; i++) { if (m_Version >= 14) { writer.AlignStream(); } uint newOffset = (uint)(offsets[i] + offsetDelta); writer.BaseStream.Seek(offsetToOffset, SeekOrigin.Current); writer.Write(newOffset); var remainingBytes = f.objectEntrySize - offsetToLength; // SB: still a little dodgy writer.BaseStream.Seek(remainingBytes, SeekOrigin.Current); } //update yarn content writer.BaseStream.Seek(f.objectDataOffset + f.offset + 4 + f.yarnFileName.Length + newLength_namePadding, SeekOrigin.Begin); writer.Write((uint)(newContentBytes.Length)); writer.Write(newContentBytes); if (newContentBytes.Length > 0) { int paddingTemp = 0; if (newContentBytes.Length % 4 > 0) { paddingTemp = 4 - (newContentBytes.Length % 4); } for (int i = 0; i < paddingTemp; i++) { writer.Write((byte)0); } } writer.BaseStream.Position = writer.BaseStream.Position; writer.Write((uint)f.yarnPath.Length); writer.Write(pathBytes); if (pathBytes.Length > 0) { int paddingTemp = 0; if (pathBytes.Length % 4 > 0) { paddingTemp = 4 - (pathBytes.Length % 4); } for (int i = 0; i < paddingTemp; i++) { writer.Write((byte)0); } } } Form1.Log("Writing " + f.yarnFileName + " to " + assetFileName + " done", true); //update yarn dictionary f.lastModified = File.GetLastWriteTime(yarnFilePath); f.length = newLength; f.edited = true; rootz.yarnFiles[f.yarnFileName] = f; JsonUtil.saveYarnDictionary(rootz); } else { Form1.Log("Failed to write " + assetFileName + " (not found)", true); return; } }
public static void WritePrefixedBytes(this BinaryWriter w, byte[] l) { w.Write((int)l.Length); w.Write(l); w.AlignStream(); }
public static void AlignStream(this BinaryWriter writer) { writer.AlignStream(4); }
private static void WriteValue(object value, List <TypeTree> members, BinaryWriter write, ref int i) { var member = members[i]; var level = member.m_Depth; var varTypeStr = member.m_Type; var align = (member.m_MetaFlag & 0x4000) != 0; switch (varTypeStr) { case "SInt8": write.Write((sbyte)value); break; case "UInt8": write.Write((byte)value); break; case "short": case "SInt16": write.Write((short)value); break; case "UInt16": case "unsigned short": write.Write((ushort)value); break; case "int": case "SInt32": write.Write((int)value); break; case "UInt32": case "unsigned int": case "Type*": write.Write((uint)value); break; case "long long": case "SInt64": write.Write((long)value); break; case "UInt64": case "unsigned long long": write.Write((ulong)value); break; case "float": write.Write((float)value); break; case "double": write.Write((double)value); break; case "bool": write.Write((bool)value); break; case "string": write.WriteAlignedString((string)value); i += 3; break; case "vector": { if ((members[i + 1].m_MetaFlag & 0x4000) != 0) { align = true; } var list = (List <object>)value; var size = list.Count; write.Write(size); var vector = GetMembers(members, level, i); i += vector.Count - 1; vector.RemoveRange(0, 3); for (int j = 0; j < size; j++) { int tmp = 0; WriteValue(list[j], vector, write, ref tmp); } break; } case "map": { if ((members[i + 1].m_MetaFlag & 0x4000) != 0) { align = true; } var dic = (List <KeyValuePair <object, object> >)value; var size = dic.Count; write.Write(size); var map = GetMembers(members, level, i); i += map.Count - 1; map.RemoveRange(0, 4); var first = GetMembers(map, map[0].m_Depth, 0); map.RemoveRange(0, first.Count); var second = map; for (int j = 0; j < size; j++) { int tmp1 = 0; int tmp2 = 0; WriteValue(dic[j].Key, first, write, ref tmp1); WriteValue(dic[j].Value, second, write, ref tmp2); } break; } case "TypelessData": { var bytes = ((object[])value).Cast <byte>().ToArray(); var size = bytes.Length; write.Write(size); write.Write(bytes); i += 2; break; } default: { if (i != members.Count && members[i + 1].m_Type == "Array") { goto case "vector"; } var @class = GetMembers(members, level, i); @class.RemoveAt(0); i += @class.Count; var obj = (ExpandoObject)value; var objdic = (IDictionary <string, object>)obj; for (int j = 0; j < @class.Count; j++) { var classmember = @class[j]; var name = classmember.m_Name; WriteValue(objdic[name], @class, write, ref j); } break; } } if (align) { write.AlignStream(4); } }
public void WriteTo(BinaryWriter w) { w.Write(fileIndex); w.AlignStream(); w.Write(inFileID); }