NetworkTransferTask

This commit is contained in:
Timerix 2024-09-20 03:25:21 +05:00
parent 9560acad07
commit 581c4b5498
5 changed files with 109 additions and 21 deletions

View File

@ -1,13 +1,72 @@
namespace Млаумчерб.Клиент;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
public record struct NetworkTransferResult
namespace Млаумчерб.Клиент;
public record struct NetworkTransferResult(long BytesTotal, long BytesTransferred, long BytesPerSecond)
{
public long BytesTotal;
public long BytesTransferred;
public long BytesPerSecond;
public override string ToString()
{
return $"transferred {BytesTransferred}/{BytesTotal} bytes ({BytesPerSecond}) bps";
}
}
public class NetworkHelper
public class NetworkTransferTask
{
public Task Task { get; private set; }
public Progress<NetworkTransferResult> Progress { get; private set; }
private Stream _src;
private Stream _dst;
private CancellationTokenSource _cts;
private DTLib.Timer _timer;
public NetworkTransferTask(Stream src, Stream dst)
{
_src = src;
_dst = dst;
_cts = new CancellationTokenSource();
Progress = new Progress<NetworkTransferResult>();
_timer = new(true, 1000, ReportProgress);
Task = Task.CompletedTask;
}
public void Start()
{
_timer.Start();
Task = _src.CopyToAsync(_dst);
_timer.Stop();
}
public void Stop()
{
_cts.Cancel();
_timer.Stop();
}
private long previousBytesTransferred;
private void ReportProgress()
{
long bytesTotal = _src.Length, bytesTransferred = _src.Position;
long bytesPerSecond = bytesTransferred - previousBytesTransferred;
previousBytesTransferred = bytesTransferred;
((IProgress<NetworkTransferResult>)Progress).Report(new NetworkTransferResult(bytesTotal, bytesTransferred, bytesPerSecond));
}
public TaskAwaiter GetAwaiter() => Task.GetAwaiter();
}
public static class NetworkHelper
{
private static HttpClient http = new();
public static NetworkTransferTask DownloadHTTPFileAsync(string url, Stream destinationStream)
{
var sourceStream = http.GetStreamAsync(url).GetAwaiter().GetResult();
NetworkTransferTask task = new(sourceStream, destinationStream);
task.Start();
return task;
}
}

View File

@ -2,6 +2,7 @@
using System.Threading.Tasks;
using CliWrap;
using DTLib.Extensions;
using Newtonsoft.Json;
using Млаумчерб.Клиент.классы;
namespace Млаумчерб.Клиент;
@ -11,7 +12,7 @@ public interface IGame
string Name { get; }
IOPath InstallationDirectory { get; }
Progress<NetworkTransferResult> BeginUpdate();
void EndUpdate();
void CancelUpdate();
Task Launch();
void Close();
}
@ -21,17 +22,25 @@ public class MinecraftVersion : IGame
public string Name { get; }
public IOPath InstallationDirectory { get; }
private IOPath JavawFilePath;
private IOPath JavaExecutableFilePath;
private MinecraftVersionDescriptor descriptor;
private JavaArguments javaArgs;
private GameArguments gameArgs;
private CancellationTokenSource? cts;
private CommandTask<CommandResult> commandTask;
private CommandTask<CommandResult>? commandTask;
public MinecraftVersion(string name)
public MinecraftVersion(IOPath descriptorFilePath)
{
Name = name;
InstallationDirectory = Path.Concat("minecraft", Path.ReplaceRestrictedChars(name));
Name = descriptorFilePath.LastName().ToString().Replace(".json", "");
InstallationDirectory = Path.Concat(Приложение.Настройки.путь_к_кубачу, Name);
string descriptorText = File.ReadAllText(descriptorFilePath);
descriptor = JsonConvert.DeserializeObject<MinecraftVersionDescriptor>(descriptorText)
?? throw new Exception($"can't parse descriptor file '{descriptorFilePath}'");
javaArgs = new JavaArguments(descriptor);
gameArgs = new GameArguments(descriptor);
JavaExecutableFilePath = Path.Concat(Приложение.Настройки.путь_к_жабе, "bin",
OperatingSystem.IsWindows() ? "javaw.exe" : "javaw");
}
public Progress<NetworkTransferResult> BeginUpdate()
@ -39,7 +48,7 @@ public class MinecraftVersion : IGame
throw new NotImplementedException();
}
public void EndUpdate()
public void CancelUpdate()
{
throw new NotImplementedException();
}
@ -48,7 +57,7 @@ public class MinecraftVersion : IGame
{
var javaArgsList = javaArgs.FillPlaceholders([]);
var gameArgsList = gameArgs.FillPlaceholders([]);
var command = Cli.Wrap(JavawFilePath.ToString())
var command = Cli.Wrap(JavaExecutableFilePath.ToString())
.WithWorkingDirectory(InstallationDirectory.ToString())
.WithArguments(javaArgsList)
.WithArguments(gameArgsList);
@ -68,4 +77,6 @@ public class MinecraftVersion : IGame
{
cts?.Cancel();
}
public override string ToString() => Name;
}

View File

@ -18,11 +18,8 @@
<PackageReference Include="Avalonia.Themes.Simple" Version="11.*" />
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.*" />
<PackageReference Include="Avalonia.Labs.Gif" Version="11.2.999-cibuild-00051673"/>
<PackageReference Include="CliWrap" Version="3.6.6" />
<PackageReference Include="DTLib" Version="1.3.*" />
<PackageReference Include="DTLib.Ben.Demystifier" Version="1.0.*" />
<PackageReference Include="DTLib.Logging" Version="1.3.*" />
<PackageReference Include="DTLib.Network" Version="1.4.*" />
<PackageReference Include="CliWrap" Version="3.6.*" />
<PackageReference Include="DTLib" Version="1.4.0" />
<PackageReference Include="MessageBox.Avalonia" Version="3.1.*" />
<PackageReference Include="Newtonsoft.Json" Version="13.*" />
</ItemGroup>

View File

@ -7,6 +7,9 @@ public record Настройки
public string имя_пользователя { get; set; } = "";
public int выделенная_память_мб { get; set; } = 4096;
public bool открыватьаесь_экран { get; set; }
public string путь_к_кубачу { get; set; } = ".";
public string путь_к_жабе { get; set; } = "java";
public bool скачатьабу { get; set; } = true;
public static Настройки ЗагрузитьИзФайла(string имяайла = "млаумчерб.настройки")
{

View File

@ -57,6 +57,15 @@ public partial class Окне : Window
Username = Приложение.Настройки.имя_пользователя;
MemoryLimit = Приложение.Настройки.выделенная_память_мб;
Fullscreen = Приложение.Настройки.открыватьаесь_экран;
IOPath localDescriptorsDir = Path.Concat(Приложение.Настройки.путь_к_кубачу, "version_descriptors");
Directory.Create(localDescriptorsDir);
var descriptorFiles = Directory.GetFiles(localDescriptorsDir);
foreach(var descriptorFile in descriptorFiles)
{
MinecraftVersion mc = new(descriptorFile);
VersionComboBox.Items.Add(mc);
}
}
catch (Exception ex)
{
@ -73,6 +82,15 @@ public partial class Окне : Window
Приложение.Настройки.открыватьаесь_экран = Fullscreen;
Приложение.Настройки.СохранитьВФайл();
IGame? game = (IGame?)VersionComboBox.SelectionBoxItem;
if (game != null)
{
if (UpdateGameFiles)
{
var progress = game.BeginUpdate();
progress.ProgressChanged += (o, result) => Приложение.Логгер.LogDebug("Downloads", result);
}
}
}
catch (Exception ex)
{