Example #1
0
    static (ModApplier, EventExchange, AssetLoaderRegistry) BuildModApplier(string baseDir, string[] mods, IFileSystem disk, IJsonUtil jsonUtil, AssetMapping mapping)
    {
        var config   = GeneralConfig.Load(Path.Combine(baseDir, "data", "config.json"), baseDir, disk, jsonUtil);
        var applier  = new ModApplier();
        var exchange = new EventExchange(new LogExchange())
        {
            Name = $"EventExchange for {string.Join(", ", mods)}"
        };
        var assetLoaderRegistry = new AssetLoaderRegistry();

        exchange
        .Register(disk)
        .Register(jsonUtil)
        .Register <IGeneralConfig>(config)
        .Attach(new StdioConsoleLogger())
        .Attach(assetLoaderRegistry)
        .Attach(new ContainerRegistry())
        .Attach(new PostProcessorRegistry())
        .Attach(new AssetLocator())
        .Attach(new SpellManager())
        .Attach(new SettingsManager(new GeneralSettings()))     // Used for event comments
        .Attach(applier)
        ;

        applier.LoadMods(mapping, config, mods);
        return(applier, exchange, assetLoaderRegistry);
    }
Example #2
0
        public static void RoundTripTest(string baseDir)
        {
            var    loader = AssetLoaderRegistry.GetLoader <SavedGame>(FileFormat.SavedGame);
            ushort i      = 0;

            foreach (var file in Directory.EnumerateFiles(Path.Combine(baseDir, "re", "TestSaves"), "*.001"))
            {
                var key = new AssetKey(AssetType.SavedGame, i++);
                using var stream = File.Open(file, FileMode.Open);
                using var br     = new BinaryReader(stream);
                var save = loader.Serdes(null, new AlbionReader(br, stream.Length), key, null);

                using var ms = new MemoryStream();
                using var bw = new BinaryWriter(ms);
                loader.Serdes(save, new AlbionWriter(bw), key, null);

                br.BaseStream.Position = 0;
                var originalBytes  = br.ReadBytes((int)stream.Length);
                var roundTripBytes = ms.ToArray();

                //* Save round-tripped and annotated text output for debugging
                File.WriteAllBytes(file + ".bin", roundTripBytes);
                using var ts = new MemoryStream();
                using var tw = new StreamWriter(ts);
                loader.Serdes(save, new AnnotatedFormatWriter(tw), key, null);
                ts.Position = 0;
                File.WriteAllBytes(file + ".txt", ts.ToArray());
                //*/

                ApiUtil.Assert(originalBytes.Length == roundTripBytes.Length);
                ApiUtil.Assert(originalBytes.SequenceEqual(roundTripBytes));

                var sw = new StringWriter();
                loader.Serdes(save, new JsonWriter(sw, true), key, null);
                File.WriteAllText(file + ".json", sw.ToString());
                break;
            }

            Console.ReadLine();
        }
Example #3
0
        static void Main(string[] args)
        {
            var baseDir = ConfigUtil.FindBasePath();

            if (baseDir == null)
            {
                throw new InvalidOperationException("No base directory could be found.");
            }

            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); // Required for code page 850 support in .NET Core
            var commands = ParseCommands(args.Skip(1)).ToList();

            if (!commands.Any())
            {
                PrintUsage();
                return;
            }

            var filename = args[0];
            var stream   = File.OpenRead(filename);

            using var br = new BinaryReader(stream, Encoding.GetEncoding(850));
            var generalConfig           = GeneralConfig.Load(Path.Combine(baseDir, "data", "config.json"), baseDir);
            var settings                = GeneralSettings.Load(generalConfig.ResolvePath("$(DATA)/settings.json"));
            var assets                  = new AssetManager();
            var loaderRegistry          = new AssetLoaderRegistry();
            var locatorRegistry         = new AssetLocatorRegistry();
            var containerLoaderRegistry = new ContainerLoaderRegistry().AddLoader(new RawContainerLoader())
                                          .AddLoader(new XldContainerLoader())
                                          .AddLoader(new BinaryOffsetContainerLoader())
                                          .AddLoader(new ItemListContainerLoader())
                                          .AddLoader(new SpellListContainerLoader())
                                          .AddLoader(new DirectoryContainerLoader())
            ;
            var modApplier = new ModApplier()
                             // Register post-processors for handling transformations of asset data that can't be done by UAlbion.Formats alone.
                             .AddAssetPostProcessor(new AlbionSpritePostProcessor())
                             .AddAssetPostProcessor(new InventoryPostProcessor())
                             .AddAssetPostProcessor(new ItemNamePostProcessor());

            var exchange = new EventExchange(new LogExchange());

            exchange
            .Attach(settings)
            .Register <IGeneralConfig>(generalConfig)
            .Attach(loaderRegistry)
            .Attach(locatorRegistry)
            .Attach(containerLoaderRegistry)
            .Attach(modApplier)
            .Attach(assets)
            ;

            modApplier.LoadMods(generalConfig);
            var save = SavedGame.Serdes(null, AssetMapping.Global, new AlbionReader(br, stream.Length));

            if (!VerifyRoundTrip(stream, save, AssetMapping.Global))
            {
                return;
            }

            foreach (var command in commands)
            {
                command.Action(save);
                Console.WriteLine();
            }
        }
Example #4
0
        static async Task <(EventExchange, IContainer)> SetupAssetSystem(string baseDir)
        {
            var generalConfigTask = Task.Run(() =>
            {
                var result = GeneralConfig.Load(Path.Combine(baseDir, "data", "config.json"), baseDir);
                PerfTracker.StartupEvent("Loaded general config");
                return(result);
            });
            var settingsTask = Task.Run(() =>
            {
                var result = GeneralSettings.Load(Path.Combine(baseDir, "data", "settings.json"));
                PerfTracker.StartupEvent("Loaded settings");
                return(result);
            });
            var coreConfigTask = Task.Run(() =>
            {
                var result = CoreConfig.Load(Path.Combine(baseDir, "data", "core.json"));
                PerfTracker.StartupEvent("Loaded core config");
                return(result);
            });
            var gameConfigTask = Task.Run(() =>
            {
                var result = GameConfig.Load(Path.Combine(baseDir, "data", "game.json"));
                PerfTracker.StartupEvent("Loaded game config");
                return(result);
            });

            var assets                  = new AssetManager();
            var factory                 = new VeldridCoreFactory();
            var loaderRegistry          = new AssetLoaderRegistry();
            var locatorRegistry         = new AssetLocatorRegistry();
            var containerLoaderRegistry = new ContainerLoaderRegistry().AddLoader(new RawContainerLoader())
                                          .AddLoader(new XldContainerLoader())
                                          .AddLoader(new BinaryOffsetContainerLoader())
                                          .AddLoader(new ItemListContainerLoader())
                                          .AddLoader(new SpellListContainerLoader())
                                          .AddLoader(new DirectoryContainerLoader())
            ;

            var modApplier = new ModApplier()
                             // Register post-processors for handling transformations of asset data that can't be done by UAlbion.Formats alone.
                             .AddAssetPostProcessor(new AlbionSpritePostProcessor())
                             .AddAssetPostProcessor(new ImageSharpPostProcessor())
                             .AddAssetPostProcessor(new InterlacedBitmapPostProcessor())
                             .AddAssetPostProcessor(new InventoryPostProcessor())
                             .AddAssetPostProcessor(new ItemNamePostProcessor());

            var settings = await settingsTask.ConfigureAwait(false);

            var services = new Container("Services", settings, // Need to register settings first, as the AssetLocator relies on it.
                                         loaderRegistry, locatorRegistry, containerLoaderRegistry, new MetafontBuilder(factory), new StdioConsoleLogger(),
                                                               // new ClipboardManager(),
                                         new ImGuiConsoleLogger(), new WordLookup(), new AssetLocator(), modApplier, assets);

            var generalConfig = await generalConfigTask.ConfigureAwait(false);

            using var exchange = new EventExchange(new LogExchange()).Register <IGeneralConfig>(generalConfig)
                                 .Register <ICoreFactory>(factory)
                                 .Attach(services);
            PerfTracker.StartupEvent("Registered asset services");

            Engine.GlobalExchange = exchange;
            generalConfig.SetPath("LANG", settings.Language.ToString()
                                  .ToUpperInvariant()); // Ensure that the LANG path is set before resolving any assets
            modApplier.LoadMods(generalConfig);
            PerfTracker.StartupEvent("Loaded mods");

            var coreConfig = await coreConfigTask.ConfigureAwait(false);

            var gameConfig = await gameConfigTask.ConfigureAwait(false);

            exchange // Need to load game config after mods so asset ids can be parsed.
            .Register(coreConfig)
            .Register(gameConfig);
            PerfTracker.StartupEvent("Loaded core and game config");
            return(exchange, services);
        }