예제 #1
0
 private string WriteAnimationDataNameChunk(string particle, BinaryWriter w)
 {
     w.Write(particle);
     w.Write((byte)0);
     w.Align(8);
     return("ANM\x01");
 }
예제 #2
0
        public void WriteToBinary(Stream stream)
        {
            var writer = new BinaryWriter(stream);

            //Write 56 byte zone object header
            writer.Write(ClassnameHash);
            writer.Write(Handle);
            writer.Write(Bmin);
            writer.Write(Bmax);
            writer.Write((ushort)Flags);
            writer.Write(BlockSize);
            writer.Write(Parent);
            writer.Write(Sibling);
            writer.Write(Child);
            writer.Write(Num);
            writer.Write(NumProps);
            writer.Write(Size);

            //Write properties
            foreach (var property in Properties)
            {
                property.WriteToStream(stream);
                writer.Align(4);
            }
        }
예제 #3
0
 public void Pack(BinaryWriter writer)
 {
     writer.Write(QwCookie);
     Addr.Pack(writer);
     writer.Write(IdServer);
     writer.Align();
 }
예제 #4
0
        // todo: render object network code
        public void Serialize(BinaryWriter writer)
        {
            writer.Write((byte)0x11);
            writer.Write((byte)modelPalettes.Count);
            writer.Write((byte)modelTextures.Count);
            writer.Write((byte)models.Count);

            if (modelPalettes.Count > 0)
            {
                writer.WritePackedDwordOfKnownType(PaletteGuid, 0x4000000);
            }
            foreach (ModelPalette palette in modelPalettes)
            {
                writer.WritePackedDwordOfKnownType(palette.PaletteId, 0x4000000);
                writer.Write((byte)palette.Offset);
                writer.Write((byte)palette.Length);
            }

            foreach (ModelTexture texture in modelTextures)
            {
                writer.Write((byte)texture.Index);
                writer.WritePackedDwordOfKnownType(texture.OldTexture, 0x5000000);
                writer.WritePackedDwordOfKnownType(texture.NewTexture, 0x5000000);
            }

            foreach (Model model in models)
            {
                writer.Write((byte)model.Index);
                writer.WritePackedDwordOfKnownType(model.ModelID, 0x1000000);
            }

            writer.Align();
        }
예제 #5
0
        public void Write(Stream outputStream)
        {
            BinaryWriter writer = new BinaryWriter(outputStream, Encoding.ASCII, true);

            BaseOffset = Convert.ToUInt32(writer.BaseStream.Position);

            writer.BaseStream.Position += IndexBlockSize;
            foreach (var chunk in Chunks)
            {
                chunk.UpdateDataOffset(outputStream, baseOffset: BaseOffset, isSingleChunk: Chunks.Count() == 1);
                chunk.WriteData(outputStream);
            }

            Alignment = writer.Align(16);
            // TODO: Write the next chunk info(s) (for streaming?)
            writer.WriteZeros(8);

            long endPosition = writer.BaseStream.Position;

            writer.BaseStream.Position = BaseOffset;
            foreach (var chunk in Chunks)
            {
                chunk.WriteIndex(writer);
            }

            writer.BaseStream.Position = endPosition;
        }
 public override void Pack(BinaryWriter writer)
 {
     writer.Write(Sequence);
     writer.Write((uint)Key);
     writer.Align();
     writer.WriteString16L(Value);
 }
예제 #7
0
        //todo: render object network code
        public void Serialize(BinaryWriter writer)
        {
            writer.Write((byte)0x11);
            writer.Write((byte)modelPalletes.Count);
            writer.Write((byte)modelTextures.Count);
            writer.Write((byte)models.Count);

            foreach (ModelPallete pallet in modelPalletes)
            {
                writer.Write((ushort)pallet.PaletteID);
                writer.Write((byte)pallet.Offset);
                writer.Write((byte)pallet.Length);
            }

            foreach (ModelTexture texture in modelTextures)
            {
                writer.Write((byte)texture.Index);
                writer.Write((ushort)texture.OldTexture);
                writer.Write((ushort)texture.NewTexture);
            }

            foreach (Model model in models)
            {
                writer.Write((ushort)model.ModelID);
                writer.Write((byte)model.Index);
            }

            writer.Align();
        }
예제 #8
0
        private void WriteStringFileInfo(BinaryWriter writer, VersionResource resource)
        {
            foreach (var value in resource.StringFileInfo)
            {
                var languageIdentifier = value.Language;
                var codePage           = (ushort)value.Encoding.CodePage;

                var key = (uint)languageIdentifier << 4 | codePage;

                WriteHeader(writer, value.Size, 0, VersionDataType.Text, key.ToString("x8"));

                foreach (var pair in value.Values)
                {
                    long valueLength = Encoding.Unicode.GetByteCount(pair.Value + '\0');
                    long keyLength   = Encoding.Unicode.GetByteCount(pair.Key + '\0');

                    long length = Marshal.SizeOf(typeof(VersionHeader));
                    length += keyLength;
                    length  = Helpers.Align(length);
                    length += valueLength;
                    length  = Helpers.Align(length);

                    WriteHeader(writer, length, valueLength / sizeof(short), VersionDataType.Text, pair.Key);
                    writer.WriteUnicodeString(pair.Value);
                    writer.Align();
                }
            }
        }
예제 #9
0
 public void Pack(BinaryWriter writer)
 {
     writer.Write(Gid);
     writer.WriteString16L(Name);
     writer.Write(SecondsGreyedOut);
     writer.Align();
 }
예제 #10
0
        public static int WriteNullTerminatedString(this BinaryWriter writer, string value)
        {
            writer.Align();
            var position = (int)writer.BaseStream.Position;

            writer.Write(UTF8.GetBytes(value + '\0'));
            return(position);
        }
예제 #11
0
        public void SerializeGenericList(BinaryWriter writer, IList list, long listHeaderPosition, ref List <Tuple <long, object> > additionalData, int addtDataIndex)
        {
            long listPosition = writer.BaseStream.Position;

            if (PrintToDebug)
            {
                Debug.WriteLine($"SerializeList start 0x{listPosition:X}, header 0x{listHeaderPosition:X}");
            }

            writer.BaseStream.Position = listHeaderPosition;

            // write the list header into the template
            if (list.Count > 0)
            {
                writer.Write(listPosition - listHeaderPosition);
            }
            else
            {
                writer.Write((long)0); // lists with 0 entries have offset set to 0
            }
            writer.Write((Int32)list.Count);
            writer.Write((UInt32)0xAAAAAA01);

            // reserve space for list offsets+names
            writer.BaseStream.Position = listPosition;
            writer.Write(new byte[list.Count * 0x48]);
            writer.Align(0x10, 0); // why

            int addtDataIndexThis = addtDataIndex;

            var entryOffsetNamePairs = new Dictionary <long, string>();

            foreach (var entry in list)
            {
                entryOffsetNamePairs.Add(writer.BaseStream.Position, entry.GetType().Name);
                var template = (NMSTemplate)entry;
                var addtData = new Dictionary <long, object>();
                if (PrintToDebug)
                {
                    Debug.WriteLine($"[C] writing {template.GetType().Name} to offset 0x{writer.BaseStream.Position:X}");
                }
                template.AppendToWriter(writer, ref additionalData, ref addtDataIndexThis, GetType());
            }

            long dataEndOffset = writer.BaseStream.Position;

            writer.BaseStream.Position = listPosition;
            foreach (var entry in entryOffsetNamePairs)
            {
                var position = writer.BaseStream.Position;
                var offset   = entry.Key - position; // get offset of this entry from the current offset
                writer.Write(offset);
                writer.WriteString("c" + entry.Value, Encoding.UTF8, 0x40);
            }

            writer.BaseStream.Position = dataEndOffset;
        }
예제 #12
0
 public void Pack(BinaryWriter writer)
 {
     Position.Pack(writer);
     writer.Write(ObjectInstanceSequence);
     writer.Write(ObjectServerControlSequence);
     writer.Write(ObjectTeleportSequence);
     writer.Write(ObjectForcePositionSequence);
     writer.Write(Contact);
     writer.Align();
 }
예제 #13
0
 public void Pack(BinaryWriter writer)
 {
     writer.Write(Extent);
     Velocity.Pack(writer);
     writer.Write(ObjectInstanceSequence);
     writer.Write(ObjectServerControlSequence);
     writer.Write(ObjectTeleportSequence);
     writer.Write(ObjectForcePositionSequence);
     writer.Align();
 }
예제 #14
0
        public static void Write(this BinaryWriter writer, InterpretedMotionState state)
        {
            var numCommands = state.Commands != null ? state.Commands.Count : 0;

            writer.Write((uint)state.Flags | (uint)numCommands << 7);

            // for MotionStance / MotionCommand, write as ushort
            if ((state.Flags & MovementStateFlag.CurrentStyle) != 0)
            {
                writer.Write((ushort)state.CurrentStyle);
            }

            if ((state.Flags & MovementStateFlag.ForwardCommand) != 0)
            {
                writer.Write((ushort)state.ForwardCommand);
            }

            if ((state.Flags & MovementStateFlag.SideStepCommand) != 0)
            {
                writer.Write((ushort)state.SidestepCommand);
            }

            if ((state.Flags & MovementStateFlag.TurnCommand) != 0)
            {
                writer.Write((ushort)state.TurnCommand);
            }

            if ((state.Flags & MovementStateFlag.ForwardSpeed) != 0)
            {
                writer.Write(state.ForwardSpeed);
            }

            if ((state.Flags & MovementStateFlag.SideStepSpeed) != 0)
            {
                writer.Write(state.SidestepSpeed);
            }

            if ((state.Flags & MovementStateFlag.TurnSpeed) != 0)
            {
                writer.Write(state.TurnSpeed);
            }

            if (numCommands > 0)
            {
                foreach (var motion in state.Commands)
                {
                    writer.Write(motion);
                }
            }

            // align to DWORD boundary
            writer.Align();
        }
예제 #15
0
        private void WriteHeader(BinaryWriter writer, long length, long valueLength, VersionDataType binary, string key)
        {
            var header = new VersionHeader
            {
                Length      = (ushort)length,
                ValueLength = (ushort)valueLength,
                Type        = binary
            };

            writer.WriteStruct(header);
            writer.WriteUnicodeString(key);
            writer.Align();
        }
예제 #16
0
 public override void Pack(BinaryWriter writer)
 {
     writer.Write((uint)ResponseType);
     switch (ResponseType)
     {
     case CharGenResponseType.OK:
         writer.Write(Gid);
         writer.WriteString16L(Name);
         writer.Write(SecondsGreyedOut);
         writer.Align();
         break;
     }
 }
예제 #17
0
        private string WriteParticlesGroupChunk(List <ParticlesGroup> groups, BinaryWriter w)
        {
            w.Write((ushort)groups.Count);
            w.Write((ushort)0);
            w.Write((int)0);
            w.Align(8);

            foreach (var item in groups)
            {
                WriteParticlesGroup(item, w);
            }

            return("PAG\x01");
        }
예제 #18
0
        public static void Write(this BinaryWriter writer, MovementData motion, bool header = true)
        {
            var wo       = motion.WorldObject;
            var sequence = wo.Sequences;

            if (header)
            {
                writer.Write(sequence.GetNextSequence(SequenceType.ObjectMovement));

                if (motion.IsAutonomous)
                {
                    writer.Write(sequence.GetCurrentSequence(SequenceType.ObjectServerControl));
                }
                else
                {
                    writer.Write(sequence.GetNextSequence(SequenceType.ObjectServerControl));
                }

                writer.Write(Convert.ToByte(motion.IsAutonomous));
                writer.Align();
            }

            writer.Write((byte)motion.MovementType);
            writer.Write((byte)motion.MotionFlags);

            writer.Write((ushort)motion.CurrentStyle);    // send MotionStance as ushort

            switch (motion.MovementType)
            {
            case MovementType.Invalid:
                writer.Write(motion.Invalid);
                break;

            case MovementType.MoveToObject:
                writer.Write(motion.MoveToObject);
                break;

            case MovementType.MoveToPosition:
                writer.Write(motion.MoveToPosition);
                break;

            case MovementType.TurnToObject:
                writer.Write(motion.TurnToObject);
                break;

            case MovementType.TurnToHeading:
                writer.Write(motion.TurnToHeading);
                break;
            }
        }
예제 #19
0
 private void WriteParticleEffect(Effect effect, BinaryWriter w)
 {
     w.Write((byte)effect.Ease);
     w.Write((byte)effect.Parameter);
     w.Write((byte)0);
     w.Write((byte)0);
     w.Write(ProcessValue(effect.Speed));
     w.Write(ProcessValue(effect.FixStep));
     w.Write(ProcessValue(effect.Sum));
     w.Write(ProcessValue(effect.Multiplier));
     w.Write(ProcessValue(effect.Delay));
     w.Write(ProcessValue(effect.Duration));
     w.Align(8);
 }
예제 #20
0
        private void WriteEntryData(BinaryWriter gpuFile, List <byte[]> rawDatas)
        {
            int  index  = 0;
            uint offset = 0;

            foreach (var entry in Entries)
            {
                var rawData = rawDatas[index];
                if (entry.Edited)
                {
                    if (entry.bitmap_format == PegFormat.PC_DXT1)
                    {
                        var compressBuffer = Squish.Compress(rawData, entry.width, entry.height, Squish.Flags.DXT1);
                        gpuFile.Write(compressBuffer);
                        entry.frame_size = (uint)compressBuffer.Length;
                    }
                    else if (entry.bitmap_format == PegFormat.PC_DXT3)
                    {
                        var compressBuffer = Squish.Compress(rawData, entry.width, entry.height, Squish.Flags.DXT3);
                        gpuFile.Write(compressBuffer);
                        entry.frame_size = (uint)compressBuffer.Length;
                    }
                    else if (entry.bitmap_format == PegFormat.PC_DXT5)
                    {
                        var compressBuffer = Squish.Compress(rawData, entry.width, entry.height, Squish.Flags.DXT5);
                        gpuFile.Write(compressBuffer);
                        entry.frame_size = (uint)compressBuffer.Length;
                    }
                    else
                    {
                        throw new Exception($"Unsupported PEG data format detected! {entry.bitmap_format.ToString()} is not yet supported.");
                    }
                }
                else
                {
                    gpuFile.Write(rawData);
                    entry.frame_size = (uint)rawData.Length;
                    entry.data       = offset;
                }
                //Align to alignment value
                gpuFile.Align(AlignValue);
                //Update offset to start of next entry
                offset = (uint)gpuFile.BaseStream.Position;
                index++;
            }
        }
예제 #21
0
        /// <summary>
        /// Writes a <see cref="VersionResource"/> object to the current <see cref="Stream"/>.
        /// </summary>
        /// <param name="resource">
        /// The <see cref="VersionResource"/> to write.
        /// </param>
        public void Write(VersionResource resource)
        {
            if (resource == null)
            {
                throw new ArgumentNullException(nameof(resource));
            }

            if (Stream.Length < resource.Size)
            {
                Stream.SetLength(resource.Size);
            }

            using (var stream = new SubStream(Stream, 0, Stream.Length, leaveParentOpen: true))
                using (var writer = new BinaryWriter(stream, Encoding.Unicode))
                {
                    // Write the version resource header
                    WriteHeader(
                        writer,
                        resource.Size,
                        resource.FixedFileInfo == null ? 0 : Marshal.SizeOf(typeof(VS_FIXEDFILEINFO)),
                        VersionDataType.Binary,
                        "VS_VERSION_INFO");

                    if (resource.FixedFileInfo != null)
                    {
                        writer.WriteStruct(resource.FixedFileInfo.Value);
                    }

                    writer.Align();

                    if (resource.VarFileInfo != null)
                    {
                        WriteHeader(writer, resource.VarFileInfoSize, 0, VersionDataType.Text, "VarFileInfo");

                        WriteVarFileInfo(writer, resource);
                    }

                    if (resource.StringFileInfo != null)
                    {
                        WriteHeader(writer, resource.StringFileInfoSize, 0, VersionDataType.Text, "StringFileInfo");

                        WriteStringFileInfo(writer, resource);
                    }
                }
        }
예제 #22
0
        // variableName should be parameter2
        // instruction count should be 19 instead of 20
        private Stream Get19SimpleInstructions(string variableName, string wrongValue, string rightValue, int afterInstructionPosition)
        {
            var instructionStream = new MemoryStream();

            using (var instructionWriter = new BinaryWriter(instructionStream, UTF8, true))
            {
                var variableNamePosition = instructionWriter.WriteNullTerminatedString(variableName);
                var wrongValuePosition   = instructionWriter.WriteNullTerminatedString(wrongValue);
                var rightValuePosition   = instructionWriter.WriteNullTerminatedString(rightValue);

                instructionWriter.Align();
                var instructionOffset = (uint)instructionStream.Position;
                instructionWriter.WriteSimpleInstruction(InstructionType.EA_PushOne);
                instructionWriter.WriteSimpleInstruction(InstructionType.EA_PushZero);
                instructionWriter.WriteSimpleInstruction(InstructionType.Add2);
                instructionWriter.WriteSimpleInstruction(InstructionType.BranchIfTrue, 18);
                instructionWriter.WriteSimpleInstruction(InstructionType.EA_PushString, variableNamePosition);
                instructionWriter.WriteSimpleInstruction(InstructionType.EA_PushString, wrongValuePosition);
                instructionWriter.WriteSimpleInstruction(InstructionType.SetVariable);
                instructionWriter.WriteSimpleInstruction(InstructionType.End);
                instructionWriter.WriteSimpleInstruction(InstructionType.EA_PushOne);
                instructionWriter.WriteSimpleInstruction(InstructionType.Not);
                instructionWriter.WriteSimpleInstruction(InstructionType.BranchIfTrue, 18);
                instructionWriter.WriteSimpleInstruction(InstructionType.EA_PushString, variableNamePosition);
                instructionWriter.WriteSimpleInstruction(InstructionType.EA_PushString, rightValuePosition);
                instructionWriter.WriteSimpleInstruction(InstructionType.SetVariable);
                instructionWriter.WriteSimpleInstruction(InstructionType.End);
                instructionWriter.WriteSimpleInstruction(InstructionType.EA_PushString, variableNamePosition);
                instructionWriter.WriteSimpleInstruction(InstructionType.EA_PushString, wrongValuePosition);
                instructionWriter.WriteSimpleInstruction(InstructionType.SetVariable);
                instructionWriter.WriteSimpleInstruction(InstructionType.End);

                // pathological case
                instructionWriter.WriteSimpleInstruction(InstructionType.BranchIfTrue, -79);

                var instructionOffsetPosition = (int)instructionStream.Position;
                instructionWriter.Write(instructionOffset);
                instructionWriter.Write(afterInstructionPosition);
                instructionWriter.Write("DummyData");

                instructionWriter.Seek(instructionOffsetPosition, SeekOrigin.Begin);
            }
            return(instructionStream);
        }
예제 #23
0
        public void Pack(BinaryWriter writer)
        {
            writer.Write(ObjectMovementSequence);
            writer.Write(ObjectServerControlSequence);
            writer.Write(Autonomous);
            writer.Align();
            writer.Write((byte)MovementType);
            writer.Write((byte)OptionFlags);
            writer.Write((ushort)Stance);
            switch (MovementType)
            {
            case MovementType.InterpertedMotionState:
                State.Pack(writer);
                if ((OptionFlags & MovementOption.StickToObject) != 0)
                {
                    writer.Write(StickyObject);
                }
                break;

            case MovementType.MoveToObject:
                writer.Write(Target);
                Origin.Pack(writer);
                MoveToParameters.Pack(writer);
                writer.Write(MyRunRate);
                break;

            case MovementType.MoveToPosition:
                Origin.Pack(writer);
                MoveToParameters.Pack(writer);
                writer.Write(MyRunRate);
                break;

            case MovementType.TurnToObject:
                writer.Write(Target);
                writer.Write(DesiredHeading);
                TurnToParameters.Pack(writer);
                break;

            case MovementType.TurnToPosition:
                TurnToParameters.Pack(writer);
                break;
            }
        }
예제 #24
0
        public void Pack(BinaryWriter writer)
        {
            uint Flags = 0;

            Flags |= (uint)(MaskFlags & 0x7F);
            Flags |= (uint)(CommandListLength & 0x7F << 7);
            writer.Write(Flags);
            if ((MaskFlags & 0x00000001) != 0)
            {
                writer.Write((ushort)CurrentStyle);
            }
            if ((MaskFlags & 0x00000002) != 0)
            {
                writer.Write((ushort)ForwardCommand);
            }
            if ((MaskFlags & 0x00000008) != 0)
            {
                writer.Write((ushort)SidestepCommand);
            }
            if ((MaskFlags & 0x00000020) != 0)
            {
                writer.Write((ushort)TurnCommand);
            }
            if ((MaskFlags & 0x00000004) != 0)
            {
                writer.Write(ForwardSpeed);
            }
            if ((MaskFlags & 0x00000010) != 0)
            {
                writer.Write(SidestepSpeed);
            }
            if ((MaskFlags & 0x00000040) != 0)
            {
                writer.Write(TurnSpeed);
            }
            for (int i = 0; i < CommandListLength; i++)
            {
                Commands[i].Pack(writer);
            }
            writer.Align();
        }
예제 #25
0
        public override bool CustomSerialize(BinaryWriter writer, Type field, object fieldData, NMSAttribute settings, FieldInfo fieldInfo, ref List <Tuple <long, object> > additionalData, ref int addtDataIndex)
        {
            var fieldName = fieldInfo.Name;

            switch (fieldName)
            {
            case nameof(MeshDataStream):
                writer.Align(8, fieldName);

                // write empty list header
                long listPos = writer.BaseStream.Position;
                writer.Write((Int64)0);                             // listPosition
                writer.Write((Int32)(MeshDataStream?.Length ?? 0)); // size of data chunk in bytes
                writer.Write((UInt32)0xFEFEFE01);

                additionalData.Insert(addtDataIndex, new Tuple <long, object>(listPos, fieldData));
                addtDataIndex++;
                return(true);
            }
            return(false);
        }
예제 #26
0
        private static string WriteStrings(List <string> list, string name, BinaryWriter w)
        {
            var index  = 0;
            var offset = sizeof(int) + list.Count * sizeof(ushort);

            w.Write(list.Count);
            foreach (var item in list)
            {
                var data = System.Text.Encoding.UTF8.GetBytes(item);

                w.BaseStream.Position = sizeof(int) + index++ *sizeof(ushort);
                w.Write((ushort)offset);
                w.BaseStream.Position = offset;
                w.Write(data);
                w.Write((byte)0);
                offset += data.Length + 1;
            }

            w.Align(8);

            return(name);
        }
        /// <inheritdoc />
        public override void Assemble(BinaryWriter writer)
        {
            // CONTRACT: ObjectFile

            // TODO: Emit .bss after the last progbits section.

            // Create a new context.
            Context context = this.ObjectFile.Architecture.CreateContext(this.ObjectFile);

            // Construct each section.
            context.Reset();
            context.Address = 0;                        // Addresses relative to file.
            foreach (Section section in this.ObjectFile.Sections)
            {
                context.Section = section;
                string sectionName = String.Format("section.{0}.start", section.Identifier);
                var    symbol      = new Symbol(SymbolType.Private, sectionName);
                symbol.Define(context, context.Address);

                section.Construct(context);
            }

            // Emit each section and write it directly to the writer.
            context.Reset();
            context.Address = 0;                        // Addresses relative to file.
            foreach (Section section in this.ObjectFile.Sections)
            {
                MathExt.CalculatePadding(writer.BaseStream.Position, section.Alignment);
                writer.Align(section.Alignment);
                section.Emit(writer, context);
            }

            // Test for illegal symbols.
            CheckSymbolSupport(context);

            writer.Flush();
        }
예제 #28
0
        private void WriteParticlesGroup(ParticlesGroup group, BinaryWriter w)
        {
            int effectsCount = group.Effects.Count;

            if (effectsCount > byte.MaxValue)
            {
                Log.Warning($"A group exceed the maximum effects count: {byte.MaxValue} effects will be exported instead of {effectsCount}.");
                effectsCount = byte.MaxValue;
            }

            w.Write(group.AnimationName.GetXeHash());
            w.Write((byte)group.ParticlesCount);
            w.Write((byte)effectsCount);
            w.Write(ProcessValue(group.GlobalDelay));
            w.Write(ProcessValue(group.GlobalDuration));
            w.Write(ProcessValue(group.Delay));
            w.Align(8);

            for (int i = 0; i < effectsCount; i++)
            {
                var item = group.Effects[i];
                WriteParticleEffect(item, w);
            }
        }
예제 #29
0
 public void Pack(BinaryWriter writer)
 {
     writer.Write((byte)0x11); // Unused value
     writer.Write(PaletteCount);
     writer.Write(TextureCount);
     writer.Write(ModelCount);
     if (PaletteCount > 0)
     {
         writer.WriteUIntCompressed16(Palette);
         for (int i = 0; i < PaletteCount; i++)
         {
             Subpalettes[i].Pack(writer);
         }
     }
     for (int i = 0; i < TextureCount; i++)
     {
         TmChanges[i].Pack(writer);
     }
     for (int i = 0; i < ModelCount; i++)
     {
         ApChanges[i].Pack(writer);
     }
     writer.Align();
 }
예제 #30
0
        public byte[] SerializeBytes()
        {
            using (var stream = new MemoryStream())
                using (var writer = new BinaryWriter(stream, Encoding.ASCII))
                {
                    var additionalData = new List <Tuple <long, object> >();

                    // write primary template + any embedded templates
                    AppendToWriter(writer, ref additionalData);

                    // now write values of lists etc
                    for (int i = 0; i < additionalData.Count; i++)
                    {
                        var data = additionalData[i];
                        //writer.BaseStream.Position = additionalDataOffset; // addtDataOffset gets updated by child templates
                        writer.Align(0x8, 0); // todo: check if this alignment is correct

                        if (data.Item2.GetType() == typeof(VariableSizeString))
                        {
                            var str = (VariableSizeString)data.Item2;

                            var stringPos = writer.BaseStream.Position;
                            writer.WriteString(str.Value, Encoding.UTF8);
                            var stringEndPos = writer.BaseStream.Position;

                            writer.BaseStream.Position = data.Item1;
                            writer.Write(stringPos - data.Item1);
                            writer.Write((Int32)str.Value.Length);
                            writer.Write((UInt32)0xAAAAAA01);

                            writer.BaseStream.Position = stringEndPos;
                        }
                        else if (data.Item2.GetType().BaseType == typeof(NMSTemplate))
                        {
                            var pos      = writer.BaseStream.Position;
                            var template = (NMSTemplate)data.Item2;
                            template.AppendToWriter(writer, ref additionalData);
                            var endPos = writer.BaseStream.Position;
                            writer.BaseStream.Position = data.Item1;
                            writer.Write(pos - data.Item1);
                            writer.WriteString(template.GetType().Name, Encoding.UTF8, 0x40);
                            writer.BaseStream.Position = endPos;
                        }
                        else if (data.Item2.GetType().IsGenericType&& data.Item2.GetType().GetGenericTypeDefinition() == typeof(List <>))
                        {
                            Type itemType = data.Item2.GetType().GetGenericArguments()[0];
                            if (itemType == typeof(NMSTemplate))
                            {
                                SerializeGenericList(writer, (IList)data.Item2, data.Item1, ref additionalData);
                            }
                            else
                            {
                                SerializeList(writer, (IList)data.Item2, data.Item1, ref additionalData);
                            }
                        }
                        else
                        {
                            throw new Exception($"[C] Unknown type {data.Item2.GetType()} in additionalData list!");
                        }
                    }

                    return(stream.ToArray());
                }
        }