Esempio n. 1
0
        private const uint WDC3FmtSig = 0x33434457; // WDC3

        public static DB6Storage <T> Read <T>(string fileName, HotfixStatements preparedStatement, HotfixStatements preparedStatementLocale = 0) where T : new()
        {
            DB6Storage <T> storage = new DB6Storage <T>();

            if (!File.Exists(CliDB.DataPath + fileName))
            {
                Log.outError(LogFilter.ServerLoading, $"File {fileName} not found.");
                return(storage);
            }

            DBReader reader = new DBReader();

            using (var stream = new FileStream(CliDB.DataPath + fileName, FileMode.Open))
            {
                if (!reader.Load(stream))
                {
                    Log.outError(LogFilter.ServerLoading, $"Error loading {fileName}.");
                    return(storage);
                }
            }

            foreach (var b in reader._records)
            {
                storage.Add((uint)b.Key, b.Value.As <T>());
            }

            storage.LoadData(reader.Header.IdIndex, preparedStatement, preparedStatementLocale);

            Global.DB2Mgr.AddDB2(reader.Header.TableHash, storage);
            CliDB.LoadedFileCount++;
            return(storage);
        }
Esempio n. 2
0
        public static DB6Storage <T> Read <T>(string fileName, HotfixStatements preparedStatement, HotfixStatements preparedStatementLocale = 0) where T : new()
        {
            ClearData();

            DB6Storage <T> storage = new DB6Storage <T>();

            if (!File.Exists(CliDB.DataPath + fileName))
            {
                Log.outError(LogFilter.ServerLoading, "File {0} not found.", fileName);
                return(storage);
            }

            //First lets load field Info
            var fields = typeof(T).GetFields();

            DB6FieldInfo[] fieldsInfo = new DB6FieldInfo[fields.Length];
            for (var i = 0; i < fields.Length; ++i)
            {
                fieldsInfo[i] = new DB6FieldInfo(fields[i]);
            }

            using (var fileReader = new BinaryReader(new MemoryStream(File.ReadAllBytes(CliDB.DataPath + fileName))))
            {
                ReadHeader(fileReader);

                var records = ReadData(fileReader);
                foreach (var pair in records)
                {
                    using (MemoryStream ms = new MemoryStream(pair.Value))
                        using (BinaryReader dataReader = new BinaryReader(ms, System.Text.Encoding.UTF8))
                        {
                            var obj = new T();

                            int objectFieldIndex = 0;
                            //First check if index is in data
                            if (Header.HasIndexTable())
                            {
                                fieldsInfo[objectFieldIndex++].SetValue(obj, (uint)pair.Key);
                            }

                            for (var dataFieldIndex = 0; dataFieldIndex < Header.FieldCount; ++dataFieldIndex)
                            {
                                int arrayLength = ColumnMeta[dataFieldIndex].ArraySize;
                                if (arrayLength > 1)
                                {
                                    for (var arrayIndex = 0; arrayIndex < arrayLength; ++arrayIndex)
                                    {
                                        var fieldInfo = fieldsInfo[objectFieldIndex++];
                                        if (fieldInfo.IsArray)
                                        {
                                            Array array = (Array)fieldInfo.Getter(obj);
                                            SetArrayValue(obj, (uint)array.Length, fieldInfo, dataReader);

                                            arrayLength -= array.Length;
                                        }
                                        else
                                        {
                                            //Only Data is Array
                                            if (Type.GetTypeCode(fieldInfo.FieldType) == TypeCode.Object)
                                            {
                                                switch (fieldInfo.FieldType.Name)
                                                {
                                                case "Vector2":
                                                    fieldInfo.SetValue(obj, dataReader.Read <Vector2>());
                                                    arrayLength -= 2;
                                                    break;

                                                case "Vector3":
                                                    fieldInfo.SetValue(obj, dataReader.Read <Vector3>());
                                                    arrayLength -= 3;
                                                    break;

                                                case "LocalizedString":
                                                    LocalizedString locString = new LocalizedString();
                                                    locString[Global.WorldMgr.GetDefaultDbcLocale()] = GetString(dataReader);
                                                    fieldInfo.SetValue(obj, locString);
                                                    arrayLength -= 1;
                                                    break;

                                                case "FlagArray128":
                                                    fieldInfo.SetValue(obj, new FlagArray128(dataReader.ReadUInt32(), dataReader.ReadUInt32(), dataReader.ReadUInt32(), dataReader.ReadUInt32()));
                                                    arrayLength -= 4;
                                                    break;

                                                default:
                                                    Log.outError(LogFilter.ServerLoading, "Unknown Array Type {0} in DBClient File", fieldInfo.FieldType.Name, nameof(T));
                                                    break;
                                                }
                                            }
                                            else
                                            {
                                                SetValue(obj, fieldInfo, dataReader);
                                            }
                                        }

                                        dataReader.BaseStream.Position += GetPadding(fieldInfo.FieldType, dataFieldIndex);
                                    }
                                }
                                else
                                {
                                    var fieldInfo = fieldsInfo[objectFieldIndex++];
                                    if (fieldInfo.IsArray)
                                    {
                                        Array array = (Array)fieldInfo.Getter(obj);
                                        SetArrayValue(obj, (uint)array.Length, fieldInfo, dataReader);

                                        dataFieldIndex += array.Length - 1;
                                    }
                                    else
                                    {
                                        SetValue(obj, fieldInfo, dataReader);
                                    }

                                    dataReader.BaseStream.Position += GetPadding(fieldInfo.FieldType, dataFieldIndex);
                                }
                            }

                            //Check if there is parent ids and fill them
                            if (objectFieldIndex < fieldsInfo.Length && Header.LookupColumnCount > 0)
                            {
                                fieldsInfo[objectFieldIndex].SetValue(obj, dataReader.ReadUInt32());
                            }

                            storage.Add((uint)pair.Key, obj);
                        }
                }

                storage.LoadData(Header.IdIndex, fieldsInfo, preparedStatement, preparedStatementLocale);
            }

            Global.DB2Mgr.AddDB2(Header.TableHash, storage);
            CliDB.LoadedFileCount++;
            return(storage);
        }
Esempio n. 3
0
        internal static DB6Storage <T> Read <T>(string fileName, DB6Meta meta, HotfixStatements preparedStatement, HotfixStatements preparedStatementLocale = 0) where T : new()
        {
            DB6Storage <T> storage = new DB6Storage <T>();

            if (!File.Exists(CliDB.DataPath + fileName))
            {
                Log.outError(LogFilter.ServerLoading, "File {0} not found.", fileName);
                return(storage);
            }

            //First lets load field Info
            var fields = typeof(T).GetFields();

            DBClientHelper[] fieldsInfo = new DBClientHelper[fields.Length];
            for (var i = 0; i < fields.Length; ++i)
            {
                fieldsInfo[i] = new DBClientHelper(fields[i]);
            }

            using (var fileReader = new BinaryReader(new MemoryStream(File.ReadAllBytes(CliDB.DataPath + fileName))))
            {
                _header = ReadHeader(fileReader);
                var data = LoadData(fileReader);

                int commonDataFieldIndex = 0;
                foreach (var pair in data)
                {
                    var dataReader = new DB6BinaryReader(pair.Value);
                    var obj        = new T();

                    int fieldIndex = 0;
                    for (var x = 0; x < _header.FieldCount; ++x)
                    {
                        int arrayLength = meta.ArraySizes[x];
                        if (arrayLength > 1)
                        {
                            for (var z = 0; z < arrayLength; ++z)
                            {
                                var fieldInfo = fieldsInfo[fieldIndex++];
                                if (fieldInfo.IsArray)
                                {
                                    //Field is Array
                                    Array array = (Array)fieldInfo.Getter(obj);
                                    for (var y = 0; y < array.Length; ++y)
                                    {
                                        SetArrayValue(array, y, fieldInfo, dataReader, x);
                                    }

                                    arrayLength -= array.Length;
                                }
                                else
                                {
                                    //Only Data is Array
                                    if (Type.GetTypeCode(fieldInfo.FieldType) == TypeCode.Object)
                                    {
                                        switch (fieldInfo.FieldType.Name)
                                        {
                                        case "Vector2":
                                            fieldInfo.SetValue(obj, new Vector2(dataReader.ReadSingle(), dataReader.ReadSingle()));
                                            arrayLength -= 2;
                                            break;

                                        case "Vector3":
                                            fieldInfo.SetValue(obj, new Vector3(dataReader.ReadSingle(), dataReader.ReadSingle(), dataReader.ReadSingle()));
                                            arrayLength -= 3;
                                            break;

                                        case "LocalizedString":
                                            LocalizedString locString = new LocalizedString();
                                            locString[Global.WorldMgr.GetDefaultDbcLocale()] = GetString(dataReader, x);
                                            fieldInfo.SetValue(obj, locString);
                                            arrayLength -= 1;
                                            break;

                                        case "FlagArray128":
                                            FlagArray128 flagArray128 = new FlagArray128(dataReader.GetUInt32(_header.GetFieldBytes(x)), dataReader.GetUInt32(_header.GetFieldBytes(x)), dataReader.GetUInt32(_header.GetFieldBytes(x)), dataReader.GetUInt32(_header.GetFieldBytes(x)));
                                            fieldInfo.SetValue(obj, flagArray128);
                                            arrayLength -= 4;
                                            break;

                                        default:
                                            Log.outError(LogFilter.ServerLoading, "Unknown Array Type {0} in DBClient File", fieldInfo.FieldType.Name, nameof(T));
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        SetValue(obj, fieldInfo, dataReader, x);
                                    }
                                }
                            }
                        }
                        else
                        {
                            var fieldInfo = fieldsInfo[fieldIndex++];
                            if (fieldInfo.IsArray)
                            {
                                Array array = (Array)fieldInfo.Getter(obj);
                                for (var y = 0; y < array.Length; ++y)
                                {
                                    SetArrayValue(array, y, fieldInfo, dataReader, x + y);
                                }

                                x += array.Length - 1;
                            }
                            else
                            {
                                SetValue(obj, fieldInfo, dataReader, x);
                            }
                        }
                    }

                    commonDataFieldIndex = fieldIndex;

                    storage.Add((uint)pair.Key, obj);
                }

                //Get DB field Index
                uint index = 0;
                for (uint i = 0; i < _header.FieldCount && i < _header.IndexField; ++i)
                {
                    index += meta.ArraySizes[i];
                }

                ReadCommonData(commonDataFieldIndex, storage, meta, fieldsInfo);
                storage.LoadData(index, fieldsInfo, preparedStatement, preparedStatementLocale);
            }

            Global.DB2Mgr.AddDB2(_header.TableHash, storage);
            CliDB.LoadedFileCount++;
            return(storage);
        }
Esempio n. 4
0
        public void LoadData(int indexField, HotfixStatements preparedStatement, HotfixStatements preparedStatementLocale)
        {
            SQLResult result = DB.Hotfix.Query(DB.Hotfix.GetPreparedStatement(preparedStatement));

            if (!result.IsEmpty())
            {
                do
                {
                    var id = result.Read <uint>(indexField == -1 ? 0 : indexField);

                    var obj = new T();

                    int dbIndex = 0;
                    foreach (var f in typeof(T).GetFields())
                    {
                        Type type = f.FieldType;

                        if (type.IsArray)
                        {
                            Type arrayElementType = type.GetElementType();
                            if (arrayElementType.IsEnum)
                            {
                                arrayElementType = arrayElementType.GetEnumUnderlyingType();
                            }

                            Array array = (Array)f.GetValue(obj);
                            switch (Type.GetTypeCode(arrayElementType))
                            {
                            case TypeCode.SByte:
                                f.SetValue(obj, ReadArray <sbyte>(result, dbIndex, array.Length));
                                break;

                            case TypeCode.Byte:
                                f.SetValue(obj, ReadArray <byte>(result, dbIndex, array.Length));
                                break;

                            case TypeCode.Int16:
                                f.SetValue(obj, ReadArray <short>(result, dbIndex, array.Length));
                                break;

                            case TypeCode.UInt16:
                                f.SetValue(obj, ReadArray <ushort>(result, dbIndex, array.Length));
                                break;

                            case TypeCode.Int32:
                                f.SetValue(obj, ReadArray <int>(result, dbIndex, array.Length));
                                break;

                            case TypeCode.UInt32:
                                f.SetValue(obj, ReadArray <uint>(result, dbIndex, array.Length));
                                break;

                            case TypeCode.Single:
                                f.SetValue(obj, ReadArray <float>(result, dbIndex, array.Length));
                                break;

                            case TypeCode.String:
                                f.SetValue(obj, ReadArray <string>(result, dbIndex, array.Length));
                                break;

                            case TypeCode.Object:
                                if (arrayElementType == typeof(Vector3))
                                {
                                    f.SetValue(obj, new Vector3(ReadArray <float>(result, dbIndex, 3)));
                                }
                                break;

                            default:
                                Log.outError(LogFilter.ServerLoading, "Wrong Array Type: {0}", arrayElementType.Name);
                                break;
                            }

                            dbIndex += array.Length;
                        }
                        else
                        {
                            if (type.IsEnum)
                            {
                                type = type.GetEnumUnderlyingType();
                            }

                            switch (Type.GetTypeCode(type))
                            {
                            case TypeCode.SByte:
                                f.SetValue(obj, result.Read <sbyte>(dbIndex++));
                                break;

                            case TypeCode.Byte:
                                f.SetValue(obj, result.Read <byte>(dbIndex++));
                                break;

                            case TypeCode.Int16:
                                f.SetValue(obj, result.Read <short>(dbIndex++));
                                break;

                            case TypeCode.UInt16:
                                f.SetValue(obj, result.Read <ushort>(dbIndex++));
                                break;

                            case TypeCode.Int32:
                                f.SetValue(obj, result.Read <int>(dbIndex++));
                                break;

                            case TypeCode.UInt32:
                                f.SetValue(obj, result.Read <uint>(dbIndex++));
                                break;

                            case TypeCode.Single:
                                f.SetValue(obj, result.Read <float>(dbIndex++));
                                break;

                            case TypeCode.String:
                                string str = result.Read <string>(dbIndex++);
                                f.SetValue(obj, str);
                                break;

                            case TypeCode.Object:
                                if (type == typeof(LocalizedString))
                                {
                                    LocalizedString locString = new LocalizedString();
                                    locString[Global.WorldMgr.GetDefaultDbcLocale()] = result.Read <string>(dbIndex++);

                                    f.SetValue(obj, locString);
                                }
                                else if (type == typeof(Vector2))
                                {
                                    f.SetValue(obj, new Vector2(ReadArray <float>(result, dbIndex, 2)));
                                    dbIndex += 2;
                                }
                                else if (type == typeof(Vector3))
                                {
                                    f.SetValue(obj, new Vector3(ReadArray <float>(result, dbIndex, 3)));
                                    dbIndex += 3;
                                }
                                else if (type == typeof(FlagArray128))
                                {
                                    f.SetValue(obj, new FlagArray128(ReadArray <uint>(result, dbIndex, 4)));
                                    dbIndex += 4;
                                }
                                break;

                            default:
                                Log.outError(LogFilter.ServerLoading, "Wrong Type: {0}", type.Name);
                                break;
                            }
                        }
                    }

                    base[id] = obj;
                }while (result.NextRow());
            }

            if (preparedStatementLocale == 0)
            {
                return;
            }

            for (LocaleConstant locale = 0; locale < LocaleConstant.Total; ++locale)
            {
                if (Global.WorldMgr.GetDefaultDbcLocale() == locale || locale == LocaleConstant.None)
                {
                    continue;
                }

                PreparedStatement stmt = DB.Hotfix.GetPreparedStatement(preparedStatementLocale);
                stmt.AddValue(0, locale.ToString());
                SQLResult localeResult = DB.Hotfix.Query(stmt);
                if (localeResult.IsEmpty())
                {
                    continue;
                }

                do
                {
                    int index = 0;
                    var obj   = this.LookupByKey(localeResult.Read <uint>(index++));
                    if (obj == null)
                    {
                        continue;
                    }

                    foreach (var f in typeof(T).GetFields())
                    {
                        if (f.FieldType != typeof(LocalizedString))
                        {
                            continue;
                        }

                        LocalizedString locString = (LocalizedString)f.GetValue(obj);
                        locString[locale] = localeResult.Read <string>(index++);
                    }
                } while (localeResult.NextRow());
            }
        }
Esempio n. 5
0
        public void LoadData(int indexField, BitSet availableDb2Locales, HotfixStatements preparedStatement, HotfixStatements preparedStatementLocale)
        {
            SQLResult result = DB.Hotfix.Query(DB.Hotfix.GetPreparedStatement(preparedStatement));

            if (!result.IsEmpty())
            {
                do
                {
                    var obj = new T();

                    int dbIndex = 0;
                    var fields  = typeof(T).GetFields();
                    foreach (var f in typeof(T).GetFields())
                    {
                        Type type = f.FieldType;

                        if (type.IsArray)
                        {
                            Type arrayElementType = type.GetElementType();
                            if (arrayElementType.IsEnum)
                            {
                                arrayElementType = arrayElementType.GetEnumUnderlyingType();
                            }

                            Array array = (Array)f.GetValue(obj);
                            switch (Type.GetTypeCode(arrayElementType))
                            {
                            case TypeCode.SByte:
                                f.SetValue(obj, ReadArray <sbyte>(result, dbIndex, array.Length));
                                break;

                            case TypeCode.Byte:
                                f.SetValue(obj, ReadArray <byte>(result, dbIndex, array.Length));
                                break;

                            case TypeCode.Int16:
                                f.SetValue(obj, ReadArray <short>(result, dbIndex, array.Length));
                                break;

                            case TypeCode.UInt16:
                                f.SetValue(obj, ReadArray <ushort>(result, dbIndex, array.Length));
                                break;

                            case TypeCode.Int32:
                                f.SetValue(obj, ReadArray <int>(result, dbIndex, array.Length));
                                break;

                            case TypeCode.UInt32:
                                f.SetValue(obj, ReadArray <uint>(result, dbIndex, array.Length));
                                break;

                            case TypeCode.Int64:
                                f.SetValue(obj, ReadArray <long>(result, dbIndex, array.Length));
                                break;

                            case TypeCode.UInt64:
                                f.SetValue(obj, ReadArray <ulong>(result, dbIndex, array.Length));
                                break;

                            case TypeCode.Single:
                                f.SetValue(obj, ReadArray <float>(result, dbIndex, array.Length));
                                break;

                            case TypeCode.String:
                                f.SetValue(obj, ReadArray <string>(result, dbIndex, array.Length));
                                break;

                            case TypeCode.Object:
                                if (arrayElementType == typeof(Vector3))
                                {
                                    float[] values = ReadArray <float>(result, dbIndex, array.Length * 3);

                                    Vector3[] vectors = new Vector3[array.Length];
                                    for (var i = 0; i < array.Length; ++i)
                                    {
                                        vectors[i] = new Vector3(values[(i * 3)..(3 + (i * 3))]);
Esempio n. 6
0
        public void LoadData(int indexField, DB6FieldInfo[] helpers, HotfixStatements preparedStatement, HotfixStatements preparedStatementLocale)
        {
            SQLResult result = DB.Hotfix.Query(DB.Hotfix.GetPreparedStatement(preparedStatement));

            if (!result.IsEmpty())
            {
                do
                {
                    var idValue = result.Read <uint>(indexField == -1 ? 0 : indexField);

                    var obj   = new T();
                    int index = 0;
                    for (var fieldIndex = 0; fieldIndex < helpers.Length; fieldIndex++)
                    {
                        var helper = helpers[fieldIndex];
                        if (helper.IsArray)
                        {
                            Array array = (Array)helper.Getter(obj);
                            for (var i = 0; i < array.Length; ++i)
                            {
                                switch (Type.GetTypeCode(helper.FieldType))
                                {
                                case TypeCode.SByte:
                                    helper.SetValue(array, result.Read <sbyte>(index++), i);
                                    break;

                                case TypeCode.Byte:
                                    helper.SetValue(array, result.Read <byte>(index++), i);
                                    break;

                                case TypeCode.Int16:
                                    helper.SetValue(array, result.Read <short>(index++), i);
                                    break;

                                case TypeCode.UInt16:
                                    helper.SetValue(array, result.Read <ushort>(index++), i);
                                    break;

                                case TypeCode.Int32:
                                    helper.SetValue(array, result.Read <int>(index++), i);
                                    break;

                                case TypeCode.UInt32:
                                    helper.SetValue(array, result.Read <uint>(index++), i);
                                    break;

                                case TypeCode.Single:
                                    helper.SetValue(array, result.Read <float>(index++), i);
                                    break;

                                case TypeCode.String:
                                    helper.SetValue(array, result.Read <string>(index++), i);
                                    break;

                                case TypeCode.Object:
                                    switch (helper.FieldType.Name)
                                    {
                                    case "Vector2":
                                        var vector2 = new Vector2();
                                        vector2.X = result.Read <float>(index++);
                                        vector2.Y = result.Read <float>(index++);
                                        helper.SetValue(array, vector2, i);
                                        break;

                                    case "Vector3":
                                        var vector3 = new Vector3();
                                        vector3.X = result.Read <float>(index++);
                                        vector3.Y = result.Read <float>(index++);
                                        vector3.Z = result.Read <float>(index++);
                                        helper.SetValue(array, vector3, i);
                                        break;

                                    case "LocalizedString":
                                        LocalizedString locString = new LocalizedString();
                                        locString[Global.WorldMgr.GetDefaultDbcLocale()] = result.Read <string>(index++);
                                        helper.SetValue(array, locString, i);
                                        break;

                                    default:
                                        Log.outError(LogFilter.ServerLoading, "Wrong Array Type: {0}", helper.FieldType.Name);
                                        break;
                                    }
                                    break;

                                default:
                                    Log.outError(LogFilter.ServerLoading, "Wrong Array Type: {0}", helper.FieldType.Name);
                                    break;
                                }
                            }
                        }
                        else
                        {
                            switch (Type.GetTypeCode(helper.FieldType))
                            {
                            case TypeCode.SByte:
                                helper.SetValue(obj, result.Read <sbyte>(index++));
                                break;

                            case TypeCode.Byte:
                                helper.SetValue(obj, result.Read <byte>(index++));
                                break;

                            case TypeCode.Int16:
                                helper.SetValue(obj, result.Read <short>(index++));
                                break;

                            case TypeCode.UInt16:
                                helper.SetValue(obj, result.Read <ushort>(index++));
                                break;

                            case TypeCode.Int32:
                                helper.SetValue(obj, result.Read <int>(index++));
                                break;

                            case TypeCode.UInt32:
                                helper.SetValue(obj, result.Read <uint>(index++));
                                break;

                            case TypeCode.Single:
                                helper.SetValue(obj, result.Read <float>(index++));
                                break;

                            case TypeCode.String:
                                string str = result.Read <string>(index++);
                                helper.SetValue(obj, str);
                                break;

                            case TypeCode.Object:
                                switch (helper.FieldType.Name)
                                {
                                case "Vector2":
                                    var vector2 = new Vector2();
                                    vector2.X = result.Read <float>(index++);
                                    vector2.Y = result.Read <float>(index++);
                                    helper.SetValue(obj, vector2);
                                    break;

                                case "Vector3":
                                    var vector3 = new Vector3();
                                    vector3.X = result.Read <float>(index++);
                                    vector3.Y = result.Read <float>(index++);
                                    vector3.Z = result.Read <float>(index++);
                                    helper.SetValue(obj, vector3);
                                    break;

                                case "LocalizedString":
                                    LocalizedString locString = new LocalizedString();
                                    locString[Global.WorldMgr.GetDefaultDbcLocale()] = result.Read <string>(index++);
                                    helper.SetValue(obj, locString);
                                    break;

                                default:
                                    Log.outError(LogFilter.ServerLoading, "Wrong Array Type: {0}", helper.FieldType.Name);
                                    break;
                                }
                                break;

                            default:
                                Log.outError(LogFilter.ServerLoading, "Wrong Array Type: {0}", helper.FieldType.Name);
                                break;
                            }
                        }
                    }

                    base[idValue] = obj;
                }while (result.NextRow());
            }

            if (preparedStatementLocale == 0)
            {
                return;
            }

            for (LocaleConstant locale = 0; locale < LocaleConstant.OldTotal; ++locale)
            {
                if (Global.WorldMgr.GetDefaultDbcLocale() == locale || locale == LocaleConstant.None)
                {
                    continue;
                }

                PreparedStatement stmt = DB.Hotfix.GetPreparedStatement(preparedStatementLocale);
                stmt.AddValue(0, locale.ToString());
                SQLResult localeResult = DB.Hotfix.Query(stmt);
                if (localeResult.IsEmpty())
                {
                    continue;
                }

                do
                {
                    int index = 0;
                    var obj   = this.LookupByKey(localeResult.Read <uint>(index++));
                    if (obj == null)
                    {
                        continue;
                    }

                    for (var i = 0; i < helpers.Length; i++)
                    {
                        var fieldInfo = helpers[i];
                        if (fieldInfo.FieldType != typeof(LocalizedString))
                        {
                            continue;
                        }

                        LocalizedString locString = (LocalizedString)fieldInfo.Getter(obj);
                        locString[locale] = localeResult.Read <string>(index++);
                    }
                } while (localeResult.NextRow());
            }
        }