Skip to content

Commit

Permalink
整合包更新实现#20
Browse files Browse the repository at this point in the history
  • Loading branch information
d3ara1n committed Jun 15, 2023
1 parent 351d02c commit 75e21ac
Show file tree
Hide file tree
Showing 11 changed files with 242 additions and 57 deletions.
61 changes: 24 additions & 37 deletions .idea/.idea.Polymerium/.idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ a little bit of personal flavor。

### Why another launcher?

这不是 *launcher*这也不是压缩毛巾,这是 Polymerium —— *游戏实例管理器*
这不是 *launcher*也不是压缩毛巾,这是 Polymerium —— *游戏实例管理器*
初衷是在用 PrismLauncher 的时候遇到一些问题并想出一些改进的的方法,不过在写代码、与 forge installer
斗智斗勇的过程中已经忘记哪些改进了(囧。现在要回答这个问题的话,那么答案是:没有为什么,小孩子不懂事写着玩的。

Expand Down
5 changes: 5 additions & 0 deletions changelogs/v0.4.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog v0.4

## v0.4.5

- **优化**增加主窗体初始尺寸
- **新增**更新整合包到指定版本(#20)

## v0.4.4

- **修复**下载中心添加整合包将不再崩溃
Expand Down
4 changes: 2 additions & 2 deletions src/Polymerium.App/Services/ImportService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,7 @@ public async Task<Result<ImportResult, GameImportError>> ExtractMetadataFromFile

// update instance info and remain FolderName untouched
var old = instance.ReferenceSource;
instance.Name = product.Content.Name;
instance.Version = product.Content.Version;
instance.Author = product.Content.Author;
instance.ReferenceSource = product.Content.ReferenceSource;
instance.ThumbnailFile = product.Content.ThumbnailFile;
instance.Metadata.Components.Clear();
Expand All @@ -164,6 +162,8 @@ public async Task<Result<ImportResult, GameImportError>> ExtractMetadataFromFile
);
if (isGenerated)
{
instance.Name = product.Content.Name;
instance.Author = product.Content.Author;
instance.FolderName = PathHelper.RemoveInvalidCharacters(instance.Name);
_instanceManager.AddInstance(instance);
}
Expand Down
141 changes: 140 additions & 1 deletion src/Polymerium.App/ViewModels/InstanceUpdateViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,144 @@
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.UI.Xaml.Controls;
using Polymerium.Abstractions;
using Polymerium.Abstractions.ResourceResolving;
using Polymerium.App.Services;
using Polymerium.App.Views;
using Polymerium.Core;
using Polymerium.Core.Engines;
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using RFile = Polymerium.Abstractions.Resources.File;

namespace Polymerium.App.ViewModels;

public class InstanceUpdateViewModel : ObservableObject { }
public class InstanceUpdateViewModel : ObservableObject
{
private readonly ImportService _importer;
private readonly ResolveEngine _resolver;
private readonly IFileBaseService _fileBase;
private readonly LocalizationService _localizationService;
private readonly INotificationService _notification;
public readonly NavigationService NavigationService;

public InstanceUpdateViewModel(
ImportService importer,
ResolveEngine resolver,
IFileBaseService fileBase,
LocalizationService localizationService,
INotificationService notification,
NavigationService navigationService
)
{
_importer = importer;
_resolver = resolver;
_fileBase = fileBase;
_localizationService = localizationService;
_notification = notification;
NavigationService = navigationService;
}

public async Task ApplyUpdateAsync(
GameInstance instance,
Uri reference,
bool resetLocal,
Action callback
)
{
var context = new ResolverContext(instance);
var fileResult = await _resolver.ResolveToFileAsync(reference, context);
if (fileResult.IsSuccessful && fileResult.Value.Resource is RFile file)
{
try
{
var client = new HttpClient();
using var stream = await client.GetStreamAsync(file.Source);
var tmpFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
if (!Directory.Exists(Path.GetDirectoryName(tmpFile)))
Directory.CreateDirectory(Path.GetDirectoryName(tmpFile)!);
var fs = new FileStream(tmpFile, FileMode.Create, FileAccess.Write);
await stream.CopyToAsync(fs);
await fs.FlushAsync();
fs.Close();
var importResult = await _importer.ExtractMetadataFromFileAsync(
tmpFile,
reference,
false
);
if (importResult.IsSuccessful)
{
var oldAttachments = instance.Metadata.Attachments
.Where(x => x.From == instance.ReferenceSource)
.ToList();
if (resetLocal)
{
var resolveResult = await _resolver.ResolveAsync(
oldAttachments.Select(x => x.Source),
context
);
if (resolveResult.IsSuccessful)
{
foreach (var localResult in resolveResult.Value)
{
if (localResult.Resource is RFile localFile)
{
var localPath = _fileBase.Locate(
new Uri(
new Uri(
ConstPath.INSTANCE_BASE.Replace("{0}", instance.Id)
),
localFile.FileName
)
);
if (File.Exists(localPath))
{
File.Delete(localPath);
}
}
}
}
else
{
EndedError($"应用本地文件错误: {importResult.Error}");
}
}
var postError = await _importer.SolidifyAsync(importResult.Value, instance);
if (postError.HasValue)
{
EndedError($"导入文件错误: {postError.Value}");
}
else
{
_notification.Enqueue(
"更新完成",
$"版本更新到 {file.Name}",
InfoBarSeverity.Success
);
}
}
else
{
EndedError($"提取信息错误: {importResult.Error}");
}
}
catch (Exception e)
{
EndedError($"文件系统错误: {e.Message}");
}
}
else
{
EndedError($"解析信息错误: {fileResult.Error}");
}
callback();
}

private void EndedError(string message)
{
_notification.Enqueue("更新失败", message, InfoBarSeverity.Error);
}
}
4 changes: 2 additions & 2 deletions src/Polymerium.App/ViewModels/SearchDetailViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -215,11 +215,11 @@ public async Task InstallModpackAsync(
report(0, false);
try
{
using var client = new HttpClient();
var response = await client.GetAsync(file.Source, token);
var tmpFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
if (!Directory.Exists(Path.GetDirectoryName(tmpFile)))
Directory.CreateDirectory(Path.GetDirectoryName(tmpFile)!);
using var client = new HttpClient();
var response = await client.GetAsync(file.Source, token);
ulong? totalSize = null;
if (
response.Content.Headers.ContentLength.HasValue
Expand Down
44 changes: 34 additions & 10 deletions src/Polymerium.App/Views/InstanceUpdateDialog.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@

using Microsoft.Extensions.DependencyInjection;
using Microsoft.UI.Xaml;
using Polymerium.Abstractions;
using Polymerium.App.Controls;
using Polymerium.App.Models;
using Polymerium.App.ViewModels;
using System.Threading.Tasks;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
Expand All @@ -27,19 +29,19 @@ InstanceModpackReferenceVersionModel version
InitializeComponent();
}



public bool IsProcessing
{
get { return (bool)GetValue(IsProcessingProperty); }
set { SetValue(IsProcessingProperty, value); }
}

// Using a DependencyProperty as the backing store for IsProcessing. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsProcessingProperty =
DependencyProperty.Register(nameof(IsProcessing), typeof(bool), typeof(InstanceUpdateDialog), new PropertyMetadata(false));


public static readonly DependencyProperty IsProcessingProperty = DependencyProperty.Register(
nameof(IsProcessing),
typeof(bool),
typeof(InstanceUpdateDialog),
new PropertyMetadata(false)
);

public bool ApplyLocalFileReset
{
Expand All @@ -49,9 +51,12 @@ public bool ApplyLocalFileReset

// Using a DependencyProperty as the backing store for ApplyLocalFileReset. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ApplyLocalFileResetProperty =
DependencyProperty.Register(nameof(ApplyLocalFileReset), typeof(bool), typeof(InstanceUpdateDialog), new PropertyMetadata(true));


DependencyProperty.Register(
nameof(ApplyLocalFileReset),
typeof(bool),
typeof(InstanceUpdateDialog),
new PropertyMetadata(true)
);

public InstanceUpdateViewModel ViewModel { get; }
public GameInstanceModel Instance { get; }
Expand All @@ -63,8 +68,27 @@ private void CancelButton_Click(object sender, RoutedEventArgs e)
Dismiss();
}

private void ConfirmButton_Click(object sender, RoutedEventArgs e)
private async void ConfirmButton_Click(object sender, RoutedEventArgs e)
{
IsProcessing = true;
var reset = ApplyLocalFileReset;
await Task.Run(
() =>
ViewModel.ApplyUpdateAsync(
Instance.Inner,
Version.Resource,
reset,
UpdateFinishHandler
)
);
}

private void UpdateFinishHandler()
{
DispatcherQueue.TryEnqueue(() =>
{
Dismiss();
ViewModel.NavigationService.Navigate<InstanceView>(Instance.Id);
});
}
}
7 changes: 6 additions & 1 deletion src/Polymerium.App/Views/MainView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ private void Navigate(Type view, object? parameter, NavigationTransitionInfo? tr
.FirstOrDefault(x => x.GameInstance?.Id == instanceId) is
{ } instanceView
)
MainNavigationBar.SelectedItem = instanceView;
{
if (MainNavigationBar.SelectedItem == instanceView)
OnSelectionChanged(MainNavigationBar, null!);
else
MainNavigationBar.SelectedItem = instanceView;
}
else
throw new ArgumentException($"parameter {parameter} not found as game instance id");
}
Expand Down
Loading

0 comments on commit 75e21ac

Please sign in to comment.