コード例 #1
0
ファイル: AbstractDBC.cs プロジェクト: zmyzy/WoW-Spell-Editor
        public Task ExportToDbc(IDatabaseAdapter adapter, MainWindow.UpdateProgressFunc updateProgress, string IdKey, string bindingName)
        {
            return(Task.Run(() =>
            {
                var binding = BindingManager.GetInstance().FindBinding(bindingName);
                if (binding == null)
                {
                    throw new Exception("Binding not found: " + bindingName);
                }

                var orderClause = binding.Fields.FirstOrDefault(f => f.Name.Equals(IdKey)) != null ? $" ORDER BY `{IdKey}`" : "";
                var rows = adapter.Query(string.Format($"SELECT * FROM `{bindingName}`{orderClause}")).Rows;
                uint numRows = uint.Parse(rows.Count.ToString());
                // Hardcode for 3.3.5a 12340
                Header = new DBCHeader();
                Header.FieldCount = (uint)binding.Fields.Count();
                Header.Magic = 1128416343;
                Header.RecordCount = numRows;
                Header.RecordSize = (uint)binding.CalcRecordSize();
                Header.StringBlockSize = 0;

                var body = new DBCBodyToSerialize();
                body.Records = new List <DataRow>((int)Header.RecordCount);
                for (int i = 0; i < numRows; ++i)
                {
                    body.Records.Add(rows[i]);
                }
                Header.StringBlockSize = body.GenerateStringOffsetsMap(binding);
                SaveDbcFile(updateProgress, body, binding);
            }));
        }
コード例 #2
0
        public Task ExportToDbc(IDatabaseAdapter adapter, MainWindow.UpdateProgressFunc updateProgress, string IdKey, string bindingName)
        {
            return(Task.Run(() =>
            {
                var binding = BindingManager.GetInstance().FindBinding(bindingName);
                if (binding == null)
                {
                    throw new Exception("Binding not found: " + bindingName);
                }
                var body = new DBCBodyToSerialize();

                var orderClause = "";
                if (binding.OrderOutput)
                {
                    orderClause = binding.Fields.FirstOrDefault(f => f.Name.Equals(IdKey)) != null ? $" ORDER BY `{IdKey}`" : "";
                }

                body.Records = LoadRecords(adapter, bindingName, orderClause, updateProgress);
                var numRows = body.Records.Count();
                if (numRows == 0)
                {
                    throw new Exception("No rows to export");
                }

                Header = new DBCHeader
                {
                    FieldCount = (uint)binding.Fields.Count(),
                    // Magic is always 'WDBC' https://wowdev.wiki/DBC
                    Magic = 1128416343,
                    RecordCount = (uint)numRows,
                    RecordSize = (uint)binding.CalcRecordSize(),
                    StringBlockSize = body.GenerateStringOffsetsMap(binding)
                };

                SaveDbcFile(updateProgress, body, binding);
            }));
        }
コード例 #3
0
ファイル: SpellDBC.cs プロジェクト: ydxjj/Spell-Editor-GUI-V2
        public Task export(DBAdapter adapter, MainWindow.UpdateProgressFunc updateProgress)
        {
            return(Task.Run(() =>
            {
                var rows = adapter.query(string.Format("SELECT * FROM `{0}` ORDER BY `ID`", adapter.Table)).Rows;
                uint numRows = UInt32.Parse(rows.Count.ToString());
                // Hardcode for 3.3.5a 12340
                header = new DBC_Header();
                header.FieldCount = 234;
                header.Magic = 1128416343;
                header.RecordCount = numRows;
                header.RecordSize = 936;
                header.StringBlockSize = 0;

                body.records = new Spell_DBC_RecordMap[numRows];
                for (int i = 0; i < numRows; ++i)
                {
                    body.records[i] = new Spell_DBC_RecordMap();
                    if (i % 250 == 0)
                    {
                        updateProgress((double)i / (double)numRows);
                    }
                    body.records[i].record = new Spell_DBC_Record();
                    body.records[i].spellName = new string[9];
                    body.records[i].spellDesc = new string[9];
                    body.records[i].spellRank = new string[9];
                    body.records[i].spellTool = new string[9];
                    body.records[i].record.SpellName = new UInt32[9];
                    body.records[i].record.SpellDescription = new UInt32[9];
                    body.records[i].record.SpellRank = new UInt32[9];
                    body.records[i].record.SpellToolTip = new UInt32[9];
                    body.records[i].record.SpellNameFlag = new UInt32[8];
                    body.records[i].record.SpellDescriptionFlags = new UInt32[8];
                    body.records[i].record.SpellRankFlags = new UInt32[8];
                    body.records[i].record.SpellToolTipFlags = new UInt32[8];
                    var fields = body.records[i].record.GetType().GetFields();
                    foreach (var f in fields)
                    {
                        switch (Type.GetTypeCode(f.FieldType))
                        {
                        case TypeCode.UInt32:
                            {
                                f.SetValueForValueType(ref body.records[i].record, UInt32.Parse(rows[i][f.Name].ToString()));
                                break;
                            }

                        case TypeCode.Int32:
                            {
                                f.SetValueForValueType(ref body.records[i].record, Int32.Parse(rows[i][f.Name].ToString()));
                                break;
                            }

                        case TypeCode.Single:
                            {
                                f.SetValueForValueType(ref body.records[i].record, Single.Parse(rows[i][f.Name].ToString()));
                                break;
                            }

                        case TypeCode.Object:
                            {
                                var attr = f.GetCustomAttribute <HandleField>();
                                if (attr != null)
                                {
                                    if (attr.Method == 1)
                                    {
                                        switch (attr.Type)
                                        {
                                        case 1:
                                            {
                                                for (int j = 0; j < attr.Count; ++j)
                                                {
                                                    body.records[i].spellName[j] = rows[i]["SpellName" + j].ToString();
                                                }
                                                break;
                                            }

                                        case 2:
                                            {
                                                for (int j = 0; j < attr.Count; ++j)
                                                {
                                                    body.records[i].spellRank[j] = rows[i]["SpellRank" + j].ToString();
                                                }
                                                break;
                                            }

                                        case 3:
                                            {
                                                for (int j = 0; j < attr.Count; ++j)
                                                {
                                                    body.records[i].spellDesc[j] = rows[i]["SpellDescription" + j].ToString();
                                                }
                                                break;
                                            }

                                        case 4:
                                            {
                                                for (int j = 0; j < attr.Count; ++j)
                                                {
                                                    body.records[i].spellTool[j] = rows[i]["SpellToolTip" + j].ToString();
                                                }
                                                break;
                                            }

                                        default:
                                            throw new Exception("ERROR: Unhandled type: " + f.FieldType + " on field: " + f.Name + " TYPE: " + attr.Type);
                                        }
                                        break;
                                    }
                                    else if (attr.Method == 2)
                                    {
                                        switch (attr.Type)
                                        {
                                        case 1:
                                            {
                                                for (int j = 0; j < attr.Count; ++j)
                                                {
                                                    body.records[i].record.SpellNameFlag[j] = UInt32.Parse(rows[i]["SpellNameFlag" + j].ToString());
                                                }
                                                break;
                                            }

                                        case 2:
                                            {
                                                for (int j = 0; j < attr.Count; ++j)
                                                {
                                                    body.records[i].record.SpellRankFlags[j] = UInt32.Parse(rows[i]["SpellRankFlags" + j].ToString());
                                                }
                                                break;
                                            }

                                        case 3:
                                            {
                                                for (int j = 0; j < attr.Count; ++j)
                                                {
                                                    body.records[i].record.SpellDescriptionFlags[j] = UInt32.Parse(rows[i]["SpellDescriptionFlags" + j].ToString());
                                                }
                                                break;
                                            }

                                        case 4:
                                            {
                                                for (int j = 0; j < attr.Count; ++j)
                                                {
                                                    body.records[i].record.SpellToolTipFlags[j] = UInt32.Parse(rows[i]["SpellToolTipFlags" + j].ToString());
                                                }
                                                break;
                                            }

                                        default:
                                            throw new Exception("ERROR: Unhandled type: " + f.FieldType + " on field: " + f.Name + " TYPE: " + attr.Type);
                                        }
                                        break;
                                    }
                                }
                                goto default;
                            }

                        default:
                            throw new Exception("Unhandled type: " + Type.GetTypeCode(f.FieldType).ToString() + ", field: " + f.Name);
                        }
                    }
                }
                SaveDBCFile();
            }));
        }
コード例 #4
0
ファイル: AbstractDBC.cs プロジェクト: zmyzy/WoW-Spell-Editor
        public Task ImportToSql(IDatabaseAdapter adapter, MainWindow.UpdateProgressFunc UpdateProgress, string IdKey, string bindingName)
        {
            return(Task.Run(() =>
            {
                var binding = BindingManager.GetInstance().FindBinding(bindingName);
                adapter.Execute(string.Format(adapter.GetTableCreateString(binding), binding.Name));
                uint currentRecord = 0;
                uint count = Header.RecordCount;
                uint updateRate = count < 100 ? 100 : count / 100;
                uint index = 0;
                StringBuilder q = null;
                foreach (var recordMap in Body.RecordMaps)
                {
                    // This might be needed? Disabled unless bugs are reported around this
                    //if (r.record.ID == 0)
                    //  continue;
                    if (index == 0 || index % 250 == 0)
                    {
                        if (q != null)
                        {
                            q.Remove(q.Length - 2, 2);
                            adapter.Execute(q.ToString());
                        }
                        q = new StringBuilder();
                        q.Append(string.Format("INSERT INTO `{0}` VALUES ", bindingName));
                    }
                    if (++index % updateRate == 0)
                    {
                        // Visual studio says these casts are redundant but it does not work without them
                        double percent = (double)index / (double)count;
                        UpdateProgress(percent);
                    }
                    currentRecord = recordMap.ContainsKey(IdKey) ? (uint)recordMap[IdKey] : 0;
                    q.Append("(");
                    foreach (var field in binding.Fields)
                    {
                        switch (field.Type)
                        {
                        case BindingType.INT:
                        case BindingType.UINT:
                            {
                                q.Append(string.Format("'{0}', ", recordMap[field.Name]));
                                break;
                            }

                        case BindingType.FLOAT:
                        case BindingType.DOUBLE:
                            {
                                q.Append(string.Format("REPLACE('{0}', ',', '.'), ", recordMap[field.Name]));
                                break;
                            }

                        case BindingType.STRING_OFFSET:
                            {
                                var strOffset = (uint)recordMap[field.Name];
                                var lookupResult = Reader.LookupStringOffset(strOffset);
                                q.Append(string.Format("\'{0}\', ", adapter.EscapeString(lookupResult)));
                                break;
                            }

                        case BindingType.UNKNOWN:
                            break;

                        default:
                            throw new Exception($"ERROR: Record[{currentRecord}] Unhandled type: {field.Type} on field: {field.Name}");
                        }
                    }
                    q.Remove(q.Length - 2, 2);
                    q.Append("), ");
                }
                if (q.Length > 0)
                {
                    q.Remove(q.Length - 2, 2);
                    adapter.Execute(q.ToString());
                }
                // We have attempted to import the Spell.dbc so clean up unneeded data
                // This will be recreated if the import process is started again
                Reader.CleanStringsMap();
            }));
        }
コード例 #5
0
ファイル: AbstractDBC.cs プロジェクト: zmyzy/WoW-Spell-Editor
        protected void SaveDbcFile(MainWindow.UpdateProgressFunc updateProgress, DBCBodyToSerialize body, Binding.Binding binding)
        {
            string path = $"Export/{binding.Name}.dbc";

            Directory.CreateDirectory(Path.GetDirectoryName(path));
            if (File.Exists(path))
            {
                File.Delete(path);
            }
            using (FileStream fileStream = new FileStream(path, FileMode.Create))
            {
                using (BinaryWriter writer = new BinaryWriter(fileStream))
                {
                    // Write the header file
                    int      count  = Marshal.SizeOf(typeof(DBCHeader));
                    byte[]   buffer = new byte[count];
                    GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
                    Marshal.StructureToPtr(Header, handle.AddrOfPinnedObject(), true);
                    writer.Write(buffer, 0, count);
                    handle.Free();
                    // Write each record
                    for (int i = 0; i < Header.RecordCount; ++i)
                    {
                        if (i % 250 == 0)
                        {
                            // Visual studio says these casts are redundant but it does not work without them
                            double percent = (double)i / (double)Header.RecordCount;
                            updateProgress(percent);
                        }
                        var record = body.Records[i];
                        foreach (var entry in binding.Fields)
                        {
                            if (!record.Table.Columns.Contains(entry.Name))
                            {
                                throw new Exception($"Column binding not found {entry.Name} in table, using binding {binding.Name}.txt");
                            }
                            var data = record[entry.Name].ToString();
                            if (entry.Type == BindingType.INT)
                            {
                                if (int.TryParse(data, out int value))
                                {
                                    writer.Write(value);
                                }
                                else
                                {
                                    writer.Write(0);
                                }
                            }
                            else if (entry.Type == BindingType.UINT)
                            {
                                if (uint.TryParse(data, out uint value))
                                {
                                    writer.Write(value);
                                }
                                else
                                {
                                    writer.Write(0u);
                                }
                            }
                            else if (entry.Type == BindingType.FLOAT)
                            {
                                if (float.TryParse(data, out float value))
                                {
                                    writer.Write(value);
                                }
                                else
                                {
                                    writer.Write(0f);
                                }
                            }
                            else if (entry.Type == BindingType.DOUBLE)
                            {
                                if (double.TryParse(data, out double value))
                                {
                                    writer.Write(value);
                                }
                                else
                                {
                                    writer.Write(0d);
                                }
                            }
                            else if (entry.Type == BindingType.STRING_OFFSET)
                            {
                                writer.Write(data.Length == 0 ? 0 : body.OffsetStorage[data.GetHashCode()]);
                            }
                            else
                            {
                                throw new Exception($"Unknwon type: {entry.Type} on entry {entry.Name} binding {binding.Name}");
                            }
                        }
                    }
                    // Write string block
                    int[] offsetsStored = body.OffsetStorage.Values.ToArray();
                    writer.Write(Encoding.UTF8.GetBytes("\0"));
                    for (int i = 0; i < offsetsStored.Length; ++i)
                    {
                        writer.Write(Encoding.UTF8.GetBytes(body.ReverseStorage[offsetsStored[i]] + "\0"));
                    }
                }
            }
        }
コード例 #6
0
        protected List <Dictionary <string, object> > LoadRecords(IDatabaseAdapter adapter, string bindingName, string orderClause, MainWindow.UpdateProgressFunc updateProgress)
        {
            const int pageSize = 1000;
            int       totalCount;

            using (var queryData = adapter.Query($"SELECT COUNT(*) FROM `{bindingName}`"))
            {
                totalCount = int.Parse(queryData.Rows[0][0].ToString());
            }
            var lowerBounds = 0;
            var results     = LoadRecordPage(lowerBounds, pageSize, adapter, bindingName, orderClause);
            var loadCount   = results.Count;

            while (loadCount > 0)
            {
                lowerBounds += pageSize;
                // Visual studio says these casts are redundant but it does not work without them
                double percent = (double)Math.Min(totalCount, lowerBounds) / (double)totalCount;
                updateProgress(percent);
                var page = LoadRecordPage(lowerBounds, pageSize, adapter, bindingName, orderClause);
                loadCount = page.Count;
                page.ForEach(results.Add);
            }
            return(results);
        }
コード例 #7
0
ファイル: SpellDBC.cs プロジェクト: yuanf225/WoW-Spell-Editor
 public Task Export(IDatabaseAdapter adapter, MainWindow.UpdateProgressFunc updateProgress)
 {
     return(ExportToDbc(adapter, updateProgress, "ID", "Spell"));
 }
コード例 #8
0
ファイル: SpellDBC.cs プロジェクト: yuanf225/WoW-Spell-Editor
 public Task ImportToSql(IDatabaseAdapter adapter, MainWindow.UpdateProgressFunc UpdateProgress, string bindingName)
 {
     return(ImportToSql(adapter, UpdateProgress, "ID", bindingName));
 }