diff --git a/Igniter/Igniter.csproj b/Igniter/Igniter.csproj index fbf122d..962a53c 100644 --- a/Igniter/Igniter.csproj +++ b/Igniter/Igniter.csproj @@ -108,6 +108,7 @@ + @@ -158,9 +159,6 @@ 5.7.0 all - - 1.16.0 - 8.0.4 diff --git a/Igniter/Utilities/IDUtility.cs b/Igniter/Utilities/IDUtility.cs new file mode 100644 index 0000000..59f3b34 --- /dev/null +++ b/Igniter/Utilities/IDUtility.cs @@ -0,0 +1,17 @@ +using System; +using System.IO; +using System.Security.Cryptography; + +namespace Igniter.Utilities +{ + public static partial class Utility + { + public static string GetID128(Stream s) + { + s.Position = 0; + return ModifyID(MD5.Create().ComputeHash(s)); + } + + static string ModifyID(byte[] hash) => BitConverter.ToString(hash).Replace("-", string.Empty).ToLowerInvariant(); + } +} diff --git a/Igniter/Utilities/IOUtility.cs b/Igniter/Utilities/IOUtility.cs index be14fc4..128a545 100644 --- a/Igniter/Utilities/IOUtility.cs +++ b/Igniter/Utilities/IOUtility.cs @@ -1,10 +1,41 @@ -using System.IO; +using System; +using System.Diagnostics; +using System.IO; namespace Igniter.Utilities { public static partial class Utility { - public static bool WipeFile(string filePath) + public static void CopyFile(string src, string target) + { + try + { + if (File.Exists(src)) + { + if (File.Exists(target)) + { + using (var fs0 = File.OpenRead(src)) + using (var fs1 = File.OpenRead(target)) + { + if (Utility.GetID128(fs0) == Utility.GetID128(fs1)) + { + return; + } + } + + WipeFile(target); + WipeEntry(target); + } + Directory.CreateDirectory(Path.GetDirectoryName(target)); + File.Copy(src, target, true); + } + } + catch + { + } + } + + public static void WipeFile(string filePath) { try { @@ -12,11 +43,59 @@ { File.Delete(filePath); } - return true; } catch { - return false; + } + } + + public static void WipeEntry(string entryPath) + { + try + { + if (Directory.Exists(entryPath)) + { + Directory.Delete(entryPath, true); + } + } + catch + { + } + } + + public static void CopyEntry(string src, string target) + { + foreach (var filePath in GetFiles(src)) + { + CopyFile(filePath, Path.Combine(target, Path.GetFileName(filePath))); + } + foreach (var entryPath in GetEntry(src)) + { + CopyEntry(entryPath, Path.Combine(target, Path.GetFileName(entryPath))); + } + } + + public static string[] GetFiles(string entryPath, string o = "*") + { + try + { + return Directory.Exists(entryPath) ? Directory.GetFiles(entryPath, o) : Array.Empty(); + } + catch + { + return Array.Empty(); + } + } + + public static string[] GetEntry(string entryPath, string o = "*") + { + try + { + return Directory.Exists(entryPath) ? Directory.GetDirectories(entryPath, o) : Array.Empty(); + } + catch + { + return Array.Empty(); } } } diff --git a/Igniter/ViewModels/MainViewModel.cs b/Igniter/ViewModels/MainViewModel.cs index fa6ed14..70740d5 100644 --- a/Igniter/ViewModels/MainViewModel.cs +++ b/Igniter/ViewModels/MainViewModel.cs @@ -1,8 +1,9 @@ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Messaging; using Igniter.MSG; -using Ionic.Zip; +using Igniter.Utilities; using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Threading.Tasks; @@ -51,22 +52,45 @@ { try { - using (var zipFile = ZipFile.Read(Environment.GetCommandLineArgs()[1])) + await Task.Run(() => { - zipFile.ExtractProgress += (sender, e) => + var rootEntryPath = Environment.GetCommandLineArgs()[1]; + + var filePaths = new List(); + SetFilePaths(rootEntryPath); + + void SetFilePaths(string targetEntryPath) { - if (e.EntriesTotal > 0) + foreach (var entryPath in Utility.GetEntry(targetEntryPath)) { - Value = 100.0 * e.EntriesExtracted / e.EntriesTotal; + SetFilePaths(entryPath); } - var fileName = e.CurrentEntry?.FileName; - if (!string.IsNullOrEmpty(fileName)) + foreach (var filePath in Utility.GetFiles(targetEntryPath)) { - Text = fileName; + filePaths.Add(filePath); } - }; - await Task.Run(() => zipFile.ExtractAll(Path.GetDirectoryName(IgniterComponent.QwilightFilePath), ExtractExistingFileAction.OverwriteSilently)); - } + } + + var filePathsCount = filePaths.Count; + for (var i = 0; i < filePathsCount; ++i) + { + var filePath = filePaths[i]; + var logicalFilePath = filePath.Replace(rootEntryPath + Path.DirectorySeparatorChar, string.Empty); + var targetFilePath = Path.Combine(Path.GetDirectoryName(IgniterComponent.QwilightFilePath), logicalFilePath); + + Value = 100.0 * i / filePathsCount; + Text = logicalFilePath; + + if (new FileInfo(filePath).Length > 0) + { + Utility.CopyFile(filePath, targetFilePath); + } + else + { + Utility.WipeFile(targetFilePath); + } + } + }); IsVisible = false; StrongReferenceMessenger.Default.Send(new ViewAllowWindow diff --git a/Qwilight.cmd b/Qwilight.cmd index 9222af2..dc92fb7 100644 --- a/Qwilight.cmd +++ b/Qwilight.cmd @@ -40,23 +40,15 @@ dotnet publish Qwilight\Qwilight.csproj -c Release -p:Platform=x64 "%BANDIZIP%" c -storeroot:no Qwilight.AMD64.zip %WINAMD64PUBLISH% -powershell $(CertUtil -hashfile %WINAMD64PUBLISH%\Qwilight.dll SHA512)[1] > Qwilight.dll.sha512sum -SET /P HASH_AMD64= < Qwilight.dll.sha512sum -DEL Qwilight.dll.sha512sum - RMDIR /S /Q %WINARM64PUBLISH% dotnet publish Qwilight\Qwilight.csproj -c Release -p:Platform=ARM64 "%BANDIZIP%" c -storeroot:no Qwilight.ARM64.zip %WINARM64PUBLISH% -powershell $(CertUtil -hashfile %WINARM64PUBLISH%\Qwilight.dll SHA512)[1] > Qwilight.dll.sha512sum -SET /P HASH_ARM64= < Qwilight.dll.sha512sum -DEL Qwilight.dll.sha512sum - CHOICE /M PATCH IF %ERRORLEVEL% == 1 ( curl -X PATCH taehui:4003/date/AMD64 --data-binary "@Qwilight.AMD64.zip" curl -X PATCH taehui:4003/date/ARM64 --data-binary "@Qwilight.ARM64.zip" - curl -X PATCH taehui:4003/date -d "%DATE% %HASH_AMD64% %HASH_ARM64%" + curl -X PATCH taehui:4003/date -d "%DATE%" ) DEL Qwilight.AMD64.zip diff --git a/Qwilight/JSON.cs b/Qwilight/JSON.cs index 1cc4240..0e44fce 100644 --- a/Qwilight/JSON.cs +++ b/Qwilight/JSON.cs @@ -155,19 +155,12 @@ { public string date; #if X64 - [JsonPropertyName("hashAMD64")] + [JsonPropertyName("hashesAMD64")] #endif #if ARM64 - [JsonPropertyName("hashARM64")] + [JsonPropertyName("hashesARM64")] #endif - public string hash; -#if X64 - [JsonPropertyName("titleAMD64")] -#endif -#if ARM64 - [JsonPropertyName("titleARM64")] -#endif - public string title; + public Dictionary hashes; } public struct TwilightWwwComment diff --git a/Qwilight/Qwilight.csproj b/Qwilight/Qwilight.csproj index d4af2b2..331db7d 100644 --- a/Qwilight/Qwilight.csproj +++ b/Qwilight/Qwilight.csproj @@ -10,7 +10,7 @@ Qwilight.ico Taehui 불로그 - 1.16.39 + 1.16.40 true enable false diff --git a/Qwilight/System/AvatarDrawingSystem.cs b/Qwilight/System/AvatarDrawingSystem.cs index 7c9b128..fbaba32 100644 --- a/Qwilight/System/AvatarDrawingSystem.cs +++ b/Qwilight/System/AvatarDrawingSystem.cs @@ -49,7 +49,7 @@ var avatarCSX = _avatarCSXs.GetOrAdd(avatarID, GetCSX); try { - await avatarCSX.WaitAsync(); + await avatarCSX.WaitAsync().ConfigureAwait(false); if (!_avatarDrawings.TryGetValue(avatarID, out var avatarDrawing)) { if (string.IsNullOrEmpty(avatarID)) diff --git a/Qwilight/System/AvatarEdgeSystem.cs b/Qwilight/System/AvatarEdgeSystem.cs index a143b05..52a4fa2 100644 --- a/Qwilight/System/AvatarEdgeSystem.cs +++ b/Qwilight/System/AvatarEdgeSystem.cs @@ -49,7 +49,7 @@ var avatarCSX = _avatarCSXs.GetOrAdd(avatarID, GetCSX); try { - await avatarCSX.WaitAsync(); + await avatarCSX.WaitAsync().ConfigureAwait(false); if (!_avatarEdges.TryGetValue(avatarID, out var avatarEdge)) { if (string.IsNullOrEmpty(avatarID)) diff --git a/Qwilight/System/AvatarTitleSystem.cs b/Qwilight/System/AvatarTitleSystem.cs index fddb693..76a959a 100644 --- a/Qwilight/System/AvatarTitleSystem.cs +++ b/Qwilight/System/AvatarTitleSystem.cs @@ -33,7 +33,7 @@ var avatarCSX = _avatarCSXs.GetOrAdd(avatarID, GetCSX); try { - await avatarCSX.WaitAsync(); + await avatarCSX.WaitAsync().ConfigureAwait(false); if (!_avatarTitles.TryGetValue(avatarID, out var avatarTitle)) { if (string.IsNullOrEmpty(avatarID)) diff --git a/Qwilight/System/DB.cs b/Qwilight/System/DB.cs index 240bdb7..53ef115 100644 --- a/Qwilight/System/DB.cs +++ b/Qwilight/System/DB.cs @@ -31,6 +31,7 @@ public static readonly DB Instance = QwilightComponent.GetBuiltInData(nameof(DB)); + readonly ReaderWriterLockSlim _dbCSX = new(); readonly object _setSaveCSX = new(); SqliteConnection _fastDB; SqliteConnection _fileDB; @@ -79,7 +80,7 @@ Compatible.Compatible.DB(_fastDB); #endregion - Ta(ta => + HandleStatements(ta => { #region 데이터베이스 정보 Date date; @@ -887,7 +888,7 @@ public void SetFavoriteEntry(BaseNoteFile noteFile) { - Ta(ta => + HandleStatements(ta => { using (var dbStatement = NewDBStatement(""" DELETE @@ -1100,7 +1101,7 @@ dbStatement.ExecuteNonQuery(); } - void Ta(Action onHandle) + void HandleStatements(Action onHandle) { using var ta = _fastDB.BeginTransaction(); try diff --git a/Qwilight/System/LevelSystem.cs b/Qwilight/System/LevelSystem.cs index f79af27..855679d 100644 --- a/Qwilight/System/LevelSystem.cs +++ b/Qwilight/System/LevelSystem.cs @@ -111,7 +111,7 @@ { using var s = await TwilightSystem.Instance.GetWwwParallel(www); using var sr = new StreamReader(s); - return await (www.IsTailCaselsss(".json") ? GetJSON(levelNotifyItem, s, www) : GetHTML(levelNotifyItem, await sr.ReadToEndAsync(), www)); + return await (www.IsTailCaselsss(".json") ? GetJSON(levelNotifyItem, s, www) : GetHTML(levelNotifyItem, await sr.ReadToEndAsync().ConfigureAwait(false), www)); }); } @@ -166,37 +166,35 @@ using (var wwwClient = new HttpClient()) { wwwClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0"); - using (var hrm = await wwwClient.GetAsync(target, HttpCompletionOption.ResponseHeadersRead)) + using (var hrm = await wwwClient.GetAsync(target, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false)) { levelNotifyItem.MaxStatus = hrm.Content.Headers.ContentLength ?? 0L; } - using (var fs = File.Open(Path.Combine(EntryPath, $"{levelTableFileName}.json"), FileMode.Create)) - using (var ws = await wwwClient.GetStreamAsync(target)) + using var fs = File.Open(Path.Combine(EntryPath, $"{levelTableFileName}.json"), FileMode.Create); + using var ws = await wwwClient.GetStreamAsync(target).ConfigureAwait(false); + var data = ArrayPool.Shared.Rent(QwilightComponent.SendUnit); + try { var length = 0; - var data = ArrayPool.Shared.Rent(QwilightComponent.SendUnit); - try + while ((length = await ws.ReadAsync(data.AsMemory(0, data.Length)).ConfigureAwait(false)) > 0) { - while ((length = await ws.ReadAsync(data.AsMemory(0, data.Length))) > 0) + if (levelNotifyItem.IsStopped) { - if (levelNotifyItem.IsStopped) - { - throw new OperationCanceledException(); - } - await fs.WriteAsync(data.AsMemory(0, length)); - levelNotifyItem.Status += length; + throw new OperationCanceledException(); } + await fs.WriteAsync(data.AsMemory(0, length)).ConfigureAwait(false); + levelNotifyItem.Status += length; } - finally - { - ArrayPool.Shared.Return(data); - } + } + finally + { + ArrayPool.Shared.Return(data); } } using (var fs = File.Open(Path.Combine(EntryPath, $"#{levelTableFileName}.json"), FileMode.Create)) { s.Position = 0; - await s.CopyToAsync(fs); + await s.CopyToAsync(fs).ConfigureAwait(false); } levelNotifyItem.Variety = NotifySystem.NotifyVariety.Closed; levelNotifyItem.Text = LanguageSystem.Instance.SavedLevelContents; diff --git a/Qwilight/System/TwilightSystem.cs b/Qwilight/System/TwilightSystem.cs index 25f8722..5d35e22 100644 --- a/Qwilight/System/TwilightSystem.cs +++ b/Qwilight/System/TwilightSystem.cs @@ -1440,9 +1440,9 @@ try { var dataGet = new HttpRequestMessage(HttpMethod.Get, target); - var www = await _wwwClient.SendAsync(dataGet); + var www = await _wwwClient.SendAsync(dataGet).ConfigureAwait(false); www.EnsureSuccessStatusCode(); - return await www.Content.ReadAsStreamAsync(); + return await www.Content.ReadAsStreamAsync().ConfigureAwait(false); } catch { @@ -1459,9 +1459,9 @@ try { var dataGet = new HttpRequestMessage(HttpMethod.Get, target); - using var www = await _wwwClient.SendAsync(dataGet); + using var www = await _wwwClient.SendAsync(dataGet).ConfigureAwait(false); www.EnsureSuccessStatusCode(); - var text = await www.Content.ReadAsStringAsync(); + var text = await www.Content.ReadAsStringAsync().ConfigureAwait(false); if (!string.IsNullOrEmpty(text)) { return Utility.GetJSON(text); @@ -1486,7 +1486,7 @@ Content = new StringContent(data, Encoding.UTF8, dataVariety) }; dataPost.Headers.Add("millis", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString()); - using var www = await _wwwClient.SendAsync(dataPost); + using var www = await _wwwClient.SendAsync(dataPost).ConfigureAwait(false); www.EnsureSuccessStatusCode(); return true; } @@ -1506,11 +1506,11 @@ { var dataPost = new HttpRequestMessage(HttpMethod.Post, target) { - Content = new ByteArrayContent(await File.ReadAllBytesAsync(fileName)) + Content = new ByteArrayContent(await File.ReadAllBytesAsync(fileName).ConfigureAwait(false)) }; dataPost.Headers.Add("millis", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString()); dataPost.Headers.Add("totem", Totem); - using var www = await _wwwClient.SendAsync(dataPost); + using var www = await _wwwClient.SendAsync(dataPost).ConfigureAwait(false); www.EnsureSuccessStatusCode(); return true; } @@ -1533,9 +1533,9 @@ Content = new ByteArrayContent(data) }; dataPost.Headers.Add("millis", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString()); - using var www = await _wwwClient.SendAsync(dataPost); + using var www = await _wwwClient.SendAsync(dataPost).ConfigureAwait(false); www.EnsureSuccessStatusCode(); - return await www.Content.ReadAsStringAsync(); + return await www.Content.ReadAsStringAsync().ConfigureAwait(false); } catch { @@ -1557,7 +1557,7 @@ }; dataPut.Headers.Add("millis", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString()); dataPut.Headers.Add("totem", Totem); - using var www = await _wwwClient.SendAsync(dataPut); + using var www = await _wwwClient.SendAsync(dataPut).ConfigureAwait(false); www.EnsureSuccessStatusCode(); } catch diff --git a/Qwilight/Utilities/IOUtility.cs b/Qwilight/Utilities/IOUtility.cs index 766bfa1..a0803df 100644 --- a/Qwilight/Utilities/IOUtility.cs +++ b/Qwilight/Utilities/IOUtility.cs @@ -109,7 +109,7 @@ } } - public static string[] GetFiles(string entryPath, string o = "") + public static string[] GetFiles(string entryPath, string o = "*") { try { @@ -121,7 +121,7 @@ } } - public static string[] GetEntry(string entryPath, string o = "") + public static string[] GetEntry(string entryPath, string o = "*") { try { diff --git a/Qwilight/View/EdgePanel.xaml.cs b/Qwilight/View/EdgePanel.xaml.cs index af4ff22..e5f34b1 100644 --- a/Qwilight/View/EdgePanel.xaml.cs +++ b/Qwilight/View/EdgePanel.xaml.cs @@ -60,13 +60,25 @@ void OnMove0(object sender, RoutedEventArgs e) { - EdgeView.GoBack(); + try + { + EdgeView.GoBack(); + } + catch + { + } } [RelayCommand] void OnLoad() { - EdgeView.Reload(); + try + { + EdgeView.Reload(); + } + catch + { + } } [RelayCommand] @@ -85,7 +97,13 @@ [RelayCommand] void OnStop() { - EdgeView.Stop(); + try + { + EdgeView.Stop(); + } + catch + { + } } void OnInputLower(object sender, KeyEventArgs e) diff --git a/Qwilight/ViewModel/LevelViewModel.cs b/Qwilight/ViewModel/LevelViewModel.cs index 875fed9..56e0977 100644 --- a/Qwilight/ViewModel/LevelViewModel.cs +++ b/Qwilight/ViewModel/LevelViewModel.cs @@ -97,7 +97,7 @@ }).Response; if (!string.IsNullOrEmpty(filePath)) { - if (await LevelSystem.Instance.GetLevelNotifyItem(async levelNotifyItem => await LevelSystem.Instance.GetHTML(levelNotifyItem, await File.ReadAllTextAsync(filePath), string.Empty))) + if (await LevelSystem.Instance.GetLevelNotifyItem(async levelNotifyItem => await LevelSystem.Instance.GetHTML(levelNotifyItem, await File.ReadAllTextAsync(filePath).ConfigureAwait(false), string.Empty))) { LevelSystem.Instance.Load(true); SetLevelItemCollection(); diff --git a/Qwilight/ViewModel/MainViewModel.cs b/Qwilight/ViewModel/MainViewModel.cs index ebe49b4..1d7b03a 100644 --- a/Qwilight/ViewModel/MainViewModel.cs +++ b/Qwilight/ViewModel/MainViewModel.cs @@ -84,7 +84,7 @@ bool _isAvailable = true; string _twilightCommentText0 = string.Empty; string _twilightCommentText1 = string.Empty; - string _qwilightFileName; + string _qwilightEntryPath; Mode _mode; int _lastEntryItemID = 1; bool _isCommentMode; @@ -1405,7 +1405,7 @@ } var assistFileViewModel = ViewModels.Instance.AssistFileValue; assistFileViewModel.Title = noteFile.EntryItem.Title; - assistFileViewModel.Assist = await File.ReadAllTextAsync(assistFilePath, Encoding.GetEncoding(format)); + assistFileViewModel.Assist = await File.ReadAllTextAsync(assistFilePath, Encoding.GetEncoding(format)).ConfigureAwait(false); assistFileViewModel.Open(); } } @@ -1701,26 +1701,19 @@ PIDClass.Instance.Dispose(); - if (File.Exists(_qwilightFileName)) + if (Directory.Exists(_qwilightEntryPath)) { - if (_qwilightFileName.IsTailCaselsss(".zip")) + Utility.CopyFile(Path.Combine(QwilightComponent.CPUAssetsEntryPath, "Igniter.exe"), Path.Combine(QwilightComponent.UtilityEntryPath, "Igniter.exe")); + try { - Utility.CopyFile(Path.Combine(QwilightComponent.CPUAssetsEntryPath, "Igniter.exe"), Path.Combine(QwilightComponent.UtilityEntryPath, "Igniter.exe")); - try + Process.Start(new ProcessStartInfo(Path.Combine(QwilightComponent.UtilityEntryPath, "Igniter.exe"), $"\"{_qwilightEntryPath}\"") { - Process.Start(new ProcessStartInfo(Path.Combine(QwilightComponent.UtilityEntryPath, "Igniter.exe"), $"\"{_qwilightFileName}\"") - { - UseShellExecute = true - }); - } - catch - { - Utility.OpenAs(_qwilightFileName); - } + UseShellExecute = true + }); } - else + catch { - Utility.OpenAs(_qwilightFileName); + Utility.OpenAs(_qwilightEntryPath); } } } @@ -3258,61 +3251,116 @@ }; try { + UIHandler.Instance.HandleParallel(() => ViewModels.Instance.NotifyValue.HandlingNotifyItemCollection.Insert(0, qwilightNotifyItem)); + NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Info, NotifySystem.NotifyConfigure.NotSave, qwilightNotifyItem.Text, false, null, null, NotifySystem.SaveQwilightID); + var taehuiQwilightDate = await TwilightSystem.Instance.GetWwwParallel($"{QwilightComponent.TaehuiNetFE}/qwilight/qwilight.json"); if (taehuiQwilightDate.HasValue) { var taehuiQwilightDateValue = taehuiQwilightDate.Value; var date = Version.Parse(taehuiQwilightDateValue.date); - if (QwilightComponent.Date < date || QwilightComponent.HashText != taehuiQwilightDateValue.hash) + + var filePaths = new List(); + await SetFilePaths(AppContext.BaseDirectory); + + async ValueTask SetFilePaths(string targetEntryPath) + { + foreach (var entryPath in Utility.GetEntry(targetEntryPath).Where(entryPath => entryPath != QwilightComponent.QwilightEntryPath)) + { + await SetFilePaths(entryPath); + } + foreach (var filePath in Utility.GetFiles(targetEntryPath)) + { + filePaths.Add(filePath); + } + } + + var hashes = new ConcurrentDictionary(); + using (var setCancelID = new CancellationTokenSource()) + { + await Parallel.ForEachAsync(filePaths, setCancelID.Token, async (filePath, t) => + { + if (qwilightNotifyItem.IsStopped) + { + setCancelID.Cancel(); + } + else + { + hashes[Path.GetRelativePath(AppContext.BaseDirectory, filePath).Replace(Path.DirectorySeparatorChar, '/')] = Utility.GetID128(await File.ReadAllBytesAsync(filePath, t).ConfigureAwait(false)); + } + }); + } + + var toWipeFiles = hashes.Keys.Except(taehuiQwilightDateValue.hashes.Keys).ToArray(); + var toNewFiles = taehuiQwilightDateValue.hashes.Keys.Except(hashes.Keys).ToArray(); + var toModifyFiles = taehuiQwilightDateValue.hashes.Keys.Intersect(hashes.Keys).Where(toModifyFile => hashes[toModifyFile] != taehuiQwilightDateValue.hashes[toModifyFile]).ToArray(); + + if (QwilightComponent.Date < date || toWipeFiles.Length > 0 || toNewFiles.Length > 0 || toModifyFiles.Length > 0) { await SaveQwilight(); } - else if (!isSilent) + else { - if (StrongReferenceMessenger.Default.Send(new ViewAllowWindow + if (!isSilent) { - Text = LanguageSystem.Instance.AlreadyLatestDate, - Data = MESSAGEBOX_STYLE.MB_YESNO | MESSAGEBOX_STYLE.MB_ICONQUESTION | MESSAGEBOX_STYLE.MB_DEFBUTTON1 - }) == MESSAGEBOX_RESULT.IDYES) - { - await SaveQwilight(); + if (StrongReferenceMessenger.Default.Send(new ViewAllowWindow + { + Text = LanguageSystem.Instance.AlreadyLatestDate, + Data = MESSAGEBOX_STYLE.MB_YESNO | MESSAGEBOX_STYLE.MB_ICONQUESTION | MESSAGEBOX_STYLE.MB_DEFBUTTON1 + }) == MESSAGEBOX_RESULT.IDYES) + { + await SaveQwilight(); + } } } async ValueTask SaveQwilight() { - UIHandler.Instance.HandleParallel(() => ViewModels.Instance.NotifyValue.HandlingNotifyItemCollection.Insert(0, qwilightNotifyItem)); - NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Info, NotifySystem.NotifyConfigure.NotSave, qwilightNotifyItem.Text, false, null, null, NotifySystem.SaveQwilightID); - var title = taehuiQwilightDateValue.title; - var tmpFileName = Path.GetTempFileName(); - var target = $"{QwilightComponent.TaehuiNetFE}/qwilight/{title}"; + var tmpEntryPath = Directory.CreateTempSubdirectory().FullName; + + foreach (var toWipeFile in toWipeFiles) + { + var filePath = Path.Combine(tmpEntryPath, toWipeFile); + Directory.CreateDirectory(Path.GetDirectoryName(filePath)); + File.Create(filePath); + } + + qwilightNotifyItem.MaxStatus = toModifyFiles.Length; using (var wwwClient = new HttpClient()) { - using (var hrm = await wwwClient.GetAsync(target, HttpCompletionOption.ResponseHeadersRead)) + foreach (var toNewFile in toNewFiles.Concat(toModifyFiles)) { - qwilightNotifyItem.MaxStatus = hrm.Content.Headers.ContentLength ?? 0L; - } - using (var fs = File.OpenWrite(tmpFileName)) - using (var ws = await wwwClient.GetStreamAsync(target)) - { - var length = 0; + if (qwilightNotifyItem.IsStopped) + { + throw new OperationCanceledException(); + } + var toNewFilePath = Path.Combine(tmpEntryPath, toNewFile); + Directory.CreateDirectory(Path.GetDirectoryName(toNewFilePath)); + using var fs = File.OpenWrite(toNewFilePath); +#if X64 + using var ws = await wwwClient.GetStreamAsync($"{QwilightComponent.TaehuiNetFE}/qwilight/zip/AMD64/{toNewFile}").ConfigureAwait(false); +#endif +#if ARM64 + using var ws = await wwwClient.GetStreamAsync($"{QwilightComponent.TaehuiNetFE}/qwilight/zip/ARM64/{toNewFile}").ConfigureAwait(false); +#endif var data = ArrayPool.Shared.Rent(QwilightComponent.SendUnit); try { - while ((length = await ws.ReadAsync(data.AsMemory(0, data.Length))) > 0) + var length = 0; + while ((length = await ws.ReadAsync(data.AsMemory(0, data.Length)).ConfigureAwait(false)) > 0) { if (qwilightNotifyItem.IsStopped) { throw new OperationCanceledException(); } - await fs.WriteAsync(data.AsMemory(0, length)); - qwilightNotifyItem.Status += length; + await fs.WriteAsync(data.AsMemory(0, length)).ConfigureAwait(false); } } finally { ArrayPool.Shared.Return(data); } + qwilightNotifyItem.Status += 1.0; } } qwilightNotifyItem.Variety = NotifySystem.NotifyVariety.Closed; @@ -3321,14 +3369,12 @@ { if (!wipeTotal) { - Utility.WipeFile(_qwilightFileName); + Utility.WipeEntry(_qwilightEntryPath); } return true; }; NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Info, NotifySystem.NotifyConfigure.NotSave, qwilightNotifyItem.Text); - var qwilightFileName = Path.ChangeExtension(tmpFileName, Path.GetExtension(title)); - Utility.MoveFile(tmpFileName, qwilightFileName); - _qwilightFileName = qwilightFileName; + _qwilightEntryPath = tmpEntryPath; } } } diff --git a/Qwilight/ViewModel/NoteFileViewModel.cs b/Qwilight/ViewModel/NoteFileViewModel.cs index 41d0f08..ac387ec 100644 --- a/Qwilight/ViewModel/NoteFileViewModel.cs +++ b/Qwilight/ViewModel/NoteFileViewModel.cs @@ -114,7 +114,7 @@ var bmscFilePath = Path.Combine(Path.GetDirectoryName(Configure.Instance.BMSEditorFilePath), "iBMSC.Settings.xml"); if (File.Exists(bmseViewerFilePath) && File.Exists(bmseFilePath)) { - var bmseViewerData = (await File.ReadAllTextAsync(bmseViewerFilePath, Encoding.ASCII)).Trim(Environment.NewLine.ToCharArray()).Split(Environment.NewLine).ToList(); + var bmseViewerData = (await File.ReadAllTextAsync(bmseViewerFilePath, Encoding.ASCII).ConfigureAwait(false)).Trim(Environment.NewLine.ToCharArray()).Split(Environment.NewLine).ToList(); bmseViewerData.AddRange(Enumerable.Repeat(string.Empty, 6 - bmseViewerData.Count % 6)); var data = $""" Qwilight @@ -127,7 +127,7 @@ if (!bmseViewerData.Contains(flintFilePath)) { bmseViewerData.AddRange(data.Split(Environment.NewLine)); - await File.WriteAllTextAsync(bmseViewerFilePath, string.Join(Environment.NewLine, bmseViewerData) + Environment.NewLine, Encoding.UTF8); + await File.WriteAllTextAsync(bmseViewerFilePath, string.Join(Environment.NewLine, bmseViewerData) + Environment.NewLine, Encoding.UTF8).ConfigureAwait(false); } var bmseCompiler = new FileIniDataParser(); @@ -147,7 +147,7 @@ else if (File.Exists(bmscFilePath)) { var bmscCompiler = new XmlDocument(); - bmscCompiler.LoadXml(await File.ReadAllTextAsync(bmscFilePath)); + bmscCompiler.LoadXml(await File.ReadAllTextAsync(bmscFilePath).ConfigureAwait(false)); var nodesViewer = bmscCompiler.SelectNodes("/iBMSC/Player/Player").Cast().ToList(); var flintID = nodesViewer.FindIndex(node => Utility.EqualsCaseless(node.Attributes["Path"].Value, flintFilePath)); diff --git a/Qwilight/ViewModel/SiteViewModel.cs b/Qwilight/ViewModel/SiteViewModel.cs index f0b70f7..577a561 100644 --- a/Qwilight/ViewModel/SiteViewModel.cs +++ b/Qwilight/ViewModel/SiteViewModel.cs @@ -238,7 +238,7 @@ }).Response; if (!string.IsNullOrEmpty(filePath)) { - TwilightSystem.Instance.SendParallel(Event.Types.EventID.PostFile, Path.GetFileName(filePath), UnsafeByteOperations.UnsafeWrap(await File.ReadAllBytesAsync(filePath))); + TwilightSystem.Instance.SendParallel(Event.Types.EventID.PostFile, Path.GetFileName(filePath), UnsafeByteOperations.UnsafeWrap(await File.ReadAllBytesAsync(filePath).ConfigureAwait(false))); } }