private static void LoadRemoteMappings(MappingDatabase mappingDatabase, string version)
        {
            Lumberjack.Log("Fetching mapping versions from remote...");
            var yarnVersions = YarnUtil.GetYarnVersions();

            if (yarnVersions == null)
            {
                // If we couldn't get them, try to use the ones we've already cached

                Lumberjack.Warn("Working in offline mode. Only local Yarn mappings will be available.");
                yarnVersions = mappingDatabase.GetYarnVersions();
            }

            if (yarnVersions.All(mapping => mapping.Version != version))
            {
                // If a specific mapping version was specified that doesn't exist in the version listing, fail

                Lumberjack.Error($"Could not find mapping version {version}!");
                return;
            }

            var mappingVersion = yarnVersions.First(mapping => mapping.Version == version);

            if (!mappingDatabase.HasMappingSet(mappingVersion))
            {
                // If we don't have those mappings cached, download them and cache them

                Lumberjack.Log("Fetching mappings from remote...");
                var mappings = YarnUtil.GetYarnMappings(mappingVersion);

                if (mappings != null)
                {
                    Lumberjack.Log("Updating database...");
                    mappingDatabase.CreateMappingSet(mappingVersion, mappings);
                }
                else
                {
                    Lumberjack.Error($"Failed to load requested mappings {mappingVersion.Version}");
                    Environment.Exit((int)ExitConditions.MappingVersionNotFound);
                }
            }
            else
            {
                Lumberjack.Log("Local database contains required mappings.");
            }

            InteractiveMapper.SetYarnVersion(mappingVersion);

            Lumberjack.Log($"Using mappings from yarn {version}");
        }
Exemplo n.º 2
0
        /// <summary>
        /// Remaps the given jar with the specified mappings and output directory
        /// </summary>
        /// <param name="args">The command line flags for the conversion</param>
        /// <remarks>
        /// Most of the logic here is finding and loading mappings. The general flow is as
        /// follows: If you supplied a Tiny mapping file, use that. Otherwise, download the mapping
        /// metadata from the Yarn site. If you provided a yarn version, make sure it's valid and then
        /// use that one. If you didn't, try to pick the mapping based on the game version listed in
        /// the dependencies of the fabric.mod.json in the archive. If it doesn't exist, fail hard.
        ///
        /// With the mapping version in hand, see if we already cached the mappings in the database,
        /// and download them if we hadn't.
        /// </remarks>
        private static void DoRemap(Options args)
        {
            BaseDirConfig = args.ConfigDirBase;
            BaseDirOutput = args.OutputDirBase;

            if (args.InputArchive == null)
            {
                InteractiveMapper.Run();
            }

            // Quick fail if the input archive doesn't exist
            if (!File.Exists(args.InputArchive))
            {
                Lumberjack.Error($"Input file \"{args.InputArchive}\" does not exist!");
                Environment.Exit((int)ExitConditions.InputFileNotFound);
            }

            // Load local mapping database
            Lumberjack.Log("Loading mapping database...");
            _mappingDatabase = new MappingDatabase(Path.Combine(BaseDirConfig, "mappings.db"));

            // Try to pick a mapping version manually or automatically
            YarnVersion mappingVersion = null;

            if (args.LocalTinyFile != null)
            {
                // Try and load mappings from a specific local .tiny file (if provided)

                Lumberjack.Log("Loading mappings from local file...");
                if (!File.Exists(args.LocalTinyFile))
                {
                    Lumberjack.Error($"Tiny v1 file \"{args.LocalTinyFile}\" does not exist!");
                    Environment.Exit((int)ExitConditions.TinyFileNotFound);
                }

                mappingVersion = new YarnVersion
                {
                    Version = args.LocalTinyFile
                };
                _mappingDatabase.UseLocalFile(args.LocalTinyFile);
            }
            else
            {
                // Download all of the mapping versions from the Yarn API

                Lumberjack.Log("Fetching mapping versions from remote...");
                var yarnVersions = YarnUtil.GetYarnVersions();

                if (yarnVersions == null)
                {
                    // If we couldn't get them, try to use the ones we've already cached

                    Lumberjack.Warn("Working in offline mode. Only local Yarn mappings will be available.");
                    yarnVersions = _mappingDatabase.GetYarnVersions();
                }

                if (args.MappingVersion != null)
                {
                    if (yarnVersions.All(mapping => mapping.Version != args.MappingVersion))
                    {
                        // If a specific mapping version was specified that doesn't exist in the version listing, fail

                        Lumberjack.Error($"Could not find mapping version {args.MappingVersion}!");
                        Environment.Exit((int)ExitConditions.MappingVersionNotFound);
                    }

                    mappingVersion = yarnVersions.First(mapping => mapping.Version == args.MappingVersion);
                }

                Lumberjack.Log("Retrieving game version from jarfile...");
                var gameVersion = JarUtils.GetGameVersion(args.InputArchive);

                if (mappingVersion == null)
                {
                    // If no mapping version was specified in any form, select one based off of the game target version

                    if (gameVersion == null)
                    {
                        // If there's no Minecraft version dependency in the fabric.mod.json, fail

                        Lumberjack.Error(
                            "Could not find fabric.mod.json in archive! Try specifying the Yarn version manually.");
                        Environment.Exit((int)ExitConditions.FabricModJsonNotFound);
                    }

                    Lumberjack.Log($"Found game version: {gameVersion}");

                    // Get the latest mapping version compatible with the jar game version
                    mappingVersion =
                        yarnVersions.FirstOrDefault(yarnVersion => YarnUtil.DoVersionsMatch(yarnVersion, gameVersion));

                    if (mappingVersion == null)
                    {
                        // If no mapping was compatible, fail
                        // This should only really happen if we're in offline mode and only able to use locally cached mappings

                        Lumberjack.Error(
                            $"Could not automatically find a mapping compatible with game version {gameVersion}");
                        Environment.Exit((int)ExitConditions.MappingVersionNotFound);
                    }

                    Lumberjack.Log(
                        $"Latest mapping that matches game version from jarfile is {mappingVersion.Version}");
                }
                else if (gameVersion != null)
                {
                    // If a specific Yarn version was specified, check the game version anyway and spit out an error if they're probably not compatible

                    // We continue anyway because we assume if they're specifying mapping versions manually they probably know they're not compatible
                    // and have a reason to need that version

                    Lumberjack.Log($"Input jarfile has fabric.mod.json, specifying gave version {gameVersion}");
                    if (!YarnUtil.DoVersionsMatch(mappingVersion, gameVersion))
                    {
                        Lumberjack.Warn(
                            $"Game version {gameVersion} is not compatible with yarn version {mappingVersion.Version}, some mappings might not exist!");
                    }
                }

                if (!_mappingDatabase.HasMappingSet(mappingVersion))
                {
                    // If we don't have those mappings cached, download them and cache them

                    Lumberjack.Log("Fetching mappings from remote...");
                    var mappings = YarnUtil.GetYarnMappings(mappingVersion);

                    if (mappings != null)
                    {
                        Lumberjack.Log("Updating database...");
                        _mappingDatabase.CreateMappingSet(mappingVersion, mappings);
                    }
                    else
                    {
                        Lumberjack.Error($"Failed to load requested mappings {mappingVersion.Version}");
                        Environment.Exit((int)ExitConditions.MappingVersionNotFound);
                    }
                }
                else
                {
                    Lumberjack.Log("Local database contains required mappings.");
                }
            }

            // Load mappings and map the archive into the output directory
            Lumberjack.Log($"Loading {mappingVersion.Version} mappings...");

            var mappingSet = _mappingDatabase.GetMappingSet(mappingVersion);

            Lumberjack.PushCategory("Jar");
            Mapper.MapArchive(mappingSet, args.InputArchive, args.OutputDir ?? $"{Path.GetFileNameWithoutExtension(args.InputArchive)}-mapped");
            Lumberjack.PopCategory();

            Lumberjack.Log("Done. Press any key to continue.");
            Console.ReadKey();
            Environment.Exit((int)ExitConditions.Success);
        }