142 lines
5.3 KiB
C#
142 lines
5.3 KiB
C#
using System.Linq;
|
||
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 propsSet = new HashSet<GameVersionProps>();
|
||
|
||
// local descriptors
|
||
foreach (IOPath f in Directory.GetFiles(GetVersionDescriptorsDir()))
|
||
{
|
||
string name = GetVersionDescriptorName(f);
|
||
propsSet.Add(new GameVersionProps(name, null, f));
|
||
}
|
||
|
||
// remote non-duplicating versions
|
||
foreach (var removeVersion in await Сеть.GetDownloadableVersions())
|
||
{
|
||
propsSet.Add(removeVersion);
|
||
}
|
||
|
||
// reverse sort
|
||
var propsList = propsSet.ToList();
|
||
propsList.Sort((a, b) => b.CompareTo(a));
|
||
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 Сеть.DownloadFile(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 UpdateFiles(bool checkHashes, Action<NetworkTask> networkTaskCreatedCallback)
|
||
{
|
||
Приложение.Логгер.LogInfo(nameof(GameVersion), $"started updating version {Name}");
|
||
|
||
List<INetworkTaskFactory> taskFactories =
|
||
[
|
||
new AssetsDownloadTaskFactory(descriptor),
|
||
new LibrariesDownloadTaskFactory(descriptor, libraries),
|
||
new VersionFileDownloadTaskFactory(descriptor),
|
||
];
|
||
if(Приложение.Настройки.скачивать_жабу)
|
||
{
|
||
taskFactories.Add(new JavaDownloadTaskFactory(descriptor));
|
||
}
|
||
//TODO: modpack
|
||
/*if (modpack != null)
|
||
{
|
||
taskFactories.Add(new ModpackDownloadTaskFactory(modpack));
|
||
}*/
|
||
|
||
var networkTasks = new List<NetworkTask>();
|
||
for (int i = 0; i < taskFactories.Count; i++)
|
||
{
|
||
var nt = await taskFactories[i].CreateAsync(checkHashes);
|
||
if (nt != null)
|
||
{
|
||
networkTasks.Add(nt);
|
||
networkTaskCreatedCallback.Invoke(nt);
|
||
}
|
||
}
|
||
|
||
foreach (var nt in networkTasks)
|
||
{
|
||
await nt.StartAsync();
|
||
}
|
||
|
||
_props.IsDownloaded = true;
|
||
Приложение.Логгер.LogInfo(nameof(GameVersion), $"finished updating version {Name}");
|
||
}
|
||
|
||
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;
|
||
} |