예제 #1
0
        public void WriteRecord(uint id, LocaleConstant locale, ByteBuffer buffer)
        {
            T entry = this.LookupByKey(id);

            foreach (var fieldInfo in entry.GetType().GetFields())
            {
                if (fieldInfo.Name == "Id")
                {
                    continue;
                }

                var type = fieldInfo.FieldType;
                if (type.IsArray)
                {
                    WriteArrayValues(entry, fieldInfo, buffer);
                    continue;
                }

                switch (Type.GetTypeCode(type))
                {
                case TypeCode.Boolean:
                    buffer.WriteUInt8(fieldInfo.GetValue(entry));
                    break;

                case TypeCode.SByte:
                    buffer.WriteInt8(fieldInfo.GetValue(entry));
                    break;

                case TypeCode.Byte:
                    buffer.WriteUInt8(fieldInfo.GetValue(entry));
                    break;

                case TypeCode.Int16:
                    buffer.WriteInt16(fieldInfo.GetValue(entry));
                    break;

                case TypeCode.UInt16:
                    buffer.WriteUInt16(fieldInfo.GetValue(entry));
                    break;

                case TypeCode.Int32:
                    buffer.WriteInt32(fieldInfo.GetValue(entry));
                    break;

                case TypeCode.UInt32:
                    buffer.WriteUInt32(fieldInfo.GetValue(entry));
                    break;

                case TypeCode.Int64:
                    buffer.WriteInt64(fieldInfo.GetValue(entry));
                    break;

                case TypeCode.UInt64:
                    buffer.WriteUInt64(fieldInfo.GetValue(entry));
                    break;

                case TypeCode.Single:
                    buffer.WriteFloat(fieldInfo.GetValue(entry));
                    break;

                case TypeCode.Object:
                    switch (type.Name)
                    {
                    case "LocalizedString":
                        LocalizedString locStr = (LocalizedString)fieldInfo.GetValue(entry);
                        if (!locStr.HasString(locale))
                        {
                            locale = 0;
                            if (!locStr.HasString(locale))
                            {
                                buffer.WriteUInt16(0);
                                break;
                            }
                        }

                        string str = locStr[locale];
                        buffer.WriteCString(str);
                        break;
                    }
                    break;
                }
            }
        }
예제 #2
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());
            }
        }
예제 #3
0
        public T As <T>() where T : new()
        {
            _data.Position = 0;
            _data.Offset   = _dataOffset;

            int fieldIndex = 0;
            T   obj        = new T();

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

                if (f.Name == "Id" && !_dataHasId)
                {
                    f.SetValue(obj, (uint)Id);
                    continue;
                }

                if (fieldIndex >= _fieldMeta.Length)
                {
                    if (_refId != -1)
                    {
                        f.SetValue(obj, (uint)_refId);
                    }
                    continue;
                }

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

                    Array atr = (Array)f.GetValue(obj);
                    switch (Type.GetTypeCode(arrayElementType))
                    {
                    case TypeCode.SByte:
                        f.SetValue(obj, GetFieldValueArray <sbyte>(fieldIndex, atr.Length));
                        break;

                    case TypeCode.Byte:
                        f.SetValue(obj, GetFieldValueArray <byte>(fieldIndex, atr.Length));
                        break;

                    case TypeCode.Int16:
                        f.SetValue(obj, GetFieldValueArray <short>(fieldIndex, atr.Length));
                        break;

                    case TypeCode.UInt16:
                        f.SetValue(obj, GetFieldValueArray <ushort>(fieldIndex, atr.Length));
                        break;

                    case TypeCode.Int32:
                        f.SetValue(obj, GetFieldValueArray <int>(fieldIndex, atr.Length));
                        break;

                    case TypeCode.UInt32:
                        f.SetValue(obj, GetFieldValueArray <uint>(fieldIndex, atr.Length));
                        break;

                    case TypeCode.UInt64:
                        f.SetValue(obj, GetFieldValueArray <ulong>(fieldIndex, atr.Length));
                        break;

                    case TypeCode.Single:
                        f.SetValue(obj, GetFieldValueArray <float>(fieldIndex, atr.Length));
                        break;

                    case TypeCode.String:
                        string[] array = new string[atr.Length];

                        if (_stringsTable == null)
                        {
                            for (int i = 0; i < array.Length; i++)
                            {
                                array[i] = _data.ReadCString();
                            }
                        }
                        else
                        {
                            var pos = _recordsOffset + _data.Offset + (_data.Position >> 3);

                            int[] strIdx = GetFieldValueArray <int>(fieldIndex, atr.Length);

                            for (int i = 0; i < array.Length; i++)
                            {
                                array[i] = _stringsTable[pos + i * 4 + strIdx[i]];
                            }
                        }

                        f.SetValue(obj, array);
                        break;

                    case TypeCode.Object:
                        if (arrayElementType == typeof(Vector3))
                        {
                            float[] pos = GetFieldValueArray <float>(fieldIndex, atr.Length * 3);

                            Vector3[] vectors = new Vector3[atr.Length];
                            for (var i = 0; i < atr.Length; ++i)
                            {
                                vectors[i] = new Vector3(pos[i * 3], pos[(i * 3) + 1], pos[(i * 3) + 2]);
                            }

                            f.SetValue(obj, vectors);
                        }
                        break;

                    default:
                        throw new Exception("Unhandled array type: " + arrayElementType.Name);
                    }
                }
                else
                {
                    if (type.IsEnum)
                    {
                        type = type.GetEnumUnderlyingType();
                    }

                    switch (Type.GetTypeCode(type))
                    {
                    case TypeCode.Single:
                        f.SetValue(obj, GetFieldValue <float>(fieldIndex));
                        break;

                    case TypeCode.Int64:
                        f.SetValue(obj, GetFieldValue <long>(fieldIndex));
                        break;

                    case TypeCode.UInt64:
                        f.SetValue(obj, GetFieldValue <ulong>(fieldIndex));
                        break;

                    case TypeCode.Int32:
                        f.SetValue(obj, GetFieldValue <int>(fieldIndex));
                        break;

                    case TypeCode.UInt32:
                        f.SetValue(obj, GetFieldValue <uint>(fieldIndex));
                        break;

                    case TypeCode.Int16:
                        f.SetValue(obj, GetFieldValue <short>(fieldIndex));
                        break;

                    case TypeCode.UInt16:
                        f.SetValue(obj, GetFieldValue <ushort>(fieldIndex));
                        break;

                    case TypeCode.Byte:
                        f.SetValue(obj, GetFieldValue <byte>(fieldIndex));
                        break;

                    case TypeCode.SByte:
                        f.SetValue(obj, GetFieldValue <sbyte>(fieldIndex));
                        break;

                    case TypeCode.String:
                        if (_stringsTable == null)
                        {
                            f.SetValue(obj, _data.ReadCString());
                        }
                        else
                        {
                            var pos = _recordsOffset + _data.Offset + (_data.Position >> 3);
                            int ofs = GetFieldValue <int>(fieldIndex);
                            f.SetValue(obj, _stringsTable[pos + ofs]);
                        }
                        break;

                    case TypeCode.Object:
                        if (type == typeof(LocalizedString))
                        {
                            LocalizedString localized = new LocalizedString();
                            if (_stringsTable == null)
                            {
                                localized[LocaleConstant.enUS] = _data.ReadCString();
                            }
                            else
                            {
                                var pos = _recordsOffset + _data.Offset + (_data.Position >> 3);
                                int ofs = GetFieldValue <int>(fieldIndex);
                                localized[LocaleConstant.enUS] = _stringsTable[pos + ofs];
                            }

                            f.SetValue(obj, localized);
                        }
                        else if (type == typeof(Vector2))
                        {
                            float[] pos = GetFieldValueArray <float>(fieldIndex, 2);
                            f.SetValue(obj, new Vector2(pos));
                        }
                        else if (type == typeof(Vector3))
                        {
                            float[] pos = GetFieldValueArray <float>(fieldIndex, 3);
                            f.SetValue(obj, new Vector3(pos));
                        }
                        else if (type == typeof(FlagArray128))
                        {
                            uint[] flags = GetFieldValueArray <uint>(fieldIndex, 4);
                            f.SetValue(obj, new FlagArray128(flags));
                        }
                        break;
                    }
                }

                fieldIndex++;
            }

            return(obj);
        }