Пример #1
0
        /// <summary>
        /// Adds a field to the TreeList and selects it.
        /// </summary>
        /// <param name="field"></param>
        /// <param name="locale"></param>
        void AddField(GffData.Field field, GffData.Locale locale = null)
        {
            string text = GeneralGFF.ConstructNodetext(field, locale);
            var    node = new Sortable(text, field.label);

            node.Tag = field;
            SelectedNode.Nodes.Add(node);

            SelectedNode = node;

            _f.GffData.Changed = true;
            _f.GffData         = _f.GffData;
        }
Пример #2
0
        /// <summary>
        /// Adds a Locale to a CExoLocString Field.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void contextclick_AddLocale(object sender, EventArgs e)
        {
            var field = (GffData.Field)SelectedNode.Tag;

            if (field.localeflags != LocaleDialog.Loc_ALL)
            {
                using (var f = new LocaleDialog(field.localeflags))
                {
                    if (f.ShowDialog(this) == DialogResult.OK)
                    {
                        var locale = new GffData.Locale();
                        locale.local = String.Empty;

                        LocaleDialog.SetLocaleFlag(ref field.localeflags,
                                                   locale.langid = _langid,
                                                   locale.F      = _langf);

                        if (field.Locales == null)
                        {
                            field.Locales = new List <GffData.Locale>();
                        }

                        var fieldloc = new GffData.Field();
                        fieldloc.type     = FieldTypes.locale;
                        fieldloc.label    = GffData.Locale.GetLanguageString(_langid, _langf);
                        fieldloc.localeid = (uint)field.Locales.Count;

                        field.Locales.Add(locale);
                        AddField(fieldloc, locale);
                    }
                }
            }
            else
            {
                using (var f = new InfoDialog(Globals.Error, "All locales are taken."))
                    f.ShowDialog(this);
            }
        }
Пример #3
0
        /// <summary>
        /// Deletes a field in the TreeList along with any of its subnodes.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        internal void contextclick_Delete(object sender, EventArgs e)
        {
            bool delete;

            if (SelectedNode.Tag == null)             // is TopLevelStruct's node
            {
                delete = false;
                using (var f = new DeleteDialog("Confirm delete TopLevelStruct"))
                {
                    f.cb_Bypass.Visible = false;
                    if (f.ShowDialog(this) == DialogResult.Yes)
                    {
                        delete = true;

                        if (_f.GffData.Pfe == Globals.TopLevelStruct)
                        {
                            _f.GffData = null;
                        }
                    }
                }
            }
            else if (!_bypassDeleteWarning)
            {
                string head = "Confirm delete";
                if (SelectedNode.Nodes.Count != 0)
                {
                    head += " multiple fields";
                }

                delete = false;
                using (var f = new DeleteDialog(head))
                {
                    f.cb_Bypass.Visible = true;

                    if (f.ShowDialog(this) == DialogResult.Yes)
                    {
                        delete = true;
                        _bypassDeleteWarning = f.cb_Bypass.Checked;
                    }
                }
            }
            else
            {
                delete = true;
            }

            if (delete)
            {
                if (SelectedNode.Tag != null)
                {
                    switch (((GffData.Field)SelectedNode.Tag).type)
                    {
                    case FieldTypes.Struct:
                    {
                        // Structs in Lists do not have a Label so keep their pseudo-labels' sequential order

                        var parent = SelectedNode.Parent;
                        if (parent.Tag != null &&                              // parent is NOT TopLevelStruct
                            ((GffData.Field)parent.Tag).type == FieldTypes.List)
                        {
                            Sortable node;

                            var field = (GffData.Field)SelectedNode.Tag;
                            int id    = Int32.Parse(field.label);
                            while (++id != parent.Nodes.Count)
                            {
                                node            = parent.Nodes[id] as Sortable;
                                field           = (GffData.Field)node.Tag;
                                node._label     =
                                    field.label = (id - 1).ToString();

                                node.Text = GeneralGFF.ConstructNodetext(field);
                            }
                        }
                        break;
                    }

                    case FieldTypes.locale:
                    {
                        var parent  = (GffData.Field)SelectedNode.Parent.Tag;
                        var locales = parent.Locales;

                        int            localeid = (int)((GffData.Field)SelectedNode.Tag).localeid;
                        GffData.Locale locale   = locales[localeid];

                        LocaleDialog.ClearLocaleFlag(ref parent.localeflags,
                                                     locale.langid,
                                                     locale.F);

                        for (int i = 0; i != SelectedNode.Parent.Nodes.Count; ++i)
                        {
                            var field = (GffData.Field)SelectedNode.Parent.Nodes[i].Tag;
                            if (field.localeid > localeid)
                            {
                                --field.localeid;
                            }
                        }

                        locales.Remove(locale);
                        break;
                    }
                    }
                }

                SelectedNode.Remove();

                if (SelectedNode == null)
                {
                    _f.ResetEditPanel();
                }

                if (_f.GffData != null)
                {
                    _f.GffData.Changed = true;
                }
                _f.GffData = _f.GffData;
            }
        }
Пример #4
0
        /// <summary>
        /// Gets a Locale's locale-flag.
        /// </summary>
        /// <param name="locale"></param>
        /// <returns></returns>
        internal static uint GetLocaleFlag(GffData.Locale locale)
        {
            switch (locale.langid)
            {
            case Languages.English:
                return(Loc_ENGLISH);

            case Languages.French:
                if (locale.F)
                {
                    return(Loc_FRENCH_F);
                }
                return(Loc_FRENCH);

            case Languages.German:
                if (locale.F)
                {
                    return(Loc_GERMAN_F);
                }
                return(Loc_GERMAN);

            case Languages.Italian:
                if (locale.F)
                {
                    return(Loc_ITALIAN_F);
                }
                return(Loc_ITALIAN);

            case Languages.Spanish:
                if (locale.F)
                {
                    return(Loc_SPANISH_F);
                }
                return(Loc_SPANISH);

            case Languages.Polish:
                if (locale.F)
                {
                    return(Loc_POLISH_F);
                }
                return(Loc_POLISH);

            case Languages.Russian:
                if (locale.F)
                {
                    return(Loc_RUSSIAN_F);
                }
                return(Loc_RUSSIAN);

            case Languages.Korean:
                if (locale.F)
                {
                    return(Loc_KOREAN_F);
                }
                return(Loc_KOREAN);

            case Languages.ChineseTraditional:
                if (locale.F)
                {
                    return(Loc_CHINESETRAD_F);
                }
                return(Loc_CHINESETRAD);

            case Languages.ChineseSimplified:
                if (locale.F)
                {
                    return(Loc_CHINESESIMP_F);
                }
                return(Loc_CHINESESIMP);

            case Languages.Japanese:
                if (locale.F)
                {
                    return(Loc_JAPANESE_F);
                }
                return(Loc_JAPANESE);

            case Languages.GffToken:
                return(Loc_GFFTOKEN);
            }
            return(Loc_non);            // error.
        }
Пример #5
0
/*		static readonly List<uint> _fieldids = new List<uint>();
 *              /// <summary>
 *              ///
 *              /// </summary>
 *              internal static List<uint> FieldIds
 *              { get { return _fieldids; } } */
        #endregion Properties (static)


        #region Methods (static)
        /// <summary>
        /// Reads a GFF-file and parses out its data to a GFFData object.
        /// @note Sections will be extracted in a non-arbitrary sequence because
        /// the data in a specific section could rely on the data in a different
        /// section. The order I have chosen is:
        /// 1. Header data (ofc)
        /// 2. FieldIndices
        /// 3. Structs - relies on FieldIndices
        /// 4. Labels
        /// 5. Fields - relies on Structs and Labels and extracts FieldData and ListIndices
        /// </summary>
        /// <param name="pfe">path-file-extension - ensure file exists before call</param>
        internal static GffData ReadGFFfile(string pfe)
        {
            Structs.Clear();             // Structs and Fields will be cleared after load completes
            Fields.Clear();              // but do it here (before load starts) also - jic.

            byte[] bytes = FileService.ReadFile(pfe);
            if (bytes != null)
            {
                if (bytes.Length != 0)
                {
                    uint pos = 0;
                    uint b;

                    var buffer = new byte[8];
                    for (b = 0; b != 8; ++b)
                    {
                        buffer[b] = bytes[pos++];
                    }

                    string ver = Encoding.ASCII.GetString(buffer, 0, buffer.Length);

                    if (ver.Substring(3) != Globals.SupportedVersion)
                    {
                        FileService.error("That is not a version 3.2 GFF file.");
                        return(null);
                    }


                    bool le = BitConverter.IsLittleEndian;                     // hardware architecture

                    var data = new GffData(pfe);

                    data.TypeVer = ver;
                    data.Type    = GffData.GetGffType(ver.Substring(0, 3));

                    data.Latest            = File.GetLastWriteTime(pfe);
                    FileWatchDialog.Bypass = false;


// HEADER METADATA ->
                    pos    = head_StructOffset;
                    buffer = new byte[4];
                    for (b = 0; b != 4; ++b)
                    {
                        buffer[b] = bytes[pos++];
                    }

                    if (!le)
                    {
                        Array.Reverse(buffer);
                    }
                    uint StructOffset = BitConverter.ToUInt32(buffer, 0);
                    //logfile.Log("StructOffset= " + StructOffset);

                    // The Struct-section will always start at 56-bytes (0x38)
                    if (StructOffset != Globals.Length_HEADER)
                    {
                        FileService.error("That does not appear to be a GFF file.");
                        return(null);
                    }

                    pos    = head_StructCount;
                    buffer = new byte[4];
                    for (b = 0; b != 4; ++b)
                    {
                        buffer[b] = bytes[pos++];
                    }

                    if (!le)
                    {
                        Array.Reverse(buffer);
                    }
                    uint StructCount = BitConverter.ToUInt32(buffer, 0);                     // count of elements
                    //logfile.Log("StructCount= " + StructCount);


                    pos    = head_FieldOffset;
                    buffer = new byte[4];
                    for (b = 0; b != 4; ++b)
                    {
                        buffer[b] = bytes[pos++];
                    }

                    if (!le)
                    {
                        Array.Reverse(buffer);
                    }
                    uint FieldOffset = BitConverter.ToUInt32(buffer, 0);
                    //logfile.Log("FieldOffset= " + FieldOffset);


                    pos    = head_FieldCount;
                    buffer = new byte[4];
                    for (b = 0; b != 4; ++b)
                    {
                        buffer[b] = bytes[pos++];
                    }

                    if (!le)
                    {
                        Array.Reverse(buffer);
                    }
                    uint FieldCount = BitConverter.ToUInt32(buffer, 0);                     // count of elements
                    //logfile.Log("FieldCount= " + FieldCount);


                    pos    = head_LabelOffset;
                    buffer = new byte[4];
                    for (b = 0; b != 4; ++b)
                    {
                        buffer[b] = bytes[pos++];
                    }

                    if (!le)
                    {
                        Array.Reverse(buffer);
                    }
                    uint LabelOffset = BitConverter.ToUInt32(buffer, 0);
                    //logfile.Log("LabelOffset= " + LabelOffset);


                    pos    = head_LabelCount;
                    buffer = new byte[4];
                    for (b = 0; b != 4; ++b)
                    {
                        buffer[b] = bytes[pos++];
                    }

                    if (!le)
                    {
                        Array.Reverse(buffer);
                    }
                    uint LabelCount = BitConverter.ToUInt32(buffer, 0);                     // count of elements
                    //logfile.Log("LabelCount= " + LabelCount);


                    pos    = head_FieldDataOffset;
                    buffer = new byte[4];
                    for (b = 0; b != 4; ++b)
                    {
                        buffer[b] = bytes[pos++];
                    }

                    if (!le)
                    {
                        Array.Reverse(buffer);
                    }
                    uint FieldDataOffset = BitConverter.ToUInt32(buffer, 0);
                    //logfile.Log("FieldDataOffset= " + FieldDataOffset);


                    pos    = head_FieldDataLength;
                    buffer = new byte[4];
                    for (b = 0; b != 4; ++b)
                    {
                        buffer[b] = bytes[pos++];
                    }

                    if (!le)
                    {
                        Array.Reverse(buffer);
                    }
                    uint FieldDataCount = BitConverter.ToUInt32(buffer, 0);                     // count of bytes (not used.)
                    //logfile.Log("FieldDataCount= " + FieldDataCount);


                    pos    = head_FieldIndicesOffset;
                    buffer = new byte[4];
                    for (b = 0; b != 4; ++b)
                    {
                        buffer[b] = bytes[pos++];
                    }

                    if (!le)
                    {
                        Array.Reverse(buffer);
                    }
                    uint FieldIndicesOffset = BitConverter.ToUInt32(buffer, 0);
                    //logfile.Log("FieldIndicesOffset= " + FieldIndicesOffset);


                    pos    = head_FieldIndicesLength;
                    buffer = new byte[4];
                    for (b = 0; b != 4; ++b)
                    {
                        buffer[b] = bytes[pos++];
                    }

                    if (!le)
                    {
                        Array.Reverse(buffer);
                    }
                    uint FieldIndicesCount = BitConverter.ToUInt32(buffer, 0);                     // count of bytes
                    //logfile.Log("FieldIndicesCount= " + FieldIndicesCount);


                    pos    = head_ListIndicesOffset;
                    buffer = new byte[4];
                    for (b = 0; b != 4; ++b)
                    {
                        buffer[b] = bytes[pos++];
                    }

                    if (!le)
                    {
                        Array.Reverse(buffer);
                    }
                    uint ListIndicesOffset = BitConverter.ToUInt32(buffer, 0);
                    //logfile.Log("ListIndicesOffset= " + ListIndicesOffset);


                    pos    = head_ListIndicesLength;
                    buffer = new byte[4];
                    for (b = 0; b != 4; ++b)
                    {
                        buffer[b] = bytes[pos++];
                    }

                    if (!le)
                    {
                        Array.Reverse(buffer);
                    }
                    uint ListIndicesCount = BitConverter.ToUInt32(buffer, 0);                     // count of bytes (not used.)
                    //logfile.Log("ListIndicesCount= " + ListIndicesCount);


                    //logfile.Log("");

// FIELDID DATA -> contains the FieldIds of Structs that contain > 1 field (is req'd for parsing Structs)
// - a list of DWORD ids into the Fields section
                    //logfile.Log("FIELDIDS");
                    //int fid = 0; // log

                    var fieldids = new List <uint>();

                    pos = FieldIndicesOffset;
                    while (pos != FieldIndicesOffset + FieldIndicesCount)
                    {
                        //logfile.Log(". start= " + FieldIndicesOffset + " stop= " + (FieldIndicesOffset + FieldIndicesCount));
                        //logfile.Log(". fid #" + fid++);

                        buffer = new byte[4];                         // 4-byte DWORD - field id
                        for (b = 0; b != 4; ++b)
                        {
                            //logfile.Log(". . pos= " + pos);
                            buffer[b] = bytes[pos++];
                        }

                        if (!le)
                        {
                            Array.Reverse(buffer);
                        }
                        fieldids.Add(BitConverter.ToUInt32(buffer, 0));                         // WARNING: There is no safety on the count below.
                    }


// STRUCT DATA ->
// - DWORD type-id
// - DWORD dataordataoffset
// - DWORD fieldcount
                    uint fields, idoroffset, i, j;

                    pos = StructOffset;
                    for (i = 0; i != StructCount; ++i)
                    {
                        //logfile.Log("Struct #" + i);
                        var st = new Struct();

                        buffer = new byte[4];                         // type-id ->
                        for (b = 0; b != 4; ++b)
                        {
                            buffer[b] = bytes[pos++];
                        }

                        if (!le)
                        {
                            Array.Reverse(buffer);
                        }
                        st.typeid = BitConverter.ToUInt32(buffer, 0);
                        //logfile.Log(". typid= " + st.typeid);

                        buffer = new byte[4];                         // dataordataoffset ->
                        for (b = 0; b != 4; ++b)
                        {
                            buffer[b] = bytes[pos++];
                        }

                        if (!le)
                        {
                            Array.Reverse(buffer);
                        }
                        idoroffset = BitConverter.ToUInt32(buffer, 0);                          // if fields=1 -> id into the FieldArray
                        // if fields>1 -> offset into FieldIndices -> list of ids into the FieldArray

                        buffer = new byte[4];                         // fieldcount ->
                        for (b = 0; b != 4; ++b)
                        {
                            buffer[b] = bytes[pos++];
                        }

                        if (!le)
                        {
                            Array.Reverse(buffer);
                        }
                        fields = BitConverter.ToUInt32(buffer, 0);
                        //logfile.Log(". fields= " + fields);

                        st.fieldids = new List <uint>();
                        if (fields == 1)                                        // get the FieldId directly w/ the Struct's 'idoroffset' id ->
                        {
                            //logfile.Log(". . idoroffset/id= " + idoroffset);
                            //logfile.Log(". . data._fields.Count= " + data._fields.Count);
                            st.fieldids.Add(idoroffset);
                        }
                        else if (fields > 1)                            // get the FieldIds out of the FieldIndices w/ the 'idoroffset' offset ->
                        {
                            uint fieldid;
                            for (j = 0; j != fields; ++j)
                            {
                                //logfile.Log(". . [" + j + "] idoroffset/offset= " + idoroffset + " -> fieldids id= " + (idoroffset / 4 + j));
                                //logfile.Log(". . data._fieldids Length= " + (data._fieldids.Count * 4));
                                //logfile.Log(". . data._fields.Count= " + data._fields.Count);

                                fieldid = fieldids[(int)(idoroffset / Globals.Length_DWORD + j)];                                       // 4 bytes in each DWORD (ie. convert offset to id id)
                                //logfile.Log(". . fieldid= " + fieldid);
                                st.fieldids.Add(fieldid);                                                                               // isn't the GFF format wonderful ... at least it works
                            }                                                                                                           // the Bioware documentation could be better.
                        }                                                                                                               // Ps. it contains inaccurate and unspecific info

                        Structs.Add(st);
                    }


// LABEL DATA -> contains Labels for the Fields (is req'd for parsing Fields)
// - each label shall be unique across the entire GFF data
// - 16-CHAR
                    var    labels = new List <string>();
                    string label;

                    pos = LabelOffset;
                    for (i = 0; i != LabelCount; ++i)
                    {
                        buffer = new byte[Globals.Length_LABEL];                         // 16-byte CHAR(s) - label length
                        for (b = 0; b != Globals.Length_LABEL; ++b)
                        {
                            buffer[b] = bytes[pos++];
                        }

                        label = Encoding.ASCII.GetString(buffer, 0, buffer.Length).TrimEnd('\0');
                        labels.Add(label);
                    }


// FIELD DATA ->
// - the doc contradicts itself by saying that the TopLevelStruct is the 1st
//   entry in the Fields section but that the Fields section does not contain
//   the TopLevelStruct ... the latter appears to be correct: the first Field in
//   a toolset-written FieldsArray is "Description" eg.
// - DWORD datatype
// - DWORD label-id
// - DWORD dataordataoffset
//   - if BYTE,CHAR,WORD,SHORT,DWORD,INT,FLOAT -> dataordataoffset is a value.
//   - if DWORD64,INT64,DOUBLE,CExoString,CResRef,CExoLocString -> dataordataoffset
//     is an offset from the start of the FieldDataBlock section to complex data:
//     - DWORD64       8-bytes
//     - INT64         8-bytes
//     - DOUBLE        8-bytes
//     - CExoString    DWORD (length) + chars
//     - CExoLocString DWORD (total length) + DWORD (strref) + DWORD (stringcount) + [INT (id) + INT (length) + chars]
//     - CResRef       1-byte (length) + chars (lowercase)
//     - VOID          arbitrary
//   - if Struct -> dataordataoffset is an id into the Struct section.
//   - if List -> dataordataoffset is an offset from the start of the ListIndices
//     section to an array of DWORDs, the first of which is the count of DWORDS
//     that follow, which are ids into the Struct section.

                    uint offset, length, count;

                    pos = FieldOffset;
                    for (i = 0; i != FieldCount; ++i)
                    {
                        var field = new GffData.Field();


                        buffer = new byte[4];                         // 4-byte DWORD - field type
                        for (b = 0; b != 4; ++b)
                        {
                            buffer[b] = bytes[pos++];
                        }

                        if (!le)
                        {
                            Array.Reverse(buffer);
                        }
                        field.type = (FieldTypes)BitConverter.ToUInt32(buffer, 0);


                        buffer = new byte[4];                         // 4-byte DWORD - field label id
                        for (b = 0; b != 4; ++b)
                        {
                            buffer[b] = bytes[pos++];
                        }

                        if (!le)
                        {
                            Array.Reverse(buffer);
                        }
                        field.label = labels[(int)BitConverter.ToUInt32(buffer, 0)];
                        //logfile.Log("label= " + field.label);


                        buffer = new byte[4];                                   // 4-byte DWORD - field data (val, is not a DWORD per se) or data
                        for (b = 0; b != 4; ++b)                                // offset into (a) DataBlock or (b) ListIds or id into (c) Structs
                        {
                            buffer[b] = bytes[pos++];
                        }


                        switch (field.type)
                        {
                        // WARNING: non-Complex types whose size is less than or
                        // equal to 4-bytes are (according to the doc) contained
                        // in the first byte(s) of the dataordataoffset 'DWORD'.

                        case FieldTypes.BYTE:
                            field.BYTE = buffer[0];
                            break;

                        case FieldTypes.CHAR:
                        {
                            var a = (sbyte[])(object)new[] { buffer[0] };
                            field.CHAR = a[0];
                            break;
                        }

                        case FieldTypes.WORD:
                        {
                            var a = new byte[2];
                            if (le)
                            {
                                a[0] = buffer[0];
                                a[1] = buffer[1];
                            }
                            else
                            {
                                a[0] = buffer[1];
                                a[1] = buffer[0];
                            }

                            field.WORD = BitConverter.ToUInt16(a, 0);
                            break;
                        }

                        case FieldTypes.SHORT:
                        {
                            var a = new byte[2];
                            if (le)
                            {
                                a[0] = buffer[0];
                                a[1] = buffer[1];
                            }
                            else
                            {
                                a[0] = buffer[1];
                                a[1] = buffer[0];
                            }

                            field.SHORT = BitConverter.ToInt16(a, 0);
                            break;
                        }

                        case FieldTypes.DWORD:
                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            field.DWORD = BitConverter.ToUInt32(buffer, 0);
                            break;

                        case FieldTypes.INT:
                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            field.INT = BitConverter.ToInt32(buffer, 0);
                            break;

                        case FieldTypes.DWORD64:
                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            offset = FieldDataOffset + BitConverter.ToUInt32(buffer, 0);
                            buffer = new byte[8];
                            for (b = 0; b != 8; ++b)
                            {
                                buffer[b] = bytes[offset++];
                            }

                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            field.DWORD64 = BitConverter.ToUInt64(buffer, 0);
                            break;

                        case FieldTypes.INT64:
                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            offset = FieldDataOffset + BitConverter.ToUInt32(buffer, 0);
                            buffer = new byte[8];
                            for (b = 0; b != 8; ++b)
                            {
                                buffer[b] = bytes[offset++];
                            }

                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            field.INT64 = BitConverter.ToInt64(buffer, 0);
                            break;

                        case FieldTypes.FLOAT:
                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            field.FLOAT = BitConverter.ToSingle(buffer, 0);
                            break;

                        case FieldTypes.DOUBLE:
                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            offset = FieldDataOffset + BitConverter.ToUInt32(buffer, 0);
                            buffer = new byte[8];
                            for (b = 0; b != 8; ++b)
                            {
                                buffer[b] = bytes[offset++];
                            }

                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            field.DOUBLE = BitConverter.ToDouble(buffer, 0);
                            break;

                        case FieldTypes.CResRef:
                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            offset = FieldDataOffset + BitConverter.ToUInt32(buffer, 0);
                            length = bytes[offset];                                     // 1-byte size

                            ++offset;
                            buffer = new byte[(int)length];
                            for (b = 0; b != length; ++b)
                            {
                                buffer[b] = bytes[offset++];
                            }

                            field.CResRef = Encoding.ASCII.GetString(buffer, 0, buffer.Length);
                            break;

                        case FieldTypes.CExoString:
                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            offset = FieldDataOffset + BitConverter.ToUInt32(buffer, 0);

                            buffer = new byte[4];
                            for (b = 0; b != 4; ++b)
                            {
                                buffer[b] = bytes[offset++];
                            }

                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            length = BitConverter.ToUInt32(buffer, 0);                                     // 4-byte size

                            buffer = new byte[(int)length];
                            for (b = 0; b != length; ++b)
                            {
                                buffer[b] = bytes[offset++];
                            }

                            field.CExoString = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
                            field.CExoString = field.CExoString.Replace("\r\n", "\n").Replace("\r", "\n").Replace("\n", "\r\n");
                            break;

                        case FieldTypes.CExoLocString:
                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            offset = FieldDataOffset + BitConverter.ToUInt32(buffer, 0);

                            buffer = new byte[4];                                                                                       // total length (not incl/ these 4 bytes) ->
                            for (b = 0; b != 4; ++b)                                                                                    // aka Pointless. just advance the offset val
                            {
                                buffer[b] = bytes[offset++];
                            }

                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            length = BitConverter.ToUInt32(buffer, 0);                                     // 4-byte size

                            buffer = new byte[4];                                                          // strref (-1 no strref)
                            for (b = 0; b != 4; ++b)
                            {
                                buffer[b] = bytes[offset++];
                            }

                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            field.CExoLocStrref = BitConverter.ToUInt32(buffer, 0);                                     // 4-byte size

                            buffer = new byte[4];                                                                       // substring count
                            for (b = 0; b != 4; ++b)
                            {
                                buffer[b] = bytes[offset++];
                            }

                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            count = BitConverter.ToUInt32(buffer, 0);                                     // 4-byte size

                            if (count != 0)
                            {
                                field.Locales = new List <GffData.Locale>();

                                //logfile.Log("label= " + field.label);
                                for (j = 0; j != count; ++j)
                                {
                                    var locale = new GffData.Locale();

                                    buffer = new byte[4];                                             // langid
                                    for (b = 0; b != 4; ++b)
                                    {
                                        buffer[b] = bytes[offset++];
                                    }

                                    if (!le)
                                    {
                                        Array.Reverse(buffer);
                                    }
                                    locale.SetLocaleLanguage(BitConverter.ToUInt32(buffer, 0));

                                    buffer = new byte[4];                                             // stringlength
                                    for (b = 0; b != 4; ++b)
                                    {
                                        buffer[b] = bytes[offset++];
                                    }

                                    if (!le)
                                    {
                                        Array.Reverse(buffer);
                                    }
                                    length = BitConverter.ToUInt32(buffer, 0);
                                    //logfile.Log("length= " + length);

                                    buffer = new byte[(int)length];
                                    for (b = 0; b != length; ++b)
                                    {
                                        buffer[b] = bytes[offset++];
                                    }

                                    locale.local = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
                                    locale.local = locale.local.Replace("\r\n", "\n").Replace("\r", "\n").Replace("\n", "\r\n");
                                    //logfile.Log("local= " + locale.local);

                                    field.Locales.Add(locale);
                                }
                            }
                            break;

                        case FieldTypes.VOID:
                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            offset = FieldDataOffset + BitConverter.ToUInt32(buffer, 0);
                            buffer = new byte[4];
                            for (b = 0; b != 4; ++b)
                            {
                                buffer[b] = bytes[offset++];
                            }

                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            length = BitConverter.ToUInt32(buffer, 0);

                            field.VOID = new byte[(int)length];

                            for (j = 0; j != length; ++j)
                            {
                                field.VOID[j] = bytes[offset++];
                            }

                            break;

                        case FieldTypes.List:                                 // a list-type Field is an offset into the FieldIndices; the later contains a list of StructIds.
                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            offset = ListIndicesOffset + BitConverter.ToUInt32(buffer, 0); // offset into the (not)FieldIndices(not) -> try ListIndices

                            buffer = new byte[4];                                          // 4-byte DWORD - count of structids
                            for (b = 0; b != 4; ++b)
                            {
                                buffer[b] = bytes[offset++];
                            }

                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            count = BitConverter.ToUInt32(buffer, 0);

                            var list = new List <uint>();
                            for (j = 0; j != count; ++j)
                            {
                                buffer = new byte[4];                                         // 4-byte DWORD - structid
                                for (b = 0; b != 4; ++b)
                                {
                                    buffer[b] = bytes[offset++];
                                }

                                if (!le)
                                {
                                    Array.Reverse(buffer);
                                }
                                list.Add(BitConverter.ToUInt32(buffer, 0));
                            }
                            field.List = list;
                            break;

                        case FieldTypes.Struct:
                            if (!le)
                            {
                                Array.Reverse(buffer);
                            }
                            field.Struct = Structs[(int)BitConverter.ToUInt32(buffer, 0)];                                     // NOTE: That is an id into the Structs not an offset.
                            break;
                        }

                        Fields.Add(field);
                    }
                    return(data);
                }

                FileService.error("That file has no data.");
            }
            return(null);
        }
Пример #6
0
        /// <summary>
        /// Adds a Field to a treenode.
        /// </summary>
        /// <param name="field">a Field to add</param>
        /// <param name="parent">a treenode to add it to</param>
        /// <param name="locale">a locale if applicable</param>
        static void AddField(GffData.Field field, TreeNode parent, GffData.Locale locale = null)
        {
            // TODO: Refactor things throughout the code such that the Tag of a
            // treenode is *either* a GffData.Field *or* a GffData.Locale.

            string text = GeneralGFF.ConstructNodetext(field, locale);

            var node = new Sortable(text, field.label);

            node.Tag = field;
            parent.Nodes.Add(node);

            switch (field.type)
            {
            case FieldTypes.Struct:                     // childs can be of any Type.
            {
                List <uint> fieldids = field.Struct.fieldids;
                for (int i = 0; i != fieldids.Count; ++i)
                {
                    AddField(GffReader.Fields[(int)fieldids[i]], node);
                }
                break;
            }

            case FieldTypes.List:                     // childs are Structs.
            {
                List <uint> list = field.List;
                for (int i = 0; i != list.Count; ++i)
                {
                    // NOTE: Structs in Lists do not have a Label inside a GFF-file.
                    // so give Structs in Lists a pseudo-label for their treenode(s)
                    field        = new GffData.Field();
                    field.type   = FieldTypes.Struct;
                    field.label  = i.ToString();
                    field.Struct = GffReader.Structs[(int)list[i]];

                    AddField(field, node);
                }
                break;
            }

            case FieldTypes.CExoLocString:                     // childs are Locales.
                if (field.Locales != null)
                {
                    int locales = field.Locales.Count;
                    for (int i = 0; i != locales; ++i)
                    {
                        locale = field.Locales[i];

                        var fieldloc = new GffData.Field();
                        fieldloc.type     = FieldTypes.locale;
                        fieldloc.localeid = (uint)i;
                        fieldloc.label    = GffData.Locale.GetLanguageString(locale.langid, locale.F);

                        AddField(fieldloc, node, locale);

                        LocaleDialog.SetLocaleFlag(ref field.localeflags,
                                                   locale.langid,
                                                   locale.F);
                    }
                }
                break;
            }
        }