From ff6716b39db0e015a94e50b01f8567a3cdfff2a4 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Mon, 16 Sep 2024 15:23:06 +0800
Subject: [PATCH] Restore backup file check

---
 v2rayN/ServiceLib/Common/FileManager.cs        | 18 ++++++++++++++++++
 v2rayN/ServiceLib/Resx/ResUI.Designer.cs       |  9 +++++++++
 v2rayN/ServiceLib/Resx/ResUI.resx              |  3 +++
 v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx      |  3 +++
 v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx      |  3 +++
 .../ViewModels/BackupAndRestoreViewModel.cs    | 16 +++++++++++++---
 6 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/v2rayN/ServiceLib/Common/FileManager.cs b/v2rayN/ServiceLib/Common/FileManager.cs
index 266709d5..014393a7 100644
--- a/v2rayN/ServiceLib/Common/FileManager.cs
+++ b/v2rayN/ServiceLib/Common/FileManager.cs
@@ -102,6 +102,24 @@ namespace ServiceLib.Common
             return true;
         }
 
+        public static List<string>? GetFilesFromZip(string fileName)
+        {
+            if (!File.Exists(fileName))
+            {
+                return null;
+            }
+            try
+            {
+                using ZipArchive archive = ZipFile.OpenRead(fileName);
+                return archive.Entries.Select(entry => entry.FullName).ToList();
+            }
+            catch (Exception ex)
+            {
+                Logging.SaveLog(ex.Message, ex);
+                return null;
+            }
+        }
+
         public static bool CreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName)
         {
             try
diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
index a7e2a98b..7248e789 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
+++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
@@ -321,6 +321,15 @@ namespace ServiceLib.Resx {
             }
         }
         
+        /// <summary>
+        ///   查找类似 Invalid backup file 的本地化字符串。
+        /// </summary>
+        public static string LocalRestoreInvalidZipTips {
+            get {
+                return ResourceManager.GetString("LocalRestoreInvalidZipTips", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   查找类似 Address 的本地化字符串。
         /// </summary>
diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx
index 615ba3c4..2d51cec7 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.resx
@@ -1315,4 +1315,7 @@
   <data name="LvWebDavDirName" xml:space="preserve">
     <value>Remote folder name (optional)</value>
   </data>
+  <data name="LocalRestoreInvalidZipTips" xml:space="preserve">
+    <value>Invalid backup file</value>
+  </data>
 </root>
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
index cc652cd3..c7ae08e2 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
@@ -1312,4 +1312,7 @@
   <data name="LvWebDavDirName" xml:space="preserve">
     <value>远程文件夹名称(可选)</value>
   </data>
+  <data name="LocalRestoreInvalidZipTips" xml:space="preserve">
+    <value>无效备份文件</value>
+  </data>
 </root>
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
index 1da20edc..367aabcb 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
@@ -1192,4 +1192,7 @@
   <data name="LvWebDavDirName" xml:space="preserve">
     <value>遠端資料夾名稱(可選)</value>
   </data>
+  <data name="LocalRestoreInvalidZipTips" xml:space="preserve">
+    <value>無效備份文件</value>
+  </data>
 </root>
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs b/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs
index b1786fd2..e83abe1f 100644
--- a/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs
+++ b/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs
@@ -7,6 +7,9 @@ namespace ServiceLib.ViewModels
 {
     public class BackupAndRestoreViewModel : MyReactiveObject
     {
+        private readonly string _guiConfigs = "guiConfigs";
+        private static string BackupFileName => $"backup_{DateTime.Now:yyyyMMddHHmmss}.zip";
+
         public ReactiveCommand<Unit, Unit> RemoteBackupCmd { get; }
         public ReactiveCommand<Unit, Unit> RemoteRestoreCmd { get; }
         public ReactiveCommand<Unit, Unit> WebDavCheckCmd { get; }
@@ -65,7 +68,7 @@ namespace ServiceLib.ViewModels
         private async Task RemoteBackup()
         {
             DisplayOperationMsg();
-            var fileName = Utils.GetBackupPath($"backup_{DateTime.Now:yyyyMMddHHmmss}.zip");
+            var fileName = Utils.GetBackupPath(BackupFileName);
             var result = await CreateZipFileFromDirectory(fileName);
             if (result)
             {
@@ -122,9 +125,16 @@ namespace ServiceLib.ViewModels
             {
                 return;
             }
+            //check
+            var lstFiles = FileManager.GetFilesFromZip(fileName);
+            if (lstFiles is null || !lstFiles.Where(t => t.Contains(_guiConfigs)).Any())
+            {
+                DisplayOperationMsg(ResUI.LocalRestoreInvalidZipTips);
+                return;
+            }
 
             //backup first
-            var fileBackup = Utils.GetBackupPath($"backup_{DateTime.Now:yyyyMMddHHmmss}.zip");
+            var fileBackup = Utils.GetBackupPath(BackupFileName);
             var result = await CreateZipFileFromDirectory(fileBackup);
             if (result)
             {
@@ -145,7 +155,7 @@ namespace ServiceLib.ViewModels
 
             var configDir = Utils.GetConfigPath();
             var configDirZipTemp = Utils.GetTempPath($"v2rayN_{DateTime.Now:yyyyMMddHHmmss}");
-            var configDirTemp = Path.Combine(configDirZipTemp, "guiConfigs");
+            var configDirTemp = Path.Combine(configDirZipTemp, _guiConfigs);
 
             await Task.Run(() => FileManager.CopyDirectory(configDir, configDirTemp, false, "cache.db"));
             var ret = await Task.Run(() => FileManager.CreateFromDirectory(configDirZipTemp, fileName));