示例#1
0
        private string GuessDBCVersion(Dictionary <String, DBCConfig> dbc_config)
        {
            foreach (string dbc_version in dbc_config.Keys)
            {
                if (!File.Exists(Properties.Settings.Default.DBC + "\\" + dbc_config[dbc_version].offsets[StorageType.Spell].file))
                {
                    break;
                }

                string          fileName = Properties.Settings.Default.DBC + "\\" + dbc_config[dbc_version].offsets[StorageType.Spell].file;
                IClientDBReader m_reader = DBReaderFactory.GetReader(fileName);
                BinaryReader    br       = m_reader.Rows.ElementAt(0);
                int             id       = br.ReadInt32();
                for (int i = 0; i < dbc_config[dbc_version].offsets[StorageType.Spell].nameOffset; i++)
                {
                    br.ReadInt32();
                }

                id = br.ReadInt32();
                if (m_reader.StringTable.ContainsKey(id) && !String.IsNullOrEmpty(m_reader.StringTable[id]))
                {
                    return(dbc_version);
                }
            }
            return(null);
        }
示例#2
0
        public IEnumerable <T> LoadDBCObject <T>(Type type, string fileName) where T : IDBObjectReader, new()
        {
            string     fullFilePath = Path.Combine(AssemblyUtils.ExecutingAssemblyPath, fileName);
            XmlElement definition   = GetDefinition(Path.GetFileNameWithoutExtension(fileName),
                                                    Path.GetFileName(fullFilePath));

            IWowClientDBReader dbReader;

            try
            {
                dbReader = DBReaderFactory.GetReader(fullFilePath, definition);
            }
            catch (Exception)
            {
                DialogResult result = MessageBox.Show($"Could not get load file \"{fileName}\", make sure it exists in the program root directory", "Load error", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
                if (result == DialogResult.Retry)
                {
                    return(LoadDBCObject <T>(type, fileName));
                }

                return(new List <T>());
            }

            IList <T> objects = new List <T>();

            foreach (var row in dbReader.Rows)
            {
                T t = new T();
                t.ReadObject(dbReader, row, _dbcDataStore, _dbDataStore);
                objects.Add(t);
            }

            return(objects);
        }
示例#3
0
        private void Load(string filename, Func <BinaryReader, Dictionary <int, string>, string> func)
        {
            if (filename != "AreaTrigger.dbc")
            {
                return;
            }

            if (!File.Exists(Properties.Settings.Default.DBC + "\\" + filename))
            {
                return;
            }
            IClientDBReader m_reader = DBReaderFactory.GetReader(Properties.Settings.Default.DBC + "\\" + filename);

            if (m_reader.StringTable != null)
            {
                int i = 0;
                foreach (var br in m_reader.Rows) // Add rows
                {
                    if (func != null)
                    {
                        int id = br.ReadInt32();
                        values[id] = func(br, m_reader.StringTable);
                    }
                    else
                    {
                        return;
                    }
                }
            }
        }
示例#4
0
        private void Load(string filename, Func <BinaryReader, Dictionary <int, string>, List <ColumnMeta>, Tuple <Int32, string> > func = null)
        {
            if (!File.Exists(Properties.Settings.Default.DBC + "\\" + filename))
            {
                return;
            }
            IClientDBReader m_reader = DBReaderFactory.GetReader(Properties.Settings.Default.DBC + "\\" + filename);

            if (m_reader.StringTable != null)
            {
                int i = 0;
                foreach (var br in m_reader.Rows) // Add rows
                {
                    List <ColumnMeta> meta = null;

                    if (m_reader is DB5Reader)
                    {
                        meta = (m_reader as DB5Reader).Meta;
                    }

                    if (m_reader is DB6Reader)
                    {
                        meta = (m_reader as DB6Reader).Meta;
                    }

                    Tuple <Int32, string> idAndName;
                    if (func != null)
                    {
                        idAndName = func(br, m_reader.StringTable, meta);
                        values[idAndName.Item1] = idAndName.Item2;
                    }
                    else if (m_reader is DBCReader || m_reader is DB2Reader)
                    {
                        int id = br.ReadInt32();
                        values[id] = dbcFunc(br, m_reader.StringTable);
                    }
                    else
                    {
                        idAndName = defaultFunc(br, m_reader.StringTable, meta);
                        values[idAndName.Item1] = idAndName.Item2;
                    }

                    if (i % 10000 == 0)
                    {
                        _db.SetCurrentAction(filename + " (" + ++i + "/" + m_reader.RecordsCount + ")");
                    }
                }
            }
        }
        /// <summary>
        /// Get DataTable from DBC file, can be modified to support other versions of WoW
        /// </summary>
        /// <param name="DbcName">DBC file name without ext</param>
        /// <returns></returns>
        public static DataTable LoadDbc(string dbcName, string[] returnColumns, int build = 12340)
        {
            if (!VerifyDbcDir())
            {
                DataTable error = new DataTable();
                foreach (string col in returnColumns)
                {
                    error.Columns.Add(col);
                }
                error.Rows.Add("Failed to load DBC file.");
                return(error);
            }

            string file       = GetDbcFilePath(dbcName);
            var    m_dbreader = DBReaderFactory.GetReader(file);

            // Filter definitions
            XmlDocument m_definitions = new XmlDocument();

            m_definitions.LoadXml(Properties.Resources.dbclayout);

            // Get correct definition
            XmlElement m_definition = (XmlElement)m_definitions.SelectSingleNode("/DBFilesClient/" + dbcName + "[@build='" + build + "']");

            if (m_definition == null) // try with build 0
            {
                m_definition = (XmlElement)m_definitions.SelectSingleNode("/DBFilesClient/" + dbcName + "[@build='0']");
            }
            if (m_definition == null) // return error
            {
                DataTable error = new DataTable();
                error.Columns.Add("Error");
                error.Rows.Add("No definitions for this table on this build.");
                return(error);
            }

            var m_fields = m_definition.GetElementsByTagName("field");

            string[] types = new string[m_fields.Count];
            for (int j = 0; j < m_fields.Count; ++j)
            {
                types[j] = m_fields[j].Attributes["type"].Value;
            }
            var m_dataTable = new DataTable(dbcName);

            m_dataTable.Locale = CultureInfo.InvariantCulture;

            // Create columns
            foreach (XmlElement field in m_fields)
            {
                var colName = field.Attributes["name"].Value;

                switch (field.Attributes["type"].Value)
                {
                case "long":
                    m_dataTable.Columns.Add(colName, typeof(long));
                    break;

                case "ulong":
                    m_dataTable.Columns.Add(colName, typeof(ulong));
                    break;

                case "int":
                    m_dataTable.Columns.Add(colName, typeof(int));
                    break;

                case "uint":
                    m_dataTable.Columns.Add(colName, typeof(uint));
                    break;

                case "short":
                    m_dataTable.Columns.Add(colName, typeof(short));
                    break;

                case "ushort":
                    m_dataTable.Columns.Add(colName, typeof(ushort));
                    break;

                case "sbyte":
                    m_dataTable.Columns.Add(colName, typeof(sbyte));
                    break;

                case "byte":
                    m_dataTable.Columns.Add(colName, typeof(byte));
                    break;

                case "float":
                    m_dataTable.Columns.Add(colName, typeof(float));
                    break;

                case "double":
                    m_dataTable.Columns.Add(colName, typeof(double));
                    break;

                case "string":
                    m_dataTable.Columns.Add(colName, typeof(string));
                    break;

                default:
                    throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "Unknown field type {0}!", field.Attributes["type"].Value));
                }
            }

            // Create indexes
            XmlNodeList indexes = m_definition.GetElementsByTagName("index");
            var         columns = new DataColumn[indexes.Count];
            var         idx     = 0;

            foreach (XmlElement index in indexes)
            {
                columns[idx++] = m_dataTable.Columns[index["primary"].InnerText];
            }
            m_dataTable.PrimaryKey = columns;

            // Create rows
            foreach (var row in m_dbreader.Rows) // Add rows
            {
                DataRow dataRow = m_dataTable.NewRow();

                using (BinaryReader br = row)
                {
                    for (int j = 0; j < m_fields.Count; ++j)    // Add cells
                    {
                        switch (types[j])
                        {
                        case "long":
                            dataRow[j] = br.ReadInt64();
                            break;

                        case "ulong":
                            dataRow[j] = br.ReadUInt64();
                            break;

                        case "int":
                            dataRow[j] = br.ReadInt32();
                            break;

                        case "uint":
                            dataRow[j] = br.ReadUInt32();
                            break;

                        case "short":
                            dataRow[j] = br.ReadInt16();
                            break;

                        case "ushort":
                            dataRow[j] = br.ReadUInt16();
                            break;

                        case "sbyte":
                            dataRow[j] = br.ReadSByte();
                            break;

                        case "byte":
                            dataRow[j] = br.ReadByte();
                            break;

                        case "float":
                            dataRow[j] = br.ReadSingle();
                            break;

                        case "double":
                            dataRow[j] = br.ReadDouble();
                            break;

                        case "string":
                            if (m_dbreader is WDBReader)
                            {
                                dataRow[j] = br.ReadStringNull();
                            }
                            else if (m_dbreader is STLReader)
                            {
                                int offset = br.ReadInt32();
                                dataRow[j] = (m_dbreader as STLReader).ReadString(offset);
                            }
                            else
                            {
                                try
                                {
                                    dataRow[j] = m_dbreader.StringTable[br.ReadInt32()];
                                }
                                catch
                                {
                                    dataRow[j] = "Invalid string index!";
                                }
                            }
                            break;

                        default:
                            throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "Unknown field type {0}!", types[j]));
                        }
                    }
                }

                m_dataTable.Rows.Add(dataRow);
            }

            return(m_dataTable.DefaultView.ToTable(false, returnColumns));
        }
        /// <summary>
        /// Get DataTable from DBC file, can be modified to support other versions of WoW
        /// </summary>
        /// <param name="DbcName">DBC file name without ext</param>
        /// <returns></returns>
        public static DataTable LoadDbc(string dbcName, string[] returnColumns, int build = 12340)
        {
            if (!VerifyDbcDir())
            {
                DataTable error = new DataTable();
                foreach (string col in returnColumns)
                {
                    error.Columns.Add(col);
                }
                error.Rows.Add("Failed to load DBC file.");
                Logger.Log($"DBC: Error loading DBC file {dbcName}. Likely not configured correctly.", Logger.Status.Warning);
                return(error);
            }

            string file       = GetDbcFilePath(dbcName);
            var    m_dbreader = DBReaderFactory.GetReader(file);

            Logger.Log($"DBC: Attempting to load DBC file: {file}");

            // Filter definitions
            XmlDocument m_definitions = new XmlDocument();

            m_definitions.LoadXml(Properties.Resources.dbclayout);

            // Get correct definition
            XmlElement m_definition = (XmlElement)m_definitions.SelectSingleNode("/DBFilesClient/" + dbcName + "[@build='" + build + "']");

            if (m_definition == null) // try with build 0
            {
                m_definition = (XmlElement)m_definitions.SelectSingleNode("/DBFilesClient/" + dbcName + "[@build='0']");
            }
            if (m_definition == null) // return error
            {
                DataTable error = new DataTable();
                error.Columns.Add("Error");
                error.Rows.Add("No definitions for this table on this build.");
                return(error);
            }

            var m_fields = m_definition.GetElementsByTagName("field");

            string[] types = new string[m_fields.Count];
            for (int j = 0; j < m_fields.Count; ++j)
            {
                types[j] = m_fields[j].Attributes["type"].Value;
            }
            var m_dataTable = new DataTable(dbcName);

            m_dataTable.Locale = CultureInfo.InvariantCulture;

            // Create columns
            foreach (XmlElement field in m_fields)
            {
                var colName = field.Attributes["name"].Value;

                switch (field.Attributes["type"].Value)
                {
                case "long":
                    m_dataTable.Columns.Add(colName, typeof(long));
                    break;

                case "ulong":
                    m_dataTable.Columns.Add(colName, typeof(ulong));
                    break;

                case "int":
                    m_dataTable.Columns.Add(colName, typeof(int));
                    break;

                case "uint":
                    m_dataTable.Columns.Add(colName, typeof(uint));
                    break;

                case "short":
                    m_dataTable.Columns.Add(colName, typeof(short));
                    break;

                case "ushort":
                    m_dataTable.Columns.Add(colName, typeof(ushort));
                    break;

                case "sbyte":
                    m_dataTable.Columns.Add(colName, typeof(sbyte));
                    break;

                case "byte":
                    m_dataTable.Columns.Add(colName, typeof(byte));
                    break;

                case "float":
                    m_dataTable.Columns.Add(colName, typeof(float));
                    break;

                case "double":
                    m_dataTable.Columns.Add(colName, typeof(double));
                    break;

                case "string":
                    m_dataTable.Columns.Add(colName, typeof(string));
                    break;

                default:
                    throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "Unknown field type {0}!", field.Attributes["type"].Value));
                }
            }

            // Create indexes
            XmlNodeList indexes = m_definition.GetElementsByTagName("index");
            var         columns = new DataColumn[indexes.Count];
            var         idx     = 0;

            foreach (XmlElement index in indexes)
            {
                columns[idx++] = m_dataTable.Columns[index["primary"].InnerText];
            }
            m_dataTable.PrimaryKey = columns;

            try
            {
                // Create rows
                foreach (var row in m_dbreader.Rows) // Add rows
                {
                    DataRow dataRow = m_dataTable.NewRow();

                    using (BinaryReader br = row)
                    {
                        for (int j = 0; j < m_fields.Count; ++j)    // Add cells
                        {
                            switch (types[j])
                            {
                            case "long":
                                dataRow[j] = br.ReadInt64();
                                break;

                            case "ulong":
                                dataRow[j] = br.ReadUInt64();
                                break;

                            case "int":
                                dataRow[j] = br.ReadInt32();
                                break;

                            case "uint":
                                dataRow[j] = br.ReadUInt32();
                                break;

                            case "short":
                                dataRow[j] = br.ReadInt16();
                                break;

                            case "ushort":
                                dataRow[j] = br.ReadUInt16();
                                break;

                            case "sbyte":
                                dataRow[j] = br.ReadSByte();
                                break;

                            case "byte":
                                dataRow[j] = br.ReadByte();
                                break;

                            case "float":
                                dataRow[j] = br.ReadSingle();
                                break;

                            case "double":
                                dataRow[j] = br.ReadDouble();
                                break;

                            case "string":
                                if (m_dbreader is WDBReader)
                                {
                                    dataRow[j] = br.ReadStringNull();
                                }
                                else if (m_dbreader is STLReader)
                                {
                                    int offset = br.ReadInt32();
                                    dataRow[j] = (m_dbreader as STLReader).ReadString(offset);
                                }
                                else
                                {
                                    try
                                    {
                                        dataRow[j] = m_dbreader.StringTable[br.ReadInt32()];
                                    }
                                    catch
                                    {
                                        dataRow[j] = "Invalid string index!";
                                    }
                                }
                                break;

                            default:
                                throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "Unknown field type {0}!", types[j]));
                            }
                        }
                    }

                    m_dataTable.Rows.Add(dataRow);
                }
            }
            catch
            {
                // Lazy catch. See issue #104. Optimally relevant data should be hardcoded in the application with version restrictions
                // or definitions for all DBC files of all wow versions should be added to the current system.
                Logger.Log("DBC: Unexpected data structure or corrupt DBC file. Please ensure that you're using 3.3.5a DBC files.",
                           Logger.Status.Error, true);
            }

            Logger.Log($"DBC: Successfully prepared datatable for {dbcName}.dbc.");
            return(m_dataTable.DefaultView.ToTable(false, returnColumns));
        }