Пример #1
0
        /// <summary>
        ///     构造函数。
        ///     Constructor.
        /// </summary>
        /// <param name="rootPath">指.minecraft/ Refers to .minecraft/</param>
        /// <param name="clientToken"></param>
        public DefaultVersionLocator(string rootPath, Guid clientToken)
        {
            RootPath = rootPath; // .minecraft/
            LauncherProfileParser = new DefaultLauncherProfileParser(rootPath, clientToken);

            //防止给定路径不存在的时候Parser遍历文件夹爆炸。
            //Prevents errors in the parser's folder traversal when the given path does not exist.
            if (!Directory.Exists(GamePathHelper.GetVersionPath(RootPath)))
            {
                Directory.CreateDirectory(GamePathHelper.GetVersionPath(RootPath));
            }
        }
Пример #2
0
        /// <summary>
        ///     保存整个launcher_profiles
        /// </summary>
        public void SaveProfile()
        {
            if (File.Exists(GamePathHelper.GetLauncherProfilePath(RootPath)))
            {
                File.Delete(GamePathHelper.GetLauncherProfilePath(RootPath));
            }

            var launcherProfileJson = JsonConvert.SerializeObject(LauncherProfile, new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            });

            FileHelper.Write(GamePathHelper.GetLauncherProfilePath(RootPath), launcherProfileJson);
        }
Пример #3
0
        public override IEnumerable <VersionInfo> GetAllGames()
        {
            // 把每个DirectoryInfo类映射到VersionInfo类。
            // Map each DirectoryInfo dir to VersionInfo class.
            var di = new DirectoryInfo(GamePathHelper.GetVersionPath(RootPath));

            foreach (var dir in di.EnumerateDirectories())
            {
                var version = ToVersion(dir.Name);
                if (version == null)
                {
                    continue;
                }
                yield return(version);
            }
        }
Пример #4
0
        public async Task <string> InstallTaskAsync()
        {
            InvokeStatusChangedEvent("开始安装", 0);

            var jsonUrl = "https://fabricmc.net/download/technic/?yarn="
                          + Uri.EscapeDataString(YarnArtifact.Version)
                          + "&loader="
                          + Uri.EscapeDataString(LoaderArtifact.Loader.Version);
            var jsonContentRes = await HttpHelper.Get(jsonUrl);

            var jsonContent = await jsonContentRes.Content.ReadAsStringAsync();

            var versionModel = JsonConvert.DeserializeObject <RawVersionModel>(jsonContent);
            var id           = string.IsNullOrEmpty(CustomId)
                ? $"{YarnArtifact.GameVersion}-fabric{YarnArtifact.Version}-{LoaderArtifact.Loader.Version}"
                : CustomId;

            versionModel.Id           = id;
            versionModel.InheritsFrom = YarnArtifact.GameVersion;

            InvokeStatusChangedEvent("解析 Libraries 完成", 23.3333);

            var dir = Path.Combine(RootPath, GamePathHelper.GetGamePath(id));
            var di  = new DirectoryInfo(dir);

            if (!di.Exists)
            {
                di.Create();
            }
            else
            {
                DirectoryHelper.CleanDirectory(di.FullName);
            }

            var resultJson = JsonConvert.SerializeObject(versionModel, JsonHelper.CamelCasePropertyNamesSettings);

            InvokeStatusChangedEvent("生成版本总成", 70);
            var jsonPath = GamePathHelper.GetGameJsonPath(RootPath, id);

            InvokeStatusChangedEvent("将版本 Json 写入文件", 90);

            await File.WriteAllTextAsync(jsonPath, resultJson);

            InvokeStatusChangedEvent("安装完成", 100);

            return(id);
        }
Пример #5
0
        public string ParseGameArguments(AuthResultBase authResult)
        {
            var mcArgumentsDic = new Dictionary <string, string>
            {
                { "${version_name}", LaunchSettings.Version },
                { "${version_type}", GameProfile?.Type ?? $"\"{LaunchSettings.LauncherName}\"" },
                { "${assets_root}", $"\"{AssetRoot}\"" },
                { "${assets_index_name}", $"\"{VersionInfo.AssetInfo.Id}\"" },
                {
                    "${game_directory}",
                    $"\"{GamePathHelper.GetGamePath(LaunchSettings.Version)}\""
                },
                { "${auth_player_name}", authResult?.SelectedProfile?.Name },
                { "${auth_uuid}", authResult?.SelectedProfile?.UUID.ToString() },
                { "${auth_access_token}", authResult?.AccessToken },
                { "${user_properties}", authResult?.User?.Properties.ResolveUserProperties() },
                { "${user_type}", "Mojang" } // use default value as placeholder
            };

            return(StringHelper.ReplaceByDic(VersionInfo.GameArguments, mcArgumentsDic));
        }
Пример #6
0
        /// <summary>
        ///     构造函数
        /// </summary>
        /// <param name="rootPath"></param>
        /// <param name="clientToken"></param>
        public DefaultLauncherProfileParser(string rootPath, Guid clientToken)
        {
            RootPath = rootPath;

            if (!File.Exists(GamePathHelper.GetLauncherProfilePath(RootPath)))
            {
                var launcherProfile = new LauncherProfileModel
                {
                    AuthenticationDatabase = new Dictionary <string, AuthInfoModel>(),
                    ClientToken            = clientToken.ToString("D"),
                    LauncherVersion        = new LauncherVersionModel
                    {
                        Format = 1,
                        Name   = ""
                    },
                    Profiles = new Dictionary <string, GameProfileModel>()
                };

                LauncherProfile = launcherProfile;

                var launcherProfileJson = JsonConvert.SerializeObject(launcherProfile, new JsonSerializerSettings
                {
                    ContractResolver = new CamelCasePropertyNamesContractResolver()
                });

                if (!Directory.Exists(RootPath))
                {
                    Directory.CreateDirectory(RootPath);
                }

                FileHelper.Write(GamePathHelper.GetLauncherProfilePath(RootPath), launcherProfileJson);
            }
            else
            {
                var launcherProfileJson =
                    File.ReadAllText(GamePathHelper.GetLauncherProfilePath(rootPath), Encoding.UTF8);
                LauncherProfile = JsonConvert.DeserializeObject <LauncherProfileModel>(launcherProfileJson);
            }
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="launchSettings">启动设置</param>
        /// <param name="launcherProfileParser">Mojang官方launcher_profiles.json适配组件</param>
        /// <param name="versionLocator"></param>
        /// <param name="authResult"></param>
        /// <param name="rootPath"></param>
        /// <param name="rootVersion"></param>
        public DefaultLaunchArgumentParser(LaunchSettings launchSettings, ILauncherProfileParser launcherProfileParser, IVersionLocator versionLocator, AuthResult authResult, string rootPath, string rootVersion)
        {
            if (launchSettings == null || launcherProfileParser == null)
            {
                throw new ArgumentNullException();
            }

            AuthResult            = authResult;
            VersionLocator        = versionLocator;
            RootPath              = rootPath;
            LaunchSettings        = launchSettings;
            LauncherProfileParser = launcherProfileParser;
            VersionInfo           = LaunchSettings.VersionLocator.GetGame(LaunchSettings.Version);
            GameProfile           = LauncherProfileParser.GetGameProfile(LaunchSettings.GameName);

            ClassPath = string.Join(string.Empty,
                                    VersionInfo.Libraries.Select(l =>
                                                                 $"{GamePathHelper.GetLibraryPath(launchSettings.GameResourcePath, l.Path.Replace('/', '\\'))};"));
            ClassPath += string.IsNullOrEmpty(rootVersion)
                ? GamePathHelper.GetGameExecutablePath(rootPath, launchSettings.Version)
                : GamePathHelper.GetGameExecutablePath(rootPath, rootVersion);
            LastAuthResult = LaunchSettings.Authenticator.GetLastAuthResult();
        }
Пример #8
0
        /// <summary>
        ///     构造函数
        /// </summary>
        /// <param name="rootPath"></param>
        /// <param name="clientToken"></param>
        public DefaultLauncherProfileParser(string rootPath, Guid clientToken)
        {
            RootPath = rootPath;
            FullLauncherProfilePath = Path.Combine(rootPath, GamePathHelper.GetLauncherProfilePath());

            if (!File.Exists(FullLauncherProfilePath))
            {
                var launcherProfile = new LauncherProfileModel
                {
                    ClientToken     = clientToken.ToString("D"),
                    LauncherVersion = new LauncherVersionModel
                    {
                        Format = 1,
                        Name   = string.Empty
                    },
                    Profiles = new Dictionary <string, GameProfileModel>()
                };

                LauncherProfile = launcherProfile;

                var launcherProfileJson =
                    JsonConvert.SerializeObject(launcherProfile, JsonHelper.CamelCasePropertyNamesSettings);

                if (!Directory.Exists(RootPath))
                {
                    Directory.CreateDirectory(RootPath);
                }

                File.WriteAllText(FullLauncherProfilePath, launcherProfileJson);
            }
            else
            {
                var launcherProfileJson =
                    File.ReadAllText(FullLauncherProfilePath, Encoding.UTF8);
                LauncherProfile = JsonConvert.DeserializeObject <LauncherProfileModel>(launcherProfileJson);
            }
        }
Пример #9
0
        /// <summary>
        /// 解析基础游戏JSON信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private protected override RawVersionModel ParseRawVersion(string id)
        {
            if (!Directory.Exists(GamePathHelper.GetGamePath(RootPath, id)))
            {
                return(null);
            }
            if (!File.Exists(GamePathHelper.GetGameJsonPath(RootPath, id)))
            {
                return(null);
            }

            var versionJson = JsonConvert.DeserializeObject <RawVersionModel>(File.ReadAllText(GamePathHelper.GetGameJsonPath(RootPath, id)));

            if (string.IsNullOrEmpty(versionJson.MainClass))
            {
                return(null);
            }
            if (string.IsNullOrEmpty(versionJson.MinecraftArguments) && versionJson.Arguments == null)
            {
                return(null);
            }

            return(versionJson);
        }
Пример #10
0
        /// <summary>
        ///     游戏信息解析。
        ///     Game info analysis.
        /// </summary>
        /// <param name="id">游戏文件夹名。Name of the game version's folder.</param>
        /// <returns>一个VersionInfo类。A VersionInfo class.</returns>
        private protected override VersionInfo ToVersion(string id)
        {
            // 反序列化。
            // Deserialize.
            var rawVersion = ParseRawVersion(id);

            if (rawVersion == null)
            {
                return(null);
            }

            List <RawVersionModel> inherits = null;

            // 检查游戏是否存在继承关系。
            // Check if there is inheritance.
            if (!string.IsNullOrEmpty(rawVersion.InheritsFrom))
            {
                // 存在继承关系。
                // Inheritance exists.

                inherits = new List <RawVersionModel>();
                var current = rawVersion;
                var first   = true;

                // 递归式地将所有反序列化的版本继承塞进一个表中。
                // Add all deserialized inherited version to a list recursively.
                while (current != null && !string.IsNullOrEmpty(current.InheritsFrom))
                {
                    if (first)
                    {
                        inherits.Add(current);
                        first   = false;
                        current = ParseRawVersion(current.InheritsFrom);
                        inherits.Add(current);
                        continue;
                    }

                    inherits.Add(ParseRawVersion(current.InheritsFrom));
                    current = ParseRawVersion(current.InheritsFrom);
                }

                if (inherits.Contains(null))
                {
                    return(null);
                }
            }

            // 生成一个随机的名字来防止重复。
            // Generates a random name to avoid duplication.

            /*
             * var rs = new RandomStringHelper().UseLower().UseUpper().UseNumbers().Shuffle(1);
             * var randomName =
             *  $"{id}-{rs.Generate(5)}-{rs.Generate(5)}";
             */

            var result = new VersionInfo
            {
                AssetInfo   = rawVersion.AssetIndex,
                MainClass   = rawVersion.MainClass,
                Libraries   = new List <FileInfo>(),
                Natives     = new List <NativeFileInfo>(),
                Id          = rawVersion.Id,
                DirName     = id,
                Name        = id, //randomName,
                JavaVersion = rawVersion.JavaVersion
            };

            // 检查游戏是否存在继承关系。
            // Check if there is inheritance.
            if (inherits?.Any() ?? false)
            {
                // 存在继承关系。
                // Inheritance exists.

                var flag       = true;
                var jvmSb      = new StringBuilder();
                var gameArgsSb = new StringBuilder();

                result.RootVersion = inherits.Last().Id;

                // 遍历所有的继承
                // Go through all inherits
                for (var i = inherits.Count - 1; i >= 0; i--)
                {
                    if (result.JavaVersion == null && inherits[i].JavaVersion != null)
                    {
                        result.JavaVersion = inherits[i].JavaVersion;
                    }
                    if (result.AssetInfo == null && inherits[i].AssetIndex != null)
                    {
                        result.AssetInfo = inherits[i].AssetIndex;
                    }

                    if (flag)
                    {
                        var rootLibs = GetNatives(inherits[i].Libraries);

                        result.Libraries = rootLibs.Item2;
                        result.Natives   = rootLibs.Item1;

                        jvmSb.Append(ParseJvmArguments(inherits[i].Arguments?.Jvm));

                        var rootArgs = ParseGameArguments((inherits[i].MinecraftArguments,
                                                           inherits[i].Arguments?.Game));
                        gameArgsSb.Append(rootArgs.Item1);
                        result.AvailableGameArguments = rootArgs.Item2;

                        flag = false;
                        continue;
                    }

                    var middleLibs = GetNatives(inherits[i].Libraries);

                    foreach (var mL in middleLibs.Item2)
                    {
                        var mLMaven = mL.Name.ResolveMavenString();
                        var mLFlag  = false;
                        for (var j = 0; j < result.Libraries.Count; j++)
                        {
                            var lMaven = result.Libraries[j].Name.ResolveMavenString();
                            if (!lMaven.GetMavenFullName().Equals(mLMaven.GetMavenFullName(), StringComparison.Ordinal))
                            {
                                continue;
                            }

                            var v1 = new Version(lMaven.Version);
                            var v2 = new Version(mLMaven.Version);

                            if (v2 > v1)
                            {
                                result.Libraries[j] = mL;
                            }

                            mLFlag = true;
                        }

                        if (mLFlag)
                        {
                            continue;
                        }

                        result.Libraries.Add(mL);
                    }

                    var currentNativesNames = new List <string>();
                    result.Natives.ForEach(n => { currentNativesNames.Add(n.FileInfo.Name); });
                    var moreMiddleNatives =
                        middleLibs.Item1.AsParallel().Where(mL => !currentNativesNames.Contains(mL.FileInfo.Name))
                        .ToList();
                    result.Natives.AddRange(moreMiddleNatives);


                    var jvmArgs        = ParseJvmArguments(inherits[i].Arguments?.Jvm);
                    var middleGameArgs = ParseGameArguments(
                        (inherits[i].MinecraftArguments, inherits[i].Arguments?.Game));

                    if (string.IsNullOrEmpty(inherits[i].MinecraftArguments))
                    {
                        jvmSb.Append(' ').Append(jvmArgs);
                        gameArgsSb.Append(' ').Append(middleGameArgs.Item1);
                        result.AvailableGameArguments = result.AvailableGameArguments
                                                        .Union(middleGameArgs.Item2)
                                                        .ToDictionary(x => x.Key, y => y.Value);
                    }
                    else
                    {
                        result.JvmArguments           = jvmArgs;
                        result.GameArguments          = middleGameArgs.Item1;
                        result.AvailableGameArguments = middleGameArgs.Item2;
                    }

                    result.Id        = inherits[i].Id ?? result.Id;
                    result.MainClass = inherits[i].MainClass ?? result.MainClass;
                }

                var finalJvmArgs = (result.JvmArguments ?? string.Empty).Split(' ').ToList();
                finalJvmArgs.AddRange(jvmSb.ToString().Split(' '));
                result.JvmArguments = string.Join(" ", finalJvmArgs.Distinct());

                var finalGameArgs = (result.GameArguments ?? string.Empty).Split(' ').ToList();
                finalGameArgs.AddRange(gameArgsSb.ToString().Split(' '));
                result.GameArguments = string.Join(" ", finalGameArgs.Distinct());

                goto ProcessProfile;
            }

            var libs = GetNatives(rawVersion.Libraries);

            result.Libraries = libs.Item2;
            result.Natives   = libs.Item1;

            result.JvmArguments = ParseJvmArguments(rawVersion.Arguments?.Jvm);

            var gameArgs =
                ParseGameArguments((rawVersion.MinecraftArguments,
                                    rawVersion.Arguments?.Game));

            result.GameArguments          = gameArgs.Item1;
            result.AvailableGameArguments = gameArgs.Item2;

ProcessProfile:
            var oldProfile = LauncherProfileParser.LauncherProfile.Profiles.FirstOrDefault(p =>
                                                                                           p.Value.LastVersionId?.Equals(id, StringComparison.Ordinal) ?? true);

            var gamePath = Path.Combine(RootPath, GamePathHelper.GetGamePath(id));

            if (oldProfile.Equals(default(KeyValuePair <string, GameProfileModel>)))
            {
                LauncherProfileParser.LauncherProfile.Profiles.Add(id.ToGuidHash().ToString("N"),
                                                                   new GameProfileModel
                {
                    GameDir       = gamePath,
                    LastVersionId = id,
                    Name          = id, // randomName,
                    Created       = DateTime.Now
                });
                LauncherProfileParser.SaveProfile();
                return(result);
            }

            result.Name = oldProfile.Value.Name;
            oldProfile.Value.GameDir       = gamePath;
            oldProfile.Value.LastVersionId = id;
            LauncherProfileParser.LauncherProfile.Profiles[oldProfile.Key] = oldProfile.Value;
            LauncherProfileParser.SaveProfile();

            return(result);
        }
Пример #11
0
        public async IAsyncEnumerable <IGameResource> ResolveResourceAsync()
        {
            var id          = VersionInfo.RootVersion ?? VersionInfo.DirName;
            var versionJson = GamePathHelper.GetGameJsonPath(BasePath, id);

            if (!File.Exists(versionJson))
            {
                yield break;
            }

            var fileContent = await File.ReadAllTextAsync(versionJson);

            var rawVersionModel = JsonConvert.DeserializeObject <RawVersionModel>(fileContent);

            if (rawVersionModel?.Downloads?.Client == null)
            {
                yield break;
            }

            var clientDownload = rawVersionModel.Downloads.Client;
            var jarPath        = GamePathHelper.GetVersionJar(BasePath, id);

            var downloadInfo = new VersionJarDownloadInfo
            {
                CheckSum = clientDownload.Sha1,
                FileName = $"{id}.jar",
                FileSize = clientDownload.Size,
                Path     = Path.Combine(BasePath, GamePathHelper.GetGamePath(id)),
                Title    = $"{id}.jar",
                Type     = "GameJar",
                Uri      = clientDownload.Url
            };

            if (!File.Exists(jarPath))
            {
                yield return(downloadInfo);
            }
            else
            {
                if (string.IsNullOrEmpty(clientDownload.Sha1))
                {
                    yield break;
                }

                using var hash = SHA1.Create();
                var computedHash = await CryptoHelper.ComputeFileHashAsync(jarPath, hash);

                if (computedHash.Equals(clientDownload.Sha1, StringComparison.OrdinalIgnoreCase))
                {
                    yield break;
                }

                try
                {
                    File.Delete(jarPath);
                }
                catch (Exception)
                {
                }
                yield return(downloadInfo);
            }
        }
Пример #12
0
        public async Task InstallTaskAsync()
        {
            InvokeStatusChangedEvent("开始安装", 0);

            var manifest = await ReadManifestTask();

            var idPath       = Path.Combine(RootPath, GamePathHelper.GetGamePath(GameId));
            var downloadPath = Path.Combine(Path.GetFullPath(idPath), "mods");

            var di = new DirectoryInfo(downloadPath);

            if (!di.Exists)
            {
                di.Create();
            }

            _needToDownload = manifest.Files.Count;

            var urlBlock = new TransformManyBlock <IEnumerable <CurseForgeFileModel>, ValueTuple <long, long> >(urls =>
            {
                return(urls.Select(file => (file.ProjectId, file.FileId)));
            });

            var actionBlock = new ActionBlock <ValueTuple <long, long> >(async t =>
            {
                var downloadUrlRes = await CurseForgeAPIHelper.GetAddonDownloadUrl(t.Item1, t.Item2);
                var d  = downloadUrlRes.Trim('"');
                var fn = Path.GetFileName(d);

                var downloadFile = new DownloadFile
                {
                    Completed = (_, args) =>
                    {
                        _totalDownloaded++;
                        _isModAllDownloaded = _isModAllDownloaded && (args.Success ?? false);

                        // if (!args.Success)
                        //     throw args.Error;

                        var progress = (double)_totalDownloaded / _needToDownload * 100;

                        InvokeStatusChangedEvent($"下载整合包中的 Mods - {fn} ({_totalDownloaded} / {_needToDownload})",
                                                 progress);
                    },
                    DownloadPath = di.FullName,
                    DownloadUri  = d,
                    FileName     = fn
                                   // Host = "proxy.freecdn.workers.dev"
                };

                await DownloadHelper.DownloadData(downloadFile);
            }, new ExecutionDataflowBlockOptions
            {
                BoundedCapacity        = 32,
                MaxDegreeOfParallelism = 32
            });

            var linkOptions = new DataflowLinkOptions {
                PropagateCompletion = true
            };

            urlBlock.LinkTo(actionBlock, linkOptions);
            urlBlock.Post(manifest.Files);
            urlBlock.Complete();

            await actionBlock.Completion;

            _totalDownloaded = 0;

            if (!_isModAllDownloaded)
            {
                throw new NullReferenceException("未能下载全部的 Mods");
            }

            using var archive = ArchiveFactory.Open(Path.GetFullPath(ModPackPath));

            _totalDownloaded = 0;
            _needToDownload  = archive.Entries.Count();

            foreach (var entry in archive.Entries)
            {
                if (!entry.Key.StartsWith(manifest.Overrides, StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                var subPath = entry.Key[(manifest.Overrides.Length + 1)..].Replace('/', '\\');
Пример #13
0
 /// <summary>
 /// 获取所有能够正常被解析的游戏信息
 /// </summary>
 /// <returns></returns>
 public IEnumerable <VersionInfo> GetAllGames()
 {
     return(new DirectoryInfo(GamePathHelper.GetVersionPath(RootPath)).EnumerateDirectories()
            .Select(dir => ToVersion(dir.Name)).Where(ver => ver != null));
 }
Пример #14
0
        /// <summary>
        /// 游戏信息解析总成(内部方法)
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private protected override VersionInfo ToVersion(string id)
        {
            var rawVersion = ParseRawVersion(id);

            if (rawVersion == null)
            {
                return(null);
            }

            List <RawVersionModel> inherits = null;

            if (!string.IsNullOrEmpty(rawVersion.InheritsFrom))
            {
                inherits = new List <RawVersionModel>();

                var current = rawVersion;
                var first   = true;
                while (current != null && !string.IsNullOrEmpty(current.InheritsFrom))
                {
                    if (first)
                    {
                        inherits.Add(current);
                        first   = false;
                        current = ParseRawVersion(current.InheritsFrom);
                        inherits.Add(current);
                        continue;
                    }

                    inherits.Add(ParseRawVersion(current.InheritsFrom));
                    current = ParseRawVersion(current.InheritsFrom);
                }

                if (!inherits.Any() || inherits.Contains(null))
                {
                    return(null);
                }
            }

            var rs         = new RandomStringHelper().UseLower().UseUpper().UseNumbers().HardMix(1);
            var randomName =
                $"{id}-{rs.Generate(5)}-{rs.Generate(5)}";

            var result = new VersionInfo
            {
                AssetInfo = rawVersion.AssetIndex,
                MainClass = rawVersion.MainClass,
                Libraries = new List <FileInfo>(),
                Natives   = new List <NativeFileInfo>(),
                Id        = rawVersion.Id,
                Name      = randomName
            };

            if (inherits?.Any() ?? false)
            {
                var flag       = true;
                var jvmSb      = new StringBuilder();
                var gameArgsSb = new StringBuilder();

                result.RootVersion = inherits.Last().Id;

                for (var i = inherits.Count - 1; i >= 0; i--)
                {
                    if (result.AssetInfo == null)
                    {
                        if (inherits[i].AssetIndex != null)
                        {
                            result.AssetInfo = inherits[i].AssetIndex;
                        }
                    }

                    if (flag)
                    {
                        var(rootNatives, rootLibraries) = GetNatives(inherits[i].Libraries);

                        result.Libraries = rootLibraries;
                        result.Natives   = rootNatives;

                        jvmSb.Append(ParseJvmArguments(inherits[i].Arguments?.Jvm));

                        var(rootGameArgument, rootAvailableGameArguments) = ParseGameArguments(
                            new Tuple <string, List <object> >(inherits[i].MinecraftArguments, inherits[i].Arguments?.Game));
                        gameArgsSb.Append(rootGameArgument);
                        result.AvailableGameArguments = rootAvailableGameArguments;

                        flag = false;
                        continue;
                    }

                    var(middleNatives, middleLibraries) = GetNatives(inherits[i].Libraries);

                    foreach (var mL in middleLibraries)
                    {
                        var mLMaven = mL.Name.ResolveMavenString();
                        var mLFlag  = false;
                        for (var j = 0; j < result.Libraries.Count; j++)
                        {
                            var lMaven = result.Libraries[j].Name.ResolveMavenString();
                            if (!lMaven.GetMavenFullName().Equals(mLMaven.GetMavenFullName(), StringComparison.Ordinal))
                            {
                                continue;
                            }

                            var v1 = new Version(lMaven.Version);
                            var v2 = new Version(mLMaven.Version);

                            if (v2 > v1)
                            {
                                result.Libraries[j] = mL;
                            }

                            mLFlag = true;
                        }

                        if (mLFlag)
                        {
                            continue;
                        }

                        result.Libraries.Add(mL);
                    }

                    var currentNativesNames = new List <string>();
                    result.Natives.ForEach(n =>
                    {
                        currentNativesNames.Add(n.FileInfo.Name);
                    });
                    var moreMiddleNatives =
                        middleNatives.Where(mL => !currentNativesNames.Contains(mL.FileInfo.Name)).ToList();
                    result.Natives.AddRange(moreMiddleNatives);


                    var jvmArgs = ParseJvmArguments(inherits[i].Arguments?.Jvm);
                    var(middleGameArgument, middleAvailableGameArguments) = ParseGameArguments(
                        new Tuple <string, List <object> >(inherits[i].MinecraftArguments, inherits[i].Arguments?.Game));

                    if (string.IsNullOrEmpty(inherits[i].MinecraftArguments))
                    {
                        jvmSb.Append(" ").Append(jvmArgs);
                        gameArgsSb.Append(" ").Append(middleGameArgument);
                        result.AvailableGameArguments = result.AvailableGameArguments
                                                        .Union(middleAvailableGameArguments)
                                                        .ToDictionary(x => x.Key, y => y.Value);
                    }
                    else
                    {
                        result.JvmArguments           = jvmArgs;
                        result.GameArguments          = middleGameArgument;
                        result.AvailableGameArguments = middleAvailableGameArguments;
                    }

                    result.Id        = inherits[i].Id ?? result.Id;
                    result.MainClass = inherits[i].MainClass ?? result.MainClass;
                }

                var finalJvmArgs = (result.JvmArguments ?? string.Empty).Split(' ').ToList();
                finalJvmArgs.AddRange(jvmSb.ToString().Split(' '));
                result.JvmArguments = string.Join(" ", finalJvmArgs.Distinct());

                var finalGameArgs = (result.GameArguments ?? string.Empty).Split(' ').ToList();
                finalGameArgs.AddRange(gameArgsSb.ToString().Split(' '));
                result.GameArguments = string.Join(" ", finalGameArgs.Distinct());

                goto ProcessProfile;
            }

            var(natives, libraries) = GetNatives(rawVersion.Libraries);
            result.Libraries        = libraries;
            result.Natives          = natives;

            result.JvmArguments = ParseJvmArguments(rawVersion.Arguments?.Jvm);

            var(gameArgument, availableGameArguments) =
                ParseGameArguments(new Tuple <string, List <object> >(rawVersion.MinecraftArguments,
                                                                      rawVersion.Arguments?.Game));
            result.GameArguments          = gameArgument;
            result.AvailableGameArguments = availableGameArguments;

ProcessProfile:
            var oldProfile = LauncherProfileParser.LauncherProfile.Profiles.FirstOrDefault(p =>
                                                                                           p.Value.LastVersionId.Equals(id, StringComparison.Ordinal));

            if (oldProfile.Equals(default(KeyValuePair <string, GameProfileModel>)))
            {
                LauncherProfileParser.LauncherProfile.Profiles.Add(randomName.ToGuid().ToString("N"), new GameProfileModel
                {
                    GameDir       = GamePathHelper.GetGamePath(RootPath, id),
                    LastVersionId = id,
                    Name          = randomName,
                    Created       = DateTime.Now
                });
                LauncherProfileParser.SaveProfile();
                return(result);
            }

            result.Name = oldProfile.Value.Name;
            oldProfile.Value.GameDir       = GamePathHelper.GetGamePath(RootPath, id);
            oldProfile.Value.LastVersionId = id;
            LauncherProfileParser.LauncherProfile.Profiles[oldProfile.Key] = oldProfile.Value;
            LauncherProfileParser.SaveProfile();

            return(result);
        }
Пример #15
0
        public async Task <string> InstallTaskAsync()
        {
            InvokeStatusChangedEvent("开始安装 Optifine", 0);
            var mcVersion      = OptifineDownloadVersion.McVersion;
            var edition        = OptifineDownloadVersion.Type;
            var release        = OptifineDownloadVersion.Patch;
            var editionRelease = $"{edition}_{release}";
            var id             = string.IsNullOrEmpty(CustomId)
                ? $"{mcVersion}-Optifine_{editionRelease}"
                : CustomId;

            var versionPath = Path.Combine(RootPath, GamePathHelper.GetGamePath(id));
            var di          = new DirectoryInfo(versionPath);

            if (!di.Exists)
            {
                di.Create();
            }

            InvokeStatusChangedEvent("读取 Optifine 数据", 20);
            using var archive = ArchiveFactory.Open(OptifineJarPath);
            var entries = archive.Entries;

            var launchWrapperVersion = "1.7";

            foreach (var entry in entries)
            {
                if (!entry.Key.Equals("launchwrapper-of.txt", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }
                await using var stream = entry.OpenEntryStream();
                using var sr           = new StreamReader(stream, Encoding.UTF8);
                launchWrapperVersion   = await sr.ReadToEndAsync();
            }

            var launchWrapperEntry =
                entries.First(x => x.Key.Equals($"launchwrapper-of-{launchWrapperVersion}.jar"));

            InvokeStatusChangedEvent("生成版本总成", 40);

            var versionModel = new RawVersionModel
            {
                Id           = id,
                InheritsFrom = mcVersion,
                Arguments    = new Arguments
                {
                    Game = new List <object>
                    {
                        "--tweakClass",
                        "optifine.OptiFineTweaker"
                    },
                    Jvm = new List <object>()
                },
                ReleaseTime = DateTime.Now,
                Time        = DateTime.Now,
                BuildType   = "release",
                Libraries   = new List <Library>
                {
                    new()
                    {
                        Name = $"optifine:launchwrapper-of:{launchWrapperVersion}"
                    },
                    new()
                    {
                        Name = $"optifine:Optifine:{OptifineDownloadVersion.McVersion}_{editionRelease}"
                    }
                },