132 lines
4.9 KiB
C#
132 lines
4.9 KiB
C#
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 GameVersionDescriptor descriptor;
|
||
private JavaArguments javaArgs;
|
||
private GameArguments gameArgs;
|
||
private Libraries libraries;
|
||
private CancellationTokenSource? gameCts;
|
||
private CommandTask<CommandResult>? commandTask;
|
||
|
||
public static async Task<List<GameVersionProps>> GetAllVersionsAsync()
|
||
{
|
||
var propsList = new List<GameVersionProps>();
|
||
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<GameVersion> 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<GameVersionDescriptor>(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<List<NetworkTask>> CreateUpdateTasksAsync(bool checkHashes)
|
||
{
|
||
List<INetworkTaskFactory> 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<NetworkTask> 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;
|
||
} |