Пример #1
0
        private static void DoExport(string exportFormat, string outDir, params string[] files)
        {
            JsonSerializer jsonserializer = new JsonSerializer {
                NullValueHandling = NullValueHandling.Ignore
            };
            DBDXMLSerializer xmlserializer = new DBDXMLSerializer();

            foreach (var file in files)
            {
                Console.WriteLine("Exporting " + file);

                var reader = new DBDReader();
                var target = Path.Combine(outDir, Path.ChangeExtension(Path.GetFileName(file), exportFormat));

                Console.WriteLine($"Saving {exportFormat.ToUpper()} to {target}");
                using (StreamWriter writer = File.CreateText(target))
                {
                    switch (exportFormat)
                    {
                    case "json":
                        jsonserializer.Serialize(writer, reader.Read(file));
                        break;

                    case "xml":
                        xmlserializer.Serialize(writer, reader.Read(file));
                        break;
                    }
                }
            }
        }
Пример #2
0
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Usage: <definitionsdir>");
                Environment.Exit(1);
            }

            var definitionDir = args[0];

            var rewrite = true;

            foreach (var file in Directory.GetFiles(definitionDir))
            {
                var dbName = Path.GetFileNameWithoutExtension(file);

                var reader = new DBDReader();
                definitionCache.Add(dbName, reader.Read(file, true));

                Console.WriteLine("Read " + definitionCache[dbName].versionDefinitions.Length + " versions and " + definitionCache[dbName].columnDefinitions.Count + " columns for " + dbName);
                if (rewrite)
                {
                    var writer = new DBDWriter();
                    writer.Save(definitionCache[dbName], Path.Combine(definitionDir, dbName + ".dbd"));
                }
            }

            Console.WriteLine("Read " + definitionCache.Count + " database definitions!");

            var foreignKeys = 0;

            foreach (var definition in definitionCache)
            {
                foreach (var columnDefinition in definition.Value.columnDefinitions)
                {
                    if (!string.IsNullOrEmpty(columnDefinition.Value.foreignTable) || !string.IsNullOrEmpty(columnDefinition.Value.foreignColumn))
                    {
                        if (definitionCache.ContainsKey(columnDefinition.Value.foreignTable) && definitionCache[columnDefinition.Value.foreignTable].columnDefinitions.ContainsKey(columnDefinition.Value.foreignColumn))
                        {
                            Console.ForegroundColor = ConsoleColor.Green;
                            //Console.WriteLine(definition.Key + "." + columnDefinition.Key + " has a foreign key to " + columnDefinition.Value.foreignTable + "." + columnDefinition.Value.foreignColumn);
                        }
                        else
                        {
                            Console.ForegroundColor = ConsoleColor.Red;
                            Console.WriteLine(definition.Key + "." + columnDefinition.Key + " has a foreign key to " + columnDefinition.Value.foreignTable + "." + columnDefinition.Value.foreignColumn + " WHICH DOES NOT EXIST!");
                        }

                        foreignKeys++;

                        Console.ResetColor();
                    }
                }
            }

            Console.WriteLine("Checked " + foreignKeys + " foreign keys!");

            Console.WriteLine("Done, press enter to exit");
            Console.ReadLine();
        }
Пример #3
0
        static void Main(string[] args)
        {
            if (args.Length < 1 || args.Length > 3)
            {
                throw new ArgumentException("Invalid argument count, need at least 1 argument: indbdfile/indbddir (outdir, default current dir) (json)");
            }

            var inFile       = args[0];
            var outDir       = Directory.GetCurrentDirectory();
            var exportFormat = "json";

            if (args.Length >= 2)
            {
                outDir = args[1];
                if (!Directory.Exists(outDir))
                {
                    Directory.CreateDirectory(outDir);
                }
            }

            if (args.Length == 3)
            {
                if (args[2] == "json")
                {
                    exportFormat = args[2];
                }
                else
                {
                    throw new ArgumentException("Export format should be json");
                }
            }

            if (Directory.Exists(args[0]))
            {
                foreach (var file in Directory.GetFiles(args[0]))
                {
                    var reader = new DBDReader();
                    Console.WriteLine("Exporting " + file);
                    if (exportFormat == "json")
                    {
                        var target = Path.Combine(outDir, Path.GetFileNameWithoutExtension(file) + ".json");;
                        ExportJSON(reader.Read(file), target);
                    }
                }
            }
            else if (File.Exists(args[0]))
            {
                var reader = new DBDReader();
                Console.WriteLine("Exporting " + args[0]);
                if (exportFormat == "json")
                {
                    var target = Path.Combine(outDir, Path.GetFileNameWithoutExtension(args[0]) + ".json");;
                    ExportJSON(reader.Read(args[0]), target);
                }
            }
            else
            {
                throw new FileNotFoundException("Unable to find directory/file " + args[0]);
            }
        }
Пример #4
0
        public VersionDefinitions[] GetVersionDefinitionsForDB2(string db2File)
        {
            var dbdStream          = dbdProvider.StreamForTableName(db2File, null);
            var dbdReader          = new DBDReader();
            var databaseDefinition = dbdReader.Read(dbdStream);

            return(databaseDefinition.versionDefinitions);
        }
Пример #5
0
        private void ValidateDefinition()
        {
            Regex  buildmatch = new Regex(@"\d\.\d{1,2}.\d.\d{4,}", RegexOptions.Compiled);
            string file       = Path.GetFileNameWithoutExtension(txtFile1.Text).ToUpper();

            Dictionary <Build, string> dbbuilds = new Dictionary <Build, string>();

            foreach (var db in AllDBs[file])
            {
                dbbuilds.Add(new Build(Directory.GetParent(db).Name.ToUpper().Replace("A", "")), db);
            }

            if (dbbuilds.Count == 0 || !AllDBDs.Any(x => Path.GetFileNameWithoutExtension(x).ToUpper() == file))
            {
                return;
            }

            DBDReader reader  = new DBDReader();
            string    dbdfile = AllDBDs.First(x => Path.GetFileNameWithoutExtension(x).ToUpper() == file);
            var       dbd     = reader.Read(dbdfile);

            var builds = dbd.versionDefinitions.SelectMany(x => x.builds).ToArray();
            var ranges = dbd.versionDefinitions.SelectMany(x => x.buildRanges).ToArray();

            List <ValidateResult> validationResults = new List <ValidateResult>();

            foreach (var b in dbbuilds)
            {
                Application.DoEvents();

                if (builds.Any(x => x.build == b.Key.build) || ranges.Any(x => x.ContainsV2(b.Key)))
                {
                    var result = DBReader.Validate(b.Value, dbdfile, b.Key);
                    if (result.Issues != DBIssues.NONE)
                    {
                        validationResults.Add(result);
                    }
                }
            }

            if (validationResults.Count > 0)
            {
                new Popup()
                {
                    Data = validationResults
                }.ShowDialog();
            }
            else
            {
                MessageBox.Show("Smashing job!");
            }
        }
Пример #6
0
        internal Type Build(Stream dbc, Stream dbd, string name = null, string build = null)
        {
            var dbdReader = new DBDReader();
            var dbcReader = ReaderForDBC(dbc);

            if (name == null)
            {
                name = Guid.NewGuid().ToString();
            }

            var databaseDefinition = dbdReader.Read(dbd);

            Structs.VersionDefinitions?versionDefinition = null;

            if (string.IsNullOrWhiteSpace(build) == false)
            {
                Utils.GetVersionDefinitionByBuild(databaseDefinition, new Build(build), out versionDefinition);
            }

            if (versionDefinition == null)
            {
                var layoutHash = dbcReader.LayoutHash.ToString("X8");
                Utils.GetVersionDefinitionByLayoutHash(databaseDefinition, layoutHash, out versionDefinition);
            }

            if (versionDefinition == null)
            {
                throw new FileNotFoundException("No definition found for this file.");
            }

            var typeBuilder = moduleBuilder.DefineType(name, TypeAttributes.Public);

            var fields = versionDefinition.Value.definitions;

            foreach (var fieldDefinition in fields)
            {
                var columnDefinition = databaseDefinition.columnDefinitions[fieldDefinition.name];
                var type             = FieldDefinitionToType(fieldDefinition, columnDefinition);
                var field            = typeBuilder.DefineField(fieldDefinition.name, type, FieldAttributes.Public);

                if (fieldDefinition.isID)
                {
                    var constructorParameters       = new Type[] { };
                    var constructorInfo             = typeof(IndexAttribute).GetConstructor(constructorParameters);
                    var displayNameAttributeBuilder = new CustomAttributeBuilder(constructorInfo, new object[] { });
                    field.SetCustomAttribute(displayNameAttributeBuilder);
                }
            }

            return(typeBuilder.CreateTypeInfo());
        }
Пример #7
0
        private void PopulateBuilds()
        {
            Regex  buildmatch = new Regex(@"\d\.\d{1,2}.\d.\d{4,}", RegexOptions.Compiled);
            string file       = Path.GetFileNameWithoutExtension(txtFile1.Text).ToUpper();

            var dbbuilds = AllDBs[file].Select(x => Directory.GetParent(x).Name.ToUpper().Replace("A", "")).Where(x => buildmatch.IsMatch(x)).ToArray();

            // flatten
            cbBuild1.DataSource = null;
            cbBuild2.DataSource = null;

            if (dbbuilds.Length == 0 || !AllDBDs.Any(x => Path.GetFileNameWithoutExtension(x).ToUpper() == file))
            {
                return;
            }

            DBDReader reader = new DBDReader();
            var       dbd    = reader.Read(AllDBDs.First(x => Path.GetFileNameWithoutExtension(x).ToUpper() == file));

            var builds = new HashSet <string>(dbd.versionDefinitions.SelectMany(x => x.builds.Select(y => y.ToString())).Intersect(dbbuilds));
            var ranges = dbd.versionDefinitions.SelectMany(x => x.buildRanges).ToArray();

            foreach (var b in dbbuilds)
            {
                Build build = new Build(b);
                foreach (var range in ranges)
                {
                    if (range.ContainsV2(build))
                    {
                        builds.Add(b);
                        break;
                    }
                }
            }

            // load
            cbBuild1.DataSource    = builds.Select(x => new Build(x)).OrderBy(x => x.expansion).ThenBy(x => x.build).Select(x => x.ToString()).ToList();
            cbBuild2.DataSource    = (cbBuild1.DataSource as List <string>).ToList();         // binding issues
            cbBuild2.SelectedIndex = cbBuild2.Items.Count - 1;
        }
Пример #8
0
        internal Tuple <Type, DBCDInfo> Build(DBReader dbcReader, Stream dbd, string name, string build)
        {
            var dbdReader = new DBDReader();

            if (name == null)
            {
                name = Guid.NewGuid().ToString();
            }

            var databaseDefinition = dbdReader.Read(dbd);

            Structs.VersionDefinitions?versionDefinition = null;

            if (!string.IsNullOrWhiteSpace(build))
            {
                var dbBuild = new Build(build);
                locStringSize = GetLocStringSize(dbBuild);
                Utils.GetVersionDefinitionByBuild(databaseDefinition, dbBuild, out versionDefinition);
            }

            if (versionDefinition == null && dbcReader.LayoutHash != 0)
            {
                var layoutHash = dbcReader.LayoutHash.ToString("X8");
                Utils.GetVersionDefinitionByLayoutHash(databaseDefinition, layoutHash, out versionDefinition);
            }

            if (versionDefinition == null)
            {
                throw new FileNotFoundException("No definition found for this file.");
            }

            if (locStringSize > 1 && (int)locale >= locStringSize)
            {
                throw new FormatException("Invalid locale for this file.");
            }

            var typeBuilder = moduleBuilder.DefineType(name, TypeAttributes.Public);

            var  fields          = versionDefinition.Value.definitions;
            var  columns         = new List <string>(fields.Length);
            bool localiseStrings = locale != Locale.None;

            foreach (var fieldDefinition in fields)
            {
                var  columnDefinition  = databaseDefinition.columnDefinitions[fieldDefinition.name];
                bool isLocalisedString = columnDefinition.type == "locstring" && locStringSize > 1;


                Type fieldType;
                if (fieldDefinition.isRelation && fieldDefinition.isNonInline)
                {
                    fieldType = fieldDefinition.arrLength == 0 ? typeof(int) : typeof(int[]);
                }
                else
                {
                    fieldType = FieldDefinitionToType(fieldDefinition, columnDefinition, localiseStrings);
                }

                var field = typeBuilder.DefineField(fieldDefinition.name, fieldType, FieldAttributes.Public);

                columns.Add(fieldDefinition.name);

                if (fieldDefinition.isID)
                {
                    AddAttribute <IndexAttribute>(field, fieldDefinition.isNonInline);
                }

                if (fieldDefinition.arrLength > 1)
                {
                    AddAttribute <CardinalityAttribute>(field, fieldDefinition.arrLength);
                }

                if (fieldDefinition.isRelation && fieldDefinition.isNonInline)
                {
                    var metaDataFieldType = FieldDefinitionToType(fieldDefinition, columnDefinition, localiseStrings);
                    AddAttribute <NonInlineRelationAttribute>(field, metaDataFieldType);
                }

                if (isLocalisedString)
                {
                    if (localiseStrings)
                    {
                        AddAttribute <LocaleAttribute>(field, (int)locale, locStringSize);
                    }
                    else
                    {
                        AddAttribute <CardinalityAttribute>(field, locStringSize);
                        // add locstring mask field
                        typeBuilder.DefineField(fieldDefinition.name + "_mask", typeof(uint), FieldAttributes.Public);
                        columns.Add(fieldDefinition.name + "_mask");
                    }
                }
            }

            var type = typeBuilder.CreateTypeInfo();

            var info = new DBCDInfo
            {
                availableColumns = columns.ToArray(),
                tableName        = name
            };

            return(new Tuple <Type, DBCDInfo>(type, info));
        }
Пример #9
0
        private static Dictionary <string, TypeCode> BuildStructure(string filename, Build build, out bool defissue)
        {
            DBDReader reader = new DBDReader();
            var       dbd    = reader.Read(filename);

            Dictionary <string, TypeCode> typeLookup = new Dictionary <string, TypeCode>();

            void AddColumn(TypeCode type, string name, int arrlength)
            {
                for (int i = 0; i < arrlength || i < 1; i++)
                {
                    typeLookup.Add(name + (arrlength > 1 ? "_" + (i + 1) : ""), type);
                }
            }

            // size, signed type, unsigned type
            var intTypes = new Dictionary <int, Tuple <TypeCode, TypeCode> >()
            {
                { 08, new Tuple <TypeCode, TypeCode>(TypeCode.Byte, TypeCode.Byte) },
                { 16, new Tuple <TypeCode, TypeCode>(TypeCode.Int16, TypeCode.UInt16) },
                { 32, new Tuple <TypeCode, TypeCode>(TypeCode.Int32, TypeCode.UInt32) },
                { 64, new Tuple <TypeCode, TypeCode>(TypeCode.Int64, TypeCode.UInt64) },
            };

            var vers = dbd.versionDefinitions.Where(y => y.Contains(build));

            defissue = vers.Count() != 1;

            var ver = vers.FirstOrDefault();

            if (!ver.IsDefault())
            {
                foreach (var def in ver.definitions)
                {
                    string name = def.name;
                    if (def.isID && !def.isNonInline)
                    {
                        name = "$id$" + name;
                    }

                    switch (dbd.columnDefinitions[def.name].type)
                    {
                    case "int":
                        AddColumn(intTypes[def.size].Item1, name, def.arrLength);
                        break;

                    case "uint":
                        AddColumn(intTypes[def.size].Item2, name, def.arrLength);
                        break;

                    case "float":
                        AddColumn(TypeCode.Single, name, def.arrLength);
                        break;

                    case "string":
                        AddColumn(TypeCode.String, name, def.arrLength);
                        break;

                    case "locstring":
                    {
                        int len = (build.expansion > 3 ? def.arrLength : (build.build < 6692 ? 8 : 16));                                         // string or locstring
                        AddColumn(TypeCode.String, name, len);
                        if (build.expansion <= 3)
                        {
                            AddColumn(TypeCode.Int32, name + "_mask", 1);                                             // mask
                        }
                    }
                    break;
                    }
                }
            }

            return(typeLookup);
        }
Пример #10
0
        static void Main(string[] args)
        {
            if (args.Length < 3)
            {
                Console.WriteLine("Usage: <firstdir> <seconddir> <outdir>");
                Environment.Exit(1);
            }

            var firstDir  = args[0];
            var secondDir = args[1];
            var targetDir = args[2];

            var firstDirFiles  = new DirectoryInfo(firstDir).GetFiles().Select(o => o.Name).ToList();
            var secondDirFiles = new DirectoryInfo(secondDir).GetFiles().Select(o => o.Name).ToList();

            var newDefinitions = new Dictionary <string, DBDefinition>();

            var reader = new DBDReader();

            foreach (var file in secondDirFiles)
            {
                var dbName = Path.GetFileNameWithoutExtension(file);
                if (firstDirFiles.Contains(file))
                {
                    // Both directories have this file. Merge!
                    var firstFile  = reader.Read(Path.Combine(firstDir, file));
                    var secondFile = reader.Read(Path.Combine(secondDir, file));

                    var newDefinition = firstFile;

                    // Merge column definitions
                    foreach (var columnDefinition2 in secondFile.columnDefinitions)
                    {
                        var foundCol = false;
                        foreach (var columnDefinition1 in firstFile.columnDefinitions)
                        {
                            if (Utils.NormalizeColumn(columnDefinition2.Key).ToLower() == Utils.NormalizeColumn(columnDefinition1.Key).ToLower())
                            {
                                foundCol = true;

                                if (columnDefinition2.Value.type != columnDefinition1.Value.type)
                                {
                                    Console.ForegroundColor = ConsoleColor.Yellow;
                                    Console.WriteLine("Types are different for (1)" + dbName + "::" + columnDefinition1.Key + " = " + columnDefinition1.Value.type + " and (2)" + dbName + "::" + columnDefinition2.Key + " = " + columnDefinition2.Value.type + ", using type " + columnDefinition2.Value.type + " from 2");

                                    // If this is an uncommon conversion (not uint -> int or vice versa) throw an error
                                    if ((columnDefinition1.Value.type == "uint" && columnDefinition2.Value.type == "int") || (columnDefinition1.Value.type == "int" && columnDefinition2.Value.type == "uint"))
                                    {
                                        Console.ForegroundColor = ConsoleColor.Yellow;
                                        Console.WriteLine("Type difference for column (1)" + dbName + "::" + columnDefinition1.Key + " = " + columnDefinition1.Value.type + " and(2)" + dbName + "::" + columnDefinition2.Key + " = " + columnDefinition2.Value.type + ", ignoring..");
                                    }
                                    else
                                    {
                                        throw new Exception("bad type difference, refusing to handle");
                                    }

                                    Console.ResetColor();
                                }

                                if (columnDefinition2.Key != columnDefinition1.Key)
                                {
                                    if (Utils.NormalizeColumn(columnDefinition2.Key, true) == columnDefinition1.Key)
                                    {
                                        Console.ForegroundColor = ConsoleColor.Green;
                                        Console.WriteLine("Automagically fixed casing issue between (1)" + dbName + "::" + columnDefinition1.Key + " and (2)" + dbName + "::" + columnDefinition2.Key);
                                        for (var i = 0; i < secondFile.versionDefinitions.Length; i++)
                                        {
                                            for (var j = 0; j < secondFile.versionDefinitions[i].definitions.Length; j++)
                                            {
                                                if (secondFile.versionDefinitions[i].definitions[j].name == columnDefinition2.Key)
                                                {
                                                    secondFile.versionDefinitions[i].definitions[j].name = Utils.NormalizeColumn(columnDefinition2.Key, true);
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        Console.ForegroundColor = ConsoleColor.Yellow;
                                        Console.WriteLine("Unable to automagically fix casing issue between (1)" + dbName + "::" + columnDefinition1.Key + " and (2)" + dbName + "::" + columnDefinition2.Key + ", falling back to (1) naming");
                                        for (var i = 0; i < secondFile.versionDefinitions.Length; i++)
                                        {
                                            for (var j = 0; j < secondFile.versionDefinitions[i].definitions.Length; j++)
                                            {
                                                if (secondFile.versionDefinitions[i].definitions[j].name == columnDefinition2.Key)
                                                {
                                                    secondFile.versionDefinitions[i].definitions[j].name = columnDefinition1.Key;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    Console.ResetColor();
                                }
                                break;
                            }
                        }

                        if (!foundCol)
                        {
                            // Column was not found, add it
                            Console.WriteLine(dbName + "::" + columnDefinition2.Key + " was not found found in first file!");

                            newDefinition.columnDefinitions.Add(columnDefinition2.Key, columnDefinition2.Value);
                        }
                    }

                    // Merge version definitions
                    foreach (var versionDefinition2 in secondFile.versionDefinitions)
                    {
                        var foundVersion = false;
                        foreach (var versionDefinition1 in firstFile.versionDefinitions)
                        {
                            foreach (var layoutHash2 in versionDefinition2.layoutHashes)
                            {
                                if (versionDefinition1.layoutHashes.Contains(layoutHash2))
                                {
                                    foundVersion = true;
                                    break;
                                }
                            }

                            // If layouthash was found, don't check builds
                            if (foundVersion)
                            {
                                break;
                            }

                            // Check builds
                            foreach (var build2 in versionDefinition2.builds)
                            {
                                foreach (var build1 in versionDefinition1.builds)
                                {
                                    if (build1.Equals(build2))
                                    {
                                        foundVersion = true;
                                        break;
                                    }
                                }

                                foreach (var buildranges1 in versionDefinition1.buildRanges)
                                {
                                    if (build2.expansion == buildranges1.minBuild.expansion && build2.major == buildranges1.minBuild.major && build2.minor == buildranges1.minBuild.minor)
                                    {
                                        if (build2.build >= buildranges1.minBuild.build && build2.build <= buildranges1.maxBuild.build)
                                        {
                                            //Console.WriteLine("Build match? Build " + Utils.BuildToString(build2) + " seem to match with " + Utils.BuildToString(buildranges1.minBuild) + "-" + Utils.BuildToString(buildranges1.maxBuild));
                                            foundVersion = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                        if (!foundVersion)
                        {
                            // TODO: Only for secondFile, not firstFile!
                            var mergedWithPreviousBuild = false;
                            var newVersions             = newDefinition.versionDefinitions.ToList();

                            for (var i = 0; i < newVersions.Count; i++)
                            {
                                if (newVersions[i].definitions.SequenceEqual(versionDefinition2.definitions))
                                {
                                    Console.WriteLine("Looks like these two definition arrays are the same!");
                                    // Make list from current builds
                                    var curBuilds = newVersions[i].builds.ToList();
                                    curBuilds.AddRange(versionDefinition2.builds.ToList());

                                    // Make list of current layouthashes
                                    var curLayouthashes = newVersions[i].layoutHashes.ToList();
                                    curLayouthashes.AddRange(versionDefinition2.layoutHashes.ToList());

                                    // Create temporary version object based of newVersion
                                    var tempVersion = newVersions[i];

                                    // Override builds with new list
                                    tempVersion.builds = curBuilds.Distinct().ToArray();

                                    // Override layoutHashes with new list
                                    tempVersion.layoutHashes = curLayouthashes.Distinct().ToArray();

                                    // Override newVersion with temporary version object
                                    newVersions[i]          = tempVersion;
                                    mergedWithPreviousBuild = true;
                                }
                            }

                            if (!mergedWithPreviousBuild)
                            {
                                // Version was not found/merged, add it!
                                newVersions.Add(versionDefinition2);
                            }

                            newDefinition.versionDefinitions = newVersions.ToArray();
                        }
                        else
                        {
                            // Version exists, compare stuff and add build if needed, TODO make less bad
                            var newVersions = newDefinition.versionDefinitions.ToList();

                            for (var i = 0; i < newVersions.Count; i++)
                            {
                                foreach (var layoutHash2 in versionDefinition2.layoutHashes)
                                {
                                    if (newVersions[i].layoutHashes.Contains(layoutHash2))
                                    {
                                        // Make list from current builds
                                        var curBuilds = newVersions[i].builds.ToList();
                                        curBuilds.AddRange(versionDefinition2.builds.ToList());

                                        // Make list of current layouthashes
                                        var curLayouthashes = newVersions[i].layoutHashes.ToList();
                                        curLayouthashes.AddRange(versionDefinition2.layoutHashes.ToList());

                                        // Create temporary version object based of newVersion
                                        var tempVersion = newVersions[i];

                                        // Override builds with new list
                                        tempVersion.builds = curBuilds.Distinct().ToArray();

                                        // Override layoutHashes with new list
                                        tempVersion.layoutHashes = curLayouthashes.Distinct().ToArray();

                                        for (var j = 0; j < versionDefinition2.definitions.Count(); j++)
                                        {
                                            // Merge signedness from second file if it is different from current
                                            if (versionDefinition2.definitions[j].isSigned != tempVersion.definitions[j].isSigned)
                                            {
                                                tempVersion.definitions[j].isSigned = versionDefinition2.definitions[j].isSigned;
                                            }
                                        }

                                        // Override newVersion with temporary version object
                                        newVersions[i] = tempVersion;
                                    }
                                }
                            }

                            newDefinition.versionDefinitions = newVersions.ToArray();
                        }
                    }

                    newDefinitions.Add(dbName, newDefinition);
                }
                else
                {
                    // Only 2nd dir has this file, use that
                    newDefinitions.Add(dbName, reader.Read(Path.Combine(secondDir, file)));
                }
            }

            foreach (var file in firstDirFiles)
            {
                if (!secondDirFiles.Contains(file))
                {
                    // Only 1st dir has this file, use that
                    newDefinitions.Add(Path.GetFileNameWithoutExtension(file), reader.Read(Path.Combine(firstDir, file)));
                }
            }

            var writer = new DBDWriter();

            foreach (var entry in newDefinitions)
            {
                writer.Save(entry.Value, Path.Combine(targetDir, entry.Key + ".dbd"));
            }

            //Console.ReadLine();
        }
Пример #11
0
        static void Main(string[] args)
        {
            if (args.Length < 3)
            {
                Console.WriteLine("Usage: <firstdir> <seconddir> <outdir>");
                Environment.Exit(1);
            }

            var numLayoutsAdded = 0;

            var firstDir  = args[0];
            var secondDir = args[1];
            var targetDir = args[2];

            var firstDirFiles  = new DirectoryInfo(firstDir).GetFiles().Select(o => o.Name).ToList();
            var secondDirFiles = new DirectoryInfo(secondDir).GetFiles().Select(o => o.Name).ToList();

            var firstDirFilesLC  = new DirectoryInfo(firstDir).GetFiles().Select(o => o.Name.ToLower()).ToList();
            var secondDirFilesLC = new DirectoryInfo(secondDir).GetFiles().Select(o => o.Name.ToLower()).ToList();

            var newDefinitions = new Dictionary <string, DBDefinition>();

            var reader = new DBDReader();

            foreach (var file in secondDirFiles)
            {
                var dbName = Path.GetFileNameWithoutExtension(file);
                if (firstDirFilesLC.Contains(file.ToLower()))
                {
                    // Both directories have this file. Merge!
                    var firstFileName = Path.Combine(firstDir, firstDirFiles.ElementAt(firstDirFilesLC.IndexOf(file.ToLower())));
                    var firstFile     = reader.Read(firstFileName);
                    var secondFile    = reader.Read(Path.Combine(secondDir, file));

                    var newDefinition = firstFile;

                    // Merge column definitions
                    foreach (var columnDefinition2 in secondFile.columnDefinitions)
                    {
                        var foundCol = false;
                        foreach (var columnDefinition1 in firstFile.columnDefinitions)
                        {
                            if (Utils.NormalizeColumn(columnDefinition2.Key).ToLower() == Utils.NormalizeColumn(columnDefinition1.Key).ToLower())
                            {
                                foundCol = true;

                                if (columnDefinition2.Value.type != columnDefinition1.Value.type)
                                {
                                    Console.ForegroundColor = ConsoleColor.Yellow;
                                    Console.WriteLine("Types are different for (1)" + dbName + "::" + columnDefinition1.Key + " = " + columnDefinition1.Value.type + " and (2)" + dbName + "::" + columnDefinition2.Key + " = " + columnDefinition2.Value.type + ", using type " + columnDefinition2.Value.type + " from 2");

                                    // If this is an uncommon conversion (not uint -> int or vice versa) throw an error
                                    if ((columnDefinition1.Value.type == "uint" && columnDefinition2.Value.type == "int") || (columnDefinition1.Value.type == "int" && columnDefinition2.Value.type == "uint"))
                                    {
                                        Console.ForegroundColor = ConsoleColor.Yellow;
                                        Console.WriteLine("Type difference for column (1)" + dbName + "::" + columnDefinition1.Key + " = " + columnDefinition1.Value.type + " and(2)" + dbName + "::" + columnDefinition2.Key + " = " + columnDefinition2.Value.type + ", ignoring..");
                                    }
                                    else
                                    {
                                        throw new Exception("bad type difference, refusing to handle");
                                    }

                                    Console.ResetColor();
                                }

                                if (columnDefinition2.Key != columnDefinition1.Key)
                                {
                                    if (Utils.NormalizeColumn(columnDefinition2.Key, true) == columnDefinition1.Key)
                                    {
                                        Console.ForegroundColor = ConsoleColor.Green;
                                        Console.WriteLine("Automagically fixed casing issue between (1)" + dbName + "::" + columnDefinition1.Key + " and (2)" + dbName + "::" + columnDefinition2.Key);
                                        for (var i = 0; i < secondFile.versionDefinitions.Length; i++)
                                        {
                                            for (var j = 0; j < secondFile.versionDefinitions[i].definitions.Length; j++)
                                            {
                                                if (secondFile.versionDefinitions[i].definitions[j].name == columnDefinition2.Key)
                                                {
                                                    secondFile.versionDefinitions[i].definitions[j].name = Utils.NormalizeColumn(columnDefinition2.Key, true);
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        Console.ForegroundColor = ConsoleColor.Yellow;
                                        Console.WriteLine("Unable to automagically fix casing issue between (1)" + dbName + "::" + columnDefinition1.Key + " and (2)" + dbName + "::" + columnDefinition2.Key + ", falling back to (1) naming");
                                        for (var i = 0; i < secondFile.versionDefinitions.Length; i++)
                                        {
                                            for (var j = 0; j < secondFile.versionDefinitions[i].definitions.Length; j++)
                                            {
                                                if (secondFile.versionDefinitions[i].definitions[j].name == columnDefinition2.Key)
                                                {
                                                    secondFile.versionDefinitions[i].definitions[j].name = columnDefinition1.Key;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    Console.ResetColor();
                                }

                                // Merge comments
                                if (columnDefinition2.Value.comment != columnDefinition1.Value.comment)
                                {
                                    for (var i = 0; i < secondFile.versionDefinitions.Length; i++)
                                    {
                                        for (var j = 0; j < secondFile.versionDefinitions[i].definitions.Length; j++)
                                        {
                                            if (secondFile.versionDefinitions[i].definitions[j].name == columnDefinition2.Key)
                                            {
                                                var colDef = newDefinition.columnDefinitions[columnDefinition1.Key];

                                                if (columnDefinition2.Value.comment == null)
                                                {
                                                    colDef.comment = columnDefinition1.Value.comment;
                                                }
                                                else if (columnDefinition1.Value.comment == null)
                                                {
                                                    colDef.comment = columnDefinition2.Value.comment;
                                                }
                                                else
                                                {
                                                    throw new Exception("Do not support merging 2 comments yet!");
                                                }

                                                newDefinition.columnDefinitions[columnDefinition1.Key] = colDef;
                                            }
                                        }
                                    }
                                }

                                // Merge foreignTable/foreignKey
                                if (columnDefinition2.Value.foreignTable != columnDefinition1.Value.foreignTable || columnDefinition2.Value.foreignColumn != columnDefinition1.Value.foreignColumn)
                                {
                                    for (var i = 0; i < secondFile.versionDefinitions.Length; i++)
                                    {
                                        for (var j = 0; j < secondFile.versionDefinitions[i].definitions.Length; j++)
                                        {
                                            if (secondFile.versionDefinitions[i].definitions[j].name == columnDefinition2.Key)
                                            {
                                                var colDef = newDefinition.columnDefinitions[columnDefinition1.Key];

                                                if (columnDefinition2.Value.foreignTable == null && columnDefinition2.Value.foreignColumn == null)
                                                {
                                                    colDef.foreignTable  = columnDefinition1.Value.foreignTable;
                                                    colDef.foreignColumn = columnDefinition1.Value.foreignColumn;
                                                }
                                                else if (columnDefinition1.Value.foreignTable == null && columnDefinition1.Value.foreignColumn == null)
                                                {
                                                    colDef.foreignTable  = columnDefinition2.Value.foreignTable;
                                                    colDef.foreignColumn = columnDefinition2.Value.foreignColumn;
                                                }
                                                else
                                                {
                                                    throw new Exception("Do not support merging 2 FKs yet!");
                                                }

                                                newDefinition.columnDefinitions[columnDefinition1.Key] = colDef;
                                            }
                                        }
                                    }
                                }

                                break;
                            }
                        }

                        if (!foundCol)
                        {
                            // Column was not found, add it
                            newDefinition.columnDefinitions.Add(columnDefinition2.Key, columnDefinition2.Value);
                        }
                    }

                    // Merge version definitions
                    foreach (var versionDefinition2 in secondFile.versionDefinitions)
                    {
                        var foundVersion = false;
                        foreach (var versionDefinition1 in firstFile.versionDefinitions)
                        {
                            foreach (var layoutHash2 in versionDefinition2.layoutHashes)
                            {
                                if (versionDefinition1.layoutHashes.Contains(layoutHash2))
                                {
                                    foundVersion = true;
                                    break;
                                }
                            }

                            // If layouthash was found, don't check builds
                            if (foundVersion)
                            {
                                break;
                            }

                            // Check builds
                            foreach (var build2 in versionDefinition2.builds)
                            {
                                foreach (var build1 in versionDefinition1.builds)
                                {
                                    if (build1.Equals(build2))
                                    {
                                        foundVersion = true;
                                        break;
                                    }
                                }

                                // Stop checking if build already exists
                                if (foundVersion)
                                {
                                    break;
                                }

                                foreach (var buildranges1 in versionDefinition1.buildRanges)
                                {
                                    if (buildranges1.Contains(build2))
                                    {
                                        Console.WriteLine(build2.ToString() + " is in build range " + buildranges1.ToString());
                                        foundVersion = true;
                                        break;
                                    }
                                }

                                // Stop checking if build exists in ranges
                                if (foundVersion)
                                {
                                    break;
                                }
                            }
                        }

                        if (!foundVersion)
                        {
                            // TODO: Only for secondFile, not firstFile!
                            var mergedWithPreviousBuild = false;
                            var newVersions             = newDefinition.versionDefinitions.ToList();

                            for (var i = 0; i < newVersions.Count; i++)
                            {
                                if (newVersions[i].definitions.SequenceEqual(versionDefinition2.definitions))
                                {
                                    Console.WriteLine("Looks like these two definition arrays are the same!");
                                    // Make list from current builds
                                    var curBuilds = newVersions[i].builds.ToList();
                                    curBuilds.AddRange(versionDefinition2.builds.ToList());

                                    // Make list from current build ranges
                                    var curBuildRanges = newVersions[i].buildRanges.ToList();
                                    curBuildRanges.AddRange(versionDefinition2.buildRanges.ToList());

                                    // Make list of current layouthashes
                                    var curLayouthashes = newVersions[i].layoutHashes.ToList();
                                    curLayouthashes.AddRange(versionDefinition2.layoutHashes.ToList());

                                    // Create temporary version object based of newVersion
                                    var tempVersion = newVersions[i];

                                    // Override builds with new list
                                    tempVersion.builds = curBuilds.Distinct().ToArray();

                                    // Override buildranges with new list
                                    tempVersion.buildRanges = curBuildRanges.Distinct().ToArray();

                                    // Override layoutHashes with new list
                                    tempVersion.layoutHashes = curLayouthashes.Distinct().ToArray();

                                    // Override newVersion with temporary version object
                                    newVersions[i]          = tempVersion;
                                    mergedWithPreviousBuild = true;
                                }
                            }

                            if (!mergedWithPreviousBuild)
                            {
                                // Version was not found/merged, add it!
                                newVersions.Add(versionDefinition2);
                                numLayoutsAdded++;
                            }

                            newDefinition.versionDefinitions = newVersions.ToArray();
                        }
                        else
                        {
                            // Version exists, compare stuff and add build if needed, TODO make less bad
                            var newVersions = newDefinition.versionDefinitions.ToList();

                            for (var i = 0; i < newVersions.Count; i++)
                            {
                                foreach (var layoutHash2 in versionDefinition2.layoutHashes)
                                {
                                    if (newVersions[i].layoutHashes.Contains(layoutHash2))
                                    {
                                        // Make list from current builds
                                        var curBuilds = newVersions[i].builds.ToList();
                                        curBuilds.AddRange(versionDefinition2.builds.ToList());

                                        // Make list from current build ranges
                                        var curBuildRanges = newVersions[i].buildRanges.ToList();
                                        curBuildRanges.AddRange(versionDefinition2.buildRanges.ToList());

                                        // Make list of current layouthashes
                                        var curLayouthashes = newVersions[i].layoutHashes.ToList();
                                        curLayouthashes.AddRange(versionDefinition2.layoutHashes.ToList());

                                        // Create temporary version object based of newVersion
                                        var tempVersion = newVersions[i];

                                        // Override builds with new list
                                        tempVersion.builds = curBuilds.Distinct().ToArray();

                                        // Override buildranges with new list
                                        tempVersion.buildRanges = curBuildRanges.Distinct().ToArray();

                                        // Override layoutHashes with new list
                                        tempVersion.layoutHashes = curLayouthashes.Distinct().ToArray();

                                        for (var j = 0; j < versionDefinition2.definitions.Count(); j++)
                                        {
                                            // Merge signedness from second file if it is different from current
                                            if (versionDefinition2.definitions[j].isSigned != tempVersion.definitions[j].isSigned)
                                            {
                                                tempVersion.definitions[j].isSigned = versionDefinition2.definitions[j].isSigned;
                                            }
                                        }

                                        // Override newVersion with temporary version object
                                        newVersions[i] = tempVersion;
                                    }
                                }
                            }

                            newDefinition.versionDefinitions = newVersions.ToArray();
                        }
                    }

                    newDefinitions.Add(Path.GetFileNameWithoutExtension(firstFileName), newDefinition);
                }
                else
                {
                    // Only 2nd dir has this file, use that
                    newDefinitions.Add(dbName, reader.Read(Path.Combine(secondDir, file)));
                }
            }

            foreach (var file in firstDirFiles)
            {
                if (!secondDirFilesLC.Contains(file.ToLower()))
                {
                    // Only 1st dir has this file, use that
                    newDefinitions.Add(Path.GetFileNameWithoutExtension(file), reader.Read(Path.Combine(firstDir, file)));
                }
            }

            var writer = new DBDWriter();

            foreach (var entry in newDefinitions)
            {
                var definitionCopy        = entry.Value;
                var versionDefinitionCopy = definitionCopy.versionDefinitions.ToList();
                for (var i = 0; i < versionDefinitionCopy.Count(); i++)
                {
                    for (var j = 0; j < versionDefinitionCopy.Count(); j++)
                    {
                        if (i == j)
                        {
                            continue;         // Do not compare same entry
                        }
                        if (versionDefinitionCopy[i].definitions.SequenceEqual(versionDefinitionCopy[j].definitions))
                        {
                            if (versionDefinitionCopy[i].layoutHashes.Length > 0 && versionDefinitionCopy[j].layoutHashes.Length > 0 && !versionDefinitionCopy[i].layoutHashes.SequenceEqual(versionDefinitionCopy[j].layoutHashes))
                            {
                                Console.ForegroundColor = ConsoleColor.Yellow;
                                Console.WriteLine(Path.GetFileNameWithoutExtension(entry.Key) + " has 2 identical version definitions (" + (i + 1) + " and " + (j + 1) + ") but two different layouthashes, ignoring...");
                                Console.ResetColor();
                            }
                            else
                            {
                                // Make list from current builds
                                var curBuilds = versionDefinitionCopy[i].builds.ToList();
                                curBuilds.AddRange(versionDefinitionCopy[j].builds.ToList());

                                // Make list from current build ranges
                                var curBuildRanges = versionDefinitionCopy[i].buildRanges.ToList();
                                curBuildRanges.AddRange(versionDefinitionCopy[j].buildRanges.ToList());

                                // Make list of current layouthashes
                                var curLayouthashes = versionDefinitionCopy[i].layoutHashes.ToList();
                                curLayouthashes.AddRange(versionDefinitionCopy[j].layoutHashes.ToList());

                                // Create temporary version object based of newVersion
                                var tempVersion = versionDefinitionCopy[i];

                                // Override builds with new list
                                tempVersion.builds = curBuilds.Distinct().ToArray();

                                // Override buildranges with new list
                                tempVersion.buildRanges = curBuildRanges.Distinct().ToArray();

                                // Override layoutHashes with new list
                                tempVersion.layoutHashes = curLayouthashes.Distinct().ToArray();

                                // Override newVersion with temporary version object
                                versionDefinitionCopy[i] = tempVersion;
                                versionDefinitionCopy.RemoveAt(j);

                                definitionCopy.versionDefinitions = versionDefinitionCopy.ToArray();
                            }
                        }
                    }
                }

                // Run through column definitions to see if there's any unused columns
                var columnDefinitionsCopy = definitionCopy.columnDefinitions.ToList();
                foreach (var columnDefinition in columnDefinitionsCopy)
                {
                    var columnUsed = false;
                    foreach (var versionDefinition in definitionCopy.versionDefinitions)
                    {
                        foreach (var definition in versionDefinition.definitions)
                        {
                            if (definition.name == columnDefinition.Key)
                            {
                                columnUsed = true;
                            }
                        }
                    }

                    if (!columnUsed)
                    {
                        definitionCopy.columnDefinitions.Remove(columnDefinition.Key);
                    }
                }

                writer.Save(definitionCopy, Path.Combine(targetDir, entry.Key + ".dbd"), true);
            }
            Console.WriteLine("Done, " + numLayoutsAdded + " new layouts added!");
            //Console.ReadLine();
        }
Пример #12
0
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Usage: <definitionsdir> (rewrite when done: bool, default false) (verbose: bool, default true) (rawRepoDir: location of WoWDBDefsRaw repository, default none)");
                Environment.Exit(1);
            }

            var definitionDir = args[0];

            var rewrite    = false;
            var verbose    = true;
            var checkRaw   = false;
            var rawRepoDir = "";

            if (args.Length >= 2 && args[1] == "true")
            {
                rewrite = true;
            }
            if (args.Length >= 3 && args[2] == "false")
            {
                verbose = false;
            }
            if (args.Length >= 4)
            {
                checkRaw   = true;
                rawRepoDir = args[3];
            }

            var errorEncountered = new List <string>();

            foreach (var file in Directory.GetFiles(definitionDir))
            {
                var dbName = Path.GetFileNameWithoutExtension(file);

                var reader = new DBDReader();
                try
                {
                    definitionCache.Add(dbName, reader.Read(file, true));

                    if (verbose)
                    {
                        Console.WriteLine("Read " + definitionCache[dbName].versionDefinitions.Length + " versions and " + definitionCache[dbName].columnDefinitions.Count + " columns for " + dbName);
                    }

                    if (rewrite)
                    {
                        var writer = new DBDWriter();
                        writer.Save(definitionCache[dbName], Path.Combine(definitionDir, dbName + ".dbd"), true);
                    }
                }
                catch (Exception ex)
                {
                    errorEncountered.Add(dbName);
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Failed to read " + dbName + ": " + ex);
                    Console.ResetColor();
                }
            }

            Console.WriteLine("Read " + definitionCache.Count + " database definitions!");

            var foreignKeys = 0;

            foreach (var definition in definitionCache)
            {
                foreach (var columnDefinition in definition.Value.columnDefinitions)
                {
                    if (!string.IsNullOrEmpty(columnDefinition.Value.foreignTable) || !string.IsNullOrEmpty(columnDefinition.Value.foreignColumn))
                    {
                        if (definitionCache.ContainsKey(columnDefinition.Value.foreignTable) && definitionCache[columnDefinition.Value.foreignTable].columnDefinitions.ContainsKey(columnDefinition.Value.foreignColumn))
                        {
                            Console.ForegroundColor = ConsoleColor.Green;
                            //Console.WriteLine(definition.Key + "." + columnDefinition.Key + " has a foreign key to " + columnDefinition.Value.foreignTable + "." + columnDefinition.Value.foreignColumn);
                        }
                        else
                        {
                            errorEncountered.Add(definition.Key);
                            Console.ForegroundColor = ConsoleColor.Red;
                            Console.WriteLine(definition.Key + "." + columnDefinition.Key + " has a foreign key to " + columnDefinition.Value.foreignTable + "." + columnDefinition.Value.foreignColumn + " WHICH DOES NOT EXIST!");
                        }

                        foreignKeys++;

                        Console.ResetColor();
                    }
                }
            }

            Console.WriteLine("Checked " + foreignKeys + " foreign keys!");

            if (checkRaw)
            {
                Console.WriteLine("Checking for differences between raw definitions and target definitions (limited to 9.0+)");

                if (!Directory.Exists(rawRepoDir))
                {
                    throw new DirectoryNotFoundException("Could not find WoWDBDefsRaw repository");
                }

                foreach (var definition in definitionCache)
                {
                    foreach (var versionDefinition in definition.Value.versionDefinitions)
                    {
                        foreach (var build in versionDefinition.builds)
                        {
                            // TODO: There are issues in older expansions, but limit to 9.0+ for now
                            if (build.expansion < 9)
                            {
                                continue;
                            }

                            var rawDefLocation = Path.Combine(rawRepoDir, build.ToString(), definition.Key + ".dbd");

                            // Definitions for really old versions aren't in raw repo, we can't check those.
                            if (!File.Exists(rawDefLocation))
                            {
                                continue;
                            }

                            var rawDefReader = new DBDReader();
                            var rawDef       = rawDefReader.Read(rawDefLocation);

                            if (versionDefinition.definitions.Length != rawDef.versionDefinitions[0].definitions.Length)
                            {
                                Console.ForegroundColor = ConsoleColor.Red;
                                Console.WriteLine("[" + definition.Key + "] [" + build + "] Column count mismatch between raw (" + rawDef.versionDefinitions[0].definitions.Length + ") and target definition (" + versionDefinition.definitions.Length + ")");
                                errorEncountered.Add(definition.Key);
                                continue;
                            }

                            for (var i = 0; i < versionDefinition.definitions.Length; i++)
                            {
                                var targetColDef = versionDefinition.definitions[i];
                                var rawColDef    = rawDef.versionDefinitions[0].definitions[i];

                                if (rawColDef.isSigned != targetColDef.isSigned)
                                {
                                    Console.ForegroundColor = ConsoleColor.Red;
                                    Console.WriteLine("[" + definition.Key + "] [" + build + "] " + rawColDef.name + " <-> " + targetColDef.name + " signedness mismatch: " + rawColDef.isSigned + " <-> " + targetColDef.isSigned);
                                    errorEncountered.Add(definition.Key);
                                }

                                if (rawColDef.size != targetColDef.size)
                                {
                                    Console.ForegroundColor = ConsoleColor.Red;
                                    Console.WriteLine("[" + definition.Key + "] [" + build + "] " + rawColDef.name + " <-> " + targetColDef.name + " size mismatch: " + rawColDef.size + " <-> " + targetColDef.size);
                                    errorEncountered.Add(definition.Key);
                                }

                                if (rawColDef.arrLength != targetColDef.arrLength)
                                {
                                    Console.ForegroundColor = ConsoleColor.Red;
                                    Console.WriteLine("[" + definition.Key + "] [" + build + "] " + rawColDef.name + " <-> " + targetColDef.name + " array length mismatch: " + rawColDef.arrLength + " <-> " + targetColDef.arrLength);
                                    errorEncountered.Add(definition.Key);
                                }

                                if (rawColDef.isRelation != targetColDef.isRelation)
                                {
                                    Console.ForegroundColor = ConsoleColor.Red;
                                    Console.WriteLine("[" + definition.Key + "] [" + build + "] " + rawColDef.name + " <-> " + targetColDef.name + " relation mismatch: " + rawColDef.isRelation + " <-> " + targetColDef.isRelation);
                                    errorEncountered.Add(definition.Key);
                                }

                                Console.ResetColor();
                            }
                        }
                    }
                }
            }

            errorEncountered = errorEncountered.Distinct().ToList();

            if (errorEncountered.Count != 0)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("There have been errors in the following DBDs:");
                foreach (var dbName in errorEncountered)
                {
                    Console.WriteLine(" - " + dbName);
                }
                Environment.Exit(1);
            }
            else
            {
                Console.WriteLine("Done");
            }
        }
Пример #13
0
        static void Main(string[] args)
        {
            if (args.Length < 3)
            {
                Console.WriteLine("Usage: <firstdir> <seconddir> <outdir>");
                Environment.Exit(1);
            }

            var firstDir  = args[0];
            var secondDir = args[1];
            var targetDir = args[2];

            var firstDirFiles  = new DirectoryInfo(firstDir).GetFiles().Select(o => o.Name).ToList();
            var secondDirFiles = new DirectoryInfo(secondDir).GetFiles().Select(o => o.Name).ToList();

            var newDefinitions = new Dictionary <string, DBDefinition>();

            var reader = new DBDReader();

            foreach (var file in secondDirFiles)
            {
                var dbName = Path.GetFileNameWithoutExtension(file);
                if (firstDirFiles.Contains(file))
                {
                    // Both directories have this file. Merge!
                    var firstFile  = reader.Read(Path.Combine(firstDir, file));
                    var secondFile = reader.Read(Path.Combine(secondDir, file));

                    var newDefinition = firstFile;

                    // Merge column definitions
                    foreach (var columnDefinition2 in secondFile.columnDefinitions)
                    {
                        var foundCol = false;
                        foreach (var columnDefinition1 in firstFile.columnDefinitions)
                        {
                            if (columnDefinition2.Key.ToLower() == columnDefinition1.Key.ToLower())
                            {
                                foundCol = true;
                                var typeOverride = "";

                                if (columnDefinition2.Value.type != columnDefinition1.Value.type)
                                {
                                    Console.ForegroundColor = ConsoleColor.Yellow;
                                    Console.WriteLine("Types are different for (1)" + dbName + "::" + columnDefinition1.Key + " = " + columnDefinition1.Value.type + " and (2)" + dbName + "::" + columnDefinition2.Key + " = " + columnDefinition2.Value.type + ", using type " + columnDefinition2.Value.type + " from 2");

                                    typeOverride = columnDefinition2.Value.type;

                                    // If this is an uncommon conversion (not uint -> int) override the version's column type
                                    if ((columnDefinition1.Value.type == "uint" && columnDefinition2.Value.type == "int") || (columnDefinition1.Value.type == "int" && columnDefinition2.Value.type == "uint"))
                                    {
                                        Console.ForegroundColor = ConsoleColor.Yellow;
                                        Console.WriteLine("Type difference for column (1)" + dbName + "::" + columnDefinition1.Key + " = " + columnDefinition1.Value.type + " and(2)" + dbName + "::" + columnDefinition2.Key + " = " + columnDefinition2.Value.type + ", ignoring..");
                                    }
                                    else
                                    {
                                        Console.ForegroundColor = ConsoleColor.Red;
                                        Console.WriteLine("Unexpected type difference for column (1)" + dbName + "::" + columnDefinition1.Key + " = " + columnDefinition1.Value.type + " and(2)" + dbName + "::" + columnDefinition2.Key + " = " + columnDefinition2.Value.type);
                                        Console.WriteLine("Adding override to type " + columnDefinition2.Value.type + " for the column in this version!");
                                        for (var i = 0; i < secondFile.versionDefinitions.Length; i++)
                                        {
                                            for (var j = 0; j < secondFile.versionDefinitions[i].definitions.Length; j++)
                                            {
                                                if (secondFile.versionDefinitions[i].definitions[j].name == columnDefinition2.Key)
                                                {
                                                    secondFile.versionDefinitions[i].definitions[j].typeOverride = columnDefinition2.Value.type;
                                                    break;
                                                }
                                            }
                                        }
                                    }

                                    // Only change type in column definitions if we're not already overriding it
                                    if (string.IsNullOrWhiteSpace(typeOverride))
                                    {
                                        var tempDefs = newDefinition.columnDefinitions;
                                        newDefinition.columnDefinitions = new Dictionary <string, ColumnDefinition>();
                                        // TODO: Figure out a better way to "rebuild" column dictionary
                                        foreach (var columnDef1 in tempDefs)
                                        {
                                            if (columnDef1.Key == columnDefinition1.Key)
                                            {
                                                var newVal = columnDef1.Value;
                                                // Use newer type to override old one
                                                newVal.type = columnDefinition2.Value.type;
                                                newDefinition.columnDefinitions.Add(columnDef1.Key, newVal);
                                            }
                                            else
                                            {
                                                newDefinition.columnDefinitions.Add(columnDef1.Key, columnDef1.Value);
                                            }
                                        }
                                    }

                                    Console.ResetColor();
                                }

                                if (columnDefinition2.Key != columnDefinition1.Key)
                                {
                                    if (Utils.NormalizeColumn(columnDefinition2.Key, true) == columnDefinition1.Key)
                                    {
                                        Console.ForegroundColor = ConsoleColor.Green;
                                        Console.WriteLine("Automagically fixed casing issue between (1)" + dbName + "::" + columnDefinition1.Key + " and (2)" + dbName + "::" + columnDefinition2.Key);
                                        for (var i = 0; i < secondFile.versionDefinitions.Length; i++)
                                        {
                                            for (var j = 0; j < secondFile.versionDefinitions[i].definitions.Length; j++)
                                            {
                                                if (secondFile.versionDefinitions[i].definitions[j].name == columnDefinition2.Key)
                                                {
                                                    secondFile.versionDefinitions[i].definitions[j].name = Utils.NormalizeColumn(columnDefinition2.Key, true);
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        Console.ForegroundColor = ConsoleColor.Yellow;
                                        Console.WriteLine("Unable to automagically fix casing issue between (1)" + dbName + "::" + columnDefinition1.Key + " and (2)" + dbName + "::" + columnDefinition2.Key + ", falling back to (1) naming");
                                        for (var i = 0; i < secondFile.versionDefinitions.Length; i++)
                                        {
                                            for (var j = 0; j < secondFile.versionDefinitions[i].definitions.Length; j++)
                                            {
                                                if (secondFile.versionDefinitions[i].definitions[j].name == columnDefinition2.Key)
                                                {
                                                    secondFile.versionDefinitions[i].definitions[j].name = columnDefinition1.Key;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    Console.ResetColor();
                                }
                                break;
                            }
                        }

                        if (!foundCol)
                        {
                            // Column was not found, add it
                            Console.WriteLine(dbName + "::" + columnDefinition2.Key + " was not found found in first file!");

                            newDefinition.columnDefinitions.Add(columnDefinition2.Key, columnDefinition2.Value);
                        }
                    }

                    // Merge version definitions
                    foreach (var versionDefinition2 in secondFile.versionDefinitions)
                    {
                        var foundVersion = false;
                        foreach (var versionDefinition1 in firstFile.versionDefinitions)
                        {
                            foreach (var layoutHash2 in versionDefinition2.layoutHashes)
                            {
                                if (versionDefinition1.layoutHashes.Contains(layoutHash2))
                                {
                                    foundVersion = true;
                                    break;
                                }
                            }

                            // If layouthash was found, don't check builds
                            if (foundVersion)
                            {
                                break;
                            }

                            // Check builds
                            foreach (var build2 in versionDefinition2.builds)
                            {
                                foreach (var build1 in versionDefinition1.builds)
                                {
                                    if (build1.Equals(build2))
                                    {
                                        foundVersion = true;
                                        break;
                                    }
                                }

                                foreach (var buildranges1 in versionDefinition1.buildRanges)
                                {
                                    if (build2.expansion == buildranges1.minBuild.expansion && build2.major == buildranges1.minBuild.major && build2.minor == buildranges1.minBuild.minor)
                                    {
                                        if (build2.build >= buildranges1.minBuild.build && build2.build <= buildranges1.maxBuild.build)
                                        {
                                            //Console.WriteLine("Build match? Build " + Utils.BuildToString(build2) + " seem to match with " + Utils.BuildToString(buildranges1.minBuild) + "-" + Utils.BuildToString(buildranges1.maxBuild));
                                            foundVersion = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                        if (!foundVersion)
                        {
                            // Version was not found, add it!

                            // TODO: Only for secondFile, not firstFile!
                            var mergedWithPreviousBuild = false;
                            var newVersions             = newDefinition.versionDefinitions.ToList();

                            for (var i = 0; i < newVersions.Count; i++)
                            {
                                if (newVersions[i].definitions.SequenceEqual(versionDefinition2.definitions))
                                {
                                    Console.WriteLine("Looks like these two definition arrays are the same!");
                                    var curBuilds = newVersions[i].builds.ToList();
                                    curBuilds.AddRange(versionDefinition2.builds.ToList());
                                    var tempVersion = newVersions[i];
                                    tempVersion.builds      = curBuilds.ToArray();
                                    newVersions[i]          = tempVersion;
                                    mergedWithPreviousBuild = true;
                                }
                            }

                            if (!mergedWithPreviousBuild)
                            {
                                newVersions.Add(versionDefinition2);
                            }

                            newDefinition.versionDefinitions = newVersions.ToArray();
                        }
                        else
                        {
                            // Version exists, compare stuff
                            // TODO
                        }
                    }

                    newDefinitions.Add(dbName, newDefinition);
                }
                else
                {
                    // Only 2nd dir has this file, use that
                    newDefinitions.Add(dbName, reader.Read(Path.Combine(secondDir, file)));
                }
            }

            foreach (var file in firstDirFiles)
            {
                if (!secondDirFiles.Contains(file))
                {
                    // Only 1st dir has this file, use that
                    newDefinitions.Add(Path.GetFileNameWithoutExtension(file), reader.Read(Path.Combine(firstDir, file)));
                }
            }

            var writer = new DBDWriter();

            foreach (var entry in newDefinitions)
            {
                writer.Save(entry.Value, Path.Combine(targetDir, entry.Key + ".dbd"));
            }

            //Console.ReadLine();
        }
Пример #14
0
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Usage: <definitionsdir>");
                Environment.Exit(1);
            }

            var definitionDir = args[0];

            var buildList = new List <string>();

            foreach (var file in Directory.GetFiles(definitionDir))
            {
                var reader = new DBDReader();
                definitionCache.Add(Path.GetFileNameWithoutExtension(file).ToLower(), reader.Read(file));

                foreach (var versionDef in definitionCache[Path.GetFileNameWithoutExtension(file).ToLower()].versionDefinitions)
                {
                    foreach (var versionBuild in versionDef.builds)
                    {
                        var buildString = versionBuild.ToString();
                        if (!buildList.Contains(buildString))
                        {
                            buildList.Add(buildString);
                        }
                    }
                }
            }

            foreach (var dir in Directory.GetDirectories("Z:/DBCs/"))
            {
                var buildDir = dir.Replace("Z:/DBCs/", "");
                if (!buildList.Contains(buildDir))
                {
                    continue;
                }

                if (Directory.Exists(Path.Combine(dir, "DBFilesClient")))
                {
                    foreach (var file in Directory.GetFiles(Path.Combine(dir, "DBFilesClient")))
                    {
                        LoadDBC(file);
                    }
                }
                else
                {
                    foreach (var file in Directory.GetFiles(dir))
                    {
                        LoadDBC(file);
                    }
                }
            }

            if (foundError)
            {
                Environment.Exit(1);
            }
        }
Пример #15
0
        static void Main(string[] args)
        {
            /* Check arguments */
            if (args.Length < 3)
            {
                throw new ArgumentException("<path to DBCache.bin file> <path to DBD definitions directory> <SQLite file to use as unpatched base>");
            }

            var hotfixFile = args[0];

            if (!File.Exists(hotfixFile))
            {
                throw new FileNotFoundException("Hotfix file " + hotfixFile + " not found!");
            }

            var definitionDir = args[1];

            if (!Directory.Exists(definitionDir))
            {
                throw new FileNotFoundException("DBD definition directory " + definitionDir + " not found!");
            }

            var inputDB = args[2];

            if (!File.Exists(inputDB))
            {
                throw new FileNotFoundException("Input SQLite DB not found!");
            }

            /* Back up non-hotfix database to new database */
            Console.WriteLine("Backing up non-hotfix database to new database..");

            SQLiteConnection dbIn  = new SQLiteConnection("Data Source= " + inputDB + ";foreign keys=True;Version=3;Read Only=True;");
            SQLiteConnection dbNew = new SQLiteConnection("Data Source=export_withhotfix.db3;foreign keys=True;Version=3;");

            dbIn.Open();
            dbNew.Open();
            dbIn.BackupDatabase(dbNew, "main", "main", -1, null, -1);
            dbIn.Close();

            /* Read DBCache.bin */
            Console.WriteLine("Reading hotfix file..");
            var hotfixes     = ReadHotfixFile(hotfixFile, definitionDir);
            var hotfixesCopy = hotfixes.ToList();

            /* Sort and clean up data so we only have status 1/2 hotfixes left */
            foreach (var hotfix in hotfixes)
            {
                if (hotfix.header.isValid == 4)
                {
                    //Console.WriteLine("Removing hotfix of status 4 for " + hotfix.tableName + " " + hotfix.header.recordID);
                    hotfixesCopy.Remove(hotfix);
                }
                else if (hotfix.header.isValid == 3)
                {
                    //Console.WriteLine("Removing hotfixes before PushID " + hotfix.header.pushID + " for " + hotfix.tableName + " " + hotfix.header.recordID);
                    foreach (var targetHotfix in hotfixes)
                    {
                        if (targetHotfix.tableName == hotfix.tableName && targetHotfix.header.recordID == hotfix.header.recordID && targetHotfix.header.pushID < hotfix.header.pushID)
                        {
                            //Console.WriteLine(" Removed hotfix " + targetHotfix.header.pushID + " for " + hotfix.tableName + " " + hotfix.header.recordID);
                            hotfixesCopy.Remove(targetHotfix);
                        }
                    }

                    hotfixesCopy.Remove(hotfix);
                }
            }

            hotfixes = hotfixesCopy;

            Dictionary <string, string> queryCache = new Dictionary <string, string>();

            /* Parse hotfixes and update database */
            Console.WriteLine("Parsing hotfix record data..");
            foreach (var hotfix in hotfixes)
            {
                DBDefinition dbd;

                if (!dbdCache.ContainsKey(hotfix.tableName))
                {
                    if (!File.Exists(Path.Combine(definitionDir, hotfix.tableName + ".dbd")))
                    {
                        Console.WriteLine("DBD for " + hotfix.tableName + " not found in DBD definitions, skipping hotfix..");
                        continue;
                    }

                    var reader = new DBDReader();
                    dbd = reader.Read(Path.Combine(definitionDir, hotfix.tableName + ".dbd"));
                    dbdCache.Add(hotfix.tableName, dbd);
                }
                else
                {
                    dbd = dbdCache[hotfix.tableName];
                }

                var buildFound = false;

                VersionDefinitions?versionToUse = null;
                foreach (var definition in dbd.versionDefinitions)
                {
                    foreach (var versionBuild in definition.builds)
                    {
                        if (versionBuild.build == hotfix.header.build)
                        {
                            versionToUse = definition;
                            buildFound   = true;
                        }
                    }
                }

                if (!buildFound)
                {
                    Console.WriteLine("\nNo matching build found for table " + hotfix.tableName + " and build " + hotfix.header.build + ", skipping hotfix..");
                    continue;
                }

                var versionDef = (VersionDefinitions)versionToUse;

                var idField = "";

                foreach (var field in versionDef.definitions)
                {
                    if (field.isID)
                    {
                        idField = field.name;
                    }
                }

                if (idField == "")
                {
                    Console.WriteLine("Could not establish ID field name for " + hotfix.tableName + ", using ID..");
                    idField = "ID";
                }

                if (hotfix.header.isValid == 2)
                {
                    // Delete record if exists
                    Console.Write("D");
                    //Console.WriteLine("Deleting DB record for hotfix " + hotfix.header.pushID + " for " + hotfix.tableName + " " + hotfix.header.recordID);
                    using (var deleteCMD = new SQLiteCommand("DELETE FROM " + hotfix.tableName + " WHERE " + idField + " = " + hotfix.header.recordID, dbNew))
                    {
                        deleteCMD.ExecuteNonQuery();
                    }
                    continue;
                }

                var insertQueryString = "";
                if (!queryCache.TryGetValue(hotfix.tableName, out insertQueryString))
                {
                    var sqlFields = new List <string>();
                    foreach (var field in versionDef.definitions)
                    {
                        var fieldName = field.name;

                        if (field.name.ToLower() == "default")
                        {
                            fieldName = "_Default";
                        }

                        if (field.name.ToLower() == "order")
                        {
                            fieldName = "_Order";
                        }
                        if (field.name.ToLower() == "index")
                        {
                            fieldName = "_Index";
                        }

                        if (field.arrLength > 0)
                        {
                            for (var i = 0; i < field.arrLength; i++)
                            {
                                sqlFields.Add(fieldName + "_" + i);
                            }
                        }
                        else
                        {
                            sqlFields.Add(fieldName);
                        }
                    }

                    insertQueryString  = "INSERT INTO " + hotfix.tableName + "(`" + string.Join("`, `", sqlFields.ToArray()) + "`) VALUES(@" + string.Join(", @", sqlFields.ToArray()) + ")";
                    insertQueryString += " ON CONFLICT(" + idField + ") DO UPDATE SET ";
                    for (var i = 0; i < sqlFields.Count; i++)
                    {
                        if (sqlFields[i] == idField)
                        {
                            continue;
                        }

                        insertQueryString += "`" + sqlFields[i] + "`" + " = @U" + sqlFields[i];

                        if (i != sqlFields.Count - 1)
                        {
                            insertQueryString += ", ";
                        }
                    }
                }

                var cmd = new SQLiteCommand(insertQueryString, dbNew);

                // Console.WriteLine(hotfix.tableName + " " + hotfix.header.recordID);
                //try
                //{
                using (var dataBin = new BinaryReader(new MemoryStream(hotfix.data)))
                {
                    foreach (var field in versionDef.definitions)
                    {
                        if (dataBin.BaseStream.Position == dataBin.BaseStream.Length)
                        {
                            continue;
                        }

                        if (field.isNonInline && field.isID)
                        {
                            cmd.Parameters.AddWithValue("@" + idField, hotfix.header.recordID);
                            continue;
                        }

                        // Add parameter
                        SetupParameter(cmd, dataBin, dbd, field);
                    }

                    if (dataBin.BaseStream.Length != dataBin.BaseStream.Position)
                    {
                        var tableHash = dataBin.ReadUInt32();
                        if (tableHash == 0)
                        {
                            continue;
                        }

                        dataBin.ReadBytes((int)(dataBin.BaseStream.Length - dataBin.BaseStream.Position));
                        //Console.WriteLine("Encountered an extra " + tableHash.ToString("X8") + " record of " + (dataBin.BaseStream.Length - dataBin.BaseStream.Position) + " bytes in " + hotfix.tableName + " ID " + hotfix.header.recordID);
                    }
                }

                Console.Write("I");
                cmd.ExecuteNonQuery();
                //}
                //catch (Exception e)
                //{
                //    Console.WriteLine("Encountered exception while reading or updating record data:" + e.Message);
                //}
            }

            Console.WriteLine("\nCleaning up new database file and closing..");
            using (var cmd = new SQLiteCommand("VACUUM", dbNew))
            {
                cmd.ExecuteNonQuery();
            }

            dbNew.Dispose();
        }
Пример #16
0
        public Type Generate(DBReader dbcReader, Stream dbd, Dictionary <string, string> dbs)
        {
            var dbdReader          = new DBDReader();
            var databaseDefinition = dbdReader.Read(dbd);

            Structs.VersionDefinitions?versionDefinition = null;
            if (!string.IsNullOrWhiteSpace(Build))
            {
                var dbBuild = new Build(Build);
                LocStringSize = GetLocStringSize(dbBuild);
                Utils.GetVersionDefinitionByBuild(databaseDefinition, dbBuild, out versionDefinition);
            }

            if (versionDefinition == null && dbcReader.LayoutHash != 0)
            {
                var layoutHash = dbcReader.LayoutHash.ToString("X8");
                Utils.GetVersionDefinitionByLayoutHash(databaseDefinition, layoutHash, out versionDefinition);
            }

            if (versionDefinition == null)
            {
                throw new FileNotFoundException("No definition found for this file.");
            }

            if (LocStringSize > 1 && (int)Locale >= LocStringSize)
            {
                throw new FormatException("Invalid locale for this file.");
            }

            var typeBuilder     = ModuleBuilder.DefineType(Name, TypeAttributes.Public);
            var fields          = versionDefinition.Value.definitions;
            var localiseStrings = Locale != Locale.None;

            foreach (var fieldDefinition in fields)
            {
                var columnInfo        = databaseDefinition.columnDefinitions[fieldDefinition.name];
                var isLocalisedString = columnInfo.type == "locstring" && LocStringSize > 1;

                var fieldType = FieldDefinitionToType(fieldDefinition, columnInfo, localiseStrings);
                var field     = typeBuilder.DefineField(fieldDefinition.name, fieldType, FieldAttributes.Public);

                if (fieldDefinition.isID)
                {
                    AddAttribute <IndexAttribute>(field, fieldDefinition.isNonInline);
                }

                if (fieldDefinition.arrLength > 1)
                {
                    AddAttribute <CardinalityAttribute>(field, fieldDefinition.arrLength);
                }

                if (fieldDefinition.isRelation && fieldDefinition.isNonInline)
                {
                    var metaDataFieldType = FieldDefinitionToType(fieldDefinition, columnInfo, localiseStrings);
                    AddAttribute <NonInlineRelationAttribute>(field, metaDataFieldType);
                }

                if (isLocalisedString)
                {
                    if (localiseStrings)
                    {
                        AddAttribute <LocaleAttribute>(field, (int)Locale, LocStringSize);
                    }
                    else
                    {
                        AddAttribute <CardinalityAttribute>(field, LocStringSize);
                        typeBuilder.DefineField(fieldDefinition.name + "_mask", typeof(uint), FieldAttributes.Public);
                    }
                }

                // export comments
                if (!string.IsNullOrEmpty(columnInfo.comment))
                {
                    AddAttribute <CommentAttribute>(field, columnInfo.comment);
                }

                // only add foreign keys that can be created
                if (fieldDefinition.isRelation &&
                    columnInfo.foreignTable != null &&
                    dbs.ContainsKey(columnInfo.foreignTable))
                {
                    AddAttribute <ForeignKeyAttribute>(field, columnInfo.foreignTable, columnInfo.foreignColumn);
                }
            }

            return(typeBuilder.CreateTypeInfo());
        }
Пример #17
0
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                Console.WriteLine("Usage: <definitionsdir> <dbcdir>");
                Environment.Exit(1);
            }

            var definitionDir = args[0];

            if (!Directory.Exists(definitionDir))
            {
                throw new DirectoryNotFoundException("Directory " + definitionDir + " does not exist!");
            }

            dbcDir = args[1];

            if (!Directory.Exists(dbcDir))
            {
                throw new DirectoryNotFoundException("Directory " + dbcDir + " does not exist!");
            }

            foreach (var file in Directory.GetFiles(definitionDir))
            {
                var reader = new DBDReader();
                definitionCache.Add(Path.GetFileNameWithoutExtension(file).ToLower(), reader.Read(file));
            }

            var builds = new List <Build>();

            foreach (var dir in Directory.GetDirectories(dbcDir))
            {
                builds.Add(new Build(dir.Replace(dbcDir + "\\", "")));
            }

            builds.Sort();

            foreach (var build in builds)
            {
                if (build.expansion != 8 || build.major != 1)
                {
                    continue;
                }

                Console.WriteLine("Checking " + build + "..");
                if (Directory.Exists(Path.Combine(dbcDir, build.ToString(), "DBFilesClient")))
                {
                    foreach (var file in Directory.GetFiles(Path.Combine(dbcDir, build.ToString(), "DBFilesClient")))
                    {
                        LoadDBC(file);
                    }
                }
                else
                {
                    foreach (var file in Directory.GetFiles(Path.Combine(dbcDir, build.ToString())))
                    {
                        LoadDBC(file);
                    }
                }
            }

            if (foundError)
            {
                Environment.Exit(1);
            }
        }
Пример #18
0
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Usage: <definitionsdir>");
                Environment.Exit(1);
            }

            var definitionDir = args[0];

            var rewrite = false;
            var verbose = true;

            if (args.Length >= 2 && args[1] == "true")
            {
                rewrite = true;
            }
            if (args.Length >= 3 && args[2] == "false")
            {
                verbose = false;
            }

            var errorEncountered = new List <string>();

            foreach (var file in Directory.GetFiles(definitionDir))
            {
                var dbName = Path.GetFileNameWithoutExtension(file);

                var reader = new DBDReader();
                try
                {
                    definitionCache.Add(dbName, reader.Read(file, true));

                    if (verbose)
                    {
                        Console.WriteLine("Read " + definitionCache[dbName].versionDefinitions.Length + " versions and " + definitionCache[dbName].columnDefinitions.Count + " columns for " + dbName);
                    }

                    if (rewrite)
                    {
                        var writer = new DBDWriter();
                        writer.Save(definitionCache[dbName], Path.Combine(definitionDir, dbName + ".dbd"));
                    }
                }
                catch (Exception ex)
                {
                    errorEncountered.Add(dbName);
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Failed to read " + dbName + ": " + ex);
                    Console.ResetColor();
                }
            }

            Console.WriteLine("Read " + definitionCache.Count + " database definitions!");

            var foreignKeys = 0;

            foreach (var definition in definitionCache)
            {
                foreach (var columnDefinition in definition.Value.columnDefinitions)
                {
                    if (!string.IsNullOrEmpty(columnDefinition.Value.foreignTable) || !string.IsNullOrEmpty(columnDefinition.Value.foreignColumn))
                    {
                        if (definitionCache.ContainsKey(columnDefinition.Value.foreignTable) && definitionCache[columnDefinition.Value.foreignTable].columnDefinitions.ContainsKey(columnDefinition.Value.foreignColumn))
                        {
                            Console.ForegroundColor = ConsoleColor.Green;
                            //Console.WriteLine(definition.Key + "." + columnDefinition.Key + " has a foreign key to " + columnDefinition.Value.foreignTable + "." + columnDefinition.Value.foreignColumn);
                        }
                        else
                        {
                            errorEncountered.Add(definition.Key);
                            Console.ForegroundColor = ConsoleColor.Red;
                            Console.WriteLine(definition.Key + "." + columnDefinition.Key + " has a foreign key to " + columnDefinition.Value.foreignTable + "." + columnDefinition.Value.foreignColumn + " WHICH DOES NOT EXIST!");
                        }

                        foreignKeys++;

                        Console.ResetColor();
                    }
                }
            }

            Console.WriteLine("Checked " + foreignKeys + " foreign keys!");

            if (errorEncountered.Count != 0)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("There have been errors in the following dbds:");
                foreach (var dbName in errorEncountered)
                {
                    Console.WriteLine(" - " + dbName);
                }
                Environment.Exit(1);
            }
            else
            {
                Console.WriteLine("Done");
            }
        }
Пример #19
0
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Usage: <definitionsdir>");
                Environment.Exit(1);
            }

            var definitionDir = args[0];

            foreach (var file in Directory.GetFiles(definitionDir))
            {
                var reader = new DBDReader();
                definitionCache.Add(Path.GetFileNameWithoutExtension(file).ToLower(), reader.Read(file));
            }

            foreach (var dir in Directory.GetDirectories("Z:/DBCs/"))
            {
                if (Directory.Exists(Path.Combine(dir, "DBFilesClient")))
                {
                    foreach (var file in Directory.GetFiles(Path.Combine(dir, "DBFilesClient")))
                    {
                        LoadDBC(file);
                    }
                }
                else
                {
                    foreach (var file in Directory.GetFiles(dir))
                    {
                        LoadDBC(file);
                    }
                }
            }

            Console.ReadLine();
        }
Пример #20
0
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                throw new ArgumentException("Need DBCache.bin location and DBef dir location!");
            }

            var actuallyV8 = false;

            var dumpKeys = false;

            if (args.Length == 3 && args[2] == "true")
            {
                dumpKeys = true;
            }

            var hotfixFile = args[0];

            if (!File.Exists(hotfixFile))
            {
                throw new FileNotFoundException("File " + hotfixFile + " not found!");
            }

            var definitionDir = args[1];

            if (!Directory.Exists(definitionDir))
            {
                throw new FileNotFoundException("DBD definition directory " + definitionDir + " not found!");
            }

            var tableHashes = new Dictionary <uint, string>();

            foreach (var file in Directory.GetFiles(definitionDir))
            {
                var dbName = Path.GetFileNameWithoutExtension(file);
                tableHashes.Add(Utils.Hash(dbName.ToUpper()), dbName);
            }

            var xfthMagic = 'X' << 0 | 'F' << 8 | 'T' << 16 | 'H' << 24;

            uint build;

            var hotfixes = new List <DBCacheEntry>();

            using (var ms = new MemoryStream(File.ReadAllBytes(hotfixFile)))
                using (var bin = new BinaryReader(ms))
                {
                    if (bin.ReadUInt32() != xfthMagic)
                    {
                        throw new Exception("Invalid hotfix file!");
                    }

                    var version = bin.ReadUInt32();
                    if (version != 7 && version != 8)
                    {
                        throw new Exception("Unsupported version: " + version);
                    }

                    build = bin.ReadUInt32();

                    var hash = bin.ReadBytes(32);

                    // --- Temporary code to detect if DBCache is actually V8 or not by checking if next hotfix magic is in the right spot or not
                    if (version == 8)
                    {
                        var prePos = bin.BaseStream.Position;

                        if (bin.ReadUInt32() != xfthMagic)
                        {
                            throw new Exception("Invalid hotfix entry magic!");
                        }

                        bin.ReadUInt32();               // PushID
                        bin.ReadUInt32();               // UniqueID but also maybe not!
                        bin.ReadUInt32();               // TableHash
                        bin.ReadUInt32();               // RecordID

                        var dataSize = bin.ReadInt32(); // DataSize

                        bin.ReadBytes(dataSize + 4);

                        if (bin.ReadUInt32() != xfthMagic)
                        {
                            actuallyV8 = false;
                        }
                        else
                        {
                            actuallyV8 = true;
                        }

                        bin.BaseStream.Position = prePos;
                    }
                    // -- End of temp code

                    while (bin.BaseStream.Length > bin.BaseStream.Position)
                    {
                        var hotfix = new DBCacheEntry();
                        hotfix.header = new DBCacheEntryHeader();

                        hotfix.header.magic  = bin.ReadUInt32();
                        hotfix.header.pushID = bin.ReadInt32();

                        if (actuallyV8)
                        {
                            hotfix.header.uniqueID = bin.ReadUInt32();
                        }

                        hotfix.header.tableHash = bin.ReadUInt32();
                        hotfix.header.recordID  = bin.ReadUInt32();
                        hotfix.header.dataSize  = bin.ReadInt32();
                        hotfix.header.isValid   = bin.ReadByte();
                        hotfix.header.pad0      = bin.ReadByte();
                        hotfix.header.pad1      = bin.ReadByte();
                        hotfix.header.pad2      = bin.ReadByte();

                        //hotfix.header = bin.Read<DBCacheEntryHeader>();

                        if (hotfix.header.magic != xfthMagic)
                        {
                            throw new Exception("Invalid hotfix entry magic!");
                        }

                        if (tableHashes.ContainsKey(hotfix.header.tableHash))
                        {
                            hotfix.tableName = tableHashes[hotfix.header.tableHash];
                        }
                        else
                        {
                            hotfix.tableName = "UNKNOWN " + hotfix.header.tableHash.ToString("X8");
                        }

                        hotfix.data = bin.ReadBytes(hotfix.header.dataSize);

                        hotfixes.Add(hotfix);
                    }
                }

            var dbdCache = new Dictionary <string, DBDefinition>();

            var filteredList = new List <HotfixEntry>();

            foreach (var hotfix in hotfixes)
            {
                var hotfixDataMD5 = "";
                if (hotfix.data.Length > 0)
                {
                    using (var md5 = System.Security.Cryptography.MD5.Create())
                    {
                        md5.TransformFinalBlock(hotfix.data, 0, hotfix.data.Length);
                        hotfixDataMD5 = BitConverter.ToString(md5.Hash).Replace("-", string.Empty).ToLower();
                    }
                }

                filteredList.Add(new HotfixEntry
                {
                    pushID    = hotfix.header.pushID,
                    recordID  = hotfix.header.recordID,
                    isValid   = hotfix.header.isValid,
                    tableName = hotfix.tableName,
                    dataMD5   = hotfixDataMD5
                });

                if (dumpKeys)
                {
                    if (!dbdCache.ContainsKey(hotfix.tableName) && File.Exists(Path.Combine(definitionDir, hotfix.tableName + ".dbd")))
                    {
                        var reader = new DBDReader();
                        var dbd    = reader.Read(Path.Combine(definitionDir, hotfix.tableName + ".dbd"));
                        dbdCache.Add(hotfix.tableName, dbd);
                    }

                    if (dbdCache.ContainsKey(hotfix.tableName) && hotfix.header.isValid == 1)
                    {
                        var dbd = dbdCache[hotfix.tableName];
                        VersionDefinitions?versionToUse = null;
                        var buildFound = false;

                        foreach (var definition in dbd.versionDefinitions)
                        {
                            foreach (var versionBuild in definition.builds)
                            {
                                if (versionBuild.build == build)
                                {
                                    versionToUse = definition;
                                    buildFound   = true;
                                }
                            }
                        }

                        if (buildFound)
                        {
                            long dataLength = 0;
                            var  versionDef = (VersionDefinitions)versionToUse;
                            //Console.WriteLine(hotfix.header.pad0 + " " + hotfix.header.pad1 + " " + hotfix.header.pad2 + " " + hotfix.tableName + " " + hotfix.header.recordID);
                            try
                            {
                                using (var dataBin = new BinaryReader(new MemoryStream(hotfix.data)))
                                {
                                    foreach (var field in versionDef.definitions)
                                    {
                                        if (dataBin.BaseStream.Position == dataBin.BaseStream.Length)
                                        {
                                            continue;
                                        }

                                        if (field.isNonInline && field.isID)
                                        {
                                            continue;
                                        }

                                        if (field.arrLength > 0)
                                        {
                                            for (var i = 0; i < field.arrLength; i++)
                                            {
                                                if (dataBin.BaseStream.Position == dataBin.BaseStream.Length)
                                                {
                                                    continue;
                                                }

                                                if (field.size == 0)
                                                {
                                                    if (dbd.columnDefinitions[field.name].type == "float")
                                                    {
                                                        dataBin.ReadSingle();
                                                        dataLength += 4;
                                                    }
                                                    else
                                                    {
                                                        var prevPos = dataBin.BaseStream.Position;
                                                        dataBin.ReadCString();
                                                        dataLength += dataBin.BaseStream.Position - prevPos;
                                                    }
                                                }
                                                else
                                                {
                                                    dataLength += field.size / 8;
                                                    dataBin.ReadBytes(field.size / 8);
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if (field.size == 0)
                                            {
                                                if (dbd.columnDefinitions[field.name].type == "float")
                                                {
                                                    dataBin.ReadSingle();
                                                    dataLength += 4;
                                                }
                                                else
                                                {
                                                    var prevPos = dataBin.BaseStream.Position;
                                                    dataBin.ReadCString();
                                                    dataLength += dataBin.BaseStream.Position - prevPos;
                                                }
                                            }
                                            else
                                            {
                                                dataLength += field.size / 8;
                                                dataBin.ReadBytes(field.size / 8);
                                            }
                                        }
                                    }

                                    if (dataBin.BaseStream.Length != dataBin.BaseStream.Position)
                                    {
                                        var tableHash = dataBin.ReadUInt32();
                                        if (tableHash == 0)
                                        {
                                            continue;
                                        }

                                        if (!tableHashes.ContainsKey(tableHash))
                                        {
                                            Console.WriteLine("Encountered an extra " + tableHash.ToString("X8") + " (unk table) record of " + (dataBin.BaseStream.Length - dataBin.BaseStream.Position) + " bytes in " + hotfix.tableName + " ID " + hotfix.header.recordID);
                                        }
                                        else
                                        {
                                            Console.WriteLine("Encountered an extra " + tableHashes[tableHash] + " record of " + (dataBin.BaseStream.Length - dataBin.BaseStream.Position) + " bytes in " + hotfix.tableName + " ID " + hotfix.header.recordID);

                                            if (tableHashes[tableHash] == "TactKey")
                                            {
                                                var lookup   = dataBin.ReadUInt64();
                                                var keyBytes = dataBin.ReadBytes(16);
                                                Console.WriteLine(lookup.ToString("X8").PadLeft(16, '0') + " " + BitConverter.ToString(keyBytes).Replace("-", ""));
                                            }
                                        }
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine("Encountered exception while reading record data:" + e.Message);
                            }
                        }
                    }
                }
            }

            var cache = new DBCache();

            cache.build   = build;
            cache.entries = filteredList.ToArray();

            if (!dumpKeys)
            {
                Console.WriteLine(JsonConvert.SerializeObject(cache, Formatting.None));
            }
        }
Пример #21
0
        static void Main(string[] args)
        {
            if (!Directory.Exists(args[0]))
            {
                throw new DirectoryNotFoundException("Directory " + args[0] + " does not exist!");
            }

            var builds = File.ReadAllLines("builds.txt");
            var files  = Directory.GetFiles(args[0]);

            var textWriter = new StreamWriter("output.csv");
            var csv        = new CsvWriter(textWriter);

            csv.WriteField("");

            for (var b = 0; b < builds.Length; b++)
            {
                string rotatedString = "";
                foreach (var character in builds[b])
                {
                    rotatedString += character + Environment.NewLine;
                }
                csv.WriteField(rotatedString);
            }

            csv.NextRecord();

            for (var f = 0; f < files.Length; f++)
            {
                var file   = files[f];
                var dbName = Path.GetFileNameWithoutExtension(file);

                var reader = new DBDReader();
                var dbd    = reader.Read(file);

                csv.WriteField(dbName);

                for (var b = 0; b < builds.Length; b++)
                {
                    var containsBuild = false;
                    var build         = new Build(builds[b]);

                    foreach (var versionDefinition in dbd.versionDefinitions)
                    {
                        if (versionDefinition.builds.Contains(build))
                        {
                            containsBuild = true;
                        }

                        foreach (var buildRange in versionDefinition.buildRanges)
                        {
                            if (buildRange.Contains(build))
                            {
                                containsBuild = true;
                            }
                        }
                    }

                    if (containsBuild)
                    {
                        csv.WriteField("X");
                    }
                    else
                    {
                        csv.WriteField("");
                    }
                }

                csv.NextRecord();
            }

            csv.Flush();
        }