static void Create(string FileName, EndianBinary.Endian Endian) { string OutFile = Path.GetFileNameWithoutExtension(FileName) + ".lang"; FileStream Output = new FileStream(OutFile, FileMode.Create); EndianBinaryWriter Writer = new EndianBinaryWriter(Output, Endian); /* * Seção String */ MemoryStream String = new MemoryStream(); EndianBinaryWriter StringWriter = new EndianBinaryWriter(String, Endian); string[] Texts = File.ReadAllText(FileName).Split(new string[] { Environment.NewLine + Environment.NewLine }, StringSplitOptions.None); List <byte[]> Buffers = new List <byte[]>(); foreach (string Text in Texts) { Buffers.Add(UTF16.GetBytes(Text, Endian)); } MemoryStream TextBlock = new MemoryStream(); foreach (byte[] Buffer in Buffers) { TextBlock.Write(Buffer, 0, Buffer.Length); TextBlock.WriteByte(0); TextBlock.WriteByte(0); //0x00 00 Null Terminator while ((TextBlock.Position & 0xf) != 0) { TextBlock.WriteByte(0); //Alinha } } StringWriter.Write(Encoding.ASCII.GetBytes("STRPACK")); StringWriter.Write(0); StringWriter.WriteLE((uint)(0x10000 | (Endian == EndianBinary.Endian.Little ? 0 : 0xff))); StringWriter.Write((uint)0x30); StringWriter.Write((uint)(0x60 + Align(Texts.Length * 4) * 2 + TextBlock.Length)); //Tamanho da seção StringWriter.Write((uint)Texts.Length); //Total de ponteiros StringWriter.Write((uint)Texts.Length); //Total de tamanhos StringWriter.Write((uint)0); //Alinha em 16 bytes StringWriter.Write((uint)0x60); //Offset relativo de inicio dos ponteiros StringWriter.Write(0x60 + Align(Texts.Length * 4)); //Offset relativo de inicio dos tamanhos StringWriter.Write((ulong)0); //Alinha em 16 bytes StringWriter.Write(Encoding.ASCII.GetBytes("string_pack")); while ((String.Position & 0xf) != 0) { String.WriteByte(0); } StringWriter.Write((uint)1); //Número de seções StringWriter.Write((uint)0x30); //Offset dos dados StringWriter.Write((ulong)0); //Alinha em 16 bytes StringWriter.Write((uint)0x54); //??? String.Seek(0xc, SeekOrigin.Current); uint DataOffset = 0x60 + Align(Texts.Length * 4) * 2; foreach (byte[] Buffer in Buffers) { StringWriter.Write(DataOffset); DataOffset += Align(Buffer.Length + 2); } while ((String.Position & 0xf) != 0) { String.WriteByte(0); } foreach (byte[] Buffer in Buffers) { StringWriter.Write((uint)Buffer.Length + 2); } while ((String.Position & 0xf) != 0) { String.WriteByte(0); } StringWriter.Write(TextBlock.ToArray()); TextBlock.Close(); /* * Seção Category */ MemoryStream Category = new MemoryStream(); EndianBinaryWriter CategoryWriter = new EndianBinaryWriter(Category, Endian); CategoryWriter.Write(Encoding.ASCII.GetBytes("CTGPACK")); CategoryWriter.Write(0); CategoryWriter.WriteLE((uint)(0x10000 | (Endian == EndianBinary.Endian.Little ? 0 : 0xff))); CategoryWriter.Write((uint)0x30); CategoryWriter.Write((uint)String.Length + 0x80); //Tamanho da seção CategoryWriter.Write((uint)1); //Total de ponteiros CategoryWriter.Write((uint)1); //Total de tamanhos CategoryWriter.Write((uint)0); //Alinha em 16 bytes CategoryWriter.Write((uint)0x60); //Offset relativo de inicio dos ponteiros CategoryWriter.Write((uint)0x70); //Offset relativo de inicio dos tamanhos CategoryWriter.Write((ulong)0); //Alinha em 16 bytes CategoryWriter.Write(Encoding.ASCII.GetBytes("category_pack")); while ((Category.Position & 0xf) != 0) { Category.WriteByte(0); } CategoryWriter.Write((uint)1); //Número de seções CategoryWriter.Write((uint)0x30); //Offset dos dados CategoryWriter.Write((ulong)0); //Alinha em 16 bytes Category.Seek(0xc, SeekOrigin.Current); if (Endian == EndianBinary.Endian.Little) { CategoryWriter.Write(0x18fc2c); //??? } else { CategoryWriter.Write((uint)0); } CategoryWriter.Write((uint)0x80); //Offset relativo onde se inicia a outra seção Category.Seek(0xc, SeekOrigin.Current); CategoryWriter.Write((uint)String.Length); //Tamanho da outra seção Category.Seek(0xc, SeekOrigin.Current); CategoryWriter.Write(String.ToArray()); String.Close(); /* * Seção Lang */ Writer.Write(Encoding.ASCII.GetBytes("LANG")); Writer.Write((uint)0); Writer.WriteLE((uint)(0x10000 | (Endian == EndianBinary.Endian.Little ? 0 : 0xff))); Writer.Write((uint)0x30); Writer.Write((uint)Category.Length + 0x80); //Tamanho da seção Writer.Write((uint)1); //Total de ponteiros Writer.Write((uint)1); //Total de tamanhos Writer.Write((uint)0); //Alinha em 16 bytes Writer.Write((uint)0x60); //Offset relativo de inicio dos ponteiros Writer.Write((uint)0x70); //Offset relativo de inicio dos tamanhos Writer.Write((ulong)0); //Alinha em 16 bytes Writer.Write(Encoding.ASCII.GetBytes("language_pack")); while ((Output.Position & 0xf) != 0) { Output.WriteByte(0); } Writer.Write((uint)1); //Número de seções Writer.Write((uint)0x30); //Offset dos dados Writer.Write((ulong)0); //Alinha em 16 bytes Output.Seek(0x10, SeekOrigin.Current); Writer.Write((uint)0x80); //Offset relativo onde se inicia a outra seção Output.Seek(0xc, SeekOrigin.Current); Writer.Write((uint)Category.Length); //Tamanho da outra seção Output.Seek(0xc, SeekOrigin.Current); Writer.Write(Category.ToArray()); Category.Close(); Output.Close(); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Created " + Path.GetFileName(OutFile) + "!"); Console.ResetColor(); }