using CliWrap; using DTLib.Extensions; using Млаумчерб.Клиент.видимое; using Млаумчерб.Клиент.классы; using Млаумчерб.Клиент.сеть; using Млаумчерб.Клиент.сеть.NetworkTaskFactories; using static Млаумчерб.Клиент.классы.Пути; namespace Млаумчерб.Клиент; public class GameVersion { private readonly GameVersionProps _props; public string Name => _props.Name; public IOPath WorkingDirectory { get; } private IOPath JavaExecutableFilePath; private VersionDescriptor descriptor; private JavaArguments javaArgs; private GameArguments gameArgs; private Libraries libraries; private CancellationTokenSource? gameCts; private CommandTask? commandTask; public static async Task> GetAllVersionsAsync() { var propsList = new List(); foreach (IOPath f in Directory.GetFiles(GetVersionDescriptorDir())) { string name = GetVersionDescriptorName(f); propsList.Add(new GameVersionProps(name, null, f)); } var remoteVersions = await Сеть.GetDownloadableVersions(); propsList.AddRange(remoteVersions); return propsList; } public static async Task CreateFromPropsAsync(GameVersionProps props) { if (!File.Exists(props.LocalDescriptorPath)) { if (props.RemoteDescriptorUrl is null) throw new NullReferenceException("can't download game version descriptor '" + props.Name + "', because RemoteDescriptorUrl is null"); await Сеть.DownloadFileHTTP(props.RemoteDescriptorUrl, props.LocalDescriptorPath); } return new GameVersion(props); } private GameVersion(GameVersionProps props) { _props = props; string descriptorText = File.ReadAllText(props.LocalDescriptorPath); descriptor = JsonConvert.DeserializeObject(descriptorText) ?? throw new Exception($"can't parse descriptor file '{props.LocalDescriptorPath}'"); javaArgs = new JavaArguments(descriptor); gameArgs = new GameArguments(descriptor); libraries = new Libraries(descriptor); WorkingDirectory = GetVersionDir(descriptor.id); JavaExecutableFilePath = GetJavaExecutablePath(descriptor.javaVersion.component); } public async Task> CreateUpdateTasksAsync(bool checkHashes) { List taskFactories = [ new AssetsDownloadTaskFactory(descriptor), new LibrariesDownloadTaskFactory(descriptor, libraries), new VersionFileDownloadTaskFactory(descriptor), ]; /*if(Приложение.Настройки.скачать_жабу) { taskFactories.Add(new JavaDownloadTaskFactory(descriptor)); }*/ /*if (modpack != null) { taskFactories.Add(new ModpackDownloadTaskFactory(modpack)); }*/ List tasks = new(); for (int i = 0; i < taskFactories.Count; i++) { var nt = await taskFactories[i].CreateAsync(checkHashes); if (nt != null) tasks.Add(nt); } if (tasks.Count == 0) { _props.IsDownloaded = true; } else { tasks[^1].OnStop += status => { if (status == NetworkTask.Status.Completed) _props.IsDownloaded = true; }; } return tasks; } public async Task Launch() { var javaArgsList = javaArgs.FillPlaceholders([]); var gameArgsList = gameArgs.FillPlaceholders([]); var command = Cli.Wrap(JavaExecutableFilePath.ToString()) .WithWorkingDirectory(WorkingDirectory.ToString()) .WithArguments(javaArgsList) .WithArguments(gameArgsList); Приложение.Логгер.LogInfo(nameof(GameVersion), $"launching the game" + "\njava: " + command.TargetFilePath + "\nworking_dir: " + command.WorkingDirPath + "\njava_arguments: \n\t" + javaArgsList.MergeToString("\n\t") + "\ngame_arguments: \n\t" + gameArgsList.MergeToString("\n\t")); gameCts = new(); commandTask = command.ExecuteAsync(gameCts.Token); var result = await commandTask; Приложение.Логгер.LogInfo(nameof(GameVersion), $"game exited with code {result.ExitCode}"); } public void Close() { gameCts?.Cancel(); } public override string ToString() => Name; }