public static async Task Main(string[] args)
        {
            Console.WriteLine(DBCToolsExtensions.BuildToolsWelcomeMessage("CreateJSON"));

            //Try to load configuration file
            Config = new ApplicationConfigurationLoader().BuildConfigFile();

            if (!Directory.Exists(Config.DiffOutputPath))
            {
                Directory.CreateDirectory(Config.DiffOutputPath);
            }

            Parallel.ForEach(Directory.GetFiles(Config.DbcOutputPath).Select(Path.GetFileNameWithoutExtension), async dbcFile =>
            {
                DbcTypeParser parser = new DbcTypeParser();
                if (!parser.HasDbcType(dbcFile))
                {
                    //TODO: We should create a logger specifically for Program.
                    if (Config.LoggingLevel >= LogLevel.Warning)
                    {
                        Console.WriteLine($"Encountered unknown DBC Type: {dbcFile}. Will skip.");
                    }

                    return;
                }

                IServiceProvider provider = new JSONContainerServiceBuilder(Config, dbcFile).Build();

                using (var scope = provider.CreateScope())
                {
                    ILogger <Program> logger = scope.ServiceProvider.GetService <ILogger <Program> >();

                    try
                    {
                        if (logger.IsEnabled(LogLevel.Information))
                        {
                            logger.LogInformation($"Populating CSV file for DBC: {dbcFile}");
                        }

                        //This may look silly but we want to support the 50+ DBC types so
                        //it needs to be handle magically otherwise we'd have to write code for each one.
                        IDbcTargetFillable tableFiller = scope.ServiceProvider.GetService <IDbcTargetFillable>();

                        await tableFiller.FillAsync()
                        .ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        if (logger.IsEnabled(LogLevel.Error))
                        {
                            logger.LogError($"Encountered Exception: {e.Message} \n\n Stack: {e.StackTrace}");
                        }

                        throw;
                    }
                }
            });

            Console.WriteLine("Finished. Press any key!");
        }
Esempio n. 2
0
        static async Task Main(string[] args)
        {
            Console.WriteLine(DBCToolsExtensions.BuildToolsWelcomeMessage("CreateGDBC"));

            //Try to load configuration file
            Config = new ApplicationConfigurationLoader().BuildConfigFile();

            DbcTypeParser dbcTypeParser = new DbcTypeParser();

            Directory.CreateDirectory($"G{Config.DbcOutputPath}");

            //For each implement DBCType we should try to build a DBC file for it.
            foreach (Type dbcType in dbcTypeParser.ComputeAllKnownDbcTypes())
            {
                string           dbcName  = dbcTypeParser.GetDbcName(dbcType);
                IServiceProvider provider = new CreateGDbcContainerServiceBuilder(Config, dbcType).Build();

                using (IServiceScope scope = provider.CreateScope())
                {
                    IDbcTargetFillable fillable = scope.ServiceProvider.GetService <IDbcTargetFillable>();

                    if (fillable == null)
                    {
                        throw new InvalidOperationException($"Failed to load Fillable for Type: {dbcType.Name}");
                    }

                    await fillable.FillAsync();

                    using (Stream ms = scope.ServiceProvider.GetRequiredService <Stream>())
                    {
                        //it is important to reset this position
                        //Since we're 20 bytes in after likely writing the header last
                        //Though the above statement could change, either way we want to be at the begining.
                        ms.Position = 0;

                        //It is possible nothing has been written, this is kinda hacky to put this
                        //and leak this in a couple places. But it means no entires were found.
                        if (ms.Length == 0)
                        {
                            continue;
                        }

                        //Once everything has been filled we should create the file
                        using (FileStream fs = new FileStream($"G{Config.DbcOutputPath}/{dbcName}.gdbc", FileMode.CreateNew, FileAccess.ReadWrite))
                        {
                            await ms.CopyToAsync(fs);
                        }
                    }
                }
            }

            Console.WriteLine("Finished. Press any key!");
        }
        /// <summary>
        /// Builds a <see cref="IServiceProvider"/> that registers
        /// <see cref="IDbcTargetFillable"/> which is the only service you should
        /// request from the container. This service will handle all complex
        /// logic for inserting and saving to the database. This is done so that support
        /// for 50 different DBC models and tables can be handled by one single set of generic services.
        /// </summary>
        /// <returns></returns>
        public IServiceProvider Build()
        {
            //With only the filename (which is why args will be passed in when this is a tool)
            //we need to be able to know the DBC model type AND we need to know what Types to use
            //to do the handling
            //We always need the TypeConverters so we register them first.
            ContainerBuilder  builder           = new ContainerBuilder();
            ServiceCollection serviceCollection = new ServiceCollection();

            builder.RegisterTypeConvertersFromAssembly(typeof(Program).Assembly);
            RegisterCreateDatabaseDatabaseService(serviceCollection);
            Type dbcModelType = new DbcTypeParser().ComputeDbcType(DbcType);

            TypedParameter pathParameter = CreateInputPathParameter();

            //TODO: Support configurable DBC location/path.

            //If it's an open generic model it will mean that it requires string type type args
            //Not requiring this is much simplier, but it is still doable when the model is generic
            if (!dbcModelType.IsGenericTypeDefinition)
            {
                RegisterNonGenericDbcModelServices(builder, dbcModelType, pathParameter);
            }
            else
            {
                RegisterGenericDbcModelServices(builder, dbcModelType, pathParameter);
            }

            //TODO: Create a parsed string type so this dictionary is not exposed
            //May look odd but some TypeConverters actually need the string database
            //so they can convert from string offset/pointer to the actual string for the database.
            builder.Register <IReadOnlyDictionary <uint, string> >(context =>
            {
                IDbcStringReadable readable = context.Resolve <IDbcStringReadable>();

                //This is blocking
                return(readable.ParseOnlyStrings()
                       .ConfigureAwait(false)
                       .GetAwaiter()
                       .GetResult());
            })
            .SingleInstance()
            .As <IReadOnlyDictionary <uint, string> >();

            //TODO: Make logging optional
            serviceCollection.RegisterLoggingServices(Config.LoggingLevel);

            //This takes the ASP/Core service collection and pushes it all into AutoFac.
            builder.Populate(serviceCollection);

            return(new AutofacServiceProvider(builder.Build()));
        }
        public static void Test_DBC_File_Converts_To_Table_Back_To_Same_DBC_File(Type t)
        {
            //arrange
            DbcTypeParser parser   = new DbcTypeParser();
            string        dbcType  = parser.GetDbcName(t);
            string        filePath = Path.Combine(TestContext.CurrentContext.TestDirectory, "DBC", $"{dbcType}.dbc");

            if (!File.Exists(filePath))
            {
                Assert.Inconclusive($"No DBC file test into provided for Type: {t.Name}");
            }

            ApplicationConfiguration config = new ApplicationConfiguration("test", true, LogLevel.Debug, Path.Combine(TestContext.CurrentContext.TestDirectory, "DBC"), "DBC_OUTPUT", "MPQ", "patch-6", "JSON");

            //If we have a DBC file then we should prepare the DBC to Database stuff
            //so we can create an in memory database
            using (MockCreateDatabaseContainerServiceBuilder databaseCreatorContainer = new MockCreateDatabaseContainerServiceBuilder(config, dbcType, filePath))
            {
                IServiceProvider databaseCreatorServiceProvider = databaseCreatorContainer.Build();

                databaseCreatorServiceProvider.GetService <IDbcTargetFillable>().Fill();

                //At this point the inmemory database is filled.
                MockedCreateDbcContainerServiceBuilder dbcCreatorContainer = new MockedCreateDbcContainerServiceBuilder(config, t, databaseCreatorServiceProvider.GetService <DbContext>());

                IServiceProvider dbcCreatorServiceProvider = dbcCreatorContainer.Build();

                dbcCreatorServiceProvider.GetService <IDbcTargetFillable>().Fill();

                //At this point the DBC file should be in DbContext and the table should have
                //been loaded and turned back into a DBC file. Meaning we can now compare streams
                using (FileStream MockedFileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                    using (BinaryReader binaryRead2 = new BinaryReader(dbcCreatorServiceProvider.GetService <Stream>()))
                        using (BinaryReader binaryRead1 = new BinaryReader(MockedFileStream))
                        {
                            binaryRead2.BaseStream.Position = 0;
                            binaryRead1.BaseStream.Position = 0;

                            byte[] originalBytes = binaryRead1.ReadBytes((int)MockedFileStream.Length);
                            byte[] outputBytes   = binaryRead2.ReadBytes((int)binaryRead2.BaseStream.Length);

                            Assert.AreEqual(originalBytes.Length, outputBytes.Length, $"Mismatch length on DBC to SQL to DBC for Type: {dbcType}");

                            for (int i = 0; i < originalBytes.Length; i++)
                            {
                                Assert.AreEqual(originalBytes[i], outputBytes[i], $"Mismatched value on DBC to SQL to DBC for Type: {dbcType} for Index: {i}");
                            }
                        }
            }
        }
Esempio n. 5
0
        static async Task Main(string[] args)
        {
            //Try to load configuration file
            Config = new ApplicationConfigurationLoader().BuildConfigFile();

            //TODO: This is just test code, we want to handle inputs better.
            Console.WriteLine($"Will create tables and database if they do not exist.");

            //TODO: We shouldn't check everytime we create a DBC table. Do this elsewhere
            await CreateDatabaseIfNotCreated();

            ConsoleLogger defaultLogger = new ConsoleLogger("Console", (s, level) => level >= Config.LoggingLevel, false);

            foreach (string dbcFile in Directory.GetFiles("DBC").Select(Path.GetFileNameWithoutExtension))
            {
                //TODO: Register in IoC
                DbcTypeParser parser = new DbcTypeParser();
                if (!parser.HasDbcType(dbcFile))
                {
                    //TODO: We should create a logger specifically for Program.
                    if (defaultLogger.IsEnabled(LogLevel.Warning))
                    {
                        defaultLogger.LogWarning($"Encountered unknown DBC Type: {dbcFile}. Will skip.");
                    }

                    continue;
                }

                //We should check if we know a DBC file of this type.
                IServiceProvider provider = new CreateDatabaseContainerServiceBuilder(Config, dbcFile).Build();

                Stopwatch watch = new Stopwatch();
                watch.Start();
                using (var scope = provider.CreateScope())
                {
                    ILogger <Program> logger = scope.ServiceProvider.GetService <ILogger <Program> >();

                    try
                    {
                        if (logger.IsEnabled(LogLevel.Information))
                        {
                            logger.LogInformation($"Populating table for DBC: {dbcFile}");
                        }

                        //This may look silly but we want to support the 50+ DBC types so
                        //it needs to be handle magically otherwise we'd have to write code for each one.
                        IDbcTargetFillable tableFiller = scope.ServiceProvider.GetService <IDbcTargetFillable>();

                        await tableFiller.FillAsync();
                    }
                    catch (Exception e)
                    {
                        if (logger.IsEnabled(LogLevel.Error))
                        {
                            logger.LogError($"Encountered Exception: {e.Message} \n\n Stack: {e.StackTrace}");
                        }

                        throw;
                    }
                }

                watch.Stop();

                if (defaultLogger.IsEnabled(LogLevel.Information))
                {
                    defaultLogger.LogInformation($"Created Table: {dbcFile} In Milliseconds: {watch.ElapsedMilliseconds}");
                }
            }

            defaultLogger.LogWarning("Finished. Press any key!");
            Console.ReadKey();
        }