Пример #1
0
        public void Import(GenericKeyValue root)
        {
            this.Data        = new MemoryStream();
            this.FileVersion = 0;

            long newOffset = this.Structures[0].DataSize;

            this.ImportStructure(this.Structures[0], root, 0, ref newOffset, new ImportState());
        }
Пример #2
0
        private void ImportStructure(GFF.StructureDefinition def, GenericKeyValue data, long offset, ref long newOffset, ImportState state)
        {
            foreach (var fieldDef in def.Fields)
            {
                if (fieldDef.Id == 16208)
                {
                }

                GenericKeyValue value;
                if (data.Values.ContainsKey(fieldDef.Id) == false)
                {
                    //throw new InvalidOperationException();
                    value = new GenericKeyValue(fieldDef.Type, null);
                }
                else
                {
                    value = data[fieldDef.Id];
                }
                this.ImportField(fieldDef, value, offset, ref newOffset, state);
            }
        }
Пример #3
0
        private GenericKeyValue ExportStructure(GFF.StructureDefinition def, long offset, ExportState state)
        {
            var kv = new GenericKeyValue(GFF.FieldType.Structure, null);

            kv.StructureId = def.Id;

            foreach (var fieldDef in def.Fields)
            {
                var value = this.ExportField(fieldDef, offset, state);

                if (value is GenericKeyValue)
                {
                    kv[fieldDef.Id] = (GenericKeyValue)value;
                }
                else
                {
                    kv[fieldDef.Id] = new GenericKeyValue(fieldDef.Type, value);
                }
            }
            return(kv);
        }
Пример #4
0
        private void ImportField(GFF.FieldDefinition def, GenericKeyValue data, long offset, ref long newOffset, ImportState state)
        {
            var endian = this.Endian;

            var output = this.Data;

            output.Seek(offset + def.Offset, SeekOrigin.Begin);

            if (def.IsList == true)
            {
                if (def.IsReference == true &&
                    (data.Value != null || def.Type != GFF.FieldType.Generic))
                {
                    throw new NotSupportedException();
                }

                var list = (IList)data.Value;
                if (list == null)
                {
                    output.WriteValueU32(0xFFFFFFFF, endian);
                }
                else
                {
                    output.WriteValueU32((uint)newOffset, endian);

                    output.Seek(newOffset, SeekOrigin.Begin);
                    output.WriteValueS32(list.Count, endian);
                    newOffset += 4;

                    uint itemSize;
                    if (def.Type == GFF.FieldType.Structure)
                    {
                        var subdef = this.Structures[def.StructureId];
                        itemSize = subdef.DataSize;
                    }
                    else
                    {
                        itemSize = GFF.Builtin.SizeOf(def.Type);
                    }

                    newOffset += list.Count * itemSize;

                    switch (def.Type)
                    {
                    case GFF.FieldType.String:
                    {
                        throw new NotImplementedException();
                    }

                    case GFF.FieldType.Structure:
                    {
                        var subdef = this.Structures[def.StructureId];

                        long itemOffset = output.Position;
                        foreach (var item in list)
                        {
                            this.ImportStructure(
                                subdef,
                                (GenericKeyValue)item,
                                itemOffset,
                                ref newOffset,
                                state);
                            itemOffset += itemSize;
                        }

                        break;
                    }

                    default:
                    {
                        if (def.Type == GFF.FieldType.UInt8 &&
                            list.GetType() == typeof(byte[]))
                        {
                            var bytes = (byte[])list;
                            output.Write(bytes, 0, bytes.Length);
                        }
                        else
                        {
                            long itemOffset = output.Position;
                            foreach (var item in list)
                            {
                                GFF.Builtin.Serialize(output, def.Type, item, endian);
                                itemOffset += itemSize;
                            }
                        }

                        break;
                    }
                    }
                }
            }
            else
            {
                if (def.IsReference == true &&
                    def.Type != GFF.FieldType.Structure)
                {
                    throw new NotSupportedException();
                }

                switch (def.Type)
                {
                case GFF.FieldType.String:
                {
                    var s = data.As <string>();

                    if (s == null || s.Length == 0)
                    {
                        output.WriteValueU32(0xFFFFFFFF, endian);
                    }
                    else
                    {
                        var length = s.Length + 1;

                        output.WriteValueU32((uint)newOffset, endian);

                        output.Seek(newOffset, SeekOrigin.Begin);
                        output.WriteValueS32(length, endian);
                        output.WriteString(s, endian == Endian.Little ? Encoding.Unicode : Encoding.BigEndianUnicode);
                        output.WriteValueU16(0, endian);
                        newOffset += 4 + (2 * length);
                    }

                    break;
                }

                case GFF.FieldType.TalkString:
                {
                    var s = data.As <GFF.Builtins.TalkString>();
                    output.WriteValueU32(s.Id, endian);

                    if (s.String == null)
                    {
                        output.WriteValueU32(0xFFFFFFFF, endian);
                    }
                    else if (s.String.Length == 0)
                    {
                        output.WriteValueU32(0, endian);
                    }
                    else
                    {
                        var length = s.String.Length + 1;

                        output.WriteValueU32((uint)newOffset, endian);

                        output.Seek(newOffset, SeekOrigin.Begin);
                        output.WriteValueS32(length, endian);
                        output.WriteString(s.String, endian == Endian.Little ? Encoding.Unicode : Encoding.BigEndianUnicode);
                        output.WriteValueU16(0, endian);
                        newOffset += 4 + (2 * length);
                    }

                    break;
                }

                case GFF.FieldType.Structure:
                {
                    if (def.IsReference == true)
                    {
                        if (data == null || data.Values == null)
                        {
                            output.WriteValueU32(0xFFFFFFFF, endian);
                        }
                        else
                        {
                            output.WriteValueU32((uint)newOffset, endian);
                            output.Seek(newOffset, SeekOrigin.Begin);

                            var subdef = this.Structures[def.StructureId];
                            newOffset += subdef.DataSize;

                            this.ImportStructure(
                                subdef,
                                data,
                                output.Position,
                                ref newOffset,
                                state);
                        }
                    }
                    else
                    {
                        var subdef = this.Structures[def.StructureId];
                        this.ImportStructure(
                            subdef,
                            data,
                            output.Position,
                            ref newOffset,
                            state);
                    }
                    break;
                }

                default:
                {
                    GFF.Builtin.Serialize(output, def.Type, data.Value, endian);
                    break;
                }
                }
            }
        }