public static void WriteArray(ByamlContext ctx, ByamlEntry entry, BinaryDataWriter bw) { var list = (List <ByamlEntry>)entry.Value; bw.Write((byte)entry.NodeType); bw.WriteInt24(list.Count); List <long> tempOffs = new List <long>(); //node types foreach (var item in list) { bw.Write((byte)item.NodeType); } bw.Align(4); //values foreach (var item in list) { if (NodeIsValue(item.NodeType)) { WriteValue(ctx, item, bw); } else { tempOffs.Add(bw.Position); bw.Write(0); //temp } } //array/dictionary int index = 0; foreach (var item in list) { if (!NodeIsValue(item.NodeType)) { long curPos = bw.Position; using (bw.TemporarySeek(tempOffs[index++], SeekOrigin.Begin)) bw.Write((int)curPos); if (item.NodeType == ByamlNodeType.Array) { WriteArray(ctx, item, bw); } else if (item.NodeType == ByamlNodeType.Dictionary) { WriteDictionary(ctx, item, bw); } } } }
private void WriteByaml(BinaryDataWriter bw) { string magic = (BOM == ByteOrder.BigEndian || (BOM == ByteOrder.System && !BitConverter.IsLittleEndian)) ? "BY" : "YB"; bw.Write(Encoding.ASCII.GetBytes(magic)); bw.Write(ByamlVersion); bw.Write(0x10); GenerateStringLists(); long tempStrTableOff = bw.Position; bw.Write(0); //temp long tempRootNodeOff = bw.Position; bw.Write(0); //temp ByamlParser.WriteStringList(NameTable, bw); long tempPos = bw.Position; using (bw.TemporarySeek(tempStrTableOff, SeekOrigin.Begin)) bw.Write((int)tempPos); ByamlParser.WriteStringList(Stringtable, bw); tempPos = bw.Position; using (bw.TemporarySeek(tempRootNodeOff, SeekOrigin.Begin)) bw.Write((int)tempPos); if (RootNode.NodeType == ByamlNodeType.Array) { ByamlParser.WriteArray(this, RootNode, bw); } else if (RootNode.NodeType == ByamlNodeType.Dictionary) { ByamlParser.WriteDictionary(this, RootNode, bw); } }
//write byaml public static void WriteStringList(List <string> list, BinaryDataWriter bw) { long startPos = bw.Position; bw.Write((byte)ByamlNodeType.StringTable); bw.WriteInt24(list.Count); bw.Write(new byte[4 * (list.Count + 1)]); //temp long tempPos; for (int i = 0; i < list.Count; i++) { tempPos = bw.Position; using (bw.TemporarySeek(startPos + 4 + i * 4, SeekOrigin.Begin)) bw.Write((int)(tempPos - startPos)); bw.Write(Encoding.UTF8.GetBytes(list[i] + "\0")); } tempPos = bw.Position; using (bw.TemporarySeek(startPos + 4 + list.Count * 4, SeekOrigin.Begin)) bw.Write((int)(tempPos - startPos)); bw.Align(4); }
public static void WriteDictionary(ByamlContext ctx, ByamlEntry entry, BinaryDataWriter bw) { var dict = (Dictionary <string, ByamlEntry>)entry.Value; bw.Write((byte)entry.NodeType); bw.WriteInt24(dict.Count); List <long> tempOffs = new List <long>(); //value foreach (var item in dict) { bw.WriteInt24(Array.IndexOf(ctx.NameTable.ToArray(), item.Key)); bw.Write((byte)item.Value.NodeType); if (NodeIsValue(item.Value.NodeType)) { WriteValue(ctx, item.Value, bw); } else { tempOffs.Add(bw.Position); bw.Write(0); //temp } } //array/dictionary int index = 0; foreach (var item in dict) { if (!NodeIsValue(item.Value.NodeType)) { long curPos = bw.Position; using (bw.TemporarySeek(tempOffs[index++], SeekOrigin.Begin)) bw.Write((int)curPos); if (item.Value.NodeType == ByamlNodeType.Array) { WriteArray(ctx, item.Value, bw); } else if (item.Value.NodeType == ByamlNodeType.Dictionary) { WriteDictionary(ctx, item.Value, bw); } } } }
internal void WriteChildren(BinaryDataWriter writer, ref int branchKey) { if (Children != null) { using (writer.TemporarySeek(keyPos, System.IO.SeekOrigin.Begin)) { writer.Write(branchKey); branchKey += 8; } foreach (ModelOctreeNode child in Children) { child.Write(writer, branchKey); } //Reset the branch offfset to 8 for new children int childBranchKey = 8; foreach (ModelOctreeNode child in Children) { child.WriteChildren(writer, ref childBranchKey); } } }
public void Write(Stream stream) { BinaryDataWriter writer = new BinaryDataWriter(stream, Encoding.ASCII) { ByteOrder = ByteOrder.BigEndian }; // order by id so that code works entries = entries.OrderBy(x => x.Key).ToDictionary(pair => pair.Key, pair => pair.Value); // MSBT header writer.WriteString("MsgStdBn"); // magic writer.WriteObject(endianness); // bom writer.WriteUInt16(0); // padding writer.WriteUInt16(0x0103); // magic shit writer.ByteOrder = endianness; // don't ask why i set it here writer.WriteUInt16(3); // only support 3 sections rn writer.WriteUInt16(0); // padding long filesizePointer = writer.Position; // saved for later writer.WriteUInt32(0); // filesize (filled in later) writer.WriteMultiple((byte)0, 10); // moar padding //LBL1 header writer.WriteString("LBL1"); long lblSizePointer = writer.Position; // to be overwritten writer.WriteUInt32(0); // size of LBL relative to after padding writer.WriteMultiple((byte)0, 8); // padding writer.WriteUInt32(1); // number of entries (we just lump every string into one entry) uint relativeOffset; long stringBytes; relativeOffset = sizeof(UInt32) * 3; // number of entries + string count + offset stringBytes = 0; writer.WriteUInt32((uint)entries.Count); writer.WriteUInt32(relativeOffset); // foreach (KeyValuePair <long, Entry> kv in entries) { long id = kv.Key; Entry entry = kv.Value; byte[] key = Encoding.ASCII.GetBytes(entry.key); long offset = relativeOffset + stringBytes; writer.Write((byte)key.Length); writer.Write(key); writer.WriteUInt32((UInt32)id); stringBytes++; stringBytes += key.Length; } SeekTask tmp; tmp = writer.TemporarySeek(lblSizePointer, SeekOrigin.Begin); writer.WriteUInt32((UInt32)stringBytes + 0x1C); tmp.Dispose(); writer.WritePadding(0xAB); writer.WriteString("ATR1"); long atrSizePointer = writer.Length; writer.WriteUInt32(0); // section size writer.WriteMultiple((UInt32)0, 2); // the magic of unknown shit writer.WriteUInt32((UInt32)entries.Count); // the entry length is variable, so i need to calculate it uint atrEntrySize = (uint)(8 + entries[0].attributes.unk7.Length); writer.WriteUInt32(atrEntrySize); foreach (KeyValuePair <long, Entry> kv in entries) { Attributes set = kv.Value.attributes ?? new Attributes(); writer.WriteObject(set.unk1); writer.WriteObject(set.unk2); writer.WriteObject(set.unk3); writer.WriteObject(set.type); writer.WriteUInt16(set.unk4); writer.WriteObject(set.unk5); writer.WriteObject(set.unk6); writer.WriteObject(set.unk7); } tmp = writer.TemporarySeek(atrSizePointer, SeekOrigin.Begin); writer.WriteUInt32((UInt32)(atrEntrySize * entries.Count) + 8); tmp.Dispose(); writer.WritePadding(0xAB); writer.WriteString("TXT2"); long txtSizePointer = writer.Length; writer.WriteUInt32(0); // section size writer.WriteMultiple((UInt32)0, 2); // unknowns writer.WriteUInt32((UInt32)entries.Count); int txtEntrySize = 4 * entries.Count; relativeOffset = sizeof(UInt32); // number of entries stringBytes = 0; foreach (KeyValuePair <long, Entry> kv in entries) { Entry entry = kv.Value; byte[] key = Encoding.Unicode.GetBytes(entry.value.ToString() + '\0'); UInt32 offset = (UInt32)(relativeOffset + (sizeof(UInt32) * entries.Count) + stringBytes); writer.WriteUInt32(offset); stringBytes += key.Length; } foreach (KeyValuePair <long, Entry> kv in entries) { Entry entry = kv.Value; byte[] key = Encoding.Unicode.GetBytes(entry.value.ToString() + '\0'); writer.WriteObject(key); } tmp = writer.TemporarySeek(txtSizePointer, SeekOrigin.Begin); writer.WriteUInt32((UInt32)(stringBytes + (sizeof(UInt32) * entries.Count) + relativeOffset)); tmp.Dispose(); writer.WritePadding(0xAB); tmp = writer.TemporarySeek(filesizePointer, SeekOrigin.Begin); writer.WriteUInt32((UInt32)(writer.Length)); tmp.Dispose(); }